diff --git a/conans/test/assets/autotools.py b/conans/test/assets/autotools.py index 473b291d252..96c0559a3c6 100644 --- a/conans/test/assets/autotools.py +++ b/conans/test/assets/autotools.py @@ -55,12 +55,12 @@ def gen_makefile(**context): {% for lib in libs %} {%- set link_libs.str = link_libs.str + ' -l' + lib|string %} lib{{lib}}.a: {{lib}}.o - $(AR) rcs lib{{lib}}.a {{lib}}.o + $(AR) rcs lib{{lib}}.a {{lib}}.o {%if static_runtime%}--static{%endif%} {% endfor %} {% for s in apps %} {{s}}: {{s}}.o libs - $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(LDFLAGS) -o {{s}} {{s}}.o $(LIBS) {{link_libs.str}} -L. + $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(LDFLAGS) -o {{s}} {{s}}.o $(LIBS) {{link_libs.str}} -L. {%if static_runtime%}--static{%endif%} {% endfor %} """) diff --git a/conans/test/conftest.py b/conans/test/conftest.py index 07905171fa5..5a871683672 100644 --- a/conans/test/conftest.py +++ b/conans/test/conftest.py @@ -92,6 +92,13 @@ "exe": "mingw32-make", "system": {"path": {'Windows': "C:/msys64/mingw32/bin"}}, }, + 'ucrt64': { + "disabled": True, + "platform": "Windows", + "default": "system", + "exe": "mingw32-make", + "system": {"path": {'Windows': "C:/msys64/ucrt64/bin"}}, + }, 'mingw64': { "platform": "Windows", "default": "system", @@ -104,6 +111,20 @@ "exe": "make", "system": {"path": {'Windows': "C:/msys64/usr/bin"}}, }, + 'msys2_clang64': { + "disabled": True, + "platform": "Windows", + "default": "system", + "exe": "mingw32-make", + "system": {"path": {'Windows': "C:/msys64/clang64/bin"}}, + }, + 'msys2_mingw64_clang64': { + "disabled": True, + "platform": "Windows", + "default": "system", + "exe": "mingw32-make", + "system": {"path": {'Windows': "C:/msys64/mingw64/bin"}}, + }, 'cygwin': { "platform": "Windows", "default": "system", @@ -156,6 +177,8 @@ def update(d, u): tools_environments = { 'mingw32': {'Windows': {'MSYSTEM': 'MINGW32'}}, 'mingw64': {'Windows': {'MSYSTEM': 'MINGW64'}}, + 'ucrt64': {'Windows': {'MSYSTEM': 'UCRT64'}}, + 'msys2_clang64': {"Windows": {"MSYSTEM": "CLANG64"}}, 'android_ndk': {'Darwin': {'TEST_CONAN_ANDROID_NDK': '/usr/local/share/android-ndk'}} } diff --git a/conans/test/functional/subsystems_build_test.py b/conans/test/functional/subsystems_build_test.py index d8c6ac4ee03..60ab0f080aa 100644 --- a/conans/test/functional/subsystems_build_test.py +++ b/conans/test/functional/subsystems_build_test.py @@ -1,11 +1,13 @@ import platform +import tempfile import pytest import textwrap +from conans.client.tools import environment_append from conans.test.assets.autotools import gen_makefile from conans.test.assets.sources import gen_function_cpp -from conans.test.functional.utils import check_exe_run +from conans.test.functional.utils import check_exe_run, check_vs_runtime from conans.test.utils.tools import TestClient @@ -14,12 +16,24 @@ class TestSubsystems: @pytest.mark.tool_msys2 def test_msys2_available(self): + """ + Msys2 needs to be installed: + - Go to https://www.msys2.org/, download the exe installer and run it + - Follow instructions in https://www.msys2.org/ to update the package DB + - Install msys2 autotools "pacman -S autotools" + - Make sure the entry in conftest_user.py of msys2 points to the right location + """ client = TestClient() client.run_command('uname') assert "MSYS" in client.out @pytest.mark.tool_cygwin def test_cygwin_available(self): + """ Cygwin is necessary + - Install from https://www.cygwin.com/install.html, use the default packages + - Install automake 1.16, gcc-g++, make and binutils packages (will add autoconf and more) + - Make sure that the path in conftest_user.py is pointing to cygwin "bin" folder + """ client = TestClient() client.run_command('uname') assert "CYGWIN" in client.out @@ -27,13 +41,36 @@ def test_cygwin_available(self): @pytest.mark.tool_msys2 @pytest.mark.tool_mingw32 def test_mingw32_available(self): + """ Mingw32 needs to be installed. We use msys2, don't know if others work + - Inside msys2, install pacman -S mingw-w64-i686-toolchain (all pkgs) + """ client = TestClient() client.run_command('uname') assert "MINGW32_NT" in client.out + @pytest.mark.tool_msys2 + @pytest.mark.tool_ucrt64 + def test_ucrt64_available(self): + """ ucrt64 needs to be installed. We use msys2, don't know if others work + - Inside msys2, install pacman -S mingw-w64-ucrt-x86_64-toolchain (all pkgs) + """ + client = TestClient() + client.run_command('uname') + assert "MINGW64_NT" in client.out + + @pytest.mark.tool_msys2 + @pytest.mark.tool_msys2_clang64 + def test_clang64_available(self): + client = TestClient() + client.run_command('uname') + assert "MINGW64_NT" in client.out + @pytest.mark.tool_msys2 @pytest.mark.tool_mingw64 def test_mingw64_available(self): + """ Mingw64 needs to be installed. We use msys2, don't know if others work + - Inside msys2, install pacman -S mingw-w64-x86_64-toolchain (all pkgs) + """ client = TestClient() client.run_command('uname') assert "MINGW64_NT" in client.out @@ -48,77 +85,136 @@ def test_tool_not_available(self): class TestSubsystemsBuild: @staticmethod - def _build(client): - makefile = gen_makefile(apps=["app"]) + def _build(client, static_runtime=None): + makefile = gen_makefile(apps=["app"], static_runtime=static_runtime) main_cpp = gen_function_cpp(name="main") client.save({"Makefile": makefile, "app.cpp": main_cpp}) client.run_command("make") client.run_command("app") + @pytest.mark.parametrize("static", [True, False]) @pytest.mark.tool_msys2 - def test_msys(self): + def test_msys2(self, static): """ native MSYS environment, binaries depend on MSYS runtime (msys-2.0.dll) + Install: + - pacman -S gcc posix-compatible, intended to be run only in MSYS environment (not in pure Windows) """ client = TestClient() - # pacman -S gcc - self._build(client) - - check_exe_run(client.out, "main", "gcc", None, "Debug", "x86_64", None) + self._build(client, static_runtime=static) - assert "__MINGW32__" not in client.out - assert "__MINGW64__" not in client.out - assert "__MSYS__" in client.out + check_exe_run(client.out, "main", "gcc", None, "Debug", "x86_64", None, subsystem="msys2") + assert "_M_X64" not in client.out + # TODO: Do not hardcode the visual version + check_vs_runtime("app.exe", client, "15", "Debug", static_runtime=static, + subsystem="msys2") + @pytest.mark.parametrize("static", [True, False]) @pytest.mark.tool_msys2 @pytest.mark.tool_mingw64 - def test_mingw64(self): + def test_mingw64(self, static): """ - 64-bit GCC, binaries for generic Windows (no dependency on MSYS runtime) + This will work if you installed the Mingw toolchain inside msys2 as TestSubystems above + 64-bit GCC, binaries """ client = TestClient() # pacman -S mingw-w64-x86_64-gcc - self._build(client) + self._build(client, static_runtime=static) + + check_exe_run(client.out, "main", "gcc", None, "Debug", "x86_64", None, subsystem="mingw64") + # it also defines the VS 64 bits macro + assert "main _M_X64 defined" in client.out + check_vs_runtime("app.exe", client, "15", "Debug", static_runtime=static, + subsystem="mingw64") - check_exe_run(client.out, "main", "gcc", None, "Debug", "x86_64", None) + @pytest.mark.parametrize("static", [True, False]) + @pytest.mark.tool_msys2 + @pytest.mark.tool_msys2_clang64 + def test_msys2_clang64(self, static): + """ + in msys2 + $ pacman -S mingw-w64-x86_64-clang (NO, this is the mingw variant in ming64) + $ pacman -S mingw-w64-clang-x86_64-toolchain + """ + client = TestClient() + self._build(client, static_runtime=static) - assert "__MINGW64__" in client.out - assert "__CYGWIN__" not in client.out - assert "__MSYS__" not in client.out + check_exe_run(client.out, "main", "clang", None, "Debug", "x86_64", None, + subsystem="mingw64") + # it also defines the VS 64 bits macro + assert "main _M_X64 defined" in client.out + check_vs_runtime("app.exe", client, "15", "Debug", static_runtime=static, + subsystem="clang64") + @pytest.mark.tool_msys2 + @pytest.mark.tool_msys2_mingw64_clang64 + def test_msys2_mingw64_clang64(self): + """ + in msys2 + $ pacman -S mingw-w64-x86_64-clang + $ pacman -S mingw-w64-clang-x86_64-toolchain (NO, this is the clang) + """ + client = TestClient() + static = False # This variant needs --static-glibc -static-libstdc++ (weird) to link static + # Need to redefine CXX otherwise is gcc + with environment_append({"CXX": "clang++"}): + self._build(client, static_runtime=static) + + check_exe_run(client.out, "main", "clang", None, "Debug", "x86_64", None, + subsystem="mingw64") + # it also defines the VS 64 bits macro + assert "main _M_X64 defined" in client.out + check_vs_runtime("app.exe", client, "15", "Debug", static_runtime=static, + subsystem="mingw64") + + @pytest.mark.parametrize("static", [True, False]) @pytest.mark.tool_msys2 @pytest.mark.tool_mingw32 - def test_mingw32(self): + def test_mingw32(self, static): """ + This will work if you installed the Mingw toolchain inside msys2 as TestSubystems above 32-bit GCC, binaries for generic Windows (no dependency on MSYS runtime) """ client = TestClient() # pacman -S mingw-w64-i686-gcc - self._build(client) + self._build(client, static_runtime=static) + + check_exe_run(client.out, "main", "gcc", None, "Debug", "x86", None, subsystem="mingw32") + # It also defines the VS flag + assert "main _M_IX86 defined" in client.out + check_vs_runtime("app.exe", client, "15", "Debug", static_runtime=static, + subsystem="mingw32") - check_exe_run(client.out, "main", "gcc", None, "Debug", "x86", None) + @pytest.mark.parametrize("static", [True, False]) + @pytest.mark.tool_msys2 + @pytest.mark.tool_ucrt64 + def test_ucrt64(self, static): + """ + This will work if you installed the Mingw toolchain inside msys2 as TestSubystems above + """ + client = TestClient() - assert "__MINGW32__" in client.out - assert "__CYGWIN__" not in client.out - assert "__MSYS__" not in client.out + self._build(client, static_runtime=static) + check_exe_run(client.out, "main", "gcc", None, "Debug", "x86_64", None, subsystem="mingw32") + # it also defines the VS macro + assert "main _M_X64 defined" in client.out + check_vs_runtime("app.exe", client, "15", "Debug", static_runtime=static, + subsystem="ucrt64") + @pytest.mark.parametrize("static", [True, False]) @pytest.mark.tool_cygwin - def test_cygwin(self): + def test_cygwin(self, static): """ Cygwin environment, binaries depend on Cygwin runtime (cygwin1.dll) posix-compatible, intended to be run only in Cygwin environment (not in pure Windows) """ client = TestClient() - # install "gcc-c++" and "make" packages - self._build(client) - check_exe_run(client.out, "main", "gcc", None, "Debug", "x86_64", None) - - assert "__CYGWIN__" in client.out - assert "__MINGW32__" not in client.out - assert "__MINGW64__" not in client.out - assert "__MSYS__" not in client.out + self._build(client, static_runtime=static) + check_exe_run(client.out, "main", "gcc", None, "Debug", "x86_64", None, subsystem="cygwin") + check_vs_runtime("app.exe", client, "15", "Debug", static_runtime=static, + subsystem="cygwin") @pytest.mark.skipif(platform.system() != "Windows", reason="Tests Windows Subsystems") @@ -157,12 +253,8 @@ def test_msys(self): client = TestClient() # pacman -S gcc self._build(client) - - check_exe_run(client.out, "main", "gcc", None, "Debug", "x86_64", None) - - assert "__MINGW32__" not in client.out - assert "__MINGW64__" not in client.out - assert "__MSYS__" in client.out + check_exe_run(client.out, "main", "gcc", None, "Debug", "x86_64", None, subsystem="msys2") + check_vs_runtime("app.exe", client, "15", "Debug", subsystem="msys2") @pytest.mark.tool_msys2 @pytest.mark.tool_mingw64 @@ -173,12 +265,8 @@ def test_mingw64(self): client = TestClient() # pacman -S mingw-w64-x86_64-gcc self._build(client) - - check_exe_run(client.out, "main", "gcc", None, "Debug", "x86_64", None) - - assert "__MINGW64__" in client.out - assert "__CYGWIN__" not in client.out - assert "__MSYS__" not in client.out + check_exe_run(client.out, "main", "gcc", None, "Debug", "x86_64", None, subsystem="mingw64") + check_vs_runtime("app.exe", client, "15", "Debug", subsystem="mingw64") @pytest.mark.tool_msys2 @pytest.mark.tool_mingw32 @@ -189,110 +277,162 @@ def test_mingw32(self): client = TestClient() # pacman -S mingw-w64-i686-gcc self._build(client) - - check_exe_run(client.out, "main", "gcc", None, "Debug", "x86", None) - - assert "__MINGW32__" in client.out - assert "__CYGWIN__" not in client.out - assert "__MSYS__" not in client.out + check_exe_run(client.out, "main", "gcc", None, "Debug", "x86", None, subsystem="mingw32") + check_vs_runtime("app.exe", client, "15", "Debug", subsystem="mingw32") @pytest.mark.tool_cygwin def test_cygwin(self): """ Cygwin environment, binaries depend on Cygwin runtime (cygwin1.dll) posix-compatible, intended to be run only in Cygwin environment (not in pure Windows) + # install autotools, autoconf, libtool, "gcc-c++" and "make" packages """ client = TestClient() - # install "gcc-c++" and "make" packages self._build(client) - check_exe_run(client.out, "main", "gcc", None, "Debug", "x86_64", None) - - assert "__CYGWIN__" in client.out - assert "__MINGW32__" not in client.out - assert "__MINGW64__" not in client.out - assert "__MSYS__" not in client.out + check_exe_run(client.out, "main", "gcc", None, "Debug", "x86_64", None, subsystem="cygwin") + check_vs_runtime("app.exe", client, "15", "Debug", subsystem="cygwin") @pytest.mark.skipif(platform.system() != "Windows", reason="Tests Windows Subsystems") class TestSubsystemsCMakeBuild: + """ These tests are running the CMake INSIDE THE subsystem, not the Windows native one + The results are basically the same if CMake is outside the subsystem, but it is NOT + enough to define CMAKE_CXX_COMPILER full path to the compiler, but it must be in the path + + """ cmakelists = textwrap.dedent(""" - cmake_minimum_required(VERSION 2.8) - project(app) + cmake_minimum_required(VERSION 3.15) + project(app CXX) + message(STATUS "MYCMAKE VERSION=${CMAKE_VERSION}") add_executable(app main.cpp) """) - def _build(self, client, generator="Unix Makefiles"): + def _build(self, client, generator="Unix Makefiles", compiler=None, toolset=None): main_cpp = gen_function_cpp(name="main") client.save({"CMakeLists.txt": self.cmakelists, "main.cpp": main_cpp}) - client.run_command("cmake " - " -DCMAKE_C_FLAGS=\"-Wl,-verbose\"" - " -DCMAKE_CXX_FLAGS=\"-Wl,-verbose\"" - " -DCMAKE_SH=\"CMAKE_SH-NOTFOUND\" -G \"%s\" ." % generator) + cmake_compiler = "" + if compiler: + cmake_compiler += " -DCMAKE_C_COMPILER={}".format(compiler) + compilerpp = "clang++" if compiler == "clang" else "g++" + cmake_compiler += " -DCMAKE_CXX_COMPILER={}".format(compilerpp) + cmake_compiler += " -DCMAKE_RC_COMPILER={}".format(compiler) + toolset = "-T {}".format(toolset) if toolset else "" + client.run_command("cmake {} {}" + " -DCMAKE_SH=\"CMAKE_SH-NOTFOUND\" -G \"{}\" .".format(cmake_compiler, + toolset, + generator)) client.run_command("cmake --build .") - client.run_command("app") + app = "app" if "Visual" not in generator else r"Debug\app" + client.run_command(app) @pytest.mark.tool_msys2 def test_msys(self): """ - native MSYS environment, binaries depend on MSYS runtime (msys-2.0.dll) - posix-compatible, intended to be run only in MSYS environment (not in pure Windows) + pacman -S cmake """ client = TestClient() - # pacman -S gcc self._build(client) - - check_exe_run(client.out, "main", "gcc", None, "Debug", "x86_64", None) - - assert "__MINGW32__" not in client.out - assert "__MINGW64__" not in client.out - assert "__MSYS__" in client.out + check_exe_run(client.out, "main", "gcc", None, "Debug", "x86_64", None, subsystem="msys2") + check_vs_runtime("app.exe", client, "15", "Debug", subsystem="msys2") @pytest.mark.tool_msys2 @pytest.mark.tool_mingw64 def test_mingw64(self): """ - 64-bit GCC, binaries for generic Windows (no dependency on MSYS runtime) + $ pacman -S mingw-w64-x86_64-cmake """ client = TestClient() - # pacman -S mingw-w64-x86_64-gcc self._build(client, generator="MinGW Makefiles") + check_exe_run(client.out, "main", "gcc", None, "Debug", "x86_64", None, subsystem="mingw64") + check_vs_runtime("app.exe", client, "15", "Debug", subsystem="mingw64") - check_exe_run(client.out, "main", "gcc", None, "Debug", "x86_64", None) + @pytest.mark.tool_msys2 + @pytest.mark.tool_msys2_clang64 + @pytest.mark.skip(reason="This doesn't work, seems CMake issue") + def test_msys2_clang64(self): + """ + FAILS WITH: + System is unknown to cmake, create: + Platform/MINGW64_NT-10.0-19044 to use this system, + """ + client = TestClient() + self._build(client, generator="Unix Makefiles") + check_exe_run(client.out, "main", "clang", None, "Debug", "x86_64", None, + subsystem="mingw64") + check_vs_runtime("app.exe", client, "15", "Debug", subsystem="clang64") - assert "__MINGW64__" in client.out - assert "__CYGWIN__" not in client.out - assert "__MSYS__" not in client.out + @pytest.mark.tool_msys2 + @pytest.mark.tool_msys2_clang64 + @pytest.mark.tool_cmake(version="3.19") + def test_msys2_clang64_external(self): + """ + Exactly the same as the previous tests, but with a native cmake 3.19 (higher priority) + """ + client = TestClient() + self._build(client) + assert "MYCMAKE VERSION=3.19" in client.out + check_exe_run(client.out, "main", "clang", None, "Debug", "x86_64", None, + subsystem="mingw64") + check_vs_runtime("app.exe", client, "15", "Debug", subsystem="clang64") + + @pytest.mark.tool_msys2 + @pytest.mark.tool_msys2_mingw64_clang64 + def test_msys2_mingw64_clang64(self): + """ + """ + client = TestClient() + # IMPORTANT: Need to redefine the CXX, otherwise CMake will use GCC by default + with environment_append({"CXX": "clang++"}): + self._build(client, generator="MinGW Makefiles") + check_exe_run(client.out, "main", "clang", None, "Debug", "x86_64", None, + subsystem="mingw64") + check_vs_runtime("app.exe", client, "15", "Debug", subsystem="mingw64") @pytest.mark.tool_msys2 @pytest.mark.tool_mingw32 def test_mingw32(self): """ - 32-bit GCC, binaries for generic Windows (no dependency on MSYS runtime) + $ pacman -S mingw-w64-i686-cmake """ client = TestClient() - # pacman -S mingw-w64-i686-gcc self._build(client, generator="MinGW Makefiles") - - check_exe_run(client.out, "main", "gcc", None, "Debug", "x86", None) - - assert "__MINGW32__" in client.out - assert "__CYGWIN__" not in client.out - assert "__MSYS__" not in client.out + check_exe_run(client.out, "main", "gcc", None, "Debug", "x86", None, subsystem="mingw32") + check_vs_runtime("app.exe", client, "15", "Debug", subsystem="mingw32") @pytest.mark.tool_cygwin def test_cygwin(self): """ - Cygwin environment, binaries depend on Cygwin runtime (cygwin1.dll) - posix-compatible, intended to be run only in Cygwin environment (not in pure Windows) + Needs to install cmake from the cygwin setup.exe """ client = TestClient() # install "gcc-c++" and "make" packages self._build(client) - check_exe_run(client.out, "main", "gcc", None, "Debug", "x86_64", None) + check_exe_run(client.out, "main", "gcc", None, "Debug", "x86_64", None, subsystem="cygwin") + check_vs_runtime("app.exe", client, "15", "Debug", subsystem="cygwin") + + @pytest.mark.tool_clang + def test_clang(self): + """ + native, LLVM/Clang compiler + Installing the binary from LLVM site + https://github.com/llvm/llvm-project/releases/tag/llvmorg-14.0.6 + """ + client = TestClient() + self._build(client, generator="Ninja", compiler="clang") + check_exe_run(client.out, "main", "clang", None, "Debug", "x86_64", None, subsystem=None) + check_vs_runtime("app.exe", client, "15", "Debug", subsystem=None) - assert "__CYGWIN__" in client.out - assert "__MINGW32__" not in client.out - assert "__MINGW64__" not in client.out - assert "__MSYS__" not in client.out + @pytest.mark.tool_cmake(version="3.23") + @pytest.mark.tool_visual_studio(version="17") + def test_vs_clang(self): + """ + native, LLVM/Clang compiler installed with VS 2022 -T ClangCL + """ + # IMPORTANT: VS CLang not found if in another unit + folder = tempfile.mkdtemp(suffix='conans') + client = TestClient(current_folder=folder) + self._build(client, generator="Visual Studio 17 2022", toolset="ClangCL") + check_exe_run(client.out, "main", "clang", None, "Debug", "x86_64", None, subsystem=None) + check_vs_runtime("Debug/app.exe", client, "15", "Debug", subsystem=None) diff --git a/conans/test/functional/toolchains/cmake/test_cmake.py b/conans/test/functional/toolchains/cmake/test_cmake.py index 0c38395fbc8..e84fc0981d1 100644 --- a/conans/test/functional/toolchains/cmake/test_cmake.py +++ b/conans/test/functional/toolchains/cmake/test_cmake.py @@ -350,7 +350,7 @@ def _verify_out(marker=">>"): "MYVAR_CONFIG": "MYVAR_{}".format(build_type.upper()), "MYDEFINE": "MYDEF_VALUE", "MYDEFINE_CONFIG": "MYDEF_{}".format(build_type.upper()) - }) + }, subsystem="mingw64") self._modify_code() time.sleep(2) diff --git a/conans/test/functional/toolchains/cmake/test_ninja.py b/conans/test/functional/toolchains/cmake/test_ninja.py index fbd7df03f59..0a15f7d9eab 100644 --- a/conans/test/functional/toolchains/cmake/test_ninja.py +++ b/conans/test/functional/toolchains/cmake/test_ninja.py @@ -171,7 +171,8 @@ def test_locally_build_gcc(build_type, shared, client): client.run_command("myapp.exe") # TODO: Need full gcc version check - check_exe_run(client.out, ["main", "hello"], "gcc", None, build_type, "x86_64", cppstd=None) + check_exe_run(client.out, ["main", "hello"], "gcc", None, build_type, "x86_64", cppstd=None, + subsystem="mingw64") @pytest.mark.skipif(platform.system() != "Darwin", reason="Requires apple-clang") diff --git a/conans/test/functional/toolchains/gnu/autotools/test_basic.py b/conans/test/functional/toolchains/gnu/autotools/test_basic.py index 3d4a41f96a1..b7c507c21fe 100644 --- a/conans/test/functional/toolchains/gnu/autotools/test_basic.py +++ b/conans/test/functional/toolchains/gnu/autotools/test_basic.py @@ -53,11 +53,12 @@ def build(self): client.run("build .") client.run_command("./main") cxx11_abi = 0 if platform.system() == "Linux" else None - check_exe_run(client.out, "main", "gcc", None, "Release", "x86_64", None, cxx11_abi=cxx11_abi) + compiler = "gcc" if platform.system() == "Linux" else "clang" + check_exe_run(client.out, "main", compiler, None, "Release", "x86_64", None, cxx11_abi=cxx11_abi) assert "hello/0.1: Hello World Release!" in client.out -def build_windows_subsystem(profile, make_program): +def build_windows_subsystem(profile, make_program, subsystem): """ The AutotoolsDeps can be used also in pure Makefiles, if the makefiles follow the Autotools conventions """ @@ -99,7 +100,7 @@ def build(self): client.run_command(cmd) client.run_command("app") # TODO: fill compiler version when ready - check_exe_run(client.out, "main", "gcc", None, "Release", "x86_64", None) + check_exe_run(client.out, "main", "gcc", None, "Release", "x86_64", None, subsystem=subsystem) assert "hello/0.1: Hello World Release!" in client.out client.save({"app.cpp": gen_function_cpp(name="main", msg="main2", @@ -111,7 +112,8 @@ def build(self): client.run("build .") client.run_command("app") # TODO: fill compiler version when ready - check_exe_run(client.out, "main2", "gcc", None, "Release", "x86_64", None, cxx11_abi=0) + check_exe_run(client.out, "main2", "gcc", None, "Release", "x86_64", None, cxx11_abi=0, + subsystem=subsystem) assert "hello/0.1: Hello World Release!" in client.out return client.out @@ -129,10 +131,7 @@ def test_autotoolsdeps_cygwin(): arch=x86_64 build_type=Release """) - out = build_windows_subsystem(gcc, make_program="make") - assert "__MSYS__" not in out - assert "MINGW" not in out - assert "main2 __CYGWIN__1" in out + build_windows_subsystem(gcc, make_program="make", subsystem="cygwin") @pytest.mark.tool_mingw64 @@ -147,13 +146,13 @@ def test_autotoolsdeps_mingw_msys(): arch=x86_64 build_type=Release """) - out = build_windows_subsystem(gcc, make_program="mingw32-make") - assert "__MSYS__" not in out - assert "main2 __MINGW64__1" in out + build_windows_subsystem(gcc, make_program="mingw32-make", subsystem="mingw64") @pytest.mark.tool_msys2 @pytest.mark.skipif(platform.system() != "Windows", reason="Needs windows") +# If we use the cmake inside msys2, it fails, so better force our own cmake +@pytest.mark.tool_cmake def test_autotoolsdeps_msys(): gcc = textwrap.dedent(""" [settings] @@ -165,11 +164,7 @@ def test_autotoolsdeps_msys(): arch=x86_64 build_type=Release """) - out = build_windows_subsystem(gcc, make_program="make") - # Msys2 is a rewrite of Msys, using Cygwin - assert "MINGW" not in out - assert "main2 __MSYS__1" in out - assert "main2 __CYGWIN__1" in out + build_windows_subsystem(gcc, make_program="make", subsystem="msys2") @pytest.mark.skipif(platform.system() not in ["Linux", "Darwin"], reason="Requires Autotools") diff --git a/conans/test/functional/utils.py b/conans/test/functional/utils.py index 9fe753eabe5..b4d1217357b 100644 --- a/conans/test/functional/utils.py +++ b/conans/test/functional/utils.py @@ -2,18 +2,64 @@ def check_vs_runtime(artifact, client, vs_version, build_type, architecture="amd64", - static_runtime=False): + static_runtime=False, subsystem=None): vcvars = vcvars_command(version=vs_version, architecture=architecture) normalized_path = artifact.replace("/", "\\") static = artifact.endswith(".a") or artifact.endswith(".lib") if not static: cmd = ('%s && dumpbin /nologo /dependents "%s"' % (vcvars, normalized_path)) client.run_command(cmd) - if static_runtime: + if subsystem: + assert "KERNEL32.dll" in client.out + if subsystem in ("mingw32", "mingw64"): + assert "msvcrt.dll" in client.out + if static_runtime: + assert "libstdc++-6.dll" not in client.out + else: + assert "libstdc++-6.dll" in client.out + if subsystem == "mingw32": + if static_runtime: + assert "libgcc_s_dw2-1.dll" not in client.out + else: + assert "libgcc_s_dw2-1.dll" in client.out + elif subsystem == "msys2": + assert "msys-2.0.dll" in client.out + if static_runtime: + assert "msys-stdc++-6.dll" not in client.out + else: + assert "msys-stdc++-6.dll" in client.out + elif subsystem == "cygwin": + assert "cygwin1.dll" in client.out + if static_runtime: + assert "cygstdc++-6.dll" not in client.out + else: + assert "cygstdc++-6.dll" in client.out + elif subsystem == "ucrt64": + assert "api-ms-win-crt-" in client.out + if static_runtime: + assert "libstdc++-6.dll" not in client.out + else: + assert "libstdc++-6.dll" in client.out + elif subsystem == "clang64": + assert "api-ms-win-crt-" in client.out + if static_runtime: + assert "libunwind.dll" not in client.out + assert "libc++.dll" not in client.out + else: + assert "libunwind.dll" in client.out + assert "libc++.dll" in client.out + else: + raise Exception("unknown {}".format(subsystem)) + elif static_runtime: assert "KERNEL32.dll" in client.out assert "MSVC" not in client.out assert "VCRUNTIME" not in client.out else: + assert "KERNEL32.dll" in client.out + if build_type == "Debug": + assert "ucrtbased" in client.out + else: + assert "api-ms-win-crt-" in client.out if vs_version in ["15", "16", "17"]: # UCRT debug = "D" if build_type == "Debug" else "" assert "MSVCP140{}.dll".format(debug) in client.out @@ -29,7 +75,7 @@ def check_vs_runtime(artifact, client, vs_version, build_type, architecture="amd def check_exe_run(output, names, compiler, version, build_type, arch, cppstd, definitions=None, - cxx11_abi=None): + cxx11_abi=None, subsystem=None): output = str(output) names = names if isinstance(names, list) else [names] @@ -51,12 +97,13 @@ def check_exe_run(output, names, compiler, version, build_type, arch, cppstd, de elif compiler in ["gcc", "clang", "apple-clang"]: if compiler == "gcc": assert "{} __GNUC__".format(name) in output + assert "clang" not in output if version: # FIXME: At the moment, the GCC version is not controlled, will change major, minor = version.split(".")[0:2] assert "{} __GNUC__{}".format(name, major) in output assert "{} __GNUC_MINOR__{}".format(name, minor) in output elif compiler == "clang": - assert "{} __clang__".format(name) in output + assert "{} __clang_".format(name) in output if version: major, minor = version.split(".")[0:2] assert "{} __clang_major__{}".format(name, major) in output @@ -88,3 +135,28 @@ def check_exe_run(output, names, compiler, version, build_type, arch, cppstd, de if definitions: for k, v in definitions.items(): assert "{}: {}".format(k, v) in output + + if subsystem: + if subsystem == "msys2": + assert "__MSYS__" in output + assert "__CYGWIN__" in output + assert "MINGW" not in output + elif subsystem in ("mingw32", "mingw64"): + assert "__MINGW32__" in output + assert "__CYGWIN__" not in output + assert "__MSYS__" not in output + if subsystem == "mingw64": + assert "__MINGW64__" in output + else: + assert "MING64" not in output + elif subsystem == "cygwin": + assert "__CYGWIN__" in output + assert "__MINGW32__" not in output + assert "__MINGW64__" not in output + assert "__MSYS__" not in output + else: + raise Exception("unknown subsystem {}".format(subsystem)) + else: + assert "CYGWIN" not in output + assert "MINGW" not in output + assert "MSYS" not in output