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