]> err.no Git - pkg-config/blob - main.c
Print out \r\n on windows, not just \n
[pkg-config] / main.c
1 /*
2  * Copyright (C) 2001, 2002 Red Hat Inc.
3  *
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.
8  *
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.
13  *
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
17  * 02111-1307, USA.
18  */
19
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include "pkg.h"
25 #include "parse.h"
26
27 #include "popt.h"
28 #include <stdlib.h>
29 #include <string.h>
30 #include <ctype.h>
31 #include <stdio.h>
32
33 #ifdef G_OS_WIN32
34 #define STRICT
35 #include <windows.h>
36 #undef STRICT
37 #endif
38
39 static int want_debug_spew = 0;
40 static int want_verbose_errors = 0;
41 static int want_stdout_errors = 0;
42 char *pcsysrootdir = NULL;
43
44 void
45 debug_spew (const char *format, ...)
46 {
47   va_list args;
48   gchar *str;
49   FILE* stream;
50
51   g_return_if_fail (format != NULL);
52
53   if (!want_debug_spew)
54     return;
55
56   va_start (args, format);
57   str = g_strdup_vprintf (format, args);
58   va_end (args);
59
60   if (want_stdout_errors)
61     stream = stdout;
62   else
63     stream = stderr;
64
65   fputs (str, stream);
66   fflush (stream);
67
68   g_free (str);
69 }
70
71 void
72 verbose_error (const char *format, ...)
73 {
74   va_list args;
75   gchar *str;
76   FILE* stream;
77   
78   g_return_if_fail (format != NULL);
79
80   if (!want_verbose_errors)
81     return;
82
83   va_start (args, format);
84   str = g_strdup_vprintf (format, args);
85   va_end (args);
86
87   if (want_stdout_errors)
88     stream = stdout;
89   else
90     stream = stderr;
91   
92   fputs (str, stream);
93   fflush (stream);
94
95   g_free (str);
96 }
97
98 #define DEFINE_VARIABLE 1
99
100 static void
101 popt_callback (poptContext con,
102                enum poptCallbackReason reason,
103                const struct poptOption * opt,
104                const char * arg, void * data)
105 {
106   debug_spew ("Option --%s seen\n", opt->longName);
107
108   if (opt->val == DEFINE_VARIABLE)
109     {
110       char *varname;
111       char *varval;
112       char *tmp;
113
114       tmp = g_strdup (arg);
115
116       varname = tmp;
117       while (*varname && isspace ((guchar)*varname))
118         ++varname;
119
120       varval = varname;
121       while (*varval && *varval != '=' && *varval != ' ')
122         ++varval;
123
124       while (*varval && (*varval == '=' || *varval == ' '))
125         {
126           *varval = '\0';
127           ++varval;
128         }
129
130       if (*varval == '\0')
131         {
132           fprintf (stderr, "--define-variable argument does not have a value for the variable\n");
133
134           exit (1);
135         }
136
137       define_global_variable (varname, varval);
138
139       g_free (tmp);
140     }
141 }
142
143 static gboolean
144 pkg_uninstalled (Package *pkg)
145 {
146   /* See if > 0 pkgs were uninstalled */
147   GSList *tmp;
148
149   if (pkg->uninstalled)
150     return TRUE;
151
152   tmp = pkg->requires;
153   while (tmp != NULL)
154     {
155       Package *pkg = tmp->data;
156
157       if (pkg_uninstalled (pkg))
158         return TRUE;
159
160       tmp = g_slist_next (tmp);
161     }
162
163   return FALSE;
164 }
165
166 int
167 main (int argc, char **argv)
168 {
169   static int want_my_version = 0;
170   static int want_version = 0;
171   static int want_libs = 0;
172   static int want_cflags = 0;
173   static int want_l_libs = 0;
174   static int want_L_libs = 0;
175   static int want_other_libs = 0;
176   static int want_I_cflags = 0;
177   static int want_other_cflags = 0;
178   static int want_list = 0;
179   static int want_static_lib_list = ENABLE_INDIRECT_DEPS;
180   static int want_short_errors = 0;
181   static int want_uninstalled = 0;
182   static char *variable_name = NULL;
183   static int want_exists = 0;
184   static char *required_atleast_version = NULL;
185   static char *required_exact_version = NULL;
186   static char *required_max_version = NULL;
187   static char *required_pkgconfig_version = NULL;
188   static int want_silence_errors = 0;
189   int result;
190   GString *str;
191   GSList *packages = NULL;
192   char *search_path;
193   char *pcbuilddir;
194   const char *pkglibdir;
195   char **search_dirs;
196   char **iter;
197   gboolean need_newline;
198   FILE *log = NULL;
199   const char *pkgname;
200   Package *pkg;
201
202   poptContext opt_context;
203
204   struct poptOption options_table[] = {
205     { NULL, 0, POPT_ARG_CALLBACK, popt_callback, 0, NULL, NULL },
206     { "version", 0, POPT_ARG_NONE, &want_my_version, 0,
207       "output version of pkg-config" },
208     { "modversion", 0, POPT_ARG_NONE, &want_version, 0,
209       "output version for package" },
210     { "atleast-pkgconfig-version", 0, POPT_ARG_STRING, &required_pkgconfig_version, 0,
211       "require given version of pkg-config", "VERSION" },
212     { "libs", 0, POPT_ARG_NONE, &want_libs, 0,
213       "output all linker flags" },
214     { "static", 0, POPT_ARG_NONE, &want_static_lib_list, 0,
215       "output linker flags for static linking" },
216     { "short-errors", 0, POPT_ARG_NONE, &want_short_errors, 0,
217       "print short errors" },
218     { "libs-only-l", 0, POPT_ARG_NONE, &want_l_libs, 0,
219       "output -l flags" },
220     { "libs-only-other", 0, POPT_ARG_NONE, &want_other_libs, 0,
221       "output other libs (e.g. -pthread)" },
222     { "libs-only-L", 0, POPT_ARG_NONE, &want_L_libs, 0,
223       "output -L flags" },
224     { "cflags", 0, POPT_ARG_NONE, &want_cflags, 0,
225       "output all pre-processor and compiler flags" },
226     { "cflags-only-I", 0, POPT_ARG_NONE, &want_I_cflags, 0,
227       "output -I flags" },
228     { "cflags-only-other", 0, POPT_ARG_NONE, &want_other_cflags, 0,
229       "output cflags not covered by the cflags-only-I option"},
230     { "variable", 0, POPT_ARG_STRING, &variable_name, 0,
231       "get the value of variable named NAME", "NAME" },
232     { "define-variable", 0, POPT_ARG_STRING, NULL, DEFINE_VARIABLE,
233       "set variable NAME to VALUE", "NAME=VALUE" },
234     { "exists", 0, POPT_ARG_NONE, &want_exists, 0,
235       "return 0 if the module(s) exist" },
236     { "uninstalled", 0, POPT_ARG_NONE, &want_uninstalled, 0,
237       "return 0 if the uninstalled version of one or more module(s) or their dependencies will be used" },
238     { "atleast-version", 0, POPT_ARG_STRING, &required_atleast_version, 0,
239       "return 0 if the module is at least version VERSION", "VERSION" },
240     { "exact-version", 0, POPT_ARG_STRING, &required_exact_version, 0,
241       "return 0 if the module is at exactly version VERSION", "VERSION" },
242     { "max-version", 0, POPT_ARG_STRING, &required_max_version, 0,
243       "return 0 if the module is at no newer than version VERSION", "VERSION" },
244     { "list-all", 0, POPT_ARG_NONE, &want_list, 0,
245       "list all known packages" },
246     { "debug", 0, POPT_ARG_NONE, &want_debug_spew, 0,
247       "show verbose debug information" },
248     { "print-errors", 0, POPT_ARG_NONE, &want_verbose_errors, 0,
249       "show verbose information about missing or conflicting packages,"
250       "default if --cflags or --libs given on the command line" },
251     { "silence-errors", 0, POPT_ARG_NONE, &want_silence_errors, 0,
252       "be silent about errors (default unless --cflags or --libs"
253       "given on the command line)" },
254     { "errors-to-stdout", 0, POPT_ARG_NONE, &want_stdout_errors, 0,
255       "print errors from --print-errors to stdout not stderr" },
256 #ifdef G_OS_WIN32
257     { "dont-define-prefix", 0, POPT_ARG_NONE, &dont_define_prefix, 0,
258       "don't try to override the value of prefix for each .pc file found with "
259       "a guesstimated value based on the location of the .pc file" },
260     { "prefix-variable", 0, POPT_ARG_STRING, &prefix_variable, 0,
261       "set the name of the variable that pkg-config automatically sets", "PREFIX" },
262     { "msvc-syntax", 0, POPT_ARG_NONE, &msvc_syntax, 0,
263       "output -l and -L flags for the Microsoft compiler (cl)" },
264 #endif
265     POPT_AUTOHELP
266     { NULL, 0, 0, NULL, 0 }
267   };
268
269   /* This is here so that we get debug spew from the start,
270    * during arg parsing
271    */
272   if (getenv ("PKG_CONFIG_DEBUG_SPEW"))
273     {
274       want_debug_spew = TRUE;
275       want_verbose_errors = TRUE;
276       want_silence_errors = FALSE;
277       debug_spew ("PKG_CONFIG_DEBUG_SPEW variable enabling debug spew\n");
278     }
279
280   search_path = getenv ("PKG_CONFIG_PATH");
281   if (search_path) 
282     {
283       add_search_dirs(search_path, G_SEARCHPATH_SEPARATOR_S);
284     }
285   if (getenv("PKG_CONFIG_LIBDIR") != NULL) 
286     {
287       add_search_dirs(getenv("PKG_CONFIG_LIBDIR"), G_SEARCHPATH_SEPARATOR_S);
288     }
289   else
290     {
291       add_search_dirs(PKG_CONFIG_PC_PATH, G_SEARCHPATH_SEPARATOR_S);
292     }
293
294   pcsysrootdir = getenv ("PKG_CONFIG_SYSROOT_DIR");
295   if (pcsysrootdir)
296     {
297       define_global_variable ("pc_sysrootdir", pcsysrootdir);
298     }
299   else
300     {
301       define_global_variable ("pc_sysrootdir", "/");
302     }
303
304   pcbuilddir = getenv ("PKG_CONFIG_TOP_BUILD_DIR");
305   if (pcbuilddir)
306     {
307       define_global_variable ("pc_top_builddir", pcbuilddir);
308     }
309   else
310     {
311       /* Default appropriate for automake */
312       define_global_variable ("pc_top_builddir", "$(top_builddir)");
313     }
314
315   if (getenv ("PKG_CONFIG_DISABLE_UNINSTALLED"))
316     {
317       debug_spew ("disabling auto-preference for uninstalled packages\n");
318       disable_uninstalled = TRUE;
319     }
320
321   opt_context = poptGetContext (NULL, argc, argv,
322                                 options_table, 0);
323
324   result = poptGetNextOpt (opt_context);
325   if (result != -1)
326     {
327       fprintf(stderr, "%s: %s\n",
328               poptBadOption(opt_context, POPT_BADOPTION_NOALIAS),
329               poptStrerror(result));
330       return 1;
331     }
332
333
334   /* Error printing is determined as follows:
335    *     - for --cflags, --libs, etc. it's on by default
336    *       and --silence-errors can turn it off
337    *     - for --exists, --max-version, etc. and no options
338    *       at all, it's off by default and --print-errors
339    *       will turn it on
340    */
341
342   if (want_my_version ||
343       want_version ||
344       want_libs ||
345       want_cflags ||
346       want_l_libs ||
347       want_L_libs ||
348       want_other_libs ||
349       want_I_cflags ||
350       want_other_cflags ||
351       want_list)
352     {
353       debug_spew ("Error printing enabled by default due to use of --version, --libs, --cflags, --libs-only-l, --libs-only-L, --libs-only-other, --cflags-only-I, --cflags-only-other or --list. Value of --silence-errors: %d\n", want_silence_errors);
354
355       if (want_silence_errors && getenv ("PKG_CONFIG_DEBUG_SPEW") == NULL)
356         want_verbose_errors = FALSE;
357       else
358         want_verbose_errors = TRUE;
359     }
360   else
361     {
362       debug_spew ("Error printing disabled by default, value of --print-errors: %d\n",
363                   want_verbose_errors);
364
365       /* Leave want_verbose_errors unchanged, reflecting --print-errors */
366     }
367
368   if (want_verbose_errors)
369     debug_spew ("Error printing enabled\n");
370   else
371     debug_spew ("Error printing disabled\n");
372
373   if (want_static_lib_list)
374     enable_private_libs();
375   else
376     disable_private_libs();
377
378   /* honor Requires.private if any Cflags are requested or any static
379    * libs are requested */
380
381   if (want_I_cflags || want_other_cflags || want_cflags ||
382       (want_static_lib_list && (want_libs || want_l_libs || want_L_libs)))
383     enable_requires_private();
384
385   /* ignore Requires if no Cflags or Libs are requested */
386
387   if (!want_I_cflags && !want_other_cflags && !want_cflags &&
388       !want_libs && !want_l_libs && !want_L_libs)
389     disable_requires();
390
391   if (want_my_version)
392     {
393       printf ("%s\n", VERSION);
394       return 0;
395     }
396
397   if (required_pkgconfig_version)
398     {
399       if (compare_versions (VERSION, required_pkgconfig_version) >= 0)
400         return 0;
401       else
402         return 1;
403     }
404
405   package_init ();
406
407   if (want_list)
408     {
409       print_package_list ();
410       return 0;
411     }
412
413   str = g_string_new ("");
414   while (1)
415     {
416       pkgname = poptGetArg (opt_context);
417       if (pkgname == NULL)
418         break;
419
420       g_string_append (str, pkgname);
421       g_string_append (str, " ");
422     }
423
424   poptFreeContext (opt_context);
425
426   g_strstrip (str->str);
427
428   if (getenv("PKG_CONFIG_LOG") != NULL)
429     {
430       log = fopen (getenv ("PKG_CONFIG_LOG"), "a");
431       if (log == NULL)
432         {
433           fprintf (stderr, "Cannot open log file: %s\n",
434                    getenv ("PKG_CONFIG_LOG"));
435           exit (1);
436         }
437     }
438
439   {
440     gboolean failed = FALSE;
441     GSList *reqs;
442     GSList *iter;
443
444     reqs = parse_module_list (NULL, str->str,
445                               "(command line arguments)");
446
447     iter = reqs;
448
449     while (iter != NULL)
450       {
451         Package *req;
452         RequiredVersion *ver = iter->data;
453
454         if (want_short_errors)
455           req = get_package_quiet (ver->name);
456         else
457           req = get_package (ver->name);
458
459         if (log != NULL)
460           {
461             if (req == NULL)
462               fprintf (log, "%s NOT-FOUND", ver->name);
463             else
464               fprintf (log, "%s %s %s", ver->name,
465                        comparison_to_str (ver->comparison),
466                        (ver->version == NULL) ? "(null)" : ver->version);
467             fprintf (log, "\n");
468           }
469
470         if (req == NULL)
471           {
472             failed = TRUE;
473             verbose_error ("No package '%s' found\n", ver->name);
474             goto nextiter;
475           }
476
477         if (!version_test (ver->comparison, req->version, ver->version))
478           {
479             failed = TRUE;
480             verbose_error ("Requested '%s %s %s' but version of %s is %s\n",
481                            ver->name,
482                            comparison_to_str (ver->comparison),
483                            ver->version,
484                            req->name,
485                            req->version);
486
487             if (req->url)
488               verbose_error ("You may find new versions of %s at %s\n",
489                              req->name, req->url);
490
491             goto nextiter;
492           }
493
494         packages = g_slist_prepend (packages, req);
495
496       nextiter:
497         iter = g_slist_next (iter);
498       }
499
500     if (log != NULL)
501       {
502         fclose (log);
503       }
504
505     if (failed) {
506       return 1;
507     }
508
509   }
510
511   g_string_free (str, TRUE);
512
513   packages = g_slist_reverse (packages);
514
515   if (packages == NULL)
516     {
517       fprintf (stderr, "Must specify package names on the command line\n");
518
519       exit (1);
520     }
521
522   if (want_exists)
523     return 0; /* if we got here, all the packages existed. */
524
525   if (want_uninstalled)
526     {
527       /* See if > 0 pkgs (including dependencies recursively) were uninstalled */
528       GSList *tmp;
529       tmp = packages;
530       while (tmp != NULL)
531         {
532           Package *pkg = tmp->data;
533
534           if (pkg_uninstalled (pkg))
535             return 0;
536
537           tmp = g_slist_next (tmp);
538         }
539
540       return 1;
541     }
542
543   if (want_version)
544     {
545       GSList *tmp;
546       tmp = packages;
547       while (tmp != NULL)
548         {
549           Package *pkg = tmp->data;
550
551           printf ("%s\n", pkg->version);
552
553           tmp = g_slist_next (tmp);
554         }
555     }
556
557   if (required_exact_version)
558     {
559       Package *pkg = packages->data;
560
561       if (compare_versions (pkg->version, required_exact_version) == 0)
562         return 0;
563       else
564         return 1;
565     }
566   else if (required_atleast_version)
567     {
568       Package *pkg = packages->data;
569
570       if (compare_versions (pkg->version, required_atleast_version) >= 0)
571         return 0;
572       else
573         return 1;
574     }
575   else if (required_max_version)
576     {
577       Package *pkg = packages->data;
578
579       if (compare_versions (pkg->version, required_max_version) <= 0)
580         return 0;
581       else
582         return 1;
583     }
584
585   /* Print all flags; then print a newline at the end. */
586   need_newline = FALSE;
587
588   if (variable_name)
589     {
590       char *str = packages_get_var (packages, variable_name);
591       printf ("%s", str);
592       g_free (str);
593       need_newline = TRUE;
594     }
595
596   if (want_I_cflags)
597     {
598       char *str = packages_get_I_cflags (packages);
599       printf ("%s ", str);
600       g_free (str);
601       need_newline = TRUE;
602     }
603   else if (want_other_cflags)
604     {
605       char *str = packages_get_other_cflags (packages);
606       printf ("%s ", str);
607       g_free (str);
608       need_newline = TRUE;
609     }
610   else if (want_cflags)
611     {
612       char *str = packages_get_all_cflags (packages);
613       printf ("%s ", str);
614       g_free (str);
615       need_newline = TRUE;
616     }
617
618   if (want_l_libs)
619     {
620       char *str = packages_get_l_libs (packages);
621       printf ("%s ", str);
622       g_free (str);
623       need_newline = TRUE;
624     }
625   else if (want_L_libs)
626     {
627       char *str = packages_get_L_libs (packages);
628       printf ("%s ", str);
629       g_free (str);
630       need_newline = TRUE;
631     }
632   else if (want_other_libs)
633     {
634       char *str = packages_get_other_libs (packages);
635       printf ("%s ", str);
636       g_free (str);
637       need_newline = TRUE;
638     }
639   else if (want_libs)
640     {
641       char *str = packages_get_all_libs (packages);
642       printf ("%s ", str);
643       g_free (str);
644       need_newline = TRUE;
645     }
646
647   if (need_newline)
648 #ifdef G_OS_WIN32
649     printf ("\r\n");
650 #else
651     printf ("\n");
652 #endif
653
654   return 0;
655 }