diff --git a/conan/internal/default_settings.py b/conan/internal/default_settings.py index 68c19ba0baa..0cdbfc35894 100644 --- a/conan/internal/default_settings.py +++ b/conan/internal/default_settings.py @@ -168,6 +168,7 @@ # There is no ABI compatibility guarantee between versions version: [ANY] libcxx: [null, libstdc++, libstdc++11, libc++] + threads: [null, posix, wasm_workers] cppstd: [null, 98, gnu98, 11, gnu11, 14, gnu14, 17, gnu17, 20, gnu20, 23, gnu23, 26, gnu26] cstd: [null, 99, gnu99, 11, gnu11, 17, gnu17, 23, gnu23] diff --git a/conan/tools/build/flags.py b/conan/tools/build/flags.py index 49156c5edf4..2b3991fa833 100644 --- a/conan/tools/build/flags.py +++ b/conan/tools/build/flags.py @@ -195,6 +195,18 @@ def build_type_flags(conanfile): return flags return [] +def threads_flags(conanfile): + """ + returns flags specific to the threading model used by the compiler + """ + compiler = conanfile.settings.get_safe("compiler") + threads = conanfile.settings.get_safe("compiler.threads") + if compiler == "emcc": + if threads == "posix": + return ["-pthread"] + elif threads == "wasm_workers": + return ["-sWASM_WORKERS=1"] + return [] def llvm_clang_front(conanfile): # Only Windows clang with MSVC backend (LLVM/Clang, not MSYS2 clang) diff --git a/conan/tools/cmake/toolchain/blocks.py b/conan/tools/cmake/toolchain/blocks.py index d2a77fda62b..7dec828d335 100644 --- a/conan/tools/cmake/toolchain/blocks.py +++ b/conan/tools/cmake/toolchain/blocks.py @@ -10,7 +10,7 @@ from conan.tools.android.utils import android_abi from conan.tools.apple.apple import is_apple_os, to_apple_arch from conan.tools.build import build_jobs -from conan.tools.build.flags import architecture_flag, architecture_link_flag, libcxx_flags +from conan.tools.build.flags import architecture_flag, architecture_link_flag, libcxx_flags, threads_flags from conan.tools.build.cross_building import cross_building from conan.tools.cmake.toolchain import CONAN_TOOLCHAIN_FILENAME from conan.tools.cmake.utils import is_multi_configuration @@ -237,8 +237,8 @@ def context(self): class ArchitectureBlock(Block): template = textwrap.dedent("""\ - # Define C++ flags, C flags and linker flags from 'settings.arch' {% if arch_flag %} + # Define C++ flags, C flags and linker flags from 'settings.arch' message(STATUS "Conan toolchain: Defining architecture flag: {{ arch_flag }}") string(APPEND CONAN_CXX_FLAGS " {{ arch_flag }}") string(APPEND CONAN_C_FLAGS " {{ arch_flag }}") @@ -250,15 +250,23 @@ class ArchitectureBlock(Block): string(APPEND CONAN_SHARED_LINKER_FLAGS " {{ arch_link_flag }}") string(APPEND CONAN_EXE_LINKER_FLAGS " {{ arch_link_flag }}") {% endif %} + {% if thread_flags_list %} + # Define C++ flags, C flags and linker flags from 'compiler.threads' + message(STATUS "Conan toolchain: Defining thread flags: {{ thread_flags_list }}") + string(APPEND CONAN_CXX_FLAGS " {{ thread_flags_list }}") + string(APPEND CONAN_C_FLAGS " {{ thread_flags_list }}") + string(APPEND CONAN_SHARED_LINKER_FLAGS " {{ thread_flags_list }}") + string(APPEND CONAN_EXE_LINKER_FLAGS " {{ thread_flags_list }}") + {% endif %} """) def context(self): arch_flag = architecture_flag(self._conanfile) arch_link_flag = architecture_link_flag(self._conanfile) - if not arch_flag and not arch_link_flag: + thread_flags_list = " ".join(threads_flags(self._conanfile)) + if not arch_flag and not arch_link_flag and not thread_flags_list: return - return {"arch_flag": arch_flag, "arch_link_flag": arch_link_flag} - + return {"arch_flag": arch_flag, "arch_link_flag": arch_link_flag, "thread_flags_list": thread_flags_list} class LinkerScriptsBlock(Block): template = textwrap.dedent("""\ diff --git a/conan/tools/gnu/autotoolstoolchain.py b/conan/tools/gnu/autotoolstoolchain.py index 1b2ecd3c9b1..e4c008553ce 100644 --- a/conan/tools/gnu/autotoolstoolchain.py +++ b/conan/tools/gnu/autotoolstoolchain.py @@ -7,7 +7,7 @@ from conan.tools.build import cmd_args_to_string, save_toolchain_args from conan.tools.build.cross_building import cross_building from conan.tools.build.flags import architecture_flag, architecture_link_flag, build_type_flags, cppstd_flag, \ - build_type_link_flags, libcxx_flags, cstd_flag, llvm_clang_front + build_type_link_flags, libcxx_flags, cstd_flag, llvm_clang_front, threads_flags from conan.tools.env import Environment, VirtualBuildEnv from conan.tools.gnu.get_gnu_triplet import _get_gnu_triplet from conan.tools.microsoft import VCVars, msvc_runtime_flag, unix_path, check_min_vs, is_msvc @@ -53,6 +53,7 @@ def __init__(self, conanfile, namespace=None, prefix="/"): self.cstd = cstd_flag(self._conanfile) self.arch_flag = architecture_flag(self._conanfile) self.arch_ld_flag = architecture_link_flag(self._conanfile) + self.threads_flags = threads_flags(self._conanfile) self.libcxx, self.gcc_cxx11_abi = libcxx_flags(self._conanfile) self.fpic = self._conanfile.options.get_safe("fPIC") self.msvc_runtime_flag = self._get_msvc_runtime_flag() @@ -203,7 +204,7 @@ def _filter_list_empty_fields(v): def cxxflags(self): fpic = "-fPIC" if self.fpic else None ret = [self.libcxx, self.cppstd, self.arch_flag, fpic, self.msvc_runtime_flag, - self.sysroot_flag] + self.sysroot_flag] + self.threads_flags apple_flags = [self.apple_isysroot_flag, self.apple_arch_flag, self.apple_min_version_flag] apple_flags += self.apple_extra_flags conf_flags = self._conanfile.conf.get("tools.build:cxxflags", default=[], check_type=list) @@ -214,7 +215,7 @@ def cxxflags(self): @property def cflags(self): fpic = "-fPIC" if self.fpic else None - ret = [self.cstd, self.arch_flag, fpic, self.msvc_runtime_flag, self.sysroot_flag] + ret = [self.cstd, self.arch_flag, fpic, self.msvc_runtime_flag, self.sysroot_flag] + self.threads_flags apple_flags = [self.apple_isysroot_flag, self.apple_arch_flag, self.apple_min_version_flag] apple_flags += self.apple_extra_flags conf_flags = self._conanfile.conf.get("tools.build:cflags", default=[], check_type=list) @@ -224,7 +225,7 @@ def cflags(self): @property def ldflags(self): - ret = [self.arch_flag, self.sysroot_flag, self.arch_ld_flag] + ret = [self.arch_flag, self.sysroot_flag, self.arch_ld_flag] + self.threads_flags apple_flags = [self.apple_isysroot_flag, self.apple_arch_flag, self.apple_min_version_flag] apple_flags += self.apple_extra_flags conf_flags = self._conanfile.conf.get("tools.build:sharedlinkflags", default=[], diff --git a/conan/tools/gnu/gnutoolchain.py b/conan/tools/gnu/gnutoolchain.py index 3a478d96242..421be382a47 100644 --- a/conan/tools/gnu/gnutoolchain.py +++ b/conan/tools/gnu/gnutoolchain.py @@ -7,7 +7,7 @@ from conan.tools.build.cross_building import cross_building from conan.tools.build.flags import architecture_flag, architecture_link_flag, build_type_flags, cppstd_flag, \ build_type_link_flags, \ - libcxx_flags, llvm_clang_front + libcxx_flags, llvm_clang_front, threads_flags from conan.tools.env import Environment, VirtualBuildEnv from conan.tools.gnu.get_gnu_triplet import _get_gnu_triplet from conan.tools.microsoft import VCVars, msvc_runtime_flag, unix_path, check_min_vs, is_msvc @@ -58,6 +58,7 @@ def __init__(self, conanfile, namespace=None, prefix="/"): self.cppstd = cppstd_flag(self._conanfile) self.arch_flag = architecture_flag(self._conanfile) self.arch_ld_flag = architecture_link_flag(self._conanfile) + self.threads_flags = threads_flags(self._conanfile) self.libcxx, self.gcc_cxx11_abi = libcxx_flags(self._conanfile) self.fpic = self._conanfile.options.get_safe("fPIC") self.msvc_runtime_flag = self._get_msvc_runtime_flag() @@ -268,7 +269,7 @@ def _dict_to_list(flags): def cxxflags(self): fpic = "-fPIC" if self.fpic else None ret = [self.libcxx, self.cppstd, self.arch_flag, fpic, self.msvc_runtime_flag, - self.sysroot_flag] + self.sysroot_flag] + self.threads_flags apple_flags = [self.apple_isysroot_flag, self.apple_arch_flag, self.apple_min_version_flag] apple_flags += self.apple_extra_flags conf_flags = self._conanfile.conf.get("tools.build:cxxflags", default=[], check_type=list) @@ -279,7 +280,7 @@ def cxxflags(self): @property def cflags(self): fpic = "-fPIC" if self.fpic else None - ret = [self.arch_flag, fpic, self.msvc_runtime_flag, self.sysroot_flag] + ret = [self.arch_flag, fpic, self.msvc_runtime_flag, self.sysroot_flag] + self.threads_flags apple_flags = [self.apple_isysroot_flag, self.apple_arch_flag, self.apple_min_version_flag] apple_flags += self.apple_extra_flags conf_flags = self._conanfile.conf.get("tools.build:cflags", default=[], check_type=list) @@ -289,7 +290,7 @@ def cflags(self): @property def ldflags(self): - ret = [self.arch_flag, self.sysroot_flag, self.arch_ld_flag] + ret = [self.arch_flag, self.sysroot_flag, self.arch_ld_flag] + self.threads_flags apple_flags = [self.apple_isysroot_flag, self.apple_arch_flag, self.apple_min_version_flag] apple_flags += self.apple_extra_flags conf_flags = self._conanfile.conf.get("tools.build:sharedlinkflags", default=[], diff --git a/conan/tools/meson/toolchain.py b/conan/tools/meson/toolchain.py index c1f1e79edf7..ece0fdb2e92 100644 --- a/conan/tools/meson/toolchain.py +++ b/conan/tools/meson/toolchain.py @@ -9,7 +9,7 @@ from conan.tools.apple.apple import is_apple_os, apple_min_version_flag, \ resolve_apple_flags, apple_extra_flags from conan.tools.build.cross_building import cross_building -from conan.tools.build.flags import architecture_link_flag, libcxx_flags, architecture_flag +from conan.tools.build.flags import architecture_link_flag, libcxx_flags, architecture_flag, threads_flags from conan.tools.env import VirtualBuildEnv from conan.tools.meson.helpers import * from conan.tools.meson.helpers import get_apple_subsystem @@ -218,6 +218,8 @@ def __init__(self, conanfile, backend=None, native=False): self.arch_flag = architecture_flag(self._conanfile) # https://github.com/conan-io/conan/issues/17624 #: Architecture link flag deduced by Conan and added to ``c_link_args`` and ``cpp_link_args`` self.arch_link_flag = architecture_link_flag(self._conanfile) + #: Threads flags deduced by Conan and added to ``c_args``, ``cpp_args``, ``c_link_args`` and ``cpp_link_args`` + self.threads_flags = threads_flags(self._conanfile) #: Dict-like object that defines Meson ``properties`` with ``key=value`` format self.properties = {} #: Dict-like object that defines Meson ``project options`` with ``key=value`` format @@ -453,14 +455,14 @@ def _get_extra_flags(self): linker_script_flags = ['-T"' + linker_script + '"' for linker_script in linker_scripts] defines = self._conanfile_conf.get("tools.build:defines", default=[], check_type=list) sys_root = [f"--sysroot={self._sys_root}"] if self._sys_root else [""] - ld = sharedlinkflags + exelinkflags + linker_script_flags + sys_root + self.extra_ldflags + ld = sharedlinkflags + exelinkflags + linker_script_flags + sys_root + self.extra_ldflags + self.threads_flags # Apple extra flags from confs (visibilty, bitcode, arc) cxxflags += self.apple_extra_flags cflags += self.apple_extra_flags ld += self.apple_extra_flags return { - "cxxflags": [self.arch_flag] + cxxflags + sys_root + self.extra_cxxflags, - "cflags": [self.arch_flag] + cflags + sys_root + self.extra_cflags, + "cxxflags": [self.arch_flag] + cxxflags + sys_root + self.extra_cxxflags + self.threads_flags, + "cflags": [self.arch_flag] + cflags + sys_root + self.extra_cflags + self.threads_flags, "ldflags": [self.arch_flag] + [self.arch_link_flag] + ld, "defines": [f"-D{d}" for d in (defines + self.extra_defines)] } diff --git a/conan/tools/premake/toolchain.py b/conan/tools/premake/toolchain.py index 34616524082..0131cf6dae8 100644 --- a/conan/tools/premake/toolchain.py +++ b/conan/tools/premake/toolchain.py @@ -1,4 +1,4 @@ -from conan.tools.build.flags import architecture_flag, architecture_link_flag, libcxx_flags +from conan.tools.build.flags import architecture_flag, architecture_link_flag, libcxx_flags, threads_flags import os import textwrap from pathlib import Path @@ -16,19 +16,19 @@ def _generate_flags(self, conanfile): template = textwrap.dedent( """\ {% if extra_cflags %} - -- C flags retrieved from CFLAGS environment, conan.conf(tools.build:cflags) and extra_cflags + -- C flags retrieved from CFLAGS environment, conan.conf(tools.build:cflags), extra_cflags and compiler settings filter { files { "**.c" } } buildoptions { {{ extra_cflags }} } filter {} {% endif %} {% if extra_cxxflags %} - -- CXX flags retrieved from CXXFLAGS environment, conan.conf(tools.build:cxxflags) and extra_cxxflags + -- CXX flags retrieved from CXXFLAGS environment, conan.conf(tools.build:cxxflags), extra_cxxflags and compiler settings filter { files { "**.cpp", "**.cxx", "**.cc" } } buildoptions { {{ extra_cxxflags }} } filter {} {% endif %} {% if extra_ldflags %} - -- Link flags retrieved from LDFLAGS environment, conan.conf(tools.build:sharedlinkflags), conan.conf(tools.build:exelinkflags) and extra_cxxflags + -- Link flags retrieved from LDFLAGS environment, conan.conf(tools.build:sharedlinkflags), conan.conf(tools.build:exelinkflags), extra_cxxflags and compiler settings linkoptions { {{ extra_ldflags }} } {% endif %} {% if extra_defines %} @@ -47,6 +47,7 @@ def to_list(value): arch_flags = to_list(architecture_flag(self._conanfile)) cxx_flags, libcxx_compile_definitions = libcxx_flags(self._conanfile) arch_link_flags = to_list(architecture_link_flag(self._conanfile)) + thread_flags_list = threads_flags(self._conanfile) extra_defines = format_list( conanfile.conf.get("tools.build:defines", default=[], check_type=list) @@ -54,13 +55,17 @@ def to_list(value): + to_list(libcxx_compile_definitions) ) extra_c_flags = format_list( - conanfile.conf.get("tools.build:cflags", default=[], check_type=list) + self.extra_cflags + arch_flags + conanfile.conf.get("tools.build:cflags", default=[], check_type=list) + + self.extra_cflags + + arch_flags + + thread_flags_list ) extra_cxx_flags = format_list( conanfile.conf.get("tools.build:cxxflags", default=[], check_type=list) + to_list(cxx_flags) + self.extra_cxxflags + arch_flags + + thread_flags_list ) extra_ld_flags = format_list( conanfile.conf.get("tools.build:sharedlinkflags", default=[], check_type=list) @@ -68,6 +73,7 @@ def to_list(value): + self.extra_ldflags + arch_flags + arch_link_flags + + thread_flags_list ) return ( diff --git a/test/integration/toolchains/cmake/test_cmaketoolchain.py b/test/integration/toolchains/cmake/test_cmaketoolchain.py index bbd6931d59b..d517e25721a 100644 --- a/test/integration/toolchains/cmake/test_cmaketoolchain.py +++ b/test/integration/toolchains/cmake/test_cmaketoolchain.py @@ -1772,3 +1772,35 @@ def test_cmake_presets_compiler(): # https://github.com/microsoft/vscode-cmake-tools/blob/a1ceda25ea93fc0060324de15970a8baa69addf6/src/presets/preset.ts#L1095C23-L1095C35 assert cache_variables["CMAKE_C_COMPILER"] == "cl" assert cache_variables["CMAKE_CXX_COMPILER"] == "cl.exe" + +@pytest.mark.parametrize( + "threads, flags", + [("posix", "-pthread"), ("wasm_workers", "-sWASM_WORKERS=1")], +) +def test_thread_flags(threads, flags): + client = TestClient() + profile = textwrap.dedent(f""" + [settings] + arch=wasm + build_type=Release + compiler=emcc + compiler.cppstd=17 + compiler.threads={threads} + compiler.libcxx=libc++ + compiler.version=4.0.10 + os=Emscripten + """) + client.save( + { + "conanfile.py": GenConanfile("pkg", "1.0") + .with_settings("os", "arch", "compiler", "build_type") + .with_generator("CMakeToolchain"), + "profile": profile, + } + ) + client.run("install . -pr=./profile") + toolchain = client.load("conan_toolchain.cmake") + assert f'string(APPEND CONAN_CXX_FLAGS " {flags}")' in toolchain + assert f'string(APPEND CONAN_C_FLAGS " {flags}")' in toolchain + assert f'string(APPEND CONAN_SHARED_LINKER_FLAGS " {flags}")' in toolchain + assert f'string(APPEND CONAN_EXE_LINKER_FLAGS " {flags}")' in toolchain diff --git a/test/integration/toolchains/gnu/test_autotoolstoolchain.py b/test/integration/toolchains/gnu/test_autotoolstoolchain.py index 95ea899de83..7da8302b162 100644 --- a/test/integration/toolchains/gnu/test_autotoolstoolchain.py +++ b/test/integration/toolchains/gnu/test_autotoolstoolchain.py @@ -1,6 +1,7 @@ import os import platform import textwrap +import pytest from conan.test.assets.genconanfile import GenConanfile from conan.test.utils.tools import TestClient @@ -367,3 +368,40 @@ def test_conf_build_does_not_exist(): tc = c.load("conanautotoolstoolchain.sh") assert 'export CC_FOR_BUILD="x86_64-linux-gnu-gcc"' in tc assert 'export CXX_FOR_BUILD="x86_64-linux-gnu-g++"' in tc + +@pytest.mark.parametrize( + "threads, flags", + [("posix", "-pthread"), ("wasm_workers", "-sWASM_WORKERS=1")], +) +def test_thread_flags(threads, flags): + os = platform.system() + client = TestClient() + profile = textwrap.dedent(f""" + [settings] + arch=wasm + build_type=Release + compiler=emcc + compiler.cppstd=17 + compiler.threads={threads} + compiler.libcxx=libc++ + compiler.version=4.0.10 + os=Emscripten + """) + client.save( + { + "conanfile.py": GenConanfile("pkg", "1.0") + .with_settings("os", "arch", "compiler", "build_type") + .with_generator("AutotoolsToolchain"), + "profile": profile, + } + ) + client.run("install . -pr=./profile") + toolchain = client.load("conanautotoolstoolchain{}".format('.bat' if os == "Windows" else '.sh')) + if os == "Windows": + assert f'set "CXXFLAGS=%CXXFLAGS% -stdlib=libc++ {flags}"' in toolchain + assert f'set "CFLAGS=%CFLAGS% {flags}"' in toolchain + assert f'set "LDFLAGS=%LDFLAGS% {flags}' in toolchain + else: + assert f'export CXXFLAGS="$CXXFLAGS -stdlib=libc++ {flags}"' in toolchain + assert f'export CFLAGS="$CFLAGS {flags}"' in toolchain + assert f'export LDFLAGS="$LDFLAGS {flags}"' in toolchain diff --git a/test/integration/toolchains/gnu/test_gnutoolchain.py b/test/integration/toolchains/gnu/test_gnutoolchain.py index 6493a3be2d6..5294123ed57 100644 --- a/test/integration/toolchains/gnu/test_gnutoolchain.py +++ b/test/integration/toolchains/gnu/test_gnutoolchain.py @@ -592,3 +592,43 @@ def build(self): "conanfile.py": consumer }) client.run("create . -pr:h host -pr:b build") + + +@pytest.mark.parametrize( + "threads, flags", + [("posix", "-pthread"), ("wasm_workers", "-sWASM_WORKERS=1")], +) +def test_thread_flags(threads, flags): + client = TestClient() + profile = textwrap.dedent(f""" + [settings] + arch=wasm + build_type=Release + compiler=emcc + compiler.cppstd=17 + compiler.threads={threads} + compiler.libcxx=libc++ + compiler.version=4.0.10 + os=Emscripten + """) + client.save( + { + "conanfile.py": GenConanfile("pkg", "1.0") + .with_settings("os", "arch", "compiler", "build_type") + .with_generator("GnuToolchain"), + "profile": profile, + } + ) + client.run("install . -pr=./profile") + os = platform.system() + toolchain = client.load( + "conangnutoolchain{}".format('.bat' if os == "Windows" else '.sh')) + + if os == "Windows": + assert f'set "CXXFLAGS=%CXXFLAGS% -stdlib=libc++ {flags}"' in toolchain + assert f'set "CFLAGS=%CFLAGS% {flags}"' in toolchain + assert f'set "LDFLAGS=%LDFLAGS% {flags}' in toolchain + else: + assert f'export CXXFLAGS="$CXXFLAGS -stdlib=libc++ {flags}"' in toolchain + assert f'export CFLAGS="$CFLAGS {flags}"' in toolchain + assert f'export LDFLAGS="$LDFLAGS {flags}"' in toolchain diff --git a/test/integration/toolchains/meson/test_mesontoolchain.py b/test/integration/toolchains/meson/test_mesontoolchain.py index 699da0a5fe1..f6e51c6afbc 100644 --- a/test/integration/toolchains/meson/test_mesontoolchain.py +++ b/test/integration/toolchains/meson/test_mesontoolchain.py @@ -823,3 +823,35 @@ def test_conf_extra_apple_flags(): assert f"{flags} = ['-m64', '-fvisibility=hidden', '-fvisibility-inlines-hidden']" in tc for flags in ["objcpp_args", "objc_args"]: assert f"{flags} = ['-fno-objc-arc', '-m64', '-fvisibility=hidden', '-fvisibility-inlines-hidden']" in tc + +@pytest.mark.parametrize( + "threads, flags", + [("posix", "-pthread"), ("wasm_workers", "-sWASM_WORKERS=1")], +) +def test_thread_flags(threads, flags): + client = TestClient() + profile = textwrap.dedent(f""" + [settings] + arch=wasm + build_type=Release + compiler=emcc + compiler.cppstd=17 + compiler.threads={threads} + compiler.libcxx=libc++ + compiler.version=4.0.10 + os=Emscripten + """) + client.save( + { + "conanfile.py": GenConanfile("pkg", "1.0") + .with_settings("os", "arch", "compiler", "build_type") + .with_generator("MesonToolchain"), + "profile": profile, + } + ) + client.run("install . -pr=./profile") + toolchain = client.load("conan_meson_cross.ini") + assert f"c_args = ['{flags}']" in toolchain + assert f"c_link_args = ['{flags}']" in toolchain + assert f"cpp_args = ['{flags}', '-stdlib=libc++']" in toolchain + assert f"cpp_link_args = ['{flags}', '-stdlib=libc++']" in toolchain diff --git a/test/integration/toolchains/premake/test_premaketoolchain.py b/test/integration/toolchains/premake/test_premaketoolchain.py index b6bdf09115f..b764579a021 100644 --- a/test/integration/toolchains/premake/test_premaketoolchain.py +++ b/test/integration/toolchains/premake/test_premaketoolchain.py @@ -1,4 +1,6 @@ import textwrap +from conan.test.assets.genconanfile import GenConanfile +import pytest from conan.test.utils.tools import TestClient from conan.tools.premake.toolchain import PremakeToolchain @@ -58,7 +60,6 @@ def test_extra_flags_via_conf(): assert 'defines { "define1=0", "_GLIBCXX_USE_CXX11_ABI=0" }' in content - def test_project_configuration(): tc = TestClient(path_with_spaces=False) profile = textwrap.dedent( @@ -132,7 +133,7 @@ def generate(self): textwrap.dedent( """ project "main" - -- CXX flags retrieved from CXXFLAGS environment, conan.conf(tools.build:cxxflags) and extra_cxxflags + -- CXX flags retrieved from CXXFLAGS environment, conan.conf(tools.build:cxxflags), extra_cxxflags and compiler settings filter { files { "**.cpp", "**.cxx", "**.cc" } } buildoptions { "-stdlib=libc++", "-FS" } filter {} @@ -151,3 +152,51 @@ def generate(self): ) in toolchain ) + + +@pytest.mark.parametrize( + "threads, flags", + [("posix", "-pthread"), ("wasm_workers", "-sWASM_WORKERS=1")], +) +def test_thread_flags(threads, flags): + client = TestClient() + profile = textwrap.dedent(f""" + [settings] + arch=wasm64 + build_type=Release + compiler=emcc + compiler.cppstd=17 + compiler.threads={threads} + compiler.libcxx=libc++ + compiler.version=4.0.10 + os=Emscripten + """) + client.save( + { + "conanfile.py": GenConanfile("pkg", "1.0") + .with_settings("os", "arch", "compiler", "build_type") + .with_generator("PremakeToolchain"), + "profile": profile, + } + ) + client.run("install . -pr=./profile") + toolchain = client.load("conantoolchain.premake5.lua") + assert ( + """ + filter { files { "**.c" } } + buildoptions { "-sMEMORY64=1", "%s" } + filter {} + """ + % flags + in toolchain + ) + assert ( + """ + filter { files { "**.cpp", "**.cxx", "**.cc" } } + buildoptions { "-stdlib=libc++", "-sMEMORY64=1", "%s" } + filter {} + """ + % flags + in toolchain + ) + assert 'linkoptions { "-sMEMORY64=1", "%s" }' % flags in toolchain diff --git a/test/unittests/client/build/compiler_flags_test.py b/test/unittests/client/build/compiler_flags_test.py index 4c82661f58d..0cbab683e2a 100644 --- a/test/unittests/client/build/compiler_flags_test.py +++ b/test/unittests/client/build/compiler_flags_test.py @@ -1,7 +1,7 @@ import unittest from parameterized.parameterized import parameterized -from conan.tools.build.flags import architecture_flag, build_type_flags +from conan.tools.build.flags import architecture_flag, build_type_flags, threads_flags from conan.test.utils.mocks import MockSettings, ConanFileMock @@ -37,6 +37,19 @@ def test_arch_flag(self, compiler, arch, the_os, flag): conanfile.settings = settings self.assertEqual(architecture_flag(conanfile), flag) + + @parameterized.expand([("clang", None, []), + ("emcc", None, []), + ("emcc", "posix", ["-pthread"]), + ("emcc", "wasm_workers", ["-sWASM_WORKERS=1"]), + ]) + def test_threads_flag(self, compiler, threads, flag): + settings = MockSettings({"compiler": compiler, + "compiler.threads": threads}) + conanfile = ConanFileMock() + conanfile.settings = settings + self.assertEqual(threads_flags(conanfile), flag) + @parameterized.expand([("clang", "x86", "Windows", ""), ("clang", "x86_64", "Windows", "") ])