Hello There,
I recently added libcurl
support to my project, and I found that if fetching and building liburl
from git, the CURL::libcurl
target is global and can be used in subfolder cmake files. But, when running find_package
on system libcurl
, CURL::libcurl
is not global,and I have to manually set it to be global.
Not sure who is responsible for libcurl find_package, so posting it here.
Thanks!!
By default, imported targets created by find_package()
will be non-global. There are reasons for that related to allowing different packages to be found for the same dependency for calls to find_package()
in unrelated directory scopes. Personally, I strongly advise people to avoid that, since it is rarely what folks expect or want these days. You are likely only going to want one version of a dependency to be used consistently across your whole project. I wish that was the default behavior, but historically it isn’t.
The easiest way to make all your find_package()
calls create global imported targets is to set the CMAKE_FIND_PACKAGE_TARGETS_GLOBAL CMake variable to true at the top level of your project, ideally soon after the first call to project()
. Keep in mind that doing so will force that choice on other projects that might consume yours via FetchContent or as a git submodule, but in some situations (like controlled company environments), it can be appropriate.
@craig.scott thanks! I agree, I can’t see why anyone would want multiple packages for a single dependency. My follow up question is : why does building from git behave differently than find_package()
?
When building from source, all build system targets are global. When you bring something in via find_package()
, you’re not building it (well, you can be these days with things like the find_package()
and FetchContent integration, but that’s a relatively recent feature). Building versus importing are completely different operations. There’s not even any requirement that they produce the same things, although a well-behaved project should provide the same set of documented targets.
You’re getting into the territory of “what goes into a package”, which is a very different question to “how do I build this, and what does the build produce”.