I would like to create a static library that depends on another library, in this case ZLIB, for which I already have a static build (libz.a).
I have the following:
...
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
However, the final step of the build is creating the static library but without any reference to /usr/lib64/libz.a
ex:
/usr/bin/ar cr libTest.a object1.o object2.o ... objectN.o
I would expect:
/usr/bin/ar cr libTest.a object1.o object2.o ... objectN.o /usr/lib64/libz.a
It seems the final archive creation doesn't care for libraries set with target_link_libraries.
Any ideas?
What can I do to force this?
Under Windows (with Visual Studio) the following would do the trick:
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}")
Unfortunately, it won't work under linux, as ar will just combine the archive files without unpacking them - creating something that is not really usable. In order to achieve your goal you need to extract the .o files and recombine them:
ar -x /usr/lib64/libz.a
ar -x libfooStatic1.a
ar -rc libcombined.a *.o
I am not aware of a CMake macro that would help in the process. You could probably run ar -x in execute_process(...), glob the output, and then run ar -rc.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With