summaryrefslogtreecommitdiffstats
path: root/Source/cmSystemTools.cxx
diff options
context:
space:
mode:
authorChristian Pfeiffer <cpfeiffer@live.de>2017-04-18 21:06:39 (GMT)
committerBrad King <brad.king@kitware.com>2017-04-19 15:02:24 (GMT)
commitbbb5c3efe2a17d046506b7c27008c77ea244f0bc (patch)
treeefa83801c7982bd247727af35fa6e7f15a13aedc /Source/cmSystemTools.cxx
parentddd2b02455db9b0ef3604af1b9b10c22af56bff9 (diff)
downloadCMake-bbb5c3efe2a17d046506b7c27008c77ea244f0bc.zip
CMake-bbb5c3efe2a17d046506b7c27008c77ea244f0bc.tar.gz
CMake-bbb5c3efe2a17d046506b7c27008c77ea244f0bc.tar.bz2
Ninja,Makefile: Unify command line limit logic
Move the logic to cmSystemTools to be shared among the generators. Revise the implementation and add comments justifying each possible source for a limit.
Diffstat (limited to 'Source/cmSystemTools.cxx')
-rw-r--r--Source/cmSystemTools.cxx40
1 files changed, 40 insertions, 0 deletions
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index 8dc6571..f4de125 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -570,6 +570,46 @@ std::vector<std::string> cmSystemTools::ParseArguments(const char* command)
return args;
}
+size_t cmSystemTools::CalculateCommandLineLengthLimit()
+{
+ size_t sz =
+#ifdef _WIN32
+ // There's a maximum of 65536 bytes and thus 32768 WCHARs on Windows
+ // However, cmd.exe itself can only handle 8191 WCHARs and Ninja for
+ // example uses it to spawn processes.
+ size_t(8191);
+#elif defined(__linux)
+ // MAX_ARG_STRLEN is the maximum length of a string permissible for
+ // the execve() syscall on Linux. It's defined as (PAGE_SIZE * 32)
+ // in Linux's binfmts.h
+ static_cast<size_t>(sysconf(_SC_PAGESIZE) * 32);
+#else
+ size_t(0);
+#endif
+
+#if defined(_SC_ARG_MAX)
+ // ARG_MAX is the maximum size of the command and environment
+ // that can be passed to the exec functions on UNIX.
+ // The value in limits.h does not need to be present and may
+ // depend upon runtime memory constraints, hence sysconf()
+ // should be used to query it.
+ long szArgMax = sysconf(_SC_ARG_MAX);
+ // A return value of -1 signifies an undetermined limit, but
+ // it does not imply an infinite limit, and thus is ignored.
+ if (szArgMax != -1) {
+ // We estimate the size of the environment block to be 1000.
+ // This isn't accurate at all, but leaves some headroom.
+ szArgMax = szArgMax < 1000 ? 0 : szArgMax - 1000;
+#if defined(_WIN32) || defined(__linux)
+ sz = std::min(sz, static_cast<size_t>(szArgMax));
+#else
+ sz = static_cast<size_t>(szArgMax);
+#endif
+ }
+#endif
+ return sz;
+}
+
bool cmSystemTools::RunSingleCommand(std::vector<std::string> const& command,
std::string* captureStdOut,
std::string* captureStdErr, int* retVal,