Woes of the distribution maintainer

I am distribution maintainer. Programmer who makes sure that software is easily installable with "apt-get" or "nix-env" or whatever, depending on distribution. And often I have to work hard to make sure particular piece of software works and feels like everything else.

The fundamental principle -- use standard build tools and be no different. For C it means using autotools, for Python -- setuptools, for Haskell -- cabal. All these tools have a lot of flexibility, but try to stick to defaults as close as possible.

List below is attempt to make classification of things I had to patch or workaround in last two years. To be extended.

Make sure your software builds from snapshot instead of git checkout.

Usually it means to refrain from calling "git describe" and friends in build system. If it is incredibly important to you (it should not), do something like that:

.version:
	git describe > .version

This way I won't have to hunt and patch for calls to git in your build system, I'll do this:

preConfigure = ''
  echo $version > .version
''

Avoid bootstrapping, if possible.

Bootstrapping (building $foo using $foo) is always complicated. If possible, try to avoid it. For example, if you are developing new build system, please make it possible to build it either with Makefile or trivial "build.sh".

Make it possible to disable building of shared libraries

Not all platforms support them, so if your build system tried to build them unconditionally, I'll have to patch. There is well-established convention what environment variable should control that; I saw ENABLE_SHARED=1 and NO_SOLIB=1.

Never access network in build system

This one should be self-evident. Accessing network kills build reproducibility. Also, downloading resources during build is form of vendoring.

Do not vendor dependencies

It may be convenient for one-off builds, but it is total disaster on scale of distribution. There is longer explanation on Gentoo Wiki (point aganist static linking is Gentoo-specific, though).

https://wiki.gentoo.org/wiki/Why_not_bundle_dependencies

Use pkg-config

You may think that all you have to known about library is that to link it you have to -lfoo, but that it not all. Static linkage requires you to list ALL transitive dependencies of library, in right order. I you won't do it, then I'll have to do it to fix static build. Just use "pkg-config --libs" and "pkgs-config --libs --static". Yes, you need some kind of flag.

AR is prefixed tool

ar(1) is part of bintools and must be prefixed, so in case of cross compilation it must be called with prefix, like "x86_64-unknown-linux-musl-ar".

Don't play smart with linker

For historical reasons, there is concept of weak symbols, strong symbols, symbol precedence between binaries and shared libraries and other things. Just don't. It will definitely break somewhere, probably during static build.

Every symbol must be defined only one, period.

Think about backward compatibility

Maintaining backward compatibility is pain, I know. But if there is some other piece of software that is incompatible with your latest version, I'll have to either patch it or package two versions of your software.

Ideally, talk to your reverse dependencies about breaking changes.

When building documentation in html, use relative paths

HTML documentation is not only about putting onto doc.yourproject.org, it also will be installed into $PREFIX/share/doc/yourproject/html and read locally, probably even with lynx, so don't go wild on recent web features.

Actually, just use TexInfo or (sigh) Sphinx. No fancy plugins, please.

Release archive is no substitute for proper build system in git

Distributions rebuild everything from the source.

Meta

Let me be an optimist and believe that mess we are in is due lack of understanding that there is a problem, not conscious refusal to address it. I plan to maintain this list, adding more items to it (sigh) or improving description of already mentioned issues. If you want to make suggestion or just talk -- you know my email:

$ echo a2FjdGlvbkB0aWxkZS5waW5rCg== | base64 -d