PC(5)
๐ NAME ๐
file.pc โ pkg-config file format. bestie, this is PC(5), and we are literally about to get into it ๐
๐ DESCRIPTION ๐
okay so .pc files are a whole vibe for storing various information about libraries and packages on a given system. The info stored by .pc files includes compiler and linker flags necessary to use a given library, plus any other relevant metadata.
These .pc files are processed by a utility called pkg-config, and pkgconf is one implementation of it. periodt.
๐ FILE SYNTAX ๐
The .pc file follows a format inspired by RFC822. Comments are prefixed by a pound sign, hash sign or octothorpe (#), and variable assignment is similar to POSIX shell. Properties are defined using RFC822-style stanzas. no cap. it's giving classic config energy.
๐ค VARIABLES ๐ค
Variable definitions start with an alphanumeric string, followed by an equal sign, and then the value the variable should contain.
Variable references are always written as ${variable}. It is possible to escape literal ${ as $${. iykyk ๐
๐งฉ PROPERTIES ๐งฉ
Properties are set using RFC822-style stanzas which consist of a keyword, followed by a colon (:) and then the value the property should be set to. Variable substitution is always performed regardless of property type.
There are three types of property: and yes, we're covering all of them.
โจ Literal โจ
The property will be set to the text of the value. simple, iconic.
๐งฉ Dependency List ๐งฉ
The property will be set to a list of dependencies parsed from the text. Dependency lists are defined by this ABNF syntax:
package-list = *WSP *( package-spec *( package-sep ) )
package-sep = WSP / ","
package-spec = package-key [ ver-op package-version ]
ver-op = "<" / "<=" / "=" / "!=" / ">=" / ">"
๐งต Fragment List ๐งต
The property will be set to a list of fragments parsed from the text. The input text must be in a format that is suitable for passing to a POSIX shell without any shell expansions after variable substitution has been done.
The text is tokenised using POSIX shell word-splitting rules: unquoted whitespace separates fragments, single and double quotes group text, and a backslash escapes the following character. A quote that is not itself escaped is consumed as a quoting delimiter and does not appear in the resulting fragment. To include a shell metacharacter โ such as a quote, whitespace, a bracket, a brace, or a glob character โ literally in a fragment, escape it with a backslash so that it survives tokenisation.
For example, to make the toolchain receive the argument
-sFUNCS=["fnA","fnB"]
escape the double quotes so they are not consumed as quoting:
Libs: -sFUNCS=[\"fnA\",\"fnB\"]
On output, such metacharacters are re-escaped so that the original fragment is recovered when the consumer tokenises the output using the same shell word-splitting rules; see the note on output escaping in pkgconf(1).
๐ PROPERTY KEYWORDS ๐
Nameโ the displayed name of the package. (mandatory; literal)Versionโ the version of the package. (mandatory; literal)Descriptionโ a description of the package. (mandatory; literal)URLโ a URL to a webpage for the package. This is used to recommend where newer versions of the package can be acquired. (mandatory; literal)Cflagsโ required compiler flags. These flags are always used, regardless of whether static compilation is requested. (optional; fragment list)Cflags.privateโ required compiler flags for static compilation only. (optional; fragment list; pkgconf extension; introduced in pkgconf 0.9.3)Cflags.sharedโ required compiler flags for shared compilation only. (optional; fragment list; pkgconf extension; introduced in pkgconf 3.0.0)Copyrightโ a copyright attestation statement. (optional; literal; pkgconf extension; introduced in pkgconf 1.9.3)Libsโ required linking flags for this package. Libraries this package depends on for linking against it, which are not described as dependencies should be specified here. (optional; fragment list)Libs.privateโ required linking flags for this package that are only required when linking statically. Libraries this package depends on for linking against it statically, which are not described as dependencies should be specified here. (optional; fragment list)Libs.sharedโ required linking flags for this package that are only required for dynamic linking. Libraries this package depends on for linking against it dynamically, which are not described as dependencies should be specified here. (optional; fragment list; pkgconf extension; introduced in pkgconf 3.0.0)Link.ABIโ a comma-separated list of tags describing the application binary interfaces a consumer must link this package against, such asc++orfortran. Tags are case-insensitive and are normalized to lowercase. This allows a build system to select the appropriate linker driver and runtime when a package, or one of its dependencies, is implemented in a language whose ABI differs from C. The tag set is unioned across the dependency closure in the same manner asLibs: a package's own tags and those of its publicRequiresalways apply, whileRequires.privatetags apply only when private dependencies are linked. Unlike a runtime library load, ABI compatibility of the exposed interface applies equally to shared and static linking. A package with noLink.ABIproperty is treated asc. (optional; pkgconf extension; introduced in pkgconf 3.0.0)Licenseโ the asserted SPDX license tag that should be applied to the given package. One should try to determine the correct SPDX license tag for package from the SPDX License list. If a standard license name isn't available, use theLicenseRef-tag. For complex licensing details, utilize SPDX expression notation. Itโs possible to assign multiple license tags in pc-file, which are then merged together with an'AND'when rendering output. (optional; literal; pkgconf extension; introduced in pkgconf 1.9.0)License.fileโ an absolute filesystem path to the installed file containing the full license text for this package. The path must refer to the license file as installed on the system, so that it corresponds to the exact version and configuration described by this.pcfile; pkgconf variable references such as${prefix}or${datadir}, which expand to absolute paths, may be used. Relative paths are not supported. This must not be a URL: useSourceto reference an upstream location. (optional; literal; pkgconf extension; introduced in pkgconf 3.0.0)Maintainerโ the preferred contact for the maintainer. This should be in the format of a name followed by an e-mail address or website. (optional; literal; pkgconf extension; introduced in pkgconf 1.9.3)Sourceโ the asserted SPDXdownloadLocationtag that should be applied to the given package.Sourceshould be URI contain tarball with exact version or Repository that contains tag with version same as mentioned in version tag. It can be also be URI with hash that is exact release point of the source. (optional; literal; pkgconf extension; introduced in pkgconf 3.0.0)Requiresโ required dependencies that must be met for the package to be usable. All dependencies must be satisfied or the pkg-config implementation must not use the package. (optional; dependency list)Requires.internalโ required dependencies that must be met for the package to be usable for static linking. The main differences versesRequires.privateare thatCFLAGSwill not be included and the solver will not consider the dependency when solving forCFLAGSonly. (optional; dependency list; pkgconf extension; introduced in pkgconf 1.5.0)Requires.privateโ required dependencies that must be met for the package to be usable for header inclusion and static linking. All dependencies must be satisfied or the pkg-config implementation must not use the package for header inclusion and static linking. (optional; dependency list)Requires.sharedโ required dependencies that are only traversed when not in static mode. This allows a package to express dependencies that are only relevant when it is used as a shared library. (optional; dependency list; pkgconf extension; introduced in pkgconf 3.0.0)Conflictsโ dependencies that must not be met for the package to be usable. If any package in the proposed dependency solution match any dependency in theConflictslist, the package being considered is not usable. (optional; dependency list)Providesโ dependencies that may be provided by an alternate package. If a package cannot be found, the entire package collection is scanned for providers which can match the requested dependency. (optional; dependency list; pkgconf extension; introduced in pkgconf 1.1.0)
๐ EXTENSIONS ๐
Features that have been marked as a pkgconf extension are only guaranteed to work with the pkgconf implementation of pkg-config. Other implementations may or may not support the extensions. vibe check.
Accordingly, it is suggested that .pc files which absolutely depend on these extensions declare a requirement on the pkgconf virtual.
In addition it should be noted that the pkgconf virtual is versioned, and thus files which absolutely depend on these extensions can declare a requirement on the specific pkgconf version which introduced the extension.
As an example:
Requires: pkgconf >= 3.0.0
Libs.shared: ...
โจ EXAMPLES โจ
Okay bestie, this is the part where it all clicks into place. ๐ Here's a real, actual .pc file so you can see the vibe in the wild โ variables, substitutions, comments, the whole thing:
# This is a comment
prefix=/home/kaniini/pkg # this defines a variable
exec_prefix=${prefix} # defining another variable with a substitution
libdir=${exec_prefix}/lib
includedir=${prefix}/include
Name: libfoo # human-readable name
Description: an example library called libfoo # human-readable description
Copyright: Copyright (c) 2022 pkgconf project authors
License: Apache-2.0
Maintainer: the pkgconf project <http://www.pkgconf.org>
Version: 1.0
URL: http://www.pkgconf.org
Requires: libbar > 2.0.0
Conflicts: libbaz <= 3.0.0
Libs: -L${libdir} -lfoo
Libs.private: -lm
Cflags: -I${includedir}/libfoo
Look at her. ๐ธ She's got:
- a
# This is a commentup top, because even config files need a little intro ๐ prefix=/home/kaniini/pkg, which defines a variableexec_prefix=${prefix}, which is defining another variable with a substitution โ see how${prefix}slides right in? iconic โจlibdir=${exec_prefix}/libandincludedir=${prefix}/includedoing the exact same substitution move, building paths out of other paths ๐ง- the fields you already know and love:
Name:,Description:,Copyright:,License:,Maintainer:,Version:,URL:,Requires:,Conflicts:,Libs:,Libs.private:,Cflags: - and yes, the inline comments (
# human-readable name,# human-readable description) are right there in the file, annotated for your viewing pleasure ๐ญ
Not a single line wasted. She ate and left no crumbs. ๐
๐ SEE ALSO ๐
Go read those too, bestie โ the lore goes deep. ๐ฆ
And that's the whole page, fr fr. ๐ซถ This one came from the Debian folks, dated June 23, 2026, and it lives in section PC(5) of your friendly neighbourhood manual. Go forth and write the most slay .pc file the world has ever seen. ๐โจ๐
๐ฆ where this page comes from
- arch rolling: pkgconf 3.0.10-1 ยท ISC
- arch rolling: pkgconf 3.0.7-1
- Copyright (c) 2017 pkgconf authors (see AUTHORS)
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms