]> git.ipfire.org Git - thirdparty/ccache.git/commitdiff
Handle several levels of nonexistent directories in make_relative_path (#334)
authorjonnyyu <yingshen.yu@gmail.com>
Sun, 9 Dec 2018 18:15:58 +0000 (02:15 +0800)
committerJoel Rosdahl <joel@rosdahl.net>
Sun, 9 Dec 2018 18:15:58 +0000 (19:15 +0100)
Currently, ccache supports calculating relative path
for 1 level non-exist path. That is to say,
if the given path does not exist, however if its
parent directory exists, then ccache can calculate
the relative path correctly.

Unfortunately this doesn't fit the needs.
Xcode build system always adds these paths into header search path:
xxxxx/DerivedResources/x86-64
xxxxx/DerivedResources

these paths are build outputs for build rules.
For projects which doesn't use build rule to generate files
these directories do not exist.

So this change refine the logic of make_relative_path
to recursively go up find the nearest existing directory
and use the remaining path as path_suffix.

src/ccache.c

index b3463b08736bf228c5ce36260bc44a93c036f31a..d09c16a34d22ed5eddba0defef3dfb9ef0856de2 100644 (file)
@@ -764,15 +764,21 @@ make_relative_path(char *path)
        if (stat(path, &st) != 0) {
                // path doesn't exist.
                char *dir = dirname(path);
-               if (stat(dir, &st) != 0) {
-                       // And neither does its parent directory, so no action to take.
+               // find the nearest existing directory in path
+               while (stat(dir, &st) != 0) {
+                       char *parent_dir = dirname(dir);
                        free(dir);
-                       return path;
+                       dir = parent_dir;
+               }
+
+               // suffix is the remaining of the path, skip the first delimiter
+               size_t dir_len = strlen(dir);
+               if (path[dir_len] == '/' || path[dir_len] == '\\') {
+                       dir_len++;
                }
-               free(dir);
-               path_suffix = basename(path);
+               path_suffix = x_strdup(&path[dir_len]);
                char *p = path;
-               path = dirname(path);
+               path = dir;
                free(p);
        }