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

Assume only config files are generated in CMakeDeps generator when none is specified #11240

Conversation

jcar87
Copy link
Contributor

@jcar87 jcar87 commented May 12, 2022

Changelog: Bugfix: Fix case where CMakeDeps assumes a module dependency when transitive dependencies do not define cmake_find_mode and fallback to a config one.

Docs: omit

Fixes #11201

The CMakeDeps generator explicitly specifies the search mode (config or module) for transitive dependencies. It does so by inspecting the value of the cmake_find_mode property defined in package_info() in the individual packages, as well as whether or not it is generating a config or a module file. When a dependency specifies that both should be generated, the CMakeDeps generator will try to align modules to "depend" on modules, and configs to depend on configs.

The issue was that when a transitive dependency does not define a cmake_find_mode explicitly, it should be assumed to be config, and thus, the transitive find_dependency calls should explicitly say CONFIG as that's the only one available to be searched for. The generator was working correctly in this case (generating the config when cmake_find_mode was not specified), but when encoding the dependency find mode in consumers, it was defaulting to MODULE instead of CONFIG. This was only causing issues when the direct dependency was consumed as a module instead of a config (as seen here)

A test has been modified to cover the case when a consumer depends on package B which depends on package A, and package B is consumed from a module when package A only generates a config.

@jcar87 jcar87 requested review from lasote, czoido and memsharded May 12, 2022 15:21
@CLAassistant
Copy link

CLAassistant commented May 12, 2022

CLA assistant check
All committers have signed the CLA.

("config", "config", ""),
("module", "module", ""),
("both", None, ""),
("both", None, "MODULE")
Copy link
Contributor Author

@jcar87 jcar87 May 12, 2022

Choose a reason for hiding this comment

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

This is the case that fails, that is fixed by the PR. It roughly replicates the issue from conan-io/conan-center-index#10698.

When:

  • Consumer has find_package(MYPKGB) and MODULES are searched first by default (this either by specifying it in the find_package call, or by setting CMAKE_FIND_PACKAGE_PREFER_CONFIG to OFF (otherwise the CMakeToolchain generator sets it to ON).

  • MYPKGB depends on MYPKGA

  • MYPKGA only provides a config because it does not specify cmake_find_mode at all (when it does, it all works fine).

Copy link
Member

Choose a reason for hiding this comment

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

Do you mean MYPKGB depends on MYPKGA? Seems typo, reversed.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oops, you're right. I've updated the comment !

@@ -22,9 +22,9 @@ def get_file_name(conanfile, forced_module_mode=None):
def get_find_mode(conanfile):
"""
:param conanfile: conanfile of the requirement
:return: "none" or "config" or "module" or "both" or None when not set
:return: "none" or "config" or "module" or "both" or "config" when not set
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is in line with the documentation.

Note that if the packages explicitly use the python None value like this (instead of a string):
self.cpp_info.set_property("cmake_find_mode", None)

it would be mapped to "config" with this change - I wonder if we need to protect ourselves against that case, or if we should always assume that the property is always a string if defined.

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think so. We try not to be overprotective, we end with a massive amount of checks that eventually make the things even worse 😓 So I wouldn't add a check here and maybe something to the documentation saying, please note that "none" has to be a string and not a None value that means "unset".

Copy link
Contributor

Choose a reason for hiding this comment

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

Is "unset" a valid setting? If so then I'd like to suggest to not allow "None" or any non-strings, and have "unset" an explicit setting that someone can see in the code and documentation.

If the parameter should be a string, then surely that should be a pre-assert?
You have to do manual checks when using a language that isn't statically typed ... that is the penalty of the "convenience" of a language like Python.

Especially if the consequence of someone typing None instead of "None" is several hours/days of debugging and struggling (surprise = bad), instead of a simple error message.

@jcar87 jcar87 changed the base branch from develop to release/1.48 May 12, 2022 16:05
@jcar87 jcar87 force-pushed the bugfix/issue-11201-cmakedeps-generates-wrong-find-package-require branch from 166f27d to 1911763 Compare May 12, 2022 16:10


@pytest.mark.parametrize("find_mode_PKGA, find_mode_PKGB, find_mode_consumer", find_modes)
def test_transitive_modules_found(find_mode_PKGA, find_mode_PKGB, find_mode_consumer):
"""
related to https://github.com/conan-io/conan/issues/10224
modules files variables were set with the pkg_name_FOUND or pkg_name_VERSION
Copy link
Contributor

Choose a reason for hiding this comment

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

I would update/review the docstring with the new issue solved by this PR.

]


@pytest.mark.parametrize("find_mode_PKGA, find_mode_PKGB, find_mode_consumer", find_modes)
Copy link
Contributor

Choose a reason for hiding this comment

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

In my opinion, I prefer to see all the inputs together instead of saving them in a variable (when the list of inputs is small enough), I think it's easier to read the test.

Suggested change
@pytest.mark.parametrize("find_mode_PKGA, find_mode_PKGB, find_mode_consumer", find_modes)
@pytest.mark.parametrize("find_mode_PKGA, find_mode_PKGB, find_mode_consumer", [
("both", "both", ""),
("config", "config", ""),
("module", "module", ""),
("both", None, ""),
("both", None, "MODULE")
])

@paulharris
Copy link
Contributor

paulharris commented May 17, 2022

Sorry, about all the noise, I've cleaned up the PRs and bugreports.

This merged PR only goes half way to fixing the problems related to module-config confusions.

Test case: conan-io/conan-center-index#10825
Discussion on the reasons behind the bug: #11201
My proposed fix: #11217

Shortest description of further problem:
conan-io/conan-center-index#10825 (comment)

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.

[bug] CMakeDeps generates a MODULE require instead of CONFIG
8 participants