diff options
author | Robert Maynard <robert.maynard@kitware.com> | 2020-06-30 14:13:53 (GMT) |
---|---|---|
committer | Robert Maynard <robert.maynard@kitware.com> | 2020-08-28 15:21:31 (GMT) |
commit | e783bf8aa6f90ddb1458c7b1a78c5d0225c1496a (patch) | |
tree | b59fe2e01365d0ec14d79f38be8bede5afde6a62 | |
parent | 34cc6acc81758e29f8c88607c21ab11d8807f87c (diff) | |
download | CMake-e783bf8aa6f90ddb1458c7b1a78c5d0225c1496a.zip CMake-e783bf8aa6f90ddb1458c7b1a78c5d0225c1496a.tar.gz CMake-e783bf8aa6f90ddb1458c7b1a78c5d0225c1496a.tar.bz2 |
ISPC: Support ISPC header generation byproducts and parallel builds
30 files changed, 343 insertions, 39 deletions
diff --git a/Auxiliary/vim/syntax/cmake.vim b/Auxiliary/vim/syntax/cmake.vim index 2d63eb0..2dd3174 100644 --- a/Auxiliary/vim/syntax/cmake.vim +++ b/Auxiliary/vim/syntax/cmake.vim @@ -1048,6 +1048,7 @@ syn keyword cmakeVariable contained \ CMAKE_HOST_UNIX \ CMAKE_HOST_WIN32 \ CMAKE_IGNORE_PATH + \ CMAKE_ISPC_HEADER_DIRECTORY \ CMAKE_IMPORT_LIBRARY_PREFIX \ CMAKE_IMPORT_LIBRARY_SUFFIX \ CMAKE_INCLUDE_CURRENT_DIR diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst index 30b2a05..bdd2333 100644 --- a/Help/manual/cmake-properties.7.rst +++ b/Help/manual/cmake-properties.7.rst @@ -258,6 +258,7 @@ Properties on Targets /prop_tgt/INTERPROCEDURAL_OPTIMIZATION_CONFIG /prop_tgt/INTERPROCEDURAL_OPTIMIZATION /prop_tgt/IOS_INSTALL_COMBINED + /prop_tgt/ISPC_HEADER_DIRECTORY /prop_tgt/JOB_POOL_COMPILE /prop_tgt/JOB_POOL_LINK /prop_tgt/JOB_POOL_PRECOMPILE_HEADER diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst index 4ce8365..4515cc3 100644 --- a/Help/manual/cmake-variables.7.rst +++ b/Help/manual/cmake-variables.7.rst @@ -507,6 +507,7 @@ Variables for Languages /variable/CMAKE_Fortran_MODDIR_DEFAULT /variable/CMAKE_Fortran_MODDIR_FLAG /variable/CMAKE_Fortran_MODOUT_FLAG + /variable/CMAKE_ISPC_HEADER_DIRECTORY /variable/CMAKE_LANG_ANDROID_TOOLCHAIN_MACHINE /variable/CMAKE_LANG_ANDROID_TOOLCHAIN_PREFIX /variable/CMAKE_LANG_ANDROID_TOOLCHAIN_SUFFIX diff --git a/Help/prop_tgt/ISPC_HEADER_DIRECTORY.rst b/Help/prop_tgt/ISPC_HEADER_DIRECTORY.rst new file mode 100644 index 0000000..61b63fb --- /dev/null +++ b/Help/prop_tgt/ISPC_HEADER_DIRECTORY.rst @@ -0,0 +1,12 @@ +ISPC_HEADER_DIRECTORY +--------------------- + +.. versionadded:: 3.19 + +Specify output directory for ISPC headers provided by the target. + +If the target contains ISPC source files, this specifies the directory in which +the generated headers will be placed. When this property is not set, the +headers will be placed a generator defined build directory. If the variable +:variable:`CMAKE_ISPC_HEADER_DIRECTORY` is set when a target is created +its value is used to initialize this property. diff --git a/Help/variable/CMAKE_ISPC_HEADER_DIRECTORY.rst b/Help/variable/CMAKE_ISPC_HEADER_DIRECTORY.rst new file mode 100644 index 0000000..a7c9cf6 --- /dev/null +++ b/Help/variable/CMAKE_ISPC_HEADER_DIRECTORY.rst @@ -0,0 +1,10 @@ +CMAKE_ISPC_HEADER_DIRECTORY +---------------------------- + +.. versionadded:: 3.19 + +ISPC generated header output directory. + +This variable is used to initialize the :prop_tgt:`ISPC_HEADER_DIRECTORY` +property on all the targets. See the target property for additional +information. diff --git a/Modules/CMakeISPCInformation.cmake b/Modules/CMakeISPCInformation.cmake index 37057d9..514036e 100644 --- a/Modules/CMakeISPCInformation.cmake +++ b/Modules/CMakeISPCInformation.cmake @@ -50,7 +50,7 @@ endif() if(NOT CMAKE_ISPC_COMPILE_OBJECT) set(CMAKE_ISPC_COMPILE_OBJECT - "<CMAKE_ISPC_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT> --emit-obj <SOURCE>") + "<CMAKE_ISPC_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT> --emit-obj <SOURCE> -h <ISPC_HEADER>") endif() set(CMAKE_ISPC_INFORMATION_LOADED 1) diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index 6fc7209..9f8736a 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -1334,10 +1334,17 @@ std::string cmGeneratorTarget::EvaluateInterfaceProperty( namespace { +enum class IncludeDirectoryFallBack +{ + BINARY, + OBJECT +}; + std::string AddLangSpecificInterfaceIncludeDirectories( const cmGeneratorTarget* root, const cmGeneratorTarget* target, const std::string& lang, const std::string& config, - const std::string& propertyName, cmGeneratorExpressionDAGChecker* context) + const std::string& propertyName, IncludeDirectoryFallBack mode, + cmGeneratorExpressionDAGChecker* context) { cmGeneratorExpressionDAGChecker dag{ target->GetBacktrace(), target, propertyName, nullptr, context }; @@ -1364,7 +1371,12 @@ std::string AddLangSpecificInterfaceIncludeDirectories( auto* lg = dependency->GetLocalGenerator(); std::string value = dependency->GetSafeProperty(propertyName); if (value.empty()) { - value = lg->GetCurrentBinaryDirectory(); + if (mode == IncludeDirectoryFallBack::BINARY) { + value = lg->GetCurrentBinaryDirectory(); + } else if (mode == IncludeDirectoryFallBack::OBJECT) { + value = cmStrCat(lg->GetCurrentBinaryDirectory(), '/', + lg->GetTargetDirectory(dependency)); + } } if (!directories.empty()) { @@ -1381,7 +1393,7 @@ std::string AddLangSpecificInterfaceIncludeDirectories( void AddLangSpecificImplicitIncludeDirectories( const cmGeneratorTarget* target, const std::string& lang, const std::string& config, const std::string& propertyName, - EvaluatedTargetPropertyEntries& entries) + IncludeDirectoryFallBack mode, EvaluatedTargetPropertyEntries& entries) { if (const auto* libraries = target->GetLinkImplementationLibraries(config)) { cmGeneratorExpressionDAGChecker dag{ target->GetBacktrace(), target, @@ -1399,12 +1411,18 @@ void AddLangSpecificImplicitIncludeDirectories( if (cmProp val = dependency->GetProperty(propertyName)) { entry.Values.emplace_back(*val); } else { - entry.Values.emplace_back(lg->GetCurrentBinaryDirectory()); + if (mode == IncludeDirectoryFallBack::BINARY) { + entry.Values.emplace_back(lg->GetCurrentBinaryDirectory()); + } else if (mode == IncludeDirectoryFallBack::OBJECT) { + entry.Values.emplace_back( + dependency->GetObjectDirectory(config)); + } } - cmExpandList(AddLangSpecificInterfaceIncludeDirectories( - target, dependency, lang, config, propertyName, &dag), - entry.Values); + cmExpandList( + AddLangSpecificInterfaceIncludeDirectories( + target, dependency, lang, config, propertyName, mode, &dag), + entry.Values); entries.Entries.emplace_back(std::move(entry)); } } @@ -3439,7 +3457,27 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetIncludeDirectories( if (lang == "Swift") { AddLangSpecificImplicitIncludeDirectories( - this, lang, config, "Swift_MODULE_DIRECTORY", entries); + 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, @@ -5933,6 +5971,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 4a03f65..680681f 100644 --- a/Source/cmGeneratorTarget.h +++ b/Source/cmGeneratorTarget.h @@ -807,6 +807,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); @@ -985,6 +990,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 cad5d1f..0865432 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 2ef202d..9a87e18 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 7e35fe7..9369bd4 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -2408,6 +2408,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/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index 854fc8b..047fee1 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -267,6 +267,7 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules() this->ExternalObjects.push_back(objectFileName); } } + std::vector<cmSourceFile const*> objectSources; this->GeneratorTarget->GetObjectSources(objectSources, this->GetConfigName()); @@ -524,6 +525,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. @@ -551,6 +560,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)) { @@ -716,6 +742,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)"); @@ -910,9 +937,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 048dbb6..95b8ad7 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -630,6 +630,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(); @@ -1368,6 +1369,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 0e5dfef..1105f31 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/Tests/ISPC/CMakeLists.txt b/Tests/ISPC/CMakeLists.txt index c8d58fd..ca5a79b 100644 --- a/Tests/ISPC/CMakeLists.txt +++ b/Tests/ISPC/CMakeLists.txt @@ -6,9 +6,8 @@ macro (add_ispc_test_macro name) PROPERTY LABELS "ISPC") endmacro () -# set (ISPC_IA_TARGETS "sse2-i32x4,sse4-i32x4,avx1-i32x8,avx2-i32x8,avx512knl-i32x16,avx512skx-i32x16") - add_ispc_test_macro(ISPC.Defines ISPCDefines) add_ispc_test_macro(ISPC.ObjectLibrary ISPCObjectLibrary) +add_ispc_test_macro(ISPC.ResponseAndDefine ISPCResponseAndDefine) add_ispc_test_macro(ISPC.StaticLibrary ISPCStaticLibrary) add_ispc_test_macro(ISPC.TryCompile ISPCTryCompile) diff --git a/Tests/ISPC/Defines/CMakeLists.txt b/Tests/ISPC/Defines/CMakeLists.txt index 2c9f4c3..5155106 100644 --- a/Tests/ISPC/Defines/CMakeLists.txt +++ b/Tests/ISPC/Defines/CMakeLists.txt @@ -1,11 +1,15 @@ cmake_minimum_required(VERSION 3.18) project(ISPCDefines CXX ISPC) -set(CMAKE_ISPC_FLAGS -DM_PI=3.1415926535f [==[-DSTRUCT_DEFINE=struct{uniform int a]==]) +set(CMAKE_ISPC_FLAGS -DM_PI=3.1415926535f) +add_compile_definitions([==[STRUCT_DEFINE=struct{uniform int a]==]) -add_executable(ISPCResponseFile +add_executable(ISPCDefines main.cxx simple.ispc ) -set_target_properties(ISPCResponseFile PROPERTIES POSITION_INDEPENDENT_CODE ON) -target_include_directories(ISPCResponseFile PRIVATE "${CMAKE_CURRENT_BINARY_DIR}") + +set_target_properties(ISPCDefines PROPERTIES POSITION_INDEPENDENT_CODE ON) +if(CMAKE_SIZEOF_VOID_P EQUAL 4) + set_source_files_properties(simple.ispc PROPERTIES COMPILE_OPTIONS "--arch=x86") +endif() diff --git a/Tests/ISPC/Defines/main.cxx b/Tests/ISPC/Defines/main.cxx index a6b91a6..4f1c9be 100644 --- a/Tests/ISPC/Defines/main.cxx +++ b/Tests/ISPC/Defines/main.cxx @@ -1,6 +1,6 @@ #include <stdio.h> -#include "simple_ispc.h" +#include "simple.ispc.h" int main() { diff --git a/Tests/ISPC/ObjectLibrary/CMakeLists.txt b/Tests/ISPC/ObjectLibrary/CMakeLists.txt index edfbdd8..333ad66 100644 --- a/Tests/ISPC/ObjectLibrary/CMakeLists.txt +++ b/Tests/ISPC/ObjectLibrary/CMakeLists.txt @@ -3,12 +3,15 @@ cmake_minimum_required(VERSION 3.18) project(ISPCObjectLibrary CXX ISPC) set(CMAKE_NINJA_FORCE_RESPONSE_FILE ON) +if(CMAKE_SIZEOF_VOID_P EQUAL 4) + set(CMAKE_ISPC_FLAGS "--arch=x86") +endif() -add_library(ispc_objects OBJECT simple.ispc) +add_library(ispc_objects OBJECT simple.ispc extra.ispc) + +target_compile_options(ispc_objects PRIVATE "$<$<COMPILE_LANGUAGE:ISPC>:--target=sse2-i32x4>") -target_compile_options(ispc_objects PRIVATE "$<$<COMPILE_LANGUAGE:ISPC>:--target=sse2-i32x4;--arch=x86-64>") -target_include_directories(ispc_objects INTERFACE "${CMAKE_CURRENT_BINARY_DIR}") set_target_properties(ispc_objects PROPERTIES POSITION_INDEPENDENT_CODE ON) -add_executable(ISPCObjectLibrary main.cxx) +add_executable(ISPCObjectLibrary main.cxx extra.cxx) target_link_libraries(ISPCObjectLibrary PRIVATE ispc_objects) diff --git a/Tests/ISPC/ObjectLibrary/extra.cxx b/Tests/ISPC/ObjectLibrary/extra.cxx new file mode 100644 index 0000000..88ef3a7 --- /dev/null +++ b/Tests/ISPC/ObjectLibrary/extra.cxx @@ -0,0 +1,17 @@ +#include <stdio.h> + +#include "extra.ispc.h" + +int extra() +{ + float vin[16], vout[16]; + for (int i = 0; i < 16; ++i) + vin[i] = i; + + ispc::extra(vin, vout, 16); + + for (int i = 0; i < 16; ++i) + printf("%d: extra(%f) = %f\n", i, vin[i], vout[i]); + + return 0; +} diff --git a/Tests/ISPC/ObjectLibrary/extra.ispc b/Tests/ISPC/ObjectLibrary/extra.ispc new file mode 100644 index 0000000..5a4a442 --- /dev/null +++ b/Tests/ISPC/ObjectLibrary/extra.ispc @@ -0,0 +1,12 @@ + +export void extra(uniform float vin[], uniform float vout[], + uniform int count) { + foreach (index = 0 ... count) { + float v = vin[index]; + if (v < 3.) + v = v * v; + else + v = sqrt(v); + vout[index] = v; + } +} diff --git a/Tests/ISPC/ObjectLibrary/main.cxx b/Tests/ISPC/ObjectLibrary/main.cxx index a6b91a6..4f1c9be 100644 --- a/Tests/ISPC/ObjectLibrary/main.cxx +++ b/Tests/ISPC/ObjectLibrary/main.cxx @@ -1,6 +1,6 @@ #include <stdio.h> -#include "simple_ispc.h" +#include "simple.ispc.h" int main() { diff --git a/Tests/ISPC/ResponseAndDefine/CMakeLists.txt b/Tests/ISPC/ResponseAndDefine/CMakeLists.txt index 0dc5320..7539209 100644 --- a/Tests/ISPC/ResponseAndDefine/CMakeLists.txt +++ b/Tests/ISPC/ResponseAndDefine/CMakeLists.txt @@ -1,5 +1,5 @@ - -project(ispc_spaces_in_path) +cmake_minimum_required(VERSION 3.18) +project(ispc_spaces_in_path ISPC CXX) set(CMAKE_NINJA_FORCE_RESPONSE_FILE ON) @@ -10,15 +10,19 @@ file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/path with spaces/simple_include.h" " ) -add_executable(SpacesInPath main.cxx simple.ispc) -set_target_properties(SpacesInPath PROPERTIES POSITION_INDEPENDENT_CODE ON) -target_include_directories(SpacesInPath PRIVATE "${CMAKE_CURRENT_BINARY_DIR}") +add_executable(ISPCResponseAndDefine main.cxx simple.ispc) +set_target_properties(ISPCResponseAndDefine PROPERTIES POSITION_INDEPENDENT_CODE ON) +target_include_directories(ISPCResponseAndDefine PRIVATE "${CMAKE_CURRENT_BINARY_DIR}") + +target_compile_options(ISPCResponseAndDefine PRIVATE "$<$<COMPILE_LANGUAGE:ISPC>:--target=sse2-i32x4>") +if(CMAKE_SIZEOF_VOID_P EQUAL 4) + target_compile_options(ISPCResponseAndDefine PRIVATE "$<$<COMPILE_LANGUAGE:ISPC>:--arch=x86>") +endif() + -target_compile_options(SpacesInPath PRIVATE - "$<$<COMPILE_LANGUAGE:ISPC>:--target=sse2-i32x4;--arch=x86-64>") -target_compile_definitions(SpacesInPath PRIVATE - "$<$<COMPILE_LANGUAGE:ISPC>:STRUCT_DEFINE=\"struct{uniform int a;varying int b;\";M_PI=3.1415926535f>") -target_include_directories(SpacesInPath PRIVATE - "$<$<COMPILE_LANGUAGE:ISPC>:\"fake path with spaces\">"" - "$<$<COMPILE_LANGUAGE:ISPC>:\"path with spaces\">") +target_compile_definitions(ISPCResponseAndDefine PRIVATE + "$<$<COMPILE_LANGUAGE:ISPC>:STRUCT_DEFINE=struct{uniform int a>;M_PI=3.14159f") +target_include_directories(ISPCResponseAndDefine PRIVATE + "$<$<COMPILE_LANGUAGE:ISPC>:${CMAKE_CURRENT_BINARY_DIR}/fake path with spaces>" + "$<$<COMPILE_LANGUAGE:ISPC>:${CMAKE_CURRENT_BINARY_DIR}/path with spaces>") diff --git a/Tests/ISPC/ResponseAndDefine/main.cxx b/Tests/ISPC/ResponseAndDefine/main.cxx index a6b91a6..4f1c9be 100644 --- a/Tests/ISPC/ResponseAndDefine/main.cxx +++ b/Tests/ISPC/ResponseAndDefine/main.cxx @@ -1,6 +1,6 @@ #include <stdio.h> -#include "simple_ispc.h" +#include "simple.ispc.h" int main() { diff --git a/Tests/ISPC/ResponseAndDefine/simple.ispc b/Tests/ISPC/ResponseAndDefine/simple.ispc index 3f32c37..81fd7ca 100644 --- a/Tests/ISPC/ResponseAndDefine/simple.ispc +++ b/Tests/ISPC/ResponseAndDefine/simple.ispc @@ -1,5 +1,5 @@ -STRUCT_DEFINE}; +STRUCT_DEFINE;}; #include "simple_include.h" diff --git a/Tests/ISPC/StaticLibrary/CMakeLists.txt b/Tests/ISPC/StaticLibrary/CMakeLists.txt index b057544..ebe5960 100644 --- a/Tests/ISPC/StaticLibrary/CMakeLists.txt +++ b/Tests/ISPC/StaticLibrary/CMakeLists.txt @@ -4,8 +4,11 @@ project(ISPCStaticLibrary CXX ISPC) add_library(ispc_objects STATIC simple.ispc) -target_compile_options(ispc_objects PRIVATE "$<$<COMPILE_LANGUAGE:ISPC>:--target=sse2-i32x4;--arch=x86-64>") -target_include_directories(ispc_objects INTERFACE "${CMAKE_CURRENT_BINARY_DIR}") +target_compile_options(ispc_objects PRIVATE "$<$<COMPILE_LANGUAGE:ISPC>:--target=sse2-i32x4>") +if(CMAKE_SIZEOF_VOID_P EQUAL 4) + target_compile_options(ispc_objects PRIVATE "$<$<COMPILE_LANGUAGE:ISPC>:--arch=x86>") +endif() + set_target_properties(ispc_objects PROPERTIES POSITION_INDEPENDENT_CODE ON) add_executable(ISPCStaticLibrary main.cxx) diff --git a/Tests/ISPC/StaticLibrary/main.cxx b/Tests/ISPC/StaticLibrary/main.cxx index a6b91a6..4f1c9be 100644 --- a/Tests/ISPC/StaticLibrary/main.cxx +++ b/Tests/ISPC/StaticLibrary/main.cxx @@ -1,6 +1,6 @@ #include <stdio.h> -#include "simple_ispc.h" +#include "simple.ispc.h" int main() { |