#!/usr/bin/env python """ Build system for tactical-shooter GDExtension simulation core. Targets a shared library (.so/.dll/.dylib) loadable by Godot 4. Dependencies: - godot-cpp submodule (git submodule update --init) - scons (pip install scons) - C++17 capable compiler (gcc >= 11, clang >= 14, MSVC 2022) Usage: scons # debug build scons target=release # release build (optimized, no debug symbols) scons target=template_release # same as release scons target=template_debug # debug build with optimization scons -j$(nproc) # parallel build Platform detection is automatic (linux, windows, macos). Architecture detection is automatic (x86_64, arm64). """ import os import sys import platform # ---- Environment Setup ------------------------------------------------------- EnsureSConsVersion(4, 0) env = SConscript("godot-cpp/SConstruct") # ---- Platform / Architecture / Target detection ------------------------------ # Add our custom options opts = Variables([], ARGUMENTS) opts.Add( EnumVariable("target", "Build target", "template_debug", ("editor", "template_debug", "template_release")) ) opts.Add(BoolVariable("verbose", "Enable verbose output", False)) opts.Add( PathVariable("gdextension_dir", "Output directory for .gdextension + binary", "gdextension", PathVariable.PathIsDirCreate) ) opts.Update(env) Help(opts.GenerateHelpText(env)) # Derive target name from platform target_platform = env["platform"] if target_platform == "linux": lib_name = "libsimulation.so" elif target_platform == "windows": lib_name = "libsimulation.dll" elif target_platform == "macos": lib_name = "libsimulation.dylib" else: lib_name = f"libsimulation.{target_platform}" # Build directory mirrors target/platform structure build_dir = os.path.join("build", env["platform"], env["target"]) # ---- Compiler Flags ---------------------------------------------------------- env.Append(CPPPATH=["src/"]) if env["target"] == "template_release": env.Append(CCFLAGS=["-O3", "-DNDEBUG", "-fomit-frame-pointer"]) elif env["target"] == "template_debug": env.Append(CCFLAGS=["-O2", "-g", "-DDEBUG_ENABLED"]) else: # editor env.Append(CCFLAGS=["-O2", "-g", "-DDEBUG_ENABLED", "-DEDITOR_ENABLED"]) # Warnings as errors (strict) env.Append(CCFLAGS=[ "-Wall", "-Wextra", "-Wno-unused-parameter", # godot-cpp callbacks have many unused params "-Wno-missing-field-initializers", ]) # C++17 required by godot-cpp env.Append(CXXFLAGS=["-std=c++17"]) # ---- Sources ---------------------------------------------------------------- sources = Glob("src/*.cpp") # ---- Build Targets ---------------------------------------------------------- # Object files go to build directory VariantDir(build_dir, "src", duplicate=False) build_objects = [os.path.join(build_dir, os.path.basename(s)) for s in sources] # Final library in gdextension/bin// output_dir = os.path.join(env["gdextension_dir"], "bin", target_platform) output_path = os.path.join(output_dir, lib_name) lib = env.SharedLibrary(target=output_path, source=build_objects) # Alias so `scons build` works env.Alias("build", lib) Default(lib) # ---- Verbose mode ----------------------------------------------------------- if not env["verbose"]: env.SetDefault(COMSTR_COMPILEPROGRESS="[{.TaskComplete}/{.TaskCount}] Compiling $TARGET") env.SetDefault(LINKCOMSTR="[Link] $TARGET") env.SetDefault(SHCCCOMSTR="[CC] $TARGET") env.SetDefault(SHCXXCOMSTR="[CXX] $TARGET") env.SetDefault(SHLINKCOMSTR="[Link] $TARGET") # ---- Clean ------------------------------------------------------------------- Clean(lib, build_dir)