libtool 是否使用 -M 删除所有选项?

Does libtool strip all options with -M?

我正在尝试使用 Solaris 上的映射文件来追踪 link 的故障。当我尝试 运行 我们的自我测试时,丢失的映射文件导致以下错误:

$ ./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

我已经了解了这条 Automake 规则。我认为是共享对象的 libcryptopp_la_LINK 丢失了 AM_LDFLAGSAM_LDFLAGS 持有 -M cryptopp.mapfile 选项。

libcryptopp_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
    $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
    $(CXXFLAGS) $(libcryptopp_la_LDFLAGS) $(LDFLAGS) -o $@

我尝试在 configure 运行 之后用 sed 修补它:

libcryptopp_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
    $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
    $(CXXFLAGS) $(libcryptopp_la_LDFLAGS) -M cryptopp.mapfile $(LDFLAGS) -o $@

我确认 sed 成功,但同样的测试再次失败。调用命令时 -M <mapfile> 丢失。

libtool manual 讨论了 Cygwin 上的 -M 参数,但不适用于 Solaris(并且该讨论仅适用于 GCC,而不适用于其他编译器,如 IBM XL C/C++、Sun C/C++ 和 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.

没有其他提及-M

并且没有诊断,例如"Removing -M <mapfile> options to Sun linker""Warning: libtool does not understand option -M <mapfile>".

我的问题是,libtool 是否出于某种原因丢弃了 -M 及其参数?

Libtool 在创建库时会删除一些 link 选项。 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.

就我个人而言,我觉得这种行为的理由有点漫不经心,而且我认为当它发生时 libtool 应该发出警告,但除非你想提出一个问题来反对它,那就是几乎没有实际意义。

实验表明 -M 确实在 libtool 删除的选项中。特别是,如果我在 make 命令行上指定 LDFLAGS 包含 -M 选项,那么我可以观察到它在运行 libtool 时在 make 输出中回显] link,但不在 libtoolown 回显实际执行的 link 命令:

$ 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

libtool 文档提出了两种解决方法来传递 link 选项,否则这些选项将被删除:

  • 对于善意的linker选项,您可以使用一个或多个-Wl,-Xlinker选项来通过 libtool 和 linker 驱动程序将您的选项传递给 linker 本身。例如,

     LDFLAGS=-Wl,-M,cryptopp.mapfile
    
  • 对于专门针对 linker 驱动程序 的选项,文档建议将标志添加到编译器驱动程序命令 (CC="gcc -M mapfile"),但是这是无效的因为$(CC)变量被make扩展形成了libtool 命令行,将其中表达的任何选项暴露给 libtool 进行剥离。

此外,还有

  • -XCClinker 选项可以将选项传递给 linker 驱动程序(与 linker 本身相反),但它的行为似乎有点古怪:它似乎忽略了不以连字符开头的选项(例如地图文件的名称)。