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
}


_______________________________________________
macports-dev mailing list
[email protected]
http://lists.macosforge.org/mailman/listinfo.cgi/macports-dev

Reply via email to