aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Willemsen <dwillemsen@google.com>2015-08-24 15:36:38 -0700
committerDan Willemsen <dwillemsen@google.com>2016-02-10 11:19:32 -0800
commit0b544c58579cf2214d19d2dce3e20dc246810628 (patch)
tree810cfc2d88c9bc20b24164426e3d4bb3d63fa31f
parent90e52cec561a406ad5683cd384148632273719d4 (diff)
downloadandroid_build_kati-0b544c58579cf2214d19d2dce3e20dc246810628.tar.gz
android_build_kati-0b544c58579cf2214d19d2dce3e20dc246810628.tar.bz2
android_build_kati-0b544c58579cf2214d19d2dce3e20dc246810628.zip
[C++] Ninja: Detect and drop mkdir -p $(dir $@)
Ninja automatically creates the necessary output directories. This also fixes the logic to remove the empty '(true) &&' that was added for echo -> description detection.
-rw-r--r--ninja.cc34
-rw-r--r--testcase/ninja_mkdir.sh42
2 files changed, 71 insertions, 5 deletions
diff --git a/ninja.cc b/ninja.cc
index f14610f..13d5e0c 100644
--- a/ninja.cc
+++ b/ninja.cc
@@ -284,6 +284,22 @@ class NinjaGenerator {
cmd_buf->size() - orig_size);
}
+ bool IsOutputMkdir(const char *name, StringPiece cmd) {
+ if (!HasPrefix(cmd, "mkdir -p ")) {
+ return false;
+ }
+ cmd = cmd.substr(9, cmd.size());
+ if (cmd.get(cmd.size() - 1) == '/') {
+ cmd = cmd.substr(0, cmd.size() - 1);
+ }
+
+ StringPiece dir = Dirname(name);
+ if (cmd == dir) {
+ return true;
+ }
+ return false;
+ }
+
bool GetDescriptionFromCommand(StringPiece cmd, string *out) {
if (!HasPrefix(cmd, "echo ")) {
return false;
@@ -333,7 +349,8 @@ class NinjaGenerator {
return true;
}
- bool GenShellScript(const vector<Command*>& commands,
+ bool GenShellScript(const char *name,
+ const vector<Command*>& commands,
string* cmd_buf,
string* description) {
// TODO: This is a dirty hack to set local_pool even without
@@ -347,7 +364,10 @@ class NinjaGenerator {
bool got_descritpion = false;
bool use_gomacc = false;
bool should_ignore_error = false;
+ auto command_count = commands.size();
for (const Command* c : commands) {
+ size_t cmd_begin = cmd_buf->size();
+
if (!cmd_buf->empty()) {
if (should_ignore_error) {
*cmd_buf += " ; ";
@@ -361,7 +381,7 @@ class NinjaGenerator {
while (isspace(*in))
in++;
- bool needs_subshell = commands.size() > 1;
+ bool needs_subshell = command_count > 1;
if (*in == '(') {
needs_subshell = false;
}
@@ -374,11 +394,15 @@ class NinjaGenerator {
if (g_flags.detect_android_echo && !got_descritpion && !c->echo &&
GetDescriptionFromCommand(translated, description)) {
got_descritpion = true;
- cmd_buf->resize(cmd_start);
+ translated.clear();
+ } else if (IsOutputMkdir(name, translated) && !c->echo &&
+ cmd_begin == 0) {
translated.clear();
}
if (translated.empty()) {
- *cmd_buf += "true";
+ cmd_buf->resize(cmd_begin);
+ command_count -= 1;
+ continue;
} else if (g_flags.goma_dir) {
size_t pos = GetGomaccPosForAndroidCompileCommand(translated);
if (pos != string::npos) {
@@ -447,7 +471,7 @@ class NinjaGenerator {
string description = "build $out";
string cmd_buf;
- use_local_pool |= GenShellScript(commands, &cmd_buf, &description);
+ use_local_pool |= GenShellScript(node->output.c_str(), commands, &cmd_buf, &description);
fprintf(fp_, " description = %s\n", description.c_str());
EmitDepfile(node, &cmd_buf);
diff --git a/testcase/ninja_mkdir.sh b/testcase/ninja_mkdir.sh
new file mode 100644
index 0000000..e54298d
--- /dev/null
+++ b/testcase/ninja_mkdir.sh
@@ -0,0 +1,42 @@
+#!/bin/sh
+#
+# Copyright 2016 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.
+
+set -e
+
+log=/tmp/log
+mk="$@"
+
+cat <<EOF > Makefile
+test: a/b
+
+a/b:
+ @mkdir -p \$(dir \$@)
+ touch \$@
+EOF
+
+${mk} 2> ${log}
+if [ -e ninja.sh ]; then
+ ./ninja.sh
+fi
+if [[ ! -d a ]]; then
+ echo "Created 'a'"
+fi
+if [ -e ninja.sh ]; then
+ if grep -q "mkdir -p" build.ninja; then
+ echo "Should not include 'mkdir -p' in build.ninja"
+ echo "Ninja will automatically create this directory"
+ fi
+fi