From 735a02bab320b75a20ed1fa822a4ee20de3267f7 Mon Sep 17 00:00:00 2001 From: JaDogg Date: Fri, 30 Aug 2024 18:53:45 +0100 Subject: [PATCH] feat(carpntr): add c compiler select feature to carpntr --- compiler/carpntr/main.yaka | 54 ++++++++++++++---- compiler/carpntr/main.yaka.c | 85 ++++++++++++++++++++++++---- compiler/carpntr/raylib_support.yaka | 2 +- 3 files changed, 119 insertions(+), 22 deletions(-) diff --git a/compiler/carpntr/main.yaka b/compiler/carpntr/main.yaka index 371c5a25..d6950a62 100644 --- a/compiler/carpntr/main.yaka +++ b/compiler/carpntr/main.yaka @@ -5,36 +5,36 @@ # Note: libs - MIT license, runtime/3rd - various # ============================================================================================== # GPLv3: -# +# # Yaksha - Programming Language. # Copyright (C) 2020 - 2024 Bhathiya Perera -# +# # This program is free software: you can redistribute it and/or modify it under the terms # of the GNU General Public License as published by the Free Software Foundation, # either version 3 of the License, or (at your option) any later version. -# +# # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY # or FITNESS FOR A PARTICULAR PURPOSE. # See the GNU General Public License for more details. -# +# # You should have received a copy of the GNU General Public License along with this program. # If not, see https://www.gnu.org/licenses/. -# +# # ============================================================================================== # Additional Terms: -# +# # Please note that any commercial use of the programming language's compiler source code # (everything except compiler/runtime, compiler/libs and compiler/3rd) require a written agreement # with author of the language (Bhathiya Perera). -# +# # If you are using it for an open source project, please give credits. # Your own project must use GPLv3 license with these additional terms. -# +# # You may use programs written in Yaksha/YakshaLisp for any legal purpose # (commercial, open-source, closed-source, etc) as long as it agrees # to the licenses of linked runtime libraries (see compiler/runtime/README.md). -# +# # ============================================================================================== import libs import libs.os @@ -49,6 +49,11 @@ import libs.argparse import configuration as carp import building +enum Comp: + GCC + CLANG + ZIG + def print_banner() -> None: # This just print a banner art: str = """ @@ -146,10 +151,23 @@ def perform_build() -> int: ret: int = build_from_config(config, False, False) return ret -def perform_mini_build(filename: str, use_raylib: bool, use_web: bool, wasm4: bool, web_shell: str, asset_path: str, silent: bool, actually_run: bool, crdll: bool, no_parallel: bool) -> int: +def perform_mini_build(filename: str, use_raylib: bool, use_web: bool, wasm4: bool, web_shell: str, asset_path: str, silent: bool, actually_run: bool, crdll: bool, no_parallel: bool, comp: Comp) -> int: # Perform single file project build and execute binary name: str = path.remove_extension(path.basename(filename)) config: carp.Config = carp.create_adhoc_config(name, filename, use_raylib, use_web, wasm4, web_shell, asset_path, crdll, no_parallel) + # Pick compiler based on the input argument + if comp == Comp.GCC: + config.use_alt_compiler = True + config.alt_compiler = carp.GCC + if config.gcc_compiler_path == "": + println("GCC compiler not found.") + return -1 + elif comp == Comp.CLANG: + config.use_alt_compiler = True + config.alt_compiler = carp.CLANG + if config.clang_compiler_path == "": + println("Clang compiler not found.") + return -1 defer carp.del_config(config) if len(config.errors) > 0: print_errors(config.errors) @@ -207,6 +225,9 @@ def handle_args(args: os.Arguments) -> int: wasm4: int = 0 silent_mode: int = 0 no_parallel: int = 0 + use_gcc: int = 0 + use_clang: int = 0 + use_zig: int = 0 file_path: c.CStr = strings.null_cstr() assets_path: c.CStr = strings.null_cstr() web_shell: str = "" @@ -222,6 +243,9 @@ def handle_args(args: os.Arguments) -> int: arrput(options, argparse.opt_boolean("4", "wasm4", getref(wasm4), "wasm4 build")) arrput(options, argparse.opt_boolean("S", "silent", getref(silent_mode), "do not print anything except errors")) arrput(options, argparse.opt_boolean("N", "nothread", getref(no_parallel), "no parallel build & disable optimization (for debugging)")) + arrput(options, argparse.opt_boolean("\0", "gcc", getref(use_gcc), "use gcc")) + arrput(options, argparse.opt_boolean("\0", "clang", getref(use_clang), "use clang")) + arrput(options, argparse.opt_boolean("\0", "zig", getref(use_zig), "use zig (this is the default behavior)")) arrput(options, argparse.opt_end()) a: argparse.ArgParseWrapper = argparse.new(options, usages) @@ -243,6 +267,14 @@ def handle_args(args: os.Arguments) -> int: return 1 single_file: str = remainder.remainder[0] + if (use_zig + use_clang + use_gcc) > 1: + println("Multiple compilers selected. Please select only one.") + return 1 + comp: Comp = Comp.ZIG + if use_clang == 1: + comp = Comp.CLANG + elif use_gcc == 1: + comp = Comp.GCC if wasm4 == 1 and (raylib == 1 or web == 1): println("Wasm4 is not compatible with raylib/web") return 1 @@ -267,7 +299,7 @@ def handle_args(args: os.Arguments) -> int: assets_path_s = strings.from_cstr(assets_path) print("Using asset-path:") println(assets_path_s) - return perform_mini_build(single_file, raylib == 1, web == 1, wasm4 == 1, web_shell, assets_path_s, silent_mode == 1, run == 1, crdll == 1, no_parallel == 1) + return perform_mini_build(single_file, raylib == 1, web == 1, wasm4 == 1, web_shell, assets_path_s, silent_mode == 1, run == 1, crdll == 1, no_parallel == 1, comp) console.red("Invalid usage. Please use '-R' option if you want to run a program. Try 'carpntr --help' for more information.\n") return 0 diff --git a/compiler/carpntr/main.yaka.c b/compiler/carpntr/main.yaka.c index d9b16f01..b833e669 100644 --- a/compiler/carpntr/main.yaka.c +++ b/compiler/carpntr/main.yaka.c @@ -264,7 +264,7 @@ void yy__printkv(yk__sds, yk__sds); void yy__print_config(struct yy__configuration_Config*); int32_t yy__build_from_config(struct yy__configuration_Config*, bool, bool); int32_t yy__perform_build(); -int32_t yy__perform_mini_build(yk__sds, bool, bool, bool, yk__sds, yk__sds, bool, bool, bool, bool); +int32_t yy__perform_mini_build(yk__sds, bool, bool, bool, yk__sds, yk__sds, bool, bool, bool, bool, int32_t); int32_t yy__handle_args(yy__os_Arguments); int32_t yy__main(); struct yy__raylib_support_CObject* yy__raylib_support_fill_arguments(yk__sds yy__raylib_support_src_path, struct yy__raylib_support_CObject* yy__raylib_support_c, bool yy__raylib_support_dll) @@ -469,19 +469,17 @@ yk__sds* yy__raylib_support_get_external_libs() if (yy__os_is_macos()) { yk__sds* t__26 = NULL; - yk__arrsetcap(t__26, 12); + yk__arrsetcap(t__26, 10); yk__arrput(t__26, yk__sdsnewlen("-framework", 10)); yk__arrput(t__26, yk__sdsnewlen("Foundation", 10)); yk__arrput(t__26, yk__sdsnewlen("-framework", 10)); - yk__arrput(t__26, yk__sdsnewlen("OpenGL", 6)); + yk__arrput(t__26, yk__sdsnewlen("CoreServices", 12)); yk__arrput(t__26, yk__sdsnewlen("-framework", 10)); - yk__arrput(t__26, yk__sdsnewlen("OpenAL", 6)); + yk__arrput(t__26, yk__sdsnewlen("CoreGraphics", 12)); yk__arrput(t__26, yk__sdsnewlen("-framework", 10)); - yk__arrput(t__26, yk__sdsnewlen("IOKit", 5)); - yk__arrput(t__26, yk__sdsnewlen("-framework", 10)); - yk__arrput(t__26, yk__sdsnewlen("CoreVideo", 9)); + yk__arrput(t__26, yk__sdsnewlen("AppKit", 6)); yk__arrput(t__26, yk__sdsnewlen("-framework", 10)); - yk__arrput(t__26, yk__sdsnewlen("Cocoa", 5)); + yk__arrput(t__26, yk__sdsnewlen("IOKit", 5)); yy__raylib_support_external_libs = t__26; } else @@ -3834,12 +3832,47 @@ int32_t yy__perform_build() yy__configuration_del_config(yy__config); return t__5; } -int32_t yy__perform_mini_build(yk__sds yy__filename, bool yy__use_raylib, bool yy__use_web, bool yy__wasm4, yk__sds yy__web_shell, yk__sds yy__asset_path, bool yy__silent, bool yy__actually_run, bool yy__crdll, bool yy__no_parallel) +int32_t yy__perform_mini_build(yk__sds yy__filename, bool yy__use_raylib, bool yy__use_web, bool yy__wasm4, yk__sds yy__web_shell, yk__sds yy__asset_path, bool yy__silent, bool yy__actually_run, bool yy__crdll, bool yy__no_parallel, int32_t yy__comp) { yk__sds t__6 = yy__path_basename(yk__sdsdup(yy__filename)); yk__sds t__7 = yy__path_remove_extension(yk__sdsdup(t__6)); yk__sds yy__name = yk__sdsdup(t__7); struct yy__configuration_Config* yy__config = yy__configuration_create_adhoc_config(yk__sdsdup(yy__name), yk__sdsdup(yy__filename), yy__use_raylib, yy__use_web, yy__wasm4, yk__sdsdup(yy__web_shell), yk__sdsdup(yy__asset_path), yy__crdll, yy__no_parallel); + if (yy__comp == 0) + { + yy__config->yy__configuration_use_alt_compiler = true; + yy__config->yy__configuration_alt_compiler = yy__configuration_GCC; + if (yk__cmp_sds_lit(yy__config->yy__configuration_gcc_compiler_path, "", 11) == 0) + { + yk__printlnstr("GCC compiler not found."); + yk__sdsfree(yy__name); + yk__sdsfree(t__7); + yk__sdsfree(t__6); + yk__sdsfree(yy__asset_path); + yk__sdsfree(yy__web_shell); + yk__sdsfree(yy__filename); + return INT32_C(-1); + } + } + else + { + if (yy__comp == 1) + { + yy__config->yy__configuration_use_alt_compiler = true; + yy__config->yy__configuration_alt_compiler = yy__configuration_CLANG; + if (yk__cmp_sds_lit(yy__config->yy__configuration_clang_compiler_path, "", 11) == 0) + { + yk__printlnstr("Clang compiler not found."); + yk__sdsfree(yy__name); + yk__sdsfree(t__7); + yk__sdsfree(t__6); + yk__sdsfree(yy__asset_path); + yk__sdsfree(yy__web_shell); + yk__sdsfree(yy__filename); + return INT32_C(-1); + } + } + } if (yk__arrlen(yy__config->yy__configuration_errors) > INT32_C(0)) { yy__print_errors(yy__config->yy__configuration_errors); @@ -3976,6 +4009,9 @@ int32_t yy__handle_args(yy__os_Arguments yy__args) int32_t yy__wasm4 = INT32_C(0); int32_t yy__silent_mode = INT32_C(0); int32_t yy__no_parallel = INT32_C(0); + int32_t yy__use_gcc = INT32_C(0); + int32_t yy__use_clang = INT32_C(0); + int32_t yy__use_zig = INT32_C(0); yy__c_CStr yy__file_path = yy__strings_null_cstr(); yy__c_CStr yy__assets_path = yy__strings_null_cstr(); yk__sds yy__web_shell = yk__sdsnewlen("" , 0); @@ -3991,6 +4027,9 @@ int32_t yy__handle_args(yy__os_Arguments yy__args) yk__arrput(yy__options, yy__argparse_opt_boolean(yk__sdsnewlen("4", 1), yk__sdsnewlen("wasm4", 5), (&(yy__wasm4)), yk__sdsnewlen("wasm4 build", 11))); yk__arrput(yy__options, yy__argparse_opt_boolean(yk__sdsnewlen("S", 1), yk__sdsnewlen("silent", 6), (&(yy__silent_mode)), yk__sdsnewlen("do not print anything except errors", 35))); yk__arrput(yy__options, yy__argparse_opt_boolean(yk__sdsnewlen("N", 1), yk__sdsnewlen("nothread", 8), (&(yy__no_parallel)), yk__sdsnewlen("no parallel build & disable optimization (for debugging)", 56))); + yk__arrput(yy__options, yy__argparse_opt_boolean(yk__sdsnewlen("\0", 1), yk__sdsnewlen("gcc", 3), (&(yy__use_gcc)), yk__sdsnewlen("use gcc", 7))); + yk__arrput(yy__options, yy__argparse_opt_boolean(yk__sdsnewlen("\0", 1), yk__sdsnewlen("clang", 5), (&(yy__use_clang)), yk__sdsnewlen("use clang", 9))); + yk__arrput(yy__options, yy__argparse_opt_boolean(yk__sdsnewlen("\0", 1), yk__sdsnewlen("zig", 3), (&(yy__use_zig)), yk__sdsnewlen("use zig (this is the default behavior)", 38))); yk__arrput(yy__options, yy__argparse_opt_end()); yy__argparse_ArgParseWrapper yy__a = yy__argparse_new(yy__options, yy__usages); yy__argparse_ArgParseRemainder yy__remainder = yy__argparse_parse(yy__a->state, yy__arguments); @@ -4025,6 +4064,32 @@ int32_t yy__handle_args(yy__os_Arguments yy__args) return INT32_C(1); } yk__sds yy__single_file = yk__sdsdup(yy__remainder->remainder[INT32_C(0)]); + if ((((yy__use_zig + yy__use_clang) + yy__use_gcc)) > INT32_C(1)) + { + yk__printlnstr("Multiple compilers selected. Please select only one."); + yy__strings_del_cstr(yy__file_path); + yy__argparse_del_remainder(yy__remainder); + yy__argparse_del_argparse(yy__a); + yy__array_del_str_array(yy__usages); + yk__arrfree(yy__options); + yy__array_del_str_array(yy__arguments); + yk__sdsfree(yy__single_file); + yk__sdsfree(yy__assets_path_s); + yk__sdsfree(yy__web_shell); + return INT32_C(1); + } + int32_t yy__comp = 2; + if (yy__use_clang == INT32_C(1)) + { + yy__comp = 1; + } + else + { + if (yy__use_gcc == INT32_C(1)) + { + yy__comp = 0; + } + } if ((yy__wasm4 == INT32_C(1)) && (((yy__raylib == INT32_C(1)) || (yy__web == INT32_C(1))))) { yk__printlnstr("Wasm4 is not compatible with raylib/web"); @@ -4115,7 +4180,7 @@ int32_t yy__handle_args(yy__os_Arguments yy__args) yk__printlnstr(yy__assets_path_s); yk__sdsfree(t__21); } - int32_t t__22 = yy__perform_mini_build(yk__sdsdup(yy__single_file), (yy__raylib == INT32_C(1)), (yy__web == INT32_C(1)), (yy__wasm4 == INT32_C(1)), yk__sdsdup(yy__web_shell), yk__sdsdup(yy__assets_path_s), (yy__silent_mode == INT32_C(1)), (yy__run == INT32_C(1)), (yy__crdll == INT32_C(1)), (yy__no_parallel == INT32_C(1))); + int32_t t__22 = yy__perform_mini_build(yk__sdsdup(yy__single_file), (yy__raylib == INT32_C(1)), (yy__web == INT32_C(1)), (yy__wasm4 == INT32_C(1)), yk__sdsdup(yy__web_shell), yk__sdsdup(yy__assets_path_s), (yy__silent_mode == INT32_C(1)), (yy__run == INT32_C(1)), (yy__crdll == INT32_C(1)), (yy__no_parallel == INT32_C(1)), yy__comp); yy__strings_del_cstr(yy__file_path); yy__argparse_del_remainder(yy__remainder); yy__argparse_del_argparse(yy__a); diff --git a/compiler/carpntr/raylib_support.yaka b/compiler/carpntr/raylib_support.yaka index 400c6f04..34659a0b 100644 --- a/compiler/carpntr/raylib_support.yaka +++ b/compiler/carpntr/raylib_support.yaka @@ -165,7 +165,7 @@ def get_external_libs() -> Array[str]: if os.is_windows(): external_libs = array("str", "-lwinmm", "-lgdi32", "-lopengl32") elif os.is_macos(): - external_libs = array("str", "-framework", "Foundation", "-framework", "OpenGL", "-framework", "OpenAL", "-framework", "IOKit", "-framework", "CoreVideo", "-framework", "Cocoa") + external_libs = array("str", "-framework", "Foundation", "-framework", "CoreServices", "-framework", "CoreGraphics", "-framework", "AppKit", "-framework", "IOKit") else: # linux external_libs = array("str", "-lGL", "-lrt", "-ldl", "-lm", "-lX11")