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