diff options
| author | ruki <[email protected]> | 2023-05-01 21:05:51 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2023-05-01 21:05:51 +0800 |
| commit | 573319e4eff83876a558155f7c4f00886122011e (patch) | |
| tree | fe6f0f73459787d28fc9fd8d0f535b473454ec80 | |
| parent | 21fb04a180feb12bb57677fc1e1638d185fb10f1 (diff) | |
improve cmake trybuild #3697
| -rw-r--r-- | xmake/modules/private/action/trybuild/cmake.lua | 175 |
1 files changed, 144 insertions, 31 deletions
diff --git a/xmake/modules/private/action/trybuild/cmake.lua b/xmake/modules/private/action/trybuild/cmake.lua index 4b57562c8..6e103d0dc 100644 --- a/xmake/modules/private/action/trybuild/cmake.lua +++ b/xmake/modules/private/action/trybuild/cmake.lua @@ -48,6 +48,18 @@ function _get_buildenv(key) return value end +-- get msvc +function _get_msvc() + local msvc = toolchain.load("msvc") + assert(msvc:check(), "vs not found!") -- we need check vs envs if it has been not checked yet + return msvc +end + +-- get msvc run environments +function _get_msvc_runenvs() + return os.joinenvs(_get_msvc():runenvs()) +end + -- translate paths function _translate_paths(paths) if is_host("windows") then @@ -313,11 +325,68 @@ function _get_configs_for_host_toolchain(configs) end end --- get configs -function _get_configs(artifacts_dir) +-- get cmake generator for msvc +function _get_cmake_generator_for_msvc() + local vsvers = + { + ["2022"] = "17", + ["2019"] = "16", + ["2017"] = "15", + ["2015"] = "14", + ["2013"] = "12", + ["2012"] = "11", + ["2010"] = "10", + ["2008"] = "9" + } + local vs = _get_msvc():config("vs") or config.get("vs") + assert(vsvers[vs], "Unknown Visual Studio version: '" .. tostring(vs) .. "' set in project.") + return "Visual Studio " .. vsvers[vs] .. " " .. vs +end + +-- get configs for cmake generator +function _get_configs_for_generator(configs, opt) + opt = opt or {} + configs = configs or {} + local cmake_generator = opt.cmake_generator + if cmake_generator then + if cmake_generator:find("Visual Studio", 1, true) then + cmake_generator = _get_cmake_generator_for_msvc() + end + table.insert(configs, "-G") + table.insert(configs, cmake_generator) + elseif is_plat("mingw") and is_subhost("msys") then + table.insert(configs, "-G") + table.insert(configs, "MSYS Makefiles") + elseif is_plat("mingw") and is_subhost("windows") then + table.insert(configs, "-G") + table.insert(configs, "MinGW Makefiles") + elseif is_plat("windows") then + table.insert(configs, "-G") + table.insert(configs, _get_cmake_generator_for_msvc()) + elseif is_plat("wasm") and is_subhost("windows") then + table.insert(configs, "-G") + table.insert(configs, "MinGW Makefiles") + else + table.insert(configs, "-G") + table.insert(configs, "Unix Makefiles") + end +end + + +-- get configs for installation +function _get_configs_for_install(configs, opt) + -- @see https://cmake.org/cmake/help/v3.14/module/GNUInstallDirs.html + -- LIBDIR: object code libraries (lib or lib64 or lib/<multiarch-tuple> on Debian) + -- + table.insert(configs, "-DCMAKE_INSTALL_PREFIX=" .. opt.artifacts_dir) + table.insert(configs, "-DCMAKE_INSTALL_LIBDIR:PATH=lib") +end - -- add prefix - local configs = {"-DCMAKE_INSTALL_PREFIX=" .. artifacts_dir, "-DCMAKE_INSTALL_LIBDIR:PATH=lib"} +-- get configs +function _get_configs(opt) + local configs = {} + _get_configs_for_install(configs, opt) + _get_configs_for_generator(configs, opt) if is_plat("windows") then _get_configs_for_windows(configs) elseif is_plat("android") then @@ -350,8 +419,8 @@ function _get_configs(artifacts_dir) -- add extra user configs local tryconfigs = config.get("tryconfigs") if tryconfigs then - for _, opt in ipairs(os.argv(tryconfigs)) do - table.insert(configs, tostring(opt)) + for _, item in ipairs(os.argv(tryconfigs)) do + table.insert(configs, tostring(item)) end end @@ -360,6 +429,50 @@ function _get_configs(artifacts_dir) return configs end +-- build for msvc +function _build_for_msvc(opt) + local runenvs = _get_msvc_runenvs() + local msbuild = find_tool("msbuild", {envs = runenvs}) + local slnfile = assert(find_file("*.sln", os.curdir()), "*.sln file not found!") + os.vexecv(msbuild.program, {slnfile, "-nologo", "-t:Build", "-m", "-p:Configuration=" .. (is_mode("debug") and "Debug" or "Release"), "-p:Platform=" .. (is_arch("x64") and "x64" or "Win32")}, {envs = runenvs}) + local projfile = os.isfile("INSTALL.vcxproj") and "INSTALL.vcxproj" or "INSTALL.vcproj" + if os.isfile(projfile) then + os.vexecv(msbuild.program, {projfile, "/property:configuration=" .. (is_mode("debug") and "Debug" or "Release")}, {envs = runenvs}) + end +end + +-- build for make +function _build_for_make(opt) + local argv = {"-j" .. option.get("jobs")} + if option.get("verbose") then + table.insert(argv, "VERBOSE=1") + end + if is_host("bsd") then + os.vexecv("gmake", argv) + os.vexecv("gmake", {"install"}) + else + os.vexecv("make", argv) + os.vexecv("make", {"install"}) + end +end + +-- build for ninja +function _build_for_ninja(opt) + local njob = option.get("jobs") or tostring(os.default_njob()) + local ninja = assert(find_tool("ninja"), "ninja not found!") + local argv = {} + if option.get("diagnosis") then + table.insert(argv, "-v") + end + table.insert(argv, "-j") + table.insert(argv, njob) + local envs + if is_plat("windows") then + envs = _get_msvc_runenvs() + end + os.vrunv(ninja.program, argv, {envs = envs}) +end + -- detect build-system and configuration file function detect() return find_file("CMakeLists.txt", os.curdir()) @@ -373,7 +486,7 @@ function clean() if configfile then local oldir = os.cd(buildir) if is_plat("windows") then - local runenvs = toolchain.load("msvc"):runenvs() + local runenvs = _get_msvc_runenvs() local msbuild = find_tool("msbuild", {envs = runenvs}) os.vexecv(msbuild.program, {configfile, "-nologo", "-t:Clean", "-p:Configuration=" .. (is_mode("debug") and "Debug" or "Release"), "-p:Platform=" .. (is_arch("x64") and "x64" or "Win32")}, {envs = runenvs}) else @@ -387,43 +500,43 @@ end -- do build function build() + -- get cmake + local cmake = assert(find_tool("cmake"), "cmake not found!") + -- get artifacts directory - local artifacts_dir = _get_artifacts_dir() + local opt = {} + opt.artifacts_dir = _get_artifacts_dir() if not os.isdir(artifacts_dir) then os.mkdir(artifacts_dir) end os.cd(_get_buildir()) - -- generate makefile - local cmake = assert(find_tool("cmake"), "cmake not found!") - local configfile = find_file("[mM]akefile", os.curdir()) or (is_plat("windows") and find_file("*.sln", os.curdir())) - if not configfile or os.mtime(config.filepath()) > os.mtime(configfile) then - os.vexecv(cmake.program, _get_configs(artifacts_dir)) - end + -- exists $CMAKE_GENERATOR? use it + opt.cmake_generator = os.getenv("CMAKE_GENERATOR") + + -- do configure + os.vexecv(cmake.program, _get_configs(opt)) -- do build - if is_plat("windows") then - local runenvs = toolchain.load("msvc"):runenvs() - local msbuild = find_tool("msbuild", {envs = runenvs}) - local slnfile = assert(find_file("*.sln", os.curdir()), "*.sln file not found!") - os.vexecv(msbuild.program, {slnfile, "-nologo", "-t:Build", "-m", "-p:Configuration=" .. (is_mode("debug") and "Debug" or "Release"), "-p:Platform=" .. (is_arch("x64") and "x64" or "Win32")}, {envs = runenvs}) - local projfile = os.isfile("INSTALL.vcxproj") and "INSTALL.vcxproj" or "INSTALL.vcproj" - if os.isfile(projfile) then - os.vexecv(msbuild.program, {projfile, "/property:configuration=" .. (is_mode("debug") and "Debug" or "Release")}, {envs = runenvs}) + local cmake_generator = opt.cmake_generator + if cmake_generator then + if cmake_generator:find("Visual Studio", 1, true) then + _build_for_msvc(opt) + elseif cmake_generator == "Ninja" then + _build_for_ninja(opt) + elseif cmake_generator:find("Makefiles", 1, true) then + _build_for_make(opt) + else + raise("unknown cmake generator(%s)!", cmake_generator) end else - local argv = {"-j" .. option.get("jobs")} - if option.get("verbose") then - table.insert(argv, "VERBOSE=1") - end - if is_host("bsd") then - os.vexecv("gmake", argv) - os.vexecv("gmake", {"install"}) + if is_plat("windows") then + _build_for_msvc(opt) else - os.vexecv("make", argv) - os.vexecv("make", {"install"}) + _build_for_make(opt) end end + cprint("output to ${bright}%s", artifacts_dir) cprint("${color.success}build ok!") end |
