[CMake] Static libraries depending on libraries: only on headers/options/defines

Andreas Naumann Andreas-Naumann at gmx.net
Sat Feb 16 17:03:23 EST 2019


Hi Paul,

I understand the relationship between libraries as strict, such that you 
always build all dependent libraries before.
In your use case I thought about splitting the libraries in the actual 
target and the interface one.
For example, you could create an interface library foo_interface
add_library(foo_interface INTERFACE )
set the properties and then link foo and bar to this interface library 
using target_link_libraries.

But be aware, that now every executable, which links against bar must 
manually link against foo. If your project is large, this seems not 
really desirable. But I think you could also split the library bar in 
two bar_withoutFoo and bar. The library bar_withoutFoo would link 
against foo_interface and compile the sources, whereas bar is an 
interface library which depends on bar_withoutFoo and foo.
The developer could than build bar completely independent from foo and 
you could transport the transitive dependencies to the executable.

I don't know if this doubled structure using pure interfaces libraries 
and the actual libraries is maintainable.

Hope that helps a bit,
Andreas

Am 16.02.19 um 20:20 schrieb Paul Smith:
> Hi all;
>
> I'm working on modernizing our large complex CMake environment.  It
> builds a number of different binaries from an even larger number of
> static libraries, and these libraries depend on each other as well, in
> that they need to include headers and, sometimes, -D options etc.
>
> I've used straightforward target_link_libraries() to declare the
> relationship between these libraries; for example:
>
>    add_library(foo STATIC ...)
>    target_include_directories(foo PUBLIC ...)
>    target_compile_definitions(foo PUBLIC ...)
>    target_compile_options(foo PUBLIC ...)
>
>    add_library(bar STATIC ...)
>    target_link_libraries(bar PUBLIC foo)
>
>    add_executable(one ...)
>    target_link_libraries(one PRIVATE bar)
>
> This works, in that everything builds properly but it has a side-effect
> we want to avoid.  Because the source tree is large many developers
> have a habit of testing compilation of subsets of the code using
> something like:
>
>    make -jX bar
>
> and expect it to just build the static library bar.  Because it's a
> static library you don't need to actually build "foo" until link time.
> But we do need all the include directories, compile definitions, and
> compile options to be inherited from "foo" into "bar".
>
> However with the above formulation, building "bar" also forces the
> compilation of "foo", which we don't need or want.
>
> I've played around with the different values of PUBLIC, PRIVATE, and
> INTERFACE but there doesn't seem to be a straightforward way to say,
> "take the interface values for includes, definitions, and options, but
> don't depend on the generated target".
>
> I can write a function to do this myself but this seems like the most
> common way someone would want to treat static libraries referencing
> other static libraries, so I wondered if I was missing something that would allow this in a simpler way.
>
> Thanks!
>



More information about the CMake mailing list