diff options
Diffstat (limited to 'Source')
-rw-r--r-- | Source/CMakeVersion.cmake | 2 | ||||
-rw-r--r-- | Source/CPack/IFW/cmCPackIFWInstaller.cxx | 17 | ||||
-rw-r--r-- | Source/CPack/IFW/cmCPackIFWInstaller.h | 3 | ||||
-rw-r--r-- | Source/CPack/cpack.cxx | 1 | ||||
-rw-r--r-- | Source/CursesDialog/ccmake.cxx | 1 | ||||
-rw-r--r-- | Source/QtDialog/CMakeSetup.cxx | 1 | ||||
-rw-r--r-- | Source/cmCoreTryCompile.cxx | 9 | ||||
-rw-r--r-- | Source/cmGeneratorExpressionNode.cxx | 9 | ||||
-rw-r--r-- | Source/cmGeneratorTarget.cxx | 30 | ||||
-rw-r--r-- | Source/cmGeneratorTarget.h | 3 | ||||
-rw-r--r-- | Source/cmMakefile.cxx | 10 | ||||
-rw-r--r-- | Source/cmNinjaNormalTargetGenerator.cxx | 14 | ||||
-rw-r--r-- | Source/cmSystemTools.cxx | 68 | ||||
-rw-r--r-- | Source/cmSystemTools.h | 2 | ||||
-rw-r--r-- | Source/cmakemain.cxx | 25 | ||||
-rw-r--r-- | Source/ctest.cxx | 1 |
16 files changed, 174 insertions, 22 deletions
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 1b34ba5..503bd6e 100644 --- a/Source/CMakeVersion.cmake +++ b/Source/CMakeVersion.cmake @@ -1,5 +1,5 @@ # CMake version number components. set(CMake_VERSION_MAJOR 3) set(CMake_VERSION_MINOR 14) -set(CMake_VERSION_PATCH 20190502) +set(CMake_VERSION_PATCH 20190508) #set(CMake_VERSION_RC 1) diff --git a/Source/CPack/IFW/cmCPackIFWInstaller.cxx b/Source/CPack/IFW/cmCPackIFWInstaller.cxx index 01e3ea4..a075a17 100644 --- a/Source/CPack/IFW/cmCPackIFWInstaller.cxx +++ b/Source/CPack/IFW/cmCPackIFWInstaller.cxx @@ -152,6 +152,15 @@ void cmCPackIFWInstaller::ConfigureFromOptions() } } + // StyleSheet + if (const char* option = this->GetOption("CPACK_IFW_PACKAGE_STYLE_SHEET")) { + if (cmSystemTools::FileExists(option)) { + this->StyleSheet = option; + } else { + this->printSkippedOptionWarning("CPACK_IFW_PACKAGE_STYLE_SHEET", option); + } + } + // WizardDefaultWidth if (const char* option = this->GetOption("CPACK_IFW_PACKAGE_WIZARD_DEFAULT_WIDTH")) { @@ -381,6 +390,14 @@ void cmCPackIFWInstaller::GenerateInstallerFile() xout.Element("WizardStyle", this->WizardStyle); } + // Stylesheet + if (!this->StyleSheet.empty()) { + std::string name = cmSystemTools::GetFilenameName(this->StyleSheet); + std::string path = this->Directory + "/config/" + name; + cmsys::SystemTools::CopyFileIfDifferent(this->StyleSheet, path); + xout.Element("StyleSheet", name); + } + // WizardDefaultWidth if (!this->WizardDefaultWidth.empty()) { xout.Element("WizardDefaultWidth", this->WizardDefaultWidth); diff --git a/Source/CPack/IFW/cmCPackIFWInstaller.h b/Source/CPack/IFW/cmCPackIFWInstaller.h index 37ad339..be51fa5 100644 --- a/Source/CPack/IFW/cmCPackIFWInstaller.h +++ b/Source/CPack/IFW/cmCPackIFWInstaller.h @@ -72,6 +72,9 @@ public: /// Wizard style name std::string WizardStyle; + /// Filename for a style sheet + std::string StyleSheet; + /// Wizard width std::string WizardDefaultWidth; diff --git a/Source/CPack/cpack.cxx b/Source/CPack/cpack.cxx index 3ceb824..58b9e70 100644 --- a/Source/CPack/cpack.cxx +++ b/Source/CPack/cpack.cxx @@ -98,6 +98,7 @@ static void cpackProgressCallback(const std::string& message, float /*unused*/) // this is CPack. int main(int argc, char const* const* argv) { + cmSystemTools::EnsureStdPipes(); #if defined(_WIN32) && defined(CMAKE_BUILD_WITH_CMAKE) // Replace streambuf so we can output Unicode to console cmsys::ConsoleBuf::Manager consoleOut(std::cout); diff --git a/Source/CursesDialog/ccmake.cxx b/Source/CursesDialog/ccmake.cxx index 745c6bb..7caed0c 100644 --- a/Source/CursesDialog/ccmake.cxx +++ b/Source/CursesDialog/ccmake.cxx @@ -67,6 +67,7 @@ void onsig(int /*unused*/) int main(int argc, char const* const* argv) { + cmSystemTools::EnsureStdPipes(); cmsys::Encoding::CommandLineArguments encoding_args = cmsys::Encoding::CommandLineArguments::Main(argc, argv); argc = encoding_args.argc(); diff --git a/Source/QtDialog/CMakeSetup.cxx b/Source/QtDialog/CMakeSetup.cxx index 8d9a50c..c9ebba8 100644 --- a/Source/QtDialog/CMakeSetup.cxx +++ b/Source/QtDialog/CMakeSetup.cxx @@ -55,6 +55,7 @@ Q_IMPORT_PLUGIN(QWindowsVistaStylePlugin); int main(int argc, char** argv) { + cmSystemTools::EnsureStdPipes(); cmsys::Encoding::CommandLineArguments encoding_args = cmsys::Encoding::CommandLineArguments::Main(argc, argv); int argc2 = encoding_args.argc(); diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx index 897f7a8..2f62db1 100644 --- a/Source/cmCoreTryCompile.cxx +++ b/Source/cmCoreTryCompile.cxx @@ -1052,7 +1052,14 @@ void cmCoreTryCompile::FindOutputFile(const std::string& targetName, } searchDirs.emplace_back("/Debug"); #if defined(__APPLE__) - std::string app = "/Debug/" + targetName + ".app"; + std::string app = "/" + targetName + ".app"; + if (config && config[0]) { + std::string tmp = "/"; + tmp += config + app; + searchDirs.push_back(std::move(tmp)); + } + std::string tmp = "/Debug" + app; + searchDirs.emplace_back(std::move(tmp)); searchDirs.push_back(std::move(app)); #endif searchDirs.emplace_back("/Development"); diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx index 06e02aa..8c6fb34 100644 --- a/Source/cmGeneratorExpressionNode.cxx +++ b/Source/cmGeneratorExpressionNode.cxx @@ -1961,7 +1961,8 @@ struct TargetOutputNameArtifactResultGetter<ArtifactNameTag> const GeneratorExpressionContent* /*unused*/) { return target->GetOutputName(context->Config, - cmStateEnums::RuntimeBinaryArtifact); + cmStateEnums::RuntimeBinaryArtifact) + + target->GetFilePostfix(context->Config); } }; @@ -1983,7 +1984,8 @@ struct TargetOutputNameArtifactResultGetter<ArtifactLinkerTag> target->HasImportLibrary(context->Config) ? cmStateEnums::ImportLibraryArtifact : cmStateEnums::RuntimeBinaryArtifact; - return target->GetOutputName(context->Config, artifact); + return target->GetOutputName(context->Config, artifact) + + target->GetFilePostfix(context->Config); } }; @@ -2023,7 +2025,8 @@ struct TargetOutputNameArtifactResultGetter<ArtifactPdbTag> return std::string(); } - return target->GetPDBOutputName(context->Config); + return target->GetPDBOutputName(context->Config) + + target->GetFilePostfix(context->Config); } }; diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index 3fb95bf..036a07d 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -491,6 +491,22 @@ std::string cmGeneratorTarget::GetFileSuffix( return suffix; } +std::string cmGeneratorTarget::GetFilePostfix(const std::string& config) const +{ + const char* postfix = nullptr; + if (!config.empty()) { + std::string configProp = cmSystemTools::UpperCase(config); + configProp += "_POSTFIX"; + postfix = this->GetProperty(configProp); + // Mac application bundles and frameworks have no postfix. + if (!this->IsImported() && postfix && + (this->IsAppBundleOnApple() || this->IsFrameworkOnApple())) { + postfix = nullptr; + } + } + return postfix ? postfix : std::string(); +} + const char* cmGeneratorTarget::GetFilePrefixInternal( cmStateEnums::ArtifactType artifact, const std::string& language) const { @@ -3930,17 +3946,7 @@ void cmGeneratorTarget::GetFullNameInternal( } // Compute the full name for main target types. - const char* configPostfix = nullptr; - if (!config.empty()) { - std::string configProp = cmSystemTools::UpperCase(config); - configProp += "_POSTFIX"; - configPostfix = this->GetProperty(configProp); - // Mac application bundles and frameworks have no postfix. - if (configPostfix && - (this->IsAppBundleOnApple() || this->IsFrameworkOnApple())) { - configPostfix = nullptr; - } - } + const std::string configPostfix = this->GetFilePostfix(config); // frameworks have directory prefix but no suffix std::string fw_prefix; @@ -3965,7 +3971,7 @@ void cmGeneratorTarget::GetFullNameInternal( outBase += this->GetOutputName(config, artifact); // Append the per-configuration postfix. - outBase += configPostfix ? configPostfix : ""; + outBase += configPostfix; // Name shared libraries with their version number on some platforms. if (const char* soversion = this->GetProperty("SOVERSION")) { diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h index 81f5255..0e0ee6a 100644 --- a/Source/cmGeneratorTarget.h +++ b/Source/cmGeneratorTarget.h @@ -543,6 +543,9 @@ public: cmStateEnums::ArtifactType artifact = cmStateEnums::RuntimeBinaryArtifact) const; + /** Get target file postfix */ + std::string GetFilePostfix(const std::string& config) const; + /** Clears cached meta data for local and external source files. * The meta data will be recomputed on demand. */ diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 3832427..6c390f7 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -1599,6 +1599,16 @@ void cmMakefile::Configure() } // if no project command is found, add one if (!hasProject) { + this->GetCMakeInstance()->IssueMessage( + MessageType::AUTHOR_WARNING, + "No project() command is present. The top-level CMakeLists.txt " + "file must contain a literal, direct call to the project() command. " + "Add a line of code such as\n" + " project(ProjectName)\n" + "near the top of the file, but after cmake_minimum_required().\n" + "CMake is pretending there is a \"project(Project)\" command on " + "the first line.", + this->Backtrace); cmListFileFunction project; project.Name.Lower = "project"; project.Arguments.emplace_back("Project", cmListFileArgument::Unquoted, diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx index af47fa7..ebb7c15 100644 --- a/Source/cmNinjaNormalTargetGenerator.cxx +++ b/Source/cmNinjaNormalTargetGenerator.cxx @@ -535,6 +535,20 @@ std::vector<std::string> cmNinjaNormalTargetGenerator::ComputeLinkCmd() std::string const& linkCmd = mf->GetRequiredDefinition(linkCmdVar); cmSystemTools::ExpandListArgument(linkCmd, linkCmds); } +#ifdef __APPLE__ + // On macOS ranlib truncates the fractional part of the static archive + // file modification time. If the archive and at least one contained + // object file were created within the same second this will make look + // the archive older than the object file. On subsequent ninja runs this + // leads to re-achiving and updating dependent targets. + // As a work-around we touch the archive after ranlib (see #19222). + { + std::string cmakeCommand = + this->GetLocalGenerator()->ConvertToOutputFormat( + cmSystemTools::GetCMakeCommand(), cmOutputConverter::SHELL); + linkCmds.push_back(cmakeCommand + " -E touch $TARGET_FILE"); + } +#endif return linkCmds; } case cmStateEnums::SHARED_LIBRARY: diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index bc853b7..17ed3f6 100644 --- a/Source/cmSystemTools.cxx +++ b/Source/cmSystemTools.cxx @@ -43,6 +43,7 @@ #include <assert.h> #include <ctype.h> #include <errno.h> +#include <fcntl.h> #include <iostream> #include <sstream> #include <stdio.h> @@ -56,8 +57,6 @@ # include <windows.h> // include wincrypt.h after windows.h # include <wincrypt.h> - -# include <fcntl.h> /* _O_TEXT */ #else # include <sys/time.h> # include <unistd.h> @@ -2007,6 +2006,71 @@ int cmSystemTools::WaitForLine(cmsysProcess* process, std::string& line, } } +#ifdef _WIN32 +static void EnsureStdPipe(DWORD fd) +{ + if (GetStdHandle(fd) != INVALID_HANDLE_VALUE) { + return; + } + SECURITY_ATTRIBUTES sa; + sa.nLength = sizeof(sa); + sa.lpSecurityDescriptor = NULL; + sa.bInheritHandle = TRUE; + + HANDLE h = CreateFileW( + L"NUL", + fd == STD_INPUT_HANDLE ? FILE_GENERIC_READ + : FILE_GENERIC_WRITE | FILE_READ_ATTRIBUTES, + FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, OPEN_EXISTING, 0, NULL); + + if (h == INVALID_HANDLE_VALUE) { + LPSTR message = NULL; + DWORD size = FormatMessageA( + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPSTR)&message, 0, NULL); + std::string msg = std::string(message, size); + LocalFree(message); + std::cerr << "failed to open NUL for missing stdio pipe: " << msg; + abort(); + } + + SetStdHandle(fd, h); +} + +void cmSystemTools::EnsureStdPipes() +{ + EnsureStdPipe(STD_INPUT_HANDLE); + EnsureStdPipe(STD_OUTPUT_HANDLE); + EnsureStdPipe(STD_ERROR_HANDLE); +} +#else +static void EnsureStdPipe(int fd) +{ + if (fcntl(fd, F_GETFD) != -1 || errno != EBADF) { + return; + } + + int f = open("/dev/null", fd == STDIN_FILENO ? O_RDONLY : O_WRONLY); + if (f == -1) { + perror("failed to open /dev/null for missing stdio pipe"); + abort(); + } + if (f != fd) { + dup2(f, fd); + close(f); + } +} + +void cmSystemTools::EnsureStdPipes() +{ + EnsureStdPipe(STDIN_FILENO); + EnsureStdPipe(STDOUT_FILENO); + EnsureStdPipe(STDERR_FILENO); +} +#endif + void cmSystemTools::DoNotInheritStdPipes() { #ifdef _WIN32 diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h index 05bd351..8a87a37 100644 --- a/Source/cmSystemTools.h +++ b/Source/cmSystemTools.h @@ -435,6 +435,8 @@ public: // not get stuck waiting for all the output on the pipes. static void DoNotInheritStdPipes(); + static void EnsureStdPipes(); + /** Copy the file create/access/modify times from the file named by the first argument to that named by the second. */ static bool CopyFileTime(const std::string& fromFile, diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx index 5631d10..e639c66 100644 --- a/Source/cmakemain.cxx +++ b/Source/cmakemain.cxx @@ -24,6 +24,7 @@ #endif #include <cassert> +#include <climits> #include <ctype.h> #include <iostream> #include <string.h> @@ -69,7 +70,7 @@ static const char* cmDocumentationUsageNote[][2] = { " --config <cfg> = For multi-configuration tools, choose <cfg>.\n" \ " --clean-first = Build target 'clean' first, then build.\n" \ " (To clean only, use --target 'clean'.)\n" \ - " --verbose, -v = Enable verbose output - if supported - including\n" \ + " --verbose, -v = Enable verbose output - if supported - including\n" \ " the build commands to be executed. \n" \ " -- = Pass remaining options to the native tool.\n" @@ -183,6 +184,7 @@ static void cmakemainProgressCallback(const std::string& m, float prog, int main(int ac, char const* const* av) { + cmSystemTools::EnsureStdPipes(); #if defined(_WIN32) && defined(CMAKE_BUILD_WITH_CMAKE) // Replace streambuf so we can output Unicode to console cmsys::ConsoleBuf::Manager consoleOut(std::cout); @@ -395,7 +397,14 @@ int extract_job_number(int& index, char const* current, char const* next, if (jobString.empty()) { jobs = cmake::DEFAULT_BUILD_PARALLEL_LEVEL; } else if (cmSystemTools::StringToULong(jobString.c_str(), &numJobs)) { - jobs = int(numJobs); + if (numJobs == 0) { + std::cerr + << "The <jobs> value requires a positive integer argument.\n\n"; + } else if (numJobs > INT_MAX) { + std::cerr << "The <jobs> value is too large.\n\n"; + } else { + jobs = int(numJobs); + } } else { std::cerr << "'" << command.substr(0, len_of_flag) << "' invalid number '" << jobString << "' given.\n\n"; @@ -507,7 +516,17 @@ static int do_build(int ac, char const* const* av) } else { unsigned long numJobs = 0; if (cmSystemTools::StringToULong(parallel.c_str(), &numJobs)) { - jobs = int(numJobs); + if (numJobs == 0) { + std::cerr << "The CMAKE_BUILD_PARALLEL_LEVEL environment variable " + "requires a positive integer argument.\n\n"; + dir.clear(); + } else if (numJobs > INT_MAX) { + std::cerr << "The CMAKE_BUILD_PARALLEL_LEVEL environment variable " + "is too large.\n\n"; + dir.clear(); + } else { + jobs = int(numJobs); + } } else { std::cerr << "'CMAKE_BUILD_PARALLEL_LEVEL' environment variable\n" << "invalid number '" << parallel << "' given.\n\n"; diff --git a/Source/ctest.cxx b/Source/ctest.cxx index 461021b..3b3630f 100644 --- a/Source/ctest.cxx +++ b/Source/ctest.cxx @@ -143,6 +143,7 @@ static const char* cmDocumentationOptions[][2] = { // this is a test driver program for cmCTest. int main(int argc, char const* const* argv) { + cmSystemTools::EnsureStdPipes(); #if defined(_WIN32) && defined(CMAKE_BUILD_WITH_CMAKE) // Replace streambuf so we can output Unicode to console cmsys::ConsoleBuf::Manager consoleOut(std::cout); |