Problems with usage requirements for `target_link_libraries(<big-shared> ... <small-static> <small-static>)` configuration
Hi,
I got problems with usage requirements for next configuration:
- Static libraries
foo_a
andfoo_b
. Libraryfoo_a
useFOO_A_VAR1
macro in public headers sotarget_compile_definitions(foo_a PUBLIC FOO_A_VAR1)
used. - Shared library
foo_all
use methods fromfoo_a
andfoo_b
. This is the main library for users (public API). - Executable
foo_c
which usefoo_all
library.
Everything works fine when all targets foo_a
, foo_b
, foo_all
installed and target_link_libraries
used with PUBLIC: target_link_libraries(foo_all PUBLIC foo_a foo_b)
.
However since we need only one foo_all
library, I want to avoid installing foo_a
and foo_b
. There are some redundancy indeed, code from foo_a
:
> objdump -dC /.../lib/libfoo_a.a | grep -A2 'foo::a::A::a()>'
0000000000000000 <foo::a::A::a()>:
0: b8 42 00 00 00 mov $0x42,%eax
5: c3 retq
Already present in foo_all
:
> objdump -dC /.../lib/libfoo_all.so | grep -A2 'foo::a::A::a()>'
00000000000007d0 <foo::a::A::a()>:
7d0: b8 42 00 00 00 mov $0x42,%eax
7d5: c3 retq
But when I remove code for installing foo_a
/foo_b
I got next errors:
CMake Error: install(EXPORT "fooTargets" ...) includes target "foo_all" which requires target "foo_a" that is not in the export set.
CMake Error: install(EXPORT "fooTargets" ...) includes target "foo_all" which requires target "foo_b" that is not in the export set.
Because we use PUBLIC in target_link_libraries(foo_all PUBLIC foo_a foo_b)
hence need foo_a
/foo_b
. I can't change it to target_link_libraries(foo_all PRIVATE foo_a foo_b)
because in this case usage requirement of foo_a
will be broken - we need FOO_A_VAR1
defined for executable foo_c
:
/usr/bin/g++ ... -c /.../app/foo/c/main.cpp
In file included from /.../lib/foo/all/all.hpp:4:0,
from /.../app/foo/c/main.cpp:1:
/.../lib/foo/a/A.hpp:5:3: error: #error "FOO_A_VAR1 not defined!"
# error "FOO_A_VAR1 not defined!"
The original code was not written by me. I personally think that it make sense to collect all sources from foo_a
/foo_b
and use them in foo_all
without intermediate static libraries. However this example shows the flaw in usage requirements system which as far as I understand assume that definitions and link libraries always tied to each other. As example shows it may not be true, dependent definitions and dependent libraries can be used separately.
Example can be found here: https://github.com/forexample/big-shared
Let me know if I'm missing something.