如何在不重新排序的情况下将 --whole-archive 与 libtool 一起使用?
背景: 我正在从依赖于 Dyninst 的源代码编译 Extrae(性能分析),该 Dyninst 依赖于 libdwarf,在 Debian Wheezy 上,它作为静态库 (usr/lib/libdwarf.a) 提供。
Dyninst 是从以下来源编译的:
# ./configure --with-libdwarf-static; make; make install
创建:
/usr/lib/libdynDwarf.so.8.1
/usr/lib/libdyninstAPI.so.8
然后 Extrae 是从源代码编译的。
# ./configure --with-mpi=/usr --with-mpi-libs=/usr/lib --with-papi=/usr/local --with-unwind=/usr --with-dyninst=/usr --with-dwarf=/usr --with-dwarf-libs=/usr/lib
...
# make
...
/bin/sh ../../../libtool --tag=CXX --mode=link g++ -I../../../src/common -I/usr/include -g -O2 -Wall -W -L/usr/lib64 -ldyninstAPI -L/usr/lib64 -lunwind -lparseAPI -lsymtabAPI -linstructionAPI -lcommon -L/usr/lib -ldwarf -lelf -L/usr/lib -lxml2 -o extrae extrae-extrae.o extrae-forkSnippets.o extrae-cudaSnippets.o extrae-ompSnippets.o extrae-apiSnippets.o extrae-mpiSnippets.o extrae-commonSnippets.o extrae-applicationType.o extrae-mini-xml-parse.o
libtool: link: g++ -I../../../src/common -I/usr/include -g -O2 -Wall -W -o extrae extrae-extrae.o extrae-forkSnippets.o extrae-cudaSnippets.o extrae-ompSnippets.o extrae-apiSnippets.o extrae-mpiSnippets.o extrae-commonSnippets.o extrae-applicationType.o extrae-mini-xml-parse.o -L/usr/lib64 -ldyninstAPI -lunwind -lparseAPI -lsymtabAPI -linstructionAPI -lcommon -L/usr/lib -ldwarf -lelf -lxml2
/usr/lib/libdynDwarf.so.8.1: undefined reference to `dwarf_elf_init'
/usr/lib/libdynDwarf.so.8.1: undefined reference to `dwarf_finish'
collect2: error: ld returned 1 exit status
make[4]: *** [extrae] Error 1
make[4]: Leaving directory `/root/src/extrae-2.3.4/src/launcher/dyninst'
导致此错误的原因是 libdynDwarf 需要链接静态库时未包含的符号。此处提供了一个解决方案,以替换:
-ldwarf
和:
-Wl,--whole-archive -ldwarf -Wl,--no-whole-archive
我将此更改为:
./src/launcher/dyninst/Makefile.am
然后再次配置和制作。我得到这个输出:
/bin/sh ../../../libtool --tag=CXX --mode=link g++ -I../../../src/common -I/usr/include -g -O2 -Wall -W -L/usr/lib64 -ldyninstAPI -L/usr/lib64 -lunwind -lparseAPI -lsymtabAPI -linstructionAPI -lcommon -L/usr/lib -Wl,--whole-archive -ldwarf -Wl,--no-whole-archive -lelf -L/usr/lib -lxml2 -o extrae extrae-extrae.o extrae-forkSnippets.o extrae-cudaSnippets.o extrae-ompSnippets.o extrae-apiSnippets.o extrae-mpiSnippets.o extrae-commonSnippets.o extrae-applicationType.o extrae-mini-xml-parse.o
libtool: link: g++ -I../../../src/common -I/usr/include -g -O2 -Wall -W -Wl,--whole-archive -Wl,--no-whole-archive -o extrae extrae-extrae.o extrae-forkSnippets.o extrae-cudaSnippets.o extrae-ompSnippets.o extrae-apiSnippets.o extrae-mpiSnippets.o extrae-commonSnippets.o extrae-applicationType.o extrae-mini-xml-parse.o -L/usr/lib64 -ldyninstAPI -lunwind -lparseAPI -lsymtabAPI -linstructionAPI -lcommon -L/usr/lib -ldwarf -lelf -lxml2
/usr/lib/libdynDwarf.so.8.1: undefined reference to `dwarf_elf_init'
/usr/lib/libdynDwarf.so.8.1: undefined reference to `dwarf_finish'
请注意,libtool 转换为(-ldwarf 不再由 --whole-archive 包装)的喜欢排序:
g++ ... -Wall -W -Wl,--whole-archive -Wl,--no-whole-archive -o extrae ... -ldyninstAPI ... -ldwarf ...
如果我手动运行以下两个重新排序的命令,编译成功,我可以重新运行 make 并继续成功。
g++ -I../../../src/common -I/usr/include -g -O2 -Wall -W -o load-module load_module-load-module.o -L/usr/lib64 -ldyninstAPI -lunwind -lparseAPI -lsymtabAPI -linstructionAPI -lcommon -L/usr/lib -Wl,--whole-archive -ldwarf -Wl,--no-whole-archive -lelf -lxml2
g++ -I../../../src/common -I/usr/include -g -O2 -Wall -W -o demo-launcher demo_launcher-demo-launcher.o -L/usr/lib64 -ldyninstAPI -lunwind -lparseAPI -lsymtabAPI -linstructionAPI -lcommon -L/usr/lib -Wl,--whole-archive -ldwarf -Wl,--no-whole-archive -lelf -lxml2
问题
- 如何停止 libtool 重新排序标志?
- 有更好的解决方案吗?
参考:Makefile.am 的片段:
...
bin_PROGRAMS = extrae
...
extrae_SOURCES = extrae.C, ...
...
extrae_CXXFLAGS = -I$(COMMON_DIR)
extrae_CFLAGS = -I$(COMMON_DIR) -I@DYNINST_INCLUDES@ @XML2_CFLAGS@
extrae_LDFLAGS = @DYNINST_LDFLAGS@ -ldyninstAPI @UNWIND_LDFLAGS@ @UNWIND_LIBS@ -lparseAPI -lsymtabAPI -linstructionAPI $(DYNINST_EXTRA_LIBS) -lcommon @DWARF_LDFLAGS@ -ldwarf @ELF_LDFLAGS@ -lelf @XML2_LDFLAGS@ @XML2_LIBS@