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.)
pull/48/head
William Pitcock 2013-03-15 18:11:43 -05:00
parent 48c6e4c383
commit 1554c3577f
3 changed files with 61 additions and 69 deletions

127
pkg.c
View File

@ -43,6 +43,17 @@ typedef struct {
pkg_node_t node; pkg_node_t node;
} pkg_path_t; } 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 static inline size_t
path_split(const char *text, pkg_list_t *dirlist) 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); iter = workbuf = strdup(text);
while ((p = strtok(iter, PKG_CONFIG_PATH_SEP_S)) != NULL) while ((p = strtok(iter, PKG_CONFIG_PATH_SEP_S)) != NULL)
{ {
pkg_path_t *pkg_path; path_add(p, dirlist);
pkg_path = calloc(sizeof(pkg_path_t), 1);
pkg_path->path = strdup(p);
pkg_node_insert_tail(&pkg_path->node, pkg_path, dirlist);
count++, iter = NULL; count++, iter = NULL;
} }
@ -147,6 +153,34 @@ pkg_get_parent_dir(pkg_t *pkg)
return buf; 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) * pkg_new_from_file(filename, file, flags)
* *
@ -368,40 +402,18 @@ pkg_scan_dir(const char *path, pkg_iteration_func_t func)
} }
void 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_node_t *n;
/* PKG_CONFIG_PATH has to take precedence */ pkg_dir_list_build(0);
if (search_path == NULL)
return;
path_split(search_path, &path); PKG_FOREACH_LIST_ENTRY(pkg_dir_list.head, n)
PKG_FOREACH_LIST_ENTRY(path.head, n)
{ {
pkg_path_t *pkg_path = n->data; pkg_path_t *pkg_path = n->data;
pkg_scan_dir(pkg_path->path, func); 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 #ifdef _WIN32
@ -445,16 +457,22 @@ pkg_find_in_registry_key(HKEY hkey, const char *name, unsigned int flags)
pkg_t * pkg_t *
pkg_find(const char *name, unsigned int flags) pkg_find(const char *name, unsigned int flags)
{ {
pkg_list_t path = PKG_LIST_INITIALIZER;
const char *env_path;
pkg_t *pkg = NULL; pkg_t *pkg = NULL;
pkg_node_t *n;
FILE *f; FILE *f;
/* name might actually be a filename. */ /* name might actually be a filename. */
if (str_has_suffix(name, PKG_CONFIG_EXT)) if (str_has_suffix(name, PKG_CONFIG_EXT))
{ {
if ((f = fopen(name, "r")) != NULL) 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 */ /* check cache */
@ -467,41 +485,15 @@ pkg_find(const char *name, unsigned int flags)
} }
} }
/* PKG_CONFIG_PATH has to take precedence */ pkg_dir_list_build(flags);
env_path = getenv("PKG_CONFIG_PATH");
if (env_path) 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 = pkg_try_specific_path(pkg_path->path, name, flags);
if (pkg != NULL)
PKG_FOREACH_LIST_ENTRY(path.head, n) goto out;
{
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;
}
} }
#ifdef _WIN32 #ifdef _WIN32
@ -513,7 +505,6 @@ pkg_find(const char *name, unsigned int flags)
out: out:
pkg_cache_add(pkg); pkg_cache_add(pkg);
path_free(&path);
return pkg; return pkg;
} }

1
pkg.h
View File

@ -133,7 +133,6 @@ pkg_t *pkg_ref(pkg_t *pkg);
void pkg_unref(pkg_t *pkg); void pkg_unref(pkg_t *pkg);
void pkg_free(pkg_t *pkg); void pkg_free(pkg_t *pkg);
pkg_t *pkg_find(const char *name, unsigned int flags); 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); 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_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); unsigned int pkg_verify_graph(pkg_t *root, int depth, unsigned int flags);

View File

@ -94,6 +94,8 @@ run_test "PKG_CONFIG_PATH='${selfdir}/lib1' ${1} --libs circular-1" \
'-lcircular-1 -lcircular-2 -lcircular-3' '-lcircular-1 -lcircular-2 -lcircular-3'
run_test "PKG_CONFIG_PATH='${selfdir}/lib1' ${1} --libs circular-3" \ run_test "PKG_CONFIG_PATH='${selfdir}/lib1' ${1} --libs circular-3" \
'-lcircular-3 -lcircular-1 -lcircular-2' '-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" \ run_test "PKG_CONFIG_PATH='${selfdir}/lib1' ${1} --libs static-archive-libs" \
'/libfoo.a -pthread' '/libfoo.a -pthread'