Appendix C — Platform notes

This section provides some notes on building R on different Unix-alike platforms. These notes are based on tests run on one or two systems in each case with particular sets of compilers and support libraries. Success in building R depends on the proper installation and functioning of support software; your results may differ if you have other versions of compilers and support libraries.

Older versions of this manual contain notes on platforms such as HP-UX, IRIX, Alpha/OSF1 (for R < 2.10.0, and support has since been removed for all of these) and AIX (for R < = 3.5.x) for which we have had no recent reports.

C macros to select particular platforms can be tricky to track down (there is a fair amount of misinformation on the Web). The Wiki (currently) at https://sourceforge.net/p/predef/wiki/Home/ can be helpful. The R sources have used (often in included software under src/extra)

AIX: _AIX
Cygwin: __CYGWIN__
FreeBSD: __FreeBSD__
HP-UX: __hpux__, __hpux
IRIX: sgi, __sgi
Linux: __linux__
macOS: __APPLE__
NetBSD: __NetBSD__
OpenBSD: __OpenBSD__
Windows: _WIN32, _WIN64
Windows on 64-but ARM: _M_ARM64 or _WIN32 plus __aarch64__

Identifying compilers can be very tricky. GCC defines __GNUC__, but so do other compilers claiming conformance with it, notably (LLVM and Apple) clang and Intel compilers. Further, some use the value of __GNUC__ for their version, not the version of GCC they claim to be compatible with.1 clang-based compilers define __clang__. Both LLVM and Apple clang define __clang_major__ as a string giving their major version, but for example Apple’s 13.x.y is very different from LLVM’s 13.x.y. And compilers based on LLVM clang, for example from Intel and IBM, will define these. Some of the included software uses __APPLE_CC__ to identify an Apple compiler (which used to include Apple builds of GCC), but Apple clang is better identified by the __apple_build_version__ macro.

1 Most clang-based compilers give 4, but not those distributed by FreeBSD. Intel’s icx reported 12 in 2023.

C.1 X11 issues

The X11() graphics device is the one started automatically on Unix-alikes (except most macOS builds) when plotting. As its name implies, it displays on a (local or remote) X server, and relies on the services provided by the X server.

The ‘modern’ version of the X11() device is based on cairo graphics and (in most implementations) uses fontconfig to pick and render fonts. This is done on the server, and although there can be selection issues, they are more amenable than the issues with X11() discussed in the rest of this section.

When X11 was designed, most displays were around 75dpi, whereas today they are of the order of 100dpi or more. If you find that X11() is reporting2 missing font sizes, especially larger ones, it is likely that you are not using scalable fonts and have not installed the 100dpi versions of the X11 fonts. The names and details differ by system, but will likely have something like Fedora’s

2 for example, X11 font at size 14 could not be loaded.

xorg-x11-fonts-75dpi
xorg-x11-fonts-100dpi
xorg-x11-fonts-ISO8859-2-75dpi
xorg-x11-fonts-Type1
xorg-x11-fonts-cyrillic

and you need to ensure that the -100dpi versions are installed and on the X11 font path (check via xset -q). The X11() device does try to set a pointsize and not a pixel size: laptop users may find the default setting of 12 too large (although very frequently laptop screens are set to a fictitious dpi to appear like a scaled-down desktop screen).

More complicated problems can occur in non-Western-European locales, so if you are using one, the first thing to check is that things work in the C locale. The likely issues are a failure to find any fonts or glyphs being rendered incorrectly (often as a pair of ASCII characters). X11 works by being asked for a font specification and coming up with its idea of a close match. For text (as distinct from the symbols used by plotmath), the specification is the first element of the option "X11fonts" which defaults to

"-adobe-helvetica-%s-%s-*-*-%d-*-*-*-*-*-*-*"

If you are using a single-byte encoding, for example ISO 8859-2 in Eastern Europe or KOI8-R in Russian, use xlsfonts to find an appropriate family of fonts in your encoding (the last field in the listing). If you find none, it is likely that you need to install further font packages, such as xorg-x11-fonts-ISO8859-2-75dpi and xorg-x11-fonts-cyrillic shown in the listing above.

Multi-byte encodings (most commonly UTF-8) are even more complicated. There are few fonts in iso10646-1, the Unicode encoding, and they only contain a subset of the available glyphs (and are often fixed-width designed for use in terminals). In such locales fontsets are used, made up of fonts encoded in other encodings. If the locale you are using has an entry in the XLC_LOCALE directory (typically /usr/share/X11/locale), it is likely that all you need to do is to pick a suitable font specification that has fonts in the encodings specified there. If not, you may have to get hold of a suitable locale entry for X11. This may mean that, for example, Japanese text can be displayed when running in ja_JP.UTF-8 but not when running in en_GB.UTF-8 on the same machine (although on some systems many UTF-8 X11 locales are aliased to en_US.UTF-8 which covers several character sets, e.g. ISO 8859-1 (Western European), JISX0208 (Kanji), KSC5601 (Korean), GB2312 (Chinese Han) and JISX0201 (Kana)).

On some systems scalable fonts are available covering a wide range of glyphs. One source is TrueType/OpenType fonts, and these can provide high coverage. Another is Type 1 fonts: the URW set of Type 1 fonts provides standard typefaces such as Helvetica with a larger coverage of Unicode glyphs than the standard X11 bitmaps, including Cyrillic. These are generally not part of the default install, and the X server may need to be configured to use them. They might be under the X11 fonts directory or elsewhere, for example,

/usr/share/fonts/default/Type1
/usr/share/fonts/ja/TrueType

C.2 Linux

Linux is the main development platform for R, so compilation from the sources is normally straightforward with the most common compilers and libraries.3

3 For example, glibc: other C libraries such as musl (as used by Alpine Linux) have been used but are not routinely tested.

This section is about the GCC compilers: gcc/gfortran/g++.

Recall that some package management systems (such as RPM and deb) make a distinction between the user version of a package and the developer version. The latter usually has the same name but with the extension -devel or -dev: you need both versions installed. So please check the configure output to see if the expected features are detected: if for example readline is missing add the developer package. (On most systems you will also need ncurses and its developer package, although these should be dependencies of the readline package(s).) You should expect to see in the configure summary

  Interfaces supported:      X11, tcltk
  External libraries:        pcre2, readline, curl
  Additional capabilities:   PNG, JPEG, TIFF, NLS, cairo, ICU

When R has been installed from a binary distribution there are sometimes problems with missing components such as the Fortran compiler. Searching the R-help archives will normally reveal what is needed.

It seems that ix86 Linux accepts non-PIC code in shared libraries, but this is not necessarily so on other platforms, in particular on 64-bit CPUs such as x86_64. So care can be needed with BLAS libraries and when building R as a shared library to ensure that position-independent code is used in any static libraries (such as the Tcl/Tk libraries, libpng, libjpeg and zlib) which might be linked against. Fortunately these are normally built as shared libraries with the exception of the ATLAS BLAS libraries.

The default optimization settings chosen for CFLAGS etc are conservative. It is likely that using -mtune will result in significant performance improvements on recent CPUs: one possibility is to add -mtune=native for the best possible performance on the machine on which R is being installed. It is also possible to increase the optimization levels to -O3: however for many versions of the compilers this has caused problems in at least one CRAN package.

Do not use -O3 with gcc 11.0 or 11.1: it mis-compiles code resulting in plausible but incorrect results. (This was seen in package MASS but has been worked around there as from version 3.1-57.)

For comments on ix86 builds (including 32-bit builds on x86_64) see the version of this manual for R 4.3.x.

To build a 64-bit version of R on ppc64 (also known as powerpc64) with gcc 4.1.1, Ei-ji Nakama used

CC="gcc -m64"
CXX="gxx -m64"
FC="gfortran -m64"
CFLAGS="-mminimal-toc -fno-optimize-sibling-calls -g -O2"
FFLAGS="-mminimal-toc -fno-optimize-sibling-calls -g -O2"

the additional flags being needed to resolve problems linking against libnmath.a and when linking R as a shared library.

The setting of the macro SAFE_FFLAGS may need some help. It should not need additional flags on platforms other than 68000 (not likely to be encountered) and ix86. For the latter, if the Fortran compiler is GNU (gfortran or possibly g77) the flags

-msse2 -mfpmath=sse

are added: earlier versions of R added -ffloat-store and this might still be needed if a ix86 CPU is encountered without SSE2 support. Note that it is a replacement for FFLAGS, so should include all the flags in that macro (except perhaps the optimization level).

Additional compilation flags can be specified for added safety/security checks. For example Fedora adds

-Werror=format-security -Wp,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS
-Fexceptions -fstack-protector-strong -fasynchronous-unwind-tables
-fstack-clash-protection -fcf-protection

to all the C, C++ and Fortran compiler flags (even though _GLIBCXX_ASSERTIONS is only for C++ in current GCC and glibc and none of these are documented for gfortran). Use of _GLIBCXX_ASSERTIONS will link abort and printf into almost all C++ code, and R CMD check --as-cran will warn.

C.2.1 Clang

R has been built with Linux ix86 and x86_64 C and C++ compilers (https://clang.llvm.org) based on the Clang front-ends, invoked by CC=clang CXX=clang++, together with gfortran. These take very similar options to the corresponding GCC compilers.

This has to be used in conjunction with a Fortran compiler: the configure code will remove -lgcc from FLIBS, which is needed for some versions of gfortran.

The current out-of-the-box default for clang++ is to use the C++ runtime from the installed g++. Using the runtime from the libc++ project (Fedora RPM libcxx-devel) via -stdlib=libc++ has also been tested.

Recent versions have (optional when built) OpenMP support.4

4 This also needs the OpenMP runtime which has sometimes been distributed separately.

There are problems mixing clang 15.0.0 and later built as default on Linux to produce PIE code and gfortran 11 or later, which does not. One symptom is that configure does not detect FC_LEN_T, which can be overcome by setting

FPIEFLAGS=-fPIE

in config.site. (configure tries that value if it is unset.)

C.2.2 flang

The name flang has been used for two projects: this is about the sub-project of LLVM which builds a Fortran compiler and runtime libraries. The compiler is currently named flang-new but has been announced to be renamed to flang when more nearly complete (and at some earlier point in its development was known as f18).

The version in LLVM 16 was able to build R on x86_64 Linux with

FC=/path/to/flang-new

with the matching clang used as the C compiler, and the build passed make check-all. There is also support for aarch64 and ppc64le Linux, but these have not been tested with R.

C.2.3 Intel compilers

In late 2020 Intel revamped their C/C++ compilers (and later their Fortran compiler) to use an LLVM back-end (and for the C/C++ compilers, a modified version of clang as the front-end). Those compilers are only for x86_64: the earlier (now called ‘Classic’) C/C++ compilers were discontinued in late 2023 (and are covered in the version of this manual for R 4.3.x: the Fortran compiler ifort remains part of the Fortran distribution)..

The compilers are now all under Intel’s ‘oneAPI’ brand. The revamped ones are icx, icpx and ifx; they are identified by the C/C++ macro __INTEL_LLVM_COMPILER (and do not define __INTEL_COMPILER: they also define __clang__ and __clang_major__).

The C++ compiler uses the system’s lidstdc++ as its runtime library rather than LLVM’s libc++.

Standalone installers (which are free-of-charge) are available from https://www.intel.com/content/www/us/en/developer/articles/tool/oneapi-standalone-components.html: they are also part of the oneAPI Base and HPC (for Fortran) toolkits.

We tried the compilers in oneAPI 2024.0.2 and 2023.x.y using (the paths do differ by compiler version)

IP=/path/to/compilers/bin/
CC=$IP/icx
CXX=$IP/icpx
FC=$IP/ifx
CFLAGS="-O3 -fp-model precise -Wall -Wstrict-prototypes"
C17FLAGS="-O3 -fp-model precise -Wall -Wno-strict-prototypes"
FFLAGS="-O3 -fp-model precise -warn all,noexternals"
FCFLAGS="-free -O3 -fp-model precise -warn all,noexternals"
CXXFLAGS="-O3 -fp-model precise -Wall"
LDFLAGS="-L/path/to/compilers/compiler/lib -L/usr/local/lib64"

but the build segfaulted in the checks (in complex arithmetic in tests/lapack.R).

Intel document building R with MKL: for the Intel compilers this needed something like

MKL_LIB_PATH=/path/to/intel_mkl/mkl/lib/intel64
export LD_LIBRARY_PATH="$MKL_LIB_PATH"
MKL="-L${MKL_LIB_PATH} -lmkl_intel_lp64 -lmkl_core -lmkl_sequential"
./configure --with-blas="$MKL" --with-lapack

and the build passed its checks with MKL 2023.2.0 (but not 2024.0 on the hardware tested). It may also be possible to use a compiler option like -qmkl=sequential.

One quirk is that the Intel Fortran compilers do not accept .f95 files, only .f90, for free-format Fortran. configure adds -Tf which tells the compiler this is indeed a Fortran file (and needs to immediately precede the file name), but -free is needed to say it is free-format. Hence setting the FCFLAGS macro.

The compilers have many options: as the C/C++ and Fortran compilers have different origins for their front-ends, there is little consistency in their options. (The C/C++ compilers support ‘all’ clang options even if undocumented for icx/icpc, such as -Wno-strict-prototypes above, However it is unclear for which version of clang: the Intel manual suggests checking icx -help.) The C/C++ compilers support clang-style LTO: it is not clear if the Fortran one does.

For some versions, including 2023.2.0, all CPU times in e.g. proc.time() are reported as zero. If you see this, uncomment the INTEL_ICX_FIX setting in config.site and re-build.

The preferred Fortran standard for ifx can be set by one of -std90, -std95, -std03, -std08 or -std18 (and variants). However, this is documented to only affect warnings on non-standard features: the default is no such warnings.

Warning to package maintainers: the Intel Fortran compiler interprets comments intended for Visual Fortran5 like

5 as the ‘Classic’ compiler has been known on Windows.

!DEC$ ATTRIBUTES DLLEXPORT,C,REFERENCE,ALIAS:'kdenestmlcvb' :: kdenestmlcvb

The DLLEXPORT gives a warning but the remainder silently generates incorrectly named entry points. Such comment lines need to be removed from code for use with R (even if using Intel Fortran on Windows).

C.3 macOS

The instructions here are for Intel 64-bit (x86_64) or ‘Apple Silicon’ (arm64) builds on macOS 11 (Big Sur), 12 (Monterey), 13 (Ventura), 14 (Sonoma) and likely later. (They may well work on Intel macOS 10.14 or 10.15, but are untested there.)

C.3.1 Prerequisites

The Intel components install into /opt/R/x86_64, the Apple silicon ones into /opt/R/arm64. This may not exist6 so it is simplest to first create the directory and adjust its ownership if desired: for example by

6 it will if R has been installed from CRAN since R 4.3.0.

sudo mkdir -p /opt/R/arm64
sudo chown -R $USER /opt/R

Also, add /opt/R/x86_64/bin or /opt/R/arm64/bin to your path.

Define an appropriate variable in your Terminal:

set LOCAL=/opt/R/x86_64 # Intel
set LOCAL=/opt/R/arm64  # Apple Silicon

to use the code snippets here.

The following are essential to build R:

  • Apple’s ‘Command Line Tools’: these can be (re-)installed by running xcode-select --install in a terminal.

    If you have a fresh OS installation, running e.g. make in a terminal will offer the installation of the command-line tools. If you have installed Xcode, this provides the command-line tools. The tools may need to be reinstalled when macOS is upgraded, as upgrading may partially or completely remove them.

    The Command Line Tools provide C and C++ compilers derived from LLVM’s clang but nowadays known as ‘Apple clang’ with different versioning (so Apple clang 14 is unrelated to LLVM clang 14).

  • A Fortran compiler. See Fortran compiler.

  • Binary components pcre27 and xz (for liblzma) from https://mac.r-project.org/bin/. There is an R script there to help with installing all the needed components. (At the time of writing install.libs("r-base-dev") installed neither readline5 nor those needed to support Pango.)

    Intel users want the darwin20 components: the darwin17 ones are for macOS 10.13–10.15.

    Or this can be done manually, by for example

    curl -OL https://mac.r-project.org/bin/darwin20/x86_64/pcre2-10.42-darwin.20-x86_64.tar.xz
    sudo tar -xvzf pcre2-10.42-darwin.20-x86_64.tar.gz -C /
    curl -OL https://mac.r-project.org/bin/darwin20/x86_64/xz-5.4.2-darwin.20-x86_64.tar.xz
    sudo tar -xvzf xz-5.4.2-darwin.20-x86_64.tar.xz -C /

    (sudo is not needed if your account owns /opt/R/x86_64 or /opt/R/arm64 as appropriate.)

    Messages like opt/R/: Can't restore time should be ignored.

7 If compiling it from source on arm64, pcre2 (at least up to version 10.39) needs to be built without JIT support (the default) as the R build segfaults if that is enabled, so do run make check on your build.

and desirable

  • Component readline5.8 If readline is not present, the emulation in Apple’s version of libedit (aka editline) will be used: if you wish to avoid that, configure with --without-readline.

  • Components jpeg, libpng, pkgconfig, tiff and zlib-system-stub from https://mac.r-project.org/bin// for the full range of bitmapped graphics devices. (Some builds of tiff may require libwebp and/or openjpeg.)

  • An X sub-system unless configuring using --without-x: see https://www.xquartz.org/. R’s configure script can be told to look for X11 in XQuartz’s main location of /opt/X11, e.g. by

    --x-includes=/opt/X11/include --x-libraries=/opt/X11/lib

    Be wary of pre-release versions of XQuartz, which may be offered as an update.

  • An Objective-C compiler, as provided by clang in the Command Line Tools: this is needed for the quartz() graphics device.

    Use --without-aqua if you want a standard Unix-alike build: apart from disabling quartz() and the ability to use the build with R.APP, it also changes the default location of the personal library (see ?.libPaths).

  • A Tcl/Tk installation, See Tcl/Tk headers and libraries.

  • Support for Cairo-based graphics devices. See Cairo graphics.

  • A TeX installation. See Other libraries.

  • texi2any from a texinfo distribution, which requires perl (currently a default part of macOS but it has been announced that it may not be in future). A version of texi2any has been included in the binary distribution of R and there is a texinfo component at https://mac.r-project.org/bin/.

8 For licence reasons this is version 5.2 of readline: for those who want a more recent version it is straightforward to compile it from its sources.

To build R itself from the sources with the C/C++ compilers in the Command Line Tools (or Xcode) and gfortran from the installer mentioned below, use a file config.site containing

CC=clang
OBJC=$CC
FC="/opt/gfortran/bin/gfortran -mtune=native"
CPPFLAGS='-isystem $LOCAL/include'
CXX=clang++

and configure by something like

./configure -C \
--enable-R-shlib --enable-memory-profiling \
--x-includes=/opt/X11/include --x-libraries=/opt/X11/lib \
--with-tcl-config=$LOCAL/lib/tclConfig.sh \
--with-tk-config=$LOCAL/lib/tkConfig.sh \
PKG_CONFIG_PATH=$LOCAL/lib/pkgconfig:/usr/lib/pkgconfig

(See below for other options for Tcl/Tk.) For an arm64 build further flags are desirable in config.site:

CFLAGS="-falign-functions=8 -g -O2"
FFLAGS="-g -O2 -mmacos-version-min=11.0"
FCFLAGS="-g -O2 -mmacos-version-min=11.0"

(the first flag in CFLAGS is needed to inter-work with the gfortran without segfaulting in some packages, and some builds of gfortran have targetted the current version of macOS (unlike clang, causing linker warnings).

To install packages using compiled code one needs the Command Line Tools (or Xcode) and appropriate compilers, e.g. the C/C++ compilers from those tools and/or gfortran. Some packages have further requirements such as component pkgconfig (and to set PKG_CONFIG_PATH= as above).

A subversion client can be obtained from https://mac.r-project.org/tools/, for example by

curl -OL https://mac.r-project.org/tools/subversion-1.14.0-darwin15.6.tar.gz
tar xf subversion-1.14.0-darwin15.6.tar.gz
sudo cp subversion-1.14.0-darwin15.6/svn $LOCAL/bin

(There also an arm64 version on that web page.)

If building software or installing source packages with cmake (or a non-Apple make) for ‘Apple Silicon’ ensure it contains the arm64 architecture (use file to be sure). Running Apple compilers from an x86_64 executable will generate x86_64 code ….

Updating an arm64 build may fail because of the bug described at https://openradar.appspot.com/FB8914243 but ab initio builds work. This has been far rarer since macOS 13.

If you are using the macOS 13 SDK9, you may need to add something like -mmacos-version-min=12.0 to CFLAGS.

9 ls -l xcrun -show-sdk-path in a terminal will show you which SDK is selected.

Linker warnings like

ld: warning: could not create compact unwind for _sort_:
   register 26 saved somewhere other than in frame
ld: warning: ld: warning:
   could not create compact unwind for _arcoef_: registers 23 and 24 not saved contiguously in frame
ld: warning: could not create compact unwind for ___emutls_get_address:
   registers 23 and 24 not saved contiguously in frame

can be ignored. These stem from compiled Fortran code, including its run-time libraries.

The default security settings can make it difficult to install Apple packages which have not been ‘notarized’10 by Apple. And not just packages, as this has been seen for executables contained in tarballs/zipfiles (for example, for pandoc). Usually one can use Open With (Control/right/two-finger-click in Finder), then select Installer and Open if you get a further warning message.

If you run into problems with ‘quarantine’ for tarballs downloaded in a browser, consider using curl -OL to download (as illustrated above) or xattr -c to remove extended attributes.

configure defaults to --with-internal-tzcode on macOS. The native implementation used to be unusable on earlier versions (with a 32-bit time_t and/or timezone tables missing information beyond the 32-bit range). For, e.g., macOS 12.6, option --without-internal-tzcode can be used to override this and R contains sufficient workarounds (for example, the native code fails to recognize dates with a negative tm_year, that is dates before 1900) for R to pass its checks. However, there are discrepancies, notably in Europe in the 1900s and 1940s, even though the Olson database contains the correct information.

C.3.2 Fortran compiler

There is ‘universal’ (Intel and arm64) build of gfortran 12.2 at https://mac.r-project.org/tools/gfortran-12.2-universal.pkg. This installs into /opt/gfortran.

The /opt/gfortran/SDK symlink should point to the desired path to the SDK (defaults to the command line tools SDK). This can be updated by running /opt/gfortran/bin/gfortran-update-sdk or manually. If the symlink is broken, the driver will issue a warning and use xcrun -show-sdk-path to try to find an SDK and use its path. (The SDK path is used when using gfortran to link, so not when building R but when installing a few packages.)

A build of gfortran 13.2 for arm64 macOS 14 is available at https://github.com/fxcoudert/gfortran-for-macOS/releases. This can be built for Intel and older OSes from the sources at https://github.com/iains/gcc-13-branch/.

C.3.3 Cairo graphics

Cairo-based graphics devices such as cairo_ps, cairo_pdf, X11(type = "cairo") and the Cairo-based types of devices bmp jpeg, png and tiff are not the default on macOS, and much less used than the Quartz-based devices. However, the only SVG device in the R distribution, svg, is based on Cairo.

Support for Cairo is optional and can be added in several ways, all of which need pkg-config. configure will add Cairo support if pkg-config finds package cairo unless --without-cairo is used.

A way to statically link Cairo is by downloading and unpacking components cairo, fontconfig, freetype, pixman and zlib-system-stub (and do not have /opt/X11/lib/pkgconfig in PKG_CONFIG_PATH). Some static builds of fontconfig need libxml2 (from component xml2) and others expat, supplied by macOS but needing a file $LOCAL/lib/pkgconfig/expat.pc along the lines of

Name: expat
Version: 2.2.8
Description: expat XML parser
URL: http://www.libexpat.org
Libs: -lexpat
Cflags: 

Note that the list of components is liable to change: running pkg-config cairo --exists --print-errors should tell you if any others are required.

The best font experience of Cairo graphics will be to use it in combination with Pango which will match that supported on most other Unix-alikes. configure uses pkg-config to determine if all the external software required by both Pango and Cairo is available: running pkg-config pangocairo --exists --print-errors should show if the installation suffices and if not, what is missing. At the time of writing using pre-built components cairo, fontconfig, freetype, ffi, fribidi, gettext, icu, glib, harfbuzz, pango, pcre, pixman and xml2 sufficed.

C.3.4 Other C/C++ compilers

Other distributions of clang may be available from https://github.com/llvm/llvm-project/releases/ (recently only for arm64 and usually unsigned/not notarized which makes them hard to use). In particular, these include support for OpenMP which Apple clang does not. Some of these have included support for the ASan and UBSan sanitizers.

Suppose one of these distributions is installed under $LOCAL/llvm. Use a file config.site containing

CC="$LOCAL/llvm/bin/clang -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk"
CXX="$LOCAL/llvm/bin/clang++ -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk"
OBJC=$CC
FC=/opt/gfortran/bin/gfortran
LDFLAGS="-L$LOCAL/llvm/lib -L$LOCAL/lib"
R_LD_LIBRARY_PATH=$LOCAL/llvm/lib:$LOCAL/lib

Should the location of the SDK change (or where Xcode provides the SDK rather than the Command Line Tools), it can be found by running xcrun -show-sdk-path.

The care to specify library paths is to ensure that the OpenMP runtime library, here $LOCAL/llvm/lib/libomp.dylib, is found when needed. If this works, you should see the line

checking whether OpenMP SIMD reduction is supported... yes

in the configure output. Also, R_LD_LIBRARY_PATH needs to be set to find the latest version of the C++ run-time libraries rather than the system ones.

It is usually possible to build R with GCC (built from the sources, from a gfortran distribution, from Homebrew, …). When last tested11 it was not possible to use gcc to build the quartz() device, so configure --without-aqua may be required.

11 with gcc 10.2.

It is usually possible to add some OpenMP support to the Apple clang compilers: see https://mac.r-project.org/openmp/. Note that that approach is somewhat fragile as it needs a libomp.dylib library matching the version of the compiler used—and for example at the time of writing none was offered for the current compilers in Xcode CLT 14.3 nor 15.

C.3.5 Other libraries

Pre-compiled versions of many of the Useful libraries and programs are available from https://mac.r-project.org/bin//.

Looking at the top of /Library/Frameworks/R.framework/Resources/etc/Makeconf will show the compilers and configuration options used for the CRAN binary package for R: at the time of writing the non-default options

--enable-memory-profiling --enable-R-framework
--x-libraries=/opt/X11/lib --x-includes=/opt/X11/include

were used. (--enable-R-framework implies --enable-R-shlib.)

The main TeX implementation used by the developers is MacTeX12 (https://www.tug.org/mactex/): the full installation is about 8.5GB, but a much smaller version (‘Basic TeX’) is available at https://www.tug.org/mactex/morepackages.html to which you will need to add some packages to build R, e.g. for the 2022 version we needed to add13 helvetic, inconsolata and texinfo which brought this to about 310MB.14 TeX Live Utility (available via the MacTeX front page) provides a graphical means to manage TeX packages. These contain executables which run natively on both x86_64 and arm64.

12 An essentially equivalent TeX installation can be obtained by the Unix TeX Live installation scripts.

13 E.g. via tlmgr install helvetic inconsolata texinfo .

14 Adding all the packages needed to check CRAN increased this to about 600MB.

Checking packages thoroughly requires Ghostscript (part of the full MacTeX distribution or separately from https://www.tug.org/mactex/morepackages.html) and qpdf (from https://mac.r-project.org/bin//, a version of which is in the bin directory of a binary installation of R, usually /Library/Frameworks/R.framework/Resources/bin/qpdf).

R CMD check --as-cran makes use of ‘HTML Tidy’. macOS has a version in /usr/bin/tidy dating from 2006 which is far too old and is skipped. Up-to-date versions can be installed from http://binaries.html-tidy.org/.

One macOS quirk is that the default path has /usr/local/bin after /usr/bin, contrary to common practice on Unix-alikes. This means that if you install tools from the sources they will by default be installed under /usr/local and not supersede the system versions.

Parallel installation of packages will make use of the utility timeout if available. A dual-architecture build can be downloaded from https://www.stats.ox.ac.uk/pub/bdr/timeout: make it executable (chmod 755 timeout) and put it somewhere on your path.

C.3.6 Accelerate

The Accelerate library15 can be used via the configuration option

--with-blas="-framework Accelerate"

to provide potentially higher-performance versions of the BLAS and LAPACK routines.16 This includes a full LAPACK which can be used via --with-lapack: however, the version of LAPACK it contains has often been seriously old (and is not used unless --with-lapack is specified). Some CRAN builds of R can be switched17 to use Accelerate’s BLAS.

16 It has been reported that for some non-Apple toolchains CPPFLAGS needed to contain -D__ACCELERATE__: not needed for clang from LLVM.

18 Released 2021-04-01.

As from macOS 13.3, the BLAS and LAPACK libraries under the Accelerate framework are ‘now inline with reference version 3.9.1’.18 However, this has been done by naming new entry points and so only accessible via their C headers. That version can be used for BLAS calls via configure option --with-newAccelerate: it requires at least macOS 13.3 and SDK 13.3 (from Xcode CLT 14.3). To use it for both BLAS and LAPACK calls, configure with --with-newAccelerate=lapack. These options cannot be used with others such as --with-blas and --with-lapack.

Threading in Accelerate is controlled by ‘Grand Central Dispatch’19 and is said not to need user control. Test nls.R in package stats has often failed with the Accelerate BLAS on Intel macOS. All versions of Accelerate show differences from the reference BLAS (and most others) in the use of NA vs NaN and a substantial number of R packages fail their checks.

C.3.7 OpenBLAS

R has been built on arm64 using OpenBLAS 0.3.24 (sources from https://github.com/OpenMathLib/OpenBLAS/releases) by symlinking /opt/OpenBLAS/lib/libopenblas.dylib to lib/libRblas.dylib (see Shared BLAS).

On macOS, a default build of OpenBLAS uses pthreads (as macOS does not have OpenMP) with the number of threads controlled by environment variable OPENBLAS_NUM_THREADS. On an M1 Pro this defaulted to 10 threads (there are 8 ‘performance’ cores and 2 ‘efficiency cores’) and we saw a 9x speedup over the reference BLAS on a large SVD (which was slightly faster than Accelerate).

C.3.8 Tcl/Tk headers and libraries

If you plan to use the tcltk package for R, you will need to install a distribution of Tcl/Tk. There are two alternatives. If you use R.APP you will want to use X11-based Tcl/Tk (as used on other Unix-alikes), which is installed under $LOCAL/lib as part of the CRAN binary for R.20 This may need configure options

20 Just that component can be selected from the installer for R: at the ‘Installation Type’ screen select ‘Customise’ and then just the ‘Tcl/Tk 8.6.11’ component.

--with-tcltk=$LOCAL/lib

or

--with-tcl-config=$LOCAL/lib/tclConfig.sh
--with-tk-config=$LOCAL/lib/tkConfig.sh

Note that this requires a matching XQuartz installation.

There is also a native (‘Aqua’) version of Tcl/Tk which produces widgets in the native macOS style: this will not work with R.APP because of conflicts over the macOS menu, but for those only using command-line R this provides a much more intuitive interface to Tk for experienced Mac users. Earlier versions of macOS came with an Aqua Tcl/Tk distribution but these were often not at all recent versions of Tcl/Tk. It is better to install Tcl/Tk 8.6.x from the sources21 or a binary distribution from https://www.activestate.com/products/tcl/. For the latter, configure R with

21 Configure Tk with --enable-aqua.

--with-tcl-config=/Library/Frameworks/Tcl.framework/tclConfig.sh 
--with-tk-config=/Library/Frameworks/Tk.framework/tkConfig.sh

If you need to find out which distribution of Tk is in use at run time, use

library(tcltk)
tclvalue(.Tcl("tk windowingsystem"))  # "x11" or "aqua"

Note that some Tcl/Tk extensions only support the X11 interface: this includes Tktable and the CRAN package tkrplot.

C.3.9 Java

macOS does not comes with an installed Java runtime (JRE) and a macOS upgrade may remove one if already installed: it is intended to be installed at first use. Check if a JRE is installed by running java -version in a Terminal window: if Java is not installed22 this should prompt you to install it.23 Builds of OpenJDK may also be available, e.g. from Adoptium, Azul or https://jdk.java.net/. We recommend you install a version with long-term support, e.g. 11, 17 or 21 but not 12–16, 18–20, 22 which have/had a 6-month lifetime. (Note that these sources may use unusual designations for Intel macOS builds such as x86 64-bit and x64.)

22 In the unlikely event that the version reported does not start with 1.8.0, 11 or higher you need to update your Java.

23 Not at the time of writing for arm64.

Binary distributions of R are built against a specific version (e.g. 11.0.18 or 17.0.1) of Java so sudo R CMD javareconf will likely be needed to be run before using Java-using packages.

To see what compatible versions of Java are currently installed, run the appropriate one of

/usr/libexec/java_home -V -a x86_64
/usr/libexec/java_home -V -a arm64

If needed, set the environment variable JAVA_HOME to choose between these, both when R is built from the sources and when R CMD javareconf is run.

Configuring and building R both looks for a JRE and for support for compiling JNI programs (used to install packages rJava and JavaGD); the latter requires a JDK (Java SDK). Most distributions of Java 9 or later are of a full JDK.

The build process tries to fathom out what JRE/JDK to use, but it may need some help, e.g. by setting environment variable JAVA_HOME. To select a build from Adoptium set e.g.

JAVA_HOME=/Library/Java/JavaVirtualMachines/termurin-17.jdk/Contents/Home

in config.site. For Java 21 from https://jdk.java.net/ (which might no longer be available), use

JAVA_HOME=/path/to/jdk-21.jdk/Contents/Home

For an arm64 build, the earliest Java version which is officially supported is 17. The currently simplest way to install Java is from Adoptium (who call the architecture aarch64): this installs into an Apple-standard location and so works with /usr/bin/java. Other builds are available from https://www.azul.com/downloads/zulu-community/?os=macos&architecture=arm-64-bit&package=jdk and from OpenJDK at https://jdk.java.net/, for which JAVA_HOME may need to be set both when configuring R and at runtime.

To use Java (specifically, binary package rJava) with a CRAN (x86_64) binary distribution of R on arm64 macOS, install an Intel build of a Java JRE from one of the sites linked above, then run sudo R CMD javareconf.

Note that it is necessary to set the environment variable NOAWT to 1 to install many of the Java-using packages.

C.3.10 Frameworks

The CRAN build of R is installed as a framework, which is selected by the option

./configure --enable-R-framework

(This is intended to be used with an Apple toolchain: others may not support frameworks correctly but those from LLVM do.)

It is only needed if you want to build R for use with the R.APP console, and implies --enable-R-shlib to build R as a dynamic library. This option configures R to be built and installed as a framework called R.framework. The default installation path for R.framework is /Library/Frameworks but this can be changed at configure time by specifying the flag --enable-R-framework[=DIR] (or --prefix) or at install time via

make prefix=/where/you/want/R.framework/to/go install

Note that installation as a framework is non-standard (especially to a non-standard location) and Unix utilities may not support it (e.g. the pkg-config file libR.pc will be put somewhere unknown to pkg-config).

C.3.11 Building R.app

Building the R.APP GUI console is a separate project, using Xcode. Before compiling R.APP make sure the current version of R is installed in /Library/Frameworks/R.framework and is working at the command-line (this can be a binary install).

The current sources can be checked out by

svn co https://svn.r-project.org/R-packages/trunk/Mac-GUI

and built by loading the R.xcodeproj project (select the R target and a suitable configuration), or from the command-line by e.g.

xcodebuild -target R -configuration Release

See also the INSTALL file in the checkout or directly at https://svn.r-project.org/R-packages/trunk/Mac-GUI/INSTALL.

R.APP does not need to be installed in any specific way. Building R.APP results in the R.APP bundle which appears as one R icon. This application bundle can be run from anywhere and it is customary to place it in the /Applications folder.

C.3.12 Building binary packages

CRAN macOS binary packages are distributed as tarballs with suffix .tgz to distinguish them from source tarballs. One can tar an existing installed package, or use R CMD INSTALL --build.

However, there are some important details.

  • Current CRAN macOS distributions are targeted at Big Sur so it is wise to ensure that the compilers generate code that will run on Big Sur or later. With the recommended compilers we can use

    CC="clang -mmacosx-version-min=11.0"
    CXX="clang++ -mmacosx-version-min=11.0"
    FC="/opt//gfortran/bin/gfortran -mmacosx-version-min=11.0"

    or set the environment variable

    export MACOSX_DEPLOYMENT_TARGET=11.0
  • Using the flag -Werror=partial-availability can help trigger compilation errors on functionality not in Big Sur.

  • Check that any compiled code is not dynamically linked to libraries only on your machine, for example by using otool -L or objdump -macho -dylibs-used. This can include C++ and Fortran run-time libraries under /opt/R/x86_64/lib or /opt/R/arm64/lib: one can use install_name_tool to point these at system versions or those shipped with R, for example

    install_name_tool -change /usr/local/llvm/lib/libc++.1.dylib \
    /usr/lib/libc++.1.dylib \
    pkg.so
    
    install_name_tool -change
    /opt/gfortran/lib/gcc/aarch64-apple-darwin20.0/12.2.0/libgfortran.5.dylib \
    /Library/Frameworks/R.framework/Resources/lib/libgfortran.5.dylib \
    pkg.so
    
    install_name_tool -change
    /opt/gfortran/lib/gcc/aarch64-apple-darwin20.0/12.2.0/libquadmath.0.dylib \
    /Library/Frameworks/R.framework/Resources/lib/libquadmath.0.dylib \
    pkg.so

    (where the details depend on the compilers and CRAN macOS R release).

  • For C++ code there is the possibility that calls will be generated to entry points not in the system /usr/lib/libc++.1.dylib. The previous step allows this to be tested against the system library on the build OS, but not against earlier ones. It may be possible to circumvent that by static linking to libc++.a and libc++abi.a by something like

    SHLIB_CXXLD = /usr/local/llvm/bin/clang
    PKG_LIBS = /usr/local/llvm/lib/libc++.a /usr/local/llvm/lib/libc++abi.a

    in src/Makevars. It would also be possible to static link the Fortran runtime libraries libgfortran.a and libquadmath.a should the Fortran compiler have later versions (but gfortran 8–13 all have version 5).

The CRAN binary packages are built with the Apple compiler on the oldest supported version of macOS, which avoids the first two and any issues with C++ libraries.

C.3.13 Building for Intel on arm64

Should one want to build R for Intel on an arm64 Big Sur Mac, add the target for the C and C++ compilers:

CC="clang -arch x86_64
OBJC=$CC
CXX="clang++ -arch x86_64"
FC="/opt//gfortran/bin/gfortran -arch x86_64 -mtune=native -mmacosx-version-min=11"

and install the Fortran compiler and external software described above for Intel builds (and have /opt/R/x86_64/bin before /opt/R/arm64/bin in your path).

To set the correct architecture (which will be auto-detected as aarch64), use something like

/path/to/configure --build=x86_64-apple-darwin20

C.3.14 Installer

The scripts for the CRAN packaging of R can be found under https://svn.r-project.org/R-dev-web/trunk/QA/Simon/R4/: start with the README file in that directory.

C.4 FreeBSD

There have been few recent reports on FreeBSD: there is a ‘port’ at https://svnweb.freebsd.org/ports/head/math/R, currently last updated for R 4.0.4. Recent versions of FreeBSD use Clang and the libc++ C++ headers and runtime, but the ‘port’ has been configured to use GCC.

Use of ICU for collation and the configure option --with-internal-tzcode are desirable workarounds.

C.5 OpenBSD

Ingo Feinerer installed R version 3.2.2 on OpenBSD 5.8 arch amd64 (their name for x86_64). Details of the build (and patches applied) are at https://cvsweb.openbsd.org/cgi-bin/cvsweb/ports/math/R/, currently updated for R 4.2.3.

C.6 Cygwin

The 32-bit version never worked well enough to pass R’s make check, and residual support from earlier experiments was removed in R 3.3.0.

The 64-bit version was never supported.

C.7 New platforms

There are a number of sources of problems when installing R on a new hardware/OS platform. These include

Floating Point Arithmetic: R requires arithmetic compliant with IEC 60559, also known as IEEE 754. This mandates the use of plus and minus infinity and NaN (not a number) as well as specific details of rounding. Although almost all current FPUs can support this, selecting such support can be a pain. The problem is that there is no agreement on how to set the signalling behaviour; Sun/Sparc, SGI/IRIX and ix86 Linux require no special action, FreeBSD requires a call to (the macro) fpsetmask(0) and OSF1 required that computation be done with a -ieee_with_inexact flag etc. With Intel compilers on 32-bit and 64-bit Intel machines, one has to explicitly disable flush-to-zero and denormals-are-zero modes. Some ARM processors including A12Z and M1 (Apple Silicon) by default use runfast mode, which includes flush-to-zero and default-nan and hence has to be disabled. With default-nan mode, the NaN payload used for representation of numeric NA values is lost even on simple operations with finite values. On a new platform you must find out the magic recipe and add some code to make it work. This can often be done via the file config.site which resides in the top level directory.

Beware of using high levels of optimization, at least initially. On many compilers these reduce the degree of compliance to the IEEE model. For example, using -fast on the Oracle compilers has caused R’s NaN to be set incorrectly, and gccs -ffast-math and clangs -Ofast have given incorrect results.

Shared Objects: There seems to be very little agreement across platforms on what needs to be done to build shared objects. there are many different combinations of flags for the compilers and loaders. GNU libtool cannot be used (yet), as it currently does not fully support Fortran: one would need a shell wrapper for this). The technique we use is to first interrogate the X window system about what it does (using xmkmf), and then override this in situations where we know better (for tools from the GNU Compiler Collection and/or platforms we know about). This typically works, but you may have to manually override the results. Scanning the manual entries for cc and ld usually reveals the correct incantation. Once you know the recipe you can modify the file config.site (following the instructions therein) so that the build will use these options.

It seems that gcc 3.4.x and later on ix86 Linux defeat attempts by the LAPACK code to avoid computations entirely in extended-precision registers, so file src/modules/lapack/dlamc.f may need to be compiled without optimization or with additional flags. Set the configure variable SAFE_FFLAGS to the flags to be used for this file.

If you do manage to get R running on a new platform please let us know about it so we can modify the configuration procedures to include that platform.

If you are having trouble getting R to work on your platform please feel free to use the R-devel mailing list to ask questions. We have had a fair amount of practice at porting R to new platforms ...

One thing you might want to add for a new platform is the mapping of C/C++/Fortran calls to entry point names used for R CMD check. See https://svn.r-project.org/R-dev-web/trunk/sotools.txt for how to do so.

Footnotes