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_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;
}

1
pkg.h
View File

@ -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);

View File

@ -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'