我想针对另一个静态库静态编译我的程序,在本例中我使用zeromq。这是我的CMakeLists.txt
cmake_minimum_required(VERSION 2.6)
add_executable( test test.cpp )
find_library(ZMQ NAMES libzmq.a)
message(STATUS ${ZMQ})
target_link_libraries( test ${ZMQ} )
当我运行mkdir build && cd build && cmake ..
.a
文件-- /usr/local/lib/libzmq.a
但是,如果我检查link.txt
文件,该库是动态链接的:
/usr/bin/c++ CMakeFiles/test.dir/test.cpp.o
-o test -rdynamic /usr/local/lib/libzmq.a
奇怪的是,如果我将文件移动到另一个目录,比如/usr/lib
,然后再次运行cmake ..
,它会定位到库的新路径:
-- /usr/lib/libzmq.a
但是现在它神奇地变成了静态链接:
/usr/bin/c++ CMakeFiles/test.dir/test.cpp.o
-o test -rdynamic -Wl,-Bstatic -lzmq -Wl,-Bdynamic
同样的事情也适用于我链接到的其他库。
为什么我所有的库在/usr/local/lib
被动态链接?
您不应该直接使用路径,而是创建一个导入的目标,因此您可以显式地将其声明为static:
cmake_minimum_required(VERSION 2.6)
add_executable( test test.cpp )
find_library(zmq_location NAMES libzmq.a)
message(STATUS ${zmq_location})
add_library(zmq STATIC IMPORTED)
set_target_properties(zmq PROPERTIES IMPORTED_LOCATION ${zmq_location})
target_link_libraries( test zmq )
这可能会导致库看起来是动态链接的,但是cmake源代码有答案:
如果目标不是静态库,请确保链接类型是共享的。这是因为动态模式链接可以处理共享和静态库,但静态模式只能处理静态库。如果以前的用户项将链接类型更改为静态的,我们需要确保它返回到共享。
本质上,它让链接器处理检测库是静态的,如果当前处于动态模式
我最初关于/usr/local/lib
和/usr/lib
之间区别的问题的答案是,默认情况下,/usr/local/lib
不是隐式链接目录之一。因此,一个快速的解决方案是在配置中包含这一行:
set(CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES /usr/local/lib ${CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES})
然而,正如在另一个答案中指出的那样,直接引用文件不是方法,而是应该使用add_library
。
这是我的DEMO:
find_library(VLQ_LIB NAMES vlq-shared PATHS /usr/local/lib/ REQUIRED)
find_path(VLQ_HEADER vlq.hpp /usr/local/include)
target_link_libraries(myproj PUBLIC VLQ_LIB)
target_include_directories(myproj PUBLIC VLQ_HEADER)
但是在运行过程中,您仍然需要将共享库复制到/lib/
文件夹,对于静态库,您可以将其保存在/usr/lib