diff options
38 files changed, 292 insertions, 157 deletions
diff --git a/.clang-tidy b/.clang-tidy index cfca64e..a6378e0 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -7,15 +7,11 @@ bugprone-*,\ -bugprone-too-small-loop-variable,\ google-readability-casting,\ misc-*,\ --misc-incorrect-roundings,\ --misc-macro-parentheses,\ --misc-misplaced-widening-cast,\ -misc-non-private-member-variables-in-classes,\ -misc-static-assert,\ modernize-*,\ -modernize-avoid-c-arrays,\ -modernize-deprecated-headers,\ --modernize-return-braced-init-list,\ -modernize-use-auto,\ -modernize-use-nodiscard,\ -modernize-use-noexcept,\ @@ -24,7 +20,6 @@ performance-*,\ readability-*,\ -readability-function-size,\ -readability-identifier-naming,\ --readability-implicit-bool-cast,\ -readability-implicit-bool-conversion,\ -readability-inconsistent-declaration-parameter-name,\ -readability-magic-numbers,\ diff --git a/Help/release/dev/windows-auto-export-incremental-build.rst b/Help/release/dev/windows-auto-export-incremental-build.rst new file mode 100644 index 0000000..3126329 --- /dev/null +++ b/Help/release/dev/windows-auto-export-incremental-build.rst @@ -0,0 +1,6 @@ +windows-auto-export-incremental-build +------------------------------------- + +* On Windows, existing auto generated exports are now only updated if the + modified time stamp of the exports is not newer than any modified time stamp + of the input files. diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index b54dbd1..45dd11e 100644 --- a/Source/CMakeVersion.cmake +++ b/Source/CMakeVersion.cmake @@ -1,7 +1,7 @@ # CMake version number components. set(CMake_VERSION_MAJOR 3) set(CMake_VERSION_MINOR 15) -set(CMake_VERSION_PATCH 20190906) +set(CMake_VERSION_PATCH 20190910) #set(CMake_VERSION_RC 0) set(CMake_VERSION_IS_DIRTY 0) diff --git a/Source/cmCacheManager.cxx b/Source/cmCacheManager.cxx index cf28cdb..4c8c224 100644 --- a/Source/cmCacheManager.cxx +++ b/Source/cmCacheManager.cxx @@ -498,7 +498,7 @@ cmCacheManager::CacheEntry* cmCacheManager::GetCacheEntry( cmCacheManager::CacheIterator cmCacheManager::GetCacheIterator(const char* key) { - return CacheIterator(*this, key); + return { *this, key }; } const std::string* cmCacheManager::GetInitializedCacheValue( diff --git a/Source/cmCacheManager.h b/Source/cmCacheManager.h index a988bd8..faa60c5 100644 --- a/Source/cmCacheManager.h +++ b/Source/cmCacheManager.h @@ -94,7 +94,7 @@ public: }; //! return an iterator to iterate through the cache map - cmCacheManager::CacheIterator NewIterator() { return CacheIterator(*this); } + cmCacheManager::CacheIterator NewIterator() { return { *this }; } //! Load a cache for given makefile. Loads from path/CMakeCache.txt. bool LoadCache(const std::string& path, bool internal, diff --git a/Source/cmExportBuildFileGenerator.cxx b/Source/cmExportBuildFileGenerator.cxx index 9f0396b..e9d2412 100644 --- a/Source/cmExportBuildFileGenerator.cxx +++ b/Source/cmExportBuildFileGenerator.cxx @@ -311,7 +311,7 @@ cmExportBuildFileGenerator::FindBuildExportInfo(cmGlobalGenerator* gg, } } - return std::make_pair(exportFiles, ns); + return { exportFiles, ns }; } void cmExportBuildFileGenerator::ComplainAboutMissingTarget( diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx index e7f301e..4e3db09 100644 --- a/Source/cmExportInstallFileGenerator.cxx +++ b/Source/cmExportInstallFileGenerator.cxx @@ -496,7 +496,7 @@ cmExportInstallFileGenerator::FindNamespaces(cmGlobalGenerator* gg, } } - return std::make_pair(exportFiles, ns); + return { exportFiles, ns }; } void cmExportInstallFileGenerator::ComplainAboutMissingTarget( diff --git a/Source/cmFileLockResult.cxx b/Source/cmFileLockResult.cxx index 9ca5d8a..c4779f0 100644 --- a/Source/cmFileLockResult.cxx +++ b/Source/cmFileLockResult.cxx @@ -8,7 +8,7 @@ #define WINMSG_BUF_LEN (1024) cmFileLockResult cmFileLockResult::MakeOk() { - return cmFileLockResult(OK, 0); + return { OK, 0 }; } cmFileLockResult cmFileLockResult::MakeSystem() @@ -18,27 +18,27 @@ cmFileLockResult cmFileLockResult::MakeSystem() #else const Error lastError = errno; #endif - return cmFileLockResult(SYSTEM, lastError); + return { SYSTEM, lastError }; } cmFileLockResult cmFileLockResult::MakeTimeout() { - return cmFileLockResult(TIMEOUT, 0); + return { TIMEOUT, 0 }; } cmFileLockResult cmFileLockResult::MakeAlreadyLocked() { - return cmFileLockResult(ALREADY_LOCKED, 0); + return { ALREADY_LOCKED, 0 }; } cmFileLockResult cmFileLockResult::MakeInternal() { - return cmFileLockResult(INTERNAL, 0); + return { INTERNAL, 0 }; } cmFileLockResult cmFileLockResult::MakeNoFunction() { - return cmFileLockResult(NO_FUNCTION, 0); + return { NO_FUNCTION, 0 }; } bool cmFileLockResult::IsOk() const diff --git a/Source/cmGeneratedFileStream.cxx b/Source/cmGeneratedFileStream.cxx index 7475e9f..491d96f 100644 --- a/Source/cmGeneratedFileStream.cxx +++ b/Source/cmGeneratedFileStream.cxx @@ -4,6 +4,7 @@ #include <stdio.h> +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #if !defined(CMAKE_BOOTSTRAP) @@ -149,7 +150,7 @@ bool cmGeneratedFileStreamBase::Close() // The destination is to be replaced. Rename the temporary to the // destination atomically. if (this->Compress) { - std::string gzname = this->TempName + ".temp.gz"; + std::string gzname = cmStrCat(this->TempName, ".temp.gz"); if (this->CompressFile(this->TempName, gzname)) { this->RenameFile(gzname, resname); } diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index b4706a3..e4659b7 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -3417,8 +3417,7 @@ std::string cmGeneratorTarget::GetPchHeader(const std::string& config, file << pchEpilogue << "\n"; } } - cmSystemTools::CopyFileIfDifferent(filename_tmp, filename); - cmSystemTools::RemoveFile(filename_tmp); + cmSystemTools::MoveFileIfDifferent(filename_tmp, filename); } return inserted.first->second; } @@ -3451,8 +3450,7 @@ std::string cmGeneratorTarget::GetPchSource(const std::string& config, cmGeneratedFileStream file(filename_tmp); file << "/* generated by CMake */\n"; } - cmSystemTools::CopyFileIfDifferent(filename_tmp, filename); - cmSystemTools::RemoveFile(filename_tmp); + cmSystemTools::MoveFileIfDifferent(filename_tmp, filename); } return inserted.first->second; } @@ -4778,21 +4776,21 @@ template <> std::pair<bool, bool> consistentProperty(bool lhs, bool rhs, CompatibleType /*unused*/) { - return std::make_pair(lhs == rhs, lhs); + return { lhs == rhs, lhs }; } std::pair<bool, const char*> consistentStringProperty(const char* lhs, const char* rhs) { const bool b = strcmp(lhs, rhs) == 0; - return std::make_pair(b, b ? lhs : nullptr); + return { b, b ? lhs : nullptr }; } std::pair<bool, std::string> consistentStringProperty(const std::string& lhs, const std::string& rhs) { const bool b = lhs == rhs; - return std::make_pair(b, b ? lhs : valueAsString(nullptr)); + return { b, b ? lhs : valueAsString(nullptr) }; } std::pair<bool, const char*> consistentNumberProperty(const char* lhs, @@ -4801,22 +4799,21 @@ std::pair<bool, const char*> consistentNumberProperty(const char* lhs, { char* pEnd; - const char* const null_ptr = nullptr; - long lnum = strtol(lhs, &pEnd, 0); if (pEnd == lhs || *pEnd != '\0' || errno == ERANGE) { - return std::pair<bool, const char*>(false, null_ptr); + return { false, nullptr }; } long rnum = strtol(rhs, &pEnd, 0); if (pEnd == rhs || *pEnd != '\0' || errno == ERANGE) { - return std::pair<bool, const char*>(false, null_ptr); + return { false, nullptr }; } if (t == NumberMaxType) { - return std::make_pair(true, std::max(lnum, rnum) == lnum ? lhs : rhs); + return { true, std::max(lnum, rnum) == lnum ? lhs : rhs }; } - return std::make_pair(true, std::min(lnum, rnum) == lnum ? lhs : rhs); + + return { true, std::min(lnum, rnum) == lnum ? lhs : rhs }; } template <> @@ -4825,21 +4822,19 @@ std::pair<bool, const char*> consistentProperty(const char* lhs, CompatibleType t) { if (!lhs && !rhs) { - return std::make_pair(true, lhs); + return { true, lhs }; } if (!lhs) { - return std::make_pair(true, rhs); + return { true, rhs }; } if (!rhs) { - return std::make_pair(true, lhs); + return { true, lhs }; } - const char* const null_ptr = nullptr; - switch (t) { case BoolType: { bool same = cmIsOn(lhs) == cmIsOn(rhs); - return std::make_pair(same, same ? lhs : nullptr); + return { same, same ? lhs : nullptr }; } case StringType: return consistentStringProperty(lhs, rhs); @@ -4848,7 +4843,7 @@ std::pair<bool, const char*> consistentProperty(const char* lhs, return consistentNumberProperty(lhs, rhs, t); } assert(false && "Unreachable!"); - return std::pair<bool, const char*>(false, null_ptr); + return { false, nullptr }; } std::pair<bool, std::string> consistentProperty(const std::string& lhs, @@ -4858,31 +4853,31 @@ std::pair<bool, std::string> consistentProperty(const std::string& lhs, const std::string null_ptr = valueAsString(nullptr); if (lhs == null_ptr && rhs == null_ptr) { - return std::make_pair(true, lhs); + return { true, lhs }; } if (lhs == null_ptr) { - return std::make_pair(true, rhs); + return { true, rhs }; } if (rhs == null_ptr) { - return std::make_pair(true, lhs); + return { true, lhs }; } switch (t) { case BoolType: { bool same = cmIsOn(lhs) == cmIsOn(rhs); - return std::make_pair(same, same ? lhs : null_ptr); + return { same, same ? lhs : null_ptr }; } case StringType: return consistentStringProperty(lhs, rhs); case NumberMinType: case NumberMaxType: { auto value = consistentNumberProperty(lhs.c_str(), rhs.c_str(), t); - return std::make_pair( - value.first, value.first ? std::string(value.second) : null_ptr); + return { value.first, + value.first ? std::string(value.second) : null_ptr }; } } assert(false && "Unreachable!"); - return std::pair<bool, std::string>(false, null_ptr); + return { false, null_ptr }; } template <typename PropertyType> diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h index f6d5998..7aa231e 100644 --- a/Source/cmGlobalNinjaGenerator.h +++ b/Source/cmGlobalNinjaGenerator.h @@ -228,7 +228,7 @@ public: return this->GG->ConvertToNinjaPath(path); } }; - MapToNinjaPathImpl MapToNinjaPath() { return MapToNinjaPathImpl(this); } + MapToNinjaPathImpl MapToNinjaPath() { return { this }; } // -- Additional clean files void AddAdditionalCleanFile(std::string fileName); diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index 10f822f..3dae824 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -1254,7 +1254,7 @@ bool cmGlobalXCodeGenerator::CreateXCodeTarget( bundleFiles[tsFlags.MacFolder].push_back(sourceFile); } } - for (auto keySources : bundleFiles) { + for (auto const& keySources : bundleFiles) { cmXCodeObject* copyFilesBuildPhase = this->CreateObject(cmXCodeObject::PBXCopyFilesBuildPhase); copyFilesBuildPhase->SetComment("Copy files"); @@ -1302,7 +1302,7 @@ bool cmGlobalXCodeGenerator::CreateXCodeTarget( bundleFiles[tsFlags.MacFolder].push_back(sourceFile); } } - for (auto keySources : bundleFiles) { + for (auto const& keySources : bundleFiles) { cmXCodeObject* copyFilesBuildPhase = this->CreateObject(cmXCodeObject::PBXCopyFilesBuildPhase); copyFilesBuildPhase->SetComment("Copy files"); @@ -1433,7 +1433,7 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateBuildPhase( void cmGlobalXCodeGenerator::CreateCustomCommands( cmXCodeObject* buildPhases, cmXCodeObject* sourceBuildPhase, cmXCodeObject* headerBuildPhase, cmXCodeObject* resourceBuildPhase, - std::vector<cmXCodeObject*> contentBuildPhases, + std::vector<cmXCodeObject*> const& contentBuildPhases, cmXCodeObject* frameworkBuildPhase, cmGeneratorTarget* gtgt) { std::vector<cmCustomCommand> const& prebuild = gtgt->GetPreBuildCommands(); diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h index 71446f9..af905d0 100644 --- a/Source/cmGlobalXCodeGenerator.h +++ b/Source/cmGlobalXCodeGenerator.h @@ -122,13 +122,11 @@ private: std::string RelativeToSource(const std::string& p); std::string RelativeToBinary(const std::string& p); std::string ConvertToRelativeForMake(std::string const& p); - void CreateCustomCommands(cmXCodeObject* buildPhases, - cmXCodeObject* sourceBuildPhase, - cmXCodeObject* headerBuildPhase, - cmXCodeObject* resourceBuildPhase, - std::vector<cmXCodeObject*> contentBuildPhases, - cmXCodeObject* frameworkBuildPhase, - cmGeneratorTarget* gtgt); + void CreateCustomCommands( + cmXCodeObject* buildPhases, cmXCodeObject* sourceBuildPhase, + cmXCodeObject* headerBuildPhase, cmXCodeObject* resourceBuildPhase, + std::vector<cmXCodeObject*> const& contentBuildPhases, + cmXCodeObject* frameworkBuildPhase, cmGeneratorTarget* gtgt); std::string ComputeInfoPListLocation(cmGeneratorTarget* target); diff --git a/Source/cmLinkLineDeviceComputer.cxx b/Source/cmLinkLineDeviceComputer.cxx index 9c0e20f..1a602ca 100644 --- a/Source/cmLinkLineDeviceComputer.cxx +++ b/Source/cmLinkLineDeviceComputer.cxx @@ -82,6 +82,9 @@ std::string cmLinkLineDeviceComputer::ComputeLinkLibraries( ItemVector const& items = cli.GetItems(); std::string config = cli.GetConfig(); bool skipItemAfterFramework = false; + // Note: + // Any modification of this algorithm should be reflected also in + // cmVisualStudio10TargetGenerator::ComputeCudaLinkOptions for (auto const& item : items) { if (skipItemAfterFramework) { skipItemAfterFramework = false; @@ -91,6 +94,7 @@ std::string cmLinkLineDeviceComputer::ComputeLinkLibraries( if (item.Target) { bool skip = false; switch (item.Target->GetType()) { + case cmStateEnums::SHARED_LIBRARY: case cmStateEnums::MODULE_LIBRARY: case cmStateEnums::INTERFACE_LIBRARY: skip = true; diff --git a/Source/cmListFileCache.cxx b/Source/cmListFileCache.cxx index ff3ecd9..349d5e9 100644 --- a/Source/cmListFileCache.cxx +++ b/Source/cmListFileCache.cxx @@ -326,6 +326,7 @@ cmListFileBacktrace::cmListFileBacktrace(cmStateSnapshot const& snapshot) { } +/* NOLINTNEXTLINE(performance-unnecessary-value-param) */ cmListFileBacktrace::cmListFileBacktrace(std::shared_ptr<Entry const> parent, cmListFileContext const& lfc) : TopEntry(std::make_shared<Entry const>(std::move(parent), lfc)) diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 9152e94..8bb3bc1 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -14,6 +14,7 @@ #include "cmInstallScriptGenerator.h" #include "cmInstallTargetGenerator.h" #include "cmLinkLineComputer.h" +#include "cmLinkLineDeviceComputer.h" #include "cmMakefile.h" #include "cmRulePlaceholderExpander.h" #include "cmSourceFile.h" @@ -1153,6 +1154,12 @@ void cmLocalGenerator::GetTargetFlags( switch (target->GetType()) { case cmStateEnums::STATIC_LIBRARY: this->GetStaticLibraryFlags(linkFlags, buildType, linkLanguage, target); + if (pcli && dynamic_cast<cmLinkLineDeviceComputer*>(linkLineComputer)) { + // Compute the required cuda device link libraries when + // resolving cuda device symbols + this->OutputLinkLibraries(pcli, linkLineComputer, linkLibs, + frameworkPath, linkPath); + } break; case cmStateEnums::MODULE_LIBRARY: libraryLinkVariable = "CMAKE_MODULE_LINKER_FLAGS"; @@ -2089,12 +2096,11 @@ void cmLocalGenerator::AddConfigVariableFlags(std::string& flags, const std::string& config) { // Add the flags from the variable itself. - std::string flagsVar = var; - this->AppendFlags(flags, this->Makefile->GetSafeDefinition(flagsVar)); + this->AppendFlags(flags, this->Makefile->GetSafeDefinition(var)); // Add the flags from the build-type specific variable. if (!config.empty()) { - flagsVar += "_"; - flagsVar += cmSystemTools::UpperCase(config); + const std::string flagsVar = + cmStrCat(var, '_', cmSystemTools::UpperCase(config)); this->AppendFlags(flags, this->Makefile->GetSafeDefinition(flagsVar)); } } @@ -2275,8 +2281,7 @@ void cmLocalGenerator::AddUnityBuild(cmGeneratorTarget* target, } } } - cmSystemTools::CopyFileIfDifferent(filename_tmp, filename); - cmSystemTools::RemoveFile(filename_tmp); + cmSystemTools::MoveFileIfDifferent(filename_tmp, filename); target->AddSource(filename, true); diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx index d603dac..36f6809 100644 --- a/Source/cmMakefileLibraryTargetGenerator.cxx +++ b/Source/cmMakefileLibraryTargetGenerator.cxx @@ -301,19 +301,16 @@ void cmMakefileLibraryTargetGenerator::WriteDeviceLibraryRules( // Collect up flags to link in needed libraries. std::string linkLibs; - if (this->GeneratorTarget->GetType() != cmStateEnums::STATIC_LIBRARY) { - - std::unique_ptr<cmLinkLineComputer> linkLineComputer( - new cmLinkLineDeviceComputer( - this->LocalGenerator, - this->LocalGenerator->GetStateSnapshot().GetDirectory())); - linkLineComputer->SetForResponse(useResponseFileForLibs); - linkLineComputer->SetUseWatcomQuote(useWatcomQuote); - linkLineComputer->SetRelink(relink); - - this->CreateLinkLibs(linkLineComputer.get(), linkLibs, - useResponseFileForLibs, depends); - } + std::unique_ptr<cmLinkLineComputer> linkLineComputer( + new cmLinkLineDeviceComputer( + this->LocalGenerator, + this->LocalGenerator->GetStateSnapshot().GetDirectory())); + linkLineComputer->SetForResponse(useResponseFileForLibs); + linkLineComputer->SetUseWatcomQuote(useWatcomQuote); + linkLineComputer->SetRelink(relink); + + this->CreateLinkLibs(linkLineComputer.get(), linkLibs, + useResponseFileForLibs, depends); // Construct object file lists that may be needed to expand the // rule. diff --git a/Source/cmScriptGenerator.h b/Source/cmScriptGenerator.h index eee331f..c8bb1ab 100644 --- a/Source/cmScriptGenerator.h +++ b/Source/cmScriptGenerator.h @@ -25,7 +25,7 @@ public: } cmScriptGeneratorIndent Next(int step = 2) const { - return cmScriptGeneratorIndent(this->Level + step); + return { this->Level + step }; } private: diff --git a/Source/cmServerProtocol.cxx b/Source/cmServerProtocol.cxx index 670161d..d576f36 100644 --- a/Source/cmServerProtocol.cxx +++ b/Source/cmServerProtocol.cxx @@ -167,7 +167,7 @@ bool cmServerProtocol::DoActivate(const cmServerRequest& /*request*/, std::pair<int, int> cmServerProtocol1::ProtocolVersion() const { - return std::make_pair(1, 2); + return { 1, 2 }; } static void setErrorMessage(std::string* errorMessage, const std::string& text) diff --git a/Source/cmState.cxx b/Source/cmState.cxx index 902287c..92d17ab 100644 --- a/Source/cmState.cxx +++ b/Source/cmState.cxx @@ -324,7 +324,7 @@ cmStateSnapshot cmState::Reset() this->DefineProperty("RULE_LAUNCH_LINK", cmProperty::TARGET, "", "", true); this->DefineProperty("RULE_LAUNCH_CUSTOM", cmProperty::TARGET, "", "", true); - return cmStateSnapshot(this, pos); + return { this, pos }; } void cmState::DefineProperty(const std::string& name, @@ -789,7 +789,7 @@ cmStateSnapshot cmState::CreateBaseSnapshot() assert(pos->Vars.IsValid()); pos->Parent = this->VarTree.Root(); pos->Root = this->VarTree.Root(); - return cmStateSnapshot(this, pos); + return { this, pos }; } cmStateSnapshot cmState::CreateBuildsystemDirectorySnapshot( @@ -842,7 +842,7 @@ cmStateSnapshot cmState::CreateFunctionCallSnapshot( cmLinkedTree<cmDefinitions>::iterator origin = originSnapshot.Position->Vars; pos->Parent = origin; pos->Vars = this->VarTree.Push(origin); - return cmStateSnapshot(this, pos); + return { this, pos }; } cmStateSnapshot cmState::CreateMacroCallSnapshot( @@ -857,7 +857,7 @@ cmStateSnapshot cmState::CreateMacroCallSnapshot( assert(originSnapshot.Position->Vars.IsValid()); pos->BuildSystemDirectory->DirectoryEnd = pos; pos->PolicyScope = originSnapshot.Position->Policies; - return cmStateSnapshot(this, pos); + return { this, pos }; } cmStateSnapshot cmState::CreateIncludeFileSnapshot( @@ -872,7 +872,7 @@ cmStateSnapshot cmState::CreateIncludeFileSnapshot( assert(originSnapshot.Position->Vars.IsValid()); pos->BuildSystemDirectory->DirectoryEnd = pos; pos->PolicyScope = originSnapshot.Position->Policies; - return cmStateSnapshot(this, pos); + return { this, pos }; } cmStateSnapshot cmState::CreateVariableScopeSnapshot( @@ -890,7 +890,7 @@ cmStateSnapshot cmState::CreateVariableScopeSnapshot( pos->Parent = origin; pos->Vars = this->VarTree.Push(origin); assert(pos->Vars.IsValid()); - return cmStateSnapshot(this, pos); + return { this, pos }; } cmStateSnapshot cmState::CreateInlineListFileSnapshot( @@ -904,7 +904,7 @@ cmStateSnapshot cmState::CreateInlineListFileSnapshot( originSnapshot.Position->ExecutionListFile, fileName); pos->BuildSystemDirectory->DirectoryEnd = pos; pos->PolicyScope = originSnapshot.Position->Policies; - return cmStateSnapshot(this, pos); + return { this, pos }; } cmStateSnapshot cmState::CreatePolicyScopeSnapshot( @@ -916,7 +916,7 @@ cmStateSnapshot cmState::CreatePolicyScopeSnapshot( pos->Keep = false; pos->BuildSystemDirectory->DirectoryEnd = pos; pos->PolicyScope = originSnapshot.Position->Policies; - return cmStateSnapshot(this, pos); + return { this, pos }; } cmStateSnapshot cmState::Pop(cmStateSnapshot const& originSnapshot) @@ -948,7 +948,7 @@ cmStateSnapshot cmState::Pop(cmStateSnapshot const& originSnapshot) this->SnapshotData.Pop(pos); } - return cmStateSnapshot(this, prevPos); + return { this, prevPos }; } static bool ParseEntryWithoutType(const std::string& entry, std::string& var, diff --git a/Source/cmStateSnapshot.cxx b/Source/cmStateSnapshot.cxx index 121923d..3c54f52 100644 --- a/Source/cmStateSnapshot.cxx +++ b/Source/cmStateSnapshot.cxx @@ -66,8 +66,7 @@ bool cmStateSnapshot::IsValid() const cmStateSnapshot cmStateSnapshot::GetBuildsystemDirectory() const { - return cmStateSnapshot(this->State, - this->Position->BuildSystemDirectory->DirectoryEnd); + return { this->State, this->Position->BuildSystemDirectory->DirectoryEnd }; } cmStateSnapshot cmStateSnapshot::GetBuildsystemDirectoryParent() const @@ -126,7 +125,7 @@ cmStateSnapshot cmStateSnapshot::GetCallStackBottom() const pos != this->State->SnapshotData.Root()) { ++pos; } - return cmStateSnapshot(this->State, pos); + return { this->State, pos }; } void cmStateSnapshot::PushPolicy(cmPolicies::PolicyMap const& entry, bool weak) @@ -426,7 +425,7 @@ cmState* cmStateSnapshot::GetState() const cmStateDirectory cmStateSnapshot::GetDirectory() const { - return cmStateDirectory(this->Position->BuildSystemDirectory, *this); + return { this->Position->BuildSystemDirectory, *this }; } void cmStateSnapshot::SetProjectName(const std::string& name) diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index b7287d9..074faa5 100644 --- a/Source/cmSystemTools.cxx +++ b/Source/cmSystemTools.cxx @@ -855,6 +855,18 @@ bool cmSystemTools::RenameFile(const std::string& oldname, #endif } +void cmSystemTools::MoveFileIfDifferent(const std::string& source, + const std::string& destination) +{ + if (FilesDiffer(source, destination)) { + if (RenameFile(source, destination)) { + return; + } + CopyFileAlways(source, destination); + } + RemoveFile(source); +} + std::string cmSystemTools::ComputeFileHash(const std::string& source, cmCryptoHash::Algo algo) { diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h index 863db3f..8ca4939 100644 --- a/Source/cmSystemTools.h +++ b/Source/cmSystemTools.h @@ -131,6 +131,10 @@ public: static bool RenameFile(const std::string& oldname, const std::string& newname); + //! Rename a file if contents are different, delete the source otherwise + static void MoveFileIfDifferent(const std::string& source, + const std::string& destination); + //! Compute the hash of a file static std::string ComputeFileHash(const std::string& source, cmCryptoHash::Algo algo); diff --git a/Source/cmUseMangledMesaCommand.cxx b/Source/cmUseMangledMesaCommand.cxx index cfc00e8..1fd386b 100644 --- a/Source/cmUseMangledMesaCommand.cxx +++ b/Source/cmUseMangledMesaCommand.cxx @@ -98,7 +98,6 @@ void CopyAndFullPathMesaHeader(const std::string& source, // close the files before attempting to copy fin.close(); fout.close(); - cmSystemTools::CopyFileIfDifferent(tempOutputFile, outFile); - cmSystemTools::RemoveFile(tempOutputFile); + cmSystemTools::MoveFileIfDifferent(tempOutputFile, outFile); } } diff --git a/Source/cmVariableWatchCommand.cxx b/Source/cmVariableWatchCommand.cxx index db23efd..f9f7d66 100644 --- a/Source/cmVariableWatchCommand.cxx +++ b/Source/cmVariableWatchCommand.cxx @@ -91,6 +91,7 @@ static void deleteVariableWatchCallbackData(void* client_data) class FinalAction { public: + /* NOLINTNEXTLINE(performance-unnecessary-value-param) */ FinalAction(cmMakefile* makefile, std::string variable) : Action(std::make_shared<Impl>(makefile, std::move(variable))) { diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 5e92622..ba72294 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -3152,6 +3152,82 @@ bool cmVisualStudio10TargetGenerator::ComputeCudaLinkOptions( "-Wno-deprecated-gpu-targets"); } + // For static libraries that have device linking enabled compute + // the libraries + if (this->GeneratorTarget->GetType() == cmStateEnums::STATIC_LIBRARY && + doDeviceLinking) { + cmComputeLinkInformation* pcli = + this->GeneratorTarget->GetLinkInformation(configName); + if (!pcli) { + cmSystemTools::Error( + "CMake can not compute cmComputeLinkInformation for target: " + + this->Name); + return false; + } + + // Would like to use: + // cmLinkLineDeviceComputer computer(this->LocalGenerator, + // this->LocalGenerator->GetStateSnapshot().GetDirectory()); + // std::string computed_libs = computer.ComputeLinkLibraries(cli, + // std::string{}); but it outputs in "<libA> <libB>" format instead of + // "<libA>;<libB>" + // Note: + // Any modification of this algorithm should be reflected also in + // cmLinkLineDeviceComputer + cmComputeLinkInformation& cli = *pcli; + std::vector<std::string> libVec; + const std::string currentBinDir = + this->LocalGenerator->GetCurrentBinaryDirectory(); + const auto& libs = cli.GetItems(); + for (cmComputeLinkInformation::Item const& l : libs) { + + if (l.Target) { + auto managedType = l.Target->GetManagedType(configName); + // Do not allow C# targets to be added to the LIB listing. LIB files + // are used for linking C++ dependencies. C# libraries do not have lib + // files. Instead, they compile down to C# reference libraries (DLL + // files). The + // `<ProjectReference>` elements added to the vcxproj are enough for + // the IDE to deduce the DLL file required by other C# projects that + // need its reference library. + if (managedType == cmGeneratorTarget::ManagedType::Managed) { + continue; + } + const auto type = l.Target->GetType(); + + bool skip = false; + switch (type) { + case cmStateEnums::SHARED_LIBRARY: + case cmStateEnums::MODULE_LIBRARY: + case cmStateEnums::INTERFACE_LIBRARY: + skip = true; + break; + case cmStateEnums::STATIC_LIBRARY: + skip = l.Target->GetPropertyAsBool("CUDA_RESOLVE_DEVICE_SYMBOLS"); + break; + default: + break; + } + if (skip) { + continue; + } + } + + if (l.IsPath) { + std::string path = this->LocalGenerator->MaybeConvertToRelativePath( + currentBinDir, l.Value); + ConvertToWindowsSlash(path); + if (!cmVS10IsTargetsFile(l.Value)) { + libVec.push_back(path); + } + } else { + libVec.push_back(l.Value); + } + } + + cudaLinkOptions.AddFlag("AdditionalDependencies", libVec); + } + this->CudaLinkOptions[configName] = std::move(pOptions); return true; } diff --git a/Source/cmXMLWriter.h b/Source/cmXMLWriter.h index a5b06af..c4103cc 100644 --- a/Source/cmXMLWriter.h +++ b/Source/cmXMLWriter.h @@ -77,14 +77,11 @@ private: void CloseStartElement(); private: - static cmXMLSafe SafeAttribute(const char* value) - { - return cmXMLSafe(value); - } + static cmXMLSafe SafeAttribute(const char* value) { return { value }; } static cmXMLSafe SafeAttribute(std::string const& value) { - return cmXMLSafe(value); + return { value }; } template <typename T> diff --git a/Source/cmake.cxx b/Source/cmake.cxx index ace9198..e7c714e 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -1081,20 +1081,18 @@ createExtraGenerator( const std::vector<std::string> generators = i->GetSupportedGlobalGenerators(); if (i->GetName() == name) { // Match aliases - return std::make_pair(i->CreateExternalMakefileProjectGenerator(), - generators.at(0)); + return { i->CreateExternalMakefileProjectGenerator(), generators.at(0) }; } for (std::string const& g : generators) { const std::string fullName = cmExternalMakefileProjectGenerator::CreateFullGeneratorName( g, i->GetName()); if (fullName == name) { - return std::make_pair(i->CreateExternalMakefileProjectGenerator(), g); + return { i->CreateExternalMakefileProjectGenerator(), g }; } } } - return std::make_pair( - static_cast<cmExternalMakefileProjectGenerator*>(nullptr), name); + return { nullptr, name }; } cmGlobalGenerator* cmake::CreateGlobalGenerator(const std::string& gname) diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx index a79a2ff..e6dd99a 100644 --- a/Source/cmcmd.cxx +++ b/Source/cmcmd.cxx @@ -562,19 +562,36 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args) "objlistfile [-nm=nm-path]\n"; return 1; } - FILE* fout = cmsys::SystemTools::Fopen(args[2].c_str(), "w+"); - if (!fout) { - std::cerr << "could not open output .def file: " << args[2].c_str() - << "\n"; - return 1; - } cmsys::ifstream fin(args[3].c_str(), std::ios::in | std::ios::binary); if (!fin) { std::cerr << "could not open object list file: " << args[3].c_str() << "\n"; return 1; } - std::string file; + std::vector<std::string> files; + { + std::string file; + cmFileTime outTime; + bool outValid = outTime.Load(args[2]); + while (cmSystemTools::GetLineFromStream(fin, file)) { + files.push_back(file); + if (outValid) { + cmFileTime inTime; + outValid = inTime.Load(file) && inTime.Older(outTime); + } + } + if (outValid) { + // The def file already exists and all input files are older than the + // existing def file. + return 0; + } + } + FILE* fout = cmsys::SystemTools::Fopen(args[2].c_str(), "w+"); + if (!fout) { + std::cerr << "could not open output .def file: " << args[2].c_str() + << "\n"; + return 1; + } bindexplib deffile; if (args.size() >= 5) { auto a = args[4]; @@ -585,7 +602,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args) std::cerr << "unknown argument: " << a << "\n"; } } - while (cmSystemTools::GetLineFromStream(fin, file)) { + for (auto const& file : files) { std::string const& ext = cmSystemTools::GetFilenameLastExtension(file); if (cmSystemTools::LowerCase(ext) == ".def") { if (!deffile.AddDefinitionFile(file.c_str())) { diff --git a/Tests/CMakeLib/testUVProcessChainHelper.cxx b/Tests/CMakeLib/testUVProcessChainHelper.cxx index 263665d..a77ec90 100644 --- a/Tests/CMakeLib/testUVProcessChainHelper.cxx +++ b/Tests/CMakeLib/testUVProcessChainHelper.cxx @@ -44,7 +44,7 @@ int main(int argc, char** argv) } if (command == "dedup") { // Use a nested scope to free all resources before aborting below. - { + try { std::string input = getStdin(); std::set<char> seen; std::string output; @@ -56,6 +56,7 @@ int main(int argc, char** argv) } std::cout << output << std::flush; std::cerr << "3" << std::flush; + } catch (...) { } // On Windows, the exit code of abort() is different between debug and diff --git a/Tests/CudaOnly/ResolveDeviceSymbols/CMakeLists.txt b/Tests/CudaOnly/ResolveDeviceSymbols/CMakeLists.txt index 796e133..64845c5 100644 --- a/Tests/CudaOnly/ResolveDeviceSymbols/CMakeLists.txt +++ b/Tests/CudaOnly/ResolveDeviceSymbols/CMakeLists.txt @@ -16,21 +16,29 @@ else() endif() #Goal for this example: -# Build a static library that defines multiple methods and kernels that -# use each other. -# Resolve the device symbols into that static library -# Verify that we can't use those device symbols from anything that links +# 1. Build two static libraries that defines multiple methods and kernels +# 2. Resolve the device symbols into the second static library, therefore +# confirming that the first static library is on the device link line +# 3. Verify that we can't use those device symbols from anything that links # to the static library -string(APPEND CMAKE_CUDA_FLAGS " -gencode arch=compute_30,code=[compute_30] -gencode arch=compute_50,code=\\\"compute_50\\\"") +string(APPEND CMAKE_CUDA_FLAGS " -gencode arch=compute_30,code=[sm_30] -gencode arch=compute_50,code=\\\"compute_50\\\"") set(CMAKE_CXX_STANDARD 11) set(CMAKE_CUDA_STANDARD 11) -add_library(CUDAResolveDeviceLib STATIC file1.cu file2.cu) +add_library(CUDAResolveDeviceDepsA STATIC file1.cu) +add_library(CUDAResolveDeviceDepsB STATIC file2.cu) +set_target_properties(CUDAResolveDeviceDepsA CUDAResolveDeviceDepsB + PROPERTIES + CUDA_SEPARABLE_COMPILATION ON + POSITION_INDEPENDENT_CODE ON) + +add_library(CUDAResolveDeviceLib STATIC file2_launch.cu) set_target_properties(CUDAResolveDeviceLib PROPERTIES CUDA_SEPARABLE_COMPILATION ON CUDA_RESOLVE_DEVICE_SYMBOLS ON POSITION_INDEPENDENT_CODE ON) +target_link_libraries(CUDAResolveDeviceLib PRIVATE CUDAResolveDeviceDepsA CUDAResolveDeviceDepsB) if(dump_command) add_custom_command(TARGET CUDAResolveDeviceLib POST_BUILD @@ -45,7 +53,8 @@ endif() add_executable(CudaOnlyResolveDeviceSymbols main.cu) set_target_properties(CudaOnlyResolveDeviceSymbols PROPERTIES - CUDA_SEPARABLE_COMPILATION ON) + CUDA_SEPARABLE_COMPILATION OFF + CUDA_RESOLVE_DEVICE_SYMBOLS OFF) target_link_libraries(CudaOnlyResolveDeviceSymbols PRIVATE CUDAResolveDeviceLib) diff --git a/Tests/CudaOnly/ResolveDeviceSymbols/file1.h b/Tests/CudaOnly/ResolveDeviceSymbols/file1.h index ff1945c..b33bcae 100644 --- a/Tests/CudaOnly/ResolveDeviceSymbols/file1.h +++ b/Tests/CudaOnly/ResolveDeviceSymbols/file1.h @@ -1,7 +1,10 @@ #pragma once + struct result_type { int input; int sum; }; + +result_type __device__ file1_func(int x); diff --git a/Tests/CudaOnly/ResolveDeviceSymbols/file2.cu b/Tests/CudaOnly/ResolveDeviceSymbols/file2.cu index 278fd6c..0e5e7aa 100644 --- a/Tests/CudaOnly/ResolveDeviceSymbols/file2.cu +++ b/Tests/CudaOnly/ResolveDeviceSymbols/file2.cu @@ -1,25 +1,9 @@ #include "file2.h" -result_type __device__ file1_func(int x); - result_type_dynamic __device__ file2_func(int x) { const result_type r = file1_func(x); const result_type_dynamic rd{ r.input, r.sum, true }; return rd; } - -static __global__ void file2_kernel(result_type_dynamic& r, int x) -{ - // call static_func which is a method that is defined in the - // static library that is always out of date - r = file2_func(x); -} - -int file2_launch_kernel(int x) -{ - result_type_dynamic r; - file2_kernel<<<1, 1>>>(r, x); - return r.sum; -} diff --git a/Tests/CudaOnly/ResolveDeviceSymbols/file2.h b/Tests/CudaOnly/ResolveDeviceSymbols/file2.h index d2dbaa4..c6e2875 100644 --- a/Tests/CudaOnly/ResolveDeviceSymbols/file2.h +++ b/Tests/CudaOnly/ResolveDeviceSymbols/file2.h @@ -8,3 +8,5 @@ struct result_type_dynamic int sum; bool from_static; }; + +result_type_dynamic __device__ file2_func(int x); diff --git a/Tests/CudaOnly/ResolveDeviceSymbols/file2_launch.cu b/Tests/CudaOnly/ResolveDeviceSymbols/file2_launch.cu new file mode 100644 index 0000000..4e8da13 --- /dev/null +++ b/Tests/CudaOnly/ResolveDeviceSymbols/file2_launch.cu @@ -0,0 +1,18 @@ + +#include "file2.h" + +static __global__ void file2_kernel(result_type_dynamic& r, int x) +{ + // call static_func which is a method that is defined in the + // static library that is always out of date + r = file2_func(x); +} + +static __global__ void file2_kernel(result_type_dynamic& r, int x); + +int file2_launch_kernel(int x) +{ + result_type_dynamic r; + file2_kernel<<<1, 1>>>(r, x); + return r.sum; +} diff --git a/Tests/CudaOnly/ResolveDeviceSymbols/main.cu b/Tests/CudaOnly/ResolveDeviceSymbols/main.cu index d464f96..ea842cc 100644 --- a/Tests/CudaOnly/ResolveDeviceSymbols/main.cu +++ b/Tests/CudaOnly/ResolveDeviceSymbols/main.cu @@ -1,26 +1,10 @@ #include <iostream> -#include "file1.h" #include "file2.h" int file2_launch_kernel(int x); -result_type_dynamic __device__ file2_func(int x); -static __global__ void main_kernel(result_type_dynamic& r, int x) -{ - // call function that was not device linked to us, this will cause - // a runtime failure of "invalid device function" - r = file2_func(x); -} - -int main_launch_kernel(int x) -{ - result_type_dynamic r; - main_kernel<<<1, 1>>>(r, x); - return r.sum; -} - int choose_cuda_device() { int nDevices = 0; @@ -62,12 +46,10 @@ int main(int argc, char** argv) return 0; } - main_launch_kernel(1); + file2_launch_kernel(1); cudaError_t err = cudaGetLastError(); - if (err == cudaSuccess) { - // This kernel launch should fail as the file2_func was device linked - // into the static library and is not usable by the executable - std::cerr << "main_launch_kernel: kernel launch should have failed" + if (err != cudaSuccess) { + std::cerr << "file2_launch_kernel: kernel launch should have passed" << std::endl; return 1; } diff --git a/Tests/RunCMake/AutoExportDll/RunCMakeTest.cmake b/Tests/RunCMake/AutoExportDll/RunCMakeTest.cmake index 27a609d..6c9be4b 100644 --- a/Tests/RunCMake/AutoExportDll/RunCMakeTest.cmake +++ b/Tests/RunCMake/AutoExportDll/RunCMakeTest.cmake @@ -7,9 +7,13 @@ file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}") run_cmake(AutoExport) unset(RunCMake_TEST_OPTIONS) # don't run this test on Watcom or Borland make as it is not supported -if("${RunCMake_GENERATOR}" MATCHES "Watcom WMake|Borland Makefiles") +if(RunCMake_GENERATOR MATCHES "Watcom WMake|Borland Makefiles") return() endif() +if(RunCMake_GENERATOR MATCHES "Ninja|Visual Studio" AND + CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") + set(EXPORTS TRUE) +endif() # we build debug so the say.exe will be found in Debug/say.exe for # Visual Studio generators if(RunCMake_GENERATOR_IS_MULTI_CONFIG) @@ -18,9 +22,36 @@ endif() # build AutoExport run_cmake_command(AutoExportBuild ${CMAKE_COMMAND} --build ${RunCMake_TEST_BINARY_DIR} --config Debug --clean-first) +# save the current timestamp of exports.def +if(EXPORTS) + set(EXPORTS_DEF "${RunCMake_TEST_BINARY_DIR}/say.dir/${INTDIR}exports.def") + if(NOT EXISTS "${EXPORTS_DEF}") + set(EXPORTS_DEF + "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/say.dir/${INTDIR}exports.def") + endif() + file(TIMESTAMP "${EXPORTS_DEF}" timestamp) + if(NOT timestamp) + message(SEND_ERROR "Could not get timestamp for \"${EXPORTS_DEF}\"") + endif() +endif() # run the executable that uses symbols from the dll if(WIN32) set(EXE_EXT ".exe") endif() run_cmake_command(AutoExportRun - ${RunCMake_BINARY_DIR}/AutoExport-build/bin/${INTDIR}say${EXE_EXT}) + ${RunCMake_TEST_BINARY_DIR}/bin/${INTDIR}say${EXE_EXT}) +# build AutoExport again without modification +run_cmake_command(AutoExportBuildAgain ${CMAKE_COMMAND} --build + ${RunCMake_TEST_BINARY_DIR} --config Debug) +# compare timestamps of exports.def to make sure it has not been updated +if(EXPORTS) + file(TIMESTAMP "${EXPORTS_DEF}" timestamp_after) + if(NOT timestamp_after) + message(SEND_ERROR "Could not get timestamp for \"${EXPORTS_DEF}\"") + endif() + if (timestamp_after STREQUAL timestamp) + message(STATUS "AutoExportTimeStamp - PASSED") + else() + message(SEND_ERROR "\"${EXPORTS_DEF}\" has been updated.") + endif() +endif() diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index 8fd5234..c663484 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -543,7 +543,7 @@ set(cpack_tests add_RunCMake_test_group(CPack "${cpack_tests}") # add a test to make sure symbols are exported from a shared library # for MSVC compilers CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS property is used -add_RunCMake_test(AutoExportDll) +add_RunCMake_test(AutoExportDll -DCMAKE_CXX_COMPILER_ID=${CMAKE_CXX_COMPILER_ID}) add_RunCMake_test(AndroidMK) |