2005-07-14 13:05:14 +00:00
|
|
|
/*
|
|
|
|
|
* Copyright (C) 2001, 2002 Red Hat Inc.
|
|
|
|
|
*
|
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
|
* modify it under the terms of the GNU General Public License as
|
|
|
|
|
* published by the Free Software Foundation; either version 2 of the
|
|
|
|
|
* License, or (at your option) any later version.
|
|
|
|
|
*
|
|
|
|
|
* This program is distributed in the hope that it will be useful, but
|
|
|
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
|
* General Public License for more details.
|
|
|
|
|
*
|
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
|
|
|
|
* 02111-1307, USA.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
2005-07-14 13:04:01 +00:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
|
#include "config.h"
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#include "pkg.h"
|
|
|
|
|
#include "parse.h"
|
2012-10-10 05:30:09 -07:00
|
|
|
#include "rpmvercmp.h"
|
2005-07-14 13:04:01 +00:00
|
|
|
|
2009-03-30 21:00:14 +02:00
|
|
|
#ifdef HAVE_MALLOC_H
|
|
|
|
|
# include <malloc.h>
|
|
|
|
|
#endif
|
|
|
|
|
|
2005-07-14 13:04:22 +00:00
|
|
|
#include <sys/types.h>
|
2005-07-14 13:04:01 +00:00
|
|
|
#include <string.h>
|
|
|
|
|
#include <errno.h>
|
|
|
|
|
#include <stdio.h>
|
2001-09-30 Tor Lillqvist <tml@iki.fi>
Author: tml
Date: 2001-09-29 21:05:25 GMT
2001-09-30 Tor Lillqvist <tml@iki.fi>
Changes for "pure" Win32 (without Cygwin or similar)
support. The most important differences compared to pkg-config
on Unix are:
We don't use hardcoded PKGLIBDIR paths but deduce the
installation prefix at runtime.
Use the normal GLib DLL, not a private copy. Yes, this does
introduce a circular dependency, but that can be worked around.
* README.win32: New file.
* configure.in: Check for Win32. If so, define USE_INSTALLED_GLIB,
and don't configure in the included glib-1.2.8. Set GLIB_CFLAGS
and GLIB_LIBS assuming that GLib is installed in the same location
pkgconfig will be. Check for dirent.h, unistd.h and sys/wait.h
headers.
* Makefile.am: If USE_INSTALLED_GLIB, use the GLIB_* values set
above, and don't make in the glib-1.2.8 subdir.
* autogen.sh: Use perl -p -i.bak, works better on Win32 (and Cygwin).
* *.c: Conditionalize inclusions of unistd.h and sys/wait.h.
* findme.c: Define X_OK on Win32 if necessary.
* parse.c
* popthelp.c: Minor Win32 portability ifdefs.
* parse.c: No need to include <windows.h>.
* pkg.c: Don't hardcode PKGLIBDIR, but use
g_win32_get_package_installation_directory() to deduce it.
(scan_dir): Make a temp copy of dirname with potential superfluous
trailing slash removed. The Win32 opendir implementation doesn't
always like those.
* pkg.h: If USE_INSTALLED_GLIB, include <glib.h> instead of
partial-glib.h.
* popt.c (execCommand): Don't compile on Win32.
* poptconfig.c (configLine): Don't bother with the "exec" stuff on
Win32, too complex to port, at least for now.
(poptReadDefaultConfig) Don't bother compiling on Win32, this
function isn't even called.
2005-07-14 13:04:29 +00:00
|
|
|
#ifdef HAVE_UNISTD_H
|
2005-07-14 13:04:01 +00:00
|
|
|
#include <unistd.h>
|
2001-09-30 Tor Lillqvist <tml@iki.fi>
Author: tml
Date: 2001-09-29 21:05:25 GMT
2001-09-30 Tor Lillqvist <tml@iki.fi>
Changes for "pure" Win32 (without Cygwin or similar)
support. The most important differences compared to pkg-config
on Unix are:
We don't use hardcoded PKGLIBDIR paths but deduce the
installation prefix at runtime.
Use the normal GLib DLL, not a private copy. Yes, this does
introduce a circular dependency, but that can be worked around.
* README.win32: New file.
* configure.in: Check for Win32. If so, define USE_INSTALLED_GLIB,
and don't configure in the included glib-1.2.8. Set GLIB_CFLAGS
and GLIB_LIBS assuming that GLib is installed in the same location
pkgconfig will be. Check for dirent.h, unistd.h and sys/wait.h
headers.
* Makefile.am: If USE_INSTALLED_GLIB, use the GLIB_* values set
above, and don't make in the glib-1.2.8 subdir.
* autogen.sh: Use perl -p -i.bak, works better on Win32 (and Cygwin).
* *.c: Conditionalize inclusions of unistd.h and sys/wait.h.
* findme.c: Define X_OK on Win32 if necessary.
* parse.c
* popthelp.c: Minor Win32 portability ifdefs.
* parse.c: No need to include <windows.h>.
* pkg.c: Don't hardcode PKGLIBDIR, but use
g_win32_get_package_installation_directory() to deduce it.
(scan_dir): Make a temp copy of dirname with potential superfluous
trailing slash removed. The Win32 opendir implementation doesn't
always like those.
* pkg.h: If USE_INSTALLED_GLIB, include <glib.h> instead of
partial-glib.h.
* popt.c (execCommand): Don't compile on Win32.
* poptconfig.c (configLine): Don't bother with the "exec" stuff on
Win32, too complex to port, at least for now.
(poptReadDefaultConfig) Don't bother compiling on Win32, this
function isn't even called.
2005-07-14 13:04:29 +00:00
|
|
|
#endif
|
2005-07-14 13:04:01 +00:00
|
|
|
#include <stdlib.h>
|
2005-07-14 13:04:37 +00:00
|
|
|
#include <ctype.h>
|
2005-07-14 13:04:01 +00:00
|
|
|
|
|
|
|
|
static void verify_package (Package *pkg);
|
|
|
|
|
|
|
|
|
|
static GHashTable *packages = NULL;
|
|
|
|
|
static GHashTable *locations = NULL;
|
2005-07-14 13:04:45 +00:00
|
|
|
static GHashTable *path_positions = NULL;
|
2005-07-14 13:04:01 +00:00
|
|
|
static GHashTable *globals = NULL;
|
2012-11-29 05:40:40 -08:00
|
|
|
static GList *search_dirs = NULL;
|
2005-07-14 13:04:45 +00:00
|
|
|
static int scanned_dir_count = 0;
|
2005-07-14 13:04:01 +00:00
|
|
|
|
|
|
|
|
gboolean disable_uninstalled = FALSE;
|
2005-07-14 13:06:19 +00:00
|
|
|
gboolean ignore_requires = FALSE;
|
2009-03-30 20:40:53 +02:00
|
|
|
gboolean ignore_requires_private = TRUE;
|
2005-07-14 13:07:18 +00:00
|
|
|
gboolean ignore_private_libs = TRUE;
|
2005-07-14 13:04:01 +00:00
|
|
|
|
|
|
|
|
void
|
|
|
|
|
add_search_dir (const char *path)
|
|
|
|
|
{
|
2012-11-29 05:40:40 -08:00
|
|
|
search_dirs = g_list_append (search_dirs, g_strdup (path));
|
2005-07-14 13:04:01 +00:00
|
|
|
}
|
|
|
|
|
|
2005-07-14 13:06:23 +00:00
|
|
|
void
|
|
|
|
|
add_search_dirs (const char *path, const char *separator)
|
|
|
|
|
{
|
|
|
|
|
char **search_dirs;
|
|
|
|
|
char **iter;
|
|
|
|
|
|
|
|
|
|
search_dirs = g_strsplit (path, separator, -1);
|
|
|
|
|
|
|
|
|
|
iter = search_dirs;
|
|
|
|
|
while (*iter)
|
|
|
|
|
{
|
|
|
|
|
debug_spew ("Adding directory '%s' from PKG_CONFIG_PATH\n",
|
|
|
|
|
*iter);
|
|
|
|
|
add_search_dir (*iter);
|
|
|
|
|
|
|
|
|
|
++iter;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
g_strfreev (search_dirs);
|
|
|
|
|
}
|
|
|
|
|
|
2005-07-14 13:04:37 +00:00
|
|
|
#ifdef G_OS_WIN32
|
|
|
|
|
/* Guard against .pc file being installed with UPPER CASE name */
|
|
|
|
|
# define FOLD(x) tolower(x)
|
|
|
|
|
# define FOLDCMP(a, b) g_ascii_strcasecmp (a, b)
|
|
|
|
|
#else
|
|
|
|
|
# define FOLD(x) (x)
|
|
|
|
|
# define FOLDCMP(a, b) strcmp (a, b)
|
|
|
|
|
#endif
|
|
|
|
|
|
2005-07-14 13:04:01 +00:00
|
|
|
#define EXT_LEN 3
|
|
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
|
ends_in_dotpc (const char *str)
|
|
|
|
|
{
|
|
|
|
|
int len = strlen (str);
|
|
|
|
|
|
|
|
|
|
if (len > EXT_LEN &&
|
|
|
|
|
str[len - 3] == '.' &&
|
2005-07-14 13:04:37 +00:00
|
|
|
FOLD (str[len - 2]) == 'p' &&
|
|
|
|
|
FOLD (str[len - 1]) == 'c')
|
2005-07-14 13:04:01 +00:00
|
|
|
return TRUE;
|
|
|
|
|
else
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2012-10-13 09:25:34 -07:00
|
|
|
/* strlen ("-uninstalled") */
|
|
|
|
|
#define UNINSTALLED_LEN 12
|
2005-07-14 13:04:01 +00:00
|
|
|
|
2005-07-14 13:04:19 +00:00
|
|
|
gboolean
|
|
|
|
|
name_ends_in_uninstalled (const char *str)
|
2005-07-14 13:04:01 +00:00
|
|
|
{
|
|
|
|
|
int len = strlen (str);
|
|
|
|
|
|
|
|
|
|
if (len > UNINSTALLED_LEN &&
|
2012-10-13 09:25:34 -07:00
|
|
|
FOLDCMP ((str + len - UNINSTALLED_LEN), "-uninstalled") == 0)
|
2005-07-14 13:04:01 +00:00
|
|
|
return TRUE;
|
|
|
|
|
else
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Look for .pc files in the given directory and add them into
|
|
|
|
|
* locations, ignoring duplicates
|
|
|
|
|
*/
|
|
|
|
|
static void
|
2013-05-01 07:25:29 -07:00
|
|
|
scan_dir (char *dirname)
|
2005-07-14 13:04:01 +00:00
|
|
|
{
|
2015-10-15 19:17:19 +08:00
|
|
|
GDir *dir;
|
|
|
|
|
const gchar *d_name;
|
|
|
|
|
|
2005-07-14 13:04:01 +00:00
|
|
|
int dirnamelen = strlen (dirname);
|
2001-09-30 Tor Lillqvist <tml@iki.fi>
Author: tml
Date: 2001-09-29 21:05:25 GMT
2001-09-30 Tor Lillqvist <tml@iki.fi>
Changes for "pure" Win32 (without Cygwin or similar)
support. The most important differences compared to pkg-config
on Unix are:
We don't use hardcoded PKGLIBDIR paths but deduce the
installation prefix at runtime.
Use the normal GLib DLL, not a private copy. Yes, this does
introduce a circular dependency, but that can be worked around.
* README.win32: New file.
* configure.in: Check for Win32. If so, define USE_INSTALLED_GLIB,
and don't configure in the included glib-1.2.8. Set GLIB_CFLAGS
and GLIB_LIBS assuming that GLib is installed in the same location
pkgconfig will be. Check for dirent.h, unistd.h and sys/wait.h
headers.
* Makefile.am: If USE_INSTALLED_GLIB, use the GLIB_* values set
above, and don't make in the glib-1.2.8 subdir.
* autogen.sh: Use perl -p -i.bak, works better on Win32 (and Cygwin).
* *.c: Conditionalize inclusions of unistd.h and sys/wait.h.
* findme.c: Define X_OK on Win32 if necessary.
* parse.c
* popthelp.c: Minor Win32 portability ifdefs.
* parse.c: No need to include <windows.h>.
* pkg.c: Don't hardcode PKGLIBDIR, but use
g_win32_get_package_installation_directory() to deduce it.
(scan_dir): Make a temp copy of dirname with potential superfluous
trailing slash removed. The Win32 opendir implementation doesn't
always like those.
* pkg.h: If USE_INSTALLED_GLIB, include <glib.h> instead of
partial-glib.h.
* popt.c (execCommand): Don't compile on Win32.
* poptconfig.c (configLine): Don't bother with the "exec" stuff on
Win32, too complex to port, at least for now.
(poptReadDefaultConfig) Don't bother compiling on Win32, this
function isn't even called.
2005-07-14 13:04:29 +00:00
|
|
|
/* Use a copy of dirname cause Win32 opendir doesn't like
|
|
|
|
|
* superfluous trailing (back)slashes in the directory name.
|
|
|
|
|
*/
|
2005-07-14 13:05:01 +00:00
|
|
|
char *dirname_copy = g_strdup (dirname);
|
2005-07-14 13:04:01 +00:00
|
|
|
|
2001-09-30 Tor Lillqvist <tml@iki.fi>
Author: tml
Date: 2001-09-29 21:05:25 GMT
2001-09-30 Tor Lillqvist <tml@iki.fi>
Changes for "pure" Win32 (without Cygwin or similar)
support. The most important differences compared to pkg-config
on Unix are:
We don't use hardcoded PKGLIBDIR paths but deduce the
installation prefix at runtime.
Use the normal GLib DLL, not a private copy. Yes, this does
introduce a circular dependency, but that can be worked around.
* README.win32: New file.
* configure.in: Check for Win32. If so, define USE_INSTALLED_GLIB,
and don't configure in the included glib-1.2.8. Set GLIB_CFLAGS
and GLIB_LIBS assuming that GLib is installed in the same location
pkgconfig will be. Check for dirent.h, unistd.h and sys/wait.h
headers.
* Makefile.am: If USE_INSTALLED_GLIB, use the GLIB_* values set
above, and don't make in the glib-1.2.8 subdir.
* autogen.sh: Use perl -p -i.bak, works better on Win32 (and Cygwin).
* *.c: Conditionalize inclusions of unistd.h and sys/wait.h.
* findme.c: Define X_OK on Win32 if necessary.
* parse.c
* popthelp.c: Minor Win32 portability ifdefs.
* parse.c: No need to include <windows.h>.
* pkg.c: Don't hardcode PKGLIBDIR, but use
g_win32_get_package_installation_directory() to deduce it.
(scan_dir): Make a temp copy of dirname with potential superfluous
trailing slash removed. The Win32 opendir implementation doesn't
always like those.
* pkg.h: If USE_INSTALLED_GLIB, include <glib.h> instead of
partial-glib.h.
* popt.c (execCommand): Don't compile on Win32.
* poptconfig.c (configLine): Don't bother with the "exec" stuff on
Win32, too complex to port, at least for now.
(poptReadDefaultConfig) Don't bother compiling on Win32, this
function isn't even called.
2005-07-14 13:04:29 +00:00
|
|
|
if (dirnamelen > 1 && dirname[dirnamelen-1] == G_DIR_SEPARATOR)
|
|
|
|
|
{
|
|
|
|
|
dirnamelen--;
|
2005-07-14 13:05:01 +00:00
|
|
|
dirname_copy[dirnamelen] = '\0';
|
2001-09-30 Tor Lillqvist <tml@iki.fi>
Author: tml
Date: 2001-09-29 21:05:25 GMT
2001-09-30 Tor Lillqvist <tml@iki.fi>
Changes for "pure" Win32 (without Cygwin or similar)
support. The most important differences compared to pkg-config
on Unix are:
We don't use hardcoded PKGLIBDIR paths but deduce the
installation prefix at runtime.
Use the normal GLib DLL, not a private copy. Yes, this does
introduce a circular dependency, but that can be worked around.
* README.win32: New file.
* configure.in: Check for Win32. If so, define USE_INSTALLED_GLIB,
and don't configure in the included glib-1.2.8. Set GLIB_CFLAGS
and GLIB_LIBS assuming that GLib is installed in the same location
pkgconfig will be. Check for dirent.h, unistd.h and sys/wait.h
headers.
* Makefile.am: If USE_INSTALLED_GLIB, use the GLIB_* values set
above, and don't make in the glib-1.2.8 subdir.
* autogen.sh: Use perl -p -i.bak, works better on Win32 (and Cygwin).
* *.c: Conditionalize inclusions of unistd.h and sys/wait.h.
* findme.c: Define X_OK on Win32 if necessary.
* parse.c
* popthelp.c: Minor Win32 portability ifdefs.
* parse.c: No need to include <windows.h>.
* pkg.c: Don't hardcode PKGLIBDIR, but use
g_win32_get_package_installation_directory() to deduce it.
(scan_dir): Make a temp copy of dirname with potential superfluous
trailing slash removed. The Win32 opendir implementation doesn't
always like those.
* pkg.h: If USE_INSTALLED_GLIB, include <glib.h> instead of
partial-glib.h.
* popt.c (execCommand): Don't compile on Win32.
* poptconfig.c (configLine): Don't bother with the "exec" stuff on
Win32, too complex to port, at least for now.
(poptReadDefaultConfig) Don't bother compiling on Win32, this
function isn't even called.
2005-07-14 13:04:29 +00:00
|
|
|
}
|
2005-10-01 10:24:02 +00:00
|
|
|
#ifdef G_OS_WIN32
|
|
|
|
|
{
|
|
|
|
|
gchar *p;
|
|
|
|
|
/* Turn backslashes into slashes or
|
2010-06-13 20:23:45 -07:00
|
|
|
* g_shell_parse_argv() will eat them when ${prefix}
|
2005-10-01 10:24:02 +00:00
|
|
|
* has been expanded in parse_libs().
|
|
|
|
|
*/
|
|
|
|
|
p = dirname;
|
|
|
|
|
while (*p)
|
|
|
|
|
{
|
|
|
|
|
if (*p == '\\')
|
|
|
|
|
*p = '/';
|
|
|
|
|
p++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|
2015-10-15 19:17:19 +08:00
|
|
|
dir = g_dir_open (dirname_copy, 0 , NULL);
|
2005-07-14 13:07:18 +00:00
|
|
|
g_free (dirname_copy);
|
2014-11-12 07:42:27 -08:00
|
|
|
|
|
|
|
|
scanned_dir_count += 1;
|
|
|
|
|
|
2005-07-14 13:04:01 +00:00
|
|
|
if (!dir)
|
|
|
|
|
{
|
2014-11-12 07:42:27 -08:00
|
|
|
debug_spew ("Cannot open directory #%i '%s' in package search path: %s\n",
|
|
|
|
|
scanned_dir_count, dirname, g_strerror (errno));
|
2005-07-14 13:04:01 +00:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2014-11-12 07:42:27 -08:00
|
|
|
debug_spew ("Scanning directory #%i '%s'\n", scanned_dir_count, dirname);
|
2005-07-14 13:04:01 +00:00
|
|
|
|
2015-10-15 19:17:19 +08:00
|
|
|
while ((d_name = g_dir_read_name(dir)))
|
2005-07-14 13:04:01 +00:00
|
|
|
{
|
2015-10-15 19:17:19 +08:00
|
|
|
int len = strlen (d_name);
|
2005-07-14 13:04:01 +00:00
|
|
|
|
2015-10-15 19:17:19 +08:00
|
|
|
if (ends_in_dotpc (d_name))
|
2005-07-14 13:04:01 +00:00
|
|
|
{
|
2014-11-12 07:47:57 -08:00
|
|
|
char *pkgname = g_malloc (len - EXT_LEN + 1);
|
2005-07-14 13:04:01 +00:00
|
|
|
|
2015-10-15 19:17:19 +08:00
|
|
|
debug_spew ("File '%s' appears to be a .pc file\n", d_name);
|
2005-07-14 13:04:01 +00:00
|
|
|
|
2015-10-15 19:17:19 +08:00
|
|
|
strncpy (pkgname, d_name, len - EXT_LEN);
|
2005-07-14 13:04:01 +00:00
|
|
|
pkgname[len-EXT_LEN] = '\0';
|
|
|
|
|
|
|
|
|
|
if (g_hash_table_lookup (locations, pkgname))
|
|
|
|
|
{
|
2015-10-15 19:17:19 +08:00
|
|
|
debug_spew ("File '%s' ignored, we already know about package '%s'\n", d_name, pkgname);
|
2005-07-14 13:04:01 +00:00
|
|
|
g_free (pkgname);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
char *filename = g_malloc (dirnamelen + 1 + len + 1);
|
|
|
|
|
strncpy (filename, dirname, dirnamelen);
|
2001-09-30 Tor Lillqvist <tml@iki.fi>
Author: tml
Date: 2001-09-29 21:05:25 GMT
2001-09-30 Tor Lillqvist <tml@iki.fi>
Changes for "pure" Win32 (without Cygwin or similar)
support. The most important differences compared to pkg-config
on Unix are:
We don't use hardcoded PKGLIBDIR paths but deduce the
installation prefix at runtime.
Use the normal GLib DLL, not a private copy. Yes, this does
introduce a circular dependency, but that can be worked around.
* README.win32: New file.
* configure.in: Check for Win32. If so, define USE_INSTALLED_GLIB,
and don't configure in the included glib-1.2.8. Set GLIB_CFLAGS
and GLIB_LIBS assuming that GLib is installed in the same location
pkgconfig will be. Check for dirent.h, unistd.h and sys/wait.h
headers.
* Makefile.am: If USE_INSTALLED_GLIB, use the GLIB_* values set
above, and don't make in the glib-1.2.8 subdir.
* autogen.sh: Use perl -p -i.bak, works better on Win32 (and Cygwin).
* *.c: Conditionalize inclusions of unistd.h and sys/wait.h.
* findme.c: Define X_OK on Win32 if necessary.
* parse.c
* popthelp.c: Minor Win32 portability ifdefs.
* parse.c: No need to include <windows.h>.
* pkg.c: Don't hardcode PKGLIBDIR, but use
g_win32_get_package_installation_directory() to deduce it.
(scan_dir): Make a temp copy of dirname with potential superfluous
trailing slash removed. The Win32 opendir implementation doesn't
always like those.
* pkg.h: If USE_INSTALLED_GLIB, include <glib.h> instead of
partial-glib.h.
* popt.c (execCommand): Don't compile on Win32.
* poptconfig.c (configLine): Don't bother with the "exec" stuff on
Win32, too complex to port, at least for now.
(poptReadDefaultConfig) Don't bother compiling on Win32, this
function isn't even called.
2005-07-14 13:04:29 +00:00
|
|
|
filename[dirnamelen] = G_DIR_SEPARATOR;
|
2015-10-15 19:17:19 +08:00
|
|
|
strcpy (filename + dirnamelen + 1, d_name);
|
2005-07-14 13:04:01 +00:00
|
|
|
|
2011-05-15 14:08:21 +02:00
|
|
|
if (g_file_test(filename, G_FILE_TEST_IS_REGULAR) == TRUE) {
|
|
|
|
|
g_hash_table_insert (locations, pkgname, filename);
|
|
|
|
|
g_hash_table_insert (path_positions, pkgname,
|
|
|
|
|
GINT_TO_POINTER (scanned_dir_count));
|
|
|
|
|
debug_spew ("Will find package '%s' in file '%s'\n",
|
|
|
|
|
pkgname, filename);
|
|
|
|
|
} else {
|
|
|
|
|
debug_spew ("Ignoring '%s' while looking for '%s'; not a "
|
|
|
|
|
"regular file.\n", pkgname, filename);
|
|
|
|
|
}
|
|
|
|
|
}
|
2005-07-14 13:04:01 +00:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
debug_spew ("Ignoring file '%s' in search directory; not a .pc file\n",
|
2015-10-15 19:17:19 +08:00
|
|
|
d_name);
|
2005-07-14 13:04:01 +00:00
|
|
|
}
|
|
|
|
|
}
|
2015-10-15 19:17:19 +08:00
|
|
|
g_dir_close (dir);
|
2005-07-14 13:04:01 +00:00
|
|
|
}
|
|
|
|
|
|
2005-07-14 13:05:53 +00:00
|
|
|
static Package *
|
|
|
|
|
add_virtual_pkgconfig_package (void)
|
|
|
|
|
{
|
|
|
|
|
Package *pkg = NULL;
|
|
|
|
|
|
|
|
|
|
pkg = g_new0 (Package, 1);
|
|
|
|
|
|
|
|
|
|
pkg->key = g_strdup ("pkg-config");
|
|
|
|
|
pkg->version = g_strdup (VERSION);
|
|
|
|
|
pkg->name = g_strdup ("pkg-config");
|
|
|
|
|
pkg->description = g_strdup ("pkg-config is a system for managing "
|
|
|
|
|
"compile/link flags for libraries");
|
2009-03-30 21:04:42 +02:00
|
|
|
pkg->url = g_strdup ("http://pkg-config.freedesktop.org/");
|
2005-07-14 13:05:53 +00:00
|
|
|
|
2009-03-30 21:17:43 +02:00
|
|
|
if (pkg->vars == NULL)
|
|
|
|
|
pkg->vars = g_hash_table_new (g_str_hash, g_str_equal);
|
2016-01-29 11:41:21 -08:00
|
|
|
g_hash_table_insert (pkg->vars, "pc_path", pkg_config_pc_path);
|
2009-03-30 21:17:43 +02:00
|
|
|
|
2005-07-14 13:05:53 +00:00
|
|
|
debug_spew ("Adding virtual 'pkg-config' package to list of known packages\n");
|
|
|
|
|
g_hash_table_insert (packages, pkg->key, pkg);
|
|
|
|
|
|
|
|
|
|
return pkg;
|
|
|
|
|
}
|
|
|
|
|
|
2005-07-14 13:04:01 +00:00
|
|
|
void
|
|
|
|
|
package_init ()
|
|
|
|
|
{
|
|
|
|
|
static gboolean initted = FALSE;
|
|
|
|
|
|
|
|
|
|
if (!initted)
|
|
|
|
|
{
|
|
|
|
|
initted = TRUE;
|
|
|
|
|
|
|
|
|
|
packages = g_hash_table_new (g_str_hash, g_str_equal);
|
|
|
|
|
locations = g_hash_table_new (g_str_hash, g_str_equal);
|
2005-07-14 13:04:45 +00:00
|
|
|
path_positions = g_hash_table_new (g_str_hash, g_str_equal);
|
2005-07-14 13:04:01 +00:00
|
|
|
|
2005-07-14 13:05:53 +00:00
|
|
|
add_virtual_pkgconfig_package ();
|
|
|
|
|
|
2012-11-29 05:40:40 -08:00
|
|
|
g_list_foreach (search_dirs, (GFunc)scan_dir, NULL);
|
2005-07-14 13:04:01 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static Package *
|
2010-09-01 20:48:57 +02:00
|
|
|
internal_get_package (const char *name, gboolean warn)
|
2005-07-14 13:04:01 +00:00
|
|
|
{
|
|
|
|
|
Package *pkg = NULL;
|
2015-06-15 09:20:58 +02:00
|
|
|
char *key;
|
2005-07-14 13:04:01 +00:00
|
|
|
const char *location;
|
2012-11-29 05:40:40 -08:00
|
|
|
GList *iter;
|
2005-07-14 13:04:01 +00:00
|
|
|
|
|
|
|
|
pkg = g_hash_table_lookup (packages, name);
|
|
|
|
|
|
|
|
|
|
if (pkg)
|
|
|
|
|
return pkg;
|
|
|
|
|
|
|
|
|
|
debug_spew ("Looking for package '%s'\n", name);
|
|
|
|
|
|
|
|
|
|
/* treat "name" as a filename if it ends in .pc and exists */
|
|
|
|
|
if ( ends_in_dotpc (name) )
|
|
|
|
|
{
|
|
|
|
|
debug_spew ("Considering '%s' to be a filename rather than a package name\n", name);
|
|
|
|
|
location = name;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
/* See if we should auto-prefer the uninstalled version */
|
|
|
|
|
if (!disable_uninstalled &&
|
2005-07-14 13:04:19 +00:00
|
|
|
!name_ends_in_uninstalled (name))
|
2005-07-14 13:04:01 +00:00
|
|
|
{
|
|
|
|
|
char *un;
|
|
|
|
|
|
|
|
|
|
un = g_strconcat (name, "-uninstalled", NULL);
|
|
|
|
|
|
2010-09-01 20:48:57 +02:00
|
|
|
pkg = internal_get_package (un, FALSE);
|
2005-07-14 13:04:01 +00:00
|
|
|
|
|
|
|
|
g_free (un);
|
|
|
|
|
|
|
|
|
|
if (pkg)
|
|
|
|
|
{
|
|
|
|
|
debug_spew ("Preferring uninstalled version of package '%s'\n", name);
|
|
|
|
|
return pkg;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
location = g_hash_table_lookup (locations, name);
|
|
|
|
|
}
|
|
|
|
|
|
2005-07-14 13:04:15 +00:00
|
|
|
if (location == NULL)
|
2005-07-14 13:04:13 +00:00
|
|
|
{
|
|
|
|
|
if (warn)
|
|
|
|
|
verbose_error ("Package %s was not found in the pkg-config search path.\n"
|
|
|
|
|
"Perhaps you should add the directory containing `%s.pc'\n"
|
|
|
|
|
"to the PKG_CONFIG_PATH environment variable\n",
|
|
|
|
|
name, name);
|
2005-07-14 13:04:01 +00:00
|
|
|
|
2005-07-14 13:04:13 +00:00
|
|
|
return NULL;
|
|
|
|
|
}
|
2005-07-14 13:04:19 +00:00
|
|
|
|
2005-07-14 13:04:01 +00:00
|
|
|
if (location != name)
|
2015-06-15 09:20:58 +02:00
|
|
|
key = g_strdup (name);
|
2005-07-14 13:04:01 +00:00
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
/* need to strip package name out of the filename */
|
|
|
|
|
int len = strlen (name);
|
|
|
|
|
const char *end = name + (len - EXT_LEN);
|
|
|
|
|
const char *start = end;
|
|
|
|
|
|
|
|
|
|
while (start != name && *start != G_DIR_SEPARATOR)
|
|
|
|
|
--start;
|
|
|
|
|
|
|
|
|
|
g_assert (end >= start);
|
2015-06-15 09:20:58 +02:00
|
|
|
|
|
|
|
|
key = g_strndup (start, end - start);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
debug_spew ("Reading '%s' from file '%s'\n", name, location);
|
|
|
|
|
pkg = parse_package_file (key, location, ignore_requires,
|
|
|
|
|
ignore_private_libs, ignore_requires_private);
|
|
|
|
|
g_free (key);
|
|
|
|
|
|
|
|
|
|
if (pkg == NULL)
|
|
|
|
|
{
|
|
|
|
|
debug_spew ("Failed to parse '%s'\n", location);
|
|
|
|
|
return NULL;
|
2005-07-14 13:04:01 +00:00
|
|
|
}
|
|
|
|
|
|
2015-06-15 09:20:58 +02:00
|
|
|
if (strstr (location, "uninstalled.pc"))
|
|
|
|
|
pkg->uninstalled = TRUE;
|
|
|
|
|
|
2005-07-14 13:05:03 +00:00
|
|
|
pkg->path_position =
|
|
|
|
|
GPOINTER_TO_INT (g_hash_table_lookup (path_positions, pkg->key));
|
|
|
|
|
|
|
|
|
|
debug_spew ("Path position of '%s' is %d\n",
|
2012-11-21 11:36:16 -08:00
|
|
|
pkg->key, pkg->path_position);
|
2005-07-14 13:05:03 +00:00
|
|
|
|
2012-05-08 05:28:13 -07:00
|
|
|
debug_spew ("Adding '%s' to list of known packages\n", pkg->key);
|
2005-07-14 13:04:01 +00:00
|
|
|
g_hash_table_insert (packages, pkg->key, pkg);
|
|
|
|
|
|
2012-05-08 05:28:13 -07:00
|
|
|
/* pull in Requires packages */
|
2012-11-29 05:40:40 -08:00
|
|
|
for (iter = pkg->requires_entries; iter != NULL; iter = g_list_next (iter))
|
2012-05-08 05:28:13 -07:00
|
|
|
{
|
|
|
|
|
Package *req;
|
|
|
|
|
RequiredVersion *ver = iter->data;
|
|
|
|
|
|
|
|
|
|
debug_spew ("Searching for '%s' requirement '%s'\n",
|
2012-11-21 11:36:16 -08:00
|
|
|
pkg->key, ver->name);
|
2012-05-08 05:28:13 -07:00
|
|
|
req = internal_get_package (ver->name, warn);
|
|
|
|
|
if (req == NULL)
|
|
|
|
|
{
|
|
|
|
|
verbose_error ("Package '%s', required by '%s', not found\n",
|
2012-11-21 11:36:16 -08:00
|
|
|
ver->name, pkg->key);
|
2012-05-08 05:28:13 -07:00
|
|
|
exit (1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (pkg->required_versions == NULL)
|
|
|
|
|
pkg->required_versions = g_hash_table_new (g_str_hash, g_str_equal);
|
|
|
|
|
|
|
|
|
|
g_hash_table_insert (pkg->required_versions, ver->name, ver);
|
2012-11-29 05:40:40 -08:00
|
|
|
pkg->requires = g_list_prepend (pkg->requires, req);
|
2012-05-08 05:28:13 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* pull in Requires.private packages */
|
|
|
|
|
for (iter = pkg->requires_private_entries; iter != NULL;
|
2012-11-29 05:40:40 -08:00
|
|
|
iter = g_list_next (iter))
|
2012-05-08 05:28:13 -07:00
|
|
|
{
|
|
|
|
|
Package *req;
|
|
|
|
|
RequiredVersion *ver = iter->data;
|
|
|
|
|
|
|
|
|
|
debug_spew ("Searching for '%s' private requirement '%s'\n",
|
2012-11-21 11:36:16 -08:00
|
|
|
pkg->key, ver->name);
|
2012-05-08 05:28:13 -07:00
|
|
|
req = internal_get_package (ver->name, warn);
|
|
|
|
|
if (req == NULL)
|
|
|
|
|
{
|
|
|
|
|
verbose_error ("Package '%s', required by '%s', not found\n",
|
2012-11-21 11:36:16 -08:00
|
|
|
ver->name, pkg->key);
|
2012-05-08 05:28:13 -07:00
|
|
|
exit (1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (pkg->required_versions == NULL)
|
|
|
|
|
pkg->required_versions = g_hash_table_new (g_str_hash, g_str_equal);
|
|
|
|
|
|
|
|
|
|
g_hash_table_insert (pkg->required_versions, ver->name, ver);
|
2012-11-29 05:40:40 -08:00
|
|
|
pkg->requires_private = g_list_prepend (pkg->requires_private, req);
|
2012-05-08 05:28:13 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* make requires_private include a copy of the public requires too */
|
2012-11-29 05:40:40 -08:00
|
|
|
pkg->requires_private = g_list_concat (g_list_copy (pkg->requires),
|
2012-05-08 05:28:13 -07:00
|
|
|
pkg->requires_private);
|
|
|
|
|
|
2012-11-29 05:40:40 -08:00
|
|
|
pkg->requires = g_list_reverse (pkg->requires);
|
|
|
|
|
pkg->requires_private = g_list_reverse (pkg->requires_private);
|
2012-05-08 05:28:13 -07:00
|
|
|
|
|
|
|
|
verify_package (pkg);
|
|
|
|
|
|
2005-07-14 13:04:01 +00:00
|
|
|
return pkg;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Package *
|
|
|
|
|
get_package (const char *name)
|
|
|
|
|
{
|
2010-09-01 20:48:57 +02:00
|
|
|
return internal_get_package (name, TRUE);
|
2005-07-14 13:04:01 +00:00
|
|
|
}
|
|
|
|
|
|
2005-10-16 17:31:41 +00:00
|
|
|
Package *
|
|
|
|
|
get_package_quiet (const char *name)
|
|
|
|
|
{
|
2010-09-01 20:48:57 +02:00
|
|
|
return internal_get_package (name, FALSE);
|
2005-10-16 17:31:41 +00:00
|
|
|
}
|
|
|
|
|
|
2012-11-19 10:45:41 -08:00
|
|
|
/* Strip consecutive duplicate arguments in the flag list. */
|
2012-11-29 05:40:40 -08:00
|
|
|
static GList *
|
2012-11-19 10:45:41 -08:00
|
|
|
flag_list_strip_duplicates (GList *list)
|
2005-07-14 13:04:01 +00:00
|
|
|
{
|
2012-11-29 05:40:40 -08:00
|
|
|
GList *tmp;
|
2005-07-14 13:04:01 +00:00
|
|
|
|
2012-11-19 10:45:41 -08:00
|
|
|
/* 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))
|
2005-07-14 13:04:01 +00:00
|
|
|
{
|
2012-11-19 10:45:41 -08:00
|
|
|
Flag *cur = tmp->data;
|
|
|
|
|
Flag *prev = tmp->prev->data;
|
2012-12-03 07:34:00 -08:00
|
|
|
|
2012-11-19 10:45:41 -08:00
|
|
|
if (cur->type == prev->type && g_strcmp0 (cur->arg, prev->arg) == 0)
|
2005-07-14 13:04:59 +00:00
|
|
|
{
|
2012-11-19 08:19:48 -08:00
|
|
|
/* Remove the duplicate flag from the list and move to the last
|
2012-11-15 20:12:22 -08:00
|
|
|
* element to prepare for the next iteration. */
|
2012-12-03 07:34:00 -08:00
|
|
|
GList *dup = tmp;
|
|
|
|
|
|
2012-11-19 10:45:41 -08:00
|
|
|
debug_spew (" removing duplicate \"%s\"\n", cur->arg);
|
|
|
|
|
tmp = g_list_previous (tmp);
|
2012-12-03 07:34:00 -08:00
|
|
|
list = g_list_remove_link (list, dup);
|
2005-07-14 13:04:59 +00:00
|
|
|
}
|
2005-07-14 13:04:01 +00:00
|
|
|
}
|
2012-11-15 20:12:22 -08:00
|
|
|
|
2012-12-03 07:34:00 -08:00
|
|
|
return list;
|
2005-07-14 13:04:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static char *
|
2012-11-19 08:19:48 -08:00
|
|
|
flag_list_to_string (GList *list)
|
2005-07-14 13:04:01 +00:00
|
|
|
{
|
2012-11-29 05:40:40 -08:00
|
|
|
GList *tmp;
|
2005-07-14 13:04:01 +00:00
|
|
|
GString *str = g_string_new ("");
|
|
|
|
|
char *retval;
|
|
|
|
|
|
|
|
|
|
tmp = list;
|
2009-12-06 22:40:13 +01:00
|
|
|
while (tmp != NULL) {
|
2012-11-19 08:19:48 -08:00
|
|
|
Flag *flag = tmp->data;
|
|
|
|
|
char *tmpstr = flag->arg;
|
|
|
|
|
|
|
|
|
|
if (pcsysrootdir != NULL && flag->type & (CFLAGS_I | LIBS_L)) {
|
2009-12-06 22:40:13 +01:00
|
|
|
g_string_append_c (str, '-');
|
|
|
|
|
g_string_append_c (str, tmpstr[1]);
|
|
|
|
|
g_string_append (str, pcsysrootdir);
|
|
|
|
|
g_string_append (str, tmpstr+2);
|
|
|
|
|
} else {
|
|
|
|
|
g_string_append (str, tmpstr);
|
2005-07-14 13:04:01 +00:00
|
|
|
}
|
2009-12-06 22:40:13 +01:00
|
|
|
g_string_append_c (str, ' ');
|
2012-11-29 05:40:40 -08:00
|
|
|
tmp = g_list_next (tmp);
|
2009-12-06 22:40:13 +01:00
|
|
|
}
|
2005-07-14 13:04:01 +00:00
|
|
|
|
|
|
|
|
retval = str->str;
|
|
|
|
|
g_string_free (str, FALSE);
|
|
|
|
|
|
|
|
|
|
return retval;
|
|
|
|
|
}
|
|
|
|
|
|
2005-07-14 13:04:45 +00:00
|
|
|
static int
|
|
|
|
|
pathposcmp (gconstpointer a, gconstpointer b)
|
|
|
|
|
{
|
|
|
|
|
const Package *pa = a;
|
|
|
|
|
const Package *pb = b;
|
2005-07-14 13:04:59 +00:00
|
|
|
|
2005-07-14 13:04:45 +00:00
|
|
|
if (pa->path_position < pb->path_position)
|
|
|
|
|
return -1;
|
|
|
|
|
else if (pa->path_position > pb->path_position)
|
|
|
|
|
return 1;
|
|
|
|
|
else
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2005-07-14 13:04:59 +00:00
|
|
|
static void
|
|
|
|
|
spew_package_list (const char *name,
|
2012-11-29 05:40:40 -08:00
|
|
|
GList *list)
|
2005-07-14 13:04:59 +00:00
|
|
|
{
|
2012-11-29 05:40:40 -08:00
|
|
|
GList *tmp;
|
2005-07-14 13:04:59 +00:00
|
|
|
|
2012-11-15 06:34:05 -08:00
|
|
|
debug_spew (" %s:", name);
|
|
|
|
|
|
2005-07-14 13:04:59 +00:00
|
|
|
tmp = list;
|
|
|
|
|
while (tmp != NULL)
|
|
|
|
|
{
|
|
|
|
|
Package *pkg = tmp->data;
|
2012-11-15 06:34:05 -08:00
|
|
|
debug_spew (" %s", pkg->key);
|
2005-07-14 13:04:59 +00:00
|
|
|
tmp = tmp->next;
|
|
|
|
|
}
|
|
|
|
|
debug_spew ("\n");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2012-11-29 05:40:40 -08:00
|
|
|
static GList *
|
|
|
|
|
packages_sort_by_path_position (GList *list)
|
2005-07-14 13:04:45 +00:00
|
|
|
{
|
2012-11-29 05:40:40 -08:00
|
|
|
return g_list_sort (list, pathposcmp);
|
2005-07-14 13:04:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2012-11-16 08:45:53 -08:00
|
|
|
recursive_fill_list (Package *pkg, gboolean include_private, GList **listp)
|
2005-07-14 13:04:45 +00:00
|
|
|
{
|
2012-11-29 05:40:40 -08:00
|
|
|
GList *tmp;
|
2005-07-14 13:04:45 +00:00
|
|
|
|
2012-05-09 05:55:47 -07:00
|
|
|
/*
|
|
|
|
|
* If the package is one of the parents, we can skip it. This allows
|
|
|
|
|
* circular requires loops to be broken.
|
|
|
|
|
*/
|
2013-01-16 16:42:48 -08:00
|
|
|
if (pkg->in_requires_chain)
|
2012-05-09 05:55:47 -07:00
|
|
|
{
|
|
|
|
|
debug_spew ("Package %s already in requires chain, skipping\n",
|
|
|
|
|
pkg->key);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* record this package in the dependency chain */
|
2013-01-16 16:42:48 -08:00
|
|
|
pkg->in_requires_chain = TRUE;
|
2012-05-09 05:55:47 -07:00
|
|
|
|
2012-11-29 07:11:57 -08:00
|
|
|
/* Start from the end of the required package list to maintain order since
|
|
|
|
|
* the recursive list is built by prepending. */
|
2012-11-16 08:45:53 -08:00
|
|
|
tmp = include_private ? pkg->requires_private : pkg->requires;
|
|
|
|
|
for (tmp = g_list_last (tmp); tmp != NULL; tmp = g_list_previous (tmp))
|
|
|
|
|
recursive_fill_list (tmp->data, include_private, listp);
|
2005-07-14 13:04:01 +00:00
|
|
|
|
2012-11-29 05:40:40 -08:00
|
|
|
*listp = g_list_prepend (*listp, pkg);
|
2012-05-09 05:55:47 -07:00
|
|
|
|
|
|
|
|
/* remove this package from the dependency chain now that we've unwound */
|
2013-01-16 16:42:48 -08:00
|
|
|
pkg->in_requires_chain = FALSE;
|
2005-07-14 13:04:01 +00:00
|
|
|
}
|
|
|
|
|
|
2012-10-29 17:30:18 -07:00
|
|
|
/* merge the flags from the individual packages */
|
2012-11-15 19:52:26 -08:00
|
|
|
static GList *
|
2012-11-16 08:45:53 -08:00
|
|
|
merge_flag_lists (GList *packages, FlagType type)
|
2012-10-29 17:30:18 -07:00
|
|
|
{
|
2012-11-29 05:40:40 -08:00
|
|
|
GList *last = NULL;
|
2012-11-15 19:52:26 -08:00
|
|
|
GList *merged = NULL;
|
2012-10-29 17:30:18 -07:00
|
|
|
|
2012-11-29 05:54:29 -08:00
|
|
|
/* keep track of the last element to avoid traversing the whole list */
|
2012-11-16 08:45:53 -08:00
|
|
|
for (; packages != NULL; packages = g_list_next (packages))
|
2012-10-29 17:30:18 -07:00
|
|
|
{
|
2012-11-16 08:45:53 -08:00
|
|
|
Package *pkg = packages->data;
|
2012-11-19 08:19:48 -08:00
|
|
|
GList *flags = (type & LIBS_ANY) ? pkg->libs : pkg->cflags;
|
2012-11-16 08:45:53 -08:00
|
|
|
|
|
|
|
|
/* manually copy the elements so we can keep track of the end */
|
|
|
|
|
for (; flags != NULL; flags = g_list_next (flags))
|
2012-10-29 17:30:18 -07:00
|
|
|
{
|
2012-11-19 08:19:48 -08:00
|
|
|
Flag *flag = flags->data;
|
|
|
|
|
|
|
|
|
|
if (flag->type & type)
|
2012-10-29 17:30:18 -07:00
|
|
|
{
|
2012-11-19 08:19:48 -08:00
|
|
|
if (last == NULL)
|
|
|
|
|
{
|
|
|
|
|
merged = g_list_prepend (NULL, flags->data);
|
|
|
|
|
last = merged;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
last = g_list_next (g_list_append (last, flags->data));
|
2012-10-29 17:30:18 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2012-11-15 19:52:26 -08:00
|
|
|
|
|
|
|
|
return merged;
|
2012-10-29 17:30:18 -07:00
|
|
|
}
|
|
|
|
|
|
2012-11-15 06:32:36 -08:00
|
|
|
/* Work backwards from the end of the package list to remove duplicate
|
|
|
|
|
* packages. This could happen because the package was specified multiple
|
|
|
|
|
* times on the command line, or because multiple packages require the same
|
|
|
|
|
* package. When we have duplicate dependencies, starting from the end of the
|
|
|
|
|
* list ensures that the dependency shows up later in the package list and
|
|
|
|
|
* Libs will come out correctly. */
|
|
|
|
|
static GList *
|
|
|
|
|
package_list_strip_duplicates (GList *packages)
|
|
|
|
|
{
|
|
|
|
|
GList *cur;
|
|
|
|
|
GHashTable *requires;
|
|
|
|
|
|
|
|
|
|
requires = g_hash_table_new (g_str_hash, g_str_equal);
|
|
|
|
|
for (cur = g_list_last (packages); cur != NULL; cur = g_list_previous (cur))
|
|
|
|
|
{
|
|
|
|
|
Package *pkg = cur->data;
|
|
|
|
|
|
2012-12-03 08:25:40 -08:00
|
|
|
if (g_hash_table_lookup_extended (requires, pkg->key, NULL, NULL))
|
2012-11-15 06:32:36 -08:00
|
|
|
{
|
|
|
|
|
GList *dup = cur;
|
|
|
|
|
|
|
|
|
|
/* Remove the duplicate package from the list */
|
|
|
|
|
debug_spew ("Removing duplicate package %s\n", pkg->key);
|
|
|
|
|
cur = cur->next;
|
|
|
|
|
packages = g_list_delete_link (packages, dup);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
/* Unique package. Track it and move to the next. */
|
2012-12-04 12:59:47 -08:00
|
|
|
g_hash_table_replace (requires, pkg->key, pkg->key);
|
2012-11-15 06:32:36 -08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
g_hash_table_destroy (requires);
|
|
|
|
|
|
|
|
|
|
return packages;
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-15 19:52:26 -08:00
|
|
|
static GList *
|
2012-11-16 08:45:53 -08:00
|
|
|
fill_list (GList *packages, FlagType type,
|
2012-11-15 19:52:26 -08:00
|
|
|
gboolean in_path_order, gboolean include_private)
|
2005-07-14 13:04:45 +00:00
|
|
|
{
|
2012-11-29 05:40:40 -08:00
|
|
|
GList *tmp;
|
2012-11-29 07:11:57 -08:00
|
|
|
GList *expanded = NULL;
|
2012-11-15 19:52:26 -08:00
|
|
|
GList *flags;
|
2012-11-29 07:11:57 -08:00
|
|
|
|
|
|
|
|
/* Start from the end of the requested package list to maintain order since
|
|
|
|
|
* the recursive list is built by prepending. */
|
|
|
|
|
for (tmp = g_list_last (packages); tmp != NULL; tmp = g_list_previous (tmp))
|
2012-11-16 08:45:53 -08:00
|
|
|
recursive_fill_list (tmp->data, include_private, &expanded);
|
2005-07-14 13:04:45 +00:00
|
|
|
|
2012-11-15 06:32:36 -08:00
|
|
|
/* Remove duplicate packages from the recursive list. This should provide a
|
|
|
|
|
* serialized package list where all interdependencies are resolved
|
|
|
|
|
* consistently. */
|
|
|
|
|
spew_package_list (" pre-remove", expanded);
|
|
|
|
|
expanded = package_list_strip_duplicates (expanded);
|
|
|
|
|
spew_package_list ("post-remove", expanded);
|
|
|
|
|
|
2005-07-14 13:05:04 +00:00
|
|
|
if (in_path_order)
|
|
|
|
|
{
|
|
|
|
|
spew_package_list ("original", expanded);
|
|
|
|
|
expanded = packages_sort_by_path_position (expanded);
|
2012-11-15 06:34:05 -08:00
|
|
|
spew_package_list (" sorted", expanded);
|
2005-07-14 13:05:04 +00:00
|
|
|
}
|
2012-10-29 17:30:18 -07:00
|
|
|
|
2012-11-16 08:45:53 -08:00
|
|
|
flags = merge_flag_lists (expanded, type);
|
2012-11-29 05:40:40 -08:00
|
|
|
g_list_free (expanded);
|
2012-11-15 19:52:26 -08:00
|
|
|
|
|
|
|
|
return flags;
|
2005-07-14 13:04:45 +00:00
|
|
|
}
|
|
|
|
|
|
2012-11-29 05:40:40 -08:00
|
|
|
static GList *
|
|
|
|
|
add_env_variable_to_list (GList *list, const gchar *env)
|
2005-07-14 13:05:22 +00:00
|
|
|
{
|
|
|
|
|
gchar **values;
|
|
|
|
|
gint i;
|
|
|
|
|
|
2005-07-14 13:05:44 +00:00
|
|
|
values = g_strsplit (env, G_SEARCHPATH_SEPARATOR_S, 0);
|
2005-07-14 13:05:22 +00:00
|
|
|
for (i = 0; values[i] != NULL; i++)
|
|
|
|
|
{
|
2012-11-29 05:40:40 -08:00
|
|
|
list = g_list_append (list, g_strdup (values[i]));
|
2005-07-14 13:05:22 +00:00
|
|
|
}
|
|
|
|
|
g_strfreev (values);
|
|
|
|
|
|
2005-07-14 13:05:28 +00:00
|
|
|
return list;
|
2005-07-14 13:05:22 +00:00
|
|
|
}
|
|
|
|
|
|
2005-07-14 13:04:01 +00:00
|
|
|
static void
|
|
|
|
|
verify_package (Package *pkg)
|
|
|
|
|
{
|
2012-11-29 05:40:40 -08:00
|
|
|
GList *requires = NULL;
|
|
|
|
|
GList *conflicts = NULL;
|
|
|
|
|
GList *system_directories = NULL;
|
|
|
|
|
GList *iter;
|
|
|
|
|
GList *requires_iter;
|
|
|
|
|
GList *conflicts_iter;
|
|
|
|
|
GList *system_dir_iter = NULL;
|
2005-07-14 13:04:51 +00:00
|
|
|
int count;
|
2011-04-13 22:56:53 +02:00
|
|
|
const gchar *search_path;
|
2005-07-14 13:05:22 +00:00
|
|
|
|
2005-07-14 13:04:01 +00:00
|
|
|
/* Be sure we have the required fields */
|
|
|
|
|
|
|
|
|
|
if (pkg->key == NULL)
|
|
|
|
|
{
|
|
|
|
|
fprintf (stderr,
|
|
|
|
|
"Internal pkg-config error, package with no key, please file a bug report\n");
|
|
|
|
|
exit (1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (pkg->name == NULL)
|
|
|
|
|
{
|
|
|
|
|
verbose_error ("Package '%s' has no Name: field\n",
|
|
|
|
|
pkg->key);
|
|
|
|
|
exit (1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (pkg->version == NULL)
|
|
|
|
|
{
|
|
|
|
|
verbose_error ("Package '%s' has no Version: field\n",
|
2005-07-14 13:05:55 +00:00
|
|
|
pkg->key);
|
2005-07-14 13:04:01 +00:00
|
|
|
exit (1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (pkg->description == NULL)
|
|
|
|
|
{
|
|
|
|
|
verbose_error ("Package '%s' has no Description: field\n",
|
2005-07-14 13:05:55 +00:00
|
|
|
pkg->key);
|
2005-07-14 13:04:01 +00:00
|
|
|
exit (1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Make sure we have the right version for all requirements */
|
|
|
|
|
|
2005-06-27 Tollef Fog Heen <tfheen@err.no>
Author: tfheen
Date: 2005-06-27 19:53:05 GMT
2005-06-27 Tollef Fog Heen <tfheen@err.no>
All those Requires.private changes are thanks to James
Henstridge. Thanks!
* check/private-dep.pc, check/public-dep.pc,
check/requires-test.pc: New files, data for the
check-requires-private test.
* check/check-requires-private: New test to check for
Requires.private support.
* check/Makefile.am (EXTRA_DIST, TESTS): Add Requires.private
test.
* pkg.h (struct _Package): Add requires_private
* pkg.c (get_requires_private, fill_list_single_package)
(fill_list, verify_package, verify_package, get_merged)
(get_merged_from_back, get_multi_merged)
(get_multi_merged_from_back, package_get_l_libs)
(packages_get_l_libs, package_get_L_libs, packages_get_L_libs)
(package_get_other_libs, packages_get_other_libs)
(package_get_I_cflags, packages_get_I_cflags)
(package_get_other_cflags, packages_get_other_cflags): Handle
private requires and cascading changes.
* parse.c (parse_requires_private, parse_conflicts)
(parse_package_file): Handle Requires.private
2005-07-14 13:07:31 +00:00
|
|
|
iter = pkg->requires_private;
|
2005-07-14 13:04:01 +00:00
|
|
|
|
|
|
|
|
while (iter != NULL)
|
|
|
|
|
{
|
|
|
|
|
Package *req = iter->data;
|
|
|
|
|
RequiredVersion *ver = NULL;
|
|
|
|
|
|
|
|
|
|
if (pkg->required_versions)
|
|
|
|
|
ver = g_hash_table_lookup (pkg->required_versions,
|
|
|
|
|
req->key);
|
|
|
|
|
|
|
|
|
|
if (ver)
|
|
|
|
|
{
|
|
|
|
|
if (!version_test (ver->comparison, req->version, ver->version))
|
|
|
|
|
{
|
|
|
|
|
verbose_error ("Package '%s' requires '%s %s %s' but version of %s is %s\n",
|
2012-11-21 11:36:16 -08:00
|
|
|
pkg->key, req->key,
|
2005-07-14 13:04:01 +00:00
|
|
|
comparison_to_str (ver->comparison),
|
|
|
|
|
ver->version,
|
2012-11-21 11:36:16 -08:00
|
|
|
req->key,
|
2005-07-14 13:04:01 +00:00
|
|
|
req->version);
|
2005-07-14 13:05:41 +00:00
|
|
|
if (req->url)
|
|
|
|
|
verbose_error ("You may find new versions of %s at %s\n",
|
|
|
|
|
req->name, req->url);
|
2005-07-14 13:04:01 +00:00
|
|
|
|
|
|
|
|
exit (1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-29 05:40:40 -08:00
|
|
|
iter = g_list_next (iter);
|
2005-07-14 13:04:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Make sure we didn't drag in any conflicts via Requires
|
|
|
|
|
* (inefficient algorithm, who cares)
|
|
|
|
|
*/
|
2012-11-16 08:45:53 -08:00
|
|
|
recursive_fill_list (pkg, TRUE, &requires);
|
|
|
|
|
conflicts = pkg->conflicts;
|
2005-07-14 13:04:01 +00:00
|
|
|
|
|
|
|
|
requires_iter = requires;
|
|
|
|
|
while (requires_iter != NULL)
|
|
|
|
|
{
|
|
|
|
|
Package *req = requires_iter->data;
|
|
|
|
|
|
|
|
|
|
conflicts_iter = conflicts;
|
|
|
|
|
|
|
|
|
|
while (conflicts_iter != NULL)
|
|
|
|
|
{
|
|
|
|
|
RequiredVersion *ver = conflicts_iter->data;
|
|
|
|
|
|
2008-03-23 21:39:07 +01:00
|
|
|
if (strcmp (ver->name, req->key) == 0 &&
|
|
|
|
|
version_test (ver->comparison,
|
|
|
|
|
req->version,
|
|
|
|
|
ver->version))
|
2005-07-14 13:04:01 +00:00
|
|
|
{
|
|
|
|
|
verbose_error ("Version %s of %s creates a conflict.\n"
|
|
|
|
|
"(%s %s %s conflicts with %s %s)\n",
|
2012-11-21 11:36:16 -08:00
|
|
|
req->version, req->key,
|
2005-07-14 13:04:01 +00:00
|
|
|
ver->name,
|
|
|
|
|
comparison_to_str (ver->comparison),
|
2007-12-29 16:46:25 +01:00
|
|
|
ver->version ? ver->version : "(any)",
|
2012-11-21 11:36:16 -08:00
|
|
|
ver->owner->key,
|
2005-07-14 13:04:01 +00:00
|
|
|
ver->owner->version);
|
|
|
|
|
|
|
|
|
|
exit (1);
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-29 05:40:40 -08:00
|
|
|
conflicts_iter = g_list_next (conflicts_iter);
|
2005-07-14 13:04:01 +00:00
|
|
|
}
|
|
|
|
|
|
2012-11-29 05:40:40 -08:00
|
|
|
requires_iter = g_list_next (requires_iter);
|
2005-07-14 13:04:01 +00:00
|
|
|
}
|
|
|
|
|
|
2012-11-29 05:40:40 -08:00
|
|
|
g_list_free (requires);
|
2005-07-14 13:04:47 +00:00
|
|
|
|
2005-07-14 13:05:22 +00:00
|
|
|
/* We make a list of system directories that gcc expects so we can remove
|
|
|
|
|
* them.
|
|
|
|
|
*/
|
2005-07-14 13:05:44 +00:00
|
|
|
|
2011-04-13 22:56:53 +02:00
|
|
|
search_path = g_getenv ("PKG_CONFIG_SYSTEM_INCLUDE_PATH");
|
|
|
|
|
|
|
|
|
|
if (search_path == NULL)
|
2005-07-14 13:05:22 +00:00
|
|
|
{
|
2011-04-13 22:56:53 +02:00
|
|
|
search_path = PKG_CONFIG_SYSTEM_INCLUDE_PATH;
|
2005-07-14 13:05:22 +00:00
|
|
|
}
|
2011-04-13 22:56:53 +02:00
|
|
|
|
|
|
|
|
system_directories = add_env_variable_to_list (system_directories, search_path);
|
|
|
|
|
|
|
|
|
|
search_path = g_getenv ("C_INCLUDE_PATH");
|
|
|
|
|
if (search_path != NULL)
|
2005-07-14 13:05:22 +00:00
|
|
|
{
|
2011-04-13 22:56:53 +02:00
|
|
|
system_directories = add_env_variable_to_list (system_directories, search_path);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
search_path = g_getenv ("CPLUS_INCLUDE_PATH");
|
|
|
|
|
if (search_path != NULL)
|
|
|
|
|
{
|
|
|
|
|
system_directories = add_env_variable_to_list (system_directories, search_path);
|
2005-07-14 13:05:22 +00:00
|
|
|
}
|
|
|
|
|
|
2005-07-14 13:04:51 +00:00
|
|
|
count = 0;
|
2012-11-19 08:19:48 -08:00
|
|
|
for (iter = pkg->cflags; iter != NULL; iter = g_list_next (iter))
|
2005-07-14 13:04:47 +00:00
|
|
|
{
|
2005-07-14 13:05:22 +00:00
|
|
|
gint offset = 0;
|
2012-11-19 08:19:48 -08:00
|
|
|
Flag *flag = iter->data;
|
|
|
|
|
|
|
|
|
|
if (!(flag->type & CFLAGS_I))
|
|
|
|
|
continue;
|
|
|
|
|
|
2005-07-14 13:04:47 +00:00
|
|
|
/* we put things in canonical -I/usr/include (vs. -I /usr/include) format,
|
|
|
|
|
* but if someone changes it later we may as well be robust
|
|
|
|
|
*/
|
2012-11-19 08:19:48 -08:00
|
|
|
if (((strncmp (flag->arg, "-I", 2) == 0) && (offset = 2))||
|
|
|
|
|
((strncmp (flag->arg, "-I ", 3) == 0) && (offset = 3)))
|
2005-07-14 13:04:47 +00:00
|
|
|
{
|
2005-07-14 13:05:22 +00:00
|
|
|
if (offset == 0)
|
|
|
|
|
{
|
|
|
|
|
iter = iter->next;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
system_dir_iter = system_directories;
|
|
|
|
|
while (system_dir_iter != NULL)
|
|
|
|
|
{
|
2005-07-14 13:05:30 +00:00
|
|
|
if (strcmp (system_dir_iter->data,
|
2012-11-19 08:19:48 -08:00
|
|
|
((char*)flag->arg) + offset) == 0)
|
2005-07-14 13:05:22 +00:00
|
|
|
{
|
2012-11-19 08:19:48 -08:00
|
|
|
debug_spew ("Package %s has %s in Cflags\n",
|
|
|
|
|
pkg->key, (gchar *)flag->arg);
|
2005-07-14 13:05:22 +00:00
|
|
|
if (g_getenv ("PKG_CONFIG_ALLOW_SYSTEM_CFLAGS") == NULL)
|
|
|
|
|
{
|
2012-11-19 08:19:48 -08:00
|
|
|
debug_spew ("Removing %s from cflags for %s\n",
|
|
|
|
|
flag->arg, pkg->key);
|
2005-07-14 13:05:22 +00:00
|
|
|
++count;
|
|
|
|
|
iter->data = NULL;
|
2012-11-19 08:19:48 -08:00
|
|
|
|
2005-07-14 13:05:28 +00:00
|
|
|
break;
|
2005-07-14 13:05:22 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
system_dir_iter = system_dir_iter->next;
|
|
|
|
|
}
|
2005-07-14 13:04:51 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while (count)
|
|
|
|
|
{
|
2012-11-19 08:19:48 -08:00
|
|
|
pkg->cflags = g_list_remove (pkg->cflags, NULL);
|
2005-07-14 13:04:51 +00:00
|
|
|
--count;
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-29 05:40:40 -08:00
|
|
|
g_list_foreach (system_directories, (GFunc) g_free, NULL);
|
|
|
|
|
g_list_free (system_directories);
|
2005-07-14 13:05:22 +00:00
|
|
|
|
2011-04-13 22:56:53 +02:00
|
|
|
system_directories = NULL;
|
|
|
|
|
|
|
|
|
|
search_path = g_getenv ("PKG_CONFIG_SYSTEM_LIBRARY_PATH");
|
|
|
|
|
|
|
|
|
|
if (search_path == NULL)
|
|
|
|
|
{
|
|
|
|
|
search_path = PKG_CONFIG_SYSTEM_LIBRARY_PATH;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
system_directories = add_env_variable_to_list (system_directories, search_path);
|
|
|
|
|
|
2005-07-14 13:04:51 +00:00
|
|
|
count = 0;
|
2012-11-19 08:19:48 -08:00
|
|
|
for (iter = pkg->libs; iter != NULL; iter = g_list_next (iter))
|
2005-07-14 13:04:51 +00:00
|
|
|
{
|
2012-11-29 05:40:40 -08:00
|
|
|
GList *system_dir_iter = system_directories;
|
2012-11-19 08:19:48 -08:00
|
|
|
Flag *flag = iter->data;
|
|
|
|
|
|
|
|
|
|
if (!(flag->type & LIBS_L))
|
|
|
|
|
continue;
|
2011-04-13 22:56:53 +02:00
|
|
|
|
|
|
|
|
while (system_dir_iter != NULL)
|
2005-07-14 13:04:51 +00:00
|
|
|
{
|
2011-04-13 22:56:53 +02:00
|
|
|
gboolean is_system = FALSE;
|
2012-11-19 08:19:48 -08:00
|
|
|
const char *linker_arg = flag->arg;
|
2011-04-13 22:56:53 +02:00
|
|
|
const char *system_libpath = system_dir_iter->data;
|
|
|
|
|
|
|
|
|
|
if (strncmp (linker_arg, "-L ", 3) == 0 &&
|
|
|
|
|
strcmp (linker_arg + 3, system_libpath) == 0)
|
|
|
|
|
is_system = TRUE;
|
|
|
|
|
else if (strncmp (linker_arg, "-L", 2) == 0 &&
|
|
|
|
|
strcmp (linker_arg + 2, system_libpath) == 0)
|
|
|
|
|
is_system = TRUE;
|
|
|
|
|
if (is_system)
|
|
|
|
|
{
|
|
|
|
|
debug_spew ("Package %s has -L %s in Libs\n",
|
2012-11-21 11:36:16 -08:00
|
|
|
pkg->key, system_libpath);
|
2011-04-13 22:56:53 +02:00
|
|
|
if (g_getenv ("PKG_CONFIG_ALLOW_SYSTEM_LIBS") == NULL)
|
|
|
|
|
{
|
|
|
|
|
iter->data = NULL;
|
|
|
|
|
++count;
|
2012-11-19 08:19:48 -08:00
|
|
|
debug_spew ("Removing -L %s from libs for %s\n",
|
|
|
|
|
system_libpath, pkg->key);
|
2011-04-13 22:56:53 +02:00
|
|
|
break;
|
|
|
|
|
}
|
2005-07-14 13:04:51 +00:00
|
|
|
}
|
2011-04-13 22:56:53 +02:00
|
|
|
system_dir_iter = system_dir_iter->next;
|
2005-07-14 13:04:47 +00:00
|
|
|
}
|
|
|
|
|
}
|
2012-11-29 05:40:40 -08:00
|
|
|
g_list_free (system_directories);
|
2005-07-14 13:04:51 +00:00
|
|
|
|
|
|
|
|
while (count)
|
|
|
|
|
{
|
2012-11-19 08:19:48 -08:00
|
|
|
pkg->libs = g_list_remove (pkg->libs, NULL);
|
2005-07-14 13:04:51 +00:00
|
|
|
--count;
|
|
|
|
|
}
|
2005-07-14 13:04:01 +00:00
|
|
|
}
|
|
|
|
|
|
2012-11-15 20:28:11 -08:00
|
|
|
/* Create a merged list of required packages and retrieve the flags from them.
|
|
|
|
|
* Strip the duplicates from the flags list. The sorting and stripping can be
|
|
|
|
|
* done in one of two ways: packages sorted by position in the pkg-config path
|
|
|
|
|
* and stripping done from the beginning of the list, or packages sorted from
|
|
|
|
|
* most dependent to least dependent and stripping from the end of the list.
|
|
|
|
|
* The former is done for -I/-L flags, and the latter for all others.
|
|
|
|
|
*/
|
|
|
|
|
static char *
|
2012-11-16 08:45:53 -08:00
|
|
|
get_multi_merged (GList *pkgs, FlagType type, gboolean in_path_order,
|
2012-11-15 20:28:11 -08:00
|
|
|
gboolean include_private)
|
2005-07-14 13:04:01 +00:00
|
|
|
{
|
2012-11-15 19:52:26 -08:00
|
|
|
GList *list;
|
2005-07-14 13:04:01 +00:00
|
|
|
char *retval;
|
|
|
|
|
|
2012-11-16 08:45:53 -08:00
|
|
|
list = fill_list (pkgs, type, in_path_order, include_private);
|
2012-11-19 10:45:41 -08:00
|
|
|
list = flag_list_strip_duplicates (list);
|
2012-11-19 08:19:48 -08:00
|
|
|
retval = flag_list_to_string (list);
|
2012-11-29 05:40:40 -08:00
|
|
|
g_list_free (list);
|
2012-12-03 07:34:00 -08:00
|
|
|
|
2005-07-14 13:04:01 +00:00
|
|
|
return retval;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char *
|
2012-11-29 05:40:40 -08:00
|
|
|
packages_get_flags (GList *pkgs, FlagType flags)
|
2005-07-14 13:04:01 +00:00
|
|
|
{
|
|
|
|
|
GString *str;
|
2012-10-16 20:44:16 -07:00
|
|
|
char *cur;
|
2005-07-14 13:04:01 +00:00
|
|
|
|
2012-10-16 20:44:16 -07:00
|
|
|
str = g_string_new (NULL);
|
2005-07-14 13:04:01 +00:00
|
|
|
|
2012-11-19 10:40:10 -08:00
|
|
|
/* sort packages in path order for -L/-I, dependency order otherwise */
|
2012-10-16 20:44:16 -07:00
|
|
|
if (flags & CFLAGS_OTHER)
|
|
|
|
|
{
|
2012-11-16 08:45:53 -08:00
|
|
|
cur = get_multi_merged (pkgs, CFLAGS_OTHER, FALSE, TRUE);
|
2012-10-16 20:44:16 -07:00
|
|
|
debug_spew ("adding CFLAGS_OTHER string \"%s\"\n", cur);
|
|
|
|
|
g_string_append (str, cur);
|
|
|
|
|
g_free (cur);
|
|
|
|
|
}
|
|
|
|
|
if (flags & CFLAGS_I)
|
|
|
|
|
{
|
2012-11-16 08:45:53 -08:00
|
|
|
cur = get_multi_merged (pkgs, CFLAGS_I, TRUE, TRUE);
|
2012-10-16 20:44:16 -07:00
|
|
|
debug_spew ("adding CFLAGS_I string \"%s\"\n", cur);
|
|
|
|
|
g_string_append (str, cur);
|
|
|
|
|
g_free (cur);
|
|
|
|
|
}
|
|
|
|
|
if (flags & LIBS_L)
|
|
|
|
|
{
|
2012-11-19 10:41:20 -08:00
|
|
|
cur = get_multi_merged (pkgs, LIBS_L, TRUE, !ignore_private_libs);
|
2012-10-16 20:44:16 -07:00
|
|
|
debug_spew ("adding LIBS_L string \"%s\"\n", cur);
|
|
|
|
|
g_string_append (str, cur);
|
|
|
|
|
g_free (cur);
|
|
|
|
|
}
|
2012-11-19 10:43:23 -08:00
|
|
|
if (flags & (LIBS_OTHER | LIBS_l))
|
2012-10-16 20:44:16 -07:00
|
|
|
{
|
2012-11-19 10:43:23 -08:00
|
|
|
cur = get_multi_merged (pkgs, flags & (LIBS_OTHER | LIBS_l), FALSE,
|
|
|
|
|
!ignore_private_libs);
|
|
|
|
|
debug_spew ("adding LIBS_OTHER | LIBS_l string \"%s\"\n", cur);
|
2012-10-16 20:44:16 -07:00
|
|
|
g_string_append (str, cur);
|
|
|
|
|
g_free (cur);
|
|
|
|
|
}
|
2005-07-14 13:04:01 +00:00
|
|
|
|
2013-05-31 05:48:01 -07:00
|
|
|
/* Strip trailing space. */
|
|
|
|
|
if (str->len > 0 && str->str[str->len - 1] == ' ')
|
|
|
|
|
g_string_truncate (str, str->len - 1);
|
|
|
|
|
|
2012-10-16 20:44:16 -07:00
|
|
|
debug_spew ("returning flags string \"%s\"\n", str->str);
|
|
|
|
|
return g_string_free (str, FALSE);
|
2005-07-14 13:04:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
define_global_variable (const char *varname,
|
|
|
|
|
const char *varval)
|
|
|
|
|
{
|
|
|
|
|
if (globals == NULL)
|
|
|
|
|
globals = g_hash_table_new (g_str_hash, g_str_equal);
|
|
|
|
|
|
|
|
|
|
if (g_hash_table_lookup (globals, varname))
|
|
|
|
|
{
|
|
|
|
|
verbose_error ("Variable '%s' defined twice globally\n", varname);
|
|
|
|
|
exit (1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
g_hash_table_insert (globals, g_strdup (varname), g_strdup (varval));
|
|
|
|
|
|
|
|
|
|
debug_spew ("Global variable definition '%s' = '%s'\n",
|
|
|
|
|
varname, varval);
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-13 10:22:48 -07:00
|
|
|
char *
|
|
|
|
|
var_to_env_var (const char *pkg, const char *var)
|
|
|
|
|
{
|
|
|
|
|
char *new = g_strconcat ("PKG_CONFIG_", pkg, "_", var, NULL);
|
|
|
|
|
char *p;
|
|
|
|
|
for (p = new; *p != 0; p++)
|
|
|
|
|
{
|
|
|
|
|
char c = g_ascii_toupper (*p);
|
|
|
|
|
|
|
|
|
|
if (!g_ascii_isalnum (c))
|
|
|
|
|
c = '_';
|
|
|
|
|
|
|
|
|
|
*p = c;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return new;
|
|
|
|
|
}
|
|
|
|
|
|
2005-07-14 13:04:01 +00:00
|
|
|
char *
|
|
|
|
|
package_get_var (Package *pkg,
|
|
|
|
|
const char *var)
|
|
|
|
|
{
|
|
|
|
|
char *varval = NULL;
|
|
|
|
|
|
|
|
|
|
if (globals)
|
2005-07-15 13:08:02 +00:00
|
|
|
varval = g_strdup (g_hash_table_lookup (globals, var));
|
2015-06-13 10:22:48 -07:00
|
|
|
|
|
|
|
|
/* Allow overriding specific variables using an environment variable of the
|
|
|
|
|
* form PKG_CONFIG_$PACKAGENAME_$VARIABLE
|
|
|
|
|
*/
|
|
|
|
|
if (pkg->key)
|
|
|
|
|
{
|
|
|
|
|
char *env_var = var_to_env_var (pkg->key, var);
|
|
|
|
|
const char *env_var_content = g_getenv (env_var);
|
|
|
|
|
g_free (env_var);
|
|
|
|
|
if (env_var_content)
|
|
|
|
|
{
|
|
|
|
|
debug_spew ("Overriding variable '%s' from environment\n", var);
|
|
|
|
|
return g_strdup (env_var_content);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2005-07-14 13:04:01 +00:00
|
|
|
if (varval == NULL && pkg->vars)
|
|
|
|
|
varval = g_strdup (g_hash_table_lookup (pkg->vars, var));
|
|
|
|
|
|
|
|
|
|
return varval;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char *
|
2016-01-29 09:52:04 -08:00
|
|
|
packages_get_var (GList *pkgs,
|
2005-07-14 13:04:01 +00:00
|
|
|
const char *varname)
|
|
|
|
|
{
|
2012-11-29 05:40:40 -08:00
|
|
|
GList *tmp;
|
2005-07-14 13:04:01 +00:00
|
|
|
GString *str;
|
2016-01-29 09:52:04 -08:00
|
|
|
|
|
|
|
|
str = g_string_new (NULL);
|
|
|
|
|
|
2005-07-14 13:04:01 +00:00
|
|
|
tmp = pkgs;
|
|
|
|
|
while (tmp != NULL)
|
|
|
|
|
{
|
|
|
|
|
Package *pkg = tmp->data;
|
2016-01-23 08:47:22 -08:00
|
|
|
char *var;
|
2005-07-14 13:04:01 +00:00
|
|
|
|
2016-01-29 09:52:04 -08:00
|
|
|
var = parse_package_variable (pkg, varname);
|
2005-07-14 13:04:01 +00:00
|
|
|
if (var)
|
|
|
|
|
{
|
2016-01-29 09:52:04 -08:00
|
|
|
if (str->len > 0)
|
|
|
|
|
g_string_append_c (str, ' ');
|
2016-01-23 08:47:22 -08:00
|
|
|
g_string_append (str, var);
|
2005-07-14 13:04:01 +00:00
|
|
|
g_free (var);
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-29 05:40:40 -08:00
|
|
|
tmp = g_list_next (tmp);
|
2005-07-14 13:04:01 +00:00
|
|
|
}
|
|
|
|
|
|
2016-01-29 09:52:04 -08:00
|
|
|
return g_string_free (str, FALSE);
|
2005-07-14 13:04:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
compare_versions (const char * a, const char *b)
|
|
|
|
|
{
|
|
|
|
|
return rpmvercmp (a, b);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gboolean
|
|
|
|
|
version_test (ComparisonType comparison,
|
|
|
|
|
const char *a,
|
|
|
|
|
const char *b)
|
|
|
|
|
{
|
|
|
|
|
switch (comparison)
|
|
|
|
|
{
|
|
|
|
|
case LESS_THAN:
|
|
|
|
|
return compare_versions (a, b) < 0;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case GREATER_THAN:
|
|
|
|
|
return compare_versions (a, b) > 0;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case LESS_THAN_EQUAL:
|
|
|
|
|
return compare_versions (a, b) <= 0;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case GREATER_THAN_EQUAL:
|
|
|
|
|
return compare_versions (a, b) >= 0;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case EQUAL:
|
|
|
|
|
return compare_versions (a, b) == 0;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case NOT_EQUAL:
|
|
|
|
|
return compare_versions (a, b) != 0;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case ALWAYS_MATCH:
|
|
|
|
|
return TRUE;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
g_assert_not_reached ();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const char *
|
|
|
|
|
comparison_to_str (ComparisonType comparison)
|
|
|
|
|
{
|
|
|
|
|
switch (comparison)
|
|
|
|
|
{
|
|
|
|
|
case LESS_THAN:
|
|
|
|
|
return "<";
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case GREATER_THAN:
|
|
|
|
|
return ">";
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case LESS_THAN_EQUAL:
|
|
|
|
|
return "<=";
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case GREATER_THAN_EQUAL:
|
|
|
|
|
return ">=";
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case EQUAL:
|
|
|
|
|
return "=";
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case NOT_EQUAL:
|
|
|
|
|
return "!=";
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case ALWAYS_MATCH:
|
|
|
|
|
return "(any)";
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
g_assert_not_reached ();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return "???";
|
|
|
|
|
}
|
|
|
|
|
|
2005-07-14 13:04:47 +00:00
|
|
|
static void
|
|
|
|
|
max_len_foreach (gpointer key, gpointer value, gpointer data)
|
|
|
|
|
{
|
|
|
|
|
int *mlen = data;
|
|
|
|
|
|
|
|
|
|
*mlen = MAX (*mlen, strlen (key));
|
|
|
|
|
}
|
|
|
|
|
|
2005-07-14 13:04:01 +00:00
|
|
|
static void
|
|
|
|
|
packages_foreach (gpointer key, gpointer value, gpointer data)
|
|
|
|
|
{
|
|
|
|
|
Package *pkg = get_package (key);
|
|
|
|
|
|
|
|
|
|
if (pkg != NULL)
|
|
|
|
|
{
|
2005-07-14 13:04:47 +00:00
|
|
|
char *pad;
|
|
|
|
|
|
|
|
|
|
pad = g_strnfill (GPOINTER_TO_INT (data) - strlen (pkg->key), ' ');
|
|
|
|
|
|
|
|
|
|
printf ("%s%s%s - %s\n",
|
|
|
|
|
pkg->key, pad, pkg->name, pkg->description);
|
|
|
|
|
|
|
|
|
|
g_free (pad);
|
2005-07-14 13:04:01 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
print_package_list (void)
|
|
|
|
|
{
|
2005-07-14 13:04:47 +00:00
|
|
|
int mlen = 0;
|
2009-03-30 20:40:53 +02:00
|
|
|
|
2005-07-14 13:06:19 +00:00
|
|
|
ignore_requires = TRUE;
|
2009-03-30 20:40:53 +02:00
|
|
|
ignore_requires_private = TRUE;
|
2005-07-14 13:06:19 +00:00
|
|
|
|
2005-07-14 13:04:47 +00:00
|
|
|
g_hash_table_foreach (locations, max_len_foreach, &mlen);
|
|
|
|
|
g_hash_table_foreach (locations, packages_foreach, GINT_TO_POINTER (mlen + 1));
|
2005-07-14 13:04:01 +00:00
|
|
|
}
|
|
|
|
|
|
2005-07-14 13:07:18 +00:00
|
|
|
void
|
|
|
|
|
enable_private_libs(void)
|
|
|
|
|
{
|
|
|
|
|
ignore_private_libs = FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
disable_private_libs(void)
|
|
|
|
|
{
|
|
|
|
|
ignore_private_libs = TRUE;
|
|
|
|
|
}
|
2009-03-30 20:40:53 +02:00
|
|
|
|
2009-03-30 20:49:17 +02:00
|
|
|
void
|
|
|
|
|
enable_requires(void)
|
|
|
|
|
{
|
|
|
|
|
ignore_requires = FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
disable_requires(void)
|
|
|
|
|
{
|
|
|
|
|
ignore_requires = TRUE;
|
|
|
|
|
}
|
2009-03-30 20:40:53 +02:00
|
|
|
|
|
|
|
|
void
|
|
|
|
|
enable_requires_private(void)
|
|
|
|
|
{
|
|
|
|
|
ignore_requires_private = FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
disable_requires_private(void)
|
|
|
|
|
{
|
|
|
|
|
ignore_requires_private = TRUE;
|
|
|
|
|
}
|