Introduction

These notes describe the building of the gcc 4.9.2 compiler we hope to use on Windows for the R release 3.2.x. It’s not stable enough yet and we’ve missed 3.2.0, but we hope to update these instructions and get it working on R-devel first, then backport it to the 3.2 branch.

If you have test cases that cause problems, please send a link to murdoch.duncan@gmail.com and if reproducible I’ll add them to the test cases section below so we can work on fixing them and making sure they stay fixed.

Installing cross-compiler

Installation was done using the scripts from Elance contractor Doug R. The full set of scripts are in scripts.tar.gz.

On Linux VM, installed scripts to ~/Mingw-w64.

Checked prerequisites:

cd ~/Mingw-w64/
./check_prerequisites.sh

all results listed as installed.

Set ~/Mingw-w64/defaults to

ROOT_DIR=$HOME/Rtools
BUILD_ARCHITECTURES=(x32)
USE_DWARF=no
USE_MULTILIB=no

PACKAGE_EXT=".tar.gz"
COMPRESS="tar --hard-dereference -zvcf"
DECOMPRESS="tar -xf"

export GNU_URL="ftp://ftp.nluug.nl/mirror/gnu"
GCC_LANGUAGES="c,c++,lto,fortran"

JOBS=1
CROSS_BUILD=`gcc -dumpmachine`

NATIVE_ARCHITECTURES=(x32 x64)

Built the cross compilers using

./build-linux-cross.sh --toolchain=toolchains/mingw-w64-gcc-4.9.2
./build-linux-cross.sh --toolchain=toolchains/mingw-w64-gcc-4.9.2 x64

then the native compilers using

./build-window-native.sh --toolchain=toolchains/mingw-w64-gcc-4.9.2.native

These take a few hours to run, and produce a number of tarballs in $HOME/RtoolsStatic/packages; copies are here:

Building multilib version

This just doesn’t work, as mentioned in the README. Doug R. has done some research into it, but neither of us has been able to get it all to work.

Building the SEH version

This was done at first, but hasn’t been tested with the latest version.
The expectation is that 64 bit SEH will not work with static libs, but this also hasn’t been tested.

Threading model

The threading model has been set using

--enable-threads=win32

in this build.

R-devel patches needed

Currently R-devel is set to use the older gcc 4.6.3 toolchain. To use the new toolchain, the following changes are needed:

Copy src/gnuwin32/MkRules.dist to src/gnuwin32/MkRules.local.
Edit the latter file as follows:

For example, to build 32 bit R-devel:

BINPREF = c:/Rtools/gcc492_32/bin/
WIN = 32
MULTI =

For 64 bit R-devel:

BINPREF = c:/Rtools/gcc492_64/bin/
WIN = 64
MULTI =

Edit the CXXFLAGS in src/gnuwin32/fixed/etc/Makeconf to add the -fno-asynchronous-unwind-tables option, i.e.

CXXFLAGS = -O2 -Wall -fno-asynchronous-unwind-tables $(DEBUGFLAG) @EOPTS@

Test cases

These are current and previous problems.

Rf_error problem

FIXED: Rf_error problem: This is a small package called RToolsTest, written by Kevin Ushey. It calls Rf_error() from C++, which caused a crash. Run it via

    devtools::install_github("kevinushey/RToolsTest")
    RToolsTest::ouch()

The -fno-asynchronous-unwind-tables option appeared to fix this.

V8 crash in 32 bits

Problem in V8: This works in the 64 bit build, but dies with a segfault in the 32 bit build:

    install.packages("V8", type = "source")
    library(V8)
    ct <- new_context()

The segfault happens when V8_make_context in RcppExports.cpp is called. At the time of the crash, the stack is corrupt, with entries

    v8::internal::JSObject::elements()
    v8::NeanderObject::get(int)
    v8::NeanderArray::length()
    v8::NeanderArray::add(v8::internal::Handle<v8::internal::Object>)
    v8::Template::Set(v8::Handle<v8::String>, v8::Handle<v8::Data>, v8::PropertyAttribute)
    make_context at V8.cpp:79
    V8_make_context(set+consoleSEXP) at RcppExports.cpp:17
    R_doDotCall()

followed by garbage.

Speculation: This may require recompiling external libs?

Small numeric differences?

The stats package examples don’t give the standard results in 64 bits:

Testing examples for package 'stats'
   comparing 'stats-Ex.Rout' to 'stats-Ex.Rout.save' ...
16222c16222
<  [8,] 0.050 .
---
 >  [8,] 0.050 *
16226c16226
< [12,] 0.010 *
---
 > [12,] 0.010 **
16232c16232
< [18,] 0.001 **
---
 > [18,] 0.001 ***

The correct values give a * for 0.05, ** for 0.01, and *** for 0.001:

pval <- rev(sort(c(outer(1:6, 10^-(1:3)))))
symp <- symnum(pval, corr = FALSE,
               cutpoints = c(0,  .001,.01,.05, .1, 1),
               symbols = c("***","**","*","."," "))
noquote(cbind(P.val = format(pval), Signif = symp))
##       P.val Signif
##  [1,] 0.600       
##  [2,] 0.500       
##  [3,] 0.400       
##  [4,] 0.300       
##  [5,] 0.200       
##  [6,] 0.100 .     
##  [7,] 0.060 .     
##  [8,] 0.050 *     
##  [9,] 0.040 *     
## [10,] 0.030 *     
## [11,] 0.020 *     
## [12,] 0.010 **    
## [13,] 0.006 **    
## [14,] 0.005 **    
## [15,] 0.004 **    
## [16,] 0.003 **    
## [17,] 0.002 **    
## [18,] 0.001 ***

The issue here is that in the 64 bit build, 5*10^-2 is 0x1.999999999999bp-5, which is one bit bigger than 0.05 = 0x1.999999999999ap-5.
In the 32 bit build, they are both 0x1.999999999999ap-5, which I believe is the correct result. I’ve traced this to the implementation of pow(x,y) in the C run-time which is part of MinGW-w64 and filed a bug report there.

I’ve compared the source for pow(), and the functions it uses (exp2l(), and log2l()) from MinGW-w64 2.0.9 (used in the previous toolchain) with 3.3.0 (used in the new one), and can’t spot any changes.