aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShinichiro Hamaji <shinichiro.hamaji@gmail.com>2015-10-15 16:01:16 +0900
committerShinichiro Hamaji <shinichiro.hamaji@gmail.com>2015-10-15 16:01:16 +0900
commit6ce977d00542b689fae703311faca1766e30b286 (patch)
treee3f5a665c444ec0b855b90e9740da1cfba4b7527
parent9c5ec1d44238c033ab9cac37e56833447c422338 (diff)
downloadandroid_build_kati-6ce977d00542b689fae703311faca1766e30b286.tar.gz
android_build_kati-6ce977d00542b689fae703311faca1766e30b286.tar.bz2
android_build_kati-6ce977d00542b689fae703311faca1766e30b286.zip
[C++] Regenerate ninja files when symlink was changed
-rw-r--r--fileutil.cc14
-rw-r--r--fileutil.h1
-rw-r--r--ninja.cc17
-rwxr-xr-xtestcase/ninja_regen_find_link.sh44
4 files changed, 69 insertions, 7 deletions
diff --git a/fileutil.cc b/fileutil.cc
index d2035f3..abfad9d 100644
--- a/fileutil.cc
+++ b/fileutil.cc
@@ -41,17 +41,21 @@ bool Exists(StringPiece filename) {
return true;
}
+double GetTimestampFromStat(const struct stat& st) {
+#if defined(__linux__)
+ return st.st_mtime + st.st_mtim.tv_nsec * 0.001 * 0.001 * 0.001;
+#else
+ return st.st_mtime;
+#endif
+}
+
double GetTimestamp(StringPiece filename) {
CHECK(filename.size() < PATH_MAX);
struct stat st;
if (stat(filename.as_string().c_str(), &st) < 0) {
return -2.0;
}
-#if defined(__linux__)
- return st.st_mtime + st.st_mtim.tv_nsec * 0.001 * 0.001 * 0.001;
-#else
- return st.st_mtime;
-#endif
+ return GetTimestampFromStat(st);
}
int RunCommand(const string& shell, const string& cmd,
diff --git a/fileutil.h b/fileutil.h
index ff7b9e0..5a4740d 100644
--- a/fileutil.h
+++ b/fileutil.h
@@ -25,6 +25,7 @@
using namespace std;
bool Exists(StringPiece f);
+double GetTimestampFromStat(const struct stat& st);
double GetTimestamp(StringPiece f);
enum struct RedirectStderr {
diff --git a/ninja.cc b/ninja.cc
index 9c85815..21c935f 100644
--- a/ninja.cc
+++ b/ninja.cc
@@ -931,8 +931,21 @@ bool NeedsRegen(double start_time, const string& orig_args) {
// directory which affects the results of find command.
if (s == "" || s == "." || ShouldIgnoreDirty(s))
continue;
- double ts = GetTimestamp(s);
- should_run_command |= (ts < 0 || gen_time < ts);
+
+ struct stat st;
+ if (lstat(s.c_str(), &st) != 0) {
+ should_run_command = true;
+ continue;
+ }
+ double ts = GetTimestampFromStat(st);
+ if (gen_time < ts) {
+ should_run_command = true;
+ continue;
+ }
+ if (S_ISLNK(st.st_mode)) {
+ ts = GetTimestamp(s);
+ should_run_command |= (ts < 0 || gen_time < ts);
+ }
}
if (!should_run_command) {
diff --git a/testcase/ninja_regen_find_link.sh b/testcase/ninja_regen_find_link.sh
new file mode 100755
index 0000000..94a6bb1
--- /dev/null
+++ b/testcase/ninja_regen_find_link.sh
@@ -0,0 +1,44 @@
+#!/bin/bash
+#
+# Copyright 2015 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
+
+mk="$@"
+if echo "${mk}" | grep kati > /dev/null; then
+ mk="${mk} --use_find_emulator"
+fi
+function build() {
+ ${mk} $@ 2> /dev/null
+ if [ -e ninja.sh ]; then ./ninja.sh -j1 $@; fi
+}
+
+cat <<EOF > Makefile
+V := \$(shell find -L linkdir/d/link)
+all:
+ @echo \$(V)
+EOF
+
+mkdir -p dir1 dir2 linkdir/d
+touch dir1/file1 dir2/file2
+ln -s ../../dir1 linkdir/d/link
+build
+
+touch dir1/file1_2
+build
+
+rm linkdir/d/link
+ln -s ../../dir2 linkdir/d/link
+build