18c2ecf20Sopenharmony_ci# SPDX-License-Identifier: GPL-2.0-only
28c2ecf20Sopenharmony_cifeature_dir := $(srctree)/tools/build/feature
38c2ecf20Sopenharmony_ci
48c2ecf20Sopenharmony_ciifneq ($(OUTPUT),)
58c2ecf20Sopenharmony_ci  OUTPUT_FEATURES = $(OUTPUT)feature/
68c2ecf20Sopenharmony_ci  $(shell mkdir -p $(OUTPUT_FEATURES))
78c2ecf20Sopenharmony_ciendif
88c2ecf20Sopenharmony_ci
98c2ecf20Sopenharmony_cifeature_check = $(eval $(feature_check_code))
108c2ecf20Sopenharmony_cidefine feature_check_code
118c2ecf20Sopenharmony_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)
128c2ecf20Sopenharmony_ciendef
138c2ecf20Sopenharmony_ci
148c2ecf20Sopenharmony_cifeature_set = $(eval $(feature_set_code))
158c2ecf20Sopenharmony_cidefine feature_set_code
168c2ecf20Sopenharmony_ci  feature-$(1) := 1
178c2ecf20Sopenharmony_ciendef
188c2ecf20Sopenharmony_ci
198c2ecf20Sopenharmony_ci#
208c2ecf20Sopenharmony_ci# Build the feature check binaries in parallel, ignore errors, ignore return value and suppress output:
218c2ecf20Sopenharmony_ci#
228c2ecf20Sopenharmony_ci
238c2ecf20Sopenharmony_ci#
248c2ecf20Sopenharmony_ci# Note that this is not a complete list of all feature tests, just
258c2ecf20Sopenharmony_ci# those that are typically built on a fully configured system.
268c2ecf20Sopenharmony_ci#
278c2ecf20Sopenharmony_ci# [ Feature tests not mentioned here have to be built explicitly in
288c2ecf20Sopenharmony_ci#   the rule that uses them - an example for that is the 'bionic'
298c2ecf20Sopenharmony_ci#   feature check. ]
308c2ecf20Sopenharmony_ci#
318c2ecf20Sopenharmony_ciFEATURE_TESTS_BASIC :=                  \
328c2ecf20Sopenharmony_ci        backtrace                       \
338c2ecf20Sopenharmony_ci        dwarf                           \
348c2ecf20Sopenharmony_ci        dwarf_getlocations              \
358c2ecf20Sopenharmony_ci        eventfd                         \
368c2ecf20Sopenharmony_ci        fortify-source                  \
378c2ecf20Sopenharmony_ci        sync-compare-and-swap           \
388c2ecf20Sopenharmony_ci        get_current_dir_name            \
398c2ecf20Sopenharmony_ci        gettid				\
408c2ecf20Sopenharmony_ci        glibc                           \
418c2ecf20Sopenharmony_ci        libbfd                          \
428c2ecf20Sopenharmony_ci        libbfd-buildid			\
438c2ecf20Sopenharmony_ci        libcap                          \
448c2ecf20Sopenharmony_ci        libelf                          \
458c2ecf20Sopenharmony_ci        libelf-getphdrnum               \
468c2ecf20Sopenharmony_ci        libelf-gelf_getnote             \
478c2ecf20Sopenharmony_ci        libelf-getshdrstrndx            \
488c2ecf20Sopenharmony_ci        libnuma                         \
498c2ecf20Sopenharmony_ci        numa_num_possible_cpus          \
508c2ecf20Sopenharmony_ci        libperl                         \
518c2ecf20Sopenharmony_ci        libpython                       \
528c2ecf20Sopenharmony_ci        libslang                        \
538c2ecf20Sopenharmony_ci        libslang-include-subdir         \
548c2ecf20Sopenharmony_ci        libcrypto                       \
558c2ecf20Sopenharmony_ci        libunwind                       \
568c2ecf20Sopenharmony_ci        pthread-attr-setaffinity-np     \
578c2ecf20Sopenharmony_ci        pthread-barrier     		\
588c2ecf20Sopenharmony_ci        reallocarray                    \
598c2ecf20Sopenharmony_ci        stackprotector-all              \
608c2ecf20Sopenharmony_ci        timerfd                         \
618c2ecf20Sopenharmony_ci        libdw-dwarf-unwind              \
628c2ecf20Sopenharmony_ci        zlib                            \
638c2ecf20Sopenharmony_ci        lzma                            \
648c2ecf20Sopenharmony_ci        get_cpuid                       \
658c2ecf20Sopenharmony_ci        bpf                             \
668c2ecf20Sopenharmony_ci        sched_getcpu			\
678c2ecf20Sopenharmony_ci        sdt				\
688c2ecf20Sopenharmony_ci        setns				\
698c2ecf20Sopenharmony_ci        libaio				\
708c2ecf20Sopenharmony_ci        libzstd				\
718c2ecf20Sopenharmony_ci        disassembler-four-args		\
728c2ecf20Sopenharmony_ci        file-handle
738c2ecf20Sopenharmony_ci
748c2ecf20Sopenharmony_ci# FEATURE_TESTS_BASIC + FEATURE_TESTS_EXTRA is the complete list
758c2ecf20Sopenharmony_ci# of all feature tests
768c2ecf20Sopenharmony_ciFEATURE_TESTS_EXTRA :=                  \
778c2ecf20Sopenharmony_ci         bionic                         \
788c2ecf20Sopenharmony_ci         compile-32                     \
798c2ecf20Sopenharmony_ci         compile-x32                    \
808c2ecf20Sopenharmony_ci         cplus-demangle                 \
818c2ecf20Sopenharmony_ci         gtk2                           \
828c2ecf20Sopenharmony_ci         gtk2-infobar                   \
838c2ecf20Sopenharmony_ci         hello                          \
848c2ecf20Sopenharmony_ci         libbabeltrace                  \
858c2ecf20Sopenharmony_ci         libbfd-liberty                 \
868c2ecf20Sopenharmony_ci         libbfd-liberty-z               \
878c2ecf20Sopenharmony_ci         libopencsd                     \
888c2ecf20Sopenharmony_ci         libunwind-x86                  \
898c2ecf20Sopenharmony_ci         libunwind-x86_64               \
908c2ecf20Sopenharmony_ci         libunwind-arm                  \
918c2ecf20Sopenharmony_ci         libunwind-aarch64              \
928c2ecf20Sopenharmony_ci         libunwind-debug-frame          \
938c2ecf20Sopenharmony_ci         libunwind-debug-frame-arm      \
948c2ecf20Sopenharmony_ci         libunwind-debug-frame-aarch64  \
958c2ecf20Sopenharmony_ci         cxx                            \
968c2ecf20Sopenharmony_ci         llvm                           \
978c2ecf20Sopenharmony_ci         llvm-version                   \
988c2ecf20Sopenharmony_ci         clang                          \
998c2ecf20Sopenharmony_ci         libbpf                         \
1008c2ecf20Sopenharmony_ci         libpfm4                        \
1018c2ecf20Sopenharmony_ci         libdebuginfod
1028c2ecf20Sopenharmony_ci
1038c2ecf20Sopenharmony_ciFEATURE_TESTS ?= $(FEATURE_TESTS_BASIC)
1048c2ecf20Sopenharmony_ci
1058c2ecf20Sopenharmony_ciifeq ($(FEATURE_TESTS),all)
1068c2ecf20Sopenharmony_ci  FEATURE_TESTS := $(FEATURE_TESTS_BASIC) $(FEATURE_TESTS_EXTRA)
1078c2ecf20Sopenharmony_ciendif
1088c2ecf20Sopenharmony_ci
1098c2ecf20Sopenharmony_ciFEATURE_DISPLAY ?=              \
1108c2ecf20Sopenharmony_ci         dwarf                  \
1118c2ecf20Sopenharmony_ci         dwarf_getlocations     \
1128c2ecf20Sopenharmony_ci         glibc                  \
1138c2ecf20Sopenharmony_ci         libbfd                 \
1148c2ecf20Sopenharmony_ci         libbfd-buildid		\
1158c2ecf20Sopenharmony_ci         libcap                 \
1168c2ecf20Sopenharmony_ci         libelf                 \
1178c2ecf20Sopenharmony_ci         libnuma                \
1188c2ecf20Sopenharmony_ci         numa_num_possible_cpus \
1198c2ecf20Sopenharmony_ci         libperl                \
1208c2ecf20Sopenharmony_ci         libpython              \
1218c2ecf20Sopenharmony_ci         libcrypto              \
1228c2ecf20Sopenharmony_ci         libunwind              \
1238c2ecf20Sopenharmony_ci         libdw-dwarf-unwind     \
1248c2ecf20Sopenharmony_ci         zlib                   \
1258c2ecf20Sopenharmony_ci         lzma                   \
1268c2ecf20Sopenharmony_ci         get_cpuid              \
1278c2ecf20Sopenharmony_ci         bpf			\
1288c2ecf20Sopenharmony_ci         libaio			\
1298c2ecf20Sopenharmony_ci         libzstd		\
1308c2ecf20Sopenharmony_ci         disassembler-four-args
1318c2ecf20Sopenharmony_ci
1328c2ecf20Sopenharmony_ci# Set FEATURE_CHECK_(C|LD)FLAGS-all for all FEATURE_TESTS features.
1338c2ecf20Sopenharmony_ci# If in the future we need per-feature checks/flags for features not
1348c2ecf20Sopenharmony_ci# mentioned in this list we need to refactor this ;-).
1358c2ecf20Sopenharmony_ciset_test_all_flags = $(eval $(set_test_all_flags_code))
1368c2ecf20Sopenharmony_cidefine set_test_all_flags_code
1378c2ecf20Sopenharmony_ci  FEATURE_CHECK_CFLAGS-all  += $(FEATURE_CHECK_CFLAGS-$(1))
1388c2ecf20Sopenharmony_ci  FEATURE_CHECK_LDFLAGS-all += $(FEATURE_CHECK_LDFLAGS-$(1))
1398c2ecf20Sopenharmony_ciendef
1408c2ecf20Sopenharmony_ci
1418c2ecf20Sopenharmony_ci$(foreach feat,$(FEATURE_TESTS),$(call set_test_all_flags,$(feat)))
1428c2ecf20Sopenharmony_ci
1438c2ecf20Sopenharmony_ci#
1448c2ecf20Sopenharmony_ci# Special fast-path for the 'all features are available' case:
1458c2ecf20Sopenharmony_ci#
1468c2ecf20Sopenharmony_ci$(call feature_check,all,$(MSG))
1478c2ecf20Sopenharmony_ci
1488c2ecf20Sopenharmony_ci#
1498c2ecf20Sopenharmony_ci# Just in case the build freshly failed, make sure we print the
1508c2ecf20Sopenharmony_ci# feature matrix:
1518c2ecf20Sopenharmony_ci#
1528c2ecf20Sopenharmony_ciifeq ($(feature-all), 1)
1538c2ecf20Sopenharmony_ci  #
1548c2ecf20Sopenharmony_ci  # test-all.c passed - just set all the core feature flags to 1:
1558c2ecf20Sopenharmony_ci  #
1568c2ecf20Sopenharmony_ci  $(foreach feat,$(FEATURE_TESTS),$(call feature_set,$(feat)))
1578c2ecf20Sopenharmony_ci  #
1588c2ecf20Sopenharmony_ci  # test-all.c does not comprise these tests, so we need to
1598c2ecf20Sopenharmony_ci  # for this case to get features proper values
1608c2ecf20Sopenharmony_ci  #
1618c2ecf20Sopenharmony_ci  $(call feature_check,compile-32)
1628c2ecf20Sopenharmony_ci  $(call feature_check,compile-x32)
1638c2ecf20Sopenharmony_ci  $(call feature_check,bionic)
1648c2ecf20Sopenharmony_ci  $(call feature_check,libbabeltrace)
1658c2ecf20Sopenharmony_cielse
1668c2ecf20Sopenharmony_ci  $(foreach feat,$(FEATURE_TESTS),$(call feature_check,$(feat)))
1678c2ecf20Sopenharmony_ciendif
1688c2ecf20Sopenharmony_ci
1698c2ecf20Sopenharmony_ci#
1708c2ecf20Sopenharmony_ci# Print the result of the feature test:
1718c2ecf20Sopenharmony_ci#
1728c2ecf20Sopenharmony_cifeature_print_status = $(eval $(feature_print_status_code)) $(info $(MSG))
1738c2ecf20Sopenharmony_ci
1748c2ecf20Sopenharmony_cidefine feature_print_status_code
1758c2ecf20Sopenharmony_ci  ifeq ($(feature-$(1)), 1)
1768c2ecf20Sopenharmony_ci    MSG = $(shell printf '...%30s: [ \033[32mon\033[m  ]' $(1))
1778c2ecf20Sopenharmony_ci  else
1788c2ecf20Sopenharmony_ci    MSG = $(shell printf '...%30s: [ \033[31mOFF\033[m ]' $(1))
1798c2ecf20Sopenharmony_ci  endif
1808c2ecf20Sopenharmony_ciendef
1818c2ecf20Sopenharmony_ci
1828c2ecf20Sopenharmony_cifeature_print_text = $(eval $(feature_print_text_code)) $(info $(MSG))
1838c2ecf20Sopenharmony_cidefine feature_print_text_code
1848c2ecf20Sopenharmony_ci    MSG = $(shell printf '...%30s: %s' $(1) $(2))
1858c2ecf20Sopenharmony_ciendef
1868c2ecf20Sopenharmony_ci
1878c2ecf20Sopenharmony_ci#
1888c2ecf20Sopenharmony_ci# generates feature value assignment for name, like:
1898c2ecf20Sopenharmony_ci#   $(call feature_assign,dwarf) == feature-dwarf=1
1908c2ecf20Sopenharmony_ci#
1918c2ecf20Sopenharmony_cifeature_assign = feature-$(1)=$(feature-$(1))
1928c2ecf20Sopenharmony_ci
1938c2ecf20Sopenharmony_ciFEATURE_DUMP_FILENAME = $(OUTPUT)FEATURE-DUMP$(FEATURE_USER)
1948c2ecf20Sopenharmony_ciFEATURE_DUMP := $(shell touch $(FEATURE_DUMP_FILENAME); cat $(FEATURE_DUMP_FILENAME))
1958c2ecf20Sopenharmony_ci
1968c2ecf20Sopenharmony_cifeature_dump_check = $(eval $(feature_dump_check_code))
1978c2ecf20Sopenharmony_cidefine feature_dump_check_code
1988c2ecf20Sopenharmony_ci  ifeq ($(findstring $(1),$(FEATURE_DUMP)),)
1998c2ecf20Sopenharmony_ci    $(2) := 1
2008c2ecf20Sopenharmony_ci  endif
2018c2ecf20Sopenharmony_ciendef
2028c2ecf20Sopenharmony_ci
2038c2ecf20Sopenharmony_ci#
2048c2ecf20Sopenharmony_ci# First check if any test from FEATURE_DISPLAY
2058c2ecf20Sopenharmony_ci# and set feature_display := 1 if it does
2068c2ecf20Sopenharmony_ci$(foreach feat,$(FEATURE_DISPLAY),$(call feature_dump_check,$(call feature_assign,$(feat)),feature_display))
2078c2ecf20Sopenharmony_ci
2088c2ecf20Sopenharmony_ci#
2098c2ecf20Sopenharmony_ci# Now also check if any other test changed,
2108c2ecf20Sopenharmony_ci# so we force FEATURE-DUMP generation
2118c2ecf20Sopenharmony_ci$(foreach feat,$(FEATURE_TESTS),$(call feature_dump_check,$(call feature_assign,$(feat)),feature_dump_changed))
2128c2ecf20Sopenharmony_ci
2138c2ecf20Sopenharmony_ci# The $(feature_display) controls the default detection message
2148c2ecf20Sopenharmony_ci# output. It's set if:
2158c2ecf20Sopenharmony_ci# - detected features differes from stored features from
2168c2ecf20Sopenharmony_ci#   last build (in $(FEATURE_DUMP_FILENAME) file)
2178c2ecf20Sopenharmony_ci# - one of the $(FEATURE_DISPLAY) is not detected
2188c2ecf20Sopenharmony_ci# - VF is enabled
2198c2ecf20Sopenharmony_ci
2208c2ecf20Sopenharmony_ciifeq ($(feature_dump_changed),1)
2218c2ecf20Sopenharmony_ci  $(shell rm -f $(FEATURE_DUMP_FILENAME))
2228c2ecf20Sopenharmony_ci  $(foreach feat,$(FEATURE_TESTS),$(shell echo "$(call feature_assign,$(feat))" >> $(FEATURE_DUMP_FILENAME)))
2238c2ecf20Sopenharmony_ciendif
2248c2ecf20Sopenharmony_ci
2258c2ecf20Sopenharmony_cifeature_display_check = $(eval $(feature_check_display_code))
2268c2ecf20Sopenharmony_cidefine feature_check_display_code
2278c2ecf20Sopenharmony_ci  ifneq ($(feature-$(1)), 1)
2288c2ecf20Sopenharmony_ci    feature_display := 1
2298c2ecf20Sopenharmony_ci  endif
2308c2ecf20Sopenharmony_ciendef
2318c2ecf20Sopenharmony_ci
2328c2ecf20Sopenharmony_ci$(foreach feat,$(FEATURE_DISPLAY),$(call feature_display_check,$(feat)))
2338c2ecf20Sopenharmony_ci
2348c2ecf20Sopenharmony_ciifeq ($(VF),1)
2358c2ecf20Sopenharmony_ci  feature_display := 1
2368c2ecf20Sopenharmony_ci  feature_verbose := 1
2378c2ecf20Sopenharmony_ciendif
2388c2ecf20Sopenharmony_ci
2398c2ecf20Sopenharmony_ciifeq ($(feature_display),1)
2408c2ecf20Sopenharmony_ci  $(info )
2418c2ecf20Sopenharmony_ci  $(info Auto-detecting system features:)
2428c2ecf20Sopenharmony_ci  $(foreach feat,$(FEATURE_DISPLAY),$(call feature_print_status,$(feat),))
2438c2ecf20Sopenharmony_ci  ifneq ($(feature_verbose),1)
2448c2ecf20Sopenharmony_ci    $(info )
2458c2ecf20Sopenharmony_ci  endif
2468c2ecf20Sopenharmony_ciendif
2478c2ecf20Sopenharmony_ci
2488c2ecf20Sopenharmony_ciifeq ($(feature_verbose),1)
2498c2ecf20Sopenharmony_ci  TMP := $(filter-out $(FEATURE_DISPLAY),$(FEATURE_TESTS))
2508c2ecf20Sopenharmony_ci  $(foreach feat,$(TMP),$(call feature_print_status,$(feat),))
2518c2ecf20Sopenharmony_ci  $(info )
2528c2ecf20Sopenharmony_ciendif
253