diff options
36 files changed, 285 insertions, 133 deletions
diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst index 3f49572..15eaece 100644 --- a/Help/manual/cmake-variables.7.rst +++ b/Help/manual/cmake-variables.7.rst @@ -118,6 +118,7 @@ Variables that Change Behavior /variable/CMAKE_DISABLE_FIND_PACKAGE_PackageName /variable/CMAKE_ERROR_DEPRECATED /variable/CMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION + /variable/CMAKE_EXPORT_COMPILE_COMMANDS /variable/CMAKE_EXPORT_NO_PACKAGE_REGISTRY /variable/CMAKE_SYSROOT /variable/CMAKE_FIND_APPBUNDLE diff --git a/Help/release/dev/ExternalProject-git-clone-o.rst b/Help/release/dev/ExternalProject-git-clone-o.rst new file mode 100644 index 0000000..c9ff3e1 --- /dev/null +++ b/Help/release/dev/ExternalProject-git-clone-o.rst @@ -0,0 +1,5 @@ +ExternalProject-git-clone-o +--------------------------- + +* The :module:`ExternalProject` module learned a new ``GIT_REMOTE_NAME`` + option to control the ``git clone --origin`` value. diff --git a/Help/release/dev/cmake-E-time-quoting.rst b/Help/release/dev/cmake-E-time-quoting.rst new file mode 100644 index 0000000..23b17c5 --- /dev/null +++ b/Help/release/dev/cmake-E-time-quoting.rst @@ -0,0 +1,7 @@ +cmake-E-time-quoting +-------------------- + +* The :manual:`cmake(1)` ``-E time`` command now properly passes arguments + with spaces or special characters through to the child process. This + may break scripts that worked around the bug with their own extra + quoting or escaping. diff --git a/Help/variable/CMAKE_EXPORT_COMPILE_COMMANDS.rst b/Help/variable/CMAKE_EXPORT_COMPILE_COMMANDS.rst new file mode 100644 index 0000000..8776279 --- /dev/null +++ b/Help/variable/CMAKE_EXPORT_COMPILE_COMMANDS.rst @@ -0,0 +1,30 @@ +CMAKE_EXPORT_COMPILE_COMMANDS +----------------------------- + +Enable/Disable output of compile commands during generation. + +If enabled, generates a ``compile_commands.json`` file containing the exact +compiler calls for all translation units of the project in machine-readable +form. The format of the JSON file looks like: + +.. code-block:: javascript + + [ + { + "directory": "/home/user/development/project", + "command": "/usr/bin/c++ ... -c ../foo/foo.cc", + "file": "../foo/foo.cc" + }, + + ... + + { + "directory": "/home/user/development/project", + "command": "/usr/bin/c++ ... -c ../foo/bar.cc", + "file": "../foo/bar.cc" + } + ] + +.. note:: + This option is implemented only by :ref:`Makefile Generators` + and the :generator:`Ninja`. It is ignored on other generators. diff --git a/Modules/ExternalProject.cmake b/Modules/ExternalProject.cmake index c822bdb..7070dc4 100644 --- a/Modules/ExternalProject.cmake +++ b/Modules/ExternalProject.cmake @@ -57,6 +57,8 @@ Create custom targets to build projects in external trees URL of git repo ``GIT_TAG <tag>`` Git branch name, commit id or tag + ``GIT_REMOTE_NAME <name>`` + The optional name of the remote, default to ``origin`` ``GIT_SUBMODULES <module>...`` Git submodules that shall be updated, all if empty ``HG_REPOSITORY <url>`` @@ -494,7 +496,7 @@ define_property(DIRECTORY PROPERTY "EP_UPDATE_DISCONNECTED" INHERITED "ExternalProject module." ) -function(_ep_write_gitclone_script script_filename source_dir git_EXECUTABLE git_repository git_tag git_submodules src_name work_dir gitclone_infofile gitclone_stampfile) +function(_ep_write_gitclone_script script_filename source_dir git_EXECUTABLE git_repository git_tag git_remote_name git_submodules src_name work_dir gitclone_infofile gitclone_stampfile) file(WRITE ${script_filename} "if(\"${git_tag}\" STREQUAL \"\") message(FATAL_ERROR \"Tag for git checkout should not be empty.\") @@ -524,7 +526,7 @@ set(error_code 1) set(number_of_tries 0) while(error_code AND number_of_tries LESS 3) execute_process( - COMMAND \"${git_EXECUTABLE}\" clone \"${git_repository}\" \"${src_name}\" + COMMAND \"${git_EXECUTABLE}\" clone --origin \"${git_remote_name}\" \"${git_repository}\" \"${src_name}\" WORKING_DIRECTORY \"${work_dir}\" RESULT_VARIABLE error_code ) @@ -645,7 +647,7 @@ endif() endfunction() -function(_ep_write_gitupdate_script script_filename git_EXECUTABLE git_tag git_submodules git_repository work_dir) +function(_ep_write_gitupdate_script script_filename git_EXECUTABLE git_tag git_remote_name git_submodules git_repository work_dir) if(NOT GIT_VERSION_STRING VERSION_LESS 1.7.6) set(git_stash_save_options --all --quiet) else() @@ -687,7 +689,7 @@ if(\"\${show_ref_output}\" MATCHES \"refs/remotes/${git_tag}\") set(git_remote \"\${CMAKE_MATCH_1}\") set(git_tag \"\${CMAKE_MATCH_2}\") else() - set(git_remote \"origin\") + set(git_remote \"${git_remote_name}\") set(git_tag \"${git_tag}\") endif() @@ -1228,9 +1230,9 @@ function(_ep_get_build_command name step cmd_var) set(cmd "${CMAKE_COMMAND}") endif() set(args --build ".") - if (CMAKE_CFG_INTDIR AND NOT CMAKE_CFG_INTDIR STREQUAL ".") - list(APPEND args --config "${CMAKE_CFG_INTDIR}") - endif () + if(CMAKE_CONFIGURATION_TYPES) + list(APPEND args --config $<CONFIG>) + endif() if(step STREQUAL "INSTALL") list(APPEND args --target install) endif() @@ -1238,6 +1240,9 @@ function(_ep_get_build_command name step cmd_var) if("x${step}x" STREQUAL "xTESTx") string(REGEX REPLACE "^(.*/)cmake([^/]*)$" "\\1ctest\\2" cmd "${cmd}") set(args "") + if(CMAKE_CONFIGURATION_TYPES) + list(APPEND args -C $<CONFIG>) + endif() endif() endif() else() @@ -1749,6 +1754,11 @@ function(_ep_add_download_command name) endif() get_property(git_submodules TARGET ${name} PROPERTY _EP_GIT_SUBMODULES) + get_property(git_remote_name TARGET ${name} PROPERTY _EP_GIT_REMOTE_NAME) + if(NOT git_remote_name) + set(git_remote_name "origin") + endif() + # For the download step, and the git clone operation, only the repository # should be recorded in a configured RepositoryInfo file. If the repo # changes, the clone script should be run again. But if only the tag @@ -1772,7 +1782,7 @@ function(_ep_add_download_command name) # The script will delete the source directory and then call git clone. # _ep_write_gitclone_script(${tmp_dir}/${name}-gitclone.cmake ${source_dir} - ${GIT_EXECUTABLE} ${git_repository} ${git_tag} "${git_submodules}" ${src_name} ${work_dir} + ${GIT_EXECUTABLE} ${git_repository} ${git_tag} ${git_remote_name} "${git_submodules}" ${src_name} ${work_dir} ${stamp_dir}/${name}-gitinfo.txt ${stamp_dir}/${name}-gitclone-lastrun.txt ) set(comment "Performing download step (git clone) for '${name}'") @@ -1993,9 +2003,13 @@ function(_ep_add_update_command name) if(NOT git_tag) set(git_tag "master") endif() + get_property(git_remote_name TARGET ${name} PROPERTY _EP_GIT_REMOTE_NAME) + if(NOT git_remote_name) + set(git_remote_name "origin") + endif() get_property(git_submodules TARGET ${name} PROPERTY _EP_GIT_SUBMODULES) _ep_write_gitupdate_script(${tmp_dir}/${name}-gitupdate.cmake - ${GIT_EXECUTABLE} ${git_tag} "${git_submodules}" ${git_repository} ${work_dir} + ${GIT_EXECUTABLE} ${git_tag} ${git_remote_name} "${git_submodules}" ${git_repository} ${work_dir} ) set(cmd ${CMAKE_COMMAND} -P ${tmp_dir}/${name}-gitupdate.cmake) set(always 1) diff --git a/Modules/FindCUDA.cmake b/Modules/FindCUDA.cmake index ada5b8a..1674e2d 100644 --- a/Modules/FindCUDA.cmake +++ b/Modules/FindCUDA.cmake @@ -1474,6 +1474,7 @@ macro(CUDA_WRAP_SRCS cuda_target format generated_files) -P "${custom_target_script}" WORKING_DIRECTORY "${cuda_compile_intermediate_directory}" COMMENT "${cuda_build_comment_string}" + VERBATIM ) # Make sure the build system knows the file is generated. @@ -1592,6 +1593,7 @@ function(CUDA_LINK_SEPARABLE_COMPILATION_OBJECTS output_file cuda_target options COMMAND ${CUDA_NVCC_EXECUTABLE} ${nvcc_flags} -dlink ${object_files} -o ${output_file} ${flags} COMMENT "Building NVCC intermediate link file ${output_file_relative_path}" + VERBATIM ) else() get_filename_component(output_file_dir "${output_file}" DIRECTORY) @@ -1601,6 +1603,7 @@ function(CUDA_LINK_SEPARABLE_COMPILATION_OBJECTS output_file cuda_target options COMMAND ${CMAKE_COMMAND} -E echo "Building NVCC intermediate link file ${output_file_relative_path}" COMMAND ${CMAKE_COMMAND} -E make_directory "${output_file_dir}" COMMAND ${CUDA_NVCC_EXECUTABLE} ${nvcc_flags} ${flags} -dlink ${object_files} -o "${output_file}" + VERBATIM ) endif() endif() diff --git a/Modules/FindPkgConfig.cmake b/Modules/FindPkgConfig.cmake index eba6953..177e7b8 100644 --- a/Modules/FindPkgConfig.cmake +++ b/Modules/FindPkgConfig.cmake @@ -238,8 +238,8 @@ macro(_pkg_check_modules_internal _is_required _is_silent _no_cmake_path _no_cma if(NOT "${_extra_paths}" STREQUAL "") # Save the PKG_CONFIG_PATH environment variable, and add paths # from the CMAKE_PREFIX_PATH variables - set(_pkgconfig_path_old $ENV{PKG_CONFIG_PATH}) - set(_pkgconfig_path ${_pkgconfig_path_old}) + set(_pkgconfig_path_old "$ENV{PKG_CONFIG_PATH}") + set(_pkgconfig_path "${_pkgconfig_path_old}") if(NOT "${_pkgconfig_path}" STREQUAL "") file(TO_CMAKE_PATH "${_pkgconfig_path}" _pkgconfig_path) endif() @@ -285,7 +285,7 @@ macro(_pkg_check_modules_internal _is_required _is_silent _no_cmake_path _no_cma string(REPLACE ";" ":" _pkgconfig_path "${_pkgconfig_path}") string(REPLACE "\\ " " " _pkgconfig_path "${_pkgconfig_path}") endif() - set(ENV{PKG_CONFIG_PATH} ${_pkgconfig_path}) + set(ENV{PKG_CONFIG_PATH} "${_pkgconfig_path}") endif() # Unset variables @@ -401,7 +401,7 @@ macro(_pkg_check_modules_internal _is_required _is_silent _no_cmake_path _no_cma if(NOT "${_extra_paths}" STREQUAL "") # Restore the environment variable - set(ENV{PKG_CONFIG_PATH} ${_pkgconfig_path}) + set(ENV{PKG_CONFIG_PATH} "${_pkgconfig_path_old}") endif() unset(_extra_paths) diff --git a/Modules/GetPrerequisites.cmake b/Modules/GetPrerequisites.cmake index e4018b6..391e7f8 100644 --- a/Modules/GetPrerequisites.cmake +++ b/Modules/GetPrerequisites.cmake @@ -538,7 +538,7 @@ function(gp_resolved_file_type original_file file exepath dirs type_var) string(TOLOWER "$ENV{windir}" windir) file(TO_CMAKE_PATH "${windir}" windir) - if(lower MATCHES "^(${sysroot}/sys(tem|wow)|${windir}/sys(tem|wow)|(.*/)*msvc[^/]+dll)") + if(lower MATCHES "^(api-ms-win-|${sysroot}/sys(tem|wow)|${windir}/sys(tem|wow)|(.*/)*msvc[^/]+dll)") set(is_system 1) endif() @@ -566,7 +566,7 @@ function(gp_resolved_file_type original_file file exepath dirs type_var) string(TOLOWER "${env_windir}" windir) string(TOLOWER "${env_sysdir}" sysroot) - if(lower MATCHES "^(${sysroot}/sys(tem|wow)|${windir}/sys(tem|wow)|(.*/)*msvc[^/]+dll)") + if(lower MATCHES "^(api-ms-win-|${sysroot}/sys(tem|wow)|${windir}/sys(tem|wow)|(.*/)*msvc[^/]+dll)") set(is_system 1) endif() endif() diff --git a/Modules/Platform/WindowsPaths.cmake b/Modules/Platform/WindowsPaths.cmake index 658de3b..eafa8fa 100644 --- a/Modules/Platform/WindowsPaths.cmake +++ b/Modules/Platform/WindowsPaths.cmake @@ -28,46 +28,32 @@ set(__WINDOWS_PATHS_INCLUDED 1) # Windows 64-bit Binary: # ENV{ProgramFiles(x86)} = [C:\Program Files (x86)] # ENV{ProgramFiles} = [C:\Program Files] -# ENV{ProgramW6432} = <not set> -# (executed from cygwin): -# ENV{ProgramFiles(x86)} = <not set> -# ENV{ProgramFiles} = [C:\Program Files] -# ENV{ProgramW6432} = <not set> +# ENV{ProgramW6432} = [C:\Program Files] or <not set> # -# Windows 32-bit Binary: +# Windows 32-bit Binary on 64-bit Windows: # ENV{ProgramFiles(x86)} = [C:\Program Files (x86)] # ENV{ProgramFiles} = [C:\Program Files (x86)] # ENV{ProgramW6432} = [C:\Program Files] -# (executed from cygwin): -# ENV{ProgramFiles(x86)} = <not set> -# ENV{ProgramFiles} = [C:\Program Files (x86)] -# ENV{ProgramW6432} = [C:\Program Files] -if(DEFINED "ENV{ProgramW6432}") - # 32-bit binary on 64-bit windows. - # The 64-bit program files are in ProgramW6432. - list(APPEND CMAKE_SYSTEM_PREFIX_PATH "$ENV{ProgramW6432}") - - # The 32-bit program files are in ProgramFiles. - if(DEFINED "ENV{ProgramFiles}") - list(APPEND CMAKE_SYSTEM_PREFIX_PATH "$ENV{ProgramFiles}") +set(_programfiles "") +foreach(v "ProgramW6432" "ProgramFiles" "ProgramFiles(x86)") + if(DEFINED "ENV{${v}}") + file(TO_CMAKE_PATH "$ENV{${v}}" _env_programfiles) + list(APPEND _programfiles "${_env_programfiles}") + unset(_env_programfiles) endif() -else() - # 64-bit binary, or 32-bit binary on 32-bit windows. - if(DEFINED "ENV{ProgramFiles}") - list(APPEND CMAKE_SYSTEM_PREFIX_PATH "$ENV{ProgramFiles}") - endif() - set(programfilesx86 "ProgramFiles(x86)") - if(DEFINED "ENV{${programfilesx86}}") - # 64-bit binary. 32-bit program files are in ProgramFiles(x86). - list(APPEND CMAKE_SYSTEM_PREFIX_PATH "$ENV{${programfilesx86}}") - elseif(DEFINED "ENV{SystemDrive}") - # Guess the 32-bit program files location. - if(EXISTS "$ENV{SystemDrive}/Program Files (x86)") - list(APPEND CMAKE_SYSTEM_PREFIX_PATH - "$ENV{SystemDrive}/Program Files (x86)") +endforeach() +if(DEFINED "ENV{SystemDrive}") + foreach(d "Program Files" "Program Files (x86)") + if(EXISTS "$ENV{SystemDrive}/${d}") + list(APPEND _programfiles "$ENV{SystemDrive}/${d}") endif() - endif() + endforeach() +endif() +if(_programfiles) + list(REMOVE_DUPLICATES _programfiles) + list(APPEND CMAKE_SYSTEM_PREFIX_PATH ${_programfiles}) endif() +unset(_programfiles) # Add the CMake install location. get_filename_component(_CMAKE_INSTALL_DIR "${CMAKE_ROOT}" PATH) diff --git a/Modules/UseJava.cmake b/Modules/UseJava.cmake index 6146d78..adaba02 100644 --- a/Modules/UseJava.cmake +++ b/Modules/UseJava.cmake @@ -1212,7 +1212,7 @@ function (create_javah) set (_output_files) if (WIN32 AND NOT CYGWIN AND CMAKE_HOST_SYSTEM_NAME MATCHES "Windows") - set(_classpath_sep ";") + set(_classpath_sep "$<SEMICOLON>") else () set(_classpath_sep ":") endif() @@ -1242,7 +1242,7 @@ function (create_javah) endif() endforeach() string (REPLACE ";" "${_classpath_sep}" _classpath "${_classpath}") - list (APPEND _javah_options -classpath ${_classpath}) + list (APPEND _javah_options -classpath "${_classpath}") endif() if (_create_javah_OUTPUT_DIR) diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index b38f6eb..06c5a99 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 4) -set(CMake_VERSION_PATCH 20160119) +set(CMake_VERSION_PATCH 20160121) #set(CMake_VERSION_RC 1) diff --git a/Source/cmCacheManager.cxx b/Source/cmCacheManager.cxx index ce8af55..7466c29 100644 --- a/Source/cmCacheManager.cxx +++ b/Source/cmCacheManager.cxx @@ -64,12 +64,14 @@ bool cmCacheManager::LoadCache(const std::string& path, const char *realbuffer; std::string buffer; std::string entryKey; + unsigned int lineno = 0; while(fin) { // Format is key:type=value std::string helpString; CacheEntry e; cmSystemTools::GetLineFromStream(fin, buffer); + lineno++; realbuffer = buffer.c_str(); while(*realbuffer != '0' && (*realbuffer == ' ' || @@ -77,6 +79,7 @@ bool cmCacheManager::LoadCache(const std::string& path, *realbuffer == '\r' || *realbuffer == '\n')) { + if (*realbuffer == '\n') lineno++; realbuffer++; } // skip blank lines and comment lines @@ -96,6 +99,7 @@ bool cmCacheManager::LoadCache(const std::string& path, helpString += &realbuffer[2]; } cmSystemTools::GetLineFromStream(fin, buffer); + lineno++; realbuffer = buffer.c_str(); if(!fin) { @@ -138,8 +142,10 @@ bool cmCacheManager::LoadCache(const std::string& path, } else { - cmSystemTools::Error("Parse error in cache file ", cacheFile.c_str(), - ". Offending entry: ", realbuffer); + std::ostringstream error; + error << "Parse error in cache file " << cacheFile; + error << " on line " << lineno << ". Offending entry: " << realbuffer; + cmSystemTools::Error(error.str().c_str()); } } this->CacheMajorVersion = 0; diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index 2126c71..c50bf66 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -1850,7 +1850,7 @@ int cmGlobalGenerator::Build( !makeCommand.empty() && cmSystemTools::LowerCase( cmSystemTools::GetFilenameName(makeCommand[0])) == "vcexpress.exe") { - outputflag = cmSystemTools::OUTPUT_NORMAL; + outputflag = cmSystemTools::OUTPUT_FORWARD; } // should we do a clean first? diff --git a/Source/cmInstallTargetGenerator.cxx b/Source/cmInstallTargetGenerator.cxx index 1158a27..5e88fa2 100644 --- a/Source/cmInstallTargetGenerator.cxx +++ b/Source/cmInstallTargetGenerator.cxx @@ -791,18 +791,10 @@ cmInstallTargetGenerator } // Write a rule to run chrpath to set the install-tree RPATH - if(newRpath.empty()) - { - os << indent << "file(RPATH_REMOVE\n" - << indent << " FILE \"" << toDestDirPath << "\")\n"; - } - else - { - os << indent << "file(RPATH_CHANGE\n" - << indent << " FILE \"" << toDestDirPath << "\"\n" - << indent << " OLD_RPATH \"" << oldRpath << "\"\n" - << indent << " NEW_RPATH \"" << newRpath << "\")\n"; - } + os << indent << "file(RPATH_CHANGE\n" + << indent << " FILE \"" << toDestDirPath << "\"\n" + << indent << " OLD_RPATH \"" << oldRpath << "\"\n" + << indent << " NEW_RPATH \"" << newRpath << "\")\n"; } } diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index 008272c..3ba7287 100644 --- a/Source/cmSystemTools.cxx +++ b/Source/cmSystemTools.cxx @@ -17,6 +17,7 @@ #include <time.h> #include <string.h> #include <stdlib.h> +#include <assert.h> #ifdef __QNX__ # include <malloc.h> /* for malloc/free on QNX */ #endif @@ -660,14 +661,6 @@ bool cmSystemTools::RunSingleCommand(std::vector<std::string>const& command, argv.push_back(a->c_str()); } argv.push_back(0); - if ( captureStdOut ) - { - *captureStdOut = ""; - } - if (captureStdErr && captureStdErr != captureStdOut) - { - *captureStdErr = ""; - } cmsysProcess* cp = cmsysProcess_New(); cmsysProcess_SetCommand(cp, &*argv.begin()); @@ -681,7 +674,16 @@ bool cmSystemTools::RunSingleCommand(std::vector<std::string>const& command, { cmsysProcess_SetPipeShared(cp, cmsysProcess_Pipe_STDOUT, 1); cmsysProcess_SetPipeShared(cp, cmsysProcess_Pipe_STDERR, 1); + captureStdOut = 0; + captureStdErr = 0; } + else if (outputflag == OUTPUT_MERGE || + (captureStdErr && captureStdErr == captureStdOut)) + { + cmsysProcess_SetOption(cp, cmsysProcess_Option_MergeOutput, 1); + captureStdErr = 0; + } + assert(!captureStdErr || captureStdErr != captureStdOut); cmsysProcess_SetTimeout(cp, timeout); cmsysProcess_Execute(cp); @@ -696,65 +698,50 @@ bool cmSystemTools::RunSingleCommand(std::vector<std::string>const& command, { while((pipe = cmsysProcess_WaitForData(cp, &data, &length, 0)) > 0) { - if(captureStdOut || captureStdErr || outputflag != OUTPUT_NONE) + // Translate NULL characters in the output into valid text. + // Visual Studio 7 puts these characters in the output of its + // build process. + for(int i=0; i < length; ++i) { - // Translate NULL characters in the output into valid text. - // Visual Studio 7 puts these characters in the output of its - // build process. - for(int i=0; i < length; ++i) + if(data[i] == '\0') { - if(data[i] == '\0') - { - data[i] = ' '; - } + data[i] = ' '; } } - if(pipe == cmsysProcess_Pipe_STDOUT || - (pipe == cmsysProcess_Pipe_STDERR && - captureStdOut == captureStdErr)) + + if (pipe == cmsysProcess_Pipe_STDOUT) { - if (captureStdOut) + if (outputflag != OUTPUT_NONE) { - tempStdOut.insert(tempStdOut.end(), data, data+length); + cmSystemTools::Stdout(data, length); } - } - else if(pipe == cmsysProcess_Pipe_STDERR) - { - if (captureStdErr) + if (captureStdOut) { - tempStdErr.insert(tempStdErr.end(), data, data+length); + tempStdOut.insert(tempStdOut.end(), data, data+length); } } - if(outputflag != OUTPUT_NONE) + else if (pipe == cmsysProcess_Pipe_STDERR) { - if(outputflag == OUTPUT_MERGE) + if (outputflag != OUTPUT_NONE) { - cmSystemTools::Stdout(data, length); + cmSystemTools::Stderr(data, length); } - else + if (captureStdErr) { - if(pipe == cmsysProcess_Pipe_STDERR) - { - cmSystemTools::Stderr(data, length); - } - else if(pipe == cmsysProcess_Pipe_STDOUT) - { - cmSystemTools::Stdout(data, length); - } + tempStdErr.insert(tempStdErr.end(), data, data+length); } } } } cmsysProcess_WaitForExit(cp, 0); - if ( captureStdOut && tempStdOut.begin() != tempStdOut.end()) + if (captureStdOut) { - captureStdOut->append(&*tempStdOut.begin(), tempStdOut.size()); + captureStdOut->assign(tempStdOut.begin(), tempStdOut.end()); } - if ( captureStdErr && captureStdErr != captureStdOut && - tempStdErr.begin() != tempStdErr.end()) + if (captureStdErr) { - captureStdErr->append(&*tempStdErr.begin(), tempStdErr.size()); + captureStdErr->assign(tempStdErr.begin(), tempStdErr.end()); } bool result = true; @@ -2565,6 +2552,7 @@ bool cmSystemTools::ChangeRPath(std::string const& file, *changed = false; } int rp_count = 0; + bool remove_rpath = true; cmSystemToolsRPathInfo rp[2]; { // Parse the ELF binary. @@ -2622,6 +2610,7 @@ bool cmSystemTools::ChangeRPath(std::string const& file, // If it contains the new rpath instead then it is okay. if(cmSystemToolsFindRPath(se[i]->Value, newRPath) != std::string::npos) { + remove_rpath = false; continue; } if(emsg) @@ -2642,13 +2631,30 @@ bool cmSystemTools::ChangeRPath(std::string const& file, rp[rp_count].Size = se[i]->Size; rp[rp_count].Name = se_name[i]; + std::string::size_type prefix_len = pos; + + // If oldRPath was at the end of the file's RPath, and newRPath is empty, + // we should remove the unnecessary ':' at the end. + if (newRPath.empty() && + pos > 0 && + se[i]->Value[pos - 1] == ':' && + pos + oldRPath.length() == se[i]->Value.length()) + { + prefix_len--; + } + // Construct the new value which preserves the part of the path // not being changed. - rp[rp_count].Value = se[i]->Value.substr(0, pos); + rp[rp_count].Value = se[i]->Value.substr(0, prefix_len); rp[rp_count].Value += newRPath; rp[rp_count].Value += se[i]->Value.substr(pos+oldRPath.length(), oldRPath.npos); + if (!rp[rp_count].Value.empty()) + { + remove_rpath = false; + } + // Make sure there is enough room to store the new rpath and at // least one null terminator. if(rp[rp_count].Size < rp[rp_count].Value.length()+1) @@ -2673,6 +2679,12 @@ bool cmSystemTools::ChangeRPath(std::string const& file, return true; } + // If the resulting rpath is empty, just remove the entire entry instead. + if (remove_rpath) + { + return cmSystemTools::RemoveRPath(file, emsg, changed); + } + { // Open the file for update. cmsys::ofstream f(file.c_str(), diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h index 9cafbec..f511ae4 100644 --- a/Source/cmSystemTools.h +++ b/Source/cmSystemTools.h @@ -203,7 +203,7 @@ public: * Output is controlled with outputflag. If outputflag is OUTPUT_NONE, no * user-viewable output from the program being run will be generated. * OUTPUT_MERGE is the legacy behaviour where stdout and stderr are merged - * into stdout. OUTPUT_NORMAL passes through the output to stdout/stderr as + * into stdout. OUTPUT_FORWARD copies the output to stdout/stderr as * it was received. OUTPUT_PASSTHROUGH passes through the original handles. * * If timeout is specified, the command will be terminated after @@ -223,7 +223,7 @@ public: { OUTPUT_NONE = 0, OUTPUT_MERGE, - OUTPUT_NORMAL, + OUTPUT_FORWARD, OUTPUT_PASSTHROUGH }; static bool RunSingleCommand(const char* command, diff --git a/Source/cmTargetLinkLibrariesCommand.cxx b/Source/cmTargetLinkLibrariesCommand.cxx index 435346a..5f3246a 100644 --- a/Source/cmTargetLinkLibrariesCommand.cxx +++ b/Source/cmTargetLinkLibrariesCommand.cxx @@ -432,8 +432,11 @@ cmTargetLinkLibrariesCommand::HandleLibrary(const std::string& lib, { std::string configLib = this->Target ->GetDebugGeneratorExpressions(lib, llt); - if (cmGeneratorExpression::IsValidTargetName(lib) - || cmGeneratorExpression::Find(lib) != std::string::npos) + if (cmGeneratorExpression::IsValidTargetName(configLib)) + { + configLib = "$<LINK_ONLY:$<TARGET_NAME:" + configLib + ">>"; + } + else if (cmGeneratorExpression::Find(configLib) != std::string::npos) { configLib = "$<LINK_ONLY:" + configLib + ">"; } diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 27ae685..09d4a90 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -762,13 +762,16 @@ void cmVisualStudio10TargetGenerator std::string mfcFlagValue = mfcFlag ? mfcFlag : "0"; std::string useOfMfcValue = "false"; - if(mfcFlagValue == "1") - { - useOfMfcValue = "Static"; - } - else if(mfcFlagValue == "2") + if(this->GeneratorTarget->GetType() <= cmState::OBJECT_LIBRARY) { - useOfMfcValue = "Dynamic"; + if(mfcFlagValue == "1") + { + useOfMfcValue = "Static"; + } + else if(mfcFlagValue == "2") + { + useOfMfcValue = "Dynamic"; + } } std::string mfcLine = "<UseOfMfc>"; mfcLine += useOfMfcValue + "</UseOfMfc>\n"; diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx index fb7b1f5..1dc304c 100644 --- a/Source/cmcmd.cxx +++ b/Source/cmcmd.cxx @@ -361,11 +361,10 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args) } // Now run the real compiler command and return its result value. - if(!cmSystemTools::RunSingleCommand(orig_cmd, 0, &stdErr, &ret, 0, + if(!cmSystemTools::RunSingleCommand(orig_cmd, 0, 0, &ret, 0, cmSystemTools::OUTPUT_PASSTHROUGH)) { - std::cerr << "Error running '" << orig_cmd[0] << "': " - << stdErr << "\n"; + std::cerr << "Error running '" << orig_cmd[0] << "'\n"; return 1; } return ret; @@ -555,7 +554,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args) // Clock command else if (args[1] == "time" && args.size() > 2) { - std::string command = cmJoin(cmMakeRange(args).advance(2), " "); + std::vector<std::string> command(args.begin()+2, args.end()); clock_t clock_start, clock_finish; time_t time_start, time_finish; @@ -563,7 +562,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args) time(&time_start); clock_start = clock(); int ret =0; - cmSystemTools::RunSingleCommand(command.c_str(), 0, 0, &ret); + cmSystemTools::RunSingleCommand(command, 0, 0, &ret); clock_finish = clock(); time(&time_finish); @@ -621,7 +620,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args) int retval = 0; int timeout = 0; if ( cmSystemTools::RunSingleCommand(command.c_str(), 0, 0, &retval, - directory.c_str(), cmSystemTools::OUTPUT_NORMAL, timeout) ) + directory.c_str(), cmSystemTools::OUTPUT_PASSTHROUGH, timeout) ) { return retval; } diff --git a/Tests/ExportImport/Export/CMakeLists.txt b/Tests/ExportImport/Export/CMakeLists.txt index dcba9ac..c2ecb0b 100644 --- a/Tests/ExportImport/Export/CMakeLists.txt +++ b/Tests/ExportImport/Export/CMakeLists.txt @@ -130,10 +130,15 @@ set_property(TARGET testLibCycleA PROPERTY LINK_INTERFACE_MULTIPLICITY 3) add_library(testLibNoSONAME SHARED testLibNoSONAME.c) set_property(TARGET testLibNoSONAME PROPERTY NO_SONAME 1) +cmake_policy(PUSH) +cmake_policy(SET CMP0022 NEW) # Test exporting dependent libraries into different exports add_library(testLibRequired testLibRequired.c) add_library(testLibDepends testLibDepends.c) target_link_libraries(testLibDepends LINK_PUBLIC testLibRequired) +add_library(testStaticLibRequiredPrivate testStaticLibRequiredPrivate.c) +target_link_libraries(testLibDepends PRIVATE testStaticLibRequiredPrivate) +cmake_policy(POP) macro(add_include_lib _libName) file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/${_libName}.c" "/* no content */\n") @@ -270,6 +275,7 @@ install(FILES DESTINATION include/testSharedLibRequiredUser ) +cmake_policy(PUSH) cmake_policy(SET CMP0022 NEW) add_library(testSharedLibRequiredUser2 SHARED testSharedLibRequiredUser2.cpp) generate_export_header(testSharedLibRequiredUser2) @@ -283,7 +289,7 @@ install(FILES "${CMAKE_CURRENT_BINARY_DIR}/testsharedlibrequireduser2_export.h" DESTINATION include/testSharedLibRequiredUser2 ) -cmake_policy(SET CMP0022 OLD) +cmake_policy(POP) add_library(testSharedLibDepends SHARED testSharedLibDepends.cpp) set_property(TARGET testSharedLibDepends APPEND PROPERTY @@ -311,6 +317,8 @@ target_link_libraries(testSharedLibDepends LINK_PUBLIC renamed_on_export) target_link_libraries(testSharedLibDepends LINK_INTERFACE_LIBRARIES $<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:$<TARGET_NAME:testSharedLibRequired>>) +cmake_policy(PUSH) +cmake_policy(SET CMP0022 OLD) add_library(cmp0022OLD SHARED cmp0022_vs6_1.cpp) generate_export_header(cmp0022OLD BASE_NAME cmp0022) target_include_directories(cmp0022OLD PUBLIC @@ -324,7 +332,7 @@ target_include_directories(cmp0022NEW PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR};${CMAKE_CURRENT_SOURCE_DIR}>" "$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/include/cmp0022>" ) -cmake_policy(SET CMP0022 OLD) +cmake_policy(POP) install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/cmp0022.h" "${CMAKE_CURRENT_BINARY_DIR}/cmp0022_export.h" @@ -388,6 +396,10 @@ install(TARGETS INCLUDES DESTINATION $<INSTALL_PREFIX>/include/$<TARGET_PROPERTY:NAME> ) +install(TARGETS + testStaticLibRequiredPrivate + EXPORT RequiredExp DESTINATION lib +) install(EXPORT RequiredExp NAMESPACE Req:: FILE testLibRequiredTargets.cmake DESTINATION lib/cmake/testLibRequired) file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/installIncludesTest") diff --git a/Tests/ExportImport/Export/testLibDepends.c b/Tests/ExportImport/Export/testLibDepends.c index fb5a002..3c7774ee 100644 --- a/Tests/ExportImport/Export/testLibDepends.c +++ b/Tests/ExportImport/Export/testLibDepends.c @@ -16,5 +16,10 @@ #endif extern int testLibRequired(void); +extern int testStaticLibRequiredPrivate(void); -int testLibDepends(void) { return testLibRequired(); } +int testLibDepends(void) { + return testLibRequired() + + testStaticLibRequiredPrivate() + ; +} diff --git a/Tests/ExportImport/Export/testStaticLibRequiredPrivate.c b/Tests/ExportImport/Export/testStaticLibRequiredPrivate.c new file mode 100644 index 0000000..28a2675 --- /dev/null +++ b/Tests/ExportImport/Export/testStaticLibRequiredPrivate.c @@ -0,0 +1 @@ +int testStaticLibRequiredPrivate(void) { return 0; } diff --git a/Tests/JavaJavah/C.cpp b/Tests/JavaJavah/C.cpp new file mode 100644 index 0000000..ec75f42 --- /dev/null +++ b/Tests/JavaJavah/C.cpp @@ -0,0 +1,10 @@ + +#include <jni.h> +#include <stdio.h> + +#include "C.h" + +JNIEXPORT void JNICALL Java_C_printName(JNIEnv *, jobject) +{ + printf("C\n"); +} diff --git a/Tests/JavaJavah/C.java b/Tests/JavaJavah/C.java new file mode 100644 index 0000000..54b1be2 --- /dev/null +++ b/Tests/JavaJavah/C.java @@ -0,0 +1,19 @@ +class C +{ + public C() + { + } + + public native void printName(); + + static { + try { + + System.loadLibrary("B"); + + } catch (UnsatisfiedLinkError e) { + System.err.println("Native code library failed to load.\n" + e); + System.exit(1); + } + } +} diff --git a/Tests/JavaJavah/CMakeLists.txt b/Tests/JavaJavah/CMakeLists.txt index 83b0ad0..071bf20 100644 --- a/Tests/JavaJavah/CMakeLists.txt +++ b/Tests/JavaJavah/CMakeLists.txt @@ -9,10 +9,13 @@ include (UseJava) # JNI support find_package(JNI) -add_jar(hello3 B.java HelloWorld2.java) -create_javah(TARGET B_javah CLASSES B CLASSPATH hello3) +add_jar(B1 B.java) +add_jar(C1 C.java) +create_javah(TARGET B_javah CLASSES B C CLASSPATH B1 C1) -add_library(B SHARED B.cpp) +add_jar(hello3 HelloWorld2.java) + +add_library(B SHARED B.cpp C.cpp) add_dependencies(B B_javah) target_include_directories(B PRIVATE ${CMAKE_CURRENT_BINARY_DIR} diff --git a/Tests/JavaJavah/HelloWorld2.java b/Tests/JavaJavah/HelloWorld2.java index faf7277..5ff710f 100644 --- a/Tests/JavaJavah/HelloWorld2.java +++ b/Tests/JavaJavah/HelloWorld2.java @@ -5,6 +5,11 @@ class HelloWorld2 B b; b = new B(); b.printName(); + + C c; + c = new C(); + c.printName(); + System.out.println("Hello World!"); } } diff --git a/Tests/RunCMake/CommandLine/E_time-no-arg-result.txt b/Tests/RunCMake/CommandLine/E_time-no-arg-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CommandLine/E_time-no-arg-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CommandLine/E_time-no-arg-stderr.txt b/Tests/RunCMake/CommandLine/E_time-no-arg-stderr.txt new file mode 100644 index 0000000..50d9b03 --- /dev/null +++ b/Tests/RunCMake/CommandLine/E_time-no-arg-stderr.txt @@ -0,0 +1,3 @@ +^CMake Error: cmake version .* +Usage: .* -E <command> \[arguments\.\.\.\] +Available commands: diff --git a/Tests/RunCMake/CommandLine/E_time-stdout.txt b/Tests/RunCMake/CommandLine/E_time-stdout.txt new file mode 100644 index 0000000..a51446a --- /dev/null +++ b/Tests/RunCMake/CommandLine/E_time-stdout.txt @@ -0,0 +1,3 @@ +^hello world +Elapsed time: [^ +]*$ diff --git a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake index e77ba1f..e3b73ff 100644 --- a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake +++ b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake @@ -12,6 +12,9 @@ run_cmake_command(E_echo_append ${CMAKE_COMMAND} -E echo_append) run_cmake_command(E_rename-no-arg ${CMAKE_COMMAND} -E rename) run_cmake_command(E_touch_nocreate-no-arg ${CMAKE_COMMAND} -E touch_nocreate) +run_cmake_command(E_time ${CMAKE_COMMAND} -E time ${CMAKE_COMMAND} -E echo "hello world") +run_cmake_command(E_time-no-arg ${CMAKE_COMMAND} -E time) + run_cmake_command(E___run_iwyu-no-iwyu ${CMAKE_COMMAND} -E __run_iwyu -- command-does-not-exist) run_cmake_command(E___run_iwyu-bad-iwyu ${CMAKE_COMMAND} -E __run_iwyu --iwyu=iwyu-does-not-exist -- command-does-not-exist) run_cmake_command(E___run_iwyu-no--- ${CMAKE_COMMAND} -E __run_iwyu --iwyu=iwyu-does-not-exist command-does-not-exist) @@ -33,6 +36,11 @@ run_cmake_command(build-bad-dir run_cmake_command(build-bad-generator ${CMAKE_COMMAND} --build ${RunCMake_SOURCE_DIR}/cache-bad-generator) +run_cmake_command(cache-bad-entry + ${CMAKE_COMMAND} --build ${RunCMake_SOURCE_DIR}/cache-bad-entry/) +run_cmake_command(cache-empty-entry + ${CMAKE_COMMAND} --build ${RunCMake_SOURCE_DIR}/cache-empty-entry/) + function(run_BuildDir) # Use a single build tree for a few tests without cleaning. set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/BuildDir-build) diff --git a/Tests/RunCMake/CommandLine/cache-bad-entry-result.txt b/Tests/RunCMake/CommandLine/cache-bad-entry-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CommandLine/cache-bad-entry-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CommandLine/cache-bad-entry-stderr.txt b/Tests/RunCMake/CommandLine/cache-bad-entry-stderr.txt new file mode 100644 index 0000000..150d2ca --- /dev/null +++ b/Tests/RunCMake/CommandLine/cache-bad-entry-stderr.txt @@ -0,0 +1 @@ +^CMake Error: Parse error in cache file .*/Tests/RunCMake/CommandLine/cache-bad-entry/CMakeCache.txt on line 7. Offending entry: BAD ENTRY.* diff --git a/Tests/RunCMake/CommandLine/cache-bad-entry/CMakeCache.txt b/Tests/RunCMake/CommandLine/cache-bad-entry/CMakeCache.txt new file mode 100644 index 0000000..75cd7c2 --- /dev/null +++ b/Tests/RunCMake/CommandLine/cache-bad-entry/CMakeCache.txt @@ -0,0 +1,10 @@ +# This is a comment + +// That was an empty line. This isn't. +EMPTY_LINE:BOOL=FALSE + +// Uhoh! Here it comes +BAD ENTRY + +// This is fine +GOOD_ENTRY:BOOL=TRUE diff --git a/Tests/RunCMake/CommandLine/cache-empty-entry-result.txt b/Tests/RunCMake/CommandLine/cache-empty-entry-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CommandLine/cache-empty-entry-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CommandLine/cache-empty-entry-stderr.txt b/Tests/RunCMake/CommandLine/cache-empty-entry-stderr.txt new file mode 100644 index 0000000..54f4452 --- /dev/null +++ b/Tests/RunCMake/CommandLine/cache-empty-entry-stderr.txt @@ -0,0 +1 @@ +^CMake Error: Parse error in cache file .*/Tests/RunCMake/CommandLine/cache-empty-entry/CMakeCache.txt on line 5. Offending entry:.* diff --git a/Tests/RunCMake/CommandLine/cache-empty-entry/CMakeCache.txt b/Tests/RunCMake/CommandLine/cache-empty-entry/CMakeCache.txt new file mode 100644 index 0000000..44da1c9 --- /dev/null +++ b/Tests/RunCMake/CommandLine/cache-empty-entry/CMakeCache.txt @@ -0,0 +1,7 @@ +// This is valid +VALID:BOOL=TRUE + +// This isn't + +// One final entry +FINAL:BOOL=TRUE |