Skip to content

Commit

Permalink
Merge pull request #4687 from Arthapz/fix-.cpp-objectfiles-update
Browse files Browse the repository at this point in the history
fix recompilation of .cpp files
  • Loading branch information
waruqi authored Feb 5, 2024
2 parents 650d8f2 + ffe0768 commit d375ab0
Show file tree
Hide file tree
Showing 4 changed files with 154 additions and 69 deletions.
49 changes: 20 additions & 29 deletions xmake/rules/c++/modules/modules_support/builder.lua
Original file line number Diff line number Diff line change
Expand Up @@ -47,24 +47,17 @@ function _build_modules(target, sourcebatch, modules, opt)

local fileconfig = target:fileconfig(cppfile)
local bmifile = provide and compiler_support.get_bmi_path(provide.bmi)
local build = _should_build(target, cppfile, bmifile, {objectfile = objectfile, requires = module.requires})

-- add objectfile if module is not from external dep
if not (fileconfig and fileconfig.external) then
target:add("objectfiles", objectfile)
end

-- needed to detect rebuild of dependencies
if provide and build then
_mark_build(target, name)
end

local deps = {}
for _, dep in ipairs(table.keys(module.requires or {})) do
table.insert(deps, opt.batchjobs and target:name() .. dep or dep)
end

opt.build_module(deps, build, module, name, provide, objectfile, cppfile, fileconfig)
opt.build_module(deps, module, name, provide, objectfile, cppfile, fileconfig)

::CONTINUE::
end
Expand All @@ -85,18 +78,18 @@ function _build_headerunits(target, headerunits, opt)
end
local bmifile = path.join(outputdir, path.filename(headerunit.name) .. compiler_support.get_bmi_extension(target))
local key = path.normalize(headerunit.path)
local build = _should_build(target, headerunit.path, bmifile, {key = key, headerunit = true})
local build = should_build(target, headerunit.path, bmifile, {key = key, headerunit = true})

if build then
_mark_build(target, key)
mark_build(target, key)
end

opt.build_headerunit(headerunit, key, bmifile, outputdir, build)
end
end

-- should we build this module or headerunit ?
function _should_build(target, sourcefile, bmifile, opt)
function should_build(target, sourcefile, bmifile, opt)

-- force rebuild a module if any of its module dependency is rebuilt
local requires = opt.requires
Expand All @@ -112,23 +105,21 @@ function _should_build(target, sourcefile, bmifile, opt)
end
end

-- or rebuild it if the file changed for headerunit and namedmodules
-- or rebuild it if the file changed
local objectfile = opt.objectfile
if compiler_support.has_module_extension(sourcefile) or (opt and opt.headerunit) then
local dryrun = option.get("dry-run")
local compinst = compiler.load("cxx", {target = target})
local compflags = compinst:compflags({sourcefile = sourcefile, target = target})
local dryrun = option.get("dry-run")
local compinst = compiler.load("cxx", {target = target})
local compflags = compinst:compflags({sourcefile = sourcefile, target = target})

local dependfile = target:dependfile(bmifile or objectfile)
local dependinfo = target:is_rebuilt() and {} or (depend.load(dependfile) or {})
local dependfile = target:dependfile(bmifile or objectfile)
local dependinfo = target:is_rebuilt() and {} or (depend.load(dependfile) or {})

-- need build this object?
local depvalues = {compinst:program(), compflags}
local lastmtime = os.isfile(bmifile or objectfile) and os.mtime(dependfile) or 0
-- need build this object?
local depvalues = {compinst:program(), compflags}
local lastmtime = os.isfile(bmifile or objectfile) and os.mtime(dependfile) or 0

if dryrun or depend.is_changed(dependinfo, {lastmtime = lastmtime, values = depvalues}) then
return true
end
if dryrun or depend.is_changed(dependinfo, {lastmtime = lastmtime, values = depvalues}) then
return true
end

return false
Expand Down Expand Up @@ -190,7 +181,7 @@ function _builder(target)
return builder
end

function _mark_build(target, name)
function mark_build(target, name)
compiler_support.memcache():set2("should_build_in" .. target:name(), name, true)
end

Expand All @@ -207,10 +198,10 @@ function build_modules_for_batchjobs(target, batchjobs, sourcebatch, modules, op

local modulesjobs = {}
_build_modules(target, sourcebatch, modules, table.join(opt, {
build_module = function(deps, build, module, name, provide, objectfile, cppfile, fileconfig)
build_module = function(deps, module, name, provide, objectfile, cppfile, fileconfig)
local job_name = name and target:name() .. name or cppfile

modulesjobs[job_name] = _builder(target).make_module_buildjobs(target, batchjobs, job_name, deps, {build = build, module = module, objectfile = objectfile, cppfile = cppfile})
modulesjobs[job_name] = _builder(target).make_module_buildjobs(target, batchjobs, job_name, deps, {module = module, objectfile = objectfile, cppfile = cppfile})

if provide and fileconfig and fileconfig.public then
batchjobs:addjob(name .. "_metafile", function(index, total)
Expand All @@ -237,8 +228,8 @@ function build_modules_for_batchcmds(target, batchcmds, sourcebatch, modules, op

-- build modules
_build_modules(target, sourcebatch, modules, table.join(opt, {
build_module = function(_, build, module, name, provide, objectfile, cppfile, fileconfig)
depmtime = math.max(depmtime, _builder(target).make_module_buildcmds(target, batchcmds, {build = build, module = module, cppfile = cppfile, objectfile = objectfile, progress = opt.progress}))
build_module = function(_, module, name, provide, objectfile, cppfile, fileconfig)
depmtime = math.max(depmtime, _builder(target).make_module_buildcmds(target, batchcmds, {module = module, cppfile = cppfile, objectfile = objectfile, progress = opt.progress}))

if provide and fileconfig and fileconfig.public then
local metafilepath = compiler_support.get_metafile(target, cppfile)
Expand Down
86 changes: 62 additions & 24 deletions xmake/rules/c++/modules/modules_support/clang/builder.lua
Original file line number Diff line number Diff line change
Expand Up @@ -205,36 +205,55 @@ function make_module_buildjobs(target, batchjobs, job_name, deps, opt)
local compinst = compiler.load("cxx", {target = target})
local compflags = compinst:compflags({sourcefile = opt.cppfile, target = target})

local build
if provide or compiler_support.has_module_extension(opt.cppfile) then
build = should_build(target, opt.cppfile, bmifile, {objectfile = opt.objectfile, requires = opt.module.requires})

-- needed to detect rebuild of dependencies
if provide and build then
mark_build(target, name)
end
end

-- append requires flags
if opt.module.requires then
_append_requires_flags(target, opt.module, name, opt.cppfile, bmifile, opt)
end

-- for cpp file we need to check after appendings the flags
if build == nil then
build = should_build(target, opt.cppfile, bmifile, {objectfile = opt.objectfile, requires = opt.module.requires})
end

local dependfile = target:dependfile(bmifile or opt.objectfile)
local dependinfo = depend.load(dependfile) or {}
dependinfo.files = {}
local depvalues = {compinst:program(), compflags}

-- compile if it's a named module
if opt.build and (provide or compiler_support.has_module_extension(opt.cppfile)) then
progress.show((index * 100) / total, "${color.build.target}<%s> ${clear}${color.build.object}compiling.module.$(mode) %s", target:name(), name or opt.cppfile)
if build then
-- compile if it's a named module
if provide or compiler_support.has_module_extension(opt.cppfile) then
progress.show((index * 100) / total, "${color.build.target}<%s> ${clear}${color.build.object}compiling.module.$(mode) %s", target:name(), name or opt.cppfile)

if not dryrun then
local objectdir = path.directory(opt.objectfile)
if not os.isdir(objectdir) then
os.mkdir(objectdir)
if not dryrun then
local objectdir = path.directory(opt.objectfile)
if not os.isdir(objectdir) then
os.mkdir(objectdir)
end
end
end

local fileconfig = target:fileconfig(opt.cppfile)
local external = fileconfig and fileconfig.external
local fileconfig = target:fileconfig(opt.cppfile)
local external = fileconfig and fileconfig.external

local precompile, first_step, second_step = _make_modulebuildflags(target, provide, bmifile, {sourcefile = opt.cppfile, external = external, name = name})
local precompile, first_step, second_step = _make_modulebuildflags(target, provide, bmifile, {sourcefile = opt.cppfile, external = external, name = name})

_compile(target, first_step, opt.cppfile, precompile and bmifile or opt.objectfile)
_compile(target, first_step, opt.cppfile, precompile and bmifile or opt.objectfile)

if second_step then
_compile(target, second_step, opt.cppfile, opt.objectfile, {bmifile = bmifile})
if second_step then
_compile(target, second_step, opt.cppfile, opt.objectfile, {bmifile = bmifile})
end
else
os.tryrm(opt.objectfile) -- force rebuild for .cpp files
end
end

Expand All @@ -250,24 +269,43 @@ function make_module_buildcmds(target, batchcmds, opt)
local name, provide, _ = compiler_support.get_provided_module(opt.module)
local bmifile = provide and compiler_support.get_bmi_path(provide.bmi)

local build
if provide or compiler_support.has_module_extension(opt.cppfile) then
build = should_build(target, opt.cppfile, bmifile, {objectfile = opt.objectfile, requires = opt.module.requires})

-- needed to detect rebuild of dependencies
if provide and build then
mark_build(target, name)
end
end

-- append requires flags
if opt.module.requires then
_append_requires_flags(target, opt.module, name, opt.cppfile, bmifile, opt)
end

-- compile if it's a named module
if opt.build and (provide or compiler_support.has_module_extension(opt.cppfile)) then
batchcmds:show_progress(opt.progress, "${color.build.target}<%s> ${clear}${color.build.object}compiling.module.$(mode) %s", target:name(), name or opt.cppfile)
batchcmds:mkdir(path.directory(opt.objectfile))
-- for cpp file we need to check after appendings the flags
if build == nil then
build = should_build(target, opt.cppfile, bmifile, {objectfile = opt.objectfile, requires = opt.module.requires})
end

if build then
-- compile if it's a named module
if provide or compiler_support.has_module_extension(opt.cppfile) then
batchcmds:show_progress(opt.progress, "${color.build.target}<%s> ${clear}${color.build.object}compiling.module.$(mode) %s", target:name(), name or opt.cppfile)
batchcmds:mkdir(path.directory(opt.objectfile))

local fileconfig = target:fileconfig(opt.cppfile)
local external = fileconfig and fileconfig.external
local fileconfig = target:fileconfig(opt.cppfile)
local external = fileconfig and fileconfig.external

local precompile, first_step, second_step = _make_modulebuildflags(target, provide, bmifile, {batchcmds = true, sourcefile = opt.cppfile, external = external, name = name})
_batchcmds_compile(batchcmds, target, first_step, opt.cppfile, precompile and bmifile or opt.objectfile)
local precompile, first_step, second_step = _make_modulebuildflags(target, provide, bmifile, {batchcmds = true, sourcefile = opt.cppfile, external = external, name = name})
_batchcmds_compile(batchcmds, target, first_step, opt.cppfile, precompile and bmifile or opt.objectfile)

if second_step then
_batchcmds_compile(batchcmds, target, second_step, opt.cppfile, opt.objectfile, {bmifile = bmifile})
if second_step then
_batchcmds_compile(batchcmds, target, second_step, opt.cppfile, opt.objectfile, {bmifile = bmifile})
end
else
batchcmds:rm(opt.objectfile) -- force rebuild for .cpp files
end
end
batchcmds:add_depfiles(opt.cppfile)
Expand Down
23 changes: 21 additions & 2 deletions xmake/rules/c++/modules/modules_support/gcc/builder.lua
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,13 @@ function make_module_buildjobs(target, batchjobs, job_name, deps, opt)
local compinst = compiler.load("cxx", {target = target})
local compflags = compinst:compflags({sourcefile = opt.cppfile, target = target})

local build = should_build(target, opt.cppfile, bmifile, {objectfile = opt.objectfile, requires = opt.module.requires})

-- needed to detect rebuild of dependencies
if provide and build then
mark_build(target, name)
end

-- generate and append module mapper file
local module_mapper
if provide or opt.module.requires then
Expand All @@ -234,7 +241,7 @@ function make_module_buildjobs(target, batchjobs, job_name, deps, opt)
dependinfo.files = {}
local depvalues = {compinst:program(), compflags}

if opt.build then
if build then
-- compile if it's a named module
if provide or compiler_support.has_module_extension(opt.cppfile) then
progress.show((index * 100) / total, "${color.build.target}<%s> ${clear}${color.build.object}compiling.module.$(mode) %s", target:name(), name or opt.cppfile)
Expand All @@ -245,6 +252,8 @@ function make_module_buildjobs(target, batchjobs, job_name, deps, opt)
local flags = _make_modulebuildflags(target, opt)
_compile(target, flags, opt.cppfile, opt.objectfile)
os.tryrm(module_mapper)
else
os.tryrm(opt.objectfile) -- force rebuild for .cpp files
end
end
table.insert(dependinfo.files, opt.cppfile)
Expand All @@ -257,16 +266,24 @@ end
function make_module_buildcmds(target, batchcmds, opt)

local name, provide, _ = compiler_support.get_provided_module(opt.module)
local bmifile = provide and compiler_support.get_bmi_path(provide.bmi)
local module_mapperflag = compiler_support.get_modulemapperflag(target)

local build = should_build(target, opt.cppfile, bmifile, {objectfile = opt.objectfile, requires = opt.module.requires})

-- needed to detect rebuild of dependencies
if provide and build then
mark_build(target, name)
end

-- generate and append module mapper file
local module_mapper
if provide or opt.module.requires then
module_mapper = _generate_modulemapper_file(target, opt.module)
target:fileconfig_add(opt.cppfile, {force = {cxxflags = {module_mapperflag .. module_mapper}}})
end

if opt.build then
if build then
-- compile if it's a named module
if provide or compiler_support.has_module_extension(opt.cppfile) then
batchcmds:show_progress(opt.progress, "${color.build.target}<%s> ${clear}${color.build.object}compiling.module.$(mode) %s", target:name(), name or opt.cppfile)
Expand All @@ -275,6 +292,8 @@ function make_module_buildcmds(target, batchcmds, opt)
end
batchcmds:mkdir(path.directory(opt.objectfile))
_batchcmds_compile(batchcmds, target, _make_modulebuildflags(target, {batchcmds = true, sourcefile = opt.cppfile}), opt.cppfile, opt.objectfile)
else
batchcmds:rm(opt.objectfile) -- force rebuild for .cpp files
end
end
batchcmds:add_depfiles(opt.cppfile)
Expand Down
Loading

0 comments on commit d375ab0

Please sign in to comment.