Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 109 additions & 0 deletions BUILD.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
# Building the Decompfrontier Server (Windows)

This repo uses CMake Presets + vcpkg. On Windows the only generator is **Ninja Multi-Config** — there is no Visual Studio solution preset. If you prefer the VS IDE, open the folder with `File > Open Folder` and VS will pick up the presets automatically.

## Prerequisites

1. **Visual Studio 2022 or 2026** with the "Desktop development with C++" workload.
The toolset version doesn't matter — Ninja picks up whatever `cl.exe` is on `PATH`.
2. **CMake** 3.21 or newer (ships with VS).
3. **Ninja** (ships with VS; or `choco install ninja`).
4. **vcpkg**. Set `VCPKG_ROOT` in your environment to the vcpkg checkout.
5. **Rust toolchain** (`cargo` on `PATH`). Install from <https://rustup.rs/>. The build compiles the Rust-based `packet-generator` CLI from source on the first build.

## One-time setup

From any shell:

```cmd
git clone https://github.com/microsoft/vcpkg %USERPROFILE%\vcpkg
%USERPROFILE%\vcpkg\bootstrap-vcpkg.bat
setx VCPKG_ROOT %USERPROFILE%\vcpkg
```

Restart your shell so `VCPKG_ROOT` is visible.

## Configuring and building

Every command below must run from an **x64 Native Tools Command Prompt** — specifically one where `VsDevCmd.bat -arch=amd64 -host_arch=amd64` has been sourced. This ensures the **x64-hosted** `cl.exe` (`Hostx64\x64\cl.exe`) is on PATH.

> **Common mistake:** The regular "Developer PowerShell for VS 2026" and the default "Developer Command Prompt" both put the **x86-hosted** `cl.exe` on PATH. CMake then compiles x86 objects but tries to link them as x64, giving `LNK1112: module machine type 'x86' conflicts with target machine type 'x64'`. Always use one of the options below.

**Option A — Start menu shortcut (easiest):**
Launch `x64 Native Tools Command Prompt for VS 2026` from the Start menu.

**Option B — From any shell:**
```cmd
call "C:\Program Files\Microsoft Visual Studio\18\Community\Common7\Tools\VsDevCmd.bat" -arch=amd64 -host_arch=amd64
```

Then build:

```cmd
cd C:\path\to\BF-WorkingDirRust

:: Configure (first time, or after editing CMake files)
cmake --preset debug-win64

:: Build Debug
cmake --build --preset debug-win64-debug

:: Build Release
cmake --build --preset debug-win64-release
```

`rebuild.bat` handles all of this automatically — it calls `VsDevCmd.bat -arch=amd64 -host_arch=amd64` internally, so you can run it from any prompt.

Artifacts land under `out/build/debug-win64/`.

### Linux

```bash
cmake --preset debug-lnx64
cmake --build --preset debug-lnx64
```

## Presets at a glance

| Preset | Generator | Triplet | Frontend |
|---|---|---|---|
| `debug-win64` | Ninja Multi-Config | `x64-windows` | `STANDALONE` |
| `release-win32` | Ninja Multi-Config | `x86-windows-static` | `PROXYAPPX` |
| `debug-lnx64` | Ninja | `x64-linux` | `STANDALONE` |

Both Windows presets produce Debug **and** Release binaries from one build tree — pick the configuration at build time via `--config Debug` / `--config Release`, or use the paired build presets (`debug-win64-debug`, `debug-win64-release`, etc.).

## The packet-generator step

The Rust CLI at `packet-generator/` compiles the KDL schemas in `packet-generator/assets/` into a single C++ header at `gimuserver/packets/all.hpp`. CMake runs this automatically via the `pkgen_generate` custom target whenever a `.kdl` file changes.

- **First build is slow** (2–5 min) because Cargo compiles the generator itself.
- **Subsequent builds re-run the generator only when a `.kdl` file is newer than `gimuserver/packets/all.hpp`.**
- **Generated file is gitignored** — `gimuserver/packets/.gitignore` excludes `*.hpp`.

To invoke the generator by hand (rarely needed):

```cmd
cd packet-generator
cargo run --release -- generate --cxx --glaze -i assets/all.kdl -o ../gimuserver/packets
```

## Troubleshooting

**`MSB8020: build tools for Visual Studio 2022 (Platform Toolset = 'v143') cannot be found`**
You're on an old preset that pinned the VS 17 2022 generator. Pull the latest presets — they all use Ninja Multi-Config now, which is toolset-agnostic.

**`LNK1112: module machine type 'x86' conflicts with target machine type 'x64'`**
You ran CMake from a shell that has the **x86-hosted** `cl.exe` on PATH (e.g. regular Developer PowerShell or the default Developer Command Prompt). Delete `out/`, then re-run from the **x64 Native Tools Command Prompt for VS 2026** or via `rebuild.bat`.

**`cl : command line error D8021 : invalid numeric argument`** or linker complains it can't find `kernel32.lib`
You're not in a Developer Command Prompt at all. `cl.exe` needs the VC environment set up first.

**`cargo: command not found`**
Rust isn't on `PATH`. Install via <https://rustup.rs/> and restart the shell.

**First build hangs at `Regenerating C++ packet headers from KDL schemas`**
Cargo is compiling `packet-generator` from source. Wait it out; subsequent builds are fast.

**Generated types don't exist after editing a KDL file**
Build again — the custom target re-runs on any `.kdl` change. If it still doesn't regenerate, delete `gimuserver/packets/all.hpp` and build; that forces a rerun.
51 changes: 51 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,57 @@ find_package(unofficial-sqlite3 CONFIG REQUIRED)
find_package(glaze CONFIG REQUIRED) # c++ JSON abstraction

add_subdirectory(packet-generator/assets/runtime/cpp)

# KDL -> C++ codegen. The packet-generator Rust CLI compiles assets/all.kdl
# into a single flat header (all.hpp) that gimuserver includes. The first
# build compiles the Rust generator itself (one-time, a few minutes); every
# subsequent build only re-runs it when a .kdl file has changed.
find_program(CARGO_EXECUTABLE cargo
DOC "Rust/Cargo toolchain, required to build packet-generator"
)
if (NOT CARGO_EXECUTABLE)
message(FATAL_ERROR
"cargo not found on PATH. Install Rust from https://rustup.rs/ "
"and re-run CMake configure."
)
endif()

set(PKGEN_SRC_DIR "${CMAKE_SOURCE_DIR}/packet-generator")
set(PKGEN_ENTRY "assets/all.kdl")
# App.hpp includes <gimuserver/packets/all.hpp>, so emit directly into the
# source tree under gimuserver/packets/. That directory has a .gitignore
# (*.hpp) that keeps the generated header out of version control.
set(PKGEN_OUT_DIR "${CMAKE_SOURCE_DIR}/gimuserver/packets")
set(PKGEN_OUT_HEADER "${PKGEN_OUT_DIR}/all.hpp")

file(GLOB_RECURSE KDL_SCHEMAS CONFIGURE_DEPENDS
"${PKGEN_SRC_DIR}/assets/*.kdl"
)

file(MAKE_DIRECTORY "${PKGEN_OUT_DIR}")

add_custom_command(
OUTPUT "${PKGEN_OUT_HEADER}"
COMMAND "${CARGO_EXECUTABLE}" run --release --
generate --cxx --glaze
-i "${PKGEN_ENTRY}"
-o "${PKGEN_OUT_DIR}"
WORKING_DIRECTORY "${PKGEN_SRC_DIR}"
DEPENDS ${KDL_SCHEMAS}
COMMENT "Regenerating C++ packet headers from KDL schemas"
VERBATIM
)

add_custom_target(pkgen_generate ALL
DEPENDS "${PKGEN_OUT_HEADER}"
SOURCES ${KDL_SCHEMAS}
)

message(STATUS
"packet-generator: first build compiles the Rust generator (~2-5 min); "
"subsequent builds only re-run it when .kdl files change."
)

add_subdirectory(gimuserver)

if (STANDALONE)
Expand Down
52 changes: 42 additions & 10 deletions CMakePresets.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
{
"name": "default-debug",
"displayName": "Config Debug",
"description": "General default debug configuration",
"description": "General default debug configuration (single-config generators only)",
"inherits": "default-base",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug"
Expand All @@ -26,7 +26,7 @@
{
"name": "default-release",
"displayName": "Config Release",
"description": "General default release configuration",
"description": "General default release configuration (single-config generators only)",
"inherits": "default-base",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "RelWithDebInfo"
Expand All @@ -35,10 +35,11 @@
},
{
"name": "debug-win64",
"displayName": "Development config for Windows (64-bit)",
"inherits": "default-debug",
"generator": "Visual Studio 17 2022",
"architecture": "x64",
"displayName": "Development config for Windows (Ninja Multi-Config)",
"description": "Multi-config (Debug + Release) build for Windows x64. Must be run from an x64 Native Tools environment (VsDevCmd.bat -arch=amd64 -host_arch=amd64) so the x64-hosted cl.exe is on PATH. Do NOT set CMAKE_C/CXX_COMPILER here — let CMake find the compiler from the environment so it inherits the correct host/target architecture.",
"inherits": "default-base",
"generator": "Ninja Multi-Config",
"binaryDir": "${sourceDir}/out/build/${presetName}",
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
Expand Down Expand Up @@ -78,10 +79,15 @@
},
{
"name": "release-win32",
"displayName": "Deployment for Brave Frontier for Windows",
"inherits": "default-release",
"generator": "Visual Studio 17 2022",
"architecture": "x64",
"displayName": "Deployment for Brave Frontier for Windows (APPX)",
"description": "Multi-config build producing the APPX-embedded server. Requires running from a Developer Command Prompt for Visual Studio.",
"inherits": "default-base",
"generator": "Ninja Multi-Config",
"binaryDir": "${sourceDir}/out/build/${presetName}",
"architecture": {
"value": "x64",
"strategy": "external"
},
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
Expand All @@ -98,5 +104,31 @@
}
}
}
],
"buildPresets": [
{
"name": "debug-win64-debug",
"configurePreset": "debug-win64",
"configuration": "Debug"
},
{
"name": "debug-win64-release",
"configurePreset": "debug-win64",
"configuration": "Release"
},
{
"name": "release-win32-debug",
"configurePreset": "release-win32",
"configuration": "Debug"
},
{
"name": "release-win32-release",
"configurePreset": "release-win32",
"configuration": "Release"
},
{
"name": "debug-lnx64",
"configurePreset": "debug-lnx64"
}
]
}
Loading