-
-
Notifications
You must be signed in to change notification settings - Fork 779
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
381 additions
and
307 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
409 changes: 106 additions & 303 deletions
409
...rules/c++/modules/modules_support/gcc.lua → ...+/modules/modules_support/gcc/builder.lua
Large diffs are not rendered by default.
Oops, something went wrong.
192 changes: 192 additions & 0 deletions
192
xmake/rules/c++/modules/modules_support/gcc/compiler_support.lua
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,192 @@ | ||
--!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 ruki, Arthapz | ||
-- @file gcc/compiler_support.lua | ||
-- | ||
|
||
-- imports | ||
import("core.base.semver") | ||
import("core.project.config") | ||
import("lib.detect.find_tool") | ||
import(".compiler_support", {inherit = true}) | ||
|
||
-- load module support for the current target | ||
function load(target) | ||
local modulesflag = get_modulesflag(target) | ||
local modulemapperflag = get_modulemapperflag(target) | ||
local mapper_file = path.join(config.buildir(), target:name(), "mapper.txt") | ||
target:add("cxxflags", {modulesflag, modulemapperflag .. path.translate(mapper_file)}, {force = true, expand = false}) | ||
-- fix cxxabi issue | ||
-- @see https://github.com/xmake-io/xmake/issues/2716#issuecomment-1225057760 | ||
-- https://github.com/xmake-io/xmake/issues/3855 | ||
if target:policy("build.c++.gcc.modules.cxx11abi") then | ||
target:add("cxxflags", "-D_GLIBCXX_USE_CXX11_ABI=1") | ||
else | ||
target:add("cxxflags", "-D_GLIBCXX_USE_CXX11_ABI=0") | ||
end | ||
end | ||
|
||
-- provide toolchain include directories for stl headerunit when p1689 is not supported | ||
function toolchain_includedirs(target) | ||
local includedirs = _g.includedirs | ||
if includedirs == nil then | ||
includedirs = {} | ||
local gcc, toolname = target:tool("cxx") | ||
assert(toolname == "gcc") | ||
_get_toolchain_includedirs_for_stlheaders(includedirs, gcc) | ||
local _, result = try {function () return os.iorunv(gcc, {"-E", "-Wp,-v", "-xc", os.nuldev()}) end} | ||
if result then | ||
for _, line in ipairs(result:split("\n", {plain = true})) do | ||
line = line:trim() | ||
if os.isdir(line) then | ||
table.insert(includedirs, path.normalize(line)) | ||
elseif line:startswith("End") then | ||
break | ||
end | ||
end | ||
end | ||
_g.includedirs = includedirs | ||
end | ||
return includedirs | ||
end | ||
|
||
-- not supported atm | ||
function get_stdmodules(target) | ||
local modules = {} | ||
return modules | ||
end | ||
|
||
function get_bmi_extension() | ||
return ".gcm" | ||
end | ||
|
||
function get_modulesflag(target) | ||
local modulesflag = _g.modulesflag | ||
if modulesflag == nil then | ||
local compinst = target:compiler("cxx") | ||
if compinst:has_flags("-fmodules-ts", "cxxflags", {flagskey = "gcc_modules_ts"}) then | ||
modulesflag = "-fmodules-ts" | ||
end | ||
assert(modulesflag, "compiler(gcc): does not support c++ module!") | ||
_g.modulesflag = modulesflag or false | ||
end | ||
return modulesflag or nil | ||
end | ||
|
||
function get_modulemapperflag(target) | ||
local modulemapperflag = _g.modulemapperflag | ||
if modulemapperflag == nil then | ||
local compinst = target:compiler("cxx") | ||
if compinst:has_flags("-fmodule-mapper=" .. os.tmpfile(), "cxxflags", {flagskey = "gcc_module_mapper"}) then | ||
modulemapperflag = "-fmodule-mapper=" | ||
end | ||
assert(modulemapperflag, "compiler(gcc): does not support c++ module!") | ||
_g.modulemapperflag = modulemapperflag or false | ||
end | ||
return modulemapperflag or nil | ||
end | ||
|
||
function get_depsflag(target) | ||
local depflag = _g.depflag | ||
if depflag == nil then | ||
local compinst = target:compiler("cxx") | ||
if compinst:has_flags("-fdeps-format=p1689r5", "cxxflags", {flagskey = "gcc_deps_format", | ||
on_check = function (ok, errors) | ||
if errors:find("-M") then | ||
ok = true | ||
end | ||
return ok, errors | ||
end}) then | ||
depflag = "-fdeps-format=p1689r5" | ||
end | ||
_g.depflag = depflag or false | ||
end | ||
return depflag or nil | ||
end | ||
|
||
function get_depsfileflag(target) | ||
local depfileflag = _g.depfileflag | ||
if depfileflag == nil then | ||
local compinst = target:compiler("cxx") | ||
if compinst:has_flags("-fdeps-file=" .. os.tmpfile(), "cxxflags", {flagskey = "gcc_deps_file", | ||
on_check = function (ok, errors) | ||
if errors:find("-M") then | ||
ok = true | ||
end | ||
return ok, errors | ||
end}) then | ||
depfileflag = "-fdeps-file=" | ||
end | ||
_g.depfileflag = depfileflag or false | ||
end | ||
return depfileflag or nil | ||
end | ||
|
||
function get_depstargetflag(target) | ||
local depoutputflag = _g.depoutputflag | ||
if depoutputflag == nil then | ||
local compinst = target:compiler("cxx") | ||
if compinst:has_flags("-fdeps-target=" .. os.tmpfile() .. ".o", "cxxflags", {flagskey = "gcc_deps_output", | ||
on_check = function (ok, errors) | ||
if errors:find("-M") then | ||
ok = true | ||
end | ||
return ok, errors | ||
end}) then | ||
depoutputflag = "-fdeps-target=" | ||
end | ||
_g.depoutputflag = depoutputflag or false | ||
end | ||
return depoutputflag or nil | ||
end | ||
|
||
function get_cppversionflag(target) | ||
local cppversionflag = _g.cppversionflag | ||
if cppversionflag == nil then | ||
local compinst = target:compiler("cxx") | ||
local flags = compinst:compflags({target = target}) | ||
cppversionflag = table.find_if(flags, function(v) string.startswith(v, "-std=c++") end) or "-std=c++20" | ||
_g.cppversionflag = cppversionflag | ||
end | ||
return cppversionflag or nil | ||
end | ||
|
||
-- get includedirs for stl headers | ||
-- | ||
-- $ echo '#include <vector>' | gcc -x c++ -E - | grep '/vector"' | ||
-- # 1 "/usr/include/c++/11/vector" 1 3 | ||
-- # 58 "/usr/include/c++/11/vector" 3 | ||
-- # 59 "/usr/include/c++/11/vector" 3 | ||
-- | ||
function _get_toolchain_includedirs_for_stlheaders(includedirs, gcc) | ||
local tmpfile = os.tmpfile() .. ".cc" | ||
io.writefile(tmpfile, "#include <vector>") | ||
local result = try {function () return os.iorunv(gcc, {"-E", "-x", "c++", tmpfile}) end} | ||
if result then | ||
for _, line in ipairs(result:split("\n", {plain = true})) do | ||
line = line:trim() | ||
if line:startswith("#") and line:find("/vector\"", 1, true) then | ||
local includedir = line:match("\"(.+)/vector\"") | ||
if includedir and os.isdir(includedir) then | ||
table.insert(includedirs, path.normalize(includedir)) | ||
break | ||
end | ||
end | ||
end | ||
end | ||
os.tryrm(tmpfile) | ||
end |
79 changes: 79 additions & 0 deletions
79
xmake/rules/c++/modules/modules_support/gcc/dependency_scanner.lua
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
--!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 ruki, Arthapz | ||
-- @file gcc/dependency_scanner.lua | ||
-- | ||
|
||
-- imports | ||
import("core.base.json") | ||
import("core.base.semver") | ||
import("core.project.depend") | ||
import("utils.progress") | ||
import("compiler_support") | ||
import("builder") | ||
import(".dependency_scanner", {inherit = true}) | ||
|
||
-- generate dependency files | ||
function generate_dependencies(target, sourcebatch, opt) | ||
local compinst = target:compiler("cxx") | ||
local common_args = {"-E", "-x", "c++"} | ||
local depsformatflag = compiler_support.get_depsflag(target, "p1689r5") | ||
local depsfileflag = compiler_support.get_depsfileflag(target) | ||
local depstargetflag = compiler_support.get_depstargetflag(target) | ||
local changed = false | ||
for _, sourcefile in ipairs(sourcebatch.sourcefiles) do | ||
local dependfile = target:dependfile(sourcefile) | ||
depend.on_changed(function() | ||
if opt.progress then | ||
progress.show(opt.progress, "${color.build.object}generating.module.deps %s", sourcefile) | ||
end | ||
|
||
local outputdir = compiler_support.get_outputdir(target, sourcefile) | ||
local jsonfile = path.translate(path.join(outputdir, path.filename(sourcefile) .. ".json")) | ||
if depsformatflag and depsfileflag and depstargetflag and not target:policy("build.c++.gcc.fallbackscanner") then | ||
local ifile = path.translate(path.join(outputdir, path.filename(sourcefile) .. ".i")) | ||
local dfile = path.translate(path.join(outputdir, path.filename(sourcefile) .. ".d")) | ||
local args = {sourcefile, "-MT", jsonfile, "-MD", "-MF", dfile, depsformatflag, depsfileflag .. jsonfile, depstargetflag .. target:objectfile(sourcefile), "-o", ifile} | ||
local compflags = compinst:compflags({sourcefile = sourcefile, target = target}) | ||
-- module mapper flag force gcc to check the imports but this is not wanted at this stage | ||
local modulemapperflag = compiler_support.get_modulemapperflag(target) .. path.translate(builder.get_module_mapper(target)) | ||
table.remove(compflags, table.unpack(table.find(compflags, modulemapperflag))) | ||
os.vrunv(compinst:program(), table.join(compflags, common_args, args)) | ||
os.rm(ifile) | ||
os.rm(dfile) | ||
else | ||
fallback_generate_dependencies(target, jsonfile, sourcefile, function(file) | ||
local compinst = target:compiler("cxx") | ||
local compflags = compinst:compflags({sourcefile = file, target = target}) | ||
-- exclude -fmodule* flags because, when they are set gcc try to find bmi of imported modules but they don't exists a this point of compilation | ||
table.remove_if(compflags, function(_, flag) return flag:startswith("-fmodule") end) | ||
local ifile = path.translate(path.join(outputdir, path.filename(file) .. ".i")) | ||
os.vrunv(compinst:program(), table.join(common_args, compflags, {file, "-o", ifile})) | ||
local content = io.readfile(ifile) | ||
os.rm(ifile) | ||
return content | ||
end) | ||
end | ||
changed = true | ||
|
||
local dependinfo = io.readfile(jsonfile) | ||
return { moduleinfo = dependinfo } | ||
end, {dependfile = dependfile, files = {sourcefile}, changed = target:is_rebuilt()}) | ||
end | ||
return changed | ||
end | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters