#!/usr/bin/make -f # # \brief Tool-chain creation tool for the Genode OS Framework # \author Norman Feske # \date 2009-02-03 # help: $(ECHO) $(ECHO) "Build tool chain for the Genode OS Framework" $(ECHO) $(ECHO) "The tool chain consists of GCC $(GCC_VERSION) and binutils $(BINUTILS_VERSION)" $(ECHO) "and will be created at '$(LOCAL_INSTALL_LOCATION)'." $(ECHO) $(ECHO) "--- available commands ---" $(ECHO) "x86 - create tool chain for x86" $(ECHO) "arm - create tool chain for arm" $(ECHO) "aarch64 - create tool chain for aarch64/arm64" $(ECHO) "riscv - create tool chain for riscv" $(ECHO) "clean - clean everything except downloaded archives" $(ECHO) "cleanall - clean everything including downloaded archives" $(ECHO) $(ECHO) "--- available command line options ---" $(ECHO) "MAKE_JOBS=... - number of parallel make jobs (default: 4)" $(ECHO) "BUILD_LOCATION=... - build location (default: $(DEFAULT_BUILD_LOCATION))" $(ECHO) "INSTALL_LOCATION=... - install location (default: $(DEFAULT_INSTALL_LOCATION))" $(ECHO) "SUDO=... - name of sudo command, leave empty to not use sudo (default: sudo)" $(ECHO) "ENABLE_FEATURES=... - features to enable (default: \"$(ENABLE_FEATURES)\")" $(ECHO) # # User interface # SUPPORTED_PLATFORMS := x86 arm riscv aarch64 ENABLE_FEATURES ?= c c++ ada go gdb PLATFORM := $(firstword $(filter $(SUPPORTED_PLATFORMS),$(MAKECMDGOALS))) $(SUPPORTED_PLATFORMS): install # # Enable parallel build for 2nd-level $(MAKE) by default # MAKE_JOBS ?= 4 # # Determine Genode base directory based on the known location of the # 'tool_chain' tool within the Genode source tree # GENODE_DIR ?= $(realpath $(dir $(firstword $(MAKEFILE_LIST)))/..) # # version numbers # TOOL_CHAIN_VERSION = 21.05 GCC_VERSION = 10.3.0 BINUTILS_VERSION = 2.32 # # locations # DEFAULT_BUILD_LOCATION = $(GENODE_DIR)/build/tool_chain-$(TOOL_CHAIN_VERSION) DEFAULT_INSTALL_LOCATION = /usr/local/genode/tool/$(TOOL_CHAIN_VERSION) BUILD_LOCATION ?= $(DEFAULT_BUILD_LOCATION) INSTALL_LOCATION ?= $(DEFAULT_INSTALL_LOCATION) # # Utilities # ## # Return $(2) if $(1) is empty, "" else # check_nonempty_f = $(if $(1),,$(info $(2))$(2)) ## # Return $(3) if $(1) != $(2), "" else # check_equal_f = $(if $(filter $(1),$(2)),,$(info $(3))$(3)) SHELL = bash BRIGHT_COL = \033[01;33m DEFAULT_COL = \033[0m ECHO = @echo -e VERBOSE ?= @ SUDO ?= sudo # # Check if 'flex' is installed # FLEX_OK = $(call check_nonempty_f,$(shell which flex),\ Need to have 'flex' installed.) # # Check if 'bison' is installed # BISON_OK = $(call check_nonempty_f,$(shell which bison),\ Need to have 'bison' installed.) # # Check if 'g++' is installed # GXX_OK = $(call check_nonempty_f,$(shell which g++),\ Need to have 'g++' installed.) # # Check if 'pkg-config' is installed # PKG_CONFIG_OK = $(call check_nonempty_f,$(shell which pkg-config),\ Need to have 'pkg-config' installed.) # # Check if 'libncurses' is installed # CURSES_OK = $(call check_equal_f,\ $(shell pkg-config --exists ncurses && echo ok),ok,\ $(call check_equal_f,\ $(shell pkg-config --exists ncursesw && echo ok),ok,\ Need to have 'libncurses' installed.)) # # Check if 'texinfo' is installed # TEXINFO_OK = $(call check_nonempty_f,$(shell which texi2pdf),\ Need to have 'texinfo' installed.) # # Check if 'libexpat' is installed # EXPAT_OK = $(call check_equal_f,\ $(shell pkg-config --exists expat && echo ok),ok,\ Need to have 'libexpat' installed.) # # Check if 'GNAT' is installed # # The '-dumpfullversion' option is used by GCC version 7, the '-dumpversion' option # is used by GCC versions < 7. # HOST_GCC_VERSION := $(shell gcc -dumpfullversion -dumpversion) GNAT_OK = $(call check_equal_f,$(shell gnatmake --version | sed -n -e 's/GNATMAKE //p'),$(HOST_GCC_VERSION),\ Need to have GNAT installed and the GNAT version must match the GCC version (found GCC $(HOST_GCC_VERSION)).) TOOLS_OK = $(FLEX_OK) $(BISON_OK) $(GXX_OK) $(PKG_CONFIG_OK) $(CURSES_OK) \ $(TEXINFO_OK) $(EXPAT_OK) ifneq ($(filter ada,$(ENABLE_FEATURES)),) TOOLS_OK += $(GNAT_OK) $(GPRBUILD_OK) endif ifneq ($(strip $(TOOLS_OK)),) $(error Please install missing tools.) endif # # 'configure' parameters for binutils, gcc and gdb # LOCAL_BOOTSTRAP_INSTALL_LOCATION = $(BUILD_LOCATION)/bootstrap/install export PATH := $(LOCAL_BOOTSTRAP_INSTALL_LOCATION)/bin:$(PATH) LOCAL_INSTALL_LOCATION = $(BUILD_LOCATION)/install TARGET_NAME_x86 = x86_64-pc-elf TARGET_NAME_arm = arm-none-eabi TARGET_NAME_riscv = riscv64-unknown-elf TARGET_NAME_aarch64 = aarch64-none-elf GCC_CONFIG_riscv = --with-arch=rv64imac --with-abi=lp64 INSTALL_riscv = cd $(INSTALL_LOCATION)/lib/gcc/riscv64-unknown-elf/$(GCC_VERSION)/rv64imac/lp64 && \ $(SUDO) ln -sf ../../include include ifneq ($(VERBOSE),) CONFIG_QUIET = --quiet MAKEFLAGS += --quiet export MAKEFLAGS endif COMMON_BOOTSTRAP_CONFIG = $(CONFIG_QUIET) \ --prefix=$(LOCAL_BOOTSTRAP_INSTALL_LOCATION) \ --disable-multilib BINUTILS_BOOTSTRAP_CONFIG += $(COMMON_BOOTSTRAP_CONFIG) LANGUAGES := $(filter-out gdb, $(ENABLE_FEATURES)) LANGUAGES := $(shell echo "${LANGUAGES}" | sed -e 's/ /,/g') ifeq ($(filter ada,$(ENABLE_FEATURES)),) ALI2DEP_INSTALLED_BINARY = endif ifeq ($(filter gdb,$(ENABLE_FEATURES)),) GDB_INSTALLED_BINARIES = endif GCC_BOOTSTRAP_CONFIG += $(COMMON_BOOTSTRAP_CONFIG) \ --enable-languages=$(filter-out go,$(LANGUAGES)) \ --disable-libgo \ --disable-gotools \ --disable-libatomic \ --disable-libcilkrts \ --disable-libgomp \ --disable-libitm \ --disable-libmpx \ --disable-libsanitizer \ --disable-libquadmath \ --disable-libssp \ --disable-lto COMMON_CONFIG = $(CONFIG_QUIET) \ --prefix=$(LOCAL_INSTALL_LOCATION) \ --program-prefix=genode-$(PLATFORM)- \ --target=$(TARGET_NAME_$(PLATFORM)) \ --program-transform-name="s/$(TARGET_NAME_$(PLATFORM))/$(PLATFORM)/" BINUTILS_CONFIG += $(COMMON_CONFIG) --disable-werror # # Prevent GNU assembler from treating '/' as the start of a comment. In # 'gas/config/tc-i386.c', the policy of handling '/' is defined. For Linux, '/' # is treated as division, which we expect. To apply this needed policy for our # plain 'elf' version gas, we supply the definition of 'TE_LINUX' by hand. # Fortunately, this define is not used outside of gas. # BINUTILS_CONFIG += CFLAGS=-DTE_LINUX # Disable the generation of new relocation types introduced with binutils 2.26 # which are not recognized by older 'ld' versions. This is needed for hybrid # Genode/Linux components on Ubuntu 14.04 with binutils 2.24. BINUTILS_CONFIG_x86 += --disable-x86-relax-relocations # # Add platform-specific binutils configure arguments # BINUTILS_CONFIG += $(BINUTILS_CONFIG_$(PLATFORM)) # # GDB configure arguments # GDB_CONFIG += $(COMMON_CONFIG) --disable-werror --disable-sim GCC_CONFIG += $(COMMON_CONFIG) \ --enable-languages=$(LANGUAGES) \ --disable-libgo \ --disable-gotools \ --disable-libssp \ --disable-libquadmath \ --disable-libffi \ --disable-libada \ --enable-targets=all \ --with-gnu-as \ --with-gnu-ld \ --disable-tls \ --disable-threads \ --disable-hosted-libstdcxx \ --enable-shared \ --enable-multiarch \ --disable-sjlj-exceptions \ CFLAGS_FOR_TARGET="-I$(GENODE_DIR)/tool -DUSE_PT_GNU_EH_FRAME -Dinhibit_libc -fPIC" \ CXXFLAGS_FOR_TARGET="-fPIC" GCC_CONFIG += $(GCC_CONFIG_$(PLATFORM)) # # Configure options passed to gcc # HOST_CONFIG_ARGS = $(CONFIG_QUIET) # # Passed to target components such as libgcc, libstdc++ # TARGET_CONFIG_ARGS = $(CONFIG_QUIET) GCC_INSTALL_RULE = install-strip MAKE_OPT += GENODE="yes" # # Platform-specific multilib support # GCC_MAKE_OPT_x86 := MULTILIB_OPTIONS="m64/m32" MULTILIB_DIRNAMES="64 32" GCC_MAKE_OPT += $(MAKE_OPT) $(GCC_MAKE_OPT_$(PLATFORM)) # # Build rules and dependencies between build steps # # We use the binaries 'objdump' and 'g++' as representatives for expressing # dependencies. All other programs will be generated as side effect. # # The 'gprbuild' tool is built from source because of a bug in the version # that comes with Ubuntu 18.04 (fixed by commit 361d080 on github). # BINUTILS_BOOTSTRAP_BINARIES = $(BUILD_LOCATION)/bootstrap/binutils/binutils/objdump BINUTILS_BOOTSTRAP_INSTALLED_BINARIES = $(LOCAL_BOOTSTRAP_INSTALL_LOCATION)/bin/objdump GCC_BOOTSTRAP_BINARIES = $(BUILD_LOCATION)/bootstrap/gcc/gcc/xg++ GCC_BOOTSTRAP_INSTALLED_BINARIES = $(LOCAL_BOOTSTRAP_INSTALL_LOCATION)/bin/g++ GPRBUILD_BOOTSTRAP_INSTALLED_BINARIES = $(LOCAL_BOOTSTRAP_INSTALL_LOCATION)/bin/gprbuild BINUTILS_BINARIES = $(BUILD_LOCATION)/$(PLATFORM)/binutils/binutils/objdump BINUTILS_INSTALLED_BINARIES = $(LOCAL_INSTALL_LOCATION)/bin/genode-$(PLATFORM)-objdump GCC_BINARIES = $(BUILD_LOCATION)/$(PLATFORM)/gcc/gcc/g++-cross GCC_INSTALLED_BINARIES = $(LOCAL_INSTALL_LOCATION)/bin/genode-$(PLATFORM)-g++ GDB_BINARIES = $(BUILD_LOCATION)/$(PLATFORM)/gdb/gdb/gdb GDB_INSTALLED_BINARIES ?= $(LOCAL_INSTALL_LOCATION)/bin/genode-$(PLATFORM)-gdb ALI2DEP_BINARY = $(BUILD_LOCATION)/ali2dep/ali2dep ALI2DEP_INSTALLED_BINARY ?= $(LOCAL_INSTALL_LOCATION)/bin/genode-$(PLATFORM)-ali2dep build_all: $(GCC_INSTALLED_BINARIES) $(GDB_INSTALLED_BINARIES) $(ALI2DEP_INSTALLED_BINARY) # prepare all ports first to detect more missing tools early BINUTILS_CONTRIB_DIR = $(shell $(GENODE_DIR)/tool/ports/current binutils)/src/noux-pkg/binutils $(BINUTILS_CONTRIB_DIR)/configure: $(ECHO) "$(BRIGHT_COL)preparing binutils...$(DEFAULT_COL)" $(VERBOSE)$(GENODE_DIR)/tool/ports/prepare_port binutils PREPARED_BINUTILS = $(BINUTILS_CONTRIB_DIR)/configure GCC_CONTRIB_DIR = $(shell $(GENODE_DIR)/tool/ports/current gcc)/src/noux-pkg/gcc $(GCC_CONTRIB_DIR)/configure: $(ECHO) "$(BRIGHT_COL)preparing gcc...$(DEFAULT_COL)" $(VERBOSE)$(GENODE_DIR)/tool/ports/prepare_port gcc PREPARED_GCC = $(GCC_CONTRIB_DIR)/configure GDB_CONTRIB_DIR = $(shell $(GENODE_DIR)/tool/ports/current gdb)/src/noux-pkg/gdb $(GDB_CONTRIB_DIR)/configure: $(ECHO) "$(BRIGHT_COL)preparing gdb...$(DEFAULT_COL)" $(VERBOSE)$(GENODE_DIR)/tool/ports/prepare_port gdb PREPARED_GDB = $(GDB_CONTRIB_DIR)/configure PREPARED_PORTS = $(PREPARED_BINUTILS) $(PREPARED_GCC) $(PREPARED_GDB) # bootstrap binutils $(BUILD_LOCATION)/bootstrap/binutils/Makefile: $(BINUTILS_CONTRIB_DIR)/configure $(PREPARED_PORTS) $(ECHO) "$(BRIGHT_COL)configuring bootstrap binutils...$(DEFAULT_COL)" $(VERBOSE)mkdir -p $(dir $@) $(VERBOSE)cd $(dir $@); $(BINUTILS_CONTRIB_DIR)/configure $(BINUTILS_BOOTSTRAP_CONFIG) $(BINUTILS_BOOTSTRAP_BINARIES): $(BUILD_LOCATION)/bootstrap/binutils/Makefile $(ECHO) "$(BRIGHT_COL)building bootstrap binutils...$(DEFAULT_COL)" $(VERBOSE)$(MAKE) -C $(dir $<) -j$(MAKE_JOBS) $(BINUTILS_BOOTSTRAP_INSTALLED_BINARIES): $(BINUTILS_BOOTSTRAP_BINARIES) $(ECHO) "$(BRIGHT_COL)installing bootstrap binutils...$(DEFAULT_COL)" $(VERBOSE)for i in binutils gas ld intl opcodes; do \ $(MAKE) -C $(BUILD_LOCATION)/bootstrap/binutils/$$i install-strip; done $(VERBOSE)$(MAKE) -C $(BUILD_LOCATION)/bootstrap/binutils/libiberty install # bootstrap gcc $(BUILD_LOCATION)/bootstrap/gcc/Makefile: $(GCC_CONTRIB_DIR)/configure \ $(BINUTILS_BOOTSTRAP_INSTALLED_BINARIES) $(BUILD_LOCATION)/bootstrap/gcc/Makefile: $(ECHO) "$(BRIGHT_COL)configuring bootstrap gcc...$(DEFAULT_COL)" $(VERBOSE)mkdir -p $(dir $@) $(VERBOSE)cd $(dir $@); $(GCC_CONTRIB_DIR)/configure $(GCC_BOOTSTRAP_CONFIG) $(GCC_BOOTSTRAP_BINARIES): $(BUILD_LOCATION)/bootstrap/gcc/Makefile $(ECHO) "$(BRIGHT_COL)building bootstrap gcc...$(DEFAULT_COL)" $(VERBOSE)$(MAKE) -C $(dir $<) -j$(MAKE_JOBS) $(GCC_BOOTSTRAP_INSTALLED_BINARIES): $(GCC_BOOTSTRAP_BINARIES) $(ECHO) "$(BRIGHT_COL)installing bootstrap gcc...$(DEFAULT_COL)" $(VERBOSE)$(MAKE) -C $(BUILD_LOCATION)/bootstrap/gcc $(GCC_INSTALL_RULE) # binutils $(BUILD_LOCATION)/$(PLATFORM)/binutils/Makefile: $(BINUTILS_CONTRIB_DIR)/configure \ $(GCC_BOOTSTRAP_INSTALLED_BINARIES) $(ECHO) "$(BRIGHT_COL)configuring binutils...$(DEFAULT_COL)" $(VERBOSE)mkdir -p $(dir $@) $(VERBOSE)cd $(dir $@); $(BINUTILS_CONTRIB_DIR)/configure $(BINUTILS_CONFIG) $(BINUTILS_BINARIES): $(BUILD_LOCATION)/$(PLATFORM)/binutils/Makefile $(ECHO) "$(BRIGHT_COL)building binutils...$(DEFAULT_COL)" $(VERBOSE)$(MAKE) -C $(dir $<) $(MAKE_OPT) -j$(MAKE_JOBS) $(BINUTILS_INSTALLED_BINARIES): $(BINUTILS_BINARIES) $(ECHO) "$(BRIGHT_COL)installing binutils...$(DEFAULT_COL)" $(VERBOSE)for i in binutils gas ld intl opcodes; do \ $(MAKE) -C $(BUILD_LOCATION)/$(PLATFORM)/binutils/$$i install-strip $(MAKE_OPT); done $(VERBOSE)$(MAKE) -C $(BUILD_LOCATION)/$(PLATFORM)/binutils/libiberty install $(MAKE_OPT) # gcc $(BUILD_LOCATION)/$(PLATFORM)/gcc/Makefile: $(GCC_CONTRIB_DIR)/configure \ $(BINUTILS_INSTALLED_BINARIES) $(BUILD_LOCATION)/$(PLATFORM)/gcc/Makefile: $(ECHO) "$(BRIGHT_COL)configuring gcc...$(DEFAULT_COL)" $(VERBOSE)mkdir -p $(dir $@) $(VERBOSE)cd $(dir $@); \ host_configargs="$(HOST_CONFIG_ARGS)" \ target_configargs="$(TARGET_CONFIG_ARGS)" \ $(GCC_CONTRIB_DIR)/configure $(GCC_CONFIG) $(GCC_BINARIES): $(BUILD_LOCATION)/$(PLATFORM)/gcc/Makefile $(GCC_BINARIES): $(ECHO) "$(BRIGHT_COL)building gcc...$(DEFAULT_COL)" $(VERBOSE)$(MAKE) -C $(dir $<) $(GCC_MAKE_OPT) -j$(MAKE_JOBS) $(GCC_INSTALLED_BINARIES): $(GCC_BINARIES) $(ECHO) "$(BRIGHT_COL)installing gcc...$(DEFAULT_COL)" $(VERBOSE)$(MAKE) -C $(BUILD_LOCATION)/$(PLATFORM)/gcc $(GCC_INSTALL_RULE) $(GCC_MAKE_OPT) # gdb $(BUILD_LOCATION)/$(PLATFORM)/gdb/Makefile: $(GDB_CONTRIB_DIR)/configure $(ECHO) "$(BRIGHT_COL)configuring gdb...$(DEFAULT_COL)" $(VERBOSE)mkdir -p $(dir $@) $(VERBOSE)cd $(dir $@); \ $(GDB_CONTRIB_DIR)/configure $(GDB_CONFIG) $(GDB_BINARIES): $(BUILD_LOCATION)/$(PLATFORM)/gdb/Makefile $(ECHO) "$(BRIGHT_COL)building gdb...$(DEFAULT_COL)" $(VERBOSE)$(MAKE) -C $(dir $<) $(MAKE_OPT) -j$(MAKE_JOBS) $(GDB_INSTALLED_BINARIES): $(GDB_BINARIES) $(ECHO) "$(BRIGHT_COL)installing gdb...$(DEFAULT_COL)" $(VERBOSE)$(MAKE) -C $(BUILD_LOCATION)/$(PLATFORM)/gdb install $(MAKE_OPT) MAKEINFO=true $(VEBOSE)strip $@ # gprbuild $(BUILD_LOCATION)/bootstrap/gprbuild/Makefile: $(ECHO) "$(BRIGHT_COL)preparing bootstrap gprbuild...$(DEFAULT_COL)" $(VERBOSE)git clone -b v21.0.0 https://github.com/AdaCore/gprbuild.git $(dir $@) $(VERBOSE)git clone -b v21.0.0 https://github.com/AdaCore/xmlada.git $(dir $@)/xmlada $(VERBOSE)git clone -b v21.0.0 https://github.com/AdaCore/gprconfig_kb.git $(dir $@)/gprconfig_kb $(VERBOSE)sed -i -e '/\/d' $(dir $@)/gprconfig_kb/db/linker.xml $(VERBOSE)sed -i -e '/\/d' $(dir $@)/gprconfig_kb/db/linker.xml $(GPRBUILD_BOOTSTRAP_INSTALLED_BINARIES): $(BUILD_LOCATION)/bootstrap/gprbuild/Makefile $(GCC_BOOTSTRAP_INSTALLED_BINARIES) $(ECHO) "$(BRIGHT_COL)building bootstrap gprbuild...$(DEFAULT_COL)" $(VERBOSE)cd $(dir $<); CC=$(LOCAL_BOOTSTRAP_INSTALL_LOCATION)/bin/gcc ./bootstrap.sh \ --with-xmlada=./xmlada --with-kb=./gprconfig_kb --prefix=$(LOCAL_BOOTSTRAP_INSTALL_LOCATION) # ali2dep $(BUILD_LOCATION)/ali2dep/build/build.gpr: $(ECHO) "$(BRIGHT_COL)preparing ali2dep...$(DEFAULT_COL)" $(VERBOSE)git clone -b gcc_10_3_0 https://github.com/cproc/ali2dep.git $(BUILD_LOCATION)/ali2dep $(VERBOSE)sed -i -e '/Create_Missing_Dirs/d' $@ $(ALI2DEP_BINARY): $(GCC_BOOTSTRAP_INSTALLED_BINARIES) $(GPRBUILD_BOOTSTRAP_INSTALLED_BINARIES) $(BUILD_LOCATION)/ali2dep/build/build.gpr $(ECHO) "$(BRIGHT_COL)building ali2dep...$(DEFAULT_COL)" $(VERBOSE)$(LOCAL_BOOTSTRAP_INSTALL_LOCATION)/bin/gprconfig --batch --target=all \ --config=Ada,,default,$(LOCAL_BOOTSTRAP_INSTALL_LOCATION)/bin,GNAT \ --config=C,,,$(LOCAL_BOOTSTRAP_INSTALL_LOCATION)/bin/,GCC \ -o $(BUILD_LOCATION)/ali2dep/genode_bootstrap_tool_chain.cgpr $(VERBOSE)GPRBUILD_ARGS="--config=genode_bootstrap_tool_chain.cgpr" $(MAKE) -C $(BUILD_LOCATION)/ali2dep $(ALI2DEP_INSTALLED_BINARY): $(ALI2DEP_BINARY) $(ECHO) "$(BRIGHT_COL)installing ali2dep...$(DEFAULT_COL)" $(VERBOSE)strip -o $@ $< # # Clean rules # clean: rm -rf $(BUILD_LOCATION) cleanall: clean # # Install rules # install: build_all $(ECHO) "$(BRIGHT_COL)installing tool chain to '$(INSTALL_LOCATION)'...$(DEFAULT_COL)" $(VERBOSE)$(SUDO) mkdir -p $(INSTALL_LOCATION) $(VERBOSE)$(SUDO) cp -a --remove-destination --no-target-directory $(LOCAL_INSTALL_LOCATION) $(INSTALL_LOCATION) $(VERBOSE)$(LIB_GCC) $(VERBOSE)$(INSTALL_$(PLATFORM)) ifeq ($(INSTALL_LOCATION),$(DEFAULT_INSTALL_LOCATION)) $(VERBOSE)$(SUDO) ln -snf $(TOOL_CHAIN_VERSION) $(dir $(INSTALL_LOCATION))current endif