diff --git a/tests/projects/c++/modules/hello_with_pch/test.lua b/tests/projects/c++/modules/hello_with_pch/test.lua new file mode 100644 index 00000000000..7717f804997 --- /dev/null +++ b/tests/projects/c++/modules/hello_with_pch/test.lua @@ -0,0 +1 @@ +inherit(".test_base") diff --git a/tests/projects/c++/modules/test_pch.lua b/tests/projects/c++/modules/test_pch.lua deleted file mode 100644 index 98286c2299d..00000000000 --- a/tests/projects/c++/modules/test_pch.lua +++ /dev/null @@ -1,31 +0,0 @@ -import("lib.detect.find_tool") -import("core.base.semver") -import("detect.sdks.find_vstudio") -import("utils.ci.is_running", {alias = "ci_is_running"}) - -function _build() - if ci_is_running() then - os.run("xmake -rvD") - else - os.run("xmake -r") - end - local outdata = os.iorun("xmake") - if outdata then - if outdata:find("compiling") or outdata:find("linking") or outdata:find("generating") then - raise("Modules incremental compilation does not work\n%s", outdata) - end - end -end - -function main(t) - -- TODO c++ modules with pch does not work for gcc now. - if is_host("linux") then - local clang = find_tool("clang", {version = true}) - if clang then - os.exec("xmake f --toolchain=clang -c --yes --policies=build.c++.modules.std:n,build.c++.clang.fallbackscanner") - _build() - end - else - _build() - end -end diff --git a/xmake/modules/core/project/depend.lua b/xmake/modules/core/project/depend.lua index 05b93acf148..ca213d97554 100644 --- a/xmake/modules/core/project/depend.lua +++ b/xmake/modules/core/project/depend.lua @@ -70,6 +70,8 @@ end -- show diagnosis info? function _is_show_diagnosis_info() + return true + --[[ local show = _g.is_show_diagnosis_info if show == nil then if project.policy("diagnosis.check_build_deps") then @@ -79,7 +81,7 @@ function _is_show_diagnosis_info() end _g.is_show_diagnosis_info = show end - return show + return show]] end -- save dependent info to file diff --git a/xmake/modules/core/tools/gcc.lua b/xmake/modules/core/tools/gcc.lua index 059eb5977cc..3de17be4a42 100644 --- a/xmake/modules/core/tools/gcc.lua +++ b/xmake/modules/core/tools/gcc.lua @@ -31,6 +31,7 @@ import("core.language.language") import("utils.progress") import("private.cache.build_cache") import("private.service.distcc_build.client", {alias = "distcc_build_client"}) +import("rules.c++.modules.modules_support.compiler_support", {rootdir = os.programdir()}) function init(self) @@ -864,24 +865,35 @@ function _compile(self, sourcefile, objectfile, compflags, opt) end end --- make the compile arguments list for the precompiled header -function _compargv_pch(self, pcheaderfile, pcoutputfile, flags, opt) - - -- remove "-include xxx.h" and "-include-pch xxx.pch" - local pchflags = {} +-- remove "-include xxx.h" and "-include-pch xxx.pch" +function _remove_flags_for_pch(self, flags, opt) + opt = opt or {} + local result = {} local include = false + local pchfile = opt.pchfile for _, flag in ipairs(flags) do + local inserted = false if not flag:startswith("-include") then if not include then - table.insert(pchflags, flag) + inserted = true end include = false else include = true end + if pchfile and flag:startswith("-fmodules") then + inserted = false + end + if inserted then + table.insert(result, flag) + end end + return result +end - -- set the language of precompiled header? +-- make the compile arguments list for the precompiled header +function _translate_flags_for_pch(self, flags) + local pchflags = _remove_flags_for_pch(self, flags, {pchfile = true}) if self:kind() == "cxx" then table.insert(pchflags, "-x") table.insert(pchflags, "c++-header") @@ -895,19 +907,24 @@ function _compargv_pch(self, pcheaderfile, pcoutputfile, flags, opt) table.insert(pchflags, "-x") table.insert(pchflags, "objective-c-header") end + return pchflags +end - -- make the compile arguments list - local argv = table.join("-c", pchflags, "-o", pcoutputfile, pcheaderfile) - return self:program(), argv +-- remove the force includes for c++modules +-- @see https://github.com/xmake-io/xmake/issues/4051#issuecomment-2795707800 +function _translate_flags_for_mpp(self, flags) + return _remove_flags_for_pch(self, flags) end -- make the compile arguments list function compargv(self, sourcefile, objectfile, flags, opt) - -- precompiled header? + -- is precompiled header or module files? remove the force includes. local extension = path.extension(sourcefile) if (extension:startswith(".h") or extension == ".inl") then - return _compargv_pch(self, sourcefile, objectfile, flags, opt) + flags = _translate_flags_for_pch(self, flags) + elseif compiler_support.has_module_extension(sourcefile, {extension = extension}) then + flags = _translate_flags_for_mpp(self, flags) end local argv = table.join("-c", flags, "-o", objectfile, sourcefile) diff --git a/xmake/plugins/project/vstudio/impl/vs201x_vcxproj.lua b/xmake/plugins/project/vstudio/impl/vs201x_vcxproj.lua index b69826694e0..9b0846930d1 100644 --- a/xmake/plugins/project/vstudio/impl/vs201x_vcxproj.lua +++ b/xmake/plugins/project/vstudio/impl/vs201x_vcxproj.lua @@ -30,6 +30,7 @@ import("detect.sdks.find_cuda") import("vsfile") import("vsutils") import("private.utils.toolchain", {alias = "toolchain_utils"}) +import("rules.c++.modules.modules_support.compiler_support", {rootdir = os.programdir()}) function _make_dirs(dir, vcxprojdir) dir = dir:trim() @@ -132,12 +133,6 @@ function _split_gpucodes(flag) return flag:split(",") end --- is module file? -function _is_modulefile(sourcefile) - local extension = path.extension(sourcefile) - return extension == ".mpp" or extension == ".mxx" or extension == ".cppm" or extension == ".ixx" -end - -- make compiling command function _make_compcmd(compargv, sourcefile, objectfile, vcxprojdir) local argv = {} @@ -1179,7 +1174,7 @@ function _make_source_file_forall(vcxprojfile, vsinfo, target, sourcefile, sourc else -- compile as c++ modules - if _is_modulefile(sourcefile) then + if compiler_support.has_module_extension(sourcefile) then vcxprojfile:print("CompileAsCppModule") end @@ -1316,7 +1311,7 @@ function _make_source_file_forspec(vcxprojfile, vsinfo, target, sourcefile, sour -- for *.c/cpp/cu files else -- compile as c++ modules - if _is_modulefile(sourcefile) then + if compiler_support.has_module_extension(sourcefile) then vcxprojfile:print("CompileAsCppModule") end diff --git a/xmake/rules/c++/modules/modules_support/builder.lua b/xmake/rules/c++/modules/modules_support/builder.lua index 7ec120cc96f..a02e1e7d36f 100644 --- a/xmake/rules/c++/modules/modules_support/builder.lua +++ b/xmake/rules/c++/modules/modules_support/builder.lua @@ -48,8 +48,9 @@ function _build_modules(target, sourcebatch, modules, opt) -- we need to use the full path as dep name if requre item is headerunit local dep = name if req.method:startswith("include-") and req.path then - dep = path.normalize(req.path) + dep = req.path end + dep = path.normalize(dep) local depname = target:fullname() .. "/module/" .. dep table.insert(deps, depname) end @@ -279,7 +280,7 @@ function build_modules_for_batchjobs(target, batchjobs, sourcebatch, modules, op -- add module jobs _build_modules(target, sourcebatch, modules, table.join(opt, { build_module = function(deps, module, name, objectfile, cppfile) - local job_name = target:fullname() .. "/module/" .. (name or cppfile) + local job_name = target:fullname() .. "/module/" .. path.normalize(name or cppfile) modulesjobs[job_name] = _builder(target).make_module_buildjobs(target, batchjobs, job_name, deps, {module = module, objectfile = objectfile, cppfile = cppfile}) end @@ -306,7 +307,7 @@ function build_modules_for_jobgraph(target, jobgraph, sourcebatch, modules, opt) -- add module jobs _build_modules(target, sourcebatch, modules, table.join(opt, { build_module = function(deps, module, name, objectfile, cppfile) - local jobname = target:fullname() .. "/module/" .. (name or cppfile) + local jobname = target:fullname() .. "/module/" .. path.normalize(name or cppfile) _builder(target).make_module_jobgraph(target, jobgraph, { module = module, objectfile = objectfile, cppfile = cppfile }) @@ -355,7 +356,7 @@ function build_headerunits_for_batchjobs(target, batchjobs, sourcebatch, modules local modulesjobs = {} _build_headerunits(target, headerunits, table.join(opt, { build_headerunit = function(headerunit, key, bmifile, outputdir, build) - local job_name = target:fullname() .. "/module/" .. key + local job_name = target:fullname() .. "/module/" .. path.normalize(key) local job = _builder(target).make_headerunit_buildjobs(target, job_name, batchjobs, headerunit, bmifile, outputdir, table.join(opt, {build = build})) if job then modulesjobs[job_name] = job @@ -392,7 +393,7 @@ function build_headerunits_for_jobgraph(target, jobgraph, sourcebatch, modules, local modulesjobs = {} _build_headerunits(target, headerunits, table.join(opt, { build_headerunit = function(headerunit, key, bmifile, outputdir, build) - local job_name = target:fullname() .. "/module/" .. key + local job_name = target:fullname() .. "/module/" .. path.normalize(key) _builder(target).make_headerunit_jobgraph(target, job_name, jobgraph, headerunit, bmifile, outputdir, table.join(opt, {build = build})) end diff --git a/xmake/rules/c++/modules/modules_support/compiler_support.lua b/xmake/rules/c++/modules/modules_support/compiler_support.lua index eed30a32054..554b536cf9e 100644 --- a/xmake/rules/c++/modules/modules_support/compiler_support.lua +++ b/xmake/rules/c++/modules/modules_support/compiler_support.lua @@ -82,13 +82,14 @@ function get_bmi_path(bmifile) end -- has module extension? e.g. *.mpp, ... -function has_module_extension(sourcefile) +function has_module_extension(sourcefile, opt) + opt = opt or {} local modulexts = _g.modulexts if modulexts == nil then modulexts = hashset.of(".mpp", ".mxx", ".cppm", ".ixx") _g.modulexts = modulexts end - local extension = path.extension(sourcefile) + local extension = opt.extension or path.extension(sourcefile) return modulexts:has(extension:lower()) end