Skip to content

Commit

Permalink
Refactor clang module support
Browse files Browse the repository at this point in the history
  • Loading branch information
Arthapz committed Oct 25, 2023
1 parent b83134f commit 4c81372
Show file tree
Hide file tree
Showing 9 changed files with 1,280 additions and 1,012 deletions.
14 changes: 7 additions & 7 deletions tests/projects/c++/modules/test_headerunits.lua
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ function main(t)
elseif is_host("linux") then
local gcc = find_tool("gcc", {version = true})
if gcc and gcc.version and semver.compare(gcc.version, "11.0") >= 0 then
-- gcc trtbd dependency detection doesn't support header units atm
-- gcc dependency detection doesn't support header units atm
os.exec("xmake f --policies=build.c++.gcc.fallbackscanner -c --yes")
_build()
end
Expand All @@ -32,12 +32,12 @@ function main(t)
-- clang-scan-deps dependency detection doesn't support header units atm
os.exec("xmake f --toolchain=clang --policies=build.c++.clang.fallbackscanner -c")
_build()
-- elseif semver.compare(clang.version, "15.0") >= 0 then
-- there is currently a bug on llvm git that prevent to build STL header units https://github.com/llvm/llvm-project/issues/58540
-- os.exec("xmake clean -a")
-- clang-scan-deps dependency detection doesn't support header units atm
-- os.exec("xmake f --toolchain=clang --policies=build.c++.modules.fallbackscanner.clang --cxxflags=\"-stdlib=libc++\" -c")
-- _build()
end
if semver.compare(clang.version, "17.0") >= 0 then
os.exec("xmake clean -a")
-- clang-scan-deps dependency detection doesn't support header units atm
os.exec("xmake f --toolchain=clang --policies=build.c++.clang.fallbackscanner --cxxflags=\"-stdlib=libc++\" -c")
_build()
end
end
end
Expand Down
9 changes: 5 additions & 4 deletions tests/projects/c++/modules/test_stdmodules.lua
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,16 @@ function main(t)
-- os.exec("xmake f -c")
-- _build()
-- end
local clang = find_tool("clang", {version = true})
-- local clang = find_tool("clang", {version = true})
if clang and clang.version and semver.compare(clang.version, "14.0") >= 0 then
-- clang don't support libstdc++ std modules atm
-- os.exec("xmake clean -a")
-- os.exec("xmake f --toolchain=clang -c")
-- _build()
os.exec("xmake clean -a")
os.exec("xmake f --toolchain=clang --cxxflags=\"-stdlib=libc++\" -c")
_build()
-- clang don't support libc++ std modules atm
-- os.exec("xmake clean -a")
-- os.exec("xmake f --toolchain=clang --cxxflags=\"-stdlib=libc++\" -c")
-- _build()
end
end
end
145 changes: 145 additions & 0 deletions xmake/rules/c++/modules/modules_support/builder.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
--!A cross-platform build utility based on Lua
--
-- Licensed under the Apache License, Version 2.0 (the "License");
-- you may not use this file except in compliance with the License.
-- You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
--
-- Copyright (C) 2015-present, TBOOX Open Source Group.
--
-- @author Arthapz, ruki
-- @file common.lua
--

-- imports
import("private.async.buildjobs")
import("compiler_support")
import("dependency_scanner")

-- build batchjobs for modules
function build_batchjobs_for_modules(modules, batchjobs, rootjob)
return buildjobs(modules, batchjobs, rootjob)
end

-- build modules for batchjobs
function build_modules_for_batchjobs(target, batchjobs, sourcebatch, modules, opt)
local objectfiles = dependency_scanner.sort_modules_by_dependencies(sourcebatch.objectfiles, modules)
_builder(target).build_modules_for_batchjobs(target, batchjobs, objectfiles, modules, opt)
end

-- build modules for batchcmds
function build_modules_for_batchcmds(target, batchcmds, sourcebatch, modules, opt)
local objectfiles = dependency_scanner.sort_modules_by_dependencies(sourcebatch.objectfiles, modules)
_builder(target).build_modules_for_batchcmds(target, batchcmds, objectfiles, modules, opt)
end

-- generate headerunits for batchjobs
function generate_headerunits_for_batchjobs(target, batchjobs, sourcebatch, modules, opt)
local user_headerunits, stl_headerunits = dependency_scanner.get_headerunits(target, sourcebatch, modules)
if not user_headerunits and not stl_headerunits then
return
end
-- we need new group(headerunits)
-- e.g. group(build_modules) -> group(headerunits)
opt.rootjob = batchjobs:group_leave() or opt.rootjob
batchjobs:group_enter(target:name() .. "/generate_headerunits", {rootjob = opt.rootjob})

-- build stl header units first as other headerunits may need them
if stl_headerunits then
_builder(target).generate_stl_headerunits_for_batchjobs(target, batchjobs, stl_headerunits, opt)
end
if user_headerunits then
_builder(target).generate_user_headerunits_for_batchjobs(target, batchjobs, user_headerunits, opt)
end
end

-- generate headerunits for batchcmds
function generate_headerunits_for_batchcmds(target, batchcmds, sourcebatch, modules, opt)
local user_headerunits, stl_headerunits = dependency_scanner.get_headerunits(target, sourcebatch, modules)
-- build stl header units first as other headerunits may need them
if stl_headerunits then
_builder(target).generate_stl_headerunits_for_batchcmds(target, batchcmds, stl_headerunits, opt)
end
if user_headerunits then
_builder(target).generate_user_headerunits_for_batchcmds(target, batchcmds, user_headerunits, opt)
end
end

-- append headerunits objectfiles to link
function append_dependency_objectfiles(target)
local cachekey = target:name() .. "dependency_objectfiles"
local cache = compiler_support.localcache():get(cachekey)
if cache then
if target:is_binary() then
target:add("ldflags", cache, {force = true, expand = false})
elseif target:is_static() then
target:add("arflags", cache, {force = true, expand = false})
elseif target:is_shared() then
target:add("shflags", cache, {force = true, expand = false})
end
end
end

-- generate meta module informations for package / other buildsystems import
-- based on https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2473r1.pdf
--
-- e.g
-- {
-- "include_paths": ["foo/", "bar/"]
-- "definitions": ["FOO=BAR"]
-- "imports": ["std", "bar"]
-- "_VENDOR_extension": {}
-- }
function generate_meta_module_info(target, name, sourcefile, requires)
local module_metadata = {}

-- add include paths
module_metadata.include_paths = table.wrap(target:get("includedirs")) or {}
for _, deps in ipairs(target:orderdeps()) do
table.join2(module_metadata.include_paths, deps:get("includedirs") or {})
end

-- add definitions
module_metadata.definitions = table.wrap(target:get("defines")) or {}
for _, deps in ipairs(target:orderdeps()) do
table.join2(module_metadata.definitions, deps:get("defines") or {})
end

-- add imports
if requires then
for name, _ in pairs(requires) do
module_metadata.imports = module_metadata.imports or {}
table.append(module_metadata.imports, name)
end
end

local modulehash = compiler_support.get_modulehash(target, sourcefile)
module_metadata._VENDOR_extension = { xmake = { name = name, file = path.join(modulehash, path.filename(sourcefile)) }}
return module_metadata
end

function _builder(target)
local cachekey = tostring(target)
local builder = compiler_support.memcache():get2("builder", cachekey)
if builder == nil then
if target:has_tool("cxx", "clang", "clangxx") then
builder = import("clang.builder", {anonymous = true})
elseif target:has_tool("cxx", "gcc", "gxx") then
builder = import("gcc.builder", {anonymous = true})
elseif target:has_tool("cxx", "cl") then
builder = import("msvc.builder", {anonymous = true})
else
local _, toolname = target:tool("cxx")
raise("compiler(%s): does not support c++ module!", toolname)
end
compiler_support.memcache():set2("builder", cachekey, builder)
end
return builder
end
Loading

0 comments on commit 4c81372

Please sign in to comment.