forked from ariadne/pkgconf
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.)feature/tap-sh
parent
48c6e4c383
commit
1554c3577f
117
pkg.c
117
pkg.c
|
@ -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,15 +485,9 @@ 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_node_t *n;
|
|
||||||
|
|
||||||
path_split(env_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;
|
||||||
|
|
||||||
|
@ -484,26 +496,6 @@ pkg_find(const char *name, unsigned int flags)
|
||||||
goto out;
|
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
|
||||||
/* support getting PKG_CONFIG_PATH from registry */
|
/* support getting PKG_CONFIG_PATH from registry */
|
||||||
pkg = pkg_find_in_registry_key(HKEY_CURRENT_USER, name, flags);
|
pkg = pkg_find_in_registry_key(HKEY_CURRENT_USER, name, flags);
|
||||||
|
@ -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
1
pkg.h
|
@ -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);
|
||||||
|
|
|
@ -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'
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue