diff options
Diffstat (limited to 'Source')
69 files changed, 1130 insertions, 717 deletions
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 3cf6c8f..5e2758a 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -260,6 +260,8 @@ set(SRCS cmInstallFilesGenerator.cxx cmInstallScriptGenerator.h cmInstallScriptGenerator.cxx + cmInstallSubdirectoryGenerator.h + cmInstallSubdirectoryGenerator.cxx cmInstallTargetGenerator.h cmInstallTargetGenerator.cxx cmInstallDirectoryGenerator.h diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 129c6fb..befdadd 100644 --- a/Source/CMakeVersion.cmake +++ b/Source/CMakeVersion.cmake @@ -1,5 +1,5 @@ # CMake version number components. set(CMake_VERSION_MAJOR 3) -set(CMake_VERSION_MINOR 12) -set(CMake_VERSION_PATCH 20181003) +set(CMake_VERSION_MINOR 13) +set(CMake_VERSION_PATCH 20181025) #set(CMake_VERSION_RC 1) diff --git a/Source/CTest/cmCTestScriptHandler.cxx b/Source/CTest/cmCTestScriptHandler.cxx index 6b62bb4..a87473d 100644 --- a/Source/CTest/cmCTestScriptHandler.cxx +++ b/Source/CTest/cmCTestScriptHandler.cxx @@ -563,7 +563,7 @@ int cmCTestScriptHandler::RunCurrentScript() // now that we have done most of the error checking finally run the // dashboard, we may be asked to repeatedly run this dashboard, such as - // for a continuous, do we ned to run it more than once? + // for a continuous, do we need to run it more than once? if (this->ContinuousDuration >= 0) { this->UpdateElapsedTime(); auto ending_time = diff --git a/Source/CTest/cmCTestSubmitHandler.cxx b/Source/CTest/cmCTestSubmitHandler.cxx index ecf309a..98872a5 100644 --- a/Source/CTest/cmCTestSubmitHandler.cxx +++ b/Source/CTest/cmCTestSubmitHandler.cxx @@ -12,6 +12,7 @@ #include <stdio.h> #include <stdlib.h> +#include "cmAlgorithms.h" #include "cmCTest.h" #include "cmCTestCurl.h" #include "cmCTestScriptHandler.h" @@ -55,6 +56,7 @@ public: std::string Filename; std::string MD5; std::string Message; + std::string BuildID; private: std::vector<char> CurrentValue; @@ -96,6 +98,8 @@ private: this->MD5 = this->GetCurrentValue(); } else if (name == "message") { this->Message = this->GetCurrentValue(); + } else if (name == "buildId") { + this->BuildID = this->GetCurrentValue(); } } }; @@ -152,10 +156,9 @@ void cmCTestSubmitHandler::Initialize() this->Files.clear(); } -bool cmCTestSubmitHandler::SubmitUsingFTP(const std::string& localprefix, - const std::set<std::string>& files, - const std::string& remoteprefix, - const std::string& url) +bool cmCTestSubmitHandler::SubmitUsingFTP( + const std::string& localprefix, const std::vector<std::string>& files, + const std::string& remoteprefix, const std::string& url) { CURL* curl; CURLcode res; @@ -299,10 +302,9 @@ bool cmCTestSubmitHandler::SubmitUsingFTP(const std::string& localprefix, } // Uploading files is simpler -bool cmCTestSubmitHandler::SubmitUsingHTTP(const std::string& localprefix, - const std::set<std::string>& files, - const std::string& remoteprefix, - const std::string& url) +bool cmCTestSubmitHandler::SubmitUsingHTTP( + const std::string& localprefix, const std::vector<std::string>& files, + const std::string& remoteprefix, const std::string& url) { CURL* curl; CURLcode res; @@ -465,6 +467,17 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP(const std::string& localprefix, cmSystemTools::ComputeFileHash(local_file, cmCryptoHash::AlgoMD5); } + // Generate Done.xml right before it is submitted. + // The reason for this is two-fold: + // 1) It must be generated after some other part has been submitted + // so we have a buildId to refer to in its contents. + // 2) By generating Done.xml here its timestamp will be as late as + // possible. This gives us a more accurate record of how long the + // entire build took to complete. + if (file == "Done.xml") { + this->CTest->GenerateDoneFile(); + } + if (!cmSystemTools::FileExists(local_file)) { cmCTestLog(this->CTest, ERROR_MESSAGE, " Cannot find file: " << local_file << std::endl); @@ -646,6 +659,7 @@ void cmCTestSubmitHandler::ParseResponse( " Submission failed: " << parser.Message << std::endl); return; } + this->CTest->SetBuildID(parser.BuildID); } output = cmSystemTools::UpperCase(output); if (output.find("WARNING") != std::string::npos) { @@ -662,9 +676,9 @@ void cmCTestSubmitHandler::ParseResponse( } } -bool cmCTestSubmitHandler::TriggerUsingHTTP(const std::set<std::string>& files, - const std::string& remoteprefix, - const std::string& url) +bool cmCTestSubmitHandler::TriggerUsingHTTP( + const std::vector<std::string>& files, const std::string& remoteprefix, + const std::string& url) { CURL* curl; char error_buffer[1024]; @@ -792,11 +806,10 @@ bool cmCTestSubmitHandler::TriggerUsingHTTP(const std::set<std::string>& files, return true; } -bool cmCTestSubmitHandler::SubmitUsingSCP(const std::string& scp_command, - const std::string& localprefix, - const std::set<std::string>& files, - const std::string& remoteprefix, - const std::string& url) +bool cmCTestSubmitHandler::SubmitUsingSCP( + const std::string& scp_command, const std::string& localprefix, + const std::vector<std::string>& files, const std::string& remoteprefix, + const std::string& url) { if (scp_command.empty() || localprefix.empty() || files.empty() || remoteprefix.empty() || url.empty()) { @@ -890,7 +903,7 @@ bool cmCTestSubmitHandler::SubmitUsingSCP(const std::string& scp_command, } bool cmCTestSubmitHandler::SubmitUsingCP(const std::string& localprefix, - const std::set<std::string>& files, + const std::vector<std::string>& files, const std::string& remoteprefix, const std::string& destination) { @@ -925,7 +938,7 @@ bool cmCTestSubmitHandler::SubmitUsingCP(const std::string& localprefix, #if defined(CTEST_USE_XMLRPC) bool cmCTestSubmitHandler::SubmitUsingXMLRPC( - const std::string& localprefix, const std::set<std::string>& files, + const std::string& localprefix, const std::vector<std::string>& files, const std::string& remoteprefix, const std::string& url) { xmlrpc_env env; @@ -1020,7 +1033,7 @@ bool cmCTestSubmitHandler::SubmitUsingXMLRPC( } #else bool cmCTestSubmitHandler::SubmitUsingXMLRPC( - std::string const& /*unused*/, std::set<std::string> const& /*unused*/, + std::string const& /*unused*/, std::vector<std::string> const& /*unused*/, std::string const& /*unused*/, std::string const& /*unused*/) { return false; @@ -1351,13 +1364,13 @@ int cmCTestSubmitHandler::ProcessHandler() cmGeneratedFileStream ofs; this->StartLogFile("Submit", ofs); - cmCTest::SetOfStrings files; + std::vector<std::string> files; std::string prefix = this->GetSubmitResultsPrefix(); if (!this->Files.empty()) { // Submit the explicitly selected files: // - files.insert(this->Files.begin(), this->Files.end()); + files.insert(files.end(), this->Files.begin(), this->Files.end()); } // Add to the list of files to submit from any selected, existing parts: @@ -1404,7 +1417,21 @@ int cmCTestSubmitHandler::ProcessHandler() // Submit files from this part. std::vector<std::string> const& pfiles = this->CTest->GetSubmitFiles(p); - files.insert(pfiles.begin(), pfiles.end()); + files.insert(files.end(), pfiles.begin(), pfiles.end()); + } + + // Make sure files are unique, but preserve order. + { + // This endPos intermediate is needed to work around non-conformant C++11 + // standard libraries that have erase(iterator,iterator) instead of + // erase(const_iterator,const_iterator). + size_t endPos = cmRemoveDuplicates(files) - files.cbegin(); + files.erase(files.begin() + endPos, files.end()); + } + + // Submit Done.xml last + if (this->SubmitPart[cmCTest::PartDone]) { + files.push_back("Done.xml"); } if (ofs) { diff --git a/Source/CTest/cmCTestSubmitHandler.h b/Source/CTest/cmCTestSubmitHandler.h index b4d0e77..66f2173 100644 --- a/Source/CTest/cmCTestSubmitHandler.h +++ b/Source/CTest/cmCTestSubmitHandler.h @@ -57,27 +57,27 @@ private: * Submit file using various ways */ bool SubmitUsingFTP(const std::string& localprefix, - const std::set<std::string>& files, + const std::vector<std::string>& files, const std::string& remoteprefix, const std::string& url); bool SubmitUsingHTTP(const std::string& localprefix, - const std::set<std::string>& files, + const std::vector<std::string>& files, const std::string& remoteprefix, const std::string& url); bool SubmitUsingSCP(const std::string& scp_command, const std::string& localprefix, - const std::set<std::string>& files, + const std::vector<std::string>& files, const std::string& remoteprefix, const std::string& url); bool SubmitUsingCP(const std::string& localprefix, - const std::set<std::string>& files, + const std::vector<std::string>& files, const std::string& remoteprefix, const std::string& url); - bool TriggerUsingHTTP(const std::set<std::string>& files, + bool TriggerUsingHTTP(const std::vector<std::string>& files, const std::string& remoteprefix, const std::string& url); bool SubmitUsingXMLRPC(const std::string& localprefix, - const std::set<std::string>& files, + const std::vector<std::string>& files, const std::string& remoteprefix, const std::string& url); diff --git a/Source/CTest/cmParseGTMCoverage.cxx b/Source/CTest/cmParseGTMCoverage.cxx index 822363d..0722753 100644 --- a/Source/CTest/cmParseGTMCoverage.cxx +++ b/Source/CTest/cmParseGTMCoverage.cxx @@ -1,5 +1,6 @@ #include "cmParseGTMCoverage.h" +#include "cmAlgorithms.h" #include "cmCTest.h" #include "cmCTestCoverageHandler.h" #include "cmSystemTools.h" @@ -86,6 +87,10 @@ bool cmParseGTMCoverage::ReadMCovFile(const char* file) } // Find the full path to the file bool found = this->FindMumpsFile(routine, filepath); + if (!found && cmHasLiteralSuffix(routine, "%")) { + routine.erase(0, 1); + found = this->FindMumpsFile(routine, filepath); + } if (found) { int lineoffset = 0; if (this->FindFunctionInMumpsFile(filepath, function, lineoffset)) { @@ -160,7 +165,7 @@ bool cmParseGTMCoverage::ParseMCOVLine(std::string const& line, { // this method parses lines from the .mcov file // each line has ^COVERAGE(...) in it, and there - // are several varients of coverage lines: + // are several variants of coverage lines: // // ^COVERAGE("DIC11","PR1",0)="2:0:0:0" // ( file , entry, line ) = "number_executed:timing_info" @@ -192,8 +197,8 @@ bool cmParseGTMCoverage::ParseMCOVLine(std::string const& line, done = true; } } else { - // all chars except ", (, and % get stored in the arg string - if (cur != '\"' && cur != '(' && cur != '%') { + // all chars except " and ( get stored in the arg string + if (cur != '\"' && cur != '(') { arg.append(1, line[pos]); } } diff --git a/Source/cmCMakePolicyCommand.cxx b/Source/cmCMakePolicyCommand.cxx index adf9ef8..3209ea5 100644 --- a/Source/cmCMakePolicyCommand.cxx +++ b/Source/cmCMakePolicyCommand.cxx @@ -46,6 +46,9 @@ bool cmCMakePolicyCommand::InitialPass(std::vector<std::string> const& args, if (args[0] == "VERSION") { return this->HandleVersionMode(args); } + if (args[0] == "GET_WARNING") { + return this->HandleGetWarningMode(args); + } std::ostringstream e; e << "given unknown first argument \"" << args[0] << "\""; @@ -181,3 +184,33 @@ bool cmCMakePolicyCommand::HandleVersionMode( this->Makefile->SetPolicyVersion(version_min, version_max); return true; } + +bool cmCMakePolicyCommand::HandleGetWarningMode( + std::vector<std::string> const& args) +{ + if (args.size() != 3) { + this->SetError( + "GET_WARNING must be given exactly 2 additional arguments."); + return false; + } + + // Get arguments. + std::string const& id = args[1]; + std::string const& var = args[2]; + + // Lookup the policy number. + cmPolicies::PolicyID pid; + if (!cmPolicies::GetPolicyID(id.c_str(), pid)) { + std::ostringstream e; + e << "GET_WARNING given policy \"" << id + << "\" which is not known to this version of CMake."; + this->SetError(e.str()); + return false; + } + + // Lookup the policy warning. + this->Makefile->AddDefinition(var, + cmPolicies::GetPolicyWarning(pid).c_str()); + + return true; +} diff --git a/Source/cmCMakePolicyCommand.h b/Source/cmCMakePolicyCommand.h index b18576c..cca1406 100644 --- a/Source/cmCMakePolicyCommand.h +++ b/Source/cmCMakePolicyCommand.h @@ -37,6 +37,7 @@ private: bool HandleSetMode(std::vector<std::string> const& args); bool HandleGetMode(std::vector<std::string> const& args); bool HandleVersionMode(std::vector<std::string> const& args); + bool HandleGetWarningMode(std::vector<std::string> const& args); }; #endif diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx index 908eea1..d0d5db6 100644 --- a/Source/cmCTest.cxx +++ b/Source/cmCTest.cxx @@ -294,6 +294,7 @@ cmCTest::cmCTest() this->SuppressUpdatingCTestConfiguration = false; this->DartVersion = 1; this->DropSiteCDash = false; + this->BuildID = ""; this->OutputTestOutputOnTestFailure = false; this->RepeatTests = 1; // default to run each test once this->RepeatUntilFail = false; @@ -320,6 +321,7 @@ cmCTest::cmCTest() this->Parts[PartNotes].SetName("Notes"); this->Parts[PartExtraFiles].SetName("ExtraFiles"); this->Parts[PartUpload].SetName("Upload"); + this->Parts[PartDone].SetName("Done"); // Fill the part name-to-id map. for (Part p = PartStart; p != PartCount; p = Part(p + 1)) { @@ -612,6 +614,7 @@ bool cmCTest::InitializeFromCommand(cmCTestStartCommand* command) std::string bld_dir = this->GetCTestConfiguration("BuildDirectory"); this->DartVersion = 1; this->DropSiteCDash = false; + this->BuildID = ""; for (Part p = PartStart; p != PartCount; p = Part(p + 1)) { this->Parts[p].SubmitFiles.clear(); } @@ -1565,6 +1568,24 @@ int cmCTest::GenerateNotesFile(const char* cfiles) return this->GenerateNotesFile(files); } +int cmCTest::GenerateDoneFile() +{ + cmGeneratedFileStream ofs; + if (!this->OpenOutputFile(this->CurrentTag, "Done.xml", ofs)) { + cmCTestLog(this, ERROR_MESSAGE, "Cannot open done file" << std::endl); + return 1; + } + cmXMLWriter xml(ofs); + xml.StartDocument(); + xml.StartElement("Done"); + xml.Element("buildId", this->BuildID); + xml.Element("time", std::chrono::system_clock::now()); + xml.EndElement(); // Done + xml.EndDocument(); + + return 0; +} + std::string cmCTest::Base64GzipEncodeFile(std::string const& file) { std::string tarFile = file + "_temp.tar.gz"; diff --git a/Source/cmCTest.h b/Source/cmCTest.h index 345b538..1ee002a 100644 --- a/Source/cmCTest.h +++ b/Source/cmCTest.h @@ -50,6 +50,7 @@ public: PartNotes, PartExtraFiles, PartUpload, + PartDone, PartCount // Update names in constructor when adding a part }; @@ -373,6 +374,9 @@ public: /** Create XML file that contains all the notes specified */ int GenerateNotesFile(const VectorOfStrings& files); + /** Create XML file to indicate that build is complete */ + int GenerateDoneFile(); + /** Submit extra files to the server */ bool SubmitExtraFiles(const char* files); bool SubmitExtraFiles(const VectorOfStrings& files); @@ -405,6 +409,10 @@ public: int GetDartVersion() { return this->DartVersion; } int GetDropSiteCDash() { return this->DropSiteCDash; } + /** The Build ID is assigned by CDash */ + void SetBuildID(const std::string& id) { this->BuildID = id; } + std::string GetBuildID() { return this->BuildID; } + /** Add file to be submitted */ void AddSubmitFile(Part part, const char* name); std::vector<std::string> const& GetSubmitFiles(Part part) @@ -607,6 +615,8 @@ private: int DartVersion; bool DropSiteCDash; + std::string BuildID; + std::vector<std::string> InitialCommandLineArguments; int SubmitIndex; diff --git a/Source/cmComputeComponentGraph.cxx b/Source/cmComputeComponentGraph.cxx index a7dc1ca..5820df6 100644 --- a/Source/cmComputeComponentGraph.cxx +++ b/Source/cmComputeComponentGraph.cxx @@ -125,8 +125,8 @@ void cmComputeComponentGraph::TransferEdges() if (i_component != j_component) { // We do not attempt to combine duplicate edges, but instead // store the inter-component edges with suitable multiplicity. - this->ComponentGraph[i_component].emplace_back(j_component, - ni.IsStrong()); + this->ComponentGraph[i_component].emplace_back( + j_component, ni.IsStrong(), ni.GetBacktrace()); } } } diff --git a/Source/cmComputeLinkDepends.cxx b/Source/cmComputeLinkDepends.cxx index aa17de6..4717cf6 100644 --- a/Source/cmComputeLinkDepends.cxx +++ b/Source/cmComputeLinkDepends.cxx @@ -6,6 +6,7 @@ #include "cmComputeComponentGraph.h" #include "cmGeneratorTarget.h" #include "cmGlobalGenerator.h" +#include "cmListFileCache.h" #include "cmLocalGenerator.h" #include "cmMakefile.h" #include "cmStateTypes.h" @@ -419,7 +420,8 @@ void cmComputeLinkDepends::HandleSharedDependency(SharedDepEntry const& dep) // This shared library dependency must follow the item that listed // it. - this->EntryConstraintGraph[dep.DependerIndex].push_back(index); + this->EntryConstraintGraph[dep.DependerIndex].emplace_back( + index, true, cmListFileBacktrace()); // Target items may have their own dependencies. if (entry.Target) { @@ -522,7 +524,8 @@ void cmComputeLinkDepends::AddLinkEntries(int depender_index, // The dependee must come after the depender. if (depender_index >= 0) { - this->EntryConstraintGraph[depender_index].push_back(dependee_index); + this->EntryConstraintGraph[depender_index].emplace_back( + dependee_index, false, cmListFileBacktrace()); } else { // This is a direct dependency of the target being linked. this->OriginalEntries.push_back(dependee_index); @@ -565,7 +568,7 @@ cmLinkItem cmComputeLinkDepends::ResolveLinkItem(int depender_index, from = depender; } } - return from->ResolveLinkItem(name); + return from->ResolveLinkItem(name, cmListFileBacktrace()); } void cmComputeLinkDepends::InferDependencies() @@ -594,7 +597,10 @@ void cmComputeLinkDepends::InferDependencies() // Add the inferred dependencies to the graph. cmGraphEdgeList& edges = this->EntryConstraintGraph[depender_index]; - edges.insert(edges.end(), common.begin(), common.end()); + edges.reserve(edges.size() + common.size()); + for (auto const& c : common) { + edges.emplace_back(c, true, cmListFileBacktrace()); + } } } diff --git a/Source/cmComputeTargetDepends.cxx b/Source/cmComputeTargetDepends.cxx index 268e749..f8ac333 100644 --- a/Source/cmComputeTargetDepends.cxx +++ b/Source/cmComputeTargetDepends.cxx @@ -6,6 +6,7 @@ #include "cmGeneratorTarget.h" #include "cmGlobalGenerator.h" #include "cmLinkItem.h" +#include "cmListFileCache.h" #include "cmLocalGenerator.h" #include "cmMakefile.h" #include "cmPolicies.h" @@ -22,8 +23,6 @@ #include <stdio.h> #include <utility> -class cmListFileBacktrace; - /* This class is meant to analyze inter-target dependencies globally @@ -152,6 +151,7 @@ void cmComputeTargetDepends::GetTargetDirectDepends(cmGeneratorTarget const* t, cmGeneratorTarget const* dep = this->Targets[ni]; cmTargetDependSet::iterator di = deps.insert(dep).first; di->SetType(ni.IsStrong()); + di->SetBacktrace(ni.GetBacktrace()); } } @@ -208,7 +208,8 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index) for (cmSourceFile const* o : objectFiles) { std::string const& objLib = o->GetObjectLibrary(); if (!objLib.empty()) { - cmLinkItem const& objItem = depender->ResolveLinkItem(objLib); + cmLinkItem const& objItem = + depender->ResolveLinkItem(objLib, cmListFileBacktrace()); if (emitted.insert(objItem).second) { if (depender->GetType() != cmStateEnums::EXECUTABLE && depender->GetType() != cmStateEnums::STATIC_LIBRARY && @@ -230,7 +231,7 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index) cmLinkImplementation const* impl = depender->GetLinkImplementation(it); // A target should not depend on itself. - emitted.insert(cmLinkItem(depender)); + emitted.insert(cmLinkItem(depender, cmListFileBacktrace())); for (cmLinkImplItem const& lib : impl->Libraries) { // Don't emit the same library twice for this target. if (emitted.insert(lib).second) { @@ -246,7 +247,7 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index) std::set<cmLinkItem> const& tutils = depender->GetUtilityItems(); std::set<cmLinkItem> emitted; // A target should not depend on itself. - emitted.insert(cmLinkItem(depender)); + emitted.insert(cmLinkItem(depender, cmListFileBacktrace())); for (cmLinkItem const& litem : tutils) { // Don't emit the same utility twice for this target. if (emitted.insert(litem).second) { @@ -258,7 +259,8 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index) void cmComputeTargetDepends::AddInterfaceDepends( int depender_index, const cmGeneratorTarget* dependee, - const std::string& config, std::set<cmLinkItem>& emitted) + cmListFileBacktrace const& dependee_backtrace, const std::string& config, + std::set<cmLinkItem>& emitted) { cmGeneratorTarget const* depender = this->Targets[depender_index]; if (cmLinkInterface const* iface = @@ -266,8 +268,13 @@ void cmComputeTargetDepends::AddInterfaceDepends( for (cmLinkItem const& lib : iface->Libraries) { // Don't emit the same library twice for this target. if (emitted.insert(lib).second) { - this->AddTargetDepend(depender_index, lib, true); - this->AddInterfaceDepends(depender_index, lib, config, emitted); + // Inject the backtrace of the original link dependency whose + // link interface we are adding. This indicates the line of + // code in the project that caused this dependency to be added. + cmLinkItem libBT = lib; + libBT.Backtrace = dependee_backtrace; + this->AddTargetDepend(depender_index, libBT, true); + this->AddInterfaceDepends(depender_index, libBT, config, emitted); } } } @@ -289,8 +296,9 @@ void cmComputeTargetDepends::AddInterfaceDepends( if (dependee) { // A target should not depend on itself. - emitted.insert(cmLinkItem(depender)); - this->AddInterfaceDepends(depender_index, dependee, config, emitted); + emitted.insert(cmLinkItem(depender, cmListFileBacktrace())); + this->AddInterfaceDepends(depender_index, dependee, + dependee_name.Backtrace, config, emitted); } } @@ -327,13 +335,7 @@ void cmComputeTargetDepends::AddTargetDepend(int depender_index, e << "The dependency target \"" << dependee_name << "\" of target \"" << depender->GetName() << "\" does not exist."; - cmListFileBacktrace const* backtrace = - depender->GetUtilityBacktrace(dependee_name.AsStr()); - if (backtrace) { - cm->IssueMessage(messageType, e.str(), *backtrace); - } else { - cm->IssueMessage(messageType, e.str()); - } + cm->IssueMessage(messageType, e.str(), dependee_name.Backtrace); } } @@ -346,13 +348,14 @@ void cmComputeTargetDepends::AddTargetDepend(int depender_index, } if (dependee) { - this->AddTargetDepend(depender_index, dependee, linking); + this->AddTargetDepend(depender_index, dependee, dependee_name.Backtrace, + linking); } } -void cmComputeTargetDepends::AddTargetDepend(int depender_index, - const cmGeneratorTarget* dependee, - bool linking) +void cmComputeTargetDepends::AddTargetDepend( + int depender_index, cmGeneratorTarget const* dependee, + cmListFileBacktrace const& dependee_backtrace, bool linking) { if (dependee->IsImported() || dependee->GetType() == cmStateEnums::INTERFACE_LIBRARY) { @@ -361,7 +364,8 @@ void cmComputeTargetDepends::AddTargetDepend(int depender_index, std::set<cmLinkItem> const& utils = dependee->GetUtilityItems(); for (cmLinkItem const& i : utils) { if (cmGeneratorTarget const* transitive_dependee = i.Target) { - this->AddTargetDepend(depender_index, transitive_dependee, false); + this->AddTargetDepend(depender_index, transitive_dependee, i.Backtrace, + false); } } } else { @@ -373,7 +377,8 @@ void cmComputeTargetDepends::AddTargetDepend(int depender_index, int dependee_index = tii->second; // Add this entry to the dependency graph. - this->InitialGraph[depender_index].emplace_back(dependee_index, !linking); + this->InitialGraph[depender_index].emplace_back(dependee_index, !linking, + dependee_backtrace); } } @@ -507,7 +512,7 @@ bool cmComputeTargetDepends::IntraComponent(std::vector<int> const& cmap, for (cmGraphEdge const& edge : el) { int j = edge; if (cmap[j] == c && edge.IsStrong()) { - this->FinalGraph[i].emplace_back(j, true); + this->FinalGraph[i].emplace_back(j, true, edge.GetBacktrace()); if (!this->IntraComponent(cmap, c, j, head, emitted, visited)) { return false; } @@ -516,7 +521,7 @@ bool cmComputeTargetDepends::IntraComponent(std::vector<int> const& cmap, // Prepend to a linear linked-list of intra-component edges. if (*head >= 0) { - this->FinalGraph[i].emplace_back(*head, false); + this->FinalGraph[i].emplace_back(*head, false, cmListFileBacktrace()); } else { this->ComponentTail[c] = i; } @@ -567,7 +572,7 @@ bool cmComputeTargetDepends::ComputeFinalDepends( int dependee_component = ni; int dependee_component_head = this->ComponentHead[dependee_component]; this->FinalGraph[depender_component_tail].emplace_back( - dependee_component_head, ni.IsStrong()); + dependee_component_head, ni.IsStrong(), ni.GetBacktrace()); } } return true; diff --git a/Source/cmComputeTargetDepends.h b/Source/cmComputeTargetDepends.h index 3046e8a..3840bd7 100644 --- a/Source/cmComputeTargetDepends.h +++ b/Source/cmComputeTargetDepends.h @@ -6,6 +6,7 @@ #include "cmConfigure.h" // IWYU pragma: keep #include "cmGraphAdjacencyList.h" +#include "cmListFileCache.h" #include <map> #include <set> @@ -47,6 +48,7 @@ private: void AddTargetDepend(int depender_index, cmLinkItem const& dependee_name, bool linking); void AddTargetDepend(int depender_index, cmGeneratorTarget const* dependee, + cmListFileBacktrace const& dependee_backtrace, bool linking); bool ComputeFinalDepends(cmComputeComponentGraph const& ccg); void AddInterfaceDepends(int depender_index, cmLinkItem const& dependee_name, @@ -54,6 +56,7 @@ private: std::set<cmLinkItem>& emitted); void AddInterfaceDepends(int depender_index, cmGeneratorTarget const* dependee, + cmListFileBacktrace const& dependee_backtrace, const std::string& config, std::set<cmLinkItem>& emitted); cmGlobalGenerator* GlobalGenerator; diff --git a/Source/cmCustomCommand.cxx b/Source/cmCustomCommand.cxx index cfd260c..e87eb1e 100644 --- a/Source/cmCustomCommand.cxx +++ b/Source/cmCustomCommand.cxx @@ -4,16 +4,6 @@ #include "cmMakefile.h" -cmCustomCommand::cmCustomCommand() - : Backtrace() -{ - this->HaveComment = false; - this->EscapeOldStyle = true; - this->EscapeAllowMakeVars = false; - this->UsesTerminal = false; - this->CommandExpandLists = false; -} - cmCustomCommand::cmCustomCommand(cmMakefile const* mf, const std::vector<std::string>& outputs, const std::vector<std::string>& byproducts, diff --git a/Source/cmCustomCommand.h b/Source/cmCustomCommand.h index 9e82f25..d82160b 100644 --- a/Source/cmCustomCommand.h +++ b/Source/cmCustomCommand.h @@ -22,9 +22,6 @@ class cmMakefile; class cmCustomCommand { public: - /** Default and copy constructors for STL containers. */ - cmCustomCommand(); - /** Main constructor specifies all information for the command. */ cmCustomCommand(cmMakefile const* mf, const std::vector<std::string>& outputs, @@ -103,11 +100,11 @@ private: std::string Comment; std::string WorkingDirectory; std::string Depfile; - bool HaveComment; - bool EscapeAllowMakeVars; - bool EscapeOldStyle; - bool UsesTerminal; - bool CommandExpandLists; + bool HaveComment = false; + bool EscapeAllowMakeVars = false; + bool EscapeOldStyle = true; + bool UsesTerminal = false; + bool CommandExpandLists = false; }; #endif diff --git a/Source/cmExtraSublimeTextGenerator.cxx b/Source/cmExtraSublimeTextGenerator.cxx index c4cca07..882d39f 100644 --- a/Source/cmExtraSublimeTextGenerator.cxx +++ b/Source/cmExtraSublimeTextGenerator.cxx @@ -384,13 +384,8 @@ std::string cmExtraSublimeTextGenerator::ComputeDefines( cmGeneratorExpressionInterpreter genexInterpreter(lg, config, target, language); - // Add the export symbol definition for shared library objects. - if (const char* exportMacro = target->GetExportMacro()) { - lg->AppendDefines(defines, exportMacro); - } - // Add preprocessor definitions for this target and configuration. - lg->AddCompileDefinitions(defines, target, config, language); + lg->GetTargetDefines(target, config, language, defines); const std::string COMPILE_DEFINITIONS("COMPILE_DEFINITIONS"); if (const char* compile_defs = source->GetProperty(COMPILE_DEFINITIONS)) { lg->AppendDefines( diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index 80fb621..b8c9598 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -439,7 +439,7 @@ static void handleSystemIncludesDep( KindedSources const& kinded = this->GetKindedSources(config); \ for (SourceAndKind const& s : kinded.Sources) { \ if (s.Kind == KIND) { \ - data.push_back(s.Source); \ + data.push_back(s.Source.Value); \ } \ } \ } @@ -674,13 +674,13 @@ std::set<cmLinkItem> const& cmGeneratorTarget::GetUtilityItems() const { if (!this->UtilityItemsDone) { this->UtilityItemsDone = true; - std::set<std::string> const& utilities = this->GetUtilities(); - for (std::string const& i : utilities) { + std::set<BT<std::string>> const& utilities = this->GetUtilities(); + for (BT<std::string> const& i : utilities) { if (cmGeneratorTarget* gt = - this->LocalGenerator->FindGeneratorTargetToUse(i)) { - this->UtilityItems.insert(cmLinkItem(gt)); + this->LocalGenerator->FindGeneratorTargetToUse(i.Value)) { + this->UtilityItems.insert(cmLinkItem(gt, i.Backtrace)); } else { - this->UtilityItems.insert(cmLinkItem(i)); + this->UtilityItems.insert(cmLinkItem(i.Value, i.Backtrace)); } } } @@ -865,7 +865,8 @@ static void AddObjectEntries( static bool processSources( cmGeneratorTarget const* tgt, const std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries, - std::vector<std::string>& srcs, std::unordered_set<std::string>& uniqueSrcs, + std::vector<BT<std::string>>& srcs, + std::unordered_set<std::string>& uniqueSrcs, cmGeneratorExpressionDAGChecker* dagChecker, std::string const& config, bool debugSources) { @@ -916,7 +917,7 @@ static bool processSources( std::string usedSources; for (std::string const& src : entrySources) { if (uniqueSrcs.insert(src).second) { - srcs.push_back(src); + srcs.emplace_back(src, entry->ge->GetBacktrace()); if (debugSources) { usedSources += " * " + src + "\n"; } @@ -933,9 +934,10 @@ static bool processSources( return contextDependent; } -void cmGeneratorTarget::GetSourceFiles(std::vector<std::string>& files, - const std::string& config) const +std::vector<BT<std::string>> cmGeneratorTarget::GetSourceFilePaths( + std::string const& config) const { + std::vector<BT<std::string>> files; assert(this->GetType() != cmStateEnums::INTERFACE_LIBRARY); if (!this->LocalGenerator->GetGlobalGenerator()->GetConfigureDoneCMP0026()) { @@ -957,7 +959,7 @@ void cmGeneratorTarget::GetSourceFiles(std::vector<std::string>& files, files.push_back(item); } } - return; + return files; } std::vector<std::string> debugProperties; @@ -1009,11 +1011,23 @@ void cmGeneratorTarget::GetSourceFiles(std::vector<std::string>& files, cmDeleteAll(linkInterfaceSourcesEntries); cmDeleteAll(linkObjectsEntries); + return files; } void cmGeneratorTarget::GetSourceFiles(std::vector<cmSourceFile*>& files, const std::string& config) const { + std::vector<BT<cmSourceFile*>> tmp = this->GetSourceFiles(config); + files.reserve(tmp.size()); + for (BT<cmSourceFile*>& v : tmp) { + files.push_back(v.Value); + } +} + +std::vector<BT<cmSourceFile*>> cmGeneratorTarget::GetSourceFiles( + std::string const& config) const +{ + std::vector<BT<cmSourceFile*>> files; if (!this->GlobalGenerator->GetConfigureDoneCMP0026()) { // Since we are still configuring not all sources may exist yet, // so we need to avoid full source classification because that @@ -1021,16 +1035,15 @@ void cmGeneratorTarget::GetSourceFiles(std::vector<cmSourceFile*>& files, // Since this is only for compatibility with old policies that // projects should not depend on anymore, just compute the files // without memoizing them. - std::vector<std::string> srcs; - this->GetSourceFiles(srcs, config); + std::vector<BT<std::string>> srcs = this->GetSourceFilePaths(config); std::set<cmSourceFile*> emitted; - for (std::string const& s : srcs) { - cmSourceFile* sf = this->Makefile->GetOrCreateSource(s); + for (BT<std::string> const& s : srcs) { + cmSourceFile* sf = this->Makefile->GetOrCreateSource(s.Value); if (emitted.insert(sf).second) { - files.push_back(sf); + files.emplace_back(sf, s.Backtrace); } } - return; + return files; } KindedSources const& kinded = this->GetKindedSources(config); @@ -1038,18 +1051,33 @@ void cmGeneratorTarget::GetSourceFiles(std::vector<cmSourceFile*>& files, for (SourceAndKind const& si : kinded.Sources) { files.push_back(si.Source); } + return files; } void cmGeneratorTarget::GetSourceFilesWithoutObjectLibraries( std::vector<cmSourceFile*>& files, const std::string& config) const { + std::vector<BT<cmSourceFile*>> tmp = + this->GetSourceFilesWithoutObjectLibraries(config); + files.reserve(tmp.size()); + for (BT<cmSourceFile*>& v : tmp) { + files.push_back(v.Value); + } +} + +std::vector<BT<cmSourceFile*>> +cmGeneratorTarget::GetSourceFilesWithoutObjectLibraries( + std::string const& config) const +{ + std::vector<BT<cmSourceFile*>> files; KindedSources const& kinded = this->GetKindedSources(config); files.reserve(kinded.Sources.size()); for (SourceAndKind const& si : kinded.Sources) { - if (si.Source->GetObjectLibrary().empty()) { + if (si.Source.Value->GetObjectLibrary().empty()) { files.push_back(si.Source); } } + return files; } cmGeneratorTarget::KindedSources const& cmGeneratorTarget::GetKindedSources( @@ -1089,16 +1117,15 @@ void cmGeneratorTarget::ComputeKindedSources(KindedSources& files, std::string const& config) const { // Get the source file paths by string. - std::vector<std::string> srcs; - this->GetSourceFiles(srcs, config); + std::vector<BT<std::string>> srcs = this->GetSourceFilePaths(config); cmsys::RegularExpression header_regex(CM_HEADER_REGEX); std::vector<cmSourceFile*> badObjLib; std::set<cmSourceFile*> emitted; - for (std::string const& s : srcs) { + for (BT<std::string> const& s : srcs) { // Create each source at most once. - cmSourceFile* sf = this->Makefile->GetOrCreateSource(s); + cmSourceFile* sf = this->Makefile->GetOrCreateSource(s.Value); if (!emitted.insert(sf).second) { continue; } @@ -1161,7 +1188,7 @@ void cmGeneratorTarget::ComputeKindedSources(KindedSources& files, } // Save this classified source file in the result vector. - files.Sources.push_back({ sf, kind }); + files.Sources.push_back({ BT<cmSourceFile*>(sf, s.Backtrace), kind }); } if (!badObjLib.empty()) { @@ -1197,14 +1224,14 @@ void cmGeneratorTarget::ComputeAllConfigSources() const KindedSources const& sources = this->GetKindedSources(configs[ci]); for (SourceAndKind const& src : sources.Sources) { std::map<cmSourceFile const*, size_t>::iterator mi = - index.find(src.Source); + index.find(src.Source.Value); if (mi == index.end()) { AllConfigSource acs; - acs.Source = src.Source; + acs.Source = src.Source.Value; acs.Kind = src.Kind; this->AllConfigSources.push_back(std::move(acs)); std::map<cmSourceFile const*, size_t>::value_type entry( - src.Source, this->AllConfigSources.size() - 1); + src.Source.Value, this->AllConfigSources.size() - 1); mi = index.insert(entry).first; } this->AllConfigSources[mi->second].Configs.push_back(ci); @@ -1710,17 +1737,11 @@ cmListFileBacktrace cmGeneratorTarget::GetBacktrace() const return this->Target->GetBacktrace(); } -const std::set<std::string>& cmGeneratorTarget::GetUtilities() const +const std::set<BT<std::string>>& cmGeneratorTarget::GetUtilities() const { return this->Target->GetUtilities(); } -const cmListFileBacktrace* cmGeneratorTarget::GetUtilityBacktrace( - const std::string& u) const -{ - return this->Target->GetUtilityBacktrace(u); -} - bool cmGeneratorTarget::HaveWellDefinedOutputFiles() const { return this->GetType() == cmStateEnums::STATIC_LIBRARY || @@ -1730,7 +1751,7 @@ bool cmGeneratorTarget::HaveWellDefinedOutputFiles() const this->GetType() == cmStateEnums::EXECUTABLE; } -const char* cmGeneratorTarget::GetExportMacro() const +const std::string* cmGeneratorTarget::GetExportMacro() const { // Define the symbol for targets that export symbols. if (this->GetType() == cmStateEnums::SHARED_LIBRARY || @@ -1743,7 +1764,7 @@ const char* cmGeneratorTarget::GetExportMacro() const in += "_EXPORTS"; this->ExportMacro = cmSystemTools::MakeCidentifier(in); } - return this->ExportMacro.c_str(); + return &this->ExportMacro; } return nullptr; } @@ -2480,7 +2501,7 @@ std::string cmGeneratorTarget::GetCreateRuleVariable( static void processIncludeDirectories( cmGeneratorTarget const* tgt, const std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries, - std::vector<std::string>& includes, + std::vector<BT<std::string>>& includes, std::unordered_set<std::string>& uniqueIncludes, cmGeneratorExpressionDAGChecker* dagChecker, const std::string& config, bool debugIncludes, const std::string& language) @@ -2572,7 +2593,7 @@ static void processIncludeDirectories( std::string inc = entryInclude; if (uniqueIncludes.insert(inc).second) { - includes.push_back(inc); + includes.emplace_back(inc, entry->ge->GetBacktrace()); if (debugIncludes) { usedIncludes += " * " + inc + "\n"; } @@ -2588,10 +2609,10 @@ static void processIncludeDirectories( } } -std::vector<std::string> cmGeneratorTarget::GetIncludeDirectories( +std::vector<BT<std::string>> cmGeneratorTarget::GetIncludeDirectories( const std::string& config, const std::string& lang) const { - std::vector<std::string> includes; + std::vector<BT<std::string>> includes; std::unordered_set<std::string> uniqueIncludes; cmGeneratorExpressionDAGChecker dagChecker(this, "INCLUDE_DIRECTORIES", @@ -2661,7 +2682,7 @@ enum class OptionsParse static void processOptionsInternal( cmGeneratorTarget const* tgt, const std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries, - std::vector<std::string>& options, + std::vector<BT<std::string>>& options, std::unordered_set<std::string>& uniqueOptions, cmGeneratorExpressionDAGChecker* dagChecker, const std::string& config, bool debugOptions, const char* logName, std::string const& language, @@ -2678,9 +2699,13 @@ static void processOptionsInternal( if (uniqueOptions.insert(opt).second) { if (parse == OptionsParse::Shell && cmHasLiteralPrefix(opt, "SHELL:")) { - cmSystemTools::ParseUnixCommandLine(opt.c_str() + 6, options); + std::vector<std::string> tmp; + cmSystemTools::ParseUnixCommandLine(opt.c_str() + 6, tmp); + for (std::string& o : tmp) { + options.emplace_back(std::move(o), entry->ge->GetBacktrace()); + } } else { - options.push_back(opt); + options.emplace_back(opt, entry->ge->GetBacktrace()); } if (debugOptions) { usedOptions += " * " + opt + "\n"; @@ -2700,7 +2725,7 @@ static void processOptionsInternal( static void processCompileOptions( cmGeneratorTarget const* tgt, const std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries, - std::vector<std::string>& options, + std::vector<BT<std::string>>& options, std::unordered_set<std::string>& uniqueOptions, cmGeneratorExpressionDAGChecker* dagChecker, const std::string& config, bool debugOptions, std::string const& language) @@ -2714,6 +2739,17 @@ void cmGeneratorTarget::GetCompileOptions(std::vector<std::string>& result, const std::string& config, const std::string& language) const { + std::vector<BT<std::string>> tmp = this->GetCompileOptions(config, language); + result.reserve(tmp.size()); + for (BT<std::string>& v : tmp) { + result.emplace_back(std::move(v.Value)); + } +} + +std::vector<BT<std::string>> cmGeneratorTarget::GetCompileOptions( + std::string const& config, std::string const& language) const +{ + std::vector<BT<std::string>> result; std::unordered_set<std::string> uniqueOptions; cmGeneratorExpressionDAGChecker dagChecker(this, "COMPILE_OPTIONS", nullptr, @@ -2749,12 +2785,13 @@ void cmGeneratorTarget::GetCompileOptions(std::vector<std::string>& result, language); cmDeleteAll(linkInterfaceCompileOptionsEntries); + return result; } static void processCompileFeatures( cmGeneratorTarget const* tgt, const std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries, - std::vector<std::string>& options, + std::vector<BT<std::string>>& options, std::unordered_set<std::string>& uniqueOptions, cmGeneratorExpressionDAGChecker* dagChecker, const std::string& config, bool debugOptions) @@ -2767,6 +2804,17 @@ static void processCompileFeatures( void cmGeneratorTarget::GetCompileFeatures(std::vector<std::string>& result, const std::string& config) const { + std::vector<BT<std::string>> tmp = this->GetCompileFeatures(config); + result.reserve(tmp.size()); + for (BT<std::string>& v : tmp) { + result.emplace_back(std::move(v.Value)); + } +} + +std::vector<BT<std::string>> cmGeneratorTarget::GetCompileFeatures( + std::string const& config) const +{ + std::vector<BT<std::string>> result; std::unordered_set<std::string> uniqueFeatures; cmGeneratorExpressionDAGChecker dagChecker(this, "COMPILE_FEATURES", nullptr, @@ -2799,12 +2847,13 @@ void cmGeneratorTarget::GetCompileFeatures(std::vector<std::string>& result, uniqueFeatures, &dagChecker, config, debugFeatures); cmDeleteAll(linkInterfaceCompileFeaturesEntries); + return result; } static void processCompileDefinitions( cmGeneratorTarget const* tgt, const std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries, - std::vector<std::string>& options, + std::vector<BT<std::string>>& options, std::unordered_set<std::string>& uniqueOptions, cmGeneratorExpressionDAGChecker* dagChecker, const std::string& config, bool debugOptions, std::string const& language) @@ -2815,9 +2864,21 @@ static void processCompileDefinitions( } void cmGeneratorTarget::GetCompileDefinitions( - std::vector<std::string>& list, const std::string& config, + std::vector<std::string>& result, const std::string& config, const std::string& language) const { + std::vector<BT<std::string>> tmp = + this->GetCompileDefinitions(config, language); + result.reserve(tmp.size()); + for (BT<std::string>& v : tmp) { + result.emplace_back(std::move(v.Value)); + } +} + +std::vector<BT<std::string>> cmGeneratorTarget::GetCompileDefinitions( + std::string const& config, std::string const& language) const +{ + std::vector<BT<std::string>> list; std::unordered_set<std::string> uniqueOptions; cmGeneratorExpressionDAGChecker dagChecker(this, "COMPILE_DEFINITIONS", @@ -2878,13 +2939,14 @@ void cmGeneratorTarget::GetCompileDefinitions( language); cmDeleteAll(linkInterfaceCompileDefinitionsEntries); + return list; } namespace { void processLinkOptions( cmGeneratorTarget const* tgt, const std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries, - std::vector<std::string>& options, + std::vector<BT<std::string>>& options, std::unordered_set<std::string>& uniqueOptions, cmGeneratorExpressionDAGChecker* dagChecker, const std::string& config, bool debugOptions, std::string const& language) @@ -2899,6 +2961,17 @@ void cmGeneratorTarget::GetLinkOptions(std::vector<std::string>& result, const std::string& config, const std::string& language) const { + std::vector<BT<std::string>> tmp = this->GetLinkOptions(config, language); + result.reserve(tmp.size()); + for (BT<std::string>& v : tmp) { + result.emplace_back(std::move(v.Value)); + } +} + +std::vector<BT<std::string>> cmGeneratorTarget::GetLinkOptions( + std::string const& config, std::string const& language) const +{ + std::vector<BT<std::string>> result; std::unordered_set<std::string> uniqueOptions; cmGeneratorExpressionDAGChecker dagChecker(this, "LINK_OPTIONS", nullptr, @@ -2952,21 +3025,24 @@ void cmGeneratorTarget::GetLinkOptions(std::vector<std::string>& result, const std::string SHELL{ "SHELL:" }; const std::string LINKER_SHELL = LINKER + SHELL; - std::vector<std::string>::iterator entry; + std::vector<BT<std::string>>::iterator entry; while ((entry = std::find_if(result.begin(), result.end(), - [&LINKER](const std::string& item) -> bool { - return item.compare(0, LINKER.length(), - LINKER) == 0; + [&LINKER](BT<std::string> const& item) -> bool { + return item.Value.compare(0, LINKER.length(), + LINKER) == 0; })) != result.end()) { + std::string value = std::move(entry->Value); + cmListFileBacktrace bt = std::move(entry->Backtrace); + entry = result.erase(entry); + std::vector<std::string> linkerOptions; - if (entry->compare(0, LINKER_SHELL.length(), LINKER_SHELL) == 0) { + if (value.compare(0, LINKER_SHELL.length(), LINKER_SHELL) == 0) { cmSystemTools::ParseUnixCommandLine( - entry->c_str() + LINKER_SHELL.length(), linkerOptions); + value.c_str() + LINKER_SHELL.length(), linkerOptions); } else { linkerOptions = - cmSystemTools::tokenize(entry->substr(LINKER.length()), ","); + cmSystemTools::tokenize(value.substr(LINKER.length()), ","); } - entry = result.erase(entry); if (linkerOptions.empty() || (linkerOptions.size() == 1 && linkerOptions.front().empty())) { @@ -2982,56 +3058,64 @@ void cmGeneratorTarget::GetLinkOptions(std::vector<std::string>& result, cmake::FATAL_ERROR, "'SHELL:' prefix is not supported as part of 'LINKER:' arguments.", this->GetBacktrace()); - return; + return result; } + std::vector<BT<std::string>> options; if (wrapperFlag.empty()) { // nothing specified, insert elements as is - result.insert(entry, linkerOptions.begin(), linkerOptions.end()); + options.reserve(linkerOptions.size()); + for (std::string& o : linkerOptions) { + options.emplace_back(std::move(o), bt); + } } else { - std::vector<std::string> options; - if (!wrapperSep.empty()) { if (concatFlagAndArgs) { // insert flag elements except last one - options.insert(options.end(), wrapperFlag.begin(), - wrapperFlag.end() - 1); + for (auto i = wrapperFlag.begin(); i != wrapperFlag.end() - 1; ++i) { + options.emplace_back(*i, bt); + } // concatenate last flag element and all LINKER list values // in one option - options.push_back(wrapperFlag.back() + - cmJoin(linkerOptions, wrapperSep)); + options.emplace_back( + wrapperFlag.back() + cmJoin(linkerOptions, wrapperSep), bt); } else { - options.insert(options.end(), wrapperFlag.begin(), - wrapperFlag.end()); + for (std::string const& i : wrapperFlag) { + options.emplace_back(i, bt); + } // concatenate all LINKER list values in one option - options.push_back(cmJoin(linkerOptions, wrapperSep)); + options.emplace_back(cmJoin(linkerOptions, wrapperSep), bt); } } else { // prefix each element of LINKER list with wrapper if (concatFlagAndArgs) { - std::transform( - linkerOptions.begin(), linkerOptions.end(), linkerOptions.begin(), - [&wrapperFlag](const std::string& value) -> std::string { - return wrapperFlag.back() + value; - }); + std::transform(linkerOptions.begin(), linkerOptions.end(), + linkerOptions.begin(), + [&wrapperFlag](std::string const& o) -> std::string { + return wrapperFlag.back() + o; + }); } - for (const auto& value : linkerOptions) { - options.insert(options.end(), wrapperFlag.begin(), - concatFlagAndArgs ? wrapperFlag.end() - 1 - : wrapperFlag.end()); - options.push_back(value); + for (std::string& o : linkerOptions) { + for (auto i = wrapperFlag.begin(), + e = concatFlagAndArgs ? wrapperFlag.end() - 1 + : wrapperFlag.end(); + i != e; ++i) { + options.emplace_back(*i, bt); + } + options.emplace_back(std::move(o), bt); } } - result.insert(entry, options.begin(), options.end()); } + result.insert(entry, options.begin(), options.end()); } + return result; } namespace { void processStaticLibraryLinkOptions( cmGeneratorTarget const* tgt, const std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries, - std::vector<std::string>& options, + std::vector<BT<std::string>>& options, std::unordered_set<std::string>& uniqueOptions, cmGeneratorExpressionDAGChecker* dagChecker, const std::string& config, std::string const& language) @@ -3046,6 +3130,18 @@ void cmGeneratorTarget::GetStaticLibraryLinkOptions( std::vector<std::string>& result, const std::string& config, const std::string& language) const { + std::vector<BT<std::string>> tmp = + this->GetStaticLibraryLinkOptions(config, language); + result.reserve(tmp.size()); + for (BT<std::string>& v : tmp) { + result.emplace_back(std::move(v.Value)); + } +} + +std::vector<BT<std::string>> cmGeneratorTarget::GetStaticLibraryLinkOptions( + std::string const& config, std::string const& language) const +{ + std::vector<BT<std::string>> result; std::vector<cmGeneratorTarget::TargetPropertyEntry*> entries; std::unordered_set<std::string> uniqueOptions; @@ -3066,13 +3162,14 @@ void cmGeneratorTarget::GetStaticLibraryLinkOptions( &dagChecker, config, language); cmDeleteAll(entries); + return result; } namespace { void processLinkDirectories( cmGeneratorTarget const* tgt, const std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries, - std::vector<std::string>& directories, + std::vector<BT<std::string>>& directories, std::unordered_set<std::string>& uniqueDirectories, cmGeneratorExpressionDAGChecker* dagChecker, const std::string& config, bool debugDirectories, std::string const& language) @@ -3151,6 +3248,18 @@ void cmGeneratorTarget::GetLinkDirectories(std::vector<std::string>& result, const std::string& config, const std::string& language) const { + std::vector<BT<std::string>> tmp = + this->GetLinkDirectories(config, language); + result.reserve(tmp.size()); + for (BT<std::string>& v : tmp) { + result.emplace_back(std::move(v.Value)); + } +} + +std::vector<BT<std::string>> cmGeneratorTarget::GetLinkDirectories( + std::string const& config, std::string const& language) const +{ + std::vector<BT<std::string>> result; std::unordered_set<std::string> uniqueDirectories; cmGeneratorExpressionDAGChecker dagChecker(this, "LINK_DIRECTORIES", nullptr, @@ -3186,13 +3295,14 @@ void cmGeneratorTarget::GetLinkDirectories(std::vector<std::string>& result, debugDirectories, language); cmDeleteAll(linkInterfaceLinkDirectoriesEntries); + return result; } namespace { void processLinkDepends( cmGeneratorTarget const* tgt, const std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries, - std::vector<std::string>& options, + std::vector<BT<std::string>>& options, std::unordered_set<std::string>& uniqueOptions, cmGeneratorExpressionDAGChecker* dagChecker, const std::string& config, std::string const& language) @@ -3207,6 +3317,17 @@ void cmGeneratorTarget::GetLinkDepends(std::vector<std::string>& result, const std::string& config, const std::string& language) const { + std::vector<BT<std::string>> tmp = this->GetLinkDepends(config, language); + result.reserve(tmp.size()); + for (BT<std::string>& v : tmp) { + result.emplace_back(std::move(v.Value)); + } +} + +std::vector<BT<std::string>> cmGeneratorTarget::GetLinkDepends( + std::string const& config, std::string const& language) const +{ + std::vector<BT<std::string>> result; std::vector<cmGeneratorTarget::TargetPropertyEntry*> linkDependsEntries; std::unordered_set<std::string> uniqueOptions; cmGeneratorExpressionDAGChecker dagChecker(this, "LINK_DEPENDS", nullptr, @@ -3228,6 +3349,7 @@ void cmGeneratorTarget::GetLinkDepends(std::vector<std::string>& result, &dagChecker, config, language); cmDeleteAll(linkDependsEntries); + return result; } void cmGeneratorTarget::ComputeTargetManifest(const std::string& config) const @@ -3293,10 +3415,9 @@ void cmGeneratorTarget::ComputeTargetManifest(const std::string& config) const bool cmGeneratorTarget::ComputeCompileFeatures(std::string const& config) const { - std::vector<std::string> features; - this->GetCompileFeatures(features, config); - for (std::string const& f : features) { - if (!this->Makefile->AddRequiredTargetFeature(this->Target, f)) { + std::vector<BT<std::string>> features = this->GetCompileFeatures(config); + for (BT<std::string> const& f : features) { + if (!this->Makefile->AddRequiredTargetFeature(this->Target, f.Value)) { return false; } } @@ -4618,6 +4739,7 @@ void cmGeneratorTarget::ReportPropertyOrigin( } void cmGeneratorTarget::LookupLinkItems(std::vector<std::string> const& names, + cmListFileBacktrace const& bt, std::vector<cmLinkItem>& items) const { for (std::string const& n : names) { @@ -4625,7 +4747,7 @@ void cmGeneratorTarget::LookupLinkItems(std::vector<std::string> const& names, if (name == this->GetName() || name.empty()) { continue; } - items.push_back(this->ResolveLinkItem(name)); + items.push_back(this->ResolveLinkItem(name, bt)); } } @@ -4647,7 +4769,7 @@ void cmGeneratorTarget::ExpandLinkItems( false, headTarget, this, &dagChecker), libs); - this->LookupLinkItems(libs, items); + this->LookupLinkItems(libs, cge->GetBacktrace(), items); hadHeadSensitiveCondition = cge->GetHadHeadSensitiveCondition(); } @@ -5200,7 +5322,7 @@ const cmLinkInterface* cmGeneratorTarget::GetImportLinkInterface( iface.HadHeadSensitiveCondition); std::vector<std::string> deps; cmSystemTools::ExpandListArgument(info->SharedDeps, deps); - this->LookupLinkItems(deps, iface.SharedDeps); + this->LookupLinkItems(deps, cmListFileBacktrace(), iface.SharedDeps); } return &iface; @@ -5736,7 +5858,7 @@ void cmGeneratorTarget::ComputeLinkImplementationLibraries( } // The entry is meant for this configuration. - impl.Libraries.emplace_back(this->ResolveLinkItem(name), *btIt, + impl.Libraries.emplace_back(this->ResolveLinkItem(name, *btIt), evaluated != *le); } @@ -5764,7 +5886,8 @@ void cmGeneratorTarget::ComputeLinkImplementationLibraries( continue; } // Support OLD behavior for CMP0003. - impl.WrongConfigLibraries.push_back(this->ResolveLinkItem(name)); + impl.WrongConfigLibraries.push_back( + this->ResolveLinkItem(name, cmListFileBacktrace())); } } } @@ -5811,12 +5934,13 @@ cmGeneratorTarget::TargetOrString cmGeneratorTarget::ResolveTargetReference( return resolved; } -cmLinkItem cmGeneratorTarget::ResolveLinkItem(std::string const& name) const +cmLinkItem cmGeneratorTarget::ResolveLinkItem( + std::string const& name, cmListFileBacktrace const& bt) const { TargetOrString resolved = this->ResolveTargetReference(name); if (!resolved.Target) { - return cmLinkItem(resolved.String); + return cmLinkItem(resolved.String, bt); } // Skip targets that will not really be linked. This is probably a @@ -5824,10 +5948,10 @@ cmLinkItem cmGeneratorTarget::ResolveLinkItem(std::string const& name) const // within the project. if (resolved.Target->GetType() == cmStateEnums::EXECUTABLE && !resolved.Target->IsExecutableWithExports()) { - return cmLinkItem(resolved.Target->GetName()); + return cmLinkItem(resolved.Target->GetName(), bt); } - return cmLinkItem(resolved.Target); + return cmLinkItem(resolved.Target, bt); } std::string cmGeneratorTarget::GetPDBDirectory(const std::string& config) const diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h index b1daa53..4c32558 100644 --- a/Source/cmGeneratorTarget.h +++ b/Source/cmGeneratorTarget.h @@ -75,8 +75,8 @@ public: bool GetPropertyAsBool(const std::string& prop) const; void GetSourceFiles(std::vector<cmSourceFile*>& files, const std::string& config) const; - void GetSourceFilesWithoutObjectLibraries(std::vector<cmSourceFile*>& files, - const std::string& config) const; + std::vector<BT<cmSourceFile*>> GetSourceFiles( + std::string const& config) const; /** Source file kinds (classifications). Generators use this to decide how to treat a source file. */ @@ -99,7 +99,7 @@ public: /** A source file paired with a kind (classification). */ struct SourceAndKind { - cmSourceFile* Source; + BT<cmSourceFile*> Source; SourceKind Kind; }; @@ -273,8 +273,7 @@ public: cmListFileBacktrace GetBacktrace() const; - std::set<std::string> const& GetUtilities() const; - cmListFileBacktrace const* GetUtilityBacktrace(const std::string& u) const; + std::set<BT<std::string>> const& GetUtilities() const; bool LinkLanguagePropagatesToDependents() const { @@ -283,7 +282,7 @@ public: /** Get the macro to define when building sources in this target. If no macro should be defined null is returned. */ - const char* GetExportMacro() const; + const std::string* GetExportMacro() const; /** Get the soname of the target. Allowed only for a shared library. */ std::string GetSOName(const std::string& config) const; @@ -362,7 +361,8 @@ public: }; TargetOrString ResolveTargetReference(std::string const& name) const; - cmLinkItem ResolveLinkItem(std::string const& name) const; + cmLinkItem ResolveLinkItem(std::string const& name, + cmListFileBacktrace const& bt) const; // Compute the set of languages compiled by the target. This is // computed every time it is called because the languages can change @@ -412,34 +412,49 @@ public: std::string const& config) const; /** Get the include directories for this target. */ - std::vector<std::string> GetIncludeDirectories( + std::vector<BT<std::string>> GetIncludeDirectories( const std::string& config, const std::string& lang) const; void GetCompileOptions(std::vector<std::string>& result, const std::string& config, const std::string& language) const; + std::vector<BT<std::string>> GetCompileOptions( + std::string const& config, std::string const& language) const; void GetCompileFeatures(std::vector<std::string>& features, const std::string& config) const; + std::vector<BT<std::string>> GetCompileFeatures( + std::string const& config) const; void GetCompileDefinitions(std::vector<std::string>& result, const std::string& config, const std::string& language) const; + std::vector<BT<std::string>> GetCompileDefinitions( + std::string const& config, std::string const& language) const; void GetLinkOptions(std::vector<std::string>& result, const std::string& config, const std::string& language) const; + std::vector<BT<std::string>> GetLinkOptions( + std::string const& config, std::string const& language) const; + void GetStaticLibraryLinkOptions(std::vector<std::string>& result, const std::string& config, const std::string& language) const; + std::vector<BT<std::string>> GetStaticLibraryLinkOptions( + std::string const& config, std::string const& language) const; void GetLinkDirectories(std::vector<std::string>& result, const std::string& config, const std::string& language) const; + std::vector<BT<std::string>> GetLinkDirectories( + std::string const& config, std::string const& language) const; void GetLinkDepends(std::vector<std::string>& result, const std::string& config, const std::string& language) const; + std::vector<BT<std::string>> GetLinkDepends( + std::string const& config, std::string const& language) const; bool IsSystemIncludeDirectory(const std::string& dir, const std::string& config, @@ -838,10 +853,15 @@ private: std::vector<cmLinkItem>& items, bool& hadHeadSensitiveCondition) const; void LookupLinkItems(std::vector<std::string> const& names, + cmListFileBacktrace const& bt, std::vector<cmLinkItem>& items) const; - void GetSourceFiles(std::vector<std::string>& files, - const std::string& config) const; + std::vector<BT<std::string>> GetSourceFilePaths( + std::string const& config) const; + std::vector<BT<cmSourceFile*>> GetSourceFilesWithoutObjectLibraries( + std::string const& config) const; + void GetSourceFilesWithoutObjectLibraries(std::vector<cmSourceFile*>& files, + const std::string& config) const; struct HeadToLinkImplementationMap : public std::map<cmGeneratorTarget const*, cmOptionalLinkImplementation> diff --git a/Source/cmGhsMultiTargetGenerator.cxx b/Source/cmGhsMultiTargetGenerator.cxx index 847230a..4d98d55 100644 --- a/Source/cmGhsMultiTargetGenerator.cxx +++ b/Source/cmGhsMultiTargetGenerator.cxx @@ -267,14 +267,9 @@ std::string cmGhsMultiTargetGenerator::GetDefines(const std::string& language, if (i == this->DefinesByLanguage.end()) { std::set<std::string> defines; const char* lang = language.c_str(); - // Add the export symbol definition for shared library objects. - if (const char* exportMacro = this->GeneratorTarget->GetExportMacro()) { - this->LocalGenerator->AppendDefines(defines, exportMacro); - } - // Add preprocessor definitions for this target and configuration. - this->LocalGenerator->AddCompileDefinitions(defines, this->GeneratorTarget, - config, language); + this->LocalGenerator->GetTargetDefines(this->GeneratorTarget, config, + language, defines); std::string definesString; this->LocalGenerator->JoinDefines(defines, definesString, lang); diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index f513403..8c69f42 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -19,6 +19,7 @@ #include "cmGeneratedFileStream.h" #include "cmGeneratorExpressionEvaluationFile.h" #include "cmGeneratorTarget.h" +#include "cmListFileCache.h" #include "cmLocalGenerator.h" #include "cmLocalNinjaGenerator.h" #include "cmMakefile.h" @@ -1008,10 +1009,11 @@ void cmGlobalNinjaGenerator::AppendTargetDepends( { if (target->GetType() == cmStateEnums::GLOBAL_TARGET) { // These depend only on other CMake-provided targets, e.g. "all". - std::set<std::string> const& utils = target->GetUtilities(); - for (std::string const& util : utils) { + std::set<BT<std::string>> const& utils = target->GetUtilities(); + for (BT<std::string> const& util : utils) { std::string d = - target->GetLocalGenerator()->GetCurrentBinaryDirectory() + "/" + util; + target->GetLocalGenerator()->GetCurrentBinaryDirectory() + "/" + + util.Value; outputs.push_back(this->ConvertToNinjaPath(d)); } } else { diff --git a/Source/cmGlobalVisualStudio71Generator.cxx b/Source/cmGlobalVisualStudio71Generator.cxx index 0b086b0..a216346 100644 --- a/Source/cmGlobalVisualStudio71Generator.cxx +++ b/Source/cmGlobalVisualStudio71Generator.cxx @@ -159,7 +159,7 @@ void cmGlobalVisualStudio71Generator::WriteProjectDepends( // executables to the libraries it uses are also done here void cmGlobalVisualStudio71Generator::WriteExternalProject( std::ostream& fout, const std::string& name, const char* location, - const char* typeGuid, const std::set<std::string>& depends) + const char* typeGuid, const std::set<BT<std::string>>& depends) { fout << "Project(\"{" << (typeGuid ? typeGuid : this->ExternalProjectType(location)) @@ -171,9 +171,10 @@ void cmGlobalVisualStudio71Generator::WriteExternalProject( // project instead of in the global section if (!depends.empty()) { fout << "\tProjectSection(ProjectDependencies) = postProject\n"; - for (std::string const& it : depends) { - if (!it.empty()) { - fout << "\t\t{" << this->GetGUID(it) << "} = {" << this->GetGUID(it) + for (BT<std::string> const& it : depends) { + std::string const& dep = it.Value; + if (!dep.empty()) { + fout << "\t\t{" << this->GetGUID(dep) << "} = {" << this->GetGUID(dep) << "}\n"; } } diff --git a/Source/cmGlobalVisualStudio71Generator.h b/Source/cmGlobalVisualStudio71Generator.h index 054c342..b6e3131 100644 --- a/Source/cmGlobalVisualStudio71Generator.h +++ b/Source/cmGlobalVisualStudio71Generator.h @@ -33,7 +33,7 @@ protected: const std::string& platformMapping = "") override; void WriteExternalProject(std::ostream& fout, const std::string& name, const char* path, const char* typeGuid, - const std::set<std::string>& depends) override; + const std::set<BT<std::string>>& depends) override; void WriteSLNHeader(std::ostream& fout) override; // Folders are not supported by VS 7.1. diff --git a/Source/cmGlobalVisualStudio7Generator.h b/Source/cmGlobalVisualStudio7Generator.h index 0c9dd88..251478d 100644 --- a/Source/cmGlobalVisualStudio7Generator.h +++ b/Source/cmGlobalVisualStudio7Generator.h @@ -145,7 +145,7 @@ protected: virtual void WriteExternalProject( std::ostream& fout, const std::string& name, const char* path, - const char* typeGuid, const std::set<std::string>& dependencies) = 0; + const char* typeGuid, const std::set<BT<std::string>>& dependencies) = 0; std::string ConvertToSolutionPath(const char* path); diff --git a/Source/cmGlobalVisualStudio8Generator.cxx b/Source/cmGlobalVisualStudio8Generator.cxx index ba138c2..b155d9c 100644 --- a/Source/cmGlobalVisualStudio8Generator.cxx +++ b/Source/cmGlobalVisualStudio8Generator.cxx @@ -315,9 +315,9 @@ bool cmGlobalVisualStudio8Generator::NeedLinkLibraryDependencies( cmGeneratorTarget* target) { // Look for utility dependencies that magically link. - for (std::string const& ui : target->GetUtilities()) { + for (BT<std::string> const& ui : target->GetUtilities()) { if (cmGeneratorTarget* depTarget = - target->GetLocalGenerator()->FindGeneratorTargetToUse(ui)) { + target->GetLocalGenerator()->FindGeneratorTargetToUse(ui.Value)) { if (depTarget->GetType() != cmStateEnums::INTERFACE_LIBRARY && depTarget->GetProperty("EXTERNAL_MSPROJECT")) { // This utility dependency names an external .vcproj target. diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index e353a37..596bc6b 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -1814,9 +1814,9 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt, BuildObjectListOrString ppDefs(this, true); this->AppendDefines( ppDefs, "CMAKE_INTDIR=\"$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)\""); - if (const char* exportMacro = gtgt->GetExportMacro()) { + if (const std::string* exportMacro = gtgt->GetExportMacro()) { // Add the export symbol definition for shared library objects. - this->AppendDefines(ppDefs, exportMacro); + this->AppendDefines(ppDefs, exportMacro->c_str()); } std::vector<std::string> targetDefines; if (!langForPreprocessor.empty()) { diff --git a/Source/cmGraphAdjacencyList.h b/Source/cmGraphAdjacencyList.h index 6a0a799..fb2eee2 100644 --- a/Source/cmGraphAdjacencyList.h +++ b/Source/cmGraphAdjacencyList.h @@ -5,6 +5,8 @@ #include "cmConfigure.h" // IWYU pragma: keep +#include "cmListFileCache.h" + #include <vector> /** @@ -15,18 +17,22 @@ class cmGraphEdge { public: - cmGraphEdge(int n = 0, bool s = true) + cmGraphEdge(int n, bool s, cmListFileBacktrace const& bt) : Dest(n) , Strong(s) + , Backtrace(bt) { } operator int() const { return this->Dest; } bool IsStrong() const { return this->Strong; } + cmListFileBacktrace const& GetBacktrace() const { return this->Backtrace; } + private: int Dest; bool Strong; + cmListFileBacktrace Backtrace; }; struct cmGraphEdgeList : public std::vector<cmGraphEdge> { diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx index 6e33cf7..fbc5278 100644 --- a/Source/cmInstallCommand.cxx +++ b/Source/cmInstallCommand.cxx @@ -20,6 +20,7 @@ #include "cmInstallGenerator.h" #include "cmInstallScriptGenerator.h" #include "cmInstallTargetGenerator.h" +#include "cmListFileCache.h" #include "cmMakefile.h" #include "cmPolicies.h" #include "cmStateTypes.h" @@ -32,7 +33,8 @@ class cmExecutionStatus; static cmInstallTargetGenerator* CreateInstallTargetGenerator( cmTarget& target, const cmInstallCommandArguments& args, bool impLib, - bool forceOpt = false, bool namelink = false) + cmListFileBacktrace const& backtrace, bool forceOpt = false, + bool namelink = false) { cmInstallGenerator::MessageLevel message = cmInstallGenerator::SelectMessageLevel(target.GetMakefile()); @@ -42,7 +44,8 @@ static cmInstallTargetGenerator* CreateInstallTargetGenerator( return new cmInstallTargetGenerator( target.GetName(), args.GetDestination().c_str(), impLib, args.GetPermissions().c_str(), args.GetConfigurations(), component, - message, args.GetExcludeFromAll(), args.GetOptional() || forceOpt); + message, args.GetExcludeFromAll(), args.GetOptional() || forceOpt, + backtrace); } static cmInstallFilesGenerator* CreateInstallFilesGenerator( @@ -435,13 +438,13 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) // This is a DLL platform. if (!archiveArgs.GetDestination().empty()) { // The import library uses the ARCHIVE properties. - archiveGenerator = - CreateInstallTargetGenerator(target, archiveArgs, true); + archiveGenerator = CreateInstallTargetGenerator( + target, archiveArgs, true, this->Makefile->GetBacktrace()); } if (!runtimeArgs.GetDestination().empty()) { // The DLL uses the RUNTIME properties. - runtimeGenerator = - CreateInstallTargetGenerator(target, runtimeArgs, false); + runtimeGenerator = CreateInstallTargetGenerator( + target, runtimeArgs, false, this->Makefile->GetBacktrace()); } if ((archiveGenerator == nullptr) && (runtimeGenerator == nullptr)) { this->SetError("Library TARGETS given no DESTINATION!"); @@ -459,8 +462,8 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) // Use the FRAMEWORK properties. if (!frameworkArgs.GetDestination().empty()) { - frameworkGenerator = - CreateInstallTargetGenerator(target, frameworkArgs, false); + frameworkGenerator = CreateInstallTargetGenerator( + target, frameworkArgs, false, this->Makefile->GetBacktrace()); } else { std::ostringstream e; e << "TARGETS given no FRAMEWORK DESTINATION for shared library " @@ -473,14 +476,15 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) // The shared library uses the LIBRARY properties. if (!libraryArgs.GetDestination().empty()) { if (namelinkMode != cmInstallTargetGenerator::NamelinkModeOnly) { - libraryGenerator = - CreateInstallTargetGenerator(target, libraryArgs, false); + libraryGenerator = CreateInstallTargetGenerator( + target, libraryArgs, false, this->Makefile->GetBacktrace()); libraryGenerator->SetNamelinkMode( cmInstallTargetGenerator::NamelinkModeSkip); } if (namelinkMode != cmInstallTargetGenerator::NamelinkModeSkip) { namelinkGenerator = CreateInstallTargetGenerator( - target, libraryArgs, false, false, true); + target, libraryArgs, false, this->Makefile->GetBacktrace(), + false, true); namelinkGenerator->SetNamelinkMode( cmInstallTargetGenerator::NamelinkModeOnly); } @@ -508,8 +512,8 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) // Use the FRAMEWORK properties. if (!frameworkArgs.GetDestination().empty()) { - frameworkGenerator = - CreateInstallTargetGenerator(target, frameworkArgs, false); + frameworkGenerator = CreateInstallTargetGenerator( + target, frameworkArgs, false, this->Makefile->GetBacktrace()); } else { std::ostringstream e; e << "TARGETS given no FRAMEWORK DESTINATION for static library " @@ -521,8 +525,8 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) } else { // Static libraries use ARCHIVE properties. if (!archiveArgs.GetDestination().empty()) { - archiveGenerator = - CreateInstallTargetGenerator(target, archiveArgs, false); + archiveGenerator = CreateInstallTargetGenerator( + target, archiveArgs, false, this->Makefile->GetBacktrace()); } else { std::ostringstream e; e << "TARGETS given no ARCHIVE DESTINATION for static library " @@ -536,8 +540,8 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) case cmStateEnums::MODULE_LIBRARY: { // Modules use LIBRARY properties. if (!libraryArgs.GetDestination().empty()) { - libraryGenerator = - CreateInstallTargetGenerator(target, libraryArgs, false); + libraryGenerator = CreateInstallTargetGenerator( + target, libraryArgs, false, this->Makefile->GetBacktrace()); libraryGenerator->SetNamelinkMode(namelinkMode); namelinkOnly = (namelinkMode == cmInstallTargetGenerator::NamelinkModeOnly); @@ -563,8 +567,8 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) return false; } - objectGenerator = - CreateInstallTargetGenerator(target, objectArgs, false); + objectGenerator = CreateInstallTargetGenerator( + target, objectArgs, false, this->Makefile->GetBacktrace()); } else { // Installing an OBJECT library without a destination transforms // it to an INTERFACE library. It installs no files but can be @@ -575,15 +579,15 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) if (target.IsAppBundleOnApple()) { // Application bundles use the BUNDLE properties. if (!bundleArgs.GetDestination().empty()) { - bundleGenerator = - CreateInstallTargetGenerator(target, bundleArgs, false); + bundleGenerator = CreateInstallTargetGenerator( + target, bundleArgs, false, this->Makefile->GetBacktrace()); } else if (!runtimeArgs.GetDestination().empty()) { bool failure = false; if (this->CheckCMP0006(failure)) { // For CMake 2.4 compatibility fallback to the RUNTIME // properties. - bundleGenerator = - CreateInstallTargetGenerator(target, runtimeArgs, false); + bundleGenerator = CreateInstallTargetGenerator( + target, runtimeArgs, false, this->Makefile->GetBacktrace()); } else if (failure) { return false; } @@ -599,8 +603,8 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) } else { // Executables use the RUNTIME properties. if (!runtimeArgs.GetDestination().empty()) { - runtimeGenerator = - CreateInstallTargetGenerator(target, runtimeArgs, false); + runtimeGenerator = CreateInstallTargetGenerator( + target, runtimeArgs, false, this->Makefile->GetBacktrace()); } else { std::ostringstream e; e << "TARGETS given no RUNTIME DESTINATION for executable " @@ -617,8 +621,8 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) if (dll_platform && !archiveArgs.GetDestination().empty() && target.IsExecutableWithExports()) { // The import library uses the ARCHIVE properties. - archiveGenerator = - CreateInstallTargetGenerator(target, archiveArgs, true, true); + archiveGenerator = CreateInstallTargetGenerator( + target, archiveArgs, true, this->Makefile->GetBacktrace(), true); } } break; case cmStateEnums::INTERFACE_LIBRARY: diff --git a/Source/cmInstallGenerator.cxx b/Source/cmInstallGenerator.cxx index 53ac716..2b23658 100644 --- a/Source/cmInstallGenerator.cxx +++ b/Source/cmInstallGenerator.cxx @@ -22,6 +22,19 @@ cmInstallGenerator::~cmInstallGenerator() { } +bool cmInstallGenerator::HaveInstall() +{ + return true; +} + +void cmInstallGenerator::CheckCMP0082(bool& haveSubdirectoryInstall, + bool& haveInstallAfterSubdirectory) +{ + if (haveSubdirectoryInstall) { + haveInstallAfterSubdirectory = true; + } +} + void cmInstallGenerator::AddInstallRule( std::ostream& os, std::string const& dest, cmInstallType type, std::vector<std::string> const& files, bool optional /* = false */, diff --git a/Source/cmInstallGenerator.h b/Source/cmInstallGenerator.h index fc1ce86..e5b88c3 100644 --- a/Source/cmInstallGenerator.h +++ b/Source/cmInstallGenerator.h @@ -38,6 +38,10 @@ public: bool exclude_from_all); ~cmInstallGenerator() override; + virtual bool HaveInstall(); + virtual void CheckCMP0082(bool& haveSubdirectoryInstall, + bool& haveInstallAfterSubdirectory); + void AddInstallRule( std::ostream& os, std::string const& dest, cmInstallType type, std::vector<std::string> const& files, bool optional = false, diff --git a/Source/cmInstallScriptGenerator.cxx b/Source/cmInstallScriptGenerator.cxx index 3a90f4c..7d77b7c 100644 --- a/Source/cmInstallScriptGenerator.cxx +++ b/Source/cmInstallScriptGenerator.cxx @@ -2,7 +2,6 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmInstallScriptGenerator.h" -#include "cmGeneratorExpression.h" #include "cmScriptGenerator.h" #include <ostream> @@ -17,47 +16,24 @@ cmInstallScriptGenerator::cmInstallScriptGenerator(const char* script, , Script(script) , Code(code) { - // We need per-config actions if the script has generator expressions. - if (cmGeneratorExpression::Find(Script) != std::string::npos) { - this->ActionsPerConfig = true; - } } cmInstallScriptGenerator::~cmInstallScriptGenerator() { } -void cmInstallScriptGenerator::Compute(cmLocalGenerator* lg) +void cmInstallScriptGenerator::GenerateScript(std::ostream& os) { - this->LocalGenerator = lg; -} + Indent indent; + std::string component_test = + this->CreateComponentTest(this->Component.c_str(), this->ExcludeFromAll); + os << indent << "if(" << component_test << ")\n"; -void cmInstallScriptGenerator::AddScriptInstallRule(std::ostream& os, - Indent indent, - std::string const& script) -{ if (this->Code) { - os << indent.Next() << script << "\n"; - } else { - os << indent.Next() << "include(\"" << script << "\")\n"; - } -} - -void cmInstallScriptGenerator::GenerateScriptActions(std::ostream& os, - Indent indent) -{ - if (this->ActionsPerConfig) { - this->cmInstallGenerator::GenerateScriptActions(os, indent); + os << indent << this->Script << "\n"; } else { - this->AddScriptInstallRule(os, indent, this->Script); + os << indent << "include(\"" << this->Script << "\")\n"; } -} -void cmInstallScriptGenerator::GenerateScriptForConfig( - std::ostream& os, const std::string& config, Indent indent) -{ - cmGeneratorExpression ge; - std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(this->Script); - this->AddScriptInstallRule(os, indent, - cge->Evaluate(this->LocalGenerator, config)); + os << indent << "endif()\n\n"; } diff --git a/Source/cmInstallScriptGenerator.h b/Source/cmInstallScriptGenerator.h index 534bc1d..fe0f7c6 100644 --- a/Source/cmInstallScriptGenerator.h +++ b/Source/cmInstallScriptGenerator.h @@ -6,13 +6,10 @@ #include "cmConfigure.h" // IWYU pragma: keep #include "cmInstallGenerator.h" -#include "cmScriptGenerator.h" #include <iosfwd> #include <string> -class cmLocalGenerator; - /** \class cmInstallScriptGenerator * \brief Generate target installation rules. */ @@ -23,18 +20,10 @@ public: const char* component, bool exclude_from_all); ~cmInstallScriptGenerator() override; - void Compute(cmLocalGenerator* lg) override; - protected: - void GenerateScriptActions(std::ostream& os, Indent indent) override; - void GenerateScriptForConfig(std::ostream& os, const std::string& config, - Indent indent) override; - void AddScriptInstallRule(std::ostream& os, Indent indent, - std::string const& script); - + void GenerateScript(std::ostream& os) override; std::string Script; bool Code; - cmLocalGenerator* LocalGenerator; }; #endif diff --git a/Source/cmInstallSubdirectoryGenerator.cxx b/Source/cmInstallSubdirectoryGenerator.cxx new file mode 100644 index 0000000..ca9f134 --- /dev/null +++ b/Source/cmInstallSubdirectoryGenerator.cxx @@ -0,0 +1,77 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#include "cmInstallSubdirectoryGenerator.h" + +#include "cmLocalGenerator.h" +#include "cmMakefile.h" +#include "cmPolicies.h" +#include "cmScriptGenerator.h" +#include "cmSystemTools.h" + +#include <sstream> +#include <vector> + +cmInstallSubdirectoryGenerator::cmInstallSubdirectoryGenerator( + cmMakefile* makefile, const char* binaryDirectory, bool excludeFromAll) + : cmInstallGenerator(nullptr, std::vector<std::string>(), nullptr, + MessageDefault, excludeFromAll) + , Makefile(makefile) + , BinaryDirectory(binaryDirectory) +{ +} + +cmInstallSubdirectoryGenerator::~cmInstallSubdirectoryGenerator() +{ +} + +bool cmInstallSubdirectoryGenerator::HaveInstall() +{ + for (auto generator : this->Makefile->GetInstallGenerators()) { + if (generator->HaveInstall()) { + return true; + } + } + + return false; +} + +void cmInstallSubdirectoryGenerator::CheckCMP0082( + bool& haveSubdirectoryInstall, bool& /*unused*/) +{ + if (this->HaveInstall()) { + haveSubdirectoryInstall = true; + } +} + +void cmInstallSubdirectoryGenerator::Compute(cmLocalGenerator* lg) +{ + this->LocalGenerator = lg; +} + +void cmInstallSubdirectoryGenerator::GenerateScript(std::ostream& os) +{ + if (!this->ExcludeFromAll) { + cmPolicies::PolicyStatus status = + this->LocalGenerator->GetPolicyStatus(cmPolicies::CMP0082); + switch (status) { + case cmPolicies::WARN: + case cmPolicies::OLD: + // OLD behavior is handled in cmLocalGenerator::GenerateInstallRules() + break; + + case cmPolicies::NEW: + case cmPolicies::REQUIRED_IF_USED: + case cmPolicies::REQUIRED_ALWAYS: { + Indent indent; + std::string odir = this->BinaryDirectory; + cmSystemTools::ConvertToUnixSlashes(odir); + os << indent << "if(NOT CMAKE_INSTALL_LOCAL_ONLY)\n" + << indent.Next() + << "# Include the install script for the subdirectory.\n" + << indent.Next() << "include(\"" << odir + << "/cmake_install.cmake\")\n" + << indent << "endif()\n\n"; + } break; + } + } +} diff --git a/Source/cmInstallSubdirectoryGenerator.h b/Source/cmInstallSubdirectoryGenerator.h new file mode 100644 index 0000000..35471dd --- /dev/null +++ b/Source/cmInstallSubdirectoryGenerator.h @@ -0,0 +1,41 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#ifndef cmInstallSubdirectoryGenerator_h +#define cmInstallSubdirectoryGenerator_h + +#include "cmConfigure.h" // IWYU pragma: keep + +#include "cmInstallGenerator.h" + +#include <iosfwd> +#include <string> + +class cmLocalGenerator; +class cmMakefile; + +/** \class cmInstallSubdirectoryGenerator + * \brief Generate target installation rules. + */ +class cmInstallSubdirectoryGenerator : public cmInstallGenerator +{ +public: + cmInstallSubdirectoryGenerator(cmMakefile* makefile, + const char* binaryDirectory, + bool excludeFromAll); + ~cmInstallSubdirectoryGenerator() override; + + bool HaveInstall() override; + void CheckCMP0082(bool& haveSubdirectoryInstall, + bool& haveInstallAfterSubdirectory) override; + + void Compute(cmLocalGenerator* lg) override; + +protected: + void GenerateScript(std::ostream& os) override; + + cmMakefile* Makefile; + std::string BinaryDirectory; + cmLocalGenerator* LocalGenerator; +}; + +#endif diff --git a/Source/cmInstallTargetGenerator.cxx b/Source/cmInstallTargetGenerator.cxx index 8b8f79b..ea3d522 100644 --- a/Source/cmInstallTargetGenerator.cxx +++ b/Source/cmInstallTargetGenerator.cxx @@ -24,7 +24,7 @@ cmInstallTargetGenerator::cmInstallTargetGenerator( const std::string& targetName, const char* dest, bool implib, const char* file_permissions, std::vector<std::string> const& configurations, const char* component, MessageLevel message, bool exclude_from_all, - bool optional) + bool optional, cmListFileBacktrace const& backtrace) : cmInstallGenerator(dest, configurations, component, message, exclude_from_all) , TargetName(targetName) @@ -32,6 +32,7 @@ cmInstallTargetGenerator::cmInstallTargetGenerator( , FilePermissions(file_permissions) , ImportLibrary(implib) , Optional(optional) + , Backtrace(backtrace) { this->ActionsPerConfig = true; this->NamelinkMode = NamelinkModeNone; diff --git a/Source/cmInstallTargetGenerator.h b/Source/cmInstallTargetGenerator.h index f6bec20..bf625d1 100644 --- a/Source/cmInstallTargetGenerator.h +++ b/Source/cmInstallTargetGenerator.h @@ -6,6 +6,7 @@ #include "cmConfigure.h" // IWYU pragma: keep #include "cmInstallGenerator.h" +#include "cmListFileCache.h" #include "cmScriptGenerator.h" #include <iosfwd> @@ -21,11 +22,12 @@ class cmLocalGenerator; class cmInstallTargetGenerator : public cmInstallGenerator { public: - cmInstallTargetGenerator(std::string const& targetName, const char* dest, - bool implib, const char* file_permissions, - std::vector<std::string> const& configurations, - const char* component, MessageLevel message, - bool exclude_from_all, bool optional); + cmInstallTargetGenerator( + std::string const& targetName, const char* dest, bool implib, + const char* file_permissions, + std::vector<std::string> const& configurations, const char* component, + MessageLevel message, bool exclude_from_all, bool optional, + cmListFileBacktrace const& backtrace = cmListFileBacktrace()); ~cmInstallTargetGenerator() override; /** Select the policy for installing shared library linkable name @@ -64,6 +66,8 @@ public: std::string GetDestination(std::string const& config) const; + cmListFileBacktrace const& GetBacktrace() const { return this->Backtrace; } + protected: void GenerateScript(std::ostream& os) override; void GenerateScriptForConfig(std::ostream& os, const std::string& config, @@ -108,6 +112,7 @@ protected: NamelinkModeType NamelinkMode; bool ImportLibrary; bool Optional; + cmListFileBacktrace Backtrace; }; #endif diff --git a/Source/cmJsonObjectDictionary.h b/Source/cmJsonObjectDictionary.h index a4d41f3..8a2b529 100644 --- a/Source/cmJsonObjectDictionary.h +++ b/Source/cmJsonObjectDictionary.h @@ -43,4 +43,3 @@ static const std::string kCTEST_COMMAND = "ctestCommand"; static const std::string kCTEST_INFO = "ctestInfo"; static const std::string kMINIMUM_CMAKE_VERSION = "minimumCMakeVersion"; static const std::string kIS_GENERATOR_PROVIDED_KEY = "isGeneratorProvided"; -static const std::string kIS_INTERFACE_SOURCES_KEY = "isInterfaceSources"; diff --git a/Source/cmJsonObjects.cxx b/Source/cmJsonObjects.cxx index a7db75f..4148894 100644 --- a/Source/cmJsonObjects.cxx +++ b/Source/cmJsonObjects.cxx @@ -150,8 +150,6 @@ Json::Value cmDumpCMakeInputs(const cmake* cm) return array; } -const std::string kInterfaceSourcesLanguageDataKey = - "INTERFACE_SOURCES_LD_KEY"; class LanguageData { public: @@ -184,12 +182,6 @@ void LanguageData::SetDefines(const std::set<std::string>& defines) Defines = std::move(result); } -struct FileGroupSources -{ - bool IsInterfaceSources; - std::vector<std::string> Files; -}; - namespace std { template <> @@ -217,35 +209,31 @@ struct hash<LanguageData> } // namespace std static Json::Value DumpSourceFileGroup(const LanguageData& data, - bool isInterfaceSource, const std::vector<std::string>& files, const std::string& baseDir) { Json::Value result = Json::objectValue; - if (isInterfaceSource) { - result[kIS_INTERFACE_SOURCES_KEY] = true; - } if (!data.Language.empty()) { result[kLANGUAGE_KEY] = data.Language; - } - if (!data.Flags.empty()) { - result[kCOMPILE_FLAGS_KEY] = data.Flags; - } - if (!data.IncludePathList.empty()) { - Json::Value includes = Json::arrayValue; - for (auto const& i : data.IncludePathList) { - Json::Value tmp = Json::objectValue; - tmp[kPATH_KEY] = i.first; - if (i.second) { - tmp[kIS_SYSTEM_KEY] = i.second; + if (!data.Flags.empty()) { + result[kCOMPILE_FLAGS_KEY] = data.Flags; + } + if (!data.IncludePathList.empty()) { + Json::Value includes = Json::arrayValue; + for (auto const& i : data.IncludePathList) { + Json::Value tmp = Json::objectValue; + tmp[kPATH_KEY] = i.first; + if (i.second) { + tmp[kIS_SYSTEM_KEY] = i.second; + } + includes.append(tmp); } - includes.append(tmp); + result[kINCLUDE_PATH_KEY] = includes; + } + if (!data.Defines.empty()) { + result[kDEFINES_KEY] = fromStringList(data.Defines); } - result[kINCLUDE_PATH_KEY] = includes; - } - if (!data.Defines.empty()) { - result[kDEFINES_KEY] = fromStringList(data.Defines); } result[kIS_GENERATED_KEY] = data.IsGenerated; @@ -260,19 +248,21 @@ static Json::Value DumpSourceFileGroup(const LanguageData& data, return result; } -static void PopulateFileGroupData( - cmGeneratorTarget* target, bool isInterfaceSources, - const std::vector<cmSourceFile*>& files, const std::string& config, - const std::map<std::string, LanguageData>& languageDataMap, - std::unordered_map<LanguageData, FileGroupSources>& fileGroups) +static Json::Value DumpSourceFilesList( + cmGeneratorTarget* target, const std::string& config, + const std::map<std::string, LanguageData>& languageDataMap) { + // Collect sourcefile groups: + + std::vector<cmSourceFile*> files; + target->GetSourceFiles(files, config); + + std::unordered_map<LanguageData, std::vector<std::string>> fileGroups; for (cmSourceFile* file : files) { LanguageData fileData; fileData.Language = file->GetLanguage(); - if (!fileData.Language.empty() || isInterfaceSources) { - const LanguageData& ld = isInterfaceSources - ? languageDataMap.at(kInterfaceSourcesLanguageDataKey) - : languageDataMap.at(fileData.Language); + if (!fileData.Language.empty()) { + const LanguageData& ld = languageDataMap.at(fileData.Language); cmLocalGenerator* lg = target->GetLocalGenerator(); cmGeneratorExpressionInterpreter genexInterpreter(lg, config, target, fileData.Language); @@ -300,14 +290,10 @@ static void PopulateFileGroupData( lg->AppendIncludeDirectories(includes, evaluatedIncludes, *file); for (const auto& include : includes) { - // INTERFACE_LIBRARY targets do not support the - // IsSystemIncludeDirectory call so just set it to false. - const bool isSystemInclude = isInterfaceSources - ? false - : target->IsSystemIncludeDirectory(include, config, - fileData.Language); fileData.IncludePathList.push_back( - std::make_pair(include, isSystemInclude)); + std::make_pair(include, + target->IsSystemIncludeDirectory( + include, config, fileData.Language))); } } @@ -336,71 +322,14 @@ static void PopulateFileGroupData( } fileData.IsGenerated = file->GetPropertyAsBool("GENERATED"); - FileGroupSources& groupFileList = fileGroups[fileData]; - groupFileList.IsInterfaceSources = isInterfaceSources; - groupFileList.Files.push_back(file->GetFullPath()); - } -} - -static Json::Value DumpSourceFilesList( - cmGeneratorTarget* target, const std::string& config, - const std::map<std::string, LanguageData>& languageDataMap) -{ - const cmStateEnums::TargetType type = target->GetType(); - std::unordered_map<LanguageData, FileGroupSources> fileGroups; - - // Collect sourcefile groups: - - std::vector<cmSourceFile*> files; - if (type == cmStateEnums::INTERFACE_LIBRARY) { - // INTERFACE_LIBRARY targets do not create all the data structures - // associated with regular targets. If properties are explicitly specified - // for files in INTERFACE_SOURCES then we can get them through the Makefile - // rather than the target. - files = target->Makefile->GetSourceFiles(); - } else { - target->GetSourceFiles(files, config); - PopulateFileGroupData(target, false /* isInterfaceSources */, files, - config, languageDataMap, fileGroups); - } - - // Collect interface sourcefile groups: - - auto targetProp = target->Target->GetProperty("INTERFACE_SOURCES"); - if (targetProp != nullptr) { - cmGeneratorExpressionInterpreter genexInterpreter( - target->GetLocalGenerator(), config, target); - - auto evaluatedSources = cmsys::SystemTools::SplitString( - genexInterpreter.Evaluate(targetProp, "INTERFACE_SOURCES"), ';'); - - std::map<std::string, cmSourceFile*> filesMap; - for (auto file : files) { - filesMap[file->GetFullPath()] = file; - } - - std::vector<cmSourceFile*> interfaceSourceFiles; - for (const std::string& interfaceSourceFilePath : evaluatedSources) { - auto entry = filesMap.find(interfaceSourceFilePath); - if (entry != filesMap.end()) { - // use what we have since it has all the associated properties - interfaceSourceFiles.push_back(entry->second); - } else { - interfaceSourceFiles.push_back( - new cmSourceFile(target->Makefile, interfaceSourceFilePath)); - } - } - - PopulateFileGroupData(target, true /* isInterfaceSources */, - interfaceSourceFiles, config, languageDataMap, - fileGroups); + std::vector<std::string>& groupFileList = fileGroups[fileData]; + groupFileList.push_back(file->GetFullPath()); } const std::string& baseDir = target->Makefile->GetCurrentSourceDirectory(); Json::Value result = Json::arrayValue; for (auto const& it : fileGroups) { - Json::Value group = DumpSourceFileGroup( - it.first, it.second.IsInterfaceSources, it.second.Files, baseDir); + Json::Value group = DumpSourceFileGroup(it.first, it.second, baseDir); if (!group.isNull()) { result.append(group); } @@ -517,58 +446,6 @@ Json::Value cmDumpCTestInfo(const cmake* cm) return result; } -static void GetTargetProperty( - cmGeneratorExpressionInterpreter& genexInterpreter, - cmGeneratorTarget* target, const char* propertyName, - std::vector<std::string>& propertyValue) -{ - auto targetProp = target->Target->GetProperty(propertyName); - if (targetProp != nullptr) { - propertyValue = cmsys::SystemTools::SplitString( - genexInterpreter.Evaluate(targetProp, propertyName), ';'); - } -} - -static void CreateInterfaceSourcesEntry( - cmLocalGenerator* lg, cmGeneratorTarget* target, const std::string& config, - std::map<std::string, LanguageData>& languageDataMap) -{ - LanguageData& ld = languageDataMap[kInterfaceSourcesLanguageDataKey]; - ld.Language = ""; - - cmGeneratorExpressionInterpreter genexInterpreter(lg, config, target); - std::vector<std::string> propertyValue; - GetTargetProperty(genexInterpreter, target, "INTERFACE_INCLUDE_DIRECTORIES", - propertyValue); - for (std::string const& i : propertyValue) { - ld.IncludePathList.push_back( - std::make_pair(i, false /* isSystemInclude */)); - } - - propertyValue.clear(); - GetTargetProperty(genexInterpreter, target, - "INTERFACE_SYSTEM_INCLUDE_DIRECTORIES", propertyValue); - for (std::string const& i : propertyValue) { - ld.IncludePathList.push_back( - std::make_pair(i, true /* isSystemInclude */)); - } - - propertyValue.clear(); - GetTargetProperty(genexInterpreter, target, "INTERFACE_COMPILE_OPTIONS", - propertyValue); - for (const auto& s : propertyValue) { - ld.Flags += " " + s; - } - - propertyValue.clear(); - GetTargetProperty(genexInterpreter, target, "INTERFACE_COMPILE_DEFINITIONS", - propertyValue); - if (!propertyValue.empty()) { - std::set<std::string> defines(propertyValue.begin(), propertyValue.end()); - ld.SetDefines(defines); - } -} - static Json::Value DumpTarget(cmGeneratorTarget* target, const std::string& config) { @@ -598,6 +475,11 @@ static Json::Value DumpTarget(cmGeneratorTarget* target, result[kTYPE_KEY] = typeName; result[kSOURCE_DIRECTORY_KEY] = lg->GetCurrentSourceDirectory(); result[kBUILD_DIRECTORY_KEY] = lg->GetCurrentBinaryDirectory(); + + if (type == cmStateEnums::INTERFACE_LIBRARY) { + return result; + } + result[kFULL_NAME_KEY] = target->GetFullName(config); if (target->Target->GetHaveInstallRule()) { @@ -684,21 +566,8 @@ static Json::Value DumpTarget(cmGeneratorTarget* target, } std::set<std::string> languages; + target->GetLanguages(languages, config); std::map<std::string, LanguageData> languageDataMap; - if (type == cmStateEnums::INTERFACE_LIBRARY) { - // INTERFACE_LIBRARY targets do not create all the data structures - // associated with regular targets. If properties are explicitly specified - // for files in INTERFACE_SOURCES then we can get them through the Makefile - // rather than the target. - for (auto file : target->Makefile->GetSourceFiles()) { - const std::string& language = file->GetLanguage(); - if (!language.empty()) { - languages.insert(language); - } - } - } else { - target->GetLanguages(languages, config); - } for (std::string const& lang : languages) { LanguageData& ld = languageDataMap[lang]; @@ -715,11 +584,6 @@ static Json::Value DumpTarget(cmGeneratorTarget* target, } } - if (target->Target->GetProperty("INTERFACE_SOURCES") != nullptr) { - // Create an entry in the languageDataMap for interface sources. - CreateInterfaceSourcesEntry(lg, target, config, languageDataMap); - } - Json::Value sourceGroupsValue = DumpSourceFilesList(target, config, languageDataMap); if (!sourceGroupsValue.empty()) { diff --git a/Source/cmLinkItem.cxx b/Source/cmLinkItem.cxx index 69b6821..121731d 100644 --- a/Source/cmLinkItem.cxx +++ b/Source/cmLinkItem.cxx @@ -12,15 +12,18 @@ cmLinkItem::cmLinkItem() { } -cmLinkItem::cmLinkItem(std::string const& n) +cmLinkItem::cmLinkItem(std::string const& n, cmListFileBacktrace const& bt) : String(n) , Target(nullptr) + , Backtrace(bt) { } -cmLinkItem::cmLinkItem(cmGeneratorTarget const* t) +cmLinkItem::cmLinkItem(cmGeneratorTarget const* t, + cmListFileBacktrace const& bt) : String() , Target(t) + , Backtrace(bt) { } @@ -58,15 +61,12 @@ std::ostream& operator<<(std::ostream& os, cmLinkItem const& item) cmLinkImplItem::cmLinkImplItem() : cmLinkItem() - , Backtrace() , FromGenex(false) { } -cmLinkImplItem::cmLinkImplItem(cmLinkItem item, cmListFileBacktrace const& bt, - bool fromGenex) +cmLinkImplItem::cmLinkImplItem(cmLinkItem item, bool fromGenex) : cmLinkItem(std::move(item)) - , Backtrace(bt) , FromGenex(fromGenex) { } diff --git a/Source/cmLinkItem.h b/Source/cmLinkItem.h index 74fd298..e1ddd22 100644 --- a/Source/cmLinkItem.h +++ b/Source/cmLinkItem.h @@ -24,10 +24,11 @@ class cmLinkItem public: cmLinkItem(); - explicit cmLinkItem(std::string const& s); - explicit cmLinkItem(cmGeneratorTarget const* t); + cmLinkItem(std::string const& s, cmListFileBacktrace const& bt); + cmLinkItem(cmGeneratorTarget const* t, cmListFileBacktrace const& bt); std::string const& AsStr() const; cmGeneratorTarget const* Target; + cmListFileBacktrace Backtrace; friend bool operator<(cmLinkItem const& l, cmLinkItem const& r); friend bool operator==(cmLinkItem const& l, cmLinkItem const& r); friend std::ostream& operator<<(std::ostream& os, cmLinkItem const& item); @@ -37,9 +38,7 @@ class cmLinkImplItem : public cmLinkItem { public: cmLinkImplItem(); - cmLinkImplItem(cmLinkItem item, cmListFileBacktrace const& bt, - bool fromGenex); - cmListFileBacktrace Backtrace; + cmLinkImplItem(cmLinkItem item, bool fromGenex); bool FromGenex; }; diff --git a/Source/cmLinkLineDeviceComputer.cxx b/Source/cmLinkLineDeviceComputer.cxx index c9bbde1..025c6e4 100644 --- a/Source/cmLinkLineDeviceComputer.cxx +++ b/Source/cmLinkLineDeviceComputer.cxx @@ -25,6 +25,23 @@ cmLinkLineDeviceComputer::~cmLinkLineDeviceComputer() { } +static bool cmLinkItemValidForDevice(std::string const& item) +{ + // Valid items are: + // * Non-flags (does not start in '-') + // * Specific flags --library, --library-path, -l, -L + // For example: + // * 'cublas_device' => pass-along + // * '--library pthread' => pass-along + // * '-lpthread' => pass-along + // * '-pthread' => drop + // * '-a' => drop + return (!cmHasLiteralPrefix(item, "-") || // + cmHasLiteralPrefix(item, "-l") || // + cmHasLiteralPrefix(item, "-L") || // + cmHasLiteralPrefix(item, "--library")); +} + std::string cmLinkLineDeviceComputer::ComputeLinkLibraries( cmComputeLinkInformation& cli, std::string const& stdLibString) { @@ -69,7 +86,7 @@ std::string cmLinkLineDeviceComputer::ComputeLinkLibraries( } out += this->ConvertToOutputFormat(this->ConvertToLinkReference(item.Value)); - } else { + } else if (cmLinkItemValidForDevice(item.Value)) { out += item.Value; } diff --git a/Source/cmListCommand.cxx b/Source/cmListCommand.cxx index d7de2fa..b2acb90 100644 --- a/Source/cmListCommand.cxx +++ b/Source/cmListCommand.cxx @@ -346,8 +346,7 @@ bool cmListCommand::HandleRemoveItemCommand( // expand the variable std::vector<std::string> varArgsExpanded; if (!this->GetList(varArgsExpanded, listName)) { - this->SetError("sub-command REMOVE_ITEM requires list to be present."); - return false; + return true; } std::vector<std::string> remove(args.begin() + 2, args.end()); @@ -376,8 +375,7 @@ bool cmListCommand::HandleReverseCommand(std::vector<std::string> const& args) // expand the variable std::vector<std::string> varArgsExpanded; if (!this->GetList(varArgsExpanded, listName)) { - this->SetError("sub-command REVERSE requires list to be present."); - return false; + return true; } std::string value = cmJoin(cmReverseRange(varArgsExpanded), ";"); @@ -399,9 +397,7 @@ bool cmListCommand::HandleRemoveDuplicatesCommand( // expand the variable std::vector<std::string> varArgsExpanded; if (!this->GetList(varArgsExpanded, listName)) { - this->SetError( - "sub-command REMOVE_DUPLICATES requires list to be present."); - return false; + return true; } std::vector<std::string>::const_iterator argsEnd = @@ -1152,8 +1148,7 @@ bool cmListCommand::HandleSortCommand(std::vector<std::string> const& args) // expand the variable std::vector<std::string> varArgsExpanded; if (!this->GetList(varArgsExpanded, listName)) { - this->SetError("sub-command SORT requires list to be present."); - return false; + return true; } if ((sortCompare == cmStringSorter::Compare::STRING) && @@ -1230,13 +1225,17 @@ bool cmListCommand::HandleRemoveAtCommand(std::vector<std::string> const& args) const std::string& listName = args[1]; // expand the variable std::vector<std::string> varArgsExpanded; - if (!this->GetList(varArgsExpanded, listName)) { - this->SetError("sub-command REMOVE_AT requires list to be present."); - return false; - } - // FIXME: Add policy to make non-existing lists an error like empty lists. - if (varArgsExpanded.empty()) { - this->SetError("REMOVE_AT given empty list"); + if (!this->GetList(varArgsExpanded, listName) || varArgsExpanded.empty()) { + std::ostringstream str; + str << "index: "; + for (size_t i = 1; i < args.size(); ++i) { + str << args[i]; + if (i != args.size() - 1) { + str << ", "; + } + } + str << " out of range (0, 0)"; + this->SetError(str.str()); return false; } @@ -1289,14 +1288,6 @@ bool cmListCommand::HandleFilterCommand(std::vector<std::string> const& args) return false; } - const std::string& listName = args[1]; - // expand the variable - std::vector<std::string> varArgsExpanded; - if (!this->GetList(varArgsExpanded, listName)) { - this->SetError("sub-command FILTER requires list to be present."); - return false; - } - const std::string& op = args[2]; bool includeMatches; if (op == "INCLUDE") { @@ -1308,6 +1299,13 @@ bool cmListCommand::HandleFilterCommand(std::vector<std::string> const& args) return false; } + const std::string& listName = args[1]; + // expand the variable + std::vector<std::string> varArgsExpanded; + if (!this->GetList(varArgsExpanded, listName)) { + return true; + } + const std::string& mode = args[3]; if (mode == "REGEX") { if (args.size() != 5) { diff --git a/Source/cmListFileCache.cxx b/Source/cmListFileCache.cxx index 4d7e1e2..d0495f7 100644 --- a/Source/cmListFileCache.cxx +++ b/Source/cmListFileCache.cxx @@ -9,10 +9,10 @@ #include "cmSystemTools.h" #include "cmake.h" -#include <algorithm> #include <assert.h> #include <memory> #include <sstream> +#include <utility> cmCommandContext::cmCommandName& cmCommandContext::cmCommandName::operator=( std::string const& name) @@ -474,3 +474,21 @@ bool operator!=(const cmListFileContext& lhs, const cmListFileContext& rhs) { return !(lhs == rhs); } + +std::ostream& operator<<(std::ostream& os, BT<std::string> const& s) +{ + return os << s.Value; +} + +std::vector<BT<std::string>> ExpandListWithBacktrace( + const char* list, cmListFileBacktrace const& bt) +{ + std::vector<BT<std::string>> result; + std::vector<std::string> tmp; + cmSystemTools::ExpandListArgument(list, tmp); + result.reserve(tmp.size()); + for (std::string& i : tmp) { + result.emplace_back(std::move(i), bt); + } + return result; +} diff --git a/Source/cmListFileCache.h b/Source/cmListFileCache.h index 3d3afdf..7c2802e 100644 --- a/Source/cmListFileCache.h +++ b/Source/cmListFileCache.h @@ -9,6 +9,7 @@ #include <memory> // IWYU pragma: keep #include <stddef.h> #include <string> +#include <utility> #include <vector> #include "cmStateSnapshot.h" @@ -169,6 +170,37 @@ private: cmListFileBacktrace(std::shared_ptr<Entry const> top); }; +// Wrap type T as a value with a backtrace. For purposes of +// ordering and equality comparison, only the original value is +// used. The backtrace is considered incidental. +template <typename T> +class BT +{ +public: + BT(T v = T(), cmListFileBacktrace bt = cmListFileBacktrace()) + : Value(std::move(v)) + , Backtrace(std::move(bt)) + { + } + T Value; + cmListFileBacktrace Backtrace; + friend bool operator==(BT<T> const& l, BT<T> const& r) + { + return l.Value == r.Value; + } + friend bool operator<(BT<T> const& l, BT<T> const& r) + { + return l.Value < r.Value; + } + friend bool operator==(BT<T> const& l, T const& r) { return l.Value == r; } + friend bool operator==(T const& l, BT<T> const& r) { return l == r.Value; } +}; + +std::ostream& operator<<(std::ostream& os, BT<std::string> const& s); + +std::vector<BT<std::string>> ExpandListWithBacktrace( + const char* list, cmListFileBacktrace const& bt = cmListFileBacktrace()); + struct cmListFile { bool ParseFile(const char* path, cmMessenger* messenger, diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 7030725..7beeb71 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -202,9 +202,10 @@ void cmLocalGenerator::ComputeObjectMaxPath() this->ObjectMaxPathViolations.clear(); } -void cmLocalGenerator::MoveSystemIncludesToEnd( - std::vector<std::string>& includeDirs, const std::string& config, - const std::string& lang, const cmGeneratorTarget* target) const +static void MoveSystemIncludesToEnd(std::vector<std::string>& includeDirs, + const std::string& config, + const std::string& lang, + const cmGeneratorTarget* target) { if (!target) { return; @@ -218,6 +219,24 @@ void cmLocalGenerator::MoveSystemIncludesToEnd( }); } +static void MoveSystemIncludesToEnd(std::vector<BT<std::string>>& includeDirs, + const std::string& config, + const std::string& lang, + const cmGeneratorTarget* target) +{ + if (!target) { + return; + } + + std::stable_sort(includeDirs.begin(), includeDirs.end(), + [target, &config, &lang](BT<std::string> const& a, + BT<std::string> const& b) { + return !target->IsSystemIncludeDirectory(a.Value, config, + lang) && + target->IsSystemIncludeDirectory(b.Value, config, lang); + }); +} + void cmLocalGenerator::TraceDependencies() { std::vector<std::string> configs; @@ -517,31 +536,62 @@ void cmLocalGenerator::GenerateInstallRules() } // Ask each install generator to write its code. + cmPolicies::PolicyStatus status = this->GetPolicyStatus(cmPolicies::CMP0082); std::vector<cmInstallGenerator*> const& installers = this->Makefile->GetInstallGenerators(); - for (cmInstallGenerator* installer : installers) { - installer->Generate(fout, config, configurationTypes); + bool haveSubdirectoryInstall = false; + bool haveInstallAfterSubdirectory = false; + if (status == cmPolicies::WARN) { + for (cmInstallGenerator* installer : installers) { + installer->CheckCMP0082(haveSubdirectoryInstall, + haveInstallAfterSubdirectory); + installer->Generate(fout, config, configurationTypes); + } + } else { + for (cmInstallGenerator* installer : installers) { + installer->Generate(fout, config, configurationTypes); + } } // Write rules from old-style specification stored in targets. this->GenerateTargetInstallRules(fout, config, configurationTypes); // Include install scripts from subdirectories. - std::vector<cmStateSnapshot> children = - this->Makefile->GetStateSnapshot().GetChildren(); - if (!children.empty()) { - fout << "if(NOT CMAKE_INSTALL_LOCAL_ONLY)\n"; - fout << " # Include the install script for each subdirectory.\n"; - for (cmStateSnapshot const& c : children) { - if (!c.GetDirectory().GetPropertyAsBool("EXCLUDE_FROM_ALL")) { - std::string odir = c.GetDirectory().GetCurrentBinary(); - cmSystemTools::ConvertToUnixSlashes(odir); - fout << " include(\"" << odir << "/cmake_install.cmake\")" - << std::endl; + switch (status) { + case cmPolicies::WARN: + if (haveInstallAfterSubdirectory && + this->Makefile->PolicyOptionalWarningEnabled( + "CMAKE_POLICY_WARNING_CMP0082")) { + std::ostringstream e; + e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0082) << "\n"; + this->IssueMessage(cmake::AUTHOR_WARNING, e.str()); } - } - fout << "\n"; - fout << "endif()\n\n"; + CM_FALLTHROUGH; + case cmPolicies::OLD: { + std::vector<cmStateSnapshot> children = + this->Makefile->GetStateSnapshot().GetChildren(); + if (!children.empty()) { + fout << "if(NOT CMAKE_INSTALL_LOCAL_ONLY)\n"; + fout << " # Include the install script for each subdirectory.\n"; + for (cmStateSnapshot const& c : children) { + if (!c.GetDirectory().GetPropertyAsBool("EXCLUDE_FROM_ALL")) { + std::string odir = c.GetDirectory().GetCurrentBinary(); + cmSystemTools::ConvertToUnixSlashes(odir); + fout << " include(\"" << odir << "/cmake_install.cmake\")" + << std::endl; + } + } + fout << "\n"; + fout << "endif()\n\n"; + } + } break; + + case cmPolicies::REQUIRED_IF_USED: + case cmPolicies::REQUIRED_ALWAYS: + case cmPolicies::NEW: + // NEW behavior is handled in + // cmInstallSubdirectoryGenerator::GenerateScript() + break; } // Record the install manifest. @@ -676,7 +726,7 @@ std::string cmLocalGenerator::GetIncludeFlags( } std::vector<std::string> includes = includeDirs; - this->MoveSystemIncludesToEnd(includes, config, lang, target); + MoveSystemIncludesToEnd(includes, config, lang, target); OutputFormat shellFormat = forResponseFile ? RESPONSE : SHELL; std::ostringstream includeFlags; @@ -773,16 +823,6 @@ std::string cmLocalGenerator::GetIncludeFlags( return flags; } -void cmLocalGenerator::AddCompileDefinitions(std::set<std::string>& defines, - cmGeneratorTarget const* target, - const std::string& config, - const std::string& lang) const -{ - std::vector<std::string> targetDefines; - target->GetCompileDefinitions(targetDefines, config, lang); - this->AppendDefines(defines, targetDefines); -} - void cmLocalGenerator::AddCompileOptions(std::string& flags, cmGeneratorTarget* target, const std::string& lang, @@ -847,6 +887,21 @@ void cmLocalGenerator::GetIncludeDirectories(std::vector<std::string>& dirs, bool stripImplicitDirs, bool appendAllImplicitDirs) const { + std::vector<BT<std::string>> tmp = this->GetIncludeDirectories( + target, lang, config, stripImplicitDirs, appendAllImplicitDirs); + dirs.reserve(tmp.size()); + for (BT<std::string>& v : tmp) { + dirs.emplace_back(std::move(v.Value)); + } +} + +std::vector<BT<std::string>> cmLocalGenerator::GetIncludeDirectories( + cmGeneratorTarget const* target, std::string const& lang, + std::string const& config, bool stripImplicitDirs, + bool appendAllImplicitDirs) const +{ + std::vector<BT<std::string>> result; + // Do not repeat an include path. std::set<std::string> emitted; @@ -863,7 +918,7 @@ void cmLocalGenerator::GetIncludeDirectories(std::vector<std::string>& dirs, std::string binDir = this->StateSnapshot.GetDirectory().GetCurrentBinary(); if (emitted.insert(binDir).second) { - dirs.push_back(std::move(binDir)); + result.emplace_back(std::move(binDir)); } } // Current source directory @@ -871,13 +926,13 @@ void cmLocalGenerator::GetIncludeDirectories(std::vector<std::string>& dirs, std::string srcDir = this->StateSnapshot.GetDirectory().GetCurrentSource(); if (emitted.insert(srcDir).second) { - dirs.push_back(std::move(srcDir)); + result.emplace_back(std::move(srcDir)); } } } if (!target) { - return; + return result; } // Implicit include directories @@ -910,7 +965,7 @@ void cmLocalGenerator::GetIncludeDirectories(std::vector<std::string>& dirs, } // Get the target-specific include directories. - std::vector<std::string> userDirs = + std::vector<BT<std::string>> userDirs = target->GetIncludeDirectories(config, lang); // Support putting all the in-project include directories first if @@ -918,44 +973,44 @@ void cmLocalGenerator::GetIncludeDirectories(std::vector<std::string>& dirs, if (this->Makefile->IsOn("CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE")) { std::string const &topSourceDir = this->GetState()->GetSourceDirectory(), &topBinaryDir = this->GetState()->GetBinaryDirectory(); - for (std::string const& i : userDirs) { + for (BT<std::string> const& i : userDirs) { // Emit this directory only if it is a subdirectory of the // top-level source or binary tree. - if (cmSystemTools::ComparePath(i, topSourceDir) || - cmSystemTools::ComparePath(i, topBinaryDir) || - cmSystemTools::IsSubDirectory(i, topSourceDir) || - cmSystemTools::IsSubDirectory(i, topBinaryDir)) { - if (emitted.insert(i).second) { - dirs.push_back(i); + if (cmSystemTools::ComparePath(i.Value, topSourceDir) || + cmSystemTools::ComparePath(i.Value, topBinaryDir) || + cmSystemTools::IsSubDirectory(i.Value, topSourceDir) || + cmSystemTools::IsSubDirectory(i.Value, topBinaryDir)) { + if (emitted.insert(i.Value).second) { + result.push_back(i); } } } } // Construct the final ordered include directory list. - for (std::string const& i : userDirs) { - if (emitted.insert(i).second) { - dirs.push_back(i); + for (BT<std::string> const& i : userDirs) { + if (emitted.insert(i.Value).second) { + result.push_back(i); } } - this->MoveSystemIncludesToEnd(dirs, config, lang, target); + MoveSystemIncludesToEnd(result, config, lang, target); // Add standard include directories for this language. { - std::vector<std::string>::size_type const before = userDirs.size(); + std::vector<std::string> userStandardDirs; { std::string key = "CMAKE_"; key += lang; key += "_STANDARD_INCLUDE_DIRECTORIES"; std::string const value = this->Makefile->GetSafeDefinition(key); - cmSystemTools::ExpandListArgument(value, userDirs); + cmSystemTools::ExpandListArgument(value, userStandardDirs); } - for (std::vector<std::string>::iterator i = userDirs.begin() + before, - ie = userDirs.end(); - i != ie; ++i) { - cmSystemTools::ConvertToUnixSlashes(*i); - dirs.push_back(*i); + userDirs.reserve(userDirs.size() + userStandardDirs.size()); + for (std::string& d : userStandardDirs) { + cmSystemTools::ConvertToUnixSlashes(d); + result.emplace_back(d); + userDirs.emplace_back(std::move(d)); } } @@ -963,18 +1018,20 @@ void cmLocalGenerator::GetIncludeDirectories(std::vector<std::string>& dirs, // Append only implicit directories that were requested by the user for (std::string const& i : implicitDirs) { if (std::find(userDirs.begin(), userDirs.end(), i) != userDirs.end()) { - dirs.push_back(i); + result.emplace_back(i); } } // Append remaining implicit directories on demand if (appendAllImplicitDirs) { for (std::string const& i : implicitDirs) { - if (std::find(dirs.begin(), dirs.end(), i) == dirs.end()) { - dirs.push_back(i); + if (std::find(result.begin(), result.end(), i) == result.end()) { + result.emplace_back(i); } } } } + + return result; } void cmLocalGenerator::GetStaticLibraryFlags(std::string& flags, @@ -1231,13 +1288,29 @@ void cmLocalGenerator::GetTargetDefines(cmGeneratorTarget const* target, std::string const& lang, std::set<std::string>& defines) const { + std::set<BT<std::string>> tmp = this->GetTargetDefines(target, config, lang); + for (BT<std::string> const& v : tmp) { + defines.emplace(v.Value); + } +} + +std::set<BT<std::string>> cmLocalGenerator::GetTargetDefines( + cmGeneratorTarget const* target, std::string const& config, + std::string const& lang) const +{ + std::set<BT<std::string>> defines; + // Add the export symbol definition for shared library objects. - if (const char* exportMacro = target->GetExportMacro()) { - this->AppendDefines(defines, exportMacro); + if (const std::string* exportMacro = target->GetExportMacro()) { + this->AppendDefines(defines, *exportMacro); } // Add preprocessor definitions for this target and configuration. - this->AddCompileDefinitions(defines, target, config, lang); + std::vector<BT<std::string>> targetDefines = + target->GetCompileDefinitions(config, lang); + this->AppendDefines(defines, targetDefines); + + return defines; } std::string cmLocalGenerator::GetTargetFortranFlags( @@ -2037,24 +2110,32 @@ void cmLocalGenerator::AppendIncludeDirectories( void cmLocalGenerator::AppendDefines(std::set<std::string>& defines, const char* defines_list) const { + std::set<BT<std::string>> tmp; + this->AppendDefines(tmp, ExpandListWithBacktrace(defines_list)); + for (BT<std::string> const& i : tmp) { + defines.emplace(i.Value); + } +} + +void cmLocalGenerator::AppendDefines(std::set<BT<std::string>>& defines, + const char* defines_list) const +{ // Short-circuit if there are no definitions. if (!defines_list) { return; } // Expand the list of definitions. - std::vector<std::string> defines_vec; - cmSystemTools::ExpandListArgument(defines_list, defines_vec); - this->AppendDefines(defines, defines_vec); + this->AppendDefines(defines, ExpandListWithBacktrace(defines_list)); } void cmLocalGenerator::AppendDefines( - std::set<std::string>& defines, - const std::vector<std::string>& defines_vec) const + std::set<BT<std::string>>& defines, + const std::vector<BT<std::string>>& defines_vec) const { - for (std::string const& d : defines_vec) { + for (BT<std::string> const& d : defines_vec) { // Skip unsupported definitions. - if (!this->CheckDefinition(d)) { + if (!this->CheckDefinition(d.Value)) { continue; } defines.insert(d); diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h index 58b7762..95a8a6a 100644 --- a/Source/cmLocalGenerator.h +++ b/Source/cmLocalGenerator.h @@ -175,8 +175,15 @@ public: { this->AppendDefines(defines, defines_list.c_str()); } - void AppendDefines(std::set<std::string>& defines, - const std::vector<std::string>& defines_vec) const; + void AppendDefines(std::set<BT<std::string>>& defines, + const char* defines_list) const; + void AppendDefines(std::set<BT<std::string>>& defines, + std::string const& defines_list) const + { + this->AppendDefines(defines, defines_list.c_str()); + } + void AppendDefines(std::set<BT<std::string>>& defines, + const std::vector<BT<std::string>>& defines_vec) const; /** * Encode a list of compile options for the compiler @@ -249,12 +256,12 @@ public: const std::string& config = "", bool stripImplicitDirs = true, bool appendAllImplicitDirs = false) const; + std::vector<BT<std::string>> GetIncludeDirectories( + cmGeneratorTarget const* target, std::string const& lang = "C", + std::string const& config = "", bool stripImplicitDirs = true, + bool appendAllImplicitDirs = false) const; void AddCompileOptions(std::string& flags, cmGeneratorTarget* target, const std::string& lang, const std::string& config); - void AddCompileDefinitions(std::set<std::string>& defines, - cmGeneratorTarget const* target, - const std::string& config, - const std::string& lang) const; std::string GetProjectName() const; @@ -336,6 +343,9 @@ public: void GetTargetDefines(cmGeneratorTarget const* target, std::string const& config, std::string const& lang, std::set<std::string>& defines) const; + std::set<BT<std::string>> GetTargetDefines(cmGeneratorTarget const* target, + std::string const& config, + std::string const& lang) const; void GetTargetCompileFlags(cmGeneratorTarget* target, std::string const& config, std::string const& lang, std::string& flags); @@ -418,10 +428,6 @@ private: int targetType); void ComputeObjectMaxPath(); - void MoveSystemIncludesToEnd(std::vector<std::string>& includeDirs, - const std::string& config, - const std::string& lang, - cmGeneratorTarget const* target) const; }; #if defined(CMAKE_BUILD_WITH_CMAKE) diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx index 4d19b3a..6a535c1 100644 --- a/Source/cmLocalUnixMakefileGenerator3.cxx +++ b/Source/cmLocalUnixMakefileGenerator3.cxx @@ -17,6 +17,7 @@ #include "cmGeneratorTarget.h" #include "cmGlobalGenerator.h" #include "cmGlobalUnixMakefileGenerator3.h" +#include "cmListFileCache.h" #include "cmLocalGenerator.h" #include "cmMakefile.h" #include "cmMakefileTargetGenerator.h" @@ -1546,8 +1547,10 @@ void cmLocalUnixMakefileGenerator3::WriteLocalAllRules( if (!text) { text = "Running external command ..."; } - depends.insert(depends.end(), gt->GetUtilities().begin(), - gt->GetUtilities().end()); + depends.reserve(gt->GetUtilities().size()); + for (BT<std::string> const& u : gt->GetUtilities()) { + depends.push_back(u.Value); + } this->AppendEcho(commands, text, cmLocalUnixMakefileGenerator3::EchoGlobal); @@ -1819,8 +1822,8 @@ void cmLocalUnixMakefileGenerator3::WriteDependLanguageInfo( // Build a list of preprocessor definitions for the target. std::set<std::string> defines; - this->AddCompileDefinitions(defines, target, this->ConfigName, - implicitLang.first); + this->GetTargetDefines(target, this->ConfigName, implicitLang.first, + defines); if (!defines.empty()) { /* clang-format off */ cmakefileStream diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx index 8428672..1da077e 100644 --- a/Source/cmLocalVisualStudio7Generator.cxx +++ b/Source/cmLocalVisualStudio7Generator.cxx @@ -735,8 +735,8 @@ void cmLocalVisualStudio7Generator::WriteConfiguration( targetOptions.AddDefine(configDefine); // Add the export symbol definition for shared library objects. - if (const char* exportMacro = target->GetExportMacro()) { - targetOptions.AddDefine(exportMacro); + if (const std::string* exportMacro = target->GetExportMacro()) { + targetOptions.AddDefine(*exportMacro); } // The intermediate directory name consists of a directory for the diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 8d163b7..0a69d09 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -28,6 +28,7 @@ #include "cmGeneratorExpressionEvaluationFile.h" #include "cmGlobalGenerator.h" #include "cmInstallGenerator.h" // IWYU pragma: keep +#include "cmInstallSubdirectoryGenerator.h" #include "cmListFileCache.h" #include "cmSourceFile.h" #include "cmSourceFileLocation.h" @@ -1669,6 +1670,9 @@ void cmMakefile::AddSubDirectory(const std::string& srcPath, } else { this->UnConfiguredDirectories.push_back(subMf); } + + this->AddInstallGenerator(new cmInstallSubdirectoryGenerator( + subMf, binPath.c_str(), excludeFromAll)); } const std::string& cmMakefile::GetCurrentSourceDirectory() const diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h index a367e47..5c27124 100644 --- a/Source/cmPolicies.h +++ b/Source/cmPolicies.h @@ -236,11 +236,15 @@ class cmMakefile; "target_link_libraries allows use with targets in other directories.", 3, \ 13, 0, cmPolicies::WARN) \ SELECT(POLICY, CMP0080, \ - "BundleUtilities cannot be included at configure time", 3, 13, 0, \ + "BundleUtilities cannot be included at configure time.", 3, 13, 0, \ cmPolicies::WARN) \ SELECT(POLICY, CMP0081, \ "Relative paths not allowed in LINK_DIRECTORIES target property.", \ - 3, 13, 0, cmPolicies::WARN) + 3, 13, 0, cmPolicies::WARN) \ + SELECT(POLICY, CMP0082, \ + "Install rules from add_subdirectory() are interleaved with those " \ + "in caller.", \ + 3, 14, 0, cmPolicies::WARN) #define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1) #define CM_FOR_EACH_POLICY_ID(POLICY) \ diff --git a/Source/cmProjectCommand.cxx b/Source/cmProjectCommand.cxx index 305c7a6..8f565c8 100644 --- a/Source/cmProjectCommand.cxx +++ b/Source/cmProjectCommand.cxx @@ -300,19 +300,15 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args, } } - if (haveDescription) { - this->Makefile->AddDefinition("PROJECT_DESCRIPTION", description.c_str()); - this->Makefile->AddDefinition(projectName + "_DESCRIPTION", - description.c_str()); - TopLevelCMakeVarCondSet("CMAKE_PROJECT_DESCRIPTION", description.c_str()); - } + this->Makefile->AddDefinition("PROJECT_DESCRIPTION", description.c_str()); + this->Makefile->AddDefinition(projectName + "_DESCRIPTION", + description.c_str()); + TopLevelCMakeVarCondSet("CMAKE_PROJECT_DESCRIPTION", description.c_str()); - if (haveHomepage) { - this->Makefile->AddDefinition("PROJECT_HOMEPAGE_URL", homepage.c_str()); - this->Makefile->AddDefinition(projectName + "_HOMEPAGE_URL", - homepage.c_str()); - TopLevelCMakeVarCondSet("CMAKE_PROJECT_HOMEPAGE_URL", homepage.c_str()); - } + this->Makefile->AddDefinition("PROJECT_HOMEPAGE_URL", homepage.c_str()); + this->Makefile->AddDefinition(projectName + "_HOMEPAGE_URL", + homepage.c_str()); + TopLevelCMakeVarCondSet("CMAKE_PROJECT_HOMEPAGE_URL", homepage.c_str()); if (languages.empty()) { // if no language is specified do c and c++ diff --git a/Source/cmQtAutoGenInitializer.cxx b/Source/cmQtAutoGenInitializer.cxx index 8a202a2..7700767 100644 --- a/Source/cmQtAutoGenInitializer.cxx +++ b/Source/cmQtAutoGenInitializer.cxx @@ -12,6 +12,7 @@ #include "cmGeneratorTarget.h" #include "cmGlobalGenerator.h" #include "cmLinkItem.h" +#include "cmListFileCache.h" #include "cmLocalGenerator.h" #include "cmMakefile.h" #include "cmOutputConverter.h" @@ -416,7 +417,7 @@ bool cmQtAutoGenInitializer::InitMoc() auto GetCompileDefinitions = [this, localGen](std::string const& cfg) -> std::string { std::set<std::string> defines; - localGen->AddCompileDefinitions(defines, this->Target, cfg, "CXX"); + localGen->GetTargetDefines(this->Target, cfg, "CXX", defines); return cmJoin(defines, ";"); }; @@ -940,8 +941,8 @@ bool cmQtAutoGenInitializer::InitAutogenTarget() new cmGeneratorTarget(autogenTarget, localGen)); // Forward origin utilities to autogen target - for (std::string const& depName : this->Target->Target->GetUtilities()) { - autogenTarget->AddUtility(depName, makefile); + for (BT<std::string> const& depName : this->Target->GetUtilities()) { + autogenTarget->AddUtility(depName.Value, makefile); } // Add additional autogen target dependencies to autogen target for (cmTarget* depTarget : this->AutogenTarget.DependTargets) { diff --git a/Source/cmServerProtocol.cxx b/Source/cmServerProtocol.cxx index f75a5ce..f051fd9 100644 --- a/Source/cmServerProtocol.cxx +++ b/Source/cmServerProtocol.cxx @@ -164,12 +164,7 @@ bool cmServerProtocol::DoActivate(const cmServerRequest& /*request*/, std::pair<int, int> cmServerProtocol1::ProtocolVersion() const { - // Revision history - // 1, 1 - Report backtraces in codemodel response - // 1, 2 - Add target install destinations to codemodel - // 1, 3 - Add a flag to target filegroups indicating whether or not the - // filegroup is for INTERFACE_SOURCES - return std::make_pair(1, 3); + return std::make_pair(1, 2); } static void setErrorMessage(std::string* errorMessage, const std::string& text) diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index 8339aac..568ee82 100644 --- a/Source/cmSystemTools.cxx +++ b/Source/cmSystemTools.cxx @@ -1733,6 +1733,32 @@ void list_item_verbose(FILE* out, struct archive_entry* entry) fflush(out); } +bool la_diagnostic(struct archive* ar, __LA_SSIZE_T r) +{ + // See archive.h definition of ARCHIVE_OK for return values. + + if (r >= ARCHIVE_OK) { + return true; + } + + if (r >= ARCHIVE_WARN) { + const char* warn = archive_error_string(ar); + if (!warn) { + warn = "unknown warning"; + } + std::cerr << "cmake -E tar: warning: " << warn << '\n'; + return true; + } + + // Error. + const char* err = archive_error_string(ar); + if (!err) { + err = "unknown error"; + } + std::cerr << "cmake -E tar: error: " << err << '\n'; + return false; +} + // Return 'true' on success bool copy_data(struct archive* ar, struct archive* aw) { @@ -1746,24 +1772,17 @@ bool copy_data(struct archive* ar, struct archive* aw) # endif for (;;) { - // Return value: - // * ARCHIVE_OK - read succeed - // * ARCHIVE_EOF - no more data to read left + // See archive.h definition of ARCHIVE_OK for return values. r = archive_read_data_block(ar, &buff, &size, &offset); if (r == ARCHIVE_EOF) { return true; } - if (r != ARCHIVE_OK) { + if (!la_diagnostic(ar, r)) { return false; } - // Return value: - // * >= ARCHIVE_OK - write succeed - // * < ARCHIVE_OK - write failed - const __LA_SSIZE_T w_size = - archive_write_data_block(aw, buff, size, offset); - if (w_size < ARCHIVE_OK) { - cmSystemTools::Message("archive_write_data_block()", - archive_error_string(aw)); + // See archive.h definition of ARCHIVE_OK for return values. + __LA_SSIZE_T const w = archive_write_data_block(aw, buff, size, offset); + if (!la_diagnostic(ar, w)) { return false; } } @@ -1822,7 +1841,6 @@ bool extract_tar(const char* outFileName, bool verbose, bool extract) r = archive_write_header(ext, entry); if (r == ARCHIVE_OK) { if (!copy_data(a, ext)) { - cmSystemTools::Error("Problem with copy_data"); break; } r = archive_write_finish_entry(ext); @@ -2826,11 +2844,11 @@ bool cmSystemTools::RemoveRPath(std::string const& file, std::string* emsg, // contain the location of the linker map, however on MIPS the // .dynamic section is always read-only so this is not possible. MIPS // objects instead contain a DT_MIPS_RLD_MAP tag which contains the - // address where the dyanmic linker will write to (an indirect + // address where the dynamic linker will write to (an indirect // version of DT_DEBUG). Since this doesn't work when using PIE, a // relative equivalent was created - DT_MIPS_RLD_MAP_REL. Since this // version contains a relative offset, moving it changes the - // calculated address. This may cause the dyanmic linker to write + // calculated address. This may cause the dynamic linker to write // into memory it should not be changing. // // To fix this, we adjust the value of DT_MIPS_RLD_MAP_REL here. If diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index f0d6519..1458f01 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -486,24 +486,10 @@ cmGlobalGenerator* cmTarget::GetGlobalGenerator() const return this->GetMakefile()->GetGlobalGenerator(); } -void cmTarget::AddUtility(const std::string& u, cmMakefile* makefile) +void cmTarget::AddUtility(std::string const& u, cmMakefile* mf) { - if (this->Utilities.insert(u).second && makefile) { - this->UtilityBacktraces.insert( - std::make_pair(u, makefile->GetBacktrace())); - } -} - -cmListFileBacktrace const* cmTarget::GetUtilityBacktrace( - const std::string& u) const -{ - std::map<std::string, cmListFileBacktrace>::const_iterator i = - this->UtilityBacktraces.find(u); - if (i == this->UtilityBacktraces.end()) { - return nullptr; - } - - return &i->second; + BT<std::string> util(u, mf ? mf->GetBacktrace() : cmListFileBacktrace()); + this->Utilities.insert(util); } cmListFileBacktrace const& cmTarget::GetBacktrace() const diff --git a/Source/cmTarget.h b/Source/cmTarget.h index 694de1c..aa2859d 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -190,10 +190,12 @@ public: * name as would be specified to the ADD_EXECUTABLE or UTILITY_SOURCE * commands. It is not a full path nor does it have an extension. */ - void AddUtility(const std::string& u, cmMakefile* makefile = nullptr); + void AddUtility(std::string const& u, cmMakefile* mf = nullptr); ///! Get the utilities used by this target - std::set<std::string> const& GetUtilities() const { return this->Utilities; } - cmListFileBacktrace const* GetUtilityBacktrace(const std::string& u) const; + std::set<BT<std::string>> const& GetUtilities() const + { + return this->Utilities; + } ///! Set/Get a property of this target file void SetProperty(const std::string& prop, const char* value); @@ -307,8 +309,7 @@ private: bool IsGeneratorProvided; cmPropertyMap Properties; std::set<std::string> SystemIncludeDirectories; - std::set<std::string> Utilities; - std::map<std::string, cmListFileBacktrace> UtilityBacktraces; + std::set<BT<std::string>> Utilities; cmPolicies::PolicyMap PolicyMap; std::string Name; std::string InstallPath; diff --git a/Source/cmTargetDepend.h b/Source/cmTargetDepend.h index b698db6..5ea0085 100644 --- a/Source/cmTargetDepend.h +++ b/Source/cmTargetDepend.h @@ -19,6 +19,7 @@ class cmTargetDepend // mutable members to achieve a map with set syntax. mutable bool Link; mutable bool Util; + mutable cmListFileBacktrace Backtrace; public: cmTargetDepend(cmGeneratorTarget const* t) @@ -42,8 +43,13 @@ public: this->Link = true; } } + void SetBacktrace(cmListFileBacktrace const& bt) const + { + this->Backtrace = bt; + } bool IsLink() const { return this->Link; } bool IsUtil() const { return this->Util; } + cmListFileBacktrace const& GetBacktrace() const { return this->Backtrace; } }; /** Unordered set of (direct) dependencies of a target. */ diff --git a/Source/cmTimestamp.cxx b/Source/cmTimestamp.cxx index 14cf6e9..da5d21e 100644 --- a/Source/cmTimestamp.cxx +++ b/Source/cmTimestamp.cxx @@ -96,7 +96,7 @@ time_t cmTimestamp::CreateUtcTimeTFromTm(struct tm& tm) const // From Linux timegm() manpage. std::string tz_old; - cmSystemTools::GetEnv("TZ", tz_old); + bool const tz_was_set = cmSystemTools::GetEnv("TZ", tz_old); tz_old = "TZ=" + tz_old; // The standard says that "TZ=" or "TZ=[UNRECOGNIZED_TZ]" means UTC. @@ -109,7 +109,17 @@ time_t cmTimestamp::CreateUtcTimeTFromTm(struct tm& tm) const time_t result = mktime(&tm); +# ifdef CMAKE_BUILD_WITH_CMAKE + if (tz_was_set) { + cmSystemTools::PutEnv(tz_old); + } else { + cmSystemTools::UnsetEnv("TZ"); + } +# else + // No UnsetEnv during bootstrap. This is good enough for CMake itself. cmSystemTools::PutEnv(tz_old); + static_cast<void>(tz_was_set); +# endif tzset(); diff --git a/Source/cmVS10CSharpFlagTable.h b/Source/cmVS10CSharpFlagTable.h index 18d587c..6ac7a76 100644 --- a/Source/cmVS10CSharpFlagTable.h +++ b/Source/cmVS10CSharpFlagTable.h @@ -21,8 +21,8 @@ static cmVS7FlagTable cmVS10CSharpFlagTable[] = { { "AddModules", "addmodule:", "", "", cmIDEFlagTable::SemicolonAppendable }, { "", "link", "", "", 0 }, - { "Win32Resource", "win32res", "", "", cmIDEFlagTable::UserValueRequired }, - { "ApplicationIcon", "win32icon", "", "", + { "Win32Resource", "win32res:", "", "", cmIDEFlagTable::UserValueRequired }, + { "ApplicationIcon", "win32icon:", "", "", cmIDEFlagTable::UserValueRequired }, { "ApplicationManifest", "win32manifest:", "", "", diff --git a/Source/cmVS11CSharpFlagTable.h b/Source/cmVS11CSharpFlagTable.h index e3ba83c..18b804a 100644 --- a/Source/cmVS11CSharpFlagTable.h +++ b/Source/cmVS11CSharpFlagTable.h @@ -21,8 +21,8 @@ static cmVS7FlagTable cmVS11CSharpFlagTable[] = { { "AddModules", "addmodule:", "", "", cmIDEFlagTable::SemicolonAppendable }, { "", "link", "", "", 0 }, - { "Win32Resource", "win32res", "", "", cmIDEFlagTable::UserValueRequired }, - { "ApplicationIcon", "win32icon", "", "", + { "Win32Resource", "win32res:", "", "", cmIDEFlagTable::UserValueRequired }, + { "ApplicationIcon", "win32icon:", "", "", cmIDEFlagTable::UserValueRequired }, { "ApplicationManifest", "win32manifest:", "", "", diff --git a/Source/cmVS12CSharpFlagTable.h b/Source/cmVS12CSharpFlagTable.h index f8db636..0370499 100644 --- a/Source/cmVS12CSharpFlagTable.h +++ b/Source/cmVS12CSharpFlagTable.h @@ -21,8 +21,8 @@ static cmVS7FlagTable cmVS12CSharpFlagTable[] = { { "AddModules", "addmodule:", "", "", cmIDEFlagTable::SemicolonAppendable }, { "", "link", "", "", 0 }, - { "Win32Resource", "win32res", "", "", cmIDEFlagTable::UserValueRequired }, - { "ApplicationIcon", "win32icon", "", "", + { "Win32Resource", "win32res:", "", "", cmIDEFlagTable::UserValueRequired }, + { "ApplicationIcon", "win32icon:", "", "", cmIDEFlagTable::UserValueRequired }, { "ApplicationManifest", "win32manifest:", "", "", diff --git a/Source/cmVS140CSharpFlagTable.h b/Source/cmVS140CSharpFlagTable.h index 055d5cb..f695f45 100644 --- a/Source/cmVS140CSharpFlagTable.h +++ b/Source/cmVS140CSharpFlagTable.h @@ -21,8 +21,8 @@ static cmVS7FlagTable cmVS140CSharpFlagTable[] = { { "AddModules", "addmodule:", "", "", cmIDEFlagTable::SemicolonAppendable }, { "", "link", "", "", 0 }, - { "Win32Resource", "win32res", "", "", cmIDEFlagTable::UserValueRequired }, - { "ApplicationIcon", "win32icon", "", "", + { "Win32Resource", "win32res:", "", "", cmIDEFlagTable::UserValueRequired }, + { "ApplicationIcon", "win32icon:", "", "", cmIDEFlagTable::UserValueRequired }, { "ApplicationManifest", "win32manifest:", "", "", diff --git a/Source/cmVS141CLFlagTable.h b/Source/cmVS141CLFlagTable.h index 7d3e356..2a9944a 100644 --- a/Source/cmVS141CLFlagTable.h +++ b/Source/cmVS141CLFlagTable.h @@ -83,6 +83,8 @@ static cmVS7FlagTable cmVS141CLFlagTable[] = { { "FloatingPointModel", "fp:strict", "Strict", "Strict", 0 }, { "FloatingPointModel", "fp:fast", "Fast", "Fast", 0 }, + { "SpectreMitigation", "Qspectre", "Spectre mitigations", "Spectre", 0 }, + { "LanguageStandard", "std:c++17", "ISO C++17 Standard", "stdcpp17", 0 }, { "LanguageStandard", "std:c++14", "ISO C++14 Standard", "stdcpp14", 0 }, { "LanguageStandard", "std:c++latest", "ISO C++ Latest Draft Standard", diff --git a/Source/cmVS141CSharpFlagTable.h b/Source/cmVS141CSharpFlagTable.h index 66c61bd..1f84097 100644 --- a/Source/cmVS141CSharpFlagTable.h +++ b/Source/cmVS141CSharpFlagTable.h @@ -21,8 +21,8 @@ static cmVS7FlagTable cmVS141CSharpFlagTable[] = { { "AddModules", "addmodule:", "", "", cmIDEFlagTable::SemicolonAppendable }, { "", "link", "", "", 0 }, - { "Win32Resource", "win32res", "", "", cmIDEFlagTable::UserValueRequired }, - { "ApplicationIcon", "win32icon", "", "", + { "Win32Resource", "win32res:", "", "", cmIDEFlagTable::UserValueRequired }, + { "ApplicationIcon", "win32icon:", "", "", cmIDEFlagTable::UserValueRequired }, { "ApplicationManifest", "win32manifest:", "", "", diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 16eca96..eb1a27e 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -45,24 +45,21 @@ struct cmVisualStudio10TargetGenerator::Elem bool HasContent = false; std::string Tag; - Elem(std::ostream& s) + Elem(std::ostream& s, const char* tag) : S(s) , Indent(0) + , Tag(tag) { + this->StartElement(); } Elem(const Elem&) = delete; - Elem(Elem& par) - : S(par.S) - , Indent(par.Indent + 1) - { - par.SetHasElements(); - } Elem(Elem& par, const char* tag) : S(par.S) , Indent(par.Indent + 1) + , Tag(tag) { par.SetHasElements(); - this->StartElement(tag); + this->StartElement(); } void SetHasElements() { @@ -72,12 +69,7 @@ struct cmVisualStudio10TargetGenerator::Elem } } std::ostream& WriteString(const char* line); - Elem& StartElement(const std::string& tag) - { - this->Tag = tag; - this->WriteString("<") << tag; - return *this; - } + void StartElement() { this->WriteString("<") << this->Tag; } void Element(const char* tag, const std::string& val) { Elem(*this, tag).Content(val); @@ -87,8 +79,6 @@ struct cmVisualStudio10TargetGenerator::Elem this->S << " " << an << "=\"" << cmVS10EscapeAttr(av) << "\""; return *this; } - // This method for now assumes that this->Tag has been set, e.g. by calling - // StartElement(). void Content(const std::string& val) { if (!this->HasContent) { @@ -380,8 +370,7 @@ void cmVisualStudio10TargetGenerator::Generate() << this->GlobalGenerator->Encoding() << "\"?>" << "\n"; { - Elem e0(BuildFileStream); - e0.StartElement("Project"); + Elem e0(BuildFileStream, "Project"); e0.Attribute("DefaultTargets", "Build"); e0.Attribute("ToolsVersion", this->GlobalGenerator->GetToolsVersion()); e0.Attribute("xmlns", @@ -922,8 +911,8 @@ void cmVisualStudio10TargetGenerator::WriteXamlFilesGroup(Elem& e0) xamlType = "Page"; } - Elem e2(e1); - this->WriteSource(e2, xamlType, oi); + Elem e2(e1, xamlType); + this->WriteSource(e2, oi); e2.SetHasElements(); if (this->ProjectType == csproj && !this->InSourceBuild) { // add <Link> tag to written XAML source if necessary @@ -1125,11 +1114,18 @@ void cmVisualStudio10TargetGenerator::WriteMSToolConfigurationValues( if (this->IPOEnabledConfigurations.count(config) > 0) { e1.Element("WholeProgramOptimization", "true"); } + if (this->SpectreMitigationConfigurations.count(config) > 0) { + e1.Element("SpectreMitigation", "Spectre"); + } } void cmVisualStudio10TargetGenerator::WriteMSToolConfigurationValuesManaged( Elem& e1, std::string const& config) { + if (this->GeneratorTarget->GetType() > cmStateEnums::OBJECT_LIBRARY) { + return; + } + cmGlobalVisualStudio10Generator* gg = this->GlobalGenerator; Options& o = *(this->ClOptions[config]); @@ -1272,15 +1268,15 @@ void cmVisualStudio10TargetGenerator::WriteCustomRule( std::unique_ptr<Elem> spe2; if (this->ProjectType != csproj) { spe1 = cm::make_unique<Elem>(e0, "ItemGroup"); - spe2 = cm::make_unique<Elem>(*spe1); - this->WriteSource(*spe2, "CustomBuild", source); + spe2 = cm::make_unique<Elem>(*spe1, "CustomBuild"); + this->WriteSource(*spe2, source); spe2->SetHasElements(); } else { Elem e1(e0, "ItemGroup"); - Elem e2(e1); + Elem e2(e1, "None"); std::string link; this->GetCSharpSourceLink(source, link); - this->WriteSource(e2, "None", source); + this->WriteSource(e2, source); e2.SetHasElements(); if (!link.empty()) { e2.Element("Link", link); @@ -1414,8 +1410,7 @@ void cmVisualStudio10TargetGenerator::WriteGroups() << this->GlobalGenerator->Encoding() << "\"?>" << "\n"; { - Elem e0(fout); - e0.StartElement("Project"); + Elem e0(fout, "Project"); e0.Attribute("ToolsVersion", this->GlobalGenerator->GetToolsVersion()); e0.Attribute("xmlns", "http://schemas.microsoft.com/developer/msbuild/2003"); @@ -1566,8 +1561,8 @@ void cmVisualStudio10TargetGenerator::WriteHeaderSource(Elem& e1, cmSourceFile const* sf) { std::string const& fileName = sf->GetFullPath(); - Elem e2(e1); - this->WriteSource(e2, "ClInclude", sf); + Elem e2(e1, "ClInclude"); + this->WriteSource(e2, sf); if (this->IsResxHeader(fileName)) { e2.Element("FileType", "CppForm"); } else if (this->IsXamlHeader(fileName)) { @@ -1735,8 +1730,8 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(Elem& e1, } } - Elem e2(e1); - this->WriteSource(e2, tool, sf); + Elem e2(e1, tool); + this->WriteSource(e2, sf); if (toolHasSettings) { e2.SetHasElements(); @@ -1856,7 +1851,6 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(Elem& e1, } void cmVisualStudio10TargetGenerator::WriteSource(Elem& e2, - std::string const& tool, cmSourceFile const* sf) { // Visual Studio tools append relative paths to the current dir, as in: @@ -1892,11 +1886,10 @@ void cmVisualStudio10TargetGenerator::WriteSource(Elem& e2, } } ConvertToWindowsSlash(sourceFile); - e2.StartElement(tool); e2.Attribute("Include", sourceFile); ToolSource toolSource = { sf, forceRelative }; - this->Tools[tool].push_back(toolSource); + this->Tools[e2.Tag].push_back(toolSource); } void cmVisualStudio10TargetGenerator::WriteAllSources(Elem& e0) @@ -2000,8 +1993,8 @@ void cmVisualStudio10TargetGenerator::WriteAllSources(Elem& e0) include_configs.begin(), include_configs.end(), std::back_inserter(exclude_configs)); - Elem e2(e1); - this->WriteSource(e2, tool, si.Source); + Elem e2(e1, tool); + this->WriteSource(e2, si.Source); if (si.Kind == cmGeneratorTarget::SourceKindObjectSource) { this->OutputSourceSpecificFlags(e2, si.Source); } @@ -2577,8 +2570,9 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions( configDefine += configName; configDefine += "\""; clOptions.AddDefine(configDefine); - if (const char* exportMacro = this->GeneratorTarget->GetExportMacro()) { - clOptions.AddDefine(exportMacro); + if (const std::string* exportMacro = + this->GeneratorTarget->GetExportMacro()) { + clOptions.AddDefine(*exportMacro); } if (this->MSTools) { @@ -2625,6 +2619,11 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions( } } + if (clOptions.HasFlag("SpectreMitigation")) { + this->SpectreMitigationConfigurations.insert(configName); + clOptions.RemoveFlag("SpectreMitigation"); + } + this->ClOptions[configName] = std::move(pOptions); return true; } @@ -2671,6 +2670,13 @@ void cmVisualStudio10TargetGenerator::WriteClOptions( // Specify the compiler program database file if configured. std::string pdb = this->GeneratorTarget->GetCompilePDBPath(configName); if (!pdb.empty()) { + if (this->GlobalGenerator->IsCudaEnabled()) { + // CUDA does not quote paths with spaces correctly when forwarding + // this to the host compiler. Use a relative path to avoid spaces. + // FIXME: We can likely do this even when CUDA is not involved, + // but for now we will make a minimal change. + pdb = this->ConvertPath(pdb, true); + } ConvertToWindowsSlash(pdb); e2.Element("ProgramDataBaseFileName", pdb); } @@ -2811,15 +2817,19 @@ bool cmVisualStudio10TargetGenerator::ComputeCudaOptions( // Specify the compiler program database file if configured. std::string pdb = this->GeneratorTarget->GetCompilePDBPath(configName); if (!pdb.empty()) { - // CUDA does not have a field for this and does not honor the - // ProgramDataBaseFileName field in ClCompile. Work around this - // limitation by creating the directory and passing the flag ourselves. + // CUDA does not make the directory if it is non-standard. std::string const pdbDir = cmSystemTools::GetFilenamePath(pdb); cmSystemTools::MakeDirectory(pdbDir); - pdb = this->ConvertPath(pdb, true); - ConvertToWindowsSlash(pdb); - std::string const clFd = "-Xcompiler=\"-Fd\\\"" + pdb + "\\\"\""; - cudaOptions.AppendFlagString("AdditionalOptions", clFd); + if (cmSystemTools::VersionCompareGreaterEq( + "9.2", this->GlobalGenerator->GetPlatformToolsetCudaString())) { + // CUDA does not have a field for this and does not honor the + // ProgramDataBaseFileName field in ClCompile. Work around this + // limitation by creating the directory and passing the flag ourselves. + pdb = this->ConvertPath(pdb, true); + ConvertToWindowsSlash(pdb); + std::string const clFd = "-Xcompiler=\"-Fd\\\"" + pdb + "\\\"\""; + cudaOptions.AppendFlagString("AdditionalOptions", clFd); + } } // CUDA automatically passes the proper '--machine' flag to nvcc @@ -2858,8 +2868,9 @@ bool cmVisualStudio10TargetGenerator::ComputeCudaOptions( configDefine += configName; configDefine += "\""; cudaOptions.AddDefine(configDefine); - if (const char* exportMacro = this->GeneratorTarget->GetExportMacro()) { - cudaOptions.AddDefine(exportMacro); + if (const std::string* exportMacro = + this->GeneratorTarget->GetExportMacro()) { + cudaOptions.AddDefine(*exportMacro); } // Get includes for this target @@ -3863,15 +3874,13 @@ void cmVisualStudio10TargetGenerator::WriteSinglePlatformExtension( void cmVisualStudio10TargetGenerator::WriteSDKReferences(Elem& e0) { std::vector<std::string> sdkReferences; - Elem e1(e0); - bool hasWrittenItemGroup = false; + std::unique_ptr<Elem> spe1; if (const char* vsSDKReferences = this->GeneratorTarget->GetProperty("VS_SDK_REFERENCES")) { cmSystemTools::ExpandListArgument(vsSDKReferences, sdkReferences); - e1.StartElement("ItemGroup"); - hasWrittenItemGroup = true; + spe1 = cm::make_unique<Elem>(e0, "ItemGroup"); for (std::string const& ri : sdkReferences) { - Elem(e1, "SDKReference").Attribute("Include", ri); + Elem(*spe1, "SDKReference").Attribute("Include", ri); } } @@ -3887,19 +3896,20 @@ void cmVisualStudio10TargetGenerator::WriteSDKReferences(Elem& e0) if (desktopExtensionsVersion || mobileExtensionsVersion || iotExtensionsVersion) { - if (!hasWrittenItemGroup) { - e1.StartElement("ItemGroup"); + if (!spe1) { + spe1 = cm::make_unique<Elem>(e0, "ItemGroup"); } if (desktopExtensionsVersion) { - this->WriteSingleSDKReference(e1, "WindowsDesktop", + this->WriteSingleSDKReference(*spe1, "WindowsDesktop", desktopExtensionsVersion); } if (mobileExtensionsVersion) { - this->WriteSingleSDKReference(e1, "WindowsMobile", + this->WriteSingleSDKReference(*spe1, "WindowsMobile", mobileExtensionsVersion); } if (iotExtensionsVersion) { - this->WriteSingleSDKReference(e1, "WindowsIoT", iotExtensionsVersion); + this->WriteSingleSDKReference(*spe1, "WindowsIoT", + iotExtensionsVersion); } } } diff --git a/Source/cmVisualStudio10TargetGenerator.h b/Source/cmVisualStudio10TargetGenerator.h index 829d2bf..b17b5f8 100644 --- a/Source/cmVisualStudio10TargetGenerator.h +++ b/Source/cmVisualStudio10TargetGenerator.h @@ -63,7 +63,7 @@ private: void WriteExtraSource(Elem& e1, cmSourceFile const* sf); void WriteNsightTegraConfigurationValues(Elem& e1, std::string const& config); - void WriteSource(Elem& e2, std::string const& tool, cmSourceFile const* sf); + void WriteSource(Elem& e2, cmSourceFile const* sf); void WriteExcludeFromBuild(Elem& e2, std::vector<size_t> const& exclude_configs); void WriteAllSources(Elem& e0); @@ -205,6 +205,7 @@ private: unsigned int NsightTegraVersion[4]; bool TargetCompileAsWinRT; std::set<std::string> IPOEnabledConfigurations; + std::set<std::string> SpectreMitigationConfigurations; cmGlobalVisualStudio10Generator* const GlobalGenerator; cmLocalVisualStudio10Generator* const LocalGenerator; std::set<std::string> CSharpCustomCommandNames; diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx index 1d2f741..e2225ff 100644 --- a/Source/cmcmd.cxx +++ b/Source/cmcmd.cxx @@ -323,11 +323,15 @@ static int HandleCppCheck(const std::string& runCmd, stdErr.find("(performance)") != std::string::npos || stdErr.find("(portability)") != std::string::npos || stdErr.find("(information)") != std::string::npos) { - std::cerr << "Warning: cppcheck reported diagnostics:\n"; + if (ret == 0) { + std::cerr << "Warning: cppcheck reported diagnostics:\n"; + } else { + std::cerr << "Error: cppcheck reported failure:\n"; + } } std::cerr << stdErr; - // ignore errors so build continues - return 0; + + return ret; } typedef int (*CoCompileHandler)(const std::string&, const std::string&, diff --git a/Source/kwsys/CMakeLists.txt b/Source/kwsys/CMakeLists.txt index 516104b..43aec00 100644 --- a/Source/kwsys/CMakeLists.txt +++ b/Source/kwsys/CMakeLists.txt @@ -35,6 +35,7 @@ # target_link_libraries. Because of how interface # properties propagate, this target is not suitable # for use with PUBLIC or INTERFACE linking. +# KWSYS_ALIAS_TARGET = The name of an alias target to create to the actual target. # # Example: # @@ -887,6 +888,9 @@ IF(KWSYS_C_SRCS OR KWSYS_CXX_SRCS) ADD_LIBRARY(${KWSYS_TARGET_INTERFACE} ${KWSYS_LIBRARY_TYPE} ${KWSYS_C_SRCS} ${KWSYS_CXX_SRCS}) ENDIF() + if (KWSYS_ALIAS_TARGET) + add_library(${KWSYS_ALIAS_TARGET} ALIAS ${KWSYS_TARGET_INTERFACE}) + endif () SET_TARGET_PROPERTIES(${KWSYS_TARGET_OBJECT} PROPERTIES C_CLANG_TIDY "" CXX_CLANG_TIDY "" diff --git a/Source/kwsys/SystemInformation.cxx b/Source/kwsys/SystemInformation.cxx index 7545ec7..d368fa2 100644 --- a/Source/kwsys/SystemInformation.cxx +++ b/Source/kwsys/SystemInformation.cxx @@ -112,7 +112,8 @@ typedef int siginfo_t; # endif #endif -#if defined(__linux) || defined(__sun) || defined(_SCO_DS) +#if defined(__linux) || defined(__sun) || defined(_SCO_DS) || \ + defined(__GLIBC__) || defined(__GNU__) # include <netdb.h> # include <netinet/in.h> # include <sys/socket.h> |