diff options
Diffstat (limited to 'Source')
96 files changed, 975 insertions, 771 deletions
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 42eed4d..695e075 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -242,6 +242,8 @@ set(SRCS cmFileTime.h cmFileTimeCache.cxx cmFileTimeCache.h + cmFileTimes.cxx + cmFileTimes.h cmFortranParserImpl.cxx cmFSPermissions.cxx cmFSPermissions.h @@ -786,6 +788,8 @@ set(SRCS ${SRCS} cmNinjaUtilityTargetGenerator.h cmNinjaLinkLineComputer.cxx cmNinjaLinkLineComputer.h + cmNinjaLinkLineDeviceComputer.cxx + cmNinjaLinkLineDeviceComputer.h ) # Temporary variable for tools targets diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 4303c25..63f1dce 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 14) -set(CMake_VERSION_PATCH 20190521) +set(CMake_VERSION_PATCH 20190530) #set(CMake_VERSION_RC 1) diff --git a/Source/CPack/cmCPackGenerator.cxx b/Source/CPack/cmCPackGenerator.cxx index 127bcf9..7e07ff4 100644 --- a/Source/CPack/cmCPackGenerator.cxx +++ b/Source/CPack/cmCPackGenerator.cxx @@ -15,6 +15,7 @@ #include "cmCryptoHash.h" #include "cmDuration.h" #include "cmFSPermissions.h" +#include "cmFileTimes.h" #include "cmGeneratedFileStream.h" #include "cmGlobalGenerator.h" #include "cmMakefile.h" @@ -388,7 +389,7 @@ int cmCPackGenerator::InstallProjectViaInstalledDirectories( } /* If it is not a symlink then do a plain copy */ else if (!(cmSystemTools::CopyFileIfDifferent(inFile, filePath) && - cmSystemTools::CopyFileTime(inFile, filePath))) { + cmFileTimes::Copy(inFile, filePath))) { cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem copying file: " << inFile << " -> " << filePath << std::endl); diff --git a/Source/CTest/cmCTestBZR.cxx b/Source/CTest/cmCTestBZR.cxx index 83aeb64..b957856 100644 --- a/Source/CTest/cmCTestBZR.cxx +++ b/Source/CTest/cmCTestBZR.cxx @@ -2,6 +2,7 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmCTestBZR.h" +#include "cmAlgorithms.h" #include "cmCTest.h" #include "cmCTestVC.h" #include "cmProcessTools.h" @@ -242,7 +243,7 @@ private: void CharacterDataHandler(const char* data, int length) override { - this->CData.insert(this->CData.end(), data, data + length); + cmAppend(this->CData, data, data + length); } void EndElement(const std::string& name) override diff --git a/Source/CTest/cmCTestBuildHandler.cxx b/Source/CTest/cmCTestBuildHandler.cxx index 1e17e1c..c8e4fa1 100644 --- a/Source/CTest/cmCTestBuildHandler.cxx +++ b/Source/CTest/cmCTestBuildHandler.cxx @@ -978,8 +978,7 @@ void cmCTestBuildHandler::ProcessBuffer(const char* data, size_t length, if (it != queue->end()) { // Create a contiguous array for the line this->CurrentProcessingLine.clear(); - this->CurrentProcessingLine.insert(this->CurrentProcessingLine.end(), - queue->begin(), it); + cmAppend(this->CurrentProcessingLine, queue->begin(), it); this->CurrentProcessingLine.push_back(0); const char* line = this->CurrentProcessingLine.data(); diff --git a/Source/CTest/cmCTestCoverageHandler.cxx b/Source/CTest/cmCTestCoverageHandler.cxx index d76bd2a..f6028c4 100644 --- a/Source/CTest/cmCTestCoverageHandler.cxx +++ b/Source/CTest/cmCTestCoverageHandler.cxx @@ -2,6 +2,7 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmCTestCoverageHandler.h" +#include "cmAlgorithms.h" #include "cmCTest.h" #include "cmDuration.h" #include "cmGeneratedFileStream.h" @@ -813,15 +814,11 @@ int cmCTestCoverageHandler::HandleJacocoCoverage( // ...and in the binary directory. cmsys::Glob g2; - std::vector<std::string> binFiles; g2.SetRecurse(true); std::string binaryDir = this->CTest->GetCTestConfiguration("BuildDirectory"); std::string binCoverageFile = binaryDir + "/*jacoco.xml"; g2.FindFiles(binCoverageFile); - binFiles = g2.GetFiles(); - if (!binFiles.empty()) { - files.insert(files.end(), binFiles.begin(), binFiles.end()); - } + cmAppend(files, g2.GetFiles()); if (!files.empty()) { cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, @@ -1465,8 +1462,7 @@ int cmCTestCoverageHandler::HandleLCovCoverage( " looking for LCOV files in: " << daGlob << std::endl, this->Quiet); gl.FindFiles(daGlob); // Keep a list of all LCOV files - lcovFiles.insert(lcovFiles.end(), gl.GetFiles().begin(), - gl.GetFiles().end()); + cmAppend(lcovFiles, gl.GetFiles()); for (std::string const& file : lcovFiles) { lcovFile = file; @@ -1604,11 +1600,11 @@ void cmCTestCoverageHandler::FindGCovFiles(std::vector<std::string>& files) std::string daGlob = lm.first; daGlob += "/*.da"; gl.FindFiles(daGlob); - files.insert(files.end(), gl.GetFiles().begin(), gl.GetFiles().end()); + cmAppend(files, gl.GetFiles()); daGlob = lm.first; daGlob += "/*.gcda"; gl.FindFiles(daGlob); - files.insert(files.end(), gl.GetFiles().begin(), gl.GetFiles().end()); + cmAppend(files, gl.GetFiles()); } } @@ -1645,7 +1641,7 @@ bool cmCTestCoverageHandler::FindLCovFiles(std::vector<std::string>& files) "Error while finding files matching " << daGlob << std::endl); return false; } - files.insert(files.end(), gl.GetFiles().begin(), gl.GetFiles().end()); + cmAppend(files, gl.GetFiles()); cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Now searching in: " << daGlob << std::endl, this->Quiet); return true; diff --git a/Source/CTest/cmCTestCurl.cxx b/Source/CTest/cmCTestCurl.cxx index 6eb4354..cc63e45 100644 --- a/Source/CTest/cmCTestCurl.cxx +++ b/Source/CTest/cmCTestCurl.cxx @@ -2,6 +2,7 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmCTestCurl.h" +#include "cmAlgorithms.h" #include "cmCTest.h" #include "cmCurl.h" #include "cmSystemTools.h" @@ -43,19 +44,15 @@ size_t curlWriteMemoryCallback(void* ptr, size_t size, size_t nmemb, void* data) { int realsize = static_cast<int>(size * nmemb); - - std::vector<char>* vec = static_cast<std::vector<char>*>(data); const char* chPtr = static_cast<char*>(ptr); - vec->insert(vec->end(), chPtr, chPtr + realsize); + cmAppend(*static_cast<std::vector<char>*>(data), chPtr, chPtr + realsize); return realsize; } size_t curlDebugCallback(CURL* /*unused*/, curl_infotype /*unused*/, char* chPtr, size_t size, void* data) { - std::vector<char>* vec = static_cast<std::vector<char>*>(data); - vec->insert(vec->end(), chPtr, chPtr + size); - + cmAppend(*static_cast<std::vector<char>*>(data), chPtr, chPtr + size); return size; } } diff --git a/Source/CTest/cmCTestHG.cxx b/Source/CTest/cmCTestHG.cxx index 727c59c..ba2252a 100644 --- a/Source/CTest/cmCTestHG.cxx +++ b/Source/CTest/cmCTestHG.cxx @@ -2,6 +2,7 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmCTestHG.h" +#include "cmAlgorithms.h" #include "cmCTest.h" #include "cmCTestVC.h" #include "cmProcessTools.h" @@ -202,7 +203,7 @@ private: void CharacterDataHandler(const char* data, int length) override { - this->CData.insert(this->CData.end(), data, data + length); + cmAppend(this->CData, data, data + length); } void EndElement(const std::string& name) override diff --git a/Source/CTest/cmCTestMultiProcessHandler.cxx b/Source/CTest/cmCTestMultiProcessHandler.cxx index 477161a..ef63073 100644 --- a/Source/CTest/cmCTestMultiProcessHandler.cxx +++ b/Source/CTest/cmCTestMultiProcessHandler.cxx @@ -3,6 +3,7 @@ #include "cmCTestMultiProcessHandler.h" #include "cmAffinity.h" +#include "cmAlgorithms.h" #include "cmCTest.h" #include "cmCTestRunTest.h" #include "cmCTestTestHandler.h" @@ -653,13 +654,10 @@ void cmCTestMultiProcessHandler::CreateParallelTestCostList() // Reverse iterate over the different dependency levels (deepest first). // Sort tests within each level by COST and append them to the cost list. for (TestSet const& currentSet : cmReverseRange(priorityStack)) { - TestComparator comp(this); - TestList sortedCopy; - - sortedCopy.insert(sortedCopy.end(), currentSet.begin(), currentSet.end()); - - std::stable_sort(sortedCopy.begin(), sortedCopy.end(), comp); + cmAppend(sortedCopy, currentSet); + std::stable_sort(sortedCopy.begin(), sortedCopy.end(), + TestComparator(this)); for (auto const& j : sortedCopy) { if (alreadySortedTests.find(j) == alreadySortedTests.end()) { @@ -688,8 +686,8 @@ void cmCTestMultiProcessHandler::CreateSerialTestCostList() presortedList.push_back(i.first); } - TestComparator comp(this); - std::stable_sort(presortedList.begin(), presortedList.end(), comp); + std::stable_sort(presortedList.begin(), presortedList.end(), + TestComparator(this)); TestSet alreadySortedTests; @@ -992,7 +990,7 @@ static Json::Value DumpCTestInfo( const std::vector<std::string>& args = testRun.GetArguments(); if (!args.empty()) { commandAndArgs.reserve(args.size() + 1); - commandAndArgs.insert(commandAndArgs.end(), args.begin(), args.end()); + cmAppend(commandAndArgs, args); } testInfo["command"] = DumpToJsonArray(commandAndArgs); } diff --git a/Source/CTest/cmCTestP4.cxx b/Source/CTest/cmCTestP4.cxx index aa42810..2eb8dba 100644 --- a/Source/CTest/cmCTestP4.cxx +++ b/Source/CTest/cmCTestP4.cxx @@ -2,6 +2,7 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmCTestP4.h" +#include "cmAlgorithms.h" #include "cmCTest.h" #include "cmCTestVC.h" #include "cmProcessTools.h" @@ -324,9 +325,7 @@ void cmCTestP4::SetP4Options(std::vector<char const*>& CommandOptions) // The CTEST_P4_OPTIONS variable adds additional Perforce command line // options before the main command std::string opts = this->CTest->GetCTestConfiguration("P4Options"); - std::vector<std::string> args = cmSystemTools::ParseArguments(opts); - - P4Options.insert(P4Options.end(), args.begin(), args.end()); + cmAppend(P4Options, cmSystemTools::ParseArguments(opts)); } CommandOptions.clear(); diff --git a/Source/CTest/cmCTestSVN.cxx b/Source/CTest/cmCTestSVN.cxx index 04749b7..c834686 100644 --- a/Source/CTest/cmCTestSVN.cxx +++ b/Source/CTest/cmCTestSVN.cxx @@ -2,6 +2,7 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmCTestSVN.h" +#include "cmAlgorithms.h" #include "cmCTest.h" #include "cmCTestVC.h" #include "cmProcessTools.h" @@ -269,9 +270,7 @@ bool cmCTestSVN::RunSVNCommand(std::vector<char const*> const& parameters, std::vector<char const*> args; args.push_back(this->CommandLineTool.c_str()); - - args.insert(args.end(), parameters.begin(), parameters.end()); - + cmAppend(args, parameters); args.push_back("--non-interactive"); std::string userOptions = this->CTest->GetCTestConfiguration("SVNOptions"); @@ -344,7 +343,7 @@ private: void CharacterDataHandler(const char* data, int length) override { - this->CData.insert(this->CData.end(), data, data + length); + cmAppend(this->CData, data, data + length); } void EndElement(const std::string& name) override diff --git a/Source/CTest/cmCTestScriptHandler.cxx b/Source/CTest/cmCTestScriptHandler.cxx index 43cfe16..a739f44 100644 --- a/Source/CTest/cmCTestScriptHandler.cxx +++ b/Source/CTest/cmCTestScriptHandler.cxx @@ -447,7 +447,8 @@ int cmCTestScriptHandler::ExtractVariables() if (updateVal) { if (this->UpdateCmd.empty()) { cmSystemTools::Error( - updateVar, " specified without specifying CTEST_CVS_COMMAND."); + std::string(updateVar) + + " specified without specifying CTEST_CVS_COMMAND."); return 12; } this->ExtraUpdates.emplace_back(updateVal); diff --git a/Source/CTest/cmCTestSubmitHandler.cxx b/Source/CTest/cmCTestSubmitHandler.cxx index 2b54365..1fa7988 100644 --- a/Source/CTest/cmCTestSubmitHandler.cxx +++ b/Source/CTest/cmCTestSubmitHandler.cxx @@ -63,7 +63,7 @@ private: void CharacterDataHandler(const char* data, int length) override { - this->CurrentValue.insert(this->CurrentValue.end(), data, data + length); + cmAppend(this->CurrentValue, data, data + length); } void EndElement(const std::string& name) override @@ -93,12 +93,9 @@ static size_t cmCTestSubmitHandlerWriteMemoryCallback(void* ptr, size_t size, size_t nmemb, void* data) { int realsize = static_cast<int>(size * nmemb); - - cmCTestSubmitHandlerVectorOfChar* vec = - static_cast<cmCTestSubmitHandlerVectorOfChar*>(data); const char* chPtr = static_cast<char*>(ptr); - vec->insert(vec->end(), chPtr, chPtr + realsize); - + cmAppend(*static_cast<cmCTestSubmitHandlerVectorOfChar*>(data), chPtr, + chPtr + realsize); return realsize; } @@ -107,10 +104,8 @@ static size_t cmCTestSubmitHandlerCurlDebugCallback(CURL* /*unused*/, char* chPtr, size_t size, void* data) { - cmCTestSubmitHandlerVectorOfChar* vec = - static_cast<cmCTestSubmitHandlerVectorOfChar*>(data); - vec->insert(vec->end(), chPtr, chPtr + size); - + cmAppend(*static_cast<cmCTestSubmitHandlerVectorOfChar*>(data), chPtr, + chPtr + size); return size; } @@ -769,8 +764,7 @@ int cmCTestSubmitHandler::ProcessHandler() if (!this->Files.empty()) { // Submit the explicitly selected files: - // - files.insert(files.end(), this->Files.begin(), this->Files.end()); + cmAppend(files, this->Files); } // Add to the list of files to submit from any selected, existing parts: @@ -816,8 +810,7 @@ int cmCTestSubmitHandler::ProcessHandler() } // Submit files from this part. - std::vector<std::string> const& pfiles = this->CTest->GetSubmitFiles(p); - files.insert(files.end(), pfiles.begin(), pfiles.end()); + cmAppend(files, this->CTest->GetSubmitFiles(p)); } // Make sure files are unique, but preserve order. diff --git a/Source/CTest/cmProcess.cxx b/Source/CTest/cmProcess.cxx index a2c30bb..7a3b82e 100644 --- a/Source/CTest/cmProcess.cxx +++ b/Source/CTest/cmProcess.cxx @@ -2,6 +2,7 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmProcess.h" +#include "cmAlgorithms.h" #include "cmCTest.h" #include "cmCTestRunTest.h" #include "cmCTestTestHandler.h" @@ -215,7 +216,7 @@ void cmProcess::OnRead(ssize_t nread, const uv_buf_t* buf) if (nread > 0) { std::string strdata; this->Conv.DecodeText(buf->base, static_cast<size_t>(nread), strdata); - this->Output.insert(this->Output.end(), strdata.begin(), strdata.end()); + cmAppend(this->Output, strdata); while (this->Output.GetLine(line)) { this->Runner.CheckOutput(line); diff --git a/Source/CursesDialog/cmCursesCacheEntryComposite.cxx b/Source/CursesDialog/cmCursesCacheEntryComposite.cxx index e7ed097..c1dd591 100644 --- a/Source/CursesDialog/cmCursesCacheEntryComposite.cxx +++ b/Source/CursesDialog/cmCursesCacheEntryComposite.cxx @@ -83,7 +83,7 @@ cmCursesCacheEntryComposite::cmCursesCacheEntryComposite( break; } case cmStateEnums::UNINITIALIZED: - cmSystemTools::Error("Found an undefined variable: ", key.c_str()); + cmSystemTools::Error("Found an undefined variable: " + key); break; default: // TODO : put warning message here diff --git a/Source/cmAddLibraryCommand.cxx b/Source/cmAddLibraryCommand.cxx index adf4464..ad12e89 100644 --- a/Source/cmAddLibraryCommand.cxx +++ b/Source/cmAddLibraryCommand.cxx @@ -4,6 +4,7 @@ #include <sstream> +#include "cmAlgorithms.h" #include "cmGeneratorExpression.h" #include "cmGlobalGenerator.h" #include "cmMakefile.h" @@ -338,7 +339,7 @@ bool cmAddLibraryCommand::InitialPass(std::vector<std::string> const& args, return true; } - srclists.insert(srclists.end(), s, args.end()); + cmAppend(srclists, s, args.end()); this->Makefile->AddLibrary(libName, type, srclists, excludeFromAll); diff --git a/Source/cmAddTestCommand.cxx b/Source/cmAddTestCommand.cxx index 3a3afdb..bf28702 100644 --- a/Source/cmAddTestCommand.cxx +++ b/Source/cmAddTestCommand.cxx @@ -27,8 +27,7 @@ bool cmAddTestCommand::InitialPass(std::vector<std::string> const& args, } // Collect the command with arguments. - std::vector<std::string> command; - command.insert(command.end(), args.begin() + 1, args.end()); + std::vector<std::string> command(args.begin() + 1, args.end()); // Create the test but add a generator only the first time it is // seen. This preserves behavior from before test generators. diff --git a/Source/cmAlgorithms.h b/Source/cmAlgorithms.h index 0980416..d1e32b0 100644 --- a/Source/cmAlgorithms.h +++ b/Source/cmAlgorithms.h @@ -171,6 +171,18 @@ void cmDeleteAll(Range const& r) ContainerAlgorithms::DefaultDeleter<Range>()); } +template <typename T, typename Range> +void cmAppend(std::vector<T>& v, Range const& r) +{ + v.insert(v.end(), r.begin(), r.end()); +} + +template <typename T, typename InputIt> +void cmAppend(std::vector<T>& v, InputIt first, InputIt last) +{ + v.insert(v.end(), first, last); +} + template <typename Range> std::string cmJoin(Range const& r, const char* delimiter) { diff --git a/Source/cmCPluginAPI.cxx b/Source/cmCPluginAPI.cxx index 5efc784..255a8e6 100644 --- a/Source/cmCPluginAPI.cxx +++ b/Source/cmCPluginAPI.cxx @@ -167,8 +167,8 @@ void CCONV cmAddLinkDirectoryForTarget(void* arg, const char* tgt, cmTarget* t = mf->FindLocalNonAliasTarget(tgt); if (!t) { cmSystemTools::Error( - "Attempt to add link directories to non-existent target: ", tgt, - " for directory ", d); + "Attempt to add link directories to non-existent target: " + + std::string(tgt) + " for directory " + std::string(d)); return; } t->InsertLinkDirectory(d, mf->GetBacktrace()); diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx index 003ebdc..071ff56 100644 --- a/Source/cmCTest.cxx +++ b/Source/cmCTest.cxx @@ -1282,7 +1282,7 @@ int cmCTest::RunTest(std::vector<const char*> argv, std::string* output, while (cmsysProcess_WaitForData(cp, &data, &length, nullptr)) { processOutput.DecodeText(data, length, strdata); if (output) { - tempOutput.insert(tempOutput.end(), data, data + length); + cmAppend(tempOutput, data, data + length); } cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, cmCTestLogWrite(strdata.c_str(), strdata.size())); @@ -2194,8 +2194,7 @@ int cmCTest::Run(std::vector<std::string>& args, std::string* output) bool SRArgumentSpecified = false; // copy the command line - this->Impl->InitialCommandLineArguments.insert( - this->Impl->InitialCommandLineArguments.end(), args.begin(), args.end()); + cmAppend(this->Impl->InitialCommandLineArguments, args); // process the command line arguments for (size_t i = 1; i < args.size(); ++i) { @@ -2958,10 +2957,10 @@ bool cmCTest::RunCommand(std::vector<std::string> const& args, res = cmsysProcess_WaitForData(cp, &data, &length, nullptr); switch (res) { case cmsysProcess_Pipe_STDOUT: - tempOutput.insert(tempOutput.end(), data, data + length); + cmAppend(tempOutput, data, data + length); break; case cmsysProcess_Pipe_STDERR: - tempError.insert(tempError.end(), data, data + length); + cmAppend(tempError, data, data + length); break; default: done = true; diff --git a/Source/cmCacheManager.cxx b/Source/cmCacheManager.cxx index 6116de0..358f095 100644 --- a/Source/cmCacheManager.cxx +++ b/Source/cmCacheManager.cxx @@ -308,8 +308,7 @@ bool cmCacheManager::SaveCache(const std::string& path, cmMessenger* messenger) if (!ce.Initialized) { /* // This should be added in, but is not for now. - cmSystemTools::Error("Cache entry \"", (*i).first.c_str(), - "\" is uninitialized"); + cmSystemTools::Error("Cache entry \"" + i.first + "\" is uninitialized"); */ } else if (t != cmStateEnums::INTERNAL) { // Format is key:type=value diff --git a/Source/cmConditionEvaluator.cxx b/Source/cmConditionEvaluator.cxx index 303b147..e7e91c1 100644 --- a/Source/cmConditionEvaluator.cxx +++ b/Source/cmConditionEvaluator.cxx @@ -94,10 +94,7 @@ bool cmConditionEvaluator::IsTrue( } // store the reduced args in this vector - cmArgumentList newArgs; - - // copy to the list structure - newArgs.insert(newArgs.end(), args.begin(), args.end()); + cmArgumentList newArgs(args.begin(), args.end()); // now loop through the arguments and see if we can reduce any of them // we do this multiple times. Once for each level of precedence @@ -398,7 +395,7 @@ bool cmConditionEvaluator::HandleLevel0(cmArgumentList& newArgs, // copy to the list structure cmArgumentList::iterator argP1 = arg; argP1++; - newArgs2.insert(newArgs2.end(), argP1, argClose); + cmAppend(newArgs2, argP1, argClose); newArgs2.pop_back(); // now recursively invoke IsTrue to handle the values inside the // parenthetical expression diff --git a/Source/cmCustomCommand.cxx b/Source/cmCustomCommand.cxx index ad8c9b9..7402eeb 100644 --- a/Source/cmCustomCommand.cxx +++ b/Source/cmCustomCommand.cxx @@ -2,6 +2,7 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmCustomCommand.h" +#include "cmAlgorithms.h" #include "cmMakefile.h" #include <utility> @@ -54,13 +55,12 @@ const char* cmCustomCommand::GetComment() const void cmCustomCommand::AppendCommands(const cmCustomCommandLines& commandLines) { - this->CommandLines.insert(this->CommandLines.end(), commandLines.begin(), - commandLines.end()); + cmAppend(this->CommandLines, commandLines); } void cmCustomCommand::AppendDepends(const std::vector<std::string>& depends) { - this->Depends.insert(this->Depends.end(), depends.begin(), depends.end()); + cmAppend(this->Depends, depends); } bool cmCustomCommand::GetEscapeOldStyle() const @@ -101,8 +101,7 @@ void cmCustomCommand::SetImplicitDepends(ImplicitDependsList const& l) void cmCustomCommand::AppendImplicitDepends(ImplicitDependsList const& l) { - this->ImplicitDepends.insert(this->ImplicitDepends.end(), l.begin(), - l.end()); + cmAppend(this->ImplicitDepends, l); } bool cmCustomCommand::GetUsesTerminal() const diff --git a/Source/cmCustomCommandGenerator.cxx b/Source/cmCustomCommandGenerator.cxx index 6bf9946..e58fc76 100644 --- a/Source/cmCustomCommandGenerator.cxx +++ b/Source/cmCustomCommandGenerator.cxx @@ -2,6 +2,7 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmCustomCommandGenerator.h" +#include "cmAlgorithms.h" #include "cmCustomCommand.h" #include "cmCustomCommandLines.h" #include "cmGeneratorExpression.h" @@ -33,9 +34,7 @@ cmCustomCommandGenerator::cmCustomCommandGenerator(cmCustomCommand const& cc, this->GE->Parse(clarg); std::string parsed_arg = cge->Evaluate(this->LG, this->Config); if (this->CC.GetCommandExpandLists()) { - std::vector<std::string> ExpandedArg; - cmSystemTools::ExpandListArgument(parsed_arg, ExpandedArg); - argv.insert(argv.end(), ExpandedArg.begin(), ExpandedArg.end()); + cmAppend(argv, cmSystemTools::ExpandedListArgument(parsed_arg)); } else { argv.push_back(std::move(parsed_arg)); } @@ -54,15 +53,14 @@ cmCustomCommandGenerator::cmCustomCommandGenerator(cmCustomCommand const& cc, std::vector<std::string> depends = this->CC.GetDepends(); for (std::string const& d : depends) { std::unique_ptr<cmCompiledGeneratorExpression> cge = this->GE->Parse(d); - std::vector<std::string> result; - cmSystemTools::ExpandListArgument(cge->Evaluate(this->LG, this->Config), - result); + std::vector<std::string> result = cmSystemTools::ExpandedListArgument( + cge->Evaluate(this->LG, this->Config)); for (std::string& it : result) { if (cmSystemTools::FileIsFullPath(it)) { it = cmSystemTools::CollapseFullPath(it); } } - this->Depends.insert(this->Depends.end(), result.begin(), result.end()); + cmAppend(this->Depends, result); } const std::string& workingdirectory = this->CC.GetWorkingDirectory(); diff --git a/Source/cmDocumentationSection.h b/Source/cmDocumentationSection.h index 7031b52..19c7407 100644 --- a/Source/cmDocumentationSection.h +++ b/Source/cmDocumentationSection.h @@ -5,6 +5,7 @@ #include "cmConfigure.h" // IWYU pragma: keep +#include "cmAlgorithms.h" #include "cmDocumentationEntry.h" #include <string> @@ -46,7 +47,7 @@ public: } void Append(const std::vector<cmDocumentationEntry>& entries) { - this->Entries.insert(this->Entries.end(), entries.begin(), entries.end()); + cmAppend(this->Entries, entries); } /** Append an entry to this section using NULL terminated chars */ diff --git a/Source/cmELF.cxx b/Source/cmELF.cxx index 27f9131..2226463 100644 --- a/Source/cmELF.cxx +++ b/Source/cmELF.cxx @@ -2,6 +2,7 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmELF.h" +#include "cmAlgorithms.h" #include "cm_kwiml.h" #include "cmsys/FStream.hxx" #include <map> @@ -572,7 +573,7 @@ std::vector<char> cmELFInternalImpl<Types>::EncodeDynamicEntries( } char* pdyn = reinterpret_cast<char*>(&dyn); - result.insert(result.end(), pdyn, pdyn + sizeof(ELF_Dyn)); + cmAppend(result, pdyn, pdyn + sizeof(ELF_Dyn)); } return result; diff --git a/Source/cmExecuteProcessCommand.cxx b/Source/cmExecuteProcessCommand.cxx index 0d9859e..494afbb 100644 --- a/Source/cmExecuteProcessCommand.cxx +++ b/Source/cmExecuteProcessCommand.cxx @@ -393,5 +393,5 @@ void cmExecuteProcessCommandAppend(std::vector<char>& output, const char* data, --length; } #endif - output.insert(output.end(), data, data + length); + cmAppend(output, data, data + length); } diff --git a/Source/cmExportBuildFileGenerator.h b/Source/cmExportBuildFileGenerator.h index ada2709..0a1e755 100644 --- a/Source/cmExportBuildFileGenerator.h +++ b/Source/cmExportBuildFileGenerator.h @@ -5,6 +5,7 @@ #include "cmConfigure.h" // IWYU pragma: keep +#include "cmAlgorithms.h" #include "cmExportFileGenerator.h" #include "cmStateTypes.h" @@ -39,7 +40,7 @@ public: void GetTargets(std::vector<std::string>& targets) const; void AppendTargets(std::vector<std::string> const& targets) { - this->Targets.insert(this->Targets.end(), targets.begin(), targets.end()); + cmAppend(this->Targets, targets); } void SetExportSet(cmExportSet*); diff --git a/Source/cmExportLibraryDependenciesCommand.cxx b/Source/cmExportLibraryDependenciesCommand.cxx index 0a0646c..b60a053 100644 --- a/Source/cmExportLibraryDependenciesCommand.cxx +++ b/Source/cmExportLibraryDependenciesCommand.cxx @@ -76,8 +76,7 @@ void cmExportLibraryDependenciesCommand::ConstFinalPass() const std::map<std::string, std::string> libDepsNew; std::map<std::string, std::string> libTypes; for (cmMakefile* local : locals) { - const cmTargets& tgts = local->GetTargets(); - for (auto const& tgt : tgts) { + for (auto const& tgt : local->GetTargets()) { // Get the current target. cmTarget const& target = tgt.second; diff --git a/Source/cmExtraCodeBlocksGenerator.cxx b/Source/cmExtraCodeBlocksGenerator.cxx index c6e44e3..f47744b 100644 --- a/Source/cmExtraCodeBlocksGenerator.cxx +++ b/Source/cmExtraCodeBlocksGenerator.cxx @@ -209,9 +209,7 @@ void cmExtraCodeBlocksGenerator::CreateNewProjectFile( // Collect all files std::vector<std::string> listFiles; for (cmLocalGenerator* lg : it.second) { - const std::vector<std::string>& files = - lg->GetMakefile()->GetListFiles(); - listFiles.insert(listFiles.end(), files.begin(), files.end()); + cmAppend(listFiles, lg->GetMakefile()->GetListFiles()); } // Convert @@ -563,27 +561,24 @@ void cmExtraCodeBlocksGenerator::AppendTarget( // the include directories for this target std::vector<std::string> allIncludeDirs; - - std::vector<std::string> includes; - lg->GetIncludeDirectories(includes, target, "C", buildType); - - allIncludeDirs.insert(allIncludeDirs.end(), includes.begin(), - includes.end()); + { + std::vector<std::string> includes; + lg->GetIncludeDirectories(includes, target, "C", buildType); + cmAppend(allIncludeDirs, includes); + } std::string systemIncludeDirs = makefile->GetSafeDefinition( "CMAKE_EXTRA_GENERATOR_CXX_SYSTEM_INCLUDE_DIRS"); if (!systemIncludeDirs.empty()) { - std::vector<std::string> dirs; - cmSystemTools::ExpandListArgument(systemIncludeDirs, dirs); - allIncludeDirs.insert(allIncludeDirs.end(), dirs.begin(), dirs.end()); + cmAppend(allIncludeDirs, + cmSystemTools::ExpandedListArgument(systemIncludeDirs)); } systemIncludeDirs = makefile->GetSafeDefinition( "CMAKE_EXTRA_GENERATOR_C_SYSTEM_INCLUDE_DIRS"); if (!systemIncludeDirs.empty()) { - std::vector<std::string> dirs; - cmSystemTools::ExpandListArgument(systemIncludeDirs, dirs); - allIncludeDirs.insert(allIncludeDirs.end(), dirs.begin(), dirs.end()); + cmAppend(allIncludeDirs, + cmSystemTools::ExpandedListArgument(systemIncludeDirs)); } std::vector<std::string>::const_iterator end = diff --git a/Source/cmFileAPICodemodel.cxx b/Source/cmFileAPICodemodel.cxx index 45e8303..0fb166a 100644 --- a/Source/cmFileAPICodemodel.cxx +++ b/Source/cmFileAPICodemodel.cxx @@ -2,6 +2,7 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmFileAPICodemodel.h" +#include "cmAlgorithms.h" #include "cmCryptoHash.h" #include "cmFileAPI.h" #include "cmGeneratorExpression.h" @@ -477,8 +478,7 @@ Json::Value CodemodelConfig::DumpTargets() cmGlobalGenerator* gg = this->FileAPI.GetCMakeInstance()->GetGlobalGenerator(); for (cmLocalGenerator const* lg : gg->GetLocalGenerators()) { - std::vector<cmGeneratorTarget*> const& list = lg->GetGeneratorTargets(); - targetList.insert(targetList.end(), list.begin(), list.end()); + cmAppend(targetList, lg->GetGeneratorTargets()); } std::sort(targetList.begin(), targetList.end(), [](cmGeneratorTarget* l, cmGeneratorTarget* r) { diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx index aa8a919..7a3954e 100644 --- a/Source/cmFileCommand.cxx +++ b/Source/cmFileCommand.cxx @@ -25,6 +25,7 @@ #include "cmFileCopier.h" #include "cmFileInstaller.h" #include "cmFileLockPool.h" +#include "cmFileTimes.h" #include "cmGeneratorExpression.h" #include "cmGlobalGenerator.h" #include "cmHexFileConverter.h" @@ -52,8 +53,6 @@ # include <windows.h> #endif -class cmSystemToolsFileTime; - #if defined(_WIN32) // libcurl doesn't support file:// urls for unicode filenames on Windows. // Convert string from UTF-8 to ACP if this is a file:// URL. @@ -891,7 +890,7 @@ bool cmFileCommand::HandleGlobCommand(std::vector<std::string> const& args, } std::vector<std::string>& foundFiles = g.GetFiles(); - files.insert(files.end(), foundFiles.begin(), foundFiles.end()); + cmAppend(files, foundFiles); if (configureDepends) { std::sort(foundFiles.begin(), foundFiles.end()); @@ -1114,8 +1113,7 @@ bool cmFileCommand::HandleRPathChangeCommand( return false; } bool success = true; - cmSystemToolsFileTime* ft = cmSystemTools::FileTimeNew(); - bool have_ft = cmSystemTools::FileTimeGet(file, ft); + cmFileTimes const ft(file); std::string emsg; bool changed; if (!cmSystemTools::ChangeRPath(file, oldRPath, newRPath, &emsg, &changed)) { @@ -1139,11 +1137,8 @@ bool cmFileCommand::HandleRPathChangeCommand( message += "\""; this->Makefile->DisplayStatus(message, -1); } - if (have_ft) { - cmSystemTools::FileTimeSet(file, ft); - } + ft.Store(file); } - cmSystemTools::FileTimeDelete(ft); return success; } @@ -1182,8 +1177,7 @@ bool cmFileCommand::HandleRPathRemoveCommand( return false; } bool success = true; - cmSystemToolsFileTime* ft = cmSystemTools::FileTimeNew(); - bool have_ft = cmSystemTools::FileTimeGet(file, ft); + cmFileTimes const ft(file); std::string emsg; bool removed; if (!cmSystemTools::RemoveRPath(file, &emsg, &removed)) { @@ -1203,11 +1197,8 @@ bool cmFileCommand::HandleRPathRemoveCommand( message += "\""; this->Makefile->DisplayStatus(message, -1); } - if (have_ft) { - cmSystemTools::FileTimeSet(file, ft); - } + ft.Store(file); } - cmSystemTools::FileTimeDelete(ft); return success; } @@ -1404,6 +1395,12 @@ bool cmFileCommand::HandleRemove(std::vector<std::string> const& args, cmMakeRange(args).advance(1)) // Get rid of subcommand { std::string fileName = arg; + if (fileName.empty()) { + std::string const r = recurse ? "REMOVE_RECURSE" : "REMOVE"; + this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, + "Ignoring empty file name in " + r + "."); + continue; + } if (!cmsys::SystemTools::FileIsFullPath(fileName)) { fileName = this->Makefile->GetCurrentSourceDirectory(); fileName += "/" + arg; @@ -1479,23 +1476,22 @@ size_t cmWriteToMemoryCallback(void* ptr, size_t size, size_t nmemb, void* data) { int realsize = static_cast<int>(size * nmemb); - cmFileCommandVectorOfChar* vec = - static_cast<cmFileCommandVectorOfChar*>(data); const char* chPtr = static_cast<char*>(ptr); - vec->insert(vec->end(), chPtr, chPtr + realsize); + cmAppend(*static_cast<cmFileCommandVectorOfChar*>(data), chPtr, + chPtr + realsize); return realsize; } size_t cmFileCommandCurlDebugCallback(CURL*, curl_infotype type, char* chPtr, size_t size, void* data) { - cmFileCommandVectorOfChar* vec = - static_cast<cmFileCommandVectorOfChar*>(data); + cmFileCommandVectorOfChar& vec = + *static_cast<cmFileCommandVectorOfChar*>(data); switch (type) { case CURLINFO_TEXT: case CURLINFO_HEADER_IN: case CURLINFO_HEADER_OUT: - vec->insert(vec->end(), chPtr, chPtr + size); + cmAppend(vec, chPtr, chPtr + size); break; case CURLINFO_DATA_IN: case CURLINFO_DATA_OUT: @@ -1505,7 +1501,7 @@ size_t cmFileCommandCurlDebugCallback(CURL*, curl_infotype type, char* chPtr, int n = sprintf(buf, "[%" KWIML_INT_PRIu64 " bytes data]\n", static_cast<KWIML_INT_uint64_t>(size)); if (n > 0) { - vec->insert(vec->end(), buf, buf + n); + cmAppend(vec, buf, buf + n); } } break; default: diff --git a/Source/cmFileCopier.cxx b/Source/cmFileCopier.cxx index 972cd6e..49e8cd5 100644 --- a/Source/cmFileCopier.cxx +++ b/Source/cmFileCopier.cxx @@ -5,6 +5,7 @@ #include "cmFSPermissions.h" #include "cmFileCommand.h" +#include "cmFileTimes.h" #include "cmMakefile.h" #include "cmSystemTools.h" #include "cmsys/Directory.hxx" @@ -75,20 +76,15 @@ bool cmFileCopier::SetPermissions(const std::string& toFile, // Writing to an NTFS alternate stream changes the modification // time, so we need to save and restore its original value. - cmSystemToolsFileTime* file_time_orig = cmSystemTools::FileTimeNew(); - cmSystemTools::FileTimeGet(toFile, file_time_orig); - - cmsys::ofstream permissionStream(mode_t_adt_filename.c_str()); - - if (permissionStream) { - permissionStream << std::oct << permissions << std::endl; + cmFileTimes file_time_orig(toFile); + { + cmsys::ofstream permissionStream(mode_t_adt_filename.c_str()); + if (permissionStream) { + permissionStream << std::oct << permissions << std::endl; + } + permissionStream.close(); } - - permissionStream.close(); - - cmSystemTools::FileTimeSet(toFile, file_time_orig); - - cmSystemTools::FileTimeDelete(file_time_orig); + file_time_orig.Store(toFile); } #endif @@ -614,7 +610,7 @@ bool cmFileCopier::InstallFile(const std::string& fromFile, if (cmSystemTools::GetPermissions(toFile, perm)) { cmSystemTools::SetPermissions(toFile, perm | mode_owner_write); } - if (!cmSystemTools::CopyFileTime(fromFile, toFile)) { + if (!cmFileTimes::Copy(fromFile, toFile)) { std::ostringstream e; e << this->Name << " cannot set modification time on \"" << toFile << "\""; diff --git a/Source/cmFileTimes.cxx b/Source/cmFileTimes.cxx new file mode 100644 index 0000000..fd4f679 --- /dev/null +++ b/Source/cmFileTimes.cxx @@ -0,0 +1,127 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#include "cmFileTimes.h" + +#include "cmAlgorithms.h" +#include "cm_sys_stat.h" + +#include <utility> + +#if defined(_WIN32) +# include "cmSystemTools.h" +# include <windows.h> +#else +# include <utime.h> +#endif + +#if defined(_WIN32) && \ + (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__MINGW32__)) +# include <io.h> +#endif + +#ifdef _WIN32 +class cmFileTimes::WindowsHandle +{ +public: + WindowsHandle(HANDLE h) + : handle_(h) + { + } + ~WindowsHandle() + { + if (this->handle_ != INVALID_HANDLE_VALUE) { + CloseHandle(this->handle_); + } + } + explicit operator bool() const + { + return this->handle_ != INVALID_HANDLE_VALUE; + } + bool operator!() const { return this->handle_ == INVALID_HANDLE_VALUE; } + operator HANDLE() const { return this->handle_; } + +private: + HANDLE handle_; +}; +#endif + +class cmFileTimes::Times +{ +public: +#if defined(_WIN32) && !defined(__CYGWIN__) + FILETIME timeCreation; + FILETIME timeLastAccess; + FILETIME timeLastWrite; +#else + struct utimbuf timeBuf; +#endif +}; + +cmFileTimes::cmFileTimes() = default; +cmFileTimes::cmFileTimes(std::string const& fileName) +{ + Load(fileName); +} +cmFileTimes::~cmFileTimes() = default; + +bool cmFileTimes::Load(std::string const& fileName) +{ + std::unique_ptr<Times> ptr; + if (IsValid()) { + // Invalidate this and re-use times + ptr.swap(this->times); + } else { + ptr = cm::make_unique<Times>(); + } + +#if defined(_WIN32) && !defined(__CYGWIN__) + cmFileTimes::WindowsHandle handle = + CreateFileW(cmSystemTools::ConvertToWindowsExtendedPath(fileName).c_str(), + GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS, 0); + if (!handle) { + return false; + } + if (!GetFileTime(handle, &ptr->timeCreation, &ptr->timeLastAccess, + &ptr->timeLastWrite)) { + return false; + } +#else + struct stat st; + if (stat(fileName.c_str(), &st) < 0) { + return false; + } + ptr->timeBuf.actime = st.st_atime; + ptr->timeBuf.modtime = st.st_mtime; +#endif + // Accept times + this->times = std::move(ptr); + return true; +} + +bool cmFileTimes::Store(std::string const& fileName) const +{ + if (!IsValid()) { + return false; + } + +#if defined(_WIN32) && !defined(__CYGWIN__) + cmFileTimes::WindowsHandle handle = CreateFileW( + cmSystemTools::ConvertToWindowsExtendedPath(fileName).c_str(), + FILE_WRITE_ATTRIBUTES, 0, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0); + if (!handle) { + return false; + } + return SetFileTime(handle, &this->times->timeCreation, + &this->times->timeLastAccess, + &this->times->timeLastWrite) != 0; +#else + return utime(fileName.c_str(), &this->times->timeBuf) >= 0; +#endif +} + +bool cmFileTimes::Copy(std::string const& fromFile, std::string const& toFile) +{ + cmFileTimes fileTimes; + return (fileTimes.Load(fromFile) && fileTimes.Store(toFile)); +} diff --git a/Source/cmFileTimes.h b/Source/cmFileTimes.h new file mode 100644 index 0000000..cbf0fe2 --- /dev/null +++ b/Source/cmFileTimes.h @@ -0,0 +1,40 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#ifndef cmFileTimes_h +#define cmFileTimes_h + +#include "cmConfigure.h" // IWYU pragma: keep + +#include <memory> // IWYU pragma: keep +#include <string> + +/** \class cmFileTimes + * \brief Loads and stores file times. + */ +class cmFileTimes +{ +public: + cmFileTimes(); + //! Calls Load() + cmFileTimes(std::string const& fileName); + ~cmFileTimes(); + + //! @return true, if file times were loaded successfully + bool IsValid() const { return (times != nullptr); } + //! Try to load the file times from @a fileName and @return IsValid() + bool Load(std::string const& fileName); + //! Stores the file times at @a fileName (if IsValid()) + bool Store(std::string const& fileName) const; + + //! Copies the file times of @a fromFile to @a toFile + static bool Copy(std::string const& fromFile, std::string const& toFile); + +private: +#ifdef _WIN32 + class WindowsHandle; +#endif + class Times; + std::unique_ptr<Times> times; +}; + +#endif diff --git a/Source/cmFindBase.cxx b/Source/cmFindBase.cxx index 2e5e29c..e590802 100644 --- a/Source/cmFindBase.cxx +++ b/Source/cmFindBase.cxx @@ -146,8 +146,7 @@ bool cmFindBase::ParseArguments(std::vector<std::string> const& argsIn) std::vector<std::string> shortArgs = this->Names; this->Names.clear(); // clear out any values in Names this->Names.push_back(shortArgs[0]); - this->UserGuessArgs.insert(this->UserGuessArgs.end(), - shortArgs.begin() + 1, shortArgs.end()); + cmAppend(this->UserGuessArgs, shortArgs.begin() + 1, shortArgs.end()); } this->ExpandPaths(); diff --git a/Source/cmFindCommon.cxx b/Source/cmFindCommon.cxx index 9aaa000..954558f 100644 --- a/Source/cmFindCommon.cxx +++ b/Source/cmFindCommon.cxx @@ -6,6 +6,7 @@ #include <string.h> #include <utility> +#include "cmAlgorithms.h" #include "cmMakefile.h" #include "cmSystemTools.h" @@ -221,7 +222,7 @@ void cmFindCommon::RerootPaths(std::vector<std::string>& paths) // If searching both rooted and unrooted paths add the original // paths again. if (this->FindRootPathMode == RootPathModeBoth) { - paths.insert(paths.end(), unrootedPaths.begin(), unrootedPaths.end()); + cmAppend(paths, unrootedPaths); } } diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx index 7ebd211..8eefaa7 100644 --- a/Source/cmFindPackageCommand.cxx +++ b/Source/cmFindPackageCommand.cxx @@ -498,57 +498,80 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args, this->SetModuleVariables(components); // See if there is a Find<PackageName>.cmake module. - if (this->UseFindModules) { - bool foundModule = false; - if (!this->FindModule(foundModule)) { - this->AppendSuccessInformation(); - return false; + bool loadedPackage = false; + if (this->Makefile->IsOn("CMAKE_FIND_PACKAGE_PREFER_CONFIG")) { + if (this->UseConfigFiles && this->FindPackageUsingConfigMode()) { + loadedPackage = true; + } else if (this->FindPackageUsingModuleMode()) { + loadedPackage = true; } - if (foundModule) { - this->AppendSuccessInformation(); - return true; + } else { + if (this->UseFindModules && this->FindPackageUsingModuleMode()) { + loadedPackage = true; + } else { + // Handle CMAKE_FIND_PACKAGE_WARN_NO_MODULE (warn when CONFIG mode is + // implicitly assumed) + if (this->UseFindModules && this->UseConfigFiles && + this->Makefile->IsOn("CMAKE_FIND_PACKAGE_WARN_NO_MODULE")) { + std::ostringstream aw; + if (this->RequiredCMakeVersion >= CMake_VERSION_ENCODE(2, 8, 8)) { + aw << "find_package called without either MODULE or CONFIG option " + "and " + "no Find" + << this->Name + << ".cmake module is in CMAKE_MODULE_PATH. " + "Add MODULE to exclusively request Module mode and fail if " + "Find" + << this->Name + << ".cmake is missing. " + "Add CONFIG to exclusively request Config mode and search for " + "a " + "package configuration file provided by " + << this->Name << " (" << this->Name << "Config.cmake or " + << cmSystemTools::LowerCase(this->Name) << "-config.cmake). "; + } else { + aw << "find_package called without NO_MODULE option and no " + "Find" + << this->Name + << ".cmake module is in CMAKE_MODULE_PATH. " + "Add NO_MODULE to exclusively request Config mode and search " + "for a " + "package configuration file provided by " + << this->Name << " (" << this->Name << "Config.cmake or " + << cmSystemTools::LowerCase(this->Name) + << "-config.cmake). " + "Otherwise make Find" + << this->Name + << ".cmake available in " + "CMAKE_MODULE_PATH."; + } + aw << "\n" + "(Variable CMAKE_FIND_PACKAGE_WARN_NO_MODULE enabled this " + "warning.)"; + this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, aw.str()); + } + + if (this->FindPackageUsingConfigMode()) { + loadedPackage = true; + } } } - if (this->UseFindModules && this->UseConfigFiles && - this->Makefile->IsOn("CMAKE_FIND_PACKAGE_WARN_NO_MODULE")) { - std::ostringstream aw; - if (this->RequiredCMakeVersion >= CMake_VERSION_ENCODE(2, 8, 8)) { - aw << "find_package called without either MODULE or CONFIG option and " - "no Find" - << this->Name - << ".cmake module is in CMAKE_MODULE_PATH. " - "Add MODULE to exclusively request Module mode and fail if " - "Find" - << this->Name - << ".cmake is missing. " - "Add CONFIG to exclusively request Config mode and search for a " - "package configuration file provided by " - << this->Name << " (" << this->Name << "Config.cmake or " - << cmSystemTools::LowerCase(this->Name) << "-config.cmake). "; - } else { - aw - << "find_package called without NO_MODULE option and no " - "Find" - << this->Name - << ".cmake module is in CMAKE_MODULE_PATH. " - "Add NO_MODULE to exclusively request Config mode and search for a " - "package configuration file provided by " - << this->Name << " (" << this->Name << "Config.cmake or " - << cmSystemTools::LowerCase(this->Name) - << "-config.cmake). " - "Otherwise make Find" - << this->Name - << ".cmake available in " - "CMAKE_MODULE_PATH."; - } - aw << "\n" - "(Variable CMAKE_FIND_PACKAGE_WARN_NO_MODULE enabled this warning.)"; - this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, aw.str()); - } - - // No find module. Assume the project has a CMake config file. Use - // a <PackageName>_DIR cache variable to locate it. + this->AppendSuccessInformation(); + return loadedPackage; +} + +bool cmFindPackageCommand::FindPackageUsingModuleMode() +{ + bool foundModule = false; + if (!this->FindModule(foundModule)) { + return false; + } + return foundModule; +} + +bool cmFindPackageCommand::FindPackageUsingConfigMode() +{ this->Variable = this->Name; this->Variable += "_DIR"; @@ -580,9 +603,7 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args, this->IgnoredPaths.insert(ignored.begin(), ignored.end()); // Find and load the package. - bool result = this->HandlePackageMode(); - this->AppendSuccessInformation(); - return result; + return this->HandlePackageMode(); } void cmFindPackageCommand::SetModuleVariables(const std::string& components) diff --git a/Source/cmFindPackageCommand.h b/Source/cmFindPackageCommand.h index a11d253..4f6d97c 100644 --- a/Source/cmFindPackageCommand.h +++ b/Source/cmFindPackageCommand.h @@ -90,6 +90,9 @@ private: static PathLabel SystemRegistry; }; + bool FindPackageUsingModuleMode(); + bool FindPackageUsingConfigMode(); + // Add additional search path labels and groups not present in the // parent class void AppendSearchPathGroups(); diff --git a/Source/cmFunctionCommand.cxx b/Source/cmFunctionCommand.cxx index 9d75b72..9067a5f 100644 --- a/Source/cmFunctionCommand.cxx +++ b/Source/cmFunctionCommand.cxx @@ -177,7 +177,7 @@ bool cmFunctionCommand::InitialPass(std::vector<std::string> const& args, // create a function blocker cmFunctionFunctionBlocker* f = new cmFunctionFunctionBlocker(); - f->Args.insert(f->Args.end(), args.begin(), args.end()); + cmAppend(f->Args, args); this->Makefile->AddFunctionBlocker(f); return true; } diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx index 709355a..68ef170 100644 --- a/Source/cmGeneratorExpressionNode.cxx +++ b/Source/cmGeneratorExpressionNode.cxx @@ -1215,7 +1215,12 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode break; } - const char* prop = target->GetProperty(propertyName); + std::string prop; + bool haveProp = false; + if (const char* p = target->GetProperty(propertyName)) { + prop = p; + haveProp = true; + } if (dagCheckerParent) { if (dagCheckerParent->EvaluatingGenexExpression() || @@ -1235,7 +1240,7 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode } #undef TRANSITIVE_PROPERTY_COMPARE - if (!prop) { + if (!haveProp) { return std::string(); } } else { @@ -1291,7 +1296,7 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode } } - if (!prop) { + if (!haveProp) { if (target->IsImported() || target->GetType() == cmStateEnums::INTERFACE_LIBRARY) { return linkedTargetsContent; diff --git a/Source/cmGeneratorExpressionParser.cxx b/Source/cmGeneratorExpressionParser.cxx index 7aa3314..304378d 100644 --- a/Source/cmGeneratorExpressionParser.cxx +++ b/Source/cmGeneratorExpressionParser.cxx @@ -2,6 +2,7 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmGeneratorExpressionParser.h" +#include "cmAlgorithms.h" #include "cmGeneratorExpressionEvaluator.h" #include <assert.h> @@ -52,9 +53,9 @@ static void extendResult( textContent->Extend( static_cast<TextContent*>(contents.front())->GetLength()); delete contents.front(); - result.insert(result.end(), contents.begin() + 1, contents.end()); + cmAppend(result, contents.begin() + 1, contents.end()); } else { - result.insert(result.end(), contents.begin(), contents.end()); + cmAppend(result, contents); } } diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index b08dd1c..3495f2a 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -1798,10 +1798,10 @@ int cmGlobalGenerator::Build( output += "\n"; if (workdir.Failed()) { cmSystemTools::SetRunCommandHideConsole(hideconsole); - cmSystemTools::Error("Failed to change directory: ", - std::strerror(workdir.GetLastResult())); - output += "Failed to change directory: "; - output += std::strerror(workdir.GetLastResult()); + std::string err = "Failed to change directory: "; + err += std::strerror(workdir.GetLastResult()); + cmSystemTools::Error(err); + output += err; output += "\n"; return 1; } diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index 88c586a..dcd8c5f 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -67,7 +67,7 @@ struct GeneratedMakeCommand void Add(std::vector<std::string>::const_iterator start, std::vector<std::string>::const_iterator end) { - PrimaryCommand.insert(PrimaryCommand.end(), start, end); + cmAppend(PrimaryCommand, start, end); } std::string Printable() const { return cmJoin(PrimaryCommand, " "); } diff --git a/Source/cmGlobalJOMMakefileGenerator.cxx b/Source/cmGlobalJOMMakefileGenerator.cxx index 43c9666..ff54288 100644 --- a/Source/cmGlobalJOMMakefileGenerator.cxx +++ b/Source/cmGlobalJOMMakefileGenerator.cxx @@ -66,8 +66,7 @@ cmGlobalJOMMakefileGenerator::GenerateBuildCommand( // Since we have full control over the invocation of JOM, let us // make it quiet. jomMakeOptions.push_back(this->MakeSilentFlag); - jomMakeOptions.insert(jomMakeOptions.end(), makeOptions.begin(), - makeOptions.end()); + cmAppend(jomMakeOptions, makeOptions); // JOM does parallel builds by default, the -j is only needed if a specific // number is given diff --git a/Source/cmGlobalNMakeMakefileGenerator.cxx b/Source/cmGlobalNMakeMakefileGenerator.cxx index a4838bc..2273c00 100644 --- a/Source/cmGlobalNMakeMakefileGenerator.cxx +++ b/Source/cmGlobalNMakeMakefileGenerator.cxx @@ -66,8 +66,7 @@ cmGlobalNMakeMakefileGenerator::GenerateBuildCommand( // Since we have full control over the invocation of nmake, let us // make it quiet. nmakeMakeOptions.push_back(this->MakeSilentFlag); - nmakeMakeOptions.insert(nmakeMakeOptions.end(), makeOptions.begin(), - makeOptions.end()); + cmAppend(nmakeMakeOptions, makeOptions); return this->cmGlobalUnixMakefileGenerator3::GenerateBuildCommand( makeProgram, projectName, projectDir, targetNames, config, fast, diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index 5ddaaa3..61dea80 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -639,13 +639,20 @@ void cmGlobalNinjaGenerator::EnableLanguage( this->ResolveLanguageCompiler(l, mf, optional); } #ifdef _WIN32 - if ((mf->GetSafeDefinition("CMAKE_C_SIMULATE_ID") != "MSVC") && - (mf->GetSafeDefinition("CMAKE_CXX_SIMULATE_ID") != "MSVC") && - (mf->IsOn("CMAKE_COMPILER_IS_MINGW") || - (mf->GetSafeDefinition("CMAKE_C_COMPILER_ID") == "GNU") || - (mf->GetSafeDefinition("CMAKE_CXX_COMPILER_ID") == "GNU") || - (mf->GetSafeDefinition("CMAKE_C_COMPILER_ID") == "Clang") || - (mf->GetSafeDefinition("CMAKE_CXX_COMPILER_ID") == "Clang"))) { + const bool clangGnuMode = + ((mf->GetSafeDefinition("CMAKE_C_COMPILER_ID") == "Clang") && + (mf->GetSafeDefinition("CMAKE_C_COMPILER_FRONTEND_VARIANT") == "GNU")) || + ((mf->GetSafeDefinition("CMAKE_CXX_COMPILER_ID") == "Clang") && + (mf->GetSafeDefinition("CMAKE_CXX_COMPILER_FRONTEND_VARIANT") == "GNU")); + + if (clangGnuMode || + ((mf->GetSafeDefinition("CMAKE_C_SIMULATE_ID") != "MSVC") && + (mf->GetSafeDefinition("CMAKE_CXX_SIMULATE_ID") != "MSVC") && + (mf->IsOn("CMAKE_COMPILER_IS_MINGW") || + (mf->GetSafeDefinition("CMAKE_C_COMPILER_ID") == "GNU") || + (mf->GetSafeDefinition("CMAKE_CXX_COMPILER_ID") == "GNU") || + (mf->GetSafeDefinition("CMAKE_C_COMPILER_ID") == "Clang") || + (mf->GetSafeDefinition("CMAKE_CXX_COMPILER_ID") == "Clang")))) { this->UsingGCCOnWindows = true; } #endif @@ -1016,7 +1023,7 @@ void cmGlobalNinjaGenerator::AppendTargetDepends( this->AppendTargetOutputs(targetDep, outs, depends); } std::sort(outs.begin(), outs.end()); - outputs.insert(outputs.end(), outs.begin(), outs.end()); + cmAppend(outputs, outs); } } @@ -1025,8 +1032,7 @@ void cmGlobalNinjaGenerator::AppendTargetDependsClosure( { cmNinjaOuts outs; this->AppendTargetDependsClosure(target, outs, true); - - outputs.insert(outputs.end(), outs.begin(), outs.end()); + cmAppend(outputs, outs); } void cmGlobalNinjaGenerator::AppendTargetDependsClosure( diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx index 8053f61..aa584ad 100644 --- a/Source/cmGlobalUnixMakefileGenerator3.cxx +++ b/Source/cmGlobalUnixMakefileGenerator3.cxx @@ -282,11 +282,8 @@ void cmGlobalUnixMakefileGenerator3::WriteMainCMakefile() // for each cmMakefile get its list of dependencies std::vector<std::string> lfiles; for (cmLocalGenerator* localGen : this->LocalGenerators) { - lg = static_cast<cmLocalUnixMakefileGenerator3*>(localGen); - // Get the list of files contributing to this generation step. - lfiles.insert(lfiles.end(), lg->GetMakefile()->GetListFiles().begin(), - lg->GetMakefile()->GetListFiles().end()); + cmAppend(lfiles, localGen->GetMakefile()->GetListFiles()); } cmake* cm = this->GetCMakeInstance(); diff --git a/Source/cmGlobalVisualStudio10Generator.cxx b/Source/cmGlobalVisualStudio10Generator.cxx index 4fa89d0..55374a4 100644 --- a/Source/cmGlobalVisualStudio10Generator.cxx +++ b/Source/cmGlobalVisualStudio10Generator.cxx @@ -784,11 +784,11 @@ bool cmGlobalVisualStudio10Generator::FindVCTargetsPath(cmMakefile* mf) if (this->GetSystemName() == "WindowsPhone") { cmXMLElement(epg, "ApplicationType").Content("Windows Phone"); cmXMLElement(epg, "ApplicationTypeRevision") - .Content(this->GetSystemVersion()); + .Content(this->GetApplicationTypeRevision()); } else if (this->GetSystemName() == "WindowsStore") { cmXMLElement(epg, "ApplicationType").Content("Windows Store"); cmXMLElement(epg, "ApplicationTypeRevision") - .Content(this->GetSystemVersion()); + .Content(this->GetApplicationTypeRevision()); } if (!this->WindowsTargetPlatformVersion.empty()) { cmXMLElement(epg, "WindowsTargetPlatformVersion") @@ -1112,6 +1112,15 @@ std::string cmGlobalVisualStudio10Generator::GetInstalledNsightTegraVersion() return version; } +std::string cmGlobalVisualStudio10Generator::GetApplicationTypeRevision() const +{ + // Return the first two '.'-separated components of the Windows version. + std::string::size_type end1 = this->SystemVersion.find('.'); + std::string::size_type end2 = + end1 == std::string::npos ? end1 : this->SystemVersion.find('.', end1 + 1); + return this->SystemVersion.substr(0, end2); +} + static std::string cmLoadFlagTableString(Json::Value entry, const char* field) { if (entry.isMember(field)) { diff --git a/Source/cmGlobalVisualStudio10Generator.h b/Source/cmGlobalVisualStudio10Generator.h index 2f532a6..1d30cd6 100644 --- a/Source/cmGlobalVisualStudio10Generator.h +++ b/Source/cmGlobalVisualStudio10Generator.h @@ -110,6 +110,9 @@ public: static std::string GetInstalledNsightTegraVersion(); + /** Return the first two components of CMAKE_SYSTEM_VERSION. */ + std::string GetApplicationTypeRevision() const; + cmIDEFlagTable const* GetClFlagTable() const; cmIDEFlagTable const* GetCSharpFlagTable() const; cmIDEFlagTable const* GetRcFlagTable() const; diff --git a/Source/cmGlobalVisualStudio8Generator.cxx b/Source/cmGlobalVisualStudio8Generator.cxx index 0da9986..85ddc85 100644 --- a/Source/cmGlobalVisualStudio8Generator.cxx +++ b/Source/cmGlobalVisualStudio8Generator.cxx @@ -141,10 +141,8 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget() // Collect the input files used to generate all targets in this // project. std::vector<std::string> listFiles; - for (unsigned int j = 0; j < generators.size(); ++j) { - cmMakefile* lmf = generators[j]->GetMakefile(); - listFiles.insert(listFiles.end(), lmf->GetListFiles().begin(), - lmf->GetListFiles().end()); + for (cmLocalGenerator* gen : generators) { + cmAppend(listFiles, gen->GetMakefile()->GetListFiles()); } // Add a custom prebuild target to run the VerifyGlobs script. diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index f2eb0ce..7c2bcd3 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -583,8 +583,7 @@ void cmGlobalXCodeGenerator::CreateReRunCMakeFile( { std::vector<std::string> lfiles; for (auto gen : gens) { - std::vector<std::string> const& lf = gen->GetMakefile()->GetListFiles(); - lfiles.insert(lfiles.end(), lf.begin(), lf.end()); + cmAppend(lfiles, gen->GetMakefile()->GetListFiles()); } // sort the array diff --git a/Source/cmIDEOptions.cxx b/Source/cmIDEOptions.cxx index ea67d45..7b992d7 100644 --- a/Source/cmIDEOptions.cxx +++ b/Source/cmIDEOptions.cxx @@ -6,6 +6,7 @@ #include <iterator> #include <string.h> +#include "cmAlgorithms.h" #include "cmIDEFlagTable.h" #include "cmSystemTools.h" @@ -170,7 +171,7 @@ void cmIDEOptions::AddDefines(std::string const& defines) } void cmIDEOptions::AddDefines(const std::vector<std::string>& defines) { - this->Defines.insert(this->Defines.end(), defines.begin(), defines.end()); + cmAppend(this->Defines, defines); } std::vector<std::string> const& cmIDEOptions::GetDefines() const @@ -192,8 +193,7 @@ void cmIDEOptions::AddIncludes(std::string const& includes) } void cmIDEOptions::AddIncludes(const std::vector<std::string>& includes) { - this->Includes.insert(this->Includes.end(), includes.begin(), - includes.end()); + cmAppend(this->Includes, includes); } std::vector<std::string> const& cmIDEOptions::GetIncludes() const diff --git a/Source/cmIncludeDirectoryCommand.cxx b/Source/cmIncludeDirectoryCommand.cxx index 549a263..62e2abd 100644 --- a/Source/cmIncludeDirectoryCommand.cxx +++ b/Source/cmIncludeDirectoryCommand.cxx @@ -6,6 +6,7 @@ #include <set> #include <utility> +#include "cmAlgorithms.h" #include "cmGeneratorExpression.h" #include "cmMakefile.h" #include "cmSystemTools.h" @@ -52,11 +53,9 @@ bool cmIncludeDirectoryCommand::InitialPass( this->GetIncludes(*i, includes); if (before) { - beforeIncludes.insert(beforeIncludes.end(), includes.begin(), - includes.end()); + cmAppend(beforeIncludes, includes); } else { - afterIncludes.insert(afterIncludes.end(), includes.begin(), - includes.end()); + cmAppend(afterIncludes, includes); } if (system) { systemIncludes.insert(includes.begin(), includes.end()); diff --git a/Source/cmInstallExportAndroidMKGenerator.cxx b/Source/cmInstallExportAndroidMKGenerator.cxx index 7de3dd4..55d3685 100644 --- a/Source/cmInstallExportAndroidMKGenerator.cxx +++ b/Source/cmInstallExportAndroidMKGenerator.cxx @@ -44,7 +44,7 @@ void cmInstallExportAndroidMKGenerator::GenerateScript(std::ostream& os) std::ostringstream e; e << "INSTALL(EXPORT) given unknown export \"" << ExportSet->GetName() << "\""; - cmSystemTools::Error(e.str().c_str()); + cmSystemTools::Error(e.str()); return; } diff --git a/Source/cmInstallFilesCommand.cxx b/Source/cmInstallFilesCommand.cxx index b068e46..efbcb67 100644 --- a/Source/cmInstallFilesCommand.cxx +++ b/Source/cmInstallFilesCommand.cxx @@ -2,6 +2,7 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmInstallFilesCommand.h" +#include "cmAlgorithms.h" #include "cmGeneratorExpression.h" #include "cmGlobalGenerator.h" #include "cmInstallFilesGenerator.h" @@ -35,8 +36,7 @@ bool cmInstallFilesCommand::InitialPass(std::vector<std::string> const& args, this->CreateInstallGenerator(); } else { this->IsFilesForm = false; - this->FinalArgs.insert(this->FinalArgs.end(), args.begin() + 1, - args.end()); + cmAppend(this->FinalArgs, args.begin() + 1, args.end()); } this->Makefile->GetGlobalGenerator()->AddInstallComponent( diff --git a/Source/cmInstallProgramsCommand.cxx b/Source/cmInstallProgramsCommand.cxx index f01a4c1..a58f875 100644 --- a/Source/cmInstallProgramsCommand.cxx +++ b/Source/cmInstallProgramsCommand.cxx @@ -2,6 +2,7 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmInstallProgramsCommand.h" +#include "cmAlgorithms.h" #include "cmGeneratorExpression.h" #include "cmGlobalGenerator.h" #include "cmInstallFilesGenerator.h" @@ -25,7 +26,7 @@ bool cmInstallProgramsCommand::InitialPass( this->Destination = args[0]; - this->FinalArgs.insert(this->FinalArgs.end(), args.begin() + 1, args.end()); + cmAppend(this->FinalArgs, args.begin() + 1, args.end()); this->Makefile->GetGlobalGenerator()->AddInstallComponent( this->Makefile->GetSafeDefinition("CMAKE_INSTALL_DEFAULT_COMPONENT_NAME")); diff --git a/Source/cmInstallTargetsCommand.cxx b/Source/cmInstallTargetsCommand.cxx index 7e67d4e..ef07e2c 100644 --- a/Source/cmInstallTargetsCommand.cxx +++ b/Source/cmInstallTargetsCommand.cxx @@ -23,7 +23,7 @@ bool cmInstallTargetsCommand::InitialPass(std::vector<std::string> const& args, // Enable the install target. this->Makefile->GetGlobalGenerator()->EnableInstallTarget(); - cmTargets& tgts = this->Makefile->GetTargets(); + cmMakefile::cmTargetMap& tgts = this->Makefile->GetTargets(); std::vector<std::string>::const_iterator s = args.begin(); ++s; std::string runtime_dir = "/bin"; @@ -38,7 +38,7 @@ bool cmInstallTargetsCommand::InitialPass(std::vector<std::string> const& args, runtime_dir = *s; } else { - cmTargets::iterator ti = tgts.find(*s); + cmMakefile::cmTargetMap::iterator ti = tgts.find(*s); if (ti != tgts.end()) { ti->second.SetInstallPath(args[0]); ti->second.SetRuntimeInstallPath(runtime_dir); diff --git a/Source/cmJsonObjects.cxx b/Source/cmJsonObjects.cxx index d723ced..636a8e1 100644 --- a/Source/cmJsonObjects.cxx +++ b/Source/cmJsonObjects.cxx @@ -2,6 +2,7 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmJsonObjects.h" // IWYU pragma: keep +#include "cmAlgorithms.h" #include "cmGeneratorExpression.h" #include "cmGeneratorTarget.h" #include "cmGlobalGenerator.h" @@ -601,8 +602,7 @@ static Json::Value DumpTargetsList( std::vector<cmGeneratorTarget*> targetList; for (auto const& lgIt : generators) { - const auto& list = lgIt->GetGeneratorTargets(); - targetList.insert(targetList.end(), list.begin(), list.end()); + cmAppend(targetList, lgIt->GetGeneratorTargets()); } std::sort(targetList.begin(), targetList.end()); diff --git a/Source/cmLinkLineDeviceComputer.cxx b/Source/cmLinkLineDeviceComputer.cxx index 211d03b..6cfe5bb 100644 --- a/Source/cmLinkLineDeviceComputer.cxx +++ b/Source/cmLinkLineDeviceComputer.cxx @@ -3,15 +3,20 @@ #include "cmLinkLineDeviceComputer.h" +#include <algorithm> #include <set> #include <sstream> #include <utility> +#include <vector> #include "cmAlgorithms.h" #include "cmComputeLinkInformation.h" #include "cmGeneratorTarget.h" -#include "cmGlobalNinjaGenerator.h" +#include "cmLocalGenerator.h" +#include "cmStateDirectory.h" +#include "cmStateSnapshot.h" #include "cmStateTypes.h" +#include "cmSystemTools.h" class cmOutputConverter; @@ -41,6 +46,27 @@ static bool cmLinkItemValidForDevice(std::string const& item) cmHasLiteralPrefix(item, "--library")); } +bool cmLinkLineDeviceComputer::ComputeRequiresDeviceLinking( + cmComputeLinkInformation& cli) +{ + // Determine if this item might requires device linking. + // For this we only consider targets + typedef cmComputeLinkInformation::ItemVector ItemVector; + ItemVector const& items = cli.GetItems(); + std::string config = cli.GetConfig(); + for (auto const& item : items) { + if (item.Target && + item.Target->GetType() == cmStateEnums::STATIC_LIBRARY) { + if ((!item.Target->GetPropertyAsBool("CUDA_RESOLVE_DEVICE_SYMBOLS")) && + item.Target->GetPropertyAsBool("CUDA_SEPARABLE_COMPILATION")) { + // this dependency requires us to device link it + return true; + } + } + } + return false; +} + std::string cmLinkLineDeviceComputer::ComputeLinkLibraries( cmComputeLinkInformation& cli, std::string const& stdLibString) { @@ -63,17 +89,12 @@ std::string cmLinkLineDeviceComputer::ComputeLinkLibraries( } if (item.Target) { - bool skip = false; - switch (item.Target->GetType()) { - case cmStateEnums::MODULE_LIBRARY: - case cmStateEnums::INTERFACE_LIBRARY: - skip = true; - break; - case cmStateEnums::STATIC_LIBRARY: - skip = item.Target->GetPropertyAsBool("CUDA_RESOLVE_DEVICE_SYMBOLS"); - break; - default: - break; + bool skip = true; + if (item.Target->GetType() == cmStateEnums::STATIC_LIBRARY) { + if ((!item.Target->GetPropertyAsBool("CUDA_RESOLVE_DEVICE_SYMBOLS")) && + item.Target->GetPropertyAsBool("CUDA_SEPARABLE_COMPILATION")) { + skip = false; + } } if (skip) { continue; @@ -118,16 +139,55 @@ std::string cmLinkLineDeviceComputer::GetLinkerLanguage(cmGeneratorTarget*, return "CUDA"; } -cmNinjaLinkLineDeviceComputer::cmNinjaLinkLineDeviceComputer( - cmOutputConverter* outputConverter, cmStateDirectory const& stateDir, - cmGlobalNinjaGenerator const* gg) - : cmLinkLineDeviceComputer(outputConverter, stateDir) - , GG(gg) +bool requireDeviceLinking(cmGeneratorTarget& target, cmLocalGenerator& lg, + const std::string& config) { -} -std::string cmNinjaLinkLineDeviceComputer::ConvertToLinkReference( - std::string const& lib) const -{ - return GG->ConvertToNinjaPath(lib); + if (target.GetType() == cmStateEnums::OBJECT_LIBRARY) { + return false; + } + + if (const char* resolveDeviceSymbols = + target.GetProperty("CUDA_RESOLVE_DEVICE_SYMBOLS")) { + // If CUDA_RESOLVE_DEVICE_SYMBOLS has been explicitly set we need + // to honor the value no matter what it is. + return cmSystemTools::IsOn(resolveDeviceSymbols); + } + + if (const char* separableCompilation = + target.GetProperty("CUDA_SEPARABLE_COMPILATION")) { + if (cmSystemTools::IsOn(separableCompilation)) { + bool doDeviceLinking = false; + switch (target.GetType()) { + case cmStateEnums::SHARED_LIBRARY: + case cmStateEnums::MODULE_LIBRARY: + case cmStateEnums::EXECUTABLE: + doDeviceLinking = true; + break; + default: + break; + } + return doDeviceLinking; + } + } + + // Determine if we have any dependencies that require + // us to do a device link step + const std::string cuda_lang("CUDA"); + cmGeneratorTarget::LinkClosure const* closure = + target.GetLinkClosure(config); + + bool closureHasCUDA = + (std::find(closure->Languages.begin(), closure->Languages.end(), + cuda_lang) != closure->Languages.end()); + if (closureHasCUDA) { + cmComputeLinkInformation* pcli = target.GetLinkInformation(config); + if (pcli) { + cmLinkLineDeviceComputer deviceLinkComputer( + &lg, lg.GetStateSnapshot().GetDirectory()); + return deviceLinkComputer.ComputeRequiresDeviceLinking(*pcli); + } + return true; + } + return false; } diff --git a/Source/cmLinkLineDeviceComputer.h b/Source/cmLinkLineDeviceComputer.h index cf66f64..0ea5f69 100644 --- a/Source/cmLinkLineDeviceComputer.h +++ b/Source/cmLinkLineDeviceComputer.h @@ -12,7 +12,7 @@ class cmComputeLinkInformation; class cmGeneratorTarget; -class cmGlobalNinjaGenerator; +class cmLocalGenerator; class cmOutputConverter; class cmStateDirectory; @@ -27,6 +27,8 @@ public: cmLinkLineDeviceComputer& operator=(cmLinkLineDeviceComputer const&) = delete; + bool ComputeRequiresDeviceLinking(cmComputeLinkInformation& cli); + std::string ComputeLinkLibraries(cmComputeLinkInformation& cli, std::string const& stdLibString) override; @@ -34,21 +36,7 @@ public: std::string const& config) override; }; -class cmNinjaLinkLineDeviceComputer : public cmLinkLineDeviceComputer -{ -public: - cmNinjaLinkLineDeviceComputer(cmOutputConverter* outputConverter, - cmStateDirectory const& stateDir, - cmGlobalNinjaGenerator const* gg); - - cmNinjaLinkLineDeviceComputer(cmNinjaLinkLineDeviceComputer const&) = delete; - cmNinjaLinkLineDeviceComputer& operator=( - cmNinjaLinkLineDeviceComputer const&) = delete; - - std::string ConvertToLinkReference(std::string const& input) const override; - -private: - cmGlobalNinjaGenerator const* GG; -}; +bool requireDeviceLinking(cmGeneratorTarget& target, cmLocalGenerator& lg, + const std::string& config); #endif diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 047d405..787e98e 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -351,9 +351,8 @@ void cmLocalGenerator::CreateEvaluationFileOutputs(std::string const& config) void cmLocalGenerator::ProcessEvaluationFiles( std::vector<std::string>& generatedFiles) { - std::vector<cmGeneratorExpressionEvaluationFile*> ef = - this->Makefile->GetEvaluationFiles(); - for (cmGeneratorExpressionEvaluationFile* geef : ef) { + for (cmGeneratorExpressionEvaluationFile* geef : + this->Makefile->GetEvaluationFiles()) { geef->Generate(this); if (cmSystemTools::GetFatalErrorOccured()) { return; @@ -372,10 +371,10 @@ void cmLocalGenerator::ProcessEvaluationFiles( return; } - generatedFiles.insert(generatedFiles.end(), files.begin(), files.end()); - std::vector<std::string>::iterator newIt = - generatedFiles.end() - files.size(); - std::inplace_merge(generatedFiles.begin(), newIt, generatedFiles.end()); + cmAppend(generatedFiles, files); + std::inplace_merge(generatedFiles.begin(), + generatedFiles.end() - files.size(), + generatedFiles.end()); } } diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx index 6a08840..c392e97 100644 --- a/Source/cmLocalUnixMakefileGenerator3.cxx +++ b/Source/cmLocalUnixMakefileGenerator3.cxx @@ -501,8 +501,11 @@ void cmLocalUnixMakefileGenerator3::WriteMakeRule( { // Make sure there is a target. if (target.empty()) { - cmSystemTools::Error("No target for WriteMakeRule! called with comment: ", - comment); + std::string err("No target for WriteMakeRule! called with comment: "); + if (comment) { + err += comment; + } + cmSystemTools::Error(err); return; } @@ -859,7 +862,7 @@ void cmLocalUnixMakefileGenerator3::AppendRuleDepends( // Add a dependency on the rule file itself unless an option to skip // it is specifically enabled by the user or project. if (!this->Makefile->IsOn("CMAKE_SKIP_RULE_DEPENDENCY")) { - depends.insert(depends.end(), ruleFiles.begin(), ruleFiles.end()); + cmAppend(depends, ruleFiles); } } @@ -1034,7 +1037,7 @@ void cmLocalUnixMakefileGenerator3::AppendCustomCommand( this->CreateCDCommand(commands1, dir, relative); // push back the custom commands - commands.insert(commands.end(), commands1.begin(), commands1.end()); + cmAppend(commands, commands1); } void cmLocalUnixMakefileGenerator3::AppendCleanCommand( diff --git a/Source/cmMacroCommand.cxx b/Source/cmMacroCommand.cxx index 6565f02..e9c6aea 100644 --- a/Source/cmMacroCommand.cxx +++ b/Source/cmMacroCommand.cxx @@ -212,7 +212,7 @@ bool cmMacroCommand::InitialPass(std::vector<std::string> const& args, // create a function blocker cmMacroFunctionBlocker* f = new cmMacroFunctionBlocker(); - f->Args.insert(f->Args.end(), args.begin(), args.end()); + cmAppend(f->Args, args); this->Makefile->AddFunctionBlocker(f); return true; } diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index ca5f009..e0f69cb 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -818,7 +818,7 @@ void cmMakefile::AddCustomCommandToTarget( bool command_expand_lists, ObjectLibraryCommands objLibraryCommands) { // Find the target to which to add the custom command. - cmTargets::iterator ti = this->Targets.find(target); + cmTargetMap::iterator ti = this->Targets.find(target); if (ti == this->Targets.end()) { MessageType messageType = MessageType::AUTHOR_WARNING; @@ -1099,7 +1099,7 @@ void cmMakefile::AddCustomCommandOldStyle( // then add the source to the target to make sure the rule is // included. if (sf && !sf->GetPropertyAsBool("__CMAKE_RULE")) { - cmTargets::iterator ti = this->Targets.find(target); + cmTargetMap::iterator ti = this->Targets.find(target); if (ti != this->Targets.end()) { ti->second.AddSource(sf->GetFullPath()); } else { @@ -2036,7 +2036,7 @@ cmTarget* cmMakefile::AddExecutable(const std::string& exeName, cmTarget* cmMakefile::AddNewTarget(cmStateEnums::TargetType type, const std::string& name) { - cmTargets::iterator it = + cmTargetMap::iterator it = this->Targets .emplace(name, cmTarget(name, type, cmTarget::VisibilityNormal, this)) .first; @@ -2534,8 +2534,7 @@ const std::string& cmMakefile::GetSafeDefinition(const std::string& name) const std::vector<std::string> cmMakefile::GetDefinitions() const { std::vector<std::string> res = this->StateSnapshot.ClosureKeys(); - std::vector<std::string> cacheKeys = this->GetState()->GetCacheEntryKeys(); - res.insert(res.end(), cacheKeys.begin(), cacheKeys.end()); + cmAppend(res, this->GetState()->GetCacheEntryKeys()); std::sort(res.begin(), res.end()); return res; } @@ -3888,7 +3887,7 @@ std::vector<std::string> cmMakefile::GetPropertyKeys() const cmTarget* cmMakefile::FindLocalNonAliasTarget(const std::string& name) const { - cmTargets::iterator i = this->Targets.find(name); + cmTargetMap::iterator i = this->Targets.find(name); if (i != this->Targets.end()) { return &i->second; } diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index be1ac5a..d223347 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -373,14 +373,13 @@ public: return this->ComplainFileRegularExpression.c_str(); } - /** - * Get the list of targets - */ - cmTargets& GetTargets() { return this->Targets; } - /** - * Get the list of targets, const version - */ - const cmTargets& GetTargets() const { return this->Targets; } + // -- List of targets + typedef std::unordered_map<std::string, cmTarget> cmTargetMap; + /** Get the target map */ + cmTargetMap& GetTargets() { return this->Targets; } + /** Get the target map - const version */ + cmTargetMap const& GetTargets() const { return this->Targets; } + const std::vector<cmTarget*>& GetOwnedImportedTargets() const { return this->ImportedTargetsOwned; @@ -896,7 +895,7 @@ protected: mutable std::set<cmListFileContext> CMP0054ReportedIds; // libraries, classes, and executables - mutable cmTargets Targets; + mutable cmTargetMap Targets; std::map<std::string, std::string> AliasTargets; typedef std::vector<cmSourceFile*> SourceFileVec; diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx index 9b21739..552463d 100644 --- a/Source/cmMakefileExecutableTargetGenerator.cxx +++ b/Source/cmMakefileExecutableTargetGenerator.cxx @@ -2,7 +2,6 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmMakefileExecutableTargetGenerator.h" -#include <algorithm> #include <memory> // IWYU pragma: keep #include <set> #include <sstream> @@ -87,20 +86,9 @@ void cmMakefileExecutableTargetGenerator::WriteDeviceExecutableRule( return; } - const std::string cuda_lang("CUDA"); - cmGeneratorTarget::LinkClosure const* closure = - this->GeneratorTarget->GetLinkClosure(this->ConfigName); - - const bool hasCUDA = - (std::find(closure->Languages.begin(), closure->Languages.end(), - cuda_lang) != closure->Languages.end()); - - bool doDeviceLinking = true; - if (const char* resolveDeviceSymbols = - this->GeneratorTarget->GetProperty("CUDA_RESOLVE_DEVICE_SYMBOLS")) { - doDeviceLinking = cmSystemTools::IsOn(resolveDeviceSymbols); - } - if (!hasCUDA || !doDeviceLinking) { + bool requiresDeviceLinking = requireDeviceLinking( + *this->GeneratorTarget, *this->LocalGenerator, this->ConfigName); + if (!requiresDeviceLinking) { return; } @@ -280,7 +268,7 @@ void cmMakefileExecutableTargetGenerator::WriteDeviceExecutableRule( this->LocalGenerator->CreateCDCommand( commands1, this->Makefile->GetCurrentBinaryDirectory(), this->LocalGenerator->GetBinaryDirectory()); - commands.insert(commands.end(), commands1.begin(), commands1.end()); + cmAppend(commands, commands1); commands1.clear(); // Write the build rule. @@ -650,7 +638,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) this->LocalGenerator->CreateCDCommand( commands1, this->Makefile->GetCurrentBinaryDirectory(), this->LocalGenerator->GetBinaryDirectory()); - commands.insert(commands.end(), commands1.begin(), commands1.end()); + cmAppend(commands, commands1); commands1.clear(); // Add a rule to create necessary symlinks for the library. @@ -663,7 +651,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) this->LocalGenerator->CreateCDCommand( commands1, this->Makefile->GetCurrentBinaryDirectory(), this->LocalGenerator->GetBinaryDirectory()); - commands.insert(commands.end(), commands1.begin(), commands1.end()); + cmAppend(commands, commands1); commands1.clear(); } diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx index f5d1fc9..99f0df8 100644 --- a/Source/cmMakefileLibraryTargetGenerator.cxx +++ b/Source/cmMakefileLibraryTargetGenerator.cxx @@ -2,7 +2,6 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmMakefileLibraryTargetGenerator.h" -#include <algorithm> #include <memory> // IWYU pragma: keep #include <set> #include <sstream> @@ -124,20 +123,10 @@ void cmMakefileLibraryTargetGenerator::WriteObjectLibraryRules() void cmMakefileLibraryTargetGenerator::WriteStaticLibraryRules() { - const std::string cuda_lang("CUDA"); - cmGeneratorTarget::LinkClosure const* closure = - this->GeneratorTarget->GetLinkClosure(this->ConfigName); - - const bool hasCUDA = - (std::find(closure->Languages.begin(), closure->Languages.end(), - cuda_lang) != closure->Languages.end()); - - bool doDeviceLinking = false; - if (const char* resolveDeviceSymbols = - this->GeneratorTarget->GetProperty("CUDA_RESOLVE_DEVICE_SYMBOLS")) { - doDeviceLinking = cmSystemTools::IsOn(resolveDeviceSymbols); - } - if (hasCUDA && doDeviceLinking) { + + bool requiresDeviceLinking = requireDeviceLinking( + *this->GeneratorTarget, *this->LocalGenerator, this->ConfigName); + if (requiresDeviceLinking) { std::string linkRuleVar = "CMAKE_CUDA_DEVICE_LINK_LIBRARY"; this->WriteDeviceLibraryRules(linkRuleVar, false); } @@ -163,19 +152,9 @@ void cmMakefileLibraryTargetGenerator::WriteSharedLibraryRules(bool relink) } if (!relink) { - const std::string cuda_lang("CUDA"); - cmGeneratorTarget::LinkClosure const* closure = - this->GeneratorTarget->GetLinkClosure(this->ConfigName); - - const bool hasCUDA = - (std::find(closure->Languages.begin(), closure->Languages.end(), - cuda_lang) != closure->Languages.end()); - bool doDeviceLinking = true; - if (const char* resolveDeviceSymbols = - this->GeneratorTarget->GetProperty("CUDA_RESOLVE_DEVICE_SYMBOLS")) { - doDeviceLinking = cmSystemTools::IsOn(resolveDeviceSymbols); - } - if (hasCUDA && doDeviceLinking) { + bool requiresDeviceLinking = requireDeviceLinking( + *this->GeneratorTarget, *this->LocalGenerator, this->ConfigName); + if (requiresDeviceLinking) { std::string linkRuleVar = "CMAKE_CUDA_DEVICE_LINK_LIBRARY"; this->WriteDeviceLibraryRules(linkRuleVar, relink); } @@ -209,19 +188,9 @@ void cmMakefileLibraryTargetGenerator::WriteModuleLibraryRules(bool relink) { if (!relink) { - const std::string cuda_lang("CUDA"); - cmGeneratorTarget::LinkClosure const* closure = - this->GeneratorTarget->GetLinkClosure(this->ConfigName); - - const bool hasCUDA = - (std::find(closure->Languages.begin(), closure->Languages.end(), - cuda_lang) != closure->Languages.end()); - bool doDeviceLinking = true; - if (const char* resolveDeviceSymbols = - this->GeneratorTarget->GetProperty("CUDA_RESOLVE_DEVICE_SYMBOLS")) { - doDeviceLinking = cmSystemTools::IsOn(resolveDeviceSymbols); - } - if (hasCUDA && doDeviceLinking) { + bool requiresDeviceLinking = requireDeviceLinking( + *this->GeneratorTarget, *this->LocalGenerator, this->ConfigName); + if (requiresDeviceLinking) { std::string linkRuleVar = "CMAKE_CUDA_DEVICE_LINK_LIBRARY"; this->WriteDeviceLibraryRules(linkRuleVar, relink); } @@ -430,7 +399,7 @@ void cmMakefileLibraryTargetGenerator::WriteDeviceLibraryRules( this->LocalGenerator->CreateCDCommand( commands1, this->Makefile->GetCurrentBinaryDirectory(), this->LocalGenerator->GetBinaryDirectory()); - commands.insert(commands.end(), commands1.begin(), commands1.end()); + cmAppend(commands, commands1); commands1.clear(); // Compute the list of outputs. @@ -606,7 +575,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules( this->LocalGenerator->CreateCDCommand( commands1, this->Makefile->GetCurrentBinaryDirectory(), this->LocalGenerator->GetBinaryDirectory()); - commands.insert(commands.end(), commands1.begin(), commands1.end()); + cmAppend(commands, commands1); commands1.clear(); } @@ -946,7 +915,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules( this->LocalGenerator->CreateCDCommand( commands1, this->Makefile->GetCurrentBinaryDirectory(), this->LocalGenerator->GetBinaryDirectory()); - commands.insert(commands.end(), commands1.begin(), commands1.end()); + cmAppend(commands, commands1); commands1.clear(); // Add a rule to create necessary symlinks for the library. @@ -963,7 +932,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules( this->LocalGenerator->CreateCDCommand( commands1, this->Makefile->GetCurrentBinaryDirectory(), this->LocalGenerator->GetBinaryDirectory()); - commands.insert(commands.end(), commands1.begin(), commands1.end()); + cmAppend(commands, commands1); commands1.clear(); } diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index 3a89d75..b3bab4b 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -219,14 +219,9 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules() std::vector<cmCustomCommand> buildEventCommands = this->GeneratorTarget->GetPreBuildCommands(); - buildEventCommands.insert( - buildEventCommands.end(), - this->GeneratorTarget->GetPreLinkCommands().begin(), - this->GeneratorTarget->GetPreLinkCommands().end()); - buildEventCommands.insert( - buildEventCommands.end(), - this->GeneratorTarget->GetPostBuildCommands().begin(), - this->GeneratorTarget->GetPostBuildCommands().end()); + cmAppend(buildEventCommands, this->GeneratorTarget->GetPreLinkCommands()); + cmAppend(buildEventCommands, + this->GeneratorTarget->GetPostBuildCommands()); for (const auto& be : buildEventCommands) { const std::vector<std::string>& byproducts = be.GetByproducts(); @@ -788,8 +783,12 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile( if (!compileCommands.empty() && !compilerLauncher.empty()) { std::vector<std::string> args; cmSystemTools::ExpandListArgument(compilerLauncher, args, true); - for (std::string& i : args) { - i = this->LocalGenerator->EscapeForShell(i); + if (!args.empty()) { + args[0] = this->LocalGenerator->ConvertToOutputFormat( + args[0], cmOutputConverter::SHELL); + for (std::string& i : cmMakeRange(args.begin() + 1, args.end())) { + i = this->LocalGenerator->EscapeForShell(i); + } } compileCommands.front().insert(0, cmJoin(args, " ") + " "); } @@ -815,8 +814,7 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile( this->LocalGenerator->CreateCDCommand( compileCommands, this->LocalGenerator->GetCurrentBinaryDirectory(), this->LocalGenerator->GetBinaryDirectory()); - commands.insert(commands.end(), compileCommands.begin(), - compileCommands.end()); + cmAppend(commands, compileCommands); } // Check for extra outputs created by the compilation. @@ -878,8 +876,7 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile( preprocessCommands, this->LocalGenerator->GetCurrentBinaryDirectory(), this->LocalGenerator->GetBinaryDirectory()); - commands.insert(commands.end(), preprocessCommands.begin(), - preprocessCommands.end()); + cmAppend(commands, preprocessCommands); } else { std::string cmd = "$(CMAKE_COMMAND) -E cmake_unimplemented_variable "; cmd += preprocessRuleVar; @@ -925,8 +922,7 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile( this->LocalGenerator->CreateCDCommand( assemblyCommands, this->LocalGenerator->GetCurrentBinaryDirectory(), this->LocalGenerator->GetBinaryDirectory()); - commands.insert(commands.end(), assemblyCommands.begin(), - assemblyCommands.end()); + cmAppend(commands, assemblyCommands); } else { std::string cmd = "$(CMAKE_COMMAND) -E cmake_unimplemented_variable "; cmd += assemblyRuleVar; @@ -1173,8 +1169,7 @@ void cmMakefileTargetGenerator::DriveCustomCommands( if (cmCustomCommand* cc = source->GetCustomCommand()) { cmCustomCommandGenerator ccg(*cc, this->ConfigName, this->LocalGenerator); - const std::vector<std::string>& outputs = ccg.GetOutputs(); - depends.insert(depends.end(), outputs.begin(), outputs.end()); + cmAppend(depends, ccg.GetOutputs()); } } } @@ -1398,8 +1393,7 @@ void cmMakefileTargetGenerator::WriteTargetDriverRule( } // Make sure the extra files are built. - depends.insert(depends.end(), this->ExtraFiles.begin(), - this->ExtraFiles.end()); + cmAppend(depends, this->ExtraFiles); } // Write the driver rule. @@ -1421,8 +1415,7 @@ void cmMakefileTargetGenerator::AppendTargetDepends( const std::string& cfg = this->LocalGenerator->GetConfigName(); if (cmComputeLinkInformation* cli = this->GeneratorTarget->GetLinkInformation(cfg)) { - std::vector<std::string> const& libDeps = cli->GetDepends(); - depends.insert(depends.end(), libDeps.begin(), libDeps.end()); + cmAppend(depends, cli->GetDepends()); } } @@ -1439,8 +1432,7 @@ void cmMakefileTargetGenerator::AppendObjectDepends( } // Add dependencies on the external object files. - depends.insert(depends.end(), this->ExternalObjects.begin(), - this->ExternalObjects.end()); + cmAppend(depends, this->ExternalObjects); // Add a dependency on the rule file itself. this->LocalGenerator->AppendRuleDepend(depends, diff --git a/Source/cmNinjaLinkLineDeviceComputer.cxx b/Source/cmNinjaLinkLineDeviceComputer.cxx new file mode 100644 index 0000000..84c1b37 --- /dev/null +++ b/Source/cmNinjaLinkLineDeviceComputer.cxx @@ -0,0 +1,20 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ + +#include "cmNinjaLinkLineDeviceComputer.h" + +#include "cmGlobalNinjaGenerator.h" + +cmNinjaLinkLineDeviceComputer::cmNinjaLinkLineDeviceComputer( + cmOutputConverter* outputConverter, cmStateDirectory const& stateDir, + cmGlobalNinjaGenerator const* gg) + : cmLinkLineDeviceComputer(outputConverter, stateDir) + , GG(gg) +{ +} + +std::string cmNinjaLinkLineDeviceComputer::ConvertToLinkReference( + std::string const& lib) const +{ + return GG->ConvertToNinjaPath(lib); +} diff --git a/Source/cmNinjaLinkLineDeviceComputer.h b/Source/cmNinjaLinkLineDeviceComputer.h new file mode 100644 index 0000000..84ced5b --- /dev/null +++ b/Source/cmNinjaLinkLineDeviceComputer.h @@ -0,0 +1,34 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ + +#ifndef cmNinjaLinkLineDeviceComputer_h +#define cmNinjaLinkLineDeviceComputer_h + +#include "cmConfigure.h" // IWYU pragma: keep + +#include <string> + +#include "cmLinkLineDeviceComputer.h" + +class cmGlobalNinjaGenerator; +class cmOutputConverter; +class cmStateDirectory; + +class cmNinjaLinkLineDeviceComputer : public cmLinkLineDeviceComputer +{ +public: + cmNinjaLinkLineDeviceComputer(cmOutputConverter* outputConverter, + cmStateDirectory const& stateDir, + cmGlobalNinjaGenerator const* gg); + + cmNinjaLinkLineDeviceComputer(cmNinjaLinkLineDeviceComputer const&) = delete; + cmNinjaLinkLineDeviceComputer& operator=( + cmNinjaLinkLineDeviceComputer const&) = delete; + + std::string ConvertToLinkReference(std::string const& input) const override; + +private: + cmGlobalNinjaGenerator const* GG; +}; + +#endif diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx index 06063b2..77af45e 100644 --- a/Source/cmNinjaNormalTargetGenerator.cxx +++ b/Source/cmNinjaNormalTargetGenerator.cxx @@ -22,6 +22,7 @@ #include "cmLocalGenerator.h" #include "cmLocalNinjaGenerator.h" #include "cmMakefile.h" +#include "cmNinjaLinkLineDeviceComputer.h" #include "cmNinjaTypes.h" #include "cmOSXBundleGenerator.h" #include "cmOutputConverter.h" @@ -288,6 +289,10 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile) vars.SwiftModuleName = "$SWIFT_MODULE_NAME"; vars.SwiftOutputFileMap = "$SWIFT_OUTPUT_FILE_MAP"; vars.SwiftSources = "$SWIFT_SOURCES"; + + vars.Defines = "$DEFINES"; + vars.Flags = "$FLAGS"; + vars.Includes = "$INCLUDES"; } std::string responseFlag; @@ -316,7 +321,11 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile) rspcontent = "$in_newline"; } rspcontent += " $LINK_PATH $LINK_LIBRARIES"; - vars.Objects = responseFlag.c_str(); + if (this->TargetLinkLanguage == "Swift") { + vars.SwiftSources = responseFlag.c_str(); + } else { + vars.Objects = responseFlag.c_str(); + } vars.LinkLibraries = ""; } @@ -574,32 +583,9 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement() cmGeneratorTarget& genTarget = *this->GetGeneratorTarget(); - // determine if we need to do any device linking for this target - const std::string cuda_lang("CUDA"); - cmGeneratorTarget::LinkClosure const* closure = - genTarget.GetLinkClosure(this->GetConfigName()); - - const bool hasCUDA = - (std::find(closure->Languages.begin(), closure->Languages.end(), - cuda_lang) != closure->Languages.end()); - - bool doDeviceLinking = false; - if (const char* resolveDeviceSymbols = - genTarget.GetProperty("CUDA_RESOLVE_DEVICE_SYMBOLS")) { - doDeviceLinking = cmSystemTools::IsOn(resolveDeviceSymbols); - } else { - switch (genTarget.GetType()) { - case cmStateEnums::SHARED_LIBRARY: - case cmStateEnums::MODULE_LIBRARY: - case cmStateEnums::EXECUTABLE: - doDeviceLinking = true; - break; - default: - break; - } - } - - if (!(doDeviceLinking && hasCUDA)) { + bool requiresDeviceLinking = requireDeviceLinking( + *this->GeneratorTarget, *this->GetLocalGenerator(), this->ConfigName); + if (!requiresDeviceLinking) { return; } @@ -814,10 +800,15 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() return targetNames.Base; }(); - vars["SWIFT_MODULE"] = [this]() -> std::string { - cmGeneratorTarget::Names targetNames = - this->GetGeneratorTarget()->GetLibraryNames(this->GetConfigName()); + vars["SWIFT_MODULE_NAME"] = [this]() -> std::string { + if (const char* name = + this->GetGeneratorTarget()->GetProperty("Swift_MODULE_NAME")) { + return name; + } + return this->GetGeneratorTarget()->GetName(); + }(); + vars["SWIFT_MODULE"] = [this](const std::string& module) -> std::string { std::string directory = this->GetLocalGenerator()->GetCurrentBinaryDirectory(); if (const char* prop = this->GetGeneratorTarget()->GetProperty( @@ -825,7 +816,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() directory = prop; } - std::string name = targetNames.Base + ".swiftmodule"; + std::string name = module + ".swiftmodule"; if (const char* prop = this->GetGeneratorTarget()->GetProperty("Swift_MODULE")) { name = prop; @@ -834,15 +825,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() return this->GetLocalGenerator()->ConvertToOutputFormat( this->ConvertToNinjaPath(directory + "/" + name), cmOutputConverter::SHELL); - }(); - - vars["SWIFT_MODULE_NAME"] = [this]() -> std::string { - if (const char* name = - this->GetGeneratorTarget()->GetProperty("Swift_MODULE_NAME")) { - return name; - } - return this->GetGeneratorTarget()->GetName(); - }(); + }(vars["SWIFT_MODULE_NAME"]); vars["SWIFT_OUTPUT_FILE_MAP"] = this->GetLocalGenerator()->ConvertToOutputFormat( @@ -865,6 +848,13 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() } return oss.str(); }(); + + // Since we do not perform object builds, compute the + // defines/flags/includes here so that they can be passed along + // appropriately. + vars["DEFINES"] = this->GetDefines("Swift"); + vars["FLAGS"] = this->GetFlags("Swift"); + vars["INCLUDES"] = this->GetIncludes("Swift"); } // Compute specific libraries to link with. @@ -1132,7 +1122,9 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() this->GetTargetFilePath(this->TargetNames.SharedObject)); // If one link has to be created. if (targetOutputReal == soName || targetOutput == soName) { - symlinkVars["SONAME"] = soName; + symlinkVars["SONAME"] = + this->GetLocalGenerator()->ConvertToOutputFormat( + soName, cmOutputConverter::SHELL); } else { symlinkVars["SONAME"].clear(); symlinks.push_back(soName); diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index 9deaa13..9652a51 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -25,6 +25,7 @@ #include "cmNinjaNormalTargetGenerator.h" #include "cmNinjaUtilityTargetGenerator.h" #include "cmOutputConverter.h" +#include "cmRange.h" #include "cmRulePlaceholderExpander.h" #include "cmSourceFile.h" #include "cmState.h" @@ -763,8 +764,12 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang) if (!compileCmds.empty() && !compilerLauncher.empty()) { std::vector<std::string> args; cmSystemTools::ExpandListArgument(compilerLauncher, args, true); - for (std::string& i : args) { - i = this->LocalGenerator->EscapeForShell(i); + if (!args.empty()) { + args[0] = this->LocalGenerator->ConvertToOutputFormat( + args[0], cmOutputConverter::SHELL); + for (std::string& i : cmMakeRange(args.begin() + 1, args.end())) { + i = this->LocalGenerator->EscapeForShell(i); + } } compileCmds.front().insert(0, cmJoin(args, " ") + " "); } @@ -836,8 +841,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements() this->GeneratorTarget, orderOnlyDeps, DependOnTargetOrdering); // Add order-only dependencies on other files associated with the target. - orderOnlyDeps.insert(orderOnlyDeps.end(), this->ExtraFiles.begin(), - this->ExtraFiles.end()); + cmAppend(orderOnlyDeps, this->ExtraFiles); // Add order-only dependencies on custom command outputs. for (cmCustomCommand const* cc : this->CustomCommands) { diff --git a/Source/cmOrderDirectories.cxx b/Source/cmOrderDirectories.cxx index 2c28fc0..585db42 100644 --- a/Source/cmOrderDirectories.cxx +++ b/Source/cmOrderDirectories.cxx @@ -329,15 +329,13 @@ void cmOrderDirectories::AddLinkLibrary(std::string const& fullPath) void cmOrderDirectories::AddUserDirectories( std::vector<std::string> const& extra) { - this->UserDirectories.insert(this->UserDirectories.end(), extra.begin(), - extra.end()); + cmAppend(this->UserDirectories, extra); } void cmOrderDirectories::AddLanguageDirectories( std::vector<std::string> const& dirs) { - this->LanguageDirectories.insert(this->LanguageDirectories.end(), - dirs.begin(), dirs.end()); + cmAppend(this->LanguageDirectories, dirs); } void cmOrderDirectories::SetImplicitDirectories( diff --git a/Source/cmOutputRequiredFilesCommand.cxx b/Source/cmOutputRequiredFilesCommand.cxx index 4ed5581..f3276ec 100644 --- a/Source/cmOutputRequiredFilesCommand.cxx +++ b/Source/cmOutputRequiredFilesCommand.cxx @@ -111,8 +111,7 @@ public: // Now extract any include paths from the targets std::set<std::string> uniqueIncludes; std::vector<std::string> orderedAndUniqueIncludes; - cmTargets& targets = this->Makefile->GetTargets(); - for (auto const& target : targets) { + for (auto const& target : this->Makefile->GetTargets()) { const char* incDirProp = target.second.GetProperty("INCLUDE_DIRECTORIES"); if (!incDirProp) { diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h index 4bb4c53..b705119 100644 --- a/Source/cmPolicies.h +++ b/Source/cmPolicies.h @@ -275,6 +275,10 @@ class cmMakefile; "MSVC warning flags are not in CMAKE_<LANG>_FLAGS by default.", 3, \ 15, 0, cmPolicies::WARN) \ SELECT(POLICY, CMP0093, "FindBoost reports Boost_VERSION in x.y.z format.", \ + 3, 15, 0, cmPolicies::WARN) \ + SELECT(POLICY, CMP0094, \ + "FindPython3, FindPython2 and FindPyton use " \ + "LOCATION for lookup strategy.", \ 3, 15, 0, cmPolicies::WARN) #define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1) diff --git a/Source/cmQtAutoGen.cxx b/Source/cmQtAutoGen.cxx index a245b54..3683edd 100644 --- a/Source/cmQtAutoGen.cxx +++ b/Source/cmQtAutoGen.cxx @@ -68,7 +68,7 @@ void MergeOptions(std::vector<std::string>& baseOpts, } } // Append options - baseOpts.insert(baseOpts.end(), extraOpts.begin(), extraOpts.end()); + cmAppend(baseOpts, extraOpts); } // - Class definitions @@ -347,8 +347,7 @@ bool cmQtAutoGen::RccLister::list(std::string const& qrcFile, { std::vector<std::string> cmd; cmd.emplace_back(this->RccExcutable_); - cmd.insert(cmd.end(), this->ListOptions_.begin(), - this->ListOptions_.end()); + cmAppend(cmd, this->ListOptions_); cmd.emplace_back(cmSystemTools::GetFilenameName(qrcFile)); // Log command diff --git a/Source/cmQtAutoGen.h b/Source/cmQtAutoGen.h index 3a346b5..9c52129 100644 --- a/Source/cmQtAutoGen.h +++ b/Source/cmQtAutoGen.h @@ -5,6 +5,7 @@ #include "cmConfigure.h" // IWYU pragma: keep +#include <memory> // IWYU pragma: keep #include <string> #include <vector> @@ -40,6 +41,15 @@ public: } }; + class CompilerFeatures + { + public: + bool Evaluated = false; + std::string HelpOutput; + std::vector<std::string> ListOptions; + }; + typedef std::shared_ptr<CompilerFeatures> CompilerFeaturesHandle; + /// @brief AutoGen generator type enum class GenT { diff --git a/Source/cmQtAutoGenGlobalInitializer.cxx b/Source/cmQtAutoGenGlobalInitializer.cxx index 59e17d7..ef8a56b 100644 --- a/Source/cmQtAutoGenGlobalInitializer.cxx +++ b/Source/cmQtAutoGenGlobalInitializer.cxx @@ -203,19 +203,16 @@ void cmQtAutoGenGlobalInitializer::AddToGlobalAutoRcc( } } -bool cmQtAutoGenGlobalInitializer::GetExecutableTestOutput( +cmQtAutoGen::CompilerFeaturesHandle +cmQtAutoGenGlobalInitializer::GetCompilerFeatures( std::string const& generator, std::string const& executable, - std::string& error, std::string* output) + std::string& error) { - // Check if we have cached output + // Check if we have cached features { - auto it = this->ExecutableTestOutputs_.find(executable); - if (it != this->ExecutableTestOutputs_.end()) { - // Return output on demand - if (output != nullptr) { - *output = it->second; - } - return true; + auto it = this->CompilerFeatures_.find(executable); + if (it != this->CompilerFeatures_.end()) { + return it->second; } } @@ -226,7 +223,7 @@ bool cmQtAutoGenGlobalInitializer::GetExecutableTestOutput( error += "\" executable "; error += cmQtAutoGen::Quoted(executable); error += " does not exist."; - return false; + return cmQtAutoGen::CompilerFeaturesHandle(); } // Test the executable @@ -234,7 +231,7 @@ bool cmQtAutoGenGlobalInitializer::GetExecutableTestOutput( { std::string stdErr; std::vector<std::string> command; - command.push_back(executable); + command.emplace_back(executable); command.emplace_back("-h"); int retVal = 0; const bool runResult = cmSystemTools::RunSingleCommand( @@ -250,19 +247,19 @@ bool cmQtAutoGenGlobalInitializer::GetExecutableTestOutput( error += stdOut; error += "\n"; error += stdErr; - return false; + return cmQtAutoGen::CompilerFeaturesHandle(); } } - // Return executable output on demand - if (output != nullptr) { - *output = stdOut; - } + // Create valid handle + cmQtAutoGen::CompilerFeaturesHandle res = + std::make_shared<cmQtAutoGen::CompilerFeatures>(); + res->HelpOutput = std::move(stdOut); - // Register executable and output - this->ExecutableTestOutputs_.emplace(executable, std::move(stdOut)); + // Register compiler features + this->CompilerFeatures_.emplace(executable, res); - return true; + return res; } bool cmQtAutoGenGlobalInitializer::generate() diff --git a/Source/cmQtAutoGenGlobalInitializer.h b/Source/cmQtAutoGenGlobalInitializer.h index 77429b7..d56153a 100644 --- a/Source/cmQtAutoGenGlobalInitializer.h +++ b/Source/cmQtAutoGenGlobalInitializer.h @@ -5,6 +5,8 @@ #include "cmConfigure.h" // IWYU pragma: keep +#include "cmQtAutoGen.h" + #include <map> #include <memory> // IWYU pragma: keep #include <string> @@ -68,15 +70,16 @@ private: void AddToGlobalAutoRcc(cmLocalGenerator* localGen, std::string const& targetName); - bool GetExecutableTestOutput(std::string const& generator, - std::string const& executable, - std::string& error, std::string* output); + cmQtAutoGen::CompilerFeaturesHandle GetCompilerFeatures( + std::string const& generator, std::string const& executable, + std::string& error); private: std::vector<std::unique_ptr<cmQtAutoGenInitializer>> Initializers_; std::map<cmLocalGenerator*, std::string> GlobalAutoGenTargets_; std::map<cmLocalGenerator*, std::string> GlobalAutoRccTargets_; - std::unordered_map<std::string, std::string> ExecutableTestOutputs_; + std::unordered_map<std::string, cmQtAutoGen::CompilerFeaturesHandle> + CompilerFeatures_; Keywords const Keywords_; }; diff --git a/Source/cmQtAutoGenInitializer.cxx b/Source/cmQtAutoGenInitializer.cxx index a5e0f32..265daf6 100644 --- a/Source/cmQtAutoGenInitializer.cxx +++ b/Source/cmQtAutoGenInitializer.cxx @@ -407,6 +407,19 @@ bool cmQtAutoGenInitializer::InitCustomTargets() } } } + + // CMAKE_AUTOMOC_RELAXED_MODE deprecation warning + if (this->Moc.Enabled) { + if (cmSystemTools::IsOn( + makefile->GetDefinition("CMAKE_AUTOMOC_RELAXED_MODE"))) { + std::string msg = "AUTOMOC: CMAKE_AUTOMOC_RELAXED_MODE is " + "deprecated an will be removed in the future. "; + msg += "Consider disabling it and converting the target "; + msg += this->Target->GetName(); + msg += " to regular mode."; + makefile->IssueMessage(MessageType::AUTHOR_WARNING, msg); + } + } } // Init rcc specific settings @@ -511,7 +524,7 @@ bool cmQtAutoGenInitializer::InitMoc() // Moc executable { - if (!this->GetQtExecutable(this->Moc, "moc", false, nullptr)) { + if (!this->GetQtExecutable(this->Moc, "moc", false)) { return false; } // Let the _autogen target depend on the moc executable @@ -565,7 +578,7 @@ bool cmQtAutoGenInitializer::InitUic() // Uic executable { - if (!this->GetQtExecutable(this->Uic, "uic", true, nullptr)) { + if (!this->GetQtExecutable(this->Uic, "uic", true)) { return false; } // Let the _autogen target depend on the uic executable @@ -582,17 +595,22 @@ bool cmQtAutoGenInitializer::InitRcc() { // Rcc executable { - std::string stdOut; - if (!this->GetQtExecutable(this->Rcc, "rcc", false, &stdOut)) { + if (!this->GetQtExecutable(this->Rcc, "rcc", false)) { return false; } - // Evaluate test output - if (this->QtVersion.Major == 5 || this->QtVersion.Major == 6) { - if (stdOut.find("--list") != std::string::npos) { - this->Rcc.ListOptions.emplace_back("--list"); - } else if (stdOut.find("-list") != std::string::npos) { - this->Rcc.ListOptions.emplace_back("-list"); + // Evaluate test output on demand + CompilerFeatures& features = *this->Rcc.ExecutableFeatures; + if (!features.Evaluated) { + // Look for list options + if (this->QtVersion.Major == 5 || this->QtVersion.Major == 6) { + if (features.HelpOutput.find("--list") != std::string::npos) { + features.ListOptions.emplace_back("--list"); + } else if (features.HelpOutput.find("-list") != std::string::npos) { + features.ListOptions.emplace_back("-list"); + } } + // Evaluation finished + features.Evaluated = true; } } @@ -931,7 +949,8 @@ bool cmQtAutoGenInitializer::InitScanFiles() for (Qrc& qrc : this->Rcc.Qrcs) { if (!qrc.Generated) { std::string error; - RccLister const lister(this->Rcc.Executable, this->Rcc.ListOptions); + RccLister const lister(this->Rcc.Executable, + this->Rcc.ExecutableFeatures->ListOptions); if (!lister.list(qrc.QrcFile, qrc.Resources, error)) { cmSystemTools::Error(error); return false; @@ -1437,7 +1456,8 @@ bool cmQtAutoGenInitializer::SetupWriteRccInfo() ofs.Write("# Rcc executable\n"); ofs.Write("ARCC_RCC_EXECUTABLE", this->Rcc.Executable); - ofs.WriteStrings("ARCC_RCC_LIST_OPTIONS", this->Rcc.ListOptions); + ofs.WriteStrings("ARCC_RCC_LIST_OPTIONS", + this->Rcc.ExecutableFeatures->ListOptions); ofs.Write("# Rcc job\n"); ofs.Write("ARCC_LOCK_FILE", qrc.LockFile); @@ -1600,8 +1620,7 @@ cmQtAutoGenInitializer::GetQtVersion(cmGeneratorTarget const* target) bool cmQtAutoGenInitializer::GetQtExecutable(GenVarsT& genVars, const std::string& executable, - bool ignoreMissingTarget, - std::string* output) const + bool ignoreMissingTarget) const { auto print_err = [this, &genVars](std::string const& err) { std::string msg = genVars.GenNameUpper; @@ -1631,9 +1650,9 @@ bool cmQtAutoGenInitializer::GetQtExecutable(GenVarsT& genVars, return false; } - // Check if the provided executable already exists (it's possible for it - // not to exist when building Qt itself). - genVars.ExecutableExists = cmSystemTools::FileExists(genVars.Executable); + // Create empty compiler features. + genVars.ExecutableFeatures = + std::make_shared<cmQtAutoGen::CompilerFeatures>(); return true; } } @@ -1664,6 +1683,9 @@ bool cmQtAutoGenInitializer::GetQtExecutable(GenVarsT& genVars, } } else { if (ignoreMissingTarget) { + // Create empty compiler features. + genVars.ExecutableFeatures = + std::make_shared<cmQtAutoGen::CompilerFeatures>(); return true; } std::string err = "Could not find "; @@ -1675,15 +1697,15 @@ bool cmQtAutoGenInitializer::GetQtExecutable(GenVarsT& genVars, } } - // Test executable + // Get executable features { std::string err; - if (!this->GlobalInitializer->GetExecutableTestOutput( - executable, genVars.Executable, err, output)) { + genVars.ExecutableFeatures = this->GlobalInitializer->GetCompilerFeatures( + executable, genVars.Executable, err); + if (!genVars.ExecutableFeatures) { print_err(err); return false; } - genVars.ExecutableExists = true; } return true; diff --git a/Source/cmQtAutoGenInitializer.h b/Source/cmQtAutoGenInitializer.h index 6d2dcb6..aa073d1 100644 --- a/Source/cmQtAutoGenInitializer.h +++ b/Source/cmQtAutoGenInitializer.h @@ -67,7 +67,7 @@ public: std::string ExecutableTargetName; cmGeneratorTarget* ExecutableTarget = nullptr; std::string Executable; - bool ExecutableExists = false; + CompilerFeaturesHandle ExecutableFeatures; /// @brief Constructor GenVarsT(GenT gen) @@ -148,7 +148,7 @@ private: void AddCleanFile(std::string const& fileName); bool GetQtExecutable(GenVarsT& genVars, const std::string& executable, - bool ignoreMissingTarget, std::string* output) const; + bool ignoreMissingTarget) const; private: cmQtAutoGenGlobalInitializer* GlobalInitializer; @@ -230,7 +230,6 @@ private: struct RccT : public GenVarsT { bool GlobalTarget = false; - std::vector<std::string> ListOptions; std::vector<Qrc> Qrcs; /// @brief Constructor diff --git a/Source/cmQtAutoMocUic.cxx b/Source/cmQtAutoMocUic.cxx index 36794d6..889f47d 100644 --- a/Source/cmQtAutoMocUic.cxx +++ b/Source/cmQtAutoMocUic.cxx @@ -293,11 +293,10 @@ void cmQtAutoMocUic::JobMocPredefsT::Process() // Compose command std::vector<std::string> cmd = MocConst().PredefsCmd; // Add includes - cmd.insert(cmd.end(), MocConst().Includes.begin(), - MocConst().Includes.end()); + cmAppend(cmd, MocConst().Includes); // Add definitions for (std::string const& def : MocConst().Definitions) { - cmd.push_back("-D" + def); + cmd.emplace_back("-D" + def); } // Execute command if (!RunProcess(GenT::MOC, result, cmd, reason.get())) { @@ -709,7 +708,7 @@ bool cmQtAutoMocUic::JobEvaluateT::MocEvalSource( msg += Quoted(sourceFile.FileName); msg += "!\nBetter include "; msg += Quoted(sourceBase + ".moc"); - msg += " for compatibility with strict mode.\n"; + msg += " for compatibility with regular mode.\n"; msg += "This is a CMAKE_AUTOMOC_RELAXED_MODE warning.\n"; Log().WarningFile(GenT::MOC, sourceFile.FileName, msg); } @@ -771,7 +770,7 @@ bool cmQtAutoMocUic::JobEvaluateT::MocEvalSource( msg += Quoted(header->FileName); msg += "!\nBetter include "; msg += Quoted("moc_" + incKey.Base + ".cpp"); - msg += " for a compatibility with strict mode.\n"; + msg += " for a compatibility with regular mode.\n"; msg += "This is a CMAKE_AUTOMOC_RELAXED_MODE warning.\n"; Log().WarningFile(GenT::MOC, sourceFile.FileName, msg); } else { @@ -783,7 +782,7 @@ bool cmQtAutoMocUic::JobEvaluateT::MocEvalSource( msg += Quoted(header->FileName); msg += "!\nBetter include "; msg += Quoted("moc_" + incKey.Base + ".cpp"); - msg += " for compatibility with strict mode.\n"; + msg += " for compatibility with regular mode.\n"; msg += "This is a CMAKE_AUTOMOC_RELAXED_MODE warning.\n"; Log().WarningFile(GenT::MOC, sourceFile.FileName, msg); } @@ -798,7 +797,7 @@ bool cmQtAutoMocUic::JobEvaluateT::MocEvalSource( // Check if this is the sources own .moc file bool const ownMoc = (incKey.Base == sourceBase); if (!ownMoc) { - // Don't allow <BASE>.moc include other than own in strict mode + // Don't allow <BASE>.moc include other than own in regular mode std::string msg = "The file includes the moc file "; msg += Quoted(incKey.Key); msg += ",\nwhich seems to be the moc file from a different " @@ -1398,8 +1397,7 @@ void cmQtAutoMocUic::JobMocT::Process() std::vector<std::string> cmd; cmd.push_back(MocConst().Executable); // Add options - cmd.insert(cmd.end(), MocConst().AllOptions.begin(), - MocConst().AllOptions.end()); + cmAppend(cmd, MocConst().AllOptions); // Add predefs include if (!MocConst().PredefsFileAbs.empty()) { cmd.emplace_back("--include"); @@ -1452,7 +1450,7 @@ void cmQtAutoMocUic::JobUicT::Process() UicMergeOptions(allOpts, optionIt->second, (BaseConst().QtVersionMajor == 5)); } - cmd.insert(cmd.end(), allOpts.begin(), allOpts.end()); + cmAppend(cmd, allOpts); } cmd.emplace_back("-o"); cmd.emplace_back(outputFile); @@ -1881,9 +1879,8 @@ bool cmQtAutoMocUic::Init(cmMakefile* makefile) // Sort include directories on demand if (BaseConst().IncludeProjectDirsBefore) { // Move strings to temporary list - std::list<std::string> includes; - includes.insert(includes.end(), MocConst().IncludePaths.begin(), - MocConst().IncludePaths.end()); + std::list<std::string> includes(MocConst().IncludePaths.begin(), + MocConst().IncludePaths.end()); MocConst_.IncludePaths.clear(); MocConst_.IncludePaths.reserve(includes.size()); // Append project directories only diff --git a/Source/cmQtAutoRcc.cxx b/Source/cmQtAutoRcc.cxx index 7ac7339..20885df 100644 --- a/Source/cmQtAutoRcc.cxx +++ b/Source/cmQtAutoRcc.cxx @@ -431,7 +431,7 @@ bool cmQtAutoRcc::GenerateRcc() // Compose rcc command std::vector<std::string> cmd; cmd.push_back(RccExecutable_); - cmd.insert(cmd.end(), Options_.begin(), Options_.end()); + cmAppend(cmd, Options_); cmd.emplace_back("-o"); cmd.push_back(RccFileOutput_); cmd.push_back(QrcFile_); diff --git a/Source/cmSetTargetPropertiesCommand.cxx b/Source/cmSetTargetPropertiesCommand.cxx index 6425913..1dc7e69 100644 --- a/Source/cmSetTargetPropertiesCommand.cxx +++ b/Source/cmSetTargetPropertiesCommand.cxx @@ -4,6 +4,7 @@ #include <iterator> +#include "cmAlgorithms.h" #include "cmMakefile.h" #include "cmTarget.h" @@ -30,7 +31,7 @@ bool cmSetTargetPropertiesCommand::InitialPass( this->SetError("called with incorrect number of arguments."); return false; } - propertyPairs.insert(propertyPairs.end(), j, args.end()); + cmAppend(propertyPairs, j, args.end()); break; } numFiles++; diff --git a/Source/cmSetTestsPropertiesCommand.cxx b/Source/cmSetTestsPropertiesCommand.cxx index e27c675..cc9587c 100644 --- a/Source/cmSetTestsPropertiesCommand.cxx +++ b/Source/cmSetTestsPropertiesCommand.cxx @@ -4,6 +4,7 @@ #include <iterator> +#include "cmAlgorithms.h" #include "cmMakefile.h" #include "cmTest.h" @@ -30,7 +31,7 @@ bool cmSetTestsPropertiesCommand::InitialPass( this->SetError("called with incorrect number of arguments."); return false; } - propertyPairs.insert(propertyPairs.end(), j, args.end()); + cmAppend(propertyPairs, j, args.end()); break; } numFiles++; diff --git a/Source/cmStateDirectory.cxx b/Source/cmStateDirectory.cxx index 31273cc..182d3fe 100644 --- a/Source/cmStateDirectory.cxx +++ b/Source/cmStateDirectory.cxx @@ -621,9 +621,7 @@ const char* cmStateDirectory::GetProperty(const std::string& prop, } if (prop == "VARIABLES") { std::vector<std::string> res = this->Snapshot_.ClosureKeys(); - std::vector<std::string> cacheKeys = - this->Snapshot_.State->GetCacheEntryKeys(); - res.insert(res.end(), cacheKeys.begin(), cacheKeys.end()); + cmAppend(res, this->Snapshot_.State->GetCacheEntryKeys()); std::sort(res.begin(), res.end()); output = cmJoin(res, ";"); return output.c_str(); diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index 4ba04ed..8b9a517 100644 --- a/Source/cmSystemTools.cxx +++ b/Source/cmSystemTools.cxx @@ -6,7 +6,6 @@ #include "cmDuration.h" #include "cmProcessOutput.h" #include "cmRange.h" -#include "cm_sys_stat.h" #include "cm_uv.h" #if defined(CMAKE_BUILD_WITH_CMAKE) @@ -60,7 +59,6 @@ #else # include <sys/time.h> # include <unistd.h> -# include <utime.h> #endif #if defined(_WIN32) && \ @@ -90,18 +88,6 @@ static bool cm_isspace(char c) return ((c & 0x80) == 0) && isspace(c); } -class cmSystemToolsFileTime -{ -public: -#if defined(_WIN32) && !defined(__CYGWIN__) - FILETIME timeCreation; - FILETIME timeLastAccess; - FILETIME timeLastWrite; -#else - struct utimbuf timeBuf; -#endif -}; - #if !defined(HAVE_ENVIRON_NOT_REQUIRE_PROTOTYPE) // For GetEnvironmentVariables # if defined(_WIN32) @@ -134,29 +120,6 @@ static int cm_archive_read_open_file(struct archive* a, const char* file, #endif #ifdef _WIN32 -class cmSystemToolsWindowsHandle -{ -public: - cmSystemToolsWindowsHandle(HANDLE h) - : handle_(h) - { - } - ~cmSystemToolsWindowsHandle() - { - if (this->handle_ != INVALID_HANDLE_VALUE) { - CloseHandle(this->handle_); - } - } - explicit operator bool() const - { - return this->handle_ != INVALID_HANDLE_VALUE; - } - bool operator!() const { return this->handle_ == INVALID_HANDLE_VALUE; } - operator HANDLE() const { return this->handle_; } - -private: - HANDLE handle_; -}; #elif defined(__APPLE__) # include <crt_externs.h> @@ -249,26 +212,6 @@ std::string cmSystemTools::TrimWhitespace(const std::string& s) return std::string(start, stop + 1); } -void cmSystemTools::Error(const char* m1, const char* m2, const char* m3, - const char* m4) -{ - std::string message = "CMake Error: "; - if (m1) { - message += m1; - } - if (m2) { - message += m2; - } - if (m3) { - message += m3; - } - if (m4) { - message += m4; - } - cmSystemTools::s_ErrorOccured = true; - cmSystemTools::Message(message, "Error"); -} - void cmSystemTools::Error(const std::string& m) { std::string message = "CMake Error: " + m; @@ -558,7 +501,7 @@ std::vector<std::string> cmSystemTools::HandleResponseFile( #else cmSystemTools::ParseUnixCommandLine(line.c_str(), args2); #endif - arg_full.insert(arg_full.end(), args2.begin(), args2.end()); + cmAppend(arg_full, args2); } } else { arg_full.push_back(arg); @@ -783,7 +726,7 @@ bool cmSystemTools::RunSingleCommand(std::vector<std::string> const& command, cmSystemTools::Stdout(strdata); } if (captureStdOut) { - tempStdOut.insert(tempStdOut.end(), data, data + length); + cmAppend(tempStdOut, data, data + length); } } else if (pipe == cmsysProcess_Pipe_STDERR) { if (outputflag != OUTPUT_NONE) { @@ -791,7 +734,7 @@ bool cmSystemTools::RunSingleCommand(std::vector<std::string> const& command, cmSystemTools::Stderr(strdata); } if (captureStdErr) { - tempStdErr.insert(tempStdErr.end(), data, data + length); + cmAppend(tempStdErr, data, data + length); } } } @@ -1749,6 +1692,16 @@ void list_item_verbose(FILE* out, struct archive_entry* entry) fflush(out); } +void ArchiveError(const char* m1, struct archive* a) +{ + std::string message(m1); + const char* m2 = archive_error_string(a); + if (m2) { + message += m2; + } + cmSystemTools::Error(message); +} + bool la_diagnostic(struct archive* ar, __LA_SSIZE_T r) { // See archive.h definition of ARCHIVE_OK for return values. @@ -1807,7 +1760,9 @@ bool copy_data(struct archive* ar, struct archive* aw) # endif } -bool extract_tar(const char* outFileName, bool verbose, bool extract) +bool extract_tar(const char* outFileName, + const std::vector<std::string>& files, bool verbose, + bool extract) { cmLocaleRAII localeRAII; static_cast<void>(localeRAII); @@ -1816,10 +1771,24 @@ bool extract_tar(const char* outFileName, bool verbose, bool extract) archive_read_support_filter_all(a); archive_read_support_format_all(a); struct archive_entry* entry; + + struct archive* matching = archive_match_new(); + if (matching == nullptr) { + cmSystemTools::Error("Out of memory"); + return false; + } + + for (const auto& filename : files) { + if (archive_match_include_pattern(matching, filename.c_str()) != + ARCHIVE_OK) { + cmSystemTools::Error("Failed to add to inclusion list: " + filename); + return false; + } + } + int r = cm_archive_read_open_file(a, outFileName, 10240); if (r) { - cmSystemTools::Error("Problem with archive_read_open_file(): ", - archive_error_string(a)); + ArchiveError("Problem with archive_read_open_file(): ", a); archive_write_free(ext); archive_read_close(a); return false; @@ -1830,10 +1799,14 @@ bool extract_tar(const char* outFileName, bool verbose, bool extract) break; } if (r != ARCHIVE_OK) { - cmSystemTools::Error("Problem with archive_read_next_header(): ", - archive_error_string(a)); + ArchiveError("Problem with archive_read_next_header(): ", a); break; } + + if (archive_match_excluded(matching, entry)) { + continue; + } + if (verbose) { if (extract) { cmSystemTools::Stdout("x "); @@ -1849,8 +1822,7 @@ bool extract_tar(const char* outFileName, bool verbose, bool extract) if (extract) { r = archive_write_disk_set_options(ext, ARCHIVE_EXTRACT_TIME); if (r != ARCHIVE_OK) { - cmSystemTools::Error("Problem with archive_write_disk_set_options(): ", - archive_error_string(ext)); + ArchiveError("Problem with archive_write_disk_set_options(): ", ext); break; } @@ -1861,8 +1833,7 @@ bool extract_tar(const char* outFileName, bool verbose, bool extract) } r = archive_write_finish_entry(ext); if (r != ARCHIVE_OK) { - cmSystemTools::Error("Problem with archive_write_finish_entry(): ", - archive_error_string(ext)); + ArchiveError("Problem with archive_write_finish_entry(): ", ext); break; } } @@ -1874,14 +1845,34 @@ bool extract_tar(const char* outFileName, bool verbose, bool extract) } # endif else { - cmSystemTools::Error("Problem with archive_write_header(): ", - archive_error_string(ext)); + ArchiveError("Problem with archive_write_header(): ", ext); cmSystemTools::Error("Current file: " + cm_archive_entry_pathname(entry)); break; } } } + + bool error_occured = false; + if (matching != nullptr) { + const char* p; + int ar; + + while ((ar = archive_match_path_unmatched_inclusions_next(matching, &p)) == + ARCHIVE_OK) { + cmSystemTools::Error("tar: " + std::string(p) + + ": Not found in archive"); + error_occured = true; + } + if (error_occured) { + return false; + } + if (ar == ARCHIVE_FATAL) { + cmSystemTools::Error("tar: Out of memory"); + return false; + } + } + archive_match_free(matching); archive_write_free(ext); archive_read_close(a); archive_read_free(a); @@ -1890,23 +1881,29 @@ bool extract_tar(const char* outFileName, bool verbose, bool extract) } #endif -bool cmSystemTools::ExtractTar(const char* outFileName, bool verbose) +bool cmSystemTools::ExtractTar(const char* outFileName, + const std::vector<std::string>& files, + bool verbose) { #if defined(CMAKE_BUILD_WITH_CMAKE) - return extract_tar(outFileName, verbose, true); + return extract_tar(outFileName, files, verbose, true); #else (void)outFileName; + (void)files; (void)verbose; return false; #endif } -bool cmSystemTools::ListTar(const char* outFileName, bool verbose) +bool cmSystemTools::ListTar(const char* outFileName, + const std::vector<std::string>& files, + bool verbose) { #if defined(CMAKE_BUILD_WITH_CMAKE) - return extract_tar(outFileName, verbose, false); + return extract_tar(outFileName, files, verbose, false); #else (void)outFileName; + (void)files; (void)verbose; return false; #endif @@ -1972,26 +1969,26 @@ int cmSystemTools::WaitForLine(cmsysProcess* process, std::string& line, processOutput.DecodeText(data, length, strdata, 1); // Append to the stdout buffer. std::vector<char>::size_type size = out.size(); - out.insert(out.end(), strdata.begin(), strdata.end()); + cmAppend(out, strdata); outiter = out.begin() + size; } else if (pipe == cmsysProcess_Pipe_STDERR) { processOutput.DecodeText(data, length, strdata, 2); // Append to the stderr buffer. std::vector<char>::size_type size = err.size(); - err.insert(err.end(), strdata.begin(), strdata.end()); + cmAppend(err, strdata); erriter = err.begin() + size; } else if (pipe == cmsysProcess_Pipe_None) { // Both stdout and stderr pipes have broken. Return leftover data. processOutput.DecodeText(std::string(), strdata, 1); if (!strdata.empty()) { std::vector<char>::size_type size = out.size(); - out.insert(out.end(), strdata.begin(), strdata.end()); + cmAppend(out, strdata); outiter = out.begin() + size; } processOutput.DecodeText(std::string(), strdata, 2); if (!strdata.empty()) { std::vector<char>::size_type size = err.size(); - err.insert(err.end(), strdata.begin(), strdata.end()); + cmAppend(err, strdata); erriter = err.begin() + size; } if (!out.empty()) { @@ -2101,91 +2098,6 @@ void cmSystemTools::DoNotInheritStdPipes() #endif } -bool cmSystemTools::CopyFileTime(const std::string& fromFile, - const std::string& toFile) -{ -#if defined(_WIN32) && !defined(__CYGWIN__) - cmSystemToolsWindowsHandle hFrom = CreateFileW( - SystemTools::ConvertToWindowsExtendedPath(fromFile).c_str(), GENERIC_READ, - FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0); - cmSystemToolsWindowsHandle hTo = CreateFileW( - SystemTools::ConvertToWindowsExtendedPath(toFile).c_str(), - FILE_WRITE_ATTRIBUTES, 0, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0); - if (!hFrom || !hTo) { - return false; - } - FILETIME timeCreation; - FILETIME timeLastAccess; - FILETIME timeLastWrite; - if (!GetFileTime(hFrom, &timeCreation, &timeLastAccess, &timeLastWrite)) { - return false; - } - return SetFileTime(hTo, &timeCreation, &timeLastAccess, &timeLastWrite) != 0; -#else - struct stat fromStat; - if (stat(fromFile.c_str(), &fromStat) < 0) { - return false; - } - - struct utimbuf buf; - buf.actime = fromStat.st_atime; - buf.modtime = fromStat.st_mtime; - return utime(toFile.c_str(), &buf) >= 0; -#endif -} - -cmSystemToolsFileTime* cmSystemTools::FileTimeNew() -{ - return new cmSystemToolsFileTime; -} - -void cmSystemTools::FileTimeDelete(cmSystemToolsFileTime* t) -{ - delete t; -} - -bool cmSystemTools::FileTimeGet(const std::string& fname, - cmSystemToolsFileTime* t) -{ -#if defined(_WIN32) && !defined(__CYGWIN__) - cmSystemToolsWindowsHandle h = CreateFileW( - SystemTools::ConvertToWindowsExtendedPath(fname).c_str(), GENERIC_READ, - FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0); - if (!h) { - return false; - } - if (!GetFileTime(h, &t->timeCreation, &t->timeLastAccess, - &t->timeLastWrite)) { - return false; - } -#else - struct stat st; - if (stat(fname.c_str(), &st) < 0) { - return false; - } - t->timeBuf.actime = st.st_atime; - t->timeBuf.modtime = st.st_mtime; -#endif - return true; -} - -bool cmSystemTools::FileTimeSet(const std::string& fname, - const cmSystemToolsFileTime* t) -{ -#if defined(_WIN32) && !defined(__CYGWIN__) - cmSystemToolsWindowsHandle h = CreateFileW( - SystemTools::ConvertToWindowsExtendedPath(fname).c_str(), - FILE_WRITE_ATTRIBUTES, 0, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0); - if (!h) { - return false; - } - return SetFileTime(h, &t->timeCreation, &t->timeLastAccess, - &t->timeLastWrite) != 0; -#else - return utime(fname.c_str(), &t->timeBuf) >= 0; -#endif -} - #ifdef _WIN32 # ifndef CRYPT_SILENT # define CRYPT_SILENT 0x40 /* Not defined by VS 6 version of header. */ diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h index 64d6d7a..f07de6d 100644 --- a/Source/cmSystemTools.h +++ b/Source/cmSystemTools.h @@ -15,8 +15,6 @@ #include <string> #include <vector> -class cmSystemToolsFileTime; - /** \class cmSystemTools * \brief A collection of useful functions for CMake. * @@ -100,8 +98,6 @@ public: /** * Display an error message. */ - static void Error(const char* m, const char* m2 = nullptr, - const char* m3 = nullptr, const char* m4 = nullptr); static void Error(const std::string& m); /** @@ -455,13 +451,15 @@ public: TarCompressNone }; - static bool ListTar(const char* outFileName, bool verbose); + static bool ListTar(const char* outFileName, + const std::vector<std::string>& files, bool verbose); static bool CreateTar(const char* outFileName, const std::vector<std::string>& files, cmTarCompression compressType, bool verbose, std::string const& mtime = std::string(), std::string const& format = std::string()); - static bool ExtractTar(const char* inFileName, bool verbose); + static bool ExtractTar(const char* inFileName, + const std::vector<std::string>& files, bool verbose); // This should be called first thing in main // it will keep child processes from inheriting the // stdin and stdout of this process. This is important @@ -471,18 +469,6 @@ public: static void EnsureStdPipes(); - /** Copy the file create/access/modify times from the file named by - the first argument to that named by the second. */ - static bool CopyFileTime(const std::string& fromFile, - const std::string& toFile); - - /** Save and restore file times. */ - static cmSystemToolsFileTime* FileTimeNew(); - static void FileTimeDelete(cmSystemToolsFileTime*); - static bool FileTimeGet(const std::string& fname, cmSystemToolsFileTime* t); - static bool FileTimeSet(const std::string& fname, - const cmSystemToolsFileTime* t); - /** Random seed generation. */ static unsigned int RandomSeed(); diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 2de8950..cd67586 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -34,13 +34,6 @@ #include "cmTargetPropertyComputer.h" #include "cmake.h" -//! Append all elements from the second container to the first container -template <class C, class R> -static inline void CApp(C& container, R const& range) -{ - container.insert(container.end(), range.begin(), range.end()); -} - template <> const char* cmTargetPropertyComputer::ComputeLocationForBuild<cmTarget>( cmTarget const* tgt) @@ -284,6 +277,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type, InitProperty("RUNTIME_OUTPUT_DIRECTORY", nullptr); InitProperty("PDB_OUTPUT_DIRECTORY", nullptr); InitProperty("COMPILE_PDB_OUTPUT_DIRECTORY", nullptr); + InitProperty("FRAMEWORK", nullptr); InitProperty("Fortran_FORMAT", nullptr); InitProperty("Fortran_MODULE_DIRECTORY", nullptr); InitProperty("Fortran_COMPILER_LAUNCHER", nullptr); @@ -405,29 +399,30 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type, if (!this->IsImported()) { // Initialize the INCLUDE_DIRECTORIES property based on the current value // of the same directory property: - CApp(impl->IncludeDirectoriesEntries, - impl->Makefile->GetIncludeDirectoriesEntries()); - CApp(impl->IncludeDirectoriesBacktraces, - impl->Makefile->GetIncludeDirectoriesBacktraces()); + cmAppend(impl->IncludeDirectoriesEntries, + impl->Makefile->GetIncludeDirectoriesEntries()); + cmAppend(impl->IncludeDirectoriesBacktraces, + impl->Makefile->GetIncludeDirectoriesBacktraces()); { auto const& sysInc = impl->Makefile->GetSystemIncludeDirectories(); impl->SystemIncludeDirectories.insert(sysInc.begin(), sysInc.end()); } - CApp(impl->CompileOptionsEntries, - impl->Makefile->GetCompileOptionsEntries()); - CApp(impl->CompileOptionsBacktraces, - impl->Makefile->GetCompileOptionsBacktraces()); + cmAppend(impl->CompileOptionsEntries, + impl->Makefile->GetCompileOptionsEntries()); + cmAppend(impl->CompileOptionsBacktraces, + impl->Makefile->GetCompileOptionsBacktraces()); - CApp(impl->LinkOptionsEntries, impl->Makefile->GetLinkOptionsEntries()); - CApp(impl->LinkOptionsBacktraces, - impl->Makefile->GetLinkOptionsBacktraces()); + cmAppend(impl->LinkOptionsEntries, + impl->Makefile->GetLinkOptionsEntries()); + cmAppend(impl->LinkOptionsBacktraces, + impl->Makefile->GetLinkOptionsBacktraces()); - CApp(impl->LinkDirectoriesEntries, - impl->Makefile->GetLinkDirectoriesEntries()); - CApp(impl->LinkDirectoriesBacktraces, - impl->Makefile->GetLinkDirectoriesBacktraces()); + cmAppend(impl->LinkDirectoriesEntries, + impl->Makefile->GetLinkDirectoriesEntries()); + cmAppend(impl->LinkDirectoriesBacktraces, + impl->Makefile->GetLinkDirectoriesBacktraces()); } if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY && diff --git a/Source/cmTarget.h b/Source/cmTarget.h index 0ac5ca7..fdcca47 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -9,7 +9,6 @@ #include <memory> // IWYU pragma: keep #include <set> #include <string> -#include <unordered_map> #include <utility> #include <vector> @@ -260,6 +259,4 @@ private: std::unique_ptr<cmTargetInternals> impl; }; -typedef std::unordered_map<std::string, cmTarget> cmTargets; - #endif diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index ab9ef79..d328a8c 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -10,6 +10,7 @@ #include "cmGeneratorExpression.h" #include "cmGeneratorTarget.h" #include "cmGlobalVisualStudio10Generator.h" +#include "cmLinkLineDeviceComputer.h" #include "cmLocalVisualStudio10Generator.h" #include "cmMakefile.h" #include "cmSourceFile.h" @@ -3007,21 +3008,8 @@ bool cmVisualStudio10TargetGenerator::ComputeCudaLinkOptions( Options& cudaLinkOptions = *pOptions; // Determine if we need to do a device link - bool doDeviceLinking = false; - if (const char* resolveDeviceSymbols = - this->GeneratorTarget->GetProperty("CUDA_RESOLVE_DEVICE_SYMBOLS")) { - doDeviceLinking = cmSystemTools::IsOn(resolveDeviceSymbols); - } else { - switch (this->GeneratorTarget->GetType()) { - case cmStateEnums::SHARED_LIBRARY: - case cmStateEnums::MODULE_LIBRARY: - case cmStateEnums::EXECUTABLE: - doDeviceLinking = true; - break; - default: - break; - } - } + bool doDeviceLinking = requireDeviceLinking( + *this->GeneratorTarget, *this->LocalGenerator, configName); cudaLinkOptions.AddFlag("PerformDeviceLink", doDeviceLinking ? "true" : "false"); @@ -4099,29 +4087,29 @@ void cmVisualStudio10TargetGenerator::WriteApplicationTypeSettings(Elem& e1) bool isAppContainer = false; bool const isWindowsPhone = this->GlobalGenerator->TargetsWindowsPhone(); bool const isWindowsStore = this->GlobalGenerator->TargetsWindowsStore(); - std::string const& v = this->GlobalGenerator->GetSystemVersion(); + std::string const& rev = this->GlobalGenerator->GetApplicationTypeRevision(); if (isWindowsPhone || isWindowsStore) { e1.Element("ApplicationType", (isWindowsPhone ? "Windows Phone" : "Windows Store")); e1.Element("DefaultLanguage", "en-US"); - if (cmHasLiteralPrefix(v, "10.0")) { - e1.Element("ApplicationTypeRevision", "10.0"); + if (rev == "10.0") { + e1.Element("ApplicationTypeRevision", rev); // Visual Studio 14.0 is necessary for building 10.0 apps e1.Element("MinimumVisualStudioVersion", "14.0"); if (this->GeneratorTarget->GetType() < cmStateEnums::UTILITY) { isAppContainer = true; } - } else if (v == "8.1") { - e1.Element("ApplicationTypeRevision", v); + } else if (rev == "8.1") { + e1.Element("ApplicationTypeRevision", rev); // Visual Studio 12.0 is necessary for building 8.1 apps e1.Element("MinimumVisualStudioVersion", "12.0"); if (this->GeneratorTarget->GetType() < cmStateEnums::UTILITY) { isAppContainer = true; } - } else if (v == "8.0") { - e1.Element("ApplicationTypeRevision", v); + } else if (rev == "8.0") { + e1.Element("ApplicationTypeRevision", rev); // Visual Studio 11.0 is necessary for building 8.0 apps e1.Element("MinimumVisualStudioVersion", "11.0"); @@ -4153,7 +4141,7 @@ void cmVisualStudio10TargetGenerator::WriteApplicationTypeSettings(Elem& e1) "VS_WINDOWS_TARGET_PLATFORM_MIN_VERSION"); if (targetPlatformMinVersion) { e1.Element("WindowsTargetPlatformMinVersion", targetPlatformMinVersion); - } else if (isWindowsStore && cmHasLiteralPrefix(v, "10.0")) { + } else if (isWindowsStore && rev == "10.0") { // If the min version is not set, then use the TargetPlatformVersion if (!targetPlatformVersion.empty()) { e1.Element("WindowsTargetPlatformMinVersion", targetPlatformVersion); diff --git a/Source/cmake.cxx b/Source/cmake.cxx index 031123a..f0b53f4 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -159,6 +159,9 @@ cmake::cmake(Role role, cmState::Mode mode) #endif this->GlobalGenerator = nullptr; + this->GeneratorInstanceSet = false; + this->GeneratorPlatformSet = false; + this->GeneratorToolsetSet = false; this->CurrentWorkingMode = NORMAL_MODE; #ifdef CMAKE_BUILD_WITH_CMAKE @@ -174,6 +177,10 @@ cmake::cmake(Role role, cmState::Mode mode) this->AddProjectCommands(); } + if (mode == cmState::Project) { + this->LoadEnvironmentPresets(); + } + // Make sure we can capture the build tool output. cmSystemTools::EnableVSConsoleOutput(); @@ -612,6 +619,35 @@ bool cmake::FindPackage(const std::vector<std::string>& args) return packageFound; } +void cmake::LoadEnvironmentPresets() +{ + std::string envGenVar; + bool hasEnvironmentGenerator = false; + if (cmSystemTools::GetEnv("CMAKE_GENERATOR", envGenVar)) { + hasEnvironmentGenerator = true; + this->EnvironmentGenerator = envGenVar; + } + + auto readGeneratorVar = [&](std::string name, std::string& key) { + std::string varValue; + if (cmSystemTools::GetEnv(name, varValue)) { + if (hasEnvironmentGenerator) { + key = varValue; + } else if (!this->GetIsInTryCompile()) { + std::string message = "Warning: Environment variable "; + message += name; + message += " will be ignored, because CMAKE_GENERATOR "; + message += "is not set."; + cmSystemTools::Message(message, "Warning"); + } + } + }; + + readGeneratorVar("CMAKE_GENERATOR_INSTANCE", this->GeneratorInstance); + readGeneratorVar("CMAKE_GENERATOR_PLATFORM", this->GeneratorPlatform); + readGeneratorVar("CMAKE_GENERATOR_TOOLSET", this->GeneratorToolset); +} + // Parse the args void cmake::SetArgs(const std::vector<std::string>& args) { @@ -767,7 +803,7 @@ void cmake::SetArgs(const std::vector<std::string>& args) cmSystemTools::Error("Multiple -A options not allowed"); return; } - this->GeneratorPlatform = value; + this->SetGeneratorPlatform(value); havePlatform = true; } else if (arg.find("-T", 0) == 0) { std::string value = arg.substr(2); @@ -783,7 +819,7 @@ void cmake::SetArgs(const std::vector<std::string>& args) cmSystemTools::Error("Multiple -T options not allowed"); return; } - this->GeneratorToolset = value; + this->SetGeneratorToolset(value); haveToolset = true; } else if (arg.find("-G", 0) == 0) { std::string value = arg.substr(2); @@ -814,6 +850,16 @@ void cmake::SetArgs(const std::vector<std::string>& args) else { this->SetDirectoriesFromFile(arg); } + // Empty instance, platform and toolset if only a generator is specified + if (this->GlobalGenerator) { + this->GeneratorInstance = ""; + if (!this->GeneratorPlatformSet) { + this->GeneratorPlatform = ""; + } + if (!this->GeneratorToolsetSet) { + this->GeneratorToolset = ""; + } + } } const bool haveSourceDir = !this->GetHomeDirectory().empty(); @@ -999,10 +1045,7 @@ void cmake::GetRegisteredGenerators(std::vector<GeneratorInfo>& generators, std::vector<std::string> names = gen->GetGeneratorNames(); if (includeNamesWithPlatform) { - std::vector<std::string> namesWithPlatform = - gen->GetGeneratorNamesWithPlatform(); - names.insert(names.end(), namesWithPlatform.begin(), - namesWithPlatform.end()); + cmAppend(names, gen->GetGeneratorNamesWithPlatform()); } for (std::string const& name : names) { @@ -1446,8 +1489,7 @@ int cmake::ActualConfigure() if (const std::string* instance = this->State->GetInitializedCacheValue("CMAKE_GENERATOR_INSTANCE")) { - if (!this->GeneratorInstance.empty() && - this->GeneratorInstance != *instance) { + if (this->GeneratorInstanceSet && this->GeneratorInstance != *instance) { std::string message = "Error: generator instance: "; message += this->GeneratorInstance; message += "\nDoes not match the instance used previously: "; @@ -1465,7 +1507,7 @@ int cmake::ActualConfigure() if (const std::string* platformName = this->State->GetInitializedCacheValue("CMAKE_GENERATOR_PLATFORM")) { - if (!this->GeneratorPlatform.empty() && + if (this->GeneratorPlatformSet && this->GeneratorPlatform != *platformName) { std::string message = "Error: generator platform: "; message += this->GeneratorPlatform; @@ -1484,7 +1526,7 @@ int cmake::ActualConfigure() if (const std::string* tsName = this->State->GetInitializedCacheValue("CMAKE_GENERATOR_TOOLSET")) { - if (!this->GeneratorToolset.empty() && this->GeneratorToolset != *tsName) { + if (this->GeneratorToolsetSet && this->GeneratorToolset != *tsName) { std::string message = "Error: generator toolset: "; message += this->GeneratorToolset; message += "\nDoes not match the toolset used previously: "; @@ -1562,6 +1604,16 @@ int cmake::ActualConfigure() std::unique_ptr<cmGlobalGenerator> cmake::EvaluateDefaultGlobalGenerator() { + if (!this->EnvironmentGenerator.empty()) { + cmGlobalGenerator* gen = + this->CreateGlobalGenerator(this->EnvironmentGenerator); + if (!gen) { + cmSystemTools::Error("CMAKE_GENERATOR was set but the specified " + "generator doesn't exist. Using CMake default."); + } else { + return std::unique_ptr<cmGlobalGenerator>(gen); + } + } #if defined(_WIN32) && !defined(__CYGWIN__) && !defined(CMAKE_BOOT_MINGW) std::string found; // Try to find the newest VS installed on the computer and diff --git a/Source/cmake.h b/Source/cmake.h index 34d9bcd..4de9d28 100644 --- a/Source/cmake.h +++ b/Source/cmake.h @@ -214,18 +214,21 @@ public: void SetGeneratorInstance(std::string const& instance) { this->GeneratorInstance = instance; + this->GeneratorInstanceSet = true; } //! Set the name of the selected generator-specific platform. void SetGeneratorPlatform(std::string const& ts) { this->GeneratorPlatform = ts; + this->GeneratorPlatformSet = true; } //! Set the name of the selected generator-specific toolset. void SetGeneratorToolset(std::string const& ts) { this->GeneratorToolset = ts; + this->GeneratorToolsetSet = true; } const std::vector<std::string>& GetSourceExtensions() const @@ -276,6 +279,9 @@ public: */ int GetSystemInformation(std::vector<std::string>&); + //! Parse environment variables + void LoadEnvironmentPresets(); + //! Parse command line arguments void SetArgs(const std::vector<std::string>& args); @@ -479,6 +485,9 @@ protected: std::string GeneratorInstance; std::string GeneratorPlatform; std::string GeneratorToolset; + bool GeneratorInstanceSet; + bool GeneratorPlatformSet; + bool GeneratorToolsetSet; //! read in a cmake list file to initialize the cache void ReadListFile(const std::vector<std::string>& args, @@ -521,6 +530,7 @@ private: std::string CheckStampFile; std::string CheckStampList; std::string VSSolutionFile; + std::string EnvironmentGenerator; std::vector<std::string> SourceFileExtensions; std::unordered_set<std::string> SourceFileExtensionsSet; std::vector<std::string> HeaderFileExtensions; diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx index e639c66..64026ca 100644 --- a/Source/cmakemain.cxx +++ b/Source/cmakemain.cxx @@ -122,7 +122,7 @@ static int do_command(int ac, char const* const* av) std::vector<std::string> args; args.reserve(ac - 1); args.emplace_back(av[0]); - args.insert(args.end(), av + 2, av + ac); + cmAppend(args, av + 2, av + ac); return cmcmd::ExecuteCMakeCommand(args); } diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx index e1b6f48..e37dbe8 100644 --- a/Source/cmcmd.cxx +++ b/Source/cmcmd.cxx @@ -173,7 +173,7 @@ static int HandleIWYU(const std::string& runCmd, // and adding all the arguments we give to the compiler. std::vector<std::string> iwyu_cmd; cmSystemTools::ExpandListArgument(runCmd, iwyu_cmd, true); - iwyu_cmd.insert(iwyu_cmd.end(), orig_cmd.begin() + 1, orig_cmd.end()); + cmAppend(iwyu_cmd, orig_cmd.begin() + 1, orig_cmd.end()); // Run the iwyu command line. Capture its stderr and hide its stdout. // Ignore its return code because the tool always returns non-zero. std::string stdErr; @@ -201,11 +201,11 @@ static int HandleTidy(const std::string& runCmd, const std::string& sourceFile, // automatically skip over the compiler itself and extract the // options. int ret; - std::vector<std::string> tidy_cmd; - cmSystemTools::ExpandListArgument(runCmd, tidy_cmd, true); + std::vector<std::string> tidy_cmd = + cmSystemTools::ExpandedListArgument(runCmd, true); tidy_cmd.push_back(sourceFile); tidy_cmd.emplace_back("--"); - tidy_cmd.insert(tidy_cmd.end(), orig_cmd.begin(), orig_cmd.end()); + cmAppend(tidy_cmd, orig_cmd); // Run the tidy command line. Capture its stdout and hide its stderr. std::string stdOut; @@ -1130,7 +1130,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args) return 1; } if (action == cmSystemTools::TarActionList) { - if (!cmSystemTools::ListTar(outFile.c_str(), verbose)) { + if (!cmSystemTools::ListTar(outFile.c_str(), files, verbose)) { cmSystemTools::Error("Problem listing tar: " + outFile); return 1; } @@ -1145,7 +1145,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args) return 1; } } else if (action == cmSystemTools::TarActionExtract) { - if (!cmSystemTools::ExtractTar(outFile.c_str(), verbose)) { + if (!cmSystemTools::ExtractTar(outFile.c_str(), files, verbose)) { cmSystemTools::Error("Problem extracting tar: " + outFile); return 1; } @@ -1922,8 +1922,7 @@ int cmVSLink::RunMT(std::string const& out, bool notify) if (this->LinkGeneratesManifest) { mtCommand.push_back(this->LinkerManifestFile); } - mtCommand.insert(mtCommand.end(), this->UserManifests.begin(), - this->UserManifests.end()); + cmAppend(mtCommand, this->UserManifests); mtCommand.push_back(out); if (notify) { // Add an undocumented option that enables a special return |