How to remove compilation dependencies for cmake static libraries?

Consider this CMake setting:

add_library( A STATIC modules/a/src/src1.cpp modules/a/src/src2.cpp )
target_include_directories( A PUBLIC modules/a/inc )
target_compile_definitions( A PUBLIC USING_A=1 )

add_library( B STATIC modules/b/src/src1.cpp modules/b/src/src2.cpp )
target_include_directories( B PUBLIC modules/b/inc )
target_compile_definitions( B PUBLIC USING_B_WRAPPER=1 )
target_link_libraries( B PUBLIC A )

add_library( C STATIC modules/c/src/src1.cpp )
target_include_directories( C PUBLIC modules/c/inc )
target_link_libraries( C PUBLIC B )

Suppose that the headers from modules/b/incinclude the headers from modules/a/inc, so any library consumer Bshould also include modules/a/incin their path and also add the definition USING_A = 1.

Use a generator Ninja(however, a problem occurs with any generator, including Makefile, Xcodeand Visual Studio):

cmake -GNinja ../path/to/source

And build a library C:

ninja libC.a

Everything builds correctly, but a lot of time is spent in the building libA.aand libB.aonly for assembly libC.a.

C's B INTERFACE, libA.a libB.a , modules/c/src/src1.cpp , , B .

CMake, , , target_link_libraries (- )? , (, , , A , ), . , , - , .

+4
1

target_link_libraries . , . CMake bugreport:

target_link_libraries , , . .

, Ninja , - , . . .

target_link_libraries STATIC, . :

" " INTERFACE. SHARED.

# Compile-time dependency.
add_library( A_compile INTERFACE )
target_include_directories( A_compile PUBLIC modules/a/inc )
target_compile_definitions( A_compile PUBLIC USING_A=1 )
# Real library.
add_library( A STATIC modules/a/src/src1.cpp modules/a/src/src2.cpp )
target_link_libraries(A A_compile)

# Compile-time dependency.
add_library( B_compile INTERFACE )
target_include_directories( B_compile PUBLIC modules/b/inc )
target_compile_definitions( B_compile PUBLIC USING_B_WRAPPER=1 )
target_link_libraries( B_compile PUBLIC A_compile )
# Real library
add_library( B STATIC modules/b/src/src1.cpp modules/b/src/src2.cpp )
target_link_libraries(B B_compile)    

# Final STATIC library.
add_library( C STATIC modules/c/src/src1.cpp )
target_include_directories( C PUBLIC modules/c/inc )
target_link_libraries( C PUBLIC B_compile )

# ...
# Creation executable or non-STATIC library, linked with C
add_executable(my_exe ...)
# Need to manually list libraries, "compile-time linked" to C.
target_link_libraries(my_exe C B A)

-STATIC- target_link_libraries real STATIC, STATIC /SHARED.

+1

Source: https://habr.com/ru/post/1695120/


All Articles