summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2022-12-06 13:04:07 (GMT)
committerKitware Robot <kwrobot@kitware.com>2022-12-06 13:04:18 (GMT)
commitf1f064b7b2c93048897014e096217e1a00f668c7 (patch)
tree6cd0ff2dbc453a45105743af22556072a1231ada
parent85d89ca88586be09e940fea938d2a2add5dd4425 (diff)
parent2c558cfd1b26e879bf6acce619255ca7b1ba0425 (diff)
downloadCMake-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.yml20
-rw-r--r--.gitlab/ci/configure_linux_clang_cxx_modules_ninja.cmake4
-rw-r--r--.gitlab/ci/configure_linux_clang_cxx_modules_ninja_multi.cmake4
-rw-r--r--.gitlab/ci/cxx_modules_rules_clang.cmake16
-rw-r--r--.gitlab/ci/docker/clang_cxx_modules/Dockerfile13
-rwxr-xr-x.gitlab/ci/docker/clang_cxx_modules/install_cmake_deps.sh7
-rwxr-xr-x.gitlab/ci/docker/clang_cxx_modules/install_deps.sh7
-rwxr-xr-x.gitlab/ci/docker/clang_cxx_modules/install_llvm.sh39
-rw-r--r--.gitlab/os-linux.yml22
-rw-r--r--Help/dev/experimental.rst9
-rw-r--r--Modules/Compiler/Clang-FindBinUtils.cmake11
-rw-r--r--Source/cmCxxModuleMapper.cxx36
-rw-r--r--Source/cmCxxModuleMapper.h1
-rw-r--r--Source/cmGlobalNinjaGenerator.cxx2
-rw-r--r--Source/cmNinjaTargetGenerator.cxx7
-rw-r--r--Tests/RunCMake/CXXModules/examples/cxx-modules-find-bmi.cmake2
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 ()