I am trying to make my library user friendly, such that a user can import it as a target and link against it in a simple way. My library has a public 3rd party dependency that I can’t seem to configure quite right.
The CMake code for my dependency is old and variable-oriented, so my project builds the dependency with ExternalProject_Add and links against it using variables:
target_link_libraries(MyLibrary
PUBLIC
$<BUILD_INTERFACE:${MYDEPENDENCY_LIBRARY}
....
$<INSTALL_INTERFACE:${MYDEPENDENCY_LIBRARY_NAME}
where MYDEPENDENCY_LIBRARY_NAME is just the library with the path stripped out (thus the INTERFACE_LINK_LIBRARIES format you quoted).
A lot of that was guesswork, so I’m not surprised to find out that its potentially wrong… what should I do differently?
You should use the target in the main build as well. Using the path will just embed the build-time path into your package. Note that ExternalProject_add doesn’t mix well with add_library in the same project. Generally, you would want each project to build “on its own” and have a “superbuild” that does ExternalProject_add to coordinate building each component in order and passing the relevant information between them.
I have heard that those don’t generally mix well, but I’m stuck with ExternalProject_Add for my dependency due to the aforementioned old-fashioned CMake in their project. I’m not entirely sure “superbuild” is the right approach either, since my customer does not want to or need to build MyDependency - they just need to link against it transitively when linking against MyLibrary.
Anyway - if I can represent my dependency as a target in my main project and link against that target, what’s next? Just add the dependency to my export set?
If you want to use variables everywhere, that’s fine; there should be no need to find the dependency as the full path should be part of your interface directly. However, it will not be relocatable. I would recommend:
adding a IMPORTED target for the ExternalProject_add artifacts as you need; and
making a FindDependency.cmake module for the dependency that makes a similarly named target (basically just do what that IMPORTED target does, but probably with find_* commands.
That should get you to something which resembles Doing It Right™, but may need tweaking to patch over minor details.