summaryrefslogtreecommitdiffstats
path: root/tools/build/Makefile
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--tools/build/Makefile54
-rw-r--r--tools/build/Makefile.build162
-rw-r--r--tools/build/Makefile.feature288
-rw-r--r--tools/build/Makefile.include10
4 files changed, 514 insertions, 0 deletions
diff --git a/tools/build/Makefile b/tools/build/Makefile
new file mode 100644
index 000000000..17cdf01e2
--- /dev/null
+++ b/tools/build/Makefile
@@ -0,0 +1,54 @@
+# SPDX-License-Identifier: GPL-2.0
+ifeq ($(srctree),)
+srctree := $(patsubst %/,%,$(dir $(CURDIR)))
+srctree := $(patsubst %/,%,$(dir $(srctree)))
+endif
+
+include $(srctree)/tools//scripts/Makefile.include
+
+define allow-override
+ $(if $(or $(findstring environment,$(origin $(1))),\
+ $(findstring command line,$(origin $(1)))),,\
+ $(eval $(1) = $(2)))
+endef
+
+$(call allow-override,CC,$(CROSS_COMPILE)gcc)
+$(call allow-override,LD,$(CROSS_COMPILE)ld)
+
+export HOSTCC HOSTLD HOSTAR
+
+ifeq ($(V),1)
+ Q =
+else
+ Q = @
+endif
+
+export Q srctree CC LD
+
+MAKEFLAGS := --no-print-directory
+build := -f $(srctree)/tools/build/Makefile.build dir=. obj
+
+all: $(OUTPUT)fixdep
+
+# Make sure there's anything to clean,
+# feature contains check for existing OUTPUT
+TMP_O := $(if $(OUTPUT),$(OUTPUT)feature/,./)
+
+clean:
+ $(call QUIET_CLEAN, fixdep)
+ $(Q)find $(or $(OUTPUT),.) -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete
+ $(Q)rm -f $(OUTPUT)fixdep
+ $(call QUIET_CLEAN, feature-detect)
+ifneq ($(wildcard $(TMP_O)),)
+ $(Q)$(MAKE) -C feature OUTPUT=$(TMP_O) clean >/dev/null
+endif
+
+$(OUTPUT)fixdep-in.o: FORCE
+ $(Q)$(MAKE) $(build)=fixdep
+
+$(OUTPUT)fixdep: $(OUTPUT)fixdep-in.o
+ $(QUIET_LINK)$(HOSTCC) $(KBUILD_HOSTLDFLAGS) -o $@ $<
+
+FORCE:
+
+.PHONY: FORCE
diff --git a/tools/build/Makefile.build b/tools/build/Makefile.build
new file mode 100644
index 000000000..715092fc6
--- /dev/null
+++ b/tools/build/Makefile.build
@@ -0,0 +1,162 @@
+# SPDX-License-Identifier: GPL-2.0
+###
+# Main build makefile.
+#
+# Lots of this code have been borrowed or heavily inspired from parts
+# of kbuild code, which is not credited, but mostly developed by:
+#
+# Copyright (C) Sam Ravnborg <sam@mars.ravnborg.org>, 2015
+# Copyright (C) Linus Torvalds <torvalds@linux-foundation.org>, 2015
+#
+
+PHONY := __build
+__build:
+
+ifeq ($(V),1)
+ quiet =
+ Q =
+else
+ quiet=quiet_
+ Q=@
+endif
+
+ifneq ($(findstring s,$(filter-out --%,$(MAKEFLAGS))),)
+ quiet=silent_
+endif
+
+build-dir := $(srctree)/tools/build
+
+# Define $(fixdep) for dep-cmd function
+ifeq ($(OUTPUT),)
+ fixdep := $(build-dir)/fixdep
+else
+ fixdep := $(OUTPUT)/fixdep
+endif
+
+# Generic definitions
+include $(build-dir)/Build.include
+
+# do not force detected configuration
+-include $(OUTPUT).config-detected
+
+# Init all relevant variables used in build files so
+# 1) they have correct type
+# 2) they do not inherit any value from the environment
+subdir-y :=
+obj-y :=
+subdir-y :=
+subdir-obj-y :=
+
+# Build definitions
+build-file := $(dir)/Build
+-include $(build-file)
+
+quiet_cmd_flex = FLEX $@
+quiet_cmd_bison = BISON $@
+
+# Create directory unless it exists
+quiet_cmd_mkdir = MKDIR $(dir $@)
+ cmd_mkdir = mkdir -p $(dir $@)
+ rule_mkdir = $(if $(wildcard $(dir $@)),,@$(call echo-cmd,mkdir) $(cmd_mkdir))
+
+# Compile command
+quiet_cmd_cc_o_c = CC $@
+ cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $<
+
+quiet_cmd_host_cc_o_c = HOSTCC $@
+ cmd_host_cc_o_c = $(HOSTCC) $(host_c_flags) -c -o $@ $<
+
+quiet_cmd_cxx_o_c = CXX $@
+ cmd_cxx_o_c = $(CXX) $(cxx_flags) -c -o $@ $<
+
+quiet_cmd_cpp_i_c = CPP $@
+ cmd_cpp_i_c = $(CC) $(c_flags) -E -o $@ $<
+
+quiet_cmd_cc_s_c = AS $@
+ cmd_cc_s_c = $(CC) $(c_flags) -S -o $@ $<
+
+quiet_cmd_gen = GEN $@
+
+# Link agregate command
+# If there's nothing to link, create empty $@ object.
+quiet_cmd_ld_multi = LD $@
+ cmd_ld_multi = $(if $(strip $(obj-y)),\
+ $(LD) -r -o $@ $(filter $(obj-y),$^),rm -f $@; $(AR) rcs $@)
+
+quiet_cmd_host_ld_multi = HOSTLD $@
+ cmd_host_ld_multi = $(if $(strip $(obj-y)),\
+ $(HOSTLD) -r -o $@ $(filter $(obj-y),$^),rm -f $@; $(HOSTAR) rcs $@)
+
+ifneq ($(filter $(obj),$(hostprogs)),)
+ host = host_
+endif
+
+# Build rules
+$(OUTPUT)%.o: %.c FORCE
+ $(call rule_mkdir)
+ $(call if_changed_dep,$(host)cc_o_c)
+
+$(OUTPUT)%.o: %.cpp FORCE
+ $(call rule_mkdir)
+ $(call if_changed_dep,cxx_o_c)
+
+$(OUTPUT)%.o: %.S FORCE
+ $(call rule_mkdir)
+ $(call if_changed_dep,$(host)cc_o_c)
+
+$(OUTPUT)%.i: %.c FORCE
+ $(call rule_mkdir)
+ $(call if_changed_dep,cpp_i_c)
+
+$(OUTPUT)%.s: %.S FORCE
+ $(call rule_mkdir)
+ $(call if_changed_dep,cpp_i_c)
+
+$(OUTPUT)%.s: %.c FORCE
+ $(call rule_mkdir)
+ $(call if_changed_dep,cc_s_c)
+
+# Gather build data:
+# obj-y - list of build objects
+# subdir-y - list of directories to nest
+# subdir-obj-y - list of directories objects 'dir/$(obj)-in.o'
+obj-y := $($(obj)-y)
+subdir-y := $(patsubst %/,%,$(filter %/, $(obj-y)))
+obj-y := $(patsubst %/, %/$(obj)-in.o, $(obj-y))
+subdir-obj-y := $(filter %/$(obj)-in.o, $(obj-y))
+
+# '$(OUTPUT)/dir' prefix to all objects
+objprefix := $(subst ./,,$(OUTPUT)$(dir)/)
+obj-y := $(addprefix $(objprefix),$(obj-y))
+subdir-obj-y := $(addprefix $(objprefix),$(subdir-obj-y))
+
+# Final '$(obj)-in.o' object
+in-target := $(objprefix)$(obj)-in.o
+
+PHONY += $(subdir-y)
+
+$(subdir-y):
+ $(Q)$(MAKE) -f $(build-dir)/Makefile.build dir=$(dir)/$@ obj=$(obj)
+
+$(sort $(subdir-obj-y)): $(subdir-y) ;
+
+$(in-target): $(obj-y) FORCE
+ $(call rule_mkdir)
+ $(call if_changed,$(host)ld_multi)
+
+__build: $(in-target)
+ @:
+
+PHONY += FORCE
+FORCE:
+
+# Include all cmd files to get all the dependency rules
+# for all objects included
+targets := $(wildcard $(sort $(obj-y) $(in-target) $(MAKECMDGOALS)))
+cmd_files := $(wildcard $(foreach f,$(targets),$(dir $(f)).$(notdir $(f)).cmd))
+
+ifneq ($(cmd_files),)
+ include $(cmd_files)
+endif
+
+.PHONY: $(PHONY)
diff --git a/tools/build/Makefile.feature b/tools/build/Makefile.feature
new file mode 100644
index 000000000..38f8851bd
--- /dev/null
+++ b/tools/build/Makefile.feature
@@ -0,0 +1,288 @@
+# SPDX-License-Identifier: GPL-2.0-only
+feature_dir := $(srctree)/tools/build/feature
+
+ifneq ($(OUTPUT),)
+ OUTPUT_FEATURES = $(OUTPUT)feature/
+ $(shell mkdir -p $(OUTPUT_FEATURES))
+endif
+
+feature_check = $(eval $(feature_check_code))
+define feature_check_code
+ feature-$(1) := $(shell $(MAKE) OUTPUT=$(OUTPUT_FEATURES) CC="$(CC)" CXX="$(CXX)" CFLAGS="$(EXTRA_CFLAGS) $(FEATURE_CHECK_CFLAGS-$(1))" CXXFLAGS="$(EXTRA_CXXFLAGS) $(FEATURE_CHECK_CXXFLAGS-$(1))" LDFLAGS="$(LDFLAGS) $(FEATURE_CHECK_LDFLAGS-$(1))" -C $(feature_dir) $(OUTPUT_FEATURES)test-$1.bin >/dev/null 2>/dev/null && echo 1 || echo 0)
+endef
+
+feature_set = $(eval $(feature_set_code))
+define feature_set_code
+ feature-$(1) := 1
+endef
+
+#
+# Build the feature check binaries in parallel, ignore errors, ignore return value and suppress output:
+#
+
+#
+# Note that this is not a complete list of all feature tests, just
+# those that are typically built on a fully configured system.
+#
+# [ Feature tests not mentioned here have to be built explicitly in
+# the rule that uses them - an example for that is the 'bionic'
+# feature check. ]
+#
+FEATURE_TESTS_BASIC := \
+ backtrace \
+ dwarf \
+ dwarf_getlocations \
+ eventfd \
+ fortify-source \
+ get_current_dir_name \
+ gettid \
+ glibc \
+ libbfd \
+ libbfd-buildid \
+ libcap \
+ libelf \
+ libelf-getphdrnum \
+ libelf-gelf_getnote \
+ libelf-getshdrstrndx \
+ libnuma \
+ numa_num_possible_cpus \
+ libperl \
+ libpython \
+ libslang \
+ libslang-include-subdir \
+ libtraceevent \
+ libtracefs \
+ libcrypto \
+ libunwind \
+ pthread-attr-setaffinity-np \
+ pthread-barrier \
+ reallocarray \
+ stackprotector-all \
+ timerfd \
+ libdw-dwarf-unwind \
+ zlib \
+ lzma \
+ get_cpuid \
+ bpf \
+ sched_getcpu \
+ sdt \
+ setns \
+ libaio \
+ libzstd \
+ disassembler-four-args \
+ disassembler-init-styled \
+ file-handle
+
+# FEATURE_TESTS_BASIC + FEATURE_TESTS_EXTRA is the complete list
+# of all feature tests
+FEATURE_TESTS_EXTRA := \
+ bionic \
+ compile-32 \
+ compile-x32 \
+ cplus-demangle \
+ gtk2 \
+ gtk2-infobar \
+ hello \
+ libbabeltrace \
+ libbfd-liberty \
+ libbfd-liberty-z \
+ libopencsd \
+ libunwind-x86 \
+ libunwind-x86_64 \
+ libunwind-arm \
+ libunwind-aarch64 \
+ libunwind-debug-frame \
+ libunwind-debug-frame-arm \
+ libunwind-debug-frame-aarch64 \
+ cxx \
+ llvm \
+ llvm-version \
+ clang \
+ libbpf \
+ libbpf-btf__load_from_kernel_by_id \
+ libbpf-bpf_prog_load \
+ libbpf-bpf_object__next_program \
+ libbpf-bpf_object__next_map \
+ libbpf-bpf_program__set_insns \
+ libbpf-bpf_create_map \
+ libpfm4 \
+ libdebuginfod \
+ clang-bpf-co-re
+
+
+FEATURE_TESTS ?= $(FEATURE_TESTS_BASIC)
+
+ifeq ($(FEATURE_TESTS),all)
+ FEATURE_TESTS := $(FEATURE_TESTS_BASIC) $(FEATURE_TESTS_EXTRA)
+endif
+
+FEATURE_DISPLAY ?= \
+ dwarf \
+ dwarf_getlocations \
+ glibc \
+ libbfd \
+ libbfd-buildid \
+ libcap \
+ libelf \
+ libnuma \
+ numa_num_possible_cpus \
+ libperl \
+ libpython \
+ libcrypto \
+ libunwind \
+ libdw-dwarf-unwind \
+ zlib \
+ lzma \
+ get_cpuid \
+ bpf \
+ libaio \
+ libzstd
+
+#
+# Declare group members of a feature to display the logical OR of the detection
+# result instead of each member result.
+#
+FEATURE_GROUP_MEMBERS-libbfd = libbfd-liberty libbfd-liberty-z
+
+# Set FEATURE_CHECK_(C|LD)FLAGS-all for all FEATURE_TESTS features.
+# If in the future we need per-feature checks/flags for features not
+# mentioned in this list we need to refactor this ;-).
+set_test_all_flags = $(eval $(set_test_all_flags_code))
+define set_test_all_flags_code
+ FEATURE_CHECK_CFLAGS-all += $(FEATURE_CHECK_CFLAGS-$(1))
+ FEATURE_CHECK_LDFLAGS-all += $(FEATURE_CHECK_LDFLAGS-$(1))
+endef
+
+$(foreach feat,$(FEATURE_TESTS),$(call set_test_all_flags,$(feat)))
+
+#
+# Special fast-path for the 'all features are available' case:
+#
+$(call feature_check,all,$(MSG))
+
+#
+# Just in case the build freshly failed, make sure we print the
+# feature matrix:
+#
+ifeq ($(feature-all), 1)
+ #
+ # test-all.c passed - just set all the core feature flags to 1:
+ #
+ $(foreach feat,$(FEATURE_TESTS),$(call feature_set,$(feat)))
+ #
+ # test-all.c does not comprise these tests, so we need to
+ # for this case to get features proper values
+ #
+ $(call feature_check,compile-32)
+ $(call feature_check,compile-x32)
+ $(call feature_check,bionic)
+ $(call feature_check,libbabeltrace)
+else
+ $(foreach feat,$(FEATURE_TESTS),$(call feature_check,$(feat)))
+endif
+
+#
+# Print the result of the feature test:
+#
+feature_print_status = $(eval $(feature_print_status_code))
+
+feature_group = $(eval $(feature_gen_group)) $(GROUP)
+
+define feature_gen_group
+ GROUP := $(1)
+ ifneq ($(feature_verbose),1)
+ GROUP += $(FEATURE_GROUP_MEMBERS-$(1))
+ endif
+endef
+
+define feature_print_status_code
+ ifneq (,$(filter 1,$(foreach feat,$(call feature_group,$(feat)),$(feature-$(feat)))))
+ MSG = $(shell printf '...%40s: [ \033[32mon\033[m ]' $(1))
+ else
+ MSG = $(shell printf '...%40s: [ \033[31mOFF\033[m ]' $(1))
+ endif
+endef
+
+feature_print_text = $(eval $(feature_print_text_code))
+define feature_print_text_code
+ MSG = $(shell printf '...%40s: %s' $(1) $(2))
+endef
+
+#
+# generates feature value assignment for name, like:
+# $(call feature_assign,dwarf) == feature-dwarf=1
+#
+feature_assign = feature-$(1)=$(feature-$(1))
+
+FEATURE_DUMP_FILENAME = $(OUTPUT)FEATURE-DUMP$(FEATURE_USER)
+FEATURE_DUMP := $(shell touch $(FEATURE_DUMP_FILENAME); cat $(FEATURE_DUMP_FILENAME))
+
+feature_dump_check = $(eval $(feature_dump_check_code))
+define feature_dump_check_code
+ ifeq ($(findstring $(1),$(FEATURE_DUMP)),)
+ $(2) := 1
+ endif
+endef
+
+#
+# First check if any test from FEATURE_DISPLAY
+# and set feature_display := 1 if it does
+$(foreach feat,$(FEATURE_DISPLAY),$(call feature_dump_check,$(call feature_assign,$(feat)),feature_display))
+
+#
+# Now also check if any other test changed,
+# so we force FEATURE-DUMP generation
+$(foreach feat,$(FEATURE_TESTS),$(call feature_dump_check,$(call feature_assign,$(feat)),feature_dump_changed))
+
+# The $(feature_display) controls the default detection message
+# output. It's set if:
+# - detected features differes from stored features from
+# last build (in $(FEATURE_DUMP_FILENAME) file)
+# - one of the $(FEATURE_DISPLAY) is not detected
+# - VF is enabled
+
+ifeq ($(feature_dump_changed),1)
+ $(shell rm -f $(FEATURE_DUMP_FILENAME))
+ $(foreach feat,$(FEATURE_TESTS),$(shell echo "$(call feature_assign,$(feat))" >> $(FEATURE_DUMP_FILENAME)))
+endif
+
+feature_display_check = $(eval $(feature_check_display_code))
+define feature_check_display_code
+ ifneq ($(feature-$(1)), 1)
+ feature_display := 1
+ endif
+endef
+
+$(foreach feat,$(FEATURE_DISPLAY),$(call feature_display_check,$(feat)))
+
+ifeq ($(VF),1)
+ feature_display := 1
+ feature_verbose := 1
+endif
+
+ifneq ($(feature_verbose),1)
+ #
+ # Determine the features to omit from the displayed message, as only the
+ # logical OR of the detection result will be shown.
+ #
+ FEATURE_OMIT := $(foreach feat,$(FEATURE_DISPLAY),$(FEATURE_GROUP_MEMBERS-$(feat)))
+endif
+
+feature_display_entries = $(eval $(feature_display_entries_code))
+define feature_display_entries_code
+ ifeq ($(feature_display),1)
+ $$(info )
+ $$(info Auto-detecting system features:)
+ $(foreach feat,$(filter-out $(FEATURE_OMIT),$(FEATURE_DISPLAY)),$(call feature_print_status,$(feat),) $$(info $(MSG)))
+ endif
+
+ ifeq ($(feature_verbose),1)
+ $(eval TMP := $(filter-out $(FEATURE_DISPLAY),$(FEATURE_TESTS)))
+ $(foreach feat,$(TMP),$(call feature_print_status,$(feat),) $$(info $(MSG)))
+ endif
+endef
+
+ifeq ($(FEATURE_DISPLAY_DEFERRED),)
+ $(call feature_display_entries)
+ $(info )
+endif
diff --git a/tools/build/Makefile.include b/tools/build/Makefile.include
new file mode 100644
index 000000000..8dadaa0fb
--- /dev/null
+++ b/tools/build/Makefile.include
@@ -0,0 +1,10 @@
+# SPDX-License-Identifier: GPL-2.0-only
+build := -f $(srctree)/tools/build/Makefile.build dir=. obj
+
+fixdep:
+ $(Q)$(MAKE) -C $(srctree)/tools/build CFLAGS= LDFLAGS= $(OUTPUT)fixdep
+
+fixdep-clean:
+ $(Q)$(MAKE) -C $(srctree)/tools/build clean
+
+.PHONY: fixdep