[Mod] 优化Makefile
This commit is contained in:
@ -7,6 +7,10 @@ root = true
|
||||
indent_style = tab
|
||||
indent_size = 8
|
||||
|
||||
[Makefile]
|
||||
indent_style = tab
|
||||
indent_size = 8
|
||||
|
||||
[*]
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
|
||||
6
.gitignore
vendored
6
.gitignore
vendored
@ -20,5 +20,7 @@ Module.symvers
|
||||
modules.order
|
||||
compile_commands.json
|
||||
|
||||
.cache/
|
||||
output/
|
||||
/.cache/
|
||||
|
||||
/include/
|
||||
/output/
|
||||
|
||||
@ -10,6 +10,8 @@
|
||||
# Path information
|
||||
#*******************************************************************************
|
||||
LOCAL_DIR := $(realpath $(dir $(lastword $(MAKEFILE_LIST))))
|
||||
|
||||
DRIVER_DIR := $(realpath $(LOCAL_DIR)/../../..)
|
||||
KERNEL_DIR ?= /home/gaoyang3513/Source/06-SG20x/02-Projects/SDK_SG200x_V2/linux_5.10/build/sg2000_milkv_duos_glibc_arm64_sd
|
||||
#KERNEL_DIR ?= $(HOME)/Source/06-SG20x/02-Projects/SDK_SG200x_V2/linux_5.10/build/sg2000_milkv_duos_glibc_arm64_sd/
|
||||
|
||||
@ -47,9 +49,17 @@ export ARCH CROSS_COMPILE
|
||||
#*******************************************************************************
|
||||
# Targets
|
||||
#*******************************************************************************
|
||||
# Read auto.conf if it exists, otherwise ignore
|
||||
-include $(DRIVER_DIR)/include/config/auto.conf
|
||||
|
||||
.PHONY: all install clean
|
||||
|
||||
ifeq ($(KERNELRELEASE),)
|
||||
ifeq ($(CONFIG_DRIVER_BUS_PLATFORM_OSDEV),)
|
||||
all:
|
||||
$(Q)echo -n ""
|
||||
install:
|
||||
$(Q)echo "[SKIP] OSAL_osdev"
|
||||
else ifeq ($(KERNELRELEASE),)
|
||||
all: init
|
||||
@$(MAKE) modules -C $(KERNEL_DIR) M=$(LOCAL_DIR) -j$(MULTI_CORES)
|
||||
# @$(MAKE) modules_install -C $(KERNEL_DIR) M=$(LOCAL_DIR) INSTALL_MOD_PATH=$(KERNEL_DIR)/_install_modules INSTALL_MOD_DIR=private
|
||||
|
||||
185
03-Bus/01-Platform/01-osdev/OSAL_osdev.c.bak
Normal file
185
03-Bus/01-Platform/01-osdev/OSAL_osdev.c.bak
Normal file
@ -0,0 +1,185 @@
|
||||
/*******************************************************************************
|
||||
* HangZhou Hikvision Digital Technology Co., Ltd. All Right Reserved.
|
||||
* Author :
|
||||
* Version : V1.0.0 2024.11.15
|
||||
* Description :
|
||||
* Note : anonymity@hikvision.com.cn Modified 2024.11.15
|
||||
******************************************************************************/
|
||||
#include <stdarg.h>
|
||||
#include <linux/sysfs.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/kdev_t.h> // MKDEV
|
||||
|
||||
#include "OSAL_osdev.h"
|
||||
|
||||
struct device osal_bus = {
|
||||
.init_name = "osal",
|
||||
};
|
||||
|
||||
struct bus_type osal_bus_type = {
|
||||
.name = "osal",
|
||||
};
|
||||
|
||||
struct osdev_device { // Object
|
||||
struct device dev;
|
||||
char name[];
|
||||
};
|
||||
|
||||
struct osdev_driver {
|
||||
struct device_driver drv;
|
||||
};
|
||||
|
||||
static void osadev_device_release(struct device *dev)
|
||||
{
|
||||
struct osdev_device *osdev_obj = container_of(dev, struct osdev_device, dev);
|
||||
|
||||
kfree(osdev_obj);
|
||||
}
|
||||
|
||||
OSAL_osdev *OSAL_osdevAlloc(const char *name, int id)
|
||||
{
|
||||
struct device *dev = NULL;
|
||||
struct osdev *osdev = NULL;
|
||||
struct osdev_device *osdev_obj = NULL;
|
||||
|
||||
osdev_obj = kzalloc(sizeof(struct osdev_device) + strlen(name) + 1, GFP_KERNEL);
|
||||
if (!osdev_obj) {
|
||||
pr_err("ErrNo(%ld), alloc memory for OSAL_sysDevice failed.", PTR_ERR(dev));
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
osdev = &(osdev_obj->osdev);
|
||||
dev = &(osdev_obj->dev);
|
||||
|
||||
strcpy(osdev_obj->name, name);
|
||||
osdev->name = osdev_obj->name;
|
||||
osdev->id = id;
|
||||
device_initialize(dev);
|
||||
dev->release = osadev_device_release;
|
||||
|
||||
osdev->obj = osdev;
|
||||
|
||||
return (OSAL_osdev *)osdev;
|
||||
}
|
||||
EXPORT_SYMBOL(OSAL_osdevAlloc);
|
||||
|
||||
int OSAL_osdevRegister(OSAL_osdev *osdev)
|
||||
{
|
||||
int ret = 0;
|
||||
struct device *dev = NULL;
|
||||
struct osdev *osdev_tmp = NULL;
|
||||
struct osdev_device *osdev_obj = NULL;
|
||||
struct osdev_device *osdev_parent = NULL;
|
||||
|
||||
if (osdev == NULL) {
|
||||
pr_err("Error, null pointer exception.");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!osdev->obj) {
|
||||
osdev_tmp = OSAL_osdevAlloc(osdev->name, osdev->id);
|
||||
osdev->obj = osdev_tmp;
|
||||
}
|
||||
else {
|
||||
osdev_tmp = osdev->obj;
|
||||
osdev_parent = container_of(osdev_tmp, struct osdev_device, osdev);
|
||||
}
|
||||
osdev_obj = container_of(osdev_tmp->obj, struct osdev_device, osdev);
|
||||
dev = &(osdev_obj->dev);
|
||||
|
||||
dev_set_name(dev, "%s.%d", osdev->name, osdev->id);
|
||||
dev_set_drvdata(dev, osdev_obj);
|
||||
dev->bus = &osal_bus_type;
|
||||
dev->devt = MKDEV(0, 0);
|
||||
dev->parent = osdev_parent ? &osdev_parent->dev : &osal_bus;
|
||||
|
||||
ret = device_add(dev);
|
||||
if (ret) {
|
||||
pr_err("ErrNo(%d), add device failed.", ret);
|
||||
put_device(dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(OSAL_osdevRegister);
|
||||
|
||||
void OSAL_osdevUnregister(OSAL_osdev *osdev)
|
||||
{
|
||||
struct osdev_device *osdev_obj = NULL;
|
||||
|
||||
if (osdev == NULL || osdev->obj == NULL) {
|
||||
pr_err("Error, null pointer exception.");
|
||||
return;
|
||||
}
|
||||
|
||||
osdev_obj = container_of(osdev->obj, struct osdev_device, osdev);
|
||||
|
||||
device_del(&osdev_obj->dev);
|
||||
put_device(&osdev_obj->dev);
|
||||
}
|
||||
EXPORT_SYMBOL(OSAL_osdevUnregister);
|
||||
|
||||
inline void *OSAL_osdevGetDrvdata(const OSAL_osdev *osdev)
|
||||
{
|
||||
struct osdev_device *osdev_obj = NULL;
|
||||
|
||||
if (osdev == NULL || osdev->obj == NULL) {
|
||||
pr_err("Error, null pointer exception.");
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
osdev_obj = container_of(osdev->obj, struct osdev_device, osdev);
|
||||
|
||||
return dev_get_drvdata(&osdev_obj->dev);
|
||||
}
|
||||
EXPORT_SYMBOL(OSAL_osdevGetDrvdata);
|
||||
|
||||
inline void OSAL_osdevSetDrvdata(OSAL_osdev *osdev, void *data)
|
||||
{
|
||||
struct osdev_device *osdev_obj = NULL;
|
||||
|
||||
if (osdev == NULL || osdev->obj == NULL) {
|
||||
pr_err("Error, null pointer exception.");
|
||||
return;
|
||||
}
|
||||
|
||||
osdev_obj = container_of(osdev->obj, struct osdev_device, osdev);
|
||||
|
||||
dev_set_drvdata(&osdev_obj->dev, data);
|
||||
}
|
||||
EXPORT_SYMBOL(OSAL_osdevSetDrvdata);
|
||||
|
||||
int __init OSAL_osdevInit(void)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
ret = device_register(&osal_bus);
|
||||
if (ret) {
|
||||
pr_err("ErrNo(%d), register bus Device[osal] failed.", ret);
|
||||
put_device(&osal_bus);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = bus_register(&osal_bus_type);
|
||||
if (ret) {
|
||||
pr_err("ErrNo(%d), register bus Type[osal] failed.", ret);
|
||||
goto out_unregister_bus;
|
||||
}
|
||||
|
||||
pr_info("OSAL_osdev initialize completed.");
|
||||
|
||||
return ret;
|
||||
|
||||
out_unregister_bus:
|
||||
device_unregister(&osal_bus);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
void __exit OSAL_osdevExit(void)
|
||||
{
|
||||
bus_unregister(&osal_bus_type);
|
||||
device_unregister(&osal_bus);
|
||||
}
|
||||
28
03-Bus/01-Platform/01-osdev/OSAL_osdev.h.bak
Normal file
28
03-Bus/01-Platform/01-osdev/OSAL_osdev.h.bak
Normal file
@ -0,0 +1,28 @@
|
||||
/*******************************************************************************
|
||||
* HangZhou Hikvision Digital Technology Co., Ltd. All Right Reserved.
|
||||
* Author :
|
||||
* Version : V1.0.0 2024.11.15
|
||||
* Description :
|
||||
* Note : anonymity@hikvision.com.cn Modified 2024.11.15
|
||||
******************************************************************************/
|
||||
#ifndef INCLUDE_WIDGET_OSAL_OSDEV_H_
|
||||
#define INCLUDE_WIDGET_OSAL_OSDEV_H_
|
||||
|
||||
typedef struct osdev {
|
||||
int id;
|
||||
const char *name;
|
||||
void *obj;
|
||||
} OSAL_osdev;
|
||||
|
||||
typedef struct osdrv {
|
||||
int (*probe)(struct osdev *);
|
||||
int (*remove)(struct osdev *);
|
||||
void *obj;
|
||||
} OSAL_osdrv;
|
||||
|
||||
int OSAL_osdevRegister(OSAL_osdev *osdev);
|
||||
void OSAL_osdevUnregister(OSAL_osdev *osdev);
|
||||
void *OSAL_osdevGetDrvdata(const OSAL_osdev *osdev);
|
||||
void OSAL_osdevSetDrvdata(OSAL_osdev *osdev, void *data);
|
||||
|
||||
#endif /* INCLUDE_WIDGET_OSAL_OSDEV_H_ */
|
||||
130
Makefile
130
Makefile
@ -1,15 +1,18 @@
|
||||
#*******************************************************************************
|
||||
# HangZhou Hikvision Digital Technology Co., Ltd. All Right Reserved.
|
||||
# ---------------------------------------------------------------------------- #
|
||||
# All Right Reserved.
|
||||
# Author :
|
||||
# Version : V1.0.0 202x.01.01
|
||||
# Description :
|
||||
# Note : gaoyang@.com.cn Modified 2020.10.21
|
||||
#*******************************************************************************
|
||||
# Note : gaoyang3513@163.com.cn Modified 202x.01.01
|
||||
# ---------------------------------------------------------------------------- #
|
||||
# That's our default target when none is given on the command line
|
||||
PHONY := all
|
||||
all:
|
||||
|
||||
#*******************************************************************************
|
||||
# ---------------------------------------------------------------------------- #
|
||||
# Path information
|
||||
#*******************************************************************************
|
||||
LOCAL_DIR := $(realpath $(dir $(lastword $(MAKEFILE_LIST))))
|
||||
# ---------------------------------------------------------------------------- #
|
||||
LOCAL_DIR := $(realpath $(dir $(lastword $(MAKEFILE_LIST))))
|
||||
|
||||
# SDK directories
|
||||
SDK_TOP ?= $(HOME)/Source/15-SG200x/01-MilkDuo/02-Project/SDK_SG200x_V2.0.0
|
||||
@ -17,26 +20,53 @@ KERNEL_DIR ?= $(SDK_TOP)/linux_5.10/build/sg2000_milkv_duos_glibc_arm64_sd
|
||||
TOOLCHAIN_DIR ?= $(SDK_TOP)/host-tools/gcc/gcc-linaro-7.3.1-2018.05-x86_64_aarch64-linux-gnu/bin
|
||||
|
||||
# Subdirectory
|
||||
|
||||
OUTPUT_DIR := $(LOCAL_DIR)/output
|
||||
INSTALL_DIR ?= $(LOCAL_DIR)/__install
|
||||
#$(info Output directoty : $(OUTPUT_DIR))
|
||||
#$(info Install directoty: $(INSTALL_DIR))
|
||||
OUTPUT_DIR := $(LOCAL_DIR)/output
|
||||
INSTALL_DIR ?= $(LOCAL_DIR)/__install
|
||||
|
||||
export KERNEL_DIR
|
||||
#*******************************************************************************
|
||||
# ---------------------------------------------------------------------------- #
|
||||
# Functions
|
||||
# ---------------------------------------------------------------------------- #
|
||||
define filechk_version.h
|
||||
echo \#define LINUX_VERSION_CODE $(shell \
|
||||
expr $(VERSION) \* 65536 + 0$(PATCHLEVEL) \* 256 + 0$(SUBLEVEL)); \
|
||||
echo '#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))'
|
||||
endef
|
||||
|
||||
# ---------------------------------------------------------------------------- #
|
||||
# Variables
|
||||
#*******************************************************************************
|
||||
MULTI_CORES ?= $(shell grep -c ^processor /proc/cpuinfo)
|
||||
# ---------------------------------------------------------------------------- #
|
||||
VERSION = 1
|
||||
PATCHLEVEL = 1
|
||||
SUBLEVEL = 0
|
||||
EXTRAVERSION =
|
||||
NAME = Kleptomaniac Octopus
|
||||
|
||||
SUB_DIRS := \
|
||||
04-Debug \
|
||||
03-Bus/01-Platform/01-osdev \
|
||||
version_h := include/generated/version.h
|
||||
|
||||
#*******************************************************************************
|
||||
MAKEFLAGS += --no-print-directory
|
||||
|
||||
MULTI_CORES ?= $(shell grep -c ^processor /proc/cpuinfo)
|
||||
|
||||
ifeq ("$(origin V)", "command line")
|
||||
KBUILD_VERBOSE = $(V)
|
||||
endif
|
||||
ifndef KBUILD_VERBOSE
|
||||
KBUILD_VERBOSE = 0
|
||||
endif
|
||||
|
||||
ifeq ($(KBUILD_VERBOSE),1)
|
||||
quiet =
|
||||
Q =
|
||||
else
|
||||
quiet = quiet_
|
||||
Q = @
|
||||
endif
|
||||
|
||||
export Q quiet
|
||||
# ---------------------------------------------------------------------------- #
|
||||
# Compile configure
|
||||
#*******************************************************************************
|
||||
#ARCH ?= riscv
|
||||
# ---------------------------------------------------------------------------- #
|
||||
#CROSS_COMPILE ?= riscv64-unknown-linux-musl-
|
||||
ARCH ?= arm64
|
||||
CROSS_COMPILE ?= aarch64-linux-gnu-
|
||||
@ -49,47 +79,57 @@ STRIP := $(CROSS_COMPILE)strip
|
||||
PATH := $(TOOLCHAIN_DIR):$(PATH)
|
||||
|
||||
export ARCH CROSS_COMPILE PATH
|
||||
#*******************************************************************************
|
||||
# Targets
|
||||
#*******************************************************************************
|
||||
.PHONY: init all clean distclean install menuconfig
|
||||
|
||||
ifeq ($(KERNELRELEASE),)
|
||||
# ---------------------------------------------------------------------------- #
|
||||
# Objects
|
||||
# ---------------------------------------------------------------------------- #
|
||||
SUB_DIRS := 03-Bus/01-Platform/01-osdev
|
||||
#$(warning "SUB_DIRS: $(SUB_DIRS)")
|
||||
|
||||
# ---------------------------------------------------------------------------- #
|
||||
# Targets
|
||||
# ---------------------------------------------------------------------------- #
|
||||
.PHONY += init all clean distclean install menuconfig oldconfig $(version_h)
|
||||
|
||||
include scripts/Kbuild.include
|
||||
|
||||
all: init
|
||||
@for sub in $(SUB_DIRS); do \
|
||||
$(Q)for sub in $(SUB_DIRS); do \
|
||||
$(MAKE) -C $$sub; \
|
||||
$(MAKE) install INSTALL_DIR=$(OUTPUT_DIR) -C $$sub || exit "$$?"; \
|
||||
done;
|
||||
|
||||
clean:
|
||||
@for sub in $(SUB_DIRS); do \
|
||||
$(Q)for sub in $(SUB_DIRS); do \
|
||||
$(MAKE) clean -C $$sub || exit "$$?"; \
|
||||
done;
|
||||
# Directory
|
||||
@if [ -d $(LOCAL_DIR)/output ]; then rm -rf $(LOCAL_DIR)/output; fi;
|
||||
@if [ -d $(LOCAL_DIR)/__install ]; then rm -rf $(LOCAL_DIR)/__install; fi;
|
||||
$(Q)if [ -d $(LOCAL_DIR)/include/config ]; then rm -rf $(LOCAL_DIR)/include/config; fi;
|
||||
$(Q)if [ -d $(LOCAL_DIR)/include/generated ]; then rm -rf $(LOCAL_DIR)/include/generated; fi;
|
||||
$(Q)if [ -d $(LOCAL_DIR)/output ]; then rm -rf $(LOCAL_DIR)/output; fi;
|
||||
$(Q)if [ -d $(LOCAL_DIR)/__install ]; then rm -rf $(LOCAL_DIR)/__install; fi;
|
||||
|
||||
install:
|
||||
@mkdir -p $(INSTALL_DIR)
|
||||
@cp -arf $(OUTPUT_DIR)/. $(INSTALL_DIR)
|
||||
$(Q)mkdir -p $(INSTALL_DIR)
|
||||
$(Q)cp -arf $(OUTPUT_DIR)/. $(INSTALL_DIR)
|
||||
|
||||
init:
|
||||
@mkdir -p $(OUTPUT_DIR);
|
||||
init: $(version_h)
|
||||
$(Q)mkdir -p $(OUTPUT_DIR);
|
||||
$(Q)mkdir -p include/config include/generated
|
||||
$(Q)$(LOCAL_DIR)/scripts/kconfig/Kconfiglib/genconfig.py --sync-dep include/config --header-path include/generated/autoconf.h
|
||||
|
||||
oldconfig:
|
||||
$(Q)$(LOCAL_DIR)/scripts/kconfig/Kconfiglib/oldconfig.py
|
||||
|
||||
%_defconfig:
|
||||
$(LOCAL_DIR)/scripts/kconfig/Kconfiglib/defconfig.py --kconfig Kconfig configs/$@
|
||||
$(Q)$(LOCAL_DIR)/scripts/kconfig/Kconfiglib/defconfig.py --kconfig Kconfig configs/$@
|
||||
|
||||
menuconfig:
|
||||
$(LOCAL_DIR)/scripts/kconfig/Kconfiglib/menuconfig.py Kconfig
|
||||
$(Q)mkdir -p include/config include/generated
|
||||
$(Q)$(LOCAL_DIR)/scripts/kconfig/Kconfiglib/menuconfig.py Kconfig
|
||||
|
||||
savedefconfig:
|
||||
$(LOCAL_DIR)/scripts/kconfig/Kconfiglib/savedefconfig.py --kconfig Kconfig --out defconfig
|
||||
$(Q)$(LOCAL_DIR)/scripts/kconfig/Kconfiglib/savedefconfig.py --kconfig Kconfig --out defconfig
|
||||
|
||||
else
|
||||
# called from kernel build system: just declare what our modules are
|
||||
obj-y += $(SUB_DIRS)
|
||||
|
||||
#INC_DIRS := $(INCLUDE_DIR)/generated
|
||||
#subdir-ccflags-y += $(addprefix -I, $(INC_DIRS))
|
||||
|
||||
endif # ifeq ($(KERNELRELEASE),)
|
||||
$(version_h):
|
||||
$(Q)$(call filechk,version.h)
|
||||
|
||||
9
config.h
Normal file
9
config.h
Normal file
@ -0,0 +1,9 @@
|
||||
#define CONFIG_MODULE_BUS 1
|
||||
#define CONFIG_DRIVER_BUS_PLATFORM 1
|
||||
#define CONFIG_DRIVER_BUS_PLATFORM_OSDEV 1
|
||||
#define CONFIG_BOOL 1
|
||||
#define CONFIG_STRING "foo"
|
||||
#define CONFIG_INT 747
|
||||
#define CONFIG_HEX 0xABC
|
||||
#define CONFIG_BOOL_CHOICE_SYM_1 1
|
||||
#define CONFIG_TRI_CHOICE_SYM_1 1
|
||||
323
scripts/Kbuild.include
Normal file
323
scripts/Kbuild.include
Normal file
@ -0,0 +1,323 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
####
|
||||
# kbuild: Generic definitions
|
||||
|
||||
# Convenient variables
|
||||
comma := ,
|
||||
quote := "
|
||||
squote := '
|
||||
empty :=
|
||||
space := $(empty) $(empty)
|
||||
space_escape := _-_SPACE_-_
|
||||
pound := \#
|
||||
|
||||
###
|
||||
# Name of target with a '.' as filename prefix. foo/bar.o => foo/.bar.o
|
||||
dot-target = $(dir $@).$(notdir $@)
|
||||
|
||||
###
|
||||
# The temporary file to save gcc -MMD generated dependencies must not
|
||||
# contain a comma
|
||||
depfile = $(subst $(comma),_,$(dot-target).d)
|
||||
|
||||
###
|
||||
# filename of target with directory and extension stripped
|
||||
basetarget = $(basename $(notdir $@))
|
||||
|
||||
###
|
||||
# real prerequisites without phony targets
|
||||
real-prereqs = $(filter-out $(PHONY), $^)
|
||||
|
||||
###
|
||||
# Escape single quote for use in echo statements
|
||||
escsq = $(subst $(squote),'\$(squote)',$1)
|
||||
|
||||
###
|
||||
# Quote a string to pass it to C files. foo => '"foo"'
|
||||
stringify = $(squote)$(quote)$1$(quote)$(squote)
|
||||
|
||||
###
|
||||
# Easy method for doing a status message
|
||||
kecho := :
|
||||
quiet_kecho := echo
|
||||
silent_kecho := :
|
||||
kecho := $($(quiet)kecho)
|
||||
|
||||
###
|
||||
# filechk is used to check if the content of a generated file is updated.
|
||||
# Sample usage:
|
||||
#
|
||||
# filechk_sample = echo $(KERNELRELEASE)
|
||||
# version.h: FORCE
|
||||
# $(call filechk,sample)
|
||||
#
|
||||
# The rule defined shall write to stdout the content of the new file.
|
||||
# The existing file will be compared with the new one.
|
||||
# - If no file exist it is created
|
||||
# - If the content differ the new file is used
|
||||
# - If they are equal no change, and no timestamp update
|
||||
define filechk
|
||||
$(Q)set -e; \
|
||||
mkdir -p $(dir $@); \
|
||||
trap "rm -f $(dot-target).tmp" EXIT; \
|
||||
{ $(filechk_$(1)); } > $(dot-target).tmp; \
|
||||
if [ ! -r $@ ] || ! cmp -s $@ $(dot-target).tmp; then \
|
||||
$(kecho) ' UPD $@'; \
|
||||
mv -f $(dot-target).tmp $@; \
|
||||
fi
|
||||
endef
|
||||
|
||||
######
|
||||
# gcc support functions
|
||||
# See documentation in Documentation/kbuild/makefiles.rst
|
||||
|
||||
# cc-cross-prefix
|
||||
# Usage: CROSS_COMPILE := $(call cc-cross-prefix, m68k-linux-gnu- m68k-linux-)
|
||||
# Return first <prefix> where a <prefix>gcc is found in PATH.
|
||||
# If no gcc found in PATH with listed prefixes return nothing
|
||||
#
|
||||
# Note: '2>/dev/null' is here to force Make to invoke a shell. Otherwise, it
|
||||
# would try to directly execute the shell builtin 'command'. This workaround
|
||||
# should be kept for a long time since this issue was fixed only after the
|
||||
# GNU Make 4.2.1 release.
|
||||
cc-cross-prefix = $(firstword $(foreach c, $(1), \
|
||||
$(if $(shell command -v -- $(c)gcc 2>/dev/null), $(c))))
|
||||
|
||||
# output directory for tests below
|
||||
TMPOUT = $(if $(KBUILD_EXTMOD),$(firstword $(KBUILD_EXTMOD))/).tmp_$$$$
|
||||
|
||||
# try-run
|
||||
# Usage: option = $(call try-run, $(CC)...-o "$$TMP",option-ok,otherwise)
|
||||
# Exit code chooses option. "$$TMP" serves as a temporary file and is
|
||||
# automatically cleaned up.
|
||||
try-run = $(shell set -e; \
|
||||
TMP=$(TMPOUT)/tmp; \
|
||||
TMPO=$(TMPOUT)/tmp.o; \
|
||||
mkdir -p $(TMPOUT); \
|
||||
trap "rm -rf $(TMPOUT)" EXIT; \
|
||||
if ($(1)) >/dev/null 2>&1; \
|
||||
then echo "$(2)"; \
|
||||
else echo "$(3)"; \
|
||||
fi)
|
||||
|
||||
# as-option
|
||||
# Usage: cflags-y += $(call as-option,-Wa$(comma)-isa=foo,)
|
||||
|
||||
as-option = $(call try-run,\
|
||||
$(CC) $(KBUILD_CFLAGS) $(1) -c -x assembler /dev/null -o "$$TMP",$(1),$(2))
|
||||
|
||||
# as-instr
|
||||
# Usage: cflags-y += $(call as-instr,instr,option1,option2)
|
||||
|
||||
as-instr = $(call try-run,\
|
||||
printf "%b\n" "$(1)" | $(CC) $(KBUILD_AFLAGS) -c -x assembler -o "$$TMP" -,$(2),$(3))
|
||||
|
||||
# __cc-option
|
||||
# Usage: MY_CFLAGS += $(call __cc-option,$(CC),$(MY_CFLAGS),-march=winchip-c6,-march=i586)
|
||||
__cc-option = $(call try-run,\
|
||||
$(1) -Werror $(2) $(3) -c -x c /dev/null -o "$$TMP",$(3),$(4))
|
||||
|
||||
# cc-option
|
||||
# Usage: cflags-y += $(call cc-option,-march=winchip-c6,-march=i586)
|
||||
|
||||
cc-option = $(call __cc-option, $(CC),\
|
||||
$(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS),$(1),$(2))
|
||||
|
||||
# cc-option-yn
|
||||
# Usage: flag := $(call cc-option-yn,-march=winchip-c6)
|
||||
cc-option-yn = $(call try-run,\
|
||||
$(CC) -Werror $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(1) -c -x c /dev/null -o "$$TMP",y,n)
|
||||
|
||||
# cc-disable-warning
|
||||
# Usage: cflags-y += $(call cc-disable-warning,unused-but-set-variable)
|
||||
cc-disable-warning = $(call try-run,\
|
||||
$(CC) -Werror $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) -W$(strip $(1)) -c -x c /dev/null -o "$$TMP",-Wno-$(strip $(1)))
|
||||
|
||||
# cc-ifversion
|
||||
# Usage: EXTRA_CFLAGS += $(call cc-ifversion, -lt, 0402, -O1)
|
||||
cc-ifversion = $(shell [ $(CONFIG_GCC_VERSION)0 $(1) $(2)000 ] && echo $(3) || echo $(4))
|
||||
|
||||
# ld-option
|
||||
# Usage: KBUILD_LDFLAGS += $(call ld-option, -X, -Y)
|
||||
ld-option = $(call try-run, $(LD) $(KBUILD_LDFLAGS) $(1) -v,$(1),$(2),$(3))
|
||||
|
||||
# ld-version
|
||||
# Note this is mainly for HJ Lu's 3 number binutil versions
|
||||
ld-version = $(shell $(LD) --version | $(srctree)/scripts/ld-version.sh)
|
||||
|
||||
# ld-ifversion
|
||||
# Usage: $(call ld-ifversion, -ge, 22252, y)
|
||||
ld-ifversion = $(shell [ $(ld-version) $(1) $(2) ] && echo $(3) || echo $(4))
|
||||
|
||||
######
|
||||
|
||||
###
|
||||
# Shorthand for $(Q)$(MAKE) -f scripts/Makefile.build obj=
|
||||
# Usage:
|
||||
# $(Q)$(MAKE) $(build)=dir
|
||||
build := -f $(srctree)/scripts/Makefile.build obj
|
||||
|
||||
###
|
||||
# Shorthand for $(Q)$(MAKE) -f scripts/Makefile.dtbinst obj=
|
||||
# Usage:
|
||||
# $(Q)$(MAKE) $(dtbinst)=dir
|
||||
dtbinst := -f $(srctree)/scripts/Makefile.dtbinst obj
|
||||
|
||||
###
|
||||
# Shorthand for $(Q)$(MAKE) -f scripts/Makefile.clean obj=
|
||||
# Usage:
|
||||
# $(Q)$(MAKE) $(clean)=dir
|
||||
clean := -f $(srctree)/scripts/Makefile.clean obj
|
||||
|
||||
# echo command.
|
||||
# Short version is used, if $(quiet) equals `quiet_', otherwise full one.
|
||||
echo-cmd = $(if $($(quiet)cmd_$(1)),\
|
||||
echo ' $(call escsq,$($(quiet)cmd_$(1)))$(echo-why)';)
|
||||
|
||||
# printing commands
|
||||
cmd = @set -e; $(echo-cmd) $(cmd_$(1))
|
||||
|
||||
###
|
||||
# if_changed - execute command if any prerequisite is newer than
|
||||
# target, or command line has changed
|
||||
# if_changed_dep - as if_changed, but uses fixdep to reveal dependencies
|
||||
# including used config symbols
|
||||
# if_changed_rule - as if_changed but execute rule instead
|
||||
# See Documentation/kbuild/makefiles.rst for more info
|
||||
|
||||
ifneq ($(KBUILD_NOCMDDEP),1)
|
||||
# Check if both commands are the same including their order. Result is empty
|
||||
# string if equal. User may override this check using make KBUILD_NOCMDDEP=1
|
||||
cmd-check = $(filter-out $(subst $(space),$(space_escape),$(strip $(cmd_$@))), \
|
||||
$(subst $(space),$(space_escape),$(strip $(cmd_$1))))
|
||||
else
|
||||
cmd-check = $(if $(strip $(cmd_$@)),,1)
|
||||
endif
|
||||
|
||||
# Replace >$< with >$$< to preserve $ when reloading the .cmd file
|
||||
# (needed for make)
|
||||
# Replace >#< with >$(pound)< to avoid starting a comment in the .cmd file
|
||||
# (needed for make)
|
||||
# Replace >'< with >'\''< to be able to enclose the whole string in '...'
|
||||
# (needed for the shell)
|
||||
make-cmd = $(call escsq,$(subst $(pound),$$(pound),$(subst $$,$$$$,$(cmd_$(1)))))
|
||||
|
||||
# Find any prerequisites that are newer than target or that do not exist.
|
||||
# (This is not true for now; $? should contain any non-existent prerequisites,
|
||||
# but it does not work as expected when .SECONDARY is present. This seems a bug
|
||||
# of GNU Make.)
|
||||
# PHONY targets skipped in both cases.
|
||||
newer-prereqs = $(filter-out $(PHONY),$?)
|
||||
|
||||
# Execute command if command has changed or prerequisite(s) are updated.
|
||||
if_changed = $(if $(newer-prereqs)$(cmd-check), \
|
||||
$(cmd); \
|
||||
printf '%s\n' 'cmd_$@ := $(make-cmd)' > $(dot-target).cmd, @:)
|
||||
|
||||
# Execute the command and also postprocess generated .d dependencies file.
|
||||
if_changed_dep = $(if $(newer-prereqs)$(cmd-check),$(cmd_and_fixdep),@:)
|
||||
|
||||
cmd_and_fixdep = \
|
||||
$(cmd); \
|
||||
scripts/basic/fixdep $(depfile) $@ '$(make-cmd)' > $(dot-target).cmd;\
|
||||
rm -f $(depfile)
|
||||
|
||||
# Usage: $(call if_changed_rule,foo)
|
||||
# Will check if $(cmd_foo) or any of the prerequisites changed,
|
||||
# and if so will execute $(rule_foo).
|
||||
if_changed_rule = $(if $(newer-prereqs)$(cmd-check),$(rule_$(1)),@:)
|
||||
|
||||
###
|
||||
# why - tell why a target got built
|
||||
# enabled by make V=2
|
||||
# Output (listed in the order they are checked):
|
||||
# (1) - due to target is PHONY
|
||||
# (2) - due to target missing
|
||||
# (3) - due to: file1.h file2.h
|
||||
# (4) - due to command line change
|
||||
# (5) - due to missing .cmd file
|
||||
# (6) - due to target not in $(targets)
|
||||
# (1) PHONY targets are always build
|
||||
# (2) No target, so we better build it
|
||||
# (3) Prerequisite is newer than target
|
||||
# (4) The command line stored in the file named dir/.target.cmd
|
||||
# differed from actual command line. This happens when compiler
|
||||
# options changes
|
||||
# (5) No dir/.target.cmd file (used to store command line)
|
||||
# (6) No dir/.target.cmd file and target not listed in $(targets)
|
||||
# This is a good hint that there is a bug in the kbuild file
|
||||
ifeq ($(KBUILD_VERBOSE),2)
|
||||
why = \
|
||||
$(if $(filter $@, $(PHONY)),- due to target is PHONY, \
|
||||
$(if $(wildcard $@), \
|
||||
$(if $(newer-prereqs),- due to: $(newer-prereqs), \
|
||||
$(if $(cmd-check), \
|
||||
$(if $(cmd_$@),- due to command line change, \
|
||||
$(if $(filter $@, $(targets)), \
|
||||
- due to missing .cmd file, \
|
||||
- due to $(notdir $@) not in $$(targets) \
|
||||
) \
|
||||
) \
|
||||
) \
|
||||
), \
|
||||
- due to target missing \
|
||||
) \
|
||||
)
|
||||
|
||||
echo-why = $(call escsq, $(strip $(why)))
|
||||
endif
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# When a Kconfig string contains a filename, it is suitable for
|
||||
# passing to shell commands. It is surrounded by double-quotes, and
|
||||
# any double-quotes or backslashes within it are escaped by
|
||||
# backslashes.
|
||||
#
|
||||
# This is no use for dependencies or $(wildcard). We need to strip the
|
||||
# surrounding quotes and the escaping from quotes and backslashes, and
|
||||
# we *do* need to escape any spaces in the string. So, for example:
|
||||
#
|
||||
# Usage: $(eval $(call config_filename,FOO))
|
||||
#
|
||||
# Defines FOO_FILENAME based on the contents of the CONFIG_FOO option,
|
||||
# transformed as described above to be suitable for use within the
|
||||
# makefile.
|
||||
#
|
||||
# Also, if the filename is a relative filename and exists in the source
|
||||
# tree but not the build tree, define FOO_SRCPREFIX as $(srctree)/ to
|
||||
# be prefixed to *both* command invocation and dependencies.
|
||||
#
|
||||
# Note: We also print the filenames in the quiet_cmd_foo text, and
|
||||
# perhaps ought to have a version specially escaped for that purpose.
|
||||
# But it's only cosmetic, and $(patsubst "%",%,$(CONFIG_FOO)) is good
|
||||
# enough. It'll strip the quotes in the common case where there's no
|
||||
# space and it's a simple filename, and it'll retain the quotes when
|
||||
# there's a space. There are some esoteric cases in which it'll print
|
||||
# the wrong thing, but we don't really care. The actual dependencies
|
||||
# and commands *do* get it right, with various combinations of single
|
||||
# and double quotes, backslashes and spaces in the filenames.
|
||||
#
|
||||
###############################################################################
|
||||
#
|
||||
define config_filename
|
||||
ifneq ($$(CONFIG_$(1)),"")
|
||||
$(1)_FILENAME := $$(subst \\,\,$$(subst \$$(quote),$$(quote),$$(subst $$(space_escape),\$$(space),$$(patsubst "%",%,$$(subst $$(space),$$(space_escape),$$(CONFIG_$(1)))))))
|
||||
ifneq ($$(patsubst /%,%,$$(firstword $$($(1)_FILENAME))),$$(firstword $$($(1)_FILENAME)))
|
||||
else
|
||||
ifeq ($$(wildcard $$($(1)_FILENAME)),)
|
||||
ifneq ($$(wildcard $$(srctree)/$$($(1)_FILENAME)),)
|
||||
$(1)_SRCPREFIX := $(srctree)/
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endef
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
# delete partially updated (i.e. corrupted) files on error
|
||||
.DELETE_ON_ERROR:
|
||||
|
||||
# do not delete intermediate files automatically
|
||||
.SECONDARY:
|
||||
526
scripts/Makefile.build
Normal file
526
scripts/Makefile.build
Normal file
@ -0,0 +1,526 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
# ==========================================================================
|
||||
# Building
|
||||
# ==========================================================================
|
||||
|
||||
src := $(obj)
|
||||
|
||||
PHONY := __build
|
||||
__build:
|
||||
|
||||
# Init all relevant variables used in kbuild files so
|
||||
# 1) they have correct type
|
||||
# 2) they do not inherit any value from the environment
|
||||
obj-y :=
|
||||
obj-m :=
|
||||
lib-y :=
|
||||
lib-m :=
|
||||
always :=
|
||||
always-y :=
|
||||
always-m :=
|
||||
targets :=
|
||||
subdir-y :=
|
||||
subdir-m :=
|
||||
EXTRA_AFLAGS :=
|
||||
EXTRA_CFLAGS :=
|
||||
EXTRA_CPPFLAGS :=
|
||||
EXTRA_LDFLAGS :=
|
||||
asflags-y :=
|
||||
ccflags-y :=
|
||||
cppflags-y :=
|
||||
ldflags-y :=
|
||||
|
||||
subdir-asflags-y :=
|
||||
subdir-ccflags-y :=
|
||||
|
||||
# Read auto.conf if it exists, otherwise ignore
|
||||
-include include/config/auto.conf
|
||||
|
||||
include scripts/Kbuild.include
|
||||
|
||||
# The filename Kbuild has precedence over Makefile
|
||||
kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src))
|
||||
kbuild-file := $(if $(wildcard $(kbuild-dir)/Kbuild),$(kbuild-dir)/Kbuild,$(kbuild-dir)/Makefile)
|
||||
include $(kbuild-file)
|
||||
|
||||
include scripts/Makefile.lib
|
||||
|
||||
# Do not include hostprogs rules unless needed.
|
||||
# $(sort ...) is used here to remove duplicated words and excessive spaces.
|
||||
hostprogs := $(sort $(hostprogs))
|
||||
ifneq ($(hostprogs),)
|
||||
include scripts/Makefile.host
|
||||
endif
|
||||
|
||||
# Do not include userprogs rules unless needed.
|
||||
# $(sort ...) is used here to remove duplicated words and excessive spaces.
|
||||
userprogs := $(sort $(userprogs))
|
||||
ifneq ($(userprogs),)
|
||||
include scripts/Makefile.userprogs
|
||||
endif
|
||||
|
||||
ifndef obj
|
||||
$(warning kbuild: Makefile.build is included improperly)
|
||||
endif
|
||||
|
||||
ifeq ($(need-modorder),)
|
||||
ifneq ($(obj-m),)
|
||||
$(warning $(patsubst %.o,'%.ko',$(obj-m)) will not be built even though obj-m is specified.)
|
||||
$(warning You cannot use subdir-y/m to visit a module Makefile. Use obj-y/m instead.)
|
||||
endif
|
||||
endif
|
||||
|
||||
# ===========================================================================
|
||||
|
||||
# subdir-builtin and subdir-modorder may contain duplications. Use $(sort ...)
|
||||
subdir-builtin := $(sort $(filter %/built-in.a, $(real-obj-y)))
|
||||
subdir-modorder := $(sort $(filter %/modules.order, $(obj-m)))
|
||||
|
||||
targets-for-builtin := $(extra-y)
|
||||
|
||||
ifneq ($(strip $(lib-y) $(lib-m) $(lib-)),)
|
||||
targets-for-builtin += $(obj)/lib.a
|
||||
endif
|
||||
|
||||
ifdef need-builtin
|
||||
targets-for-builtin += $(obj)/built-in.a
|
||||
endif
|
||||
|
||||
targets-for-modules := $(patsubst %.o, %.mod, $(filter %.o, $(obj-m)))
|
||||
|
||||
ifdef need-modorder
|
||||
targets-for-modules += $(obj)/modules.order
|
||||
endif
|
||||
|
||||
targets += $(targets-for-builtin) $(targets-for-modules)
|
||||
|
||||
# Linus' kernel sanity checking tool
|
||||
ifeq ($(KBUILD_CHECKSRC),1)
|
||||
quiet_cmd_checksrc = CHECK $<
|
||||
cmd_checksrc = $(CHECK) $(CHECKFLAGS) $(c_flags) $<
|
||||
else ifeq ($(KBUILD_CHECKSRC),2)
|
||||
quiet_cmd_force_checksrc = CHECK $<
|
||||
cmd_force_checksrc = $(CHECK) $(CHECKFLAGS) $(c_flags) $<
|
||||
endif
|
||||
|
||||
ifneq ($(KBUILD_EXTRA_WARN),)
|
||||
cmd_checkdoc = $(srctree)/scripts/kernel-doc -none $<
|
||||
endif
|
||||
|
||||
# Compile C sources (.c)
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
quiet_cmd_cc_s_c = CC $(quiet_modtag) $@
|
||||
cmd_cc_s_c = $(CC) $(filter-out $(DEBUG_CFLAGS), $(c_flags)) -fverbose-asm -S -o $@ $<
|
||||
|
||||
$(obj)/%.s: $(src)/%.c FORCE
|
||||
$(call if_changed_dep,cc_s_c)
|
||||
|
||||
quiet_cmd_cpp_i_c = CPP $(quiet_modtag) $@
|
||||
cmd_cpp_i_c = $(CPP) $(c_flags) -o $@ $<
|
||||
|
||||
$(obj)/%.i: $(src)/%.c FORCE
|
||||
$(call if_changed_dep,cpp_i_c)
|
||||
|
||||
# These mirror gensymtypes_S and co below, keep them in synch.
|
||||
cmd_gensymtypes_c = \
|
||||
$(CPP) -D__GENKSYMS__ $(c_flags) $< | \
|
||||
scripts/genksyms/genksyms $(if $(1), -T $(2)) \
|
||||
$(patsubst y,-R,$(CONFIG_MODULE_REL_CRCS)) \
|
||||
$(if $(KBUILD_PRESERVE),-p) \
|
||||
-r $(firstword $(wildcard $(2:.symtypes=.symref) /dev/null))
|
||||
|
||||
quiet_cmd_cc_symtypes_c = SYM $(quiet_modtag) $@
|
||||
cmd_cc_symtypes_c = \
|
||||
$(call cmd_gensymtypes_c,true,$@) >/dev/null; \
|
||||
test -s $@ || rm -f $@
|
||||
|
||||
$(obj)/%.symtypes : $(src)/%.c FORCE
|
||||
$(call cmd,cc_symtypes_c)
|
||||
|
||||
# LLVM assembly
|
||||
# Generate .ll files from .c
|
||||
quiet_cmd_cc_ll_c = CC $(quiet_modtag) $@
|
||||
cmd_cc_ll_c = $(CC) $(c_flags) -emit-llvm -S -o $@ $<
|
||||
|
||||
$(obj)/%.ll: $(src)/%.c FORCE
|
||||
$(call if_changed_dep,cc_ll_c)
|
||||
|
||||
# C (.c) files
|
||||
# The C file is compiled and updated dependency information is generated.
|
||||
# (See cmd_cc_o_c + relevant part of rule_cc_o_c)
|
||||
|
||||
quiet_cmd_cc_o_c = CC $(quiet_modtag) $@
|
||||
cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $<
|
||||
|
||||
ifdef CONFIG_MODVERSIONS
|
||||
# When module versioning is enabled the following steps are executed:
|
||||
# o compile a <file>.o from <file>.c
|
||||
# o if <file>.o doesn't contain a __ksymtab version, i.e. does
|
||||
# not export symbols, it's done.
|
||||
# o otherwise, we calculate symbol versions using the good old
|
||||
# genksyms on the preprocessed source and postprocess them in a way
|
||||
# that they are usable as a linker script
|
||||
# o generate .tmp_<file>.o from <file>.o using the linker to
|
||||
# replace the unresolved symbols __crc_exported_symbol with
|
||||
# the actual value of the checksum generated by genksyms
|
||||
# o remove .tmp_<file>.o to <file>.o
|
||||
|
||||
cmd_modversions_c = \
|
||||
if $(OBJDUMP) -h $@ | grep -q __ksymtab; then \
|
||||
$(call cmd_gensymtypes_c,$(KBUILD_SYMTYPES),$(@:.o=.symtypes)) \
|
||||
> $(@D)/.tmp_$(@F:.o=.ver); \
|
||||
\
|
||||
$(LD) $(KBUILD_LDFLAGS) -r -o $(@D)/.tmp_$(@F) $@ \
|
||||
-T $(@D)/.tmp_$(@F:.o=.ver); \
|
||||
mv -f $(@D)/.tmp_$(@F) $@; \
|
||||
rm -f $(@D)/.tmp_$(@F:.o=.ver); \
|
||||
fi
|
||||
endif
|
||||
|
||||
ifdef CONFIG_FTRACE_MCOUNT_RECORD
|
||||
ifndef CC_USING_RECORD_MCOUNT
|
||||
# compiler will not generate __mcount_loc use recordmcount or recordmcount.pl
|
||||
ifdef BUILD_C_RECORDMCOUNT
|
||||
ifeq ("$(origin RECORDMCOUNT_WARN)", "command line")
|
||||
RECORDMCOUNT_FLAGS = -w
|
||||
endif
|
||||
# Due to recursion, we must skip empty.o.
|
||||
# The empty.o file is created in the make process in order to determine
|
||||
# the target endianness and word size. It is made before all other C
|
||||
# files, including recordmcount.
|
||||
sub_cmd_record_mcount = \
|
||||
if [ $(@) != "scripts/mod/empty.o" ]; then \
|
||||
$(objtree)/scripts/recordmcount $(RECORDMCOUNT_FLAGS) "$(@)"; \
|
||||
fi;
|
||||
recordmcount_source := $(srctree)/scripts/recordmcount.c \
|
||||
$(srctree)/scripts/recordmcount.h
|
||||
else
|
||||
sub_cmd_record_mcount = perl $(srctree)/scripts/recordmcount.pl "$(ARCH)" \
|
||||
"$(if $(CONFIG_CPU_BIG_ENDIAN),big,little)" \
|
||||
"$(if $(CONFIG_64BIT),64,32)" \
|
||||
"$(OBJDUMP)" "$(OBJCOPY)" "$(CC) $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS)" \
|
||||
"$(LD) $(KBUILD_LDFLAGS)" "$(NM)" "$(RM)" "$(MV)" \
|
||||
"$(if $(part-of-module),1,0)" "$(@)";
|
||||
recordmcount_source := $(srctree)/scripts/recordmcount.pl
|
||||
endif # BUILD_C_RECORDMCOUNT
|
||||
cmd_record_mcount = $(if $(findstring $(strip $(CC_FLAGS_FTRACE)),$(_c_flags)), \
|
||||
$(sub_cmd_record_mcount))
|
||||
endif # CC_USING_RECORD_MCOUNT
|
||||
endif # CONFIG_FTRACE_MCOUNT_RECORD
|
||||
|
||||
ifdef CONFIG_STACK_VALIDATION
|
||||
ifneq ($(SKIP_STACK_VALIDATION),1)
|
||||
|
||||
__objtool_obj := $(objtree)/tools/objtool/objtool
|
||||
|
||||
objtool_args = $(if $(CONFIG_UNWINDER_ORC),orc generate,check)
|
||||
|
||||
objtool_args += $(if $(part-of-module), --module,)
|
||||
|
||||
ifndef CONFIG_FRAME_POINTER
|
||||
objtool_args += --no-fp
|
||||
endif
|
||||
ifdef CONFIG_GCOV_KERNEL
|
||||
objtool_args += --no-unreachable
|
||||
endif
|
||||
ifdef CONFIG_RETPOLINE
|
||||
objtool_args += --retpoline
|
||||
endif
|
||||
ifdef CONFIG_X86_SMAP
|
||||
objtool_args += --uaccess
|
||||
endif
|
||||
|
||||
# 'OBJECT_FILES_NON_STANDARD := y': skip objtool checking for a directory
|
||||
# 'OBJECT_FILES_NON_STANDARD_foo.o := 'y': skip objtool checking for a file
|
||||
# 'OBJECT_FILES_NON_STANDARD_foo.o := 'n': override directory skip for a file
|
||||
cmd_objtool = $(if $(patsubst y%,, \
|
||||
$(OBJECT_FILES_NON_STANDARD_$(basetarget).o)$(OBJECT_FILES_NON_STANDARD)n), \
|
||||
$(__objtool_obj) $(objtool_args) $@)
|
||||
objtool_obj = $(if $(patsubst y%,, \
|
||||
$(OBJECT_FILES_NON_STANDARD_$(basetarget).o)$(OBJECT_FILES_NON_STANDARD)n), \
|
||||
$(__objtool_obj))
|
||||
|
||||
endif # SKIP_STACK_VALIDATION
|
||||
endif # CONFIG_STACK_VALIDATION
|
||||
|
||||
# Rebuild all objects when objtool changes, or is enabled/disabled.
|
||||
objtool_dep = $(objtool_obj) \
|
||||
$(wildcard include/config/orc/unwinder.h \
|
||||
include/config/stack/validation.h)
|
||||
|
||||
ifdef CONFIG_TRIM_UNUSED_KSYMS
|
||||
cmd_gen_ksymdeps = \
|
||||
$(CONFIG_SHELL) $(srctree)/scripts/gen_ksymdeps.sh $@ >> $(dot-target).cmd
|
||||
|
||||
# List module undefined symbols
|
||||
undefined_syms = $(NM) $< | $(AWK) '$$1 == "U" { printf("%s%s", x++ ? " " : "", $$2) }';
|
||||
endif
|
||||
|
||||
define rule_cc_o_c
|
||||
$(call cmd_and_fixdep,cc_o_c)
|
||||
$(call cmd,gen_ksymdeps)
|
||||
$(call cmd,checksrc)
|
||||
$(call cmd,checkdoc)
|
||||
$(call cmd,objtool)
|
||||
$(call cmd,modversions_c)
|
||||
$(call cmd,record_mcount)
|
||||
endef
|
||||
|
||||
define rule_as_o_S
|
||||
$(call cmd_and_fixdep,as_o_S)
|
||||
$(call cmd,gen_ksymdeps)
|
||||
$(call cmd,objtool)
|
||||
$(call cmd,modversions_S)
|
||||
endef
|
||||
|
||||
# Built-in and composite module parts
|
||||
$(obj)/%.o: $(src)/%.c $(recordmcount_source) $(objtool_dep) FORCE
|
||||
$(call if_changed_rule,cc_o_c)
|
||||
$(call cmd,force_checksrc)
|
||||
|
||||
cmd_mod = { \
|
||||
echo $(if $($*-objs)$($*-y)$($*-m), $(addprefix $(obj)/, $($*-objs) $($*-y) $($*-m)), $(@:.mod=.o)); \
|
||||
$(undefined_syms) echo; \
|
||||
} > $@
|
||||
|
||||
$(obj)/%.mod: $(obj)/%.o FORCE
|
||||
$(call if_changed,mod)
|
||||
|
||||
quiet_cmd_cc_lst_c = MKLST $@
|
||||
cmd_cc_lst_c = $(CC) $(c_flags) -g -c -o $*.o $< && \
|
||||
$(CONFIG_SHELL) $(srctree)/scripts/makelst $*.o \
|
||||
System.map $(OBJDUMP) > $@
|
||||
|
||||
$(obj)/%.lst: $(src)/%.c FORCE
|
||||
$(call if_changed_dep,cc_lst_c)
|
||||
|
||||
# Compile assembler sources (.S)
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
# .S file exports must have their C prototypes defined in asm/asm-prototypes.h
|
||||
# or a file that it includes, in order to get versioned symbols. We build a
|
||||
# dummy C file that includes asm-prototypes and the EXPORT_SYMBOL lines from
|
||||
# the .S file (with trailing ';'), and run genksyms on that, to extract vers.
|
||||
#
|
||||
# This is convoluted. The .S file must first be preprocessed to run guards and
|
||||
# expand names, then the resulting exports must be constructed into plain
|
||||
# EXPORT_SYMBOL(symbol); to build our dummy C file, and that gets preprocessed
|
||||
# to make the genksyms input.
|
||||
#
|
||||
# These mirror gensymtypes_c and co above, keep them in synch.
|
||||
cmd_gensymtypes_S = \
|
||||
{ echo "\#include <linux/kernel.h>" ; \
|
||||
echo "\#include <asm/asm-prototypes.h>" ; \
|
||||
$(CPP) $(a_flags) $< | \
|
||||
grep "\<___EXPORT_SYMBOL\>" | \
|
||||
sed 's/.*___EXPORT_SYMBOL[[:space:]]*\([a-zA-Z0-9_]*\)[[:space:]]*,.*/EXPORT_SYMBOL(\1);/' ; } | \
|
||||
$(CPP) -D__GENKSYMS__ $(c_flags) -xc - | \
|
||||
scripts/genksyms/genksyms $(if $(1), -T $(2)) \
|
||||
$(patsubst y,-R,$(CONFIG_MODULE_REL_CRCS)) \
|
||||
$(if $(KBUILD_PRESERVE),-p) \
|
||||
-r $(firstword $(wildcard $(2:.symtypes=.symref) /dev/null))
|
||||
|
||||
quiet_cmd_cc_symtypes_S = SYM $(quiet_modtag) $@
|
||||
cmd_cc_symtypes_S = \
|
||||
$(call cmd_gensymtypes_S,true,$@) >/dev/null; \
|
||||
test -s $@ || rm -f $@
|
||||
|
||||
$(obj)/%.symtypes : $(src)/%.S FORCE
|
||||
$(call cmd,cc_symtypes_S)
|
||||
|
||||
|
||||
quiet_cmd_cpp_s_S = CPP $(quiet_modtag) $@
|
||||
cmd_cpp_s_S = $(CPP) $(a_flags) -o $@ $<
|
||||
|
||||
$(obj)/%.s: $(src)/%.S FORCE
|
||||
$(call if_changed_dep,cpp_s_S)
|
||||
|
||||
quiet_cmd_as_o_S = AS $(quiet_modtag) $@
|
||||
cmd_as_o_S = $(CC) $(a_flags) -c -o $@ $<
|
||||
|
||||
ifdef CONFIG_ASM_MODVERSIONS
|
||||
|
||||
# versioning matches the C process described above, with difference that
|
||||
# we parse asm-prototypes.h C header to get function definitions.
|
||||
|
||||
cmd_modversions_S = \
|
||||
if $(OBJDUMP) -h $@ | grep -q __ksymtab; then \
|
||||
$(call cmd_gensymtypes_S,$(KBUILD_SYMTYPES),$(@:.o=.symtypes)) \
|
||||
> $(@D)/.tmp_$(@F:.o=.ver); \
|
||||
\
|
||||
$(LD) $(KBUILD_LDFLAGS) -r -o $(@D)/.tmp_$(@F) $@ \
|
||||
-T $(@D)/.tmp_$(@F:.o=.ver); \
|
||||
mv -f $(@D)/.tmp_$(@F) $@; \
|
||||
rm -f $(@D)/.tmp_$(@F:.o=.ver); \
|
||||
fi
|
||||
endif
|
||||
|
||||
$(obj)/%.o: $(src)/%.S $(objtool_dep) FORCE
|
||||
$(call if_changed_rule,as_o_S)
|
||||
|
||||
targets += $(filter-out $(subdir-builtin), $(real-obj-y))
|
||||
targets += $(filter-out $(subdir-modorder), $(real-obj-m))
|
||||
targets += $(lib-y) $(always-y) $(MAKECMDGOALS)
|
||||
|
||||
# Linker scripts preprocessor (.lds.S -> .lds)
|
||||
# ---------------------------------------------------------------------------
|
||||
quiet_cmd_cpp_lds_S = LDS $@
|
||||
cmd_cpp_lds_S = $(CPP) $(cpp_flags) -P -U$(ARCH) \
|
||||
-D__ASSEMBLY__ -DLINKER_SCRIPT -o $@ $<
|
||||
|
||||
$(obj)/%.lds: $(src)/%.lds.S FORCE
|
||||
$(call if_changed_dep,cpp_lds_S)
|
||||
|
||||
# ASN.1 grammar
|
||||
# ---------------------------------------------------------------------------
|
||||
quiet_cmd_asn1_compiler = ASN.1 $(basename $@).[ch]
|
||||
cmd_asn1_compiler = $(objtree)/scripts/asn1_compiler $< \
|
||||
$(basename $@).c $(basename $@).h
|
||||
|
||||
$(obj)/%.asn1.c $(obj)/%.asn1.h: $(src)/%.asn1 $(objtree)/scripts/asn1_compiler
|
||||
$(call cmd,asn1_compiler)
|
||||
|
||||
# Build the compiled-in targets
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
# To build objects in subdirs, we need to descend into the directories
|
||||
$(subdir-builtin): $(obj)/%/built-in.a: $(obj)/% ;
|
||||
$(subdir-modorder): $(obj)/%/modules.order: $(obj)/% ;
|
||||
|
||||
#
|
||||
# Rule to compile a set of .o files into one .a file (without symbol table)
|
||||
#
|
||||
|
||||
quiet_cmd_ar_builtin = AR $@
|
||||
cmd_ar_builtin = rm -f $@; $(AR) cDPrST $@ $(real-prereqs)
|
||||
|
||||
$(obj)/built-in.a: $(real-obj-y) FORCE
|
||||
$(call if_changed,ar_builtin)
|
||||
|
||||
#
|
||||
# Rule to create modules.order file
|
||||
#
|
||||
# Create commands to either record .ko file or cat modules.order from
|
||||
# a subdirectory
|
||||
# Add $(obj-m) as the prerequisite to avoid updating the timestamp of
|
||||
# modules.order unless contained modules are updated.
|
||||
|
||||
cmd_modules_order = { $(foreach m, $(real-prereqs), \
|
||||
$(if $(filter %/modules.order, $m), cat $m, echo $(patsubst %.o,%.ko,$m));) :; } \
|
||||
| $(AWK) '!x[$$0]++' - > $@
|
||||
|
||||
$(obj)/modules.order: $(obj-m) FORCE
|
||||
$(call if_changed,modules_order)
|
||||
|
||||
#
|
||||
# Rule to compile a set of .o files into one .a file (with symbol table)
|
||||
#
|
||||
$(obj)/lib.a: $(lib-y) FORCE
|
||||
$(call if_changed,ar)
|
||||
|
||||
# NOTE:
|
||||
# Do not replace $(filter %.o,^) with $(real-prereqs). When a single object
|
||||
# module is turned into a multi object module, $^ will contain header file
|
||||
# dependencies recorded in the .*.cmd file.
|
||||
quiet_cmd_link_multi-m = LD [M] $@
|
||||
cmd_link_multi-m = $(LD) $(ld_flags) -r -o $@ $(filter %.o,$^)
|
||||
|
||||
$(multi-used-m): FORCE
|
||||
$(call if_changed,link_multi-m)
|
||||
$(call multi_depend, $(multi-used-m), .o, -objs -y -m)
|
||||
|
||||
targets += $(multi-used-m)
|
||||
targets := $(filter-out $(PHONY), $(targets))
|
||||
|
||||
# Add intermediate targets:
|
||||
# When building objects with specific suffix patterns, add intermediate
|
||||
# targets that the final targets are derived from.
|
||||
intermediate_targets = $(foreach sfx, $(2), \
|
||||
$(patsubst %$(strip $(1)),%$(sfx), \
|
||||
$(filter %$(strip $(1)), $(targets))))
|
||||
# %.asn1.o <- %.asn1.[ch] <- %.asn1
|
||||
# %.dtb.o <- %.dtb.S <- %.dtb <- %.dts
|
||||
# %.lex.o <- %.lex.c <- %.l
|
||||
# %.tab.o <- %.tab.[ch] <- %.y
|
||||
targets += $(call intermediate_targets, .asn1.o, .asn1.c .asn1.h) \
|
||||
$(call intermediate_targets, .dtb.o, .dtb.S .dtb) \
|
||||
$(call intermediate_targets, .lex.o, .lex.c) \
|
||||
$(call intermediate_targets, .tab.o, .tab.c .tab.h)
|
||||
|
||||
# Build
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
ifdef single-build
|
||||
|
||||
KBUILD_SINGLE_TARGETS := $(filter $(obj)/%, $(KBUILD_SINGLE_TARGETS))
|
||||
|
||||
curdir-single := $(sort $(foreach x, $(KBUILD_SINGLE_TARGETS), \
|
||||
$(if $(filter $(x) $(basename $(x)).o, $(targets)), $(x))))
|
||||
|
||||
# Handle single targets without any rule: show "Nothing to be done for ..." or
|
||||
# "No rule to make target ..." depending on whether the target exists.
|
||||
unknown-single := $(filter-out $(addsuffix /%, $(subdir-ym)), \
|
||||
$(filter-out $(curdir-single), $(KBUILD_SINGLE_TARGETS)))
|
||||
|
||||
single-subdirs := $(foreach d, $(subdir-ym), \
|
||||
$(if $(filter $(d)/%, $(KBUILD_SINGLE_TARGETS)), $(d)))
|
||||
|
||||
__build: $(curdir-single) $(single-subdirs)
|
||||
ifneq ($(unknown-single),)
|
||||
$(Q)$(MAKE) -f /dev/null $(unknown-single)
|
||||
endif
|
||||
@:
|
||||
|
||||
ifeq ($(curdir-single),)
|
||||
# Nothing to do in this directory. Do not include any .*.cmd file for speed-up
|
||||
targets :=
|
||||
else
|
||||
targets += $(curdir-single)
|
||||
endif
|
||||
|
||||
else
|
||||
|
||||
__build: $(if $(KBUILD_BUILTIN), $(targets-for-builtin)) \
|
||||
$(if $(KBUILD_MODULES), $(targets-for-modules)) \
|
||||
$(subdir-ym) $(always-y)
|
||||
@:
|
||||
|
||||
endif
|
||||
|
||||
# Descending
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
PHONY += $(subdir-ym)
|
||||
$(subdir-ym):
|
||||
$(Q)$(MAKE) $(build)=$@ \
|
||||
$(if $(filter $@/, $(KBUILD_SINGLE_TARGETS)),single-build=) \
|
||||
need-builtin=$(if $(filter $@/built-in.a, $(subdir-builtin)),1) \
|
||||
need-modorder=$(if $(filter $@/modules.order, $(subdir-modorder)),1)
|
||||
|
||||
# Add FORCE to the prequisites of a target to force it to be always rebuilt.
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
PHONY += FORCE
|
||||
|
||||
FORCE:
|
||||
|
||||
# Read all saved command lines and dependencies for the $(targets) we
|
||||
# may be building above, using $(if_changed{,_dep}). As an
|
||||
# optimization, we don't need to read them if the target does not
|
||||
# exist, we will rebuild anyway in that case.
|
||||
|
||||
existing-targets := $(wildcard $(sort $(targets)))
|
||||
|
||||
-include $(foreach f,$(existing-targets),$(dir $(f)).$(notdir $(f)).cmd)
|
||||
|
||||
# Create directories for object files if they do not exist
|
||||
obj-dirs := $(sort $(patsubst %/,%, $(dir $(targets))))
|
||||
# If targets exist, their directories apparently exist. Skip mkdir.
|
||||
existing-dirs := $(sort $(patsubst %/,%, $(dir $(existing-targets))))
|
||||
obj-dirs := $(strip $(filter-out $(existing-dirs), $(obj-dirs)))
|
||||
ifneq ($(obj-dirs),)
|
||||
$(shell mkdir -p $(obj-dirs))
|
||||
endif
|
||||
|
||||
.PHONY: $(PHONY)
|
||||
73
scripts/Makefile.clean
Normal file
73
scripts/Makefile.clean
Normal file
@ -0,0 +1,73 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
# ==========================================================================
|
||||
# Cleaning up
|
||||
# ==========================================================================
|
||||
|
||||
src := $(obj)
|
||||
|
||||
PHONY := __clean
|
||||
__clean:
|
||||
|
||||
include scripts/Kbuild.include
|
||||
|
||||
# The filename Kbuild has precedence over Makefile
|
||||
kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src))
|
||||
include $(if $(wildcard $(kbuild-dir)/Kbuild), $(kbuild-dir)/Kbuild, $(kbuild-dir)/Makefile)
|
||||
|
||||
# Figure out what we need to build from the various variables
|
||||
# ==========================================================================
|
||||
|
||||
subdir-ymn := $(sort $(subdir-y) $(subdir-m) $(subdir-) \
|
||||
$(patsubst %/,%, $(filter %/, $(obj-y) $(obj-m) $(obj-))))
|
||||
|
||||
# Add subdir path
|
||||
|
||||
subdir-ymn := $(addprefix $(obj)/,$(subdir-ymn))
|
||||
|
||||
# build a list of files to remove, usually relative to the current
|
||||
# directory
|
||||
|
||||
__clean-files := \
|
||||
$(clean-files) $(targets) $(hostprogs) $(userprogs) \
|
||||
$(extra-y) $(extra-m) $(extra-) \
|
||||
$(always-y) $(always-m) $(always-) \
|
||||
$(hostprogs-always-y) $(hostprogs-always-m) $(hostprogs-always-) \
|
||||
$(userprogs-always-y) $(userprogs-always-m) $(userprogs-always-)
|
||||
|
||||
# deprecated
|
||||
__clean-files += $(always) $(hostprogs-y) $(hostprogs-m) $(hostprogs-)
|
||||
|
||||
__clean-files := $(filter-out $(no-clean-files), $(__clean-files))
|
||||
|
||||
# clean-files is given relative to the current directory, unless it
|
||||
# starts with $(objtree)/ (which means "./", so do not add "./" unless
|
||||
# you want to delete a file from the toplevel object directory).
|
||||
|
||||
__clean-files := $(wildcard \
|
||||
$(addprefix $(obj)/, $(filter-out $(objtree)/%, $(__clean-files))) \
|
||||
$(filter $(objtree)/%, $(__clean-files)))
|
||||
|
||||
# ==========================================================================
|
||||
|
||||
quiet_cmd_clean = CLEAN $(obj)
|
||||
cmd_clean = rm -rf $(__clean-files)
|
||||
|
||||
__clean: $(subdir-ymn)
|
||||
ifneq ($(strip $(__clean-files)),)
|
||||
$(call cmd,clean)
|
||||
endif
|
||||
@:
|
||||
|
||||
|
||||
# ===========================================================================
|
||||
# Generic stuff
|
||||
# ===========================================================================
|
||||
|
||||
# Descending
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
PHONY += $(subdir-ymn)
|
||||
$(subdir-ymn):
|
||||
$(Q)$(MAKE) $(clean)=$@
|
||||
|
||||
.PHONY: $(PHONY)
|
||||
Reference in New Issue
Block a user