packetvisor 1.0.1

Packetvisor is a Raw Packet I/O framework based on the Rust language. It can process packets much faster than Standard Sockets through the Linux Kernel's eXpress Data Path(XDP).
Documentation
# 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