diff options
author | Brad King <brad.king@kitware.com> | 2020-09-01 13:15:29 (GMT) |
---|---|---|
committer | Kitware Robot <kwrobot@kitware.com> | 2020-09-01 13:15:39 (GMT) |
commit | f10682b7961c2ad56384641ab141a66f34923753 (patch) | |
tree | 4bf3b7b721dd33b6934faf6c119770bf04209891 /Source | |
parent | cd2f894052ea8191e21ec4997b2181c75f637ae9 (diff) | |
parent | 5ece12b7e452acb091300022a392ff71dfce9504 (diff) | |
download | CMake-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.cxx | 12 | ||||
-rw-r--r-- | Source/cmGeneratorExpressionNode.cxx | 5 | ||||
-rw-r--r-- | Source/cmGeneratorTarget.cxx | 122 | ||||
-rw-r--r-- | Source/cmGeneratorTarget.h | 8 | ||||
-rw-r--r-- | Source/cmGlobalGenerator.cxx | 1 | ||||
-rw-r--r-- | Source/cmGlobalNinjaGenerator.cxx | 42 | ||||
-rw-r--r-- | Source/cmGlobalNinjaGenerator.h | 6 | ||||
-rw-r--r-- | Source/cmLocalGenerator.cxx | 32 | ||||
-rw-r--r-- | Source/cmLocalGenerator.h | 1 | ||||
-rw-r--r-- | Source/cmLocalUnixMakefileGenerator3.cxx | 6 | ||||
-rw-r--r-- | Source/cmMakefileTargetGenerator.cxx | 39 | ||||
-rw-r--r-- | Source/cmNinjaTargetGenerator.cxx | 37 | ||||
-rw-r--r-- | Source/cmRulePlaceholderExpander.cxx | 5 | ||||
-rw-r--r-- | Source/cmRulePlaceholderExpander.h | 1 | ||||
-rw-r--r-- | Source/cmTarget.cxx | 1 | ||||
-rw-r--r-- | Source/cmake.cxx | 3 | ||||
-rw-r--r-- | Source/cmake.h | 4 |
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; |