Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better clang Windows support #11492

Merged
merged 30 commits into from
Sep 30, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
3a834a8
fix conftest
memsharded Jun 20, 2022
52fc208
new test clang-mingw backend
memsharded Jun 20, 2022
66481ef
Merge branch 'develop' into test/clang_mingw
memsharded Jun 21, 2022
57ee148
wip
memsharded Jun 21, 2022
e654981
wip
memsharded Jun 22, 2022
d75b76c
test passing
memsharded Jun 22, 2022
8cb3879
Merge branch 'develop' into test/clang_mingw
memsharded Jun 22, 2022
1f7f222
solved clang CMake verify
memsharded Jun 22, 2022
88db84f
Merge branch 'develop' into test/clang_mingw
memsharded Jun 23, 2022
ef7c23a
wip
memsharded Jun 23, 2022
0d32828
Merge branch 'develop' into test/clang_mingw
memsharded Jun 23, 2022
c43ac11
C example
memsharded Jun 24, 2022
6ffddbf
Merge branch 'develop' into test/clang_mingw
memsharded Jun 24, 2022
f1d4a9a
wip
memsharded Jun 25, 2022
41773ee
Merge branch 'develop' into test/clang_mingw
memsharded Aug 25, 2022
ab0c8fd
wip
memsharded Aug 26, 2022
7bd21cc
wip
memsharded Aug 26, 2022
ffb8bd4
wip
memsharded Aug 26, 2022
77367ea
Merge branch 'develop' into test/clang_mingw
memsharded Aug 27, 2022
2fe9762
wip
memsharded Aug 28, 2022
8acb186
fix settings.yml
memsharded Aug 28, 2022
df9312d
fix test
memsharded Aug 29, 2022
e936bda
Merge branch 'develop' into test/clang_mingw
memsharded Sep 22, 2022
d458555
review and update compiler versions
memsharded Sep 22, 2022
4d6f354
Merge branch 'develop' into test/clang_mingw
memsharded Sep 23, 2022
4fe7287
fix
memsharded Sep 23, 2022
707a065
Update conan/tools/microsoft/visual.py
memsharded Sep 29, 2022
6e5c97b
fix missing binary search message (#12184)
memsharded Sep 23, 2022
a20570d
add GCC 11.3 to the list of compilers in the settings file (#12215)
Nekto89 Sep 29, 2022
cf9935c
review
memsharded Sep 30, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 9 additions & 1 deletion conan/tools/_compilers.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,15 @@ def architecture_flag(settings):
if the_os == "Android":
return ""

if str(compiler) in ['gcc', 'apple-clang', 'clang', 'sun-cc']:
if compiler == "clang" and the_os == "Windows":
# LLVM/Clang and VS/Clang must define runtime. msys2 clang won't
runtime = settings.get_safe("compiler.runtime") # runtime is Windows only
if runtime is not None:
return ""
# TODO: Maybe Clang-Mingw runtime does, but with C++ is impossible to test
return {"x86_64": "-m64",
"x86": "-m32"}.get(arch, "")
elif str(compiler) in ['gcc', 'apple-clang', 'clang', 'sun-cc']:
if str(the_os) == 'Macos' and str(subsystem) == 'catalyst':
# FIXME: This might be conflicting with Autotools --target cli arg
apple_arch = to_apple_arch(arch)
Expand Down
31 changes: 24 additions & 7 deletions conan/tools/cmake/toolchain/blocks.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,15 @@ class VSRuntimeBlock(Block):
def context(self):
# Parsing existing toolchain file to get existing configured runtimes
settings = self._conanfile.settings
if settings.get_safe("os") != "Windows":
return

compiler = settings.get_safe("compiler")
if compiler not in ("Visual Studio", "msvc", "intel-cc"):
if compiler not in ("Visual Studio", "msvc", "clang", "intel-cc"):
return

runtime = settings.get_safe("compiler.runtime")
if runtime is None:
return

config_dict = {}
Expand All @@ -119,18 +126,26 @@ def context(self):
build_type = settings.get_safe("build_type") # FIXME: change for configuration
if build_type is None:
return None
runtime = settings.get_safe("compiler.runtime")

if compiler == "Visual Studio":
config_dict[build_type] = {"MT": "MultiThreaded",
"MTd": "MultiThreadedDebug",
"MD": "MultiThreadedDLL",
"MDd": "MultiThreadedDebugDLL"}[runtime]
if compiler == "msvc" or compiler == "intel-cc":
elif compiler == "msvc" or compiler == "intel-cc" or compiler == "clang":
runtime_type = settings.get_safe("compiler.runtime_type")
rt = "MultiThreadedDebug" if runtime_type == "Debug" else "MultiThreaded"
if runtime != "static":
rt += "DLL"
config_dict[build_type] = rt

# If clang is being used the CMake check of compiler will try to create a simple
# test application, and will fail because the Debug runtime is not there
if compiler == "clang":
if config_dict.get("Debug") is None:
clang_rt = "MultiThreadedDebug" + ("DLL" if runtime != "static" else "")
config_dict["Debug"] = clang_rt

return {"vs_runtimes": config_dict}


Expand Down Expand Up @@ -693,10 +708,11 @@ def _get_toolset(self, generator):
toolset = msvc_version_to_toolset_version(compiler_version)
elif compiler == "clang":
if generator and "Visual" in generator:
if "Visual Studio 16" in generator:
if "Visual Studio 16" in generator or "Visual Studio 17" in generator:
toolset = "ClangCL"
else:
raise ConanException("CMakeToolchain compiler=clang only supported VS 16")
raise ConanException("CMakeToolchain with compiler=clang and a CMake "
"'Visual Studio' generator requires VS16 or VS17")
toolset_arch = self._conanfile.conf.get("tools.cmake.cmaketoolchain:toolset_arch")
if toolset_arch is not None:
toolset_arch = "host={}".format(toolset_arch)
Expand All @@ -713,7 +729,7 @@ def _get_generator_platform(self, generator):
if settings.get_safe("os") == "WindowsCE":
return settings.get_safe("os.platform")

if (compiler in ("Visual Studio", "msvc") or compiler_base == "Visual Studio") and \
if (compiler in ("Visual Studio", "msvc", "clang") or compiler_base == "Visual Studio") and \
generator and "Visual" in generator:
return {"x86": "Win32",
"x86_64": "x64",
Expand All @@ -730,7 +746,8 @@ def _get_compiler(self, generator):
# TODO: Check if really necessary now that conanvcvars is used
if "Ninja" in str(generator) and is_msvc(self._conanfile):
compiler_c = compiler_cpp = "cl"
elif os_ == "Windows" and compiler == "clang" and "Visual" not in str(generator):
elif os_ == "Windows" and compiler == "clang" and "Visual" not in generator:
# definition of compiler only if not using the VS Clang toolset
compiler_rc = "clang"
compiler_c = "clang"
compiler_cpp = "clang++"
Expand Down
23 changes: 20 additions & 3 deletions conan/tools/microsoft/visual.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,29 @@ def generate(self, scope="build"):
return

compiler = conanfile.settings.get_safe("compiler")
if compiler != "Visual Studio" and compiler != "msvc":
if compiler not in ("Visual Studio", "msvc", "clang"):
return

vs_version = vs_ide_version(conanfile)
if compiler == "clang":
# The vcvars only needed for LLVM/Clang and VS ClangCL, who define runtime
if not conanfile.settings.get_safe("compiler.runtime"):
# NMake Makefiles will need vcvars activated, for VS target, defined with runtime
return
toolset_version = conanfile.settings.get_safe("compiler.runtime_version")
vs_version = {"v140": "14",
"v141": "15",
"v142": "16",
"v143": "17"}.get(toolset_version)
if vs_version is None:
raise ConanException("Visual Studio Runtime version (v140-v143) not defined")
vcvars_ver = {"v140": "14.0",
"v141": "14.1",
"v142": "14.2",
"v143": "14.3"}.get(toolset_version)
else:
vs_version = vs_ide_version(conanfile)
vcvars_ver = _vcvars_vers(conanfile, compiler, vs_version)
vcvarsarch = vcvars_arch(conanfile)
vcvars_ver = _vcvars_vers(conanfile, compiler, vs_version)

vs_install_path = conanfile.conf.get("tools.microsoft.msbuild:installation_path")
# The vs_install_path is like
Expand Down
3 changes: 2 additions & 1 deletion conans/client/conf/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@
"8", "8.1", "8.2", "8.3", "8.4",
"9", "9.1", "9.2", "9.3", "9.4",
"10", "10.1", "10.2", "10.3",
"11", "11.1", "11.2",
"11", "11.1", "11.2", "11.3",
"12"]
libcxx: [libstdc++, libstdc++11]
threads: [None, posix, win32] # Windows MinGW
Expand Down Expand Up @@ -123,6 +123,7 @@
cppstd: [None, 98, gnu98, 11, gnu11, 14, gnu14, 17, gnu17, 20, gnu20, 23, gnu23]
runtime: [None, MD, MT, MTd, MDd, static, dynamic]
runtime_type: [None, Debug, Release]
runtime_version: [None, v140, v141, v142, v143]
apple-clang: &apple_clang
version: ["5.0", "5.1", "6.0", "6.1", "7.0", "7.3", "8.0", "8.1", "9.0", "9.1", "10.0", "11.0", "12.0", "13", "13.0", "13.1", "14", "14.0"]
libcxx: [libstdc++, libc++]
Expand Down
4 changes: 3 additions & 1 deletion conans/client/installer.py
Original file line number Diff line number Diff line change
Expand Up @@ -368,13 +368,15 @@ def _raise_missing(self, missing):
else:
build_str = " ".join(["--build=%s" % pref.ref.name for pref in missing_prefs])

search_ref = str(ref)
search_ref = search_ref + "@" if "@" not in search_ref else search_ref
raise ConanException(textwrap.dedent('''\
Missing prebuilt package for '%s'
Use 'conan search %s --table=table.html -r=remote' and open the table.html file to see available packages
Or try to build locally from sources with '%s'

More Info at 'https://docs.conan.io/en/latest/faq/troubleshooting.html#error-missing-prebuilt-package'
''' % (missing_pkgs, ref, build_str)))
''' % (missing_pkgs, search_ref, build_str)))

def _download(self, downloads, processed_package_refs):
""" executes the download of packages (both download and update), only once for a given
Expand Down
3 changes: 2 additions & 1 deletion conans/client/migrations_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -3955,7 +3955,7 @@
"8", "8.1", "8.2", "8.3", "8.4",
"9", "9.1", "9.2", "9.3", "9.4",
"10", "10.1", "10.2", "10.3",
"11", "11.1", "11.2",
"11", "11.1", "11.2", "11.3",
"12"]
libcxx: [libstdc++, libstdc++11]
threads: [None, posix, win32] # Windows MinGW
Expand Down Expand Up @@ -3985,6 +3985,7 @@
cppstd: [None, 98, gnu98, 11, gnu11, 14, gnu14, 17, gnu17, 20, gnu20, 23, gnu23]
runtime: [None, MD, MT, MTd, MDd, static, dynamic]
runtime_type: [None, Debug, Release]
runtime_version: [None, v140, v141, v142, v143]
apple-clang: &apple_clang
version: ["5.0", "5.1", "6.0", "6.1", "7.0", "7.3", "8.0", "8.1", "9.0", "9.1", "10.0", "11.0", "12.0", "13", "13.0", "13.1", "14", "14.0"]
libcxx: [libstdc++, libc++]
Expand Down
126 changes: 125 additions & 1 deletion conans/test/assets/sources.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
#if __x86_64__
std::cout << " {{ msg or name }} __x86_64__ defined\n";
#endif

#if __aarch64__
std::cout << " {{ msg or name }} __aarch64__ defined\n";
#endif
Expand Down Expand Up @@ -120,6 +120,130 @@ def gen_function_cpp(**context):
return t.render(**context)


_function_c = r"""

#define STRINGIFY_(x) #x
#define STRINGIFY(y) STRINGIFY_(y)

{% if name != "main" %}
#include "{{name}}.h"
{% endif %}

#include <stdio.h>

{% for it in includes -%}
#include "{{it}}.h"
{% endfor %}

int {{name}}(){
#ifdef NDEBUG
printf("{{ msg or name }}: Release!\n");
#else
printf("{{ msg or name }}: Debug!\n");
#endif

// ARCHITECTURES
#ifdef _M_X64
printf(" {{ msg or name }} _M_X64 defined\n");
#endif

#ifdef _M_IX86
printf(" {{ msg or name }} _M_IX86 defined\n");
#endif

#ifdef _M_ARM64
printf(" {{ msg or name }} _M_ARM64 defined\n");
#endif

#if __i386__
memsharded marked this conversation as resolved.
Show resolved Hide resolved
printf(" {{ msg or name }} __i386__ defined\n");
#endif

#if __x86_64__
printf(" {{ msg or name }} __x86_64__ defined\n");
#endif

#if __aarch64__
printf(" {{ msg or name }} __aarch64__ defined\n");
#endif

// Libstdc++
#if defined _GLIBCXX_USE_CXX11_ABI
printf(" {{ msg or name }} _GLIBCXX_USE_CXX11_ABI %s\n", STRINGIFY(_GLIBCXX_USE_CXX11_ABI));
#endif

// COMPILER VERSIONS
#if _MSC_VER
printf(" {{ msg or name }} _MSC_VER%s\n", STRINGIFY(_MSC_VER));
#endif

#if _MSVC_LANG
printf(" {{ msg or name }} _MSVC_LANG%s\n", STRINGIFY(_MSVC_LANG));
#endif

#if __cplusplus
printf(" {{ msg or name }} __cplusplus%s\n", STRINGIFY(__cplusplus));
#endif

#if __INTEL_COMPILER
printf(" {{ msg or name }} __INTEL_COMPILER%s\n", STRINGIFY(__INTEL_COMPILER));
#endif

#if __GNUC__
printf(" {{ msg or name }} __GNUC__%s\n", STRINGIFY(__GNUC__));
#endif

#if __GNUC_MINOR__
printf(" {{ msg or name }} __GNUC_MINOR__%s\n", STRINGIFY(__GNUC_MINOR__));
#endif

#if __clang_major__
printf(" {{ msg or name }} __clang_major__%s\n", STRINGIFY(__clang_major__));
#endif

#if __clang_minor__
printf(" {{ msg or name }} __clang_minor__%s\n", STRINGIFY(__clang_minor__));
#endif

#if __apple_build_version__
printf(" {{ msg or name }} __apple_build_version__%s\n", STRINGIFY(__apple_build_version__));
#endif

// SUBSYSTEMS

#if __MSYS__
printf(" {{ msg or name }} __MSYS__%s\n", STRINGIFY(__MSYS__));
#endif

#if __MINGW32__
printf(" {{ msg or name }} __MINGW32__%s\n", STRINGIFY(__MINGW32__));
#endif

#if __MINGW64__
printf(" {{ msg or name }} __MINGW64__%s\n", STRINGIFY(__MINGW64__));
#endif

#if __CYGWIN__
printf(" {{ msg or name }} __CYGWIN__%s\n", STRINGIFY(__CYGWIN__));
#endif

{% for it in preprocessor -%}
printf(" {{msg}} {{it}}: %s\n", {{it}} );
{%- endfor %}

{% for it in calls -%}
{{it}}();
{% endfor %}
return 0;
}
"""


def gen_function_c(**context):
t = Template(_function_c)
return t.render(**context)


_function_h = """
#pragma once

Expand Down
4 changes: 2 additions & 2 deletions conans/test/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,14 +136,14 @@
"disabled": True,
"platform": "Windows",
"default": "system",
"exe": "mingw32-make",
"exe": "clang",
"system": {"path": {'Windows': "C:/msys64/clang64/bin"}},
},
'msys2_mingw64_clang64': {
"disabled": True,
"platform": "Windows",
"default": "system",
"exe": "mingw32-make",
"exe": "clang",
"system": {"path": {'Windows': "C:/msys64/mingw64/bin"}},
},
'cygwin': {
Expand Down
10 changes: 7 additions & 3 deletions conans/test/functional/toolchains/cmake/test_cmake.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,17 @@ def test_simple_cmake_mingw():
compiler.libcxx=libstdc++11
compiler.threads=win32
compiler.version=11.2
cppstd=17
compiler.cppstd=17
"""})
client.run("create . --profile=mingw")
# FIXME: Note that CI contains 10.X, so it uses another version rather than the profile one
# and no one notices. It would be good to have some details in confuser.py to be consistent
assert "hello/1.0: __GNUC__" in client.out
assert "hello/1.0: __MINGW" in client.out
check_exe_run(client.out, "hello/1.0:", "gcc", None, "Release", "x86_64", "17",
subsystem="mingw64", extra_msg="Hello World", cxx11_abi="1")
check_vs_runtime("test_package/build/Release/example.exe", client, "15", build_type="Release",
static_runtime=False, subsystem="mingw64")

# TODO: How to link with mingw statically?


@pytest.mark.tool_cmake
Expand Down