mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2024-12-29 17:23:36 +00:00
59b2bd05f5
In Linux build system, build targets and installation targets are separated. Examples are: - 'make vmlinux' -> 'make install' - 'make modules' -> 'make modules_install' - 'make dtbs' -> 'make dtbs_install' - 'make vdso' -> 'make vdso_install' The intention is to run the build targets under the normal privilege, then the installation targets under the root privilege since we need the write permission to the system directories. We have 'make headers_install' but the corresponding 'make headers' stage does not exist. The purpose of headers_install is to provide the kernel interface to C library. So, nobody would try to install headers to /usr/include directly. If 'sudo make INSTALL_HDR_PATH=/usr/include headers_install' were run, some build artifacts in the kernel tree would be owned by root because some of uapi headers are generated by 'uapi-asm-generic', 'archheaders' targets. Anyway, I believe it makes sense to split the header installation into two stages. [1] 'make headers' Process headers in uapi directories by scripts/headers_install.sh and copy them to usr/include [2] 'make headers_install' Copy '*.h' verbatim from usr/include to $(INSTALL_HDR_PATH)/include For the backward compatibility, 'headers_install' depends on 'headers'. Some samples expect uapi headers in usr/include. So, the 'headers' target is useful to build up them in the fixed location usr/include irrespective of INSTALL_HDR_PATH. Another benefit is to stop polluting the final destination with the time-stamp files '.install' and '.check'. Maybe you can see them in your toolchains. Lastly, my main motivation is to prepare for compile-testing uapi headers. To build something, we have to save an object and .*.cmd somewhere. The usr/include/ will be the work directory for that. Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
123 lines
3.7 KiB
Makefile
123 lines
3.7 KiB
Makefile
# SPDX-License-Identifier: GPL-2.0
|
|
# ==========================================================================
|
|
# Installing headers
|
|
#
|
|
# All headers under include/uapi, include/generated/uapi,
|
|
# arch/<arch>/include/uapi and arch/<arch>/include/generated/uapi are
|
|
# exported.
|
|
# They are preprocessed to remove __KERNEL__ section of the file.
|
|
#
|
|
# ==========================================================================
|
|
|
|
PHONY := __headers
|
|
__headers:
|
|
|
|
include scripts/Kbuild.include
|
|
|
|
srcdir := $(srctree)/$(obj)
|
|
|
|
# When make is run under a fakechroot environment, the function
|
|
# $(wildcard $(srcdir)/*/.) doesn't only return directories, but also regular
|
|
# files. So, we are using a combination of sort/dir/wildcard which works
|
|
# with fakechroot.
|
|
subdirs := $(patsubst $(srcdir)/%/,%,\
|
|
$(filter-out $(srcdir)/,\
|
|
$(sort $(dir $(wildcard $(srcdir)/*/)))))
|
|
|
|
# Recursion
|
|
__headers: $(subdirs)
|
|
|
|
PHONY += $(subdirs)
|
|
$(subdirs):
|
|
$(Q)$(MAKE) $(hdr-inst)=$(obj)/$@ dst=$(dst)/$@
|
|
|
|
# Skip header install/check for include/uapi and arch/$(SRCARCH)/include/uapi.
|
|
# We have only sub-directories there.
|
|
skip-inst := $(if $(filter %/uapi,$(obj)),1)
|
|
|
|
ifeq ($(skip-inst),)
|
|
|
|
# Kbuild file is optional
|
|
kbuild-file := $(srctree)/$(obj)/Kbuild
|
|
-include $(kbuild-file)
|
|
|
|
installdir := usr/$(dst)
|
|
gendir := $(objtree)/$(subst include/,include/generated/,$(obj))
|
|
header-files := $(notdir $(wildcard $(srcdir)/*.h))
|
|
header-files := $(filter-out $(no-export-headers), $(header-files))
|
|
genhdr-files := $(notdir $(wildcard $(gendir)/*.h))
|
|
genhdr-files := $(filter-out $(header-files), $(genhdr-files))
|
|
|
|
# files used to track state of install/check
|
|
install-file := $(installdir)/.install
|
|
check-file := $(installdir)/.check
|
|
|
|
# all headers files for this dir
|
|
all-files := $(header-files) $(genhdr-files)
|
|
output-files := $(addprefix $(installdir)/, $(all-files))
|
|
|
|
# Work out what needs to be removed
|
|
oldheaders := $(patsubst $(installdir)/%,%,$(wildcard $(installdir)/*.h))
|
|
unwanted := $(filter-out $(all-files),$(oldheaders))
|
|
|
|
# Prefix unwanted with full paths to objtree
|
|
unwanted-file := $(addprefix $(installdir)/, $(unwanted))
|
|
|
|
printdir = $(patsubst %/,%,$(dir $@))
|
|
|
|
quiet_cmd_install = INSTALL $(printdir) ($(words $(all-files))\
|
|
file$(if $(word 2, $(all-files)),s))
|
|
cmd_install = \
|
|
$(CONFIG_SHELL) $< $(installdir) $(srcdir) $(header-files); \
|
|
$(CONFIG_SHELL) $< $(installdir) $(gendir) $(genhdr-files); \
|
|
touch $@
|
|
|
|
quiet_cmd_remove = REMOVE $(unwanted)
|
|
cmd_remove = rm -f $(unwanted-file)
|
|
|
|
quiet_cmd_check = CHECK $(printdir) ($(words $(all-files)) files)
|
|
# Headers list can be pretty long, xargs helps to avoid
|
|
# the "Argument list too long" error.
|
|
cmd_check = for f in $(all-files); do \
|
|
echo "$(installdir)/$${f}"; done \
|
|
| xargs \
|
|
$(PERL) $< usr/include $(SRCARCH); \
|
|
touch $@
|
|
|
|
ifndef HDRCHECK
|
|
# Rules for installing headers
|
|
__headers: $(install-file)
|
|
@:
|
|
|
|
targets += $(install-file)
|
|
$(install-file): scripts/headers_install.sh \
|
|
$(addprefix $(srcdir)/,$(header-files)) \
|
|
$(addprefix $(gendir)/,$(genhdr-files)) FORCE
|
|
$(if $(unwanted),$(call cmd,remove),)
|
|
$(if $(wildcard $(dir $@)),,$(shell mkdir -p $(dir $@)))
|
|
$(call if_changed,install)
|
|
|
|
else
|
|
__headers: $(check-file)
|
|
@:
|
|
|
|
targets += $(check-file)
|
|
$(check-file): scripts/headers_check.pl $(output-files) FORCE
|
|
$(call if_changed,check)
|
|
|
|
endif
|
|
|
|
cmd_files := $(wildcard \
|
|
$(foreach f,$(sort $(targets)),$(dir $(f)).$(notdir $(f)).cmd))
|
|
|
|
ifneq ($(cmd_files),)
|
|
include $(cmd_files)
|
|
endif
|
|
|
|
endif # skip-inst
|
|
|
|
PHONY += FORCE
|
|
FORCE: ;
|
|
|
|
.PHONY: $(PHONY)
|