2 * Copyright (C) 2001, 2002 Red Hat Inc.
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
38 char *pcsysrootdir = NULL;
39 char *pkg_config_pc_path = NULL;
41 static gboolean want_my_version = FALSE;
42 static gboolean want_version = FALSE;
43 static FlagType pkg_flags = 0;
44 static gboolean want_list = FALSE;
45 static gboolean want_static_lib_list = ENABLE_INDIRECT_DEPS;
46 static gboolean want_short_errors = FALSE;
47 static gboolean want_uninstalled = FALSE;
48 static char *variable_name = NULL;
49 static gboolean want_exists = FALSE;
50 static gboolean want_provides = FALSE;
51 static gboolean want_requires = FALSE;
52 static gboolean want_requires_private = FALSE;
53 static char *required_atleast_version = NULL;
54 static char *required_exact_version = NULL;
55 static char *required_max_version = NULL;
56 static char *required_pkgconfig_version = NULL;
57 static gboolean want_silence_errors = FALSE;
58 static gboolean want_variable_list = FALSE;
59 static gboolean want_debug_spew = FALSE;
60 static gboolean want_verbose_errors = FALSE;
61 static gboolean want_stdout_errors = FALSE;
62 static gboolean output_opt_set = FALSE;
65 debug_spew (const char *format, ...)
71 g_return_if_fail (format != NULL);
76 va_start (args, format);
77 str = g_strdup_vprintf (format, args);
80 if (want_stdout_errors)
92 verbose_error (const char *format, ...)
98 g_return_if_fail (format != NULL);
100 if (!want_verbose_errors)
103 va_start (args, format);
104 str = g_strdup_vprintf (format, args);
107 if (want_stdout_errors)
119 define_variable_cb (const char *opt, const char *arg, gpointer data,
126 tmp = g_strdup (arg);
129 while (*varname && isspace ((guchar)*varname))
133 while (*varval && *varval != '=' && *varval != ' ')
136 while (*varval && (*varval == '=' || *varval == ' '))
144 fprintf (stderr, "--define-variable argument does not have a value "
145 "for the variable\n");
149 define_global_variable (varname, varval);
156 output_opt_cb (const char *opt, const char *arg, gpointer data,
159 static gboolean vercmp_opt_set = FALSE;
161 /* only allow one output mode, with a few exceptions */
164 gboolean bad_opt = TRUE;
166 /* multiple flag options (--cflags --libs-only-l) allowed */
167 if (pkg_flags != 0 &&
168 (strcmp (opt, "--libs") == 0 ||
169 strcmp (opt, "--libs-only-l") == 0 ||
170 strcmp (opt, "--libs-only-other") == 0 ||
171 strcmp (opt, "--libs-only-L") == 0 ||
172 strcmp (opt, "--cflags") == 0 ||
173 strcmp (opt, "--cflags-only-I") == 0 ||
174 strcmp (opt, "--cflags-only-other") == 0))
177 /* --print-requires and --print-requires-private allowed */
178 if ((want_requires && strcmp (opt, "--print-requires-private") == 0) ||
179 (want_requires_private && strcmp (opt, "--print-requires") == 0))
182 /* --exists allowed with --atleast/exact/max-version */
183 if (want_exists && !vercmp_opt_set &&
184 (strcmp (opt, "--atleast-version") == 0 ||
185 strcmp (opt, "--exact-version") == 0 ||
186 strcmp (opt, "--max-version") == 0))
191 fprintf (stderr, "Ignoring incompatible output option \"%s\"\n",
197 if (strcmp (opt, "--version") == 0)
198 want_my_version = TRUE;
199 else if (strcmp (opt, "--modversion") == 0)
201 else if (strcmp (opt, "--libs") == 0)
202 pkg_flags |= LIBS_ANY;
203 else if (strcmp (opt, "--libs-only-l") == 0)
205 else if (strcmp (opt, "--libs-only-other") == 0)
206 pkg_flags |= LIBS_OTHER;
207 else if (strcmp (opt, "--libs-only-L") == 0)
209 else if (strcmp (opt, "--cflags") == 0)
210 pkg_flags |= CFLAGS_ANY;
211 else if (strcmp (opt, "--cflags-only-I") == 0)
212 pkg_flags |= CFLAGS_I;
213 else if (strcmp (opt, "--cflags-only-other") == 0)
214 pkg_flags |= CFLAGS_OTHER;
215 else if (strcmp (opt, "--variable") == 0)
216 variable_name = g_strdup (arg);
217 else if (strcmp (opt, "--exists") == 0)
219 else if (strcmp (opt, "--print-variables") == 0)
220 want_variable_list = TRUE;
221 else if (strcmp (opt, "--uninstalled") == 0)
222 want_uninstalled = TRUE;
223 else if (strcmp (opt, "--atleast-version") == 0)
225 required_atleast_version = g_strdup (arg);
227 vercmp_opt_set = TRUE;
229 else if (strcmp (opt, "--exact-version") == 0)
231 required_exact_version = g_strdup (arg);
233 vercmp_opt_set = TRUE;
235 else if (strcmp (opt, "--max-version") == 0)
237 required_max_version = g_strdup (arg);
239 vercmp_opt_set = TRUE;
241 else if (strcmp (opt, "--list-all") == 0)
243 else if (strcmp (opt, "--print-provides") == 0)
244 want_provides = TRUE;
245 else if (strcmp (opt, "--print-requires") == 0)
246 want_requires = TRUE;
247 else if (strcmp (opt, "--print-requires-private") == 0)
248 want_requires_private = TRUE;
252 output_opt_set = TRUE;
257 pkg_uninstalled (Package *pkg)
259 /* See if > 0 pkgs were uninstalled */
262 if (pkg->uninstalled)
268 Package *pkg = tmp->data;
270 if (pkg_uninstalled (pkg))
273 tmp = g_list_next (tmp);
280 print_hashtable_key (gpointer key,
284 printf("%s\n", (gchar*)key);
291 char *instdir, *lpath, *shpath;
293 instdir = g_win32_get_package_installation_directory_of_module (NULL);
296 /* This only happens when GetModuleFilename() fails. If it does, that
297 * failure should be investigated and fixed.
299 debug_spew ("g_win32_get_package_installation_directory_of_module failed\n");
303 lpath = g_build_filename (instdir, "lib", "pkgconfig", NULL);
304 shpath = g_build_filename (instdir, "share", "pkgconfig", NULL);
305 pkg_config_pc_path = g_strconcat (lpath, G_SEARCHPATH_SEPARATOR_S, shpath,
311 pkg_config_pc_path = PKG_CONFIG_PC_PATH;
316 process_package_args (const char *cmdline, GList **packages, FILE *log)
318 gboolean success = TRUE;
321 reqs = parse_module_list (NULL, cmdline, "(command line arguments)");
324 fprintf (stderr, "Must specify package names on the command line\n");
328 for (; reqs != NULL; reqs = g_list_next (reqs))
331 RequiredVersion *ver = reqs->data;
333 /* override requested versions with cmdline options */
334 if (required_exact_version)
336 g_free (ver->version);
337 ver->comparison = EQUAL;
338 ver->version = g_strdup (required_exact_version);
340 else if (required_atleast_version)
342 g_free (ver->version);
343 ver->comparison = GREATER_THAN_EQUAL;
344 ver->version = g_strdup (required_atleast_version);
346 else if (required_max_version)
348 g_free (ver->version);
349 ver->comparison = LESS_THAN_EQUAL;
350 ver->version = g_strdup (required_max_version);
353 if (want_short_errors)
354 req = get_package_quiet (ver->name);
356 req = get_package (ver->name);
361 fprintf (log, "%s NOT-FOUND\n", ver->name);
363 fprintf (log, "%s %s %s\n", ver->name,
364 comparison_to_str (ver->comparison),
365 (ver->version == NULL) ? "(null)" : ver->version);
371 verbose_error ("No package '%s' found\n", ver->name);
375 if (!version_test (ver->comparison, req->version, ver->version))
378 verbose_error ("Requested '%s %s %s' but version of %s is %s\n",
380 comparison_to_str (ver->comparison),
385 verbose_error ("You may find new versions of %s at %s\n",
386 req->name, req->url);
390 *packages = g_list_prepend (*packages, req);
393 *packages = g_list_reverse (*packages);
398 static const GOptionEntry options_table[] = {
399 { "version", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
400 &output_opt_cb, "output version of pkg-config", NULL },
401 { "modversion", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
402 &output_opt_cb, "output version for package", NULL },
403 { "atleast-pkgconfig-version", 0, 0, G_OPTION_ARG_STRING,
404 &required_pkgconfig_version,
405 "require given version of pkg-config", "VERSION" },
406 { "libs", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, &output_opt_cb,
407 "output all linker flags", NULL },
408 { "static", 0, 0, G_OPTION_ARG_NONE, &want_static_lib_list,
409 "output linker flags for static linking", NULL },
410 { "short-errors", 0, 0, G_OPTION_ARG_NONE, &want_short_errors,
411 "print short errors", NULL },
412 { "libs-only-l", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
413 &output_opt_cb, "output -l flags", NULL },
414 { "libs-only-other", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
415 &output_opt_cb, "output other libs (e.g. -pthread)", NULL },
416 { "libs-only-L", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
417 &output_opt_cb, "output -L flags", NULL },
418 { "cflags", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, &output_opt_cb,
419 "output all pre-processor and compiler flags", NULL },
420 { "cflags-only-I", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
421 &output_opt_cb, "output -I flags", NULL },
422 { "cflags-only-other", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
423 &output_opt_cb, "output cflags not covered by the cflags-only-I option",
425 { "variable", 0, 0, G_OPTION_ARG_CALLBACK, &output_opt_cb,
426 "get the value of variable named NAME", "NAME" },
427 { "define-variable", 0, 0, G_OPTION_ARG_CALLBACK, &define_variable_cb,
428 "set variable NAME to VALUE", "NAME=VALUE" },
429 { "exists", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, &output_opt_cb,
430 "return 0 if the module(s) exist", NULL },
431 { "print-variables", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
432 &output_opt_cb, "output list of variables defined by the module", NULL },
433 { "uninstalled", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
434 &output_opt_cb, "return 0 if the uninstalled version of one or more "
435 "module(s) or their dependencies will be used", NULL },
436 { "atleast-version", 0, 0, G_OPTION_ARG_CALLBACK, &output_opt_cb,
437 "return 0 if the module is at least version VERSION", "VERSION" },
438 { "exact-version", 0, 0, G_OPTION_ARG_CALLBACK, &output_opt_cb,
439 "return 0 if the module is at exactly version VERSION", "VERSION" },
440 { "max-version", 0, 0, G_OPTION_ARG_CALLBACK, &output_opt_cb,
441 "return 0 if the module is at no newer than version VERSION", "VERSION" },
442 { "list-all", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
443 &output_opt_cb, "list all known packages", NULL },
444 { "debug", 0, 0, G_OPTION_ARG_NONE, &want_debug_spew,
445 "show verbose debug information", NULL },
446 { "print-errors", 0, 0, G_OPTION_ARG_NONE, &want_verbose_errors,
447 "show verbose information about missing or conflicting packages "
448 "(default unless --exists or --atleast/exact/max-version given on the "
449 "command line)", NULL },
450 { "silence-errors", 0, 0, G_OPTION_ARG_NONE, &want_silence_errors,
451 "be silent about errors (default when --exists or "
452 "--atleast/exact/max-version given on the command line)", NULL },
453 { "errors-to-stdout", 0, 0, G_OPTION_ARG_NONE, &want_stdout_errors,
454 "print errors from --print-errors to stdout not stderr", NULL },
455 { "print-provides", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
456 &output_opt_cb, "print which packages the package provides", NULL },
457 { "print-requires", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
458 &output_opt_cb, "print which packages the package requires", NULL },
459 { "print-requires-private", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
460 &output_opt_cb, "print which packages the package requires for static "
463 { "dont-define-prefix", 0, 0, G_OPTION_ARG_NONE, &dont_define_prefix,
464 "don't try to override the value of prefix for each .pc file found with "
465 "a guesstimated value based on the location of the .pc file", NULL },
466 { "prefix-variable", 0, 0, G_OPTION_ARG_STRING, &prefix_variable,
467 "set the name of the variable that pkg-config automatically sets",
469 { "msvc-syntax", 0, 0, G_OPTION_ARG_NONE, &msvc_syntax,
470 "output -l and -L flags for the Microsoft compiler (cl)", NULL },
472 { NULL, 0, 0, 0, NULL, NULL, NULL }
476 main (int argc, char **argv)
479 GList *packages = NULL;
482 gboolean need_newline;
484 GError *error = NULL;
485 GOptionContext *opt_context;
487 /* This is here so that we get debug spew from the start,
490 if (getenv ("PKG_CONFIG_DEBUG_SPEW"))
492 want_debug_spew = TRUE;
493 want_verbose_errors = TRUE;
494 want_silence_errors = FALSE;
495 debug_spew ("PKG_CONFIG_DEBUG_SPEW variable enabling debug spew\n");
499 /* Get the built-in search path */
501 if (pkg_config_pc_path == NULL)
503 /* Even when we override the built-in search path, we still use it later
504 * to add pc_path to the virtual pkg-config package.
506 verbose_error ("Failed to get default search path\n");
510 search_path = getenv ("PKG_CONFIG_PATH");
513 add_search_dirs(search_path, G_SEARCHPATH_SEPARATOR_S);
515 if (getenv("PKG_CONFIG_LIBDIR") != NULL)
517 add_search_dirs(getenv("PKG_CONFIG_LIBDIR"), G_SEARCHPATH_SEPARATOR_S);
521 add_search_dirs(pkg_config_pc_path, G_SEARCHPATH_SEPARATOR_S);
524 pcsysrootdir = getenv ("PKG_CONFIG_SYSROOT_DIR");
527 define_global_variable ("pc_sysrootdir", pcsysrootdir);
531 define_global_variable ("pc_sysrootdir", "/");
534 pcbuilddir = getenv ("PKG_CONFIG_TOP_BUILD_DIR");
537 define_global_variable ("pc_top_builddir", pcbuilddir);
541 /* Default appropriate for automake */
542 define_global_variable ("pc_top_builddir", "$(top_builddir)");
545 if (getenv ("PKG_CONFIG_DISABLE_UNINSTALLED"))
547 debug_spew ("disabling auto-preference for uninstalled packages\n");
548 disable_uninstalled = TRUE;
552 opt_context = g_option_context_new (NULL);
553 g_option_context_add_main_entries (opt_context, options_table, NULL);
554 if (!g_option_context_parse(opt_context, &argc, &argv, &error))
556 fprintf (stderr, "%s\n", error->message);
560 /* If no output option was set, then --exists is the default. */
563 debug_spew ("no output option set, defaulting to --exists\n");
567 /* Error printing is determined as follows:
568 * - for all output options besides --exists and --*-version,
569 * it's on by default and --silence-errors can turn it off
570 * - for --exists, --*-version, etc. and no options at all,
571 * it's off by default and --print-errors will turn it on
575 debug_spew ("Error printing enabled by default due to use of output "
576 "options besides --exists or --atleast/exact/max-version. "
577 "Value of --silence-errors: %d\n",
578 want_silence_errors);
580 if (want_silence_errors && getenv ("PKG_CONFIG_DEBUG_SPEW") == NULL)
581 want_verbose_errors = FALSE;
583 want_verbose_errors = TRUE;
587 debug_spew ("Error printing disabled by default due to use of output "
588 "options --exists, --atleast/exact/max-version or no "
589 "output option at all. Value of --print-errors: %d\n",
590 want_verbose_errors);
592 /* Leave want_verbose_errors unchanged, reflecting --print-errors */
595 if (want_verbose_errors)
596 debug_spew ("Error printing enabled\n");
598 debug_spew ("Error printing disabled\n");
600 if (want_static_lib_list)
601 enable_private_libs();
603 disable_private_libs();
605 /* honor Requires.private if any Cflags are requested or any static
606 * libs are requested */
608 if (pkg_flags & CFLAGS_ANY || want_requires_private || want_exists ||
609 (want_static_lib_list && (pkg_flags & LIBS_ANY)))
610 enable_requires_private();
612 /* ignore Requires if no Cflags or Libs are requested */
614 if (pkg_flags == 0 && !want_requires && !want_exists)
619 printf ("%s\n", VERSION);
623 if (required_pkgconfig_version)
625 if (compare_versions (VERSION, required_pkgconfig_version) >= 0)
635 print_package_list ();
639 /* Collect packages from remaining args */
640 str = g_string_new ("");
646 g_string_append (str, *argv);
647 g_string_append (str, " ");
650 g_option_context_free (opt_context);
652 g_strstrip (str->str);
654 if (getenv("PKG_CONFIG_LOG") != NULL)
656 log = fopen (getenv ("PKG_CONFIG_LOG"), "a");
659 fprintf (stderr, "Cannot open log file: %s\n",
660 getenv ("PKG_CONFIG_LOG"));
665 /* find and parse each of the packages specified */
666 if (!process_package_args (str->str, &packages, log))
672 g_string_free (str, TRUE);
675 return 0; /* if we got here, all the packages existed. */
677 if (want_variable_list)
683 Package *pkg = tmp->data;
684 if (pkg->vars != NULL)
685 g_hash_table_foreach(pkg->vars,
686 &print_hashtable_key,
688 tmp = g_list_next (tmp);
689 if (tmp) printf ("\n");
691 need_newline = FALSE;
694 if (want_uninstalled)
696 /* See if > 0 pkgs (including dependencies recursively) were uninstalled */
701 Package *pkg = tmp->data;
703 if (pkg_uninstalled (pkg))
706 tmp = g_list_next (tmp);
718 Package *pkg = tmp->data;
720 printf ("%s\n", pkg->version);
722 tmp = g_list_next (tmp);
732 Package *pkg = tmp->data;
738 printf ("%s = %s\n", key, pkg->version);
739 tmp = g_list_next (tmp);
746 for (pkgtmp = packages; pkgtmp != NULL; pkgtmp = g_list_next (pkgtmp))
748 Package *pkg = pkgtmp->data;
751 /* process Requires: */
752 for (reqtmp = pkg->requires; reqtmp != NULL; reqtmp = g_list_next (reqtmp))
754 Package *deppkg = reqtmp->data;
755 RequiredVersion *req;
756 req = g_hash_table_lookup(pkg->required_versions, deppkg->key);
757 if ((req == NULL) || (req->comparison == ALWAYS_MATCH))
758 printf ("%s\n", deppkg->key);
760 printf ("%s %s %s\n", deppkg->key,
761 comparison_to_str(req->comparison),
766 if (want_requires_private)
769 for (pkgtmp = packages; pkgtmp != NULL; pkgtmp = g_list_next (pkgtmp))
771 Package *pkg = pkgtmp->data;
773 /* process Requires.private: */
774 for (reqtmp = pkg->requires_private; reqtmp != NULL; reqtmp = g_list_next (reqtmp))
777 Package *deppkg = reqtmp->data;
778 RequiredVersion *req;
780 if (g_list_find (pkg->requires, reqtmp->data))
783 req = g_hash_table_lookup(pkg->required_versions, deppkg->key);
784 if ((req == NULL) || (req->comparison == ALWAYS_MATCH))
785 printf ("%s\n", deppkg->key);
787 printf ("%s %s %s\n", deppkg->key,
788 comparison_to_str(req->comparison),
794 /* Print all flags; then print a newline at the end. */
795 need_newline = FALSE;
799 char *str = packages_get_var (packages, variable_name);
807 char *str = packages_get_flags (packages, pkg_flags);