mirror of
https://github.com/Kitware/CMake.git
synced 2026-05-06 14:19:59 -05:00
Merge topic 'cpp-named-module-file-sets'
07bc3b07ecgitlab-ci: test C++ modules using GCC1b2270aa4eci: add a Docker image to test out C++ modules with GCC8c5a53096aTests/RunCMake/CXXModules: add module-using examples4151547e2fcmGlobalNinjaGenerator: use `cmModuleMapper` implementationb43bdaff3ccmCxxModuleMapper: implement support for GCC's module map format02d0f0e752cmCxxModuleMapper: add source to handle module mapper contentsa046a45aadcmGlobalNinjaGenerator: add a TODO for header units386465bf83cmTarget: add support for C++ module fileset types ... Acked-by: Kitware Robot <kwrobot@kitware.com> Tested-by: buildbot <buildbot@kitware.com> Merge-request: !7369
This commit is contained in:
@@ -275,6 +275,26 @@ t:hip4.2-radeon:
|
||||
variables:
|
||||
CMAKE_CI_NO_MR: "true"
|
||||
|
||||
t:linux-gcc-cxx-modules-ninja:
|
||||
extends:
|
||||
- .gcc_cxx_modules_ninja
|
||||
- .cmake_test_linux_release
|
||||
- .linux_builder_tags
|
||||
- .run_dependent
|
||||
- .needs_centos6_x86_64
|
||||
variables:
|
||||
CMAKE_CI_JOB_NIGHTLY: "true"
|
||||
|
||||
t:linux-gcc-cxx-modules-ninja-multi:
|
||||
extends:
|
||||
- .gcc_cxx_modules_ninja_multi
|
||||
- .cmake_test_linux_release
|
||||
- .linux_builder_tags
|
||||
- .run_dependent
|
||||
- .needs_centos6_x86_64
|
||||
variables:
|
||||
CMAKE_CI_JOB_NIGHTLY: "true"
|
||||
|
||||
b:fedora36-ninja:
|
||||
extends:
|
||||
- .fedora36_ninja
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
set(CMake_TEST_MODULE_COMPILATION "named,partitions,internal_partitions" CACHE STRING "")
|
||||
set(CMake_TEST_MODULE_COMPILATION_RULES "${CMAKE_CURRENT_LIST_DIR}/cxx_modules_rules_gcc.cmake" CACHE STRING "")
|
||||
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/configure_external_test.cmake")
|
||||
@@ -0,0 +1,4 @@
|
||||
set(CMake_TEST_MODULE_COMPILATION "named,partitions,internal_partitions" CACHE STRING "")
|
||||
set(CMake_TEST_MODULE_COMPILATION_RULES "${CMAKE_CURRENT_LIST_DIR}/cxx_modules_rules_gcc.cmake" CACHE STRING "")
|
||||
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/configure_external_test.cmake")
|
||||
@@ -0,0 +1,10 @@
|
||||
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> <DEFINES> <INCLUDES> <FLAGS> -E -x c++ <SOURCE>"
|
||||
" -MT <DYNDEP_FILE> -MD -MF <DEP_FILE>"
|
||||
" -fmodules-ts -fdep-file=<DYNDEP_FILE> -fdep-output=<OBJECT> -fdep-format=trtbd"
|
||||
" -o <PREPROCESSED_SOURCE>")
|
||||
set(CMAKE_EXPERIMENTAL_CXX_MODULE_MAP_FORMAT "gcc")
|
||||
set(CMAKE_EXPERIMENTAL_CXX_MODULE_MAP_FLAG "-fmodules-ts -fmodule-mapper=<MODULE_MAP_FILE> -fdep-format=trtbd -x c++")
|
||||
@@ -0,0 +1,9 @@
|
||||
FROM fedora:36
|
||||
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_gcc.sh /root/install_gcc.sh
|
||||
RUN sh /root/install_gcc.sh
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
dnf install -y --setopt=install_weak_deps=False \
|
||||
gcc-c++ mpfr-devel libmpc-devel isl-devel flex bison file findutils diffutils
|
||||
dnf clean all
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
readonly revision="p1689r5-cmake-ci-20220614" # 3075e510e3d29583f8886b95aff044c0474c84a5
|
||||
readonly tarball="https://github.com/mathstuf/gcc/archive/$revision.tar.gz"
|
||||
|
||||
readonly workdir="$HOME/gcc"
|
||||
readonly srcdir="$workdir/gcc"
|
||||
readonly builddir="$workdir/build"
|
||||
readonly njobs="$( nproc )"
|
||||
|
||||
mkdir -p "$workdir"
|
||||
cd "$workdir"
|
||||
curl -L "$tarball" > "gcc-$revision.tar.gz"
|
||||
tar xf "gcc-$revision.tar.gz"
|
||||
mv "gcc-$revision" "$srcdir"
|
||||
mkdir -p "$builddir"
|
||||
cd "$builddir"
|
||||
"$srcdir/configure" \
|
||||
--disable-multilib \
|
||||
--enable-languages=c,c++ \
|
||||
--prefix="/opt/gcc-p1689"
|
||||
make "-j$njobs"
|
||||
make "-j$njobs" install-strip
|
||||
rm -rf "$workdir"
|
||||
@@ -299,6 +299,30 @@
|
||||
CMAKE_CONFIGURATION: hip4.2_radeon
|
||||
CMAKE_GENERATOR: "Ninja Multi-Config"
|
||||
|
||||
### C++ modules
|
||||
|
||||
.gcc_cxx_modules_x86_64:
|
||||
image: "kitware/cmake:ci-gcc_cxx_modules-x86_64-2022-06-14"
|
||||
|
||||
variables:
|
||||
GIT_CLONE_PATH: "$CI_BUILDS_DIR/cmake ci"
|
||||
CMAKE_ARCH: x86_64
|
||||
CC: "/opt/gcc-p1689/bin/gcc"
|
||||
CXX: "/opt/gcc-p1689/bin/g++"
|
||||
|
||||
.gcc_cxx_modules_ninja:
|
||||
extends: .gcc_cxx_modules_x86_64
|
||||
|
||||
variables:
|
||||
CMAKE_CONFIGURATION: linux_gcc_cxx_modules_ninja
|
||||
|
||||
.gcc_cxx_modules_ninja_multi:
|
||||
extends: .gcc_cxx_modules_x86_64
|
||||
|
||||
variables:
|
||||
CMAKE_CONFIGURATION: linux_gcc_cxx_modules_ninja_multi
|
||||
CMAKE_GENERATOR: "Ninja Multi-Config"
|
||||
|
||||
## Tags
|
||||
|
||||
.linux_builder_tags:
|
||||
|
||||
@@ -75,9 +75,33 @@ File Sets
|
||||
Adds a file set to a target, or adds files to an existing file set. Targets
|
||||
have zero or more named file sets. Each file set has a name, a type, a scope of
|
||||
``INTERFACE``, ``PUBLIC``, or ``PRIVATE``, one or more base directories, and
|
||||
files within those directories. The only acceptable type is ``HEADERS``. The
|
||||
optional default file sets are named after their type. The target may not be a
|
||||
custom target or :prop_tgt:`FRAMEWORK` target.
|
||||
files within those directories. The acceptable types include:
|
||||
|
||||
``HEADERS``
|
||||
|
||||
Sources intended to be used via a language's ``#include`` mechanism.
|
||||
|
||||
``CXX_MODULES``
|
||||
|
||||
.. note ::
|
||||
|
||||
Experimental. Gated by ``CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API``
|
||||
|
||||
Sources which contain C++ interface module or partition units (i.e., those
|
||||
using the ``export`` keyword). This file set type may not have an
|
||||
``INTERFACE`` scope.
|
||||
|
||||
``CXX_MODULE_HEADER_UNITS``
|
||||
|
||||
.. note ::
|
||||
|
||||
Experimental. Gated by ``CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API``
|
||||
|
||||
C++ header sources which may be imported by other C++ source code. This file
|
||||
set type may not have an ``INTERFACE`` scope.
|
||||
|
||||
The optional default file sets are named after their type. The target may not
|
||||
be a custom target or :prop_tgt:`FRAMEWORK` target.
|
||||
|
||||
Files in a ``PRIVATE`` or ``PUBLIC`` file set are marked as source files for
|
||||
the purposes of IDE integration. Additionally, files in ``HEADERS`` file sets
|
||||
@@ -93,16 +117,17 @@ Each ``target_sources(FILE_SET)`` entry starts with ``INTERFACE``, ``PUBLIC``, o
|
||||
|
||||
The name of the file set to create or add to. It must contain only letters,
|
||||
numbers and underscores. Names starting with a capital letter are reserved
|
||||
for built-in file sets predefined by CMake. The only predefined set name is
|
||||
``HEADERS``. All other set names must not start with a capital letter or
|
||||
for built-in file sets predefined by CMake. The only predefined set names
|
||||
are those matching the acceptable types. All other set names must not start
|
||||
with a capital letter or
|
||||
underscore.
|
||||
|
||||
``TYPE <type>``
|
||||
|
||||
Every file set is associated with a particular type of file. ``HEADERS``
|
||||
is currently the only defined type and it is an error to specify anything
|
||||
else. As a special case, if the name of the file set is ``HEADERS``, the
|
||||
type does not need to be specified and the ``TYPE <type>`` arguments can be
|
||||
Every file set is associated with a particular type of file. Only types
|
||||
specified above may be used and it is an error to specify anything else. As
|
||||
a special case, if the name of the file set is one of the types, the type
|
||||
does not need to be specified and the ``TYPE <type>`` arguments can be
|
||||
omitted. For all other file set names, ``TYPE`` is required.
|
||||
|
||||
``BASE_DIRS <dirs>...``
|
||||
@@ -134,6 +159,8 @@ Each ``target_sources(FILE_SET)`` entry starts with ``INTERFACE``, ``PUBLIC``, o
|
||||
The following target properties are set by ``target_sources(FILE_SET)``,
|
||||
but they should not generally be manipulated directly:
|
||||
|
||||
For file sets of type ``HEADERS``:
|
||||
|
||||
* :prop_tgt:`HEADER_SETS`
|
||||
* :prop_tgt:`INTERFACE_HEADER_SETS`
|
||||
* :prop_tgt:`HEADER_SET`
|
||||
@@ -141,17 +168,37 @@ but they should not generally be manipulated directly:
|
||||
* :prop_tgt:`HEADER_DIRS`
|
||||
* :prop_tgt:`HEADER_DIRS_<NAME>`
|
||||
|
||||
For file sets of type ``CXX_MODULES``:
|
||||
|
||||
* :prop_tgt:`CXX_MODULE_SETS`
|
||||
* :prop_tgt:`INTERFACE_CXX_MODULE_SETS`
|
||||
* :prop_tgt:`CXX_MODULE_SET`
|
||||
* :prop_tgt:`CXX_MODULE_SET_<NAME>`
|
||||
* :prop_tgt:`CXX_MODULE_DIRS`
|
||||
* :prop_tgt:`CXX_MODULE_DIRS_<NAME>`
|
||||
|
||||
For file sets of type ``CXX_MODULE_HEADER_UNITS``:
|
||||
|
||||
* :prop_tgt:`CXX_MODULE_HEADER_UNIT_SETS`
|
||||
* :prop_tgt:`INTERFACE_CXX_MODULE_HEADER_UNIT_SETS`
|
||||
* :prop_tgt:`CXX_MODULE_HEADER_UNIT_SET`
|
||||
* :prop_tgt:`CXX_MODULE_HEADER_UNIT_SET_<NAME>`
|
||||
* :prop_tgt:`CXX_MODULE_HEADER_UNIT_DIRS`
|
||||
* :prop_tgt:`CXX_MODULE_HEADER_UNIT_DIRS_<NAME>`
|
||||
|
||||
Target properties related to include directories are also modified by
|
||||
``target_sources(FILE_SET)`` as follows:
|
||||
|
||||
:prop_tgt:`INCLUDE_DIRECTORIES`
|
||||
|
||||
If the ``TYPE`` is ``HEADERS``, and the scope of the file set is ``PRIVATE``
|
||||
or ``PUBLIC``, all of the ``BASE_DIRS`` of the file set are wrapped in
|
||||
:genex:`$<BUILD_INTERFACE>` and appended to this property.
|
||||
If the ``TYPE`` is ``HEADERS`` or ``CXX_MODULE_HEADER_UNITS``, and the scope
|
||||
of the file set is ``PRIVATE`` or ``PUBLIC``, all of the ``BASE_DIRS`` of
|
||||
the file set are wrapped in :genex:`$<BUILD_INTERFACE>` and appended to this
|
||||
property.
|
||||
|
||||
:prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES`
|
||||
|
||||
If the ``TYPE`` is ``HEADERS``, and the scope of the file set is
|
||||
``INTERFACE`` or ``PUBLIC``, all of the ``BASE_DIRS`` of the file set are
|
||||
wrapped in :genex:`$<BUILD_INTERFACE>` and appended to this property.
|
||||
If the ``TYPE`` is ``HEADERS`` or ``CXX_MODULE_HEADER_UNITS``, and the scope
|
||||
of the file set is ``INTERFACE`` or ``PUBLIC``, all of the ``BASE_DIRS`` of
|
||||
the file set are wrapped in :genex:`$<BUILD_INTERFACE>` and appended to this
|
||||
property.
|
||||
|
||||
@@ -7,6 +7,23 @@ See documentation on `CMake Development`_ for more information.
|
||||
|
||||
.. _`CMake Development`: README.rst
|
||||
|
||||
Features are gated behind ``CMAKE_EXPERIMENTAL_`` variables which must be set
|
||||
to specific values in order to enable their gated behaviors. Note that the
|
||||
specific values will change over time to reinforce their experimental nature.
|
||||
When used, a warning will be generated to indicate that an experimental
|
||||
feature is in use and that the affected behavior in the project is not part of
|
||||
CMake's stability guarantees.
|
||||
|
||||
C++20 Module APIs
|
||||
=================
|
||||
|
||||
Variable: ``CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API``
|
||||
Value: ``17be90bd-a850-44e0-be50-448de847d652``
|
||||
|
||||
In order to support C++20 modules, there are a number of behaviors that have
|
||||
CMake APIs to provide the required features to build and export them from a
|
||||
project.
|
||||
|
||||
C++20 Module Dependencies
|
||||
=========================
|
||||
|
||||
@@ -40,11 +57,6 @@ dependencies to the file specified by the ``<DYNDEP_FILE>`` placeholder. The
|
||||
``CMAKE_EXPERIMENTAL_CXX_SCANDEP_DEPFILE_FORMAT`` file may be set to ``msvc``
|
||||
for scandep rules which use ``msvc``-style dependency reporting.
|
||||
|
||||
For tools which need to know the file set the source belongs to, the
|
||||
``CMAKE_EXPERIMENTAL_CXX_MODULE_SOURCE_TYPE_FLAG_<FILE_SET_TYPE>`` flag may
|
||||
be provided so that different source types can be distinguished prior to
|
||||
scanning.
|
||||
|
||||
The module dependencies should be written in the format described
|
||||
by the `P1689r4`_ paper.
|
||||
|
||||
|
||||
@@ -184,6 +184,16 @@ Properties on Targets
|
||||
/prop_tgt/CUDA_STANDARD
|
||||
/prop_tgt/CUDA_STANDARD_REQUIRED
|
||||
/prop_tgt/CXX_EXTENSIONS
|
||||
/prop_tgt/CXX_MODULE_DIRS
|
||||
/prop_tgt/CXX_MODULE_DIRS_NAME
|
||||
/prop_tgt/CXX_MODULE_SET
|
||||
/prop_tgt/CXX_MODULE_SET_NAME
|
||||
/prop_tgt/CXX_MODULE_SETS
|
||||
/prop_tgt/CXX_MODULE_HEADER_UNIT_DIRS
|
||||
/prop_tgt/CXX_MODULE_HEADER_UNIT_DIRS_NAME
|
||||
/prop_tgt/CXX_MODULE_HEADER_UNIT_SET
|
||||
/prop_tgt/CXX_MODULE_HEADER_UNIT_SET_NAME
|
||||
/prop_tgt/CXX_MODULE_HEADER_UNIT_SETS
|
||||
/prop_tgt/CXX_STANDARD
|
||||
/prop_tgt/CXX_STANDARD_REQUIRED
|
||||
/prop_tgt/DEBUG_POSTFIX
|
||||
@@ -262,6 +272,8 @@ Properties on Targets
|
||||
/prop_tgt/INTERFACE_COMPILE_DEFINITIONS
|
||||
/prop_tgt/INTERFACE_COMPILE_FEATURES
|
||||
/prop_tgt/INTERFACE_COMPILE_OPTIONS
|
||||
/prop_tgt/INTERFACE_CXX_MODULE_SETS
|
||||
/prop_tgt/INTERFACE_CXX_MODULE_HEADER_UNIT_SETS
|
||||
/prop_tgt/INTERFACE_HEADER_SETS
|
||||
/prop_tgt/INTERFACE_HEADER_SETS_TO_VERIFY
|
||||
/prop_tgt/INTERFACE_INCLUDE_DIRECTORIES
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
CXX_MODULE_DIRS
|
||||
---------------
|
||||
|
||||
.. note ::
|
||||
|
||||
Experimental. Gated by ``CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API``
|
||||
|
||||
Semicolon-separated list of base directories of the target's default
|
||||
C++ module set (i.e. the file set with name and type ``CXX_MODULES``). The
|
||||
property supports
|
||||
:manual:`generator expressions <cmake-generator-expressions(7)>`.
|
||||
|
||||
This property is normally only set by :command:`target_sources(FILE_SET)`
|
||||
rather than being manipulated directly.
|
||||
|
||||
See :prop_tgt:`CXX_MODULE_DIRS_<NAME>` for the list of base directories in
|
||||
other C++ module sets.
|
||||
@@ -0,0 +1,17 @@
|
||||
CXX_MODULE_DIRS_<NAME>
|
||||
----------------------
|
||||
|
||||
.. note ::
|
||||
|
||||
Experimental. Gated by ``CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API``
|
||||
|
||||
Semicolon-separated list of base directories of the target's ``<NAME>`` C++
|
||||
module set, which has the set type ``CXX_MODULES``. The property supports
|
||||
:manual:`generator expressions <cmake-generator-expressions(7)>`.
|
||||
|
||||
This property is normally only set by :command:`target_sources(FILE_SET)`
|
||||
rather than being manipulated directly.
|
||||
|
||||
See :prop_tgt:`CXX_MODULE_DIRS` for the list of base directories in the
|
||||
default C++ module set. See :prop_tgt:`CXX_MODULE_SETS` for the file set names
|
||||
of all C++ module sets.
|
||||
@@ -0,0 +1,17 @@
|
||||
CXX_MODULE_HEADER_UNIT_DIRS
|
||||
---------------------------
|
||||
|
||||
.. note ::
|
||||
|
||||
Experimental. Gated by ``CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API``
|
||||
|
||||
Semicolon-separated list of base directories of the target's default C++
|
||||
module header set (i.e. the file set with name and type
|
||||
``CXX_MODULE_HEADER_UNITS``). The property supports
|
||||
:manual:`generator expressions <cmake-generator-expressions(7)>`.
|
||||
|
||||
This property is normally only set by :command:`target_sources(FILE_SET)`
|
||||
rather than being manipulated directly.
|
||||
|
||||
See :prop_tgt:`CXX_MODULE_HEADER_UNIT_DIRS_<NAME>` for the list of base directories
|
||||
in other C++ module header sets.
|
||||
@@ -0,0 +1,19 @@
|
||||
CXX_MODULE_HEADER_UNIT_DIRS_<NAME>
|
||||
----------------------------------
|
||||
|
||||
.. note ::
|
||||
|
||||
Experimental. Gated by ``CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API``
|
||||
|
||||
Semicolon-separated list of base directories of the target's ``<NAME>`` C++
|
||||
module header set, which has the set type ``CXX_MODULE_HEADER_UNITS``. The
|
||||
property supports
|
||||
:manual:`generator expressions <cmake-generator-expressions(7)>`.
|
||||
|
||||
This property is normally only set by :command:`target_sources(FILE_SET)`
|
||||
rather than being manipulated directly.
|
||||
|
||||
See :prop_tgt:`CXX_MODULE_HEADER_UNIT_DIRS` for the list of base directories
|
||||
in the default C++ module header set. See
|
||||
:prop_tgt:`CXX_MODULE_HEADER_UNIT_SETS` for the file set names of all C++
|
||||
module header sets.
|
||||
@@ -0,0 +1,18 @@
|
||||
CXX_MODULE_HEADER_UNIT_SET
|
||||
--------------------------
|
||||
|
||||
.. note ::
|
||||
|
||||
Experimental. Gated by ``CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API``
|
||||
|
||||
Semicolon-separated list of files in the target's default C++ module header
|
||||
set, (i.e. the file set with name and type ``CXX_MODULE_HEADER_UNITS``). If
|
||||
any of the paths are relative, they are computed relative to the target's
|
||||
source directory. The property supports
|
||||
:manual:`generator expressions <cmake-generator-expressions(7)>`.
|
||||
|
||||
This property is normally only set by :command:`target_sources(FILE_SET)`
|
||||
rather than being manipulated directly.
|
||||
|
||||
See :prop_tgt:`CXX_MODULE_HEADER_UNIT_SET_<NAME>` for the list of files in
|
||||
other C++ module header sets.
|
||||
@@ -0,0 +1,18 @@
|
||||
CXX_MODULE_HEADER_UNIT_SETS
|
||||
---------------------------
|
||||
|
||||
.. note ::
|
||||
|
||||
Experimental. Gated by ``CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API``
|
||||
|
||||
Read-only list of the target's ``PRIVATE`` and ``PUBLIC`` C++ module header
|
||||
sets (i.e. all file sets with the type ``CXX_MODULE_HEADER_UNITS``). Files
|
||||
listed in these file sets are treated as source files for the purpose of IDE
|
||||
integration.
|
||||
|
||||
C++ module header sets may be defined using the :command:`target_sources`
|
||||
command ``FILE_SET`` option with type ``CXX_MODULE_HEADER_UNITS``.
|
||||
|
||||
See also :prop_tgt:`CXX_MODULE_HEADER_UNIT_SET_<NAME>`,
|
||||
:prop_tgt:`CXX_MODULE_HEADER_UNIT_SET` and
|
||||
:prop_tgt:`INTERFACE_CXX_MODULE_HEADER_UNIT_SETS`.
|
||||
@@ -0,0 +1,19 @@
|
||||
CXX_MODULE_HEADER_UNIT_SET_<NAME>
|
||||
---------------------------------
|
||||
|
||||
.. note ::
|
||||
|
||||
Experimental. Gated by ``CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API``
|
||||
|
||||
Semicolon-separated list of files in the target's ``<NAME>`` C++ module header
|
||||
set, which has the set type ``CXX_MODULE_HEADER_UNITS``. If any of the paths
|
||||
are relative, they are computed relative to the target's source directory. The
|
||||
property supports
|
||||
:manual:`generator expressions <cmake-generator-expressions(7)>`.
|
||||
|
||||
This property is normally only set by :command:`target_sources(FILE_SET)`
|
||||
rather than being manipulated directly.
|
||||
|
||||
See :prop_tgt:`CXX_MODULE_HEADER_UNIT_SET` for the list of files in the
|
||||
default C++ module header set. See :prop_tgt:`CXX_MODULE_HEADER_UNIT_SETS` for
|
||||
the file set names of all C++ module header sets.
|
||||
@@ -0,0 +1,18 @@
|
||||
CXX_MODULE_SET
|
||||
--------------
|
||||
|
||||
.. note ::
|
||||
|
||||
Experimental. Gated by ``CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API``
|
||||
|
||||
Semicolon-separated list of files in the target's default C++ module set,
|
||||
(i.e. the file set with name and type ``CXX_MODULES``). If any of the paths
|
||||
are relative, they are computed relative to the target's source directory. The
|
||||
property supports
|
||||
:manual:`generator expressions <cmake-generator-expressions(7)>`.
|
||||
|
||||
This property is normally only set by :command:`target_sources(FILE_SET)`
|
||||
rather than being manipulated directly.
|
||||
|
||||
See :prop_tgt:`CXX_MODULE_SET_<NAME>` for the list of files in other C++
|
||||
module sets.
|
||||
@@ -0,0 +1,16 @@
|
||||
CXX_MODULE_SETS
|
||||
---------------
|
||||
|
||||
.. note ::
|
||||
|
||||
Experimental. Gated by ``CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API``
|
||||
|
||||
Read-only list of the target's ``PRIVATE`` and ``PUBLIC`` C++ module sets (i.e.
|
||||
all file sets with the type ``CXX_MODULES``). Files listed in these file sets are
|
||||
treated as source files for the purpose of IDE integration.
|
||||
|
||||
C++ module sets may be defined using the :command:`target_sources` command
|
||||
``FILE_SET`` option with type ``CXX_MODULES``.
|
||||
|
||||
See also :prop_tgt:`CXX_MODULE_SET_<NAME>`, :prop_tgt:`CXX_MODULE_SET` and
|
||||
:prop_tgt:`INTERFACE_CXX_MODULE_SETS`.
|
||||
@@ -0,0 +1,18 @@
|
||||
CXX_MODULE_SET_<NAME>
|
||||
---------------------
|
||||
|
||||
.. note ::
|
||||
|
||||
Experimental. Gated by ``CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API``
|
||||
|
||||
Semicolon-separated list of files in the target's ``<NAME>`` C++ module set,
|
||||
which has the set type ``CXX_MODULES``. If any of the paths are relative, they
|
||||
are computed relative to the target's source directory. The property supports
|
||||
:manual:`generator expressions <cmake-generator-expressions(7)>`.
|
||||
|
||||
This property is normally only set by :command:`target_sources(FILE_SET)`
|
||||
rather than being manipulated directly.
|
||||
|
||||
See :prop_tgt:`CXX_MODULE_SET` for the list of files in the default C++ module
|
||||
set. See :prop_tgt:`CXX_MODULE_SETS` for the file set names of all C++ module
|
||||
sets.
|
||||
@@ -0,0 +1,16 @@
|
||||
INTERFACE_CXX_MODULE_HEADER_UNIT_SETS
|
||||
-------------------------------------
|
||||
|
||||
.. note ::
|
||||
|
||||
Experimental. Gated by ``CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API``
|
||||
|
||||
Read-only list of the target's ``PUBLIC`` C++ module header sets (i.e. all
|
||||
file sets with the type ``CXX_MODULE_HEADER_UNITS``). Files listed in these
|
||||
C++ module header sets can be installed with :command:`install(TARGETS)` and
|
||||
exported with :command:`install(EXPORT)` and :command:`export`.
|
||||
|
||||
C++ module header sets may be defined using the :command:`target_sources`
|
||||
command ``FILE_SET`` option with type ``CXX_MODULE_HEADER_UNITS``.
|
||||
|
||||
See also :prop_tgt:`CXX_MODULE_HEADER_UNIT_SETS`.
|
||||
@@ -0,0 +1,16 @@
|
||||
INTERFACE_CXX_MODULE_SETS
|
||||
-------------------------
|
||||
|
||||
.. note ::
|
||||
|
||||
Experimental. Gated by ``CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API``
|
||||
|
||||
Read-only list of the target's ``PUBLIC`` C++ module sets (i.e. all file sets
|
||||
with the type ``CXX_MODULES``). Files listed in these C++ module sets can be
|
||||
installed with :command:`install(TARGETS)` and exported with
|
||||
:command:`install(EXPORT)` and :command:`export`.
|
||||
|
||||
C++ module sets may be defined using the :command:`target_sources` command
|
||||
``FILE_SET`` option with type ``CXX_MODULES``.
|
||||
|
||||
See also :prop_tgt:`CXX_MODULE_SETS`.
|
||||
@@ -197,6 +197,8 @@ set(SRCS
|
||||
cmCustomCommandLines.cxx
|
||||
cmCustomCommandLines.h
|
||||
cmCustomCommandTypes.h
|
||||
cmCxxModuleMapper.cxx
|
||||
cmCxxModuleMapper.h
|
||||
cmDefinitions.cxx
|
||||
cmDefinitions.h
|
||||
cmDependencyProvider.h
|
||||
@@ -543,6 +545,8 @@ set(SRCS
|
||||
cmExecuteProcessCommand.h
|
||||
cmExpandedCommandArgument.cxx
|
||||
cmExpandedCommandArgument.h
|
||||
cmExperimental.cxx
|
||||
cmExperimental.h
|
||||
cmExportCommand.cxx
|
||||
cmExportCommand.h
|
||||
cmExportLibraryDependenciesCommand.cxx
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "cmComputeLinkInformation.h"
|
||||
#include "cmGeneratorTarget.h"
|
||||
#include "cmGlobalCommonGenerator.h"
|
||||
#include "cmGlobalGenerator.h"
|
||||
#include "cmLocalCommonGenerator.h"
|
||||
#include "cmLocalGenerator.h"
|
||||
#include "cmMakefile.h"
|
||||
@@ -175,6 +176,9 @@ std::vector<std::string> cmCommonTargetGenerator::GetLinkedTargetDirectories(
|
||||
cmLocalGenerator* lg = linkee->GetLocalGenerator();
|
||||
std::string di = cmStrCat(lg->GetCurrentBinaryDirectory(), '/',
|
||||
lg->GetTargetDirectory(linkee));
|
||||
if (lg->GetGlobalGenerator()->IsMultiConfig()) {
|
||||
di = cmStrCat(di, '/', config);
|
||||
}
|
||||
dirs.push_back(std::move(di));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||
#include "cmCxxModuleMapper.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
|
||||
#include "cmScanDepFormat.h"
|
||||
|
||||
cm::optional<std::string> CxxModuleLocations::BmiGeneratorPathForModule(
|
||||
std::string const& logical_name) const
|
||||
{
|
||||
if (auto l = this->BmiLocationForModule(logical_name)) {
|
||||
return this->PathForGenerator(*l);
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
std::string CxxModuleMapContentGcc(CxxModuleLocations const& loc,
|
||||
cmScanDepInfo const& obj)
|
||||
{
|
||||
std::stringstream mm;
|
||||
|
||||
// Documented in GCC's documentation. The format is a series of
|
||||
// lines with a module name and the associated filename separated
|
||||
// by spaces. The first line may use `$root` as the module name
|
||||
// to specify a "repository root". That is used to anchor any
|
||||
// relative paths present in the file (CMake should never
|
||||
// generate any).
|
||||
|
||||
// Write the root directory to use for module paths.
|
||||
mm << "$root " << loc.RootDirectory << "\n";
|
||||
|
||||
for (auto const& p : obj.Provides) {
|
||||
if (auto bmi_loc = loc.BmiGeneratorPathForModule(p.LogicalName)) {
|
||||
mm << p.LogicalName << ' ' << *bmi_loc << '\n';
|
||||
}
|
||||
}
|
||||
for (auto const& r : obj.Requires) {
|
||||
if (auto bmi_loc = loc.BmiGeneratorPathForModule(r.LogicalName)) {
|
||||
mm << r.LogicalName << ' ' << *bmi_loc << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
return mm.str();
|
||||
}
|
||||
}
|
||||
|
||||
cm::static_string_view CxxModuleMapExtension(
|
||||
cm::optional<CxxModuleMapFormat> format)
|
||||
{
|
||||
if (format) {
|
||||
switch (*format) {
|
||||
case CxxModuleMapFormat::Gcc:
|
||||
return ".gcm"_s;
|
||||
}
|
||||
}
|
||||
|
||||
return ".bmi"_s;
|
||||
}
|
||||
|
||||
std::string CxxModuleMapContent(CxxModuleMapFormat format,
|
||||
CxxModuleLocations const& loc,
|
||||
cmScanDepInfo const& obj)
|
||||
{
|
||||
switch (format) {
|
||||
case CxxModuleMapFormat::Gcc:
|
||||
return CxxModuleMapContentGcc(loc, obj);
|
||||
}
|
||||
|
||||
assert(false);
|
||||
return {};
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||
#pragma once
|
||||
|
||||
#include "cmConfigure.h" // IWYU pragma: keep
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
|
||||
#include <cm/optional>
|
||||
#include <cmext/string_view>
|
||||
|
||||
struct cmScanDepInfo;
|
||||
|
||||
enum class CxxModuleMapFormat
|
||||
{
|
||||
Gcc,
|
||||
};
|
||||
|
||||
struct CxxModuleLocations
|
||||
{
|
||||
// The path from which all relative paths should be computed. If
|
||||
// this is relative, it is relative to the compiler's working
|
||||
// directory.
|
||||
std::string RootDirectory;
|
||||
|
||||
// A function to convert a full path to a path for the generator.
|
||||
std::function<std::string(std::string const&)> PathForGenerator;
|
||||
|
||||
// Lookup the BMI location of a logical module name.
|
||||
std::function<cm::optional<std::string>(std::string const&)>
|
||||
BmiLocationForModule;
|
||||
|
||||
// Returns the generator path (if known) for the BMI given a
|
||||
// logical module name.
|
||||
cm::optional<std::string> BmiGeneratorPathForModule(
|
||||
std::string const& logical_name) const;
|
||||
};
|
||||
|
||||
// Return the extension to use for a given modulemap format.
|
||||
cm::static_string_view CxxModuleMapExtension(
|
||||
cm::optional<CxxModuleMapFormat> format);
|
||||
|
||||
// Return the contents of the module map in the given format for the
|
||||
// object file.
|
||||
std::string CxxModuleMapContent(CxxModuleMapFormat format,
|
||||
CxxModuleLocations const& loc,
|
||||
cmScanDepInfo const& obj);
|
||||
@@ -0,0 +1,63 @@
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||
|
||||
#include "cmExperimental.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
|
||||
#include "cmMakefile.h"
|
||||
#include "cmMessageType.h"
|
||||
#include "cmValue.h"
|
||||
|
||||
namespace {
|
||||
|
||||
/*
|
||||
* The `Uuid` fields of these objects should change periodically.
|
||||
* Search for other instances to keep the documentation and test suite
|
||||
* up-to-date.
|
||||
*/
|
||||
|
||||
struct FeatureData
|
||||
{
|
||||
std::string const Uuid;
|
||||
std::string const Variable;
|
||||
std::string const Description;
|
||||
bool Warned;
|
||||
} LookupTable[] = {
|
||||
// CxxModuleCMakeApi
|
||||
{ "17be90bd-a850-44e0-be50-448de847d652",
|
||||
"CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API",
|
||||
"CMake's C++ module support is experimental. It is meant only for "
|
||||
"experimentation and feedback to CMake developers.",
|
||||
false },
|
||||
};
|
||||
static_assert(sizeof(LookupTable) / sizeof(LookupTable[0]) ==
|
||||
static_cast<size_t>(cmExperimental::Feature::Sentinel),
|
||||
"Experimental feature lookup table mismatch");
|
||||
|
||||
FeatureData& DataForFeature(cmExperimental::Feature f)
|
||||
{
|
||||
assert(f != cmExperimental::Feature::Sentinel);
|
||||
return LookupTable[static_cast<size_t>(f)];
|
||||
}
|
||||
}
|
||||
|
||||
bool cmExperimental::HasSupportEnabled(cmMakefile const& mf, Feature f)
|
||||
{
|
||||
bool enabled = false;
|
||||
auto& data = DataForFeature(f);
|
||||
|
||||
auto value = mf.GetDefinition(data.Variable);
|
||||
if (value == data.Uuid) {
|
||||
enabled = true;
|
||||
}
|
||||
|
||||
if (enabled && !data.Warned) {
|
||||
mf.IssueMessage(MessageType::AUTHOR_WARNING, data.Description);
|
||||
data.Warned = true;
|
||||
}
|
||||
|
||||
return enabled;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cmConfigure.h" // IWYU pragma: keep
|
||||
|
||||
class cmMakefile;
|
||||
|
||||
class cmExperimental
|
||||
{
|
||||
public:
|
||||
enum class Feature
|
||||
{
|
||||
CxxModuleCMakeApi,
|
||||
|
||||
Sentinel,
|
||||
};
|
||||
|
||||
static bool HasSupportEnabled(cmMakefile const& mf, Feature f);
|
||||
};
|
||||
@@ -9,7 +9,9 @@
|
||||
#include <sstream>
|
||||
#include <utility>
|
||||
|
||||
#include <cm/string_view>
|
||||
#include <cmext/algorithm>
|
||||
#include <cmext/string_view>
|
||||
|
||||
#include "cmExportSet.h"
|
||||
#include "cmFileSet.h"
|
||||
@@ -382,6 +384,21 @@ std::string cmExportBuildFileGenerator::GetFileSetDirectories(
|
||||
std::any_of(directoryEntries.begin(), directoryEntries.end(),
|
||||
EntryIsContextSensitive);
|
||||
|
||||
auto const& type = fileSet->GetType();
|
||||
// C++ modules do not support interface file sets which are dependent upon
|
||||
// the configuration.
|
||||
if (contextSensitive &&
|
||||
(type == "CXX_MODULES"_s || type == "CXX_MODULE_HEADER_UNITS"_s)) {
|
||||
auto* mf = this->LG->GetMakefile();
|
||||
std::ostringstream e;
|
||||
e << "The \"" << gte->GetName() << "\" target's interface file set \""
|
||||
<< fileSet->GetName() << "\" of type \"" << type
|
||||
<< "\" contains context-sensitive base directory entries which is not "
|
||||
"supported.";
|
||||
mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
|
||||
return std::string{};
|
||||
}
|
||||
|
||||
for (auto const& directory : directories) {
|
||||
auto dest = cmOutputConverter::EscapeForCMake(
|
||||
directory, cmOutputConverter::WrapQuotes::NoWrap);
|
||||
@@ -427,6 +444,21 @@ std::string cmExportBuildFileGenerator::GetFileSetFiles(cmGeneratorTarget* gte,
|
||||
std::any_of(fileEntries.begin(), fileEntries.end(),
|
||||
EntryIsContextSensitive);
|
||||
|
||||
auto const& type = fileSet->GetType();
|
||||
// C++ modules do not support interface file sets which are dependent upon
|
||||
// the configuration.
|
||||
if (contextSensitive &&
|
||||
(type == "CXX_MODULES"_s || type == "CXX_MODULE_HEADER_UNITS"_s)) {
|
||||
auto* mf = this->LG->GetMakefile();
|
||||
std::ostringstream e;
|
||||
e << "The \"" << gte->GetName() << "\" target's interface file set \""
|
||||
<< fileSet->GetName() << "\" of type \"" << type
|
||||
<< "\" contains context-sensitive file entries which is not "
|
||||
"supported.";
|
||||
mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
|
||||
return std::string{};
|
||||
}
|
||||
|
||||
for (auto const& it : files) {
|
||||
for (auto const& filename : it.second) {
|
||||
auto escapedFile = cmOutputConverter::EscapeForCMake(
|
||||
|
||||
@@ -7,6 +7,9 @@
|
||||
#include <sstream>
|
||||
#include <utility>
|
||||
|
||||
#include <cm/string_view>
|
||||
#include <cmext/string_view>
|
||||
|
||||
#include "cmExportSet.h"
|
||||
#include "cmFileSet.h"
|
||||
#include "cmGeneratedFileStream.h"
|
||||
@@ -18,6 +21,7 @@
|
||||
#include "cmInstallTargetGenerator.h"
|
||||
#include "cmLocalGenerator.h"
|
||||
#include "cmMakefile.h"
|
||||
#include "cmMessageType.h"
|
||||
#include "cmOutputConverter.h"
|
||||
#include "cmPolicies.h"
|
||||
#include "cmStateTypes.h"
|
||||
@@ -562,6 +566,21 @@ std::string cmExportInstallFileGenerator::GetFileSetDirectories(
|
||||
cge->Evaluate(gte->LocalGenerator, config, gte),
|
||||
cmOutputConverter::WrapQuotes::NoWrap));
|
||||
|
||||
auto const& type = fileSet->GetType();
|
||||
// C++ modules do not support interface file sets which are dependent upon
|
||||
// the configuration.
|
||||
if (cge->GetHadContextSensitiveCondition() &&
|
||||
(type == "CXX_MODULES"_s || type == "CXX_MODULE_HEADER_UNITS"_s)) {
|
||||
auto* mf = this->IEGen->GetLocalGenerator()->GetMakefile();
|
||||
std::ostringstream e;
|
||||
e << "The \"" << gte->GetName() << "\" target's interface file set \""
|
||||
<< fileSet->GetName() << "\" of type \"" << type
|
||||
<< "\" contains context-sensitive base file entries which is not "
|
||||
"supported.";
|
||||
mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
|
||||
return std::string{};
|
||||
}
|
||||
|
||||
if (cge->GetHadContextSensitiveCondition() && configs.size() != 1) {
|
||||
resultVector.push_back(
|
||||
cmStrCat("\"$<$<CONFIG:", config, ">:", dest, ">\""));
|
||||
@@ -610,6 +629,21 @@ std::string cmExportInstallFileGenerator::GetFileSetFiles(
|
||||
std::any_of(fileEntries.begin(), fileEntries.end(),
|
||||
EntryIsContextSensitive);
|
||||
|
||||
auto const& type = fileSet->GetType();
|
||||
// C++ modules do not support interface file sets which are dependent upon
|
||||
// the configuration.
|
||||
if (contextSensitive &&
|
||||
(type == "CXX_MODULES"_s || type == "CXX_MODULE_HEADER_UNITS"_s)) {
|
||||
auto* mf = this->IEGen->GetLocalGenerator()->GetMakefile();
|
||||
std::ostringstream e;
|
||||
e << "The \"" << gte->GetName() << "\" target's interface file set \""
|
||||
<< fileSet->GetName() << "\" of type \"" << type
|
||||
<< "\" contains context-sensitive base file entries which is not "
|
||||
"supported.";
|
||||
mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
|
||||
return std::string{};
|
||||
}
|
||||
|
||||
for (auto const& it : files) {
|
||||
auto prefix = it.first.empty() ? "" : cmStrCat(it.first, '/');
|
||||
for (auto const& filename : it.second) {
|
||||
|
||||
@@ -1712,7 +1712,8 @@ void addFileSetEntry(cmGeneratorTarget const* headTarget,
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
if (fileSet->GetType() == "HEADERS"_s) {
|
||||
if (fileSet->GetType() == "HEADERS"_s ||
|
||||
fileSet->GetType() == "CXX_MODULE_HEADER_UNITS"_s) {
|
||||
headTarget->Makefile->GetOrCreateSourceGroup("Header Files")
|
||||
->AddGroupFile(path);
|
||||
}
|
||||
@@ -1733,6 +1734,20 @@ void AddFileSetEntries(cmGeneratorTarget const* headTarget,
|
||||
addFileSetEntry(headTarget, config, dagChecker, headerSet, entries);
|
||||
}
|
||||
}
|
||||
for (auto const& entry : headTarget->Target->GetCxxModuleSetsEntries()) {
|
||||
for (auto const& name : cmExpandedList(entry.Value)) {
|
||||
auto const* cxxModuleSet = headTarget->Target->GetFileSet(name);
|
||||
addFileSetEntry(headTarget, config, dagChecker, cxxModuleSet, entries);
|
||||
}
|
||||
}
|
||||
for (auto const& entry :
|
||||
headTarget->Target->GetCxxModuleHeaderSetsEntries()) {
|
||||
for (auto const& name : cmExpandedList(entry.Value)) {
|
||||
auto const* cxxModuleHeaderSet = headTarget->Target->GetFileSet(name);
|
||||
addFileSetEntry(headTarget, config, dagChecker, cxxModuleHeaderSet,
|
||||
entries);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool processSources(cmGeneratorTarget const* tgt,
|
||||
@@ -8705,3 +8720,76 @@ std::string cmGeneratorTarget::GenerateHeaderSetVerificationFile(
|
||||
|
||||
return filename;
|
||||
}
|
||||
|
||||
bool cmGeneratorTarget::HaveCxx20ModuleSources() const
|
||||
{
|
||||
auto const& fs_names = this->Target->GetAllFileSetNames();
|
||||
return std::any_of(fs_names.begin(), fs_names.end(),
|
||||
[this](std::string const& name) -> bool {
|
||||
auto const* file_set = this->Target->GetFileSet(name);
|
||||
if (!file_set) {
|
||||
this->Makefile->IssueMessage(
|
||||
MessageType::INTERNAL_ERROR,
|
||||
cmStrCat("Target \"", this->Target->GetName(),
|
||||
"\" is tracked to have file set \"", name,
|
||||
"\", but it was not found."));
|
||||
return false;
|
||||
}
|
||||
|
||||
auto const& fs_type = file_set->GetType();
|
||||
return fs_type == "CXX_MODULES"_s ||
|
||||
fs_type == "CXX_MODULE_HEADER_UNITS"_s;
|
||||
});
|
||||
}
|
||||
|
||||
cmGeneratorTarget::Cxx20SupportLevel cmGeneratorTarget::HaveCxxModuleSupport(
|
||||
std::string const& config) const
|
||||
{
|
||||
auto const* state = this->Makefile->GetState();
|
||||
if (!state->GetLanguageEnabled("CXX")) {
|
||||
return Cxx20SupportLevel::MissingCxx;
|
||||
}
|
||||
cmStandardLevelResolver standardResolver(this->Makefile);
|
||||
if (!standardResolver.HaveStandardAvailable(this, "CXX", config,
|
||||
"cxx_std_20")) {
|
||||
return Cxx20SupportLevel::NoCxx20;
|
||||
}
|
||||
if (!this->Makefile->IsOn("CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP")) {
|
||||
return Cxx20SupportLevel::MissingExperimentalFlag;
|
||||
}
|
||||
return Cxx20SupportLevel::Supported;
|
||||
}
|
||||
|
||||
void cmGeneratorTarget::CheckCxxModuleStatus(std::string const& config) const
|
||||
{
|
||||
// Check for `CXX_MODULE*` file sets and a lack of support.
|
||||
if (this->HaveCxx20ModuleSources()) {
|
||||
switch (this->HaveCxxModuleSupport(config)) {
|
||||
case cmGeneratorTarget::Cxx20SupportLevel::MissingCxx:
|
||||
this->Makefile->IssueMessage(
|
||||
MessageType::FATAL_ERROR,
|
||||
cmStrCat("The \"", this->GetName(),
|
||||
"\" target has C++ module sources but the \"CXX\" language "
|
||||
"has not been enabled"));
|
||||
break;
|
||||
case cmGeneratorTarget::Cxx20SupportLevel::MissingExperimentalFlag:
|
||||
this->Makefile->IssueMessage(
|
||||
MessageType::FATAL_ERROR,
|
||||
cmStrCat("The \"", this->GetName(),
|
||||
"\" target has C++ module sources but its experimental "
|
||||
"support has not been requested"));
|
||||
break;
|
||||
case cmGeneratorTarget::Cxx20SupportLevel::NoCxx20:
|
||||
this->Makefile->IssueMessage(
|
||||
MessageType::FATAL_ERROR,
|
||||
cmStrCat(
|
||||
"The \"", this->GetName(),
|
||||
"\" target has C++ module sources but is not using at least "
|
||||
"\"cxx_std_20\""));
|
||||
break;
|
||||
case cmGeneratorTarget::Cxx20SupportLevel::Supported:
|
||||
// All is well.
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1196,4 +1196,34 @@ public:
|
||||
bool operator()(cmGeneratorTarget const* t1,
|
||||
cmGeneratorTarget const* t2) const;
|
||||
};
|
||||
|
||||
// C++20 module support queries.
|
||||
|
||||
/**
|
||||
* Query whether the target expects C++20 module support.
|
||||
*
|
||||
* This will inspect the target itself to see if C++20 module
|
||||
* support is expected to work based on its sources.
|
||||
*/
|
||||
bool HaveCxx20ModuleSources() const;
|
||||
|
||||
enum class Cxx20SupportLevel
|
||||
{
|
||||
// C++ is not available.
|
||||
MissingCxx,
|
||||
// The experimental feature is not available.
|
||||
MissingExperimentalFlag,
|
||||
// The target does not require at least C++20.
|
||||
NoCxx20,
|
||||
// C++20 modules are available and working.
|
||||
Supported,
|
||||
};
|
||||
/**
|
||||
* Query whether the target has C++20 module support available (regardless of
|
||||
* whether it is required or not).
|
||||
*/
|
||||
Cxx20SupportLevel HaveCxxModuleSupport(std::string const& config) const;
|
||||
|
||||
// Check C++ module status for the target.
|
||||
void CheckCxxModuleStatus(std::string const& config) const;
|
||||
};
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
#include <cstdio>
|
||||
#include <functional>
|
||||
#include <sstream>
|
||||
#include <utility>
|
||||
|
||||
@@ -21,6 +22,7 @@
|
||||
|
||||
#include "cmsys/FStream.hxx"
|
||||
|
||||
#include "cmCxxModuleMapper.h"
|
||||
#include "cmDocumentationEntry.h"
|
||||
#include "cmFortranParser.h"
|
||||
#include "cmGeneratedFileStream.h"
|
||||
@@ -2517,7 +2519,7 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile(
|
||||
// Populate the module map with those provided by linked targets first.
|
||||
for (std::string const& linked_target_dir : linked_target_dirs) {
|
||||
std::string const ltmn =
|
||||
cmStrCat(linked_target_dir, "/", arg_lang, "Modules.json");
|
||||
cmStrCat(linked_target_dir, '/', arg_lang, "Modules.json");
|
||||
Json::Value ltm;
|
||||
cmsys::ifstream ltmf(ltmn.c_str(), std::ios::in | std::ios::binary);
|
||||
Json::Reader reader;
|
||||
@@ -2534,11 +2536,20 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile(
|
||||
}
|
||||
}
|
||||
|
||||
const char* module_ext = "";
|
||||
if (arg_modmapfmt == "gcc") {
|
||||
module_ext = ".gcm";
|
||||
cm::optional<CxxModuleMapFormat> modmap_fmt;
|
||||
if (arg_modmapfmt.empty()) {
|
||||
// nothing to do.
|
||||
} else if (arg_modmapfmt == "gcc") {
|
||||
modmap_fmt = CxxModuleMapFormat::Gcc;
|
||||
} else {
|
||||
cmSystemTools::Error(
|
||||
cmStrCat("-E cmake_ninja_dyndep does not understand the ", arg_modmapfmt,
|
||||
" module map format"));
|
||||
return false;
|
||||
}
|
||||
|
||||
auto module_ext = CxxModuleMapExtension(modmap_fmt);
|
||||
|
||||
// Extend the module map with those provided by this target.
|
||||
// We do this after loading the modules provided by linked targets
|
||||
// in case we have one of the same name that must be preferred.
|
||||
@@ -2555,7 +2566,8 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile(
|
||||
}
|
||||
} else {
|
||||
// Assume the module file path matches the logical module name.
|
||||
std::string safe_logical_name = p.LogicalName;
|
||||
std::string safe_logical_name =
|
||||
p.LogicalName; // TODO: needs fixing for header units
|
||||
cmSystemTools::ReplaceString(safe_logical_name, ":", "-");
|
||||
mod = cmStrCat(module_dir, safe_logical_name, module_ext);
|
||||
}
|
||||
@@ -2568,6 +2580,20 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile(
|
||||
ddf << "ninja_dyndep_version = 1.0\n";
|
||||
|
||||
{
|
||||
CxxModuleLocations locs;
|
||||
locs.RootDirectory = ".";
|
||||
locs.PathForGenerator = [this](std::string const& path) -> std::string {
|
||||
return this->ConvertToNinjaPath(path);
|
||||
};
|
||||
locs.BmiLocationForModule =
|
||||
[&mod_files](std::string const& logical) -> cm::optional<std::string> {
|
||||
auto m = mod_files.find(logical);
|
||||
if (m != mod_files.end()) {
|
||||
return m->second;
|
||||
}
|
||||
return {};
|
||||
};
|
||||
|
||||
cmNinjaBuild build("dyndep");
|
||||
build.Outputs.emplace_back("");
|
||||
for (cmScanDepInfo const& object : objects) {
|
||||
@@ -2589,46 +2615,14 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile(
|
||||
build.Variables.emplace("restat", "1");
|
||||
}
|
||||
|
||||
if (arg_modmapfmt.empty()) {
|
||||
// nothing to do.
|
||||
} else {
|
||||
std::stringstream mm;
|
||||
if (arg_modmapfmt == "gcc") {
|
||||
// Documented in GCC's documentation. The format is a series of lines
|
||||
// with a module name and the associated filename separated by
|
||||
// spaces. The first line may use `$root` as the module name to
|
||||
// specify a "repository root". That is used to anchor any relative
|
||||
// paths present in the file (CMake should never generate any).
|
||||
|
||||
// Write the root directory to use for module paths.
|
||||
mm << "$root .\n";
|
||||
|
||||
for (auto const& l : object.Provides) {
|
||||
auto m = mod_files.find(l.LogicalName);
|
||||
if (m != mod_files.end()) {
|
||||
mm << l.LogicalName << " " << this->ConvertToNinjaPath(m->second)
|
||||
<< "\n";
|
||||
}
|
||||
}
|
||||
for (auto const& r : object.Requires) {
|
||||
auto m = mod_files.find(r.LogicalName);
|
||||
if (m != mod_files.end()) {
|
||||
mm << r.LogicalName << " " << this->ConvertToNinjaPath(m->second)
|
||||
<< "\n";
|
||||
}
|
||||
}
|
||||
} else {
|
||||
cmSystemTools::Error(
|
||||
cmStrCat("-E cmake_ninja_dyndep does not understand the ",
|
||||
arg_modmapfmt, " module map format"));
|
||||
return false;
|
||||
}
|
||||
if (modmap_fmt) {
|
||||
auto mm = CxxModuleMapContent(*modmap_fmt, locs, object);
|
||||
|
||||
// XXX(modmap): If changing this path construction, change
|
||||
// `cmNinjaTargetGenerator::WriteObjectBuildStatements` to generate the
|
||||
// corresponding file path.
|
||||
cmGeneratedFileStream mmf(cmStrCat(object.PrimaryOutput, ".modmap"));
|
||||
mmf << mm.str();
|
||||
mmf << mm;
|
||||
}
|
||||
|
||||
this->WriteBuild(ddf, build);
|
||||
|
||||
@@ -395,12 +395,27 @@ void cmGlobalVisualStudio7Generator::WriteTargetsToSolution(
|
||||
{
|
||||
VisualStudioFolders.clear();
|
||||
|
||||
std::vector<std::string> configs =
|
||||
root->GetMakefile()->GetGeneratorConfigs(cmMakefile::ExcludeEmptyConfig);
|
||||
|
||||
for (cmGeneratorTarget const* target : projectTargets) {
|
||||
if (!this->IsInSolution(target)) {
|
||||
continue;
|
||||
}
|
||||
bool written = false;
|
||||
|
||||
for (auto const& c : configs) {
|
||||
target->CheckCxxModuleStatus(c);
|
||||
}
|
||||
|
||||
if (target->HaveCxx20ModuleSources() && !this->SupportsCxxModuleDyndep()) {
|
||||
root->GetMakefile()->IssueMessage(
|
||||
MessageType::FATAL_ERROR,
|
||||
cmStrCat("The \"", target->GetName(),
|
||||
"\" target contains C++ module sources which are not "
|
||||
"supported by the generator"));
|
||||
}
|
||||
|
||||
// handle external vc project files
|
||||
cmValue expath = target->GetProperty("EXTERNAL_MSPROJECT");
|
||||
if (expath) {
|
||||
|
||||
@@ -157,6 +157,8 @@ protected:
|
||||
cmValue typeGuid,
|
||||
const std::set<BT<std::pair<std::string, bool>>>& dependencies) = 0;
|
||||
|
||||
virtual bool SupportsCxxModuleDyndep() const { return false; }
|
||||
|
||||
std::string ConvertToSolutionPath(const std::string& path);
|
||||
|
||||
std::set<std::string> IsPartOfDefaultBuild(
|
||||
|
||||
@@ -468,6 +468,10 @@ bool cmGlobalXCodeGenerator::Open(const std::string& bindir,
|
||||
}
|
||||
CFRelease(cfStr);
|
||||
}
|
||||
#else
|
||||
(void)bindir;
|
||||
(void)projectName;
|
||||
(void)dryRun;
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
@@ -1372,6 +1376,18 @@ bool cmGlobalXCodeGenerator::CreateXCodeTarget(
|
||||
return true;
|
||||
}
|
||||
|
||||
for (std::string const& configName : this->CurrentConfigurationTypes) {
|
||||
gtgt->CheckCxxModuleStatus(configName);
|
||||
}
|
||||
|
||||
if (gtgt->HaveCxx20ModuleSources()) {
|
||||
gtgt->Makefile->IssueMessage(
|
||||
MessageType::FATAL_ERROR,
|
||||
cmStrCat("The \"", gtgt->GetName(),
|
||||
"\" target contains C++ module sources which are not "
|
||||
"supported by the generator"));
|
||||
}
|
||||
|
||||
auto& gtgt_visited = this->CommandsVisited[gtgt];
|
||||
auto& deps = this->GetTargetDirectDepends(gtgt);
|
||||
for (auto& d : deps) {
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "cmComputeLinkInformation.h"
|
||||
#include "cmCustomCommand.h"
|
||||
#include "cmCustomCommandGenerator.h"
|
||||
#include "cmFileSet.h"
|
||||
#include "cmGeneratedFileStream.h"
|
||||
#include "cmGeneratorExpression.h"
|
||||
#include "cmGeneratorTarget.h"
|
||||
@@ -46,6 +47,7 @@
|
||||
#include "cmStateTypes.h"
|
||||
#include "cmStringAlgorithms.h"
|
||||
#include "cmSystemTools.h"
|
||||
#include "cmTarget.h"
|
||||
#include "cmValue.h"
|
||||
#include "cmake.h"
|
||||
|
||||
@@ -190,6 +192,16 @@ void cmMakefileTargetGenerator::CreateRuleFile()
|
||||
|
||||
void cmMakefileTargetGenerator::WriteTargetBuildRules()
|
||||
{
|
||||
this->GeneratorTarget->CheckCxxModuleStatus(this->GetConfigName());
|
||||
|
||||
if (this->GeneratorTarget->HaveCxx20ModuleSources()) {
|
||||
this->Makefile->IssueMessage(
|
||||
MessageType::FATAL_ERROR,
|
||||
cmStrCat("The \"", this->GeneratorTarget->GetName(),
|
||||
"\" target contains C++ module sources which are not supported "
|
||||
"by the generator"));
|
||||
}
|
||||
|
||||
// -- Write the custom commands for this target
|
||||
|
||||
// Evaluates generator expressions and expands prop_value
|
||||
@@ -302,6 +314,40 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules()
|
||||
}
|
||||
}
|
||||
|
||||
std::map<std::string, std::string> file_set_map;
|
||||
|
||||
auto const* tgt = this->GeneratorTarget->Target;
|
||||
for (auto const& name : tgt->GetAllFileSetNames()) {
|
||||
auto const* file_set = tgt->GetFileSet(name);
|
||||
if (!file_set) {
|
||||
this->Makefile->IssueMessage(
|
||||
MessageType::INTERNAL_ERROR,
|
||||
cmStrCat("Target \"", tgt->GetName(),
|
||||
"\" is tracked to have file set \"", name,
|
||||
"\", but it was not found."));
|
||||
continue;
|
||||
}
|
||||
|
||||
auto fileEntries = file_set->CompileFileEntries();
|
||||
auto directoryEntries = file_set->CompileDirectoryEntries();
|
||||
auto directories = file_set->EvaluateDirectoryEntries(
|
||||
directoryEntries, this->LocalGenerator, this->GetConfigName(),
|
||||
this->GeneratorTarget);
|
||||
|
||||
std::map<std::string, std::vector<std::string>> files;
|
||||
for (auto const& entry : fileEntries) {
|
||||
file_set->EvaluateFileEntry(directories, files, entry,
|
||||
this->LocalGenerator, this->GetConfigName(),
|
||||
this->GeneratorTarget);
|
||||
}
|
||||
|
||||
for (auto const& it : files) {
|
||||
for (auto const& filename : it.second) {
|
||||
file_set_map[filename] = file_set->GetType();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<cmSourceFile const*> objectSources;
|
||||
this->GeneratorTarget->GetObjectSources(objectSources,
|
||||
this->GetConfigName());
|
||||
@@ -314,6 +360,25 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules()
|
||||
this->WriteObjectRuleFiles(*sf);
|
||||
}
|
||||
}
|
||||
|
||||
for (cmSourceFile const* sf : objectSources) {
|
||||
auto const& path = sf->GetFullPath();
|
||||
auto const it = file_set_map.find(path);
|
||||
if (it != file_set_map.end()) {
|
||||
auto const& file_set_type = it->second;
|
||||
if (file_set_type == "CXX_MODULES"_s ||
|
||||
file_set_type == "CXX_MODULE_HEADER_UNITS"_s) {
|
||||
if (sf->GetLanguage() != "CXX"_s) {
|
||||
this->Makefile->IssueMessage(
|
||||
MessageType::FATAL_ERROR,
|
||||
cmStrCat(
|
||||
"Target \"", tgt->GetName(), "\" contains the source\n ", path,
|
||||
"\nin a file set of type \"", file_set_type,
|
||||
R"(" but the source is not classified as a "CXX" source.)"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void cmMakefileTargetGenerator::WriteCommonCodeRules()
|
||||
|
||||
@@ -36,7 +36,6 @@
|
||||
#include "cmRange.h"
|
||||
#include "cmRulePlaceholderExpander.h"
|
||||
#include "cmSourceFile.h"
|
||||
#include "cmStandardLevelResolver.h"
|
||||
#include "cmState.h"
|
||||
#include "cmStateTypes.h"
|
||||
#include "cmStringAlgorithms.h"
|
||||
@@ -153,17 +152,12 @@ std::string cmNinjaTargetGenerator::LanguageDyndepRule(
|
||||
bool cmNinjaTargetGenerator::NeedCxxModuleSupport(
|
||||
std::string const& lang, std::string const& config) const
|
||||
{
|
||||
if (lang != "CXX") {
|
||||
if (lang != "CXX"_s) {
|
||||
return false;
|
||||
}
|
||||
if (!this->Makefile->IsOn("CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP")) {
|
||||
return false;
|
||||
}
|
||||
cmGeneratorTarget const* tgt = this->GetGeneratorTarget();
|
||||
cmStandardLevelResolver standardResolver(this->Makefile);
|
||||
bool const uses_cxx20 =
|
||||
standardResolver.HaveStandardAvailable(tgt, "CXX", config, "cxx_std_20");
|
||||
return uses_cxx20 && this->GetGlobalGenerator()->CheckCxxModuleSupport();
|
||||
return this->GetGeneratorTarget()->HaveCxxModuleSupport(config) ==
|
||||
cmGeneratorTarget::Cxx20SupportLevel::Supported &&
|
||||
this->GetGlobalGenerator()->CheckCxxModuleSupport();
|
||||
}
|
||||
|
||||
bool cmNinjaTargetGenerator::NeedDyndep(std::string const& lang,
|
||||
@@ -255,52 +249,54 @@ std::string cmNinjaTargetGenerator::ComputeFlagsForObject(
|
||||
flags, genexInterpreter.Evaluate(pchOptions, COMPILE_OPTIONS));
|
||||
}
|
||||
|
||||
if (this->NeedCxxModuleSupport(language, config)) {
|
||||
auto const& path = source->GetFullPath();
|
||||
auto const* tgt = this->GeneratorTarget->Target;
|
||||
auto const& path = source->GetFullPath();
|
||||
auto const* tgt = this->GeneratorTarget->Target;
|
||||
|
||||
std::string file_set_type;
|
||||
std::string file_set_type;
|
||||
|
||||
for (auto const& name : tgt->GetAllFileSetNames()) {
|
||||
auto const* file_set = tgt->GetFileSet(name);
|
||||
if (!file_set) {
|
||||
for (auto const& name : tgt->GetAllFileSetNames()) {
|
||||
auto const* file_set = tgt->GetFileSet(name);
|
||||
if (!file_set) {
|
||||
this->GetMakefile()->IssueMessage(
|
||||
MessageType::INTERNAL_ERROR,
|
||||
cmStrCat("Target \"", tgt->GetName(),
|
||||
"\" is tracked to have file set \"", name,
|
||||
"\", but it was not found."));
|
||||
continue;
|
||||
}
|
||||
|
||||
auto fileEntries = file_set->CompileFileEntries();
|
||||
auto directoryEntries = file_set->CompileDirectoryEntries();
|
||||
auto directories = file_set->EvaluateDirectoryEntries(
|
||||
directoryEntries, this->LocalGenerator, config, this->GeneratorTarget);
|
||||
|
||||
std::map<std::string, std::vector<std::string>> files;
|
||||
for (auto const& entry : fileEntries) {
|
||||
file_set->EvaluateFileEntry(directories, files, entry,
|
||||
this->LocalGenerator, config,
|
||||
this->GeneratorTarget);
|
||||
}
|
||||
|
||||
for (auto const& it : files) {
|
||||
for (auto const& filename : it.second) {
|
||||
if (filename == path) {
|
||||
file_set_type = file_set->GetType();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (file_set_type == "CXX_MODULES"_s ||
|
||||
file_set_type == "CXX_MODULE_HEADER_UNITS"_s) {
|
||||
if (source->GetLanguage() != "CXX"_s) {
|
||||
this->GetMakefile()->IssueMessage(
|
||||
MessageType::INTERNAL_ERROR,
|
||||
cmStrCat("Target `", tgt->GetName(),
|
||||
"` is tracked to have file set `", name,
|
||||
"`, but it was not found."));
|
||||
MessageType::FATAL_ERROR,
|
||||
cmStrCat(
|
||||
"Target \"", tgt->GetName(), "\" contains the source\n ", path,
|
||||
"\nin a file set of type \"", file_set_type,
|
||||
R"(" but the source is not classified as a "CXX" source.)"));
|
||||
continue;
|
||||
}
|
||||
|
||||
auto fileEntries = file_set->CompileFileEntries();
|
||||
auto directoryEntries = file_set->CompileDirectoryEntries();
|
||||
auto directories = file_set->EvaluateDirectoryEntries(
|
||||
directoryEntries, this->LocalGenerator, config, this->GeneratorTarget);
|
||||
|
||||
std::map<std::string, std::vector<std::string>> files;
|
||||
for (auto const& entry : fileEntries) {
|
||||
file_set->EvaluateFileEntry(directories, files, entry,
|
||||
this->LocalGenerator, config,
|
||||
this->GeneratorTarget);
|
||||
}
|
||||
|
||||
for (auto const& it : files) {
|
||||
for (auto const& filename : it.second) {
|
||||
if (filename == path) {
|
||||
file_set_type = file_set->GetType();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!file_set_type.empty()) {
|
||||
std::string source_type_var = cmStrCat(
|
||||
"CMAKE_EXPERIMENTAL_CXX_MODULE_SOURCE_TYPE_FLAG_", file_set_type);
|
||||
cmMakefile* mf = this->GetMakefile();
|
||||
if (cmValue source_type_flag = mf->GetDefinition(source_type_var)) {
|
||||
this->LocalGenerator->AppendFlags(flags, *source_type_flag);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1038,6 +1034,8 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements(
|
||||
const std::string& config, const std::string& fileConfig,
|
||||
bool firstForConfig)
|
||||
{
|
||||
this->GeneratorTarget->CheckCxxModuleStatus(config);
|
||||
|
||||
// Write comments.
|
||||
cmGlobalNinjaGenerator::WriteDivider(this->GetImplFileStream(fileConfig));
|
||||
this->GetImplFileStream(fileConfig)
|
||||
@@ -1616,8 +1614,9 @@ void cmNinjaTargetGenerator::WriteTargetDependInfo(std::string const& lang,
|
||||
mod_dir = this->GeneratorTarget->GetFortranModuleDirectory(
|
||||
this->Makefile->GetHomeOutputDirectory());
|
||||
} else if (lang == "CXX") {
|
||||
mod_dir =
|
||||
cmSystemTools::CollapseFullPath(this->GeneratorTarget->ObjectDirectory);
|
||||
mod_dir = this->GetGlobalGenerator()->ExpandCFGIntDir(
|
||||
cmSystemTools::CollapseFullPath(this->GeneratorTarget->ObjectDirectory),
|
||||
config);
|
||||
}
|
||||
if (mod_dir.empty()) {
|
||||
mod_dir = this->Makefile->GetCurrentBinaryDirectory();
|
||||
|
||||
@@ -133,7 +133,7 @@ void cmScriptGenerator::GenerateScriptActionsOnce(std::ostream& os,
|
||||
std::string config_test = this->CreateConfigTest(this->Configurations);
|
||||
os << indent << "if(" << config_test << ")\n";
|
||||
this->GenerateScriptActions(os, indent.Next());
|
||||
os << indent << "endif(" << config_test << ")\n";
|
||||
os << indent << "endif()\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -272,6 +272,8 @@ public:
|
||||
cmListFileBacktrace Backtrace;
|
||||
|
||||
FileSetType HeadersFileSets;
|
||||
FileSetType CxxModulesFileSets;
|
||||
FileSetType CxxModuleHeadersFileSets;
|
||||
|
||||
cmTargetInternals();
|
||||
|
||||
@@ -301,6 +303,19 @@ cmTargetInternals::cmTargetInternals()
|
||||
"The default header set"_s, "Header set"_s,
|
||||
FileSetEntries("HEADER_SETS"_s),
|
||||
FileSetEntries("INTERFACE_HEADER_SETS"_s))
|
||||
, CxxModulesFileSets("CXX_MODULES"_s, "CXX_MODULE_DIRS"_s,
|
||||
"CXX_MODULE_SET"_s, "CXX_MODULE_DIRS_"_s,
|
||||
"CXX_MODULE_SET_"_s, "C++ module"_s,
|
||||
"The default C++ module set"_s, "C++ module set"_s,
|
||||
FileSetEntries("CXX_MODULE_SETS"_s),
|
||||
FileSetEntries("INTERFACE_CXX_MODULE_SETS"_s))
|
||||
, CxxModuleHeadersFileSets(
|
||||
"CXX_MODULE_HEADER_UNITS"_s, "CXX_MODULE_HEADER_UNIT_DIRS"_s,
|
||||
"CXX_MODULE_HEADER_UNIT_SET"_s, "CXX_MODULE_HEADER_UNIT_DIRS_"_s,
|
||||
"CXX_MODULE_HEADER_UNIT_SET_"_s, "C++ module header"_s,
|
||||
"The default C++ module header set"_s, "C++ module header set"_s,
|
||||
FileSetEntries("CXX_MODULE_HEADER_UNIT_SETS"_s),
|
||||
FileSetEntries("INTERFACE_CXX_MODULE_HEADER_UNIT_SETS"_s))
|
||||
{
|
||||
}
|
||||
|
||||
@@ -1371,11 +1386,32 @@ cmBTStringRange cmTarget::GetHeaderSetsEntries() const
|
||||
return cmMakeRange(this->impl->HeadersFileSets.SelfEntries.Entries);
|
||||
}
|
||||
|
||||
cmBTStringRange cmTarget::GetCxxModuleSetsEntries() const
|
||||
{
|
||||
return cmMakeRange(this->impl->CxxModulesFileSets.SelfEntries.Entries);
|
||||
}
|
||||
|
||||
cmBTStringRange cmTarget::GetCxxModuleHeaderSetsEntries() const
|
||||
{
|
||||
return cmMakeRange(this->impl->CxxModuleHeadersFileSets.SelfEntries.Entries);
|
||||
}
|
||||
|
||||
cmBTStringRange cmTarget::GetInterfaceHeaderSetsEntries() const
|
||||
{
|
||||
return cmMakeRange(this->impl->HeadersFileSets.InterfaceEntries.Entries);
|
||||
}
|
||||
|
||||
cmBTStringRange cmTarget::GetInterfaceCxxModuleSetsEntries() const
|
||||
{
|
||||
return cmMakeRange(this->impl->CxxModulesFileSets.InterfaceEntries.Entries);
|
||||
}
|
||||
|
||||
cmBTStringRange cmTarget::GetInterfaceCxxModuleHeaderSetsEntries() const
|
||||
{
|
||||
return cmMakeRange(
|
||||
this->impl->CxxModuleHeadersFileSets.InterfaceEntries.Entries);
|
||||
}
|
||||
|
||||
namespace {
|
||||
#define MAKE_PROP(PROP) const std::string prop##PROP = #PROP
|
||||
MAKE_PROP(C_STANDARD);
|
||||
@@ -1635,6 +1671,12 @@ void cmTarget::StoreProperty(const std::string& prop, ValueType value)
|
||||
} else if (this->impl->HeadersFileSets.WriteProperties(
|
||||
this, this->impl.get(), prop, value, true)) {
|
||||
/* Handled in the `if` condition. */
|
||||
} else if (this->impl->CxxModulesFileSets.WriteProperties(
|
||||
this, this->impl.get(), prop, value, true)) {
|
||||
/* Handled in the `if` condition. */
|
||||
} else if (this->impl->CxxModuleHeadersFileSets.WriteProperties(
|
||||
this, this->impl.get(), prop, value, true)) {
|
||||
/* Handled in the `if` condition. */
|
||||
} else {
|
||||
this->impl->Properties.SetProperty(prop, value);
|
||||
}
|
||||
@@ -1746,6 +1788,13 @@ void cmTarget::AppendProperty(const std::string& prop,
|
||||
this->impl->Makefile->IssueMessage(
|
||||
MessageType::FATAL_ERROR, prop + " property may not be appended.");
|
||||
} else if (this->impl->HeadersFileSets.WriteProperties(
|
||||
this, this->impl.get(), prop, value,
|
||||
false)) { // NOLINT(bugprone-branch-clone)
|
||||
/* Handled in the `if` condition. */
|
||||
} else if (this->impl->CxxModulesFileSets.WriteProperties(
|
||||
this, this->impl.get(), prop, value, false)) {
|
||||
/* Handled in the `if` condition. */
|
||||
} else if (this->impl->CxxModuleHeadersFileSets.WriteProperties(
|
||||
this, this->impl.get(), prop, value, false)) {
|
||||
/* Handled in the `if` condition. */
|
||||
} else {
|
||||
@@ -2254,6 +2303,17 @@ cmValue cmTarget::GetProperty(const std::string& prop) const
|
||||
if (headers.first) {
|
||||
return headers.second;
|
||||
}
|
||||
auto cxx_modules = this->impl->CxxModulesFileSets.ReadProperties(
|
||||
this, this->impl.get(), prop);
|
||||
if (cxx_modules.first) {
|
||||
return cxx_modules.second;
|
||||
}
|
||||
auto cxx_module_headers =
|
||||
this->impl->CxxModuleHeadersFileSets.ReadProperties(
|
||||
this, this->impl.get(), prop);
|
||||
if (cxx_module_headers.first) {
|
||||
return cxx_module_headers.second;
|
||||
}
|
||||
}
|
||||
|
||||
cmValue retVal = this->impl->Properties.GetPropertyValue(prop);
|
||||
@@ -2531,6 +2591,11 @@ std::pair<cmFileSet*, bool> cmTarget::GetOrCreateFileSet(
|
||||
auto bt = this->impl->Makefile->GetBacktrace();
|
||||
if (type == this->impl->HeadersFileSets.TypeName) {
|
||||
this->impl->HeadersFileSets.AddFileSet(name, vis, std::move(bt));
|
||||
} else if (type == this->impl->CxxModulesFileSets.TypeName) {
|
||||
this->impl->CxxModulesFileSets.AddFileSet(name, vis, std::move(bt));
|
||||
} else if (type == this->impl->CxxModuleHeadersFileSets.TypeName) {
|
||||
this->impl->CxxModuleHeadersFileSets.AddFileSet(name, vis,
|
||||
std::move(bt));
|
||||
}
|
||||
}
|
||||
return std::make_pair(&result.first->second, result.second);
|
||||
@@ -2541,6 +2606,12 @@ std::string cmTarget::GetFileSetsPropertyName(const std::string& type)
|
||||
if (type == "HEADERS") {
|
||||
return "HEADER_SETS";
|
||||
}
|
||||
if (type == "CXX_MODULES") {
|
||||
return "CXX_MODULE_SETS";
|
||||
}
|
||||
if (type == "CXX_MODULE_HEADER_UNITS") {
|
||||
return "CXX_MODULE_HEADER_UNIT_SETS";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
@@ -2549,6 +2620,12 @@ std::string cmTarget::GetInterfaceFileSetsPropertyName(const std::string& type)
|
||||
if (type == "HEADERS") {
|
||||
return "INTERFACE_HEADER_SETS";
|
||||
}
|
||||
if (type == "CXX_MODULES") {
|
||||
return "INTERFACE_CXX_MODULE_SETS";
|
||||
}
|
||||
if (type == "CXX_MODULE_HEADER_UNITS") {
|
||||
return "INTERFACE_CXX_MODULE_HEADER_UNIT_SETS";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
@@ -2576,6 +2653,8 @@ std::vector<std::string> cmTarget::GetAllInterfaceFileSets() const
|
||||
};
|
||||
|
||||
appendEntries(this->impl->HeadersFileSets.InterfaceEntries.Entries);
|
||||
appendEntries(this->impl->CxxModulesFileSets.InterfaceEntries.Entries);
|
||||
appendEntries(this->impl->CxxModuleHeadersFileSets.InterfaceEntries.Entries);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -275,8 +275,12 @@ public:
|
||||
cmBTStringRange GetLinkInterfaceDirectExcludeEntries() const;
|
||||
|
||||
cmBTStringRange GetHeaderSetsEntries() const;
|
||||
cmBTStringRange GetCxxModuleSetsEntries() const;
|
||||
cmBTStringRange GetCxxModuleHeaderSetsEntries() const;
|
||||
|
||||
cmBTStringRange GetInterfaceHeaderSetsEntries() const;
|
||||
cmBTStringRange GetInterfaceCxxModuleSetsEntries() const;
|
||||
cmBTStringRange GetInterfaceCxxModuleHeaderSetsEntries() const;
|
||||
|
||||
std::string ImportedGetFullPath(const std::string& config,
|
||||
cmStateEnums::ArtifactType artifact) const;
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <cmext/string_view>
|
||||
|
||||
#include "cmArgumentParser.h"
|
||||
#include "cmExperimental.h"
|
||||
#include "cmFileSet.h"
|
||||
#include "cmGeneratorExpression.h"
|
||||
#include "cmListFileCache.h"
|
||||
@@ -256,9 +257,30 @@ bool TargetSourcesImpl::HandleOneFileSet(
|
||||
this->SetError("Must specify a TYPE when creating file set");
|
||||
return false;
|
||||
}
|
||||
if (type != "HEADERS"_s) {
|
||||
this->SetError("File set TYPE may only be \"HEADERS\"");
|
||||
return false;
|
||||
bool const supportCxx20FileSetTypes = cmExperimental::HasSupportEnabled(
|
||||
*this->Makefile, cmExperimental::Feature::CxxModuleCMakeApi);
|
||||
|
||||
if (supportCxx20FileSetTypes) {
|
||||
if (type != "HEADERS"_s && type != "CXX_MODULES"_s &&
|
||||
type != "CXX_MODULE_HEADER_UNITS"_s) {
|
||||
this->SetError(
|
||||
R"(File set TYPE may only be "HEADERS", "CXX_MODULES", or "CXX_MODULE_HEADER_UNITS")");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cmFileSetVisibilityIsForInterface(visibility) &&
|
||||
!cmFileSetVisibilityIsForSelf(visibility)) {
|
||||
if (type == "CXX_MODULES"_s || type == "CXX_MODULE_HEADER_UNITS"_s) {
|
||||
this->SetError(
|
||||
R"(File set TYPEs "CXX_MODULES" and "CXX_MODULE_HEADER_UNITS" may not have "INTERFACE" visibility)");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (type != "HEADERS"_s) {
|
||||
this->SetError("File set TYPE may only be \"HEADERS\"");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (args.BaseDirs.empty()) {
|
||||
@@ -294,7 +316,7 @@ bool TargetSourcesImpl::HandleOneFileSet(
|
||||
if (!baseDirectories.empty()) {
|
||||
fileSet.first->AddDirectoryEntry(
|
||||
BT<std::string>(baseDirectories, this->Makefile->GetBacktrace()));
|
||||
if (type == "HEADERS"_s) {
|
||||
if (type == "HEADERS"_s || type == "CXX_MODULE_HEADER_UNITS"_s) {
|
||||
for (auto const& dir : cmExpandedList(baseDirectories)) {
|
||||
auto interfaceDirectoriesGenex =
|
||||
cmStrCat("$<BUILD_INTERFACE:", dir, ">");
|
||||
|
||||
@@ -347,6 +347,18 @@ std::ostream& cmVisualStudio10TargetGenerator::Elem::WriteString(
|
||||
|
||||
void cmVisualStudio10TargetGenerator::Generate()
|
||||
{
|
||||
for (std::string const& config : this->Configurations) {
|
||||
this->GeneratorTarget->CheckCxxModuleStatus(config);
|
||||
}
|
||||
|
||||
if (this->GeneratorTarget->HaveCxx20ModuleSources()) {
|
||||
this->Makefile->IssueMessage(
|
||||
MessageType::FATAL_ERROR,
|
||||
cmStrCat("The \"", this->GeneratorTarget->GetName(),
|
||||
"\" target contains C++ module sources which are not supported "
|
||||
"by the generator"));
|
||||
}
|
||||
|
||||
this->ProjectType = this->ComputeProjectType(this->GeneratorTarget);
|
||||
this->Managed = this->ProjectType == VsProjectType::csproj;
|
||||
const std::string ProjectFileExtension =
|
||||
|
||||
@@ -564,6 +564,9 @@ if(CMake_TEST_CUDA)
|
||||
endif()
|
||||
add_RunCMake_test(DependencyGraph -DCMAKE_Fortran_COMPILER=${CMAKE_Fortran_COMPILER})
|
||||
|
||||
# Add C++ Module tests.
|
||||
add_RunCMake_test(CXXModules -DCMake_TEST_MODULE_COMPILATION=${CMake_TEST_MODULE_COMPILATION} -DCMake_TEST_MODULE_COMPILATION_RULES=${CMake_TEST_MODULE_COMPILATION_RULES})
|
||||
|
||||
# ctresalloc links against CMakeLib and CTestLib, which means it can't be built
|
||||
# if CMake_TEST_EXTERNAL_CMAKE is activated (the compiler might be different.)
|
||||
# So, it has to be provided in the original build tree.
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
cmake_minimum_required(VERSION 3.23)
|
||||
project(${RunCMake_TEST} NONE)
|
||||
|
||||
set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "17be90bd-a850-44e0-be50-448de847d652")
|
||||
|
||||
include(${RunCMake_TEST}.cmake)
|
||||
@@ -0,0 +1 @@
|
||||
1
|
||||
@@ -0,0 +1,12 @@
|
||||
CMake Warning \(dev\) at FileSetModuleHeaderUnitsInterface.cmake:2 \(target_sources\):
|
||||
CMake's C\+\+ module support is experimental. It is meant only for
|
||||
experimentation and feedback to CMake developers.
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:6 \(include\)
|
||||
This warning is for project developers. Use -Wno-dev to suppress it.
|
||||
|
||||
CMake Error at FileSetModuleHeaderUnitsInterface.cmake:2 \(target_sources\):
|
||||
target_sources File set TYPEs "CXX_MODULES" and "CXX_MODULE_HEADER_UNITS"
|
||||
may not have "INTERFACE" visibility
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:6 \(include\)
|
||||
@@ -0,0 +1,8 @@
|
||||
add_library(module-header)
|
||||
target_sources(module-header
|
||||
INTERFACE
|
||||
FILE_SET fs TYPE CXX_MODULE_HEADER_UNITS FILES
|
||||
sources/module-header.h)
|
||||
target_compile_features(module-header
|
||||
PRIVATE
|
||||
cxx_std_20)
|
||||
@@ -0,0 +1,11 @@
|
||||
CMake Warning \(dev\) at FileSetModuleHeaderUnitsPrivate.cmake:7 \(target_sources\):
|
||||
CMake's C\+\+ module support is experimental. It is meant only for
|
||||
experimentation and feedback to CMake developers.
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:6 \(include\)
|
||||
This warning is for project developers. Use -Wno-dev to suppress it.
|
||||
|
||||
CMake Warning \(dev\):
|
||||
C\+\+20 modules support via CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP is
|
||||
experimental. It is meant only for compiler developers to try.
|
||||
This warning is for project developers. Use -Wno-dev to suppress it.
|
||||
@@ -0,0 +1,13 @@
|
||||
enable_language(CXX)
|
||||
set(CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP 1)
|
||||
set(CMAKE_EXPERIMENTAL_CXX_SCANDEP_SOURCE "")
|
||||
|
||||
add_library(module-header
|
||||
sources/cxx-anchor.cxx)
|
||||
target_sources(module-header
|
||||
PRIVATE
|
||||
FILE_SET fs TYPE CXX_MODULE_HEADER_UNITS FILES
|
||||
sources/module-header.h)
|
||||
target_compile_features(module-header
|
||||
PRIVATE
|
||||
cxx_std_20)
|
||||
@@ -0,0 +1,11 @@
|
||||
CMake Warning \(dev\) at FileSetModuleHeaderUnitsPublic.cmake:7 \(target_sources\):
|
||||
CMake's C\+\+ module support is experimental. It is meant only for
|
||||
experimentation and feedback to CMake developers.
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:6 \(include\)
|
||||
This warning is for project developers. Use -Wno-dev to suppress it.
|
||||
|
||||
CMake Warning \(dev\):
|
||||
C\+\+20 modules support via CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP is
|
||||
experimental. It is meant only for compiler developers to try.
|
||||
This warning is for project developers. Use -Wno-dev to suppress it.
|
||||
@@ -0,0 +1,13 @@
|
||||
enable_language(CXX)
|
||||
set(CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP 1)
|
||||
set(CMAKE_EXPERIMENTAL_CXX_SCANDEP_SOURCE "")
|
||||
|
||||
add_library(module-header
|
||||
sources/cxx-anchor.cxx)
|
||||
target_sources(module-header
|
||||
PUBLIC
|
||||
FILE_SET fs TYPE CXX_MODULE_HEADER_UNITS FILES
|
||||
sources/module-header.h)
|
||||
target_compile_features(module-header
|
||||
PRIVATE
|
||||
cxx_std_20)
|
||||
@@ -0,0 +1 @@
|
||||
1
|
||||
@@ -0,0 +1,12 @@
|
||||
CMake Warning \(dev\) at FileSetModulesInterface.cmake:2 \(target_sources\):
|
||||
CMake's C\+\+ module support is experimental. It is meant only for
|
||||
experimentation and feedback to CMake developers.
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:6 \(include\)
|
||||
This warning is for project developers. Use -Wno-dev to suppress it.
|
||||
|
||||
CMake Error at FileSetModulesInterface.cmake:2 \(target_sources\):
|
||||
target_sources File set TYPEs "CXX_MODULES" and "CXX_MODULE_HEADER_UNITS"
|
||||
may not have "INTERFACE" visibility
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:6 \(include\)
|
||||
@@ -0,0 +1,8 @@
|
||||
add_library(module)
|
||||
target_sources(module
|
||||
INTERFACE
|
||||
FILE_SET fs TYPE CXX_MODULES FILES
|
||||
sources/module.cxx)
|
||||
target_compile_features(module
|
||||
PRIVATE
|
||||
cxx_std_20)
|
||||
@@ -0,0 +1,11 @@
|
||||
CMake Warning \(dev\) at FileSetModulesPrivate.cmake:6 \(target_sources\):
|
||||
CMake's C\+\+ module support is experimental. It is meant only for
|
||||
experimentation and feedback to CMake developers.
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:6 \(include\)
|
||||
This warning is for project developers. Use -Wno-dev to suppress it.
|
||||
|
||||
CMake Warning \(dev\):
|
||||
C\+\+20 modules support via CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP is
|
||||
experimental. It is meant only for compiler developers to try.
|
||||
This warning is for project developers. Use -Wno-dev to suppress it.
|
||||
@@ -0,0 +1,12 @@
|
||||
enable_language(CXX)
|
||||
set(CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP 1)
|
||||
set(CMAKE_EXPERIMENTAL_CXX_SCANDEP_SOURCE "")
|
||||
|
||||
add_library(module)
|
||||
target_sources(module
|
||||
PRIVATE
|
||||
FILE_SET fs TYPE CXX_MODULES FILES
|
||||
sources/module.cxx)
|
||||
target_compile_features(module
|
||||
PRIVATE
|
||||
cxx_std_20)
|
||||
@@ -0,0 +1,11 @@
|
||||
CMake Warning \(dev\) at FileSetModulesPublic.cmake:6 \(target_sources\):
|
||||
CMake's C\+\+ module support is experimental. It is meant only for
|
||||
experimentation and feedback to CMake developers.
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:6 \(include\)
|
||||
This warning is for project developers. Use -Wno-dev to suppress it.
|
||||
|
||||
CMake Warning \(dev\):
|
||||
C\+\+20 modules support via CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP is
|
||||
experimental. It is meant only for compiler developers to try.
|
||||
This warning is for project developers. Use -Wno-dev to suppress it.
|
||||
@@ -0,0 +1,12 @@
|
||||
enable_language(CXX)
|
||||
set(CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP 1)
|
||||
set(CMAKE_EXPERIMENTAL_CXX_SCANDEP_SOURCE "")
|
||||
|
||||
add_library(module)
|
||||
target_sources(module
|
||||
PUBLIC
|
||||
FILE_SET fs TYPE CXX_MODULES FILES
|
||||
sources/module.cxx)
|
||||
target_compile_features(module
|
||||
PRIVATE
|
||||
cxx_std_20)
|
||||
@@ -0,0 +1 @@
|
||||
1
|
||||
@@ -0,0 +1,20 @@
|
||||
CMake Warning \(dev\) at NoCXX.cmake:4 \(target_sources\):
|
||||
CMake's C\+\+ module support is experimental. It is meant only for
|
||||
experimentation and feedback to CMake developers.
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:6 \(include\)
|
||||
This warning is for project developers. Use -Wno-dev to suppress it.
|
||||
|
||||
CMake Error in CMakeLists.txt:
|
||||
The "nocxx" target has C\+\+ module sources but the "CXX" language has not
|
||||
been enabled
|
||||
|
||||
(
|
||||
CMake Error in CMakeLists.txt:
|
||||
( The "nocxx" target has C\+\+ module sources but the "CXX" language has not
|
||||
been enabled
|
||||
| The "nocxx" target contains C\+\+ module sources which are not supported by
|
||||
the generator
|
||||
)
|
||||
)*
|
||||
CMake Generate step failed. Build files cannot be regenerated correctly.
|
||||
@@ -0,0 +1,9 @@
|
||||
enable_language(C)
|
||||
|
||||
add_library(nocxx)
|
||||
target_sources(nocxx
|
||||
PRIVATE
|
||||
sources/c-anchor.c
|
||||
PUBLIC
|
||||
FILE_SET fs TYPE CXX_MODULES FILES
|
||||
sources/module.cxx)
|
||||
@@ -0,0 +1 @@
|
||||
1
|
||||
@@ -0,0 +1,20 @@
|
||||
CMake Warning \(dev\) at NoCXX20.cmake:4 \(target_sources\):
|
||||
CMake's C\+\+ module support is experimental. It is meant only for
|
||||
experimentation and feedback to CMake developers.
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:6 \(include\)
|
||||
This warning is for project developers. Use -Wno-dev to suppress it.
|
||||
|
||||
CMake Error in CMakeLists.txt:
|
||||
The "nocxx20" target has C\+\+ module sources but is not using at least
|
||||
"cxx_std_20"
|
||||
|
||||
(
|
||||
CMake Error in CMakeLists.txt:
|
||||
( The "nocxx20" target has C\+\+ module sources but is not using at least
|
||||
"cxx_std_20"
|
||||
| The "nocxx20" target contains C\+\+ module sources which are not supported by
|
||||
the generator
|
||||
)
|
||||
)*
|
||||
CMake Generate step failed. Build files cannot be regenerated correctly.
|
||||
@@ -0,0 +1,10 @@
|
||||
enable_language(CXX)
|
||||
|
||||
add_library(nocxx20)
|
||||
target_sources(nocxx20
|
||||
PUBLIC
|
||||
FILE_SET fs TYPE CXX_MODULES FILES
|
||||
sources/module.cxx)
|
||||
target_compile_features(nocxx20
|
||||
PRIVATE
|
||||
cxx_std_17)
|
||||
@@ -0,0 +1 @@
|
||||
1
|
||||
@@ -0,0 +1,20 @@
|
||||
CMake Warning \(dev\) at NoCXX20ModuleFlag.cmake:4 \(target_sources\):
|
||||
CMake's C\+\+ module support is experimental. It is meant only for
|
||||
experimentation and feedback to CMake developers.
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:6 \(include\)
|
||||
This warning is for project developers. Use -Wno-dev to suppress it.
|
||||
|
||||
CMake Error in CMakeLists.txt:
|
||||
The "noexperimentalflag" target has C\+\+ module sources but its experimental
|
||||
support has not been requested
|
||||
|
||||
(
|
||||
CMake Error in CMakeLists.txt:
|
||||
( The "noexperimentalflag" target has C\+\+ module sources but its experimental
|
||||
support has not been requested
|
||||
| The "noexperimentalflag" target contains C\+\+ module sources which are not
|
||||
supported by the generator
|
||||
)
|
||||
)*
|
||||
CMake Generate step failed. Build files cannot be regenerated correctly.
|
||||
@@ -0,0 +1,10 @@
|
||||
enable_language(CXX)
|
||||
|
||||
add_library(noexperimentalflag)
|
||||
target_sources(noexperimentalflag
|
||||
PUBLIC
|
||||
FILE_SET fs TYPE CXX_MODULES FILES
|
||||
sources/module.cxx)
|
||||
target_compile_features(noexperimentalflag
|
||||
PRIVATE
|
||||
cxx_std_20)
|
||||
@@ -0,0 +1 @@
|
||||
1
|
||||
@@ -0,0 +1,30 @@
|
||||
CMake Warning \(dev\) at NoDyndepSupport.cmake:10 \(target_sources\):
|
||||
CMake's C\+\+ module support is experimental. It is meant only for
|
||||
experimentation and feedback to CMake developers.
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:6 \(include\)
|
||||
This warning is for project developers. Use -Wno-dev to suppress it.
|
||||
|
||||
(CMake Warning \(dev\):
|
||||
C\+\+20 modules support via CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP is
|
||||
experimental. It is meant only for compiler developers to try.
|
||||
This warning is for project developers. Use -Wno-dev to suppress it.
|
||||
|
||||
CMake Error:
|
||||
The Ninja generator does not support C\+\+20 modules using Ninja version
|
||||
|
||||
.*
|
||||
|
||||
due to lack of required features. Ninja 1.10 or higher is required.
|
||||
|
||||
|CMake Error in CMakeLists.txt:
|
||||
The "nodyndep" target contains C\+\+ module sources which are not supported
|
||||
by the generator
|
||||
|
||||
(
|
||||
CMake Error in CMakeLists.txt:
|
||||
The "nodyndep" target contains C\+\+ module sources which are not supported
|
||||
by the generator
|
||||
|
||||
)*)
|
||||
CMake Generate step failed. Build files cannot be regenerated correctly.
|
||||
@@ -0,0 +1,16 @@
|
||||
enable_language(CXX)
|
||||
set(CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP 1)
|
||||
set(CMAKE_EXPERIMENTAL_CXX_SCANDEP_SOURCE "")
|
||||
|
||||
if (NOT CMAKE_CXX_STANDARD_DEFAULT)
|
||||
set(CMAKE_CXX_STANDARD_DEFAULT "11")
|
||||
endif ()
|
||||
|
||||
add_library(nodyndep)
|
||||
target_sources(nodyndep
|
||||
PUBLIC
|
||||
FILE_SET fs TYPE CXX_MODULES FILES
|
||||
sources/module.cxx)
|
||||
target_compile_features(nodyndep
|
||||
PRIVATE
|
||||
cxx_std_20)
|
||||
@@ -0,0 +1 @@
|
||||
1
|
||||
@@ -0,0 +1,22 @@
|
||||
CMake Warning \(dev\) at NotCXXSourceModuleHeaderUnits.cmake:7 \(target_sources\):
|
||||
CMake's C\+\+ module support is experimental. It is meant only for
|
||||
experimentation and feedback to CMake developers.
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:6 \(include\)
|
||||
This warning is for project developers. Use -Wno-dev to suppress it.
|
||||
|
||||
CMake Warning \(dev\):
|
||||
C\+\+20 modules support via CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP is
|
||||
experimental. It is meant only for compiler developers to try.
|
||||
This warning is for project developers. Use -Wno-dev to suppress it.
|
||||
|
||||
CMake Error in CMakeLists.txt:
|
||||
Target "not-cxx-source" contains the source
|
||||
|
||||
.*/Tests/RunCMake/CXXModules/sources/c-anchor.c
|
||||
|
||||
in a file set of type "CXX_MODULE_HEADER_UNITS" but the source is not
|
||||
classified as a "CXX" source.
|
||||
|
||||
|
||||
CMake Generate step failed. Build files cannot be regenerated correctly.
|
||||
@@ -0,0 +1,15 @@
|
||||
enable_language(C)
|
||||
enable_language(CXX)
|
||||
set(CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP 1)
|
||||
set(CMAKE_EXPERIMENTAL_CXX_SCANDEP_SOURCE "")
|
||||
|
||||
add_library(not-cxx-source)
|
||||
target_sources(not-cxx-source
|
||||
PRIVATE
|
||||
sources/cxx-anchor.cxx
|
||||
PUBLIC
|
||||
FILE_SET fs TYPE CXX_MODULE_HEADER_UNITS FILES
|
||||
sources/c-anchor.c)
|
||||
target_compile_features(not-cxx-source
|
||||
PRIVATE
|
||||
cxx_std_20)
|
||||
@@ -0,0 +1 @@
|
||||
1
|
||||
@@ -0,0 +1,17 @@
|
||||
CMake Warning \(dev\) at NotCXXSourceModules.cmake:7 \(target_sources\):
|
||||
CMake's C\+\+ module support is experimental. It is meant only for
|
||||
experimentation and feedback to CMake developers.
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:6 \(include\)
|
||||
This warning is for project developers. Use -Wno-dev to suppress it.
|
||||
|
||||
CMake Error in CMakeLists.txt:
|
||||
Target "not-cxx-source" contains the source
|
||||
|
||||
.*/Tests/RunCMake/CXXModules/sources/c-anchor.c
|
||||
|
||||
in a file set of type "CXX_MODULES" but the source is not classified as a
|
||||
"CXX" source.
|
||||
|
||||
|
||||
CMake Generate step failed. Build files cannot be regenerated correctly.
|
||||
@@ -0,0 +1,13 @@
|
||||
enable_language(C)
|
||||
enable_language(CXX)
|
||||
set(CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP 1)
|
||||
set(CMAKE_EXPERIMENTAL_CXX_SCANDEP_SOURCE "")
|
||||
|
||||
add_library(not-cxx-source)
|
||||
target_sources(not-cxx-source
|
||||
PUBLIC
|
||||
FILE_SET fs TYPE CXX_MODULES FILES
|
||||
sources/c-anchor.c)
|
||||
target_compile_features(not-cxx-source
|
||||
PRIVATE
|
||||
cxx_std_20)
|
||||
@@ -0,0 +1,120 @@
|
||||
include(RunCMake)
|
||||
|
||||
# For `if (IN_LIST)`
|
||||
cmake_policy(SET CMP0057 NEW)
|
||||
|
||||
run_cmake(compiler_introspection)
|
||||
include("${RunCMake_BINARY_DIR}/compiler_introspection-build/info.cmake")
|
||||
|
||||
# Test negative cases where C++20 modules do not work.
|
||||
run_cmake(NoCXX)
|
||||
if ("cxx_std_20" IN_LIST CMAKE_CXX_COMPILE_FEATURES)
|
||||
# This test requires that the compiler be told to compile in an older-than-20
|
||||
# standard. If the compiler forces a standard to be used, skip it.
|
||||
if (NOT forced_cxx_standard)
|
||||
run_cmake(NoCXX20)
|
||||
endif ()
|
||||
|
||||
# This test uses C++20, but another prerequisite is missing, so forced
|
||||
# standards don't matter.
|
||||
run_cmake(NoCXX20ModuleFlag)
|
||||
endif ()
|
||||
|
||||
if (RunCMake_GENERATOR MATCHES "Ninja")
|
||||
execute_process(
|
||||
COMMAND "${CMAKE_MAKE_PROGRAM}" --version
|
||||
RESULT_VARIABLE res
|
||||
OUTPUT_VARIABLE ninja_version
|
||||
ERROR_VARIABLE err
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
ERROR_STRIP_TRAILING_WHITESPACE)
|
||||
|
||||
if (res)
|
||||
message(WARNING
|
||||
"Failed to determine `ninja` version: ${err}")
|
||||
set(ninja_version "0")
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
# Test behavior when the generator does not support C++20 modules.
|
||||
if (NOT RunCMake_GENERATOR MATCHES "Ninja" OR
|
||||
ninja_version VERSION_LESS "1.10" OR
|
||||
NOT "cxx_std_20" IN_LIST CMAKE_CXX_COMPILE_FEATURES)
|
||||
if ("cxx_std_20" IN_LIST CMAKE_CXX_COMPILE_FEATURES)
|
||||
run_cmake(NoDyndepSupport)
|
||||
endif ()
|
||||
|
||||
# Bail; the remaining tests require the generator to successfully generate
|
||||
# with C++20 modules in the source list.
|
||||
return ()
|
||||
endif ()
|
||||
|
||||
set(fileset_types
|
||||
Modules
|
||||
ModuleHeaderUnits)
|
||||
set(scopes
|
||||
Interface
|
||||
Private
|
||||
Public)
|
||||
foreach (fileset_type IN LISTS fileset_types)
|
||||
foreach (scope IN LISTS scopes)
|
||||
run_cmake("FileSet${fileset_type}${scope}")
|
||||
endforeach ()
|
||||
|
||||
# Test the error message when a non-C++ source file is found in the source
|
||||
# list.
|
||||
run_cmake("NotCXXSource${fileset_type}")
|
||||
endforeach ()
|
||||
|
||||
# Actual compilation tests.
|
||||
if (NOT CMake_TEST_MODULE_COMPILATION)
|
||||
return ()
|
||||
endif ()
|
||||
|
||||
function (run_cxx_module_test directory)
|
||||
set(test_name "${directory}")
|
||||
if (NOT ARGN STREQUAL "")
|
||||
list(POP_FRONT ARGN test_name)
|
||||
endif ()
|
||||
|
||||
set(RunCMake_TEST_SOURCE_DIR "${CMAKE_CURRENT_LIST_DIR}/examples/${directory}")
|
||||
set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/examples/${test_name}-build")
|
||||
|
||||
if (RunCMake_GENERATOR_IS_MULTI_CONFIG)
|
||||
set(RunCMake_TEST_OPTIONS -DCMAKE_CONFIGURATION_TYPES=Debug)
|
||||
else ()
|
||||
set(RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=Debug)
|
||||
endif ()
|
||||
|
||||
set(RunCMake_TEST_OPTIONS
|
||||
"-DCMake_TEST_MODULE_COMPILATION_RULES=${CMake_TEST_MODULE_COMPILATION_RULES}"
|
||||
${ARGN})
|
||||
run_cmake("examples/${test_name}")
|
||||
set(RunCMake_TEST_NO_CLEAN 1)
|
||||
run_cmake_command("${test_name}-build" "${CMAKE_COMMAND}" --build . --config Debug)
|
||||
run_cmake_command("${test_name}-test" "${CMAKE_CTEST_COMMAND}" -C Debug)
|
||||
endfunction ()
|
||||
|
||||
string(REPLACE "," ";" CMake_TEST_MODULE_COMPILATION "${CMake_TEST_MODULE_COMPILATION}")
|
||||
|
||||
# Tests which use named modules.
|
||||
if ("named" IN_LIST CMake_TEST_MODULE_COMPILATION)
|
||||
run_cxx_module_test(simple)
|
||||
run_cxx_module_test(library library-static -DBUILD_SHARED_LIBS=OFF)
|
||||
run_cxx_module_test(generated)
|
||||
endif ()
|
||||
|
||||
# Tests which use named modules in shared libraries.
|
||||
if ("shared" IN_LIST CMake_TEST_MODULE_COMPILATION)
|
||||
run_cxx_module_test(library library-shared -DBUILD_SHARED_LIBS=ON)
|
||||
endif ()
|
||||
|
||||
# Tests which use partitions.
|
||||
if ("partitions" IN_LIST CMake_TEST_MODULE_COMPILATION)
|
||||
run_cxx_module_test(partitions)
|
||||
endif ()
|
||||
|
||||
# Tests which use internal partitions.
|
||||
if ("internal_partitions" IN_LIST CMake_TEST_MODULE_COMPILATION)
|
||||
run_cxx_module_test(internal-partitions)
|
||||
endif ()
|
||||
@@ -0,0 +1,25 @@
|
||||
enable_language(CXX)
|
||||
|
||||
set(info "")
|
||||
|
||||
# See `Modules/Compiler/MSVC-CXX.cmake` for this. If there is explicitly no
|
||||
# default, the feature list is populated to be everything.
|
||||
if (DEFINED CMAKE_CXX_STANDARD_DEFAULT AND
|
||||
CMAKE_CXX_STANDARD_DEFAULT STREQUAL "")
|
||||
set(CMAKE_CXX_COMPILE_FEATURES "")
|
||||
endif ()
|
||||
|
||||
# Detect if the environment forces a C++ standard, let the test selection know.
|
||||
set(forced_cxx_standard 0)
|
||||
if (CMAKE_CXX_FLAGS MATCHES "-std=")
|
||||
set(forced_cxx_standard 1)
|
||||
endif ()
|
||||
|
||||
# Forward information about the C++ compile features.
|
||||
string(APPEND info "\
|
||||
set(CMAKE_CXX_COMPILE_FEATURES \"${CMAKE_CXX_COMPILE_FEATURES}\")
|
||||
set(CMAKE_MAKE_PROGRAM \"${CMAKE_MAKE_PROGRAM}\")
|
||||
set(forced_cxx_standard \"${forced_cxx_standard}\")
|
||||
")
|
||||
|
||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/info.cmake" "${info}")
|
||||
@@ -0,0 +1,18 @@
|
||||
set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "17be90bd-a850-44e0-be50-448de847d652")
|
||||
|
||||
if (NOT EXISTS "${CMake_TEST_MODULE_COMPILATION_RULES}")
|
||||
message(FATAL_ERROR
|
||||
"The `CMake_TEST_MODULE_COMPILATION_RULES` file must be specified "
|
||||
"for these tests to operate.")
|
||||
endif ()
|
||||
|
||||
include("${CMake_TEST_MODULE_COMPILATION_RULES}")
|
||||
|
||||
if (NOT CMake_TEST_CXXModules_UUID STREQUAL "a246741c-d067-4019-a8fb-3d16b0c9d1d3")
|
||||
message(FATAL_ERROR
|
||||
"The compilation rule file needs updated for changes in the test "
|
||||
"suite. Please see the history for what needs to be updated.")
|
||||
endif ()
|
||||
|
||||
include(CTest)
|
||||
enable_testing()
|
||||
@@ -0,0 +1,9 @@
|
||||
CMake Warning \(dev\) at CMakeLists.txt:12 \(target_sources\):
|
||||
CMake's C\+\+ module support is experimental. It is meant only for
|
||||
experimentation and feedback to CMake developers.
|
||||
This warning is for project developers. Use -Wno-dev to suppress it.
|
||||
|
||||
CMake Warning \(dev\):
|
||||
C\+\+20 modules support via CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP is
|
||||
experimental. It is meant only for compiler developers to try.
|
||||
This warning is for project developers. Use -Wno-dev to suppress it.
|
||||
@@ -0,0 +1,23 @@
|
||||
cmake_minimum_required(VERSION 3.24)
|
||||
project(cxx_modules_generated CXX)
|
||||
|
||||
include("${CMAKE_SOURCE_DIR}/../cxx-modules-rules.cmake")
|
||||
|
||||
configure_file(
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/importable.cxx.in"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/importable.cxx"
|
||||
COPYONLY)
|
||||
|
||||
add_executable(generated)
|
||||
target_sources(generated
|
||||
PRIVATE
|
||||
main.cxx
|
||||
PRIVATE
|
||||
FILE_SET CXX_MODULES
|
||||
BASE_DIRS
|
||||
"${CMAKE_CURRENT_BINARY_DIR}"
|
||||
FILES
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/importable.cxx")
|
||||
target_compile_features(generated PUBLIC cxx_std_20)
|
||||
|
||||
add_test(NAME generated COMMAND generated)
|
||||
@@ -0,0 +1,5 @@
|
||||
export module importable;
|
||||
|
||||
export int from_import() {
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
import importable;
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
return from_import();
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
CMake Warning \(dev\) at CMakeLists.txt:10 \(target_sources\):
|
||||
CMake's C\+\+ module support is experimental. It is meant only for
|
||||
experimentation and feedback to CMake developers.
|
||||
This warning is for project developers. Use -Wno-dev to suppress it.
|
||||
|
||||
CMake Warning \(dev\):
|
||||
C\+\+20 modules support via CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP is
|
||||
experimental. It is meant only for compiler developers to try.
|
||||
This warning is for project developers. Use -Wno-dev to suppress it.
|
||||
@@ -0,0 +1,31 @@
|
||||
cmake_minimum_required(VERSION 3.24)
|
||||
project(cxx_modules_internal_partitions CXX)
|
||||
|
||||
include("${CMAKE_SOURCE_DIR}/../cxx-modules-rules.cmake")
|
||||
|
||||
include(GenerateExportHeader)
|
||||
|
||||
add_library(internal-partitions)
|
||||
generate_export_header(internal-partitions)
|
||||
target_sources(internal-partitions
|
||||
PUBLIC
|
||||
FILE_SET HEADERS
|
||||
BASE_DIRS
|
||||
"${CMAKE_CURRENT_BINARY_DIR}"
|
||||
FILES
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/internal-partitions_export.h"
|
||||
FILE_SET CXX_MODULES
|
||||
BASE_DIRS
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
FILES
|
||||
importable.cxx
|
||||
partition.cxx)
|
||||
target_compile_features(internal-partitions PUBLIC cxx_std_20)
|
||||
|
||||
add_executable(exe)
|
||||
target_link_libraries(exe PRIVATE internal-partitions)
|
||||
target_sources(exe
|
||||
PRIVATE
|
||||
main.cxx)
|
||||
|
||||
add_test(NAME exe COMMAND exe)
|
||||
@@ -0,0 +1,9 @@
|
||||
export module importable;
|
||||
import importable : internal_partition;
|
||||
|
||||
#include "internal-partitions_export.h"
|
||||
|
||||
export INTERNAL_PARTITIONS_EXPORT int from_import()
|
||||
{
|
||||
return from_partition();
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
import importable;
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
return from_import();
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
module importable : internal_partition;
|
||||
|
||||
int from_partition()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
CMake Warning \(dev\) at CMakeLists.txt:10 \(target_sources\):
|
||||
CMake's C\+\+ module support is experimental. It is meant only for
|
||||
experimentation and feedback to CMake developers.
|
||||
This warning is for project developers. Use -Wno-dev to suppress it.
|
||||
|
||||
CMake Warning \(dev\):
|
||||
C\+\+20 modules support via CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP is
|
||||
experimental. It is meant only for compiler developers to try.
|
||||
This warning is for project developers. Use -Wno-dev to suppress it.
|
||||
@@ -0,0 +1,9 @@
|
||||
CMake Warning \(dev\) at CMakeLists.txt:10 \(target_sources\):
|
||||
CMake's C\+\+ module support is experimental. It is meant only for
|
||||
experimentation and feedback to CMake developers.
|
||||
This warning is for project developers. Use -Wno-dev to suppress it.
|
||||
|
||||
CMake Warning \(dev\):
|
||||
C\+\+20 modules support via CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP is
|
||||
experimental. It is meant only for compiler developers to try.
|
||||
This warning is for project developers. Use -Wno-dev to suppress it.
|
||||
@@ -0,0 +1,30 @@
|
||||
cmake_minimum_required(VERSION 3.24)
|
||||
project(cxx_modules_library CXX)
|
||||
|
||||
include("${CMAKE_SOURCE_DIR}/../cxx-modules-rules.cmake")
|
||||
|
||||
include(GenerateExportHeader)
|
||||
|
||||
add_library(library)
|
||||
generate_export_header(library)
|
||||
target_sources(library
|
||||
PUBLIC
|
||||
FILE_SET HEADERS
|
||||
BASE_DIRS
|
||||
"${CMAKE_CURRENT_BINARY_DIR}"
|
||||
FILES
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/library_export.h"
|
||||
FILE_SET CXX_MODULES
|
||||
BASE_DIRS
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
FILES
|
||||
importable.cxx)
|
||||
target_compile_features(library PUBLIC cxx_std_20)
|
||||
|
||||
add_executable(exe)
|
||||
target_link_libraries(exe PRIVATE library)
|
||||
target_sources(exe
|
||||
PRIVATE
|
||||
main.cxx)
|
||||
|
||||
add_test(NAME exe COMMAND exe)
|
||||
@@ -0,0 +1,8 @@
|
||||
export module importable;
|
||||
|
||||
#include "library_export.h"
|
||||
|
||||
export LIBRARY_EXPORT int from_import()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
import importable;
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
return from_import();
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
CMake Warning \(dev\) at CMakeLists.txt:10 \(target_sources\):
|
||||
CMake's C\+\+ module support is experimental. It is meant only for
|
||||
experimentation and feedback to CMake developers.
|
||||
This warning is for project developers. Use -Wno-dev to suppress it.
|
||||
|
||||
CMake Warning \(dev\):
|
||||
C\+\+20 modules support via CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP is
|
||||
experimental. It is meant only for compiler developers to try.
|
||||
This warning is for project developers. Use -Wno-dev to suppress it.
|
||||
@@ -0,0 +1,31 @@
|
||||
cmake_minimum_required(VERSION 3.24)
|
||||
project(cxx_modules_partitions CXX)
|
||||
|
||||
include("${CMAKE_SOURCE_DIR}/../cxx-modules-rules.cmake")
|
||||
|
||||
include(GenerateExportHeader)
|
||||
|
||||
add_library(partitions)
|
||||
generate_export_header(partitions)
|
||||
target_sources(partitions
|
||||
PUBLIC
|
||||
FILE_SET HEADERS
|
||||
BASE_DIRS
|
||||
"${CMAKE_CURRENT_BINARY_DIR}"
|
||||
FILES
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/partitions_export.h"
|
||||
FILE_SET CXX_MODULES
|
||||
BASE_DIRS
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
FILES
|
||||
importable.cxx
|
||||
partition.cxx)
|
||||
target_compile_features(partitions PUBLIC cxx_std_20)
|
||||
|
||||
add_executable(exe)
|
||||
target_link_libraries(exe PRIVATE partitions)
|
||||
target_sources(exe
|
||||
PRIVATE
|
||||
main.cxx)
|
||||
|
||||
add_test(NAME exe COMMAND exe)
|
||||
@@ -0,0 +1,9 @@
|
||||
export module importable;
|
||||
export import importable : partition;
|
||||
|
||||
#include "partitions_export.h"
|
||||
|
||||
export PARTITIONS_EXPORT int from_import()
|
||||
{
|
||||
return from_partition();
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
import importable;
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
return from_import() + from_partition();
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
export module importable : partition;
|
||||
|
||||
#include "partitions_export.h"
|
||||
|
||||
export PARTITIONS_EXPORT int from_partition()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user