diff --git a/Makefile.am b/Makefile.am index 95998a6..b9edccc 100644 --- a/Makefile.am +++ b/Makefile.am @@ -11,6 +11,8 @@ SUBDIRS = $(GLIB_SUBDIR) check m4dir = $(datadir)/aclocal m4_DATA = pkg.m4 +dist_doc_DATA = pkg-config-guide.html + man_MANS = pkg-config.1 EXTRA_DIST = $(m4_DATA) $(man_MANS) README.win32 diff --git a/pkg-config-guide.html b/pkg-config-guide.html new file mode 100644 index 0000000..0f6c72f --- /dev/null +++ b/pkg-config-guide.html @@ -0,0 +1,420 @@ + + + + + +
+ + + +This document aims to give an overview to using the pkg-config + tool from the perspective of both a user and a developer. It reviews the + concepts behind pkg-config, how to write pkg-config files + to support your project, and how to use pkg-config to integrate + with 3rd party projects.
+ +More information on pkg-config can be found at the + website and in the + pkg-config(1) manual page.
+ +This document assumes usage of pkg-config on a Unix-like + operating system such as Linux. Some of the details may be different on + other platforms.
+ +Modern computer systems use many layered components to provide + applications to the user. One of the difficulties in assembling these parts + is properly integrating them. pkg-config collects metadata about + the installed libraries on the system and easily provides it to the user. +
+ +Without a metadata system such as pkg-config, it can be very + difficult to locate and obtain details about the services provided on a + given computer. For a developer, installing pkg-config files with + your package greatly eases adoption of your API.
+ +The primary use of pkg-config is to provide the necessary + details for compiling and linking a program to a library. This metadata is + stored in pkg-config files. These files have the suffix + .pc and reside in specific locations known to the + pkg-config tool. This will be described in more detail later.
+ +The file format contains predefined metadata keywords and freeform + variables. An example may be illustrative:
+ +
prefix=/usr/local
+exec_prefix=${prefix}
+includedir=${prefix}/include
+libdir=${exec_prefix}/lib
+
+Name: foo
+Description: The foo library
+Version: 1.0.0
+Cflags: -I${includedir}/foo
+Libs: -L${libdir} -lfoo
+
+ The keyword definitions such as Name: begin with a keyword + followed by a colon and the value. The variables such as prefix= + are a string and value separated by an equals sign. The keywords are defined + and exported by pkg-config. The variables are not necessary, but + can be used by the keyword definitions for flexibility or to store data not + covered by pkg-config.
+ +Here is a short description of the keyword fields. A more in depth + description of these fields and how to use them effectively will be given in + the Writing pkg-config files section.
+ +When creating pkg-config files for a package, it is first + necessary to decide how they will be distributed. Each file is best used to + describe a single library, so each package should have at least as many + pkg-config files as they do installed libraries.
+ +The package name is determined through the filename of the + pkg-config metadata file. This is the portion of the filename prior + to the .pc suffix. A common choice is to match the library name to + the .pc name. For instance, a package installing libfoo.so + would have a corresponding libfoo.pc file containing the + pkg-config metadata. This choice is not necessary; the .pc + file should simply be a unique identifier for your library. Following the + above example, foo.pc or foolib.pc would probably work + just as well.
+ +The Name, Description and URL fields are + purely informational and should be easy to fill in. The Version + field is a bit trickier to ensure that it is usable by consumers of the + data. pkg-config uses the algorithm from + RPM for version comparisons. This works best + with a dotted decimal number such as 1.2.3 since letters can cause + unexpected results. The number should be monotonically increasing and be + as specific as possible in describing the library. Usually it's sufficient + to use the package's version number here since it's easy for consumers to + track.
+ +Before describing the more useful fields, it will be helpful to + demonstrate variable definitions. The most common usage is to define the + installation paths so that they don't clutter the metadata fields. Since + the variables are expanded recursively, this is very helpful when used in + conjunction with autoconf derived paths.
+ +prefix=/usr/local
+includedir=${prefix}/include
+
+Cflags: -I${includedir}/foo
+
+ The most important pkg-config metadata fields are + Requires, Requires.private, Cflags, Libs + and Libs.private. They will define the metadata used by external + projects to compile and link with the library.
+ +Requires and Requires.private define other modules + needed by the library. It is usually preferred to use the private variant of + Requires to avoid exposing unnecessary libraries to the program + that is linking with your library. If the program will not be using the + symbols of the required library, it should not be linking directly to that + library. See the discussion of + overlinking for a more + thorough explanation.
+ +Since pkg-config always exposes the link flags of the + Requires libraries, these modules will become direct dependencies + of the program. On the other hand, libraries from Requires.private + will only be included when static linking. For this reason, it is usually + only appropriate to add modules from the same package in Requires. +
+ +The Libs field contains the link flags necessary to use that + library. In addition, Libs and Libs.private contain link + flags for other libraries not supported by pkg-config. Similar to + the Requires field, it is preferred to add link flags for external + libraries to the Libs.private field so programs do not acquire an + additional direct dependency.
+ +Finally, the Cflags contains the compiler flags for using the + library. Unlike the Libs field, there is not a private variant of + Cflags. This is because the data types and macro definitions are + needed regardless of the linking scenario.
+ +Assuming that there are .pc files installed on the system, the + pkg-config tool is used to extract the metadata for usage. A short + description of the options can be seen by executing + pkg-config --help. A more in depth discussion can be found in the + pkg-config(1) manual page. This section will provide a brief + explanation of common usages. + +
Consider a system with two modules, foo and bar. + Their .pc files might look like this:
+ +foo.pc:
+prefix=/usr
+exec_prefix=${prefix}
+includedir=${prefix}/include
+libdir=${exec_prefix}/lib
+
+Name: foo
+Description: The foo library
+Version: 1.0.0
+Cflags: -I${includedir}/foo
+Libs: -L${libdir} -lfoo
+
+bar.pc:
+prefix=/usr
+exec_prefix=${prefix}
+includedir=${prefix}/include
+libdir=${exec_prefix}/lib
+
+Name: bar
+Description: The bar library
+Version: 2.1.2
+Requires.private: foo >= 0.7
+Cflags: -I${includedir}
+Libs: -L${libdir} -lbar
+
+ The version of the modules can be obtained with the --modversion + option.
+ +$ pkg-config --modversion foo +1.0.0 +$ pkg-config --modversion bar +2.1.2+ +
To print the link flags needed for each module, use the --libs + option.
+ +$ pkg-config --libs foo +-lfoo +$ pkg-config --libs bar +-lbar+ +
Notice that pkg-config has suppressed part of the Libs + field for both modules. This is because it treats the -L flag + specially and knows that the ${libdir} directory /usr/lib + is part of the system linker search path. This keeps pkg-config + from interfering with the linker operation.
+ +Also, although foo is required by bar, the link flags + for foo are not output. This is because foo is not + directly needed by an application that only wants to use the bar + library. For statically linking a bar application, we need both + sets of linker flags:
+ +$ pkg-config --libs --static bar +-lbar -lfoo+ +
pkg-config needs to output both sets of link flags in this case + to ensure that the statically linked application will find all the necessary + symbols. On the other hand, it will always output all the Cflags. +
+ +$ pkg-config --cflags bar +-I/usr/include/foo +$ pkg-config --cflags --static bar +-I/usr/include/foo+ +
Another useful option, --exists, can be used to test for a + module's availability.
+ +$ pkg-config --exists foo +$ echo $? +0+ +
One of the nicest features of pkg-config is providing version + checking. It can be used to determine if a sufficient version is available. +
+ +$ pkg-config --libs "bar >= 2.7" +Requested 'bar >= 2.7' but version of bar is 2.1.2+ +
Some commands will provide more verbose output when combined with the + --print-errors option.
+ +$ pkg-config --exists --print-errors xoxo +Package xoxo was not found in the pkg-config search path. +Perhaps you should add the directory containing `xoxo.pc' +to the PKG_CONFIG_PATH environment variable +No package 'xoxo' found+ +
The message above references the PKG_CONFIG_PATH environment + variable. This variable is used to augment pkg-config's search + path. On a typical Unix system, it will search in the directories + /usr/lib/pkgconfig and /usr/share/pkgconfig. This will + usually cover system installed modules. However, some local modules may be + installed in a different prefix such as /usr/local. In that case, + it's necessary to prepend the search path so that pkg-config can + locate the .pc files.
+ +$ pkg-config --modversion hello +Package hello was not found in the pkg-config search path. +Perhaps you should add the directory containing `hello.pc' +to the PKG_CONFIG_PATH environment variable +No package 'hello' found +$ export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig +$ pkg-config --modversion hello +1.0.0+ +
A few autoconf macros + are also provided to ease integration of pkg-config modules into + projects.
+ +The pkg-config output can easily be used on the compiler + command line. Assuming the x library has a x.pc + pkg-config file:
+ +cc `pkg-config --cflags --libs x` -o myapp myapp.c+ +
The integration can be more robust when used with + autoconf and + automake. By using the + supplied PKG_CHECK_MODULES macro, the metadata is easily accessed + in the build process.
+ +configure.ac: +PKG_CHECK_MODULES([X], [x]) + +Makefile.am: +myapp_CFLAGS = $(X_CFLAGS) +myapp_LDADD = $(X_LIBS)+ +
If the x module is found, the macro will fill and substitute + the X_CFLAGS and X_LIBS variables. If the module is not + found, an error will be produced. Optional 3rd and 4th arguments can be + supplied to PKG_CHECK_MODULES to control actions when the module + is found or not.
+ +If the x library has pkg-config support, add it to + the Requires.private field. If it does not, augment the + Cflags field with the necessary compiler flags for using the + libx headers. In either case, pkg-config will output + the compiler flags when --static is used or not.
+ +Again, add the module to Requires.private if it supports + pkg-config. In this case, the compiler flags will be emitted + unnecessarily, but it ensures that the linker flags will be present when + linking statically. If libx does not support pkg-config, + add the necessary linker flags to Libs.private.
+Copyright (C) 2010 Dan Nicholson.
+ This document is licensed under the
+ GNU General Public License, Version 2
+ or any later version.