Opened 9 years ago

Closed 9 years ago

#33006 closed enhancement (fixed)

enhancement: gcc46 variant for R-framework

Reported by: adfernandes (Andrew Fernandes) Owned by: kjell.konis@…
Priority: Normal Milestone:
Component: ports Version: 2.0.3
Keywords: haspatch Cc:
Port: R-framework

Description

The compilers used by R-framework are quite old and have problems with many modern extensions that rely on more modern C++ or Fortran compilers.

I have tried a lot of mugging about with Makevars and so on, and it is very difficult to control how extensions get built using this technique.

The attached patch enables gcc46 to be the default compiler, falling back to the original llvm-gcc-4.2 from MacPorts for OBJC and OBJCXX.

I've build and run many extensions with this patch, and it seems robust, even using the quartz graphics device, or mixed quartz plus x11.

Great work on these ports, BTW - that's a lot of munging around to get things to work!

Attachments (2)

Portfile.diff (858 bytes) - added by adfernandes (Andrew Fernandes) 9 years ago.
add gcc46 variant
Portfile.2.diff (1.7 KB) - added by kjell.konis@… 9 years ago.

Download all attachments as: .zip

Change History (7)

Changed 9 years ago by adfernandes (Andrew Fernandes)

Attachment: Portfile.diff added

add gcc46 variant

comment:1 Changed 9 years ago by kjell.konis@…

When the R port is built as a framework it links against the CoreFoundation framework. The whole reason for using the macports-llvm-gcc-4.2 compilers is that they (1) are supposed to binary compatible with Apple's Xcode provided compilers and (2) they include compilers for Fortran, C, C++ and Objective C (I am not a fan of mixing and match different compilers/versions). The last time (a long time ago) I tried to use the gcc compilers to build R-framework was with macports gcc 4.2 on Tiger and then any R package that used C++ iostream caused R to segfault. Anyway, my Hello World C++ test program runs fine with this patch so maybe this is no longer an issue... It would b nice if someone with more compiler knowledge could confirm this for me though.

comment:2 Changed 9 years ago by adfernandes (Andrew Fernandes)

I understand completely. I have been bitten by the "different pieces compiled by different compilers" bug before, and it was a nightmare to sort out.

I believe that some of the old problems were caused by an ABI change in gcc back in the early 4-something days. That was horrible. Plus, now I believe that for shared objects as long as you link to the correct libgcc_s initialization library, you should never have a problem combining shared objects with an executable no matter the compiler version.

Objective-C is a tricky beast, though. Here we're talking about compiling one object via apple's gcc then linking with the gcc runtime... I did a DYLD_PRINT_LIBRARIES=1 for R and used the quartz plotting system as a test just now. The first few entries are

dyld: loaded: /opt/local/Library/Frameworks/R.framework/Versions/2.14/Resources/library/grDevices/libs/x86_64/grDevices.so
dyld: loaded: /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit
dyld: loaded: /System/Library/Frameworks/ApplicationServices.framework/Versions/A/ApplicationServices
dyld: loaded: /System/Library/Frameworks/Foundation.framework/Versions/C/Foundation
...

Now all of these, including R's grDevices.so' link to the system /usr/lib/libobjc.A.dylib`.

I've checked ALL the libraries in ALL of the executable and shared objects in the R port, and NONE of them link to any of the /opt/local/lib/gcc46/libobjc-gnu.* files.

So what I think is happening is that using Apple's objective-c compiler is always legal in this case because it always links to Apple's objective-c runtime, and not the GNU objective-c runtime by mistake. I do know, from hacking with gcc and clang on mac and linux, that the compiler is tightly coupled to the runtime; gcc-objc assumes the gnu-objc runtime, apple's compilers assume apple's runtime.

It appears that, since grDevices.so automagically links the apple runtime, the apple objective-c gets used to resolve all objective-c link references.

(And it appears that this graphics device is the only part of the R code base that uses any objective-c!)

So... my conclusion is that this appears safe for gcc46 and the current R-framework port since the correct libraries and compilers and runtimes always seem to link up together.

Plus... I've been using R, Rcpp, Rmpi, and rgl a lot in the past couple of weeks, along with many of my own compiled objects (fortran with openmpi), and have never had a crash yet... :-)

Changed 9 years ago by kjell.konis@…

Attachment: Portfile.2.diff added

comment:3 Changed 9 years ago by kjell.konis@…

I made one small change to your patch: I use /usr/bin/clang rather than the llvm-gcc42 port so that that port doesn't need to get installed when the +gcc46 variant is selected. Also, I did a little reformatting. Please can you test this out and let me know if you have any problems (or, better, that you don't have any problems). Thanks.

Note to committer: since the only thing that changed is the addition of a non-default variant, I didn't bother to bump the revision number.

comment:4 Changed 9 years ago by adfernandes (Andrew Fernandes)

Note to maintainer - I've been swamped the past few days - will get to testing this shortly - thanks for your patience!

comment:5 Changed 9 years ago by adfernandes (Andrew Fernandes)

Resolution: fixed
Status: newclosed

Tested with all my c++ and fortran extensions, and with aqua graphics (including rgl and rmpi) and works fine.

Committed in r90090.

Note: See TracTickets for help on using tickets.