Tools.gmk revision 910:a667caba1e84
1#
2# Copyright (c) 2013, 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.7.3
53binutils_ver := binutils-2.22
54ccache_ver := ccache-3.1.9
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 OEL5.5
67RPM_LIST := \
68    kernel-headers \
69    glibc-2 glibc-headers glibc-devel \
70    cups-libs cups-devel \
71    libX11 libX11-devel \
72    xorg-x11-proto-devel \
73    alsa-lib alsa-lib-devel \
74    libXext libXext-devel \
75    libXtst libXtst-devel \
76    libXrender libXrender-devel \
77    freetype freetype-devel \
78    libXt libXt-devel \
79    libSM libSM-devel \
80    libICE libICE-devel \
81    libXi libXi-devel \
82    libXdmcp libXdmcp-devel \
83    libXau libXau-devel \
84    libgcc
85
86
87ifeq ($(ARCH),x86_64)
88  RPM_DIR ?= $(RPM_DIR_x86_64)
89  RPM_ARCHS := x86_64
90  ifeq ($(BUILD),$(HOST))
91    ifeq ($(TARGET),$(HOST))
92      # When building the native compiler for x86_64, enable mixed mode.
93      RPM_ARCHS += i386 i686
94    endif
95  endif
96else
97  RPM_DIR ?= $(RPM_DIR_i686)
98  RPM_ARCHS := i386 i686
99endif
100
101# Sort to remove duplicates
102RPM_FILE_LIST := $(sort $(foreach a,$(RPM_ARCHS),$(wildcard $(patsubst %,$(RPM_DIR)/%*$a.rpm,$(RPM_LIST)))))
103
104ifeq ($(RPM_FILE_LIST),)
105  $(error Found no RPMs, RPM_DIR must point to list of directories to search for RPMs)
106endif
107
108##########################################################################################
109# Define common directories and files
110
111# Ensure we have 32-bit libs also for x64. We enable mixed-mode.
112ifeq (x86_64,$(ARCH))
113  LIBDIRS := lib64 lib
114  CFLAGS_lib := -m32
115else
116  LIBDIRS := lib
117endif
118
119# Define directories
120RESULT := $(OUTPUT_ROOT)/result
121BUILDDIR := $(OUTPUT_ROOT)/$(HOST)/$(TARGET)
122PREFIX := $(RESULT)/$(HOST)
123TARGETDIR := $(PREFIX)/$(TARGET)
124SYSROOT := $(TARGETDIR)/sys-root
125DOWNLOAD := $(OUTPUT_ROOT)/download
126SRCDIR := $(OUTPUT_ROOT)/src
127
128# Marker file for unpacking rpms
129rpms := $(SYSROOT)/rpms_unpacked
130
131# Need to patch libs that are linker scripts to use non-absolute paths
132libs := $(SYSROOT)/libs_patched
133
134##########################################################################################
135# Unpack source packages
136
137# Generate downloading + unpacking of sources.
138define Download
139  $(1)_DIR = $(abspath $(SRCDIR)/$(basename $(basename $(notdir $($(1))))))
140  $(1)_CFG = $$($(1)_DIR)/configure
141  $(1)_FILE = $(DOWNLOAD)/$(notdir $($(1)))
142
143  $$($(1)_CFG) : $$($(1)_FILE)
144	mkdir -p $$(SRCDIR)
145	tar -C $$(SRCDIR) -x$$(if $$(findstring .gz, $$<),z,j)f $$<
146	$$(foreach p,$$(abspath $$(wildcard $$(notdir $$($(1)_DIR)).patch)), \
147	  echo PATCHING $$(p) ; \
148	  patch -d $$($(1)_DIR) -p1 -i $$(p) ; \
149	)
150	touch $$@
151
152  $$($(1)_FILE) :
153	wget -P $(DOWNLOAD) $$($(1))
154endef
155
156# Download and unpack all source packages
157$(foreach p,GCC BINUTILS CCACHE MPFR GMP MPC,$(eval $(call Download,$(p))))
158
159##########################################################################################
160# Unpack RPMS
161
162# Note. For building linux you should install rpm2cpio.
163define unrpm
164  $(SYSROOT)/$(notdir $(1)).unpacked \
165    : $(1)
166  $$(rpms) : $(SYSROOT)/$(notdir $(1)).unpacked
167endef
168
169%.unpacked :
170	$(info Unpacking target rpms and libraries from $<)
171	@(mkdir -p $(@D); \
172	cd $(@D); \
173	rpm2cpio $< | \
174	    cpio --extract --make-directories \
175	        -f \
176	        "./usr/share/doc/*" \
177	        "./usr/share/man/*" \
178	        "./usr/X11R6/man/*" \
179	        "*/X11/locale/*" \
180	    || die ; )
181	touch $@
182
183$(foreach p,$(RPM_FILE_LIST),$(eval $(call unrpm,$(p))))
184
185##########################################################################################
186
187# Note: MUST create a <sys-root>/usr/lib even if not really needed.
188# gcc will use a path relative to it to resolve lib64. (x86_64).
189# we're creating multi-lib compiler with 32bit libc as well, so we should
190# have it anyway, but just to make sure...
191# Patch libc.so and libpthread.so to force linking against libraries in sysroot
192# and not the ones installed on the build machine.
193$(libs) : $(rpms)
194	@echo Patching libc and pthreads
195	@(for f in `find $(SYSROOT) -name libc.so -o -name libpthread.so`; do \
196	  (cat $$f | sed -e 's|/usr/lib64/||g' \
197	      -e 's|/usr/lib/||g' \
198	      -e 's|/lib64/||g' \
199	      -e 's|/lib/||g' ) > $$f.tmp ; \
200	  mv $$f.tmp $$f ; \
201	done)
202	@mkdir -p $(SYSROOT)/usr/lib
203	@touch $@
204
205##########################################################################################
206
207# Define marker files for each source package to be compiled
208$(foreach t,binutils mpfr gmp mpc gcc ccache,$(eval $(t) = $(TARGETDIR)/$($(t)_ver).done))
209
210##########################################################################################
211
212# Default base config
213CONFIG = --target=$(TARGET) \
214    --host=$(HOST) --build=$(BUILD) \
215    --prefix=$(PREFIX)
216
217PATHEXT = $(RESULT)/$(BUILD)/bin:
218
219PATHPRE = PATH=$(PATHEXT)$(PATH)
220BUILDPAR = -j16
221
222# Default commands to when making
223MAKECMD =
224INSTALLCMD = install
225
226
227declare_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
228
229ifeq ($(HOST),$(BUILD))
230  ifeq ($(HOST),$(TARGET))
231    TOOLS = $(call declare_tools,_FOR_TARGET,)
232  endif
233endif
234
235TOOLS ?= $(call declare_tools,_FOR_TARGET,$(TARGET)-)
236
237##########################################################################################
238
239# Create a TARGET bfd + libiberty only.
240# Configure one or two times depending on mulitlib arch.
241# If multilib, the second should be 32-bit, and we resolve
242# CFLAG_<name> to most likely -m32.
243define mk_bfd
244  $$(info Libs for $(1))
245  $$(BUILDDIR)/$$(binutils_ver)-$(subst /,-,$(1))/Makefile \
246      : CFLAGS += $$(CFLAGS_$(1))
247  $$(BUILDDIR)/$$(binutils_ver)-$(subst /,-,$(1))/Makefile \
248      : LIBDIRS = --libdir=$(TARGETDIR)/$(1)
249
250  bfdlib += $$(TARGETDIR)/$$(binutils_ver)-$(subst /,-,$(1)).done
251  bfdmakes += $$(BUILDDIR)/$$(binutils_ver)-$(subst /,-,$(1))/Makefile
252endef
253
254# Create one set of bfds etc for each multilib arch
255$(foreach l,$(LIBDIRS),$(eval $(call mk_bfd,$(l))))
256
257# Only build these two libs.
258$(bfdlib) : MAKECMD = all-libiberty all-bfd
259$(bfdlib) : INSTALLCMD = install-libiberty install-bfd
260
261# Building targets libbfd + libiberty. HOST==TARGET, i.e not
262# for a cross env.
263$(bfdmakes) : CONFIG = --target=$(TARGET) \
264    --host=$(TARGET) --build=$(BUILD) \
265    --prefix=$(TARGETDIR) \
266    --with-sysroot=$(SYSROOT) \
267    $(LIBDIRS)
268
269$(bfdmakes) : TOOLS = $(call declare_tools,_FOR_TARGET,$(TARGET)-) $(call declare_tools,,$(TARGET)-)
270
271##########################################################################################
272
273$(gcc) \
274    $(binutils) \
275    $(gmp) \
276    $(mpfr) \
277    $(mpc) \
278    $(bfdmakes) \
279    $(ccache) : ENVS += $(TOOLS)
280
281# libdir to work around hateful bfd stuff installing into wrong dirs...
282# ensure we have 64 bit bfd support in the HOST library. I.e our
283# compiler on i686 will know 64 bit symbols, BUT later
284# we build just the libs again for TARGET, then with whatever the arch
285# wants.
286$(BUILDDIR)/$(binutils_ver)/Makefile : CONFIG += --enable-64-bit-bfd --libdir=$(PREFIX)/$(word 1,$(LIBDIRS))
287
288# Makefile creation. Simply run configure in build dir.
289$(bfdmakes) \
290$(BUILDDIR)/$(binutils_ver)/Makefile \
291    : $(BINUTILS_CFG)
292	$(info Configuring $@. Log in $(@D)/log.config)
293	@mkdir -p $(@D)
294	( \
295	  cd $(@D) ; \
296	  $(PATHPRE) $(ENVS) CFLAGS="$(CFLAGS)" \
297	      $(BINUTILS_CFG) \
298	      $(CONFIG) \
299	      --with-sysroot=$(SYSROOT) \
300	      --disable-nls \
301	      --program-prefix=$(TARGET)- \
302	      --enable-multilib \
303	) > $(@D)/log.config 2>&1
304	@echo 'done'
305
306$(BUILDDIR)/$(mpfr_ver)/Makefile \
307    : $(MPFR_CFG)
308	$(info Configuring $@. Log in $(@D)/log.config)
309	@mkdir -p $(@D)
310	( \
311	  cd $(@D) ; \
312	  $(PATHPRE) $(ENVS) CFLAGS="$(CFLAGS)" \
313	      $(MPFR_CFG) \
314	      $(CONFIG) \
315	      --program-prefix=$(TARGET)- \
316	      --enable-shared=no \
317	      --with-gmp=$(PREFIX) \
318	) > $(@D)/log.config 2>&1
319	@echo 'done'
320
321$(BUILDDIR)/$(gmp_ver)/Makefile \
322    : $(GMP_CFG)
323	$(info Configuring $@. Log in $(@D)/log.config)
324	@mkdir -p $(@D)
325	( \
326	  cd $(@D) ; \
327	  $(PATHPRE) $(ENVS) CFLAGS="$(CFLAGS)" \
328	      $(GMP_CFG) \
329	      --host=$(HOST) --build=$(BUILD) \
330	      --prefix=$(PREFIX) \
331	      --disable-nls \
332	      --program-prefix=$(TARGET)- \
333	      --enable-shared=no \
334	      --with-mpfr=$(PREFIX) \
335	) > $(@D)/log.config 2>&1
336	@echo 'done'
337
338$(BUILDDIR)/$(mpc_ver)/Makefile \
339    : $(MPC_CFG)
340	$(info Configuring $@. Log in $(@D)/log.config)
341	@mkdir -p $(@D)
342	( \
343	  cd $(@D) ; \
344	  $(PATHPRE) $(ENVS) CFLAGS="$(CFLAGS)" \
345	      $(MPC_CFG) \
346	      $(CONFIG) \
347	      --program-prefix=$(TARGET)- \
348	      --enable-shared=no \
349	      --with-mpfr=$(PREFIX) \
350	      --with-gmp=$(PREFIX) \
351	) > $(@D)/log.config 2>&1
352	@echo 'done'
353
354# Only valid if glibc target -> linux
355# proper destructor handling for c++
356ifneq (,$(findstring linux,$(TARGET)))
357  $(BUILDDIR)/$(gcc_ver)/Makefile : CONFIG += --enable-__cxa_atexit
358endif
359
360# Want:
361# c,c++
362# shared libs
363# multilib (-m32/-m64 on x64)
364# skip native language.
365# and link and assemble with the binutils we created
366# earlier, so --with-gnu*
367$(BUILDDIR)/$(gcc_ver)/Makefile \
368    : $(GCC_CFG)
369	$(info Configuring $@. Log in $(@D)/log.config)
370	mkdir -p $(@D)
371	( \
372	  cd $(@D) ; \
373	  $(PATHPRE) $(ENVS) $(GCC_CFG) $(EXTRA_CFLAGS) \
374	      $(CONFIG) \
375	      --with-sysroot=$(SYSROOT) \
376	      --enable-languages=c,c++ \
377	      --enable-shared \
378	      --enable-multilib \
379	      --disable-nls \
380	      --with-gnu-as \
381	      --with-gnu-ld \
382	      --with-mpfr=$(PREFIX) \
383	      --with-gmp=$(PREFIX) \
384	      --with-mpc=$(PREFIX) \
385	) > $(@D)/log.config 2>&1
386	@echo 'done'
387
388# need binutils for gcc
389$(gcc) : $(binutils)
390
391# as of 4.3 or so need these for doing config
392$(BUILDDIR)/$(gcc_ver)/Makefile : $(gmp) $(mpfr) $(mpc)
393$(mpfr) : $(gmp)
394$(mpc) : $(gmp) $(mpfr)
395
396##########################################################################################
397# very straightforward. just build a ccache. it is only for host.
398$(BUILDDIR)/$(ccache_ver)/Makefile \
399    : $(CCACHE_CFG)
400	$(info Configuring $@. Log in $(@D)/log.config)
401	@mkdir -p $(@D)
402	@( \
403	  cd $(@D) ; \
404	  $(PATHPRE) $(ENVS) $(CCACHE_CFG) \
405	      $(CONFIG) \
406	) > $(@D)/log.config 2>&1
407	@echo 'done'
408
409gccpatch = $(TARGETDIR)/gcc-patched
410
411##########################################################################################
412# For some reason cpp is not created as a target-compiler
413ifeq ($(HOST),$(TARGET))
414  $(gccpatch) : $(gcc) link_libs
415	@echo -n 'Creating compiler symlinks...'
416	@for f in cpp; do \
417	  if [ ! -e $(PREFIX)/bin/$(TARGET)-$$f ]; \
418	  then \
419	    cd $(PREFIX)/bin && \
420	    ln -s $$f $(TARGET)-$$f ; \
421	  fi \
422	done
423	@touch $@
424	@echo 'done'
425
426  ##########################################################################################
427  # Ugly at best. Seems that when we compile host->host compiler, that are NOT
428  # the BUILD compiler, the result will not try searching for libs in package root.
429  # "Solve" this by create links from the target libdirs to where they are.
430  link_libs:
431	@echo -n 'Creating library symlinks...'
432	@$(foreach l,$(LIBDIRS), \
433	for f in `cd $(PREFIX)/$(l) && ls`; do \
434	  if [ ! -e $(TARGETDIR)/$(l)/$$f ]; then \
435	    mkdir -p $(TARGETDIR)/$(l) && \
436	    cd $(TARGETDIR)/$(l)/ && \
437	    ln -s $(if $(findstring /,$(l)),../,)../../$(l)/$$f $$f; \
438	  fi \
439	done;)
440	@echo 'done'
441else
442  $(gccpatch) :
443	@echo 'done'
444endif
445
446##########################################################################################
447# Build in two steps.
448# make <default>
449# make install.
450# Use path to our build hosts cross tools
451# Always need to build cross tools for build host self.
452$(TARGETDIR)/%.done : $(BUILDDIR)/%/Makefile
453	$(info Building $(basename $@). Log in $(<D)/log.build)
454	$(PATHPRE) $(ENVS) $(MAKE) $(BUILDPAR) -f $< -C $(<D) $(MAKECMD) $(MAKECMD.$(notdir $@)) > $(<D)/log.build 2>&1
455	@echo -n 'installing...'
456	$(PATHPRE) $(MAKE) $(INSTALLPAR) -f $< -C $(<D) $(INSTALLCMD) $(MAKECMD.$(notdir $@)) > $(<D)/log.install 2>&1
457	@touch $@
458	@echo 'done'
459
460##########################################################################################
461
462bfdlib : $(bfdlib)
463binutils : $(binutils)
464rpms : $(rpms)
465libs : $(libs)
466sysroot : rpms libs
467gcc : sysroot $(gcc) $(gccpatch)
468all : binutils gcc bfdlib
469
470# this is only built for host. so separate.
471ccache : $(ccache)
472
473.PHONY : gcc all binutils bfdlib link_libs rpms libs sysroot
474