xref: /freebsd/contrib/pkgconf/cli/main.c (revision a259b98fa211ed87bfee58c575de4e2de94ee0fa)
1 /*
2  * main.c
3  * main() routine
4  *
5  * SPDX-License-Identifier: pkgconf
6  *
7  * Copyright (c) 2011-2025 pkgconf authors (see AUTHORS).
8  *
9  * Permission to use, copy, modify, and/or distribute this software for any
10  * purpose with or without fee is hereby granted, provided that the above
11  * copyright notice and this permission notice appear in all copies.
12  *
13  * This software is provided 'as is' and without any warranty, express or
14  * implied.  In no event shall the authors be liable for any damages arising
15  * from the use of this software.
16  */
17 
18 #include "libpkgconf/config.h"
19 #include <libpkgconf/stdinc.h>
20 #include <libpkgconf/libpkgconf.h>
21 #include "getopt_long.h"
22 #include "core.h"
23 
24 static const char *
25 environ_lookup_handler(const pkgconf_client_t *client, const char *key)
26 {
27 	(void) client;
28 
29 	return getenv(key);
30 }
31 
32 static bool
33 error_handler(const char *msg, const pkgconf_client_t *client, void *data)
34 {
35 	(void) data;
36 	pkgconf_cli_state_t *state = client->client_data;
37 
38 	if (state->error_msgout == NULL)
39 		return true;
40 
41 	pkgconf_output_file_fmt(state->error_msgout, "%s", msg);
42 	return true;
43 }
44 
45 static void
46 unveil_handler(const pkgconf_client_t *client, const char *path, const char *permissions)
47 {
48 	(void) client;
49 
50 	if (pkgconf_unveil(path, permissions) == -1 && errno != ENOENT)
51 	{
52 		pkgconf_output_file_fmt(stderr, "pkgconf: unveil failed: %s\n", strerror(errno));
53 		exit(EXIT_FAILURE);
54 	}
55 }
56 
57 #ifndef PKGCONF_LITE
58 static pkgconf_cross_personality_t *
59 deduce_personality(char *argv[])
60 {
61 	const char *argv0 = argv[0];
62 	char *i, *prefix;
63 	pkgconf_cross_personality_t *out;
64 
65 	i = strrchr(argv0, '/');
66 	if (i != NULL)
67 		argv0 = i + 1;
68 
69 #if defined(_WIN32) || defined(_WIN64)
70 	i = strrchr(argv0, '\\');
71 	if (i != NULL)
72 		argv0 = i + 1;
73 #endif
74 
75 	i = strstr(argv0, "-pkg");
76 	if (i == NULL)
77 		return pkgconf_cross_personality_default();
78 
79 	prefix = pkgconf_strndup(argv0, i - argv0);
80 	out = pkgconf_cross_personality_find(prefix);
81 	free(prefix);
82 	if (out == NULL)
83 		return pkgconf_cross_personality_default();
84 
85 	return out;
86 }
87 #endif
88 
89 #ifdef _WIN32
90 static UINT original_console_cp;
91 static UINT original_console_out_cp;
92 
93 static void
94 restore_console_code_page(void)
95 {
96 	SetConsoleCP(original_console_cp);
97 	SetConsoleOutputCP(original_console_out_cp);
98 }
99 #endif
100 
101 static void
102 version(void)
103 {
104 	printf("%s\n", PACKAGE_VERSION);
105 }
106 
107 static void
108 about(void)
109 {
110 	printf("%s %s\n", PACKAGE_NAME, PACKAGE_VERSION);
111 	printf("Copyright (c) 2011-2026 pkgconf authors (see AUTHORS in documentation directory)\n\n");
112 	printf("Permission to use, copy, modify, and/or distribute this software for any\n");
113 	printf("purpose with or without fee is hereby granted, provided that the above\n");
114 	printf("copyright notice and this permission notice appear in all copies.\n\n");
115 	printf("This software is provided 'as is' and without any warranty, express or\n");
116 	printf("implied.  In no event shall the authors be liable for any damages arising\n");
117 	printf("from the use of this software.\n\n");
118 	printf("Report bugs at <%s>.\n", PACKAGE_BUGREPORT);
119 }
120 
121 static void
122 usage(void)
123 {
124 	printf("usage: %s [OPTIONS] [LIBRARIES]\n", PACKAGE_NAME);
125 
126 	printf("\nbasic options:\n\n");
127 
128 	printf("  --help                            this message\n");
129 	printf("  --about                           print pkgconf version and license to stdout\n");
130 	printf("  --version                         print supported pkg-config version to stdout\n");
131 	printf("  --verbose                         print additional information\n");
132 	printf("  --atleast-pkgconfig-version       check whether or not pkgconf is compatible\n");
133 	printf("                                    with a specified pkg-config version\n");
134 	printf("  --errors-to-stdout                print all errors on stdout instead of stderr\n");
135 	printf("  --print-errors                    ensure all errors are printed\n");
136 	printf("  --short-errors                    be less verbose about some errors\n");
137 	printf("  --silence-errors                  explicitly be silent about errors\n");
138 	printf("  --list-all                        list all known packages\n");
139 	printf("  --list-package-names              list all known package names\n");
140 #ifndef PKGCONF_LITE
141 	printf("  --simulate                        simulate walking the calculated dependency graph\n");
142 #endif
143 	printf("  --no-cache                        do not cache already seen packages when\n");
144 	printf("                                    walking the dependency graph\n");
145 	printf("  --log-file=filename               write an audit log to a specified file\n");
146 	printf("  --with-path=path                  adds a directory to the search path\n");
147 	printf("  --define-prefix                   override the prefix variable with one that is guessed based on\n");
148 	printf("                                    the location of the .pc file\n");
149 	printf("  --dont-define-prefix              do not override the prefix variable under any circumstances\n");
150 	printf("  --prefix-variable=varname         sets the name of the variable that pkgconf considers\n");
151 	printf("                                    to be the package prefix\n");
152 	printf("  --dont-relocate-paths             disables path relocation support\n");
153 
154 #ifndef PKGCONF_LITE
155 	printf("\ncross-compilation personality support:\n\n");
156 	printf("  --personality=triplet|filename    sets the personality to 'triplet' or a file named 'filename'\n");
157 	printf("  --dump-personality                dumps details concerning selected personality\n");
158 #endif
159 
160 	printf("\nchecking specific pkg-config database entries:\n\n");
161 
162 	printf("  --atleast-version                 require a specific version of a module\n");
163 	printf("  --exact-version                   require an exact version of a module\n");
164 	printf("  --max-version                     require a maximum version of a module\n");
165 	printf("  --exists                          check whether or not a module exists\n");
166 	printf("  --uninstalled                     check whether or not an uninstalled module will be used\n");
167 	printf("  --no-uninstalled                  never use uninstalled modules when satisfying dependencies\n");
168 	printf("  --no-provides                     do not use 'provides' rules to resolve dependencies\n");
169 	printf("  --maximum-traverse-depth          maximum allowed depth for dependency graph\n");
170 	printf("  --static                          be more aggressive when computing dependency graph\n");
171 	printf("                                    (for static linking)\n");
172 	printf("  --shared                          use a simplified dependency graph (usually default)\n");
173 	printf("  --pure                            optimize a static dependency graph as if it were a normal\n");
174 	printf("                                    dependency graph\n");
175 	printf("  --env-only                        look only for package entries in PKG_CONFIG_PATH\n");
176 	printf("  --ignore-conflicts                ignore 'conflicts' rules in modules\n");
177 	printf("  --validate                        validate specific .pc files for correctness\n");
178 
179 	printf("\nquerying specific pkg-config database fields:\n\n");
180 
181 	printf("  --define-variable=varname=value   define variable 'varname' as 'value'\n");
182 	printf("  --variable=varname                print specified variable entry to stdout\n");
183 	printf("  --cflags                          print required CFLAGS to stdout\n");
184 	printf("  --cflags-only-I                   print required include-dir CFLAGS to stdout\n");
185 	printf("  --cflags-only-other               print required non-include-dir CFLAGS to stdout\n");
186 	printf("  --libs                            print required linker flags to stdout\n");
187 	printf("  --libs-only-L                     print required LDPATH linker flags to stdout\n");
188 	printf("  --libs-only-l                     print required LIBNAME linker flags to stdout\n");
189 	printf("  --libs-only-other                 print required other linker flags to stdout\n");
190 	printf("  --print-requires                  print required dependency frameworks to stdout\n");
191 	printf("  --print-requires-private          print required dependency frameworks for static\n");
192 	printf("                                    linking to stdout\n");
193 	printf("  --print-provides                  print provided dependencies to stdout\n");
194 	printf("  --print-variables                 print all known variables in module to stdout\n");
195 #ifndef PKGCONF_LITE
196 	printf("  --digraph                         print entire dependency graph in graphviz 'dot' format\n");
197 	printf("  --print-digraph-query-nodes       also print query nodes in 'dot' format\n");
198 	printf("  --solution                        print dependency graph solution in a simple format\n");
199 #endif
200 	printf("  --keep-system-cflags              keep -I%s entries in cflags output\n", SYSTEM_INCLUDEDIR);
201 	printf("  --keep-system-libs                keep -L%s entries in libs output\n", SYSTEM_LIBDIR);
202 	printf("  --path                            show the exact filenames for any matching .pc files\n");
203 	printf("  --modversion                      print the specified module's version to stdout\n");
204 	printf("  --internal-cflags                 do not filter 'internal' cflags from output\n");
205 	printf("  --license                         print the specified module's license to stdout if known\n");
206 	printf("  --link-abi                        print the link ABIs (e.g. c, c++) the module must be linked against\n");
207 	printf("  --source                          print the specified module's source code location to stdout if known\n");
208 	printf("  --exists-cflags                   add -DHAVE_FOO fragments to cflags for each found module\n");
209 
210 	printf("\nfiltering output:\n\n");
211 #ifndef PKGCONF_LITE
212 	printf("  --msvc-syntax                     print translatable fragments in MSVC syntax\n");
213 #endif
214 	printf("  --fragment-filter=types           filter output fragments to the specified types\n");
215 	printf("  --env=prefix                      print output as shell-compatible environmental variables\n");
216 	printf("  --fragment-tree                   visualize printed CFLAGS/LIBS fragments as a tree\n");
217 	printf("  --newlines                        use newlines for whitespace between fragments\n");
218 
219 	printf("\nreport bugs to <%s>.\n", PACKAGE_BUGREPORT);
220 }
221 
222 int
223 main(int argc, char *argv[])
224 {
225 #ifdef _WIN32
226 	// When activeCodePage is set to UTF-8 in the application manifest (requires Windows 1903+),
227 	// GetACP() returns CP_UTF8 but the console code pages are not automatically updated to match.
228 	// Detect this condition via GetACP() == CP_UTF8 and align the console code pages accordingly.
229 	// Restoring on exit is safe: if ACP is already CP_UTF8, resetting to the saved values is a no-op.
230 	if (GetACP() == CP_UTF8)
231 	{
232 		original_console_cp = GetConsoleCP();
233 		original_console_out_cp = GetConsoleOutputCP();
234 		SetConsoleCP(CP_UTF8);
235 		SetConsoleOutputCP(CP_UTF8);
236 		atexit(restore_console_code_page);
237 	}
238 #endif
239 
240 	int ret;
241 	pkgconf_cli_state_t state = {
242 		.want_flags = 0,
243 	};
244 	pkgconf_list_t dir_list = PKGCONF_LIST_INITIALIZER;
245 	char *env_traverse_depth;
246 	char *logfile_arg = NULL;
247 	pkgconf_cross_personality_t *personality = NULL;
248 
249 	if (pkgconf_pledge("stdio rpath wpath cpath unveil", NULL) == -1)
250 	{
251 		pkgconf_output_file_fmt(stderr, "pkgconf: pledge failed: %s\n", strerror(errno));
252 		return EXIT_FAILURE;
253 	}
254 
255 #ifdef _WIN32
256 	/* When running regression tests in cygwin, and building native
257 	 * executable, tests fail unless native executable outputs unix
258 	 * line endings.  Come to think of it, this will probably help
259 	 * real people who use cygwin build environments but native pkgconf, too.
260 	 */
261 	_setmode(fileno(stdout), O_BINARY);
262 	_setmode(fileno(stderr), O_BINARY);
263 #endif
264 
265 	struct pkg_option options[] = {
266 		{ "version", no_argument, &state.want_flags, PKG_VERSION|PKG_PRINT_ERRORS, },
267 		{ "about", no_argument, &state.want_flags, PKG_ABOUT|PKG_PRINT_ERRORS, },
268 		{ "atleast-version", required_argument, NULL, 2, },
269 		{ "atleast-pkgconfig-version", required_argument, NULL, 3, },
270 		{ "libs", no_argument, &state.want_flags, PKG_LIBS|PKG_PRINT_ERRORS, },
271 		{ "cflags", no_argument, &state.want_flags, PKG_CFLAGS|PKG_PRINT_ERRORS, },
272 		{ "modversion", no_argument, &state.want_flags, PKG_MODVERSION|PKG_PRINT_ERRORS, },
273 		{ "variable", required_argument, NULL, 7, },
274 		{ "exists", no_argument, &state.want_flags, PKG_EXISTS, },
275 		{ "print-errors", no_argument, &state.want_flags, PKG_PRINT_ERRORS, },
276 		{ "short-errors", no_argument, &state.want_flags, PKG_SHORT_ERRORS, },
277 		{ "maximum-traverse-depth", required_argument, NULL, 11, },
278 		{ "static", no_argument, &state.want_flags, PKG_STATIC, },
279 		{ "shared", no_argument, &state.want_flags, PKG_SHARED, },
280 		{ "pure", no_argument, &state.want_flags, PKG_PURE, },
281 		{ "print-requires", no_argument, &state.want_flags, PKG_REQUIRES, },
282 		{ "print-variables", no_argument, &state.want_flags, PKG_VARIABLES|PKG_PRINT_ERRORS, },
283 #ifndef PKGCONF_LITE
284 		{ "digraph", no_argument, &state.want_flags, PKG_DIGRAPH, },
285 		{ "solution", no_argument, &state.want_flags, PKG_SOLUTION, },
286 #endif
287 		{ "help", no_argument, &state.want_flags, PKG_HELP, },
288 		{ "env-only", no_argument, &state.want_flags, PKG_ENV_ONLY, },
289 		{ "print-requires-private", no_argument, &state.want_flags, PKG_REQUIRES_PRIVATE, },
290 		{ "cflags-only-I", no_argument, &state.want_flags, PKG_CFLAGS_ONLY_I|PKG_PRINT_ERRORS, },
291 		{ "cflags-only-other", no_argument, &state.want_flags, PKG_CFLAGS_ONLY_OTHER|PKG_PRINT_ERRORS, },
292 		{ "libs-only-L", no_argument, &state.want_flags, PKG_LIBS_ONLY_LDPATH|PKG_PRINT_ERRORS, },
293 		{ "libs-only-l", no_argument, &state.want_flags, PKG_LIBS_ONLY_LIBNAME|PKG_PRINT_ERRORS, },
294 		{ "libs-only-other", no_argument, &state.want_flags, PKG_LIBS_ONLY_OTHER|PKG_PRINT_ERRORS, },
295 		{ "uninstalled", no_argument, &state.want_flags, PKG_UNINSTALLED, },
296 		{ "no-uninstalled", no_argument, &state.want_flags, PKG_NO_UNINSTALLED, },
297 		{ "keep-system-cflags", no_argument, &state.want_flags, PKG_KEEP_SYSTEM_CFLAGS, },
298 		{ "keep-system-libs", no_argument, &state.want_flags, PKG_KEEP_SYSTEM_LIBS, },
299 		{ "define-variable", required_argument, NULL, 27, },
300 		{ "exact-version", required_argument, NULL, 28, },
301 		{ "max-version", required_argument, NULL, 29, },
302 		{ "ignore-conflicts", no_argument, &state.want_flags, PKG_IGNORE_CONFLICTS, },
303 		{ "errors-to-stdout", no_argument, &state.want_flags, PKG_ERRORS_ON_STDOUT, },
304 		{ "silence-errors", no_argument, &state.want_flags, PKG_SILENCE_ERRORS, },
305 		{ "list-all", no_argument, &state.want_flags, PKG_LIST|PKG_PRINT_ERRORS, },
306 		{ "list-package-names", no_argument, &state.want_flags, PKG_LIST_PACKAGE_NAMES|PKG_PRINT_ERRORS, },
307 #ifndef PKGCONF_LITE
308 		{ "simulate", no_argument, &state.want_flags, PKG_SIMULATE, },
309 #endif
310 		{ "no-cache", no_argument, &state.want_flags, PKG_NO_CACHE, },
311 		{ "print-provides", no_argument, &state.want_flags, PKG_PROVIDES, },
312 		{ "no-provides", no_argument, &state.want_flags, PKG_NO_PROVIDES, },
313 		{ "debug", no_argument, &state.want_flags, PKG_DEBUG|PKG_PRINT_ERRORS, },
314 		{ "validate", no_argument, &state.want_flags, PKG_VALIDATE|PKG_PRINT_ERRORS|PKG_ERRORS_ON_STDOUT },
315 		{ "log-file", required_argument, NULL, 40 },
316 		{ "path", no_argument, &state.want_flags, PKG_PATH },
317 		{ "with-path", required_argument, NULL, 42 },
318 		{ "prefix-variable", required_argument, NULL, 43 },
319 		{ "define-prefix", no_argument, &state.want_flags, PKG_DEFINE_PREFIX },
320 		{ "dont-define-prefix", no_argument, &state.want_flags, PKG_DONT_DEFINE_PREFIX },
321 		{ "dont-relocate-paths", no_argument, &state.want_flags, PKG_DONT_RELOCATE_PATHS },
322 		{ "env", required_argument, NULL, 48 },
323 #ifndef PKGCONF_LITE
324 		{ "msvc-syntax", no_argument, &state.want_flags, PKG_MSVC_SYNTAX },
325 #endif
326 		{ "fragment-filter", required_argument, NULL, 50 },
327 		{ "internal-cflags", no_argument, &state.want_flags, PKG_INTERNAL_CFLAGS },
328 #ifndef PKGCONF_LITE
329 		{ "dump-personality", no_argument, &state.want_flags, PKG_DUMP_PERSONALITY },
330 		{ "personality", required_argument, NULL, 53 },
331 #endif
332 		{ "license", no_argument, &state.want_flags, PKG_DUMP_LICENSE },
333 		{ "license-file", no_argument, &state.want_flags, PKG_DUMP_LICENSE_FILE },
334 		{ "link-abi", no_argument, &state.want_flags, PKG_LINK_ABI },
335 		{ "verbose", no_argument, NULL, 55 },
336 		{ "exists-cflags", no_argument, &state.want_flags, PKG_EXISTS_CFLAGS },
337 		{ "fragment-tree", no_argument, &state.want_flags, PKG_FRAGMENT_TREE },
338 		{ "source", no_argument, &state.want_flags, PKG_DUMP_SOURCE },
339 		{ "newlines", no_argument, &state.want_flags, PKG_NEWLINES },
340 #ifndef PKGCONF_LITE
341 		{ "print-digraph-query-nodes", no_argument, &state.want_flags, PKG_PRINT_DIGRAPH_QUERY_NODES },
342 #endif
343 		{ NULL, 0, NULL, 0 }
344 	};
345 
346 #ifndef PKGCONF_LITE
347 	if (getenv("PKG_CONFIG_EARLY_TRACE"))
348 	{
349 		state.error_msgout = stderr;
350 		pkgconf_client_set_trace_handler(&state.pkg_client, error_handler, NULL);
351 	}
352 #endif
353 
354 	while ((ret = pkg_getopt_long_only(argc, argv, "", options, NULL)) != -1)
355 	{
356 		switch (ret)
357 		{
358 		case 2:
359 			state.required_module_version = pkg_optarg;
360 			break;
361 		case 3:
362 			state.required_pkgconfig_version = pkg_optarg;
363 			break;
364 		case 7:
365 			state.want_variable = pkg_optarg;
366 			break;
367 		case 11:
368 			state.maximum_traverse_depth = atoi(pkg_optarg);
369 			break;
370 		case 27:
371 			pkgconf_tuple_define_global(&state.pkg_client, pkg_optarg);
372 			break;
373 		case 28:
374 			state.required_exact_module_version = pkg_optarg;
375 			break;
376 		case 29:
377 			state.required_max_module_version = pkg_optarg;
378 			break;
379 		case 40:
380 			logfile_arg = pkg_optarg;
381 			break;
382 		case 42:
383 			pkgconf_path_prepend(pkg_optarg, &dir_list, true);
384 			break;
385 		case 43:
386 			pkgconf_client_set_prefix_varname(&state.pkg_client, pkg_optarg);
387 			break;
388 		case 48:
389 			state.want_env_prefix = pkg_optarg;
390 			break;
391 		case 50:
392 			state.want_fragment_filter = pkg_optarg;
393 			break;
394 #ifndef PKGCONF_LITE
395 		case 53:
396 			personality = pkgconf_cross_personality_find(pkg_optarg);
397 			break;
398 #endif
399 		case 55:
400 			state.verbosity++;
401 			break;
402 		case '?':
403 		case ':':
404 			ret = EXIT_FAILURE;
405 			goto out;
406 		default:
407 			break;
408 		}
409 	}
410 
411 	if (personality == NULL) {
412 #ifndef PKGCONF_LITE
413 		personality = deduce_personality(argv);
414 #else
415 		personality = pkgconf_cross_personality_default();
416 #endif
417 	}
418 
419 	/* now, bring up the client.  settings are preserved since the client is prealloced */
420 	pkgconf_client_init(&state.pkg_client, error_handler, &state, personality, &state, environ_lookup_handler);
421 	pkgconf_client_set_unveil_handler(&state.pkg_client, unveil_handler);
422 
423 #ifndef PKGCONF_LITE
424 	if (getenv("PKG_CONFIG_MSVC_SYNTAX") != NULL)
425 		state.want_flags |= PKG_MSVC_SYNTAX;
426 #endif
427 
428 	if ((env_traverse_depth = getenv("PKG_CONFIG_MAXIMUM_TRAVERSE_DEPTH")) != NULL)
429 		state.maximum_traverse_depth = atoi(env_traverse_depth);
430 
431 	if ((state.want_flags & PKG_PRINT_ERRORS) != PKG_PRINT_ERRORS)
432 		state.want_flags |= (PKG_SILENCE_ERRORS);
433 
434 	if ((state.want_flags & PKG_SILENCE_ERRORS) == PKG_SILENCE_ERRORS && !getenv("PKG_CONFIG_DEBUG_SPEW"))
435 		state.want_flags |= (PKG_SILENCE_ERRORS);
436 	else
437 		state.want_flags &= ~(PKG_SILENCE_ERRORS);
438 
439 	if (getenv("PKG_CONFIG_DONT_RELOCATE_PATHS"))
440 		state.want_flags |= (PKG_DONT_RELOCATE_PATHS);
441 
442 	if ((state.want_flags & PKG_VALIDATE) == PKG_VALIDATE || (state.want_flags & PKG_DEBUG) == PKG_DEBUG)
443 		pkgconf_client_set_warn_handler(&state.pkg_client, error_handler, NULL);
444 
445 #ifndef PKGCONF_LITE
446 	if ((state.want_flags & PKG_DEBUG) == PKG_DEBUG)
447 		pkgconf_client_set_trace_handler(&state.pkg_client, error_handler, NULL);
448 #endif
449 
450 	pkgconf_path_prepend_list(&state.pkg_client.dir_list, &dir_list);
451 	pkgconf_path_free(&dir_list);
452 
453 	if ((state.want_flags & PKG_ABOUT) == PKG_ABOUT)
454 	{
455 		about();
456 
457 		ret = EXIT_SUCCESS;
458 		goto out;
459 	}
460 
461 	if ((state.want_flags & PKG_VERSION) == PKG_VERSION)
462 	{
463 		version();
464 
465 		ret = EXIT_SUCCESS;
466 		goto out;
467 	}
468 
469 	if ((state.want_flags & PKG_HELP) == PKG_HELP)
470 	{
471 		usage();
472 
473 		ret = EXIT_SUCCESS;
474 		goto out;
475 	}
476 
477 	if (logfile_arg == NULL)
478 		logfile_arg = getenv("PKG_CONFIG_LOG");
479 
480 	if (logfile_arg != NULL)
481 	{
482 		if (pkgconf_unveil(logfile_arg, "rwc") == -1)
483 		{
484 			pkgconf_output_file_fmt(stderr, "pkgconf: unveil failed: %s\n", strerror(errno));
485 			return EXIT_FAILURE;
486 		}
487 
488 		state.logfile_out = fopen(logfile_arg, "a");
489 		pkgconf_audit_set_log(&state.pkg_client, state.logfile_out);
490 	}
491 
492 	if (getenv("PKG_CONFIG_ALLOW_SYSTEM_CFLAGS") != NULL)
493 		state.want_flags |= PKG_KEEP_SYSTEM_CFLAGS;
494 
495 	if (getenv("PKG_CONFIG_ALLOW_SYSTEM_LIBS") != NULL)
496 		state.want_flags |= PKG_KEEP_SYSTEM_LIBS;
497 
498 	return pkgconf_cli_run(&state, argc, argv, pkg_optind);
499 
500 out:
501 	pkgconf_cli_state_reset(&state);
502 	return ret;
503 }
504