diff --git a/conans/client/subsystems.py b/conans/client/subsystems.py index 3a1f23f47e8..25511f270f7 100644 --- a/conans/client/subsystems.py +++ b/conans/client/subsystems.py @@ -104,6 +104,8 @@ def deduce_subsystem(conanfile, scope): if scope.startswith("build"): if hasattr(conanfile, "settings_build"): the_os = conanfile.settings_build.get_safe("os") + if the_os is None: + raise ConanException("The 'build' profile must have a 'os' declared") subsystem = conanfile.settings_build.get_safe("os.subsystem") else: the_os = platform.system() # FIXME: Temporary fallback until 2.0 diff --git a/conans/test/integration/build_requires/profile_build_requires_test.py b/conans/test/integration/build_requires/profile_build_requires_test.py index de19da8a9c5..134c6b61cf9 100644 --- a/conans/test/integration/build_requires/profile_build_requires_test.py +++ b/conans/test/integration/build_requires/profile_build_requires_test.py @@ -197,6 +197,7 @@ def test_consumer_patterns_loop_error(): client = TestClient() profile_patterns = textwrap.dedent(""" + include(default) [tool_requires] tool1/1.0 tool2/1.0 @@ -208,12 +209,12 @@ def test_consumer_patterns_loop_error(): client.run("export tool1 --name=tool1 --version=1.0") client.run("export tool2 --name=tool2 --version=1.0") - with pytest.raises(Exception) as e: - client.run("install consumer --build=missing -pr:b=profile.txt -pr:h=profile.txt") - assert "graph loop" in str(e.value) + client.run("install consumer --build=missing -pr:b=profile.txt -pr:h=profile.txt", assert_error=True) + assert "graph loop" in client.out # we can fix it with the negation profile_patterns = textwrap.dedent(""" + include(default) [tool_requires] tool1/1.0 !tool1*:tool2/1.0 diff --git a/conans/test/integration/command/create_test.py b/conans/test/integration/command/create_test.py index 6921d78aa64..25fdfffe8cd 100644 --- a/conans/test/integration/command/create_test.py +++ b/conans/test/integration/command/create_test.py @@ -15,8 +15,6 @@ class CreateTest(unittest.TestCase): def test_dependencies_order_matches_requires(self): client = TestClient() - save(client.cache.default_profile_path, "") - save(client.cache.settings_path, "build_type: [Release, Debug]\narch: [x86]") client.save({"conanfile.py": GenConanfile()}) client.run("create . --name=pkga --version=0.1 --user=user --channel=testing") client.save({"conanfile.py": GenConanfile()}) diff --git a/conans/test/integration/command/upload/syncronize_test.py b/conans/test/integration/command/upload/syncronize_test.py index 975fa5a5112..fe3bdbd1dc3 100644 --- a/conans/test/integration/command/upload/syncronize_test.py +++ b/conans/test/integration/command/upload/syncronize_test.py @@ -15,7 +15,6 @@ class SynchronizeTest(unittest.TestCase): def test_upload(self): client = TestClient(servers={"default": TestServer()}, inputs=["admin", "password"]) - save(client.cache.default_profile_path, "") ref = RecipeReference.loads("hello/0.1@lasote/stable") files = {"conanfile.py": GenConanfile("hello", "0.1").with_exports("*"), "to_be_deleted.txt": "delete me", diff --git a/conans/test/integration/command/upload/upload_complete_test.py b/conans/test/integration/command/upload/upload_complete_test.py index e4dd44ff3fd..b585ac577cd 100644 --- a/conans/test/integration/command/upload/upload_complete_test.py +++ b/conans/test/integration/command/upload/upload_complete_test.py @@ -97,7 +97,6 @@ def _get_client(self, requester=None): servers["default"] = self.test_server test_client = TestClient(servers=servers, inputs=["lasote", "mypass"], requester_class=requester) - save(test_client.cache.default_profile_path, "") return test_client def test_upload_error(self): diff --git a/conans/test/integration/configuration/default_profile_test.py b/conans/test/integration/configuration/default_profile_test.py index 11f967f94aa..9546ed20635 100644 --- a/conans/test/integration/configuration/default_profile_test.py +++ b/conans/test/integration/configuration/default_profile_test.py @@ -19,7 +19,6 @@ def test_conanfile_txt_incomplete_profile(self): conanfile = GenConanfile() client = TestClient() - save(client.cache.default_profile_path, "") client.save({CONANFILE: conanfile}) client.run("create . --name=pkg --version=0.1 --user=lasote --channel=stable") @@ -165,7 +164,7 @@ def build(self): # Test with the 'default' profile env_variable = "env_variable=profile_default" - save(client.cache.default_profile_path, "[buildenv]\n" + env_variable) + save(client.cache.default_profile_path, "[settings]\nos=Windows\n[buildenv]\n" + env_variable) client.run("create . --name=name --version=version --user=user --channel=channel") self.assertIn(">>> " + env_variable, client.out) @@ -173,7 +172,7 @@ def build(self): tmp = temp_folder() env_variable = "env_variable=profile_environment" default_profile_path = os.path.join(tmp, 'env_profile') - save(default_profile_path, "[buildenv]\n" + env_variable) + save(default_profile_path, "[settings]\nos=Windows\n[buildenv]\n" + env_variable) with environment_update({'CONAN_DEFAULT_PROFILE': default_profile_path}): client.run("create . --name=name --version=version --user=user --channel=channel") self.assertIn(">>> " + env_variable, client.out) @@ -184,7 +183,7 @@ def build(self): self.assertFalse(os.path.isabs(rel_path)) default_profile_path = os.path.join(client.cache_folder, PROFILES_FOLDER, rel_path) - save(default_profile_path, "[buildenv]\n" + env_variable) + save(default_profile_path, "[settings]\nos=Windows\n[buildenv]\n" + env_variable) with environment_update({'CONAN_DEFAULT_PROFILE': rel_path}): client.run("create . --name=name --version=version --user=user --channel=channel") self.assertIn(">>> " + env_variable, client.out) diff --git a/conans/test/integration/graph/core/test_version_ranges.py b/conans/test/integration/graph/core/test_version_ranges.py index 929ec472c04..bb1fc8186b6 100644 --- a/conans/test/integration/graph/core/test_version_ranges.py +++ b/conans/test/integration/graph/core/test_version_ranges.py @@ -368,8 +368,6 @@ def test_mixed_user_channel(): def test_remote_version_ranges(): t = TestClient(default_server_user=True) - save(t.cache.default_profile_path, "") - save(t.cache.settings_path, "") t.save({"conanfile.py": GenConanfile()}) for v in ["0.1", "0.2", "0.3", "1.1", "1.1.2", "1.2.1", "2.1", "2.2.1"]: t.run(f"create . --name=dep --version={v}") @@ -406,8 +404,6 @@ def test_different_user_channel_resolved_correctly(): servers = OrderedDict([("server1", server1), ("server2", server2)]) client = TestClient(servers=servers, inputs=2*["admin", "password"]) - save(client.cache.default_profile_path, "") - save(client.cache.settings_path, "") client.save({"conanfile.py": GenConanfile()}) client.run("create . --name=lib --version=1.0 --user=conan --channel=stable") client.run("create . --name=lib --version=1.0 --user=conan --channel=testing") diff --git a/conans/test/integration/package_id/test_cache_compatibles.py b/conans/test/integration/package_id/test_cache_compatibles.py index 907de4847cb..fc8b4566a32 100644 --- a/conans/test/integration/package_id/test_cache_compatibles.py +++ b/conans/test/integration/package_id/test_cache_compatibles.py @@ -143,7 +143,7 @@ class Pkg(ConanFile): package_type = "application" settings = "os", "arch", "compiler", "build_type" """) - c.save({"conanfile.py": conanfile}) + c.save({"conanfile.py": conanfile, "profile_build": "[settings]\nos=Windows\narch=x86_64"}) os_ = "Windows" build_type = "Release" arch = "x86_64" @@ -155,9 +155,9 @@ class Pkg(ConanFile): c.run(f"create . -s os={os_} -s arch={arch} -s build_type={build_type} " f"-s compiler={compiler} " f"-s compiler.version={version} -s compiler.cppstd={cppstd} " - f"-s compiler.runtime={runtime}") + f"-s compiler.runtime={runtime} -pr:b=profile_build") package_id = c.created_package_id("app/1.0") - c.run(f"install --requires=app/1.0@ -s os={os_} -s arch={arch}") + c.run(f"install --requires=app/1.0@ -s os={os_} -s arch={arch} -pr:b=profile_build") assert "app/1.0: Main binary package 'e340edd75790e7156c595edebd3d98b10a2e091e' missing."\ f"Using compatible package '{package_id}'" @@ -178,7 +178,7 @@ def package_id(self): except: pass """) - c.save({"conanfile.py": conanfile}) + c.save({"conanfile.py": conanfile, "profile_build": "[settings]\nos=Windows\narch=x86_64"}) os_ = "Windows" build_type = "Release" arch = "x86_64" @@ -189,16 +189,16 @@ def package_id(self): c.run(f"create . -s os={os_} -s arch={arch} -s build_type={build_type} " f"-s compiler={compiler} " f"-s compiler.version={version} -s compiler.cppstd={cppstd} " - f"-s compiler.runtime={runtime}") + f"-s compiler.runtime={runtime} -pr:b=profile_build") package_id1 = c.created_package_id("app/1.0") c.run(f"create . -s os={os_} -s arch={arch} -s build_type={build_type} " f"-s compiler={compiler} " f"-s compiler.version={version} -s compiler.cppstd=17 " - f"-s compiler.runtime={runtime}") + f"-s compiler.runtime={runtime} -pr:b=profile_build") package_id2 = c.created_package_id("app/1.0") assert package_id1 == package_id2 # It does not depend on 'compiler.cppstd' - c.run(f"install --requires=app/1.0@ -s os={os_} -s arch={arch}") + c.run(f"install --requires=app/1.0@ -s os={os_} -s arch={arch} -pr:b=profile_build") assert "app/1.0: Main binary package 'e340edd75790e7156c595edebd3d98b10a2e091e' missing."\ f"Using compatible package '{package_id1}'" @@ -215,7 +215,7 @@ class Pkg(ConanFile): default_options = {"shared": False} settings = "os", "arch", "compiler", "build_type" """) - c.save({"conanfile.py": conanfile}) + c.save({"conanfile.py": conanfile, "profile_build": "[settings]\nos=Windows\narch=x86_64"}) os_ = "Windows" build_type = "Release" arch = "x86_64" @@ -226,14 +226,14 @@ class Pkg(ConanFile): c.run(f"create . -s os={os_} -s arch={arch} -s build_type={build_type} " f"-s compiler={compiler} " f"-s compiler.version={version} -s compiler.cppstd={cppstd} " - f"-s compiler.runtime={runtime}") + f"-s compiler.runtime={runtime} -pr:b=profile_build") package_id1 = c.created_package_id("mylib/1.0") # Try to install with cppstd 14, it will find cppstd 17 as compatible c.run(f"install --requires=mylib/1.0@ -s os={os_} -s arch={arch} -s build_type={build_type} " f"-s compiler={compiler} " f"-s compiler.version={version} -s compiler.cppstd=14 " - f"-s compiler.runtime={runtime}") + f"-s compiler.runtime={runtime} -pr:b=profile_build") assert "mylib/1.0: Main binary package 'e340edd75790e7156c595edebd3d98b10a2e091e' missing."\ f"Using compatible package '{package_id1}'" diff --git a/conans/test/integration/toolchains/cmake/test_cmake.py b/conans/test/integration/toolchains/cmake/test_cmake.py index fc3cef0a501..86ae90d270d 100644 --- a/conans/test/integration/toolchains/cmake/test_cmake.py +++ b/conans/test/integration/toolchains/cmake/test_cmake.py @@ -1,5 +1,4 @@ import textwrap - from conans.test.utils.tools import TestClient diff --git a/conans/test/integration/toolchains/env/test_buildenv.py b/conans/test/integration/toolchains/env/test_buildenv.py new file mode 100644 index 00000000000..bc6a4047094 --- /dev/null +++ b/conans/test/integration/toolchains/env/test_buildenv.py @@ -0,0 +1,39 @@ +import platform +import textwrap + +import pytest + +from conans.test.utils.tools import TestClient + + +@pytest.mark.skipif(platform.system() != "Windows", reason="Fails on windows") +def test_crossbuild_windows_incomplete(): + client = TestClient() + conanfile = textwrap.dedent(""" + from conan import ConanFile + from conan.tools.cmake import CMake + class Pkg(ConanFile): + name = "pkg" + version = "0.1" + settings = "os", "compiler", "build_type", "arch" + generators = "CMakeToolchain" + def build(self): + self.run("dir c:") + """) + build_profile = textwrap.dedent(""" + [settings] + arch=x86_64 + """) + client.save({"conanfile.py": conanfile, "build_profile": build_profile}) + client.run("create . -pr:b=build_profile", assert_error=True) + assert "'.' is not recognized as an internal or external command" not in client.out + assert "ERROR: The 'build' profile must have a 'os' declared" in client.out + + build_profile = textwrap.dedent(""" + [settings] + os=Windows + arch=x86_64 + """) + client.save({"conanfile.py": conanfile, "build_profile": build_profile}) + client.run("create . -pr:b=build_profile") + assert " ." in client.out diff --git a/conans/test/unittests/client/profile_loader/profile_loader_test.py b/conans/test/unittests/client/profile_loader/profile_loader_test.py index dfdbf72c7ea..28c9316940f 100644 --- a/conans/test/unittests/client/profile_loader/profile_loader_test.py +++ b/conans/test/unittests/client/profile_loader/profile_loader_test.py @@ -6,7 +6,7 @@ from conans.client.profile_loader import _ProfileParser, ProfileLoader from conans.errors import ConanException from conans.model.recipe_ref import RecipeReference -from conans.test.utils.mocks import ConanFileMock +from conans.test.utils.mocks import ConanFileMock, MockSettings from conans.test.utils.test_files import temp_folder from conans.util.files import save @@ -212,11 +212,15 @@ def test_profile_buildenv(): buildenv = profile.buildenv env = buildenv.get_profile_env(None) conanfile = ConanFileMock() + conanfile.settings_build = MockSettings({"os": "Linux", "arch": "x86_64"}) env_vars = env.vars(conanfile) assert env_vars.get("MyVar1") == "My Value; 11 MyValue12" - # Mock is never Windows path assert env_vars.get("MyPath1") == "/some/path11:/other path/path12" + conanfile.settings_build = MockSettings({"os": "Windows", "arch": "x86_64"}) + env_vars = env.vars(conanfile) + assert env_vars.get("MyPath1") == "/some/path11;/other path/path12" + @pytest.mark.parametrize("conf_name", [ "core.doesnotexist:never", diff --git a/conans/test/unittests/client/toolchain/autotools/autotools_toolchain_test.py b/conans/test/unittests/client/toolchain/autotools/autotools_toolchain_test.py index c0eae5f87fe..c9cb62f6d26 100644 --- a/conans/test/unittests/client/toolchain/autotools/autotools_toolchain_test.py +++ b/conans/test/unittests/client/toolchain/autotools/autotools_toolchain_test.py @@ -135,6 +135,7 @@ def test_ndebug(): conanfile = ConanFileMock() for bt in ['Release', 'RelWithDebInfo', 'MinSizeRel']: conanfile.settings = MockSettings({"build_type": bt}) + conanfile.settings_build = MockSettings({"os": "Linux", "arch": "x86_64"}) be = AutotoolsToolchain(conanfile) assert be.ndebug == "NDEBUG" env = be.vars() @@ -166,8 +167,10 @@ def test_ndebug(): def test_libcxx(config): compiler, libcxx, expected_flag = config conanfile = ConanFileMock() + the_os = "Linux" if compiler != "apple-clang" else "Macos" conanfile.settings = MockSettings( - {"build_type": "Release", + {"os": the_os, + "build_type": "Release", "arch": "x86", "compiler": compiler, "compiler.libcxx": libcxx, @@ -184,7 +187,8 @@ def test_libcxx(config): def test_cxx11_abi_define(): conanfile = ConanFileMock() conanfile.settings = MockSettings( - {"build_type": "Release", + {"os": "Linux", + "build_type": "Release", "arch": "x86", "compiler": "gcc", "compiler.libcxx": "libstdc++", @@ -197,7 +201,8 @@ def test_cxx11_abi_define(): assert "-D_GLIBCXX_USE_CXX11_ABI=0" in env["CPPFLAGS"] conanfile.settings = MockSettings( - {"build_type": "Release", + {"os": "Linux", + "build_type": "Release", "arch": "x86", "compiler": "gcc", "compiler.libcxx": "libstdc++11", diff --git a/conans/test/unittests/tools/env/test_env.py b/conans/test/unittests/tools/env/test_env.py index 362ac9653ee..b24ef4da6b0 100644 --- a/conans/test/unittests/tools/env/test_env.py +++ b/conans/test/unittests/tools/env/test_env.py @@ -188,7 +188,9 @@ def env(): env.append("MYVAR1", "MyValue1B") env.define("MyVar2", "MyNewValue2") - env = env.vars(ConanFileMock()) + conanfile = ConanFileMock() + conanfile.settings_build = MockSettings({"os": "Windows", "arch": "x86_64"}) + env = env.vars(conanfile) env._subsystem = WINDOWS return env diff --git a/conans/test/utils/mocks.py b/conans/test/utils/mocks.py index b8b3deede32..0a141f25117 100644 --- a/conans/test/utils/mocks.py +++ b/conans/test/utils/mocks.py @@ -103,14 +103,14 @@ def run(self, *args, **kwargs): class ConanFileMock(ConanFile): - def __init__(self, shared=None, ): + def __init__(self, shared=None): self.display_name = "" self._conan_node = None self.command = None self._commands = [] self.path = None self.settings = None - self.settings_build = MockSettings({}) + self.settings_build = MockSettings({"os": "Linux", "arch": "x86_64"}) self.options = Options() if shared is not None: self.options = namedtuple("options", "shared")(shared)