426 lines
12 KiB
Lua
426 lines
12 KiB
Lua
set_xmakever("3.0.0")
|
|
set_project("clice")
|
|
|
|
set_allowedplats("windows", "linux", "macosx")
|
|
set_allowedmodes("debug", "release", "releasedbg")
|
|
|
|
option("enable_test", { default = true })
|
|
option("dev", { default = true })
|
|
option("release", { default = false })
|
|
option("llvm", { default = nil, description = "Specify pre-compiled llvm binary directory." })
|
|
option("ci", { default = false })
|
|
|
|
if has_config("dev") then
|
|
set_policy("build.ccache", true)
|
|
set_policy("package.install_only", true) -- Don't fetch system package
|
|
if is_plat("windows") then
|
|
set_runtimes("MD")
|
|
if is_mode("debug") then
|
|
print(
|
|
"clice does not support build in debug mode with pre-compiled llvm binary on windows.\n"
|
|
.. "See https://github.com/clice-io/clice/issues/42 for more information."
|
|
)
|
|
os.raise()
|
|
end
|
|
elseif is_mode("debug") and is_plat("linux", "macosx") then
|
|
set_policy("build.sanitizer.address", true)
|
|
end
|
|
end
|
|
|
|
local libuv_require = "libuv"
|
|
|
|
if has_config("release") then
|
|
set_policy("build.optimization.lto", true)
|
|
set_policy("package.cmake_generator.ninja", true)
|
|
set_policy("package.install_only", true) -- Don't fetch system package
|
|
|
|
if is_plat("windows") then
|
|
set_runtimes("MD")
|
|
-- workaround cmake
|
|
libuv_require = "libuv[toolchains=clang-cl]"
|
|
end
|
|
|
|
includes("@builtin/xpack")
|
|
end
|
|
|
|
if is_plat("macosx", "linux") then
|
|
local cxflags
|
|
if is_plat("macosx") then
|
|
-- https://conda-forge.org/docs/maintainer/knowledge_base/#newer-c-features-with-old-sdk
|
|
cxflags = "-D_LIBCPP_DISABLE_AVAILABILITY=1"
|
|
end
|
|
local ldflags = "-fuse-ld=lld"
|
|
local shflags = "-fuse-ld=lld"
|
|
|
|
add_cxflags(cxflags)
|
|
add_ldflags(ldflags)
|
|
add_shflags(shflags)
|
|
|
|
add_requireconfs("**|cmake", {
|
|
configs = {
|
|
cxflags = cxflags,
|
|
ldflags = ldflags,
|
|
shflags = shflags,
|
|
},
|
|
})
|
|
end
|
|
|
|
add_defines("TOML_EXCEPTIONS=0")
|
|
add_requires(
|
|
"spdlog",
|
|
{ system = false, version = "1.15.3", configs = { header_only = false, std_format = true, noexcept = true } }
|
|
)
|
|
add_requires(libuv_require, "toml++", "croaring", "flatbuffers", "cpptrace")
|
|
add_requires("clice-llvm", { alias = "llvm" })
|
|
|
|
add_rules("mode.release", "mode.debug", "mode.releasedbg")
|
|
set_languages("c++23")
|
|
add_rules("clice_build_config")
|
|
|
|
target("clice-core", function()
|
|
set_kind("$(kind)")
|
|
add_files("src/**.cpp|Driver/*.cpp", "include/Index/schema.fbs")
|
|
add_includedirs("include", { public = true })
|
|
|
|
add_rules("flatbuffers.schema.gen", "clice_clang_tidy_config")
|
|
add_packages("flatbuffers")
|
|
add_packages("libuv", "spdlog", "toml++", "croaring", { public = true })
|
|
|
|
if is_mode("debug") then
|
|
add_packages("llvm", {
|
|
public = true,
|
|
links = {
|
|
"LLVMSupport",
|
|
"LLVMFrontendOpenMP",
|
|
"LLVMOption",
|
|
"LLVMTargetParser",
|
|
"clangAST",
|
|
"clangASTMatchers",
|
|
"clangBasic",
|
|
"clangDriver",
|
|
"clangFormat",
|
|
"clangFrontend",
|
|
"clangLex",
|
|
"clangSema",
|
|
"clangSerialization",
|
|
"clangTidy",
|
|
"clangTidyUtils",
|
|
-- ALL_CLANG_TIDY_CHECKS
|
|
"clangTidyAndroidModule",
|
|
"clangTidyAbseilModule",
|
|
"clangTidyAlteraModule",
|
|
"clangTidyBoostModule",
|
|
"clangTidyBugproneModule",
|
|
"clangTidyCERTModule",
|
|
"clangTidyConcurrencyModule",
|
|
"clangTidyCppCoreGuidelinesModule",
|
|
"clangTidyDarwinModule",
|
|
"clangTidyFuchsiaModule",
|
|
"clangTidyGoogleModule",
|
|
"clangTidyHICPPModule",
|
|
"clangTidyLinuxKernelModule",
|
|
"clangTidyLLVMModule",
|
|
"clangTidyLLVMLibcModule",
|
|
"clangTidyMiscModule",
|
|
"clangTidyModernizeModule",
|
|
"clangTidyObjCModule",
|
|
"clangTidyOpenMPModule",
|
|
"clangTidyPerformanceModule",
|
|
"clangTidyPortabilityModule",
|
|
"clangTidyReadabilityModule",
|
|
"clangTidyZirconModule",
|
|
"clangTooling",
|
|
"clangToolingCore",
|
|
"clangToolingInclusions",
|
|
"clangToolingInclusionsStdlib",
|
|
"clangToolingSyntax",
|
|
},
|
|
})
|
|
on_config(function(target)
|
|
local llvm_dynlib_dir = path.join(target:pkg("llvm"):installdir(), "lib")
|
|
target:add("rpathdirs", llvm_dynlib_dir)
|
|
end)
|
|
elseif is_mode("release", "releasedbg") then
|
|
add_packages("llvm", { public = true })
|
|
end
|
|
end)
|
|
|
|
target("clice", function()
|
|
set_kind("binary")
|
|
add_files("src/clice.cc")
|
|
add_deps("clice-core")
|
|
|
|
-- workaround
|
|
-- @see https://github.com/xmake-io/xmake/issues/7029
|
|
if is_plat("macosx") then
|
|
set_toolset("dsymutil", "dsymutil")
|
|
end
|
|
|
|
on_config(function(target)
|
|
local llvm_dir = target:dep("clice-core"):pkg("llvm"):installdir()
|
|
target:add("installfiles", path.join(llvm_dir, "lib/clang/(**)"), { prefixdir = "lib/clang" })
|
|
end)
|
|
|
|
after_build(function(target)
|
|
local res_dir = path.join(target:targetdir(), "../lib/clang")
|
|
if not os.exists(res_dir) then
|
|
local llvm_dir = target:dep("clice-core"):pkg("llvm"):installdir()
|
|
os.vcp(path.join(llvm_dir, "lib/clang"), res_dir)
|
|
end
|
|
end)
|
|
end)
|
|
|
|
target("unit_tests", function()
|
|
set_default(false)
|
|
set_kind("binary")
|
|
add_files("tests/unit/unit_tests.cc", "tests/unit/**.cpp")
|
|
add_includedirs(".", { public = true })
|
|
|
|
add_packages("cpptrace")
|
|
add_deps("clice-core")
|
|
|
|
add_tests("default")
|
|
|
|
after_load(function(target)
|
|
target:set("runargs", "--test-dir=" .. path.absolute("tests/data"))
|
|
end)
|
|
end)
|
|
|
|
target("integration_tests", function()
|
|
set_default(false)
|
|
set_kind("phony")
|
|
|
|
add_deps("clice")
|
|
add_packages("llvm")
|
|
|
|
add_tests("default")
|
|
|
|
on_test(function(target, opt)
|
|
local argv = {
|
|
"--log-cli-level=INFO",
|
|
"-s",
|
|
"tests/integration",
|
|
"--executable=" .. target:dep("clice"):targetfile(),
|
|
}
|
|
local run_opt = { curdir = os.projectdir() }
|
|
os.vrunv("pytest", argv, run_opt)
|
|
|
|
return true
|
|
end)
|
|
end)
|
|
|
|
rule("clice_clang_tidy_config", function()
|
|
on_load(function(target)
|
|
import("core.project.depend")
|
|
|
|
local autogendir = path.join(target:autogendir(), "rules/clice_clang_tidy_config")
|
|
os.mkdir(autogendir)
|
|
target:add("includedirs", autogendir, { public = true })
|
|
|
|
local src = path.join(os.projectdir(), "config/clang-tidy-config.h")
|
|
depend.on_changed(function()
|
|
os.vcp(src, path.join(autogendir, "clang-tidy-config.h"))
|
|
end, {
|
|
files = src,
|
|
changed = target:is_rebuilt(),
|
|
})
|
|
end)
|
|
|
|
before_build(function(target)
|
|
local dest = path.join(target:autogendir(), "rules/clice_clang_tidy_config/clang-tidy-config.h")
|
|
if not os.exists(dest) then
|
|
local src = path.join(os.projectdir(), "config/clang-tidy-config.h")
|
|
os.vcp(src, dest)
|
|
end
|
|
end)
|
|
end)
|
|
|
|
rule("clice_build_config", function()
|
|
on_load(function(target)
|
|
target:set("exceptions", "no-cxx")
|
|
target:add("cxflags", "-fno-rtti", "-Wno-undefined-inline", { tools = { "clang", "clangxx", "gcc", "gxx" } })
|
|
target:add("cxflags", "/GR-", "/Zc:preprocessor", { tools = { "clang_cl", "cl" } })
|
|
|
|
if target:is_plat("windows") and not target:toolchain("msvc") then
|
|
target:set("toolset", "ar", "llvm-ar")
|
|
if target:toolchain("clang-cl") then
|
|
target:set("toolset", "ld", "lld-link")
|
|
target:set("toolset", "sh", "lld-link")
|
|
else
|
|
target:add("ldflags", "-fuse-ld=lld-link")
|
|
end
|
|
elseif target:is_plat("linux") then
|
|
target:add("ldflags", "-fuse-ld=lld", "-static-libstdc++", "-Wl,--gc-sections")
|
|
elseif target:is_plat("macosx") then
|
|
target:add("ldflags", "-fuse-ld=lld", "-Wl,-dead_strip,-object_path_lto,clice.lto.o", { force = true })
|
|
-- dsymutil so slow, disable it in dev ci
|
|
if not has_config("release") and is_mode("releasedbg") and has_config("ci") then
|
|
target:rule_enable("utils.symbols.extract", false)
|
|
end
|
|
end
|
|
|
|
if has_config("release") then
|
|
-- pixi clang failed to add lto flags because it need `-fuse-ld=lld`
|
|
target:add("ldflags", "-flto=thin", { force = true })
|
|
end
|
|
|
|
if has_config("ci") then
|
|
target:add("cxxflags", "-DCLICE_CI_ENVIRONMENT=1")
|
|
end
|
|
|
|
if has_config("enable_test") then
|
|
target:add("cxxflags", "-DCLICE_ENABLE_TEST=1")
|
|
end
|
|
end)
|
|
end)
|
|
|
|
rule("flatbuffers.schema.gen", function()
|
|
set_extensions(".fbs")
|
|
|
|
on_prepare_files(function(target, jobgraph, sourcebatch, opt)
|
|
import("lib.detect.find_tool")
|
|
import("core.project.depend")
|
|
import("utils.progress")
|
|
|
|
assert(
|
|
target:pkg("flatbuffers"),
|
|
'Please configure add_packages("flatbuffers") for target(' .. target:name() .. ")"
|
|
)
|
|
local envs = target:pkgenvs()
|
|
local flatc = assert(find_tool("flatc", { envs = envs }), "flatc not found!")
|
|
|
|
local group_name = path.join(target:fullname(), "generate/fbs")
|
|
local autogendir = path.join(target:autogendir(), "rules/flatbuffers")
|
|
jobgraph:group(group_name, function()
|
|
for _, sourcefile in ipairs(sourcebatch.sourcefiles) do
|
|
local job = path.join(group_name, sourcefile)
|
|
local generate_dir = path.normalize(path.join(autogendir, path.directory(sourcefile)))
|
|
target:add("includedirs", generate_dir, { public = true })
|
|
os.mkdir(generate_dir)
|
|
jobgraph:add(job, function(index, total, opt)
|
|
local argv = {
|
|
"--cpp",
|
|
"-o",
|
|
generate_dir,
|
|
sourcefile,
|
|
}
|
|
|
|
depend.on_changed(function()
|
|
progress.show(flatc.progress or 0, "${color.build.object}generating.fbs %s", sourcefile)
|
|
os.vrunv(flatc.program, argv)
|
|
end, {
|
|
files = sourcefile,
|
|
dependfile = target:dependfile(sourcefile),
|
|
changed = target:is_rebuilt(),
|
|
})
|
|
end)
|
|
end
|
|
end)
|
|
end, { jobgraph = true })
|
|
end)
|
|
|
|
package("clice-llvm", function()
|
|
if has_config("llvm") then
|
|
set_sourcedir(get_config("llvm"))
|
|
else
|
|
on_source(function(package)
|
|
import("core.base.json")
|
|
|
|
local build_type = {
|
|
Debug = "debug",
|
|
Release = "release",
|
|
RelWithDebInfo = "releasedbg",
|
|
}
|
|
local info = json.loadfile("./config/llvm-manifest.json")
|
|
for _, info in ipairs(info) do
|
|
local current_plat = get_config("plat")
|
|
local current_mode = get_config("mode")
|
|
local info_plat = info.platform:lower()
|
|
local info_mode = build_type[info.build_type]
|
|
local mode_match = (info_mode == current_mode)
|
|
or (info_mode == "releasedbg" and current_mode == "release")
|
|
if info_plat == current_plat and mode_match and (info.lto == has_config("release")) then
|
|
package:add(
|
|
"urls",
|
|
format(
|
|
"https://github.com/clice-io/clice-llvm/releases/download/%s/%s",
|
|
info.version,
|
|
info.filename
|
|
)
|
|
)
|
|
package:add("versions", info.version, info.sha256)
|
|
end
|
|
end
|
|
end)
|
|
end
|
|
|
|
if is_plat("linux", "macosx") then
|
|
if is_mode("debug") then
|
|
add_configs(
|
|
"shared",
|
|
{ description = "Build shared library.", default = true, type = "boolean", readonly = true }
|
|
)
|
|
end
|
|
end
|
|
|
|
if is_plat("windows", "mingw") then
|
|
add_syslinks("version", "ntdll")
|
|
end
|
|
|
|
on_install(function(package)
|
|
if not package:config("shared") then
|
|
package:add("defines", "CLANG_BUILD_STATIC")
|
|
end
|
|
|
|
os.trycp("bin", package:installdir())
|
|
os.vcp("lib", package:installdir())
|
|
os.vcp("include", package:installdir())
|
|
end)
|
|
end)
|
|
|
|
if has_config("release") then
|
|
xpack("clice")
|
|
if is_plat("windows") then
|
|
set_formats("zip")
|
|
set_extension(".zip")
|
|
else
|
|
set_formats("targz")
|
|
set_extension(".tar.gz")
|
|
end
|
|
|
|
set_prefixdir("clice")
|
|
|
|
add_targets("clice")
|
|
-- add_installfiles(path.join(os.projectdir(), "docs/clice.toml"))
|
|
|
|
on_package(function(package)
|
|
import("utils.archive")
|
|
|
|
local build_dir = path.absolute(package:install_rootdir())
|
|
os.tryrm(build_dir)
|
|
os.mkdir(build_dir)
|
|
|
|
local function clice_archive(output_file)
|
|
local old_dir = os.cd(build_dir)
|
|
local archive_files = os.files("**")
|
|
os.cd(old_dir)
|
|
os.tryrm(output_file)
|
|
cprint("packing %s .. ", output_file)
|
|
archive.archive(path.absolute(output_file), archive_files, { curdir = build_dir, compress = "best" })
|
|
end
|
|
|
|
local target = package:target("clice")
|
|
os.vcp(target:symbolfile(), build_dir)
|
|
clice_archive(path.join(package:outputdir(), "clice-symbol" .. package:extension()))
|
|
|
|
os.tryrm(build_dir)
|
|
os.mkdir(path.join(build_dir, "bin"))
|
|
os.vcp(target:targetfile(), path.join(build_dir, "bin"))
|
|
os.vcp(path.join(os.projectdir(), "docs/clice.toml"), build_dir)
|
|
|
|
local llvm_dir = target:dep("clice-core"):pkg("llvm"):installdir()
|
|
os.vcp(path.join(llvm_dir, "lib/clang"), path.join(build_dir, "lib/clang"))
|
|
clice_archive(path.join(package:outputdir(), "clice" .. package:extension()))
|
|
end)
|
|
end
|