1 /*
2 * main.c
3 * main() routine, printer functions
4 *
5 * Copyright (c) 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019
6 * pkgconf authors (see AUTHORS).
7 *
8 * Permission to use, copy, modify, and/or distribute this software for any
9 * purpose with or without fee is hereby granted, provided that the above
10 * copyright notice and this permission notice appear in all copies.
11 *
12 * This software is provided 'as is' and without any warranty, express or
13 * implied. In no event shall the authors be liable for any damages arising
14 * from the use of this software.
15 */
16
17 #include "libpkgconf/config.h"
18 #include <libpkgconf/stdinc.h>
19 #include <libpkgconf/libpkgconf.h>
20 #include "getopt_long.h"
21 #ifndef PKGCONF_LITE
22 #include "renderer-msvc.h"
23 #endif
24 #ifdef _WIN32
25 #include <io.h> /* for _setmode() */
26 #include <fcntl.h>
27 #endif
28
29 #define PKG_CFLAGS_ONLY_I (((uint64_t) 1) << 2)
30 #define PKG_CFLAGS_ONLY_OTHER (((uint64_t) 1) << 3)
31 #define PKG_CFLAGS (PKG_CFLAGS_ONLY_I|PKG_CFLAGS_ONLY_OTHER)
32 #define PKG_LIBS_ONLY_LDPATH (((uint64_t) 1) << 5)
33 #define PKG_LIBS_ONLY_LIBNAME (((uint64_t) 1) << 6)
34 #define PKG_LIBS_ONLY_OTHER (((uint64_t) 1) << 7)
35 #define PKG_LIBS (PKG_LIBS_ONLY_LDPATH|PKG_LIBS_ONLY_LIBNAME|PKG_LIBS_ONLY_OTHER)
36 #define PKG_MODVERSION (((uint64_t) 1) << 8)
37 #define PKG_REQUIRES (((uint64_t) 1) << 9)
38 #define PKG_REQUIRES_PRIVATE (((uint64_t) 1) << 10)
39 #define PKG_VARIABLES (((uint64_t) 1) << 11)
40 #define PKG_DIGRAPH (((uint64_t) 1) << 12)
41 #define PKG_KEEP_SYSTEM_CFLAGS (((uint64_t) 1) << 13)
42 #define PKG_KEEP_SYSTEM_LIBS (((uint64_t) 1) << 14)
43 #define PKG_VERSION (((uint64_t) 1) << 15)
44 #define PKG_ABOUT (((uint64_t) 1) << 16)
45 #define PKG_ENV_ONLY (((uint64_t) 1) << 17)
46 #define PKG_ERRORS_ON_STDOUT (((uint64_t) 1) << 18)
47 #define PKG_SILENCE_ERRORS (((uint64_t) 1) << 19)
48 #define PKG_IGNORE_CONFLICTS (((uint64_t) 1) << 20)
49 #define PKG_STATIC (((uint64_t) 1) << 21)
50 #define PKG_NO_UNINSTALLED (((uint64_t) 1) << 22)
51 #define PKG_UNINSTALLED (((uint64_t) 1) << 23)
52 #define PKG_LIST (((uint64_t) 1) << 24)
53 #define PKG_HELP (((uint64_t) 1) << 25)
54 #define PKG_PRINT_ERRORS (((uint64_t) 1) << 26)
55 #define PKG_SIMULATE (((uint64_t) 1) << 27)
56 #define PKG_NO_CACHE (((uint64_t) 1) << 28)
57 #define PKG_PROVIDES (((uint64_t) 1) << 29)
58 #define PKG_VALIDATE (((uint64_t) 1) << 30)
59 #define PKG_LIST_PACKAGE_NAMES (((uint64_t) 1) << 31)
60 #define PKG_NO_PROVIDES (((uint64_t) 1) << 32)
61 #define PKG_PURE (((uint64_t) 1) << 33)
62 #define PKG_PATH (((uint64_t) 1) << 34)
63 #define PKG_DEFINE_PREFIX (((uint64_t) 1) << 35)
64 #define PKG_DONT_DEFINE_PREFIX (((uint64_t) 1) << 36)
65 #define PKG_DONT_RELOCATE_PATHS (((uint64_t) 1) << 37)
66 #define PKG_DEBUG (((uint64_t) 1) << 38)
67 #define PKG_SHORT_ERRORS (((uint64_t) 1) << 39)
68 #define PKG_EXISTS (((uint64_t) 1) << 40)
69 #define PKG_MSVC_SYNTAX (((uint64_t) 1) << 41)
70 #define PKG_INTERNAL_CFLAGS (((uint64_t) 1) << 42)
71 #define PKG_DUMP_PERSONALITY (((uint64_t) 1) << 43)
72 #define PKG_SHARED (((uint64_t) 1) << 44)
73 #define PKG_DUMP_LICENSE (((uint64_t) 1) << 45)
74 #define PKG_SOLUTION (((uint64_t) 1) << 46)
75 #define PKG_EXISTS_CFLAGS (((uint64_t) 1) << 47)
76 #define PKG_FRAGMENT_TREE (((uint64_t) 1) << 48)
77
78 static pkgconf_client_t pkg_client;
79 static const pkgconf_fragment_render_ops_t *want_render_ops = NULL;
80
81 static uint64_t want_flags;
82 static int verbosity = 0;
83 static int maximum_traverse_depth = 2000;
84 static size_t maximum_package_count = 0;
85
86 static char *want_variable = NULL;
87 static char *want_fragment_filter = NULL;
88
89 FILE *error_msgout = NULL;
90 FILE *logfile_out = NULL;
91
92 static bool
error_handler(const char * msg,const pkgconf_client_t * client,void * data)93 error_handler(const char *msg, const pkgconf_client_t *client, void *data)
94 {
95 (void) client;
96 (void) data;
97 fprintf(error_msgout, "%s", msg);
98 return true;
99 }
100
101 static bool
print_list_entry(const pkgconf_pkg_t * entry,void * data)102 print_list_entry(const pkgconf_pkg_t *entry, void *data)
103 {
104 (void) data;
105
106 if (entry->flags & PKGCONF_PKG_PROPF_UNINSTALLED)
107 return false;
108
109 printf("%-30s %s - %s\n", entry->id, entry->realname, entry->description);
110
111 return false;
112 }
113
114 static bool
print_package_entry(const pkgconf_pkg_t * entry,void * data)115 print_package_entry(const pkgconf_pkg_t *entry, void *data)
116 {
117 (void) data;
118
119 if (entry->flags & PKGCONF_PKG_PROPF_UNINSTALLED)
120 return false;
121
122 printf("%s\n", entry->id);
123
124 return false;
125 }
126
127 static bool
filter_cflags(const pkgconf_client_t * client,const pkgconf_fragment_t * frag,void * data)128 filter_cflags(const pkgconf_client_t *client, const pkgconf_fragment_t *frag, void *data)
129 {
130 int got_flags = 0;
131 (void) client;
132 (void) data;
133
134 if (!(want_flags & PKG_KEEP_SYSTEM_CFLAGS) && pkgconf_fragment_has_system_dir(client, frag))
135 return false;
136
137 if (want_fragment_filter != NULL && (strchr(want_fragment_filter, frag->type) == NULL || !frag->type))
138 return false;
139
140 if (frag->type == 'I')
141 got_flags = PKG_CFLAGS_ONLY_I;
142 else
143 got_flags = PKG_CFLAGS_ONLY_OTHER;
144
145 return (want_flags & got_flags) != 0;
146 }
147
148 static bool
filter_libs(const pkgconf_client_t * client,const pkgconf_fragment_t * frag,void * data)149 filter_libs(const pkgconf_client_t *client, const pkgconf_fragment_t *frag, void *data)
150 {
151 int got_flags = 0;
152 (void) client;
153 (void) data;
154
155 if (!(want_flags & PKG_KEEP_SYSTEM_LIBS) && pkgconf_fragment_has_system_dir(client, frag))
156 return false;
157
158 if (want_fragment_filter != NULL && (strchr(want_fragment_filter, frag->type) == NULL || !frag->type))
159 return false;
160
161 switch (frag->type)
162 {
163 case 'L': got_flags = PKG_LIBS_ONLY_LDPATH; break;
164 case 'l': got_flags = PKG_LIBS_ONLY_LIBNAME; break;
165 default: got_flags = PKG_LIBS_ONLY_OTHER; break;
166 }
167
168 return (want_flags & got_flags) != 0;
169 }
170
171 static void
print_variables(pkgconf_pkg_t * pkg)172 print_variables(pkgconf_pkg_t *pkg)
173 {
174 pkgconf_node_t *node;
175
176 PKGCONF_FOREACH_LIST_ENTRY(pkg->vars.head, node)
177 {
178 pkgconf_tuple_t *tuple = node->data;
179
180 printf("%s\n", tuple->key);
181 }
182 }
183
184 static void
print_requires(pkgconf_pkg_t * pkg)185 print_requires(pkgconf_pkg_t *pkg)
186 {
187 pkgconf_node_t *node;
188
189 PKGCONF_FOREACH_LIST_ENTRY(pkg->required.head, node)
190 {
191 pkgconf_dependency_t *dep = node->data;
192
193 printf("%s", dep->package);
194
195 if (dep->version != NULL)
196 printf(" %s %s", pkgconf_pkg_get_comparator(dep), dep->version);
197
198 printf("\n");
199 }
200 }
201
202 static void
print_requires_private(pkgconf_pkg_t * pkg)203 print_requires_private(pkgconf_pkg_t *pkg)
204 {
205 pkgconf_node_t *node;
206
207 PKGCONF_FOREACH_LIST_ENTRY(pkg->requires_private.head, node)
208 {
209 pkgconf_dependency_t *dep = node->data;
210
211 printf("%s", dep->package);
212
213 if (dep->version != NULL)
214 printf(" %s %s", pkgconf_pkg_get_comparator(dep), dep->version);
215
216 printf("\n");
217 }
218 }
219
220 static void
print_provides(pkgconf_pkg_t * pkg)221 print_provides(pkgconf_pkg_t *pkg)
222 {
223 pkgconf_node_t *node;
224
225 PKGCONF_FOREACH_LIST_ENTRY(pkg->provides.head, node)
226 {
227 pkgconf_dependency_t *dep = node->data;
228
229 printf("%s", dep->package);
230
231 if (dep->version != NULL)
232 printf(" %s %s", pkgconf_pkg_get_comparator(dep), dep->version);
233
234 printf("\n");
235 }
236 }
237
238 static bool
apply_provides(pkgconf_client_t * client,pkgconf_pkg_t * world,void * unused,int maxdepth)239 apply_provides(pkgconf_client_t *client, pkgconf_pkg_t *world, void *unused, int maxdepth)
240 {
241 pkgconf_node_t *iter;
242 (void) client;
243 (void) unused;
244 (void) maxdepth;
245
246 PKGCONF_FOREACH_LIST_ENTRY(world->required.head, iter)
247 {
248 pkgconf_dependency_t *dep = iter->data;
249 pkgconf_pkg_t *pkg = dep->match;
250
251 print_provides(pkg);
252 }
253
254 return true;
255 }
256
257 #ifndef PKGCONF_LITE
258 static void
print_digraph_node(pkgconf_client_t * client,pkgconf_pkg_t * pkg,void * data)259 print_digraph_node(pkgconf_client_t *client, pkgconf_pkg_t *pkg, void *data)
260 {
261 pkgconf_node_t *node;
262 (void) client;
263 pkgconf_pkg_t **last_seen = data;
264
265 if(pkg->flags & PKGCONF_PKG_PROPF_VIRTUAL)
266 return;
267
268 if (pkg->flags & PKGCONF_PKG_PROPF_VISITED_PRIVATE)
269 printf("\"%s\" [fontname=Sans fontsize=8 fontcolor=gray color=gray]\n", pkg->id);
270 else
271 printf("\"%s\" [fontname=Sans fontsize=8]\n", pkg->id);
272
273 if (last_seen != NULL)
274 {
275 if (*last_seen != NULL)
276 printf("\"%s\" -> \"%s\" [fontname=Sans fontsize=8 color=red]\n", (*last_seen)->id, pkg->id);
277
278 *last_seen = pkg;
279 }
280
281 PKGCONF_FOREACH_LIST_ENTRY(pkg->required.head, node)
282 {
283 pkgconf_dependency_t *dep = node->data;
284 const char *dep_id = (dep->match != NULL) ? dep->match->id : dep->package;
285
286 if ((dep->flags & PKGCONF_PKG_DEPF_PRIVATE) == 0)
287 printf("\"%s\" -> \"%s\" [fontname=Sans fontsize=8]\n", pkg->id, dep_id);
288 else
289 printf("\"%s\" -> \"%s\" [fontname=Sans fontsize=8 color=gray]\n", pkg->id, dep_id);
290 }
291
292 PKGCONF_FOREACH_LIST_ENTRY(pkg->requires_private.head, node)
293 {
294 pkgconf_dependency_t *dep = node->data;
295 const char *dep_id = (dep->match != NULL) ? dep->match->id : dep->package;
296
297 printf("\"%s\" -> \"%s\" [fontname=Sans fontsize=8 color=gray]\n", pkg->id, dep_id);
298 }
299 }
300
301 static bool
apply_digraph(pkgconf_client_t * client,pkgconf_pkg_t * world,void * data,int maxdepth)302 apply_digraph(pkgconf_client_t *client, pkgconf_pkg_t *world, void *data, int maxdepth)
303 {
304 int eflag;
305 pkgconf_list_t *list = data;
306 pkgconf_pkg_t *last_seen = NULL;
307 pkgconf_node_t *iter;
308
309 printf("digraph deptree {\n");
310 printf("edge [color=blue len=7.5 fontname=Sans fontsize=8]\n");
311 printf("node [fontname=Sans fontsize=8]\n");
312 printf("\"user:request\" [fontname=Sans fontsize=8]\n");
313
314 PKGCONF_FOREACH_LIST_ENTRY(list->head, iter)
315 {
316 pkgconf_queue_t *pkgq = iter->data;
317 pkgconf_pkg_t *pkg = pkgconf_pkg_find(client, pkgq->package);
318 printf("\"user:request\" -> \"%s\" [fontname=Sans fontsize=8]\n", pkg == NULL ? pkgq->package : pkg->id);
319 if (pkg != NULL)
320 pkgconf_pkg_unref(client, pkg);
321 }
322
323 eflag = pkgconf_pkg_traverse(client, world, print_digraph_node, &last_seen, maxdepth, 0);
324
325 if (eflag != PKGCONF_PKG_ERRF_OK)
326 return false;
327
328 printf("}\n");
329 return true;
330 }
331
332 static void
print_solution_node(pkgconf_client_t * client,pkgconf_pkg_t * pkg,void * unused)333 print_solution_node(pkgconf_client_t *client, pkgconf_pkg_t *pkg, void *unused)
334 {
335 (void) client;
336 (void) unused;
337
338 printf("%s (%"PRIu64")%s\n", pkg->id, pkg->identifier, (pkg->flags & PKGCONF_PKG_PROPF_VISITED_PRIVATE) == PKGCONF_PKG_PROPF_VISITED_PRIVATE ? " [private]" : "");
339 }
340
341 static bool
apply_print_solution(pkgconf_client_t * client,pkgconf_pkg_t * world,void * unused,int maxdepth)342 apply_print_solution(pkgconf_client_t *client, pkgconf_pkg_t *world, void *unused, int maxdepth)
343 {
344 int eflag;
345
346 eflag = pkgconf_pkg_traverse(client, world, print_solution_node, unused, maxdepth, 0);
347
348 return eflag == PKGCONF_PKG_ERRF_OK;
349 }
350 #endif
351
352 static bool
apply_modversion(pkgconf_client_t * client,pkgconf_pkg_t * world,void * data,int maxdepth)353 apply_modversion(pkgconf_client_t *client, pkgconf_pkg_t *world, void *data, int maxdepth)
354 {
355 pkgconf_node_t *queue_iter;
356 pkgconf_list_t *pkgq = data;
357 (void) client;
358 (void) maxdepth;
359
360 PKGCONF_FOREACH_LIST_ENTRY(pkgq->head, queue_iter)
361 {
362 pkgconf_node_t *world_iter;
363 pkgconf_queue_t *queue_node = queue_iter->data;
364
365 PKGCONF_FOREACH_LIST_ENTRY(world->required.head, world_iter)
366 {
367 pkgconf_dependency_t *dep = world_iter->data;
368 pkgconf_pkg_t *pkg = dep->match;
369
370 const size_t name_len = strlen(pkg->why);
371 if (name_len > strlen(queue_node->package) ||
372 strncmp(pkg->why, queue_node->package, name_len) ||
373 (queue_node->package[name_len] != 0 &&
374 !isspace((unsigned char)queue_node->package[name_len]) &&
375 !PKGCONF_IS_OPERATOR_CHAR(queue_node->package[name_len])))
376 continue;
377
378 if (pkg->version != NULL) {
379 if (verbosity)
380 printf("%s: ", pkg->id);
381
382 printf("%s\n", pkg->version);
383 }
384
385 break;
386 }
387 }
388
389 return true;
390 }
391
392 static bool
apply_variables(pkgconf_client_t * client,pkgconf_pkg_t * world,void * unused,int maxdepth)393 apply_variables(pkgconf_client_t *client, pkgconf_pkg_t *world, void *unused, int maxdepth)
394 {
395 pkgconf_node_t *iter;
396 (void) client;
397 (void) unused;
398 (void) maxdepth;
399
400 PKGCONF_FOREACH_LIST_ENTRY(world->required.head, iter)
401 {
402 pkgconf_dependency_t *dep = iter->data;
403 pkgconf_pkg_t *pkg = dep->match;
404
405 print_variables(pkg);
406 }
407
408 return true;
409 }
410
411 static bool
apply_path(pkgconf_client_t * client,pkgconf_pkg_t * world,void * unused,int maxdepth)412 apply_path(pkgconf_client_t *client, pkgconf_pkg_t *world, void *unused, int maxdepth)
413 {
414 pkgconf_node_t *iter;
415 (void) client;
416 (void) unused;
417 (void) maxdepth;
418
419 PKGCONF_FOREACH_LIST_ENTRY(world->required.head, iter)
420 {
421 pkgconf_dependency_t *dep = iter->data;
422 pkgconf_pkg_t *pkg = dep->match;
423
424 /* a module entry with no filename is either virtual, static (builtin) or synthesized. */
425 if (pkg->filename != NULL)
426 printf("%s\n", pkg->filename);
427 }
428
429 return true;
430 }
431
432 static bool
apply_variable(pkgconf_client_t * client,pkgconf_pkg_t * world,void * variable,int maxdepth)433 apply_variable(pkgconf_client_t *client, pkgconf_pkg_t *world, void *variable, int maxdepth)
434 {
435 pkgconf_node_t *iter;
436 (void) maxdepth;
437
438 PKGCONF_FOREACH_LIST_ENTRY(world->required.head, iter)
439 {
440 pkgconf_dependency_t *dep = iter->data;
441 pkgconf_pkg_t *pkg = dep->match;
442 const char *var;
443
444 var = pkgconf_tuple_find(client, &pkg->vars, variable);
445
446 if (var != NULL)
447 printf("%s%s", iter->prev != NULL ? " " : "", var);
448 }
449
450 printf("\n");
451
452 return true;
453 }
454
455 static bool
apply_env_var(const char * prefix,pkgconf_client_t * client,pkgconf_pkg_t * world,int maxdepth,unsigned int (* collect_fn)(pkgconf_client_t * client,pkgconf_pkg_t * world,pkgconf_list_t * list,int maxdepth),bool (* filter_fn)(const pkgconf_client_t * client,const pkgconf_fragment_t * frag,void * data),void (* postprocess_fn)(pkgconf_client_t * client,pkgconf_pkg_t * world,pkgconf_list_t * fragment_list))456 apply_env_var(const char *prefix, pkgconf_client_t *client, pkgconf_pkg_t *world, int maxdepth,
457 unsigned int (*collect_fn)(pkgconf_client_t *client, pkgconf_pkg_t *world, pkgconf_list_t *list, int maxdepth),
458 bool (*filter_fn)(const pkgconf_client_t *client, const pkgconf_fragment_t *frag, void *data),
459 void (*postprocess_fn)(pkgconf_client_t *client, pkgconf_pkg_t *world, pkgconf_list_t *fragment_list))
460 {
461 pkgconf_list_t unfiltered_list = PKGCONF_LIST_INITIALIZER;
462 pkgconf_list_t filtered_list = PKGCONF_LIST_INITIALIZER;
463 unsigned int eflag;
464 char *render_buf;
465
466 eflag = collect_fn(client, world, &unfiltered_list, maxdepth);
467 if (eflag != PKGCONF_PKG_ERRF_OK)
468 return false;
469
470 pkgconf_fragment_filter(client, &filtered_list, &unfiltered_list, filter_fn, NULL);
471
472 if (postprocess_fn != NULL)
473 postprocess_fn(client, world, &filtered_list);
474
475 if (filtered_list.head == NULL)
476 goto out;
477
478 render_buf = pkgconf_fragment_render(&filtered_list, true, want_render_ops);
479 printf("%s='%s'\n", prefix, render_buf);
480 free(render_buf);
481
482 out:
483 pkgconf_fragment_free(&unfiltered_list);
484 pkgconf_fragment_free(&filtered_list);
485
486 return true;
487 }
488
489 static void
maybe_add_module_definitions(pkgconf_client_t * client,pkgconf_pkg_t * world,pkgconf_list_t * fragment_list)490 maybe_add_module_definitions(pkgconf_client_t *client, pkgconf_pkg_t *world, pkgconf_list_t *fragment_list)
491 {
492 pkgconf_node_t *world_iter;
493
494 if ((want_flags & PKG_EXISTS_CFLAGS) != PKG_EXISTS_CFLAGS)
495 return;
496
497 PKGCONF_FOREACH_LIST_ENTRY(world->required.head, world_iter)
498 {
499 pkgconf_dependency_t *dep = world_iter->data;
500 char havebuf[PKGCONF_ITEM_SIZE];
501 char *p;
502
503 if ((dep->flags & PKGCONF_PKG_DEPF_QUERY) != PKGCONF_PKG_DEPF_QUERY)
504 continue;
505
506 if (dep->match == NULL)
507 continue;
508
509 snprintf(havebuf, sizeof havebuf, "HAVE_%s", dep->match->id);
510
511 for (p = havebuf; *p; p++)
512 {
513 switch (*p)
514 {
515 case ' ':
516 case '-':
517 *p = '_';
518 break;
519
520 default:
521 *p = toupper((unsigned char) *p);
522 }
523 }
524
525 pkgconf_fragment_insert(client, fragment_list, 'D', havebuf, false);
526 }
527 }
528
529 static void
apply_env_variables(pkgconf_client_t * client,pkgconf_pkg_t * world,const char * env_prefix)530 apply_env_variables(pkgconf_client_t *client, pkgconf_pkg_t *world, const char *env_prefix)
531 {
532 (void) client;
533 pkgconf_node_t *world_iter;
534
535 PKGCONF_FOREACH_LIST_ENTRY(world->required.head, world_iter)
536 {
537 pkgconf_dependency_t *dep = world_iter->data;
538 pkgconf_pkg_t *pkg = dep->match;
539 pkgconf_node_t *tuple_iter;
540
541 if ((dep->flags & PKGCONF_PKG_DEPF_QUERY) != PKGCONF_PKG_DEPF_QUERY)
542 continue;
543
544 if (dep->match == NULL)
545 continue;
546
547 PKGCONF_FOREACH_LIST_ENTRY(pkg->vars.head, tuple_iter)
548 {
549 pkgconf_tuple_t *tuple = tuple_iter->data;
550 char havebuf[PKGCONF_ITEM_SIZE];
551 char *p;
552
553 if (want_variable != NULL && strcmp(want_variable, tuple->key))
554 continue;
555
556 snprintf(havebuf, sizeof havebuf, "%s_%s", env_prefix, tuple->key);
557
558 for (p = havebuf; *p; p++)
559 {
560 switch (*p)
561 {
562 case ' ':
563 case '-':
564 *p = '_';
565 break;
566
567 default:
568 *p = toupper((unsigned char) *p);
569 }
570 }
571
572 printf("%s='%s'\n", havebuf, tuple->value);
573 }
574 }
575 }
576
577 static bool
apply_env(pkgconf_client_t * client,pkgconf_pkg_t * world,void * env_prefix_p,int maxdepth)578 apply_env(pkgconf_client_t *client, pkgconf_pkg_t *world, void *env_prefix_p, int maxdepth)
579 {
580 const char *want_env_prefix = env_prefix_p, *it;
581 char workbuf[PKGCONF_ITEM_SIZE];
582
583 for (it = want_env_prefix; *it != '\0'; it++)
584 if (!isalpha((unsigned char)*it) &&
585 !isdigit((unsigned char)*it))
586 return false;
587
588 snprintf(workbuf, sizeof workbuf, "%s_CFLAGS", want_env_prefix);
589 if (!apply_env_var(workbuf, client, world, maxdepth, pkgconf_pkg_cflags, filter_cflags, maybe_add_module_definitions))
590 return false;
591
592 snprintf(workbuf, sizeof workbuf, "%s_LIBS", want_env_prefix);
593 if (!apply_env_var(workbuf, client, world, maxdepth, pkgconf_pkg_libs, filter_libs, NULL))
594 return false;
595
596 if ((want_flags & PKG_VARIABLES) == PKG_VARIABLES || want_variable != NULL)
597 apply_env_variables(client, world, want_env_prefix);
598
599 return true;
600 }
601
602 static bool
apply_cflags(pkgconf_client_t * client,pkgconf_pkg_t * world,void * unused,int maxdepth)603 apply_cflags(pkgconf_client_t *client, pkgconf_pkg_t *world, void *unused, int maxdepth)
604 {
605 pkgconf_list_t unfiltered_list = PKGCONF_LIST_INITIALIZER;
606 pkgconf_list_t filtered_list = PKGCONF_LIST_INITIALIZER;
607 int eflag;
608 char *render_buf;
609 (void) unused;
610
611 eflag = pkgconf_pkg_cflags(client, world, &unfiltered_list, maxdepth);
612 if (eflag != PKGCONF_PKG_ERRF_OK)
613 return false;
614
615 pkgconf_fragment_filter(client, &filtered_list, &unfiltered_list, filter_cflags, NULL);
616 maybe_add_module_definitions(client, world, &filtered_list);
617
618 if (filtered_list.head == NULL)
619 goto out;
620
621 render_buf = pkgconf_fragment_render(&filtered_list, true, want_render_ops);
622 printf("%s", render_buf);
623 free(render_buf);
624
625 out:
626 pkgconf_fragment_free(&unfiltered_list);
627 pkgconf_fragment_free(&filtered_list);
628
629 return true;
630 }
631
632 static bool
apply_libs(pkgconf_client_t * client,pkgconf_pkg_t * world,void * unused,int maxdepth)633 apply_libs(pkgconf_client_t *client, pkgconf_pkg_t *world, void *unused, int maxdepth)
634 {
635 pkgconf_list_t unfiltered_list = PKGCONF_LIST_INITIALIZER;
636 pkgconf_list_t filtered_list = PKGCONF_LIST_INITIALIZER;
637 int eflag;
638 char *render_buf;
639 (void) unused;
640
641 eflag = pkgconf_pkg_libs(client, world, &unfiltered_list, maxdepth);
642 if (eflag != PKGCONF_PKG_ERRF_OK)
643 return false;
644
645 pkgconf_fragment_filter(client, &filtered_list, &unfiltered_list, filter_libs, NULL);
646
647 if (filtered_list.head == NULL)
648 goto out;
649
650 render_buf = pkgconf_fragment_render(&filtered_list, true, want_render_ops);
651 printf("%s", render_buf);
652 free(render_buf);
653
654 out:
655 pkgconf_fragment_free(&unfiltered_list);
656 pkgconf_fragment_free(&filtered_list);
657
658 return true;
659 }
660
661 static bool
apply_requires(pkgconf_client_t * client,pkgconf_pkg_t * world,void * unused,int maxdepth)662 apply_requires(pkgconf_client_t *client, pkgconf_pkg_t *world, void *unused, int maxdepth)
663 {
664 pkgconf_node_t *iter;
665 (void) client;
666 (void) unused;
667 (void) maxdepth;
668
669 PKGCONF_FOREACH_LIST_ENTRY(world->required.head, iter)
670 {
671 pkgconf_dependency_t *dep = iter->data;
672 pkgconf_pkg_t *pkg = dep->match;
673
674 print_requires(pkg);
675 }
676
677 return true;
678 }
679
680 static bool
apply_requires_private(pkgconf_client_t * client,pkgconf_pkg_t * world,void * unused,int maxdepth)681 apply_requires_private(pkgconf_client_t *client, pkgconf_pkg_t *world, void *unused, int maxdepth)
682 {
683 pkgconf_node_t *iter;
684 (void) client;
685 (void) unused;
686 (void) maxdepth;
687
688 PKGCONF_FOREACH_LIST_ENTRY(world->required.head, iter)
689 {
690 pkgconf_dependency_t *dep = iter->data;
691 pkgconf_pkg_t *pkg = dep->match;
692
693 print_requires_private(pkg);
694 }
695 return true;
696 }
697
698 static void
check_uninstalled(pkgconf_client_t * client,pkgconf_pkg_t * pkg,void * data)699 check_uninstalled(pkgconf_client_t *client, pkgconf_pkg_t *pkg, void *data)
700 {
701 int *retval = data;
702 (void) client;
703
704 if (pkg->flags & PKGCONF_PKG_PROPF_UNINSTALLED)
705 *retval = EXIT_SUCCESS;
706 }
707
708 static bool
apply_uninstalled(pkgconf_client_t * client,pkgconf_pkg_t * world,void * data,int maxdepth)709 apply_uninstalled(pkgconf_client_t *client, pkgconf_pkg_t *world, void *data, int maxdepth)
710 {
711 int eflag;
712
713 eflag = pkgconf_pkg_traverse(client, world, check_uninstalled, data, maxdepth, 0);
714
715 if (eflag != PKGCONF_PKG_ERRF_OK)
716 return false;
717
718 return true;
719 }
720
721 #ifndef PKGCONF_LITE
722 static void
print_graph_node(pkgconf_client_t * client,pkgconf_pkg_t * pkg,void * data)723 print_graph_node(pkgconf_client_t *client, pkgconf_pkg_t *pkg, void *data)
724 {
725 pkgconf_node_t *n;
726
727 (void) client;
728 (void) data;
729
730 printf("node '%s' {\n", pkg->id);
731
732 if (pkg->version != NULL)
733 printf(" version = '%s';\n", pkg->version);
734
735 PKGCONF_FOREACH_LIST_ENTRY(pkg->required.head, n)
736 {
737 pkgconf_dependency_t *dep = n->data;
738 printf(" dependency '%s'", dep->package);
739 if (dep->compare != PKGCONF_CMP_ANY)
740 {
741 printf(" {\n");
742 printf(" comparator = '%s';\n", pkgconf_pkg_get_comparator(dep));
743 printf(" version = '%s';\n", dep->version);
744 printf(" };\n");
745 }
746 else
747 printf(";\n");
748 }
749
750 printf("};\n");
751 }
752
753 static bool
apply_simulate(pkgconf_client_t * client,pkgconf_pkg_t * world,void * data,int maxdepth)754 apply_simulate(pkgconf_client_t *client, pkgconf_pkg_t *world, void *data, int maxdepth)
755 {
756 int eflag;
757
758 eflag = pkgconf_pkg_traverse(client, world, print_graph_node, data, maxdepth, 0);
759
760 if (eflag != PKGCONF_PKG_ERRF_OK)
761 return false;
762
763 return true;
764 }
765 #endif
766
767 static void
print_fragment_tree_branch(pkgconf_list_t * fragment_list,int indent)768 print_fragment_tree_branch(pkgconf_list_t *fragment_list, int indent)
769 {
770 pkgconf_node_t *iter;
771
772 PKGCONF_FOREACH_LIST_ENTRY(fragment_list->head, iter)
773 {
774 pkgconf_fragment_t *frag = iter->data;
775
776 if (frag->type)
777 printf("%*s'-%c%s' [type %c]\n", indent, "", frag->type, frag->data, frag->type);
778 else
779 printf("%*s'%s' [untyped]\n", indent, "", frag->data);
780
781 print_fragment_tree_branch(&frag->children, indent + 2);
782 }
783
784 if (fragment_list->head != NULL)
785 printf("\n");
786 }
787
788 static bool
apply_fragment_tree(pkgconf_client_t * client,pkgconf_pkg_t * world,void * data,int maxdepth)789 apply_fragment_tree(pkgconf_client_t *client, pkgconf_pkg_t *world, void *data, int maxdepth)
790 {
791 pkgconf_list_t unfiltered_list = PKGCONF_LIST_INITIALIZER;
792 int eflag;
793
794 (void) data;
795
796 eflag = pkgconf_pkg_cflags(client, world, &unfiltered_list, maxdepth);
797 if (eflag != PKGCONF_PKG_ERRF_OK)
798 return false;
799
800 eflag = pkgconf_pkg_libs(client, world, &unfiltered_list, maxdepth);
801 if (eflag != PKGCONF_PKG_ERRF_OK)
802 return false;
803
804 print_fragment_tree_branch(&unfiltered_list, 0);
805 pkgconf_fragment_free(&unfiltered_list);
806
807 return true;
808 }
809
810 static void
print_license(pkgconf_client_t * client,pkgconf_pkg_t * pkg,void * data)811 print_license(pkgconf_client_t *client, pkgconf_pkg_t *pkg, void *data)
812 {
813 (void) client;
814 (void) data;
815
816 if (pkg->flags & PKGCONF_PKG_PROPF_VIRTUAL)
817 return;
818
819 /* NOASSERTION is the default when the license is unknown, per SPDX spec § 3.15 */
820 printf("%s: %s\n", pkg->id, pkg->license != NULL ? pkg->license : "NOASSERTION");
821 }
822
823 static bool
apply_license(pkgconf_client_t * client,pkgconf_pkg_t * world,void * data,int maxdepth)824 apply_license(pkgconf_client_t *client, pkgconf_pkg_t *world, void *data, int maxdepth)
825 {
826 int eflag;
827
828 eflag = pkgconf_pkg_traverse(client, world, print_license, data, maxdepth, 0);
829
830 if (eflag != PKGCONF_PKG_ERRF_OK)
831 return false;
832
833 return true;
834 }
835
836 static void
version(void)837 version(void)
838 {
839 printf("%s\n", PACKAGE_VERSION);
840 }
841
842 static void
about(void)843 about(void)
844 {
845 printf("%s %s\n", PACKAGE_NAME, PACKAGE_VERSION);
846 printf("Copyright (c) 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021\n");
847 printf(" pkgconf authors (see AUTHORS in documentation directory).\n\n");
848 printf("Permission to use, copy, modify, and/or distribute this software for any\n");
849 printf("purpose with or without fee is hereby granted, provided that the above\n");
850 printf("copyright notice and this permission notice appear in all copies.\n\n");
851 printf("This software is provided 'as is' and without any warranty, express or\n");
852 printf("implied. In no event shall the authors be liable for any damages arising\n");
853 printf("from the use of this software.\n\n");
854 printf("Report bugs at <%s>.\n", PACKAGE_BUGREPORT);
855 }
856
857 static void
usage(void)858 usage(void)
859 {
860 printf("usage: %s [OPTIONS] [LIBRARIES]\n", PACKAGE_NAME);
861
862 printf("\nbasic options:\n\n");
863
864 printf(" --help this message\n");
865 printf(" --about print pkgconf version and license to stdout\n");
866 printf(" --version print supported pkg-config version to stdout\n");
867 printf(" --verbose print additional information\n");
868 printf(" --atleast-pkgconfig-version check whether or not pkgconf is compatible\n");
869 printf(" with a specified pkg-config version\n");
870 printf(" --errors-to-stdout print all errors on stdout instead of stderr\n");
871 printf(" --print-errors ensure all errors are printed\n");
872 printf(" --short-errors be less verbose about some errors\n");
873 printf(" --silence-errors explicitly be silent about errors\n");
874 printf(" --list-all list all known packages\n");
875 printf(" --list-package-names list all known package names\n");
876 #ifndef PKGCONF_LITE
877 printf(" --simulate simulate walking the calculated dependency graph\n");
878 #endif
879 printf(" --no-cache do not cache already seen packages when\n");
880 printf(" walking the dependency graph\n");
881 printf(" --log-file=filename write an audit log to a specified file\n");
882 printf(" --with-path=path adds a directory to the search path\n");
883 printf(" --define-prefix override the prefix variable with one that is guessed based on\n");
884 printf(" the location of the .pc file\n");
885 printf(" --dont-define-prefix do not override the prefix variable under any circumstances\n");
886 printf(" --prefix-variable=varname sets the name of the variable that pkgconf considers\n");
887 printf(" to be the package prefix\n");
888 printf(" --relocate=path relocates a path and exits (mostly for testsuite)\n");
889 printf(" --dont-relocate-paths disables path relocation support\n");
890
891 #ifndef PKGCONF_LITE
892 printf("\ncross-compilation personality support:\n\n");
893 printf(" --personality=triplet|filename sets the personality to 'triplet' or a file named 'filename'\n");
894 printf(" --dump-personality dumps details concerning selected personality\n");
895 #endif
896
897 printf("\nchecking specific pkg-config database entries:\n\n");
898
899 printf(" --atleast-version require a specific version of a module\n");
900 printf(" --exact-version require an exact version of a module\n");
901 printf(" --max-version require a maximum version of a module\n");
902 printf(" --exists check whether or not a module exists\n");
903 printf(" --uninstalled check whether or not an uninstalled module will be used\n");
904 printf(" --no-uninstalled never use uninstalled modules when satisfying dependencies\n");
905 printf(" --no-provides do not use 'provides' rules to resolve dependencies\n");
906 printf(" --maximum-traverse-depth maximum allowed depth for dependency graph\n");
907 printf(" --static be more aggressive when computing dependency graph\n");
908 printf(" (for static linking)\n");
909 printf(" --shared use a simplified dependency graph (usually default)\n");
910 printf(" --pure optimize a static dependency graph as if it were a normal\n");
911 printf(" dependency graph\n");
912 printf(" --env-only look only for package entries in PKG_CONFIG_PATH\n");
913 printf(" --ignore-conflicts ignore 'conflicts' rules in modules\n");
914 printf(" --validate validate specific .pc files for correctness\n");
915
916 printf("\nquerying specific pkg-config database fields:\n\n");
917
918 printf(" --define-variable=varname=value define variable 'varname' as 'value'\n");
919 printf(" --variable=varname print specified variable entry to stdout\n");
920 printf(" --cflags print required CFLAGS to stdout\n");
921 printf(" --cflags-only-I print required include-dir CFLAGS to stdout\n");
922 printf(" --cflags-only-other print required non-include-dir CFLAGS to stdout\n");
923 printf(" --libs print required linker flags to stdout\n");
924 printf(" --libs-only-L print required LDPATH linker flags to stdout\n");
925 printf(" --libs-only-l print required LIBNAME linker flags to stdout\n");
926 printf(" --libs-only-other print required other linker flags to stdout\n");
927 printf(" --print-requires print required dependency frameworks to stdout\n");
928 printf(" --print-requires-private print required dependency frameworks for static\n");
929 printf(" linking to stdout\n");
930 printf(" --print-provides print provided dependencies to stdout\n");
931 printf(" --print-variables print all known variables in module to stdout\n");
932 #ifndef PKGCONF_LITE
933 printf(" --digraph print entire dependency graph in graphviz 'dot' format\n");
934 printf(" --solution print dependency graph solution in a simple format\n");
935 #endif
936 printf(" --keep-system-cflags keep -I%s entries in cflags output\n", SYSTEM_INCLUDEDIR);
937 printf(" --keep-system-libs keep -L%s entries in libs output\n", SYSTEM_LIBDIR);
938 printf(" --path show the exact filenames for any matching .pc files\n");
939 printf(" --modversion print the specified module's version to stdout\n");
940 printf(" --internal-cflags do not filter 'internal' cflags from output\n");
941 printf(" --license print the specified module's license to stdout if known\n");
942 printf(" --exists-cflags add -DHAVE_FOO fragments to cflags for each found module\n");
943
944 printf("\nfiltering output:\n\n");
945 #ifndef PKGCONF_LITE
946 printf(" --msvc-syntax print translatable fragments in MSVC syntax\n");
947 #endif
948 printf(" --fragment-filter=types filter output fragments to the specified types\n");
949 printf(" --env=prefix print output as shell-compatible environmental variables\n");
950 printf(" --fragment-tree visualize printed CFLAGS/LIBS fragments as a tree\n");
951
952 printf("\nreport bugs to <%s>.\n", PACKAGE_BUGREPORT);
953 }
954
955 static void
relocate_path(const char * path)956 relocate_path(const char *path)
957 {
958 char buf[PKGCONF_BUFSIZE];
959
960 pkgconf_strlcpy(buf, path, sizeof buf);
961 pkgconf_path_relocate(buf, sizeof buf);
962
963 printf("%s\n", buf);
964 }
965
966 #ifndef PKGCONF_LITE
967 static void
dump_personality(const pkgconf_cross_personality_t * p)968 dump_personality(const pkgconf_cross_personality_t *p)
969 {
970 pkgconf_node_t *n;
971
972 printf("Triplet: %s\n", p->name);
973
974 if (p->sysroot_dir)
975 printf("SysrootDir: %s\n", p->sysroot_dir);
976
977 printf("DefaultSearchPaths: ");
978 PKGCONF_FOREACH_LIST_ENTRY(p->dir_list.head, n)
979 {
980 pkgconf_path_t *pn = n->data;
981 printf("%s ", pn->path);
982 }
983
984 printf("\n");
985 printf("SystemIncludePaths: ");
986 PKGCONF_FOREACH_LIST_ENTRY(p->filter_includedirs.head, n)
987 {
988 pkgconf_path_t *pn = n->data;
989 printf("%s ", pn->path);
990 }
991
992 printf("\n");
993 printf("SystemLibraryPaths: ");
994 PKGCONF_FOREACH_LIST_ENTRY(p->filter_libdirs.head, n)
995 {
996 pkgconf_path_t *pn = n->data;
997 printf("%s ", pn->path);
998 }
999
1000 printf("\n");
1001 }
1002
1003 static pkgconf_cross_personality_t *
deduce_personality(char * argv[])1004 deduce_personality(char *argv[])
1005 {
1006 const char *argv0 = argv[0];
1007 char *i, *prefix;
1008 pkgconf_cross_personality_t *out;
1009
1010 i = strrchr(argv0, '/');
1011 if (i != NULL)
1012 argv0 = i + 1;
1013
1014 #if defined(_WIN32) || defined(_WIN64)
1015 i = strrchr(argv0, '\\');
1016 if (i != NULL)
1017 argv0 = i + 1;
1018 #endif
1019
1020 i = strstr(argv0, "-pkg");
1021 if (i == NULL)
1022 return pkgconf_cross_personality_default();
1023
1024 prefix = pkgconf_strndup(argv0, i - argv0);
1025 out = pkgconf_cross_personality_find(prefix);
1026 free(prefix);
1027 if (out == NULL)
1028 return pkgconf_cross_personality_default();
1029
1030 return out;
1031 }
1032 #endif
1033
1034 static void
unveil_handler(const pkgconf_client_t * client,const char * path,const char * permissions)1035 unveil_handler(const pkgconf_client_t *client, const char *path, const char *permissions)
1036 {
1037 (void) client;
1038
1039 if (pkgconf_unveil(path, permissions) == -1)
1040 {
1041 fprintf(stderr, "pkgconf: unveil failed: %s\n", strerror(errno));
1042 exit(EXIT_FAILURE);
1043 }
1044 }
1045
1046 static bool
unveil_search_paths(const pkgconf_client_t * client,const pkgconf_cross_personality_t * personality)1047 unveil_search_paths(const pkgconf_client_t *client, const pkgconf_cross_personality_t *personality)
1048 {
1049 pkgconf_node_t *n;
1050
1051 if (pkgconf_unveil("/dev/null", "rwc") == -1)
1052 return false;
1053
1054 PKGCONF_FOREACH_LIST_ENTRY(client->dir_list.head, n)
1055 {
1056 pkgconf_path_t *pn = n->data;
1057
1058 if (pkgconf_unveil(pn->path, "r") == -1)
1059 return false;
1060 }
1061
1062 PKGCONF_FOREACH_LIST_ENTRY(personality->dir_list.head, n)
1063 {
1064 pkgconf_path_t *pn = n->data;
1065
1066 if (pkgconf_unveil(pn->path, "r") == -1)
1067 return false;
1068 }
1069
1070 pkgconf_client_set_unveil_handler(&pkg_client, unveil_handler);
1071
1072 return true;
1073 }
1074
1075 int
main(int argc,char * argv[])1076 main(int argc, char *argv[])
1077 {
1078 int ret;
1079 pkgconf_list_t pkgq = PKGCONF_LIST_INITIALIZER;
1080 pkgconf_list_t dir_list = PKGCONF_LIST_INITIALIZER;
1081 char *builddir;
1082 char *sysroot_dir;
1083 char *env_traverse_depth;
1084 char *required_pkgconfig_version = NULL;
1085 char *required_exact_module_version = NULL;
1086 char *required_max_module_version = NULL;
1087 char *required_module_version = NULL;
1088 char *logfile_arg = NULL;
1089 char *want_env_prefix = NULL;
1090 unsigned int want_client_flags = PKGCONF_PKG_PKGF_NONE;
1091 pkgconf_cross_personality_t *personality = NULL;
1092 bool opened_error_msgout = false;
1093 pkgconf_pkg_t world = {
1094 .id = "virtual:world",
1095 .realname = "virtual world package",
1096 .flags = PKGCONF_PKG_PROPF_STATIC | PKGCONF_PKG_PROPF_VIRTUAL,
1097 };
1098
1099 if (pkgconf_pledge("stdio rpath wpath cpath unveil", NULL) == -1)
1100 {
1101 fprintf(stderr, "pkgconf: pledge failed: %s\n", strerror(errno));
1102 return EXIT_FAILURE;
1103 }
1104
1105 want_flags = 0;
1106
1107 #ifdef _WIN32
1108 /* When running regression tests in cygwin, and building native
1109 * executable, tests fail unless native executable outputs unix
1110 * line endings. Come to think of it, this will probably help
1111 * real people who use cygwin build environments but native pkgconf, too.
1112 */
1113 _setmode(fileno(stdout), O_BINARY);
1114 _setmode(fileno(stderr), O_BINARY);
1115 #endif
1116
1117 struct pkg_option options[] = {
1118 { "version", no_argument, &want_flags, PKG_VERSION|PKG_PRINT_ERRORS, },
1119 { "about", no_argument, &want_flags, PKG_ABOUT|PKG_PRINT_ERRORS, },
1120 { "atleast-version", required_argument, NULL, 2, },
1121 { "atleast-pkgconfig-version", required_argument, NULL, 3, },
1122 { "libs", no_argument, &want_flags, PKG_LIBS|PKG_PRINT_ERRORS, },
1123 { "cflags", no_argument, &want_flags, PKG_CFLAGS|PKG_PRINT_ERRORS, },
1124 { "modversion", no_argument, &want_flags, PKG_MODVERSION|PKG_PRINT_ERRORS, },
1125 { "variable", required_argument, NULL, 7, },
1126 { "exists", no_argument, &want_flags, PKG_EXISTS, },
1127 { "print-errors", no_argument, &want_flags, PKG_PRINT_ERRORS, },
1128 { "short-errors", no_argument, &want_flags, PKG_SHORT_ERRORS, },
1129 { "maximum-traverse-depth", required_argument, NULL, 11, },
1130 { "static", no_argument, &want_flags, PKG_STATIC, },
1131 { "shared", no_argument, &want_flags, PKG_SHARED, },
1132 { "pure", no_argument, &want_flags, PKG_PURE, },
1133 { "print-requires", no_argument, &want_flags, PKG_REQUIRES, },
1134 { "print-variables", no_argument, &want_flags, PKG_VARIABLES|PKG_PRINT_ERRORS, },
1135 #ifndef PKGCONF_LITE
1136 { "digraph", no_argument, &want_flags, PKG_DIGRAPH, },
1137 { "solution", no_argument, &want_flags, PKG_SOLUTION, },
1138 #endif
1139 { "help", no_argument, &want_flags, PKG_HELP, },
1140 { "env-only", no_argument, &want_flags, PKG_ENV_ONLY, },
1141 { "print-requires-private", no_argument, &want_flags, PKG_REQUIRES_PRIVATE, },
1142 { "cflags-only-I", no_argument, &want_flags, PKG_CFLAGS_ONLY_I|PKG_PRINT_ERRORS, },
1143 { "cflags-only-other", no_argument, &want_flags, PKG_CFLAGS_ONLY_OTHER|PKG_PRINT_ERRORS, },
1144 { "libs-only-L", no_argument, &want_flags, PKG_LIBS_ONLY_LDPATH|PKG_PRINT_ERRORS, },
1145 { "libs-only-l", no_argument, &want_flags, PKG_LIBS_ONLY_LIBNAME|PKG_PRINT_ERRORS, },
1146 { "libs-only-other", no_argument, &want_flags, PKG_LIBS_ONLY_OTHER|PKG_PRINT_ERRORS, },
1147 { "uninstalled", no_argument, &want_flags, PKG_UNINSTALLED, },
1148 { "no-uninstalled", no_argument, &want_flags, PKG_NO_UNINSTALLED, },
1149 { "keep-system-cflags", no_argument, &want_flags, PKG_KEEP_SYSTEM_CFLAGS, },
1150 { "keep-system-libs", no_argument, &want_flags, PKG_KEEP_SYSTEM_LIBS, },
1151 { "define-variable", required_argument, NULL, 27, },
1152 { "exact-version", required_argument, NULL, 28, },
1153 { "max-version", required_argument, NULL, 29, },
1154 { "ignore-conflicts", no_argument, &want_flags, PKG_IGNORE_CONFLICTS, },
1155 { "errors-to-stdout", no_argument, &want_flags, PKG_ERRORS_ON_STDOUT, },
1156 { "silence-errors", no_argument, &want_flags, PKG_SILENCE_ERRORS, },
1157 { "list-all", no_argument, &want_flags, PKG_LIST|PKG_PRINT_ERRORS, },
1158 { "list-package-names", no_argument, &want_flags, PKG_LIST_PACKAGE_NAMES|PKG_PRINT_ERRORS, },
1159 #ifndef PKGCONF_LITE
1160 { "simulate", no_argument, &want_flags, PKG_SIMULATE, },
1161 #endif
1162 { "no-cache", no_argument, &want_flags, PKG_NO_CACHE, },
1163 { "print-provides", no_argument, &want_flags, PKG_PROVIDES, },
1164 { "no-provides", no_argument, &want_flags, PKG_NO_PROVIDES, },
1165 { "debug", no_argument, &want_flags, PKG_DEBUG|PKG_PRINT_ERRORS, },
1166 { "validate", no_argument, &want_flags, PKG_VALIDATE|PKG_PRINT_ERRORS|PKG_ERRORS_ON_STDOUT },
1167 { "log-file", required_argument, NULL, 40 },
1168 { "path", no_argument, &want_flags, PKG_PATH },
1169 { "with-path", required_argument, NULL, 42 },
1170 { "prefix-variable", required_argument, NULL, 43 },
1171 { "define-prefix", no_argument, &want_flags, PKG_DEFINE_PREFIX },
1172 { "relocate", required_argument, NULL, 45 },
1173 { "dont-define-prefix", no_argument, &want_flags, PKG_DONT_DEFINE_PREFIX },
1174 { "dont-relocate-paths", no_argument, &want_flags, PKG_DONT_RELOCATE_PATHS },
1175 { "env", required_argument, NULL, 48 },
1176 #ifndef PKGCONF_LITE
1177 { "msvc-syntax", no_argument, &want_flags, PKG_MSVC_SYNTAX },
1178 #endif
1179 { "fragment-filter", required_argument, NULL, 50 },
1180 { "internal-cflags", no_argument, &want_flags, PKG_INTERNAL_CFLAGS },
1181 #ifndef PKGCONF_LITE
1182 { "dump-personality", no_argument, &want_flags, PKG_DUMP_PERSONALITY },
1183 { "personality", required_argument, NULL, 53 },
1184 #endif
1185 { "license", no_argument, &want_flags, PKG_DUMP_LICENSE },
1186 { "verbose", no_argument, NULL, 55 },
1187 { "exists-cflags", no_argument, &want_flags, PKG_EXISTS_CFLAGS },
1188 { "fragment-tree", no_argument, &want_flags, PKG_FRAGMENT_TREE },
1189 { NULL, 0, NULL, 0 }
1190 };
1191
1192 #ifndef PKGCONF_LITE
1193 if (getenv("PKG_CONFIG_EARLY_TRACE"))
1194 {
1195 error_msgout = stderr;
1196 pkgconf_client_set_trace_handler(&pkg_client, error_handler, NULL);
1197 }
1198 #endif
1199
1200 while ((ret = pkg_getopt_long_only(argc, argv, "", options, NULL)) != -1)
1201 {
1202 switch (ret)
1203 {
1204 case 2:
1205 required_module_version = pkg_optarg;
1206 break;
1207 case 3:
1208 required_pkgconfig_version = pkg_optarg;
1209 break;
1210 case 7:
1211 want_variable = pkg_optarg;
1212 break;
1213 case 11:
1214 maximum_traverse_depth = atoi(pkg_optarg);
1215 break;
1216 case 27:
1217 pkgconf_tuple_define_global(&pkg_client, pkg_optarg);
1218 break;
1219 case 28:
1220 required_exact_module_version = pkg_optarg;
1221 break;
1222 case 29:
1223 required_max_module_version = pkg_optarg;
1224 break;
1225 case 40:
1226 logfile_arg = pkg_optarg;
1227 break;
1228 case 42:
1229 pkgconf_path_prepend(pkg_optarg, &dir_list, true);
1230 break;
1231 case 43:
1232 pkgconf_client_set_prefix_varname(&pkg_client, pkg_optarg);
1233 break;
1234 case 45:
1235 relocate_path(pkg_optarg);
1236 return EXIT_SUCCESS;
1237 case 48:
1238 want_env_prefix = pkg_optarg;
1239 break;
1240 case 50:
1241 want_fragment_filter = pkg_optarg;
1242 break;
1243 #ifndef PKGCONF_LITE
1244 case 53:
1245 personality = pkgconf_cross_personality_find(pkg_optarg);
1246 break;
1247 #endif
1248 case 55:
1249 verbosity++;
1250 break;
1251 case '?':
1252 case ':':
1253 ret = EXIT_FAILURE;
1254 goto out;
1255 default:
1256 break;
1257 }
1258 }
1259
1260 if (personality == NULL) {
1261 #ifndef PKGCONF_LITE
1262 personality = deduce_personality(argv);
1263 #else
1264 personality = pkgconf_cross_personality_default();
1265 #endif
1266 }
1267
1268 #ifndef PKGCONF_LITE
1269 if ((want_flags & PKG_DUMP_PERSONALITY) == PKG_DUMP_PERSONALITY)
1270 {
1271 dump_personality(personality);
1272 return EXIT_SUCCESS;
1273 }
1274 #endif
1275
1276 /* now, bring up the client. settings are preserved since the client is prealloced */
1277 pkgconf_client_init(&pkg_client, error_handler, NULL, personality);
1278
1279 /* unveil the entire search path now that we have loaded the personality data. */
1280 if (!unveil_search_paths(&pkg_client, personality))
1281 {
1282 fprintf(stderr, "pkgconf: unveil failed: %s\n", strerror(errno));
1283 return EXIT_FAILURE;
1284 }
1285
1286 #ifndef PKGCONF_LITE
1287 if ((want_flags & PKG_MSVC_SYNTAX) == PKG_MSVC_SYNTAX || getenv("PKG_CONFIG_MSVC_SYNTAX") != NULL)
1288 want_render_ops = msvc_renderer_get();
1289 #endif
1290
1291 if ((env_traverse_depth = getenv("PKG_CONFIG_MAXIMUM_TRAVERSE_DEPTH")) != NULL)
1292 maximum_traverse_depth = atoi(env_traverse_depth);
1293
1294 if ((want_flags & PKG_PRINT_ERRORS) != PKG_PRINT_ERRORS)
1295 want_flags |= (PKG_SILENCE_ERRORS);
1296
1297 if ((want_flags & PKG_SILENCE_ERRORS) == PKG_SILENCE_ERRORS && !getenv("PKG_CONFIG_DEBUG_SPEW"))
1298 want_flags |= (PKG_SILENCE_ERRORS);
1299 else
1300 want_flags &= ~(PKG_SILENCE_ERRORS);
1301
1302 if (getenv("PKG_CONFIG_DONT_RELOCATE_PATHS"))
1303 want_flags |= (PKG_DONT_RELOCATE_PATHS);
1304
1305 if ((want_flags & PKG_VALIDATE) == PKG_VALIDATE || (want_flags & PKG_DEBUG) == PKG_DEBUG)
1306 pkgconf_client_set_warn_handler(&pkg_client, error_handler, NULL);
1307
1308 #ifndef PKGCONF_LITE
1309 if ((want_flags & PKG_DEBUG) == PKG_DEBUG)
1310 pkgconf_client_set_trace_handler(&pkg_client, error_handler, NULL);
1311 #endif
1312
1313 pkgconf_path_prepend_list(&pkg_client.dir_list, &dir_list);
1314 pkgconf_path_free(&dir_list);
1315
1316 if ((want_flags & PKG_ABOUT) == PKG_ABOUT)
1317 {
1318 about();
1319
1320 ret = EXIT_SUCCESS;
1321 goto out;
1322 }
1323
1324 if ((want_flags & PKG_VERSION) == PKG_VERSION)
1325 {
1326 version();
1327
1328 ret = EXIT_SUCCESS;
1329 goto out;
1330 }
1331
1332 if ((want_flags & PKG_HELP) == PKG_HELP)
1333 {
1334 usage();
1335
1336 ret = EXIT_SUCCESS;
1337 goto out;
1338 }
1339
1340 if (getenv("PKG_CONFIG_FDO_SYSROOT_RULES"))
1341 want_client_flags |= PKGCONF_PKG_PKGF_FDO_SYSROOT_RULES;
1342
1343 if (getenv("PKG_CONFIG_PKGCONF1_SYSROOT_RULES"))
1344 want_client_flags |= PKGCONF_PKG_PKGF_PKGCONF1_SYSROOT_RULES;
1345
1346 if ((want_flags & PKG_SHORT_ERRORS) == PKG_SHORT_ERRORS)
1347 want_client_flags |= PKGCONF_PKG_PKGF_SIMPLIFY_ERRORS;
1348
1349 if ((want_flags & PKG_DONT_RELOCATE_PATHS) == PKG_DONT_RELOCATE_PATHS)
1350 want_client_flags |= PKGCONF_PKG_PKGF_DONT_RELOCATE_PATHS;
1351
1352 error_msgout = stderr;
1353 if ((want_flags & PKG_ERRORS_ON_STDOUT) == PKG_ERRORS_ON_STDOUT)
1354 error_msgout = stdout;
1355 if ((want_flags & PKG_SILENCE_ERRORS) == PKG_SILENCE_ERRORS) {
1356 error_msgout = fopen(PATH_DEV_NULL, "w");
1357 opened_error_msgout = true;
1358 }
1359
1360 if ((want_flags & PKG_IGNORE_CONFLICTS) == PKG_IGNORE_CONFLICTS || getenv("PKG_CONFIG_IGNORE_CONFLICTS") != NULL)
1361 want_client_flags |= PKGCONF_PKG_PKGF_SKIP_CONFLICTS;
1362
1363 if ((want_flags & PKG_STATIC) == PKG_STATIC || personality->want_default_static)
1364 want_client_flags |= (PKGCONF_PKG_PKGF_SEARCH_PRIVATE | PKGCONF_PKG_PKGF_MERGE_PRIVATE_FRAGMENTS);
1365
1366 if ((want_flags & PKG_SHARED) == PKG_SHARED)
1367 want_client_flags &= ~(PKGCONF_PKG_PKGF_SEARCH_PRIVATE | PKGCONF_PKG_PKGF_MERGE_PRIVATE_FRAGMENTS);
1368
1369 /* if --static and --pure are both specified, then disable merge-back.
1370 * this allows for a --static which searches private modules, but has the same fragment behaviour as if
1371 * --static were disabled. see <https://github.com/pkgconf/pkgconf/issues/83> for rationale.
1372 */
1373 if ((want_flags & PKG_PURE) == PKG_PURE || getenv("PKG_CONFIG_PURE_DEPGRAPH") != NULL || personality->want_default_pure)
1374 want_client_flags &= ~PKGCONF_PKG_PKGF_MERGE_PRIVATE_FRAGMENTS;
1375
1376 if ((want_flags & PKG_ENV_ONLY) == PKG_ENV_ONLY)
1377 want_client_flags |= PKGCONF_PKG_PKGF_ENV_ONLY;
1378
1379 if ((want_flags & PKG_NO_CACHE) == PKG_NO_CACHE)
1380 want_client_flags |= PKGCONF_PKG_PKGF_NO_CACHE;
1381
1382 /* On Windows we want to always redefine the prefix by default
1383 * but allow that behavior to be manually disabled */
1384 #if !defined(_WIN32) && !defined(_WIN64)
1385 if ((want_flags & PKG_DEFINE_PREFIX) == PKG_DEFINE_PREFIX || getenv("PKG_CONFIG_RELOCATE_PATHS") != NULL)
1386 #endif
1387 want_client_flags |= PKGCONF_PKG_PKGF_REDEFINE_PREFIX;
1388
1389 if ((want_flags & PKG_NO_UNINSTALLED) == PKG_NO_UNINSTALLED || getenv("PKG_CONFIG_DISABLE_UNINSTALLED") != NULL)
1390 want_client_flags |= PKGCONF_PKG_PKGF_NO_UNINSTALLED;
1391
1392 if ((want_flags & PKG_NO_PROVIDES) == PKG_NO_PROVIDES)
1393 want_client_flags |= PKGCONF_PKG_PKGF_SKIP_PROVIDES;
1394
1395 if ((want_flags & PKG_DONT_DEFINE_PREFIX) == PKG_DONT_DEFINE_PREFIX || getenv("PKG_CONFIG_DONT_DEFINE_PREFIX") != NULL)
1396 want_client_flags &= ~PKGCONF_PKG_PKGF_REDEFINE_PREFIX;
1397
1398 if ((want_flags & PKG_INTERNAL_CFLAGS) == PKG_INTERNAL_CFLAGS)
1399 want_client_flags |= PKGCONF_PKG_PKGF_DONT_FILTER_INTERNAL_CFLAGS;
1400
1401 /* if these selectors are used, it means that we are querying metadata.
1402 * so signal to libpkgconf that we only want to walk the flattened dependency set.
1403 */
1404 if ((want_flags & PKG_MODVERSION) == PKG_MODVERSION ||
1405 (want_flags & PKG_REQUIRES) == PKG_REQUIRES ||
1406 (want_flags & PKG_REQUIRES_PRIVATE) == PKG_REQUIRES_PRIVATE ||
1407 (want_flags & PKG_PROVIDES) == PKG_PROVIDES ||
1408 (want_flags & PKG_VARIABLES) == PKG_VARIABLES ||
1409 (want_flags & PKG_PATH) == PKG_PATH ||
1410 want_variable != NULL)
1411 maximum_traverse_depth = 1;
1412
1413 /* if we are asking for a variable, path or list of variables, this only makes sense
1414 * for a single package.
1415 */
1416 if ((want_flags & PKG_VARIABLES) == PKG_VARIABLES ||
1417 (want_flags & PKG_PATH) == PKG_PATH ||
1418 want_variable != NULL)
1419 maximum_package_count = 1;
1420
1421 if (getenv("PKG_CONFIG_ALLOW_SYSTEM_CFLAGS") != NULL)
1422 want_flags |= PKG_KEEP_SYSTEM_CFLAGS;
1423
1424 if (getenv("PKG_CONFIG_ALLOW_SYSTEM_LIBS") != NULL)
1425 want_flags |= PKG_KEEP_SYSTEM_LIBS;
1426
1427 if ((builddir = getenv("PKG_CONFIG_TOP_BUILD_DIR")) != NULL)
1428 pkgconf_client_set_buildroot_dir(&pkg_client, builddir);
1429
1430 if ((want_flags & PKG_REQUIRES_PRIVATE) == PKG_REQUIRES_PRIVATE ||
1431 (want_flags & PKG_CFLAGS))
1432 {
1433 want_client_flags |= PKGCONF_PKG_PKGF_SEARCH_PRIVATE;
1434 }
1435
1436 if ((sysroot_dir = getenv("PKG_CONFIG_SYSROOT_DIR")) != NULL)
1437 {
1438 const char *destdir;
1439
1440 pkgconf_client_set_sysroot_dir(&pkg_client, sysroot_dir);
1441
1442 if ((destdir = getenv("DESTDIR")) != NULL)
1443 {
1444 if (!strcmp(destdir, sysroot_dir))
1445 want_client_flags |= PKGCONF_PKG_PKGF_FDO_SYSROOT_RULES;
1446 }
1447 }
1448
1449 /* we have determined what features we want most likely. in some cases, we override later. */
1450 pkgconf_client_set_flags(&pkg_client, want_client_flags);
1451
1452 /* at this point, want_client_flags should be set, so build the dir list */
1453 pkgconf_client_dir_list_build(&pkg_client, personality);
1454
1455 /* preload any files in PKG_CONFIG_PRELOADED_FILES */
1456 pkgconf_client_preload_from_environ(&pkg_client, "PKG_CONFIG_PRELOADED_FILES");
1457
1458 if (required_pkgconfig_version != NULL)
1459 {
1460 if (pkgconf_compare_version(PACKAGE_VERSION, required_pkgconfig_version) >= 0)
1461 ret = EXIT_SUCCESS;
1462 else
1463 ret = EXIT_FAILURE;
1464
1465 goto out;
1466 }
1467
1468 if ((want_flags & PKG_LIST) == PKG_LIST)
1469 {
1470 pkgconf_scan_all(&pkg_client, NULL, print_list_entry);
1471 ret = EXIT_SUCCESS;
1472 goto out;
1473 }
1474
1475 if ((want_flags & PKG_LIST_PACKAGE_NAMES) == PKG_LIST_PACKAGE_NAMES)
1476 {
1477 pkgconf_scan_all(&pkg_client, NULL, print_package_entry);
1478 ret = EXIT_SUCCESS;
1479 goto out;
1480 }
1481
1482 if (logfile_arg == NULL)
1483 logfile_arg = getenv("PKG_CONFIG_LOG");
1484
1485 if (logfile_arg != NULL)
1486 {
1487 if (pkgconf_unveil(logfile_arg, "rwc") == -1)
1488 {
1489 fprintf(stderr, "pkgconf: unveil failed: %s\n", strerror(errno));
1490 return EXIT_FAILURE;
1491 }
1492
1493 logfile_out = fopen(logfile_arg, "w");
1494 pkgconf_audit_set_log(&pkg_client, logfile_out);
1495 }
1496
1497 if (required_module_version != NULL)
1498 {
1499 pkgconf_pkg_t *pkg = NULL;
1500 pkgconf_node_t *node;
1501 pkgconf_list_t deplist = PKGCONF_LIST_INITIALIZER;
1502
1503 while (argv[pkg_optind])
1504 {
1505 pkgconf_dependency_parse_str(&pkg_client, &deplist, argv[pkg_optind], 0);
1506 pkg_optind++;
1507 }
1508
1509 PKGCONF_FOREACH_LIST_ENTRY(deplist.head, node)
1510 {
1511 pkgconf_dependency_t *pkgiter = node->data;
1512
1513 pkg = pkgconf_pkg_find(&pkg_client, pkgiter->package);
1514 if (pkg == NULL)
1515 {
1516 if (want_flags & PKG_PRINT_ERRORS)
1517 pkgconf_error(&pkg_client, "Package '%s' was not found\n", pkgiter->package);
1518
1519 ret = EXIT_FAILURE;
1520 goto cleanup;
1521 }
1522
1523 if (pkgconf_compare_version(pkg->version, required_module_version) >= 0)
1524 {
1525 ret = EXIT_SUCCESS;
1526 goto cleanup;
1527 }
1528 }
1529
1530 ret = EXIT_FAILURE;
1531 cleanup:
1532 if (pkg != NULL)
1533 pkgconf_pkg_unref(&pkg_client, pkg);
1534 pkgconf_dependency_free(&deplist);
1535 goto out;
1536 }
1537 else if (required_exact_module_version != NULL)
1538 {
1539 pkgconf_pkg_t *pkg = NULL;
1540 pkgconf_node_t *node;
1541 pkgconf_list_t deplist = PKGCONF_LIST_INITIALIZER;
1542
1543 while (argv[pkg_optind])
1544 {
1545 pkgconf_dependency_parse_str(&pkg_client, &deplist, argv[pkg_optind], 0);
1546 pkg_optind++;
1547 }
1548
1549 PKGCONF_FOREACH_LIST_ENTRY(deplist.head, node)
1550 {
1551 pkgconf_dependency_t *pkgiter = node->data;
1552
1553 pkg = pkgconf_pkg_find(&pkg_client, pkgiter->package);
1554 if (pkg == NULL)
1555 {
1556 if (want_flags & PKG_PRINT_ERRORS)
1557 pkgconf_error(&pkg_client, "Package '%s' was not found\n", pkgiter->package);
1558
1559 ret = EXIT_FAILURE;
1560 goto cleanup2;
1561 }
1562
1563 if (pkgconf_compare_version(pkg->version, required_exact_module_version) == 0)
1564 {
1565 ret = EXIT_SUCCESS;
1566 goto cleanup2;
1567 }
1568 }
1569
1570 ret = EXIT_FAILURE;
1571 cleanup2:
1572 if (pkg != NULL)
1573 pkgconf_pkg_unref(&pkg_client, pkg);
1574 pkgconf_dependency_free(&deplist);
1575 goto out;
1576 }
1577 else if (required_max_module_version != NULL)
1578 {
1579 pkgconf_pkg_t *pkg = NULL;
1580 pkgconf_node_t *node;
1581 pkgconf_list_t deplist = PKGCONF_LIST_INITIALIZER;
1582
1583 while (argv[pkg_optind])
1584 {
1585 pkgconf_dependency_parse_str(&pkg_client, &deplist, argv[pkg_optind], 0);
1586 pkg_optind++;
1587 }
1588
1589 PKGCONF_FOREACH_LIST_ENTRY(deplist.head, node)
1590 {
1591 pkgconf_dependency_t *pkgiter = node->data;
1592
1593 pkg = pkgconf_pkg_find(&pkg_client, pkgiter->package);
1594 if (pkg == NULL)
1595 {
1596 if (want_flags & PKG_PRINT_ERRORS)
1597 pkgconf_error(&pkg_client, "Package '%s' was not found\n", pkgiter->package);
1598
1599 ret = EXIT_FAILURE;
1600 goto cleanup3;
1601 }
1602
1603 if (pkgconf_compare_version(pkg->version, required_max_module_version) <= 0)
1604 {
1605 ret = EXIT_SUCCESS;
1606 goto cleanup3;
1607 }
1608 }
1609
1610 ret = EXIT_FAILURE;
1611 cleanup3:
1612 if (pkg != NULL)
1613 pkgconf_pkg_unref(&pkg_client, pkg);
1614 pkgconf_dependency_free(&deplist);
1615 goto out;
1616 }
1617
1618 while (1)
1619 {
1620 char *package = argv[pkg_optind];
1621 char *end;
1622
1623 if (package == NULL)
1624 break;
1625
1626 /* check if there is a limit to the number of packages allowed to be included, if so and we have hit
1627 * the limit, stop adding packages to the queue.
1628 */
1629 if (maximum_package_count > 0 && pkgq.length >= maximum_package_count)
1630 break;
1631
1632 while (isspace((unsigned char)package[0]))
1633 package++;
1634
1635 /* skip empty packages */
1636 if (package[0] == '\0') {
1637 pkg_optind++;
1638 continue;
1639 }
1640
1641 end = package + strlen(package) - 1;
1642 while(end > package && isspace((unsigned char)end[0])) end--;
1643 end[1] = '\0';
1644
1645 if (argv[pkg_optind + 1] == NULL || !PKGCONF_IS_OPERATOR_CHAR(*(argv[pkg_optind + 1])))
1646 {
1647 pkgconf_queue_push(&pkgq, package);
1648 pkg_optind++;
1649 }
1650 else if (argv[pkg_optind + 2] == NULL)
1651 {
1652 char packagebuf[PKGCONF_BUFSIZE];
1653
1654 snprintf(packagebuf, sizeof packagebuf, "%s %s", package, argv[pkg_optind + 1]);
1655 pkg_optind += 2;
1656
1657 pkgconf_queue_push(&pkgq, packagebuf);
1658 }
1659 else
1660 {
1661 char packagebuf[PKGCONF_BUFSIZE];
1662
1663 snprintf(packagebuf, sizeof packagebuf, "%s %s %s", package, argv[pkg_optind + 1], argv[pkg_optind + 2]);
1664 pkg_optind += 3;
1665
1666 pkgconf_queue_push(&pkgq, packagebuf);
1667 }
1668 }
1669
1670 if (pkgq.head == NULL)
1671 {
1672 fprintf(stderr, "Please specify at least one package name on the command line.\n");
1673 ret = EXIT_FAILURE;
1674 goto out;
1675 }
1676
1677 ret = EXIT_SUCCESS;
1678
1679 if (!pkgconf_queue_solve(&pkg_client, &pkgq, &world, maximum_traverse_depth))
1680 {
1681 ret = EXIT_FAILURE;
1682 goto out;
1683 }
1684
1685 /* we shouldn't need to unveil any more filesystem accesses from this point, so lock it down */
1686 if (pkgconf_unveil(NULL, NULL) == -1)
1687 {
1688 fprintf(stderr, "pkgconf: unveil lockdown failed: %s\n", strerror(errno));
1689 return EXIT_FAILURE;
1690 }
1691
1692 #ifndef PKGCONF_LITE
1693 if ((want_flags & PKG_SIMULATE) == PKG_SIMULATE)
1694 {
1695 want_flags &= ~(PKG_CFLAGS|PKG_LIBS);
1696
1697 pkgconf_client_set_flags(&pkg_client, want_client_flags | PKGCONF_PKG_PKGF_SKIP_ERRORS);
1698 apply_simulate(&pkg_client, &world, NULL, -1);
1699 }
1700 #endif
1701
1702 if ((want_flags & PKG_VALIDATE) == PKG_VALIDATE)
1703 goto out;
1704
1705 if ((want_flags & PKG_DUMP_LICENSE) == PKG_DUMP_LICENSE)
1706 {
1707 apply_license(&pkg_client, &world, &ret, 2);
1708 goto out;
1709 }
1710
1711 if ((want_flags & PKG_UNINSTALLED) == PKG_UNINSTALLED)
1712 {
1713 ret = EXIT_FAILURE;
1714 apply_uninstalled(&pkg_client, &world, &ret, 2);
1715 goto out;
1716 }
1717
1718 if (want_env_prefix != NULL)
1719 {
1720 apply_env(&pkg_client, &world, want_env_prefix, 2);
1721 goto out;
1722 }
1723
1724 if ((want_flags & PKG_PROVIDES) == PKG_PROVIDES)
1725 {
1726 want_flags &= ~(PKG_CFLAGS|PKG_LIBS);
1727 apply_provides(&pkg_client, &world, NULL, 2);
1728 }
1729
1730 #ifndef PKGCONF_LITE
1731 if ((want_flags & PKG_DIGRAPH) == PKG_DIGRAPH)
1732 {
1733 want_flags &= ~(PKG_CFLAGS|PKG_LIBS);
1734 apply_digraph(&pkg_client, &world, &pkgq, 2);
1735 }
1736
1737 if ((want_flags & PKG_SOLUTION) == PKG_SOLUTION)
1738 {
1739 want_flags &= ~(PKG_CFLAGS|PKG_LIBS);
1740 apply_print_solution(&pkg_client, &world, NULL, 2);
1741 }
1742 #endif
1743
1744 if ((want_flags & PKG_MODVERSION) == PKG_MODVERSION)
1745 {
1746 want_flags &= ~(PKG_CFLAGS|PKG_LIBS);
1747 apply_modversion(&pkg_client, &world, &pkgq, 2);
1748 }
1749
1750 if ((want_flags & PKG_PATH) == PKG_PATH)
1751 {
1752 want_flags &= ~(PKG_CFLAGS|PKG_LIBS);
1753
1754 pkgconf_client_set_flags(&pkg_client, want_client_flags | PKGCONF_PKG_PKGF_SKIP_ROOT_VIRTUAL);
1755 apply_path(&pkg_client, &world, NULL, 2);
1756 }
1757
1758 if ((want_flags & PKG_VARIABLES) == PKG_VARIABLES)
1759 {
1760 want_flags &= ~(PKG_CFLAGS|PKG_LIBS);
1761 apply_variables(&pkg_client, &world, NULL, 2);
1762 }
1763
1764 if (want_variable)
1765 {
1766 want_flags &= ~(PKG_CFLAGS|PKG_LIBS);
1767
1768 pkgconf_client_set_flags(&pkg_client, want_client_flags | PKGCONF_PKG_PKGF_SKIP_ROOT_VIRTUAL);
1769 apply_variable(&pkg_client, &world, want_variable, 2);
1770 }
1771
1772 if ((want_flags & PKG_REQUIRES) == PKG_REQUIRES)
1773 {
1774 want_flags &= ~(PKG_CFLAGS|PKG_LIBS);
1775 apply_requires(&pkg_client, &world, NULL, 2);
1776 }
1777
1778 if ((want_flags & PKG_REQUIRES_PRIVATE) == PKG_REQUIRES_PRIVATE)
1779 {
1780 want_flags &= ~(PKG_CFLAGS|PKG_LIBS);
1781
1782 apply_requires_private(&pkg_client, &world, NULL, 2);
1783 }
1784
1785 if ((want_flags & PKG_FRAGMENT_TREE))
1786 {
1787 want_flags &= ~(PKG_CFLAGS|PKG_LIBS);
1788
1789 apply_fragment_tree(&pkg_client, &world, NULL, 2);
1790 }
1791
1792 if ((want_flags & PKG_CFLAGS))
1793 {
1794 apply_cflags(&pkg_client, &world, NULL, 2);
1795 }
1796
1797 if ((want_flags & PKG_LIBS))
1798 {
1799 if (want_flags & PKG_CFLAGS)
1800 printf(" ");
1801
1802 if (!(want_flags & PKG_STATIC))
1803 pkgconf_client_set_flags(&pkg_client, pkg_client.flags & ~PKGCONF_PKG_PKGF_SEARCH_PRIVATE);
1804
1805 apply_libs(&pkg_client, &world, NULL, 2);
1806 }
1807
1808 if (want_flags & (PKG_CFLAGS|PKG_LIBS))
1809 printf("\n");
1810
1811 out:
1812 pkgconf_solution_free(&pkg_client, &world);
1813 pkgconf_queue_free(&pkgq);
1814 pkgconf_cross_personality_deinit(personality);
1815 pkgconf_client_deinit(&pkg_client);
1816
1817 if (logfile_out != NULL)
1818 fclose(logfile_out);
1819 if (opened_error_msgout)
1820 fclose(error_msgout);
1821
1822 return ret;
1823 }
1824