Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update NDK 25 LTS (r25b) #7240

Merged
merged 22 commits into from Jan 16, 2023
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 7 additions & 0 deletions .gitignore
Expand Up @@ -5,6 +5,9 @@
.lock-waf*
/share/ext/build
/share/ext/download
/share/ext/tremolo/tmp/
/share/ext/protobuf/tmp/
/share/ext/protobuf/cross_tmp/
/share/extender/build
/go/pkg
/go/bin
Expand Down Expand Up @@ -50,3 +53,7 @@ external/**/build/
editor/resources/splash.css
editor/.calva/output-window/output.calva-repl
editor/.lsp/sqlite.db

#build_external
/packages/bullet-2.77/
/packages/lib/
2 changes: 1 addition & 1 deletion build_tools/sdk.py
Expand Up @@ -58,7 +58,7 @@
## **********************************************************************************************
# Android

ANDROID_NDK_VERSION='20'
ANDROID_NDK_VERSION='25b'

## **********************************************************************************************
# Win32
Expand Down
17 changes: 6 additions & 11 deletions build_tools/waf_dynamo.py
Expand Up @@ -81,11 +81,10 @@ def transform_runnable_path(platform, path):

ANDROID_ROOT=SDK_ROOT
ANDROID_BUILD_TOOLS_VERSION = '32.0.0'
ANDROID_NDK_API_VERSION='16' # Android 4.1
ANDROID_NDK_API_VERSION='19' # Android 4.4
ANDROID_NDK_ROOT=os.path.join(SDK_ROOT,'android-ndk-r%s' % sdk.ANDROID_NDK_VERSION)
ANDROID_TARGET_API_LEVEL='31' # Android 12.0
ANDROID_MIN_API_LEVEL='16'
ANDROID_GCC_VERSION='4.9'
ANDROID_MIN_API_LEVEL='19'
ANDROID_64_NDK_API_VERSION='21' # Android 5.0
EMSCRIPTEN_ROOT=os.environ.get('EMSCRIPTEN', '')

Expand Down Expand Up @@ -246,9 +245,6 @@ def getAndroidNDKArch(target_arch):
def getAndroidArch(target_arch):
return 'arm64-v8a' if 'arm64' == target_arch else 'armeabi-v7a'

def getAndroidBuildtoolName(target_arch):
return 'aarch64-linux-android' if 'arm64' == target_arch else 'arm-linux-androideabi'

def getAndroidCompilerName(target_arch, api_version):
if target_arch == 'arm64':
return 'aarch64-linux-android%s-clang' % (api_version)
Expand Down Expand Up @@ -872,8 +868,7 @@ def _strip_executable(bld, platform, target_arch, path):
if 'android' in platform:
HOME = os.environ['USERPROFILE' if sys.platform == 'win32' else 'HOME']
ANDROID_HOST = 'linux' if sys.platform == 'linux' else 'darwin'
build_tool = getAndroidBuildtoolName(target_arch)
strip = "%s/toolchains/%s-%s/prebuilt/%s-x86_64/bin/%s-strip" % (ANDROID_NDK_ROOT, build_tool, ANDROID_GCC_VERSION, ANDROID_HOST, build_tool)
strip = "%s/toolchains/llvm/prebuilt/%s-x86_64/bin/llvm-strip" % (ANDROID_NDK_ROOT, ANDROID_HOST)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the 64 bit stripnowwork on armv7` executables?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't find docs for it (it's always isn't so easy) but I tested it and it works


return bld.exec_command("%s %s" % (strip, path))

Expand Down Expand Up @@ -1517,7 +1512,7 @@ def detect(conf):
conf.env['CPP'] = '%s/clang -E' % bin_dir
conf.env['AR'] = '%s/ar' % bin_dir
conf.env['RANLIB'] = '%s/ranlib' % bin_dir
conf.env['LD'] = '%s/ld' % bin_dir
conf.env['LD'] = '%s/lld' % bin_dir

conf.env['GCC-OBJCXX'] = '-xobjective-c++'
conf.env['GCC-OBJCLINK'] = '-lobjc'
Expand All @@ -1529,18 +1524,18 @@ def detect(conf):
if bp_os == 'macos':
bp_os = 'darwin' # the toolset is still called darwin
target_arch = build_util.get_target_architecture()
tool_name = getAndroidBuildtoolName(target_arch)
api_version = getAndroidNDKAPIVersion(target_arch)
clang_name = getAndroidCompilerName(target_arch, api_version)
bintools = '%s/toolchains/llvm/prebuilt/%s-%s/bin' % (ANDROID_NDK_ROOT, bp_os, bp_arch)
tool_name = "llvm"

conf.env['CC'] = '%s/%s' % (bintools, clang_name)
conf.env['CXX'] = '%s/%s++' % (bintools, clang_name)
conf.env['LINK_CXX'] = '%s/%s++' % (bintools, clang_name)
conf.env['CPP'] = '%s/%s -E' % (bintools, clang_name)
conf.env['AR'] = '%s/%s-ar' % (bintools, tool_name)
conf.env['RANLIB'] = '%s/%s-ranlib' % (bintools, tool_name)
conf.env['LD'] = '%s/%s-ld' % (bintools, tool_name)
conf.env['LD'] = '%s/lld' % (bintools)
conf.env['DX'] = '%s/android-sdk/build-tools/%s/dx' % (ANDROID_ROOT, ANDROID_BUILD_TOOLS_VERSION)

elif 'linux' == build_util.get_target_os():
Expand Down
58 changes: 4 additions & 54 deletions build_tools/waf_package.py
Expand Up @@ -13,20 +13,15 @@
# CONDITIONS OF ANY KIND, either express or implied. See the License for the
# specific language governing permissions and limitations under the License.



import os
import glob
import run
import Constants
import Environment
import Node
import Utils
from waflib import ConfigSet
from waflib import Build

def load_build_context(directory):
cachedir = os.path.join(directory,Constants.CACHE_DIR)
return Environment.Environment(os.path.join(cachedir,'default.cache.py'))

cachedir = os.path.join(directory,Build.CACHE_DIR)
return ConfigSet.ConfigSet(os.path.join(cachedir,'_cache.py'))

def glob_files(patterns, cwd=None):
oldcwd=os.getcwd()
Expand All @@ -41,51 +36,6 @@ def glob_files(patterns, cwd=None):
os.chdir(oldcwd)
return out

# Original from wafadmin/Build.py install_files:
# I couldn't get the original code to work as I needed, so I made a small change to it.
def package_install_files(self, path, files, env=None, chmod=Constants.O644, relative_trick=False, cwd=None):
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

new waf doesn't have this function
it is possible to implement it using default waf functionality

if env:
assert isinstance(env,Environment.Environment),"invalid parameter"
else:
env=self.env
if not path:return[]
if not cwd:
cwd=self.path
if isinstance(files,str)and'*'in files:
gl=cwd.abspath()+os.sep+files
lst=glob.glob(gl)
else:
lst=Utils.to_list(files)
destpath=self.get_install_path(path,env)
Utils.check_dir(destpath)
installed_files=[]
for filename in lst:
if isinstance(filename,str)and os.path.isabs(filename):
alst=Utils.split_path(filename)
destfile=os.path.join(destpath,alst[-1])
else:
if isinstance(filename,Node.Node):
nd=filename
else:
# DEFOLD: This is the fix to make the relative paths work our way
fullpath=os.path.join(self.path.abspath(),filename)
filename=os.path.relpath(fullpath,cwd.abspath())
# DEFOLD: <- end fix
nd=cwd.find_resource(filename)
if not nd:
raise Utils.WafError("Unable to install the file %r (not found in %s)"%(filename,cwd))
if relative_trick:
destfile=os.path.join(destpath,filename)
Utils.check_dir(os.path.dirname(destfile))
else:
destfile=os.path.join(destpath,nd.name)
filename=nd.abspath(env)
if self.do_install(filename,destfile,chmod):
installed_files.append(destfile)
return installed_files


def create_tar(files, cwd, target):
cmd = 'tar zcf %s %s' % (target, ' '.join(files))
run.command(cmd.split(), cwd=cwd)

2 changes: 1 addition & 1 deletion editor/resources/meta.edn
Expand Up @@ -642,7 +642,7 @@
:path ["android" "version_code"]}
{:type :integer,
:help "minimum API Level required for the application to run (android:minSdkVersion)",
:default 16,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minimum android version increased to 19

:default 19,
:path ["android" "minimum_sdk_version"]}
{:type :integer,
:help "the API Level that the application targets (android:targetSdkVersion)",
Expand Down
172 changes: 172 additions & 0 deletions engine/crash/src/backtrace_libunwind_ndk.cpp
@@ -0,0 +1,172 @@
// Copyright 2020-2022 The Defold Foundation
// Copyright 2014-2020 King
// Copyright 2009-2014 Ragnar Svensson, Christian Murray
// Licensed under the Defold License version 1.0 (the "License"); you may not use
// this file except in compliance with the License.
//
// You may obtain a copy of the License, together with FAQs at
// https://www.defold.com/license
//
// 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 <assert.h>
#include <dlib/log.h>
#include <dlib/dlib.h>
#include <signal.h>
#include <stdio.h>
#include <unwind.h>
#include <dlfcn.h>
#include "crash.h"
#include "crash_private.h"

namespace dmCrash
{
static const int SIGNAL_MAX = 64;

static bool g_CrashDumpEnabled = true;
static FCallstackExtraInfoCallback g_CrashExtraInfoCallback = 0;
static void* g_CrashExtraInfoCallbackCtx = 0;

struct unwind_data {
uint32_t offset_extra;
uint32_t stack_index;
};

void EnableHandler(bool enable)
{
g_CrashDumpEnabled = enable;
}

void HandlerSetExtraInfoCallback(FCallstackExtraInfoCallback cbk, void* ctx)
{
g_CrashExtraInfoCallback = cbk;
g_CrashExtraInfoCallbackCtx = ctx;
}

_Unwind_Reason_Code OnFrameEnter(struct _Unwind_Context *context, void *data)
{
unwind_data * unwindData = (unwind_data *) data;
const uintptr_t pc = _Unwind_GetIP(context);
if (pc)
{
g_AppState.m_Ptr[g_AppState.m_PtrCount] = (void*)(uintptr_t)pc;
g_AppState.m_PtrCount++;
Dl_info dl_info;
int result = dladdr((void *) pc, &dl_info);
if (result) {
const char* proc_path = dl_info.dli_fname;
bool proc_path_truncated = false;
if (proc_path) {
int proc_path_len = strlen(proc_path);
if (proc_path_len > 32) {
proc_path = proc_path + (proc_path_len-32);
proc_path_truncated = true;
}
}
char extra[256];
snprintf(extra, sizeof(extra),
"#%02d pc %012p %s%s %s+%u",
unwindData->stack_index++,
(void*)((uintptr_t)pc - (intptr_t) dl_info.dli_fbase),
proc_path_truncated ? "..." : "",
proc_path ? proc_path : "",
dl_info.dli_sname ? dl_info.dli_sname : "<unknown>",
dl_info.dli_saddr != NULL ? (void*)((intptr_t) pc - (intptr_t) dl_info.dli_saddr) : 0);

int extra_len = strlen(extra);
if ((unwindData->offset_extra + extra_len) < (dmCrash::AppState::EXTRA_MAX - 1))
{
memcpy(g_AppState.m_Extra + unwindData->offset_extra, extra, extra_len);
g_AppState.m_Extra[unwindData->offset_extra + extra_len] = '\n';
unwindData->offset_extra += extra_len + 1;
}
else
{
dmLogWarning("Not enough space to write entire stacktrace!");
}
}
}
return g_AppState.m_PtrCount >= AppState::PTRS_MAX ? _URC_END_OF_STACK : _URC_NO_REASON;
}

static void ResetToDefaultHandler(const int signum)
{
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sigemptyset(&sa.sa_mask);
sa.sa_handler = SIG_DFL;
sa.sa_flags = 0;
sigaction(signum, &sa, NULL);
}

static void Handler(const int signo, siginfo_t* const si, void *const sc)
{
if (!g_CrashDumpEnabled)
return;

g_AppState.m_Signum = signo;
g_AppState.m_PtrCount = 0;

// The default behavior is restored for the signal.
// Unless this is done first thing in the signal handler we'll
// be stuck in a signal-handler loop forever.
ResetToDefaultHandler(signo);

unwind_data unwindData;
unwindData.offset_extra = 0;
unwindData.stack_index = 0;
_Unwind_Backtrace(OnFrameEnter, &unwindData);

if (g_CrashExtraInfoCallback)
{
int extra_len = strlen(g_AppState.m_Extra);
g_CrashExtraInfoCallback(g_CrashExtraInfoCallbackCtx, g_AppState.m_Extra + extra_len, dmCrash::AppState::EXTRA_MAX - extra_len - 1);
}

WriteCrash(g_FilePath, &g_AppState);

bool is_debug_mode = dLib::IsDebugMode();
dLib::SetDebugMode(true);
dmLogError("CALL STACK:\n\n%s\n", g_AppState.m_Extra);
dLib::SetDebugMode(is_debug_mode);
}

void WriteDump()
{
siginfo_t empty;
Handler(0xDEAD, &empty, 0);
}

void InstallOnSignal(int signum)
{
assert(signum >= 0 && signum < SIGNAL_MAX);

struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sigemptyset(&sa.sa_mask);
sa.sa_sigaction = Handler;
sa.sa_flags = SA_SIGINFO;

sigaction(signum, &sa, NULL);
}

void SetCrashFilename(const char*)
{
}

void PlatformPurge()
{
}

void InstallHandler()
{
InstallOnSignal(SIGSEGV);
InstallOnSignal(SIGBUS);
InstallOnSignal(SIGTRAP);
InstallOnSignal(SIGILL);
InstallOnSignal(SIGABRT);
}
}
2 changes: 1 addition & 1 deletion engine/crash/src/wscript
Expand Up @@ -20,7 +20,7 @@ def build(bld):
target = 'crashext_null')

if 'android' in bld.env['PLATFORM']:
sig_handler = 'backtrace_libunwind.cpp'
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New backtrace unwinder implemented for Android. It uses clang libunwind

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ANd, now we have two files using the libunwind library.
I think you need to rename one.

Note that "lib" is implicit for library names. I.e. "libunwind" == "the unwind library"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we use libunwind from NDK on Android and modified libunwind from Google for macos (because it's a bit better and can get symbols from DWARF).
What do you think is the best name backtrace_libunwind_ndk.cpp?

sig_handler = 'backtrace_libunwind_ndk.cpp'
load_addrs = 'load_addrs_proc_smap.cpp'
file_handler = 'file_posix.cpp'
elif 'linux' in bld.env['PLATFORM']:
Expand Down