Merge pull request #2316 from gerioldman/TaskingRSP
AddTasking RSP syntax to printCompdb functionality
diff --git a/CMakeLists.txt b/CMakeLists.txt
index ac62a49..d0c62f9 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -246,7 +246,8 @@
src/util_test.cc
)
if(WIN32)
- target_sources(ninja_test PRIVATE src/includes_normalize_test.cc src/msvc_helper_test.cc)
+ target_sources(ninja_test PRIVATE src/includes_normalize_test.cc src/msvc_helper_test.cc
+ windows/ninja.manifest)
endif()
target_link_libraries(ninja_test PRIVATE libninja libninja-re2c)
diff --git a/src/disk_interface.cc b/src/disk_interface.cc
index 1157463..ed064e1 100644
--- a/src/disk_interface.cc
+++ b/src/disk_interface.cc
@@ -26,6 +26,7 @@
#include <sstream>
#include <windows.h>
#include <direct.h> // _mkdir
+#include <atlcore.h>
#else
#include <unistd.h>
#endif
@@ -157,13 +158,27 @@
}
// RealDiskInterface -----------------------------------------------------------
+RealDiskInterface::RealDiskInterface()
+#ifdef _WIN32
+: use_cache_(false), long_paths_enabled_(false) {
+ setlocale(LC_ALL, "");
+ IFDYNAMICGETCACHEDFUNCTIONTYPEDEF(L"ntdll", BOOLEAN(WINAPI*)(),
+ "RtlAreLongPathsEnabled",
+ RtlAreLongPathsEnabled) {
+ long_paths_enabled_ = RtlAreLongPathsEnabled();
+ }
+}
+#else
+{}
+#endif
TimeStamp RealDiskInterface::Stat(const string& path, string* err) const {
METRIC_RECORD("node stat");
#ifdef _WIN32
// MSDN: "Naming Files, Paths, and Namespaces"
// http://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx
- if (!path.empty() && path[0] != '\\' && path.size() > MAX_PATH) {
+ if (!path.empty() && !AreLongPathsEnabled() && path[0] != '\\' &&
+ path.size() > MAX_PATH) {
ostringstream err_stream;
err_stream << "Stat(" << path << "): Filename longer than " << MAX_PATH
<< " characters";
@@ -333,3 +348,9 @@
cache_.clear();
#endif
}
+
+#ifdef _WIN32
+bool RealDiskInterface::AreLongPathsEnabled(void) const {
+ return long_paths_enabled_;
+}
+#endif
diff --git a/src/disk_interface.h b/src/disk_interface.h
index bc29ab7..74200b8 100644
--- a/src/disk_interface.h
+++ b/src/disk_interface.h
@@ -69,11 +69,7 @@
/// Implementation of DiskInterface that actually hits the disk.
struct RealDiskInterface : public DiskInterface {
- RealDiskInterface()
-#ifdef _WIN32
- : use_cache_(false)
-#endif
- {}
+ RealDiskInterface();
virtual ~RealDiskInterface() {}
virtual TimeStamp Stat(const std::string& path, std::string* err) const;
virtual bool MakeDir(const std::string& path);
@@ -85,11 +81,19 @@
/// Whether stat information can be cached. Only has an effect on Windows.
void AllowStatCache(bool allow);
+#ifdef _WIN32
+ /// Whether long paths are enabled. Only has an effect on Windows.
+ bool AreLongPathsEnabled() const;
+#endif
+
private:
#ifdef _WIN32
/// Whether stat information can be cached.
bool use_cache_;
+ /// Whether long paths are enabled.
+ bool long_paths_enabled_;
+
typedef std::map<std::string, TimeStamp> DirCache;
// TODO: Neither a map nor a hashmap seems ideal here. If the statcache
// works out, come up with a better data structure.
diff --git a/src/disk_interface_test.cc b/src/disk_interface_test.cc
index 294df72..e8d869c 100644
--- a/src/disk_interface_test.cc
+++ b/src/disk_interface_test.cc
@@ -17,6 +17,7 @@
#ifdef _WIN32
#include <io.h>
#include <windows.h>
+#include <direct.h>
#endif
#include "disk_interface.h"
@@ -96,6 +97,24 @@
EXPECT_EQ("", err);
}
+#ifdef _WIN32
+TEST_F(DiskInterfaceTest, StatExistingFileWithLongPath) {
+ string err;
+ char currentdir[32767];
+ _getcwd(currentdir, sizeof(currentdir));
+ const string filename = string(currentdir) +
+"\\filename_with_256_characters_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\
+xxxxxxxxxxxxxxxxxxxxx";
+ const string prefixed = "\\\\?\\" + filename;
+ ASSERT_TRUE(Touch(prefixed.c_str()));
+ EXPECT_GT(disk_.Stat(disk_.AreLongPathsEnabled() ?
+ filename : prefixed, &err), 1);
+ EXPECT_EQ("", err);
+}
+#endif
+
TEST_F(DiskInterfaceTest, StatExistingDir) {
string err;
ASSERT_TRUE(disk_.MakeDir("subdir"));