Linux链接到.so,但仍然得到未定义的引用
linux linking to a .so , but still getting undefined reference
我正在尝试创建一个使用静态库和共享库代码的可执行文件:
静态库是几个boost .a, pthread
和libbus.a
。共享库类型为libwrap.so
。
注意libwrap使用libbus
的代码,而libbus
使用pthread
的代码。最后,可执行文件使用libwrap
和boost
中的代码。
由于链接器中包含的库的顺序很重要,所以我试图找到"获胜"的序列。
链接阶段如下(为方便起见,粘贴成多行):
$ /usr/bin/c++
-Wall -Wextra
-fPIC
-fvisibility=hidden -fno-strict-aliasing -Wno-long-long
-m64
-rdynamic
-D_UNICODE -DUNICODE
CMakeFiles/Wrapper_Test.dir/test.cpp.o
/usr/local/lib/libboost_log.a
/usr/local/lib/libboost_system.a
/usr/local/lib/libboost_filesystem.a
/usr/local/lib/libboost_date_time.a
/usr/local/lib/libboost_thread.a
/usr/local/lib/libboost_log_setup.a
/usr/local/lib/libboost_chrono.a
-pthread
/home/nass/dev/Data_Parser/trunk/external/lib/linux64_gcc_release/libbus.a
-L/home/nass/dev/Data_Parser_build/lib #this is where the libwrap.so is located
-Wl,-rpath,/home/nass/dev/Data_Parser_build/lib
-lwrap #the shared lib
-o ../../../bin/Wrapper_Test
链接错误
CMakeFiles/Wrapper_Test.dir/test.cpp.o: In function `main':
test.cpp:(.text+0x2e): undefined reference to `wrapperNamespace::GetWrapper()'
collect2: error: ld returned 1 exit status
GetWrapper()
当然位于libwrap.so
中,我可以验证它是一个可以在那里找到的符号:
$ nm -Ca ../../../lib/libwrap.so | grep GetWrapper
00000000000423d6 t wrapperNamespace::GetWrapper()
但是,链接器找不到它。我哪里做错了?
编辑:
上面的链接命令由以下CMakeLists.txt文件生成:
set(TARGET_NAME Wrapper_Test)
#set(CMAKE_BINARY_DIR ${CMAKE_SOURCE_DIR}/bin)
#set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR})
#set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR})
# INCLUDE INTERNAL FOLDER
include_directories(${CMAKE_SOURCE_DIR}/include/Wrapper)
add_executable(${TARGET_NAME} test.cpp)
add_boost_lib(${TARGET_NAME} log system filesystem date_time thread log_setup chrono)
setup_libbus(${TARGET_NAME}) #the libbus.a
target_link_libraries(${TARGET_NAME} -L../../../lib -lwrap)
set_property(TARGET ${TARGET_NAME} PROPERTY FOLDER test)
我将从生成这些行的cmake
文件开始。
find_library(
LIBWrapper
NAMES wrap
PATHS /home/nass/dev/Data_Parser_build/lib
)
然后链接到您的测试文件,例如
add_executable(test src/test.cpp)
target_link_libraries(test ${LIBWrapper})
也适用于静态库。这样做的好处是,你不必处理CMake应该为你处理的所有编译器/平台特定细节,这些细节可能相当复杂。模糊。
如果你的库是动态生成的,即在cmake配置时间之前,你可以把适当的链接标志传递给target_link_libraries
:
target_link_libraries(test -L/home/nass/dev/Data_Parser_build/lib -lwrap)
我在几个项目(例如https://github.com/caskorg/cask/blob/master/CMakeLists.txt)中使用了这个建议,它动态生成库,然后链接到它。
您应该在静态库前面使用-Wl,-Bstatic
,在动态库前面使用-Wl,-Bdynamic
。您还需要为库使用-l
,为库路径使用-L
。
类似:
$ /usr/bin/c++ test.cpp.o
-L/usr/local/lib
-Wl,-Bstatic
-lboost_log
-lsystem
-L/home/nass/dev/Data_Parser_build/lib
-Wl-Bdynamic
-Wl,-rpath,/home/nass/dev/Data_Parser_build/lib
-lwrap
-o ../../../bin/Wrapper_Test
看起来更好。很多事情取决于你的编译器/链接器/操作系统的版本。
相关文章:
- 对C宏的未定义引用,但在定义它时会出现重新定义错误
- 编译时的 CImg 库返回对"__imp_SetDIBitsToDevice"的未定义引用
- 对Py_Initialize()的未定义引用
- 使用mysql c++连接器的未定义引用
- 对 Scalar ::Scalar() 的未定义引用
- 对复制 CTOR 和 CTOR 的未定义引用
- 对显式实例化的模板函数的未定义引用
- TensorRT (C++ API) 对"createNvOnnxParser_INTERNAL"的未定义引用
- 2个模板化类的非模板友元函数未定义引用错误
- 编译 libfluid 样本控制器时对"event_base_del_virtual"的未定义引用
- 获取对function_name的未定义引用
- 对 'std::thread::_M_start_thread CMake 的未定义引用进行基准测试
- 对结构方法的未定义引用
- 使用内联函数 c++ 的未定义引用
- 对 CMake 中'cudaRegisterLinkedBinary'链接错误的未定义引用?
- 对 DLOPEN 的未定义引用
- QT C++中对全局变量的未定义引用
- 快速数学导致对"__pow_finite"的未定义引用
- 对 boost::system::d etail::system_category_instance 的未定义引用,从
- OpenCV 3.4.3 中对 'cv::String::d eallocate()' 错误的未定义引用