2005-07-14 13:04:01 +00:00
# ifdef HAVE_CONFIG_H
# include "config.h"
# endif
# include "pkg.h"
# include "parse.h"
# include "popt.h"
# include <stdlib.h>
# include <string.h>
# include <ctype.h>
# include <stdio.h>
static int want_debug_spew = 0 ;
static int want_verbose_errors = 0 ;
2005-07-14 13:04:10 +00:00
static int want_stdout_errors = 0 ;
2005-07-14 13:04:01 +00:00
void
debug_spew ( const char * format , . . . )
{
va_list args ;
gchar * str ;
2005-07-14 13:04:10 +00:00
FILE * stream ;
2005-07-14 13:04:01 +00:00
g_return_if_fail ( format ! = NULL ) ;
if ( ! want_debug_spew )
return ;
va_start ( args , format ) ;
str = g_strdup_vprintf ( format , args ) ;
va_end ( args ) ;
2005-07-14 13:04:10 +00:00
if ( want_stdout_errors )
stream = stdout ;
else
stream = stderr ;
fputs ( str , stream ) ;
fflush ( stream ) ;
2005-07-14 13:04:01 +00:00
g_free ( str ) ;
}
void
verbose_error ( const char * format , . . . )
{
va_list args ;
gchar * str ;
g_return_if_fail ( format ! = NULL ) ;
if ( ! want_verbose_errors )
return ;
va_start ( args , format ) ;
str = g_strdup_vprintf ( format , args ) ;
va_end ( args ) ;
fputs ( str , stderr ) ;
fflush ( stdout ) ;
g_free ( str ) ;
}
# define DEFINE_VARIABLE 1
static void
popt_callback ( poptContext con ,
enum poptCallbackReason reason ,
const struct poptOption * opt ,
const char * arg , void * data )
{
2005-07-14 13:04:19 +00:00
debug_spew ( " Option --%s seen \n " , opt - > longName ) ;
2005-07-14 13:04:01 +00:00
if ( opt - > val = = DEFINE_VARIABLE )
{
char * varname ;
char * varval ;
char * tmp ;
tmp = g_strdup ( arg ) ;
varname = tmp ;
while ( * varname & & isspace ( * varname ) )
+ + varname ;
varval = varname ;
while ( * varval & & * varval ! = ' = ' & & * varval ! = ' ' )
+ + varval ;
while ( * varval & & ( * varval = = ' = ' | | * varval = = ' ' ) )
{
* varval = ' \0 ' ;
+ + varval ;
}
if ( * varval = = ' \0 ' )
{
fprintf ( stderr , " --define-variable argument does not have a value for the variable \n " ) ;
exit ( 1 ) ;
}
define_global_variable ( varname , varval ) ;
g_free ( tmp ) ;
}
}
static gboolean
pkg_uninstalled ( Package * pkg )
{
/* See if > 0 pkgs were uninstalled */
GSList * tmp ;
if ( pkg - > uninstalled )
return TRUE ;
tmp = pkg - > requires ;
while ( tmp ! = NULL )
{
Package * pkg = tmp - > data ;
if ( pkg_uninstalled ( pkg ) )
return TRUE ;
tmp = g_slist_next ( tmp ) ;
}
return FALSE ;
}
int
main ( int argc , char * * argv )
{
static int want_my_version = 0 ;
static int want_version = 0 ;
static int want_libs = 0 ;
static int want_cflags = 0 ;
static int want_l_libs = 0 ;
static int want_L_libs = 0 ;
static int want_I_cflags = 0 ;
static int want_list = 0 ;
static int result ;
static int want_uninstalled = 0 ;
static char * variable_name = NULL ;
static int want_exists = 0 ;
static char * required_atleast_version = NULL ;
static char * required_exact_version = NULL ;
static char * required_max_version = NULL ;
static char * required_pkgconfig_version = NULL ;
static int want_silence_errors = 0 ;
GString * str ;
GSList * packages = NULL ;
char * search_path ;
char * pcbuilddir ;
gboolean need_newline ;
const char * pkgname ;
Package * pkg ;
poptContext opt_context ;
struct poptOption options_table [ ] = {
{ NULL , 0 , POPT_ARG_CALLBACK , popt_callback , 0 , NULL , NULL } ,
{ " version " , 0 , POPT_ARG_NONE , & want_my_version , 0 ,
" output version of pkg-config " } ,
{ " modversion " , 0 , POPT_ARG_NONE , & want_version , 0 ,
" output version for package " } ,
{ " atleast-pkgconfig-version " , 0 , POPT_ARG_STRING , & required_pkgconfig_version , 0 ,
" require given version of pkg-config " , " VERSION " } ,
{ " libs " , 0 , POPT_ARG_NONE , & want_libs , 0 ,
" output all linker flags " } ,
{ " libs-only-l " , 0 , POPT_ARG_NONE , & want_l_libs , 0 ,
" output -l flags " } ,
{ " libs-only-L " , 0 , POPT_ARG_NONE , & want_L_libs , 0 ,
" output -L flags " } ,
{ " cflags " , 0 , POPT_ARG_NONE , & want_cflags , 0 ,
" output all pre-processor and compiler flags " } ,
{ " cflags-only-I " , 0 , POPT_ARG_NONE , & want_I_cflags , 0 ,
" output -I flags " } ,
{ " variable " , 0 , POPT_ARG_STRING , & variable_name , 0 ,
" get the value of a variable " , " VARIABLENAME " } ,
{ " define-variable " , 0 , POPT_ARG_STRING , NULL , DEFINE_VARIABLE ,
" set the value of a variable " , " VARIABLENAME=VARIABLEVALUE " } ,
{ " exists " , 0 , POPT_ARG_NONE , & want_exists , 0 ,
" return 0 if the module(s) exist " } ,
{ " uninstalled " , 0 , POPT_ARG_NONE , & want_uninstalled , 0 ,
" return 0 if the uninstalled version of one or more module(s) or their dependencies will be used " } ,
{ " atleast-version " , 0 , POPT_ARG_STRING , & required_atleast_version , 0 ,
" return 0 if the module is at least version VERSION " , " VERSION " } ,
{ " exact-version " , 0 , POPT_ARG_STRING , & required_exact_version , 0 ,
" return 0 if the module is at exactly version VERSION " , " VERSION " } ,
{ " max-version " , 0 , POPT_ARG_STRING , & required_max_version , 0 ,
" return 0 if the module is at no newer than version VERSION " , " VERSION " } ,
{ " list-all " , 0 , POPT_ARG_NONE , & want_list , 0 ,
" list all known packages " } ,
{ " debug " , 0 , POPT_ARG_NONE , & want_debug_spew , 0 ,
" show verbose debug information " } ,
{ " print-errors " , 0 , POPT_ARG_NONE , & want_verbose_errors , 0 ,
" show verbose information about missing or conflicting packages " } ,
{ " silence-errors " , 0 , POPT_ARG_NONE , & want_silence_errors , 0 ,
" show verbose information about missing or conflicting packages " } ,
2005-07-14 13:04:10 +00:00
{ " errors-to-stdout " , 0 , POPT_ARG_NONE , & want_stdout_errors , 0 ,
" print errors from --print-errors to stdout not stderr " } ,
2005-07-14 13:04:01 +00:00
POPT_AUTOHELP
{ NULL , 0 , 0 , NULL , 0 }
} ;
/* This is here so that we get debug spew from the start,
* during arg parsing
*/
if ( getenv ( " PKG_CONFIG_DEBUG_SPEW " ) )
{
want_debug_spew = TRUE ;
want_verbose_errors = TRUE ;
want_silence_errors = FALSE ;
2005-07-14 13:04:19 +00:00
debug_spew ( " PKG_CONFIG_DEBUG_SPEW variable enabling debug spew \n " ) ;
2005-07-14 13:04:01 +00:00
}
search_path = getenv ( " PKG_CONFIG_PATH " ) ;
if ( search_path )
{
char * * search_dirs ;
char * * iter ;
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
search_dirs = g_strsplit ( search_path , G_SEARCHPATH_SEPARATOR_S , - 1 ) ;
2005-07-14 13:04:01 +00:00
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 ) ;
}
pcbuilddir = getenv ( " PKG_CONFIG_TOP_BUILD_DIR " ) ;
if ( pcbuilddir )
{
define_global_variable ( " pc_top_builddir " , pcbuilddir ) ;
}
else
{
/* Default appropriate for automake */
define_global_variable ( " pc_top_builddir " , " $(top_builddir) " ) ;
}
if ( getenv ( " PKG_CONFIG_DISABLE_UNINSTALLED " ) )
{
debug_spew ( " disabling auto-preference for uninstalled packages \n " ) ;
disable_uninstalled = TRUE ;
}
opt_context = poptGetContext ( NULL , argc , argv ,
options_table , 0 ) ;
result = poptGetNextOpt ( opt_context ) ;
if ( result ! = - 1 )
{
fprintf ( stderr , " %s: %s \n " ,
poptBadOption ( opt_context , POPT_BADOPTION_NOALIAS ) ,
poptStrerror ( result ) ) ;
return 1 ;
}
/* Error printing is determined as follows:
* - for - - cflags , - - libs , etc . it ' s on by default
* and - - silence - errors can turn it off
* - for - - exists , - - max - version , etc . and no options
* at all , it ' s off by default and - - print - errors
* will turn it on
*/
if ( want_my_version | |
want_version | |
want_libs | |
want_cflags | |
want_l_libs | |
want_L_libs | |
want_I_cflags | |
want_list )
{
2005-07-14 13:04:19 +00:00
debug_spew ( " Error printing enabled by default due to use of --version, --libs, --cflags, --libs-only-l, --libs-only-L, --cflags-only-I, or --list. Value of --silence-errors: %d \n " , want_silence_errors ) ;
2005-07-14 13:04:01 +00:00
if ( want_silence_errors & & getenv ( " PKG_CONFIG_DEBUG_SPEW " ) = = NULL )
want_verbose_errors = FALSE ;
else
want_verbose_errors = TRUE ;
}
else
{
2005-07-14 13:04:19 +00:00
debug_spew ( " Error printing disabled by default, value of --print-errors: %d \n " ,
want_verbose_errors ) ;
2005-07-14 13:04:01 +00:00
/* Leave want_verbose_errors unchanged, reflecting --print-errors */
2005-07-14 13:04:19 +00:00
}
if ( want_verbose_errors )
debug_spew ( " Error printing enabled \n " ) ;
else
debug_spew ( " Error printing disabled \n " ) ;
2005-07-14 13:04:01 +00:00
if ( want_my_version )
{
printf ( " %s \n " , VERSION ) ;
return 0 ;
}
if ( required_pkgconfig_version )
{
if ( compare_versions ( VERSION , required_pkgconfig_version ) > = 0 )
return 0 ;
else
return 1 ;
}
package_init ( ) ;
if ( want_list )
{
print_package_list ( ) ;
return 0 ;
}
str = g_string_new ( " " ) ;
while ( 1 )
{
pkgname = poptGetArg ( opt_context ) ;
if ( pkgname = = NULL )
break ;
g_string_append ( str , pkgname ) ;
g_string_append ( str , " " ) ;
}
g_strstrip ( str - > str ) ;
{
GSList * reqs ;
GSList * iter ;
reqs = parse_module_list ( NULL , str - > str ,
" (command line arguments) " ) ;
iter = reqs ;
while ( iter ! = NULL )
{
Package * req ;
RequiredVersion * ver = iter - > data ;
req = get_package ( ver - > name ) ;
if ( req = = NULL )
{
verbose_error ( " No package '%s' found \n " , ver - > name ) ;
return 1 ;
}
if ( ! version_test ( ver - > comparison , req - > version , ver - > version ) )
{
verbose_error ( " Requested '%s %s %s' but version of %s is %s \n " ,
ver - > name ,
comparison_to_str ( ver - > comparison ) ,
ver - > version ,
req - > name ,
req - > version ) ;
return 1 ;
}
packages = g_slist_prepend ( packages , req ) ;
iter = g_slist_next ( iter ) ;
}
}
g_string_free ( str , TRUE ) ;
packages = g_slist_reverse ( packages ) ;
if ( packages = = NULL )
{
fprintf ( stderr , " Must specify package names on the command line \n " ) ;
exit ( 1 ) ;
}
if ( want_exists )
return 0 ; /* if we got here, all the packages existed. */
if ( want_uninstalled )
{
/* See if > 0 pkgs (including dependencies recursively) were uninstalled */
GSList * tmp ;
tmp = packages ;
while ( tmp ! = NULL )
{
Package * pkg = tmp - > data ;
if ( pkg_uninstalled ( pkg ) )
return 0 ;
tmp = g_slist_next ( tmp ) ;
}
return 1 ;
}
if ( want_version )
{
GSList * tmp ;
tmp = packages ;
while ( tmp ! = NULL )
{
Package * pkg = tmp - > data ;
printf ( " %s \n " , pkg - > version ) ;
tmp = g_slist_next ( tmp ) ;
}
}
if ( required_exact_version )
{
Package * pkg = packages - > data ;
if ( compare_versions ( pkg - > version , required_exact_version ) = = 0 )
return 0 ;
else
return 1 ;
}
else if ( required_atleast_version )
{
Package * pkg = packages - > data ;
if ( compare_versions ( pkg - > version , required_atleast_version ) > = 0 )
return 0 ;
else
return 1 ;
}
else if ( required_max_version )
{
Package * pkg = packages - > data ;
if ( compare_versions ( pkg - > version , required_max_version ) < = 0 )
return 0 ;
else
return 1 ;
}
/* Print all flags; then print a newline at the end. */
need_newline = FALSE ;
if ( variable_name )
{
char * str = packages_get_var ( packages , variable_name ) ;
printf ( " %s " , str ) ;
g_free ( str ) ;
need_newline = TRUE ;
}
if ( want_I_cflags )
{
char * str = packages_get_I_cflags ( packages ) ;
printf ( " %s " , str ) ;
g_free ( str ) ;
need_newline = TRUE ;
}
else if ( want_cflags )
{
char * str = packages_get_all_cflags ( packages ) ;
printf ( " %s " , str ) ;
g_free ( str ) ;
need_newline = TRUE ;
}
if ( want_l_libs )
{
char * str = packages_get_l_libs ( packages ) ;
printf ( " %s " , str ) ;
g_free ( str ) ;
need_newline = TRUE ;
}
else if ( want_L_libs )
{
char * str = packages_get_L_libs ( packages ) ;
printf ( " %s " , str ) ;
g_free ( str ) ;
need_newline = TRUE ;
}
else if ( want_libs )
{
char * str = packages_get_all_libs ( packages ) ;
printf ( " %s " , str ) ;
g_free ( str ) ;
need_newline = TRUE ;
}
if ( need_newline )
printf ( " \n " ) ;
return 0 ;
}