Merge pull request #1876 from orgads/msvc-warnings
Suppress MSVC warnings
diff --git a/.clang-tidy b/.clang-tidy
index df4c1ed..18ffaac 100644
--- a/.clang-tidy
+++ b/.clang-tidy
@@ -1,12 +1,14 @@
---
Checks: '
,readability-avoid-const-params-in-decls,
+ ,readability-inconsistent-declaration-parameter-name,
,readability-non-const-parameter,
,readability-redundant-string-cstr,
,readability-redundant-string-init,
'
WarningsAsErrors: '
,readability-avoid-const-params-in-decls,
+ ,readability-inconsistent-declaration-parameter-name,
,readability-non-const-parameter,
,readability-redundant-string-cstr,
,readability-redundant-string-init,
diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml
index 411cfe1..4ea958f 100644
--- a/.github/workflows/macos.yml
+++ b/.github/workflows/macos.yml
@@ -8,7 +8,7 @@
jobs:
build:
- runs-on: macOS-latest
+ runs-on: macos-11.0
steps:
- uses: actions/checkout@v2
@@ -21,8 +21,9 @@
env:
MACOSX_DEPLOYMENT_TARGET: 10.12
run: |
- cmake -DCMAKE_BUILD_TYPE=Release -B build
- cmake --build build --parallel --config Release
+ sudo xcode-select -s /Applications/Xcode_12.2.app
+ cmake -Bbuild -GXcode '-DCMAKE_OSX_ARCHITECTURES=arm64;x86_64'
+ cmake --build build --config Release
- name: Test ninja
run: ctest -vv
@@ -32,7 +33,7 @@
shell: bash
run: |
mkdir artifact
- 7z a artifact/ninja-mac.zip ./build/ninja
+ 7z a artifact/ninja-mac.zip ./build/Release/ninja
# Upload ninja binary archive as an artifact
- name: Upload artifact
diff --git a/.gitignore b/.gitignore
index dca1129..b9a45a1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -38,3 +38,7 @@
# Qt Creator project files
/CMakeLists.txt.user
+
+# clangd
+/.clangd/
+/compile_commands.json
diff --git a/CMakeLists.txt b/CMakeLists.txt
index d772e15..3e4bafa 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,20 +1,18 @@
cmake_minimum_required(VERSION 3.15)
include(CheckIncludeFileCXX)
+include(CheckIPOSupported)
project(ninja)
# --- optional link-time optimization
-if(CMAKE_BUILD_TYPE MATCHES "Release")
- include(CheckIPOSupported)
- check_ipo_supported(RESULT lto_supported OUTPUT error)
+check_ipo_supported(RESULT lto_supported OUTPUT error)
- if(lto_supported)
- message(STATUS "IPO / LTO enabled")
- set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
- else()
- message(STATUS "IPO / LTO not supported: <${error}>")
- endif()
+if(lto_supported)
+ message(STATUS "IPO / LTO enabled")
+ set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE TRUE)
+else()
+ message(STATUS "IPO / LTO not supported: <${error}>")
endif()
# --- compiler flags
@@ -114,6 +112,14 @@
endif()
else()
target_sources(libninja PRIVATE src/subprocess-posix.cc)
+ if(CMAKE_SYSTEM_NAME STREQUAL "OS400" OR CMAKE_SYSTEM_NAME STREQUAL "AIX")
+ target_sources(libninja PRIVATE src/getopt.c)
+ endif()
+
+ # Needed for perfstat_cpu_total
+ if(CMAKE_SYSTEM_NAME STREQUAL "AIX")
+ target_link_libraries(libninja PUBLIC "-lperfstat")
+ endif()
endif()
#Fixes GetActiveProcessorCount on MinGW
@@ -121,11 +127,10 @@
target_compile_definitions(libninja PRIVATE _WIN32_WINNT=0x0601 __USE_MINGW_ANSI_STDIO=1)
endif()
-# On IBM i (identified as "OS400" for compatibility reasons), this fixes missing
-# PRId64 (and others) at compile time, and links to libutil for getopt_long
-if(CMAKE_SYSTEM_NAME STREQUAL "OS400")
+# On IBM i (identified as "OS400" for compatibility reasons) and AIX, this fixes missing
+# PRId64 (and others) at compile time in C++ sources
+if(CMAKE_SYSTEM_NAME STREQUAL "OS400" OR CMAKE_SYSTEM_NAME STREQUAL "AIX")
string(APPEND CMAKE_CXX_FLAGS " -D__STDC_FORMAT_MACROS")
- string(APPEND CMAKE_EXE_LINKER_FLAGS " -lutil")
endif()
# Main executable is library plus main() function.
@@ -198,6 +203,12 @@
target_link_libraries(${perftest} PRIVATE libninja libninja-re2c)
endforeach()
+ if(CMAKE_SYSTEM_NAME STREQUAL "AIX" AND CMAKE_SIZEOF_VOID_P EQUAL 4)
+ # These tests require more memory than will fit in the standard AIX shared stack/heap (256M)
+ target_link_libraries(hash_collision_bench PRIVATE "-Wl,-bmaxdata:0x80000000")
+ target_link_libraries(manifest_parser_perftest PRIVATE "-Wl,-bmaxdata:0x80000000")
+ endif()
+
add_test(NinjaTest ninja_test)
endif()
diff --git a/configure.py b/configure.py
index 48c4821..cded265 100755
--- a/configure.py
+++ b/configure.py
@@ -596,6 +596,11 @@
n.comment('Ancillary executables.')
+if platform.is_aix() and '-maix64' not in ldflags:
+ # Both hash_collision_bench and manifest_parser_perftest require more
+ # memory than will fit in the standard 32-bit AIX shared stack/heap (256M)
+ libs.append('-Wl,-bmaxdata:0x80000000')
+
for name in ['build_log_perftest',
'canon_perftest',
'depfile_parser_perftest',
diff --git a/src/build.cc b/src/build.cc
index 2fb2aa4..2007d82 100644
--- a/src/build.cc
+++ b/src/build.cc
@@ -318,8 +318,8 @@
want_.clear();
}
-bool Plan::AddTarget(const Node* node, string* err) {
- return AddSubTarget(node, NULL, err, NULL);
+bool Plan::AddTarget(const Node* target, string* err) {
+ return AddSubTarget(target, NULL, err, NULL);
}
bool Plan::AddSubTarget(const Node* node, const Node* dependent, string* err,
@@ -381,7 +381,7 @@
Edge* Plan::FindWork() {
if (ready_.empty())
return NULL;
- set<Edge*>::iterator e = ready_.begin();
+ EdgeSet::iterator e = ready_.begin();
Edge* edge = *e;
ready_.erase(e);
return edge;
@@ -782,16 +782,16 @@
return node;
}
-bool Builder::AddTarget(Node* node, string* err) {
- if (!scan_.RecomputeDirty(node, err))
+bool Builder::AddTarget(Node* target, string* err) {
+ if (!scan_.RecomputeDirty(target, err))
return false;
- if (Edge* in_edge = node->in_edge()) {
+ if (Edge* in_edge = target->in_edge()) {
if (in_edge->outputs_ready())
return true; // Nothing to do.
}
- if (!plan_.AddTarget(node, err))
+ if (!plan_.AddTarget(target, err))
return false;
return true;
diff --git a/src/build.h b/src/build.h
index 2798693..0a68478 100644
--- a/src/build.h
+++ b/src/build.h
@@ -19,7 +19,6 @@
#include <map>
#include <memory>
#include <queue>
-#include <set>
#include <string>
#include <vector>
@@ -46,7 +45,7 @@
/// Add a target to our plan (including all its dependencies).
/// Returns false if we don't need to build this target; may
/// fill in |err| with an error message if there's a problem.
- bool AddTarget(const Node* node, std::string* err);
+ bool AddTarget(const Node* target, std::string* err);
// Pop a ready edge off the queue of edges to build.
// Returns NULL if there's no work to do.
@@ -122,7 +121,7 @@
/// we want for the edge.
std::map<Edge*, Want> want_;
- std::set<Edge*> ready_;
+ EdgeSet ready_;
Builder* builder_;
diff --git a/src/graph.h b/src/graph.h
index 4833f49..8c51782 100644
--- a/src/graph.h
+++ b/src/graph.h
@@ -15,6 +15,7 @@
#ifndef NINJA_GRAPH_H_
#define NINJA_GRAPH_H_
+#include <set>
#include <string>
#include <vector>
@@ -143,10 +144,11 @@
VisitDone
};
- Edge() : rule_(NULL), pool_(NULL), dyndep_(NULL), env_(NULL),
- mark_(VisitNone), outputs_ready_(false), deps_loaded_(false),
- deps_missing_(false), implicit_deps_(0), order_only_deps_(0),
- implicit_outs_(0) {}
+ Edge()
+ : rule_(NULL), pool_(NULL), dyndep_(NULL), env_(NULL), mark_(VisitNone),
+ id_(0), outputs_ready_(false), deps_loaded_(false),
+ deps_missing_(false), implicit_deps_(0), order_only_deps_(0),
+ implicit_outs_(0) {}
/// Return true if all inputs' in-edges are ready.
bool AllInputsReady() const;
@@ -176,6 +178,7 @@
Node* dyndep_;
BindingEnv* env_;
VisitMark mark_;
+ size_t id_;
bool outputs_ready_;
bool deps_loaded_;
bool deps_missing_;
@@ -218,6 +221,13 @@
bool maybe_phonycycle_diagnostic() const;
};
+struct EdgeCmp {
+ bool operator()(const Edge* a, const Edge* b) const {
+ return a->id_ < b->id_;
+ }
+};
+
+typedef std::set<Edge*, EdgeCmp> EdgeSet;
/// ImplicitDepLoader loads implicit dependencies, as referenced via the
/// "depfile" attribute in build files.
diff --git a/src/graphviz.h b/src/graphviz.h
index 601c9b2..3a3282e 100644
--- a/src/graphviz.h
+++ b/src/graphviz.h
@@ -18,6 +18,7 @@
#include <set>
#include "dyndep.h"
+#include "graph.h"
struct DiskInterface;
struct Node;
@@ -34,7 +35,7 @@
DyndepLoader dyndep_loader_;
std::set<Node*> visited_nodes_;
- std::set<Edge*> visited_edges_;
+ EdgeSet visited_edges_;
};
#endif // NINJA_GRAPHVIZ_H_
diff --git a/src/hash_collision_bench.cc b/src/hash_collision_bench.cc
index 52ff56d..8f37ed0 100644
--- a/src/hash_collision_bench.cc
+++ b/src/hash_collision_bench.cc
@@ -27,9 +27,10 @@
void RandomCommand(char** s) {
int len = random(5, 100);
- *s = new char[len];
+ *s = new char[len+1];
for (int i = 0; i < len; ++i)
(*s)[i] = (char)random(32, 127);
+ (*s)[len] = '\0';
}
int main() {
diff --git a/src/manifest_parser_perftest.cc b/src/manifest_parser_perftest.cc
index 92f5e13..853d8e0 100644
--- a/src/manifest_parser_perftest.cc
+++ b/src/manifest_parser_perftest.cc
@@ -25,6 +25,9 @@
#ifdef _WIN32
#include "getopt.h"
#include <direct.h>
+#elif defined(_AIX)
+#include "getopt.h"
+#include <unistd.h>
#else
#include <getopt.h>
#include <unistd.h>
diff --git a/src/ninja.cc b/src/ninja.cc
index 471a023..eb97320 100644
--- a/src/ninja.cc
+++ b/src/ninja.cc
@@ -613,7 +613,7 @@
}
enum PrintCommandMode { PCM_Single, PCM_All };
-void PrintCommands(Edge* edge, set<Edge*>* seen, PrintCommandMode mode) {
+void PrintCommands(Edge* edge, EdgeSet* seen, PrintCommandMode mode) {
if (!edge)
return;
if (!seen->insert(edge).second)
@@ -664,7 +664,7 @@
return 1;
}
- set<Edge*> seen;
+ EdgeSet seen;
for (vector<Node*>::iterator in = nodes.begin(); in != nodes.end(); ++in)
PrintCommands((*in)->in_edge(), &seen, mode);
diff --git a/src/state.cc b/src/state.cc
index d3a9e29..a33d5a8 100644
--- a/src/state.cc
+++ b/src/state.cc
@@ -39,7 +39,7 @@
delayed_.insert(edge);
}
-void Pool::RetrieveReadyEdges(set<Edge*>* ready_queue) {
+void Pool::RetrieveReadyEdges(EdgeSet* ready_queue) {
DelayedEdges::iterator it = delayed_.begin();
while (it != delayed_.end()) {
Edge* edge = *it;
@@ -62,14 +62,6 @@
}
}
-// static
-bool Pool::WeightedEdgeCmp(const Edge* a, const Edge* b) {
- if (!a) return b;
- if (!b) return false;
- int weight_diff = a->weight() - b->weight();
- return ((weight_diff < 0) || (weight_diff == 0 && a < b));
-}
-
Pool State::kDefaultPool("", 0);
Pool State::kConsolePool("console", 1);
const Rule State::kPhonyRule("phony");
@@ -97,6 +89,7 @@
edge->rule_ = rule;
edge->pool_ = &State::kDefaultPool;
edge->env_ = &bindings_;
+ edge->id_ = edges_.size();
edges_.push_back(edge);
return edge;
}
diff --git a/src/state.h b/src/state.h
index f553ed4..72c5b33 100644
--- a/src/state.h
+++ b/src/state.h
@@ -21,6 +21,7 @@
#include <vector>
#include "eval_env.h"
+#include "graph.h"
#include "hash_map.h"
#include "util.h"
@@ -38,7 +39,7 @@
/// completes).
struct Pool {
Pool(const std::string& name, int depth)
- : name_(name), current_use_(0), depth_(depth), delayed_(&WeightedEdgeCmp) {}
+ : name_(name), current_use_(0), depth_(depth), delayed_() {}
// A depth of 0 is infinite
bool is_valid() const { return depth_ >= 0; }
@@ -61,7 +62,7 @@
void DelayEdge(Edge* edge);
/// Pool will add zero or more edges to the ready_queue
- void RetrieveReadyEdges(std::set<Edge*>* ready_queue);
+ void RetrieveReadyEdges(EdgeSet* ready_queue);
/// Dump the Pool and its edges (useful for debugging).
void Dump() const;
@@ -74,9 +75,16 @@
int current_use_;
int depth_;
- static bool WeightedEdgeCmp(const Edge* a, const Edge* b);
+ struct WeightedEdgeCmp {
+ bool operator()(const Edge* a, const Edge* b) const {
+ if (!a) return b;
+ if (!b) return false;
+ int weight_diff = a->weight() - b->weight();
+ return ((weight_diff < 0) || (weight_diff == 0 && EdgeCmp()(a, b)));
+ }
+ };
- typedef std::set<Edge*,bool(*)(const Edge*, const Edge*)> DelayedEdges;
+ typedef std::set<Edge*, WeightedEdgeCmp> DelayedEdges;
DelayedEdges delayed_;
};
diff --git a/src/util.cc b/src/util.cc
index c76f730..05bdb2d 100644
--- a/src/util.cc
+++ b/src/util.cc
@@ -51,6 +51,10 @@
#include <sys/sysinfo.h>
#endif
+#if defined(__FreeBSD__)
+#include <sys/cpuset.h>
+#endif
+
#include "edit_distance.h"
#include "metrics.h"
@@ -485,10 +489,17 @@
#ifdef _WIN32
return GetActiveProcessorCount(ALL_PROCESSOR_GROUPS);
#else
-#ifdef CPU_COUNT
// The number of exposed processors might not represent the actual number of
// processors threads can run on. This happens when a CPU set limitation is
// active, see https://github.com/ninja-build/ninja/issues/1278
+#if defined(__FreeBSD__)
+ cpuset_t mask;
+ CPU_ZERO(&mask);
+ if (cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TID, -1, sizeof(mask),
+ &mask) == 0) {
+ return CPU_COUNT(&mask);
+ }
+#elif defined(CPU_COUNT)
cpu_set_t set;
if (sched_getaffinity(getpid(), sizeof(set), &set) == 0) {
return CPU_COUNT(&set);
diff --git a/src/version.cc b/src/version.cc
index f25a30a..97afa7e 100644
--- a/src/version.cc
+++ b/src/version.cc
@@ -20,7 +20,7 @@
using namespace std;
-const char* kNinjaVersion = "1.10.1.git";
+const char* kNinjaVersion = "1.10.2.git";
void ParseVersion(const string& version, int* major, int* minor) {
size_t end = version.find('.');