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 
  46 ARCH := $(word 1,$(subst -, ,$(TARGET)))
  47 
  48 ##########################################################################################
  49 # Define external dependencies
  50 
  51 # Latest that could be made to work.
  52 gcc_ver := gcc-4.9.2
  53 binutils_ver := binutils-2.25
  54 ccache_ver := ccache-3.2.1
  55 mpfr_ver := mpfr-3.0.1
  56 gmp_ver := gmp-4.3.2
  57 mpc_ver := mpc-1.0.1
  58 
  59 GCC := http://ftp.gnu.org/pub/gnu/gcc/$(gcc_ver)/$(gcc_ver).tar.bz2
  60 BINUTILS := http://ftp.gnu.org/pub/gnu/binutils/$(binutils_ver).tar.bz2
  61 CCACHE := http://samba.org/ftp/ccache/$(ccache_ver).tar.gz
  62 MPFR := http://www.mpfr.org/${mpfr_ver}/${mpfr_ver}.tar.bz2
  63 GMP := http://ftp.gnu.org/pub/gnu/gmp/${gmp_ver}.tar.bz2
  64 MPC := http://www.multiprecision.org/mpc/download/${mpc_ver}.tar.gz
  65 
  66 # RPMs in OEL6.4
  67 LINUX_VERSION := OEL6.4
  68 RPM_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 
  89 ifeq ($(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
  98 else
  99   RPM_DIR ?= $(RPM_DIR_i686)
 100   RPM_ARCHS := i386 i686
 101 endif
 102 
 103 # Sort to remove duplicates
 104 RPM_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 
 108 ifeq ($(RPM_FILE_LIST),)
 109   $(error Found no RPMs, RPM_DIR must point to list of directories to search for RPMs)
 110 endif
 111 
 112 ##########################################################################################
 113 # Define common directories and files
 114 
 115 # Ensure we have 32-bit libs also for x64. We enable mixed-mode.
 116 ifeq (x86_64,$(ARCH))
 117   LIBDIRS := lib64 lib
 118   CFLAGS_lib := -m32
 119 else
 120   LIBDIRS := lib
 121 endif
 122 
 123 # Define directories
 124 RESULT := $(OUTPUT_ROOT)/result
 125 BUILDDIR := $(OUTPUT_ROOT)/$(HOST)/$(TARGET)
 126 PREFIX := $(RESULT)/$(HOST)
 127 TARGETDIR := $(PREFIX)/$(TARGET)
 128 SYSROOT := $(TARGETDIR)/sysroot
 129 DOWNLOAD := $(OUTPUT_ROOT)/download
 130 SRCDIR := $(OUTPUT_ROOT)/src
 131 
 132 # Marker file for unpacking rpms
 133 rpms := $(SYSROOT)/rpms_unpacked
 134 
 135 # Need to patch libs that are linker scripts to use non-absolute paths
 136 libs := $(SYSROOT)/libs_patched
 137 
 138 ##########################################################################################
 139 # Unpack source packages
 140 
 141 # Generate downloading + unpacking of sources.
 142 define 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))
 158 endef
 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.
 167 define unrpm
 168   $(SYSROOT)/$(notdir $(1)).unpacked \
 169     : $(1)
 170   $$(rpms) : $(SYSROOT)/$(notdir $(1)).unpacked
 171 endef
 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 
 219 SYSROOT_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
 229 CONFIG = --target=$(TARGET) \
 230     --host=$(HOST) --build=$(BUILD) \
 231     --prefix=$(PREFIX)
 232 
 233 PATHEXT = $(RESULT)/$(BUILD)/bin:
 234 
 235 PATHPRE = PATH=$(PATHEXT)$(PATH)
 236 BUILDPAR = -j16
 237 
 238 # Default commands to when making
 239 MAKECMD =
 240 INSTALLCMD = install
 241 
 242 
 243 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
 244 
 245 ifeq ($(HOST),$(BUILD))
 246   ifeq ($(HOST),$(TARGET))
 247     TOOLS = $(call declare_tools,_FOR_TARGET,)
 248   endif
 249 endif
 250 
 251 TOOLS ?= $(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.
 259 define 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
 268 endef
 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++
 372 ifneq (,$(findstring linux,$(TARGET)))
 373   $(BUILDDIR)/$(gcc_ver)/Makefile : CONFIG += --enable-__cxa_atexit
 374 endif
 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 
 425 gccpatch = $(TARGETDIR)/gcc-patched
 426 
 427 ##########################################################################################
 428 # For some reason cpp is not created as a target-compiler
 429 ifeq ($(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'
 457 else
 458   $(gccpatch) :
 459         @echo 'done'
 460 endif
 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 
 491 ifeq ($(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)
 499 endif
 500 
 501 ##########################################################################################
 502 
 503 bfdlib : $(bfdlib)
 504 binutils : $(binutils)
 505 rpms : $(rpms)
 506 libs : $(libs)
 507 sysroot : rpms libs
 508 gcc : sysroot $(gcc) $(gccpatch)
 509 all : binutils gcc bfdlib $(PREFIX)/devkit.info $(missing-links) $(SYSROOT_LINKS)
 510 
 511 # this is only built for host. so separate.
 512 ccache : $(ccache)
 513 
 514 # Force target
 515 FRC:
 516 
 517 .PHONY : gcc all binutils bfdlib link_libs rpms libs sysroot