mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 03:51:18 +00:00
Improve android support & add CI (#2664)
* Change context destruction order. * enable emulated tls on termux * Fix stdlib on android * Add a CI workflow for android termux * update release notes * use the new unified CI tests on android --------- Co-authored-by: Christoffer Lerno <christoffer@aegik.com>
This commit is contained in:
75
.github/workflows/main.yml
vendored
75
.github/workflows/main.yml
vendored
@@ -352,9 +352,74 @@ jobs:
|
||||
if [[ ${{ matrix.build_type }} = "Debug" ]]; then CHECK_NAME=".#c3c-debug-checks"; fi
|
||||
nix build -L "$CHECK_NAME"
|
||||
|
||||
build-android:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
build_type: [ Release, Debug ]
|
||||
architecture: [ aarch64, x86_64 ]
|
||||
include:
|
||||
- architecture: aarch64
|
||||
runner: ubuntu-24.04-arm
|
||||
- architecture: x86_64
|
||||
runner: ubuntu-24.04
|
||||
runs-on: ${{matrix.runner}}
|
||||
container:
|
||||
image: termux/termux-docker:${{matrix.architecture}}
|
||||
volumes:
|
||||
- /tmp/node20:/__e/node20
|
||||
env:
|
||||
TERMUX_MAIN_PACKAGE_FORMAT: debian
|
||||
ANDROID_ROOT: /system
|
||||
ANDROID_DATA: /data
|
||||
PREFIX: /data/data/com.termux/files/usr
|
||||
HOME: /data/data/com.termux/files/home
|
||||
PATH: /data/data/com.termux/files/usr/bin
|
||||
TMPDIR: /data/data/com.termux/files/usr/tmp
|
||||
LANG: en_US.UTF-8
|
||||
TZ: UTC
|
||||
steps:
|
||||
- name: prepare termux
|
||||
run: |
|
||||
ln -sf ${PREFIX}/etc/termux/mirrors/default ${PREFIX}/etc/termux/chosen_mirrors
|
||||
/entrypoint.sh pkg update
|
||||
/entrypoint.sh bash -c "yes | pkg upgrade -y"
|
||||
chmod -R o+x ${PREFIX}/bin
|
||||
/entrypoint.sh pkg install -y nodejs-lts
|
||||
ln -sf ${PREFIX}/bin /__e/node20/bin
|
||||
- uses: actions/checkout@v4.2.2
|
||||
- name: fix permissions after checkout (checkout runs as root and entrypoint.sh switches to user 1000)
|
||||
run: chown -R 1000:1000 .
|
||||
|
||||
- name: setup
|
||||
run: /entrypoint.sh pkg install -y llvm binutils libgc build-essential cmake git libedit zlib clang make mlir llvm-tools libpolly python libllvm-static
|
||||
- name: build
|
||||
run: |
|
||||
cmake -Bbuild -DCMAKE_BUILD_TYPE=${{matrix.build_type}}
|
||||
cmake --build build
|
||||
|
||||
- name: Run Unified Tests
|
||||
run: ./scripts/tools/ci_tests.sh "./build/c3c" "android"
|
||||
|
||||
- name: bundle_output
|
||||
run: |
|
||||
mkdir c3
|
||||
cp -r lib c3
|
||||
cp msvc_build_libraries.py c3
|
||||
cp build/c3c c3
|
||||
cp README.md c3
|
||||
cp releasenotes.md c3
|
||||
tar czf c3-android-${{matrix.architecture}}-${{matrix.build_type}}.tar.gz c3
|
||||
|
||||
- name: upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: c3-android-${{matrix.architecture}}-${{matrix.build_type}}
|
||||
path: c3-android-${{matrix.architecture}}-${{matrix.build_type}}.tar.gz
|
||||
|
||||
release:
|
||||
runs-on: ubuntu-22.04
|
||||
needs: [build-msvc, build-linux, build-mac, build-linux-alpine, build-openbsd, build-netbsd]
|
||||
needs: [build-msvc, build-linux, build-mac, build-linux-alpine, build-openbsd, build-netbsd, build-android]
|
||||
if: github.ref == 'refs/heads/master'
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -372,6 +437,8 @@ jobs:
|
||||
mv c3-linux-musl-Release/c3-linux-musl-Release.tar.gz c3-linux-musl.tar.gz
|
||||
mv c3-openbsd-Release/c3-openbsd-Release.tar.gz c3-openbsd.tar.gz || true
|
||||
mv c3-netbsd-Release/c3-netbsd-Release.tar.gz c3-netbsd.tar.gz || true
|
||||
mv c3-android-aarch64-Release/c3-android-aarch64-Release.tar.gz c3-android-aarch64.tar.gz
|
||||
mv c3-android-x86_64-Release/c3-android-x86_64-Release.tar.gz c3-android-x86_64.tar.gz
|
||||
|
||||
# --- Debug Assets ---
|
||||
mv c3-windows-Debug/c3-windows-Debug.zip c3-windows-debug.zip
|
||||
@@ -381,6 +448,8 @@ jobs:
|
||||
mv c3-linux-musl-Debug/c3-linux-musl-Debug.tar.gz c3-linux-musl-debug.tar.gz
|
||||
mv c3-openbsd-Debug/c3-openbsd-Debug.tar.gz c3-openbsd-debug.tar.gz || true
|
||||
mv c3-netbsd-Debug/c3-netbsd-Debug.tar.gz c3-netbsd-debug.tar.gz || true
|
||||
mv c3-android-aarch64-Debug/c3-android-aarch64-Debug.tar.gz c3-android-aarch64-debug.tar.gz
|
||||
mv c3-android-x86_64-Debug/c3-android-x86_64-Debug.tar.gz c3-android-x86_64-debug.tar.gz
|
||||
|
||||
- run: gh release delete latest-prerelease-tag --cleanup-tag -y || true
|
||||
- run: echo "RELEASE_NAME=latest-prerelease-$(date +'%Y%m%d-%H%M')" >> $GITHUB_ENV
|
||||
@@ -397,6 +466,8 @@ jobs:
|
||||
c3-linux-musl.tar.gz
|
||||
c3-openbsd.tar.gz
|
||||
c3-netbsd.tar.gz
|
||||
c3-android-aarch64.tar.gz
|
||||
c3-android-x86_64.tar.gz
|
||||
# --- Debug Artifacts ---
|
||||
c3-windows-debug.zip
|
||||
c3-macos-debug.zip
|
||||
@@ -404,3 +475,5 @@ jobs:
|
||||
c3-linux-musl-debug.tar.gz
|
||||
c3-openbsd-debug.tar.gz
|
||||
c3-netbsd-debug.tar.gz
|
||||
c3-android-aarch64-debug.tar.gz
|
||||
c3-android-x86_64-debug.tar.gz
|
||||
|
||||
@@ -22,18 +22,20 @@ alias Pid_t = int;
|
||||
alias Uid_t = uint;
|
||||
alias Gid_t = uint;
|
||||
|
||||
const CUInt SA_ONSTACK = env::LINUX ? 0x08000000 : 0x0001;
|
||||
const CUInt SA_RESTART = env::LINUX ? 0x10000000 : 0x0002;
|
||||
const CUInt SA_RESETHAND = env::LINUX ? 0x80000000 : 0x0004;
|
||||
const CUInt SA_SIGINFO = env::LINUX ? 0x00000004 : 0x0040;
|
||||
const CUInt SA_ONSTACK = env::LINUX || env::ANDROID ? 0x08000000 : 0x0001;
|
||||
const CUInt SA_RESTART = env::LINUX || env::ANDROID ? 0x10000000 : 0x0002;
|
||||
const CUInt SA_RESETHAND = env::LINUX || env::ANDROID ? 0x80000000 : 0x0004;
|
||||
const CUInt SA_SIGINFO = env::LINUX || env::ANDROID ? 0x00000004 : 0x0040;
|
||||
|
||||
alias Sigset_t @if((env::DARWIN || env::BSD_FAMILY) && !env::NETBSD) = uint;
|
||||
alias Sigset_t @if(env::NETBSD) = uint[4];
|
||||
alias Sigset_t @if(env::LINUX) = ulong[16];
|
||||
alias Sigset_t @if(env::ANDROID) = ulong;
|
||||
alias SigActionFunction = fn void(CInt, void*, void*);
|
||||
|
||||
struct Sigaction
|
||||
{
|
||||
CInt sa_flags @if(env::ANDROID);
|
||||
union
|
||||
{
|
||||
SignalFunction sa_handler;
|
||||
@@ -43,20 +45,20 @@ struct Sigaction
|
||||
CInt sa_flags @if(env::DARWIN || env::BSD_FAMILY );
|
||||
Sigset_t sa_mask @if(env::DARWIN || env::BSD_FAMILY);
|
||||
|
||||
Sigset_t sa_mask @if(env::LINUX);
|
||||
Sigset_t sa_mask @if(env::LINUX || env::ANDROID);
|
||||
CInt sa_flags @if(env::LINUX);
|
||||
void* sa_restorer @if(env::LINUX);
|
||||
void* sa_restorer @if(env::LINUX || env::ANDROID);
|
||||
}
|
||||
|
||||
struct Stack_t
|
||||
{
|
||||
void* ss_sp;
|
||||
struct @if(!env::LINUX)
|
||||
struct @if(!env::LINUX && !env::ANDROID)
|
||||
{
|
||||
usz ss_size;
|
||||
CInt ss_flags;
|
||||
}
|
||||
struct @if(env::LINUX)
|
||||
struct @if(env::LINUX || env::ANDROID)
|
||||
{
|
||||
CInt ss_flags;
|
||||
usz ss_size;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
module std::os::android @if(env::ANDROID);
|
||||
|
||||
|
||||
enum LogPriority : (CInt val)
|
||||
enum AndroidLogPriority : (CInt val)
|
||||
{
|
||||
ANDROID_LOG_UNKNOWN = 0,
|
||||
ANDROID_LOG_DEFAULT = 1,
|
||||
@@ -14,7 +14,7 @@ enum LogPriority : (CInt val)
|
||||
ANDROID_LOG_SILENT = 8
|
||||
}
|
||||
|
||||
enum LogId : (CInt val)
|
||||
enum AndroidLogId : (CInt val)
|
||||
{
|
||||
LOG_ID_MIN = 0,
|
||||
LOG_ID_MAIN = 0,
|
||||
@@ -29,7 +29,7 @@ enum LogId : (CInt val)
|
||||
LOG_ID_DEFAULT = 0x7FFFFFFF
|
||||
}
|
||||
|
||||
struct LogMessage @packed
|
||||
struct AndroidLogMessage @packed
|
||||
{
|
||||
usz struct_size;
|
||||
CInt buffer_id;
|
||||
@@ -40,11 +40,11 @@ struct LogMessage @packed
|
||||
ZString message;
|
||||
}
|
||||
|
||||
extern fn CInt log_write(LogPriority prio, ZString tag, ZString text) @cname("__android_log_write");
|
||||
extern fn CInt log_print(LogPriority prio, ZString tag, ZString fmt, ...) @cname("__android_log_print");
|
||||
extern fn CInt log_write(AndroidLogPriority prio, ZString tag, ZString text) @cname("__android_log_write");
|
||||
extern fn CInt log_print(AndroidLogPriority prio, ZString tag, ZString fmt, ...) @cname("__android_log_print");
|
||||
extern fn void log_assert(ZString cond, ZString tag, ZString fmt, ...) @cname("__android_log_assert");
|
||||
|
||||
fn bool log_id_is_valid(LogId id)
|
||||
fn bool log_id_is_valid(AndroidLogId id)
|
||||
{
|
||||
return id >= LOG_ID_MIN && id < LOG_ID_MAX;
|
||||
}
|
||||
@@ -52,13 +52,13 @@ fn bool log_id_is_valid(LogId id)
|
||||
extern fn CInt log_buf_write(CInt bufID, CInt prio, ZString tag, ZString text) @cname("__android_log_buf_write");
|
||||
extern fn CInt log_buf_print(CInt bufID, CInt prio, ZString tag, ZString fmt, ...) @cname("__android_log_buf_print");
|
||||
|
||||
alias LoggerFunction = fn void(LogMessage* log_message);
|
||||
alias LoggerFunction = fn void(AndroidLogMessage* log_message);
|
||||
alias AborterFunction = fn void(ZString abort_message);
|
||||
|
||||
extern fn void log_write_log_message(LogMessage log_message) @cname("__android_log_write_log_message");
|
||||
extern fn void log_write_log_message(AndroidLogMessage log_message) @cname("__android_log_write_log_message");
|
||||
extern fn void log_set_logger(LoggerFunction logger) @cname("__android_log_set_logger");
|
||||
extern fn void log_logd_logger(LogMessage log_message) @cname("__android_log_logd_logger");
|
||||
extern fn void log_stderr_logger(LogMessage log_message) @cname("__android_log_stderr_logger");
|
||||
extern fn void log_logd_logger(AndroidLogMessage log_message) @cname("__android_log_logd_logger");
|
||||
extern fn void log_stderr_logger(AndroidLogMessage log_message) @cname("__android_log_stderr_logger");
|
||||
extern fn void log_set_aborter(AborterFunction aborter) @cname("__android_log_set_aborter");
|
||||
extern fn void log_call_aborter(ZString abort_message) @cname("__android_log_call_aborter");
|
||||
extern fn void log_default_aborter(ZString abort_message) @cname("__android_log_default_aborter");
|
||||
|
||||
@@ -15,7 +15,7 @@ fn uint num_cpu()
|
||||
return count;
|
||||
}
|
||||
|
||||
module std::os @if(env::LINUX);
|
||||
module std::os @if(env::LINUX || env::ANDROID);
|
||||
import std::os::posix;
|
||||
|
||||
fn uint num_cpu()
|
||||
|
||||
@@ -12,7 +12,7 @@ const MAP_PRIVATE = 0x0002; // changes are private
|
||||
|
||||
const MAP_FILE = 0x0000; // map from file (default)
|
||||
|
||||
const MAP_ANONYMOUS = env::LINUX ??? 0x20 : 0x1000; // allocated from memory, swap space
|
||||
const MAP_ANONYMOUS = env::LINUX || env::ANDROID ??? 0x20 : 0x1000; // allocated from memory, swap space
|
||||
|
||||
const void* MAP_FAILED = (void *)(uptr)-1; // mmap failed
|
||||
const MADV_NORMAL = 0; // no further special treatment
|
||||
|
||||
@@ -3,8 +3,8 @@ import std::thread;
|
||||
import libc;
|
||||
|
||||
const PTHREAD_MUTEX_NORMAL = 0;
|
||||
const PTHREAD_MUTEX_ERRORCHECK = env::LINUX ? 2 : 1;
|
||||
const PTHREAD_MUTEX_RECURSIVE = env::LINUX ? 1 : 2;
|
||||
const PTHREAD_MUTEX_ERRORCHECK = env::LINUX || env::ANDROID ? 2 : 1;
|
||||
const PTHREAD_MUTEX_RECURSIVE = env::LINUX || env::ANDROID ? 1 : 2;
|
||||
|
||||
alias PosixThreadFn = fn void*(void*);
|
||||
typedef Pthread_t = void*;
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
### Changes / improvements
|
||||
- Method resolution and `$define` now works together well unless definitions are out of order for real.
|
||||
- Improve error message when using functions as values #2856
|
||||
- Improve support for Android with Termux.
|
||||
|
||||
### Stdlib changes
|
||||
- Summarize sort macros as generic function wrappers to reduce the amount of generated code. #2831
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
"c-include-dirs": [
|
||||
"C:\\"
|
||||
]
|
||||
}
|
||||
},
|
||||
"android-aarch64": {},
|
||||
"android-x86_64": {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
"linux-x64": {
|
||||
"cflags-override": "-fPIE"
|
||||
},
|
||||
"windows-x64": {}
|
||||
"windows-x64": {},
|
||||
"android-aarch64": {},
|
||||
"android-x86_64": {},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,7 +118,7 @@ run_cli_tests() {
|
||||
cd "$ROOT_DIR/resources"
|
||||
"$C3C_BIN" vendor-fetch raylib
|
||||
|
||||
if [ -f "/etc/alpine-release" ] || [[ "$SYSTEM_NAME" == "OpenBSD" ]] || [[ "$SYSTEM_NAME" == "NetBSD" ]]; then
|
||||
if [ -f "/etc/alpine-release" ] || [[ "$SYSTEM_NAME" == "OpenBSD" ]] || [[ "$SYSTEM_NAME" == "NetBSD" ]] || [[ "$OS_MODE" == "android" ]]; then
|
||||
echo "Skipping raylib_arkanoid (vendor raylib doesn't support this platform)"
|
||||
return
|
||||
fi
|
||||
@@ -128,8 +128,8 @@ run_cli_tests() {
|
||||
|
||||
run_dynlib_tests() {
|
||||
echo "--- Running Dynamic Lib Tests ---"
|
||||
# Skip openbsd, idk
|
||||
if [[ "$SYSTEM_NAME" == *"OpenBSD"* ]]; then return; fi
|
||||
# Skip openbsd and android
|
||||
if [[ "$SYSTEM_NAME" == *"OpenBSD"* ]] || [[ "$OS_MODE" == "android" ]]; then return; fi
|
||||
|
||||
cd "$ROOT_DIR/resources/examples/dynlib-test"
|
||||
"$C3C_BIN" -vv dynamic-lib add.c3
|
||||
|
||||
@@ -80,9 +80,9 @@ static void gencontext_destroy(GenContext *context)
|
||||
{
|
||||
ASSERT(llvm_is_global_eval(context));
|
||||
LLVMDisposeBuilder(context->global_builder);
|
||||
if (!context->shared_context) LLVMContextDispose(context->context);
|
||||
LLVMDisposeTargetData(context->target_data);
|
||||
LLVMDisposeTargetMachine(context->machine);
|
||||
LLVMDisposeTargetData(context->target_data);
|
||||
if (!context->shared_context) LLVMContextDispose(context->context);
|
||||
free(context);
|
||||
}
|
||||
|
||||
|
||||
@@ -1982,6 +1982,8 @@ void *llvm_target_machine_create(void)
|
||||
(LLVMCodeGenOptLevel)compiler.platform.llvm_opt_level,
|
||||
reloc_mode, model);
|
||||
LLVMSetTargetMachineUseInitArray(result, true);
|
||||
if (compiler.platform.emulated_tls) LLVMSetTargetMachineEmulatedTLS(result, true);
|
||||
|
||||
if (!result) error_exit("Failed to create target machine.");
|
||||
LLVMSetTargetMachineAsmVerbosity(result, 1);
|
||||
return result;
|
||||
@@ -2213,6 +2215,7 @@ void target_setup(BuildTarget *target)
|
||||
// ARM Cygwin
|
||||
// NVPTX
|
||||
compiler.platform.tls_supported = os_target_use_thread_local(compiler.platform.os);
|
||||
compiler.platform.emulated_tls = compiler.platform.os == OS_TYPE_ANDROID;
|
||||
compiler.platform.big_endian = arch_big_endian(compiler.platform.arch);
|
||||
compiler.platform.width_pointer = arch_pointer_bit_width(compiler.platform.os, compiler.platform.arch);
|
||||
compiler.platform.width_register = arch_int_register_bit_width(compiler.platform.os, compiler.platform.arch);
|
||||
|
||||
@@ -145,6 +145,7 @@ typedef struct
|
||||
} systemz;
|
||||
};
|
||||
bool big_endian;
|
||||
bool emulated_tls;
|
||||
bool tls_supported;
|
||||
bool asm_supported;
|
||||
bool float128;
|
||||
|
||||
@@ -79,6 +79,7 @@ bool LLVMHasUseList(LLVMValueRef value);
|
||||
void LLVMBuilderSetFastMathFlags(LLVMBuilderRef Builder, FastMathOption option);
|
||||
void LLVMSetDSOLocal(LLVMValueRef Global, bool value);
|
||||
void LLVMSetTargetMachineUseInitArray(LLVMTargetMachineRef ref, bool use_init_array);
|
||||
void LLVMSetTargetMachineEmulatedTLS(LLVMTargetMachineRef ref, bool emulated_tls);
|
||||
void LLVMSetNoSanitizeAddress(LLVMValueRef Global);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -323,6 +323,11 @@ void LLVMSetTargetMachineUseInitArray(LLVMTargetMachineRef ref, bool use_init_ar
|
||||
auto machine = (llvm::TargetMachine*)ref;
|
||||
machine->Options.UseInitArray = use_init_array;
|
||||
}
|
||||
void LLVMSetTargetMachineEmulatedTLS(LLVMTargetMachineRef ref, bool emulated_tls)
|
||||
{
|
||||
auto machine = (llvm::TargetMachine*)ref;
|
||||
machine->Options.EmulatedTLS = emulated_tls;
|
||||
}
|
||||
void LLVMSetDSOLocal(LLVMValueRef Global, bool value)
|
||||
{
|
||||
llvm::unwrap<llvm::GlobalValue>(Global)->setDSOLocal(value);
|
||||
|
||||
Reference in New Issue
Block a user