Pārlūkot izejas kodu

Merge topic 'find_program-conditional-cwd'

c76c1ea208 find_program: Consider CWD only for paths with separator

Acked-by: Kitware Robot <[email protected]>
Merge-request: !2120
Brad King 7 gadi atpakaļ
vecāks
revīzija
b0b99d877e

+ 26 - 8
Source/cmFindProgramCommand.cxx

@@ -34,6 +34,9 @@ struct cmFindProgramHelper
   // Current names under consideration.
   std::vector<std::string> Names;
 
+  // Current name with extension under consideration.
+  std::string TestNameExt;
+
   // Current full path under consideration.
   std::string TestPath;
 
@@ -43,6 +46,19 @@ struct cmFindProgramHelper
     this->Names.clear();
     this->AddName(name);
   }
+  bool CheckCompoundNames()
+  {
+    for (std::string const& n : this->Names) {
+      // Only perform search relative to current directory if the file name
+      // contains a directory separator.
+      if (n.find('/') != std::string::npos) {
+        if (this->CheckDirectoryForName("", n)) {
+          return true;
+        }
+      }
+    }
+    return false;
+  }
   bool CheckDirectory(std::string const& path)
   {
     for (std::string const& n : this->Names) {
@@ -55,14 +71,16 @@ struct cmFindProgramHelper
   bool CheckDirectoryForName(std::string const& path, std::string const& name)
   {
     for (std::string const& ext : this->Extensions) {
-      this->TestPath = path;
-      this->TestPath += name;
       if (!ext.empty() && cmSystemTools::StringEndsWith(name, ext.c_str())) {
         continue;
       }
-      this->TestPath += ext;
+      this->TestNameExt = name;
+      this->TestNameExt += ext;
+      this->TestPath =
+        cmSystemTools::CollapseCombinedPath(path, this->TestNameExt);
+
       if (cmSystemTools::FileExists(this->TestPath, true)) {
-        this->BestPath = cmSystemTools::CollapseFullPath(this->TestPath);
+        this->BestPath = this->TestPath;
         return true;
       }
     }
@@ -145,8 +163,8 @@ std::string cmFindProgramCommand::FindNormalProgramNamesPerDir()
     helper.AddName(n);
   }
 
-  // Check for the names themselves (e.g. absolute paths).
-  if (helper.CheckDirectory(std::string())) {
+  // Check for the names themselves if they contain a directory separator.
+  if (helper.CheckCompoundNames()) {
     return helper.BestPath;
   }
 
@@ -168,8 +186,8 @@ std::string cmFindProgramCommand::FindNormalProgramDirsPerName()
     // Switch to searching for this name.
     helper.SetName(n);
 
-    // Check for the name by itself (e.g. an absolute path).
-    if (helper.CheckDirectory(std::string())) {
+    // Check for the names themselves if they contain a directory separator.
+    if (helper.CheckCompoundNames()) {
       return helper.BestPath;
     }
 

+ 6 - 0
Tests/RunCMake/find_program/RelAndAbsPath-stdout.txt

@@ -0,0 +1,6 @@
+-- PROG_ABS='PROG_ABS-NOTFOUND'
+-- PROG_ABS_NPD='PROG_ABS_NPD-NOTFOUND'
+-- PROG_CWD='PROG_CWD-NOTFOUND'
+-- PROG_CWD_NPD='PROG_CWD_NPD-NOTFOUND'
+-- PROG_CWD_DOT='[^']*/Tests/RunCMake/find_program/testCWD'
+-- PROG_CWD_DOT_NPD='[^']*/Tests/RunCMake/find_program/testCWD'

+ 63 - 0
Tests/RunCMake/find_program/RelAndAbsPath.cmake

@@ -0,0 +1,63 @@
+# testNoSuchFile should only be found if the file absolute path is
+# incorrectly prepended with the search path.
+
+function(strip_windows_path_prefix p outvar)
+    if(CMAKE_HOST_SYSTEM_NAME MATCHES "Windows")
+        string(REGEX REPLACE "^.:" "" p "${p}")
+    endif()
+    set(${outvar} "${p}" PARENT_SCOPE)
+endfunction()
+
+strip_windows_path_prefix("${CMAKE_CURRENT_SOURCE_DIR}" srcdir)
+
+file(MAKE_DIRECTORY "tmp${srcdir}")
+configure_file(testCWD "tmp${srcdir}/testNoSuchFile" COPYONLY)
+
+find_program(PROG_ABS
+  NAMES "${srcdir}/testNoSuchFile"
+  PATHS "${CMAKE_CURRENT_BINARY_DIR}/tmp"
+  NO_DEFAULT_PATH
+  )
+message(STATUS "PROG_ABS='${PROG_ABS}'")
+
+find_program(PROG_ABS_NPD
+  NAMES "${srcdir}/testNoSuchFile"
+  PATHS "${CMAKE_CURRENT_BINARY_DIR}/tmp"
+  NAMES_PER_DIR
+  NO_DEFAULT_PATH
+  )
+message(STATUS "PROG_ABS_NPD='${PROG_ABS_NPD}'")
+
+# ./testCWD should not be found without '.' being in the path list.
+
+configure_file(testCWD testCWD COPYONLY)
+
+find_program(PROG_CWD
+  NAMES testCWD
+  NO_DEFAULT_PATH
+  )
+message(STATUS "PROG_CWD='${PROG_CWD}'")
+
+find_program(PROG_CWD_NPD
+  NAMES testCWD
+  NAMES_PER_DIR
+  NO_DEFAULT_PATH
+  )
+message(STATUS "PROG_CWD_NPD='${PROG_CWD_NPD}'")
+
+# Confirm that adding '.' to path does locate ./testCWD.
+
+find_program(PROG_CWD_DOT
+  NAMES testCWD
+  PATHS .
+  NO_DEFAULT_PATH
+  )
+message(STATUS "PROG_CWD_DOT='${PROG_CWD_DOT}'")
+
+find_program(PROG_CWD_DOT_NPD
+  NAMES testCWD
+  PATHS .
+  NAMES_PER_DIR
+  NO_DEFAULT_PATH
+  )
+message(STATUS "PROG_CWD_DOT_NPD='${PROG_CWD_DOT_NPD}'")

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

@@ -3,6 +3,7 @@ include(RunCMake)
 run_cmake(EnvAndHints)
 run_cmake(DirsPerName)
 run_cmake(NamesPerDir)
+run_cmake(RelAndAbsPath)
 
 if(CMAKE_SYSTEM_NAME MATCHES "^(Windows|CYGWIN)$")
   run_cmake(WindowsCom)

+ 1 - 0
Tests/RunCMake/find_program/testCWD

@@ -0,0 +1 @@
+#!/bin/sh