mirror of
https://github.com/Kitware/CMake.git
synced 2025-10-14 02:08:27 +08:00
ISPC: Support ISPC header generation byproducts and parallel builds
This commit is contained in:
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
12
Help/prop_tgt/ISPC_HEADER_DIRECTORY.rst
Normal file
12
Help/prop_tgt/ISPC_HEADER_DIRECTORY.rst
Normal file
@@ -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.
|
10
Help/variable/CMAKE_ISPC_HEADER_DIRECTORY.rst
Normal file
10
Help/variable/CMAKE_ISPC_HEADER_DIRECTORY.rst
Normal file
@@ -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.
|
@@ -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)
|
||||
|
@@ -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);
|
||||
|
@@ -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;
|
||||
|
||||
|
@@ -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());
|
||||
|
@@ -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());
|
||||
|
@@ -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();
|
||||
|
@@ -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 =
|
||||
|
@@ -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,
|
||||
|
@@ -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,
|
||||
|
@@ -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 {
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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
|
||||
|
@@ -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");
|
||||
|
@@ -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)
|
||||
|
@@ -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()
|
||||
|
@@ -1,6 +1,6 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "simple_ispc.h"
|
||||
#include "simple.ispc.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
|
@@ -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)
|
||||
|
17
Tests/ISPC/ObjectLibrary/extra.cxx
Normal file
17
Tests/ISPC/ObjectLibrary/extra.cxx
Normal file
@@ -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;
|
||||
}
|
12
Tests/ISPC/ObjectLibrary/extra.ispc
Normal file
12
Tests/ISPC/ObjectLibrary/extra.ispc
Normal file
@@ -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;
|
||||
}
|
||||
}
|
@@ -1,6 +1,6 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "simple_ispc.h"
|
||||
#include "simple.ispc.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
|
@@ -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(SpacesInPath PRIVATE
|
||||
"$<$<COMPILE_LANGUAGE:ISPC>:--target=sse2-i32x4;--arch=x86-64>")
|
||||
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_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>")
|
||||
|
@@ -1,6 +1,6 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "simple_ispc.h"
|
||||
#include "simple.ispc.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
|
@@ -1,5 +1,5 @@
|
||||
|
||||
STRUCT_DEFINE};
|
||||
STRUCT_DEFINE;};
|
||||
|
||||
#include "simple_include.h"
|
||||
|
||||
|
@@ -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)
|
||||
|
@@ -1,6 +1,6 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "simple_ispc.h"
|
||||
#include "simple.ispc.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
|
Reference in New Issue
Block a user