-- Copyright Epic Games, Inc. All Rights Reserved. -------------------------------------------------------------------------------- local function _exec(cmd, ...) local args = {} for _, arg in pairs({...}) do if arg then table.insert(args, arg) end end print("--", cmd, table.unpack(args)) local ret = os.execv(cmd, args) print() return ret end -------------------------------------------------------------------------------- local function _build(arch, debug, config_args) variant = debug and "debug" or "release" local ret = _exec( "xmake", "config", "--yes", "--clean", "--mode="..variant, "--arch="..arch, config_args) if ret > 0 then raise("Failed to configure xmake") end ret = _exec("xmake", "clean", "--yes", "zenserver") if ret > 0 then raise("Clean zenserver failed") end ret = _exec("xmake", "clean", "--yes", "zen") if ret > 0 then raise("Clean zen failed") end ret = _exec("xmake", "build", "--yes", "zenserver") if ret > 0 then raise("Build zenserver failed") end ret = _exec("xmake", "build", "--yes", "zen") if ret > 0 then raise("Build zen failed") end end -------------------------------------------------------------------------------- local function _zip(store_only, zip_path, ...) -- Here's the rules; if len(...) is 1 and it is a dir then create a zip with -- archive paths like this; -- -- glob(foo/bar/**) -> foo/bar/abc, foo/bar/dir/123 -> zip(abc, dir/123) -- -- Otherwise assume ... is file paths and add without leading directories; -- -- foo/abc, bar/123 -> zip(abc, 123) zip_path = path.absolute(zip_path) os.tryrm(zip_path) local inputs = {...} local source_dir = nil if #inputs == 1 and os.isdir(inputs[1]) then source_dir = inputs[1] end import("detect.tools.find_7z") local cmd = find_7z() if cmd then input_paths = {} if source_dir then -- Suffixing a directory path with a "/." will have 7z set the path -- for archived files relative to that directory. input_paths = { path.join(source_dir, ".") } else for _, input_path in pairs(inputs) do -- If there is a "/./" anywhere in file paths then 7z drops all -- directory information and just archives the file by name input_path = path.relative(input_path, ".") if input_path:sub(2,2) ~= ":" then input_path = "./"..input_path end table.insert(input_paths, input_path) end end compression_level = "-mx1" if store_only then compression_level = "-mx0" end local ret = _exec("7z", "a", compression_level, zip_path, table.unpack(input_paths)) if ret > 0 then raise("Received error from 7z") end return end print("7z not found") import("detect.tools.find_zip") cmd = find_zip() if cmd then local input_paths = inputs local cwd = os.curdir() if source_dir then os.cd(source_dir) input_paths = { "." } end compression_level = "-1" if store_only then compression_level = "-0" end local strip_leading_path = nil if not source_dir then strip_leading_path = "--junk-paths" end local ret = _exec("zip", "-r", compression_level, strip_leading_path, zip_path, table.unpack(input_paths)) if ret > 0 then raise("Received error from zip") end os.cd(cwd) return end print("zip not found") raise("Unable to find a suitable zip tool") end -------------------------------------------------------------------------------- local function _find_vcpkg_binary(triple, port, binary) import("detect.sdks.find_vcpkgdir") local root_dir = find_vcpkgdir() if root_dir == nil or root_dir == "" then raise("Unable to find vcpkg root directory") end bin_path = root_dir.."/installed/"..triple.."/tools/"..port.."/"..binary if not os.isfile(bin_path) then raise("Unable to locate vcpkg tool "..bin_path) end return bin_path end -------------------------------------------------------------------------------- local function _append_content_zip(bin_path) local zip_path = "build/frontend.zip" local content_dir = "zenserver/frontend/html/" _zip(true, zip_path, content_dir) zip_file = io.open(zip_path, "rb") local zip_data = zip_file:read("*all") zip_file:close() bin_file = io.open(bin_path, "ab") bin_file:write(zip_data) bin_file:close() end -------------------------------------------------------------------------------- local function main_windows() import("core.base.option") zip_path = "build/zenserver-win64.zip" config_args = nil if option.get("withtrace") then zip_path = "build/zenserver-trace-win64.zip" config_args = "--zentrace=yes" end _build("x64", false, config_args) _append_content_zip("build/windows/x64/release/zenserver.exe") _append_content_zip("build/windows/x64/release/zens.exe") local crashpad_handler_path = _find_vcpkg_binary( "x64-windows-static", "sentry-native", "crashpad_handler.exe") _zip(false, zip_path, "build/windows/x64/release/zenserver.exe", "build/windows/x64/release/zenserver.pdb", "build/windows/x64/release/zen.exe", "build/windows/x64/release/zen.pdb", crashpad_handler_path) end -------------------------------------------------------------------------------- local function main_mac() -- Build and universalify _build("x86_64", false, "--target_minver=10.15") _build("arm64", false, "--target_minver=10.15") os.mkdir("build/macosx/universal/release/") local ret = _exec( "lipo", "-create", "-output", "build/macosx/universal/release/zenserver", "build/macosx/x86_64/release/zenserver", "build/macosx/arm64/release/zenserver" ) if ret > 0 then raise("Failed creating universal zenserver binary") end _append_content_zip("build/macosx/universal/release/zenserver") ret = _exec( "lipo", "-create", "-output", "build/macosx/universal/release/zen", "build/macosx/x86_64/release/zen", "build/macosx/arm64/release/zen" ) if ret > 0 then raise("Failed creating universal zen binary") end _append_content_zip("build/macosx/universal/release/zen") -- At the time of writing vcpkg does not support sentry-native on arm64. Once -- it does we can create a univeral binary for this. For now just bundle x64 local crashpad_handler_path = _find_vcpkg_binary( "x64-osx", "sentry-native", "crashpad_handler") -- Zip _zip(false, "build/zenserver-macos.zip", "build/macosx/universal/release/zenserver", "build/macosx/universal/release/zen", crashpad_handler_path) end -------------------------------------------------------------------------------- local function main_linux() _build("x86_64") -- Crashpad handler does not exist for Linux local crashpad_handler_path = nil --[[ local crashpad_handler_path = _find_vcpkg_binary( "x64-linux", "sentry-native", "crashpad_handler") --]] _append_content_zip("build/linux/x86_64/release/zenserver") _append_content_zip("build/linux/x86_64/release/zen") _exec("scripts/bundle_linux.sh") _zip(false, "build/zenserver-linux.zip", "build/appimage/zenserver", "build/linux/x86_64/release/zen", crashpad_handler_path) end -------------------------------------------------------------------------------- function main() if is_host("windows") then return main_windows() end if is_host("mac") then return main_mac() end if is_host("linux") then return main_linux() end raise("'xmake bundle' not currently supported on this platform") end