创建一个静态库,该静态库引用其他静态库。

3
我希望创建一个静态库,它依赖于另一个库,即ZLIB。我已经有一个静态版本的构建(libz.a)。
以下是我的代码:
...
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static")
set (BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE)
set (CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES}) # to find the .a   instead of the .so
...
find_package(ZLIB REQUIRED)
if (ZLIB_FOUND)
  message(STATUS "ZLIB library: ${ZLIB_LIBRARIES}") # ZLIB library:     /usr/lib64/libz.a
  include_directories(${ZLIB_INCLUDE_DIRS})
  set (EXT_LIBS ${EXT_LIBS} ${ZLIB_LIBRARIES})
endif()
...
add_library (libTest ${MCCORE_SOURCES_CC})
target_link_libraries(libTest ${EXT_LIBS}) #EXT_LIBS = /usr/lib64/libz.a

然而,构建的最后一步是创建静态库,但没有任何引用到/usr/lib64/libz.a
例如:
/usr/bin/ar cr libTest.a  object1.o object2.o ... objectN.o 

我期望:

/usr/bin/ar cr libTest.a  object1.o object2.o ... objectN.o /usr/lib64/libz.a

似乎最终的归档创建不考虑使用 target_link_libraries 设置的库。有什么想法吗?我该怎么做才能强制它生效呢?

所以,如果我理解正确的话,您基本上想要合并两个静态库?您的库和其他一些库?为什么需要这样做?这些库将被链接到可执行文件中。 - Anonymous
我知道这很不寻常,而且库将完全包含在可执行文件中,但我已被要求提供一个静态链接版本的库,你知道客户总是正确的。对吧? - yorjo
明天早上我应该发表一个答案。我做过类似的事情。 - Anonymous
1个回答

2
在Windows系统下(使用Visual Studio),以下代码可以解决问题:
add_library(fooStatic1 STATIC fooStatic.cpp)

set(LIBS_TO_COMBINE "${CMAKE_BINARY_DIR}/libfooStatic1.lib ${ZLIB_LIBRARIES}")

add_library(combined STATIC ${LIBS_TO_COMBINE} dummy.cpp) #dummy.cpp being empty
add_dependencies(combined fooStatic1)
set_source_files_properties(${LIBS_TO_COMBINE} PROPERTIES EXTERNAL_OBJECT TRUE GENERATED TRUE)
set_target_properties(combined PROPERTIES LINKER_LANGUAGE CXX)
set_target_properties(combined PROPERTIES STATIC_LIBRARY_FLAGS "${LIBS_TO_COMBINE}")

很遗憾,在Linux下它不能工作,因为ar只会将归档文件组合在一起,而不会解压它们 - 创建出来的东西实际上是无法使用的。为了实现您的目标,您需要提取.o文件并重新组合它们:

ar -x /usr/lib64/libz.a
ar -x libfooStatic1.a
ar -rc libcombined.a  *.o

我不知道是否有一个CMake宏可以帮助这个过程。你可以在execute_process(...)中运行ar -x,然后对输出进行全局匹配,最后再运行ar -rc


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接