From a68ccd960a685d6082ecc6963d2de311b02632d9 Mon Sep 17 00:00:00 2001 From: jonnyyu Date: Mon, 10 Dec 2018 02:15:58 +0800 Subject: [PATCH] Handle several levels of nonexistent directories in make_relative_path (#334) 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 | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/ccache.c b/src/ccache.c index b3463b087..d09c16a34 100644 --- a/src/ccache.c +++ b/src/ccache.c @@ -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); } -- 2.47.3