200 Commits

Author SHA1 Message Date
Ariadne Conill
18e32f2fb6 libpkgconf: pkg: make pkgconf_pkg_walk_conflicts_list public
It is needed by the solver to check the solution for conflicts.

Signed-off-by: Ariadne Conill <ariadne@ariadne.space>
2026-01-18 21:03:07 -08:00
Ariadne Conill
07dfbfffee libpkgconf: pkg: track conflict rule origins
Signed-off-by: Ariadne Conill <ariadne@ariadne.space>
2026-01-18 20:50:18 -08:00
Ariadne Conill
be0687f637 libpkgconf: use pkgconf_client_getenv wrapper for mocking
Signed-off-by: Ariadne Conill <ariadne@ariadne.space>
2025-12-24 15:47:53 -08:00
Ariadne Conill
0c38d0afd6 libpkgconf: pkg: fix formatting of version matching truth table
Signed-off-by: Ariadne Conill <ariadne@ariadne.space>
2025-12-23 10:33:05 -08:00
Ariadne Conill
213cccf9dc libpkgconf: pkg: tolerate missing requires.internal dependency nodes if unnecessary
Requires.internal is intended to be a weaker version of requires.private,
where a dependency node does not need to be satisfied if link libraries are
not requested.

Closes: https://github.com/pkgconf/pkgconf/issues/434
Signed-off-by: Ariadne Conill <ariadne@ariadne.space>
2025-12-21 13:32:20 -08:00
Ariadne Conill
c863ef3f82 libpkgconf: clean up _WIN32 include mess quite a bit
Ref: https://github.com/pkgconf/pkgconf/issues/406
Signed-off-by: Ariadne Conill <ariadne@ariadne.space>
2025-12-20 15:25:17 -08:00
Ariadne Conill
c8bfa9fee0 libpkgconf: pkg: do not override pc_sysrootdir when emulating pkgconf 1.x
In pkgconf 1.x, we unconditionally prepend PKG_CONFIG_SYSROOT_DIR if
it is not already present.  Emulate this by not overriding pc_sysrootdir
in cases where the .pc file is outside the sysroot.

Signed-off-by: Ariadne Conill <ariadne@ariadne.space>
2025-12-20 14:43:03 -08:00
Ariadne Conill
0658ba7721 libpkgconf: pkg: add lint for duplicated dependency-list fields
Duplicating fields does not have consistent behavior across pkg-config
implementations, so we add a lint for it.

Ref: https://github.com/microsoft/vcpkg/issues/48837
Signed-off-by: Ariadne Conill <ariadne@ariadne.space>
2025-12-20 01:52:49 -08:00
Jonathan Gray
31c71208e3 libpkgconf: pkg: fix unintended bitwise and
found with sparse: 'warning: dubious: !x & !y'
2025-12-19 22:27:13 -08:00
Ariadne Conill
3dbec89d3d libpkgconf: pkg: allow environment variables to override tuple contents
This was a feature in original pkg-config that was overlooked.

Fixes: https://github.com/pkgconf/pkgconf/issues/426
Signed-off-by: Ariadne Conill <ariadne@ariadne.space>
2025-12-07 21:44:00 -08:00
Ariadne Conill
ccd916d0a8 libpkgconf: pkg: remove old static pkg-config virtual objects
These are no longer used (or even compiled).  They were left behind for reference.

Signed-off-by: Ariadne Conill <ariadne@ariadne.space>
2025-12-01 23:59:39 -08:00
Ariadne Conill
9baf542f84 libpkgconf: remove pkgconf_builtin_pkg_get
Now that we have preloaded packages, we can handle the builtin packages as
preloads.

Signed-off-by: Ariadne Conill <ariadne@ariadne.space>
2025-12-01 23:16:47 -08:00
Ariadne Conill
a1e09753bc libpkgconf: parser: add function to allow for parsing a pkgconf_buffer_t directly
This will be used to overhaul the built-in package support by synthesizing a .pc
file on the fly for built-ins.

Ref: https://github.com/pkgconf/pkgconf/issues/418
2025-11-02 01:27:38 -08:00
Tuukka Pasanen
d0481ddafd libpkgconf: Add License.file-tag
Add License.file-tag for determining where to find
correct license for package. License.file should
be in URI format.
2025-11-01 15:21:32 -07:00
Ariadne Conill
15650665b3 libpkgconf: ensure source-tag is freed when package is freed 2025-10-22 13:38:31 -07:00
Tuukka Pasanen
a04e269553 libpkgconf: Add Source-tag
Add Source-tag for determining where to find
correct source code for the package. Source tag
should be URI.
2025-10-22 13:32:32 -07:00
Marc-André Lureau
499083eba9 build: fix -Werror=unused-variable
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
2025-08-18 10:22:05 -07:00
Ariadne Conill
de3ffe21cf libpkgconf: downgrade to readlink(3) if readlinkat(3) is unavailable
Signed-off-by: Ariadne Conill <ariadne@ariadne.space>
Fixes: https://github.com/pkgconf/pkgconf/issues/420
2025-07-30 12:06:38 -07:00
Ariadne Conill
a3af684d16 libpkgconf: pkg: ensure pkgconf_pkg_new_from_path only loads .pc files
Signed-off-by: Ariadne Conill <ariadne@ariadne.space>
2025-06-04 11:18:41 -07:00
Ariadne Conill
0a93248351 libpkgconf: pkg: add functionality for searching and scanning the preloaded package list
Signed-off-by: Ariadne Conill <ariadne@ariadne.space>
2025-06-04 10:58:27 -07:00
Ariadne Conill
d477016924 libpkgconf: pkg: remove freed packages from the preload list
Signed-off-by: Ariadne Conill <ariadne@ariadne.space>
2025-06-04 10:42:11 -07:00
Ariadne Conill
aa5813ac5e libpkgconf: path: refactor windows registry PKG_CONFIG_PATH support
Now we add to the search list rather than falling back to the registry
after the search list fails to find a package.

Signed-off-by: Ariadne Conill <ariadne@ariadne.space>
2025-05-31 00:17:11 -07:00
Ariadne Conill
61610c65cb libpkgconf: pkg: refactor pkgconf_pkg_new_from_file into pkgconf_pkg_new_from_path
Previously, files would be closed by side effect, which is a somewhat bad API
design that trips up various static analysis tools.

Signed-off-by: Ariadne Conill <ariadne@ariadne.space>
2025-05-29 10:08:00 -07:00
Ariadne Conill
7fbb8bf280 libpkgconf: pkg: refactor pkgconf_pkg_free into micro-operations
Then use pkg_free_lists and pkg_free_object to clean up package objects
which have not been fully initialized.

Found-by: GCC -fanalyzer
Signed-off-by: Ariadne Conill <ariadne@ariadne.space>
2025-05-28 22:59:43 -07:00
Ariadne Conill
e4e3b45b78 libpkgconf: pkg: gracefully handle NULL parameter to pkgconf_pkg_unref()
This could happen when pkgconf_pkg_new_from_file() fails due to error.

Found-by: GCC -fanalyzer
Signed-off-by: Ariadne Conill <ariadne@ariadne.space>
2025-05-28 22:32:06 -07:00
Ariadne Conill
859402ef3d libpkgconf: pkg: allow pkgconf_pkg_new_from_file to return NULL on malloc error
Other errors can already cause pkgconf_pkg_new_from_file() to return NULL, so
this doesn't break API.

Found-by: GCC -fanalyzer
Signed-off-by: Ariadne Conill <ariadne@ariadne.space>
2025-05-28 22:30:34 -07:00
Ariadne Conill
5a18878451 libpkgconf: add support for late-breaking unveil(2) notifications
Signed-off-by: Ariadne Conill <ariadne@ariadne.space>
2025-05-17 23:49:54 -07:00
Ariadne Conill
3611b056fb libpkgconf: pkg: consistently use pc_sysrootdir for path munging
In some cases, client.sysroot_dir would be used instead of the
package-specific override.

Fixes: https://github.com/pkgconf/pkgconf/pull/280
Signed-off-by: Ariadne Conill <ariadne@ariadne.space>
2025-03-05 16:54:52 -08:00
Ariadne Conill
a79952a084 libpkgconf: queue: always walk requires.private lists internally
This ensures the internal dependency graph solution is always consistent.
We filter out the nodes we don't care about in cases where we need to filter
as of commit 86602bc, so now we can just simplify the solving a little bit.

Signed-off-by: Ariadne Conill <ariadne@ariadne.space>
2025-02-02 02:30:38 -08:00
Ariadne Conill
86602bc17e libpkgconf: pkg: skip over private dependency nodes when --static is not explicitly requested
Fixes: 197fcad ("queue: add flattening code")
Signed-off-by: Ariadne Conill <ariadne@ariadne.space>
2025-02-02 02:10:00 -08:00
David Seifert
e6c1d4b8bd
${pcfiledir} should point to parent dir of actual file, not symlink
* In situations where we have a real <path1>/foo.pc that uses ${pcfiledir} and
  a symlink <path2>/foo.pc that points to <path1>/foo.pc, then ${pcfiledir}
  should resolve to <path1> and not <path2>.
2024-10-09 19:06:05 +02:00
Kai Pastor
883b57df47 Cache packages from explicit file requests 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
e7c9bdb317 Don't print 'required by <VIRTUAL-PACKAGE>' 2024-03-27 11:09:16 -07: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
45073b7460 Circular deps: track ancestors, not serial 2023-11-22 10:09:22 -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
Colin Gillespie
5aeb469b81 libpkgconf: fix memory leak
Signed-off-by: Colin Gillespie <colin@cgillespie.xyz>
2023-10-08 22:46:53 +00:00
Ariadne Conill
ee702658cd use PRIu64 format specifiers for some uint64 identifiers in trace logging
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
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
Ariadne Conill
a265f8a42b libpkgconf: pkg: fix long-standing bug where -uninstalled pkg-config files would have the wrong identifier 2023-08-17 11:53:07 -07: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
Taylor R Campbell
212c85863a Avoid undefined behaviour with the ctype(3) functions.
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
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
e2a12fd4c2 main: reset solver when solving for library groups 2023-01-21 20:39:53 +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
Ariadne Conill
ced9bee613 pkg: remove dead store in pkgconf_compare_version 2022-08-16 18:51:11 +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
aa99ddf789 pkg: add Copyright and Maintainer fields
These are helpful pieces of information for BOM documents
generated by pkgconf.
2022-08-11 15:52:33 +00:00