I am trying to find a way to specify an option during a top-level build, so it will be recursively passed to all required packages. I can do this in the config_options() method for explicitly specified packages, but these settings are not passed down the dependencies tree. To be more precise, I have the following:
In conanfile.py from package A:
requires = ["B/1.0@user/channel"]
def config_options(self):
self.options["B"].my_option = self.options.my_option
In conanfile.py from package B:
requires = ["C/1.0@user/channel"]
def config_options(self):
self.options["C"].my_option = self.options.my_option
When building package A, my_option value is correctly passed to the package B, but not to the package C.
Is there any other way to solve the problem I have?
Hi, friend.
See https://docs.conan.io/en/latest/reference/conanfile/methods.html#configure-config-options
config_options() is used to configure or constraint the available options in a package, before they are given a value. So when a value is tried to be assigned it will raise an error.
The bug here is that it allows you to set dependent options, should error on it too!
Also, the problem here is that you can have potentially multiple sources of truth for your options if your user explicitly selects an option of your recipe or if you have multiple recipes that are trying to force the option for a common dependency. It's a very fragile design.
Usually, for the global-wide configuration we use settings. Consider them instead.
Hi @perfhunter
Have you tried using the configure() method instead? I think that should work.
In any case, I agree with @Minimonium this might not be the best design, unless everything is consistent it will lead to options conflicts. There might be other possibilities, for example using in the consumer the patterns, you can set -o *:my_option=myvalue for the whole dependency graph at once. You can put that value also in the profile (recommended to use profiles). In that way, if in the future you need to change the value of myoption for a specific package, you will be able, as it is not hardcoded in the recipes.
The other option could be using settings, yes, depending in what you want to achieve and what you are modelling. Could you please give more details about what are you modeling with my_option?
Could you please give more details about what are you modeling with
my_option
We have a set of dependent libraries and different versions of the application using that library set. The older application version should be able to run on some ancient OSes, so the library set requires several compatibility flags at compile time (also affecting the overall performance) which is triggered via Conan option. We do not want to use settings, as in this case the appropriate compatibility setting should be necessarily specified either in the profile or in the command line. We do not like this, as the library set may be used by other applications that do not care about these compatibility issues.
Actually, if -o *:my_option=myvalue works correctly, this is enough for our purpose, I missed this feature in the docs.
Thanks!
Most helpful comment
Hi @perfhunter
Have you tried using the
configure()method instead? I think that should work.In any case, I agree with @Minimonium this might not be the best design, unless everything is consistent it will lead to options conflicts. There might be other possibilities, for example using in the consumer the patterns, you can set
-o *:my_option=myvaluefor the whole dependency graph at once. You can put that value also in the profile (recommended to use profiles). In that way, if in the future you need to change the value ofmyoptionfor a specific package, you will be able, as it is not hardcoded in the recipes.The other option could be using settings, yes, depending in what you want to achieve and what you are modelling. Could you please give more details about what are you modeling with
my_option?