Merge branch 'sysroot-map' into 'master'

Add PKG_CONFIG_SYSROOT_MAP support

See merge request pkg-config/pkg-config!7
This commit is contained in:
Xavier Claessens 2021-01-25 03:30:14 +00:00
commit 75cee688ad
6 changed files with 99 additions and 33 deletions

View file

@ -36,3 +36,18 @@ run_test --cflags special-flags
RESULT="-L$root/sysroot/foo -L$root/sysroot/bar -framework Foo -lsimple -framework Bar -Wl,-framework -Wl,Baz"
run_test --libs special-flags
# packages from different locations gets the same /sysroot prefix
export PKG_CONFIG_PATH="${srcdir}/sub"
RESULT="-I/sysroot/sub/include -I/sysroot/public-dep/include"
run_test --cflags public-dep sub1
# Map sub1 location to another sysroot
if [ "$native_win32" = yes ]; then
export PKG_CONFIG_SYSROOT_MAP="${srcdir}/sub;/subsysroot"
else
export PKG_CONFIG_SYSROOT_MAP="${srcdir}/sub:/subsysroot"
fi
RESULT="-I/subsysroot/sub/include -I/sysroot/public-dep/include"
run_test --cflags public-dep sub1

7
main.c
View file

@ -490,6 +490,7 @@ main (int argc, char **argv)
GList *packages = NULL;
char *search_path;
char *pcbuilddir;
char *pcsysrootmap;
gboolean need_newline;
FILE *log = NULL;
GError *error = NULL;
@ -547,6 +548,12 @@ main (int argc, char **argv)
define_global_variable ("pc_sysrootdir", "/");
}
pcsysrootmap = getenv ("PKG_CONFIG_SYSROOT_MAP");
if (pcsysrootmap)
{
add_sysroot_map (pcsysrootmap, G_SEARCHPATH_SEPARATOR_S);
}
pcbuilddir = getenv ("PKG_CONFIG_TOP_BUILD_DIR");
if (pcbuilddir)
{

View file

@ -640,6 +640,8 @@ static void _do_parse_libs (Package *pkg, int argc, char **argv)
p = arg;
g_free(tmp);
flag->pkg = pkg;
if (p[0] == '-' &&
p[1] == 'l' &&
/* -lib: is used by the C# compiler for libs; it's not an -l
@ -842,6 +844,8 @@ parse_cflags (Package *pkg, const char *str, const char *path)
char *p = arg;
g_free(tmp);
flag->pkg = pkg;
if (p[0] == '-' &&
p[1] == 'I')
{

View file

@ -368,6 +368,13 @@ to determine CFLAGS and LDFLAGS. -I and -L are modified to point to
the new system root. this means that a -I/usr/include/libfoo will
become -I/var/target/usr/include/libfoo with a PKG_CONFIG_SYSROOT_DIR
equal to /var/target (same rule apply to -L)
.I "PKG_CONFIG_SYSROOT_MAP"
Similar to PKG_CONFIG_SYSROOT_DIR but allow mapping location where the pc file
was found to a sysroot. A colon-separated (on Windows, semicolon-separated) list
that gets splitted in pairs where the first path is the location of package file
(usually part of PKG_CONFIG_LIBDIR or PKG_CONFIG_PATH) and the second path is
the sysroot. For example:
PKG_CONFIG_SYSROOT_MAP=/sysroot/usr/lib/pkgconfig:/sysroot:/sysroot2/usr/lib/pkgconfig:/sysroot2
.TP
.I "PKG_CONFIG_LIBDIR"
Replaces the default

97
pkg.c
View file

@ -45,6 +45,7 @@ static void verify_package (Package *pkg);
static GHashTable *packages = NULL;
static GHashTable *globals = NULL;
static GList *search_dirs = NULL;
static GHashTable *sysroot_map = NULL;
gboolean disable_uninstalled = FALSE;
gboolean ignore_requires = FALSE;
@ -78,6 +79,36 @@ add_search_dirs (const char *path, const char *separator)
g_strfreev (search_dirs);
}
void
add_sysroot_map (const char *path, const char *separator)
{
char **strv;
char **iter;
if (sysroot_map == NULL)
sysroot_map = g_hash_table_new (g_str_hash, g_str_equal);
strv = g_strsplit (path, separator, -1);
iter = strv;
while (*iter)
{
char *pcfiledir = *iter++;
char *sysroot = *iter++;
if (sysroot == NULL) {
verbose_error ("PKG_CONFIG_SYSROOT_MAP must contain even number of paths.");
exit (1);
}
debug_spew ("Adding sysroot map '%s' -> '%s' from PKG_CONFIG_SYSROOT_MAP\n",
pcfiledir, sysroot);
g_hash_table_insert(sysroot_map, pcfiledir, sysroot);
}
g_free (strv);
}
#ifdef G_OS_WIN32
/* Guard against .pc file being installed with UPPER CASE name */
# define FOLD(x) tolower(x)
@ -393,47 +424,33 @@ get_package_quiet (const char *name)
return internal_get_package (name, FALSE);
}
/* Strip consecutive duplicate arguments in the flag list. */
static GList *
flag_list_strip_duplicates (GList *list)
{
GList *tmp;
/* Start at the 2nd element of the list so we don't have to check for an
* existing previous element. */
for (tmp = g_list_next (list); tmp != NULL; tmp = g_list_next (tmp))
{
Flag *cur = tmp->data;
Flag *prev = tmp->prev->data;
if (cur->type == prev->type && g_strcmp0 (cur->arg, prev->arg) == 0)
{
/* Remove the duplicate flag from the list and move to the last
* element to prepare for the next iteration. */
GList *dup = tmp;
debug_spew (" removing duplicate \"%s\"\n", cur->arg);
tmp = g_list_previous (tmp);
list = g_list_remove_link (list, dup);
}
}
return list;
}
static char *
flag_list_to_string (GList *list)
{
GList *tmp;
GString *str = g_string_new ("");
char *retval;
gsize prev_arg_len = 0;
FlagType prev_type = 0;
if (sysroot_map == NULL)
sysroot_map = g_hash_table_new (g_str_hash, g_str_equal);
tmp = list;
while (tmp != NULL) {
Flag *flag = tmp->data;
char *tmpstr = flag->arg;
char *sysroot;
char *cur_arg;
char *prev_arg;
gsize cur_arg_len;
gsize old_len = str->len;
if (pcsysrootdir != NULL && flag->type & (CFLAGS_I | LIBS_L)) {
sysroot = g_hash_table_lookup (sysroot_map, flag->pkg->pcfiledir);
if (sysroot == NULL)
sysroot = pcsysrootdir;
if (sysroot != NULL && flag->type & (CFLAGS_I | LIBS_L)) {
/* Handle non-I Cflags like -isystem */
if (flag->type & CFLAGS_I && strncmp (tmpstr, "-I", 2) != 0) {
char *space = strchr (tmpstr, ' ');
@ -441,18 +458,33 @@ flag_list_to_string (GList *list)
/* Ensure this has a separate arg */
g_assert (space != NULL && space[1] != '\0');
g_string_append_len (str, tmpstr, space - tmpstr + 1);
g_string_append (str, pcsysrootdir);
g_string_append (str, sysroot);
g_string_append (str, space + 1);
} else {
g_string_append_c (str, '-');
g_string_append_c (str, tmpstr[1]);
g_string_append (str, pcsysrootdir);
g_string_append (str, sysroot);
g_string_append (str, tmpstr+2);
}
} else {
g_string_append (str, tmpstr);
}
g_string_append_c (str, ' ');
/* truncate the string if the arg we added is identical to the previous one */
cur_arg = str->str + old_len;
cur_arg_len = str->len - old_len;
prev_arg = cur_arg - prev_arg_len;
if (prev_type == flag->type && prev_arg_len == cur_arg_len && strncmp(cur_arg, prev_arg, cur_arg_len) == 0)
{
g_string_truncate (str, old_len);
}
else
{
prev_type = flag->type;
prev_arg_len = cur_arg_len;
}
tmp = g_list_next (tmp);
}
@ -918,7 +950,6 @@ get_multi_merged (GList *pkgs, FlagType type, gboolean in_path_order,
char *retval;
list = fill_list (pkgs, type, in_path_order, include_private);
list = flag_list_strip_duplicates (list);
retval = flag_list_to_string (list);
g_list_free (list);

2
pkg.h
View file

@ -53,6 +53,7 @@ struct Flag_
{
FlagType type;
char *arg;
Package *pkg;
};
struct RequiredVersion_
@ -98,6 +99,7 @@ char * packages_get_var (GList *pkgs,
void add_search_dir (const char *path);
void add_search_dirs (const char *path, const char *separator);
void add_sysroot_map (const char *path, const char *separator);
void package_init (gboolean want_list);
int compare_versions (const char * a, const char *b);
gboolean version_test (ComparisonType comparison,