mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-25 12:04:46 +08:00
cebdb73745
Cross-compilation with clang uses the -target parameter rather than a
toolchain prefix. Just like the kernel Makefile, add that parameter to
CFLAGS when CROSS_COMPILE is set.
Unlike the kernel Makefile, we use the --sysroot and --gcc-toolchain
options because unlike the kernel, tools require standard libraries.
Commit c91d4e47e1
("Makefile: Remove '--gcc-toolchain' flag") provides
some background about --gcc-toolchain. Normally clang finds on its own
the additional utilities and libraries that it needs (for example GNU ld
or glibc). On some systems however, this autodetection doesn't work.
There, our only recourse is asking GCC directly, and pass the result to
--sysroot and --gcc-toolchain. Of course that only works when a cross
GCC is available.
Autodetection worked fine on Debian, but to use the aarch64-linux-gnu
toolchain from Archlinux I needed both --sysroot (for crt1.o) and
--gcc-toolchain (for crtbegin.o, -lgcc). The --prefix parameter wasn't
needed there, but it might be useful on other distributions.
Use the CLANG_CROSS_FLAGS variable instead of CLANG_FLAGS because it
allows tools such as bpftool, that need to build both host and target
binaries, to easily filter out the cross-build flags from CFLAGS.
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Acked-by: Quentin Monnet <quentin@isovalent.com>
Acked-by: Nick Desaulniers <ndesaulniers@google.com>
Link: https://lore.kernel.org/bpf/20211216163842.829836-2-jean-philippe@linaro.org
172 lines
5.2 KiB
Makefile
172 lines
5.2 KiB
Makefile
# SPDX-License-Identifier: GPL-2.0
|
|
ifneq ($(O),)
|
|
ifeq ($(origin O), command line)
|
|
dummy := $(if $(shell cd $(PWD); test -d $(O) || echo $(O)),$(error O=$(O) does not exist),)
|
|
ABSOLUTE_O := $(shell cd $(PWD); cd $(O) ; pwd)
|
|
OUTPUT := $(ABSOLUTE_O)/$(if $(subdir),$(subdir)/)
|
|
COMMAND_O := O=$(ABSOLUTE_O)
|
|
ifeq ($(objtree),)
|
|
objtree := $(O)
|
|
endif
|
|
endif
|
|
endif
|
|
|
|
# check that the output directory actually exists
|
|
ifneq ($(OUTPUT),)
|
|
OUTDIR := $(shell cd $(OUTPUT) && pwd)
|
|
$(if $(OUTDIR),, $(error output directory "$(OUTPUT)" does not exist))
|
|
endif
|
|
|
|
#
|
|
# Include saner warnings here, which can catch bugs:
|
|
#
|
|
EXTRA_WARNINGS := -Wbad-function-cast
|
|
EXTRA_WARNINGS += -Wdeclaration-after-statement
|
|
EXTRA_WARNINGS += -Wformat-security
|
|
EXTRA_WARNINGS += -Wformat-y2k
|
|
EXTRA_WARNINGS += -Winit-self
|
|
EXTRA_WARNINGS += -Wmissing-declarations
|
|
EXTRA_WARNINGS += -Wmissing-prototypes
|
|
EXTRA_WARNINGS += -Wnested-externs
|
|
EXTRA_WARNINGS += -Wno-system-headers
|
|
EXTRA_WARNINGS += -Wold-style-definition
|
|
EXTRA_WARNINGS += -Wpacked
|
|
EXTRA_WARNINGS += -Wredundant-decls
|
|
EXTRA_WARNINGS += -Wstrict-prototypes
|
|
EXTRA_WARNINGS += -Wswitch-default
|
|
EXTRA_WARNINGS += -Wswitch-enum
|
|
EXTRA_WARNINGS += -Wundef
|
|
EXTRA_WARNINGS += -Wwrite-strings
|
|
EXTRA_WARNINGS += -Wformat
|
|
EXTRA_WARNINGS += -Wno-type-limits
|
|
|
|
# Makefiles suck: This macro sets a default value of $(2) for the
|
|
# variable named by $(1), unless the variable has been set by
|
|
# environment or command line. This is necessary for CC and AR
|
|
# because make sets default values, so the simpler ?= approach
|
|
# won't work as expected.
|
|
define allow-override
|
|
$(if $(or $(findstring environment,$(origin $(1))),\
|
|
$(findstring command line,$(origin $(1)))),,\
|
|
$(eval $(1) = $(2)))
|
|
endef
|
|
|
|
ifneq ($(LLVM),)
|
|
$(call allow-override,CC,clang)
|
|
$(call allow-override,AR,llvm-ar)
|
|
$(call allow-override,LD,ld.lld)
|
|
$(call allow-override,CXX,clang++)
|
|
$(call allow-override,STRIP,llvm-strip)
|
|
else
|
|
# Allow setting various cross-compile vars or setting CROSS_COMPILE as a prefix.
|
|
$(call allow-override,CC,$(CROSS_COMPILE)gcc)
|
|
$(call allow-override,AR,$(CROSS_COMPILE)ar)
|
|
$(call allow-override,LD,$(CROSS_COMPILE)ld)
|
|
$(call allow-override,CXX,$(CROSS_COMPILE)g++)
|
|
$(call allow-override,STRIP,$(CROSS_COMPILE)strip)
|
|
endif
|
|
|
|
CC_NO_CLANG := $(shell $(CC) -dM -E -x c /dev/null | grep -Fq "__clang__"; echo $$?)
|
|
|
|
ifneq ($(LLVM),)
|
|
HOSTAR ?= llvm-ar
|
|
HOSTCC ?= clang
|
|
HOSTLD ?= ld.lld
|
|
else
|
|
HOSTAR ?= ar
|
|
HOSTCC ?= gcc
|
|
HOSTLD ?= ld
|
|
endif
|
|
|
|
# Some tools require Clang, LLC and/or LLVM utils
|
|
CLANG ?= clang
|
|
LLC ?= llc
|
|
LLVM_CONFIG ?= llvm-config
|
|
LLVM_OBJCOPY ?= llvm-objcopy
|
|
LLVM_STRIP ?= llvm-strip
|
|
|
|
ifeq ($(CC_NO_CLANG), 1)
|
|
EXTRA_WARNINGS += -Wstrict-aliasing=3
|
|
|
|
else ifneq ($(CROSS_COMPILE),)
|
|
CLANG_CROSS_FLAGS := --target=$(notdir $(CROSS_COMPILE:%-=%))
|
|
GCC_TOOLCHAIN_DIR := $(dir $(shell which $(CROSS_COMPILE)gcc))
|
|
ifneq ($(GCC_TOOLCHAIN_DIR),)
|
|
CLANG_CROSS_FLAGS += --prefix=$(GCC_TOOLCHAIN_DIR)$(notdir $(CROSS_COMPILE))
|
|
CLANG_CROSS_FLAGS += --sysroot=$(shell $(CROSS_COMPILE)gcc -print-sysroot)
|
|
CLANG_CROSS_FLAGS += --gcc-toolchain=$(realpath $(GCC_TOOLCHAIN_DIR)/..)
|
|
endif # GCC_TOOLCHAIN_DIR
|
|
CFLAGS += $(CLANG_CROSS_FLAGS)
|
|
AFLAGS += $(CLANG_CROSS_FLAGS)
|
|
endif # CROSS_COMPILE
|
|
|
|
# Hack to avoid type-punned warnings on old systems such as RHEL5:
|
|
# We should be changing CFLAGS and checking gcc version, but this
|
|
# will do for now and keep the above -Wstrict-aliasing=3 in place
|
|
# in newer systems.
|
|
# Needed for the __raw_cmpxchg in tools/arch/x86/include/asm/cmpxchg.h
|
|
#
|
|
# See https://lore.kernel.org/lkml/9a8748490611281710g78402fbeh8ff7fcc162dbcbca@mail.gmail.com/
|
|
# and https://gcc.gnu.org/gcc-4.8/changes.html,
|
|
# that takes into account Linus's comments (search for Wshadow) for the reasoning about
|
|
# -Wshadow not being interesting before gcc 4.8.
|
|
|
|
ifneq ($(filter 3.%,$(MAKE_VERSION)),) # make-3
|
|
EXTRA_WARNINGS += -fno-strict-aliasing
|
|
EXTRA_WARNINGS += -Wno-shadow
|
|
else
|
|
EXTRA_WARNINGS += -Wshadow
|
|
endif
|
|
|
|
ifneq ($(findstring $(MAKEFLAGS), w),w)
|
|
PRINT_DIR = --no-print-directory
|
|
else
|
|
NO_SUBDIR = :
|
|
endif
|
|
|
|
ifneq ($(findstring s,$(filter-out --%,$(MAKEFLAGS))),)
|
|
silent=1
|
|
endif
|
|
|
|
#
|
|
# Define a callable command for descending to a new directory
|
|
#
|
|
# Call by doing: $(call descend,directory[,target])
|
|
#
|
|
descend = \
|
|
+mkdir -p $(OUTPUT)$(1) && \
|
|
$(MAKE) $(COMMAND_O) subdir=$(if $(subdir),$(subdir)/$(1),$(1)) $(PRINT_DIR) -C $(1) $(2)
|
|
|
|
QUIET_SUBDIR0 = +$(MAKE) $(COMMAND_O) -C # space to separate -C and subdir
|
|
QUIET_SUBDIR1 =
|
|
|
|
ifneq ($(silent),1)
|
|
ifneq ($(V),1)
|
|
QUIET_CC = @echo ' CC '$@;
|
|
QUIET_CC_FPIC = @echo ' CC FPIC '$@;
|
|
QUIET_CLANG = @echo ' CLANG '$@;
|
|
QUIET_AR = @echo ' AR '$@;
|
|
QUIET_LINK = @echo ' LINK '$@;
|
|
QUIET_MKDIR = @echo ' MKDIR '$@;
|
|
QUIET_GEN = @echo ' GEN '$@;
|
|
QUIET_SUBDIR0 = +@subdir=
|
|
QUIET_SUBDIR1 = ;$(NO_SUBDIR) \
|
|
echo ' SUBDIR '$$subdir; \
|
|
$(MAKE) $(PRINT_DIR) -C $$subdir
|
|
QUIET_FLEX = @echo ' FLEX '$@;
|
|
QUIET_BISON = @echo ' BISON '$@;
|
|
QUIET_GENSKEL = @echo ' GENSKEL '$@;
|
|
|
|
descend = \
|
|
+@echo ' DESCEND '$(1); \
|
|
mkdir -p $(OUTPUT)$(1) && \
|
|
$(MAKE) $(COMMAND_O) subdir=$(if $(subdir),$(subdir)/$(1),$(1)) $(PRINT_DIR) -C $(1) $(2)
|
|
|
|
QUIET_CLEAN = @printf ' CLEAN %s\n' $1;
|
|
QUIET_INSTALL = @printf ' INSTALL %s\n' $1;
|
|
QUIET_UNINST = @printf ' UNINST %s\n' $1;
|
|
endif
|
|
endif
|
|
|
|
pound := \#
|