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.

Reply via email to