[R-SIG-Win] Some suggested changes to Windows makefiles with respect to experimental toolchain
Duncan Murdoch
murdoch.duncan at gmail.com
Wed Sep 9 00:56:25 CEST 2015
On 08/09/2015 6:32 PM, Avraham Adler wrote:
> 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").
I didn't write the make files, and can't answer your questions. You're
on your own here if nobody else pipes up.
Duncan Murdoch
>
> 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