Great read. I started off wondering why anyone would need to replace something as “obviously simple” as pkg-config, and finished the article completely horrified by pkg-config‘s behaviour. And it’s not even bootstrappable.
I came from a different starting point: I was watching closely when FreeBSD switched from pkg-config to pkgconf and so I’m fully aware of how horrible the original codebase was (to work on and to build), but I didn’t know why the author didn’t just use pkgconf.
I wasn’t tremendously impressed with the code quality in pkgconf either. It uses fixed-width bitfields in a few places with no abstraction and with all of the bits allocated so if you need to add a new flag later it’s a massive refactoring, for example, so I can kind-of see why you’d want to write a new version.
The thing that I really didn’t understand is why you’d use C, particularly if Windows support is a key requirement. Unlike the C standard library, the C++ standard library is very well supported on Windows (by both Visual Studio and LLVM’s libc++) and provides platform abstractions over all of the things that are required for a pkg-config implementation. If you’re going to write a tool that does a load of string processing, why not implement it in a language that at least has a standard-library string type that integrates with its I/O functionality, even if it’s not a great one). Personally, I’d prefer to see pkg-config written in Lua with a tiny C++ wrapper for launching it. It’s not like it’s performance critical.
As poor as the original pkg-config’s code and bootstrapability may be, I haven’t hit any bugs with it yet while with pkgconf I’ve been lucky enough to find a “how is the code structured that makes this possible” bug: https://github.com/pkgconf/pkgconf/issues/275
Totally agree that lua or similar would be more appropriate for this kind of program.
I wasn’t tremendously impressed with the code quality in pkgconf either.
It’s an over-engineered, inscruitable mess and its author has no regard for backwards compatibility. It got so bad that we forked the library, cleaned it up a bit, and fixed quite a few buffer overflows. In case anyone is interested: https://github.com/build2/libpkg-config It builds and works fine on Windows.
BTW, the README file in the above-linked project also describes the alternative usage from a build system that addresses quite a few issues (like cross compilation) that plague the traditional pkg-config usage.
Interesting how supporting otherwise-portable development tools on Windows today is akin to once-upon-a-time supporting DR DOS under Windows 3.1: Possible, but painful, and you have to wonder how long it is for this world.
That’s nothing to do with pkg-config etc, and only because fish always quotes command substitutions, unlike traditional shells in which you can choose to quote or not:
The first, quoted version has all the output of pkg-config as one argument, but the second version expands spaces as argument delimiters. In fish you have to use workarounds like pkg-config --cflags sdl2 | string split " ".
Great read. I started off wondering why anyone would need to replace something as “obviously simple” as
pkg-config
, and finished the article completely horrified bypkg-config
‘s behaviour. And it’s not even bootstrappable.I came from a different starting point: I was watching closely when FreeBSD switched from
pkg-config
topkgconf
and so I’m fully aware of how horrible the original codebase was (to work on and to build), but I didn’t know why the author didn’t just usepkgconf
.I wasn’t tremendously impressed with the code quality in
pkgconf
either. It uses fixed-width bitfields in a few places with no abstraction and with all of the bits allocated so if you need to add a new flag later it’s a massive refactoring, for example, so I can kind-of see why you’d want to write a new version.The thing that I really didn’t understand is why you’d use C, particularly if Windows support is a key requirement. Unlike the C standard library, the C++ standard library is very well supported on Windows (by both Visual Studio and LLVM’s libc++) and provides platform abstractions over all of the things that are required for a
pkg-config
implementation. If you’re going to write a tool that does a load of string processing, why not implement it in a language that at least has a standard-library string type that integrates with its I/O functionality, even if it’s not a great one). Personally, I’d prefer to see pkg-config written in Lua with a tiny C++ wrapper for launching it. It’s not like it’s performance critical.As poor as the original pkg-config’s code and bootstrapability may be, I haven’t hit any bugs with it yet while with pkgconf I’ve been lucky enough to find a “how is the code structured that makes this possible” bug: https://github.com/pkgconf/pkgconf/issues/275
Totally agree that lua or similar would be more appropriate for this kind of program.
It’s an over-engineered, inscruitable mess and its author has no regard for backwards compatibility. It got so bad that we forked the library, cleaned it up a bit, and fixed quite a few buffer overflows. In case anyone is interested: https://github.com/build2/libpkg-config It builds and works fine on Windows.
BTW, the
README
file in the above-linked project also describes the alternative usage from a build system that addresses quite a few issues (like cross compilation) that plague the traditionalpkg-config
usage.Interesting how supporting otherwise-portable development tools on Windows today is akin to once-upon-a-time supporting DR DOS under Windows 3.1: Possible, but painful, and you have to wonder how long it is for this world.
An inconvenience with the original pkg-config is that command substitutions like
cc $(pkg-config --cflags)
don’t work when pasted into fish: https://github.com/fish-shell/fish-shell/issues/982I would take the opportunity to fix that.
That’s nothing to do with pkg-config etc, and only because fish always quotes command substitutions, unlike traditional shells in which you can choose to quote or not:
The first, quoted version has all the output of pkg-config as one argument, but the second version expands spaces as argument delimiters. In fish you have to use workarounds like
pkg-config --cflags sdl2 | string split " "
.