PKGCONF(1)

PKGCONF(1) โ€” General Commands Manual ๐Ÿ’–

okay bestie, welcome to the PKGCONF(1) page, straight out of the General Commands Manual โœจ this is the main character of build-dependency config and we're gonna go through it all, no skips, no skimming ๐Ÿ’…


๐ŸŒธ NAME ๐ŸŒธ

pkgconf โ€” a system for configuring build dependency information ๐Ÿฆ‹


โœจ SYNOPSIS โœจ

pkgconf [options] module ...

๐Ÿ’– DESCRIPTION ๐Ÿ’–

so basically, pkgconf goes and fetches configuration info that's related to the module arguments you hand it, pulling from the pc(5) files installed on the system, and then it prints out whichever parts of that retrieved info match the options you asked for ๐ŸŒˆ the most common use is printing the compiler and linker flags you need to build software that uses the libraries given by the module arguments. that's the whole point, that's the assignment ๐Ÿ‘‘

when it's printing compiler and linker flags, pkgconf escapes shell metacharacters โ€” think quotes, whitespace, brackets, braces and glob characters โ€” in each fragment by putting a backslash in front of them ๐Ÿ’ซ the output is meant to be re-tokenised by the consumer using POSIX shell word-splitting rules, the way build systems generally do; under those rules the protective backslashes get stripped and the original values come back ๐Ÿ™Œ

ngl this next bit matters: if you paste the output directly into an unquoted command substitution, like cc $(pkgconf --libs foo), that performs word-splitting and pathname expansion but it does not remove the backslashes ๐Ÿ˜ญ so a value containing characters like that can reach the toolchain with the escaping still sitting there. not the vibe you want.

the pc(5) files get searched for along a path that's constructed from the --with-path option, the PKG_CONFIG_PATH and PKG_CONFIG_LIBDIR environment variables, and some compiled-in default directories ๐Ÿงš and the module arguments correspond to the file names, but without the .pc filename extension ๐ŸŽ€

several of the options cause an immediate exit ๐Ÿšช if you give more than one of those, only the option with the highest priority actually takes effect, and the lower-priority ones get silently ignored. here they are, ordered by descending priority:

  1. No-module options: --dump-personality, --about, --version, --help, --atleast-pkgconfig-version, --list-all, and --list-package-names: these options cause all arguments to be ignored.
  2. Argument-only options: --atleast-version, --exact-version, and --max-version: these options only inspect modules that were explicitly specified on the command line and do not look at dependencies.
  3. Limited-output options: --validate, --license, --license-file, --link-abi, --source, --uninstalled, and --env: these options do perform dependency resolution, but they exit right after printing the information requested by the highest-priority option, ignoring any other output options that may have been specified.

and then there's another little crew of options that need at least one module argument, produce output, don't cause an early exit, can be combined with each other, but override and disable every --cflags and --libs option ๐Ÿ”ฅ

  1. Single-module output options: --path, --print-variables: if any of these is specified, only the first module argument is used, all the other arguments are silently ignored, and no dependency resolution is attempted.
  2. Depth-one output options: --print-provides, --modversion, --print-requires, --print-requires-private, and --variable: if any of these is specified, only modules explicitly specified on the command line are inspected and no dependency resolution is attempted.
  3. General output options: --simulate, --digraph, --solution, --fragment-tree, --newlines: these options do not limit dependency resolution.

the most important output options, --cflags and --libs, can be combined with each other, but they get overridden and ignored if any of the options listed above are specified ๐Ÿ™ˆ

the complete list of options is as follows:

--about

prints the version number, the Copyright notice, and the license of the pkgconf program to standard output, then exits ๐Ÿ’– most other options and all command line arguments are ignored.

--atleast-pkgconfig-version=version

exits with an error if the requested version number is greater than the version number of the pkgconf program, or exits with success otherwise โœจ most other options and all command line arguments are ignored.

--atleast-version=version

checks the module arguments in the order they were given ๐Ÿซถ it exits with an error as soon as a module doesn't exist, and exits with success as soon as the version number of a module is greater than or equal to the requested version number. if the version number of every single module is less than the requested version number, it exits with an error ๐Ÿ˜ญ

--cflags, --cflags-only-I, --cflags-only-other

print all the compiler flags required to compile against the module; or only the include path (-I) flags; or only the compiler flags that are not include path flags โ€” respectively ๐ŸŽ€ these options imply --print-errors.

--debug

prints some non-fatal warning messages to standard error output that would otherwise be silently ignored ๐Ÿ‘€ this option also implies --print-errors. and if pkgconf was compiled without defining the preprocessor macro PKGCONF_LITE, this option also prints many debugging messages to standard error output ๐Ÿ’€

--define-prefix

attempts to determine the prefix variable to use for CFLAGS and LIBS entry relocations ๐ŸŒธ this is mainly useful for platforms where framework SDKs are relocatable, such as Windows.

--define-variable=varname=value

define varname as value ๐Ÿ’ซ variables are used in query output, and some modules' results may change based on the presence of a variable definition.

--digraph

dumps the dependency resolver's solution as a graphviz โ€˜dotโ€™ file ๐Ÿฆ‹ this can be used with graphviz to visualize module interdependencies. heads up: this option is only available if the preprocessor macro PKGCONF_LITE was not defined during compilation.

--dont-define-prefix

disables the โ€˜define-prefixโ€™ feature ๐Ÿ™…

--dont-relocate-paths

disables the path relocation feature ๐Ÿšซ

--dump-personality

prints some default settings to standard output and exits โ€” in particular the default module search path that's used when PKG_CONFIG_LIBDIR is not defined, the default list of include paths that get filtered out when PKG_CONFIG_SYSTEM_INCLUDE_PATH is not defined, and the default list of library paths that get filtered out when PKG_CONFIG_SYSTEM_LIBRARY_PATH is not defined ๐ŸŒˆ most other options and all command line arguments are ignored. this option is only available if the preprocessor macro PKGCONF_LITE was not defined during compilation.

--env=varname

prints the requested values as variable declarations in a format similar to what the env(1) command uses ๐Ÿ‘‘

--env-only

initializes the module search path from --with-path and PKG_CONFIG_PATH only, ignoring PKG_CONFIG_LIBDIR and the compiled-in default directories ๐Ÿ’…

--errors-to-stdout

prints all error, warning, and debugging messages to standard output instead of to standard error output ๐Ÿ“ข

--exact-version=version

checks the module arguments in the order they were given ๐ŸŒŸ it exits with an error as soon as a module doesn't exist, and exits with success as soon as the version number of a module is exactly the requested version number. if the version number of every single module differs from the requested version number, it exits with an error ๐Ÿ˜ค

--exists

exits with a non-zero exit status if the dependency resolver can't find all of the requested modules ๐Ÿ” this option is active by default and cannot be disabled. however โ€” plot twist โ€” various other options cause pkgconf to exit and report success or failure before all the arguments have been inspected ๐Ÿ‘€

--fragment-filter=types

filters the fragment lists for the specified types โœ‚๏ธ

--help

prints a usage summary on standard output and exits ๐Ÿ’– most other options and all command line arguments are ignored.

--ignore-conflicts

ignores โ€˜Conflictsโ€™ rules in modules ๐Ÿ™ˆ this option is implied by the options that merely report metadata about the requested modules rather than combining them into a build, namely --license, --license-file, --modversion, --path, --print-provides, --print-requires, --print-requires-private, --print-variables, --source, and --variable.

--keep-system-cflags, --keep-system-libs

keep the CFLAGS or linker flag fragments that would otherwise get filtered out for being included by default in the compiler ๐ŸŽ€

--libs, --libs-only-L, --libs-only-l, --libs-only-other

print all the linker flags required to link against the module; or only the library path (-L) flags; or only the library (-l) flags; or only the linker flags that are neither library path nor library flags โ€” respectively ๐Ÿ”ฅ these options imply --print-errors.

prints the set of link ABI tags (for example c or c++) that the module must be linked against, derived from the Link.ABI properties found across its dependency closure โœจ the tags from a package's own Link.ABI property and those of its public Requires always apply, while Requires.private tags apply only when linking statically (--static). a module with no link ABI requirements prints c. see pc(5) for details of the Link.ABI property.

--list-all

walks the module search path in the order of descending priority ๐Ÿšถโ€โ™€๏ธ for each pc(5) file found, it prints one line to standard output containing the basename of the file without the extension, the Name property, a dash (โ€˜-โ€™), and the Description property ๐ŸŒธ this option implies --print-errors. all command line arguments are ignored.

--list-package-names

performs the same search as --list-all, but only prints the basename of each pc(5) file without the extension โ€” not the module name and the description ๐Ÿฆ‹ this option implies --print-errors. all command line arguments are ignored.

  • --log-file=file โ€” okay so bestie, this one sets the name of the output file where pkgconf logs info about the modules it picked, both the ones you asked for as arguments and the ones it pulled in as dependencies. For each selected module it prints one line, containing the basename of the pc(5) file without the extension, optionally an operator and version number describing the desired range of versions, and then either the actual version number in square brackets or the string "NOT-FOUND". ๐ŸŒธ No --log-file? Then it takes the output file name from the PKG_CONFIG_LOG environment variable instead. No env var either? Then this whole logging thing is justโ€ฆ off. disabled. not happening. ๐Ÿ’ค
  • --max-version=version โ€” checks the module arguments in the order you gave them, bestie. Exits with error the second a module doesn't exist, and exits with success the second a module's version number is less than or equal to the requested version number. And if every single module's version is greater than the requested version? Exit with error. That's the vibe. ๐Ÿ˜Œ
  • --maximum-traverse-depth=depth โ€” puts a cap on how deep the dependency graph is allowed to go. Default depth is 256. Set depth to -1 for unlimited traversal (go off, no limits ๐Ÿ‘‘). Like, a depth of 2 restricts the resolver from acting on child dependencies of modules added to the resolver's solution. Heads up though: this option gets overridden by the PKG_CONFIG_MAXIMUM_TRAVERSE_DEPTH environment variable and by the options --modversion, --path, --print-provides, --print-requires, --print-requires-private, --print-variables, and --variable. So yeah, those are the main characters here and this flag is lowkey just backup dancer energy. ๐Ÿ’…
  • --modversion โ€” for each module you specify, print the version number to standard output. ๐Ÿ“ข And if --verbose is also on, the name of the respective module and a colon gets printed before each version number. This option implies --print-errors and --maximum-traverse-depth=1, and it overrides and disables all --cflags and --libs flags. Not me absolutely bulldozing those other flags though ๐Ÿ˜ญ
  • --msvc-syntax โ€” use MSVC syntax for --cflags, --env, and --libs output. Fair warning: this option is only available if the preprocessor macro PKGCONF_LITE was not defined during compilation. ๐Ÿฆ‹
  • --newlines โ€” use newlines to separate individual CFLAGS or linker flag fragments instead of spaces. Tiny change, huge difference, obsessed. โœจ
  • --no-cache โ€” skip caching packages when they're loaded into the internal resolver. This may result in an alternate dependency graph being computed. it's giving "trust nothing, recompute everything" ๐Ÿ’€
  • --no-provides โ€” ignore โ€˜Providesโ€™ rules in modules when resolving dependencies. ๐Ÿšซ
  • --no-uninstalled โ€” forbids the dependency resolver from considering 'uninstalled' modules as part of a solution. so uninstalled modules aren't even invited to the party ๐Ÿ™ˆ
  • --path โ€” for the first module given on the command line, let the dependency resolver find the pc(5) file describing that module, print the absolute pathname of that file to standard output, and exit immediately โ€” ignoring most other options and all other arguments. it literally grabs the first one and dips ๐Ÿƒโ™€๏ธ
  • --prefix-variable=variable โ€” sets the โ€˜prefixโ€™ variable used by the โ€˜define-prefixโ€™ feature. ๐ŸŽ€
  • --print-errors โ€” print some messages about fatal errors to standard error output that would otherwise be omitted. This option is implied by many other options, but not by all. It can be overridden with --silence-errors. ๐Ÿ“ฃ
  • --print-provides โ€” for each specified module, print one line to standard output containing the Name property, an equal sign (=), and the Version property. And if the module contains one or more Provides properties, it prints additional lines in dependency list format, one name per line, each name optionally followed by an operator and a version. This option implies --maximum-traverse-depth=1 and overrides and disables all --cflags and --libs flags. ๐Ÿ’–
  • --print-requires, --print-requires-private โ€” for each specified module, print the Requires or Requires.private properties, respectively, in dependency list format to standard output. Both of these options imply --maximum-traverse-depth=1 and override and disable all --cflags and --libs flags. duo behavior, split the info, slay โœŒ๏ธ
  • --print-variables โ€” for the first module given on the command line, print the names of all seen variables to standard output, one per line. Any subsequent arguments are silently ignored (we're not even acknowledging them bestie ๐Ÿ’…). This option implies --print-errors and --maximum-traverse-depth=1 and overrides and disables all --cflags and --libs flags.
  • --pure โ€” treats the computed dependency graph as if it were pure. This is mainly intended for use with the --static flag, and it has no effect if --shared is also specified. so pure + shared = pure does nothing, noted ๐Ÿ“
  • --shared โ€” compute a simple dependency graph that is only suitable for shared linking. This option overrides --static. simple, clean, shared-girl era ๐Ÿซถ
  • --short-errors โ€” when printing error messages about modules that aren't found or conflict with each other, avoid printing additional, verbose instructions explaining potential methods for solving the problem. we're keeping it brief, no paragraphs of advice ๐Ÿ˜Œ
  • --silence-errors โ€” do not print any error, warning, or debugging messages at all. ๐Ÿ”‡ Overrides all of --debug, --errors-to-stdout, and --print-errors. But heads up: this option is itself overridden and disabled if the PKG_CONFIG_DEBUG_SPEW environment variable is set. so debug spew beats silence, that's the hierarchy. ๐Ÿ’€
  • --simulate โ€” simulates resolving a dependency graph based on the requested modules on the command line. Dumps a series of trees denoting pkgconf's resolver state. ๐ŸŒˆ This option is only available if the preprocessor macro PKGCONF_LITE was not defined during compilation.
  • --solution โ€” print the names of the modules requested with module arguments and their dependencies to standard output. ๐Ÿงš This option is only available if the preprocessor macro PKGCONF_LITE was not defined during compilation.
  • --static โ€” compute a deeper dependency graph and use compiler/linker flags intended for static linking. This option is overridden by --shared. ๐Ÿ‘‘
  • --uninstalled โ€” exit with a non-zero result if the dependency resolver uses an โ€˜uninstalledโ€™ module as part of its solution. like, if an uninstalled module sneaks in, we're calling it out ๐Ÿšจ
  • --validate package ... โ€” validate specific โ€˜.pcโ€™ files for correctness. โœ… This option implies --print-errors and --errors-to-stdout.
  • --variable=varname โ€” for each specified module, print the value of the variable with the name varname to standard output, in command-line order. This option implies --maximum-traverse-depth=1 and overrides and disables all --cflags and --libs flags. ๐Ÿ“‹
  • --verbose โ€” this option only has an effect if --modversion is also specified. In that case it prints the name of the respective module and a colon before each version number. no --modversion, no effect, that's the rule ๐ŸŽ€
  • --version โ€” print the version number of the pkgconf program to standard output and exit. Most other options and all command line arguments are ignored. it's giving "I only have one job and I do it flawlessly" โญ
  • --with-path=path โ€” prepend the directory path to the module search path, giving it priority over all other directories โ€” including those from PKG_CONFIG_PATH and PKG_CONFIG_LIBDIR. front of the line privileges, periodt. ๐Ÿ‘‘

๐ŸŒธ ENVIRONMENT ๐ŸŒธ

okay bestie, this is the part where the shell hands pkgconf little secret notes before it even wakes up ๐Ÿ’Œ every one of these is optional, but they all change the vibe of what happens next. read carefully, no skimming ๐Ÿ™ˆ

  • CPATH โ€” the first supplementary colon-separated list of include paths, and they get filtered out exactly the same way as PKG_CONFIG_SYSTEM_INCLUDE_PATH does it โœจ
  • CPLUS_INCLUDE_PATH โ€” the third supplementary colon-separated list of include paths, filtered out the same way as PKG_CONFIG_SYSTEM_INCLUDE_PATH ๐ŸŽ€ (yes the numbering is chaotic, we don't make the rules)
  • C_INCLUDE_PATH โ€” the second supplementary colon-separated list of include paths, filtered out just like PKG_CONFIG_SYSTEM_INCLUDE_PATH ๐Ÿฆ‹
  • DESTDIR โ€” if you set this to the same value as PKG_CONFIG_SYSROOT_DIR, then pkgconf follows PKG_CONFIG_FDO_SYSROOT_RULES for variable lookups, but it disables automatic sysroot injection into -I and -L fragments, so it doesn't end up prefixing your paths with DESTDIR twice ๐Ÿ™…โ€โ™€๏ธ and if PKG_CONFIG_SYSROOT_DIR isn't set at all, or is set to a different value, then DESTDIR is simply ignored. periodt.
  • LIBRARY_PATH โ€” supplementary colon-separated list of library paths, filtered out in the same way as PKG_CONFIG_SYSTEM_LIBRARY_PATH ๐Ÿ’…
  • OBJC_INCLUDE_PATH โ€” the fourth supplementary colon-separated list of include paths, filtered out the same way as PKG_CONFIG_SYSTEM_INCLUDE_PATH ๐ŸŒˆ
  • PKG_CONFIG_ALLOW_SYSTEM_CFLAGS โ€” if it's set, it does the exact same thing as the --keep-system-cflags option ๐Ÿ‘‘
  • PKG_CONFIG_ALLOW_SYSTEM_LIBS โ€” if it's set, it does the exact same thing as the --keep-system-libs option ๐Ÿ‘‘
  • PKG_CONFIG_DEBUG_SPEW โ€” if it's set, it overrides and disables the --silence-errors option. so much for being quiet ๐Ÿ˜ญ
  • PKG_CONFIG_DISABLE_UNINSTALLED โ€” if it's set, you get the same behaviour as the --no-uninstalled flag ๐Ÿšซ
  • PKG_CONFIG_DONT_DEFINE_PREFIX โ€” if it's set, this variable has the same effect as the --dont-define-prefix option โœจ
  • PKG_CONFIG_DONT_RELOCATE_PATHS โ€” if it's set, it disables the path relocation feature ๐Ÿ›‘
  • PKG_CONFIG_FDO_SYSROOT_RULES โ€” if it's set, pkgconf follows the sysroot prefixing rules that freedesktop.org pkg-config uses ๐Ÿงš
  • PKG_CONFIG_IGNORE_CONFLICTS โ€” if it's set, Conflicts rules in modules get ignored. same effect as the --ignore-conflicts option ๐Ÿ’–
  • PKG_CONFIG_LIBDIR โ€” a colon-separated list of low-priority directories where pc(5) files get looked up. the module search path is built by appending this list onto PKG_CONFIG_PATH, which has higher priority. if PKG_CONFIG_LIBDIR isn't defined, the default list compiled into the pkgconf program from the PKG_DEFAULT_PATH preprocessor macro gets appended instead. and if PKG_CONFIG_LIBDIR is defined but empty, then nothing gets appended at all ๐Ÿซถ
  • PKG_CONFIG_LOG โ€” if it's set, info about the selected modules gets logged to the file named in this variable. for more deets, peep the --log-file command line option, which overrides this variable ๐Ÿ“
  • PKG_CONFIG_MAXIMUM_TRAVERSE_DEPTH โ€” puts a limit on the allowed depth in the dependency graph. set it to -1 to allow unlimited traversal. this variable overrides the --maximum-traverse-depth option, but it gets overridden by the other options mentioned there ๐Ÿ”
  • PKG_CONFIG_MSVC_SYNTAX โ€” if it's set, use MSVC syntax for --cflags, --env, and --libs output. same effect as the --msvc-syntax option. heads up though: if the preprocessor macro PKGCONF_LITE was defined during compilation, this variable is ignored ๐Ÿ’€
  • PKG_CONFIG_PATH โ€” a colon-separated list of high-priority directories where pc(5) files get looked up. the module search path is built by prepending the directory specified with --with-path, if there is one, and โ€” unless --env-only is specified โ€” by appending either PKG_CONFIG_LIBDIR or the compiled-in default directories, at lower priority ๐ŸŒŸ
  • PKG_CONFIG_PRELOADED_FILES โ€” colon-separated list of pc(5) files that get loaded before any other pkg-config files. these packages get the highest priority over any other pc(5) files that would otherwise provide a given package ๐Ÿ‘‘
  • PKG_CONFIG_PURE_DEPGRAPH โ€” if it's set, you get the same behaviour as the --pure flag โœจ
  • PKG_CONFIG_RELOCATE_PATHS โ€” if it's set, this variable has the same effect as the --define-prefix option ๐ŸŽ€
  • PKG_CONFIG_SYSROOT_DIR โ€” if it's set, this variable defines a โ€˜sysrootโ€™ directory, which gets prepended to every path variable beginning with the prefix variable in a given pc(5) file. super useful for cross compilation ๐Ÿ› ๏ธ the value of this environment variable also gets copied into the global variable pc_sysrootdir ๐Ÿฆ‹
  • PKG_CONFIG_SYSTEM_INCLUDE_PATH โ€” colon-separated list of include paths that get filtered out and not printed by the --cflags and --cflags-only-I options, because they count as system include paths. if it's not defined, the default list compiled into the pkgconf program from the SYSTEM_INCLUDEDIR preprocessor macro is used instead. and any directories listed in the environment variables CPATH, C_INCLUDE_PATH, CPLUS_INCLUDE_PATH, and OBJC_INCLUDE_PATH are filtered out too ๐Ÿงน
  • PKG_CONFIG_SYSTEM_LIBRARY_PATH โ€” colon-separated list of library paths that get filtered out and not printed by the --libs and --libs-only-L options, because they count as system library paths. if it's not defined, the default list compiled into the pkgconf program from the SYSTEM_LIBDIR preprocessor macro is used instead ๐Ÿงน
  • PKG_CONFIG_TOP_BUILD_DIR โ€” this is the value of the pc_top_builddir global variable. if this environment variable isn't defined, the string "$(top_builddir)" is used as the value of pc_top_builddir ๐Ÿ’œ

๐Ÿšฆ EXIT STATUS ๐Ÿšฆ

the pkgconf utility exits 0 on success, and >0 if an error occurs. so like, zero = slay, anything above zero = something went sideways ๐Ÿ˜ญ


โœจ EXAMPLES โœจ

displaying the CFLAGS of a package, bestie:

$ pkgconf --cflags foo
-fPIC -I/usr/include/foo

see? it just hands you the flags. iconic behaviour honestly ๐Ÿ”ฅ


๐Ÿ‘€ SEE ALSO ๐Ÿ‘€

pc(5), pkg.m4(7) โ€” go read those next, iykyk ๐Ÿ“š


and that's the whole page, bestie ๐Ÿ’– this one came from Debian, dated September 8, 2026, and it's PKGCONF(1) โ€” go forth and let your build system thrive, no cap ๐Ÿซถ๐ŸŒธ

๐Ÿ“ฆ where this page comes from
  • arch rolling: pkgconf 3.0.10-1 ยท ISC
  • ๐Ÿ’– girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms