php5 as universal binary (Mac OS X)

php.internals

Christian Speich

19 years ago
hello, I have asked in the gernal php list and they say I should be ask here: I have an problem with php5 as universal binary on Mac OsX. The universal binary was build on an intel mac and it works good... on an intel mac ;) When a friend it try on an ppc mac he had some problems. For example phpsqliteadmin say this error: Fatal error: Balloc() allocation exceeds list boundary in /Applications/xampp/xamppfiles/phpsqliteadmin/SPSQLite.class.php on line 998 And phpmyadmin loads and loads and loads and loads... BUT my php4 universal binary works perfect on intel and ppc macs... :/ My configure for php5 look like this: PREFIX=/Applications/xampp/xamppfiles SYSCONFDIR=/Applications/xampp/etc export LD_RUN_PATH="$PREFIX/lib" export LD_LIBRARY_PATH="$PREFIX/lib" export CFLAGS="-I$PREFIX/include -L$PREFIX/lib -isysroot /Developer/SDKs/MacOSX10.4u.sdk" export CPPFLAGS="-I$PREFIX/include" export CXXFLAGS="-I$PREFIX/include -L$PREFIX/lib" export LDFLAGS="-L$PREFIX/lib -I$PREFIX/include" export SOFLAGS="-L$PREFIX/lib" CFLAGS="$CFLAGS -arch i386 -arch ppc" ./configure --prefix=$PREFIX --program-suffix=-5.2.3 --libdir=$PREFIX/lib/php/php5 --includedir= $PREFIX/include/php/php5 --with-apxs2=$PREFIX/bin/apxs --with-config-file-path=$SYSCONFDIR --with-mysql=$PREFIX --disable-debug --enable-bcmath --enable-calendar --enable-ctype --enable-dbase --enable-discard-path --enable-exif --enable-filepro --enable-force-cgi-redirect --enable-ftp --enable-gd-imgstrttf --enable-gd-native-ttf --with-ttf --enable-magic-quotes --enable-memory-limit --enable-safe-mode --enable-shmop --enable-sigchild --enable-sysvsem --enable-sysvshm --enable-track-vars --enable-trans-sid --enable-wddx --enable-yp --with-ftp --with-ncurses= $PREFIX --with-gdbm=$PREFIX --with-jpeg-dir=$PREFIX --with-png-dir= $PREFIX --with-freetype-dir=$PREFIX --without-xpm --with-zlib=yes --with-zlib-dir=$PREFIX --with-openssl=$PREFIX --with-expat-dir=$PREFIX --enable-xslt=$PREFIX --with-xsl=$PREFIX --with-dom=$PREFIX --with-ldap= $PREFIX --with-gd=$PREFIX --with-mysql-sock=$PREFIX/var/mysql/mysql.sock --with-mcrypt=$PREFIX --with-mhash=$PREFIX --enable-sockets --with-curl=$PREFIX --enable-mbregex --enable-zend-multibyte --with-zip= $PREFIX --enable-exif --with-sqlite --with-libxml-dir=$PREFIX --enable-soap --enable-pcntl --enable-dbx --with-mysqli= $PREFIX/bin/mysql_config --with-bz2=$PREFIX --with-pear= $PREFIX/lib/php/pear --with-mssql=$PREFIX --with-imap-dir=$PREFIX --with-imap=$PREFIX --enable-mbstring=all --with-pgsql=shared,/usr --with-gettext=$PREFIX I don't think thats this are errors from the php-scripts, I think thats an problem with php. I hope you can help me to resolve this problem thanks, kleinweby

Antony Dovgal

19 years ago
Intel Mac is little-endian, PPC Mac is big-endian. Endiannes is detected during configure run, that's why the binary works fine on Intel Mac, but not on PPC. To make it work on both you either need to build separate binaries on PPC and Intel, and then merge them (IIRC that was possible), or you need to patch PHP sources. In my case patching PHP sources was the easiest solution, so I replaced WORDS_BIGENDIAN macro (defined by configure) with __BIG_ENDIAN__ (defined by Mac GCC in compile time). If anyone have any suggestions on how to improve universal binary support so that it would not require patching, I'd gladly listen to them. On 27.07.2007 13:15, Christian Speich wrote:
> hello, > > I have asked in the gernal php list and they say I should be ask here: > > I have an problem with php5 as universal binary on Mac OsX. > > The universal binary was build on an intel mac and it works good... on > an intel mac ;) > > When a friend it try on an ppc mac he had some problems. > > For example phpsqliteadmin say this error: > Fatal error: Balloc() allocation exceeds list boundary > in /Applications/xampp/xamppfiles/phpsqliteadmin/SPSQLite.class.php on > line 998 > > And phpmyadmin loads and loads and loads and loads... > > BUT my php4 universal binary works perfect on intel and ppc macs... :/ > > My configure for php5 look like this: > > PREFIX=/Applications/xampp/xamppfiles > SYSCONFDIR=/Applications/xampp/etc > > export LD_RUN_PATH="$PREFIX/lib" > export LD_LIBRARY_PATH="$PREFIX/lib" > export CFLAGS="-I$PREFIX/include -L$PREFIX/lib > -isysroot /Developer/SDKs/MacOSX10.4u.sdk" > export CPPFLAGS="-I$PREFIX/include" > export CXXFLAGS="-I$PREFIX/include -L$PREFIX/lib" > export LDFLAGS="-L$PREFIX/lib -I$PREFIX/include" > export SOFLAGS="-L$PREFIX/lib" > > CFLAGS="$CFLAGS -arch i386 -arch ppc" ./configure --prefix=$PREFIX > --program-suffix=-5.2.3 --libdir=$PREFIX/lib/php/php5 --includedir= > $PREFIX/include/php/php5 --with-apxs2=$PREFIX/bin/apxs > --with-config-file-path=$SYSCONFDIR --with-mysql=$PREFIX --disable-debug > --enable-bcmath --enable-calendar --enable-ctype --enable-dbase > --enable-discard-path --enable-exif --enable-filepro > --enable-force-cgi-redirect --enable-ftp --enable-gd-imgstrttf > --enable-gd-native-ttf --with-ttf --enable-magic-quotes > --enable-memory-limit --enable-safe-mode --enable-shmop > --enable-sigchild --enable-sysvsem --enable-sysvshm --enable-track-vars > --enable-trans-sid --enable-wddx --enable-yp --with-ftp --with-ncurses= > $PREFIX --with-gdbm=$PREFIX --with-jpeg-dir=$PREFIX --with-png-dir= > $PREFIX --with-freetype-dir=$PREFIX --without-xpm --with-zlib=yes > --with-zlib-dir=$PREFIX --with-openssl=$PREFIX --with-expat-dir=$PREFIX > --enable-xslt=$PREFIX --with-xsl=$PREFIX --with-dom=$PREFIX --with-ldap= > $PREFIX --with-gd=$PREFIX --with-mysql-sock=$PREFIX/var/mysql/mysql.sock > --with-mcrypt=$PREFIX --with-mhash=$PREFIX --enable-sockets > --with-curl=$PREFIX --enable-mbregex --enable-zend-multibyte --with-zip= > $PREFIX --enable-exif --with-sqlite --with-libxml-dir=$PREFIX > --enable-soap --enable-pcntl --enable-dbx --with-mysqli= > $PREFIX/bin/mysql_config --with-bz2=$PREFIX --with-pear= > $PREFIX/lib/php/pear --with-mssql=$PREFIX --with-imap-dir=$PREFIX > --with-imap=$PREFIX --enable-mbstring=all --with-pgsql=shared,/usr > --with-gettext=$PREFIX > > I don't think thats this are errors from the php-scripts, I think thats > an problem with php. > > I hope you can help me to resolve this problem > > thanks, > kleinweby >
-- Wbr, Antony Dovgal

Jani Taskinen

19 years ago
Just sponsor me with one of these Apple laptops and I can see what I can do for it.. ;) --Jani On Fri, 2007-07-27 at 13:45 +0400, Antony Dovgal wrote:

Uwe Schindler

19 years ago
The simpliest would be to create a patch that is included *after* the configure-generated .h file. I do not exactly now, in which PHP/Zend specific .h file the configure generated php_config.h one is included, but that would be the place to place the following macro: #if defined(MACOSX) (I do not know the exact macro for detecting osx) # undef WORDS_BIGENDIAN # define WORDS_BIGENDIAN __BIG_ENDIAN__ #endif Just an idea. Or just update to a newer autoconf version that can detect this (I know newer ones do this correctly). But this is not possible for PHP. ----- Uwe Schindler thetaphi@php.net - http://www.php.net NSAPI SAPI developer Bremen, Germany

Antony Dovgal

19 years ago
On 27.07.2007 14:23, Uwe Schindler wrote:
> The simpliest would be to create a patch that is included *after* the > configure-generated .h file. I do not exactly now, in which PHP/Zend > specific .h file the configure generated php_config.h one is included, but > that would be the place to place the following macro: > > #if defined(MACOSX) (I do not know the exact macro for detecting osx) > # undef WORDS_BIGENDIAN > # define WORDS_BIGENDIAN __BIG_ENDIAN__ > #endif
I'm not completely sure it's ok when you're NOT compiling a universal binary. Also the __BIG_ENDIAN__ constant my not exist IIRC. But the main reason of course is the fact that the patch I use works just fine and I'm not relly interested in debugging something that isn't broken for me. If you are - feel free to spend some time on this issue, I'd help you where I can.
-- Wbr, Antony Dovgal

Uwe Schindler

19 years ago
On http://developer.apple.com/documentation/Porting/Conceptual/PortingUnix/comp iling/chapter_4_section_3.html Apple states: "However, applications that make configuration-time decisions about the size of data structures will generally fail to build correctly in such an environment (since those sizes may need to be different depending on whether the compiler is executing a ppc pass, a ppc64 pass, or an i386 pass). When this happens, the tool must be configured and compiled for each architecture as separate executables, then glued together manually using lipo(1). In rare cases, software not written with cross-compilation in mind will make configure-time decisions by executing code on the build host. In these cases, you will have to manually alter either the configuration scripts or the resulting headers to be appropriate for the actual target architecture (rather than the build architecture). In some cases, this can be solved by telling the configure script that you are cross-compiling using the --host, --build, and --target flags. However, this may simply result in defaults for the target platform being inserted, which doesn't really solve the problem. 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). Similarly, instead of performing elaborate tests to determine whether to use int or long for a 4-byte piece of data, you should simply use a standard sized type such as uint32_t." So a good test would be to check if one of both macros is defined and its an apple gcc: #if (defined(__APPLE__) || defined(__APPLE_CC__)) && (defined(__BIG_ENDIAN__) || defined(__LITTLE_ENDIAN__)) # undef WORDS_BIGENDIAN # define WORDS_BIGENDIAN __BIG_ENDIAN__ #endif If gcc is not the apple one the configure value is used. If it is an apple one, but a very old one neither BIG or LITTLE endian is defined, which also lets configure test it. But if one of both is defined then we can rely on the macros. Uwe Schindler H.-H.-Meier-Allee 63, D-28213 Bremen http://www.thetaphi.de eMail: uwe@thetaphi.de

Antony Dovgal

19 years ago
Uwe, could you plz test this patch? http://dev.daylessday.org/diff/macos_uni.diff Thanks. On 27.07.2007 16:21, Uwe Schindler wrote:
> On > http://developer.apple.com/documentation/Porting/Conceptual/PortingUnix/comp > iling/chapter_4_section_3.html Apple states:
-- Wbr, Antony Dovgal

Uwe Schindler

19 years ago
Hi Antony, the problem is that my VMWare-patched MacOSX is corrupt. I have to reinstall it and also install XCode. And my "official Mac" is a PowerPc one that cannot create universal binaries. It could be better for a fast answer to ask the person (Christian Speich) who originally asked for help to test your patch. ----- Uwe Schindler thetaphi@php.net - http://www.php.net NSAPI SAPI developer Bremen, Germany

Christian Speich

19 years ago
hey, i try to test it and report then here :) kleinweby Am 09.08.2007 um 18:03 schrieb Uwe Schindler:

Christian Speich

19 years ago
hello again, so now i have the test results :) (I dont have an ppc mac, so i ask an friend) And it dosn't work! When i configure it on an intel mac, the WORDS_BIDENDIAN macro will never definied. But i need to define this macro when the compiler runs the ppc-compile. I think the code should look like this: if (defined(__APPLE__) || defined(__APPLE_CC__)) && (defined (__BIG_ENDIAN__) || defined(__LITTLE_ENDIAN__)) # if defined(__LITTLE_ENDIAN__) # undef WORDS_BIGENDIAN # else if defined(__BIG_ENDIAN__) # define WORDS_BIGENDIAN # endif #endif I will test it later. kleinweby Am 09.08.2007 um 18:03 schrieb Uwe Schindler:

Antony Dovgal

19 years ago
On 13.08.2007 14:09, Christian Speich wrote:
> hello again, > > so now i have the test results :) (I dont have an ppc mac, so i ask > an friend)
As far as I know, GCC on PPC is unable to generate universal binaries, so I don't understand what exactly you were testing there..
> And it dosn't work! > > When i configure it on an intel mac, the WORDS_BIDENDIAN macro will never definied.
Right, because Intel is little endian.
> But i need to define this macro when the compiler runs the ppc-compile.
That's why the ifdefs check for __LITTLE_ENDIAN__ and __BIG_ENDIAN__ which are defined by Apple's GCC.
> I think the code should look like this: > > if (defined(__APPLE__) || defined(__APPLE_CC__)) && (defined > (__BIG_ENDIAN__) || defined(__LITTLE_ENDIAN__)) > # if defined(__LITTLE_ENDIAN__) > # undef WORDS_BIGENDIAN > # else if defined(__BIG_ENDIAN__) > # define WORDS_BIGENDIAN > # endif > #endif
Yes, I guess you're right.
-- Wbr, Antony Dovgal

Christian Speich

19 years ago
hello,
>> I think the code should look like this: >> if (defined(__APPLE__) || defined(__APPLE_CC__)) && (defined >> (__BIG_ENDIAN__) || defined(__LITTLE_ENDIAN__)) >> # if defined(__LITTLE_ENDIAN__) >> # undef WORDS_BIGENDIAN >> # else if defined(__BIG_ENDIAN__) >> # define WORDS_BIGENDIAN >> # endif >> #endif > > Yes, I guess you're right. >
I have tested it and it works good :) kleinweby

David

19 years ago
Isn't an universal binary just two binaries packaged together? One has to be compiled for Intel and the other for PowerPC. How exactly is this currently being done in a single run on Christian's machine? Is there a special build tool that runs the compilation twice or a special compiler that generates two binaries? Something tells me that you'd have to know how this tool works and this would not be an extremely easy thing to fix. On 7/27/07, Uwe Schindler <thetaphi@php.net> wrote:

Antony Dovgal

19 years ago
On 27.07.2007 14:47, David Wang wrote:
> Isn't an universal binary just two binaries packaged together?
Yes.
> One has to be compiled for Intel and the other for PowerPC.
GCC is able to build both on Intel.
> How exactly is this currently being done in a single run on Christian's machine?
It should be as easy as CFLAGS="-arch ppc -arch i386", that's it.
> Is there a special build tool that runs the compilation twice or a > special compiler that generates two binaries? > > Something tells me that you'd have to know how this tool works and > this would not be an extremely easy thing to fix. > > On 7/27/07, Uwe Schindler <thetaphi@php.net> wrote: >> The simpliest would be to create a patch that is included *after* the >> configure-generated .h file. I do not exactly now, in which PHP/Zend >> specific .h file the configure generated php_config.h one is included, but >> that would be the place to place the following macro: >> >> #if defined(MACOSX) (I do not know the exact macro for detecting osx) >> # undef WORDS_BIGENDIAN >> # define WORDS_BIGENDIAN __BIG_ENDIAN__ >> #endif >> >> Just an idea. >> Or just update to a newer autoconf version that can detect this (I know >> newer ones do this correctly). But this is not possible for PHP. >
-- Wbr, Antony Dovgal

Christian Speich

19 years ago
thanks, thats great :) I would be try now if it works. I add these two lines after the configure to the main/php-config.h i hope its correct: #undef WORDS_BIGENDIAN #define WORDS_BIGENDIAN __BIG_ENDIAN__ thank you, kleinweby :) Am Freitag, den 27.07.2007, 12:23 +0200 schrieb Uwe Schindler:

Christian Speich

19 years ago
it looks good, very good :) i have add the followings lines to the php-config.h #if defined(__BIG_ENDIAN__) # undef WORDS_BIGENDIAN # define WORDS_BIGENDIAN __BIG_ENDIAN__ #endif Note: __BIG_ENDIAN__ is only defined when we bulid ppc thank you, kleinweby Am Freitag, den 27.07.2007, 12:47 +0200 schrieb Christian Speich: