Skip to content

Commit

Permalink
Nicer error in the compatibility plugin with custom compilers (#13328)
Browse files Browse the repository at this point in the history
* Nicer error when the compiler is not included in the supported_cppstd compilers

* Return an empty list, but warn the user about missing compatibility, which is the best of both worlds

* Add cppstd_compat test

* Fix GenConanfile import

* Fixup imports
  • Loading branch information
AbrilRBS authored Mar 8, 2023
1 parent 7db49cb commit 5019d08
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 1 deletion.
2 changes: 1 addition & 1 deletion conan/tools/build/cppstd.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ def default_cppstd(conanfile, compiler=None, compiler_version=None):

def supported_cppstd(conanfile, compiler=None, compiler_version=None):
"""
Get the a list of supported ``compiler.cppstd`` for the "conanfile.settings.compiler" and
Get a list of supported ``compiler.cppstd`` for the "conanfile.settings.compiler" and
"conanfile.settings.compiler_version" or for the parameters "compiler" and "compiler_version"
if specified.
Expand Down
4 changes: 4 additions & 0 deletions conans/client/graph/compatibility.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ def compatibility(conanfile):
# This file was generated by Conan. Remove this comment if you edit this file or Conan
# will destroy your changes.
from conan.tools.build import supported_cppstd
from conan.errors import ConanException
def cppstd_compat(conanfile):
Expand All @@ -36,6 +37,9 @@ def cppstd_compat(conanfile):
return []
base = dict(conanfile.settings.values_list)
cppstd_possible_values = supported_cppstd(conanfile)
if cppstd_possible_values is None:
conanfile.output.warning(f'No cppstd compatibility defined for compiler "{compiler}"')
return []
ret = []
for _cppstd in cppstd_possible_values:
if _cppstd is None or _cppstd == cppstd:
Expand Down
85 changes: 85 additions & 0 deletions conans/test/integration/extensions/test_cppstd_compat.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import textwrap

from conans.test.assets.genconanfile import GenConanfile
from conans.test.utils.tools import TestClient


def test_compatible_cppstd():
c = TestClient()
conanfile = textwrap.dedent("""
from conan import ConanFile
class Pkg(ConanFile):
name = "pkg"
version = "0.1"
settings = "os", "compiler"
def package_info(self):
self.output.info("PackageInfo!: Cppstd version: %s!"
% self.settings.compiler.cppstd)
""")
profile = textwrap.dedent("""
[settings]
os = Linux
compiler=gcc
compiler.version=12
compiler.libcxx=libstdc++
""")
c.save({"conanfile.py": conanfile,
"myprofile": profile})
# Create package with cppstd 17
c.run("create . -pr=myprofile -s compiler.cppstd=17")
package_id = "95dcfeb51c04968b4ee960ee393cf2c1ebcf7782"
assert f"pkg/0.1: Package '{package_id}' created" in c.out

# package can be used with a profile gcc cppstd20 falling back to 17
c.save({"conanfile.py": GenConanfile().with_require("pkg/0.1")})
c.run("install . -pr=myprofile -s compiler.cppstd=20")
assert f"Using compatible package '{package_id}'"
assert "pkg/0.1: PackageInfo!: Cppstd version: 17!" in c.out
c.assert_listed_binary({"pkg/0.1": (f"{package_id}", "Cache")})
assert "pkg/0.1: Already installed!" in c.out


def test_compatible_cppstd_missing_compiler():
c = TestClient()
settings_user = textwrap.dedent("""
compiler:
mycompiler:
version: ["12"]
libcxx: ["libstdc++"]
cppstd: [15, 17, 20]
""")
conanfile = textwrap.dedent("""
from conan import ConanFile
class Pkg(ConanFile):
name = "pkg"
version = "0.1"
settings = "os", "compiler"
def package_info(self):
self.output.info("PackageInfo!: Cppstd version: %s!"
% self.settings.compiler.cppstd)
""")
profile = textwrap.dedent("""
[settings]
os = Linux
compiler=mycompiler
compiler.version=12
compiler.libcxx=libstdc++
""")
c.save({"conanfile.py": conanfile,
"myprofile": profile})
c.save_home({"settings_user.yml": settings_user})
# Create package with cppstd 17
c.run("create . -pr=myprofile -s compiler.cppstd=17")
package_id = "51a90090adb1cbd330a64b4c3b3b32af809af4f9"
assert f"pkg/0.1: Package '{package_id}' created" in c.out

# package can't be used with cppstd 20 and fallback to 17, because mycompiler is not known
# to the default cppstd_compat function. Ensure that it does not break and warns the user
c.save({"conanfile.py": GenConanfile().with_require("pkg/0.1")})
c.run("install . -pr=myprofile -s compiler.cppstd=20", assert_error=True)
assert "Missing binary: pkg/0.1:b4b07859713551e8aac612f8080888c58b4711ae" in c.out
assert 'pkg/0.1: WARN: No cppstd compatibility defined for compiler "mycompiler"' in c.out

0 comments on commit 5019d08

Please sign in to comment.