mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Initial Android support. (#2024)
* Initial Android support. * Add Android x86_64 * - Typo api_verion - Typo in DEFAULT_TARGETS - Removed unnecessary snprintf --------- Co-authored-by: Christoffer Lerno <christoffer@aegik.com>
This commit is contained in:
committed by
GitHub
parent
1461414128
commit
f21cc02320
@@ -57,6 +57,7 @@ enum OsType
|
||||
HURD,
|
||||
WASI,
|
||||
EMSCRIPTEN,
|
||||
ANDROID,
|
||||
}
|
||||
|
||||
enum ArchType
|
||||
@@ -150,6 +151,7 @@ const bool FREEBSD = LIBC && OS_TYPE == FREEBSD;
|
||||
const bool NETBSD = LIBC && OS_TYPE == NETBSD;
|
||||
const bool BSD_FAMILY = env::FREEBSD || env::OPENBSD || env::NETBSD;
|
||||
const bool WASI = LIBC && OS_TYPE == WASI;
|
||||
const bool ANDROID = LIBC && OS_TYPE == ANDROID;
|
||||
const bool WASM_NOLIBC @builtin = !LIBC && ARCH_TYPE == ArchType.WASM32 || ARCH_TYPE == ArchType.WASM64;
|
||||
const bool ADDRESS_SANITIZER = $$ADDRESS_SANITIZER;
|
||||
const bool MEMORY_SANITIZER = $$MEMORY_SANITIZER;
|
||||
@@ -182,6 +184,7 @@ macro bool os_is_posix() @const
|
||||
$case SOLARIS:
|
||||
$case TVOS:
|
||||
$case WATCHOS:
|
||||
$case ANDROID:
|
||||
return true;
|
||||
$case WIN32:
|
||||
$case WASI:
|
||||
|
||||
@@ -203,7 +203,7 @@ const CInt STDIN_FD = 0;
|
||||
const CInt STDOUT_FD = 1;
|
||||
const CInt STDERR_FD = 2;
|
||||
|
||||
module libc @if(env::LINUX);
|
||||
module libc @if(env::LINUX || env::ANDROID);
|
||||
extern CFile __stdin @extern("stdin");
|
||||
extern CFile __stdout @extern("stdout");
|
||||
extern CFile __stderr @extern("stderr");
|
||||
@@ -246,7 +246,7 @@ macro CFile stdin() => __acrt_iob_func(STDIN_FD);
|
||||
macro CFile stdout() => __acrt_iob_func(STDOUT_FD);
|
||||
macro CFile stderr() => __acrt_iob_func(STDERR_FD);
|
||||
|
||||
module libc @if(env::LIBC && !env::WIN32 && !env::LINUX && !env::DARWIN && !env::BSD_FAMILY);
|
||||
module libc @if(env::LIBC && !env::WIN32 && !env::LINUX && !env::ANDROID && !env::DARWIN && !env::BSD_FAMILY);
|
||||
macro CFile stdin() { return (CFile*)(uptr)STDIN_FD; }
|
||||
macro CFile stdout() { return (CFile*)(uptr)STDOUT_FD; }
|
||||
macro CFile stderr() { return (CFile*)(uptr)STDERR_FD; }
|
||||
|
||||
62
lib/std/libc/os/android.c3
Normal file
62
lib/std/libc/os/android.c3
Normal file
@@ -0,0 +1,62 @@
|
||||
module libc @if(env::ANDROID);
|
||||
|
||||
// Checked for x86_64, this is notoriously incorrect when comparing with Rust code etc
|
||||
|
||||
def Blksize_t = $typefrom(env::X86_64 ? long.typeid : CInt.typeid);
|
||||
def Nlink_t = $typefrom(env::X86_64 ? ulong.typeid : CUInt.typeid);
|
||||
def Blkcnt_t = long;
|
||||
def Ino_t = ulong;
|
||||
def Dev_t = ulong;
|
||||
def Mode_t = uint;
|
||||
def Ino64_t = ulong;
|
||||
def Blkcnt64_t = long;
|
||||
|
||||
struct Stat @if(env::X86_64)
|
||||
{
|
||||
Dev_t st_dev;
|
||||
Ino_t st_ino;
|
||||
Nlink_t st_nlink;
|
||||
Mode_t st_mode;
|
||||
Uid_t st_uid;
|
||||
Gid_t st_gid;
|
||||
CInt __pad0;
|
||||
Dev_t st_rdev;
|
||||
Off_t st_size;
|
||||
Blksize_t st_blksize;
|
||||
Blkcnt_t st_blocks;
|
||||
Time_t st_atime;
|
||||
long st_atime_nsec;
|
||||
Time_t st_mtime;
|
||||
long st_mtime_nsec;
|
||||
Time_t st_ctime;
|
||||
long st_ctime_nsec;
|
||||
long[3] __unused;
|
||||
}
|
||||
|
||||
struct Stat @if(!env::X86_64)
|
||||
{
|
||||
Dev_t st_dev;
|
||||
Ino_t st_ino;
|
||||
Mode_t st_mode;
|
||||
Nlink_t st_nlink;
|
||||
Uid_t st_uid;
|
||||
Gid_t st_gid;
|
||||
Dev_t st_rdev;
|
||||
CInt __pad1;
|
||||
Off_t st_size;
|
||||
Blksize_t st_blksize;
|
||||
CInt __pad2;
|
||||
Blkcnt_t st_blocks;
|
||||
Time_t st_atime;
|
||||
long st_atime_nsec;
|
||||
Time_t st_mtime;
|
||||
long st_mtime_nsec;
|
||||
Time_t st_ctime;
|
||||
long st_ctime_nsec;
|
||||
CInt[2] __unused;
|
||||
}
|
||||
|
||||
extern fn CInt stat(ZString path, Stat* stat);
|
||||
|
||||
extern fn CInt get_nprocs();
|
||||
extern fn CInt get_nprocs_conf();
|
||||
@@ -67,7 +67,7 @@ const CLOCK_UPTIME_RAW_APPROX = 9;
|
||||
const CLOCK_PROCESS_CPUTIME_ID = 12;
|
||||
const CLOCK_THREAD_CPUTIME_ID = 16;
|
||||
|
||||
module std::time::os @if(env::LINUX);
|
||||
module std::time::os @if(env::LINUX || env::ANDROID);
|
||||
const CLOCK_REALTIME = 0;
|
||||
const CLOCK_MONOTONIC = 1;
|
||||
const CLOCK_PROCESS_CPUTIME_ID = 2;
|
||||
|
||||
@@ -344,6 +344,7 @@ typedef enum
|
||||
{
|
||||
ARCH_OS_TARGET_DEFAULT = -1,
|
||||
ANDROID_AARCH64 = 0,
|
||||
ANDROID_X86_64,
|
||||
ELF_AARCH64,
|
||||
ELF_RISCV32,
|
||||
ELF_RISCV64,
|
||||
@@ -475,6 +476,11 @@ typedef struct BuildOptions_
|
||||
const char *crt;
|
||||
const char *crtbegin;
|
||||
} linuxpaths;
|
||||
struct
|
||||
{
|
||||
const char *ndk_path;
|
||||
int api_version;
|
||||
} android;
|
||||
int build_threads;
|
||||
const char **libraries_to_fetch;
|
||||
const char **files;
|
||||
@@ -742,6 +748,11 @@ typedef struct
|
||||
const char *crt;
|
||||
const char *crtbegin;
|
||||
} linuxpaths;
|
||||
struct
|
||||
{
|
||||
const char *ndk_path;
|
||||
int api_version;
|
||||
} android;
|
||||
} BuildTarget;
|
||||
|
||||
static const char *x86_cpu_set[8] = {
|
||||
|
||||
@@ -197,6 +197,9 @@ static void usage(bool full)
|
||||
print_opt("--linux-crt <dir>", "Set the directory to use for finding crt1.o and related files.");
|
||||
print_opt("--linux-crtbegin <dir>", "Set the directory to use for finding crtbegin.o and related files.");
|
||||
PRINTF("");
|
||||
print_opt("--android-ndk <dir>", "Set the NDK directory location.");
|
||||
print_opt("--android-api <dir>", "Set Android API version.");
|
||||
PRINTF("");
|
||||
print_opt("--sanitize=<option>", "Enable sanitizer: address, memory, thread.");
|
||||
}
|
||||
if (!full)
|
||||
@@ -984,7 +987,7 @@ static void parse_option(BuildOptions *options)
|
||||
PRINTF("Available targets:");
|
||||
EOUTPUT("Invalid target %s.", target);
|
||||
EOUTPUT("These targets are supported:");
|
||||
for (unsigned i = 1; i <= ARCH_OS_TARGET_LAST; i++)
|
||||
for (unsigned i = 0; i <= ARCH_OS_TARGET_LAST; i++)
|
||||
{
|
||||
EOUTPUT(" %s", arch_os_target[i]);
|
||||
}
|
||||
@@ -1229,6 +1232,18 @@ static void parse_option(BuildOptions *options)
|
||||
options->linuxpaths.crtbegin = check_dir(next_arg());
|
||||
return;
|
||||
}
|
||||
if (match_longopt("android-ndk"))
|
||||
{
|
||||
if (at_end() || next_is_opt()) error_exit("error: android-ndk needs a directory.");
|
||||
options->android.ndk_path = check_dir(next_arg());
|
||||
return;
|
||||
}
|
||||
if (match_longopt("android-api"))
|
||||
{
|
||||
if (at_end() || next_is_opt()) error_exit("error: android-api needs a version.");
|
||||
options->android.api_version = atoi(next_arg());
|
||||
return;
|
||||
}
|
||||
if (match_longopt("benchmarking"))
|
||||
{
|
||||
options->benchmarking = true;
|
||||
@@ -1358,13 +1373,29 @@ BuildOptions parse_arguments(int argc, const char *argv[])
|
||||
{
|
||||
FAIL_WITH_ERR("Missing a compiler command such as 'compile' or 'build'.");
|
||||
}
|
||||
if (build_options.arch_os_target_override == ANDROID_AARCH64)
|
||||
{
|
||||
if (!build_options.android.ndk_path)
|
||||
{
|
||||
const char *ndk_path = getenv("ANDROID_NDK");
|
||||
if (!ndk_path)
|
||||
{
|
||||
FAIL_WITH_ERR("Can't find Android NDK, please set --ndk-path.");
|
||||
}
|
||||
build_options.android.ndk_path = strdup(ndk_path);
|
||||
}
|
||||
if (build_options.android.api_version <= 0)
|
||||
{
|
||||
build_options.android.api_version = 30; // 30 = Android 11
|
||||
}
|
||||
}
|
||||
debug_log = build_options.verbosity_level > 2;
|
||||
return build_options;
|
||||
}
|
||||
|
||||
ArchOsTarget arch_os_target_from_string(const char *target)
|
||||
{
|
||||
for (unsigned i = 1; i <= ARCH_OS_TARGET_LAST; i++)
|
||||
for (unsigned i = 0; i <= ARCH_OS_TARGET_LAST; i++)
|
||||
{
|
||||
if (strcmp(arch_os_target[i], target) == 0)
|
||||
{
|
||||
@@ -1505,7 +1536,7 @@ static void update_feature_flags(const char ***flags, const char ***removed_flag
|
||||
static void print_all_targets(void)
|
||||
{
|
||||
PRINTF("Available targets:");
|
||||
for (unsigned i = 1; i <= ARCH_OS_TARGET_LAST; i++)
|
||||
for (unsigned i = 0; i <= ARCH_OS_TARGET_LAST; i++)
|
||||
{
|
||||
PRINTF(" %s", arch_os_target[i]);
|
||||
}
|
||||
@@ -1534,6 +1565,7 @@ static int parse_option_select(const char *start, unsigned count, const char **e
|
||||
|
||||
const char *arch_os_target[ARCH_OS_TARGET_LAST + 1] = {
|
||||
[ANDROID_AARCH64] = "android-aarch64",
|
||||
[ANDROID_X86_64] = "android-x86_64",
|
||||
[ELF_AARCH64] = "elf-aarch64",
|
||||
[ELF_RISCV32] = "elf-riscv32",
|
||||
[ELF_RISCV64] = "elf-riscv64",
|
||||
|
||||
@@ -230,6 +230,7 @@ static LinkLibc libc_from_arch_os(ArchOsTarget target)
|
||||
switch (target)
|
||||
{
|
||||
case ANDROID_AARCH64:
|
||||
case ANDROID_X86_64:
|
||||
case FREEBSD_X86:
|
||||
case FREEBSD_X64:
|
||||
case IOS_AARCH64:
|
||||
@@ -412,7 +413,8 @@ static void update_build_target_from_options(BuildTarget *target, BuildOptions *
|
||||
OVERRIDE_IF_SET(macos.sdk_version);
|
||||
OVERRIDE_IF_SET(linuxpaths.crt);
|
||||
OVERRIDE_IF_SET(linuxpaths.crtbegin);
|
||||
|
||||
OVERRIDE_IF_SET(android.ndk_path);
|
||||
OVERRIDE_IF_SET(android.api_version);
|
||||
|
||||
if (options->silence_deprecation || options->verbosity_level < 0) target->silence_deprecation = options->silence_deprecation || options->verbosity_level < 0;
|
||||
target->print_linking = options->print_linking || options->verbosity_level > 1;
|
||||
|
||||
@@ -170,6 +170,7 @@ const char* MAIN_INTERFACE_TEMPLATE =
|
||||
"// extern fn int some_library_function();\n";
|
||||
|
||||
const char* DEFAULT_TARGETS[] = {
|
||||
"android-aarch64",
|
||||
"freebsd-x64",
|
||||
"linux-aarch64",
|
||||
"linux-riscv32",
|
||||
|
||||
@@ -1098,6 +1098,7 @@ static int jump_buffer_size()
|
||||
return 32;
|
||||
case ELF_X64:
|
||||
case LINUX_X64:
|
||||
case ANDROID_X86_64:
|
||||
// Godbolt test
|
||||
return 25;
|
||||
case FREEBSD_X64:
|
||||
|
||||
@@ -941,7 +941,8 @@ typedef enum
|
||||
OS_TYPE_HURD,
|
||||
OS_TYPE_WASI,
|
||||
OS_TYPE_EMSCRIPTEN,
|
||||
OS_TYPE_LAST = OS_TYPE_EMSCRIPTEN
|
||||
OS_TYPE_ANDROID,
|
||||
OS_TYPE_LAST = OS_TYPE_ANDROID
|
||||
} OsType;
|
||||
|
||||
|
||||
@@ -1647,5 +1648,3 @@ case TYPE_U8: case TYPE_U16: case TYPE_U32: case TYPE_U64: case TYPE_U128
|
||||
case EXPR_CATCH_UNRESOLVED: case EXPR_UNRESOLVED_IDENTIFIER: case EXPR_CAST: \
|
||||
case EXPR_TYPEID: case EXPR_EMBED: case EXPR_VASPLAT: case EXPR_OTHER_CONTEXT: \
|
||||
case EXPR_GENERIC_IDENT: case EXPR_COMPOUND_LITERAL: case EXPR_MACRO_BODY: case EXPR_CT_SUBSCRIPT
|
||||
|
||||
|
||||
|
||||
@@ -443,6 +443,71 @@ static void linker_setup_linux(const char ***args_ref, Linker linker_type, bool
|
||||
add_plain_arg(ld_target(compiler.platform.arch));
|
||||
}
|
||||
|
||||
static void linker_setup_android(const char ***args_ref, Linker linker_type, bool is_dylib)
|
||||
{
|
||||
#ifdef __linux__
|
||||
#define ANDROID_HOST_TAG "linux-x86_64"
|
||||
#elif __APPLE__
|
||||
#define ANDROID_HOST_TAG "darwin-x86_64"
|
||||
#elif _WIN32
|
||||
#define ANDROID_HOST_TAG "windows-x86_64"
|
||||
#else
|
||||
#error Unknown Host OS
|
||||
#endif
|
||||
|
||||
if (is_no_pie(compiler.platform.reloc_model)) add_plain_arg("-no-pie");
|
||||
if (is_pie(compiler.platform.reloc_model)) add_plain_arg("-pie");
|
||||
add_plain_arg("-dynamic-linker"); add_plain_arg("/system/bin/linker64");
|
||||
|
||||
scratch_buffer_clear();
|
||||
scratch_buffer_append("-L");
|
||||
scratch_buffer_append(compiler.build.android.ndk_path);
|
||||
scratch_buffer_append("/toolchains/llvm/prebuilt/");
|
||||
scratch_buffer_append(ANDROID_HOST_TAG);
|
||||
scratch_buffer_append("/sysroot/usr/lib/");
|
||||
scratch_buffer_append(compiler.platform.target_triple);
|
||||
scratch_buffer_append_char('/');
|
||||
scratch_buffer_append_signed_int(compiler.build.android.api_version);
|
||||
add_plain_arg(scratch_buffer_copy());
|
||||
|
||||
scratch_buffer_clear();
|
||||
scratch_buffer_append(compiler.build.android.ndk_path);
|
||||
scratch_buffer_append("/toolchains/llvm/prebuilt/");
|
||||
scratch_buffer_append(ANDROID_HOST_TAG);
|
||||
scratch_buffer_append("/sysroot/usr/lib/");
|
||||
scratch_buffer_append(compiler.platform.target_triple);
|
||||
scratch_buffer_append_char('/');
|
||||
scratch_buffer_append_signed_int(compiler.build.android.api_version);
|
||||
scratch_buffer_append("/crtbegin_dynamic.o");
|
||||
add_plain_arg(scratch_buffer_copy());
|
||||
|
||||
scratch_buffer_clear();
|
||||
scratch_buffer_append(compiler.build.android.ndk_path);
|
||||
scratch_buffer_append("/toolchains/llvm/prebuilt/");
|
||||
scratch_buffer_append(ANDROID_HOST_TAG);
|
||||
scratch_buffer_append("/sysroot/usr/lib/");
|
||||
scratch_buffer_append(compiler.platform.target_triple);
|
||||
scratch_buffer_append_char('/');
|
||||
scratch_buffer_append_signed_int(compiler.build.android.api_version);
|
||||
scratch_buffer_append("/crt_pad_segment.o");
|
||||
add_plain_arg(scratch_buffer_copy());
|
||||
|
||||
scratch_buffer_clear();
|
||||
scratch_buffer_append(compiler.build.android.ndk_path);
|
||||
scratch_buffer_append("/toolchains/llvm/prebuilt/");
|
||||
scratch_buffer_append(ANDROID_HOST_TAG);
|
||||
scratch_buffer_append("/sysroot/usr/lib/");
|
||||
scratch_buffer_append(compiler.platform.target_triple);
|
||||
scratch_buffer_append_char('/');
|
||||
scratch_buffer_append_signed_int(compiler.build.android.api_version);
|
||||
scratch_buffer_append("/crtend_android.o");
|
||||
add_plain_arg(scratch_buffer_copy());
|
||||
|
||||
add_plain_arg("-ldl");
|
||||
add_plain_arg("-lm");
|
||||
add_plain_arg("-lc");
|
||||
}
|
||||
|
||||
static void linker_setup_freebsd(const char ***args_ref, Linker linker_type, bool is_dylib)
|
||||
{
|
||||
if (linker_type == LINKER_CC) {
|
||||
@@ -594,6 +659,9 @@ static bool linker_setup(const char ***args_ref, const char **files_to_link, uns
|
||||
case OS_TYPE_LINUX:
|
||||
linker_setup_linux(args_ref, linker_type, is_dylib);
|
||||
break;
|
||||
case OS_TYPE_ANDROID:
|
||||
linker_setup_android(args_ref, linker_type, is_dylib);
|
||||
break;
|
||||
case OS_TYPE_UNKNOWN:
|
||||
if (link_libc())
|
||||
{
|
||||
@@ -694,6 +762,7 @@ Linker linker_find_linker_type(void)
|
||||
case OS_TYPE_LINUX:
|
||||
case OS_TYPE_NETBSD:
|
||||
case OS_TYPE_OPENBSD:
|
||||
case OS_TYPE_ANDROID:
|
||||
return LINKER_LD;
|
||||
case OS_DARWIN_TYPES:
|
||||
return LINKER_LD64;
|
||||
|
||||
@@ -122,6 +122,7 @@ static bool os_target_use_thread_local(OsType os)
|
||||
case OS_DARWIN_TYPES:
|
||||
case OS_TYPE_FREE_BSD:
|
||||
case OS_TYPE_LINUX:
|
||||
case OS_TYPE_ANDROID:
|
||||
case OS_TYPE_NETBSD:
|
||||
case OS_TYPE_OPENBSD:
|
||||
case OS_TYPE_WIN32:
|
||||
@@ -1100,7 +1101,8 @@ static char *arch_to_target_triple[ARCH_OS_TARGET_LAST + 1] = {
|
||||
[FREEBSD_X64] = "x86_64-pc-freebsd",
|
||||
[OPENBSD_X64] = "x86_64-pc-openbsd",
|
||||
[ELF_X64] = "x86_64-unknown-elf",
|
||||
[ANDROID_AARCH64] = "aarch64-unknown-linux-android",
|
||||
[ANDROID_AARCH64] = "aarch64-linux-android",
|
||||
[ANDROID_X86_64] = "x86_64-linux-android",
|
||||
[LINUX_AARCH64] = "aarch64-unknown-linux-gnu",
|
||||
[IOS_AARCH64] = "aarch64-apple-ios",
|
||||
[MACOS_AARCH64] = "aarch64-apple-macosx",
|
||||
@@ -1309,6 +1311,7 @@ static OsType os_from_llvm_string(StringSlice os_string)
|
||||
STRCASE("wasi", OS_TYPE_WASI)
|
||||
STRCASE("emscripten", OS_TYPE_EMSCRIPTEN)
|
||||
STRCASE("elf", OS_TYPE_NONE)
|
||||
STRCASE("android", OS_TYPE_ANDROID)
|
||||
return OS_TYPE_UNKNOWN;
|
||||
#undef STRCASE
|
||||
}
|
||||
@@ -1474,6 +1477,7 @@ static ObjectFormatType object_format_from_os(OsType os, ArchType arch_type)
|
||||
if (arch_is_wasm(arch_type)) return OBJ_FORMAT_WASM;
|
||||
FALLTHROUGH;
|
||||
case OS_TYPE_LINUX:
|
||||
case OS_TYPE_ANDROID:
|
||||
case OS_TYPE_NETBSD:
|
||||
case OS_TYPE_OPENBSD:
|
||||
case OS_TYPE_FREE_BSD:
|
||||
@@ -1529,6 +1533,7 @@ static unsigned os_target_c_type_bits(OsType os, ArchType arch, CType type)
|
||||
break;
|
||||
case OS_DARWIN_TYPES:
|
||||
case OS_TYPE_LINUX:
|
||||
case OS_TYPE_ANDROID:
|
||||
case OS_TYPE_NONE:
|
||||
case OS_TYPE_FREE_BSD:
|
||||
case OS_TYPE_NETBSD:
|
||||
@@ -1706,6 +1711,7 @@ static RelocModel arch_os_reloc_default(ArchType arch, OsType os, EnvironmentTyp
|
||||
if (arch == ARCH_TYPE_X86) return RELOC_NONE;
|
||||
return RELOC_BIG_PIC;
|
||||
case OS_TYPE_LINUX:
|
||||
case OS_TYPE_ANDROID:
|
||||
return RELOC_BIG_PIC;
|
||||
case OS_TYPE_WASI:
|
||||
return RELOC_NONE;
|
||||
@@ -1746,6 +1752,7 @@ static RelocModel arch_os_reloc_default(ArchType arch, OsType os, EnvironmentTyp
|
||||
case OS_TYPE_WASI:
|
||||
return RELOC_NONE;
|
||||
case OS_TYPE_LINUX:
|
||||
case OS_TYPE_ANDROID:
|
||||
return RELOC_BIG_PIE;
|
||||
case OS_TYPE_OPENBSD:
|
||||
return RELOC_SMALL_PIE;
|
||||
@@ -1768,6 +1775,7 @@ static bool arch_os_pic_default_forced(ArchType arch, OsType os)
|
||||
case OS_TYPE_NONE:
|
||||
case OS_TYPE_FREE_BSD:
|
||||
case OS_TYPE_LINUX:
|
||||
case OS_TYPE_ANDROID:
|
||||
case OS_TYPE_NETBSD:
|
||||
case OS_TYPE_OPENBSD:
|
||||
return false;
|
||||
@@ -2119,4 +2127,3 @@ void target_setup(BuildTarget *target)
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user