summaryrefslogtreecommitdiffstats
path: root/Source/cmCMakeHostSystemInformationCommand.cxx
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 /Source/cmCMakeHostSystemInformationCommand.cxx
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
Diffstat (limited to 'Source/cmCMakeHostSystemInformationCommand.cxx')
-rw-r--r--Source/cmCMakeHostSystemInformationCommand.cxx97
1 files changed, 97 insertions, 0 deletions
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