aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2016-07-30 11:41:48 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2016-07-30 11:41:48 +0200
commit988fd0eec5d88bf6534fb1f645777350c20d4723 (patch)
treeb04f8c47dedc7d63b138ce50356f509196c4f7bc
parente3004011bbab5b0e031804465a0c340c7102be6d (diff)
Actualize project root directories
This solves the problem of changing path spelling on platforms with case- insensitive filesystems. For example, you may build a project in the current working directory without specifying any paths. This means the current working directory will be used as the project's root. On Windows this could be C:\x. Now you are building another project that imports the above project and you specify config.import.x variable pointing to the above build. But you are lazy to type capital C so you spell it as config.import.x=c:\x. What happens now is the value from config.import.x is used as the project root. And now it is a different spelling compared to your original build. This is not a problem when the build system itself is concerned -- it is smart enough to use case-insensitive comparison. However, we often use roots to derive other things, say, -I options that we pass to compilers. And these options are normally no longer treated as (case-insensitive) paths. If they are hashed and the result stored in depdb, then we end up with rebuilds that are triggered by changes from C:\ to c:\.
-rw-r--r--build2/b.cxx12
-rw-r--r--build2/file16
-rw-r--r--build2/file.cxx6
-rw-r--r--build2/types2
-rw-r--r--build2/variable.cxx2
5 files changed, 23 insertions, 15 deletions
diff --git a/build2/b.cxx b/build2/b.cxx
index b2ba2c1..4efbdd2 100644
--- a/build2/b.cxx
+++ b/build2/b.cxx
@@ -358,7 +358,9 @@ main (int argc, char* argv[])
if (out_base.relative ())
out_base = work / out_base;
- out_base.normalize ();
+ // This directory came from the command line so actualize it.
+ //
+ out_base.normalize (true);
// The order in which we determine the roots depends on whether
// src_base was specified explicitly. There will also be a few
@@ -384,7 +386,9 @@ main (int argc, char* argv[])
if (src_base.relative ())
src_base = work / src_base;
- src_base.normalize ();
+ // Also came from the command line, so actualize.
+ //
+ src_base.normalize (true);
// If the src_base was explicitly specified, search for src_root.
//
@@ -427,7 +431,7 @@ main (int argc, char* argv[])
//
if (out_root.empty ())
{
- src_root = find_src_root (work);
+ src_root = find_src_root (work); // Work is actualized.
if (!src_root.empty ())
{
@@ -512,7 +516,7 @@ main (int argc, char* argv[])
// If not, then assume we are running from src_base
// and calculate src_root based on out_root/out_base.
//
- src_base = work;
+ src_base = work; // Work is actualized.
src_root = src_base.directory (out_base.leaf (out_root));
guessing = true;
}
diff --git a/build2/file b/build2/file
index 00ece85..062487a 100644
--- a/build2/file
+++ b/build2/file
@@ -34,17 +34,19 @@ namespace build2
bool
is_out_root (const dir_path&);
- // Given an src_base directory, look for a project's src_root
- // based on the presence of known special files. Return empty
- // path if not found.
+ // Given an src_base directory, look for a project's src_root based on the
+ // presence of known special files. Return empty path if not found. Note
+ // that if the input is normalized/actualized, then the output will be as
+ // well.
//
dir_path
find_src_root (const dir_path&);
- // The same as above but for project's out. Note that we also
- // check whether a directory happens to be src_root, in case
- // this is an in-tree build. The second argument is the out
- // flag that is set to true if this is src_root.
+ // The same as above but for project's out. Note that we also check whether
+ // a directory happens to be src_root, in case this is an in-tree build. The
+ // second argument is the out flag that is set to true if this is src_root.
+ // Note that if the input is normalized/actualized, then the output will be
+ // as well.
//
dir_path
find_out_root (const dir_path&, bool* src = nullptr);
diff --git a/build2/file.cxx b/build2/file.cxx
index 155c8e6..a70c97a 100644
--- a/build2/file.cxx
+++ b/build2/file.cxx
@@ -664,7 +664,7 @@ namespace build2
const dir_path& d (cast<dir_path> (l));
dir_path out_root (root.out_path () / d);
- out_root.normalize ();
+ out_root.normalize (); // No need to actualize (d is a bunch of ..)
// src_root is a bit more complicated. Here we have three cases:
//
@@ -692,7 +692,7 @@ namespace build2
else // #1
{
dir_path src_root (root.src_path () / d);
- src_root.normalize ();
+ src_root.normalize (); // No need to actualize (as above).
v = move (src_root);
}
}
@@ -855,7 +855,7 @@ namespace build2
if (auto l = iroot[var])
{
- out_root = cast<dir_path> (l);
+ out_root = cast<dir_path> (l); // Normalized and actualized.
config::save_variable (iroot, var); // Mark as part of configuration.
}
else
diff --git a/build2/types b/build2/types
index 5409c60..8ccbd13 100644
--- a/build2/types
+++ b/build2/types
@@ -91,6 +91,8 @@ namespace build2
// a (variable) value of this type gets initialized from untyped names. See
// value_type<abs_dir_path> for details.
//
+ // Note that currently we also normalize and actualize the path.
+ //
struct abs_dir_path: dir_path
{
using dir_path::dir_path;
diff --git a/build2/variable.cxx b/build2/variable.cxx
index 2d4db86..eec0573 100644
--- a/build2/variable.cxx
+++ b/build2/variable.cxx
@@ -601,7 +601,7 @@ namespace build2
if (d.relative ())
d.complete ();
- d.normalize ();
+ d.normalize (true); // Actualize.
return abs_dir_path (move (d));
}