pkgconf extension. seems to be used in practice. from grepping
my system, i see it's used by the following .pc files:
libcurl liblzma libavif expat expatw libarchive
---
test_main.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++
u-config.c | 9 ++++++--
2 files changed, 68 insertions(+), 2 deletions(-)
diff --git a/test_main.c b/test_main.c
index 0c2ecfc..147308c 100644
--- a/test_main.c
+++ b/test_main.c
@@ -377,6 +377,66 @@ static void test_maximum_traverse_depth(void)
EXPECT("-Da -Db -Dc\n");
}
+static void test_private_cflags(void)
+{
+ // Scenario: a has private cflags
+ // Expect: --cflags should not output it unless --static is also given
+ config conf = newtest_(S("private cflags"));
+ newfile_(&conf, S("/usr/lib/pkgconfig/a.pc"), S(
+ PCHDR
+ "Cflags: -DA_PUB\n"
+ "Cflags.private: -DA_PRIV\n"
+ "Libs: -la\n"
+ ));
+ // Scenario: b has private cflags and so does it's dependencies
+ // Expect: only output private flags if --static is given
+ newfile_(&conf, S("/usr/lib/pkgconfig/b.pc"), S(
+ PCHDR
+ "Cflags: -DB_PUB\n"
+ "Cflags.private: -DB_PRIV\n"
+ "Libs: -lb\n"
+ "Requires: c\n"
+ "Requires.private: d\n"
+ ));
+ newfile_(&conf, S("/usr/lib/pkgconfig/c.pc"), S(
+ PCHDR
+ "Cflags: -DC_PUB\n"
+ "Cflags.private: -DC_PRIV\n"
+ "Libs: -lc\n"
+ ));
+ newfile_(&conf, S("/usr/lib/pkgconfig/d.pc"), S(
+ PCHDR
+ "Cflags: -DD_PUB\n"
+ "Cflags.private: -DD_PRIV\n"
+ "Libs: -ld\n"
+ ));
+
+ SHOULDPASS {
+ run(conf, S("--cflags"), S("a"), E);
+ }
+ EXPECT("-DA_PUB\n");
+
+ SHOULDPASS {
+ run(conf, S("--static"), S("--cflags"), S("a"), E);
+ }
+ EXPECT("-DA_PUB -DA_PRIV\n");
+
+ SHOULDPASS {
+ run(conf, S("--libs"), S("--static"), S("a"), E);
+ }
+ EXPECT("-la\n");
+
+ SHOULDPASS {
+ run(conf, S("--cflags"), S("b"), E);
+ }
+ EXPECT("-DB_PUB -DC_PUB\n");
+
+ SHOULDPASS {
+ run(conf, S("--cflags"), S("--static"), S("b"), E);
+ }
+ EXPECT("-DB_PUB -DB_PRIV -DC_PUB -DC_PRIV -DD_PUB -DD_PRIV\n");
+}
+
static void test_private_transitive(void)
{
// Scenario: a privately requires b which publicly requires c
@@ -877,6 +937,7 @@ int main(void)
test_versionorder();
test_overrides();
test_maximum_traverse_depth();
+ test_private_cflags();
test_private_transitive();
test_private_non_existing();
test_revealed_transitive();
diff --git a/u-config.c b/u-config.c
index 55ed77c..0a9f23f 100644
--- a/u-config.c
+++ b/u-config.c
@@ -553,7 +553,7 @@ struct pkg {
pkgspec *specs_requiresprivate;
i32 flags;
- #define PKG_NFIELDS 10
+ #define PKG_NFIELDS 11
s8 name;
s8 description;
s8 url;
@@ -564,6 +564,7 @@ struct pkg {
s8 libs;
s8 libsprivate;
s8 cflags;
+ s8 cflagsprivate;
};
static s8 *fieldbyid(pkg *p, i32 id)
@@ -585,7 +586,8 @@ static s8 *fieldbyname(pkg *p, s8 name)
s8("Conflicts"),
s8("Libs"),
s8("Libs.private"),
- s8("Cflags")
+ s8("Cflags"),
+ s8("Cflags.private")
};
for (i32 i = 0; i < countof(fields); i++) {
if (s8equals(fields[i], name)) {
@@ -2062,6 +2064,9 @@ static void uconfig(config *conf)
}
for (pkg *p = pkgs.head; p; p = p->list) {
appendfield(err, &fw, p, p->cflags);
+ if (proc->static_) {
+ appendfield(err, &fw, p, p->cflagsprivate);
+ }
}
writeargs(out, &fw);
}
--
2.48.1
Thanks! I grepped my own system and found Cflags.private, too. But when I
compared outputs to pkgconf it didn't match. Neither did freedesktop.org.
They both output Cflags of private packages, and u-config was not due to
the recent 62c88c08 (ignore missing private packages). In fact, they both
disagree with one of your new test outputs. So I also reverted 62c88c08,
which required changing that expected test output.
A quick test you can see for yourself, freedesktop.org or any version of
pkgconf, "a.pc":
...
Requires.private: b
And "b.pc":
...
Cflags: -DB
Then "pkg-config --cflags a" will output "-DB". Despite reverting it, I'm
still glad it's captured in the repository history as an explored path.
On Tue, Mar 11, 2025 at 08:01:28PM -0400, Christopher Wellons wrote:
> Thanks! I grepped my own system and found Cflags.private, too. But when I
> compared outputs to pkgconf it didn't match. Neither did freedesktop.org.
> They both output Cflags of private packages, and u-config was not due to the
> recent 62c88c08 (ignore missing private packages). In fact, they both
> disagree with one of your new test outputs. So I also reverted 62c88c08,
> which required changing that expected test output.
>
> A quick test you can see for yourself, freedesktop.org or any version of
> pkgconf, "a.pc":
>
> ...
> Requires.private: b
>
> And "b.pc":
>
> ...
> Cflags: -DB
>
> Then "pkg-config --cflags a" will output "-DB". Despite reverting it, I'm
> still glad it's captured in the repository history as an explored path.
For some more context: I was working on adding an "exec" backend to muon
(https://muon.build) which calls and parses output of pkg-config
executable. Mainly so that I can occasionally build and test meson based
projects on volatile windows VM with w64devkit.
During that, I noticed this comment in src/external/libpkgconf.c:
// meson runs pkg-config to look for cflags,
// which honors Requires.private if any cflags are requested.
pkgconf_client_set_flags(&pkgconf_ctx.client, flags | PKGCONF_PKG_PKGF_SEARCH_PRIVATE);
I misread Requires.private as Cflags.private which prompted me to grep
it on my system then add it to u-config. This is also why I didn't pick
up on the inconsistency since I tested Cflags.private rather than
Requires.private. In any case, reverting is the right call.
As for the whole libplacebo mystery, it's (apparently) a meson bug [1]
[2] where it adds vulkan as a private lib if it's installed in the
system (even though vulkan support was disabled). This also explains how
I ended up with "stale" pc file earlier and why reinstalling fixed it.
And in case you're interested, I've attached my current (still WIP)
muon patch. The parsing is a bit shoddy. Doesn't handle all unusual
inputs, only some of the more practical ones like "\ " space unescaping
for windows path.
[1]: https://bugs.gentoo.org/951125
[2]: https://github.com/mesonbuild/meson/issues/11080
- NRK