diff options
author | Brad King <brad.king@kitware.com> | 2023-09-09 00:06:13 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2023-09-10 11:33:47 (GMT) |
commit | 84a25fc263b19dc12b062b1272546638721ca28a (patch) | |
tree | 2c5a75a6f073119178d9691b80a9c6a6260fb3ab | |
parent | cdcff0a0f0b67b19ebd0fb49c6d54a9bca71581e (diff) | |
download | CMake-84a25fc263b19dc12b062b1272546638721ca28a.zip CMake-84a25fc263b19dc12b062b1272546638721ca28a.tar.gz CMake-84a25fc263b19dc12b062b1272546638721ca28a.tar.bz2 |
cmake_host_system_information: Add MSYSTEM_PREFIX query
Add a query on Windows hosts for the installation prefix of a
MSYS or MinGW development environment.
Issue: #24216
13 files changed, 146 insertions, 0 deletions
diff --git a/.gitlab/ci/configure_mingw_osdn_io_common.cmake b/.gitlab/ci/configure_mingw_osdn_io_common.cmake index 55dce1d..d316233 100644 --- a/.gitlab/ci/configure_mingw_osdn_io_common.cmake +++ b/.gitlab/ci/configure_mingw_osdn_io_common.cmake @@ -1,5 +1,8 @@ set(CMake_TEST_Java OFF CACHE BOOL "") +get_filename_component(mingw_dir "${CMAKE_CURRENT_LIST_DIR}/../mingw" ABSOLUTE) +set(CMake_TEST_MSYSTEM_PREFIX "${mingw_dir}" CACHE STRING "") + set(configure_no_sccache 1) include("${CMAKE_CURRENT_LIST_DIR}/configure_external_test.cmake") diff --git a/Help/command/cmake_host_system_information.rst b/Help/command/cmake_host_system_information.rst index 76824ef..dad0833 100644 --- a/Help/command/cmake_host_system_information.rst +++ b/Help/command/cmake_host_system_information.rst @@ -146,6 +146,13 @@ queried. The list of queried values is stored in ``<variable>``. See :variable:`CMAKE_HOST_SYSTEM_PROCESSOR` +``MSYSTEM_PREFIX`` + .. versionadded:: 3.28 + + Available only on Windows hosts. In a MSYS or MinGW development + environment that sets the ``MSYSTEM`` environment variable, this + is its installation prefix. Otherwise, this is the empty string. + ``DISTRIB_INFO`` .. versionadded:: 3.22 diff --git a/Help/release/dev/host-msystem-prefix.rst b/Help/release/dev/host-msystem-prefix.rst new file mode 100644 index 0000000..4377144 --- /dev/null +++ b/Help/release/dev/host-msystem-prefix.rst @@ -0,0 +1,6 @@ +host-msystem-prefix +------------------- + +* The :command:`cmake_host_system_information` command gained a + ``MSYSTEM_PREFIX`` query for the installation prefix of a MSYS + or MinGW development environment on Windows hosts. diff --git a/Source/cmCMakeHostSystemInformationCommand.cxx b/Source/cmCMakeHostSystemInformationCommand.cxx index e9fc72e..0efb9a4 100644 --- a/Source/cmCMakeHostSystemInformationCommand.cxx +++ b/Source/cmCMakeHostSystemInformationCommand.cxx @@ -414,6 +414,86 @@ cm::optional<std::string> GetDistribValue(cmExecutionStatus& status, } #ifdef _WIN32 +std::string FindMSYSTEM_PREFIX(std::vector<std::string> prefixes) +{ + for (std::string const& prefix : prefixes) { + std::string out; + std::string err; + int ret; + // In a modern MSYSTEM environment we expect cygpath to be in PATH. + std::vector<std::string> cygpath_cmd{ "cygpath", "-w", prefix }; + if (cmSystemTools::RunSingleCommand(cygpath_cmd, &out, &err, &ret, nullptr, + cmSystemTools::OUTPUT_NONE)) { + if (ret == 0) { + out = cmTrimWhitespace(out); + cmSystemTools::ConvertToUnixSlashes(out); + if (cmSystemTools::FileIsDirectory(out)) { + return out; + } + } + } else { + // In a legacy MSYSTEM environment (MinGW/MSYS 1.0) there is no + // cygpath but we expect 'sh' to be in PATH. + std::vector<std::string> sh_cmd{ + "sh", "-c", cmStrCat("cd \"", prefix, "\" && cmd //c cd") + }; + if (cmSystemTools::RunSingleCommand(sh_cmd, &out, &err, &ret, nullptr, + cmSystemTools::OUTPUT_NONE)) { + if (ret == 0) { + out = cmTrimWhitespace(out); + cmSystemTools::ConvertToUnixSlashes(out); + if (cmSystemTools::FileIsDirectory(out)) { + return out; + } + } + } + } + } + return {}; +} + +std::string FallbackMSYSTEM_PREFIX(cm::string_view msystem) +{ + // These layouts are used by distributions such as + // * MSYS2: https://www.msys2.org/docs/environments/ + // * MinGW/MSYS 1.0: http://mingw.osdn.io/ + if (msystem == "MSYS"_s) { + static std::string const msystem_msys = FindMSYSTEM_PREFIX({ "/usr" }); + return msystem_msys; + } + if (msystem == "MINGW32"_s) { + static std::string const msystem_mingw32 = + FindMSYSTEM_PREFIX({ "/mingw32", "/mingw" }); + return msystem_mingw32; + } + if (msystem == "MINGW64"_s) { + static std::string const msystem_mingw64 = + FindMSYSTEM_PREFIX({ "/mingw64" }); + return msystem_mingw64; + } + if (msystem == "UCRT64"_s) { + static std::string const msystem_ucrt64 = + FindMSYSTEM_PREFIX({ "/ucrt64" }); + return msystem_ucrt64; + } + if (msystem == "CLANG32"_s) { + static std::string const msystem_clang32 = + FindMSYSTEM_PREFIX({ "/clang32" }); + return msystem_clang32; + } + if (msystem == "CLANG64"_s) { + static std::string const msystem_clang64 = + FindMSYSTEM_PREFIX({ "/clang64" }); + return msystem_clang64; + } + if (msystem == "CLANGARM64"_s) { + static std::string const msystem_clangarm64 = + FindMSYSTEM_PREFIX({ "/clangarm64" }); + return msystem_clangarm64; + } + return {}; +} + cm::optional<std::string> GetWindowsValue(cmExecutionStatus& status, std::string const& key) { @@ -446,6 +526,23 @@ cm::optional<std::string> GetWindowsValue(cmExecutionStatus& status, return vs10gen->FindMSBuildCommandEarly(&status.GetMakefile()); } + if (key == "MSYSTEM_PREFIX") { + // MSYSTEM_PREFIX is meaningful only under a MSYSTEM environment. + cm::optional<std::string> ms = cmSystemTools::GetEnvVar("MSYSTEM"); + if (!ms || ms->empty()) { + return std::string(); + } + // Prefer the MSYSTEM_PREFIX environment variable. + if (cm::optional<std::string> msp = + cmSystemTools::GetEnvVar("MSYSTEM_PREFIX")) { + cmSystemTools::ConvertToUnixSlashes(*msp); + if (cmSystemTools::FileIsDirectory(*msp)) { + return msp; + } + } + // Fall back to known distribution layouts. + return FallbackMSYSTEM_PREFIX(*ms); + } return {}; } #endif diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index 5e212bd..02efb25 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -474,6 +474,9 @@ if(NOT CMake_TEST_EXTERNAL_CMAKE) endif() add_RunCMake_test(execute_process) add_RunCMake_test(export) +if(CMake_TEST_MSYSTEM_PREFIX) + list(APPEND cmake_host_system_information_ARGS -DCMake_TEST_MSYSTEM_PREFIX=${CMake_TEST_MSYSTEM_PREFIX}) +endif() add_RunCMake_test(cmake_host_system_information) add_RunCMake_test(cmake_language) add_RunCMake_test(cmake_minimum_required) diff --git a/Tests/RunCMake/cmake_host_system_information/MSYSTEM_PREFIX-Empty-stdout.txt b/Tests/RunCMake/cmake_host_system_information/MSYSTEM_PREFIX-Empty-stdout.txt new file mode 100644 index 0000000..d5a0ca8 --- /dev/null +++ b/Tests/RunCMake/cmake_host_system_information/MSYSTEM_PREFIX-Empty-stdout.txt @@ -0,0 +1 @@ +MSYSTEM_PREFIX='' diff --git a/Tests/RunCMake/cmake_host_system_information/MSYSTEM_PREFIX-Empty.cmake b/Tests/RunCMake/cmake_host_system_information/MSYSTEM_PREFIX-Empty.cmake new file mode 100644 index 0000000..ac36c8d --- /dev/null +++ b/Tests/RunCMake/cmake_host_system_information/MSYSTEM_PREFIX-Empty.cmake @@ -0,0 +1,3 @@ +unset(ENV{MSYSTEM}) +cmake_host_system_information(RESULT result QUERY MSYSTEM_PREFIX) +message(STATUS "MSYSTEM_PREFIX='${result}'") diff --git a/Tests/RunCMake/cmake_host_system_information/MSYSTEM_PREFIX-Missing-result.txt b/Tests/RunCMake/cmake_host_system_information/MSYSTEM_PREFIX-Missing-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/cmake_host_system_information/MSYSTEM_PREFIX-Missing-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/cmake_host_system_information/MSYSTEM_PREFIX-Missing-stderr.txt b/Tests/RunCMake/cmake_host_system_information/MSYSTEM_PREFIX-Missing-stderr.txt new file mode 100644 index 0000000..89c4e9b --- /dev/null +++ b/Tests/RunCMake/cmake_host_system_information/MSYSTEM_PREFIX-Missing-stderr.txt @@ -0,0 +1,3 @@ +^CMake Error at [^ +]*/Tests/RunCMake/cmake_host_system_information/MSYSTEM_PREFIX-Missing.cmake:[0-9]+ \(cmake_host_system_information\): + cmake_host_system_information does not recognize <key> MSYSTEM_PREFIX$ diff --git a/Tests/RunCMake/cmake_host_system_information/MSYSTEM_PREFIX-Missing.cmake b/Tests/RunCMake/cmake_host_system_information/MSYSTEM_PREFIX-Missing.cmake new file mode 100644 index 0000000..dc1def3 --- /dev/null +++ b/Tests/RunCMake/cmake_host_system_information/MSYSTEM_PREFIX-Missing.cmake @@ -0,0 +1,2 @@ +unset(ENV{MSYSTEM}) +cmake_host_system_information(RESULT result QUERY MSYSTEM_PREFIX) diff --git a/Tests/RunCMake/cmake_host_system_information/MSYSTEM_PREFIX-stdout.txt b/Tests/RunCMake/cmake_host_system_information/MSYSTEM_PREFIX-stdout.txt new file mode 100644 index 0000000..f6e2549 --- /dev/null +++ b/Tests/RunCMake/cmake_host_system_information/MSYSTEM_PREFIX-stdout.txt @@ -0,0 +1,2 @@ +-- MSYSTEM_PREFIX='[^ +]+' diff --git a/Tests/RunCMake/cmake_host_system_information/MSYSTEM_PREFIX.cmake b/Tests/RunCMake/cmake_host_system_information/MSYSTEM_PREFIX.cmake new file mode 100644 index 0000000..d1c996b --- /dev/null +++ b/Tests/RunCMake/cmake_host_system_information/MSYSTEM_PREFIX.cmake @@ -0,0 +1,7 @@ +cmake_host_system_information(RESULT result QUERY MSYSTEM_PREFIX) +message(STATUS "MSYSTEM_PREFIX='${result}'") +if(CMake_TEST_MSYSTEM_PREFIX) + if(NOT "${result}" STREQUAL "${CMake_TEST_MSYSTEM_PREFIX}") + message(FATAL_ERROR "Actual result:\n ${result}\nis not expected result:\n ${CMake_TEST_MSYSTEM_PREFIX}") + endif() +endif() diff --git a/Tests/RunCMake/cmake_host_system_information/RunCMakeTest.cmake b/Tests/RunCMake/cmake_host_system_information/RunCMakeTest.cmake index 9122470..0b3576d 100644 --- a/Tests/RunCMake/cmake_host_system_information/RunCMakeTest.cmake +++ b/Tests/RunCMake/cmake_host_system_information/RunCMakeTest.cmake @@ -22,6 +22,17 @@ else() run_cmake(VsMSBuildMissing) endif() +if(CMAKE_HOST_WIN32) + run_cmake_script(MSYSTEM_PREFIX-Empty) + if("$ENV{MSYSTEM}" MATCHES "(MSYS|MINGW32|MINGW64|UCRT64)") + set(RunCMake_TEST_VARIANT_DESCRIPTION "-$ENV{MSYSTEM}") + run_cmake_script(MSYSTEM_PREFIX -DCMake_TEST_MSYSTEM_PREFIX=${CMake_TEST_MSYSTEM_PREFIX}) + unset(RunCMake_TEST_VARIANT_DESCRIPTION) + endif() +else() + run_cmake_script(MSYSTEM_PREFIX-Missing) +endif() + # WINDOWS_REGISTRY tests run_cmake(Registry_NoArgs) run_cmake(Registry_BadQuery1) |