summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2020-09-01 13:15:29 (GMT)
committerKitware Robot <kwrobot@kitware.com>2020-09-01 13:15:39 (GMT)
commitf10682b7961c2ad56384641ab141a66f34923753 (patch)
tree4bf3b7b721dd33b6934faf6c119770bf04209891 /Source
parentcd2f894052ea8191e21ec4997b2181c75f637ae9 (diff)
parent5ece12b7e452acb091300022a392ff71dfce9504 (diff)
downloadCMake-f10682b7961c2ad56384641ab141a66f34923753.zip
CMake-f10682b7961c2ad56384641ab141a66f34923753.tar.gz
CMake-f10682b7961c2ad56384641ab141a66f34923753.tar.bz2
Merge topic 'ispc_lang_support'
5ece12b7e4 gitlab-ci: add ISPC to the Fedora CI image 8976817d6d ISPC: Update help documentation to include ISPC 2368f46ba4 ISPC: Support building with the MSVC toolchain e783bf8aa6 ISPC: Support ISPC header generation byproducts and parallel builds 34cc6acc81 Add ISPC compiler support to CMake 419d70d490 Refactor some swift only logic to be re-used by other languages Acked-by: Kitware Robot <kwrobot@kitware.com> Merge-request: !5065
Diffstat (limited to 'Source')
-rw-r--r--Source/cmCoreTryCompile.cxx12
-rw-r--r--Source/cmGeneratorExpressionNode.cxx5
-rw-r--r--Source/cmGeneratorTarget.cxx122
-rw-r--r--Source/cmGeneratorTarget.h8
-rw-r--r--Source/cmGlobalGenerator.cxx1
-rw-r--r--Source/cmGlobalNinjaGenerator.cxx42
-rw-r--r--Source/cmGlobalNinjaGenerator.h6
-rw-r--r--Source/cmLocalGenerator.cxx32
-rw-r--r--Source/cmLocalGenerator.h1
-rw-r--r--Source/cmLocalUnixMakefileGenerator3.cxx6
-rw-r--r--Source/cmMakefileTargetGenerator.cxx39
-rw-r--r--Source/cmNinjaTargetGenerator.cxx37
-rw-r--r--Source/cmRulePlaceholderExpander.cxx5
-rw-r--r--Source/cmRulePlaceholderExpander.h1
-rw-r--r--Source/cmTarget.cxx1
-rw-r--r--Source/cmake.cxx3
-rw-r--r--Source/cmake.h4
17 files changed, 290 insertions, 35 deletions
diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx
index 63c1484..b9b91f6 100644
--- a/Source/cmCoreTryCompile.cxx
+++ b/Source/cmCoreTryCompile.cxx
@@ -192,6 +192,8 @@ SETUP_LANGUAGE(objc_properties, OBJC);
// NOLINTNEXTLINE(bugprone-suspicious-missing-comma)
SETUP_LANGUAGE(objcxx_properties, OBJCXX);
// NOLINTNEXTLINE(bugprone-suspicious-missing-comma)
+SETUP_LANGUAGE(ispc_properties, ISPC);
+// NOLINTNEXTLINE(bugprone-suspicious-missing-comma)
SETUP_LANGUAGE(swift_properties, Swift);
#undef SETUP_LANGUAGE
@@ -499,6 +501,12 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
}
}
+ // when the only language is ISPC we know that the output
+ // type must by a static library
+ if (testLangs.size() == 1 && testLangs.count("ISPC") == 1) {
+ targetType = cmStateEnums::STATIC_LIBRARY;
+ }
+
std::string const tcConfig =
this->Makefile->GetSafeDefinition("CMAKE_TRY_COMPILE_CONFIGURATION");
@@ -702,6 +710,8 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
vars.insert(
&objcxx_properties[lang_property_start],
&objcxx_properties[lang_property_start + lang_property_size]);
+ vars.insert(&ispc_properties[lang_property_start],
+ &ispc_properties[lang_property_start + lang_property_size]);
vars.insert(&swift_properties[lang_property_start],
&swift_properties[lang_property_start + lang_property_size]);
vars.insert(kCMAKE_CUDA_ARCHITECTURES);
@@ -744,6 +754,8 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
vars.insert(
&objcxx_properties[pie_property_start],
&objcxx_properties[pie_property_start + pie_property_size]);
+ vars.insert(&ispc_properties[pie_property_start],
+ &ispc_properties[pie_property_start + pie_property_size]);
vars.insert(&swift_properties[pie_property_start],
&swift_properties[pie_property_start + pie_property_size]);
}
diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx
index fdc8f29..83e9aac 100644
--- a/Source/cmGeneratorExpressionNode.cxx
+++ b/Source/cmGeneratorExpressionNode.cxx
@@ -715,7 +715,8 @@ struct CompilerIdNode : public cmGeneratorExpressionNode
static const CompilerIdNode cCompilerIdNode("C"), cxxCompilerIdNode("CXX"),
cudaCompilerIdNode("CUDA"), objcCompilerIdNode("OBJC"),
- objcxxCompilerIdNode("OBJCXX"), fortranCompilerIdNode("Fortran");
+ objcxxCompilerIdNode("OBJCXX"), fortranCompilerIdNode("Fortran"),
+ ispcCompilerIdNode("ISPC");
struct CompilerVersionNode : public cmGeneratorExpressionNode
{
@@ -780,7 +781,7 @@ struct CompilerVersionNode : public cmGeneratorExpressionNode
static const CompilerVersionNode cCompilerVersionNode("C"),
cxxCompilerVersionNode("CXX"), cudaCompilerVersionNode("CUDA"),
objcCompilerVersionNode("OBJC"), objcxxCompilerVersionNode("OBJCXX"),
- fortranCompilerVersionNode("Fortran");
+ fortranCompilerVersionNode("Fortran"), ispcCompilerVersionNode("ISPC");
struct PlatformIdNode : public cmGeneratorExpressionNode
{
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 7c526a0..dc5265f 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -1363,18 +1363,25 @@ std::string cmGeneratorTarget::EvaluateInterfaceProperty(
}
namespace {
-std::string AddSwiftInterfaceIncludeDirectories(
+
+enum class IncludeDirectoryFallBack
+{
+ BINARY,
+ OBJECT
+};
+
+std::string AddLangSpecificInterfaceIncludeDirectories(
const cmGeneratorTarget* root, const cmGeneratorTarget* target,
- const std::string& config, cmGeneratorExpressionDAGChecker* context)
+ const std::string& lang, const std::string& config,
+ const std::string& propertyName, IncludeDirectoryFallBack mode,
+ cmGeneratorExpressionDAGChecker* context)
{
cmGeneratorExpressionDAGChecker dag{ target->GetBacktrace(), target,
- "Swift_MODULE_DIRECTORY", nullptr,
- context };
+ propertyName, nullptr, context };
switch (dag.Check()) {
case cmGeneratorExpressionDAGChecker::SELF_REFERENCE:
- dag.ReportError(nullptr,
- "$<TARGET_PROPERTY:" + target->GetName() +
- ",Swift_MODULE_DIRECTORY>");
+ dag.ReportError(
+ nullptr, "$<TARGET_PROPERTY:" + target->GetName() + ",propertyName");
CM_FALLTHROUGH;
case cmGeneratorExpressionDAGChecker::CYCLIC_REFERENCE:
// No error. We just skip cyclic references.
@@ -1390,13 +1397,16 @@ std::string AddSwiftInterfaceIncludeDirectories(
target->GetLinkInterfaceLibraries(config, root, true)) {
for (const cmLinkItem& library : interface->Libraries) {
if (const cmGeneratorTarget* dependency = library.Target) {
- if (cm::contains(dependency->GetAllConfigCompileLanguages(),
- "Swift")) {
- std::string value =
- dependency->GetSafeProperty("Swift_MODULE_DIRECTORY");
+ if (cm::contains(dependency->GetAllConfigCompileLanguages(), lang)) {
+ auto* lg = dependency->GetLocalGenerator();
+ std::string value = dependency->GetSafeProperty(propertyName);
if (value.empty()) {
- value =
- dependency->GetLocalGenerator()->GetCurrentBinaryDirectory();
+ if (mode == IncludeDirectoryFallBack::BINARY) {
+ value = lg->GetCurrentBinaryDirectory();
+ } else if (mode == IncludeDirectoryFallBack::OBJECT) {
+ value = cmStrCat(lg->GetCurrentBinaryDirectory(), '/',
+ lg->GetTargetDirectory(dependency));
+ }
}
if (!directories.empty()) {
@@ -1410,35 +1420,39 @@ std::string AddSwiftInterfaceIncludeDirectories(
return directories;
}
-void AddSwiftImplicitIncludeDirectories(
- const cmGeneratorTarget* target, const std::string& config,
- EvaluatedTargetPropertyEntries& entries)
+void AddLangSpecificImplicitIncludeDirectories(
+ const cmGeneratorTarget* target, const std::string& lang,
+ const std::string& config, const std::string& propertyName,
+ IncludeDirectoryFallBack mode, EvaluatedTargetPropertyEntries& entries)
{
if (const auto* libraries = target->GetLinkImplementationLibraries(config)) {
cmGeneratorExpressionDAGChecker dag{ target->GetBacktrace(), target,
- "Swift_MODULE_DIRECTORY", nullptr,
- nullptr };
+ propertyName, nullptr, nullptr };
for (const cmLinkImplItem& library : libraries->Libraries) {
if (const cmGeneratorTarget* dependency = library.Target) {
if (!dependency->IsInBuildSystem()) {
continue;
}
- if (cm::contains(dependency->GetAllConfigCompileLanguages(),
- "Swift")) {
+ if (cm::contains(dependency->GetAllConfigCompileLanguages(), lang)) {
+ auto* lg = dependency->GetLocalGenerator();
EvaluatedTargetPropertyEntry entry{ library, library.Backtrace };
- if (cmProp val = dependency->GetProperty("Swift_MODULE_DIRECTORY")) {
+ if (cmProp val = dependency->GetProperty(propertyName)) {
entry.Values.emplace_back(*val);
} else {
- entry.Values.emplace_back(
- dependency->GetLocalGenerator()->GetCurrentBinaryDirectory());
+ if (mode == IncludeDirectoryFallBack::BINARY) {
+ entry.Values.emplace_back(lg->GetCurrentBinaryDirectory());
+ } else if (mode == IncludeDirectoryFallBack::OBJECT) {
+ entry.Values.emplace_back(
+ dependency->GetObjectDirectory(config));
+ }
}
- cmExpandList(AddSwiftInterfaceIncludeDirectories(target, dependency,
- config, &dag),
- entry.Values);
-
+ cmExpandList(
+ AddLangSpecificInterfaceIncludeDirectories(
+ target, dependency, lang, config, propertyName, mode, &dag),
+ entry.Values);
entries.Entries.emplace_back(std::move(entry));
}
}
@@ -3482,7 +3496,28 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetIncludeDirectories(
this, config, lang, &dagChecker, this->IncludeDirectoriesEntries);
if (lang == "Swift") {
- AddSwiftImplicitIncludeDirectories(this, config, entries);
+ AddLangSpecificImplicitIncludeDirectories(
+ this, lang, config, "Swift_MODULE_DIRECTORY",
+ IncludeDirectoryFallBack::BINARY, entries);
+ }
+
+ if (this->CanCompileSources() && (lang != "Swift" && lang != "Fortran")) {
+
+ const std::string propertyName = "ISPC_HEADER_DIRECTORY";
+
+ // If this target has ISPC sources make sure to add the header
+ // directory to other compilation units
+ if (cm::contains(this->GetAllConfigCompileLanguages(), "ISPC")) {
+ if (cmProp val = this->GetProperty(propertyName)) {
+ includes.emplace_back(*val);
+ } else {
+ includes.emplace_back(this->GetObjectDirectory(config));
+ }
+ }
+
+ AddLangSpecificImplicitIncludeDirectories(
+ this, "ISPC", config, propertyName, IncludeDirectoryFallBack::OBJECT,
+ entries);
}
AddInterfaceEntries(this, config, "INTERFACE_INCLUDE_DIRECTORIES", lang,
@@ -5976,6 +6011,37 @@ std::string cmGeneratorTarget::CreateFortranModuleDirectory(
return mod_dir;
}
+void cmGeneratorTarget::AddISPCGeneratedHeader(std::string const& header,
+ std::string const& config)
+{
+ std::string config_upper;
+ if (!config.empty()) {
+ config_upper = cmSystemTools::UpperCase(config);
+ }
+ auto iter = this->ISPCGeneratedHeaders.find(config_upper);
+ if (iter == this->ISPCGeneratedHeaders.end()) {
+ std::vector<std::string> headers;
+ headers.emplace_back(header);
+ this->ISPCGeneratedHeaders.insert({ config_upper, headers });
+ } else {
+ iter->second.emplace_back(header);
+ }
+}
+
+std::vector<std::string> cmGeneratorTarget::GetGeneratedISPCHeaders(
+ std::string const& config) const
+{
+ std::string config_upper;
+ if (!config.empty()) {
+ config_upper = cmSystemTools::UpperCase(config);
+ }
+ auto iter = this->ISPCGeneratedHeaders.find(config_upper);
+ if (iter == this->ISPCGeneratedHeaders.end()) {
+ return std::vector<std::string>{};
+ }
+ return iter->second;
+}
+
std::string cmGeneratorTarget::GetFrameworkVersion() const
{
assert(this->GetType() != cmStateEnums::INTERFACE_LIBRARY);
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index 544b27a..246eede 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -816,6 +816,11 @@ public:
const std::string& GetSourcesProperty() const;
+ void AddISPCGeneratedHeader(std::string const& header,
+ std::string const& config);
+ std::vector<std::string> GetGeneratedISPCHeaders(
+ std::string const& config) const;
+
private:
void AddSourceCommon(const std::string& src, bool before = false);
@@ -994,6 +999,9 @@ private:
std::unordered_set<std::string> UnityBatchedSourceFiles;
+ std::unordered_map<std::string, std::vector<std::string>>
+ ISPCGeneratedHeaders;
+
bool IsLinkLookupScope(std::string const& n,
cmLocalGenerator const*& lg) const;
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index a192ffd..a550b50 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -1601,6 +1601,7 @@ bool cmGlobalGenerator::AddAutomaticSources()
continue;
}
lg->AddUnityBuild(gt.get());
+ lg->AddISPCDependencies(gt.get());
// Targets that re-use a PCH are handled below.
if (!gt->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM")) {
lg->AddPchDependencies(gt.get());
diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx
index f0fa1f4..ed61021 100644
--- a/Source/cmGlobalNinjaGenerator.cxx
+++ b/Source/cmGlobalNinjaGenerator.cxx
@@ -680,6 +680,9 @@ void cmGlobalNinjaGenerator::CheckNinjaFeatures()
this->NinjaSupportsRestatTool = !cmSystemTools::VersionCompare(
cmSystemTools::OP_LESS, this->NinjaVersion.c_str(),
RequiredNinjaVersionForRestatTool().c_str());
+ this->NinjaSupportsMultipleOutputs = !cmSystemTools::VersionCompare(
+ cmSystemTools::OP_LESS, this->NinjaVersion.c_str(),
+ RequiredNinjaVersionForMultipleOutputs().c_str());
}
bool cmGlobalNinjaGenerator::CheckLanguages(
@@ -688,6 +691,9 @@ bool cmGlobalNinjaGenerator::CheckLanguages(
if (cm::contains(languages, "Fortran")) {
return this->CheckFortran(mf);
}
+ if (cm::contains(languages, "ISPC")) {
+ return this->CheckISPC(mf);
+ }
if (cm::contains(languages, "Swift")) {
const std::string architectures =
mf->GetSafeDefinition("CMAKE_OSX_ARCHITECTURES");
@@ -721,6 +727,25 @@ bool cmGlobalNinjaGenerator::CheckFortran(cmMakefile* mf) const
return false;
}
+bool cmGlobalNinjaGenerator::CheckISPC(cmMakefile* mf) const
+{
+ if (this->NinjaSupportsMultipleOutputs) {
+ return true;
+ }
+
+ std::ostringstream e;
+ /* clang-format off */
+ e <<
+ "The Ninja generator does not support ISPC using Ninja version\n"
+ " " << this->NinjaVersion << "\n"
+ "due to lack of required features. Ninja 1.10 or higher is required."
+ ;
+ /* clang-format on */
+ mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ cmSystemTools::SetFatalErrorOccured();
+ return false;
+}
+
void cmGlobalNinjaGenerator::EnableLanguage(
std::vector<std::string> const& langs, cmMakefile* mf, bool optional)
{
@@ -1127,6 +1152,21 @@ void cmGlobalNinjaGenerator::AppendTargetDepends(
}
} else {
cmNinjaDeps outs;
+
+ auto computeISPCOuputs = [](cmGlobalNinjaGenerator* gg,
+ cmGeneratorTarget const* depTarget,
+ cmNinjaDeps& outputDeps,
+ const std::string& targetConfig) {
+ if (depTarget->CanCompileSources()) {
+ auto headers = depTarget->GetGeneratedISPCHeaders(targetConfig);
+ if (!headers.empty()) {
+ std::transform(headers.begin(), headers.end(), headers.begin(),
+ gg->MapToNinjaPath());
+ outputDeps.insert(outputDeps.end(), headers.begin(), headers.end());
+ }
+ }
+ };
+
for (cmTargetDepend const& targetDep :
this->GetTargetDirectDepends(target)) {
if (!targetDep->IsInBuildSystem()) {
@@ -1134,8 +1174,10 @@ void cmGlobalNinjaGenerator::AppendTargetDepends(
}
if (targetDep.IsCross()) {
this->AppendTargetOutputs(targetDep, outs, fileConfig, depends);
+ computeISPCOuputs(this, targetDep, outs, fileConfig);
} else {
this->AppendTargetOutputs(targetDep, outs, config, depends);
+ computeISPCOuputs(this, targetDep, outs, config);
}
}
std::sort(outs.begin(), outs.end());
diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h
index 10f5cf6..0881ce0 100644
--- a/Source/cmGlobalNinjaGenerator.h
+++ b/Source/cmGlobalNinjaGenerator.h
@@ -370,6 +370,10 @@ public:
return "1.10";
}
static std::string RequiredNinjaVersionForCleanDeadTool() { return "1.10"; }
+ static std::string RequiredNinjaVersionForMultipleOutputs()
+ {
+ return "1.10";
+ }
bool SupportsConsolePool() const;
bool SupportsImplicitOuts() const;
bool SupportsManifestRestat() const;
@@ -447,6 +451,7 @@ private:
bool CheckLanguages(std::vector<std::string> const& languages,
cmMakefile* mf) const override;
bool CheckFortran(cmMakefile* mf) const;
+ bool CheckISPC(cmMakefile* mf) const;
void CloseCompileCommandsStream();
@@ -533,6 +538,7 @@ private:
bool NinjaSupportsRestatTool = false;
bool NinjaSupportsUnconditionalRecompactTool = false;
bool NinjaSupportsCleanDeadTool = false;
+ bool NinjaSupportsMultipleOutputs = false;
private:
void InitOutputPathPrefix();
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index 40010fc..300bb26 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -2426,6 +2426,38 @@ void cmLocalGenerator::AppendFlagEscape(std::string& flags,
this->EscapeForShell(rawFlag, false, false, false, this->IsNinjaMulti()));
}
+void cmLocalGenerator::AddISPCDependencies(cmGeneratorTarget* target)
+{
+ //
+ std::vector<std::string> configsList =
+ this->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
+ for (std::string const& config : configsList) {
+
+ std::string perConfigDir = target->GetObjectDirectory(config);
+ if (cmProp prop = target->GetProperty("ISPC_HEADER_DIRECTORY")) {
+ perConfigDir = cmSystemTools::CollapseFullPath(
+ cmStrCat(this->GetBinaryDirectory(), '/', *prop));
+ }
+
+ std::vector<cmSourceFile*> sources;
+ target->GetSourceFiles(sources, config);
+
+ // build up the list of ispc headers that this target is generating
+ for (cmSourceFile const* sf : sources) {
+ // Generate this object file's rule file.
+ const std::string& lang = sf->GetLanguage();
+ if (lang == "ISPC") {
+ std::string const& objectName = target->GetObjectName(sf);
+ std::string ispcSource =
+ cmSystemTools::GetFilenameWithoutLastExtension(objectName);
+
+ auto headerPath = cmStrCat(perConfigDir, '/', ispcSource, ".h");
+ target->AddISPCGeneratedHeader(headerPath, config);
+ }
+ }
+ }
+}
+
void cmLocalGenerator::AddPchDependencies(cmGeneratorTarget* target)
{
std::vector<std::string> configsList =
diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h
index 0c51a65..cf2bce1 100644
--- a/Source/cmLocalGenerator.h
+++ b/Source/cmLocalGenerator.h
@@ -133,6 +133,7 @@ public:
const std::vector<BT<std::string>>& newFlags) const;
virtual void AppendFlagEscape(std::string& flags,
const std::string& rawFlag) const;
+ void AddISPCDependencies(cmGeneratorTarget* target);
void AddPchDependencies(cmGeneratorTarget* target);
void AddUnityBuild(cmGeneratorTarget* target);
void AppendIPOLinkerFlags(std::string& flags, cmGeneratorTarget* target,
diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx
index 8acd1e3..26b0989 100644
--- a/Source/cmLocalUnixMakefileGenerator3.cxx
+++ b/Source/cmLocalUnixMakefileGenerator3.cxx
@@ -235,7 +235,8 @@ void cmLocalUnixMakefileGenerator3::WriteLocalMakefile()
for (LocalObjectEntry const& entry : localObjectFile.second) {
if (entry.Language == "C" || entry.Language == "CXX" ||
- entry.Language == "CUDA" || entry.Language == "Fortran") {
+ entry.Language == "CUDA" || entry.Language == "Fortran" ||
+ entry.Language == "ISPC") {
// Right now, C, C++, Fortran and CUDA have both a preprocessor and the
// ability to generate assembly code
lang_has_preprocessor = true;
@@ -1444,7 +1445,8 @@ bool cmLocalUnixMakefileGenerator3::ScanDependencies(
// Create the scanner for this language
std::unique_ptr<cmDepends> scanner;
if (lang == "C" || lang == "CXX" || lang == "RC" || lang == "ASM" ||
- lang == "OBJC" || lang == "OBJCXX" || lang == "CUDA") {
+ lang == "OBJC" || lang == "OBJCXX" || lang == "CUDA" ||
+ lang == "ISPC") {
// TODO: Handle RC (resource files) dependencies correctly.
scanner = cm::make_unique<cmDependsC>(this, targetDir, lang, &validDeps);
}
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index fae1d76..afbbbd4 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -268,6 +268,7 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules()
this->ExternalObjects.push_back(objectFileName);
}
}
+
std::vector<cmSourceFile const*> objectSources;
this->GeneratorTarget->GetObjectSources(objectSources,
this->GetConfigName());
@@ -525,6 +526,14 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
}
}
+ if (lang != "ISPC") {
+ auto const& headers =
+ this->GeneratorTarget->GetGeneratedISPCHeaders(config);
+ if (!headers.empty()) {
+ depends.insert(depends.end(), headers.begin(), headers.end());
+ }
+ }
+
std::string relativeObj =
cmStrCat(this->LocalGenerator->GetHomeRelativeOutputPath(), obj);
// Write the build rule.
@@ -552,6 +561,23 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
this->AppendFortranPreprocessFlags(flags, source);
}
+ std::string ispcHeaderRelative;
+ std::string ispcHeaderForShell;
+ if (lang == "ISPC") {
+ std::string ispcSource =
+ cmSystemTools::GetFilenameWithoutLastExtension(objectName);
+
+ std::string directory = this->GeneratorTarget->GetObjectDirectory(config);
+ if (cmProp prop =
+ this->GeneratorTarget->GetProperty("ISPC_HEADER_DIRECTORY")) {
+ directory =
+ cmStrCat(this->LocalGenerator->GetBinaryDirectory(), '/', *prop);
+ }
+ ispcHeaderRelative = cmStrCat(directory, '/', ispcSource, ".h");
+ ispcHeaderForShell = this->LocalGenerator->ConvertToOutputFormat(
+ ispcHeaderRelative, cmOutputConverter::SHELL);
+ }
+
// Add flags from source file properties.
const std::string COMPILE_FLAGS("COMPILE_FLAGS");
if (cmProp cflags = source.GetProperty(COMPILE_FLAGS)) {
@@ -717,6 +743,7 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
cmOutputConverter::SHELL);
vars.ObjectFileDir = objectFileDir.c_str();
vars.Flags = flags.c_str();
+ vars.ISPCHeader = ispcHeaderForShell.c_str();
std::string definesString = cmStrCat("$(", lang, "_DEFINES)");
@@ -735,7 +762,8 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
// ability to export compile commands
bool lang_has_preprocessor =
((lang == "C") || (lang == "CXX") || (lang == "OBJC") ||
- (lang == "OBJCXX") || (lang == "Fortran") || (lang == "CUDA"));
+ (lang == "OBJCXX") || (lang == "Fortran") || (lang == "CUDA") ||
+ lang == "ISPC");
bool const lang_has_assembly = lang_has_preprocessor;
bool const lang_can_export_cmds = lang_has_preprocessor;
@@ -910,9 +938,16 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
if (!evaluated_outputs.empty()) {
// Register these as extra files to clean.
cmExpandList(evaluated_outputs, outputs);
- this->CleanFiles.insert(outputs.begin() + 1, outputs.end());
}
}
+ if (!ispcHeaderRelative
+ .empty()) { // can't move ispcHeader as vars is using it
+ outputs.emplace_back(ispcHeaderRelative);
+ }
+
+ if (outputs.size() > 1) {
+ this->CleanFiles.insert(outputs.begin() + 1, outputs.end());
+ }
// Write the rule.
this->WriteMakeRule(*this->BuildFileStream, nullptr, outputs, depends,
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index 57f526e..96e0c69 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -631,6 +631,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
vars.TargetCompilePDB = "$TARGET_COMPILE_PDB";
vars.ObjectDir = "$OBJECT_DIR";
vars.ObjectFileDir = "$OBJECT_FILE_DIR";
+ vars.ISPCHeader = "$ISPC_HEADER_FILE";
cmMakefile* mf = this->GetMakefile();
@@ -1369,6 +1370,42 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
objBuild.RspFile = cmStrCat(objectFileName, ".rsp");
+ if (language == "ISPC") {
+ std::string const& objectName =
+ this->GeneratorTarget->GetObjectName(source);
+ std::string ispcSource =
+ cmSystemTools::GetFilenameWithoutLastExtension(objectName);
+
+ std::string ispcDirectory = objectFileDir;
+ if (cmProp prop =
+ this->GeneratorTarget->GetProperty("ISPC_HEADER_DIRECTORY")) {
+ ispcDirectory = *prop;
+ }
+ ispcDirectory =
+ cmStrCat(this->LocalGenerator->GetBinaryDirectory(), '/', ispcDirectory);
+
+ std::string ispcHeader = cmStrCat(ispcDirectory, '/', ispcSource, ".h");
+ ispcHeader = this->ConvertToNinjaPath(ispcHeader);
+
+ // Make sure ninja knows what command generates the header
+ objBuild.ImplicitOuts.push_back(ispcHeader);
+
+ // Make sure ninja knows how to clean the generated header
+ this->GetGlobalGenerator()->AddAdditionalCleanFile(ispcHeader, config);
+
+ vars["ISPC_HEADER_FILE"] =
+ this->GetLocalGenerator()->ConvertToOutputFormat(
+ ispcHeader, cmOutputConverter::SHELL);
+ } else {
+ auto headers = this->GeneratorTarget->GetGeneratedISPCHeaders(config);
+ if (!headers.empty()) {
+ std::transform(headers.begin(), headers.end(), headers.begin(),
+ MapToNinjaPath());
+ objBuild.OrderOnlyDeps.insert(objBuild.OrderOnlyDeps.end(),
+ headers.begin(), headers.end());
+ }
+ }
+
if (language == "Swift") {
this->EmitSwiftDependencyInfo(source, config);
} else {
diff --git a/Source/cmRulePlaceholderExpander.cxx b/Source/cmRulePlaceholderExpander.cxx
index 4ff81c1..6f40ec6 100644
--- a/Source/cmRulePlaceholderExpander.cxx
+++ b/Source/cmRulePlaceholderExpander.cxx
@@ -90,6 +90,11 @@ std::string cmRulePlaceholderExpander::ExpandRuleVariable(
return replaceValues.AIXExports;
}
}
+ if (replaceValues.ISPCHeader) {
+ if (variable == "ISPC_HEADER") {
+ return replaceValues.ISPCHeader;
+ }
+ }
if (replaceValues.Defines && variable == "DEFINES") {
return replaceValues.Defines;
}
diff --git a/Source/cmRulePlaceholderExpander.h b/Source/cmRulePlaceholderExpander.h
index 09e8a3b..96e731f 100644
--- a/Source/cmRulePlaceholderExpander.h
+++ b/Source/cmRulePlaceholderExpander.h
@@ -64,6 +64,7 @@ public:
const char* SwiftModuleName;
const char* SwiftOutputFileMap;
const char* SwiftSources;
+ const char* ISPCHeader;
};
// Expand rule variables in CMake of the type found in language rules
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index bea9001..a30c9e9 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -366,6 +366,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
initProp("JOB_POOL_COMPILE");
initProp("JOB_POOL_LINK");
initProp("JOB_POOL_PRECOMPILE_HEADER");
+ initProp("ISPC_HEADER_DIRECTORY");
initProp("LINK_SEARCH_START_STATIC");
initProp("LINK_SEARCH_END_STATIC");
initProp("Swift_LANGUAGE_VERSION");
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index f630a7e..1bee728 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -205,6 +205,7 @@ cmake::cmake(Role role, cmState::Mode mode)
setupExts(this->CudaFileExtensions, { "cu" });
setupExts(this->FortranFileExtensions,
{ "f", "F", "for", "f77", "f90", "f95", "f03" });
+ setupExts(this->ISPCFileExtensions, { "ispc" });
}
}
@@ -1978,6 +1979,8 @@ std::vector<std::string> cmake::GetAllExtensions() const
// cuda extensions are also in SourceFileExtensions so we ignore it here
allExt.insert(allExt.end(), this->FortranFileExtensions.ordered.begin(),
this->FortranFileExtensions.ordered.end());
+ allExt.insert(allExt.end(), this->ISPCFileExtensions.ordered.begin(),
+ this->ISPCFileExtensions.ordered.end());
return allExt;
}
diff --git a/Source/cmake.h b/Source/cmake.h
index 0c4f429..06ab8ac 100644
--- a/Source/cmake.h
+++ b/Source/cmake.h
@@ -268,7 +268,8 @@ public:
{
return this->CLikeSourceFileExtensions.Test(ext) ||
this->CudaFileExtensions.Test(ext) ||
- this->FortranFileExtensions.Test(ext);
+ this->FortranFileExtensions.Test(ext) ||
+ this->ISPCFileExtensions.Test(ext);
}
bool IsACLikeSourceExtension(cm::string_view ext) const
@@ -617,6 +618,7 @@ private:
FileExtensions CLikeSourceFileExtensions;
FileExtensions HeaderFileExtensions;
FileExtensions CudaFileExtensions;
+ FileExtensions ISPCFileExtensions;
FileExtensions FortranFileExtensions;
bool ClearBuildSystem = false;
bool DebugTryCompile = false;