Hacker News new | ask | show | jobs
by humanrebar 2031 days ago
I always like hearing about more work in this space. More attention needs to be paid to native language packaging.

That being said, the core problems with current packaging tech don't seem to be addressed here. Though maybe they are and someone can enlighten me.

1. Repo contents are not portable across packaging systems or distributions.

Antipatterns: Often your Makefiles have to be hardcoded to assume pkg-config. Or assume there's a monorepo. Or your CMake has to explicitly mention your packaging system (i.e., Conan::zlib). Or all the projects must be ported to use a particular build system (like CMake exported config packages).

2. Repo contents are not portable across architecturesnand OSs.

There are well known source code anitpatterns here, but per-repo build and packaging specifications still like to have "if windows" and "if ARM" sections. I can live with working around edge cases, but it's really pervasive.

3. Repo contents are not portable across sets of ABI assumptions.

Similar to item 2, but with respect to de facto ABI levers like what language standard is used (libraries often have different ABIs based on language feature detection) or magic preprocessor defines (like which std::string is assumed).

Now, I think the above are hard problems. But I would like to see more folks thinking about them. Especially people researching package management. Especially because someone just wanting to meaningfully use folly or boost::filesystem is generally unaware of the above foot guns.

2 comments

>Antipatterns: Often your Makefiles have to be hardcoded to assume pkg-config.

I'm not clear what you mean here - are you suggesting "hard-coding" use of pkg-config is a bad thing? Why? "Hard-coding" pkg-config would be ideal, I think, since pkg-config is the only package-manager-independent option that I know of for native dependencies...

On paper pkg-config is in the right general direction. Shipping package metadata alongside binaries is probably required to solve the problems I sketched out. And topologically sorting that data makes a ton of sense.

A few problems though:

A. Its model could be more robust. There is no way to specify a language runtime dependency other than providing non-portable linker and compilation flags. Cycles in search paths are easy to introduce, partly because there search paths aren't modeled as such. Instead, flags are just graphed and flattened.

B. To generalize on A, pkg-config very much travels in terms of non-portable flags that you flatten. It would be more useful, arguably essential, to be able to simply export a graph of metadata.

C. In theory pkg-config is portable. In practice, uptake on Windows is underwhelming to be generous. And many Linux distros treat that sort of metadata as optional for native packages as well.

But within a given distro, I have seen pkg-config work well enough. It might be the closest we have to a standard in this space. If the major build systems like CMake and bazel supported exporting cross-compatible .pc files, and then if distros required .pc files (with consistent names!) every time a header was shipped, we would be taking a big step in the right direction.

Only on unix-like systems, and even there...
> Or all the projects must be ported to use a particular build system (like CMake exported config packages).

They really don't. I mean, it's a nice to have but not a must have.

If you want to use a project that doesn't offer Cmake support then all you need to do is, say, add a find-<projectname>.Cmake file which pretty much just calls find_library and sets a couple of variables, stash it in your project tree under ~/Cmake, add that path to your Cmake modules path and you're all set.

I mean, in all this can be done for each package with less than a dozen lines of code, total.

I'd say not bad.