Universal and binary builds (was: Re: Is isysroot useful for non-universal?)
Ryan Schmidt
ryandesign at macports.org
Mon Mar 23 15:12:07 PDT 2009
On Mar 23, 2009, at 05:47, Anders F Björklund wrote:
> The +universal "variant" is a glorious mess that mixes all
> of fatness (universalness, archness, whatever...) and
> MDT and SDK together in one big undefined configuration.
>
> Back then in the day, ppc+i386/10.4/MacOSX10.4u.sdk seemed
> like a reasonable default for building "Universal Binaries".
> These days, i686+x86_64/10.5/MacOSX10.5.sdk is more popular*.
>
> There's some minimal separation into archs/target/sysroot,
> but it's still all covered with the "universal" variant -
> just like flags are covered with the "configure" target.
>
> Despite the fact that they cover much more than "just"
> universal (arch) and configure (autotools), that is...
> So it's more of a legacy quirk, than a design decision.
I'm getting really burned out on universal.
The default universal variant has severe problems, in that the
configure phase runs just once for all architectures combined, and
many programs' configure scripts are written wrong so they assume,
for example, the size of ints or the endianness of the processor
based on just one of the multiple architectures for which we're
trying to configure. The software then probably builds and installs
without error and we never learn of the problem until someone
actually tries to run it on another platform from the one it was
compiled on. Or maybe they don't notice until their data ends up
being corrupted. Port maintainers can add ed scripts to fix things
after the configure phase, but that only fixes it at that instant.
Who's to say the upstream software won't introduce new processor-
specific variables in a later version? How is the maintainer to
detect that this has occurred?
The new muniversal portgroup aims to solve this but has other severe
problems, in that the configure phase runs once for each
architecture, and some configure scripts are written wrong so they
try to run a program at configure time to learn things about the
build environment, which is not appropriate when cross-compiling. So
the configure script exits saying it cannot run a program when cross-
compiling, and the maintainer has to research what those values are
supposed to be for each architecture, possibly getting them wrong.
Many programs simply cannot be cross-compiled so then the list of
supported architectures is reduced, and it's a different list of
supported architectures depending on the computer doing the build.
What if we set aside what we have now for universal variants and
spent some energy on finally doing binary builds? Finish the script
that builds a port in a clean MacPorts tree in a chroot. Make it
package that up and send it to a download server. Modify MacPorts
base to look for, download and install those binaries first. Make
those binaries integrate properly with the registry. Begin by having
the build server only build the default variant of a port, but later
it can be expanded to build more combinations of variants. We can
work out a system later that allows more variant combinations of an
old port to be built without impacting the building of newly-updated
ports. Since the server will have multiple cores we can run multiple
ports' builds simultaneously, in multiple chroots.
I would want (at least) one build server for each OS and processor
combination, but if we began with just a single Intel Leopard
machine, that would cover the majority of users. If we add a
corresponding PowerPC Leopard machine, then we could do something
interesting: Once the Intel and PowerPC builds are sent to the
download server, the download server could combine both builds into a
single universal binary package. It would use lipo, probably assisted
by the code we have in the MacPorts merge procedure or the muniversal
portgroup. It would avoid the above problems with our existing
universal variants because the configure phase would run once for
each processor, on that processor. We wouldn't need to deal with SDKs
anymore. (I've never been comfortable with the idea of allowing the
user to specify an SDK in macports.conf, so I don't see it as a
problem that that would not be accommodated by our binary builds.)
Using the above, we would have stable 32-bit universal binaries. We
would also want each build server to separately build 64-bit
versions. Obviously the build servers would be 64-bit machines.
We would need a way for ports to indicate what architectures they can
be built for. The universal_archs_supported variable from the
muniversal portgroup should be formalized and brought into MacPorts
base. Only it should be renamed to not include the word universal,
because sometimes it's not about being universal at all. For example
wine lets you run Windows binaries on an Intel Mac. It can currently
be compiled on i386. It cannot be compiled on x86_64; I presume that
is a bug. It will never be possible to compile on ppc or ppc64
because a PowerPC Mac cannot run the Intel code contained within
Windows binaries. So totally unrelated to being universal or not, I
need to be able to indicate, via a better mechanism than
"universal_variant no" and a pre-fetch block, that the port can only
be built for i386.
We also need a way to indicate that a port has no compiled parts and
only needs to be packaged up once. For example all the xorg-*proto
ports.
We also need a way to indicate that a port already provides binaries
of a certain architecture. For example isightcapture and oracle-
instantclient.
Ports would no longer need to include any directives for cross-
compiling universal, because that would no longer be done. Some ports
would possibly need to include directives for compiling 64-bit, for
software that doesn't manage that on its own. We could provide a
platform selector ("64bit") that ports could use to easily deal with
this, for example:
platform darwin 64bit {
configure.args-append --disable-some-carbon-feature
}
More information about the macports-dev
mailing list