Tools.gmk revision 1972:905405fcc3b4
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-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