From 7237b811e762a3b68a51fa141fc56e11e57f08dc Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Fri, 20 Jan 2017 00:58:48 -0600 Subject: [PATCH] add support for making paths relocatable (closes #103) --- Makefile.am | 1 + libpkgconf/libpkgconf.h | 1 + libpkgconf/pkg.c | 52 +++++++++++++++++++++- main.c | 23 ++++++++++ tests/basic.sh | 11 ++++- tests/lib-relocatable/lib/pkgconfig/foo.pc | 11 +++++ 6 files changed, 97 insertions(+), 2 deletions(-) create mode 100644 tests/lib-relocatable/lib/pkgconfig/foo.pc diff --git a/Makefile.am b/Makefile.am index ed433db..ae5468c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -14,6 +14,7 @@ bin_PROGRAMS = pkgconf lib_LTLIBRARIES = libpkgconf.la EXTRA_DIST = pkg.m4 \ + tests/lib-relocatable/lib/pkgconfig/foo.pc \ tests/lib1/argv-parse-2.pc \ tests/lib1/dos-lineendings.pc \ tests/lib1/paren-quoting.pc \ diff --git a/libpkgconf/libpkgconf.h b/libpkgconf/libpkgconf.h index 22dfb0f..a32eb0b 100644 --- a/libpkgconf/libpkgconf.h +++ b/libpkgconf/libpkgconf.h @@ -184,6 +184,7 @@ void pkgconf_client_set_prefix_varname(pkgconf_client_t *client, const char *pre #define PKGCONF_PKG_PKGF_SKIP_ERRORS 0x080 #define PKGCONF_PKG_PKGF_ITER_PKG_IS_PRIVATE 0x100 #define PKGCONF_PKG_PKGF_SKIP_PROVIDES 0x200 +#define PKGCONF_PKG_PKGF_REDEFINE_PREFIX 0x400 #define PKGCONF_PKG_ERRF_OK 0x0 #define PKGCONF_PKG_ERRF_PACKAGE_NOT_FOUND 0x1 diff --git a/libpkgconf/pkg.c b/libpkgconf/pkg.c index d40888c..c2fa160 100644 --- a/libpkgconf/pkg.c +++ b/libpkgconf/pkg.c @@ -181,6 +181,44 @@ pkgconf_pkg_parser_keyword_set(const pkgconf_client_t *client, pkgconf_pkg_t *pk return true; } +static const char * +determine_prefix(const pkgconf_pkg_t *pkg) +{ + static char buf[PKGCONF_BUFSIZE]; + char *pathiter; + + pkgconf_strlcpy(buf, pkg->filename, sizeof buf); + pkgconf_path_relocate(buf, sizeof buf); + + pathiter = strrchr(buf, PKG_DIR_SEP_S); + if (pathiter == NULL) + pathiter = strrchr(buf, '/'); + if (pathiter != NULL) + pathiter[0] = '\0'; + + pathiter = strrchr(buf, PKG_DIR_SEP_S); + if (pathiter == NULL) + pathiter = strrchr(buf, '/'); + if (pathiter == NULL) + return NULL; + + /* parent dir is not pkgconfig, can't relocate then */ + if (strcmp(pathiter + 1, "pkgconfig")) + return NULL; + + /* okay, work backwards and do it again. */ + pathiter[0] = '\0'; + pathiter = strrchr(buf, PKG_DIR_SEP_S); + if (pathiter == NULL) + pathiter = strrchr(buf, '/'); + if (pathiter == NULL) + return NULL; + + pathiter[0] = '\0'; + + return buf; +} + /* * !doc * @@ -249,7 +287,19 @@ pkgconf_pkg_new_from_file(const pkgconf_client_t *client, const char *filename, pkgconf_pkg_parser_keyword_set(client, pkg, key, value); break; case '=': - pkgconf_tuple_add(client, &pkg->vars, key, value, true); + if (strcmp(key, client->prefix_varname) || !(client->flags & PKGCONF_PKG_PKGF_REDEFINE_PREFIX)) + pkgconf_tuple_add(client, &pkg->vars, key, value, true); + else + { + const char *relvalue = determine_prefix(pkg); + if (relvalue != NULL) + { + pkgconf_tuple_add(client, &pkg->vars, "orig_prefix", value, true); + pkgconf_tuple_add(client, &pkg->vars, key, relvalue, false); + } + else + pkgconf_tuple_add(client, &pkg->vars, key, value, true); + } break; default: break; diff --git a/main.c b/main.c index 9415576..210fafe 100644 --- a/main.c +++ b/main.c @@ -52,6 +52,7 @@ #define PKG_NO_PROVIDES (((uint64_t) 1) << 32) #define PKG_PURE (((uint64_t) 1) << 33) #define PKG_PATH (((uint64_t) 1) << 34) +#define PKG_DEFINE_PREFIX (((uint64_t) 1) << 35) static pkgconf_client_t pkg_client; @@ -569,8 +570,11 @@ usage(void) printf(" walking the dependency graph\n"); printf(" --log-file=filename write an audit log to a specified file\n"); printf(" --with-path=path adds a directory to the search path\n"); + printf(" --define-prefix override the prefix variable with one that is guessed based on\n"); + printf(" the location of the .pc file\n"); printf(" --prefix-variable=varname sets the name of the variable that pkgconf considers\n"); printf(" to be the package prefix\n"); + printf(" --relocate=path relocates a path and exits (mostly for testsuite)\n"); printf("\nchecking specific pkg-config database entries:\n\n"); @@ -614,6 +618,17 @@ usage(void) printf("\nreport bugs to <%s>.\n", PACKAGE_BUGREPORT); } +static void +relocate_path(const char *path) +{ + char buf[PKGCONF_BUFSIZE]; + + pkgconf_strlcpy(buf, path, sizeof buf); + pkgconf_path_relocate(buf, sizeof buf); + + printf("%s\n", buf); +} + int main(int argc, char *argv[]) { @@ -678,6 +693,8 @@ main(int argc, char *argv[]) { "path", no_argument, &want_flags, PKG_PATH }, { "with-path", required_argument, NULL, 42 }, { "prefix-variable", required_argument, NULL, 43 }, + { "define-prefix", no_argument, &want_flags, PKG_DEFINE_PREFIX }, + { "relocate", required_argument, NULL, 45 }, { NULL, 0, NULL, 0 } }; @@ -717,6 +734,9 @@ main(int argc, char *argv[]) case 43: pkgconf_client_set_prefix_varname(&pkg_client, pkg_optarg); break; + case 45: + relocate_path(pkg_optarg); + return EXIT_SUCCESS; case '?': case ':': return EXIT_FAILURE; @@ -787,6 +807,9 @@ main(int argc, char *argv[]) if ((want_flags & PKG_NO_CACHE) == PKG_NO_CACHE) want_client_flags |= PKGCONF_PKG_PKGF_NO_CACHE; + if ((want_flags & PKG_DEFINE_PREFIX) == PKG_DEFINE_PREFIX) + want_client_flags |= PKGCONF_PKG_PKGF_REDEFINE_PREFIX; + if ((want_flags & PKG_NO_UNINSTALLED) == PKG_NO_UNINSTALLED || getenv("PKG_CONFIG_DISABLE_UNINSTALLED") != NULL) want_client_flags |= PKGCONF_PKG_PKGF_NO_UNINSTALLED; diff --git a/tests/basic.sh b/tests/basic.sh index 294246e..1d6261a 100755 --- a/tests/basic.sh +++ b/tests/basic.sh @@ -33,7 +33,8 @@ tests_init \ nolibs \ nocflags \ arbitary_path \ - with_path + with_path \ + relocatable noargs_body() { @@ -289,3 +290,11 @@ arbitary_path_body() -o inline:"-L/test/lib -lfoo \n" \ pkgconf --libs foo.pc } + +relocatable_body() +{ + basedir=$(pkgconf --relocate ${selfdir}) + atf_check \ + -o inline:"${basedir}/lib-relocatable\n" \ + pkgconf --define-prefix --variable=prefix ${basedir}/lib-relocatable/lib/pkgconfig/foo.pc +} diff --git a/tests/lib-relocatable/lib/pkgconfig/foo.pc b/tests/lib-relocatable/lib/pkgconfig/foo.pc new file mode 100644 index 0000000..f154eb7 --- /dev/null +++ b/tests/lib-relocatable/lib/pkgconfig/foo.pc @@ -0,0 +1,11 @@ +prefix=/test +exec_prefix=${prefix} +libdir=${prefix}/lib +includedir=${prefix}/include + +Name: foo +Description: A testing pkg-config file +Version: 1.2.3 +Libs: -L${libdir} -lfoo +Cflags: -fPIC -I${includedir}/foo +Cflags.private: -DFOO_STATIC