diff options
| author | Sang-Heon Jeon <ekffu200098@gmail.com> | 2026-08-24 01:18:14 +0900 |
|---|---|---|
| committer | Julia Lawall <Julia.Lawall@inria.fr> | 2026-08-23 22:12:11 +0200 |
| commit | 2bd30b8dc75b823dd7bbef9d7bc68e1fd7ecee5c (patch) | |
| tree | dcc4da1d99f17541c5590ac63c77da4bf372a4ab /tools/build | |
| download | linux-stable-2bd30b8dc75b823dd7bbef9d7bc68e1fd7ecee5c.tar.gz linux-stable-2bd30b8dc75b823dd7bbef9d7bc68e1fd7ecee5c.zip | |
coccinelle: alloc_cast: drop removed allocatorsgrafted
- pci_alloc_consistent() and pci_zalloc_consistent() were removed by
commit 7968778914e5
("PCI: Remove the deprecated "pci-dma-compat.h" API")
- kmem_alloc() was removed by commit f078d4ea8276
("xfs: convert kmem_alloc() to kmalloc()")
- kmem_zalloc() was removed by commit 10634530f7ba
("xfs: convert kmem_zalloc() to kzalloc()")
- kmem_zone_alloc() and kmem_zone_zalloc() were removed by commit
bae633a4a283 ("xfs: remove xfs_zone_{alloc,zalloc} helpers")
So drop them from the rules.
No functional change.
Signed-off-by: Sang-Heon Jeon <ekffu200098@gmail.com>
Signed-off-by: Julia Lawall <Julia.Lawall@inria.fr>
Diffstat (limited to 'tools/build')
87 files changed, 2635 insertions, 0 deletions
diff --git a/tools/build/.gitignore b/tools/build/.gitignore new file mode 100644 index 000000000..98ae1f509 --- /dev/null +++ b/tools/build/.gitignore @@ -0,0 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only +fixdep diff --git a/tools/build/Build b/tools/build/Build new file mode 100644 index 000000000..1c7e598e9 --- /dev/null +++ b/tools/build/Build @@ -0,0 +1,2 @@ +hostprogs := fixdep +fixdep-y := fixdep.o diff --git a/tools/build/Build.include b/tools/build/Build.include new file mode 100644 index 000000000..cd0baa7a1 --- /dev/null +++ b/tools/build/Build.include @@ -0,0 +1,137 @@ +### +# build: Generic definitions +# +# Lots of this code have been borrowed or heavily inspired from parts +# of kbuild code, which is not credited, but mostly developed by: +# +# Copyright (C) Sam Ravnborg <sam@mars.ravnborg.org>, 2015 +# Copyright (C) Linus Torvalds <torvalds@linux-foundation.org>, 2015 +# + +### +# Convenient variables +comma := , +squote := ' +pound := \# +empty := +space := $(empty) $(empty) + +### +# Name of target with a '.' as filename prefix. foo/bar.o => foo/.bar.o +dot-target = $(dir $@).$(notdir $@) + +### +# filename of target with directory and extension stripped +basetarget = $(basename $(notdir $@)) + +### +# The temporary file to save gcc -MD generated dependencies must not +# contain a comma +depfile = $(subst $(comma),_,$(dot-target).d) + +### +# Check if both arguments has same arguments. Result is empty string if equal. +arg-check = $(strip $(filter-out $(cmd_$(1)), $(cmd_$@)) \ + $(filter-out $(cmd_$@), $(cmd_$(1))) ) + +### +# Escape single quote for use in echo statements +escsq = $(subst $(squote),'\$(squote)',$1) + +# Echo command +# Short version is used, if $(quiet) equals `quiet_', otherwise full one. +echo-cmd = $(if $($(quiet)cmd_$(1)),\ + echo ' $(call escsq,$($(quiet)cmd_$(1)))';) + +### +# Replace >$< with >$$< to preserve $ when reloading the .cmd file +# (needed for make) +# Replace >#< with >$(pound)< to avoid starting a comment in the .cmd file +# (needed for make) +# Replace >'< with >'\''< to be able to enclose the whole string in '...' +# (needed for the shell) +make-cmd = $(call escsq,$(subst $(pound),$$(pound),$(subst $$,$$$$,$(cmd_$(1))))) + +### +# Find any prerequisites that is newer than target or that does not exist. +# PHONY targets skipped in both cases. +any-prereq = $(filter-out $(PHONY),$?) $(filter-out $(PHONY) $(wildcard $^),$^) + +### +# Copy dependency data into .cmd file +# - gcc -M dependency info +# - command line to create object 'cmd_object :=' +dep-cmd = $(if $(wildcard $(fixdep)), \ + $(fixdep) $(depfile) $@ '$(make-cmd)' > $(dot-target).tmp; \ + rm -f $(depfile); \ + mv -f $(dot-target).tmp $(dot-target).cmd, \ + printf '$(pound) cannot find fixdep (%s)\n' $(fixdep) > $(dot-target).cmd; \ + printf '$(pound) using basic dep data\n\n' >> $(dot-target).cmd; \ + cat $(depfile) >> $(dot-target).cmd; \ + printf '\n%s\n' 'cmd_$@ := $(make-cmd)' >> $(dot-target).cmd) + +### +# if_changed_dep - execute command if any prerequisite is newer than +# target, or command line has changed and update +# dependencies in the cmd file +if_changed_dep = $(if $(strip $(any-prereq) $(arg-check)), \ + @set -e; \ + $(echo-cmd) $(cmd_$(1)); \ + $(dep-cmd)) + +# if_changed - execute command if any prerequisite is newer than +# target, or command line has changed +if_changed = $(if $(strip $(any-prereq) $(arg-check)), \ + @set -e; \ + $(echo-cmd) $(cmd_$(1)); \ + printf '%s\n' 'cmd_$@ := $(make-cmd)' > $(dot-target).cmd) + +### +# C flags to be used in rule definitions, includes: +# - depfile generation +# - global $(CFLAGS) +# - per target C flags +# - per object C flags +# - BUILD_STR macro to allow '-D"$(variable)"' constructs +c_flags_1 = -Wp,-MD,$(depfile) -Wp,-MT,$@ $(CFLAGS) -D"BUILD_STR(s)=\#s" $(CFLAGS_$(basetarget).o) $(CFLAGS_$(obj)) +c_flags_2 = $(filter-out $(CFLAGS_REMOVE_$(basetarget).o), $(c_flags_1)) +c_flags = $(filter-out $(CFLAGS_REMOVE_$(obj)), $(c_flags_2)) +cxx_flags = -Wp,-MD,$(depfile) -Wp,-MT,$@ $(CXXFLAGS) -D"BUILD_STR(s)=\#s" $(CXXFLAGS_$(basetarget).o) $(CXXFLAGS_$(obj)) + +### +# Rust flags to be used on rule definition, includes: +# - global $(RUST_FLAGS) +# - per target Rust flags +# - per object Rust flags +rust_flags_1 = $(RUST_FLAGS) $(RUST_FLAGS_$(basetarget).o) $(RUST_FLAGS_$(obj)) +rust_flags_2 = $(filter-out $(RUST_FLAGS_REMOVE_$(basetarget).o), $(rust_flags_1)) +rust_flags = $(filter-out $(RUST_FLAGS_REMOVE_$(obj)), $(rust_flags_2)) + +### +## HOSTCC C flags + +host_c_flags = -Wp,-MD,$(depfile) -Wp,-MT,$@ $(HOSTCFLAGS) -D"BUILD_STR(s)=\#s" $(HOSTCFLAGS_$(basetarget).o) $(HOSTCFLAGS_$(obj)) + +# output directory for tests below +TMPOUT = .tmp_$$$$ + +# try-run +# Usage: option = $(call try-run, $(CC)...-o "$$TMP",option-ok,otherwise) +# Exit code chooses option. "$$TMP" serves as a temporary file and is +# automatically cleaned up. +try-run = $(shell set -e; \ + TMP=$(TMPOUT)/tmp; \ + mkdir -p $(TMPOUT); \ + trap "rm -rf $(TMPOUT)" EXIT; \ + if ($(1)) >/dev/null 2>&1; \ + then echo "$(2)"; \ + else echo "$(3)"; \ + fi) + +# cc-option +# Usage: cflags-y += $(call cc-option,-march=winchip-c6,-march=i586) +cc-option = $(call try-run, \ + $(CC) -Werror $(1) -c -x c /dev/null -o "$$TMP",$(1),$(2)) + +# delete partially updated (i.e. corrupted) files on error +.DELETE_ON_ERROR: diff --git a/tools/build/Documentation/Build.txt b/tools/build/Documentation/Build.txt new file mode 100644 index 000000000..a22587475 --- /dev/null +++ b/tools/build/Documentation/Build.txt @@ -0,0 +1,168 @@ +Build Framework +=============== + +The perf build framework was adopted from the kernel build system, hence the +idea and the way how objects are built is the same. + +Basically the user provides set of 'Build' files that list objects and +directories to nest for specific target to be build. + +Unlike the kernel we don't have a single build object 'obj-y' list that where +we setup source objects, but we support more. This allows one 'Build' file to +carry a sources list for multiple build objects. + + +Build framework makefiles +------------------------- + +The build framework consists of 2 Makefiles: + + Build.include + Makefile.build + +While the 'Build.include' file contains just some generic definitions, the +'Makefile.build' file is the makefile used from the outside. It's +interface/usage is following: + + $ make -f tools/build/Makefile.build srctree=$(KSRC) dir=$(DIR) obj=$(OBJECT) + +where: + + KSRC - is the path to kernel sources + DIR - is the path to the project to be built + OBJECT - is the name of the build object + +When succefully finished the $(DIR) directory contains the final object file +called $(OBJECT)-in.o: + + $ ls $(DIR)/$(OBJECT)-in.o + +which includes all compiled sources described in 'Build' makefiles. + + +Build makefiles +--------------- + +The user supplies 'Build' makefiles that contains a objects list, and connects +the build to nested directories. + +Assume we have the following project structure: + + ex/a.c + /b.c + /c.c + /d.c + /arch/e.c + /arch/f.c + +Out of which you build the 'ex' binary ' and the 'libex.a' library: + + 'ex' - consists of 'a.o', 'b.o' and libex.a + 'libex.a' - consists of 'c.o', 'd.o', 'e.o' and 'f.o' + +The build framework does not create the 'ex' and 'libex.a' binaries for you, it +only prepares proper objects to be compiled and grouped together. + +To follow the above example, the user provides following 'Build' files: + + ex/Build: + ex-y += a.o + ex-y += b.o + ex-y += b.o # duplicates in the lists are allowed + + libex-y += c.o + libex-y += d.o + libex-y += arch/ + + ex/arch/Build: + libex-y += e.o + libex-y += f.o + +and runs: + + $ make -f tools/build/Makefile.build dir=. obj=ex + $ make -f tools/build/Makefile.build dir=. obj=libex + +which creates the following objects: + + ex/ex-in.o + ex/libex-in.o + +that contain request objects names in Build files. + +It's only a matter of 2 single commands to create the final binaries: + + $ ar rcs libex.a libex-in.o + $ gcc -o ex ex-in.o libex.a + +You can check the 'ex' example in 'tools/build/tests/ex' for more details. + + +Makefile.include +---------------- + +The tools/build/Makefile.include makefile could be included +via user makefiles to get usefull definitions. + +It defines following interface: + + - build macro definition: + build := -f $(srctree)/tools/build/Makefile.build dir=. obj + + to make it easier to invoke build like: + make $(build)=ex + + +Fixdep +------ +It is necessary to build the fixdep helper before invoking the build. +The Makefile.include file adds the fixdep target, that could be +invoked by the user. + + +Rules +----- + +The build framework provides standard compilation rules to handle .S and .c +compilation. + +It's possible to include special rule if needed (like we do for flex or bison +code generation). + + +CFLAGS +------ + +It's possible to alter the standard object C flags in the following way: + + CFLAGS_perf.o += '...' - adds CFLAGS for perf.o object + CFLAGS_gtk += '...' - adds CFLAGS for gtk build object + CFLAGS_REMOVE_perf.o += '...' - removes CFLAGS for perf.o object + CFLAGS_REMOVE_gtk += '...' - removes CFLAGS for gtk build object + +This C flags changes has the scope of the Build makefile they are defined in. + + +Dependencies +------------ + +For each built object file 'a.o' the '.a.cmd' is created and holds: + + - Command line used to built that object + (for each object) + + - Dependency rules generated by 'gcc -Wp,-MD,...' + (for compiled object) + +All existing '.cmd' files are included in the Build process to follow properly +the dependencies and trigger a rebuild when necessary. + + +Single rules +------------ + +It's possible to build single object file by choice, like: + + $ make util/map.o # objects + $ make util/map.i # preprocessor + $ make util/map.s # assembly diff --git a/tools/build/Makefile b/tools/build/Makefile new file mode 100644 index 000000000..3a5a3808a --- /dev/null +++ b/tools/build/Makefile @@ -0,0 +1,58 @@ +# SPDX-License-Identifier: GPL-2.0 +ifeq ($(srctree),) +srctree := $(patsubst %/,%,$(dir $(CURDIR))) +srctree := $(patsubst %/,%,$(dir $(srctree))) +endif + +include $(srctree)/tools//scripts/Makefile.include + +define allow-override + $(if $(or $(findstring environment,$(origin $(1))),\ + $(findstring command line,$(origin $(1)))),,\ + $(eval $(1) = $(2))) +endef + +$(call allow-override,CC,$(CROSS_COMPILE)gcc) +$(call allow-override,LD,$(CROSS_COMPILE)ld) + +export HOSTCC HOSTLD HOSTAR + +export srctree CC LD + +MAKEFLAGS := --no-print-directory +build := -f $(srctree)/tools/build/Makefile.build dir=. obj + +all: $(OUTPUT)fixdep + +# Make sure there's anything to clean, +# feature contains check for existing OUTPUT +TMP_O := $(if $(OUTPUT),$(OUTPUT)feature/,./) + +clean: + $(call QUIET_CLEAN, fixdep) + $(Q)find $(or $(OUTPUT),.) -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete + $(Q)rm -f $(OUTPUT)fixdep + $(call QUIET_CLEAN, feature-detect) +ifneq ($(wildcard $(TMP_O)),) + $(Q)$(MAKE) -C feature OUTPUT=$(TMP_O) clean >/dev/null +endif + +FIXDEP := $(OUTPUT)fixdep +FIXDEP_IN := $(OUTPUT)fixdep-in.o + +# To track fixdep's dependencies properly, fixdep needs to run on itself. +# Build it twice the first time. +$(FIXDEP_IN): FORCE + $(Q)if [ ! -f $(FIXDEP) ]; then \ + $(MAKE) $(build)=fixdep HOSTCFLAGS="$(KBUILD_HOSTCFLAGS)"; \ + rm -f $(FIXDEP).o; \ + fi + $(Q)$(MAKE) $(build)=fixdep HOSTCFLAGS="$(KBUILD_HOSTCFLAGS)" + + +$(FIXDEP): $(FIXDEP_IN) + $(QUIET_LINK)$(HOSTCC) $(FIXDEP_IN) $(KBUILD_HOSTLDFLAGS) -o $@ + +FORCE: + +.PHONY: FORCE diff --git a/tools/build/Makefile.build b/tools/build/Makefile.build new file mode 100644 index 000000000..ad69efdd4 --- /dev/null +++ b/tools/build/Makefile.build @@ -0,0 +1,181 @@ +# SPDX-License-Identifier: GPL-2.0 +### +# Main build makefile. +# +# Lots of this code have been borrowed or heavily inspired from parts +# of kbuild code, which is not credited, but mostly developed by: +# +# Copyright (C) Sam Ravnborg <sam@mars.ravnborg.org>, 2015 +# Copyright (C) Linus Torvalds <torvalds@linux-foundation.org>, 2015 +# + +PHONY := __build +__build: + +build-dir := $(srctree)/tools/build + +# Define $(fixdep) for dep-cmd function +ifeq ($(OUTPUT),) + fixdep := $(build-dir)/fixdep +else + fixdep := $(OUTPUT)/fixdep +endif + +# Generic definitions +include $(build-dir)/Build.include + +# do not force detected configuration +-include $(OUTPUT).config-detected + +# Init all relevant variables used in build files so +# 1) they have correct type +# 2) they do not inherit any value from the environment +subdir-y := +obj-y := +subdir-y := +subdir-obj-y := + +# Build definitions +build-file := $(dir)/Build +-include $(build-file) + +quiet_cmd_flex = FLEX $@ +quiet_cmd_bison = BISON $@ +quiet_cmd_test = TEST $@ + +# Create directory unless it exists +quiet_cmd_mkdir = MKDIR $(dir $@) + cmd_mkdir = mkdir -p $(dir $@) + rule_mkdir = $(if $(wildcard $(dir $@)),,@$(call echo-cmd,mkdir) $(cmd_mkdir)) + +# Compile command +quiet_cmd_cc_o_c = CC $@ + cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $< + +quiet_cmd_host_cc_o_c = HOSTCC $@ + cmd_host_cc_o_c = $(HOSTCC) $(host_c_flags) -c -o $@ $< + +quiet_cmd_cxx_o_c = CXX $@ + cmd_cxx_o_c = $(CXX) $(cxx_flags) -c -o $@ $< + +quiet_cmd_cpp_i_c = CPP $@ + cmd_cpp_i_c = $(CC) $(c_flags) -E -o $@ $< + +quiet_cmd_cc_s_c = AS $@ + cmd_cc_s_c = $(CC) $(c_flags) -S -o $@ $< + +quiet_cmd_gen = GEN $@ + +# Link agregate command +# If there's nothing to link, create empty $@ object. +quiet_cmd_ld_multi = LD $@ + cmd_ld_multi = $(if $(strip $(obj-y)),\ + printf "$(objprefix)%s " $(patsubst $(objprefix)%,%,$(filter $(obj-y),$^)) | \ + xargs $(LD) -r -o $@,rm -f $@; $(AR) rcs $@) + +quiet_cmd_host_ld_multi = HOSTLD $@ + cmd_host_ld_multi = $(if $(strip $(obj-y)),\ + printf "$(objprefix)%s " $(patsubst $(objprefix)%,%,$(filter $(obj-y),$^)) | \ + xargs $(HOSTLD) -r -o $@,rm -f $@; $(HOSTAR) rcs $@) + +rust_common_cmd = \ + $(RUSTC) $(rust_flags) \ + --crate-type staticlib -L $(objtree)/rust/ \ + --emit=dep-info=$(depfile),link + +quiet_cmd_rustc_a_rs = $(RUSTC) $(quiet_modtag) $@ + cmd_rustc_a_rs = $(rust_common_cmd) -o $@ -g $< $(cmd_objtool) + +ifneq ($(filter $(obj),$(hostprogs)),) + host = host_ +endif + +# Build rules +$(OUTPUT)%.o: %.c FORCE + $(call rule_mkdir) + $(call if_changed_dep,$(host)cc_o_c) + +$(OUTPUT)%.o: %.cpp FORCE + $(call rule_mkdir) + $(call if_changed_dep,cxx_o_c) + +$(OUTPUT)%.o: %.S FORCE + $(call rule_mkdir) + $(call if_changed_dep,$(host)cc_o_c) + +$(OUTPUT)%.i: %.c FORCE + $(call rule_mkdir) + $(call if_changed_dep,cpp_i_c) + +$(OUTPUT)%.s: %.S FORCE + $(call rule_mkdir) + $(call if_changed_dep,cpp_i_c) + +$(OUTPUT)%.s: %.c FORCE + $(call rule_mkdir) + $(call if_changed_dep,cc_s_c) + +# it's recommended to build a static rust library, when a foreight (to rust) +# linker is used. +$(OUTPUT)%.a: %.rs FORCE + $(call rule_mkdir) + $(call if_changed_dep,rustc_a_rs) + +# bison and flex files are generated in the OUTPUT directory +# so it needs a separate rule to depend on them properly +$(OUTPUT)%-bison.o: $(OUTPUT)%-bison.c FORCE + $(call rule_mkdir) + $(call if_changed_dep,$(host)cc_o_c) + +$(OUTPUT)%-flex.o: $(OUTPUT)%-flex.c FORCE + $(call rule_mkdir) + $(call if_changed_dep,$(host)cc_o_c) + +# Gather build data: +# obj-y - list of build objects +# subdir-y - list of directories to nest +# subdir-obj-y - list of directories objects 'dir/$(obj)-in.o' +obj-y := $($(obj)-y) +subdir-y := $(patsubst %/,%,$(filter %/, $(obj-y))) +obj-y := $(patsubst %/, %/$(obj)-in.o, $(obj-y)) +subdir-obj-y := $(filter %/$(obj)-in.o, $(obj-y)) + +# '$(OUTPUT)/dir' prefix to all objects +objprefix := $(subst ./,,$(OUTPUT)$(dir)/) +obj-y := $(addprefix $(objprefix),$(obj-y)) +subdir-obj-y := $(addprefix $(objprefix),$(subdir-obj-y)) + +# Separate out test log files from real build objects. +test-y := $(filter %_log, $(obj-y)) +obj-y := $(filter-out %_log, $(obj-y)) + +# Final '$(obj)-in.o' object +in-target := $(objprefix)$(obj)-in.o + +PHONY += $(subdir-y) + +$(subdir-y): + $(Q)$(MAKE) -f $(build-dir)/Makefile.build dir=$(dir)/$@ obj=$(obj) + +$(sort $(subdir-obj-y)): $(subdir-y) ; + +$(in-target): $(obj-y) $(test-y) FORCE + $(call rule_mkdir) + $(call if_changed,$(host)ld_multi) + +__build: $(in-target) + @: + +PHONY += FORCE +FORCE: + +# Include all cmd files to get all the dependency rules +# for all objects included +targets := $(wildcard $(sort $(obj-y) $(in-target) $(MAKECMDGOALS))) +cmd_files := $(wildcard $(foreach f,$(targets),$(dir $(f)).$(notdir $(f)).cmd)) + +ifneq ($(cmd_files),) + include $(cmd_files) +endif + +.PHONY: $(PHONY) diff --git a/tools/build/Makefile.feature b/tools/build/Makefile.feature new file mode 100644 index 000000000..99eb0ea09 --- /dev/null +++ b/tools/build/Makefile.feature @@ -0,0 +1,334 @@ +# SPDX-License-Identifier: GPL-2.0-only +feature_dir := $(srctree)/tools/build/feature + +ifneq ($(OUTPUT),) + OUTPUT_FEATURES = $(OUTPUT)feature/ + $(shell mkdir -p $(OUTPUT_FEATURES)) +endif + +feature_check = $(eval $(feature_check_code)) +define feature_check_code + 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) +endef + +feature_set = $(eval $(feature_set_code)) +define feature_set_code + feature-$(1) := 1 +endef + +# +# Build the feature check binaries in parallel, ignore errors, ignore return value and suppress output: +# + +# +# Note that this is not a complete list of all feature tests, just +# those that are typically built on a fully configured system. +# +# [ Feature tests not mentioned here have to be built explicitly in +# the rule that uses them - an example for that is the 'bionic' +# feature check. ] +# +# These + the ones in FEATURE_TESTS_EXTRA are included in +# tools/build/feature/test-all.c and we try to build it all together +# then setting all those features to '1' meaning they are all enabled. +# +# There are things like fortify-source that will be set to 1 because test-all +# is built with the flags needed to test if its enabled, resulting in +# +# $ rm -rf /tmp/b ; mkdir /tmp/b ; make -C tools/perf O=/tmp/b feature-dump +# $ grep fortify-source /tmp/b/FEATURE-DUMP +# feature-fortify-source=1 +# $ +# +# All the others should have lines in tools/build/feature/test-all.c like: +# +# #define main main_test_disassembler_init_styled +# # include "test-disassembler-init-styled.c" +# #undef main +# +# #define main main_test_libzstd +# # include "test-libzstd.c" +# #undef main +# +# int main(int argc, char *argv[]) +# { +# main_test_disassembler_four_args(); +# main_test_libzstd(); +# return 0; +# } +# +# If the sample above works, then we end up with these lines in the FEATURE-DUMP +# file: +# +# feature-disassembler-four-args=1 +# feature-libzstd=1 +# +FEATURE_TESTS_BASIC := \ + backtrace \ + libdw \ + eventfd \ + fortify-source \ + gettid \ + glibc \ + libbfd \ + libbfd-threadsafe \ + libelf \ + libelf-getphdrnum \ + libelf-gelf_getnote \ + libelf-getshdrstrndx \ + libelf-zstd \ + libnuma \ + numa_num_possible_cpus \ + libpython \ + libslang \ + libtraceevent \ + libcpupower \ + pthread-attr-setaffinity-np \ + pthread-barrier \ + reallocarray \ + stackprotector-all \ + timerfd \ + zlib \ + lzma \ + bpf \ + scandirat \ + sched_getcpu \ + sdt \ + setns \ + libaio \ + libzstd \ + disassembler-four-args \ + disassembler-init-styled \ + file-handle \ + libopenssl + +# FEATURE_TESTS_BASIC + FEATURE_TESTS_EXTRA is the complete list +# of all feature tests + +LIBUNWIND_ARCHS:=aarch64 arm loongarch64 mips ppc32 ppc64 riscv s390x x86 x86_64 + +FEATURE_TESTS_EXTRA := \ + bionic \ + compile-32 \ + compile-x32 \ + cplus-demangle \ + cxa-demangle \ + gtk2 \ + gtk2-infobar \ + hello \ + babeltrace2-ctf-writer \ + libcapstone \ + libcheck \ + libbfd-liberty \ + libbfd-liberty-z \ + libopencsd \ + libperl \ + llvm \ + libbpf \ + libpfm4 \ + libdebuginfod \ + clang-bpf-co-re \ + bpftool-skeletons \ + libunwind \ + libunwind-debug-frame \ + $(foreach arch,$(LIBUNWIND_ARCHS),libunwind-$(arch) libunwind-debug-frame-$(arch)) + + +FEATURE_TESTS ?= $(FEATURE_TESTS_BASIC) + +ifeq ($(FEATURE_TESTS),all) + FEATURE_TESTS := $(FEATURE_TESTS_BASIC) $(FEATURE_TESTS_EXTRA) +endif + +FEATURE_DISPLAY ?= \ + libdw \ + glibc \ + libelf \ + libnuma \ + numa_num_possible_cpus \ + libpython \ + libcapstone \ + llvm-perf \ + zlib \ + lzma \ + bpf \ + libaio \ + libzstd \ + libopenssl \ + rust + +# +# Declare group members of a feature to display the logical OR of the detection +# result instead of each member result. +# +FEATURE_GROUP_MEMBERS-libbfd = libbfd-liberty libbfd-liberty-z + +# +# Declare list of feature dependency packages that provide pkg-config files. +# +FEATURE_PKG_CONFIG ?= \ + babeltrace2-ctf-writer \ + libtraceevent \ + libtracefs + +feature_pkg_config = $(eval $(feature_pkg_config_code)) +define feature_pkg_config_code + FEATURE_CHECK_CFLAGS-$(1) := $(shell $(PKG_CONFIG) --cflags $(1) 2>/dev/null) + FEATURE_CHECK_LDFLAGS-$(1) := $(shell $(PKG_CONFIG) --libs $(1) 2>/dev/null) +endef + +# Set FEATURE_CHECK_(C|LD)FLAGS-$(package) for packages using pkg-config. +ifneq ($(PKG_CONFIG),) + $(foreach package,$(FEATURE_PKG_CONFIG),$(call feature_pkg_config,$(package))) +endif + +FEATURE_CHECK_LDFLAGS-libcheck = -lcheck + +# Set FEATURE_CHECK_(C|LD)FLAGS-all for all FEATURE_TESTS features. +# If in the future we need per-feature checks/flags for features not +# mentioned in this list we need to refactor this ;-). +set_test_all_flags = $(eval $(set_test_all_flags_code)) +define set_test_all_flags_code + FEATURE_CHECK_CFLAGS-all += $(FEATURE_CHECK_CFLAGS-$(1)) + FEATURE_CHECK_LDFLAGS-all += $(FEATURE_CHECK_LDFLAGS-$(1)) +endef + +$(foreach feat,$(FEATURE_TESTS),$(call set_test_all_flags,$(feat))) + +# +# Special fast-path for the 'all features are available' case: +# +$(call feature_check,all,$(MSG)) + +# +# Just in case the build freshly failed, make sure we print the +# feature matrix: +# +ifeq ($(feature-all), 1) + # + # test-all.c passed - just set all the core feature flags to 1: + # + $(foreach feat,$(FEATURE_TESTS),$(call feature_set,$(feat))) + # + # test-all.c does not comprise these tests, so we need to + # for this case to get features proper values + # + $(call feature_check,compile-32) + $(call feature_check,compile-x32) + $(call feature_check,bionic) + $(call feature_check,babeltrace2-ctf-writer) + $(call feature_check,libunwind) + $(call feature_check,libunwind-debug-frame) + $(foreach arch,$(LIBUNWIND_ARCHS),$(call feature_check,libunwind-$(arch))) + $(foreach arch,$(LIBUNWIND_ARCHS),$(call feature_check,libunwind-debug-frame-$(arch))) +else + $(foreach feat,$(FEATURE_TESTS),$(call feature_check,$(feat))) +endif + +# +# Print the result of the feature test: +# +feature_print_status = $(eval $(feature_print_status_code)) + +feature_group = $(eval $(feature_gen_group)) $(GROUP) + +define feature_gen_group + GROUP := $(1) + ifneq ($(feature_verbose),1) + GROUP += $(FEATURE_GROUP_MEMBERS-$(1)) + endif +endef + +define feature_print_status_code + ifneq (,$(filter 1,$(foreach feat,$(call feature_group,$(feat)),$(feature-$(feat))))) + MSG = $(shell printf '...%40s: [ \033[32mon\033[m ]' $(1)) + else + MSG = $(shell printf '...%40s: [ \033[31mOFF\033[m ]' $(1)) + endif +endef + +feature_print_text = $(eval $(feature_print_text_code)) +define feature_print_text_code + MSG = $(shell printf '...%40s: %s' $(1) $(2)) +endef + +# +# generates feature value assignment for name, like: +# $(call feature_assign,libdw) == feature-libdw=1 +# +feature_assign = feature-$(1)=$(feature-$(1)) + +FEATURE_DUMP_FILENAME = $(OUTPUT)FEATURE-DUMP$(FEATURE_USER) +FEATURE_DUMP := $(shell touch $(FEATURE_DUMP_FILENAME); cat $(FEATURE_DUMP_FILENAME)) + +feature_dump_check = $(eval $(feature_dump_check_code)) +define feature_dump_check_code + ifeq ($(findstring $(1),$(FEATURE_DUMP)),) + $(2) := 1 + endif +endef + +# +# First check if any test from FEATURE_DISPLAY +# and set feature_display := 1 if it does +$(foreach feat,$(FEATURE_DISPLAY),$(call feature_dump_check,$(call feature_assign,$(feat)),feature_display)) + +# +# Now also check if any other test changed, +# so we force FEATURE-DUMP generation +$(foreach feat,$(FEATURE_TESTS),$(call feature_dump_check,$(call feature_assign,$(feat)),feature_dump_changed)) + +# The $(feature_display) controls the default detection message +# output. It's set if: +# - detected features differes from stored features from +# last build (in $(FEATURE_DUMP_FILENAME) file) +# - one of the $(FEATURE_DISPLAY) is not detected +# - VF is enabled + +ifeq ($(feature_dump_changed),1) + $(shell rm -f $(FEATURE_DUMP_FILENAME)) + $(foreach feat,$(FEATURE_TESTS),$(shell echo "$(call feature_assign,$(feat))" >> $(FEATURE_DUMP_FILENAME))) +endif + +feature_display_check = $(eval $(feature_check_display_code)) +define feature_check_display_code + ifneq ($(feature-$(1)), 1) + feature_display := 1 + endif +endef + +$(foreach feat,$(FEATURE_DISPLAY),$(call feature_display_check,$(feat))) + +ifeq ($(VF),1) + feature_display := 1 + feature_verbose := 1 +endif + +ifneq ($(feature_verbose),1) + # + # Determine the features to omit from the displayed message, as only the + # logical OR of the detection result will be shown. + # + FEATURE_OMIT := $(foreach feat,$(FEATURE_DISPLAY),$(FEATURE_GROUP_MEMBERS-$(feat))) +endif + +feature_display_entries = $(eval $(feature_display_entries_code)) +define feature_display_entries_code + ifeq ($(feature_display),1) + $$(info ) + $$(info Auto-detecting system features:) + $(foreach feat,$(filter-out $(FEATURE_OMIT),$(FEATURE_DISPLAY)),$(call feature_print_status,$(feat),) $$(info $(MSG))) + endif + + ifeq ($(feature_verbose),1) + $(eval TMP := $(filter-out $(FEATURE_DISPLAY),$(FEATURE_TESTS))) + $(foreach feat,$(TMP),$(call feature_print_status,$(feat),) $$(info $(MSG))) + endif +endef + +ifeq ($(FEATURE_DISPLAY_DEFERRED),) + $(call feature_display_entries) + ifeq ($(feature_display),1) + $(info ) + endif +endif diff --git a/tools/build/Makefile.include b/tools/build/Makefile.include new file mode 100644 index 000000000..0e4de8340 --- /dev/null +++ b/tools/build/Makefile.include @@ -0,0 +1,20 @@ +# SPDX-License-Identifier: GPL-2.0-only +build := -f $(srctree)/tools/build/Makefile.build dir=. obj + +# More than just $(Q), we sometimes want to suppress all command output from a +# recursive make -- even the 'up to date' printout. +ifeq ($(V),1) + Q ?= + SILENT_MAKE = +$(Q)$(MAKE) +else + Q ?= @ + SILENT_MAKE = +$(Q)$(MAKE) --silent +endif + +fixdep: + $(SILENT_MAKE) -C $(srctree)/tools/build CFLAGS= LDFLAGS= $(OUTPUT)fixdep + +fixdep-clean: + $(Q)$(MAKE) -C $(srctree)/tools/build clean + +.PHONY: fixdep diff --git a/tools/build/feature/.gitignore b/tools/build/feature/.gitignore new file mode 100644 index 000000000..15fcd34ac --- /dev/null +++ b/tools/build/feature/.gitignore @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only +*.d +*.bin +*.output diff --git a/tools/build/feature/Makefile b/tools/build/feature/Makefile new file mode 100644 index 000000000..7d1650181 --- /dev/null +++ b/tools/build/feature/Makefile @@ -0,0 +1,397 @@ +# SPDX-License-Identifier: GPL-2.0 +include ../../scripts/Makefile.include + +LIBUNWIND_ARCHS:=aarch64 arm loongarch64 mips ppc32 ppc64 riscv s390x x86 x86_64 + +FILES= \ + test-all.bin \ + test-backtrace.bin \ + test-bionic.bin \ + test-libdw.bin \ + test-eventfd.bin \ + test-fortify-source.bin \ + test-glibc.bin \ + test-gtk2.bin \ + test-gtk2-infobar.bin \ + test-hello.bin \ + test-libbfd.bin \ + test-libbfd-threadsafe.bin \ + test-disassembler-four-args.bin \ + test-disassembler-init-styled.bin \ + test-reallocarray.bin \ + test-libbfd-liberty.bin \ + test-libbfd-liberty-z.bin \ + test-cplus-demangle.bin \ + test-cxa-demangle.bin \ + test-libcap.bin \ + test-libelf.bin \ + test-libelf-getphdrnum.bin \ + test-libelf-gelf_getnote.bin \ + test-libelf-getshdrstrndx.bin \ + test-libelf-zstd.bin \ + test-libdebuginfod.bin \ + test-libnuma.bin \ + test-numa_num_possible_cpus.bin \ + test-libperl.bin \ + test-libpython.bin \ + test-libslang.bin \ + test-libtraceevent.bin \ + test-libcpupower.bin \ + test-libtracefs.bin \ + test-libunwind.bin \ + test-libunwind-debug-frame.bin \ + $(foreach arch,$(LIBUNWIND_ARCHS),test-libunwind-$(arch).bin test-libunwind-debug-frame-$(arch).bin) \ + test-pthread-attr-setaffinity-np.bin \ + test-pthread-barrier.bin \ + test-stackprotector-all.bin \ + test-timerfd.bin \ + test-babeltrace2-ctf-writer.bin \ + test-libcapstone.bin \ + test-libcheck.bin \ + test-compile-32.bin \ + test-compile-x32.bin \ + test-zlib.bin \ + test-lzma.bin \ + test-bpf.bin \ + test-libbpf.bin \ + test-sdt.bin \ + test-gettid.bin \ + test-jvmti.bin \ + test-jvmti-cmlr.bin \ + test-scandirat.bin \ + test-sched_getcpu.bin \ + test-setns.bin \ + test-libopencsd.bin \ + test-llvm.bin \ + test-llvm-perf.bin \ + test-libaio.bin \ + test-libzstd.bin \ + test-clang-bpf-co-re.bin \ + test-file-handle.bin \ + test-libpfm4.bin \ + test-rust.bin \ + test-libopenssl.bin \ + test-bpftool-skeletons.bin + +FILES := $(addprefix $(OUTPUT),$(FILES)) + +# Some distros provide the command $(CROSS_COMPILE)pkg-config for +# searching packges installed with Multiarch. Use it for cross +# compilation if it is existed. +ifneq (, $(shell which $(CROSS_COMPILE)pkg-config)) + PKG_CONFIG ?= $(CROSS_COMPILE)pkg-config +else + PKG_CONFIG ?= pkg-config + + # PKG_CONFIG_PATH or PKG_CONFIG_LIBDIR, alongside PKG_CONFIG_SYSROOT_DIR + # for modified system root, are required for the cross compilation. + # If these PKG_CONFIG environment variables are not set, Multiarch library + # paths are used instead. + ifdef CROSS_COMPILE + ifeq ($(PKG_CONFIG_LIBDIR)$(PKG_CONFIG_PATH)$(PKG_CONFIG_SYSROOT_DIR),) + CROSS_ARCH = $(notdir $(CROSS_COMPILE:%-=%)) + PKG_CONFIG_LIBDIR := /usr/local/$(CROSS_ARCH)/lib/pkgconfig/ + PKG_CONFIG_LIBDIR := $(PKG_CONFIG_LIBDIR):/usr/local/lib/$(CROSS_ARCH)/pkgconfig/ + PKG_CONFIG_LIBDIR := $(PKG_CONFIG_LIBDIR):/usr/lib/$(CROSS_ARCH)/pkgconfig/ + PKG_CONFIG_LIBDIR := $(PKG_CONFIG_LIBDIR):/usr/local/share/pkgconfig/ + PKG_CONFIG_LIBDIR := $(PKG_CONFIG_LIBDIR):/usr/share/pkgconfig/ + export PKG_CONFIG_LIBDIR + endif + endif +endif + +ifeq ($(findstring -static,${LDFLAGS}),-static) + PKG_CONFIG += --static +endif + +all: $(FILES) + +__BUILD = $(CC) $(CFLAGS) -MD -Wall -Werror -o $@ $(patsubst %.bin,%.c,$(@F)) $(LDFLAGS) + BUILD = $(__BUILD) > $(@:.bin=.make.output) 2>&1 + BUILD_BFD = $(BUILD) -DPACKAGE='"perf"' -lbfd -ldl + BUILD_ALL = $(BUILD) -fstack-protector-all -O2 -D_FORTIFY_SOURCE=2 -ldw -lelf -lnuma -lelf -lslang \ + $(FLAGS_PERL_EMBED) $(FLAGS_PYTHON_EMBED) -ldl -lz -llzma -lzstd \ + $(shell $(PKG_CONFIG) --libs --cflags openssl 2>/dev/null) + +__BUILDXX = $(CXX) $(CXXFLAGS) -MD -Wall -Werror -o $@ $(patsubst %.bin,%.cpp,$(@F)) $(LDFLAGS) + BUILDXX = $(__BUILDXX) > $(@:.bin=.make.output) 2>&1 + +############################### + +$(OUTPUT)test-all.bin: + $(BUILD_ALL) + +$(OUTPUT)test-hello.bin: + $(BUILD) + +$(OUTPUT)test-pthread-attr-setaffinity-np.bin: + $(BUILD) -D_GNU_SOURCE -lpthread + +$(OUTPUT)test-pthread-barrier.bin: + $(BUILD) -lpthread + +$(OUTPUT)test-stackprotector-all.bin: + $(BUILD) -fstack-protector-all + +$(OUTPUT)test-fortify-source.bin: + $(BUILD) -O2 -D_FORTIFY_SOURCE=2 + +$(OUTPUT)test-bionic.bin: + $(BUILD) + +$(OUTPUT)test-libcap.bin: + $(BUILD) -lcap + +$(OUTPUT)test-libelf.bin: + $(BUILD) -lelf + +$(OUTPUT)test-eventfd.bin: + $(BUILD) + +$(OUTPUT)test-glibc.bin: + $(BUILD) + +$(OUTPUT)test-scandirat.bin: + $(BUILD) + +$(OUTPUT)test-sched_getcpu.bin: + $(BUILD) + +$(OUTPUT)test-setns.bin: + $(BUILD) + +$(OUTPUT)test-libopencsd.bin: + $(BUILD) # -lopencsd_c_api -lopencsd provided by + # $(FEATURE_CHECK_LDFLAGS-libopencsd) + +DWLIBS := -ldw +ifeq ($(findstring -static,${LDFLAGS}),-static) + DWLIBS += -lelf -lz -llzma -lbz2 -lzstd + + LIBDW_VERSION := $(shell $(PKG_CONFIG) --modversion libdw).0.0 + LIBDW_VERSION_1 := $(word 1, $(subst ., ,$(LIBDW_VERSION))) + LIBDW_VERSION_2 := $(word 2, $(subst ., ,$(LIBDW_VERSION))) + + # Elfutils merged libebl.a into libdw.a starting from version 0.177, + # Link libebl.a only if libdw is older than this version. + ifeq ($(shell test $(LIBDW_VERSION_2) -lt 177; echo $$?),0) + DWLIBS += -lebl + endif + + # Must put -ldl after -lebl for dependency + DWARFLIBS += -ldl +endif + +$(OUTPUT)test-libdw.bin: + $(BUILD) $(DWLIBS) + +$(OUTPUT)test-libelf-getphdrnum.bin: + $(BUILD) -lelf + +$(OUTPUT)test-libelf-gelf_getnote.bin: + $(BUILD) -lelf + +$(OUTPUT)test-libelf-getshdrstrndx.bin: + $(BUILD) -lelf + +$(OUTPUT)test-libelf-zstd.bin: + $(BUILD) -lelf -lz -lzstd + +$(OUTPUT)test-libdebuginfod.bin: + $(BUILD) -ldebuginfod + +$(OUTPUT)test-libnuma.bin: + $(BUILD) -lnuma + +$(OUTPUT)test-numa_num_possible_cpus.bin: + $(BUILD) -lnuma + +$(OUTPUT)test-libunwind.bin: + $(BUILD) -include libunwind.h -lelf -llzma -lunwind + +$(OUTPUT)test-libunwind-debug-frame.bin: + $(BUILD) -include libunwind.h -lelf -llzma -lunwind + +define LIBUNWIND_RULE +$$(OUTPUT)test-libunwind-$(1).bin: + $$(CC) $$(CFLAGS) -MD -Wall -Werror -include libunwind-$(1).h -o $$@ \ + test-libunwind.c $$(LDFLAGS) -lelf -llzma -lunwind-$(1) \ + > $$(@:.bin=.make.output) 2>&1 + +$$(OUTPUT)test-libunwind-debug-frame-$(1).bin: + $$(CC) $$(CFLAGS) -MD -Wall -Werror -include libunwind-$(1).h -o $$@ \ + test-libunwind-debug-frame.c $$(LDFLAGS) -lelf -llzma -lunwind-$(1) \ + > $$(@:.bin=.make.output) 2>&1 + +endef +$(foreach arch,$(LIBUNWIND_ARCHS), \ + $(eval $(call LIBUNWIND_RULE,$(arch))) \ +) + +$(OUTPUT)test-libslang.bin: + $(BUILD) -lslang + +$(OUTPUT)test-libtraceevent.bin: + $(BUILD) -ltraceevent + +$(OUTPUT)test-libcpupower.bin: + $(BUILD) -lcpupower + +$(OUTPUT)test-libtracefs.bin: + $(BUILD) $(shell $(PKG_CONFIG) --cflags libtracefs 2>/dev/null) -ltracefs + +$(OUTPUT)test-gtk2.bin: + $(BUILD) $(shell $(PKG_CONFIG) --libs --cflags gtk+-2.0 2>/dev/null) -Wno-deprecated-declarations + +$(OUTPUT)test-gtk2-infobar.bin: + $(BUILD) $(shell $(PKG_CONFIG) --libs --cflags gtk+-2.0 2>/dev/null) + +grep-libs = $(filter -l%,$(1)) +strip-libs = $(filter-out -l%,$(1)) + +PERL_EMBED_LDOPTS = $(shell perl -MExtUtils::Embed -e ldopts 2>/dev/null) +PERL_EMBED_LDFLAGS = $(call strip-libs,$(PERL_EMBED_LDOPTS)) +PERL_EMBED_LIBADD = $(call grep-libs,$(PERL_EMBED_LDOPTS)) +PERL_EMBED_CCOPTS = $(shell perl -MExtUtils::Embed -e ccopts 2>/dev/null) +FLAGS_PERL_EMBED=$(PERL_EMBED_CCOPTS) $(PERL_EMBED_LDOPTS) + +ifeq ($(CC_NO_CLANG), 0) + PERL_EMBED_LDOPTS := $(filter-out -specs=%,$(PERL_EMBED_LDOPTS)) + PERL_EMBED_CCOPTS := $(filter-out -flto=auto -ffat-lto-objects, $(PERL_EMBED_CCOPTS)) + PERL_EMBED_CCOPTS := $(filter-out -specs=%,$(PERL_EMBED_CCOPTS)) + FLAGS_PERL_EMBED += -Wno-compound-token-split-by-macro +endif + +$(OUTPUT)test-libperl.bin: + $(BUILD) $(FLAGS_PERL_EMBED) + +$(OUTPUT)test-libpython.bin: + $(BUILD) $(FLAGS_PYTHON_EMBED) + +$(OUTPUT)test-libbfd.bin: + $(BUILD_BFD) + +$(OUTPUT)test-libbfd-threadsafe.bin: + $(BUILD_BFD) || $(BUILD_BFD) -liberty || $(BUILD_BFD) -liberty -lz + +$(OUTPUT)test-disassembler-four-args.bin: + $(BUILD_BFD) -lopcodes || $(BUILD_BFD) -lopcodes -liberty || \ + $(BUILD_BFD) -lopcodes -liberty -lz + +$(OUTPUT)test-disassembler-init-styled.bin: + $(BUILD_BFD) -lopcodes || $(BUILD_BFD) -lopcodes -liberty || \ + $(BUILD_BFD) -lopcodes -liberty -lz + +$(OUTPUT)test-reallocarray.bin: + $(BUILD) + +$(OUTPUT)test-libbfd-liberty.bin: + $(CC) $(CFLAGS) -Wall -Werror -o $@ test-libbfd.c -DPACKAGE='"perf"' $(LDFLAGS) -lbfd -ldl -liberty + +$(OUTPUT)test-libbfd-liberty-z.bin: + $(CC) $(CFLAGS) -Wall -Werror -o $@ test-libbfd.c -DPACKAGE='"perf"' $(LDFLAGS) -lbfd -ldl -liberty -lz + +$(OUTPUT)test-cplus-demangle.bin: + $(BUILD) -liberty + +$(OUTPUT)test-cxa-demangle.bin: + $(BUILDXX) + +$(OUTPUT)test-backtrace.bin: + $(BUILD) + +$(OUTPUT)test-timerfd.bin: + $(BUILD) + +$(OUTPUT)test-babeltrace2-ctf-writer.bin: + $(BUILD) # -lbabeltrace2-ctf-writer provided by $(FEATURE_CHECK_LDFLAGS-babeltrace2-ctf-writer) + +$(OUTPUT)test-libcapstone.bin: + $(BUILD) # -lcapstone provided by $(FEATURE_CHECK_LDFLAGS-libcapstone) + +$(OUTPUT)test-libcheck.bin: + $(BUILD) # -lcheck is provided by $(FEATURE_CHECK_LDFLAGS-libcheck) + +$(OUTPUT)test-compile-32.bin: + $(CC) -m32 -Wall -Werror -o $@ test-compile.c + +$(OUTPUT)test-compile-x32.bin: + $(CC) -mx32 -Wall -Werror -o $@ test-compile.c + +$(OUTPUT)test-zlib.bin: + $(BUILD) -lz + +$(OUTPUT)test-lzma.bin: + $(BUILD) -llzma + +$(OUTPUT)test-bpf.bin: + $(BUILD) + +$(OUTPUT)test-libbpf.bin: + $(BUILD) -lbpf + +$(OUTPUT)test-sdt.bin: + $(BUILD) + +$(OUTPUT)test-gettid.bin: + $(BUILD) + +$(OUTPUT)test-jvmti.bin: + $(BUILD) + +$(OUTPUT)test-jvmti-cmlr.bin: + $(BUILD) + +$(OUTPUT)test-llvm.bin: + $(BUILDXX) -std=gnu++17 \ + -I$(shell $(LLVM_CONFIG) --includedir) \ + -L$(shell $(LLVM_CONFIG) --libdir) \ + $(shell $(LLVM_CONFIG) --libs Core BPF) \ + $(shell $(LLVM_CONFIG) --system-libs) \ + > $(@:.bin=.make.output) 2>&1 + +$(OUTPUT)test-llvm-perf.bin: + $(BUILDXX) -std=gnu++17 \ + -I$(shell $(LLVM_CONFIG) --includedir) \ + -L$(shell $(LLVM_CONFIG) --libdir) \ + $(shell $(LLVM_CONFIG) --libs Core BPF) \ + $(shell $(LLVM_CONFIG) --system-libs) \ + > $(@:.bin=.make.output) 2>&1 + +-include $(OUTPUT)*.d + +$(OUTPUT)test-libaio.bin: + $(BUILD) -lrt + +$(OUTPUT)test-libzstd.bin: + $(BUILD) -lzstd + +$(OUTPUT)test-clang-bpf-co-re.bin: test-clang-bpf-co-re.c + { $(CLANG) -S -g --target=bpf -o - $< | \ + grep BTF_KIND_VAR; } > $(@:.bin=.make.output) 2>&1 && touch $@ + +$(OUTPUT)test-file-handle.bin: + $(BUILD) + +$(OUTPUT)test-libpfm4.bin: + $(BUILD) -lpfm + +$(OUTPUT)test-libopenssl.bin: + $(BUILD) $(shell $(PKG_CONFIG) --libs --cflags openssl 2>/dev/null) + +$(OUTPUT)test-bpftool-skeletons.bin: + { $(SYSTEM_BPFTOOL) version | grep '^features:.*skeletons'; } \ + > $(@:.bin=.make.output) 2>&1 && touch $@ + +# Testing Rust is special: we don't compile anything, it's enough to check the +# compiler presence. Compiling a test code for this purposes is problematic, +# because Rust will emit a dependency file without any external references, +# meaning that if rustc will be removed the build process will still think it's +# there. +$(OUTPUT)test-rust.bin: + $(RUSTC) --version > /dev/null 2>&1 + +############################### + +clean: + rm -f $(FILES) $(OUTPUT)*.d $(FILES:.bin=.make.output) diff --git a/tools/build/feature/test-all.c b/tools/build/feature/test-all.c new file mode 100644 index 000000000..544563d62 --- /dev/null +++ b/tools/build/feature/test-all.c @@ -0,0 +1,183 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * test-all.c: Try to build all the main testcases at once. + * + * A well-configured system will have all the prereqs installed, so we can speed + * up auto-detection on such systems. + */ + +/* + * Quirk: Python headers cannot be in arbitrary places, so keep this testcase at + * the top: + */ +#define main main_test_libpython +# include "test-libpython.c" +#undef main + +#define main main_test_hello +# include "test-hello.c" +#undef main + +#define main main_test_libelf +# include "test-libelf.c" +#undef main + +#define main main_test_gettid +# include "test-gettid.c" +#undef main + +#define main main_test_glibc +# include "test-glibc.c" +#undef main + +#define main main_test_libdw +# include "test-libdw.c" +#undef main + +#define main main_test_eventfd +# include "test-eventfd.c" +#undef main + +#define main main_test_libelf_getphdrnum +# include "test-libelf-getphdrnum.c" +#undef main + +#define main main_test_libelf_gelf_getnote +# include "test-libelf-gelf_getnote.c" +#undef main + +#define main main_test_libelf_getshdrstrndx +# include "test-libelf-getshdrstrndx.c" +#undef main + +#define main main_test_libelf_zstd +# include "test-libelf-zstd.c" +#undef main + +#define main main_test_libslang +# include "test-libslang.c" +#undef main + +#define main main_test_backtrace +# include "test-backtrace.c" +#undef main + +#define main main_test_libnuma +# include "test-libnuma.c" +#undef main + +#define main main_test_numa_num_possible_cpus +# include "test-numa_num_possible_cpus.c" +#undef main + +#define main main_test_timerfd +# include "test-timerfd.c" +#undef main + +#define main main_test_stackprotector_all +# include "test-stackprotector-all.c" +#undef main + +#define main main_test_zlib +# include "test-zlib.c" +#undef main + +#define main main_test_pthread_attr_setaffinity_np +# include "test-pthread-attr-setaffinity-np.c" +#undef main + +#define main main_test_pthread_barrier +# include "test-pthread-barrier.c" +#undef main + +#define main main_test_scandirat +# include "test-scandirat.c" +#undef main + +#define main main_test_sched_getcpu +# include "test-sched_getcpu.c" +#undef main + +# if 0 +/* + * Disable babeltrace2-ctf-writer check for test-all, because the requested + * library version is not released yet in most distributions. Will + * reenable later. + */ + +#define main main_test_babeltrace2_ctf_writer +# include "test-babeltrace2-ctf-writer.c" +#undef main +#endif + +#define main main_test_lzma +# include "test-lzma.c" +#undef main + +#define main main_test_bpf +# include "test-bpf.c" +#undef main + +#define main main_test_sdt +# include "test-sdt.c" +#undef main + +#define main main_test_setns +# include "test-setns.c" +#undef main + +#define main main_test_libaio +# include "test-libaio.c" +#undef main + +#define main main_test_reallocarray +# include "test-reallocarray.c" +#undef main + +#define main main_test_libzstd +# include "test-libzstd.c" +#undef main + +#define main main_test_libtraceevent +# include "test-libtraceevent.c" +#undef main + +#define main main_test_libopenssl +# include "test-libopenssl.c" +#undef main + +int main(int argc, char *argv[]) +{ + main_test_libpython(); + main_test_hello(); + main_test_libelf(); + main_test_gettid(); + main_test_glibc(); + main_test_libdw(); + main_test_eventfd(); + main_test_libelf_getphdrnum(); + main_test_libelf_gelf_getnote(); + main_test_libelf_getshdrstrndx(); + main_test_libslang(); + main_test_backtrace(); + main_test_libnuma(); + main_test_numa_num_possible_cpus(); + main_test_timerfd(); + main_test_stackprotector_all(); + main_test_zlib(); + main_test_pthread_attr_setaffinity_np(); + main_test_pthread_barrier(); + main_test_lzma(); + main_test_bpf(); + main_test_scandirat(); + main_test_sched_getcpu(); + main_test_sdt(); + main_test_setns(); + main_test_libaio(); + main_test_reallocarray(); + main_test_libzstd(); + main_test_libtraceevent(); + main_test_libopenssl(); + + return 0; +} diff --git a/tools/build/feature/test-babeltrace2-ctf-writer.c b/tools/build/feature/test-babeltrace2-ctf-writer.c new file mode 100644 index 000000000..9c89082e9 --- /dev/null +++ b/tools/build/feature/test-babeltrace2-ctf-writer.c @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include <babeltrace2-ctf-writer/writer.h> + +int main(void) +{ + bt_ctf_stream_class_get_packet_context_type((void *) 0); + return 0; +} diff --git a/tools/build/feature/test-backtrace.c b/tools/build/feature/test-backtrace.c new file mode 100644 index 000000000..7962fbad6 --- /dev/null +++ b/tools/build/feature/test-backtrace.c @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: GPL-2.0 +#include <execinfo.h> +#include <stdio.h> + +int main(void) +{ + void *backtrace_fns[10]; + int entries; + + entries = backtrace(backtrace_fns, 10); + backtrace_symbols_fd(backtrace_fns, entries, 1); + + return 0; +} diff --git a/tools/build/feature/test-bionic.c b/tools/build/feature/test-bionic.c new file mode 100644 index 000000000..4bcc97765 --- /dev/null +++ b/tools/build/feature/test-bionic.c @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0 +#include <android/api-level.h> + +int main(void) +{ + return __ANDROID_API__; +} diff --git a/tools/build/feature/test-bpf.c b/tools/build/feature/test-bpf.c new file mode 100644 index 000000000..89d59674f --- /dev/null +++ b/tools/build/feature/test-bpf.c @@ -0,0 +1,50 @@ +// SPDX-License-Identifier: GPL-2.0 +#include <asm/unistd.h> +#include <linux/bpf.h> +#include <unistd.h> + +#ifndef __NR_bpf +# if defined(__i386__) +# define __NR_bpf 357 +# elif defined(__x86_64__) +# define __NR_bpf 321 +# elif defined(__aarch64__) +# define __NR_bpf 280 +# elif defined(__sparc__) +# define __NR_bpf 349 +# elif defined(__s390__) +# define __NR_bpf 351 +# elif defined(__mips__) && defined(_ABIO32) +# define __NR_bpf 4355 +# elif defined(__mips__) && defined(_ABIN32) +# define __NR_bpf 6319 +# elif defined(__mips__) && defined(_ABI64) +# define __NR_bpf 5315 +# elif defined(__loongarch__) +# define __NR_bpf 280 +# else +# error __NR_bpf not defined. libbpf does not support your arch. +# endif +#endif + +int main(void) +{ + union bpf_attr attr; + + /* Check fields in attr */ + attr.prog_type = BPF_PROG_TYPE_KPROBE; + attr.insn_cnt = 0; + attr.insns = 0; + attr.license = 0; + attr.log_buf = 0; + attr.log_size = 0; + attr.log_level = 0; + attr.kern_version = 0; + attr.prog_flags = 0; + + /* + * Test existence of __NR_bpf and BPF_PROG_LOAD. + * This call should fail if we run the testcase. + */ + return syscall(__NR_bpf, BPF_PROG_LOAD, &attr, sizeof(attr)) == 0; +} diff --git a/tools/build/feature/test-clang-bpf-co-re.c b/tools/build/feature/test-clang-bpf-co-re.c new file mode 100644 index 000000000..cb5265bfd --- /dev/null +++ b/tools/build/feature/test-clang-bpf-co-re.c @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2020 Facebook + +struct test { + int a; + int b; +} __attribute__((preserve_access_index)); + +volatile struct test global_value_for_test = {}; diff --git a/tools/build/feature/test-compile.c b/tools/build/feature/test-compile.c new file mode 100644 index 000000000..9821b8271 --- /dev/null +++ b/tools/build/feature/test-compile.c @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0 +#include <stdio.h> +int main(void) +{ + printf("Hello World!\n"); + return 0; +} diff --git a/tools/build/feature/test-cplus-demangle.c b/tools/build/feature/test-cplus-demangle.c new file mode 100644 index 000000000..2ba56474a --- /dev/null +++ b/tools/build/feature/test-cplus-demangle.c @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: GPL-2.0 +extern int printf(const char *format, ...); +extern char *cplus_demangle(const char *, int); + +int main(void) +{ + char symbol[4096] = "FieldName__9ClassNameFd"; + char *tmp; + + tmp = cplus_demangle(symbol, 0); + + printf("demangled symbol: {%s}\n", tmp); + + return 0; +} diff --git a/tools/build/feature/test-cxa-demangle.cpp b/tools/build/feature/test-cxa-demangle.cpp new file mode 100644 index 000000000..a3e712f65 --- /dev/null +++ b/tools/build/feature/test-cxa-demangle.cpp @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: GPL-2.0 +#include <stdio.h> +#include <stdlib.h> +#include <cxxabi.h> + +int main(void) +{ + size_t len = 256; + char *output = (char*)malloc(len); + int status; + + output = abi::__cxa_demangle("FieldName__9ClassNameFd", output, &len, &status); + + printf("demangled symbol: {%s}\n", output); + + return 0; +} diff --git a/tools/build/feature/test-disassembler-four-args.c b/tools/build/feature/test-disassembler-four-args.c new file mode 100644 index 000000000..45ce65cfd --- /dev/null +++ b/tools/build/feature/test-disassembler-four-args.c @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: GPL-2.0 +#include <bfd.h> +#include <dis-asm.h> + +int main(void) +{ + bfd *abfd = bfd_openr(NULL, NULL); + + disassembler(bfd_get_arch(abfd), + bfd_big_endian(abfd), + bfd_get_mach(abfd), + abfd); + + return 0; +} diff --git a/tools/build/feature/test-disassembler-init-styled.c b/tools/build/feature/test-disassembler-init-styled.c new file mode 100644 index 000000000..f1ce0ec3b --- /dev/null +++ b/tools/build/feature/test-disassembler-init-styled.c @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: GPL-2.0 +#include <stdio.h> +#include <dis-asm.h> + +int main(void) +{ + struct disassemble_info info; + + init_disassemble_info(&info, stdout, + NULL, NULL); + + return 0; +} diff --git a/tools/build/feature/test-eventfd.c b/tools/build/feature/test-eventfd.c new file mode 100644 index 000000000..f4de7ef00 --- /dev/null +++ b/tools/build/feature/test-eventfd.c @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2018, Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com> + +#include <sys/eventfd.h> + +int main(void) +{ + return eventfd(0, EFD_NONBLOCK); +} diff --git a/tools/build/feature/test-file-handle.c b/tools/build/feature/test-file-handle.c new file mode 100644 index 000000000..4d3b03b27 --- /dev/null +++ b/tools/build/feature/test-file-handle.c @@ -0,0 +1,17 @@ +#define _GNU_SOURCE +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <inttypes.h> + +int main(void) +{ + struct { + struct file_handle fh; + uint64_t cgroup_id; + } handle; + int mount_id; + + name_to_handle_at(AT_FDCWD, "/", &handle.fh, &mount_id, 0); + return 0; +} diff --git a/tools/build/feature/test-fortify-source.c b/tools/build/feature/test-fortify-source.c new file mode 100644 index 000000000..c8a57194f --- /dev/null +++ b/tools/build/feature/test-fortify-source.c @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0 +#include <stdio.h> + +int main(void) +{ + return puts("hi"); +} diff --git a/tools/build/feature/test-gettid.c b/tools/build/feature/test-gettid.c new file mode 100644 index 000000000..ef24e42d3 --- /dev/null +++ b/tools/build/feature/test-gettid.c @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2019, Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com> +#define _GNU_SOURCE +#include <unistd.h> + +int main(void) +{ + return gettid(); +} + +#undef _GNU_SOURCE diff --git a/tools/build/feature/test-glibc.c b/tools/build/feature/test-glibc.c new file mode 100644 index 000000000..20a250419 --- /dev/null +++ b/tools/build/feature/test-glibc.c @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: GPL-2.0 +#include <stdlib.h> + +#if !defined(__UCLIBC__) +#include <gnu/libc-version.h> +#else +#define XSTR(s) STR(s) +#define STR(s) #s +#endif + +int main(void) +{ +#if !defined(__UCLIBC__) + const char *version = gnu_get_libc_version(); +#else + const char *version = XSTR(__GLIBC__) "." XSTR(__GLIBC_MINOR__); +#endif + + return version == NULL; +} diff --git a/tools/build/feature/test-gtk2-infobar.c b/tools/build/feature/test-gtk2-infobar.c new file mode 100644 index 000000000..b1b716dd5 --- /dev/null +++ b/tools/build/feature/test-gtk2-infobar.c @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: GPL-2.0 +#pragma GCC diagnostic ignored "-Wstrict-prototypes" +#include <gtk/gtk.h> +#pragma GCC diagnostic error "-Wstrict-prototypes" + +int main(int argc, char *argv[]) +{ + gtk_init(&argc, &argv); + gtk_info_bar_new(); + + return 0; +} diff --git a/tools/build/feature/test-gtk2.c b/tools/build/feature/test-gtk2.c new file mode 100644 index 000000000..2aaf4bfc2 --- /dev/null +++ b/tools/build/feature/test-gtk2.c @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0 +#pragma GCC diagnostic ignored "-Wstrict-prototypes" +#include <gtk/gtk.h> +#pragma GCC diagnostic error "-Wstrict-prototypes" + +int main(int argc, char *argv[]) +{ + gtk_init(&argc, &argv); + + return 0; +} diff --git a/tools/build/feature/test-hello.c b/tools/build/feature/test-hello.c new file mode 100644 index 000000000..c8a57194f --- /dev/null +++ b/tools/build/feature/test-hello.c @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0 +#include <stdio.h> + +int main(void) +{ + return puts("hi"); +} diff --git a/tools/build/feature/test-jvmti-cmlr.c b/tools/build/feature/test-jvmti-cmlr.c new file mode 100644 index 000000000..c27b5b71a --- /dev/null +++ b/tools/build/feature/test-jvmti-cmlr.c @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0 +#include <jvmti.h> +#include <jvmticmlr.h> + +int main(void) +{ + jvmtiCompiledMethodLoadInlineRecord rec __attribute__((unused)); + jvmtiCompiledMethodLoadRecordHeader hdr __attribute__((unused)); + PCStackInfo p __attribute__((unused)); + return 0; +} diff --git a/tools/build/feature/test-jvmti.c b/tools/build/feature/test-jvmti.c new file mode 100644 index 000000000..799916d2e --- /dev/null +++ b/tools/build/feature/test-jvmti.c @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: GPL-2.0 +#include <jvmti.h> + +int main(void) +{ + JavaVM jvm __attribute__((unused)); + jvmtiEventCallbacks cb __attribute__((unused)); + jvmtiCapabilities caps __attribute__((unused)); + jvmtiJlocationFormat format __attribute__((unused)); + jvmtiEnv jvmti __attribute__((unused)); + + return 0; +} diff --git a/tools/build/feature/test-libaio.c b/tools/build/feature/test-libaio.c new file mode 100644 index 000000000..932133c9a --- /dev/null +++ b/tools/build/feature/test-libaio.c @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0 +#include <aio.h> + +int main(void) +{ + struct aiocb aiocb; + + aiocb.aio_fildes = 0; + aiocb.aio_offset = 0; + aiocb.aio_buf = 0; + aiocb.aio_nbytes = 0; + aiocb.aio_reqprio = 0; + aiocb.aio_sigevent.sigev_notify = 1 /*SIGEV_NONE*/; + + return (int)aio_return(&aiocb); +} diff --git a/tools/build/feature/test-libbfd-threadsafe.c b/tools/build/feature/test-libbfd-threadsafe.c new file mode 100644 index 000000000..fe97f95f6 --- /dev/null +++ b/tools/build/feature/test-libbfd-threadsafe.c @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: GPL-2.0 +#include <bfd.h> + +static bool lock(void *unused) +{ + return true; +} + +static bool unlock(void *unused) +{ + return true; +} + +int main(void) +{ + /* Check for presence of new thread safety API (version 2.42) */ + return !bfd_thread_init(lock, unlock, NULL); +} diff --git a/tools/build/feature/test-libbfd.c b/tools/build/feature/test-libbfd.c new file mode 100644 index 000000000..afa46b046 --- /dev/null +++ b/tools/build/feature/test-libbfd.c @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0 +#include <bfd.h> + +extern int printf(const char *format, ...); + +int main(void) +{ + char symbol[4096] = "FieldName__9ClassNameFd"; + char *tmp; + + tmp = bfd_demangle(0, symbol, 0); + + printf("demangled symbol: {%s}\n", tmp); + + return 0; +} diff --git a/tools/build/feature/test-libbpf.c b/tools/build/feature/test-libbpf.c new file mode 100644 index 000000000..cd9989f52 --- /dev/null +++ b/tools/build/feature/test-libbpf.c @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0 +#include <bpf/libbpf.h> + +#if !defined(LIBBPF_MAJOR_VERSION) || (LIBBPF_MAJOR_VERSION < 1) +#error At least libbpf 1.0 is required for Linux tools. +#endif + +int main(void) +{ + return bpf_object__open("test") ? 0 : -1; +} diff --git a/tools/build/feature/test-libcap.c b/tools/build/feature/test-libcap.c new file mode 100644 index 000000000..d2a2e1521 --- /dev/null +++ b/tools/build/feature/test-libcap.c @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: GPL-2.0 +#include <sys/capability.h> +#include <linux/capability.h> + +int main(void) +{ + cap_flag_value_t val; + cap_t caps = cap_get_proc(); + + if (!caps) + return 1; + + if (cap_get_flag(caps, CAP_SYS_ADMIN, CAP_EFFECTIVE, &val) != 0) + return 1; + + if (cap_free(caps) != 0) + return 1; + + return 0; +} diff --git a/tools/build/feature/test-libcapstone.c b/tools/build/feature/test-libcapstone.c new file mode 100644 index 000000000..fbe8dba18 --- /dev/null +++ b/tools/build/feature/test-libcapstone.c @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include <capstone/capstone.h> + +int main(void) +{ + csh handle; + + cs_open(CS_ARCH_X86, CS_MODE_64, &handle); + return 0; +} diff --git a/tools/build/feature/test-libcheck.c b/tools/build/feature/test-libcheck.c new file mode 100644 index 000000000..cfb8d452e --- /dev/null +++ b/tools/build/feature/test-libcheck.c @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 +#include <check.h> + +int main(void) +{ + Suite *s = suite_create("test"); + return s == 0; +} diff --git a/tools/build/feature/test-libcpupower.c b/tools/build/feature/test-libcpupower.c new file mode 100644 index 000000000..a346aa332 --- /dev/null +++ b/tools/build/feature/test-libcpupower.c @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 +#include <cpuidle.h> + +int main(void) +{ + int rv = cpuidle_state_count(0); + return rv; +} diff --git a/tools/build/feature/test-libdebuginfod.c b/tools/build/feature/test-libdebuginfod.c new file mode 100644 index 000000000..823f9fa93 --- /dev/null +++ b/tools/build/feature/test-libdebuginfod.c @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 +#include <elfutils/debuginfod.h> + +int main(void) +{ + debuginfod_client* c = debuginfod_begin(); + return !!c; +} diff --git a/tools/build/feature/test-libdw.c b/tools/build/feature/test-libdw.c new file mode 100644 index 000000000..aabd63ca7 --- /dev/null +++ b/tools/build/feature/test-libdw.c @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: GPL-2.0 +#include <stdlib.h> +#include <dwarf.h> +#include <elfutils/libdw.h> +#include <elfutils/libdwfl.h> +#include <elfutils/version.h> + +int test_libdw(void) +{ + Dwarf *dbg = dwarf_begin(0, DWARF_C_READ); + + return dbg == NULL; +} + +int test_libdw_unwind(void) +{ + /* + * This function is guarded via: __nonnull_attribute__ (1, 2). + * Passing '1' as arguments value. This code is never executed, + * only compiled. + */ + dwfl_thread_getframes((void *) 1, (void *) 1, NULL); + return 0; +} + +int test_libdw_getlocations(void) +{ + Dwarf_Addr base, start, end; + Dwarf_Attribute attr; + Dwarf_Op *op; + size_t nops; + ptrdiff_t offset = 0; + + return (int)dwarf_getlocations(&attr, offset, &base, &start, &end, &op, &nops); +} + +int test_libdw_getcfi(void) +{ + Dwarf *dwarf = NULL; + + return dwarf_getcfi(dwarf) == NULL; +} + +int test_elfutils(void) +{ + Dwarf_CFI *cfi = NULL; + + dwarf_cfi_end(cfi); + return 0; +} + +int main(void) +{ + return test_libdw() + test_libdw_unwind() + test_libdw_getlocations() + + test_libdw_getcfi() + test_elfutils(); +} diff --git a/tools/build/feature/test-libelf-gelf_getnote.c b/tools/build/feature/test-libelf-gelf_getnote.c new file mode 100644 index 000000000..e06121161 --- /dev/null +++ b/tools/build/feature/test-libelf-gelf_getnote.c @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 +#include <stdlib.h> +#include <gelf.h> + +int main(void) +{ + return gelf_getnote(NULL, 0, NULL, NULL, NULL) == 0; +} diff --git a/tools/build/feature/test-libelf-getphdrnum.c b/tools/build/feature/test-libelf-getphdrnum.c new file mode 100644 index 000000000..96a7f8d30 --- /dev/null +++ b/tools/build/feature/test-libelf-getphdrnum.c @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0 +#include <libelf.h> + +int main(void) +{ + size_t dst; + + return elf_getphdrnum(0, &dst); +} diff --git a/tools/build/feature/test-libelf-getshdrstrndx.c b/tools/build/feature/test-libelf-getshdrstrndx.c new file mode 100644 index 000000000..ae9f2fff5 --- /dev/null +++ b/tools/build/feature/test-libelf-getshdrstrndx.c @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0 +#include <libelf.h> + +int main(void) +{ + size_t dst; + + return elf_getshdrstrndx(0, &dst); +} diff --git a/tools/build/feature/test-libelf-zstd.c b/tools/build/feature/test-libelf-zstd.c new file mode 100644 index 000000000..a1324a1db --- /dev/null +++ b/tools/build/feature/test-libelf-zstd.c @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0 +#include <stddef.h> +#include <libelf.h> + +int main(void) +{ + elf_compress(NULL, ELFCOMPRESS_ZSTD, 0); + return 0; +} diff --git a/tools/build/feature/test-libelf.c b/tools/build/feature/test-libelf.c new file mode 100644 index 000000000..2dbb6ea87 --- /dev/null +++ b/tools/build/feature/test-libelf.c @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0 +#include <libelf.h> + +int main(void) +{ + Elf *elf = elf_begin(0, ELF_C_READ, 0); + + return !!elf; +} diff --git a/tools/build/feature/test-libnuma.c b/tools/build/feature/test-libnuma.c new file mode 100644 index 000000000..b3aa59f8b --- /dev/null +++ b/tools/build/feature/test-libnuma.c @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0 +#include <numa.h> +#include <numaif.h> + +int main(void) +{ + numa_available(); + + return 0; +} diff --git a/tools/build/feature/test-libopencsd.c b/tools/build/feature/test-libopencsd.c new file mode 100644 index 000000000..4cfcef9da --- /dev/null +++ b/tools/build/feature/test-libopencsd.c @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0 +#include <opencsd/c_api/opencsd_c_api.h> + +/* + * Check OpenCSD library version is sufficient to provide required features + */ +#define OCSD_MIN_VER ((1 << 16) | (2 << 8) | (1)) +#if !defined(OCSD_VER_NUM) || (OCSD_VER_NUM < OCSD_MIN_VER) +#error "OpenCSD >= 1.2.1 is required" +#endif + +int main(void) +{ + (void)ocsd_get_version(); + return 0; +} diff --git a/tools/build/feature/test-libopenssl.c b/tools/build/feature/test-libopenssl.c new file mode 100644 index 000000000..168c45894 --- /dev/null +++ b/tools/build/feature/test-libopenssl.c @@ -0,0 +1,7 @@ +#include <openssl/ssl.h> +#include <openssl/opensslv.h> + +int main(void) +{ + return SSL_library_init(); +} diff --git a/tools/build/feature/test-libperl.c b/tools/build/feature/test-libperl.c new file mode 100644 index 000000000..0415f437e --- /dev/null +++ b/tools/build/feature/test-libperl.c @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0 +#include <EXTERN.h> +#include <perl.h> + +int main(void) +{ + perl_alloc(); + + return 0; +} diff --git a/tools/build/feature/test-libpfm4.c b/tools/build/feature/test-libpfm4.c new file mode 100644 index 000000000..af49b2594 --- /dev/null +++ b/tools/build/feature/test-libpfm4.c @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0 +#include <sys/types.h> +#include <perfmon/pfmlib.h> + +int main(void) +{ + pfm_initialize(); + return 0; +} diff --git a/tools/build/feature/test-libpython.c b/tools/build/feature/test-libpython.c new file mode 100644 index 000000000..371c9113e --- /dev/null +++ b/tools/build/feature/test-libpython.c @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0 +#include <Python.h> + +int main(void) +{ + Py_Initialize(); + + return 0; +} +#undef _GNU_SOURCE diff --git a/tools/build/feature/test-libslang.c b/tools/build/feature/test-libslang.c new file mode 100644 index 000000000..9cbff8d1d --- /dev/null +++ b/tools/build/feature/test-libslang.c @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0 +#include <slang.h> + +int main(void) +{ + return SLsmg_init_smg(); +} diff --git a/tools/build/feature/test-libtraceevent.c b/tools/build/feature/test-libtraceevent.c new file mode 100644 index 000000000..804ad80db --- /dev/null +++ b/tools/build/feature/test-libtraceevent.c @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: GPL-2.0 +#include <trace-seq.h> + +int main(void) +{ + int rv = 0; + struct trace_seq s; + trace_seq_init(&s); + rv += !(s.state == TRACE_SEQ__GOOD); + trace_seq_destroy(&s); + return rv; +} diff --git a/tools/build/feature/test-libtracefs.c b/tools/build/feature/test-libtracefs.c new file mode 100644 index 000000000..29a757a7d --- /dev/null +++ b/tools/build/feature/test-libtracefs.c @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0 +#include <tracefs.h> + +int main(void) +{ + struct tracefs_instance *inst = tracefs_instance_create("dummy"); + + tracefs_instance_destroy(inst); + return 0; +} diff --git a/tools/build/feature/test-libunwind-debug-frame.c b/tools/build/feature/test-libunwind-debug-frame.c new file mode 100644 index 000000000..4c57e3700 --- /dev/null +++ b/tools/build/feature/test-libunwind-debug-frame.c @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0 +#include <stdlib.h> + +extern int +UNW_OBJ(dwarf_find_debug_frame) (int found, unw_dyn_info_t *di_debug, + unw_word_t ip, unw_word_t segbase, + const char *obj_name, unw_word_t start, + unw_word_t end); + +#define dwarf_find_debug_frame UNW_OBJ(dwarf_find_debug_frame) + +int main(void) +{ + dwarf_find_debug_frame(0, NULL, 0, 0, NULL, 0, 0); + return 0; +} diff --git a/tools/build/feature/test-libunwind.c b/tools/build/feature/test-libunwind.c new file mode 100644 index 000000000..5af5dc3a7 --- /dev/null +++ b/tools/build/feature/test-libunwind.c @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: GPL-2.0 +#include <stdlib.h> + +extern int UNW_OBJ(dwarf_search_unwind_table) (unw_addr_space_t as, + unw_word_t ip, + unw_dyn_info_t *di, + unw_proc_info_t *pi, + int need_unwind_info, void *arg); + + +#define dwarf_search_unwind_table UNW_OBJ(dwarf_search_unwind_table) + +static unw_accessors_t accessors; + +int main(void) +{ + unw_addr_space_t addr_space; + + addr_space = unw_create_addr_space(&accessors, 0); + if (addr_space) + return 0; + + unw_init_remote(NULL, addr_space, NULL); + dwarf_search_unwind_table(addr_space, 0, NULL, NULL, 0, NULL); + + return 0; +} diff --git a/tools/build/feature/test-libzstd.c b/tools/build/feature/test-libzstd.c new file mode 100644 index 000000000..55268c01b --- /dev/null +++ b/tools/build/feature/test-libzstd.c @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: GPL-2.0 +#include <zstd.h> + +int main(void) +{ + ZSTD_CStream *cstream; + + cstream = ZSTD_createCStream(); + ZSTD_freeCStream(cstream); + + return 0; +} diff --git a/tools/build/feature/test-llvm-perf.cpp b/tools/build/feature/test-llvm-perf.cpp new file mode 100644 index 000000000..a8cbb67e3 --- /dev/null +++ b/tools/build/feature/test-llvm-perf.cpp @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: GPL-2.0 +#include "llvm/Support/ManagedStatic.h" +#include "llvm/Support/raw_ostream.h" + +#if LLVM_VERSION_MAJOR < 13 +# error "Perf requires llvm-devel/llvm-dev version 13 or greater" +#endif + +int main() +{ + llvm::errs() << "Hello World!\n"; + llvm::llvm_shutdown(); + return 0; +} diff --git a/tools/build/feature/test-llvm.cpp b/tools/build/feature/test-llvm.cpp new file mode 100644 index 000000000..88a3d1bdd --- /dev/null +++ b/tools/build/feature/test-llvm.cpp @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: GPL-2.0 +#include "llvm/Support/ManagedStatic.h" +#include "llvm/Support/raw_ostream.h" +#define NUM_VERSION (((LLVM_VERSION_MAJOR) << 16) + (LLVM_VERSION_MINOR << 8) + LLVM_VERSION_PATCH) + +#if NUM_VERSION < 0x030900 +# error "LLVM version too low" +#endif +int main() +{ + llvm::errs() << "Hello World!\n"; + llvm::llvm_shutdown(); + return 0; +} diff --git a/tools/build/feature/test-lzma.c b/tools/build/feature/test-lzma.c new file mode 100644 index 000000000..b57103774 --- /dev/null +++ b/tools/build/feature/test-lzma.c @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0 +#include <lzma.h> + +int main(void) +{ + lzma_stream strm = LZMA_STREAM_INIT; + lzma_ret ret; + + ret = lzma_stream_decoder(&strm, UINT64_MAX, LZMA_CONCATENATED); + return ret ? -1 : 0; +} diff --git a/tools/build/feature/test-numa_num_possible_cpus.c b/tools/build/feature/test-numa_num_possible_cpus.c new file mode 100644 index 000000000..573d07b9c --- /dev/null +++ b/tools/build/feature/test-numa_num_possible_cpus.c @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0 +#include <numa.h> + +int main(void) +{ + return numa_num_possible_cpus(); +} diff --git a/tools/build/feature/test-pthread-attr-setaffinity-np.c b/tools/build/feature/test-pthread-attr-setaffinity-np.c new file mode 100644 index 000000000..38c71131c --- /dev/null +++ b/tools/build/feature/test-pthread-attr-setaffinity-np.c @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: GPL-2.0 +#include <stdint.h> +#include <pthread.h> +#include <sched.h> + +int main(void) +{ + int ret = 0; + pthread_attr_t thread_attr; + cpu_set_t cs; + + pthread_attr_init(&thread_attr); + CPU_ZERO(&cs); + + ret = pthread_attr_setaffinity_np(&thread_attr, sizeof(cs), &cs); + + return ret; +} diff --git a/tools/build/feature/test-pthread-barrier.c b/tools/build/feature/test-pthread-barrier.c new file mode 100644 index 000000000..0558d9334 --- /dev/null +++ b/tools/build/feature/test-pthread-barrier.c @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: GPL-2.0 +#include <stdint.h> +#include <pthread.h> + +int main(void) +{ + pthread_barrier_t barrier; + + pthread_barrier_init(&barrier, NULL, 1); + pthread_barrier_wait(&barrier); + return pthread_barrier_destroy(&barrier); +} diff --git a/tools/build/feature/test-reallocarray.c b/tools/build/feature/test-reallocarray.c new file mode 100644 index 000000000..8f6743e31 --- /dev/null +++ b/tools/build/feature/test-reallocarray.c @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0 +#define _GNU_SOURCE +#include <stdlib.h> + +int main(void) +{ + return !!reallocarray(NULL, 1, 1); +} + +#undef _GNU_SOURCE diff --git a/tools/build/feature/test-scandirat.c b/tools/build/feature/test-scandirat.c new file mode 100644 index 000000000..d7e19e185 --- /dev/null +++ b/tools/build/feature/test-scandirat.c @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: GPL-2.0 +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif +#include <dirent.h> + +int main(void) +{ + // expects non-NULL, arg3 is 'restrict' so "pointers" have to be different + return scandirat(/*dirfd=*/ 0, /*dirp=*/ (void *)1, /*namelist=*/ (void *)2, /*filter=*/ (void *)3, /*compar=*/ (void *)4); +} + +#undef _GNU_SOURCE diff --git a/tools/build/feature/test-sched_getcpu.c b/tools/build/feature/test-sched_getcpu.c new file mode 100644 index 000000000..48995ac79 --- /dev/null +++ b/tools/build/feature/test-sched_getcpu.c @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: GPL-2.0 +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif +#include <sched.h> + +int main(void) +{ + return sched_getcpu(); +} + +#undef _GNU_SOURCE diff --git a/tools/build/feature/test-sdt.c b/tools/build/feature/test-sdt.c new file mode 100644 index 000000000..22737b0da --- /dev/null +++ b/tools/build/feature/test-sdt.c @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 +#include <sys/sdt.h> + +int main(void) +{ + DTRACE_PROBE(provider, name); + return 0; +} diff --git a/tools/build/feature/test-setns.c b/tools/build/feature/test-setns.c new file mode 100644 index 000000000..2757c201e --- /dev/null +++ b/tools/build/feature/test-setns.c @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0 +#define _GNU_SOURCE +#include <sched.h> + +int main(void) +{ + return setns(0, 0); +} +#undef _GNU_SOURCE diff --git a/tools/build/feature/test-stackprotector-all.c b/tools/build/feature/test-stackprotector-all.c new file mode 100644 index 000000000..c8a57194f --- /dev/null +++ b/tools/build/feature/test-stackprotector-all.c @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0 +#include <stdio.h> + +int main(void) +{ + return puts("hi"); +} diff --git a/tools/build/feature/test-timerfd.c b/tools/build/feature/test-timerfd.c new file mode 100644 index 000000000..9c72c697a --- /dev/null +++ b/tools/build/feature/test-timerfd.c @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * test for timerfd functions used by perf-kvm-stat-live + */ +#include <sys/timerfd.h> + +int main(void) +{ + struct itimerspec new_value; + + int fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK); + if (fd < 0) + return 1; + + if (timerfd_settime(fd, 0, &new_value, NULL) != 0) + return 1; + + return 0; +} diff --git a/tools/build/feature/test-zlib.c b/tools/build/feature/test-zlib.c new file mode 100644 index 000000000..da6c35794 --- /dev/null +++ b/tools/build/feature/test-zlib.c @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0 +#include <zlib.h> + +int main(void) +{ + z_stream zs; + + inflateInit(&zs); + return 0; +} diff --git a/tools/build/fixdep.c b/tools/build/fixdep.c new file mode 100644 index 000000000..2501fea7a --- /dev/null +++ b/tools/build/fixdep.c @@ -0,0 +1,170 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * "Optimize" a list of dependencies as spit out by gcc -MD + * for the build framework. + * + * Original author: + * Copyright 2002 by Kai Germaschewski <kai.germaschewski@gmx.de> + * + * This code has been borrowed from kbuild's fixdep (scripts/basic/fixdep.c), + * Please check it for detailed explanation. This fixdep borow only the + * base transformation of dependecies without the CONFIG mangle. + */ + +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/mman.h> +#include <unistd.h> +#include <fcntl.h> +#include <string.h> +#include <stdlib.h> +#include <stdio.h> +#include <limits.h> + +char *target; +char *depfile; +char *cmdline; + +static void usage(void) +{ + fprintf(stderr, "Usage: fixdep <depfile> <target> <cmdline>\n"); + exit(1); +} + +/* + * Print out the commandline prefixed with cmd_<target filename> := + */ +static void print_cmdline(void) +{ + printf("cmd_%s := %s\n\n", target, cmdline); +} + +/* + * Important: The below generated source_foo.o and deps_foo.o variable + * assignments are parsed not only by make, but also by the rather simple + * parser in scripts/mod/sumversion.c. + */ +static void parse_dep_file(void *map, size_t len) +{ + char *m = map; + char *end = m + len; + char *p; + char s[PATH_MAX]; + int is_target, has_target = 0; + int saw_any_target = 0; + int is_first_dep = 0; + + while (m < end) { + /* Skip any "white space" */ + while (m < end && (*m == ' ' || *m == '\\' || *m == '\n')) + m++; + /* Find next "white space" */ + p = m; + while (p < end && *p != ' ' && *p != '\\' && *p != '\n') + p++; + /* Is the token we found a target name? */ + is_target = (*(p-1) == ':'); + /* Don't write any target names into the dependency file */ + if (is_target) { + /* The /next/ file is the first dependency */ + is_first_dep = 1; + has_target = 1; + } else if (has_target) { + /* Save this token/filename */ + memcpy(s, m, p-m); + s[p - m] = 0; + + /* + * Do not list the source file as dependency, + * so that kbuild is not confused if a .c file + * is rewritten into .S or vice versa. Storing + * it in source_* is needed for modpost to + * compute srcversions. + */ + if (is_first_dep) { + /* + * If processing the concatenation of + * multiple dependency files, only + * process the first target name, which + * will be the original source name, + * and ignore any other target names, + * which will be intermediate temporary + * files. + */ + if (!saw_any_target) { + saw_any_target = 1; + printf("source_%s := %s\n\n", + target, s); + printf("deps_%s := \\\n", + target); + } + is_first_dep = 0; + } else + printf(" %s \\\n", s); + } + /* + * Start searching for next token immediately after the first + * "whitespace" character that follows this token. + */ + m = p + 1; + } + + if (!saw_any_target) { + fprintf(stderr, "fixdep: parse error; no targets found\n"); + exit(1); + } + + printf("\n%s: $(deps_%s)\n\n", target, target); + printf("$(deps_%s):\n", target); +} + +static void print_deps(void) +{ + struct stat st; + int fd; + void *map; + + fd = open(depfile, O_RDONLY); + if (fd < 0) { + fprintf(stderr, "fixdep: error opening depfile: "); + perror(depfile); + exit(2); + } + if (fstat(fd, &st) < 0) { + fprintf(stderr, "fixdep: error fstat'ing depfile: "); + perror(depfile); + exit(2); + } + if (st.st_size == 0) { + fprintf(stderr, "fixdep: %s is empty\n", depfile); + close(fd); + return; + } + map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); + if ((long) map == -1) { + perror("fixdep: mmap"); + close(fd); + return; + } + + parse_dep_file(map, st.st_size); + + munmap(map, st.st_size); + + close(fd); +} + +int main(int argc, char **argv) +{ + if (argc != 4) + usage(); + + depfile = argv[1]; + target = argv[2]; + cmdline = argv[3]; + + print_cmdline(); + print_deps(); + + return 0; +} diff --git a/tools/build/tests/ex/Build b/tools/build/tests/ex/Build new file mode 100644 index 000000000..4d502f9b1 --- /dev/null +++ b/tools/build/tests/ex/Build @@ -0,0 +1,11 @@ +ex-y += ex.o +ex-y += a.o +ex-y += b.o +ex-y += b.o +ex-y += empty/ +ex-y += empty2/ +ex-y += inc.o + +libex-y += c.o +libex-y += d.o +libex-y += arch/ diff --git a/tools/build/tests/ex/Makefile b/tools/build/tests/ex/Makefile new file mode 100644 index 000000000..fee032e06 --- /dev/null +++ b/tools/build/tests/ex/Makefile @@ -0,0 +1,27 @@ +# SPDX-License-Identifier: GPL-2.0 +export srctree := $(abspath ../../../..) +export CC := gcc +export LD := ld +export AR := ar + +ex: + +include $(srctree)/tools/build/Makefile.include + +ex: ex-in.o libex-in.o + $(CC) -o $@ $^ + +ex.%: fixdep FORCE + make -f $(srctree)/tools/build/Makefile.build dir=. $@ + +ex-in.o: fixdep FORCE + make $(build)=ex + +libex-in.o: fixdep FORCE + make $(build)=libex + +clean: + find . -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete + rm -f ex ex.i ex.s + +.PHONY: FORCE diff --git a/tools/build/tests/ex/a.c b/tools/build/tests/ex/a.c new file mode 100644 index 000000000..66017a9f4 --- /dev/null +++ b/tools/build/tests/ex/a.c @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 + +int a(void) +{ + return 0; +} diff --git a/tools/build/tests/ex/arch/Build b/tools/build/tests/ex/arch/Build new file mode 100644 index 000000000..55506189e --- /dev/null +++ b/tools/build/tests/ex/arch/Build @@ -0,0 +1,2 @@ +libex-y += e.o +libex-y += f.o diff --git a/tools/build/tests/ex/arch/e.c b/tools/build/tests/ex/arch/e.c new file mode 100644 index 000000000..f6ef585b5 --- /dev/null +++ b/tools/build/tests/ex/arch/e.c @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 + +int e(void) +{ + return 0; +} diff --git a/tools/build/tests/ex/arch/f.c b/tools/build/tests/ex/arch/f.c new file mode 100644 index 000000000..bffd9c67e --- /dev/null +++ b/tools/build/tests/ex/arch/f.c @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 + +int f(void) +{ + return 0; +} diff --git a/tools/build/tests/ex/b.c b/tools/build/tests/ex/b.c new file mode 100644 index 000000000..2b29fb4d3 --- /dev/null +++ b/tools/build/tests/ex/b.c @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 + +int b(void) +{ + return 0; +} diff --git a/tools/build/tests/ex/c.c b/tools/build/tests/ex/c.c new file mode 100644 index 000000000..a63b20ab8 --- /dev/null +++ b/tools/build/tests/ex/c.c @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 + +int c(void) +{ + return 0; +} diff --git a/tools/build/tests/ex/d.c b/tools/build/tests/ex/d.c new file mode 100644 index 000000000..e114e8dca --- /dev/null +++ b/tools/build/tests/ex/d.c @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 + +int d(void) +{ + return 0; +} diff --git a/tools/build/tests/ex/empty/Build b/tools/build/tests/ex/empty/Build new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/tools/build/tests/ex/empty/Build diff --git a/tools/build/tests/ex/empty2/README b/tools/build/tests/ex/empty2/README new file mode 100644 index 000000000..2107cc5bf --- /dev/null +++ b/tools/build/tests/ex/empty2/README @@ -0,0 +1,2 @@ +This directory is left intentionally without Build file +to test proper nesting into Build-less directories. diff --git a/tools/build/tests/ex/ex.c b/tools/build/tests/ex/ex.c new file mode 100644 index 000000000..3c02756ef --- /dev/null +++ b/tools/build/tests/ex/ex.c @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: GPL-2.0 + +int a(void); +int b(void); +int c(void); +int d(void); +int e(void); +int f(void); +int inc(void); + +int main(void) +{ + a(); + b(); + c(); + d(); + e(); + f(); + inc(); + + return 0; +} diff --git a/tools/build/tests/ex/inc.c b/tools/build/tests/ex/inc.c new file mode 100644 index 000000000..3636ab5bf --- /dev/null +++ b/tools/build/tests/ex/inc.c @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0 +#ifdef INCLUDE +#include "krava.h" +#endif + +int inc(void) +{ + return 0; +} diff --git a/tools/build/tests/run.sh b/tools/build/tests/run.sh new file mode 100755 index 000000000..2c54e4d43 --- /dev/null +++ b/tools/build/tests/run.sh @@ -0,0 +1,70 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 + +function test_ex { + make -C ex V=1 clean > ex.out 2>&1 + make -C ex V=1 >> ex.out 2>&1 + + if [ ! -x ./ex/ex ]; then + echo FAILED + exit -1 + fi + + make -C ex V=1 clean > /dev/null 2>&1 + rm -f ex.out +} + +function test_ex_suffix { + make -C ex V=1 clean > ex.out 2>&1 + + # use -rR to disable make's builtin rules + make -rR -C ex V=1 ex.o >> ex.out 2>&1 + make -rR -C ex V=1 ex.i >> ex.out 2>&1 + make -rR -C ex V=1 ex.s >> ex.out 2>&1 + + if [ -x ./ex/ex ]; then + echo FAILED + exit -1 + fi + + if [ ! -f ./ex/ex.o -o ! -f ./ex/ex.i -o ! -f ./ex/ex.s ]; then + echo FAILED + exit -1 + fi + + make -C ex V=1 clean > /dev/null 2>&1 + rm -f ex.out +} + +function test_ex_include { + make -C ex V=1 clean > ex.out 2>&1 + + # build with krava.h include + touch ex/krava.h + make -C ex V=1 CFLAGS=-DINCLUDE >> ex.out 2>&1 + + if [ ! -x ./ex/ex ]; then + echo FAILED + exit -1 + fi + + # build without the include + rm -f ex/krava.h ex/ex + make -C ex V=1 >> ex.out 2>&1 + + if [ ! -x ./ex/ex ]; then + echo FAILED + exit -1 + fi + + make -C ex V=1 clean > /dev/null 2>&1 + rm -f ex.out +} + +echo -n Testing.. + +test_ex +test_ex_suffix +test_ex_include + +echo OK |
