This patch mainly modifies the main makefile to support compiling OSv kernel natively on aarch64 hardware like RPI 4, Odroid N2 and RockPro64. At the same time, we also support cross-compiling aarch64 kernel on x86_64 Ubuntu and Fedora host.
To achieve that, we mainly drop many conditionals 'ifeq ($(arch),aarch64)' and some 'ifeq ($(arch),x64)' that drive inclusion of aarch64 or x64 C++, boost and gcc headers in favour of sigle block testing CXX_INCLUDES and CROSS_PREFIX variables. Please note that the CXX_INCLUDES variable will be set to C++ headers path on both x86_64 and aarch64 host when compiling the corresponding arch artifacts (host_arch == arch) as well as on Ubuntu x86_64 when cross-compiling aarch64 version (host_arch = 'x64' and arch = 'aarch64'). The latter works like this because the corresponding Ubuntu package comes with all C++ and gcc headers. On Fedora we still need to point to build/downloaded_packages/aarch64/gcc/install directory where we install the aarch64 packages from Fedora repo. For the libraries' binaries like the *.so and *.a files we use the 'CXX --print-file-name *' technique which finds those on both x86_64 and aarch64 host when compiling natively and cross-compiling aarch64 on Ubuntu x86_64. Otherwise (cross-compiling on Fedora x86_64) we fallback to the directories in build/downloaded_packages/aarch64/gcc/install. Finally when cross-compiling aarch64, for boost, we always point the header includes and *so patch to build/downloaded_packages/aarch64/boost/install. Fixes #1106 Signed-off-by: Waldemar Kozaczuk <jwkozac...@gmail.com> --- Makefile | 119 ++++++++++++++++++++++++++++++-------------------- scripts/build | 10 ++++- 2 files changed, 79 insertions(+), 50 deletions(-) diff --git a/Makefile b/Makefile index f2779bfa..66448a9b 100644 --- a/Makefile +++ b/Makefile @@ -191,24 +191,44 @@ cscope: local-includes = INCLUDES = $(local-includes) -Iarch/$(arch) -I. -Iinclude -Iarch/common INCLUDES += -isystem include/glibc-compat +# +# Let us detect presence of standard C++ headers +CXX_INCLUDES = $(shell $(CXX) -E -xc++ - -v </dev/null 2>&1 | awk '/^End/ {exit} /^ .*c\+\+/ {print "-isystem" $$0}') +ifeq ($(CXX_INCLUDES),) + ifeq ($(CROSS_PREFIX),aarch64-linux-gnu-) + # We are on distribution where the aarch64-linux-gnu package does not come with C++ headers + # So let use point it to the expected location + aarch64_gccbase = build/downloaded_packages/aarch64/gcc/install + ifeq (,$(wildcard $(aarch64_gccbase))) + $(error Missing $(aarch64_gccbase) directory. Please run "./scripts/download_aarch64_packages.py") + endif -aarch64_gccbase = build/downloaded_packages/aarch64/gcc/install -aarch64_boostbase = build/downloaded_packages/aarch64/boost/install + gcc-inc-base := $(dir $(shell find $(aarch64_gccbase)/ -name vector | grep -v -e debug/vector$$ -e profile/vector$$ -e experimental/vector$$)) + ifeq (,$(gcc-inc-base)) + $(error Could not find C++ headers under $(aarch64_gccbase) directory. Please run "./scripts/download_aarch64_packages.py") + endif -ifeq ($(arch),aarch64) -ifeq (,$(wildcard $(aarch64_gccbase))) - $(error Missing $(aarch64_gccbase) directory. Please run "./scripts/download_fedora_aarch64_packages.py") -endif -ifeq (,$(wildcard $(aarch64_boostbase))) - $(error Missing $(aarch64_boostbase) directory. Please run "./scripts/download_fedora_aarch64_packages.py") -endif -endif + gcc-inc-base3 := $(dir $(shell dirname `find $(aarch64_gccbase)/ -name c++config.h | grep -v /32/`)) + ifeq (,$(gcc-inc-base3)) + $(error Could not find C++ headers under $(aarch64_gccbase) directory. Please run "./scripts/download_aarch64_packages.py") + endif + CXX_INCLUDES = -isystem $(gcc-inc-base) -isystem $(gcc-inc-base3) -ifeq ($(arch),aarch64) - gcc-inc-base := $(dir $(shell find $(aarch64_gccbase)/ -name vector | grep -v -e debug/vector$$ -e profile/vector$$ -e experimental/vector$$)) - gcc-inc-base3 := $(dir $(shell dirname `find $(aarch64_gccbase)/ -name c++config.h | grep -v /32/`)) - INCLUDES += -isystem $(gcc-inc-base) - INCLUDES += -isystem $(gcc-inc-base3) + gcc-inc-base2 := $(dir $(shell find $(aarch64_gccbase)/ -name unwind.h)) + ifeq (,$(gcc-inc-base2)) + $(error Could not find standard gcc headers like "unwind.h" under $(aarch64_gccbase) directory. Please run "./scripts/download_aarch64_packages.py") + endif + STANDARD_GCC_INCLUDES = -isystem $(gcc-inc-base2) + + gcc-sysroot = --sysroot $(aarch64_gccbase) + standard-includes-flag = -nostdinc + else + $(error Could not find standard C++ headers. Please run "sudo ./scripts/setup.py") + endif +else + # If gcc can find C++ headers it also means it can find standard libc headers, so no need to add them specifically + STANDARD_GCC_INCLUDES = + standard-includes-flag = endif ifeq ($(arch),x64) @@ -221,22 +241,17 @@ INCLUDES += -isystem $(libfdt_base) endif INCLUDES += $(boost-includes) -ifeq ($(arch),x64) # Starting in Gcc 6, the standard C++ header files (which we do not change) # must precede in the include path the C header files (which we replace). # This is explained in https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70722. # So we are forced to list here (before include/api) the system's default # C++ include directories, though they are already in the default search path. -INCLUDES += $(shell $(CXX) -E -xc++ - -v </dev/null 2>&1 | awk '/^End/ {exit} /^ .*c\+\+/ {print "-isystem" $$0}') -endif +INCLUDES += $(CXX_INCLUDES) INCLUDES += $(pre-include-api) INCLUDES += -isystem include/api INCLUDES += -isystem include/api/$(arch) -ifeq ($(arch),aarch64) - gcc-inc-base2 := $(dir $(shell find $(aarch64_gccbase)/ -name unwind.h)) - # must be after include/api, since it includes some libc-style headers: - INCLUDES += -isystem $(gcc-inc-base2) -endif +# must be after include/api, since it includes some libc-style headers: +INCLUDES += $(STANDARD_GCC_INCLUDES) INCLUDES += -isystem $(out)/gen/include INCLUDES += $(post-includes-bsd) @@ -266,8 +281,6 @@ $(out)/musl/%.o: source-dialects = kernel-defines = -D_KERNEL $(source-dialects) -gcc-sysroot = $(if $(CROSS_PREFIX), --sysroot $(aarch64_gccbase)) \ - # This play the same role as "_KERNEL", but _KERNEL unfortunately is too # overloaded. A lot of files will expect it to be set no matter what, specially # in headers. "userspace" inclusion of such headers is valid, and lacking @@ -291,9 +304,7 @@ COMMON = $(autodepend) -g -Wall -Wno-pointer-arith $(CFLAGS_WERROR) -Wformat=0 - -include compiler/include/intrinsics.hh \ $(arch-cflags) $(conf-opt) $(acpi-defines) $(tracing-flags) $(gcc-sysroot) \ $(configuration) -D__OSV__ -D__XEN_INTERFACE_VERSION__="0x00030207" -DARCH_STRING=$(ARCH_STR) $(EXTRA_FLAGS) -ifeq ($(arch),aarch64) - COMMON += -nostdinc -endif +COMMON += $(standard-includes-flag) tracing-flags-0 = tracing-flags-1 = -finstrument-functions -finstrument-functions-exclude-file-list=c++,trace.cc,trace.hh,align.hh,mmintrin.h @@ -1798,37 +1809,43 @@ objects += $(addprefix fs/, $(fs_objs)) objects += $(addprefix libc/, $(libc)) objects += $(addprefix musl/src/, $(musl)) -ifeq ($(arch),x64) - libstdc++.a := $(shell $(CXX) -print-file-name=libstdc++.a) - ifeq ($(filter /%,$(libstdc++.a)),) +libstdc++.a := $(shell $(CXX) -print-file-name=libstdc++.a) +ifeq ($(filter /%,$(libstdc++.a)),) +ifeq ($(arch),aarch64) + libstdc++.a := $(shell find $(aarch64_gccbase)/ -name libstdc++.a) + ifeq ($(libstdc++.a),) $(error Error: libstdc++.a needs to be installed.) endif - - libsupc++.a := $(shell $(CXX) -print-file-name=libsupc++.a) - ifeq ($(filter /%,$(libsupc++.a)),) - $(error Error: libsupc++.a needs to be installed.) - endif else - libstdc++.a := $(shell find $(aarch64_gccbase)/ -name libstdc++.a) - libsupc++.a := $(shell find $(aarch64_gccbase)/ -name libsupc++.a) + $(error Error: libstdc++.a needs to be installed.) +endif endif -ifeq ($(arch),x64) - libgcc.a := $(shell $(CC) -print-libgcc-file-name) - ifeq ($(filter /%,$(libgcc.a)),) +libgcc.a := $(shell $(CC) -print-libgcc-file-name) +ifeq ($(filter /%,$(libgcc.a)),) +ifeq ($(arch),aarch64) + libgcc.a := $(shell find $(aarch64_gccbase)/ -name libgcc.a | grep -v /32/) + ifeq ($(libgcc.a),) $(error Error: libgcc.a needs to be installed.) endif +else + $(error Error: libgcc.a needs to be installed.) +endif +endif - libgcc_eh.a := $(shell $(CC) -print-file-name=libgcc_eh.a) - ifeq ($(filter /%,$(libgcc_eh.a)),) +libgcc_eh.a := $(shell $(CC) -print-file-name=libgcc_eh.a) +ifeq ($(filter /%,$(libgcc_eh.a)),) +ifeq ($(arch),aarch64) + libgcc_eh.a := $(shell find $(aarch64_gccbase)/ -name libgcc_eh.a | grep -v /32/) + ifeq ($(libgcc_eh.a),) $(error Error: libgcc_eh.a needs to be installed.) endif else - libgcc.a := $(shell find $(aarch64_gccbase)/ -name libgcc.a | grep -v /32/) - libgcc_eh.a := $(shell find $(aarch64_gccbase)/ -name libgcc_eh.a | grep -v /32/) + $(error Error: libgcc_eh.a needs to be installed.) +endif endif -ifeq ($(arch),x64) +ifeq ($(CROSS_PREFIX),) # link with -mt if present, else the base version (and hope it is multithreaded) boost-mt := -mt boost-lib-dir := $(dir $(shell $(CC) --print-file-name libboost_system$(boost-mt).a)) @@ -1844,10 +1861,17 @@ ifeq ($(arch),x64) # special for Boost. boost-includes = else +ifeq ($(arch),aarch64) + aarch64_boostbase = build/downloaded_packages/aarch64/boost/install + ifeq (,$(wildcard $(aarch64_boostbase))) + $(error Missing $(aarch64_boostbase) directory. Please run "./scripts/download_aarch64_packages.py") + endif + boost-lib-dir := $(firstword $(dir $(shell find $(aarch64_boostbase)/ -name libboost_system*.a))) boost-mt := $(if $(filter %-mt.a, $(wildcard $(boost-lib-dir)/*.a)),-mt) boost-includes = -isystem $(aarch64_boostbase)/usr/include endif +endif boost-libs := $(boost-lib-dir)/libboost_system$(boost-mt).a @@ -1934,9 +1958,8 @@ $(bootfs_manifest_dep): phony echo -n $(bootfs_manifest) > $(bootfs_manifest_dep) ; \ fi -ifeq ($(arch),x64) libgcc_s_dir := $(dir $(shell $(CC) -print-file-name=libgcc_s.so.1)) -else +ifeq (,$(libgcc_s_dir)) libgcc_s_dir := ../../$(aarch64_gccbase)/lib64 endif diff --git a/scripts/build b/scripts/build index fed78fd3..4b907804 100755 --- a/scripts/build +++ b/scripts/build @@ -262,8 +262,14 @@ kernel_end=$(($loader_size+2097151 & ~2097151)) # the case in our old build.mk). cd $OUT -if [[ "$arch" == 'aarch64' ]]; then - libgcc_s_dir=$(readlink -f ../downloaded_packages/aarch64/gcc/install/lib64) +host_arch=$(uname -m) +if [[ "$host_arch" == "x86_64" && "$arch" == 'aarch64' ]]; then + libgcc_s_path=$(aarch64-linux-gnu-gcc -print-file-name=libgcc_s.so.1) + if [[ "$libgcc_s_path" == "libgcc_s.so.1" ]]; then + libgcc_s_dir=$(readlink -f ../downloaded_packages/aarch64/gcc/install/lib64) + else + libgcc_s_dir=$(dirname $(readlink -f $libgcc_s_path)) + fi else libgcc_s_dir=$(dirname $(readlink -f $(gcc -print-file-name=libgcc_s.so.1))) fi -- 2.29.2 -- You received this message because you are subscribed to the Google Groups "OSv Development" group. To unsubscribe from this group and stop receiving emails from it, send an email to osv-dev+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/osv-dev/20210105163708.182346-1-jwkozaczuk%40gmail.com.