-- 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") -------------------------------------------------------------------------- -- 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") 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 -- -- When using sanitizers, it may be necessary to change some configuration -- options. In particular, you may want to use `--zensentry=no` to disable -- Sentry support as it may not be compatible with some sanitizers. Also, -- it may be necessary to disable mimalloc by using `--zenmimalloc=no`. -- AddressSanitizer is supported on Windows (MSVC 2019+), Linux, and MacOS local use_asan = false -- Automatically disables Sentry when set to true set_policy("build.sanitizer.address", use_asan) -- ThreadSanitizer, MemorySanitizer, LeakSanitizer, and UndefinedBehaviorSanitizer -- are supported on Linux and MacOS only. --set_policy("build.sanitizer.thread", true) --set_policy("build.sanitizer.memory", true) --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 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 -- If we're using the UE cross-compile toolchain, we need to ensure we link statically -- against the toolchain libc++ and libc++abi, as the system ones can differ in ABI -- leading to nasty crashes if is_plat("linux") and os.getenv("UE_TOOLCHAIN_DIR") then add_ldflags("-static-libstdc++") add_ldflags("$(projectdir)/thirdparty/ue-libcxx/lib64/libc++.a") add_ldflags("$(projectdir)/thirdparty/ue-libcxx/lib64/libc++abi.a") set_toolset("objcopy", "$(env UE_TOOLCHAIN_DIR)/bin/llvm-objcopy") 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 -- It's currently also temporarily disabled on Windows to investigate -- build issues due to git apply not applying the necessary patches correctly -- in CI for some reason. -- Also, disabled LTO on Mac to reduce time spent building openssl tests if not is_plat("linux", "windows", "macosx") 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 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 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:preprocessor") -- Enable preprocessor conformance mode add_cxxflags("/Zc:u8EscapeEncoding") -- Enable UTF-8 encoding for u8 string literals add_cxxflags("/Zc:inline") -- Enforce inline semantics -- add_ldflags("/MAP") end if is_os("linux") or is_os("macosx") then add_cxxflags("-Wno-implicit-fallthrough") add_cxxflags("-Wno-missing-field-initializers") add_cxxflags("-Wno-strict-aliasing") add_cxxflags("-Wno-switch") add_cxxflags("-Wno-unused-lambda-capture") add_cxxflags("-Wno-unused-private-field") add_cxxflags("-Wno-unused-value") add_cxxflags("-Wno-unused-variable") add_cxxflags("-Wno-vla-cxx-extension") end if is_os("macosx") then -- silence warnings about -Wno-vla-cxx-extension since to my knowledge we can't -- detect the clang version used in Xcode and only recent versions contain this flag add_cxxflags("-Wno-unknown-warning-option") 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") option_end() add_define_by_config("ZEN_USE_SENTRY", "zensentry") option("zenmimalloc") set_default(not use_asan) set_showmenu(true) set_description("Use MiMalloc for faster memory management") option_end() add_define_by_config("ZEN_USE_MIMALLOC", "zenmimalloc") 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 option("zencompute") set_default(false) set_showmenu(true) set_description("Enable compute services endpoint") option_end() add_define_by_config("ZEN_WITH_COMPUTE_SERVICES", "zencompute") 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") set_warnings("allextra", "error") set_languages("cxx20") -- always generate debug information set_symbols("debug") 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") includes("src/zenstore", "src/zenstore-test") includes("src/zentelemetry", "src/zentelemetry-test") includes("src/zenutil", "src/zenutil-test") includes("src/zenvfs") 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("updatefrontend") set_menu { usage = "xmake updatefrontend", description = "Create Zip of the frontend/html folder for bundling with zenserver executable", } on_run(function() import("scripts.updatefrontend") updatefrontend() end) task("precommit") set_menu { usage = "xmake precommit", description = "Run required pre-commit steps (clang-format, etc)", } on_run(function () print(os.exec("pre-commit run --all-files")) end) task("sln") set_menu { usage = "xmake sln", description = "Generate IDE project files", } if is_os("windows") then on_run(function () print(os.exec("xmake project --yes --kind=vsxmake2022 -m release,debug -a x64")) end) elseif is_os("macosx") then on_run(function () print(os.exec("xmake project --yes --kind=xcode -m release,debug -a x64,arm64")) end) end task("test") set_menu { usage = "xmake test --run=[core|store|server|integration|all]", description = "Run Zen tests", options = { {'r', "run", "kv", "all", "Run test(s)", " - all", " - core ", " - remotestore", " - store", " - server", " - integration"}, {'j', "junit", "k", nil, "Enable junit report output"} } } on_run(function() import("core.base.option") import("core.project.config") import("core.project.project") config.load() local testname = option.get("run") local available_tests = { core = "zencore-test", http = "zenhttp-test", util = "zenutil-test", store = "zenstore-test", remotestore = "zenremotestore-test", server = "zenserver", integration = "zenserver-test" } local arch if is_host("windows") then arch = "x64" elseif is_arch("arm64") then arch = "arm64" else arch = "x86_64" end print(os.exec("xmake config -c -m debug -a "..arch)) print(os.exec("xmake")) local tests = {} local found_match = false for name, test in pairs(available_tests) do if name == testname or testname == "all" then tests[name] = test found_match = true end end if not found_match then raise("no tests match specification: '%s'", testname) end local use_junit_reporting = option.get("junit") local junit_report_files = {} local junit_report_dir if use_junit_reporting then junit_report_dir = path.join(os.projectdir(), config.get("buildir"), "reports") os.mkdir(junit_report_dir) end try { function() for name, test in pairs(tests) do printf("=== %s ===\n", test) local cmd = string.format("xmake run %s", test) if name == "server" then cmd = string.format("xmake run %s test", test) end cmd = string.format("%s --duration=true", cmd) if use_junit_reporting then local target = project.target(test) local junit_report_file = path.join(junit_report_dir, string.format("junit-%s-%s-%s.xml", config.plat(), arch, test)) junit_report_files[test] = junit_report_file cmd = string.format("%s --reporters=junit --out=%s", cmd, junit_report_file) end os.exec(cmd) end end, finally { function (ok, errors) for test, junit_report_file in pairs(junit_report_files) do printf("=== report - %s ===\n", test) local data = io.readfile(junit_report_file) print(data) end if (errors) then raise(errors) end end } } end)