1# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 3pound := \# 4 5CFLAGS_BACKUP := $(CFLAGS) 6CFLAGS := $(EXTRA_CFLAGS) 7ifneq ($(LLVM),) 8 CFLAGS += -Wno-unused-command-line-argument 9endif 10 11ifeq ($(V),1) 12 LOG=$(warning $(1)) 13 LOG_RES = (echo $(1) && >&2 echo result: $(1)) 14 define detect 15 $(warning $(1) && $(call LOG_RES,1) || $(call LOG_RES,0)) 16 $(shell $(1) && $(call LOG_RES,1) || $(call LOG_RES,0)) 17 endef 18else 19 LOG= 20 LOG_RES = (echo $(1)) 21 define detect 22 $(shell $(1) 2>&1 && $(call LOG_RES,1) || $(call LOG_RES,0)) 23 endef 24 QUIET_STDERR := 2>/dev/null 25endif 26 27### feature-clang-bpf-co-re 28 29CLANG_BPF_CO_RE_PROBE_CMD = \ 30 printf '%s\n' 'struct s { int i; } __attribute__((preserve_access_index)); struct s foo = {};' | \ 31 $(CLANG) -g -target bpf -S -o - -x c - $(QUIET_STDERR) | grep -q BTF_KIND_VAR 32 33ifneq ($(findstring clang-bpf-co-re,$(FEATURE_TESTS)),) 34$(call LOG,Probing: feature-clang-bpf-co-re) 35feature-clang-bpf-co-re := \ 36 $(findstring 1,$(call detect,$(CLANG_BPF_CO_RE_PROBE_CMD))) 37endif # clang-bpf-co-re 38 39### feature-libbfd 40 41ifneq ($(findstring libbfd,$(FEATURE_TESTS)),) 42LIBBFD_PROBE := '$(pound)include <bfd.h>\n' 43LIBBFD_PROBE += 'int main(void) {' 44LIBBFD_PROBE += ' bfd_demangle(0, 0, 0);' 45LIBBFD_PROBE += ' return 0;' 46LIBBFD_PROBE += '}' 47LIBBFD_PROBE_CMD = printf '%b\n' $(LIBBFD_PROBE) | \ 48 $(CC) $(CFLAGS) -Wall -Werror -x c - $(1) -o /dev/null >/dev/null 49 50define libbfd_build 51 $(call detect,$(LIBBFD_PROBE_CMD)) 52endef 53 54$(call LOG,Probing: feature-libbfd) 55feature-libbfd := \ 56 $(findstring 1,$(call libbfd_build,-lbfd -ldl)) 57ifneq ($(feature-libbfd),1) 58 $(call LOG,Probing: feature-libbfd-liberty) 59 feature-libbfd-liberty := \ 60 $(findstring 1,$(call libbfd_build,-lbfd -ldl -liberty)) 61 ifneq ($(feature-libbfd-liberty),1) 62 $(call LOG,Probing: feature-libbfd-liberty-z) 63 feature-libbfd-liberty-z := \ 64 $(findstring 1,$(call libbfd_build,-lbfd -ldl -liberty -lz)) 65 endif 66endif 67HAS_LIBBFD := $(findstring 1, \ 68 $(feature-libbfd)$(feature-libbfd-liberty)$(feature-libbfd-liberty-z)) 69endif # libbfd 70 71### feature-disassembler-four-args 72 73ifneq ($(findstring disassembler-four-args,$(FEATURE_TESTS)),) 74DISASSEMBLER_PROBE := '$(pound)include <dis-asm.h>\n' 75DISASSEMBLER_PROBE += 'int main(void) {' 76DISASSEMBLER_PROBE += ' disassembler((enum bfd_architecture)0, 0, 0, NULL);' 77DISASSEMBLER_PROBE += ' return 0;' 78DISASSEMBLER_PROBE += '}' 79 80DISASSEMBLER_PROBE_CMD = printf '%b\n' $(1) | \ 81 $(CC) $(CFLAGS) -Wall -Werror -x c - -lbfd -lopcodes -S -o - >/dev/null 82define disassembler_build 83 $(call detect,$(DISASSEMBLER_PROBE_CMD)) 84endef 85 86$(call LOG,Probing: feature-disassembler-four-args) 87feature-disassembler-four-args := \ 88 $(findstring 1, $(call disassembler_build,$(DISASSEMBLER_PROBE))) 89endif # disassembler-four-args 90 91### feature-disassembler-init-styled 92 93ifneq ($(findstring disassembler-init-styled,$(FEATURE_TESTS)),) 94DISASSEMBLER_STYLED_PROBE := '$(pound)include <dis-asm.h>\n' 95DISASSEMBLER_STYLED_PROBE += 'int main(void) {' 96DISASSEMBLER_STYLED_PROBE += ' init_disassemble_info(NULL, 0, NULL, NULL);' 97DISASSEMBLER_STYLED_PROBE += ' return 0;' 98DISASSEMBLER_STYLED_PROBE += '}' 99 100$(call LOG,Probing: feature-disassembler-styled) 101feature-disassembler-init-styled := \ 102 $(findstring 1, $(call disassembler_build,$(DISASSEMBLER_STYLED_PROBE))) 103endif # disassembler-init-styled 104 105### feature-libcap 106 107ifneq ($(findstring libcap,$(FEATURE_TESTS)),) 108LIBCAP_PROBE := '$(pound)include <sys/capability.h>\n' 109LIBCAP_PROBE += 'int main(void) {' 110LIBCAP_PROBE += ' cap_free(0);' 111LIBCAP_PROBE += ' return 0;' 112LIBCAP_PROBE += '}' 113LIBCAP_PROBE_CMD = printf '%b\n' $(LIBCAP_PROBE) | \ 114 $(CC) $(CFLAGS) -Wall -Werror -x c - -lcap -S -o - >/dev/null 115 116define libcap_build 117 $(call detect,$(LIBCAP_PROBE_CMD)) 118endef 119 120$(call LOG,Probing: feature-libcap) 121feature-libcap := $(findstring 1, $(call libcap_build)) 122endif # libcap 123 124### feature-llvm 125 126ifneq ($(findstring llvm,$(FEATURE_TESTS)),) 127LLVM_PROBE := '$(pound)include <llvm-c/Core.h>\n' 128LLVM_PROBE += '$(pound)include <llvm-c/TargetMachine.h>\n' 129LLVM_PROBE += 'int main(void) {' 130LLVM_PROBE += ' char *triple = LLVMNormalizeTargetTriple("");' 131LLVM_PROBE += ' LLVMDisposeMessage(triple);' 132LLVM_PROBE += ' return 0;' 133LLVM_PROBE += '}' 134 135# We need some adjustments for the flags. 136# - $(CFLAGS) was set to parent $(EXTRA_CFLAGS) at the beginning of this file. 137# - $(EXTRA_LDFLAGS) from parent Makefile should be kept as well. 138# - Libraries to use depend on whether we have a static or shared version of 139# LLVM, pass the llvm-config flag and adjust the list of libraries 140# accordingly. 141FEATURE_LLVM_CFLAGS := $(CFLAGS) $(shell $(LLVM_CONFIG) --cflags 2>/dev/null) 142FEATURE_LLVM_LIBS := $(shell $(LLVM_CONFIG) --libs target 2>/dev/null) 143ifeq ($(shell $(LLVM_CONFIG) --shared-mode 2>/dev/null),static) 144 FEATURE_LLVM_LIBS += $(shell $(LLVM_CONFIG) --system-libs target 2>/dev/null) 145 FEATURE_LLVM_LIBS += -lstdc++ 146endif 147FEATURE_LDFLAGS := $(EXTRA_LDFLAGS) $(shell $(LLVM_CONFIG) --ldflags 2>/dev/null) 148 149LLVM_PROBE_CMD = printf '%b\n' $(LLVM_PROBE) | \ 150 $(CC) $(FEATURE_LLVM_CFLAGS) $(FEATURE_LDFLAGS) \ 151 -Wall -Werror -x c - $(FEATURE_LLVM_LIBS) \ 152 -o /dev/null >/dev/null 153 154define llvm_build 155 $(call detect,$(LLVM_PROBE_CMD)) 156endef 157 158$(call LOG,Probing: feature-llvm) 159feature-llvm := $(findstring 1, $(call llvm_build)) 160endif # llvm 161 162### Print detection results 163 164define print_status 165 ifeq ($(1), 1) 166 MSG = $(shell printf '...%30s: [ \033[32mon\033[m ]' $(2)) 167 else 168 MSG = $(shell printf '...%30s: [ \033[31mOFF\033[m ]' $(2)) 169 endif 170endef 171feature_print_status = $(eval $(print_status)) $(info $(MSG)) 172 173$(call feature_print_status,$(HAS_LIBBFD),libbfd) 174 175$(foreach feature,$(filter-out libbfd%,$(FEATURE_DISPLAY)), \ 176 $(call feature_print_status,$(feature-$(feature)),$(feature))) 177 178CFLAGS := $(CFLAGS_BACKUP) 179undefine LOG LOG_RES 180