[Cmake-commits] CMake branch, next, updated. v3.5.2-1455-g48d6c42

Brad King brad.king at kitware.com
Tue May 17 09:50:23 EDT 2016


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "CMake".

The branch, next has been updated
       via  48d6c426e5a5634f9897ef6ecc6d8e9918fdd405 (commit)
       via  8a862a4d4b852c9f61ae4ed7fc46042b00a83123 (commit)
       via  038e7716e58e4cf79bda6ba72b92814a14978a8f (commit)
       via  7c26a6a269b0c12ecdf7605183d9fa26ad2b91eb (commit)
       via  ac3cdd9af287e653d53b18c432f21a919b102158 (commit)
       via  d4381cb15df3e81b78b6d8d9e7d9b727a616985d (commit)
       via  0397c92a15e505021d75eb0a156a312b024eb85e (commit)
       via  3b3ecdfa4872a86dcb8eb7d5f5478259890d4707 (commit)
       via  5ca72750c8de3c1c925c433293eb3bc6b3ea234c (commit)
      from  1c84ab1660ee48611ca04fc739613c7d553d6ae3 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=48d6c426e5a5634f9897ef6ecc6d8e9918fdd405
commit 48d6c426e5a5634f9897ef6ecc6d8e9918fdd405
Merge: 1c84ab1 8a862a4
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Tue May 17 09:50:20 2016 -0400
Commit:     CMake Topic Stage <kwrobot at kitware.com>
CommitDate: Tue May 17 09:50:20 2016 -0400

    Merge topic 'ninja-output-path-prefix' into next
    
    8a862a4d Ninja: Support embedding of CMake as subninja project
    038e7716 Ninja: Pass all build paths through a central method
    7c26a6a2 Ninja: Fix path to soname-d target file
    ac3cdd9a Ninja: Convert object file names to ninja paths earlier
    d4381cb1 Ninja: Convert link library file names like all other output paths
    0397c92a Ninja: Pre-compute "CMakeCache.txt" build target name
    3b3ecdfa Ninja: Pre-compute "all" build target name
    5ca72750 Ninja: Simplify generation of custom target logical path


https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=8a862a4d4b852c9f61ae4ed7fc46042b00a83123
commit 8a862a4d4b852c9f61ae4ed7fc46042b00a83123
Author:     Nicolas Despres <nicolas.despres at gmail.com>
AuthorDate: Sat May 14 01:18:20 2016 +0200
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Tue May 17 09:34:12 2016 -0400

    Ninja: Support embedding of CMake as subninja project
    
    Add a `CMAKE_NINJA_OUTPUT_PATH_PREFIX` variable.  When it is set, CMake
    generates a `build.ninja` file suitable for embedding into another ninja
    project potentially generated by an alien generator.

diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst
index 181fbbc..ec741ae 100644
--- a/Help/manual/cmake-variables.7.rst
+++ b/Help/manual/cmake-variables.7.rst
@@ -281,6 +281,7 @@ Variables that Control the Build
    /variable/CMAKE_MAP_IMPORTED_CONFIG_CONFIG
    /variable/CMAKE_MODULE_LINKER_FLAGS_CONFIG
    /variable/CMAKE_MODULE_LINKER_FLAGS
+   /variable/CMAKE_NINJA_OUTPUT_PATH_PREFIX
    /variable/CMAKE_NO_BUILTIN_CHRPATH
    /variable/CMAKE_NO_SYSTEM_FROM_IMPORTED
    /variable/CMAKE_OSX_ARCHITECTURES
diff --git a/Help/release/dev/ninja-output-path-prefix.rst b/Help/release/dev/ninja-output-path-prefix.rst
new file mode 100644
index 0000000..47a9660
--- /dev/null
+++ b/Help/release/dev/ninja-output-path-prefix.rst
@@ -0,0 +1,6 @@
+ninja-output-path-prefix
+------------------------
+
+* The :generator:`Ninja` generator learned to read a new
+  :variable:`CMAKE_NINJA_OUTPUT_PATH_PREFIX` variable to configure
+  the generated ``build.ninja`` file for use as a ``subninja``.
diff --git a/Help/variable/CMAKE_NINJA_OUTPUT_PATH_PREFIX.rst b/Help/variable/CMAKE_NINJA_OUTPUT_PATH_PREFIX.rst
new file mode 100644
index 0000000..64091aa
--- /dev/null
+++ b/Help/variable/CMAKE_NINJA_OUTPUT_PATH_PREFIX.rst
@@ -0,0 +1,27 @@
+CMAKE_NINJA_OUTPUT_PATH_PREFIX
+------------------------------
+
+Set output files path prefix for the :generator:`Ninja` generator.
+
+Every output files listed in the generated ``build.ninja`` will be
+prefixed by the contents of this variable (a trailing slash is
+appended if missing).  This is useful when the generated ninja file is
+meant to be embedded as a ``subninja`` file into a *super* ninja
+project.  For example, a ninja build file generated with a command
+like::
+
+  cd top-build-dir/sub &&
+  cmake -G Ninja -DCMAKE_NINJA_OUTPUT_PATH_PREFIX=sub/ path/to/source
+
+can be embedded in ``top-build-dir/build.ninja`` with a directive like
+this::
+
+  subninja sub/build.ninja
+
+The ``auto-regeneration`` rule in ``top-build-dir/build.ninja`` must have an
+order-only dependency on ``sub/build.ninja``.
+
+.. note::
+  When ``CMAKE_NINJA_OUTPUT_PATH_PREFIX`` is set, the project generated
+  by CMake cannot be used as a standalone project.  No default targets
+  are specified.
diff --git a/Source/cmAlgorithms.h b/Source/cmAlgorithms.h
index 76acaca..ee803c8 100644
--- a/Source/cmAlgorithms.h
+++ b/Source/cmAlgorithms.h
@@ -379,4 +379,19 @@ std::reverse_iterator<Iter> cmMakeReverseIterator(Iter it)
   return std::reverse_iterator<Iter>(it);
 }
 
+inline bool cmHasSuffix(const std::string& str, const std::string& suffix)
+{
+  if (str.size() < suffix.size()) {
+    return false;
+  }
+  return str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0;
+}
+
+inline void cmStripSuffixIfExists(std::string& str, const std::string& suffix)
+{
+  if (cmHasSuffix(str, suffix)) {
+    str.resize(str.size() - suffix.size());
+  }
+}
+
 #endif
diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx
index 3c5a8e3..d65b463 100644
--- a/Source/cmGlobalNinjaGenerator.cxx
+++ b/Source/cmGlobalNinjaGenerator.cxx
@@ -488,6 +488,7 @@ void cmGlobalNinjaGenerator::Generate()
   this->OpenBuildFileStream();
   this->OpenRulesFileStream();
 
+  this->InitOutputPathPrefix();
   this->TargetAll = this->NinjaOutputPath("all");
   this->CMakeCacheFile = this->NinjaOutputPath("CMakeCache.txt");
 
@@ -717,6 +718,23 @@ void cmGlobalNinjaGenerator::CloseRulesFileStream()
   }
 }
 
+static void EnsureTrailingSlash(std::string& path)
+{
+  if (path.empty()) {
+    return;
+  }
+  std::string::value_type last = path[path.size() - 1];
+#ifdef _WIN32
+  if (last != '\\') {
+    path += '\\';
+  }
+#else
+  if (last != '/') {
+    path += '/';
+  }
+#endif
+}
+
 std::string cmGlobalNinjaGenerator::ConvertToNinjaPath(const std::string& path)
 {
   cmLocalNinjaGenerator* ng =
@@ -1136,8 +1154,10 @@ void cmGlobalNinjaGenerator::WriteTargetAll(std::ostream& os)
   this->WritePhonyBuild(os, "The main all target.", outputs,
                         this->AllDependencies);
 
-  cmGlobalNinjaGenerator::WriteDefault(os, outputs,
-                                       "Make the all target the default.");
+  if (!this->HasOutputPathPrefix()) {
+    cmGlobalNinjaGenerator::WriteDefault(os, outputs,
+                                         "Make the all target the default.");
+  }
 }
 
 void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os)
@@ -1251,7 +1271,28 @@ void cmGlobalNinjaGenerator::WriteTargetHelp(std::ostream& os)
              /*variables=*/cmNinjaVars());
 }
 
+void cmGlobalNinjaGenerator::InitOutputPathPrefix()
+{
+  this->OutputPathPrefix =
+    this->LocalGenerators[0]->GetMakefile()->GetSafeDefinition(
+      "CMAKE_NINJA_OUTPUT_PATH_PREFIX");
+  EnsureTrailingSlash(this->OutputPathPrefix);
+}
+
 std::string cmGlobalNinjaGenerator::NinjaOutputPath(std::string const& path)
 {
-  return path;
+  if (!this->HasOutputPathPrefix() || cmSystemTools::FileIsFullPath(path)) {
+    return path;
+  }
+  return this->OutputPathPrefix + path;
+}
+
+void cmGlobalNinjaGenerator::StripNinjaOutputPathPrefixAsSuffix(
+  std::string& path)
+{
+  if (path.empty()) {
+    return;
+  }
+  EnsureTrailingSlash(path);
+  cmStripSuffixIfExists(path, this->OutputPathPrefix);
 }
diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h
index 15c0f34..6d9bfe8 100644
--- a/Source/cmGlobalNinjaGenerator.h
+++ b/Source/cmGlobalNinjaGenerator.h
@@ -315,6 +315,8 @@ public:
   bool SupportsConsolePool() const;
 
   std::string NinjaOutputPath(std::string const& path);
+  bool HasOutputPathPrefix() const { return !this->OutputPathPrefix.empty(); }
+  void StripNinjaOutputPathPrefixAsSuffix(std::string& path);
 
 protected:
   virtual void Generate();
@@ -401,6 +403,9 @@ private:
   std::string NinjaVersion;
 
 private:
+  void InitOutputPathPrefix();
+
+  std::string OutputPathPrefix;
   std::string TargetAll;
   std::string CMakeCacheFile;
 };
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index 994daea..4d58242 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -669,10 +669,12 @@ void cmNinjaTargetGenerator::EnsureDirectoryExists(
   if (cmSystemTools::FileIsFullPath(path.c_str())) {
     cmSystemTools::MakeDirectory(path.c_str());
   } else {
-    const std::string fullPath = std::string(this->GetGlobalGenerator()
-                                               ->GetCMakeInstance()
-                                               ->GetHomeOutputDirectory()) +
-      "/" + path;
+    cmGlobalNinjaGenerator* gg = this->GetGlobalGenerator();
+    std::string fullPath =
+      std::string(gg->GetCMakeInstance()->GetHomeOutputDirectory());
+    // Also ensures their is a trailing slash.
+    gg->StripNinjaOutputPathPrefixAsSuffix(fullPath);
+    fullPath += path;
     cmSystemTools::MakeDirectory(fullPath.c_str());
   }
 }
diff --git a/Tests/RunCMake/Ninja/CheckNoPrefixSubDir.cmake b/Tests/RunCMake/Ninja/CheckNoPrefixSubDir.cmake
new file mode 100644
index 0000000..b845f2f
--- /dev/null
+++ b/Tests/RunCMake/Ninja/CheckNoPrefixSubDir.cmake
@@ -0,0 +1,7 @@
+add_custom_target(check_no_prefix_sub_dir ALL
+  COMMAND "${CMAKE_COMMAND}"
+          "-DNINJA_OUTPUT_PATH_PREFIX=${CMAKE_NINJA_OUTPUT_PATH_PREFIX}"
+          "-DCUR_BIN_DIR=${CMAKE_CURRENT_BINARY_DIR}"
+          -P "${CMAKE_CURRENT_SOURCE_DIR}/CheckNoPrefixSubDirScript.cmake"
+  VERBATIM
+  )
diff --git a/Tests/RunCMake/Ninja/CheckNoPrefixSubDirScript.cmake b/Tests/RunCMake/Ninja/CheckNoPrefixSubDirScript.cmake
new file mode 100644
index 0000000..5a03fcb
--- /dev/null
+++ b/Tests/RunCMake/Ninja/CheckNoPrefixSubDirScript.cmake
@@ -0,0 +1,8 @@
+# Check that the prefix sub-directory is not repeated.
+
+if(EXISTS "${CUR_BIN_DIR}/${NINJA_OUTPUT_PATH_PREFIX}")
+  message(FATAL_ERROR
+    "no sub directory named after the CMAKE_NINJA_OUTPUT_PATH_PREFIX "
+    "should be in the binary directory."
+    )
+endif()
diff --git a/Tests/RunCMake/Ninja/CheckOutput.cmake b/Tests/RunCMake/Ninja/CheckOutput.cmake
new file mode 100644
index 0000000..ddb35a7
--- /dev/null
+++ b/Tests/RunCMake/Ninja/CheckOutput.cmake
@@ -0,0 +1,23 @@
+# Add rules to check the generated executable works.
+
+set(hello_output "${CMAKE_CURRENT_BINARY_DIR}/hello.output")
+add_custom_command(
+  OUTPUT "${hello_output}"
+  COMMAND "$<TARGET_FILE:hello>" > "${hello_output}"
+  DEPENDS hello
+  VERBATIM
+  )
+
+if(NOT DEFINED HELLO_OUTPUT_STRING)
+  set(HELLO_OUTPUT_STRING "Hello world!\n")
+endif()
+
+set(hello_output_ref "${CMAKE_CURRENT_BINARY_DIR}/hello.output.ref")
+file(WRITE "${hello_output_ref}" "${HELLO_OUTPUT_STRING}")
+
+add_custom_target(check_output ALL
+  COMMAND "${CMAKE_COMMAND}" -E compare_files
+          "${hello_output}" "${hello_output_ref}"
+  DEPENDS "${hello_output}" "${hello_output_ref}"
+  VERBATIM
+  )
diff --git a/Tests/RunCMake/Ninja/CustomCommandWorkingDirectory.cmake b/Tests/RunCMake/Ninja/CustomCommandWorkingDirectory.cmake
new file mode 100644
index 0000000..8e01c8c
--- /dev/null
+++ b/Tests/RunCMake/Ninja/CustomCommandWorkingDirectory.cmake
@@ -0,0 +1,13 @@
+cmake_minimum_required(VERSION 3.5)
+project(hello NONE)
+
+add_custom_command(
+  OUTPUT hello.copy.c
+  COMMAND "${CMAKE_COMMAND}" -E copy
+          "${CMAKE_CURRENT_SOURCE_DIR}/hello.c"
+          hello.copy.c
+  WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
+  )
+add_custom_target(copy ALL DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/hello.copy.c")
+
+include(CheckNoPrefixSubDir.cmake)
diff --git a/Tests/RunCMake/Ninja/Executable.cmake b/Tests/RunCMake/Ninja/Executable.cmake
new file mode 100644
index 0000000..4e17d68
--- /dev/null
+++ b/Tests/RunCMake/Ninja/Executable.cmake
@@ -0,0 +1,5 @@
+cmake_minimum_required(VERSION 3.5)
+project(hello C)
+add_executable(hello hello.c)
+include(CheckOutput.cmake)
+include(CheckNoPrefixSubDir.cmake)
diff --git a/Tests/RunCMake/Ninja/RunCMakeTest.cmake b/Tests/RunCMake/Ninja/RunCMakeTest.cmake
index 4e06888..8160c2d 100644
--- a/Tests/RunCMake/Ninja/RunCMakeTest.cmake
+++ b/Tests/RunCMake/Ninja/RunCMakeTest.cmake
@@ -32,3 +32,148 @@ function(run_SubDir)
   run_cmake_command(SubDir-build ${CMAKE_COMMAND} --build . --target ${SubDir_all})
 endfunction()
 run_SubDir()
+
+function(run_ninja dir)
+  execute_process(
+    COMMAND "${RunCMake_MAKE_PROGRAM}"
+    WORKING_DIRECTORY "${dir}"
+    OUTPUT_VARIABLE ninja_stdout
+    ERROR_VARIABLE ninja_stderr
+    RESULT_VARIABLE ninja_result
+    )
+  if(NOT ninja_result EQUAL 0)
+    message(STATUS "
+============ beginning of ninja's stdout ============
+${ninja_stdout}
+=============== end of ninja's stdout ===============
+")
+    message(STATUS "
+============ beginning of ninja's stderr ============
+${ninja_stderr}
+=============== end of ninja's stderr ===============
+")
+    message(FATAL_ERROR
+      "top ninja build failed exited with status ${ninja_result}")
+  endif()
+endfunction(run_ninja)
+
+function(sleep delay)
+  execute_process(
+    COMMAND ${CMAKE_COMMAND} -E sleep ${delay}
+    RESULT_VARIABLE result
+    )
+  if(NOT result EQUAL 0)
+    message(FATAL_ERROR "failed to sleep for ${delay} second.")
+  endif()
+endfunction(sleep)
+
+function(touch path)
+  execute_process(
+    COMMAND ${CMAKE_COMMAND} -E touch ${path}
+    RESULT_VARIABLE result
+    )
+  if(NOT result EQUAL 0)
+    message(FATAL_ERROR "failed to touch main ${path} file.")
+  endif()
+endfunction(touch)
+
+macro(ninja_escape_path path out)
+  string(REPLACE "\$ " "\$\$" "${out}" "${path}")
+  string(REPLACE " " "\$ " "${out}" "${${out}}")
+  string(REPLACE ":" "\$:" "${out}" "${${out}}")
+endmacro(ninja_escape_path)
+
+macro(shell_escape string out)
+  string(REPLACE "\"" "\\\"" "${out}" "${string}")
+endmacro(shell_escape)
+
+function(run_sub_cmake test ninja_output_path_prefix)
+  set(top_build_dir "${RunCMake_BINARY_DIR}/${test}-build/")
+  file(REMOVE_RECURSE "${top_build_dir}")
+  file(MAKE_DIRECTORY "${top_build_dir}")
+
+  ninja_escape_path("${ninja_output_path_prefix}"
+    escaped_ninja_output_path_prefix)
+
+  # Generate top build ninja file.
+  set(top_build_ninja "${top_build_dir}/build.ninja")
+  shell_escape("${top_build_ninja}" escaped_top_build_ninja)
+  set(build_ninja_dep "${top_build_dir}/build_ninja_dep")
+  ninja_escape_path("${build_ninja_dep}" escaped_build_ninja_dep)
+  shell_escape("${CMAKE_COMMAND}" escaped_CMAKE_COMMAND)
+  file(WRITE "${build_ninja_dep}" "fake dependency of top build.ninja file\n")
+  if(WIN32)
+    set(cmd_prefix "cmd.exe /C \"")
+    set(cmd_suffix "\"")
+  else()
+    set(cmd_prefix "")
+    set(cmd_suffix "")
+  endif()
+  file(WRITE "${top_build_ninja}" "\
+subninja ${escaped_ninja_output_path_prefix}/build.ninja
+default ${escaped_ninja_output_path_prefix}/all
+
+# Sleep for 1 second before to regenerate to make sure the timestamp of
+# the top build.ninja will be strictly greater than the timestamp of the
+# sub/build.ninja file. We assume the system as 1 sec timestamp resolution.
+rule RERUN
+  command = ${cmd_prefix}\"${escaped_CMAKE_COMMAND}\" -E sleep 1 && \"${escaped_CMAKE_COMMAND}\" -E touch \"${escaped_top_build_ninja}\"${cmd_suffix}
+  description = Testing regeneration
+  generator = 1
+
+build build.ninja: RERUN ${escaped_build_ninja_dep} || ${escaped_ninja_output_path_prefix}/build.ninja
+  pool = console
+")
+
+  # Run sub cmake project.
+  set(RunCMake_TEST_OPTIONS "-DCMAKE_NINJA_OUTPUT_PATH_PREFIX=${ninja_output_path_prefix}")
+  set(RunCMake_TEST_BINARY_DIR "${top_build_dir}/${ninja_output_path_prefix}")
+  run_cmake(${test})
+
+  # Check there is no 'default' statement in Ninja file generated by CMake.
+  set(sub_build_ninja "${RunCMake_TEST_BINARY_DIR}/build.ninja")
+  file(READ "${sub_build_ninja}" sub_build_ninja_file)
+  if(sub_build_ninja_file MATCHES "\ndefault [^\n][^\n]*all\n")
+    message(FATAL_ERROR
+      "unexpected 'default' statement found in '${sub_build_ninja}'")
+  endif()
+
+  # Run ninja from the top build directory.
+  run_ninja("${top_build_dir}")
+
+  # Test regeneration rules run in order.
+  set(main_cmakelists "${RunCMake_SOURCE_DIR}/CMakeLists.txt")
+  sleep(1) # Assume the system as 1 sec timestamp resolution.
+  touch("${main_cmakelists}")
+  touch("${build_ninja_dep}")
+  run_ninja("${top_build_dir}")
+  file(TIMESTAMP "${main_cmakelists}" mtime_main_cmakelists UTC)
+  file(TIMESTAMP "${sub_build_ninja}" mtime_sub_build_ninja UTC)
+  file(TIMESTAMP "${top_build_ninja}" mtime_top_build_ninja UTC)
+
+  # Check sub build.ninja is regenerated.
+  if(mtime_main_cmakelists STRGREATER mtime_sub_build_ninja)
+    message(FATAL_ERROR
+      "sub build.ninja not regenerated:
+  CMakeLists.txt  = ${mtime_main_cmakelists}
+  sub/build.ninja = ${mtime_sub_build_ninja}")
+  endif()
+
+  # Check top build.ninja is regenerated after sub build.ninja.
+  if(NOT mtime_top_build_ninja STRGREATER mtime_sub_build_ninja)
+    message(FATAL_ERROR
+      "top build.ninja not regenerated strictly after sub build.ninja:
+  sub/build.ninja = ${mtime_sub_build_ninja}
+  build.ninja     = ${mtime_top_build_ninja}")
+  endif()
+
+endfunction(run_sub_cmake)
+
+foreach(ninja_output_path_prefix "sub space" "sub")
+  run_sub_cmake(Executable "${ninja_output_path_prefix}")
+  run_sub_cmake(StaticLib  "${ninja_output_path_prefix}")
+  run_sub_cmake(SharedLib "${ninja_output_path_prefix}")
+  run_sub_cmake(TwoLibs "${ninja_output_path_prefix}")
+  run_sub_cmake(SubDirPrefix "${ninja_output_path_prefix}")
+  run_sub_cmake(CustomCommandWorkingDirectory "${ninja_output_path_prefix}")
+endforeach(ninja_output_path_prefix)
diff --git a/Tests/RunCMake/Ninja/SharedLib.cmake b/Tests/RunCMake/Ninja/SharedLib.cmake
new file mode 100644
index 0000000..1a78390
--- /dev/null
+++ b/Tests/RunCMake/Ninja/SharedLib.cmake
@@ -0,0 +1,8 @@
+cmake_minimum_required(VERSION 3.5)
+project(hello C)
+add_library(greeting SHARED greeting.c)
+include_directories(${CMAKE_CURRENT_SOURCE_DIR})
+add_executable(hello hello_with_greeting.c)
+target_link_libraries(hello greeting)
+include(CheckOutput.cmake)
+include(CheckNoPrefixSubDir.cmake)
diff --git a/Tests/RunCMake/Ninja/StaticLib.cmake b/Tests/RunCMake/Ninja/StaticLib.cmake
new file mode 100644
index 0000000..0f815ae
--- /dev/null
+++ b/Tests/RunCMake/Ninja/StaticLib.cmake
@@ -0,0 +1,9 @@
+cmake_minimum_required(VERSION 3.5)
+project(hello C)
+add_definitions(-DGREETING_STATIC)
+add_library(greeting STATIC greeting.c)
+include_directories(${CMAKE_CURRENT_SOURCE_DIR})
+add_executable(hello hello_with_greeting.c)
+target_link_libraries(hello greeting)
+include(CheckOutput.cmake)
+include(CheckNoPrefixSubDir.cmake)
diff --git a/Tests/RunCMake/Ninja/SubDirPrefix.cmake b/Tests/RunCMake/Ninja/SubDirPrefix.cmake
new file mode 100644
index 0000000..30ad1e6
--- /dev/null
+++ b/Tests/RunCMake/Ninja/SubDirPrefix.cmake
@@ -0,0 +1,8 @@
+cmake_minimum_required(VERSION 3.5)
+project(hello C)
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin")
+add_subdirectory(SubDirPrefix)
+include_directories(${CMAKE_CURRENT_SOURCE_DIR})
+add_executable(hello hello_sub_greeting.c)
+target_link_libraries(hello greeting)
+include(CheckOutput.cmake)
diff --git a/Tests/RunCMake/Ninja/SubDirPrefix/CMakeLists.txt b/Tests/RunCMake/Ninja/SubDirPrefix/CMakeLists.txt
new file mode 100644
index 0000000..575597d
--- /dev/null
+++ b/Tests/RunCMake/Ninja/SubDirPrefix/CMakeLists.txt
@@ -0,0 +1,2 @@
+add_library(greeting SHARED greeting.c)
+include_directories(${CMAKE_CURRENT_SOURCE_DIR})
diff --git a/Tests/RunCMake/Ninja/SubDirPrefix/greeting.c b/Tests/RunCMake/Ninja/SubDirPrefix/greeting.c
new file mode 100644
index 0000000..ba3e55b
--- /dev/null
+++ b/Tests/RunCMake/Ninja/SubDirPrefix/greeting.c
@@ -0,0 +1,9 @@
+#include <stdio.h>
+
+#if defined(_WIN32) && !defined(GREETING_STATIC)
+__declspec(dllexport)
+#endif
+  void greeting(void)
+{
+  printf("Hello world!\n");
+}
diff --git a/Tests/RunCMake/Ninja/SubDirPrefix/greeting.h b/Tests/RunCMake/Ninja/SubDirPrefix/greeting.h
new file mode 100644
index 0000000..ee4053e
--- /dev/null
+++ b/Tests/RunCMake/Ninja/SubDirPrefix/greeting.h
@@ -0,0 +1,4 @@
+#if defined(_WIN32) && !defined(GREETING_STATIC)
+__declspec(dllimport)
+#endif
+  void greeting(void);
diff --git a/Tests/RunCMake/Ninja/TwoLibs.cmake b/Tests/RunCMake/Ninja/TwoLibs.cmake
new file mode 100644
index 0000000..666452f
--- /dev/null
+++ b/Tests/RunCMake/Ninja/TwoLibs.cmake
@@ -0,0 +1,17 @@
+cmake_minimum_required(VERSION 3.5)
+project(hello C)
+
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
+set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib-static")
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib")
+
+add_library(greeting SHARED greeting.c)
+add_library(greeting2 STATIC greeting2.c)
+include_directories(${CMAKE_CURRENT_SOURCE_DIR})
+add_executable(hello hello_with_two_greetings.c)
+target_link_libraries(hello greeting greeting2)
+
+set(HELLO_OUTPUT_STRING "Hello world!\nHello world 2!\n")
+include(CheckOutput.cmake)
+
+include(CheckNoPrefixSubDir.cmake)
diff --git a/Tests/RunCMake/Ninja/greeting.c b/Tests/RunCMake/Ninja/greeting.c
new file mode 100644
index 0000000..ba3e55b
--- /dev/null
+++ b/Tests/RunCMake/Ninja/greeting.c
@@ -0,0 +1,9 @@
+#include <stdio.h>
+
+#if defined(_WIN32) && !defined(GREETING_STATIC)
+__declspec(dllexport)
+#endif
+  void greeting(void)
+{
+  printf("Hello world!\n");
+}
diff --git a/Tests/RunCMake/Ninja/greeting.h b/Tests/RunCMake/Ninja/greeting.h
new file mode 100644
index 0000000..ee4053e
--- /dev/null
+++ b/Tests/RunCMake/Ninja/greeting.h
@@ -0,0 +1,4 @@
+#if defined(_WIN32) && !defined(GREETING_STATIC)
+__declspec(dllimport)
+#endif
+  void greeting(void);
diff --git a/Tests/RunCMake/Ninja/greeting2.c b/Tests/RunCMake/Ninja/greeting2.c
new file mode 100644
index 0000000..c6ed87d
--- /dev/null
+++ b/Tests/RunCMake/Ninja/greeting2.c
@@ -0,0 +1,6 @@
+#include <stdio.h>
+
+void greeting2(void)
+{
+  printf("Hello world 2!\n");
+}
diff --git a/Tests/RunCMake/Ninja/greeting2.h b/Tests/RunCMake/Ninja/greeting2.h
new file mode 100644
index 0000000..c4d8f9b
--- /dev/null
+++ b/Tests/RunCMake/Ninja/greeting2.h
@@ -0,0 +1 @@
+void greeting2(void);
diff --git a/Tests/RunCMake/Ninja/hello.c b/Tests/RunCMake/Ninja/hello.c
new file mode 100644
index 0000000..aac8b4e
--- /dev/null
+++ b/Tests/RunCMake/Ninja/hello.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+int main(void)
+{
+  printf("Hello world!\n");
+  return 0;
+}
diff --git a/Tests/RunCMake/Ninja/hello_sub_greeting.c b/Tests/RunCMake/Ninja/hello_sub_greeting.c
new file mode 100644
index 0000000..fc4bd60
--- /dev/null
+++ b/Tests/RunCMake/Ninja/hello_sub_greeting.c
@@ -0,0 +1,7 @@
+#include <SubDirPrefix/greeting.h>
+
+int main(void)
+{
+  greeting();
+  return 0;
+}
diff --git a/Tests/RunCMake/Ninja/hello_with_greeting.c b/Tests/RunCMake/Ninja/hello_with_greeting.c
new file mode 100644
index 0000000..dbf90e3
--- /dev/null
+++ b/Tests/RunCMake/Ninja/hello_with_greeting.c
@@ -0,0 +1,7 @@
+#include <greeting.h>
+
+int main(void)
+{
+  greeting();
+  return 0;
+}
diff --git a/Tests/RunCMake/Ninja/hello_with_two_greetings.c b/Tests/RunCMake/Ninja/hello_with_two_greetings.c
new file mode 100644
index 0000000..cbbdaad
--- /dev/null
+++ b/Tests/RunCMake/Ninja/hello_with_two_greetings.c
@@ -0,0 +1,9 @@
+#include <greeting.h>
+#include <greeting2.h>
+
+int main(void)
+{
+  greeting();
+  greeting2();
+  return 0;
+}

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=038e7716e58e4cf79bda6ba72b92814a14978a8f
commit 038e7716e58e4cf79bda6ba72b92814a14978a8f
Author:     Nicolas Despres <nicolas.despres at gmail.com>
AuthorDate: Sat May 14 01:18:20 2016 +0200
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Tue May 17 09:34:11 2016 -0400

    Ninja: Pass all build paths through a central method
    
    This gives us a central location to revise paths.

diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx
index df5a001..3c5a8e3 100644
--- a/Source/cmGlobalNinjaGenerator.cxx
+++ b/Source/cmGlobalNinjaGenerator.cxx
@@ -488,8 +488,8 @@ void cmGlobalNinjaGenerator::Generate()
   this->OpenBuildFileStream();
   this->OpenRulesFileStream();
 
-  this->TargetAll = "all";
-  this->CMakeCacheFile = "CMakeCache.txt";
+  this->TargetAll = this->NinjaOutputPath("all");
+  this->CMakeCacheFile = this->NinjaOutputPath("CMakeCache.txt");
 
   this->PolicyCMP0058 =
     this->LocalGenerators[0]->GetMakefile()->GetPolicyStatus(
@@ -722,6 +722,7 @@ std::string cmGlobalNinjaGenerator::ConvertToNinjaPath(const std::string& path)
   cmLocalNinjaGenerator* ng =
     static_cast<cmLocalNinjaGenerator*>(this->LocalGenerators[0]);
   std::string convPath = ng->Convert(path, cmOutputConverter::HOME_OUTPUT);
+  convPath = this->NinjaOutputPath(convPath);
 #ifdef _WIN32
   cmSystemTools::ReplaceString(convPath, "/", "\\");
 #endif
@@ -734,6 +735,7 @@ std::string cmGlobalNinjaGenerator::ConvertToNinjaFolderRule(
   cmLocalNinjaGenerator* ng =
     static_cast<cmLocalNinjaGenerator*>(this->LocalGenerators[0]);
   std::string convPath = ng->Convert(path + "/all", cmOutputConverter::HOME);
+  convPath = this->NinjaOutputPath(convPath);
 #ifdef _WIN32
   cmSystemTools::ReplaceString(convPath, "/", "\\");
 #endif
@@ -849,7 +851,7 @@ void cmGlobalNinjaGenerator::AppendTargetOutputs(
     case cmState::GLOBAL_TARGET:
       // Always use the target in HOME instead of an unused duplicate in a
       // subdirectory.
-      outputs.push_back(target->GetName());
+      outputs.push_back(this->NinjaOutputPath(target->GetName()));
       break;
 
     default:
@@ -883,6 +885,7 @@ void cmGlobalNinjaGenerator::AppendTargetDepends(
 void cmGlobalNinjaGenerator::AddTargetAlias(const std::string& alias,
                                             cmGeneratorTarget* target)
 {
+  std::string buildAlias = this->NinjaOutputPath(alias);
   cmNinjaDeps outputs;
   this->AppendTargetOutputs(target, outputs);
   // Mark the target's outputs as ambiguous to ensure that no other target uses
@@ -893,7 +896,7 @@ void cmGlobalNinjaGenerator::AddTargetAlias(const std::string& alias,
   // Insert the alias into the map.  If the alias was already present in the
   // map and referred to another target, mark it as ambiguous.
   std::pair<TargetAliasMap::iterator, bool> newAlias =
-    TargetAliases.insert(std::make_pair(alias, target));
+    TargetAliases.insert(std::make_pair(buildAlias, target));
   if (newAlias.second && newAlias.first->second != target)
     newAlias.first->second = 0;
 }
@@ -1182,9 +1185,10 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os)
     variables["pool"] = "console";
   }
 
+  std::string const ninjaBuildFile = this->NinjaOutputPath(NINJA_BUILD_FILE);
   this->WriteBuild(os, "Re-run CMake if any of its inputs changed.",
                    "RERUN_CMAKE",
-                   /*outputs=*/cmNinjaDeps(1, NINJA_BUILD_FILE),
+                   /*outputs=*/cmNinjaDeps(1, ninjaBuildFile),
                    /*explicitDeps=*/cmNinjaDeps(), implicitDeps,
                    /*orderOnlyDeps=*/cmNinjaDeps(), variables);
 
@@ -1221,7 +1225,7 @@ void cmGlobalNinjaGenerator::WriteTargetClean(std::ostream& os)
             /*restat=*/"",
             /*generator=*/false);
   WriteBuild(os, "Clean all the built files.", "CLEAN",
-             /*outputs=*/cmNinjaDeps(1, "clean"),
+             /*outputs=*/cmNinjaDeps(1, this->NinjaOutputPath("clean")),
              /*explicitDeps=*/cmNinjaDeps(),
              /*implicitDeps=*/cmNinjaDeps(),
              /*orderOnlyDeps=*/cmNinjaDeps(),
@@ -1240,9 +1244,14 @@ void cmGlobalNinjaGenerator::WriteTargetHelp(std::ostream& os)
             /*restat=*/"",
             /*generator=*/false);
   WriteBuild(os, "Print all primary targets available.", "HELP",
-             /*outputs=*/cmNinjaDeps(1, "help"),
+             /*outputs=*/cmNinjaDeps(1, this->NinjaOutputPath("help")),
              /*explicitDeps=*/cmNinjaDeps(),
              /*implicitDeps=*/cmNinjaDeps(),
              /*orderOnlyDeps=*/cmNinjaDeps(),
              /*variables=*/cmNinjaVars());
 }
+
+std::string cmGlobalNinjaGenerator::NinjaOutputPath(std::string const& path)
+{
+  return path;
+}
diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h
index 28034f6..15c0f34 100644
--- a/Source/cmGlobalNinjaGenerator.h
+++ b/Source/cmGlobalNinjaGenerator.h
@@ -314,6 +314,8 @@ public:
   static std::string RequiredNinjaVersionForConsolePool() { return "1.5"; }
   bool SupportsConsolePool() const;
 
+  std::string NinjaOutputPath(std::string const& path);
+
 protected:
   virtual void Generate();
 
diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx
index 69f8fe5..c7e1a90f8 100644
--- a/Source/cmLocalNinjaGenerator.cxx
+++ b/Source/cmLocalNinjaGenerator.cxx
@@ -225,8 +225,13 @@ void cmLocalNinjaGenerator::WriteNinjaFilesInclusion(std::ostream& os)
   cmGlobalNinjaGenerator::WriteDivider(os);
   os << "# Include auxiliary files.\n"
      << "\n";
-  cmGlobalNinjaGenerator::WriteInclude(
-    os, cmGlobalNinjaGenerator::NINJA_RULES_FILE, "Include rules file.");
+  cmGlobalNinjaGenerator* ng = this->GetGlobalNinjaGenerator();
+  std::string const ninjaRulesFile =
+    ng->NinjaOutputPath(cmGlobalNinjaGenerator::NINJA_RULES_FILE);
+  std::string const rulesFilePath =
+    ng->EncodeIdent(ng->EncodePath(ninjaRulesFile), os);
+  cmGlobalNinjaGenerator::WriteInclude(os, rulesFilePath,
+                                       "Include rules file.");
   os << "\n";
 }
 
diff --git a/Source/cmNinjaUtilityTargetGenerator.cxx b/Source/cmNinjaUtilityTargetGenerator.cxx
index b0b1147..d07341c 100644
--- a/Source/cmNinjaUtilityTargetGenerator.cxx
+++ b/Source/cmNinjaUtilityTargetGenerator.cxx
@@ -33,6 +33,8 @@ void cmNinjaUtilityTargetGenerator::Generate()
 {
   std::string utilCommandName = cmake::GetCMakeFilesDirectoryPostSlash();
   utilCommandName += this->GetTargetName() + ".util";
+  utilCommandName =
+    this->GetGlobalGenerator()->NinjaOutputPath(utilCommandName);
 
   std::vector<std::string> commands;
   cmNinjaDeps deps, outputs, util_outputs(1, utilCommandName);

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=7c26a6a269b0c12ecdf7605183d9fa26ad2b91eb
commit 7c26a6a269b0c12ecdf7605183d9fa26ad2b91eb
Author:     Nicolas Despres <nicolas.despres at gmail.com>
AuthorDate: Sat May 14 01:18:20 2016 +0200
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Tue May 17 09:34:10 2016 -0400

    Ninja: Fix path to soname-d target file
    
    In WriteLinkStatement we convert all target output paths to ninja-style
    paths.  Add a missing conversion for the `soname` file name.

diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx
index 831d44b..8d7a892 100644
--- a/Source/cmNinjaNormalTargetGenerator.cxx
+++ b/Source/cmNinjaNormalTargetGenerator.cxx
@@ -652,7 +652,8 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
         cmNinjaDeps(1, targetOutputReal), emptyDeps, emptyDeps, symlinkVars);
     } else {
       cmNinjaDeps symlinks;
-      const std::string soName = this->GetTargetFilePath(this->TargetNameSO);
+      std::string const soName =
+        this->ConvertToNinjaPath(this->GetTargetFilePath(this->TargetNameSO));
       // If one link has to be created.
       if (targetOutputReal == soName || targetOutput == soName) {
         symlinkVars["SONAME"] = soName;

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=ac3cdd9af287e653d53b18c432f21a919b102158
commit ac3cdd9af287e653d53b18c432f21a919b102158
Author:     Nicolas Despres <nicolas.despres at gmail.com>
AuthorDate: Sat May 14 01:18:20 2016 +0200
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Tue May 17 09:34:09 2016 -0400

    Ninja: Convert object file names to ninja paths earlier
    
    In WriteObjectBuildStatement we pass object file names and directories
    to several places that expect paths as Ninja sees them.  Convert them to
    Ninja paths before all such uses.

diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index c214c8a..994daea 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -521,8 +521,10 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
   std::string const language = source->GetLanguage();
   std::string const sourceFileName =
     language == "RC" ? source->GetFullPath() : this->GetSourceFilePath(source);
-  std::string const objectDir = this->GeneratorTarget->GetSupportDirectory();
-  std::string const objectFileName = this->GetObjectFilePath(source);
+  std::string const objectDir =
+    this->ConvertToNinjaPath(this->GeneratorTarget->GetSupportDirectory());
+  std::string const objectFileName =
+    this->ConvertToNinjaPath(this->GetObjectFilePath(source));
   std::string const objectFileDir =
     cmSystemTools::GetFilenamePath(objectFileName);
 
@@ -582,9 +584,9 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
   EnsureParentDirectoryExists(objectFileName);
 
   vars["OBJECT_DIR"] = this->GetLocalGenerator()->ConvertToOutputFormat(
-    ConvertToNinjaPath(objectDir), cmLocalGenerator::SHELL);
+    objectDir, cmLocalGenerator::SHELL);
   vars["OBJECT_FILE_DIR"] = this->GetLocalGenerator()->ConvertToOutputFormat(
-    ConvertToNinjaPath(objectFileDir), cmLocalGenerator::SHELL);
+    objectFileDir, cmLocalGenerator::SHELL);
 
   this->addPoolNinjaVariable("JOB_POOL_COMPILE", this->GetGeneratorTarget(),
                              vars);

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=d4381cb15df3e81b78b6d8d9e7d9b727a616985d
commit d4381cb15df3e81b78b6d8d9e7d9b727a616985d
Author:     Nicolas Despres <nicolas.despres at gmail.com>
AuthorDate: Sat May 14 01:18:20 2016 +0200
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Tue May 17 09:34:09 2016 -0400

    Ninja: Convert link library file names like all other output paths
    
    All paths generated on Ninja-invoked command lines should be passed
    through ConvertToNinjaPath.  Fix ConvertToLinkReference to call this
    instead of partially duplicating its implementation.

diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx
index 671d8a0..69f8fe5 100644
--- a/Source/cmLocalNinjaGenerator.cxx
+++ b/Source/cmLocalNinjaGenerator.cxx
@@ -123,7 +123,8 @@ cmGlobalNinjaGenerator* cmLocalNinjaGenerator::GetGlobalNinjaGenerator()
 std::string cmLocalNinjaGenerator::ConvertToLinkReference(
   std::string const& lib, OutputFormat format)
 {
-  return this->Convert(lib, HOME_OUTPUT, format);
+  std::string path = this->GetGlobalNinjaGenerator()->ConvertToNinjaPath(lib);
+  return this->ConvertToOutputFormat(path, format);
 }
 
 std::string cmLocalNinjaGenerator::ConvertToIncludeReference(

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=0397c92a15e505021d75eb0a156a312b024eb85e
commit 0397c92a15e505021d75eb0a156a312b024eb85e
Author:     Nicolas Despres <nicolas.despres at gmail.com>
AuthorDate: Fri May 13 23:44:25 2016 +0200
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Tue May 17 09:34:08 2016 -0400

    Ninja: Pre-compute "CMakeCache.txt" build target name

diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx
index 864cd2b..df5a001 100644
--- a/Source/cmGlobalNinjaGenerator.cxx
+++ b/Source/cmGlobalNinjaGenerator.cxx
@@ -489,6 +489,7 @@ void cmGlobalNinjaGenerator::Generate()
   this->OpenRulesFileStream();
 
   this->TargetAll = "all";
+  this->CMakeCacheFile = "CMakeCache.txt";
 
   this->PolicyCMP0058 =
     this->LocalGenerators[0]->GetMakefile()->GetPolicyStatus(
@@ -1040,7 +1041,7 @@ void cmGlobalNinjaGenerator::WriteUnknownExplicitDependencies(std::ostream& os)
       }
     }
   }
-  knownDependencies.insert("CMakeCache.txt");
+  knownDependencies.insert(this->CMakeCacheFile);
 
   for (TargetAliasMap::const_iterator i = this->TargetAliases.begin();
        i != this->TargetAliases.end(); ++i) {
@@ -1168,7 +1169,7 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os)
       implicitDeps.push_back(this->ConvertToNinjaPath(*fi));
     }
   }
-  implicitDeps.push_back("CMakeCache.txt");
+  implicitDeps.push_back(this->CMakeCacheFile);
 
   std::sort(implicitDeps.begin(), implicitDeps.end());
   implicitDeps.erase(std::unique(implicitDeps.begin(), implicitDeps.end()),
diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h
index 151950b..28034f6 100644
--- a/Source/cmGlobalNinjaGenerator.h
+++ b/Source/cmGlobalNinjaGenerator.h
@@ -400,6 +400,7 @@ private:
 
 private:
   std::string TargetAll;
+  std::string CMakeCacheFile;
 };
 
 #endif // ! cmGlobalNinjaGenerator_h

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=3b3ecdfa4872a86dcb8eb7d5f5478259890d4707
commit 3b3ecdfa4872a86dcb8eb7d5f5478259890d4707
Author:     Nicolas Despres <nicolas.despres at gmail.com>
AuthorDate: Fri May 13 23:42:02 2016 +0200
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Tue May 17 09:34:07 2016 -0400

    Ninja: Pre-compute "all" build target name

diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx
index a8e02e1..864cd2b 100644
--- a/Source/cmGlobalNinjaGenerator.cxx
+++ b/Source/cmGlobalNinjaGenerator.cxx
@@ -488,6 +488,8 @@ void cmGlobalNinjaGenerator::Generate()
   this->OpenBuildFileStream();
   this->OpenRulesFileStream();
 
+  this->TargetAll = "all";
+
   this->PolicyCMP0058 =
     this->LocalGenerators[0]->GetMakefile()->GetPolicyStatus(
       cmPolicies::CMP0058);
@@ -1059,7 +1061,7 @@ void cmGlobalNinjaGenerator::WriteUnknownExplicitDependencies(std::ostream& os)
   // should all match now.
 
   std::vector<std::string> unknownExplicitDepends;
-  this->CombinedCustomCommandExplicitDependencies.erase("all");
+  this->CombinedCustomCommandExplicitDependencies.erase(this->TargetAll);
 
   std::set_difference(this->CombinedCustomCommandExplicitDependencies.begin(),
                       this->CombinedCustomCommandExplicitDependencies.end(),
@@ -1125,7 +1127,7 @@ void cmGlobalNinjaGenerator::WriteBuiltinTargets(std::ostream& os)
 void cmGlobalNinjaGenerator::WriteTargetAll(std::ostream& os)
 {
   cmNinjaDeps outputs;
-  outputs.push_back("all");
+  outputs.push_back(this->TargetAll);
 
   this->WritePhonyBuild(os, "The main all target.", outputs,
                         this->AllDependencies);
diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h
index 881104f..151950b 100644
--- a/Source/cmGlobalNinjaGenerator.h
+++ b/Source/cmGlobalNinjaGenerator.h
@@ -397,6 +397,9 @@ private:
 
   std::string NinjaCommand;
   std::string NinjaVersion;
+
+private:
+  std::string TargetAll;
 };
 
 #endif // ! cmGlobalNinjaGenerator_h

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=5ca72750c8de3c1c925c433293eb3bc6b3ea234c
commit 5ca72750c8de3c1c925c433293eb3bc6b3ea234c
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Mon May 16 15:30:53 2016 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Tue May 17 09:34:06 2016 -0400

    Ninja: Simplify generation of custom target logical path
    
    In `AppendTargetOutputs` we generate a logical build target name for
    each UTILITY command.  Simplify the logic to avoid testing the result
    of `ConvertToNinjaPath`.

diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx
index 012ef90..a8e02e1 100644
--- a/Source/cmGlobalNinjaGenerator.cxx
+++ b/Source/cmGlobalNinjaGenerator.cxx
@@ -836,15 +836,10 @@ void cmGlobalNinjaGenerator::AppendTargetOutputs(
     }
     case cmState::OBJECT_LIBRARY:
     case cmState::UTILITY: {
-      std::string path = this->ConvertToNinjaPath(
-        target->GetLocalGenerator()->GetCurrentBinaryDirectory());
-      if (path.empty() || path == ".")
-        outputs.push_back(target->GetName());
-      else {
-        path += "/";
-        path += target->GetName();
-        outputs.push_back(path);
-      }
+      std::string path =
+        target->GetLocalGenerator()->GetCurrentBinaryDirectory() +
+        std::string("/") + target->GetName();
+      outputs.push_back(this->ConvertToNinjaPath(path));
       break;
     }
 

-----------------------------------------------------------------------

Summary of changes:
 Help/manual/cmake-variables.7.rst                  |    1 +
 Help/release/dev/ninja-output-path-prefix.rst      |    6 +
 Help/variable/CMAKE_NINJA_OUTPUT_PATH_PREFIX.rst   |   27 ++++
 Source/cmAlgorithms.h                              |   15 ++
 Source/cmGlobalNinjaGenerator.cxx                  |   88 +++++++++---
 Source/cmGlobalNinjaGenerator.h                    |   11 ++
 Source/cmLocalNinjaGenerator.cxx                   |   12 +-
 Source/cmNinjaNormalTargetGenerator.cxx            |    3 +-
 Source/cmNinjaTargetGenerator.cxx                  |   20 +--
 Source/cmNinjaUtilityTargetGenerator.cxx           |    2 +
 Tests/RunCMake/Ninja/CheckNoPrefixSubDir.cmake     |    7 +
 .../RunCMake/Ninja/CheckNoPrefixSubDirScript.cmake |    8 ++
 Tests/RunCMake/Ninja/CheckOutput.cmake             |   23 ++++
 .../Ninja/CustomCommandWorkingDirectory.cmake      |   13 ++
 Tests/RunCMake/Ninja/Executable.cmake              |    5 +
 Tests/RunCMake/Ninja/RunCMakeTest.cmake            |  145 ++++++++++++++++++++
 Tests/RunCMake/Ninja/SharedLib.cmake               |    8 ++
 Tests/RunCMake/Ninja/StaticLib.cmake               |    9 ++
 Tests/RunCMake/Ninja/SubDirPrefix.cmake            |    8 ++
 Tests/RunCMake/Ninja/SubDirPrefix/CMakeLists.txt   |    2 +
 Tests/RunCMake/Ninja/SubDirPrefix/greeting.c       |    9 ++
 Tests/RunCMake/Ninja/SubDirPrefix/greeting.h       |    4 +
 Tests/RunCMake/Ninja/TwoLibs.cmake                 |   17 +++
 Tests/RunCMake/Ninja/greeting.c                    |    9 ++
 Tests/RunCMake/Ninja/greeting.h                    |    4 +
 Tests/RunCMake/Ninja/greeting2.c                   |    6 +
 Tests/RunCMake/Ninja/greeting2.h                   |    1 +
 Tests/RunCMake/Ninja/hello.c                       |    7 +
 Tests/RunCMake/Ninja/hello_sub_greeting.c          |    7 +
 Tests/RunCMake/Ninja/hello_with_greeting.c         |    7 +
 Tests/RunCMake/Ninja/hello_with_two_greetings.c    |    9 ++
 31 files changed, 461 insertions(+), 32 deletions(-)
 create mode 100644 Help/release/dev/ninja-output-path-prefix.rst
 create mode 100644 Help/variable/CMAKE_NINJA_OUTPUT_PATH_PREFIX.rst
 create mode 100644 Tests/RunCMake/Ninja/CheckNoPrefixSubDir.cmake
 create mode 100644 Tests/RunCMake/Ninja/CheckNoPrefixSubDirScript.cmake
 create mode 100644 Tests/RunCMake/Ninja/CheckOutput.cmake
 create mode 100644 Tests/RunCMake/Ninja/CustomCommandWorkingDirectory.cmake
 create mode 100644 Tests/RunCMake/Ninja/Executable.cmake
 create mode 100644 Tests/RunCMake/Ninja/SharedLib.cmake
 create mode 100644 Tests/RunCMake/Ninja/StaticLib.cmake
 create mode 100644 Tests/RunCMake/Ninja/SubDirPrefix.cmake
 create mode 100644 Tests/RunCMake/Ninja/SubDirPrefix/CMakeLists.txt
 create mode 100644 Tests/RunCMake/Ninja/SubDirPrefix/greeting.c
 create mode 100644 Tests/RunCMake/Ninja/SubDirPrefix/greeting.h
 create mode 100644 Tests/RunCMake/Ninja/TwoLibs.cmake
 create mode 100644 Tests/RunCMake/Ninja/greeting.c
 create mode 100644 Tests/RunCMake/Ninja/greeting.h
 create mode 100644 Tests/RunCMake/Ninja/greeting2.c
 create mode 100644 Tests/RunCMake/Ninja/greeting2.h
 create mode 100644 Tests/RunCMake/Ninja/hello.c
 create mode 100644 Tests/RunCMake/Ninja/hello_sub_greeting.c
 create mode 100644 Tests/RunCMake/Ninja/hello_with_greeting.c
 create mode 100644 Tests/RunCMake/Ninja/hello_with_two_greetings.c


hooks/post-receive
-- 
CMake


More information about the Cmake-commits mailing list