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/gl-host-common/meson.build b/gl-host-common/meson.build
index 0392ee0..158581f 100644
--- a/gl-host-common/meson.build
+++ b/gl-host-common/meson.build
@@ -26,6 +26,10 @@
'opengl/NativeGpuInfo_linux.cpp',
)
+files_gl_host_common_qnx = files(
+ 'opengl/NativeGpuInfo_qnx.cpp',
+)
+
# HACK: For the misc.h file already in AEMU host common
inc_gl_host_common = include_directories('include')
@@ -35,6 +39,8 @@
files_lib_gl_host_common += files_gl_host_common_win32
elif host_machine.system() == 'linux'
files_lib_gl_host_common += files_gl_host_common_linux
+elif host_machine.system() == 'qnx'
+ files_lib_gl_host_common += files_gl_host_common_qnx
endif
lib_gl_host_common = static_library(
diff --git a/gl-host-common/opengl/NativeGpuInfo_qnx.cpp b/gl-host-common/opengl/NativeGpuInfo_qnx.cpp
new file mode 100644
index 0000000..9cd2ca4
--- /dev/null
+++ b/gl-host-common/opengl/NativeGpuInfo_qnx.cpp
@@ -0,0 +1,25 @@
+// Copyright 2017 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "host-common/opengl/NativeGpuInfo.h"
+
+void getGpuInfoListNative(GpuInfoList* gpulist) {
+ (void)gpulist;
+ // Adding noop instead of messing with the meson build.
+ // The cmake build did not require adding this file.
+}
+
+bool isVulkanSafeToUseNative() {
+ return true;
+}
diff --git a/host/gl/glestranslator/EGL/EglGlobalInfo.cpp b/host/gl/glestranslator/EGL/EglGlobalInfo.cpp
index 1603f41..167772c 100644
--- a/host/gl/glestranslator/EGL/EglGlobalInfo.cpp
+++ b/host/gl/glestranslator/EGL/EglGlobalInfo.cpp
@@ -68,7 +68,7 @@
}
EglGlobalInfo::EglGlobalInfo(bool nullEgl) {
-#ifdef ANDROID
+#if defined(ANDROID) || defined(__QNX__)
sEgl2Egl = true;
sEgl2EglSyncSafeToUse = true;
m_engine = EglOS::
diff --git a/host/meson.build b/host/meson.build
index a6b14c5..046fe31 100644
--- a/host/meson.build
+++ b/host/meson.build
@@ -75,6 +75,8 @@
files_lib_gfxstream_backend += files('NativeSubWindow_win32.cpp')
elif host_machine.system() == 'linux'
files_lib_gfxstream_backend += files('NativeSubWindow_x11.cpp')
+elif host_machine.system() == 'qnx'
+ files_lib_gfxstream_backend += files('NativeSubWindow_qnx.cpp')
endif
gfxstream_backend_cpp_args = [
@@ -84,13 +86,24 @@
'-DVK_GFXSTREAM_STRUCTURE_TYPE_EXT',
]
+deps_gfxstream_backend = [
+ aemu_common_dep,
+ aemu_base_dep,
+ aemu_logging_dep,
+ aemu_snapshot_dep,
+]
+
+if host_machine.system() == 'qnx'
+ deps_gfxstream_backend += qnx_screen_dep
+endif
+
gfxstream_backend = library(
'gfxstream_backend',
files_lib_gfxstream_backend,
cpp_args: default_cpp_args + gfxstream_backend_cpp_args,
include_directories: [inc_gfxstream_backend, inc_glm],
gnu_symbol_visibility: 'default',
- dependencies: [aemu_common_dep, aemu_base_dep, aemu_logging_dep, aemu_snapshot_dep],
+ dependencies: deps_gfxstream_backend,
link_with: link_gfxstream_backend,
version: '0.1.2',
install: true,
diff --git a/host/vulkan/meson.build b/host/vulkan/meson.build
index 4a03a60..00a2be3 100644
--- a/host/vulkan/meson.build
+++ b/host/vulkan/meson.build
@@ -46,6 +46,9 @@
vulkan_server_cpp_args += '-DVK_USE_PLATFORM_METAL_EXT'
elif host_machine.system() == 'windows'
vulkan_server_cpp_args += '-DVK_USE_PLATFORM_WIN32_KHR'
+elif host_machine.system() == 'qnx'
+## TODO: jsimonot: resolve vk header issue
+# vulkan_server_cpp_args += '-DVK_USE_PLATFORM_SCREEN_QNX'
endif
lib_vulkan_server = static_library(
diff --git a/meson.build b/meson.build
index 31a8753..a55d904 100644
--- a/meson.build
+++ b/meson.build
@@ -26,13 +26,54 @@
'-Wno-implicit-fallthrough',
]
+if host_machine.system() == 'qnx'
+ default_cpp_args += '-D_QNX_SOURCE'
+ qnx_target = get_option('qnx_target')
+ if qnx_target == ''
+ error('option qnx_target is not set')
+ endif
+endif
+
#===============#
# Dependencies #
#===============#
-aemu_base_dep = dependency('aemu_base')
-aemu_common_dep = dependency('aemu_host_common')
-aemu_logging_dep = dependency('aemu_logging')
-aemu_snapshot_dep = dependency('aemu_snapshot')
+if host_machine.system() == 'qnx'
+ ## have not yet got pkgconfig to work with cross-compile,
+ ## finding libraries manually in the meantime.
+
+ ## ERROR: Dependency "screen" not found, tried pkgconfig
+ # qnx_screen_dep = dependency('screen')
+
+ rel_path_prefix = meson.get_external_property('qnx_path_prefix')
+ abs_path_prefix = meson.current_source_dir() + '/' + rel_path_prefix
+
+ aemu_incl_path = rel_path_prefix + '/aemu/install/include'
+ aemu_libs_path = abs_path_prefix + '/aemu/install/lib'
+
+ incl_aemu_headers = include_directories(aemu_incl_path)
+
+ aemu_base_lib = cc.find_library('aemu-base', dirs: aemu_libs_path)
+ aemu_base_dep = declare_dependency(include_directories : incl_aemu_headers, dependencies : [aemu_base_lib])
+
+ aemu_common_lib = cc.find_library('aemu-host-common', dirs: aemu_libs_path)
+ aemu_common_dep = declare_dependency(include_directories : incl_aemu_headers, dependencies : [aemu_common_lib])
+
+ aemu_logging_lib = cc.find_library('logging-base', dirs: aemu_libs_path)
+ aemu_logging_dep = declare_dependency(include_directories : incl_aemu_headers, dependencies : [aemu_logging_lib])
+
+ aemu_snapshot_lib = cc.find_library('gfxstream-snapshot', dirs: aemu_libs_path)
+ aemu_snapshot_dep = declare_dependency(include_directories : incl_aemu_headers, dependencies : [aemu_snapshot_lib])
+
+ inc_qnx_headers = include_directories(join_paths(qnx_target, 'usr/include'))
+ qnx_screen_lib = cc.find_library('screen', required : true)
+ qnx_screen_dep = declare_dependency(include_directories: inc_qnx_headers, dependencies: [qnx_screen_lib])
+
+else
+ aemu_base_dep = dependency('aemu_base')
+ aemu_common_dep = dependency('aemu_host_common')
+ aemu_logging_dep = dependency('logging_base')
+ aemu_snapshot_dep = dependency('aemu_snapshot')
+endif
#========================#
# Logging + error report #
diff --git a/meson_options.txt b/meson_options.txt
index f5f6216..1a703b8 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -25,3 +25,5 @@
],
description : 'The logging level of gfxstream'
)
+
+option('qnx_target', type : 'string', value : '', description : 'QNX SDP target path')
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}