diff --git a/src/build/build_options.h b/src/build/build.h similarity index 85% rename from src/build/build_options.h rename to src/build/build.h index 7e9b741b5..96198a94c 100644 --- a/src/build/build_options.h +++ b/src/build/build.h @@ -1,6 +1,5 @@ #pragma once - -// Copyright (c) 2019 Christoffer Lerno. All rights reserved. +// Copyright (c) 2019-2023 Christoffer Lerno. All rights reserved. // Use of this source code is governed by the GNU LGPLv3.0 license // a copy of which can be found in the LICENSE file. @@ -14,8 +13,6 @@ #define DEFAULT_SYMTAB_SIZE (256 * 1024) #define DEFAULT_SWITCHRANGE_MAX_SIZE (256) -void update_feature_flags(const char ***flags, const char ***removed_flag, const char *arg, bool add); - typedef enum { BACKEND_LLVM = 1, @@ -228,57 +225,6 @@ typedef enum RISCVFLOAT_DOUBLE = 2, } RiscvFloatCapability; - -static const char *x86_vector_capability[6] = { - [X86VECTOR_NONE] = "none", - [X86VECTOR_MMX] = "mmx", - [X86VECTOR_SSE] = "sse", - [X86VECTOR_AVX] = "avx", - [X86VECTOR_AVX512] = "avx512", - [X86VECTOR_NATIVE] = "native" -}; - -static const char *x86_cpu_set[8] = { - [X86CPU_BASELINE] = "baseline", - [X86CPU_SSSE3] = "ssse3", - [X86CPU_SSE4] = "sse4", - [X86CPU_AVX1] = "avx1", - [X86CPU_AVX2_V1] = "avx2-v1", - [X86CPU_AVX2_V2] = "avx2-v2", - [X86CPU_AVX512] = "avx512", - [X86CPU_NATIVE] = "native" -}; - -static const char *fp_math[3] = { - [FP_STRICT] = "strict", - [FP_RELAXED] = "relaxed", - [FP_FAST] = "fast", -}; - -static const char *optlevels[4] = { - [OPTIMIZATION_NONE] = "none", - [OPTIMIZATION_LESS] = "less", - [OPTIMIZATION_MORE] = "more", - [OPTIMIZATION_AGGRESSIVE] = "max", -}; - -static const char *optsizes[3] = { - [SIZE_OPTIMIZATION_NONE] = "none", - [SIZE_OPTIMIZATION_SMALL] = "small", - [SIZE_OPTIMIZATION_TINY] = "more", -}; - -static const char *on_off[2] = { - [SAFETY_OFF] = "no", - [SAFETY_ON] = "yes", -}; - -static const char *riscv_capability[3] = { - [RISCVFLOAT_NONE] = "none", - [RISCVFLOAT_FLOAT] = "float", - [RISCVFLOAT_DOUBLE] = "double", -}; - typedef enum { MEMORY_ENV_NOT_SET = -1, @@ -288,13 +234,6 @@ typedef enum MEMORY_ENV_NONE = 3, } MemoryEnvironment; -static const char *memory_environment[6] = { - [MEMORY_ENV_NORMAL] = "normal", - [MEMORY_ENV_SMALL] = "small", - [MEMORY_ENV_TINY] = "tiny", - [MEMORY_ENV_NONE] = "none", -}; - typedef enum { WIN_CRT_DEFAULT = -1, @@ -303,12 +242,6 @@ typedef enum WIN_CRT_STATIC = 2, } WinCrtLinking; -static const char *wincrt_linking[3] = { - [WIN_CRT_NONE] = "none", - [WIN_CRT_DYNAMIC] = "dynamic", - [WIN_CRT_STATIC] = "static", -}; - typedef enum { RELOC_DEFAULT = -1, @@ -319,14 +252,6 @@ typedef enum RELOC_BIG_PIE = 4, } RelocModel; -static const char *reloc_models[5] = { - [RELOC_NONE] = "none", - [RELOC_SMALL_PIC] = "pic", - [RELOC_BIG_PIC] = "PIC", - [RELOC_SMALL_PIE] = "pie", - [RELOC_BIG_PIE] = "PIE", -}; - typedef enum { DEBUG_INFO_NOT_SET = -1, @@ -454,9 +379,6 @@ typedef struct BuildOptions_ bool testing; } BuildOptions; - - - typedef enum { TARGET_TYPE_EXECUTABLE, @@ -580,11 +502,16 @@ typedef struct } linuxpaths; } BuildTarget; - -BuildOptions parse_arguments(int argc, const char *argv[]); -ArchOsTarget arch_os_target_from_string(const char *target); -bool command_is_projectless(CompilerCommand command); -void update_build_target_with_opt_level(BuildTarget *target, OptimizationSetting level); +static const char *x86_cpu_set[8] = { + [X86CPU_BASELINE] = "baseline", + [X86CPU_SSSE3] = "ssse3", + [X86CPU_SSE4] = "sse4", + [X86CPU_AVX1] = "avx1", + [X86CPU_AVX2_V1] = "avx2-v1", + [X86CPU_AVX2_V2] = "avx2-v2", + [X86CPU_AVX512] = "avx512", + [X86CPU_NATIVE] = "native" +}; static BuildTarget default_build_target = { .optlevel = OPTIMIZATION_NOT_SET, @@ -616,4 +543,11 @@ static BuildTarget default_build_target = { .feature.safe_mode = SAFETY_NOT_SET, .win.crt_linking = WIN_CRT_DEFAULT, .switchrange_max_size = DEFAULT_SWITCHRANGE_MAX_SIZE, -}; \ No newline at end of file +}; + +BuildOptions parse_arguments(int argc, const char *argv[]); +ArchOsTarget arch_os_target_from_string(const char *target); +bool command_accepts_files(CompilerCommand command); +void update_build_target_with_opt_level(BuildTarget *target, OptimizationSetting level); +void create_project(BuildOptions *build_options); + diff --git a/src/build/build_internal.h b/src/build/build_internal.h index d3b9c7a85..72918c209 100644 --- a/src/build/build_internal.h +++ b/src/build/build_internal.h @@ -1,19 +1,77 @@ #pragma once - -// Copyright (c) 2020 Christoffer Lerno. All rights reserved. +// Copyright (c) 2020-2023 Christoffer Lerno. All rights reserved. // Use of this source code is governed by a LGPLv3.0 // a copy of which can be found in the LICENSE file. #include "utils/lib.h" #include "utils/json.h" -#include "build_options.h" - +#include "build.h" typedef struct { BuildTarget **targets; } Project; +static const char *memory_environment[6] = { + [MEMORY_ENV_NORMAL] = "normal", + [MEMORY_ENV_SMALL] = "small", + [MEMORY_ENV_TINY] = "tiny", + [MEMORY_ENV_NONE] = "none", +}; + +static const char *wincrt_linking[3] = { + [WIN_CRT_NONE] = "none", + [WIN_CRT_DYNAMIC] = "dynamic", + [WIN_CRT_STATIC] = "static", +}; + +static const char *optsizes[3] = { + [SIZE_OPTIMIZATION_NONE] = "none", + [SIZE_OPTIMIZATION_SMALL] = "small", + [SIZE_OPTIMIZATION_TINY] = "tiny", +}; + +static const char *on_off[2] = { + [SAFETY_OFF] = "no", + [SAFETY_ON] = "yes", +}; + +static const char *riscv_capability[3] = { + [RISCVFLOAT_NONE] = "none", + [RISCVFLOAT_FLOAT] = "float", + [RISCVFLOAT_DOUBLE] = "double", +}; + +static const char *fp_math[3] = { + [FP_STRICT] = "strict", + [FP_RELAXED] = "relaxed", + [FP_FAST] = "fast", +}; + +static const char *x86_vector_capability[6] = { + [X86VECTOR_NONE] = "none", + [X86VECTOR_MMX] = "mmx", + [X86VECTOR_SSE] = "sse", + [X86VECTOR_AVX] = "avx", + [X86VECTOR_AVX512] = "avx512", + [X86VECTOR_NATIVE] = "native" +}; + +static const char *optlevels[4] = { + [OPTIMIZATION_NONE] = "none", + [OPTIMIZATION_LESS] = "less", + [OPTIMIZATION_MORE] = "more", + [OPTIMIZATION_AGGRESSIVE] = "max", +}; + +static const char *reloc_models[5] = { + [RELOC_NONE] = "none", + [RELOC_SMALL_PIC] = "pic", + [RELOC_BIG_PIC] = "PIC", + [RELOC_SMALL_PIE] = "pie", + [RELOC_BIG_PIE] = "PIE", +}; + Project *project_load(void); BuildTarget *project_select_target(Project *project, const char *optional_target); - +void update_feature_flags(const char ***flags, const char ***removed_flag, const char *arg, bool add); diff --git a/src/build/build_options.c b/src/build/build_options.c index 040a940c8..c704904ba 100644 --- a/src/build/build_options.c +++ b/src/build/build_options.c @@ -1,17 +1,8 @@ -// Copyright (c) 2019 Christoffer Lerno. All rights reserved. +// Copyright (c) 2019-2023 Christoffer Lerno. All rights reserved. // Use of this source code is governed by the GNU LGPLv3.0 license // a copy of which can be found in the LICENSE file. -#include "build_options.h" -#include -#include -#include -#ifndef _MSC_VER -#include -#endif -#include -#include -#include +#include "build_internal.h" #include "../utils/whereami.h" extern int llvm_version_major; @@ -24,30 +15,30 @@ extern const char* llvm_version; extern const char* llvm_target; char *arch_os_target[ARCH_OS_TARGET_LAST + 1] = { - [ELF_AARCH64] = "elf-aarch64", - [ELF_RISCV32] = "elf-riscv32", - [ELF_RISCV64] = "elf-riscv64", - [ELF_X86] = "elf-x86", - [ELF_X64] = "elf-x64", - [FREEBSD_X86] = "freebsd-x86", - [FREEBSD_X64] = "freebsd-x64", - [LINUX_AARCH64] = "linux-aarch64", - [LINUX_RISCV32] = "linux-riscv32", - [LINUX_RISCV64] = "linux-riscv64", - [LINUX_X86] = "linux-x86", - [LINUX_X64] = "linux-x64", - [MACOS_AARCH64] = "macos-aarch64", - [MACOS_X64] = "macos-x64", - [MCU_X86] = "mcu-x86", - [MINGW_X64] = "mingw-x64", - [NETBSD_X86] = "netbsd-x86", - [NETBSD_X64] = "netbsd-x64", - [OPENBSD_X86] = "openbsd-x86", - [OPENBSD_X64] = "openbsd-x64", - [WASM32] = "wasm32", - [WASM64] = "wasm64", - [WINDOWS_AARCH64] = "windows-aarch64", - [WINDOWS_X64] = "windows-x64", + [ELF_AARCH64] = "elf-aarch64", + [ELF_RISCV32] = "elf-riscv32", + [ELF_RISCV64] = "elf-riscv64", + [ELF_X86] = "elf-x86", + [ELF_X64] = "elf-x64", + [FREEBSD_X86] = "freebsd-x86", + [FREEBSD_X64] = "freebsd-x64", + [LINUX_AARCH64] = "linux-aarch64", + [LINUX_RISCV32] = "linux-riscv32", + [LINUX_RISCV64] = "linux-riscv64", + [LINUX_X86] = "linux-x86", + [LINUX_X64] = "linux-x64", + [MACOS_AARCH64] = "macos-aarch64", + [MACOS_X64] = "macos-x64", + [MCU_X86] = "mcu-x86", + [MINGW_X64] = "mingw-x64", + [NETBSD_X86] = "netbsd-x86", + [NETBSD_X64] = "netbsd-x64", + [OPENBSD_X86] = "openbsd-x86", + [OPENBSD_X64] = "openbsd-x64", + [WASM32] = "wasm32", + [WASM64] = "wasm64", + [WINDOWS_AARCH64] = "windows-aarch64", + [WINDOWS_X64] = "windows-x64", }; #define EOUTPUT(string, ...) fprintf(stderr, string "\n", ##__VA_ARGS__) @@ -404,29 +395,40 @@ static void add_linker_arg(BuildOptions *options, const char *arg) options->linker_args[options->linker_arg_count++] = arg; } +/** + * Update feature flags, adding to one list and removing it from the other. + * @param flags the "add" flags + * @param removed_flags the "undef" flags + * @param arg the argument to add or undef + * @param add true if we add, false to undef + */ void update_feature_flags(const char ***flags, const char ***removed_flags, const char *arg, bool add) { - const char **to_remove_from = add ? *removed_flags : *flags; - unsigned len = vec_size(to_remove_from); - // Remove if it's in there. - for (unsigned i = 0; i < len; i++) - { - if (str_eq(to_remove_from[i], arg)) + // We keep two lists "remove" and "add" lists: + const char ***to_remove_from = add ? removed_flags : flags; + + // Remove from opposite list using string equality + // More elegant would be using a Set or Map, but that's overkill + // for something that's likely just 1-2 values. + FOREACH_BEGIN_IDX(i, const char *value, *to_remove_from) + if (str_eq(value, arg)) { - vec_erase_ptr_at(to_remove_from, i); + vec_erase_ptr_at(*to_remove_from, i); break; } - } + FOREACH_END(); + + // First we check that it's not in the list const char ***to_add_to_ref = add ? flags : removed_flags; - unsigned add_len = vec_size(*to_add_to_ref); - for (unsigned i = 0; i < add_len; i++) - { - if (str_eq((*to_add_to_ref)[i], arg)) return; - } + FOREACH_BEGIN(const char *value, *to_add_to_ref) + // If we have a match, we don't add it. + if (str_eq(value, arg)) return; + FOREACH_END(); + + // No match, so add it. vec_add(*to_add_to_ref, arg); } - static int parse_multi_option(const char *start, unsigned count, const char** elements) { const char *arg = current_arg; @@ -1062,7 +1064,7 @@ BuildOptions parse_arguments(int argc, const char *argv[]) parse_command(&build_options); continue; } - if (command_is_projectless(build_options.command) || build_options.command == COMMAND_GENERATE_HEADERS) + if (command_accepts_files(build_options.command) || build_options.command == COMMAND_GENERATE_HEADERS) { append_file(&build_options); continue; diff --git a/src/build/builder.c b/src/build/builder.c index 363f18f85..cc04405ed 100644 --- a/src/build/builder.c +++ b/src/build/builder.c @@ -1,8 +1,7 @@ -// Copyright (c) 2019 Christoffer Lerno. All rights reserved. +// Copyright (c) 2019-2023 Christoffer Lerno. All rights reserved. // Use of this source code is governed by a LGPLv3.0 // a copy of which can be found in the LICENSE file. #include "build_internal.h" -#include "build_options.h" void load_library_files(void) {} @@ -60,7 +59,7 @@ ArchOsTarget default_target = ELF_RISCV64; ArchOsTarget default_target = ARCH_OS_TARGET_DEFAULT; #endif -bool command_is_projectless(CompilerCommand command) +bool command_accepts_files(CompilerCommand command) { switch (command) { @@ -306,7 +305,7 @@ static void update_build_target_from_options(BuildTarget *target, BuildOptions * { target->feature.riscv_float_capability = options->riscv_float_capability; } - if (command_is_projectless(options->command)) + if (command_accepts_files(options->command)) { target->build_dir = options->build_dir ? options->build_dir : NULL; target->object_file_dir = options->obj_out ? options->obj_out : target->build_dir; diff --git a/src/build/project.c b/src/build/project.c index 7d90f9d5c..97914c95a 100644 --- a/src/build/project.c +++ b/src/build/project.c @@ -1,4 +1,4 @@ -// Copyright (c) 2020 Christoffer Lerno. All rights reserved. +// Copyright (c) 2020-2023 Christoffer Lerno. All rights reserved. // Use of this source code is governed by a LGPLv3.0 // a copy of which can be found in the LICENSE file. @@ -6,111 +6,110 @@ #include "build_internal.h" #define MAX_SYMTAB_SIZE (1024 * 1024) - const char *project_default_keys[] = { - "authors", - "benchfn", - "c-sources", - "cc", - "cflags", - "cpu", - "debug-info", - "dependencies", - "dependency-search-paths", - "features", - "fp-math", - "langrev", - "linked-libraries", - "linker-search-paths", - "link-args", - "link-libc", - "macossdk", - "memory-env", - "no-entry", - "opt", - "optlevel", - "optsize", - "output", - "panicfn", - "reloc", - "safe", - "single-module", - "soft-float", - "sources", - "strip-unused", - "symtab", - "system-linker", - "target", - "targets", - "testfn", - "trap-on-wrap", - "use-stdlib", - "version", - "warnings", - "wincrt", - "winsdk", - "x86cpu", - "x86vec", - "x86-stack-struct-return", + "authors", + "benchfn", + "c-sources", + "cc", + "cflags", + "cpu", + "debug-info", + "dependencies", + "dependency-search-paths", + "features", + "fp-math", + "langrev", + "linked-libraries", + "linker-search-paths", + "link-args", + "link-libc", + "macossdk", + "memory-env", + "no-entry", + "opt", + "optlevel", + "optsize", + "output", + "panicfn", + "reloc", + "safe", + "single-module", + "soft-float", + "sources", + "strip-unused", + "symtab", + "system-linker", + "target", + "targets", + "testfn", + "trap-on-wrap", + "use-stdlib", + "version", + "warnings", + "wincrt", + "winsdk", + "x86cpu", + "x86vec", + "x86-stack-struct-return", }; -const int project_default_keys_count = sizeof(project_default_keys) / sizeof(char*); +const int project_default_keys_count = ELEMENTLEN(project_default_keys); const char* project_target_keys[] = { - "benchfn", - "c-sources-add", - "c-sources-override", - "cc", - "cflags-add", - "cflags-override", - "cpu", - "debug-info", - "dependencies-add", - "dependencies-override", - "dependency-search-paths-add", - "dependency-search-paths-override", - "features", - "fp-math", - "langrev", - "linked-libraries-add", - "linked-libraries-override", - "linker-search-paths-add", - "linker-search-paths-override", - "link-args-add", - "link-args-override", - "link-libc", - "macossdk", - "memory-env", - "no-entry", - "opt", - "optlevel", - "optsize", - "output" - "panicfn", - "reloc", - "safe", - "single-module", - "soft-float", - "sources-add", - "sources-override", - "strip-unused", - "symtab", - "system-linker", - "target", - "testfn", - "trap-on-wrap", - "type", - "use-stdlib", - "version", - "warnings", - "wincrt", - "winsdk", - "x86cpu", - "x86vec", - "x86-stack-struct-return", + "benchfn", + "c-sources-add", + "c-sources-override", + "cc", + "cflags-add", + "cflags-override", + "cpu", + "debug-info", + "dependencies-add", + "dependencies-override", + "dependency-search-paths-add", + "dependency-search-paths-override", + "features", + "fp-math", + "langrev", + "linked-libraries-add", + "linked-libraries-override", + "linker-search-paths-add", + "linker-search-paths-override", + "link-args-add", + "link-args-override", + "link-libc", + "macossdk", + "memory-env", + "no-entry", + "opt", + "optlevel", + "optsize", + "output" + "panicfn", + "reloc", + "safe", + "single-module", + "soft-float", + "sources-add", + "sources-override", + "strip-unused", + "symtab", + "system-linker", + "target", + "testfn", + "trap-on-wrap", + "type", + "use-stdlib", + "version", + "warnings", + "wincrt", + "winsdk", + "x86cpu", + "x86vec", + "x86-stack-struct-return", }; -const int project_target_keys_count = sizeof(project_target_keys) / sizeof(char*); +const int project_target_keys_count = ELEMENTLEN(project_target_keys); const char *get_valid_string(JSONObject *table, const char *key, const char *category, bool mandatory) { @@ -252,11 +251,11 @@ static void load_into_build_target(JSONObject *json, const char *type, BuildTarg { if (is_default) { - check_json_keys(project_default_keys, sizeof(project_default_keys) / sizeof(char*), json, type); + check_json_keys(project_default_keys, project_default_keys_count, json, type); } else { - check_json_keys(project_target_keys, sizeof(project_target_keys) / sizeof(char*), json, type); + check_json_keys(project_target_keys, project_target_keys_count, json, type); } const char *cc = get_valid_string(json, "cc", type, false); if (cc) target->cc = cc; @@ -315,26 +314,15 @@ static void load_into_build_target(JSONObject *json, const char *type, BuildTarg [DEBUG_INFO_NONE] = "none", [DEBUG_INFO_LINE_TABLES] = "line-tables" }; - DebugInfo info = get_valid_string_setting(json, "debug-info", type, debug_infos, 0, 3, "one of 'full' 'line-table' or 'none'."); + DebugInfo info = get_valid_string_setting(json, "debug-info", type, debug_infos, 0, ELEMENTLEN(debug_infos), "one of 'full' 'line-table' or 'none'."); if (info > -1) target->debug_info = info; // Optimization Level - static const char *opt_level_settings[4] = { - [OPTIMIZATION_NONE] = "none", - [OPTIMIZATION_LESS] = "less", - [OPTIMIZATION_MORE] = "more", - [OPTIMIZATION_AGGRESSIVE] = "max", - }; - OptimizationLevel optlevel = (OptimizationLevel)get_valid_string_setting(json, "optlevel", type, opt_level_settings, 0, 4, "`none`, `less`, `more`, `max`."); + OptimizationLevel optlevel = (OptimizationLevel)get_valid_string_setting(json, "optlevel", type, optlevels, 0, ELEMENTLEN(optlevels), "`none`, `less`, `more`, `max`."); target->optlevel = optlevel; - // Size optimization Level - static const char *opt_size_settings[3] = { - [SIZE_OPTIMIZATION_NONE] = "none", - [SIZE_OPTIMIZATION_SMALL] = "small", - [SIZE_OPTIMIZATION_TINY] = "tiny", - }; - SizeOptimizationLevel optsize = (SizeOptimizationLevel)get_valid_string_setting(json, "optsize", type, opt_size_settings, 0, 4, "`none`, `small`, `tiny`."); + // Size optimization + SizeOptimizationLevel optsize = (SizeOptimizationLevel)get_valid_string_setting(json, "optsize", type, optsizes, 0, ELEMENTLEN(optlevels), "`none`, `small`, `tiny`."); target->optsize = optsize; static const char *opt_settings[8] = { @@ -347,7 +335,7 @@ static void load_into_build_target(JSONObject *json, const char *type, BuildTarg [OPT_SETTING_OSMALL] = "Os", [OPT_SETTING_OTINY] = "Oz" }; - OptimizationSetting opt = (OptimizationSetting)get_valid_string_setting(json, "opt", type, opt_settings, 0, 8, "'O0', 'O1' etc."); + OptimizationSetting opt = (OptimizationSetting)get_valid_string_setting(json, "opt", type, opt_settings, 0, ELEMENTLEN(opt_settings), "'O0', 'O1' etc."); update_build_target_with_opt_level(target, opt); // Safety level @@ -356,7 +344,8 @@ static void load_into_build_target(JSONObject *json, const char *type, BuildTarg // Single module target->single_module = (SingleModule)get_valid_bool(json, "single-module", type, target->single_module); - MemoryEnvironment env = get_valid_string_setting(json, "memory-env", type, memory_environment, 0, 4, "one of 'normal', 'small', 'tiny' or 'none'."); + // Memory environment for memory constrained environments. + MemoryEnvironment env = get_valid_string_setting(json, "memory-env", type, memory_environment, 0, ELEMENTLEN(memory_environment), "one of 'normal', 'small', 'tiny' or 'none'."); if (env > -1) target->memory_environment = env; // Symtab @@ -384,20 +373,19 @@ static void load_into_build_target(JSONObject *json, const char *type, BuildTarg } // Reloc - int reloc = get_valid_string_setting(json, "reloc", type, reloc_models, 0, 5, "'none', 'pic', 'PIC', 'pie' or 'PIE'."); + int reloc = get_valid_string_setting(json, "reloc", type, reloc_models, 0, ELEMENTLEN(reloc_models), "'none', 'pic', 'PIC', 'pie' or 'PIE'."); if (reloc > -1) target->reloc_model = (RelocModel)reloc; - // Cpu const char *cpu = get_valid_string(json, "cpu", type, false); if (cpu) target->cpu = cpu; // WinCRT - int wincrt = get_valid_string_setting(json, "wincrt", type, wincrt_linking, 0, 5, "'none', 'static' or 'dynamic'."); + int wincrt = get_valid_string_setting(json, "wincrt", type, wincrt_linking, 0, ELEMENTLEN(wincrt_linking), "'none', 'static' or 'dynamic'."); if (wincrt > -1) target->win.crt_linking = (WinCrtLinking)wincrt; // fp-math - int fpmath = get_valid_string_setting(json, "fp-math", type, fp_math, 0, 3, "`strict`, `relaxed` or `fast`."); + int fpmath = get_valid_string_setting(json, "fp-math", type, fp_math, 0, ELEMENTLEN(fp_math), "`strict`, `relaxed` or `fast`."); if (fpmath > -1) target->feature.fp_math = fpmath; const char **features = get_valid_array(json, "features", type, false); @@ -413,15 +401,15 @@ static void load_into_build_target(JSONObject *json, const char *type, BuildTarg } // x86vec - int x86vec = get_valid_string_setting(json, "x86vec", type, x86_vector_capability, 0, 6, "`none`, `native`, `mmx`, `sse`, `avx` or `avx512`."); + int x86vec = get_valid_string_setting(json, "x86vec", type, x86_vector_capability, 0, ELEMENTLEN(x86_vector_capability), "`none`, `native`, `mmx`, `sse`, `avx` or `avx512`."); if (x86vec > -1) target->feature.x86_vector_capability = x86vec; // x86vec - int x86cpu = get_valid_string_setting(json, "x86cpu", type, x86_cpu_set, 0, 8, "`baseline`, `ssse3`, `sse4`, `avx1`, `avx2-v1`, `avx2-v2`, `avx512` or `native`."); + int x86cpu = get_valid_string_setting(json, "x86cpu", type, x86_cpu_set, 0, ELEMENTLEN(x86_cpu_set), "`baseline`, `ssse3`, `sse4`, `avx1`, `avx2-v1`, `avx2-v2`, `avx512` or `native`."); if (x86cpu > -1) target->feature.x86_cpu_set = x86cpu; // riscvfloat - int riscv_float = get_valid_string_setting(json, "riscvfloat", type, riscv_capability, 0, 3, "`none`, `float` or `double`."); + int riscv_float = get_valid_string_setting(json, "riscvfloat", type, riscv_capability, 0, ELEMENTLEN(riscv_capability), "`none`, `float` or `double`."); if (riscv_float > -1) target->feature.riscv_float_capability = riscv_float; // winsdk @@ -515,19 +503,22 @@ static void project_add_target(Project *project, BuildTarget *default_target, J static void project_add_targets(Project *project, JSONObject *project_data) { assert(project_data->type == J_OBJECT); - static const char* targets[6] = { [TARGET_TYPE_EXECUTABLE] = "executable", - [TARGET_TYPE_STATIC_LIB] = "static-lib", - [TARGET_TYPE_DYNAMIC_LIB] = "dynamic-lib", - [TARGET_TYPE_BENCHMARK] = "benchmark", - [TARGET_TYPE_TEST] = "test", - [TARGET_TYPE_OBJECT_FILES] = "object-files"}; + static const char* targets[6] = { + [TARGET_TYPE_EXECUTABLE] = "executable", + [TARGET_TYPE_STATIC_LIB] = "static-lib", + [TARGET_TYPE_DYNAMIC_LIB] = "dynamic-lib", + [TARGET_TYPE_BENCHMARK] = "benchmark", + [TARGET_TYPE_TEST] = "test", + [TARGET_TYPE_OBJECT_FILES] = "object-files" + }; static const char *target_desc[6] = { [TARGET_TYPE_EXECUTABLE] = "Executable", [TARGET_TYPE_STATIC_LIB] = "Static library", [TARGET_TYPE_DYNAMIC_LIB] = "Dynamic library", [TARGET_TYPE_BENCHMARK] = "benchmark suite", [TARGET_TYPE_TEST] = "test suite", - [TARGET_TYPE_OBJECT_FILES] = "object files"}; + [TARGET_TYPE_OBJECT_FILES] = "object files" + }; BuildTarget default_target = default_build_target; load_into_build_target(project_data, "default target", &default_target, true); @@ -548,12 +539,19 @@ static void project_add_targets(Project *project, JSONObject *project_data) { error_exit("Invalid data in target '%s'", key); } - int type = get_valid_string_setting(object, "type", "Target type", targets, 0, 5, "a target type like 'executable' or 'static-lib'"); + int type = get_valid_string_setting(object, "type", "Target type", targets, 0, ELEMENTLEN(targets), "a target type like 'executable' or 'static-lib'"); if (type < 0) error_exit("Target %s did not contain 'type' key.", key); project_add_target(project, &default_target, object, key, target_desc[type], type); } } +/** + * Grab the default target, this will be the executable if one exists, otherwise + * it's the first target in the list. + * + * @param project + * @return the selected build target. + */ static BuildTarget *project_select_default_target(Project *project) { VECEACH(project->targets, i) @@ -564,6 +562,14 @@ static BuildTarget *project_select_default_target(Project *project) return project->targets[0]; } +/** + * Select the project target. This may be given a target, if so it is looked for. + * If the project has no targets, or the optional target can't be found, issue an error. + * + * @param project the project to look in. + * @param optional_target the selected target, may be NULL. + * @return the target if one is provided, otherwise the default target. + */ BuildTarget *project_select_target(Project *project, const char *optional_target) { if (!vec_size(project->targets)) @@ -577,7 +583,7 @@ BuildTarget *project_select_target(Project *project, const char *optional_target VECEACH(project->targets, i) { BuildTarget *target = project->targets[i]; - if (strcmp(target->name, optional_target) == 0) return target; + if (str_eq(target->name, optional_target)) return target; } error_exit("No build target named '%s' was found in %s. Was it misspelled?", optional_target, PROJECT_JSON); } diff --git a/src/build/project_creation.c b/src/build/project_creation.c index 49da2ac00..d5ca27366 100644 --- a/src/build/project_creation.c +++ b/src/build/project_creation.c @@ -1,15 +1,8 @@ -// Copyright (c) 2019 Christoffer Lerno. All rights reserved. +// Copyright (c) 2019-2023 Christoffer Lerno. All rights reserved. // Use of this source code is governed by the GNU LGPLv3.0 license // a copy of which can be found in the LICENSE file. -#include -#include -#ifndef _MSC_VER -#include -#endif -#include "project_creation.h" -#include "build_options.h" -#include "../utils/lib.h" +#include "build_internal.h" const char* JSON_EXE = "{\n" diff --git a/src/build/project_creation.h b/src/build/project_creation.h deleted file mode 100644 index f25f0029a..000000000 --- a/src/build/project_creation.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -// Copyright (c) 2019 Christoffer Lerno. All rights reserved. -// Use of this source code is governed by the GNU LGPLv3.0 license -// a copy of which can be found in the LICENSE file. - -struct BuildOptions_; -void create_project(struct BuildOptions_ *build_options); diff --git a/src/compiler/asm_target.c b/src/compiler/asm_target.c index 03695e771..cb7615dfe 100644 --- a/src/compiler/asm_target.c +++ b/src/compiler/asm_target.c @@ -1,4 +1,4 @@ -// Copyright (c) 2022 Christoffer Lerno. All rights reserved. +// Copyright (c) 2022-2023 Christoffer Lerno. All rights reserved. // Use of this source code is governed by a LGPLv3.0 // a copy of which can be found in the LICENSE file. #include "compiler_internal.h" diff --git a/src/compiler/compiler.h b/src/compiler/compiler.h index 6bad80128..dc7ac2446 100644 --- a/src/compiler/compiler.h +++ b/src/compiler/compiler.h @@ -1,11 +1,11 @@ #pragma once - -#include "build/build_options.h" - -// Copyright (c) 2019 Christoffer Lerno. All rights reserved. +// Copyright (c) 2019-2023 Christoffer Lerno. All rights reserved. // Use of this source code is governed by the GNU LGPLv3.0 license // a copy of which can be found in the LICENSE file. +#include "build/build.h" + + void compiler_init(const char *std_lib_dir); void compile(); void compile_target(BuildOptions *options); diff --git a/src/compiler/compiler_internal.h b/src/compiler/compiler_internal.h index 1746b3fbd..8e3ff6108 100644 --- a/src/compiler/compiler_internal.h +++ b/src/compiler/compiler_internal.h @@ -4,14 +4,13 @@ #include "../utils/common.h" #include "../utils/lib.h" -#include "../build/build_options.h" +#include "../build/build.h" #include "compiler.h" #include "enums.h" #include "target.h" #include "utils/malloc.h" #include - typedef double Real; #define MAX_ARRAYINDEX INT32_MAX diff --git a/src/main.c b/src/main.c index dc464e0d7..4c177bef9 100644 --- a/src/main.c +++ b/src/main.c @@ -1,7 +1,6 @@ #include #include "compiler/compiler.h" -#include "build/build_options.h" -#include "build/project_creation.h" +#include "build/build.h" #include "compiler_tests/tests.h" #include "utils/lib.h" diff --git a/src/utils/common.h b/src/utils/common.h index 56fb9cc9d..f46685bc3 100644 --- a/src/utils/common.h +++ b/src/utils/common.h @@ -13,6 +13,9 @@ #include #include #include +#ifndef _MSC_VER +#include +#endif #define NO_ARENA 0 #define MAX_VECTOR_WIDTH 65536 @@ -20,7 +23,6 @@ #define MAX_SOURCE_LOCATION_LEN 255 #define PROJECT_JSON "project.json" - #if defined( _WIN32 ) || defined( __WIN32__ ) || defined( _WIN64 ) #define PLATFORM_WINDOWS 1 #define PLATFORM_POSIX 0 diff --git a/src/utils/lib.h b/src/utils/lib.h index 679b87c3d..9978770ec 100644 --- a/src/utils/lib.h +++ b/src/utils/lib.h @@ -15,6 +15,7 @@ const char *download_file(const char *url, const char *resource, const char *file_path); #endif +#define ELEMENTLEN(x) (sizeof(x) / sizeof(x[0])) extern const char *compiler_exe_name; typedef struct StringSlice_ diff --git a/src/version.h b/src/version.h index 45705f8a8..f02d05667 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define COMPILER_VERSION "0.4.658" \ No newline at end of file +#define COMPILER_VERSION "0.4.659" \ No newline at end of file