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

CMakeDeps/CMakeToolchain: Several improvements for open issues #9455

Merged
merged 11 commits into from Sep 1, 2021

Conversation

lasote
Copy link
Contributor

@lasote lasote commented Aug 20, 2021

Changelog: Feature: CMakeToolchain new member find_builddirs defaulted to True to add the cpp_info.builddirs from the requirements to the CMAKE_PREFIX_PATH/CMAKE_MODULE_PATH. That would allow finding the config files packaged and to be able to include() them from the consumer CMakeLists.txt.
Changelog: Bugfix: CMakeToolchain. Fixed a bugfix whereby a variable declared at the .variables containing a boolean ended at CMake with a quoted "True" or "False" values, instead of ON / OFF
Changelog: Feature: CMakeDeps. Added a new property cmake_find_mode with possible values to config(default), module, both or none to control the files to be generated from a package itself. The none replaces the current skip_deps_file property.
Changelog: Feature: CMakeDeps: Added two new properties cmake_module_file_name and cmake_module_target_name, analog to cmake_file_name and cmake_target_name, but to configure the name of FindXXX.cmake file and the target declared inside.

Docs: conan-io/docs#2209

@lasote lasote changed the title [DRAFT] CMakeDeps: Several improvements for open issues [DRAFT] CMakeDeps/CMakeToolchain: Several improvements for open issues Aug 20, 2021
Copy link
Member

@memsharded memsharded left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd say that overall, it looks good, lets talk about the comments.

Breaking them into smaller pieces would be nice, yes, some things like the cmake_value template function is fine and can be merged already, but not necessary, the PR is not that long, so as you prefer.

@jgsogo
Copy link
Contributor

jgsogo commented Aug 23, 2021

So far I think this kind of flexibility will be needed if we want to support all the scenarios out there and adapt to the existing [nightmare] ecosystem. Probably we need a decision about the use-cases that we won't cover and how to workaround them: build-modules, patches to consumer sources, duplicated files for Meson,... that can help us to understand the full picture.

  • CMakeToolchain: Added the build modules paths from the requirements to the CMAKE_PREFIX_PATH/CMAKE_MODULE_PATH. That would allow finding the config files packaged. THAT COULD BE OPT-IN MAYBE!

There can be different files that one consumer will always think it is the best one:

  1. Conan generated files
  2. Official files provided by the dependency (packaged in the Conan package)
  3. Files provided by the consumer itself: some libraries provide their own scripts to find the dependencies and populate custom variables
  4. Official CMake files (related: [package] opengl/system: CMake find module incompatible with standard FindOpenGL conan-center-index#2311)

Depending on how intrusive Conan wants to be, we will need more or fewer config parameters in the recipe to fit each scenario.

  • CMakeDeps: Exclude generate the configs for a given dependency FROM THE CONSUMER, actually only available from the recipe of the dependency as a property. That would allow skipping the Conan-generated config file to use another one, like the packaged or whatever.

I don't like to have too many config parameters... but sometimes the same library mixes several of the previous approaches. You need some files provided by the library and for some others Conan generated ones are better. In this scenario you can remove selected ones in the recipe:

        for package in ("Fontconfig", "Freetype", "GDAL", "GIFLIB", "GTA", "Jasper", "OpenEXR"):
            # Prefer conan's find package scripts over osg's
            os.unlink(os.path.join(self._source_subfolder, "CMakeModules", "Find{}.cmake".format(package)))
  • CMakeDeps: Added two new properties cmake_module_file_name and cmake_module_target_name (analog to cmake_file_name and cmake_target_name, but these new ones will activate the generation of FindXXX.cmake cmake scripts in order to use modules. This issue respond to this situation like this:

    • CMake installation has FindZLIB.cmake but the author (irrespective if we package or not the config files) have a zlib-config.cmake.
    • So Conan recipe needs to decide the name of the target...to make the consumers happy. ZLIBor zlib?
    • But not only that, a consumer might be doing find_package(zlib MODULE) so he won't be able to use config files.
    • That is happening is Conan center, and causing the recipe authors to use cmake, cmake_find_package or cmake_find_package_multi depending on how the CMakeLists consume the dependency, because cmake_find_package generate modules, cmake_find_package_multi generate config...

Life is hard 😢


This weekend I've been fighting with DART, I think it is a library with good build-system files (CMake) but with subtle details that make it a bit complicated: library-provided module files that use pkg_config to find dependencies, problems with multi-config generators, casing and names conflicts,... It would be very challenging to provide something that just is a drop-in replacement.

@SSE4
Copy link
Contributor

SSE4 commented Aug 29, 2021

@SpaceIm @prince-chrismc @madebr WDYT? will it make your life easier/harder/same? any comments are welcomed.

@lasote lasote added this to the 1.40 milestone Aug 31, 2021
@lasote lasote changed the title [DRAFT] CMakeDeps/CMakeToolchain: Several improvements for open issues CMakeDeps/CMakeToolchain: Several improvements for open issues Aug 31, 2021
@lasote lasote marked this pull request as ready for review August 31, 2021 12:07
Copy link
Contributor

@prince-chrismc prince-chrismc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The template looks really really complete! 🚀 Great work

WDYT? will it make your life easier/harder/same? any comments are welcomed.

Gut reaction, the same, but it's hard to say only reviewing the code.... Some of the property names are a little ambiguous for me.

Some questions that might be outside of the diff.

  • Could config be the default? that's what the majority of projects install (or they are supposed to)
  • Maybe an example of setting the package name, namespace and a target?
  • How about namespaces per target?

I also have a few questions about the code


ret = req.new_cpp_info.get_property("cmake_target_name", "CMakeDeps")
if not ret:
ret = req.cpp_info.get_name("cmake_find_package_multi", default_name=False)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No fallback to "cmake_find_package" for module?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've been greping conan-center-index and the name is always set for both of them:

        self.cpp_info.names["cmake_find_package"] = "Crc32c"
        self.cpp_info.names["cmake_find_package_multi"] = "Crc32c"

So the fallback looks enough. We introduce this fallback mostly for Conan center.

FIND_MODE_MODULE = "module"
FIND_MODE_CONFIG = "config"
FIND_MODE_NONE = "none"
FIND_MODE_BOTH = "both"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am curious why a "both" option?
AFAIK official CMake are modules (And there are a few projects the provide their own) and most project install targets + follow https://cmake.org/cmake/help/latest/module/CMakePackageConfigHelpers.html which are your config packages

but I've not come across a project that does both 🤔 with the old generators it was the costume who decided what to install but now it's defined by the recipe... we'll need to be more careful to define it correctly

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

both cover the case where the library has a module in cmake, typical FindXXX.cmake but also the author's provided config (irrespective if we package it or not). In that case, you don't know how the consumer will expect to consume the package, maybe find_package(XXX MODULE) maybe find_package(xxx CONFIG) but we want Conan to be as "ready" as possible to consume any conan center package. So CMakeDeps will generate both. Note that the config namespace and target name should be declared typically following the author's one.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes sense, I understand the motivation but I am not aware of any examples.

There are a few project out there that provide their own module files even though the upstream project provides config files. I wonder if this bonus feature will help there 🤔

self.cpp_info.set_property("cmake_target_name", "MyDepTarget")

self.cpp_info.set_property("cmake_module_file_name", "mi_dependencia")
self.cpp_info.set_property("cmake_module_target_name", "mi_dependencia_target")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about modules without targets? some of the older only use variables... how can we provide those?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The issue with these modules without targets is, Which variables should we declare? probably nothing to be automated. This might be another reason to enable a property to introduce custom cmake code that would be declared when consuming the module/config but we didn't agree yet about that.

Copy link
Member

@memsharded memsharded left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good to me, can be merged and continue working and improving over it (like #9511)

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

Successfully merging this pull request may close these issues.

None yet

5 participants