Compare commits

...

741 Commits

Author SHA1 Message Date
Petr Písař 2d26db3a98 doc: Requires.private is used for header inclusion
ci/woodpecker/push/woodpecker Pipeline failed Details
Document that "pkgconf --cflags" inherits paths for including headers
from dependencies listed in Requires.private.

https://github.com/pkgconf/pkgconf/issues/300
https://github.com/pkgconf/pkgconf/issues/352
2024-04-25 23:50:21 -07:00
Pierce a8a492e2e4 Fix typo in README.md
ci/woodpecker/push/woodpecker Pipeline failed Details
2024-04-25 23:49:39 -07:00
Ismael Luceno c583d49a37 pkg.m4: Abort by default if no pkgconf
ci/woodpecker/push/woodpecker Pipeline failed Details
Provide a second optional argument to PKG_PROG_PKG_CONFIG with an action to
take if no pkgconf is found, and default to aborting.

Too many configure scripts in the wild don't handle an empty PKG_CONFIG,
resulting in weird error messages through the run, which often confuse
users.

Authors wishing to fallback to other methods can either return to the old
behavior by specifying [:] as an action, or use [PKG_CONFIG=false] and call
pkg-config macros normally, handling the fallback as any other failure.

Users can override PKG_CONFIG in the command line so this should imply no
regression.

Closes: https://github.com/pkgconf/pkgconf/issues/350
Ref: https://gitlab.freedesktop.org/pkg-config/pkg-config/-/issues/69
Signed-off-by: Ismael Luceno <ismael@iodev.co.uk>
2024-04-25 23:48:18 -07:00
Ariadne Conill 06120a8769 pkgconf 2.2.0 2024-03-27 18:39:44 +00:00
Ariadne Conill 7a8532f849 queue: remove no longer used root package reference when walking dependency graphs 2024-03-27 18:39:43 +00:00
Ariadne Conill a3d7ecb31b Use libpkgconf.so.5 due to ABI changes 2024-03-27 11:31:48 -07:00
Kai Pastor e2a8080cbf Reuse static solution for general solution 2024-03-27 11:15:04 -07:00
Kai Pastor 883b57df47 Cache packages from explicit file requests 2024-03-27 11:15:04 -07:00
Kai Pastor 194dde096b Update expected test results 2024-03-27 11:15:04 -07:00
Kai Pastor 78d53ea012 Revise serials, traversal, flattening
Remove the 'traverse_serial' fields which were added in 2.1.1.
Use the 'serial' field to track the current traversal.
Stop using 'identifier' to sort packages in the flattened solution.
Directly construct the flattened solution by a specific walk which
also preserves the relative order in Requires and Requires.private.
The topological sort is a single list, so don't fill requires_private.
Purely private dependencies are marked in dependency flags.
The ancestor flag is a pkg property, not a client property.
2024-03-27 11:15:04 -07:00
Kai Pastor 4090ba3e0d Clarify tracing messages 2024-03-27 11:15:04 -07:00
Kai Pastor 5eb79f6651 Add tests for lib order 2024-03-27 11:15:04 -07:00
Kai Pastor e7c9bdb317 Don't print 'required by <VIRTUAL-PACKAGE>' 2024-03-27 11:09:16 -07:00
Kai Pastor 4e01010d6f Mark user input in error message 2024-03-27 11:09:16 -07:00
Kai Pastor 6219af9a0a Color private-reachable nodes gray 2024-03-27 11:06:30 -07:00
Kai Pastor eaf1a2d804 Resolve user request for digraph 2024-03-27 11:06:30 -07:00
Kai Pastor d6753888b8 Update test expected results 2024-03-27 11:06:30 -07:00
Kai Pastor f95e8d4428 Print digraph for user request perspective 2024-03-27 11:06:30 -07:00
Kai Pastor db63c8ee0b Show edges for flattened order 2024-03-27 11:06:30 -07:00
Kai Pastor b6e04e2d47 pkgconf 2.1.1
ci/woodpecker/push/woodpecker Pipeline was successful Details
ci/woodpecker/tag/woodpecker Pipeline was successful Details
2024-02-04 03:26:15 -08:00
Ariadne Conill 2edf954f3a Update NEWS for pkgconf 2.1.1 2024-02-04 03:25:54 -08:00
Ariadne Conill d8924aced5 Update gitignore to catch all of the autoconf-generated files
ci/woodpecker/push/woodpecker Pipeline was successful Details
2024-02-04 03:16:14 -08:00
Ariadne Conill 80b5011e69 Use traverse_serial to short circuit graph evaluation for already visited nodes.
In our previous attempt to optimize this problem, we did not track the type of the
visit to the node, e.g. whether it came from evaluating Requires or Requires.private,
which resulted in some solutions being correctly incalculated due to greedy optimization
of the dependency graph.

We reintroduce this optimization by adding a second traversal serial as well as
re-introducing the PROPF_VISITED node property as well as a new PROPF_VISITED_PRIVATE
node property flag.  This allows a node to be revisted at maximum two times per
traversal level.

Co-authored-by: Yi Chou <yich@google.com>
2024-02-04 03:04:52 -08:00
Kai Pastor 4a3adf3457 Test digraph completeness for private-libs-duplication
ci/woodpecker/push/woodpecker Pipeline was successful Details
Complements 45073b7.
2024-02-04 02:37:14 -08:00
Kai Pastor 5825e2c6d6 Fix crash on two-word expressions
ci/woodpecker/push/woodpecker Pipeline was successful Details
2023-12-05 10:50:18 -07:00
Kai Pastor b2f8386c32 Fix --modversion output 2023-12-05 10:50:18 -07:00
Kai Pastor 125af82dbe Test --modversion with constraint 2023-12-05 10:50:18 -07:00
Sam James 08f4a9da15 NEWS: fix typo
ci/woodpecker/push/woodpecker Pipeline was successful Details
Signed-off-by: Sam James <sam@gentoo.org>
2023-11-29 12:03:11 -08:00
Stefan Weil a4ecd42bf3 Fix it's -> its
Signed-off-by: Stefan Weil <sw@weilnetz.de>
2023-11-29 12:02:44 -08:00
Ariadne Conill 61d39ad899 pkgconf 2.1.0.
ci/woodpecker/push/woodpecker Pipeline was successful Details
ci/woodpecker/tag/woodpecker Pipeline was successful Details
2023-11-22 18:46:19 +00:00
Ariadne Conill 5fb09af863 queue: ensure the initial solution is cleaned up when it is no longer needed
ci/woodpecker/push/woodpecker Pipeline was successful Details
2023-11-22 18:43:04 +00:00
Ariadne Conill d0038689fd build: add metapackage-3.pc to testsuite files
ci/woodpecker/push/woodpecker Pipeline was successful Details
2023-11-22 18:30:21 +00:00
Ariadne Conill 31512b210b add NEWS for pkgconf 2.1.0.
ci/woodpecker/push/woodpecker Pipeline was successful Details
2023-11-22 18:24:29 +00:00
Ariadne Conill 5f6c5320e5 cli: add simple --solution applet for dumping the solver solution
ci/woodpecker/push/woodpecker Pipeline was successful Details
2023-11-22 18:13:18 +00:00
Ariadne Conill f3540de30d queue: clarify the relationship between a flattened dep and its parent
Signed-off-by: Ariadne Conill <ariadne@dereferenced.org>
2023-11-22 18:13:07 +00:00
Kai Pastor be1ea7888b Separate input world from output world
ci/woodpecker/push/woodpecker Pipeline was successful Details
2023-11-22 10:11:21 -08:00
Kai Pastor 45073b7460 Circular deps: track ancestors, not serial 2023-11-22 10:09:22 -08:00
Victor Westerhuis 948297b5b8 Search XDG Base Directories for personality files
Try $XDG_DATA_HOME/pkgconfig/personality.d and $XDG_DATA_DIRS/pkgconfig/personality.d.
2023-11-22 10:07:41 -08:00
Sam James d454f62c73 libpkgconf: fix -Walloc-size
GCC 14 introduces a new -Walloc-size included in -Wextra which gives:
```
libpkgconf/personality.c:260:11: warning: allocation of insufficient size '1' for type 'pkgconf_cross_personality_t' {aka 'struct pkgconf_cross_personality_'} with size '48' [-Walloc-size]
libpkgconf/queue.c:46:33: warning: allocation of insufficient size '1' for type 'pkgconf_queue_t' {aka'struct pkgconf_queue_'} with size '16' [-Walloc-size]
libpkgconf/client.c:164:33: warning: allocation of insufficient size '1' for type 'pkgconf_client_t' {aka 'struct pkgconf_client_'} with size '120' [-Walloc-size]
libpkgconf/path.c:105:14: warning: allocation of insufficient size '1' for type 'pkgconf_path_t' {aka 'struct pkgconf_path_'} with size '24' [-Walloc-size]
libpkgconf/path.c:237:22: warning: allocation of insufficient size '1' for type 'pkgconf_path_t' {aka 'struct pkgconf_path_'} with size '24' [-Walloc-size]
libpkgconf/tuple.c:239:34: warning: allocation of insufficient size '1' for type 'pkgconf_tuple_t' {aka 'struct pkgconf_tuple_'} with size '24' [-Walloc-size]
libpkgconf/dependency.c:133:13: warning: allocation of insufficient size '1' for type 'pkgconf_dependency_t' {aka 'struct pkgconf_dependency_'} with size '44' [-Walloc-size]
libpkgconf/dependency.c:472:17: warning: allocation of insufficient size '1' for type 'pkgconf_dependency_t' {aka 'struct pkgconf_dependency_'} with size '44' [-Walloc-size]
libpkgconf/fragment.c:146:22: warning: allocation of insufficient size '1' for type 'pkgconf_fragment_t' {aka 'struct pkgconf_fragment_'} with size '24' [-Walloc-size]
libpkgconf/fragment.c:195:22: warning: allocation of insufficient size '1' for type 'pkgconf_fragment_t' {aka 'struct pkgconf_fragment_'} with size '24' [-Walloc-size]
libpkgconf/fragment.c:356:14: warning: allocation of insufficient size '1' for type 'pkgconf_fragment_t' {aka 'struct pkgconf_fragment_'} with size '24' [-Walloc-size]
libpkgconf/pkg.c:422:13: warning: allocation of insufficient size '1' for type 'pkgconf_pkg_t' {aka 'struct pkgconf_pkg_'} with size '188' [-Walloc-size]
libpkgconf/client.c:164:33: warning: allocation of insufficient size '1' for type 'pkgconf_client_t' {aka 'struct pkgconf_client_'} with size '224' [-Walloc-size]
libpkgconf/personality.c:260:11: warning: allocation of insufficient size '1' for type 'pkgconf_cross_personality_t' {aka 'struct pkgconf_cross_personality_'} with size '96' [-Walloc-size]
libpkgconf/dependency.c:133:13: warning: allocation of insufficient size '1' for type 'pkgconf_dependency_t' {aka 'struct pkgconf_dependency_'} with size '80' [-Walloc-size]
libpkgconf/dependency.c:472:17: warning: allocation of insufficient size '1' for type 'pkgconf_dependency_t' {aka 'struct pkgconf_dependency_'} with size '80' [-Walloc-size]
libpkgconf/path.c:105:14: warning: allocation of insufficient size '1' for type 'pkgconf_path_t' {aka 'struct pkgconf_path_'} with size '48' [-Walloc-size]
libpkgconf/path.c:237:22: warning: allocation of insufficient size '1' for type 'pkgconf_path_t' {aka 'struct pkgconf_path_'} with size '48' [-Walloc-size]
libpkgconf/queue.c:46:33: warning: allocation of insufficient size '1' for type 'pkgconf_queue_t' {aka 'struct pkgconf_queue_'} with size '32' [-Walloc-size]
libpkgconf/tuple.c:239:34: warning: allocation of insufficient size '1' for type 'pkgconf_tuple_t' {aka 'struct pkgconf_tuple_'} with size '48' [-Walloc-size]
libpkgconf/fragment.c:146:22: warning: allocation of insufficient size '1' for type 'pkgconf_fragment_t' {aka 'struct pkgconf_fragment_'} with size '48' [-Walloc-size]
libpkgconf/fragment.c:195:22: warning: allocation of insufficient size '1' for type 'pkgconf_fragment_t' {aka 'struct pkgconf_fragment_'} with size '48' [-Walloc-size]
libpkgconf/fragment.c:356:14: warning: allocation of insufficient size '1' for type 'pkgconf_fragment_t' {aka 'struct pkgconf_fragment_'} with size '48' [-Walloc-size]
libpkgconf/pkg.c:422:13: warning: allocation of insufficient size '1' for type 'pkgconf_pkg_t' {aka 'struct pkgconf_pkg_'} with size '360' [-Walloc-size]
```

The calloc prototype is:
```
void *calloc(size_t nmemb, size_t size);
    ```

So, just swap the number of members and size arguments to match the prototype, as
we're initialising 1 struct of size `sizeof(struct ...)`. GCC then sees we're not
doing anything wrong.

The only exception there is for argv which I fixed while at it.

Signed-off-by: Sam James <sam@gentoo.org>
2023-11-22 10:06:14 -08:00
Ariadne Conill 752a9825dc queue: demote requires to requires.private when processing requires.private parents
ci/woodpecker/push/woodpecker Pipeline failed Details
Signed-off-by: Ariadne Conill <ariadne@dereferenced.org>
2023-10-09 07:22:59 +00:00
Ariadne Conill 86c43b4e3d cli: --digraph: use directed relationships as part of the visualization
ci/woodpecker/push/woodpecker Pipeline failed Details
Signed-off-by: Ariadne Conill <ariadne@dereferenced.org>
2023-10-09 07:10:47 +00:00
Ariadne Conill 4db8031402 cli: --digraph: properly visualize requires.private edges
ci/woodpecker/push/woodpecker Pipeline failed Details
Signed-off-by: Ariadne Conill <ariadne@dereferenced.org>
2023-10-09 07:06:29 +00:00
Kai Pastor eb087a6c84 Test simple metapackage
ci/woodpecker/push/woodpecker Pipeline failed Details
2023-10-09 06:48:59 +00:00
Colin Gillespie dd6a8e3fc7 cli: trim trailing whitespace from package arguments
ci/woodpecker/push/woodpecker Pipeline was successful Details
Signed-off-by: Colin Gillespie <colin@cgillespie.xyz>
2023-10-09 06:36:47 +00:00
Ariadne Conill 97d907ba93 cli: remove strncmp() from modversion comparison
Signed-off-by: Ariadne Conill <ariadne@dereferenced.org>
2023-10-09 06:35:26 +00:00
Peter Kokot a4033ab9c6 Update AX_CHECK_COMPILE_FLAG to serial 6
ci/woodpecker/push/woodpecker Pipeline failed Details
curl --output m4/ax_check_compile_flag.m4 \
https://raw.githubusercontent.com/autoconf-archive/autoconf-archive/master/m4/ax_check_compile_flag.m4
2023-10-08 22:50:31 +00:00
L. E. Segovia a7c29fec18 meson: Add with-system options
ci/woodpecker/push/woodpecker Pipeline failed Details
Fixes #283
2023-10-08 22:49:22 +00:00
Xi Ruoyao 962a5e96b7 cli: fix --modversion not showing version with versioned query
ci/woodpecker/push/woodpecker Pipeline failed Details
Fixes #317.

Signed-off-by: Xi Ruoyao <xry111@xry111.site>
2023-10-08 22:47:51 +00:00
Colin Gillespie 5aeb469b81 libpkgconf: fix memory leak
ci/woodpecker/push/woodpecker Pipeline was successful Details
Signed-off-by: Colin Gillespie <colin@cgillespie.xyz>
2023-10-08 22:46:53 +00:00
Ariadne Conill 652aff9790 path: add pkgconf_path_prepend API for --with-path
ci/woodpecker/push/woodpecker Pipeline was successful Details
Otherwise, PKG_CONFIG_PATH and PKG_CONFIG_LIBDIR elements would be processed backwards.

Fixes: 384ade5 (path: prepend paths rather than append paths when processing --with-path arguments)
Closes: #250
Signed-off-by: Ariadne Conill <ariadne@dereferenced.org>
2023-10-08 22:27:56 +00:00
Ariadne Conill a6fb59a0ed pkgconf 2.0.3.
ci/woodpecker/push/woodpecker Pipeline was successful Details
ci/woodpecker/tag/woodpecker Pipeline was successful Details
Signed-off-by: Ariadne Conill <ariadne@dereferenced.org>
2023-09-03 04:18:48 +00:00
Ariadne Conill 3f07015d3a add new test files to build system
Signed-off-by: Ariadne Conill <ariadne@dereferenced.org>
2023-09-03 04:18:48 +00:00
Ariadne Conill ee702658cd use PRIu64 format specifiers for some uint64 identifiers in trace logging
ci/woodpecker/push/woodpecker Pipeline was successful Details
Signed-off-by: Ariadne Conill <ariadne@dereferenced.org>
2023-09-02 21:05:03 -07:00
Colin Gillespie 66994f1533 cli: fix --modversion not showing version in various cases
ci/woodpecker/push/woodpecker Pipeline was successful Details
There are numerous edge cases where version is wrong or missing when
matching the dependency queue to resolved packages. This adds the
dependency name as it appears in the dependency queue to each package as
it is resolved, allowing for a simple and correct comparison when
printing.

Signed-off-by: Colin Gillespie <colin@cgillespie.xyz>
2023-09-02 20:57:46 -07:00
Colin Gillespie 9cddd22bbc tests: add regression tests for --modversion
Signed-off-by: Colin Gillespie <colin@cgillespie.xyz>
2023-09-02 20:57:46 -07:00
Ariadne Conill eaa4bb44a0 pkgconf 2.0.2.
ci/woodpecker/push/woodpecker Pipeline was successful Details
ci/woodpecker/tag/woodpecker Pipeline was successful Details
2023-08-17 11:56:08 -07:00
Ariadne Conill a265f8a42b libpkgconf: pkg: fix long-standing bug where -uninstalled pkg-config files would have the wrong identifier
ci/woodpecker/push/woodpecker Pipeline was successful Details
2023-08-17 11:53:07 -07:00
Ariadne Conill f0f28fa690 tests: add regression test for --modversion with uninstalled pkg-config files 2023-08-17 11:50:00 -07:00
Ariadne Conill 6a84d70439 pkgconf 2.0.1.
ci/woodpecker/push/woodpecker Pipeline was successful Details
ci/woodpecker/tag/woodpecker Pipeline was successful Details
Signed-off-by: Ariadne Conill <ariadne@dereferenced.org>
2023-08-11 14:23:08 -07:00
Ariadne Conill f49029c681 cli: ensure --modversion is output is printed in dependency queue order
ci/woodpecker/push/woodpecker Pipeline was successful Details
Previously, --modversion operated on the calculated solution and printed versions in
order of the calculated dependency graph.  Change this to use the dependency queue
instead, looking up nodes in the dependency graph as needed, to ensure that the
--modversion output behaves as intended.

Signed-off-by: Ariadne Conill <ariadne@dereferenced.org>
2023-08-11 14:19:26 -07:00
Ariadne Conill 4fb0988a29 libpkgconf: queue: make the pkgconf_queue_t type public
Signed-off-by: Ariadne Conill <ariadne@dereferenced.org>
2023-08-11 14:16:41 -07:00
Ariadne Conill 5ef2ab8c7c cli: add --verbose parameter
ci/woodpecker/push/woodpecker Pipeline was successful Details
Signed-off-by: Ariadne Conill <ariadne@dereferenced.org>
2023-08-11 14:09:01 -07:00
Ariadne Conill 95086643fa cli: remove package count restriction from --modversion
ci/woodpecker/push/woodpecker Pipeline was successful Details
Signed-off-by: Ariadne Conill <ariadne@dereferenced.org>
2023-08-11 13:48:02 -07:00
Ariadne Conill fe69ccc6b9 Revert "main: explicitly error with --modversion and more than 1 package being queried"
This reverts commit a97b75ab2c.
2023-08-11 13:41:20 -07:00
Ariadne Conill de51b03cc1 pkgconf 2.0.0.
ci/woodpecker/tag/woodpecker Pipeline was successful Details
ci/woodpecker/push/woodpecker Pipeline was successful Details
2023-08-04 08:45:16 +00:00
Ariadne Conill f305901052 tests: regress: remove obsolete modversion test 2023-08-04 08:44:57 +00:00
Ariadne Conill a97b75ab2c main: explicitly error with --modversion and more than 1 package being queried 2023-08-04 08:38:48 +00:00
Ariadne Conill 384ade5f31 path: prepend paths rather than append paths when processing --with-path arguments 2023-08-04 08:24:32 +00:00
Ariadne Conill a4eb097b39 queue: process packages in the resolution queue in the correct order 2023-08-04 08:23:00 +00:00
Ariadne Conill 5d0e2f5092 Track packages using a lifetime unique identifier
Use that identifier to cancel graph edges rather than the number of hits,
which biases the earliest edge rather than the latest.
2023-08-04 08:19:42 +00:00
Ariadne Conill 437c2a3218 update release tarball location because dynadot is a shitty registrar
ci/woodpecker/push/woodpecker Pipeline was successful Details
2023-07-02 11:34:50 -07:00
Ariadne Conill 094dc38468 pkgconf 1.9.5.
ci/woodpecker/push/woodpecker Pipeline was successful Details
ci/woodpecker/tag/woodpecker Pipeline was successful Details
Signed-off-by: Ariadne Conill <ariadne@dereferenced.org>
2023-05-02 12:10:54 -07:00
Ariadne Conill 35b1a62314 update libpkgconf version to 10905
Signed-off-by: Ariadne Conill <ariadne@dereferenced.org>
2023-05-02 12:09:55 -07:00
Ariadne Conill 83f412a1fd update NEWS for 1.9.5.
Signed-off-by: Ariadne Conill <ariadne@dereferenced.org>
2023-05-02 12:09:19 -07:00
Ariadne Conill 7bfc2289fd tests: add regression test for maximum package count off-by-one
ci/woodpecker/push/woodpecker Pipeline was successful Details
Signed-off-by: Ariadne Conill <ariadne@dereferenced.org>
2023-05-02 11:58:56 -07:00
Ariadne Conill 1e179963d4 Enforce maximum package count correctly for --modversion
Signed-off-by: Ariadne Conill <ariadne@dereferenced.org>
2023-05-02 11:58:39 -07:00
Harmen Stoppels f7bebba664 fix meson.build
Co-authored-by: Ariadne Conill <ariadne@dereferenced.org>
2023-05-02 11:52:10 -07:00
Harmen Stoppels 434cb2935e use includes 2023-05-02 11:49:34 -07:00
Harmen Stoppels 40638f2472 use AC_CHECK_DECLS to avoid implicit function definition
AC_CHECK_FUNCS is not safe, since implicit function definitions is just
a warning. On 64-bit glibc systems where reallocarray is not defined or
hidden behind macros that are not set, it gets implicitly defined to
return an integer, which is a big problem given that it should return a
pointer, and leads to immediate segfaults.
2023-05-02 11:49:34 -07:00
h30032433 b08733f45d Fix the issue where tests/meson.build was deleted. 2023-05-02 11:48:38 -07:00
huyubiao 6d1f160e89 argvsplit: fix some quoting rules 2023-05-02 11:45:42 -07:00
Taylor R Campbell 212c85863a Avoid undefined behaviour with the ctype(3) functions.
ci/woodpecker/push/woodpecker Pipeline was successful Details
fix https://github.com/pkgconf/pkgconf/issues/291

As defined in the C standard:

        In all cases the argument is an int, the value of which shall
        be representable as an unsigned char or shall equal the value
        of the macro EOF.  If the argument has any other value, the
        behavior is undefined.

This is because they're designed to work with the int values returned
by getc or fgetc; they need extra work to handle a char value.

If EOF is -1 (as it almost always is), with 8-bit bytes, the allowed
inputs to the ctype(3) functions are:

        {-1, 0, 1, 2, 3, ..., 255}.

However, on platforms where char is signed, such as x86 with the
usual ABI, code like

        char *ptr = ...;
        ... isspace(*ptr) ...

may pass in values in the range:

        {-128, -127, -126, ..., -2, -1, 0, 1, ..., 127}.

This has two problems:

1. Inputs in the set {-128, -127, -126, ..., -2} are forbidden.

2. The non-EOF byte 0xff is conflated with the value EOF = -1, so
   even though the input is not forbidden, it may give the wrong
   answer.

Casting char to unsigned int first before passing the result to
ctype(3) doesn't help: inputs like -128 are unchanged by this cast,
because (on a two's-complement machine with 32-bit int and unsigned
int), converting the signed char with integer value -128 to unsigned
int gives integer value 2^32 - 128 = 0xffffff80, which is out of
range, and which is converted in int back to -128, which is also out
of range.

It is necessary to cast char inputs to unsigned char first; you can
then cast to unsigned int if you like but there's no need because the
functions will always convert the argument to int by definition.  So
the above fragment needs to be:

        char *ptr = ...;
        ... isspace((unsigned char)*ptr) ...

This patch changes unsigned int casts to unsigned char casts, and
adds unsigned char casts where they are missing.
2023-05-02 11:43:56 -07:00
Andrej Shadura 78f3abc935 doc: Regenerate the documentation for libpkgconf
ci/woodpecker/push/woodpecker Pipeline was successful Details
Signed-off-by: Andrej Shadura <andrew.shadura@collabora.co.uk>
2023-01-22 10:58:01 +00:00
Andrej Shadura 9ab5ea2e83 doc: personality: Add a documentation header
Signed-off-by: Andrej Shadura <andrew.shadura@collabora.co.uk>
2023-01-22 10:58:01 +00:00
Andrej Shadura cfda825f80 doc: extract: Use "==" instead of "is" with literals
This fixes:
    SyntaxWarning: "is" with a literal. Did you mean "=="?

Signed-off-by: Andrej Shadura <andrew.shadura@collabora.co.uk>
2023-01-22 10:58:01 +00:00
Ariadne Conill 873e51aaae pkgconf 1.9.4.
ci/woodpecker/push/woodpecker Pipeline was successful Details
ci/woodpecker/tag/woodpecker Pipeline was successful Details
2023-01-22 04:56:44 +00:00
Ariadne Conill f7305434eb libpkgconf: bump API version to 10904 2023-01-22 04:56:06 +00:00
Ariadne Conill 93edd215b4 update NEWS for 1.9.4
ci/woodpecker/push/woodpecker Pipeline was successful Details
2023-01-22 04:52:25 +00:00
Ariadne Conill 49ab0b2ab7 tests: fixup! 2023-01-21 21:43:23 +00:00
Ariadne Conill 98b33b48cd cli: use flattened solution for almost all user-facing queries 2023-01-21 21:43:08 +00:00
Ariadne Conill d9e507cc6e pkg: do not do serial checks for flattened solutions, as they are already flattened 2023-01-21 21:31:38 +00:00
Ariadne Conill 90b65c866b main: use flattened solution for cflags/libs only 2023-01-21 21:31:16 +00:00
Ariadne Conill 1ce000f397 Revert "pkg.m4: PKG_CHECK_MODULES provides modversion"
ci/woodpecker/push/woodpecker Pipeline was successful Details
This reverts commit 8d9d3de6eb.
2023-01-21 20:59:22 +00:00
Ariadne Conill 99bc93fbe5 use SIZE_FMT_SPECIFIER everywhere
ci/woodpecker/push/woodpecker Pipeline was successful Details
2023-01-21 20:45:29 +00:00
Ariadne Conill e2a12fd4c2 main: reset solver when solving for library groups
ci/woodpecker/push/woodpecker Pipeline was successful Details
2023-01-21 20:39:53 +00:00
Ariadne Conill 8f12d36b76 tests: fixup trailing whitespace in expected results
ci/woodpecker/push/woodpecker Pipeline was successful Details
2023-01-21 20:22:03 +00:00
Ariadne Conill b106de0c7a cli: add whitespace between cflags and libs fragments 2023-01-21 20:21:26 +00:00
Ariadne Conill 648a2249fc fragment: render: only include trailing space if there is another fragment 2023-01-21 20:17:33 +00:00
Ariadne Conill dd741e722f README: fix tests option to reflect meson changes
ci/woodpecker/push/woodpecker Pipeline was successful Details
2023-01-21 20:12:02 +00:00
Timo Röhling 506ebab7d6 Ignore whitespace indentation
ci/woodpecker/push/woodpecker Pipeline was successful Details
Fixes #265
2023-01-21 20:09:52 +00:00
Ariadne Conill be0d811942 argvsplit: fix some quoting rules to match POSIX
ci/woodpecker/push/woodpecker Pipeline was successful Details
2023-01-21 19:51:24 +00:00
Ariadne Conill 6a5b55740d tests: fix test regressions caused by tilde changes
ci/woodpecker/push/woodpecker Pipeline failed Details
2023-01-21 19:25:46 +00:00
Doug Freed 131619ae4b doc: update libpkgconf-pkg docs to match
ci/woodpecker/push/woodpecker Pipeline failed Details
2023-01-20 22:21:31 +00:00
Doug Freed 08db74c474 pkg: make pkgconf_compare_version consistent
The code taken from rpmvercmp in pkg-config returns -1 if a is less than
b, 0 if a is equal to b, and 1 if a is greater than b. This matches the
expectations of the comparison operators that use this function.
However, the tilde handling, the NULL handling, and the docstring all do
the opposite.

This fixes the tilde handling, the NULL handling, and the docstring to
match the behavior of the rpmvercmp code and the expectations of the
comparison operators.
2023-01-20 22:21:31 +00:00
Doug Freed eb5c6b49d6 Fix Mingw GH CI broken by 179a056
ci/woodpecker/push/woodpecker Pipeline failed Details
2023-01-20 22:19:13 +00:00
Ziemowit Łąski 1c3f246198 pkgconf: Handle spaces correctly when expanding variables
ci/woodpecker/push/woodpecker Pipeline failed Details
Given the following .pc fragment:

includedir=/mingw64/include
Cflags: -I${includedir} -I${includedir}/taglib

Should includedir be assigned the value 'C:/Program\ Files/Git/mingw64/include', the expansion of ${includedir} will be chopped off after the first space:

Cflags: -IC:/Program\

With this patch, the expansion is corrected:

Cflags: -IC:/Program\ Files/Git/mingw64/include -IC:/Program\ Files/Git/mingw64/include/taglib

Create spaces-in-paths.pc
2023-01-20 22:18:26 +00:00
wi24rd 27287f323d Update sum value of types of property.
ci/woodpecker/push/woodpecker Pipeline was successful Details
2023-01-20 22:17:33 +00:00
Eli Schwartz 8f233383cd meson: remove useless command that isn't needed
ci/woodpecker/push/woodpecker Pipeline was successful Details
The tests/*.sh are executable in the source tree, and don't need to be
chmodded after being copied to the build tree.
2023-01-20 22:13:21 +00:00
Ariadne Conill 2f51733e34 tests: add regression test for billion-laughs
ci/woodpecker/push/woodpecker Pipeline was successful Details
2023-01-20 22:11:00 +00:00
Ariadne Conill 628b2b2baf tuple: test for, and stop string processing, on truncation
otherwise a buffer overflow occurs.
this has been a bug in pkgconf since the beginning, it seems.
instead of disclosing the bug correctly, a "hotshot" developer
decided to blog about it instead.  sigh.

https://nullprogram.com/blog/2023/01/18/
2023-01-20 22:07:03 +00:00
Ariadne Conill 3e481581ba add billion-laughs test fixture 2023-01-20 22:01:38 +00:00
Ariadne Conill 0226cdda6d Merge pull request 'meson: use a feature option for tests instead of boolean' (#244) from dcbaker/pkgconf:tests-feature into master
ci/woodpecker/push/woodpecker Pipeline was successful Details
Reviewed-on: #244
2022-08-20 13:27:45 +00:00
Dylan Baker fa803c7ecd meson: use a feature option for tests instead of boolean
ci/woodpecker/pr/woodpecker Pipeline was successful Details
This allows tests to be autodetected gracefully, which is particularly
convenient for kyua and atf_sh which are fairly painful to build and
install by hand. Those who want to ensure tests are enabled or disabled
may pass `-Dtests=enabled` or `-Dtests=disabled` respectively.

This does require a modest bump in the required meson version to 0.49,
which was released at the end of 2018, so roughly 4 years ago.
2022-08-17 11:07:44 -07:00
Ariadne Conill bddf1641f8 bomtool: fix ASan issues
ci/woodpecker/push/woodpecker Pipeline was successful Details
2022-08-16 20:41:10 +00:00
Ariadne Conill 8754bdfe09 pkgconf 1.9.3.
ci/woodpecker/push/woodpecker Pipeline was successful Details
ci/woodpecker/tag/woodpecker Pipeline was successful Details
2022-08-16 19:50:26 +00:00
Ariadne Conill 6a66b312b4 libpkgconf: increase API level to 10903 2022-08-16 19:49:42 +00:00
Ariadne Conill 4c38d3f60c update NEWS for pkgconf 1.9.3
ci/woodpecker/push/woodpecker Pipeline was successful Details
2022-08-16 19:49:02 +00:00
Ariadne Conill b7593aea27 build: automake: use top_srcdir as needed 2022-08-16 19:48:44 +00:00
Ariadne Conill dbd78db67f tests: add regression test for github #259
ci/woodpecker/push/woodpecker Pipeline was successful Details
2022-08-16 19:42:13 +00:00
Ariadne Conill 80bc5ac3b9 tuple: if a global tuple is explicitly defined with --define-variable, prefer it
ci/woodpecker/push/woodpecker Pipeline was successful Details
fixes github #259
2022-08-16 19:39:05 +00:00
Ariadne Conill 5044491f43 queue: add function to free a compiled solution
ci/woodpecker/push/woodpecker Pipeline was successful Details
2022-08-16 19:27:35 +00:00
Ariadne Conill c6d14e6fa1 cli: renderer-msvc: remove pointless buf_remaining store
ci/woodpecker/push/woodpecker Pipeline was successful Details
2022-08-16 18:53:29 +00:00
Ariadne Conill ced9bee613 pkg: remove dead store in pkgconf_compare_version
ci/woodpecker/push/woodpecker Pipeline was successful Details
2022-08-16 18:51:11 +00:00
Ariadne Conill 2c89541101 bomtool: return EXIT_FAILURE if solver fails to solve 2022-08-16 18:50:35 +00:00
Ariadne Conill 5500a15133 fragment: avoid trying to merge fragments where data == NULL 2022-08-16 18:46:43 +00:00
Ariadne Conill 74faf8d0e2 queue: do not enqueue unsolved nodes as part of a solution
ci/woodpecker/push/woodpecker Pipeline was successful Details
2022-08-16 18:38:46 +00:00
Ariadne Conill c918b6e225 bomtool: enable PKGCONF_PKG_PKGF_SEARCH_PRIVATE to collect dev dependencies
ci/woodpecker/push/woodpecker Pipeline was successful Details
2022-08-13 06:44:40 +00:00
Ariadne Conill 12f3a30980 bomtool: write dependency relationships in both directions 2022-08-13 06:44:19 +00:00
Ariadne Conill 01c1d9f4cc bomtool: remove empty creation date field
ci/woodpecker/push/woodpecker Pipeline was successful Details
2022-08-12 13:07:58 +00:00
Ariadne Conill 9e8052b699 bomtool: add enough to generate a basic SBOM
ci/woodpecker/push/woodpecker Pipeline was successful Details
2022-08-12 12:57:53 +00:00
Ariadne Conill 696124b608 pkg: add support for parsing the URL from pc files 2022-08-12 12:36:21 +00:00
Ariadne Conill 79327b8967 add bomtool skeleton
ci/woodpecker/push/woodpecker Pipeline was successful Details
2022-08-12 12:07:56 +00:00
Ariadne Conill f3021a82c5 libpkgconf.pc: add license 2022-08-12 11:59:11 +00:00
Ariadne Conill 194ad3e656 man: pc.5: document copyright/maintainer fields
ci/woodpecker/push/woodpecker Pipeline was successful Details
2022-08-11 16:01:30 +00:00
Ariadne Conill aa99ddf789 pkg: add Copyright and Maintainer fields
ci/woodpecker/push/woodpecker Pipeline was successful Details
These are helpful pieces of information for BOM documents
generated by pkgconf.
2022-08-11 15:52:33 +00:00
Ariadne Conill 68b5cab72d cli: remove redundant SEARCH_PRIVATE block
ci/woodpecker/push/woodpecker Pipeline was successful Details
It turns out there was already a check for PKG_CFLAGS being requested,
but the check was busted because PKG_CFLAGS is a combined-or of all of
the various --cflags flags.

Check that PKG_CFLAGS bits are set at all on want_flags instead.
2022-08-11 15:06:08 +00:00
Ariadne Conill 78f00da130 Merge pull request 'cli: use Requires.private when cflags are requested' (#243) from psykose/pkgconf:cflags-i into master
ci/woodpecker/push/woodpecker Pipeline was successful Details
Reviewed-on: #243
2022-08-11 13:49:44 +00:00
psykose 746005582f
cli: use Requires.private when cflags are requested
ci/woodpecker/pr/woodpecker Pipeline was successful Details
2022-08-11 15:47:32 +02:00
Ariadne Conill 28b5d57b98 pkg: free SPDX license tags when a package is destroyed
ci/woodpecker/push/woodpecker Pipeline was successful Details
2022-08-08 10:25:24 +00:00
Ariadne Conill af9b26c15c pkgconf 1.9.2.
ci/woodpecker/push/woodpecker Pipeline was successful Details
ci/woodpecker/tag/woodpecker Pipeline was successful Details
2022-08-08 10:03:15 +00:00
Ariadne Conill c0d2d65347 NEWS for pkgconf 1.9.2.
ci/woodpecker/push/woodpecker Pipeline was successful Details
2022-08-08 10:02:56 +00:00
Ariadne Conill 69a3d458ef libpkgconf: revise API revision to 10902
ci/woodpecker/push/woodpecker Pipeline was successful Details
2022-08-08 09:59:50 +00:00
Ariadne Conill 7e9aa7e1fc pkg: do not break cycles across dependency lists
ci/woodpecker/push/woodpecker Pipeline was successful Details
2022-08-08 09:56:28 +00:00
Ariadne Conill 4e449bd45f cli: do not search requires.private for --libs unless --static 2022-08-08 09:42:01 +00:00
Ariadne Conill 69f630aadc pkg: only advance serial if we are actually traversing from a root 2022-08-08 09:34:45 +00:00
Ariadne Conill 760d1eea10 cli: use pkgconf_queue_solve instead of pkgconf_queue_apply 2022-08-08 09:27:39 +00:00
Ariadne Conill 8764578719 tests: ignore stdout on regress:missing test 2022-08-08 09:26:22 +00:00
Ariadne Conill 5b10a85a82 queue: add pkgconf_queue_solve API 2022-08-08 09:08:27 +00:00
Ariadne Conill 884a88583b tests: add testcase for requires.private debounce 2022-08-08 08:56:53 +00:00
Ariadne Conill 4e8f376c5d tests: add fixtures for github #258
ci/woodpecker/push/woodpecker Pipeline was successful Details
2022-08-08 05:26:00 +00:00
Ariadne Conill 79d25f979d queue: ensure private deps get flattened when --static is requested
ci/woodpecker/push/woodpecker Pipeline was successful Details
2022-08-08 00:58:55 +00:00
Ariadne Conill 03ba00d30b Merge pull request 'bsdstubs: include errno.h' (#242) from dcbaker/pkgconf:bsdstubs-errno into master
ci/woodpecker/push/woodpecker Pipeline was successful Details
Reviewed-on: #242
2022-08-08 00:51:32 +00:00
Ariadne Conill 1a66d963cf pkgconf 1.9.1.
ci/woodpecker/push/woodpecker Pipeline was successful Details
ci/woodpecker/tag/woodpecker Pipeline was successful Details
2022-08-08 00:44:23 +00:00
Ariadne Conill 8271ea1952 NEWS: update for pkgconf 1.9.1.
ci/woodpecker/push/woodpecker Pipeline was successful Details
2022-08-08 00:43:20 +00:00
Ariadne Conill b29f9d8713 cli: do not flatten or traverse the graph when asking for module-specific values
ci/woodpecker/push/woodpecker Pipeline was successful Details
2022-08-08 00:40:52 +00:00
Ariadne Conill 94b3f118cc tests: add regression test to catch --modversion regression introduced by new solver 2022-08-08 00:37:07 +00:00
Dylan Baker 7976daab9a bsdstubs: include errno.h
ci/woodpecker/pr/woodpecker Pipeline was successful Details
Needed for ENOMEM, and fixes the build on MacOS.
2022-08-06 22:30:25 -07:00
Ariadne Conill d8d669f637 pkgconf 1.9.0.
ci/woodpecker/push/woodpecker Pipeline was successful Details
ci/woodpecker/tag/woodpecker Pipeline was successful Details
2022-08-07 04:47:04 +00:00
Ariadne Conill 23556ff818 Bump libpkgconf SOVERSION for 1.9.0 changes. 2022-08-07 04:46:35 +00:00
Ariadne Conill da9b2cfbc1 NEWS: note the SPDX license branch has been merged
ci/woodpecker/push/woodpecker Pipeline was successful Details
2022-08-07 04:45:33 +00:00
Ariadne Conill b2579a661b man: pc(5): document the License field
ci/woodpecker/push/woodpecker Pipeline was successful Details
2022-08-07 04:42:55 +00:00
Ariadne Conill 666b520273 tests: add tests for SPDX license assertions
ci/woodpecker/push/woodpecker Pipeline was successful Details
2022-08-07 04:40:31 +00:00
Ariadne Conill d5f9bdae57 cli: add support for dumping SPDX expressions from modules 2022-08-07 04:40:19 +00:00
Ariadne Conill 0e05308f9c pkg: add SPDX license assertion to pkgconf builtin 2022-08-07 04:35:29 +00:00
Ariadne Conill 1389aa05ba pkg: add pkgconf_pkg_t.license field
ci/woodpecker/push/woodpecker Pipeline was successful Details
The pkgconf_pkg_t.license field maps to the new License keyword, and
should be an SPDX license expression.
2022-08-07 04:21:22 +00:00
Ariadne Conill dce34e9afd Update NEWS for pending 1.9.0 release
ci/woodpecker/push/woodpecker Pipeline was successful Details
2022-08-07 04:13:43 +00:00
Ariadne Conill 9aa0006c27 tests: improve circular reference tests to make use of the circular reference diagnostic
ci/woodpecker/push/woodpecker Pipeline was successful Details
2022-08-07 01:35:12 +00:00
Ariadne Conill 7edfdbff0b pkg: upgrade circular reference trace to a warning
ci/woodpecker/push/woodpecker Pipeline was successful Details
2022-08-07 01:29:21 +00:00
Ariadne Conill 662668d082 pkg: add trace log when breaking a circular reference
ci/woodpecker/push/woodpecker Pipeline was successful Details
2022-08-07 01:09:07 +00:00
Eli Schwartz 59a56dfa64 trivial sync of pkg.m4 from freedesktop
ci/woodpecker/push/woodpecker Pipeline was successful Details
This contains 3 changes, mostly inconsequential:

- fix some spelling issues in the comments

  eb866ade77

- bump the serial number; upstream rationale is very 🤷 but it is
  what it is:
  > There aren't any significant changes here, but this will cause aclocal
  > to get the latest version.

  677e924875

- make the status log for PKG_CHECK_MODULES say "checking for <mod>..."
  instead of "checking for <VAR>..."

  3b96e7434c

There are additional whitespace-only changes that could be synced, and
were explicitly synced in commit 95b683c864
but then undone in commit 360a818f2f so
rather than fighting over it, are simply ignored. Diffing against the
freedesktop version of pkg.m4 will therefore show additional
inconsistencies.
2022-08-07 00:40:17 +00:00
Ariadne Conill 56881f64f0 cli: resolve uninitialized pointer warnings reported by GCC 12
ci/woodpecker/push/woodpecker Pipeline was successful Details
2022-08-07 00:38:38 +00:00
Ariadne Conill b310728111 Merge pull request 'Do a better job cleaning up memory' (#239) from dcbaker/pkgconf:free-memory into master
ci/woodpecker/push/woodpecker Pipeline was successful Details
Reviewed-on: #239
2022-08-04 23:36:15 +00:00
Dylan Baker 179a0560a6 ci: run meson test with the address sanitizer enabled
Set the ASAN_OPTION so that the exitcode is not 1, this avoids asan
returning the exitcode that the tests already expect from a normal
pkgconf error
2022-08-04 15:52:10 -07:00
Dylan Baker 1cfa2d1e20 pkg: prevent circular ownership
Otherwise in a case where A references B, and B references A, A and B
will have mutual ownership of each other and prevent each other from
being free'd.
2022-08-04 15:52:10 -07:00
Dylan Baker 301d8fa0c6 queue: free unused dependencies when flattening 2022-08-04 15:52:10 -07:00
Dylan Baker 34b110200a dependency: zero list after freeing 2022-08-04 15:52:10 -07:00
Dylan Baker e71a5a3370 dependency: add debug information for dependency refcounting 2022-08-04 15:52:10 -07:00
Dylan Baker 4934205737 pkg: add name of pkg being refed/unrefed to debug outpu 2022-08-04 15:52:10 -07:00
Dylan Baker a46ce3672f queue: when collecting dependents don't iterate private twice
Currently, the private field is iterated collecting private deps and
normal deps. It should only be iterated when collecting private deps.
2022-08-04 15:52:10 -07:00
Dylan Baker 4493a322f6 main: do cleanup when checking required version 2022-08-04 15:52:10 -07:00
Dylan Baker a391f9b650 pkg: use goto cleanup idiom 2022-08-04 15:52:10 -07:00
Dylan Baker 38103134a5 main: goto cleanup in validate case too
This fixes leaks in two tests
2022-08-04 15:52:10 -07:00
Dylan Baker 171738024e cache: clear the cache with pkgconf_cache_remove
Which results in more code re-use.
2022-08-04 15:52:10 -07:00
Dylan Baker e4d1c8ffa5 queue: when flattening do nothing if the flattened deps are empty 2022-08-04 15:52:10 -07:00
Dylan Baker 6609001114 queue: unref dependency in all cases 2022-08-04 15:52:10 -07:00
Dylan Baker e275594ba6 queue: ensure cleanup happens when applying 2022-08-04 15:52:10 -07:00
Dylan Baker 4a1119aa2a dependency: Fix reference counting of dependency_addraw
We only want a reference to be added for the value inserted into the
list, not the one returned. The returned one is unowned until it reaches
the public dependency_add function, which returns an owned pointer
instead. This makes things semantically more correct.

Unfortunately, this means in a few cases we have to write some ugly
code like:
```c
pkgconf_dependency_t *dep = pkgcond_dependency_add("args");
pkgconf_dependency_unref(dep->owner, dep);
```
2022-08-04 15:52:10 -07:00
Dylan Baker a4de6235c2 cache: when removing a package from the cache unset the cached flag 2022-08-04 15:52:10 -07:00
Dylan Baker ebe74fd253 cache: free the cache table when it is empty and set to NULL
We do the latter for the benefit of libpkgconf. This cleans up a
significant number of memory leaks in the cache handling.
2022-08-04 15:52:10 -07:00
Ariadne Conill d240afe7d9 Merge pull request 'Fix macro definition interfering with -Wmisleading-indentation' (#241) from dcbaker/pkgconf:submit/misleading-indentation into master
ci/woodpecker/push/woodpecker Pipeline was successful Details
Reviewed-on: #241
2022-08-04 04:33:11 +00:00
Dylan Baker 125a13d3b9 meson: add -Wmisleading-indentation
ci/woodpecker/pr/woodpecker Pipeline was successful Details
A useful warning when loop and conditional statements are allowed
without braces.
2022-08-03 12:03:15 -07:00
Dylan Baker 96c61cbab0 libpkgconf: remove trailing ; from macro definition
GCC has a lovely bug (which I will report as soon as I have an account),
which causes -Wmisleading-indentation to miss cases of misleading
indentation after a `;;`, since the macro adds `;`, and in call cases
the caller also adds `;`, we end up with a double macro and gcc fails to
warn.
2022-08-03 12:03:15 -07:00
Ariadne Conill a042827951 Merge pull request 'meson cleanups and fixes' (#240) from dcbaker/pkgconf:submit/meson-cleanups into master
ci/woodpecker/push/woodpecker Pipeline was successful Details
Reviewed-on: #240
2022-08-02 23:09:24 +00:00
Dylan Baker dd779ad9f8 meson: add check to run_command
ci/woodpecker/pr/woodpecker Pipeline was successful Details
Because we really should be checking that it succeeds, and because not
setting it is deprecated.
2022-08-01 09:40:08 -07:00
Dylan Baker c04097e491 meson: pass configured files idiomatically
Instead of attempting to figure out what the paths will be, take the
returned file object and pass that around, meson will then automatically
figure out the correct paths.
2022-08-01 09:40:08 -07:00
Dylan Baker 06fe2e23b0 meson: use current_source_dir and current_build_dir instead of *_root
The latter doesn't work correctly when being used as a subproject, as it
returns the *absolute* root. So if pkgconf is being built as part of
muon, then it will return muon's source root. current_source_dir, on the
other hand returns the directory correctly whether being built as a
subproject or superproject.
2022-08-01 09:40:08 -07:00
Dylan Baker 1f993bc095 meson: use string methods to avoid repeating data
Instead of writing `['HAVE_FOO_H', 'foo.h']`, use meson's string methods
to just write `['foo.h']`, and let meson create `HAVE_FOO_H` for us.
2022-08-01 09:40:08 -07:00
Dylan Baker f947af057f meson: use str.format for improved readability 2022-08-01 09:40:08 -07:00
Dylan Baker 5ba74dec93 meson: use straight indexing instead of array.get()
It's more terse, and we don't need the support of a fallback value.
2022-08-01 09:40:08 -07:00
Dylan Baker bf307c1d95 ci: set meson to build with -Werror
This will help catch any new warnings added in CI.
2022-08-01 09:40:08 -07:00
Dylan Baker 4a2c9c285f meson: use C99 as the standard
autoconf uses either C99 or Gnu99. Meson does not provide a graceful way
to select gnu99 if possible or c99 (though there are several proposals
currently happening to get there), so I've selected c99 as the
conservative default. Without this, the compiler uses whatever it's
default happens to be, which may or may not work out correctly, and
hides bugs from CI that are present with c99 as the default.
2022-07-29 10:23:18 -07:00
Dylan Baker 40ec08594e meson: add warning for implicit-function-declarations
This would be triggered without the previous addition of -D_BSD_SOURCE
for strdup, among others
2022-07-29 10:23:18 -07:00
Dylan Baker 71974d8c54 meson: Add _BSD_SOURCE and _DEFAULT_SOURCE
To avoid warnings about string functions like strdup which are otherwise
undefined, but succeed at linking anyway when the C standard is c99.
2022-07-29 10:23:02 -07:00
Ariadne Conill 918b660992 woodpecker: track debian testing for autoconf 2.71
ci/woodpecker/push/woodpecker Pipeline was successful Details
2022-07-26 18:15:50 +00:00
Ariadne Conill f93870efd9 tests: add testcase for legacy FDO rules plus pc_sysrootdir
ci/woodpecker/push/woodpecker Pipeline was successful Details
2022-07-26 18:05:31 +00:00
Ariadne Conill 18e2406002 tests: add omg-sysroot-uninstalled fixture 2022-07-26 18:03:15 +00:00
Ariadne Conill 6c70781aad introduce PKG_CONFIG_PKGCONF1_SYSROOT_RULES for legacy pkgconf behavior 2022-07-26 18:00:22 +00:00
Ariadne Conill f8aefea7ec pkg: add flags argument to pkgconf_pkg_new_from_file 2022-07-26 17:13:15 +00:00
Ariadne Conill 297e18f2c8 tuple: add flags parameter to pkgconf_tuple_parse 2022-07-26 17:08:48 +00:00
Ariadne Conill d9ec3ee642 tests: add testcases for confirming desired sysroot behavior regarding -uninstalled packages 2022-07-26 16:46:39 +00:00
Ariadne Conill b0802cb3d1 Revert "pkgconf_pkg_parser_value_set(): fix code-path ordering bug."
ci/woodpecker/push/woodpecker Pipeline was successful Details
This reverts commit 13fe4c8c58.
2022-06-26 19:41:31 +00:00
Ariadne Conill b602e33141 github actions: use debian testing
ci/woodpecker/push/woodpecker Pipeline was successful Details
2022-06-26 19:39:09 +00:00
Ariadne Conill 72e429ae70 tuple: use ${pc_sysrootdir} instead of client->sysroot_dir where relevant
ci/woodpecker/push/woodpecker Pipeline was successful Details
2022-06-26 19:35:19 +00:00
Ariadne Conill 7fa632a658 tests: sysroot: add additional tests 2022-06-26 19:34:54 +00:00
Ariadne Conill 9950312fde tests: add additional test fixtures 2022-06-26 19:34:39 +00:00
Ariadne Conill 19b1befb5d add additional sysroot testcase fixtures
ci/woodpecker/push/woodpecker Pipeline was successful Details
2022-06-26 19:21:52 +00:00
Ariadne Conill a61193c723 pkg: fix sysroot_dir logic for github 213
ci/woodpecker/push/woodpecker Pipeline was successful Details
2022-06-26 19:16:00 +00:00
Ariadne Conill d68a867dc0 tuple: fall back to using globals rather than preferring them 2022-06-26 19:15:07 +00:00
Ariadne Conill bc272e4e9f autoconf: run autoupdate
ci/woodpecker/push/woodpecker Pipeline was successful Details
2022-06-26 18:58:08 +00:00
Ariadne Conill 623b8f7851 tests: further fixups 2022-06-26 18:56:36 +00:00
Ariadne Conill fdd7d192e0 queue: fix ISO C conformance for fallthrough label
ci/woodpecker/push/woodpecker Pipeline failed Details
2022-06-26 18:39:00 +00:00
Ariadne Conill 11164376f7 main: handle --personality load failure
ci/woodpecker/push/woodpecker Pipeline failed Details
2022-06-26 18:34:22 +00:00
Ariadne Conill ab352222a2 tests: fix up some test changes from the solver optimizations
ci/woodpecker/push/woodpecker Pipeline failed Details
the output of pkgconf is basically functionally equivalent in both cases
2022-06-26 18:22:04 +00:00
Ariadne Conill 04a6dda79f main: refactor apply_variable 2022-06-26 18:17:30 +00:00
Ariadne Conill a1a415111f queue: handle pkgconf_pkg_verify_dependency failure while flattening
ci/woodpecker/push/woodpecker Pipeline failed Details
2022-06-26 18:09:22 +00:00
Ariadne Conill 9bc6d80e61 queue: push new unresolved dependencies to the front of the queue, rather than the tail 2022-06-26 18:06:04 +00:00
Ariadne Conill fe4db3aad9 queue: skip dependency collection for root node 2022-06-26 18:04:42 +00:00
Ariadne Conill 5a82a259ac queue: use maxdepth after flattening
ci/woodpecker/push/woodpecker Pipeline failed Details
2022-06-26 15:17:08 +00:00
Ariadne Conill a416dc1fd6 queue: advance client serial when walking requires.private for flattening 2022-06-26 15:16:36 +00:00
Ariadne Conill 197fcadd4c queue: add flattening code 2022-06-26 15:02:37 +00:00
Ariadne Conill 5817e8848f pkg: track the number of hits a package has gotten while solving for dependencies
ci/woodpecker/push/woodpecker Pipeline failed Details
2022-06-26 07:22:56 +00:00
Ariadne Conill 6ae17bd0ef pkg: split pkgconf_pkg_traverse into a serial-modifying version 2022-06-26 06:05:40 +00:00
Ariadne Conill ffa0805d58 cache: use pkgconf_reallocarray stub
ci/woodpecker/push/woodpecker Pipeline was successful Details
2022-06-26 04:38:02 +00:00
Ariadne Conill c1579d381c bsdstubs: add pkgconf_reallocarray 2022-06-26 04:37:18 +00:00
Ariadne Conill 4c76f6bf01 meson: check for reallocarray
ci/woodpecker/push/woodpecker Pipeline was successful Details
it is needed for the new cache code
2022-06-26 04:33:47 +00:00
Ariadne Conill 664f741f26 autoconf: check for reallocarray
it is needed for the new cache code
2022-06-26 04:33:25 +00:00
Ariadne Conill 464672404e cache: refactor to use a continguous table and bsearch
ci/woodpecker/push/woodpecker Pipeline was successful Details
cache functions are the hottest part of the pkgconf code when
profiled, by removing the linked list for lookups, we can turn
lookups into an O(k) operation
2022-06-26 04:30:35 +00:00
Dylan Baker c0fa7879b2 libpkgconf: zero path lists after freeing
ci/woodpecker/push/woodpecker Pipeline was successful Details
This is required to make the pointer safely re-usable after being freed,
otherwise the list still says that it has nodes, but they point nowhere.
This is particularly important for libpkgconf, if a caller needs to
re-enter the library after freeing a path in a static path (such as the
default personality)
2022-06-26 03:12:34 +00:00
Dylan Baker 2d201af326 libpkgconf: Add a helper to zero `pkgconf_list_t`s 2022-06-26 03:12:34 +00:00
Ariadne Conill 21ffd343e1 CI: woodpecker: use matrix builds
ci/woodpecker/push/woodpecker Pipeline was successful Details
2022-06-26 03:11:36 +00:00
Ariadne Conill a441455bf4 CI: add woodpecker config 2022-06-26 03:11:36 +00:00
Ariadne Conill cf48b61a59 stdinc: include strings.h on POSIX 2022-02-21 04:42:26 -06:00
Ariadne Conill 40131312ec meson: check for strdup, strcasecmp, strncasecmp 2022-02-21 04:41:08 -06:00
Ariadne Conill cc4ccc1429 meson: use _BSD_SOURCE for checking for symbols 2022-02-21 04:39:49 -06:00
Ariadne Conill ac964d13f3
Merge pull request #240 from Tachi107/readme-meson
docs: mention Meson instead of CMake for Win build
2022-02-21 04:27:20 -06:00
Ariadne Conill 0995e49977
Merge branch 'master' into readme-meson 2022-02-21 04:27:11 -06:00
Ariadne Conill 820af53a2d
Merge pull request #241 from Olf0/patch-1
Re-do MR #235, i.e. the vanished commit fe98e1b
2022-02-21 04:25:48 -06:00
Ariadne Conill a45dbccc01
Merge pull request #242 from data-man/dirent_latest
Update dirent.h to latest
2022-02-21 04:25:36 -06:00
Ariadne Conill c6cfca6730
Merge pull request #245 from dcbaker/submit/remove-const
libpkgconf: remove const modifier from error_handler data pointer
2022-02-21 04:25:26 -06:00
Ariadne Conill aaabc2cb15
Merge pull request #246 from dcbaker/submit/personality-deinit
personality: use an unsigned to track initializations instead of a bool.
2022-02-21 04:25:14 -06:00
Dylan Baker c581e24a67 personality: use an unsigned to track initializations
Instead of a bool. The latter will result in de-initing leaving the
library unable to init again, which works out for the cli, but is
problematic for other consumers (meson++ and muon).

v2: - Add docs that the functions are not thread safe
2022-02-14 21:22:05 -08:00
Dylan Baker f5d6bb71f8 libpkgconf: remove const modifier from error_handler data pointer
Currently, the data pointer is `const void *`, which means that the
handler can't modify the data without casting away the constness.
2022-02-07 09:34:09 -08:00
data-man b132ce8317 Update dirent.h to latest 2022-01-08 10:55:28 +05:00
olf ae3a9c5440
Re-do MR #235, i.e. the vanished commit fe98e1b 2021-12-11 22:56:31 +01:00
Andrea Pappacoda 6109e06089
docs: mention Meson instead of CMake for Win build
Fixes #233
2021-12-11 14:49:19 +01:00
Dylan Baker 1044bb57ca meson: make use of override_dependency() if possible
This allows simplifying the subproject override to simply

```meson
dependency('libpkgconf')
```
2021-12-01 09:17:07 -06:00
Dylan Baker 72c59b89c6 meson: Add dependency for for libpkgconf
This allows others using libpkgconf as a dependency to do use this as a
subproject. They can write something like:

```meson
dependency('libpkgconf', fallback : ['libpkgconf', 'dep_libpkgconf'])
```

Then install a wrap file for libpkgconf and build it as part of their
project.
2021-12-01 09:17:07 -06:00
Mattias Hansson 8d9d3de6eb pkg.m4: PKG_CHECK_MODULES provides modversion
Projects using PKG_CHECK_MODULES wants to add dependency versions to
their binaries. Currently, the projects have to resolve dependency
versions themselves when using pkgconf.

With this patch PKG_CHECK_MODULES now defines a $PKG_VERSION variable
that represents `--modversion`.
2021-10-27 06:41:28 -05:00
Mattias Hansson 360a818f2f pkg.m4: Unified indentation in PKG_CHECK_MODULES
Currently the indentation in PKG_CHECK_MODULES is a mix och tabs and
spaces which makes it hard to read. This patch unifies the indentation
in the function to spaces.
2021-10-27 06:41:28 -05:00
Ariadne Conill f3049d634d README: note that --debug output should not be considered stable 2021-10-25 21:52:52 -06:00
Ariadne Conill bf933903aa hackfix a couple of flaky tests 2021-10-07 01:29:29 -06:00
Ariadne Conill 2b82a4f63e use a serial instead of PKGCONF_PKG_PROPF_SEEN 2021-10-07 00:27:32 -06:00
Ariadne Conill 7d8cc1e4ce dependency: add pkgconf_dependency_copy() 2021-10-06 13:13:34 -06:00
Ariadne Conill c547edd07f deconst the client on pkgconf_dependency_add() 2021-10-06 11:52:18 -06:00
Ariadne Conill 4144d506bb implement dependency refcounting 2021-10-06 11:48:37 -06:00
olf d87114068f Fix typo
verses -> versus
2021-10-06 12:30:49 -05:00
Ariadne Conill 8130dd159e dependency: add pkgconf_dependency_free_one 2021-10-06 11:29:18 -06:00
Ariadne Conill 2b390ea9cf add memory leak fix info to NEWS 2021-08-17 15:32:30 -06:00
Ariadne Conill 4b87e256d3 cache: clear package cache without using the refcounts 2021-08-17 15:29:55 -06:00
Ariadne Conill df1b671c83 dependency: use dependency match owner with pkgconf_pkg_unref() 2021-08-17 15:18:47 -06:00
Ariadne Conill 41bff10998 cli: ensure the client and cross-personality are cleaned up in all cases 2021-08-17 14:54:36 -06:00
Ariadne Conill f411e7e55b cli: free package resolution queue unconditionally 2021-08-17 14:47:10 -06:00
Ariadne Conill ce82e36c14 cli: fix memory leak when packages are not provided on the command line 2021-08-17 14:39:44 -06:00
Ariadne Conill cef30268e1 pkgconf 1.8.0. 2021-07-24 20:40:52 -06:00
Ariadne Conill a10a88ef64 tests: regress: disable sysroot_munge test for now, not working with distcheck 2021-07-24 20:39:29 -06:00
Ariadne Conill 2ed2b98e64 workflows: more distcheck fixes 2021-07-24 20:28:04 -06:00
Ariadne Conill 9b49eb2280 workflows: install xz package 2021-07-24 20:26:44 -06:00
Ariadne Conill 4d5b378f9e workflows: use distcheck instead of check for autotools tests 2021-07-24 20:25:15 -06:00
Ariadne Conill f3f7145963 NEWS: add updates for pkgconf 1.8.0 2021-07-24 20:19:46 -06:00
Ariadne Conill 78bcb17116 personality: do not perform path filtering on default SYSTEM_INCLUDE_PATHS and SYSTEM_LIBRARY_PATHS
This is not consistent with the way the personality files or environment variables
are handled.

Fixes #224.
2021-07-24 20:06:55 -06:00
Ariadne Conill 4e73e37d29 meson: fix non-static build 2021-07-24 19:56:46 -06:00
Ariadne Conill ceece2c195 pkg: fix up comment about issue #213 workaround 2021-07-24 19:47:33 -06:00
Ariadne Conill 76968a4f8d fix static builds on Windows with Meson
Fixes #222
2021-07-24 19:45:43 -06:00
Sandro Mani ed86f2dda3 Don't prepend sysroot_dir if pkg-config file lies outside of sysroot_dir 2021-07-24 20:43:58 -05:00
Ariadne Conill 9ea26eb913 README: expand on the pkg-config compatibility promise
A bunch of CMake developers, who apparently did not comprehend the previous
compatibility promise statement, decided to passive-aggressively demand we fix
their non-bug anyway.

Clarify in more detail what level of pkg-config compatibility we provide, and
mention that such passive-aggressive behaviour is considered a CoC violation.

Fixes #228.
2021-07-24 19:41:48 -06:00
Stone Tickle fa859bb045 close error_msgout if opened 2021-07-24 06:08:25 -05:00
Stone Tickle dba2600014 deinit personality in cli 2021-07-24 06:08:25 -05:00
Stone Tickle d688a7bd03 implement pkgconf_cross_personality_deinit 2021-07-24 06:08:25 -05:00
midipix 13fe4c8c58 pkgconf_pkg_parser_value_set(): fix code-path ordering bug.
Prior to this commit, the code path responsible for prefix redefinition
(motivated by --define-prefix or otherwise) was visited more than
once, specifically since the check ignored pkg->owner->prefix_varname.
2021-06-18 14:42:41 -05:00
Ariadne Conill 1f319c2608 we are moving to OFTC 2021-05-19 05:52:27 -05:00
orbea 2fdc5f0081 man: Document the --validate option. 2021-03-29 09:50:41 -08:00
Christoph Reiter 4f73f6a1d6 Rework path handling on native Windows
The current approach was to parse the .pc and, detect the prefix, throw
everything together and at the end replace all \ with / to not produce invalid
escape sequences.

This has the problem that escaping in .pc files is ignored and no longer
possible. Also in case the prefix path has a space in it the result would be
invalid because of missing escaping.

This changes the following things:

* We no longer normalize values at the end. Instead we assume .pc files use "/"
  as a directory separator or "\\", same format as under Unix. "\" alone no
  longer works. This shouldn't be a problem since most build tools produce .pc
  files with "/" like meson, cmake, autotools.

* When injecting the prefix at runtime we convert the prefix to use "/" and
  escape spaces so that in combination with the .pc content the result is a
  valid escaped path value again.

This patch has been used in MSYS2 for some months now.

See #212
2021-03-20 06:59:38 -08:00
Christoph Reiter 4be39c59fb Remove usage of cygwin_conv_path() under cygwin/msys
This converted Unix paths to Windows paths, but all cygwin tools
work with Unix paths so this shouldn't be needed.

There is one use case if you use a cygwin pkgconf with a non-cygwin toolchain,
but pkgconf works reasonable well natively now so this shouldn't be needed
anymore and more likely leads to problems and confusion.

Both cygwin and msys have patched this out already:
* https://cygwin.com/git-cygwin-packages/?p=git/cygwin-packages/pkgconf.git;a=blob;f=pkgconf.cygport;h=e5d003f3f3dfc9e374b916974018022ad8d68852;hb=HEAD#l55
* a4bce0c294/pkgconf/PKGBUILD (L26)
2021-03-20 06:58:53 -08:00
Ariadne Conill 458101e787 pkgconf 1.7.4. 2021-03-18 07:05:03 -06:00
Ariadne Conill dbb6a232e5 path: don't use PATH_MAX, use PKGCONF_ITEM_SIZE * 4 for realpath buffer 2021-03-18 06:56:55 -06:00
Ariadne Conill a4e8cf87ad remove sourcehut CI config 2021-03-18 06:52:55 -06:00
Ariadne Conill 9f6b2ced47 README: use github CI badge 2021-03-18 06:52:31 -06:00
Ariadne Conill 37b596ccda CI: fix alpine autotools CI 2021-03-18 06:49:16 -06:00
Ariadne Conill caaf4861cf CI: fix alpine CI 2021-03-18 06:48:07 -06:00
Ariadne Conill 00cc9a8caf CI: add alpine CI alongside debian CI 2021-03-18 06:46:09 -06:00
Ariadne Conill 599dfcb264 main: extend copyright notice to 2021 2021-03-18 06:42:57 -06:00
Ariadne Conill 402fd9fe1f add funding.yml 2021-03-18 06:38:24 -06:00
Ariadne Conill fd1b8ccca6 main: if PKG_CONFIG_FDO_SYSROOT_RULES is set, or DESTDIR matches PKG_CONFIG_SYSROOT_DIRS, disable the automatic sysroot rewriting
Closes #205.
2021-03-18 06:22:11 -06:00
Ariadne Conill b6c8f6fb0a NEWS: document --static --pure default on Windows (closes #207) 2021-03-18 06:05:48 -06:00
Ariadne Conill 008d706958 libpkgconf: personality: default: set want_default_static and want_default_pure to true on windows 2021-03-18 06:03:47 -06:00
Ariadne Conill f9531ce9fe add support for pkgconf_cross_personality_t.want_default_pure 2021-03-18 06:02:00 -06:00
Ariadne Conill 52d19e1b9e libpkgconf: fileio: pkgconf_fgetline(): handle quoted=true when a comment introduction is encountered
Fixes #215.
2021-03-18 05:45:41 -06:00
Ariadne Conill 347281ebfe tests: add fragment-comment testcase (ref #215) 2021-03-18 05:39:45 -06:00
Jeff Moguillansky dcf529b83d cli: add environment variable PKG_CONFIG_DONT_DEFINE_PREFIX
On Windows, pkgconf redefines the prefix by default.
This gives the user the option to disable this behavior via an environment variable.
The benefit of an environment variable is the user can change this behavior when
using a build system such as cmake or meson, which may not expose this
parameter to the user.
2021-02-06 14:06:04 -07:00
Ryan Scott ab404bc25b Fix #209
This commit fixes #209 by applying the suggestion from
https://github.com/pkgconf/pkgconf/issues/209#issuecomment-771609136.
2021-02-05 23:57:10 -07:00
Fabian Groffen 13a5d9a5f0 libpkgconf: path: supply buffer to realpath
To avoid a crash on some platforms (like Darwin 9) provide a buffer to
realpath(3).

Darwin 9 (last PPC target) documents realpath needs to be given a buffer
to the resolved_path argument large enough to hold PATH_MAX bytes.
With NULL argument it crashes.  Solaris makes no mention of
resolved_path to be allowed NULL, yet recent versions accept it and
malloc(3) accordingly.

Because the documentation explicitly mentions PATH_MAX being the limit
to what realpath(3) would write in resolved_path, switching to a static
buffer here doesn't limit resolution compared to dynamically allocating
a buffer by realpath(3).

While this change requires a bit more space on the stack, it avoids a
malloc/free sequence, and allows successful operation on (older)
platforms that lack support for dynamically allocating a return buffer
in realpath(3).

Signed-off-by: Fabian Groffen <grobian@gentoo.org>
2021-01-08 18:44:40 -05:00
Christoph Reiter 78a77dd497 meson: install README.md/AUTHORS to share/doc/pkgconf
To mirror what the autotools build does.
2020-11-28 19:42:00 -07:00
Christoph Reiter 0526364b85 meson: allow building a static version of libpkgconf
when using library() instead of shared_library() the user can decide
to build a shared or static version, or both. The default is still shared
as before.

This mirrors what the autotools based build sysstem can do.
2020-11-28 19:42:00 -07:00
Christoph Reiter a69bdfa28e meson: generate a .pc file for libpkgconf 2020-11-28 19:42:00 -07:00
Christoph Reiter de8fc9e438 meson: install headers into pkgconf/libpkgconf instead of just libpkgconf
To mirror what the autotools build does
2020-11-28 19:42:00 -07:00
Christoph Reiter 869f2a84d6 pkgconf_pkg_parser_version_func: fix whitespace detection
In case the version string has no whitespace then strcspn() returns
strlen() of the input, so whitespace is only found if len != strlen.

This fixes invalid warnings when parsing version fields.
2020-11-28 19:17:03 -07:00
Christoph Reiter b218cae5a9 Add CI for debian+meson/autotools
Builds and runs tests. Using Debian testing since the test framework
is only in testing right now.
2020-11-23 10:31:52 -07:00
Christoph Reiter 24589cddb0 Add basic CI for mingw-w64 32/64 bit
This only builds things with meson and no tests are run.
2020-11-23 04:13:05 -07:00
Ariadne Conill f418b997e5 configure: shift issue tracking back to github 2020-11-21 10:00:41 -07:00
orbea bd960e9d05 man: Silence pkgconf-personality.5 warning.
man: ./pkgconf-personality.5:97:2: WARNING: unusual Xr order: pc(5) after pkg.m4(7)
2020-08-09 20:22:14 -06:00
Ariadne Conill 1eeb4ee5c2 start NEWS for 1.7.4 2020-06-11 18:03:42 -06:00
Ariadne Conill 2a8bebf289 libpkgconf: path: rewrite DOS paths in non-cygwin case too 2020-06-11 18:00:56 -06:00
Tobias Stoeckmann 262a0c964f man: pkgconf: fixed typo
Fixed typo in it's vs its.
2020-06-10 00:20:36 -06:00
Tobias Stoeckmann f818a69b3d libpkgconf: pkg: fix out ouf boundary access
If a file with a matching "uninstalled" name exists but cannot be
parsed, an invalid memory area is accessed.

How to reproduce:
$ touch poc-uninstalled.pc
$ PKG_CONFIG_PATH=. pkgconf poc
2020-06-10 00:20:36 -06:00
Ariadne Conill ef135d819c meson: remove some autotools cruft 2020-06-02 18:58:00 -06:00
Ariadne Conill aca0674837 pkgconf 1.7.3. 2020-05-30 19:20:25 -06:00
Ariadne Conill 40726b14ac update NEWS 2020-05-30 19:20:25 -06:00
Ariadne Conill 354c87279b libpkgconf: tuple: fix truncation when no overflow occurs 2020-05-30 19:20:25 -06:00
Tobias Stoeckmann 5eb9cae009 libpkgconf: tuple: fix out of boundary write
This is the same issue which has been fixed in dependency code.

If a line contains a variable which is longer than PKGCONF_ITEM_SIZE,
then the varname buffer overflows.

The code itself still does not check if a closing } exists and
truncates variable names which are too long. Since these would
be functional changes and this commit is about a protection against
undefined behaviour on a language level, these changes are not
included.

Proof of concept:
$ echo "Description: poc" > poc.pc
$ echo "Version: 1" >> poc.pc
$ echo -n 'Name: ${'
$ dd if=/dev/zero bs=1 count=66535 | tr '\0' 'x' >> poc.pc
$ echo >> poc.pc
$ pkgconf poc.pc

On my Linux system, when compiled with gcc, the varname buffer overflows
directly into buf, which means that no crash can be notified.

It's easiest to figure out when adding strlen() and sizeof() output
as debug lines.
2020-05-30 19:09:24 -06:00
Tobias Stoeckmann 100bc605de libpkgconf: fragment: fix out of boundary write
fragment_quote adds quotation to fragments if needed. It allocates a
buffer and grows it as needed.

Unfortunately the dst pointer is not updated after a realloc, which
means that dst still points into the old memory area. Further writing
characters into that area leads to out of boundy writes.

Proof of concept:

$ cat > poc.pc << EOF
Name: poc
Description: poc
Version: 1
CFlags: -Ia
CFlags: -I%%%%%%%%%%%%%%%%%%%%b
CFlags: -I%%%%%%%%%%%%%%%%%%%%c
CFlags: -Id
EOF
$ pkgconf --cflags poc.pc

Most reliable attempt is to compile pkgconf with address sanitizer,
but this file should lead to an abort on a glibc system due to modified
chunk pointers (tested with Linux on amd64).

But since this is undefined behaviour, it depends on system details.
2020-05-30 19:05:53 -06:00
Ariadne Conill 7bd08a51bf update NEWS 2020-05-30 12:43:08 -06:00
Tobias Stoeckmann dc04193c48 libpkgconf: fragment: fix out of boundary read
Parsing a fragment which consists only of a single dash leads to
an out of boundary read. It duplicates the following entry which
is not expected behaviour if another fragment follows.

Proof of concept:

$ cat > poc.pc << "EOF"
Name: poc
Description: poc
Version: 1
Cflags: - -I/somewhere
EOF
$ PKG_CONFIG_PATH=. pkgconf --cflags poc
-I/somewhere -I/somewhere

If - is the last entry, it leads to an out of boundary read, which is
easy to see if pkgconf is compiled with address sanitizer.
2020-05-30 12:43:08 -06:00
Vincent Torri 42b355310f fix missing backslashes in paths on Windows
According to

https://docs.microsoft.com/fr-fr/windows/win32/fileio/naming-a-file

backslashes (with slashes) are a path separator, hence must no be
considered as an escape code.

The first fix, in argvsplit.c, disables this. But because of fragment_quote(),
the backslashes are doubled. Hence the second fix in fragment.c

With this pc file :

prefix=C:/Documents/msys2/opt/efl_64
libdir=${prefix}/lib
includedir=${prefix}/include

Name: eina
Description: efl: eina
Version: 1.24.99
Requires.private: iconv
Libs: -L${libdir} -leina -pthread -levil
Libs.private: -lpsapi -lole32 -lws2_32 -lsecur32 -luuid -lregex -lm
Cflags:-I${includedir}/eina-1 -I${includedir}/efl-1
-I${includedir}/eina-1/eina -pthread

pkgconf.exe --cflags eina

returns :

-IC:\Documents\msys2\opt\efl_64/include/eina-1
-IC:\Documents\msys2\opt\efl_64/include/efl-1
-IC:\Documents\msys2\opt\efl_64/include/eina-1/eina -pthread
-DWINICONV_CONST= -IC:\Documents\msys2\opt\ewpi_64/include
2020-05-30 12:39:43 -06:00
Ariadne Conill e3e89926b5 start NEWS for 1.7.3 2020-05-26 14:04:34 -06:00
Tobias Stoeckmann fb9acedcad libpkgconf: dependency: fix out of boundary write
It is possible to trigger an out of boundary write in function
pkgconf_dependency_parse_str if a dependency line contains a very
long comparator. The comparator is stored in a temporary buffer which
has a size of PKGCONF_ITEM_SIZE.

The line which is parsed can be up to PKGCONF_BUFSIZE characters long,
which is larger than PKGCONF_ITEM_SIZE (although it depends on PATH_MAX).

Having a comparator which is longer than PKGCONF_ITEM_SIZE therefore
leads to an out of boundary write. Although it is undefined behaviour,
this can lead to an overridden compare variable, which in turn can lead
to an invalid instruction pointer, i.e. most likely a crash or code
execution (very unlikely).

Proof of concept:

$ echo "Requires: x " > poc.pc
$ dd if=/dev/zero bs=1 count=65535 | tr '\0' '<' >> poc.pc
$ pkgconf poc.pc

Eiter compile pkgconf with address sanitizer or run pkgconf multiple
times, eventually it might crash (assuming that ASLR is in place).

In order to fix this, I decided to use an end pointer to avoid OOB write.
Alternative would be to increase the buffer size, but I try to avoid that
since this would be additional ~60 KB stack space for a very unlikely
situation.
2020-05-26 14:03:55 -06:00
Ariadne Conill c6b93941a0 pkgconf 1.7.2. 2020-05-26 13:46:20 -06:00
Ariadne Conill c613eb5cce libpkgconf: pkg: use a second pointer for demunging windows paths 2020-05-26 13:42:39 -06:00
Ariadne Conill 92b09aef9a pkgconf 1.7.1. 2020-05-26 11:06:35 -06:00
Ariadne Conill e70b536ea3 libpkgconf: pkg: when generating a search path, use the correct path separator
Before, this could result in generated paths like C:\foo\pkgconfig/bar.pc on Windows.
2020-05-26 11:01:46 -06:00
Ariadne Conill 47466470d2 main: extend copyright statement to 2020 in --about 2020-05-26 10:57:51 -06:00
Ariadne Conill ee1fe1a70a update NEWS for 1.7.1 changes so far 2020-05-26 07:49:15 -06:00
Ariadne Conill 0253fddc1d libpkgconf: pkg: fix computation of pkgconf_pkg_t.id on Windows.
Windows allows both \ and / as valid path characters.  A computed path
such as C:\development\libfoo\pkgconfig/foo.pc will result in a computed
pkgconf_pkg_t.id of "pkgconfig/foo".

Accordingly, correct the path normalization for checking for / after
the \ path has been dealt with in all cases.
2020-05-26 07:41:16 -06:00
Neal Gompa be6b382dde Makefile.am: Add remaining Meson files to be included in dist tarballs
The tarballs produced by 'make distcheck' did not include all files
required for using Meson because they were not all enumerated in
EXTRA_DIST.

This change adds the remaining Meson files to the tarball.
2020-05-25 05:59:35 -06:00
Tobias Stoeckmann 9e16d2709c libpkgconf: personality: fix out of boundary access
It is possible to set the instruction pointer to undefined values by
using an operator larger than ':' in ASCII.

Since the personality function array does not have 256 entries, an
invalid operator can overflow the array.

Proof of concept:

$ echo "a _ b" > poc
$ ln -s $(which pkgconf) poc-pkgconf
$ ./poc-pkgconf
2020-05-25 05:55:39 -06:00
Ariadne Conill dd57abfe9f pkgconf 1.7.0. 2020-05-24 14:55:02 -06:00
Ariadne Conill 82d57184e7 meson: fix detection of strndup() on windows 2020-05-24 14:54:58 -06:00
Ariadne Conill 4fb7683c3e add support for the PKGCONF_PKG_PKGF_DONT_MERGE_SPECIAL_FRAGMENTS flag used in build2. 2020-05-24 14:40:47 -06:00
Ariadne Conill fb9c2258d1 update NEWS for previous patch 2020-05-24 14:37:13 -06:00
Ben 011db1bb88 Do not complain about malformed whitespace from \n on Version line
Every version line has a newline at the end; the malformed whitespace checker
should just check for trailing spaces and tabs.

Resolves https://todo.sr.ht/~kaniini/pkgconf/15
2020-05-24 14:36:46 -06:00
Ariadne Conill fce1199b53 cli: add support for PKG_CONFIG_MSVC_SYNTAX env variable
Patch from Dan Kegel.
2020-05-24 14:34:17 -06:00
Olaf Hering cdc2bf887e use correct autoconf macro name
AC_CONFIG_MACRO_DIR without trailing S is known by autoconf since 2.58.
AC_CONFIG_MACRO_DIR with trailing S is known by autoconf newer than 2.69.

This fixes libtool after 'autoreconf -fi'.

Fixes commit a8a65c7f6c
Related to issue #145

Signed-off-by: Olaf Hering <olaf@aepfle.de>
2020-05-24 14:29:19 -06:00
Ariadne Conill 80508f7138 NEWS: start NEWS for 1.7.0
was hoping to go straight into 2.0 but we need a new maintenance
branch :(
2020-05-24 14:27:52 -06:00
Ariadne Conill 382a89c173 pkg: pkgconf_compare_version(): do not return levenshtein distance in strcmp() case 2020-05-24 14:18:16 -06:00
Tobias Stoeckmann 92745ad9cb libpkgconf: parser: fix out of boundary access
It is possible to trigger an out of boundary access with specially
crafted files. If a line consist of only a key and spaces, then
op will point to '\0'-ending of the buffer. Since p is iterated by
one byte right past this ending '\0', the next read access to p is
effectively out of bounds.

Theoretically this can also lead to out of boundary writes if spaces
are encountered.

Proof of concept (I recommend to compile with address sanitizer):

$ echo -n a > poc.pc
$ dd if=/dev/zero bs=1 count=65533 | tr '\0' ' ' >> poc.pc
$ pkgconf poc.pc
2020-05-24 14:10:18 -06:00
Tobias Stoeckmann bd4ed1ca02 libpkgconf: fileio: prevent buffer overflow.
pkgconf_fgetline is called with a user-defined buffer, its size, and
a FILE stream to read input from.

If the buffer is almost completely filled and the file stream contains
an escaped character, then it is possible to trigger an off-by-one
buffer overflow with a '\0' character.

Easiest example to trigger this:

char buf[2];
pkgconf_fgetline(buf, sizeof(buf), stdin);

Enter "\\" (two backslashes) and press enter. If the library and the
program are compiled with address sanitizer, you will see the program
crashing. Otherwise it depends on your architecture what happens.

Since nobody should be using a buffer of only size 1 or 2, keep enough
space for a possibly escaped character in while loop by subtracting one
more byte for this situation, not just for '\0'.
2020-05-24 14:09:44 -06:00
Ariadne Conill 62bbd3b664 cli: remove --version to --modversion remapping
This has been a source of frequent complaints, so we drop it.
Resolves: https://todo.sr.ht/~kaniini/pkgconf/6
2020-01-21 10:32:36 -06:00
Ariadne Conill 48dc665ae3 personality: add support for WantDefaultStatic setting 2019-10-19 00:56:17 -05:00
Ariadne Conill 40fe48355b cli: main: add --shared option 2019-10-19 00:46:32 -05:00
Ariadne Conill f1ce393632 fix pkgconf-personality man page 2019-09-30 05:22:21 -05:00
Ariadne Conill 2adafc2729 libpkgconf: personality: return the default personality if loading a personality file failed 2019-08-23 12:48:11 -05:00
Ariadne Conill 19aa93e371 prepare for pkgconf 2.0 development 2019-08-04 15:54:24 -05:00
Nicolas Braud-Santoni 1d8c6b71d6 Fix troff markup in pkgconf-personality(5)
A list was started with .Bl but not ended (with .El)
2019-07-12 09:54:02 -05:00
Nicolas Braud-Santoni db3ba0ef86 Fix spelling in pkg.m4(7) 2019-07-12 09:54:02 -05:00
Ariadne Conill af1fbf9820 builds: add fedora meson build 2019-07-12 08:57:25 -05:00
Ariadne Conill 3f178f71d7 builds: add fedora rawhide build 2019-07-12 08:50:23 -05:00
Ariadne Conill f3e1073f96 build: include meson build files in generated tarballs 2019-07-12 08:31:21 -05:00
Ariadne Conill d351e6ae59 Revert "tests: remove some no longer relevant bitrot in the test environment file"
This reverts commit 107ad34f8f.

Breaks autoconf.
2019-07-12 08:23:36 -05:00
Ariadne Conill 061627f091 meson: bump required version to 0.47 for copy directive 2019-07-12 08:20:05 -05:00
Ariadne Conill 107ad34f8f tests: remove some no longer relevant bitrot in the test environment file 2019-07-12 08:19:19 -05:00
Ariadne Conill c862e030cf pkgconf 1.6.3. 2019-07-12 06:53:37 -05:00
Ariadne Conill 5f3aa3a8d2 cli: bump copyright notice to 2019 2019-07-12 06:53:25 -05:00
Ariadne Conill 286e354785 update NEWS for 1.6.3. 2019-07-12 06:46:29 -05:00
Ariadne Conill 3740bfb6d7 tests: add test for malformed versions generating a diagnostic with --validate 2019-07-12 06:42:08 -05:00
Ariadne Conill a91e0bf215 tests: explicitly test --print-provides with malformed versions 2019-07-12 06:37:46 -05:00
Ariadne Conill c10f69994b libpkgconf: pkg: generate diagnostic for and trim malformed versions 2019-07-12 06:35:48 -05:00
Ariadne Conill 312b4e51a9 tests: add test for malformed version handling 2019-07-12 06:22:41 -05:00
Ariadne Conill 3783d65784 tests: add malformed-version fixture 2019-07-12 06:15:35 -05:00
Ariadne Conill 6c3356a094 update README [ci skip] 2019-07-12 05:56:35 -05:00
Ariadne Conill 833294f592 builds: add freebsd CI build 2019-07-12 05:52:37 -05:00
Ariadne Conill cab8eddc3a build: remove no longer included CMakeLists files 2019-07-12 05:48:22 -05:00
Ariadne Conill 7a395932f2 drop CMake support 2019-07-12 05:45:16 -05:00
Ariadne Conill c816ce6969 pkgconf 1.6.2. (closes #38, #40, #41) 2019-07-11 03:50:00 -05:00
Ariadne Conill 0a247fa102 man: pkgconf: add --modversion description (closes #34) 2019-07-11 03:43:18 -05:00
Ariadne Conill 7e0b0fadab libpkgconf: path: fix memory leak when deduping paths (closes #39) 2019-07-11 03:43:18 -05:00
Ariadne Conill 03e5d0fd31 update AUTHORS using `git shortlog -e` 2019-07-11 03:30:56 -05:00
Ariadne Conill c7c3ddbfcf add mailmap 2019-07-11 03:27:15 -05:00
kaniini 984dc98438 Merge branch 'lfs-fix' of a_tsoy/pkgconf into master 2019-06-16 05:59:03 +00:00
Alexander Tsoy db9c1e96a1
fix the order of header includes
config.h should be included before stdinc.h, otherwise large file
support is not enabled.

Downstream bug: https://bugs.gentoo.org/687548
2019-06-08 04:55:52 +03:00
William Pitcock ebfcaf5081 normalize include guards. closes #33 2019-05-25 16:00:09 -05:00
kaniini 7460d2870e Merge branch 'fix-msvc-build' of seungha.yang/pkgconf into master 2019-05-18 00:52:09 +00:00
Seungha Yang 5436558eb8 main: Fix build with MSVC
Use pkgconf_strndup() since strndup() might be unavailable
2019-05-11 01:17:32 +09:00
William Pitcock 0ba98da26c lite: remove --simulate 2019-05-06 15:22:11 -05:00
William Pitcock 2d0c1f5cb7 lite: disable debug logging 2019-05-06 15:17:08 -05:00
William Pitcock 43ca536b9f lite: disable some bloat 2019-05-06 15:13:17 -05:00
William Pitcock fb98f5a866 lite: add build system for pkgconf-lite mode 2019-05-06 14:48:38 -05:00
William Pitcock bd6f90a8e6 ci: add freebsd test build 2019-05-04 03:03:24 -05:00
William Pitcock 7a8f96a98c add cmake test build 2019-05-04 02:54:52 -05:00
William Pitcock 8d322b8959 add meson test build 2019-05-04 02:51:32 -05:00
William Pitcock bf1c18a181 add test sr.ht autoconf alpine edge build 2019-05-04 02:47:28 -05:00
William Pitcock be6011222b pkgconf 1.6.1. 2019-03-23 22:38:50 -05:00
William Pitcock 662957ca7d libpkgconf: tuple: tighten quoting logic a bit
closes #12
2019-03-23 22:34:11 -05:00
William Pitcock 3afd14c49e libpkgconf: path: use realpath(3) to deduplicate the search path
closes #24
2019-03-23 22:27:05 -05:00
William Pitcock ba1f48e48e libpkgconf: client: ensure PKG_CONFIG_LIBDIR being empty overrides the default search paths
closes #25
2019-03-23 22:18:40 -05:00
William Pitcock 45eae2039e start NEWS for 1.6.1. 2019-03-23 21:56:13 -05:00
kaniini 3e8103c7ac Merge branch 'master' of esmil/pkgconf into master 2019-03-07 00:01:39 +00:00
Emil Renner Berthing d926e75b34 main: fix personalities when argv[0] contains path 2019-03-06 16:09:21 +01:00
William Pitcock e2fdd6f470 pkgconf 1.6.0. 2019-01-14 14:12:32 -06:00
William Pitcock 9315ee9ee6 tests: add orphaned-requires-private test 2019-01-14 14:07:19 -06:00
William Pitcock 737e326ae1 tests: add orphaned requires.private testcase 2019-01-14 14:04:50 -06:00
William Pitcock 183e68df39 libpkgconf: add LIBPKGCONF_VERSION macro 2019-01-14 13:52:04 -06:00
William Pitcock 5c7c9127bc doc: update fragment API docs 2019-01-14 13:49:41 -06:00
William Pitcock 6854265f28 libpkgconf: pkg: use pkgconf_fragment_copy_list() to clean up cflags gathering logic (closes #20) 2019-01-14 13:48:23 -06:00
William Pitcock 36a5b7acbd libpkgconf: fragment: add pkgconf_fragment_copy_list() 2019-01-14 13:48:02 -06:00
William Pitcock 0ae52182c9 libpkgconf: pkg: clean up pkgconf_parser interactions (closes #13) 2019-01-14 13:11:59 -06:00
William Pitcock 059b2f61ec add a code of conduct 2018-10-22 15:12:44 -05:00
William Pitcock 74133eda31 pkgconf 1.5.4. 2018-10-15 10:23:35 -05:00
kaniini ccd2440cde Merge branch 'fix-slashes' of nacho/pkgconf into master 2018-09-27 02:07:31 +00:00
Ignacio Casal Quinteiro 2c05971029 Canonicalize paths before using them
This fixes a problem where on Windows the prefix would
not match if the prefix is generated with backslashes
and the rest of the variables use normal slashes
2018-09-17 16:31:25 +02:00
Ignacio Casal Quinteiro 9f17da92d2 On Windows the path prefix should be checked caseless 2018-09-17 15:41:27 +02:00
Ignacio Casal Quinteiro c9dffb8570 Fix build on windows with meson 2018-09-17 15:41:27 +02:00
William Pitcock 101b99b5b5 pkgconf 1.5.3. 2018-07-28 19:47:53 -05:00
William Pitcock 47284486df regress: add test for empty tuple buffer overflow issue 2018-07-28 19:45:57 -05:00
kaniini 3b5626a008 Merge branch 'master' of awilfox/pkgconf into master 2018-07-29 00:18:09 +00:00
A. Wilcox 9b7affe0b1
tuple: Ensure buf length is always >= 1 in dequote
If a key is defined with no value, dequote will allocate a buffer with a
length of 0.  Since the buffer's length is 0, any manipulation of its
content is UB.

Example .pc file:

prefix=/usr
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${prefix}/include

xcflags=
xlibs= -lSM -lICE  -lX11

Name: Obt
Description: Openbox Toolkit Library
Version: 3.6
Requires: glib-2.0 libxml-2.0
Libs: -L${libdir} -lobt ${xlibs}
Cflags: -I${includedir}/openbox/3.6 ${xcflags}

Output using pkgconf 1.5.2 on x86_64 Linux/musl:

% pkgconf --cflags obt-3.5
-I/usr/include/openbox/3.6 \�\\�I\�\ -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/include/libxml2
2018-07-28 19:06:33 -05:00
William Pitcock 4735e17287 pkgconf 1.5.2. 2018-07-19 17:30:33 -05:00
William Pitcock 7939732f80 build: install pkgconf-personality(5) manpage 2018-07-19 17:27:02 -05:00
William Pitcock 41f8031533 man: add pkgconf-personality(5) 2018-07-19 17:25:28 -05:00
kaniini 7e89a30442 Merge branch 'graham/system-paths-regression' of pkgconf/pkgconf into master 2018-07-05 13:35:54 +00:00
Graham Ollis fb08ae2bd2 environment variables for system paths should override compiled-in defaults 2018-06-25 06:36:57 -04:00
William Pitcock 5601568267 pkgconf 1.5.1. 2018-06-16 16:37:36 -05:00
William Pitcock 6f05fec4b5 pkg: give a correctly sized vtable to the parser 2018-06-16 16:35:44 -05:00
William Pitcock 8f6e071d58 tests: add test fixture for bogus .pc files 2018-06-16 16:35:19 -05:00
William Pitcock b77c04f343 update NEWS 2018-06-14 16:17:54 -05:00
William Pitcock b46bb93cd1 libpkgconf: tuple: properly dequote tuples when added from the parser (closes legacy github bug #186) 2018-06-14 16:12:04 -05:00
William Pitcock ae7faf73fd tests: add testcase for tuple dequoting bug (legacy github bug #186) 2018-06-14 16:11:21 -05:00
William Pitcock 854a6adfe9 tests: add tuple-quoting fixture 2018-06-14 15:31:00 -05:00
William Pitcock 3673494431 README: make it more clear the git repo has moved 2018-06-14 14:49:24 -05:00
Graham Ollis 273d1d0461 use pkgconf_strlcpy
On Debian/Ubuntu I get:

  CC       libpkgconf/personality.lo
  libpkgconf/personality.c: In function ‘load_personality_with_path’:
  libpkgconf/personality.c:195:3: warning: implicit declaration of function ‘strlcpy’ [-Wimplicit-function-declaration]
  strlcpy(pathbuf, path, sizeof pathbuf);
        ^~~~~~~
  CC       libpkgconf/parser.lo
  CCLD     libpkgconf.la
  ar: `u' modifier ignored since `D' is the default (see `U')
  CC       cli/pkgconf-main.o
  CC       cli/pkgconf-getopt_long.o
  CC       cli/pkgconf-renderer-msvc.o
  CCLD     pkgconf
  ./.libs/libpkgconf.so: undefined reference to `strlcpy'
2018-06-14 14:46:34 -05:00
William Pitcock 2b5202dd1a cmake: likewise 2018-06-14 14:45:33 -05:00
William Pitcock 782c88ce77 meson: set PERSONALITY_PATH to something useful 2018-06-14 14:43:01 -05:00
William Pitcock ea98ff3e5b not at github anymore 2018-06-04 13:13:42 -05:00
William Pitcock ab8df57205 NEWS: mention progress on #166 2018-05-10 13:41:47 -05:00
William Pitcock 8aa662227c main: deduce the cross-compilation triplet based on program name 2018-05-10 13:37:40 -05:00
William Pitcock db7845b4c7 configure: fix search path for triplets 2018-05-10 13:36:49 -05:00
William Pitcock 3ccc4454d1 libpkgconf: personality: ensure the path list is properly initialized before searching for triplets 2018-05-10 13:36:22 -05:00
William Pitcock c46868294f cli: implement --personality 2018-05-09 22:53:55 -05:00
William Pitcock 40897f246b libpkgconf: personality: remove const from the default personality, since it's not really const 2018-05-09 22:52:27 -05:00
William Pitcock 25b2105e93 libpkgconf: client: if tracing is disabled, don't try to trace 2018-05-09 22:52:07 -05:00
William Pitcock e6ce6c8edd libpkgconf: personality: fixups 2018-05-09 22:39:39 -05:00
William Pitcock e9324ee4bc cli: implement --dump-personality 2018-05-09 22:21:45 -05:00
William Pitcock 751348298b libpkgconf: personality: fill in the rest of the personality parser 2018-05-09 22:08:28 -05:00
William Pitcock 1244f8f8e7 libpkgconf: refactor out the rfc822 message parser so that the cross-personality code can share it 2018-05-09 21:21:39 -05:00
William Pitcock f702967d0a libpkgconf: pkg: refactor pkgconf_pkg_new_from_file to prepare to factor out the rfc822 parser 2018-05-09 19:56:30 -05:00
William Pitcock 0f17a4f390 libpkgconf: pkg: mark owning client earlier, to allow for refactoring out the rfc822 parser 2018-05-09 19:33:12 -05:00
William Pitcock 9439b683ca libpkgconf: personality: add stub cross personality loader 2018-05-09 19:27:53 -05:00
William Pitcock 6b0e346c28 libpkgconf: refactor building the dir lists into separate concerns 2018-05-09 17:07:26 -05:00
William Pitcock 854490c5b9 libpkgconf: add basic support for cross-compile personality objects 2018-05-09 16:54:21 -05:00
William Pitcock 43e8c7b44d libpkgconf: path: add path list copying function 2018-05-09 16:35:21 -05:00
William Pitcock 15efbc249b update NEWS 2018-05-09 15:59:13 -05:00
orbea 4704b9325c man: Silence mandoc warnings for pkg.m4.7
man -Tlint pkg.m4

  new sentence, new line
    (mdoc) A new sentence starts in the middle of a text line. Start it
    on a new input line to help formatters produce correct spacing.

  skipping paragraph macro
    In mdoc(7) documents, this happens

      - at the beginning and end of sections and subsections
      - right before non-compact lists and displays
      - at the end of items in non-column, non-compact lists
      - and for multiple consecutive paragraph macros.

    In man(7) documents, it happens

      - for empty P, PP, and LP macros
      - for IP macros having neither head nor body arguments
      - for br or sp right after SH or SS

  no blank before trailing delimiter
    (mdoc) The last argument of a macro that supports trailing
    delimiter arguments is longer than one byte and ends with a
    trailing delimiter. Consider inserting a blank such that the
    delimiter becomes a separate argument, thus moving it out of
    the scope of the macro.

  man: pkg.m4.7:30:34: WARNING: new sentence, new line
  man: pkg.m4.7:38:20: WARNING: new sentence, new line
  man: pkg.m4.7:33:2: WARNING: skipping paragraph macro: Pp after Sh
  man: pkg.m4.7:41:2: WARNING: skipping paragraph macro: Pp at the end of Ss
  man: pkg.m4.7:46:2: WARNING: skipping paragraph macro: Pp at the end of Ss
  man: pkg.m4.7:134:27: STYLE: no blank before trailing delimiter: Nm ... check.
  man: pkg.m4.7:143:27: STYLE: no blank before trailing delimiter: Nm ... check.

https://man.openbsd.org/mandoc.1
2018-04-10 00:42:52 -05:00
orbea 8d060b84da man: Silence more mandoc warnings
man -Tlint pkgconf

  skipping no-space macro
    (mdoc) An input line begins with an Ns macro, or the next argument
    after an Ns macro is an isolated closing delimiter. The macro is
    ignored.

  unusual Xr order
    (mdoc) In the SEE ALSO section, an Xr macro with a lower section
    number follows one with a higher number, or two Xr macros referring
    to the same section are out of alphabetical order.

  man: pkgconf.1:114:16: WARNING: skipping no-space macro
  man: pkgconf.1:114:39: WARNING: skipping no-space macro
  man: pkgconf.1:119:14: WARNING: skipping no-space macro
  man: pkgconf.1:119:35: WARNING: skipping no-space macro
  man: pkgconf.1:119:56: WARNING: skipping no-space macro
  man: pkgconf.1:128:28: WARNING: skipping no-space macro
  man: pkgconf.1:147:24: WARNING: skipping no-space macro
  man: pkgconf.1:217:2: WARNING: unusual Xr order: pc(5) after pkg.m4(7)

  man -Tlint pc

  whitespace at end of input line
    (mdoc, man, roff) Whitespace at the end of input lines is almost
    never semantically significant -- but in the odd case where it
    might be, it is extremely confusing when reviewing and maintaining
    documents.

  new sentence, new line
    (mdoc) A new sentence starts in the middle of a text line. Start it
    on a new input line to help formatters produce correct spacing.

  missing -width in -tag list, using 8n
    (mdoc) Every Bl macro having the -tag argument requires -width, too.

  man: pc.5:17:76: STYLE: whitespace at end of input line
  man: pc.5:18:50: WARNING: new sentence, new line
  man: pc.5:49:67: WARNING: new sentence, new line
  man: pc.5:87:38: WARNING: new sentence, new line
  man: pc.5:90:27: WARNING: new sentence, new line
  man: pc.5:113:66: WARNING: new sentence, new line
  man: pc.5:117:61: WARNING: new sentence, new line
  man: pc.5:123:49: WARNING: new sentence, new line
  man: pc.5:56:2: WARNING: missing -width in -tag list, using 6n: Bl -tag
  man: pc.5:80:2: WARNING: missing -width in -tag list, using 6n: Bl -tag

https://man.openbsd.org/mandoc.1
2018-04-09 22:28:35 -05:00
orbea 3e8a55e186 man: Silence mandoc warnings.
man -Tlint pkgconf

  new sentence, new line
    (mdoc) A new sentence starts in the middle of a text line. Start it
    on a new input line to help formatters produce correct spacing.

  man: pkgconf.1:23:24: WARNING: new sentence, new line
  man: pkgconf.1:42:15: WARNING: new sentence, new line
  man: pkgconf.1:44:73: WARNING: new sentence, new line
  man: pkgconf.1:53:63: WARNING: new sentence, new line
  man: pkgconf.1:60:58: WARNING: new sentence, new line
  man: pkgconf.1:69:66: WARNING: new sentence, new line
  man: pkgconf.1:85:56: WARNING: new sentence, new line
  man: pkgconf.1:153:7: WARNING: new sentence, new line
  man: pkgconf.1:202:43: WARNING: new sentence, new line

  https://man.openbsd.org/mandoc.1
2018-04-09 03:33:58 -05:00
Leorize f36ccc1d91 libpkgconf: add support for Haiku
client: use BELIBRARIES

On Haiku, BELIBRARIES is the equivalent to LIBRARY_PATH on many other
systems, while LIBRARY_PATH is instead the LD_LIBRARY_PATH of Haiku.

pkg: bootstrap package search paths with Haiku's find_paths

This commit adds build_default_pkgconfig_path. The function appends
to the list given the default pkgconfig paths, and will supersede
get_default_pkgconfig_path
2018-04-05 10:02:54 -05:00
William Pitcock 3f753fa3dd libpkgconf: dependency: preference uncoloured nodes in event of a dependency collision 2018-03-18 19:03:18 -05:00
William Pitcock 7e9ed6922d libpkgconf: pkg: skip over -I cflags from Requires.internal nodes when building a cflags list 2018-03-18 18:05:55 -05:00
William Pitcock ad65bc4a71 libpkgconf: dependency: allow dependency nodes to be colored with traits 2018-03-18 18:03:33 -05:00
William Pitcock 9a53290d8a tests: add new test fixtures for Requires.internal 2018-03-18 18:00:04 -05:00
William Pitcock f03ec3ff90 libpkgconf: add support for proposed Requires.internal extension 2018-03-18 15:46:53 -05:00
William Pitcock 30f7a96ea2 cmake: make it work under mingw by restricting MSVC flags to an if(MSVC) block
closes #179
2018-03-13 13:35:12 -05:00
TingPing a50bf726e0 Fix incorrect comment (#178) 2018-03-07 23:16:18 -06:00
TingPing 60c05f5621 Improve prefix rewriting on Windows (#177)
* cli: Default to rewriting prefix on Windows

This matches `pkg-config` behavior

* libpkgconf: Rewrite the prefix of all variables
2018-03-07 23:00:22 -06:00
TingPing 706273c746 meson: Add option to build without kyua for tests (#175) 2018-03-06 23:28:05 -06:00
TingPing 83eea876b0 meson: Fix defining PKGCONF_API (#174) 2018-03-06 23:27:54 -06:00
Tobias Kortkamp b0796cffa3 Fix --exists description in man page (#173)
pkgconf exists with 0 if all modules exist and not the other way around.
2018-03-06 13:37:43 -06:00
William Pitcock 2156a74afc cli: implement --fragment-filter (closes #167) 2018-02-28 13:00:53 -06:00
William Pitcock ca4349655c travis: real gzip is needed instead of busybox gzip 2018-02-20 12:15:15 -06:00
William Pitcock 39b85c51f4 travis: distcheck needs xz 2018-02-20 12:13:04 -06:00
William Pitcock 67f8cc7fb9 travis: use alpine instead of ubuntu for CI 2018-02-20 12:10:35 -06:00
William Pitcock a705b5a018 build: fix autoconf sanity check path 2018-02-12 00:46:47 -06:00
William Pitcock 1e91c245e3 build: chase changes for cmake & meson i hope 2018-02-12 00:45:55 -06:00
William Pitcock 2902141a9f build: move cli tool to cli folder 2018-02-12 00:42:27 -06:00
William Pitcock f4137995d9 pkgconf 1.4.2. 2018-02-12 00:37:03 -06:00
William Pitcock d4bb96b7f1 tests: add regression test for #172, closes #172 2018-02-08 14:31:28 -06:00
William Pitcock 0d52339141 libpkgconf: pkg: ensure the dependency node has a solution associated with it
Sometimes this did not happen, e.g. when using providers as the solution (ref #172).
2018-02-08 14:26:25 -06:00
William Pitcock 1eb866efb2 tests: parser: late-breaking testsuite changes for quoting changes 2018-01-22 15:35:54 -06:00
William Pitcock 1645683d62 pkgconf 1.4.1. 2018-01-22 15:20:29 -06:00
William Pitcock d5fd74d799 libpkgconf: fragment: revert the quoting changes, but not the lexing changes
a few strange edge cases are causing problems (closes #168)
2018-01-22 15:13:14 -06:00
William Pitcock d1618ece3a msvc: add support for converting cflags too 2018-01-05 18:05:47 -06:00
William Pitcock 4a09efe070 libpkgconf: pkg: fix harmless gcc7 compiler warning 2018-01-05 11:38:21 -06:00
William Pitcock 1c9f36036a pkgconf 1.4.0. 2018-01-05 11:33:21 -06:00
William Pitcock 7cce958d78 msvc: handle quoting correctly for cmd.exe 2018-01-05 11:31:43 -06:00
William Pitcock 5d6c9ba98c build: set soversion to 3 2018-01-05 11:18:19 -06:00
William Pitcock 789da4cf33 bump copyrights to 2018 2017-12-31 10:41:32 -06:00
William Pitcock 7ba36b5d89 NEWS: document #165 changes 2017-12-21 02:35:48 -06:00
William Pitcock a7864d0111 man: pc: discuss extensions and optional gating approach for hard dependency on extensions 2017-12-21 02:25:09 -06:00
William Pitcock a42f265c07 libpkgconf: pkg: include system libdir and includedir search paths as variables in builtin packages (closes #165) 2017-12-21 02:19:21 -06:00
Issam Maghni 8a9b7d59df Shortening symlink (#164) 2017-12-19 17:48:44 -06:00
William Pitcock e214ec88e8 pkgconf 1.3.90. 2017-12-15 19:00:09 -06:00
William Pitcock 11c1e5d090 NEWS: mention the new manpages [skip c-i] 2017-12-15 18:58:30 -06:00
William Pitcock fef3293467 man: add pc(5) mdoc (closes #148) 2017-12-15 18:53:59 -06:00
William Pitcock cf96c562e1 libpkgconf: argvsplit: fix escape handling in tokenizer (closes #163) 2017-12-14 22:41:14 -06:00
William Pitcock 6073a49229 tests: add testcases for #163 2017-12-14 22:13:19 -06:00
William Pitcock 18abb4ccc1 libpkgconf: fragment: fix nitpick warning reported by MSVC (closes #162) 2017-12-13 11:18:25 -06:00
William Pitcock f5627481d7 NEWS: document API change discussed in #154 2017-12-12 00:23:23 -06:00
William Pitcock e0bf4009cb libpkgconf: pkg: rename pkgconf_pkg_t.requires to pkgconf_pkg_t.required (closes #154)
C++20 makes requires a keyword, so we need to not use it in headers.
2017-12-12 00:21:21 -06:00
William Pitcock 4fea62b08e NEWS: update 2017-12-11 18:45:10 -06:00
William Pitcock 278a2bd667 libpkgconf: fragment: rework quoting and lexing (closes #139, #153)
we now use POSIX-style quoting for all fragments.  it is our belief that this is the
most optimal behaviour for portability, because all POSIX-compliant tools require
single-quotes to be considered as literal (closes #153).

because of this, we are able to remove some hacks on the lexer side which were there
to simulate pkg-config quoting, but were basically utterly wrong (closes #139).
2017-12-11 18:25:55 -06:00
William Pitcock 1c9880a03b main: fix refcount violation exposed by incremental dependency solver 2017-12-11 18:23:14 -06:00
William Pitcock 7b1fac4c99 tests: remove fragment-quoting-4 and fragment-quoting-6 tests as they are not relevant anymore 2017-12-11 17:41:08 -06:00
William Pitcock 973aff21e9 libpkgconf: tuple: add some trace logging 2017-12-11 17:39:12 -06:00
William Pitcock 7274357565 libpkgconf: fragment: track merged fragments, as they should never be quoted 2017-12-10 00:39:39 -06:00
William Pitcock cad2515be5 libpkgconf: fragment: there are no consumers of non-escaped rendered fragment lists, so deprecate the option 2017-12-10 00:36:20 -06:00
William Pitcock d2b6983385 libpkgconf: cache: fix refcount issue exposed by recent depgraph solver changes 2017-12-08 13:39:40 -06:00
William Pitcock 4058a722a4 NEWS: mention --msvc-syntax and the infrastructure allowing it 2017-12-07 20:12:29 -06:00
William Pitcock b216ccb33d build: add renderer-msvc.h to noinst_HEADERS 2017-12-07 20:08:29 -06:00
William Pitcock 0b09c111ed main: implement a MSVC renderer (only some fragments supported) (closes #161) 2017-12-07 20:07:30 -06:00
William Pitcock 19d91e90e5 libpkgconf: fragment: allow for overriding the default fragment rendering behaviour 2017-12-07 19:13:35 -06:00
William Pitcock eec34c480c NEWS: cmake was mentioned twice 2017-12-07 15:22:58 -06:00
William Pitcock fc5e33a3cb add 1.4 stuff so far to NEWS 2017-12-07 15:22:05 -06:00
William Pitcock 73119e0165 update NEWS with bugfixes/enhancements that were backported to 1.3.8 and later 2017-12-07 15:14:35 -06:00
William Pitcock 0d6cad31fa meson: look for atf-sh (closes #160) 2017-12-07 12:34:06 -06:00
William Pitcock f1e5014921 main: use single-quotes for --env output 2017-12-07 12:31:45 -06:00
William Pitcock 7ab4dffaf1 main: implement --env (closes #159) 2017-12-06 17:45:17 -06:00
William Pitcock 69a05a74b5 man: pkgconf(1): add crossreference to new pkg.m4(7) manpage (closes #147) 2017-12-05 19:52:32 -06:00
William Pitcock 7fed573a6f man: finish pkg.m4(7) 2017-12-05 19:47:51 -06:00
William Pitcock d80d66f5ff man: add starting point on pkg.m4(7) manpage 2017-12-05 19:17:31 -06:00
William Pitcock 60df6ba3b0 build: move manpages to man subdir 2017-12-05 18:45:06 -06:00
William Pitcock 5ed0f532d4 docs: s/frameworks/libraries/ (closes #156) 2017-12-05 18:12:47 -06:00
William Pitcock f7406afc5b libpkgconf: pkg: do not mention PKG_CONFIG_SKIP_CONFLICTS env var when simplified errors are requested (closes #134) 2017-12-05 18:04:42 -06:00
William Pitcock 06abf28dab libpkgconf: client: handle NULL client in pkgconf_trace calls 2017-12-05 17:46:57 -06:00
William Pitcock 74d58d1b63 libpkgconf: pkg: cache solutions for already solved dependency graph nodes
in almost all cases, we partially solve the dependency graph multiple times, which
just wastes resources.  if we record the solution to a given dependency node, further
iterations can make use of the previous solution without having to solve it again.

this is safe because all provides entries (including virtuals) are knowable prior to
solving the dependency graph the first time.

a nice side effect of this is that all packages are preloaded when querying
information about them (--cflags and related commands).
2017-12-05 17:34:01 -06:00
William Pitcock 44b4b126f3 libpkgconf: pkg: record which pkgconf_client_t owns each pkgconf_pkg_t object 2017-12-05 17:32:00 -06:00
William Pitcock 4c0cc29277 libpkgconf: pkg: add refcount debugging 2017-12-05 17:24:57 -06:00
William Pitcock b6a56c8728 main: do not evaluate module paths for modules that are not really on disk (closes #158) 2017-12-02 21:14:43 -06:00
William Pitcock b52d3819a2 main: add --modversion to --help output (closes #157) 2017-11-28 13:41:35 -06:00
William Pitcock 4589274c43 libpkgconf: start to remove PKGCONF_BUFSIZE allocations from the stack. (closes #149)
Patch by Karen Arutyunov.
2017-10-16 12:56:19 -05:00
William Pitcock 1297385762 libpkgconf: fragment: remove obsolete code in pkgconf_fragment_should_munge() 2017-10-16 12:51:59 -05:00
William Pitcock 36551cca83 libpkgconf: path: relocate the path before doing dedup checks (closes #151) 2017-10-16 11:30:22 -05:00
William Pitcock 3bc2e21dd1 libpkgconf: path: ensure entire buffer is zeroed before calling realpath() on it (closes #150) 2017-10-16 11:26:27 -05:00
Baptiste Daroussin 6985a179c1 libpkgconf: Fix issue when sysroot is '/'
If sysroot is /, simply do nothing.

This fixes #146
2017-10-11 17:05:35 +02:00
Baptiste Daroussin 4e50938e78 tests: add a test case for #146 2017-10-11 17:05:23 +02:00
✈ Graham ✈ a8a65c7f6c Only add warnings and std flags if supported by compiler (autoconf) (#145)
* Only add warning and std flags if supported by compiler (autoconf)

* bundle AX_CHECK_COMPILE_FLAG macro from autoconf-archive
2017-09-26 12:27:52 -05:00
William Pitcock 301dc16909 makefile: helps to add the test to the actual testfile list 2017-09-24 14:22:56 -05:00
William Pitcock e56fea66e4 travis: third time should be the charm 2017-09-24 14:15:04 -05:00
William Pitcock 5a10c6bb7b travis: retry 2017-09-24 14:10:30 -05:00
William Pitcock 0d89bea9a8 travis: grrrrr 2017-09-24 14:06:06 -05:00
✈ Graham ✈ e9c2e6f127 Only add warning and std flags if supported by compiler (#144)
This fixes errors like those reported in #143 on Solaris
(and probably other platforms where gcc is not the native
compiler):

c99: -W option with unknown program all

This only fixes it for cmake, but presumably similar checks
could be added for autoconf as well.
2017-09-24 12:52:49 -05:00
William Pitcock fae657101c libpkgconf: argvsplit: handle double backslash case properly (closes #140) 2017-09-23 00:24:34 -05:00
William Pitcock abe0f5c821 libpkgconf: fileio: fix quoting logic for double backslash case (ref #140) 2017-09-23 00:19:16 -05:00
William Pitcock db56c80d92 libpkgconf: fragment: add debug to document post-subst output to parser 2017-09-23 00:11:55 -05:00
William Pitcock 95b68f7c02 tests: add testcase for #140 2017-09-23 00:08:12 -05:00
William Pitcock 67dd48a343 libpkgconf: api: handle DLL_EXPORT libtool case on mingw (closes #141) 2017-09-23 00:00:43 -05:00
William Pitcock 24c1439d52 libpkgconf: stdinc: fix SIZE_FMT_SPECIFIER on mingw 2017-09-22 23:58:40 -05:00
William Pitcock 420c62e10c libpkgconf: pkg: refactor parser harness to allow providing warnings, provide warning for improper fragment list 2017-09-19 21:58:54 -05:00
William Pitcock 7ced8d77ae libpkgconf: fragment: pkgconf_fragment_parse: return false on parse failure 2017-09-19 21:48:53 -05:00
William Pitcock 72cf871421 tests: regress: add malformed quoting test 2017-09-19 21:35:18 -05:00
William Pitcock 7786554be2 libpkgconf: fragment: check pkgconf_argv_split() return value 2017-09-19 21:34:24 -05:00
William Pitcock 56101390ac libpkgconf: fragment parsing: do not pass NULL to pkgconf_fragment_add() 2017-09-19 21:08:18 -05:00
William Pitcock e9fd43caa7 libpkgconf: clean up header includes (closes #137) 2017-09-17 23:38:25 -05:00
William Pitcock ebb4c73525 libpkgconf: client: resolve memory leak of filter lists (closes #130) 2017-09-13 15:02:57 -05:00
William Pitcock ed63a31b7a main: free fragment lists in apply_cflags/apply_libs() in all cases (closes #131) 2017-09-13 15:01:49 -05:00
William Pitcock f808300a01 libpkgconf: pkg: some elements of virtual packages should be freed as they have heap-allocated portions (closes #132) 2017-09-13 14:56:10 -05:00
William Pitcock 9b55fc3c23 libpkgconf: cache: refactor the way package objects are marked as cached to avoid memory leaks (#133) 2017-09-13 14:41:19 -05:00
William Pitcock 048deb95b3 headers: add C++ wrappers (closes #136) 2017-09-13 14:35:28 -05:00
William Pitcock b5da424ef7 stdinc: drop _GNU_SOURCE definition 2017-09-13 14:20:47 -05:00
William Pitcock 75074635bb meson: install pkg.m4 to aclocal dir (closes #124) 2017-09-08 20:52:02 -05:00
William Pitcock 906fef8449 libpkgconf: fragment: mark some inline match tables as const 2017-09-08 20:09:12 -05:00
William Pitcock b7839f6bb7 libpkgconf: pkg: pkgconf_pkg_scan_dir: remove unnecessary static declaration of filebuf 2017-09-08 20:06:52 -05:00
William Pitcock 2681c29edd libpkgconf: pkg: determine_prefix: use caller-provided buffer for reentrancy 2017-09-08 20:04:49 -05:00
William Pitcock adae70445a libpkgconf: pkg: get_default_pkgconfig_path: use caller-supplied buffer for reentrancy 2017-09-08 20:01:34 -05:00
William Pitcock 1252d7ae6a libpkgconf: dependency: make dependency_to_str() private, use a caller-supplied buffer for reentrancy 2017-09-08 19:53:52 -05:00
William Pitcock 615bab3df9 libpkgconf: pkg: pkgconf_pkg_report_graph_error(): move already_sent_notice to pkgconf_client_t 2017-09-08 19:48:31 -05:00
William Pitcock b0ef708efc libpkgconf: pkg: pkg_get_parent_dir(): use caller-supplied buffer instead of a static buffer to make reentrant 2017-09-08 19:23:04 -05:00
William Pitcock b9dac13ef3 libpkgconf: tuple: pkgconf_tuple_parse(): remove unnecessary static buffer declaration 2017-09-08 19:17:38 -05:00
William Pitcock 47ce9765a8 libpkgconf: define SIZE_FMT_SPECIFIER on POSIX and Windows platforms and use it in place of %zu
The MSVCRT runtime as used on Windows does not support %zu, but instead recommends %Iu.  As we want
to remain portable to other runtimes, even on Windows, we do not use %Iu, but instead expand it logically
to either %lu or %llu depending on if it's _WIN32 or _WIN64 headers.

On POSIX, we assume C99 support is available and always use %zu, as pkgconf has never supported anything
earlier than C99 officially.

Closes #125.
2017-09-08 18:46:48 -05:00
William Pitcock a6d6b88d14 libpkgconf: path: fix logic error in path relocation case when matching against a list (closes #129) 2017-09-08 18:27:04 -05:00
William Pitcock 9505213c1b tuple: check expanded variables to see if a sysroot has been duplicated, and if so, remove the prepended sysroot.
This allows compatibility between legacy pkg-config's broken sysroot implementation and pkgconf's sysroot
implementation, by removing any prepended sysroot paths and preferencing the variable expansion sysroot path
we typically do instead.

Closes github #123.
2017-07-16 17:37:41 -05:00
William Pitcock 95b4930aac tests: add test for github #123 2017-07-16 17:33:42 -05:00
Maxin B. John 74666bff38 stdinc.h: fix build with mingw (#122)
Fixes this build error with mingw:
...
| compilation terminated.
| In file included from ../pkgconf-1.3.7/libpkgconf/libpkgconf.h:19:0,
| from ../pkgconf-1.3.7/libpkgconf/audit.c:16:
| ../pkgconf-1.3.7/libpkgconf/stdinc.h:36:12: fatal error: BaseTsd.h: No
such file or directory
| # include <BaseTsd.h>

Signed-off-by: Maxin B. John <maxin.john@intel.com>
2017-07-16 13:21:45 -05:00
William Pitcock 38cda5e584 autotools: replace PKGCONFIGDIR with PKG_DEFAULT_PATH 2017-06-24 12:45:44 -05:00
William Pitcock 3ae11b1b4d meson: add kyua integration for testsuite for now 2017-06-24 12:40:33 -05:00
William Pitcock a928ad75e6 meson: use join_paths() for kyua invocation 2017-06-20 16:20:30 -05:00
William Pitcock adc7f92874 meson: fix up SYSTEM_LIBDIR, SYSTEM_INCLUDEDIR, PKG_DEFAULT_PATH 2017-06-20 01:23:55 -05:00
William Pitcock bca827649d meson: add some support for pulling in testsuite 2017-06-20 01:11:36 -05:00
William Pitcock 186545fc4f meson: fix check for HAVE_CYGWIN_CONV_PATH 2017-06-20 00:29:03 -05:00
William Pitcock d40a90761a meson: clean up a few things 2017-06-19 19:11:42 -05:00
Jussi Pakkanen 40fd995060 Experiment to build with Meson (#119)
* Initial Meson build definitions.

* Install man page and headers.
2017-06-19 19:03:00 -05:00
William Pitcock b77fbbb025 libpkgconf: add win-dirent.h to file list too 2017-06-16 21:26:23 -05:00
William Pitcock 01a2c2375c fix autotools build 2017-06-16 21:25:44 -05:00
William Pitcock b45cf98fb7 start NEWS for 1.4 series 2017-06-16 21:19:20 -05:00
William Pitcock 037d15210c add some notes on building for Windows 2017-06-16 21:15:23 -05:00
William Pitcock 864b14e5b9 Merge branch 'cmakeify' of github.com:dankegel/pkgconf 2017-06-16 21:06:01 -05:00
William Pitcock 03f7841065 libpkgconf: pkg: windows can use either \ or / as directory separators
ref #118
2017-06-16 15:27:23 -05:00
William Pitcock d45e850130 Revert "pkg: use pkgconf_pkg_t.realname instead of pkgconf_pkg_t.id for injecting the default provides entry"
This reverts commit 0c22b4d8a1.
2017-06-16 13:03:51 -05:00
William Pitcock 0c22b4d8a1 pkg: use pkgconf_pkg_t.realname instead of pkgconf_pkg_t.id for injecting the default provides entry
This issue was noticed while porting pkgconf to Windows.

ref #118
2017-06-16 11:49:54 -05:00
Dan Kegel 794aa5016a Tidy up a bit. 2017-06-05 20:54:57 -07:00
Dan Kegel 0ba391bc6f Miscelaneous tweaks for Visual C in Cygwin compatibility 2017-06-05 17:41:13 -07:00
Dan Kegel ededaa6415 cmake: add missing configure variables, install headers and .pc file, use simpler line to invoke kyua, tweak build location of dll for ease of testing 2017-06-05 17:40:10 -07:00
Dan Kegel 4ba2bac538 Don't depend on libtool magic to control which symbols are exported from shared libraries 2017-06-05 14:00:02 -07:00
Dan Kegel 2e80d72a6f cmake: remove DOS line endings from tests 2017-06-05 13:58:03 -07:00
Dan Kegel 9258874ee1 cmake: use right soversion for libpkgconf 2017-06-05 10:23:56 -07:00
Dan Kegel 9131496d64 getopt_long.c: placate visual c by adding a few explicit typecasts 2017-06-05 10:23:30 -07:00
Dan Kegel 347539ca87 cmake: ignore more visual C warnings, don't feed DOS line endings to atf 2017-06-05 10:22:38 -07:00
Dan Kegel 26d9a81c9c install_deps.sh: first cut at cygwin support 2017-06-05 07:26:00 -07:00
Dan Kegel 8b4a4b831b First draft of cmake install rules 2017-06-04 19:32:08 -07:00
Dan Kegel 4d7b4d7c8e Minimal tweaks to compile with Visual C 2015 2017-06-04 19:19:55 -07:00
Dan Kegel 35d0f63daf win-dirent.h: MIT-licensed port of dirent to win32 from https://github.com/tronkko/dirent 2017-06-04 19:19:01 -07:00
Dan Kegel d4098f95c3 Document how to install test dependencies on ubuntu
Just a tip to save other devs a few minutes.
2017-06-04 19:17:44 -07:00
Dan Kegel 251f747343 First draft of cmake port 2017-06-04 17:44:37 -07:00
William Pitcock f7e9d61f4d pkgconf 1.3.7. 2017-05-19 23:47:51 -05:00
William Pitcock 4a508b4fd9 tests: regress: add regression test for malformed package testcase 2017-05-19 23:43:47 -05:00
William Pitcock d280060ed7 libpkgconf: pkg: add additional validation rules in post-parse phase 2017-05-19 23:37:57 -05:00
William Pitcock 0262b8251d libpkgconf: pkgconf_pkg_find(): correctly handle failure from pkgconf_pkg_new_from_file() 2017-05-19 23:33:49 -05:00
William Pitcock cf3c50ca78 libpkgconf: pkg: pkgconf_try_specific_path() and pkgconf_pkg_new_from_file() require a mutable client to release resources when encountering invalid packages 2017-05-19 23:21:58 -05:00
William Pitcock 4b104d49df pkgconf 1.3.6. 2017-05-09 19:43:08 -05:00
William Pitcock f55e989f0a update NEWS for 1.3.6 2017-05-09 19:42:48 -05:00
William Pitcock 3c7f82a7fb fragment: also protect -nostdinc, -nostdlibinc, -nobuiltininc 2017-05-09 19:38:57 -05:00
William Pitcock 74eb74a3ef fragment: handle -include similarly to -isystem and -idirafter 2017-05-09 19:37:23 -05:00
William Pitcock 9fde4be1f3 fragment: also protect -ansi, -std=, -stdlib=, -pedantic, -trigraphs, -Wa, and -Wp fragments 2017-05-09 19:34:39 -05:00
William Pitcock c7a8e1e3b8 fragment: give -Wl fragments the same protection as -pthread 2017-05-09 19:30:02 -05:00
William Pitcock 90d52e6c2a fragment: add -pthread as a special fragment 2017-05-05 01:40:57 -05:00
William Pitcock ce47fa8d89 tests: add reduced version of freebsd gtk+-3.0 crappy output situation as a testcase 2017-05-05 01:40:09 -05:00
William Pitcock 5940ad6412 pkgconf 1.3.5. 2017-04-04 16:20:57 -05:00
William Pitcock a504e67097 update NEWS for 1.3.5. 2017-04-04 16:20:44 -05:00
William Pitcock 30c35b7096 main: re-enable --variable pkg-config bug emulation because downstreams take advantage of it 2017-04-01 18:34:59 -05:00
William Pitcock a7f8a809c1 pkgconf 1.3.4. 2017-03-29 18:02:59 -05:00
William Pitcock 1da1b83ba5 update NEWS for 1.3.4 2017-03-29 18:02:43 -05:00
William Pitcock 6e643aa432 libpkgconf: hopefully the last necessary tweak to quoting... 2017-03-29 18:00:57 -05:00
William Pitcock 77ca17b6ff tests: back out go-style test, just verify the output because shells are terrible 2017-03-29 18:00:10 -05:00
William Pitcock f5ce5fd755 testsuite: add a parser test from Go (redhat #1437101) 2017-03-29 16:58:04 -05:00
William Pitcock 849261cf58 pkgconf 1.3.3. 2017-03-27 12:12:27 -05:00
William Pitcock fbbf5316fb update NEWS for 1.3.3. 2017-03-27 11:01:41 -05:00
William Pitcock 6fcb5ba5c0 testsuite: update test with PKG_CONFIG_MAXIMUM_TRAVERSE_DEPTH=1 env var 2017-03-27 01:03:24 -05:00
William Pitcock 2f4a1eb4e0 main: implement a different solution for dependency generators, too many broken configure scripts still :/ 2017-03-27 00:56:23 -05:00
William Pitcock 92ce179d23 pkgconf 1.3.2. 2017-03-24 01:03:11 -05:00
William Pitcock 7a121725be update NEWS for 1.3.2 2017-03-24 01:03:11 -05:00
William Pitcock acac1f8ed3 libpkgconf: pkg: show iteration depth when traversing 2017-03-24 00:59:53 -05:00
William Pitcock be184cba1d main: further fix up handling of single-package query flags 2017-03-24 00:59:26 -05:00
William Pitcock 05e257e678 pkgconf 1.3.1. 2017-03-24 00:19:55 -05:00
William Pitcock 85375d9fda update NEWS for 1.3.1 2017-03-24 00:19:27 -05:00
William Pitcock 541de8bd59 main: handle query selectors that are only usable for single packages correctly
--print-requires, --print-requires-private, --print-provides, --modversion, --print-variable and --print-variables
are inquiring information about a package, not about a dependency graph.

in such cases, we should not try to solve the problem set to determine if it is satisfiable, as any invocation
of these commands are trying to inquire about a specific package.  instead, just solve the problem set for a single
level (so we can load the package itself) which is far more useful behaviour when scanning .pc files for their
dependency metadata.

as an aside, this allows us to successfully scan .pc files which are otherwise unsatisfiable.
2017-03-24 00:13:30 -05:00
William Pitcock 9d05871d32 testsuite: check to see if --print-requires incorrectly invokes the dependency resolver 2017-03-24 00:13:14 -05:00
Dag-Erling Smørgrav 95b683c864 Update pkg.m4 to latest upstream version (0.29.1) (#116)
* Update comments to reduce diffs against latest upstream (0.29.1).

* Clean up our comments to match the new upstream style.

* Update pkg.m4 to latest upstream version (0.29.1).
2017-03-07 11:11:01 -06:00
William Pitcock ced4ec00c8 main: add some very primitive --print-errors support for --atleast-version and friends (closes #115) 2017-02-27 10:09:16 -06:00
William Pitcock 81011ba522 main: implement --short-errors (#115) 2017-02-27 09:54:02 -06:00
William Pitcock ec42e4f8d2 add NEWS for 1.3.0 2017-02-25 16:17:42 -06:00
William Pitcock d40aac3626 pkgconf 1.3.0. 2017-02-25 16:09:00 -06:00
William Pitcock 40fe6c5f53 configure: stop checking for realpath(3) 2017-02-25 16:08:13 -06:00
William Pitcock 7a5da837f2 docs: we no longer use realpath(3) 2017-02-25 16:07:51 -06:00
William Pitcock 794443a92a dependency: break API to add tracepoints to dependency list building 2017-02-25 16:04:55 -06:00
William Pitcock e0c9569f14 fragment: add tracepoints 2017-02-25 15:53:50 -06:00
William Pitcock 3744a84380 testsuite: parser testcase output changes a little because we escape when running as pkgconf CLI now 2017-02-25 15:33:41 -06:00
William Pitcock 44b676b782 main: chase API changes 2017-02-25 15:33:34 -06:00
William Pitcock 01fe5743ea fragment: add new option to control escaping shell arguments 2017-02-25 15:32:49 -06:00
William Pitcock ae42261c3f argvsplit: refactor splitting state machine 2017-02-25 15:04:08 -06:00
William Pitcock a3fa9732b3 testsuite: add testsuite cases for inverse quoting situations 2017-02-25 13:57:38 -06:00
John Hein 9b255d465c If PKG_CONFIG_PATH element is a sym link, use the link destination instead of the link for inode caching checks.
See issue 112 & issue 110 (https://github.com/pkgconf/pkgconf/issues)
2017-02-24 23:26:41 -06:00
John Hein 76b8e0a26b Normalize the path to remove duplicate / separators rather than possibly altering the path with realpath(3). Leave sym links as is in path components. This is also cheaper than realpath(3), and works on platforms that don't have realpath(3).
Note: if this is accepted, the check for realpath in configure.ac
can be removed, and some docs that mention realpath will be adjusted.
2017-02-24 23:26:10 -06:00
William Pitcock d558e30ab3 libpkgconf: argvsplit: quoting logic was simplified too much 2017-02-07 10:25:38 -06:00
William Pitcock 2dcd749601 main: remove whitespace added for compatibility with older pkg-config (closes #113) 2017-02-07 10:11:12 -06:00
William Pitcock b0c36cd128 libpkgconf: pkg: add some trace points 2017-02-04 20:35:49 -06:00
William Pitcock 16ecf82fd7 libpkgconf: client: bring up the default trace handler as early as possible 2017-02-04 20:09:21 -06:00
William Pitcock f7f0bfc460 libpkgconf: cache: add trace points 2017-02-04 20:01:41 -06:00
William Pitcock 2b6bb5a252 libpkgconf: client: add trace points 2017-02-04 19:50:58 -06:00
William Pitcock d20efff495 libpkgconf: overhaul pkgconf_trace() a little 2017-02-04 19:49:59 -06:00
William Pitcock 9fc170bda5 main: add early tracing support via PKG_CONFIG_EARLY_TRACE environment variable 2017-02-04 19:49:20 -06:00
William Pitcock 276e36fe28 main: install a trace handler if --debug is specified 2017-02-04 19:09:31 -06:00
William Pitcock c1d7f1a620 main: install a warning handler if --validate is requested 2017-02-04 19:06:58 -06:00
William Pitcock 820ad83edd libpkgconf: pkg: add variable whitespace warnings back, using pkgconf_warn(). 2017-02-04 19:05:28 -06:00
William Pitcock bef293080a libpkgconf: client: add trace logging too 2017-02-04 18:57:21 -06:00
William Pitcock a6755cd792 libpkgconf: client: add pkgconf_warn() 2017-02-04 18:46:53 -06:00
William Pitcock eb98a1e6c3 libpkgconf: client: clean up various aspects of error/warn handlers 2017-02-04 18:46:33 -06:00
William Pitcock d884dc46a2 libpkgconf: client: ensure error/warn handlers always have a sane default instead of actually NULL 2017-02-04 18:41:16 -06:00
William Pitcock c0b6a62c40 libpkgconf: client: add warn handler and getter/setter for both warn handler and error handler 2017-02-04 18:37:58 -06:00
William Pitcock badcd8d2ef pkgconf manpage: add PKG_CONFIG_DONT_RELOCATE_PATHS and --dont-relocate-paths 2017-02-03 13:29:49 -06:00
William Pitcock 647c0255aa libpkgconf: add PKGCONF_PKG_PKGF_DONT_RELOCATE_PATHS (#110)
main: add PKG_CONFIG_DONT_RELOCATE_PATHS environment variable and --dont-relocate-paths option to disable path relocation
2017-02-03 13:17:21 -06:00
William Pitcock 02ad6d1ab9 testsuite: add regression test for #111 2017-02-03 12:58:11 -06:00
William Pitcock fe40bc33f8 libpkgconf: argvsplit: do not consider ' or " to be equivalent to \ (#111) 2017-02-03 12:53:50 -06:00
William Pitcock 42d65b14c7 libpkgconf: client: add INCLUDE environment to the cflags path filter list on windows 2017-02-01 13:03:06 -06:00
William Pitcock 1aa1a43321 Revert "libpkgconf: pkg: warn when encountering trailing whitespace"
This reverts commit 2fa4fd09d0.
2017-01-26 13:38:57 -06:00
William Pitcock 2fa4fd09d0 libpkgconf: pkg: warn when encountering trailing whitespace 2017-01-26 13:32:07 -06:00
William Pitcock da34d940ea main: print warnings/errors when using --validate 2017-01-26 13:30:41 -06:00
William Pitcock ef1503b769 libpkgconf: strip trailing whitespace 2017-01-26 13:10:52 -06:00
William Pitcock 8b043a10ce testsuite: add tests for variable whitespace 2017-01-26 12:55:48 -06:00
William Pitcock 3204bfe96c configure: reenable dist-gzip 2017-01-25 17:07:10 -06:00
William Pitcock b06bbe75a4 libpkgconf: path: only enable cygwin path relocation backend for msys (ref #72) 2017-01-23 23:17:26 -06:00
William Pitcock e36a92dc9e getopt: add some padding to EMSG to avoid overrun 2017-01-23 13:01:59 -06:00
William Pitcock e87595b3d1 libpkgconf: use a better check instead of stat() for pkg-config file iteration, avoiding a TOCTOU race condition identified by coverity 2017-01-23 12:42:13 -06:00
William Pitcock eacc5463c3 travis: more fixing 2017-01-23 12:30:53 -06:00
William Pitcock 79584539b4 travis: further cleanups 2017-01-23 11:44:06 -06:00
William Pitcock f20dcb6769 travis: cleanups 2017-01-23 11:42:45 -06:00
William Pitcock eae4fb9a27 travis: add coverity bits 2017-01-23 11:36:35 -06:00
William Pitcock db65f935f0 libpkgconf: iter: check list->tail for null, not list->head 2017-01-23 00:24:13 -06:00
William Pitcock 0927ecf1c6 Revert "Actually fix the regression introduced in 7b39c38"
This reverts commit 5e5c418837.
2017-01-22 23:29:59 -06:00
William Pitcock 5554be4986 libpkgconf: queue: chase API change (mark static root virtual packages as static) 2017-01-22 23:28:51 -06:00
William Pitcock 0c01a81299 libpkgconf: split virtual/static package state (this is API/ABI safe, static packages are always treated as virtual when it comes to mutation) 2017-01-22 23:26:01 -06:00
William Pitcock 987cf94a7f tests: add a regression test for #108 2017-01-22 23:21:51 -06:00
William Pitcock 9ece7cd487 libpkgconf: move sys/stat.h inclusion out of stdinc.h to the only other consumer of sys/stat.h 2017-01-22 23:09:38 -06:00
William Pitcock e5f3dac6e7 libpkgconf: pkg: handle error value from stat(2). 2017-01-22 23:07:39 -06:00
William Pitcock 67796a1d86 libpkgconf: argvsplit: make escape handling more explicit 2017-01-22 23:04:01 -06:00
Igor Gnatenko 5db87c9685 remove dead assignments (#109)
* remove dead assignments

None of them are used.

Signed-off-by: Igor Gnatenko <ignatenko@redhat.com>

* The address of an object "&pkgconf_pkg_provides_vermatch_rules[pkgdep->compare]" is never null

Signed-off-by: Igor Gnatenko <ignatenko@redhat.com>

* Overrunning array pkgconf_pkg_comparator_names at element index 7

Signed-off-by: Igor Gnatenko <ignatenko@redhat.com>
2017-01-22 11:31:34 -08:00
Baptiste Daroussin 5e5c418837 Actually fix the regression introduced in 7b39c38 2017-01-22 11:26:43 +01:00
Baptiste Daroussin 17be554a21 Revert "Fix regression introduced in 7b39c38"
This reverts commit 7d89f659ff.
2017-01-22 11:23:24 +01:00
Baptiste Daroussin 7d89f659ff Fix regression introduced in 7b39c38
now pkgconf --variable=pc_path pkg-config works
2017-01-22 10:44:09 +01:00
William Pitcock f540ece217 pkgconf 1.2.0. 2017-01-20 18:45:41 -06:00
William Pitcock 81b4b9ce87 pkgconf manpage: document --define-prefix, --dont-define-prefix, --prefix-variable and --relocate switches 2017-01-20 18:20:41 -06:00
William Pitcock 18a58836c9 main: add --dont-define-prefix for feature parity with pkg-config 2017-01-20 18:09:56 -06:00
William Pitcock e5dda3301c update NEWS 2017-01-20 18:07:00 -06:00
William Pitcock 7237b811e7 add support for making paths relocatable (closes #103) 2017-01-20 00:58:48 -06:00
William Pitcock bd6be71115 main: add support for --prefix-variable (ref #103) 2017-01-19 19:21:46 -06:00
William Pitcock ced4f00363 libpkgconf: client: add pkgconf_client_[get|set]_prefix_varname() 2017-01-19 19:16:00 -06:00
William Pitcock 13cf74c7a3 libpkgconf: kill flags from top-level fragment API (ref #105) 2017-01-19 18:23:25 -06:00
William Pitcock 7b39c38408 libpkgconf: pkg: clean up use of flags variable (ref #105) 2017-01-19 18:17:29 -06:00
William Pitcock 127fd037d4 libpkgconf: pkg: uncouple resolver flags from pkgconf_pkg_dir_list_build(). (ref #105) 2017-01-19 17:35:57 -06:00
William Pitcock 0ca6a16ce5 libpkgconf: queue: nuke flags parameters (ref #105) 2017-01-19 17:32:38 -06:00
William Pitcock 597c3c7faf libpkgconf: client: add pkgconf_client_t.flags and a get/set interface for it 2017-01-19 17:22:20 -06:00
William Pitcock 3c628084c5 main: kill global_traverse_flags (ref #105) 2017-01-19 17:16:20 -06:00
William Pitcock 1ee3c12f53 libpkgconf: path: use pkgconf_path_relocate() when matching paths 2017-01-19 10:43:23 -06:00
William Pitcock fa927fd379 libpkgconf: path: pkgconf_path_relocate(): implement realpath backend 2017-01-19 10:36:07 -06:00
William Pitcock 0315832285 doc: document pkgconf_path_relocate() 2017-01-19 10:31:40 -06:00
William Pitcock 4a3d3745e0 configure: check for realpath 2017-01-19 10:24:03 -06:00
William Pitcock 492d220d73 main: properly honour --keep-system-libs and --keep-system-cflags 2017-01-18 20:34:06 -06:00
William Pitcock 6c2bc94cc3 tests: regress: fix --keep-system-libs test, seems to have been broken for some years 2017-01-18 20:33:18 -06:00
William Pitcock 4f94090fe4 libpkgconf: fragment: make pkgconf_fragment_filter() accept userdata (closes #106) 2017-01-18 20:25:19 -06:00
William Pitcock bd386d20ac configure: start preparing for the tree to report as 1.2.x 2017-01-18 20:04:06 -06:00
William Pitcock d7bf55a194 main: add --with-path CLI option (closes #104) 2017-01-18 11:36:52 -06:00
William Pitcock b428eeaacf libpkgconf: remove legacy check to ensure pkgconf_pkg_dir_list_build() is only called once.
this is not necessary anymore because:

- we do path entry deduplication
- it is possible that we want to prime the dir list with some user-specified paths prior to building it
2017-01-18 11:29:24 -06:00
William Pitcock 147fd80750 path: relocate system libdir/includedir if appropriate 2017-01-13 20:12:38 -06:00
William Pitcock cb1dc71e23 fragment: simplify pkgconf_fragment_copy_munged() 2017-01-13 20:10:02 -06:00
William Pitcock 87a5a1f0cc path: when stubbing pkgconf_path_relocate(), suppress unused variables warnings 2017-01-13 20:08:22 -06:00
William Pitcock 27c3710521 fragment: when munging, do a path relocation too 2017-01-13 20:06:48 -06:00
William Pitcock 1369f558c6 path: add new pkgconf_path_relocate() API which is a stub when path
relocation is not needed
2017-01-13 20:05:21 -06:00
William Pitcock 7f6a185977 fragment: only munge if sysroot_dir is actually set
on cygwin/msys2, it is possible for munging to be enabled for other types of munging (instead of sysroot)
2017-01-13 19:55:54 -06:00
William Pitcock 5b8e59f036 configure: check for cygwin_conv_path 2017-01-13 19:24:56 -06:00
William Pitcock 45819eaa6d windows: allow building libpkgconf as DLL 2017-01-13 19:09:15 -06:00
William Pitcock 4ba414f74a fragment: handle oddball fragments like -framework more accurately 2017-01-07 15:04:34 -06:00
Baptiste Daroussin 3b3f1dc76e Fix gcc warnings 2017-01-07 17:57:37 +01:00
Baptiste Daroussin 2e855972dc inode cache: ensure we never use an unitilized struct stat 2017-01-07 17:52:44 +01:00
William Pitcock e9b4c2c789 manpage: document --path option 2017-01-07 03:02:10 -06:00
William Pitcock 02fcc31e00 main: add --path option to show the exact filename of each .pc file used 2017-01-07 02:58:39 -06:00
Graham Ollis 9c426b6f2c do not filter non-existent directories if filter is off 2016-12-31 14:10:59 -06:00
118 changed files with 9743 additions and 2193 deletions

3
.github/FUNDING.yml vendored Normal file
View File

@ -0,0 +1,3 @@
github: kaniini
patreon: kaniini
liberapay: kaniini

153
.github/workflows/test.yml vendored Normal file
View File

@ -0,0 +1,153 @@
name: test
on:
push:
pull_request:
jobs:
msys2:
runs-on: windows-latest
strategy:
fail-fast: false
matrix:
include: [
{ msystem: MINGW64, arch: x86_64},
{ msystem: MINGW32, arch: i686}
]
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: setup-msys2
uses: msys2/setup-msys2@v2
with:
msystem: ${{ matrix.msystem }}
update: true
install: >-
mingw-w64-${{ matrix.arch }}-meson
mingw-w64-${{ matrix.arch }}-ninja
mingw-w64-${{ matrix.arch }}-gcc
- name: Build
shell: msys2 {0}
run: |
# the code assumes msvc style printf atm
export CFLAGS=-D__USE_MINGW_ANSI_STDIO=0
meson -Dtests=disabled _build
meson compile -C _build
debian-meson:
runs-on: ubuntu-latest
container:
image: debian:testing
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Update system and add dependencies
run: |
apt-get update
apt-get install -y kyua atf-sh build-essential meson
- name: Build
run: |
meson _build -Dwerror=true
meson compile -C _build
- name: Run tests
run: |
meson test -v -C _build
debian-meson-asan:
runs-on: ubuntu-latest
container:
image: debian:testing
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Update system and add dependencies
run: |
apt-get update
apt-get install -y kyua atf-sh build-essential meson
- name: Build
run: |
meson _build -Db_sanitize=address
meson compile -C _build
- name: Run tests
run: |
meson test -v -C _build
env:
ASAN_OPTIONS: "exitcode=7"
debian-autotools:
runs-on: ubuntu-latest
container:
image: debian:testing
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Update system and add dependencies
run: |
apt-get update
apt-get install -y kyua atf-sh build-essential autoconf libtool
- name: Build
run: |
./autogen.sh
./configure
make -j9
- name: Run tests
run: |
make distcheck
alpine-meson:
runs-on: ubuntu-latest
container:
image: alpine
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Update system and add dependencies
run: |
apk update
apk add kyua atf build-base meson
- name: Build
run: |
meson _build -Dwerror=true
meson compile -C _build
- name: Run tests
run: |
meson test -v -C _build
alpine-autotools:
runs-on: ubuntu-latest
container:
image: alpine
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Update system and add dependencies
run: |
apk update
apk add kyua atf build-base autoconf automake libtool xz gzip
- name: Build
run: |
./autogen.sh
./configure
make -j9
- name: Run tests
run: |
make distcheck

49
.gitignore vendored
View File

@ -1,13 +1,19 @@
Makefile
Makefile.in
.dirstamp
stamp-h*
*.h.in~
*.o
*.og
*.op
*.lo
*.gcno
*.gcda
*.gcov
core
.gdb_history
.libs
.deps
*.exe
@ -16,8 +22,8 @@ core
*.orig
*.patch
*.rej
/tests/run.sh
# autoconf stuff
/aclocal.m4
/autom4te.cache/
/buildsys.mk
@ -26,8 +32,47 @@ core
/config.log
/config.status
/configure
/compile
/config.guess
/config.sub
/depcomp
/install-sh
/missing
# programs
/bomtool
/pkgconf
/pkgconf-gcov
/pkgconf-profile
Makefile
# libtool
/libtool
/ltmain.sh
/libpkgconf.la
/m4/libtool.m4
/m4/lt~obsolete.m4
/m4/ltoptions.m4
/m4/ltsugar.m4
/m4/ltversion.m4
# pkgconfig file
/libpkgconf.pc
# autoheader
/libpkgconf/config.h
/libpkgconf/config.h.in
# tests
/Kyuafile
/tests/Kyuafile
/tests/basic
/tests/builtins
/tests/conflicts
/tests/framework
/tests/parser
/tests/provides
/tests/regress
/tests/requires
/tests/sysroot
/tests/test_env.sh
/tests/version

1
.mailmap Normal file
View File

@ -0,0 +1 @@
Ariadne Conill <ariadne@dereferenced.org> <nenolod@dereferenced.org>

View File

@ -1,28 +0,0 @@
language: c
compiler:
- clang
- gcc
addons:
apt:
packages:
- liblua5.2-dev
sudo: required
before_install:
scripts/install_deps.sh
script:
- sh ./autogen.sh
- ./configure
- make distcheck
notifications:
email: false
irc:
channels:
- "irc.freenode.org#pkgconf"
on_success: change
on_failure: always

75
.woodpecker.yml Normal file
View File

@ -0,0 +1,75 @@
pipeline:
debian-meson:
image: debian:testing
commands:
- apt-get update
- apt-get install -y kyua atf-sh build-essential meson
- meson _build -Dwerror=true
- meson compile -C _build
- meson test -v -C _build
when:
matrix:
IMAGE: debian
BUILD: meson
debian-meson-asan:
image: debian:testing
environment:
- ASAN_OPTIONS="exitcode=7"
commands:
- apt-get update
- apt-get install -y kyua atf-sh build-essential meson
- meson _build -Db_sanitize=address
- meson compile -C _build
- meson test -v -C _build
when:
matrix:
IMAGE: debian
BUILD: meson
debian-autotools:
image: debian:testing
commands:
- apt-get update
- apt-get install -y kyua atf-sh build-essential autoconf libtool
- ./autogen.sh
- ./configure
- make -j
- make distcheck
when:
matrix:
IMAGE: debian
BUILD: autotools
alpine-meson:
image: alpine
commands:
- apk add -U --no-cache kyua atf build-base meson
- meson _build -Dwerror=true
- meson compile -C _build
- meson test -v -C _build
when:
matrix:
IMAGE: alpine
BUILD: meson
alpine-autotools:
image: alpine
commands:
- apk add -U --no-cache kyua atf build-base autoconf automake libtool xz gzip
- ./autogen.sh
- ./configure
- make -j
- make distcheck
when:
matrix:
IMAGE: alpine
BUILD: autotools
matrix:
IMAGE:
- debian
- alpine
BUILD:
- meson
- autotools

43
AUTHORS
View File

@ -1,4 +1,41 @@
A. Wilcox <AWilcox@Wilcox-Tech.com>
Alexander Tsoy <alexander@tsoy.me>
Alexpux <alexey.pawlow@gmail.com>
Alon Bar-Lev <alon.barlev@gmail.com>
Alyx <alyx@malkier.net>
Ariadne Conill <ariadne@dereferenced.org>
Baptiste Daroussin <bapt@FreeBSD.org>
Jeff Horelick <jdhore@gentoo.org>
Michał Górny <mgorny@gentoo.org
William Pitcock <nenolod@atheme.org>
Baptiste Daroussin <bapt@gandi.net>
Bryan Drewery <bryan@shatow.net>
Dag-Erling Smørgrav <des@des.no>
Dan Kegel <dank@kegel.com>
Dan Kegel <dank@oblong.com>
Dan Nicholson <dbn.lists@gmail.com>
David Michael <fedora.dm0@gmail.com>
Emil Renner Berthing <esmil@mailme.dk>
Fabian Groffen <grobian@gentoo.org>
Graham Ollis <plicease@cpan.org>
Gregor Richards <Richards@codu.org>
Ignacio Casal Quinteiro <qignacio@amazon.com>
Igor Gnatenko <ignatenko@redhat.com>
Issam Maghni <concatime@users.noreply.github.com>
JD Horelick <jdhore1@gmail.com>
Jason Dusek <jason.dusek@gmail.com>
Javier Viguera <javier.viguera@digi.com>
Jean-Sébastien Pédron <dumbbell@FreeBSD.org>
John Hein <jhgit@users.github.com>
Jussi Pakkanen <jpakkane@gmail.com>
Leorize <alaviss@users.noreply.github.com>
Luca Barbato <lu_zero@gentoo.org>
Marcin Wojdyr <wojdyr@gmail.com>
Maxin B. John <maxinbjohn@users.noreply.github.com>
Michał Górny <mgorny@gentoo.org>
Mike Frysinger <vapier@gentoo.org>
Seungha Yang <seungha.yang@navercorp.com>
TingPing <tingping@tingping.se>
Tobias Kortkamp <t6@users.noreply.github.com>
Tony Theodore <tonyt@logyst.com>
Volker Braun <vbraun.name@gmail.com>
Yu Kobayashi <yukoba@accelart.jp>
orbea <orbea@fredslev.dk>
✈ Graham ✈ <plicease@cpan.org>

27
CODE_OF_CONDUCT.md Normal file
View File

@ -0,0 +1,27 @@
# pkgconf Code of Conduct
We invite and encourage everybody to express their opinions on relevant
topics. All participants should at all times feel at ease to do so without
fearing any form of attack, reprisal or harassment. We ask everybody to be
respectful and considerate towards each other, especially when attempting
to provide constructive criticism.
To foster tolerance, respect and hospitality in our community, we agree not
to engage in discriminatory, disparaging or offensive speech or actions,
including as to (but not limited to) gender, sexuality, race, nationality,
religion or profession. We are a community of many different nationalities
and backgrounds, and we cherish our strength in diversity.
## Reporting incidents
Please report any incidents which may be perceived as violations to
`ariadne+conduct@dereferenced.org`. Incidents will be investigated and,
if warranted, acted upon.
## Credits
This CoC is derived from the [FSFE Code of Conduct][fsfe-coc].
[fsfe-coc]: https://fsfe.org/about/codeofconduct.en.html

View File

@ -1,4 +1,4 @@
Copyright (c) 2011, 2012, 2013, 2014, 2015, 2016, 2017
Copyright (c) 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018
pkgconf authors (see AUTHORS file in source directory).
Permission to use, copy, modify, and/or distribute this software for any

View File

@ -4,21 +4,31 @@ datadir = @datadir@
includedir = @includedir@
system_includedir = @SYSTEM_INCLUDEDIR@
system_libdir = @SYSTEM_LIBDIR@
pkg_default_dir = @PKGCONFIGDIR@
pkg_default_dir = @PKG_DEFAULT_PATH@
personality_dir = @PERSONALITY_PATH@
pkgconfigdir = $(libdir)/pkgconfig
nodist_pkgconfig_DATA = libpkgconf.pc
AM_CFLAGS = -Wall -Wextra -Wformat=2 -std=gnu99 -DPKG_DEFAULT_PATH=\"$(pkg_default_dir)\" -DSYSTEM_INCLUDEDIR=\"$(system_includedir)\" -DSYSTEM_LIBDIR=\"$(system_libdir)\"
AM_CFLAGS = -DPERSONALITY_PATH=\"$(personality_dir)\" -DPKG_DEFAULT_PATH=\"$(pkg_default_dir)\" -DSYSTEM_INCLUDEDIR=\"$(system_includedir)\" -DSYSTEM_LIBDIR=\"$(system_libdir)\"
bin_PROGRAMS = pkgconf
bin_PROGRAMS = pkgconf bomtool
lib_LTLIBRARIES = libpkgconf.la
EXTRA_DIST = pkg.m4 \
meson.build \
meson_options.txt \
libpkgconf/meson.build \
libpkgconf/config.h.meson \
libpkgconf/win-dirent.h \
tests/lib-relocatable/lib/pkgconfig/foo.pc \
tests/lib1/argv-parse-2.pc \
tests/lib1/billion-laughs.pc \
tests/lib1/dos-lineendings.pc \
tests/lib1/paren-quoting.pc \
tests/lib1/argv-parse-3.pc \
tests/lib1/foo.pc \
tests/lib1/foobar.pc \
tests/lib1/unavailable-provider.pc \
tests/lib1/prefix-foo1.pc \
tests/lib1/argv-parse.pc \
tests/lib1/framework-1.pc \
@ -40,6 +50,7 @@ EXTRA_DIST = pkg.m4 \
tests/lib1/sysroot-dir.pc \
tests/lib1/circular-2.pc \
tests/lib1/multiline.pc \
tests/lib1/multiline-bogus.pc \
tests/lib1/tilde-quoting.pc \
tests/lib1/circular-3.pc \
tests/lib1/no-trailing-newline.pc \
@ -53,6 +64,7 @@ EXTRA_DIST = pkg.m4 \
tests/lib3/bar.pc \
tests/lib1/conflicts.pc \
tests/lib1/omg-uninstalled.pc \
tests/lib1/omg-sysroot-uninstalled.pc \
tests/lib1/isystem.pc \
tests/lib1/idirafter.pc \
tests/lib1/idirafter-ordering.pc \
@ -63,7 +75,41 @@ EXTRA_DIST = pkg.m4 \
tests/lib1/provides-request-simple.pc \
tests/lib1/flag-order-1.pc \
tests/lib1/flag-order-3.pc \
tests/test_env.sh \
tests/lib1/variable-whitespace.pc \
tests/lib1/fragment-collision.pc \
tests/lib1/fragment-collision-intermediary.pc \
tests/lib1/fragment-collision-1.pc \
tests/lib1/fragment-collision-2.pc \
tests/lib1/fragment-comment.pc \
tests/lib1/fragment-escaping-1.pc \
tests/lib1/fragment-escaping-2.pc \
tests/lib1/fragment-escaping-3.pc \
tests/lib1/fragment-quoting.pc \
tests/lib1/fragment-quoting-2.pc \
tests/lib1/fragment-quoting-3.pc \
tests/lib1/fragment-quoting-5.pc \
tests/lib1/fragment-quoting-7.pc \
tests/lib1/malformed-1.pc \
tests/lib1/malformed-quoting.pc \
tests/lib1/malformed-version.pc \
tests/lib1/metapackage.pc \
tests/lib1/metapackage-1.pc \
tests/lib1/metapackage-2.pc \
tests/lib1/metapackage-3.pc \
tests/lib1/explicit-sysroot.pc \
tests/lib1/escaped-backslash.pc \
tests/lib1/cflags-internal.pc \
tests/lib1/requires-internal.pc \
tests/lib1/requires-internal-2.pc \
tests/lib1/requires-internal-missing.pc \
tests/lib1/requires-internal-collision.pc \
tests/lib1/tuple-quoting.pc \
tests/lib1/empty-tuple.pc \
tests/lib1/orphaned-requires-private.pc \
tests/lib1/sysroot-dir-2.pc \
tests/lib1/sysroot-dir-3.pc \
tests/lib1/sysroot-dir-4.pc \
tests/lib1/sysroot-dir-5.pc \
$(test_scripts) \
doc/conf.py \
doc/extract.py \
@ -80,7 +126,7 @@ EXTRA_DIST = pkg.m4 \
doc/libpkgconf-queue.rst \
doc/libpkgconf-tuple.rst
test_scripts= \
test_scripts= tests/meson.build \
tests/basic.sh \
tests/builtins.sh \
tests/conflicts.sh \
@ -92,11 +138,12 @@ test_scripts= \
tests/sysroot.sh \
tests/version.sh
check_SCRIPTS= $(test_scripts:.sh=)
test_sh = $(filter-out tests/meson.build, $(test_scripts))
check_SCRIPTS = $(test_sh:.sh=)
SUFFIXES= .sh
nobase_pkginclude_HEADERS = libpkgconf/bsdstubs.h libpkgconf/iter.h libpkgconf/libpkgconf.h libpkgconf/stdinc.h
nobase_pkginclude_HEADERS = libpkgconf/bsdstubs.h libpkgconf/iter.h libpkgconf/libpkgconf.h libpkgconf/stdinc.h libpkgconf/libpkgconf-api.h
libpkgconf_la_SOURCES = \
libpkgconf/audit.c \
libpkgconf/cache.c \
@ -109,14 +156,32 @@ libpkgconf_la_SOURCES = \
libpkgconf/tuple.c \
libpkgconf/dependency.c \
libpkgconf/queue.c \
libpkgconf/path.c
libpkgconf_la_LDFLAGS = -version-info 2:0:0 -export-symbols-regex '^pkgconf_'
libpkgconf/path.c \
libpkgconf/personality.c \
libpkgconf/parser.c
libpkgconf_la_LDFLAGS = -no-undefined -version-info 5:0:0 -export-symbols-regex '^pkgconf_'
dist_man_MANS = \
man/pkgconf.1 \
man/pkg.m4.7 \
man/pc.5 \
man/pkgconf-personality.5
dist_man_MANS = pkgconf.1
pkgconf_LDADD = libpkgconf.la
pkgconf_SOURCES = main.c getopt_long.c
pkgconf_CPPFLAGS = -Ilibpkgconf
noinst_HEADERS = getopt_long.h
pkgconf_SOURCES = \
cli/main.c \
cli/getopt_long.c \
cli/renderer-msvc.c
pkgconf_CPPFLAGS = -I$(top_srcdir)/libpkgconf -I$(top_srcdir)/cli
noinst_HEADERS = \
cli/getopt_long.h \
cli/renderer-msvc.h
bomtool_LDADD = libpkgconf.la
bomtool_SOURCES = \
cli/bomtool/main.c \
cli/getopt_long.c
bomtool_CPPFLAGS = -I$(top_srcdir)/libpkgconf -I$(top_srcdir)/cli -I$(top_srcdir)/cli/bomtool
dist_doc_DATA = README.md AUTHORS

77
Makefile.lite Normal file
View File

@ -0,0 +1,77 @@
# Copyright (c) 2019 William Pitcock <nenolod@dereferenced.org>
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# This software is provided 'as is' and without any warranty, express or
# implied. In no event shall the authors be liable for any damages arising
# from the use of this software.
# pkgconf-lite is a staticly-linked version of pkgconf that does not include
# all features, notably it does not include cross-compile support and MSVC
# support. It does not include the libpkgconf library.
SRCS = \
libpkgconf/argvsplit.c \
libpkgconf/audit.c \
libpkgconf/bsdstubs.c \
libpkgconf/cache.c \
libpkgconf/client.c \
libpkgconf/dependency.c \
libpkgconf/fileio.c \
libpkgconf/fragment.c \
libpkgconf/parser.c \
libpkgconf/path.c \
libpkgconf/personality.c \
libpkgconf/pkg.c \
libpkgconf/queue.c \
libpkgconf/tuple.c \
cli/getopt_long.c \
cli/main.c
OBJS = ${SRCS:.c=.o}
CFLAGS = ${STATIC} -DPKGCONF_LITE -I. -Ilibpkgconf -Icli -DSYSTEM_LIBDIR=\"${SYSTEM_LIBDIR}\" -DSYSTEM_INCLUDEDIR=\"${SYSTEM_INCLUDEDIR}\" -DPKG_DEFAULT_PATH=\"${PKG_DEFAULT_PATH}\"
STATIC =
STRIP = strip
all: pkgconf-lite
libpkgconf/config.h:
@echo '#define PACKAGE_NAME "pkgconf-lite"' >> $@
@echo '#define PACKAGE_BUGREPORT "https://git.dereferenced.org/pkgconf/pkgconf/issues"' >> $@
@echo '#define PACKAGE_VERSION "2.2.0"' >> $@
@echo '#define PACKAGE PACKAGE_NAME " " PACKAGE_VERSION' >> $@
@echo '#define HAVE_STRLCPY' >> $@
@echo '#define HAVE_STRLCAT' >> $@
@echo '#define HAVE_STRNDUP' >> $@
pkgconf-lite: preflight libpkgconf/config.h ${OBJS}
${CC} ${STATIC} -o $@ ${OBJS}
${STRIP} $@
clean:
rm -f libpkgconf/config.h
rm -f ${OBJS}
rm -f pkgconf-lite
preflight: preflight-system-libdir preflight-system-includedir preflight-pkg-default-path
preflight-system-libdir:
@if test -z "${SYSTEM_LIBDIR}"; then \
echo "SYSTEM_LIBDIR not set."; \
exit 1; \
fi
preflight-system-includedir:
@if test -z "${SYSTEM_INCLUDEDIR}"; then \
echo "SYSTEM_INCLUDEDIR not set."; \
exit 1; \
fi
preflight-pkg-default-path:
@if test -z "${PKG_DEFAULT_PATH}"; then \
echo "PKG_DEFAULT_PATH not set."; \
exit 1; \
fi
.PHONY: preflight preflight-system-libdir preflight-system-includedir preflight-pkg-default-path clean

629
NEWS
View File

@ -1,6 +1,628 @@
Changes from previous version of pkgconf
========================================
Changes from 2.1.1 to 2.2.0:
----------------------------
* libpkgconf SOVERSION is now 5.
* Significant solver rework to flatten both requires and requires.private
dependencies in a single pass. Improves performance slightly and ensures
proper dependency order.
Patches by Kai Pastor.
* Improve `--digraph` output to reflect more of the solver's state in the
rendered dependency graph.
Patches by Kai Pastor.
* Do not reference the graph root by name when presenting error messages about
directly requested dependency nodes.
Patch by Kai Pastor.
Changes from 2.1.0 to 2.1.1:
----------------------------
* Documentation fixes from Sam James and Stefan Weil.
* Fix --modversion with constraints.
Patch by Kai Pastor.
* Reintroduce an optimization to the dependency graph walker which avoids
revisiting already visited nodes.
Patch by Yi Chou with some modifications.
* Add a regression test to check that the dependency flattener is working
as expected.
Patch by Kai Pastor.
Changes from 2.0.3 to 2.1.0:
----------------------------
* Do not flatten the solver solution into the original world used as
input to the solver.
Patches by Kai Pastor.
* Fix warnings with GCC 14 -Walloc-size.
Patch by Sam James.
* Add --solution to the pkgconf CLI to dump the solver state.
* Improve the --digraph output to clarify cancelled edges in a given
solution.
* Demote requires dependencies to requires.private when a parent
dependency is pulled in via requires.private.
* Trim trailing whitespace when processing package arguments.
Patch by Colin Gillespie.
* Avoid strncmp() in --modversion version comparison.
Patch by Colin Gillespie.
* Update autoconf compile flag checking macro.
Patch by Peter Kokot.
* Add system default path configuration to Meson.
Patch by L. E. Segovia.
* Fix order of PKG_CONFIG_LIBDIR and PKG_CONFIG_PATH element processing.
Changes from 2.0.2 to 2.0.3:
----------------------------
* Fix some edge-cases with the new `--modversion` implementation
and add additional regression tests.
Patch by Colin Gillespie.
* Fix some format specifiers to use PRIu64 in debug tracing.
Changes from 2.0.1 to 2.0.2:
----------------------------
* Fix long-standing bug where package identifiers for "uninstalled"
packages incorrectly included the "-uninstalled" suffix.
This was exposed by the recent change to `--modversion` in 2.0.1.
Changes from 2.0.0 to 2.0.1:
----------------------------
* The behavior of --modversion was largely reverted back to the traditional
pkg-config behavior, but still operates on a solved dependency graph.
The order of --modversion output is based on the dependency resolution
queue which is passed to the solver, which itself generally maps to the
order of the constrants provided on the command line.
* A new flag, --verbose, has been added. When used with `--modversion`, it
is possible to disambiguate which version belongs to which module:
% pkgconf --modversion --verbose foo bar
foo: 1.2.3
bar: 1.3
Changes from 1.9.5 to 2.0.0:
----------------------------
* When flattening the dependency graph, retain the latest seen edges
rather than the earliest.
* Fix a long-standing bug where the dependency resolution queue was
evaluated in reverse. This bug masked the aforementioned dependency
flattening bug in many cases.
* Fix handling of --with-path, which was appending paths to the search
list rather than prepending them as intended.
* Error when --modversion is requested with more than one package, as
the output is ambiguous.
Changes from 1.9.4 to 1.9.5:
----------------------------
* Fix incorrect assumptions involving the use of ctype(3) functions.
Patch by Taylor R Campbell.
* Fix detection of provided functions on autoconf.
Patches by Harmen Stoppels.
* Fix deletion of tests/meson.build by the autoconf build system.
Patch by h30032433.
* Fix quoting rules in argvsplit.c.
Patch by huyubiao.
* Update libpkgconf documentation and documentation building scripts.
Patches by Andrew Shadura.
* Enforce maximum package count correctly for --modversion.
Changes from 1.9.3 to 1.9.4:
----------------------------
* Fix a buffer overflow vulnerability involving very large variable expansions.
CVE-2023-24056
* Fix a bunch of minor regressions with the solver.
* Create separate solutions for `--cflags` and `--libs` when `--static` is not
used.
* Remove final trailing whitespace in pkgconf_fragment_render_buf().
* Revert broken pkg.m4 change involving querying module versions in
PKG_CHECK_MODULES.
* Fix handling of tildes in version strings.
* Various C99 formatting string fixes involving SIZE_FMT_SPECIFIER.
Changes from 1.9.2 to 1.9.3:
----------------------------
* Fix a bunch of minor code issues pointed out using Clang static analyzer.
* New API: pkgconf_solution_free(), which frees a compiled solution graph.
* Fix behavior when overriding global variables with `--define-variable`.
Changes from 1.9.1 to 1.9.2:
----------------------------
* Do not try to break dependency cycles across dependency lists. This causes
the solved graph to sometimes miss required dependency nodes because the
solver detected an incorrect dependency cycle.
* New API: pkgconf_queue_solve(), which replaces pkgconf_queue_apply().
pkgconf_queue_apply is now deprecated and should not be used in new code.
Changes from 1.9.0 to 1.9.1:
----------------------------
* Skip graph flattening and traversal for query types which only make sense
for a single pkg-config module.
The old solver walked these graphs with --maximum-traverse-depth=1 in
these cases, but this is no longer helpful because the graph is flattened
by the new solver.
Changes from 1.8.0 to 1.9.0:
----------------------------
* pkgconf 1.9.0 is the first testing release in the pkgconf 2.0 development
series. While it is believed to be suitable for production, there may be
bugs due to the overall redesign of the solver and other initiatives.
Additionally, a future release of pkgconf plans will have additional ABI
breaks for the libpkgconf library before the pkgconf 2.0 release is cut.
* There is now a new solver that is designed to provide higher performance
with complicated graphs, which works by flattening the dependency graph
into a smaller set of dependencies. This graph can then be evaluated
instead of the original dependency graph without having to visit every
edge in the graph.
NOTE: This solver, while providing significant performance improvements,
does so, at the cost of changed behavior for some edge cases (such as
circular dependencies).
* Bug fixes:
- Resolved several memory leaks with edge cases when using libpkgconf
directly.
- pkgconf CLI now consistently frees libpkgconf resources under all
circumstances.
- SYSROOT rules are no longer applied to `-uninstalled` packages by
default. Use `PKG_CONFIG_PKGCONF1_SYSROOT_RULES` for legacy behavior.
* A new `--license` selector has been added to the pkgconf CLI. This uses
SPDX expressions which can be set as the `License` field in `.pc` files.
See the `pc(5)` manpage for more information.
* The canonical location for pkgconf maintenance going forward is
<https://gitea.treehouse.systems/ariadne/pkgconf>. This is presently
mirrored to GitHub for user convenience, but that mirroring will
be terminated at some point (due to GitHub Copilot).
Changes from 1.7.4 to 1.8.0:
----------------------------
* This is the last planned maintenance branch. I see pkgconf as basically
a finished tool at this point, and very few people were ultimately interested
in libpkgconf. So, from here on out, it will just be bug fixes only and
very minor enhancements.
* Bug fixes:
- Improved path handling on Windows to conform to what the MSYS2
and Cygwin teams were already modifying pkgconf to do.
Patches by Christoph Reiter.
- Fix a minor memory leak relating to cross-personalities.
Patch by Stone Tickle.
- Fix static builds for Windows on Meson.
Patch by Alexander Neumann.
- Fix some edge cases with --redefine-prefix.
Patch by midipix.
- Do not prepend sysroot_dir if the .pc file does not exist in the
sysroot.
Patch by Sandro Mani.
- Do not perform path filtering on default system include and library
path lists. This fixes consistency with other mechanisms that modify
these path lists.
* Enhancements:
- Document the --validate option in the manpage.
Patch by orbea.
Changes from 1.7.3 to 1.7.4:
----------------------------
* Bug fixes:
- Fix null-dereference crash when pulling a malformed 'uninstalled'
.pc file into a dependency tree. Patch by Tobias Stöckmann.
- Fix truncation of comment characters when quoted.
- Fix handling of .pc module names in --list-all on Windows.
Patch by Ryan Scott.
- Handle platforms where realpath(3) requires a pre-allocated buffer.
Patch by Fabian Groffen.
- Fix version whitespace warning.
Patch by Christoph Reiter.
* Enhancements:
- Rewrite DOS paths on native Windows builds that don't use
Cygwin/MSYS.
- Add WantDefaultPure cross-compiler personality option.
- Prefer --static --pure linking on Windows.
- Add PKG_CONFIG_DONT_DEFINE_PREFIX environment variable.
Patch by Jeff Moguillansky.
- Many improvements when building pkgconf with Meson.
Patches by Christoph Reiter.
Changes from 1.7.2 to 1.7.3:
----------------------------
* Bug fixes:
- Fix a possible out of boundary write when evaluating dependencies.
Patch by Tobias Stöckmann.
- Fix escaping logic on Windows. Patch by Vincent Torri.
- Fix out of boundary reads and writes with a malformed fragment.
Patches by Tobias Stöckmann.
- Fix a possible out of boundary write when evaluating tuples.
Patch by Tobias Stöckmann.
Changes from 1.7.1 to 1.7.2:
----------------------------
* Bug fixes:
- Fix a windows-specific crash relating to path fixups.
Changes from 1.7.0 to 1.7.1:
----------------------------
* Bug fixes:
- Fix a possible out of boundary access in the parser for the
cross-compile database. Patch by Tobias Stöckmann.
- Missing files for building with Meson are now included in the
tarball. Patch by Neal Gompa.
- Fix calculation of package atoms on Windows with paths that
use both directory separator characters.
Changes from 1.6.3 to 1.7.0:
----------------------------
* Bug fixes:
- Fix a possible buffer overflow involving newline escaping.
Patch by Tobias Stöckmann.
- Fix an out of boundary access in the parser.
Patch by Tobias Stöckmann.
- Fix leakage of strcmp() result value in pkgconf_compare_version()
responses.
- Return the default personality if loading a cross-compile
personality file failed.
- Do not complain about newlines when validating package versions.
- Properly detect strndup() on Windows when building with Meson.
* Enhancements:
- A new --shared option and WantDefaultStatic cross-compile
configuration option have been added. This allows for toolchains
to specify that static linking should be used by default.
- Support for the PKG_CONFIG_MSVC_SYNTAX environment variable has
been added. Patch by Dan Kegel.
- Support for the PKGCONF_PKG_PKGF_DONT_MERGE_SPECIAL_FRAGMENTS
client flag which disables emulation of freedesktop.org pkg-config
fragment merging semantics has been added.
Patch by Karen Arutyunov.
Changes from 1.6.2 to 1.6.3:
----------------------------
* Bug fixes:
- Properly tokenize versions. Versions cannot logically contain
whitespace, as dependency-lists would not properly tokenize if
they could. A diagnostic is generated for malformed version
strings containing whitespace when --validate is used.
* Enhancements:
- CMake support has been dropped. Use Meson to build on Windows.
Changes from 1.6.1 to 1.6.2:
----------------------------
* Bug fixes:
- Fixed a memory leak when deduplicating paths.
- Fixed strndup-related build regression on Windows.
* Enhancements:
- Added pkgconf-lite variant. pkgconf-lite is a stripped down
variant of pkgconf that only includes pkg-config features.
- Added --modversion description to pkgconf(1) man page.
Changes from 1.6.0 to 1.6.1:
----------------------------
* Bug fixes:
- Fixed an issue where a personality may not be properly selected
due to argv[0] containing a full path.
- Fixed a regression where having an empty PKG_CONFIG_LIBDIR
environment variable would not eliminate the default search
paths.
- Use POSIX realpath(3) instead of readlink() for deduplicating the
search path. Use _fullpath() on Windows for the same purpose.
- The dequoting logic for tuples has been improved to ensure that
quotes *inside* a value remain quoted when necessary.
Changes from 1.5.4 to 1.6.0:
----------------------------
* Bug fixes:
- Fixed issue where packages which referenced missing packages in
Requires.private may have crashed due to memory corruption issues
in some circumstances.
- Fixed warnings reported by GCC 8 diagnostics.
* Enhancements:
- Add LIBPKGCONF_VERSION and LIBPKGCONF_VERSION_STR macros for
determining libpkgconf version.
- Add pkgconf_fragment_copy_list() to copy a fragment list to
another fragment list.
Changes from 1.5.3 to 1.5.4:
----------------------------
* Bug fixes:
- fix build on Windows with Meson
- fix edge cases for path canonicalization (especially on Windows)
Changes from 1.5.2 to 1.5.3:
----------------------------
* Security fixes:
- Fix edge cases involving dequoting zero-length tuples that can lead to a
buffer overflow under the right circumstances. Thanks to A. Wilcox for
reporting and supplying a patch. (MR 3)
Changes from 1.5.1 to 1.5.2:
----------------------------
* Bug fixes:
- Ensure environment variables override values learned from personality files
or built-in defaults.
* Documentation enhancements:
- Add pkgconf-personality(5) manpage documenting the personality file format.
Changes from 1.5.0 to 1.5.1:
----------------------------
* Bug fixes:
- fixed a crash with some invalid multi-line .pc files
Changes from 1.4.2 to 1.5.0:
---------------------------
* Administrative:
- The git repository has moved to <https://git.dereferenced.org/pkgconf/pkgconf>,
due to the acquisition of GitHub by Microsoft.
* Overall enhancements:
- pkgconf now supports the proposed Requires.internal pkg-config extension,
by merging it with the Requires.private list (there is no functional difference
between the two in our resolver implementation)
- Support for cross-compilation personalities have been added. To make use of this
functionality, create a file in the new personality.d directory that sits inside
the pkgconfig directory. The personality file format is described in
pc-personality(5). (github #166)
- Support for Haiku has been added, including interpretation of BELIBRARIES and
other toolchain specifics. (github #180)
- Testsuite support can be disabled when building with Meson. (github #175)
* Bug fixes:
- tuples are now appropriately dequoted when added by the parser (github #186).
* Various Windows enhancements:
- CMake supports building with GCC on Windows. (github #179)
- Prefix rewriting has been improved. (github #177)
- PKGCONF_API support has been implemented when building with Meson,
allowing Meson to be used to build pkgconf on Windows. (github #174)
* Documentation fixes:
- The manpages have been linted and fixed. (github #181, #182, #183)
- The description of pkgconf --exists has been corrected. (github #173)
Changes from 1.4.1 to 1.4.2:
----------------------------
* Bug fixes:
- ensure pkgconf_dependency_t nodes have a solution marked when satisfied
by an indirect provider (github #172)
Changes from 1.4.0 to 1.4.1:
----------------------------
* Bug fixes:
- revert some quoting changes because they don't work well with certain
GCC edge cases (github #168)
* Enhancements:
- add limited support for --cflags with --msvc-syntax
Changes from 1.3.7 to 1.4.0:
----------------------------
* Notable libpkgconf API changes:
- pkgconf_pkg_t.requires has been renamed to pkgconf_pkg_t.required for
C++20 compatibility.
* Enhancements:
- pkgconf and libpkgconf has been ported to Windows as native binaries.
- improved compatibility with freedesktop.org pkg-config's ${pc_sysrootdir}
usage pattern.
- do not mention PKG_CONFIG_SKIP_CONFLICTS environmental variable when
simplified errors are requested, as with PKG_CONFIG_PATH.
- the dependency solver now stores solutions to dependency graph elements
it visits, allowing for the dependency graph to be incrementally solved.
this improves dependency solving time by an order of magnitude in most
cases.
- new --env option allows for exporting cflags/libs fragments as export
variables
- new support for building pkgconf with CMake and Meson
- improved compiler warning flag detection on autoconf and CMake
- removed PKGCONF_BUFSIZE allocations from the stack where possible
- allow for customizing the way fragment lists are rendered using a callback API
- new support for --msvc-syntax output using the new fragment rendering callbacks
- fragments are now quoted according to POSIX literal rules
- new variables on the pkg-config builtin:
- ${pc_system_includedirs}: the system includedir search path known by pkgconf
- ${pc_system_libdirs}: the system libdir search path known by pkgconf
- new manpages:
- pc(5) describing pkgconf's interpretation of pkg-config .pc files
- pkg.m4(7) describing the autotools macros bundled with pkgconf
* Bug fixes:
- fix pkgconf_pkg_t.id generation on native Windows where either \ or / are usable
as path separator.
- add missing --modversion to --help output
- do not evaluate module paths for modules that are not actually on disk
- ensure we work on a zeroed buffer prior to calling realpath(2) with it
- fix path deduplication edge case when cache-inodes feature is unavailable
- fix path rewriting regression with PKG_CONFIG_SYSROOT_DIR when
PKG_CONFIG_SYSROOT_DIR is set to /
- fix crash in edge case where a .pc file has misquoting in a fragment list.
- fix logic edge case when comparing relocated paths
Changes from 1.3.6 to 1.3.7:
----------------------------
* Enhancements:
- improved diagnostics for malformed packages.
* Bug fixes:
- reject packages which contain incomplete metadata in post-parse phase.
Changes from 1.3.5 to 1.3.6:
----------------------------
* Enhancements:
- add many cflags to the protected set: -Wa, -Wl, -Wp, -ansi, -std=, -stdlib=,
-pedantic, -pthread, -trigraphs, -nostdinc, -nostdlibinc, -nobuiltininc.
* Bug fixes:
- handle -include cflag fragments properly.
Changes from 1.3.4 to 1.3.5:
----------------------------
* Bug fixes:
- fix --variable output for compatibility some broken configure scripts when they
request the same variable from multiple packages
Changes from 1.3.3 to 1.3.4:
----------------------------
* Bug fixes:
- fix a quoting issue exposed by the Go testsuite
Changes from 1.3.2 to 1.3.3:
----------------------------
* Bug fixes:
- back out disabling the dependency resolver for single-package queries, it caused
too many regressions.
* Enhancements:
- allow explicitly disabling the dependency resolver via new environment variable,
PKG_CONFIG_MINIMUM_TRAVERSE_DEPTH=1. while pkgconf could already do this using
--minimum-traverse-depth=1, other pkg-config implementations do not have this
option, so adding an environment variable allows to make better use of this
feature (other implementations won't error due to unknown option this way)
Changes from 1.3.1 to 1.3.2:
----------------------------
* Bug fixes:
- rewrite handling of --modversion, --print-variables and --variable to not require
the dependency resolver
- ensure we disable the dependency resolver in all cases where it is a single-package
query (1.3.1 did not go far enough)
Changes from 1.3.0 to 1.3.1:
----------------------------
* Features:
- implement --short-errors
* Bug fixes:
- only consider a single package at a time with --print-requires, --print-requires-private,
--print-provides, --modversion, --print-variable and --print-variables
* Enhancements:
- synchronized latest freedesktop.org changes to pkg.m4
- improve error reporting with legacy --atleast-version and similar flags.
Changes from 1.2.0 to 1.3.0:
----------------------------
* Features:
- pkgconf --debug now provides a facility for tracing most relevant libpkgconf operations
- libpkgconf: add warn and trace handlers for warnings
- replace realpath() with faster, lighter weight path normalization function (github #112)
- pkgconf CLI now emulates pkg-config quoting rules precisely, while allowing direct access
to the actual fragments via libpkgconf
* Bug fixes:
- pkg: properly separate static and virtual packages so they are not inappropriately
optimized out of the dependency graph (github #108)
- argvsplit: do not consider ' and " to have similar rules to escape sequences (github #111)
- pkg: strip trailing whitespace when parsing .pc files
* Enhancements:
- argvsplit basically rewritten from scratch
- many code fixes spotted by coverity
- add PKG_CONFIG_DONT_RELOCATE_PATHS and --dont-relocate-paths environment variables to
disable path relocation feature if needed
- remove extra whitespace that was present for compatibility with older pkg-config releases
(github #113)
Changes from 1.1.0 to 1.2.0:
----------------------------
* Features:
- new --path option lists the .pc files which provided the requested dependencies
- new path relocation API: pkgconf_path_relocate(), which wraps functions such as
realpath() and cygwin_conv_path().
- new --with-path option adds a path to the search list
- new --define-prefix and --dont-define-prefix features enable automatic prefix
detection for relocatable SDKs. this is mostly useful on windows.
* Bug fixes:
- fragments: fix even more edge cases involving token concatenation
- path lists: don't attempt to collect path inodes if the filter is disabled
- path lists: explicitly avoid uninitialised data for the path inode cache
- client: properly handle --keep-system-cflags and --keep-system-libs
* Enhancements:
- windows: build libpkgconf as a DLL
- fragments: only munge fragments if sysroot_dir is actually set
- overall API: resolver flags have been moved to being a client-object setting
instead of used for every function invocation
Changes from 1.0.1 to 1.1.0:
----------------------------
@ -19,17 +641,18 @@ Changes from 1.0.1 to 1.1.0:
- filter duplicate PKG_CONFIG_PATH (and other) entries by inode
* Bug fixes:
- fragments: fix another edge case involving empty tokens being concatenated onto previous tokens (#99)
- fragments: fix another edge case involving empty tokens being concatenated onto previous tokens
(github #99)
- libpkgconf: remove dependencies on config.h in public headers
Changes from 1.0.0 to 1.0.1:
----------------------------
* Enhancements:
- new stub implementation of --print-provides (#95)
- new stub implementation of --print-provides (github #95)
* Bug fixes:
- fragments: fix an edge case involving path-only fragments and PKG_CONFIG_SYSROOT_DIR (#94)
- fragments: fix an edge case involving path-only fragments and PKG_CONFIG_SYSROOT_DIR (github #94)
Changes from 0.9.12 to 1.0.0:
-----------------------------

View File

@ -1,11 +1,11 @@
# pkgconf [![Build Status](https://travis-ci.org/pkgconf/pkgconf.svg?branch=master)](https://travis-ci.org/pkgconf/pkgconf) [![Documentation Status](https://readthedocs.org/projects/pkgconf/badge/?version=latest)](http://pkgconf.readthedocs.io/en/latest/?badge=latest)
# pkgconf [![test](https://github.com/pkgconf/pkgconf/actions/workflows/test.yml/badge.svg)](https://github.com/pkgconf/pkgconf/actions/workflows/test.yml)
`pkgconf` is a program which helps to configure compiler and linker flags for
development frameworks. It is similar to pkg-config from freedesktop.org.
development libraries. It is similar to pkg-config from freedesktop.org.
`libpkgconf` is a library which provides access to most of `pkgconf`'s functionality, to allow
other tooling such as compilers and IDEs to discover and use frameworks configured by
pkgconf.
`libpkgconf` is a library which provides access to most of `pkgconf`'s functionality,
to allow other tooling such as compilers and IDEs to discover and use libraries
configured by pkgconf.
## using `pkgconf` with autotools
@ -41,7 +41,7 @@ to improve this behaviour.
As of the 1.1 series, pkgconf also fully implements support for `Provides` rules,
while pkg-config does not. pkg-config only provides the `--print-provides` functionality
as a stub. There are other intentional implementation differences in pkgconf's dependency
resolver verses pkg-config's dependency resolver in terms of completeness and correctness,
resolver versus pkg-config's dependency resolver in terms of completeness and correctness,
such as, for example, how `Conflicts` rules are processed.
## linker flags optimization
@ -50,7 +50,7 @@ As previously mentioned, pkgconf makes optimizations to the linker flags in both
case of static and shared linking in order to avoid overlinking binaries and also
simplifies the `CFLAGS` and `LIBS` output of the pkgconf tool for improved readability.
This functionality depends on the pkg-config module properly declaring it's dependency
This functionality depends on the pkg-config module properly declaring its dependency
tree instead of using `Libs` and `Cflags` fields to directly link against other modules
which have pkg-config metadata files installed.
@ -60,6 +60,10 @@ Doing so is discouraged by the [freedesktop tutorial][fd-tut] anyway.
## compatibility with pkg-config
I really hate that I have to have this section, I like being a nice person, but we
unfortunately have to say this because otherwise we get passive-aggressive people who
try to argue with us about what pkg-config compatibility means.
We do not provide bug-level compatibility with pkg-config.
What that means is, if you feel that there is a legitimate regression versus pkg-config,
@ -67,7 +71,27 @@ do let us know, but also make sure that the .pc files are valid and follow the r
the [pkg-config tutorial][fd-tut], as most likely fixing them to follow the specified
rules will solve the problem.
## compiling `pkgconf` and `libpkgconf`
Additionally, **we do not consider pkgconf doing what you tell it to do, in cases for
which pkg-config fails to do so, to be a bug**.
If, for example, you use environment variables such as `PKG_CONFIG_SYSTEM_[INCLUDE|LIBRARY]_PATH`
and then find yourself surprised that `pkgconf` is stripping `-I` and `-L` flags relating
to those paths, it is not a `pkgconf` problem -- `pkgconf` is doing exactly what you told
it to do.
We will reject bugs like this, and if someone insists on fixing such a non-bug, this
constitutes a violation of our [Code of Conduct](CODE_OF_CONDUCT.md), which may be
addressed by banning from this repository.
## debug output
Please use only the stable interfaces to query pkg-config. Do not screen-scrape the
output from `--debug`: this is sent to `stderr` for a reason, it is not intended to be
scraped. The `--debug` output is **not** a stable interface, and should **never** be
depended on as a source of information. If you need a stable interface to query pkg-config
which is not covered, please get in touch.
## compiling `pkgconf` and `libpkgconf` on UNIX
pkgconf is basically compiled the same way any other autotools-based project is
compiled:
@ -88,21 +112,38 @@ flags like so:
$ make
$ sudo make install
## compiling `pkgconf` and `libpkgconf` with Meson (usually for Windows)
pkgconf is compiled using [Meson](https://mesonbuild.com) on Windows. In theory, you could also use
Meson to build on UNIX, but this is not recommended at this time as pkgconf is typically built
much earlier than Meson.
$ meson setup build -Dtests=disabled
$ meson compile -C build
$ meson install -C build
There are a few defines such as SYSTEM_LIBDIR, PKGCONFIGDIR and SYSTEM_INCLUDEDIR.
However, on Windows, the default PKGCONFIGDIR value is usually overridden at runtime based
on path relocation.
## pkg-config symlink
If you want pkgconf to be used when you invoke `pkg-config`, you should install a
symlink for this. We do not do this for you, as we believe it is better for vendors
to make this determination themselves.
$ ln -sf /usr/bin/pkgconf /usr/bin/pkg-config
$ ln -sf pkgconf /usr/bin/pkg-config
## release tarballs
Release tarballs are available at <https://distfiles.dereferenced.org/pkgconf/>.
Release tarballs are available at <https://distfiles.ariadne.space/pkgconf/>.
Please only use the tarballs from distfiles.ariadne.space.
Please do not use the github tarballs as they are not pristine (instead generated by github everytime
a download occurs).
## contacts
## reporting bugs
You can report bugs at <https://github.com/pkgconf/pkgconf/issues>.
See <https://github.com/pkgconf/pkgconf/issues>.
There is a mailing list at <https://lists.sr.ht/~kaniini/pkgconf>.
Also you can contact us at `#pkgconf` at `irc.freenode.net`.
You can contact us via IRC at `#pkgconf` at `irc.oftc.net`.

365
cli/bomtool/main.c Normal file
View File

@ -0,0 +1,365 @@
/*
* bomtool/main.c
* main() routine, printer functions
*
* Copyright (c) 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019
* pkgconf authors (see AUTHORS).
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* This software is provided 'as is' and without any warranty, express or
* implied. In no event shall the authors be liable for any damages arising
* from the use of this software.
*/
#include "libpkgconf/config.h"
#include <libpkgconf/stdinc.h>
#include <libpkgconf/libpkgconf.h>
#include "getopt_long.h"
#define PKG_VERSION (((uint64_t) 1) << 1)
#define PKG_ABOUT (((uint64_t) 1) << 2)
#define PKG_HELP (((uint64_t) 1) << 3)
static const char *spdx_version = "SPDX-2.2";
static const char *bom_license = "CC0-1.0";
static const char *document_ref = "SPDXRef-DOCUMENT";
static pkgconf_client_t pkg_client;
static uint64_t want_flags;
static size_t maximum_package_count = 0;
static int maximum_traverse_depth = 2000;
FILE *error_msgout = NULL;
static bool
error_handler(const char *msg, const pkgconf_client_t *client, void *data)
{
(void) client;
(void) data;
fprintf(error_msgout, "%s", msg);
return true;
}
static const char *
sbom_spdx_identity(pkgconf_pkg_t *pkg)
{
static char buf[PKGCONF_ITEM_SIZE];
snprintf(buf, sizeof buf, "%sC64%s", pkg->id, pkg->version);
return buf;
}
static const char *
sbom_name(pkgconf_pkg_t *world)
{
static char buf[PKGCONF_BUFSIZE];
pkgconf_node_t *node;
pkgconf_strlcpy(buf, "SBOM-SPDX", sizeof buf);
PKGCONF_FOREACH_LIST_ENTRY(world->required.head, node)
{
pkgconf_dependency_t *dep = node->data;
pkgconf_pkg_t *match = dep->match;
if (!dep->match)
continue;
pkgconf_strlcat(buf, "-", sizeof buf);
pkgconf_strlcat(buf, sbom_spdx_identity(match), sizeof buf);
}
return buf;
}
static void
write_sbom_header(pkgconf_client_t *client, pkgconf_pkg_t *world)
{
(void) client;
(void) world;
printf("SPDXVersion: %s\n", spdx_version);
printf("DataLicense: %s\n", bom_license);
printf("SPDXID: %s\n", document_ref);
printf("DocumentName: %s\n", sbom_name(world));
printf("DocumentNamespace: https://spdx.org/spdxdocs/bomtool-%s\n", PACKAGE_VERSION);
printf("Creator: Tool: bomtool %s\n", PACKAGE_VERSION);
printf("\n\n");
}
static const char *
sbom_identity(pkgconf_pkg_t *pkg)
{
static char buf[PKGCONF_ITEM_SIZE];
snprintf(buf, sizeof buf, "%s@%s", pkg->id, pkg->version);
return buf;
}
static void
write_sbom_package(pkgconf_client_t *client, pkgconf_pkg_t *pkg, void *unused)
{
(void) client;
(void) unused;
if (pkg->flags & PKGCONF_PKG_PROPF_VIRTUAL)
return;
printf("##### Package: %s\n\n", sbom_identity(pkg));
printf("PackageName: %s\n", sbom_identity(pkg));
printf("SPDXID: SPDXRef-Package-%s\n", sbom_spdx_identity(pkg));
printf("PackageVersion: %s\n", pkg->version);
printf("PackageDownloadLocation: NOASSERTION\n");
printf("PackageVerificationCode: NOASSERTION\n");
/* XXX: What about projects? */
if (pkg->maintainer != NULL)
printf("PackageSupplier: Person: %s\n", pkg->maintainer);
if (pkg->url != NULL)
printf("PackageHomePage: %s\n", pkg->url);
printf("PackageLicenseDeclared: %s\n", pkg->license != NULL ? pkg->license : "NOASSERTION");
if (pkg->copyright != NULL)
printf("PackageCopyrightText: <text>%s</text>\n", pkg->copyright);
if (pkg->description != NULL)
printf("PackageSummary: <text>%s</text>\n", pkg->description);
printf("\n\n");
}
static void
write_sbom_relationships(pkgconf_client_t *client, pkgconf_pkg_t *pkg, void *unused)
{
(void) client;
(void) unused;
char baseref[PKGCONF_ITEM_SIZE];
pkgconf_node_t *node;
if (pkg->flags & PKGCONF_PKG_PROPF_VIRTUAL)
return;
snprintf(baseref, sizeof baseref, "SPDXRef-Package-%sC64%s", pkg->id, pkg->version);
PKGCONF_FOREACH_LIST_ENTRY(pkg->required.head, node)
{
pkgconf_dependency_t *dep = node->data;
pkgconf_pkg_t *match = dep->match;
if (!dep->match)
continue;
printf("Relationship: %s DEPENDS_ON SPDXRef-Package-%s\n", baseref, sbom_spdx_identity(match));
printf("Relationship: SPDXRef-Package-%s DEPENDENCY_OF %s\n", sbom_spdx_identity(match), baseref);
}
PKGCONF_FOREACH_LIST_ENTRY(pkg->requires_private.head, node)
{
pkgconf_dependency_t *dep = node->data;
pkgconf_pkg_t *match = dep->match;
if (!dep->match)
continue;
printf("Relationship: %s DEPENDS_ON SPDXRef-Package-%s\n", baseref, sbom_spdx_identity(match));
printf("Relationship: SPDXRef-Package-%s DEV_DEPENDENCY_OF %s\n", sbom_spdx_identity(match), baseref);
}
if (pkg->required.head != NULL || pkg->requires_private.head != NULL)
printf("\n\n");
}
static bool
generate_sbom_from_world(pkgconf_client_t *client, pkgconf_pkg_t *world)
{
int eflag;
pkgconf_node_t *node;
write_sbom_header(client, world);
eflag = pkgconf_pkg_traverse(client, world, write_sbom_package, NULL, maximum_traverse_depth, 0);
if (eflag != PKGCONF_PKG_ERRF_OK)
return false;
eflag = pkgconf_pkg_traverse(client, world, write_sbom_relationships, NULL, maximum_traverse_depth, 0);
if (eflag != PKGCONF_PKG_ERRF_OK)
return false;
PKGCONF_FOREACH_LIST_ENTRY(world->required.head, node)
{
pkgconf_dependency_t *dep = node->data;
pkgconf_pkg_t *match = dep->match;
if (!dep->match)
continue;
printf("Relationship: %s DESCRIBES SPDXRef-Package-%s\n", document_ref, sbom_spdx_identity(match));
}
return true;
}
static int
version(void)
{
printf("bomtool %s\n", PACKAGE_VERSION);
return EXIT_SUCCESS;
}
static int
about(void)
{
printf("bomtool (%s %s)\n", PACKAGE_NAME, PACKAGE_VERSION);
printf("Copyright (c) 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021\n");
printf(" pkgconf authors (see AUTHORS in documentation directory).\n\n");
printf("Permission to use, copy, modify, and/or distribute this software for any\n");
printf("purpose with or without fee is hereby granted, provided that the above\n");
printf("copyright notice and this permission notice appear in all copies.\n\n");
printf("This software is provided 'as is' and without any warranty, express or\n");
printf("implied. In no event shall the authors be liable for any damages arising\n");
printf("from the use of this software.\n\n");
printf("Report bugs at <%s>.\n", PACKAGE_BUGREPORT);
return EXIT_SUCCESS;
}
static int
usage(void)
{
printf("usage: bomtool [--flags] [modules]\n");
printf("\nbasic options:\n\n");
printf(" --help this message\n");
printf(" --about print bomtool version and license to stdout\n");
printf(" --version print bomtool version to stdout\n");
return EXIT_SUCCESS;
}
int
main(int argc, char *argv[])
{
int ret = EXIT_SUCCESS;
pkgconf_list_t pkgq = PKGCONF_LIST_INITIALIZER;
unsigned int want_client_flags = PKGCONF_PKG_PKGF_SEARCH_PRIVATE;
pkgconf_cross_personality_t *personality = pkgconf_cross_personality_default();
pkgconf_pkg_t world = {
.id = "virtual:world",
.realname = "virtual world package",
.flags = PKGCONF_PKG_PROPF_STATIC | PKGCONF_PKG_PROPF_VIRTUAL,
};
error_msgout = stderr;
struct pkg_option options[] = {
{ "version", no_argument, &want_flags, PKG_VERSION, },
{ "about", no_argument, &want_flags, PKG_ABOUT, },
{ "help", no_argument, &want_flags, PKG_HELP, },
{ NULL, 0, NULL, 0 }
};
while ((ret = pkg_getopt_long_only(argc, argv, "", options, NULL)) != -1)
{
switch (ret)
{
case '?':
case ':':
return EXIT_FAILURE;
default:
break;
}
}
pkgconf_client_init(&pkg_client, error_handler, NULL, personality);
/* we have determined what features we want most likely. in some cases, we override later. */
pkgconf_client_set_flags(&pkg_client, want_client_flags);
/* at this point, want_client_flags should be set, so build the dir list */
pkgconf_client_dir_list_build(&pkg_client, personality);
if ((want_flags & PKG_ABOUT) == PKG_ABOUT)
return about();
if ((want_flags & PKG_VERSION) == PKG_VERSION)
return version();
if ((want_flags & PKG_HELP) == PKG_HELP)
return usage();
while (1)
{
const char *package = argv[pkg_optind];
if (package == NULL)
break;
/* check if there is a limit to the number of packages allowed to be included, if so and we have hit
* the limit, stop adding packages to the queue.
*/
if (maximum_package_count > 0 && pkgq.length > maximum_package_count)
break;
while (isspace((unsigned char)package[0]))
package++;
/* skip empty packages */
if (package[0] == '\0') {
pkg_optind++;
continue;
}
if (argv[pkg_optind + 1] == NULL || !PKGCONF_IS_OPERATOR_CHAR(*(argv[pkg_optind + 1])))
{
pkgconf_queue_push(&pkgq, package);
pkg_optind++;
}
else
{
char packagebuf[PKGCONF_BUFSIZE];
snprintf(packagebuf, sizeof packagebuf, "%s %s %s", package, argv[pkg_optind + 1], argv[pkg_optind + 2]);
pkg_optind += 3;
pkgconf_queue_push(&pkgq, packagebuf);
}
}
if (pkgq.head == NULL)
{
fprintf(stderr, "Please specify at least one package name on the command line.\n");
ret = EXIT_FAILURE;
goto out;
}
ret = EXIT_SUCCESS;
if (!pkgconf_queue_solve(&pkg_client, &pkgq, &world, maximum_traverse_depth))
{
ret = EXIT_FAILURE;
goto out;
}
if (!generate_sbom_from_world(&pkg_client, &world))
{
ret = EXIT_FAILURE;
goto out;
}
out:
pkgconf_solution_free(&pkg_client, &world);
pkgconf_queue_free(&pkgq);
pkgconf_cross_personality_deinit(personality);
pkgconf_client_deinit(&pkg_client);
return ret;
}

View File

@ -62,7 +62,9 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef _WIN32
#include <unistd.h>
#endif
#define PKGCONF_HACK_LOGICAL_OR_ALL_VALUES
@ -83,7 +85,8 @@ char *pkg_optarg; /* argument associated with option */
#define BADARG ((*options == ':') ? (int)':' : (int)'?')
#define INORDER (int)1
#define EMSG ""
/* add some padding to EMSG to avoid overrun */
#define EMSG "\0\0\0\0"
#ifdef GNU_COMPATIBLE
#define NO_PREFIX (-1)
@ -284,7 +287,7 @@ parse_long_options(char * const *nargv, const char *options,
* XXX: GNU sets pkg_optopt to val regardless of flag
*/
if (long_options[match].flag == NULL)
pkg_optopt = long_options[match].val;
pkg_optopt = (int)long_options[match].val;
else
pkg_optopt = 0;
#ifdef GNU_COMPATIBLE
@ -324,7 +327,7 @@ parse_long_options(char * const *nargv, const char *options,
* XXX: GNU sets pkg_optopt to val regardless of flag
*/
if (long_options[match].flag == NULL)
pkg_optopt = long_options[match].val;
pkg_optopt = (int)long_options[match].val;
else
pkg_optopt = 0;
--pkg_optind;
@ -357,7 +360,7 @@ parse_long_options(char * const *nargv, const char *options,
#endif
return (0);
} else
return (long_options[match].val);
return ((int)long_options[match].val);
}
/*

1599
cli/main.c Normal file

File diff suppressed because it is too large Load Diff

172
cli/renderer-msvc.c Normal file
View File

@ -0,0 +1,172 @@
/*
* renderer-msvc.c
* MSVC library syntax renderer
*
* Copyright (c) 2017 pkgconf authors (see AUTHORS).
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* This software is provided 'as is' and without any warranty, express or
* implied. In no event shall the authors be liable for any damages arising
* from the use of this software.
*/
#include <string.h>
#include <stdlib.h>
#include <libpkgconf/libpkgconf.h>
#include "renderer-msvc.h"
static inline bool
fragment_should_quote(const pkgconf_fragment_t *frag)
{
const char *src;
if (frag->data == NULL)
return false;
for (src = frag->data; *src; src++)
{
if (((*src < ' ') ||
(*src >= (' ' + (frag->merged ? 1 : 0)) && *src < '$') ||
(*src > '$' && *src < '(') ||
(*src > ')' && *src < '+') ||
(*src > ':' && *src < '=') ||
(*src > '=' && *src < '@') ||
(*src > 'Z' && *src < '^') ||
(*src == '`') ||
(*src > 'z' && *src < '~') ||
(*src > '~')))
return true;
}
return false;
}
static inline size_t
fragment_len(const pkgconf_fragment_t *frag)
{
size_t len = 1;
if (frag->type)
len += 2;
if (frag->data != NULL)
{
len += strlen(frag->data);
if (fragment_should_quote(frag))
len += 2;
}
return len;
}
static inline bool
allowed_fragment(const pkgconf_fragment_t *frag)
{
return !(!frag->type || frag->data == NULL || strchr("DILl", frag->type) == NULL);
}
static size_t
msvc_renderer_render_len(const pkgconf_list_t *list, bool escape)
{
(void) escape;
size_t out = 1; /* trailing nul */
pkgconf_node_t *node;
PKGCONF_FOREACH_LIST_ENTRY(list->head, node)
{
const pkgconf_fragment_t *frag = node->data;
if (!allowed_fragment(frag))
continue;
switch (frag->type)
{
case 'L':
out += 9; /* "/libpath:" */
break;
case 'l':
out += 4; /* ".lib" */
break;
default:
break;
}
out += fragment_len(frag);
}
return out;
}
static void
msvc_renderer_render_buf(const pkgconf_list_t *list, char *buf, size_t buflen, bool escape)
{
pkgconf_node_t *node;
char *bptr = buf;
memset(buf, 0, buflen);
PKGCONF_FOREACH_LIST_ENTRY(list->head, node)
{
const pkgconf_fragment_t *frag = node->data;
size_t buf_remaining = buflen - (bptr - buf);
size_t cnt;
if (!allowed_fragment(frag))
continue;
if (fragment_len(frag) > buf_remaining)
break;
switch(frag->type) {
case 'D':
case 'I':
*bptr++ = '/';
*bptr++ = frag->type;
break;
case 'L':
cnt = pkgconf_strlcpy(bptr, "/libpath:", buf_remaining);
bptr += cnt;
buf_remaining -= cnt;
break;
}
escape = fragment_should_quote(frag);
if (escape)
*bptr++ = '"';
cnt = pkgconf_strlcpy(bptr, frag->data, buf_remaining);
bptr += cnt;
buf_remaining -= cnt;
if (frag->type == 'l')
{
cnt = pkgconf_strlcpy(bptr, ".lib", buf_remaining);
bptr += cnt;
}
if (escape)
*bptr++ = '"';
*bptr++ = ' ';
}
*bptr = '\0';
}
static const pkgconf_fragment_render_ops_t msvc_renderer_ops = {
.render_len = msvc_renderer_render_len,
.render_buf = msvc_renderer_render_buf
};
const pkgconf_fragment_render_ops_t *
msvc_renderer_get(void)
{
return &msvc_renderer_ops;
}

23
cli/renderer-msvc.h Normal file
View File

@ -0,0 +1,23 @@
/*
* renderer-msvc.h
* MSVC library syntax renderer header
*
* Copyright (c) 2017 pkgconf authors (see AUTHORS).
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* This software is provided 'as is' and without any warranty, express or
* implied. In no event shall the authors be liable for any damages arising
* from the use of this software.
*/
#ifndef RENDERER_MSVC_H
#define RENDERER_MSVC_H
#include <libpkgconf/libpkgconf.h>
const pkgconf_fragment_render_ops_t *msvc_renderer_get(void);
#endif

View File

@ -11,31 +11,46 @@ dnl This software is provided 'as is' and without any warranty, express or
dnl implied. In no event shall the authors be liable for any damages arising
dnl from the use of this software.
AC_PREREQ([2.68])
AC_INIT([pkgconf], [1.1.0], [http://github.com/pkgconf/pkgconf/issues])
AC_CONFIG_SRCDIR([main.c])
AC_PREREQ([2.71])
AC_INIT([pkgconf],[2.2.0],[https://github.com/pkgconf/pkgconf/issues/new])
AC_CONFIG_SRCDIR([cli/main.c])
AC_CONFIG_MACRO_DIR([m4])
AX_CHECK_COMPILE_FLAG([-Wall], [CFLAGS="$CFLAGS -Wall"])
AX_CHECK_COMPILE_FLAG([-Wextra], [CFLAGS="$CFLAGS -Wextra"])
AX_CHECK_COMPILE_FLAG([-Wformat=2], [CFLAGS="$CFLAGS -Wformat=2"])
AX_CHECK_COMPILE_FLAG([-std=gnu99], [CFLAGS="$CFLAGS -std=gnu99"], [
AX_CHECK_COMPILE_FLAG([-std=c99], [CFLAGS="$CFLAGS -std=c99"])
])
AC_CONFIG_HEADERS([libpkgconf/config.h])
AC_CHECK_FUNCS([strlcpy strlcat strndup])
AC_CHECK_DECLS([strlcpy, strlcat, strndup], [], [], [[#include <string.h>]])
AC_CHECK_DECLS([reallocarray])
AC_CHECK_HEADERS([sys/stat.h])
AM_INIT_AUTOMAKE([foreign no-dist-gzip dist-xz subdir-objects])
AM_INIT_AUTOMAKE([foreign dist-xz subdir-objects])
AM_SILENT_RULES([yes])
LT_INIT
AC_SYS_LARGEFILE
AC_ARG_WITH([pkg-config-dir],[AC_HELP_STRING([--with-pkg-config-dir],[specify
the place where pc files will be found])],PKGCONFIGDIR="$withval",
PKGCONFIGDIR="${libdir}/pkgconfig:${datadir}/pkgconfig")
AC_ARG_WITH([personality-dir],[AS_HELP_STRING([--with-personality-dir],[specify
the place where cross-compile personality files will be found])],
PERSONALITY_PATH="$withval",
PERSONALITY_PATH="${datadir}/pkgconfig/personality.d:${sysconfdir}/pkgconfig/personality.d")
AC_SUBST([PKGCONFIGDIR])
AC_SUBST([PERSONALITY_PATH])
AC_ARG_WITH([system-libdir],[AC_HELP_STRING([--with-system-libdir],[specify the
AC_ARG_WITH([pkg-config-dir],[AS_HELP_STRING([--with-pkg-config-dir],[specify
the place where pc files will be found])],PKG_DEFAULT_PATH="$withval",
PKG_DEFAULT_PATH="${libdir}/pkgconfig:${datadir}/pkgconfig")
AC_SUBST([PKG_DEFAULT_PATH])
AC_ARG_WITH([system-libdir],[AS_HELP_STRING([--with-system-libdir],[specify the
system library directory (default LIBDIR)])],
SYSTEM_LIBDIR="$withval", SYSTEM_LIBDIR="${libdir}")
AC_SUBST([SYSTEM_LIBDIR])
AC_ARG_WITH([system-includedir],[AC_HELP_STRING([--with-system-includedir],[specify the
AC_ARG_WITH([system-includedir],[AS_HELP_STRING([--with-system-includedir],[specify the
system include directory (default INCLUDEDIR)])],
SYSTEM_INCLUDEDIR="$withval", SYSTEM_INCLUDEDIR="${includedir}")

View File

@ -70,21 +70,21 @@ def extract_comments(filename):
while True:
char = source_file.read(1)
if not char:
if state is 3 or state is 4:
if state == 3 or state == 4:
raise UnterminatedCommentError()
if state is 2:
if state == 2:
# Was in single line comment. Create comment.
comment = Comment(current_comment, line_counter, False)
comments.append(comment)
return comments
if state is 0:
if state == 0:
# Waiting for comment start character or beginning of
# string.
if char == '/':
state = 1
elif char == '"':
state = 5
elif state is 1:
elif state == 1:
# Found comment start character, classify next character and
# determine if single or multiline comment.
if char == '/':
@ -94,7 +94,7 @@ def extract_comments(filename):
state = 3
else:
state = 0
elif state is 2:
elif state == 2:
# In single line comment, read characters until EOL.
if char == '\n':
comment = Comment(current_comment, line_counter, False)
@ -103,14 +103,14 @@ def extract_comments(filename):
state = 0
else:
current_comment += char
elif state is 3:
elif state == 3:
# In multi-line comment, add characters until '*'
# encountered.
if char == '*':
state = 4
else:
current_comment += char
elif state is 4:
elif state == 4:
# In multi-line comment with asterisk found. Determine if
# comment is ending.
if char == '/':
@ -125,13 +125,13 @@ def extract_comments(filename):
if char != '*':
current_comment += char
state = 3
elif state is 5:
elif state == 5:
# In string literal, expect literal end or escape char.
if char == '"':
state = 0
elif char == '\\':
state = 6
elif state is 6:
elif state == 6:
# In string literal, escaping current char.
state = 5
if char == '\n':

View File

@ -9,21 +9,32 @@ in parallel.
Client objects are not thread safe, in other words, a client object should not be shared across
thread boundaries.
.. c:function:: void pkgconf_client_init(pkgconf_client_t *client, pkgconf_error_handler_func_t error_handler)
.. c:function:: void pkgconf_client_dir_list_build(pkgconf_client_t *client)
Bootstraps the package search paths. If the ``PKGCONF_PKG_PKGF_ENV_ONLY`` `flag` is set on the client,
then only the ``PKG_CONFIG_PATH`` environment variable will be used, otherwise both the
``PKG_CONFIG_PATH`` and ``PKG_CONFIG_LIBDIR`` environment variables will be used.
:param pkgconf_client_t* client: The pkgconf client object to bootstrap.
:return: nothing
.. c:function:: void pkgconf_client_init(pkgconf_client_t *client, pkgconf_error_handler_func_t error_handler, void *error_handler_data, const pkgconf_cross_personality_t *personality)
Initialise a pkgconf client object.
:param pkgconf_client_t* client: The client to initialise.
:param pkgconf_error_handler_func_t error_handler: An optional error handler to use for logging errors.
:param void* error_handler_data: user data passed to optional error handler
:param pkgconf_cross_personality_t* personality: the cross-compile personality to use for defaults
:return: nothing
.. c:function:: pkgconf_client_t* pkgconf_client_new(pkgconf_error_handler_func_t error_handler)
.. c:function:: pkgconf_client_t* pkgconf_client_new(pkgconf_error_handler_func_t error_handler, void *error_handler_data, const pkgconf_cross_personality_t *personality)
Allocate and initialise a pkgconf client object.
:param pkgconf_error_handler_func_t error_handler: An optional error handler to use for logging errors.
:param void* error_handler_data: user data passed to optional error handler
:param pkgconf_cross_personality_t* personality: cross-compile personality to use
:return: A pkgconf client object.
:rtype: pkgconf_client_t*
@ -78,3 +89,124 @@ thread boundaries.
:param pkgconf_client_t* client: The client object being modified.
:param char* buildroot_dir: The buildroot directory to set or NULL to unset.
:return: nothing
.. c:function:: bool pkgconf_error(const pkgconf_client_t *client, const char *format, ...)
Report an error to a client-registered error handler.
:param pkgconf_client_t* client: The pkgconf client object to report the error to.
:param char* format: A printf-style format string to use for formatting the error message.
:return: true if the error handler processed the message, else false.
:rtype: bool
.. c:function:: bool pkgconf_warn(const pkgconf_client_t *client, const char *format, ...)
Report an error to a client-registered warn handler.
:param pkgconf_client_t* client: The pkgconf client object to report the error to.
:param char* format: A printf-style format string to use for formatting the warning message.
:return: true if the warn handler processed the message, else false.
:rtype: bool
.. c:function:: bool pkgconf_trace(const pkgconf_client_t *client, const char *filename, size_t len, const char *funcname, const char *format, ...)
Report a message to a client-registered trace handler.
:param pkgconf_client_t* client: The pkgconf client object to report the trace message to.
:param char* filename: The file the function is in.
:param size_t lineno: The line number currently being executed.
:param char* funcname: The function name to use.
:param char* format: A printf-style format string to use for formatting the trace message.
:return: true if the trace handler processed the message, else false.
:rtype: bool
.. c:function:: bool pkgconf_default_error_handler(const char *msg, const pkgconf_client_t *client, const void *data)
The default pkgconf error handler.
:param char* msg: The error message to handle.
:param pkgconf_client_t* client: The client object the error originated from.
:param void* data: An opaque pointer to extra data associated with the client for error handling.
:return: true (the function does nothing to process the message)
:rtype: bool
.. c:function:: unsigned int pkgconf_client_get_flags(const pkgconf_client_t *client)
Retrieves resolver-specific flags associated with a client object.
:param pkgconf_client_t* client: The client object to retrieve the resolver-specific flags from.
:return: a bitfield of resolver-specific flags
:rtype: uint
.. c:function:: void pkgconf_client_set_flags(pkgconf_client_t *client, unsigned int flags)
Sets resolver-specific flags associated with a client object.
:param pkgconf_client_t* client: The client object to set the resolver-specific flags on.
:return: nothing
.. c:function:: const char *pkgconf_client_get_prefix_varname(const pkgconf_client_t *client)
Retrieves the name of the variable that should contain a module's prefix.
In some cases, it is necessary to override this variable to allow proper path relocation.
:param pkgconf_client_t* client: The client object to retrieve the prefix variable name from.
:return: the prefix variable name as a string
:rtype: const char *
.. c:function:: void pkgconf_client_set_prefix_varname(pkgconf_client_t *client, const char *prefix_varname)
Sets the name of the variable that should contain a module's prefix.
If the variable name is ``NULL``, then the default variable name (``prefix``) is used.
:param pkgconf_client_t* client: The client object to set the prefix variable name on.
:param char* prefix_varname: The prefix variable name to set.
:return: nothing
.. c:function:: pkgconf_client_get_warn_handler(const pkgconf_client_t *client)
Returns the warning handler if one is set, else ``NULL``.
:param pkgconf_client_t* client: The client object to get the warn handler from.
:return: a function pointer to the warn handler or ``NULL``
.. c:function:: pkgconf_client_set_warn_handler(pkgconf_client_t *client, pkgconf_error_handler_func_t warn_handler, void *warn_handler_data)
Sets a warn handler on a client object or uninstalls one if set to ``NULL``.
:param pkgconf_client_t* client: The client object to set the warn handler on.
:param pkgconf_error_handler_func_t warn_handler: The warn handler to set.
:param void* warn_handler_data: Optional data to associate with the warn handler.
:return: nothing
.. c:function:: pkgconf_client_get_error_handler(const pkgconf_client_t *client)
Returns the error handler if one is set, else ``NULL``.
:param pkgconf_client_t* client: The client object to get the error handler from.
:return: a function pointer to the error handler or ``NULL``
.. c:function:: pkgconf_client_set_error_handler(pkgconf_client_t *client, pkgconf_error_handler_func_t error_handler, void *error_handler_data)
Sets a warn handler on a client object or uninstalls one if set to ``NULL``.
:param pkgconf_client_t* client: The client object to set the error handler on.
:param pkgconf_error_handler_func_t error_handler: The error handler to set.
:param void* error_handler_data: Optional data to associate with the error handler.
:return: nothing
.. c:function:: pkgconf_client_get_trace_handler(const pkgconf_client_t *client)
Returns the error handler if one is set, else ``NULL``.
:param pkgconf_client_t* client: The client object to get the error handler from.
:return: a function pointer to the error handler or ``NULL``
.. c:function:: pkgconf_client_set_trace_handler(pkgconf_client_t *client, pkgconf_error_handler_func_t trace_handler, void *trace_handler_data)
Sets a warn handler on a client object or uninstalls one if set to ``NULL``.
:param pkgconf_client_t* client: The client object to set the error handler on.
:param pkgconf_error_handler_func_t trace_handler: The error handler to set.
:param void* trace_handler_data: Optional data to associate with the error handler.
:return: nothing

View File

@ -9,10 +9,12 @@ The `dependency` module provides support for building `dependency lists` (the ba
Adds a parsed dependency to a dependency list as a dependency node.
:param pkgconf_client_t* client: The client object that owns the package this dependency list belongs to.
:param pkgconf_list_t* list: The dependency list to add a dependency node to.
:param char* package: The package `atom` to set on the dependency node.
:param char* version: The package `version` to set on the dependency node.
:param pkgconf_pkg_comparator_t compare: The comparison operator to set on the dependency node.
:param uint flags: Any flags to attach to the dependency node.
:return: A dependency node.
:rtype: pkgconf_dependency_t *
@ -24,9 +26,32 @@ The `dependency` module provides support for building `dependency lists` (the ba
:param pkgconf_dependency_t* tail: The dependency node to add to the tail of the dependency list.
:return: nothing
.. c:function:: void pkgconf_dependency_free_one(pkgconf_dependency_t *dep)
Frees a dependency node.
:param pkgconf_dependency_t* dep: The dependency node to free.
:return: nothing
.. c:function:: pkgconf_dependency_t *pkgconf_dependency_ref(pkgconf_client_t *owner, pkgconf_dependency_t *dep)
Increases a dependency node's refcount.
:param pkgconf_client_t* owner: The client object which owns the memory of this dependency node.
:param pkgconf_dependency_t* dep: The dependency to increase the refcount of.
:return: the dependency node on success, else NULL
.. c:function:: void pkgconf_dependency_unref(pkgconf_client_t *owner, pkgconf_dependency_t *dep)
Decreases a dependency node's refcount and frees it if necessary.
:param pkgconf_client_t* owner: The client object which owns the memory of this dependency node.
:param pkgconf_dependency_t* dep: The dependency to decrease the refcount of.
:return: nothing
.. c:function:: void pkgconf_dependency_free(pkgconf_list_t *list)
Release a dependency list and it's child dependency nodes.
Release a dependency list and its child dependency nodes.
:param pkgconf_list_t* list: The dependency list to release.
:return: nothing
@ -37,8 +62,10 @@ The `dependency` module provides support for building `dependency lists` (the ba
Commas are counted as whitespace to allow for constructs such as ``@SUBSTVAR@, zlib`` being processed
into ``, zlib``.
:param pkgconf_client_t* client: The client object that owns the package this dependency list belongs to.
:param pkgconf_list_t* deplist_head: The dependency list to populate with dependency nodes.
:param char* depends: The dependency data to parse.
:param uint flags: Any flags to attach to the dependency nodes.
:return: nothing
.. c:function:: void pkgconf_dependency_parse(const pkgconf_client_t *client, pkgconf_pkg_t *pkg, pkgconf_list_t *deplist, const char *depends)
@ -51,4 +78,13 @@ The `dependency` module provides support for building `dependency lists` (the ba
:param pkgconf_pkg_t* pkg: The package object that owns this dependency list.
:param pkgconf_list_t* deplist: The dependency list to populate with dependency nodes.
:param char* depends: The dependency data to parse.
:param uint flags: Any flags to attach to the dependency nodes.
:return: nothing
.. c:function:: pkgconf_dependency_t *pkgconf_dependency_copy(pkgconf_client_t *client, const pkgconf_dependency_t *dep)
Copies a dependency node to a new one.
:param pkgconf_client_t* client: The client object that will own this dependency.
:param pkgconf_dependency_t* dep: The dependency node to copy.
:return: a pointer to a new dependency node, else NULL

View File

@ -6,13 +6,14 @@ The `fragment` module provides low-level management and rendering of fragment li
`fragment list` contains various `fragments` of text (such as ``-I /usr/include``) in a matter
which is composable, mergeable and reorderable.
.. c:function:: void pkgconf_fragment_add(const pkgconf_client_t *client, pkgconf_list_t *list, const char *string)
.. c:function:: void pkgconf_fragment_add(const pkgconf_client_t *client, pkgconf_list_t *list, const char *string, unsigned int flags)
Adds a `fragment` of text to a `fragment list`, possibly modifying the fragment if a sysroot is set.
:param pkgconf_client_t* client: The pkgconf client being accessed.
:param pkgconf_list_t* list: The fragment list.
:param char* string: The string of text to add as a fragment to the fragment list.
:param uint flags: Parsing-related flags for the package.
:return: nothing
.. c:function:: bool pkgconf_fragment_has_system_dir(const pkgconf_client_t *client, const pkgconf_fragment_t *frag)
@ -25,18 +26,28 @@ which is composable, mergeable and reorderable.
:return: true if the fragment contains a system path, else false
:rtype: bool
.. c:function:: void pkgconf_fragment_copy(pkgconf_list_t *list, const pkgconf_fragment_t *base, unsigned int flags, bool is_private)
.. c:function:: void pkgconf_fragment_copy(const pkgconf_client_t *client, pkgconf_list_t *list, const pkgconf_fragment_t *base, bool is_private)
Copies a `fragment` to another `fragment list`, possibly removing a previous copy of the `fragment`
in a process known as `mergeback`.
:param pkgconf_client_t* client: The pkgconf client being accessed.
:param pkgconf_list_t* list: The list the fragment is being added to.
:param pkgconf_fragment_t* base: The fragment being copied.
:param uint flags: A set of dependency resolver flags.
:param bool is_private: Whether the fragment list is a `private` fragment list (static linking).
:return: nothing
.. c:function:: void pkgconf_fragment_filter(const pkgconf_client_t *client, pkgconf_list_t *dest, pkgconf_list_t *src, pkgconf_fragment_filter_func_t filter_func, unsigned int flags)
.. c:function:: void pkgconf_fragment_copy_list(const pkgconf_client_t *client, pkgconf_list_t *list, const pkgconf_list_t *base)
Copies a `fragment list` to another `fragment list`, possibly removing a previous copy of the fragments
in a process known as `mergeback`.
:param pkgconf_client_t* client: The pkgconf client being accessed.
:param pkgconf_list_t* list: The list the fragments are being added to.
:param pkgconf_list_t* base: The list the fragments are being copied from.
:return: nothing
.. c:function:: void pkgconf_fragment_filter(const pkgconf_client_t *client, pkgconf_list_t *dest, pkgconf_list_t *src, pkgconf_fragment_filter_func_t filter_func)
Copies a `fragment list` to another `fragment list` which match a user-specified filtering function.
@ -44,24 +55,28 @@ which is composable, mergeable and reorderable.
:param pkgconf_list_t* dest: The destination list.
:param pkgconf_list_t* src: The source list.
:param pkgconf_fragment_filter_func_t filter_func: The filter function to use.
:param uint flags: A set of dependency resolver flags.
:param void* data: Optional data to pass to the filter function.
:return: nothing
.. c:function:: size_t pkgconf_fragment_render_len(const pkgconf_list_t *list)
.. c:function:: size_t pkgconf_fragment_render_len(const pkgconf_list_t *list, bool escape, const pkgconf_fragment_render_ops_t *ops)
Calculates the required memory to store a `fragment list` when rendered as a string.
:param pkgconf_list_t* list: The `fragment list` being rendered.
:param bool escape: Whether or not to escape special shell characters (deprecated).
:param pkgconf_fragment_render_ops_t* ops: An optional ops structure to use for custom renderers, else ``NULL``.
:return: the amount of bytes required to represent the `fragment list` when rendered
:rtype: size_t
.. c:function:: void pkgconf_fragment_render_buf(const pkgconf_list_t *list, char *buf, size_t buflen)
.. c:function:: void pkgconf_fragment_render_buf(const pkgconf_list_t *list, char *buf, size_t buflen, bool escape, const pkgconf_fragment_render_ops_t *ops)
Renders a `fragment list` into a buffer.
:param pkgconf_list_t* list: The `fragment list` being rendered.
:param char* buf: The buffer to render the fragment list into.
:param size_t buflen: The length of the buffer.
:param bool escape: Whether or not to escape special shell characters (deprecated).
:param pkgconf_fragment_render_ops_t* ops: An optional ops structure to use for custom renderers, else ``NULL``.
:return: nothing
.. c:function:: char *pkgconf_fragment_render(const pkgconf_list_t *list)
@ -69,6 +84,8 @@ which is composable, mergeable and reorderable.
Allocate memory and render a `fragment list` into it.
:param pkgconf_list_t* list: The `fragment list` being rendered.
:param bool escape: Whether or not to escape special shell characters (deprecated).
:param pkgconf_fragment_render_ops_t* ops: An optional ops structure to use for custom renderers, else ``NULL``.
:return: An allocated string containing the rendered `fragment list`.
:rtype: char *
@ -87,12 +104,13 @@ which is composable, mergeable and reorderable.
:param pkgconf_list_t* list: The `fragment list` to delete.
:return: nothing
.. c:function:: void pkgconf_fragment_parse(const pkgconf_client_t *client, pkgconf_list_t *list, pkgconf_list_t *vars, const char *value)
.. c:function:: bool pkgconf_fragment_parse(const pkgconf_client_t *client, pkgconf_list_t *list, pkgconf_list_t *vars, const char *value)
Parse a string into a `fragment list`.
:param pkgconf_client_t* client: The pkgconf client being accessed.
:param pkgconf_list_t* list: The `fragment list` to add the fragment entries to.
:param pkgconf_list_t* vars: A list of variables to use for variable substitution.
:param uint flags: Any parsing flags to be aware of.
:param char* value: The string to parse into fragments.
:return: nothing
:return: true on success, false on parse error

View File

@ -25,12 +25,12 @@ variables.
:return: number of path nodes added to the path list
:rtype: size_t
.. c:function:: size_t pkgconf_path_build_from_environ(const char *environ, const char *fallback, pkgconf_list_t *dirlist)
.. c:function:: size_t pkgconf_path_build_from_environ(const char *envvarname, const char *fallback, pkgconf_list_t *dirlist)
Adds the paths specified in an environment variable to a path list. If the environment variable is not set,
an optional default set of paths is added.
:param char* environ: The environment variable to look up.
:param char* envvarname: The environment variable to look up.
:param char* fallback: The fallback paths to use if the environment variable is not set.
:param pkgconf_list_t* dirlist: The path list to add the path nodes to.
:param bool filter: Whether to perform duplicate filtering.
@ -46,9 +46,26 @@ variables.
:return: true if the path list has a matching prefix, otherwise false
:rtype: bool
.. c:function:: void pkgconf_path_copy_list(pkgconf_list_t *dst, const pkgconf_list_t *src)
Copies a path list to another path list.
:param pkgconf_list_t* dst: The path list to copy to.
:param pkgconf_list_t* src: The path list to copy from.
:return: nothing
.. c:function:: void pkgconf_path_free(pkgconf_list_t *dirlist)
Releases any path nodes attached to the given path list.
:param pkgconf_list_t* dirlist: The path list to clean up.
:return: nothing
.. c:function:: bool pkgconf_path_relocate(char *buf, size_t buflen)
Relocates a path, possibly calling normpath() on it.
:param char* buf: The path to relocate.
:param size_t buflen: The buffer length the path is contained in.
:return: true on success, false on error
:rtype: bool

View File

@ -0,0 +1,27 @@
libpkgconf `personality` module
=========================
.. c:function:: const pkgconf_cross_personality_t *pkgconf_cross_personality_default(void)
Returns the default cross-compile personality.
Not thread safe.
:rtype: pkgconf_cross_personality_t*
:return: the default cross-compile personality
.. c:function:: void pkgconf_cross_personality_deinit(pkgconf_cross_personality_t *)
Decrements the count of default cross personality instances.
Not thread safe.
:rtype: void
.. c:function:: pkgconf_cross_personality_t *pkgconf_cross_personality_find(const char *triplet)
Attempts to find a cross-compile personality given a triplet.
:rtype: pkgconf_cross_personality_t*
:return: the default cross-compile personality

View File

@ -5,23 +5,14 @@ libpkgconf `pkg` module
The `pkg` module provides dependency resolution services and the overall `.pc` file parsing
routines.
.. c:function:: void pkgconf_pkg_dir_list_build(pkgconf_client_t *client, unsigned int flags)
Bootstraps the package search paths. If the ``PKGCONF_PKG_PKGF_ENV_ONLY`` `flag` is provided,
then only the ``PKG_CONFIG_PATH`` environment variable will be used, otherwise both the
``PKG_CONFIG_PATH`` and ``PKG_CONFIG_LIBDIR`` environment variables will be used.
:param pkgconf_client_t* client: The pkgconf client object to bootstrap.
:param uint flags: A set of dependency resolver options.
:return: nothing
.. c:function:: pkgconf_pkg_t *pkgconf_pkg_new_from_file(const pkgconf_client_t *client, const char *filename, FILE *f)
.. c:function:: pkgconf_pkg_t *pkgconf_pkg_new_from_file(const pkgconf_client_t *client, const char *filename, FILE *f, unsigned int flags)
Parse a .pc file into a pkgconf_pkg_t object structure.
:param pkgconf_client_t* client: The pkgconf client object to use for dependency resolution.
:param char* filename: The filename of the package file (including full path).
:param FILE* f: The file object to read from.
:param uint flags: The flags to use when parsing.
:returns: A ``pkgconf_pkg_t`` object which contains the package data.
:rtype: pkgconf_pkg_t *
@ -62,13 +53,12 @@ routines.
:return: A package object reference if one is found by the scan function, else ``NULL``.
:rtype: pkgconf_pkg_t *
.. c:function:: pkgconf_pkg_t *pkgconf_pkg_find(pkgconf_client_t *client, const char *name, unsigned int flags)
.. c:function:: pkgconf_pkg_t *pkgconf_pkg_find(pkgconf_client_t *client, const char *name)
Search for a package.
:param pkgconf_client_t* client: The pkgconf client object to use for dependency resolution.
:param char* name: The name of the package `atom` to use for searching.
:param uint flags: A set of flags which define the behaviour of the dependency resolver.
:return: A package object reference if the package was found, else ``NULL``.
:rtype: pkgconf_pkg_t *
@ -78,7 +68,7 @@ routines.
:param char* a: The first version to compare in the pair.
:param char* b: The second version to compare in the pair.
:return: -1 if the first version is greater, 0 if both versions are equal, 1 if the second version is greater.
:return: -1 if the first version is less than, 0 if both versions are equal, 1 if the second version is less than.
:rtype: int
.. c:function:: pkgconf_pkg_t *pkgconf_builtin_pkg_get(const char *name)
@ -106,19 +96,18 @@ routines.
:return: The comparator bytecode if found, else ``PKGCONF_CMP_ANY``.
:rtype: pkgconf_pkg_comparator_t
.. c:function:: pkgconf_pkg_t *pkgconf_pkg_verify_dependency(pkgconf_client_t *client, pkgconf_dependency_t *pkgdep, unsigned int flags, unsigned int *eflags)
.. c:function:: pkgconf_pkg_t *pkgconf_pkg_verify_dependency(pkgconf_client_t *client, pkgconf_dependency_t *pkgdep, unsigned int *eflags)
Verify a pkgconf_dependency_t node in the depgraph. If the dependency is solvable,
return the appropriate ``pkgconf_pkg_t`` object, else ``NULL``.
:param pkgconf_client_t* client: The pkgconf client object to use for dependency resolution.
:param pkgconf_dependency_t* pkgdep: The dependency graph node to solve.
:param uint flags: A set of package resolver flags which modify behaviour.
:param uint* eflags: An optional pointer that, if set, will be populated with an error code from the resolver.
:return: On success, the appropriate ``pkgconf_pkg_t`` object to solve the dependency, else ``NULL``.
:rtype: pkgconf_pkg_t *
.. c:function:: unsigned int pkgconf_pkg_verify_graph(pkgconf_client_t *client, pkgconf_pkg_t *root, int depth, unsigned int flags)
.. c:function:: unsigned int pkgconf_pkg_verify_graph(pkgconf_client_t *client, pkgconf_pkg_t *root, int depth)
Verify the graph dependency nodes are satisfiable by walking the tree using
``pkgconf_pkg_traverse()``.
@ -126,11 +115,10 @@ routines.
:param pkgconf_client_t* client: The pkgconf client object to use for dependency resolution.
:param pkgconf_pkg_t* root: The root entry in the package dependency graph which should contain the top-level dependencies to resolve.
:param int depth: The maximum allowed depth for dependency resolution.
:param uint flags: A set of package resolver flags which modify it's behaviour.
:return: On success, ``PKGCONF_PKG_ERRF_OK`` (0), else an error code.
:rtype: unsigned int
.. c:function:: unsigned int pkgconf_pkg_traverse(pkgconf_client_t *client, pkgconf_pkg_t *root, pkgconf_pkg_traverse_func_t func, void *data, int maxdepth, unsigned int flags)
.. c:function:: unsigned int pkgconf_pkg_traverse(pkgconf_client_t *client, pkgconf_pkg_t *root, pkgconf_pkg_traverse_func_t func, void *data, int maxdepth, unsigned int skip_flags)
Walk and resolve the dependency graph up to `maxdepth` levels.
@ -139,17 +127,11 @@ routines.
:param pkgconf_pkg_traverse_func_t func: A traversal function to call for each resolved node in the dependency graph.
:param void* data: An opaque pointer to data to be passed to the traversal function.
:param int maxdepth: The maximum depth to walk the dependency graph for. -1 means infinite recursion.
:param uint flags: A set of flags which modify the dependency resolver's behaviour:
:``PKGCONF_PKG_PKGF_SKIP_ROOT_VIRTUAL``: Do not call the traversal function for the root element in the graph if it is a virtual or built-in package.
:``PKGCONF_PKG_PKGF_SKIP_CONFLICTS``: Do not process `conflicts` rules.
:``PKGCONF_PKG_PKGF_SKIP_PROVIDES``: Do not process `provides` rules.
:``PKGCONF_PKG_PKGF_SEARCH_PRIVATE``: Process `requires.private` rules.
:param uint skip_flags: Skip over dependency nodes containing the specified flags. A setting of 0 skips no dependency nodes.
:return: ``PKGCONF_PKG_ERRF_OK`` on success, else an error code.
:rtype: unsigned int
.. c:function:: int pkgconf_pkg_cflags(pkgconf_client_t *client, pkgconf_pkg_t *root, pkgconf_list_t *list, int maxdepth, unsigned int flags)
.. c:function:: int pkgconf_pkg_cflags(pkgconf_client_t *client, pkgconf_pkg_t *root, pkgconf_list_t *list, int maxdepth)
Walks a dependency graph and extracts relevant ``CFLAGS`` fragments.
@ -157,14 +139,10 @@ routines.
:param pkgconf_pkg_t* root: The root of the dependency graph.
:param pkgconf_list_t* list: The fragment list to add the extracted ``CFLAGS`` fragments to.
:param int maxdepth: The maximum allowed depth for dependency resolution. -1 means infinite recursion.
:param uint flags: A set of optional dependency resolver flags. All of the flags for ``pkgconf_pkg_traverse()`` are relevant here, as well as:
:``PKGCONF_PKG_PKGF_MERGE_PRIVATE_FRAGMENTS``: merge ``CFLAGS.private`` entries as well
:return: ``PKGCONF_PKG_ERRF_OK`` if successful, otherwise an error code.
:rtype: unsigned int
.. c:function:: int pkgconf_pkg_libs(pkgconf_client_t *client, pkgconf_pkg_t *root, pkgconf_list_t *list, int maxdepth, unsigned int flags)
.. c:function:: int pkgconf_pkg_libs(pkgconf_client_t *client, pkgconf_pkg_t *root, pkgconf_list_t *list, int maxdepth)
Walks a dependency graph and extracts relevant ``LIBS`` fragments.
@ -172,9 +150,5 @@ routines.
:param pkgconf_pkg_t* root: The root of the dependency graph.
:param pkgconf_list_t* list: The fragment list to add the extracted ``LIBS`` fragments to.
:param int maxdepth: The maximum allowed depth for dependency resolution. -1 means infinite recursion.
:param uint flags: A set of optional dependency resolver flags. All of the flags for ``pkgconf_pkg_traverse()`` are relevant here, as well as:
:``PKGCONF_PKG_PKGF_MERGE_PRIVATE_FRAGMENTS``: merge ``LIBS.private`` entries as well
:return: ``PKGCONF_PKG_ERRF_OK`` if successful, otherwise an error code.
:rtype: unsigned int

View File

@ -33,27 +33,46 @@ Using the `queue` module functions is the recommended way of working with depend
:param pkgconf_list_t* list: The dependency resolution queue to release.
:return: nothing
.. c:function:: void pkgconf_queue_apply(pkgconf_client_t *client, pkgconf_list_t *list, pkgconf_queue_apply_func_t func, int maxdepth, unsigned int flags, void *data)
.. c:function:: void pkgconf_solution_free(pkgconf_client_t *client, pkgconf_pkg_t *world, int maxdepth)
Removes references to package nodes contained in a solution.
:param pkgconf_client_t* client: The pkgconf client object to use for dependency resolution.
:param pkgconf_pkg_t* world: The root for the generated dependency graph. Should have PKGCONF_PKG_PROPF_VIRTUAL flag.
:returns: nothing
.. c:function:: bool pkgconf_queue_solve(pkgconf_client_t *client, pkgconf_list_t *list, pkgconf_pkg_t *world, int maxdepth)
Solves and flattens the dependency graph for the supplied dependency list.
:param pkgconf_client_t* client: The pkgconf client object to use for dependency resolution.
:param pkgconf_list_t* list: The list of dependency requests to consider.
:param pkgconf_pkg_t* world: The root for the generated dependency graph, provided by the caller. Should have PKGCONF_PKG_PROPF_VIRTUAL flag.
:param int maxdepth: The maximum allowed depth for the dependency resolver. A depth of -1 means unlimited.
:returns: true if the dependency resolver found a solution, otherwise false.
:rtype: bool
.. c:function:: void pkgconf_queue_apply(pkgconf_client_t *client, pkgconf_list_t *list, pkgconf_queue_apply_func_t func, int maxdepth, void *data)
Attempt to compile a dependency resolution queue into a dependency resolution problem, then attempt to solve the problem and
feed the solution to a callback function if a complete dependency graph is found.
This function should not be used in new code. Use pkgconf_queue_solve instead.
:param pkgconf_client_t* client: The pkgconf client object to use for dependency resolution.
:param pkgconf_list_t* list: The list of dependency requests to consider.
:param pkgconf_queue_apply_func_t func: The callback function to call if a solution is found by the dependency resolver.
:param int maxdepth: The maximum allowed depth for the dependency resolver. A depth of -1 means unlimited.
:param uint flags: A bitfield of flags that is passed to the dependency resolver, optionally modifying it's behaviour.
:param void* data: An opaque pointer which is passed to the callback function.
:returns: true if the dependency resolver found a solution, otherwise false.
:rtype: bool
.. c:function:: void pkgconf_queue_validate(pkgconf_client_t *client, pkgconf_list_t *list, pkgconf_queue_apply_func_t func, int maxdepth, unsigned int flags, void *data)
.. c:function:: void pkgconf_queue_validate(pkgconf_client_t *client, pkgconf_list_t *list, pkgconf_queue_apply_func_t func, int maxdepth, void *data)
Attempt to compile a dependency resolution queue into a dependency resolution problem, then attempt to solve the problem.
:param pkgconf_client_t* client: The pkgconf client object to use for dependency resolution.
:param pkgconf_list_t* list: The list of dependency requests to consider.
:param int maxdepth: The maximum allowed depth for the dependency resolver. A depth of -1 means unlimited.
:param uint flags: A bitfield of flags that is passed to the dependency resolver, optionally modifying it's behaviour.
:returns: true if the dependency resolver found a solution, otherwise false.
:rtype: bool

View File

@ -64,13 +64,14 @@ attached to a given client object.
:return: the value of the variable or ``NULL``
:rtype: char *
.. c:function:: char *pkgconf_tuple_parse(const pkgconf_client_t *client, pkgconf_list_t *vars, const char *value)
.. c:function:: char *pkgconf_tuple_parse(const pkgconf_client_t *client, pkgconf_list_t *vars, const char *value, unsigned int flags)
Parse an expression for variable substitution.
:param pkgconf_client_t* client: The pkgconf client object to access.
:param pkgconf_list_t* list: The variable list to search for variables (along side the global variable list).
:param char* value: The ``key=value`` string to parse.
:param uint flags: Any flags to consider while parsing.
:return: the variable data with any variables substituted
:rtype: char *

View File

@ -11,6 +11,7 @@ libpkgconf - an API for managing `pkg-config` modules
libpkgconf-dependency
libpkgconf-fragment
libpkgconf-path
libpkgconf-personality
libpkgconf-pkg
libpkgconf-queue
libpkgconf-tuple

View File

@ -5,7 +5,8 @@ libdir=@libdir@
Name: libpkgconf
Description: a library for accessing and manipulating development framework configuration
URL: http://github.com/pkgconf/pkgconf
URL: https://gitea.treehouse.systems/ariadne/pkgconf
License: ISC
Version: @PACKAGE_VERSION@
CFlags: -I${includedir}/pkgconf
Libs: -L${libdir} -lpkgconf

View File

@ -2,7 +2,7 @@
* argvsplit.c
* argv_split() routine
*
* Copyright (c) 2012 pkgconf authors (see AUTHORS).
* Copyright (c) 2012, 2017 pkgconf authors (see AUTHORS).
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -13,6 +13,7 @@
* from the use of this software.
*/
#include <libpkgconf/stdinc.h>
#include <libpkgconf/libpkgconf.h>
/*
@ -64,37 +65,45 @@ pkgconf_argv_split(const char *src, int *argc, char ***argv)
int argc_count = 0;
int argv_size = 5;
char quote = 0;
bool escaped = false;
src_iter = src;
dst_iter = buf;
memset(buf, 0, strlen(src) + 1);
*argv = calloc(sizeof (void *), argv_size);
*argv = calloc(argv_size, sizeof (void *));
(*argv)[argc_count] = dst_iter;
while (*src_iter)
{
if (quote == *src_iter)
quote = 0;
if (escaped)
{
/* POSIX: only \CHAR is special inside a double quote if CHAR is {$, `, ", \, newline}. */
if (quote == '"')
{
if (!(*src_iter == '$' || *src_iter == '`' || *src_iter == '"' || *src_iter == '\\'))
*dst_iter++ = '\\';
*dst_iter++ = *src_iter;
}
else
{
*dst_iter++ = *src_iter;
}
escaped = false;
}
else if (quote)
{
if (*src_iter == '\\')
{
src_iter++;
if (!*src_iter)
{
free(*argv);
free(buf);
return -1;
}
if (*src_iter != quote)
*dst_iter++ = '\\';
}
*dst_iter++ = *src_iter;
if (*src_iter == quote)
quote = 0;
else if (*src_iter == '\\' && quote != '\'')
escaped = true;
else
*dst_iter++ = *src_iter;
}
else if (isspace((unsigned int)*src_iter))
else if (isspace((unsigned char)*src_iter))
{
if ((*argv)[argc_count] != NULL)
{
@ -111,22 +120,15 @@ pkgconf_argv_split(const char *src, int *argc, char ***argv)
}
else switch(*src_iter)
{
case '"':
case '\\':
escaped = true;
break;
case '\"':
case '\'':
quote = *src_iter;
break;
case '\\':
src_iter++;
if (!*src_iter)
{
free(argv);
free(buf);
return -1;
} else {
*dst_iter++ = '\\';
}
default:
*dst_iter++ = *src_iter;
break;
@ -135,7 +137,15 @@ pkgconf_argv_split(const char *src, int *argc, char ***argv)
src_iter++;
}
if (strlen((*argv)[argc_count])) {
if (escaped || quote)
{
free(*argv);
free(buf);
return -1;
}
if (strlen((*argv)[argc_count]))
{
argc_count++;
}

View File

@ -17,13 +17,15 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include <errno.h>
#include <libpkgconf/bsdstubs.h>
#include <libpkgconf/config.h>
#ifndef HAVE_STRLCPY
#if !HAVE_DECL_STRLCPY
/*
* Copy src to string dst of size siz. At most siz-1 characters
* will be copied. Always NUL terminates (unless siz == 0).
@ -56,7 +58,7 @@ strlcpy(char *dst, const char *src, size_t siz)
}
#endif
#ifndef HAVE_STRLCAT
#if !HAVE_DECL_STRLCAT
/*
* Appends src to string dst of size siz (unlike strncat, siz is the
* full size of dst, not space left). At most siz-1 characters
@ -105,7 +107,7 @@ strlcat(char *dst, const char *src, size_t siz)
* from the use of this software.
*/
#ifndef HAVE_STRNDUP
#if !HAVE_DECL_STRNDUP
/*
* Creates a memory buffer and copies at most 'len' characters to it.
* If 'len' is less than the length of the source string, truncation occured.
@ -136,3 +138,23 @@ pkgconf_strndup(const char *src, size_t len)
{
return strndup(src, len);
}
#if !HAVE_DECL_REALLOCARRAY
void *
reallocarray(void *ptr, size_t m, size_t n)
{
if (n && m > -1 / n)
{
errno = ENOMEM;
return 0;
}
return realloc(ptr, m * n);
}
#endif
void *
pkgconf_reallocarray(void *ptr, size_t m, size_t n)
{
return reallocarray(ptr, m, n);
}

View File

@ -13,11 +13,22 @@
* from the use of this software.
*/
#ifndef __BSDSTUBS_H__
#define __BSDSTUBS_H__
#ifndef LIBPKGCONF_BSDSTUBS_H
#define LIBPKGCONF_BSDSTUBS_H
extern size_t pkgconf_strlcpy(char *dst, const char *src, size_t siz);
extern size_t pkgconf_strlcat(char *dst, const char *src, size_t siz);
extern char *pkgconf_strndup(const char *src, size_t len);
#include <libpkgconf/libpkgconf-api.h>
#ifdef __cplusplus
extern "C" {
#endif
PKGCONF_API extern size_t pkgconf_strlcpy(char *dst, const char *src, size_t siz);
PKGCONF_API extern size_t pkgconf_strlcat(char *dst, const char *src, size_t siz);
PKGCONF_API extern char *pkgconf_strndup(const char *src, size_t len);
PKGCONF_API extern void *pkgconf_reallocarray(void *ptr, size_t m, size_t n);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -13,8 +13,11 @@
* from the use of this software.
*/
#include <libpkgconf/stdinc.h>
#include <libpkgconf/libpkgconf.h>
#include <assert.h>
/*
* !doc
*
@ -28,6 +31,46 @@
* be shared across threads.
*/
static int
cache_member_cmp(const void *a, const void *b)
{
const char *key = a;
const pkgconf_pkg_t *pkg = *(void **) b;
return strcmp(key, pkg->id);
}
static int
cache_member_sort_cmp(const void *a, const void *b)
{
const pkgconf_pkg_t *pkgA = *(void **) a;
const pkgconf_pkg_t *pkgB = *(void **) b;
if (pkgA == NULL)
return 1;
if (pkgB == NULL)
return -1;
return strcmp(pkgA->id, pkgB->id);
}
static void
cache_dump(const pkgconf_client_t *client)
{
size_t i;
PKGCONF_TRACE(client, "dumping package cache contents");
for (i = 0; i < client->cache_count; i++)
{
const pkgconf_pkg_t *pkg = client->cache_table[i];
PKGCONF_TRACE(client, SIZE_FMT_SPECIFIER": %p(%s)",
i, pkg, pkg == NULL ? "NULL" : pkg->id);
}
}
/*
* !doc
*
@ -43,18 +86,24 @@
* :rtype: pkgconf_pkg_t *
*/
pkgconf_pkg_t *
pkgconf_cache_lookup(const pkgconf_client_t *client, const char *id)
pkgconf_cache_lookup(pkgconf_client_t *client, const char *id)
{
pkgconf_node_t *node;
if (client->cache_table == NULL)
return NULL;
PKGCONF_FOREACH_LIST_ENTRY(client->pkg_cache.head, node)
pkgconf_pkg_t **pkg;
pkg = bsearch(id, client->cache_table,
client->cache_count, sizeof (void *),
cache_member_cmp);
if (pkg != NULL)
{
pkgconf_pkg_t *pkg = node->data;
if (!strcmp(pkg->id, id))
return pkgconf_pkg_ref(client, pkg);
PKGCONF_TRACE(client, "found: %s @%p", id, *pkg);
return pkgconf_pkg_ref(client, *pkg);
}
PKGCONF_TRACE(client, "miss: %s", id);
return NULL;
}
@ -77,7 +126,19 @@ pkgconf_cache_add(pkgconf_client_t *client, pkgconf_pkg_t *pkg)
return;
pkgconf_pkg_ref(client, pkg);
pkgconf_node_insert(&pkg->cache_iter, pkg, &client->pkg_cache);
PKGCONF_TRACE(client, "added @%p to cache", pkg);
/* mark package as cached */
pkg->flags |= PKGCONF_PKG_PROPF_CACHED;
++client->cache_count;
client->cache_table = pkgconf_reallocarray(client->cache_table,
client->cache_count, sizeof (void *));
client->cache_table[client->cache_count - 1] = pkg;
qsort(client->cache_table, client->cache_count,
sizeof(void *), cache_member_sort_cmp);
}
/*
@ -94,10 +155,52 @@ pkgconf_cache_add(pkgconf_client_t *client, pkgconf_pkg_t *pkg)
void
pkgconf_cache_remove(pkgconf_client_t *client, pkgconf_pkg_t *pkg)
{
if (client->cache_table == NULL)
return;
if (pkg == NULL)
return;
pkgconf_node_delete(&pkg->cache_iter, &client->pkg_cache);
if (!(pkg->flags & PKGCONF_PKG_PROPF_CACHED))
return;
PKGCONF_TRACE(client, "removed @%p from cache", pkg);
pkgconf_pkg_t **slot;
slot = bsearch(pkg->id, client->cache_table,
client->cache_count, sizeof (void *),
cache_member_cmp);
if (slot == NULL)
return;
(*slot)->flags &= ~PKGCONF_PKG_PROPF_CACHED;
pkgconf_pkg_unref(client, *slot);
*slot = NULL;
qsort(client->cache_table, client->cache_count,
sizeof(void *), cache_member_sort_cmp);
if (client->cache_table[client->cache_count - 1] != NULL)
{
PKGCONF_TRACE(client, "end of cache table refers to %p, not NULL",
client->cache_table[client->cache_count - 1]);
cache_dump(client);
abort();
}
client->cache_count--;
if (client->cache_count > 0)
{
client->cache_table = pkgconf_reallocarray(client->cache_table,
client->cache_count, sizeof(void *));
}
else
{
free(client->cache_table);
client->cache_table = NULL;
}
}
/*
@ -114,13 +217,15 @@ pkgconf_cache_remove(pkgconf_client_t *client, pkgconf_pkg_t *pkg)
void
pkgconf_cache_free(pkgconf_client_t *client)
{
pkgconf_node_t *iter, *iter2;
if (client->cache_table == NULL)
return;
PKGCONF_FOREACH_LIST_ENTRY_SAFE(client->pkg_cache.head, iter2, iter)
{
pkgconf_pkg_t *pkg = iter->data;
pkgconf_pkg_free(client, pkg);
}
while (client->cache_count > 0)
pkgconf_cache_remove(client, client->cache_table[0]);
memset(&client->pkg_cache, 0, sizeof client->pkg_cache);
free(client->cache_table);
client->cache_table = NULL;
client->cache_count = 0;
PKGCONF_TRACE(client, "cleared package cache");
}

View File

@ -13,6 +13,8 @@
* from the use of this software.
*/
#include <libpkgconf/config.h>
#include <libpkgconf/stdinc.h>
#include <libpkgconf/libpkgconf.h>
/*
@ -29,59 +31,138 @@
* thread boundaries.
*/
static void
trace_path_list(const pkgconf_client_t *client, const char *desc, pkgconf_list_t *list)
{
const pkgconf_node_t *n;
PKGCONF_TRACE(client, "%s:", desc);
PKGCONF_FOREACH_LIST_ENTRY(list->head, n)
{
const pkgconf_path_t *p = n->data;
PKGCONF_TRACE(client, " - '%s'", p->path);
}
}
/*
* !doc
*
* .. c:function:: void pkgconf_client_init(pkgconf_client_t *client, pkgconf_error_handler_func_t error_handler)
* .. c:function:: void pkgconf_client_dir_list_build(pkgconf_client_t *client)
*
* Bootstraps the package search paths. If the ``PKGCONF_PKG_PKGF_ENV_ONLY`` `flag` is set on the client,
* then only the ``PKG_CONFIG_PATH`` environment variable will be used, otherwise both the
* ``PKG_CONFIG_PATH`` and ``PKG_CONFIG_LIBDIR`` environment variables will be used.
*
* :param pkgconf_client_t* client: The pkgconf client object to bootstrap.
* :return: nothing
*/
void
pkgconf_client_dir_list_build(pkgconf_client_t *client, const pkgconf_cross_personality_t *personality)
{
pkgconf_path_build_from_environ("PKG_CONFIG_PATH", NULL, &client->dir_list, true);
if (!(client->flags & PKGCONF_PKG_PKGF_ENV_ONLY))
{
pkgconf_list_t dir_list = PKGCONF_LIST_INITIALIZER;
const pkgconf_list_t *prepend_list = &personality->dir_list;
if (getenv("PKG_CONFIG_LIBDIR") != NULL)
{
/* PKG_CONFIG_LIBDIR= should empty the search path entirely. */
(void) pkgconf_path_build_from_environ("PKG_CONFIG_LIBDIR", NULL, &dir_list, true);
prepend_list = &dir_list;
}
pkgconf_path_copy_list(&client->dir_list, prepend_list);
pkgconf_path_free(&dir_list);
}
}
/*
* !doc
*
* .. c:function:: void pkgconf_client_init(pkgconf_client_t *client, pkgconf_error_handler_func_t error_handler, void *error_handler_data, const pkgconf_cross_personality_t *personality)
*
* Initialise a pkgconf client object.
*
* :param pkgconf_client_t* client: The client to initialise.
* :param pkgconf_error_handler_func_t error_handler: An optional error handler to use for logging errors.
* :param void* error_handler_data: user data passed to optional error handler
* :param pkgconf_cross_personality_t* personality: the cross-compile personality to use for defaults
* :return: nothing
*/
void
pkgconf_client_init(pkgconf_client_t *client, pkgconf_error_handler_func_t error_handler, void *error_handler_data)
pkgconf_client_init(pkgconf_client_t *client, pkgconf_error_handler_func_t error_handler, void *error_handler_data, const pkgconf_cross_personality_t *personality)
{
client->error_handler_data = error_handler_data;
client->error_handler = error_handler;
client->auditf = NULL;
client->cache_table = NULL;
client->cache_count = 0;
pkgconf_client_set_sysroot_dir(client, NULL);
#ifndef PKGCONF_LITE
if (client->trace_handler == NULL)
pkgconf_client_set_trace_handler(client, NULL, NULL);
#endif
pkgconf_client_set_error_handler(client, error_handler, error_handler_data);
pkgconf_client_set_warn_handler(client, NULL, NULL);
pkgconf_client_set_sysroot_dir(client, personality->sysroot_dir);
pkgconf_client_set_buildroot_dir(client, NULL);
pkgconf_client_set_prefix_varname(client, NULL);
if (client->error_handler == NULL)
client->error_handler = pkgconf_default_error_handler;
if(getenv("PKG_CONFIG_SYSTEM_LIBRARY_PATH") == NULL)
pkgconf_path_copy_list(&client->filter_libdirs, &personality->filter_libdirs);
else
pkgconf_path_build_from_environ("PKG_CONFIG_SYSTEM_LIBRARY_PATH", NULL, &client->filter_libdirs, false);
pkgconf_path_build_from_environ("PKG_CONFIG_SYSTEM_LIBRARY_PATH", SYSTEM_LIBDIR, &client->filter_libdirs, false);
pkgconf_path_build_from_environ("PKG_CONFIG_SYSTEM_INCLUDE_PATH", SYSTEM_INCLUDEDIR, &client->filter_includedirs, false);
if(getenv("PKG_CONFIG_SYSTEM_INCLUDE_PATH") == NULL)
pkgconf_path_copy_list(&client->filter_includedirs, &personality->filter_includedirs);
else
pkgconf_path_build_from_environ("PKG_CONFIG_SYSTEM_INCLUDE_PATH", NULL, &client->filter_includedirs, false);
/* GCC uses these environment variables to define system include paths, so we should check them. */
#ifdef __HAIKU__
pkgconf_path_build_from_environ("BELIBRARIES", NULL, &client->filter_libdirs, false);
#else
pkgconf_path_build_from_environ("LIBRARY_PATH", NULL, &client->filter_libdirs, false);
#endif
pkgconf_path_build_from_environ("CPATH", NULL, &client->filter_includedirs, false);
pkgconf_path_build_from_environ("C_INCLUDE_PATH", NULL, &client->filter_includedirs, false);
pkgconf_path_build_from_environ("CPLUS_INCLUDE_PATH", NULL, &client->filter_includedirs, false);
pkgconf_path_build_from_environ("OBJC_INCLUDE_PATH", NULL, &client->filter_includedirs, false);
#ifdef _WIN32
/* also use the path lists that MSVC uses on windows */
pkgconf_path_build_from_environ("INCLUDE", NULL, &client->filter_includedirs, false);
#endif
PKGCONF_TRACE(client, "initialized client @%p", client);
trace_path_list(client, "filtered library paths", &client->filter_libdirs);
trace_path_list(client, "filtered include paths", &client->filter_includedirs);
}
/*
* !doc
*
* .. c:function:: pkgconf_client_t* pkgconf_client_new(pkgconf_error_handler_func_t error_handler)
* .. c:function:: pkgconf_client_t* pkgconf_client_new(pkgconf_error_handler_func_t error_handler, void *error_handler_data, const pkgconf_cross_personality_t *personality)
*
* Allocate and initialise a pkgconf client object.
*
* :param pkgconf_error_handler_func_t error_handler: An optional error handler to use for logging errors.
* :param void* error_handler_data: user data passed to optional error handler
* :param pkgconf_cross_personality_t* personality: cross-compile personality to use
* :return: A pkgconf client object.
* :rtype: pkgconf_client_t*
*/
pkgconf_client_t *
pkgconf_client_new(pkgconf_error_handler_func_t error_handler, void *error_handler_data)
pkgconf_client_new(pkgconf_error_handler_func_t error_handler, void *error_handler_data, const pkgconf_cross_personality_t *personality)
{
pkgconf_client_t *out = calloc(sizeof(pkgconf_client_t), 1);
pkgconf_client_init(out, error_handler, error_handler_data);
pkgconf_client_t *out = calloc(1, sizeof(pkgconf_client_t));
pkgconf_client_init(out, error_handler, error_handler_data, personality);
return out;
}
@ -98,12 +179,20 @@ pkgconf_client_new(pkgconf_error_handler_func_t error_handler, void *error_handl
void
pkgconf_client_deinit(pkgconf_client_t *client)
{
PKGCONF_TRACE(client, "deinit @%p", client);
if (client->prefix_varname != NULL)
free(client->prefix_varname);
if (client->sysroot_dir != NULL)
free(client->sysroot_dir);
if (client->buildroot_dir != NULL)
free(client->buildroot_dir);
pkgconf_path_free(&client->filter_libdirs);
pkgconf_path_free(&client->filter_includedirs);
pkgconf_tuple_free_global(client);
pkgconf_path_free(&client->dir_list);
pkgconf_cache_free(client);
@ -165,6 +254,8 @@ pkgconf_client_set_sysroot_dir(pkgconf_client_t *client, const char *sysroot_dir
client->sysroot_dir = sysroot_dir != NULL ? strdup(sysroot_dir) : NULL;
PKGCONF_TRACE(client, "set sysroot_dir to: %s", client->sysroot_dir != NULL ? client->sysroot_dir : "<default>");
pkgconf_tuple_add_global(client, "pc_sysrootdir", client->sysroot_dir != NULL ? client->sysroot_dir : "/");
}
@ -207,6 +298,8 @@ pkgconf_client_set_buildroot_dir(pkgconf_client_t *client, const char *buildroot
client->buildroot_dir = buildroot_dir != NULL ? strdup(buildroot_dir) : NULL;
PKGCONF_TRACE(client, "set buildroot_dir to: %s", client->buildroot_dir != NULL ? client->buildroot_dir : "<default>");
pkgconf_tuple_add_global(client, "pc_top_builddir", client->buildroot_dir != NULL ? client->buildroot_dir : "$(top_builddir)");
}
@ -235,6 +328,67 @@ pkgconf_error(const pkgconf_client_t *client, const char *format, ...)
return client->error_handler(errbuf, client, client->error_handler_data);
}
/*
* !doc
*
* .. c:function:: bool pkgconf_warn(const pkgconf_client_t *client, const char *format, ...)
*
* Report an error to a client-registered warn handler.
*
* :param pkgconf_client_t* client: The pkgconf client object to report the error to.
* :param char* format: A printf-style format string to use for formatting the warning message.
* :return: true if the warn handler processed the message, else false.
* :rtype: bool
*/
bool
pkgconf_warn(const pkgconf_client_t *client, const char *format, ...)
{
char errbuf[PKGCONF_BUFSIZE];
va_list va;
va_start(va, format);
vsnprintf(errbuf, sizeof errbuf, format, va);
va_end(va);
return client->warn_handler(errbuf, client, client->warn_handler_data);
}
/*
* !doc
*
* .. c:function:: bool pkgconf_trace(const pkgconf_client_t *client, const char *filename, size_t len, const char *funcname, const char *format, ...)
*
* Report a message to a client-registered trace handler.
*
* :param pkgconf_client_t* client: The pkgconf client object to report the trace message to.
* :param char* filename: The file the function is in.
* :param size_t lineno: The line number currently being executed.
* :param char* funcname: The function name to use.
* :param char* format: A printf-style format string to use for formatting the trace message.
* :return: true if the trace handler processed the message, else false.
* :rtype: bool
*/
bool
pkgconf_trace(const pkgconf_client_t *client, const char *filename, size_t lineno, const char *funcname, const char *format, ...)
{
char errbuf[PKGCONF_BUFSIZE];
size_t len;
va_list va;
if (client == NULL || client->trace_handler == NULL)
return false;
len = snprintf(errbuf, sizeof errbuf, "%s:" SIZE_FMT_SPECIFIER " [%s]: ", filename, lineno, funcname);
va_start(va, format);
vsnprintf(errbuf + len, sizeof(errbuf) - len, format, va);
va_end(va);
pkgconf_strlcat(errbuf, "\n", sizeof errbuf);
return client->trace_handler(errbuf, client, client->trace_handler_data);
}
/*
* !doc
*
@ -249,7 +403,7 @@ pkgconf_error(const pkgconf_client_t *client, const char *format, ...)
* :rtype: bool
*/
bool
pkgconf_default_error_handler(const char *msg, const pkgconf_client_t *client, const void *data)
pkgconf_default_error_handler(const char *msg, const pkgconf_client_t *client, void *data)
{
(void) msg;
(void) client;
@ -257,3 +411,205 @@ pkgconf_default_error_handler(const char *msg, const pkgconf_client_t *client, c
return true;
}
/*
* !doc
*
* .. c:function:: unsigned int pkgconf_client_get_flags(const pkgconf_client_t *client)
*
* Retrieves resolver-specific flags associated with a client object.
*
* :param pkgconf_client_t* client: The client object to retrieve the resolver-specific flags from.
* :return: a bitfield of resolver-specific flags
* :rtype: uint
*/
unsigned int
pkgconf_client_get_flags(const pkgconf_client_t *client)
{
return client->flags;
}
/*
* !doc
*
* .. c:function:: void pkgconf_client_set_flags(pkgconf_client_t *client, unsigned int flags)
*
* Sets resolver-specific flags associated with a client object.
*
* :param pkgconf_client_t* client: The client object to set the resolver-specific flags on.
* :return: nothing
*/
void
pkgconf_client_set_flags(pkgconf_client_t *client, unsigned int flags)
{
client->flags = flags;
}
/*
* !doc
*
* .. c:function:: const char *pkgconf_client_get_prefix_varname(const pkgconf_client_t *client)
*
* Retrieves the name of the variable that should contain a module's prefix.
* In some cases, it is necessary to override this variable to allow proper path relocation.
*
* :param pkgconf_client_t* client: The client object to retrieve the prefix variable name from.
* :return: the prefix variable name as a string
* :rtype: const char *
*/
const char *
pkgconf_client_get_prefix_varname(const pkgconf_client_t *client)
{
return client->prefix_varname;
}
/*
* !doc
*
* .. c:function:: void pkgconf_client_set_prefix_varname(pkgconf_client_t *client, const char *prefix_varname)
*
* Sets the name of the variable that should contain a module's prefix.
* If the variable name is ``NULL``, then the default variable name (``prefix``) is used.
*
* :param pkgconf_client_t* client: The client object to set the prefix variable name on.
* :param char* prefix_varname: The prefix variable name to set.
* :return: nothing
*/
void
pkgconf_client_set_prefix_varname(pkgconf_client_t *client, const char *prefix_varname)
{
if (prefix_varname == NULL)
prefix_varname = "prefix";
if (client->prefix_varname != NULL)
free(client->prefix_varname);
client->prefix_varname = strdup(prefix_varname);
PKGCONF_TRACE(client, "set prefix_varname to: %s", client->prefix_varname);
}
/*
* !doc
*
* .. c:function:: pkgconf_client_get_warn_handler(const pkgconf_client_t *client)
*
* Returns the warning handler if one is set, else ``NULL``.
*
* :param pkgconf_client_t* client: The client object to get the warn handler from.
* :return: a function pointer to the warn handler or ``NULL``
*/
pkgconf_error_handler_func_t
pkgconf_client_get_warn_handler(const pkgconf_client_t *client)
{
return client->warn_handler;
}
/*
* !doc
*
* .. c:function:: pkgconf_client_set_warn_handler(pkgconf_client_t *client, pkgconf_error_handler_func_t warn_handler, void *warn_handler_data)
*
* Sets a warn handler on a client object or uninstalls one if set to ``NULL``.
*
* :param pkgconf_client_t* client: The client object to set the warn handler on.
* :param pkgconf_error_handler_func_t warn_handler: The warn handler to set.
* :param void* warn_handler_data: Optional data to associate with the warn handler.
* :return: nothing
*/
void
pkgconf_client_set_warn_handler(pkgconf_client_t *client, pkgconf_error_handler_func_t warn_handler, void *warn_handler_data)
{
client->warn_handler = warn_handler;
client->warn_handler_data = warn_handler_data;
if (client->warn_handler == NULL)
{
PKGCONF_TRACE(client, "installing default warn handler");
client->warn_handler = pkgconf_default_error_handler;
}
}
/*
* !doc
*
* .. c:function:: pkgconf_client_get_error_handler(const pkgconf_client_t *client)
*
* Returns the error handler if one is set, else ``NULL``.
*
* :param pkgconf_client_t* client: The client object to get the error handler from.
* :return: a function pointer to the error handler or ``NULL``
*/
pkgconf_error_handler_func_t
pkgconf_client_get_error_handler(const pkgconf_client_t *client)
{
return client->error_handler;
}
/*
* !doc
*
* .. c:function:: pkgconf_client_set_error_handler(pkgconf_client_t *client, pkgconf_error_handler_func_t error_handler, void *error_handler_data)
*
* Sets a warn handler on a client object or uninstalls one if set to ``NULL``.
*
* :param pkgconf_client_t* client: The client object to set the error handler on.
* :param pkgconf_error_handler_func_t error_handler: The error handler to set.
* :param void* error_handler_data: Optional data to associate with the error handler.
* :return: nothing
*/
void
pkgconf_client_set_error_handler(pkgconf_client_t *client, pkgconf_error_handler_func_t error_handler, void *error_handler_data)
{
client->error_handler = error_handler;
client->error_handler_data = error_handler_data;
if (client->error_handler == NULL)
{
PKGCONF_TRACE(client, "installing default error handler");
client->error_handler = pkgconf_default_error_handler;
}
}
#ifndef PKGCONF_LITE
/*
* !doc
*
* .. c:function:: pkgconf_client_get_trace_handler(const pkgconf_client_t *client)
*
* Returns the error handler if one is set, else ``NULL``.
*
* :param pkgconf_client_t* client: The client object to get the error handler from.
* :return: a function pointer to the error handler or ``NULL``
*/
pkgconf_error_handler_func_t
pkgconf_client_get_trace_handler(const pkgconf_client_t *client)
{
return client->trace_handler;
}
/*
* !doc
*
* .. c:function:: pkgconf_client_set_trace_handler(pkgconf_client_t *client, pkgconf_error_handler_func_t trace_handler, void *trace_handler_data)
*
* Sets a warn handler on a client object or uninstalls one if set to ``NULL``.
*
* :param pkgconf_client_t* client: The client object to set the error handler on.
* :param pkgconf_error_handler_func_t trace_handler: The error handler to set.
* :param void* trace_handler_data: Optional data to associate with the error handler.
* :return: nothing
*/
void
pkgconf_client_set_trace_handler(pkgconf_client_t *client, pkgconf_error_handler_func_t trace_handler, void *trace_handler_data)
{
client->trace_handler = trace_handler;
client->trace_handler_data = trace_handler_data;
if (client->trace_handler == NULL)
{
client->trace_handler = pkgconf_default_error_handler;
PKGCONF_TRACE(client, "installing default trace handler");
}
}
#endif

68
libpkgconf/config.h.meson Normal file
View File

@ -0,0 +1,68 @@
/* libpkgconf/config.h.in. Generated from configure.ac by autoheader. */
/* Define to 1 if you have the `strlcat' function. */
#mesondefine HAVE_STRLCAT
/* Define to 1 if you have the `strlcpy' function. */
#mesondefine HAVE_STRLCPY
/* Define to 1 if you have the `strndup' function. */
#mesondefine HAVE_STRNDUP
/* Define to 1 if you have the `reallocarray' function. */
#mesondefine HAVE_REALLOCARRAY
/* Define to 1 if you have the `strlcat' function. */
#mesondefine HAVE_DECL_STRLCAT
/* Define to 1 if you have the `strlcpy' function. */
#mesondefine HAVE_DECL_STRLCPY
/* Define to 1 if you have the `strndup' function. */
#mesondefine HAVE_DECL_STRNDUP
/* Define to 1 if you have the `reallocarray' function. */
#mesondefine HAVE_DECL_REALLOCARRAY
/* Name of package */
#mesondefine PACKAGE
/* Define to the address where bug reports for this package should be sent. */
#mesondefine PACKAGE_BUGREPORT
/* Define to the full name of this package. */
#mesondefine PACKAGE_NAME
/* Define to the full name and version of this package. */
#mesondefine PACKAGE_STRING
/* Define to the one symbol short name of this package. */
#mesondefine PACKAGE_TARNAME
/* Define to the home page for this package. */
#mesondefine PACKAGE_URL
/* Define to the version of this package. */
#mesondefine PACKAGE_VERSION
/* Define to 1 if you have the ANSI C header files. */
#mesondefine STDC_HEADERS
/* Version number of package */
#mesondefine VERSION
/* Enable large inode numbers on Mac OS X 10.5. */
#ifndef _DARWIN_USE_64_BIT_INODE
# define _DARWIN_USE_64_BIT_INODE 1
#endif
/* Number of bits in a file offset, on hosts where this is settable. */
#mesondefine _FILE_OFFSET_BITS
/* Define for large files, on AIX-style hosts. */
#mesondefine _LARGE_FILES
#mesondefine PKG_DEFAULT_PATH
#mesondefine SYSTEM_INCLUDEDIR
#mesondefine SYSTEM_LIBDIR
#mesondefine PERSONALITY_PATH

View File

@ -13,6 +13,7 @@
* from the use of this software.
*/
#include <libpkgconf/stdinc.h>
#include <libpkgconf/libpkgconf.h>
/*
@ -36,22 +37,111 @@ typedef enum {
#define DEBUG_PARSE 0
static const char *
dependency_to_str(const pkgconf_dependency_t *dep, char *buf, size_t buflen)
{
pkgconf_strlcpy(buf, dep->package, buflen);
if (dep->version != NULL)
{
pkgconf_strlcat(buf, " ", buflen);
pkgconf_strlcat(buf, pkgconf_pkg_get_comparator(dep), buflen);
pkgconf_strlcat(buf, " ", buflen);
pkgconf_strlcat(buf, dep->version, buflen);
}
return buf;
}
/* find a colliding dependency that is coloured differently */
static inline pkgconf_dependency_t *
pkgconf_dependency_addraw(pkgconf_list_t *list, const char *package, size_t package_sz, const char *version, size_t version_sz, pkgconf_pkg_comparator_t compare)
find_colliding_dependency(const pkgconf_dependency_t *dep, const pkgconf_list_t *list)
{
const pkgconf_node_t *n;
PKGCONF_FOREACH_LIST_ENTRY(list->head, n)
{
pkgconf_dependency_t *dep2 = n->data;
if (strcmp(dep->package, dep2->package))
continue;
if (dep->flags != dep2->flags)
return dep2;
}
return NULL;
}
static inline pkgconf_dependency_t *
add_or_replace_dependency_node(pkgconf_client_t *client, pkgconf_dependency_t *dep, pkgconf_list_t *list)
{
char depbuf[PKGCONF_ITEM_SIZE];
pkgconf_dependency_t *dep2 = find_colliding_dependency(dep, list);
/* there is already a node in the graph which describes this dependency */
if (dep2 != NULL)
{
char depbuf2[PKGCONF_ITEM_SIZE];
PKGCONF_TRACE(client, "dependency collision: [%s/%x] -- [%s/%x]",
dependency_to_str(dep, depbuf, sizeof depbuf), dep->flags,
dependency_to_str(dep2, depbuf2, sizeof depbuf2), dep2->flags);
/* prefer the uncoloured node, either dep or dep2 */
if (dep->flags && dep2->flags == 0)
{
PKGCONF_TRACE(client, "dropping dependency [%s]@%p because of collision", depbuf, dep);
pkgconf_dependency_unref(dep->owner, dep);
return NULL;
}
else if (dep2->flags && dep->flags == 0)
{
PKGCONF_TRACE(client, "dropping dependency [%s]@%p because of collision", depbuf2, dep2);
pkgconf_node_delete(&dep2->iter, list);
pkgconf_dependency_unref(dep2->owner, dep2);
}
else
/* If both dependencies have equal strength, we keep both, because of situations like:
* Requires: foo > 1, foo < 3
*
* If the situation is that both dependencies are literally equal, it is still harmless because
* fragment deduplication will handle the excessive fragments.
*/
PKGCONF_TRACE(client, "keeping both dependencies (harmless)");
}
PKGCONF_TRACE(client, "added dependency [%s] to list @%p; flags=%x", dependency_to_str(dep, depbuf, sizeof depbuf), list, dep->flags);
pkgconf_node_insert_tail(&dep->iter, pkgconf_dependency_ref(dep->owner, dep), list);
/* This dependency is intentionally unowned.
*
* Internally we have no use for the returned type, and usually just
* discard it. However, there is a publig pkgconf_dependency_add
* function, which references this return value before returning it,
* giving ownership at that point.
*/
return dep;
}
static inline pkgconf_dependency_t *
pkgconf_dependency_addraw(pkgconf_client_t *client, pkgconf_list_t *list, const char *package, size_t package_sz, const char *version, size_t version_sz, pkgconf_pkg_comparator_t compare, unsigned int flags)
{
pkgconf_dependency_t *dep;
dep = calloc(sizeof(pkgconf_dependency_t), 1);
dep = calloc(1, sizeof(pkgconf_dependency_t));
dep->package = pkgconf_strndup(package, package_sz);
if (version_sz != 0)
dep->version = pkgconf_strndup(version, version_sz);
dep->compare = compare;
dep->flags = flags;
dep->owner = client;
dep->refcount = 0;
pkgconf_node_insert_tail(&dep->iter, dep, list);
return dep;
return add_or_replace_dependency_node(client, dep, list);
}
/*
@ -61,20 +151,22 @@ pkgconf_dependency_addraw(pkgconf_list_t *list, const char *package, size_t pack
*
* Adds a parsed dependency to a dependency list as a dependency node.
*
* :param pkgconf_client_t* client: The client object that owns the package this dependency list belongs to.
* :param pkgconf_list_t* list: The dependency list to add a dependency node to.
* :param char* package: The package `atom` to set on the dependency node.
* :param char* version: The package `version` to set on the dependency node.
* :param pkgconf_pkg_comparator_t compare: The comparison operator to set on the dependency node.
* :param uint flags: Any flags to attach to the dependency node.
* :return: A dependency node.
* :rtype: pkgconf_dependency_t *
*/
pkgconf_dependency_t *
pkgconf_dependency_add(pkgconf_list_t *list, const char *package, const char *version, pkgconf_pkg_comparator_t compare)
pkgconf_dependency_add(pkgconf_client_t *client, pkgconf_list_t *list, const char *package, const char *version, pkgconf_pkg_comparator_t compare, unsigned int flags)
{
if (version != NULL)
return pkgconf_dependency_addraw(list, package, strlen(package), version, strlen(version), compare);
return pkgconf_dependency_addraw(list, package, strlen(package), NULL, 0, compare);
pkgconf_dependency_t *dep;
dep = pkgconf_dependency_addraw(client, list, package, strlen(package), version,
version != NULL ? strlen(version) : 0, compare, flags);
return pkgconf_dependency_ref(dep->owner, dep);
}
/*
@ -94,12 +186,83 @@ pkgconf_dependency_append(pkgconf_list_t *list, pkgconf_dependency_t *tail)
pkgconf_node_insert_tail(&tail->iter, tail, list);
}
/*
* !doc
*
* .. c:function:: void pkgconf_dependency_free_one(pkgconf_dependency_t *dep)
*
* Frees a dependency node.
*
* :param pkgconf_dependency_t* dep: The dependency node to free.
* :return: nothing
*/
void
pkgconf_dependency_free_one(pkgconf_dependency_t *dep)
{
if (dep->match != NULL)
pkgconf_pkg_unref(dep->match->owner, dep->match);
if (dep->package != NULL)
free(dep->package);
if (dep->version != NULL)
free(dep->version);
free(dep);
}
/*
* !doc
*
* .. c:function:: pkgconf_dependency_t *pkgconf_dependency_ref(pkgconf_client_t *owner, pkgconf_dependency_t *dep)
*
* Increases a dependency node's refcount.
*
* :param pkgconf_client_t* owner: The client object which owns the memory of this dependency node.
* :param pkgconf_dependency_t* dep: The dependency to increase the refcount of.
* :return: the dependency node on success, else NULL
*/
pkgconf_dependency_t *
pkgconf_dependency_ref(pkgconf_client_t *client, pkgconf_dependency_t *dep)
{
if (client != dep->owner)
return NULL;
dep->refcount++;
PKGCONF_TRACE(client, "%s refcount@%p: %d", dep->package, dep, dep->refcount);
return dep;
}
/*
* !doc
*
* .. c:function:: void pkgconf_dependency_unref(pkgconf_client_t *owner, pkgconf_dependency_t *dep)
*
* Decreases a dependency node's refcount and frees it if necessary.
*
* :param pkgconf_client_t* owner: The client object which owns the memory of this dependency node.
* :param pkgconf_dependency_t* dep: The dependency to decrease the refcount of.
* :return: nothing
*/
void
pkgconf_dependency_unref(pkgconf_client_t *client, pkgconf_dependency_t *dep)
{
if (client != dep->owner)
return;
--dep->refcount;
PKGCONF_TRACE(client, "%s refcount@%p: %d", dep->package, dep, dep->refcount);
if (dep->refcount <= 0)
pkgconf_dependency_free_one(dep);
}
/*
* !doc
*
* .. c:function:: void pkgconf_dependency_free(pkgconf_list_t *list)
*
* Release a dependency list and it's child dependency nodes.
* Release a dependency list and its child dependency nodes.
*
* :param pkgconf_list_t* list: The dependency list to release.
* :return: nothing
@ -113,14 +276,11 @@ pkgconf_dependency_free(pkgconf_list_t *list)
{
pkgconf_dependency_t *dep = node->data;
if (dep->package != NULL)
free(dep->package);
if (dep->version != NULL)
free(dep->version);
free(dep);
pkgconf_node_delete(&dep->iter, list);
pkgconf_dependency_unref(dep->owner, dep);
}
pkgconf_list_zero(list);
}
/*
@ -132,16 +292,18 @@ pkgconf_dependency_free(pkgconf_list_t *list)
* Commas are counted as whitespace to allow for constructs such as ``@SUBSTVAR@, zlib`` being processed
* into ``, zlib``.
*
* :param pkgconf_client_t* client: The client object that owns the package this dependency list belongs to.
* :param pkgconf_list_t* deplist_head: The dependency list to populate with dependency nodes.
* :param char* depends: The dependency data to parse.
* :param uint flags: Any flags to attach to the dependency nodes.
* :return: nothing
*/
void
pkgconf_dependency_parse_str(pkgconf_list_t *deplist_head, const char *depends)
pkgconf_dependency_parse_str(pkgconf_client_t *client, pkgconf_list_t *deplist_head, const char *depends, unsigned int flags)
{
parse_state_t state = OUTSIDE_MODULE;
pkgconf_pkg_comparator_t compare = PKGCONF_CMP_ANY;
char cmpname[PKGCONF_BUFSIZE];
char cmpname[PKGCONF_ITEM_SIZE];
char buf[PKGCONF_BUFSIZE];
size_t package_sz = 0, version_sz = 0;
char *start = buf;
@ -149,6 +311,7 @@ pkgconf_dependency_parse_str(pkgconf_list_t *deplist_head, const char *depends)
char *vstart = NULL;
char *package = NULL, *version = NULL;
char *cnameptr = cmpname;
char *cnameend = cmpname + PKGCONF_ITEM_SIZE - 1;
memset(cmpname, '\0', sizeof cmpname);
@ -166,11 +329,11 @@ pkgconf_dependency_parse_str(pkgconf_list_t *deplist_head, const char *depends)
break;
case INSIDE_MODULE_NAME:
if (isspace((unsigned int)*ptr))
if (isspace((unsigned char)*ptr))
{
const char *sptr = ptr;
while (*sptr && isspace((unsigned int)*sptr))
while (*sptr && isspace((unsigned char)*sptr))
sptr++;
if (*sptr == '\0')
@ -204,11 +367,10 @@ pkgconf_dependency_parse_str(pkgconf_list_t *deplist_head, const char *depends)
if (state == OUTSIDE_MODULE)
{
pkgconf_dependency_addraw(deplist_head, package, package_sz, NULL, 0, compare);
pkgconf_dependency_addraw(client, deplist_head, package, package_sz, NULL, 0, compare, flags);
compare = PKGCONF_CMP_ANY;
package_sz = 0;
version_sz = 0;
}
break;
@ -217,7 +379,8 @@ pkgconf_dependency_parse_str(pkgconf_list_t *deplist_head, const char *depends)
if (PKGCONF_IS_OPERATOR_CHAR(*ptr))
{
state = INSIDE_OPERATOR;
*cnameptr++ = *ptr;
if (cnameptr < cnameend)
*cnameptr++ = *ptr;
}
break;
@ -228,13 +391,13 @@ pkgconf_dependency_parse_str(pkgconf_list_t *deplist_head, const char *depends)
state = AFTER_OPERATOR;
compare = pkgconf_pkg_comparator_lookup_by_name(cmpname);
}
else
else if (cnameptr < cnameend)
*cnameptr++ = *ptr;
break;
case AFTER_OPERATOR:
if (!isspace((unsigned int)*ptr))
if (!isspace((unsigned char)*ptr))
{
vstart = ptr;
state = INSIDE_VERSION;
@ -248,13 +411,12 @@ pkgconf_dependency_parse_str(pkgconf_list_t *deplist_head, const char *depends)
version_sz = ptr - vstart;
state = OUTSIDE_MODULE;
pkgconf_dependency_addraw(deplist_head, package, package_sz, version, version_sz, compare);
pkgconf_dependency_addraw(client, deplist_head, package, package_sz, version, version_sz, compare, flags);
compare = PKGCONF_CMP_ANY;
cnameptr = cmpname;
memset(cmpname, 0, sizeof cmpname);
package_sz = 0;
version_sz = 0;
}
if (state == OUTSIDE_MODULE)
@ -279,13 +441,47 @@ pkgconf_dependency_parse_str(pkgconf_list_t *deplist_head, const char *depends)
* :param pkgconf_pkg_t* pkg: The package object that owns this dependency list.
* :param pkgconf_list_t* deplist: The dependency list to populate with dependency nodes.
* :param char* depends: The dependency data to parse.
* :param uint flags: Any flags to attach to the dependency nodes.
* :return: nothing
*/
void
pkgconf_dependency_parse(const pkgconf_client_t *client, pkgconf_pkg_t *pkg, pkgconf_list_t *deplist, const char *depends)
pkgconf_dependency_parse(pkgconf_client_t *client, pkgconf_pkg_t *pkg, pkgconf_list_t *deplist, const char *depends, unsigned int flags)
{
char *kvdepends = pkgconf_tuple_parse(client, &pkg->vars, depends);
char *kvdepends = pkgconf_tuple_parse(client, &pkg->vars, depends, pkg->flags);
pkgconf_dependency_parse_str(deplist, kvdepends);
pkgconf_dependency_parse_str(client, deplist, kvdepends, flags);
free(kvdepends);
}
/*
* !doc
*
* .. c:function:: pkgconf_dependency_t *pkgconf_dependency_copy(pkgconf_client_t *client, const pkgconf_dependency_t *dep)
*
* Copies a dependency node to a new one.
*
* :param pkgconf_client_t* client: The client object that will own this dependency.
* :param pkgconf_dependency_t* dep: The dependency node to copy.
* :return: a pointer to a new dependency node, else NULL
*/
pkgconf_dependency_t *
pkgconf_dependency_copy(pkgconf_client_t *client, const pkgconf_dependency_t *dep)
{
pkgconf_dependency_t *new_dep;
new_dep = calloc(1, sizeof(pkgconf_dependency_t));
new_dep->package = strdup(dep->package);
if (dep->version != NULL)
new_dep->version = strdup(dep->version);
new_dep->compare = dep->compare;
new_dep->flags = dep->flags;
new_dep->owner = client;
new_dep->refcount = 0;
if (dep->match != NULL)
new_dep->match = pkgconf_pkg_ref(client, dep->match);
return pkgconf_dependency_ref(client, new_dep);
}

View File

@ -13,13 +13,14 @@
* from the use of this software.
*/
#include <libpkgconf/stdinc.h>
#include <libpkgconf/libpkgconf.h>
char *
pkgconf_fgetline(char *line, size_t size, FILE *stream)
{
char *s = line;
char *end = line + size - 1;
char *end = line + size - 2;
bool quoted = false;
int c = '\0', c2;
@ -28,7 +29,7 @@ pkgconf_fgetline(char *line, size_t size, FILE *stream)
while (s < end && (c = getc(stream)) != EOF)
{
if (c == '\\')
if (c == '\\' && !quoted)
{
quoted = true;
continue;
@ -43,6 +44,9 @@ pkgconf_fgetline(char *line, size_t size, FILE *stream)
*s++ = c;
break;
}
else
*s++ = c;
quoted = false;
continue;
}

View File

@ -13,6 +13,7 @@
* from the use of this software.
*/
#include <libpkgconf/stdinc.h>
#include <libpkgconf/libpkgconf.h>
/*
@ -34,10 +35,23 @@ struct pkgconf_fragment_check {
static inline bool
pkgconf_fragment_is_unmergeable(const char *string)
{
static struct pkgconf_fragment_check check_fragments[] = {
static const struct pkgconf_fragment_check check_fragments[] = {
{"-framework", 10},
{"-isystem", 8},
{"-idirafter", 10},
{"-pthread", 8},
{"-Wa,", 4},
{"-Wl,", 4},
{"-Wp,", 4},
{"-trigraphs", 10},
{"-pedantic", 9},
{"-ansi", 5},
{"-std=", 5},
{"-stdlib=", 8},
{"-include", 8},
{"-nostdinc", 9},
{"-nostdlibinc", 12},
{"-nobuiltininc", 13},
};
if (*string != '-')
@ -47,27 +61,22 @@ pkgconf_fragment_is_unmergeable(const char *string)
if (!strncmp(string, check_fragments[i].token, check_fragments[i].len))
return true;
/* only one pair of {-flag, arg} may be merged together */
if (strchr(string, ' ') != NULL)
return false;
return false;
}
static inline bool
pkgconf_fragment_should_munge(const char *string, const char *sysroot_dir)
{
static struct pkgconf_fragment_check check_fragments[] = {
{"-isystem", 8},
{"-idirafter", 10},
};
if (*string != '/')
return false;
if (sysroot_dir != NULL && strncmp(sysroot_dir, string, strlen(sysroot_dir)))
return true;
for (size_t i = 0; i < PKGCONF_ARRAY_SIZE(check_fragments); i++)
if (!strncmp(string, check_fragments[i].token, check_fragments[i].len))
return true;
return false;
}
@ -84,73 +93,79 @@ pkgconf_fragment_is_special(const char *string)
}
static inline void
pkgconf_fragment_munge(const pkgconf_client_t *client, char *buf, size_t buflen, const char *source, const char *sysroot_dir)
pkgconf_fragment_munge(const pkgconf_client_t *client, char *buf, size_t buflen, const char *source, const char *sysroot_dir, unsigned int flags)
{
*buf = '\0';
if (sysroot_dir == NULL)
sysroot_dir = pkgconf_tuple_find_global(client, "pc_sysrootdir");
if (!(flags & PKGCONF_PKG_PROPF_UNINSTALLED) || (client->flags & PKGCONF_PKG_PKGF_PKGCONF1_SYSROOT_RULES))
{
if (sysroot_dir == NULL)
sysroot_dir = pkgconf_tuple_find_global(client, "pc_sysrootdir");
if (pkgconf_fragment_should_munge(source, sysroot_dir))
pkgconf_strlcat(buf, sysroot_dir, buflen);
if (sysroot_dir != NULL && pkgconf_fragment_should_munge(source, sysroot_dir))
pkgconf_strlcat(buf, sysroot_dir, buflen);
}
pkgconf_strlcat(buf, source, buflen);
if (*buf == '/' && !(client->flags & PKGCONF_PKG_PKGF_DONT_RELOCATE_PATHS))
pkgconf_path_relocate(buf, buflen);
}
static inline char *
pkgconf_fragment_copy_munged(const pkgconf_client_t *client, const char *source)
pkgconf_fragment_copy_munged(const pkgconf_client_t *client, const char *source, unsigned int flags)
{
char mungebuf[PKGCONF_BUFSIZE];
if (client->sysroot_dir == NULL)
return strdup(source);
pkgconf_fragment_munge(client, mungebuf, sizeof mungebuf, source, client->sysroot_dir);
char mungebuf[PKGCONF_ITEM_SIZE];
pkgconf_fragment_munge(client, mungebuf, sizeof mungebuf, source, client->sysroot_dir, flags);
return strdup(mungebuf);
}
/*
* !doc
*
* .. c:function:: void pkgconf_fragment_add(const pkgconf_client_t *client, pkgconf_list_t *list, const char *string)
* .. c:function:: void pkgconf_fragment_add(const pkgconf_client_t *client, pkgconf_list_t *list, const char *string, unsigned int flags)
*
* Adds a `fragment` of text to a `fragment list`, possibly modifying the fragment if a sysroot is set.
*
* :param pkgconf_client_t* client: The pkgconf client being accessed.
* :param pkgconf_list_t* list: The fragment list.
* :param char* string: The string of text to add as a fragment to the fragment list.
* :param uint flags: Parsing-related flags for the package.
* :return: nothing
*/
void
pkgconf_fragment_add(const pkgconf_client_t *client, pkgconf_list_t *list, const char *string)
pkgconf_fragment_add(const pkgconf_client_t *client, pkgconf_list_t *list, const char *string, unsigned int flags)
{
pkgconf_fragment_t *frag;
if (*string == '\0')
return;
if (!pkgconf_fragment_is_special(string))
if (strlen(string) > 1 && !pkgconf_fragment_is_special(string))
{
frag = calloc(sizeof(pkgconf_fragment_t), 1);
frag = calloc(1, sizeof(pkgconf_fragment_t));
frag->type = *(string + 1);
frag->data = pkgconf_fragment_copy_munged(client, string + 2);
frag->data = pkgconf_fragment_copy_munged(client, string + 2, flags);
PKGCONF_TRACE(client, "added fragment {%c, '%s'} to list @%p", frag->type, frag->data, list);
}
else
{
char mungebuf[PKGCONF_BUFSIZE];
char mungebuf[PKGCONF_ITEM_SIZE];
if (list->tail != NULL && list->tail->data != NULL)
if (list->tail != NULL && list->tail->data != NULL &&
!(client->flags & PKGCONF_PKG_PKGF_DONT_MERGE_SPECIAL_FRAGMENTS))
{
pkgconf_fragment_t *parent = list->tail->data;
if (pkgconf_fragment_is_unmergeable(parent->data))
/* only attempt to merge 'special' fragments together */
if (!parent->type && parent->data != NULL && pkgconf_fragment_is_unmergeable(parent->data))
{
size_t len;
char *newdata;
pkgconf_fragment_munge(client, mungebuf, sizeof mungebuf, string, NULL);
pkgconf_fragment_munge(client, mungebuf, sizeof mungebuf, string, NULL, flags);
len = strlen(parent->data) + strlen(mungebuf) + 2;
newdata = malloc(len);
@ -159,17 +174,30 @@ pkgconf_fragment_add(const pkgconf_client_t *client, pkgconf_list_t *list, const
pkgconf_strlcat(newdata, " ", len);
pkgconf_strlcat(newdata, mungebuf, len);
PKGCONF_TRACE(client, "merging '%s' to '%s' to form fragment {'%s'} in list @%p", mungebuf, parent->data, newdata, list);
free(parent->data);
parent->data = newdata;
parent->merged = true;
/* use a copy operation to force a dedup */
pkgconf_node_delete(&parent->iter, list);
pkgconf_fragment_copy(client, list, parent, false);
/* the fragment list now (maybe) has the copied node, so free the original */
free(parent->data);
free(parent);
return;
}
}
frag = calloc(sizeof(pkgconf_fragment_t), 1);
frag = calloc(1, sizeof(pkgconf_fragment_t));
frag->type = 0;
frag->data = strdup(string);
PKGCONF_TRACE(client, "created special fragment {'%s'} in list @%p", frag->data, list);
}
pkgconf_node_insert_tail(&frag->iter, frag, list);
@ -261,7 +289,7 @@ pkgconf_fragment_should_merge(const pkgconf_fragment_t *base)
case 'I':
return true;
default:
return parent->type == base->type;
return !base->type || parent->type == base->type;
}
}
@ -301,34 +329,36 @@ pkgconf_fragment_has_system_dir(const pkgconf_client_t *client, const pkgconf_fr
/*
* !doc
*
* .. c:function:: void pkgconf_fragment_copy(pkgconf_list_t *list, const pkgconf_fragment_t *base, unsigned int flags, bool is_private)
* .. c:function:: void pkgconf_fragment_copy(const pkgconf_client_t *client, pkgconf_list_t *list, const pkgconf_fragment_t *base, bool is_private)
*
* Copies a `fragment` to another `fragment list`, possibly removing a previous copy of the `fragment`
* in a process known as `mergeback`.
*
* :param pkgconf_client_t* client: The pkgconf client being accessed.
* :param pkgconf_list_t* list: The list the fragment is being added to.
* :param pkgconf_fragment_t* base: The fragment being copied.
* :param uint flags: A set of dependency resolver flags.
* :param bool is_private: Whether the fragment list is a `private` fragment list (static linking).
* :return: nothing
*/
void
pkgconf_fragment_copy(pkgconf_list_t *list, const pkgconf_fragment_t *base, unsigned int flags, bool is_private)
pkgconf_fragment_copy(const pkgconf_client_t *client, pkgconf_list_t *list, const pkgconf_fragment_t *base, bool is_private)
{
pkgconf_fragment_t *frag;
if ((frag = pkgconf_fragment_exists(list, base, flags, is_private)) != NULL)
if ((frag = pkgconf_fragment_exists(list, base, client->flags, is_private)) != NULL)
{
if (pkgconf_fragment_should_merge(frag))
pkgconf_fragment_delete(list, frag);
}
else if (!is_private && !pkgconf_fragment_can_merge_back(base, flags, is_private) && (pkgconf_fragment_lookup(list, base) != NULL))
else if (!is_private && !pkgconf_fragment_can_merge_back(base, client->flags, is_private) && (pkgconf_fragment_lookup(list, base) != NULL))
return;
frag = calloc(sizeof(pkgconf_fragment_t), 1);
frag = calloc(1, sizeof(pkgconf_fragment_t));
frag->type = base->type;
frag->data = strdup(base->data);
frag->merged = base->merged;
if (base->data != NULL)
frag->data = strdup(base->data);
pkgconf_node_insert_tail(&frag->iter, frag, list);
}
@ -336,7 +366,33 @@ pkgconf_fragment_copy(pkgconf_list_t *list, const pkgconf_fragment_t *base, unsi
/*
* !doc
*
* .. c:function:: void pkgconf_fragment_filter(const pkgconf_client_t *client, pkgconf_list_t *dest, pkgconf_list_t *src, pkgconf_fragment_filter_func_t filter_func, unsigned int flags)
* .. c:function:: void pkgconf_fragment_copy_list(const pkgconf_client_t *client, pkgconf_list_t *list, const pkgconf_list_t *base)
*
* Copies a `fragment list` to another `fragment list`, possibly removing a previous copy of the fragments
* in a process known as `mergeback`.
*
* :param pkgconf_client_t* client: The pkgconf client being accessed.
* :param pkgconf_list_t* list: The list the fragments are being added to.
* :param pkgconf_list_t* base: The list the fragments are being copied from.
* :return: nothing
*/
void
pkgconf_fragment_copy_list(const pkgconf_client_t *client, pkgconf_list_t *list, const pkgconf_list_t *base)
{
pkgconf_node_t *node;
PKGCONF_FOREACH_LIST_ENTRY(base->head, node)
{
pkgconf_fragment_t *frag = node->data;
pkgconf_fragment_copy(client, list, frag, true);
}
}
/*
* !doc
*
* .. c:function:: void pkgconf_fragment_filter(const pkgconf_client_t *client, pkgconf_list_t *dest, pkgconf_list_t *src, pkgconf_fragment_filter_func_t filter_func)
*
* Copies a `fragment list` to another `fragment list` which match a user-specified filtering function.
*
@ -344,11 +400,11 @@ pkgconf_fragment_copy(pkgconf_list_t *list, const pkgconf_fragment_t *base, unsi
* :param pkgconf_list_t* dest: The destination list.
* :param pkgconf_list_t* src: The source list.
* :param pkgconf_fragment_filter_func_t filter_func: The filter function to use.
* :param uint flags: A set of dependency resolver flags.
* :param void* data: Optional data to pass to the filter function.
* :return: nothing
*/
void
pkgconf_fragment_filter(const pkgconf_client_t *client, pkgconf_list_t *dest, pkgconf_list_t *src, pkgconf_fragment_filter_func_t filter_func, unsigned int flags)
pkgconf_fragment_filter(const pkgconf_client_t *client, pkgconf_list_t *dest, pkgconf_list_t *src, pkgconf_fragment_filter_func_t filter_func, void *data)
{
pkgconf_node_t *node;
@ -356,11 +412,56 @@ pkgconf_fragment_filter(const pkgconf_client_t *client, pkgconf_list_t *dest, pk
{
pkgconf_fragment_t *frag = node->data;
if (filter_func(client, frag, flags))
pkgconf_fragment_copy(dest, frag, flags, true);
if (filter_func(client, frag, data))
pkgconf_fragment_copy(client, dest, frag, true);
}
}
static inline char *
fragment_quote(const pkgconf_fragment_t *frag)
{
const char *src = frag->data;
ssize_t outlen = strlen(src) + 10;
char *out, *dst;
if (frag->data == NULL)
return NULL;
out = dst = calloc(1, outlen);
for (; *src; src++)
{
if (((*src < ' ') ||
(*src >= (' ' + (frag->merged ? 1 : 0)) && *src < '$') ||
(*src > '$' && *src < '(') ||
(*src > ')' && *src < '+') ||
(*src > ':' && *src < '=') ||
(*src > '=' && *src < '@') ||
(*src > 'Z' && *src < '\\') ||
#ifndef _WIN32
(*src == '\\') ||
#endif
(*src > '\\' && *src < '^') ||
(*src == '`') ||
(*src > 'z' && *src < '~') ||
(*src > '~')))
*dst++ = '\\';
*dst++ = *src;
if ((ptrdiff_t)(dst - out) + 2 > outlen)
{
ptrdiff_t offset = dst - out;
outlen *= 2;
out = realloc(out, outlen);
dst = out + offset;
}
}
*dst = 0;
return out;
}
static inline size_t
pkgconf_fragment_len(const pkgconf_fragment_t *frag)
{
@ -370,25 +471,20 @@ pkgconf_fragment_len(const pkgconf_fragment_t *frag)
len += 2;
if (frag->data != NULL)
len += strlen(frag->data);
{
char *quoted = fragment_quote(frag);
len += strlen(quoted);
free(quoted);
}
return len;
}
/*
* !doc
*
* .. c:function:: size_t pkgconf_fragment_render_len(const pkgconf_list_t *list)
*
* Calculates the required memory to store a `fragment list` when rendered as a string.
*
* :param pkgconf_list_t* list: The `fragment list` being rendered.
* :return: the amount of bytes required to represent the `fragment list` when rendered
* :rtype: size_t
*/
size_t
pkgconf_fragment_render_len(const pkgconf_list_t *list)
static size_t
fragment_render_len(const pkgconf_list_t *list, bool escape)
{
(void) escape;
size_t out = 1; /* trailing nul */
pkgconf_node_t *node;
@ -401,21 +497,11 @@ pkgconf_fragment_render_len(const pkgconf_list_t *list)
return out;
}
/*
* !doc
*
* .. c:function:: void pkgconf_fragment_render_buf(const pkgconf_list_t *list, char *buf, size_t buflen)
*
* Renders a `fragment list` into a buffer.
*
* :param pkgconf_list_t* list: The `fragment list` being rendered.
* :param char* buf: The buffer to render the fragment list into.
* :param size_t buflen: The length of the buffer.
* :return: nothing
*/
void
pkgconf_fragment_render_buf(const pkgconf_list_t *list, char *buf, size_t buflen)
static void
fragment_render_buf(const pkgconf_list_t *list, char *buf, size_t buflen, bool escape)
{
(void) escape;
pkgconf_node_t *node;
char *bptr = buf;
@ -425,9 +511,13 @@ pkgconf_fragment_render_buf(const pkgconf_list_t *list, char *buf, size_t buflen
{
const pkgconf_fragment_t *frag = node->data;
size_t buf_remaining = buflen - (bptr - buf);
char *quoted = fragment_quote(frag);
if (pkgconf_fragment_len(frag) > buf_remaining)
if (strlen(quoted) > buf_remaining)
{
free(quoted);
break;
}
if (frag->type)
{
@ -435,15 +525,69 @@ pkgconf_fragment_render_buf(const pkgconf_list_t *list, char *buf, size_t buflen
*bptr++ = frag->type;
}
if (frag->data)
bptr += pkgconf_strlcpy(bptr, frag->data, buf_remaining);
if (quoted != NULL)
{
bptr += pkgconf_strlcpy(bptr, quoted, buf_remaining);
free(quoted);
}
*bptr++ = ' ';
if (node->next != NULL)
*bptr++ = ' ';
}
*bptr = '\0';
}
static const pkgconf_fragment_render_ops_t default_render_ops = {
.render_len = fragment_render_len,
.render_buf = fragment_render_buf
};
/*
* !doc
*
* .. c:function:: size_t pkgconf_fragment_render_len(const pkgconf_list_t *list, bool escape, const pkgconf_fragment_render_ops_t *ops)
*
* Calculates the required memory to store a `fragment list` when rendered as a string.
*
* :param pkgconf_list_t* list: The `fragment list` being rendered.
* :param bool escape: Whether or not to escape special shell characters (deprecated).
* :param pkgconf_fragment_render_ops_t* ops: An optional ops structure to use for custom renderers, else ``NULL``.
* :return: the amount of bytes required to represent the `fragment list` when rendered
* :rtype: size_t
*/
size_t
pkgconf_fragment_render_len(const pkgconf_list_t *list, bool escape, const pkgconf_fragment_render_ops_t *ops)
{
(void) escape;
ops = ops != NULL ? ops : &default_render_ops;
return ops->render_len(list, true);
}
/*
* !doc
*
* .. c:function:: void pkgconf_fragment_render_buf(const pkgconf_list_t *list, char *buf, size_t buflen, bool escape, const pkgconf_fragment_render_ops_t *ops)
*
* Renders a `fragment list` into a buffer.
*
* :param pkgconf_list_t* list: The `fragment list` being rendered.
* :param char* buf: The buffer to render the fragment list into.
* :param size_t buflen: The length of the buffer.
* :param bool escape: Whether or not to escape special shell characters (deprecated).
* :param pkgconf_fragment_render_ops_t* ops: An optional ops structure to use for custom renderers, else ``NULL``.
* :return: nothing
*/
void
pkgconf_fragment_render_buf(const pkgconf_list_t *list, char *buf, size_t buflen, bool escape, const pkgconf_fragment_render_ops_t *ops)
{
(void) escape;
ops = ops != NULL ? ops : &default_render_ops;
ops->render_buf(list, buf, buflen, true);
}
/*
* !doc
*
@ -452,16 +596,20 @@ pkgconf_fragment_render_buf(const pkgconf_list_t *list, char *buf, size_t buflen
* Allocate memory and render a `fragment list` into it.
*
* :param pkgconf_list_t* list: The `fragment list` being rendered.
* :param bool escape: Whether or not to escape special shell characters (deprecated).
* :param pkgconf_fragment_render_ops_t* ops: An optional ops structure to use for custom renderers, else ``NULL``.
* :return: An allocated string containing the rendered `fragment list`.
* :rtype: char *
*/
char *
pkgconf_fragment_render(const pkgconf_list_t *list)
pkgconf_fragment_render(const pkgconf_list_t *list, bool escape, const pkgconf_fragment_render_ops_t *ops)
{
size_t buflen = pkgconf_fragment_render_len(list);
(void) escape;
size_t buflen = pkgconf_fragment_render_len(list, true, ops);
char *buf = calloc(1, buflen);
pkgconf_fragment_render_buf(list, buf, buflen);
pkgconf_fragment_render_buf(list, buf, buflen, true, ops);
return buf;
}
@ -513,28 +661,51 @@ pkgconf_fragment_free(pkgconf_list_t *list)
/*
* !doc
*
* .. c:function:: void pkgconf_fragment_parse(const pkgconf_client_t *client, pkgconf_list_t *list, pkgconf_list_t *vars, const char *value)
* .. c:function:: bool pkgconf_fragment_parse(const pkgconf_client_t *client, pkgconf_list_t *list, pkgconf_list_t *vars, const char *value)
*
* Parse a string into a `fragment list`.
*
* :param pkgconf_client_t* client: The pkgconf client being accessed.
* :param pkgconf_list_t* list: The `fragment list` to add the fragment entries to.
* :param pkgconf_list_t* vars: A list of variables to use for variable substitution.
* :param uint flags: Any parsing flags to be aware of.
* :param char* value: The string to parse into fragments.
* :return: nothing
* :return: true on success, false on parse error
*/
void
pkgconf_fragment_parse(const pkgconf_client_t *client, pkgconf_list_t *list, pkgconf_list_t *vars, const char *value)
bool
pkgconf_fragment_parse(const pkgconf_client_t *client, pkgconf_list_t *list, pkgconf_list_t *vars, const char *value, unsigned int flags)
{
int i, argc;
int i, ret, argc;
char **argv;
char *repstr = pkgconf_tuple_parse(client, vars, value);
char *repstr = pkgconf_tuple_parse(client, vars, value, flags);
pkgconf_argv_split(repstr, &argc, &argv);
PKGCONF_TRACE(client, "post-subst: [%s] -> [%s]", value, repstr);
ret = pkgconf_argv_split(repstr, &argc, &argv);
if (ret < 0)
{
PKGCONF_TRACE(client, "unable to parse fragment string [%s]", repstr);
free(repstr);
return false;
}
for (i = 0; i < argc; i++)
pkgconf_fragment_add(client, list, argv[i]);
{
PKGCONF_TRACE(client, "processing %s", argv[i]);
if (argv[i] == NULL)
{
PKGCONF_TRACE(client, "parsed fragment string is inconsistent: argc = %d while argv[%d] == NULL", argc, i);
pkgconf_argv_free(argv);
free(repstr);
return false;
}
pkgconf_fragment_add(client, list, argv[i], flags);
}
pkgconf_argv_free(argv);
free(repstr);
return true;
}

View File

@ -13,8 +13,12 @@
* from the use of this software.
*/
#ifndef PKGCONF__ITER_H
#define PKGCONF__ITER_H
#ifndef LIBPKGCONF_ITER_H
#define LIBPKGCONF_ITER_H
#ifdef __cplusplus
extern "C" {
#endif
typedef struct pkgconf_node_ pkgconf_node_t;
@ -30,6 +34,14 @@ typedef struct {
#define PKGCONF_LIST_INITIALIZER { NULL, NULL, 0 }
static inline void
pkgconf_list_zero(pkgconf_list_t *list)
{
list->head = NULL;
list->tail = NULL;
list->length = 0;
}
static inline void
pkgconf_node_insert(pkgconf_node_t *node, void *data, pkgconf_list_t *list)
{
@ -61,7 +73,7 @@ pkgconf_node_insert_tail(pkgconf_node_t *node, void *data, pkgconf_list_t *list)
node->data = data;
if (list->head == NULL)
if (list->tail == NULL)
{
list->head = node;
list->tail = node;
@ -94,4 +106,8 @@ pkgconf_node_delete(pkgconf_node_t *node, pkgconf_list_t *list)
node->next->prev = node->prev;
}
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,19 @@
#ifndef LIBPKGCONF_LIBPKGCONF_API_H
#define LIBPKGCONF_LIBPKGCONF_API_H
/* Makefile.am specifies visibility using the libtool option -export-symbols-regex '^pkgconf_'
* Unfortunately, that is not available when building with meson, so use attributes instead.
*/
#if defined(PKGCONFIG_IS_STATIC)
# define PKGCONF_API
#elif defined(_WIN32) || defined(_WIN64)
# if defined(LIBPKGCONF_EXPORT) || defined(DLL_EXPORT)
# define PKGCONF_API __declspec(dllexport)
# else
# define PKGCONF_API __declspec(dllimport)
# endif
#else
# define PKGCONF_API __attribute__((visibility("default")))
#endif
#endif

View File

@ -16,10 +16,20 @@
#ifndef LIBPKGCONF__LIBPKGCONF_H
#define LIBPKGCONF__LIBPKGCONF_H
#include <libpkgconf/stdinc.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdbool.h>
#include <stdint.h>
#include <libpkgconf/libpkgconf-api.h>
#include <libpkgconf/iter.h>
#include <libpkgconf/bsdstubs.h>
#ifdef __cplusplus
extern "C" {
#endif
/* pkg-config uses ';' on win32 as ':' is part of path */
#ifdef _WIN32
#define PKG_CONFIG_PATH_SEP_S ";"
@ -33,6 +43,10 @@
#define PKG_DIR_SEP_S '/'
#endif
#ifdef _WIN32
#define realpath(N,R) _fullpath((R),(N),_MAX_PATH)
#endif
#define PKGCONF_BUFSIZE (65535)
typedef enum {
@ -53,6 +67,8 @@ typedef struct pkgconf_tuple_ pkgconf_tuple_t;
typedef struct pkgconf_fragment_ pkgconf_fragment_t;
typedef struct pkgconf_path_ pkgconf_path_t;
typedef struct pkgconf_client_ pkgconf_client_t;
typedef struct pkgconf_cross_personality_ pkgconf_cross_personality_t;
typedef struct pkgconf_queue_ pkgconf_queue_t;
#define PKGCONF_ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x)))
@ -65,11 +81,21 @@ typedef struct pkgconf_client_ pkgconf_client_t;
#define PKGCONF_FOREACH_LIST_ENTRY_REVERSE(tail, value) \
for ((value) = (tail); (value) != NULL; (value) = (value)->prev)
#define LIBPKGCONF_VERSION 20200
#define LIBPKGCONF_VERSION_STR "2.2.0"
struct pkgconf_queue_ {
pkgconf_node_t iter;
char *package;
};
struct pkgconf_fragment_ {
pkgconf_node_t iter;
char type;
char *data;
bool merged;
};
struct pkgconf_dependency_ {
@ -79,6 +105,12 @@ struct pkgconf_dependency_ {
pkgconf_pkg_comparator_t compare;
char *version;
pkgconf_pkg_t *parent;
pkgconf_pkg_t *match;
unsigned int flags;
int refcount;
pkgconf_client_t *owner;
};
struct pkgconf_tuple_ {
@ -86,8 +118,12 @@ struct pkgconf_tuple_ {
char *key;
char *value;
unsigned int flags;
};
#define PKGCONF_PKG_TUPLEF_OVERRIDE 0x1
struct pkgconf_path_ {
pkgconf_node_t lnode;
@ -96,15 +132,15 @@ struct pkgconf_path_ {
void *handle_device;
};
#define PKGCONF_PKG_PROPF_NONE 0x0
#define PKGCONF_PKG_PROPF_VIRTUAL 0x1
#define PKGCONF_PKG_PROPF_CACHED 0x2
#define PKGCONF_PKG_PROPF_SEEN 0x4
#define PKGCONF_PKG_PROPF_UNINSTALLED 0x8
#define PKGCONF_PKG_PROPF_NONE 0x00
#define PKGCONF_PKG_PROPF_STATIC 0x01
#define PKGCONF_PKG_PROPF_CACHED 0x02
#define PKGCONF_PKG_PROPF_UNINSTALLED 0x08
#define PKGCONF_PKG_PROPF_VIRTUAL 0x10
#define PKGCONF_PKG_PROPF_ANCESTOR 0x20
#define PKGCONF_PKG_PROPF_VISITED_PRIVATE 0x40
struct pkgconf_pkg_ {
pkgconf_node_t cache_iter;
int refcount;
char *id;
char *filename;
@ -113,13 +149,17 @@ struct pkgconf_pkg_ {
char *description;
char *url;
char *pc_filedir;
char *license;
char *maintainer;
char *copyright;
char *why;
pkgconf_list_t libs;
pkgconf_list_t libs_private;
pkgconf_list_t cflags;
pkgconf_list_t cflags_private;
pkgconf_list_t requires;
pkgconf_list_t required; /* this used to be requires but that is now a reserved keyword */
pkgconf_list_t requires_private;
pkgconf_list_t conflicts;
pkgconf_list_t provides;
@ -127,16 +167,26 @@ struct pkgconf_pkg_ {
pkgconf_list_t vars;
unsigned int flags;
pkgconf_client_t *owner;
/* these resources are owned by the package and do not need special management,
* under no circumstance attempt to allocate or free objects belonging to these pointers
*/
pkgconf_tuple_t *orig_prefix;
pkgconf_tuple_t *prefix;
uint64_t serial;
uint64_t identifier;
};
typedef bool (*pkgconf_pkg_iteration_func_t)(const pkgconf_pkg_t *pkg, void *data);
typedef void (*pkgconf_pkg_traverse_func_t)(pkgconf_client_t *client, pkgconf_pkg_t *pkg, void *data, unsigned int flags);
typedef bool (*pkgconf_queue_apply_func_t)(pkgconf_client_t *client, pkgconf_pkg_t *world, void *data, int maxdepth, unsigned int flags);
typedef bool (*pkgconf_error_handler_func_t)(const char *msg, const pkgconf_client_t *client, const void *data);
typedef void (*pkgconf_pkg_traverse_func_t)(pkgconf_client_t *client, pkgconf_pkg_t *pkg, void *data);
typedef bool (*pkgconf_queue_apply_func_t)(pkgconf_client_t *client, pkgconf_pkg_t *world, void *data, int maxdepth);
typedef bool (*pkgconf_error_handler_func_t)(const char *msg, const pkgconf_client_t *client, void *data);
struct pkgconf_client_ {
pkgconf_list_t dir_list;
pkgconf_list_t pkg_cache;
pkgconf_list_t filter_libdirs;
pkgconf_list_t filter_includedirs;
@ -144,38 +194,95 @@ struct pkgconf_client_ {
pkgconf_list_t global_vars;
void *error_handler_data;
void *warn_handler_data;
void *trace_handler_data;
pkgconf_error_handler_func_t error_handler;
pkgconf_error_handler_func_t warn_handler;
pkgconf_error_handler_func_t trace_handler;
FILE *auditf;
char *sysroot_dir;
char *buildroot_dir;
unsigned int flags;
char *prefix_varname;
bool already_sent_notice;
uint64_t serial;
uint64_t identifier;
pkgconf_pkg_t **cache_table;
size_t cache_count;
};
struct pkgconf_cross_personality_ {
const char *name;
pkgconf_list_t dir_list;
pkgconf_list_t filter_libdirs;
pkgconf_list_t filter_includedirs;
char *sysroot_dir;
bool want_default_static;
bool want_default_pure;
};
/* client.c */
void pkgconf_client_init(pkgconf_client_t *client, pkgconf_error_handler_func_t error_handler, void *error_handler_data);
pkgconf_client_t *pkgconf_client_new(pkgconf_error_handler_func_t error_handler, void *error_handler_data);
void pkgconf_client_deinit(pkgconf_client_t *client);
void pkgconf_client_free(pkgconf_client_t *client);
const char *pkgconf_client_get_sysroot_dir(const pkgconf_client_t *client);
void pkgconf_client_set_sysroot_dir(pkgconf_client_t *client, const char *sysroot_dir);
const char *pkgconf_client_get_buildroot_dir(const pkgconf_client_t *client);
void pkgconf_client_set_buildroot_dir(pkgconf_client_t *client, const char *buildroot_dir);
PKGCONF_API void pkgconf_client_init(pkgconf_client_t *client, pkgconf_error_handler_func_t error_handler, void *error_handler_data, const pkgconf_cross_personality_t *personality);
PKGCONF_API pkgconf_client_t * pkgconf_client_new(pkgconf_error_handler_func_t error_handler, void *error_handler_data, const pkgconf_cross_personality_t *personality);
PKGCONF_API void pkgconf_client_deinit(pkgconf_client_t *client);
PKGCONF_API void pkgconf_client_free(pkgconf_client_t *client);
PKGCONF_API const char *pkgconf_client_get_sysroot_dir(const pkgconf_client_t *client);
PKGCONF_API void pkgconf_client_set_sysroot_dir(pkgconf_client_t *client, const char *sysroot_dir);
PKGCONF_API const char *pkgconf_client_get_buildroot_dir(const pkgconf_client_t *client);
PKGCONF_API void pkgconf_client_set_buildroot_dir(pkgconf_client_t *client, const char *buildroot_dir);
PKGCONF_API unsigned int pkgconf_client_get_flags(const pkgconf_client_t *client);
PKGCONF_API void pkgconf_client_set_flags(pkgconf_client_t *client, unsigned int flags);
PKGCONF_API const char *pkgconf_client_get_prefix_varname(const pkgconf_client_t *client);
PKGCONF_API void pkgconf_client_set_prefix_varname(pkgconf_client_t *client, const char *prefix_varname);
PKGCONF_API pkgconf_error_handler_func_t pkgconf_client_get_warn_handler(const pkgconf_client_t *client);
PKGCONF_API void pkgconf_client_set_warn_handler(pkgconf_client_t *client, pkgconf_error_handler_func_t warn_handler, void *warn_handler_data);
PKGCONF_API pkgconf_error_handler_func_t pkgconf_client_get_error_handler(const pkgconf_client_t *client);
PKGCONF_API void pkgconf_client_set_error_handler(pkgconf_client_t *client, pkgconf_error_handler_func_t error_handler, void *error_handler_data);
PKGCONF_API pkgconf_error_handler_func_t pkgconf_client_get_trace_handler(const pkgconf_client_t *client);
PKGCONF_API void pkgconf_client_set_trace_handler(pkgconf_client_t *client, pkgconf_error_handler_func_t trace_handler, void *trace_handler_data);
PKGCONF_API void pkgconf_client_dir_list_build(pkgconf_client_t *client, const pkgconf_cross_personality_t *personality);
#define PKGCONF_IS_MODULE_SEPARATOR(c) ((c) == ',' || isspace ((unsigned int)(c)))
/* personality.c */
PKGCONF_API pkgconf_cross_personality_t *pkgconf_cross_personality_default(void);
PKGCONF_API pkgconf_cross_personality_t *pkgconf_cross_personality_find(const char *triplet);
PKGCONF_API void pkgconf_cross_personality_deinit(pkgconf_cross_personality_t *personality);
#define PKGCONF_IS_MODULE_SEPARATOR(c) ((c) == ',' || isspace ((unsigned char)(c)))
#define PKGCONF_IS_OPERATOR_CHAR(c) ((c) == '<' || (c) == '>' || (c) == '!' || (c) == '=')
#define PKGCONF_PKG_PKGF_NONE 0x000
#define PKGCONF_PKG_PKGF_SEARCH_PRIVATE 0x001
#define PKGCONF_PKG_PKGF_ENV_ONLY 0x002
#define PKGCONF_PKG_PKGF_NO_UNINSTALLED 0x004
#define PKGCONF_PKG_PKGF_SKIP_ROOT_VIRTUAL 0x008
#define PKGCONF_PKG_PKGF_MERGE_PRIVATE_FRAGMENTS 0x010
#define PKGCONF_PKG_PKGF_SKIP_CONFLICTS 0x020
#define PKGCONF_PKG_PKGF_NO_CACHE 0x040
#define PKGCONF_PKG_PKGF_SKIP_ERRORS 0x080
#define PKGCONF_PKG_PKGF_ITER_PKG_IS_PRIVATE 0x100
#define PKGCONF_PKG_PKGF_SKIP_PROVIDES 0x200
#define PKGCONF_PKG_PKGF_NONE 0x0000
#define PKGCONF_PKG_PKGF_SEARCH_PRIVATE 0x0001
#define PKGCONF_PKG_PKGF_ENV_ONLY 0x0002
#define PKGCONF_PKG_PKGF_NO_UNINSTALLED 0x0004
#define PKGCONF_PKG_PKGF_SKIP_ROOT_VIRTUAL 0x0008
#define PKGCONF_PKG_PKGF_MERGE_PRIVATE_FRAGMENTS 0x0010
#define PKGCONF_PKG_PKGF_SKIP_CONFLICTS 0x0020
#define PKGCONF_PKG_PKGF_NO_CACHE 0x0040
#define PKGCONF_PKG_PKGF_SKIP_ERRORS 0x0080
#define PKGCONF_PKG_PKGF_ITER_PKG_IS_PRIVATE 0x0100
#define PKGCONF_PKG_PKGF_SKIP_PROVIDES 0x0200
#define PKGCONF_PKG_PKGF_REDEFINE_PREFIX 0x0400
#define PKGCONF_PKG_PKGF_DONT_RELOCATE_PATHS 0x0800
#define PKGCONF_PKG_PKGF_SIMPLIFY_ERRORS 0x1000
#define PKGCONF_PKG_PKGF_DONT_FILTER_INTERNAL_CFLAGS 0x2000
#define PKGCONF_PKG_PKGF_DONT_MERGE_SPECIAL_FRAGMENTS 0x4000
#define PKGCONF_PKG_PKGF_FDO_SYSROOT_RULES 0x8000
#define PKGCONF_PKG_PKGF_PKGCONF1_SYSROOT_RULES 0x10000
#define PKGCONF_PKG_DEPF_INTERNAL 0x1
#define PKGCONF_PKG_DEPF_PRIVATE 0x2
#define PKGCONF_PKG_ERRF_OK 0x0
#define PKGCONF_PKG_ERRF_PACKAGE_NOT_FOUND 0x1
@ -183,7 +290,6 @@ void pkgconf_client_set_buildroot_dir(pkgconf_client_t *client, const char *buil
#define PKGCONF_PKG_ERRF_PACKAGE_CONFLICT 0x4
#define PKGCONF_PKG_ERRF_DEPGRAPH_BREAK 0x8
/* pkg.c */
#if defined(__GNUC__) || defined(__INTEL_COMPILER)
#define PRINTFLIKE(fmtarg, firstvararg) \
__attribute__((__format__ (__printf__, fmtarg, firstvararg)))
@ -194,88 +300,129 @@ void pkgconf_client_set_buildroot_dir(pkgconf_client_t *client, const char *buil
#define DEPRECATED
#endif /* defined(__INTEL_COMPILER) || defined(__GNUC__) */
bool pkgconf_error(const pkgconf_client_t *client, const char *format, ...) PRINTFLIKE(2, 3);
bool pkgconf_default_error_handler(const char *msg, const pkgconf_client_t *client, const void *data);
/* parser.c */
typedef void (*pkgconf_parser_operand_func_t)(void *data, const size_t lineno, const char *key, const char *value);
typedef void (*pkgconf_parser_warn_func_t)(void *data, const char *fmt, ...);
pkgconf_pkg_t *pkgconf_pkg_ref(const pkgconf_client_t *client, pkgconf_pkg_t *pkg);
void pkgconf_pkg_unref(pkgconf_client_t *client, pkgconf_pkg_t *pkg);
void pkgconf_pkg_free(pkgconf_client_t *client, pkgconf_pkg_t *pkg);
pkgconf_pkg_t *pkgconf_pkg_find(pkgconf_client_t *client, const char *name, unsigned int flags);
unsigned int pkgconf_pkg_traverse(pkgconf_client_t *client, pkgconf_pkg_t *root, pkgconf_pkg_traverse_func_t func, void *data, int maxdepth, unsigned int flags);
unsigned int pkgconf_pkg_verify_graph(pkgconf_client_t *client, pkgconf_pkg_t *root, int depth, unsigned int flags);
pkgconf_pkg_t *pkgconf_pkg_verify_dependency(pkgconf_client_t *client, pkgconf_dependency_t *pkgdep, unsigned int flags, unsigned int *eflags);
const char *pkgconf_pkg_get_comparator(const pkgconf_dependency_t *pkgdep);
unsigned int pkgconf_pkg_cflags(pkgconf_client_t *client, pkgconf_pkg_t *root, pkgconf_list_t *list, int maxdepth, unsigned int flags);
unsigned int pkgconf_pkg_libs(pkgconf_client_t *client, pkgconf_pkg_t *root, pkgconf_list_t *list, int maxdepth, unsigned int flags);
pkgconf_pkg_comparator_t pkgconf_pkg_comparator_lookup_by_name(const char *name);
pkgconf_pkg_t *pkgconf_builtin_pkg_get(const char *name);
PKGCONF_API void pkgconf_parser_parse(FILE *f, void *data, const pkgconf_parser_operand_func_t *ops, const pkgconf_parser_warn_func_t warnfunc, const char *filename);
int pkgconf_compare_version(const char *a, const char *b);
pkgconf_pkg_t *pkgconf_scan_all(pkgconf_client_t *client, void *ptr, pkgconf_pkg_iteration_func_t func);
void pkgconf_pkg_dir_list_build(pkgconf_client_t *client, unsigned int flags);
/* pkg.c */
PKGCONF_API bool pkgconf_error(const pkgconf_client_t *client, const char *format, ...) PRINTFLIKE(2, 3);
PKGCONF_API bool pkgconf_warn(const pkgconf_client_t *client, const char *format, ...) PRINTFLIKE(2, 3);
PKGCONF_API bool pkgconf_trace(const pkgconf_client_t *client, const char *filename, size_t lineno, const char *funcname, const char *format, ...) PRINTFLIKE(5, 6);
PKGCONF_API bool pkgconf_default_error_handler(const char *msg, const pkgconf_client_t *client, void *data);
#ifndef PKGCONF_LITE
#if defined(__GNUC__) || defined(__INTEL_COMPILER)
#define PKGCONF_TRACE(client, ...) do { \
pkgconf_trace(client, __FILE__, __LINE__, __PRETTY_FUNCTION__, __VA_ARGS__); \
} while (0)
#else
#define PKGCONF_TRACE(client, ...) do { \
pkgconf_trace(client, __FILE__, __LINE__, __func__, __VA_ARGS__); \
} while (0)
#endif
#else
#define PKGCONF_TRACE(client, ...)
#endif
PKGCONF_API pkgconf_pkg_t *pkgconf_pkg_ref(pkgconf_client_t *client, pkgconf_pkg_t *pkg);
PKGCONF_API void pkgconf_pkg_unref(pkgconf_client_t *client, pkgconf_pkg_t *pkg);
PKGCONF_API void pkgconf_pkg_free(pkgconf_client_t *client, pkgconf_pkg_t *pkg);
PKGCONF_API pkgconf_pkg_t *pkgconf_pkg_find(pkgconf_client_t *client, const char *name);
PKGCONF_API unsigned int pkgconf_pkg_traverse(pkgconf_client_t *client, pkgconf_pkg_t *root, pkgconf_pkg_traverse_func_t func, void *data, int maxdepth, unsigned int skip_flags);
PKGCONF_API unsigned int pkgconf_pkg_verify_graph(pkgconf_client_t *client, pkgconf_pkg_t *root, int depth);
PKGCONF_API pkgconf_pkg_t *pkgconf_pkg_verify_dependency(pkgconf_client_t *client, pkgconf_dependency_t *pkgdep, unsigned int *eflags);
PKGCONF_API const char *pkgconf_pkg_get_comparator(const pkgconf_dependency_t *pkgdep);
PKGCONF_API unsigned int pkgconf_pkg_cflags(pkgconf_client_t *client, pkgconf_pkg_t *root, pkgconf_list_t *list, int maxdepth);
PKGCONF_API unsigned int pkgconf_pkg_libs(pkgconf_client_t *client, pkgconf_pkg_t *root, pkgconf_list_t *list, int maxdepth);
PKGCONF_API pkgconf_pkg_comparator_t pkgconf_pkg_comparator_lookup_by_name(const char *name);
PKGCONF_API pkgconf_pkg_t *pkgconf_builtin_pkg_get(const char *name);
PKGCONF_API int pkgconf_compare_version(const char *a, const char *b);
PKGCONF_API pkgconf_pkg_t *pkgconf_scan_all(pkgconf_client_t *client, void *ptr, pkgconf_pkg_iteration_func_t func);
/* parse.c */
pkgconf_pkg_t *pkgconf_pkg_new_from_file(const pkgconf_client_t *client, const char *path, FILE *f);
void pkgconf_dependency_parse_str(pkgconf_list_t *deplist_head, const char *depends);
void pkgconf_dependency_parse(const pkgconf_client_t *client, pkgconf_pkg_t *pkg, pkgconf_list_t *deplist_head, const char *depends);
void pkgconf_dependency_append(pkgconf_list_t *list, pkgconf_dependency_t *tail);
void pkgconf_dependency_free(pkgconf_list_t *list);
pkgconf_dependency_t *pkgconf_dependency_add(pkgconf_list_t *list, const char *package, const char *version, pkgconf_pkg_comparator_t compare);
PKGCONF_API pkgconf_pkg_t *pkgconf_pkg_new_from_file(pkgconf_client_t *client, const char *path, FILE *f, unsigned int flags);
PKGCONF_API void pkgconf_dependency_parse_str(pkgconf_client_t *client, pkgconf_list_t *deplist_head, const char *depends, unsigned int flags);
PKGCONF_API void pkgconf_dependency_parse(pkgconf_client_t *client, pkgconf_pkg_t *pkg, pkgconf_list_t *deplist_head, const char *depends, unsigned int flags);
PKGCONF_API void pkgconf_dependency_append(pkgconf_list_t *list, pkgconf_dependency_t *tail);
PKGCONF_API void pkgconf_dependency_free(pkgconf_list_t *list);
PKGCONF_API void pkgconf_dependency_free_one(pkgconf_dependency_t *dep);
PKGCONF_API pkgconf_dependency_t *pkgconf_dependency_add(pkgconf_client_t *client, pkgconf_list_t *list, const char *package, const char *version, pkgconf_pkg_comparator_t compare, unsigned int flags);
PKGCONF_API pkgconf_dependency_t *pkgconf_dependency_ref(pkgconf_client_t *client, pkgconf_dependency_t *dep);
PKGCONF_API void pkgconf_dependency_unref(pkgconf_client_t *client, pkgconf_dependency_t *dep);
PKGCONF_API pkgconf_dependency_t *pkgconf_dependency_copy(pkgconf_client_t *client, const pkgconf_dependency_t *dep);
/* argvsplit.c */
int pkgconf_argv_split(const char *src, int *argc, char ***argv);
void pkgconf_argv_free(char **argv);
PKGCONF_API int pkgconf_argv_split(const char *src, int *argc, char ***argv);
PKGCONF_API void pkgconf_argv_free(char **argv);
/* fragment.c */
typedef bool (*pkgconf_fragment_filter_func_t)(const pkgconf_client_t *client, const pkgconf_fragment_t *frag, unsigned int flags);
void pkgconf_fragment_parse(const pkgconf_client_t *client, pkgconf_list_t *list, pkgconf_list_t *vars, const char *value);
void pkgconf_fragment_add(const pkgconf_client_t *client, pkgconf_list_t *list, const char *string);
void pkgconf_fragment_copy(pkgconf_list_t *list, const pkgconf_fragment_t *base, unsigned int flags, bool is_private);
void pkgconf_fragment_delete(pkgconf_list_t *list, pkgconf_fragment_t *node);
void pkgconf_fragment_free(pkgconf_list_t *list);
void pkgconf_fragment_filter(const pkgconf_client_t *client, pkgconf_list_t *dest, pkgconf_list_t *src, pkgconf_fragment_filter_func_t filter_func, unsigned int flags);
size_t pkgconf_fragment_render_len(const pkgconf_list_t *list);
void pkgconf_fragment_render_buf(const pkgconf_list_t *list, char *buf, size_t len);
char *pkgconf_fragment_render(const pkgconf_list_t *list);
bool pkgconf_fragment_has_system_dir(const pkgconf_client_t *client, const pkgconf_fragment_t *frag);
typedef struct pkgconf_fragment_render_ops_ {
size_t (*render_len)(const pkgconf_list_t *list, bool escape);
void (*render_buf)(const pkgconf_list_t *list, char *buf, size_t len, bool escape);
} pkgconf_fragment_render_ops_t;
typedef bool (*pkgconf_fragment_filter_func_t)(const pkgconf_client_t *client, const pkgconf_fragment_t *frag, void *data);
PKGCONF_API bool pkgconf_fragment_parse(const pkgconf_client_t *client, pkgconf_list_t *list, pkgconf_list_t *vars, const char *value, unsigned int flags);
PKGCONF_API void pkgconf_fragment_add(const pkgconf_client_t *client, pkgconf_list_t *list, const char *string, unsigned int flags);
PKGCONF_API void pkgconf_fragment_copy(const pkgconf_client_t *client, pkgconf_list_t *list, const pkgconf_fragment_t *base, bool is_private);
PKGCONF_API void pkgconf_fragment_copy_list(const pkgconf_client_t *client, pkgconf_list_t *list, const pkgconf_list_t *base);
PKGCONF_API void pkgconf_fragment_delete(pkgconf_list_t *list, pkgconf_fragment_t *node);
PKGCONF_API void pkgconf_fragment_free(pkgconf_list_t *list);
PKGCONF_API void pkgconf_fragment_filter(const pkgconf_client_t *client, pkgconf_list_t *dest, pkgconf_list_t *src, pkgconf_fragment_filter_func_t filter_func, void *data);
PKGCONF_API size_t pkgconf_fragment_render_len(const pkgconf_list_t *list, bool escape, const pkgconf_fragment_render_ops_t *ops);
PKGCONF_API void pkgconf_fragment_render_buf(const pkgconf_list_t *list, char *buf, size_t len, bool escape, const pkgconf_fragment_render_ops_t *ops);
PKGCONF_API char *pkgconf_fragment_render(const pkgconf_list_t *list, bool escape, const pkgconf_fragment_render_ops_t *ops);
PKGCONF_API bool pkgconf_fragment_has_system_dir(const pkgconf_client_t *client, const pkgconf_fragment_t *frag);
/* fileio.c */
char *pkgconf_fgetline(char *line, size_t size, FILE *stream);
PKGCONF_API char *pkgconf_fgetline(char *line, size_t size, FILE *stream);
/* tuple.c */
pkgconf_tuple_t *pkgconf_tuple_add(const pkgconf_client_t *client, pkgconf_list_t *parent, const char *key, const char *value, bool parse);
char *pkgconf_tuple_find(const pkgconf_client_t *client, pkgconf_list_t *list, const char *key);
char *pkgconf_tuple_parse(const pkgconf_client_t *client, pkgconf_list_t *list, const char *value);
void pkgconf_tuple_free(pkgconf_list_t *list);
void pkgconf_tuple_free_entry(pkgconf_tuple_t *tuple, pkgconf_list_t *list);
void pkgconf_tuple_add_global(pkgconf_client_t *client, const char *key, const char *value);
char *pkgconf_tuple_find_global(const pkgconf_client_t *client, const char *key);
void pkgconf_tuple_free_global(pkgconf_client_t *client);
void pkgconf_tuple_define_global(pkgconf_client_t *client, const char *kv);
PKGCONF_API pkgconf_tuple_t *pkgconf_tuple_add(const pkgconf_client_t *client, pkgconf_list_t *parent, const char *key, const char *value, bool parse, unsigned int flags);
PKGCONF_API char *pkgconf_tuple_find(const pkgconf_client_t *client, pkgconf_list_t *list, const char *key);
PKGCONF_API char *pkgconf_tuple_parse(const pkgconf_client_t *client, pkgconf_list_t *list, const char *value, unsigned int flags);
PKGCONF_API void pkgconf_tuple_free(pkgconf_list_t *list);
PKGCONF_API void pkgconf_tuple_free_entry(pkgconf_tuple_t *tuple, pkgconf_list_t *list);
PKGCONF_API void pkgconf_tuple_add_global(pkgconf_client_t *client, const char *key, const char *value);
PKGCONF_API char *pkgconf_tuple_find_global(const pkgconf_client_t *client, const char *key);
PKGCONF_API void pkgconf_tuple_free_global(pkgconf_client_t *client);
PKGCONF_API void pkgconf_tuple_define_global(pkgconf_client_t *client, const char *kv);
/* queue.c */
void pkgconf_queue_push(pkgconf_list_t *list, const char *package);
bool pkgconf_queue_compile(pkgconf_client_t *client, pkgconf_pkg_t *world, pkgconf_list_t *list);
void pkgconf_queue_free(pkgconf_list_t *list);
bool pkgconf_queue_apply(pkgconf_client_t *client, pkgconf_list_t *list, pkgconf_queue_apply_func_t func, int maxdepth, unsigned int flags, void *data);
bool pkgconf_queue_validate(pkgconf_client_t *client, pkgconf_list_t *list, int maxdepth, unsigned int flags);
PKGCONF_API void pkgconf_queue_push(pkgconf_list_t *list, const char *package);
PKGCONF_API bool pkgconf_queue_compile(pkgconf_client_t *client, pkgconf_pkg_t *world, pkgconf_list_t *list);
PKGCONF_API bool pkgconf_queue_solve(pkgconf_client_t *client, pkgconf_list_t *list, pkgconf_pkg_t *world, int maxdepth);
PKGCONF_API void pkgconf_queue_free(pkgconf_list_t *list);
PKGCONF_API bool pkgconf_queue_apply(pkgconf_client_t *client, pkgconf_list_t *list, pkgconf_queue_apply_func_t func, int maxdepth, void *data);
PKGCONF_API bool pkgconf_queue_validate(pkgconf_client_t *client, pkgconf_list_t *list, int maxdepth);
PKGCONF_API void pkgconf_solution_free(pkgconf_client_t *client, pkgconf_pkg_t *world);
/* cache.c */
pkgconf_pkg_t *pkgconf_cache_lookup(const pkgconf_client_t *client, const char *id);
void pkgconf_cache_add(pkgconf_client_t *client, pkgconf_pkg_t *pkg);
void pkgconf_cache_remove(pkgconf_client_t *client, pkgconf_pkg_t *pkg);
void pkgconf_cache_free(pkgconf_client_t *client);
PKGCONF_API pkgconf_pkg_t *pkgconf_cache_lookup(pkgconf_client_t *client, const char *id);
PKGCONF_API void pkgconf_cache_add(pkgconf_client_t *client, pkgconf_pkg_t *pkg);
PKGCONF_API void pkgconf_cache_remove(pkgconf_client_t *client, pkgconf_pkg_t *pkg);
PKGCONF_API void pkgconf_cache_free(pkgconf_client_t *client);
/* audit.c */
void pkgconf_audit_set_log(pkgconf_client_t *client, FILE *auditf);
void pkgconf_audit_log(pkgconf_client_t *client, const char *format, ...) PRINTFLIKE(2, 3);
void pkgconf_audit_log_dependency(pkgconf_client_t *client, const pkgconf_pkg_t *dep, const pkgconf_dependency_t *depnode);
PKGCONF_API void pkgconf_audit_set_log(pkgconf_client_t *client, FILE *auditf);
PKGCONF_API void pkgconf_audit_log(pkgconf_client_t *client, const char *format, ...) PRINTFLIKE(2, 3);
PKGCONF_API void pkgconf_audit_log_dependency(pkgconf_client_t *client, const pkgconf_pkg_t *dep, const pkgconf_dependency_t *depnode);
/* path.c */
void pkgconf_path_add(const char *text, pkgconf_list_t *dirlist, bool filter);
size_t pkgconf_path_split(const char *text, pkgconf_list_t *dirlist, bool filter);
size_t pkgconf_path_build_from_environ(const char *environ, const char *fallback, pkgconf_list_t *dirlist, bool filter);
bool pkgconf_path_match_list(const char *path, const pkgconf_list_t *dirlist);
void pkgconf_path_free(pkgconf_list_t *dirlist);
PKGCONF_API void pkgconf_path_add(const char *text, pkgconf_list_t *dirlist, bool filter);
PKGCONF_API void pkgconf_path_prepend(const char *text, pkgconf_list_t *dirlist, bool filter);
PKGCONF_API size_t pkgconf_path_split(const char *text, pkgconf_list_t *dirlist, bool filter);
PKGCONF_API size_t pkgconf_path_build_from_environ(const char *envvarname, const char *fallback, pkgconf_list_t *dirlist, bool filter);
PKGCONF_API bool pkgconf_path_match_list(const char *path, const pkgconf_list_t *dirlist);
PKGCONF_API void pkgconf_path_free(pkgconf_list_t *dirlist);
PKGCONF_API bool pkgconf_path_relocate(char *buf, size_t buflen);
PKGCONF_API void pkgconf_path_copy_list(pkgconf_list_t *dst, const pkgconf_list_t *src);
#ifdef __cplusplus
}
#endif
#endif

12
libpkgconf/meson.build Normal file
View File

@ -0,0 +1,12 @@
configure_file(input : 'config.h.meson',
output : 'config.h',
configuration : cdata)
install_headers('libpkgconf.h',
'stdinc.h',
'iter.h',
'bsdstubs.h',
'libpkgconf-api.h',
subdir : 'pkgconf/libpkgconf')

106
libpkgconf/parser.c Normal file
View File

@ -0,0 +1,106 @@
/*
* parser.c
* rfc822 message parser
*
* Copyright (c) 2018 pkgconf authors (see AUTHORS).
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* This software is provided 'as is' and without any warranty, express or
* implied. In no event shall the authors be liable for any damages arising
* from the use of this software.
*/
#include <libpkgconf/config.h>
#include <libpkgconf/stdinc.h>
#include <libpkgconf/libpkgconf.h>
/*
* !doc
*
* .. c:function:: pkgconf_pkg_t *pkgconf_pkg_new_from_file(const pkgconf_client_t *client, const char *filename, FILE *f)
*
* Parse a .pc file into a pkgconf_pkg_t object structure.
*
* :param pkgconf_client_t* client: The pkgconf client object to use for dependency resolution.
* :param char* filename: The filename of the package file (including full path).
* :param FILE* f: The file object to read from.
* :returns: A ``pkgconf_pkg_t`` object which contains the package data.
* :rtype: pkgconf_pkg_t *
*/
void
pkgconf_parser_parse(FILE *f, void *data, const pkgconf_parser_operand_func_t *ops, const pkgconf_parser_warn_func_t warnfunc, const char *filename)
{
char readbuf[PKGCONF_BUFSIZE];
size_t lineno = 0;
while (pkgconf_fgetline(readbuf, PKGCONF_BUFSIZE, f) != NULL)
{
char op, *p, *key, *value;
bool warned_key_whitespace = false, warned_value_whitespace = false;
lineno++;
p = readbuf;
while (*p && isspace((unsigned char)*p))
p++;
if (*p && p != readbuf)
{
warnfunc(data, "%s:" SIZE_FMT_SPECIFIER ": warning: whitespace encountered while parsing key section\n",
filename, lineno);
warned_key_whitespace = true;
}
key = p;
while (*p && (isalpha((unsigned char)*p) || isdigit((unsigned char)*p) || *p == '_' || *p == '.'))
p++;
if (!isalpha((unsigned char)*key) &&
!isdigit((unsigned char)*p))
continue;
while (*p && isspace((unsigned char)*p))
{
if (!warned_key_whitespace)
{
warnfunc(data, "%s:" SIZE_FMT_SPECIFIER ": warning: whitespace encountered while parsing key section\n",
filename, lineno);
warned_key_whitespace = true;
}
/* set to null to avoid trailing spaces in key */
*p = '\0';
p++;
}
op = *p;
if (*p != '\0')
{
*p = '\0';
p++;
}
while (*p && isspace((unsigned char)*p))
p++;
value = p;
p = value + (strlen(value) - 1);
while (*p && isspace((unsigned char) *p) && p > value)
{
if (!warned_value_whitespace && op == '=')
{
warnfunc(data, "%s:" SIZE_FMT_SPECIFIER ": warning: trailing whitespace encountered while parsing value section\n",
filename, lineno);
warned_value_whitespace = true;
}
*p = '\0';
p--;
}
if (ops[(unsigned char) op])
ops[(unsigned char) op](data, lineno, key, value);
}
fclose(f);
}

View File

@ -13,10 +13,11 @@
* from the use of this software.
*/
#include <libpkgconf/libpkgconf.h>
#include <libpkgconf/config.h>
#include <libpkgconf/stdinc.h>
#include <libpkgconf/libpkgconf.h>
#ifdef HAVE_SYS_STAT_H
#if defined(HAVE_SYS_STAT_H) && ! defined(_WIN32)
# include <sys/stat.h>
# define PKGCONF_CACHE_INODES
#endif
@ -35,7 +36,7 @@ path_list_contains_entry(const char *text, pkgconf_list_t *dirlist)
pkgconf_path_t *pn = n->data;
#ifdef PKGCONF_CACHE_INODES
if (((dev_t) pn->handle_device) == st->st_dev && ((ino_t) pn->handle_path) == st->st_ino)
if (pn->handle_device == (void *)(intptr_t)st->st_dev && pn->handle_path == (void *)(intptr_t)st->st_ino)
return true;
#endif
@ -57,6 +58,51 @@ path_list_contains_entry(const char *text, pkgconf_list_t *dirlist)
* variables.
*/
static pkgconf_path_t *
prepare_path_node(const char *text, pkgconf_list_t *dirlist, bool filter)
{
pkgconf_path_t *node;
char path[PKGCONF_ITEM_SIZE];
pkgconf_strlcpy(path, text, sizeof path);
pkgconf_path_relocate(path, sizeof path);
#ifdef PKGCONF_CACHE_INODES
struct stat st;
if (filter)
{
if (lstat(path, &st) == -1)
return NULL;
if (S_ISLNK(st.st_mode))
{
char pathbuf[PKGCONF_ITEM_SIZE * 4];
char *linkdest = realpath(path, pathbuf);
if (linkdest != NULL && stat(linkdest, &st) == -1)
return NULL;
}
if (path_list_contains_entry(path, dirlist, &st))
return NULL;
}
#else
if (filter && path_list_contains_entry(path, dirlist))
return NULL;
#endif
node = calloc(1, sizeof(pkgconf_path_t));
node->path = strdup(path);
#ifdef PKGCONF_CACHE_INODES
if (filter) {
node->handle_path = (void *)(intptr_t) st.st_ino;
node->handle_device = (void *)(intptr_t) st.st_dev;
}
#endif
return node;
}
/*
* !doc
*
@ -72,30 +118,35 @@ path_list_contains_entry(const char *text, pkgconf_list_t *dirlist)
void
pkgconf_path_add(const char *text, pkgconf_list_t *dirlist, bool filter)
{
pkgconf_path_t *node;
#ifdef PKGCONF_CACHE_INODES
struct stat st;
if (stat(text, &st) == -1)
pkgconf_path_t *node = prepare_path_node(text, dirlist, filter);
if (node == NULL)
return;
if (filter && path_list_contains_entry(text, dirlist, &st))
return;
#else
if (filter && path_list_contains_entry(text, dirlist))
return;
#endif
node = calloc(sizeof(pkgconf_path_t), 1);
node->path = strdup(text);
#ifdef PKGCONF_CACHE_INODES
node->handle_path = (void *)(intptr_t) st.st_ino;
node->handle_device = (void *)(intptr_t) st.st_dev;
#endif
pkgconf_node_insert_tail(&node->lnode, node, dirlist);
}
/*
* !doc
*
* .. c:function:: void pkgconf_path_prepend(const char *text, pkgconf_list_t *dirlist)
*
* Prepends a path node to a path list. If the path is already in the list, do nothing.
*
* :param char* text: The path text to add as a path node.
* :param pkgconf_list_t* dirlist: The path list to add the path node to.
* :param bool filter: Whether to perform duplicate filtering.
* :return: nothing
*/
void
pkgconf_path_prepend(const char *text, pkgconf_list_t *dirlist, bool filter)
{
pkgconf_path_t *node = prepare_path_node(text, dirlist, filter);
if (node == NULL)
return;
pkgconf_node_insert(&node->lnode, node, dirlist);
}
/*
* !doc
*
@ -133,12 +184,12 @@ pkgconf_path_split(const char *text, pkgconf_list_t *dirlist, bool filter)
/*
* !doc
*
* .. c:function:: size_t pkgconf_path_build_from_environ(const char *environ, const char *fallback, pkgconf_list_t *dirlist)
* .. c:function:: size_t pkgconf_path_build_from_environ(const char *envvarname, const char *fallback, pkgconf_list_t *dirlist)
*
* Adds the paths specified in an environment variable to a path list. If the environment variable is not set,
* an optional default set of paths is added.
*
* :param char* environ: The environment variable to look up.
* :param char* envvarname: The environment variable to look up.
* :param char* fallback: The fallback paths to use if the environment variable is not set.
* :param pkgconf_list_t* dirlist: The path list to add the path nodes to.
* :param bool filter: Whether to perform duplicate filtering.
@ -146,11 +197,11 @@ pkgconf_path_split(const char *text, pkgconf_list_t *dirlist, bool filter)
* :rtype: size_t
*/
size_t
pkgconf_path_build_from_environ(const char *environ, const char *fallback, pkgconf_list_t *dirlist, bool filter)
pkgconf_path_build_from_environ(const char *envvarname, const char *fallback, pkgconf_list_t *dirlist, bool filter)
{
const char *data;
data = getenv(environ);
data = getenv(envvarname);
if (data != NULL)
return pkgconf_path_split(data, dirlist, filter);
@ -177,18 +228,56 @@ bool
pkgconf_path_match_list(const char *path, const pkgconf_list_t *dirlist)
{
pkgconf_node_t *n = NULL;
char relocated[PKGCONF_ITEM_SIZE];
const char *cpath = path;
pkgconf_strlcpy(relocated, path, sizeof relocated);
if (pkgconf_path_relocate(relocated, sizeof relocated))
cpath = relocated;
PKGCONF_FOREACH_LIST_ENTRY(dirlist->head, n)
{
pkgconf_path_t *pnode = n->data;
if (!strcmp(pnode->path, path))
if (!strcmp(pnode->path, cpath))
return true;
}
return false;
}
/*
* !doc
*
* .. c:function:: void pkgconf_path_copy_list(pkgconf_list_t *dst, const pkgconf_list_t *src)
*
* Copies a path list to another path list.
*
* :param pkgconf_list_t* dst: The path list to copy to.
* :param pkgconf_list_t* src: The path list to copy from.
* :return: nothing
*/
void
pkgconf_path_copy_list(pkgconf_list_t *dst, const pkgconf_list_t *src)
{
pkgconf_node_t *n;
PKGCONF_FOREACH_LIST_ENTRY(src->head, n)
{
pkgconf_path_t *srcpath = n->data, *path;
path = calloc(1, sizeof(pkgconf_path_t));
path->path = strdup(srcpath->path);
#ifdef PKGCONF_CACHE_INODES
path->handle_path = srcpath->handle_path;
path->handle_device = srcpath->handle_device;
#endif
pkgconf_node_insert_tail(&path->lnode, path, dst);
}
}
/*
* !doc
*
@ -211,4 +300,70 @@ pkgconf_path_free(pkgconf_list_t *dirlist)
free(pnode->path);
free(pnode);
}
pkgconf_list_zero(dirlist);
}
static char *
normpath(const char *path)
{
if (!path)
return NULL;
char *copy = strdup(path);
if (NULL == copy)
return NULL;
char *ptr = copy;
for (int ii = 0; copy[ii]; ii++)
{
*ptr++ = path[ii];
if ('/' == path[ii])
{
ii++;
while ('/' == path[ii])
ii++;
ii--;
}
}
*ptr = '\0';
return copy;
}
/*
* !doc
*
* .. c:function:: bool pkgconf_path_relocate(char *buf, size_t buflen)
*
* Relocates a path, possibly calling normpath() on it.
*
* :param char* buf: The path to relocate.
* :param size_t buflen: The buffer length the path is contained in.
* :return: true on success, false on error
* :rtype: bool
*/
bool
pkgconf_path_relocate(char *buf, size_t buflen)
{
#ifdef _WIN32
char *ti;
#endif
char *tmpbuf;
if ((tmpbuf = normpath(buf)) != NULL)
{
size_t tmpbuflen = strlen(tmpbuf);
if (tmpbuflen > buflen)
{
free(tmpbuf);
return false;
}
pkgconf_strlcpy(buf, tmpbuf, buflen);
free(tmpbuf);
}
return true;
}

339
libpkgconf/personality.c Normal file
View File

@ -0,0 +1,339 @@
/*
* personality.c
* libpkgconf cross-compile personality database
*
* Copyright (c) 2018 pkgconf authors (see AUTHORS).
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* This software is provided 'as is' and without any warranty, express or
* implied. In no event shall the authors be liable for any damages arising
* from the use of this software.
*/
#include <libpkgconf/config.h>
#include <libpkgconf/stdinc.h>
#include <libpkgconf/libpkgconf.h>
/*
* !doc
*
* libpkgconf `personality` module
* =========================
*/
#ifdef _WIN32
# define strcasecmp _stricmp
#endif
/*
* Increment each time the default personality is inited, decrement each time
* it's deinited. Whenever it is 0, then the deinit frees the personality. In
* that case an additional call to init will create it anew.
*/
static unsigned default_personality_init = 0;
static pkgconf_cross_personality_t default_personality = {
.name = "default",
#ifdef _WIN32
.want_default_static = true,
.want_default_pure = true,
#endif
};
static inline void
build_default_search_path(pkgconf_list_t* dirlist)
{
#ifdef _WIN32
char namebuf[MAX_PATH];
char outbuf[MAX_PATH];
char *p;
int sizepath = GetModuleFileName(NULL, namebuf, sizeof namebuf);
char * winslash;
namebuf[sizepath] = '\0';
while ((winslash = strchr (namebuf, '\\')) != NULL)
{
*winslash = '/';
}
p = strrchr(namebuf, '/');
if (p == NULL)
pkgconf_path_split(PKG_DEFAULT_PATH, dirlist, true);
*p = '\0';
pkgconf_strlcpy(outbuf, namebuf, sizeof outbuf);
pkgconf_strlcat(outbuf, "/", sizeof outbuf);
pkgconf_strlcat(outbuf, "../lib/pkgconfig", sizeof outbuf);
pkgconf_path_add(outbuf, dirlist, true);
pkgconf_strlcpy(outbuf, namebuf, sizeof outbuf);
pkgconf_strlcat(outbuf, "/", sizeof outbuf);
pkgconf_strlcat(outbuf, "../share/pkgconfig", sizeof outbuf);
pkgconf_path_add(outbuf, dirlist, true);
#elif __HAIKU__
char **paths;
size_t count;
if (find_paths(B_FIND_PATH_DEVELOP_LIB_DIRECTORY, "pkgconfig", &paths, &count) == B_OK) {
for (size_t i = 0; i < count; i++)
pkgconf_path_add(paths[i], dirlist, true);
free(paths);
paths = NULL;
}
if (find_paths(B_FIND_PATH_DATA_DIRECTORY, "pkgconfig", &paths, &count) == B_OK) {
for (size_t i = 0; i < count; i++)
pkgconf_path_add(paths[i], dirlist, true);
free(paths);
paths = NULL;
}
#else
pkgconf_path_split(PKG_DEFAULT_PATH, dirlist, true);
#endif
}
/*
* !doc
*
* .. c:function:: const pkgconf_cross_personality_t *pkgconf_cross_personality_default(void)
*
* Returns the default cross-compile personality.
*
* Not thread safe.
*
* :rtype: pkgconf_cross_personality_t*
* :return: the default cross-compile personality
*/
pkgconf_cross_personality_t *
pkgconf_cross_personality_default(void)
{
if (default_personality_init) {
++default_personality_init;
return &default_personality;
}
build_default_search_path(&default_personality.dir_list);
pkgconf_path_split(SYSTEM_LIBDIR, &default_personality.filter_libdirs, false);
pkgconf_path_split(SYSTEM_INCLUDEDIR, &default_personality.filter_includedirs, false);
++default_personality_init;
return &default_personality;
}
/*
* !doc
*
* .. c:function:: void pkgconf_cross_personality_deinit(pkgconf_cross_personality_t *)
*
* Decrements the count of default cross personality instances.
*
* Not thread safe.
*
* :rtype: void
*/
void
pkgconf_cross_personality_deinit(pkgconf_cross_personality_t *personality)
{
if (--default_personality_init == 0) {
pkgconf_path_free(&personality->dir_list);
pkgconf_path_free(&personality->filter_libdirs);
pkgconf_path_free(&personality->filter_includedirs);
}
}
#ifndef PKGCONF_LITE
static bool
valid_triplet(const char *triplet)
{
const char *c = triplet;
for (; *c; c++)
if (!isalnum((unsigned char)*c) && *c != '-' && *c != '_')
return false;
return true;
}
typedef void (*personality_keyword_func_t)(pkgconf_cross_personality_t *p, const char *keyword, const size_t lineno, const ptrdiff_t offset, char *value);
typedef struct {
const char *keyword;
const personality_keyword_func_t func;
const ptrdiff_t offset;
} personality_keyword_pair_t;
static void
personality_bool_func(pkgconf_cross_personality_t *p, const char *keyword, const size_t lineno, const ptrdiff_t offset, char *value)
{
(void) keyword;
(void) lineno;
bool *dest = (bool *)((char *) p + offset);
*dest = strcasecmp(value, "true") || strcasecmp(value, "yes") || *value == '1';
}
static void
personality_copy_func(pkgconf_cross_personality_t *p, const char *keyword, const size_t lineno, const ptrdiff_t offset, char *value)
{
(void) keyword;
(void) lineno;
char **dest = (char **)((char *) p + offset);
*dest = strdup(value);
}
static void
personality_fragment_func(pkgconf_cross_personality_t *p, const char *keyword, const size_t lineno, const ptrdiff_t offset, char *value)
{
(void) keyword;
(void) lineno;
pkgconf_list_t *dest = (pkgconf_list_t *)((char *) p + offset);
pkgconf_path_split(value, dest, false);
}
/* keep in alphabetical order! */
static const personality_keyword_pair_t personality_keyword_pairs[] = {
{"DefaultSearchPaths", personality_fragment_func, offsetof(pkgconf_cross_personality_t, dir_list)},
{"SysrootDir", personality_copy_func, offsetof(pkgconf_cross_personality_t, sysroot_dir)},
{"SystemIncludePaths", personality_fragment_func, offsetof(pkgconf_cross_personality_t, filter_includedirs)},
{"SystemLibraryPaths", personality_fragment_func, offsetof(pkgconf_cross_personality_t, filter_libdirs)},
{"Triplet", personality_copy_func, offsetof(pkgconf_cross_personality_t, name)},
{"WantDefaultPure", personality_bool_func, offsetof(pkgconf_cross_personality_t, want_default_pure)},
{"WantDefaultStatic", personality_bool_func, offsetof(pkgconf_cross_personality_t, want_default_static)},
};
static int
personality_keyword_pair_cmp(const void *key, const void *ptr)
{
const personality_keyword_pair_t *pair = ptr;
return strcasecmp(key, pair->keyword);
}
static void
personality_keyword_set(pkgconf_cross_personality_t *p, const size_t lineno, const char *keyword, char *value)
{
const personality_keyword_pair_t *pair = bsearch(keyword,
personality_keyword_pairs, PKGCONF_ARRAY_SIZE(personality_keyword_pairs),
sizeof(personality_keyword_pair_t), personality_keyword_pair_cmp);
if (pair == NULL || pair->func == NULL)
return;
pair->func(p, keyword, lineno, pair->offset, value);
}
static const pkgconf_parser_operand_func_t personality_parser_ops[256] = {
[':'] = (pkgconf_parser_operand_func_t) personality_keyword_set
};
static void personality_warn_func(void *p, const char *fmt, ...) PRINTFLIKE(2, 3);
static void
personality_warn_func(void *p, const char *fmt, ...)
{
va_list va;
(void) p;
va_start(va, fmt);
vfprintf(stderr, fmt, va);
va_end(va);
}
static pkgconf_cross_personality_t *
load_personality_with_path(const char *path, const char *triplet, bool datadir)
{
char pathbuf[PKGCONF_ITEM_SIZE];
FILE *f;
pkgconf_cross_personality_t *p;
/* if triplet is null, assume that path is a direct path to the personality file */
if (triplet == NULL)
pkgconf_strlcpy(pathbuf, path, sizeof pathbuf);
else if (datadir)
snprintf(pathbuf, sizeof pathbuf, "%s/pkgconfig/personality.d/%s.personality", path, triplet);
else
snprintf(pathbuf, sizeof pathbuf, "%s/%s.personality", path, triplet);
f = fopen(pathbuf, "r");
if (f == NULL)
return NULL;
p = calloc(1, sizeof(pkgconf_cross_personality_t));
if (triplet != NULL)
p->name = strdup(triplet);
pkgconf_parser_parse(f, p, personality_parser_ops, personality_warn_func, pathbuf);
return p;
}
/*
* !doc
*
* .. c:function:: pkgconf_cross_personality_t *pkgconf_cross_personality_find(const char *triplet)
*
* Attempts to find a cross-compile personality given a triplet.
*
* :rtype: pkgconf_cross_personality_t*
* :return: the default cross-compile personality
*/
pkgconf_cross_personality_t *
pkgconf_cross_personality_find(const char *triplet)
{
pkgconf_list_t plist = PKGCONF_LIST_INITIALIZER;
pkgconf_node_t *n;
pkgconf_cross_personality_t *out = NULL;
#if ! defined(_WIN32) && ! defined(__HAIKU__)
char pathbuf[PKGCONF_ITEM_SIZE];
const char *envvar;
#endif
out = load_personality_with_path(triplet, NULL, false);
if (out != NULL)
return out;
if (!valid_triplet(triplet))
return NULL;
#if ! defined(_WIN32) && ! defined(__HAIKU__)
envvar = getenv("XDG_DATA_HOME");
if (envvar != NULL)
pkgconf_path_add(envvar, &plist, true);
else {
envvar = getenv("HOME");
if (envvar != NULL) {
pkgconf_strlcpy(pathbuf, envvar, sizeof pathbuf);
pkgconf_strlcat(pathbuf, "/.local/share", sizeof pathbuf);
pkgconf_path_add(pathbuf, &plist, true);
}
}
pkgconf_path_build_from_environ("XDG_DATA_DIRS", "/usr/local/share" PKG_CONFIG_PATH_SEP_S "/usr/share", &plist, true);
PKGCONF_FOREACH_LIST_ENTRY(plist.head, n)
{
pkgconf_path_t *pn = n->data;
out = load_personality_with_path(pn->path, triplet, true);
if (out != NULL)
goto finish;
}
pkgconf_path_free(&plist);
#endif
pkgconf_path_split(PERSONALITY_PATH, &plist, true);
PKGCONF_FOREACH_LIST_ENTRY(plist.head, n)
{
pkgconf_path_t *pn = n->data;
out = load_personality_with_path(pn->path, triplet, false);
if (out != NULL)
goto finish;
}
finish:
pkgconf_path_free(&plist);
return out != NULL ? out : pkgconf_cross_personality_default();
}
#endif

File diff suppressed because it is too large Load Diff

View File

@ -13,6 +13,7 @@
* from the use of this software.
*/
#include <libpkgconf/stdinc.h>
#include <libpkgconf/libpkgconf.h>
/*
@ -28,11 +29,6 @@
* Using the `queue` module functions is the recommended way of working with dependency graphs.
*/
typedef struct {
pkgconf_node_t iter;
char *package;
} pkgconf_queue_t;
/*
* !doc
*
@ -47,7 +43,7 @@ typedef struct {
void
pkgconf_queue_push(pkgconf_list_t *list, const char *package)
{
pkgconf_queue_t *pkgq = calloc(sizeof(pkgconf_queue_t), 1);
pkgconf_queue_t *pkgq = calloc(1, sizeof(pkgconf_queue_t));
pkgq->package = strdup(package);
pkgconf_node_insert_tail(&pkgq->iter, pkgq, list);
@ -76,10 +72,10 @@ pkgconf_queue_compile(pkgconf_client_t *client, pkgconf_pkg_t *world, pkgconf_li
pkgconf_queue_t *pkgq;
pkgq = iter->data;
pkgconf_dependency_parse(client, world, &world->requires, pkgq->package);
pkgconf_dependency_parse(client, world, &world->required, pkgq->package, 0);
}
return (world->requires.head != NULL);
return (world->required.head != NULL);
}
/*
@ -106,88 +102,301 @@ pkgconf_queue_free(pkgconf_list_t *list)
}
}
static inline unsigned int
pkgconf_queue_verify(pkgconf_client_t *client, pkgconf_pkg_t *world, pkgconf_list_t *list, int maxdepth, unsigned int flags)
static void
pkgconf_queue_mark_public(pkgconf_client_t *client, pkgconf_pkg_t *pkg, void *data)
{
if (!pkgconf_queue_compile(client, world, list))
return PKGCONF_PKG_ERRF_DEPGRAPH_BREAK;
if (pkg->flags & PKGCONF_PKG_PROPF_VISITED_PRIVATE)
{
pkgconf_list_t *list = data;
pkgconf_node_t *node;
return pkgconf_pkg_verify_graph(client, world, maxdepth, flags);
PKGCONF_FOREACH_LIST_ENTRY(list->head, node)
{
pkgconf_dependency_t *dep = node->data;
if (dep->match == pkg)
dep->flags &= ~PKGCONF_PKG_DEPF_PRIVATE;
}
pkg->flags &= ~PKGCONF_PKG_PROPF_VISITED_PRIVATE;
PKGCONF_TRACE(client, "%s: updated, public", pkg->id);
}
}
static unsigned int
pkgconf_queue_collect_dependencies_main(pkgconf_client_t *client,
pkgconf_pkg_t *root,
void *data,
int maxdepth);
static inline unsigned int
pkgconf_queue_collect_dependencies_walk(pkgconf_client_t *client,
pkgconf_list_t *deplist,
void *data,
int depth)
{
unsigned int eflags = PKGCONF_PKG_ERRF_OK;
pkgconf_node_t *node;
pkgconf_pkg_t *world = data;
PKGCONF_FOREACH_LIST_ENTRY_REVERSE(deplist->tail, node)
{
pkgconf_dependency_t *dep = node->data;
pkgconf_dependency_t *flattened_dep;
pkgconf_pkg_t *pkg = dep->match;
if (*dep->package == '\0')
continue;
if (pkg == NULL)
{
PKGCONF_TRACE(client, "WTF: unmatched dependency %p <%s>", dep, dep->package);
abort();
}
if (pkg->serial == client->serial)
continue;
if (client->flags & PKGCONF_PKG_PKGF_ITER_PKG_IS_PRIVATE)
pkg->flags |= PKGCONF_PKG_PROPF_VISITED_PRIVATE;
else
pkg->flags &= ~PKGCONF_PKG_PROPF_VISITED_PRIVATE;
eflags |= pkgconf_queue_collect_dependencies_main(client, pkg, data, depth - 1);
flattened_dep = pkgconf_dependency_copy(client, dep);
pkgconf_node_insert(&flattened_dep->iter, flattened_dep, &world->required);
}
return eflags;
}
static unsigned int
pkgconf_queue_collect_dependencies_main(pkgconf_client_t *client,
pkgconf_pkg_t *root,
void *data,
int maxdepth)
{
unsigned int eflags = PKGCONF_PKG_ERRF_OK;
if (maxdepth == 0)
return eflags;
/* Short-circuit if we have already visited this node.
*/
if (root->serial == client->serial)
return eflags;
root->serial = client->serial;
if (client->flags & PKGCONF_PKG_PKGF_SEARCH_PRIVATE)
{
PKGCONF_TRACE(client, "%s: collecting private dependencies, level %d", root->id, maxdepth);
/* XXX: ugly */
const unsigned int saved_flags = client->flags;
client->flags |= PKGCONF_PKG_PKGF_ITER_PKG_IS_PRIVATE;
eflags = pkgconf_queue_collect_dependencies_walk(client, &root->requires_private, data, maxdepth);
client->flags = saved_flags;
if (eflags != PKGCONF_PKG_ERRF_OK)
return eflags;
}
PKGCONF_TRACE(client, "%s: collecting public dependencies, level %d", root->id, maxdepth);
eflags = pkgconf_queue_collect_dependencies_walk(client, &root->required, data, maxdepth);
if (eflags != PKGCONF_PKG_ERRF_OK)
return eflags;
PKGCONF_TRACE(client, "%s: finished, %s", root->id, (root->flags & PKGCONF_PKG_PROPF_VISITED_PRIVATE) ? "private" : "public");
return eflags;
}
static inline unsigned int
pkgconf_queue_collect_dependencies(pkgconf_client_t *client,
pkgconf_pkg_t *root,
void *data,
int maxdepth)
{
++client->serial;
return pkgconf_queue_collect_dependencies_main(client, root, data, maxdepth);
}
static inline unsigned int
pkgconf_queue_verify(pkgconf_client_t *client, pkgconf_pkg_t *world, pkgconf_list_t *list, int maxdepth)
{
unsigned int result;
const unsigned int saved_flags = client->flags;
pkgconf_pkg_t initial_world = {
.id = "user:request",
.realname = "virtual world package",
.flags = PKGCONF_PKG_PROPF_STATIC | PKGCONF_PKG_PROPF_VIRTUAL,
};
if (!pkgconf_queue_compile(client, &initial_world, list))
{
pkgconf_solution_free(client, &initial_world);
return PKGCONF_PKG_ERRF_DEPGRAPH_BREAK;
}
PKGCONF_TRACE(client, "solving");
result = pkgconf_pkg_traverse(client, &initial_world, NULL, NULL, maxdepth, 0);
if (result != PKGCONF_PKG_ERRF_OK)
{
pkgconf_solution_free(client, &initial_world);
return result;
}
PKGCONF_TRACE(client, "flattening");
result = pkgconf_queue_collect_dependencies(client, &initial_world, world, maxdepth);
if (result != PKGCONF_PKG_ERRF_OK)
{
pkgconf_solution_free(client, &initial_world);
return result;
}
if (client->flags & PKGCONF_PKG_PKGF_SEARCH_PRIVATE)
{
PKGCONF_TRACE(client, "marking public deps");
client->flags &= ~PKGCONF_PKG_PKGF_SEARCH_PRIVATE;
client->flags |= PKGCONF_PKG_PKGF_SKIP_CONFLICTS;
result = pkgconf_pkg_traverse(client, &initial_world, pkgconf_queue_mark_public, &world->required, maxdepth, 0);
client->flags = saved_flags;
if (result != PKGCONF_PKG_ERRF_OK)
{
pkgconf_solution_free(client, &initial_world);
return result;
}
}
/* free the initial solution */
pkgconf_solution_free(client, &initial_world);
return PKGCONF_PKG_ERRF_OK;
}
/*
* !doc
*
* .. c:function:: void pkgconf_queue_apply(pkgconf_client_t *client, pkgconf_list_t *list, pkgconf_queue_apply_func_t func, int maxdepth, unsigned int flags, void *data)
* .. c:function:: void pkgconf_solution_free(pkgconf_client_t *client, pkgconf_pkg_t *world, int maxdepth)
*
* Removes references to package nodes contained in a solution.
*
* :param pkgconf_client_t* client: The pkgconf client object to use for dependency resolution.
* :param pkgconf_pkg_t* world: The root for the generated dependency graph. Should have PKGCONF_PKG_PROPF_VIRTUAL flag.
* :returns: nothing
*/
void
pkgconf_solution_free(pkgconf_client_t *client, pkgconf_pkg_t *world)
{
(void) client;
if (world->flags & PKGCONF_PKG_PROPF_VIRTUAL)
{
pkgconf_dependency_free(&world->required);
pkgconf_dependency_free(&world->requires_private);
}
}
/*
* !doc
*
* .. c:function:: bool pkgconf_queue_solve(pkgconf_client_t *client, pkgconf_list_t *list, pkgconf_pkg_t *world, int maxdepth)
*
* Solves and flattens the dependency graph for the supplied dependency list.
*
* :param pkgconf_client_t* client: The pkgconf client object to use for dependency resolution.
* :param pkgconf_list_t* list: The list of dependency requests to consider.
* :param pkgconf_pkg_t* world: The root for the generated dependency graph, provided by the caller. Should have PKGCONF_PKG_PROPF_VIRTUAL flag.
* :param int maxdepth: The maximum allowed depth for the dependency resolver. A depth of -1 means unlimited.
* :returns: true if the dependency resolver found a solution, otherwise false.
* :rtype: bool
*/
bool
pkgconf_queue_solve(pkgconf_client_t *client, pkgconf_list_t *list, pkgconf_pkg_t *world, int maxdepth)
{
/* if maxdepth is one, then we will not traverse deeper than our virtual package. */
if (!maxdepth)
maxdepth = -1;
return pkgconf_queue_verify(client, world, list, maxdepth) == PKGCONF_PKG_ERRF_OK;
}
/*
* !doc
*
* .. c:function:: void pkgconf_queue_apply(pkgconf_client_t *client, pkgconf_list_t *list, pkgconf_queue_apply_func_t func, int maxdepth, void *data)
*
* Attempt to compile a dependency resolution queue into a dependency resolution problem, then attempt to solve the problem and
* feed the solution to a callback function if a complete dependency graph is found.
*
* This function should not be used in new code. Use pkgconf_queue_solve instead.
*
* :param pkgconf_client_t* client: The pkgconf client object to use for dependency resolution.
* :param pkgconf_list_t* list: The list of dependency requests to consider.
* :param pkgconf_queue_apply_func_t func: The callback function to call if a solution is found by the dependency resolver.
* :param int maxdepth: The maximum allowed depth for the dependency resolver. A depth of -1 means unlimited.
* :param uint flags: A bitfield of flags that is passed to the dependency resolver, optionally modifying it's behaviour.
* :param void* data: An opaque pointer which is passed to the callback function.
* :returns: true if the dependency resolver found a solution, otherwise false.
* :rtype: bool
*/
bool
pkgconf_queue_apply(pkgconf_client_t *client, pkgconf_list_t *list, pkgconf_queue_apply_func_t func, int maxdepth, unsigned int flags, void *data)
pkgconf_queue_apply(pkgconf_client_t *client, pkgconf_list_t *list, pkgconf_queue_apply_func_t func, int maxdepth, void *data)
{
bool ret = false;
pkgconf_pkg_t world = {
.id = "virtual:world",
.realname = "virtual world package",
.flags = PKGCONF_PKG_PROPF_VIRTUAL,
.flags = PKGCONF_PKG_PROPF_STATIC | PKGCONF_PKG_PROPF_VIRTUAL,
};
/* if maxdepth is one, then we will not traverse deeper than our virtual package. */
if (!maxdepth)
maxdepth = -1;
if (pkgconf_queue_verify(client, &world, list, maxdepth, flags) != PKGCONF_PKG_ERRF_OK)
return false;
if (!pkgconf_queue_solve(client, list, &world, maxdepth))
goto cleanup;
if (!func(client, &world, data, maxdepth, flags))
{
pkgconf_pkg_free(client, &world);
return false;
}
/* the world dependency set is flattened after it is returned from pkgconf_queue_verify */
if (!func(client, &world, data, maxdepth))
goto cleanup;
ret = true;
cleanup:
pkgconf_pkg_free(client, &world);
return true;
return ret;
}
/*
* !doc
*
* .. c:function:: void pkgconf_queue_validate(pkgconf_client_t *client, pkgconf_list_t *list, pkgconf_queue_apply_func_t func, int maxdepth, unsigned int flags, void *data)
* .. c:function:: void pkgconf_queue_validate(pkgconf_client_t *client, pkgconf_list_t *list, pkgconf_queue_apply_func_t func, int maxdepth, void *data)
*
* Attempt to compile a dependency resolution queue into a dependency resolution problem, then attempt to solve the problem.
*
* :param pkgconf_client_t* client: The pkgconf client object to use for dependency resolution.
* :param pkgconf_list_t* list: The list of dependency requests to consider.
* :param int maxdepth: The maximum allowed depth for the dependency resolver. A depth of -1 means unlimited.
* :param uint flags: A bitfield of flags that is passed to the dependency resolver, optionally modifying it's behaviour.
* :returns: true if the dependency resolver found a solution, otherwise false.
* :rtype: bool
*/
bool
pkgconf_queue_validate(pkgconf_client_t *client, pkgconf_list_t *list, int maxdepth, unsigned int flags)
pkgconf_queue_validate(pkgconf_client_t *client, pkgconf_list_t *list, int maxdepth)
{
bool retval = true;
pkgconf_pkg_t world = {
.id = "virtual:world",
.realname = "virtual world package",
.flags = PKGCONF_PKG_PROPF_VIRTUAL,
.flags = PKGCONF_PKG_PROPF_STATIC | PKGCONF_PKG_PROPF_VIRTUAL,
};
/* if maxdepth is one, then we will not traverse deeper than our virtual package. */
if (!maxdepth)
maxdepth = -1;
if (pkgconf_queue_verify(client, &world, list, maxdepth, flags) != PKGCONF_PKG_ERRF_OK)
if (pkgconf_queue_verify(client, &world, list, maxdepth) != PKGCONF_PKG_ERRF_OK)
retval = false;
pkgconf_pkg_free(client, &world);

View File

@ -13,10 +13,9 @@
* from the use of this software.
*/
#ifndef __STDINC_H
#define __STDINC_H
#ifndef LIBPKGCONF_STDINC_H
#define LIBPKGCONF_STDINC_H
#define _GNU_SOURCE
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
@ -24,10 +23,7 @@
#include <stdbool.h>
#include <stdarg.h>
#include <string.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdint.h>
#ifdef _WIN32
@ -35,8 +31,40 @@
# include <windows.h>
# include <malloc.h>
# define PATH_DEV_NULL "nul"
# ifdef _WIN64
# define SIZE_FMT_SPECIFIER "%I64u"
# else
# define SIZE_FMT_SPECIFIER "%u"
# endif
# ifndef ssize_t
# ifndef __MINGW32__
# include <BaseTsd.h>
# else
# include <basetsd.h>
# endif
# define ssize_t SSIZE_T
# endif
# ifndef __MINGW32__
# include "win-dirent.h"
# else
# include <dirent.h>
# endif
# define PKGCONF_ITEM_SIZE (_MAX_PATH + 1024)
#else
# define PATH_DEV_NULL "/dev/null"
# define SIZE_FMT_SPECIFIER "%zu"
# ifdef __HAIKU__
# include <FindDirectory.h>
# endif
# include <dirent.h>
# include <unistd.h>
# include <limits.h>
# include <strings.h>
# ifdef PATH_MAX
# define PKGCONF_ITEM_SIZE (PATH_MAX + 1024)
# else
# define PKGCONF_ITEM_SIZE (4096 + 1024)
# endif
#endif
#endif

View File

@ -13,6 +13,7 @@
* from the use of this software.
*/
#include <libpkgconf/stdinc.h>
#include <libpkgconf/libpkgconf.h>
/*
@ -44,7 +45,23 @@
void
pkgconf_tuple_add_global(pkgconf_client_t *client, const char *key, const char *value)
{
pkgconf_tuple_add(client, &client->global_vars, key, value, false);
pkgconf_tuple_add(client, &client->global_vars, key, value, false, 0);
}
static pkgconf_tuple_t *
lookup_global_tuple(const pkgconf_client_t *client, const char *key)
{
pkgconf_node_t *node;
PKGCONF_FOREACH_LIST_ENTRY(client->global_vars.head, node)
{
pkgconf_tuple_t *tuple = node->data;
if (!strcmp(tuple->key, key))
return tuple;
}
return NULL;
}
/*
@ -62,17 +79,13 @@ pkgconf_tuple_add_global(pkgconf_client_t *client, const char *key, const char *
char *
pkgconf_tuple_find_global(const pkgconf_client_t *client, const char *key)
{
pkgconf_node_t *node;
pkgconf_tuple_t *tuple;
PKGCONF_FOREACH_LIST_ENTRY(client->global_vars.head, node)
{
pkgconf_tuple_t *tuple = node->data;
tuple = lookup_global_tuple(client, key);
if (tuple == NULL)
return NULL;
if (!strcmp(tuple->key, key))
return tuple->value;
}
return NULL;
return tuple->value;
}
/*
@ -107,13 +120,18 @@ pkgconf_tuple_define_global(pkgconf_client_t *client, const char *kv)
{
char *workbuf = strdup(kv);
char *value;
pkgconf_tuple_t *tuple;
value = strchr(workbuf, '=');
if (value == NULL)
goto out;
*value++ = '\0';
pkgconf_tuple_add_global(client, workbuf, value);
tuple = pkgconf_tuple_add(client, &client->global_vars, workbuf, value, false, 0);
if (tuple != NULL)
tuple->flags = PKGCONF_PKG_TUPLEF_OVERRIDE;
out:
free(workbuf);
}
@ -135,6 +153,70 @@ pkgconf_tuple_find_delete(pkgconf_list_t *list, const char *key)
}
}
static char *
dequote(const char *value)
{
char *buf = calloc(1, (strlen(value) + 1) * 2);
char *bptr = buf;
const char *i;
char quote = 0;
if (*value == '\'' || *value == '"')
quote = *value;
for (i = value; *i != '\0'; i++)
{
if (*i == '\\' && quote && *(i + 1) == quote)
{
i++;
*bptr++ = *i;
}
else if (*i != quote)
*bptr++ = *i;
}
return buf;
}
static const char *
find_sysroot(const pkgconf_client_t *client, pkgconf_list_t *vars)
{
const char *sysroot_dir;
sysroot_dir = pkgconf_tuple_find(client, vars, "pc_sysrootdir");
if (sysroot_dir == NULL)
sysroot_dir = client->sysroot_dir;
return sysroot_dir;
}
static bool
should_rewrite_sysroot(const pkgconf_client_t *client, pkgconf_list_t *vars, const char *buf, unsigned int flags)
{
const char *sysroot_dir;
if (flags & PKGCONF_PKG_PROPF_UNINSTALLED && !(client->flags & PKGCONF_PKG_PKGF_FDO_SYSROOT_RULES))
return false;
sysroot_dir = find_sysroot(client, vars);
if (sysroot_dir == NULL)
return false;
if (*buf != '/')
return false;
if (!strcmp(sysroot_dir, "/"))
return false;
if (strlen(buf) <= strlen(sysroot_dir))
return false;
if (strstr(buf + strlen(sysroot_dir), sysroot_dir) == NULL)
return false;
return true;
}
/*
* !doc
*
@ -151,20 +233,27 @@ pkgconf_tuple_find_delete(pkgconf_list_t *list, const char *key)
* :rtype: pkgconf_tuple_t *
*/
pkgconf_tuple_t *
pkgconf_tuple_add(const pkgconf_client_t *client, pkgconf_list_t *list, const char *key, const char *value, bool parse)
pkgconf_tuple_add(const pkgconf_client_t *client, pkgconf_list_t *list, const char *key, const char *value, bool parse, unsigned int flags)
{
pkgconf_tuple_t *tuple = calloc(sizeof(pkgconf_tuple_t), 1);
char *dequote_value;
pkgconf_tuple_t *tuple = calloc(1, sizeof(pkgconf_tuple_t));
pkgconf_tuple_find_delete(list, key);
dequote_value = dequote(value);
tuple->key = strdup(key);
if (parse)
tuple->value = pkgconf_tuple_parse(client, list, value);
tuple->value = pkgconf_tuple_parse(client, list, dequote_value, flags);
else
tuple->value = strdup(value);
tuple->value = strdup(dequote_value);
PKGCONF_TRACE(client, "adding tuple to @%p: %s => %s (parsed? %d)", list, key, tuple->value, parse);
pkgconf_node_insert(&tuple->iter, tuple, list);
free(dequote_value);
return tuple;
}
@ -185,10 +274,11 @@ char *
pkgconf_tuple_find(const pkgconf_client_t *client, pkgconf_list_t *list, const char *key)
{
pkgconf_node_t *node;
char *res;
pkgconf_tuple_t *global_tuple;
if ((res = pkgconf_tuple_find_global(client, key)) != NULL)
return res;
global_tuple = lookup_global_tuple(client, key);
if (global_tuple != NULL && global_tuple->flags & PKGCONF_PKG_TUPLEF_OVERRIDE)
return global_tuple->value;
PKGCONF_FOREACH_LIST_ENTRY(list->head, node)
{
@ -198,31 +288,39 @@ pkgconf_tuple_find(const pkgconf_client_t *client, pkgconf_list_t *list, const c
return tuple->value;
}
if (global_tuple != NULL)
return global_tuple->value;
return NULL;
}
/*
* !doc
*
* .. c:function:: char *pkgconf_tuple_parse(const pkgconf_client_t *client, pkgconf_list_t *vars, const char *value)
* .. c:function:: char *pkgconf_tuple_parse(const pkgconf_client_t *client, pkgconf_list_t *vars, const char *value, unsigned int flags)
*
* Parse an expression for variable substitution.
*
* :param pkgconf_client_t* client: The pkgconf client object to access.
* :param pkgconf_list_t* list: The variable list to search for variables (along side the global variable list).
* :param char* value: The ``key=value`` string to parse.
* :param uint flags: Any flags to consider while parsing.
* :return: the variable data with any variables substituted
* :rtype: char *
*/
char *
pkgconf_tuple_parse(const pkgconf_client_t *client, pkgconf_list_t *vars, const char *value)
pkgconf_tuple_parse(const pkgconf_client_t *client, pkgconf_list_t *vars, const char *value, unsigned int flags)
{
char buf[PKGCONF_BUFSIZE];
const char *ptr;
char *bptr = buf;
if (*value == '/' && client->sysroot_dir != NULL && strncmp(value, client->sysroot_dir, strlen(client->sysroot_dir)))
bptr += pkgconf_strlcpy(buf, client->sysroot_dir, sizeof buf);
if (!(client->flags & PKGCONF_PKG_PKGF_FDO_SYSROOT_RULES) &&
(!(flags & PKGCONF_PKG_PROPF_UNINSTALLED) || (client->flags & PKGCONF_PKG_PKGF_PKGCONF1_SYSROOT_RULES)))
{
if (*value == '/' && client->sysroot_dir != NULL && strncmp(value, client->sysroot_dir, strlen(client->sysroot_dir)))
bptr += pkgconf_strlcpy(buf, client->sysroot_dir, sizeof buf);
}
for (ptr = value; *ptr != '\0' && bptr - buf < PKGCONF_BUFSIZE; ptr++)
{
@ -230,7 +328,8 @@ pkgconf_tuple_parse(const pkgconf_client_t *client, pkgconf_list_t *vars, const
*bptr++ = *ptr;
else if (*(ptr + 1) == '{')
{
static char varname[PKGCONF_BUFSIZE];
char varname[PKGCONF_ITEM_SIZE];
char *vend = varname + PKGCONF_ITEM_SIZE - 1;
char *vptr = varname;
const char *pptr;
char *kv, *parsekv;
@ -240,7 +339,15 @@ pkgconf_tuple_parse(const pkgconf_client_t *client, pkgconf_list_t *vars, const
for (pptr = ptr + 2; *pptr != '\0'; pptr++)
{
if (*pptr != '}')
*vptr++ = *pptr;
{
if (vptr < vend)
*vptr++ = *pptr;
else
{
*vptr = '\0';
break;
}
}
else
{
*vptr = '\0';
@ -248,12 +355,23 @@ pkgconf_tuple_parse(const pkgconf_client_t *client, pkgconf_list_t *vars, const
}
}
PKGCONF_TRACE(client, "lookup tuple %s", varname);
size_t remain = PKGCONF_BUFSIZE - (bptr - buf);
ptr += (pptr - ptr);
kv = pkgconf_tuple_find_global(client, varname);
if (kv != NULL)
{
strncpy(bptr, kv, PKGCONF_BUFSIZE - (bptr - buf));
bptr += strlen(kv);
size_t nlen = pkgconf_strlcpy(bptr, kv, remain);
if (nlen > remain)
{
pkgconf_warn(client, "warning: truncating very long variable to 64KB\n");
bptr = buf + (PKGCONF_BUFSIZE - 1);
break;
}
bptr += nlen;
}
else
{
@ -261,12 +379,21 @@ pkgconf_tuple_parse(const pkgconf_client_t *client, pkgconf_list_t *vars, const
if (kv != NULL)
{
parsekv = pkgconf_tuple_parse(client, vars, kv);
strncpy(bptr, parsekv, PKGCONF_BUFSIZE - (bptr - buf));
bptr += strlen(parsekv);
size_t nlen;
parsekv = pkgconf_tuple_parse(client, vars, kv, flags);
nlen = pkgconf_strlcpy(bptr, parsekv, remain);
free(parsekv);
if (nlen > remain)
{
pkgconf_warn(client, "warning: truncating very long variable to 64KB\n");
bptr = buf + (PKGCONF_BUFSIZE - 1);
break;
}
bptr += nlen;
}
}
}
@ -274,6 +401,34 @@ pkgconf_tuple_parse(const pkgconf_client_t *client, pkgconf_list_t *vars, const
*bptr = '\0';
/*
* Sigh. Somebody actually attempted to use freedesktop.org pkg-config's broken sysroot support,
* which was written by somebody who did not understand how sysroots are supposed to work. This
* results in an incorrect path being built as the sysroot will be prepended twice, once explicitly,
* and once by variable expansion (the pkgconf approach). We could simply make ${pc_sysrootdir} blank,
* but sometimes it is necessary to know the explicit sysroot path for other reasons, so we can't really
* do that.
*
* As a result, we check to see if ${pc_sysrootdir} is prepended as a duplicate, and if so, remove the
* prepend. This allows us to handle both our approach and the broken freedesktop.org implementation's
* approach. Because a path can be shorter than ${pc_sysrootdir}, we do some checks first to ensure it's
* safe to skip ahead in the string to scan for our sysroot dir.
*
* Finally, we call pkgconf_path_relocate() to clean the path of spurious elements.
*
* New in 1.9: Only attempt to rewrite the sysroot if we are not processing an uninstalled package.
*/
if (should_rewrite_sysroot(client, vars, buf, flags))
{
char cleanpath[PKGCONF_ITEM_SIZE];
const char *sysroot_dir = find_sysroot(client, vars);
pkgconf_strlcpy(cleanpath, buf + strlen(sysroot_dir), sizeof cleanpath);
pkgconf_path_relocate(cleanpath, sizeof cleanpath);
return strdup(cleanpath);
}
return strdup(buf);
}
@ -316,4 +471,6 @@ pkgconf_tuple_free(pkgconf_list_t *list)
PKGCONF_FOREACH_LIST_ENTRY_SAFE(list->head, next, node)
pkgconf_tuple_free_entry(node->data, list);
pkgconf_list_zero(list);
}

1028
libpkgconf/win-dirent.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,53 @@
# ===========================================================================
# https://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT])
#
# DESCRIPTION
#
# Check whether the given FLAG works with the current language's compiler
# or gives an error. (Warnings, however, are ignored)
#
# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on
# success/failure.
#
# If EXTRA-FLAGS is defined, it is added to the current language's default
# flags (e.g. CFLAGS) when the check is done. The check is thus made with
# the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to
# force the compiler to issue an error when a bad flag is given.
#
# INPUT gives an alternative input source to AC_COMPILE_IFELSE.
#
# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this
# macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG.
#
# LICENSE
#
# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
#
# Copying and distribution of this file, with or without modification, are
# permitted in any medium without royalty provided the copyright notice
# and this notice are preserved. This file is offered as-is, without any
# warranty.
#serial 6
AC_DEFUN([AX_CHECK_COMPILE_FLAG],
[AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF
AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl
AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [
ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS
_AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1"
AC_COMPILE_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])],
[AS_VAR_SET(CACHEVAR,[yes])],
[AS_VAR_SET(CACHEVAR,[no])])
_AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags])
AS_VAR_IF(CACHEVAR,yes,
[m4_default([$2], :)],
[m4_default([$3], :)])
AS_VAR_POPDEF([CACHEVAR])dnl
])dnl AX_CHECK_COMPILE_FLAGS

1067
main.c

File diff suppressed because it is too large Load Diff

178
man/pc.5 Normal file
View File

@ -0,0 +1,178 @@
.\" Copyright (c) 2017 pkgconf authors (see AUTHORS).
.\"
.\" Permission to use, copy, modify, and/or distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
.\" copyright notice and this permission notice appear in all copies.
.\"
.\" This software is provided 'as is' and without any warranty, express or
.\" implied. In no event shall the authors be liable for any damages arising
.\" from the use of this software.
.Dd December 15, 2017
.Dt PC 5
.Os
.Sh NAME
.Nm file.pc
.Nd pkg-config file format
.Sh DESCRIPTION
pkg-config files provide a useful mechanism for storing various information
about libraries and packages on a given system.
Information stored by
.Nm .pc
files include compiler and linker flags necessary to use a given library, as
well as any other relevant metadata.
.Pp
These
.Nm .pc
files are processed by a utility called
.Nm pkg-config ,
of which
.Nm pkgconf
is an implementation.
.\"
.Ss FILE SYNTAX
The
.Nm .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.
.\"
.Ss VARIABLES
.\"
Variable definitions start with an alphanumeric string, followed by an equal sign,
and then the value the variable should contain.
.Pp
Variable references are always written as "${variable}".
It is possible to escape literal "${" as "$${".
.\"
.Ss 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.
.Pp
There are three types of property:
.\"
.Bl -tag -width indent
.\"
.It Literal
The property will be set to the text of the value.
.\"
.It Dependency List
The property will be set to a list of dependencies parsed from the
text.
Dependency lists are defined by this ABNF syntax:
.Bd -literal
package-list = *WSP *( package-spec *( package-sep ) )
package-sep = WSP / ","
.\"
package-spec = package-key [ ver-op package-version ]
ver-op = "<" / "<=" / "=" / "!=" / ">=" / ">"
.Ed
.\"
.It 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.
.\"
.El
.Ss PROPERTY KEYWORDS
.Bl -tag -width indent
.\"
.It Name
The displayed name of the package.
(mandatory; literal)
.It Version
The version of the package.
(mandatory; literal)
.It Description
A description of the package.
(mandatory; literal)
.It 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)
.It Cflags
Required compiler flags.
These flags are always used, regardless of whether static compilation is requested.
(optional; fragment list)
.It Cflags.private
Required compiler flags for static compilation.
(optional; fragment list; pkgconf extension)
.It Copyright
A copyright attestation statement.
(optional; literal; pkgconf extension)
.It 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)
.It 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)
.It License
The asserted SPDX license tag that should be applied to the given package.
(optional; literal; pkgconf extension)
.It 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)
.It 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)
.It 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)
.It 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 the
Conflicts list, the package being considered is not usable.
(optional; dependency list)
.It 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)
.El
.Ss 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.
.Pp
Accordingly, it is suggested that
.Nm .pc
files which absolutely depend on these extensions declare a requirement on the
pkgconf virtual.
.Sh EXAMPLES
An example .pc file:
.Bd -literal
# 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
.Ed
.Sh SEE ALSO
.Xr pkgconf 1 ,
.Xr pkg.m4 7

143
man/pkg.m4.7 Normal file
View File

@ -0,0 +1,143 @@
.\" Copyright (c) 2017 pkgconf authors (see AUTHORS).
.\"
.\" Permission to use, copy, modify, and/or distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
.\" copyright notice and this permission notice appear in all copies.
.\"
.\" This software is provided 'as is' and without any warranty, express or
.\" implied. In no event shall the authors be liable for any damages arising
.\" from the use of this software.
.Dd December 5, 2017
.Dt PKG.M4 7
.Os
.Sh NAME
.Nm pkg.m4
.Nd autoconf macros for using pkgconf
.Sh SYNOPSIS
.Nm PKG_PREREQ
.Nm PKG_PROG_PKG_CONFIG
.Nm PKG_CHECK_MODULES
.Nm PKG_CHECK_MODULES_STATIC
.Nm PKG_INSTALLDIR
.Nm PKG_NOARCH_INSTALLDIR
.Nm PKG_CHECK_VAR
.Nm PKG_WITH_MODULES
.Nm PKG_HAVE_WITH_MODULES
.Nm PKG_HAVE_DEFINE_WITH_MODULES
.Sh DESCRIPTION
.Nm
is a collection of autoconf macros which help to configure compiler and linker
flags for development libraries.
This allows build systems to detect other dependencies and use them with the
system toolchain.
.Sh "AUTOCONF MACROS"
.Ss "PKG_PREREQ(MIN-VERSION)"
Checks that the version of the
.Nm
autoconf macros in use is at least MIN-VERSION.
This can be used to ensure a particular
.Nm
macro will be available.
.Ss "PKG_PROG_PKG_CONFIG([MIN-VERSION])"
Checks for an implementation of
.Nm pkg-config
which is at least MIN-VERSION or newer.
.Ss "PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES [,ACTION-IF-FOUND [,ACTION-IF-NOT-FOUND]])"
.Ss "PKG_CHECK_MODULES_STATIC(VARIABLE-PREFIX, MODULES [,ACTION-IF-FOUND [,ACTION-IF-NOT-FOUND]])"
Checks whether a given module set exists, and if so, defines
.Nm CFLAGS
and
.Nm LIBS
variables prefixed by
.Nm VARIABLE-PREFIX
with the output from
.Fl -cflags
and
.Fl -libs
respectively.
.Pp
The optional
.Nm ACTION-IF-FOUND
and
.Nm ACTION-IF-NOT-FOUND
arguments are shell fragments that should be executed if the module set is
found or not found.
.Pp
If
.Nm $PKG_CONFIG
is not defined, the
.Nm PKG_PROG_PKG_CONFIG
macro will be executed to locate a
.Nm pkg-config
implementation.
.Pp
The
.Nm PKG_CHECK_MODULES_STATIC
macro provides the same behaviour as
.Nm PKG_CHECK_MODULES
with static linking enabled via the
.Fl -static
flag.
.Ss "PKG_INSTALLDIR(DIRECTORY)"
Defines the variable $pkgconfigdir as the location where a package
should install pkg-config .pc files.
.Pp
By default the directory is $libdir/pkgconfig, but the default can
be changed by passing the
.Nm DIRECTORY
parameter.
.Pp
This value can be overridden with the
.Fl -with-pkgconfigdir
configure parameter.
.Ss "PKG_NOARCH_INSTALLDIR(DIRECTORY)"
Defines the variable $noarch_pkgconfigdir as the location where a package
should install pkg-config .pc files.
.Pp
By default the directory is $datadir/pkgconfig, but the default can
be changed by passing the
.Nm DIRECTORY
parameter.
.Pp
This value can be overridden with the
.Fl -with-noarch-pkgconfigdir
configure parameter.
.Ss "PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])"
Retrieves the value of the
.Nm pkg-config
variable
.Nm CONFIG-VARIABLE
from
.Nm MODULE
and stores it in the
.Nm VARIABLE
variable.
.Pp
Note that repeated usage of
.Nm VARIABLE
is not recommended as the check will be skipped if the variable is
already set.
.Ss "PKG_WITH_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND], [DESCRIPTION], [DEFAULT])"
Prepares a "--with-" configure option using the lowercase
.Nm VARIABLE-PREFIX
name, merging the behaviour of
.Nm AC_ARG_WITH
and
.Nm PKG_CHECK_MODULES
in a single macro.
.Ss "PKG_HAVE_WITH_MODULES(VARIABLE-PREFIX, MODULES, [DESCRIPTION], [DEFAULT])"
Convenience macro to trigger
.Nm AM_CONDITIONAL
after a
.Nm PKG_WITH_MODULES check.\&
.Nm VARIABLE-PREFIX
is exported as a make variable.
.Ss "PKG_HAVE_DEFINE_WITH_MODULES(VARIABLE-PREFIX, MODULES, [DESCRIPTION], [DEFAULT])"
Convenience macro to trigger
.Nm AM_CONDITIONAL
and
.Nm AC_DEFINE
after a
.Nm PKG_WITH_MODULES check.\&
.Nm VARIABLE-PREFIX
is exported as a make variable.

100
man/pkgconf-personality.5 Normal file
View File

@ -0,0 +1,100 @@
.\" Copyright (c) 2018 pkgconf authors (see AUTHORS).
.\"
.\" Permission to use, copy, modify, and/or distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
.\" copyright notice and this permission notice appear in all copies.
.\"
.\" This software is provided 'as is' and without any warranty, express or
.\" implied. In no event shall the authors be liable for any damages arising
.\" from the use of this software.
.Dd July 19, 2018
.Dt PKGCONF-PERSONALITY 5
.Os
.Sh NAME
.Nm file.personality
.Nd pkgconf cross-compile personality file format
.Sh DESCRIPTION
pkgconf cross-compile personality files provide a useful mechanism for storing
various information about system toolchains.
Information stored by
.Nm .personality
files include information about paths used by a cross-compile toolchain, such as
the sysroot directory and default include and library paths. pkgconf uses this
information to determine what information is necessary to use libraries.
.\"
.Ss FILE SYNTAX
The
.Nm .personality
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.
.\"
.Ss 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.
.Pp
There are three types of property:
.\"
.Bl -tag -width indent
.\"
.It Literal
The property will be set to the text of the value.
.\"
.It 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.
Elements are delimited with a colon.
.\"
.It Boolean
The property will be set to true if the value is one of: true, yes or 1.
Otherwise it will be set to false.
.\"
.El
.Ss PROPERTY KEYWORDS
.Bl -tag -width indent
.\"
.It Triplet
The triplet used by the cross-compile toolchain.
(mandatory; literal)
.It SysrootDir
The directory used by the system root of the cross-compile toolchain.
(mandatory; literal)
.It DefaultSearchPaths
A list of directories to look for
.Xr pc 5
files in.
(mandatory; fragment list)
.It SystemIncludePaths
A list of directories that are included by default in the search path for
include files.
(mandatory; fragment list)
.It SystemLibraryPaths
A list of directories that are included by default in the search path for
libraries.
(mandatory; fragment list)
.It WantDefaultPure
If true, pkgconf will default to preferring a pure dependency graph.
(optional; boolean; default is false)
.It WantDefaultStatic
If true, pkgconf will default to operating in static linking mode.
(optional; boolean; default is false)
.\"
.El
.Sh EXAMPLES
An example .personality file:
.Bd -literal
# This is a comment
Triplet: x86_64-pc-linux-gnu
SysrootDir: /home/kaniini/sysroot/x86_64-pc-linux-gnu
DefaultSearchPaths: /home/kaniini/sysroot/x86_64-pc-linux-gnu/lib/pkgconfig:/home/kaniini/sysroot/x86_64-pc-linux-gnu/share/pkgconfig
SystemIncludePaths: /home/kaniini/sysroot/x86_64-pc-linux-gnu/include
SystemLibraryPaths: /home/kaniini/sysroot/x86_64-pc-linux-gnu/lib
.Ed
.Sh SEE ALSO
.Xr pkgconf 1 ,
.Xr pc 5 ,
.Xr pkg.m4 7

View File

@ -20,8 +20,9 @@
.Sh DESCRIPTION
.Nm
is a program which helps to configure compiler and linker flags for
development frameworks. This allows build systems to detect other dependencies
and use them with the system toolchain.
development libraries.
This allows build systems to detect other dependencies and use them with the
system toolchain.
.Sh GENERAL OPTIONS
.Bl -tag -width indent
.It Fl -version
@ -39,32 +40,61 @@ environmental variable and display information on packages which have registered
information there.
.It Fl -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.
command line.
Dumps a series of trees denoting pkgconf's resolver state.
.It Fl -no-cache
Skip caching packages when they are loaded into the internal resolver. This may
result in an alternate dependency graph being computed.
Skip caching packages when they are loaded into the internal resolver.
This may result in an alternate dependency graph being computed.
.It Fl -ignore-conflicts
Ignore
.Sq Conflicts
rules in modules.
.It Fl -env-only
Learn about pkgconf's configuration strictly from environmental variables.
.It Fl -validate Ar package ...
Validate specific
.Sq .pc
files for correctness.
.It Fl -maximum-traverse-depth Ns = Ns Ar DEPTH
Impose a limit on the allowed depth in the dependency graph. For example, a
depth of 2 will restrict the resolver from acting on child dependencies of
modules added to the resolver's solution.
Impose a limit on the allowed depth in the dependency graph.
For example, a depth of 2 will restrict the resolver from acting on child
dependencies of modules added to the resolver's solution.
.It Fl -static
Compute a deeper dependency graph and use compiler/linker flags intended for
static linking.
.It Fl -shared
Compute a simple dependency graph that is only suitable for shared linking.
.It Fl -pure
Treats the computed dependency graph as if it were pure. This is mainly intended
for use with the
Treats the computed dependency graph as if it were pure.
This is mainly intended for use with the
.Fl -static
flag.
.It Fl -no-provides
Ignore
.Sq Provides
rules in modules when resolving dependencies.
.It Fl -with-path Ns = Ns Ar PATH
Adds a new module search path to pkgconf's dependency resolver.
Paths added in this way are given preference before other paths.
.It Fl -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.
.It Fl -dont-define-prefix
Disables the
.Sq define-prefix
feature.
.It Fl -prefix-variable Ns = Ns Ar VARIABLE
Sets the
.Sq prefix
variable used by the
.Sq define-prefix
feature.
.It Fl -relocate Ns = Ns Ar PATH
Relocates a path using the pkgconf_path_relocate API.
This is mainly used by the testsuite to provide a guaranteed interface
to the system's path relocation backend.
.It Fl -dont-relocate-paths
Disables the path relocation feature.
.El
.Sh MODULE-SPECIFIC OPTIONS
.Bl -tag -width indent
@ -75,24 +105,24 @@ Exit with error if a module's version is not exactly the specified version.
.It Fl -max-version Ns = Ns Ar VERSION
Exit with error if a module's version is greater than the specified version.
.It Fl -exists
Exit with a non-zero result if the dependency resolver was able to find all of
Exit with a non-zero result if the dependency resolver was unable to find all of
the requested modules.
.It Fl -uninstalled
Exit with a non-zero result if the dependency resolver uses an
.Sq uninstalled
module as part of it's solution.
module as part of its solution.
.It Fl -no-uninstalled
Forbids the dependency resolver from considering 'uninstalled' modules as part
of a solution.
.El
.Sh QUERY-SPECIFIC OPTIONS
.Bl -tag -width indent
.It Fl -cflags Ns , Fl -cflags-only-I Ns , Fl -cflags-only-other
.It Fl -cflags , Fl -cflags-only-I , Fl -cflags-only-other
Display either all CFLAGS, only
.Fl I
CFLAGS or only CFLAGS that are not
.Fl I .
.It Fl -libs Ns , Fl -libs-only-L Ns , Fl -libs-only-l Ns , Fl -libs-only-other
.It Fl -libs , Fl -libs-only-L , Fl -libs-only-l , Fl -libs-only-other
Display either all linker flags, only
.Fl L
linker flags, only
@ -101,7 +131,7 @@ linker flags or only linker flags that are not
.Fl L
or
.Fl l .
.It Fl -keep-system-cflags Ns , Fl -keep-system-libs
.It Fl -keep-system-cflags , Fl -keep-system-libs
Keep CFLAGS or linker flag fragments that would be filtered due to being
included by default in the compiler.
.It Fl -define-variable Ns = Ns Ar VARNAME Ns = Ns Ar VALUE
@ -120,7 +150,7 @@ entries for a module to the output channel.
.It Fl -variable Ns = Ns Ar VARNAME
Print the value of
.Va VARNAME .
.It Fl -print-requires Ns , Fl -print-requires-private
.It Fl -print-requires , Fl -print-requires-private
Print the modules included in either the
.Va Requires
field or the
@ -129,7 +159,20 @@ field.
.It Fl -digraph
Dump the dependency resolver's solution as a graphviz
.Sq dot
file. This can be used with graphviz to visualize module interdependencies.
file.
This can be used with graphviz to visualize module interdependencies.
.It Fl -path
Display the filenames of the
.Sq .pc
files used by the dependency resolver for a given dependency set.
.It Fl -env Ns = Ns Ar VARNAME
Print the requested values as variable declarations in a similar format as the
.Xr env 1
command.
.It Fl -fragment-filter Ns = Ns Ar TYPES
Filter the fragment lists for the specified types.
.It Fl -modversion
Print the version of the queried module.
.El
.Sh ENVIRONMENT
.Bl -tag -width indent
@ -168,10 +211,21 @@ flag.
.Sq logfile
which is used for dumping audit information concerning installed module versions.
.It Va PKG_CONFIG_DEBUG_SPEW
If set, enables additional debug logging. The format of the debug log messages is
implementation-specific.
If set, enables additional debug logging.
The format of the debug log messages is implementation-specific.
.It Va PKG_CONFIG_DONT_RELOCATE_PATHS
If set, disables the path relocation feature.
.It Va PKG_CONFIG_MSVC_SYNTAX
If set, uses MSVC syntax for fragments.
.It Va PKG_CONFIG_FDO_SYSROOT_RULES
If set, follow the sysroot prefixing rules that freedesktop.org pkg-config uses.
.It Va DESTDIR
If set to PKG_CONFIG_SYSROOT_DIR, assume that PKG_CONFIG_FDO_SYSROOT_RULES is set.
.El
.Sh EXAMPLES
Displaying the CFLAGS of a package:
.Dl $ pkgconf --cflags foo
.Dl -fPIC -I/usr/include/foo
.Sh SEE ALSO
.Xr pc 5 ,
.Xr pkg.m4 7

147
meson.build Normal file
View File

@ -0,0 +1,147 @@
project('pkgconf', 'c',
version : '2.2.0',
license : 'ISC',
meson_version : '>=0.49',
default_options : ['c_std=c99'],
)
cc = meson.get_compiler('c')
add_project_arguments(
'-D_BSD_SOURCE',
'-D_DEFAULT_SOURCE',
cc.get_supported_arguments(
'-Wimplicit-function-declaration',
'-Wmisleading-indentation',
),
language : 'c',
)
cdata = configuration_data()
check_functions = [
['strlcat', 'string.h'],
['strlcpy', 'string.h'],
['strndup', 'string.h'],
['strdup', 'string.h'],
['strncasecmp', 'strings.h'],
['strcasecmp', 'strings.h'],
['reallocarray', 'stdlib.h'],
]
foreach f : check_functions
name = f[0].to_upper().underscorify()
if cc.has_function(f[0], prefix : '#define _BSD_SOURCE\n#include <@0@>'.format(f[1])) and cc.has_header_symbol(f[1], f[0], prefix : '#define _BSD_SOURCE')
cdata.set('HAVE_@0@'.format(name), 1)
cdata.set('HAVE_DECL_@0@'.format(name), 1)
else
cdata.set('HAVE_DECL_@0@'.format(name), 0)
endif
endforeach
default_path = []
foreach f : ['libdir', 'datadir']
default_path += [join_paths(get_option('prefix'), get_option(f), 'pkgconfig')]
endforeach
personality_path = []
foreach f : ['libdir', 'datadir']
personality_path += [join_paths(get_option('prefix'), get_option(f), 'pkgconfig', 'personality.d')]
endforeach
SYSTEM_LIBDIR = get_option('with-system-libdir')
if SYSTEM_LIBDIR != ''
cdata.set_quoted('SYSTEM_LIBDIR', SYSTEM_LIBDIR)
else
cdata.set_quoted('SYSTEM_LIBDIR', join_paths(get_option('prefix'), get_option('libdir')))
endif
SYSTEM_INCLUDEDIR = get_option('with-system-includedir')
if SYSTEM_INCLUDEDIR != ''
cdata.set_quoted('SYSTEM_INCLUDEDIR', SYSTEM_INCLUDEDIR)
else
cdata.set_quoted('SYSTEM_INCLUDEDIR', join_paths(get_option('prefix'), get_option('includedir')))
endif
cdata.set_quoted('PKG_DEFAULT_PATH', ':'.join(default_path))
cdata.set_quoted('PERSONALITY_PATH', ':'.join(personality_path))
cdata.set_quoted('PACKAGE_NAME', meson.project_name())
cdata.set_quoted('PACKAGE_VERSION', meson.project_version())
cdata.set_quoted('PACKAGE_BUGREPORT', 'https://todo.sr.ht/~kaniini/pkgconf')
cdata.set('abs_top_srcdir', meson.current_source_dir())
cdata.set('abs_top_builddir', meson.current_build_dir())
subdir('libpkgconf')
libtype = get_option('default_library')
if libtype == 'static'
build_static = '-DPKGCONFIG_IS_STATIC'
else
build_static = '-DPKGCONFIG_IS_NOT_STATIC'
endif
libpkgconf = library('pkgconf',
'libpkgconf/argvsplit.c',
'libpkgconf/audit.c',
'libpkgconf/bsdstubs.c',
'libpkgconf/cache.c',
'libpkgconf/client.c',
'libpkgconf/dependency.c',
'libpkgconf/fileio.c',
'libpkgconf/fragment.c',
'libpkgconf/parser.c',
'libpkgconf/path.c',
'libpkgconf/personality.c',
'libpkgconf/pkg.c',
'libpkgconf/queue.c',
'libpkgconf/tuple.c',
c_args: ['-DLIBPKGCONF_EXPORT', build_static],
install : true,
version : '5.0.0',
soversion : '5',
)
# For other projects using libpkgconfig as a subproject
dep_libpkgconf = declare_dependency(
link_with : libpkgconf,
include_directories : include_directories('.'),
)
# If we have a new enough meson override the dependency so that only
# `dependency('libpkgconf')` is required from the consumer
if meson.version().version_compare('>= 0.54.0')
meson.override_dependency('libpkgconf', dep_libpkgconf)
endif
pkg = import('pkgconfig')
pkg.generate(libpkgconf,
name : 'libpkgconf',
description : 'a library for accessing and manipulating development framework configuration',
url: 'http://github.com/pkgconf/pkgconf',
filebase : 'libpkgconf',
subdirs: ['pkgconf'],
extra_cflags : build_static
)
pkgconf_exe = executable('pkgconf',
'cli/main.c',
'cli/getopt_long.c',
'cli/renderer-msvc.c',
link_with : libpkgconf,
c_args: build_static,
install : true)
with_tests = get_option('tests')
kyua_exe = find_program('kyua', required : with_tests, disabler : true)
atf_sh_exe = find_program('atf-sh', required : with_tests, disabler : true)
kyuafile = configure_file(input : 'Kyuafile.in', output : 'Kyuafile', configuration : cdata)
test('kyua', kyua_exe, args : ['--config=none', 'test', '--kyuafile', kyuafile, '--build-root', meson.current_build_dir()])
subdir('tests')
install_man('man/pkgconf.1')
install_man('man/pkg.m4.7')
install_man('man/pc.5')
install_man('man/pkgconf-personality.5')
install_data('pkg.m4', install_dir: 'share/aclocal')
install_data('AUTHORS', install_dir: 'share/doc/pkgconf')
install_data('README.md', install_dir: 'share/doc/pkgconf')

19
meson_options.txt Normal file
View File

@ -0,0 +1,19 @@
option(
'tests',
type: 'feature',
description: 'Build tests which depends upon the kyua framework',
)
option(
'with-system-libdir',
type: 'string',
value: '',
description: 'Specify the system library directory (default {prefix}/{libdir})'
)
option(
'with-system-includedir',
type: 'string',
value: '',
description: 'Specify the system include directory (default {prefix}/{includedir})'
)

299
pkg.m4
View File

@ -1,29 +1,66 @@
# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-
# serial 1 (pkg-config-0.24)
#
# Copyright © 2004 Scott James Remnant <scott@netsplit.com>.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# pkg.m4 - Macros to locate and use pkg-config. -*- Autoconf -*-
# serial 12 (pkg-config-0.29.2)
# PKG_PROG_PKG_CONFIG([MIN-VERSION])
# ----------------------------------
dnl Copyright © 2004 Scott James Remnant <scott@netsplit.com>.
dnl Copyright © 2012-2015 Dan Nicholson <dbn.lists@gmail.com>
dnl
dnl This program is free software; you can redistribute it and/or modify
dnl it under the terms of the GNU General Public License as published by
dnl the Free Software Foundation; either version 2 of the License, or
dnl (at your option) any later version.
dnl
dnl This program is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of
dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
dnl General Public License for more details.
dnl
dnl You should have received a copy of the GNU General Public License
dnl along with this program; if not, write to the Free Software
dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
dnl 02111-1307, USA.
dnl
dnl As a special exception to the GNU General Public License, if you
dnl distribute this file as part of a program that contains a
dnl configuration script generated by Autoconf, you may include it under
dnl the same distribution terms that you use for the rest of that
dnl program.
dnl PKG_PREREQ(MIN-VERSION)
dnl -----------------------
dnl Since: 0.29
dnl
dnl Verify that the version of the pkg-config macros are at least
dnl MIN-VERSION. Unlike PKG_PROG_PKG_CONFIG, which checks the user's
dnl installed version of pkg-config, this checks the developer's version
dnl of pkg.m4 when generating configure.
dnl
dnl To ensure that this macro is defined, also add:
dnl m4_ifndef([PKG_PREREQ],
dnl [m4_fatal([must install pkg-config 0.29 or later before running autoconf/autogen])])
dnl
dnl See the "Since" comment for each macro you use to see what version
dnl of the macros you require.
m4_defun([PKG_PREREQ],
[m4_define([PKG_MACROS_VERSION], [0.29.2])
m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1,
[m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])])
])dnl PKG_PREREQ
dnl PKG_PROG_PKG_CONFIG([MIN-VERSION], [ACTION-IF-NOT-FOUND])
dnl ---------------------------------------------------------
dnl Since: 0.16
dnl
dnl Search for the pkg-config tool and set the PKG_CONFIG variable to
dnl first found in the path. Checks that the version of pkg-config found
dnl is at least MIN-VERSION. If MIN-VERSION is not specified, 0.9.0 is
dnl used since that's the first version where most current features of
dnl pkg-config existed.
dnl
dnl If pkg-config is not found or older than specified, it will result
dnl in an empty PKG_CONFIG variable. To avoid widespread issues with
dnl scripts not checking it, ACTION-IF-NOT-FOUND defaults to aborting.
dnl You can specify [PKG_CONFIG=false] as an action instead, which would
dnl result in pkg-config tests failing, but no bogus error messages.
AC_DEFUN([PKG_PROG_PKG_CONFIG],
[m4_pattern_forbid([^_?PKG_[A-Z_]+$])
m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$])
@ -44,19 +81,23 @@ if test -n "$PKG_CONFIG"; then
AC_MSG_RESULT([no])
PKG_CONFIG=""
fi
fi
if test -z "$PKG_CONFIG"; then
m4_default([$2], [AC_MSG_ERROR([pkg-config not found])])
fi[]dnl
])# PKG_PROG_PKG_CONFIG
])dnl PKG_PROG_PKG_CONFIG
# PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
#
# Check to see whether a particular set of modules exists. Similar
# to PKG_CHECK_MODULES(), but does not set variables or print errors.
#
# Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG])
# only at the first occurence in configure.ac, so if the first place
# it's called might be skipped (such as if it is within an "if", you
# have to call PKG_CHECK_EXISTS manually
# --------------------------------------------------------------
dnl PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
dnl -------------------------------------------------------------------
dnl Since: 0.18
dnl
dnl Check to see whether a particular set of modules exists. Similar to
dnl PKG_CHECK_MODULES(), but does not set variables or print errors.
dnl
dnl Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG])
dnl only at the first occurrence in configure.ac, so if the first place
dnl it's called might be skipped (such as if it is within an "if", you
dnl have to call PKG_CHECK_EXISTS manually
AC_DEFUN([PKG_CHECK_EXISTS],
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
if test -n "$PKG_CONFIG" && \
@ -66,8 +107,10 @@ m4_ifvaln([$3], [else
$3])dnl
fi])
# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES])
# ---------------------------------------------
dnl _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES])
dnl ---------------------------------------------
dnl Internal wrapper calling pkg-config via PKG_CONFIG and setting
dnl pkg_failed based on the result.
m4_define([_PKG_CONFIG],
[if test -n "$$1"; then
pkg_cv_[]$1="$$1"
@ -79,10 +122,11 @@ m4_define([_PKG_CONFIG],
else
pkg_failed=untried
fi[]dnl
])# _PKG_CONFIG
])dnl _PKG_CONFIG
# _PKG_SHORT_ERRORS_SUPPORTED
# -----------------------------
dnl _PKG_SHORT_ERRORS_SUPPORTED
dnl ---------------------------
dnl Internal check to see if pkg-config supports short errors.
AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED],
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])
if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
@ -90,26 +134,24 @@ if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
else
_pkg_short_errors_supported=no
fi[]dnl
])# _PKG_SHORT_ERRORS_SUPPORTED
])dnl _PKG_SHORT_ERRORS_SUPPORTED
# PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
# [ACTION-IF-NOT-FOUND])
#
#
# Note that if there is a possibility the first call to
# PKG_CHECK_MODULES might not happen, you should be sure to include an
# explicit call to PKG_PROG_PKG_CONFIG in your configure.ac
#
#
# --------------------------------------------------------------
dnl PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
dnl [ACTION-IF-NOT-FOUND])
dnl --------------------------------------------------------------
dnl Since: 0.4.0
dnl
dnl Note that if there is a possibility the first call to
dnl PKG_CHECK_MODULES might not happen, you should be sure to include an
dnl explicit call to PKG_PROG_PKG_CONFIG in your configure.ac
AC_DEFUN([PKG_CHECK_MODULES],
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl
AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl
pkg_failed=no
AC_MSG_CHECKING([for $1])
AC_MSG_CHECKING([for $2])
_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2])
_PKG_CONFIG([$1][_LIBS], [libs], [$2])
@ -119,17 +161,17 @@ and $1[]_LIBS to avoid the need to call pkg-config.
See the pkg-config man page for more details.])
if test $pkg_failed = yes; then
AC_MSG_RESULT([no])
AC_MSG_RESULT([no])
_PKG_SHORT_ERRORS_SUPPORTED
if test $_pkg_short_errors_supported = yes; then
$1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1`
else
$1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1`
$1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1`
else
$1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1`
fi
# Put the nasty error message in config.log where it belongs
echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD
# Put the nasty error message in config.log where it belongs
echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD
m4_default([$4], [AC_MSG_ERROR(
m4_default([$4], [AC_MSG_ERROR(
[Package requirements ($2) were not met:
$$1_PKG_ERRORS
@ -140,8 +182,8 @@ installed software in a non-standard prefix.
_PKG_TEXT])[]dnl
])
elif test $pkg_failed = untried; then
AC_MSG_RESULT([no])
m4_default([$4], [AC_MSG_FAILURE(
AC_MSG_RESULT([no])
m4_default([$4], [AC_MSG_FAILURE(
[The pkg-config script could not be found or is too old. Make sure it
is in your PATH or set the PKG_CONFIG environment variable to the full
path to pkg-config.
@ -151,20 +193,45 @@ _PKG_TEXT
To get pkg-config, see <http://pkg-config.freedesktop.org/>.])[]dnl
])
else
$1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS
$1[]_LIBS=$pkg_cv_[]$1[]_LIBS
$1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS
$1[]_LIBS=$pkg_cv_[]$1[]_LIBS
AC_MSG_RESULT([yes])
$3
$3
fi[]dnl
])# PKG_CHECK_MODULES
])dnl PKG_CHECK_MODULES
# PKG_INSTALLDIR(DIRECTORY)
# -------------------------
# Substitutes the variable pkgconfigdir as the location where a module
# should install pkg-config .pc files. By default the directory is
# $libdir/pkgconfig, but the default can be changed by passing
# DIRECTORY. The user can override through the --with-pkgconfigdir
# parameter.
dnl PKG_CHECK_MODULES_STATIC(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
dnl [ACTION-IF-NOT-FOUND])
dnl ---------------------------------------------------------------------
dnl Since: 0.29
dnl
dnl Checks for existence of MODULES and gathers its build flags with
dnl static libraries enabled. Sets VARIABLE-PREFIX_CFLAGS from --cflags
dnl and VARIABLE-PREFIX_LIBS from --libs.
dnl
dnl Note that if there is a possibility the first call to
dnl PKG_CHECK_MODULES_STATIC might not happen, you should be sure to
dnl include an explicit call to PKG_PROG_PKG_CONFIG in your
dnl configure.ac.
AC_DEFUN([PKG_CHECK_MODULES_STATIC],
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
_save_PKG_CONFIG=$PKG_CONFIG
PKG_CONFIG="$PKG_CONFIG --static"
PKG_CHECK_MODULES($@)
PKG_CONFIG=$_save_PKG_CONFIG[]dnl
])dnl PKG_CHECK_MODULES_STATIC
dnl PKG_INSTALLDIR([DIRECTORY])
dnl -------------------------
dnl Since: 0.27
dnl
dnl Substitutes the variable pkgconfigdir as the location where a module
dnl should install pkg-config .pc files. By default the directory is
dnl $libdir/pkgconfig, but the default can be changed by passing
dnl DIRECTORY. The user can override through the --with-pkgconfigdir
dnl parameter.
AC_DEFUN([PKG_INSTALLDIR],
[m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])])
m4_pushdef([pkg_description],
@ -175,16 +242,18 @@ AC_ARG_WITH([pkgconfigdir],
AC_SUBST([pkgconfigdir], [$with_pkgconfigdir])
m4_popdef([pkg_default])
m4_popdef([pkg_description])
]) dnl PKG_INSTALLDIR
])dnl PKG_INSTALLDIR
# PKG_NOARCH_INSTALLDIR(DIRECTORY)
# -------------------------
# Substitutes the variable noarch_pkgconfigdir as the location where a
# module should install arch-independent pkg-config .pc files. By
# default the directory is $datadir/pkgconfig, but the default can be
# changed by passing DIRECTORY. The user can override through the
# --with-noarch-pkgconfigdir parameter.
dnl PKG_NOARCH_INSTALLDIR([DIRECTORY])
dnl --------------------------------
dnl Since: 0.27
dnl
dnl Substitutes the variable noarch_pkgconfigdir as the location where a
dnl module should install arch-independent pkg-config .pc files. By
dnl default the directory is $datadir/pkgconfig, but the default can be
dnl changed by passing DIRECTORY. The user can override through the
dnl --with-noarch-pkgconfigdir parameter.
AC_DEFUN([PKG_NOARCH_INSTALLDIR],
[m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])])
m4_pushdef([pkg_description],
@ -195,13 +264,15 @@ AC_ARG_WITH([noarch-pkgconfigdir],
AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir])
m4_popdef([pkg_default])
m4_popdef([pkg_description])
]) dnl PKG_NOARCH_INSTALLDIR
])dnl PKG_NOARCH_INSTALLDIR
# PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE,
# [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
# -------------------------------------------
# Retrieves the value of the pkg-config variable for the given module.
dnl PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE,
dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
dnl -------------------------------------------
dnl Since: 0.28
dnl
dnl Retrieves the value of the pkg-config variable for the given module.
AC_DEFUN([PKG_CHECK_VAR],
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl
@ -210,17 +281,16 @@ _PKG_CONFIG([$1], [variable="][$3]["], [$2])
AS_VAR_COPY([$1], [pkg_cv_][$1])
AS_VAR_IF([$1], [""], [$5], [$4])dnl
])# PKG_CHECK_VAR
])dnl PKG_CHECK_VAR
# PKG_WITH_MODULES(VARIABLE-PREFIX, MODULES,
# [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND],
# [DESCRIPTION], [DEFAULT])
#
# Prepare a "--with-" configure option using the lowercase [VARIABLE-PREFIX]
# name, merging the behaviour of AC_ARG_WITH and PKG_CHECK_MODULES in a single
# macro
#
# --------------------------------------------------------------
dnl PKG_WITH_MODULES(VARIABLE-PREFIX, MODULES,
dnl [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND],
dnl [DESCRIPTION], [DEFAULT])
dnl ------------------------------------------
dnl
dnl Prepare a "--with-" configure option using the lowercase
dnl [VARIABLE-PREFIX] name, merging the behaviour of AC_ARG_WITH and
dnl PKG_CHECK_MODULES in a single macro.
AC_DEFUN([PKG_WITH_MODULES],
[
m4_pushdef([with_arg], m4_tolower([$1]))
@ -250,38 +320,33 @@ m4_popdef([with_arg])
m4_popdef([description])
m4_popdef([def_arg])
]) dnl PKG_WITH_MODULES
])dnl PKG_WITH_MODULES
# PKG_HAVE_WITH_MODULES(VARIABLE-PREFIX, MODULES,
# [DESCRIPTION], [DEFAULT])
#
# Convenience macro to trigger AM_CONDITIONAL after
# PKG_WITH_MODULES check.
#
# HAVE_[VARIABLE-PREFIX] is exported as make variable.
#
# --------------------------------------------------------------
dnl PKG_HAVE_WITH_MODULES(VARIABLE-PREFIX, MODULES,
dnl [DESCRIPTION], [DEFAULT])
dnl -----------------------------------------------
dnl
dnl Convenience macro to trigger AM_CONDITIONAL after PKG_WITH_MODULES
dnl check._[VARIABLE-PREFIX] is exported as make variable.
AC_DEFUN([PKG_HAVE_WITH_MODULES],
[
PKG_WITH_MODULES([$1],[$2],,,[$3],[$4])
AM_CONDITIONAL([HAVE_][$1],
[test "$AS_TR_SH([with_]m4_tolower([$1]))" = "yes"])
])
])dnl PKG_HAVE_WITH_MODULES
# PKG_HAVE_DEFINE_WITH_MODULES(VARIABLE-PREFIX, MODULES,
# [DESCRIPTION], [DEFAULT])
#
# Convenience macro to run AM_CONDITIONAL and AC_DEFINE after
# PKG_WITH_MODULES check.
#
# HAVE_[VARIABLE-PREFIX] is exported as make and preprocessor variable.
#
# --------------------------------------------------------------
dnl PKG_HAVE_DEFINE_WITH_MODULES(VARIABLE-PREFIX, MODULES,
dnl [DESCRIPTION], [DEFAULT])
dnl ------------------------------------------------------
dnl
dnl Convenience macro to run AM_CONDITIONAL and AC_DEFINE after
dnl PKG_WITH_MODULES check. HAVE_[VARIABLE-PREFIX] is exported as make
dnl and preprocessor variable.
AC_DEFUN([PKG_HAVE_DEFINE_WITH_MODULES],
[
PKG_HAVE_WITH_MODULES([$1],[$2],[$3],[$4])
AS_IF([test "$AS_TR_SH([with_]m4_tolower([$1]))" = "yes"],
[AC_DEFINE([HAVE_][$1], 1, [Enable ]m4_tolower([$1])[ support])])
])
])dnl PKG_HAVE_DEFINE_WITH_MODULES

View File

@ -1,65 +0,0 @@
#! /bin/sh
# Copyright (c) 2012 Bryan Drewery <bryan@shatow.net>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer
# in this position and unchanged.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# Install build dependencies for pkg on Mac or Linux (Debiaun/Ubuntu) systems.
#
# This script is primarily intended for travis CI to be able to setup the
# build environment.
install_from_github() {
local name="${1}"
local ver="${2}"
local distname="${name}-${ver}"
# https://github.com/jmmv/kyua/releases/download/kyua-0.12/kyua-0.12.tar.gz
local url="https://github.com/jmmv/${name}"
wget "${url}/releases/download/${distname}/${distname}.tar.gz"
tar -xzvf "${distname}.tar.gz"
cd "${distname}"
./configure \
--disable-developer \
--without-atf \
--without-doxygen \
CPPFLAGS="-I/usr/local/include" \
LDFLAGS="-L/usr/local/lib -Wl,-R/usr/local/lib" \
PKG_CONFIG_PATH="/usr/local/lib/pkgconfig"
make
sudo make install
cd -
rm -rf "${distname}" "${distname}.tar.gz"
}
if [ $(uname -s) = "Darwin" ]; then
brew update
brew install libarchive --with-xz
brew install openssl
brew install kyua
elif [ $(uname -s) = "Linux" ]; then
install_from_github atf 0.21
install_from_github lutok 0.4
install_from_github kyua 0.12
fi

View File

@ -29,10 +29,17 @@ tests_init \
libs_circular_directpc \
libs_static \
libs_static_ordering \
libs_metapackage \
license_isc \
license_noassertion \
modversion_noflatten \
pkg_config_path \
nolibs \
nocflags \
arbitary_path
arbitary_path \
with_path \
relocatable \
single_depth_selectors
noargs_body()
{
@ -44,7 +51,7 @@ libs_body()
{
export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \
-o inline:"-L/test/lib -lfoo \n" \
-o inline:"-L/test/lib -lfoo\n" \
pkgconf --libs foo
}
@ -52,7 +59,7 @@ libs_cflags_body()
{
export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \
-o inline:"-fPIC -I/test/include/foo -L/test/lib -lfoo \n" \
-o inline:"-fPIC -I/test/include/foo -L/test/lib -lfoo\n" \
pkgconf --cflags --libs foo
}
@ -61,7 +68,7 @@ libs_cflags_version_body()
{
export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \
-o inline:"-fPIC -I/test/include/foo -L/test/lib -lfoo \n" \
-o inline:"-fPIC -I/test/include/foo -L/test/lib -lfoo\n" \
pkgconf --cflags --libs 'foo > 1.2'
}
@ -69,7 +76,7 @@ libs_cflags_version_multiple_body()
{
export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \
-o inline:"-I/test/include/foo -fPIC -L/test/lib -lbar -lfoo \n" \
-o inline:"-fPIC -I/test/include/foo -L/test/lib -lbar -lfoo\n" \
pkgconf --cflags --libs 'foo > 1.2 bar >= 1.3'
}
@ -77,7 +84,7 @@ libs_cflags_version_multiple_coma_body()
{
export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \
-o inline:"-I/test/include/foo -fPIC -L/test/lib -lbar -lfoo \n" \
-o inline:"-fPIC -I/test/include/foo -L/test/lib -lbar -lfoo\n" \
pkgconf --cflags --libs 'foo > 1.2,bar >= 1.3'
}
@ -85,7 +92,7 @@ libs_cflags_version_alt_body()
{
export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \
-o inline:"-fPIC -I/test/include/foo -L/test/lib -lfoo \n" \
-o inline:"-fPIC -I/test/include/foo -L/test/lib -lfoo\n" \
pkgconf --cflags --libs 'foo' '>' '1.2'
}
@ -93,7 +100,7 @@ libs_cflags_version_different_body()
{
export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \
-o inline:"-fPIC -I/test/include/foo -L/test/lib -lfoo \n" \
-o inline:"-fPIC -I/test/include/foo -L/test/lib -lfoo\n" \
pkgconf --cflags --libs 'foo' '!=' '1.3.0'
}
@ -173,7 +180,7 @@ exists_version_bad3_body()
export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \
-s exit:1 \
pkgconf --exists 'tilde <= 1.0.0'
pkgconf --exists 'tilde >= 1.0.0'
}
exists_body()
@ -187,7 +194,7 @@ exists2_body()
{
export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \
pkgconf --exists 'tilde >= 1.0.0'
pkgconf --exists 'tilde <= 1.0.0'
}
exists3_body()
@ -201,30 +208,30 @@ libs_intermediary_body()
{
export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \
-o inline:"-lintermediary-1 -lintermediary-2 -lfoo -lbar -lbaz \n" \
-o inline:"-lintermediary-1 -lintermediary-2 -lfoo -lbar -lbaz\n" \
pkgconf --libs intermediary-1 intermediary-2
}
libs_circular1_body()
{
export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \
-o inline:"-lcircular-1 -lcircular-2 -lcircular-3 \n" \
pkgconf --libs circular-1
}
libs_circular2_body()
{
export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \
-o inline:"-lcircular-3 -lcircular-1 -lcircular-2 \n" \
pkgconf --libs circular-3
-o inline:"circular-1: breaking circular reference (circular-1 -> circular-2 -> circular-1)\n" \
pkgconf circular-2 --validate
}
libs_circular1_body()
{
export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \
-o inline:"circular-3: breaking circular reference (circular-3 -> circular-1 -> circular-3)\n" \
pkgconf circular-1 --validate
}
libs_circular_directpc_body()
{
atf_check \
-o inline:"-lcircular-1 -lcircular-2 -lcircular-3 \n" \
-o inline:"-lcircular-3 -lcircular-1 -lcircular-2\n" \
pkgconf --libs ${selfdir}/lib1/circular-3.pc
}
@ -232,7 +239,7 @@ libs_static_body()
{
export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \
-o inline:"/libfoo.a -pthread \n" \
-o inline:"/libfoo.a -pthread\n" \
pkgconf --libs static-archive-libs
}
@ -240,26 +247,44 @@ libs_static_ordering_body()
{
export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \
-o inline:"-L/test/lib -lbar -lfoo \n" \
-o inline:"-L/test/lib -lbar -lfoo\n" \
pkgconf --libs foo bar
}
libs_metapackage_body()
{
export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \
-o inline:"-L/test/lib -lbar -lfoo\n" \
pkgconf --static --libs metapackage-3
}
pkg_config_path_body()
{
export PKG_CONFIG_PATH="${selfdir}/lib1${PATH_SEP}${selfdir}/lib2"
atf_check \
-o inline:"-L/test/lib -lfoo \n" \
-o inline:"-L/test/lib -lfoo\n" \
pkgconf --libs foo
atf_check \
-o inline:"-L/test/lib -lbar -lfoo \n" \
-o inline:"-L/test/lib -lbar -lfoo\n" \
pkgconf --libs bar
}
with_path_body()
{
atf_check \
-o inline:"-L/test/lib -lfoo\n" \
pkgconf --with-path=${selfdir}/lib1 --with-path=${selfdir}/lib2 --libs foo
atf_check \
-o inline:"-L/test/lib -lbar -lfoo\n" \
pkgconf --with-path=${selfdir}/lib1 --with-path=${selfdir}/lib2 --libs bar
}
nolibs_body()
{
export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \
-o inline:" \n" \
-o inline:"\n" \
pkgconf --libs nolib
}
@ -267,7 +292,7 @@ nocflags_body()
{
export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \
-o inline:" \n" \
-o inline:"\n" \
pkgconf --cflags nocflag
}
@ -275,6 +300,43 @@ arbitary_path_body()
{
cp ${selfdir}/lib1/foo.pc .
atf_check \
-o inline:"-L/test/lib -lfoo \n" \
-o inline:"-L/test/lib -lfoo\n" \
pkgconf --libs foo.pc
}
relocatable_body()
{
basedir=$(pkgconf --relocate ${selfdir})
atf_check \
-o inline:"${basedir}/lib-relocatable\n" \
pkgconf --define-prefix --variable=prefix ${basedir}/lib-relocatable/lib/pkgconfig/foo.pc
}
single_depth_selectors_body()
{
export PKG_CONFIG_MAXIMUM_TRAVERSE_DEPTH=1
atf_check \
-o inline:"foo\n" \
pkgconf --with-path=${selfdir}/lib3 --print-requires bar
}
license_isc_body()
{
atf_check \
-o inline:"foo: ISC\n" \
pkgconf --with-path=${selfdir}/lib1 --license foo
}
license_noassertion_body()
{
atf_check \
-o inline:"bar: NOASSERTION\nfoo: ISC\n" \
pkgconf --with-path=${selfdir}/lib1 --license bar
}
modversion_noflatten_body()
{
atf_check \
-o inline:"1.3\n" \
pkgconf --with-path=${selfdir}/lib1 --modversion bar
}

View File

@ -12,7 +12,7 @@ modversion_body()
{
export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \
-o inline:"1.0.1 \n" \
-o inline:"1.0.1 \n" \
pkgconf --modversion pkg-config
}
@ -20,7 +20,7 @@ variable_body()
{
export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \
-o inline:"/test \n" \
-o inline:"/test \n" \
pkgconf --variable=prefix foo
}
@ -28,7 +28,7 @@ define_variable_body()
{
export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \
-o inline:"/test2 \n" \
-o inline:"/test2 \n" \
pkgconf --define-variable=prefix=/test2 --variable=prefix foo
}
@ -36,7 +36,7 @@ global_variable_body()
{
export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \
-o inline:"${selfdir}/lib1 \n"
-o inline:"${selfdir}/lib1 \n"
pkgconf --exists -foo
}
@ -44,7 +44,7 @@ argv_parse_3_body()
{
export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \
-o inline:"-llib-1 -pthread /test/lib/lib2.so \n" \
-o inline:"-llib-1 -pthread /test/lib/lib2.so \n" \
pkgconf --libs argv-parse-3
}
@ -52,10 +52,10 @@ tilde_quoting_body()
{
export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \
-o inline:"-L~ -ltilde \n" \
-o inline:"-L~ -ltilde \n" \
pkgconf --libs tilde-quoting
atf_check \
-o inline:"-I~ \n" \
-o inline:"-I~ \n" \
pkgconf --cflags tilde-quoting
}
@ -63,6 +63,6 @@ paren_quoting_body()
{
export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \
-o inline:"-L\$(libdir) -ltilde \n" \
-o inline:"-L\$(libdir) -ltilde \n" \
pkgconf --libs paren-quoting
}

View File

@ -10,7 +10,7 @@ libs_body()
{
export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \
-o inline:"-L/test/lib -lconflicts \n" \
-o inline:"-L/test/lib -lconflicts\n" \
pkgconf --libs conflicts
}
@ -18,6 +18,6 @@ ignore_body()
{
export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \
-o inline:"-L/test/lib -lconflicts \n" \
-o inline:"-L/test/lib -lconflicts\n" \
pkgconf --ignore-conflicts --libs conflicts
}

View File

@ -9,12 +9,12 @@ libs_body()
{
export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \
-o inline:"-F/test/lib -framework framework-1 \n" \
-o inline:"-F/test/lib -framework framework-1\n" \
pkgconf --libs framework-1
atf_check \
-o inline:"-F/test/lib -framework framework-2 -F/test/lib -framework framework-1 \n" \
-o inline:"-F/test/lib -framework framework-2 -framework framework-1\n" \
pkgconf --libs framework-2
atf_check \
-o inline:"-F/test/lib -framework framework-1 -F/test/lib -framework framework-2 \n" \
-o inline:"-F/test/lib -framework framework-2 -framework framework-1\n" \
pkgconf --libs framework-1 framework-2
}

View File

@ -0,0 +1,11 @@
prefix=/test
exec_prefix=${prefix}
libdir=${prefix}/lib
includedir=${prefix}/include
Name: foo
Description: A testing pkg-config file
Version: 1.2.3
Libs: -L${libdir} -lfoo
Cflags: -fPIC -I${includedir}/foo
Cflags.private: -DFOO_STATIC

View File

@ -0,0 +1,13 @@
v9=lol
v8=${v9}${v9}${v9}${v9}${v9}${v9}${v9}${v9}${v9}${v9}
v7=${v8}${v8}${v8}${v8}${v8}${v8}${v8}${v8}${v8}${v8}
v6=${v7}${v7}${v7}${v7}${v7}${v7}${v7}${v7}${v7}${v7}
v5=${v6}${v6}${v6}${v6}${v6}${v6}${v6}${v6}${v6}${v6}
v4=${v5}${v5}${v5}${v5}${v5}${v5}${v5}${v5}${v5}${v5}
v3=${v4}${v4}${v4}${v4}${v4}${v4}${v4}${v4}${v4}${v4}
v2=${v3}${v3}${v3}${v3}${v3}${v3}${v3}${v3}${v3}${v3}
v1=${v2}${v2}${v2}${v2}${v2}${v2}${v2}${v2}${v2}${v2}
v0=${v1}${v1}${v1}${v1}${v1}${v1}${v1}${v1}${v1}${v1}
Name: One Billion Laughs
Version: ${v0}
Description: Don't install this!

View File

@ -0,0 +1,9 @@
prefix=/test/local
exec_prefix=${prefix}
libdir=${prefix}/lib
includedir=${prefix}/include
Name: cflags-internal
Description: A testing pkg-config file
Version: 1.2.3
Cflags: -I${includedir}/foo

View File

@ -0,0 +1,6 @@
xcflags=
Name: empty-tuple
Description: testing file
Version: 1
CFlags: ${xcflags}

View File

@ -0,0 +1,4 @@
Name: escaped-backslash
Version: 1
Description: test package for backslash escape scenario
Cflags: -IC:\\A

View File

@ -0,0 +1,7 @@
prefix=/usr
datarootdir=${prefix}/share
pkgdatadir=${pc_sysrootdir}/${datarootdir}/test
Name: Test
Description: Testing pc_sysrootdir auto-expansion
Version: 1.0

View File

@ -9,3 +9,4 @@ Version: 1.2.3
Libs: -L${libdir} -lfoo
Cflags: -fPIC -I${includedir}/foo
Cflags.private: -DFOO_STATIC
License: ISC

12
tests/lib1/foobar.pc Normal file
View File

@ -0,0 +1,12 @@
prefix=/test
exec_prefix=${prefix}
libdir=${prefix}/lib
includedir=${prefix}/include
Name: foobar
Description: A testing pkg-config file
Version: 3.2.1
Libs: -L${libdir} -lfoobar
Cflags: -fPIC -I${includedir}/foobar
Cflags.private: -DFOOBAR_STATIC
License: ISC

View File

@ -0,0 +1,4 @@
Name: fragment-collision-1
Version: 0
Description: fragment collision test package
Cflags: -D_THREAD_SAFE -pthread

View File

@ -0,0 +1,4 @@
Name: fragment-collision-2
Version: 0
Description: fragment collision test package
CFlags: -D_FOO

View File

@ -0,0 +1,5 @@
Name: fragment-collision-intermediary
Version: 0
Description: fragment collision test package
Requires.private: fragment-collision-1, fragment-collision-2
CFlags: -D_BAR

View File

@ -0,0 +1,6 @@
Name: fragment-collision
Version: 0
Description: fragment collision test package
Requires: fragment-collision-2, fragment-collision-intermediary
Requires.private: fragment-collision-1
Cflags: -D_BAZ

View File

@ -0,0 +1,4 @@
Name: fragment-comment
Description: Test case for issue #215
Version: 1.0
Cflags: kuku=\#ttt

View File

@ -0,0 +1,5 @@
Name: fragment-escaping-1
Version: 0
Description: fragment escaping test
Cflags: "-IC:\\D E"
Libs: "-LC:\\D E" -lE

View File

@ -0,0 +1,4 @@
Name: fragment-escaping-2
Version: 0
Description: fragment escaping test
Cflags: '-IC:\D E'

View File

@ -0,0 +1,4 @@
Name: fragment-escaping-3
Version: 0
Description: fragment escaping test
Cflags: -IC:\\D\ E

View File

@ -0,0 +1,10 @@
prefix=/test
exec_prefix=${prefix}
libdir=${prefix}/lib
includedir=${prefix}/include
Name: fragment-quoting
Description: A testing pkg-config file
Version: 1.2.3
Cflags: -fPIC -I${includedir}/foo -DQUOTED="${prefix}/share/doc"
Cflags.private: -DFOO_STATIC

View File

@ -0,0 +1,10 @@
prefix=/test
exec_prefix=${prefix}
libdir=${prefix}/lib
includedir=${prefix}/include
Name: fragment-quoting
Description: A testing pkg-config file
Version: 1.2.3
Cflags: -fPIC -I${includedir}/foo -DQUOTED=\"${prefix}/share/doc\"
Cflags.private: -DFOO_STATIC

View File

@ -0,0 +1,10 @@
prefix=/test
exec_prefix=${prefix}
libdir=${prefix}/lib
includedir=${prefix}/include
Name: fragment-quoting-5
Description: A testing pkg-config file
Version: 1.2.3
Cflags: -fPIC -I${includedir}/foo -DQUOTED='${prefix}/share/doc'
Cflags.private: -DFOO_STATIC

View File

@ -0,0 +1,4 @@
Name: fragment-quoting-7
Description: A testing pkg-config file, this time from Go
Version: 1.2.3
Cflags: -Dhello=10 -Dworld=+32 -DDEFINED_FROM_PKG_CONFIG=hello\ world

View File

@ -0,0 +1,10 @@
prefix=/test
exec_prefix=${prefix}
libdir=${prefix}/lib
includedir=${prefix}/include
Name: fragment-quoting
Description: A testing pkg-config file
Version: 1.2.3
Cflags: -fPIC -I${includedir}/foo -DQUOTED='"${prefix}/share/doc"'
Cflags.private: -DFOO_STATIC

View File

@ -0,0 +1,2 @@
prefix=/usr\nName: GKrellM\nDescription: Extensible GTK system monitoring application\nVersion: 2.3.7\nRequires: gtk+-2.0 >= 2.4.0\nCflags: -I/usr/include\n

View File

@ -0,0 +1,4 @@
Name: malformed-quoting
Version: 1
Description: None.
Cflags: '-I/ABC

View File

@ -0,0 +1,5 @@
Name: malformed-version
Version: 3.922 2018-03-17
Description: None.
Cflags: -Ifoo
Libs: -lbar

View File

@ -0,0 +1,6 @@
Name: metapackage-1
Version: 0.1
Description: metapackage for testing purposes
Requires.private: metapackage-2
Libs: -lmetapackage-1
Cflags: -I/metapackage-1

View File

@ -0,0 +1,5 @@
Name: metapackage-2
Version: 0.1
Description: metapackage for testing purposes
Libs: -lmetapackage-2
Cflags: -I/metapackage-2

View File

@ -0,0 +1,4 @@
Name: metapackage-3
Version: 0.1
Description: metapackage for testing purposes
Requires.private: bar

View File

@ -0,0 +1,4 @@
Name: metapackage
Version: 0.1
Description: metapackage for testing purposes
Requires: metapackage-1, metapackage-2

View File

@ -0,0 +1,9 @@
prefix=/test
exec_prefix=${prefix}
libdir=${prefix}/lib
includedir=${prefix}/include
Name: multiline
Description: A multiline
description blah blah blah
Version: 1.2.3

View File

@ -0,0 +1,10 @@
prefix=${pc_sysrootdir}/test
exec_prefix=${prefix}
libdir=${prefix}/lib
includedir=${prefix}/include
Name: omg-sysroot
Description: A testing pkg-config file
Version: 1.2.3
Libs: -L${libdir} -lomg
Cflags: -fPIC -I${includedir}/omg

View File

@ -0,0 +1,8 @@
Name: orphaned-requires-private
Version: 1
Description: A testing module for pkgconf
URL: http://www.pkgconf.org/
Requires: foo
Requires.private: orphaned-foo
Cflags: -DUNREACHABLE
Libs:

View File

@ -7,4 +7,4 @@ Name: quotes
Description: A testing pkg-config file
Version: 1.2.3
Libs: -L${libdir} -lfoo
Cflags: -DQUOTED=\"bla\"
Cflags: -DQUOTED=\"bla\" -DA=\"escaped\ string\'\ \literal\" -DB="\1\$" -DC='bla'

View File

@ -0,0 +1,9 @@
prefix=/test/local
exec_prefix=${prefix}
libdir=${prefix}/lib
includedir=${prefix}/include
Name: requires-internal
Description: A testing pkg-config file
Version: 1.2.3
Requires.internal: cflags-internal

View File

@ -0,0 +1,10 @@
prefix=/test/local
exec_prefix=${prefix}
libdir=${prefix}/lib
includedir=${prefix}/include
Name: requires-internal
Description: A testing pkg-config file
Version: 1.2.3
Requires.internal: cflags-internal
Requires.private: cflags-internal

Some files were not shown because too many files have changed in this diff Show More