如何正确构建静态库?

时间:2012-06-27 13:04:37

标签: c++ c linker makefile cmake

我使用log4cxx日志库。我需要链接其静态版本以避免其他二进制依赖项。我在动态库中使用它。 log4cxx的默认构建产生静态库但我无法与它链接,因为它是使用w / o -fPIC标志编译的。所以我将log4cxx bulding改为:

CPPFLAGS="-fPIC -static" ./configure
make

结果我收到了liblog4cxx.a我可以链接到我的.so库。链接是由Cmake完成的,例如:

target_link_libraries(my_dynamic_lib log4cxx)
link_directories(relative_path_to_dir_where_liblog4cxx.a_lives)

直到运行时,一切看起来都很好。由于undefined symbol "logger"

,我无法加载my_dynamic_lib.so

请解释我的错误以及如何解决这个问题。

感谢

2 个答案:

答案 0 :(得分:1)

通常您会将liblog4cxx.a与您的可执行文件链接,而不是与my_dynamic_lib.so相关联。我不认为你可以像你的例子那样链接,除非你能提供另外说明的文件。

答案 1 :(得分:1)

您可以使用

验证共享库是否包含该符号
nm -g my_dynamic_lib.so | grep logger

如果它以符号类型U显示,则表示它未定义。

通常,共享库在运行时不会解析所需的所有符号,因此可以(并且完全正常)链接具有缺失符号的共享库。

如果将-llog4cxx放在my_dynamic_lib.so的链接器命令行的开头,那么它将不会链接到那里的任何代码,并且会使logger符号保持未解析状态直到运行时。要强制它使用静态库中的符号,请确保在需要它的对象后列出静态库

g++ -fPIC -shared -o my_dynamic_lib.so obj1.o obj2.o -llog4cxx ...

我不知道如何使用cmake,但看起来你的CMakefile在链接主可执行文件时只链接到log4cxx,而不是动态库。