Add support for Android build to GN config

This commit is contained in:
Attila Uygun 2023-08-17 18:05:42 +02:00
parent 2ca0bb9b5b
commit 9ff2e51ff1
12 changed files with 272 additions and 59 deletions

View File

@ -1,4 +1,4 @@
group("kaliber") { group("all") {
deps = [ deps = [
"//src/demo", "//src/demo",
"//src/hello_world", "//src/hello_world",

View File

@ -6,7 +6,6 @@ copy("assets") {
"Boss_ok_lvl2.png", "Boss_ok_lvl2.png",
"Boss_ok_lvl3.png", "Boss_ok_lvl3.png",
"Boss_ok.png", "Boss_ok.png",
"BUILD.gn",
"chromatic_aberration.glsl_fragment", "chromatic_aberration.glsl_fragment",
"chromatic_aberration.glsl_vertex", "chromatic_aberration.glsl_vertex",
"enemy_anims_01_frames_ok.png", "enemy_anims_01_frames_ok.png",

View File

@ -54,9 +54,9 @@ config("default") {
# ] # ]
if (is_linux) { if (is_linux) {
# cflags += [ cflags += [
# "-fPIC", # Emit position-independent code suitable for dynamic linking. "-fPIC", # Emit position-independent code suitable for dynamic linking.
# ] ]
libs = [ libs = [
"pthread", # Use the POSIX thread library. "pthread", # Use the POSIX thread library.
] ]
@ -74,6 +74,12 @@ config("default") {
"-target", "-target",
"arm64-apple-macos11", "arm64-apple-macos11",
] ]
} else if (is_android) {
cflags += [
"--sysroot=$ndk/toolchains/llvm/prebuilt/$ndk_host/sysroot",
"-fPIC", # Emit position-independent code suitable for dynamic linking.
]
ldflags = [ "-static-libstdc++" ]
} }
} }
@ -82,6 +88,13 @@ config("default") {
# "//", # "//",
"//src", "//src",
] ]
if (is_android) {
include_dirs += [
"$ndk/sources/android",
"$ndk/sources/android/native_app_glue",
"$ndk/sources/android/cpufeatures",
]
}
} }
config("debug") { config("debug") {
@ -191,9 +204,11 @@ config("warnings") {
"/wd4191", # 'type cast': unsafe conversion "/wd4191", # 'type cast': unsafe conversion
"/wd4244", # conversion, possible loss of data. 'int' to 'float' "/wd4244", # conversion, possible loss of data. 'int' to 'float'
"/wd4245", # tmp:conversion from 'int' to 'const unsigned int' "/wd4245", # tmp:conversion from 'int' to 'const unsigned int'
# "/wd4267", # conversion, possible loss of data. # "/wd4267", # conversion, possible loss of data.
"/wd4305", # truncation from 'double' to 'float'. "/wd4305", # truncation from 'double' to 'float'.
"/wd4365", # conversion, signed/unsigned mismatch. "/wd4365", # conversion, signed/unsigned mismatch.
# "/wd5219", # conversion, possible loss of data. 'int' to 'float' # "/wd5219", # conversion, possible loss of data. 'int' to 'float'
"/wd4722", # destructor never returns, potential memory leak "/wd4722", # destructor never returns, potential memory leak
"/wd4702", # unreachable code "/wd4702", # unreachable code
@ -260,6 +275,7 @@ config("warnings") {
# Disable the following warnings: # Disable the following warnings:
"-Wno-unused-parameter", "-Wno-unused-parameter",
"-Wno-sign-compare",
] ]
} }
} }
@ -291,6 +307,34 @@ config("executable") {
} }
} }
config("shared_library") {
if (is_android) {
ldflags = [
"-Wl,--build-id=sha1",
"-Wl,--no-rosegment",
"-Wl,--fatal-warnings",
"-Wl,--no-undefined",
"-Qunused-arguments",
"-u ANativeActivity_onCreate",
]
} else if (is_linux) {
ldflags = [
"-Wl,-rpath,\$ORIGIN", # Add directory to runtime library search path.
]
} else if (is_mac) {
ldflags = [ "-Wl,-rpath,@loader_path/." ]
} else if (is_win) {
ldflags = [
"/DYNAMICBASE", # Use address space layout randomization.
"/INCREMENTAL:NO", # Incremental linking interferes with both ninja and
# release optimizations.
# Leave the target architecture to environment settings.
# "/MACHINE:X64",
]
}
}
# TODO: This needs some more investigation. # TODO: This needs some more investigation.
# Is it possible to avoid setting it and rely on defaults? # Is it possible to avoid setting it and rely on defaults?
# Some tools will be console apps while games will be gui apps. # Some tools will be console apps while games will be gui apps.

View File

@ -1,5 +1,14 @@
declare_args() { declare_args() {
is_debug = false is_debug = false
# Note that this uses the 'cc' and 'c++' links that should map to GCC on linux
# systems and clang on macs.
ar = "ar"
cc = "cc"
cxx = "c++"
ndk = ""
ndk_api = 24
} }
# Platform detection # Platform detection
@ -21,9 +30,6 @@ is_desktop = is_mac || is_linux || is_win
is_mobile = is_android || is_ios is_mobile = is_android || is_ios
is_unix = is_android || is_linux is_unix = is_android || is_linux
# Optional build components
have_vulkan = false
if (target_cpu == "") { if (target_cpu == "") {
if (is_mobile) { if (is_mobile) {
target_cpu = "arm64" target_cpu = "arm64"
@ -38,6 +44,42 @@ if (current_cpu == "") {
current_cpu = target_cpu current_cpu = target_cpu
} }
if (is_android) {
assert(ndk != "", "NDK path argument is empty")
ndk_host = ""
ndk_target = ""
if (host_os == "linux") {
ndk_host = "linux-x86_64"
} else if (host_os == "mac") {
ndk_host = "darwin-x86_64"
} else if (host_os == "win") {
ndk_host = "windows-x86_64"
}
if (target_cpu == "arm64") {
ndk_target = "aarch64-linux-android"
} else if (target_cpu == "arm") {
ndk_target = "armv7a-linux-androideabi"
} else if (target_cpu == "x64") {
ndk_target = "x86_64-linux-android"
} else if (target_cpu == "x86") {
ndk_target = "i686-linux-android"
}
_prefix = "$ndk/toolchains/llvm/prebuilt/$ndk_host/bin"
if (host_os == "win") {
ar = "$_prefix/llvm-ar.exe"
cc = "$_prefix/clang.exe --target=$ndk_target$ndk_api -fno-addrsig"
cxx = "$_prefix/clang++.exe --target=$ndk_target$ndk_api -fno-addrsig"
} else {
ar = "$_prefix/llvm-ar"
cc = "$_prefix/$ndk_target$ndk_api-clang"
cxx = "$_prefix/$ndk_target$ndk_api-clang++"
}
}
# Set defaults # Set defaults
_default_config = [ _default_config = [
"//build:default", "//build:default",

View File

@ -1,21 +1,21 @@
#!/usr/bin/env python #!/usr/bin/env python
import os import os
import shutil import shutil
import sys import sys
src, dst = sys.argv[1:] src, dst = sys.argv[1:]
if os.path.exists(dst): if os.path.exists(dst):
if os.path.isdir(dst): if os.path.isdir(dst):
shutil.rmtree(dst) shutil.rmtree(dst)
else: else:
os.remove(dst) os.remove(dst)
if os.path.isdir(src): if os.path.isdir(src):
shutil.copytree(src, dst) shutil.copytree(src, dst)
else: else:
shutil.copy2(src, dst) shutil.copy2(src, dst)
# https://github.com/ninja-build/ninja/issues/1554 # https://github.com/ninja-build/ninja/issues/1554
os.utime(dst, None) os.utime(dst, None)

View File

@ -1,16 +1,10 @@
# Note that this uses the 'cc' and 'c++' environment variables or links that
# should map to GCC on linux systems and clang on macs.
# This also means that you can install clang or another compiler and it should
# automatically use that instead.
toolchain("gcc") { toolchain("gcc") {
lib_switch = "-l" lib_switch = "-l"
lib_dir_switch = "-L" lib_dir_switch = "-L"
tool("asm") { tool("asm") {
depfile = "{{output}}.d" depfile = "{{output}}.d"
command = "cc -MD -MF $depfile {{defines}} {{include_dirs}} {{asmflags}} -c {{source}} -o {{output}}" command = "$cc -MD -MF $depfile {{defines}} {{include_dirs}} {{asmflags}} -c {{source}} -o {{output}}"
depsformat = "gcc" depsformat = "gcc"
outputs = outputs =
[ "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o" ] [ "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o" ]
@ -19,7 +13,7 @@ toolchain("gcc") {
tool("cc") { tool("cc") {
depfile = "{{output}}.d" depfile = "{{output}}.d"
command = "cc -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_c}} -c {{source}} -o {{output}}" command = "$cc -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_c}} -c {{source}} -o {{output}}"
depsformat = "gcc" depsformat = "gcc"
outputs = outputs =
[ "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o" ] [ "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o" ]
@ -28,7 +22,7 @@ toolchain("gcc") {
tool("cxx") { tool("cxx") {
depfile = "{{output}}.d" depfile = "{{output}}.d"
command = "c++ -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_cc}} -c {{source}} -o {{output}}" command = "$cxx -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_cc}} -c {{source}} -o {{output}}"
depsformat = "gcc" depsformat = "gcc"
outputs = outputs =
[ "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o" ] [ "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o" ]
@ -37,7 +31,7 @@ toolchain("gcc") {
tool("objc") { tool("objc") {
depfile = "{{output}}.d" depfile = "{{output}}.d"
command = "cc -MMD -MF $depfile {{defines}} {{include_dirs}} {{framework_dirs}} {{cflags}} {{cflags_c}} {{cflags_objc}} -c {{source}} -o {{output}}" command = "$cc -MMD -MF $depfile {{defines}} {{include_dirs}} {{framework_dirs}} {{cflags}} {{cflags_c}} {{cflags_objc}} -c {{source}} -o {{output}}"
depsformat = "gcc" depsformat = "gcc"
outputs = outputs =
[ "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o" ] [ "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o" ]
@ -46,7 +40,7 @@ toolchain("gcc") {
tool("objcxx") { tool("objcxx") {
depfile = "{{output}}.d" depfile = "{{output}}.d"
command = "c++ -MMD -MF $depfile {{defines}} {{include_dirs}} {{framework_dirs}} {{cflags}} {{cflags_cc}} {{cflags_objcc}} -c {{source}} -o {{output}}" command = "$cxx -MMD -MF $depfile {{defines}} {{include_dirs}} {{framework_dirs}} {{cflags}} {{cflags_cc}} {{cflags_objcc}} -c {{source}} -o {{output}}"
depsformat = "gcc" depsformat = "gcc"
outputs = outputs =
[ "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o" ] [ "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o" ]
@ -62,7 +56,7 @@ toolchain("gcc") {
command = command =
"libtool -static -o {{output}} -no_warning_for_no_symbols {{inputs}}" "libtool -static -o {{output}} -no_warning_for_no_symbols {{inputs}}"
} else { } else {
command = "rm -f {{output}} && ar rcs {{output}} {{inputs}}" command = "rm -f {{output}} && $ar rcs {{output}} {{inputs}}"
} }
outputs = outputs =
[ "{{target_out_dir}}/{{target_output_name}}{{output_extension}}" ] [ "{{target_out_dir}}/{{target_output_name}}{{output_extension}}" ]
@ -82,7 +76,7 @@ toolchain("gcc") {
os_specific_option = "-Wl,-soname=$soname" os_specific_option = "-Wl,-soname=$soname"
rspfile_content = "-Wl,--whole-archive {{inputs}} {{solibs}} -Wl,--no-whole-archive {{libs}}" rspfile_content = "-Wl,--whole-archive {{inputs}} {{solibs}} -Wl,--no-whole-archive {{libs}}"
} }
command = "c++ -shared {{ldflags}} {{frameworks}} -o $sofile $os_specific_option @$rspfile" command = "$cxx -shared {{ldflags}} {{frameworks}} -o $sofile $os_specific_option @$rspfile"
default_output_extension = ".so" default_output_extension = ".so"
default_output_dir = "{{root_out_dir}}" default_output_dir = "{{root_out_dir}}"
outputs = [ sofile ] outputs = [ sofile ]
@ -97,22 +91,40 @@ toolchain("gcc") {
rspfile = "$outfile.rsp" rspfile = "$outfile.rsp"
rspfile_content = "{{inputs}}" rspfile_content = "{{inputs}}"
if (is_apple) { if (is_apple) {
command = "c++ {{ldflags}} {{solibs}} {{libs}} {{frameworks}} -o $outfile @$rspfile" command = "$cxx {{ldflags}} {{solibs}} {{libs}} {{frameworks}} -o $outfile @$rspfile"
} else { } else {
command = "c++ {{ldflags}} -o $outfile -Wl,--start-group @$rspfile {{solibs}} -Wl,--end-group {{libs}}" command = "$cxx {{ldflags}} -o $outfile -Wl,--start-group @$rspfile {{solibs}} -Wl,--end-group {{libs}}"
} }
default_output_dir = "{{root_out_dir}}" default_output_dir = "{{root_out_dir}}"
outputs = [ outfile ] outputs = [ outfile ]
description = "link $outfile" description = "link $outfile"
} }
tool("stamp") { if (host_os == "win") {
command = "touch {{output}}" tool("stamp") {
description = "stamp {{output}}" command = "cmd.exe /c echo > {{output}}"
} description = "stamp {{output}}"
}
tool("copy") { tool("copy") {
command = "cp -af {{source}} {{output}}" # Note: The build in copy command can't handle forward slashes as path separators.
description = "copy {{source}} {{output}}" # Use a python script as a work around.
# command = "cmd.exe /c copy /Y {{source}} {{output}}"
copy_cmd = rebase_path("../copy.py")
command = "python \"$copy_cmd\" {{source}} {{output}}"
description = "copy {{source}} {{output}}"
}
} else {
tool("stamp") {
command = "touch {{output}}"
description = "stamp {{output}}"
}
tool("copy") {
command = "cp -af {{source}} {{output}}"
description = "copy {{source}} {{output}}"
}
} }
} }

View File

@ -82,7 +82,7 @@ toolchain("msvc") {
# Use a python script as a work around. # Use a python script as a work around.
# command = "cmd.exe /c copy /Y {{source}} {{output}}" # command = "cmd.exe /c copy /Y {{source}} {{output}}"
copy_cmd = rebase_path("copy.py") copy_cmd = rebase_path("../copy.py")
command = "python \"$copy_cmd\" {{source}} {{output}}" command = "python \"$copy_cmd\" {{source}} {{output}}"
description = "copy {{source}} {{output}}" description = "copy {{source}} {{output}}"

11
build/utils.gni Normal file
View File

@ -0,0 +1,11 @@
# Build a shared library for Android. Build an executable for other platforms.
template("game_tmpl") {
if (target_os == "android") {
_target_type = "shared_library"
} else {
_target_type = "executable"
}
target(_target_type, target_name) {
forward_variables_from(invoker, "*")
}
}

View File

@ -1,4 +1,6 @@
executable("demo") { import("//build/utils.gni")
game_tmpl("demo") {
sources = [ sources = [
"credits.cc", "credits.cc",
"credits.h", "credits.h",
@ -16,7 +18,6 @@ executable("demo") {
"sky_quad.cc", "sky_quad.cc",
"sky_quad.h", "sky_quad.h",
] ]
deps = [ deps = [
"//assets", "//assets",
"//src/base", "//src/base",

View File

@ -98,6 +98,26 @@ source_set("engine") {
] ]
} }
if (target_os == "android") {
sources += [
"audio/audio_sink_oboe.cc",
"audio/audio_sink_oboe.h",
"platform/asset_file_android.cc",
"platform/platform_android.cc",
"renderer/opengl/renderer_opengl_android.cc",
"renderer/vulkan/renderer_vulkan_android.cc",
"renderer/vulkan/vulkan_context_android.cc",
]
libs += [
"android",
"EGL",
"GLESv2",
"log",
"z",
]
}
deps = [ deps = [
"//assets/engine", "//assets/engine",
"//src/base", "//src/base",

View File

@ -1,6 +1,7 @@
executable("hello_world") { import("//build/utils.gni")
sources = [ "hello_world.cc" ]
game_tmpl("hello_world") {
sources = [ "hello_world.cc" ]
deps = [ deps = [
"//src/base", "//src/base",
"//src/engine", "//src/engine",

View File

@ -6,10 +6,11 @@ config("third_party_config") {
if (target_os == "linux") { if (target_os == "linux") {
defines = [ "VK_USE_PLATFORM_XLIB_KHR" ] defines = [ "VK_USE_PLATFORM_XLIB_KHR" ]
} } else if (target_os == "win") {
if (target_os == "win") {
defines = [ "VK_USE_PLATFORM_WIN32_KHR" ] defines = [ "VK_USE_PLATFORM_WIN32_KHR" ]
} else if (target_os == "android") {
defines = [ "VK_USE_PLATFORM_ANDROID_KHR" ]
include_dirs += [ "oboe/include" ]
} }
} }
@ -111,6 +112,88 @@ source_set("third_party") {
] ]
} }
if (target_os == "android") {
sources += [
"$ndk/sources/android/cpufeatures/cpu-features.c",
"$ndk/sources/android/native_app_glue/android_native_app_glue.c",
"android/GLContext.cpp",
"android/gl3stub.c",
"glslang/glslang/OSDependent/Unix/ossource.cpp",
"minizip/ioapi.c",
"minizip/unzip.c",
"oboe/src/aaudio/AAudioLoader.cpp",
"oboe/src/aaudio/AudioStreamAAudio.cpp",
"oboe/src/common/AudioSourceCaller.cpp",
"oboe/src/common/AudioStream.cpp",
"oboe/src/common/AudioStreamBuilder.cpp",
"oboe/src/common/DataConversionFlowGraph.cpp",
"oboe/src/common/FilterAudioStream.cpp",
"oboe/src/common/FixedBlockAdapter.cpp",
"oboe/src/common/FixedBlockReader.cpp",
"oboe/src/common/FixedBlockWriter.cpp",
"oboe/src/common/LatencyTuner.cpp",
"oboe/src/common/OboeExtensions.cpp",
"oboe/src/common/QuirksManager.cpp",
"oboe/src/common/SourceFloatCaller.cpp",
"oboe/src/common/SourceI16Caller.cpp",
"oboe/src/common/SourceI24Caller.cpp",
"oboe/src/common/SourceI32Caller.cpp",
"oboe/src/common/StabilizedCallback.cpp",
"oboe/src/common/Trace.cpp",
"oboe/src/common/Utilities.cpp",
"oboe/src/common/Version.cpp",
"oboe/src/fifo/FifoBuffer.cpp",
"oboe/src/fifo/FifoController.cpp",
"oboe/src/fifo/FifoControllerBase.cpp",
"oboe/src/fifo/FifoControllerIndirect.cpp",
"oboe/src/flowgraph/ChannelCountConverter.cpp",
"oboe/src/flowgraph/ClipToRange.cpp",
"oboe/src/flowgraph/FlowGraphNode.cpp",
"oboe/src/flowgraph/ManyToMultiConverter.cpp",
"oboe/src/flowgraph/MonoBlend.cpp",
"oboe/src/flowgraph/MonoToMultiConverter.cpp",
"oboe/src/flowgraph/MultiToManyConverter.cpp",
"oboe/src/flowgraph/MultiToMonoConverter.cpp",
"oboe/src/flowgraph/RampLinear.cpp",
"oboe/src/flowgraph/SampleRateConverter.cpp",
"oboe/src/flowgraph/SinkFloat.cpp",
"oboe/src/flowgraph/SinkI16.cpp",
"oboe/src/flowgraph/SinkI24.cpp",
"oboe/src/flowgraph/SinkI32.cpp",
"oboe/src/flowgraph/SourceFloat.cpp",
"oboe/src/flowgraph/SourceI16.cpp",
"oboe/src/flowgraph/SourceI24.cpp",
"oboe/src/flowgraph/SourceI32.cpp",
"oboe/src/flowgraph/resampler/IntegerRatio.cpp",
"oboe/src/flowgraph/resampler/LinearResampler.cpp",
"oboe/src/flowgraph/resampler/MultiChannelResampler.cpp",
"oboe/src/flowgraph/resampler/PolyphaseResampler.cpp",
"oboe/src/flowgraph/resampler/PolyphaseResamplerMono.cpp",
"oboe/src/flowgraph/resampler/PolyphaseResamplerStereo.cpp",
"oboe/src/flowgraph/resampler/SincResampler.cpp",
"oboe/src/flowgraph/resampler/SincResamplerStereo.cpp",
"oboe/src/opensles/AudioInputStreamOpenSLES.cpp",
"oboe/src/opensles/AudioOutputStreamOpenSLES.cpp",
"oboe/src/opensles/AudioStreamBuffered.cpp",
"oboe/src/opensles/AudioStreamOpenSLES.cpp",
"oboe/src/opensles/EngineOpenSLES.cpp",
"oboe/src/opensles/OpenSLESUtilities.cpp",
"oboe/src/opensles/OutputMixerOpenSLES.cpp",
]
if (target_cpu == "arm" || target_cpu == "arm64") {
sources += [
"texture_compressor/dxt_encoder_neon.cc",
"texture_compressor/texture_compressor_etc1_neon.cc",
]
}
cflags += [
"-Wno-nullability-completeness",
"-Wno-deprecated-enum-enum-conversion",
]
include_dirs = [ "oboe/src" ]
libs = [ "OpenSLES" ]
}
configs -= [ "//build:warnings" ] configs -= [ "//build:warnings" ]
deps = [] deps = []