# Copyright (c) 2015 Cisco and/or its affiliates. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at: # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # Copyright (c) 2007-2008 Eliot Dresselhaus # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including # without limitation the rights to use, copy, modify, merge, publish, # distribute, sublicense, and/or sell copies of the Software, and to # permit persons to whom the Software is furnished to do so, subject to # the following conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # ###################################################################### # Collect makefile fragments ###################################################################### # Scripts require non-POSIX parts of bash SHELL := /bin/bash # Where this makefile lives MU_BUILD_ROOT_DIR = $(shell pwd) MU_BUILD_NAME = $(shell basename $(MU_BUILD_ROOT_DIR)) # Search path (e.g. multiple directories) where sources are found. SOURCE_PATH = # Pick up user's definitions for variables e.g. SOURCE_PATH, etc. -include build-config.mk MU_BUILD_ROOT_NAME = $(shell basename $(MU_BUILD_ROOT_DIR)) MU_BUILD_DATA_DIR_NAME = build-data ABSOLUTE_SOURCE_PATH = $(foreach d,$(SOURCE_PATH),$(shell cd $(d) && pwd)) SOURCE_PATH_BUILD_ROOT_DIRS = $(addsuffix /$(MU_BUILD_NAME),$(ABSOLUTE_SOURCE_PATH)) SOURCE_PATH_BUILD_DATA_DIRS = $(addsuffix /$(MU_BUILD_DATA_DIR_NAME),$(ABSOLUTE_SOURCE_PATH)) # For tools use build-root as source path, otherwise use given source path FIND_SOURCE_PATH = \ $(if $(is_build_tool), \ $(SOURCE_PATH_BUILD_ROOT_DIRS) $(MU_BUILD_ROOT_DIR), \ $(SOURCE_PATH_BUILD_DATA_DIRS)) # First search given source path, then default to build-root FULL_SOURCE_PATH = $(SOURCE_PATH_BUILD_DATA_DIRS) $(MU_BUILD_ROOT_DIR) # Misc functions is_in_fn = $(strip $(filter $(1),$(2))) last_fn = $(lastword $1) chop_fn = $(wordlist 2,$(words $1),x $1) uniq_fn = $(strip $(if $1,$(call uniq_fn,$(call chop_fn,$1)) \ $(if $(filter $(call last_fn,$1),$(call chop_fn,$1)),,$(call last_fn,$1)))) ifdef3_fn = $(if $(patsubst undefined,,$(origin $(1))),$(3),$(2)) ifdef_fn = $(call ifdef3_fn,$(1),$(2),$($(1))) _mu_debug = $(warning "$(1) = $($(1))") $(foreach d,$(FIND_SOURCE_PATH), \ $(eval _mu_package_mk_in_$(d) = $(shell find $(d)/packages/*.mk 2> /dev/null)) \ $(eval _mu_srcdirs_in_$(d) = \ $(shell find $(d)/.. \ -maxdepth 1 \ -type d \ -and -not -name ".." \ -and -not -name $(MU_BUILD_ROOT_NAME) \ -and -not -name $(MU_BUILD_DATA_DIR_NAME))) \ $(eval _mu_non_package_files_in_$(d) = \ $(shell find $(d)/packages \ -type f \ -and -not -name '*.mk' \ -and -not -name '*~' 2> /dev/null)) \ $(foreach p,$(patsubst %.mk,%,$(notdir $(_mu_package_mk_in_$(d)))), \ $(eval _mu_package_dir_$(p) = $(d)) \ $(eval _mu_package_mk_$(p) = $(d)/packages/$(p).mk) \ ) \ $(foreach p,$(notdir $(_mu_srcdirs_in_$(d))), \ $(eval _mu_package_srcdir_$(p) = $(shell cd $(d)/../$(p) && pwd)) \ ) \ ) # Find root directory for package based on presence of package .mk # makefile fragment on source path. _find_build_data_dir_for_package_fn = $(shell \ set -eu$(BUILD_DEBUG) ; \ for d in $(FIND_SOURCE_PATH) ; do \ f="$${d}/packages/$(1).mk" ; \ [[ -f $${f} ]] && echo `cd $${d} && pwd` && exit 0 ; \ done ; \ echo "") find_build_data_dir_for_package_fn = $(call ifdef_fn,_mu_package_dir_$(1),) # dir/PACKAGE _find_source_fn = $(shell \ set -eu$(BUILD_DEBUG) ; \ d="$(call find_build_data_dir_for_package_fn,$(1))" ; \ [[ -n "$${d}" ]] && d="$${d}/../$(1)" ; \ echo "$${d}") find_source_fn = $(call ifdef3_fn,_mu_package_dir_$(1),,$(_mu_package_dir_$(1))/../$(1)) # Find given FILE in source path as build-data/packages/FILE find_package_file_fn = $(shell \ set -eu$(BUILD_DEBUG) ; \ d="$(call find_build_data_dir_for_package_fn,$(1))" ; \ [[ -n "$${d}" ]] && d="$${d}/packages/$(2)" ; \ [[ -f "$${d}" ]] && echo "$${d}") # Find first FILE in source path with name PATH/build-data/FILE find_build_data_file_fn = $(shell \ set -eu$(BUILD_DEBUG) ; \ for d in $(FIND_SOURCE_PATH) ; do \ f="$${d}/$(1)" ; \ [[ -f $${f} ]] && echo `cd $${d} && pwd`/$(1) && exit 0 ; \ done ; \ echo "") ###################################################################### # ARCH, PLATFORM ###################################################################### NATIVE_ARCH = $(shell gcc -dumpmachine | sed -e 's/\([a-zA-Z_0-9]*\)-.*/\1/') # Find all platforms.mk that we can, including those from build-root $(foreach d,$(FULL_SOURCE_PATH), \ $(eval -include $(d)/platforms.mk)) # Platform should be defined somewhere by specifying $($(PLATFORM)_arch) ARCH = $(strip $($(PLATFORM)_arch)) ifeq ($(ARCH),) $(error "Unknown platform `$(PLATFORM)'") endif # map e.g. ppc7450 -> ppc BASIC_ARCH = \ ${shell case '$(ARCH)' in \ (native) echo $(NATIVE_ARCH) ;; \ (i*86*) echo i386 ;; \ (ppc*|powerpc*) echo ppc ;; \ (*) echo '$(ARCH)' ;; \ esac } # x86_64 can be either 32/64. set BIACH=32 to get 32 bit libraries. BIARCH = 64 aarch64_libdir = 64 x86_64_libdir = $(BIARCH) native_libdir = $($(NATIVE_ARCH)_libdir) # lib or lib64 depending arch_lib_dir = lib$($(BASIC_ARCH)_libdir) # OS to configure for. configure --host will be set to $(ARCH)-$(OS) # Allow per-platform overrides OS = $(strip $($(PLATFORM)_os)) ifeq ($(OS),) OS = mu-linux endif spu_target = spu native_target = is_native = $(if $(ARCH:native=),,true) not_native = $(if $(ARCH:native=),true,) ARCH_TARGET_tmp = $(call ifdef_fn,$(ARCH)_target,$(ARCH)-$(OS)) TARGET = $(call ifdef_fn,$(PLATFORM)_target,$(ARCH_TARGET_tmp)) TARGET_PREFIX = $(if $(not_native),$(TARGET)-,) # CPU microarchitecture detection. # Either set _march in build-data/platforms/.mk, # or detect and use the build-host instruction set MARCH = $(strip $($(PLATFORM)_march)) ifeq ($(MARCH),) ifneq ($(wildcard $(TOOL_INSTALL_DIR)/bin/$(TARGET)-gcc),) TARGET_GCC = $(TOOL_INSTALL_DIR)/bin/$(TARGET)-gcc else ifneq ($(wildcard $(MU_BUILD_ROOT_DIR)/tools/bin/$(TARGET)-gcc),) TARGET_GCC = $(MU_BUILD_ROOT_DIR)/tools/bin/$(TARGET)-gcc endif ifneq ($(TARGET_GCC),) MARCH = $(shell $(TARGET_GCC) -Q --help=target -march=native | grep march | sed -e 's/.*march=[[:space:]]*//') else MARCH = native endif else ifeq ($(MARCH),nehalem) override MARCH = corei7 else ifeq ($(MARCH),westmere) override MARCH = corei7 else ifeq ($(MARCH),sandybridge) override MARCH = corei7-avx else ifeq ($(MARCH),ivybridge) override MARCH = core-avx-i else ifeq ($(MARCH),haswell) override MARCH = core-avx2 endif endif export MARCH MTUNE = $(strip $($(PLATFORM)_mtune)) ifeq ($(MTUNE),) MTUNE = generic endif ###################################################################### # Generic build stuff ###################################################################### # The package we are currently working on PACKAGE = $* # Build/install tags. This lets you have different CFLAGS/CPPFLAGS/LDFLAGS # for e.g. debug versus optimized compiles. Each tag has its own set of build/install # areas. TAG = TAG_PREFIX = $(if $(TAG),$(TAG)-) # yes you need the space tag_var_with_added_space_fn = $(if $($(TAG)_TAG_$(1)),$($(TAG)_TAG_$(1)) ) # TAG=debug for debugging debug_TAG_CFLAGS = -g -O0 -DCLIB_DEBUG -DFORTIFY_SOURCE=2 -march=$(MARCH) \ -fstack-protector-all -fPIC debug_TAG_CXXFLAGS = -g -O0 -DCLIB_DEBUG -DFORTIFY_SOURCE=2 -march=$(MARCH) \ -fstack-protector-all -fPIC debug_TAG_LDFLAGS = -g -O0 -DCLIB_DEBUG -DFORTIFY_SOURCE=2 -march=$(MARCH) \ -fstack-protector-all -fPIC BUILD_PREFIX_package = build-$(TAG_PREFIX) BUILD_PREFIX_tool = build-tool-$(TAG_PREFIX) INSTALL_PREFIX = install-$(TAG_PREFIX) IMAGES_PREFIX = images-$(TAG_PREFIX) # Whether we are building a tool or not tool_or_package_fn = $(if $(is_build_tool),tool,package) # Directory where packages are built & installed BUILD_DIR = $(MU_BUILD_ROOT_DIR)/$(BUILD_PREFIX_$(call tool_or_package_fn))$(ARCH) INSTALL_DIR = $(MU_BUILD_ROOT_DIR)/$(INSTALL_PREFIX)$(ARCH) PLATFORM_IMAGE_DIR = $(MU_BUILD_ROOT_DIR)/$(IMAGES_PREFIX)$(PLATFORM) # $(call VAR,DEFAULT) override_var_with_default_fn = $(if $($(1)),$($(1)),$(2)) # $(call if_directory_exists_fn,D1,D2) returns D1 if it exists else D2 define if_directory_exists_fn $(shell if test -d $(1); then echo $(1); else echo $(2); fi) endef # $(call if_file_exists_fn,F1,F2) returns F1 if it exists else F2 define if_file_exists_fn $(shell if test -f $(1); then echo $(1); else echo $(2); fi) endef # Default VAR, package specified override of default PACKAGE_VAR package_var_fn = $(call override_var_with_default_fn,$(1)_$(2),$(1)) package_build_dir_fn = $(call package_var_fn,$(1),build_dir) package_install_dir_fn = \ $(if $(is_build_tool),$(TOOL_INSTALL_DIR),$(INSTALL_DIR)/$(call package_build_dir_fn,$(1))) PACKAGE_BUILD_DIR = \ $(BUILD_DIR)/$(call package_build_dir_fn,$(PACKAGE)) PACKAGE_INSTALL_DIR = \ $(call package_install_dir_fn,$(PACKAGE)) # Tools (gcc, binutils, glibc...) are installed here TOOL_INSTALL_DIR = $(MU_BUILD_ROOT_DIR)/tools # Target specific tools go here e.g. mu-build/tools/ppc-mu-linux TARGET_TOOL_INSTALL_DIR = $(TOOL_INSTALL_DIR)/$(TARGET) # Set BUILD_DEBUG to vx or x enable shell command tracing. BUILD_DEBUG = # Message from build system itself (as opposed to make or shell commands) build_msg_fn = echo "@@@@ $(1) @@@@" # Allow CCACHE_DIR to be overridden, e.g. in .../build-root/build-config.mk ifeq ($(CCACHE_DIR),) CCACHE_DIR=$(MU_BUILD_ROOT_DIR)/.ccache endif # Always prefer our own tools to those installed on system. # Note: ccache-bin must be before tool bin. # # Removed LD_LIBRARY_PATH from BUILD_ENV (drb, 10/31/17): # export LD_LIBRARY_PATH=$(TOOL_INSTALL_DIR)/lib64:$(TOOL_INSTALL_DIR)/lib # Reported to cause trouble. Only of historical interest, since we no longer # build a full tool chain from source. BUILD_ENV = \ export CCACHE_DIR=$(CCACHE_DIR) ; \ export PATH=$(wildcard /usr/lib*/ccache):$(TOOL_INSTALL_DIR)/bin:$${PATH} ; \ $(if $(call configure_var_fn,PATH), export PATH=$${PATH}:$(call configure_var_fn,PATH);,) \ export PATH="`echo $${PATH} | sed -e s/[.]://`" ; \ $(if $(not_native),export CONFIG_SITE=$(MU_BUILD_ROOT_DIR)/config.site ;,) \ set -eu$(BUILD_DEBUG) ; \ set -o pipefail ###################################################################### # Package build generic definitions ###################################################################### package_dir_fn = \ $(call find_build_data_dir_for_package_fn,$(1))/packages package_mk_fn = $(call package_dir_fn,$(1))/$(1).mk # Pick up built-root/pre-package-include.mk for all source directories $(foreach d,$(SOURCE_PATH_BUILD_ROOT_DIRS), \ $(eval -include $(d)/pre-package-include.mk)) $(foreach d,$(addsuffix /packages,$(FIND_SOURCE_PATH)), \ $(eval -include $(d)/*.mk) \ $(eval ALL_PACKAGES += $(patsubst $(d)/%.mk,%,$(wildcard $(d)/*.mk))) \ ) # Pick up built-root/post-package-include.mk for all source directories $(foreach d,$(SOURCE_PATH_BUILD_ROOT_DIRS), \ $(eval -include $(d)/post-package-include.mk)) # Linux specific native build tools NATIVE_TOOLS_LINUX = \ e2fsimage \ e2fsprogs \ fakeroot \ jffs2 \ mkimage \ zlib \ xz \ squashfs IS_LINUX = $(if $(findstring no,$($(PLATFORM)_uses_linux)),no,yes) NATIVE_TOOLS_$(IS_LINUX) += $(NATIVE_TOOLS_LINUX) # only build glibc for linux installs CROSS_TOOLS_$(IS_LINUX) += glibc gcc # must be first for bootstrapping NATIVE_TOOLS = findutils make # basic tools needed for build system NATIVE_TOOLS += git automake autoconf libtool texinfo tar # needed to compile gcc NATIVE_TOOLS += mpfr gmp mpc # Tool to sign binaries NATIVE_TOOLS += sign # ccache NATIVE_TOOLS += ccache # Tools needed on native host to build for platform NATIVE_TOOLS += $(call ifdef_fn,$(PLATFORM)_native_tools,) # Tools for cross-compiling from native -> ARCH CROSS_TOOLS = binutils gcc-bootstrap gdb # Tools needed on native host to build for platform CROSS_TOOLS += $(call ifdef_fn,$(PLATFORM)_cross_tools,) NATIVE_TOOLS += $(NATIVE_TOOLS_yes) CROSS_TOOLS += $(CROSS_TOOLS_yes) timestamp_name_fn = .mu_build_$(1)_timestamp CONFIGURE_TIMESTAMP = $(call timestamp_name_fn,configure) BUILD_TIMESTAMP = $(call timestamp_name_fn,build) INSTALL_TIMESTAMP = $(call timestamp_name_fn,install) TIMESTAMP_DIR = $(PACKAGE_BUILD_DIR) find_newer_files_fn = \ "`for i in $(2) ; do \ [[ -f $$i && $$i -nt $(1) ]] && echo "$$i" && exit 0; \ done ; \ exit 0;`" find_filter = -not -name '*~' find_filter += -and -not -path '*/.git*' find_filter += -and -not -path '*/.svn*' find_filter += -and -not -path '*/.CVS*' find_filter += -and -not -path '*/manual/*' find_filter += -and -not -path '*/autom4te.cache/*' find_filter += -and -not -path '*/doc/all-cfg.texi' find_filter += -and -not -path '*/.mu_build_*' find_newer_filtered_fn = \ (! -f $(1) \ || -n $(call find_newer_files_fn,$(1),$(3)) \ || -n "`find -H $(2) \ -type f \ -and -newer $(1) \ -and \( $(4) \) \ -print -quit`") find_newer_fn = \ $(call find_newer_filtered_fn,$(1),$(2),$(3),$(find_filter)) ###################################################################### # Package dependencies ###################################################################### # This must come before %-configure, %-build, %-install pattern rules # or else dependencies will not work. package_dependencies_fn = \ $(patsubst %-install, %, \ $(filter %-install,$($(1)_configure_depend))) PACKAGE_DEPENDENCIES = $(call package_dependencies_fn,$(PACKAGE)) # package specific configure, build, install dependencies add_package_dependency_fn = \ $(if $($(1)_$(2)_depend), \ $(eval $(1)-$(2) : $($(1)_$(2)_depend))) $(foreach p,$(ALL_PACKAGES), \ $(call add_package_dependency_fn,$(p),configure) \ $(call add_package_dependency_fn,$(p),build) \ $(call add_package_dependency_fn,$(p),install)) TARGETS_RESPECTING_DEPENDENCIES = image_install wipe diff push-all pull-all find-source # carry over packages dependencies to image install, wipe, pull-all, push-all $(foreach p,$(ALL_PACKAGES), \ $(if $($(p)_configure_depend), \ $(foreach s,$(TARGETS_RESPECTING_DEPENDENCIES), \ $(eval $(p)-$(s): \ $(addsuffix -$(s), $(call package_dependencies_fn,$(p))))))) # recursively resolve dependencies resolve_dependencies2_fn = $(strip \ $(eval __added = $(filter-out $(4), \ $(call uniq_fn, \ $(foreach l,$(3), \ $(call ifdef3_fn,$(l)$(1),,$(call $(2),$($(l)$(1)))) \ )))) \ $(eval __known = $(call uniq_fn,$(4) $(3) $(__added))) \ $(if $(__added), \ $(call resolve_dependencies2_fn,$(1),$(2),$(__added),$(__known)), \ $(__known)) \ ) resolve_dependencies_null_fn = $(1) resolve_dependencies_fn = $(call resolve_dependencies2_fn,$(1),resolve_dependencies_null_fn,$(2)) #################### ker # Allow per-platform overrides CROSS_LDFLAGS = $(strip $($(PLATFORM)_cross_ldflags)) ifeq ($(CROSS_LDFLAGS),) CROSS_LDFLAGS = \ -Wl,--dynamic-linker=$(lots_of_slashes_to_pad_names)$(TOOL_INSTALL_LIB_DIR)/$(DYNAMIC_LINKER) \ -Wl,-rpath -Wl,$(lots_of_slashes_to_pad_names)$(TOOL_INSTALL_LIB_DIR) endif cross_ldflags = $(if $(is_native)$(is_build_tool),,$(CROSS_LDFLAGS) ) # $(call installed_libs_fn,PACKAGE) # Return install library directory for given package. # Some packages (e.g. openssl) don't install under lib64; instead they use lib define installed_lib_fn $(call if_directory_exists_fn, $(call package_install_dir_fn,$(1))/$(arch_lib_dir), $(call package_install_dir_fn,$(1))/lib) endef # Set -L and rpath to point to dependent libraries previously built by us. installed_libs_fn = \ $(foreach i,$(1), \ -L$(call installed_lib_fn,$(i)) \ -Wl,-rpath -Wl,$(call installed_lib_fn,$(i))) # As above for include files installed_include_fn = $(call package_install_dir_fn,$(1))/include installed_includes_fn = $(foreach i,$(1),-I$(call installed_include_fn,$(i))) # By default package CPPFLAGS (to set include path -I) and LDFLAGS (to set link path -L) # point at dependent install directories. DEFAULT_CPPFLAGS = $(call installed_includes_fn, $(PACKAGE_DEPENDENCIES)) DEFAULT_LDFLAGS = $(call installed_libs_fn, $(PACKAGE_DEPENDENCIES)) configure_var_fn = \ $(call tag_var_with_added_space_fn,$(1))$(call override_var_with_default_fn,$(PACKAGE)_$(1),$(DEFAULT_$(1))) configure_ldflags_fn = \ $(cross_ldflags)$(call configure_var_fn,LDFLAGS) # Allow packages to override CPPFLAGS, CFLAGS, and LDFLAGS CONFIGURE_ENV = \ $(if $(call configure_var_fn,CPPFLAGS), \ CPPFLAGS="$(CPPFLAGS) $(call configure_var_fn,CPPFLAGS)") \ $(if $(call configure_var_fn,CXXFLAGS), \ CXXFLAGS="$(CXXFLAGS) $(call configure_var_fn,CXXFLAGS)") \ $(if $(call configure_var_fn,CFLAGS), \ CFLAGS="$(CFLAGS) $(call configure_var_fn,CFLAGS)") \ $(if $(call configure_var_fn,CCASFLAGS), \ CCASFLAGS="$(CCASFLAGS) $(call configure_var_fn,CCASFLAGS)") \ $(if $(call configure_ldflags_fn), \ LDFLAGS="$(LDFLAGS) $(call configure_ldflags_fn)") \ $(if $($(PACKAGE)_configure_env),$($(PACKAGE)_configure_env)) # only partially used now (used in a few .mk files) ifeq ($(is_build_tool),yes) prefix = $(PACKAGE_INSTALL_DIR) libdir = $(PACKAGE_INSTALL_DIR)/$(arch_lib_dir) libexecdir = $(PACKAGE_INSTALL_DIR)/usr/libexec DESTDIR = / else # Eventually simplify this with no per package DESTDIR or prefix ppdMacro = $(if $(PER_PACKAGE_DESTDIR),$(call package_build_dir_fn,$(1))) pppMacro = $(if $(PER_PACKAGE_PREFIX),$(call package_build_dir_fn,$(1))) prefixMacro = $($(PLATFORM)_PREFIX_BASE)/$(pppMacro) prefix = $(call prefixMacro,$(PACKAGE)) libdir = $($(PLATFORM)_LIBDIR) libexecdir = $($(PLATFORM)_LIBEXECDIR) destdirMacro = $($(PLATFORM)_DESTDIR_BASE)$(ppdMacro) DESTDIR = $(call destdirMacro,$(PACKAGE)) endif configure_package_gnu = \ s=$(call find_source_fn,$(PACKAGE_SOURCE))$(PACKAGE_SUBDIR) ; \ if [ ! -f $$s/configure ] ; then \ autoreconf -i -f $$s ; \ fi ; \ cd $(PACKAGE_BUILD_DIR) ; \ env $(CONFIGURE_ENV) \ $$s/configure \ $(if $($(PACKAGE)_configure_host_and_target), \ $($(PACKAGE)_configure_host_and_target), \ $(if $(not_native),--host=$(TARGET),)) \ $(if $($(PACKAGE)_configure_prefix), \ $($(PACKAGE)_configure_prefix), \ --libdir=$(PACKAGE_INSTALL_DIR)/$(arch_lib_dir) \ --prefix=$(PACKAGE_INSTALL_DIR)) \ $($(PACKAGE)_configure_args) \ $($(PACKAGE)_configure_args_$(PLATFORM)) configure_package = \ $(call build_msg_fn,Configuring $(PACKAGE) in $(PACKAGE_BUILD_DIR)) ; \ mkdir -p $(PACKAGE_BUILD_DIR) ; \ $(if $($(PACKAGE)_configure), \ $($(PACKAGE)_configure), \ $(configure_package_gnu)) # Tools (e.g. gcc, binutils, gdb) required a platform to build for check_platform = \ is_tool="$(is_build_tool)" ; \ is_cross_package="$(findstring $(PACKAGE),$(CROSS_TOOLS))" ; \ is_arch_native="$(if $(subst native,,$(ARCH)),,yes)" ; \ if [ "$${is_tool}" == "yes" \ -a "$${is_cross_package}" != "" \ -a "$${is_arch_native}" != "" ]; then \ $(call build_msg_fn,You must specify PLATFORM for building tools) ; \ exit 1 ; \ fi ; \ : check that platform gcc can be found ; \ target_gcc=gcc ; \ if [ "$${is_arch_native}" != "yes" ] ; then \ target_gcc=$(TARGET)-gcc ; \ fi ; \ if [ "$${is_tool}" != "yes" \ -a "$${is_arch_native}" != "yes" \ -a ! -x "`which 2> /dev/null $${target_gcc}`" ] ; then \ $(call build_msg_fn, \ No cross-compiler found for platform $(PLATFORM) target $(TARGET); \ try make PLATFORM=$(PLATFORM) install-tools) ; \ exit 1 ; \ fi configure_check_timestamp = \ @$(BUILD_ENV) ; \ $(check_platform) ; \ mkdir -p $(PACKAGE_BUILD_DIR) ; \ mkdir -p $(PACKAGE_INSTALL_DIR) ; \ conf="$(TIMESTAMP_DIR)/$(CONFIGURE_TIMESTAMP)" ; \ dirs="$(call package_mk_fn,$(PACKAGE)) \ $(SOURCE_PATH_BUILD_DATA_DIRS)/platforms/$(PLATFORM).mk \ $(wildcard $(call find_source_fn,$(PACKAGE_SOURCE))/cmake) \ $(shell find $(call find_source_fn,$(PACKAGE_SOURCE)) \ -name CMakeLists.txt) \ $(wildcard $(call find_source_fn, \ $(PACKAGE_SOURCE))$(PACKAGE_SUBDIR)/configure) \ $(MU_BUILD_ROOT_DIR)/config.site" ; \ if [[ $(call find_newer_fn, $${conf}, $${dirs}, $?) ]]; then \ $(configure_package) ; \ touch $${conf} ; \ else \ $(call build_msg_fn,Configuring $(PACKAGE): nothing to do) ; \ fi .PHONY: %-configure %-configure: %-find-source $(configure_check_timestamp) ###################################################################### # Package build ###################################################################### # /proc/cpuinfo does not exist on platforms without a /proc and on some # platforms, notably inside containers, it has no content. In those cases # we assume there's 1 processor; we use 2*ncpu for the -j option. # NB: GNU Make 4.2 will let us use '$(file & /dev/null && $(GIT) pull && popd >& /dev/null ; \ done ; \ $(call build_msg_fn,Git pull build tools) ; \ $(call tool_make_target_fn,pull-all) ; \ $(call build_msg_fn,Git pull packages for platform $(PLATFORM)) ; \ make PLATFORM=$(PLATFORM) $(patsubst %,%-pull-all,$(ROOT_PACKAGES)) .PHONY: %-diff %-diff: @$(BUILD_ENV) ; \ d=$(call find_source_fn,$(PACKAGE_SOURCE)) ; \ $(call build_msg_fn,Git diff $(PACKAGE)) ; \ if [ -d $${d}/.git ] ; then \ cd $${d} && $(GIT) --no-pager diff 2>/dev/null; \ else \ $(call build_msg_fn, $(PACKAGE) not a git directory) ; \ fi # generate diffs for everything in source path .PHONY: diff-all diff-all: @$(BUILD_ENV) ; \ $(call build_msg_fn,Generate diffs) ; \ for r in $(ABSOLUTE_SOURCE_PATH); do \ for d in $${r}/* ; do \ if [ -d $${d} ] ; then \ $(call build_msg_fn,Git diff $${d}) ; \ if [ -d $${d}/.git ] ; then \ cd $${d} && $(GIT) --no-pager diff 2>/dev/null; \ else \ $(call build_msg_fn, $${d} not a git directory) ; \ fi ; \ fi ; \ done ; \ done ###################################################################### # System images ###################################################################### IMAGE_DIR = $(MU_BUILD_ROOT_DIR)/image-$(PLATFORM) # Reports shared libraries in given directory find_shared_libs_fn = \ find $(1) \ -maxdepth 1 \ -regex '.*/lib[a-z0-9_]+\+?\+?.so' \ -o -regex '.*/lib[a-z0-9_]+-[0-9.]+\+?\+?.so' \ -o -regex '.*/lib[a-z0-9_]+\+?\+?.so.[0-9.]+' # By default pick up files from binary directories and /etc. # Also include shared libraries. DEFAULT_IMAGE_INCLUDE = \ for d in bin sbin libexec \ usr/bin usr/sbin usr/libexec \ etc; do \ [[ -d $$d ]] && echo $$d; \ done ; \ [[ -d $(arch_lib_dir) ]] \ && $(call find_shared_libs_fn,$(arch_lib_dir)) # Define any shell functions needed by install scripts image_install_functions = \ $(foreach p,$(ALL_PACKAGES), \ $(if $($(p)_image_install_functions), \ $($(p)_image_install_functions))) # Should always be over-written by temp dir in %-root-image rule IMAGE_INSTALL_DIR = $(error you need to set IMAGE_INSTALL_DIR) image_install_fn = \ @$(BUILD_ENV) ; \ $(call build_msg_fn,Image-install $(1) for platform $(PLATFORM)) ; \ inst_dir=$(IMAGE_INSTALL_DIR) ; \ mkdir -p $${inst_dir} ; \ cd $(2) ; \ : select files to include in image ; \ image_include_files=" \ `$(call ifdef_fn,$(1)_image_include,$(DEFAULT_IMAGE_INCLUDE)) ; \ echo "" ; \ exit 0 ; `"; \ : select files regexps to exclude from image ; \ image_exclude_files="" ; \ if [ ! -z "$($(1)_image_exclude)" ] ; then \ image_exclude_files="${image_exclude_files} \ $(patsubst %,--exclude=%,$($(1)_image_exclude))" ; \ fi ; \ [[ -z "$${image_include_files}" || $${image_include_files} == " " ]] \ || tar cf - $${image_include_files} $${image_exclude_files} \ | tar xf - -C $${inst_dir} ; \ : copy files from copyimg directories on source path if present ; \ for build_data_dir in $(SOURCE_PATH_BUILD_DATA_DIRS) ; do \ d="$${build_data_dir}/packages/$(1).copyimg" ; \ if [ -d "$${d}" ] ; then \ env $($(PLATFORM)_copyimg_env) \ $(MU_BUILD_ROOT_DIR)/copyimg $${d} $${inst_dir} ; \ fi ; \ done ; \ : run package dependent install script ; \ $(if $($(1)_image_install), \ $(image_install_functions) \ cd $${inst_dir} ; \ $($(1)_image_install)) .PHONY: %-image_install %-image_install: %-install $(call image_install_fn,$(PACKAGE),$(PACKAGE_INSTALL_DIR)) basic_system_image_include = \ $(call ifdef_fn,$(PLATFORM)_basic_system_image_include, \ echo bin/ldd ; \ echo $(arch_lib_dir)/ld*.so* ; \ $(call find_shared_libs_fn, $(arch_lib_dir))) basic_system_image_install = \ mkdir -p bin lib mnt proc root sbin sys tmp etc ; \ mkdir -p usr usr/{bin,sbin} usr/lib ; \ mkdir -p var var/{lib,lock,log,run,tmp} ; \ mkdir -p var/lock/subsys var/lib/urandom .PHONY: basic_system-image_install basic_system-image_install: # linuxrc-install $(if $(not_native), \ $(call image_install_fn,basic_system,$(TARGET_TOOL_INSTALL_DIR)),) ROOT_PACKAGES = $(if $($(PLATFORM)_root_packages),$($(PLATFORM)_root_packages),$(default_root_packages)) .PHONY: install-packages install-packages: $(patsubst %,%-find-source,$(ROOT_PACKAGES)) @$(BUILD_ENV) ; \ set -eu$(BUILD_DEBUG) ; \ d=$(MU_BUILD_ROOT_DIR)/packages-$(PLATFORM) ; \ rm -rf $${d} ; \ mkdir -p $${d}; \ $(MAKE) -C $(MU_BUILD_ROOT_DIR) IMAGE_INSTALL_DIR=$${d} \ $(patsubst %,%-image_install, \ basic_system \ $(ROOT_PACKAGES)) || exit 1; \ $(call build_msg_fn, Relocating ELF executables to run in $${d}) ; \ scripts/set-rpath $${d} $${d}/$(arch_lib_dir) ; \ : strip symbols from files ; \ if [ $${strip_symbols:-no} = 'yes' ] ; then \ $(call build_msg_fn, Stripping symbols from files) ; \ find $${d} -type f \ -exec \ $(TARGET_PREFIX)strip \ --strip-unneeded '{}' ';' \ >& /dev/null ; \ else \ $(call build_msg_fn, NOT stripping symbols) ; \ fi # readonly root squashfs image # Note: $(call build_msg_fn) does not seem to work inside of fakeroot so we use echo .PHONY: ro-image $(PLATFORM_IMAGE_DIR)/ro.img ro-image: $(patsubst %,%-find-source,$(ROOT_PACKAGES)) @$(BUILD_ENV) ; \ d=$(PLATFORM_IMAGE_DIR) ; \ mkdir -p $$d; \ ro_image=$$d/ro.img ; \ rm -f $${ro_image} ; \ tmp_dir="`mktemp -d $$d/ro-image-XXXXXX`" ; \ chmod 0755 $${tmp_dir} ; \ cd $${tmp_dir} ; \ trap "rm -rf $${tmp_dir}" err ; \ fakeroot /bin/bash -c "{ \ set -eu$(BUILD_DEBUG) ; \ $(MAKE) -C $(MU_BUILD_ROOT_DIR) IMAGE_INSTALL_DIR=$${tmp_dir} \ $(patsubst %,%-image_install, \ basic_system \ $(ROOT_PACKAGES)) ; \ : make dev directory ; \ $(linuxrc_makedev) ; \ echo @@@@ Relocating ELF executables to run in / @@@@ ; \ scripts/set-rpath /$(arch_lib_dir):/lib ; \ : strip symbols from files ; \ if [ '$${strip_symbols:-yes}' = 'yes' ] ; then \ echo @@@@ Stripping symbols from files @@@@ ; \ find $${tmp_dir} -type f \ -exec \ $(TARGET_PREFIX)strip \ --strip-unneeded '{}' ';' \ >& /dev/null ; \ else \ echo @@@@ NOT stripping symbols @@@@ ; \ fi ; \ if [ $${sign_executables:-yes} = 'yes' \ -a -n "$($(PLATFORM)_public_key)" ] ; then \ echo @@@@ Signing executables @@@@ ; \ find $${tmp_dir} -type f \ | xargs sign $($(PLATFORM)_public_key) \ $($(PLATFORM)_private_key_passphrase) ; \ fi ; \ : make read-only file system ; \ mksquashfs \ $${tmp_dir} $${ro_image} \ -no-exports -no-progress -no-recovery ; \ }" ; \ : cleanup tmp directory ; \ rm -rf $${tmp_dir} MKFS_JFFS2_BYTE_ORDER_x86_64 = -l MKFS_JFFS2_BYTE_ORDER_i686 = -l MKFS_JFFS2_BYTE_ORDER_ppc = -b MKFS_JFFS2_BYTE_ORDER_mips = -b MKFS_JFFS2_BYTE_ORDER_native = $(MKFS_JFFS2_BYTE_ORDER_$(NATIVE_ARCH)) MKFS_JFFS2_SECTOR_SIZE_IN_KBYTES = \ $(call ifdef_fn,$(PLATFORM)_jffs2_sector_size_in_kbytes,256) mkfs_fn_jffs2 = mkfs.jffs2 \ --eraseblock=$(MKFS_JFFS2_SECTOR_SIZE_IN_KBYTES)KiB \ --root=$(1) --output=$(2) \ $(MKFS_JFFS2_BYTE_ORDER_$(BASIC_ARCH)) # As things stand the actual initrd size parameter # is set in .../open-repo/build-data/packages/linuxrc.mk. EXT2_RW_IMAGE_SIZE=notused mkfs_fn_ext2 = \ e2fsimage -d $(1) -f $(2) -s $(EXT2_RW_IMAGE_SIZE) RW_IMAGE_TYPE=jffs2 make_rw_image_fn = \ $(call mkfs_fn_$(RW_IMAGE_TYPE),$(1),$(2)) rw_image_embed_ro_image_fn = \ mkdir -p proc initrd images ro rw union ; \ cp $(PLATFORM_IMAGE_DIR)/$(1) images/$(1) ; \ md5sum images/$(1) > images/$(1).md5 ; \ echo Built by $(LOGNAME) at `date` > images/$(1).stamp ; \ mkdir -p changes/$(1) # make sure RW_IMAGE_TYPE is a type we know how to build .PHONY: rw-image-check-type rw-image-check-type: @$(BUILD_ENV) ; \ if [ -z "$(make_rw_image_fn)" ] ; then \ $(call build_msg_fn,Unknown read/write fs image type; \ try RW_IMAGE_TYPE=ext2 or RW_IMAGE_TYPE=jffs2) ; \ exit 1; \ fi # read write image .PHONY: rw-image rw-image: rw-image-check-type ro-image @$(BUILD_ENV) ; \ d=$(PLATFORM_IMAGE_DIR) ; \ mkdir -p $$d ; \ rw_image="$$d/rw.$(RW_IMAGE_TYPE)" ; \ ro_image="ro.img" ; \ rm -f $$rw_image ; \ tmp_dir="`mktemp -d $$d/rw-image-XXXXXX`" ; \ chmod 0755 $${tmp_dir} ; \ cd $${tmp_dir} ; \ trap "rm -rf $${tmp_dir}" err ; \ fakeroot /bin/bash -c "{ \ set -eu$(BUILD_DEBUG) ; \ $(linuxrc_makedev) ; \ $(call rw_image_embed_ro_image_fn,$${ro_image}) ; \ $(call make_rw_image_fn,$${tmp_dir},$${rw_image}) ; \ }" ; \ : cleanup tmp directory ; \ rm -rf $${tmp_dir} images: linuxrc-install linux-install $(image_extra_dependencies) rw-image @$(BUILD_ENV) ; \ d=$(PLATFORM_IMAGE_DIR) ; \ cd $(BUILD_DIR)/linux-$(PLATFORM) ; \ i="" ; \ [[ -z $$i && -f bzImage ]] && i=bzImage ; \ [[ -z $$i && -f zImage ]] && i=zImage ; \ [[ -z $$i && -f linux ]] && i=linux ; \ [[ -z $$i && -f vmlinux ]] && i=vmlinux ; \ [[ -z $$i ]] \ && $(call build_msg_fn,no linux image to install \ in $(BUILD_DIR)/linux-$(PLATFORM)) \ && exit 1 ; \ cp $$i $$d ###################################################################### # Tool chain build/install ###################################################################### .PHONY: ccache-install ccache-install: $(MAKE) -C $(MU_BUILD_ROOT_DIR) ccache-build mkdir -p $(TOOL_INSTALL_DIR)/ccache-bin ln -sf $(MU_BUILD_ROOT_DIR)/build-tool-native/ccache/ccache \ $(TOOL_INSTALL_DIR)/ccache-bin/$(TARGET_PREFIX)gcc TOOL_MAKE = $(MAKE) is_build_tool=yes tool_make_target_fn = \ $(if $(strip $(NATIVE_TOOLS)), \ $(TOOL_MAKE) $(patsubst %,%-$(1),$(NATIVE_TOOLS)) ARCH=native || exit 1 ;) \ $(TOOL_MAKE) $(patsubst %,%-$(1),$(CROSS_TOOLS)) .PHONY: install-tools install-tools: $(call tool_make_target_fn,install) .PHONY: bootstrap-tools bootstrap-tools: $(TOOL_MAKE) make-install findutils-install git-install \ automake-install autoconf-install libtool-install fakeroot-install ###################################################################### # Clean ###################################################################### package_clean_script = \ @$(call build_msg_fn, Cleaning $* in $(PACKAGE_INSTALL_DIR)) ; \ $(BUILD_ENV) ; \ $(if $(is_build_tool),,rm -rf $(PACKAGE_INSTALL_DIR) ;) \ rm -rf $(TIMESTAMP_DIR)/$(call timestamp_name_fn,*) ; \ $(if $($(PACKAGE)_clean), \ $($(PACKAGE)_clean), \ $(PACKAGE_MAKE) clean) .PHONY: %-clean %-clean: $(package_clean_script) # Wipe e.g. remove build and install directories for packages. package_wipe_script = \ @message=$(if $(is_build_tool),"Wiping build $(PACKAGE)","Wiping build/install $(PACKAGE)") ; \ $(call build_msg_fn,$$message) ; \ $(BUILD_ENV) ; \ rm -rf $(if $(is_build_tool),$(PACKAGE_BUILD_DIR),$(PACKAGE_INSTALL_DIR) $(PACKAGE_BUILD_DIR)) .PHONY: %-wipe %-wipe: $(package_wipe_script) # Wipe entire build/install area for TAG and PLATFORM .PHONY: wipe-all wipe-all: @$(call build_msg_fn, Wiping $(BUILD_DIR) $(INSTALL_DIR)) ; \ $(BUILD_ENV) ; \ rm -rf $(BUILD_DIR) $(INSTALL_DIR) # Clean everything distclean: rm -rf $(MU_BUILD_ROOT_DIR)/$(BUILD_PREFIX_package)*/ rm -rf $(MU_BUILD_ROOT_DIR)/$(BUILD_PREFIX_tool)* rm -rf $(MU_BUILD_ROOT_DIR)/$(INSTALL_PREFIX)* rm -rf $(MU_BUILD_ROOT_DIR)/$(IMAGES_PREFIX)* rm -rf $(TOOL_INSTALL_DIR) rm -rf $(MU_BUILD_ROOT_DIR)/*.deb rm -rf $(MU_BUILD_ROOT_DIR)/*.rpm rm -rf $(MU_BUILD_ROOT_DIR)/*.changes rm -rf $(MU_BUILD_ROOT_DIR)/*.buildinfo