Conan: Conditional settings don't propagate to dependencies

Created on 2 Jun 2019  路  7Comments  路  Source: conan-io/conan

Conditional settings validates but still gives ERROR (original title)
I'm trying to conditionally set os_target and arch_target from os_build and arch_build when they have not been explicitly provided.

def configure(self):
    if not self.settings.os_target:
        self.settings.os_target = self.settings.os_build
    if not self.settings.arch_target:
        self.settings.arch_target = self.settings.arch_build
    print("pre validate")
    self.settings.validate()
    print("post validate")

Gives

pre validate
post validate
ERROR: some_pkg/1.0@demo/testing: 'settings.arch_target' value not defined
triaging

All 7 comments

Ok got it, some_pkg is a requires of the current recipe. I can fix it in the dependency's recipe by doing the same conditional setting of os_target and arch_target.

Is there a better solution given conan's current capabilities, and if not what should the better solution look like? I might just implement it, but not sure what it should be :)

Should settings like this be propagated to dependencies?
Should defaults for build, host and target exist in profiles?

Hi @Ignition

Regarding your questions, I'd like to point the following ideas:

  • In general, defining settings values from a recipe is not a good idea, might be considered a smell. Future versions of Conan might completely forbid it and raise an error.
  • Settings should be defined as inputs in profiles or command line. A recipe failing because one setting has not been defined is totally expected and OK, a good thing.
  • So yes, settings should be defined in profiles, including defaults for build (host are the standard ones). Target are extremely unusual, so they won't be necessary.
  • Try to propagate settings to dependencies shouldn't be done. The settings (contrary to options) are considered project-wide configuration, and with very small exceptions that can be defined with Pkg:setting=value in command line or profiles, they should have the same value, and always defined from the outside, not in recipes.

Please tell me if this makes sense.

In an case, we are aware that the current model has some limitations, regarding cross-building when build-requires are involved. There is ongoing work for a better solution for the cross-build model, you can follow here:

The above makes sense.

To give you full detail on what I am slowly trying to achieve. I intend to make recipes for binutils+gcc+sysroot so that my team can easily get the correct toolchain (for production building) as defined by a build_requires within a profile.

Ignore the sysroot part for now as that muddies the water. The problem I'm forseeing for how the final use case will work seemlessly. I'll have a profile saying arch_build=x86_64, arch=ppc64le and a build_requires saying I need gcc of some version (the recipe general enough to support native and cross compiler). When building our gcc cross compiler arch_target needs to match arch (ppc64le) but also arch needs to change to become x86_64 (value of arch_build). This is needed so when building of the cross compiler is complete our library/executable can actually use it as a cross compiler to make the ppc64le package.

I see a special behaviour needed for building of missing build_requires where *_target, *_host, *_build all get shifted into each other.

If this is already considered then great, otherwise I hope my usecase is useful for future planning.

Same use-case for conditional settings here (though the future toolchain method may help to solve this).

The setting is only valid for a certain type of recipe (which independently need to specify the version of a development toolkit package they need), so it doesn't make sense to put this in the default profile.

Lots of recipes using common recipe code through python_requires.

from recipe:

baseline = python_requires("baseline_recipe/[~=1.0.0]@user/channel")

# recipe inherits properties from the conanfile defined in the baseline
class ConanRecipe(baseline.get_conanfile(toolkit_version="1.0.0")):
    name = "dummy"
    version = "1.0.0"

    # store git information in exported recipe for
    # checking out src when needed for building
    scm = {
        "type": "git",
        "url": "auto",
        "revision": "auto"
    }

from baseline recipe:

def get_conanfile(**kwargs):

    class InheritedConanRecipe(ConanFile):
        settings = "os", "compiler", "build_type", "arch", "toolkit_version"

        def configure(self):
            if "toolkit_version" in kwargs:
                self.settings.toolkit_version= kwargs["toolkit_version"]
            else:
                del self.settings.toolkit_version

        def requirements(self):
            if self.settings.toolkit_version:
                self.requires("toolkit/[~=%s]@user/channel" % self.settings.toolkit_version)

Oh, the reason I came here is that I'd also like the conditional settings to be printed along with the profile settings:

Configuration:
[settings]
os=Windows
arch=x86_64
build_type=Release
toolkit_version=1.0.0 <--------- add

Hi, @Ignition , Conan 1.24 will release a new _cross-building_ model that will allow to define a full profile for the _host machine_ and another full profile for the _build machine_ https://github.com/conan-io/conan/pull/5594 It will probably help with this issue (or at least we should think about this on top of that).

Thanks @jgsogo, I'll give a try and report back if I have any issues.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

uilianries picture uilianries  路  3Comments

tonka3000 picture tonka3000  路  3Comments

niosHD picture niosHD  路  3Comments

theodelrieu picture theodelrieu  路  3Comments

uilianries picture uilianries  路  3Comments