让我快速设置问题。我有一个依赖于boost的库“serial”,它是在cmake中设置的,我有一个Findserial.cmake,它可以帮助我的第二个库“xbow_400”找到它。这很好,直到我尝试编译链接到“xbow_400”的“test_xbow_400”,此时我收到此链接错误:
Undefined symbols:
"boost::system::generic_category()", referenced from:
__static_initialization_and_destruction_0(int, int)in test_xbow_400.o
__static_initialization_and_destruction_0(int, int)in test_xbow_400.o
__static_initialization_and_destruction_0(int, int)in libxbow_400.a(xbow_400.o)
__static_initialization_and_destruction_0(int, int)in libxbow_400.a(xbow_400.o)
__static_initialization_and_destruction_0(int, int)in libserial.a(serial.o)
__static_initialization_and_destruction_0(int, int)in libserial.a(serial.o)
"boost::system::system_category()", referenced from:
boost::asio::error::get_system_category() in test_xbow_400.o
__static_initialization_and_destruction_0(int, int)in test_xbow_400.o
boost::asio::error::get_system_category() in libxbow_400.a(xbow_400.o)
__static_initialization_and_destruction_0(int, int)in libxbow_400.a(xbow_400.o)
boost::asio::error::get_system_category() in libserial.a(serial.o)
boost::system::error_code::error_code()in libserial.a(serial.o)
__static_initialization_and_destruction_0(int, int)in libserial.a(serial.o)
ld: symbol(s) not found
现在,我可以通过将这些行添加到我的CMakeLists.txt文件“xbow_400”来解决此问题:
+ # Find Boost
+ find_package(Boost COMPONENTS system filesystem thread REQUIRED)
+
+ link_directories(${Boost_LIBRARY_DIRS})
+ include_directories(${Boost_INCLUDE_DIRS})
# Compile the xbow_400 Library
add_library(xbow_400 src/xbow_400.cpp include/xbow_400.h)
- target_link_libraries(xbow_400 ${serial_LIBRARIES})
+ target_link_libraries(xbow_400 ${serial_LIBRARIES} ${Boost_SYSTEM_LIBRARY} ${Boost_FILESYSTEM_LIBRARY} ${Boost_THREAD_LIBRARY})
但是,我想让xbow_400使用serial而不必特别找到boost并链接到它。 (xbow_400代码不包括或直接使用boost,只能通过串行库。)
这可能吗?如果是这样,我应该向Findserial.cmake添加内容,还是应该改变构建序列的方式?
串行库:https://github.com/wjwwood/serial xbow_400:https://github.com/wjwwood/Crossbow-IMU400CC-100
我在OS X 10.6.6上。我还没有在Linux或Windows上试过这个。
答案 0 :(得分:2)
假设我正确理解你的问题然后没有,这是不可能的。如果您的程序使用库A而库使用库B,那么您必须将程序与库B链接。如果库B使用库C,那么您还必须链接库C.这可以永远持续下去。
有些时候链接器可以判断您是否使用了符号,有时则不能。例如:如果在程序中使用符号a而不是符号b或c,则库A包含全局符号a和b以及带有GNU链接器的静态符号c。链接器将插入符号b但不插入符号c,即使这两个符号都未使用。这里的规则很复杂,特定于平台。要使链接器不链接boost :: system,您必须弄清楚哪个规则导致链接器需要该符号并更改代码以删除依赖项。在大多数情况下,除非链接器疯狂并在程序中添加20 MB不需要的符号,否则可能不值得付出努力。