CMake静态链接.a文件的有几个坑要注意。
CMakeLists.txt文件内容如下:
add_executable (backalarm "backalarm.cpp" "backalarm.h")
if (CMAKE_VERSION VERSION_GREATER 3.12)
set_property(TARGET backalarm PROPERTY CXX_STANDARD 20)
endif()
# TODO: 如有需要,请添加测试并安装目标。
target_link_libraries(backalarm ${PROJECT_SOURCE_DIR}/library/acl/libacl.a ${PROJECT_SOURCE_DIR}/library/acl/libacl_cpp.a)
报错如下:
ninja: error: '/root/.vs/backalarm/library/acl/libacl.a', needed by 'backalarm/backalarm', missing and no known rule to make it
百思不得其解,经查确认是路径问题,但提示的路径应该是对的呀,然后尝试加上完整路径
target_link_libraries(backalarm ${PROJECT_SOURCE_DIR}/backalarm/library/acl/libacl.a ${PROJECT_SOURCE_DIR}/backalarm/library/acl/libacl_cpp.a)
编译后错误提示变成了函数未定义的引用,说明路径这次应该对了,只是链接时候可能有其它问题
[1/1] Linking CXX executable backalarm/backalarm
FAILED: backalarm/backalarm
: && /usr/bin/c++ -g backalarm/CMakeFiles/backalarm.dir/backalarm.cpp.o -o backalarm/backalarm /root/.vs/backalarm/backalarm/library/acl/libacl.a /root/.vs/backalarm/backalarm/library/acl/libacl_cpp.a && :
/root/.vs/backalarm/backalarm/library/acl/libacl_cpp.a(acl_cpp_init.cpp.o):在函数‘acl::acl_cpp_init()’中:
/root/.vs/acl-master/7e3c2249-4b5f-433d-b810-8bf4227af76f/src/lib_acl_cpp/src/acl_cpp_init.cpp:14:对‘acl_lib_init’未定义的引用
/root/.vs/backalarm/backalarm/library/acl/libacl_cpp.a(string.cpp.o):在函数‘acl::prepare_once()’中:
/root/.vs/acl-master/7e3c2249-4b5f-433d-b810-8bf4227af76f/src/lib_acl_cpp/src/stdlib/string.cpp:1896:对‘acl_main_thread_self’未定义的引用
/root/.vs/acl-master/7e3c2249-4b5f-433d-b810-8bf4227af76f/src/lib_acl_cpp/src/stdlib/string.cpp:1898:对‘pthread_key_create’未定义的引用
/root/.vs/backalarm/backalarm/library/acl/libacl_cpp.a(string.cpp.o):在函数‘acl::string::init(unsigned long)’中:
/root/.vs/acl-master/7e3c2249-4b5f-433d-b810-8bf4227af76f/src/lib_acl_cpp/src/stdlib/string.cpp:31:对‘acl_vstring_alloc’未定义的引用
再经各方面查找资料,终于找到原因,原因是lib_acl_cpp是依赖于lib_acl的,但是在target_link_libraries时,必须是依赖的要写在后面,于是改成
target_link_libraries(backalarm ${PROJECT_SOURCE_DIR}/backalarm/library/acl/libacl_cpp.a ${PROJECT_SOURCE_DIR}/backalarm/library/acl/libacl.a)
这次错误提示又变了,大部分变成了缺少pthread_xxxx未定义的引用,说明上面调整顺序后成功链接,只是缺少了pthread相关引用
1/1] Linking CXX executable backalarm/backalarm
FAILED: backalarm/backalarm
: && /usr/bin/c++ -g backalarm/CMakeFiles/backalarm.dir/backalarm.cpp.o -o backalarm/backalarm /root/.vs/backalarm/backalarm/library/acl/libacl_cpp.a /root/.vs/backalarm/backalarm/library/acl/libacl.a && :
/root/.vs/backalarm/backalarm/library/acl/libacl_cpp.a(string.cpp.o):在函数‘acl::prepare_once()’中:
/root/.vs/acl-master/7e3c2249-4b5f-433d-b810-8bf4227af76f/src/lib_acl_cpp/src/stdlib/string.cpp:1898:对‘pthread_key_create’未定义的引用
/root/.vs/backalarm/backalarm/library/acl/libacl_cpp.a(string.cpp.o):在函数‘acl::get_buf()’中:
/root/.vs/acl-master/7e3c2249-4b5f-433d-b810-8bf4227af76f/src/lib_acl_cpp/src/stdlib/string.cpp:1910:对‘pthread_once’未定义的引用
/root/.vs/acl-master/7e3c2249-4b5f-433d-b810-8bf4227af76f/src/lib_acl_cpp/src/stdlib/string.cpp:1912:对‘pthread_getspecific’未定义的引用
/root/.vs/acl-master/7e3c2249-4b5f-433d-b810-8bf4227af76f/src/lib_acl_cpp/src/stdlib/string.cpp:1918:对‘pthread_setspecific’未定义的引用
最后,经查加上以下内容链接pthread即可。
target_link_libraries(backalarm -lpthread)
总结:
1、target_link_libraries在使用${PROJECT_SOURCE_DIR}变量是,要使用完整代码路径
2、target_link_libraries各个库顺序,顺序是要依赖的要放在后面。
参考:
CMakeLists详解
https://blog.csdn.net/weixin_43837968/article/details/115257575
cmake 添加头文件目录,链接动态、静态库
https://blog.51cto.com/u_15202985/6324905
CMake学习(5): 链接静(动)态库
https://blog.csdn.net/weixin_38346042/article/details/131069948
链接过程中静态库先后顺序的影响分析
https://zhuanlan.zhihu.com/p/259893540?utm_id=0
cmake 编译c++文件时, 对‘pthread_create’未定义的引用等错误
https://blog.csdn.net/u014742995/article/details/107979243