With Conan 1.61, on OS X
The addition of os.version setting is very helpful for OS X. PR #3091 describe it as an "optional" setting, and we see it is not generated in the automatic default profile.
Let say we try to access this setting as follows:
def build(self):
print("MIN OSX VERSION: {}".format(self.settings.os.version))
When a value is given for this settings (through command line, or profile) we can access it as expected.
The issue arise if the setting is not given any value. What we observe in our environment is that accessing the setting with conan build raises a ConanExcpetion (even though the setting is present in the _.conan/settings.yml_ file)
ERROR: curl/7.61.0@PROJECT: Error in build() method, line xy
print("MIN OSX VERSION: {}".format(self.settings.os.version))
ConanException: 'settings.os.version' doesn't exist for 'Macos'
'settings.os' possible configurations are none
While accessing it with conan create simply returns None.
Is that the expected behaviour? (It could seem strange, as it would force to have different handling of the situation in order to support both commands. Unless there is a built-in way to handle optional settings?)
New settings.yml is only created for new Conan installations. This is done to not overwrite old settings and preserve user modifications. You could find them in a new settings.yml.new file created for the purpose.
As the macos version was not there before Conan 1.0 we cannot make its use compulsory as it may break recipes modifying package IDs. I think that is the reason why default profile detection does not include the version.
If you want to use this "optional" settings, make sure you have it listed in your settings.yml file (use the new one if possible) and then add to your profile:
[settings]
os.version=10.14
That way the self.settings.os.version would be accesible from your conanfiles while doing conan create, conan install...
Hi @danimtb, thank you for looking that up.
As I was pointing out in the first message, this setting is present in my _setting.yml_ (I manually overwrite at each updates, since I don't customize settings).
Sorry if my message was confusing, I did not propose to make the setting compulsory. You are right, maintaining recipe backward compatibility seems very important !
My report was really about the inconsistent handling in cases the setting value is not defined [I can define it in my profile locally, or give it on the command line. But I would want my recipes to be usable even for users that did not define it].
When this optional setting is used in a recipe, but it is not defined:
conan build raises a ConanExceptionconan create can access it, and returns the value NoneSo, this seems inconsistent, and having a single behaviour in both cases would be more convenient for recipe implementers (so they can handle the case when it is not defined with a single approach).
It may be a bug, unless this is actually expected behaviour?
ok, now I get what you mean.
I think it is not documented because it is mostly intended for the internal Conan codebase but you can use get_safe():
self.settings.get_safe("os.version")
Tha will return None if the setting does not exist.
Before the conan build you have to execute a conan install that will lock the settings (from the used profile or the default one) in a conaninfo.txt file. Then the result should be the same as executing a conan create command. Please check and report.
@lasote Thank you for also taking a look at this behaviour.
Side note: Unless I am missing something, it is always required to run conan install before conan build, otherwise it would return the error:
ERROR: conanbuildinfo.txt file not found
I created a minimal example demonstrating the inconsistent behaviour (which exists when executing conan install before conan build):
https://github.com/Adnn/issue_conan-3345
After doing a:
git clone https://github.com/Adnn/issue_conan-3345.git
cd issue_conan-3345
This raises a ConanException
conan install conan/
conan build conan/ -sf .
ERROR: conan-test/0.0.0@PROJECT: Error in build() method, line 13
print("The cpp standard is: {}".format(self.settings.cppstd))
ConanException: 'settings.cppstd' doesn't exist
This returns None
conan create conan com/testing
ERROR: conan-test/0.0.0@com/testing: Error in build() method, line 13
print("The cpp standard is: {}".format(self.settings.cppstd))
TypeError: __str__ returned non-string (type NoneType)
Thanks for the example, I'll take a look.
You are totally right. When the settings are retrieved from the conaninfo.txt the behavior is not exactly the same. We are currently working on a refactor of this part, it will take a long time, but probably at some point, the settings won't be retrieved from the conaninfo.txt but from a more complete graph dump.
Meanwhile, this is not urgent, correct?
Thank you @lasote for confirming that it will be addressed
You are right, nothing urgent for us, as we get a unified behaviour in our recipes by using get_safe()
Related to #3367