Skip to content

Commit ad2a376

Browse files
committed
mkmf: split try_link0 into separate compile and link steps
When `mkmf.rb` checks for functions via `have_func`, it compiles and links a test program in a single clang invocation. On macOS, passing a source file together with `-lruby.4.1-static` (28MB static archive) to clang in one command triggers a ~1.4s overhead per invocation. Splitting into two steps (compile `.c` to `.o`, then link `.o`) reduces this to ~0.14s — a 10x improvement per check. This dramatically speeds up extension configuration: - `ext/io/console`: 12.1s → 1.8s (6.7x faster) - `ext/openssl`: 8.3s → 3.0s (2.8x faster) - `ext/json`: 6.6s → 1.4s (4.7x faster) - `ext/strscan`: 5.0s → 0.6s (8.3x faster) Overall clean build: 52s → 44s (16% faster)
1 parent 661344b commit ad2a376

1 file changed

Lines changed: 8 additions & 4 deletions

File tree

lib/mkmf.rb

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -606,20 +606,24 @@ def with_werror(opt, opts = nil)
606606

607607
def try_link0(src, opt = "", ldflags: "", **opts, &b) # :nodoc:
608608
exe = CONFTEST+$EXEEXT
609-
cmd = link_command(ldflags, opt)
609+
conf = link_config(ldflags, opt)
610+
conf['src'] = "#{CONFTEST}.#{$OBJEXT}"
611+
ld = RbConfig::expand(TRY_LINK.dup, conf)
610612
if $universal
611613
require 'tmpdir'
612614
Dir.mktmpdir("mkmf_", oldtmpdir = ENV["TMPDIR"]) do |tmpdir|
613615
begin
614616
ENV["TMPDIR"] = tmpdir
615-
try_do(src, cmd, **opts, &b)
617+
try_do(src, cc_command(opt), **opts, &b)
616618
ensure
617619
ENV["TMPDIR"] = oldtmpdir
618620
end
619621
end
620622
else
621-
try_do(src, cmd, **opts, &b)
622-
end and File.executable?(exe) or return nil
623+
try_do(src, cc_command(opt), **opts, &b)
624+
end or return nil
625+
xsystem(ld, **opts) or return nil
626+
return nil unless File.executable?(exe)
623627
exe
624628
ensure
625629
MakeMakefile.rm_rf(*Dir["#{CONFTEST}*"]-[exe])

0 commit comments

Comments
 (0)