diff options
34 files changed, 459 insertions, 25 deletions
diff --git a/Auxiliary/vim/syntax/cmake.vim b/Auxiliary/vim/syntax/cmake.vim index 715676d..53681a9 100644 --- a/Auxiliary/vim/syntax/cmake.vim +++ b/Auxiliary/vim/syntax/cmake.vim @@ -44,7 +44,7 @@ syn keyword cmakeModule \ contained syn keyword cmakeKWExternalProject - \ ALGO ALWAYS BINARY_DIR BUILD_ALWAYS BUILD_BYPRODUCTS BUILD_COMMAND BUILD_IN_SOURCE BYPRODUCTS CMAKE_ARGS CMAKE_CACHE_ARGS CMAKE_CACHE_DEFAULT_ARGS COMMAND COMMENT CONFIGURE_COMMAND CVS CVSROOT CVS_ CVS_MODULE CVS_REPOSITORY CVS_TAG DEPENDEES DEPENDERS DEPENDS DIRECTORY DOWNLOAD_COMMAND DOWNLOAD_DIR DOWNLOAD_NAME DOWNLOAD_NO_PROGRESS EP_BASE EP_INDEPENDENT_STEP_TARGETS EP_PREFIX EP_STEP_TARGETS EP_UPDATE_DISCONNECTED EXCLUDE_FROM_ALL EXCLUDE_FROM_MAIN FORCE GIT_REMOTE_NAME GIT_REPOSITORY GIT_SUBMODULES GIT_TAG HG_REPOSITORY HG_TAG INDEPENDENT INDEPENDENT_STEP_TARGETS INSTALL_COMMAND INSTALL_DIR JOB_POOLS LIST_SEPARATOR LOG LOG_BUILD LOG_CONFIGURE LOG_DOWNLOAD LOG_INSTALL LOG_TEST LOG_UPDATE NO_DEPENDS PATCH_COMMAND PREFIX PROPERTY SOURCE_DIR STAMP_DIR STEP_TARGETS SVN_ SVN_PASSWORD SVN_REPOSITORY SVN_REVISION SVN_TRUST_CERT SVN_USERNAME TEST_AFTER_INSTALL TEST_BEFORE_INSTALL TEST_COMMAND TEST_EXCLUDE_FROM_MAIN TIMEOUT TLS_CAINFO TLS_VERIFY TMP_DIR UPDATE_COMMAND UPDATE_DISCONNECTED URL URL_HASH USES_TERMINAL USES_TERMINAL_BUILD USES_TERMINAL_CONFIGURE USES_TERMINAL_DOWNLOAD USES_TERMINAL_INSTALL USES_TERMINAL_TEST USES_TERMINAL_UPDATE WORKING_DIRECTORY _COMMAND _DIR + \ ALGO ALWAYS BINARY_DIR BUILD_ALWAYS BUILD_BYPRODUCTS BUILD_COMMAND BUILD_IN_SOURCE BYPRODUCTS CMAKE_ARGS CMAKE_CACHE_ARGS CMAKE_CACHE_DEFAULT_ARGS COMMAND COMMENT CONFIGURE_COMMAND CVS CVSROOT CVS_ CVS_MODULE CVS_REPOSITORY CVS_TAG DEPENDEES DEPENDERS DEPENDS DIRECTORY DOWNLOAD_COMMAND DOWNLOAD_DIR DOWNLOAD_NAME DOWNLOAD_NO_PROGRESS EP_BASE EP_INDEPENDENT_STEP_TARGETS EP_PREFIX EP_STEP_TARGETS EP_UPDATE_DISCONNECTED EXCLUDE_FROM_ALL EXCLUDE_FROM_MAIN FORCE GIT_REMOTE_NAME GIT_REPOSITORY GIT_SUBMODULES GIT_TAG HG_REPOSITORY HG_TAG INDEPENDENT INDEPENDENT_STEP_TARGETS INSTALL_COMMAND INSTALL_DIR JOB_POOLS LIST_SEPARATOR LOG LOG_BUILD LOG_CONFIGURE LOG_DOWNLOAD LOG_INSTALL LOG_TEST LOG_UPDATE NO_DEPENDS PATCH_COMMAND PREFIX PROPERTY SOURCE_DIR STAMP_DIR STEP_TARGETS SVN_ SVN_PASSWORD SVN_REPOSITORY SVN_REVISION SVN_TRUST_CERT SVN_USERNAME TEST_AFTER_INSTALL TEST_BEFORE_INSTALL TEST_COMMAND TEST_EXCLUDE_FROM_MAIN TIMEOUT TLS_CAINFO TLS_VERIFY TMP_DIR UPDATE_COMMAND UPDATE_DISCONNECTED URL URL_HASH HTTP_USERNAME HTTP_PASSWORD USES_TERMINAL USES_TERMINAL_BUILD USES_TERMINAL_CONFIGURE USES_TERMINAL_DOWNLOAD USES_TERMINAL_INSTALL USES_TERMINAL_TEST USES_TERMINAL_UPDATE WORKING_DIRECTORY _COMMAND _DIR \ contained syn keyword cmakeKWadd_compile_options diff --git a/CMakeLists.txt b/CMakeLists.txt index 4ef2ca2..c8bd063 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,7 +9,7 @@ # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the License for more information. #============================================================================= -cmake_minimum_required(VERSION 2.8.4 FATAL_ERROR) +cmake_minimum_required(VERSION 2.8.12.2 FATAL_ERROR) if(POLICY CMP0025) cmake_policy(SET CMP0025 NEW) endif() diff --git a/Help/command/file.rst b/Help/command/file.rst index f8727f0..77e9f62 100644 --- a/Help/command/file.rst +++ b/Help/command/file.rst @@ -225,6 +225,9 @@ Options to both ``DOWNLOAD`` and ``UPLOAD`` are: ``USERPWD <username>:<password>`` Set username and password for operation. +``HTTPHEADER <HTTP-header>`` + HTTP header for operation. Suboption can be repeated several times. + Additional options to ``DOWNLOAD`` are: ``EXPECTED_HASH ALGO=<value>`` diff --git a/Help/command/find_package.rst b/Help/command/find_package.rst index c44fe86..2cb1e5f 100644 --- a/Help/command/find_package.rst +++ b/Help/command/find_package.rst @@ -170,11 +170,21 @@ is acceptable the following variables are set: ``<package>_VERSION_COUNT`` number of version components, 0 to 4 -and the corresponding package configuration file is loaded. When -multiple package configuration files are available whose version files +and the corresponding package configuration file is loaded. +When multiple package configuration files are available whose version files claim compatibility with the version requested it is unspecified which -one is chosen. No attempt is made to choose a highest or closest -version number. +one is chosen: unless the variable :variable:`CMAKE_FIND_PACKAGE_SORT_ORDER` +is set no attempt is made to choose a highest or closest version number. + +To control the order in which ``find_package`` checks for compatibiliy use +the two variables :variable:`CMAKE_FIND_PACKAGE_SORT_ORDER` and +:variable:`CMAKE_FIND_PACKAGE_SORT_DIRECTION`. +For instance in order to select the highest version one can set:: + + SET(CMAKE_FIND_PACKAGE_SORT_ORDER NATURAL) + SET(CMAKE_FIND_PACKAGE_SORT_DIRECTION DEC) + +before calling ``find_package``. Config mode provides an elaborate interface and search procedure. Much of the interface is provided for completeness and for use diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst index 74c9265..9e0efe9 100644 --- a/Help/manual/cmake-variables.7.rst +++ b/Help/manual/cmake-variables.7.rst @@ -38,6 +38,8 @@ Variables that Provide Information /variable/CMAKE_EXTRA_GENERATOR /variable/CMAKE_EXTRA_SHARED_LIBRARY_SUFFIXES /variable/CMAKE_FIND_PACKAGE_NAME + /variable/CMAKE_FIND_PACKAGE_SORT_DIRECTION + /variable/CMAKE_FIND_PACKAGE_SORT_ORDER /variable/CMAKE_GENERATOR /variable/CMAKE_GENERATOR_PLATFORM /variable/CMAKE_GENERATOR_TOOLSET diff --git a/Help/release/dev/ExternalProject-http-credentials.rst b/Help/release/dev/ExternalProject-http-credentials.rst new file mode 100644 index 0000000..e3a362a --- /dev/null +++ b/Help/release/dev/ExternalProject-http-credentials.rst @@ -0,0 +1,5 @@ +ExternalProject-http-credentials +-------------------------------- + +* The :module:`ExternalProject` module gained ``HTTP_USERNAME`` and + ``HTTP_PASSWORD`` options to set http download credentials. diff --git a/Help/release/dev/file-curl-httpheader.rst b/Help/release/dev/file-curl-httpheader.rst new file mode 100644 index 0000000..2147d40 --- /dev/null +++ b/Help/release/dev/file-curl-httpheader.rst @@ -0,0 +1,5 @@ +file-curl-httpheader +-------------------- + +* The :command:`file(DOWNLOAD)` and :command:`file(UPLOAD)` commands + gained a ``HTTPHEADER <HTTP-header>`` option. diff --git a/Help/release/dev/find_package-dir-sort.rst b/Help/release/dev/find_package-dir-sort.rst new file mode 100644 index 0000000..67b93eb --- /dev/null +++ b/Help/release/dev/find_package-dir-sort.rst @@ -0,0 +1,13 @@ +find_package-dir-sort +--------------------- + +* The :command:`find_package` command gained the possibility of + sorting compatible libraries by ``NAME`` or by ``NATURAL`` sorting by + setting the two new variables :variable:`CMAKE_FIND_PACKAGE_SORT_ORDER` + and :variable:`CMAKE_FIND_PACKAGE_SORT_DIRECTION`. + +* Variable :variable:`CMAKE_FIND_PACKAGE_SORT_ORDER` was added to control + the sorting mode of the :command:`find_package` command. + +* Variable :variable:`CMAKE_FIND_PACKAGE_SORT_DIRECTION` was added to control + the sorting direction the :command:`find_package` command. diff --git a/Help/variable/CMAKE_FIND_PACKAGE_SORT_DIRECTION.rst b/Help/variable/CMAKE_FIND_PACKAGE_SORT_DIRECTION.rst new file mode 100644 index 0000000..99e4ec1 --- /dev/null +++ b/Help/variable/CMAKE_FIND_PACKAGE_SORT_DIRECTION.rst @@ -0,0 +1,16 @@ +CMAKE_FIND_PACKAGE_SORT_DIRECTION +--------------------------------- + +The sorting direction used by :variable:`CMAKE_FIND_PACKAGE_SORT_ORDER`. +It can assume one of the following values: + +``DEC`` + Default. Ordering is done in descending mode. + The highest folder found will be tested first. + +``ASC`` + Ordering is done in ascending mode. + The lowest folder found will be tested first. + +If :variable:`CMAKE_FIND_PACKAGE_SORT_ORDER` is not set or is set to ``NONE`` +this variable has no effect. diff --git a/Help/variable/CMAKE_FIND_PACKAGE_SORT_ORDER.rst b/Help/variable/CMAKE_FIND_PACKAGE_SORT_ORDER.rst new file mode 100644 index 0000000..ba5f3a8 --- /dev/null +++ b/Help/variable/CMAKE_FIND_PACKAGE_SORT_ORDER.rst @@ -0,0 +1,36 @@ +CMAKE_FIND_PACKAGE_SORT_ORDER +----------------------------- + +The default order for sorting packages found using :command:`find_package`. +It can assume one of the following values: + +``NONE`` + Default. No attempt is done to sort packages. + The first valid package found will be selected. + +``NAME`` + Sort packages lexicographically before selecting one. + +``NATURAL`` + Sort packages using natural order (see ``strverscmp(3)`` manual), + i.e. such that contiguous digits are compared as whole numbers. + +Natural sorting can be employed to return the highest version when multiple +versions of the same library are found by :command:`find_package`. For +example suppose that the following libraries have been found: + +* libX-1.1.0 +* libX-1.2.9 +* libX-1.2.10 + +By setting ``NATURAL`` order we can select the one with the highest +version number ``libX-1.2.10``. + +.. code-block:: cmake + + set(CMAKE_FIND_PACKAGE_SORT_ORDER NATURAL) + find_package(libX CONFIG) + +The sort direction can be controlled using the +:variable:`CMAKE_FIND_PACKAGE_SORT_DIRECTION` variable +(by default decrescent, e.g. lib-B will be tested before lib-A). diff --git a/Modules/ExternalProject-download.cmake.in b/Modules/ExternalProject-download.cmake.in index 91d74e0..0e82adb 100644 --- a/Modules/ExternalProject-download.cmake.in +++ b/Modules/ExternalProject-download.cmake.in @@ -135,6 +135,7 @@ foreach(i RANGE ${retry_number}) @TIMEOUT_ARGS@ STATUS status LOG log + @USERPWD_ARGS@ ) list(GET status 0 status_code) diff --git a/Modules/ExternalProject.cmake b/Modules/ExternalProject.cmake index 5ea309f..31fa459 100644 --- a/Modules/ExternalProject.cmake +++ b/Modules/ExternalProject.cmake @@ -75,6 +75,10 @@ Create custom targets to build projects in external trees Hash of file at URL ``URL_MD5 md5`` Equivalent to URL_HASH MD5=md5 + ``HTTP_USERNAME <username>`` + Username for download operation + ``HTTP_PASSWORD <username>`` + Password for download operation ``TLS_VERIFY <bool>`` Should certificate for https be checked ``TLS_CAINFO <file>`` @@ -858,7 +862,7 @@ endif() endfunction(_ep_write_gitupdate_script) -function(_ep_write_downloadfile_script script_filename REMOTE LOCAL timeout no_progress hash tls_verify tls_cainfo) +function(_ep_write_downloadfile_script script_filename REMOTE LOCAL timeout no_progress hash tls_verify tls_cainfo userpwd) if(timeout) set(TIMEOUT_ARGS TIMEOUT ${timeout}) set(TIMEOUT_MSG "${timeout} seconds") @@ -906,6 +910,12 @@ function(_ep_write_downloadfile_script script_filename REMOTE LOCAL timeout no_p set(TLS_CAINFO_CODE "set(CMAKE_TLS_CAINFO \"${tls_cainfo}\")") endif() + if(userpwd STREQUAL ":") + set(USERPWD_ARGS) + else() + set(USERPWD_ARGS USERPWD "${userpwd}") + endif() + # Used variables: # * TLS_VERIFY_CODE # * TLS_CAINFO_CODE @@ -916,6 +926,7 @@ function(_ep_write_downloadfile_script script_filename REMOTE LOCAL timeout no_p # * SHOW_PROGRESS # * TIMEOUT_ARGS # * TIMEOUT_MSG + # * USERPWD_ARGS configure_file( "${_ExternalProject_SELF_DIR}/ExternalProject-download.cmake.in" "${script_filename}" @@ -1919,8 +1930,10 @@ function(_ep_add_download_command name) get_property(no_progress TARGET ${name} PROPERTY _EP_DOWNLOAD_NO_PROGRESS) get_property(tls_verify TARGET ${name} PROPERTY _EP_TLS_VERIFY) get_property(tls_cainfo TARGET ${name} PROPERTY _EP_TLS_CAINFO) + get_property(http_username TARGET ${name} PROPERTY _EP_HTTP_USERNAME) + get_property(http_password TARGET ${name} PROPERTY _EP_HTTP_PASSWORD) set(download_script "${stamp_dir}/download-${name}.cmake") - _ep_write_downloadfile_script("${download_script}" "${url}" "${file}" "${timeout}" "${no_progress}" "${hash}" "${tls_verify}" "${tls_cainfo}") + _ep_write_downloadfile_script("${download_script}" "${url}" "${file}" "${timeout}" "${no_progress}" "${hash}" "${tls_verify}" "${tls_cainfo}" "${http_username}:${http_password}") set(cmd ${CMAKE_COMMAND} -P "${download_script}" COMMAND) if (no_extract) diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 0569e8e..09f55fa 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 6) -set(CMake_VERSION_PATCH 20160915) +set(CMake_VERSION_PATCH 20160916) #set(CMake_VERSION_RC 1) diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx index 2c226cd..c10f426 100644 --- a/Source/cmFileCommand.cxx +++ b/Source/cmFileCommand.cxx @@ -2483,6 +2483,8 @@ bool cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args) bool showProgress = false; std::string userpwd; + std::list<std::string> curl_headers; + while (i != args.end()) { if (*i == "TIMEOUT") { ++i; @@ -2572,6 +2574,13 @@ bool cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args) return false; } userpwd = *i; + } else if (*i == "HTTPHEADER") { + ++i; + if (i == args.end()) { + this->SetError("DOWNLOAD missing string for HTTPHEADER."); + return false; + } + curl_headers.push_back(*i); } else { // Do not return error for compatibility reason. std::string err = "Unexpected argument: "; @@ -2716,8 +2725,17 @@ bool cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args) check_curl_result(res, "DOWNLOAD cannot set user password: "); } + struct curl_slist* headers = CM_NULLPTR; + for (std::list<std::string>::const_iterator h = curl_headers.begin(); + h != curl_headers.end(); ++h) { + headers = ::curl_slist_append(headers, h->c_str()); + } + ::curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); + res = ::curl_easy_perform(curl); + ::curl_slist_free_all(headers); + /* always cleanup */ g_curl.release(); ::curl_easy_cleanup(curl); @@ -2798,6 +2816,8 @@ bool cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args) bool showProgress = false; std::string userpwd; + std::list<std::string> curl_headers; + while (i != args.end()) { if (*i == "TIMEOUT") { ++i; @@ -2838,6 +2858,13 @@ bool cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args) return false; } userpwd = *i; + } else if (*i == "HTTPHEADER") { + ++i; + if (i == args.end()) { + this->SetError("UPLOAD missing string for HTTPHEADER."); + return false; + } + curl_headers.push_back(*i); } else { // Do not return error for compatibility reason. std::string err = "Unexpected argument: "; @@ -2956,8 +2983,17 @@ bool cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args) check_curl_result(res, "UPLOAD cannot set user password: "); } + struct curl_slist* headers = CM_NULLPTR; + for (std::list<std::string>::const_iterator h = curl_headers.begin(); + h != curl_headers.end(); ++h) { + headers = ::curl_slist_append(headers, h->c_str()); + } + ::curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); + res = ::curl_easy_perform(curl); + ::curl_slist_free_all(headers); + /* always cleanup */ g_curl.release(); ::curl_easy_cleanup(curl); diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx index 7761759..405dce3 100644 --- a/Source/cmFindPackageCommand.cxx +++ b/Source/cmFindPackageCommand.cxx @@ -12,6 +12,7 @@ #include "cmFindPackageCommand.h" #include "cmAlgorithms.h" +#include <cmSystemTools.h> #include <cmsys/Directory.hxx> #include <cmsys/Encoding.hxx> #include <cmsys/RegularExpression.hxx> @@ -33,6 +34,45 @@ cmFindPackageCommand::PathLabel cmFindPackageCommand::PathLabel::Builds( cmFindPackageCommand::PathLabel cmFindPackageCommand::PathLabel::SystemRegistry("SYSTEM_PACKAGE_REGISTRY"); +struct StrverscmpGreater +{ + bool operator()(const std::string& lhs, const std::string& rhs) const + { + return cmSystemTools::strverscmp(lhs, rhs) > 0; + } +}; + +struct StrverscmpLesser +{ + bool operator()(const std::string& lhs, const std::string& rhs) const + { + return cmSystemTools::strverscmp(lhs, rhs) < 0; + } +}; + +void cmFindPackageCommand::Sort(std::vector<std::string>::iterator begin, + std::vector<std::string>::iterator end, + SortOrderType order, SortDirectionType dir) +{ + if (order == Name_order) { + if (dir == Dec) { + std::sort(begin, end, std::greater<std::string>()); + } else { + std::sort(begin, end); + } + } else if (order == Natural) + // natural order uses letters and numbers (contiguous numbers digit are + // compared such that e.g. 000 00 < 01 < 010 < 09 < 0 < 1 < 9 < 10 + { + if (dir == Dec) { + std::sort(begin, end, StrverscmpGreater()); + } else { + std::sort(begin, end, StrverscmpLesser()); + } + } + // else do not sort +} + cmFindPackageCommand::cmFindPackageCommand() { this->CMakePathName = "PACKAGE"; @@ -58,7 +98,8 @@ cmFindPackageCommand::cmFindPackageCommand() this->VersionFoundTweak = 0; this->VersionFoundCount = 0; this->RequiredCMakeVersion = 0; - + this->SortOrder = None; + this->SortDirection = Asc; this->AppendSearchPathGroups(); } @@ -135,6 +176,23 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args, this->NoSystemRegistry = true; } + // Check if Sorting should be enabled + if (const char* so = + this->Makefile->GetDefinition("CMAKE_FIND_PACKAGE_SORT_ORDER")) { + + if (strcmp(so, "NAME") == 0) { + this->SortOrder = Name_order; + } else if (strcmp(so, "NATURAL") == 0) { + this->SortOrder = Natural; + } else { + this->SortOrder = None; + } + } + if (const char* sd = + this->Makefile->GetDefinition("CMAKE_FIND_PACKAGE_SORT_DIRECTION")) { + this->SortDirection = strcmp(sd, "ASC") == 0 ? Asc : Dec; + } + // Find the current root path mode. this->SelectDefaultRootPathMode(); @@ -1666,17 +1724,33 @@ private: class cmFileListGeneratorProject : public cmFileListGeneratorBase { public: - cmFileListGeneratorProject(std::vector<std::string> const& names) + cmFileListGeneratorProject(std::vector<std::string> const& names, + cmFindPackageCommand::SortOrderType so, + cmFindPackageCommand::SortDirectionType sd) : cmFileListGeneratorBase() , Names(names) { + this->SetSort(so, sd); } cmFileListGeneratorProject(cmFileListGeneratorProject const& r) : cmFileListGeneratorBase() , Names(r.Names) { + this->SetSort(r.SortOrder, r.SortDirection); + } + + void SetSort(cmFindPackageCommand::SortOrderType o, + cmFindPackageCommand::SortDirectionType d) + { + SortOrder = o; + SortDirection = d; } +protected: + // sort parameters + cmFindPackageCommand::SortOrderType SortOrder; + cmFindPackageCommand::SortDirectionType SortDirection; + private: std::vector<std::string> const& Names; bool Search(std::string const& parent, cmFileList& lister) CM_OVERRIDE @@ -1698,6 +1772,13 @@ private: } } + // before testing the matches check if there is a specific sorting order to + // perform + if (this->SortOrder != cmFindPackageCommand::None) { + cmFindPackageCommand::Sort(matches.begin(), matches.end(), SortOrder, + SortDirection); + } + for (std::vector<std::string>::const_iterator i = matches.begin(); i != matches.end(); ++i) { if (this->Consider(parent + *i, lister)) { @@ -1895,7 +1976,8 @@ bool cmFindPackageCommand::SearchPrefix(std::string const& prefix_in) { cmFindPackageFileList lister(this); lister / cmFileListGeneratorFixed(prefix) / - cmFileListGeneratorProject(this->Names); + cmFileListGeneratorProject(this->Names, this->SortOrder, + this->SortDirection); if (lister.Search()) { return true; } @@ -1905,7 +1987,8 @@ bool cmFindPackageCommand::SearchPrefix(std::string const& prefix_in) { cmFindPackageFileList lister(this); lister / cmFileListGeneratorFixed(prefix) / - cmFileListGeneratorProject(this->Names) / + cmFileListGeneratorProject(this->Names, this->SortOrder, + this->SortDirection) / cmFileListGeneratorCaseInsensitive("cmake"); if (lister.Search()) { return true; @@ -1932,7 +2015,8 @@ bool cmFindPackageCommand::SearchPrefix(std::string const& prefix_in) lister / cmFileListGeneratorFixed(prefix) / cmFileListGeneratorEnumerate(common) / cmFileListGeneratorFixed("cmake") / - cmFileListGeneratorProject(this->Names); + cmFileListGeneratorProject(this->Names, this->SortOrder, + this->SortDirection); if (lister.Search()) { return true; } @@ -1943,7 +2027,8 @@ bool cmFindPackageCommand::SearchPrefix(std::string const& prefix_in) cmFindPackageFileList lister(this); lister / cmFileListGeneratorFixed(prefix) / cmFileListGeneratorEnumerate(common) / - cmFileListGeneratorProject(this->Names); + cmFileListGeneratorProject(this->Names, this->SortOrder, + this->SortDirection); if (lister.Search()) { return true; } @@ -1954,7 +2039,8 @@ bool cmFindPackageCommand::SearchPrefix(std::string const& prefix_in) cmFindPackageFileList lister(this); lister / cmFileListGeneratorFixed(prefix) / cmFileListGeneratorEnumerate(common) / - cmFileListGeneratorProject(this->Names) / + cmFileListGeneratorProject(this->Names, this->SortOrder, + this->SortDirection) / cmFileListGeneratorCaseInsensitive("cmake"); if (lister.Search()) { return true; @@ -1965,10 +2051,12 @@ bool cmFindPackageCommand::SearchPrefix(std::string const& prefix_in) { cmFindPackageFileList lister(this); lister / cmFileListGeneratorFixed(prefix) / - cmFileListGeneratorProject(this->Names) / + cmFileListGeneratorProject(this->Names, this->SortOrder, + this->SortDirection) / cmFileListGeneratorEnumerate(common) / cmFileListGeneratorFixed("cmake") / - cmFileListGeneratorProject(this->Names); + cmFileListGeneratorProject(this->Names, this->SortOrder, + this->SortDirection); if (lister.Search()) { return true; } @@ -1978,9 +2066,11 @@ bool cmFindPackageCommand::SearchPrefix(std::string const& prefix_in) { cmFindPackageFileList lister(this); lister / cmFileListGeneratorFixed(prefix) / - cmFileListGeneratorProject(this->Names) / + cmFileListGeneratorProject(this->Names, this->SortOrder, + this->SortDirection) / cmFileListGeneratorEnumerate(common) / - cmFileListGeneratorProject(this->Names); + cmFileListGeneratorProject(this->Names, this->SortOrder, + this->SortDirection); if (lister.Search()) { return true; } @@ -1990,9 +2080,11 @@ bool cmFindPackageCommand::SearchPrefix(std::string const& prefix_in) { cmFindPackageFileList lister(this); lister / cmFileListGeneratorFixed(prefix) / - cmFileListGeneratorProject(this->Names) / + cmFileListGeneratorProject(this->Names, this->SortOrder, + this->SortDirection) / cmFileListGeneratorEnumerate(common) / - cmFileListGeneratorProject(this->Names) / + cmFileListGeneratorProject(this->Names, this->SortOrder, + this->SortDirection) / cmFileListGeneratorCaseInsensitive("cmake"); if (lister.Search()) { return true; diff --git a/Source/cmFindPackageCommand.h b/Source/cmFindPackageCommand.h index 087107e..babdd5a 100644 --- a/Source/cmFindPackageCommand.h +++ b/Source/cmFindPackageCommand.h @@ -24,6 +24,27 @@ class cmFindPackageFileList; class cmFindPackageCommand : public cmFindCommon { public: + /*! A sorting order strategy to be applied to recovered package folders (see + * FIND_PACKAGE_SORT_ORDER)*/ + enum /*class*/ SortOrderType + { + None, + Name_order, + Natural + }; + /*! A sorting direction to be applied to recovered package folders (see + * FIND_PACKAGE_SORT_DIRECTION)*/ + enum /*class*/ SortDirectionType + { + Asc, + Dec + }; + + /*! sorts a given list of string based on the input sort parameters */ + static void Sort(std::vector<std::string>::iterator begin, + std::vector<std::string>::iterator end, SortOrderType order, + SortDirectionType dir); + cmFindPackageCommand(); /** @@ -156,6 +177,11 @@ private: std::vector<std::string> Configs; std::set<std::string> IgnoredPaths; + /*! the selected sortOrder (None by default)*/ + SortOrderType SortOrder; + /*! the selected sortDirection (Asc by default)*/ + SortDirectionType SortDirection; + struct ConfigFileInfo { std::string filename; diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index 4f8c036..1e21ac4 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -1162,7 +1162,28 @@ bool cmGeneratorTarget::NeedRelinkBeforeInstall( // If either a build or install tree rpath is set then the rpath // will likely change between the build tree and install tree and // this target must be relinked. - return this->HaveBuildTreeRPATH(config) || this->HaveInstallTreeRPATH(); + bool have_rpath = + this->HaveBuildTreeRPATH(config) || this->HaveInstallTreeRPATH(); + bool is_ninja = + this->LocalGenerator->GetGlobalGenerator()->GetName() == "Ninja"; + + if (have_rpath && is_ninja) { + std::ostringstream w; + /* clang-format off */ + w << + "The install of the " << this->GetName() << " target requires " + "changing an RPATH from the build tree, but this is not supported " + "with the Ninja generator unless on an ELF-based platform. The " + "CMAKE_BUILD_WITH_INSTALL_RPATH variable may be set to avoid this " + "relinking step." + ; + /* clang-format on */ + + cmake* cm = this->LocalGenerator->GetCMakeInstance(); + cm->IssueMessage(cmake::FATAL_ERROR, w.str(), this->GetBacktrace()); + } + + return have_rpath; } bool cmGeneratorTarget::IsChrpathUsed(const std::string& config) const diff --git a/Tests/CMakeLib/CMakeLists.txt b/Tests/CMakeLib/CMakeLists.txt index 7ef3c03..405917a 100644 --- a/Tests/CMakeLib/CMakeLists.txt +++ b/Tests/CMakeLib/CMakeLists.txt @@ -11,6 +11,7 @@ set(CMakeLib_TESTS testUTF8 testXMLParser testXMLSafe + testFindPackageCommand ) set(testRST_ARGS ${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/Tests/CMakeLib/testFindPackageCommand.cxx b/Tests/CMakeLib/testFindPackageCommand.cxx new file mode 100644 index 0000000..1cddb0e --- /dev/null +++ b/Tests/CMakeLib/testFindPackageCommand.cxx @@ -0,0 +1,76 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2011 Kitware, Inc., Insight Software Consortium + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#include "cmFindPackageCommand.h" + +#include <iostream> +#include <string> + +#define cmPassed(m) std::cout << "Passed: " << (m) << "\n" +#define cmFailed(m) \ + std::cout << "FAILED: " << (m) << "\n"; \ + failed = 1 + +int testFindPackageCommand(int /*unused*/, char* /*unused*/ []) +{ + int failed = 0; + + // ---------------------------------------------------------------------- + // Test cmFindPackage::Sort + std::vector<std::string> testString; + testString.push_back("lib-0.0"); + testString.push_back("lib-1.2"); + testString.push_back("lib-2.0"); + testString.push_back("lib-19.0.1"); + testString.push_back("lib-20.01.1"); + testString.push_back("lib-20.2.2a"); + + cmFindPackageCommand::Sort(testString.begin(), testString.end(), + cmFindPackageCommand::Natural, + cmFindPackageCommand::Asc); + if (!(testString[0] == "lib-0.0" && testString[1] == "lib-1.2" && + testString[2] == "lib-2.0" && testString[3] == "lib-19.0.1" && + testString[4] == "lib-20.01.1" && testString[5] == "lib-20.2.2a")) { + cmFailed("cmSystemTools::Sort fail with Natural ASC"); + } + + cmFindPackageCommand::Sort(testString.begin(), testString.end(), + cmFindPackageCommand::Natural, + cmFindPackageCommand::Dec); + if (!(testString[5] == "lib-0.0" && testString[4] == "lib-1.2" && + testString[3] == "lib-2.0" && testString[2] == "lib-19.0.1" && + testString[1] == "lib-20.01.1" && testString[0] == "lib-20.2.2a")) { + cmFailed("cmSystemTools::Sort fail with Natural ASC"); + } + + cmFindPackageCommand::Sort(testString.begin(), testString.end(), + cmFindPackageCommand::Name_order, + cmFindPackageCommand::Dec); + if (!(testString[5] == "lib-0.0" && testString[4] == "lib-1.2" && + testString[3] == "lib-19.0.1" && testString[2] == "lib-2.0" && + testString[1] == "lib-20.01.1" && testString[0] == "lib-20.2.2a")) { + cmFailed("cmSystemTools::Sort fail with Name DEC"); + } + + cmFindPackageCommand::Sort(testString.begin(), testString.end(), + cmFindPackageCommand::Name_order, + cmFindPackageCommand::Asc); + if (!(testString[0] == "lib-0.0" && testString[1] == "lib-1.2" && + testString[2] == "lib-19.0.1" && testString[3] == "lib-2.0" && + testString[4] == "lib-20.01.1" && testString[5] == "lib-20.2.2a")) { + cmFailed("cmSystemTools::Sort fail with Natural ASC"); + } + + if (!failed) { + cmPassed("cmSystemTools::Sort working"); + } + return failed; +} diff --git a/Tests/FindPackageTest/CMakeLists.txt b/Tests/FindPackageTest/CMakeLists.txt index 04bbbc6..1a6f204 100644 --- a/Tests/FindPackageTest/CMakeLists.txt +++ b/Tests/FindPackageTest/CMakeLists.txt @@ -633,3 +633,33 @@ endif() if(PACKAGE_VERSION_UNSUITABLE) message(SEND_ERROR "PACKAGE_VERSION_UNSUITABLE set, but must not be !") endif() + + +############################################################################ +##Test FIND_PACKAGE using sorting +set(CMAKE_PREFIX_PATH ${CMAKE_CURRENT_SOURCE_DIR}) +SET(CMAKE_FIND_PACKAGE_SORT_ORDER NAME) +SET(CMAKE_FIND_PACKAGE_SORT_DIRECTION ASC) + +set(SortLib_DIR "" CACHE FILEPATH "Wipe out find results for testing." FORCE) +FIND_PACKAGE(SortLib CONFIG) +IF (NOT "${SortLib_VERSION}" STREQUAL "3.1.1") + message(SEND_ERROR "FIND_PACKAGE_SORT_ORDER Name Asc! ${SortLib_VERSION}") +endif() +unset(SortLib_VERSION) + + +set(SortLib_DIR "" CACHE FILEPATH "Wipe out find results for testing." FORCE) +SET(CMAKE_FIND_PACKAGE_SORT_ORDER NATURAL) +SET(CMAKE_FIND_PACKAGE_SORT_DIRECTION DEC) +FIND_PACKAGE(SortLib CONFIG) +IF (NOT "${SortLib_VERSION}" STREQUAL "3.10.1") + message(SEND_ERROR "FIND_PACKAGE_SORT_ORDER Natural! Dec ${SortLib_VERSION}") +endif() +set(SortLib_DIR "" CACHE FILEPATH "Wipe out find results for testing." FORCE) +unset(SortLib_VERSION) + + +unset(CMAKE_FIND_PACKAGE_SORT_ORDER) +unset(CMAKE_FIND_PACKAGE_SORT_DIRECTION) +set(CMAKE_PREFIX_PATH ) diff --git a/Tests/FindPackageTest/SortLib-3.1.1/SortLibConfig.cmake b/Tests/FindPackageTest/SortLib-3.1.1/SortLibConfig.cmake new file mode 100644 index 0000000..c1f2088 --- /dev/null +++ b/Tests/FindPackageTest/SortLib-3.1.1/SortLibConfig.cmake @@ -0,0 +1,2 @@ +set(SORT_LIB_VERSION 3.1.1) +message("SortLib 3.1.1 config reached") diff --git a/Tests/FindPackageTest/SortLib-3.1.1/SortLibConfigVersion.cmake b/Tests/FindPackageTest/SortLib-3.1.1/SortLibConfigVersion.cmake new file mode 100644 index 0000000..fa927c7 --- /dev/null +++ b/Tests/FindPackageTest/SortLib-3.1.1/SortLibConfigVersion.cmake @@ -0,0 +1,9 @@ +set(PACKAGE_VERSION 3.1.1) +if(PACKAGE_FIND_VERSION_MAJOR EQUAL 3) + if(PACKAGE_FIND_VERSION_MINOR EQUAL 1) + set(PACKAGE_VERSION_COMPATIBLE 1) + if(PACKAGE_FIND_VERSION_PATCH EQUAL 1) + set(PACKAGE_VERSION_EXACT 1) + endif() + endif() +endif() diff --git a/Tests/FindPackageTest/SortLib-3.10.1/SortLibConfig.cmake b/Tests/FindPackageTest/SortLib-3.10.1/SortLibConfig.cmake new file mode 100644 index 0000000..3f3f659 --- /dev/null +++ b/Tests/FindPackageTest/SortLib-3.10.1/SortLibConfig.cmake @@ -0,0 +1,2 @@ +set(SORT_LIB_VERSION 3.10.1) +message("SortLib 3.10.1 config reached") diff --git a/Tests/FindPackageTest/SortLib-3.10.1/SortLibConfigVersion.cmake b/Tests/FindPackageTest/SortLib-3.10.1/SortLibConfigVersion.cmake new file mode 100644 index 0000000..6f44c2d --- /dev/null +++ b/Tests/FindPackageTest/SortLib-3.10.1/SortLibConfigVersion.cmake @@ -0,0 +1,9 @@ +set(PACKAGE_VERSION 3.10.1) +if(PACKAGE_FIND_VERSION_MAJOR EQUAL 3) + if(PACKAGE_FIND_VERSION_MINOR EQUAL 10) + set(PACKAGE_VERSION_COMPATIBLE 1) + if(PACKAGE_FIND_VERSION_PATCH EQUAL 1) + set(PACKAGE_VERSION_EXACT 1) + endif() + endif() +endif() diff --git a/Tests/RunCMake/file/DOWNLOAD-httpheader-not-set-result.txt b/Tests/RunCMake/file/DOWNLOAD-httpheader-not-set-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/file/DOWNLOAD-httpheader-not-set-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/file/DOWNLOAD-httpheader-not-set-stderr.txt b/Tests/RunCMake/file/DOWNLOAD-httpheader-not-set-stderr.txt new file mode 100644 index 0000000..247923b --- /dev/null +++ b/Tests/RunCMake/file/DOWNLOAD-httpheader-not-set-stderr.txt @@ -0,0 +1,4 @@ +^CMake Error at DOWNLOAD-httpheader-not-set.cmake:[0-9]+ \(file\): + file DOWNLOAD missing string for HTTPHEADER. +Call Stack \(most recent call first\): + CMakeLists.txt:[0-9]+ \(include\)$ diff --git a/Tests/RunCMake/file/DOWNLOAD-httpheader-not-set.cmake b/Tests/RunCMake/file/DOWNLOAD-httpheader-not-set.cmake new file mode 100644 index 0000000..6efc958 --- /dev/null +++ b/Tests/RunCMake/file/DOWNLOAD-httpheader-not-set.cmake @@ -0,0 +1 @@ +file(DOWNLOAD "" "" HTTPHEADER "Content-Type: application/x-compressed-tar" HTTPHEADER) diff --git a/Tests/RunCMake/file/LOCK-lowercase.cmake b/Tests/RunCMake/file/LOCK-lowercase.cmake new file mode 100644 index 0000000..373afda --- /dev/null +++ b/Tests/RunCMake/file/LOCK-lowercase.cmake @@ -0,0 +1,11 @@ +set(lock "${CMAKE_CURRENT_BINARY_DIR}/file-to-lock") + +if(WIN32) + string(TOLOWER ${lock} lock) +endif() + +file(LOCK ${lock} TIMEOUT 0) +file(LOCK ${lock} RELEASE) + +file(LOCK ${lock} TIMEOUT 0) +file(LOCK ${lock} RELEASE) diff --git a/Tests/RunCMake/file/RunCMakeTest.cmake b/Tests/RunCMake/file/RunCMakeTest.cmake index d8e9ce0..48fa757 100644 --- a/Tests/RunCMake/file/RunCMakeTest.cmake +++ b/Tests/RunCMake/file/RunCMakeTest.cmake @@ -2,8 +2,10 @@ include(RunCMake) run_cmake(DOWNLOAD-hash-mismatch) run_cmake(DOWNLOAD-unused-argument) +run_cmake(DOWNLOAD-httpheader-not-set) run_cmake(DOWNLOAD-pass-not-set) run_cmake(UPLOAD-unused-argument) +run_cmake(UPLOAD-httpheader-not-set) run_cmake(UPLOAD-pass-not-set) run_cmake(INSTALL-DIRECTORY) run_cmake(INSTALL-MESSAGE-bad) @@ -22,6 +24,7 @@ run_cmake(LOCK-error-no-result-variable) run_cmake(LOCK-error-no-timeout) run_cmake(LOCK-error-timeout) run_cmake(LOCK-error-unknown-option) +run_cmake(LOCK-lowercase) run_cmake(GLOB) run_cmake(GLOB_RECURSE) # test is valid both for GLOB and GLOB_RECURSE diff --git a/Tests/RunCMake/file/UPLOAD-httpheader-not-set-result.txt b/Tests/RunCMake/file/UPLOAD-httpheader-not-set-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/file/UPLOAD-httpheader-not-set-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/file/UPLOAD-httpheader-not-set-stderr.txt b/Tests/RunCMake/file/UPLOAD-httpheader-not-set-stderr.txt new file mode 100644 index 0000000..341baf5 --- /dev/null +++ b/Tests/RunCMake/file/UPLOAD-httpheader-not-set-stderr.txt @@ -0,0 +1,4 @@ +^CMake Error at UPLOAD-httpheader-not-set.cmake:[0-9]+ \(file\): + file UPLOAD missing string for HTTPHEADER. +Call Stack \(most recent call first\): + CMakeLists.txt:[0-9]+ \(include\)$ diff --git a/Tests/RunCMake/file/UPLOAD-httpheader-not-set.cmake b/Tests/RunCMake/file/UPLOAD-httpheader-not-set.cmake new file mode 100644 index 0000000..18d43cc --- /dev/null +++ b/Tests/RunCMake/file/UPLOAD-httpheader-not-set.cmake @@ -0,0 +1 @@ +file(UPLOAD "" "" HTTPHEADER "Content-Type: application/x-compressed-tar" HTTPHEADER) diff --git a/Utilities/Doxygen/CMakeLists.txt b/Utilities/Doxygen/CMakeLists.txt index 6ebf2b4..add5326 100644 --- a/Utilities/Doxygen/CMakeLists.txt +++ b/Utilities/Doxygen/CMakeLists.txt @@ -12,7 +12,7 @@ if(NOT CMake_SOURCE_DIR) set(CMakeDeveloperReference_STANDALONE 1) - cmake_minimum_required(VERSION 2.8.4 FATAL_ERROR) + cmake_minimum_required(VERSION 2.8.12.2 FATAL_ERROR) get_filename_component(tmp "${CMAKE_CURRENT_SOURCE_DIR}" PATH) get_filename_component(CMake_SOURCE_DIR "${tmp}" PATH) include(${CMake_SOURCE_DIR}/Modules/CTestUseLaunchers.cmake) diff --git a/Utilities/Sphinx/CMakeLists.txt b/Utilities/Sphinx/CMakeLists.txt index 45f79dd..be4850e 100644 --- a/Utilities/Sphinx/CMakeLists.txt +++ b/Utilities/Sphinx/CMakeLists.txt @@ -11,7 +11,7 @@ #============================================================================= if(NOT CMake_SOURCE_DIR) set(CMakeHelp_STANDALONE 1) - cmake_minimum_required(VERSION 2.8.4 FATAL_ERROR) + cmake_minimum_required(VERSION 2.8.12.2 FATAL_ERROR) get_filename_component(tmp "${CMAKE_CURRENT_SOURCE_DIR}" PATH) get_filename_component(CMake_SOURCE_DIR "${tmp}" PATH) include(${CMake_SOURCE_DIR}/Modules/CTestUseLaunchers.cmake) |