Proposal: Unified cross-platform build system using mise
#3908
Sephyi
started this conversation in
Engineering Discussion
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
Summary
I'd like to propose adopting
mise(formerlyrtx) as a single, unified build orchestration layer for the FXServer build, replacing the scattered Windows-centric tooling with one config file (mise.toml) that works identically on macOS, Linux, and Windows. The change is purely additive — existing build paths (fxd, GitLab CI, Visual Studio) continue to work unchanged.I have a working implementation on a personal fork that compiles FXServer cleanly on macOS ARM (Apple Silicon) for the first time, in addition to Linux and Windows. I'd like to discuss whether upstream is interested before opening a PR.
Problem statement
The current developer tooling is deeply Windows-centric:
fxd.ps1andcode/tools/fxd/*.ps1are PowerShell-only and contain hardcoded paths like$env:WINDIR\system32\tar.exe,curl.exe,vswhere.exe,premake5.exe,nuget.exe.fxd wsl-build) orcode/tools/ci/build_server_docker_alpine.shrunningprootinside Docker — there is no native developer entry point.fxd.ps1,code/tools/fxd/*.ps1,code/tools/ci/psm1/*.psm1,code/tools/ci/build_server_docker_alpine.sh,code/tools/ci/build_server_proot_alpine.sh, andwsl-build.sh— with no single entry point.Proposed solution
Add a single
mise.tomlat the repository root that:premake5,lua,python,cmakeare declared with exact versions and installed bymise installon all three operating systems.mise run build,mise run gen,mise run server, etc. Each task lives in one block withrun(Unix sh) andrun_windows(PowerShell) variants.podmanordocker, transparently.code/tools/ci/docker-builder/Dockerfile→code/tools/container/Containerfile(renamed to the OCI standard, moved out ofci/since it's now a developer tool, not just CI).Why
miseovermake/just/Taskfile/cmakemisejustTaskfilemakecmakerun+run_windows[unix]/[windows]attrsplatforms:filtermise installpremake5?miseis the only option that solves both the toolchain problem (getting the rightpremake5/lua/clangversions) and the task orchestration problem in one tool. The others would needmise(orasdf) alongside them anyway.cmakewould require rewriting hundreds of.luafiles and the entire vendor/component system.premake5works fine cross-platform — there's no reason to replace it.Tasks
A new contributor on any OS does:
Or for the reproducible Linux build:
Renames / moves
code/tools/ci/docker-builder/Dockerfilecode/tools/container/Containerfilecode/tools/ci/docker-builder/proot_prepare.shcode/tools/container/proot_prepare.shUpdated references in
.gitlab-ci.yml,.github/workflows/build_alpine_container.yml, andcode/tools/ci/wsl-build.sh.Cross-platform fixes to existing files
The existing
fxdPowerShell scripts also got cross-platform fixes so they keep working as a secondary entry point on macOS/Linux:fxd.ps1:Join-Pathinstead of\literals;& $scriptinstead ofInvoke-Expression(the latter breaks with spaces in paths).code/tools/fxd/gen.ps1: detects OS, runspremake5 gmake2on non-Windows andvs2022on Windows.code/tools/fxd/build.ps1:makeon Unix,MSBuildon Windows.code/tools/fxd/get-chrome.ps1: platform-awarecurl/tarcommands instead ofcurl.exe/tar.exe.code/tools/ci/psm1/cfxBuildTools.psm1: platform-aware tool resolution inGet-CfxBuildTools.code/tools/ci/psm1/cfxSetupCEF.psm1:Join-Paththroughout, platform-aware curl.Native macOS build support
Note
The macOS porting work was a side-effect of building this proposal, since macOS is my primary working environment. It's not the central pitch — the core proposal is the unified
mise-based build orchestration. The macOS support is a bonus that falls out naturally once the build system stops being Windows-only.Getting FXServer to actually compile on macOS Apple Silicon required vendor-level porting work. All changes are guarded by
os.istarget('macosx')and don't affect Linux or Windows builds.Vendor library patches (click to expand)
ucontextremoved in macOS 26 SDK__TBB_RESUMABLE_TASKS_USE_THREADS(already done for Linux)-mrtm/-mwaitpkgare x86-onlyarchitecture:x86_64filterssize_t=longwhich conflicts with macOS nativessize_tclockid_tdouble-declared (FOLLY_NO_CONFIGskips detection)FOLLY_HAVE_CLOCK_GETTIME=1on macOS (10.12+)char_traits<unsigned char>needed byfolly::RangeNNG_PLATFORM_DARWIN+ kqueue-based poll queueOS_LINUXon all non-Windows;endian.hnot on macOSOS_MACOSXon macOSHAVE_PTHREADonly on Linux_POSIX_SOURCEredefinition breaks_stdio.h)-lz) on macOSlibcurl_dummy.afailsaron macOS.dylib(only.so/.dllin repo)getticks()only implemented for x86/sparc,#erroron aarch64utils.hppoverlay withmrs cntvct_el0ARM64 implementation__has_include(<x86intrin.h>)wrongly succeeds on ARMGLM_FORCE_SSE2define on ARM_llocale functions movedxlocale/_*.hheadershtole32/htole64not on macOSOSSwapHostToLittleInt*src/**.cincludingimpl_x86_macos.con ARMHAVE_SYSCTLBYNAMEelsebranch on non-Linux included Windows crash handlermemaligndoesn't exist on macOSposix_memalign(already POSIX-standard)Toolchain notes (click to expand)
code/premake5.lua— skiparchitecture 'x64'on macOS (use native ARM64), applyvectorextensions 'SSSE3'only on x86_64._llocale functions (strtod_l, etc.) moved out of the global namespace. Fix: use Homebrew LLVM and force-includexlocale/_stdlib.h,xlocale/_string.h,xlocale/_stdio.hfor C++ compilation.-D_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTRand-D_LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION(lua-rapidjson usesstd::unary_function).System.Runtime.dll,System.IO.dll) are at$(brew --prefix mono)/lib/mono/4.5/Facades/on macOS instead of/usr/lib/mono/4.5/Facades/.IDL generation — Python becomes optional
The Python IDL tool (Mozilla XPIDL parser) is now optional. There are only 3
.idlfiles in the entire repo and they change rarely (~10 times in project history). The generated.hfiles can be committed alongside the.idlsources, treating them as source-controlled artifacts (like lock files).mise run idl:genregenerates them when an.idlfile changes. Python is no longer required for a normal build.Native definitions — pure-Lua replacement for native-doc-tooling
The CFX-specific natives codegen pipeline (
ext/native-doc-gen/build.sh) requires Node.js + a custom libclang Node binding (citizenfx/node-libclang) that's hard to build on macOS. I added a small pure-Lua parser (ext/natives/gen_natives_cfx.lua) that reads the existing markdown declarations inext/native-decls/directly and generatesnatives_cfx.lua— no Node.js, no libclang, runs on every platform with just the bundledluaandcfx.somodules. Generates 864 natives. This could replace the Node.js pipeline entirely if upstream agrees the Lua-based approach is sufficient.Known limitation
JavaScript scripting (
libnode22) does not work on macOS in the current state. Thelibnode22.so/dllbinaries committed to git LFS are built from a CitizenFX-patched Node 22.22 source that isn't publicly available — thevendor/nodesubmodule is stuck oncfx/node-16which is incompatible with the C++ code that uses Node 22 / V8 12.4 APIs.To fix this we would need either:
cfx/node-22branch incitizenfx/node.libnode22from scratch (vanilla Node 22 + the CFX patches).Lua and C# (Mono) scripting work fine on macOS. Most FiveM resources use Lua, so the limitation is acceptable for development workflows.
Why this matters
premake5 5.0.0-beta8,lua 5.3, etc.miseis widely adopted, well-maintained, and the right shape for polyglot projects like this one.Open questions for upstream
miseas a developer tooling layer? If so, I'll prepare a clean PR.Containerfilerename, or should it stay atDockerfilefor compatibility?cfx/node-22branch (or macOSlibnode22.dylibprebuilt) so JS scripting works on macOS too?.idlsources to eliminate Python from the build?Status
Working implementation on a personal fork — happy to share the branch or open a draft PR for review. The branch is ~16 commits, all guarded by platform filters, fully additive to the existing build paths.
Beta Was this translation helpful? Give feedback.
All reactions