c++ CMake动态链接'/usr/local/lib'中的`.a '文件

lstz6jyr  于 2023-01-06  发布在  其他
关注(0)|答案(3)|浏览(269)

我想静态编译另一个静态库的程序,在这个例子中我使用了zeromq。

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中的所有库都是动态链接的?

s5a0g9ez

s5a0g9ez1#

您不应该直接使用路径,而是创建一个导入的目标,这样您就可以显式地将其声明为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源代码有答案:
如果目标不是静态库,请确保链接类型为共享。这是因为动态模式链接可以处理共享库和静态库,但静态模式只能处理静态库。如果以前的用户项将链接类型更改为静态,则需要确保它恢复为共享。
本质上,它让链接器处理检测库是否是静态的(如果当前处于动态模式)。

pw136qt2

pw136qt22#

我最初提出的关于/usr/local/lib/usr/lib之间区别的问题的答案是,默认情况下,/usr/local/lib不是隐式链接目录之一,因此,一个快速解决方法是在config中包含以下行:

set(CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES /usr/local/lib ${CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES})

然而,正如在另一个答案中所指出的,直接引用文件不是一种可行的方法,而是应该使用add_library

kt06eoxx

kt06eoxx3#

下面是我的演示:

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

相关问题