blob: d091cdac37c1e8aa92614f7eddc05e0f47ea3214 [file] [log] [blame]
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
pound := \#
CFLAGS_BACKUP := $(CFLAGS)
CFLAGS := $(EXTRA_CFLAGS)
ifneq ($(LLVM),)
CFLAGS += -Wno-unused-command-line-argument
endif
ifeq ($(V),1)
LOG=$(warning $(1))
LOG_RES = (echo $(1) && >&2 echo result: $(1))
define detect
$(warning $(1) && $(call LOG_RES,1) || $(call LOG_RES,0))
$(shell $(1) && $(call LOG_RES,1) || $(call LOG_RES,0))
endef
else
LOG=
LOG_RES = (echo $(1))
define detect
$(shell $(1) 2>&1 && $(call LOG_RES,1) || $(call LOG_RES,0))
endef
QUIET_STDERR := 2>/dev/null
endif
### feature-clang-bpf-co-re
CLANG_BPF_CO_RE_PROBE_CMD = \
printf '%s\n' 'struct s { int i; } __attribute__((preserve_access_index)); struct s foo;' | \
$(CLANG) -g -target bpf -S -o - -x c - $(QUIET_STDERR) | grep -q BTF_KIND_VAR
ifneq ($(findstring clang-bpf-co-re,$(FEATURE_TESTS)),)
$(call LOG,Probing: feature-clang-bpf-co-re)
feature-clang-bpf-co-re := \
$(findstring 1,$(call detect,$(CLANG_BPF_CO_RE_PROBE_CMD)))
endif # clang-bpf-co-re
### feature-libbfd
ifneq ($(findstring libbfd,$(FEATURE_TESTS)),)
LIBBFD_PROBE := '$(pound)include <bfd.h>\n'
LIBBFD_PROBE += 'int main(void) {'
LIBBFD_PROBE += ' bfd_demangle(0, 0, 0);'
LIBBFD_PROBE += ' return 0;'
LIBBFD_PROBE += '}'
LIBBFD_PROBE_CMD = printf '%b\n' $(LIBBFD_PROBE) | \
$(CC) $(CFLAGS) -Wall -Werror -x c - $(1) -o /dev/null >/dev/null
define libbfd_build
$(call detect,$(LIBBFD_PROBE_CMD))
endef
$(call LOG,Probing: feature-libbfd)
feature-libbfd := \
$(findstring 1,$(call libbfd_build,-lbfd -ldl))
ifneq ($(feature-libbfd),1)
$(call LOG,Probing: feature-libbfd-liberty)
feature-libbfd-liberty := \
$(findstring 1,$(call libbfd_build,-lbfd -ldl -liberty))
ifneq ($(feature-libbfd-liberty),1)
$(call LOG,Probing: feature-libbfd-liberty-z)
feature-libbfd-liberty-z := \
$(findstring 1,$(call libbfd_build,-lbfd -ldl -liberty -lz))
endif
endif
HAS_LIBBFD := $(findstring 1, \
$(feature-libbfd)$(feature-libbfd-liberty)$(feature-libbfd-liberty-z))
endif # libbfd
### feature-disassembler-four-args
ifneq ($(findstring disassembler-four-args,$(FEATURE_TESTS)),)
DISASSEMBLER_PROBE := '$(pound)include <dis-asm.h>\n'
DISASSEMBLER_PROBE += 'int main(void) {'
DISASSEMBLER_PROBE += ' disassembler((enum bfd_architecture)0, 0, 0, NULL);'
DISASSEMBLER_PROBE += ' return 0;'
DISASSEMBLER_PROBE += '}'
DISASSEMBLER_PROBE_CMD = printf '%b\n' $(1) | \
$(CC) $(CFLAGS) -Wall -Werror -x c - -lbfd -lopcodes -S -o - >/dev/null
define disassembler_build
$(call detect,$(DISASSEMBLER_PROBE_CMD))
endef
$(call LOG,Probing: feature-disassembler-four-args)
feature-disassembler-four-args := \
$(findstring 1, $(call disassembler_build,$(DISASSEMBLER_PROBE)))
endif # disassembler-four-args
### feature-disassembler-init-styled
ifneq ($(findstring disassembler-init-styled,$(FEATURE_TESTS)),)
DISASSEMBLER_STYLED_PROBE := '$(pound)include <dis-asm.h>\n'
DISASSEMBLER_STYLED_PROBE += 'int main(void) {'
DISASSEMBLER_STYLED_PROBE += ' init_disassemble_info(NULL, 0, NULL, NULL);'
DISASSEMBLER_STYLED_PROBE += ' return 0;'
DISASSEMBLER_STYLED_PROBE += '}'
$(call LOG,Probing: feature-disassembler-styled)
feature-disassembler-init-styled := \
$(findstring 1, $(call disassembler_build,$(DISASSEMBLER_STYLED_PROBE)))
endif # disassembler-init-styled
### feature-libcap
ifneq ($(findstring libcap,$(FEATURE_TESTS)),)
LIBCAP_PROBE := '$(pound)include <sys/capability.h>\n'
LIBCAP_PROBE += 'int main(void) {'
LIBCAP_PROBE += ' cap_free(0);'
LIBCAP_PROBE += ' return 0;'
LIBCAP_PROBE += '}'
LIBCAP_PROBE_CMD = printf '%b\n' $(LIBCAP_PROBE) | \
$(CC) $(CFLAGS) -Wall -Werror -x c - -lcap -S -o - >/dev/null
define libcap_build
$(call detect,$(LIBCAP_PROBE_CMD))
endef
$(call LOG,Probing: feature-libcap)
feature-libcap := $(findstring 1, $(call libcap_build))
endif # libcap
### feature-llvm
ifneq ($(findstring llvm,$(FEATURE_TESTS)),)
LLVM_PROBE := '$(pound)include <llvm-c/Core.h>\n'
LLVM_PROBE += '$(pound)include <llvm-c/TargetMachine.h>\n'
LLVM_PROBE += 'int main(void) {'
LLVM_PROBE += ' char *triple = LLVMNormalizeTargetTriple("");'
LLVM_PROBE += ' LLVMDisposeMessage(triple);'
LLVM_PROBE += ' return 0;'
LLVM_PROBE += '}'
# We need some adjustments for the flags.
# - $(CFLAGS) was set to parent $(EXTRA_CFLAGS) at the beginning of this file.
# - $(EXTRA_LDFLAGS) from parent Makefile should be kept as well.
# - Libraries to use depend on whether we have a static or shared version of
# LLVM, pass the llvm-config flag and adjust the list of libraries
# accordingly.
FEATURE_LLVM_CFLAGS := $(CFLAGS) $(shell $(LLVM_CONFIG) --cflags 2>/dev/null)
FEATURE_LLVM_LIBS := $(shell $(LLVM_CONFIG) --libs target 2>/dev/null)
ifeq ($(shell $(LLVM_CONFIG) --shared-mode 2>/dev/null),static)
FEATURE_LLVM_LIBS += $(shell $(LLVM_CONFIG) --system-libs target 2>/dev/null)
FEATURE_LLVM_LIBS += -lstdc++
endif
FEATURE_LDFLAGS := $(EXTRA_LDFLAGS) $(shell $(LLVM_CONFIG) --ldflags 2>/dev/null)
LLVM_PROBE_CMD = printf '%b\n' $(LLVM_PROBE) | \
$(CC) $(FEATURE_LLVM_CFLAGS) $(FEATURE_LDFLAGS) \
-Wall -Werror -x c - $(FEATURE_LLVM_LIBS) \
-o /dev/null >/dev/null
define llvm_build
$(call detect,$(LLVM_PROBE_CMD))
endef
$(call LOG,Probing: feature-llvm)
feature-llvm := $(findstring 1, $(call llvm_build))
endif # llvm
### Print detection results
define print_status
ifeq ($(1), 1)
MSG = $(shell printf '...%30s: [ \033[32mon\033[m ]' $(2))
else
MSG = $(shell printf '...%30s: [ \033[31mOFF\033[m ]' $(2))
endif
endef
feature_print_status = $(eval $(print_status)) $(info $(MSG))
$(call feature_print_status,$(HAS_LIBBFD),libbfd)
$(foreach feature,$(filter-out libbfd%,$(FEATURE_DISPLAY)), \
$(call feature_print_status,$(feature-$(feature)),$(feature)))
CFLAGS := $(CFLAGS_BACKUP)
undefine LOG LOG_RES