fragments: handle sysroot dir munging directly in a smarter way

Previously we just let the tuple system handle it, but pkg-config modules which do not define
variables were able to get by the checks.  While here, check to ensure we do not duplicate the
sysroot dir twice if it is already defined in the pkg-config module file.

Downstream bug: https://bugs.busybox.net/show_bug.cgi?id=5750
feature/tap-sh
William Pitcock 2014-07-09 01:23:51 -05:00
parent 84050f8fda
commit 12ff14f856
6 changed files with 52 additions and 23 deletions

View File

@ -16,8 +16,29 @@
#include "pkg.h" #include "pkg.h"
#include "bsdstubs.h" #include "bsdstubs.h"
static inline char *
pkg_fragment_copy_munged(const char *source, unsigned int flags)
{
char mungebuf[PKG_BUFSIZE];
char *sysroot_dir;
if (!(flags & PKGF_MUNGE_SYSROOT_PREFIX))
return strdup(source);
sysroot_dir = pkg_tuple_find_global("pc_sysrootdir");
if (*source != '/' ||
(sysroot_dir != NULL && !strncmp(sysroot_dir, source, strlen(sysroot_dir))))
return strdup(source);
strlcpy(mungebuf, sysroot_dir, sizeof mungebuf);
strlcat(mungebuf, source, sizeof mungebuf);
return strdup(mungebuf);
}
void void
pkg_fragment_add(pkg_list_t *list, const char *string) pkg_fragment_add(pkg_list_t *list, const char *string, unsigned int flags)
{ {
pkg_fragment_t *frag; pkg_fragment_t *frag;
@ -26,7 +47,7 @@ pkg_fragment_add(pkg_list_t *list, const char *string)
frag = calloc(sizeof(pkg_fragment_t), 1); frag = calloc(sizeof(pkg_fragment_t), 1);
frag->type = *(string + 1); frag->type = *(string + 1);
frag->data = strdup(string + 2); frag->data = pkg_fragment_copy_munged(string + 2, flags);
} }
else else
{ {
@ -156,7 +177,7 @@ pkg_fragment_free(pkg_list_t *list)
} }
void void
pkg_fragment_parse(pkg_list_t *list, pkg_list_t *vars, const char *value) pkg_fragment_parse(pkg_list_t *list, pkg_list_t *vars, const char *value, unsigned int flags)
{ {
int i, argc; int i, argc;
char **argv; char **argv;
@ -165,7 +186,7 @@ pkg_fragment_parse(pkg_list_t *list, pkg_list_t *vars, const char *value)
pkg_argv_split(repstr, &argc, &argv); pkg_argv_split(repstr, &argc, &argv);
for (i = 0; i < argc; i++) for (i = 0; i < argc; i++)
pkg_fragment_add(list, argv[i]); pkg_fragment_add(list, argv[i], flags);
pkg_argv_free(argv); pkg_argv_free(argv);
free(repstr); free(repstr);

11
main.c
View File

@ -290,11 +290,20 @@ print_variable(pkg_t *pkg, void *data, unsigned int flags)
{ {
if (*(req->buf) == '\0') if (*(req->buf) == '\0')
{ {
strlcpy(req->buf, var, sizeof(req->buf)); memset(req->buf, 0, sizeof(req->buf));
if (*var == '/' && (flags & PKGF_MUNGE_SYSROOT_PREFIX))
strlcat(req->buf, sysroot_dir, sizeof(req->buf));
strlcat(req->buf, var, sizeof(req->buf));
return; return;
} }
strlcat(req->buf, " ", sizeof(req->buf)); strlcat(req->buf, " ", sizeof(req->buf));
if (*var == '/' && (flags & PKGF_MUNGE_SYSROOT_PREFIX))
strlcat(req->buf, sysroot_dir, sizeof(req->buf));
strlcat(req->buf, var, sizeof(req->buf)); strlcat(req->buf, var, sizeof(req->buf));
} }
} }

21
pkg.c
View File

@ -247,13 +247,13 @@ pkg_new_from_file(const char *filename, FILE *f, unsigned int flags)
else if (!strcmp(key, "Version")) else if (!strcmp(key, "Version"))
pkg->version = pkg_tuple_parse(&pkg->vars, value); pkg->version = pkg_tuple_parse(&pkg->vars, value);
else if (!strcasecmp(key, "CFLAGS")) else if (!strcasecmp(key, "CFLAGS"))
pkg_fragment_parse(&pkg->cflags, &pkg->vars, value); pkg_fragment_parse(&pkg->cflags, &pkg->vars, value, flags);
else if (!strcasecmp(key, "CFLAGS.private")) else if (!strcasecmp(key, "CFLAGS.private"))
pkg_fragment_parse(&pkg->cflags_private, &pkg->vars, value); pkg_fragment_parse(&pkg->cflags_private, &pkg->vars, value, flags);
else if (!strcasecmp(key, "LIBS")) else if (!strcasecmp(key, "LIBS"))
pkg_fragment_parse(&pkg->libs, &pkg->vars, value); pkg_fragment_parse(&pkg->libs, &pkg->vars, value, flags);
else if (!strcasecmp(key, "LIBS.private")) else if (!strcasecmp(key, "LIBS.private"))
pkg_fragment_parse(&pkg->libs_private, &pkg->vars, value); pkg_fragment_parse(&pkg->libs_private, &pkg->vars, value, flags);
else if (!strcmp(key, "Requires")) else if (!strcmp(key, "Requires"))
pkg_dependency_parse(pkg, &pkg->requires, value); pkg_dependency_parse(pkg, &pkg->requires, value);
else if (!strcmp(key, "Requires.private")) else if (!strcmp(key, "Requires.private"))
@ -262,18 +262,7 @@ pkg_new_from_file(const char *filename, FILE *f, unsigned int flags)
pkg_dependency_parse(pkg, &pkg->conflicts, value); pkg_dependency_parse(pkg, &pkg->conflicts, value);
break; break;
case '=': case '=':
if (!(flags & PKGF_MUNGE_SYSROOT_PREFIX) || strcasecmp(key, "prefix")) pkg_tuple_add(&pkg->vars, key, value);
pkg_tuple_add(&pkg->vars, key, value);
else
{
char mungebuf[PKG_BUFSIZE];
char *sysroot_dir = pkg_tuple_find_global("pc_sysrootdir");
strlcpy(mungebuf, sysroot_dir, sizeof mungebuf);
strlcat(mungebuf, value, sizeof mungebuf);
pkg_tuple_add(&pkg->vars, key, mungebuf);
}
break; break;
default: default:
break; break;

4
pkg.h
View File

@ -157,8 +157,8 @@ int pkg_argv_split(const char *src, int *argc, char ***argv);
void pkg_argv_free(char **argv); void pkg_argv_free(char **argv);
/* fragment.c */ /* fragment.c */
void pkg_fragment_parse(pkg_list_t *list, pkg_list_t *vars, const char *value); void pkg_fragment_parse(pkg_list_t *list, pkg_list_t *vars, const char *value, unsigned int flags);
void pkg_fragment_add(pkg_list_t *list, const char *string); void pkg_fragment_add(pkg_list_t *list, const char *string, unsigned int flags);
void pkg_fragment_copy(pkg_list_t *list, pkg_fragment_t *base, unsigned int flags); void pkg_fragment_copy(pkg_list_t *list, pkg_fragment_t *base, unsigned int flags);
void pkg_fragment_delete(pkg_list_t *list, pkg_fragment_t *node); void pkg_fragment_delete(pkg_list_t *list, pkg_fragment_t *node);
void pkg_fragment_free(pkg_list_t *list); void pkg_fragment_free(pkg_list_t *list);

View File

@ -0,0 +1,5 @@
Name: sysroot-dir
Description: Package for testing whether sysroot dirs are repeated or not
Version: 1
CFlags: -I/sysroot/include
Libs: -L/sysroot/lib -lfoo

View File

@ -244,6 +244,11 @@ run_test "PKG_CONFIG_PATH='${selfdir}/lib1' ${1} --variable=foo case-sensitivity
run_test "PKG_CONFIG_PATH='${selfdir}/lib1' ${1} --variable=Foo case-sensitivity" \ run_test "PKG_CONFIG_PATH='${selfdir}/lib1' ${1} --variable=Foo case-sensitivity" \
"4" "4"
run_test "PKG_CONFIG_PATH='${selfdir}/lib1' PKG_CONFIG_SYSROOT_DIR='/sysroot' ${1} --libs sysroot-dir" \
'-L/sysroot/lib -lfoo'
run_test "PKG_CONFIG_PATH='${selfdir}/lib1' PKG_CONFIG_SYSROOT_DIR='/sysroot2' ${1} --libs sysroot-dir" \
'-L/sysroot2/sysroot/lib -lfoo'
# 10) tests for internal getopt implementation with options at the end # 10) tests for internal getopt implementation with options at the end
if [ "x@STRICT_MODE@" = "xno" ]; then if [ "x@STRICT_MODE@" = "xno" ]; then
run_test "PKG_CONFIG_PATH='${selfdir}/lib1' ${1} foo --libs" \ run_test "PKG_CONFIG_PATH='${selfdir}/lib1' ${1} foo --libs" \