[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