Makefile.feature 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. # SPDX-License-Identifier: GPL-2.0-only
  2. feature_dir := $(srctree)/tools/build/feature
  3. ifneq ($(OUTPUT),)
  4. OUTPUT_FEATURES = $(OUTPUT)feature/
  5. $(shell mkdir -p $(OUTPUT_FEATURES))
  6. endif
  7. feature_check = $(eval $(feature_check_code))
  8. define feature_check_code
  9. 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)
  10. endef
  11. feature_set = $(eval $(feature_set_code))
  12. define feature_set_code
  13. feature-$(1) := 1
  14. endef
  15. #
  16. # Build the feature check binaries in parallel, ignore errors, ignore return value and suppress output:
  17. #
  18. #
  19. # Note that this is not a complete list of all feature tests, just
  20. # those that are typically built on a fully configured system.
  21. #
  22. # [ Feature tests not mentioned here have to be built explicitly in
  23. # the rule that uses them - an example for that is the 'bionic'
  24. # feature check. ]
  25. #
  26. # These + the ones in FEATURE_TESTS_EXTRA are included in
  27. # tools/build/feature/test-all.c and we try to build it all together
  28. # then setting all those features to '1' meaning they are all enabled.
  29. #
  30. # There are things like fortify-source that will be set to 1 because test-all
  31. # is built with the flags needed to test if its enabled, resulting in
  32. #
  33. # $ rm -rf /tmp/b ; mkdir /tmp/b ; make -C tools/perf O=/tmp/b feature-dump
  34. # $ grep fortify-source /tmp/b/FEATURE-DUMP
  35. # feature-fortify-source=1
  36. # $
  37. #
  38. # All the others should have lines in tools/build/feature/test-all.c like:
  39. #
  40. # #define main main_test_disassembler_init_styled
  41. # # include "test-disassembler-init-styled.c"
  42. # #undef main
  43. #
  44. # #define main main_test_libzstd
  45. # # include "test-libzstd.c"
  46. # #undef main
  47. #
  48. # int main(int argc, char *argv[])
  49. # {
  50. # main_test_disassembler_four_args();
  51. # main_test_libzstd();
  52. # return 0;
  53. # }
  54. #
  55. # If the sample above works, then we end up with these lines in the FEATURE-DUMP
  56. # file:
  57. #
  58. # feature-disassembler-four-args=1
  59. # feature-libzstd=1
  60. #
  61. FEATURE_TESTS_BASIC := \
  62. backtrace \
  63. libdw \
  64. eventfd \
  65. fortify-source \
  66. gettid \
  67. glibc \
  68. libbfd \
  69. libbfd-threadsafe \
  70. libelf \
  71. libelf-getphdrnum \
  72. libelf-gelf_getnote \
  73. libelf-getshdrstrndx \
  74. libelf-zstd \
  75. libnuma \
  76. numa_num_possible_cpus \
  77. libpython \
  78. libslang \
  79. libtraceevent \
  80. libcpupower \
  81. pthread-attr-setaffinity-np \
  82. pthread-barrier \
  83. reallocarray \
  84. stackprotector-all \
  85. timerfd \
  86. zlib \
  87. lzma \
  88. bpf \
  89. scandirat \
  90. sched_getcpu \
  91. sdt \
  92. setns \
  93. libaio \
  94. libzstd \
  95. disassembler-four-args \
  96. disassembler-init-styled \
  97. file-handle \
  98. libopenssl
  99. # FEATURE_TESTS_BASIC + FEATURE_TESTS_EXTRA is the complete list
  100. # of all feature tests
  101. FEATURE_TESTS_EXTRA := \
  102. bionic \
  103. compile-32 \
  104. compile-x32 \
  105. cplus-demangle \
  106. cxa-demangle \
  107. gtk2 \
  108. gtk2-infobar \
  109. hello \
  110. libbabeltrace \
  111. libcapstone \
  112. libbfd-liberty \
  113. libbfd-liberty-z \
  114. libopencsd \
  115. libperl \
  116. cxx \
  117. llvm \
  118. clang \
  119. libbpf \
  120. libpfm4 \
  121. libdebuginfod \
  122. clang-bpf-co-re \
  123. bpftool-skeletons
  124. FEATURE_TESTS ?= $(FEATURE_TESTS_BASIC)
  125. ifeq ($(FEATURE_TESTS),all)
  126. FEATURE_TESTS := $(FEATURE_TESTS_BASIC) $(FEATURE_TESTS_EXTRA)
  127. endif
  128. FEATURE_DISPLAY ?= \
  129. libdw \
  130. glibc \
  131. libelf \
  132. libnuma \
  133. numa_num_possible_cpus \
  134. libpython \
  135. libcapstone \
  136. llvm-perf \
  137. zlib \
  138. lzma \
  139. bpf \
  140. libaio \
  141. libzstd \
  142. libopenssl \
  143. rust
  144. #
  145. # Declare group members of a feature to display the logical OR of the detection
  146. # result instead of each member result.
  147. #
  148. FEATURE_GROUP_MEMBERS-libbfd = libbfd-liberty libbfd-liberty-z
  149. #
  150. # Declare list of feature dependency packages that provide pkg-config files.
  151. #
  152. FEATURE_PKG_CONFIG ?= \
  153. libtraceevent \
  154. libtracefs
  155. feature_pkg_config = $(eval $(feature_pkg_config_code))
  156. define feature_pkg_config_code
  157. FEATURE_CHECK_CFLAGS-$(1) := $(shell $(PKG_CONFIG) --cflags $(1) 2>/dev/null)
  158. FEATURE_CHECK_LDFLAGS-$(1) := $(shell $(PKG_CONFIG) --libs $(1) 2>/dev/null)
  159. endef
  160. # Set FEATURE_CHECK_(C|LD)FLAGS-$(package) for packages using pkg-config.
  161. ifneq ($(PKG_CONFIG),)
  162. $(foreach package,$(FEATURE_PKG_CONFIG),$(call feature_pkg_config,$(package)))
  163. endif
  164. # Set FEATURE_CHECK_(C|LD)FLAGS-all for all FEATURE_TESTS features.
  165. # If in the future we need per-feature checks/flags for features not
  166. # mentioned in this list we need to refactor this ;-).
  167. set_test_all_flags = $(eval $(set_test_all_flags_code))
  168. define set_test_all_flags_code
  169. FEATURE_CHECK_CFLAGS-all += $(FEATURE_CHECK_CFLAGS-$(1))
  170. FEATURE_CHECK_LDFLAGS-all += $(FEATURE_CHECK_LDFLAGS-$(1))
  171. endef
  172. $(foreach feat,$(FEATURE_TESTS),$(call set_test_all_flags,$(feat)))
  173. #
  174. # Special fast-path for the 'all features are available' case:
  175. #
  176. $(call feature_check,all,$(MSG))
  177. #
  178. # Just in case the build freshly failed, make sure we print the
  179. # feature matrix:
  180. #
  181. ifeq ($(feature-all), 1)
  182. #
  183. # test-all.c passed - just set all the core feature flags to 1:
  184. #
  185. $(foreach feat,$(FEATURE_TESTS),$(call feature_set,$(feat)))
  186. #
  187. # test-all.c does not comprise these tests, so we need to
  188. # for this case to get features proper values
  189. #
  190. $(call feature_check,compile-32)
  191. $(call feature_check,compile-x32)
  192. $(call feature_check,bionic)
  193. $(call feature_check,libbabeltrace)
  194. else
  195. $(foreach feat,$(FEATURE_TESTS),$(call feature_check,$(feat)))
  196. endif
  197. #
  198. # Print the result of the feature test:
  199. #
  200. feature_print_status = $(eval $(feature_print_status_code))
  201. feature_group = $(eval $(feature_gen_group)) $(GROUP)
  202. define feature_gen_group
  203. GROUP := $(1)
  204. ifneq ($(feature_verbose),1)
  205. GROUP += $(FEATURE_GROUP_MEMBERS-$(1))
  206. endif
  207. endef
  208. define feature_print_status_code
  209. ifneq (,$(filter 1,$(foreach feat,$(call feature_group,$(feat)),$(feature-$(feat)))))
  210. MSG = $(shell printf '...%40s: [ \033[32mon\033[m ]' $(1))
  211. else
  212. MSG = $(shell printf '...%40s: [ \033[31mOFF\033[m ]' $(1))
  213. endif
  214. endef
  215. feature_print_text = $(eval $(feature_print_text_code))
  216. define feature_print_text_code
  217. MSG = $(shell printf '...%40s: %s' $(1) $(2))
  218. endef
  219. #
  220. # generates feature value assignment for name, like:
  221. # $(call feature_assign,libdw) == feature-libdw=1
  222. #
  223. feature_assign = feature-$(1)=$(feature-$(1))
  224. FEATURE_DUMP_FILENAME = $(OUTPUT)FEATURE-DUMP$(FEATURE_USER)
  225. FEATURE_DUMP := $(shell touch $(FEATURE_DUMP_FILENAME); cat $(FEATURE_DUMP_FILENAME))
  226. feature_dump_check = $(eval $(feature_dump_check_code))
  227. define feature_dump_check_code
  228. ifeq ($(findstring $(1),$(FEATURE_DUMP)),)
  229. $(2) := 1
  230. endif
  231. endef
  232. #
  233. # First check if any test from FEATURE_DISPLAY
  234. # and set feature_display := 1 if it does
  235. $(foreach feat,$(FEATURE_DISPLAY),$(call feature_dump_check,$(call feature_assign,$(feat)),feature_display))
  236. #
  237. # Now also check if any other test changed,
  238. # so we force FEATURE-DUMP generation
  239. $(foreach feat,$(FEATURE_TESTS),$(call feature_dump_check,$(call feature_assign,$(feat)),feature_dump_changed))
  240. # The $(feature_display) controls the default detection message
  241. # output. It's set if:
  242. # - detected features differes from stored features from
  243. # last build (in $(FEATURE_DUMP_FILENAME) file)
  244. # - one of the $(FEATURE_DISPLAY) is not detected
  245. # - VF is enabled
  246. ifeq ($(feature_dump_changed),1)
  247. $(shell rm -f $(FEATURE_DUMP_FILENAME))
  248. $(foreach feat,$(FEATURE_TESTS),$(shell echo "$(call feature_assign,$(feat))" >> $(FEATURE_DUMP_FILENAME)))
  249. endif
  250. feature_display_check = $(eval $(feature_check_display_code))
  251. define feature_check_display_code
  252. ifneq ($(feature-$(1)), 1)
  253. feature_display := 1
  254. endif
  255. endef
  256. $(foreach feat,$(FEATURE_DISPLAY),$(call feature_display_check,$(feat)))
  257. ifeq ($(VF),1)
  258. feature_display := 1
  259. feature_verbose := 1
  260. endif
  261. ifneq ($(feature_verbose),1)
  262. #
  263. # Determine the features to omit from the displayed message, as only the
  264. # logical OR of the detection result will be shown.
  265. #
  266. FEATURE_OMIT := $(foreach feat,$(FEATURE_DISPLAY),$(FEATURE_GROUP_MEMBERS-$(feat)))
  267. endif
  268. feature_display_entries = $(eval $(feature_display_entries_code))
  269. define feature_display_entries_code
  270. ifeq ($(feature_display),1)
  271. $$(info )
  272. $$(info Auto-detecting system features:)
  273. $(foreach feat,$(filter-out $(FEATURE_OMIT),$(FEATURE_DISPLAY)),$(call feature_print_status,$(feat),) $$(info $(MSG)))
  274. endif
  275. ifeq ($(feature_verbose),1)
  276. $(eval TMP := $(filter-out $(FEATURE_DISPLAY),$(FEATURE_TESTS)))
  277. $(foreach feat,$(TMP),$(call feature_print_status,$(feat),) $$(info $(MSG)))
  278. endif
  279. endef
  280. ifeq ($(FEATURE_DISPLAY_DEFERRED),)
  281. $(call feature_display_entries)
  282. ifeq ($(feature_display),1)
  283. $(info )
  284. endif
  285. endif