问题
I'm working on a project with a lot of external dependencies, which are included in the project tree. I would like to pre-build all of the dependencies and share the importable targets within the project tree.
I was planning to use cmake install with a CMAKE_INSTALL_PREFIX in the source tree, and use CMAKE_PREFIX_PATH to reference it for find_package. However, I'm beginning to wonder how maintainable this strategy is going to be? For example here's something I noticed in one of the installed cmake scripts:
${CMAKE_PREFIX_PATH}/lib/cmake/glfw3/glfw3Targets.cmake:
set_target_properties(glfw PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include"
INTERFACE_LINK_LIBRARIES "/usr/lib/x86_64-linux-gnu/librt.so;/usr/lib/x86_64-linux-gnu/libm.so;dl;/usr/lib/x86_64-linux-gnu/libX11.so;-lpthread"
)
It seems really suspicious to me that all of those link libraries are fully resolved to paths on the host machine.
I guess the question is: Are cmake installs to a prefix meant to be distributable and this is just a bad example, or are they meant to be tied to the machine you "install" them on? Ie. Is prefix really meant to just relocate where on the system things are supposed to be "installed", and my hope to use it as a shared package manager likely to be problematic?
回答1:
Yes, EXPORT'ed CMake targets can be "distributable", but the project should follow some principles for achieve that.
If you link with a (external) library, but do not want export file to contain absolute path to it, then do not pass absolute path directly to target_link_libraries
.
In case a linked library is shipped with a compiler (e.g. m
or rt
), things are simple: just pass the library's name to the target_link_libraries
.
In case a linked library YYY comes from other package and is detected by find_package(YYY)
, this implies several things:
Script
FindYYY.cmake
orYYYConfig.cmake
should return IMPORTED target. If this is not true, you may try to wrap its results into IMPORTED target.target_link_libraries
should use this IMPORTED target.Script
XXXConfig.cmake
, shipped with your project, should use find_dependency(YYY) for discover a library on a user machine.For
find_dependency(YYY)
work, a user machine should haveFindYYY.cmake
orYYYConfig.cmake
script. Alternatively, you may shipFindYYY.cmake
with your project, and adjustCMAKE_MODULE_PATH
variable beforefind_dependency()
call (in yourXXXConfig.cmake
).
来源:https://stackoverflow.com/questions/50941571/are-exported-installed-cmake-targets-distributable