diff --git a/lib/std/core/env.c3 b/lib/std/core/env.c3 index acdfc17da..1b609bfda 100644 --- a/lib/std/core/env.c3 +++ b/lib/std/core/env.c3 @@ -124,7 +124,8 @@ const usz MAX_VECTOR_SIZE = $$MAX_VECTOR_SIZE; const bool ARCH_32_BIT = $$REGISTER_SIZE == 32; const bool ARCH_64_BIT = $$REGISTER_SIZE == 64; const bool LIBC = $$COMPILER_LIBC_AVAILABLE; -const bool NO_LIBC = !$$COMPILER_LIBC_AVAILABLE; +const bool NO_LIBC = !LIBC && !CUSTOM_LIBC; +const bool CUSTOM_LIBC = $$CUSTOM_LIBC; const CompilerOptLevel COMPILER_OPT_LEVEL = CompilerOptLevel.from_ordinal($$COMPILER_OPT_LEVEL); const bool BIG_ENDIAN = $$PLATFORM_BIG_ENDIAN; const bool I128_NATIVE_SUPPORT = $$PLATFORM_I128_SUPPORTED; diff --git a/lib/std/libc/libc.c3 b/lib/std/libc/libc.c3 index b879f676b..eb73d570a 100644 --- a/lib/std/libc/libc.c3 +++ b/lib/std/libc/libc.c3 @@ -258,7 +258,7 @@ macro CFile stdin() { return (CFile*)(uptr)STDIN_FD; } macro CFile stdout() { return (CFile*)(uptr)STDOUT_FD; } macro CFile stderr() { return (CFile*)(uptr)STDERR_FD; } -module libc @if(!env::LIBC); +module libc @if(env::NO_LIBC); import std::core::mem; diff --git a/releasenotes.md b/releasenotes.md index 46d72e9bc..4424ff3df 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -4,6 +4,7 @@ ## 0.7.9 Change list ### Changes / improvements +- Add `--custom-libc` option for custom libc implementations. ### Fixes - Regression with npot vector in struct triggering an assert #2219. diff --git a/src/build/build.h b/src/build/build.h index 215ca6627..9dc026f8a 100644 --- a/src/build/build.h +++ b/src/build/build.h @@ -237,6 +237,13 @@ typedef enum USE_STDLIB_ON = 1 } UseStdlib; +typedef enum +{ + CUSTOM_LIBC_NOT_SET = -1, + CUSTOM_LIBC_OFF = 0, + CUSTOM_LIBC_ON = 1 +} CustomLibc; + typedef enum { SHOW_BACKTRACE_NOT_SET = -1, @@ -609,6 +616,7 @@ typedef struct BuildOptions_ FpOpt fp_math; EmitStdlib emit_stdlib; UseStdlib use_stdlib; + CustomLibc custom_libc; LinkLibc link_libc; StripUnused strip_unused; OptimizationLevel optlevel; @@ -750,6 +758,7 @@ typedef struct UseStdlib use_stdlib; EmitStdlib emit_stdlib; LinkLibc link_libc; + CustomLibc custom_libc; ShowBacktrace show_backtrace; StripUnused strip_unused; DebugInfo debug_info; @@ -858,6 +867,7 @@ static BuildTarget default_build_target = { .use_stdlib = USE_STDLIB_NOT_SET, .link_libc = LINK_LIBC_NOT_SET, .emit_stdlib = EMIT_STDLIB_NOT_SET, + .custom_libc = CUSTOM_LIBC_NOT_SET, .linker_type = LINKER_TYPE_NOT_SET, .validation_level = VALIDATION_NOT_SET, .single_module = SINGLE_MODULE_NOT_SET, diff --git a/src/build/build_options.c b/src/build/build_options.c index becb169da..a070f24fb 100644 --- a/src/build/build_options.c +++ b/src/build/build_options.c @@ -167,6 +167,7 @@ static void usage(bool full) PRINTF(""); print_opt("--use-stdlib=", "Include the standard library (default: yes)."); print_opt("--link-libc=", "Link libc other default libraries (default: yes)."); + print_opt("--custom-libc=", "Set to true if a custom libc implementation is provided (default: no)."); print_opt("--emit-stdlib=", "Output files for the standard library. (default: yes)"); print_opt("--emit-only ", "Output only the file matching ."); print_opt("--panicfn ", "Override the panic function name."); @@ -948,6 +949,11 @@ static void parse_option(BuildOptions *options) options->emit_stdlib = parse_opt_select(EmitStdlib, argopt, on_off); return; } + if ((argopt = match_argopt("custom-libc"))) + { + options->custom_libc = parse_opt_select(CustomLibc, argopt, on_off); + return; + } if (match_longopt("emit-only")) { if (at_end() || next_is_opt()) error_exit("error: --emit-only expects an output name, e.g. 'foo', to only output 'foo.o'."); @@ -1489,6 +1495,7 @@ BuildOptions parse_arguments(int argc, const char *argv[]) .win.crt_linking = WIN_CRT_DEFAULT, .emit_stdlib = EMIT_STDLIB_NOT_SET, .link_libc = LINK_LIBC_NOT_SET, + .custom_libc = CUSTOM_LIBC_NOT_SET, .use_stdlib = USE_STDLIB_NOT_SET, .arch_os_target_override = ARCH_OS_TARGET_DEFAULT, .linker_type = LINKER_TYPE_NOT_SET, diff --git a/src/build/builder.c b/src/build/builder.c index b3a71265c..8caa281a1 100644 --- a/src/build/builder.c +++ b/src/build/builder.c @@ -460,6 +460,7 @@ static void update_build_target_from_options(BuildTarget *target, BuildOptions * set_if_updated(target->reloc_model, options->reloc_model); set_if_updated(target->use_stdlib, options->use_stdlib); set_if_updated(target->link_libc, options->link_libc); + set_if_updated(target->custom_libc, options->custom_libc); set_if_updated(target->emit_stdlib, options->emit_stdlib); set_if_updated(target->win.crt_linking, options->win.crt_linking); set_if_updated(target->feature.fp_math, options->fp_math); diff --git a/src/build/project.c b/src/build/project.c index 917a2e361..4422bdbb6 100644 --- a/src/build/project.c +++ b/src/build/project.c @@ -26,6 +26,7 @@ const char *project_default_keys[][2] = { {"langrev", "Version of the C3 language used."}, {"link-args", "Linker arguments for all targets."}, {"link-libc", "Link libc (default: true)."}, + {"custom-libc", "Implement your own libc (default: false)."}, {"linked-libraries", "Libraries linked by the linker for all targets."}, {"linker", "'builtin' for the builtin linker, 'cc' for the system linker or to a custom compiler."}, {"linker-search-paths", "Linker search paths."}, @@ -109,6 +110,7 @@ const char* project_target_keys[][2] = { {"link-args", "Additional linker arguments for the target."}, {"link-args-override", "Linker arguments for this target, overriding global settings."}, {"link-libc", "Link libc (default: true)."}, + {"custom-libc", "Implement your own libc (default: false)."}, {"linked-libraries", "Additional libraries linked by the linker for the target."}, {"linked-libraries-override", "Libraries linked by the linker for this target, overriding global settings."}, {"linker", "'builtin' for the builtin linker, 'cc' for the system linker or to a custom compiler."}, @@ -540,6 +542,9 @@ static void load_into_build_target(BuildParseContext context, JSONObject *json, // emit-stdlib target->emit_stdlib = (EmitStdlib) get_valid_bool(context, json, "emit-stdlib", target->emit_stdlib); + // implement-stdlib + target->custom_libc = (CustomLibc) get_valid_bool(context, json, "custom-libc", target->custom_libc); + // single-module target->single_module = (SingleModule) get_valid_bool(context, json, "single-module", target->single_module); diff --git a/src/build/project_manipulation.c b/src/build/project_manipulation.c index 59e042294..708a93ae4 100644 --- a/src/build/project_manipulation.c +++ b/src/build/project_manipulation.c @@ -234,6 +234,7 @@ static void view_target(BuildParseContext context, JSONObject *target, bool verb TARGET_VIEW_STRING_ARRAY("Additional linker arguments", "link-args", ", "); TARGET_VIEW_STRING_ARRAY("Linker arguments (override)", "link-args-override", ", "); TARGET_VIEW_BOOL("Link libc", "link-libc"); + TARGET_VIEW_BOOL("Custom libc", "custom-libc"); TARGET_VIEW_STRING("MacOS SDK directory", "macossdk"); TARGET_VIEW_SETTING("Memory environment", "memory-env", memory_environment); TARGET_VIEW_BOOL("Don't generate/require main function", "no-entry"); @@ -558,6 +559,7 @@ void view_project(BuildOptions *build_options) VIEW_STRING_ARRAY("Linker search paths", "linker-search-paths", ", "); VIEW_STRING_ARRAY("Linker arguments", "link-args", ", "); VIEW_BOOL("Link libc", "link-libc"); + VIEW_BOOL("Custom libc", "custom-libc"); VIEW_STRING("MacOS SDK directory", "macossdk"); VIEW_SETTING("Memory environment", "memory-env", memory_environment); VIEW_BOOL("Don't generate/require main function", "no-entry"); diff --git a/src/compiler/compiler.c b/src/compiler/compiler.c index 335d40f03..d8991ce58 100644 --- a/src/compiler/compiler.c +++ b/src/compiler/compiler.c @@ -1502,6 +1502,7 @@ void compile() setup_int_define("ARCH_TYPE", (uint64_t)compiler.platform.arch, type_int); setup_int_define("MEMORY_ENVIRONMENT", (uint64_t)compiler.build.memory_environment, type_int); setup_bool_define("COMPILER_LIBC_AVAILABLE", link_libc()); + setup_bool_define("CUSTOM_LIBC", custom_libc()); setup_int_define("COMPILER_OPT_LEVEL", (uint64_t)compiler.build.optlevel, type_int); setup_int_define("OS_TYPE", (uint64_t)compiler.platform.os, type_int); setup_int_define("COMPILER_SIZE_OPT_LEVEL", (uint64_t)compiler.build.optsize, type_int); diff --git a/src/compiler/compiler_internal.h b/src/compiler/compiler_internal.h index 85ac481fe..d75e33324 100644 --- a/src/compiler/compiler_internal.h +++ b/src/compiler/compiler_internal.h @@ -2120,6 +2120,11 @@ INLINE bool link_libc(void) return compiler.build.link_libc != LINK_LIBC_OFF; } +INLINE bool custom_libc(void) +{ + return compiler.build.custom_libc == CUSTOM_LIBC_ON; +} + INLINE bool strip_unused(void) { return compiler.build.strip_unused != STRIP_UNUSED_OFF;