2

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 with IA instead of --start-group, the command line becomes Foo Bar IA Foo Bar, and then everything works fine. But I cannot do this in general, because of ExeB.


  • 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?
Etan
  • 17,014
  • 17
  • 89
  • 148
  • `X cannot link to A and linking fails.` - So X is actually linked with A. Why do not tell that explicitely with `target_link_libraries(X A)`? – Tsyvarev Jul 05 '16 at 19:58
  • A second program links to Y B. B has the same interface as A, so if I would have X depend on A, both A and B would be compiled. – Etan Jul 06 '16 at 07:43
  • What is meaning of `Y (uses headers of X)`? If *Y* **implements** same interface as X, then it should be additional interface library *X_I*, which is linked both by *X* and *Y*. In that case you may separately link *X* to *A* and *Y* to *B*. – Tsyvarev Jul 06 '16 at 08:22
  • 1
    A, B, C implement I. X uses I, Y uses X, App1 uses Y + A. App2 uses Y + B. App3 uses Y + C. Sorry for the confusion. – Etan Jul 06 '16 at 11:49

0 Answers0