diff options
23 files changed, 165 insertions, 24 deletions
diff --git a/Help/manual/cmake.1.rst b/Help/manual/cmake.1.rst index ff8c6c7..c2e6435 100644 --- a/Help/manual/cmake.1.rst +++ b/Help/manual/cmake.1.rst @@ -337,7 +337,7 @@ Available commands are: ``paxr`` (restricted pax, default), and ``zip``. ``time <command> [<args>...]`` - Run command and return elapsed time. + Run command and display elapsed time. ``touch <file>`` Touch a file. diff --git a/Help/release/dev/cache-newline.rst b/Help/release/dev/cache-newline.rst new file mode 100644 index 0000000..96900bb --- /dev/null +++ b/Help/release/dev/cache-newline.rst @@ -0,0 +1,7 @@ +cache-newline +------------- + +* Variables containing newlines in their values now get truncated before the + newline when they are written to the cache file. In addition, a warning + comment is written to the cache file, and a warning message is displayed to + the user on the console. diff --git a/Help/variable/CMAKE_AUTOMOC_MACRO_NAMES.rst b/Help/variable/CMAKE_AUTOMOC_MACRO_NAMES.rst index 5b79c40..2c8997b 100644 --- a/Help/variable/CMAKE_AUTOMOC_MACRO_NAMES.rst +++ b/Help/variable/CMAKE_AUTOMOC_MACRO_NAMES.rst @@ -12,7 +12,7 @@ information. The default value is ``Q_OBJECT;Q_GADGET;Q_NAMESPACE``. Example -------- +^^^^^^^ Let CMake know that source files that contain ``CUSTOM_MACRO`` must be ``moc`` processed as well:: diff --git a/Help/variable/CMAKE_CROSSCOMPILING.rst b/Help/variable/CMAKE_CROSSCOMPILING.rst index cf9865b..9e96769 100644 --- a/Help/variable/CMAKE_CROSSCOMPILING.rst +++ b/Help/variable/CMAKE_CROSSCOMPILING.rst @@ -1,8 +1,26 @@ CMAKE_CROSSCOMPILING -------------------- -Is CMake currently cross compiling. +Intended to indicate whether CMake is cross compiling, but note limitations +discussed below. -This variable will be set to true by CMake if CMake is cross -compiling. Specifically if the build platform is different from the -target platform. +This variable will be set to true by CMake if the :variable:`CMAKE_SYSTEM_NAME` +variable has been set manually (i.e. in a toolchain file or as a cache entry +from the :manual:`cmake <cmake(1)>` command line). In most cases, manually +setting :variable:`CMAKE_SYSTEM_NAME` will only be done when cross compiling, +since it will otherwise be given the same value as +:variable:`CMAKE_HOST_SYSTEM_NAME` if not manually set, which is correct for +the non-cross-compiling case. In the event that :variable:`CMAKE_SYSTEM_NAME` +is manually set to the same value as :variable:`CMAKE_HOST_SYSTEM_NAME`, then +``CMAKE_CROSSCOMPILING`` will still be set to true. + +Another case to be aware of is that builds targeting Apple platforms other than +macOS are handled differently to other cross compiling scenarios. Rather than +relying on :variable:`CMAKE_SYSTEM_NAME` to select the target platform, Apple +device builds use :variable:`CMAKE_OSX_SYSROOT` to select the appropriate SDK, +which indirectly determines the target platform. Furthermore, when using the +Xcode generator, developers can switch between device and simulator builds at +build time rather than having a single choice at configure time, so the concept +of whether the build is cross compiling or not is more complex. Therefore, the +use of ``CMAKE_CROSSCOMPILING`` is not recommended for projects targeting Apple +devices. diff --git a/Help/variable/CMAKE_LANG_COMPILER_EXTERNAL_TOOLCHAIN.rst b/Help/variable/CMAKE_LANG_COMPILER_EXTERNAL_TOOLCHAIN.rst index 5be935b..cbe3544 100644 --- a/Help/variable/CMAKE_LANG_COMPILER_EXTERNAL_TOOLCHAIN.rst +++ b/Help/variable/CMAKE_LANG_COMPILER_EXTERNAL_TOOLCHAIN.rst @@ -6,7 +6,7 @@ The external toolchain for cross-compiling, if supported. Some compiler toolchains do not ship their own auxiliary utilities such as archivers and linkers. The compiler driver may support a command-line argument to specify the location of such tools. -``CMAKE_<LANG>_COMPILER_EXTERNAL_TOOLCHAIN`` may be set to a path to a path to +``CMAKE_<LANG>_COMPILER_EXTERNAL_TOOLCHAIN`` may be set to a path to the external toolchain and will be passed to the compiler driver if supported. This variable may only be set in a toolchain file specified by diff --git a/Modules/FindOpenGL.cmake b/Modules/FindOpenGL.cmake index 9ccd46b..4d0786c 100644 --- a/Modules/FindOpenGL.cmake +++ b/Modules/FindOpenGL.cmake @@ -22,7 +22,6 @@ # Defined to the platform-specific OpenGL libraries if the system has OpenGL. # ``OpenGL::OpenGL`` # Defined to libOpenGL if the system is GLVND-based. -# ``OpenGL::GL`` # ``OpenGL::GLU`` # Defined if the system has GLU. # ``OpenGL::GLX`` diff --git a/Modules/FindOpenMP.cmake b/Modules/FindOpenMP.cmake index 893ddc6..ced092e 100644 --- a/Modules/FindOpenMP.cmake +++ b/Modules/FindOpenMP.cmake @@ -470,7 +470,7 @@ foreach(LANG IN LISTS OpenMP_FINDLIST) if(OpenMP_${LANG}_FLAGS) separate_arguments(_OpenMP_${LANG}_OPTIONS NATIVE_COMMAND "${OpenMP_${LANG}_FLAGS}") set_property(TARGET OpenMP::OpenMP_${LANG} PROPERTY - INTERFACE_COMPILE_OPTIONS "${_OpenMP_${LANG}_OPTIONS}") + INTERFACE_COMPILE_OPTIONS "$<$<COMPILE_LANGUAGE:${LANG}>:${_OpenMP_${LANG}_OPTIONS}>") unset(_OpenMP_${LANG}_OPTIONS) endif() if(OpenMP_${LANG}_LIBRARIES) diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 353ee61..b41f400 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 10) -set(CMake_VERSION_PATCH 20180119) +set(CMake_VERSION_PATCH 20180122) #set(CMake_VERSION_RC 1) diff --git a/Source/cmCacheManager.cxx b/Source/cmCacheManager.cxx index 44095ec..64aa46e 100644 --- a/Source/cmCacheManager.cxx +++ b/Source/cmCacheManager.cxx @@ -10,6 +10,7 @@ #include <string.h> #include "cmGeneratedFileStream.h" +#include "cmMessenger.h" #include "cmState.h" #include "cmSystemTools.h" #include "cmVersion.h" @@ -205,7 +206,8 @@ bool cmCacheManager::ReadPropertyEntry(std::string const& entryKey, return false; } -void cmCacheManager::WritePropertyEntries(std::ostream& os, CacheIterator i) +void cmCacheManager::WritePropertyEntries(std::ostream& os, CacheIterator i, + cmMessenger* messenger) { for (const char** p = this->PersistentProperties; *p; ++p) { if (const char* value = i.GetProperty(*p)) { @@ -221,11 +223,13 @@ void cmCacheManager::WritePropertyEntries(std::ostream& os, CacheIterator i) os << ":INTERNAL="; this->OutputValue(os, value); os << "\n"; + cmCacheManager::OutputNewlineTruncationWarning(os, key, value, + messenger); } } } -bool cmCacheManager::SaveCache(const std::string& path) +bool cmCacheManager::SaveCache(const std::string& path, cmMessenger* messenger) { std::string cacheFile = path; cacheFile += "/CMakeCache.txt"; @@ -316,7 +320,10 @@ bool cmCacheManager::SaveCache(const std::string& path) this->OutputKey(fout, i.first); fout << ":" << cmState::CacheEntryTypeToString(t) << "="; this->OutputValue(fout, ce.Value); - fout << "\n\n"; + fout << "\n"; + cmCacheManager::OutputNewlineTruncationWarning(fout, i.first, ce.Value, + messenger); + fout << "\n"; } } @@ -333,7 +340,7 @@ bool cmCacheManager::SaveCache(const std::string& path) } cmStateEnums::CacheEntryType t = i.GetType(); - this->WritePropertyEntries(fout, i); + this->WritePropertyEntries(fout, i, messenger); if (t == cmStateEnums::INTERNAL) { // Format is key:type=value if (const char* help = i.GetProperty("HELPSTRING")) { @@ -343,6 +350,8 @@ bool cmCacheManager::SaveCache(const std::string& path) fout << ":" << cmState::CacheEntryTypeToString(t) << "="; this->OutputValue(fout, i.GetValue()); fout << "\n"; + cmCacheManager::OutputNewlineTruncationWarning(fout, i.GetName(), + i.GetValue(), messenger); } } fout << "\n"; @@ -390,6 +399,19 @@ void cmCacheManager::OutputKey(std::ostream& fout, std::string const& key) void cmCacheManager::OutputValue(std::ostream& fout, std::string const& value) { + // look for and truncate newlines + std::string::size_type newline = value.find('\n'); + if (newline != std::string::npos) { + std::string truncated = value.substr(0, newline); + OutputValueNoNewlines(fout, truncated); + } else { + OutputValueNoNewlines(fout, value); + } +} + +void cmCacheManager::OutputValueNoNewlines(std::ostream& fout, + std::string const& value) +{ // if value has trailing space or tab, enclose it in single quotes if (!value.empty() && (value[value.size() - 1] == ' ' || value[value.size() - 1] == '\t')) { @@ -423,6 +445,50 @@ void cmCacheManager::OutputHelpString(std::ostream& fout, } } +void cmCacheManager::OutputWarningComment(std::ostream& fout, + std::string const& message, + bool wrapSpaces) +{ + std::string::size_type end = message.size(); + std::string oneLine; + std::string::size_type pos = 0; + for (std::string::size_type i = 0; i <= end; i++) { + if ((i == end) || (message[i] == '\n') || + ((i - pos >= 60) && (message[i] == ' ') && wrapSpaces)) { + fout << "# "; + if (message[pos] == '\n') { + pos++; + fout << "\\n"; + } + oneLine = message.substr(pos, i - pos); + fout << oneLine << "\n"; + pos = i; + } + } +} + +void cmCacheManager::OutputNewlineTruncationWarning(std::ostream& fout, + std::string const& key, + std::string const& value, + cmMessenger* messenger) +{ + if (value.find('\n') != std::string::npos) { + if (messenger) { + std::string message = "Value of "; + message += key; + message += " contained a newline; truncating"; + messenger->IssueMessage(cmake::WARNING, message); + } + + std::string comment = "WARNING: Value of "; + comment += key; + comment += " contained a newline and was truncated. Original value:"; + + OutputWarningComment(fout, comment, true); + OutputWarningComment(fout, value, false); + } +} + void cmCacheManager::RemoveCacheEntry(const std::string& key) { CacheEntryMap::iterator i = this->Cache.find(key); diff --git a/Source/cmCacheManager.h b/Source/cmCacheManager.h index 28cba85..73923d1 100644 --- a/Source/cmCacheManager.h +++ b/Source/cmCacheManager.h @@ -15,7 +15,7 @@ #include "cmPropertyMap.h" #include "cmStateTypes.h" -class cmake; +class cmMessenger; /** \class cmCacheManager * \brief Control class for cmake's cache @@ -108,7 +108,7 @@ public: std::set<std::string>& includes); ///! Save cache for given makefile. Saves to output path/CMakeCache.txt - bool SaveCache(const std::string& path); + bool SaveCache(const std::string& path, cmMessenger* messenger); ///! Delete the cache given bool DeleteCache(const std::string& path); @@ -218,16 +218,25 @@ protected: unsigned int CacheMinorVersion; private: - cmake* CMakeInstance; typedef std::map<std::string, CacheEntry> CacheEntryMap; static void OutputHelpString(std::ostream& fout, const std::string& helpString); + static void OutputWarningComment(std::ostream& fout, + std::string const& message, + bool wrapSpaces); + static void OutputNewlineTruncationWarning(std::ostream& fout, + std::string const& key, + std::string const& value, + cmMessenger* messenger); static void OutputKey(std::ostream& fout, std::string const& key); static void OutputValue(std::ostream& fout, std::string const& value); + static void OutputValueNoNewlines(std::ostream& fout, + std::string const& value); static const char* PersistentProperties[]; bool ReadPropertyEntry(std::string const& key, CacheEntry& e); - void WritePropertyEntries(std::ostream& os, CacheIterator i); + void WritePropertyEntries(std::ostream& os, CacheIterator i, + cmMessenger* messenger); CacheEntryMap Cache; // Only cmake and cmState should be able to add cache values diff --git a/Source/cmGeneratorExpressionEvaluationFile.cxx b/Source/cmGeneratorExpressionEvaluationFile.cxx index 87b6b34..c988969 100644 --- a/Source/cmGeneratorExpressionEvaluationFile.cxx +++ b/Source/cmGeneratorExpressionEvaluationFile.cxx @@ -13,6 +13,7 @@ #include "cmLocalGenerator.h" #include "cmMakefile.h" #include "cmSourceFile.h" +#include "cmSourceFileLocationKind.h" #include "cmSystemTools.h" #include "cmake.h" @@ -102,7 +103,8 @@ void cmGeneratorExpressionEvaluationFile::CreateOutputFile( for (std::string const& le : enabledLanguages) { std::string name = this->OutputFileExpr->Evaluate( lg, config, false, nullptr, nullptr, nullptr, le); - cmSourceFile* sf = lg->GetMakefile()->GetOrCreateSource(name); + cmSourceFile* sf = lg->GetMakefile()->GetOrCreateSource( + name, false, cmSourceFileLocationKind::Known); sf->SetProperty("GENERATED", "1"); gg->SetFilenameTargetDepends( diff --git a/Source/cmState.cxx b/Source/cmState.cxx index 5957b5b..00d7e9a 100644 --- a/Source/cmState.cxx +++ b/Source/cmState.cxx @@ -107,9 +107,9 @@ bool cmState::LoadCache(const std::string& path, bool internal, return this->CacheManager->LoadCache(path, internal, excludes, includes); } -bool cmState::SaveCache(const std::string& path) +bool cmState::SaveCache(const std::string& path, cmMessenger* messenger) { - return this->CacheManager->SaveCache(path); + return this->CacheManager->SaveCache(path, messenger); } bool cmState::DeleteCache(const std::string& path) diff --git a/Source/cmState.h b/Source/cmState.h index e03ad89..7282f0a 100644 --- a/Source/cmState.h +++ b/Source/cmState.h @@ -23,6 +23,7 @@ class cmCacheManager; class cmCommand; class cmPropertyDefinition; class cmStateSnapshot; +class cmMessenger; class cmState { @@ -59,7 +60,7 @@ public: std::set<std::string>& excludes, std::set<std::string>& includes); - bool SaveCache(const std::string& path); + bool SaveCache(const std::string& path, cmMessenger* messenger); bool DeleteCache(const std::string& path); diff --git a/Source/cmake.cxx b/Source/cmake.cxx index 2341dd6..480646e 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -1771,7 +1771,7 @@ bool cmake::LoadCache(const std::string& path, bool internal, bool cmake::SaveCache(const std::string& path) { - bool result = this->State->SaveCache(path); + bool result = this->State->SaveCache(path, this->GetMessenger()); static const char* entries[] = { "CMAKE_CACHE_MAJOR_VERSION", "CMAKE_CACHE_MINOR_VERSION", "CMAKE_CACHE_PATCH_VERSION", diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx index f660f43..2c3bda2 100644 --- a/Source/cmcmd.cxx +++ b/Source/cmcmd.cxx @@ -103,7 +103,7 @@ void CMakeCommandUsage(const char* program) << " sleep <number>... - sleep for given number of seconds\n" << " tar [cxt][vf][zjJ] file.tar [file/dir1 file/dir2 ...]\n" << " - create or extract a tar or zip archive\n" - << " time command [args...] - run command and return elapsed time\n" + << " time command [args...] - run command and display elapsed time\n" << " touch file - touch a file.\n" << " touch_nocreate file - touch a file but do not create it.\n" #if defined(_WIN32) && !defined(__CYGWIN__) diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index edd6c79..e440b7f 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -339,6 +339,7 @@ add_RunCMake_test(CPackInstallProperties) add_RunCMake_test(ExternalProject) add_RunCMake_test(FetchContent) add_RunCMake_test(CTestCommandLine) +add_RunCMake_test(CacheNewline) # Only run this test on unix platforms that support # symbolic links if(UNIX) diff --git a/Tests/RunCMake/CacheNewline/CMakeLists.txt b/Tests/RunCMake/CacheNewline/CMakeLists.txt new file mode 100644 index 0000000..93ee9df --- /dev/null +++ b/Tests/RunCMake/CacheNewline/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 3.5) +project(${RunCMake_TEST} NONE) +include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/CacheNewline/CacheNewline-check.cmake b/Tests/RunCMake/CacheNewline/CacheNewline-check.cmake new file mode 100644 index 0000000..6534f63 --- /dev/null +++ b/Tests/RunCMake/CacheNewline/CacheNewline-check.cmake @@ -0,0 +1,16 @@ +set(CACHE_EXPECTED_FILE "${RunCMake_TEST_SOURCE_DIR}/cache-regex.txt") +set(CACHE_ACTUAL_FILE "${RunCMake_BINARY_DIR}/CacheNewline-build/CMakeCache.txt") + +file(READ ${CACHE_EXPECTED_FILE} CACHE_EXPECTED) +string(REGEX REPLACE "\r\n" "\n" CACHE_EXPECTED "${CACHE_EXPECTED}") +string(REGEX REPLACE "\n+$" "" CACHE_EXPECTED "${CACHE_EXPECTED}") +file(READ ${CACHE_ACTUAL_FILE} CACHE_ACTUAL) +string(REGEX REPLACE "\r\n" "\n" CACHE_ACTUAL "${CACHE_ACTUAL}") +string(REGEX REPLACE "\n+$" "" CACHE_ACTUAL "${CACHE_ACTUAL}") + +if(NOT "${CACHE_ACTUAL}" MATCHES "${CACHE_EXPECTED}") + set(RunCMake_TEST_FAILED "${CACHE_ACTUAL_FILE} does not match ${CACHE_EXPECTED_FILE}: + +CMakeCache.txt contents = [\n${CACHE_ACTUAL}\n] +Expected = [\n${CACHE_EXPECTED}\n]") +endif() diff --git a/Tests/RunCMake/CacheNewline/CacheNewline-stderr.txt b/Tests/RunCMake/CacheNewline/CacheNewline-stderr.txt new file mode 100644 index 0000000..726c65c --- /dev/null +++ b/Tests/RunCMake/CacheNewline/CacheNewline-stderr.txt @@ -0,0 +1,2 @@ +CMake Warning: + Value of NEWLINE_VARIABLE contained a newline; truncating diff --git a/Tests/RunCMake/CacheNewline/CacheNewline.cmake b/Tests/RunCMake/CacheNewline/CacheNewline.cmake new file mode 100644 index 0000000..81851db --- /dev/null +++ b/Tests/RunCMake/CacheNewline/CacheNewline.cmake @@ -0,0 +1,5 @@ +cmake_minimum_required(VERSION 3.5) + +project(CacheNewlineTest NONE) + +set(NEWLINE_VARIABLE "a\nb" CACHE STRING "Offending entry") diff --git a/Tests/RunCMake/CacheNewline/RunCMakeTest.cmake b/Tests/RunCMake/CacheNewline/RunCMakeTest.cmake new file mode 100644 index 0000000..5e3d2d4 --- /dev/null +++ b/Tests/RunCMake/CacheNewline/RunCMakeTest.cmake @@ -0,0 +1,3 @@ +include(RunCMake) + +run_cmake(CacheNewline) diff --git a/Tests/RunCMake/CacheNewline/cache-regex.txt b/Tests/RunCMake/CacheNewline/cache-regex.txt new file mode 100644 index 0000000..b239dbc --- /dev/null +++ b/Tests/RunCMake/CacheNewline/cache-regex.txt @@ -0,0 +1,6 @@ +//Offending entry +NEWLINE_VARIABLE:STRING=a +# WARNING: Value of NEWLINE_VARIABLE contained a newline and was +# truncated\. Original value: +# a +# \\nb diff --git a/Utilities/IWYU/mapping.imp b/Utilities/IWYU/mapping.imp index 5408402..892cdcb 100644 --- a/Utilities/IWYU/mapping.imp +++ b/Utilities/IWYU/mapping.imp @@ -23,8 +23,11 @@ # HACK: check whether this can be removed with next iwyu release. { include: [ "<bits/shared_ptr.h>", private, "<memory>", public ] }, { include: [ "<bits/std_function.h>", private, "<functional>", public ] }, + { include: [ "<bits/stdint-intn.h>", private, "<stdint.h>", public ] }, + { include: [ "<bits/stdint-uintn.h>", private, "<stdint.h>", public ] }, { include: [ "<bits/time.h>", private, "<time.h>", public ] }, { include: [ "<bits/types/clock_t.h>", private, "<time.h>", public ] }, + { include: [ "<bits/types/mbstate_t.h>", private, "<wchar.h>", public ] }, { include: [ "<bits/types/struct_timespec.h>", private, "<time.h>", public ] }, { include: [ "<bits/types/struct_timeval.h>", private, "<time.h>", public ] }, { include: [ "<bits/types/struct_tm.h>", private, "<time.h>", public ] }, |