浏览代码

Merge branch 'implicit-dir-symlinks' into release

Brad King 8 年之前
父节点
当前提交
8d1af9cad2

+ 15 - 7
Source/cmOrderDirectories.cxx

@@ -287,8 +287,7 @@ void cmOrderDirectories::AddRuntimeLibrary(std::string const& fullPath,
         }
       }
 
-      if (this->ImplicitDirectories.find(dir) !=
-          this->ImplicitDirectories.end()) {
+      if (this->IsImplicitDirectory(dir)) {
         this->ImplicitDirEntries.push_back(
           new cmOrderDirectoriesConstraintSOName(this, fullPath, soname));
         return;
@@ -316,8 +315,7 @@ void cmOrderDirectories::AddLinkLibrary(std::string const& fullPath)
     // Implicit link directories need special handling.
     if (!this->ImplicitDirectories.empty()) {
       std::string dir = cmSystemTools::GetFilenamePath(fullPath);
-      if (this->ImplicitDirectories.find(dir) !=
-          this->ImplicitDirectories.end()) {
+      if (this->IsImplicitDirectory(dir)) {
         this->ImplicitDirEntries.push_back(
           new cmOrderDirectoriesConstraintLibrary(this, fullPath));
         return;
@@ -347,7 +345,18 @@ void cmOrderDirectories::AddLanguageDirectories(
 void cmOrderDirectories::SetImplicitDirectories(
   std::set<std::string> const& implicitDirs)
 {
-  this->ImplicitDirectories = implicitDirs;
+  this->ImplicitDirectories.clear();
+  for (std::set<std::string>::const_iterator i = implicitDirs.begin();
+       i != implicitDirs.end(); ++i) {
+    this->ImplicitDirectories.insert(this->GetRealPath(*i));
+  }
+}
+
+bool cmOrderDirectories::IsImplicitDirectory(std::string const& dir)
+{
+  std::string const& real = this->GetRealPath(dir);
+  return this->ImplicitDirectories.find(real) !=
+    this->ImplicitDirectories.end();
 }
 
 void cmOrderDirectories::SetLinkExtensionInfo(
@@ -394,8 +403,7 @@ void cmOrderDirectories::AddOriginalDirectories(
   for (std::vector<std::string>::const_iterator di = dirs.begin();
        di != dirs.end(); ++di) {
     // We never explicitly specify implicit link directories.
-    if (this->ImplicitDirectories.find(*di) !=
-        this->ImplicitDirectories.end()) {
+    if (this->IsImplicitDirectory(*di)) {
       continue;
     }
 

+ 2 - 0
Source/cmOrderDirectories.h

@@ -82,6 +82,8 @@ private:
   // Compare directories after resolving symlinks.
   bool IsSameDirectory(std::string const& l, std::string const& r);
 
+  bool IsImplicitDirectory(std::string const& dir);
+
   std::string const& GetRealPath(std::string const& dir);
   std::map<std::string, std::string> RealPaths;
 

+ 3 - 0
Tests/RunCMake/CMakeLists.txt

@@ -153,6 +153,9 @@ add_RunCMake_test(TargetPropertyGeneratorExpressions)
 add_RunCMake_test(Languages)
 add_RunCMake_test(LinkStatic)
 add_RunCMake_test(ObjectLibrary)
+if(UNIX AND CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG AND CMAKE_EXECUTABLE_FORMAT STREQUAL "ELF")
+  add_RunCMake_test(RuntimePath)
+endif()
 add_RunCMake_test(Swift)
 add_RunCMake_test(TargetObjects)
 add_RunCMake_test(TargetSources)

+ 4 - 0
Tests/RunCMake/RuntimePath/A.c

@@ -0,0 +1,4 @@
+int libA(void)
+{
+  return 0;
+}

+ 3 - 0
Tests/RunCMake/RuntimePath/CMakeLists.txt

@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.7)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)

+ 18 - 0
Tests/RunCMake/RuntimePath/RunCMakeTest.cmake

@@ -0,0 +1,18 @@
+include(RunCMake)
+
+
+function(run_SymlinkImplicit)
+  # Use a single build tree for a few tests without cleaning.
+  set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/SymlinkImplicit-build)
+  set(RunCMake_TEST_NO_CLEAN 1)
+  if(RunCMake_GENERATOR MATCHES "Make|Ninja")
+    set(RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=Debug)
+  endif()
+  file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+  file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+  run_cmake(SymlinkImplicit)
+  run_cmake_command(SymlinkImplicit-build ${CMAKE_COMMAND} --build . --config Debug)
+  run_cmake_command(SymlinkImplicitCheck
+    ${CMAKE_COMMAND} -Ddir=${RunCMake_TEST_BINARY_DIR} -P ${RunCMake_SOURCE_DIR}/SymlinkImplicitCheck.cmake)
+endfunction()
+run_SymlinkImplicit()

+ 17 - 0
Tests/RunCMake/RuntimePath/SymlinkImplicit.cmake

@@ -0,0 +1,17 @@
+enable_language(C)
+
+set(lib_dir ${CMAKE_CURRENT_BINARY_DIR}/lib)
+set(lib_link ${CMAKE_CURRENT_BINARY_DIR}/libLink)
+set(lib_always ${CMAKE_CURRENT_BINARY_DIR}/libAlways)
+file(MAKE_DIRECTORY ${lib_dir})
+execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink lib ${lib_link})
+execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink lib ${lib_always})
+
+add_library(A SHARED A.c)
+list(APPEND CMAKE_C_IMPLICIT_LINK_DIRECTORIES ${lib_dir})
+set_property(TARGET A PROPERTY LIBRARY_OUTPUT_DIRECTORY ${lib_link})
+
+add_executable(exe main.c)
+target_link_libraries(exe A)
+set_property(TARGET exe PROPERTY RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/bin)
+set_property(TARGET exe PROPERTY BUILD_RPATH ${lib_always})

+ 1 - 0
Tests/RunCMake/RuntimePath/SymlinkImplicitCheck-result.txt

@@ -0,0 +1 @@
+1

+ 22 - 0
Tests/RunCMake/RuntimePath/SymlinkImplicitCheck-stderr.txt

@@ -0,0 +1,22 @@
+^CMake Error at .*/Tests/RunCMake/RuntimePath/SymlinkImplicitCheck.cmake:[0-9]+ \(file\):
+  file RPATH_CHANGE could not write new RPATH:
+
+    old-should-not-exist
+
+  to the file:
+
+    [^
+]*/Tests/RunCMake/RuntimePath/SymlinkImplicit-build/exe
+
+  The current (RPATH|RUNPATH) is:
+
+    [^
+]*/Tests/RunCMake/RuntimePath/SymlinkImplicit-build/libAlways(:[^
+]*)?
+
+  which does not contain:
+
+    [^
+]*/Tests/RunCMake/RuntimePath/SymlinkImplicit-build/libLink
+
+  as was expected\.$

+ 2 - 0
Tests/RunCMake/RuntimePath/SymlinkImplicitCheck.cmake

@@ -0,0 +1,2 @@
+file(COPY ${dir}/bin/exe DESTINATION ${dir})
+file(RPATH_CHANGE FILE "${dir}/exe" OLD_RPATH "${dir}/libLink" NEW_RPATH "old-should-not-exist")

+ 4 - 0
Tests/RunCMake/RuntimePath/main.c

@@ -0,0 +1,4 @@
+int main(void)
+{
+  return 0;
+}