In my project, I have a mix of dependencies, some with cmake files that I can nicely use target_link_libraries()
(e.g. boost_program_options
) with, but some don't (e.g. openssl
; I have to compile a custom version for compatibility reasons) and I have to use ExternalProject_Add
and for them, and then I need to use a mixture of target_link_libraries()
, target_compile_options()
and target_link_options()
, e.g.:
# This is only for certain libraries.
target_compile_options(my_program
PUBLIC
-I${OPENSSL_INSTALL_DIR}/include
)
# This is only for certain libraries.
target_link_options(my_program
PUBLIC
-L${OPENSSL_INSTALL_DIR}/lib
)
# This is only for everything, but I have to remember
# whether I add the target name or the actual library
# files.
target_link_libraries(my_program
PUBLIC
boost_program_options
libssl.a libcrypto.a
)
What I'd rather do is replace this with something like:
# Everything in one place.
target_link_libraries(my_program
PUBLIC
boost_program_options
openssl_pseudo_target
)
And elsewhere have openssl_pseudo_target
tell cmake
the appropriate compile/link options/libraries to use.
Is there any way to do this, or achieve a similar effect?
This is what Interface Libraries are for. They also provide an example similar to what you want to do:
Another use-case is to employ an entirely target-focussed design for usage requirements:
add_library(pic_on INTERFACE) set_property(TARGET pic_on PROPERTY INTERFACE_POSITION_INDEPENDENT_CODE ON) add_library(pic_off INTERFACE) set_property(TARGET pic_off PROPERTY INTERFACE_POSITION_INDEPENDENT_CODE OFF) add_library(enable_rtti INTERFACE) target_compile_options(enable_rtti INTERFACE $<$<OR:$<COMPILER_ID:GNU>,$<COMPILER_ID:Clang>>:-rtti> ) add_executable(exe1 exe1.cpp) target_link_libraries(exe1 pic_on enable_rtti)
This way, the build specification of exe1 is expressed entirely as linked targets, and the complexity of compiler-specific flags is encapsulated in an INTERFACE library target.
P.S. There is also find_package(OpenSSL)
which provides needed targets so you don't need to make your own.