mirror of
https://github.com/Kitware/CMake.git
synced 2026-01-05 21:31:08 -06:00
cxxmodules: add properties to control scanning
The `CXX_SCAN_FOR_MODULES` property may be used to control scanning for targets and for source files rather than assuming "C++20 always needs to be scanned".
This commit is contained in:
@@ -195,6 +195,7 @@ Properties on Targets
|
|||||||
/prop_tgt/CXX_MODULE_SET
|
/prop_tgt/CXX_MODULE_SET
|
||||||
/prop_tgt/CXX_MODULE_SET_NAME
|
/prop_tgt/CXX_MODULE_SET_NAME
|
||||||
/prop_tgt/CXX_MODULE_SETS
|
/prop_tgt/CXX_MODULE_SETS
|
||||||
|
/prop_tgt/CXX_SCAN_FOR_MODULES
|
||||||
/prop_tgt/CXX_STANDARD
|
/prop_tgt/CXX_STANDARD
|
||||||
/prop_tgt/CXX_STANDARD_REQUIRED
|
/prop_tgt/CXX_STANDARD_REQUIRED
|
||||||
/prop_tgt/DEBUG_POSTFIX
|
/prop_tgt/DEBUG_POSTFIX
|
||||||
@@ -533,6 +534,7 @@ Properties on Source Files
|
|||||||
/prop_sf/COMPILE_DEFINITIONS
|
/prop_sf/COMPILE_DEFINITIONS
|
||||||
/prop_sf/COMPILE_FLAGS
|
/prop_sf/COMPILE_FLAGS
|
||||||
/prop_sf/COMPILE_OPTIONS
|
/prop_sf/COMPILE_OPTIONS
|
||||||
|
/prop_sf/CXX_SCAN_FOR_MODULES
|
||||||
/prop_sf/EXTERNAL_OBJECT
|
/prop_sf/EXTERNAL_OBJECT
|
||||||
/prop_sf/Fortran_FORMAT
|
/prop_sf/Fortran_FORMAT
|
||||||
/prop_sf/Fortran_PREPROCESS
|
/prop_sf/Fortran_PREPROCESS
|
||||||
|
|||||||
@@ -417,6 +417,7 @@ Variables that Control the Build
|
|||||||
/variable/CMAKE_CUDA_RESOLVE_DEVICE_SYMBOLS
|
/variable/CMAKE_CUDA_RESOLVE_DEVICE_SYMBOLS
|
||||||
/variable/CMAKE_CUDA_RUNTIME_LIBRARY
|
/variable/CMAKE_CUDA_RUNTIME_LIBRARY
|
||||||
/variable/CMAKE_CUDA_SEPARABLE_COMPILATION
|
/variable/CMAKE_CUDA_SEPARABLE_COMPILATION
|
||||||
|
/variable/CMAKE_CXX_SCAN_FOR_MODULES
|
||||||
/variable/CMAKE_DEBUG_POSTFIX
|
/variable/CMAKE_DEBUG_POSTFIX
|
||||||
/variable/CMAKE_DEFAULT_BUILD_TYPE
|
/variable/CMAKE_DEFAULT_BUILD_TYPE
|
||||||
/variable/CMAKE_DEFAULT_CONFIGS
|
/variable/CMAKE_DEFAULT_CONFIGS
|
||||||
|
|||||||
19
Help/prop_sf/CXX_SCAN_FOR_MODULES.rst
Normal file
19
Help/prop_sf/CXX_SCAN_FOR_MODULES.rst
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
CXX_SCAN_FOR_MODULES
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
.. versionadded:: 3.26
|
||||||
|
|
||||||
|
``CXX_SCAN_FOR_MODULES`` is a boolean specifying whether CMake will scan the
|
||||||
|
source for C++ module dependencies. See also the
|
||||||
|
:prop_tgt:`CXX_SCAN_FOR_MODULES` for target-wide settings.
|
||||||
|
|
||||||
|
When this property is set ``ON``, CMake will scan the source at build time and
|
||||||
|
add module dependency information to the compile line as necessary. When this
|
||||||
|
property is set ``OFF``, CMake will not scan the source at build time. When
|
||||||
|
this property is unset, the :prop_tgt:`CXX_SCAN_FOR_MODULES` property is
|
||||||
|
consulted.
|
||||||
|
|
||||||
|
Note that scanning is only performed if C++20 or higher is enabled for the
|
||||||
|
target and the source uses the ``CXX`` language. Scanning for modules in
|
||||||
|
sources belonging to file sets of type ``CXX_MODULES`` and
|
||||||
|
``CXX_MODULES_HEADER_UNITS`` is always performed.
|
||||||
22
Help/prop_tgt/CXX_SCAN_FOR_MODULES.rst
Normal file
22
Help/prop_tgt/CXX_SCAN_FOR_MODULES.rst
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
CXX_SCAN_FOR_MODULES
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
.. versionadded:: 3.26
|
||||||
|
|
||||||
|
``CXX_SCAN_FOR_MODULES`` is a boolean specifying whether CMake will scan C++
|
||||||
|
sources in the target for module dependencies. See also the
|
||||||
|
:prop_sf:`CXX_SCAN_FOR_MODULES` for per-source settings which, if set,
|
||||||
|
overrides the target-wide settings.
|
||||||
|
|
||||||
|
This property is initialized by the value of the
|
||||||
|
:variable:`CMAKE_CXX_SCAN_FOR_MODULES` variable if it is set when a target is
|
||||||
|
created.
|
||||||
|
|
||||||
|
When this property is set ``ON`` or unset, CMake will scan the target's
|
||||||
|
``CXX`` sources at build time and add module dependency information to the
|
||||||
|
compile line as necessary. When this property is set ``OFF``, CMake will not
|
||||||
|
scan the target's ``CXX`` sources at build time.
|
||||||
|
|
||||||
|
Note that scanning is only performed if C++20 or higher is enabled for the
|
||||||
|
target. Scanning for modules in the target's sources belonging to file sets
|
||||||
|
of type ``CXX_MODULES`` and ``CXX_MODULES_HEADER_UNITS`` is always performed.
|
||||||
5
Help/release/dev/cxx-scanning-properties.rst
Normal file
5
Help/release/dev/cxx-scanning-properties.rst
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
cxx-scanning-properties
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
* The :prop_tgt:`CXX_SCAN_FOR_MODULES` target and source file properties may
|
||||||
|
be used to enable or disable scanning for C++ module dependencies.
|
||||||
10
Help/variable/CMAKE_CXX_SCAN_FOR_MODULES.rst
Normal file
10
Help/variable/CMAKE_CXX_SCAN_FOR_MODULES.rst
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
CMAKE_CXX_SCAN_FOR_MODULES
|
||||||
|
--------------------------
|
||||||
|
|
||||||
|
.. versionadded:: 3.26
|
||||||
|
|
||||||
|
Whether to scan C++ source files for module dependencies.
|
||||||
|
|
||||||
|
This variable is used to initialize the :prop_tgt:`CXX_SCAN_FOR_MODULES`
|
||||||
|
property on all the targets. See that target property for additional
|
||||||
|
information.
|
||||||
@@ -109,12 +109,13 @@ cmGlobalNinjaGenerator* cmNinjaTargetGenerator::GetGlobalGenerator() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string cmNinjaTargetGenerator::LanguageCompilerRule(
|
std::string cmNinjaTargetGenerator::LanguageCompilerRule(
|
||||||
const std::string& lang, const std::string& config) const
|
const std::string& lang, const std::string& config,
|
||||||
|
WithScanning withScanning) const
|
||||||
{
|
{
|
||||||
return cmStrCat(
|
return cmStrCat(
|
||||||
lang, "_COMPILER__",
|
lang, "_COMPILER__",
|
||||||
cmGlobalNinjaGenerator::EncodeRuleName(this->GeneratorTarget->GetName()),
|
cmGlobalNinjaGenerator::EncodeRuleName(this->GeneratorTarget->GetName()),
|
||||||
'_', config);
|
withScanning == WithScanning::Yes ? "_scanned_" : "_unscanned_", config);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string cmNinjaTargetGenerator::LanguagePreprocessAndScanRule(
|
std::string cmNinjaTargetGenerator::LanguagePreprocessAndScanRule(
|
||||||
@@ -231,6 +232,32 @@ cmFileSet const* cmNinjaTargetGenerator::GetFileSetForSource(
|
|||||||
return fsit->second;
|
return fsit->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool cmNinjaTargetGenerator::NeedDyndepForSource(std::string const& lang,
|
||||||
|
std::string const& config,
|
||||||
|
cmSourceFile const* sf)
|
||||||
|
{
|
||||||
|
bool const needDyndep = this->NeedDyndep(lang, config);
|
||||||
|
if (!needDyndep) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
auto const* fs = this->GetFileSetForSource(config, sf);
|
||||||
|
if (fs &&
|
||||||
|
(fs->GetType() == "CXX_MODULES"_s ||
|
||||||
|
fs->GetType() == "CXX_MODULE_HEADER_UNITS"_s)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
auto const sfProp = sf->GetProperty("CXX_SCAN_FOR_MODULES");
|
||||||
|
if (sfProp.IsSet()) {
|
||||||
|
return sfProp.IsOn();
|
||||||
|
}
|
||||||
|
auto const tgtProp =
|
||||||
|
this->GeneratorTarget->GetProperty("CXX_SCAN_FOR_MODULES");
|
||||||
|
if (tgtProp.IsSet()) {
|
||||||
|
return tgtProp.IsOn();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
std::string cmNinjaTargetGenerator::OrderDependsTargetForTarget(
|
std::string cmNinjaTargetGenerator::OrderDependsTargetForTarget(
|
||||||
const std::string& config)
|
const std::string& config)
|
||||||
{
|
{
|
||||||
@@ -670,6 +697,19 @@ cmNinjaRule GetScanRule(
|
|||||||
|
|
||||||
void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
|
void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
|
||||||
const std::string& config)
|
const std::string& config)
|
||||||
|
{
|
||||||
|
// For some cases we scan to dynamically discover dependencies.
|
||||||
|
bool const needDyndep = this->NeedDyndep(lang, config);
|
||||||
|
|
||||||
|
if (needDyndep) {
|
||||||
|
this->WriteCompileRule(lang, config, WithScanning::Yes);
|
||||||
|
}
|
||||||
|
this->WriteCompileRule(lang, config, WithScanning::No);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
|
||||||
|
const std::string& config,
|
||||||
|
WithScanning withScanning)
|
||||||
{
|
{
|
||||||
cmRulePlaceholderExpander::RuleVariables vars;
|
cmRulePlaceholderExpander::RuleVariables vars;
|
||||||
vars.CMTargetName = this->GetGeneratorTarget()->GetName().c_str();
|
vars.CMTargetName = this->GetGeneratorTarget()->GetName().c_str();
|
||||||
@@ -690,7 +730,6 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
|
|||||||
cmMakefile* mf = this->GetMakefile();
|
cmMakefile* mf = this->GetMakefile();
|
||||||
|
|
||||||
// For some cases we scan to dynamically discover dependencies.
|
// For some cases we scan to dynamically discover dependencies.
|
||||||
bool const needDyndep = this->NeedDyndep(lang, config);
|
|
||||||
bool const compilationPreprocesses = !this->NeedExplicitPreprocessing(lang);
|
bool const compilationPreprocesses = !this->NeedExplicitPreprocessing(lang);
|
||||||
|
|
||||||
std::string flags = "$FLAGS";
|
std::string flags = "$FLAGS";
|
||||||
@@ -728,7 +767,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
|
|||||||
this->GetLocalGenerator()->ConvertToOutputFormat(
|
this->GetLocalGenerator()->ConvertToOutputFormat(
|
||||||
cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL);
|
cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL);
|
||||||
|
|
||||||
if (needDyndep) {
|
if (withScanning == WithScanning::Yes) {
|
||||||
const auto& scanDepType = this->GetMakefile()->GetSafeDefinition(
|
const auto& scanDepType = this->GetMakefile()->GetSafeDefinition(
|
||||||
cmStrCat("CMAKE_EXPERIMENTAL_", lang, "_SCANDEP_DEPFILE_FORMAT"));
|
cmStrCat("CMAKE_EXPERIMENTAL_", lang, "_SCANDEP_DEPFILE_FORMAT"));
|
||||||
|
|
||||||
@@ -834,7 +873,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
|
|||||||
this->GetGlobalGenerator()->AddRule(rule);
|
this->GetGlobalGenerator()->AddRule(rule);
|
||||||
}
|
}
|
||||||
|
|
||||||
cmNinjaRule rule(this->LanguageCompilerRule(lang, config));
|
cmNinjaRule rule(this->LanguageCompilerRule(lang, config, withScanning));
|
||||||
// If using a response file, move defines, includes, and flags into it.
|
// If using a response file, move defines, includes, and flags into it.
|
||||||
if (!responseFlag.empty()) {
|
if (!responseFlag.empty()) {
|
||||||
rule.RspFile = "$RSP_FILE";
|
rule.RspFile = "$RSP_FILE";
|
||||||
@@ -888,7 +927,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (needDyndep && !modmapFormat.empty()) {
|
if (withScanning == WithScanning::Yes && !modmapFormat.empty()) {
|
||||||
std::string modmapFlags = mf->GetRequiredDefinition(
|
std::string modmapFlags = mf->GetRequiredDefinition(
|
||||||
cmStrCat("CMAKE_EXPERIMENTAL_", lang, "_MODULE_MAP_FLAG"));
|
cmStrCat("CMAKE_EXPERIMENTAL_", lang, "_MODULE_MAP_FLAG"));
|
||||||
cmSystemTools::ReplaceString(modmapFlags, "<MODULE_MAP_FILE>",
|
cmSystemTools::ReplaceString(modmapFlags, "<MODULE_MAP_FILE>",
|
||||||
@@ -1348,8 +1387,10 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
|
|||||||
!(language == "RC" || (language == "CUDA" && !flag));
|
!(language == "RC" || (language == "CUDA" && !flag));
|
||||||
int const commandLineLengthLimit =
|
int const commandLineLengthLimit =
|
||||||
((lang_supports_response && this->ForceResponseFile())) ? -1 : 0;
|
((lang_supports_response && this->ForceResponseFile())) ? -1 : 0;
|
||||||
|
bool const needDyndep = this->NeedDyndepForSource(language, config, source);
|
||||||
|
|
||||||
cmNinjaBuild objBuild(this->LanguageCompilerRule(language, config));
|
cmNinjaBuild objBuild(this->LanguageCompilerRule(
|
||||||
|
language, config, needDyndep ? WithScanning::Yes : WithScanning::No));
|
||||||
cmNinjaVars& vars = objBuild.Variables;
|
cmNinjaVars& vars = objBuild.Variables;
|
||||||
vars["FLAGS"] = this->ComputeFlagsForObject(source, language, config);
|
vars["FLAGS"] = this->ComputeFlagsForObject(source, language, config);
|
||||||
vars["DEFINES"] = this->ComputeDefines(source, language, config);
|
vars["DEFINES"] = this->ComputeDefines(source, language, config);
|
||||||
@@ -1458,7 +1499,6 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// For some cases we scan to dynamically discover dependencies.
|
// For some cases we scan to dynamically discover dependencies.
|
||||||
bool const needDyndep = this->NeedDyndep(language, config);
|
|
||||||
bool const compilationPreprocesses =
|
bool const compilationPreprocesses =
|
||||||
!this->NeedExplicitPreprocessing(language);
|
!this->NeedExplicitPreprocessing(language);
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
#include "cmOSXBundleGenerator.h"
|
#include "cmOSXBundleGenerator.h"
|
||||||
|
|
||||||
class cmCustomCommand;
|
class cmCustomCommand;
|
||||||
|
class cmFileSet;
|
||||||
class cmGeneratedFileStream;
|
class cmGeneratedFileStream;
|
||||||
class cmGeneratorTarget;
|
class cmGeneratorTarget;
|
||||||
class cmLocalNinjaGenerator;
|
class cmLocalNinjaGenerator;
|
||||||
@@ -67,8 +68,14 @@ protected:
|
|||||||
cmFileSet const* GetFileSetForSource(std::string const& config,
|
cmFileSet const* GetFileSetForSource(std::string const& config,
|
||||||
cmSourceFile const* sf);
|
cmSourceFile const* sf);
|
||||||
|
|
||||||
|
enum class WithScanning
|
||||||
|
{
|
||||||
|
No,
|
||||||
|
Yes,
|
||||||
|
};
|
||||||
std::string LanguageCompilerRule(const std::string& lang,
|
std::string LanguageCompilerRule(const std::string& lang,
|
||||||
const std::string& config) const;
|
const std::string& config,
|
||||||
|
WithScanning withScanning) const;
|
||||||
std::string LanguagePreprocessAndScanRule(std::string const& lang,
|
std::string LanguagePreprocessAndScanRule(std::string const& lang,
|
||||||
const std::string& config) const;
|
const std::string& config) const;
|
||||||
std::string LanguageScanRule(std::string const& lang,
|
std::string LanguageScanRule(std::string const& lang,
|
||||||
@@ -76,6 +83,8 @@ protected:
|
|||||||
std::string LanguageDyndepRule(std::string const& lang,
|
std::string LanguageDyndepRule(std::string const& lang,
|
||||||
const std::string& config) const;
|
const std::string& config) const;
|
||||||
bool NeedDyndep(std::string const& lang, std::string const& config) const;
|
bool NeedDyndep(std::string const& lang, std::string const& config) const;
|
||||||
|
bool NeedDyndepForSource(std::string const& lang, std::string const& config,
|
||||||
|
cmSourceFile const* sf);
|
||||||
bool NeedExplicitPreprocessing(std::string const& lang) const;
|
bool NeedExplicitPreprocessing(std::string const& lang) const;
|
||||||
bool CompileWithDefines(std::string const& lang) const;
|
bool CompileWithDefines(std::string const& lang) const;
|
||||||
bool NeedCxxModuleSupport(std::string const& lang,
|
bool NeedCxxModuleSupport(std::string const& lang,
|
||||||
@@ -154,6 +163,8 @@ protected:
|
|||||||
const std::string& config);
|
const std::string& config);
|
||||||
void WriteCompileRule(const std::string& language,
|
void WriteCompileRule(const std::string& language,
|
||||||
const std::string& config);
|
const std::string& config);
|
||||||
|
void WriteCompileRule(const std::string& language, const std::string& config,
|
||||||
|
WithScanning withScanning);
|
||||||
void WriteObjectBuildStatements(const std::string& config,
|
void WriteObjectBuildStatements(const std::string& config,
|
||||||
const std::string& fileConfig,
|
const std::string& fileConfig,
|
||||||
bool firstForConfig);
|
bool firstForConfig);
|
||||||
|
|||||||
@@ -526,6 +526,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
|
|||||||
initProp("ANDROID_ANT_ADDITIONAL_OPTIONS");
|
initProp("ANDROID_ANT_ADDITIONAL_OPTIONS");
|
||||||
initProp("BUILD_RPATH");
|
initProp("BUILD_RPATH");
|
||||||
initProp("BUILD_RPATH_USE_ORIGIN");
|
initProp("BUILD_RPATH_USE_ORIGIN");
|
||||||
|
initProp("CXX_SCAN_FOR_MODULES");
|
||||||
initProp("INSTALL_NAME_DIR");
|
initProp("INSTALL_NAME_DIR");
|
||||||
initProp("INSTALL_REMOVE_ENVIRONMENT_RPATH");
|
initProp("INSTALL_REMOVE_ENVIRONMENT_RPATH");
|
||||||
initPropValue("INSTALL_RPATH", "");
|
initPropValue("INSTALL_RPATH", "");
|
||||||
|
|||||||
@@ -138,6 +138,7 @@ if ("named" IN_LIST CMake_TEST_MODULE_COMPILATION)
|
|||||||
set(RunCMake_CXXModules_NO_TEST 1)
|
set(RunCMake_CXXModules_NO_TEST 1)
|
||||||
run_cxx_module_test(circular)
|
run_cxx_module_test(circular)
|
||||||
unset(RunCMake_CXXModules_NO_TEST)
|
unset(RunCMake_CXXModules_NO_TEST)
|
||||||
|
run_cxx_module_test(scan_properties)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
# Tests which use named modules in shared libraries.
|
# Tests which use named modules in shared libraries.
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
CMake Warning \(dev\) at CMakeLists.txt:20 \(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,54 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.24)
|
||||||
|
project(scan_properties CXX)
|
||||||
|
|
||||||
|
include("${CMAKE_SOURCE_DIR}/../cxx-modules-rules.cmake")
|
||||||
|
|
||||||
|
# To detect that not-to-be scanned sources are not scanned, add a `-D` to the
|
||||||
|
# scan flags so that the files can detect whether scanning happened and error
|
||||||
|
# if not.
|
||||||
|
string(APPEND CMAKE_EXPERIMENTAL_CXX_MODULE_MAP_FLAG
|
||||||
|
" -DCMAKE_SCANNED_THIS_SOURCE")
|
||||||
|
string(APPEND CMAKE_EXPERIMENTAL_CXX_SCANDEP_SOURCE
|
||||||
|
" -DCMAKE_SCANNED_THIS_SOURCE")
|
||||||
|
|
||||||
|
set_property(SOURCE always_scan.cxx
|
||||||
|
PROPERTY CXX_SCAN_FOR_MODULES 1)
|
||||||
|
set_property(SOURCE never_scan.cxx
|
||||||
|
PROPERTY CXX_SCAN_FOR_MODULES 0)
|
||||||
|
|
||||||
|
add_executable(scans_everything)
|
||||||
|
target_sources(scans_everything
|
||||||
|
PRIVATE
|
||||||
|
main.cxx
|
||||||
|
join.cxx
|
||||||
|
always_scan.cxx
|
||||||
|
never_scan.cxx
|
||||||
|
PRIVATE
|
||||||
|
FILE_SET CXX_MODULES
|
||||||
|
BASE_DIRS
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}"
|
||||||
|
FILES
|
||||||
|
module.cxx)
|
||||||
|
target_compile_features(scans_everything PRIVATE cxx_std_20)
|
||||||
|
target_compile_definitions(scans_everything PRIVATE SCAN_AT_TARGET_LEVEL=1)
|
||||||
|
|
||||||
|
set(CMAKE_CXX_SCAN_FOR_MODULES 0)
|
||||||
|
|
||||||
|
add_executable(no_scan_everything)
|
||||||
|
target_sources(no_scan_everything
|
||||||
|
PRIVATE
|
||||||
|
main.cxx
|
||||||
|
join.cxx
|
||||||
|
always_scan.cxx
|
||||||
|
never_scan.cxx
|
||||||
|
PRIVATE
|
||||||
|
FILE_SET CXX_MODULES
|
||||||
|
BASE_DIRS
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}"
|
||||||
|
FILES
|
||||||
|
module.cxx)
|
||||||
|
target_compile_features(no_scan_everything PRIVATE cxx_std_20)
|
||||||
|
target_compile_definitions(no_scan_everything PRIVATE SCAN_AT_TARGET_LEVEL=0)
|
||||||
|
|
||||||
|
add_test(NAME scanned COMMAND scans_everything)
|
||||||
|
add_test(NAME unscanned COMMAND no_scan_everything)
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
#ifndef CMAKE_SCANNED_THIS_SOURCE
|
||||||
|
# error "This file should have been scanned"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
import M;
|
||||||
|
|
||||||
|
int scanned_file()
|
||||||
|
{
|
||||||
|
return from_module();
|
||||||
|
}
|
||||||
17
Tests/RunCMake/CXXModules/examples/scan_properties/join.cxx
Normal file
17
Tests/RunCMake/CXXModules/examples/scan_properties/join.cxx
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
#if SCAN_AT_TARGET_LEVEL
|
||||||
|
# ifndef CMAKE_SCANNED_THIS_SOURCE
|
||||||
|
# error "This file should have been scanned"
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
# ifdef CMAKE_SCANNED_THIS_SOURCE
|
||||||
|
# error "This file should not have been scanned"
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int scanned_file();
|
||||||
|
int never_scan();
|
||||||
|
|
||||||
|
int join()
|
||||||
|
{
|
||||||
|
return scanned_file() + never_scan();
|
||||||
|
}
|
||||||
16
Tests/RunCMake/CXXModules/examples/scan_properties/main.cxx
Normal file
16
Tests/RunCMake/CXXModules/examples/scan_properties/main.cxx
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
#if SCAN_AT_TARGET_LEVEL
|
||||||
|
# ifndef CMAKE_SCANNED_THIS_SOURCE
|
||||||
|
# error "This file should have been scanned"
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
# ifdef CMAKE_SCANNED_THIS_SOURCE
|
||||||
|
# error "This file should not have been scanned"
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int join();
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
return join();
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
#ifndef CMAKE_SCANNED_THIS_SOURCE
|
||||||
|
# error "This file should have been scanned"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
export module M;
|
||||||
|
|
||||||
|
export int from_module()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
#ifdef CMAKE_SCANNED_THIS_SOURCE
|
||||||
|
# error "This file should not have been scanned"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int never_scan()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user