Conan: profiles - Use setting as a variable in `build_requires`

Created on 9 Sep 2019  路  3Comments  路  Source: conan-io/conan

To help us debug your issue please explain:

  • [ x] I've read the CONTRIBUTING guide.
  • [x] I've specified the Conan version, operating system version and any tool that can be relevant.
  • [x] I've explained the steps to reproduce the error or the motivation/use case of the question/suggestion.
Distributor ID: Ubuntu
Description:    Ubuntu 16.04.6 LTS
Release:    16.04
Codename:   xenial

Conan version 1.18.2

I have a SDK/toolchain provided by a vendor that I want to include as a build_require in a conan profile. I also want to make sure that everything is rebuilt when we pick a new version of this toolchain, as it contains libraries that are statically linked. It also contains the compiler used for the target platform.

So I added a subsetting sdkversion (bad name I know) in the settings.yml, and this works great, it forces a rebuild for everyone
settings.yml

    gcc:
        version: ["4.1", "4.4", "4.5", "4.6", "4.7", "4.8", "4.9", "4.9.3",
                  "5", "5.1", "5.2", "5.3", "5.4", "5.5",
                  "6", "6.1", "6.2", "6.3", "6.4",
                  "7", "7.1", "7.2", "7.3",
                  "8", "8.1"]
        libcxx: [libstdc++, libstdc++11]
        threads: [None, posix, win32] #  Windows MinGW
        exception: [None, dwarf2, sjlj, seh] # Windows MinGW
        sdkversion: [None, ANY] #VendorSDK

vendor_profile

VERSION=5.0.0

[settings]
os_build=Linux
arch_build=x86_64
compiler=gcc
compiler.sdkversion=$VERSION

os=Linux
arch=armv7
compiler=gcc
compiler.version=4.9
compiler.libcxx=libstdc++11
build_type=Release

[build_requires]
VendorSDK/$VERSION@user/channel

So this works great, it will pull in the defined VendorSDK as a build_requires and it will force a new packageID on everyone when that compiler.sdkversion changes.

However, I was thinking about reproducibility and future VendorSDK versions.
Ideally if I needed to hotfix something or use an older VendorSDK it should be as simple as -s compiler.sdkversion=5.0.0

However, this doesn't change the version used for the build_requires and therefore doesn't pull in the correct VendorSDK/5.0.0

  1. I looked at the ENV variable CONAN_ENV_XXXX_YYYY, but it appears to be getting deprecated. It also only works for the default profiles.
  2. I could keep adding profiles for every VendorSDK version, but that would get out of control quickly.
  3. As needed I could create a custom profile, and change VERSION variable and rebuild. But this is not very convenient and may be confusing to some developers.

Like I said above it feels like it should be as simple as -s compiler.sdkversion and pull in the right version of build_requires

Ideally I'd just be able to set the VERSION variable to whatever compiler.sdkversion is and reuse it for the build_requires version.

VendorSDK/$compiler.sdkversion@user/channel

I'm also open to suggestions if there is a better avenue.
Thanks so much!

Most helpful comment

Once more, a problem in SW Engineering is solved with another layer of indirection!! 馃槃 馃槃 馃槃

Thanks @Minimonium for the suggestion!

All 3 comments

Hi, Mark.
What if you make a special wrapper recipe, let's say VendorSDKWrapper/latest@user/channel (you can pick a name that you like).
Which would contain something like this:

def requirements(self):
    self.requires("VendorSDK/%s@user/channel" % self.settings.compiler.sdkversion)

You can drop in some checks too, but the idea is like that.

So you would be able to use it like a build_requires everywhere and customize with -s compiler.sdkversion

@Minimonium very nice! This works very well.
I created a wrapper called "VendorSDKInstaller" to pseudo match some of the other installers I've seen.

Recipe

from conans import ConanFile, python_requires

common = python_requires('CastleConanRecipes/[>=0.0.22-0, include_prerelease=True]@user/master')

class VendorSDKInstaller(ConanFile):
    name = "VendorSDKInstaller"
    version = "1.0.0"
    settings = "compiler"

    def requirements(self):
        self.requires("VendorSDK/%s@user/master" % self.settings.get_safe("compiler.sdkversion"))

Profile

VERSION=5.1.2

[settings]
os_build=Linux
arch_build=x86_64
compiler=gcc
compiler.sdkversion=$VERSION

os=Linux
arch=arch=armv7
compiler=gcc
compiler.version=4.9
compiler.libcxx=libstdc++11
build_type=Release

[build_requires]
VendorSDKInstaller/1.0.0@mark/local

This worked very well, and I was able to change the settings via command line via -s compiler.sdkversion=5.1.2

It uses the default version, but you can override it. Perfect!

Thanks, I think this is sufficient and can be closed.

Once more, a problem in SW Engineering is solved with another layer of indirection!! 馃槃 馃槃 馃槃

Thanks @Minimonium for the suggestion!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

theodelrieu picture theodelrieu  路  3Comments

niosHD picture niosHD  路  3Comments

mpdelbuono picture mpdelbuono  路  3Comments

tonka3000 picture tonka3000  路  3Comments

claasd picture claasd  路  3Comments