target_find_dependencies and pkg-config
ddassie-texa opened this issue · comments
I'm trying to use target_find_dependencies
to add the dependencies for a STATIC
library that depends on some libraries that can be found via pkg-config
, I'm able to pass the PkgConfig
package to target_find_dependencies
but there doesn't seem to be an easy way to add the pkg_check_modules
calls to the CMake package config, is there any way I can solve this situation?
My old Config.cmake.in
file used to look like this:
@PACKAGE_INIT@
include(CMakeFindDependencyMacro)
find_dependency(Threads)
find_dependency(PkgConfig)
if(NOT TARGET PkgConfig::gio)
pkg_check_modules(gio REQUIRED IMPORTED_TARGET gio-2.0)
endif()
if(NOT TARGET PkgConfig::dbus)
pkg_check_modules(dbus REQUIRED IMPORTED_TARGET dbus-1)
endif()
include("${CMAKE_CURRENT_LIST_DIR}/@TARGET_NAME@Targets.cmake")
check_required_components(@TARGET_NAME@)
Upvote & Fund
@aminya is using Polar.sh so you can upvote and help fund this issue. The funding is received once the issue is completed & confirmed by you.
Thank you in advance for helping prioritize & fund our backlog!
I’m not quite sure what your question is. Are you trying to target_find_dependencies(<target> PUBLIC gio)
in which gio
is a library that should be found by pkg_check_modules
?
If that's the case, there is an official way for cmake to custom find_package, which might be helpful. You can see an actual example here, which is the CMake dependency provider for the Conan C and C++ package manager.
Sure, so is there a way to inject a custom dependency provider into the project_options target_find_dependencies call?
Or does the custom provider have to be implemented on the users of the package instead of the provider? And in that case, won't it break conan?
The situation is that PkgConfig dosen't provide find_package provider, so you have to. I think this won't break conan as both cmake-conan and vcpkg use this approach and project_options works well while enabling both run_conan()
and run_vcpkg()
.
What target_find_dependencies
actually do is to
- call
find_package
for the specified packages; - register them as a part of installation.
When running cmake --install
, the corresponding cmake config file will insert a find_package(<package> [args])
for all the packages specifed in target_find_dependencies
. That's how the function works.
To install pkg_check_modules
dependency, you can
- either
pkg_check_modules
by manual, and insert the code into cmake config file yourself at the same time. - or write a find_package provider which allows
find_package
to handlepkg_check_modules
, and install the find_package provider file.
Is this fixed after #257?
Is this fixed after #257?
@aminya Possibly not. Instead of allowing custom find_package
args like #257, this issue is about extending target_find_dependencies
to be able to find dependencies that are imported by functions other than find_package
, and install such a dependency when the target is required to install.
Without modifying the target_find_dependencies
, this could be done by:
- either pkg_check_modules by manual, and inserting the code into cmake config file yourself at the same time.
- or writing a find_package provider which allows find_package to handle pkg_check_modules, and installing the find_package provider file.
Another option could be extending target_find_dependencies
to have a custom mode:
target_find_dependencies(target
PUBLIC
# Syntax option 1
CUSTOM "pkg_check_modules(gio REQUIRED IMPORTED_TARGET gio-2.0)"
# Or syntax option 2?
CUSTOM pkg_check_modules gio REQUIRED IMPORTED_TARGET gio-2.0
)
Please let me know if this is acceptable. If it is, which is the best syntax?
I think the most versatile solution would be to add a way to provide a CMake script as an extension point (maybe allow multiple files?), eg: target_find_dependencies(<target> CUSTOM MyInjectedDep.cmake)
, then it can be installed as part of the package and included after the other find_dependency()
calls.
add a way to provide a CMake script as an extension point (maybe allow multiple files?), eg:
target_find_dependencies(<target> CUSTOM MyInjectedDep.cmake)
After setting cmake_language(SET_DEPENDENCY_PROVIDER...)
, all find_package
will try to use the provider, so this seems like a dependency for the whole project instead of the <target>
, which violets the purpose of using target_find_dependencies
(that is, bind the dependency to the target).
If setting the MyInjectedDep.cmake
is the preferable way than CUSTOM pkg_check_modules gio REQUIRED IMPORTED_TARGET gio-2.0
, I would prefer add a function like set_dependency_provider(<provider.cmake>)
to both call cmake_language(SET_DEPENDENCY_PROVIDER...)
and install it. But it is almost just a wrapper for a cmake_language(SET_DEPENDENCY_PROVIDER...)
command and a install(FILES...)
command, which is the solution describe before:
writing a find_package provider which allows find_package to handle pkg_check_modules, and installing the find_package provider file.
Another difference between setting dependency provider and just allowing CUSTOM any_function args
is that you have to adapt the call to find_package
style. For example, for pkg_check_modules(gio REQUIRED IMPORTED_TARGET gio-2.0)
, you have to adapt it to be find_package(gio)
or something else, which is not implementable for some functions.
I'm also unsure about what will happen if a user has a custom Findgio.cmake
module and a dependency provider is added, my idea with the MyInjectedDep.cmake
was just so you could more easily write complex logic to find dependencies if needed, without dealing with a long string.
You could have MyInjectedDep.cmake
without modifying target_find_dependencies
. Just use include(MyInjectedDep.cmake)
and install(FILES MyInjectedDep.cmake)
.
My question here is that target_find_dependencies
is to set dependencies for a single target, so maybe a function like set_dependency_provider(<provider.cmake>)
is more suitable than allowing target_find_dependencies
to set (possibly global) a file dependency.
Is this fixed after #257?
@aminya Possibly not. Instead of allowing custom
find_package
args like #257, this issue is about extendingtarget_find_dependencies
to be able to find dependencies that are imported by functions other thanfind_package
, and install such a dependency when the target is required to install.Without modifying the
target_find_dependencies
, this could be done by:* either pkg_check_modules by manual, and inserting the code into cmake config file yourself at the same time. * or writing a find_package provider which allows find_package to handle pkg_check_modules, and installing the find_package provider file.
Another option could be extending
target_find_dependencies
to have a custom mode:target_find_dependencies(target PUBLIC # Syntax option 1 CUSTOM "pkg_check_modules(gio REQUIRED IMPORTED_TARGET gio-2.0)" # Or syntax option 2? CUSTOM pkg_check_modules gio REQUIRED IMPORTED_TARGET gio-2.0 )Please let me know if this is acceptable. If it is, which is the best syntax?
I guess the syntax on option 2 would be the best in this case than.