aoqi@0: # aoqi@0: # Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. aoqi@0: # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. aoqi@0: # aoqi@0: # This code is free software; you can redistribute it and/or modify it aoqi@0: # under the terms of the GNU General Public License version 2 only, as aoqi@0: # published by the Free Software Foundation. Oracle designates this aoqi@0: # particular file as subject to the "Classpath" exception as provided aoqi@0: # by Oracle in the LICENSE file that accompanied this code. aoqi@0: # aoqi@0: # This code is distributed in the hope that it will be useful, but WITHOUT aoqi@0: # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or aoqi@0: # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License aoqi@0: # version 2 for more details (a copy is included in the LICENSE file that aoqi@0: # accompanied this code). aoqi@0: # aoqi@0: # You should have received a copy of the GNU General Public License version aoqi@0: # 2 along with this work; if not, write to the Free Software Foundation, aoqi@0: # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. aoqi@0: # aoqi@0: # Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA aoqi@0: # or visit www.oracle.com if you need additional information or have any aoqi@0: # questions. aoqi@0: # aoqi@0: aoqi@0: ########################################################################################## aoqi@0: # aoqi@0: # Workhorse makefile for creating ONE cross compiler aoqi@0: # Needs either to be from BUILD -> BUILD OR have aoqi@0: # BUILD -> HOST prebuilt aoqi@0: # aoqi@0: # NOTE: There is a bug here. We don't limit the aoqi@0: # PATH when building BUILD -> BUILD, which means that aoqi@0: # if you configure after you've once build the BUILD->BUILD aoqi@0: # compiler THAT one will be picked up as the compiler for itself. aoqi@0: # This is not so great, especially if you did a partial delete aoqi@0: # of the target tree. aoqi@0: # aoqi@0: # Fix this... aoqi@0: # aoqi@0: aoqi@0: $(info TARGET=$(TARGET)) aoqi@0: $(info HOST=$(HOST)) aoqi@0: $(info BUILD=$(BUILD)) aoqi@0: aoqi@0: ARCH := $(word 1,$(subst -, ,$(TARGET))) aoqi@0: aoqi@0: ########################################################################################## aoqi@0: # Define external dependencies aoqi@0: aoqi@0: # Latest that could be made to work. aoqi@0: gcc_ver := gcc-4.7.3 aoqi@0: binutils_ver := binutils-2.22 aoqi@0: ccache_ver := ccache-3.1.9 aoqi@0: mpfr_ver := mpfr-3.0.1 aoqi@0: gmp_ver := gmp-4.3.2 aoqi@0: mpc_ver := mpc-1.0.1 aoqi@0: aoqi@0: GCC := http://ftp.gnu.org/pub/gnu/gcc/$(gcc_ver)/$(gcc_ver).tar.bz2 aoqi@0: BINUTILS := http://ftp.gnu.org/pub/gnu/binutils/$(binutils_ver).tar.bz2 aoqi@0: CCACHE := http://samba.org/ftp/ccache/$(ccache_ver).tar.gz aoqi@0: MPFR := http://www.mpfr.org/${mpfr_ver}/${mpfr_ver}.tar.bz2 aoqi@0: GMP := http://ftp.gnu.org/pub/gnu/gmp/${gmp_ver}.tar.bz2 aoqi@0: MPC := http://www.multiprecision.org/mpc/download/${mpc_ver}.tar.gz aoqi@0: aoqi@0: # RPMs in OEL5.5 aoqi@0: RPM_LIST := \ aoqi@0: kernel-headers \ aoqi@0: glibc-2 glibc-headers glibc-devel \ aoqi@0: cups-libs cups-devel \ aoqi@0: libX11 libX11-devel \ aoqi@0: xorg-x11-proto-devel \ aoqi@0: alsa-lib alsa-lib-devel \ aoqi@0: libXext libXext-devel \ aoqi@0: libXtst libXtst-devel \ aoqi@0: libXrender libXrender-devel \ aoqi@0: freetype freetype-devel \ aoqi@0: libXt libXt-devel \ aoqi@0: libSM libSM-devel \ aoqi@0: libICE libICE-devel \ aoqi@0: libXi libXi-devel \ aoqi@0: libXdmcp libXdmcp-devel \ aoqi@0: libXau libXau-devel \ aoqi@0: libgcc aoqi@0: aoqi@0: aoqi@0: ifeq ($(ARCH),x86_64) aoqi@0: RPM_DIR ?= $(RPM_DIR_x86_64) aoqi@0: RPM_ARCHS := x86_64 aoqi@0: ifeq ($(BUILD),$(HOST)) aoqi@0: ifeq ($(TARGET),$(HOST)) aoqi@0: # When building the native compiler for x86_64, enable mixed mode. aoqi@0: RPM_ARCHS += i386 i686 aoqi@0: endif aoqi@0: endif aoqi@0: else aoqi@0: RPM_DIR ?= $(RPM_DIR_i686) aoqi@0: RPM_ARCHS := i386 i686 aoqi@0: endif aoqi@0: aoqi@0: # Sort to remove duplicates aoqi@0: RPM_FILE_LIST := $(sort $(foreach a,$(RPM_ARCHS),$(wildcard $(patsubst %,$(RPM_DIR)/%*$a.rpm,$(RPM_LIST))))) aoqi@0: aoqi@0: ifeq ($(RPM_FILE_LIST),) aoqi@0: $(error Found no RPMs, RPM_DIR must point to list of directories to search for RPMs) aoqi@0: endif aoqi@0: aoqi@0: ########################################################################################## aoqi@0: # Define common directories and files aoqi@0: aoqi@0: # Ensure we have 32-bit libs also for x64. We enable mixed-mode. aoqi@0: ifeq (x86_64,$(ARCH)) aoqi@0: LIBDIRS := lib64 lib aoqi@0: CFLAGS_lib := -m32 aoqi@0: else aoqi@0: LIBDIRS := lib aoqi@0: endif aoqi@0: aoqi@0: # Define directories aoqi@0: RESULT := $(OUTPUT_ROOT)/result aoqi@0: BUILDDIR := $(OUTPUT_ROOT)/$(HOST)/$(TARGET) aoqi@0: PREFIX := $(RESULT)/$(HOST) aoqi@0: TARGETDIR := $(PREFIX)/$(TARGET) aoqi@0: SYSROOT := $(TARGETDIR)/sys-root aoqi@0: DOWNLOAD := $(OUTPUT_ROOT)/download aoqi@0: SRCDIR := $(OUTPUT_ROOT)/src aoqi@0: aoqi@0: # Marker file for unpacking rpms aoqi@0: rpms := $(SYSROOT)/rpms_unpacked aoqi@0: aoqi@0: # Need to patch libs that are linker scripts to use non-absolute paths aoqi@0: libs := $(SYSROOT)/libs_patched aoqi@0: aoqi@0: ########################################################################################## aoqi@0: # Unpack source packages aoqi@0: aoqi@0: # Generate downloading + unpacking of sources. aoqi@0: define Download aoqi@0: $(1)_DIR = $(abspath $(SRCDIR)/$(basename $(basename $(notdir $($(1)))))) aoqi@0: $(1)_CFG = $$($(1)_DIR)/configure aoqi@0: $(1)_FILE = $(DOWNLOAD)/$(notdir $($(1))) aoqi@0: aoqi@0: $$($(1)_CFG) : $$($(1)_FILE) aoqi@0: mkdir -p $$(SRCDIR) aoqi@0: tar -C $$(SRCDIR) -x$$(if $$(findstring .gz, $$<),z,j)f $$< aoqi@0: $$(foreach p,$$(abspath $$(wildcard $$(notdir $$($(1)_DIR)).patch)), \ aoqi@0: echo PATCHING $$(p) ; \ aoqi@0: patch -d $$($(1)_DIR) -p1 -i $$(p) ; \ aoqi@0: ) aoqi@0: touch $$@ aoqi@0: aoqi@0: $$($(1)_FILE) : aoqi@0: wget -P $(DOWNLOAD) $$($(1)) aoqi@0: endef aoqi@0: aoqi@0: # Download and unpack all source packages aoqi@0: $(foreach p,GCC BINUTILS CCACHE MPFR GMP MPC,$(eval $(call Download,$(p)))) aoqi@0: aoqi@0: ########################################################################################## aoqi@0: # Unpack RPMS aoqi@0: aoqi@0: # Note. For building linux you should install rpm2cpio. aoqi@0: define unrpm aoqi@0: $(SYSROOT)/$(notdir $(1)).unpacked \ aoqi@0: : $(1) aoqi@0: $$(rpms) : $(SYSROOT)/$(notdir $(1)).unpacked aoqi@0: endef aoqi@0: aoqi@0: %.unpacked : aoqi@0: $(info Unpacking target rpms and libraries from $<) aoqi@0: @(mkdir -p $(@D); \ aoqi@0: cd $(@D); \ aoqi@0: rpm2cpio $< | \ aoqi@0: cpio --extract --make-directories \ aoqi@0: -f \ aoqi@0: "./usr/share/doc/*" \ aoqi@0: "./usr/share/man/*" \ aoqi@0: "./usr/X11R6/man/*" \ aoqi@0: "*/X11/locale/*" \ aoqi@0: || die ; ) aoqi@0: touch $@ aoqi@0: aoqi@0: $(foreach p,$(RPM_FILE_LIST),$(eval $(call unrpm,$(p)))) aoqi@0: aoqi@0: ########################################################################################## aoqi@0: aoqi@0: # Note: MUST create a /usr/lib even if not really needed. aoqi@0: # gcc will use a path relative to it to resolve lib64. (x86_64). aoqi@0: # we're creating multi-lib compiler with 32bit libc as well, so we should aoqi@0: # have it anyway, but just to make sure... aoqi@0: # Patch libc.so and libpthread.so to force linking against libraries in sysroot aoqi@0: # and not the ones installed on the build machine. aoqi@0: $(libs) : $(rpms) aoqi@0: @echo Patching libc and pthreads aoqi@0: @(for f in `find $(SYSROOT) -name libc.so -o -name libpthread.so`; do \ aoqi@0: (cat $$f | sed -e 's|/usr/lib64/||g' \ aoqi@0: -e 's|/usr/lib/||g' \ aoqi@0: -e 's|/lib64/||g' \ aoqi@0: -e 's|/lib/||g' ) > $$f.tmp ; \ aoqi@0: mv $$f.tmp $$f ; \ aoqi@0: done) aoqi@0: @mkdir -p $(SYSROOT)/usr/lib aoqi@0: @touch $@ aoqi@0: aoqi@0: ########################################################################################## aoqi@0: aoqi@0: # Define marker files for each source package to be compiled aoqi@0: $(foreach t,binutils mpfr gmp mpc gcc ccache,$(eval $(t) = $(TARGETDIR)/$($(t)_ver).done)) aoqi@0: aoqi@0: ########################################################################################## aoqi@0: aoqi@0: # Default base config aoqi@0: CONFIG = --target=$(TARGET) \ aoqi@0: --host=$(HOST) --build=$(BUILD) \ aoqi@0: --prefix=$(PREFIX) aoqi@0: aoqi@0: PATHEXT = $(RESULT)/$(BUILD)/bin: aoqi@0: aoqi@0: PATHPRE = PATH=$(PATHEXT)$(PATH) aoqi@0: BUILDPAR = -j16 aoqi@0: aoqi@0: # Default commands to when making aoqi@0: MAKECMD = aoqi@0: INSTALLCMD = install aoqi@0: aoqi@0: aoqi@0: declare_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 aoqi@0: aoqi@0: ifeq ($(HOST),$(BUILD)) aoqi@0: ifeq ($(HOST),$(TARGET)) aoqi@0: TOOLS = $(call declare_tools,_FOR_TARGET,) aoqi@0: endif aoqi@0: endif aoqi@0: aoqi@0: TOOLS ?= $(call declare_tools,_FOR_TARGET,$(TARGET)-) aoqi@0: aoqi@0: ########################################################################################## aoqi@0: aoqi@0: # Create a TARGET bfd + libiberty only. aoqi@0: # Configure one or two times depending on mulitlib arch. aoqi@0: # If multilib, the second should be 32-bit, and we resolve aoqi@0: # CFLAG_ to most likely -m32. aoqi@0: define mk_bfd aoqi@0: $$(info Libs for $(1)) aoqi@0: $$(BUILDDIR)/$$(binutils_ver)-$(subst /,-,$(1))/Makefile \ aoqi@0: : CFLAGS += $$(CFLAGS_$(1)) aoqi@0: $$(BUILDDIR)/$$(binutils_ver)-$(subst /,-,$(1))/Makefile \ aoqi@0: : LIBDIRS = --libdir=$(TARGETDIR)/$(1) aoqi@0: aoqi@0: bfdlib += $$(TARGETDIR)/$$(binutils_ver)-$(subst /,-,$(1)).done aoqi@0: bfdmakes += $$(BUILDDIR)/$$(binutils_ver)-$(subst /,-,$(1))/Makefile aoqi@0: endef aoqi@0: aoqi@0: # Create one set of bfds etc for each multilib arch aoqi@0: $(foreach l,$(LIBDIRS),$(eval $(call mk_bfd,$(l)))) aoqi@0: aoqi@0: # Only build these two libs. aoqi@0: $(bfdlib) : MAKECMD = all-libiberty all-bfd aoqi@0: $(bfdlib) : INSTALLCMD = install-libiberty install-bfd aoqi@0: aoqi@0: # Building targets libbfd + libiberty. HOST==TARGET, i.e not aoqi@0: # for a cross env. aoqi@0: $(bfdmakes) : CONFIG = --target=$(TARGET) \ aoqi@0: --host=$(TARGET) --build=$(BUILD) \ aoqi@0: --prefix=$(TARGETDIR) \ aoqi@0: --with-sysroot=$(SYSROOT) \ aoqi@0: $(LIBDIRS) aoqi@0: aoqi@0: $(bfdmakes) : TOOLS = $(call declare_tools,_FOR_TARGET,$(TARGET)-) $(call declare_tools,,$(TARGET)-) aoqi@0: aoqi@0: ########################################################################################## aoqi@0: aoqi@0: $(gcc) \ aoqi@0: $(binutils) \ aoqi@0: $(gmp) \ aoqi@0: $(mpfr) \ aoqi@0: $(mpc) \ aoqi@0: $(bfdmakes) \ aoqi@0: $(ccache) : ENVS += $(TOOLS) aoqi@0: aoqi@0: # libdir to work around hateful bfd stuff installing into wrong dirs... aoqi@0: # ensure we have 64 bit bfd support in the HOST library. I.e our aoqi@0: # compiler on i686 will know 64 bit symbols, BUT later aoqi@0: # we build just the libs again for TARGET, then with whatever the arch aoqi@0: # wants. aoqi@0: $(BUILDDIR)/$(binutils_ver)/Makefile : CONFIG += --enable-64-bit-bfd --libdir=$(PREFIX)/$(word 1,$(LIBDIRS)) aoqi@0: aoqi@0: # Makefile creation. Simply run configure in build dir. aoqi@0: $(bfdmakes) \ aoqi@0: $(BUILDDIR)/$(binutils_ver)/Makefile \ aoqi@0: : $(BINUTILS_CFG) aoqi@0: $(info Configuring $@. Log in $(@D)/log.config) aoqi@0: @mkdir -p $(@D) aoqi@0: ( \ aoqi@0: cd $(@D) ; \ aoqi@0: $(PATHPRE) $(ENVS) CFLAGS="$(CFLAGS)" \ aoqi@0: $(BINUTILS_CFG) \ aoqi@0: $(CONFIG) \ aoqi@0: --with-sysroot=$(SYSROOT) \ aoqi@0: --disable-nls \ aoqi@0: --program-prefix=$(TARGET)- \ aoqi@0: --enable-multilib \ aoqi@0: ) > $(@D)/log.config 2>&1 aoqi@0: @echo 'done' aoqi@0: aoqi@0: $(BUILDDIR)/$(mpfr_ver)/Makefile \ aoqi@0: : $(MPFR_CFG) aoqi@0: $(info Configuring $@. Log in $(@D)/log.config) aoqi@0: @mkdir -p $(@D) aoqi@0: ( \ aoqi@0: cd $(@D) ; \ aoqi@0: $(PATHPRE) $(ENVS) CFLAGS="$(CFLAGS)" \ aoqi@0: $(MPFR_CFG) \ aoqi@0: $(CONFIG) \ aoqi@0: --program-prefix=$(TARGET)- \ aoqi@0: --enable-shared=no \ aoqi@0: --with-gmp=$(PREFIX) \ aoqi@0: ) > $(@D)/log.config 2>&1 aoqi@0: @echo 'done' aoqi@0: aoqi@0: $(BUILDDIR)/$(gmp_ver)/Makefile \ aoqi@0: : $(GMP_CFG) aoqi@0: $(info Configuring $@. Log in $(@D)/log.config) aoqi@0: @mkdir -p $(@D) aoqi@0: ( \ aoqi@0: cd $(@D) ; \ aoqi@0: $(PATHPRE) $(ENVS) CFLAGS="$(CFLAGS)" \ aoqi@0: $(GMP_CFG) \ aoqi@0: --host=$(HOST) --build=$(BUILD) \ aoqi@0: --prefix=$(PREFIX) \ aoqi@0: --disable-nls \ aoqi@0: --program-prefix=$(TARGET)- \ aoqi@0: --enable-shared=no \ aoqi@0: --with-mpfr=$(PREFIX) \ aoqi@0: ) > $(@D)/log.config 2>&1 aoqi@0: @echo 'done' aoqi@0: aoqi@0: $(BUILDDIR)/$(mpc_ver)/Makefile \ aoqi@0: : $(MPC_CFG) aoqi@0: $(info Configuring $@. Log in $(@D)/log.config) aoqi@0: @mkdir -p $(@D) aoqi@0: ( \ aoqi@0: cd $(@D) ; \ aoqi@0: $(PATHPRE) $(ENVS) CFLAGS="$(CFLAGS)" \ aoqi@0: $(MPC_CFG) \ aoqi@0: $(CONFIG) \ aoqi@0: --program-prefix=$(TARGET)- \ aoqi@0: --enable-shared=no \ aoqi@0: --with-mpfr=$(PREFIX) \ aoqi@0: --with-gmp=$(PREFIX) \ aoqi@0: ) > $(@D)/log.config 2>&1 aoqi@0: @echo 'done' aoqi@0: aoqi@0: # Only valid if glibc target -> linux aoqi@0: # proper destructor handling for c++ aoqi@0: ifneq (,$(findstring linux,$(TARGET))) aoqi@0: $(BUILDDIR)/$(gcc_ver)/Makefile : CONFIG += --enable-__cxa_atexit aoqi@0: endif aoqi@0: aoqi@0: # Want: aoqi@0: # c,c++ aoqi@0: # shared libs aoqi@0: # multilib (-m32/-m64 on x64) aoqi@0: # skip native language. aoqi@0: # and link and assemble with the binutils we created aoqi@0: # earlier, so --with-gnu* aoqi@0: $(BUILDDIR)/$(gcc_ver)/Makefile \ aoqi@0: : $(GCC_CFG) aoqi@0: $(info Configuring $@. Log in $(@D)/log.config) aoqi@0: mkdir -p $(@D) aoqi@0: ( \ aoqi@0: cd $(@D) ; \ aoqi@0: $(PATHPRE) $(ENVS) $(GCC_CFG) $(EXTRA_CFLAGS) \ aoqi@0: $(CONFIG) \ aoqi@0: --with-sysroot=$(SYSROOT) \ aoqi@0: --enable-languages=c,c++ \ aoqi@0: --enable-shared \ aoqi@0: --enable-multilib \ aoqi@0: --disable-nls \ aoqi@0: --with-gnu-as \ aoqi@0: --with-gnu-ld \ aoqi@0: --with-mpfr=$(PREFIX) \ aoqi@0: --with-gmp=$(PREFIX) \ aoqi@0: --with-mpc=$(PREFIX) \ aoqi@0: ) > $(@D)/log.config 2>&1 aoqi@0: @echo 'done' aoqi@0: aoqi@0: # need binutils for gcc aoqi@0: $(gcc) : $(binutils) aoqi@0: aoqi@0: # as of 4.3 or so need these for doing config aoqi@0: $(BUILDDIR)/$(gcc_ver)/Makefile : $(gmp) $(mpfr) $(mpc) aoqi@0: $(mpfr) : $(gmp) aoqi@0: $(mpc) : $(gmp) $(mpfr) aoqi@0: aoqi@0: ########################################################################################## aoqi@0: # very straightforward. just build a ccache. it is only for host. aoqi@0: $(BUILDDIR)/$(ccache_ver)/Makefile \ aoqi@0: : $(CCACHE_CFG) aoqi@0: $(info Configuring $@. Log in $(@D)/log.config) aoqi@0: @mkdir -p $(@D) aoqi@0: @( \ aoqi@0: cd $(@D) ; \ aoqi@0: $(PATHPRE) $(ENVS) $(CCACHE_CFG) \ aoqi@0: $(CONFIG) \ aoqi@0: ) > $(@D)/log.config 2>&1 aoqi@0: @echo 'done' aoqi@0: aoqi@0: gccpatch = $(TARGETDIR)/gcc-patched aoqi@0: aoqi@0: ########################################################################################## aoqi@0: # For some reason cpp is not created as a target-compiler aoqi@0: ifeq ($(HOST),$(TARGET)) aoqi@0: $(gccpatch) : $(gcc) link_libs aoqi@0: @echo -n 'Creating compiler symlinks...' aoqi@0: @for f in cpp; do \ aoqi@0: if [ ! -e $(PREFIX)/bin/$(TARGET)-$$f ]; \ aoqi@0: then \ aoqi@0: cd $(PREFIX)/bin && \ aoqi@0: ln -s $$f $(TARGET)-$$f ; \ aoqi@0: fi \ aoqi@0: done aoqi@0: @touch $@ aoqi@0: @echo 'done' aoqi@0: aoqi@0: ########################################################################################## aoqi@0: # Ugly at best. Seems that when we compile host->host compiler, that are NOT aoqi@0: # the BUILD compiler, the result will not try searching for libs in package root. aoqi@0: # "Solve" this by create links from the target libdirs to where they are. aoqi@0: link_libs: aoqi@0: @echo -n 'Creating library symlinks...' aoqi@0: @$(foreach l,$(LIBDIRS), \ aoqi@0: for f in `cd $(PREFIX)/$(l) && ls`; do \ aoqi@0: if [ ! -e $(TARGETDIR)/$(l)/$$f ]; then \ aoqi@0: mkdir -p $(TARGETDIR)/$(l) && \ aoqi@0: cd $(TARGETDIR)/$(l)/ && \ aoqi@0: ln -s $(if $(findstring /,$(l)),../,)../../$(l)/$$f $$f; \ aoqi@0: fi \ aoqi@0: done;) aoqi@0: @echo 'done' aoqi@0: else aoqi@0: $(gccpatch) : aoqi@0: @echo 'done' aoqi@0: endif aoqi@0: aoqi@0: ########################################################################################## aoqi@0: # Build in two steps. aoqi@0: # make aoqi@0: # make install. aoqi@0: # Use path to our build hosts cross tools aoqi@0: # Always need to build cross tools for build host self. aoqi@0: $(TARGETDIR)/%.done : $(BUILDDIR)/%/Makefile aoqi@0: $(info Building $(basename $@). Log in $( $(&1 aoqi@0: @echo -n 'installing...' aoqi@0: $(PATHPRE) $(MAKE) $(INSTALLPAR) -f $< -C $( $(&1 aoqi@0: @touch $@ aoqi@0: @echo 'done' aoqi@0: aoqi@0: ########################################################################################## aoqi@0: aoqi@0: bfdlib : $(bfdlib) aoqi@0: binutils : $(binutils) aoqi@0: rpms : $(rpms) aoqi@0: libs : $(libs) aoqi@0: sysroot : rpms libs aoqi@0: gcc : sysroot $(gcc) $(gccpatch) aoqi@0: all : binutils gcc bfdlib aoqi@0: aoqi@0: # this is only built for host. so separate. aoqi@0: ccache : $(ccache) aoqi@0: aoqi@0: .PHONY : gcc all binutils bfdlib link_libs rpms libs sysroot