-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathxmake.lua
More file actions
596 lines (488 loc) · 19.7 KB
/
xmake.lua
File metadata and controls
596 lines (488 loc) · 19.7 KB
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
set_xmakever("2.9.8")
set_project("uwvm")
-- Version
set_version("2.0.2")
add_defines("UWVM_VERSION_X=2")
add_defines("UWVM_VERSION_Y=0")
add_defines("UWVM_VERSION_Z=2")
add_defines("UWVM_VERSION_S=0")
set_allowedplats("windows", "mingw", "cygwin", "linux", "djgpp", "unix", "bsd", "freebsd", "dragonflybsd", "netbsd",
"openbsd", "macosx", "iphoneos", "watchos", "wasm-wasi", "wasm-wasip1", "wasm-wasip2", "wasm-wasip3",
"wasm-wasi-threads", "wasm-wasip1-threads", "wasm-wasip2-threads", "wasm-wasip3-threads", "wasm-emscripten",
"serenity", "sun", "cross", "none")
includes("xmake/impl.lua")
includes("xmake/platform/impl.lua")
add_moduledirs("xmake")
-- Currently, there are no plugins.
-- add_plugindirs("xmake/plugins")
set_defaultmode("release")
set_allowedmodes(support_rules_table)
function def_build()
if is_mode("debug") then
add_rules("debug")
elseif is_mode("release") then
add_rules("release")
elseif is_mode("minsizerel") then
add_rules("minsizerel")
elseif is_mode("releasedbg") then
add_rules("releasedbg")
end
set_languages("c23", "cxx26")
set_encodings("utf-8")
set_warnings("all", "extra", "pedantic", "error")
local enable_cxx_module = get_config("use-cxx-module")
if enable_cxx_module then
add_defines("UWVM_MODULE")
set_policy("build.c++.modules", true)
-- set_policy("build.c++.modules.std", true)
end
local use_stdlib = get_config("stdlib")
if use_stdlib ~= "default" and use_stdlib then
local flags = "-stdlib=" .. use_stdlib
add_cxflags(flags)
add_ldflags(flags)
end
local disable_cpp_exceptions = get_config("fno-exceptions")
if disable_cpp_exceptions then
set_exceptions("no-cxx")
end
local enable_debug_timer = get_config("debug-timer")
if enable_debug_timer then
add_defines("UWVM_TIMER")
end
local enable_multithread_allocator_mem = get_config("use-multithread-allocator-memory")
if enable_multithread_allocator_mem then
add_defines("UWVM_USE_MULTITHREAD_ALLOCATOR")
end
local disable_local_imported_wasip1 = get_config("disable-local-imported-wasip1")
if disable_local_imported_wasip1 then
add_defines("UWVM_DISABLE_LOCAL_IMPORTED_WASIP1")
end
local enable_local_imported_wasip1_wasm64 = get_config("enable-local-imported-wasip1-wasm64")
if enable_local_imported_wasip1_wasm64 then
add_defines("UWVM_ENABLE_LOCAL_IMPORTED_WASIP1_WASM64")
end
local enable_local_imported_wasip1_socket = get_config("enable-local-imported-wasip1-socket")
if not enable_local_imported_wasip1_socket or enable_local_imported_wasip1_socket == "none" then
-- do nothing
elseif enable_local_imported_wasip1_socket == "wasip1" then
add_defines("UWVM_ENABLE_WASIP1_SOCKET")
elseif enable_local_imported_wasip1_socket == "wasix" then
add_defines("UWVM_ENABLE_WASIX_VER_WASIP1_SOCKET")
end
local enable_int = get_config("enable-int")
if not enable_int or enable_int == "none" then
add_defines("UWVM_DISABLE_INT")
elseif enable_int == "default" then
add_defines("UWVM_USE_DEFAULT_INT")
elseif enable_int == "uwvm-int" then
add_defines("UWVM_USE_UWVM_INT")
end
local enable_jit = get_config("enable-jit")
if not enable_jit or enable_jit == "none" then
add_defines("UWVM_DISABLE_JIT")
elseif enable_jit == "default" then
add_defines("UWVM_USE_DEFAULT_JIT")
add_options("llvm-jit-env")
elseif enable_jit == "llvm" then
add_defines("UWVM_USE_LLVM_JIT")
add_options("llvm-jit-env")
end
local enable_debug_int = get_config("enable-debug-int")
if enable_debug_int then
add_defines("UWVM_ENABLE_DEBUG_INT")
end
local heavy_combine_ops_mode = get_config("enable-uwvm-int-combine-ops")
if heavy_combine_ops_mode ~= "none" then
-- Soft/light combine is enabled by default unless explicitly set to "none".
add_defines("UWVM_ENABLE_UWVM_INT_COMBINE_OPS")
if heavy_combine_ops_mode == "heavy" or heavy_combine_ops_mode == "extra" then
add_defines("UWVM_ENABLE_UWVM_INT_HEAVY_COMBINE_OPS")
if heavy_combine_ops_mode == "extra" then
add_defines("UWVM_ENABLE_UWVM_INT_EXTRA_HEAVY_COMBINE_OPS")
end
end
end
local delay_local_mode = get_config("enable-uwvm-int-delay-local")
if delay_local_mode == "soft" or delay_local_mode == "heavy" then
add_defines("UWVM_ENABLE_UWVM_INT_DELAY_LOCAL_SOFT")
if delay_local_mode == "heavy" then
add_defines("UWVM_ENABLE_UWVM_INT_DELAY_LOCAL_HEAVY")
end
end
local use_thread_local = get_config("use-thread-local")
if use_thread_local then
add_defines("UWVM_USE_THREAD_LOCAL")
end
local detailed_debug_check = get_config("detailed-debug-check")
if is_mode("debug") and detailed_debug_check then
add_defines("UWVM_ENABLE_DETAILED_DEBUG_CHECK")
end
if is_plat("windows") then
windows_target()
elseif is_plat("mingw") then
mingw_target()
elseif is_plat("linux") then
linux_target()
elseif is_plat("macosx", "iphoneos", "watchos") then
darwin_target()
elseif is_plat("djgpp") then
djgpp_target()
elseif is_plat("unix", "bsd", "freebsd", "dragonflybsd", "netbsd", "openbsd") then
bsd_target()
elseif is_plat("wasm-wasi", "wasm-wasip1", "wasm-wasip2", "wasm-wasip3", "wasm-wasi-threads", "wasm-wasip1-threads", "wasm-wasip2-threads", "wasm-wasip3-threads") then
wasm_wasi_target()
elseif is_plat("wasm-emscripten") then
wasm_emscripten_target()
elseif is_plat("cygwin") then
cygwin_target()
elseif is_plat("none") then
none_target()
end
local use_llvm_compiler = get_config("use-llvm-compiler")
if use_llvm_compiler then
local llvm_target = get_config("llvm-target")
if llvm_target ~= "detect" and llvm_target then
local llvm_target_cvt = "--target=" .. llvm_target
add_cxflags(llvm_target_cvt, { force = true })
add_ldflags(llvm_target_cvt, { force = true })
end
-- Since neither LLVM nor Wextra supports this parameter by default, this addition prevents compilation.
add_cxflags("-Wimplicit-fallthrough", { force = true })
else
if not is_plat("windows") then
add_cxflags("-Wno-maybe-musttail-local-addr")
end
end
before_build(
function(target)
try
{
function()
local function git_available()
local result = os.iorun("git --version")
return result and not result:find("fatal:") and not result:find("not found")
end
local function is_git_repo()
if not git_available() then return false end
local result = os.iorun("git rev-parse --is-inside-work-tree")
return result and result:trim() == "true"
end
if not git_available() or not is_git_repo() then
return
end
-- General Git commands execute functions and return results or nil
local function git_command(cmd)
local result = os.iorun(cmd)
if result and not result:find("fatal:") then
return result:trim()
end
return nil
end
-- Get Commit ID
local commit_id = git_command("git rev-parse HEAD") or "unknown"
-- Get the current branch name (may be empty, such as the separation HEAD status)
local current_branch = git_command("git branch --show-current")
-- Dynamically resolve the associated remote name
local remote_name = nil
if current_branch then
-- Get the traced remote name through git config
remote_name = git_command("git config branch." .. current_branch .. ".remote")
end
-- If the remote name is not found, try to resolve it through HEAD upstream
local upstream_branch = git_command("git rev-parse --abbrev-ref --symbolic-full-name HEAD") or "unknown"
if not remote_name then
local upstream_branch_tmp = git_command("git rev-parse --abbrev-ref --symbolic-full-name @{u}")
if upstream_branch_tmp then
-- Resolve the remote name of the upstream branch (format: remote_name/branch_name)
remote_name = upstream_branch_tmp:match("^(.-)/")
end
end
-- If there is still no remote name, go back to the first remote or default value
local remote_url = "unknown"
if remote_name then
remote_url = git_command("git remote get-url " .. remote_name) or "unknown"
else
-- Get all remote lists, the first one
local remotes = git_command("git remote")
if remotes then
local first_remote = remotes:match("[^\r\n]+")
if first_remote then
remote_url = git_command("git remote get-url " .. first_remote) or "unknown"
end
end
end
-- Get submission timestamp (UTC)
local timestamp_str = git_command("git log -1 --format=%ct HEAD")
local timestamp = tonumber(timestamp_str) or 0
-- Convert timestamp to date string (UTC time zone)
local commit_date = "unknown"
if timestamp > 0 then
commit_date = os.date("!%Y-%m-%d", timestamp) -- Attention '! 'means forcing UTC
end
local is_dirty = false
local status_output = git_command("git status --porcelain")
if status_output and status_output ~= "" then
is_dirty = true -- There are uncommitted modifications or untracked files
end
target:add("defines", "UWVM_GIT_COMMIT_ID=u8\"" .. commit_id .. "\"")
target:add("defines", "UWVM_GIT_REMOTE_URL=u8\"" .. remote_url .. "\"")
target:add("defines", "UWVM_GIT_COMMIT_DATA=u8\"" .. commit_date .. "\"")
target:add("defines", "UWVM_GIT_UPSTREAM_BRANCH=u8\"" .. upstream_branch .. "\"")
if is_dirty then
target:add("defines", "UWVM_GIT_HAS_UNCOMMITTED_MODIFICATIONS")
end
end,
catch
{
function()
return nil
end
}
}
end
)
end
target("uwvm")
set_kind("binary")
def_build()
-- uwvm uses precise floating-point model to ensure determinism.
set_fpmodels("precise")
local is_debug_mode = is_mode("debug") -- public all modules in debug mode
local enable_cxx_module = get_config("use-cxx-module")
-- third-parties/fast_io
add_includedirs("third-parties/fast_io/include")
if enable_cxx_module then
add_files("third-parties/fast_io/share/fast_io/fast_io.cppm", { public = is_debug_mode })
add_files("third-parties/fast_io/share/fast_io/fast_io_crypto.cppm", { public = is_debug_mode })
end
-- third-parties/bizwen
add_includedirs("third-parties/bizwen/include")
-- third-parties/boost
add_includedirs("third-parties/boost_unordered/include")
-- uwvm
add_defines("UWVM=2")
-- src
add_includedirs("src/")
add_headerfiles("src/**.h")
if enable_cxx_module then
-- uwvm predefine
add_files("src/uwvm2/uwvm_predefine/**.cppm", { public = is_debug_mode })
-- utils
add_files("src/uwvm2/utils/**.cppm", { public = is_debug_mode })
-- object
add_files("src/uwvm2/object/**.cppm", { public = is_debug_mode })
-- imported
add_files("src/uwvm2/imported/**.cppm", { public = is_debug_mode })
-- wasm parser
add_files("src/uwvm2/parser/**.cppm", { public = is_debug_mode })
-- validation
add_files("src/uwvm2/validation/**.cppm", { public = is_debug_mode })
-- uwvm
add_files("src/uwvm2/uwvm/**.cppm", { public = is_debug_mode })
end
if enable_cxx_module then
-- uwvm main
add_files("src/uwvm2/uwvm/main.module.cpp")
add_files("src/uwvm2/uwvm/host_api.module.cpp")
else
-- uwvm main
add_files("src/uwvm2/uwvm/main.default.cpp")
add_files("src/uwvm2/uwvm/host_api.default.cpp")
end
-- uwvm_runtime (uwvm_runtime interpreter runtime unit)
if get_config("enable-int") == "uwvm-int" or get_config("enable-int") == "default" then
add_deps("uwvm_runtime")
end
target_end()
-- uwvm_runtime: build the interpreter/runtime execution unit separately so it can use its own FP flags.
if get_config("enable-int") == "uwvm-int" or get_config("enable-int") == "default" then
target("uwvm_runtime")
set_kind("object")
def_build()
-- Interpreter/runtime execution unit: disable observable floating-point side effects
-- (errno, traps, dynamic rounding, and FMA contraction) to preserve WebAssembly FP semantics.
add_cxflags("-fno-math-errno", "-fno-trapping-math", "-fno-rounding-math", "-ffp-contract=off")
-- third-parties/fast_io
add_includedirs("third-parties/fast_io/include")
if enable_cxx_module then
add_files("third-parties/fast_io/share/fast_io/fast_io.cppm", { public = is_debug_mode })
add_files("third-parties/fast_io/share/fast_io/fast_io_crypto.cppm", { public = is_debug_mode })
end
-- third-parties/bizwen
add_includedirs("third-parties/bizwen/include")
-- third-parties/boost
add_includedirs("third-parties/boost_unordered/include")
-- src
add_includedirs("src/")
add_defines("UWVM=2")
if enable_cxx_module then
-- uwvm predefine
add_files("src/uwvm2/uwvm_predefine/**.cppm", { public = is_debug_mode })
-- utils
add_files("src/uwvm2/utils/**.cppm", { public = is_debug_mode })
-- object
add_files("src/uwvm2/object/**.cppm", { public = is_debug_mode })
-- imported
add_files("src/uwvm2/imported/**.cppm", { public = is_debug_mode })
-- wasm parser
add_files("src/uwvm2/parser/**.cppm", { public = is_debug_mode })
-- validation
add_files("src/uwvm2/validation/**.cppm", { public = is_debug_mode })
-- uwvm
add_files("src/uwvm2/uwvm/**.cppm", { public = is_debug_mode })
-- runtime
add_files("src/uwvm2/runtime/**.cppm", { public = is_debug_mode })
end
if enable_cxx_module then
-- uwvm int main
add_files("src/uwvm2/runtime/lib/uwvm_runtime.module.cpp")
else
-- uwvm int main
add_files("src/uwvm2/runtime/lib/uwvm_runtime.default.cpp")
end
target_end()
end
-- test unit
for _, file in ipairs(os.files("test/**.cc")) do
local is_0013_uwvm_int = (string.find(file, "test/0013.uwvm_int/", 1, true) ~= nil) or (string.find(file, "test\\0013.uwvm_int\\", 1, true) ~= nil)
if not (is_0013_uwvm_int and not get_config("enable-test-uwvm-int")) then
local name = path.basename(file)
target(name)
local group = path.directory(file):gsub("\\\\", "/")
set_group(group)
set_kind("binary")
def_build()
-- uwvm uses precise floating-point model to ensure determinism.
set_fpmodels("precise")
set_default(false)
local enable_cxx_module = get_config("use-cxx-module")
-- third-parties/fast_io
add_includedirs("third-parties/fast_io/include")
if enable_cxx_module then
add_files("third-parties/fast_io/share/fast_io/fast_io.cppm", { public = is_debug_mode })
add_files("third-parties/fast_io/share/fast_io/fast_io_crypto.cppm", { public = is_debug_mode })
end
-- third-parties/bizwen
add_includedirs("third-parties/bizwen/include")
-- third-parties/boost
add_includedirs("third-parties/boost_unordered/include")
-- uwvm
add_defines("UWVM=2")
-- uwvm test
add_defines("UWVM_TEST=2")
-- src
add_includedirs("src/")
if enable_cxx_module then
-- uwvm predefine
add_files("src/uwvm2/uwvm_predefine/**.cppm", { public = is_debug_mode })
-- utils
add_files("src/uwvm2/utils/**.cppm", { public = is_debug_mode })
-- object
add_files("src/uwvm2/object/**.cppm", { public = is_debug_mode })
-- imported
add_files("src/uwvm2/imported/**.cppm", { public = is_debug_mode })
-- wasm parser
add_files("src/uwvm2/parser/**.cppm", { public = is_debug_mode })
-- validation
add_files("src/uwvm2/validation/**.cppm", { public = is_debug_mode })
-- uwvm
add_files("src/uwvm2/uwvm/**.cppm", { public = is_debug_mode })
end
set_warnings("all", "extra", "error")
local is_libfuzzer = (string.find(file, "test/0009.libfuzzer/", 1, true) ~= nil) or
(string.find(file, "test\\0009.libfuzzer\\", 1, true) ~= nil)
local test_libfuzzer = get_config("test-libfuzzer")
if is_libfuzzer then
if get_config("use-llvm-compiler") and test_libfuzzer then
local need_wabt = (string.find(file, "wabt", 1, true) ~= nil)
if need_wabt then
before_build(function(target)
local function has_wabt(wabt_root)
local wabt_include = path.join(wabt_root, "include")
local wabt_build = path.join(wabt_root, "build")
local wabt_config = path.join(wabt_build, "include/wabt/config.h")
local has_lib = os.isfile(path.join(wabt_build, "libwabt.a")) or
os.isfile(path.join(wabt_build, "libwabt.so")) or
os.isfile(path.join(wabt_build, "libwabt.dylib")) or
os.isfile(path.join(wabt_build, "wabt.lib"))
return os.isdir(wabt_include) and os.isfile(wabt_config) and has_lib
end
if not (has_wabt("build/test/third-parties/wabt") or has_wabt("wabt")) then
local wabt_root = "build/test/third-parties/wabt"
-- Check if directory exists AND contains CMakeLists.txt to ensure it's not just an empty placeholder
if not os.isdir(wabt_root) or not os.isfile(path.join(wabt_root, "CMakeLists.txt")) then
print("wabt source not found or incomplete. Attempting to pull...")
if not os.isdir(wabt_root) then
os.mkdir(wabt_root)
end
-- Use git clone/pull instead of submodule
if not os.isdir(path.join(wabt_root, ".git")) then
os.vrunv("git", {"clone", "https://github.com/WebAssembly/wabt.git", wabt_root, "--recursive"})
else
os.vrunv("git", {"-C", wabt_root, "pull"})
os.vrunv("git", {"-C", wabt_root, "submodule", "update", "--init", "--recursive"})
end
end
if not os.isdir(wabt_root) then
wabt_root = "wabt"
end
if os.isdir(wabt_root) then
print("wabt is required for " .. target:name() .. " but no built artifacts were found. Building wabt...")
local build_dir = path.join(wabt_root, "build")
-- Build WABT in Release so libwabt is compiled with NDEBUG and won't abort on debug assertions
-- when fed malformed inputs (important for fuzzing/differential validation).
os.vrunv("cmake", {"-S", wabt_root, "-B", build_dir, "-DCMAKE_BUILD_TYPE=Release", "-DBUILD_TESTS=OFF", "-DBUILD_TOOLS=OFF", "-DBUILD_LIBWASM=OFF"})
os.vrunv("cmake", {"--build", build_dir, "--target", "wabt", "--config", "Release"})
else
raise("wabt is required for " .. target:name() .. " but neither source nor built artifacts were found.")
end
end
end)
on_load(function(target)
local function try_add_wabt(wabt_root, force)
local wabt_include = path.join(wabt_root, "include")
local wabt_build = path.join(wabt_root, "build")
local wabt_config = path.join(wabt_build, "include/wabt/config.h")
local has_lib = os.isfile(path.join(wabt_build, "libwabt.a")) or
os.isfile(path.join(wabt_build, "libwabt.so")) or
os.isfile(path.join(wabt_build, "libwabt.dylib")) or
os.isfile(path.join(wabt_build, "wabt.lib"))
if force or (os.isdir(wabt_include) and os.isfile(wabt_config) and has_lib) then
target:add("includedirs", wabt_include, path.join(wabt_build, "include"))
target:add("linkdirs", wabt_build)
target:add("links", "wabt")
-- libwabt may depend on OpenSSL's libcrypto (e.g. SHA256)
if not is_plat("windows") then
target:add("syslinks", "crypto")
end
return true
end
return false
end
-- Try to find existing wabt, if not found, force configure build/third-parties/wabt
-- assuming before_build will handle the build.
if not try_add_wabt("build/test/third-parties/wabt", false) and not try_add_wabt("wabt", false) then
try_add_wabt("build/test/third-parties/wabt", true)
end
end)
end
add_cxflags("-fsanitize=fuzzer", { force = true })
add_ldflags("-fsanitize=fuzzer", { force = true })
-- change the env variables in ci to change the default values
local rss = os.getenv("FUZZ_RSS") or "512"
local maxtime = os.getenv("FUZZ_MAX_TIME") or "10"
local maxlen = os.getenv("FUZZ_MAX_LEN") or "1024"
add_tests("fuzz",
{ group = "libfuzzer", runargs = { "-rss_limit_mb=" .. rss, "-max_total_time=" .. maxtime, "-max_len=" .. maxlen } }) -- xmake test -g libfuzzer
add_files(file)
elseif not get_config("use-llvm-compiler") and test_libfuzzer then
raise("Libfuzzer is not supported on this platform, please use llvm toolchain.")
end
else
add_tests("unit", { group = "default" }) -- xmake test -g default
add_files(file)
end
target_end()
end
end