summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2023-09-09 00:06:13 (GMT)
committerBrad King <brad.king@kitware.com>2023-09-10 11:33:47 (GMT)
commit84a25fc263b19dc12b062b1272546638721ca28a (patch)
tree2c5a75a6f073119178d9691b80a9c6a6260fb3ab
parentcdcff0a0f0b67b19ebd0fb49c6d54a9bca71581e (diff)
downloadCMake-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
-rw-r--r--.gitlab/ci/configure_mingw_osdn_io_common.cmake3
-rw-r--r--Help/command/cmake_host_system_information.rst7
-rw-r--r--Help/release/dev/host-msystem-prefix.rst6
-rw-r--r--Source/cmCMakeHostSystemInformationCommand.cxx97
-rw-r--r--Tests/RunCMake/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/cmake_host_system_information/MSYSTEM_PREFIX-Empty-stdout.txt1
-rw-r--r--Tests/RunCMake/cmake_host_system_information/MSYSTEM_PREFIX-Empty.cmake3
-rw-r--r--Tests/RunCMake/cmake_host_system_information/MSYSTEM_PREFIX-Missing-result.txt1
-rw-r--r--Tests/RunCMake/cmake_host_system_information/MSYSTEM_PREFIX-Missing-stderr.txt3
-rw-r--r--Tests/RunCMake/cmake_host_system_information/MSYSTEM_PREFIX-Missing.cmake2
-rw-r--r--Tests/RunCMake/cmake_host_system_information/MSYSTEM_PREFIX-stdout.txt2
-rw-r--r--Tests/RunCMake/cmake_host_system_information/MSYSTEM_PREFIX.cmake7
-rw-r--r--Tests/RunCMake/cmake_host_system_information/RunCMakeTest.cmake11
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)