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