From 1554c3577fee79b7efa04c618605e337d5876c0a Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Fri, 15 Mar 2013 18:11:43 -0500 Subject: [PATCH] pkg: rework PKG_CONFIG_PATH handling code. As a side effect, the dependency resolver now understands that it should check in the parent directory as well for dependencies if given a literal path to a .pc file. (pkg-config 0.28 does not do this, it should.) --- pkg.c | 127 ++++++++++++++++++++++-------------------------- pkg.h | 1 - tests/run.sh.in | 2 + 3 files changed, 61 insertions(+), 69 deletions(-) diff --git a/pkg.c b/pkg.c index 390628e..d338fca 100644 --- a/pkg.c +++ b/pkg.c @@ -43,6 +43,17 @@ typedef struct { pkg_node_t node; } pkg_path_t; +static inline void +path_add(const char *text, pkg_list_t *dirlist) +{ + pkg_path_t *pkg_path; + + pkg_path = calloc(sizeof(pkg_path_t), 1); + pkg_path->path = strdup(text); + + pkg_node_insert_tail(&pkg_path->node, pkg_path, dirlist); +} + static inline size_t path_split(const char *text, pkg_list_t *dirlist) { @@ -55,12 +66,7 @@ path_split(const char *text, pkg_list_t *dirlist) iter = workbuf = strdup(text); while ((p = strtok(iter, PKG_CONFIG_PATH_SEP_S)) != NULL) { - pkg_path_t *pkg_path; - - pkg_path = calloc(sizeof(pkg_path_t), 1); - pkg_path->path = strdup(p); - - pkg_node_insert_tail(&pkg_path->node, pkg_path, dirlist); + path_add(p, dirlist); count++, iter = NULL; } @@ -147,6 +153,34 @@ pkg_get_parent_dir(pkg_t *pkg) return buf; } +static pkg_list_t pkg_dir_list = PKG_LIST_INITIALIZER; + +void +pkg_dir_list_build(unsigned int flags) +{ + const char *env_path; + + if (pkg_dir_list.head != NULL || pkg_dir_list.tail != NULL) + return; + + /* PKG_CONFIG_PATH has to take precedence */ + env_path = getenv("PKG_CONFIG_PATH"); + if (env_path) + path_split(env_path, &pkg_dir_list); + + if (!(flags & PKGF_ENV_ONLY)) + { + env_path = get_pkgconfig_path(); + path_split(env_path, &pkg_dir_list); + } +} + +void +pkg_dir_list_free(void) +{ + path_free(&pkg_dir_list); +} + /* * pkg_new_from_file(filename, file, flags) * @@ -368,40 +402,18 @@ pkg_scan_dir(const char *path, pkg_iteration_func_t func) } void -pkg_scan(const char *search_path, pkg_iteration_func_t func) +pkg_scan_all(pkg_iteration_func_t func) { - pkg_list_t path = PKG_LIST_INITIALIZER; pkg_node_t *n; - /* PKG_CONFIG_PATH has to take precedence */ - if (search_path == NULL) - return; + pkg_dir_list_build(0); - path_split(search_path, &path); - - PKG_FOREACH_LIST_ENTRY(path.head, n) + PKG_FOREACH_LIST_ENTRY(pkg_dir_list.head, n) { pkg_path_t *pkg_path = n->data; pkg_scan_dir(pkg_path->path, func); } - - path_free(&path); -} - -void -pkg_scan_all(pkg_iteration_func_t func) -{ - char *path; - - path = getenv("PKG_CONFIG_PATH"); - if (path) - { - pkg_scan(path, func); - return; - } - - pkg_scan(get_pkgconfig_path(), func); } #ifdef _WIN32 @@ -445,16 +457,22 @@ pkg_find_in_registry_key(HKEY hkey, const char *name, unsigned int flags) pkg_t * pkg_find(const char *name, unsigned int flags) { - pkg_list_t path = PKG_LIST_INITIALIZER; - const char *env_path; pkg_t *pkg = NULL; + pkg_node_t *n; FILE *f; /* name might actually be a filename. */ if (str_has_suffix(name, PKG_CONFIG_EXT)) { if ((f = fopen(name, "r")) != NULL) - return pkg_new_from_file(name, f, flags); + { + pkg_t *pkg; + + pkg = pkg_new_from_file(name, f, flags); + path_add(pkg_get_parent_dir(pkg), &pkg_dir_list); + + return pkg; + } } /* check cache */ @@ -467,41 +485,15 @@ pkg_find(const char *name, unsigned int flags) } } - /* PKG_CONFIG_PATH has to take precedence */ - env_path = getenv("PKG_CONFIG_PATH"); - if (env_path) + pkg_dir_list_build(flags); + + PKG_FOREACH_LIST_ENTRY(pkg_dir_list.head, n) { - pkg_node_t *n; + pkg_path_t *pkg_path = n->data; - path_split(env_path, &path); - - PKG_FOREACH_LIST_ENTRY(path.head, n) - { - pkg_path_t *pkg_path = n->data; - - pkg = pkg_try_specific_path(pkg_path->path, name, flags); - if (pkg != NULL) - goto out; - } - - path_free(&path); - } - - env_path = get_pkgconfig_path(); - if (!(flags & PKGF_ENV_ONLY)) - { - pkg_node_t *n; - - path_split(env_path, &path); - - PKG_FOREACH_LIST_ENTRY(path.head, n) - { - pkg_path_t *pkg_path = n->data; - - pkg = pkg_try_specific_path(pkg_path->path, name, flags); - if (pkg != NULL) - goto out; - } + pkg = pkg_try_specific_path(pkg_path->path, name, flags); + if (pkg != NULL) + goto out; } #ifdef _WIN32 @@ -513,7 +505,6 @@ pkg_find(const char *name, unsigned int flags) out: pkg_cache_add(pkg); - path_free(&path); return pkg; } diff --git a/pkg.h b/pkg.h index 610e645..ca071b6 100644 --- a/pkg.h +++ b/pkg.h @@ -133,7 +133,6 @@ pkg_t *pkg_ref(pkg_t *pkg); void pkg_unref(pkg_t *pkg); void pkg_free(pkg_t *pkg); pkg_t *pkg_find(const char *name, unsigned int flags); -void pkg_scan(const char *search_path, pkg_iteration_func_t func); void pkg_scan_all(pkg_iteration_func_t func); unsigned int pkg_traverse(pkg_t *root, pkg_traverse_func_t func, void *data, int maxdepth, unsigned int flags); unsigned int pkg_verify_graph(pkg_t *root, int depth, unsigned int flags); diff --git a/tests/run.sh.in b/tests/run.sh.in index 51515f7..a0e0a99 100644 --- a/tests/run.sh.in +++ b/tests/run.sh.in @@ -94,6 +94,8 @@ run_test "PKG_CONFIG_PATH='${selfdir}/lib1' ${1} --libs circular-1" \ '-lcircular-1 -lcircular-2 -lcircular-3' run_test "PKG_CONFIG_PATH='${selfdir}/lib1' ${1} --libs circular-3" \ '-lcircular-3 -lcircular-1 -lcircular-2' +run_test "${1} --libs ${selfdir}/lib1/circular-3.pc" \ + '-lcircular-1 -lcircular-2 -lcircular-3' run_test "PKG_CONFIG_PATH='${selfdir}/lib1' ${1} --libs static-archive-libs" \ '/libfoo.a -pthread'