aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Willemsen <dwillemsen@google.com>2016-03-22 14:08:17 -0700
committerDan Willemsen <dwillemsen@google.com>2016-03-22 19:53:36 -0700
commit6ac18ecb84332b6e84f498434812541f58a64ed4 (patch)
treeaf18bd7447c199f1c99fe0dc9b880aeb30dc8b3a
parent7253e0b8a486797347b8bdec43aa98ce135f3ad7 (diff)
downloadbuild_soong-6ac18ecb84332b6e84f498434812541f58a64ed4.tar.gz
build_soong-6ac18ecb84332b6e84f498434812541f58a64ed4.tar.bz2
build_soong-6ac18ecb84332b6e84f498434812541f58a64ed4.zip
Improve BUILDDIR handling with symlinks
If BUILDDIR is a local symlink to another directory in the same parent directory (out -> out.angler), then using out and .. as relative paths to get back and forth work. But if BUILDDIR is a symlink to another directory altogether (out -> /mnt/sdd/out.master), then we shouldn't be relying on relative paths (so that the source directory can still be moved). Change-Id: I946c8116090410ab2b935eafba9b6e96f5f2f1dd
-rwxr-xr-xbootstrap.bash12
-rwxr-xr-xreverse_path.py40
-rw-r--r--reverse_path_test.py45
3 files changed, 87 insertions, 10 deletions
diff --git a/bootstrap.bash b/bootstrap.bash
index c4c7e35c..62c429c5 100755
--- a/bootstrap.bash
+++ b/bootstrap.bash
@@ -8,11 +8,7 @@ if [[ "$ORIG_SRCDIR" != "." ]]; then
echo "error: To use BUILDDIR, run from the source directory"
exit 1
fi
- if [[ ${ORIG_SRCDIR:0:1} == '/' ]]; then
- export BUILDDIR=$PWD
- else
- export BUILDDIR=$(python -c "import os; print os.path.relpath('.', '$ORIG_SRCDIR')")
- fi
+ export BUILDDIR=$("${ORIG_SRCDIR}/build/soong/reverse_path.py" "$ORIG_SRCDIR")
cd $ORIG_SRCDIR
fi
if [[ -z "$BUILDDIR" ]]; then
@@ -49,11 +45,7 @@ if [[ $# -eq 0 ]]; then
exit 1
fi
- if [[ ${BUILDDIR:0:1} == '/' ]]; then
- export SRCDIR_FROM_BUILDDIR=$PWD
- else
- export SRCDIR_FROM_BUILDDIR=$(python -c "import os; print os.path.relpath('.', '$BUILDDIR')")
- fi
+ export SRCDIR_FROM_BUILDDIR=$(build/soong/reverse_path.py "$BUILDDIR")
sed -e "s|@@BuildDir@@|${BUILDDIR}|" \
-e "s|@@SrcDirFromBuildDir@@|${SRCDIR_FROM_BUILDDIR}|" \
diff --git a/reverse_path.py b/reverse_path.py
new file mode 100755
index 00000000..7b7d6217
--- /dev/null
+++ b/reverse_path.py
@@ -0,0 +1,40 @@
+#!/usr/bin/env python
+
+from __future__ import print_function
+
+import os
+import sys
+
+# Find the best reverse path to reference the current directory from another
+# directory. We use this to find relative paths to and from the source and build
+# directories.
+#
+# If the directory is given as an absolute path, return an absolute path to the
+# current directory.
+#
+# If there's a symlink involved, and the same relative path would not work if
+# the symlink was replace with a regular directory, then return an absolute
+# path. This handles paths like out -> /mnt/ssd/out
+#
+# For symlinks that can use the same relative path (out -> out.1), just return
+# the relative path. That way out.1 can be renamed as long as the symlink is
+# updated.
+#
+# For everything else, just return the relative path. That allows the source and
+# output directories to be moved as long as they stay in the same position
+# relative to each other.
+def reverse_path(path):
+ if path.startswith("/"):
+ return os.path.abspath('.')
+
+ realpath = os.path.relpath(os.path.realpath('.'), os.path.realpath(path))
+ relpath = os.path.relpath('.', path)
+
+ if realpath != relpath:
+ return os.path.abspath('.')
+
+ return relpath
+
+
+if __name__ == '__main__':
+ print(reverse_path(sys.argv[1]))
diff --git a/reverse_path_test.py b/reverse_path_test.py
new file mode 100644
index 00000000..c5bb8e69
--- /dev/null
+++ b/reverse_path_test.py
@@ -0,0 +1,45 @@
+from __future__ import print_function
+
+import os
+import shutil
+import tempfile
+import unittest
+
+from reverse_path import reverse_path
+
+class TestReversePath(unittest.TestCase):
+ def setUp(self):
+ self.tmpdir = tempfile.mkdtemp()
+ os.chdir(self.tmpdir)
+
+ def tearDown(self):
+ shutil.rmtree(self.tmpdir)
+
+ def test_absolute(self):
+ self.assertEqual(self.tmpdir, reverse_path('/out'))
+
+ def test_relative(self):
+ os.mkdir('a')
+ os.mkdir('b')
+
+ self.assertEqual('..', reverse_path('a'))
+
+ os.chdir('a')
+ self.assertEqual('a', reverse_path('..'))
+ self.assertEqual('.', reverse_path('../a'))
+ self.assertEqual('../a', reverse_path('../b'))
+
+ def test_symlink(self):
+ os.mkdir('b')
+ os.symlink('b', 'a')
+ os.mkdir('b/d')
+ os.symlink('b/d', 'c')
+
+ self.assertEqual('..', reverse_path('a'))
+ self.assertEqual('..', reverse_path('b'))
+ self.assertEqual(self.tmpdir, reverse_path('c'))
+ self.assertEqual('../..', reverse_path('b/d'))
+
+
+if __name__ == '__main__':
+ unittest.main()