是否有可能告诉cmake链接静态库而不是共享 ?
在我的CMakeLists.txt
的顶部我有以下configuration:
set(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
后来,我添加一个二进制文件,并告诉它在发布模式下与tcmalloc
链接:
target_link_libraries(${BIN_NAME} optimized tcmalloc_minimal)
由此产生的makefile链接aginst共享版本的tcmalloc
:
$ make VERBOSE=1 | grep tcmalloc /usr/bin/c++ ... -Wl,-Bdynamic ltcmalloc_minimal
进一步certificate:
$ ldd app ... libtcmalloc_minimal.so.4 => /usr/local/lib/libtcmalloc_minimal.so.4 (0x00007eff89733000) ...
tcmalloc的静态和共享版本都存在:
$ ls -1 /usr/local/lib/libtcmalloc_minimal* /usr/local/lib/libtcmalloc_minimal.a /usr/local/lib/libtcmalloc_minimal_debug.a /usr/local/lib/libtcmalloc_minimal_debug.la /usr/local/lib/libtcmalloc_minimal_debug.so /usr/local/lib/libtcmalloc_minimal_debug.so.4 /usr/local/lib/libtcmalloc_minimal_debug.so.4.2.6 /usr/local/lib/libtcmalloc_minimal.la /usr/local/lib/libtcmalloc_minimal.so /usr/local/lib/libtcmalloc_minimal.so.4 /usr/local/lib/libtcmalloc_minimal.so.4.2.6
题:
我如何configurationcmake链接到静态版本的tcmalloc
?
如果您只需要支持非Windows平台,那么来自Kitware开发人员的CMake邮件列表中的这个旧电子邮件提供了最简单的方法。 本质上,使用find_library()
来查找实际库的位置,通过首先将它们列在名称中来寻找静态库。 即
find_library(TCMALLOC_LIB NAMES libtcmalloc_minimal.a tcmalloc_minimal)
然后,您将链接到以通常方式找到的库:
target_link_libraries(${BIN_NAME} ${TCMALLOC_LIB})
如果你需要支持静态库被命名为lib???.a
以外的平台,你可以更聪明地定义静态库名。 你会使用CMAKE_STATIC_LIBRARY_PREFIX和CMAKE_STATIC_LIBRARY_SUFFIX变量。
在Windows上,问题在于你无法区分DLL的静态库和导入库,正如Kitware bug跟踪器中这个老问题所讨论的那样。 两者的文件扩展名都是.lib
,所以如果某个文件是一个静态库,那么你就不能使用这个扩展来解决这个问题,不像基于Unix的平台。
您可以创建一个辅助函数,将CMAKE_FIND_LIBRARY_SUFFIXES
设置为函数范围( 因此不会影响父范围 ),该函数搜索所讨论的库并设置输出变量的结果
function(find_static_library LIB_NAME OUT) if (WIN32 OR MSVC) set(CMAKE_FIND_LIBRARY_SUFFIXES ".lib") elseif (UNIX) set(CMAKE_FIND_LIBRARY_SUFFIXES ".a") endif() find_library( FOUND_${LIB_NAME}_STATIC ${LIB_NAME} ) if (FOUND_${LIB_NAME}_STATIC) get_filename_component(ABS_FILE ${FOUND_${LIB_NAME}_STATIC} ABSOLUTE) else() message(SEND_ERROR "Unable to find library ${LIB_NAME}") endif() set(${OUT} ${ABS_FILE} PARENT_SCOPE) endfunction()
然后可以从CMakeLists.txt
中的某处调用该函数,以便使用该库的位置填充变量。
没有找到它会导致严重的失败
find_static_library(tcmalloc_minimal TCMALLOC)
然后,您可以在调用target_link_libraries
使用此变量,并确保您链接的是静态版本
target_link_libraries(${BIN_NAME} optimized ${TCMALLOC})
在这里你可以看到结果:
$ make VERBOSE=1 | grep tcmalloc
/usr/bin/c++ ... /usr/local/lib/libtcmalloc_minimal.a ...
你必须以这种方式设置你的CMAKE_FIND_LIBRARY_SUFFIXES变量:
set(CMAKE_FIND_LIBRARY_SUFFIXES .a)
因为在默认CMAKE_FIND_LIBRARY_SUFFIXES也有.so后缀(而且它似乎不按照插入顺序搜索)。 为了实现可移植性,应该添加其他后缀(请参阅此处 ,了解不同平台上CMAKE_FIND_LIBRARY_SUFFIXES的默认值)。