diff --git a/.editorconfig b/.editorconfig index 63251a3b..49caa8c7 100644 --- a/.editorconfig +++ b/.editorconfig @@ -9,7 +9,7 @@ insert_final_newline = true max_line_length = 120 trim_trailing_whitespace = true -[{*.py,SConstruct,SCsub}] +[*.py] indent_style = space [{*.{yml,yaml},.clang{-format,-tidy,d}}] diff --git a/.github/actions/openvic-build/action.yml b/.github/actions/openvic-build/action.yml index 66d1de05..c1e7075c 100644 --- a/.github/actions/openvic-build/action.yml +++ b/.github/actions/openvic-build/action.yml @@ -1,30 +1,18 @@ name: Build OpenVic -description: Setup and Build OpenVic with the provided options +description: Configure, build, and install OpenVic with CMake inputs: identifier: - description: Identifier of this build - target: - description: Target type to build for + description: Identifier of this build (artifact name) + preset: + description: CMake configure preset required: true - platform: - description: Platform to build for + configuration: + description: Build configuration (Debug, Release, RelWithDebInfo) required: true - arch: - description: Architecture to build for - required: true - api-version: - description: API version to build for - required: true - scons-flags: - description: Additional flags to send to SCons + cmake-args: + description: Additional -D flags passed to the CMake configure step default: '' - cache-base-branch: - description: Branch to base the cache upon - default: 'master' - disable-cache: - description: Whether to disable the build cache - default: 'false' tag-name: description: Name of tag default: '' @@ -35,34 +23,40 @@ inputs: runs: using: composite steps: - - name: Setup build cache - uses: OpenVicProject/openvic-cache@master - if: ${{ inputs.disable-cache != 'true' }} - with: - cache-name: ${{ inputs.identifier }} - base-branch: ${{ inputs.cache-base-branch }} - continue-on-error: true - - - name: Set up Python - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 - with: - python-version: "3.x" + - name: Setup MSVC environment + if: ${{ runner.os == 'Windows' }} + shell: pwsh + run: | + $vswhere = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" + $vsPath = & $vswhere -latest -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath + Import-Module (Join-Path $vsPath "Common7\Tools\Microsoft.VisualStudio.DevShell.dll") + Enter-VsDevShell -VsInstallPath $vsPath -SkipAutomaticLocation -DevCmdArguments '-arch=x64 -host_arch=x64' + Get-ChildItem env: | ForEach-Object { Add-Content -Path $env:GITHUB_ENV -Value "$($_.Name)=$($_.Value)" } - - name: Set up SCons + - name: Setup Ninja shell: bash run: | - python -c "import sys; print(sys.version)" - python -m pip install scons - scons --version + # Ninja is preinstalled on GitHub-hosted images; fall back to the + # image's package manager if a future image drops it. + if ! command -v ninja >/dev/null 2>&1; then + if [ "$RUNNER_OS" = "macOS" ]; then + brew install ninja + elif [ "$RUNNER_OS" = "Windows" ]; then + choco install ninja -y + else + sudo apt-get update -y && sudo apt-get install -y ninja-build + fi + fi + ninja --version - name: Install APT dependencies - if: ${{ inputs.platform == 'linux' }} + if: ${{ runner.os == 'Linux' }} uses: awalsh128/cache-apt-pkgs-action@681749ae568c81c2037cb9185e38b709b261bd2f # v1.6.1 with: packages: build-essential pkg-config libtbb-dev - name: Install and Set g++ to version 13 - if: ${{ inputs.platform == 'linux' }} + if: ${{ runner.os == 'Linux' }} shell: sh run: | g++ --version @@ -73,26 +67,23 @@ runs: sudo update-alternatives --set g++ /usr/bin/g++-13 g++ --version - - name: Setup MinGW for Windows/MinGW build - if: ${{ inputs.platform == 'windows' }} - uses: egor-tensin/setup-mingw@ef0952fadae6794e225c0c1654887408bcadbf64 - - - name: Compile with SCons - uses: OpenVicProject/openvic-build@master + - name: Configure + shell: bash env: - GAME_TAG: ${{ inputs.tag-name }} - GAME_RELEASE: ${{ inputs.release-name }} - with: - platform: ${{ inputs.platform }} - target: ${{ inputs.target }} - bin-dir: "game/bin/" - sconsflags: arch=${{ inputs.arch }} api_version=${{ inputs.api-version }} ${{ inputs.scons-flags }} - - - name: Delete compilation files - if: ${{ inputs.platform == 'windows' }} - shell: pwsh + # Baked into the commit-info header at configure time. + OPENVIC_TAG: ${{ inputs.tag-name }} + OPENVIC_RELEASE: ${{ inputs.release-name }} run: | - Remove-Item game/bin/openvic/* -Include *.exp,*.lib,*.pdb -Force + cmake --preset ${{ inputs.preset }} \ + ${{ inputs.cmake-args }} + + - name: Build + shell: bash + run: cmake --build out/build/${{ inputs.preset }} --config ${{ inputs.configuration }} + + - name: Install + shell: bash + run: cmake --install out/build/${{ inputs.preset }} --config ${{ inputs.configuration }} - name: Upload extension artifact uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 diff --git a/.github/changed-files.yml b/.github/changed-files.yml index 8d8972b9..b41c0693 100644 --- a/.github/changed-files.yml +++ b/.github/changed-files.yml @@ -4,23 +4,23 @@ everything: &everything - "**" # Determines if build actions should occur after static checks are ran. Broadly speaking, these -# files changing would result in SCons rebuilding the engine, or are otherwise pertinent to the +# files changing would result in CMake rebuilding, or are otherwise pertinent to the # buildsystem itself. sources: - .github/{actions/*,workflows}/*.yml - - "**/{SConstruct,SCsub,*.py}" + - "**/CMakeLists.txt" + - "**/*.cmake" + - "**/CMakePresets.json" + - "**/*.py" - "**/*.{hpp,cpp,inc,gd,tscn,scn,tres,res}" - "**/*.{cfg,godot,gdextension,uid,import}" - "**/*.{svg,ico,icns,png,ogv,ogg,mp3,csv,xml}" - - scripts - - godot-cpp - extension/deps/** pre-commit: - *everything - - '!scripts/**' - - '!godot-cpp/**' - - '!extension/deps/*/**' + # The first-party submodule (openvic-simulation) runs its own checks. + - '!extension/deps/openvic-simulation/**' # Determines which files are appropriate for running clangd-tidy checks on. clangd: diff --git a/.github/workflows/build-matrix.yml b/.github/workflows/build-matrix.yml index 47b5bffe..1b0b000b 100644 --- a/.github/workflows/build-matrix.yml +++ b/.github/workflows/build-matrix.yml @@ -2,15 +2,7 @@ name: 🔢 Build Matrix on: workflow_call: - inputs: - godot-api-version: - type: string - required: true workflow_dispatch: - inputs: - godot-api-version: - type: string - required: true jobs: build-matrix: @@ -25,44 +17,56 @@ jobs: - identifier: windows-debug os: windows-latest name: 🏁 Windows Debug - target: template_debug - platform: windows - arch: x86_64 + preset: windows-x64-template_debug + configuration: Debug - identifier: windows-release os: windows-latest name: 🏁 Windows Release - target: template_release - platform: windows - arch: x86_64 + preset: windows-x64-template_release + configuration: Release + + - identifier: windows-editor + os: windows-latest + name: 🏁 Windows Editor + preset: windows-x64-editor + configuration: RelWithDebInfo - identifier: macos-debug os: macos-latest name: 🍎 macOS (universal) Debug - target: template_debug - platform: macos - arch: universal + preset: macos-universal-template_debug + configuration: Debug - identifier: macos-release os: macos-latest name: 🍎 macOS (universal) Release - target: template_release - platform: macos - arch: universal + preset: macos-universal-template_release + configuration: Release + + - identifier: macos-editor + os: macos-latest + name: 🍎 macOS (universal) Editor + preset: macos-universal-editor + configuration: RelWithDebInfo - identifier: linux-debug os: ubuntu-22.04 name: 🐧 Linux Debug - target: template_debug - platform: linux - arch: x86_64 + preset: linux-x64-template_debug + configuration: Debug - identifier: linux-release os: ubuntu-22.04 name: 🐧 Linux Release - target: template_release - platform: linux - arch: x86_64 + preset: linux-x64-template_release + configuration: Release + + - identifier: linux-editor + os: ubuntu-22.04 + name: 🐧 Linux Editor + preset: linux-x64-editor + configuration: RelWithDebInfo steps: - name: Checkout project @@ -75,7 +79,5 @@ jobs: uses: ./.github/actions/openvic-build with: identifier: ${{ matrix.identifier }} - target: ${{ matrix.target }} - platform: ${{ matrix.platform }} - arch: ${{ matrix.arch }} - api-version: ${{ inputs.godot-api-version }} + preset: ${{ matrix.preset }} + configuration: ${{ matrix.configuration }} diff --git a/.github/workflows/builds.yml b/.github/workflows/builds.yml index e21ddb51..4d8e0c8c 100644 --- a/.github/workflows/builds.yml +++ b/.github/workflows/builds.yml @@ -23,7 +23,6 @@ jobs: sources-changed: ${{ steps.changed-files.outputs.sources_any_changed }} godot-executable-url: ${{ steps.godot-env.outputs.godot-linux-url }} godot-templates-url: ${{ steps.godot-env.outputs.godot-template-url }} - godot-api-version: ${{ steps.godot-env.outputs.godot-api-version }} steps: - name: Checkout project uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 @@ -68,8 +67,6 @@ jobs: permissions: contents: read uses: ./.github/workflows/build-matrix.yml - with: - godot-api-version: ${{ needs.static-checks-builds.outputs.godot-api-version }} godot-debug-checks: runs-on: ubuntu-latest diff --git a/.github/workflows/nightly-releases.yml b/.github/workflows/nightly-releases.yml index ee9e1f19..80c9aa47 100644 --- a/.github/workflows/nightly-releases.yml +++ b/.github/workflows/nightly-releases.yml @@ -24,7 +24,6 @@ jobs: commit: ${{ steps.check_for_new_commits.outputs.commit }} godot-executable-url: ${{ steps.godot-env.outputs.godot-linux-url }} godot-templates-url: ${{ steps.godot-env.outputs.godot-template-url }} - godot-api-version: ${{ steps.godot-env.outputs.godot-api-version }} latest-tag: ${{ steps.default-values.outputs.latest-tag || steps.master-values.outputs.latest-tag || steps.nightly-values.outputs.latest-tag }} commit-hash: ${{ steps.default-values.outputs.commit-hash || steps.master-values.outputs.commit-hash || steps.nightly-values.outputs.commit-hash }} from-ref: ${{ steps.default-values.outputs.from-ref || steps.master-values.outputs.from-ref || steps.nightly-values.outputs.from-ref }} @@ -100,15 +99,14 @@ jobs: run: | relevant_files=( "extension/deps/*" - "scripts" - "godot-cpp" "extension/src/*.hpp" "extension/src/*.cpp" "game/*" ':!extension/src/openvic-extension/pch.hpp' ':!extension/src/openvic-extension/pch.cpp' "pyproject.toml" - "SConstruct" + "CMakeLists.txt" + "CMakePresets.json" ".github/workflows/builds.yml" ".github/actions/openvic-build/action.yml" ".github/actions/openvic-release/action.yml" @@ -227,39 +225,37 @@ jobs: fail-fast: false matrix: include: + # RelWithDebInfo = optimized with debug symbols (the old + # optimize=speed_trace debug_symbols=yes flavor). - identifier: windows-release os: windows-latest name: 🏁 Windows Release - target: template_release - platform: windows - arch: x86_64 - scons-flags: optimize=speed_trace + preset: windows-x64-template_release + configuration: RelWithDebInfo + cmake-args: '' - identifier: macos-release os: macos-latest name: 🍎 macOS (universal) Release - target: template_release - platform: macos - arch: universal - scons-flags: "optimize=speed_trace lto=full" + preset: macos-universal-template_release + configuration: RelWithDebInfo + cmake-args: -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON - identifier: linux-release os: ubuntu-latest name: 🐧 Linux Release runner: ubuntu-22.04 - target: template_release - platform: linux - arch: x86_64 - scons-flags: "optimize=speed_trace lto=full use_static_cpp=yes" + preset: linux-x64-template_release + configuration: RelWithDebInfo + cmake-args: -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON - identifier: linux-debug os: ubuntu-latest name: 🐧 Linux Debug runner: ubuntu-latest - target: template_debug - platform: linux - arch: x86_64 - scons-flags: optimize=none + preset: linux-x64-template_debug + configuration: Debug + cmake-args: '' steps: - name: Checkout project @@ -272,13 +268,10 @@ jobs: uses: ./.github/actions/openvic-build with: identifier: ${{ matrix.identifier }} - target: ${{ matrix.target }} - platform: ${{ matrix.platform }} - arch: ${{ matrix.arch }} - api-version: ${{ needs.nightly-check.outputs.godot-api-version }} + preset: ${{ matrix.preset }} + configuration: ${{ matrix.configuration }} tag-name: ${{ needs.nightly-check.outputs.tag-name }} - disable-cache: true - scons-flags: use_hot_reload=no debug_symbols=yes ${{ matrix.scons-flags }} + cmake-args: ${{ matrix.cmake-args }} publish-nightly-release: name: Publish Release diff --git a/.github/workflows/releases.yml b/.github/workflows/releases.yml index f79f9695..a6735035 100644 --- a/.github/workflows/releases.yml +++ b/.github/workflows/releases.yml @@ -20,7 +20,6 @@ jobs: release-name: ${{ steps.get_release_name.outputs.release-name }} godot-executable-url: ${{ steps.godot-env.outputs.godot-linux-url }} godot-templates-url: ${{ steps.godot-env.outputs.godot-template-url }} - godot-api-version: ${{ steps.godot-env.outputs.godot-api-version }} env: GITHUB_REF_NAME: ${{ github.ref_name }} steps: @@ -92,36 +91,32 @@ jobs: - identifier: windows-release os: windows-latest name: 🏁 Build Windows - target: template_release - platform: windows - arch: x86_64 - scons-flags: '' + preset: windows-x64-template_release + configuration: Release + cmake-args: '' - identifier: macos-release os: macos-latest name: 🍎 Build macOS - target: template_release - platform: macos - arch: universal - scons-flags: lto=full + preset: macos-universal-template_release + configuration: Release + cmake-args: -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON - identifier: linux-release os: ubuntu-latest name: 🐧 Build Linux runner: ubuntu-22.04 - target: template_release - platform: linux - arch: x86_64 - scons-flags: lto=full use_static_cpp=yes + preset: linux-x64-template_release + configuration: Release + cmake-args: -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON - identifier: linux-debug os: ubuntu-latest name: 🐧 Build Linux (debug) runner: ubuntu-latest - target: template_debug - platform: linux - arch: x86_64 - scons-flags: optimize=none + preset: linux-x64-template_debug + configuration: Debug + cmake-args: '' steps: - name: Checkout project @@ -134,14 +129,11 @@ jobs: uses: ./.github/actions/openvic-build with: identifier: ${{ matrix.identifier }} - target: ${{ matrix.target }} - platform: ${{ matrix.platform }} - arch: ${{ matrix.arch }} - version-api: ${{ needs.static-checks-release.outputs.godot-api-version }} + preset: ${{ matrix.preset }} + configuration: ${{ matrix.configuration }} tag-name: ${{ github.ref_name }} release-name: ${{ needs.static-checks-release.outputs.release-name }} - disable-cache: true - scons-flags: use_hot_reload=no ${{ matrix.scons-flags }} + cmake-args: ${{ matrix.cmake-args }} publish-release: name: Publish Release diff --git a/.gitignore b/.gitignore index 7593eee3..eaa5a30a 100644 --- a/.gitignore +++ b/.gitignore @@ -7,10 +7,6 @@ *.o *.obj -# Precompiled Headers -*.gch -*.pch - # Compiled Dynamic libraries *.so *.dylib @@ -44,7 +40,6 @@ # Godot 4+ specific ignores .godot/ game/bin/openvic/* -.sconsign*.dblite # Binaries *.o @@ -53,7 +48,6 @@ game/bin/openvic/* *.obj *.bc *.pyc -*.dblite *.pdb *.lib bin/* @@ -65,9 +59,6 @@ bin/* *.idb *.exp -# Build configuarion. -/custom.py - # MacOS stuff .DS_Store @@ -77,15 +68,16 @@ bin/* # JetBrains .idea -# scons stuff +# clangd .cache compile_commands.json -# Out-of-source build directory -/build/ - # ccls .ccls-cache # Generated source files extension/src/gen/* + +# CMake out-of-source build directory +out/ +CMakeUserPresets.json diff --git a/.gitmodules b/.gitmodules index 96db130d..21971c7d 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,12 +1,3 @@ -[submodule "godot-cpp"] - path = godot-cpp - url = https://github.com/godotengine/godot-cpp [submodule "extension/deps/openvic-simulation"] path = extension/deps/openvic-simulation url = https://github.com/OpenVicProject/OpenVic-Simulation -[submodule "scripts"] - path = scripts - url = https://github.com/OpenVicProject/scripts -[submodule "extension/deps/gli"] - path = extension/deps/gli - url = https://github.com/g-truc/gli diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e505854b..908397d7 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -43,10 +43,10 @@ repos: hooks: - id: ruff-check args: [--fix] - files: (\.py|SConstruct|SCsub)$ + files: \.py$ types_or: [text] - id: ruff-format - files: (\.py|SConstruct|SCsub)$ + files: \.py$ types_or: [text] - repo: https://github.com/pre-commit/mirrors-mypy diff --git a/.vscode/tasks.json b/.vscode/tasks.json index f8bcc923..cc3612de 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -3,14 +3,40 @@ // for the documentation about the tasks.json format "version": "2.0.0", "tasks": [ + { + "label": "configure", + "group": "build", + "type": "shell", + "command": "cmake", + "args": [ + "--preset", + "windows-x64-editor" + ], + "problemMatcher": "$msCompile" + }, + { + "label": "configure_dev", + "group": "build", + "type": "shell", + "command": "cmake", + "args": [ + "--preset", + "windows-x64-editor-dev" + ], + "problemMatcher": "$msCompile" + }, { "label": "build", "group": "build", "type": "shell", - "command": "scons", + "command": "cmake", "args": [ - // enable for debugging with breakpoints - //"dev_build=yes", + "--build", + "--preset", + "windows-x64-editor" + ], + "dependsOn": [ + "configure" ], "problemMatcher": "$msCompile" }, @@ -18,10 +44,27 @@ "label": "dev_build", "group": "build", "type": "shell", - "command": "scons", + "command": "cmake", + "args": [ + "--build", + "--preset", + "windows-x64-editor-dev" + ], + "dependsOn": [ + "configure_dev" + ], + "problemMatcher": "$msCompile" + }, + { + "label": "install", + "group": "build", + "type": "shell", + "command": "cmake", "args": [ - // enable for debugging with breakpoints - "dev_build=yes" + "--install", + "out/build/windows-x64-editor", + "--config", + "RelWithDebInfo" ], "dependsOn": [ "build" @@ -32,9 +75,13 @@ "label": "clean", "group": "build", "type": "shell", - "command": "scons", + "command": "cmake", "args": [ - "--clean" + "--build", + "--preset", + "windows-x64-editor", + "--target", + "clean" ], "problemMatcher": "$msCompile" }, @@ -49,4 +96,4 @@ "problemMatcher": "$msCompile" } ] -} \ No newline at end of file +} diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000..a870dcd8 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,140 @@ +cmake_minimum_required(VERSION 3.28) +project(openvic LANGUAGES CXX) + +if(NOT COMMAND openvic_setup_base_flags) + # scripts is the shared build-tooling repo, fetched once as a pinned + # tarball (like the other third-party deps). In a composed build the + # outermost repo fetches + loads it first and this guard skips for the + # nested repos; a standalone repo fetches it itself. FetchContent also + # dedups by name, so either path yields exactly one fetch. + # + # Raw FetchContent (not openvic_declare_dep) on purpose: openvic_declare_dep + # lives INSIDE scripts (OpenVicDeps.cmake), so it isn't defined yet here. + # Local-dev escape hatch: -DFETCHCONTENT_SOURCE_DIR_OPENVIC_SCRIPTS= + # points this at a working-tree scripts checkout. + include(FetchContent) + FetchContent_Declare( + openvic_scripts + URL "https://github.com/OpenVicProject/scripts/archive/3fcac2ec942c152bd83b2c5ad279ef192e0125d7.tar.gz" + URL_HASH SHA256=c0759a8d5eb8c6a8fa7780f01a6bd2bf079a18ef2527f0c7ec7ecc9b87aed635 + ) + FetchContent_MakeAvailable(openvic_scripts) + include("${openvic_scripts_SOURCE_DIR}/cmake/OpenVicScripts.cmake") +endif() + +option(OPENVIC_USE_PCH "Precompile openvic-extension/pch.hpp" ON) + +# godot-cpp builds with its own flag setup; the OpenVic base flags apply only +# to what follows, so this fetch stays BEFORE openvic_setup_base_flags(). +openvic_declare_dep(godotcpp + REPO godotengine/godot-cpp + SHA 5ffd70e34d0ab87009a9f0ffa3361bc8f4b09731 + SHA256 69ade893349e77b2dd0e2e538ba2f6c1dd09e1b1ddd0bb3003c5be57c3d5ab69 +) +FetchContent_MakeAvailable(godotcpp) + +openvic_setup_base_flags() +# The extension builds WITH RTTI (unlike the simulation stack), so no +# openvic_disable_rtti() here. + +add_subdirectory(extension/deps/openvic-simulation) + +# gli is header-only; its upstream CMakeLists pollutes global state +# (add_definitions(/Za) etc.), so fetch source-only and hand-roll the include +# target. +openvic_declare_dep(gli + REPO g-truc/gli + SHA 779b99ac6656e4d30c3b24e96e0136a59649a869 + SHA256 2f4f67ac4d1673216f03ff37e406bb403689b39a2df3d2efad501448705bbb3f + DOWNLOAD_ONLY +) +FetchContent_MakeAvailable(gli) +add_library(ov_gli INTERFACE) +target_include_directories( + ov_gli + SYSTEM + INTERFACE ${gli_SOURCE_DIR} ${gli_SOURCE_DIR}/external +) + +file(GLOB_RECURSE openvic_sources CONFIGURE_DEPENDS extension/src/*.cpp) +list(REMOVE_ITEM openvic_sources ${CMAKE_CURRENT_SOURCE_DIR}/extension/src/openvic-extension/pch.cpp) + +add_library(openvic SHARED ${openvic_sources}) + +set(game_gen_dir ${CMAKE_CURRENT_BINARY_DIR}/gen-include) +target_include_directories(openvic PRIVATE extension/src ${game_gen_dir}) + +openvic_generate_commit_info( + TARGET openvic + PREFIX game + REPO_DIR ${CMAKE_CURRENT_SOURCE_DIR} + OUTPUT ${game_gen_dir}/gen/commit_info.gen.hpp +) +openvic_generate_license_info( + TARGET openvic + PREFIX game + COPYRIGHT ${CMAKE_CURRENT_SOURCE_DIR}/COPYRIGHT + LICENSE ${CMAKE_CURRENT_SOURCE_DIR}/LICENSE.md + OUTPUT ${game_gen_dir}/gen/license_info.gen.hpp +) +openvic_generate_author_info( + TARGET openvic + PREFIX game + AUTHORS ${CMAKE_CURRENT_SOURCE_DIR}/AUTHORS.md + OUTPUT ${game_gen_dir}/gen/author_info.gen.hpp + SECTIONS + "Senior Developers=AUTHORS_SENIOR_DEVELOPERS" + "Developers=AUTHORS_DEVELOPERS" + "Contributors=AUTHORS_CONTRIBUTORS" + "Consultants=AUTHORS_CONSULTANTS" + "Artists=AUTHORS_ARTISTS" +) + +if(OPENVIC_USE_PCH) + target_precompile_headers(openvic PRIVATE extension/src/openvic-extension/pch.hpp) +endif() + +# Godot class reference docs are compiled in for targets with editor UI. +if(NOT GODOTCPP_TARGET STREQUAL "template_release") + file(GLOB doc_xml CONFIGURE_DEPENDS extension/doc_classes/*.xml) + target_doc_sources(openvic "${doc_xml}") +endif() + +target_link_libraries(openvic PRIVATE godot::cpp openvic::simulation ov_gli) + +set_target_properties(openvic PROPERTIES CXX_VISIBILITY_PRESET hidden VISIBILITY_INLINES_HIDDEN ON) + +if(CMAKE_SYSTEM_NAME STREQUAL "Linux") + set_target_properties(openvic PROPERTIES BUILD_RPATH_USE_ORIGIN ON INSTALL_RPATH "$ORIGIN") +elseif(APPLE) + target_link_options(openvic PRIVATE -Wl,-undefined,dynamic_lookup) + target_link_libraries(openvic PRIVATE "-framework Foundation") +endif() + +# --- Artifact naming + install: must match the committed +# game/bin/openvic.gdextension entries exactly. Native prefixes/suffixes per +# platform (no lib prefix on Windows, plain .dylib on macOS -- the universal +# binary covers both x86_64 and arm64, so no arch segment there). --- +get_target_property(OV_ARCH godot-cpp GODOTCPP_ARCH) + +if(APPLE) + set(OV_OUTPUT_NAME "openvic.macos.${GODOTCPP_TARGET}") +elseif(CMAKE_SYSTEM_NAME STREQUAL "Windows") + set(OV_OUTPUT_NAME "openvic.windows.${GODOTCPP_TARGET}.${OV_ARCH}") + # MinGW defaults to a "lib" dll prefix; the gdextension entries have none. + set_target_properties(openvic PROPERTIES PREFIX "") +elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux") + set(OV_OUTPUT_NAME "openvic.linux.${GODOTCPP_TARGET}.${OV_ARCH}") +else() + message(FATAL_ERROR "Unsupported platform: ${CMAKE_SYSTEM_NAME}") +endif() +set_target_properties( + openvic + PROPERTIES + OUTPUT_NAME "${OV_OUTPUT_NAME}" + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/$" + LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/$" +) +# install(FILES $) copies just the dll/so/dylib (no MSVC +# import .lib/.exp/.pdb). +install(FILES $ DESTINATION ".") diff --git a/CMakePresets.json b/CMakePresets.json new file mode 100644 index 00000000..3bb4b53c --- /dev/null +++ b/CMakePresets.json @@ -0,0 +1,381 @@ +{ + "version": 6, + "cmakeMinimumRequired": { + "major": 3, + "minor": 28 + }, + "configurePresets": [ + { + "name": "base", + "hidden": true, + "generator": "Ninja Multi-Config", + "binaryDir": "${sourceDir}/out/build/${presetName}", + "installDir": "${sourceDir}/game/bin/openvic", + "cacheVariables": { + "CMAKE_EXPORT_COMPILE_COMMANDS": "ON", + "CMAKE_CONFIGURATION_TYPES": "Release;RelWithDebInfo;Debug", + "GODOTCPP_USE_HOT_RELOAD": "OFF", + "GODOTCPP_PRECISION": "single" + } + }, + { + "name": "t-template_debug", + "hidden": true, + "cacheVariables": { + "GODOTCPP_TARGET": "template_debug", + "CMAKE_DEFAULT_BUILD_TYPE": "Debug" + } + }, + { + "name": "t-template_release", + "hidden": true, + "cacheVariables": { + "GODOTCPP_TARGET": "template_release", + "CMAKE_DEFAULT_BUILD_TYPE": "Release" + } + }, + { + "name": "t-editor", + "hidden": true, + "cacheVariables": { + "GODOTCPP_TARGET": "editor", + "CMAKE_DEFAULT_BUILD_TYPE": "RelWithDebInfo" + } + }, + { + "name": "t-dev", + "hidden": true, + "cacheVariables": { + "GODOTCPP_DEV_BUILD": "ON", + "CMAKE_DEFAULT_BUILD_TYPE": "Debug" + } + }, + { + "name": "p-windows-x64", + "hidden": true, + "inherits": "base", + "condition": { + "type": "equals", + "lhs": "${hostSystemName}", + "rhs": "Windows" + }, + "architecture": { + "value": "x64", + "strategy": "external" + }, + "cacheVariables": { + "GODOTCPP_USE_STATIC_CPP": "OFF" + } + }, + { + "name": "p-linux-x64", + "hidden": true, + "inherits": "base", + "condition": { + "type": "equals", + "lhs": "${hostSystemName}", + "rhs": "Linux" + }, + "cacheVariables": { + "CMAKE_CXX_COMPILER": "g++", + "GODOTCPP_USE_STATIC_CPP": "ON" + } + }, + { + "name": "p-macos-universal", + "hidden": true, + "inherits": "base", + "condition": { + "type": "equals", + "lhs": "${hostSystemName}", + "rhs": "Darwin" + }, + "cacheVariables": { + "CMAKE_OSX_ARCHITECTURES": "x86_64;arm64" + } + }, + { + "name": "tc-clang-cl", + "hidden": true, + "cacheVariables": { + "CMAKE_C_COMPILER": "clang-cl", + "CMAKE_CXX_COMPILER": "clang-cl" + } + }, + { + "name": "tc-mingw", + "hidden": true, + "cacheVariables": { + "CMAKE_C_COMPILER": "gcc", + "CMAKE_CXX_COMPILER": "g++", + "GODOTCPP_USE_STATIC_CPP": "ON" + } + }, + { + "name": "windows-x64-template_debug", + "inherits": [ + "p-windows-x64", + "t-template_debug" + ] + }, + { + "name": "windows-x64-template_release", + "inherits": [ + "p-windows-x64", + "t-template_release" + ] + }, + { + "name": "windows-x64-editor", + "inherits": [ + "p-windows-x64", + "t-editor" + ] + }, + { + "name": "windows-x64-template_debug-dev", + "inherits": [ + "p-windows-x64", + "t-template_debug", + "t-dev" + ] + }, + { + "name": "windows-x64-editor-dev", + "inherits": [ + "p-windows-x64", + "t-dev", + "t-editor" + ] + }, + { + "name": "windows-x64-template_release-clang", + "inherits": [ + "tc-clang-cl", + "p-windows-x64", + "t-template_release" + ] + }, + { + "name": "windows-x64-template_release-mingw", + "inherits": [ + "tc-mingw", + "p-windows-x64", + "t-template_release" + ] + }, + { + "name": "windows-x64-template_debug-clang", + "inherits": [ + "tc-clang-cl", + "p-windows-x64", + "t-template_debug" + ] + }, + { + "name": "windows-x64-template_debug-mingw", + "inherits": [ + "tc-mingw", + "p-windows-x64", + "t-template_debug" + ] + }, + { + "name": "windows-x64-editor-clang", + "inherits": [ + "tc-clang-cl", + "p-windows-x64", + "t-editor" + ] + }, + { + "name": "windows-x64-editor-mingw", + "inherits": [ + "tc-mingw", + "p-windows-x64", + "t-editor" + ] + }, + { + "name": "linux-x64-template_debug", + "inherits": [ + "p-linux-x64", + "t-template_debug" + ] + }, + { + "name": "linux-x64-template_release", + "inherits": [ + "p-linux-x64", + "t-template_release" + ] + }, + { + "name": "linux-x64-editor", + "inherits": [ + "p-linux-x64", + "t-editor" + ] + }, + { + "name": "linux-x64-template_debug-dev", + "inherits": [ + "p-linux-x64", + "t-template_debug", + "t-dev" + ] + }, + { + "name": "linux-x64-editor-dev", + "inherits": [ + "p-linux-x64", + "t-dev", + "t-editor" + ] + }, + { + "name": "macos-universal-template_debug", + "inherits": [ + "p-macos-universal", + "t-template_debug" + ] + }, + { + "name": "macos-universal-template_release", + "inherits": [ + "p-macos-universal", + "t-template_release" + ] + }, + { + "name": "macos-universal-editor", + "inherits": [ + "p-macos-universal", + "t-editor" + ] + }, + { + "name": "macos-universal-template_debug-dev", + "inherits": [ + "p-macos-universal", + "t-template_debug", + "t-dev" + ] + }, + { + "name": "macos-universal-editor-dev", + "inherits": [ + "p-macos-universal", + "t-dev", + "t-editor" + ] + } + ], + "buildPresets": [ + { + "name": "windows-x64-editor", + "configurePreset": "windows-x64-editor", + "configuration": "RelWithDebInfo" + }, + { + "name": "windows-x64-template_debug", + "configurePreset": "windows-x64-template_debug", + "configuration": "Debug" + }, + { + "name": "windows-x64-template_release", + "configurePreset": "windows-x64-template_release", + "configuration": "Release" + }, + { + "name": "windows-x64-template_release-clang", + "configurePreset": "windows-x64-template_release-clang", + "configuration": "Release" + }, + { + "name": "windows-x64-template_release-mingw", + "configurePreset": "windows-x64-template_release-mingw", + "configuration": "Release" + }, + { + "name": "windows-x64-template_debug-clang", + "configurePreset": "windows-x64-template_debug-clang", + "configuration": "Debug" + }, + { + "name": "windows-x64-template_debug-mingw", + "configurePreset": "windows-x64-template_debug-mingw", + "configuration": "Debug" + }, + { + "name": "windows-x64-editor-clang", + "configurePreset": "windows-x64-editor-clang", + "configuration": "RelWithDebInfo" + }, + { + "name": "windows-x64-editor-mingw", + "configurePreset": "windows-x64-editor-mingw", + "configuration": "RelWithDebInfo" + }, + { + "name": "windows-x64-editor-dev", + "configurePreset": "windows-x64-editor-dev", + "configuration": "Debug" + }, + { + "name": "windows-x64-template_debug-dev", + "configurePreset": "windows-x64-template_debug-dev", + "configuration": "Debug" + }, + { + "name": "linux-x64-editor", + "configurePreset": "linux-x64-editor", + "configuration": "RelWithDebInfo" + }, + { + "name": "linux-x64-template_debug", + "configurePreset": "linux-x64-template_debug", + "configuration": "Debug" + }, + { + "name": "linux-x64-template_release", + "configurePreset": "linux-x64-template_release", + "configuration": "Release" + }, + { + "name": "linux-x64-editor-dev", + "configurePreset": "linux-x64-editor-dev", + "configuration": "Debug" + }, + { + "name": "linux-x64-template_debug-dev", + "configurePreset": "linux-x64-template_debug-dev", + "configuration": "Debug" + }, + { + "name": "macos-universal-editor", + "configurePreset": "macos-universal-editor", + "configuration": "RelWithDebInfo" + }, + { + "name": "macos-universal-template_debug", + "configurePreset": "macos-universal-template_debug", + "configuration": "Debug" + }, + { + "name": "macos-universal-template_release", + "configurePreset": "macos-universal-template_release", + "configuration": "Release" + }, + { + "name": "macos-universal-editor-dev", + "configurePreset": "macos-universal-editor-dev", + "configuration": "Debug" + }, + { + "name": "macos-universal-template_debug-dev", + "configurePreset": "macos-universal-template_debug-dev", + "configuration": "Debug" + } + ] +} diff --git a/README.md b/README.md index 321ea07d..e37d8447 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,9 @@ For detailed instructions, view the Contributor Quickstart Guide [here](docs/CON ## System Requirements * [Godot 4.7](https://github.com/godotengine/godot/releases/tag/4.7-stable) -* [scons](https://scons.org/) +* [CMake](https://cmake.org/) 3.28+ +* [Ninja](https://ninja-build.org/) +* Python 3 (used by the build for code generation) > [!WARNING] > If you are using Arch Linux, do not use the Arch repo package, it is known to break under some GDExtensions, use the official release file. @@ -22,18 +24,24 @@ See [System Requirements](docs/contribution/system-requirements.md). ## Repo Setup 1. Clone the OpenVic Repo to a suitable folder using the git command `git clone https://github.com/OpenVicProject/OpenVic.git` -2. Update the submodules by executing the git command `git submodule update --init --recursive` +2. Update the submodules by executing the git command `git submodule update --init --recursive` (only the first-party OpenVic repos are submodules; all third-party dependencies are fetched automatically by CMake during configure) -Note that using a zip download instead of cloning means a lot of work in manually managing submodules individually. It is strongly recommended to use git to obtain the source code. +Note that using a zip download instead of cloning means manually managing the submodules. It is strongly recommended to use git to obtain the source code. See [Cloning](docs/contribution/cloning.md). ## [Godot Documentation](https://docs.godotengine.org/en/latest/) ## Build/Run Instructions -1. Install [Godot 4.7](https://github.com/godotengine/godot/releases/tag/4.7-stable) and [scons](https://scons.org/) for your system. +1. Install [Godot 4.7](https://github.com/godotengine/godot/releases/tag/4.7-stable), [CMake](https://cmake.org/) 3.28+, and [Ninja](https://ninja-build.org/) for your system. 2. Run the command `git submodule update --init --recursive` to retrieve all related submodules. -3. Run `scons` in the project root, you should see a libopenvic file in `game/bin/openvic`. +3. Configure and build with the preset for your platform (`windows-x64-template_debug`, `linux-x64-template_debug`, or `macos-universal-template_debug`): + ```sh + cmake --preset windows-x64-template_debug + cmake --build --preset windows-x64-template_debug + cmake --install out/build/windows-x64-template_debug --config Debug + ``` + The install step copies the extension library into `game/bin/openvic`. 4. Open with Godot 4, click import and navigate to the `game` directory. 5. Press "Import & Edit", wait for the Editor to finish re-importing assets, and then close the Editor ***without saving*** and reopen the project. 6. Once loaded, click the play button at the top right, and you should see and hear the game application open on the main menu. @@ -41,7 +49,7 @@ See [Cloning](docs/contribution/cloning.md). See [Run, Build, and Export](docs/contribution/run-build-and-export.md). ## Project Export -1. Build the extension with `scons` or `scons target=template_debug`. (or `scons target=template_release` for release) +1. Build and install the extension with the `*-template_debug` preset (or `*-template_release` for release), as in the Build/Run instructions above. 2. Open `game/project.godot` with Godot 4. 3. Click `Project` at the top left, click `Export`. 4. If you do not have the templates, you must download the templates, there is highlighted white text at the bottom of the Export subwindow that opens up the template manager for you to download. @@ -55,8 +63,7 @@ See [Run, Build, and Export](docs/contribution/run-build-and-export.md). See [Run, Build, and Export](docs/contribution/run-build-and-export.md). ## Extension Debugging -1. If in a clean build, build the extension with `scons`. -2. Build with `scons dev_build=yes`. +1. Configure and build the dev preset (`GODOTCPP_DEV_BUILD`, Debug config): `cmake --preset windows-x64-template_debug-dev && cmake --build --preset windows-x64-template_debug-dev`, then install it with `cmake --install out/build/windows-x64-template_debug-dev --config Debug`. 3. [Setup your IDE](https://godotengine.org/qa/108346/how-can-i-debug-runtime-errors-of-native-library-in-godot) so your Command/Host/Launching App is your Godot 4 binary and the Working Directory is the `game` directory. 4. Start the debugger. @@ -64,10 +71,10 @@ See [Debugging](docs/contribution/debugging.md). ## Extension Class Reference Documentation Every time you add something to the GDExtension you need to add to the class reference documentation, to do such: -1. Build with `scons`. +1. Build and install the extension (see Build/Run Instructions). 2. Run your Godot 4 binary with `--doctool --headless ../extension --gdextension-docs` in the `game` directory. 3. Write documentation in the style of Godot, see [Godot's Writing Documentation: Class Reference Guides](https://docs.godotengine.org/en/stable/contributing/documentation/index.html#class-reference-guides). -4. Build with `scons`. +4. Build and install again. Windows note: doctool may not work in powershell/vscode terminal use command prompt directly. diff --git a/SConstruct b/SConstruct deleted file mode 100644 index 6b7d725d..00000000 --- a/SConstruct +++ /dev/null @@ -1,171 +0,0 @@ -#!/usr/bin/env python - -import atexit as _atexit -import os -import time as _time - -import SCons - -# Log how long the whole scons invocation took. Fires at interpreter exit so it -# also reports for failed builds. -_BUILD_START = _time.monotonic() - - -@_atexit.register -def _print_build_duration(): - elapsed = _time.monotonic() - _BUILD_START - mins = int(elapsed // 60) - secs = elapsed - (mins * 60) - print(f"[BUILD TIMING] elapsed: {mins}m {secs:.1f}s ({elapsed:.1f}s total)") - - -BINDIR = "game/bin" - -env = SConscript("scripts/SConstruct") - -env.PrependENVPath("PATH", os.getenv("PATH")) - -env["disable_rtti"] = False -env["use_hot_reload"] = env.get("use_hot_reload", False) -opts = env.SetupOptions() - -env.FinalizeOptions() - - -def _build_config_dir(env): - parts = [env["platform"], env["target"], env["arch"]] - if env.dev_build: - parts.append("dev") - if env["precision"] == "double": - parts.append("double") - if env["platform"] == "windows": - parts.append("mdd" if env.get("debug_crt", False) else "mt" if env.get("use_static_cpp", False) else "md") - if env.get("use_asan", False): - parts.append("san") - return "build/" + ".".join(parts) - - -build_dir = _build_config_dir(env) - -# Needs Clone, else godot-cpp builds using our modified environment variables. eg: godot-cpp builds on C++20 -OLD_ARGS = SCons.Script.ARGUMENTS.copy() -SCons.Script.ARGUMENTS["use_hot_reload"] = env["use_hot_reload"] -SCons.Script.ARGUMENTS["use_static_cpp"] = env["use_static_cpp"] -SCons.Script.ARGUMENTS["disable_exceptions"] = env["disable_exceptions"] -SCons.Script.ARGUMENTS["compiledb_file"] = "godot-cpp/compile_commands.json" -# godot-cpp builds in-source and forcing VariantDir on it breaks the GodotCPPBingings builder -godot_env = SConscript("godot-cpp/SConstruct") -SCons.Script.ARGUMENTS = OLD_ARGS - -# Make LIBS into a list which is easier to deal with. -godot_env["LIBS"] = [godot_env["LIBS"]] -env.Append(CPPPATH=godot_env["CPPPATH"]) -env.Prepend(LIBS=godot_env["LIBS"]) - -SConscript("extension/deps/SCsub", "env") - -ovsim_gen_files = env.openvic_simulation["GEN_FILES"] - -# Out-of-source build: variant tree holds object files and generated headers, -# not copies of the source. Compile diagnostics therefore reference original -# source paths. -ext_src = "extension/src" -ext_variant = build_dir + "/" + ext_src # forward slashes so VariantDir matches -env.VariantDir(ext_variant, ext_src, duplicate=False) - -env.Append(CPPPATH=[env.Dir(ext_variant), env.Dir(ext_src)]) - -Default( - env.CommandNoCache( - ext_variant + "/gen/commit_info.gen.hpp", - env.Value(env.get_git_info("game")), - env.Run(env.git_builder), - name_prefix="game", - ) -) -Default( - env.CommandNoCache( - ext_variant + "/gen/license_info.gen.hpp", - ["COPYRIGHT", "LICENSE.md"], - env.Run(env.license_builder), - name_prefix="game", - ) -) -Default( - env.CommandNoCache( - ext_variant + "/gen/author_info.gen.hpp", - "AUTHORS.md", - env.Run(env.author_builder), - name_prefix="game", - sections={ - "Senior Developers": "AUTHORS_SENIOR_DEVELOPERS", - "Developers": "AUTHORS_DEVELOPERS", - "Contributors": "AUTHORS_CONTRIBUTORS", - "Consultants": "AUTHORS_CONSULTANTS", - "Artists": "AUTHORS_ARTISTS", - }, - ) -) - -# For the reference: -# - CCFLAGS are compilation flags shared between C and C++ -# - CFLAGS are for C-specific compilation flags -# - CXXFLAGS are for C++-specific compilation flags -# - CPPFLAGS are for pre-processor flags -# - CPPDEFINES are for pre-processor defines -# - LINKFLAGS are for linking flags - -doc_gen_source = ext_src + "/gen/doc_data.gen.cpp" -doc_gen_variant = ext_variant + "/gen/doc_data.gen.cpp" -# Exclude doc_data.gen.cpp and pch.cpp from the regular source list. -pch_cpp_source = ext_src + "/openvic-extension/pch.cpp" -pch_cpp_variant = ext_variant + "/openvic-extension/pch.cpp" -sources = env.GlobRecursiveVariant("*.cpp", ext_src, ext_variant, [doc_gen_source, pch_cpp_source]) -env.extension_sources = sources - -env.SetupPCH("openvic-extension/pch.hpp", pch_cpp_variant) - -objects = [] -for s in sources: - obj = env.SharedObject(s) - env.Depends(obj, ovsim_gen_files) - objects.extend(obj if isinstance(obj, (list, tuple)) else [obj]) - -if env["target"] in ["editor", "template_debug"]: - doc_data = godot_env.GodotCPPDocData(doc_gen_source, source=Glob("extension/doc_classes/*.xml")) - objects.append(doc_data) - -# Link into the per-config build_dir so each CRT/config keeps its own cached -# binary. game/bin/openvic/ then receives a copy via env.Install -build_bin = build_dir + "/bin" -final_bin = BINDIR + "/openvic" - -if env["platform"] == "macos": - framework_name = "libopenvic.{}.{}.framework".format(godot_env["platform"], godot_env["target"]) - dylib_name = "libopenvic.{}.{}".format(godot_env["platform"], godot_env["target"]) - library = env.SharedLibrary( - build_bin + "/" + framework_name + "/" + dylib_name, - source=objects, - ) - installed = env.Install(final_bin + "/" + framework_name, library[0]) -else: - suffix = ".{}.{}.{}".format(godot_env["platform"], godot_env["target"], godot_env["arch"]) - library = env.SharedLibrary( - build_bin + "/libopenvic{}{}".format(suffix, godot_env["SHLIBSUFFIX"]), - source=objects, - ) - installed = env.Install(final_bin, library[0]) - -env.Clean(library, env.Dir(build_dir)) - -default_args = [installed] - -if "env" in locals(): - # FIXME: This method mixes both cosmetic progress stuff and cache handling... - env.show_progress(env) - -# Add compiledb if the option is set -if env.get("compiledb", False): - default_args += ["compiledb"] - -Default(*default_args) diff --git a/docs/SETUP.md b/docs/SETUP.md index 19fc0299..e73d6462 100644 --- a/docs/SETUP.md +++ b/docs/SETUP.md @@ -3,7 +3,7 @@ ## Required Software - A way to use `git` such as Git Bash or the Windows-Linux Subsystem - Python 3.x -- Scons +- CMake 3.28+ and Ninja (included with Visual Studio's "C++ CMake tools for Windows" component) - Godot - A programming IDE such as Visual Studio Code @@ -28,10 +28,9 @@ ![](images/installation/python-installer.png) -## 3. Scons -- Open Windows Powershell and run the command `pip install scons==4.7.0` - -![](images/installation/scons-install.png) +## 3. CMake and Ninja +- Install [CMake](https://cmake.org/download/) (3.28 or newer) and [Ninja](https://ninja-build.org/), or select the "C++ CMake tools for Windows" component in the Visual Studio Installer, which includes both +- Verify with `cmake --version` and `ninja --version` in Powershell ## 4. [Godot](https://github.com/godotengine/godot/releases/latest) - Download Godot 4.7 The current version for the project will be on the [main README](../README.md) page. @@ -71,10 +70,13 @@ ![](images/proj-setup/04-new-branch.png) -7. Build the C++ portion of the project by running `scons` in Powershell - - It will take a minute to initially compile. Any future C++ changes only need to recompile the files that were changed and are much faster - -![](images/proj-setup/05-scons.png) +7. Build the C++ portion of the project by running the following in a "x64 Native Tools Command Prompt for VS" (or any shell with the MSVC environment loaded): + ``` + cmake --preset windows-x64-template_debug + cmake --build --preset windows-x64-template_debug + cmake --install out/build/windows-x64-template_debug --config Debug + ``` + - It will take a few minutes to initially compile (third-party dependencies are downloaded automatically during configure). Any future C++ changes only need to recompile the files that were changed and are much faster 8. Run the Godot executable diff --git a/docs/contribution/debugging.md b/docs/contribution/debugging.md index e788c442..168cef2e 100644 --- a/docs/contribution/debugging.md +++ b/docs/contribution/debugging.md @@ -2,11 +2,16 @@ For debugging, foremost you must: -1. Build the extension with dev_build, it is also recommended to include debug_symbols. To do so run `scons dev_build=yes debug_symbols=yes`. +1. Build the extension with a dev preset (dev-only debugging code plus debug symbols) and install it: + ```sh + cmake --preset windows-x64-editor-dev + cmake --build --preset windows-x64-editor-dev + cmake --install out/build/windows-x64-editor-dev --config Debug + ``` 2. Attach a debugger to Godot: * For VSCode this has been mostly setup for you, in `.vscode/launch.json` just set `configuration.program` to your Godot binary path. * For Visual Studio: TODO -3. Run the task with the debugger attached. \ No newline at end of file +3. Run the task with the debugger attached. diff --git a/docs/contribution/run-build-and-export.md b/docs/contribution/run-build-and-export.md index d0e81db7..1280d567 100644 --- a/docs/contribution/run-build-and-export.md +++ b/docs/contribution/run-build-and-export.md @@ -2,30 +2,66 @@ If you have haven't read the quick intro to Git see [Cloning](cloning.md) and [System Requirements](system-requirements.md) first. +The build presets are named `-`, where `` is `windows-x64`, `linux-x64`, or `macos-universal`, and `` is `template_debug`, `template_release`, or `editor`. The examples below use `windows-x64`; substitute your platform. On Windows every target also has `-clang` and `-mingw` suffixed presets for [alternative toolchains](#alternative-windows-toolchains). + ## Run With the project installed and system requirements ready: -1. Run `scons` in the project root. - * Ensure a `game/bin/openvic/libopenvic` file is produced for your platform (windows, linux, macos) +1. Configure, build, and install the extension in the project root: + ```sh + cmake --preset windows-x64-template_debug + cmake --build --preset windows-x64-template_debug + cmake --install out/build/windows-x64-template_debug --config Debug + ``` + * Ensure the install step produced an extension library for your platform in `game/bin/openvic`. 2. Open Godot, click import, navigate to the `game` directory and click `Import and Edit`. * Wait for the import to finish, close the editor without saving, then reopen the project in Godot. 3. Press the play button at the top right of the editor. ## Build -* To build for debug run `scons` in the project root. -* To build for debug with debug symbols and breakpoints run `scons dev_build=yes debug_symbols=yes` in the project root. -* To build for release run `scons target=template_release` +* To build for debug use the `windows-x64-template_debug` preset as above. +* To build for debug with dev-only debugging code and breakpoints use the `windows-x64-template_debug-dev` preset (`GODOTCPP_DEV_BUILD=ON`, Debug configuration). +* To build for release use the `windows-x64-template_release` preset (install with `--config Release`). + +## Alternative Windows toolchains + +MSVC is the primary Windows compiler, but LLVM clang-cl and MinGW GCC are also supported through dedicated presets. Every target has a `-clang` and a `-mingw` variant (`windows-x64-template_debug-clang`, `windows-x64-editor-mingw`, and so on); for example: + +```sh +cmake --preset windows-x64-template_release-clang +cmake --build --preset windows-x64-template_release-clang +``` + +```sh +cmake --preset windows-x64-template_release-mingw +cmake --build --preset windows-x64-template_release-mingw +``` + +Both produce the same artifact name and install layout as the MSVC preset. + +### clang-cl (LLVM) + +* Run from a "x64 Native Tools Command Prompt for VS" like an MSVC build — clang-cl uses the MSVC standard library, linker, and Windows SDK from that environment. +* The preset picks whichever `clang-cl` is first on your PATH. A Native Tools prompt puts Visual Studio's bundled clang-cl (from the "C++ Clang tools for Windows" component) ahead of everything else; to use a standalone [LLVM](https://releases.llvm.org/) install instead, prepend it *after* loading the VS environment: + ```bat + set "PATH=C:\Program Files\LLVM\bin;%PATH%" + ``` +* Use clang-cl, not `clang++`: godot-cpp's method bindings only support the MSVC-compatible clang driver on Windows. + +### MinGW (GCC) + +* Requires [mingw-w64](https://www.mingw-w64.org/) GCC 13+ (tested with 13.2) with its `bin` directory on PATH (`g++`, `gcc`, and `windres` must resolve). +* Build from a plain shell — do **not** load the VS environment. +* The preset sets `GODOTCPP_USE_STATIC_CPP=ON`, so libgcc/libstdc++/winpthread are linked statically and the resulting DLL has no MinGW runtime dependencies. ## Export -1. Build `scons` with either debug or release: - * For debug just run `scons` or `scons target=template_debug` - * For release just run `scons target=template_release` +1. Build and install with either the debug or release preset as above. 2. Open Godot and open the project. 3. Click `Project` at the top left and click `Export`. * If you do not have templates, download and install them, wait for them to complete. 4. Click `Export Project...` * If you built all binaries, you can click `Export All` and select debug or release there. 5. A file popup will appear, to export click `Save`: - * If you built scons with debug, leave `Export With Debug` ticked. - * Else untick `Export With Debug` for release. \ No newline at end of file + * If you built with the debug preset, leave `Export With Debug` ticked. + * Else untick `Export With Debug` for release. diff --git a/docs/contribution/system-requirements.md b/docs/contribution/system-requirements.md index 2f094ecc..cf1a7dcd 100644 --- a/docs/contribution/system-requirements.md +++ b/docs/contribution/system-requirements.md @@ -1,24 +1,25 @@ # System Requirements ## Build Requirements -* [Python 3.6+](https://www.python.org/downloads/) -* [Scons 3.0+](https://scons.org/) +* [CMake 3.28+](https://cmake.org/download/) +* [Ninja](https://ninja-build.org/) +* [Python 3.6+](https://www.python.org/downloads/) (used by the build for code generation) * [Godot 4](https://github.com/godotengine/godot) ### Windows Requirements * [Visual Studio Community](https://www.visualstudio.com/vs/community/) * [Python 3.6+](https://www.python.org/downloads/windows/) - Ensure the installer adds Python to your PATH (you can rerun the installer to do so) +* Optional alternative compilers, each with its own build preset (see [Run, Build, and Export](run-build-and-export.md#alternative-windows-toolchains)): + * [LLVM](https://releases.llvm.org/) clang-cl (Visual Studio still required for the standard library, linker, and Windows SDK) + * [mingw-w64](https://www.mingw-w64.org/) GCC 13+ -#### Installing Scons -With Python 3.6+ installed, you can install Scons through pip: -```sh -python -m pip install scons -``` -If you get `Defaulting to user installation because normal site-packages is not writable` then open a command prompt as Administrator and run the command again. When finished call: +#### Installing CMake and Ninja +Download CMake from [cmake.org](https://cmake.org/download/) (or install the "C++ CMake tools for Windows" component in the Visual Studio Installer, which includes Ninja). When finished call: ``` -scons --version +cmake --version +ninja --version ``` -to ensure that you are using a correct version of Scons. +to ensure both are on your PATH. Configure and build from a "x64 Native Tools Command Prompt for VS" (or any shell where the MSVC environment is loaded) so CMake can find the compiler. #### Installing Visual Studio Ensure that if you install from Visual Studio 2017, 2019 or 2022, ensure you're installing the C++ tools. @@ -33,7 +34,8 @@ If you're installing Visual Studio 2015, ensure you choose custom and pick C++ a ```sh apt-get install \ build-essential \ - scons \ + cmake \ + ninja-build \ pkg-config \ libx11-dev \ libxcursor-dev \ @@ -55,7 +57,8 @@ update-alternatives --set g++ /usr/bin/g++-12 #### Arch Linux Requirements ```sh pacman -S --needed \ - scons \ + cmake \ + ninja \ pkgconf \ gcc \ libxcursor \ @@ -76,12 +79,12 @@ pacman -S --needed \ #### Homebrew ```sh -brew install scons +brew install cmake ninja ``` #### MacPorts ```sh -sudo port install scons +sudo port install cmake ninja ``` -Credit: [Godot Docs](https://docs.godotengine.org/en/stable/contributing/development/compiling/index.html) \ No newline at end of file +Credit: [Godot Docs](https://docs.godotengine.org/en/stable/contributing/development/compiling/index.html) diff --git a/extension/deps/SCsub b/extension/deps/SCsub deleted file mode 100644 index 7cef12ad..00000000 --- a/extension/deps/SCsub +++ /dev/null @@ -1,23 +0,0 @@ -#!/usr/bin/env python - -Import("env") - - -def build_openvic_simulation(env): - ovsim_env = SConscript("openvic-simulation/SConstruct") - env.AppendUnique(CPPDEFINES=ovsim_env["CPPDEFINES"]) - env.Append(LIBPATH=ovsim_env.openvic_simulation["LIBPATH"]) - env.Prepend(LIBS=ovsim_env.openvic_simulation["LIBS"]) - env.Append(CPPPATH=ovsim_env.openvic_simulation["INCPATH"]) - env.openvic_simulation = ovsim_env.openvic_simulation - - -def build_gli(env): - gli_includes = ["gli", "gli/external"] - env.gli_loader = {} - env.gli_loader["INCPATH"] = [env.Dir(p) for p in gli_includes] - env.Append(CPPPATH=env.gli_loader["INCPATH"]) - - -build_openvic_simulation(env) -build_gli(env) diff --git a/extension/deps/gli b/extension/deps/gli deleted file mode 160000 index 779b99ac..00000000 --- a/extension/deps/gli +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 779b99ac6656e4d30c3b24e96e0136a59649a869 diff --git a/extension/deps/openvic-simulation b/extension/deps/openvic-simulation index d96116b7..718ab282 160000 --- a/extension/deps/openvic-simulation +++ b/extension/deps/openvic-simulation @@ -1 +1 @@ -Subproject commit d96116b7d6fc498bd97a70499db3c22495baba60 +Subproject commit 718ab2829d00f6309415b89c42dbd830ab230c21 diff --git a/extension/src/openvic-extension/components/budget/BudgetMenu.hpp b/extension/src/openvic-extension/components/budget/BudgetMenu.hpp index 2bb4b464..7594f327 100644 --- a/extension/src/openvic-extension/components/budget/BudgetMenu.hpp +++ b/extension/src/openvic-extension/components/budget/BudgetMenu.hpp @@ -16,7 +16,7 @@ namespace OpenVic { struct CountryInstance; - struct GUINode; + class GUINode; struct GUILabel; struct BudgetMenu { diff --git a/extension/src/openvic-extension/components/budget/DiplomaticBudget.hpp b/extension/src/openvic-extension/components/budget/DiplomaticBudget.hpp index bfc2a6b0..d0e55fef 100644 --- a/extension/src/openvic-extension/components/budget/DiplomaticBudget.hpp +++ b/extension/src/openvic-extension/components/budget/DiplomaticBudget.hpp @@ -8,7 +8,7 @@ namespace OpenVic { struct GUILabel; - struct GUINode; + class GUINode; struct DiplomaticBudget : public BudgetComponent, diff --git a/extension/src/openvic-extension/components/budget/NationalStockpileBudget.hpp b/extension/src/openvic-extension/components/budget/NationalStockpileBudget.hpp index 11cd3e51..035fe4ca 100644 --- a/extension/src/openvic-extension/components/budget/NationalStockpileBudget.hpp +++ b/extension/src/openvic-extension/components/budget/NationalStockpileBudget.hpp @@ -7,7 +7,7 @@ namespace OpenVic { struct GUILabel; - struct GUINode; + class GUINode; struct GUIScrollbar; struct NationalStockpileBudget : public BudgetComponent, public BudgetExpenseComponent { diff --git a/extension/src/openvic-extension/components/budget/abstract/SliderBudgetComponent.hpp b/extension/src/openvic-extension/components/budget/abstract/SliderBudgetComponent.hpp index d9c3646d..ab96b355 100644 --- a/extension/src/openvic-extension/components/budget/abstract/SliderBudgetComponent.hpp +++ b/extension/src/openvic-extension/components/budget/abstract/SliderBudgetComponent.hpp @@ -8,7 +8,7 @@ namespace OpenVic { struct CountryInstance; struct GUILabel; - struct GUINode; + class GUINode; struct GUIScrollbar; struct ReadOnlyClampedValue; diff --git a/extension/src/openvic-extension/components/overview/BudgetOverview.hpp b/extension/src/openvic-extension/components/overview/BudgetOverview.hpp index 5f83adce..8cebf567 100644 --- a/extension/src/openvic-extension/components/overview/BudgetOverview.hpp +++ b/extension/src/openvic-extension/components/overview/BudgetOverview.hpp @@ -3,7 +3,7 @@ namespace OpenVic { struct GUILabel; struct GUILineChart; - struct GUINode; + class GUINode; struct BudgetOverview { private: diff --git a/extension/src/openvic-extension/components/overview/ScoreOverview.hpp b/extension/src/openvic-extension/components/overview/ScoreOverview.hpp index aca8855c..223a4d8d 100644 --- a/extension/src/openvic-extension/components/overview/ScoreOverview.hpp +++ b/extension/src/openvic-extension/components/overview/ScoreOverview.hpp @@ -11,7 +11,7 @@ namespace OpenVic { struct GUIIcon; struct GUIMaskedFlagButton; struct GUILabel; - struct GUINode; + class GUINode; struct fixed_point_t; struct ScoreOverview : public observer { diff --git a/extension/src/openvic-extension/components/overview/TopBar.hpp b/extension/src/openvic-extension/components/overview/TopBar.hpp index 2ce6d7c8..578546af 100644 --- a/extension/src/openvic-extension/components/overview/TopBar.hpp +++ b/extension/src/openvic-extension/components/overview/TopBar.hpp @@ -4,7 +4,7 @@ #include "openvic-extension/components/overview/ScoreOverview.hpp" namespace OpenVic { - struct GUINode; + class GUINode; struct TopBar { private: diff --git a/game/bin/openvic.gdextension b/game/bin/openvic.gdextension index 764e0c5d..b2b70541 100644 --- a/game/bin/openvic.gdextension +++ b/game/bin/openvic.gdextension @@ -6,11 +6,12 @@ reloadable = true [libraries] +linux.x86_64.editor = "res://bin/openvic/libopenvic.linux.editor.x86_64.so" +windows.x86_64.editor = "res://bin/openvic/openvic.windows.editor.x86_64.dll" +macos.editor = "res://bin/openvic/libopenvic.macos.editor.dylib" linux.x86_64.debug = "res://bin/openvic/libopenvic.linux.template_debug.x86_64.so" linux.x86_64.release = "res://bin/openvic/libopenvic.linux.template_release.x86_64.so" -linux.debug.arm64 = "res://bin/openvic/libopenvic.linux.template_debug.arm64.so" -linux.release.arm64 = "res://bin/openvic/libopenvic.linux.template_release.arm64.so" -windows.x86_64.debug = "res://bin/openvic/libopenvic.windows.template_debug.x86_64.dll" -windows.x86_64.release = "res://bin/openvic/libopenvic.windows.template_release.x86_64.dll" -macos.debug = "res://bin/openvic/libopenvic.macos.template_debug.framework" -macos.release = "res://bin/openvic/libopenvic.macos.template_release.framework" +windows.x86_64.debug = "res://bin/openvic/openvic.windows.template_debug.x86_64.dll" +windows.x86_64.release = "res://bin/openvic/openvic.windows.template_release.x86_64.dll" +macos.debug = "res://bin/openvic/libopenvic.macos.template_debug.dylib" +macos.release = "res://bin/openvic/libopenvic.macos.template_release.dylib" diff --git a/godot-cpp b/godot-cpp deleted file mode 160000 index 5ffd70e3..00000000 --- a/godot-cpp +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 5ffd70e34d0ab87009a9f0ffa3361bc8f4b09731 diff --git a/pyproject.toml b/pyproject.toml index 88ee22b5..f8c0f50c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,7 +11,6 @@ namespace_packages = true explicit_package_bases = true [tool.ruff] -extend-include = ["SConstruct", "SCsub"] line-length = 120 target-version = "py37" @@ -20,12 +19,6 @@ extend-select = [ "I", # isort ] -[tool.ruff.lint.per-file-ignores] -"{SConstruct,SCsub}" = [ - "E402", # Module level import not at top of file - "F821", # Undefined name -] - [tool.typos] files.extend-exclude = [".mailmap", "*.gitignore", "*.po", "*.pot", "*.rc"] default.extend-ignore-re = [ diff --git a/scripts b/scripts deleted file mode 160000 index 9f8318fb..00000000 --- a/scripts +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 9f8318fb9f34fc49709ad8227577438e488dc88b