当前仓库属于关闭状态,部分功能使用受限,详情请查阅 仓库状态说明
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
Makefile 45.11 KB
一键复制 编辑 原始数据 按行查看 历史
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277
# Makefile for Unikraft
#
# Copyright (C) 1999-2005 by Erik Andersen <andersen@codepoet.org>
# Copyright (C) 2006-2014 by the Buildroot developers <buildroot@uclibc.org>
# Copyright (C) 2014-2016 by the Buildroot developers <buildroot@buildroot.org>
# Copyright (C) 2016-2017 by NEC Europe Ltd. <simon.kuenzer@neclab.eu>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
HOSTOSENV := $(shell uname)
# Set initial and basic tools that we need to operate
ifeq ($(HOSTOSENV),Darwin)
SED := gsed
else
SED := sed
endif
# Trick for always running with a fixed umask
UMASK = 0022
ifneq ($(shell umask),$(UMASK))
.PHONY: _all $(MAKECMDGOALS)
$(MAKECMDGOALS): _all
@:
_all:
@umask $(UMASK) && $(MAKE) --no-print-directory $(MAKECMDGOALS)
else # umask
# This is our default rule, so must come first
.PHONY: all
all:
# Disable built-in rules
.SUFFIXES:
# Enable secondary expansion
.SECONDEXPANSION:
# Save running make version
RUNNING_MAKE_VERSION := $(MAKE_VERSION)
# Check for minimal make version (note: this check will break at make 10.x)
MIN_MAKE_VERSION = 4.1
ifneq ($(firstword $(sort $(RUNNING_MAKE_VERSION) $(MIN_MAKE_VERSION))),$(MIN_MAKE_VERSION))
ifneq ($(HOSTOSENV),Darwin)
$(error You have make '$(RUNNING_MAKE_VERSION)' installed. GNU make >= $(MIN_MAKE_VERSION) is required)
else
$(error We need GNU make >= $(MIN_MAKE_VERSION). It can be installed with 'brew install make'. Retry with: 'gmake $(MAKECMDGOALS)')
endif
endif
# Strip quotes and then whitespaces
qstrip = $(strip $(subst ",,$(1)))
#"))
# Variables for use in Make constructs
comma := ,
empty :=
space := $(empty) $(empty)
plus := $(call qstrip,"+")
# bash prints the name of the directory on 'cd <dir>' if CDPATH is
# set, so unset it here to not cause problems. Notice that the export
# line doesn't affect the environment of $(shell ..) calls, so
# explictly throw away any output from 'cd' here.
export CDPATH :=
# To put more focus on warnings, be less verbose as default
# Use 'make V=1' to see the full commands
# Set KBUILD_VERBOSE and Q to quiet mode
KBUILD_VERBOSE := 0
Q := @
ifeq ("$(origin V)", "command line")
BUILD_VERBOSE = $(V)
endif
ifndef BUILD_VERBOSE
BUILD_VERBOSE = 0
endif
ifneq ($(BUILD_VERBOSE),0)
KBUILD_VERBOSE := 1
Q :=
endif
# Enable warnings about undefined variables
# with verbosity level 2
ifeq ($(BUILD_VERBOSE),2)
MAKEFLAGS+=--warn-undefined-variables
endif
# Helper that shows an `info` message only
# when verbose mode is on
# verbose_info $verbosemessage
ifneq ($(BUILD_VERBOSE),0)
verbose_info = $(info $(1))
else
verbose_info =
endif
# Use current directory as base
CONFIG_UK_BASE ?= $(CURDIR)
override CONFIG_UK_BASE := $(realpath $(CONFIG_UK_BASE))
ifeq ($(CONFIG_UK_BASE),)
$(error "Invalid base directory (CONFIG_UK_BASE)")
endif
# parameter A: APP_DIR ###
# Set A variable if not already done on the command line;
ifneq ("$(origin A)", "command line")
override A := $(CONFIG_UK_BASE)
else
ifeq ("$(filter /%,$(A))", "")
$(error Path to app directory (A) is not absolute)
endif
endif
# Remove the trailing '/.'
# Also remove the trailing '/' the user can set when on the command line.
override A := $(realpath $(patsubst %/,%,$(patsubst %.,%,$(A))))
ifeq ($(A),)
$(error Invalid app directory (A))
endif
override CONFIG_UK_APP := $(A)
override APP_DIR := $(A)
override APP_BASE := $(A)
# parameter O: BUILD_DIR ###
# Use O variable if set on the command line, otherwise use $(A)/build;
ifneq ("$(origin O)", "command line")
_O := $(APP_BASE)/build
else
ifeq ("$(filter /%,$(O))", "")
$(error Path to output directory (O) is not absolute)
endif
_O := $(realpath $(dir $(O)))/$(notdir $(O))
endif
BUILD_DIR := $(shell mkdir -p $(_O) && cd $(_O) >/dev/null && pwd)
$(if $(BUILD_DIR),, $(error could not create directory "$(_O)"))
BUILD_DIR := $(realpath $(patsubst %/,%,$(patsubst %.,%,$(BUILD_DIR))))
override O := $(BUILD_DIR)
# parameter C: UK_CONFIG ###
# Use C variable if set on the command line, otherwise use $(A)/.config;
ifneq ("$(origin C)", "command line")
ifeq ("$(origin C)", "undefined")
override C := $(CONFIG_UK_APP)/.config
endif
else
ifeq ("$(filter /%,$(C))", "")
$(error Path to configuration file (C) is not absolute)
endif
override C := $(realpath $(dir $(C)))/$(notdir $(C))
endif
UK_CONFIG := $(C)
CONFIG_DIR := $(dir $(C))
# As UK_CONFIG could be different files, always assume it has a newer version
.PHONY: $(UK_CONFIG)
# EPLAT_DIR (list of external platform libraries)
# Retrieved from P variable from the command line (paths separated by colon)
ifeq ("$(origin P)", "command line")
$(foreach ITR,$(subst :, ,$(P)), \
$(if $(filter /%,$(ITR)),,$(error Path to external platform "$(ITR)" (P) is not absolute));\
$(if $(wildcard $(ITR)), \
$(eval EPLAT_DIR += $(realpath $(patsubst %/,%,$(patsubst %.,%,$(ITR))))), \
$(error Cannot find platform library: $(ITR)) \
) \
)
endif
EPLAT_DIR := $(realpath $(patsubst %/,%,$(patsubst %.,%,$(EPLAT_DIR))))
# ELIB_DIR (list of external libraries)
# Retrieved from L variable from the command line (paths separated by colon)
ifeq ("$(origin L)", "command line")
# library path exists?
$(foreach ITR,$(subst :, ,$(L)), \
$(if $(filter /%,$(ITR)),,$(error Path to external library "$(ITR)" (L) is not absolute));\
$(if $(wildcard $(ITR)), \
$(eval ELIB_DIR += $(realpath $(patsubst %/,%,$(patsubst %.,%,$(ITR))))), \
$(error Cannot find library: $(ITR)) \
) \
)
endif
ELIB_DIR := $(realpath $(patsubst %/,%,$(patsubst %.,%,$(ELIB_DIR))))
# IMPORT_EXCLUDEDIRS (list of (library) paths to exclude)
# Retrieved from E variable from the command line
# (paths are separated by colon)
KCONFIG_EXCLUDEDIRS:=
IMPORT_EXCLUDEDIRS:=
ifeq ("$(origin E)", "command line")
$(foreach ITR,$(subst :, ,$(E)), \
$(if $(filter /%,$(ITR)),,$(error Path to library to exclude "$(ITR)" (E) is not absolute));\
$(if $(wildcard $(ITR)), \
$(eval IMPORT_EXCLUDEDIRS += $(realpath $(patsubst %/,%,$(patsubst %.,%,$(ITR))))) \
$(eval KCONFIG_EXCLUDEDIRS = $(KCONFIG_EXCLUDEDIRS)$(colon)$(realpath $(patsubst %/,%,$(patsubst %.,%,$(ITR))))), \
$(error Cannot find library for exclusion: $(ITR)) \
) \
)
endif
$(call verbose_info,* Unikraft base: $(CONFIG_UK_BASE))
$(call verbose_info,* Configuration: $(UK_CONFIG))
$(call verbose_info,* Application base: $(CONFIG_UK_APP))
$(call verbose_info,* External platforms: [ $(EPLAT_DIR) ])
$(call verbose_info,* External libraries: [ $(ELIB_DIR) ])
$(call verbose_info,* Import excludes: [ $(IMPORT_EXCLUDEDIRS) ])
$(call verbose_info,* Build output: $(BUILD_DIR))
build_dir_make := 0
ifneq ($(BUILD_DIR),$(UK_BASE))
build_dir_make := 1;
else
sub_make_exec := 1;
endif
# KConfig settings
CONFIG_UK_PLAT := $(CONFIG_UK_BASE)/plat/
CONFIG_UK_LIB := $(CONFIG_UK_BASE)/lib/
CONFIG_UK_DRIV := $(CONFIG_UK_BASE)/drivers/
CONFIG_CONFIG_IN := $(CONFIG_UK_BASE)/Config.uk
CONFIG := $(CONFIG_UK_BASE)/support/kconfig
CONFIGLIB := $(CONFIG_UK_BASE)/support/kconfiglib
UK_CONFIG_OUT := $(BUILD_DIR)/config
UK_GENERATED_INCLUDES := $(BUILD_DIR)/include
KCONFIG_INCLUDES_DIR := $(UK_GENERATED_INCLUDES)/uk/bits
KCONFIG_DIR := $(BUILD_DIR)/kconfig
UK_FIXDEP := $(KCONFIG_DIR)/fixdep
KCONFIG_AUTOCONFIG := $(KCONFIG_DIR)/auto.conf
KCONFIG_TRISTATE := $(KCONFIG_DIR)/tristate.config
KCONFIG_AUTOHEADER := $(KCONFIG_INCLUDES_DIR)/config.h
KCONFIG_LIB_BASE := $(CONFIG_UK_BASE)/lib
KCONFIG_ELIB_DIRS := $(L)
KCONFIG_PLAT_BASE := $(CONFIG_UK_BASE)/plat
KCONFIG_EPLAT_DIRS := $(P)
KCONFIG_DRIV_BASE := $(CONFIG_UK_BASE)/drivers
ifneq ($(CONFIG_UK_BASE),$(CONFIG_UK_APP))
KCONFIG_EAPP_DIR := $(CONFIG_UK_APP)
else
KCONFIG_EAPP_DIR :=
endif
# Makefile support scripts
SCRIPTS_DIR := $(CONFIG_UK_BASE)/support/scripts
# # Set and export the version string
$(call verbose_info,Including $(CONFIG_UK_BASE)/version.mk...)
include $(CONFIG_UK_BASE)/version.mk
# Compute the full local version string so packages can use it as-is
# Need to export it, so it can be got from environment in children (eg. mconf)
ifdef UK_EXTRAVERSION
export UK_FULLVERSION := $(UK_VERSION).$(UK_SUBVERSION).$(UK_EXTRAVERSION)$(shell cd $(CONFIG_UK_BASE); $(SCRIPTS_DIR)/gitsha1)
else
export UK_FULLVERSION := $(UK_VERSION).$(UK_SUBVERSION)$(shell cd $(CONFIG_UK_BASE); $(SCRIPTS_DIR)/gitsha1)
endif
# Makefile targets
null_targets := print-version print-vars help
nokconfig_targets := properclean distclean $(null_targets)
noconfig_targets := ukconfig menuconfig nconfig gconfig xconfig config \
oldconfig defconfig olddefconfig savedefconfig \
randconfig allyesconfig allnoconfig \
scriptconfig iscriptconfig kmenuconfig guiconfig \
dumpvarsconfig \
$(nokconfig_targets)
# we want bash as shell
SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
else if [ -x /bin/bash ]; then echo /bin/bash; \
else echo sh; fi; fi)
# basic tools
RM := rm -f
MV := mv -f
CP := cp -f
MKDIR := mkdir
TOUCH := touch
XARGS := xargs
# kconfig uses CONFIG_SHELL
CONFIG_SHELL := $(SHELL)
export SHELL CONFIG_SHELL Q KBUILD_VERBOSE
################################################################################
# Create minimal necessary folder structure
################################################################################
# Create them before trying to include a .config
ifeq ($(filter $(nokconfig_targets),$(MAKECMDGOALS)),)
$(if $(shell $(MKDIR) -pv $(KCONFIG_DIR) && cd $(KCONFIG_DIR) >/dev/null && pwd),,\
$(error Could not create $(KCONFIG_DIR)))
$(if $(shell $(MKDIR) -pv $(UK_GENERATED_INCLUDES) && cd $(KCONFIG_DIR) >/dev/null && pwd),,\
$(error Could not create $(UK_GENERATED_INCLUDES)))
$(if $(shell $(MKDIR) -pv $(KCONFIG_INCLUDES_DIR) && cd $(KCONFIG_DIR) >/dev/null && pwd),,\
$(error Could not create $(KCONFIG_INCLUDES_DIR)))
endif
################################################################################
# .config
################################################################################
# Initialize important internal variables
UK_FETCH:=
UK_FETCH-y:=
UK_PREPARE:=
UK_PREPARE-y:=
UK_PREPROCESS:=
UK_PREPROCESS-y:=
UK_PLATS:=
UK_PLATS-y:=
UK_LIBS:=
UK_LIBS-y:=
UK_ALIBS:=
UK_ALIBS-y:=
UK_OLIBS:=
UK_OLIBS-y:=
UK_SRCS:=
UK_SRCS-y:=
UK_DEPS:=
UK_DEPS-y:=
UK_OBJS:=
UK_OBJS-y:=
UK_IMAGES:=
UK_IMAGES-y:=
UK_CLEAN :=
UK_CLEAN-y :=
ARCHFLAGS :=
ARCHFLAGS-y :=
ISR_ARCHFLAGS :=
ISR_ARCHFLAGS-y :=
COMPFLAGS :=
COMPFLAGS-y :=
ASFLAGS :=
ASFLAGS-y :=
ASINCLUDES :=
ASINCLUDES-y :=
CFLAGS :=
CFLAGS-y :=
CINCLUDES :=
CINCLUDES-y :=
CXXFLAGS :=
CXXFLAGS-y :=
CXXINCLUDES :=
CXXINCLUDES-y :=
GOCFLAGS :=
GOCFLAGS-y :=
RUSTCFLAGS :=
RUSTCFLAGS-y :=
GOCINCLUDES :=
GOCINCLUDES-y :=
DBGFLAGS :=
DBGFLAGS-y :=
LDFLAGS :=
LDFLAGS-y :=
IMAGE_LDFLAGS :=
IMAGE_LDFLAGS-y :=
EACHOLIB_SRCS :=
EACHOLIB_SRCS-y :=
EACHOLIB_OBJS :=
EACHOLIB_OBJS-y :=
EACHOLIB_ALIBS :=
EACHOLIB_ALIBS-y :=
EACHOLIB_LOCALS :=
EACHOLIB_LOCALS-y :=
# Pull in the user's configuration file
ifeq ($(filter $(noconfig_targets),$(MAKECMDGOALS)),)
ifneq ("$(wildcard $(UK_CONFIG))","")
$(call verbose_info,Including $(UK_CONFIG)...)
-include $(UK_CONFIG)
UK_HAVE_DOT_CONFIG := y
endif
endif
# parameter N: UK_NAME ###
# # Use N variable if set on the command line, otherwise use directory name
ifeq ("$(origin N)", "command line")
CONFIG_UK_NAME := $(N)
else
CONFIG_UK_NAME ?= $(notdir $(APP_DIR))
endif
# Option to overwrite file name of generated images by supported platforms. The
# target platform has to support this feature. When unset or unsupported by the
# platform, the default semantic of the target platform (typically
# `$(UK_NAME)_$(PLAT)_$(ARCH)`) will be used.
#
# NOTE: Please note that multi-platform builds do not work anymore when this
# option is used. The reason is that the build system will generate the
# same file by each selected platform. Make won't be able to proceed
# building.
# NOTE: This feature is currently used by kraftkit.
ifneq ($(call qstrip,$(UK_IMAGE_NAME_OVERWRITE)),)
UK_IMAGE_NAME_OVERWRITE := $(call qstrip,$(UK_IMAGE_NAME_OVERWRITE))
endif
# remove quotes from CONFIG_UK_NAME
CONFIG_UK_NAME := $(call qstrip,$(CONFIG_UK_NAME))
export CONFIG_UK_NAME
################################################################################
# Host compiler and linker tools
################################################################################
ifndef HOSTAR
HOSTAR := ar
endif
ifndef HOSTAS
HOSTAS := as
endif
ifndef HOSTCC
HOSTCC := gcc
HOSTCC := $(shell which $(HOSTCC) || type -p $(HOSTCC) || echo gcc)
endif
HOSTCC_NOCCACHE := $(HOSTCC)
ifndef HOSTCXX
HOSTCXX := g++
HOSTCXX := $(shell which $(HOSTCXX) || type -p $(HOSTCXX) || echo g++)
endif
HOSTCXX_NOCCACHE := $(HOSTCXX)
ifndef HOSTCPP
HOSTCPP := cpp
endif
ifndef HOSTLD
HOSTLD := ld
endif
ifndef HOSTLN
HOSTLN := ln
endif
ifndef HOSTNM
HOSTNM := nm
endif
ifndef HOSTOBJCOPY
HOSTOBJCOPY := objcopy
endif
ifndef HOSTRANLIB
HOSTRANLIB := ranlib
endif
HOSTAR := $(shell which $(HOSTAR) || type -p $(HOSTAR) || echo ar)
HOSTAS := $(shell which $(HOSTAS) || type -p $(HOSTAS) || echo as)
HOSTCPP := $(shell which $(HOSTCPP) || type -p $(HOSTCPP) || echo cpp)
HOSTLD := $(shell which $(HOSTLD) || type -p $(HOSTLD) || echo ld)
HOSTLN := $(shell which $(HOSTLN) || type -p $(HOSTLN) || echo ln)
HOSTNM := $(shell which $(HOSTNM) || type -p $(HOSTNM) || echo nm)
HOSTOBJCOPY := $(shell which $(HOSTOBJCOPY) || type -p $(HOSTOBJCOPY) || echo objcopy)
HOSTRANLIB := $(shell which $(HOSTRANLIB) || type -p $(HOSTRANLIB) || echo ranlib)
HOSTCC_VERSION := $(shell $(HOSTCC_NOCCACHE) --version | \
$(SED) -n -r 's/^.* ([0-9]*)\.([0-9]*)\.([0-9]*)[ ]*.*/\1 \2/p')
# UTC time in ISO 8601 format:
HOSTUTC := $(shell date -Iseconds -u)
HOSTNAME := $(shell hostname -s)
HOSTUSER := $(shell whoami)
# For gcc >= 5.x, we only need the major version.
ifneq ($(firstword $(HOSTCC_VERSION)),4)
HOSTCC_VERSION := $(firstword $(HOSTCC_VERSION))
endif
# Determine the userland we are running on.
#
export HOSTARCH := $(shell LC_ALL=C $(HOSTCC_NOCCACHE) -v 2>&1 | \
$(SED) -e '/^Target: \([^-]*\).*/!d' \
-e 's//\1/' \
-e 's/i.86/x86/' \
-e 's/sun4u/sparc64/' \
-e 's/arm64.*/arm64/' -e 's/aarch64.*/arm64/' \
-e '/arm64/! s/arm.*/arm/' \
-e 's/sa110/arm/' \
-e 's/ppc64/powerpc64/' \
-e 's/ppc/powerpc/' \
-e 's/macppc/powerpc/' \
-e 's/sh.*/sh/' )
export HOSTAR HOSTAS HOSTCC HOSTCC_VERSION HOSTCXX HOSTLD HOSTARCH
export HOSTCC_NOCCACHE HOSTCXX_NOCCACHE
################################################################################
# Makefile helpers
################################################################################
$(call verbose_info,Including $(CONFIG_UK_BASE)/support/build/Makefile.rules...)
include $(CONFIG_UK_BASE)/support/build/Makefile.rules
# We need to include this file early (before any rule is defined)
# but after we have tried to load a .config and after having our tools defined
$(foreach _M,$(wildcard $(addsuffix Makefile.rules,\
$(CONFIG_UK_BASE)/arch/ $(CONFIG_UK_BASE)/arch/*/ \
$(CONFIG_UK_BASE)/plat/*/ $(CONFIG_UK_BASE)/lib/*/ \
$(CONFIG_UK_BASE)/drivers/*/ $(CONFIG_UK_BASE)/drivers/*/*/ \
$(addsuffix /,$(ELIB_DIR)) $(APP_DIR)/)), \
$(eval $(call verbose_include,$(_M))) \
)
################################################################################
# Clean targets that do not have any dependency on a configuration
################################################################################
# Declare them before we depend on having .config
properclean:
$(call verbose_cmd,RM,$(notdir $(BUILD_DIR)),$(RM) -r \
$(BUILD_DIR))
distclean: properclean
$(call verbose_cmd,RM,config,$(RM) \
$(UK_CONFIG) $(UK_CONFIG).old \
$(CONFIG_DIR)/.$(notdir $(UK_CONFIG)).tmp \
$(CONFIG_DIR)/.auto.deps)
.PHONY: distclean properclean
################################################################################
# Unikraft Architecture
################################################################################
# Set target archicture as set in config
$(eval $(call verbose_include,$(CONFIG_UK_BASE)/arch/Arch.uk))
ifeq ($(CONFIG_UK_ARCH),)
# Set target archicture as set in environment
ifneq ($(ARCH),)
export CONFIG_UK_ARCH ?= $(shell echo "$(call qstrip,$(ARCH))" | \
$(SED) -e "s/-.*//" \
-e 's//\1/' \
-e 's/i.86/x86/' \
-e 's/sun4u/sparc64/' \
-e 's/arm64.*/arm64/' -e 's/aarch64.*/arm64/' \
-e '/arm64/! s/arm.*/arm/' \
-e 's/sa110/arm/' \
-e 's/ppc64/powerpc64/' \
-e 's/ppc/powerpc/' \
-e 's/macppc/powerpc/' \
-e 's/sh.*/sh/' )
else
# Nothing set, use detected host architecture
export CONFIG_UK_ARCH ?= $(shell echo "$(HOSTARCH)" | \
$(SED) -e "s/-.*//" \
-e 's//\1/' \
-e 's/i.86/x86/' \
-e 's/sun4u/sparc64/' \
-e 's/arm64.*/arm64/' -e 's/aarch64.*/arm64/' \
-e '/arm64/! s/arm.*/arm/' \
-e 's/sa110/arm/' \
-e 's/ppc64/powerpc64/' \
-e 's/ppc/powerpc/' \
-e 's/macppc/powerpc/' \
-e 's/sh.*/sh/' )
endif
endif
override ARCH := $(CONFIG_UK_ARCH)
export CONFIG_UK_ARCH ARCH
export UK_FAMILY ?= $(shell echo "$(CONFIG_UK_ARCH)" | \
$(SED) -e "s/-.*//" \
-e 's//\1/' \
-e 's/x86.*/x86/' \
-e 's/sparc64/sparc/' \
-e 's/arm.*/arm/' \
-e 's/powerpc.*/powerpc/' \
-e 's/sh.*/sh/' )
# Quick-check if architecture exists
ifeq ($(filter $(null_targets),$(MAKECMDGOALS)),)
ifeq ($(wildcard $(CONFIG_UK_BASE)/arch/$(UK_FAMILY)/$(ARCH)/Makefile.uk),)
$(error Target architecture ($(ARCH)) is currently not supported (could not find $(CONFIG_UK_BASE)/arch/$(UK_FAMILY)/$(ARCH)/Makefile.uk).)
endif
ifeq ($(wildcard $(CONFIG_UK_BASE)/arch/$(UK_FAMILY)/$(ARCH)/Compiler.uk),)
$(error Target architecture ($(ARCH)) is currently not supported (could not find $(CONFIG_UK_BASE)/arch/$(UK_FAMILY)/$(ARCH)/Compiler.uk).)
endif
endif
################################################################################
# Compiler and linker tools
################################################################################
ifeq ($(sub_make_exec), 1)
ifeq ($(UK_HAVE_DOT_CONFIG),y)
# Hide troublesome environment variables from sub processes
unexport CONFIG_CROSS_COMPILE
unexport CONFIG_LLVM_TARGET_ARCH
unexport CONFIG_COMPILER
#unexport CC
#unexport LD
#unexport AR
#unexport CXX
#unexport CPP
unexport RANLIB
unexport CFLAGS
unexport CXXFLAGS
unexport ARFLAGS
unexport GREP_OPTIONS
unexport TAR_OPTIONS
unexport CONFIG_SITE
unexport QMAKESPEC
unexport TERMINFO
unexport MACHINE
#unexport O
# CONFIG_CROSS_COMPILE specify the prefix used for all executables used
# during compilation. Only gcc and related bin-utils executables
# are prefixed with $(CONFIG_CROSS_COMPILE).
# CONFIG_CROSS_COMPILE can be set on the command line
# make CROSS_COMPILE=ia64-linux-
# Alternatively CONFIG_CROSS_COMPILE can be set in the environment.
# A third alternative is to store a setting in .config so that plain
# "make" in the configured kernel build directory always uses that.
# Default value for CONFIG_CROSS_COMPILE is not to prefix executables
# Note: Some architectures assign CONFIG_CROSS_COMPILE in their arch/*/Makefile.uk
ifneq ("$(origin CROSS_COMPILE)","undefined")
CONFIG_CROSS_COMPILE := $(CROSS_COMPILE:"%"=%)
endif
ifneq ("$(origin LLVM_TARGET_ARCH)","undefined")
CONFIG_LLVM_TARGET_ARCH := $(LLVM_TARGET_ARCH:"%"=%)
endif
ifneq ("$(origin COMPILER)","undefined")
CONFIG_COMPILER := $(COMPILER:"%"=%)
else
CONFIG_COMPILER := gcc
endif
$(eval $(call verbose_include,$(CONFIG_UK_BASE)/arch/$(UK_FAMILY)/Compiler.uk))
# Make variables (CC, etc...)
LD := $(CONFIG_CROSS_COMPILE)$(CONFIG_COMPILER)
CC := $(CONFIG_CROSS_COMPILE)$(CONFIG_COMPILER)
CPP := $(CC)
CXX := $(CPP)
GOC := $(CONFIG_CROSS_COMPILE)gccgo
# We use rustc because the gcc frontend is experimental and missing features such
# as borrowing checking
ifneq ("$(origin LLVM_TARGET_ARCH)","undefined")
RUSTC := rustc --target=$(CONFIG_LLVM_TARGET_ARCH)
else
RUSTC := rustc
endif
AS := $(CC)
AR := $(CONFIG_CROSS_COMPILE)gcc-ar
NM := $(CONFIG_CROSS_COMPILE)gcc-nm
READELF := $(CONFIG_CROSS_COMPILE)readelf
STRIP := $(CONFIG_CROSS_COMPILE)strip
OBJCOPY := $(CONFIG_CROSS_COMPILE)objcopy
OBJDUMP := $(CONFIG_CROSS_COMPILE)objdump
M4 := m4
AR := ar
CAT := cat
# Prefer using GNU AWK because of provided error messages on script errors
ifeq (, $(shell which gawk))
AWK := awk
else
AWK := gawk --lint
endif
ifeq ($(HOSTOSENV),Darwin)
GREP := ggrep
READLINK := greadlink
DIRNAME := gdirname
else
GREP := grep
READLINK := readlink
DIRNAME := dirname
endif
YACC := bison
LEX := flex
PATCH := patch
GZIP := gzip
TAR := tar
UNZIP := unzip -qq -u
GIT := git
WGET := wget
PYTHON := python3
SHA1SUM := sha1sum -b
SHA256SUM := sha256sum -b
SHA512SUM := sha512sum -b
MD5SUM := md5sum -b
DTC := dtc
# Time requires the full path so that subarguments are handled correctly
TIME := $(shell which time)
LIFTOFF := liftoff -e -s
override ARFLAGS:= rcs
CC_INFO := $(shell $(CONFIG_UK_BASE)/support/build/cc-version.sh $(CC))
CC_NAME := $(word 1,$(CC_INFO))
# Retrieve GCC major and minor number from CC_VERSION. They would be used
# to select correct optimization parameters for target CPUs.
CC_VER_MAJOR := $(word 2,$(subst ., ,$(CC_INFO)))
CC_VER_MINOR := $(word 3,$(subst ., ,$(CC_INFO)))
CC_VERSION := $(CC_VER_MAJOR).$(CC_VER_MINOR)
ASFLAGS += -DCC_VERSION=$(CC_VERSION)
CFLAGS += -DCC_VERSION=$(CC_VERSION)
CXXFLAGS += -DCC_VERSION=$(CC_VERSION)
GOCFLAGS += -DCC_VERSION=$(CC_VERSION)
# Add user supplied flags as the last assignments
ASFLAGS += $(UK_ASFLAGS)
CFLAGS += $(UK_CFLAGS)
CXXFLAGS += $(UK_CXXFLAGS)
GOCFLAGS += $(UK_GOCFLAGS)
LDFLAGS += $(UK_LDFLAGS)
ASINCLUDES += -I$(UK_GENERATED_INCLUDES)
CINCLUDES += -I$(UK_GENERATED_INCLUDES)
CXXINCLUDES += -I$(UK_GENERATED_INCLUDES)
GOCINCLUDES += -I$(UK_GENERATED_INCLUDES)
################################################################################
# Build rules
################################################################################
# external application
ifneq ($(CONFIG_UK_BASE),$(CONFIG_UK_APP))
$(eval $(call import_lib,$(CONFIG_UK_APP)));
endif
# internal libraries
$(eval $(call verbose_include,$(CONFIG_UK_BASE)/lib/Makefile.uk))
# external libraries
$(foreach ITR,$(ELIB_DIR), \
$(eval $(call import_lib,$(ITR))); \
)
# architecture library
$(eval $(call import_lib,$(CONFIG_UK_BASE)/arch/$(UK_FAMILY)))
# drivers
$(eval $(call verbose_include,$(CONFIG_UK_BASE)/drivers/Makefile.uk))
# internal platform libraries
$(eval $(call verbose_include,$(CONFIG_UK_BASE)/plat/Makefile.uk))
# external platform libraries
# NOTE: We include them after internal platform libs so that also base variables
# provided with /plat/Makefile.uk are populated
$(foreach ITR,$(EPLAT_DIR), \
$(eval $(call import_lib,$(ITR))); \
)
$(eval $(call verbose_include,$(CONFIG_UK_BASE)/Makefile.uk)) # Unikraft base
ifeq ($(call have_clang),y)
$(call error_if_clang_version_lt,9,0)
endif
ifeq ($(call have_gcc),y)
$(call error_if_gcc_version_lt,7,0)
endif
ifeq ($(call qstrip,$(UK_PLATS) $(UK_PLATS-y)),)
$(warning You did not choose any target platform.)
$(error Please choose at least one target platform in the configuration!)
endif
ifneq ($(CONFIG_HAVE_BOOTENTRY),y)
$(error You did not select a library that handles bootstrapping! (e.g., ukboot))
endif
ifeq ($(CONFIG_OPTIMIZE_LTO), y)
ifeq ($(call have_gcc),y)
ifneq ($(call gcc_version_ge,6,1),y)
$(error Your gcc version does not support incremental link time optimisation)
endif
endif
endif
# Generate build rules
$(eval $(call verbose_include,$(CONFIG_UK_BASE)/support/build/Makefile.build))
$(foreach _M,$(wildcard $(addsuffix Makefile.build,\
$(CONFIG_UK_BASE)/lib/*/ $(CONFIG_UK_BASE)/plat/*/ \
$(addsuffix /,$(ELIB_DIR)) $(APP_DIR)/)), \
$(eval $(call verbose_include,$(_M))) \
)
# Include source dependencies
ifneq ($(call qstrip,$(UK_DEPS) $(UK_DEPS-y)),)
$(foreach _D,$(UK_DEPS) $(UK_DEPS-y),\
$(eval $(call verbose_include_try,$(_D))) \
)
endif
# include Makefile for platform linking (`Linker.uk`)
$(foreach plat,$(UK_PLATS),$(eval $(call import_linker,$(plat))))
.PHONY: prepare preprocess image libs objs clean
fetch: $(UK_FETCH) $(UK_FETCH-y)
# Copy current configuration in order to detect changes
$(UK_CONFIG_OUT): $(UK_CONFIG)
$(call verbose_cmd,CP,config, \
cmp -s $^ $@; if [ $$? -ne 0 ]; then cp $^ $@; fi)
prepare: $(KCONFIG_AUTOHEADER) $(UK_CONFIG_OUT) $(UK_PREPARE) $(UK_PREPARE-y)
prepare: $(UK_FIXDEP) | fetch
preprocess: $(UK_PREPROCESS) $(UK_PREPROCESS-y) | prepare
objs: $(UK_OBJS) $(UK_OBJS-y)
libs: $(UK_ALIBS) $(UK_ALIBS-y) $(UK_OLIBS) $(UK_OLIBS-y)
images: $(UK_DEBUG_IMAGES) $(UK_DEBUG_IMAGES-y) $(UK_IMAGES) $(UK_IMAGES-y)
GDB_HELPER_LINKS := $(addsuffix .gdb.py,$(UK_DEBUG_IMAGES) $(UK_DEBUG_IMAGES-y))
$(GDB_HELPER_LINKS):
$(call verbose_cmd,LN,$(notdir $@),$(HOSTLN) -sf uk-gdb.py $@)
SCRIPTS_DIR_BACKSLASHED = $(subst /,\/,$(SCRIPTS_DIR))
$(BUILD_DIR)/uk-gdb.py: $(SCRIPTS_DIR)/uk-gdb.py
$(call verbose_cmd,GEN,$(notdir $@), \
sed '/scripts_dir = / s/os.path.dirname(os.path.realpath(__file__))/"$(SCRIPTS_DIR_BACKSLASHED)"/g' $^ > $@)
gdb_helpers: $(GDB_HELPER_LINKS) $(BUILD_DIR)/uk-gdb.py
all: images gdb_helpers
################################################################################
# Cleanup rules
################################################################################
# Generate cleaning rules
$(eval $(call verbose_include,$(CONFIG_UK_BASE)/support/build/Makefile.clean))
clean-libs: $(addprefix clean-,\
$(foreach P,$(UK_PLATS) $(UK_PLATS-y),\
$(if $(call qstrip,$($(call uc,$(P))_LIBS) $($(call uc,$(P))_LIBS-y)),\
$(foreach L,$($(call uc,$(P))_LIBS) $($(call uc,$(P))_LIBS-y), $(L)))) $(UK_LIBS) $(UK_LIBS-y))
clean: clean-libs
$(call verbose_cmd,CLEAN,build/,$(RM) \
$(UK_CONFIG_OUT) \
$(call build_clean,\
$(UK_DEBUG_IMAGES) $(UK_DEBUG_IMAGES-y) \
$(UK_IMAGES) $(UK_IMAGES-y)) \
$(GDB_HELPER_LINKS) $(BUILD_DIR)/uk-gdb.py \
$(UK_CLEAN) $(UK_CLEAN-y))
else # !($(UK_HAVE_DOT_CONFIG),y)
$(filter %config,$(MAKECMDGOALS)): $(BUILD_DIR)/Makefile
## ukconfig
ukconfig: $(BUILD_DIR)/Makefile menuconfig
all: ukconfig
.PHONY: prepare image libs objs clean-libs clean ukconfig
fetch: ukconfig
prepare: ukconfig
preprocess: ukconfig
objs: ukconfig
libs: ukconfig
images: ukconfig
clean-libs clean:
$(error Do not know which files to clean without having a configuration. Did you mean 'properclean' or 'distclean'?)
endif
.PHONY: print-vars print-libs print-objs print-srcs print-loc help
# Configuration
# ---------------------------------------------------------------------------
HOSTCFLAGS = $(CFLAGS_FOR_BUILD)
export HOSTCFLAGS
ifeq ($(HOSTOSENV),Linux)
KCONFIG_TOOLS = conf mconf gconf nconf qconf fixdep confdata_test
KCONFIG_TOOLS := $(addprefix $(KCONFIG_DIR)/,$(KCONFIG_TOOLS))
$(KCONFIG_TOOLS):
$(call verbose_cmd,MKDIR,lxdialog,$(MKDIR) -p $(@D)/lxdialog)
$(call verbose_cmd,MAKE,$(notdir $(CONFIG)),$(MAKE) \
--no-print-directory \
CC="$(HOSTCC_NOCCACHE)" HOSTCC="$(HOSTCC_NOCCACHE)" \
YACC="$(YACC)" LEX="$(LEX)" \
obj=$(@D) -C $(CONFIG) -f Makefile.br $(@))
endif
$(UK_FIXDEP):
$(call verbose_cmd,MAKE,$(notdir $(@)),$(MAKE) \
--no-print-directory \
CC="$(HOSTCC_NOCCACHE)" HOSTCC="$(HOSTCC_NOCCACHE)" \
obj=$(@D) -C $(CONFIG) -f Makefile.br $(@))
DEFCONFIG = $(call qstrip,$(UK_DEFCONFIG))
# We don't want to fully expand UK_DEFCONFIG here, so Kconfig will
# recognize that if it's still at its default $(CONFIG_DIR)/defconfig
COMMON_CONFIG_ENV = \
CONFIG_="CONFIG_" \
KCONFIG_CONFIG="$(UK_CONFIG)" \
KCONFIG_AUTOCONFIG="$(KCONFIG_AUTOCONFIG)" \
KCONFIG_AUTOHEADER="$(KCONFIG_AUTOHEADER)" \
KCONFIG_TRISTATE="$(KCONFIG_TRISTATE)" \
HOST_ARCH="$(HOSTARCH)" \
BUILD_DIR="$(BUILD_DIR)" \
UK_BASE="$(CONFIG_UK_BASE)" \
UK_APP="$(CONFIG_UK_APP)" \
UK_CONFIG="$(UK_CONFIG)" \
UK_FULLVERSION="$(UK_FULLVERSION)" \
UK_CODENAME="$(UK_CODENAME)" \
UK_ARCH="$(CONFIG_UK_ARCH)" \
KCONFIG_DIR="$(KCONFIG_DIR)" \
KCONFIG_LIB_BASE="$(KCONFIG_LIB_BASE)" \
KCONFIG_ELIB_DIRS="$(KCONFIG_ELIB_DIRS)" \
KCONFIG_PLAT_BASE="$(KCONFIG_PLAT_BASE)" \
KCONFIG_EPLAT_DIRS="$(KCONFIG_EPLAT_DIRS)" \
KCONFIG_DRIV_BASE="$(KCONFIG_DRIV_BASE)" \
KCONFIG_EAPP_DIR="$(KCONFIG_EAPP_DIR)" \
KCONFIG_EXCLUDEDIRS="$(KCONFIG_EXCLUDEDIRS)" \
UK_NAME="$(CONFIG_UK_NAME)"
PHONY += scriptconfig scriptsyncconfig iscriptconfig kmenuconfig guiconfig \
dumpvarsconfig
KPYTHON := PYTHONPATH=$(UK_CONFIGLIB):$$PYTHONPATH $(PYTHON)
ifneq ($(filter scriptconfig,$(MAKECMDGOALS)),)
ifndef SCRIPT
$(error Use "make scriptconfig SCRIPT=<path to script> [SCRIPT_ARG=<argument>]")
endif
endif
scriptconfig:
$(Q)$(COMMON_CONFIG_ENV) $(KPYTHON) $(SCRIPT) $(Kconfig) $(if $(SCRIPT_ARG),"$(SCRIPT_ARG)")
iscriptconfig:
$(Q)$(COMMON_CONFIG_ENV) $(KPYTHON) -i -c \
"import kconfiglib; \
kconf = kconfiglib.Kconfig('$(UK_CONFIG)'); \
print('A Kconfig instance \'kconf\' for the architecture $(ARCH) has been created.')"
kmenuconfig:
@$(COMMON_CONFIG_ENV) $(KPYTHON) $(CONFIGLIB)/menuconfig.py \
$(CONFIG_CONFIG_IN)
@$(COMMON_CONFIG_ENV) $(SCRIPTS_DIR)/configupdate $(UK_CONFIG) $(UK_CONFIG_OUT)
scriptsyncconfig:
@$(COMMON_CONFIG_ENV) $(KPYTHON) $(CONFIGLIB)/genconfig.py \
--sync-deps=$(BUILD_DIR)/include/config \
--header-path=$(KCONFIG_AUTOHEADER) $(CONFIG_CONFIG_IN)
@$(COMMON_CONFIG_ENV) $(SCRIPTS_DIR)/configupdate $(UK_CONFIG) $(UK_CONFIG_OUT)
guiconfig:
@$(COMMON_CONFIG_ENV) $(KPYTHON) $(CONFIGLIB)/guiconfig.py $(CONFIG_CONFIG_IN)
@$(SCRIPTS_DIR)/configupdate $(UK_CONFIG) $(UK_CONFIG_OUT)
dumpvarsconfig:
$(Q)$(COMMON_CONFIG_ENV) $(KPYTHON) $(CONFIGLIB)/examples/dumpvars.py $(CONFIG_CONFIG_IN)
@$(SCRIPTS_DIR)/configupdate $(UK_CONFIG) $(UK_CONFIG_OUT)
ifneq ($(HOSTOSENV),Linux)
# Use libkconfiglib for non-Linux hosts
# Compatibility wrappers:
menuconfig: kmenuconfig
nconfig: kmenuconfig
gconfig: guiconfig
xconfig: guiconfig
allyesconfig:
@$(COMMON_CONFIG_ENV) $(KPYTHON) $(CONFIGLIB)/allyesconfig.py $(CONFIG_CONFIG_IN)
@$(COMMON_CONFIG_ENV) $(SCRIPTS_DIR)/configupdate $(UK_CONFIG) $(UK_CONFIG_OUT)
allnoconfig:
@$(COMMON_CONFIG_ENV) $(KPYTHON) $(CONFIGLIB)/allnoconfig.py $(CONFIG_CONFIG_IN)
@$(COMMON_CONFIG_ENV) $(SCRIPTS_DIR)/configupdate $(UK_CONFIG) $(UK_CONFIG_OUT)
defconfig:
@$(COMMON_CONFIG_ENV) $(KPYTHON) $(CONFIGLIB)/defconfig.py --kconfig $(CONFIG_CONFIG_IN) $(DEFCONFIG)
@$(COMMON_CONFIG_ENV) $(SCRIPTS_DIR)/configupdate $(UK_CONFIG) $(UK_CONFIG_OUT)
savedefconfig:
@$(COMMON_CONFIG_ENV) $(KPYTHON) $(CONFIGLIB)/savedefconfig.py --kconfig $(CONFIG_CONFIG_IN) --out $(DEFCONFIG)
ifeq ($(HOSTARCH),$(CONFIG_UK_ARCH))
@# Make sure arch is stored in the file even if arch matches between host and config
@echo "$(call ukarch_str2cfg,$(CONFIG_UK_ARCH))=y" >> $(DEFCONFIG)
endif
@echo "CONFIG_UK_NAME=\"$(CONFIG_UK_NAME)\"" >> $(DEFCONFIG)
oldconfig:
@$(COMMON_CONFIG_ENV) $(KPYTHON) $(CONFIGLIB)/oldconfig.py $(CONFIG_CONFIG_IN)
@$(COMMON_CONFIG_ENV) $(SCRIPTS_DIR)/configupdate $(UK_CONFIG) $(UK_CONFIG_OUT)
# Regenerate $(KCONFIG_AUTOHEADER) whenever $(UK_CONFIG) changed
$(KCONFIG_AUTOHEADER): $(UK_CONFIG_OUT)
$(call verbose_cmd,GEN,config.h, \
$(COMMON_CONFIG_ENV) $(KPYTHON) $(CONFIGLIB)/genconfig.py \
--header-path $(KCONFIG_AUTOHEADER) $(CONFIG_CONFIG_IN))
else
# Use traditional KConfig system on Linux
xconfig: $(KCONFIG_DIR)/qconf
@$(COMMON_CONFIG_ENV) $< $(CONFIG_CONFIG_IN)
@$(COMMON_CONFIG_ENV) $(SCRIPTS_DIR)/configupdate $(UK_CONFIG) $(UK_CONFIG_OUT)
gconfig: $(KCONFIG_DIR)/gconf
@$(COMMON_CONFIG_ENV) srctree=$(CONFIG_UK_BASE) $< $(CONFIG_CONFIG_IN)
@$(COMMON_CONFIG_ENV) $(SCRIPTS_DIR)/configupdate $(UK_CONFIG) $(UK_CONFIG_OUT)
menuconfig: $(KCONFIG_DIR)/mconf
@$(COMMON_CONFIG_ENV) $< $(CONFIG_CONFIG_IN)
@$(COMMON_CONFIG_ENV) $(SCRIPTS_DIR)/configupdate $(UK_CONFIG) $(UK_CONFIG_OUT)
nconfig: $(KCONFIG_DIR)/nconf
@$(COMMON_CONFIG_ENV) $< $(CONFIG_CONFIG_IN)
@$(COMMON_CONFIG_ENV) $(SCRIPTS_DIR)/configupdate $(UK_CONFIG) $(UK_CONFIG_OUT)
# For the config targets that automatically select options, we pass
# SKIP_LEGACY=y to disable the legacy options. However, in that case
# no values are set for the legacy options so a subsequent oldconfig
# will query them. Therefore, run an additional olddefconfig.
oldconfig: $(KCONFIG_DIR)/conf
@$(COMMON_CONFIG_ENV) $< --oldconfig $(CONFIG_CONFIG_IN)
@$(COMMON_CONFIG_ENV) $(SCRIPTS_DIR)/configupdate $(UK_CONFIG) $(UK_CONFIG_OUT)
randconfig: $(KCONFIG_DIR)/conf
@$(COMMON_CONFIG_ENV) SKIP_LEGACY=y $< --randconfig $(CONFIG_CONFIG_IN)
@$(COMMON_CONFIG_ENV) $< --olddefconfig $(CONFIG_CONFIG_IN) >/dev/null
@$(COMMON_CONFIG_ENV) $(SCRIPTS_DIR)/configupdate $(UK_CONFIG) $(UK_CONFIG_OUT)
allyesconfig: $(KCONFIG_DIR)/conf
@$(COMMON_CONFIG_ENV) SKIP_LEGACY=y $< --allyesconfig $(CONFIG_CONFIG_IN)
@$(COMMON_CONFIG_ENV) $< --olddefconfig $(CONFIG_CONFIG_IN) >/dev/null
@$(COMMON_CONFIG_ENV) $(SCRIPTS_DIR)/configupdate $(UK_CONFIG) $(UK_CONFIG_OUT)
allnoconfig: $(KCONFIG_DIR)/conf
@$(COMMON_CONFIG_ENV) SKIP_LEGACY=y $< --allnoconfig $(CONFIG_CONFIG_IN)
@$(COMMON_CONFIG_ENV) $< --olddefconfig $(CONFIG_CONFIG_IN) >/dev/null
@$(COMMON_CONFIG_ENV) $(SCRIPTS_DIR)/configupdate $(UK_CONFIG) $(UK_CONFIG_OUT)
syncconfig: $(KCONFIG_DIR)/conf
@$(COMMON_CONFIG_ENV) $< --syncconfig $(CONFIG_CONFIG_IN)
@$(COMMON_CONFIG_ENV) $(SCRIPTS_DIR)/configupdate $(UK_CONFIG) $(UK_CONFIG_OUT)
olddefconfig: $(KCONFIG_DIR)/conf
@$(COMMON_CONFIG_ENV) $< --olddefconfig $(CONFIG_CONFIG_IN)
@$(COMMON_CONFIG_ENV) $(SCRIPTS_DIR)/configupdate $(UK_CONFIG) $(UK_CONFIG_OUT)
defconfig: $(KCONFIG_DIR)/conf
@$(COMMON_CONFIG_ENV) $< --defconfig$(if $(DEFCONFIG),=$(DEFCONFIG)) $(CONFIG_CONFIG_IN)
@$(COMMON_CONFIG_ENV) $(SCRIPTS_DIR)/configupdate $(UK_CONFIG) $(UK_CONFIG_OUT)
savedefconfig: $(KCONFIG_DIR)/conf
@$(COMMON_CONFIG_ENV) $< \
--savedefconfig=$(if $(DEFCONFIG),$(DEFCONFIG),$(CONFIG_DIR)/defconfig) \
$(CONFIG_CONFIG_IN)
ifeq ($(HOSTARCH),$(CONFIG_UK_ARCH))
@# Make sure arch is stored in the file even if arch matches between host and config
@echo "$(call ukarch_str2cfg,$(CONFIG_UK_ARCH))=y" >> \
$(if $(DEFCONFIG),$(DEFCONFIG),$(CONFIG_DIR)/defconfig)
endif
@echo "CONFIG_UK_NAME=\"$(CONFIG_UK_NAME)\"" >> \
$(if $(DEFCONFIG),$(DEFCONFIG),$(CONFIG_DIR)/defconfig)
.PHONY: defconfig savedefconfig
# parameter T: test case for 'make testconfig'
# Set T variable if not already done on the command line;
ifeq ("$(origin T)", "command line")
TEST_CONFIG_CASES := support/kconfig/tests/$(T)
else
TEST_CONFIG_CASES := support/kconfig/tests
endif
testconfig: $(KCONFIG_DIR)/conf
CONFIG_="CONFIG_" python3 -B -m pytest $(CONFIG_UK_BASE)/$(TEST_CONFIG_CASES) \
--BASE_PATH=$(CONFIG_UK_BASE) \
-o cache_dir=$(abspath $(KCONFIG_DIR)/tests/.cache)\
$(if $(findstring 1,$(KBUILD_VERBOSE)),--capture=no)
testextendconfig: $(KCONFIG_DIR)/confdata_test
@$(CP) -r $(CONFIG)/c_tests/extend_config/def_test_files $(KCONFIG_DIR)/def_test_files
@$(COMMON_CONFIG_ENV) $< $(CONFIG_CONFIG_IN)
@$(COMMON_CONFIG_ENV) $(SCRIPTS_DIR)/configupdate $(UK_CONFIG) $(UK_CONFIG_OUT)
.PHONY: defconfig savedefconfig silentoldconfig testconfig testextendconfig
# Regenerate $(KCONFIG_AUTOHEADER) whenever $(UK_CONFIG) changed
$(KCONFIG_AUTOHEADER): $(UK_CONFIG_OUT) $(KCONFIG_DIR)/conf
$(call verbose_cmd,GEN,config.h, \
$(COMMON_CONFIG_ENV) $(KCONFIG_DIR)/conf \
--syncconfig $(CONFIG_CONFIG_IN))
endif
# Misc stuff
# ---------------------------------------------------------------------------
print-loc: images
@$(info [LoC stats])
@$(foreach I,$(UK_DEBUG_IMAGES) $(UK_DEBUG_IMAGES-y),\
$(info $(shell basename $(I) .dbg) has $(call measure_loc,$(I)) lines of code))
print-vars:
@$(foreach V, \
$(sort $(if $(VARS),$(filter $(VARS),$(.VARIABLES)),$(.VARIABLES))), \
$(if $(filter-out environment% default automatic,$(origin $V)), \
$(if $(filter simple,$(flavor $V)), \
$(info [$(origin $V)] $V := $(value $V)), \
$(info [$(origin $V)] $V = <$(flavor $V)>))))
print-version:
@echo $(UK_FULLVERSION)
ifeq ($(UK_HAVE_DOT_CONFIG),y)
print-libs:
@echo $(foreach P,$(UK_PLATS) $(UK_PLATS-y),\
$(if $(call qstrip,$($(call uc,$(P))_LIBS) $($(call uc,$(P))_LIBS-y)),\
$(foreach L,$($(call uc,$(P))_LIBS) $($(call uc,$(P))_LIBS-y), \
$(if $(call qstrip,$($(call vprefix_lib,$(L),SRCS)) $($(call vprefix_lib,$(L),SRCS-y))), \
$(L) \
)))) \
$(UK_LIBS) $(UK_LIBS-y)
print-lds:
@echo -e \
$(foreach P,$(UK_PLATS) $(UK_PLATS-y),\
$(if $(call qstrip,$($(call uc,$(P))_LIBS) $($(call uc,$(P))_LIBS-y)),\
$(foreach L,$($(call uc,$(P))_LIBS) $($(call uc,$(P))_LIBS-y), \
$(if $(call qstrip,$($(call vprefix_lib,$(L),LDS)) $($(call vprefix_lib,$(L),LDS-y))), \
'$(L):\n $($(call vprefix_lib,$(L),LDS)) $($(call vprefix_lib,$(L),LDS-y))\n'\
))))\
$(foreach L,$(UK_LIBS) $(UK_LIBS-y),\
$(if $(call qstrip,$($(call vprefix_lib,$(L),LDS)) $($(call vprefix_lib,$(L),LDS-y))),\
'$(L):\n $($(call vprefix_lib,$(L),LDS)) $($(call vprefix_lib,$(L),LDS-y))\n'\
))
print-objs:
@echo -e \
$(foreach P,$(UK_PLATS) $(UK_PLATS-y),\
$(if $(call qstrip,$($(call uc,$(P))_LIBS) $($(call uc,$(P))_LIBS-y)),\
$(foreach L,$($(call uc,$(P))_LIBS) $($(call uc,$(P))_LIBS-y), \
$(if $(call qstrip,$($(call vprefix_lib,$(L),OBJS)) $($(call vprefix_lib,$(L),OBJS-y)) \
$(EACHOLIB_OBJS) $(EACHOLIB_OBJS-y)), \
'$(L):\n $($(call vprefix_lib,$(L),OBJS)) $($(call vprefix_lib,$(L),OBJS-y)) $(EACHOLIB_OBJS) $(EACHOLIB_OBJS-y)\n'\
))))\
$(foreach L,$(UK_LIBS) $(UK_LIBS-y),\
$(if $(call qstrip,$($(call vprefix_lib,$(L),OBJS)) $($(call vprefix_lib,$(L),OBJS-y)) \
$(EACHOLIB_OBJS) $(EACHOLIB_OBJS-y)), \
'$(L):\n $($(call vprefix_lib,$(L),OBJS)) $($(call vprefix_lib,$(L),OBJS-y)) $(EACHOLIB_OBJS) $(EACHOLIB_OBJS-y)\n'\
))
print-srcs:
@echo -e \
$(foreach P,$(UK_PLATS) $(UK_PLATS-y),\
$(if $(call qstrip,$($(call uc,$(P))_LIBS) $($(call uc,$(P))_LIBS-y)),\
$(foreach L,$($(call uc,$(P))_LIBS) $($(call uc,$(P))_LIBS-y), \
$(if $(call qstrip,$($(call vprefix_lib,$(L),SRCS)) $($(call vprefix_lib,$(L),SRCS-y)) \
$(EACHOLIB_SRCS) $(EACHOLIB_SRCS-y)), \
'$(L):\n $($(call vprefix_lib,$(L),SRCS)) $($(call vprefix_lib,$(L),SRCS-y)) $(EACHOLIB_SRCS) $(EACHOLIB_SRCS-y)\n'\
))))\
$(foreach L,$(UK_LIBS) $(UK_LIBS-y),\
$(if $(call qstrip,$($(call vprefix_lib,$(L),SRCS)) $($(call vprefix_lib,$(L),SRCS-y)) \
$(EACHOLIB_SRCS) $(EACHOLIB_SRCS-y)), \
'$(L):\n $($(call vprefix_lib,$(L),SRCS)) $($(call vprefix_lib,$(L),SRCS-y)) $(EACHOLIB_SRCS) $(EACHOLIB_SRCS-y)\n'\
))
else
print-libs:
$(error Do not have a configuration. Please run one of the configuration targets first)
print-objs:
$(error Do not have a configuration. Please run one of the configuration targets first)
print-srcs:
$(error Do not have a configuration. Please run one of the configuration targets first)
endif
else #!($(sub_make_exec),)
export sub_make_exec:=1
$(BUILD_DIR)/Makefile:
$(call verbose_cmd,LN,$(notdir $@),$(HOSTLN) -sf $(CONFIG_UK_BASE)/Makefile $@)
.PHONY: $(BUILD_DIR)/Makefile
$(filter-out _all $(BUILD_DIR)/Makefile sub-make distclean properclean help $(lastword $(MAKEFILE_LIST)), \
$(MAKECMDGOALS)) all: sub-make
@:
sub-make: $(BUILD_DIR)/Makefile
$(Q)$(MAKE) --no-print-directory CONFIG_UK_BASE=$(CONFIG_UK_BASE) -C $(BUILD_DIR) -f $(BUILD_DIR)/Makefile $(MAKECMDGOALS)
endif
help:
@echo 'Cleaning:'
@echo ' clean-[LIBNAME] - delete all files created by build for a single library'
@echo ' (e.g., clean-libfdt)'
@echo ' clean-libs - delete all files created by build for all libraries'
@echo ' but keep final images and fetched files'
@echo ' clean - delete all files created by build for all libraries'
@echo ' including final images, but keep fetched files'
@echo ' properclean - delete build directory'
@echo ' distclean - delete build directory and configurations (including .config)'
@echo ''
@echo 'Building:'
@echo '* all - build everything (default target)'
@echo ' images - build kernel images for selected platforms'
@echo ' libs - build libraries and objects'
@echo ' [LIBNAME] - build a single library'
@echo ' objs - build objects only'
@echo ' preprocess - run preprocessing steps'
@echo ' prepare - run preparation steps'
@echo ' fetch - fetch, extract, and patch remote code'
@echo ''
@echo 'Configuration:'
@echo '* menuconfig - interactive curses-based configurator'
@echo ' (default target when no config exists)'
@echo ' kmenuconfig - interactive python based configurator'
@echo ' guiconfig - interactive python based configurator'
@echo ' nconfig - interactive ncurses-based configurator'
@echo ' xconfig - interactive Qt-based configurator'
@echo ' gconfig - interactive GTK-based configurator'
@echo ' oldconfig - resolve any unresolved symbols in .config'
ifeq ($(HOSTOSENV),Linux)
@echo ' syncconfig - Same as oldconfig, but quietly, additionally update deps'
@echo ' scriptsyncconfig - Same as oldconfig, but quietly, additionally update deps'
@echo ' olddefconfig - Same as defconfig but sets new symbols to their default value'
@echo ' randconfig - New config with random answer to all options'
endif
@echo ' defconfig - New config with default answer to all options'
@echo ' UK_DEFCONFIG, if set, is used as input'
@echo ' savedefconfig - Save current config to UK_DEFCONFIG (minimal config)'
@echo ' allyesconfig - New config where all options are accepted with yes'
@echo ' allnoconfig - New config where all options are answered with no'
@echo ''
@echo 'Command-line variables:'
@echo ' V=0|1|2 - 0 => quiet build (default), 1 => verbose build,'
@echo ' 2 => like 1 and warn about undefined build variables'
@echo ' C=[PATH] - path to .config configuration file'
@echo ' O=[PATH] - path to build output (will be created if it does not exist)'
@echo ' A=[PATH] - path to Unikraft application'
@echo ' N=[NAME] - use NAME as image name instead the one found in the configuration'
@echo ' (note: the name in the configuration file is not overwritten)'
@echo ' L=[PATH]:[PATH]:.. - colon-separated list of paths to external libraries'
@echo ' P=[PATH]:[PATH]:.. - colon-separated list of paths to external platforms'
@echo ' E=[PATH]:[PATH]:.. - colon-separated list of paths to libraries that shall be skipped/excluded'
@echo ' (note: `E=` acts as a global exclusion mask, which means that the mask'
@echo ' is applied to every internal and external import of libraries, platforms,'
@echo ' and applications. For example, an external library (via `L=`) will also be'
@echo ' skipped if its path was specified with `E=` at the same time.)'
@echo ''
@echo 'Environment variables:'
@echo ' UK_ASFLAGS - explicit Unikraft-specific additions to the assembler flags (the ASFLAGS variable is ignored)'
@echo ' UK_CFLAGS - explicit Unikraft-specific additions to the C compiler flags (the CFLAGS variable is ignored)'
@echo ' UK_CXXFLAGS - explicit Unikraft-specific additions to the C++ compiler flags (the CXXFLAGS variable is ignored)'
@echo ' UK_GOCFLAGS - explicit Unikraft-specific additions to the GO compiler flags (the GOCFLAGS variable is ignored)'
@echo ' UK_LDFLAGS - explicit Unikraft-specific additions to the linker flags (the LDFLAGS variable is ignored)'
@echo ' UK_LDEPS - explicit, space-seperated link-time file dependencies (changes to these files will trigger relinking on subsequent builds)'
@echo ''
@echo 'Miscellaneous:'
@echo ' print-version - print Unikraft version'
@echo ' print-libs - print library names enabled for build'
@echo ' print-lds - print linker script enabled for the build'
@echo ' print-objs - print object file names enabled for build'
@echo ' print-srcs - print source file names enabled for build'
@echo ' print-vars - prints all the variables currently defined in Makefile'
@echo ' print-loc - print Lines-of-Code statistics for built unikernel image(s)'
@echo ''
endif #umask
# This is used to detect if a makefile macro expansion is immediate or deferred.
# As the last statement in the main makefile, this is read in the end of the
# immediate expansion phase. Therefore, UK_DEFERRED_EXPANSION is expanded to a
# empty string in immediate expansion and to 'y' in a deferred expansion.
UK_DEFERRED_EXPANSION := y
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化