I'm working with PAR executables on Mac OSX and am trying to support
both x86 and PPC architectures. I've come up with an idea for how to
implement Universal Binaries in PAR, and would like some feedback on
the feasibility of this design before I begin implementation.
== Background ==
Apple has a multi-architecture file format they call Universal
Binary. This file format works by compiling two binary images and
merging them into one file package via the "lipo" command-line tool.
This file package usually has a 60-byte header indicating which
architectures are present and what their offsets and sizes are in the
file. PPC machines just use the PPC branch, or die. Intel machines
use the x86 branch, if present, or the PPC branch via emulation.
This latter decision happens exactly once per process -- i.e. if the
main executable is run via PPC emulation, all dynamically-loaded
libraries must run under PPC too even if they are themselves Universal.
== Problem ==
PAR executables have several architecture-dependent components: the
executable header, the libperl shlib, various XS .bundle files, and
possibly other embedded shlibs (via "pp -l"). If the PAR is PPC-
only, it works fine on both platforms (yay!) but runs slowly under
PPC emulation on Intel machines. I would like to make all binary
components be Universal so a single PAR can be run optimally on both
platforms, at the expense of file size. However, I don't want to
duplicate files (like .pm) that are already cross-platform.
== Proposal ==
I propose a "par_lipo" command that works analogously to Apple's
"lipo". par_lipo accepts two PAR executables, one compiled for PPC
and one for x86, and merges them into a single larger PAR
executable. The steps involved would be:
* compare the embedded .zip containers file-by-file (including
libperl)
- if the file is present in one PAR and missing in the other, die
- if the file is already Universal in either PAR, keep that one
- if the file is single-architecture binary, merge via Apple's
"lipo" and reinsert
- if the file is not binary and is byte-wise different in the
two PARs, die
- if the file is not binary and is the same in both PARs, keep
it as-is
* create a "lipo"d header for the executable
The strict "die" scenarios above ensure that the PARs don't have
different versions of various libraries -- a real problem since the
originating PARs may be built on different machines.
I've glossed over a few points in the above where I need more
research or input:
* How hard is the "reinsert" step?
Do I need to recompute MD5s and MANIFEST records?
* What is the header that I need to lipo in the last section?
Can I find that header in the PAR distro?
Should I take an existing PAR executable and empty its .zip
container?
== Rejected ideas ==
Here's a couple of (straw man?) counter-ideas that reinforce the
above proposal:
* Why not just build the binaries Universal in the first place?
This is what I initially pursued, following advice on how to build
Universal XS bundles. However, there are just too many important
libraries that lack the infrastructure to easily build Universal --
like the Fink collection of software, which is explicitly and
deliberately not Universal.
* Why not just "lipo" the two PARs as-is?
The way PAR accesses the embedded .zip container, only one of the
containers would be found. Thus for one of the architectures, the
wrong binaries would be found for XS bundles and the program would
crash.
* Why not use PAR's existing multi-arch infrastructure?
Not allowed for standalone executables.
* Why not use PAR's "pp -P" standalone scripts?
This is a possibility, but would still need some of the "lipo" work
detailed above, just not on the executable header.
* Why not use a thin wrapper that decides which PAR to use and exec
()s that one?
Inelegant and larger file size. I prefer a monolithic file so users
can't as easily lose an important piece.
Chris
--
Chris Dolan, Software Developer, Clotho Advanced Media Inc.
608-294-7900, fax 294-7025, 1435 E Main St, Madison WI 53703
vCard: http://www.chrisdolan.net/ChrisDolan.vcf
Clotho Advanced Media, Inc. - Creators of MediaLandscape Software
(http://www.media-landscape.com/) and partners in the revolutionary
Croquet project (http://www.opencroquet.org/)