summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xconfigure.py3
-rw-r--r--src/manifest_parser.cc12
-rw-r--r--src/ninja.cc9
-rw-r--r--src/version.cc56
-rw-r--r--src/version.h32
5 files changed, 102 insertions, 10 deletions
diff --git a/configure.py b/configure.py
index f530ebf..dc6bfb9 100755
--- a/configure.py
+++ b/configure.py
@@ -279,7 +279,8 @@ for name in ['build',
'manifest_parser',
'metrics',
'state',
- 'util']:
+ 'util',
+ 'version']:
objs += cxx(name)
if platform in ('mingw', 'windows'):
for name in ['subprocess-win32',
diff --git a/src/manifest_parser.cc b/src/manifest_parser.cc
index 9d17932..14fca73 100644
--- a/src/manifest_parser.cc
+++ b/src/manifest_parser.cc
@@ -23,6 +23,7 @@
#include "metrics.h"
#include "state.h"
#include "util.h"
+#include "version.h"
ManifestParser::ManifestParser(State* state, FileReader* file_reader)
: state_(state), file_reader_(file_reader) {
@@ -66,10 +67,15 @@ bool ManifestParser::Parse(const string& filename, const string& input,
case Lexer::IDENT: {
lexer_.UnreadToken();
string name;
- EvalString value;
- if (!ParseLet(&name, &value, err))
+ EvalString let_value;
+ if (!ParseLet(&name, &let_value, err))
return false;
- env_->AddBinding(name, value.Evaluate(env_));
+ string value = let_value.Evaluate(env_);
+ // Check ninja_required_version immediately so we can exit
+ // before encountering any syntactic surprises.
+ if (name == "ninja_required_version")
+ CheckNinjaVersion(value);
+ env_->AddBinding(name, value);
break;
}
case Lexer::INCLUDE:
diff --git a/src/ninja.cc b/src/ninja.cc
index 324b884..06dee8a 100644
--- a/src/ninja.cc
+++ b/src/ninja.cc
@@ -41,16 +41,13 @@
#include "metrics.h"
#include "state.h"
#include "util.h"
+#include "version.h"
// Defined in msvc_helper_main-win32.cc.
int MSVCHelperMain(int argc, char** argv);
namespace {
-/// The version number of the current Ninja release. This will always
-/// be "git" on trunk.
-const char* kVersion = "git";
-
/// Global information passed into subtools.
struct Globals {
Globals() : state(new State()) {}
@@ -121,7 +118,7 @@ void Usage(const BuildConfig& config) {
" -d MODE enable debugging (use -d list to list modes)\n"
" -t TOOL run a subtool (use -t list to list subtools)\n"
" terminates toplevel options; further flags are passed to the tool\n",
- kVersion, config.parallelism);
+ kNinjaVersion, config.parallelism);
}
/// Choose a default value for the -j (parallelism) flag.
@@ -772,7 +769,7 @@ int NinjaMain(int argc, char** argv) {
working_dir = optarg;
break;
case OPT_VERSION:
- printf("%s\n", kVersion);
+ printf("%s\n", kNinjaVersion);
return 0;
case 'h':
default:
diff --git a/src/version.cc b/src/version.cc
new file mode 100644
index 0000000..7e805c1
--- /dev/null
+++ b/src/version.cc
@@ -0,0 +1,56 @@
+// Copyright 2013 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "version.h"
+
+#include <stdlib.h>
+
+#include "util.h"
+
+const char* kNinjaVersion = "1.1.0.git";
+
+void ParseVersion(const string& version, int* major, int* minor) {
+ size_t end = version.find('.');
+ *major = atoi(version.substr(0, end).c_str());
+ *minor = 0;
+ if (end != string::npos) {
+ size_t start = end + 1;
+ end = version.find(start, '.');
+ *minor = atoi(version.substr(start, end).c_str());
+ }
+}
+
+void CheckNinjaVersion(const string& version) {
+ int bin_major, bin_minor;
+ ParseVersion(kNinjaVersion, &bin_major, &bin_minor);
+ int file_major, file_minor;
+ ParseVersion(version, &file_major, &file_minor);
+
+ if (bin_major > file_major) {
+ Warning("ninja executable version (%s) greater than build file "
+ "ninja_required_version (%s); versions may be incompatible.",
+ kNinjaVersion, version.c_str());
+ return;
+ }
+
+ if ((bin_major == file_major && bin_minor < file_minor) ||
+ bin_major < file_major) {
+ Fatal("ninja version (%s) incompatible with build file "
+ "ninja_required_version version (%s).",
+ kNinjaVersion, version.c_str());
+ }
+}
+
+
+
diff --git a/src/version.h b/src/version.h
new file mode 100644
index 0000000..bd6b9ff
--- /dev/null
+++ b/src/version.h
@@ -0,0 +1,32 @@
+// Copyright 2013 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef NINJA_VERSION_H_
+#define NINJA_VERSION_H_
+
+#include <string>
+using namespace std;
+
+/// The version number of the current Ninja release. This will always
+/// be "git" on trunk.
+extern const char* kNinjaVersion;
+
+/// Parse the major/minor components of a version string.
+void ParseVersion(const string& version, int* major, int* minor);
+
+/// Check whether \a version is compatible with the current Ninja version,
+/// aborting if not.
+void CheckNinjaVersion(const string& required_version);
+
+#endif // NINJA_VERSION_H_