diff options
35 files changed, 466 insertions, 274 deletions
diff --git a/Help/command/ctest_submit.rst b/Help/command/ctest_submit.rst index cc9612b..a412792 100644 --- a/Help/command/ctest_submit.rst +++ b/Help/command/ctest_submit.rst @@ -65,6 +65,7 @@ Submit to CDash Upload API [HTTPHEADER <header>] [RETRY_COUNT <count>] [RETRY_DELAY <delay>] + [RETURN_VALUE <result-var>] [QUIET]) This second signature is used to upload files to CDash via the CDash @@ -73,5 +74,5 @@ with a content hash of the file. If CDash does not already have the file, then it is uploaded. Along with the file, a CDash type string is specified to tell CDash which handler to use to process the data. -This signature accepts the ``HTTPHEADER``, ``RETRY_COUNT``, ``RETRY_DELAY``, and -``QUIET`` options as described above. +This signature accepts the ``HTTPHEADER``, ``RETRY_COUNT``, ``RETRY_DELAY``, +``RETURN_VALUE`` and ``QUIET`` options as described above. diff --git a/Help/command/include_directories.rst b/Help/command/include_directories.rst index f694934..e797b5d 100644 --- a/Help/command/include_directories.rst +++ b/Help/command/include_directories.rst @@ -33,3 +33,9 @@ Arguments to ``include_directories`` may use "generator expressions" with the syntax "$<...>". See the :manual:`cmake-generator-expressions(7)` manual for available expressions. See the :manual:`cmake-buildsystem(7)` manual for more on defining buildsystem properties. + +.. note:: + + Prefer the :command:`target_include_directories` command to add include + directories to individual targets and optionally propagate/export them + to dependents. diff --git a/Help/command/unset.rst b/Help/command/unset.rst index a1fc95c..c19dd31 100644 --- a/Help/command/unset.rst +++ b/Help/command/unset.rst @@ -7,9 +7,16 @@ Unset a variable, cache variable, or environment variable. unset(<variable> [CACHE | PARENT_SCOPE]) -Removes the specified variable causing it to become undefined. If -``CACHE`` is present then the variable is removed from the cache instead -of the current scope. +Removes a normal variable from the current scope, causing it +to become undefined. If ``CACHE`` is present, then a cache variable +is removed instead of a normal variable. Note that when evaluating +:ref:`Variable References` of the form ``${VAR}``, CMake first searches +for a normal variable with that name. If no such normal variable exists, +CMake will then search for a cache entry with that name. Because of this +unsetting a normal variable can expose a cache variable that was previously +hidden. To force a variable reference of the form ``${VAR}`` to return an +empty string, use ``set(<variable> "")``, which clears the normal variable +but leaves it defined. If ``PARENT_SCOPE`` is present then the variable is removed from the scope above the current scope. See the same option in the :command:`set` command diff --git a/Help/variable/CMAKE_LANG_CLANG_TIDY.rst b/Help/variable/CMAKE_LANG_CLANG_TIDY.rst index d1fccbb..bd49de3 100644 --- a/Help/variable/CMAKE_LANG_CLANG_TIDY.rst +++ b/Help/variable/CMAKE_LANG_CLANG_TIDY.rst @@ -9,5 +9,5 @@ created. For example: .. code-block:: cmake - set(CMAKE_CXX_CLANG_TIDY clang-tidy checks=-*,readability-*) + set(CMAKE_CXX_CLANG_TIDY clang-tidy -checks=-*,readability-*) add_executable(foo foo.cxx) diff --git a/Modules/CMakeCUDAInformation.cmake b/Modules/CMakeCUDAInformation.cmake index 8e62941..43ae989 100644 --- a/Modules/CMakeCUDAInformation.cmake +++ b/Modules/CMakeCUDAInformation.cmake @@ -185,7 +185,7 @@ if(__IMPLICT_DLINK_DIRS) endif() set(__IMPLICT_DLINK_FLAGS ) foreach(dir ${__IMPLICT_DLINK_DIRS}) - if(EXISTS "${dir}/libcublas_device.a") + if(EXISTS "${dir}/libcurand_static.a") string(APPEND __IMPLICT_DLINK_FLAGS " -L\"${dir}\"") endif() endforeach() diff --git a/Modules/CMakeDetermineCompilerId.cmake b/Modules/CMakeDetermineCompilerId.cmake index 16dde65..dc4d9be 100644 --- a/Modules/CMakeDetermineCompilerId.cmake +++ b/Modules/CMakeDetermineCompilerId.cmake @@ -355,6 +355,12 @@ Id flags: ${testflags} ${CMAKE_${lang}_COMPILER_ID_FLAGS_ALWAYS} else() set(id_development_team "") endif() + if(DEFINED CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY) + set(id_code_sign_identity + "CODE_SIGN_IDENTITY = \"${CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY}\";") + else() + set(id_code_sign_identity "") + endif() configure_file(${CMAKE_ROOT}/Modules/CompilerId/Xcode-3.pbxproj.in ${id_dir}/CompilerId${lang}.xcodeproj/project.pbxproj @ONLY) unset(_ENV_MACOSX_DEPLOYMENT_TARGET) diff --git a/Modules/CMakeExtraGeneratorDetermineCompilerMacrosAndIncludeDirs.cmake b/Modules/CMakeExtraGeneratorDetermineCompilerMacrosAndIncludeDirs.cmake index 3a72622..55e0373 100644 --- a/Modules/CMakeExtraGeneratorDetermineCompilerMacrosAndIncludeDirs.cmake +++ b/Modules/CMakeExtraGeneratorDetermineCompilerMacrosAndIncludeDirs.cmake @@ -66,10 +66,10 @@ macro(_DETERMINE_GCC_SYSTEM_INCLUDE_DIRS _lang _resultIncludeDirs _resultDefines #message(STATUS "m1: -${CMAKE_MATCH_1}- m2: -${CMAKE_MATCH_2}- m3: -${CMAKE_MATCH_3}-") list(APPEND ${_resultDefines} "${_name}") - if(_value) - list(APPEND ${_resultDefines} "${_value}") - else() + if ("${_value}" STREQUAL "") list(APPEND ${_resultDefines} " ") + else() + list(APPEND ${_resultDefines} "${_value}") endif() endforeach() diff --git a/Modules/CompilerId/Xcode-3.pbxproj.in b/Modules/CompilerId/Xcode-3.pbxproj.in index 94bcbf8..4686b64 100644 --- a/Modules/CompilerId/Xcode-3.pbxproj.in +++ b/Modules/CompilerId/Xcode-3.pbxproj.in @@ -73,6 +73,7 @@ isa = XCBuildConfiguration; buildSettings = { @id_development_team@ + @id_code_sign_identity@ PRODUCT_NAME = CompilerId@id_lang@; }; name = Debug; diff --git a/Modules/FindCUDA.cmake b/Modules/FindCUDA.cmake index 21cace3..1650e55 100644 --- a/Modules/FindCUDA.cmake +++ b/Modules/FindCUDA.cmake @@ -971,7 +971,8 @@ if(NOT CUDA_VERSION VERSION_LESS "3.2") find_cuda_helper_libs(nvcuvid) endif() endif() -if(CUDA_VERSION VERSION_GREATER "5.0") +if(CUDA_VERSION VERSION_GREATER "5.0" AND CUDA_VERSION VERSION_LESS "9.2") + # In CUDA 9.2 cublas_device was deprecated find_cuda_helper_libs(cublas_device) endif() diff --git a/Modules/FindZLIB.cmake b/Modules/FindZLIB.cmake index a5c04ac..1a4635a 100644 --- a/Modules/FindZLIB.cmake +++ b/Modules/FindZLIB.cmake @@ -58,10 +58,12 @@ if(ZLIB_ROOT) endif() # Normal search. +set(_ZLIB_x86 "(x86)") set(_ZLIB_SEARCH_NORMAL - PATHS "[HKEY_LOCAL_MACHINE\\SOFTWARE\\GnuWin32\\Zlib;InstallPath]" - "$ENV{PROGRAMFILES}/zlib" - ) + PATHS "[HKEY_LOCAL_MACHINE\\SOFTWARE\\GnuWin32\\Zlib;InstallPath]" + "$ENV{ProgramFiles}/zlib" + "$ENV{ProgramFiles${_ZLIB_x86}}/zlib") +unset(_ZLIB_x86) list(APPEND _ZLIB_SEARCHES _ZLIB_SEARCH_NORMAL) set(ZLIB_NAMES z zlib zdll zlib1) diff --git a/Modules/Platform/Windows-NVIDIA-CUDA.cmake b/Modules/Platform/Windows-NVIDIA-CUDA.cmake index f1c1f2d..ba1638f 100644 --- a/Modules/Platform/Windows-NVIDIA-CUDA.cmake +++ b/Modules/Platform/Windows-NVIDIA-CUDA.cmake @@ -44,7 +44,7 @@ if(__IMPLICT_DLINK_DIRS) endif() set(__IMPLICT_DLINK_FLAGS ) foreach(dir ${__IMPLICT_DLINK_DIRS}) - if(EXISTS "${dir}/cublas_device.lib") + if(EXISTS "${dir}/curand_static.lib") string(APPEND __IMPLICT_DLINK_FLAGS " -L\"${dir}\"") endif() endforeach() diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index b7641ff..dc64c6c 100644 --- a/Source/CMakeVersion.cmake +++ b/Source/CMakeVersion.cmake @@ -1,5 +1,5 @@ # CMake version number components. set(CMake_VERSION_MAJOR 3) set(CMake_VERSION_MINOR 12) -set(CMake_VERSION_PATCH 20180815) +set(CMake_VERSION_PATCH 20180827) #set(CMake_VERSION_RC 1) diff --git a/Source/CTest/cmCTestSubmitHandler.cxx b/Source/CTest/cmCTestSubmitHandler.cxx index 4c2b75e..cbed40e 100644 --- a/Source/CTest/cmCTestSubmitHandler.cxx +++ b/Source/CTest/cmCTestSubmitHandler.cxx @@ -454,6 +454,10 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP(const std::string& localprefix, // specify target ::curl_easy_setopt(curl, CURLOPT_URL, upload_as.c_str()); + // CURLAUTH_BASIC is default, and here we allow additional methods, + // including more secure ones + ::curl_easy_setopt(curl, CURLOPT_HTTPAUTH, CURLAUTH_ANY); + // now specify which file to upload ::curl_easy_setopt(curl, CURLOPT_INFILE, ftpfile); diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx index 002fae6..75d3374 100644 --- a/Source/cmExportFileGenerator.cxx +++ b/Source/cmExportFileGenerator.cxx @@ -1174,6 +1174,11 @@ bool cmExportFileGenerator::PopulateExportProperties( return false; } auto propertyValue = targetProperties.GetPropertyValue(prop); + if (propertyValue == nullptr) { + // Asked to export a property that isn't defined on the target. Do not + // consider this an error, there's just nothing to export. + continue; + } std::string evaluatedValue = cmGeneratorExpression::Preprocess( propertyValue, cmGeneratorExpression::StripAllGeneratorExpressions); if (evaluatedValue != propertyValue) { diff --git a/Source/cmGeneratorExpression.cxx b/Source/cmGeneratorExpression.cxx index f26c717..b1b2b88 100644 --- a/Source/cmGeneratorExpression.cxx +++ b/Source/cmGeneratorExpression.cxx @@ -390,7 +390,7 @@ const char* cmGeneratorExpressionInterpreter::Evaluate( const char* expression, const std::string& property) { if (this->Target.empty()) { - return this->EvaluateExpression(expression); + return this->EvaluateExpression(expression).c_str(); } // Specify COMPILE_OPTIONS to DAGchecker, same semantic as COMPILE_FLAGS @@ -398,5 +398,5 @@ const char* cmGeneratorExpressionInterpreter::Evaluate( this->Target, property == "COMPILE_FLAGS" ? "COMPILE_OPTIONS" : property, nullptr, nullptr); - return this->EvaluateExpression(expression, &dagChecker); + return this->EvaluateExpression(expression, &dagChecker).c_str(); } diff --git a/Source/cmGeneratorExpression.h b/Source/cmGeneratorExpression.h index 2899317..1ceb7da 100644 --- a/Source/cmGeneratorExpression.h +++ b/Source/cmGeneratorExpression.h @@ -181,7 +181,7 @@ public: const char* Evaluate(const char* expression) { - return this->EvaluateExpression(expression); + return this->EvaluateExpression(expression).c_str(); } const char* Evaluate(const std::string& expression) { @@ -212,7 +212,7 @@ protected: const std::string& GetTargetName() const { return this->Target; } const std::string& GetLanguage() const { return this->Language; } - const char* EvaluateExpression( + const std::string& EvaluateExpression( const char* expression, cmGeneratorExpressionDAGChecker* dagChecker = nullptr) { @@ -220,16 +220,13 @@ protected: this->GeneratorExpression.Parse(expression); if (dagChecker == nullptr) { - return this->CompiledGeneratorExpression - ->Evaluate(this->LocalGenerator, this->Config, false, - this->GeneratorTarget) - .c_str(); + return this->CompiledGeneratorExpression->Evaluate( + this->LocalGenerator, this->Config, false, this->GeneratorTarget); } - return this->CompiledGeneratorExpression - ->Evaluate(this->LocalGenerator, this->Config, false, - this->GeneratorTarget, dagChecker, this->Language) - .c_str(); + return this->CompiledGeneratorExpression->Evaluate( + this->LocalGenerator, this->Config, false, this->GeneratorTarget, + dagChecker, this->Language); } private: diff --git a/Source/cmGlobVerificationManager.cxx b/Source/cmGlobVerificationManager.cxx index d8c854c..e8959f2 100644 --- a/Source/cmGlobVerificationManager.cxx +++ b/Source/cmGlobVerificationManager.cxx @@ -170,3 +170,10 @@ void cmGlobVerificationManager::AddCacheEntry( value.Backtraces.emplace_back(variable, backtrace); } } + +void cmGlobVerificationManager::Reset() +{ + this->Cache.clear(); + this->VerifyScript.clear(); + this->VerifyStamp.clear(); +} diff --git a/Source/cmGlobVerificationManager.h b/Source/cmGlobVerificationManager.h index 4508602..cf04c97 100644 --- a/Source/cmGlobVerificationManager.h +++ b/Source/cmGlobVerificationManager.h @@ -37,6 +37,9 @@ protected: const std::string& variable, const cmListFileBacktrace& bt); + ///! Clear the glob cache for state reset. + void Reset(); + ///! Check targets should be written in generated build system. bool DoWriteVerifyTarget() const; diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index 324b56a..4060269 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -34,6 +34,7 @@ #include "cmMakefile.h" #include "cmOutputConverter.h" #include "cmPolicies.h" +#include "cmQtAutoGen.h" #include "cmQtAutoGenInitializer.h" #include "cmSourceFile.h" #include "cmState.h" @@ -1495,15 +1496,14 @@ bool cmGlobalGenerator::QtAutoGen() continue; } - std::string qtVersionMajor = - cmQtAutoGenInitializer::GetQtMajorVersion(target); + auto qtVersion = cmQtAutoGenInitializer::GetQtVersion(target); // don't do anything if there is no Qt4 or Qt5Core (which contains moc) - if (qtVersionMajor != "4" && qtVersionMajor != "5") { + if (qtVersion.Major != 4 && qtVersion.Major != 5) { continue; } autogenInits.emplace_back(cm::make_unique<cmQtAutoGenInitializer>( - target, mocEnabled, uicEnabled, rccEnabled, qtVersionMajor)); + target, mocEnabled, uicEnabled, rccEnabled, qtVersion)); } } diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index 8ba38df..677a340 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -1111,6 +1111,12 @@ void cmGlobalNinjaGenerator::WriteTargetAliases(std::ostream& os) continue; } + // Don't write alias if there is a already a custom command with + // matching output + if (this->HasCustomCommandOutput(ta.first)) { + continue; + } + cmNinjaDeps deps; this->AppendTargetOutputs(ta.second, deps); diff --git a/Source/cmQtAutoGen.h b/Source/cmQtAutoGen.h index a3e16ac..4118dc7 100644 --- a/Source/cmQtAutoGen.h +++ b/Source/cmQtAutoGen.h @@ -28,6 +28,32 @@ public: RCC }; + /// @brief Integer version + struct IntegerVersion + { + unsigned int Major = 0; + unsigned int Minor = 0; + + IntegerVersion() = default; + IntegerVersion(unsigned int major, unsigned int minor) + : Major(major) + , Minor(minor) + { + } + + bool operator>(IntegerVersion const version) + { + return (this->Major > version.Major) || + ((this->Major == version.Major) && (this->Minor > version.Minor)); + } + + bool operator>=(IntegerVersion const version) + { + return (this->Major > version.Major) || + ((this->Major == version.Major) && (this->Minor >= version.Minor)); + } + }; + public: /// @brief Returns the generator name static std::string const& GeneratorName(GeneratorT genType); diff --git a/Source/cmQtAutoGenInitializer.cxx b/Source/cmQtAutoGenInitializer.cxx index 72ae09a..db7fde6 100644 --- a/Source/cmQtAutoGenInitializer.cxx +++ b/Source/cmQtAutoGenInitializer.cxx @@ -173,19 +173,17 @@ static bool StaticLibraryCycle(cmGeneratorTarget const* targetOrigin, return cycle; } -cmQtAutoGenInitializer::cmQtAutoGenInitializer( - cmGeneratorTarget* target, bool mocEnabled, bool uicEnabled, bool rccEnabled, - std::string const& qtVersionMajor) +cmQtAutoGenInitializer::cmQtAutoGenInitializer(cmGeneratorTarget* target, + bool mocEnabled, + bool uicEnabled, + bool rccEnabled, + IntegerVersion const& qtVersion) : Target(target) - , MultiConfig(false) - , QtVersionMajor(qtVersionMajor) + , QtVersion(qtVersion) { Moc.Enabled = mocEnabled; Uic.Enabled = uicEnabled; Rcc.Enabled = rccEnabled; - - this->QtVersionMinor = - cmQtAutoGenInitializer::GetQtMinorVersion(target, this->QtVersionMajor); } bool cmQtAutoGenInitializer::InitCustomTargets() @@ -194,6 +192,13 @@ bool cmQtAutoGenInitializer::InitCustomTargets() cmLocalGenerator* localGen = this->Target->GetLocalGenerator(); cmGlobalGenerator* globalGen = localGen->GetGlobalGenerator(); + // Configurations + this->MultiConfig = globalGen->IsMultiConfig(); + this->ConfigDefault = makefile->GetConfigurations(this->ConfigsList); + if (this->ConfigsList.empty()) { + this->ConfigsList.push_back(this->ConfigDefault); + } + // Verbosity this->Verbosity = makefile->GetSafeDefinition("CMAKE_AUTOGEN_VERBOSE"); if (!this->Verbosity.empty()) { @@ -205,115 +210,116 @@ bool cmQtAutoGenInitializer::InitCustomTargets() } } - // Configurations - this->MultiConfig = globalGen->IsMultiConfig(); - this->ConfigDefault = makefile->GetConfigurations(this->ConfigsList); - if (this->ConfigsList.empty()) { - this->ConfigsList.push_back(this->ConfigDefault); - } - - // Parallel processing - this->Parallel = this->Target->GetSafeProperty("AUTOGEN_PARALLEL"); - if (this->Parallel.empty() || (this->Parallel == "AUTO")) { - // Autodetect number of CPUs - this->Parallel = std::to_string(GetParallelCPUCount()); + // Targets FOLDER + { + const char* folder = + makefile->GetState()->GetGlobalProperty("AUTOMOC_TARGETS_FOLDER"); + if (folder == nullptr) { + folder = + makefile->GetState()->GetGlobalProperty("AUTOGEN_TARGETS_FOLDER"); + } + // Inherit FOLDER property from target (#13688) + if (folder == nullptr) { + folder = this->Target->GetProperty("FOLDER"); + } + if (folder != nullptr) { + this->TargetsFolder = folder; + } } - // Autogen target name - this->AutogenTargetName = this->Target->GetName(); - this->AutogenTargetName += "_autogen"; - - // Autogen directories + // Common directories { // Collapsed current binary directory std::string const cbd = cmSystemTools::CollapseFullPath( "", makefile->GetCurrentBinaryDirectory()); - // Autogen info dir - this->DirInfo = cbd; - this->DirInfo += makefile->GetCMakeInstance()->GetCMakeFilesDirectory(); - this->DirInfo += '/'; - this->DirInfo += this->AutogenTargetName; - this->DirInfo += ".dir"; - cmSystemTools::ConvertToUnixSlashes(this->DirInfo); - - // Autogen build dir - this->DirBuild = this->Target->GetSafeProperty("AUTOGEN_BUILD_DIR"); - if (this->DirBuild.empty()) { - this->DirBuild = cbd; - this->DirBuild += '/'; - this->DirBuild += this->AutogenTargetName; + // Info directory + this->Dir.Info = cbd; + this->Dir.Info += makefile->GetCMakeInstance()->GetCMakeFilesDirectory(); + this->Dir.Info += '/'; + this->Dir.Info += this->Target->GetName(); + this->Dir.Info += "_autogen"; + this->Dir.Info += ".dir"; + cmSystemTools::ConvertToUnixSlashes(this->Dir.Info); + + // Build directory + this->Dir.Build = this->Target->GetSafeProperty("AUTOGEN_BUILD_DIR"); + if (this->Dir.Build.empty()) { + this->Dir.Build = cbd; + this->Dir.Build += '/'; + this->Dir.Build += this->Target->GetName(); + this->Dir.Build += "_autogen"; } - cmSystemTools::ConvertToUnixSlashes(this->DirBuild); - // Remove build directories on cleanup - AddCleanFile(makefile, this->DirBuild); + cmSystemTools::ConvertToUnixSlashes(this->Dir.Build); + // Cleanup build directory + AddCleanFile(makefile, this->Dir.Build); // Working directory - this->DirWork = cbd; - cmSystemTools::ConvertToUnixSlashes(this->DirWork); + this->Dir.Work = cbd; + cmSystemTools::ConvertToUnixSlashes(this->Dir.Work); // Include directory - this->DirInclude = this->DirBuild; - this->DirInclude += "/include"; + this->Dir.Include = this->Dir.Build; + this->Dir.Include += "/include"; if (this->MultiConfig) { - this->DirInclude += "_$<CONFIG>"; + this->Dir.Include += "_$<CONFIG>"; } + // Per config include directories if (this->MultiConfig) { for (std::string const& cfg : this->ConfigsList) { - std::string& dir = this->DirConfigInclude[cfg]; - dir = this->DirBuild; + std::string& dir = this->Dir.ConfigInclude[cfg]; + dir = this->Dir.Build; dir += "/include_"; dir += cfg; } } } - // Autogen info and settings files - { - this->AutogenInfoFile = this->DirInfo; - this->AutogenInfoFile += "/AutogenInfo.cmake"; - - this->AutogenSettingsFile = this->DirInfo; - this->AutogenSettingsFile += "/AutogenOldSettings.txt"; - - if (this->MultiConfig) { - for (std::string const& cfg : this->ConfigsList) { - std::string& filename = this->AutogenConfigSettingsFile[cfg]; - filename = AppendFilenameSuffix(this->AutogenSettingsFile, "_" + cfg); - AddCleanFile(makefile, filename); - } - } else { - AddCleanFile(makefile, this->AutogenSettingsFile); - } - } - - // Autogen target FOLDER property - { - const char* folder = - makefile->GetState()->GetGlobalProperty("AUTOMOC_TARGETS_FOLDER"); - if (folder == nullptr) { - folder = - makefile->GetState()->GetGlobalProperty("AUTOGEN_TARGETS_FOLDER"); - } - // Inherit FOLDER property from target (#13688) - if (folder == nullptr) { - folder = this->Target->GetProperty("FOLDER"); - } - if (folder != nullptr) { - this->AutogenFolder = folder; - } - } - + // Moc, Uic and _autogen target settings if (this->Moc.Enabled || this->Uic.Enabled) { // Init moc specific settings if (this->Moc.Enabled && !InitMoc()) { return false; } + // Init uic specific settings if (this->Uic.Enabled && !InitUic()) { return false; } + // Autogen target name + this->AutogenTarget.Name = this->Target->GetName(); + this->AutogenTarget.Name += "_autogen"; + + // Autogen target parallel processing + this->AutogenTarget.Parallel = + this->Target->GetSafeProperty("AUTOGEN_PARALLEL"); + if (this->AutogenTarget.Parallel.empty() || + (this->AutogenTarget.Parallel == "AUTO")) { + // Autodetect number of CPUs + this->AutogenTarget.Parallel = std::to_string(GetParallelCPUCount()); + } + + // Autogen target info and settings files + { + this->AutogenTarget.InfoFile = this->Dir.Info; + this->AutogenTarget.InfoFile += "/AutogenInfo.cmake"; + + this->AutogenTarget.SettingsFile = this->Dir.Info; + this->AutogenTarget.SettingsFile += "/AutogenOldSettings.txt"; + + if (this->MultiConfig) { + for (std::string const& cfg : this->ConfigsList) { + std::string& filename = this->AutogenTarget.ConfigSettingsFile[cfg]; + filename = + AppendFilenameSuffix(this->AutogenTarget.SettingsFile, "_" + cfg); + AddCleanFile(makefile, filename); + } + } else { + AddCleanFile(makefile, this->AutogenTarget.SettingsFile); + } + } + // Autogen target: Compute user defined dependencies { std::string const deps = @@ -325,14 +331,15 @@ bool cmQtAutoGenInitializer::InitCustomTargets() // Allow target and file dependencies auto* depTarget = makefile->FindTargetToUse(depName); if (depTarget != nullptr) { - this->AutogenDependTargets.insert(depTarget); + this->AutogenTarget.DependTargets.insert(depTarget); } else { - this->AutogenDependFiles.insert(depName); + this->AutogenTarget.DependFiles.insert(depName); } } } } } + // Init rcc specific settings if (this->Rcc.Enabled && !InitRcc()) { return false; @@ -341,7 +348,7 @@ bool cmQtAutoGenInitializer::InitCustomTargets() // Add autogen include directory to the origin target INCLUDE_DIRECTORIES if (this->Moc.Enabled || this->Uic.Enabled || (this->Rcc.Enabled && this->MultiConfig)) { - this->Target->AddIncludeDirectory(this->DirInclude, true); + this->Target->AddIncludeDirectory(this->Dir.Include, true); } // Scan files @@ -368,19 +375,19 @@ bool cmQtAutoGenInitializer::InitMoc() cmLocalGenerator* localGen = this->Target->GetLocalGenerator(); // Mocs compilation file - this->Moc.MocsCompilation = this->DirBuild; + this->Moc.MocsCompilation = this->Dir.Build; this->Moc.MocsCompilation += "/mocs_compilation.cpp"; // Moc predefs command if (this->Target->GetPropertyAsBool("AUTOMOC_COMPILER_PREDEFINES") && - this->QtVersionGreaterOrEqual(5, 8)) { + (this->QtVersion >= IntegerVersion(5, 8))) { this->Moc.PredefsCmd = makefile->GetSafeDefinition("CMAKE_CXX_COMPILER_PREDEFINES_COMMAND"); } // Moc includes { - bool const appendImplicit = (this->QtVersionMajor == "5"); + bool const appendImplicit = (this->QtVersion.Major == 5); auto GetIncludeDirs = [this, localGen, appendImplicit](std::string const& cfg) -> std::string { // Get the include dirs for this target, without stripping the implicit @@ -552,15 +559,15 @@ bool cmQtAutoGenInitializer::InitScanFiles() const bool generated = sf->GetPropertyAsBool("GENERATED"); if (fileType == cmSystemTools::HEADER_FILE_FORMAT) { if (generated) { - this->MocUic.HeadersGenerated.push_back(absPath); + this->AutogenTarget.HeadersGenerated.push_back(absPath); } else { - this->MocUic.Headers.push_back(absPath); + this->AutogenTarget.Headers.push_back(absPath); } } else { if (generated) { - this->MocUic.SourcesGenerated.push_back(absPath); + this->AutogenTarget.SourcesGenerated.push_back(absPath); } else { - this->MocUic.Sources.push_back(absPath); + this->AutogenTarget.Sources.push_back(absPath); } } } @@ -631,8 +638,8 @@ bool cmQtAutoGenInitializer::InitScanFiles() } // Process GENERATED sources and headers - if (!this->MocUic.SourcesGenerated.empty() || - !this->MocUic.HeadersGenerated.empty()) { + if (!this->AutogenTarget.SourcesGenerated.empty() || + !this->AutogenTarget.HeadersGenerated.empty()) { // Check status of policy CMP0071 bool policyAccept = false; bool policyWarn = false; @@ -655,13 +662,15 @@ bool cmQtAutoGenInitializer::InitScanFiles() if (policyAccept) { // Accept GENERATED sources - for (std::string const& absFile : this->MocUic.HeadersGenerated) { - this->MocUic.Headers.push_back(absFile); - this->AutogenDependFiles.insert(absFile); + for (std::string const& absFile : + this->AutogenTarget.HeadersGenerated) { + this->AutogenTarget.Headers.push_back(absFile); + this->AutogenTarget.DependFiles.insert(absFile); } - for (std::string const& absFile : this->MocUic.SourcesGenerated) { - this->MocUic.Sources.push_back(absFile); - this->AutogenDependFiles.insert(absFile); + for (std::string const& absFile : + this->AutogenTarget.SourcesGenerated) { + this->AutogenTarget.Sources.push_back(absFile); + this->AutogenTarget.DependFiles.insert(absFile); } } else { if (policyWarn) { @@ -682,10 +691,12 @@ bool cmQtAutoGenInitializer::InitScanFiles() } msg += "For compatibility, CMake is excluding the GENERATED source " "file(s):\n"; - for (const std::string& absFile : this->MocUic.HeadersGenerated) { + for (const std::string& absFile : + this->AutogenTarget.HeadersGenerated) { msg.append(" ").append(Quoted(absFile)).append("\n"); } - for (const std::string& absFile : this->MocUic.SourcesGenerated) { + for (const std::string& absFile : + this->AutogenTarget.SourcesGenerated) { msg.append(" ").append(Quoted(absFile)).append("\n"); } msg += "from processing by "; @@ -704,14 +715,16 @@ bool cmQtAutoGenInitializer::InitScanFiles() } // Sort headers and sources if (this->Moc.Enabled || this->Uic.Enabled) { - std::sort(this->MocUic.Headers.begin(), this->MocUic.Headers.end()); - std::sort(this->MocUic.Sources.begin(), this->MocUic.Sources.end()); + std::sort(this->AutogenTarget.Headers.begin(), + this->AutogenTarget.Headers.end()); + std::sort(this->AutogenTarget.Sources.begin(), + this->AutogenTarget.Sources.end()); } } // Process qrc files if (!this->Rcc.Qrcs.empty()) { - const bool QtV5 = (this->QtVersionMajor == "5"); + const bool QtV5 = (this->QtVersion.Major == 5); // Target rcc options std::vector<std::string> optionsTarget; cmSystemTools::ExpandListArgument( @@ -734,7 +747,7 @@ bool cmQtAutoGenInitializer::InitScanFiles() qrc.PathChecksum = fpathCheckSum.getPart(qrc.QrcFile); // RCC output file name { - std::string rccFile = this->DirBuild + "/"; + std::string rccFile = this->Dir.Build + "/"; rccFile += qrc.PathChecksum; rccFile += "/qrc_"; rccFile += qrc.QrcName; @@ -742,7 +755,7 @@ bool cmQtAutoGenInitializer::InitScanFiles() qrc.RccFile = std::move(rccFile); } { - std::string base = this->DirInfo; + std::string base = this->Dir.Info; base += "/RCC"; base += qrc.QrcName; if (!qrc.Unique) { @@ -811,7 +824,7 @@ bool cmQtAutoGenInitializer::InitAutogenTarget() cmGlobalGenerator* globalGen = localGen->GetGlobalGenerator(); // Register info file as generated by CMake - makefile->AddCMakeOutputFile(this->AutogenInfoFile); + makefile->AddCMakeOutputFile(this->AutogenTarget.InfoFile); // Files provided by the autogen target std::vector<std::string> autogenProvides; @@ -846,7 +859,7 @@ bool cmQtAutoGenInitializer::InitAutogenTarget() currentLine.push_back(cmSystemTools::GetCMakeCommand()); currentLine.push_back("-E"); currentLine.push_back("cmake_autogen"); - currentLine.push_back(this->AutogenInfoFile); + currentLine.push_back(this->AutogenTarget.InfoFile); currentLine.push_back("$<CONFIGURATION>"); commandLines.push_back(std::move(currentLine)); } @@ -863,14 +876,14 @@ bool cmQtAutoGenInitializer::InitAutogenTarget() // Disable PRE_BUILD in some cases if (usePRE_BUILD) { // Cannot use PRE_BUILD with file depends - if (!this->AutogenDependFiles.empty()) { + if (!this->AutogenTarget.DependFiles.empty()) { usePRE_BUILD = false; } } // Create the autogen target/command if (usePRE_BUILD) { // Add additional autogen target dependencies to origin target - for (cmTarget* depTarget : this->AutogenDependTargets) { + for (cmTarget* depTarget : this->AutogenTarget.DependTargets) { this->Target->Target->AddUtility(depTarget->GetName(), makefile); } @@ -883,7 +896,7 @@ bool cmQtAutoGenInitializer::InitAutogenTarget() const std::vector<std::string> no_deps; cmCustomCommand cc(makefile, no_output, autogenProvides, no_deps, commandLines, autogenComment.c_str(), - this->DirWork.c_str()); + this->Dir.Work.c_str()); cc.SetEscapeOldStyle(false); cc.SetEscapeAllowMakeVars(true); this->Target->Target->AddPreBuildCommand(cc); @@ -911,17 +924,17 @@ bool cmQtAutoGenInitializer::InitAutogenTarget() } for (auto const& item : commonTargets) { if (item.second == this->ConfigsList.size()) { - this->AutogenDependTargets.insert(item.first->Target); + this->AutogenTarget.DependTargets.insert(item.first->Target); } } } // Create autogen target cmTarget* autogenTarget = makefile->AddUtilityCommand( - this->AutogenTargetName, cmMakefile::TargetOrigin::Generator, true, - this->DirWork.c_str(), /*byproducts=*/autogenProvides, - std::vector<std::string>(this->AutogenDependFiles.begin(), - this->AutogenDependFiles.end()), + this->AutogenTarget.Name, cmMakefile::TargetOrigin::Generator, true, + this->Dir.Work.c_str(), /*byproducts=*/autogenProvides, + std::vector<std::string>(this->AutogenTarget.DependFiles.begin(), + this->AutogenTarget.DependFiles.end()), commandLines, false, autogenComment.c_str()); // Create autogen generator target localGen->AddGeneratorTarget( @@ -932,17 +945,17 @@ bool cmQtAutoGenInitializer::InitAutogenTarget() autogenTarget->AddUtility(depName, makefile); } // Add additional autogen target dependencies to autogen target - for (cmTarget* depTarget : this->AutogenDependTargets) { + for (cmTarget* depTarget : this->AutogenTarget.DependTargets) { autogenTarget->AddUtility(depTarget->GetName(), makefile); } // Set FOLDER property in autogen target - if (!this->AutogenFolder.empty()) { - autogenTarget->SetProperty("FOLDER", this->AutogenFolder.c_str()); + if (!this->TargetsFolder.empty()) { + autogenTarget->SetProperty("FOLDER", this->TargetsFolder.c_str()); } // Add autogen target to the origin target dependencies - this->Target->Target->AddUtility(this->AutogenTargetName, makefile); + this->Target->Target->AddUtility(this->AutogenTarget.Name, makefile); } return true; @@ -1004,15 +1017,15 @@ bool cmQtAutoGenInitializer::InitRccTargets() cmTarget* autoRccTarget = makefile->AddUtilityCommand( ccName, cmMakefile::TargetOrigin::Generator, true, - this->DirWork.c_str(), ccOutput, ccDepends, commandLines, false, + this->Dir.Work.c_str(), ccOutput, ccDepends, commandLines, false, ccComment.c_str()); // Create autogen generator target localGen->AddGeneratorTarget( new cmGeneratorTarget(autoRccTarget, localGen)); // Set FOLDER property in autogen target - if (!this->AutogenFolder.empty()) { - autoRccTarget->SetProperty("FOLDER", this->AutogenFolder.c_str()); + if (!this->TargetsFolder.empty()) { + autoRccTarget->SetProperty("FOLDER", this->TargetsFolder.c_str()); } } // Add autogen target to the origin target dependencies @@ -1034,7 +1047,7 @@ bool cmQtAutoGenInitializer::InitRccTargets() makefile->AddCustomCommandToOutput(ccOutput, ccByproducts, ccDepends, /*main_dependency*/ std::string(), commandLines, ccComment.c_str(), - this->DirWork.c_str()); + this->Dir.Work.c_str()); } // Reconfigure when .qrc file changes makefile->AddCMakeDependFile(qrc.QrcFile); @@ -1047,9 +1060,9 @@ bool cmQtAutoGenInitializer::InitRccTargets() bool cmQtAutoGenInitializer::SetupCustomTargets() { // Create info directory on demand - if (!cmSystemTools::MakeDirectory(this->DirInfo)) { + if (!cmSystemTools::MakeDirectory(this->Dir.Info)) { std::string emsg = ("AutoGen: Could not create directory: "); - emsg += Quoted(this->DirInfo); + emsg += Quoted(this->Dir.Info); cmSystemTools::Error(emsg.c_str()); return false; } @@ -1076,13 +1089,16 @@ bool cmQtAutoGenInitializer::SetupWriteAutogenInfo() cmGeneratedFileStream ofs; ofs.SetCopyIfDifferent(true); - ofs.Open(this->AutogenInfoFile, false, true); + ofs.Open(this->AutogenTarget.InfoFile, false, true); if (ofs) { // Utility lambdas auto CWrite = [&ofs](const char* key, std::string const& value) { ofs << "set(" << key << " " << cmOutputConverter::EscapeForCMake(value) << ")\n"; }; + auto CWriteUInt = [&ofs](const char* key, unsigned int value) { + ofs << "set(" << key << " " << value << ")\n"; + }; auto CWriteList = [&CWrite](const char* key, std::vector<std::string> const& list) { CWrite(key, cmJoin(list, ";")); @@ -1117,7 +1133,7 @@ bool cmQtAutoGenInitializer::SetupWriteAutogenInfo() // Write ofs << "# Meta\n"; CWrite("AM_MULTI_CONFIG", this->MultiConfig ? "TRUE" : "FALSE"); - CWrite("AM_PARALLEL", this->Parallel); + CWrite("AM_PARALLEL", this->AutogenTarget.Parallel); CWrite("AM_VERBOSITY", this->Verbosity); ofs << "# Directories\n"; @@ -1127,18 +1143,18 @@ bool cmQtAutoGenInitializer::SetupWriteAutogenInfo() CWrite("AM_CMAKE_CURRENT_BINARY_DIR", MfDef("CMAKE_CURRENT_BINARY_DIR")); CWrite("AM_CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE", MfDef("CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE")); - CWrite("AM_BUILD_DIR", this->DirBuild); - CWrite("AM_INCLUDE_DIR", this->DirInclude); - CWriteMap("AM_INCLUDE_DIR", this->DirConfigInclude); + CWrite("AM_BUILD_DIR", this->Dir.Build); + CWrite("AM_INCLUDE_DIR", this->Dir.Include); + CWriteMap("AM_INCLUDE_DIR", this->Dir.ConfigInclude); ofs << "# Files\n"; - CWriteList("AM_SOURCES", this->MocUic.Sources); - CWriteList("AM_HEADERS", this->MocUic.Headers); - CWrite("AM_SETTINGS_FILE", this->AutogenSettingsFile); - CWriteMap("AM_SETTINGS_FILE", this->AutogenConfigSettingsFile); + CWriteList("AM_SOURCES", this->AutogenTarget.Sources); + CWriteList("AM_HEADERS", this->AutogenTarget.Headers); + CWrite("AM_SETTINGS_FILE", this->AutogenTarget.SettingsFile); + CWriteMap("AM_SETTINGS_FILE", this->AutogenTarget.ConfigSettingsFile); ofs << "# Qt\n"; - CWrite("AM_QT_VERSION_MAJOR", this->QtVersionMajor); + CWriteUInt("AM_QT_VERSION_MAJOR", this->QtVersion.Major); CWrite("AM_QT_MOC_EXECUTABLE", this->Moc.Executable); CWrite("AM_QT_UIC_EXECUTABLE", this->Uic.Executable); @@ -1170,7 +1186,7 @@ bool cmQtAutoGenInitializer::SetupWriteAutogenInfo() } } else { std::string err = "AutoGen: Could not write file "; - err += this->AutogenInfoFile; + err += this->AutogenTarget.InfoFile; cmSystemTools::Error(err.c_str()); return false; } @@ -1207,9 +1223,9 @@ bool cmQtAutoGenInitializer::SetupWriteRccInfo() CWriteMap("ARCC_SETTINGS_FILE", qrc.ConfigSettingsFile); ofs << "# Directories\n"; - CWrite("ARCC_BUILD_DIR", this->DirBuild); - CWrite("ARCC_INCLUDE_DIR", this->DirInclude); - CWriteMap("ARCC_INCLUDE_DIR", this->DirConfigInclude); + CWrite("ARCC_BUILD_DIR", this->Dir.Build); + CWrite("ARCC_INCLUDE_DIR", this->Dir.Include); + CWriteMap("ARCC_INCLUDE_DIR", this->Dir.ConfigInclude); ofs << "# Rcc executable\n"; CWrite("ARCC_RCC_EXECUTABLE", this->Rcc.Executable); @@ -1251,53 +1267,56 @@ void cmQtAutoGenInitializer::AddGeneratedSource(std::string const& filename, this->Target->AddSource(filename); } -std::string cmQtAutoGenInitializer::GetQtMajorVersion( +cmQtAutoGenInitializer::IntegerVersion cmQtAutoGenInitializer::GetQtVersion( cmGeneratorTarget const* target) { + cmQtAutoGenInitializer::IntegerVersion res; cmMakefile* makefile = target->Target->GetMakefile(); + + // -- Major version std::string qtMajor = makefile->GetSafeDefinition("QT_VERSION_MAJOR"); if (qtMajor.empty()) { qtMajor = makefile->GetSafeDefinition("Qt5Core_VERSION_MAJOR"); } - const char* targetQtVersion = - target->GetLinkInterfaceDependentStringProperty("QT_MAJOR_VERSION", ""); - if (targetQtVersion != nullptr) { - qtMajor = targetQtVersion; + { + const char* targetQtVersion = + target->GetLinkInterfaceDependentStringProperty("QT_MAJOR_VERSION", ""); + if (targetQtVersion != nullptr) { + qtMajor = targetQtVersion; + } } - return qtMajor; -} -std::string cmQtAutoGenInitializer::GetQtMinorVersion( - cmGeneratorTarget const* target, std::string const& qtVersionMajor) -{ - cmMakefile* makefile = target->Target->GetMakefile(); + // -- Minor version std::string qtMinor; - if (qtVersionMajor == "5") { - qtMinor = makefile->GetSafeDefinition("Qt5Core_VERSION_MINOR"); - } - if (qtMinor.empty()) { - qtMinor = makefile->GetSafeDefinition("QT_VERSION_MINOR"); + if (!qtMajor.empty()) { + if (qtMajor == "5") { + qtMinor = makefile->GetSafeDefinition("Qt5Core_VERSION_MINOR"); + } + if (qtMinor.empty()) { + qtMinor = makefile->GetSafeDefinition("QT_VERSION_MINOR"); + } + { + const char* targetQtVersion = + target->GetLinkInterfaceDependentStringProperty("QT_MINOR_VERSION", + ""); + if (targetQtVersion != nullptr) { + qtMinor = targetQtVersion; + } + } } - const char* targetQtVersion = - target->GetLinkInterfaceDependentStringProperty("QT_MINOR_VERSION", ""); - if (targetQtVersion != nullptr) { - qtMinor = targetQtVersion; + // -- Convert to integer + if (!qtMajor.empty() && !qtMinor.empty()) { + unsigned long majorUL(0); + unsigned long minorUL(0); + if (cmSystemTools::StringToULong(qtMajor.c_str(), &majorUL) && + cmSystemTools::StringToULong(qtMinor.c_str(), &minorUL)) { + res.Major = static_cast<unsigned int>(majorUL); + res.Minor = static_cast<unsigned int>(minorUL); + } } - return qtMinor; -} -bool cmQtAutoGenInitializer::QtVersionGreaterOrEqual( - unsigned long requestMajor, unsigned long requestMinor) const -{ - unsigned long majorUL(0); - unsigned long minorUL(0); - if (cmSystemTools::StringToULong(this->QtVersionMajor.c_str(), &majorUL) && - cmSystemTools::StringToULong(this->QtVersionMinor.c_str(), &minorUL)) { - return (majorUL > requestMajor) || - (majorUL == requestMajor && minorUL >= requestMinor); - } - return false; + return res; } bool cmQtAutoGenInitializer::GetMocExecutable() @@ -1307,9 +1326,9 @@ bool cmQtAutoGenInitializer::GetMocExecutable() // Find moc executable { std::string targetName; - if (this->QtVersionMajor == "5") { + if (this->QtVersion.Major == 5) { targetName = "Qt5::moc"; - } else if (QtVersionMajor == "4") { + } else if (this->QtVersion.Major == 4) { targetName = "Qt4::moc"; } else { err = "The AUTOMOC feature supports only Qt 4 and Qt 5"; @@ -1368,9 +1387,9 @@ bool cmQtAutoGenInitializer::GetUicExecutable() // Find uic executable { std::string targetName; - if (this->QtVersionMajor == "5") { + if (this->QtVersion.Major == 5) { targetName = "Qt5::uic"; - } else if (QtVersionMajor == "4") { + } else if (this->QtVersion.Major == 4) { targetName = "Qt4::uic"; } else { err = "The AUTOUIC feature supports only Qt 4 and Qt 5"; @@ -1381,7 +1400,7 @@ bool cmQtAutoGenInitializer::GetUicExecutable() if (tgt != nullptr) { this->Uic.Executable = tgt->ImportedGetLocation(""); } else { - if (this->QtVersionMajor == "5") { + if (this->QtVersion.Major == 5) { // Project does not use Qt5Widgets, but has AUTOUIC ON anyway } else { err = "Could not find target " + targetName; @@ -1433,9 +1452,9 @@ bool cmQtAutoGenInitializer::GetRccExecutable() // Find rcc executable { std::string targetName; - if (this->QtVersionMajor == "5") { + if (this->QtVersion.Major == 5) { targetName = "Qt5::rcc"; - } else if (QtVersionMajor == "4") { + } else if (this->QtVersion.Major == 4) { targetName = "Qt4::rcc"; } else { err = "The AUTORCC feature supports only Qt 4 and Qt 5"; @@ -1465,7 +1484,7 @@ bool cmQtAutoGenInitializer::GetRccExecutable() cmSystemTools::OUTPUT_NONE, cmDuration::zero(), cmProcessOutput::Auto); if (result) { // Detect if rcc supports (-)-list - if (this->QtVersionMajor == "5") { + if (this->QtVersion.Major == 5) { if (stdOut.find("--list") != std::string::npos) { this->Rcc.ListOptions.push_back("--list"); } else { diff --git a/Source/cmQtAutoGenInitializer.h b/Source/cmQtAutoGenInitializer.h index 16f9cdd..ce00e00 100644 --- a/Source/cmQtAutoGenInitializer.h +++ b/Source/cmQtAutoGenInitializer.h @@ -18,10 +18,6 @@ class cmTarget; class cmQtAutoGenInitializer : public cmQtAutoGen { public: - static std::string GetQtMajorVersion(cmGeneratorTarget const* target); - static std::string GetQtMinorVersion(cmGeneratorTarget const* target, - std::string const& qtVersionMajor); - /// @brief Rcc job information class Qrc { @@ -48,9 +44,11 @@ public: }; public: + static IntegerVersion GetQtVersion(cmGeneratorTarget const* target); + cmQtAutoGenInitializer(cmGeneratorTarget* target, bool mocEnabled, bool uicEnabled, bool rccEnabled, - std::string const& qtVersionMajor); + IntegerVersion const& qtVersion); bool InitCustomTargets(); bool SetupCustomTargets(); @@ -69,9 +67,6 @@ private: void AddGeneratedSource(std::string const& filename, GeneratorT genType); - bool QtVersionGreaterOrEqual(unsigned long requestMajor, - unsigned long requestMinor) const; - bool GetMocExecutable(); bool GetUicExecutable(); bool GetRccExecutable(); @@ -82,39 +77,46 @@ private: private: cmGeneratorTarget* Target; + + // Configuration + IntegerVersion QtVersion; bool MultiConfig = false; - // Qt - std::string QtVersionMajor; - std::string QtVersionMinor; - // Configurations std::string ConfigDefault; std::vector<std::string> ConfigsList; - std::string Parallel; std::string Verbosity; - // Names - std::string AutogenTargetName; - std::string AutogenFolder; - std::string AutogenInfoFile; - std::string AutogenSettingsFile; - std::map<std::string, std::string> AutogenConfigSettingsFile; - std::set<std::string> AutogenDependFiles; - std::set<cmTarget*> AutogenDependTargets; - // Directories - std::string DirInfo; - std::string DirBuild; - std::string DirWork; - std::string DirInclude; - std::map<std::string, std::string> DirConfigInclude; - // Moc and UIC + std::string TargetsFolder; + + /// @brief Common directories + struct + { + std::string Info; + std::string Build; + std::string Work; + std::string Include; + std::map<std::string, std::string> ConfigInclude; + } Dir; + + /// @brief Autogen target variables struct { - // Sources + std::string Name; + // Settings + std::string Parallel; + // Configuration files + std::string InfoFile; + std::string SettingsFile; + std::map<std::string, std::string> ConfigSettingsFile; + // Dependencies + std::set<std::string> DependFiles; + std::set<cmTarget*> DependTargets; + // Sources to process std::vector<std::string> Headers; std::vector<std::string> Sources; std::vector<std::string> HeadersGenerated; std::vector<std::string> SourcesGenerated; - } MocUic; - // Moc + } AutogenTarget; + + /// @brief Moc only variables struct { bool Enabled = false; @@ -127,7 +129,8 @@ private: std::map<std::string, std::string> ConfigDefines; std::string MocsCompilation; } Moc; - // Uic + + ///@brief Uic only variables struct { bool Enabled = false; @@ -139,7 +142,8 @@ private: std::vector<std::string> FileFiles; std::vector<std::vector<std::string>> FileOptions; } Uic; - // Rcc + + /// @brief Rcc only variables struct { bool Enabled = false; diff --git a/Source/cmState.cxx b/Source/cmState.cxx index dcf6ea0..5651594 100644 --- a/Source/cmState.cxx +++ b/Source/cmState.cxx @@ -267,6 +267,7 @@ cmStateSnapshot cmState::Reset() { this->GlobalProperties.clear(); this->PropertyDefinitions.clear(); + this->GlobVerificationManager->Reset(); cmStateDetail::PositionType pos = this->SnapshotData.Truncate(); this->ExecutionListFiles.Truncate(); diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 50d93d5..4597bc6 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -2490,6 +2490,16 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions( if (this->MSTools) { if (this->ProjectType == vcxproj) { clOptions.FixExceptionHandlingDefault(); + if (this->GlobalGenerator->GetVersion() >= + cmGlobalVisualStudioGenerator::VS15) { + // Toolsets that come with VS 2017 may now enable UseFullPaths + // by default and there is no negative /FC option that projects + // can use to switch it back. Older toolsets disable this by + // default anyway so this will not hurt them. If the project + // is using an explicit /FC option then parsing flags will + // replace this setting with "true" below. + clOptions.AddFlag("UseFullPaths", "false"); + } clOptions.AddFlag("PrecompiledHeader", "NotUsing"); std::string asmLocation = configName + "/"; clOptions.AddFlag("AssemblerListingLocation", asmLocation); @@ -3782,31 +3792,29 @@ void cmVisualStudio10TargetGenerator::WriteProjectReferences(Elem& e0) e2.Element("Project", "{" + this->GlobalGenerator->GetGUID(name) + "}"); e2.Element("Name", name); this->WriteDotNetReferenceCustomTags(e2, name); - if (this->Managed) { - // If the dependency target is not managed (compiled with /clr or - // C# target) we cannot reference it and have to set - // 'ReferenceOutputAssembly' to false. - auto referenceNotManaged = - dt->GetManagedType("") < cmGeneratorTarget::ManagedType::Mixed; - // Workaround to check for manually set /clr flags. - if (referenceNotManaged) { - if (const auto* flags = dt->GetProperty("COMPILE_OPTIONS")) { - std::string flagsStr = flags; - if (flagsStr.find("clr") != std::string::npos) { - // There is a warning already issued when building the flags. - referenceNotManaged = false; - } + + // If the dependency target is not managed (compiled with /clr or + // C# target) we cannot reference it and have to set + // 'ReferenceOutputAssembly' to false. + auto referenceNotManaged = + dt->GetManagedType("") < cmGeneratorTarget::ManagedType::Mixed; + // Workaround to check for manually set /clr flags. + if (referenceNotManaged) { + if (const auto* flags = dt->GetProperty("COMPILE_OPTIONS")) { + std::string flagsStr = flags; + if (flagsStr.find("clr") != std::string::npos) { + // There is a warning already issued when building the flags. + referenceNotManaged = false; } } - // Workaround for static library C# targets - if (referenceNotManaged && - dt->GetType() == cmStateEnums::STATIC_LIBRARY) { - referenceNotManaged = !dt->HasLanguage("CSharp", ""); - } - if (referenceNotManaged) { - e2.Element("ReferenceOutputAssembly", "false"); - e2.Element("CopyToOutputDirectory", "Never"); - } + } + // Workaround for static library C# targets + if (referenceNotManaged && dt->GetType() == cmStateEnums::STATIC_LIBRARY) { + referenceNotManaged = !dt->HasLanguage("CSharp", ""); + } + if (referenceNotManaged) { + e2.Element("ReferenceOutputAssembly", "false"); + e2.Element("CopyToOutputDirectory", "Never"); } } } diff --git a/Tests/CMakeCommands/target_link_options/CMakeLists.txt b/Tests/CMakeCommands/target_link_options/CMakeLists.txt index c66cd37..3bb6ff3 100644 --- a/Tests/CMakeCommands/target_link_options/CMakeLists.txt +++ b/Tests/CMakeCommands/target_link_options/CMakeLists.txt @@ -15,5 +15,12 @@ if (NOT result MATCHES "-PRIVATE_FLAG") endif() get_target_property(result target_link_options_2 INTERFACE_LINK_OPTIONS) if (NOT result MATCHES "-INTERFACE_FLAG") - message(SEND_ERROR "target_link_options not populated the INTERFACE_LINK_OPTIONS target property") + message(SEND_ERROR "target_link_options not populated the INTERFACE_LINK_OPTIONS target property of shared library") +endif() + +add_library(target_link_options_3 STATIC EXCLUDE_FROM_ALL LinkOptionsLib.c) +target_link_options(target_link_options_3 INTERFACE -INTERFACE_FLAG) +get_target_property(result target_link_options_3 INTERFACE_LINK_OPTIONS) +if (NOT result MATCHES "-INTERFACE_FLAG") + message(SEND_ERROR "target_link_options not populated the INTERFACE_LINK_OPTIONS target property of static library") endif() diff --git a/Tests/CudaOnly/LinkSystemDeviceLibraries/main.cu b/Tests/CudaOnly/LinkSystemDeviceLibraries/main.cu index 7eecec1..2c7c388 100644 --- a/Tests/CudaOnly/LinkSystemDeviceLibraries/main.cu +++ b/Tests/CudaOnly/LinkSystemDeviceLibraries/main.cu @@ -3,6 +3,9 @@ #include <cuda_runtime.h> #include <iostream> +// this test only makes sense for versions of CUDA that ships +// static libraries that have separable compilation device symbols +#if __CUDACC_VER_MAJOR__ <= 9 __global__ void deviceCublasSgemm(int n, float alpha, float beta, const float* d_A, const float* d_B, float* d_C) @@ -22,6 +25,7 @@ __global__ void deviceCublasSgemm(int n, float alpha, float beta, cublasDestroy(cnpHandle); } +#endif int choose_cuda_device() { @@ -63,6 +67,7 @@ int main(int argc, char** argv) return 0; } +#if __CUDACC_VER_MAJOR__ <= 9 // initial values that will make sure that the cublasSgemm won't actually // do any work int n = 0; @@ -72,6 +77,7 @@ int main(int argc, char** argv) float* d_B = nullptr; float* d_C = nullptr; deviceCublasSgemm<<<1, 1>>>(n, alpha, beta, d_A, d_B, d_C); +#endif return 0; } diff --git a/Tests/RunCMake/Ninja/PreventTargetAliasesDupBuildRule.cmake b/Tests/RunCMake/Ninja/PreventTargetAliasesDupBuildRule.cmake new file mode 100644 index 0000000..da6f86a --- /dev/null +++ b/Tests/RunCMake/Ninja/PreventTargetAliasesDupBuildRule.cmake @@ -0,0 +1,41 @@ +cmake_minimum_required(VERSION 3.12) +project(Test LANGUAGES C) + +# fake launcher executable +set(input_launcher_executable ${CMAKE_CURRENT_BINARY_DIR}/fake_launcher_executable) +file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/fake_launcher_executable "") + +# application and executable name +set(application_target "HelloApp") +set(application_name "Hello") +set(executable_name "Hello") + +# target built in "<root>/bin" +add_executable(${application_target} hello.c) +set_target_properties(${application_target} PROPERTIES + OUTPUT_NAME ${executable_name} + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/bin + ) + +# configured launcher in "<root>" +set(configured_launcher_executable "${CMAKE_CURRENT_BINARY_DIR}/${application_name}") + +# create command to copy the launcher +add_custom_command( + DEPENDS + ${input_launcher_executable} + OUTPUT + ${configured_launcher_executable} + COMMAND + ${CMAKE_COMMAND} -E copy ${input_launcher_executable} ${configured_launcher_executable} + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMENT + "Configuring application launcher: ${application_name}" + ) + +add_custom_target(Configure${application_name}Launcher ALL + DEPENDS + ${application_target} + ${input_launcher_executable} + ${configured_launcher_executable} + ) diff --git a/Tests/RunCMake/Ninja/RunCMakeTest.cmake b/Tests/RunCMake/Ninja/RunCMakeTest.cmake index b6e6cd4..e0ddc9c 100644 --- a/Tests/RunCMake/Ninja/RunCMakeTest.cmake +++ b/Tests/RunCMake/Ninja/RunCMakeTest.cmake @@ -278,3 +278,10 @@ foreach(ninja_output_path_prefix "sub space" "sub") run_sub_cmake(SubDirPrefix "${ninja_output_path_prefix}") run_sub_cmake(CustomCommandWorkingDirectory "${ninja_output_path_prefix}") endforeach(ninja_output_path_prefix) + +function (run_PreventTargetAliasesDupBuildRule) + set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/PreventTargetAliasesDupBuildRule-build) + run_cmake(PreventTargetAliasesDupBuildRule) + run_ninja("${RunCMake_TEST_BINARY_DIR}" -w dupbuild=err) +endfunction () +run_PreventTargetAliasesDupBuildRule() diff --git a/Tests/RunCMake/export/ExportPropertiesUndefined.cmake b/Tests/RunCMake/export/ExportPropertiesUndefined.cmake new file mode 100644 index 0000000..aa529f2 --- /dev/null +++ b/Tests/RunCMake/export/ExportPropertiesUndefined.cmake @@ -0,0 +1,11 @@ +enable_language(CXX) +add_library(foo empty.cpp) +set_target_properties(foo PROPERTIES + EXPORT_PROPERTIES "NotDefinedProp" +) +export(TARGETS foo FILE "${CMAKE_CURRENT_BINARY_DIR}/foo.cmake") +install(TARGETS foo EXPORT fooExport + RUNTIME DESTINATION bin + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib +) diff --git a/Tests/RunCMake/export/RunCMakeTest.cmake b/Tests/RunCMake/export/RunCMakeTest.cmake index 10ced90..46bb1fc 100644 --- a/Tests/RunCMake/export/RunCMakeTest.cmake +++ b/Tests/RunCMake/export/RunCMakeTest.cmake @@ -8,3 +8,4 @@ run_cmake(NoExportSet) run_cmake(ForbiddenToExportInterfaceProperties) run_cmake(ForbiddenToExportImportedProperties) run_cmake(ForbiddenToExportPropertyWithGenExp) +run_cmake(ExportPropertiesUndefined) diff --git a/Tests/RunCMake/target_link_options/LINK_OPTIONS-interface-static-check.cmake b/Tests/RunCMake/target_link_options/LINK_OPTIONS-interface-static-check.cmake new file mode 100644 index 0000000..6c5ffdb --- /dev/null +++ b/Tests/RunCMake/target_link_options/LINK_OPTIONS-interface-static-check.cmake @@ -0,0 +1,4 @@ + +if (NOT actual_stdout MATCHES "BADFLAG_INTERFACE") + set (RunCMake_TEST_FAILED "Not found expected 'BADFLAG_INTERFACE'.") +endif() diff --git a/Tests/RunCMake/target_link_options/LINK_OPTIONS-interface-static-result.txt b/Tests/RunCMake/target_link_options/LINK_OPTIONS-interface-static-result.txt new file mode 100644 index 0000000..8d98f9d --- /dev/null +++ b/Tests/RunCMake/target_link_options/LINK_OPTIONS-interface-static-result.txt @@ -0,0 +1 @@ +.* diff --git a/Tests/RunCMake/target_link_options/LINK_OPTIONS.cmake b/Tests/RunCMake/target_link_options/LINK_OPTIONS.cmake index 84cf129..bb04841 100644 --- a/Tests/RunCMake/target_link_options/LINK_OPTIONS.cmake +++ b/Tests/RunCMake/target_link_options/LINK_OPTIONS.cmake @@ -22,6 +22,15 @@ add_executable(LinkOptions_consumer LinkOptionsExe.c) target_link_libraries(LinkOptions_consumer PRIVATE LinkOptions_producer) +# static library with INTERFACE_LINK_OPTIONS +add_library(LinkOptions_producer_static STATIC LinkOptionsLib.c) +target_link_options(LinkOptions_producer_static + INTERFACE ${pre}BADFLAG_INTERFACE${obj}) + +add_executable(LinkOptions_consumer_static LinkOptionsExe.c) +target_link_libraries(LinkOptions_consumer_static PRIVATE LinkOptions_producer_static) + + # static library with generator expression add_library(LinkOptions_static STATIC LinkOptionsLib.c) target_link_options(LinkOptions_static PRIVATE $<$<CONFIG:Release>:${pre}BADFLAG_RELEASE${obj}> diff --git a/Tests/RunCMake/target_link_options/RunCMakeTest.cmake b/Tests/RunCMake/target_link_options/RunCMakeTest.cmake index 39f580f..1eaa5d2 100644 --- a/Tests/RunCMake/target_link_options/RunCMakeTest.cmake +++ b/Tests/RunCMake/target_link_options/RunCMakeTest.cmake @@ -21,6 +21,7 @@ if (NOT CMAKE_C_COMPILER_ID STREQUAL "Intel") run_cmake_target(LINK_OPTIONS basic LinkOptions) run_cmake_target(LINK_OPTIONS interface LinkOptions_consumer) + run_cmake_target(LINK_OPTIONS interface-static LinkOptions_consumer_static) run_cmake_target(LINK_OPTIONS static LinkOptions_static --config Release) run_cmake_target(LINK_OPTIONS shared LinkOptions_shared --config Release) run_cmake_target(LINK_OPTIONS mod LinkOptions_mod --config Release) |