Browse Source

Merge topic 'restore-home-tidle' into release-4.0

01f92efeb0 Restore expansion of leading '~' as home directory in input paths

Acked-by: Kitware Robot <[email protected]>
Merge-request: !10580
Brad King 8 months ago
parent
commit
77b3c85fe8

+ 5 - 0
Source/CMakeLists.txt

@@ -1033,6 +1033,11 @@ endif()
 if(CMAKE_SYSTEM_NAME STREQUAL "SunOS" AND CMAKE_SYSTEM_VERSION STREQUAL "5.10" AND CMAKE_SYSTEM_PROCESSOR MATCHES "^(i386|x86_64)$")
   set_property(SOURCE cmSystemTools.cxx APPEND PROPERTY COMPILE_DEFINITIONS CMAKE_NO_MKDTEMP)
 endif()
+get_property(targetSupportsSharedLibs GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS)
+if(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND NOT targetSupportsSharedLibs)
+  # Disable getpwnam for static linux builds since it depends on shared glibc.
+  set_property(SOURCE cmSystemTools.cxx APPEND PROPERTY COMPILE_DEFINITIONS CMAKE_NO_GETPWNAM)
+endif()
 
 # Some atomic instructions are implemented using libatomic on some platforms.
 if(CMake_HAVE_CXX_ATOMIC_LIB)

+ 39 - 0
Source/cmSystemTools.cxx

@@ -149,6 +149,15 @@
 #  include <dlfcn.h>
 #endif
 
+#ifndef CMAKE_NO_GETPWNAM
+#  if defined(_WIN32)
+#    define CMAKE_NO_GETPWNAM
+#  endif
+#endif
+#ifndef CMAKE_NO_GETPWNAM
+#  include <pwd.h>
+#endif
+
 #if defined(_MSC_VER) && _MSC_VER >= 1800
 #  define CM_WINDOWS_DEPRECATED_GetVersionEx
 #endif
@@ -160,6 +169,35 @@ cmSystemTools::MessageCallback s_MessageCallback;
 cmSystemTools::OutputCallback s_StderrCallback;
 cmSystemTools::OutputCallback s_StdoutCallback;
 
+std::string ResolveTildePath(std::string p)
+{
+  if (!p.empty() && p[0] == '~') {
+    cm::optional<std::string> home;
+    std::string::size_type last = p.find_first_of("/\\");
+    if (last == std::string::npos) {
+      last = p.size();
+    }
+    if (last == 1) {
+#if defined(_WIN32) && !defined(__CYGWIN__)
+      home = cmSystemTools::GetEnvVar("USERPROFILE");
+      if (!home)
+#endif
+        home = cmSystemTools::GetEnvVar("HOME");
+#ifndef CMAKE_NO_GETPWNAM
+    } else if (last > 1) {
+      std::string user = p.substr(1, last - 1);
+      if (passwd* pw = getpwnam(user.c_str())) {
+        home = std::string(pw->pw_dir);
+      }
+#endif
+    }
+    if (home) {
+      p.replace(0, last, *home);
+    }
+  }
+  return p;
+}
+
 #ifdef _WIN32
 std::string GetDosDriveWorkingDirectory(char letter)
 {
@@ -2044,6 +2082,7 @@ std::vector<std::string> cmSystemTools::SplitEnvPathNormalized(
 
 std::string cmSystemTools::ToNormalizedPathOnDisk(std::string p)
 {
+  p = ResolveTildePath(p);
   using namespace cm::PathResolver;
 #ifdef _WIN32
   // IWYU pragma: no_forward_declare cm::PathResolver::Policies::CasePath

+ 21 - 0
Tests/RunCMake/CommandLine/D-tilde.cmake

@@ -0,0 +1,21 @@
+if(NOT "$ENV{HOME}" STREQUAL "")
+  if(TILDE_PATH MATCHES "~" OR NOT IS_ABSOLUTE "${TILDE_PATH}")
+    message(SEND_ERROR "~ not expanded as expected:\n ${TILDE_PATH}")
+  endif()
+
+  if(TILDE_SLASH_PATH MATCHES "~" OR NOT IS_ABSOLUTE "${TILDE_SLASH_PATH}" OR NOT TILDE_SLASH_PATH MATCHES "/InHome$")
+    message(SEND_ERROR "~/ not expanded as expected:\n ${TILDE_SLASH_PATH}")
+  endif()
+else()
+  set(ENV{HOME} "${CMAKE_CURRENT_LIST_DIR}")
+endif()
+
+set(TILDE "" CACHE PATH "")
+if(TILDE MATCHES "~" OR NOT IS_ABSOLUTE "${TILDE}")
+  message(SEND_ERROR "~ not expanded as expected:\n ${TILDE}")
+endif()
+
+set(TILDE_SLASH "" CACHE PATH "")
+if(TILDE_SLASH MATCHES "~" OR NOT IS_ABSOLUTE "${TILDE_SLASH}" OR NOT TILDE_SLASH MATCHES "/InHome$")
+  message(SEND_ERROR "~/ not expanded as expected:\n ${TILDE_SLASH}")
+endif()

+ 1 - 0
Tests/RunCMake/CommandLine/RunCMakeTest.cmake

@@ -18,6 +18,7 @@ run_cmake_command(lists-no-file ${CMAKE_COMMAND} nosuchsubdir/CMakeLists.txt)
 run_cmake_command(D-no-arg ${CMAKE_COMMAND} -B DummyBuildDir -D)
 run_cmake_command(D-no-src ${CMAKE_COMMAND} -B DummyBuildDir -D VAR=VALUE)
 run_cmake_command(Dno-src ${CMAKE_COMMAND} -B DummyBuildDir -DVAR=VALUE)
+run_cmake_script(D-tilde -DTILDE=~ -DTILDE_PATH:PATH=~ -DTILDE_SLASH=~/InHome -DTILDE_SLASH_PATH:PATH=~/InHome)
 run_cmake_command(U-no-arg ${CMAKE_COMMAND} -B DummyBuildDir -U)
 run_cmake_command(U-no-src ${CMAKE_COMMAND} -B DummyBuildDir -U VAR)
 run_cmake_command(Uno-src ${CMAKE_COMMAND} -B DummyBuildDir -UVAR)