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