1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
|
-- Copyright Epic Games, Inc. All Rights Reserved.
set_configvar("ZEN_SCHEMA_VERSION", 5) -- force state wipe after 0.2.31 causing bad data (dan.engelbrecht)
set_configvar("ZEN_DATA_FORCE_SCRUB_VERSION", 0)
set_allowedplats("windows", "linux", "macosx")
set_allowedarchs("windows|x64", "linux|x86_64", "macosx|x86_64", "macosx|arm64")
-- Returns true when building for Windows with native MSVC (not clang-cl cross-compilation)
function is_native_msvc()
local tc = get_config("toolchain") or ""
return is_plat("windows") and tc ~= "clang-cl"
end
--------------------------------------------------------------------------
-- We support debug and release modes. On Windows we use static CRT to
-- minimize dependencies.
set_allowedmodes("debug", "release")
add_rules("mode.debug", "mode.release")
-- Disable xmake's run.autobuild (on by default in xmake 3.x). Auto-rebuild
-- before run is dangerous: if the current config differs from the build that
-- produced the binary (e.g. ASAN was toggled), xmake can rebuild with wrong
-- flags, causing linker errors (e.g. MSVC annotate_string mismatch). Users
-- are expected to run `xmake build` explicitly before `xmake run`.
set_policy("run.autobuild", false)
if is_plat("windows") then
if false then
-- DLL runtime
if is_mode("debug") then
set_runtimes("MDd")
else
set_runtimes("MD")
end
else
-- static runtime
if is_mode("debug") then
set_runtimes("MTd")
else
set_runtimes("MT")
end
end
end
-- Sanitizers
--
-- https://xmake.io/api/description/builtin-policies.html#build-sanitizer-address
--
-- Each sanitizer has a .supp file (asan.supp, tsan.supp, msan.supp). A single
-- sanitizer.options rule handles all three in one before_run callback.
--
-- asan.supp and msan.supp contain key=value runtime options (no native
-- "options from file" mechanism exists for either sanitizer on any platform).
--
-- tsan.supp is a mixed-format file: key=value runtime options (parsed by xmake
-- and set in TSAN_OPTIONS) plus native TSAN suppression patterns (race:...,
-- mutex:...) that are passed via TSAN_OPTIONS=suppressions=<path> on Linux/Mac.
-- The TSAN runtime silently skips key=value lines when parsing the suppression
-- file (they don't match type:pattern; TSAN emits a verbose-level warning).
--
-- IMPORTANT: The env vars are set by xmake's before_run hook. If you run a
-- binary directly (not via xmake run / xmake test) you must set them manually.
--------------------------------------------------------------------------
-- AddressSanitizer is supported on Windows (MSVC 2019+), Linux, and MacOS.
-- Enable with: `xmake config --asan=y` or `xmake test --asan`
-- (automatically disables mimalloc and sentry, which are incompatible with ASAN)
--
-- Options live in asan.supp. For manual runs:
-- Linux/Mac: ASAN_OPTIONS="new_delete_type_mismatch=0" ./zenserver
-- Windows: set ASAN_OPTIONS=new_delete_type_mismatch=0
option("asan")
set_default(false)
set_showmenu(true)
set_description("Enable AddressSanitizer (disables mimalloc and sentry)")
option_end()
-- Global flag: read by sub-target xmake.lua files (like enable_unity)
use_asan = has_config("asan")
if use_asan then
set_policy("build.sanitizer.address", true)
-- On Windows/MSVC, explicitly define __SANITIZE_ADDRESS__ so that
-- IntelliSense in VS sees it (XmakeDefines -> PreprocessorDefinitions).
-- MSVC sets it implicitly at compile time via /fsanitize=address, but
-- vsxmake IntelliSense needs it in the explicit defines list.
-- Not needed on Clang/GCC: they set it implicitly and adding it via -D
-- would cause a macro-redefinition warning (error with -Werror).
if is_os("windows") then
add_defines("__SANITIZE_ADDRESS__=1")
end
end
--------------------------------------------------------------------------
-- ThreadSanitizer is supported on Linux and MacOS only.
-- Enable with: `xmake config --tsan=y` or `xmake test --tsan`
--
-- Key=value options and suppression patterns both live in tsan.supp. For
-- manual runs: TSAN_OPTIONS="detect_deadlocks=0:suppressions=$(pwd)/tsan.supp"
option("tsan")
set_default(false)
set_showmenu(true)
set_description("Enable ThreadSanitizer (Linux/Mac only)")
option_end()
use_tsan = has_config("tsan")
if use_tsan then
if is_os("windows") then
raise("TSAN is not supported on Windows. Use Linux or macOS.")
end
set_policy("build.sanitizer.thread", true)
end
--------------------------------------------------------------------------
-- MemorySanitizer is supported on Linux only. In practice it rarely works
-- because all dependencies must also be compiled with MSan instrumentation.
-- Enable with: `xmake config --msan=y` or `xmake test --msan`
--
-- Options live in msan.supp. For manual runs: set MSAN_OPTIONS manually.
option("msan")
set_default(false)
set_showmenu(true)
set_description("Enable MemorySanitizer (Linux only, requires all deps instrumented)")
option_end()
use_msan = has_config("msan")
if use_msan then
set_policy("build.sanitizer.memory", true)
end
--------------------------------------------------------------------------
-- Single rule handles all three sanitizer env vars. parse_supp_opts is defined
-- once inside before_run (scripting scope) where io is a valid global.
rule("sanitizer.options")
before_run(function(target)
-- Parses key=value lines from a .supp file. Blank lines and lines whose
-- first non-whitespace character is '#' are ignored. Suppression-pattern
-- lines (race:..., mutex:...) don't match ^[%w_]+= and are skipped.
local function parse_supp_opts(filepath)
local opts = {}
local content = os.isfile(filepath) and io.readfile(filepath) or ""
for line in content:gmatch("[^\r\n]+") do
line = line:match("^%s*(.-)%s*$")
if line ~= "" and not line:match("^#") and line:match("^[%w_]+=") then
table.insert(opts, line)
end
end
return opts
end
if target:policy("build.sanitizer.address") and not os.getenv("ASAN_OPTIONS") then
local opts = parse_supp_opts(path.join(os.projectdir(), "asan.supp"))
if #opts > 0 then
os.setenv("ASAN_OPTIONS", table.concat(opts, ":"))
end
end
if target:policy("build.sanitizer.thread") and not os.getenv("TSAN_OPTIONS") then
local suppfile = path.join(os.projectdir(), "tsan.supp")
local opts = parse_supp_opts(suppfile)
-- Also pass the suppression patterns via the native file mechanism when
-- both conditions hold:
-- 1. Not clang-cl: file path support requires the LLVM/GCC TSAN runtime.
-- 2. Platform is Linux or macOS: TSAN is unavailable on Windows
-- (config-time raise() above prevents reaching here on Windows).
local tc_name = get_config("toolchain") or ""
local is_not_clang_cl = tc_name ~= "clang-cl"
if os.isfile(suppfile) and is_not_clang_cl
and (target:is_plat("linux") or target:is_plat("macosx")) then
table.insert(opts, "suppressions=" .. suppfile)
end
if #opts > 0 then
os.setenv("TSAN_OPTIONS", table.concat(opts, ":"))
end
end
if target:policy("build.sanitizer.memory") and not os.getenv("MSAN_OPTIONS") then
local opts = parse_supp_opts(path.join(os.projectdir(), "msan.supp"))
if #opts > 0 then
os.setenv("MSAN_OPTIONS", table.concat(opts, ":"))
end
end
end)
rule_end()
add_rules("sanitizer.options")
--set_policy("build.sanitizer.leak", true)
--set_policy("build.sanitizer.undefined", true)
--------------------------------------------------------------------------
-- Dependencies
add_repositories("zen-repo repo")
set_policy("build.ccache", false)
set_policy("package.precompiled", false)
add_defines("gsl_FEATURE_GSL_COMPATIBILITY_MODE=1")
add_requires("gsl-lite", {system = false})
add_requires("http_parser", {system = false})
add_requires("json11", {system = false})
add_requires("lua", {system = false})
add_requires("lz4", {system = false})
add_requires("xxhash", {system = false})
add_requires("zlib", {system = false})
add_defines("EASTL_STD_ITERATOR_CATEGORY_ENABLED", "EASTL_DEPRECATIONS_FOR_2024_APRIL=EA_DISABLED")
add_requires("eastl", {system = false})
add_requires("consul", {system = false}) -- for hub tests
add_requires("minio RELEASE.2025-07-23T15-54-02Z", {system = false}) -- for S3 storage tests
add_requires("nomad", {system = false}) -- for nomad provisioner tests
add_requires("oidctoken", {system = false})
if has_config("zenmimalloc") and not use_asan then
add_requires("mimalloc", {system = false})
end
--------------------------------------------------------------------------
-- Crypto configuration. For reasons unknown each platform needs a
-- different package
if is_plat("windows") then
-- we use schannel on Windows
add_defines("ZEN_USE_OPENSSL=0")
add_requires("libcurl", {system = false})
elseif is_plat("linux", "macosx") then
add_requires("openssl3", {system = false})
add_defines("ZEN_USE_OPENSSL=1")
add_requires("libcurl", {system = false, configs = {openssl3 = true}})
end
--------------------------------------------------------------------------
if is_plat("windows") then
-- for bundling, Linux tries to compile from source which fails with UE toolchain,
-- fallback is regular zip
add_requires("7z")
end
-- When using the UE clang toolchain, statically link the toolchain's libc++ and
-- libc++abi to avoid ABI mismatches with system libraries at runtime.
-- These are project-level flags (not in the toolchain definition) so they don't
-- propagate into cmake package builds.
if is_plat("linux") and get_config("toolchain") == "ue-clang" then
add_ldflags("-static-libstdc++", {force = true})
add_ldflags("$(projectdir)/thirdparty/ue-libcxx/lib64/libc++.a", {force = true})
add_ldflags("$(projectdir)/thirdparty/ue-libcxx/lib64/libc++abi.a", {force = true})
add_ldflags("-lpthread", {force = true})
end
if has_config("zensentry") and not use_asan then
if is_plat("linux") then
add_requires("sentry-native 0.12.1", {configs = {backend = "crashpad"}})
elseif is_plat("windows") then
add_requires("sentry-native 0.12.1", {debug = is_mode("debug"), configs = {backend = "crashpad"}})
else
add_requires("sentry-native 0.12.1", {configs = {backend = "crashpad"}})
end
end
enable_unity = false
--add_rules("c++.unity_build")
if is_mode("release") then
-- LTO does not appear to work with the current Linux UE toolchain
-- Also, disabled LTO on Mac to reduce time spent building openssl tests
-- Disabled for cross-compilation (clang-cl on Linux) due to cmake package compat issues
local is_cross_win = is_plat("windows") and is_host("linux")
if not is_plat("linux", "macosx") and not is_cross_win then
set_policy("build.optimization.lto", true)
end
set_optimize("fastest")
end
if is_mode("debug") then
add_defines("DEBUG")
end
if is_mode("debug") then
add_defines("ZEN_WITH_TESTS=1")
else
add_defines("ZEN_WITH_TESTS=0")
end
-- fmt 11+ requires utf-8 when using unicode
if is_os("windows") then
set_encodings("utf-8")
else
set_encodings("source:utf-8", "target:utf-8")
end
-- When cross-compiling with clang-cl, the xwin SDK may ship a newer MSVC STL
-- than the host clang version supports. Bypass the version gate.
if is_plat("windows") and not is_native_msvc() then
add_defines("_ALLOW_COMPILER_AND_STL_VERSION_MISMATCH")
end
if is_os("windows") then
add_defines(
"_CRT_SECURE_NO_WARNINGS",
"_UNICODE",
"UNICODE",
"_CONSOLE",
"NOMINMAX", -- stop Windows SDK defining 'min' and 'max'
"NOGDI", -- otherwise Windows.h defines 'GetObject'
"WIN32_LEAN_AND_MEAN", -- cut down Windows.h
"_WIN32_WINNT=0x0A00",
"_WINSOCK_DEPRECATED_NO_WARNINGS" -- let us use the ANSI functions
)
-- Make builds more deterministic and portable (MSVC-only flags)
if is_native_msvc() then
add_cxxflags("/d1trimfile:$(curdir)\\") -- eliminates the base path from __FILE__ paths
add_cxxflags("/experimental:deterministic") -- (more) deterministic compiler output
add_ldflags("/PDBALTPATH:%_PDB%") -- deterministic pdb reference in exe
add_cxxflags("/Zc:u8EscapeEncoding") -- Enable UTF-8 encoding for u8 string literals (clang does this by default)
add_cxxflags("/Zc:preprocessor") -- Enable preprocessor conformance mode
add_cxxflags("/Zc:inline") -- Enforce inline semantics
end
-- add_ldflags("/MAP")
end
-- Clang warning suppressions (native clang on Linux/Mac, or clang-cl cross-compile)
if is_os("linux") or is_os("macosx") or not is_native_msvc() then
-- Silence warnings about unrecognized -Wno-* flags on older clang versions
add_cxxflags("-Wno-unknown-warning-option", {force = true})
add_cxxflags("-Wno-delete-non-abstract-non-virtual-dtor", {force = true})
add_cxxflags("-Wno-format", {force = true})
add_cxxflags("-Wno-implicit-fallthrough", {force = true})
add_cxxflags("-Wno-inconsistent-missing-override", {force = true})
add_cxxflags("-Wno-missing-field-initializers", {force = true})
add_cxxflags("-Wno-nonportable-include-path", {force = true})
add_cxxflags("-Wno-sign-compare", {force = true})
add_cxxflags("-Wno-strict-aliasing", {force = true})
add_cxxflags("-Wno-switch", {force = true})
add_cxxflags("-Wno-unused-lambda-capture", {force = true})
add_cxxflags("-Wno-unused-private-field", {force = true})
add_cxxflags("-Wno-unused-value", {force = true})
add_cxxflags("-Wno-unused-variable", {force = true})
add_cxxflags("-Wno-vla-cxx-extension", {force = true})
-- GCC false positive: constinit static locals used by reference are reported as unused-but-set
add_cxxflags("-Wno-unused-but-set-variable", {tools = "gcc"})
end
-- Additional suppressions specific to clang-cl cross-compilation
if get_config("toolchain") == "clang-cl" then
add_cxxflags("-Wno-cast-function-type-mismatch", {force = true})
add_cxxflags("-Wno-parentheses-equality", {force = true})
add_cxxflags("-Wno-reorder-ctor", {force = true})
add_cxxflags("-Wno-unused-but-set-variable", {force = true})
add_cxxflags("-Wno-unused-parameter", {force = true})
add_cflags("-Wno-unknown-warning-option", {force = true})
add_cflags("-Wno-unused-command-line-argument", {force = true})
end
if is_os("linux") then
add_defines("_GNU_SOURCE")
end
-- Turn use of undefined cpp macros into errors
if is_os("windows") then
add_cxxflags("/we4668")
else
add_cxxflags("-Wundef")
end
function add_define_by_config(define, config_name)
local value = has_config(config_name) and 1 or 0
add_defines(define.."="..value)
end
option("zensentry")
set_default(true)
set_showmenu(true)
set_description("Enables Sentry support (incompatible with ASAN)")
option_end()
add_defines("ZEN_USE_SENTRY=" .. ((has_config("zensentry") and not use_asan) and "1" or "0"))
option("zenmimalloc")
set_default(true)
set_showmenu(true)
set_description("Use MiMalloc for faster memory management (incompatible with ASAN)")
option_end()
add_defines("ZEN_USE_MIMALLOC=" .. ((has_config("zenmimalloc") and not use_asan) and "1" or "0"))
option("zenrpmalloc")
set_default(true)
set_showmenu(true)
set_description("Use rpmalloc for faster memory management")
option_end()
add_define_by_config("ZEN_USE_RPMALLOC", "zenrpmalloc")
if is_os("windows") then
option("httpsys")
set_default(true)
set_showmenu(true)
set_description("Enable http.sys server")
option_end()
add_define_by_config("ZEN_WITH_HTTPSYS", "httpsys")
else
add_defines("ZEN_WITH_HTTPSYS=0")
end
-- Note that this controls the defaults here but currently
-- releases explicitly disable compute services since they are
-- WIP and should not be enabled widely yet.
local compute_default = true
option("zencompute")
set_default(compute_default)
set_showmenu(true)
set_description("Enable compute services endpoint")
option_end()
add_define_by_config("ZEN_WITH_COMPUTE_SERVICES", "zencompute")
option("zenhorde")
set_default(compute_default)
set_showmenu(true)
set_description("Enable Horde worker provisioning")
option_end()
add_define_by_config("ZEN_WITH_HORDE", "zenhorde")
option("zennomad")
set_default(compute_default)
set_showmenu(true)
set_description("Enable Nomad worker provisioning")
option_end()
add_define_by_config("ZEN_WITH_NOMAD", "zennomad")
if is_os("windows") then
add_defines("UE_MEMORY_TRACE_AVAILABLE=1")
option("zenmemtrack")
set_default(true)
set_showmenu(true)
set_description("Enable UE's Memory Trace support")
option_end()
add_define_by_config("ZEN_WITH_MEMTRACK", "zenmemtrack")
else
add_defines("ZEN_WITH_MEMTRACK=0")
end
option("zentrace")
set_default(true)
set_showmenu(true)
set_description("Enable UE's Trace support")
option_end()
add_define_by_config("ZEN_WITH_TRACE", "zentrace")
option("zencpr")
set_default(true)
set_showmenu(true)
set_description("Enable CPR HTTP client backend")
option_end()
add_define_by_config("ZEN_WITH_CPR", "zencpr")
set_warnings("allextra", "error")
set_languages("cxx20")
-- always generate debug information
set_symbols("debug")
includes("toolchains")
-- Auto-select the UE clang toolchain on Linux when the SDK is available
if is_plat("linux") and not get_config("toolchain") then
local ue_sdk = os.getenv("UE_TOOLCHAIN_DIR")
if not ue_sdk or ue_sdk == "" then
local home = os.getenv("HOME")
if home then
local default_path = path.join(home, ".ue-toolchain")
if os.isdir(default_path) then
ue_sdk = default_path
end
end
end
if ue_sdk and ue_sdk ~= "" and os.isdir(ue_sdk) then
set_toolchains("ue-clang")
end
end
includes("thirdparty")
includes("src/transports")
includes("src/zenbase")
includes("src/zencore", "src/zencore-test")
includes("src/zenhttp", "src/zenhttp-test")
includes("src/zennet", "src/zennet-test")
includes("src/zenremotestore", "src/zenremotestore-test")
includes("src/zencompute", "src/zencompute-test")
if has_config("zenhorde") then
includes("src/zenhorde")
end
if has_config("zennomad") then
includes("src/zennomad")
end
includes("src/zens3-testbed")
includes("src/zenstore", "src/zenstore-test")
includes("src/zentelemetry", "src/zentelemetry-test")
includes("src/zenutil", "src/zenutil-test")
if is_plat("windows") then
includes("src/zenvfs")
end
includes("src/zenserver", "src/zenserver-test")
includes("src/zen")
includes("src/zentest-appstub")
--------------------------------------------------------------------------
task("bundle")
set_menu {
usage = "xmake bundle",
description = "Create Zip bundle from binaries",
options = {
{nil, "withtrace", "k", nil, "Compiles with trace support"},
{nil, "codesignidentity", "v", nil, "Code signing identity"},
}
}
on_run(function ()
import("scripts.bundle")
bundle()
end)
task("docker")
set_menu {
usage = "xmake docker [--push] [--no-wine] [--win-binary PATH] [--tag TAG] [--registry REGISTRY]",
description = "Build Docker image for zenserver compute workers",
options = {
{nil, "push", "k", nil, "Push the image after building"},
{nil, "no-wine", "k", nil, "Build without Wine (smaller image, Linux-only workers)"},
{nil, "win-binary", "v", nil, "Path to Windows zenserver.exe to include in image"},
{nil, "tag", "v", nil, "Override image tag (default: version from VERSION.txt)"},
{nil, "registry", "v", nil, "Registry prefix (e.g. ghcr.io/epicgames)"},
}
}
on_run(function ()
import("scripts.docker")
docker()
end)
task("kill")
set_menu {
usage = "xmake kill",
description = "Terminate any running zenserver instances",
}
on_run(function ()
local ok = try { function() os.execv("xmake", {"run", "zen", "down", "--all"}) end }
if ok then return end
if is_host("windows") then
ok = try { function() os.runv("taskkill", {"/F", "/IM", "zenserver.exe"}) end }
if ok then print("zenserver terminated") end
else
ok = try { function() os.runv("pkill", {"-f", "zenserver"}) end }
if ok then print("zenserver terminated") end
end
end)
task("precommit")
set_menu {
usage = "xmake precommit",
description = "Run required pre-commit steps (clang-format, etc)",
}
on_run(function ()
print(os.exec("python -m pre_commit run --all-files"))
end)
task("sln")
set_menu {
usage = "xmake sln [vsXXXX|xcode|vscode] [--open]",
description = "Generate IDE project files (default: vs2022 on Windows, xcode on macOS, vscode on Linux)",
options = {
{nil, "arguments", "vs", nil, "IDE kind (vsXXXX, xcode, vscode) and flags (--open)"},
}
}
on_run(function ()
import("core.base.option")
local open = false
local kind = nil
for _, v in ipairs(option.get("arguments") or {}) do
if v == "--open" or v == "-o" then
open = true
elseif not v:startswith("-") then
kind = v
end
end
if not kind then
if os.is_host("windows") then
kind = "vs2022"
elseif os.is_host("macosx") then
kind = "xcode"
else
kind = "vscode"
end
end
if kind == "vscode" then
os.exec("xmake project --yes --kind=compile_commands --lsp=clangd")
printf("generated compile_commands.json\n")
elseif kind == "xcode" then
os.exec("xmake project --yes --kind=xcode -m release,debug -a x64,arm64")
if open then
local xcproj = path.join(os.projectdir(), path.filename(os.projectdir()) .. ".xcodeproj")
printf("opening %s\n", xcproj)
os.exec("open \"%s\"", xcproj)
end
elseif kind:startswith("vs") then
local vs_ver = kind:sub(3)
if vs_ver == "" then
raise("'vs' requires a version, e.g. vs2022")
end
local xmake_kind = "vsxmake" .. vs_ver
os.exec("xmake project --yes --kind=" .. xmake_kind .. " -m release,debug -a x64")
if open then
local sln = path.join(os.projectdir(), xmake_kind, path.filename(os.projectdir()) .. ".sln")
printf("opening %s\n", sln)
try { function() os.execv("explorer", {sln}) end, catch { function() end } }
end
else
raise("Unknown kind '%s'. Expected vsXXXX (e.g. vs2022), xcode, or vscode.", kind)
end
end)
task("test")
set_menu {
usage = "xmake test --run=[name|all] [-- extra-args...] (use --list to see available tests)",
description = "Run Zen tests",
options = {
{'r', "run", "kv", "all", "Run test(s) - comma-separated"},
{'l', "list", "k", nil, "List available test names"},
{'j', "junit", "k", nil, "Enable junit report output"},
{'n', "noskip", "k", nil, "Run skipped tests (passes --no-skip to doctest)"},
{nil, "repeat", "kv", nil, "Repeat tests N times (stops on first failure)"},
{'V', "output", "k", nil, "Route child process output to stdout (zenserver-test)"},
{nil, "asan", "k", nil, "Enable AddressSanitizer (disables mimalloc and sentry)"},
{nil, "tsan", "k", nil, "Enable ThreadSanitizer (Linux/Mac only)"},
{nil, "msan", "k", nil, "Enable MemorySanitizer (Linux only, requires all deps instrumented)"},
{nil, "arguments", "vs", nil, "Extra arguments passed to test runners (after --)"}
}
}
on_run(function()
import("scripts.test")
test()
end)
|