| The R for Windows Build Process | |
| =============================== | |
| from the point of view of a Unix installer of R. | |
| Compilation of C/Fortran code is done in two pathways. | |
| 1) standard and add-on packages, the most similar to Unix. | |
| The primary Makefiles are | |
| $(R_HOME)/etc${R_ARCH}/Makeconf | |
| share/make/winshlib.mk | |
| included in that order. Some settings in Makeconf are substituted in | |
| etc/Makeconf by fixed/Makefile, taken from MkRules. | |
| 2) Everything else, where the primary Makefile is MkRules which is | |
| where all the customization is done. This is included by all | |
| Makefile.win files in directories above this one and | |
| ./Makefile | |
| ./fixed/Makefile | |
| ./front-ends/Makefile | |
| ./getline/Makefile | |
| ./installer/Makefile | |
| and replaces Unix's top-level Makeconf. | |
| The largest difference from Unix (even a R-shlib build) is the use of | |
| DLLs, which require the exported symbols to be listed (via nm) in a | |
| .def file and fed to the compiler with the object files for linking. | |
| In recent years DLLs are linked to directly as libraries, but there | |
| remains provision for import libraries via lib%.dll.a: %.def rules. | |
| Making executables has a number of Windows-specific features, done in | |
| front-ends/Makefile: | |
| - A resource compiler is used to compile in version information, an | |
| icon and a manifest. Also done for version information in all the | |
| other DLLs under bin and modules (R.dll Rblas.dll Rgraphapp.dll | |
| Riconv.dll Rlapack.dll lapack.dll). | |
| - LINKFLAGS includes flags for the stack size and to allow addressing | |
| over 2GB for 32-bit executables. | |
| A resource compiler is used to add version information to the DLLs | |
| under directories bin and modules. | |
| The default is to compile without debug info: this can be enabled by | |
| using 'make DEBUG=T' from this directory, or install add-on packages | |
| with Rcmd INSTALL --debug. Otherwise DLLs and executables are | |
| stripped. | |
| Link-Time Optimization | |
| ====================== | |
| To enable LTO for building R set the LTO macro in MkRules.local, to | |
| -flto or e.g. -flto=8 to use 8 threads. | |
| Checking of packages with LTO can be performed by setting the LTO_OPT | |
| macro to -flto in MkRules.local and using Rcmd INSTALL --use-LTO. | |
| For an installed version of R it should suffice to edit the value of | |
| LTO_OPT in the etc/*/Makeconf files or to set it in a personal or site | |
| Makevars file. | |
| [Unlike a Unix-alike, LTO/LTO_OPT are used for Fortran as well as C/C++.] | |
| Cross-compilation | |
| ================= | |
| Linux distributions including Fedora, Debian and Ubuntu provide | |
| cross-compilers and many cross-compiled libraries for both 32- and | |
| 64-bit Windows. For example, on Fedora 32 for a 64-bit build one | |
| might install the RPMs | |
| mingw64-binutils | |
| mingw64-bzip2 | |
| mingw64-cairo | |
| mingw64-cpp | |
| mingw64-crt | |
| mingw64-filesystem | |
| mingw64-gcc | |
| mingw64-gcc-c++ (not needed for R, but needed for cairo, icu and libtiff) | |
| mingw64-gcc-gfortran | |
| mingw64-headers | |
| mingw64-libgomp | |
| mingw64-libpng | |
| mingw64-libjpeg-turbo | |
| mingw64-libtiff | |
| mingw64-pcre2 | |
| mingw64-pkg-config | |
| mingw64-readline | |
| mingw64-tcl | |
| mingw64-termcap | |
| mingw64-tk | |
| mingw64-winpthreads | |
| mingw64-xz-libs | |
| mingw64-zlib | |
| or install the mingw32- variants for a 32-bit build. At the time of | |
| writing this used GCC 9.2.1. | |
| To build all the compiled code, set BINPREF in MkRules.local, e.g. to | |
| WIN = 64 | |
| BINPREF64 = /usr/bin/x86_64-w64-mingw32- | |
| or | |
| WIN = 32 | |
| BINPREF = /usr/bin/i686-w64-mingw32- | |
| Setting LTO is supported. | |
| Then in this directory | |
| make MkRules rbuild rpackages-cross | |
| To make the cairo devices, set something like | |
| USE_CAIRO = TRUE | |
| CAIRO_CPPFLAGS = -I/usr/x86_64-w64-mingw32/sys-root/mingw/include/cairo | |
| CAIRO_LIBS = "-lcairo -lpixman-1 -lpng -lz -lgdi32 -lmsimg32" | |
| in MkRules.local and run | |
| make cairodevices | |
| This will link to the DLLs of external software and for libgomp and | |
| pthreads (for OpenMP). | |
| For a more static build, install | |
| mingw64-bzip2-static | |
| mingw64-libpng-static | |
| mingw64-libjpeg-turbo-static | |
| mingw64-libtiff-static | |
| mingw64-pcre2-static | |
| mingw64-winpthreads-static | |
| mingw64-xz-libs-static | |
| mingw64-zlib-static | |
| and remove the corresponding libfoo.dll.a files from | |
| /usr/x86_64-w64-mingw32/sys-root/mingw/lib, and libgomp.dll.a. (The | |
| build still uses DLLs for libgcc_s_seh and Tcl/Tk). For a static | |
| build of the Cairo devices one would need other RPMs like | |
| mingw64-cairo-static | |
| mingw64-fontconfig-static | |
| mingw64-freetype-static | |
| mingw64-pixman-static | |
| Rather than remove the .dll.a files, one could experiment with -Wl,-Bstatic. | |
| There are curl and ICU libraries for optional features. Settings for | |
| Fedora's libs (DLL versions): | |
| USE_LIBCURL = YES | |
| CURL_LIBS = -lcurl | |
| USE_ICU = YES | |
| ICU_LIBS = -licuuc -licui18n -licudata | |
| There is a static version for curl but not ICU. | |
| Cross-building packages | |
| ======================= | |
| There is experimental minimal support for cross-building packages. | |
| Copy {bin,etc}/{i386,x64} from this build to a standard Linux build. | |
| Edit the copy of etc/*/Makeconf to have | |
| R_WIN = /path/to/top/directory/of/this/build | |
| R_XTRA_CPPFLAGS = -I"$(R_WIN)/include" -DNDEBUG | |
| Set the environment variable R_CROSS_BUILD to i386 or x64. | |
| Use R CMD INSTALL as usual. (This does not do a staged install nor | |
| test loading.) --use-LTO is supported if LTO_OPT was set. | |
| R CMD INSTALL --build will produce a zipped installation. | |
| Should a package require external libraries, these can be placed under | |
| LOCAL_SOFT as defined in etc/*/Makeconf in the copy. | |