Files
mruby-mruby/tasks/presym.rake
T
Yukihiro "Matz" Matsumoto 8df9a22a85 presym.rake: fix unnecessary full recompilation on single file changes
Restrict .o -> presym.list_path dependency to internal builds only
(mrbc sub-build). Regular host/cross builds don't need this because
:all => :gensym ordering guarantees presym headers exist before .o
compilation, and compiler .d files track header changes.

The broad dependency caused full recompilation because Rake's
all_prerequisite_tasks checks transitive prerequisites: every .o
transitively depended on every .pi file through presym.list_path.

Fixes #6721.

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-25 15:10:05 +09:00

61 lines
2.1 KiB
Ruby

all_prerequisites = ->(task_name, prereqs) do
Rake::Task[task_name].prerequisites.each do |prereq_name|
next if prereqs[prereq_name]
prereqs[prereq_name] = true
all_prerequisites.(Rake::Task[prereq_name].name, prereqs)
end
end
MRuby.each_target do |build|
gensym_task = task(:gensym)
presym = build.presym
include_dir = "#{build.build_dir}/include"
build.compilers.each{|c| c.include_paths << include_dir}
build.gems.each{|gem| gem.compilers.each{|c| c.include_paths << include_dir}}
prereqs = {}
ppps = []
build_dir = "#{build.build_dir}/"
mrbc_build_dir = "#{build.mrbc_build.build_dir}/" if build.mrbc_build
build.products.each{|product| all_prerequisites.(product, prereqs)}
prereqs.each_key do |prereq|
next unless File.extname(prereq) == build.exts.object
next unless prereq.start_with?(build_dir)
next if mrbc_build_dir && prereq.start_with?(mrbc_build_dir)
ppp = prereq.ext(build.exts.presym_preprocessed)
if Rake.application.lookup(ppp) ||
Rake.application.enhance_with_matching_rule(ppp)
ppps << ppp
end
end
file presym.list_path => ppps do
presyms = presym.scan(ppps)
current_presyms = presym.read_list if File.exist?(presym.list_path)
update = presyms != current_presyms
presym.write_list(presyms) if update
mkdir_p presym.header_dir
%w[id table].each do |type|
next if !update && File.exist?(presym.send("#{type}_header_path"))
presym.send("write_#{type}_header", presyms)
end
end
# Internal sub-builds (e.g., mrbc) may be compiled within another
# build's presym scanning chain, before :gensym completes.
# They need explicit .o -> presym.list_path dependencies.
# Regular builds don't need this since :all => :gensym => :build
# already guarantees ordering, and .d files track header changes.
if build.internal?
prereqs.each_key do |prereq|
next unless File.extname(prereq) == build.exts.object
next unless prereq.start_with?(build_dir)
file prereq => presym.list_path
end
end
gensym_task.enhance([presym.list_path])
end