diff options
Diffstat (limited to 'libbuild2/filesystem.hxx')
-rw-r--r-- | libbuild2/filesystem.hxx | 37 |
1 files changed, 34 insertions, 3 deletions
diff --git a/libbuild2/filesystem.hxx b/libbuild2/filesystem.hxx index ee7ba9a..7b45a08 100644 --- a/libbuild2/filesystem.hxx +++ b/libbuild2/filesystem.hxx @@ -22,6 +22,8 @@ // namespace build2 { + using butl::entry_type; + using butl::auto_rmfile; using butl::auto_rmdir; @@ -73,10 +75,10 @@ namespace build2 using mkdir_status = butl::mkdir_status; LIBBUILD2_SYMEXPORT fs_status<mkdir_status> - mkdir (const dir_path&, uint16_t verbosity = 1); + mkdir (const dir_path&, uint16_t verbosity); LIBBUILD2_SYMEXPORT fs_status<mkdir_status> - mkdir_p (const dir_path&, uint16_t verbosity = 1); + mkdir_p (const dir_path&, uint16_t verbosity); // Rename a file (or file symlink) overwriting the destination if exists. // @@ -166,7 +168,7 @@ namespace build2 // LIBBUILD2_SYMEXPORT fs_status<mkdir_status> mkdir_buildignore (context&, - const dir_path&, const path&, uint16_t verbosity = 1); + const dir_path&, const path&, uint16_t verbosity); // Return true if the directory is empty or only contains the .buildignore // file. Fail if the directory doesn't exist. @@ -189,6 +191,35 @@ namespace build2 LIBBUILD2_SYMEXPORT void path_perms (const path&, permissions); + + // Normalize an absolute path to an existing file that may reside outside of + // any project and could involve funny filesystem business (e.g., relative + // directory symlinks). For example, a C/C++ header path returned by a + // compiler which could be a system header. + // + // We used to just normalize such a path but that could result in an invalid + // path (e.g., for some system/compiler headers on CentOS 7 with Clang 3.4) + // because of the symlinks (if a directory component is a symlink, then any + // following `..` are resolved relative to the target; see path::normalize() + // for background). + // + // Initially, to fix this, we realized (i.e., realpath(3)) it instead. But + // that turned out also not to be quite right since now we have all the + // symlinks resolved: conceptually it feels correct to keep the original + // header names since that's how the user chose to arrange things and + // practically this is how compilers see/report them (e.g., the GCC module + // mapper). + // + // So now we have a pretty elaborate scheme where we try to use the + // normalized path if possible and fallback to realized. Normalized paths + // will work for situations where `..` does not cross symlink boundaries, + // which is the sane case. And for the insane case we only really care + // about out-of-project files (i.e., system/compiler headers). In other + // words, if you have the insane case inside your project, then you are on + // your own. + // + LIBBUILD2_SYMEXPORT void + normalize_external (path&, const char* what); } #include <libbuild2/filesystem.ixx> |