I'm trying to track down a failure to link with a mapfile on Solaris. The missing mapfile causes the following error when I try to run our self tests:
$ ./cryptestcwd v
ld.so.1: cryptestcwd: fatal:
/export/home/cryptopp/.libs/libcryptopp.so.6: hardware capability
(CA_SUNW_HW_1) unsupported: 0x4800000 [ AES SSE4.1 ]
Killed
I've gotten as far as this Automake rule. libcryptopp_la_LINK
, which I believe is the shared object, is missing AM_LDFLAGS
. AM_LDFLAGS
holds the -M cryptopp.mapfile
option.
libcryptopp_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
$(CXXFLAGS) $(libcryptopp_la_LDFLAGS) $(LDFLAGS) -o $@
I tried to patch it with sed
after configure
runs:
libcryptopp_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
$(CXXFLAGS) $(libcryptopp_la_LDFLAGS) -M cryptopp.mapfile $(LDFLAGS) -o $@
I confirmed the sed
is successful, but the same test fails again. When the commands are invoked -M <mapfile>
is missing.
The libtool manual talks about -M
arguments on Cygwin, but not Solaris (and the discussion only applies to GCC, and not other compilers like IBM XL C/C++, Sun C/C++ and LLVM Clang):
Note that you also need to ensure that the standard Unix directories (like /bin, /lib, /usr, /etc) appear in the root of a drive. This means that you must install Cygwin itself into the C:/ root directory (or D:/, or E:/, etc)—instead of the recommended installation into C:/cygwin/. In addition, all file names used in the build system must be relative, symlinks should not be used within the source or build directory trees, and all -M* options to gcc except -MMD must be avoided.
There is no other mention of -M
.
And there is no diagnostic, like "Removing -M <mapfile>
options to Sun linker" or "Warning: libtool
does not understand option -M <mapfile>
".
My question is, does libtool
discard -M
and its arguments for some reason?
Libtool does drop some link options when creating a library. The manual explains:
When creating a shared library, but not when compiling or creating a
program, libtool drops some flags from the command line provided by
the user. This is done because flags unknown to libtool may interfere
with library creation or require additional support from libtool, and
because omitting flags is usually the conservative choice for a
successful build.
Personally, I find the justification for this behavior to be a bit cavalier, and I furthermore think it warrants a warning from libtool
when it occurs, but unless you care to raise an issue against it, that's pretty much moot.
Experimentation shows that -M
is indeed among the options that libtool
strips. In particular, if I specify LDFLAGS
containing an -M
option on the make
command line then I can observe it echoed in the make
output when it runs the libtool
link, but not in libtool
's own echo of the link command that is actually executed:
$ make LDFLAGS="-M mapfile"
/bin/sh ./libtool --tag=CC --mode=link gcc -g -O2 -M mapfile -o libmylib.la -rpath /usr/local/lib x.lo y.lo
libtool: link: gcc -shared -fPIC -DPIC .libs/x.o .libs/y.o -O2 -Wl,-soname -Wl,libmylib.so.0 -o .libs/libmylib.so.0.0.0
The libtool
docs suggest two workarounds to pass link options that otherwise would be stripped:
For bona fide linker options, you can use one or more -Wl,
or -Xlinker
options to pass your options through libtool
and the linker driver to the linker itself. For example,
LDFLAGS=-Wl,-M,cryptopp.mapfile
For options directed specifically to the linker driver, the docs suggest adding the flags to the compiler driver command (CC="gcc -M mapfile"), but this is ineffective because the $(CC)
variable is expanded by make
to form the libtool
command line, leaving any options expressed in it exposed to libtool
for stripping.
Additionally, however, there is
- The
-XCClinker
option by which options can be passed through to the linker driver (as opposed to the linker itself), but its behavior seems a bit quirky: it seems to ignore options that don't start with a hyphen (such as the name of your map file).