diff options
author | Brad King <brad.king@kitware.com> | 2022-12-06 13:04:07 (GMT) |
---|---|---|
committer | Kitware Robot <kwrobot@kitware.com> | 2022-12-06 13:04:18 (GMT) |
commit | f1f064b7b2c93048897014e096217e1a00f668c7 (patch) | |
tree | 6cd0ff2dbc453a45105743af22556072a1231ada | |
parent | 85d89ca88586be09e940fea938d2a2add5dd4425 (diff) | |
parent | 2c558cfd1b26e879bf6acce619255ca7b1ba0425 (diff) | |
download | CMake-f1f064b7b2c93048897014e096217e1a00f668c7.zip CMake-f1f064b7b2c93048897014e096217e1a00f668c7.tar.gz CMake-f1f064b7b2c93048897014e096217e1a00f668c7.tar.bz2 |
Merge topic 'cxx-module-map-clang'
2c558cfd1b gitlab-ci: add CI jobs for Clang with C++20 modules
abd42e9cfc ci: add a Docker container for clang support of C++20 modules
51093f3002 Clang-FindBinUtils: also find `clang-scan-deps`
0b333de923 ci: add C++ module rules file for Clang
21b9fb1e8c cmCxxModuleMapper: support the `clang` module map format
9c66224668 cmNinjaTargetGenerator: skip setting `depfile` for `none` scantypes
9123a0991f cmNinjaTargetGenerator: use `.clear()` to empty out some strings
Acked-by: Kitware Robot <kwrobot@kitware.com>
Acked-by: Cristian Adam <cristian.adam@gmail.com>
Merge-request: !7978
-rw-r--r-- | .gitlab-ci.yml | 20 | ||||
-rw-r--r-- | .gitlab/ci/configure_linux_clang_cxx_modules_ninja.cmake | 4 | ||||
-rw-r--r-- | .gitlab/ci/configure_linux_clang_cxx_modules_ninja_multi.cmake | 4 | ||||
-rw-r--r-- | .gitlab/ci/cxx_modules_rules_clang.cmake | 16 | ||||
-rw-r--r-- | .gitlab/ci/docker/clang_cxx_modules/Dockerfile | 13 | ||||
-rwxr-xr-x | .gitlab/ci/docker/clang_cxx_modules/install_cmake_deps.sh | 7 | ||||
-rwxr-xr-x | .gitlab/ci/docker/clang_cxx_modules/install_deps.sh | 7 | ||||
-rwxr-xr-x | .gitlab/ci/docker/clang_cxx_modules/install_llvm.sh | 39 | ||||
-rw-r--r-- | .gitlab/os-linux.yml | 22 | ||||
-rw-r--r-- | Help/dev/experimental.rst | 9 | ||||
-rw-r--r-- | Modules/Compiler/Clang-FindBinUtils.cmake | 11 | ||||
-rw-r--r-- | Source/cmCxxModuleMapper.cxx | 36 | ||||
-rw-r--r-- | Source/cmCxxModuleMapper.h | 1 | ||||
-rw-r--r-- | Source/cmGlobalNinjaGenerator.cxx | 2 | ||||
-rw-r--r-- | Source/cmNinjaTargetGenerator.cxx | 7 | ||||
-rw-r--r-- | Tests/RunCMake/CXXModules/examples/cxx-modules-find-bmi.cmake | 2 |
16 files changed, 194 insertions, 6 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index a2b3ec3..cd3f0a0 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -325,6 +325,26 @@ t:linux-gcc-cxx-modules-ninja-multi: variables: CMAKE_CI_JOB_NIGHTLY: "true" +t:linux-clang-cxx-modules-ninja: + extends: + - .clang_cxx_modules_ninja + - .cmake_test_linux_release + - .linux_x86_64_tags + - .run_dependent + - .needs_centos6_x86_64 + variables: + CMAKE_CI_JOB_NIGHTLY: "true" + +t:linux-clang-cxx-modules-ninja-multi: + extends: + - .clang_cxx_modules_ninja_multi + - .cmake_test_linux_release + - .linux_x86_64_tags + - .run_dependent + - .needs_centos6_x86_64 + variables: + CMAKE_CI_JOB_NIGHTLY: "true" + b:fedora37-ninja: extends: - .fedora37_ninja diff --git a/.gitlab/ci/configure_linux_clang_cxx_modules_ninja.cmake b/.gitlab/ci/configure_linux_clang_cxx_modules_ninja.cmake new file mode 100644 index 0000000..43bccdb --- /dev/null +++ b/.gitlab/ci/configure_linux_clang_cxx_modules_ninja.cmake @@ -0,0 +1,4 @@ +set(CMake_TEST_MODULE_COMPILATION "named,partitions,internal_partitions,export_bmi,install_bmi,shared" CACHE STRING "") +set(CMake_TEST_MODULE_COMPILATION_RULES "${CMAKE_CURRENT_LIST_DIR}/cxx_modules_rules_clang.cmake" CACHE STRING "") + +include("${CMAKE_CURRENT_LIST_DIR}/configure_external_test.cmake") diff --git a/.gitlab/ci/configure_linux_clang_cxx_modules_ninja_multi.cmake b/.gitlab/ci/configure_linux_clang_cxx_modules_ninja_multi.cmake new file mode 100644 index 0000000..43bccdb --- /dev/null +++ b/.gitlab/ci/configure_linux_clang_cxx_modules_ninja_multi.cmake @@ -0,0 +1,4 @@ +set(CMake_TEST_MODULE_COMPILATION "named,partitions,internal_partitions,export_bmi,install_bmi,shared" CACHE STRING "") +set(CMake_TEST_MODULE_COMPILATION_RULES "${CMAKE_CURRENT_LIST_DIR}/cxx_modules_rules_clang.cmake" CACHE STRING "") + +include("${CMAKE_CURRENT_LIST_DIR}/configure_external_test.cmake") diff --git a/.gitlab/ci/cxx_modules_rules_clang.cmake b/.gitlab/ci/cxx_modules_rules_clang.cmake new file mode 100644 index 0000000..9d75880 --- /dev/null +++ b/.gitlab/ci/cxx_modules_rules_clang.cmake @@ -0,0 +1,16 @@ +set(CMake_TEST_CXXModules_UUID "a246741c-d067-4019-a8fb-3d16b0c9d1d3") + +set(CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP 1) +string(CONCAT CMAKE_EXPERIMENTAL_CXX_SCANDEP_SOURCE + "${CMAKE_CXX_COMPILER_CLANG_SCAN_DEPS}" + " -format=p1689 --p1689-targeted-file-name=<SOURCE> --p1689-targeted-output=<OBJECT> --" + " <DEFINES> <INCLUDES> <FLAGS> -x c++ <SOURCE>" + " > <DYNDEP_FILE>") +# No support for `-MF` discovered dependencies in `clang-scan-deps`. +set(CMAKE_EXPERIMENTAL_CXX_SCANDEP_DEPFILE_FORMAT "none") +set(CMAKE_EXPERIMENTAL_CXX_MODULE_MAP_FORMAT "clang") +set(CMAKE_EXPERIMENTAL_CXX_MODULE_MAP_FLAG "@<MODULE_MAP_FILE>") + +# Default to C++ extensions being off. Clang's modules support have trouble +# with extensions right now. +set(CMAKE_CXX_EXTENSIONS OFF) diff --git a/.gitlab/ci/docker/clang_cxx_modules/Dockerfile b/.gitlab/ci/docker/clang_cxx_modules/Dockerfile new file mode 100644 index 0000000..4e58125 --- /dev/null +++ b/.gitlab/ci/docker/clang_cxx_modules/Dockerfile @@ -0,0 +1,13 @@ +FROM fedora:37 +MAINTAINER Ben Boeckel <ben.boeckel@kitware.com> + +# Install build dependencies for packages. +COPY install_deps.sh /root/install_deps.sh +RUN sh /root/install_deps.sh + +COPY install_llvm.sh /root/install_llvm.sh +RUN sh /root/install_llvm.sh + +# Install build dependencies for CMake's CI. +COPY install_cmake_deps.sh /root/install_cmake_deps.sh +RUN sh /root/install_cmake_deps.sh diff --git a/.gitlab/ci/docker/clang_cxx_modules/install_cmake_deps.sh b/.gitlab/ci/docker/clang_cxx_modules/install_cmake_deps.sh new file mode 100755 index 0000000..465e125 --- /dev/null +++ b/.gitlab/ci/docker/clang_cxx_modules/install_cmake_deps.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +set -e + +dnf install -y --setopt=install_weak_deps=False \ + file git-core +dnf clean all diff --git a/.gitlab/ci/docker/clang_cxx_modules/install_deps.sh b/.gitlab/ci/docker/clang_cxx_modules/install_deps.sh new file mode 100755 index 0000000..c1957c3 --- /dev/null +++ b/.gitlab/ci/docker/clang_cxx_modules/install_deps.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +set -e + +dnf install -y --setopt=install_weak_deps=False \ + gcc-c++ cmake ninja-build +dnf clean all diff --git a/.gitlab/ci/docker/clang_cxx_modules/install_llvm.sh b/.gitlab/ci/docker/clang_cxx_modules/install_llvm.sh new file mode 100755 index 0000000..09d0106 --- /dev/null +++ b/.gitlab/ci/docker/clang_cxx_modules/install_llvm.sh @@ -0,0 +1,39 @@ +#!/bin/sh + +set -e + +readonly revision="p1689r5-cmake-ci-20221201" # ae3b5489585b60a2b7f090ebb9e1e8729b811253 +readonly tarball="https://github.com/mathstuf/llvm-project/archive/$revision.tar.gz" + +readonly workdir="$HOME/llvm" +readonly srcdir="$workdir/llvm" +readonly builddir="$workdir/build" + +mkdir -p "$workdir" +cd "$workdir" +curl -L "$tarball" > "llvm-$revision.tar.gz" +tar xf "llvm-$revision.tar.gz" +mv "llvm-project-$revision" "$srcdir" +mkdir -p "$builddir" +cd "$builddir" +cmake -GNinja \ + -DCMAKE_BUILD_TYPE=Release \ + -DBUILD_SHARED_LIBS=ON \ + -DLLVM_ENABLE_BINDINGS=OFF \ + -DLLVM_INCLUDE_BENCHMARKS=OFF \ + -DLLVM_INCLUDE_DOCS=OFF \ + -DLLVM_INCLUDE_EXAMPLES=OFF \ + -DLLVM_INCLUDE_RUNTIMES=OFF \ + -DLLVM_INCLUDE_TESTS=OFF \ + -DLLVM_INCLUDE_UTILS=OFF \ + -DLLVM_TARGETS_TO_BUILD=X86 \ + -DLLVM_TOOL_CLANG_BUILD=ON \ + -DLLVM_USE_SYMLINKS=ON \ + "-DLLVM_EXTERNAL_CLANG_SOURCE_DIR=$srcdir/clang" \ + -DLLVM_PARALLEL_LINK_JOBS=1 \ + -DCLANG_BUILD_TOOLS=ON \ + "-DCMAKE_INSTALL_PREFIX=/opt/llvm-p1689" \ + "$srcdir/llvm" +ninja +ninja install/strip +rm -rf "$workdir" diff --git a/.gitlab/os-linux.yml b/.gitlab/os-linux.yml index decf1b1..5dbeff5 100644 --- a/.gitlab/os-linux.yml +++ b/.gitlab/os-linux.yml @@ -372,6 +372,28 @@ CMAKE_CONFIGURATION: linux_gcc_cxx_modules_ninja_multi CMAKE_GENERATOR: "Ninja Multi-Config" +.clang_cxx_modules_x86_64: + image: "kitware/cmake:ci-clang_cxx_modules-x86_64-2022-12-02" + + variables: + GIT_CLONE_PATH: "$CI_BUILDS_DIR/cmake ci" + CMAKE_ARCH: x86_64 + CC: "/opt/llvm-p1689/bin/clang" + CXX: "/opt/llvm-p1689/bin/clang++" + +.clang_cxx_modules_ninja: + extends: .clang_cxx_modules_x86_64 + + variables: + CMAKE_CONFIGURATION: linux_clang_cxx_modules_ninja + +.clang_cxx_modules_ninja_multi: + extends: .clang_cxx_modules_x86_64 + + variables: + CMAKE_CONFIGURATION: linux_clang_cxx_modules_ninja_multi + CMAKE_GENERATOR: "Ninja Multi-Config" + ## Tags .linux_x86_64_tags: diff --git a/Help/dev/experimental.rst b/Help/dev/experimental.rst index 794a686..fbbad30 100644 --- a/Help/dev/experimental.rst +++ b/Help/dev/experimental.rst @@ -102,9 +102,9 @@ For compilers that generate module maps, tell CMake as follows: set(CMAKE_EXPERIMENTAL_CXX_MODULE_MAP_FLAG "${compiler_flags_for_module_map} -fmodule-mapper=<MODULE_MAP_FILE>") -Currently, the only supported formats are ``gcc`` and ``msvc``. The ``gcc`` -format is described in the GCC documentation, but the relevant section for the -purposes of CMake is: +Currently, the only supported formats are, ``clang``, ``gcc``, and ``msvc``. +The ``gcc`` format is described in the GCC documentation, but the relevant +section for the purposes of CMake is: A mapping file consisting of space-separated module-name, filename pairs, one per line. Only the mappings for the direct imports and any @@ -119,6 +119,9 @@ The ``msvc`` format is a response file containing flags required to compile any module interfaces properly as well as find any required files to satisfy ``import`` statements as required for Microsoft's Visual Studio toolchains. +Similarly, the ``clang`` format is a response file containing flags using +Clang's module flags. + .. _`D1483r1`: https://mathstuf.fedorapeople.org/fortran-modules/fortran-modules.html .. _`P1689r5`: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p1689r5.html .. _`cxx-modules-sandbox`: https://github.com/mathstuf/cxx-modules-sandbox diff --git a/Modules/Compiler/Clang-FindBinUtils.cmake b/Modules/Compiler/Clang-FindBinUtils.cmake index 125ae78..daf0371 100644 --- a/Modules/Compiler/Clang-FindBinUtils.cmake +++ b/Modules/Compiler/Clang-FindBinUtils.cmake @@ -43,3 +43,14 @@ find_program(CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_RANLIB NAMES DOC "Generate index for LLVM archive" ) mark_as_advanced(CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_RANLIB) + +# clang-scan-deps +find_program(CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_CLANG_SCAN_DEPS NAMES + "${_CMAKE_TOOLCHAIN_PREFIX}clang-scan-deps-${__version_x_y}" + "${_CMAKE_TOOLCHAIN_PREFIX}clang-scan-deps-${__version_x}" + "${_CMAKE_TOOLCHAIN_PREFIX}clang-scan-deps" + HINTS ${__clang_hints} + NO_CMAKE_PATH NO_CMAKE_ENVIRONMENT_PATH + DOC "`clang-scan-deps` dependency scanner" +) +mark_as_advanced(CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_CLANG_SCAN_DEPS) diff --git a/Source/cmCxxModuleMapper.cxx b/Source/cmCxxModuleMapper.cxx index 84691c9..ca4ffdf 100644 --- a/Source/cmCxxModuleMapper.cxx +++ b/Source/cmCxxModuleMapper.cxx @@ -28,6 +28,38 @@ cm::optional<std::string> CxxModuleLocations::BmiGeneratorPathForModule( namespace { +std::string CxxModuleMapContentClang(CxxModuleLocations const& loc, + cmScanDepInfo const& obj) +{ + std::stringstream mm; + + // Clang's command line only supports a single output. If more than one is + // expected, we cannot make a useful module map file. + if (obj.Provides.size() > 1) { + return {}; + } + + // A series of flags which tell the compiler where to look for modules. + + for (auto const& p : obj.Provides) { + if (auto bmi_loc = loc.BmiGeneratorPathForModule(p.LogicalName)) { + // Force the TU to be considered a C++ module source file regardless of + // extension. + mm << "-x c++-module\n"; + + mm << "-fsave-std-c++-module-file=" << *bmi_loc << '\n'; + break; + } + } + for (auto const& r : obj.Requires) { + if (auto bmi_loc = loc.BmiGeneratorPathForModule(r.LogicalName)) { + mm << "-fmodule-file=" << *bmi_loc << '\n'; + } + } + + return mm.str(); +} + std::string CxxModuleMapContentGcc(CxxModuleLocations const& loc, cmScanDepInfo const& obj) { @@ -179,6 +211,8 @@ cm::static_string_view CxxModuleMapExtension( { if (format) { switch (*format) { + case CxxModuleMapFormat::Clang: + return ".pcm"_s; case CxxModuleMapFormat::Gcc: return ".gcm"_s; case CxxModuleMapFormat::Msvc: @@ -297,6 +331,8 @@ std::string CxxModuleMapContent(CxxModuleMapFormat format, CxxModuleUsage const& usages) { switch (format) { + case CxxModuleMapFormat::Clang: + return CxxModuleMapContentClang(loc, obj); case CxxModuleMapFormat::Gcc: return CxxModuleMapContentGcc(loc, obj); case CxxModuleMapFormat::Msvc: diff --git a/Source/cmCxxModuleMapper.h b/Source/cmCxxModuleMapper.h index 8526a07..9271978 100644 --- a/Source/cmCxxModuleMapper.h +++ b/Source/cmCxxModuleMapper.h @@ -17,6 +17,7 @@ enum class CxxModuleMapFormat { + Clang, Gcc, Msvc, }; diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index 4500f33..f7753da 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -2567,6 +2567,8 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile( cm::optional<CxxModuleMapFormat> modmap_fmt; if (arg_modmapfmt.empty()) { // nothing to do. + } else if (arg_modmapfmt == "clang") { + modmap_fmt = CxxModuleMapFormat::Clang; } else if (arg_modmapfmt == "gcc") { modmap_fmt = CxxModuleMapFormat::Gcc; } else if (arg_modmapfmt == "msvc") { diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index 85a6fc2..3912632 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -542,9 +542,12 @@ cmNinjaRule GetScanRule( // Scanning always uses a depfile for preprocessor dependencies. if (deptype == "msvc"_s) { rule.DepType = deptype; - rule.DepFile = ""; + rule.DepFile.clear(); + } else if (deptype == "none"_s) { + rule.DepType.clear(); // no deps= for multiple outputs + rule.DepFile.clear(); } else { - rule.DepType = ""; // no deps= for multiple outputs + rule.DepType.clear(); // no deps= for multiple outputs rule.DepFile = "$DEP_FILE"; } diff --git a/Tests/RunCMake/CXXModules/examples/cxx-modules-find-bmi.cmake b/Tests/RunCMake/CXXModules/examples/cxx-modules-find-bmi.cmake index 91f3995..88d50db 100644 --- a/Tests/RunCMake/CXXModules/examples/cxx-modules-find-bmi.cmake +++ b/Tests/RunCMake/CXXModules/examples/cxx-modules-find-bmi.cmake @@ -1,6 +1,6 @@ function (check_for_bmi prefix destination name) set(found 0) - foreach (ext IN ITEMS gcm ifc) + foreach (ext IN ITEMS gcm ifc pcm) if (EXISTS "${prefix}/${destination}/${name}.${ext}") set(found 1) break () |