octave-maintainers
[Top][All Lists]
Advanced

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

Re: Succees on OSX 64-bit with development branch


From: Jarno Rajahalme
Subject: Re: Succees on OSX 64-bit with development branch
Date: Wed, 21 Apr 2010 18:12:26 -0700

On Apr 21, 2010, at 5:45 PM, ext Jarno Rajahalme wrote:

> 
> On Apr 21, 2010, at 5:08 PM, ext Ben Abbott wrote:
> 
>> On Apr 21, 2010, at 5:18 PM, Jarno Rajahalme wrote:
>> 
>>> On Apr 15, 2010, at 11:58 AM, ext Jarno Rajahalme wrote:
>>> 
>>>> The root of the problem seems to be the linkage from line 24 to 23: Why 
>>>> would the gcc 4.4 libstdc++.6.dylib link to a streambuf function in the 
>>>> system libstdc++, and not it's own copy of it?
>>>> ...
>>>> How it is possible that a call to a function within GCC 4.4 libstdc++ is 
>>>> resolved at the load time, and to a different library (system's version of 
>>>> the libstdc++)? Could the linking be somehow changed to have GCC 4.4 
>>>> libstdc++ use it's own version of the function?
>>>> 
>>>> For some reason unknown to me, configuring with --without-framework-opengl 
>>>> produces binaries where this problem does not arise (no seg fault), even 
>>>> when there still are two different copies of libstdc++ within the binary 
>>>> images. The system version of libstdc++ is pulled in by libGLU, which is 
>>>> linked in regardless of the framework-opengl status.
>>> 
>>> Short recap: in OSX, system dylibs pull in the system version of the 
>>> libstdc++.6.dylib. When using GCC > 4.2, the code needs to be linked with a 
>>> newer libstdc++.6.dylib. Having two copies of the same dylib linked in 
>>> causes some weird results, caused by one libstdc++ linking to another, 
>>> which results in malloc/free errors, segmentation faults, aborts, etc.
>>> 
>>> The solution to this linking problem was quite easy, when found. All it 
>>> takes is to have the newer libstdc++ (e.g. 
>>> /opt/local/lib/gcc44/libstdc++.6.dylib) in the LDFLAGS. This way to 
>>> cross-linkage between the different versions seems to go away, no seg 
>>> faults, and all tests (but the one of the svds tests) succeed.
>>> 
>>> There is also a linking option -dylib_file, which, according to the man ld 
>>> is intended for resolving a similar kind of a problem. However having 
>>> "-dylib_file 
>>> /usr/lib/libstdc++.6.dylib:/opt/local/lib/gcc44/libstdc++.6.dylib" in 
>>> LDFLAGS did not help, there are still two versions of libstdc++.6.dylib 
>>> linked in.
>>> 
>>> Finally, there is the linking option -flat_namespace, which reveals the 
>>> duplicate libraries at the link time (warnings), but did not resolve the 
>>> problem.
>>> 
>>> In the end, neither of these options is required.
>>> 
>>> Jarno
>> 
>> Jarno, did you build all dependencies with the same version of the gcc 
>> compiler and link to Apple's frameworks, or did you mix versions of gcc when 
>> building dependencies?
>> 
>> Also, were any of the dependencies built under Leopard (10.5), or did you 
>> rebuild all of them using Snow Leopard (10.6)?
>> 
>> Ben
>> 
>> p.s. notice I've switch to bottom posting so that late comers can follow 
>> along more easily.
> 
> I started out using Octave on Mac on Leopard, but I think all of the 
> dependencies were rebuild when switching to a newer version of macports, 
> while on Snow Leopard. Macports Octave 3.2.3 has been a 64-bit build from 
> since I upgraded to 10.6, since I have been using 64-bit kernel all along, 
> and the ports build according to the running kernel architecture.
> 
> I think rebuilding is actually mandatory, as the binary interface is 
> different between 32-bit (i386) and 64-bit (x86_64). You can't link 32-bit 
> and 64-bit together, as the linking phase will fail due to incompatible 
> architectures.
> 
> I had a seg fault in eigs() test for a long time, and that turned out to be 
> due to macports arpack being built with -ff2c, while everything else is built 
> without (including Octave). In the process of figuring this out I have 
> locally built atlas (including lapack), with errata from the atlas site, 
> qrupdate (with a fix from Octave maintainers list), and arpack, now with 
> proper compiler options (no -ff2c).
> 
> I recall that you have been using the -ff2c version using fink and Apple 
> accelerated blas? There is a bug in the 64-bit apple blas library, as it is 
> not following the f2c calling conventions regarding returning single 
> precision floats. This is the reason configure fails in 64-bit, if using 
> Apple blas library (veclib). I reported this to Apple, and someone responded 
> to me at MacResearch and confirmed that this is really an Apple bug. So, for 
> the time being, you have to use atlas for blas, if building 64-bit, as 
> Apple's doesn't work either with or without -ff2c.
> 
> macports atlas is linked with compiler-specific fortran libraries. While this 
> is probably no problem, I built them locally so that the fortran library 
> references are left unresolved, so that they are resolved to whatever fortran 
> library octave is built with. Officially, you should not mix new code and 
> older library (older code and newer library should be fine), but apparently 
> there has not been any significant change in libgfortran, so that using 4.2 
> library with code compiled with 4.4 still works as intended.
> 
> I have successfully built octave 64-bit now with both Apple GCC 4.2 (with 
> gfortran from the R-site) and macport GCC 4.4. The only quirk with the former 
> was that the gfortran installation from the R-site did not include a dylib 
> version of libgfortran, so I had to build that from the static library. With 
> static libgfortran octave itself linked ok, but my atlas dylib did not find 
> the missing gfortran symbols.
> 
> So, to make it clear, yes, I have mixed versions, building some of the 
> dependencies with GCC 4.4, and using Apple GCC 4.2 to build octave. Linking 
> to Apple frameworks worked fine all along, when compiling Octave with Apple 
> GCC 4.2. Many of my dependencies are still from macports, some build with GCC 
> 4.3, some with GCC 4.4. These dependencies have NOT been rebuilt after I 
> upgraded to Xcode 3.2.2 two weeks ago.
> 
> The LDFLAGS stuff I mentioned above allowed me to build and link Octave with 
> macports GCC 4.4 while linking to Apple frameworks.
> 
>  Jarno
> 
> 


I need to add that there is one remaining gnulib problem, when building 64-bit 
on OSX. However, due to changes in GCC includes, this problem is not showing up 
any more in GCC 4.4. But this is an acute problem building Octave with Apple 
GCC 4.2 or GCC 4.3. The problem is that gnulib defines int64_t as "long int" if 
in 64-bit, and "long long int" if in 32-bit, while Apple has it typedef'd as 
"long long" either way. Even though the length is the same (64 bits), there is 
a C++ name mangling difference between the two, so linking fails. I.e., gnulib 
breaks the 64-bit ABI. I have reported this to the gnulib bug list (many 
times), but so far there has been only one short response, no idea when this is 
going to be fixed.

However, this is easy enough to fix locally with the following patch (while in 
octave/gnulib):

--- a/lib/stdint.in.h
+++ b/lib/stdint.in.h
@@ -135,7 +135,8 @@ typedef unsigned int gl_uint32_t;
 
 /* Do not undefine int64_t if gnulib is not being used with 64-bit
    types, since otherwise it breaks platforms like Tandem/NSK.  */
-#if LONG_MAX >> 31 >> 31 == 1
+/* OSX needs int64_t to be "long long" rather than "long int" */
+#if LONG_MAX >> 31 >> 31 == 1 && !(defined (__APPLE__) && defined (__MACH__))
 # undef int64_t
 typedef long int gl_int64_t;
 # define int64_t gl_int64_t
@@ -152,7 +153,8 @@ typedef long long int gl_int64_t;
 # define GL_INT64_T
 #endif
 
-#if ULONG_MAX >> 31 >> 31 >> 1 == 1
+/* OSX needs uint64_t to be "long long" rather than "long int" */
+#if ULONG_MAX >> 31 >> 31 >> 1 == 1 && !(defined (__APPLE__) && defined 
(__MACH__))
 # undef uint64_t
 typedef unsigned long int gl_uint64_t;
 # define uint64_t gl_uint64_t


This is a clear error in gnulib, as earlier in the file there is a comment that 
states that the defines should be consistent with the system versions, while in 
the case of 64-bit OSX they are not.

I prefer patching the gnulib itself, so that "git diff" in the gnulib directory 
will see the difference.

After patching, while in octave directory:
$ gnulib/gnulib-tool --import

The only other patch needed is from you, regarding the -pthreads:

--- a/m4/acx_pthread.m4 Wed Apr 14 22:15:34 2010 +0300
+++ b/m4/acx_pthread.m4 Wed Apr 21 17:57:01 2010 -0700
@@ -149,6 +149,10 @@
 
         acx_pthread_flags="-pthreads pthread -mt -pthread $acx_pthread_flags"
         ;;
+
+       *-darwin*)
+       acx_pthread_flags="-pthread"
+       ;;
 esac
 
 if test x"$acx_pthread_ok" = xno; then


This I believe should be fixed in Octave, of where is this file coming from?

So, compiling with macports GCC 4.4 I source the following before doing 
"./configure":

    export CPPFLAGS="-I${dev_prefix}/include -I${ports_prefix}/include"
    export CFLAGS="-O2 -m64 $CPPFLAGS"
    export CXXFLAGS="-O1 -m64 $CPPFLAGS"
    export FFLAGS="-O2 -m64 $CPPFLAGS"

    export LDFLAGS="${ports_prefix}/lib/gcc44/libstdc++.6.dylib 
-L${dev_prefix}/lib -L${ports_prefix}/lib"

    export CC="gcc-mp-4.4"
    export CPP="cpp-mp-4.4"
    export CXX="g++-mp-4.4"
    export F77="gfortran-mp-4.4"
    
    export MACOSX_DEPLOYMENT_TARGET=10.6
    
    export PERL="${ports_prefix}/bin/perl"
    export AWK="${ports_prefix}/bin/gawk"
    export SED="${ports_prefix}/bin/gsed"
    export FLEX="${ports_prefix}/bin/flex"
    export MAKEINFO="${ports_prefix}/bin/makeinfo"
    export TEXI2DVI="${ports_prefix}/bin/texi2dvi"
    export TEXI2PDF="${ports_prefix}/bin/texi2pdf"
    export LIBTOOLIZE="${ports_prefix}/bin/glibtoolize"
    export LIBTOOL="${ports_prefix}/bin/glibtool"

${dev_prefix} is to the directory where I have my locally built dependencies, 
and ${ports_prefix} is for macports.

  Jarno




reply via email to

[Prev in Thread] Current Thread [Next in Thread]