[CMake] Why do executables link static libs that shared libs were built from?

Paul Smith paul at mad-scientist.net
Sat Jun 15 19:22:04 EDT 2019


I have a situation where I create a number of static libraries, then I
create a shared library from them, then I create an executable from the
shared library.

This seems straightforward, but I can't get it do work as I want.  The
behavior of STATIC -> SHARED for target property inheritance seems
incorrect to me.

I'm using CMake 3.14.5 on GNU/Linux for this test.

I need the compile properties of the static library (include
directories etc.) to be public for all users of the shared library as
well.  But obviously I don't want users of the shared library to also
link the static library!!  That defeats the whole purpose of the shared
library.

If I set up like this:

  $ touch foo.c bar.c
  $ echo 'int main() { return 0; }' > run.c

then write my CMakeFiles.txt like this:

  cmake_minimum_required(VERSION 3.13)
  project(Test C)

  add_library(foo STATIC foo.c)
  target_include_directories(foo PUBLIC /tmp)

  add_library(bar SHARED bar.c)
  target_link_libraries(bar PUBLIC foo)

  add_executable(run run.c)
  target_link_libraries(run PUBLIC bar)

Then, I DO get the -I/tmp forwarded up to run.c:

  cc -I/tmp -o CMakeFiles/run.dir/run.c.o -c run.c
     ^^^^^^

But libfoo.a is ALSO added to my link line, which is really wrong!

  cc CMakeFiles/run.dir/run.c.o  -o run -Wl,-rpath,. libbar.so libfoo.a
                                                               ^^^^^^^^

On the other hand if I change the link of foo to be PRIVATE instead of
PUBLIC:

  target_link_libraries(bar PRIVATE foo)

then the link doesn't include libfoo.a, which is good, but I also don't
have the -I/tmp when I compile run.c, which is wrong:

  cc -o CMakeFiles/run.dir/run.c.o -c run.c
  cc CMakeFiles/run.dir/run.c.o -o run -Wl,-rpath,. libbar.so

Does this seem wrong to anyone else?  Is there some trick to it?

Or do I have to resort to by-hand forwarding of build properties rather
than relying on a straightforward target_link_libraries() line?



More information about the CMake mailing list