diff options
| author | ruki <[email protected]> | 2022-12-02 08:52:39 +0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2022-12-02 08:52:39 +0800 |
| commit | 5fc45303b35401bc2b1cb8c898c010f1505fce84 (patch) | |
| tree | 3e7dbaa2cfe5c8b0a5d65b6d7a058dd1250f3283 /xmake/rules/c++/modules/modules_support | |
| parent | 427f36fa0fc5250bf5a37b492102736bdd80867f (diff) | |
| parent | daca55898c15cf8e486e29d55ebb11dfb0e6190b (diff) | |
Merge pull request #3122 from Arthapz/process_modules
Generate dependencies of preprocessed modules to avoid importing #ifdef import
Diffstat (limited to 'xmake/rules/c++/modules/modules_support')
| -rw-r--r-- | xmake/rules/c++/modules/modules_support/clang.lua | 29 | ||||
| -rw-r--r-- | xmake/rules/c++/modules/modules_support/common.lua | 9 | ||||
| -rw-r--r-- | xmake/rules/c++/modules/modules_support/gcc.lua | 40 | ||||
| -rw-r--r-- | xmake/rules/c++/modules/modules_support/msvc.lua | 43 |
4 files changed, 114 insertions, 7 deletions
diff --git a/xmake/rules/c++/modules/modules_support/clang.lua b/xmake/rules/c++/modules/modules_support/clang.lua index 379aa517c..ad32931de 100644 --- a/xmake/rules/c++/modules/modules_support/clang.lua +++ b/xmake/rules/c++/modules/modules_support/clang.lua @@ -253,7 +253,34 @@ function generate_dependencies(target, sourcebatch, opt) -- no support of p1689 atm local jsonfile = path.translate(path.join(outputdir, path.filename(sourcefile) .. ".json")) - common.fallback_generate_dependencies(target, jsonfile, sourcefile) + common.fallback_generate_dependencies(target, jsonfile, sourcefile, function(file) + local compinst = target:compiler("cxx") + local defines = {} + for _, define in pairs(target:get("defines")) do + table.insert(defines, "-D" .. define) + end + local includedirs = {} + for _, dep in ipairs(target:orderdeps()) do + local includedir = dep:get("sysincludedirs") or dep:get("includedirs") + if includedir then + table.join2(includedirs, includedir) + end + end + for _, pkg in pairs(target:pkgs()) do + local includedir = pkg:get("sysincludedirs") or pkg:get("includedirs") + if includedir then + table.join2(includedirs, includedir) + end + end + for i, includedir in pairs(includedirs) do + includedirs[i] = "-I" .. includedir + end + local ifile = path.translate(path.join(outputdir, path.filename(file) .. ".i")) + os.vrunv(compinst:program(), table.join(includedirs, defines, {"-E", "-x", "c++", file, "-o", ifile})) + local content = io.readfile(ifile) + os.rm(ifile) + return content + end) changed = true local dependinfo = io.readfile(jsonfile) diff --git a/xmake/rules/c++/modules/modules_support/common.lua b/xmake/rules/c++/modules/modules_support/common.lua index 175a0db8c..b21613f61 100644 --- a/xmake/rules/c++/modules/modules_support/common.lua +++ b/xmake/rules/c++/modules/modules_support/common.lua @@ -432,7 +432,7 @@ end } ] }]] -function fallback_generate_dependencies(target, jsonfile, sourcefile) +function fallback_generate_dependencies(target, jsonfile, sourcefile, preprocess_file) local output = {version = 0, revision = 0, rules = {}} local rule = {outputs = {jsonfile}} rule["primary-output"] = target:objectfile(sourcefile) @@ -441,15 +441,15 @@ function fallback_generate_dependencies(target, jsonfile, sourcefile) local module_name_private local module_deps = {} local module_deps_set = hashset.new() - local sourcecode = io.readfile(sourcefile) + local sourcecode = preprocess_file(sourcefile) or io.readfile(sourcefile) sourcecode = sourcecode:gsub("//.-\n", "\n") sourcecode = sourcecode:gsub("/%*.-%*/", "") for _, line in ipairs(sourcecode:split("\n", {plain = true})) do if not module_name_export then - module_name_export = line:match("export%s+module%s+(.+)%s*;") + module_name_export = line:match("export%s+module%s+(.+)%s*;") or line:match("export%s+__preprocessed_module%s+(.+)%s*;") end if not module_name_private then - module_name_private = line:match("module%s+(.+)%s*;") + module_name_private = line:match("module%s+(.+)%s*;") or line:match("__preprocessed_module%s+(.+)%s*;") end local module_depname = line:match("import%s+(.+)%s*;") -- we need parse module interface dep in cxx/impl_unit.cpp, e.g. hello.mpp and hello_impl.cpp @@ -487,6 +487,7 @@ function fallback_generate_dependencies(target, jsonfile, sourcefile) local provide = {} provide["logical-name"] = module_name_export provide["source-path"] = path.absolute(sourcefile, project.directory()) + provide["is-interface"] = true rule.provides = {} table.insert(rule.provides, provide) diff --git a/xmake/rules/c++/modules/modules_support/gcc.lua b/xmake/rules/c++/modules/modules_support/gcc.lua index d02512e59..476bc6487 100644 --- a/xmake/rules/c++/modules/modules_support/gcc.lua +++ b/xmake/rules/c++/modules/modules_support/gcc.lua @@ -212,7 +212,34 @@ function generate_dependencies(target, sourcebatch, opt) local args = {sourcefile, "-MD", "-MT", jsonfile, "-MF", dfile, depfileflag .. jsonfile, trtbdflag, depoutputfile .. target:objectfile(sourcefile), "-o", ifile} os.vrunv(compinst:program(), table.join(compinst:compflags({target = target}), common_args, args), {envs = vcvars}) else - common.fallback_generate_dependencies(target, jsonfile, sourcefile) + common.fallback_generate_dependencies(target, jsonfile, sourcefile, function(file) + local compinst = target:compiler("cxx") + local defines = {} + for _, define in ipairs(target:get("defines")) do + table.insert(defines, "-D" .. define) + end + local includedirs = {} + for _, dep in ipairs(target:orderdeps()) do + local includedir = dep:get("sysincludedirs") or dep:get("includedirs") + if includedir then + table.join2(includedirs, includedir) + end + end + for _, pkg in pairs(target:pkgs()) do + local includedir = pkg:get("sysincludedirs") or pkg:get("includedirs") + if includedir then + table.join2(includedirs, includedir) + end + end + for i, includedir in pairs(includedirs) do + includedirs[i] = "-I" .. includedir + end + local ifile = path.translate(path.join(outputdir, path.filename(file) .. ".i")) + os.vrunv(compinst:program(), table.join(includedirs, defines, {get_cppversionflag(target), "-E", "-x", "c++", file, "-o", ifile})) + local content = io.readfile(ifile) + os.rm(ifile) + return content + end) end changed = true @@ -557,3 +584,14 @@ function get_depoutputflag(target) 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
\ No newline at end of file diff --git a/xmake/rules/c++/modules/modules_support/msvc.lua b/xmake/rules/c++/modules/modules_support/msvc.lua index d9f3019d6..da0f69535 100644 --- a/xmake/rules/c++/modules/modules_support/msvc.lua +++ b/xmake/rules/c++/modules/modules_support/msvc.lua @@ -208,6 +208,8 @@ end -- generate dependency files function generate_dependencies(target, sourcebatch, opt) + local toolchain = target:toolchain("msvc") + local scandependenciesflag = nil -- get_scandependenciesflag(target) local scandependenciesflag = get_scandependenciesflag(target) local common_flags = {"-TP", scandependenciesflag} local cachedir = common.modules_cachedir(target) @@ -228,7 +230,36 @@ function generate_dependencies(target, sourcebatch, opt) local flags = {jsonfile, sourcefile, "-Fo" .. target:objectfile(sourcefile)} _compile(target, table.join(common_flags, flags)) else - common.fallback_generate_dependencies(target, jsonfile, sourcefile) + common.fallback_generate_dependencies(target, jsonfile, sourcefile, function(file) + local compinst = target:compiler("cxx") + local defines = {} + for _, define in ipairs(target:get("defines")) do + table.insert(defines, "/D" .. define) + end + local _includedirs = {} + for _, dep in ipairs(target:orderdeps()) do + local includedir = dep:get("sysincludedirs") or dep:get("includedirs") + if includedir then + table.join2(includedirs, includedir) + end + end + for _, pkg in pairs(target:pkgs()) do + local includedir = pkg:get("sysincludedirs") or pkg:get("includedirs") + if includedir then + table.join2(includedirs, includedir) + end + end + local includedirs = {} + for i, includedir in pairs(_includedirs) do + table.insert(includedirs, "/I") + table.insert(includedirs, includedir) + end + local ifile = path.translate(path.join(outputdir, path.filename(file) .. ".i")) + os.vrunv(compinst:program(), table.join(includedirs, defines, {"/nologo", get_cppversionflag(target), "/P", "-TP", file, "/Fi" .. ifile}), {envs = toolchain:runenvs()}) + local content = io.readfile(ifile) + os.rm(ifile) + return content + end) end changed = true @@ -789,3 +820,13 @@ function get_requiresflags(target, requires, opt) return requireflags end 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++latest" + end + return cppversionflag or nil +end |
