summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Help/manual/cmake.1.rst4
-rw-r--r--Help/release/dev/get_filename_component-fix-program-split.rst9
-rw-r--r--Modules/CMakeGraphVizOptions.cmake14
-rw-r--r--Modules/FindPackageHandleStandardArgs.cmake2
-rw-r--r--Modules/Platform/Windows-NMcl.cmake4
-rw-r--r--Source/CMakeVersion.cmake2
-rw-r--r--Source/cmGetFilenameComponentCommand.cxx25
-rw-r--r--Source/cmGlobalVisualStudio71Generator.cxx14
-rw-r--r--Source/cmGlobalVisualStudio8Generator.cxx14
-rw-r--r--Source/cmSystemTools.cxx50
-rw-r--r--Source/cmSystemTools.h5
-rw-r--r--Source/kwsys/SystemTools.cxx60
-rw-r--r--Source/kwsys/SystemTools.hxx.in6
-rw-r--r--Tests/RunCMake/FPHSA/RunCMakeTest.cmake8
-rw-r--r--Tests/RunCMake/README.rst4
-rw-r--r--Tests/RunCMake/get_filename_component/KnownComponents.cmake11
-rwxr-xr-xbootstrap6
17 files changed, 142 insertions, 96 deletions
diff --git a/Help/manual/cmake.1.rst b/Help/manual/cmake.1.rst
index 8aece23..6eef6c6 100644
--- a/Help/manual/cmake.1.rst
+++ b/Help/manual/cmake.1.rst
@@ -69,11 +69,11 @@ Options
See `Find-Package Tool Mode`_.
``--graphviz=[file]``
- Generate graphviz of dependencies, see CMakeGraphVizOptions.cmake for more.
+ Generate graphviz of dependencies, see :module:`CMakeGraphVizOptions` for more.
Generate a graphviz input file that will contain all the library and
executable dependencies in the project. See the documentation for
- CMakeGraphVizOptions.cmake for more details.
+ :module:`CMakeGraphVizOptions` for more details.
``--system-information [file]``
Dump information about this system.
diff --git a/Help/release/dev/get_filename_component-fix-program-split.rst b/Help/release/dev/get_filename_component-fix-program-split.rst
new file mode 100644
index 0000000..55c8719
--- /dev/null
+++ b/Help/release/dev/get_filename_component-fix-program-split.rst
@@ -0,0 +1,9 @@
+get_filename_component-fix-program-split
+----------------------------------------
+
+* The :command:`get_filename_component` ``PROGRAM`` mode semantics
+ have been revised to not tolerate unquoted spaces in the path
+ to the program while also accepting arguments. While technically
+ incompatible with the old behavior, it is expected that behavior
+ under typical use cases with properly-quoted command-lines has
+ not changed.
diff --git a/Modules/CMakeGraphVizOptions.cmake b/Modules/CMakeGraphVizOptions.cmake
index 420e3a9..3976581 100644
--- a/Modules/CMakeGraphVizOptions.cmake
+++ b/Modules/CMakeGraphVizOptions.cmake
@@ -11,19 +11,19 @@
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#
# CMake
-# can generate graphviz files, showing the dependencies between the
+# can generate `graphviz <http://www.graphviz.org/>`_ files, showing the dependencies between the
# targets in a project and also external libraries which are linked
-# against. When CMake is run with the --graphviz=foo.dot option, it will
+# against. When CMake is run with the ``--graphviz=foo.dot`` option, it will
# produce:
#
-# * a foo.dot file showing all dependencies in the project
-# * a foo.dot.<target> file for each target, file showing on which other targets the respective target depends
-# * a foo.dot.<target>.dependers file, showing which other targets depend on the respective target
+# * a ``foo.dot`` file showing all dependencies in the project
+# * a ``foo.dot.<target>`` file for each target, file showing on which other targets the respective target depends
+# * a ``foo.dot.<target>.dependers`` file, showing which other targets depend on the respective target
#
# This can result in huge graphs. Using the file
-# CMakeGraphVizOptions.cmake the look and content of the generated
+# ``CMakeGraphVizOptions.cmake`` the look and content of the generated
# graphs can be influenced. This file is searched first in
-# ${CMAKE_BINARY_DIR} and then in ${CMAKE_SOURCE_DIR}. If found, it is
+# :variable:`CMAKE_BINARY_DIR` and then in :variable:`CMAKE_SOURCE_DIR`. If found, it is
# read and the variables set in it are used to adjust options for the
# generated graphviz files.
#
diff --git a/Modules/FindPackageHandleStandardArgs.cmake b/Modules/FindPackageHandleStandardArgs.cmake
index 7b08bea..67f6bd6 100644
--- a/Modules/FindPackageHandleStandardArgs.cmake
+++ b/Modules/FindPackageHandleStandardArgs.cmake
@@ -322,7 +322,7 @@ function(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FIRST_ARG)
endif ()
unset(_VERSION_HEAD)
else ()
- if (NOT ${_NAME}_FIND_VERSION VERSION_EQUAL VERSION)
+ if (NOT ${_NAME}_FIND_VERSION VERSION_EQUAL _FOUND_VERSION)
set(VERSION_MSG "Found unsuitable version \"${_FOUND_VERSION}\", but required is exact version \"${${_NAME}_FIND_VERSION}\"")
set(VERSION_OK FALSE)
else ()
diff --git a/Modules/Platform/Windows-NMcl.cmake b/Modules/Platform/Windows-NMcl.cmake
deleted file mode 100644
index 7add0b0..0000000
--- a/Modules/Platform/Windows-NMcl.cmake
+++ /dev/null
@@ -1,4 +0,0 @@
-# this is for the numega compiler which is really a front
-# end for visual studio, but adds memory checking code.
-
-include(Platform/Windows-cl)
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 9c1da41..8ba34f2 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 9)
-set(CMake_VERSION_PATCH 20170913)
+set(CMake_VERSION_PATCH 20170915)
#set(CMake_VERSION_RC 1)
diff --git a/Source/cmGetFilenameComponentCommand.cxx b/Source/cmGetFilenameComponentCommand.cxx
index c23684c..1b358ab 100644
--- a/Source/cmGetFilenameComponentCommand.cxx
+++ b/Source/cmGetFilenameComponentCommand.cxx
@@ -60,7 +60,30 @@ bool cmGetFilenameComponentCommand::InitialPass(
}
}
}
- cmSystemTools::SplitProgramFromArgs(filename, result, programArgs);
+
+ // First assume the path to the program was specified with no
+ // arguments and with no quoting or escaping for spaces.
+ // Only bother doing this if there is non-whitespace.
+ if (!cmSystemTools::TrimWhitespace(filename).empty()) {
+ result = cmSystemTools::FindProgram(filename);
+ }
+
+ // If that failed then assume a command-line string was given
+ // and split the program part from the rest of the arguments.
+ if (result.empty()) {
+ std::string program;
+ if (cmSystemTools::SplitProgramFromArgs(filename, program,
+ programArgs)) {
+ if (cmSystemTools::FileExists(program)) {
+ result = program;
+ } else {
+ result = cmSystemTools::FindProgram(program);
+ }
+ }
+ if (result.empty()) {
+ programArgs.clear();
+ }
+ }
} else if (args[2] == "EXT") {
result = cmSystemTools::GetFilenameExtension(filename);
} else if (args[2] == "NAME_WE") {
diff --git a/Source/cmGlobalVisualStudio71Generator.cxx b/Source/cmGlobalVisualStudio71Generator.cxx
index 624f9e5..3b45c90 100644
--- a/Source/cmGlobalVisualStudio71Generator.cxx
+++ b/Source/cmGlobalVisualStudio71Generator.cxx
@@ -200,10 +200,16 @@ void cmGlobalVisualStudio71Generator::WriteProjectConfigurations(
std::string guid = this->GetGUID(name);
for (std::vector<std::string>::const_iterator i = configs.begin();
i != configs.end(); ++i) {
- const char* dstConfig = target.GetProperty("MAP_IMPORTED_CONFIG_" +
- cmSystemTools::UpperCase(*i));
- if (dstConfig == nullptr) {
- dstConfig = i->c_str();
+ std::vector<std::string> mapConfig;
+ const char* dstConfig = i->c_str();
+ if (target.GetProperty("EXTERNAL_MSPROJECT")) {
+ if (const char* m = target.GetProperty("MAP_IMPORTED_CONFIG_" +
+ cmSystemTools::UpperCase(*i))) {
+ cmSystemTools::ExpandListArgument(m, mapConfig);
+ if (!mapConfig.empty()) {
+ dstConfig = mapConfig[0].c_str();
+ }
+ }
}
fout << "\t\t{" << guid << "}." << *i << ".ActiveCfg = " << dstConfig
<< "|" << platformName << std::endl;
diff --git a/Source/cmGlobalVisualStudio8Generator.cxx b/Source/cmGlobalVisualStudio8Generator.cxx
index 728ad2d..f56c78b 100644
--- a/Source/cmGlobalVisualStudio8Generator.cxx
+++ b/Source/cmGlobalVisualStudio8Generator.cxx
@@ -354,10 +354,16 @@ void cmGlobalVisualStudio8Generator::WriteProjectConfigurations(
std::string guid = this->GetGUID(name);
for (std::vector<std::string>::const_iterator i = configs.begin();
i != configs.end(); ++i) {
- const char* dstConfig = target.GetProperty("MAP_IMPORTED_CONFIG_" +
- cmSystemTools::UpperCase(*i));
- if (dstConfig == nullptr) {
- dstConfig = i->c_str();
+ std::vector<std::string> mapConfig;
+ const char* dstConfig = i->c_str();
+ if (target.GetProperty("EXTERNAL_MSPROJECT")) {
+ if (const char* m = target.GetProperty("MAP_IMPORTED_CONFIG_" +
+ cmSystemTools::UpperCase(*i))) {
+ cmSystemTools::ExpandListArgument(m, mapConfig);
+ if (!mapConfig.empty()) {
+ dstConfig = mapConfig[0].c_str();
+ }
+ }
}
fout << "\t\t{" << guid << "}." << *i << "|" << this->GetPlatformName()
<< ".ActiveCfg = " << dstConfig << "|"
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index fd9fb5e..4118664 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -603,6 +603,56 @@ std::vector<std::string> cmSystemTools::ParseArguments(const char* command)
return args;
}
+bool cmSystemTools::SplitProgramFromArgs(std::string const& command,
+ std::string& program,
+ std::string& args)
+{
+ const char* c = command.c_str();
+
+ // Skip leading whitespace.
+ while (isspace(static_cast<unsigned char>(*c))) {
+ ++c;
+ }
+
+ // Parse one command-line element up to an unquoted space.
+ bool in_escape = false;
+ bool in_double = false;
+ bool in_single = false;
+ for (; *c; ++c) {
+ if (in_single) {
+ if (*c == '\'') {
+ in_single = false;
+ } else {
+ program += *c;
+ }
+ } else if (in_escape) {
+ in_escape = false;
+ program += *c;
+ } else if (*c == '\\') {
+ in_escape = true;
+ } else if (in_double) {
+ if (*c == '"') {
+ in_double = false;
+ } else {
+ program += *c;
+ }
+ } else if (*c == '"') {
+ in_double = true;
+ } else if (*c == '\'') {
+ in_single = true;
+ } else if (isspace(static_cast<unsigned char>(*c))) {
+ break;
+ } else {
+ program += *c;
+ }
+ }
+
+ // The remainder of the command line holds unparsed arguments.
+ args = c;
+
+ return !in_single && !in_escape && !in_double;
+}
+
size_t cmSystemTools::CalculateCommandLineLengthLimit()
{
size_t sz =
diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h
index 9bec361..e7082e6 100644
--- a/Source/cmSystemTools.h
+++ b/Source/cmSystemTools.h
@@ -255,6 +255,11 @@ public:
static void ParseUnixCommandLine(const char* command,
std::vector<std::string>& args);
+ /** Split a command-line string into the parsed command and the unparsed
+ arguments. Returns false on unfinished quoting or escaping. */
+ static bool SplitProgramFromArgs(std::string const& command,
+ std::string& program, std::string& args);
+
/**
* Handle response file in an argument list and return a new argument list
* **/
diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx
index 560c19c..0a22d63 100644
--- a/Source/kwsys/SystemTools.cxx
+++ b/Source/kwsys/SystemTools.cxx
@@ -4102,66 +4102,6 @@ bool SystemTools::GetShortPath(const std::string& path, std::string& shortPath)
#endif
}
-void SystemTools::SplitProgramFromArgs(const std::string& path,
- std::string& program, std::string& args)
-{
- // see if this is a full path to a program
- // if so then set program to path and args to nothing
- if (SystemTools::FileExists(path)) {
- program = path;
- args = "";
- return;
- }
- // Try to find the program in the path, note the program
- // may have spaces in its name so we have to look for it
- std::vector<std::string> e;
- std::string findProg = SystemTools::FindProgram(path, e);
- if (!findProg.empty()) {
- program = findProg;
- args = "";
- return;
- }
-
- // Now try and peel off space separated chunks from the end of the string
- // so the largest path possible is found allowing for spaces in the path
- std::string dir = path;
- std::string::size_type spacePos = dir.rfind(' ');
- while (spacePos != std::string::npos) {
- std::string tryProg = dir.substr(0, spacePos);
- // See if the file exists
- if (SystemTools::FileExists(tryProg)) {
- program = tryProg;
- // remove trailing spaces from program
- std::string::size_type pos = program.size() - 1;
- while (program[pos] == ' ') {
- program.erase(pos);
- pos--;
- }
- args = dir.substr(spacePos, dir.size() - spacePos);
- return;
- }
- // Now try and find the program in the path
- findProg = SystemTools::FindProgram(tryProg, e);
- if (!findProg.empty()) {
- program = findProg;
- // remove trailing spaces from program
- std::string::size_type pos = program.size() - 1;
- while (program[pos] == ' ') {
- program.erase(pos);
- pos--;
- }
- args = dir.substr(spacePos, dir.size() - spacePos);
- return;
- }
- // move past the space for the next search
- spacePos--;
- spacePos = dir.rfind(' ', spacePos);
- }
-
- program = "";
- args = "";
-}
-
std::string SystemTools::GetCurrentDateTime(const char* format)
{
char buf[1024];
diff --git a/Source/kwsys/SystemTools.hxx.in b/Source/kwsys/SystemTools.hxx.in
index 1672e92..41a60d3 100644
--- a/Source/kwsys/SystemTools.hxx.in
+++ b/Source/kwsys/SystemTools.hxx.in
@@ -498,12 +498,6 @@ public:
static std::string GetFilenameName(const std::string&);
/**
- * Split a program from its arguments and handle spaces in the paths
- */
- static void SplitProgramFromArgs(const std::string& path,
- std::string& program, std::string& args);
-
- /**
* Return longest file extension of a full filename (dot included)
*/
static std::string GetFilenameExtension(const std::string&);
diff --git a/Tests/RunCMake/FPHSA/RunCMakeTest.cmake b/Tests/RunCMake/FPHSA/RunCMakeTest.cmake
index 1b71a31..dd73cd4 100644
--- a/Tests/RunCMake/FPHSA/RunCMakeTest.cmake
+++ b/Tests/RunCMake/FPHSA/RunCMakeTest.cmake
@@ -9,13 +9,13 @@ run_cmake(BadFoundVar)
set(RunCMake_TEST_OPTIONS "-DCMAKE_MODULE_PATH=${CMAKE_CURRENT_LIST_DIR}" "-DPseudo_VERSION=0")
run_cmake(any_version_find_0)
-# Find a package with more customary version number, without requestion a specific version and in
+# Find a package with more customary version number, without requesting a specific version and in
# the presence of a cache variable VERSION.
-set(RunCMake_TEST_OPTIONS "-DCMAKE_MODULE_PATH=${CMAKE_CURRENT_LIST_DIR}" "-DPseudoNoVersionVar_VERSION=1.2.3.4.5_SHOULD_BE_IGNORED" "-DVERSION=BAD_VERSION")
+set(RunCMake_TEST_OPTIONS "-DCMAKE_MODULE_PATH=${CMAKE_CURRENT_LIST_DIR}" "-DPseudoNoVersionVar_VERSION=1.2.3.4_SHOULD_BE_IGNORED" "-DVERSION=BAD_VERSION")
run_cmake(any_version_VERSION_cache_variable)
-# Find a package with a more customary version number, without requestion a specific version.
-set(RunCMake_TEST_OPTIONS "-DCMAKE_MODULE_PATH=${CMAKE_CURRENT_LIST_DIR}" "-DPseudo_VERSION=1.2.3.4.5")
+# Find a package with a more customary version number, without requesting a specific version.
+set(RunCMake_TEST_OPTIONS "-DCMAKE_MODULE_PATH=${CMAKE_CURRENT_LIST_DIR}" "-DPseudo_VERSION=1.2.3.4")
run_cmake(any_version)
# test EXACT mode with every subcomponent
diff --git a/Tests/RunCMake/README.rst b/Tests/RunCMake/README.rst
index 4aae4ae..08b51d9 100644
--- a/Tests/RunCMake/README.rst
+++ b/Tests/RunCMake/README.rst
@@ -47,11 +47,11 @@ but do not actually build anything. To add a test:
containing expected test results:
``<SubTest>-result.txt``
- Process result expected if not "0"
+ Regex matching expected process result, if not ``0``
``<SubTest>-stdout.txt``
Regex matching expected stdout content
``<SubTest>-stderr.txt``
- Regex matching expected stderr content, if not "^$"
+ Regex matching expected stderr content, if not ``^$``
``<SubTest>-check.cmake``
Custom result check.
diff --git a/Tests/RunCMake/get_filename_component/KnownComponents.cmake b/Tests/RunCMake/get_filename_component/KnownComponents.cmake
index 7dfb55d..ac77ac3 100644
--- a/Tests/RunCMake/get_filename_component/KnownComponents.cmake
+++ b/Tests/RunCMake/get_filename_component/KnownComponents.cmake
@@ -80,6 +80,17 @@ get_filename_component(test_program_name "/ arg1 arg2" PROGRAM
check("PROGRAM with args output: name" "${test_program_name}" "/")
check("PROGRAM with args output: args" "${test_program_args}" " arg1 arg2")
+get_filename_component(test_program_name " " PROGRAM)
+check("PROGRAM with just a space" "${test_program_name}" "")
+
+get_filename_component(test_program_name "${CMAKE_CURRENT_LIST_FILE}" PROGRAM)
+check("PROGRAM specified explicitly without quoting" "${test_program_name}" "${CMAKE_CURRENT_LIST_FILE}")
+
+get_filename_component(test_program_name "\"${CMAKE_CURRENT_LIST_FILE}\" arg1 arg2" PROGRAM
+ PROGRAM_ARGS test_program_args)
+check("PROGRAM specified explicitly with arguments: name" "${test_program_name}" "${CMAKE_CURRENT_LIST_FILE}")
+check("PROGRAM specified explicitly with arguments: args" "${test_program_args}" " arg1 arg2")
+
list(APPEND non_cache_vars test_program_name)
list(APPEND non_cache_vars test_program_args)
diff --git a/bootstrap b/bootstrap
index 430f53b..5afc43b 100755
--- a/bootstrap
+++ b/bootstrap
@@ -830,6 +830,12 @@ rm -f "${cmake_bootstrap_dir}/cmake_bootstrap.log"
rm -f "${cmake_bootstrap_dir}/cmConfigure.h${_tmp}"
rm -f "${cmake_bootstrap_dir}/cmVersionConfig.h${_tmp}"
+# If building in-source, remove any cmConfigure.h that may
+# have been created by a previous run of the bootstrap cmake.
+if [ -n "${cmake_in_source_build}" ]; then
+ rm -f "${cmake_source_dir}/Source/cmConfigure.h"
+fi
+
# If exist compiler flags, set them
cmake_c_flags=${CFLAGS}
cmake_cxx_flags=${CXXFLAGS}