Open sakra opened 1 year ago
There is a compatibility.py file which is adding these extra compatibilities which in your case are making it select the non-compatible package. You can check the file in the conan home directory and see the compatibility method documentation on conan 2.
You can try returning empty from the comptaibility method in that file and see how that works for you
@adnan-ali1 There is no compatibility.py in my .conana2 directory. Actually I have set up conan2 on a new Windows 11 machine and it uses default settings. Maybe its a problem in the catch2 recipe.
Hi @sakra
The compatibility.py
file will be automatically created the first time it is needed if it doesn't exist. So after a conan install
invocation or similar the file should be there. If catch2/3.4.0: Checking 3 compatible configurations:
is in the output, the file has been generated.
Thanks very much for the insights about catch2 not being compatible over different cppstd
values. Building it from sources as you tried with the compiler.cppstd=17
setting should work, maybe it is the syntax? It shouldn't use brackets but something like --build="catch*"
with quotes. Can you please try that?
As @adnan-ali1 suggested (thanks!) it is also possible to edit the compatibility.py
, for example you could add a exception for packages that matches catch2
, and avoid the fallback to older cppstd14.
Finally, we need to investigate this a bit further. It seems that we want packages to be able to inhibit themselves from certain possible compatibility.py
behavior, but this doesn't seem possible at this moment. We might want to consider this a new feature.
Hi @memsharded
Thanks for your reply and clarifying the situation regarding compatibility.py
. The file has indeed bin generated in the directory .conan2/extensions/plugins/compatibility
.
Regarding forcing a manual build. I have tried the following combinations:
--build="catch2"
does not force a build.
--build="catch2*"
does indeed force a build.
--build="[catch2*]"
does not force a build. Looking at the documentation, I do not see why this one does not work.
Regarding the cppstd
compatibility:
I think that the default assumption that a dependency that has been compiled with an older standard as the one used by the current profile is compatible is too optimistic for C++. IMHO that default choice should be that compiler.cppstd
must match exactly. Some packages may opt-out of this behavior.
--build="catch2*" does indeed force a build.
The match is a fnmatch over the whole catch2/version
reference. This is why catch2*
works but not the others. If you provide the full catch2/version
it should work too
I think that the default assumption that a dependency that has been compiled with an older standard as the one used by the current profile is compatible is too optimistic for C++. IMHO that default choice should be that compiler.cppstd must match exactly. Some packages may opt-out of this behavior.
We took this decission based on the ConanCenter behavior. Conan 1.X assumed cppstd
compatibility implicitly, and it has been working quite good for years, for around 1500 different packages, without reports similar to this one. While we knew that it is possible that some packages can be using some variability based on the different standard, it doesn't seem the norm, so we decided to go with a default compatibility.py
that assumes that. It seems to work so far because:
compatibility.py
to force exact matching is trivialcppstd
matching is bad, as it forces the majority of users to build from source most of the packages, taking too long.--build="catch2*" does indeed force a build.
The match is a fnmatch over the whole
catch2/version
reference. This is whycatch2*
works but not the others. If you provide the fullcatch2/version
it should work too
I tried the following variants:
--build="catch2/3.4.0"
forces a build
--build="[catch2/*]"
does not force a build
--build="[catch2/3.4.0]"
does not force a build
We took this decission based on the ConanCenter behavior. Conan 1.X assumed
cppstd
compatibility implicitly, and it has been working quite good for years, for around 1500 different packages, without reports similar to this one. While we knew that it is possible that some packages can be using some variability based on the different standard, it doesn't seem the norm, so we decided to go with a defaultcompatibility.py
that assumes that. It seems to work so far because:* The usual thing is that teams using Conan in prod make sure they build their own binaries with the right settings that they want * Deactivating the default `compatibility.py` to force exact matching is trivial * It is a reasonable default to build binaries for ConanCenter. Multiplying the number of packages to build x5 is simply unfeasible. And forcing exact `cppstd` matching is bad, as it forces the majority of users to build from source most of the packages, taking too long.
I see. How would I have to change compatibility.py
in order to force exact matching for catch2 only?
Currently it looks like this:
def compatibility(conanfile):
configs = cppstd_compat(conanfile)
# TODO: Append more configurations for your custom compatibility rules
return configs
--build="[catch2/*]" does not force a build
Yes, the brackets are taken literally, don't use brackets at all. Maybe have you seen that somewhere in the docs? If that is the case, we should fix the docs, but the brackets should never be used in the --build
patterns. The --build=[pattern]
in the conan install -h
cli help is not literal, probably a legacy when the --build
didn't really require a value (defaulted to *
)
I see. How would I have to change compatibility.py in order to force exact matching for catch2 only?
Something like:
def compatibility(conanfile):
if conanfile.name == "catch2":
return
configs = cppstd_compat(conanfile)
# TODO: Append more configurations for your custom compatibility rules
return configs
--build="[catch2/*]" does not force a build
Yes, the brackets are taken literally, don't use brackets at all. Maybe have you seen that somewhere in the docs? If that is the case, we should fix the docs, but the brackets should never be used in the
--build
patterns. The--build=[pattern]
in theconan install -h
cli help is not literal, probably a legacy when the--build
didn't really require a value (defaulted to*
)
My bad. I interpreted the brackets as literally. I thing adding examples to the install documentation would be helpful here.
I see. How would I have to change compatibility.py in order to force exact matching for catch2 only?
Something like:
def compatibility(conanfile): if conanfile.name == "catch2": return configs = cppstd_compat(conanfile) # TODO: Append more configurations for your custom compatibility rules return configs
Thanks. That works.
We re-opened this, as we want to discuss the above:
It seems that we want packages to be able to inhibit themselves from certain possible compatibility.py behavior, but this doesn't seem possible at this moment. We might want to consider this a new feature.
Environment details
Steps to reproduce
In my
conanfile.txt
I am declaring catch2 as a dependency:catch2/[~3]
Upon running conan2 with the following command line:
conan.exe install --update --settings=build_type=Release -vverbose --build=missing --output-folder=. path/to/source
conan resolves the catch2 dependency in the following way:
Conan2 selects the compatible package
256d8e24411ffc8da15f42452ef405d7117905dc
which is not compatible at all. Since it is compiled forcppstd=14
, it misses all the extensions that Catch2 adds when it is compiled for C++17 or newer. This make the build fail upon linking.I tried to force conan2 to build catch2 from source by adding
--build=[catch2*]
to the command line. That however seems to be completely ignored by conan2.Logs
No response