Wednesday, January 2, 2013

Overriding install prefix in build systems

Following up with reviewing capabilities of various build systems in previous post, recently I looked how to build all packages with custom --prefix and friends values. This is continuation of Optware for Android project, where I'd like to achieve ability to install on non-rooted device.

Here are the results:
  • I was surprised at first, but OpenWRT has --prefix hardcoded as /usr when calling configure. Fortunately, that call is in common file, so it would be easy to introduce configurable variable instead. However, it turns out that install routines, which are individual for each package, have /usr hardcoded either, so each recipe needs to be patched still, which is problem for maintainability and/or upstreaming.
  • Looking at Optware, situation is even worse - there, there's even less common infrastructure, and even configure call is hardcoded in each script with --prefix=/opt.
  • Buildroot, being prototype for OpenWRT, has the same hardcode at /usr.
  • I obviously turned to OpenEmbedded at that point (well, I tried Yocto this time) - it for sure always have had nice configurable variables for prefix and all other layout variables (--sysconfdir, etc.). Turned out, while variables are there, OE/Yocto is not ready out of the box to full configurability of both prefix and base_prefix. There were few issues seen:
    • Compiler search path issues. Some aspects of search paths (mostly related to shlib linking) appear to be not stored by gcc when configured during cross-compiler, and require command-line overrides. OE passes --sysroot on each invocation, but I had to add few -rpath-link directives to get it right. While it took some time to figure the need for -rpath-link, I'm still not sure I figured where to put them (well, per upstreamability criteria).
    • Some packages still hardcode paths, especially related to base_prefix. Sometimes it's a bit harder than trivial to patch (like with busybox).
    • Ordering issues. Some packages implicitly assume that base_prefix and prefix are different, and filter filesets during packaging by file prefix. This doesn't work if base_prefix==prefix, so requires reshuffling filtering patters and/or package order (fortunately, OE has well-defined package splitting order).