UNIT_NAMES :: string.["raudio", "rcore", "rmodels", "rshapes", "rtext", "rtextures", "utils", "rglfw"]; FILES_TO_COMPILE :: #run -> [UNIT_NAMES.count]string { result: [UNIT_NAMES.count]string; for UNIT_NAMES result[it_index] = sprint("raylib/src/%.c", UNIT_NAMES[it_index]); return result; } CFLAGS :: string.["-w", "-pipe", "-I./src", "-DPLATFORM_DESKTOP", "-D_GLFW_X11"]; #run,stallable generate(); generate :: () { set_build_options_dc(.{do_output=false}); options := get_build_options(); args := options.compile_time_command_line; remove_unneeded_cringe(); if array_find(args, "compile") { success := build_cpp_static_lib("libraylib", ..FILES_TO_COMPILE, debug=true, extra = CFLAGS); if !success { log_error("Building raylib static library failed"); compiler_set_workspace_status(.FAILED); return; } success = build_cpp_dynamic_lib("libraylib", ..FILES_TO_COMPILE, debug=true, extra = CFLAGS); if !success { log_error("Building raylib shared library failed"); compiler_set_workspace_status(.FAILED); return; } } generate_raylib_bindings(output_filename = "generated.jai"); } generate_raylib_bindings :: (output_filename: string) { using opts: Generate_Bindings_Options; generate_library_declarations = false; array_add(*library_search_paths,"./"); array_add(*libraries, { filename = "libraylib" }); array_add(*include_paths, "raylib/src/external/glfw/include"); array_add(*source_files, "raylib/src/raylib.h"); array_add(*source_files, "raylib/src/rlgl.h"); array_add(*source_files, "raylib/src/raymath.h"); /* Raylib for some reason loves using `int` instead of the actual enum type. */ Stupid_Table :: #type Table(string, struct { #as using type: CType; argument_position: s64; }); STUPID_FUNCTION_TABLE :: #run -> Stupid_Table { table: Stupid_Table; table_add(*table, "SetConfigFlags", { hardcoded_jai_string = "ConfigFlags", argument_position = 0 }); table_add(*table, "IsKeyDown", { hardcoded_jai_string = "KeyboardKey", argument_position = 0 }); table_add(*table, "IsKeyPressed", { hardcoded_jai_string = "KeyboardKey", argument_position = 0 }); table_add(*table, "IsKeyPressedRepeat", { hardcoded_jai_string = "KeyboardKey", argument_position = 0 }); table_add(*table, "IsMouseButtonDown", { hardcoded_jai_string = "MouseButton", argument_position = 0 }); table_add(*table, "IsMouseButtonUp", { hardcoded_jai_string = "MouseButton", argument_position = 0 }); table_add(*table, "IsMouseButtonReleased", { hardcoded_jai_string = "MouseButton", argument_position = 0 }); table_add(*table, "IsMouseButtonPressed", { hardcoded_jai_string = "MouseButton", argument_position = 0 }); table_add(*table, "SetMouseCursor", { hardcoded_jai_string = "MouseCursor", argument_position = 0 }); table_add(*table, "SetShaderValue", { hardcoded_jai_string = "ShaderUniformDataType", argument_position = 3 }); table_add(*table, "SetTraceLogLevel", { hardcoded_jai_string = "TraceLogLevel", argument_position = 0 }); table_add(*table, "UpdateCamera", { hardcoded_jai_string = "CameraMode", argument_position = 1 }); table_add(*table, "LoadFontData", { hardcoded_jai_string = "FontType", argument_position = 5 }); table_add(*table, "SetTextureFilter", { hardcoded_jai_string = "TextureFilter", argument_position = 1 }); return table; } /* These clash with Jai's Math module. These are the same structs anyway. */ NAMES_TO_DISCARD :: string.["Vector2", "Vector3", "Quaternion", "Vector4", "PI"]; visitor = (decl: *Declaration, parent_decl: *Declaration) -> Declaration_Visit_Result { if array_find(NAMES_TO_DISCARD, decl.name) { log("Discarded raylib's %", decl.name); decl.decl_flags |= .OMIT_FROM_OUTPUT; return .STOP; } if decl.kind == .FUNCTION { result := table_find_pointer(*STUPID_FUNCTION_TABLE, decl.name); if result != null { /* Replace the argument type at the position with a hardcoded string. For example: u32 -> ConfigFlags */ cast(*Function, decl).type.type_of_function.arguments[result.argument_position].type = result; log("Fixed the type of stupid function '%'", decl.name); } } if parent_decl && parent_decl.kind == .STRUCT { if parent_decl.name == "Camera3D" && decl.name == "projection" && decl.kind == .DECLARATION && decl.type.number_flags == ._32BIT | .SIGNED { change_type_to_enum(decl, "CameraProjection"); log("Changed the type of '%(%)'", parent_decl.name, parent_decl.kind); } } return .RECURSE; }; if !generate_bindings(opts, output_filename) { log_error("Failed to generated raylib bindings"); compiler_set_workspace_status(.FAILED); return; } } remove_unneeded_cringe :: () { FILES_TO_DELETE :: string.[ ".gitignore", "BINDINGS.md", "CHANGELOG", "CMakeLists.txt", "CMakeOptions.txt", "CONTRIBUTING.md", "CONVENTIONS.md", "FAQ.md", "HISTORY.md", "README.md", "ROADMAP.md", "SECURITY.md", "build.zig", "build.zig.zon", "raylib.pc.in", "src/CMakeLists.txt", "src/Makefile", "src/minshell.html", "src/raylib.dll.rc", "src/raylib.dll.rc.data", "src/raylib.ico", "src/raylib.rc", "src/raylib.rc.data", "src/shell.html", "src/external/glfw/CMakeLists.txt", "src/external/glfw/CONTRIBUTORS.md", "src/external/glfw/README.md", "src/external/glfw/.mailmap", ]; FOLDER :: "raylib"; for FILES_TO_DELETE { file_to_delete := tprint("%/%", FOLDER, it); if file_exists(file_to_delete) { assert(!is_directory(file_to_delete)); file_delete(file_to_delete); log("Deleted cringe file - %", file_to_delete); } reset_temporary_storage(); } FOLDERS_TO_DELETE :: string.[ ".git", ".github", "cmake", "examples", "logo", "projects", "tools", "src/external/glfw/CMake", ]; for FOLDERS_TO_DELETE { file_to_delete := tprint("%/%", FOLDER, it); if file_exists(file_to_delete) { assert(is_directory(file_to_delete)); delete_directory(file_to_delete); log("Deleted cringe directory - %", file_to_delete); } reset_temporary_storage(); } } #import "Compiler"; #import "Basic"; #import "BuildCpp"; #import "File_Utilities"; #import "File"; #import "Hash_Table"; #import "Bindings_Generator";