Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

target_find_dependencies and pkg-config #253

Open
ddassie-texa opened this issue Mar 13, 2024 · 10 comments
Open

target_find_dependencies and pkg-config #253

ddassie-texa opened this issue Mar 13, 2024 · 10 comments

Comments

@ddassie-texa
Copy link
Contributor

ddassie-texa commented Mar 13, 2024

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}/@[email protected]")

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!


Fund with Polar
@FeignClaims
Copy link
Contributor

FeignClaims commented Apr 28, 2024

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.

@ddassie-texa
Copy link
Contributor Author

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?

@FeignClaims
Copy link
Contributor

FeignClaims commented Apr 29, 2024

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 handle pkg_check_modules, and install the find_package provider file.

@aminya
Copy link
Owner

aminya commented Apr 29, 2024

Is this fixed after #257?

@FeignClaims
Copy link
Contributor

FeignClaims commented Apr 30, 2024

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?

@ddassie-texa
Copy link
Contributor Author

ddassie-texa commented Apr 30, 2024

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.

@FeignClaims
Copy link
Contributor

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.

@ddassie-texa
Copy link
Contributor Author

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.

@FeignClaims
Copy link
Contributor

FeignClaims commented Apr 30, 2024

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.

@ddassie-texa
Copy link
Contributor Author

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 guess the syntax on option 2 would be the best in this case than.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants