Revamped flag output - please test
dbn.lists at gmail.com
Sat Dec 8 11:59:35 PST 2012
I spent a bunch of time over the past month or so working on fixes for
two long standing bugs in pkg-config.
Bug 16101 - duplicate argument removal for Cflags/Libs is incorrect
Bug 19950 - -Bstatic and -Bdynamic not handled properly
These two bugs were intertwined deeply into how pkg-config gathers and
outputs packages and Libs/Cflags. The current algorithm gathers a full
recursive list of packages from those on the command line and their
Requires/Requires.private. For each requested -I/-other Cflags and
-L/-l/-other Libs, a separate list of flags is built up by walking
down the full package list. After building the list, all duplicate
flags are stripped from the list. pkg-config then outputs each list
There are a couple issues with this approach.
1. By always considering each flag output type (e.g. -L vs -l)
separately, the order and context of the mixed flags from the
Libs/Cflags in the original .pc files is lost.
2. Since packages can show up multiple times in the recursive list
(e.g., two packages both require a 3rd), the stripping of all
duplicate arguments means the flags from each package will show up at
most once. However, it also means that the semantics of the order of
the flags can easily be lost.
I've pushed a new branch to pkg-config that attempts to fix these
issues. It's on the flag-order-fixes branch.
In this branch, a couple changes are made that are significant to the output.
1. The Libs and Cflags from each package are kept in a single list and
each flag is marked by its type. This allows the order of the flags
from each package to be retained. Later, this is used to output the
Libs -l and -other flags in proper order. This part essentially fixes
#19950 and allows things like -Wl,--whole-archive -lfoo
-Wl,--no-whole-archive -lbar to work.
2. When building the recursive package list, duplicates are stripped
out starting at most required dependency. So, if foo and bar both
depend on baz, the original package list would be foo->baz->bar->baz.
Stripping duplicates from the end results in foo->bar->baz. This
allows the need to aggressively strip duplicate flags to be removed.
This part is actually on master already.
3. After constructing the flag output, only consecutive duplicate
flags are removed. This fixes #16101. This means that if you have like
-Wl,--whole-archive that need to show up multiple times in the output,
they'll continue to work. Unfortunately, this means that you will
sometimes get repeats of things you wouldn't have before, like if
multiple packages contain flags from non-pkg-config libraries like
-lm. I think this change is required, though, because there's no way
for pkg-config to have a complete understanding of the semantics the
.pc flags are holding. I think we have to just pass along to the
compiler/linker and let it do the right thing.
Along the way I added a bunch more test cases to see how these changes
would affect things. One significant add was a directory of .pc files
for gtk+-3.0 and all its dependencies. This provides a fairly complex
case where regressions can be spotted. You can see the git log on
check/check-gtk to see how it's changed with my changes vs previous
pkg-configs. I checked that building a gtk program before and after
produces the same binary except the order of the DT_NEEDED libs is
Anyway, please try out the branch if you can. I'd like to push this to
master soon and make a pkg-config-0.28 with it.
More information about the pkg-config