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.
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:
Linux cross-compiler for 64 bit Windows output linux32mingw64_gcc-4.9.2.toolchain.tar.gz
Windows native compiler for 64 bit Windows output mingw32mingw64_gcc-4.9.2.toolchain.tar.gz
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.
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.
The threading model has been set using
--enable-threads=win32
in this build.
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:
BINPREF
should be set to the path to the bin
directory in the 32 bit compiler. BINPREF64
should be set to the path to the 64 bit compiler.
MULTI
should be left blank. WIN
should be set to 32 or 64.
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@
These are current and previous problems.
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.
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?
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.