Skip to content

error: unrecognized option ‘-arch’ -- suggestion!

8 messages · Peder Axensten, Simon Urbanek, Brian Ripley +1 more

#
The compiler (clang) and linker that Apple includes (with Xcode) uses the argument -arch to specify the architecture to build for. This is not recognized by, for instance, the gcc compilers. Because this argument is 'hardcoded' into the Makeconfig files, it is an involved process to compile libraries for R with any other compiler.

Either all all `-arch i386` and `-arch x86_64` must be removed from these files (this must be done every time R is updated) or you create a file `~/.R/Makevars` with something like
~~~~~~~
MYARCH = -arch x86_64

# Comment the next line to return to the original setting:
MYARCH = 

CC = gcc $(MYARCH) -std=gnu99
CXX=g++ $(MYARCH)
CXXCPP = g++ $(MYARCH) -E
FC = gfortran $(MYARCH)
F77 = gfortran $(MYARCH)
OBJC = gcc $(MYARCH)
OBJCXX = g++ $(MYARCH)

DYLIB_LD = gcc $(MYARCH) -std=gnu99
MAIN_LD = gcc $(MYARCH) -std=gnu99
SHLIB_CXXLD = g++ $(MYARCH)
SHLIB_FCLD = gfortran $(MYARCH)
SHLIB_LD = gcc $(MYARCH) -std=gnu99
~~~~~~~
Unfortunately, a few instances of `-arch` are outside the variables and can not be reached this way.



My suggestion is that the Makeconfig files are slightly changed:

- Change all `-arch i386` or `-arch x86_64` in these files to `$(MYARCH)`.
- Add a line `MYARCH = -arch x86_64` or `MYARCH = -arch i386`, respectively, to the top of these files.

No functionality is changed but using another compiler is more compatible and simpler as only MYARCH would need to be predefined.



Even better would be to be able to specify the compiler set to be used by using a variable (and handle the architecture accordingly), but I know to little about make files to come up with a constructive suggestion. Probably something like using
PREFIX = 
GCC = $(PREFIX)gcc $(MYARCH)
GPP = $(PREFIX)g++ $(MYARCH)
GFORTRAN = $(PREFIX)gfortran $(MYARCH)
and then using them when defining CC, XXX, etc.

No functionality would be changed, but a different set of compilers could be used just by changing PREFIX and MYARCH.

Best regards,

Peder Axensten
Research engineer

Swedish University of Agricultural Sciences
Dept. of Forest Resource Management
Remote Sensing
se-90183 Ume?
Sweden
Visiting address: Skogsmarksgr?nd
#
On Sep 27, 2012, at 5:02 AM, Peder Axensten wrote:

            
It is not - those (assuming you mean Makeconf) are generated from the flags used to build R, so if you use any other compiler with other flags they will be reflected in the Makeconf accordingly.
R doen't care what you compile libraries with as long as R can links against them at configure time. Again, this has nothing to do with Makevars.

Cheers,
Simon
#
On 27 sep 2012, at 14:27, Simon Urbanek <simon.urbanek at r-project.org> wrote:

            
I know little about how this is set up, is it not possible to change some kind of template to change the way this is done? Some base variables that are generated from the flags, these variables are then used in the rest of the Makeconf along the lines I suggested?
As I understand it, if I use R CMD INSTALL I'm stuck with what is defined in the Makeconf files. If I use any other compiler other than Apple's clang as my "default" compiler, I get errors when I run R CMD INSTALL ?? that is, if I from R try to install any package that requires compilation. I think it would be better to determine the value of the variables when R CMD INSTALL is run, rather than when R is installed (or even compiled?).

I'm sure it could be implemented better, but something like:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
GCCPATH = 

# If we are using the Apple compiler [that supports the -arch option], this is the argument to that option.
ARCH = x86_64

# Get information on the gcc to be used.
ISAPPLESTRING := $(shell "$(GCCPATH)gcc --version")
ISAPPLEKEY := Apple

# This will either be nothing or '-arch $(ARCH)'
MYARCH := $(if $(findstring $(ISAPPLEKEY),$(ISAPPLESTRING)),"-arch $(ARCH)")

MYGCC = $(GCCPATH)gcc $(MYARCH)
MYGPP = $(GCCPATH)g++ $(MYARCH)
MYFORTRAN = $(GCCPATH)gfortran $(MYARCH)

## etc.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


All the best,
/Peder
#
On Thu, Sep 27, 2012 at 10:07 AM, Peder Axensten <Peder.Axensten at slu.se> wrote:
Peder,

You seem a bit confused.  Let me explain it a bit clearer.  When you
compile R, the settings (and compiler) with which you compiled R is
stored in Makeconf and used to compile new packages using R CMD
INSTALL.  This ensures that you use the same compiler settings to
build R and add-on packages, which is obviously an _extremely good_
idea.  If you want to use another compiler with R, you will need to
re-compile R using this compiler, which should work.

My guess is that you are using the CRAN binary of R (compiled using
the official compiler) and you want to use another compiler to build
an add-on package.  This is not supported, and it should not be
supported, because it is an extremely bad idea.

Below is my configure call for building R from svn, using Simon's
build of Apple's GCC codebase (aka the official compiler).  It should
be easy to modify this to build R using a different compiler.  I am
just including this as an example.  Once you have build R using you
new compiler, R CMD INSTALL should work out of the box.

Note that if you want aqua support, you need a compiler that supports
objective-C (as far as I understand).  I don't use a GUI, but I use an
aqua device, like
R>  quartz()

(I may use imprecise terminology here, wrt. aqua and quartz).

Kasper

configure:

export LANG=en_US.UTF-8
../${SRCDIR}/configure SHELL='/bin/bash' \
  --prefix=/usr/local/R/R-${R_VERSION} --disable-R-framework\
  CC="/usr/bin/gcc-4.2 -arch x86_64 -std=gnu99" \
  CFLAGS="-g -O2 -std=gnu99 -march=nocona" \
  CXX="/usr/bin/g++-4.2 -arch x86_64" \
  CXXFLAGS="-g -O2 -march=nocona" \
  OBJC="/usr/bin/gcc-4.2 -arch x86_64" \
  F77="/usr/bin/gfortran-4.2 -arch x86_64" \
  FFLAGS="-g -O2 -march=nocona" \
  FC="/usr/bin/gfortran-4.2 -arch x86_64" \
  FCFLAGS="-g -O2 -march=nocona" \
  --enable-memory-profiling\
  --x-includes=/usr/X11/include --x-libraries=/usr/X11/lib\
  --with-system-zlib\
  --with-blas='-framework vecLib' --with-lapack
#
So I had a few emails with Peder, and I think he gets it now.

However, one point came up which I have been wondering about as well.
In Makeconf R only stores the name of the compiler, say "gcc" or
perhaps "gcc-4.2".  Why not store the full path?  Peder's situation is
that he has installed another compiler that resolves to gcc in his
environment, masking the one in /usr/bin.  It seems to me that it
would be more "safe" to save the entire path to the compiler, both on
multi-user systems on in case like (for os x) the binary is downloaded
from somewhere else.  [ on the other hand, it may be easier on Windows
to not have the full path ]

Now, there is probably a perfectly good reason to do what is happening
now.  Or perhaps changing it is not worth the effort.  But I just
wanted to raise the issue for 2 seconds.

Kasper

On Thu, Sep 27, 2012 at 10:29 AM, Kasper Daniel Hansen
<kasperdanielhansen at gmail.com> wrote:
#
On 28/09/2012 15:29, Kasper Daniel Hansen wrote:
You get what you specified when you configured R.  I usually configure 
with full paths except on Windows (where paths like /usr/local do not 
exist in general).

The point is that you can do what suits you.  If you choose to use a 
binary distribution you get what suits the distributor: if you don't 
like that, build from the sources yourself.

The documentation for the CRAN Mac binary distribution is a bit 
scattered.  I am not sure it would help, but we could add some more 
words to the R-admin manual.  I suspect few people want to work with 
source packages with compiled code and use the CRAN distribution (not 
least as it is hard to make portable binary packages that way).

  
    
#
On Fri, Sep 28, 2012 at 10:58 AM, Prof Brian Ripley
<ripley at stats.ox.ac.uk> wrote:
Thanks.  I see how this works now, and I should have investigated a bit more.

Kasper
#
On Sep 28, 2012, at 10:29 AM, Kasper Daniel Hansen wrote:

            
Using the full path is not really a solution, because /usr/bin/gcc is just a symlink to whatever the user chooses. In fact, it would complicate things since Xcode now uses dynamic paths, so a setup that is perfectly fine today would break if you do that. It doesn't seem sensible to me to do that just to accommodate esoteric setups that are not even supported. If you mess with PATH and other system variables, you better know what you're doing - you get what you deserve. That's why we warn specifically about 3rd party compiler binaries as they are well known to break. But, as Brian pointed out, all this seems to come from a failure to adhere to the most basic requirement: if you use our binaries, you have to use the tools we tell you to use. You're free to not use our binaries and do what you want, but then you're on your own and can't claim that it's something we are responsible for.

Cheers,
Simon