diff options
42 files changed, 468 insertions, 147 deletions
diff --git a/Help/command/ctest_submit.rst b/Help/command/ctest_submit.rst index 426475c..fba03fd 100644 --- a/Help/command/ctest_submit.rst +++ b/Help/command/ctest_submit.rst @@ -6,6 +6,7 @@ Perform the :ref:`CTest Submit Step` as a :ref:`Dashboard Client`. :: ctest_submit([PARTS <part>...] [FILES <file>...] + [SUBMIT_URL <url>] [HTTPHEADER <header>] [RETRY_COUNT <count>] [RETRY_DELAY <delay>] @@ -39,6 +40,10 @@ The options are: Specify an explicit list of specific files to be submitted. Each individual file must exist at the time of the call. +``SUBMIT_URL <url>`` + The ``http`` or ``https`` URL of the dashboard server to send the submission + to. If not given, the :variable:`CTEST_SUBMIT_URL` variable is used. + ``HTTPHEADER <HTTP-header>`` Specify HTTP header to be included in the request to CDash during submission. This suboption can be repeated several times. @@ -68,6 +73,7 @@ Submit to CDash Upload API :: ctest_submit(CDASH_UPLOAD <file> [CDASH_UPLOAD_TYPE <type>] + [SUBMIT_URL <url>] [HTTPHEADER <header>] [RETRY_COUNT <count>] [RETRY_DELAY <delay>] @@ -80,5 +86,5 @@ with a content hash of the file. If CDash does not already have the file, then it is uploaded. Along with the file, a CDash type string is specified to tell CDash which handler to use to process the data. -This signature accepts the ``HTTPHEADER``, ``RETRY_COUNT``, ``RETRY_DELAY``, -``RETURN_VALUE`` and ``QUIET`` options as described above. +This signature accepts the ``SUBMIT_URL``, ``HTTPHEADER``, ``RETRY_COUNT``, +``RETRY_DELAY``, ``RETURN_VALUE`` and ``QUIET`` options as described above. diff --git a/Help/command/file.rst b/Help/command/file.rst index 6e2a6dd..db4d6fc 100644 --- a/Help/command/file.rst +++ b/Help/command/file.rst @@ -27,6 +27,7 @@ Synopsis file({`COPY`_ | `INSTALL`_} <file>... DESTINATION <dir> [...]) file(`SIZE`_ <filename> <out-var>) file(`READ_SYMLINK`_ <filename> <out-var>) + file(`CREATE_LINK`_ <file> <new-file> [...]) `Path Conversion`_ file(`RELATIVE_PATH`_ <out-var> <directory> <file>) @@ -368,6 +369,28 @@ could do something like this: set(result "${dir}/${result}") endif() +.. _CREATE_LINK: + +.. code-block:: cmake + + file(CREATE_LINK <file> <new-file> + [RESULT <result>] [COPY_ON_ERROR] [SYMBOLIC]) + +Create a link to ``<file>`` at ``<new-file>``. + +It is a hard link by default. This can be changed to symbolic links by +using ``SYMBOLIC``. The original file needs to exist for hard links. + +The ``<result>`` variable, if specified, gets the status of the operation. +It is set to ``0`` in case of success. Otherwise, it contains the error +generated. In case of failures, if ``RESULT`` is not specified, a fatal error +is emitted. + +Specifying ``COPY_ON_ERROR`` enables copying the file as a fallback if +creating the link fails. + +Overwrites the ``<new-file>`` if it exists. + Path Conversion ^^^^^^^^^^^^^^^ diff --git a/Help/command/find_package.rst b/Help/command/find_package.rst index cafef8c..54d5f68 100644 --- a/Help/command/find_package.rst +++ b/Help/command/find_package.rst @@ -354,6 +354,11 @@ enabled. .. include:: FIND_XXX_ROOT.txt .. include:: FIND_XXX_ORDER.txt +By default the value stored in the result variable will be the path at +which the file is found. The :variable:`CMAKE_FIND_PACKAGE_RESOLVE_SYMLINKS` +variable may be set to ``TRUE`` before calling ``find_package`` in order +to resolve symbolic links and store the real path to the file. + Every non-REQUIRED ``find_package`` call can be disabled by setting the :variable:`CMAKE_DISABLE_FIND_PACKAGE_<PackageName>` variable to ``TRUE``. diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst index 122be3a..bd6a58f 100644 --- a/Help/manual/cmake-variables.7.rst +++ b/Help/manual/cmake-variables.7.rst @@ -170,6 +170,7 @@ Variables that Change Behavior /variable/CMAKE_FIND_NO_INSTALL_PREFIX /variable/CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY /variable/CMAKE_FIND_PACKAGE_NO_SYSTEM_PACKAGE_REGISTRY + /variable/CMAKE_FIND_PACKAGE_RESOLVE_SYMLINKS /variable/CMAKE_FIND_PACKAGE_WARN_NO_MODULE /variable/CMAKE_FIND_ROOT_PATH /variable/CMAKE_FIND_ROOT_PATH_MODE_INCLUDE @@ -569,6 +570,7 @@ Variables for CTest /variable/CTEST_RUN_CURRENT_SCRIPT /variable/CTEST_SCP_COMMAND /variable/CTEST_SITE + /variable/CTEST_SUBMIT_URL /variable/CTEST_SOURCE_DIRECTORY /variable/CTEST_SVN_COMMAND /variable/CTEST_SVN_OPTIONS diff --git a/Help/manual/ctest.1.rst b/Help/manual/ctest.1.rst index 8490e3d..bcf75ac 100644 --- a/Help/manual/ctest.1.rst +++ b/Help/manual/ctest.1.rst @@ -1109,38 +1109,45 @@ Configuration settings include: * :module:`CTest` module variable: ``CTEST_CURL_OPTIONS`` ``DropLocation`` - The path on the dashboard server to send the submission. + Legacy option. When ``SubmitURL`` is not set, it is constructed from + ``DropMethod``, ``DropSiteUser``, ``DropSitePassword``, ``DropSite``, and + ``DropLocation``. * `CTest Script`_ variable: :variable:`CTEST_DROP_LOCATION` * :module:`CTest` module variable: ``DROP_LOCATION`` if set, else ``CTEST_DROP_LOCATION`` ``DropMethod`` - Specify the method by which results should be submitted to the - dashboard server. The value may be ``http`` or ``https``. + Legacy option. When ``SubmitURL`` is not set, it is constructed from + ``DropMethod``, ``DropSiteUser``, ``DropSitePassword``, ``DropSite``, and + ``DropLocation``. * `CTest Script`_ variable: :variable:`CTEST_DROP_METHOD` * :module:`CTest` module variable: ``DROP_METHOD`` if set, else ``CTEST_DROP_METHOD`` ``DropSite`` - The dashboard server name. + Legacy option. When ``SubmitURL`` is not set, it is constructed from + ``DropMethod``, ``DropSiteUser``, ``DropSitePassword``, ``DropSite``, and + ``DropLocation``. * `CTest Script`_ variable: :variable:`CTEST_DROP_SITE` * :module:`CTest` module variable: ``DROP_SITE`` if set, else ``CTEST_DROP_SITE`` ``DropSitePassword`` - The dashboard server login password, if any - (for ``ftp``, ``http``, and ``https``). + Legacy option. When ``SubmitURL`` is not set, it is constructed from + ``DropMethod``, ``DropSiteUser``, ``DropSitePassword``, ``DropSite``, and + ``DropLocation``. * `CTest Script`_ variable: :variable:`CTEST_DROP_SITE_PASSWORD` * :module:`CTest` module variable: ``DROP_SITE_PASSWORD`` if set, else ``CTEST_DROP_SITE_PASWORD`` ``DropSiteUser`` - The dashboard server login user name, if any - (for ``ftp``, ``http``, and ``https``). + Legacy option. When ``SubmitURL`` is not set, it is constructed from + ``DropMethod``, ``DropSiteUser``, ``DropSitePassword``, ``DropSite``, and + ``DropLocation``. * `CTest Script`_ variable: :variable:`CTEST_DROP_SITE_USER` * :module:`CTest` module variable: ``DROP_SITE_USER`` if set, @@ -1166,6 +1173,14 @@ Configuration settings include: * :module:`CTest` module variable: ``SITE``, initialized by the :command:`site_name` command +``SubmitURL`` + The ``http`` or ``https`` URL of the dashboard server to send the submission + to. + + * `CTest Script`_ variable: :variable:`CTEST_SUBMIT_URL` + * :module:`CTest` module variable: ``SUBMIT_URL`` if set, + else ``CTEST_SUBMIT_URL`` + ``TriggerSite`` Legacy option. Not used. diff --git a/Help/release/dev/ctest-submit-url.rst b/Help/release/dev/ctest-submit-url.rst new file mode 100644 index 0000000..f848877 --- /dev/null +++ b/Help/release/dev/ctest-submit-url.rst @@ -0,0 +1,7 @@ +ctest-submit-url +---------------- + +* CTest learned to accept the dashboard server submission URL from a single + variable. See the ``SubmitURL`` setting in :manual:`ctest(1)`, + the :variable:`CTEST_SUBMIT_URL` variable, and the ``SUBMIT_URL`` + argument of the :command:`ctest_submit` command. diff --git a/Help/release/dev/find-package-resolve-symlinks.rst b/Help/release/dev/find-package-resolve-symlinks.rst new file mode 100644 index 0000000..7adb9fe --- /dev/null +++ b/Help/release/dev/find-package-resolve-symlinks.rst @@ -0,0 +1,6 @@ +find-package-resolve-symlinks +----------------------------- + +* The :command:`find_package` command learned to optionally resolve + symbolic links in the paths to package configuration files. + See the :variable:`CMAKE_FIND_PACKAGE_RESOLVE_SYMLINKS` variable. diff --git a/Help/variable/CMAKE_FIND_PACKAGE_RESOLVE_SYMLINKS.rst b/Help/variable/CMAKE_FIND_PACKAGE_RESOLVE_SYMLINKS.rst new file mode 100644 index 0000000..dfbde20 --- /dev/null +++ b/Help/variable/CMAKE_FIND_PACKAGE_RESOLVE_SYMLINKS.rst @@ -0,0 +1,10 @@ +CMAKE_FIND_PACKAGE_RESOLVE_SYMLINKS +----------------------------------- + +Set to ``TRUE`` to tell :command:`find_package` calls to resolve symbolic +links in the value of ``<PackageName>_DIR``. + +This is helpful in use cases where the package search path points at a +proxy directory in which symlinks to the real package locations appear. +This is not enabled by default because there are also common use cases +in which the symlinks should be preserved. diff --git a/Help/variable/CTEST_SUBMIT_URL.rst b/Help/variable/CTEST_SUBMIT_URL.rst new file mode 100644 index 0000000..7d84da4 --- /dev/null +++ b/Help/variable/CTEST_SUBMIT_URL.rst @@ -0,0 +1,5 @@ +CTEST_SUBMIT_URL +---------------- + +Specify the CTest ``SubmitURL`` setting +in a :manual:`ctest(1)` dashboard client script. diff --git a/Modules/CTest.cmake b/Modules/CTest.cmake index 8848bdd..d100704 100644 --- a/Modules/CTest.cmake +++ b/Modules/CTest.cmake @@ -28,10 +28,7 @@ To enable submissions to a CDash server, create a ``CTestConfig.cmake`` file at the top of the project with content such as:: set(CTEST_NIGHTLY_START_TIME "01:00:00 UTC") - set(CTEST_DROP_METHOD "http") - set(CTEST_DROP_SITE "my.cdash.org") - set(CTEST_DROP_LOCATION "/submit.php?project=MyProject") - set(CTEST_DROP_SITE_CDASH TRUE) + set(CTEST_SUBMIT_URL "http://my.cdash.org/submit.php?project=MyProject") (the CDash server can provide the file to a project administrator who configures ``MyProject``). Settings in the config file are shared by @@ -89,6 +86,7 @@ if(BUILD_TESTING) if(EXISTS "${PROJECT_SOURCE_DIR}/CTestConfig.cmake") include("${PROJECT_SOURCE_DIR}/CTestConfig.cmake") SET_IF_SET_AND_NOT_SET(NIGHTLY_START_TIME "${CTEST_NIGHTLY_START_TIME}") + SET_IF_SET_AND_NOT_SET(SUBMIT_URL "${CTEST_SUBMIT_URL}") SET_IF_SET_AND_NOT_SET(DROP_METHOD "${CTEST_DROP_METHOD}") SET_IF_SET_AND_NOT_SET(DROP_SITE "${CTEST_DROP_SITE}") SET_IF_SET_AND_NOT_SET(DROP_SITE_USER "${CTEST_DROP_SITE_USER}") @@ -111,6 +109,18 @@ if(BUILD_TESTING) endif() SET_IF_NOT_SET (NIGHTLY_START_TIME "00:00:00 EDT") + if(NOT SUBMIT_URL) + set(SUBMIT_URL "${DROP_METHOD}://") + if(DROP_SITE_USER) + string(APPEND SUBMIT_URL "${DROP_SITE_USER}") + if(DROP_SITE_PASSWORD) + string(APPEND SUBMIT_URL ":${DROP_SITE_PASSWORD}") + endif() + string(APPEND SUBMIT_URL "@") + endif() + string(APPEND SUBMIT_URL "${DROP_SITE}${DROP_SITE_LOCATION}") + endif() + find_program(CVSCOMMAND cvs ) set(CVS_UPDATE_OPTIONS "-d -A -P" CACHE STRING "Options passed to the cvs update command.") diff --git a/Modules/DartConfiguration.tcl.in b/Modules/DartConfiguration.tcl.in index 24e7b55..e4513b3 100644 --- a/Modules/DartConfiguration.tcl.in +++ b/Modules/DartConfiguration.tcl.in @@ -20,12 +20,7 @@ BuildName: @BUILDNAME@ LabelsForSubprojects: @CTEST_LABELS_FOR_SUBPROJECTS@ # Submission information -DropSite: @DROP_SITE@ -DropLocation: @DROP_LOCATION@ -DropSiteUser: @DROP_SITE_USER@ -DropSitePassword: @DROP_SITE_PASSWORD@ -DropSiteMode: @DROP_SITE_MODE@ -DropMethod: @DROP_METHOD@ +SubmitURL: @SUBMIT_URL@ # Dashboard start time NightlyStartTime: @NIGHTLY_START_TIME@ diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 245bd71..62f5f70 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 13) -set(CMake_VERSION_PATCH 20190118) +set(CMake_VERSION_PATCH 20190121) #set(CMake_VERSION_RC 1) diff --git a/Source/CTest/cmCTestSubmitCommand.cxx b/Source/CTest/cmCTestSubmitCommand.cxx index 76a1830..00c0610 100644 --- a/Source/CTest/cmCTestSubmitCommand.cxx +++ b/Source/CTest/cmCTestSubmitCommand.cxx @@ -15,36 +15,28 @@ class cmExecutionStatus; cmCTestGenericHandler* cmCTestSubmitCommand::InitializeHandler() { - const char* ctestDropMethod = - this->Makefile->GetDefinition("CTEST_DROP_METHOD"); - const char* ctestDropSite = this->Makefile->GetDefinition("CTEST_DROP_SITE"); - const char* ctestDropLocation = - this->Makefile->GetDefinition("CTEST_DROP_LOCATION"); - if (!ctestDropMethod) { - ctestDropMethod = "http"; - } + const char* submitURL = !this->SubmitURL.empty() + ? this->SubmitURL.c_str() + : this->Makefile->GetDefinition("CTEST_SUBMIT_URL"); - if (!ctestDropSite) { - // error: CDash requires CTEST_DROP_SITE definition - // in CTestConfig.cmake - } - if (!ctestDropLocation) { - // error: CDash requires CTEST_DROP_LOCATION definition - // in CTestConfig.cmake + if (submitURL) { + this->CTest->SetCTestConfiguration("SubmitURL", submitURL, this->Quiet); + } else { + this->CTest->SetCTestConfigurationFromCMakeVariable( + this->Makefile, "DropMethod", "CTEST_DROP_METHOD", this->Quiet); + this->CTest->SetCTestConfigurationFromCMakeVariable( + this->Makefile, "DropSiteUser", "CTEST_DROP_SITE_USER", this->Quiet); + this->CTest->SetCTestConfigurationFromCMakeVariable( + this->Makefile, "DropSitePassword", "CTEST_DROP_SITE_PASSWORD", + this->Quiet); + this->CTest->SetCTestConfigurationFromCMakeVariable( + this->Makefile, "DropSite", "CTEST_DROP_SITE", this->Quiet); + this->CTest->SetCTestConfigurationFromCMakeVariable( + this->Makefile, "DropLocation", "CTEST_DROP_LOCATION", this->Quiet); } - this->CTest->SetCTestConfiguration("DropMethod", ctestDropMethod, - this->Quiet); - this->CTest->SetCTestConfiguration("DropSite", ctestDropSite, this->Quiet); - this->CTest->SetCTestConfiguration("DropLocation", ctestDropLocation, - this->Quiet); this->CTest->SetCTestConfigurationFromCMakeVariable( this->Makefile, "CurlOptions", "CTEST_CURL_OPTIONS", this->Quiet); - this->CTest->SetCTestConfigurationFromCMakeVariable( - this->Makefile, "DropSiteUser", "CTEST_DROP_SITE_USER", this->Quiet); - this->CTest->SetCTestConfigurationFromCMakeVariable( - this->Makefile, "DropSitePassword", "CTEST_DROP_SITE_PASSWORD", - this->Quiet); const char* notesFilesVariable = this->Makefile->GetDefinition("CTEST_NOTES_FILES"); @@ -184,6 +176,11 @@ bool cmCTestSubmitCommand::CheckArgumentKeyword(std::string const& arg) return true; } + if (arg == "SUBMIT_URL") { + this->ArgumentDoing = ArgumentDoingSubmitURL; + return true; + } + if (arg == "INTERNAL_TEST_CHECKSUM") { this->InternalTest = true; return true; @@ -249,6 +246,12 @@ bool cmCTestSubmitCommand::CheckArgumentValue(std::string const& arg) return true; } + if (this->ArgumentDoing == ArgumentDoingSubmitURL) { + this->ArgumentDoing = ArgumentDoingNone; + this->SubmitURL = arg; + return true; + } + // Look for other arguments. return this->Superclass::CheckArgumentValue(arg); } diff --git a/Source/CTest/cmCTestSubmitCommand.h b/Source/CTest/cmCTestSubmitCommand.h index c4b84ce..0caccd6 100644 --- a/Source/CTest/cmCTestSubmitCommand.h +++ b/Source/CTest/cmCTestSubmitCommand.h @@ -71,6 +71,7 @@ protected: ArgumentDoingCDashUpload, ArgumentDoingCDashUploadType, ArgumentDoingHttpHeader, + ArgumentDoingSubmitURL, ArgumentDoingLast2 }; @@ -85,6 +86,7 @@ protected: std::string CDashUploadFile; std::string CDashUploadType; std::vector<std::string> HttpHeaders; + std::string SubmitURL; }; #endif diff --git a/Source/CTest/cmCTestSubmitHandler.cxx b/Source/CTest/cmCTestSubmitHandler.cxx index 3042480..600194a 100644 --- a/Source/CTest/cmCTestSubmitHandler.cxx +++ b/Source/CTest/cmCTestSubmitHandler.cxx @@ -162,7 +162,6 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP( /* In windows, this will init the winsock stuff */ ::curl_global_init(CURL_GLOBAL_ALL); - std::string dropMethod(this->CTest->GetCTestConfiguration("DropMethod")); std::string curlopt(this->CTest->GetCTestConfiguration("CurlOptions")); std::vector<std::string> args; cmSystemTools::ExpandListArgument(curlopt, args); @@ -495,27 +494,6 @@ void cmCTestSubmitHandler::ParseResponse( } } -void cmCTestSubmitHandler::ConstructCDashURL(std::string& dropMethod, - std::string& url) -{ - dropMethod = this->CTest->GetCTestConfiguration("DropMethod"); - url = dropMethod; - url += "://"; - if (!this->CTest->GetCTestConfiguration("DropSiteUser").empty()) { - url += this->CTest->GetCTestConfiguration("DropSiteUser"); - cmCTestOptionalLog( - this->CTest, HANDLER_OUTPUT, - this->CTest->GetCTestConfiguration("DropSiteUser").c_str(), this->Quiet); - if (!this->CTest->GetCTestConfiguration("DropSitePassword").empty()) { - url += ":" + this->CTest->GetCTestConfiguration("DropSitePassword"); - cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, ":******", this->Quiet); - } - url += "@"; - } - url += this->CTest->GetCTestConfiguration("DropSite") + - this->CTest->GetCTestConfiguration("DropLocation"); -} - int cmCTestSubmitHandler::HandleCDashUploadFile(std::string const& file, std::string const& typeString) { @@ -536,16 +514,15 @@ int cmCTestSubmitHandler::HandleCDashUploadFile(std::string const& file, curl.SetCurlOptions(args); curl.SetTimeOutSeconds(SUBMIT_TIMEOUT_IN_SECONDS_DEFAULT); curl.SetHttpHeaders(this->HttpHeaders); - std::string dropMethod; - std::string url; - this->ConstructCDashURL(dropMethod, url); + std::string url = this->CTest->GetSubmitURL(); std::string fields; std::string::size_type pos = url.find('?'); if (pos != std::string::npos) { fields = url.substr(pos + 1); url = url.substr(0, pos); } - if (!(dropMethod == "http" || dropMethod == "https")) { + if (!cmHasLiteralPrefix(url, "http://") && + !cmHasLiteralPrefix(url, "https://")) { cmCTestLog(this->CTest, ERROR_MESSAGE, "Only http and https are supported for CDASH_UPLOAD\n"); return -1; @@ -872,10 +849,7 @@ int cmCTestSubmitHandler::ProcessHandler() cnt++; } } - cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, - "Submit files (using " - << this->CTest->GetCTestConfiguration("DropMethod") - << ")" << std::endl, + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, "Submit files\n", this->Quiet); const char* specificTrack = this->CTest->GetSpecificTrack(); if (specificTrack) { @@ -885,72 +859,32 @@ int cmCTestSubmitHandler::ProcessHandler() } this->SetLogFile(&ofs); - std::string dropMethod(this->CTest->GetCTestConfiguration("DropMethod")); - - if (dropMethod.empty()) { - dropMethod = "http"; + std::string url = this->CTest->GetSubmitURL(); + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, + " SubmitURL: " << url << '\n', this->Quiet); + if (!this->SubmitUsingHTTP(buildDirectory + "/Testing/" + + this->CTest->GetCurrentTag(), + files, prefix, url)) { + cmCTestLog(this->CTest, ERROR_MESSAGE, + " Problems when submitting via HTTP\n"); + ofs << " Problems when submitting via HTTP\n"; + return -1; } - - if (dropMethod == "http" || dropMethod == "https") { - std::string url = dropMethod; - url += "://"; - ofs << "Using drop method: " << dropMethod << std::endl; - cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, - " Using HTTP submit method" << std::endl - << " Drop site:" << url, - this->Quiet); - if (!this->CTest->GetCTestConfiguration("DropSiteUser").empty()) { - url += this->CTest->GetCTestConfiguration("DropSiteUser"); - cmCTestOptionalLog( - this->CTest, HANDLER_OUTPUT, - this->CTest->GetCTestConfiguration("DropSiteUser").c_str(), - this->Quiet); - if (!this->CTest->GetCTestConfiguration("DropSitePassword").empty()) { - url += ":" + this->CTest->GetCTestConfiguration("DropSitePassword"); - cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, ":******", - this->Quiet); - } - url += "@"; - cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, "@", this->Quiet); - } - url += this->CTest->GetCTestConfiguration("DropSite") + - this->CTest->GetCTestConfiguration("DropLocation"); + if (this->HasErrors) { + cmCTestLog(this->CTest, HANDLER_OUTPUT, + " Errors occurred during submission.\n"); + ofs << " Errors occurred during submission.\n"; + } else { cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, - this->CTest->GetCTestConfiguration("DropSite") - << this->CTest->GetCTestConfiguration("DropLocation") + " Submission successful" + << (this->HasWarnings ? ", with warnings." : "") << std::endl, this->Quiet); - if (!this->SubmitUsingHTTP(buildDirectory + "/Testing/" + - this->CTest->GetCurrentTag(), - files, prefix, url)) { - cmCTestLog(this->CTest, ERROR_MESSAGE, - " Problems when submitting via HTTP" << std::endl); - ofs << " Problems when submitting via HTTP" << std::endl; - return -1; - } - if (this->HasErrors) { - cmCTestLog(this->CTest, HANDLER_OUTPUT, - " Errors occurred during " - "submission." - << std::endl); - ofs << " Errors occurred during submission. " << std::endl; - } else { - cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, - " Submission successful" - << (this->HasWarnings ? ", with warnings." : "") - << std::endl, - this->Quiet); - ofs << " Submission successful" - << (this->HasWarnings ? ", with warnings." : "") << std::endl; - } - - return 0; + ofs << " Submission successful" + << (this->HasWarnings ? ", with warnings." : "") << std::endl; } - cmCTestLog(this->CTest, ERROR_MESSAGE, - " Unknown submission method: \"" << dropMethod << "\"" - << std::endl); - return -1; + return 0; } std::string cmCTestSubmitHandler::GetSubmitResultsPrefix() diff --git a/Source/CTest/cmCTestSubmitHandler.h b/Source/CTest/cmCTestSubmitHandler.h index 393e826..58f4f97 100644 --- a/Source/CTest/cmCTestSubmitHandler.h +++ b/Source/CTest/cmCTestSubmitHandler.h @@ -48,8 +48,6 @@ public: this->HttpHeaders = v; } - void ConstructCDashURL(std::string& dropMethod, std::string& url); - private: void SetLogFile(std::ostream* ost) { this->LogFile = ost; } diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx index 1c0d9f6..ded2525 100644 --- a/Source/cmCTest.cxx +++ b/Source/cmCTest.cxx @@ -2626,6 +2626,32 @@ void cmCTest::SetCTestConfiguration(const char* name, const char* value, this->CTestConfiguration[name] = value; } +std::string cmCTest::GetSubmitURL() +{ + std::string url = this->GetCTestConfiguration("SubmitURL"); + if (url.empty()) { + std::string method = this->GetCTestConfiguration("DropMethod"); + std::string user = this->GetCTestConfiguration("DropSiteUser"); + std::string password = this->GetCTestConfiguration("DropSitePassword"); + std::string site = this->GetCTestConfiguration("DropSite"); + std::string location = this->GetCTestConfiguration("DropLocation"); + + url = method.empty() ? "http" : method; + url += "://"; + if (!user.empty()) { + url += user; + if (!password.empty()) { + url += ':'; + url += password; + } + url += '@'; + } + url += site; + url += location; + } + return url; +} + std::string cmCTest::GetCurrentTag() { return this->CurrentTag; diff --git a/Source/cmCTest.h b/Source/cmCTest.h index 2b40ca3..a82f400 100644 --- a/Source/cmCTest.h +++ b/Source/cmCTest.h @@ -176,6 +176,8 @@ public: bool suppress = false); void EmptyCTestConfiguration(); + std::string GetSubmitURL(); + /** * constructor and destructor */ diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx index db2fde8..999af54 100644 --- a/Source/cmFileCommand.cxx +++ b/Source/cmFileCommand.cxx @@ -185,6 +185,9 @@ bool cmFileCommand::InitialPass(std::vector<std::string> const& args, if (subCommand == "READ_SYMLINK") { return this->HandleReadSymlinkCommand(args); } + if (subCommand == "CREATE_LINK") { + return this->HandleCreateLinkCommand(args); + } std::string e = "does not recognize sub-command " + subCommand; this->SetError(e); @@ -3670,3 +3673,119 @@ bool cmFileCommand::HandleReadSymlinkCommand( return true; } + +bool cmFileCommand::HandleCreateLinkCommand( + std::vector<std::string> const& args) +{ + if (args.size() < 3) { + this->SetError("CREATE_LINK must be called with at least two additional " + "arguments"); + return false; + } + + cmCommandArgumentsHelper argHelper; + cmCommandArgumentGroup group; + + cmCAString linkArg(&argHelper, "CREATE_LINK"); + cmCAString fileArg(&argHelper, nullptr); + cmCAString newFileArg(&argHelper, nullptr); + + cmCAString resultArg(&argHelper, "RESULT", &group); + cmCAEnabler copyOnErrorArg(&argHelper, "COPY_ON_ERROR", &group); + cmCAEnabler symbolicArg(&argHelper, "SYMBOLIC", &group); + + linkArg.Follows(nullptr); + fileArg.Follows(&linkArg); + newFileArg.Follows(&fileArg); + group.Follows(&newFileArg); + + std::vector<std::string> unconsumedArgs; + argHelper.Parse(&args, &unconsumedArgs); + + if (!unconsumedArgs.empty()) { + this->SetError("unknown argument: \"" + unconsumedArgs.front() + '\"'); + return false; + } + + std::string fileName = fileArg.GetString(); + std::string newFileName = newFileArg.GetString(); + + // Output variable for storing the result. + const std::string& resultVar = resultArg.GetString(); + + // The system error message generated in the operation. + std::string result; + + // Check if the paths are distinct. + if (fileName == newFileName) { + result = "CREATE_LINK cannot use same file and newfile"; + if (!resultVar.empty()) { + this->Makefile->AddDefinition(resultVar, result.c_str()); + return true; + } + this->SetError(result); + return false; + } + + // Hard link requires original file to exist. + if (!symbolicArg.IsEnabled() && !cmSystemTools::FileExists(fileName)) { + result = "Cannot hard link \'" + fileName + "\' as it does not exist."; + if (!resultVar.empty()) { + this->Makefile->AddDefinition(resultVar, result.c_str()); + return true; + } + this->SetError(result); + return false; + } + + // Check if the new file already exists and remove it. + if ((cmSystemTools::FileExists(newFileName) || + cmSystemTools::FileIsSymlink(newFileName)) && + !cmSystemTools::RemoveFile(newFileName)) { + std::ostringstream e; + e << "Failed to create link '" << newFileName + << "' because existing path cannot be removed: " + << cmSystemTools::GetLastSystemError() << "\n"; + + if (!resultVar.empty()) { + this->Makefile->AddDefinition(resultVar, e.str().c_str()); + return true; + } + this->SetError(e.str()); + return false; + } + + // Whether the operation completed successfully. + bool completed = false; + + // Check if the command requires a symbolic link. + if (symbolicArg.IsEnabled()) { + completed = cmSystemTools::CreateSymlink(fileName, newFileName, &result); + } else { + completed = cmSystemTools::CreateLink(fileName, newFileName, &result); + } + + // Check if copy-on-error is enabled in the arguments. + if (!completed && copyOnErrorArg.IsEnabled()) { + completed = + cmSystemTools::cmCopyFile(fileName.c_str(), newFileName.c_str()); + if (!completed) { + result = "Copy failed: " + cmSystemTools::GetLastSystemError(); + } + } + + // Check if the operation was successful. + if (completed) { + result = "0"; + } else if (resultVar.empty()) { + // The operation failed and the result is not reported in a variable. + this->SetError(result); + return false; + } + + if (!resultVar.empty()) { + this->Makefile->AddDefinition(resultVar, result.c_str()); + } + + return true; +} diff --git a/Source/cmFileCommand.h b/Source/cmFileCommand.h index fe05c98..12c5115 100644 --- a/Source/cmFileCommand.h +++ b/Source/cmFileCommand.h @@ -61,6 +61,7 @@ protected: bool HandleLockCommand(std::vector<std::string> const& args); bool HandleSizeCommand(std::vector<std::string> const& args); bool HandleReadSymlinkCommand(std::vector<std::string> const& args); + bool HandleCreateLinkCommand(std::vector<std::string> const& args); private: void AddEvaluationFile(const std::string& inputName, diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx index 8dc7ca2..2567b7a 100644 --- a/Source/cmFindPackageCommand.cxx +++ b/Source/cmFindPackageCommand.cxx @@ -95,6 +95,7 @@ cmFindPackageCommand::cmFindPackageCommand() this->UseLib32Paths = false; this->UseLib64Paths = false; this->UseLibx32Paths = false; + this->UseRealPath = false; this->PolicyScope = true; this->VersionMajor = 0; this->VersionMinor = 0; @@ -195,6 +196,11 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args, this->NoSystemRegistry = true; } + // Check whether we should resolve symlinks when finding packages + if (this->Makefile->IsOn("CMAKE_FIND_PACKAGE_RESOLVE_SYMLINKS")) { + this->UseRealPath = true; + } + // Check if Sorting should be enabled if (const char* so = this->Makefile->GetDefinition("CMAKE_FIND_PACKAGE_SORT_ORDER")) { @@ -1502,6 +1508,10 @@ bool cmFindPackageCommand::FindConfigFile(std::string const& dir, fprintf(stderr, "Checking file [%s]\n", file.c_str()); } if (cmSystemTools::FileExists(file, true) && this->CheckVersion(file)) { + // Allow resolving symlinks when the config file is found through a link + if (this->UseRealPath) { + file = cmSystemTools::GetRealPath(file); + } return true; } } diff --git a/Source/cmFindPackageCommand.h b/Source/cmFindPackageCommand.h index 05bad49..83d8431 100644 --- a/Source/cmFindPackageCommand.h +++ b/Source/cmFindPackageCommand.h @@ -178,6 +178,7 @@ private: bool UseLib32Paths; bool UseLib64Paths; bool UseLibx32Paths; + bool UseRealPath; bool PolicyScope; std::string LibraryArchitecture; std::vector<std::string> Names; diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index be65853..52957c1 100644 --- a/Source/cmSystemTools.cxx +++ b/Source/cmSystemTools.cxx @@ -3114,7 +3114,8 @@ std::string cmSystemTools::EncodeURL(std::string const& in, bool escapeSlashes) } bool cmSystemTools::CreateSymlink(const std::string& origName, - const std::string& newName) + const std::string& newName, + std::string* errorMessage) { uv_fs_t req; int flags = 0; @@ -3128,7 +3129,32 @@ bool cmSystemTools::CreateSymlink(const std::string& origName, if (err) { std::string e = "failed to create symbolic link '" + newName + "': " + uv_strerror(err); - cmSystemTools::Error(e.c_str()); + if (errorMessage) { + *errorMessage = std::move(e); + } else { + cmSystemTools::Error(e.c_str()); + } + return false; + } + + return true; +} + +bool cmSystemTools::CreateLink(const std::string& origName, + const std::string& newName, + std::string* errorMessage) +{ + uv_fs_t req; + int err = + uv_fs_link(nullptr, &req, origName.c_str(), newName.c_str(), nullptr); + if (err) { + std::string e = + "failed to create link '" + newName + "': " + uv_strerror(err); + if (errorMessage) { + *errorMessage = std::move(e); + } else { + cmSystemTools::Error(e.c_str()); + } return false; } diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h index c0999e7..489811d 100644 --- a/Source/cmSystemTools.h +++ b/Source/cmSystemTools.h @@ -528,7 +528,14 @@ public: /** Create a symbolic link if the platform supports it. Returns whether creation succeeded. */ static bool CreateSymlink(const std::string& origName, - const std::string& newName); + const std::string& newName, + std::string* errorMessage = nullptr); + + /** Create a hard link if the platform supports it. Returns whether + creation succeeded. */ + static bool CreateLink(const std::string& origName, + const std::string& newName, + std::string* errorMessage = nullptr); private: static bool s_ForceUnixPaths; diff --git a/Tests/FindPackageTest/CMakeLists.txt b/Tests/FindPackageTest/CMakeLists.txt index 6a80df5..f8b36c5 100644 --- a/Tests/FindPackageTest/CMakeLists.txt +++ b/Tests/FindPackageTest/CMakeLists.txt @@ -188,6 +188,37 @@ find_package(ArchC 3.1 EXACT NAMES zot) find_package(ArchD 4.0 EXACT NAMES zot) unset(CMAKE_LIBRARY_ARCHITECTURE) +# Test find_package() with CMAKE_FIND_PACKAGE_RESOLVE_SYMLINKS enabled +if(UNIX) + # Create ./symlink pointing back here. + execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink + . "${CMAKE_CURRENT_SOURCE_DIR}/symlink") + # Make find_package search through the symlink + set(CMAKE_PREFIX_PATH "${CMAKE_CURRENT_SOURCE_DIR}/symlink") + + # First, test the default behavior where symlinks are preserved. + set(SetFoundResolved_DIR "") + find_package(SetFoundResolved) + # The result must preserve the /symlink/ path. + set(SetFoundResolved_EXPECTED "${CMAKE_CURRENT_SOURCE_DIR}/symlink/cmake") + if(NOT "${SetFoundResolved_DIR}" STREQUAL "${SetFoundResolved_EXPECTED}") + message(SEND_ERROR "SetFoundResolved_DIR set by find_package() is set to \"${SetFoundResolved_DIR}\" (expected \"${SetFoundResolved_EXPECTED}\")") + endif() + + # Resolve symlinks when finding the package. + set(CMAKE_FIND_PACKAGE_RESOLVE_SYMLINKS TRUE) + set(SetFoundResolved_DIR "") + find_package(SetFoundResolved) + # ./symlink points back here so it should be gone when resolved. + set(SetFoundResolved_EXPECTED "${CMAKE_CURRENT_SOURCE_DIR}/cmake") + if(NOT "${SetFoundResolved_DIR}" STREQUAL "${SetFoundResolved_EXPECTED}") + message(SEND_ERROR "SetFoundResolved_DIR set by find_package() is set to \"${SetFoundResolved_DIR}\" (expected \"${SetFoundResolved_EXPECTED}\")") + endif() + # Cleanup. + unset(CMAKE_FIND_PACKAGE_RESOLVE_SYMLINKS) + file(REMOVE "${CMAKE_CURRENT_SOURCE_DIR}/symlink") +endif() + # Test <PackageName>_DIR environment variable. # We erase the main prefix path to ensure the env var is used. set(CMAKE_PREFIX_PATH) diff --git a/Tests/FindPackageTest/cmake/SetFoundResolvedConfig.cmake b/Tests/FindPackageTest/cmake/SetFoundResolvedConfig.cmake new file mode 100644 index 0000000..b2cf87c --- /dev/null +++ b/Tests/FindPackageTest/cmake/SetFoundResolvedConfig.cmake @@ -0,0 +1 @@ +set(SetFoundResolved_DIR "${CMAKE_CURRENT_LIST_DIR}") diff --git a/Tests/RunCMake/ctest_submit/FailDrop-http-stdout.txt b/Tests/RunCMake/ctest_submit/FailDrop-http-stdout.txt index c7f35c5..c9111b0 100644 --- a/Tests/RunCMake/ctest_submit/FailDrop-http-stdout.txt +++ b/Tests/RunCMake/ctest_submit/FailDrop-http-stdout.txt @@ -1,3 +1,2 @@ -Submit files \(using http\) - Using HTTP submit method - Drop site:http:// +Submit files + SubmitURL: http://-no-site- diff --git a/Tests/RunCMake/ctest_submit/FailDrop-https-stdout.txt b/Tests/RunCMake/ctest_submit/FailDrop-https-stdout.txt index 19f8234..2c67eb9 100644 --- a/Tests/RunCMake/ctest_submit/FailDrop-https-stdout.txt +++ b/Tests/RunCMake/ctest_submit/FailDrop-https-stdout.txt @@ -1,3 +1,2 @@ -Submit files \(using https\) - Using HTTP submit method - Drop site:https:// +Submit files + SubmitURL: https://-no-site- diff --git a/Tests/RunCMake/file/CREATE_LINK-COPY_ON_ERROR.cmake b/Tests/RunCMake/file/CREATE_LINK-COPY_ON_ERROR.cmake new file mode 100644 index 0000000..777ef4e --- /dev/null +++ b/Tests/RunCMake/file/CREATE_LINK-COPY_ON_ERROR.cmake @@ -0,0 +1,11 @@ +# Use COPY_ON_ERROR to handle the case where the source and destination +# directory are on different devices. Cross-device links are not permitted +# and the following command falls back to copying the file if link fails. +file(CREATE_LINK + ${CMAKE_CURRENT_LIST_FILE} TestCreateLink.cmake + RESULT result + COPY_ON_ERROR + ) +if(NOT result STREQUAL "0") + message(SEND_ERROR "COPY_ON_ERROR failed: '${result}'") +endif() diff --git a/Tests/RunCMake/file/CREATE_LINK-SYMBOLIC-noexist.cmake b/Tests/RunCMake/file/CREATE_LINK-SYMBOLIC-noexist.cmake new file mode 100644 index 0000000..61aaf38 --- /dev/null +++ b/Tests/RunCMake/file/CREATE_LINK-SYMBOLIC-noexist.cmake @@ -0,0 +1,4 @@ +file(CREATE_LINK does_not_exist.txt TestSymLink.txt RESULT sym_result SYMBOLIC) +if(NOT sym_result STREQUAL "0") + message("Symlink fail: ${sym_result}") +endif() diff --git a/Tests/RunCMake/file/CREATE_LINK-SYMBOLIC.cmake b/Tests/RunCMake/file/CREATE_LINK-SYMBOLIC.cmake new file mode 100644 index 0000000..77b899c --- /dev/null +++ b/Tests/RunCMake/file/CREATE_LINK-SYMBOLIC.cmake @@ -0,0 +1,4 @@ +file(CREATE_LINK ${CMAKE_CURRENT_LIST_FILE} TestSymLink.cmake RESULT sym_result SYMBOLIC) +if(NOT sym_result STREQUAL "0") + message(SEND_ERROR "Symlink result='${sym_result}'") +endif() diff --git a/Tests/RunCMake/file/CREATE_LINK-noarg-result.txt b/Tests/RunCMake/file/CREATE_LINK-noarg-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/file/CREATE_LINK-noarg-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/file/CREATE_LINK-noarg-stderr.txt b/Tests/RunCMake/file/CREATE_LINK-noarg-stderr.txt new file mode 100644 index 0000000..12494f8 --- /dev/null +++ b/Tests/RunCMake/file/CREATE_LINK-noarg-stderr.txt @@ -0,0 +1,4 @@ +CMake Error at CREATE_LINK-noarg\.cmake:[0-9]+ \(file\): + file CREATE_LINK must be called with at least two additional arguments +Call Stack \(most recent call first\): + CMakeLists\.txt:[0-9]+ \(include\) diff --git a/Tests/RunCMake/file/CREATE_LINK-noarg.cmake b/Tests/RunCMake/file/CREATE_LINK-noarg.cmake new file mode 100644 index 0000000..65002fa --- /dev/null +++ b/Tests/RunCMake/file/CREATE_LINK-noarg.cmake @@ -0,0 +1 @@ +file(CREATE_LINK ${CMAKE_CURRENT_LIST_FILE}) diff --git a/Tests/RunCMake/file/CREATE_LINK-noexist-stderr.txt b/Tests/RunCMake/file/CREATE_LINK-noexist-stderr.txt new file mode 100644 index 0000000..97eee4f --- /dev/null +++ b/Tests/RunCMake/file/CREATE_LINK-noexist-stderr.txt @@ -0,0 +1 @@ +Hard link error: Cannot hard link 'does_not_exist.txt' as it does not exist. diff --git a/Tests/RunCMake/file/CREATE_LINK-noexist.cmake b/Tests/RunCMake/file/CREATE_LINK-noexist.cmake new file mode 100644 index 0000000..5ee2580 --- /dev/null +++ b/Tests/RunCMake/file/CREATE_LINK-noexist.cmake @@ -0,0 +1,4 @@ +file(CREATE_LINK does_not_exist.txt TestLink.txt RESULT result) +if(NOT result STREQUAL "0") + message("Hard link error: ${result}") +endif() diff --git a/Tests/RunCMake/file/CREATE_LINK.cmake b/Tests/RunCMake/file/CREATE_LINK.cmake new file mode 100644 index 0000000..ca61646 --- /dev/null +++ b/Tests/RunCMake/file/CREATE_LINK.cmake @@ -0,0 +1,11 @@ +# start with a file in the same directory to avoid cross-device links +set(test_file ${CMAKE_CURRENT_BINARY_DIR}/CreateLinkTest.txt) +file(TOUCH ${test_file}) + +file(CREATE_LINK + ${test_file} ${CMAKE_CURRENT_BINARY_DIR}/TestCreateLink.txt + RESULT result + ) +if(NOT result STREQUAL "0") + message(SEND_ERROR "Hard link result='${result}'") +endif() diff --git a/Tests/RunCMake/file/RunCMakeTest.cmake b/Tests/RunCMake/file/RunCMakeTest.cmake index b872824..128e8f3 100644 --- a/Tests/RunCMake/file/RunCMakeTest.cmake +++ b/Tests/RunCMake/file/RunCMakeTest.cmake @@ -1,5 +1,9 @@ include(RunCMake) +run_cmake(CREATE_LINK) +run_cmake(CREATE_LINK-COPY_ON_ERROR) +run_cmake(CREATE_LINK-noarg) +run_cmake(CREATE_LINK-noexist) run_cmake(DOWNLOAD-hash-mismatch) run_cmake(DOWNLOAD-unused-argument) run_cmake(DOWNLOAD-httpheader-not-set) @@ -53,6 +57,8 @@ run_cmake_command(GLOB-error-CONFIGURE_DEPENDS-SCRIPT_MODE ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/GLOB-error-CONFIGURE_DEPENDS-SCRIPT_MODE.cmake) if(NOT WIN32 OR CYGWIN) + run_cmake(CREATE_LINK-SYMBOLIC) + run_cmake(CREATE_LINK-SYMBOLIC-noexist) run_cmake(GLOB_RECURSE-cyclic-recursion) run_cmake(INSTALL-SYMLINK) run_cmake(READ_SYMLINK) diff --git a/Tests/RunCMake/find_package/PackageRoot/ResolvedConfig.cmake b/Tests/RunCMake/find_package/PackageRoot/ResolvedConfig.cmake new file mode 100644 index 0000000..4496a05 --- /dev/null +++ b/Tests/RunCMake/find_package/PackageRoot/ResolvedConfig.cmake @@ -0,0 +1 @@ +set(Resolved_DIR "${CMAKE_CURRENT_LIST_DIR}") diff --git a/Tests/RunCMake/find_package/RunCMakeTest.cmake b/Tests/RunCMake/find_package/RunCMakeTest.cmake index e9f3558..066523e 100644 --- a/Tests/RunCMake/find_package/RunCMakeTest.cmake +++ b/Tests/RunCMake/find_package/RunCMakeTest.cmake @@ -26,3 +26,6 @@ run_cmake(WrongVersionConfig) run_cmake(CMP0084-OLD) run_cmake(CMP0084-WARN) run_cmake(CMP0084-NEW) +if(UNIX) + run_cmake(SetFoundResolved) +endif() diff --git a/Tests/RunCMake/find_package/SetFoundResolved-stderr.txt b/Tests/RunCMake/find_package/SetFoundResolved-stderr.txt new file mode 100644 index 0000000..ea94be5 --- /dev/null +++ b/Tests/RunCMake/find_package/SetFoundResolved-stderr.txt @@ -0,0 +1,10 @@ +CMake Warning at SetFoundResolved.cmake:10 \(message\): + .*/Tests/RunCMake/find_package/symlink +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) + + +CMake Warning at SetFoundResolved.cmake:15 \(message\): + .*/Tests/RunCMake/find_package/PackageRoot +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/find_package/SetFoundResolved.cmake b/Tests/RunCMake/find_package/SetFoundResolved.cmake new file mode 100644 index 0000000..8d56513 --- /dev/null +++ b/Tests/RunCMake/find_package/SetFoundResolved.cmake @@ -0,0 +1,17 @@ +# Create ./symlink pointing back here. +execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink + PackageRoot "${CMAKE_CURRENT_SOURCE_DIR}/symlink") + +# Make find_package search through the symlink. +set(CMAKE_PREFIX_PATH "${CMAKE_CURRENT_SOURCE_DIR}/symlink") + +# Test preservation of symlinks. +find_package(Resolved) +message(WARNING "${Resolved_DIR}") + +# Test resolving symlinks. +set(CMAKE_FIND_PACKAGE_RESOLVE_SYMLINKS ON) +find_package(Resolved) +message(WARNING "${Resolved_DIR}") + +file(REMOVE "${CMAKE_CURRENT_SOURCE_DIR}/symlink") |