Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve clang-cl toolchain support #4866

Merged
merged 10 commits into from
Mar 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions xmake/core/package/package.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1165,6 +1165,9 @@ function _instance:toolchain(name)
end
self:_memcache():set("toolchains_map", toolchains_map)
end
if not toolchains_map[name] then
toolchains_map[name] = toolchain.load(name, {plat = self:plat(), arch = self:arch()})
end
return toolchains_map[name]
end

Expand Down
20 changes: 20 additions & 0 deletions xmake/modules/package/manager/system/find_package.lua
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,17 @@ function _get_package_items()
return items
end

-- check package toolchains
function _check_package_toolchains(package)
local has_standalone
for _, toolchain_inst in pairs(package:toolchains()) do
if toolchain_inst:check() and toolchain_inst:is_standalone() then
has_standalone = true
end
end
return has_standalone
end

-- find package from system and compiler
-- @see https://github.com/xmake-io/xmake/issues/4596
--
Expand All @@ -55,6 +66,15 @@ function main(name, opt)
end
snippet_configs.links = snippet_configs.links or name

-- We need to check package toolchain first
-- https://github.com/xmake-io/xmake/issues/4596#issuecomment-2014528801
--
-- But if it depends on some toolchain packages,
-- then they can't be detected early in the fetch and we have to disable system.find_package
if opt.package and not _check_package_toolchains(opt.package) then
return
end

local snippet_opt = {
verbose = opt.verbose,
target = opt.package,
Expand Down
2 changes: 1 addition & 1 deletion xmake/modules/package/tools/autoconf.lua
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ end

-- get msvc
function _get_msvc(package)
local msvc = package:toolchain("msvc") or toolchain.load("msvc", {plat = package:plat(), arch = package:arch()})
local msvc = package:toolchain("msvc")
assert(msvc:check(), "vs not found!") -- we need to check vs envs if it has been not checked yet
return msvc
end
Expand Down
52 changes: 36 additions & 16 deletions xmake/modules/package/tools/cmake.lua
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ end

-- get msvc
function _get_msvc(package)
local msvc = package:toolchain("msvc") or toolchain.load("msvc", {plat = package:plat(), arch = package:arch()})
local msvc = package:toolchain("msvc")
assert(msvc:check(), "vs not found!") -- we need to check vs envs if it has been not checked yet
return msvc
end
Expand Down Expand Up @@ -371,6 +371,15 @@ function _get_configs_for_windows(package, configs, opt)
table.insert(configs, "-DCMAKE_GENERATOR_TOOLSET=" .. vs_toolset)
end
end

-- use clang-cl
if package:has_tool("cc", "clang_cl") then
table.insert(configs, "-DCMAKE_C_COMPILER=" .. _translate_bin_path(package:build_getenv("cc")))
end
if package:has_tool("cxx", "clang_cl") then
table.insert(configs, "-DCMAKE_CXX_COMPILER=" .. _translate_bin_path(package:build_getenv("cxx")))
end

-- we maybe need patch `cmake_policy(SET CMP0091 NEW)` to enable this argument for some packages
-- @see https://cmake.org/cmake/help/latest/policy/CMP0091.html#policy:CMP0091
-- https://github.com/xmake-io/xmake-repo/pull/303
Expand Down Expand Up @@ -964,23 +973,40 @@ function _install_for_cmakebuild(package, configs, opt)
os.vrunv(cmake.program, {"--install", os.curdir()})
end

-- get cmake generator
function _get_cmake_generator(package, opt)
opt = opt or {}
local cmake_generator = opt.cmake_generator
if not cmake_generator then
if project.policy("package.cmake_generator.ninja") then
cmake_generator = "Ninja"
end
if not cmake_generator then
if package:has_tool("cc", "clang_cl") or package:has_tool("cxx", "clang_cl") then
cmake_generator = "Ninja"
end
end
local cmake_generator_env = os.getenv("CMAKE_GENERATOR")
if not cmake_generator and cmake_generator_env then
cmake_generator = cmake_generator_env
end
if cmake_generator then
opt.cmake_generator = cmake_generator
end
end
return cmake_generator
end

-- build package
function build(package, configs, opt)

-- init options
opt = opt or {}
local cmake_generator = _get_cmake_generator(package, opt)

-- enter build directory
local buildir = opt.buildir or package:buildir()
os.mkdir(path.join(buildir, "install"))
local oldir = os.cd(buildir)

-- exists $CMAKE_GENERATOR? use it
local cmake_generator_env = os.getenv("CMAKE_GENERATOR")
if not opt.cmake_generator and cmake_generator_env then
opt.cmake_generator = cmake_generator_env
end

-- pass configurations
local argv = {}
for name, value in pairs(_get_configs(package, configs, opt)) do
Expand All @@ -1000,7 +1026,6 @@ function build(package, configs, opt)
os.vrunv(cmake.program, argv, {envs = opt.envs or buildenvs(package, opt)})

-- do build
local cmake_generator = opt.cmake_generator
if opt.cmake_build then
_build_for_cmakebuild(package, configs, opt)
elseif cmake_generator then
Expand All @@ -1025,12 +1050,8 @@ end

-- install package
function install(package, configs, opt)

-- init options
opt = opt or {}
if (not opt.cmake_generator) and project.policy("package.cmake_generator.ninja") then
opt.cmake_generator = "Ninja"
end
local cmake_generator = _get_cmake_generator(package, opt)

-- enter build directory
local buildir = opt.buildir or package:buildir()
Expand All @@ -1056,7 +1077,6 @@ function install(package, configs, opt)
os.vrunv(cmake.program, argv, {envs = opt.envs or buildenvs(package, opt)})

-- do build and install
local cmake_generator = opt.cmake_generator
if opt.cmake_build then
_install_for_cmakebuild(package, configs, opt)
elseif cmake_generator then
Expand Down
2 changes: 1 addition & 1 deletion xmake/modules/package/tools/gn.lua
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ end

-- get msvc
function _get_msvc(package)
local msvc = toolchain.load("msvc", {plat = package:plat(), arch = package:arch()})
local msvc = package:toolchain("msvc")
assert(msvc:check(), "vs not found!") -- we need to check vs envs if it has been not checked yet
return msvc
end
Expand Down
2 changes: 1 addition & 1 deletion xmake/modules/package/tools/meson.lua
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,7 @@ end

-- get msvc
function _get_msvc(package)
local msvc = toolchain.load("msvc", {plat = package:plat(), arch = package:arch()})
local msvc = package:toolchain("msvc")
assert(msvc:check(), "vs not found!") -- we need to check vs envs if it has been not checked yet
return msvc
end
Expand Down
2 changes: 1 addition & 1 deletion xmake/modules/package/tools/msbuild.lua
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ end

-- get msvc
function _get_msvc(package)
local msvc = toolchain.load("msvc", {plat = package:plat(), arch = package:arch()})
local msvc = package:toolchain("msvc")
assert(msvc:check(), "vs not found!") -- we need to check vs envs if it has been not checked yet
return msvc
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,6 @@ function _fix_paths_for_precompiled_package(package)
end
end


-- check package toolchains
function _check_package_toolchains(package)
for _, toolchain_inst in pairs(package:toolchains()) do
Expand Down
2 changes: 1 addition & 1 deletion xmake/modules/private/utils/toolchain.lua
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ function is_compatible_with_host(name)
return true
end
elseif is_host("windows") then
if name == "msvc" or name == "llvm" then
if name == "msvc" or name == "llvm" or name == "clang-cl" then
return true
end
end
Expand Down