gfxstream: meson qnx cross build
Pkgconfig wasn't able to resolve the dependencies for qnx build, so the
libraries and headers are found and added manually. Hopefully we can get
pkgconfig working soon to clean this up.
A `qnx` directory is added to the project root for qnx build scripts and
cross files. A script also handles the aemu dependency. Run 'make' to
build cross-compiled aemu deps, and then gfxstream. Cmake toolchain
file is added for building the aemu dependancy.
BUG=287082350
TEST=qnx cross compile: cd qnx || make
Change-Id: I1793356c42bfbc65c285fc7da5b7f13461f9dd4e
diff --git a/qnx/Makefile b/qnx/Makefile
new file mode 100644
index 0000000..1f25400
--- /dev/null
+++ b/qnx/Makefile
@@ -0,0 +1,8 @@
+LIST=OS
+ifndef QRECURSE
+QRECURSE=recurse.mk
+ifdef QCONFIG
+QRDIR=$(dir $(QCONFIG))
+endif
+endif
+include $(QRDIR)$(QRECURSE)
diff --git a/qnx/README.md b/qnx/README.md
new file mode 100644
index 0000000..b4a94d8
--- /dev/null
+++ b/qnx/README.md
@@ -0,0 +1,30 @@
+# Build: QNX
+
+Requires QNX SDP to build, with `QNX_TARGET` and `QNX_HOST` environment variables set. Make sure the latest meson is installed.
+
+Build scripts are made available to show how to cross-compile gfxstream and its aemu dependencies. See `./qnx/nto/build-aemu.sh` and `./qnx/nto/build-gfxstream.sh`
+
+ cd ./qnx
+ make
+
+Make will navigate to `./qnx/nto/aarch64le` and run the build scripts from there.
+
+The aemu dependency is downloaded to, and built in `./qnx/nto/aarch64le/aemu`.
+
+Gfxstream's build directory is `./qnx/nto/aarch64le/gfxstream`.
+
+ cd ./qnx
+ make install
+
+The install target requires the `INSTALL_ROOT_nto` environment variable, which sets the qnx staging/install path.
+
+pinfo.mk writes build info into the binary:
+
+ # use -i ./nto/aarch64le/gfxstream/host/libgfxstream_backend.so
+ QNX_BUILDID=(GNU)5dc1327b962ed2a7e992c1f6f35c0df3
+ NAME=libgfxstream_backend.so
+ DESCRIPTION=virtio-gpu backend renderer
+ DATE=2023/09/18-10:58:49-EDT
+ COMMIT=7b8c19e51845aee014684c43e6aa8409e919af6a
+
+A "recursive make" directory layout is used to allow multiplatform builds. For more info, see: [Conventions for Recursive Makefiles and Directories](https://www.qnx.com/developers/docs/7.1/#com.qnx.doc.neutrino.prog/topic/make_convent.html)
diff --git a/qnx/common.mk b/qnx/common.mk
new file mode 100644
index 0000000..478ba15
--- /dev/null
+++ b/qnx/common.mk
@@ -0,0 +1,43 @@
+ifndef QCONFIG
+QCONFIG=qconfig.mk
+endif
+include $(QCONFIG)
+
+.PHONY: gfxstream
+.PHONY: aemu
+.PHONY: clean
+.PHONY: install
+
+all: gfxstream
+
+check-sdp:
+ @if [ -z "$${QNX_TARGET}" ]; then \
+ echo "'QNX_TARGET' not set. Make sure QNX SDP environment is configured"; \
+ exit 1; \
+ fi
+ @if [ -z "$${QNX_HOST}" ]; then \
+ echo "'QNX_HOST' not set. Make sure QNX SDP environment is configured"; \
+ exit 1; \
+ fi
+
+check-install-root:
+ @if [ -z "$${INSTALL_ROOT_nto}" ]; then \
+ echo "'INSTALL_ROOT_nto' not set."; \
+ exit 1; \
+ fi
+
+aemu: check-sdp
+ ../build-aemu.sh
+
+gfxstream: check-sdp aemu
+ ../build-gfxstream.sh
+
+install: check-sdp check-install-root gfxstream
+ $(MAKE) -f ../../pinfo.mk gfxstream/host/libgfxstream*.so
+ $(CP_HOST) -d gfxstream/host/libgfxstream*.so $(INSTALL_ROOT_nto)/$(VARIANT)/usr/lib/
+
+clean: check-install-root
+ rm -rf aemu
+ rm -rf gfxstream
+ rm *.pinfo
+ rm $(INSTALL_ROOT_nto)/$(VARIANT)/usr/lib/libgfxstream*
diff --git a/qnx/nto/Makefile b/qnx/nto/Makefile
new file mode 100644
index 0000000..0cc5eae
--- /dev/null
+++ b/qnx/nto/Makefile
@@ -0,0 +1,8 @@
+LIST=CPU
+ifndef QRECURSE
+QRECURSE=recurse.mk
+ifdef QCONFIG
+QRDIR=$(dir $(QCONFIG))
+endif
+endif
+include $(QRDIR)$(QRECURSE)
diff --git a/qnx/nto/aarch64-le/Makefile b/qnx/nto/aarch64-le/Makefile
new file mode 100644
index 0000000..262ffd4
--- /dev/null
+++ b/qnx/nto/aarch64-le/Makefile
@@ -0,0 +1,3 @@
+export PROCESSOR=aarch64
+export VARIANT=aarch64le
+include ../../common.mk
diff --git a/qnx/nto/aarch64-le/meson.cross.ini b/qnx/nto/aarch64-le/meson.cross.ini
new file mode 100644
index 0000000..d6fd11a
--- /dev/null
+++ b/qnx/nto/aarch64-le/meson.cross.ini
@@ -0,0 +1,17 @@
+[properties]
+pkg_config_libdir = '@GLOBAL_SOURCE_ROOT@/qnx/pkgconfig'
+qnx_path_prefix = 'qnx/nto/aarch64-le'
+
+[binaries]
+c = 'ntoaarch64-gcc'
+cpp = 'ntoaarch64-g++'
+ar = 'ntoaarch64-ar'
+strip = 'ntoaarch64-strip'
+pkg-config = 'pkg-config'
+
+# meson host_machine == QNX target system
+[host_machine]
+system = 'qnx'
+cpu_family = 'aarch64'
+cpu = 'aarch64'
+endian = 'little'
diff --git a/qnx/nto/build-aemu.sh b/qnx/nto/build-aemu.sh
new file mode 100755
index 0000000..1deb5c9
--- /dev/null
+++ b/qnx/nto/build-aemu.sh
@@ -0,0 +1,20 @@
+#!/bin/sh
+set -e
+
+AEMU_COMMIT_SHA=HEAD
+
+if [ ! -d aemu ]
+then
+ git clone https://android.googlesource.com/platform/hardware/google/aemu aemu
+fi
+
+cd aemu
+git checkout $AEMU_COMMIT_SHA
+
+cmake -D CMAKE_TOOLCHAIN_FILE=../../qnx.nto.toolchain.cmake \
+ -D AEMU_COMMON_GEN_PKGCONFIG=ON \
+ -D AEMU_COMMON_BUILD_CONFIG=gfxstream \
+ -D ENABLE_VKCEREAL_TESTS=OFF -B build
+
+cmake --build build -j
+cmake --install build --prefix install
diff --git a/qnx/nto/build-gfxstream.sh b/qnx/nto/build-gfxstream.sh
new file mode 100755
index 0000000..8ac1b5b
--- /dev/null
+++ b/qnx/nto/build-gfxstream.sh
@@ -0,0 +1,22 @@
+#!/bin/sh
+set -e
+
+if [ -z "$QNX_HOST" ]; then
+ echo "QNX_HOST not set"
+ exit 1
+fi
+
+if [ -z "$QNX_TARGET" ]; then
+ echo "QNX_TARGET not set"
+ exit 1
+fi
+
+export PKG_CONFIG_LIBDIR=../../pkgconfig
+
+meson setup ../../.. gfxstream/ \
+ --cross-file ./meson.cross.ini \
+ -Ddefault_library=shared \
+ -Ddecoders=gles,vulkan,composer \
+ -Dqnx_target=$QNX_TARGET
+
+ninja -C gfxstream
diff --git a/qnx/nto/qnx.nto.toolchain.cmake b/qnx/nto/qnx.nto.toolchain.cmake
new file mode 100644
index 0000000..97b4b05
--- /dev/null
+++ b/qnx/nto/qnx.nto.toolchain.cmake
@@ -0,0 +1,42 @@
+
+if("$ENV{QNX_HOST}" STREQUAL "")
+ message(FATAL_ERROR "QNX_HOST environment variable not found. Please set path to your QNX SDP installation")
+endif()
+
+if("$ENV{QNX_TARGET}" STREQUAL "")
+ message(FATAL_ERROR "QNX_TARGET environment variable not found. Please set QNX target path")
+endif()
+
+if("$ENV{PROCESSOR}" STREQUAL "")
+ message(FATAL_ERROR "PROCESSOR variable not found. This variable should be set in the Makefile at CPU level (ie: nto/aarch64/Makefile)")
+endif()
+
+if("$ENV{VARIANT}" STREQUAL "")
+ message(FATAL_ERROR "VARIANT variable not found. This variable should be set in the Makefile at VARIANT level (ie: nto/aarch64/le/Makefile)")
+endif()
+
+message(STATUS "using QNX_HOST $ENV{QNX_HOST}")
+message(STATUS "using QNX_TARGET $ENV{QNX_TARGET}")
+message(STATUS "cpu=$ENV{PROCESSOR}")
+message(STATUS "variant=$ENV{VARIANT}")
+
+set(QNX true)
+set(CMAKE_SYSTEM_NAME QNX)
+add_definitions("-D_QNX_SOURCE")
+
+set(DEPENDENCY_OVERRIDE "DOWNLOAD")
+
+set(GENERATE_PINFO_FILES $ENV{GENERATE_PINFO_FILES})
+
+set(target gcc_nto$ENV{VARIANT})
+set(ntoarch $ENV{VARIANT})
+set(processor $ENV{PROCESSOR})
+set(CMAKE_C_COMPILER qcc)
+set(CMAKE_C_COMPILER_TARGET ${target})
+set(CMAKE_CXX_COMPILER qcc -lang-c++)
+set(CMAKE_CXX_COMPILER_TARGET ${target})
+set(CMAKE_ASM_COMPILER qcc -V${target})
+set(CMAKE_RANLIB $ENV{QNX_HOST}/usr/bin/nto${processor}-ranlib CACHE PATH "QNX ranlib Program" FORCE)
+set(CMAKE_AR $ENV{QNX_HOST}/usr/bin/nto${processor}-ar CACHE PATH "QNX ar Program" FORCE)
+set(CMAKE_SYSROOT $ENV{QNX_TARGET})
+set(CMAKE_CXX_STANDARD 20)
\ No newline at end of file
diff --git a/qnx/pinfo.mk b/qnx/pinfo.mk
new file mode 100644
index 0000000..5b87584
--- /dev/null
+++ b/qnx/pinfo.mk
@@ -0,0 +1,17 @@
+ifndef QCONFIG
+QCONFIG=qconfig.mk
+endif
+include $(QCONFIG)
+
+define PINFO
+PINFO DESCRIPTION=virtio-gpu backend renderer
+PINFO COMMIT=${shell git log --pretty=format:'%H' -n1 }
+endef
+USEFILE=
+
+include $(MKFILES_ROOT)/qtargets.mk
+
+FORCE:
+%.so: FORCE
+ $(ADD_PINFO)
+ $(ADD_USAGE)
diff --git a/qnx/pkgconfig/screen.pc b/qnx/pkgconfig/screen.pc
new file mode 100644
index 0000000..7879e17
--- /dev/null
+++ b/qnx/pkgconfig/screen.pc
@@ -0,0 +1,9 @@
+prefix=${env:QNX_TARGET}
+exec_prefix=${prefix}/${env:VARIANT}
+libdir=${exec_prefix}/usr/lib
+includedir=${prefix}/usr/include
+
+Name: screen
+Description: QNX Screen Composited Windowing Native API client
+Libs: -L${libdir} -lscreen
+Cflags: -I${includedir}