[R-SIG-Win] Some suggested changes to Windows makefiles with respect to experimental toolchain

Avraham Adler avraham.adler at gmail.com
Wed Sep 9 00:32:15 CEST 2015


Hello.

While trying to build WITH LTO, I am seeing core R building properly,
seeing the variables I created (including finding the BLAS) and
passing the '-flto' flag properly up to building lapack.dll. From
"building package 'base'" and on (such as stats, compiler, the
recommended packages), the calls to gcc (compilation and linking) no
longer have -flto in them. However, EOPTS does seem to propogate,
which is why I missed this the first time around as I passed -flto in
EOPTS. Of course, that misses the point as the linker doesn't use the
EOPTS flag, which is why I modified the CC, FC, F77 etc. calls. Which
file is it that controls the calls to gcc and gfortran from building
base and on? If it helps, below is the patch I am using (well,
actually the diff, as Windows doesn't play nicely with "patch").

Thank you very much,

Avi


-------------8<-----------------

diff -ruN C:/R/ORIG/R-patched/src/extra/blas/Makefile.win
C:/R/R-patched/src/extra/blas/Makefile.win
--- C:/R/ORIG/R-patched/src/extra/blas/Makefile.win    2015-04-09
16:34:55.000000000 -0400
+++ C:/R/R-patched/src/extra/blas/Makefile.win    2015-09-08
17:03:04.925632500 -0400
@@ -8,11 +8,11 @@
     $(CC) -O3 -I../../include  -c $< -o $@

 ## Rblas.dll imports xerbla_ from R.dll
-ifeq "$(USE_ATLAS)" "YES"
+ifeq "$(USE_EXTBLAS)" "YES"
 ../../../$(BINDIR)/Rblas.dll: blas00.o ../../gnuwin32/dllversion.o
     @$(ECHO) -------- Building $@ --------
     $(DLL) -shared $(DLLFLAGS) -o $@ $^ Rblas.def \
-       -L../../../$(IMPDIR) -lR  -L"$(ATLAS_PATH)" -lf77blas -latlas
+       -L../../../$(IMPDIR) -lR  -L"$(EXTBLAS_PATH)" $(EXTBLASLIBS)
 else
 ../../../$(BINDIR)/Rblas.dll: blas.o cmplxblas.o ../../gnuwin32/dllversion.o
     @$(ECHO) -------- Building $@ --------
diff -ruN C:/R/ORIG/R-patched/src/gnuwin32/Makefile
C:/R/R-patched/src/gnuwin32/Makefile
--- C:/R/ORIG/R-patched/src/gnuwin32/Makefile    2015-04-19
11:02:02.000000000 -0400
+++ C:/R/R-patched/src/gnuwin32/Makefile    2015-09-08 17:21:42.945036900 -0400
@@ -65,6 +65,10 @@
  DLLFLAGS = -s
 endif

+ifdef USE_LTO
+ DLLFLAGS += -Wl,--allow-multiple-definition
+endif
+

 R-DLLFLAGS = -mwindows
 LIBEXTRAS = -L"$(EXT_LIBS)"/lib$(R_ARCH) -lpcre -lz -lbz2 -llzma
diff -ruN C:/R/ORIG/R-patched/src/gnuwin32/MkRules.dist
C:/R/R-patched/src/gnuwin32/MkRules.dist
--- C:/R/ORIG/R-patched/src/gnuwin32/MkRules.dist    2015-04-19
11:02:01.000000000 -0400
+++ C:/R/R-patched/src/gnuwin32/MkRules.dist    2015-09-08
17:07:23.112662800 -0400
@@ -26,9 +26,12 @@
 # an alternative is to use -gstabs here, if the debugger supports only stabs.
 # G_FLAG = -gdwarf-2

-# Set to YES and specify the path if you want to use the ATLAS BLAS.
-# USE_ATLAS = NO
-# ATLAS_PATH =
+# Set to YES and specify the path if you want to use a pre-compiled
ATLAS or OpenBLAS EXTERNAL BLAS.
+# USE_EXTBLAS = NO
+# EXTBLAS_PATH =
+# Use '-lf77blas -latlas' ast the value for EXTBLASLIBS for ATLAS.
+# Use the appropriate version of -lopenblas for OpenBLAS
+# EXTBLASLIBS =

 # Support for the ACML and Goto BLASes has been withdrawn: see R-admin.html

@@ -48,6 +51,8 @@
 # Include the trailing /, and use / not \.
 # Do this in the more detailed options below

+# To enable link-time optimization using the 4.9.2 toolset, set to YES
+# USE_LTO = YES

 ### BEGIN more detailed options
 # Some of the toolchains have prefixes for e.g. ar, gcc.
diff -ruN C:/R/ORIG/R-patched/src/gnuwin32/MkRules.rules
C:/R/R-patched/src/gnuwin32/MkRules.rules
--- C:/R/ORIG/R-patched/src/gnuwin32/MkRules.rules    2015-04-19
11:02:03.000000000 -0400
+++ C:/R/R-patched/src/gnuwin32/MkRules.rules    2015-09-08
17:09:36.373309600 -0400
@@ -5,10 +5,12 @@
 LOCAL_SOFT ?= $(R_HOME)/extsoft
 EXT_LIBS ?= $(LOCAL_SOFT)
 G_FLAG ?= -gdwarf-2
-USE_ATLAS ?= NO
-ATLAS_PATH ?=
+USE_EXTBLAS ?= NO
+EXTBLAS_PATH ?=
+EXTBLASLIBS ?=
 MULTI ?=
 TOOL_PATH ?=
+USE_LTO ?=
 BINPREF ?=
 BINPREF64 ?= x86_64-w64-mingw32-
 M_ARCH ?=
@@ -67,6 +69,15 @@
 SYMPAT = 's/^.* [BCDRT] _/ /p'
 endif

+## Link-time optimization
+ifeq "$(USE_LTO)" "YES"
+LTOPREF = gcc-
+LTOCALL = -flto
+else
+LTOPREF =
+LTOCALL =
+endif
+
 ## -std=c99 would force __STRICT_ANSI__ disabling strdup etc, and also alloca
 C99FLAG=-std=gnu99

@@ -81,10 +92,10 @@
 IMPDIR=$(BINDIR)
 endif

-AR=$(BINPREF)ar
+AR=$(BINPREF)$(LTOPREF)ar
 # AWK=gawk
 CAT=cat
-CC=$(BINPREF)gcc$(GCC4_SUFF) $(C99FLAG) $(M_ARCH)
+CC=$(BINPREF)gcc$(GCC4_SUFF) $(C99FLAG) $(M_ARCH) $(LTOCALL)
 CP=cp
 # as set by make
 CPP=$(CC) -E
@@ -94,14 +105,14 @@
 ## even for native builds
 DLLTOOLFLAGS=--as $(BINPREF)as $(DT_ARCH) -k
 ECHO=echo
-F77=$(BINPREF)gfortran$(GCC4_SUFF) $(M_ARCH)
+F77=$(BINPREF)gfortran$(GCC4_SUFF) $(M_ARCH) $(LTOCALL)
 FLIBS=-lgfortran -lquadmath
 LINKER=$(MAIN_LD)
 MAIN_LD=$(CC)
 MAKEINFO = $(TEXI2ANY)
 MKDIR=mkdir
-NM=$(BINPREF)nm
-RANLIB=$(BINPREF)ranlib
+NM=$(BINPREF)$(LTOPREF)nm
+RANLIB=$(BINPREF)$(LTOPREF)ranlib
 RESCOMP=$(BINPREF)windres $(RC_ARCH)

 # as set by make
diff -ruN C:/R/ORIG/R-patched/src/gnuwin32/fixed/Makefile
C:/R/R-patched/src/gnuwin32/fixed/Makefile
--- C:/R/ORIG/R-patched/src/gnuwin32/fixed/Makefile    2015-04-19
11:02:01.000000000 -0400
+++ C:/R/R-patched/src/gnuwin32/fixed/Makefile    2015-09-08
18:09:11.695519700 -0400
@@ -34,6 +34,8 @@
       -e "s|R_ARCH =|R_ARCH = $(R_ARCH)|" \
       -e "s|DT_ARCH =|DT_ARCH = $(DT_ARCH)|" \
       -e "s|RC_ARCH =|RC_ARCH = $(RC_ARCH)|" \
+      -e "s|LTOCALL =|LTOCALL = $(LTOCALL)|" \
+      -e "s|LTOPREF =|LTOPREF = $(LTOPREF)|" \
       -e "s|M_ARCH =|M_ARCH = $(M_ARCH)|" \
       -e "s|@SYMPAT@|$(SYMPAT)|" \
       -e "s|(TCL_HOME)/bin|(TCL_HOME)/bin64|" \
@@ -49,6 +51,8 @@
       -e "s|R_ARCH =|R_ARCH = $(R_ARCH)|" \
       -e "s|DT_ARCH =|DT_ARCH = $(DT_ARCH)|" \
       -e "s|RC_ARCH =|RC_ARCH = $(RC_ARCH)|" \
+      -e "s|LTOCALL =|LTOCALL = $(LTOCALL)|" \
+      -e "s|LTOPREF =|LTOPREF = $(LTOPREF)|" \
       -e "s|M_ARCH =|M_ARCH = $(M_ARCH)|" \
       -e "s|@SYMPAT@|$(SYMPAT)|" \
       -e "s|@OPENMP@|$(OPENMP)|" \
diff -ruN C:/R/ORIG/R-patched/src/gnuwin32/fixed/etc/Makeconf
C:/R/R-patched/src/gnuwin32/fixed/etc/Makeconf
--- C:/R/ORIG/R-patched/src/gnuwin32/fixed/etc/Makeconf    2015-04-19
11:02:01.000000000 -0400
+++ C:/R/R-patched/src/gnuwin32/fixed/etc/Makeconf    2015-09-08
18:09:32.898759500 -0400
@@ -14,6 +14,12 @@
 DLLFLAGS+= -static-libgcc
 LINKFLAGS+= -static-libgcc

+ifdef USE_LTO
+  DLLFLAGS+= -Wl,--allow-multiple-definition
+  LINKFLAGS+= -Wl,--allow-multiple-definition
+
+endif
+
 ## Things which are substituted by fixed/Makefile (and also -O3 -> -O2)
 WIN = 32
 BINPREF =
@@ -37,7 +43,7 @@

 DLLTOOL = $(BINPREF)dlltool --as $(BINPREF)as $(DT_ARCH)
 DLLTOOLFLAGS = -k
-NM = $(BINPREF)nm
+NM = $(BINPREF)$(LTOPREF)nm
 RESCOMP = $(BINPREF)windres $(RC_ARCH)
 ## MAIN_LD needs to be set by the package
 LINKER = $(MAIN_LD)
@@ -61,20 +67,20 @@
 # was a reference to Rzlib.dll in R < 3.2.0
 ZLIB_LIBS = -lz

-AR = $(BINPREF)ar
+AR = $(BINPREF)$(LTOPREF)ar
 ## Used by packages 'maps' and 'mapdata'
 AWK = gawk
 BLAS_LIBS = -L"$(R_HOME)/$(IMPDIR)" -lRblas
 C_VISIBILITY =
-CC = $(BINPREF)gcc $(M_ARCH)
+CC = $(BINPREF)gcc $(M_ARCH) $(LTOCALL)
 CFLAGS = -O3 -Wall $(DEBUGFLAG) -std=gnu99 @EOPTS@
 CPICFLAGS =
-CPPFLAGS =
-CXX = $(BINPREF)g++ $(M_ARCH)
+CPPFLAGS =
+CXX = $(BINPREF)g++ $(M_ARCH) $(LTOCALL)
 CXXCPP = $(CXX) -E
 CXXFLAGS = -O2 -Wall $(DEBUGFLAG) @EOPTS@
 CXXPICFLAGS =
-CXX1X = $(BINPREF)g++ $(M_ARCH)
+CXX1X = $(BINPREF)g++ $(M_ARCH) $(LTOCALL)
 CXX1XFLAGS = -O2 -Wall $(DEBUGFLAG) @EOPTS@
 CXX1XPICFLAGS =
 CXX1XSTD = -std=c++0x
@@ -86,11 +92,11 @@
 ECHO_C =
 ECHO_N = -n
 ECHO_T =
-FC = $(BINPREF)gfortran $(M_ARCH)
+FC = $(BINPREF)gfortran $(M_ARCH) $(LTOCALL)
 FCFLAGS = -O3 $(DEBUGFLAG) @EOPTS@
 # additional libs needed when linking with $(FC), e.g. on Solaris
 FCLIBS =
-F77 = $(BINPREF)gfortran $(M_ARCH)
+F77 = $(BINPREF)gfortran $(M_ARCH) $(LTOCALL)
 F77_VISIBILITY =
 FFLAGS = -O3 $(DEBUGFLAG) @EOPTS@
 FLIBS = -lgfortran
@@ -129,7 +135,7 @@
 OBJC_LIBS = -lobjc
 OBJCXX =
 R_ARCH =
-RANLIB = $(BINPREF)ranlib
+RANLIB = $(BINPREF)$(LTOPREF)ranlib
 SAFE_FFLAGS = -O3 -ffloat-store
 SED = sed
 ## it seems some makes (but not ours) get upset if SHELL is set.

------------->8-----------------


On Tue, Sep 8, 2015 at 2:00 PM, Duncan Murdoch <murdoch.duncan at gmail.com> wrote:
> On 08/09/2015 12:56 PM, Avraham Adler wrote:
>> Hello.
>>
>> As the new toolchain is going to require some changes to some of the
>> makefiles for Windows (such as the NM_FILTER already in place, I would
>> like to make some suggestions for review.
>>
>> A: Link-time Optimization
>> I have successfully compiled R (Windows7 64bit) using link-time
>> optimization, but it required some monkeying around with various
>> files. Specifically:
>>
>> 1) src/gnuwin32/Mkrules.local: (no change needed)
>>     needs '-flto -ffat-lto-objects' passed in EOPTS
>>
>> 2) src/gnuwin32/Mkrules: (changes needed to lines 243, 262, and 263)
>>     AR, NM, and RANLIB all need to add 'gcc-' as a prefix to the
>> actual calls. For example: AR=$(BINPREF)gcc-ar
>
> That's no good.  The makefiles will need to work with both toolchains,
> and that doesn't look compatible with the old toolchain.
>
> I'd be happy to put in changes, subject to the following:
>
>  - Existing builds should work with no change.
>  - Users of the new toolchain should be able to try it out with a one
> line addition to Mkrules.local.
>  - It would be nice to allow some flexibility, so if you get it wrong on
> the first try, only Mkrules.local needs to be updated, not the R-devel
> sources.
>
> Send me a patch that you've tested on both toolchains, and I'll put it
> in (after testing on the old toolchain).
>
> Duncan Murdoch
>
>>
>> 3) src/gnuwin32/Makefile: (changes needed to line 65)
>>     DLLFLAGS needs to allow multiple definitions (for the tools
>> package) so the else branch needs to be changed to 'DLLFLAGS =
>> -Wl,--allow-multiple-definition -s'
>>
>> 4) src/gnuwin32/fixed/etc/Makeconf (changes needed to lines 14, 15,
>> 40, 64, and 132)
>>     DLLFLAGS and LINKFLAGS need '-Wl,--allow-multiple-definition'
>> added (lines 14 & 15)
>>     AR, NM, and RANLIB need the 'gcc-' prefix (lines 40, 64, and 132)
>>
>> Would it be possible and make sense to expose the variables AR, NM,
>> RANLIB, DLLFLAGS, and LINKFLAGS in Mkrules.local to allow for LTO?
>>
>> B: External BLAS
>> I have been compiling R (Windows7 64bit) linking to an external
>> OpenBLAS for years now. The method requires changing
>> src/gnuwin32/Mkrules.local to 'USE_ATLAS = YES' and setting the proper
>> ATLAS_PATH (lines 30 & 31). Then changing src/extra/blas/Makefile.win
>> line 15 to point to the proper file. Specifically, from
>> '-L../../../$(IMPDIR) -lR  -L"$(ATLAS_PATH)" -lf77blas -latlas' to '
>> -L../../../$(IMPDIR) -lR  -L"$(ATLAS_PATH)" -lopenblas' or the
>> equivalent. Could the name of the BLAS library itself be made a
>> variable for Mkrules.local? Perhaps something like 'USE_EXTBLAS',
>> 'EXTBLAS_PATH', and 'EXTBLASLIBS' could be used in Mkrules.local, with
>> EXTBLASLIBS even defaulting to '-lf77blas -latlas'. Then
>> src/extra/blas/Makefile.win line 15 could look something like
>> '-L../../../$(IMPDIR) -lR  -L"$(ATLAS_PATH)" $(EXTBLASLIBS)'? I admit
>> I have not tested this configuration yet, though.
>>
>> C: Toolchain definitions
>> If the toolchain developed by Jeroen will be be the eventual Rtools,
>> as it is a multilib, src/gnuwin32/Mkrules.local lines 52–59 will
>> probably require a rewrite, if they are necessary at all.
>>
>> Thank you,
>>
>> Avi
>>
>> _______________________________________________
>> R-SIG-windows mailing list
>> R-SIG-windows at r-project.org
>> https://stat.ethz.ch/mailman/listinfo/r-sig-windows
>>
>



More information about the R-SIG-windows mailing list