blob: d0922e0f264a79904458435e6969193e4748f693 [file] [log] [blame]
#
# Copyright (c) 2010-2012 Nest Labs, Inc.
# All rights reserved.
#
# This document is the property of Nest. It is considered
# confidential and proprietary information.
#
# This document may not be reproduced or transmitted in any form,
# in whole or in part, without the express written permission of
# Nest.
#
# Description:
# This file is the makefile for the Linux kernel.
#
.NOTPARALLEL:
include pre.mak
PackageRoot := .
PackageSeparator :=
PackageSourceDir := $(PackageRoot)/$(LinuxPackageName)
PackageBuildConfig := $(call GenerateBuildPaths,.config)
PackageBuildMakefile := $(call GenerateBuildPaths,Makefile)
CleanPaths += $(PackageLicenseFile)
UBootFolder := fw/u-boot
UBootMkimage := bin/mkimage
MKIMAGE := $(call GenerateResultPaths,$(UBootFolder),$(UBootMkimage))
MAKE_FIT := ${BuildRoot}/boot/usb-loader-imx/scripts/make_fit.sh
CP := cp
#
# Configuration
#
# Kernel default configuration is handled from most-specific to
# least-specific, as follows:
#
# Out-of-tree:
#
# 1) If configs/$(BuildProduct)/$(BuildConfig)_defconfig exists,
# it is used.
# 2) If configs/$(BuildProduct)/defconfig exists, it is used.
# 3) If configs/$(BuildConfig)_defconfig exists, it is used.
# 4) If configs/defconfig exists, it is used.
#
# In-tree:
#
# 5) If none of those exist, $(LinuxDefaultConfig) is used, which
# refers to an architecture- and/or board-specific default
# configuration.
#
# We go through this elaborate scheme because, once created, the
# kernel loses all association with it configuration file and the
# source it was created from. As a consequence, if the default
# configuration is edited, the kernel doesn't know about the
# change. This is especially problematic when changing branches or
# receiving updates to the default configuration and the kernel
# doesn't rebuild to reflect those changes.
#
# With this scheme, the user can edit .config as before. However, now
# if the default configuration is changed, out-of-tree only, .config
# is updated and the kernel will rebuild to reflect those changes.
#
PackageConfigDir := configs
PackageProjectConfig := $(PackageConfigDir)/defconfig
PackageConfigConfig := $(PackageConfigDir)/$(BuildConfig)_defconfig
PackageProductConfig := $(PackageConfigDir)/$(BuildProduct)/defconfig
PackageProductConfigConfig := $(PackageConfigDir)/$(BuildProduct)/$(BuildConfig)_defconfig
PackageMaybeProjectConfig := $(wildcard $(PackageProjectConfig))
PackageMaybeConfigConfig := $(wildcard $(PackageConfigConfig))
PackageMaybeProductConfig := $(wildcard $(PackageProductConfig))
PackageMaybeProductConfigConfig := $(wildcard $(PackageProductConfigConfig))
PackageMaybeConfig := $(if $(PackageMaybeProductConfigConfig),$(PackageProductConfigConfig),$(if $(PackageMaybeProductConfig),$(PackageProductConfig),$(if $(PackageMaybeConfigConfig),$(PackageConfigConfig),$(if $(PackageMaybeProjectConfig),$(PackageProjectConfig),))))
PackageSourceConfig := $(if $(PackageMaybeConfig),$(PackageMaybeConfig),)
#
# Specific products may want additional build targets beyond those
# produced by the linux build's 'all' target. Process and establish
# those.
#
LinuxAllTarget := all
LinuxBuildTargets := $(filter-out $(LinuxAllTarget),$(LinuxProductTargets)) $(LinuxAllTarget)
#
# For some architectures, the linux build requires u-boot's host
# 'mkimage' tool. Establish some paths and directories that will be
# used, if present, to help the linux build find it.
#
MkimagePath := $(wildcard $(call GenerateResultPaths,fw/u-boot/bin,mkimage))
MkimageDir := $(call Deslashify,$(dir $(MkimagePath)))
#
# Architecture-specific boot images that may need to be copied from
# the build to the result directory.
#
LinuxBootFolder = arch/$(LinuxProductArch)/boot
LinuxBootDir = $(call GenerateBuildPaths,$(LinuxBootFolder))
LinuxBootBuildPaths = $(call GenerateBuildPaths,$(addprefix $(LinuxBootFolder)/,$(LinuxProductBootFiles)))
LinuxBootResultPaths = $(call GenerateResultPaths,,$(notdir $(LinuxBootBuildPaths)))
LinuxKernelFiles = vmlinux
LinuxKernelFolder = .
LinuxKernelDir = $(call GenerateBuildPaths,$(LinuxKernelFolder))
LinuxKernelBuildPaths = $(call GenerateBuildPaths,$(addprefix $(call Slashify,$(LinuxKernelFolder)),$(LinuxKernelFiles)))
LinuxKernelResultPaths = $(call GenerateResultPaths,,$(notdir $(LinuxKernelBuildPaths)))
LinuxDtbFolder = arch/$(LinuxProductArch)/boot/dts
LinuxDtbDir = $(call GenerateBuildPaths,$(LinuxDtbFolder))
LinuxDtbBuildPaths = $(call GenerateBuildPaths,$(addprefix $(call Slashify,$(LinuxDtbFolder)),$(LinuxDtbFiles)))
LinuxDtbResultPaths = $(call GenerateResultPaths,,$(notdir $(LinuxDtbBuildPaths)))
ifneq ($(words $(LinuxDtbFiles)), $(words $(LinuxDtbNames)))
$(error The number of DTB files and DTB names for use in the ITB do not match: $(words $(LinuxDtbFiles)) != $(words $(LinuxDtbNames)))
else
# We need to join the list of DTB files and names for make_fit.sh, so it can generate a FIT with all of the DTB files.
# GNU make doesn't do this well (the join function leaves no spaces between the pairs to be joined); this is the most readable solution I could find.
i=0
dtb_list=
$(foreach dtbName, $(LinuxDtbNames), \
$(eval i = $(shell expr $(i) + 1)) \
$(eval dtb_list += $(abspath $(word $(i),$(LinuxDtbBuildPaths))) $(dtbName)) \
)
endif
zImageFile := zImage
zImageFolder := arch/$(LinuxProductArch)/boot
zImageResultPath := $(call GenerateBuildPaths,$(addprefix $(call Slashify,$(zImageFolder)),$(zImageFile)))
LinuxItbFolder = arch/$(LinuxProductArch)/boot
LinuxItbBuildPaths = $(call GenerateBuildPaths,$(addprefix $(call Slashify,$(LinuxItbFolder)),$(LinuxItbResultFile)))
LinuxItbResultPaths = $(call GenerateResultPaths,,$(LinuxItbResultFile))
LinuxConfigsDir = $(PackageSourceDir)/arch/arm/configs
#
# Common make arguments shared by all Linux target commands
#
LinuxCommonMakeArgs = $(JOBSFLAG) -C $(PackageSourceDir) O=$(CURDIR)/$(BuildDirectory) ARCH=$(LinuxProductArch)
all: $(PackageDefaultGoal)
# Generate the package license contents.
$(PackageSourceDir)/COPYING: source
$(PackageLicenseFile): $(PackageSourceDir)/COPYING
$(copy-result)
# We are building this package from version-controller source, so
# there is nothing to do for this target goal.
$(PackageSourceDir):
# Prepare the sources.
.PHONY: source
source: | $(PackageSourceDir)
# Patch the sources, if necessary.
.PHONY: patch
patch: source
# The Linux kernel build has no way of explicitly setting CC, LD,
# OBJCOPY, et al and instead relies on the value of
# CROSS_COMPILE. Consequently, we have to ensure that 'ToolBinDir' is
# in 'PATH' so that the kernel build infrastructure can find
# $(CROSS_COMPILE)gcc, $(CROSS_COMPILE)ld, et al.
#
# Additionally, per the above, add the path to U-Boot's 'mkimage' if
# the variable is defined.
configure build images stage stage-modules: PATH := $(PATH):$(ToolBinDir)$(if $(MkimageDir),:$(MkimageDir),)
CROSS_COMPILE:= $(CCACHE) $(CROSS_COMPILE)
# Generate the Linux build configuration and make file
#
# We are either copying and out-of-tree configuration or using an
# in-tree default (see above).
# $(PackageBuildConfig): help-defconfig
ifeq ($(PackageSourceConfig),)
DefconfigBasename=$(subst _defconfig,,$(LinuxDefaultConfig))
ConfigFragment=$(DefconfigBasename)_$(BuildConfig)_fragment
$(PackageBuildConfig): $(LinuxConfigsDir)/$(LinuxDefaultConfig) $(LinuxConfigsDir)/$(ConfigFragment) | $(BuildDirectory)
$(Echo) "The default Linux build configuration is \"$(LinuxDefaultConfig)\"."
$(Verbose)$(MAKE) $(LinuxCommonMakeArgs) $(LinuxDefaultConfig)
$(Echo) "Applying config fragment \"$(ConfigFragment)\"."
$(PackageSourceDir)/scripts/kconfig/merge_config.sh -O $(BuildDirectory) -m $(BuildDirectory)/.config $(LinuxConfigsDir)/$(ConfigFragment)
$(Echo) "Setting unspecified options to defaults"
$(Verbose) yes " " | $(MAKE) $(LinuxCommonMakeArgs) oldconfig
else
$(PackageBuildConfig): $(PackageSourceConfig) | $(PackageSourceDir) $(BuildDirectory)
$(Echo) "The default Linux build configuration is \"$(PackageSourceConfig)\"."
$(copy-result)
endif
# Configure the source for building.
.PHONY: configure
configure: source $(PackageBuildConfig)
# Build the source.
.PHONY: build
build: configure images
# Build the linux kernel images, including vmlinux (ELF).
.PHONY: images
images: configure | $(BuildDirectory)
$(Verbose)$(MAKE) $(LinuxCommonMakeArgs) $(LinuxProductMakeArgs) $(LinuxBuildTargets) $(LinuxDtbFiles)
$(LinuxItbBuildPaths) : images
$(Verbose)$(MAKE_FIT) $(MKIMAGE) \
$(abspath $(zImageResultPath)) \
NULL \
"$(KernelSigningKeyName)" \
"$(KernelSigningKeyURL)" \
$(LinuxItbBuildPaths) \
$(dtb_list) # Combine the kernel and DTBs into a FIT
# Stage the build to a temporary installation area.
.PHONY: stage stage-boot stage-modules stage-headers
stage: stage-boot stage-modules stage-headers
stage-boot stage-modules stage-headers: build | $(ResultDirectory)
stage-modules:
$(Verbose)$(MAKE) $(LinuxCommonMakeArgs) INSTALL="$(INSTALL) $(INSTALLFLAGS)" INSTALL_MOD_PATH=$(ResultDirectory) DEPMOD=$(DEPMOD) modules_install
stage-headers:
$(Verbose)$(MAKE) $(LinuxCommonMakeArgs) INSTALL="$(INSTALL) $(INSTALLFLAGS)" INSTALL_HDR_PATH=$(ResultDirectory) headers_install
$(LinuxBootResultPaths): $(ResultDirectory)/%: $(LinuxBootDir)/%
$(copy-result)
$(LinuxKernelResultPaths): $(ResultDirectory)/%: $(LinuxKernelDir)/%
$(copy-result)
$(LinuxDtbResultPaths): $(ResultDirectory)/%: $(LinuxDtbDir)/%
$(copy-result)
$(LinuxItbResultPaths): $(LinuxItbBuildPaths)
$(copy-result)
stage-boot: $(LinuxDtbResultPaths) $(LinuxItbResultPaths) $(LinuxBootResultPaths) $(LinuxKernelResultPaths)
clean:
$(Verbose)$(RM) $(RMFLAGS) -r $(BuildDirectory)
$(Verbose)$(RM) $(RMFLAGS) -r $(ResultDirectory)
.PHONY: help help-defconfig
help-defconfig:
$(echo-defconfig)
help: help-defconfig
include post.mak