[rubygems/rubygems] Use a constant empty tar header to avoid extra allocations
[ruby.git] / defs / gmake.mk
blobc914b39690d50f572c0446797c36baebaaebf121
1 # -*- mode: makefile-gmake; indent-tabs-mode: t -*-
3 reconfig config.status: export MAKE:=$(MAKE)
4 export BASERUBY:=$(BASERUBY)
5 override gnumake_recursive := $(if $(findstring n,$(firstword $(MFLAGS))),,+)
6 override mflags := $(filter-out -j%,$(MFLAGS))
7 MSPECOPT += $(if $(filter -j%,$(MFLAGS)),-j)
8 nproc = $(subst -j,,$(filter -j%,$(MFLAGS)))
10 ifeq ($(GITHUB_ACTIONS),true)
11 # 93(bright yellow) is copied from .github/workflows/mingw.yml
12 override ACTIONS_GROUP = @echo "::group::\e[93m$(@:yes-%=%)\e[m"
13 override ACTIONS_ENDGROUP = @echo "::endgroup::"
14 endif
16 ifneq ($(filter darwin%,$(target_os)),)
17 INSTRUBY_ENV += SDKROOT=
18 endif
19 INSTRUBY_ARGS += --gnumake
21 ifeq ($(DOT_WAIT),)
22 CHECK_TARGETS := great exam love check test check% test% btest%
23 # expand test targets, and those dependents
24 TEST_TARGETS := $(filter $(CHECK_TARGETS),$(MAKECMDGOALS))
25 TEST_DEPENDS := $(filter-out commit $(TEST_TARGETS),$(MAKECMDGOALS))
26 TEST_TARGETS := $(patsubst great,exam,$(TEST_TARGETS))
27 TEST_DEPENDS := $(filter-out great $(TEST_TARGETS),$(TEST_DEPENDS))
28 TEST_TARGETS := $(patsubst exam,test-bundled-gems test-bundler-parallel check,$(TEST_TARGETS))
29 TEST_TARGETS := $(patsubst check,test-syntax-suggest test-spec test-all test-tool test-short,$(TEST_TARGETS))
30 TEST_TARGETS := $(patsubst test-rubyspec,test-spec,$(TEST_TARGETS))
31 TEST_DEPENDS := $(filter-out exam check test-spec $(TEST_TARGETS),$(TEST_DEPENDS))
32 TEST_TARGETS := $(patsubst love,check,$(TEST_TARGETS))
33 TEST_DEPENDS := $(filter-out love $(TEST_TARGETS),$(TEST_DEPENDS))
34 TEST_TARGETS := $(patsubst test-almost,test-all,$(patsubst check-%,test test-%,$(TEST_TARGETS)))
35 TEST_DEPENDS := $(filter-out test-all $(TEST_TARGETS),$(TEST_DEPENDS))
36 TEST_TARGETS := $(patsubst test,test-short,$(TEST_TARGETS))
37 TEST_DEPENDS := $(filter-out test $(TEST_TARGETS),$(TEST_DEPENDS))
38 TEST_TARGETS := $(patsubst test-short,btest-ruby test-knownbug test-basic,$(TEST_TARGETS))
39 TEST_TARGETS := $(patsubst test-basic,test-basic test-leaked-globals,$(TEST_TARGETS))
40 TEST_TARGETS := $(patsubst test-bundled-gems,test-bundled-gems-run,$(TEST_TARGETS))
41 TEST_TARGETS := $(patsubst test-bundled-gems-run,test-bundled-gems-run $(PREPARE_BUNDLED_GEMS),$(TEST_TARGETS))
42 TEST_TARGETS := $(patsubst test-bundled-gems-prepare,test-bundled-gems-prepare $(PRECHECK_BUNDLED_GEMS) test-bundled-gems-fetch,$(TEST_TARGETS))
43 TEST_TARGETS := $(patsubst test-bundler-parallel,test-bundler-parallel $(PREPARE_BUNDLER),$(TEST_TARGETS))
44 TEST_TARGETS := $(patsubst test-syntax-suggest,test-syntax-suggest $(PREPARE_SYNTAX_SUGGEST),$(TEST_TARGETS))
45 TEST_DEPENDS := $(filter-out test-short $(TEST_TARGETS),$(TEST_DEPENDS))
46 TEST_DEPENDS += $(if $(filter great exam love check,$(MAKECMDGOALS)),all exts)
47 TEST_TARGETS := $(patsubst yes-%,%,$(filter-out no-%,$(TEST_TARGETS)))
48 endif
50 in-srcdir := $(if $(filter-out .,$(srcdir)),$(CHDIR) $(srcdir) &&)
52 ifeq ($(if $(filter all main exts enc trans libencs libenc libtrans \
53 prog program ruby ruby$(EXEEXT) \
54 wprogram rubyw rubyw$(EXEEXT) \
55 miniruby$(EXEEXT) mini,\
56 $(MAKECMDGOALS)),,$(MAKECMDGOALS)),)
57 -include $(SHOWFLAGS)
58 endif
60 ifeq ($(HAVE_BASERUBY):$(HAVE_GIT),yes:yes)
61 override modified := $(shell $(BASERUBY) -C $(srcdir) tool/file2lastrev.rb --modified='%Y %m %d')
62 override RUBY_RELEASE_YEAR := $(word 1,$(modified))
63 override RUBY_RELEASE_MONTH := $(word 2,$(modified))
64 override RUBY_RELEASE_DAY := $(word 3,$(modified))
65 endif
67 ifneq ($(filter universal-%,$(arch)),)
68 define archcmd
69 %.$(1).S: %.c
70 @$$(ECHO) translating $$< with $(2)
71 $$(Q) $$(CC) $$(CFLAGS_NO_ARCH) $(2) $$(XCFLAGS) $$(CPPFLAGS) $$(COUTFLAG)$$@ -S $$<
73 %.S: %.$(1).S
75 %.$(1).i: %.c
76 @$$(ECHO) preprocessing $$< with $(2)
77 $$(Q) $$(CPP) $$(warnflags) $(2) $$(XCFLAGS) $$(CPPFLAGS) $$(COUTFLAG)$$@ -E $$< > $$@
79 %.i: %.$(1).i
80 endef
82 $(foreach arch,$(filter -arch=%,$(subst -arch ,-arch=,$(ARCH_FLAG))),\
83 $(eval $(call archcmd,$(patsubst -arch=%,%,$(value arch)),$(patsubst -arch=%,-arch %,$(value arch)))))
84 endif
86 ifeq ($(DOT_WAIT),)
87 .PHONY: $(addprefix yes-,$(TEST_TARGETS))
89 ifneq ($(filter-out btest%,$(TEST_TARGETS)),)
90 $(addprefix yes-,$(TEST_TARGETS)): $(TEST_DEPENDS)
91 endif
93 ORDERED_TEST_TARGETS := $(filter $(TEST_TARGETS), \
94 btest-ruby test-knownbug test-leaked-globals test-basic \
95 test-testframework test-tool test-ruby test-all \
96 test-spec test-syntax-suggest-prepare test-syntax-suggest \
97 test-bundler-prepare test-bundler test-bundler-parallel \
98 test-bundled-gems-precheck test-bundled-gems-fetch \
99 test-bundled-gems-prepare test-bundled-gems-run \
102 # grep ^yes-test-.*-precheck: template/Makefile.in defs/gmake.mk common.mk
103 test_prechecks := $(filter $(ORDERED_TEST_TARGETS),\
104 test-leaked-globals \
105 test-all \
106 test-spec \
107 test-syntax-suggest \
108 test-bundler \
109 test-bundler-parallel \
110 test-bundled-gems\
112 prev_test := $(subst test-bundler-parallel,test-bundler,$(test_prechecks))
113 prev_test := $(addsuffix -precheck,$(prev_test))
114 first_test_prechecks := $(prev_test)
116 $(foreach test,$(ORDERED_TEST_TARGETS), \
117 $(eval yes-$(value test): $(addprefix yes-,$(value prev_test))); \
118 $(eval no-$(value test): $(addprefix no-,$(value prev_test))); \
119 $(eval prev_test := $(value test)))
120 endif
122 ifneq ($(if $(filter install,$(MAKECMDGOALS)),$(filter uninstall,$(MAKECMDGOALS))),)
123 install-targets := $(filter install uninstall,$(MAKECMDGOALS))
124 $(word 1,$(install-targets)): $(word 0,$(install-targets))
125 endif
127 ifneq ($(filter reinstall,$(MAKECMDGOALS)),)
128 install-prereq: uninstall
129 uninstall sudo-precheck: all $(if $(filter all,$(INSTALLDOC)),docs)
130 endif
132 ifneq ($(filter love,$(MAKECMDGOALS)),)
133 showflags: up
134 sudo-precheck: test yes-test-testframework no-test-testframework
135 install-prereq: sudo-precheck
136 yes-test-all no-test-all: install
137 endif
138 yes-test-bundler-parallel: PARALLELRSPECOPTS += $(if $(nproc),-n$(shell expr $(nproc) + $(nproc) / 2))
140 # Cross reference needs to parse all files at once
141 love install reinstall: RDOCFLAGS = --force-update
143 ifneq ($(if $(filter -flto%,$(CFLAGS)),$(subst darwin,,$(arch)),$(arch)),$(arch))
144 override EXE_LDFLAGS = $(filter-out -g%,$(LDFLAGS))
145 endif
147 $(srcdir)/missing/des_tables.c: $(srcdir)/missing/crypt.c
148 ifeq ($(if $(filter yes,$(CROSS_COMPILING)),,$(CC)),)
149 touch $@
150 else
151 @$(ECHO) building make_des_table
152 $(CC) $(INCFLAGS) $(CPPFLAGS) -DDUMP $(EXE_LDFLAGS) $(XLDFLAGS) $(LIBS) -omake_des_table $(srcdir)/missing/crypt.c
153 @[ -x ./make_des_table ]
154 @$(ECHO) generating $@
155 $(Q) $(MAKEDIRS) $(@D)
156 $(Q) ./make_des_table > $@.new
157 $(Q) mv $@.new $@
158 $(Q) $(RMALL) make_des_table*
159 endif
161 config.status: $(wildcard config.cache)
163 STUBPROGRAM = rubystub$(EXEEXT)
164 IGNOREDPATTERNS = %~ .% %.orig %.rej \#%\#
165 SCRIPTBINDIR := $(if $(EXEEXT),,exec/)
166 SCRIPTPROGRAMS = $(addprefix $(SCRIPTBINDIR),$(addsuffix $(EXEEXT),$(filter-out $(IGNOREDPATTERNS),$(notdir $(wildcard $(srcdir)/bin/*)))))
168 stub: $(STUBPROGRAM)
169 scriptbin: $(SCRIPTPROGRAMS)
170 ifneq ($(STUBPROGRAM),rubystub)
171 rubystub: $(STUBPROGRAM)
172 endif
174 $(SCRIPTPROGRAMS): $(STUBPROGRAM)
176 $(STUBPROGRAM): rubystub.$(OBJEXT) $(LIBRUBY) $(MAINOBJ) $(OBJS) $(EXTOBJS) $(SETUP) $(PREP)
178 rubystub$(EXEEXT):
179 @rm -f $@
180 $(ECHO) linking $@
181 $(Q) $(PURIFY) $(CC) $(EXE_LDFLAGS) $(XLDFLAGS) rubystub.$(OBJEXT) $(EXTOBJS) $(LIBRUBYARG) $(MAINLIBS) $(LIBS) $(EXTLIBS) $(OUTFLAG)$@
182 $(Q) $(POSTLINK)
183 $(if $(STRIP),$(Q) $(STRIP) $@)
185 $(SCRIPTBINDIR)%$(EXEEXT): bin/% $(STUBPROGRAM) \
186 $(if $(SCRIPTBINDIR),$(TIMESTAMPDIR)/.exec.time)
187 $(ECHO) generating $@
188 $(Q) { cat $(STUBPROGRAM); echo; sed -e '1{' -e '/^#!.*ruby/!i\' -e '#!/bin/ruby' -e '}' $<; } > $@
189 $(Q) chmod +x $@
190 $(Q) $(POSTLINK)
192 $(SCRIPTBINDIR):
193 $(Q) mkdir $@
195 .PHONY: commit
196 COMMIT_PREPARE := $(subst :,\:,$(filter-out commit do-commit,$(MAKECMDGOALS))) up
198 commit: pre-commit $(DOT_WAIT) do-commit $(DOT_WAIT) post_commit
199 pre-commit: $(COMMIT_PREPARE)
200 do-commit: $(if $(DOT_WAIT),,pre-commit)
201 @$(BASERUBY) -C "$(srcdir)" -I./tool/lib -rvcs -e 'VCS.detect(".").commit'
202 post-commit: $(if $(DOT_WAIT),,do-commit)
203 +$(Q) \
205 $(in-srcdir) \
206 exec sed -f tool/prereq.status defs/gmake.mk template/Makefile.in common.mk; \
207 } | \
208 $(MAKE) $(mflags) Q=$(Q) ECHO=$(ECHO) \
209 top_srcdir="$(top_srcdir)" srcdir="$(srcdir)" srcs_vpath="" CHDIR="$(CHDIR)" \
210 BOOTSTRAPRUBY="$(BOOTSTRAPRUBY)" BOOTSTRAPRUBY_OPT="$(BOOTSTRAPRUBY_OPT)" \
211 MINIRUBY="$(BASERUBY)" BASERUBY="$(BASERUBY)" HAVE_BASERUBY="$(HAVE_BASERUBY)" \
212 VCSUP="" ENC_MK=.top-enc.mk REVISION_FORCE=PHONY CONFIGURE="$(CONFIGURE)" -f - \
213 update-src srcs all-incs
215 GITHUB_RUBY_URL = https://github.com/ruby/ruby
216 PR =
218 COMMIT_GPG_SIGN = $(shell $(GIT) -C "$(srcdir)" config commit.gpgsign)
219 REMOTE_GITHUB_URL = $(shell $(GIT) -C "$(srcdir)" config remote.github.url)
220 COMMITS_NOTES = commits
222 .PHONY: fetch-github
223 fetch-github:
224 $(call fetch-github,$(PR))
226 define fetch-github
227 $(if $(1),,\
228 echo "usage:"; echo " make $@ PR=1234"; \
229 exit 1; \
231 $(eval REMOTE_GITHUB_URL := $(REMOTE_GITHUB_URL))
232 $(if $(REMOTE_GITHUB_URL),,
233 echo adding $(GITHUB_RUBY_URL) as remote github
234 $(GIT) -C "$(srcdir)" remote add github $(GITHUB_RUBY_URL)
235 $(GIT) -C "$(srcdir)" config --add remote.github.fetch +refs/notes/$(COMMITS_NOTES):refs/notes/$(COMMITS_NOTES)
236 $(eval REMOTE_GITHUB_URL := $(GITHUB_RUBY_URL))
238 $(if $(shell $(GIT) -C "$(srcdir)" rev-parse "github/pull/$(1)/head" -- 2> /dev/null),
239 $(GIT) -C "$(srcdir)" branch -f "gh-$(1)" "github/pull/$(1)/head",
240 $(GIT) -C "$(srcdir)" fetch -f github "pull/$(1)/head:gh-$(1)"
242 endef
244 .PHONY: checkout-github
245 checkout-github: fetch-github
246 $(GIT) -C "$(srcdir)" checkout "gh-$(PR)"
248 .PHONY: update-github
249 update-github: fetch-github
250 $(eval PULL_REQUEST_API := https://api.github.com/repos/ruby/ruby/pulls/$(PR))
251 $(eval PULL_REQUEST_FORK_BRANCH := $(shell \
252 curl -s $(if $(GITHUB_TOKEN),-H "Authorization: bearer $(GITHUB_TOKEN)") $(PULL_REQUEST_API) | \
253 $(BASERUBY) -rjson -e 'JSON.parse(STDIN.read)["head"].tap { |h| print "#{h["repo"]["full_name"]} #{h["ref"]}" }' \
255 $(eval FORK_REPO := $(word 1,$(PULL_REQUEST_FORK_BRANCH)))
256 $(eval PR_BRANCH := $(word 2,$(PULL_REQUEST_FORK_BRANCH)))
258 $(eval GITHUB_UPDATE_WORKTREE := $(shell mktemp -d "$(srcdir)/gh-$(PR)-XXXXXX"))
259 $(GIT) -C "$(srcdir)" worktree add $(notdir $(GITHUB_UPDATE_WORKTREE)) "gh-$(PR)"
260 $(GIT) -C "$(GITHUB_UPDATE_WORKTREE)" merge master --no-edit
261 @$(BASERUBY) -e 'print "Are you sure to push this to PR=$(PR)? [Y/n]: "; exit(gets.chomp != "n")'
262 $(GIT) -C "$(srcdir)" remote add fork-$(PR) git@github.com:$(FORK_REPO).git
263 $(GIT) -C "$(GITHUB_UPDATE_WORKTREE)" push fork-$(PR) gh-$(PR):$(PR_BRANCH)
264 $(GIT) -C "$(srcdir)" remote rm fork-$(PR)
265 $(GIT) -C "$(srcdir)" worktree remove $(notdir $(GITHUB_UPDATE_WORKTREE))
266 $(GIT) -C "$(srcdir)" branch -D gh-$(PR)
268 .PHONY: pull-github
269 pull-github: fetch-github
270 $(call pull-github,$(PR))
272 define pull-github
273 $(eval GITHUB_MERGE_BASE := $(shell $(GIT) -C "$(srcdir)" log -1 --format=format:%H))
274 $(eval GITHUB_MERGE_BRANCH := $(shell $(GIT) -C "$(srcdir)" symbolic-ref --short HEAD))
275 $(eval GITHUB_MERGE_WORKTREE := $(shell mktemp -d "$(srcdir)/gh-$(1)-XXXXXX"))
276 $(GIT) -C "$(srcdir)" worktree prune
277 $(GIT) -C "$(srcdir)" worktree add $(notdir $(GITHUB_MERGE_WORKTREE)) "gh-$(1)"
278 $(GIT) -C "$(GITHUB_MERGE_WORKTREE)" rebase $(GITHUB_MERGE_BRANCH)
279 $(eval COMMIT_GPG_SIGN := $(COMMIT_GPG_SIGN))
280 $(if $(filter true,$(COMMIT_GPG_SIGN)), \
281 $(GIT) -C "$(GITHUB_MERGE_WORKTREE)" rebase --exec "$(GIT) commit --amend --no-edit -S" "$(GITHUB_MERGE_BASE)"; \
283 $(GIT) -C "$(GITHUB_MERGE_WORKTREE)" rebase --exec "$(GIT) notes add --message 'Merged: $(GITHUB_RUBY_URL)/pull/$(1)'" "$(GITHUB_MERGE_BASE)"
284 endef
286 .PHONY: fetch-github-%
287 fetch-github-%:
288 $(call fetch-github,$*)
290 .PHONY: checkout-github-%
291 checkout-github-%: fetch-github-%
292 $(GIT) -C "$(srcdir)" checkout "gh-$*"
294 .PHONY: pr-% pull-github-%
295 pr-% pull-github-%: fetch-github-%
296 $(call pull-github,$*)
298 HELP_EXTRA_TASKS = \
299 " checkout-github: checkout GitHub Pull Request [PR=1234]" \
300 " pull-github: rebase GitHub Pull Request to new worktree [PR=1234]" \
301 " update-github: merge master branch and push it to Pull Request [PR=1234]" \
302 " tags: generate TAGS file" \
305 # 1. squeeze spaces
306 # 2. strip and skip comment/empty lines
307 # 3. "gem x.y.z URL xxxxxx" -> "gem|x.y.z|xxxxxx|URL"
308 # 4. "gem x.y.z URL" -> "gem-x.y.z"
309 bundled-gems := $(shell sed \
310 -e 's/[ ][ ]*/ /g' \
311 -e 's/^ //;/\#/d;s/ *$$//;/^$$/d' \
312 $(if $(filter yes,$(HAVE_GIT)), \
313 -e 's/^\(.*\) \(.*\) \(.*\) \(.*\)/\1|\2|\4|\3/' \
315 -e 's/ /-/;s/ .*//' \
316 $(srcdir)/gems/bundled_gems)
318 bundled-gems-rev := $(filter-out $(subst |,,$(bundled-gems)),$(bundled-gems))
319 bundled-gems := $(filter-out $(bundled-gems-rev),$(bundled-gems))
321 # calls $(1) with name, version, revision, URL
322 foreach-bundled-gems-rev = \
323 $(foreach g,$(bundled-gems-rev),$(call foreach-bundled-gems-rev-0,$(1),$(subst |, ,$(value g))))
324 foreach-bundled-gems-rev-0 = \
325 $(call $(1),$(word 1,$(2)),$(word 2,$(2)),$(word 3,$(2)),$(word 4,$(2)))
326 bundled-gem-gemfile = $(srcdir)/gems/$(1)-$(2).gem
327 bundled-gem-gemspec = $(srcdir)/gems/src/$(1)/$(1).gemspec
328 bundled-gem-extracted = $(srcdir)/.bundle/gems/$(1)-$(2)
329 bundled-gem-revision = $(srcdir)/.bundle/.timestamp/$(1).revision
331 update-gems: | $(patsubst %,$(srcdir)/gems/%.gem,$(bundled-gems))
332 update-gems: | $(call foreach-bundled-gems-rev,bundled-gem-gemfile)
333 update-gems: | $(call foreach-bundled-gems-rev,bundled-gem-gemspec)
335 test-bundler-precheck: | $(srcdir)/.bundle/cache
337 $(srcdir)/.bundle/cache:
338 $(MAKEDIRS) $(@D) $(CACHE_DIR)
339 $(LN_S) ../.downloaded-cache $@
341 $(srcdir)/gems/%.gem:
342 $(ECHO) Downloading bundled gem $*...
343 $(Q) $(BASERUBY) -C "$(srcdir)" \
344 -I./tool -rdownloader \
345 -e 'gem = "$(@F)"' \
346 -e 'old = Dir.glob("gems/"+gem.sub(/-[^-]*$$/, "-*.gem"))' \
347 -e 'Downloader::RubyGems.download(gem, "gems", nil) and' \
348 -e '(old.delete("gems/#{gem}"); !old.empty?) and' \
349 -e 'File.unlink(*old) and' \
350 -e 'FileUtils.rm_rf(old.map{'"|n|"'n.chomp(".gem")})'
352 extract-gems: | $(patsubst %,$(srcdir)/.bundle/gems/%,$(bundled-gems))
353 extract-gems: | $(call foreach-bundled-gems-rev,bundled-gem-extracted)
355 $(srcdir)/.bundle/gems/%: $(srcdir)/gems/%.gem | .bundle/gems
356 $(ECHO) Extracting bundle gem $*...
357 $(Q) $(BASERUBY) -C "$(srcdir)" \
358 -Itool/lib -rbundled_gem \
359 -e 'BundledGem.unpack("gems/$(@F).gem", ".bundle")'
361 $(srcdir)/.bundle/.timestamp:
362 $(MAKEDIRS) $@
364 define build-gem
365 $(srcdir)/gems/src/$(1)/.git: | $(srcdir)/gems/src
366 $(ECHO) Cloning $(4)
367 $(Q) $(GIT) clone $(4) $$(@D)
369 $(bundled-gem-revision): \
370 $(if $(if $(wildcard $$(@)),$(filter $(3),$(shell cat $$(@)))),,PHONY) \
371 | $(srcdir)/.bundle/.timestamp $(srcdir)/gems/src/$(1)/.git
372 $(ECHO) Update $(1) to $(3)
373 $(Q) $(CHDIR) "$(srcdir)/gems/src/$(1)" && \
374 if [ `$(GIT) rev-parse HEAD` != $(3) ]; then \
375 $(GIT) fetch origin $(3) && \
376 $(GIT) checkout --detach $(3) && \
377 :; \
379 echo $(3) | $(IFCHANGE) $$(@) -
381 # The repository of minitest does not include minitest.gemspec because it uses hoe.
382 # This creates a dummy gemspec.
383 $(bundled-gem-gemspec): $(bundled-gem-revision) \
384 | $(srcdir)/gems/src/$(1)/.git
385 $(Q) $(BASERUBY) -I$(tooldir)/lib -rbundled_gem -e 'BundledGem.dummy_gemspec(*ARGV)' $$(@)
387 $(bundled-gem-gemfile): $(bundled-gem-gemspec) $(bundled-gem-revision)
388 $(ECHO) Building $(1)@$(3) to $$(@)
389 $(Q) $(BASERUBY) -C "$(srcdir)" \
390 -Itool/lib -rbundled_gem \
391 -e 'BundledGem.build("gems/src/$(1)/$(1).gemspec", "$(2)", "gems", validation: false)'
393 endef
394 define build-gem-0
395 $(eval $(call build-gem,$(1),$(2),$(3),$(4)))
396 endef
398 $(call foreach-bundled-gems-rev,build-gem-0)
400 $(srcdir)/gems/src:
401 $(MAKEDIRS) $@
403 $(srcdir)/.bundle/gems:
404 $(MAKEDIRS) $@
406 ifneq ($(DOT_WAIT),)
407 up:: $(DOT_WAIT) after-update
408 endif
410 ifneq ($(filter update-bundled_gems refresh-gems,$(MAKECMDGOALS)),)
411 update-gems: update-bundled_gems
412 endif
414 .SECONDARY: update-unicode-files
415 .SECONDARY: update-unicode-auxiliary-files
416 .SECONDARY: update-unicode-ucd-emoji-files
417 .SECONDARY: update-unicode-emoji-files
419 ifneq ($(DOT_WAIT),)
420 .NOTPARALLEL: update-unicode
421 .NOTPARALLEL: update-unicode-files
422 .NOTPARALLEL: update-unicode-auxiliary-files
423 .NOTPARALLEL: update-unicode-ucd-emoji-files
424 .NOTPARALLEL: update-unicode-emoji-files
425 .NOTPARALLEL: $(UNICODE_FILES) $(UNICODE_PROPERTY_FILES)
426 .NOTPARALLEL: $(UNICODE_AUXILIARY_FILES)
427 .NOTPARALLEL: $(UNICODE_UCD_EMOJI_FILES) $(UNICODE_EMOJI_FILES)
428 endif
430 ifeq ($(HAVE_GIT),yes)
431 REVISION_LATEST := $(shell $(CHDIR) $(srcdir) && $(GIT) log -1 --format=%H 2>/dev/null)
432 else
433 REVISION_LATEST := update
434 endif
435 REVISION_IN_HEADER := $(shell sed '/^\#define RUBY_FULL_REVISION "\(.*\)"/!d;s//\1/;q' $(wildcard $(srcdir)/revision.h revision.h) /dev/null 2>/dev/null)
436 ifeq ($(REVISION_IN_HEADER),)
437 REVISION_IN_HEADER := none
438 endif
439 ifneq ($(REVISION_IN_HEADER),$(REVISION_LATEST))
440 $(REVISION_H): PHONY
441 endif
443 include $(top_srcdir)/yjit/yjit.mk
445 # Query on the generated rdoc
447 # $ make rdoc:Integer#+
448 rdoc\:%: PHONY
449 $(Q)$(RUNRUBY) $(srcdir)/libexec/ri --no-standard-docs --doc-dir=$(RDOCOUT) $(patsubst rdoc:%,%,$@)
451 test_%.rb test/%: programs PHONY
452 $(Q)$(exec) $(RUNRUBY) "$(TESTSDIR)/runner.rb" --ruby="$(RUNRUBY)" $(TEST_EXCLUDES) $(TESTOPTS) -- $(patsubst test/%,%,$@)
454 spec/bundler/%: PHONY
455 $(Q)$(exec) $(XRUBY) -C $(srcdir) -Ispec/bundler .bundle/bin/rspec --require spec_helper $(RSPECOPTS) $@
457 spec/bundler: test-bundler-parallel
458 $(Q)$(NULLCMD)
460 # workaround to avoid matching non ruby files with "spec/%/" under GNU make 3.81
461 spec/%_spec.c:
462 $(empty)
463 $(srcdir)/$(RUBYSPEC_CAPIEXT)/rubyspec.h:
464 $(empty)
466 benchmark/%: miniruby$(EXEEXT) update-benchmark-driver PHONY
467 $(Q)$(BASERUBY) -rrubygems -I$(srcdir)/benchmark/lib $(srcdir)/benchmark/benchmark-driver/exe/benchmark-driver \
468 --executables="compare-ruby::$(COMPARE_RUBY) -I$(EXTOUT)/common --disable-gem" \
469 --executables="built-ruby::$(BENCH_RUBY) --disable-gem" \
470 $(srcdir)/$@ $(BENCH_OPTS) $(OPTS)
472 clean-local:: TARGET_SO = $(PROGRAM) $(WPROGRAM) $(LIBRUBY_SO) $(STATIC_RUBY) miniruby goruby
473 clean-local::
474 -$(Q)$(RMALL) $(cleanlibs)
476 clean-srcs-ext::
477 $(Q)$(RM) $(patsubst $(srcdir)/%,%,$(EXT_SRCS))
479 clean-srcs-extra::
480 $(Q)$(RM) $(patsubst $(srcdir)/%,%,$(EXTRA_SRCS))
482 ifneq ($(filter $(VCS),git),)
483 update-src::
484 @$(BASERUBY) $(tooldir)/lib/colorize.rb pass "Latest commit hash = $(shell $(filter-out svn,$(VCS)) -C $(srcdir) rev-parse --short=10 HEAD)"
485 endif
487 # Update dependencies and commit the updates to the current branch.
488 update-deps:
489 $(eval update_deps := $(shell date +update-deps-%Y%m%d))
490 $(eval deps_dir := $(shell mktemp -d)/$(update_deps))
491 $(eval GIT_DIR := $(shell $(GIT) -C $(srcdir) rev-parse --absolute-git-dir))
492 $(GIT) --git-dir=$(GIT_DIR) worktree add $(deps_dir)
493 cp $(tooldir)/config.guess $(tooldir)/config.sub $(deps_dir)/tool
494 [ -f config.status ] && cp config.status $(deps_dir)
495 cd $(deps_dir) && autoconf && \
496 exec ./configure -q -C --enable-load-relative --disable-install-doc --disable-rubygems 'optflags=-O0' 'debugflags=-save-temps=obj -g'
497 $(RUNRUBY) -C $(deps_dir) tool/update-deps --fix
498 $(GIT) -C $(deps_dir) diff --no-ext-diff --ignore-submodules --exit-code || \
499 $(GIT) -C $(deps_dir) commit --all --message='Update dependencies'
500 $(GIT) --git-dir=$(GIT_DIR) worktree remove $(deps_dir)
501 $(RMDIR) $(dir $(deps_dir))
502 $(GIT) --git-dir=$(GIT_DIR) merge --no-edit --ff-only $(update_deps)
503 $(GIT) --git-dir=$(GIT_DIR) branch --delete $(update_deps)
505 # order-only-prerequisites doesn't work for $(RUBYSPEC_CAPIEXT)
506 # because the same named directory exists in the source tree.
507 $(RUBYSPEC_CAPIEXT)/%.$(DLEXT): $(srcdir)/$(RUBYSPEC_CAPIEXT)/%.c $(srcdir)/$(RUBYSPEC_CAPIEXT)/rubyspec.h $(RUBY_H_INCLUDES) $(LIBRUBY)
508 $(ECHO) building $@
509 $(Q) $(MAKEDIRS) $(@D)
510 $(Q) $(DLDSHARED) -L. $(XDLDFLAGS) $(XLDFLAGS) $(LDFLAGS) $(INCFLAGS) $(CPPFLAGS) $(OUTFLAG)$@ $< $(LIBRUBYARG)
511 ifneq ($(POSTLINK),)
512 $(Q) $(POSTLINK)
513 endif
514 $(Q) $(RMALL) $@.*
516 RUBYSPEC_CAPIEXT_SO := $(patsubst %.c,$(RUBYSPEC_CAPIEXT)/%.$(DLEXT),$(notdir $(wildcard $(srcdir)/$(RUBYSPEC_CAPIEXT)/*.c)))
517 rubyspec-capiext: $(RUBYSPEC_CAPIEXT_SO)
518 @ $(NULLCMD)
520 ifeq ($(ENABLE_SHARED),yes)
521 ruby: $(if $(LIBRUBY_SO_UPDATE),$(RUBYSPEC_CAPIEXT_SO))
522 exts: rubyspec-capiext
523 endif
525 spec/%/ spec/%_spec.rb: programs exts PHONY
526 +$(RUNRUBY) -r./$(arch)-fake $(srcdir)/spec/mspec/bin/mspec-run -B $(srcdir)/spec/default.mspec $(SPECOPTS) $(patsubst %,$(srcdir)/%,$@)
528 ruby.pc: $(filter-out ruby.pc,$(ruby_pc))
530 matz: up
531 $(eval OLD := $(MAJOR).$(MINOR).0)
532 $(eval MINOR := $(shell expr $(MINOR) + 1))
533 $(eval NEW := $(MAJOR).$(MINOR).0)
534 $(eval message := Development of $(NEW) started.)
535 $(eval files := include/ruby/version.h include/ruby/internal/abi.h)
536 $(GIT) -C $(srcdir) mv -f NEWS.md doc/NEWS/NEWS-$(OLD).md
537 $(GIT) -C $(srcdir) commit -m "[DOC] Flush NEWS.md"
538 sed -i~ \
539 -e "s/^\(#define RUBY_API_VERSION_MINOR\) .*/\1 $(MINOR)/" \
540 -e "s/^\(#define RUBY_ABI_VERSION\) .*/\1 0/" \
541 $(files:%=$(srcdir)/%)
542 $(GIT) -C $(srcdir) add $(files)
543 $(BASERUBY) -C $(srcdir) -p -00 \
544 -e 'BEGIN {old, new = ARGV.shift(2); STDOUT.reopen("NEWS.md")}' \
545 -e 'case $$.' \
546 -e 'when 1; $$_.sub!(/Ruby \K[0-9.]+/, new)' \
547 -e 'when 2; $$_.sub!(/\*\*\K[0-9.]+(?=\*\*)/, old)' \
548 -e 'end' \
549 -e 'next if /^[\[ *]/ =~ $$_' \
550 -e '$$_.sub!(/\n{2,}\z/, "\n\n")' \
551 $(OLD) $(NEW) doc/NEWS/NEWS-$(OLD).md
552 $(GIT) -C $(srcdir) add NEWS.md
553 $(GIT) -C $(srcdir) commit -m "$(message)"
555 tags:
556 $(MAKE) GIT="$(GIT)" -C "$(srcdir)" -f defs/tags.mk
559 # ripper_srcs makes all sources at once. invoking this target multiple
560 # times in parallel means all sources will be built for the number of
561 # sources times respectively.
562 ifneq ($(DOT_WAIT),)
563 .NOTPARALLEL: ripper_srcs
564 else
565 ripper_src =
566 $(foreach r,$(RIPPER_SRCS),$(eval $(value r): | $(value ripper_src))\
567 $(eval ripper_src := $(value r)))
568 ripper_srcs: $(ripper_src)
569 endif