2012-04-12 133 views
2

我想创建一个静态库,它依赖于另一个库,在这种情况下,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设置的库。

任何想法?

我能做些什么来强制这个?

+0

所以,如果我理解正确,你基本上想合并两个静态库?你的图书馆和其他一些?你为什么需要这个?这些库文件将被链接到可执行文件中。 – Anonymous 2012-04-12 19:05:18

+0

我知道这是不寻常的,图书馆将被完全包含在可执行文件中,但我已经被要求发布静态链接版本的图书馆,并且您知道客户永远是对的。对? – yorjo 2012-04-12 21:21:38

+0

明天早上我应该回答问题。我做了类似的事情。 – Anonymous 2012-04-12 21:28:24

回答

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,输出glob,然后运行ar -rc