Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 28 additions & 1 deletion lib/mruby/build/command.rb
Original file line number Diff line number Diff line change
Expand Up @@ -175,11 +175,20 @@ def setup_debug(conf)
#
# /src/value_array.h:
#
# The compile of the object writes the +.d+ file, and the presym
# preprocess of the same source reads it too: both run the preprocessor
# over the same source with the same include paths, so a header that
# changes what one sees changes what the other sees. Only the presym
# headers are left out of the preprocess: they are made from the
# preprocessed files, so depending on them would preprocess every source
# again on the run after the symbol table changed. The scan does not
# include them anyway (see +MRB_PRESYM_SCANNING+ in +mruby/presym.h+).
#
def get_dependencies(file, source)
discard_foreign_output(file) if rule_applies?(source)
deps = [MRUBY_CONFIG]
dep_file = file.ext(".d")
return deps unless object_ext?(file) && File.exist?(dep_file)
return deps unless File.exist?(dep_file)

header_deps = File.read(dep_file).gsub("\\\n ", "").split("\n").map do |dep_line|
# dep_line:
Expand All @@ -191,6 +200,24 @@ def get_dependencies(file, source)
# []
# []
end.flatten.uniq
unless object_ext?(file)
presym_dir = "#{build.presym.header_dir}/"
header_deps.reject! {|dep| dep.start_with?(presym_dir) }
end
# A header the +.d+ file names but that no longer exists is not a
# dependency Rake can resolve: `Rake::TaskManager#attempt_rule` gives up
# on the rule when a source neither exists nor has a task, and the
# output is left as it is, with nothing to rebuild it (the object keeps
# only the presym proxy from `tasks/presym.rake`, the preprocess drops
# out of the scan). The +.d+ describes a compile that read that header,
# so the output is stale by its own record: it is removed here, so that
# the rule, with the header left out, builds it again and writes a
# +.d+ that matches the sources of now.
missing = header_deps.reject {|dep| File.exist?(dep) || Rake::Task.task_defined?(dep) }
unless missing.empty?
header_deps -= missing
rm_f file if rule_applies?(source)
end
deps.concat(header_deps)
end

Expand Down
4 changes: 4 additions & 0 deletions lib/mruby/presym.rb
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,10 @@ def table_header_path
@table_header_path ||= "#{header_dir}/table.h".freeze
end

def headers_exist?
File.exist?(id_header_path) && File.exist?(table_header_path)
end

private

def read_preprocessed(presym_hash, path)
Expand Down
18 changes: 18 additions & 0 deletions tasks/presym.rake
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,27 @@ MRuby.each_target do |build|
presym.send("write_#{type}_header", presyms)
end
presym.write_list(presyms)
elsif !presym.headers_exist?
# The headers are made from the list, so a header that is gone is
# written again from the list as it stands. The list itself is left
# alone: its timestamp is what every object depends on, and nothing
# about the symbols changed. Only the header that is gone is written,
# since a new `id.h` recompiles every object that includes it.
mkdir_p presym.header_dir
%w[id table].each do |type|
next if File.exist?(presym.send("#{type}_header_path"))
presym.send("write_#{type}_header", presyms)
end
Comment thread
coderabbitai[bot] marked this conversation as resolved.
end
end

# The list is the file of the task above, so Rake runs it only when a
# preprocessed file is newer than the list. The headers are made from the
# list, so a header that is gone needs the task too, with the list as it is.
presym_task.define_singleton_method :needed? do
super() || !presym.headers_exist?
end

# Don't directly write dependency tasks in the "task" arguments.
# The rake system tracks dependencies recursively
# (see Rake::Task#all_prerequisite_tasks and #collect_prerequisites).
Expand Down
Loading