Re: [gtk-osx-users] Universal ppc/i386 build



On Jan 23, 2013, at 9:53 AM, Steffen Gutmann <muibase yahoo com> wrote:

>> Sorry, I don't have time today for a proper answer, but
> 
>> 
>> http://www.sourceware.org/autobook/autobook/autobook_258.html#SEC258
>> 
>> will get you started.
>> 
>> The universal module runs those packages which need it twice and lipos them 
>> together. I think
>> https://developer.apple.com/library/mac/#documentation/Porting/Conceptual/PortingUnix/compiling/compiling.html
>> talks about the process, but you can also look at setup_universal() in .jhbuild 
>> and read the man page for lipo.
> 
> 
> Thanks for the pointers.
> 
> I can see that building a module multiple times, once for each architecture using the (build,host,target) variables and lipo'ing the binaries together should work.  Although, it seems that for 95 % of the source files the universal binary could be generated directly by a single compile run.
> 
> But how about header files that are installed in ~/gtk/inst/include?  In glib, for example we have the G_BYTE_ORDER define, which I changed into the following in the configure script:
> 
> #if defined(__POWERPC__)
> +    #define G_BYTE_ORDER G_BIG_ENDIAN
> +#elif defined(__i386__)
> +    #define G_BYTE_ORDER G_LITTLE_ENDIAN
> +#else
> +    #define G_BYTE_ORDER $g_byte_order
> +#endif
> 
> Similar things apply to ffitarget.h in libffi which depends on whether we compile for ppc or x86.
> 
> Your second link actually suggest to make use of the preprocessor symbols:
> 
> --------------------
> The best fix is to replace configure-time detection of endianness, data type sizes, and so on with compile-time or run-time detection. For example, instead of testing the architecture for endianness to obtain consistent byte order in a file, you should do one of the following:
> 
> Use C preprocessor macros like __BIG_ENDIAN__ and __LITTLE_ENDIAN__ to test endianness at compile time.
> Use functions like htonl, htons, ntohl, and ntohs to guarantee a big-endian representation on any architecture.
> Extract individual bytes by bitwise masking and shifting (for example, lowbyte=word & 0xff; nextbyte = (word >> 8) & 0xff; and so on).
> -----------------
> 
> (I just learned that I should have used __BIG_ENDIAN__ and __LITTLE_ENDIAN__ instead of __POWERPC__ and __i386__).

Steffen,

This is what has kicked my butt every time I've tried to make universal builds work. You're right that 95% of the time just passing multiple arch flags to the compiler does the right thing. It's the other 5%, which includes GLib ,Gtk (actually gdk-pixbuf IIRC -- I haven't looked at this since it was split back out into a separate library), and libffi: Anything doing bit-twiddling cares and has to be written so that it will execute the right code. Nobody but Apple is doing this universal binary thing, and the FOSS community doesn't really think about it when they're prematurely optimizing.

Note that the __BIG_ENDIAN__/__LITTLE_ENDIAN__ flags are Apple-only.

But ISTM that if you tell configure to build ppc that it should tell gcc, and that AC_C_BIGENDIAN should set $ac_cv_c_bigendian to "yes" and you shouldn't have to write your own macros.

But that's not the *real* problem. That problem is that configure writes a value to G_BYTE_ORDER in $PREFIX/lib/glib-2.0/glibconfig.h, there's only one, and that's used not only in glib itself (where separate runs of configure for each architecture will take care of the problem for that particular build) but in other dependent libraries. Setup_universal_build() tries to finesse that by building separate trees for each architecture, but I was never able to get it to work right and gave up. The correct fix would determine endianess at compile time rather than at configure time.

Regards,
John Ralls



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]