162306a36Sopenharmony_ci# SPDX-License-Identifier: GPL-2.0-only
262306a36Sopenharmony_cifeature_dir := $(srctree)/tools/build/feature
362306a36Sopenharmony_ci
462306a36Sopenharmony_ciifneq ($(OUTPUT),)
562306a36Sopenharmony_ci  OUTPUT_FEATURES = $(OUTPUT)feature/
662306a36Sopenharmony_ci  $(shell mkdir -p $(OUTPUT_FEATURES))
762306a36Sopenharmony_ciendif
862306a36Sopenharmony_ci
962306a36Sopenharmony_cifeature_check = $(eval $(feature_check_code))
1062306a36Sopenharmony_cidefine feature_check_code
1162306a36Sopenharmony_ci  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)
1262306a36Sopenharmony_ciendef
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_cifeature_set = $(eval $(feature_set_code))
1562306a36Sopenharmony_cidefine feature_set_code
1662306a36Sopenharmony_ci  feature-$(1) := 1
1762306a36Sopenharmony_ciendef
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ci#
2062306a36Sopenharmony_ci# Build the feature check binaries in parallel, ignore errors, ignore return value and suppress output:
2162306a36Sopenharmony_ci#
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_ci#
2462306a36Sopenharmony_ci# Note that this is not a complete list of all feature tests, just
2562306a36Sopenharmony_ci# those that are typically built on a fully configured system.
2662306a36Sopenharmony_ci#
2762306a36Sopenharmony_ci# [ Feature tests not mentioned here have to be built explicitly in
2862306a36Sopenharmony_ci#   the rule that uses them - an example for that is the 'bionic'
2962306a36Sopenharmony_ci#   feature check. ]
3062306a36Sopenharmony_ci#
3162306a36Sopenharmony_ciFEATURE_TESTS_BASIC :=                  \
3262306a36Sopenharmony_ci        backtrace                       \
3362306a36Sopenharmony_ci        dwarf                           \
3462306a36Sopenharmony_ci        dwarf_getlocations              \
3562306a36Sopenharmony_ci        eventfd                         \
3662306a36Sopenharmony_ci        fortify-source                  \
3762306a36Sopenharmony_ci        get_current_dir_name            \
3862306a36Sopenharmony_ci        gettid				\
3962306a36Sopenharmony_ci        glibc                           \
4062306a36Sopenharmony_ci        libbfd                          \
4162306a36Sopenharmony_ci        libbfd-buildid			\
4262306a36Sopenharmony_ci        libcap                          \
4362306a36Sopenharmony_ci        libelf                          \
4462306a36Sopenharmony_ci        libelf-getphdrnum               \
4562306a36Sopenharmony_ci        libelf-gelf_getnote             \
4662306a36Sopenharmony_ci        libelf-getshdrstrndx            \
4762306a36Sopenharmony_ci        libnuma                         \
4862306a36Sopenharmony_ci        numa_num_possible_cpus          \
4962306a36Sopenharmony_ci        libperl                         \
5062306a36Sopenharmony_ci        libpython                       \
5162306a36Sopenharmony_ci        libslang                        \
5262306a36Sopenharmony_ci        libslang-include-subdir         \
5362306a36Sopenharmony_ci        libtraceevent                   \
5462306a36Sopenharmony_ci        libtracefs                      \
5562306a36Sopenharmony_ci        libcrypto                       \
5662306a36Sopenharmony_ci        libunwind                       \
5762306a36Sopenharmony_ci        pthread-attr-setaffinity-np     \
5862306a36Sopenharmony_ci        pthread-barrier     		\
5962306a36Sopenharmony_ci        reallocarray                    \
6062306a36Sopenharmony_ci        stackprotector-all              \
6162306a36Sopenharmony_ci        timerfd                         \
6262306a36Sopenharmony_ci        libdw-dwarf-unwind              \
6362306a36Sopenharmony_ci        zlib                            \
6462306a36Sopenharmony_ci        lzma                            \
6562306a36Sopenharmony_ci        get_cpuid                       \
6662306a36Sopenharmony_ci        bpf                             \
6762306a36Sopenharmony_ci        scandirat			\
6862306a36Sopenharmony_ci        sched_getcpu			\
6962306a36Sopenharmony_ci        sdt				\
7062306a36Sopenharmony_ci        setns				\
7162306a36Sopenharmony_ci        libaio				\
7262306a36Sopenharmony_ci        libzstd				\
7362306a36Sopenharmony_ci        disassembler-four-args		\
7462306a36Sopenharmony_ci        disassembler-init-styled	\
7562306a36Sopenharmony_ci        file-handle
7662306a36Sopenharmony_ci
7762306a36Sopenharmony_ci# FEATURE_TESTS_BASIC + FEATURE_TESTS_EXTRA is the complete list
7862306a36Sopenharmony_ci# of all feature tests
7962306a36Sopenharmony_ciFEATURE_TESTS_EXTRA :=                  \
8062306a36Sopenharmony_ci         bionic                         \
8162306a36Sopenharmony_ci         compile-32                     \
8262306a36Sopenharmony_ci         compile-x32                    \
8362306a36Sopenharmony_ci         cplus-demangle                 \
8462306a36Sopenharmony_ci         cxa-demangle                   \
8562306a36Sopenharmony_ci         gtk2                           \
8662306a36Sopenharmony_ci         gtk2-infobar                   \
8762306a36Sopenharmony_ci         hello                          \
8862306a36Sopenharmony_ci         libbabeltrace                  \
8962306a36Sopenharmony_ci         libbfd-liberty                 \
9062306a36Sopenharmony_ci         libbfd-liberty-z               \
9162306a36Sopenharmony_ci         libopencsd                     \
9262306a36Sopenharmony_ci         libunwind-x86                  \
9362306a36Sopenharmony_ci         libunwind-x86_64               \
9462306a36Sopenharmony_ci         libunwind-arm                  \
9562306a36Sopenharmony_ci         libunwind-aarch64              \
9662306a36Sopenharmony_ci         libunwind-debug-frame          \
9762306a36Sopenharmony_ci         libunwind-debug-frame-arm      \
9862306a36Sopenharmony_ci         libunwind-debug-frame-aarch64  \
9962306a36Sopenharmony_ci         cxx                            \
10062306a36Sopenharmony_ci         llvm                           \
10162306a36Sopenharmony_ci         llvm-version                   \
10262306a36Sopenharmony_ci         clang                          \
10362306a36Sopenharmony_ci         libbpf                         \
10462306a36Sopenharmony_ci         libbpf-btf__load_from_kernel_by_id \
10562306a36Sopenharmony_ci         libbpf-bpf_prog_load           \
10662306a36Sopenharmony_ci         libbpf-bpf_object__next_program \
10762306a36Sopenharmony_ci         libbpf-bpf_object__next_map    \
10862306a36Sopenharmony_ci         libbpf-bpf_program__set_insns  \
10962306a36Sopenharmony_ci         libbpf-bpf_create_map		\
11062306a36Sopenharmony_ci         libpfm4                        \
11162306a36Sopenharmony_ci         libdebuginfod			\
11262306a36Sopenharmony_ci         clang-bpf-co-re
11362306a36Sopenharmony_ci
11462306a36Sopenharmony_ci
11562306a36Sopenharmony_ciFEATURE_TESTS ?= $(FEATURE_TESTS_BASIC)
11662306a36Sopenharmony_ci
11762306a36Sopenharmony_ciifeq ($(FEATURE_TESTS),all)
11862306a36Sopenharmony_ci  FEATURE_TESTS := $(FEATURE_TESTS_BASIC) $(FEATURE_TESTS_EXTRA)
11962306a36Sopenharmony_ciendif
12062306a36Sopenharmony_ci
12162306a36Sopenharmony_ciFEATURE_DISPLAY ?=              \
12262306a36Sopenharmony_ci         dwarf                  \
12362306a36Sopenharmony_ci         dwarf_getlocations     \
12462306a36Sopenharmony_ci         glibc                  \
12562306a36Sopenharmony_ci         libbfd                 \
12662306a36Sopenharmony_ci         libbfd-buildid		\
12762306a36Sopenharmony_ci         libcap                 \
12862306a36Sopenharmony_ci         libelf                 \
12962306a36Sopenharmony_ci         libnuma                \
13062306a36Sopenharmony_ci         numa_num_possible_cpus \
13162306a36Sopenharmony_ci         libperl                \
13262306a36Sopenharmony_ci         libpython              \
13362306a36Sopenharmony_ci         libcrypto              \
13462306a36Sopenharmony_ci         libunwind              \
13562306a36Sopenharmony_ci         libdw-dwarf-unwind     \
13662306a36Sopenharmony_ci         zlib                   \
13762306a36Sopenharmony_ci         lzma                   \
13862306a36Sopenharmony_ci         get_cpuid              \
13962306a36Sopenharmony_ci         bpf			\
14062306a36Sopenharmony_ci         libaio			\
14162306a36Sopenharmony_ci         libzstd
14262306a36Sopenharmony_ci
14362306a36Sopenharmony_ci#
14462306a36Sopenharmony_ci# Declare group members of a feature to display the logical OR of the detection
14562306a36Sopenharmony_ci# result instead of each member result.
14662306a36Sopenharmony_ci#
14762306a36Sopenharmony_ciFEATURE_GROUP_MEMBERS-libbfd = libbfd-liberty libbfd-liberty-z
14862306a36Sopenharmony_ci
14962306a36Sopenharmony_ci# Set FEATURE_CHECK_(C|LD)FLAGS-all for all FEATURE_TESTS features.
15062306a36Sopenharmony_ci# If in the future we need per-feature checks/flags for features not
15162306a36Sopenharmony_ci# mentioned in this list we need to refactor this ;-).
15262306a36Sopenharmony_ciset_test_all_flags = $(eval $(set_test_all_flags_code))
15362306a36Sopenharmony_cidefine set_test_all_flags_code
15462306a36Sopenharmony_ci  FEATURE_CHECK_CFLAGS-all  += $(FEATURE_CHECK_CFLAGS-$(1))
15562306a36Sopenharmony_ci  FEATURE_CHECK_LDFLAGS-all += $(FEATURE_CHECK_LDFLAGS-$(1))
15662306a36Sopenharmony_ciendef
15762306a36Sopenharmony_ci
15862306a36Sopenharmony_ci$(foreach feat,$(FEATURE_TESTS),$(call set_test_all_flags,$(feat)))
15962306a36Sopenharmony_ci
16062306a36Sopenharmony_ci#
16162306a36Sopenharmony_ci# Special fast-path for the 'all features are available' case:
16262306a36Sopenharmony_ci#
16362306a36Sopenharmony_ci$(call feature_check,all,$(MSG))
16462306a36Sopenharmony_ci
16562306a36Sopenharmony_ci#
16662306a36Sopenharmony_ci# Just in case the build freshly failed, make sure we print the
16762306a36Sopenharmony_ci# feature matrix:
16862306a36Sopenharmony_ci#
16962306a36Sopenharmony_ciifeq ($(feature-all), 1)
17062306a36Sopenharmony_ci  #
17162306a36Sopenharmony_ci  # test-all.c passed - just set all the core feature flags to 1:
17262306a36Sopenharmony_ci  #
17362306a36Sopenharmony_ci  $(foreach feat,$(FEATURE_TESTS),$(call feature_set,$(feat)))
17462306a36Sopenharmony_ci  #
17562306a36Sopenharmony_ci  # test-all.c does not comprise these tests, so we need to
17662306a36Sopenharmony_ci  # for this case to get features proper values
17762306a36Sopenharmony_ci  #
17862306a36Sopenharmony_ci  $(call feature_check,compile-32)
17962306a36Sopenharmony_ci  $(call feature_check,compile-x32)
18062306a36Sopenharmony_ci  $(call feature_check,bionic)
18162306a36Sopenharmony_ci  $(call feature_check,libbabeltrace)
18262306a36Sopenharmony_cielse
18362306a36Sopenharmony_ci  $(foreach feat,$(FEATURE_TESTS),$(call feature_check,$(feat)))
18462306a36Sopenharmony_ciendif
18562306a36Sopenharmony_ci
18662306a36Sopenharmony_ci#
18762306a36Sopenharmony_ci# Print the result of the feature test:
18862306a36Sopenharmony_ci#
18962306a36Sopenharmony_cifeature_print_status = $(eval $(feature_print_status_code))
19062306a36Sopenharmony_ci
19162306a36Sopenharmony_cifeature_group = $(eval $(feature_gen_group)) $(GROUP)
19262306a36Sopenharmony_ci
19362306a36Sopenharmony_cidefine feature_gen_group
19462306a36Sopenharmony_ci  GROUP := $(1)
19562306a36Sopenharmony_ci  ifneq ($(feature_verbose),1)
19662306a36Sopenharmony_ci    GROUP += $(FEATURE_GROUP_MEMBERS-$(1))
19762306a36Sopenharmony_ci  endif
19862306a36Sopenharmony_ciendef
19962306a36Sopenharmony_ci
20062306a36Sopenharmony_cidefine feature_print_status_code
20162306a36Sopenharmony_ci  ifneq (,$(filter 1,$(foreach feat,$(call feature_group,$(feat)),$(feature-$(feat)))))
20262306a36Sopenharmony_ci    MSG = $(shell printf '...%40s: [ \033[32mon\033[m  ]' $(1))
20362306a36Sopenharmony_ci  else
20462306a36Sopenharmony_ci    MSG = $(shell printf '...%40s: [ \033[31mOFF\033[m ]' $(1))
20562306a36Sopenharmony_ci  endif
20662306a36Sopenharmony_ciendef
20762306a36Sopenharmony_ci
20862306a36Sopenharmony_cifeature_print_text = $(eval $(feature_print_text_code))
20962306a36Sopenharmony_cidefine feature_print_text_code
21062306a36Sopenharmony_ci    MSG = $(shell printf '...%40s: %s' $(1) $(2))
21162306a36Sopenharmony_ciendef
21262306a36Sopenharmony_ci
21362306a36Sopenharmony_ci#
21462306a36Sopenharmony_ci# generates feature value assignment for name, like:
21562306a36Sopenharmony_ci#   $(call feature_assign,dwarf) == feature-dwarf=1
21662306a36Sopenharmony_ci#
21762306a36Sopenharmony_cifeature_assign = feature-$(1)=$(feature-$(1))
21862306a36Sopenharmony_ci
21962306a36Sopenharmony_ciFEATURE_DUMP_FILENAME = $(OUTPUT)FEATURE-DUMP$(FEATURE_USER)
22062306a36Sopenharmony_ciFEATURE_DUMP := $(shell touch $(FEATURE_DUMP_FILENAME); cat $(FEATURE_DUMP_FILENAME))
22162306a36Sopenharmony_ci
22262306a36Sopenharmony_cifeature_dump_check = $(eval $(feature_dump_check_code))
22362306a36Sopenharmony_cidefine feature_dump_check_code
22462306a36Sopenharmony_ci  ifeq ($(findstring $(1),$(FEATURE_DUMP)),)
22562306a36Sopenharmony_ci    $(2) := 1
22662306a36Sopenharmony_ci  endif
22762306a36Sopenharmony_ciendef
22862306a36Sopenharmony_ci
22962306a36Sopenharmony_ci#
23062306a36Sopenharmony_ci# First check if any test from FEATURE_DISPLAY
23162306a36Sopenharmony_ci# and set feature_display := 1 if it does
23262306a36Sopenharmony_ci$(foreach feat,$(FEATURE_DISPLAY),$(call feature_dump_check,$(call feature_assign,$(feat)),feature_display))
23362306a36Sopenharmony_ci
23462306a36Sopenharmony_ci#
23562306a36Sopenharmony_ci# Now also check if any other test changed,
23662306a36Sopenharmony_ci# so we force FEATURE-DUMP generation
23762306a36Sopenharmony_ci$(foreach feat,$(FEATURE_TESTS),$(call feature_dump_check,$(call feature_assign,$(feat)),feature_dump_changed))
23862306a36Sopenharmony_ci
23962306a36Sopenharmony_ci# The $(feature_display) controls the default detection message
24062306a36Sopenharmony_ci# output. It's set if:
24162306a36Sopenharmony_ci# - detected features differes from stored features from
24262306a36Sopenharmony_ci#   last build (in $(FEATURE_DUMP_FILENAME) file)
24362306a36Sopenharmony_ci# - one of the $(FEATURE_DISPLAY) is not detected
24462306a36Sopenharmony_ci# - VF is enabled
24562306a36Sopenharmony_ci
24662306a36Sopenharmony_ciifeq ($(feature_dump_changed),1)
24762306a36Sopenharmony_ci  $(shell rm -f $(FEATURE_DUMP_FILENAME))
24862306a36Sopenharmony_ci  $(foreach feat,$(FEATURE_TESTS),$(shell echo "$(call feature_assign,$(feat))" >> $(FEATURE_DUMP_FILENAME)))
24962306a36Sopenharmony_ciendif
25062306a36Sopenharmony_ci
25162306a36Sopenharmony_cifeature_display_check = $(eval $(feature_check_display_code))
25262306a36Sopenharmony_cidefine feature_check_display_code
25362306a36Sopenharmony_ci  ifneq ($(feature-$(1)), 1)
25462306a36Sopenharmony_ci    feature_display := 1
25562306a36Sopenharmony_ci  endif
25662306a36Sopenharmony_ciendef
25762306a36Sopenharmony_ci
25862306a36Sopenharmony_ci$(foreach feat,$(FEATURE_DISPLAY),$(call feature_display_check,$(feat)))
25962306a36Sopenharmony_ci
26062306a36Sopenharmony_ciifeq ($(VF),1)
26162306a36Sopenharmony_ci  feature_display := 1
26262306a36Sopenharmony_ci  feature_verbose := 1
26362306a36Sopenharmony_ciendif
26462306a36Sopenharmony_ci
26562306a36Sopenharmony_ciifneq ($(feature_verbose),1)
26662306a36Sopenharmony_ci  #
26762306a36Sopenharmony_ci  # Determine the features to omit from the displayed message, as only the
26862306a36Sopenharmony_ci  # logical OR of the detection result will be shown.
26962306a36Sopenharmony_ci  #
27062306a36Sopenharmony_ci  FEATURE_OMIT := $(foreach feat,$(FEATURE_DISPLAY),$(FEATURE_GROUP_MEMBERS-$(feat)))
27162306a36Sopenharmony_ciendif
27262306a36Sopenharmony_ci
27362306a36Sopenharmony_cifeature_display_entries = $(eval $(feature_display_entries_code))
27462306a36Sopenharmony_cidefine feature_display_entries_code
27562306a36Sopenharmony_ci  ifeq ($(feature_display),1)
27662306a36Sopenharmony_ci    $$(info )
27762306a36Sopenharmony_ci    $$(info Auto-detecting system features:)
27862306a36Sopenharmony_ci    $(foreach feat,$(filter-out $(FEATURE_OMIT),$(FEATURE_DISPLAY)),$(call feature_print_status,$(feat),) $$(info $(MSG)))
27962306a36Sopenharmony_ci  endif
28062306a36Sopenharmony_ci
28162306a36Sopenharmony_ci  ifeq ($(feature_verbose),1)
28262306a36Sopenharmony_ci    $(eval TMP := $(filter-out $(FEATURE_DISPLAY),$(FEATURE_TESTS)))
28362306a36Sopenharmony_ci    $(foreach feat,$(TMP),$(call feature_print_status,$(feat),) $$(info $(MSG)))
28462306a36Sopenharmony_ci  endif
28562306a36Sopenharmony_ciendef
28662306a36Sopenharmony_ci
28762306a36Sopenharmony_ciifeq ($(FEATURE_DISPLAY_DEFERRED),)
28862306a36Sopenharmony_ci  $(call feature_display_entries)
28962306a36Sopenharmony_ci  $(info )
29062306a36Sopenharmony_ciendif
291