Tools.gmk revision 2281:4353c659dfde
150276Speter#
2166124Srafan# Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
350276Speter# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
450276Speter#
550276Speter# This code is free software; you can redistribute it and/or modify it
650276Speter# under the terms of the GNU General Public License version 2 only, as
750276Speter# published by the Free Software Foundation.  Oracle designates this
850276Speter# particular file as subject to the "Classpath" exception as provided
950276Speter# by Oracle in the LICENSE file that accompanied this code.
1050276Speter#
1150276Speter# This code is distributed in the hope that it will be useful, but WITHOUT
1250276Speter# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1350276Speter# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1450276Speter# version 2 for more details (a copy is included in the LICENSE file that
1550276Speter# accompanied this code).
1650276Speter#
1750276Speter# You should have received a copy of the GNU General Public License version
1850276Speter# 2 along with this work; if not, write to the Free Software Foundation,
1950276Speter# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2050276Speter#
2150276Speter# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2250276Speter# or visit www.oracle.com if you need additional information or have any
2350276Speter# questions.
2450276Speter#
2550276Speter
2650276Speter##########################################################################################
2750276Speter#
2850276Speter# Workhorse makefile for creating ONE cross compiler
2950276Speter# Needs either to be from BUILD -> BUILD OR have
30166124Srafan# BUILD -> HOST prebuilt
3150276Speter#
3250276Speter# NOTE: There is a bug here. We don't limit the
3350276Speter# PATH when building BUILD -> BUILD, which means that
3450276Speter# if you configure after you've once build the BUILD->BUILD
3550276Speter# compiler THAT one will be picked up as the compiler for itself.
3650276Speter# This is not so great, especially if you did a partial delete
3750276Speter# of the target tree.
3850276Speter#
3950276Speter# Fix this...
40166124Srafan#
4150276Speter
4250276Speter$(info TARGET=$(TARGET))
4350276Speter$(info HOST=$(HOST))
4450276Speter$(info BUILD=$(BUILD))
4550276Speter
4650276SpeterARCH := $(word 1,$(subst -, ,$(TARGET)))
4750276Speter
4850276Speter##########################################################################################
4950276Speter# Define external dependencies
5050276Speter
5150276Speter# Latest that could be made to work.
5250276Spetergcc_ver := gcc-4.9.2
5376726Speterbinutils_ver := binutils-2.25
54166124Srafanccache_ver := ccache-3.2.1
5550276Spetermpfr_ver := mpfr-3.0.1
56166124Srafangmp_ver := gmp-4.3.2
57166124Srafanmpc_ver := mpc-1.0.1
58166124Srafan
59166124SrafanGCC := http://ftp.gnu.org/pub/gnu/gcc/$(gcc_ver)/$(gcc_ver).tar.bz2
60166124SrafanBINUTILS := http://ftp.gnu.org/pub/gnu/binutils/$(binutils_ver).tar.bz2
6150276SpeterCCACHE := http://samba.org/ftp/ccache/$(ccache_ver).tar.gz
6250276SpeterMPFR := http://www.mpfr.org/${mpfr_ver}/${mpfr_ver}.tar.bz2
6350276SpeterGMP := http://ftp.gnu.org/pub/gnu/gmp/${gmp_ver}.tar.bz2
6450276SpeterMPC := http://www.multiprecision.org/mpc/download/${mpc_ver}.tar.gz
6550276Speter
6650276Speter# RPMs in OEL6.4
6750276SpeterLINUX_VERSION := OEL6.4
6850276SpeterRPM_LIST := \
6950276Speter    kernel-headers \
70166124Srafan    glibc glibc-headers glibc-devel \
7150276Speter    cups-libs cups-devel \
7250276Speter    libX11 libX11-devel \
7350276Speter    xorg-x11-proto-devel \
74    alsa-lib alsa-lib-devel \
75    libXext libXext-devel \
76    libXtst libXtst-devel \
77    libXrender libXrender-devel \
78    freetype freetype-devel \
79    libXt libXt-devel \
80    libSM libSM-devel \
81    libICE libICE-devel \
82    libXi libXi-devel \
83    libXdmcp libXdmcp-devel \
84    libXau libXau-devel \
85    libgcc \
86    elfutils elfutils-libs elfutils-devel \
87    elfutils-libelf elfutils-libelf-devel \
88    zlib zlib-devel
89
90
91ifeq ($(ARCH),x86_64)
92  RPM_DIR ?= $(RPM_DIR_x86_64)
93  RPM_ARCHS := x86_64 noarch
94  ifeq ($(BUILD),$(HOST))
95    ifeq ($(TARGET),$(HOST))
96      # When building the native compiler for x86_64, enable mixed mode.
97      RPM_ARCHS += i386 i686
98    endif
99  endif
100else
101  RPM_DIR ?= $(RPM_DIR_i686)
102  RPM_ARCHS := i386 i686
103endif
104
105# Sort to remove duplicates
106RPM_FILE_LIST := $(sort $(foreach a,$(RPM_ARCHS),$(wildcard $(patsubst %,$(RPM_DIR)/%*$a.rpm,$(RPM_LIST)))))
107
108#$(info RPM_FILE_LIST $(RPM_FILE_LIST))
109
110ifeq ($(RPM_FILE_LIST),)
111  $(error Found no RPMs, RPM_DIR must point to list of directories to search for RPMs)
112endif
113
114##########################################################################################
115# Define common directories and files
116
117# Ensure we have 32-bit libs also for x64. We enable mixed-mode.
118ifeq (x86_64,$(ARCH))
119  LIBDIRS := lib64 lib
120  CFLAGS_lib := -m32
121else
122  LIBDIRS := lib
123endif
124
125# Define directories
126RESULT := $(OUTPUT_ROOT)/result
127BUILDDIR := $(OUTPUT_ROOT)/$(HOST)/$(TARGET)
128PREFIX := $(RESULT)/$(HOST)
129TARGETDIR := $(PREFIX)/$(TARGET)
130SYSROOT := $(TARGETDIR)/sysroot
131DOWNLOAD := $(OUTPUT_ROOT)/download
132SRCDIR := $(OUTPUT_ROOT)/src
133
134# Marker file for unpacking rpms
135rpms := $(SYSROOT)/rpms_unpacked
136
137# Need to patch libs that are linker scripts to use non-absolute paths
138libs := $(SYSROOT)/libs_patched
139
140##########################################################################################
141# Unpack source packages
142
143# Generate downloading + unpacking of sources.
144define Download
145  $(1)_DIR = $(abspath $(SRCDIR)/$(basename $(basename $(notdir $($(1))))))
146  $(1)_CFG = $$($(1)_DIR)/configure
147  $(1)_FILE = $(DOWNLOAD)/$(notdir $($(1)))
148
149  $$($(1)_CFG) : $$($(1)_FILE)
150	mkdir -p $$(SRCDIR)
151	tar -C $$(SRCDIR) -x$$(if $$(findstring .gz, $$<),z,j)f $$<
152	$$(foreach p,$$(abspath $$(wildcard $$(notdir $$($(1)_DIR)).patch)), \
153	  echo PATCHING $$(p) ; \
154	  patch -d $$($(1)_DIR) -p1 -i $$(p) ; \
155	)
156	touch $$@
157
158  $$($(1)_FILE) :
159	wget -P $(DOWNLOAD) $$($(1))
160endef
161
162# Download and unpack all source packages
163$(foreach p,GCC BINUTILS CCACHE MPFR GMP MPC,$(eval $(call Download,$(p))))
164
165##########################################################################################
166# Unpack RPMS
167
168# Note. For building linux you should install rpm2cpio.
169define unrpm
170  $(SYSROOT)/$(notdir $(1)).unpacked \
171    : $(1)
172  $$(rpms) : $(SYSROOT)/$(notdir $(1)).unpacked
173endef
174
175%.unpacked :
176	$(info Unpacking target rpms and libraries from $<)
177	@(mkdir -p $(@D); \
178	cd $(@D); \
179	rpm2cpio $< | \
180	    cpio --extract --make-directories \
181	        -f \
182	        "./usr/share/doc/*" \
183	        "./usr/share/man/*" \
184	        "./usr/X11R6/man/*" \
185	        "*/X11/locale/*" \
186	    || die ; )
187	touch $@
188
189$(foreach p,$(RPM_FILE_LIST),$(eval $(call unrpm,$(p))))
190
191##########################################################################################
192
193# Note: MUST create a <sysroot>/usr/lib even if not really needed.
194# gcc will use a path relative to it to resolve lib64. (x86_64).
195# we're creating multi-lib compiler with 32bit libc as well, so we should
196# have it anyway, but just to make sure...
197# Patch libc.so and libpthread.so to force linking against libraries in sysroot
198# and not the ones installed on the build machine.
199$(libs) : $(rpms)
200	@echo Patching libc and pthreads
201	@(for f in `find $(SYSROOT) -name libc.so -o -name libpthread.so`; do \
202	  (cat $$f | sed -e 's|/usr/lib64/||g' \
203	      -e 's|/usr/lib/||g' \
204	      -e 's|/lib64/||g' \
205	      -e 's|/lib/||g' ) > $$f.tmp ; \
206	  mv $$f.tmp $$f ; \
207	done)
208	@mkdir -p $(SYSROOT)/usr/lib
209	@touch $@
210
211##########################################################################################
212
213# Define marker files for each source package to be compiled
214$(foreach t,binutils mpfr gmp mpc gcc ccache,$(eval $(t) = $(TARGETDIR)/$($(t)_ver).done))
215
216##########################################################################################
217
218# Default base config
219CONFIG = --target=$(TARGET) \
220    --host=$(HOST) --build=$(BUILD) \
221    --prefix=$(PREFIX)
222
223PATHEXT = $(RESULT)/$(BUILD)/bin:
224
225PATHPRE = PATH=$(PATHEXT)$(PATH)
226BUILDPAR = -j16
227
228# Default commands to when making
229MAKECMD =
230INSTALLCMD = install
231
232
233declare_tools = CC$(1)=$(2)gcc LD$(1)=$(2)ld AR$(1)=$(2)ar AS$(1)=$(2)as RANLIB$(1)=$(2)ranlib CXX$(1)=$(2)g++ OBJDUMP$(1)=$(2)objdump
234
235ifeq ($(HOST),$(BUILD))
236  ifeq ($(HOST),$(TARGET))
237    TOOLS = $(call declare_tools,_FOR_TARGET,)
238  endif
239endif
240
241TOOLS ?= $(call declare_tools,_FOR_TARGET,$(TARGET)-)
242
243##########################################################################################
244
245# Create a TARGET bfd + libiberty only.
246# Configure one or two times depending on mulitlib arch.
247# If multilib, the second should be 32-bit, and we resolve
248# CFLAG_<name> to most likely -m32.
249define mk_bfd
250  $$(info Libs for $(1))
251  $$(BUILDDIR)/$$(binutils_ver)-$(subst /,-,$(1))/Makefile \
252      : CFLAGS += $$(CFLAGS_$(1))
253  $$(BUILDDIR)/$$(binutils_ver)-$(subst /,-,$(1))/Makefile \
254      : LIBDIRS = --libdir=$(TARGETDIR)/$(1)
255
256  bfdlib += $$(TARGETDIR)/$$(binutils_ver)-$(subst /,-,$(1)).done
257  bfdmakes += $$(BUILDDIR)/$$(binutils_ver)-$(subst /,-,$(1))/Makefile
258endef
259
260# Create one set of bfds etc for each multilib arch
261$(foreach l,$(LIBDIRS),$(eval $(call mk_bfd,$(l))))
262
263# Only build these two libs.
264$(bfdlib) : MAKECMD = all-libiberty all-bfd
265$(bfdlib) : INSTALLCMD = install-libiberty install-bfd
266
267# Building targets libbfd + libiberty. HOST==TARGET, i.e not
268# for a cross env.
269$(bfdmakes) : CONFIG = --target=$(TARGET) \
270    --host=$(TARGET) --build=$(BUILD) \
271    --prefix=$(TARGETDIR) \
272    --with-sysroot=$(SYSROOT) \
273    $(LIBDIRS)
274
275$(bfdmakes) : TOOLS = $(call declare_tools,_FOR_TARGET,$(TARGET)-) $(call declare_tools,,$(TARGET)-)
276
277##########################################################################################
278
279$(gcc) \
280    $(binutils) \
281    $(gmp) \
282    $(mpfr) \
283    $(mpc) \
284    $(bfdmakes) \
285    $(ccache) : ENVS += $(TOOLS)
286
287# libdir to work around hateful bfd stuff installing into wrong dirs...
288# ensure we have 64 bit bfd support in the HOST library. I.e our
289# compiler on i686 will know 64 bit symbols, BUT later
290# we build just the libs again for TARGET, then with whatever the arch
291# wants.
292$(BUILDDIR)/$(binutils_ver)/Makefile : CONFIG += --enable-64-bit-bfd --libdir=$(PREFIX)/$(word 1,$(LIBDIRS))
293
294# Makefile creation. Simply run configure in build dir.
295$(bfdmakes) \
296$(BUILDDIR)/$(binutils_ver)/Makefile \
297    : $(BINUTILS_CFG)
298	$(info Configuring $@. Log in $(@D)/log.config)
299	@mkdir -p $(@D)
300	( \
301	  cd $(@D) ; \
302	  $(PATHPRE) $(ENVS) CFLAGS="$(CFLAGS)" \
303	      $(BINUTILS_CFG) \
304	      $(CONFIG) \
305	      --with-sysroot=$(SYSROOT) \
306	      --disable-nls \
307	      --program-prefix=$(TARGET)- \
308	      --enable-multilib \
309	) > $(@D)/log.config 2>&1
310	@echo 'done'
311
312$(BUILDDIR)/$(mpfr_ver)/Makefile \
313    : $(MPFR_CFG)
314	$(info Configuring $@. Log in $(@D)/log.config)
315	@mkdir -p $(@D)
316	( \
317	  cd $(@D) ; \
318	  $(PATHPRE) $(ENVS) CFLAGS="$(CFLAGS)" \
319	      $(MPFR_CFG) \
320	      $(CONFIG) \
321	      --program-prefix=$(TARGET)- \
322	      --enable-shared=no \
323	      --with-gmp=$(PREFIX) \
324	) > $(@D)/log.config 2>&1
325	@echo 'done'
326
327$(BUILDDIR)/$(gmp_ver)/Makefile \
328    : $(GMP_CFG)
329	$(info Configuring $@. Log in $(@D)/log.config)
330	@mkdir -p $(@D)
331	( \
332	  cd $(@D) ; \
333	  $(PATHPRE) $(ENVS) CFLAGS="$(CFLAGS)" \
334	      $(GMP_CFG) \
335	      --host=$(HOST) --build=$(BUILD) \
336	      --prefix=$(PREFIX) \
337	      --disable-nls \
338	      --program-prefix=$(TARGET)- \
339	      --enable-shared=no \
340	      --with-mpfr=$(PREFIX) \
341	) > $(@D)/log.config 2>&1
342	@echo 'done'
343
344$(BUILDDIR)/$(mpc_ver)/Makefile \
345    : $(MPC_CFG)
346	$(info Configuring $@. Log in $(@D)/log.config)
347	@mkdir -p $(@D)
348	( \
349	  cd $(@D) ; \
350	  $(PATHPRE) $(ENVS) CFLAGS="$(CFLAGS)" \
351	      $(MPC_CFG) \
352	      $(CONFIG) \
353	      --program-prefix=$(TARGET)- \
354	      --enable-shared=no \
355	      --with-mpfr=$(PREFIX) \
356	      --with-gmp=$(PREFIX) \
357	) > $(@D)/log.config 2>&1
358	@echo 'done'
359
360# Only valid if glibc target -> linux
361# proper destructor handling for c++
362ifneq (,$(findstring linux,$(TARGET)))
363  $(BUILDDIR)/$(gcc_ver)/Makefile : CONFIG += --enable-__cxa_atexit
364endif
365
366# Want:
367# c,c++
368# shared libs
369# multilib (-m32/-m64 on x64)
370# skip native language.
371# and link and assemble with the binutils we created
372# earlier, so --with-gnu*
373$(BUILDDIR)/$(gcc_ver)/Makefile \
374    : $(GCC_CFG)
375	$(info Configuring $@. Log in $(@D)/log.config)
376	mkdir -p $(@D)
377	( \
378	  cd $(@D) ; \
379	  $(PATHPRE) $(ENVS) $(GCC_CFG) $(EXTRA_CFLAGS) \
380	      $(CONFIG) \
381	      --with-sysroot=$(SYSROOT) \
382	      --enable-languages=c,c++ \
383	      --enable-shared \
384	      --enable-multilib \
385	      --disable-nls \
386	      --with-gnu-as \
387	      --with-gnu-ld \
388	      --with-mpfr=$(PREFIX) \
389	      --with-gmp=$(PREFIX) \
390	      --with-mpc=$(PREFIX) \
391	) > $(@D)/log.config 2>&1
392	@echo 'done'
393
394# need binutils for gcc
395$(gcc) : $(binutils)
396
397# as of 4.3 or so need these for doing config
398$(BUILDDIR)/$(gcc_ver)/Makefile : $(gmp) $(mpfr) $(mpc)
399$(mpfr) : $(gmp)
400$(mpc) : $(gmp) $(mpfr)
401
402##########################################################################################
403# very straightforward. just build a ccache. it is only for host.
404$(BUILDDIR)/$(ccache_ver)/Makefile \
405    : $(CCACHE_CFG)
406	$(info Configuring $@. Log in $(@D)/log.config)
407	@mkdir -p $(@D)
408	@( \
409	  cd $(@D) ; \
410	  $(PATHPRE) $(ENVS) $(CCACHE_CFG) \
411	      $(CONFIG) \
412	) > $(@D)/log.config 2>&1
413	@echo 'done'
414
415gccpatch = $(TARGETDIR)/gcc-patched
416
417##########################################################################################
418# For some reason cpp is not created as a target-compiler
419ifeq ($(HOST),$(TARGET))
420  $(gccpatch) : $(gcc) link_libs
421	@echo -n 'Creating compiler symlinks...'
422	@for f in cpp; do \
423	  if [ ! -e $(PREFIX)/bin/$(TARGET)-$$f ]; \
424	  then \
425	    cd $(PREFIX)/bin && \
426	    ln -s $$f $(TARGET)-$$f ; \
427	  fi \
428	done
429	@touch $@
430	@echo 'done'
431
432  ##########################################################################################
433  # Ugly at best. Seems that when we compile host->host compiler, that are NOT
434  # the BUILD compiler, the result will not try searching for libs in package root.
435  # "Solve" this by create links from the target libdirs to where they are.
436  link_libs:
437	@echo -n 'Creating library symlinks...'
438	@$(foreach l,$(LIBDIRS), \
439	for f in `cd $(PREFIX)/$(l) && ls`; do \
440	  if [ ! -e $(TARGETDIR)/$(l)/$$f ]; then \
441	    mkdir -p $(TARGETDIR)/$(l) && \
442	    cd $(TARGETDIR)/$(l)/ && \
443	    ln -s $(if $(findstring /,$(l)),../,)../../$(l)/$$f $$f; \
444	  fi \
445	done;)
446	@echo 'done'
447else
448  $(gccpatch) :
449	@echo 'done'
450endif
451
452##########################################################################################
453# Build in two steps.
454# make <default>
455# make install.
456# Use path to our build hosts cross tools
457# Always need to build cross tools for build host self.
458$(TARGETDIR)/%.done : $(BUILDDIR)/%/Makefile
459	$(info Building $(basename $@). Log in $(<D)/log.build)
460	$(PATHPRE) $(ENVS) $(MAKE) $(BUILDPAR) -f $< -C $(<D) $(MAKECMD) $(MAKECMD.$(notdir $@)) > $(<D)/log.build 2>&1
461	@echo -n 'installing...'
462	$(PATHPRE) $(MAKE) $(INSTALLPAR) -f $< -C $(<D) $(INSTALLCMD) $(MAKECMD.$(notdir $@)) > $(<D)/log.install 2>&1
463	@touch $@
464	@echo 'done'
465
466##########################################################################################
467
468$(PREFIX)/devkit.info: FRC
469	@echo 'Creating devkit.info in the root of the kit'
470	rm -f $@
471	touch $@
472	echo '# This file describes to configure how to interpret the contents of this' >> $@
473	echo '# devkit' >> $@
474	echo '' >> $@
475	echo 'DEVKIT_NAME="$(gcc_ver) - $(LINUX_VERSION)"' >> $@
476	echo 'DEVKIT_TOOLCHAIN_PATH="$$DEVKIT_ROOT/bin"' >> $@
477	echo 'DEVKIT_SYSROOT="$$DEVKIT_ROOT/$$host/sysroot"' >> $@
478
479##########################################################################################
480
481ifeq ($(TARGET), $(HOST))
482  $(PREFIX)/bin/%:
483	@echo 'Creating missing $* soft link'
484	ln -s $(TARGET)-$* $@
485
486  missing-links := $(addprefix $(PREFIX)/bin/, \
487      addr2line ar as c++ c++filt elfedit g++ gcc gprof ld nm objcopy ranlib readelf \
488      size strings strip)
489endif
490
491##########################################################################################
492
493bfdlib : $(bfdlib)
494binutils : $(binutils)
495rpms : $(rpms)
496libs : $(libs)
497sysroot : rpms libs
498gcc : sysroot $(gcc) $(gccpatch)
499all : binutils gcc bfdlib $(PREFIX)/devkit.info $(missing-links)
500
501# this is only built for host. so separate.
502ccache : $(ccache)
503
504# Force target
505FRC:
506
507.PHONY : gcc all binutils bfdlib link_libs rpms libs sysroot
508