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