diff mbox series

[1/2] package/gcc/gcc-bpf: add BPF target support

Message ID 20220809094109.2279598-1-james.hilliard1@gmail.com
State New
Headers show
Series [1/2] package/gcc/gcc-bpf: add BPF target support | expand

Commit Message

James Hilliard Aug. 9, 2022, 9:41 a.m. UTC
This adds GCC BPF target support, however unlike traditional targets
the BPF target is effectively used by packages such as systemd as
a separate language rather than an entirely separate architecture.

As such we need to build what is effectively a multi-arch toolchain
for GCC BPF support, as the BPF target is effectively a bare metal
target this isn't the same as a multi-lib toolchain and generally
avoids library conflict issues as the BPF target does not have
userspace libraries.

This adds an additional gcc build stage which is similar to gcc-final
and added as a toolchain dependency when BPF target support is
enabled.

Similar to our gcc toolchain we also need a toolchain wrapper, this
is separate from our normal toolchain wrapper.

Cc: Jose E. Marchesi <jose.marchesi@oracle.com>
Cc: David Faust <david.faust@oracle.com>
Signed-off-by: James Hilliard <james.hilliard1@gmail.com>
---
 package/Makefile.in                           |   3 +
 package/gcc/Config.in.host                    |  12 ++
 package/gcc/gcc-bpf/gcc-bpf.hash              |   1 +
 package/gcc/gcc-bpf/gcc-bpf.mk                | 116 ++++++++++++++++++
 .../toolchain-buildroot.mk                    |   4 +
 5 files changed, 136 insertions(+)
 create mode 120000 package/gcc/gcc-bpf/gcc-bpf.hash
 create mode 100644 package/gcc/gcc-bpf/gcc-bpf.mk
diff mbox series

Patch

diff --git a/package/Makefile.in b/package/Makefile.in
index ff60f85092..a6f5292903 100644
--- a/package/Makefile.in
+++ b/package/Makefile.in
@@ -39,6 +39,9 @@  endif
 # Compute GNU_TARGET_NAME
 GNU_TARGET_NAME = $(ARCH)-$(TARGET_VENDOR)-$(TARGET_OS)-$(LIBC)$(ABI)
 
+# Compute BPF_TARGET_NAME
+BPF_TARGET_NAME = bpf-$(TARGET_VENDOR)-none
+
 # FLAT binary format needs uclinux, except RISC-V 64-bits which needs
 # the regular linux name.
 ifeq ($(BR2_BINFMT_FLAT):$(BR2_RISCV_64),y:)
diff --git a/package/gcc/Config.in.host b/package/gcc/Config.in.host
index ba2a2ee072..c49f6e6b26 100644
--- a/package/gcc/Config.in.host
+++ b/package/gcc/Config.in.host
@@ -60,6 +60,10 @@  config BR2_GCC_VERSION_12_X
 
 endchoice
 
+config BR2_GCC_SUPPORTS_BPF
+	bool
+	default y if BR2_TOOLCHAIN_GCC_AT_LEAST_12
+
 # libcilkrts was introduced in gcc 4.9 and removed in gcc 8.x
 config BR2_GCC_SUPPORTS_LIBCILKRTS
 	bool
@@ -94,6 +98,14 @@  config BR2_EXTRA_GCC_CONFIG_OPTIONS
 	  include. Those options are applied for all of the gcc
 	  initial, gcc intermediate and gcc final passes.
 
+config BR2_TOOLCHAIN_BUILDROOT_BPF
+	bool "Enable bpf support"
+	depends on BR2_GCC_SUPPORTS_BPF
+	depends on BR2_PACKAGE_HOST_BINUTILS_SUPPORTS_BPF
+	help
+	  Enable this option if you want your toolchain to support BPF
+	  targets.
+
 config BR2_TOOLCHAIN_BUILDROOT_CXX
 	bool "Enable C++ support"
 	select BR2_INSTALL_LIBSTDCPP
diff --git a/package/gcc/gcc-bpf/gcc-bpf.hash b/package/gcc/gcc-bpf/gcc-bpf.hash
new file mode 120000
index 0000000000..7ac9361ab2
--- /dev/null
+++ b/package/gcc/gcc-bpf/gcc-bpf.hash
@@ -0,0 +1 @@ 
+../gcc.hash
\ No newline at end of file
diff --git a/package/gcc/gcc-bpf/gcc-bpf.mk b/package/gcc/gcc-bpf/gcc-bpf.mk
new file mode 100644
index 0000000000..b12d27ad00
--- /dev/null
+++ b/package/gcc/gcc-bpf/gcc-bpf.mk
@@ -0,0 +1,116 @@ 
+################################################################################
+#
+# gcc-bpf
+#
+################################################################################
+
+GCC_BPF_VERSION = $(GCC_VERSION)
+GCC_BPF_SITE = $(GCC_SITE)
+GCC_BPF_SOURCE = $(GCC_SOURCE)
+
+HOST_GCC_BPF_DL_SUBDIR = gcc
+
+HOST_GCC_BPF_DEPENDENCIES = \
+	$(HOST_GCC_COMMON_DEPENDENCIES) \
+	$(BR_LIBC)
+
+HOST_GCC_BPF_EXCLUDES = $(HOST_GCC_EXCLUDES)
+
+HOST_GCC_BPF_POST_PATCH_HOOKS += HOST_GCC_APPLY_PATCHES
+
+# gcc doesn't support in-tree build, so we create a 'build'
+# subdirectory in the gcc sources, and build from there.
+HOST_GCC_BPF_SUBDIR = build
+
+HOST_GCC_BPF_PRE_CONFIGURE_HOOKS += HOST_GCC_CONFIGURE_SYMLINK
+
+HOST_GCC_BPF_CONF_OPTS = \
+	--target=$(BPF_TARGET_NAME) \
+	--prefix="$(HOST_DIR)" \
+	--sysconfdir="$(HOST_DIR)/etc" \
+	--enable-languages=c \
+	--with-gnu-ld \
+	--enable-static \
+	--disable-decimal-float \
+	--disable-gcov \
+	--disable-libssp \
+	--disable-multilib \
+	--disable-shared \
+	--with-gmp=$(HOST_DIR) \
+	--with-mpc=$(HOST_DIR) \
+	--with-mpfr=$(HOST_DIR) \
+	--with-pkgversion="Buildroot $(BR2_VERSION_FULL)" \
+	--with-bugurl="http://bugs.buildroot.net/" \
+	--without-zstd \
+	$(call qstrip,$(BR2_EXTRA_GCC_CONFIG_OPTIONS))
+
+ifeq ($(BR2_GCC_ENABLE_GRAPHITE),y)
+HOST_GCC_BPF_DEPENDENCIES += host-isl
+HOST_GCC_BPF_CONF_OPTS += --with-isl=$(HOST_DIR)
+else
+HOST_GCC_BPF_CONF_OPTS += --without-isl --without-cloog
+endif
+
+# Don't build documentation. It takes up extra space / build time,
+# and sometimes needs specific makeinfo versions to work
+HOST_GCC_BPF_CONF_ENV = \
+	MAKEINFO=missing
+
+# Make sure we have 'cc'
+define HOST_GCC_BPF_CREATE_CC_SYMLINKS
+	if [ ! -e $(HOST_DIR)/bin/$(BPF_TARGET_NAME)-cc ]; then \
+		ln -f $(HOST_DIR)/bin/$(BPF_TARGET_NAME)-gcc \
+			$(HOST_DIR)/bin/$(BPF_TARGET_NAME)-cc; \
+	fi
+endef
+
+HOST_GCC_BPF_POST_INSTALL_HOOKS += HOST_GCC_BPF_CREATE_CC_SYMLINKS
+
+HOST_GCC_BPF_MAKE_OPTS = $(HOST_GCC_COMMON_MAKE_OPTS) all-gcc all-target-libgcc
+HOST_GCC_BPF_INSTALL_OPTS = install-gcc install-target-libgcc
+
+HOST_GCC_BPF_TOOLCHAIN_WRAPPER_ARGS = -DBR_SYSROOT='"$(STAGING_SUBDIR)"'
+HOST_GCC_BPF_TOOLCHAIN_WRAPPER_ARGS += $(HOST_GCC_COMMON_TOOLCHAIN_WRAPPER_ARGS)
+
+define HOST_GCC_BPF_TOOLCHAIN_WRAPPER_BUILD
+	$(HOSTCC) $(HOST_CFLAGS) $(HOST_GCC_BPF_TOOLCHAIN_WRAPPER_ARGS) \
+		-s -Wl,--hash-style=$(TOOLCHAIN_WRAPPER_HASH_STYLE) \
+		toolchain/toolchain-wrapper.c \
+		-o $(@D)/toolchain-wrapper-bpf
+endef
+
+define HOST_GCC_BPF_TOOLCHAIN_WRAPPER_INSTALL
+	$(INSTALL) -D -m 0755 $(@D)/toolchain-wrapper-bpf \
+		$(HOST_DIR)/bin/toolchain-wrapper-bpf
+endef
+
+HOST_GCC_BPF_POST_BUILD_HOOKS += HOST_GCC_BPF_TOOLCHAIN_WRAPPER_BUILD
+HOST_GCC_BPF_POST_INSTALL_HOOKS += HOST_GCC_BPF_TOOLCHAIN_WRAPPER_INSTALL
+
+define HOST_GCC_BPF_INSTALL_WRAPPER_AND_SIMPLE_SYMLINKS
+	$(Q)cd $(HOST_DIR)/bin; \
+	for i in $(BPF_TARGET_NAME)-*; do \
+		case "$$i" in \
+		*.br_real) \
+			;; \
+		*-ar|*-ranlib|*-nm) \
+			ln -snf $$i bpf$${i##$(BPF_TARGET_NAME)}; \
+			;; \
+		*cc|*cc-*|*++|*++-*|*cpp|*-gfortran|*-gdc) \
+			rm -f $$i.br_real; \
+			mv $$i $$i.br_real; \
+			ln -sf toolchain-wrapper-bpf $$i; \
+			ln -sf toolchain-wrapper-bpf bpf$${i##$(BPF_TARGET_NAME)}; \
+			ln -snf $$i.br_real bpf$${i##$(BPF_TARGET_NAME)}.br_real; \
+			;; \
+		*) \
+			ln -snf $$i bpf$${i##$(BPF_TARGET_NAME)}; \
+			;; \
+		esac; \
+	done
+
+endef
+
+HOST_GCC_BPF_POST_INSTALL_HOOKS += HOST_GCC_BPF_INSTALL_WRAPPER_AND_SIMPLE_SYMLINKS
+
+$(eval $(host-autotools-package))
diff --git a/toolchain/toolchain-buildroot/toolchain-buildroot.mk b/toolchain/toolchain-buildroot/toolchain-buildroot.mk
index b30cc332d2..34e7e49a5f 100644
--- a/toolchain/toolchain-buildroot/toolchain-buildroot.mk
+++ b/toolchain/toolchain-buildroot/toolchain-buildroot.mk
@@ -12,6 +12,10 @@  BR_LIBC = $(call qstrip,$(BR2_TOOLCHAIN_BUILDROOT_LIBC))
 
 TOOLCHAIN_BUILDROOT_DEPENDENCIES = host-gcc-final
 
+ifeq ($(BR2_TOOLCHAIN_BUILDROOT_BPF),y)
+TOOLCHAIN_BUILDROOT_DEPENDENCIES += host-gcc-bpf
+endif
+
 TOOLCHAIN_BUILDROOT_ADD_TOOLCHAIN_DEPENDENCY = NO
 
 $(eval $(virtual-package))