Search code examples
ioscmakecross-platformstatic-linking

Create a STATIC library with another STATIC library that content inside in iOS using CMake


I have a collection of libfooi.a; libfoo1.a, libfoo2.a, libfoo3.a ... that using factories (with static code) have a common interface to create C++ objects.

With CMake I choose one of them, and create a libfooWrapper.a that link it and add all content. Using CMake this CMakeLists.txt works in Android:

PROJECT(fooWrapper)

INCLUDE_DIRECTORIES(___)

ADD_LIBRARY(fooWrapper SHARED ${SRC} ${HEADERS} ) # Must be STATIC in iOS

IF(selected1)
  TARGET_LINK_LIBRARIES(fooWrapper -Wl,--whole-archive foo1 -Wl,--no-whole-archive)
ELSEIF(...)
  TARGET_LINK_LIBRARIES(fooWrapper -Wl,--whole-archive foo2 -Wl,--no-whole-archive)

A executable app project created manually, just link generated fooWrapper and work.

But in iOS using Clang, I have changed ADD_LIBRARY to STATIC, and try using -Wl,--whole-archive but doesnt work. I have checked the documentation of that using -Obj -Wl,-force_load must work. I have tried too using flag -Obj -Wl,-all_load.

Analysing library libfooWrapper.a with otool, it seems that all content from libfooi.a is no added into libfooWrapper.a, but I need to put it inside to avoid change manually flags in executable app project.

What is wrong with linking?


Solution

  • For iOS, use libtool to create a single static library from multiple static libraries:

    add_library(fooWrapper STATIC ${SRC} ${HEADERS} )
    
    add_custom_command(TARGET fooWrapper POST_BUILD
        COMMAND /usr/bin/libtool -static -o $<TARGET_FILE:fooWrapper>
        $<TARGET_FILE:fooWrapper> $<TARGET_FILE:foo1> $<TARGET_FILE:foo2> $<TARGET_FILE:foo3>
    )
    

    The post build action merges the CMake static library targets foo1, foo2 and foo3 into fooWrapper. Alternatively, you can also use the full paths to the libraries instead of the $<TARGET_FILE:...> generator expressions.