I have a project with a layer consisting of interface libraries:
add_library(I INTERFACE)
These interface libraries are then implemented several times, to fit the different environments of applications:
add_library(IA STATIC ...)
target_link_libraries(IA PUBLIC I)
add_library(IB STATIC ...)
target_link_libraries(IB PUBLIC I)
There are also application independent libraries, that make use of the interface libraries.
add_library(Foo STATIC ...)
target_link_libraries(Foo PUBLIC I)
add_library(Bar STATIC ...)
target_link_libraries(Bar PUBLIC I)
And finally, the application defines which implementation of the interface library layer is being used.
add_executable(ExeA ...)
target_link_libraries(ExeA Foo Bar IA)
add_executable(ExeB ...)
target_link_libraries(ExeB Foo Bar IB)
Luckily, this is okay, as long as IA
is listed after Foo
and Bar
in the synthesized link command.
However, certain implementations of I make use of the application independent libraries again. On these environments, the link command line becomes something like this:
IA Foo Bar
While it should be
Foo Bar IA Foo Bar
This make sense, because there is no explicit dependency being described that Foo
/ Bar
depend on IA
while compiling ExeA
.
In the simple case, we just get lucky, because it happens to be the default that link command line has the same order as in the target_link_libraries
call.
I'm working with gcc-arm-none-eabi cross compiler. Here's what I've tried:
LINK_INTERFACE_MULTIPLICITY
Does not seem to work. The generated command line is still the same even with higher numbers.
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--start-group")
Linking succeeds, but the program does not run properly on the target hardware. Only after connecting a debugger and resetting, it runs. Strange behaviour.
When I link
Foo
/Bar
explicitly withIA
instead of--start-group
, the command line becomesFoo Bar IA Foo Bar
, and then everything works fine. But I cannot do this in general, because ofExeB
.
- Is there a way how I can define that Foo / Bar temporarily depend on IA while compiling ExeA, and temporarily depend on IB while compiling ExeB?
- Is there a different approach on how to handle project structured like the one described above?