diff options
Diffstat (limited to 'Source/cmLocalGenerator.cxx')
-rw-r--r-- | Source/cmLocalGenerator.cxx | 491 |
1 files changed, 220 insertions, 271 deletions
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index feea49f40..2adb232ca 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -37,6 +37,7 @@ #include "cmInstallTargetGenerator.h" #include "cmLinkLineComputer.h" #include "cmMakefile.h" +#include "cmRange.h" #include "cmRulePlaceholderExpander.h" #include "cmSourceFile.h" #include "cmSourceFileLocation.h" @@ -834,16 +835,14 @@ cmValue cmLocalGenerator::GetRuleLauncher(cmGeneratorTarget* target, } std::string cmLocalGenerator::ConvertToIncludeReference( - std::string const& path, IncludePathStyle pathStyle, OutputFormat format) + std::string const& path, OutputFormat format) { - static_cast<void>(pathStyle); return this->ConvertToOutputForExisting(path, format); } std::string cmLocalGenerator::GetIncludeFlags( std::vector<std::string> const& includeDirs, cmGeneratorTarget* target, - std::string const& lang, std::string const& config, bool forResponseFile, - IncludePathStyle pathStyle) + std::string const& lang, std::string const& config, bool forResponseFile) { if (lang.empty()) { return ""; @@ -922,8 +921,7 @@ std::string cmLocalGenerator::GetIncludeFlags( } flagUsed = true; } - std::string includePath = - this->ConvertToIncludeReference(i, pathStyle, shellFormat); + std::string includePath = this->ConvertToIncludeReference(i, shellFormat); if (quotePaths && !includePath.empty() && includePath.front() != '\"') { includeFlags << "\""; } @@ -1056,14 +1054,8 @@ void cmLocalGenerator::AddCompileOptions(std::vector<BT<std::string>>& flags, } cmTarget* cmLocalGenerator::AddCustomCommandToTarget( - const std::string& target, const std::vector<std::string>& byproducts, - const std::vector<std::string>& depends, - const cmCustomCommandLines& commandLines, cmCustomCommandType type, - const char* comment, const char* workingDir, - cmPolicies::PolicyStatus cmp0116, bool escapeOldStyle, bool uses_terminal, - const std::string& depfile, const std::string& job_pool, - bool command_expand_lists, cmObjectLibraryCommands objLibCommands, - bool stdPipesUTF8) + const std::string& target, cmCustomCommandType type, + std::unique_ptr<cmCustomCommand> cc, cmObjectLibraryCommands objLibCommands) { cmTarget* t = this->Makefile->GetCustomCommandTarget( target, objLibCommands, this->DirectoryBacktrace); @@ -1071,74 +1063,43 @@ cmTarget* cmLocalGenerator::AddCustomCommandToTarget( return nullptr; } - detail::AddCustomCommandToTarget( - *this, this->DirectoryBacktrace, cmCommandOrigin::Generator, t, byproducts, - depends, commandLines, type, comment, workingDir, escapeOldStyle, - uses_terminal, depfile, job_pool, command_expand_lists, stdPipesUTF8, - cmp0116); + cc->SetBacktrace(this->DirectoryBacktrace); - return t; -} + detail::AddCustomCommandToTarget(*this, cmCommandOrigin::Generator, t, type, + std::move(cc)); -cmSourceFile* cmLocalGenerator::AddCustomCommandToOutput( - const std::string& output, const std::vector<std::string>& depends, - const std::string& main_dependency, const cmCustomCommandLines& commandLines, - const char* comment, const char* workingDir, - cmPolicies::PolicyStatus cmp0116, bool replace, bool escapeOldStyle, - bool uses_terminal, bool command_expand_lists, const std::string& depfile, - const std::string& job_pool, bool stdPipesUTF8) -{ - std::vector<std::string> no_byproducts; - cmImplicitDependsList no_implicit_depends; - return this->AddCustomCommandToOutput( - { output }, no_byproducts, depends, main_dependency, no_implicit_depends, - commandLines, comment, workingDir, cmp0116, replace, escapeOldStyle, - uses_terminal, command_expand_lists, depfile, job_pool, stdPipesUTF8); + return t; } cmSourceFile* cmLocalGenerator::AddCustomCommandToOutput( - const std::vector<std::string>& outputs, - const std::vector<std::string>& byproducts, - const std::vector<std::string>& depends, const std::string& main_dependency, - const cmImplicitDependsList& implicit_depends, - const cmCustomCommandLines& commandLines, const char* comment, - const char* workingDir, cmPolicies::PolicyStatus cmp0116, bool replace, - bool escapeOldStyle, bool uses_terminal, bool command_expand_lists, - const std::string& depfile, const std::string& job_pool, bool stdPipesUTF8) + std::unique_ptr<cmCustomCommand> cc, bool replace) { // Make sure there is at least one output. - if (outputs.empty()) { + if (cc->GetOutputs().empty()) { cmSystemTools::Error("Attempt to add a custom rule with no output!"); return nullptr; } - return detail::AddCustomCommandToOutput( - *this, this->DirectoryBacktrace, cmCommandOrigin::Generator, outputs, - byproducts, depends, main_dependency, implicit_depends, commandLines, - comment, workingDir, replace, escapeOldStyle, uses_terminal, - command_expand_lists, depfile, job_pool, stdPipesUTF8, cmp0116); + cc->SetBacktrace(this->DirectoryBacktrace); + return detail::AddCustomCommandToOutput(*this, cmCommandOrigin::Generator, + std::move(cc), replace); } cmTarget* cmLocalGenerator::AddUtilityCommand( - const std::string& utilityName, bool excludeFromAll, const char* workingDir, - const std::vector<std::string>& byproducts, - const std::vector<std::string>& depends, - const cmCustomCommandLines& commandLines, cmPolicies::PolicyStatus cmp0116, - bool escapeOldStyle, const char* comment, bool uses_terminal, - bool command_expand_lists, const std::string& job_pool, bool stdPipesUTF8) + const std::string& utilityName, bool excludeFromAll, + std::unique_ptr<cmCustomCommand> cc) { cmTarget* target = this->Makefile->AddNewUtilityTarget(utilityName, excludeFromAll); target->SetIsGeneratorProvided(true); - if (commandLines.empty() && depends.empty()) { + if (cc->GetCommandLines().empty() && cc->GetDepends().empty()) { return target; } - detail::AddUtilityCommand( - *this, this->DirectoryBacktrace, cmCommandOrigin::Generator, target, - workingDir, byproducts, depends, commandLines, escapeOldStyle, comment, - uses_terminal, command_expand_lists, job_pool, stdPipesUTF8, cmp0116); + cc->SetBacktrace(this->DirectoryBacktrace); + detail::AddUtilityCommand(*this, cmCommandOrigin::Generator, target, + std::move(cc)); return target; } @@ -1410,25 +1371,23 @@ std::vector<BT<std::string>> cmLocalGenerator::GetStaticLibraryFlags( } void cmLocalGenerator::GetDeviceLinkFlags( - cmLinkLineComputer* linkLineComputer, const std::string& config, + cmLinkLineComputer& linkLineComputer, const std::string& config, std::string& linkLibs, std::string& linkFlags, std::string& frameworkPath, std::string& linkPath, cmGeneratorTarget* target) { cmGeneratorTarget::DeviceLinkSetter setter(*target); cmComputeLinkInformation* pcli = target->GetLinkInformation(config); - const std::string linkLanguage = - linkLineComputer->GetLinkerLanguage(target, config); if (pcli) { // Compute the required device link libraries when // resolving gpu lang device symbols - this->OutputLinkLibraries(pcli, linkLineComputer, linkLibs, frameworkPath, + this->OutputLinkLibraries(pcli, &linkLineComputer, linkLibs, frameworkPath, linkPath); } std::vector<std::string> linkOpts; - target->GetLinkOptions(linkOpts, config, linkLanguage); + target->GetLinkOptions(linkOpts, config, "CUDA"); // LINK_OPTIONS are escaped. this->AppendCompileOptions(linkFlags, linkOpts); } @@ -2510,12 +2469,12 @@ void cmLocalGenerator::AddPchDependencies(cmGeneratorTarget* target) static const std::array<std::string, 4> langs = { { "C", "CXX", "OBJC", "OBJCXX" } }; - std::set<std::string> pchLangSet; + bool haveAnyPch = false; if (this->GetGlobalGenerator()->IsXcode()) { for (const std::string& lang : langs) { const std::string pchHeader = target->GetPchHeader(config, lang, ""); if (!pchHeader.empty()) { - pchLangSet.emplace(lang); + haveAnyPch = true; } } } @@ -2560,11 +2519,9 @@ void cmLocalGenerator::AddPchDependencies(cmGeneratorTarget* target) const std::string pchHeader = target->GetPchHeader(config, lang, arch); if (pchSource.empty() || pchHeader.empty()) { - if (this->GetGlobalGenerator()->IsXcode() && !pchLangSet.empty()) { + if (this->GetGlobalGenerator()->IsXcode() && haveAnyPch) { for (auto* sf : sources) { - if (pchLangSet.find(sf->GetLanguage()) == pchLangSet.end()) { - sf->SetProperty("SKIP_PRECOMPILE_HEADERS", "ON"); - } + sf->SetProperty("SKIP_PRECOMPILE_HEADERS", "ON"); } } continue; @@ -2658,10 +2615,15 @@ void cmLocalGenerator::AddPchDependencies(cmGeneratorTarget* target) true); } else if (reuseTarget->GetType() == cmStateEnums::OBJECT_LIBRARY) { + // FIXME: This can propagate more than one level, unlike + // the rest of the object files in an object library. + // Find another way to do this. target->Target->AppendProperty( "INTERFACE_LINK_LIBRARIES", cmStrCat("$<$<CONFIG:", config, ">:$<LINK_ONLY:", pchSourceObj, ">>")); + // We updated the link interface, so ensure it is recomputed. + target->ClearLinkInterfaceCache(); } } } else { @@ -2753,8 +2715,6 @@ void cmLocalGenerator::CopyPchCompilePdb( file << "endforeach()\n"; } - bool stdPipesUTF8 = true; - auto configGenex = [&](cm::string_view expr) -> std::string { if (this->GetGlobalGenerator()->IsMultiConfig()) { return cmStrCat("$<$<CONFIG:", config, ">:", expr, ">"); @@ -2767,29 +2727,26 @@ void cmLocalGenerator::CopyPchCompilePdb( configGenex(cmStrCat("-DPDB_PREFIX=", pdb_prefix)), configGenex("-P"), configGenex(copy_script) }); - const std::string no_main_dependency; - const std::vector<std::string> no_deps; const char* no_message = ""; - const char* no_current_dir = nullptr; - const cmPolicies::PolicyStatus cmp0116_new = cmPolicies::NEW; - std::vector<std::string> no_byproducts; std::vector<std::string> outputs; outputs.push_back(configGenex( cmStrCat(target_compile_pdb_dir, pdb_prefix, ReuseFrom, ".pdb"))); + auto cc = cm::make_unique<cmCustomCommand>(); + cc->SetCommandLines(commandLines); + cc->SetComment(no_message); + cc->SetCMP0116Status(cmPolicies::NEW); + cc->SetStdPipesUTF8(true); + if (this->GetGlobalGenerator()->IsVisualStudio()) { + cc->SetByproducts(outputs); this->AddCustomCommandToTarget( - target->GetName(), outputs, no_deps, commandLines, - cmCustomCommandType::PRE_BUILD, no_message, no_current_dir, cmp0116_new, - true, false, "", "", false, cmObjectLibraryCommands::Accept, - stdPipesUTF8); + target->GetName(), cmCustomCommandType::PRE_BUILD, std::move(cc), + cmObjectLibraryCommands::Accept); } else { - cmImplicitDependsList no_implicit_depends; - cmSourceFile* copy_rule = this->AddCustomCommandToOutput( - outputs, no_byproducts, no_deps, no_main_dependency, no_implicit_depends, - commandLines, no_message, no_current_dir, cmp0116_new, false, true, - false, false, "", "", stdPipesUTF8); + cc->SetOutputs(outputs); + cmSourceFile* copy_rule = this->AddCustomCommandToOutput(std::move(cc)); if (copy_rule) { target->AddSource(copy_rule->ResolveFullPath()); @@ -2810,10 +2767,47 @@ inline void RegisterUnitySources(cmGeneratorTarget* target, cmSourceFile* sf, } } -void cmLocalGenerator::IncludeFileInUnitySources( - cmGeneratedFileStream& unity_file, std::string const& sf_full_path, - cmValue beforeInclude, cmValue afterInclude, cmValue uniqueIdName) const +cmLocalGenerator::UnitySource cmLocalGenerator::WriteUnitySource( + cmGeneratorTarget* target, std::vector<std::string> const& configs, + cmRange<std::vector<UnityBatchedSource>::const_iterator> sources, + cmValue beforeInclude, cmValue afterInclude, std::string filename) const +{ + cmValue uniqueIdName = target->GetProperty("UNITY_BUILD_UNIQUE_ID"); + cmGeneratedFileStream file( + filename, false, target->GetGlobalGenerator()->GetMakefileEncoding()); + file.SetCopyIfDifferent(true); + file << "/* generated by CMake */\n\n"; + + bool perConfig = false; + for (UnityBatchedSource const& ubs : sources) { + cm::optional<std::string> cond; + if (ubs.Configs.size() != configs.size()) { + perConfig = true; + cond = std::string(); + cm::string_view sep; + for (size_t ci : ubs.Configs) { + cond = cmStrCat(*cond, sep, "defined(CMAKE_UNITY_CONFIG_", + cmSystemTools::UpperCase(configs[ci]), ")"); + sep = " || "_s; + } + } + RegisterUnitySources(target, ubs.Source, filename); + WriteUnitySourceInclude(file, cond, ubs.Source->ResolveFullPath(), + beforeInclude, afterInclude, uniqueIdName); + } + + return UnitySource(std::move(filename), perConfig); +} + +void cmLocalGenerator::WriteUnitySourceInclude( + std::ostream& unity_file, cm::optional<std::string> const& cond, + std::string const& sf_full_path, cmValue beforeInclude, cmValue afterInclude, + cmValue uniqueIdName) const { + if (cond) { + unity_file << "#if " << *cond << "\n"; + } + if (cmNonempty(uniqueIdName)) { std::string pathToHash; auto PathEqOrSubDir = [](std::string const& a, std::string const& b) { @@ -2833,7 +2827,10 @@ void cmLocalGenerator::IncludeFileInUnitySources( unity_file << "/* " << pathToHash << " */\n" << "#undef " << *uniqueIdName << "\n" << "#define " << *uniqueIdName << " unity_" - << cmSystemTools::ComputeStringMD5(pathToHash) << "\n"; +#ifndef CMAKE_BOOTSTRAP + << cmSystemTools::ComputeStringMD5(pathToHash) << "\n" +#endif + ; } if (beforeInclude) { @@ -2845,21 +2842,25 @@ void cmLocalGenerator::IncludeFileInUnitySources( if (afterInclude) { unity_file << *afterInclude << "\n"; } + if (cond) { + unity_file << "#endif\n"; + } unity_file << "\n"; } -std::vector<std::string> cmLocalGenerator::AddUnityFilesModeAuto( +std::vector<cmLocalGenerator::UnitySource> +cmLocalGenerator::AddUnityFilesModeAuto( cmGeneratorTarget* target, std::string const& lang, - std::vector<cmSourceFile*> const& filtered_sources, cmValue beforeInclude, - cmValue afterInclude, std::string const& filename_base, size_t batchSize) + std::vector<std::string> const& configs, + std::vector<UnityBatchedSource> const& filtered_sources, + cmValue beforeInclude, cmValue afterInclude, + std::string const& filename_base, size_t batchSize) { if (batchSize == 0) { batchSize = filtered_sources.size(); } - cmValue uniqueIdName = target->GetProperty("UNITY_BUILD_UNIQUE_ID"); - - std::vector<std::string> unity_files; + std::vector<UnitySource> unity_files; for (size_t itemsLeft = filtered_sources.size(), chunk, batch = 0; itemsLeft > 0; itemsLeft -= chunk, ++batch) { @@ -2867,74 +2868,48 @@ std::vector<std::string> cmLocalGenerator::AddUnityFilesModeAuto( std::string filename = cmStrCat(filename_base, "unity_", batch, (lang == "C") ? "_c.c" : "_cxx.cxx"); - - const std::string filename_tmp = cmStrCat(filename, ".tmp"); - { - size_t begin = batch * batchSize; - size_t end = begin + chunk; - - cmGeneratedFileStream file( - filename_tmp, false, - target->GetGlobalGenerator()->GetMakefileEncoding()); - file << "/* generated by CMake */\n\n"; - - for (; begin != end; ++begin) { - cmSourceFile* sf = filtered_sources[begin]; - RegisterUnitySources(target, sf, filename); - IncludeFileInUnitySources(file, sf->ResolveFullPath(), beforeInclude, - afterInclude, uniqueIdName); - } - } - cmSystemTools::MoveFileIfDifferent(filename_tmp, filename); - unity_files.emplace_back(std::move(filename)); + auto const begin = filtered_sources.begin() + batch * batchSize; + auto const end = begin + chunk; + unity_files.emplace_back(this->WriteUnitySource( + target, configs, cmMakeRange(begin, end), beforeInclude, afterInclude, + std::move(filename))); } return unity_files; } -std::vector<std::string> cmLocalGenerator::AddUnityFilesModeGroup( +std::vector<cmLocalGenerator::UnitySource> +cmLocalGenerator::AddUnityFilesModeGroup( cmGeneratorTarget* target, std::string const& lang, - std::vector<cmSourceFile*> const& filtered_sources, cmValue beforeInclude, - cmValue afterInclude, std::string const& filename_base) + std::vector<std::string> const& configs, + std::vector<UnityBatchedSource> const& filtered_sources, + cmValue beforeInclude, cmValue afterInclude, + std::string const& filename_base) { - std::vector<std::string> unity_files; + std::vector<UnitySource> unity_files; // sources organized by group name. Drop any source // without a group - std::unordered_map<std::string, std::vector<cmSourceFile*>> explicit_mapping; - for (cmSourceFile* sf : filtered_sources) { - if (cmValue value = sf->GetProperty("UNITY_GROUP")) { + std::unordered_map<std::string, std::vector<UnityBatchedSource>> + explicit_mapping; + for (UnityBatchedSource const& ubs : filtered_sources) { + if (cmValue value = ubs.Source->GetProperty("UNITY_GROUP")) { auto i = explicit_mapping.find(*value); if (i == explicit_mapping.end()) { - std::vector<cmSourceFile*> sources{ sf }; - explicit_mapping.emplace(*value, sources); + std::vector<UnityBatchedSource> sources{ ubs }; + explicit_mapping.emplace(*value, std::move(sources)); } else { - i->second.emplace_back(sf); + i->second.emplace_back(ubs); } } } - cmValue uniqueIdName = target->GetProperty("UNITY_BUILD_UNIQUE_ID"); - for (auto const& item : explicit_mapping) { auto const& name = item.first; std::string filename = cmStrCat(filename_base, "unity_", name, (lang == "C") ? "_c.c" : "_cxx.cxx"); - - const std::string filename_tmp = cmStrCat(filename, ".tmp"); - { - cmGeneratedFileStream file( - filename_tmp, false, - target->GetGlobalGenerator()->GetMakefileEncoding()); - file << "/* generated by CMake */\n\n"; - - for (cmSourceFile* sf : item.second) { - RegisterUnitySources(target, sf, filename); - IncludeFileInUnitySources(file, sf->ResolveFullPath(), beforeInclude, - afterInclude, uniqueIdName); - } - } - cmSystemTools::MoveFileIfDifferent(filename_tmp, filename); - unity_files.emplace_back(std::move(filename)); + unity_files.emplace_back(this->WriteUnitySource( + target, configs, cmMakeRange(item.second), beforeInclude, afterInclude, + std::move(filename))); } return unity_files; @@ -2946,20 +2921,33 @@ void cmLocalGenerator::AddUnityBuild(cmGeneratorTarget* target) return; } - // FIXME: Handle all configurations in multi-config generators. - std::string config; - if (!this->GetGlobalGenerator()->IsMultiConfig()) { - config = this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"); + std::vector<UnityBatchedSource> unitySources; + + std::vector<std::string> configs = + this->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig); + + std::map<cmSourceFile const*, size_t> index; + + for (size_t ci = 0; ci < configs.size(); ++ci) { + // FIXME: Refactor collection of sources to not evaluate object libraries. + std::vector<cmSourceFile*> sources; + target->GetSourceFiles(sources, configs[ci]); + for (cmSourceFile* sf : sources) { + auto mi = index.find(sf); + if (mi == index.end()) { + unitySources.emplace_back(sf); + std::map<cmSourceFile const*, size_t>::value_type entry( + sf, unitySources.size() - 1); + mi = index.insert(entry).first; + } + unitySources[mi->second].Configs.emplace_back(ci); + } } std::string filename_base = cmStrCat(this->GetCurrentBinaryDirectory(), "/CMakeFiles/", target->GetName(), ".dir/Unity/"); - // FIXME: Refactor collection of sources to not evaluate object libraries. - std::vector<cmSourceFile*> sources; - target->GetSourceFiles(sources, config); - cmValue batchSizeString = target->GetProperty("UNITY_BUILD_BATCH_SIZE"); const size_t unityBatchSize = batchSizeString ? static_cast<size_t>(std::atoi(batchSizeString->c_str())) @@ -2971,9 +2959,11 @@ void cmLocalGenerator::AddUnityBuild(cmGeneratorTarget* target) cmValue unityMode = target->GetProperty("UNITY_BUILD_MODE"); for (std::string lang : { "C", "CXX" }) { - std::vector<cmSourceFile*> filtered_sources; - std::copy_if(sources.begin(), sources.end(), - std::back_inserter(filtered_sources), [&](cmSourceFile* sf) { + std::vector<UnityBatchedSource> filtered_sources; + std::copy_if(unitySources.begin(), unitySources.end(), + std::back_inserter(filtered_sources), + [&](UnityBatchedSource const& ubs) -> bool { + cmSourceFile* sf = ubs.Source; return sf->GetLanguage() == lang && !sf->GetPropertyAsBool("SKIP_UNITY_BUILD_INCLUSION") && !sf->GetPropertyAsBool("HEADER_FILE_ONLY") && @@ -2983,15 +2973,15 @@ void cmLocalGenerator::AddUnityBuild(cmGeneratorTarget* target) !sf->GetProperty("INCLUDE_DIRECTORIES"); }); - std::vector<std::string> unity_files; + std::vector<UnitySource> unity_files; if (!unityMode || *unityMode == "BATCH") { - unity_files = - AddUnityFilesModeAuto(target, lang, filtered_sources, beforeInclude, - afterInclude, filename_base, unityBatchSize); + unity_files = AddUnityFilesModeAuto( + target, lang, configs, filtered_sources, beforeInclude, afterInclude, + filename_base, unityBatchSize); } else if (unityMode && *unityMode == "GROUP") { unity_files = - AddUnityFilesModeGroup(target, lang, filtered_sources, beforeInclude, - afterInclude, filename_base); + AddUnityFilesModeGroup(target, lang, configs, filtered_sources, + beforeInclude, afterInclude, filename_base); } else { // unity mode is set to an unsupported value std::string e("Invalid UNITY_BUILD_MODE value of " + *unityMode + @@ -3000,11 +2990,15 @@ void cmLocalGenerator::AddUnityBuild(cmGeneratorTarget* target) this->IssueMessage(MessageType::FATAL_ERROR, e); } - for (auto const& file : unity_files) { - auto* unity = this->GetMakefile()->GetOrCreateSource(file); - target->AddSource(file, true); + for (UnitySource const& file : unity_files) { + auto* unity = this->GetMakefile()->GetOrCreateSource(file.Path); + target->AddSource(file.Path, true); unity->SetProperty("SKIP_UNITY_BUILD_INCLUSION", "ON"); - unity->SetProperty("UNITY_SOURCE_FILE", file); + unity->SetProperty("UNITY_SOURCE_FILE", file.Path); + if (file.PerConfig) { + unity->SetProperty("COMPILE_DEFINITIONS", + "CMAKE_UNITY_CONFIG_$<UPPER_CASE:$<CONFIG>>"); + } } } } @@ -3441,21 +3435,27 @@ void cmLocalGenerator::GenerateTargetInstallRules( static bool cmLocalGeneratorShortenObjectName(std::string& objName, std::string::size_type max_len) { + // Check if the path can be shortened using an md5 sum replacement for + // a portion of the path. + std::string::size_type md5Len = 32; + std::string::size_type numExtraChars = objName.size() - max_len + md5Len; + std::string::size_type pos = objName.find('/', numExtraChars); + if (pos == std::string::npos) { + pos = objName.rfind('/', numExtraChars); + if (pos == std::string::npos || pos <= md5Len) { + return false; + } + } + // Replace the beginning of the path portion of the object name with // its own md5 sum. - std::string::size_type pos = - objName.find('/', objName.size() - max_len + 32); - if (pos != std::string::npos) { - cmCryptoHash md5(cmCryptoHash::AlgoMD5); - std::string md5name = cmStrCat(md5.HashString(objName.substr(0, pos)), - cm::string_view(objName).substr(pos)); - objName = md5name; + cmCryptoHash md5(cmCryptoHash::AlgoMD5); + std::string md5name = cmStrCat(md5.HashString(objName.substr(0, pos)), + cm::string_view(objName).substr(pos)); + objName = md5name; - // The object name is now short enough. - return true; - } - // The object name could not be shortened enough. - return false; + // The object name is now shorter, check if it is short enough. + return pos >= numExtraChars; } bool cmLocalGeneratorCheckObjectName(std::string& objName, @@ -3507,7 +3507,7 @@ std::string& cmLocalGenerator::CreateSafeUniqueObjectFileName( bool done; int cc = 0; char rpstr[100]; - sprintf(rpstr, "_p_"); + snprintf(rpstr, sizeof(rpstr), "_p_"); cmSystemTools::ReplaceString(ssin, "+", rpstr); std::string sssin = sin; do { @@ -3523,7 +3523,7 @@ std::string& cmLocalGenerator::CreateSafeUniqueObjectFileName( } sssin = ssin; cmSystemTools::ReplaceString(ssin, "_p_", rpstr); - sprintf(rpstr, "_p%d_", cc++); + snprintf(rpstr, sizeof(rpstr), "_p%d_", cc++); } while (!done); } @@ -4017,23 +4017,20 @@ std::string ComputeCustomCommandRuleFileName(cmLocalGenerator& lg, h.HashString(output).substr(0, 16)); } -cmSourceFile* AddCustomCommand( - cmLocalGenerator& lg, const cmListFileBacktrace& lfbt, - cmCommandOrigin origin, const std::vector<std::string>& outputs, - const std::vector<std::string>& byproducts, - const std::vector<std::string>& depends, const std::string& main_dependency, - const cmImplicitDependsList& implicit_depends, - const cmCustomCommandLines& commandLines, const char* comment, - const char* workingDir, bool replace, bool escapeOldStyle, - bool uses_terminal, bool command_expand_lists, const std::string& depfile, - const std::string& job_pool, bool stdPipesUTF8, - cmPolicies::PolicyStatus cmp0116) +cmSourceFile* AddCustomCommand(cmLocalGenerator& lg, cmCommandOrigin origin, + std::unique_ptr<cmCustomCommand> cc, + bool replace) { cmMakefile* mf = lg.GetMakefile(); + const auto& lfbt = cc->GetBacktrace(); + const auto& outputs = cc->GetOutputs(); + const auto& byproducts = cc->GetByproducts(); + const auto& commandLines = cc->GetCommandLines(); // Choose a source file on which to store the custom command. cmSourceFile* file = nullptr; - if (!commandLines.empty() && !main_dependency.empty()) { + if (!commandLines.empty() && cc->HasMainDependency()) { + const auto& main_dependency = cc->GetMainDependency(); // The main dependency was specified. Use it unless a different // custom command already used it. file = mf->GetSource(main_dependency); @@ -4083,29 +4080,14 @@ cmSourceFile* AddCustomCommand( // Attach the custom command to the file. if (file) { - // Construct a complete list of dependencies. - std::vector<std::string> depends2(depends); - if (!main_dependency.empty()) { - depends2.push_back(main_dependency); - } - - std::unique_ptr<cmCustomCommand> cc = cm::make_unique<cmCustomCommand>( - outputs, byproducts, depends2, commandLines, lfbt, comment, workingDir, - stdPipesUTF8); - cc->SetEscapeOldStyle(escapeOldStyle); cc->SetEscapeAllowMakeVars(true); - cc->SetImplicitDepends(implicit_depends); - cc->SetUsesTerminal(uses_terminal); - cc->SetCommandExpandLists(command_expand_lists); - cc->SetDepfile(depfile); - cc->SetJobPool(job_pool); - cc->SetCMP0116Status(cmp0116); - file->SetCustomCommand(std::move(cc)); lg.AddSourceOutputs(file, outputs, cmLocalGenerator::OutputRole::Primary, lfbt, origin); lg.AddSourceOutputs(file, byproducts, cmLocalGenerator::OutputRole::Byproduct, lfbt, origin); + + file->SetCustomCommand(std::move(cc)); } return file; } @@ -4134,63 +4116,38 @@ bool AnyTargetCommandOutputMatches( } namespace detail { -void AddCustomCommandToTarget(cmLocalGenerator& lg, - const cmListFileBacktrace& lfbt, - cmCommandOrigin origin, cmTarget* target, - const std::vector<std::string>& byproducts, - const std::vector<std::string>& depends, - const cmCustomCommandLines& commandLines, - cmCustomCommandType type, const char* comment, - const char* workingDir, bool escapeOldStyle, - bool uses_terminal, const std::string& depfile, - const std::string& job_pool, - bool command_expand_lists, bool stdPipesUTF8, - cmPolicies::PolicyStatus cmp0116) +void AddCustomCommandToTarget(cmLocalGenerator& lg, cmCommandOrigin origin, + cmTarget* target, cmCustomCommandType type, + std::unique_ptr<cmCustomCommand> cc) { // Add the command to the appropriate build step for the target. - std::vector<std::string> no_output; - cmCustomCommand cc(no_output, byproducts, depends, commandLines, lfbt, - comment, workingDir, stdPipesUTF8); - cc.SetEscapeOldStyle(escapeOldStyle); - cc.SetEscapeAllowMakeVars(true); - cc.SetUsesTerminal(uses_terminal); - cc.SetCommandExpandLists(command_expand_lists); - cc.SetDepfile(depfile); - cc.SetJobPool(job_pool); - cc.SetCMP0116Status(cmp0116); - cc.SetTarget(target->GetName()); + cc->SetEscapeAllowMakeVars(true); + cc->SetTarget(target->GetName()); + + lg.AddTargetByproducts(target, cc->GetByproducts(), cc->GetBacktrace(), + origin); + switch (type) { case cmCustomCommandType::PRE_BUILD: - target->AddPreBuildCommand(std::move(cc)); + target->AddPreBuildCommand(std::move(*cc)); break; case cmCustomCommandType::PRE_LINK: - target->AddPreLinkCommand(std::move(cc)); + target->AddPreLinkCommand(std::move(*cc)); break; case cmCustomCommandType::POST_BUILD: - target->AddPostBuildCommand(std::move(cc)); + target->AddPostBuildCommand(std::move(*cc)); break; } - lg.AddTargetByproducts(target, byproducts, lfbt, origin); + cc.reset(); } -cmSourceFile* AddCustomCommandToOutput( - cmLocalGenerator& lg, const cmListFileBacktrace& lfbt, - cmCommandOrigin origin, const std::vector<std::string>& outputs, - const std::vector<std::string>& byproducts, - const std::vector<std::string>& depends, const std::string& main_dependency, - const cmImplicitDependsList& implicit_depends, - const cmCustomCommandLines& commandLines, const char* comment, - const char* workingDir, bool replace, bool escapeOldStyle, - bool uses_terminal, bool command_expand_lists, const std::string& depfile, - const std::string& job_pool, bool stdPipesUTF8, - cmPolicies::PolicyStatus cmp0116) +cmSourceFile* AddCustomCommandToOutput(cmLocalGenerator& lg, + cmCommandOrigin origin, + std::unique_ptr<cmCustomCommand> cc, + bool replace) { - return AddCustomCommand(lg, lfbt, origin, outputs, byproducts, depends, - main_dependency, implicit_depends, commandLines, - comment, workingDir, replace, escapeOldStyle, - uses_terminal, command_expand_lists, depfile, - job_pool, stdPipesUTF8, cmp0116); + return AddCustomCommand(lg, origin, std::move(cc), replace); } void AppendCustomCommandToOutput(cmLocalGenerator& lg, @@ -4233,33 +4190,25 @@ void AppendCustomCommandToOutput(cmLocalGenerator& lg, lfbt); } -void AddUtilityCommand(cmLocalGenerator& lg, const cmListFileBacktrace& lfbt, - cmCommandOrigin origin, cmTarget* target, - const char* workingDir, - const std::vector<std::string>& byproducts, - const std::vector<std::string>& depends, - const cmCustomCommandLines& commandLines, - bool escapeOldStyle, const char* comment, - bool uses_terminal, bool command_expand_lists, - const std::string& job_pool, bool stdPipesUTF8, - cmPolicies::PolicyStatus cmp0116) +void AddUtilityCommand(cmLocalGenerator& lg, cmCommandOrigin origin, + cmTarget* target, std::unique_ptr<cmCustomCommand> cc) { + // They might be moved away + auto byproducts = cc->GetByproducts(); + auto lfbt = cc->GetBacktrace(); + // Use an empty comment to avoid generation of default comment. - if (!comment) { - comment = ""; + if (!cc->GetComment()) { + cc->SetComment(""); } // Create the generated symbolic output name of the utility target. std::string output = lg.CreateUtilityOutput(target->GetName(), byproducts, lfbt); + cc->SetOutputs(output); - std::string no_main_dependency; - cmImplicitDependsList no_implicit_depends; - cmSourceFile* rule = AddCustomCommand( - lg, lfbt, origin, { output }, byproducts, depends, no_main_dependency, - no_implicit_depends, commandLines, comment, workingDir, - /*replace=*/false, escapeOldStyle, uses_terminal, command_expand_lists, - /*depfile=*/"", job_pool, stdPipesUTF8, cmp0116); + cmSourceFile* rule = AddCustomCommand(lg, origin, std::move(cc), + /*replace=*/false); if (rule) { lg.AddTargetByproducts(target, byproducts, lfbt, origin); } |