From 5affd5fab801fd747e8f90afec6c196ab40c7f50 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 14 May 2026 13:54:42 +0000 Subject: [PATCH 1/2] Build bundled-gem extensions for docs targets After b5e6e0a4 (Use rbs-integrated RDoc), tool/rdoc-srcdir does require 'rdoc/rdoc' which activates rdoc-7.2.0 and its new add_dependency 'rbs', '>= 4.0.0'. RubyGems then needs rbs's gemspec in .bundle/specifications/ and its C extension built. ext/extmk.rb already handles both via each per-gem Makefile (all -> install -> gemspec copies .bundled.rbs-*.gemspec into specifications/, and the TARGET_SO recipe writes gem.build_complete) -- but only if ext/configure-ext.mk has seen .bundle/gems/ populated when its template's Dir.glob(".bundle/gems/**/extconf.rb") runs. On a clean tree, ext/configure-ext.mk regenerates before prepare-gems extracts anything, so its template glob finds nothing, exts.mk lacks rules for bundled-gem extensions, the rbs C extension never compiles, and RubyGems aborts with "Ignoring rbs-4.0.2 because its extensions are not built." Add prepare-gems as a prereq of ext/configure-ext.mk, scoped via MAKECMDGOALS to docs goals only (rdoc, rdoc:%, html, html-server, rdoc-coverage, undocumented). Plain `make` is untouched, so an offline-fresh-checkout build doesn't reach prepare-gems -> update-gems. Also fix tool/update-deps: with the new dep, `make -p all` now includes rules from inside .bundle/gems//ext//, where make prints relative targets like `bigdecimal.o:` whose curdir is under .bundle/. The existing filter checked the raw target string, missing these; move the check onto `dir + target` so the full path is what's inspected. Bundled gems own their depend files, so skipping them here matches the intent of the original filter. https://claude.ai/code/session_01YRoRyZPew2LtN6u6BX8bzx --- defs/gmake.mk | 15 +++++++++++++++ tool/update-deps | 7 ++++--- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/defs/gmake.mk b/defs/gmake.mk index 0320f9b7d553fb..2e575ed21978d5 100644 --- a/defs/gmake.mk +++ b/defs/gmake.mk @@ -358,6 +358,21 @@ $(srcdir)/gems/%.gem: extract-gems: | $(patsubst %,$(srcdir)/.bundle/gems/%,$(bundled-gems)) extract-gems: | $(call foreach-bundled-gems-rev,bundled-gem-extracted) +# Docs targets call $(RDOC) -> tool/rdoc-srcdir, which loads rdoc/rdoc and +# activates its `add_dependency 'rbs', '>= 4.0.0'`. Activation requires +# the bundled rbs gem to be discoverable and its C extension built. The +# existing per-bundled-gem Makefile generated by ext/extmk.rb does both +# (extension build + copy of .bundled.rbs-*.gemspec into +# .bundle/specifications/), but only if ext/configure-ext.mk has seen +# `.bundle/gems/` populated when its template's +# `Dir.glob(".bundle/gems/**/extconf.rb")` runs. On a clean tree +# prepare-gems may not have run yet, so make the dep explicit for the +# docs goals. Other targets are left alone so a plain `make` doesn't +# reach for prepare-gems -> update-gems (network). +ifneq ($(filter rdoc rdoc:% html html-server rdoc-coverage undocumented,$(MAKECMDGOALS)),) +ext/configure-ext.mk: $(HAVE_BASERUBY:yes=prepare-gems) +endif + $(srcdir)/.bundle/gems/%: $(srcdir)/gems/%.gem | .bundle/gems $(ECHO) Extracting bundle gem $*... $(Q) $(BASERUBY) -C "$(srcdir)" \ diff --git a/tool/update-deps b/tool/update-deps index 2d4a5674be72a7..bfaf1fe0989aaa 100755 --- a/tool/update-deps +++ b/tool/update-deps @@ -328,12 +328,13 @@ def read_make_deps(cwd) next if /libyjit.o\z/ =~ target.to_s # skip YJIT Rust object (no corresponding C source) next if /libzjit.o\z/ =~ target.to_s # skip ZJIT Rust object (no corresponding C source) next if /target\/release\/libruby.o\z/ =~ target.to_s # skip YJIT+ZJIT Rust object (no corresponding C source) - next if /\.bundle\// =~ target.to_s next if /\A\./ =~ target.to_s # skip rules such as ".c.o" #p [curdir, target, deps] dir = curdir || dirstack.last - dependencies[dir + target] ||= [] - dependencies[dir + target] |= deps.map {|dep| dir + dep } + key = dir + target + next if /\.bundle\// =~ key.to_s # bundled gem extensions manage their own depend files + dependencies[key] ||= [] + dependencies[key] |= deps.map {|dep| dir + dep } elsif data_base_end curdir = nil elsif directory_leave From 9aad8a06bd3195dff16c3c49169d9e4cb320d52c Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 14 May 2026 14:00:59 +0000 Subject: [PATCH 2/2] Include aggregate doc/install goals in scoping filter Per @chatgpt-codex-connector review on #4: docs is also reached via \`make docs\` (which routes to srcs-doc + \$(DOCTARGETS)) and via \`make install INSTALLDOC=all\` (do-install-all has docs in its prereqs). In those cases MAKECMDGOALS only contains \`docs\` or \`install\`/ \`install-all\`/\`reinstall\`, so the previous filter stayed false and the ordering between prepare-gems and ext/configure-ext.mk regen was not enforced -- a clean-tree parallel docs install could still race. Add \`docs install install-all install-doc install-html install-rdoc reinstall\` to the filter. For \`make install INSTALLDOC=nodoc\`, prepare-gems was already pulled in transitively via pre-install-gem, so this only adds an ordering constraint, not a new fetch. Verified with \`make -n\` on a clean tree: plain \`make\` does not extract gems; \`make docs\`, \`make install\`, and \`make html\` do. https://claude.ai/code/session_01YRoRyZPew2LtN6u6BX8bzx --- defs/gmake.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/defs/gmake.mk b/defs/gmake.mk index 2e575ed21978d5..a05f5943aa981a 100644 --- a/defs/gmake.mk +++ b/defs/gmake.mk @@ -369,7 +369,7 @@ extract-gems: | $(call foreach-bundled-gems-rev,bundled-gem-extracted) # prepare-gems may not have run yet, so make the dep explicit for the # docs goals. Other targets are left alone so a plain `make` doesn't # reach for prepare-gems -> update-gems (network). -ifneq ($(filter rdoc rdoc:% html html-server rdoc-coverage undocumented,$(MAKECMDGOALS)),) +ifneq ($(filter rdoc rdoc:% html html-server rdoc-coverage undocumented docs install install-all install-doc install-html install-rdoc reinstall,$(MAKECMDGOALS)),) ext/configure-ext.mk: $(HAVE_BASERUBY:yes=prepare-gems) endif