Skip to content

mkmf: Stabilize temporary filenames#16734

Draft
gemmaro wants to merge 1 commit intoruby:masterfrom
gemmaro:mkmf/deterministic
Draft

mkmf: Stabilize temporary filenames#16734
gemmaro wants to merge 1 commit intoruby:masterfrom
gemmaro:mkmf/deterministic

Conversation

@gemmaro
Copy link
Copy Markdown
Contributor

@gemmaro gemmaro commented Apr 13, 2026

Hello,

This closes mkmf generates a non-deterministic log file.
Related pull request and issue: ruby/rubygems#2481 and ruby/rubygems#6259

Thank you,


TODO to remove draft mark:

Details
  • draft patch
From 85f034594e93ef4186ad8ec99d7d7ba5fd1759d4 Mon Sep 17 00:00:00 2001
From: gemmaro <gemmaro.dev@gmail.com>
Date: Mon, 13 Apr 2026 14:15:14 +0900
Subject: [PATCH] mkmf: Stabilize temporary filenames

---
 lib/mkmf.rb           | 12 ++++++++++++
 test/mkmf/test_log.rb | 18 ++++++++++++++++++
 2 files changed, 30 insertions(+)
 create mode 100644 test/mkmf/test_log.rb

diff --git a/lib/mkmf.rb b/lib/mkmf.rb
index 37ee4a70d9..e9cf1d7149 100644
--- a/lib/mkmf.rb
+++ b/lib/mkmf.rb
@@ -515,6 +515,17 @@ def create_tmpsrc(src)
 
   # :stopdoc:
 
+  # Try to stabilize temporary filenames as far as compilers (such as
+  # GCC or Clang) support it.  Without this, object files generated
+  # from conftest.c during feature checks may have randomized names
+  # (e.g. /tmp/ccXXXXXX.o), making the content of mkmf.log
+  # non-deterministic.
+  def stabilize_filenames
+    defined? @stabilized_filenames and return
+    @stabilized_filenames = true
+    append_cflags('-save-temps')
+  end
+
   def have_devel?
     unless defined? $have_devel
       $have_devel = true
@@ -524,6 +535,7 @@ def have_devel?
   end
 
   def try_do(src, command, **opts, &b)
+    stabilize_filenames
     unless have_devel?
       raise <<MSG
 The compiler failed to generate an executable file.
diff --git a/test/mkmf/test_log.rb b/test/mkmf/test_log.rb
new file mode 100644
index 0000000000..2030e583d1
--- /dev/null
+++ b/test/mkmf/test_log.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: false
+require_relative 'base'
+
+class TestMkmfLog < TestMkmf
+  def test_mkmf_log_is_deterministic
+    %w[gcc clang].include?(RbConfig::MAKEFILE_CONFIG["CC"]) \
+      or omit 'Only supported with GCC or Clang'
+
+    have_func('non_existent_function')
+    have_func('non_existent_function')
+
+    # deterministic: ld: conftest.o: in function `t':
+    # non-deterministic: ld: /path/to/ccXXXXXX.o: in function `t':
+    ld1, ld2 = MKMFLOG[].scan(/^ld: .*?[.]o: in function `t':/)
+
+    assert_equal ld1, ld2
+  end
+end
-- 
2.52.0
  • omnibus compilation number 5 C99

      compiling /github/workspace/src/ext/-test-/RUBY_ALIGNOF/cpp.cpp
    c.i:1:5: error: this style of line directive is a GNU extension [-Werror,-Wgnu-line-marker]
        1 | # 1 "/github/workspace/src/ext/-test-/RUBY_ALIGNOF/c.c"
          |     ^
    /github/workspace/src/ext/-test-/RUBY_ALIGNOF/c.c:1:5: error: this style of line directive is a GNU extension [-Werror,-Wgnu-line-marker]
        1 | # 1 "<built-in>" 1
          |     ^
    /github/workspace/src/ext/-test-/RUBY_ALIGNOF/c.c:1:5: error: this style of line directive is a GNU extension [-Werror,-Wgnu-line-marker]
        1 | # 1 "/github/workspace/src/include/ruby.h" 1
          |     ^
    In file included from /github/workspace/src/ext/-test-/RUBY_ALIGNOF/c.c:1:
    /github/workspace/src/include/ruby.h:1:6: error: this style of line directive is a GNU extension [-Werror,-Wgnu-line-marker]
        1 | # 38 "/github/workspace/src/include/ruby.h"
          |      ^
    /github/workspace/src/include/ruby.h:38:5: error: this style of line directive is a GNU extension [-Werror,-Wgnu-line-marker]
       38 | # 1 "/github/workspace/src/include/ruby/ruby.h" 1
          |     ^
    In file included from /github/workspace/src/ext/-test-/RUBY_ALIGNOF/c.c:1:
    In file included from /github/workspace/src/include/ruby.h:38:
    /github/workspace/src/include/ruby/ruby.h:1:6: error: this style of line directive is a GNU extension [-Werror,-Wgnu-line-marker]
        1 | # 15 "/github/workspace/src/include/ruby/ruby.h"
          |      ^
    /github/workspace/src/include/ruby/ruby.h:15:5: error: this style of line directive is a GNU extension [-Werror,-Wgnu-line-marker]
       15 | # 1 "/github/workspace/src/include/ruby/internal/config.h" 1
          |     ^
    In file included from /github/workspace/src/ext/-test-/RUBY_ALIGNOF/c.c:1:
    In file included from /github/workspace/src/include/ruby.h:38:
    In file included from /github/workspace/src/include/ruby/ruby.h:15:
    /github/workspace/src/include/ruby/internal/config.h:1:6: error: this style of line directive is a GNU extension [-Werror,-Wgnu-line-marker]
        1 | # 22 "/github/workspace/src/include/ruby/internal/config.h"
          |      ^
    /github/workspace/src/include/ruby/internal/config.h:22:5: error: this style of line directive is a GNU extension [-Werror,-Wgnu-line-marker]
       22 | # 1 "../../../.ext/include/x86_64-linux/ruby/config.h" 1
          |     ^
    In file included from /github/workspace/src/ext/-test-/RUBY_ALIGNOF/c.c:1:
    In file included from /github/workspace/src/include/ruby.h:38:
    In file included from /github/workspace/src/include/ruby/ruby.h:15:
    In file included from /github/workspace/src/include/ruby/internal/config.h:22:
    ../../../.ext/include/x86_64-linux/ruby/config.h:1:6: error: this style of line directive is a GNU extension [-Werror,-Wgnu-line-marker]
        1 | # 23 "/github/workspace/src/include/ruby/internal/config.h" 2
          |      ^
    In file included from /github/workspace/src/ext/-test-/RUBY_ALIGNOF/c.c:1:
    In file included from /github/workspace/src/include/ruby.h:38:
    In file included from /github/workspace/src/include/ruby/ruby.h:15:
    /github/workspace/src/include/ruby/internal/config.h:25:5: error: this style of line directive is a GNU extension [-Werror,-Wgnu-line-marker]
       25 | # 1 "./extconf.h" 1
          |     ^
    In file included from /github/workspace/src/ext/-test-/RUBY_ALIGNOF/c.c:1:
    In file included from /github/workspace/src/include/ruby.h:38:
    In file included from /github/workspace/src/include/ruby/ruby.h:15:
    In file included from /github/workspace/src/include/ruby/internal/config.h:25:
    ./extconf.h:1:6: error: this style of line directive is a GNU extension [-Werror,-Wgnu-line-marker]
        1 | # 26 "/github/workspace/src/include/ruby/internal/config.h" 2
          |      ^
    In file included from /github/workspace/src/ext/-test-/RUBY_ALIGNOF/c.c:1:
    In file included from /github/workspace/src/include/ruby.h:38:
    In file included from /github/workspace/src/include/ruby/ruby.h:15:
    /github/workspace/src/include/ruby/internal/config.h:28:5: error: this style of line directive is a GNU extension [-Werror,-Wgnu-line-marker]
       28 | # 1 "/github/workspace/src/include/ruby/internal/compiler_since.h" 1
          |     ^
    In file included from /github/workspace/src/ext/-test-/RUBY_ALIGNOF/c.c:1:
    In file included from /github/workspace/src/include/ruby.h:38:
    In file included from /github/workspace/src/include/ruby/ruby.h:15:
    In file included from /github/workspace/src/include/ruby/internal/config.h:28:
    /github/workspace/src/include/ruby/internal/compiler_since.h:1:6: error: this style of line directive is a GNU extension [-Werror,-Wgnu-line-marker]
        1 | # 23 "/github/workspace/src/include/ruby/internal/compiler_since.h"
          |      ^
    /github/workspace/src/include/ruby/internal/compiler_since.h:23:5: error: this style of line directive is a GNU extension [-Werror,-Wgnu-line-marker]
       23 | # 1 "/github/workspace/src/include/ruby/internal/compiler_is.h" 1
          |     ^
    In file included from /github/workspace/src/ext/-test-/RUBY_ALIGNOF/c.c:1:
    In file included from /github/workspace/src/include/ruby.h:38:
    In file included from /github/workspace/src/include/ruby/ruby.h:15:
    In file included from /github/workspace/src/include/ruby/internal/config.h:28:
    In file included from /github/workspace/src/include/ruby/internal/compiler_since.h:23:
    /github/workspace/src/include/ruby/internal/compiler_is.h:1:6: error: this style of line directive is a GNU extension [-Werror,-Wgnu-line-marker]
        1 | # 32 "/github/workspace/src/include/ruby/internal/compiler_is.h"
          |      ^
    /github/workspace/src/include/ruby/internal/compiler_is.h:32:5: error: this style of line directive is a GNU extension [-Werror,-Wgnu-line-marker]
       32 | # 1 "/github/workspace/src/include/ruby/internal/compiler_is/apple.h" 1
          |     ^
    In file included from /github/workspace/src/ext/-test-/RUBY_ALIGNOF/c.c:1:
    In file included from /github/workspace/src/include/ruby.h:38:
    In file included from /github/workspace/src/include/ruby/ruby.h:15:
    In file included from /github/workspace/src/include/ruby/internal/config.h:28:
    In file included from /github/workspace/src/include/ruby/internal/compiler_since.h:23:
    In file included from /github/workspace/src/include/ruby/internal/compiler_is.h:32:
    /github/workspace/src/include/ruby/internal/compiler_is/apple.h:1:6: error: this style of line directive is a GNU extension [-Werror,-Wgnu-line-marker]
        1 | # 33 "/github/workspace/src/include/ruby/internal/compiler_is.h" 2
          |      ^
    In file included from /github/workspace/src/ext/-test-/RUBY_ALIGNOF/c.c:1:
    In file included from /github/workspace/src/include/ruby.h:38:
    In file included from /github/workspace/src/include/ruby/ruby.h:15:
    In file included from /github/workspace/src/include/ruby/internal/config.h:28:
    In file included from /github/workspace/src/include/ruby/internal/compiler_since.h:23:
    /github/workspace/src/include/ruby/internal/compiler_is.h:33:5: error: this style of line directive is a GNU extension [-Werror,-Wgnu-line-marker]
       33 | # 1 "/github/workspace/src/include/ruby/internal/compiler_is/clang.h" 1
          |     ^
    fatal error: too many errors emitted, stopping now [-ferror-limit=]
    linking shared-object -test-/arith_seq/beg_len_step.so
    linking shared-object -test-/arith_seq/extract.so
    linking shared-object -test-/array/to_ary_concat.so
    make[2]: Leaving directory '/tmp/tmp.Gm1VrLZN8s/ext/-test-/arith_seq/beg_len_step'
    make[2]: Leaving directory '/tmp/tmp.Gm1VrLZN8s/ext/-test-/arith_seq/extract'
    make[2]: Entering directory '/tmp/tmp.Gm1VrLZN8s/ext/-test-/array/resize'
    compiling /github/workspace/src/ext/-test-/array/resize/resize.c
    make[2]: Entering directory '/tmp/tmp.Gm1VrLZN8s/ext/-test-/bignum'
    compiling /github/workspace/src/ext/-test-/bignum/big2str.c
    20 errors generated.
    make[2]: *** [Makefile:257: c.o] Error 1
    

Memo 1: Adding empty commit passes CI, so the patch I added surely causes CI failing.
Memo 2: Targeting only GCC (excluding Clang) doesn't mitigate the issue -- in the contrary, it fails more.

@gemmaro gemmaro force-pushed the mkmf/deterministic branch 2 times, most recently from 3034b2b to dd1690d Compare April 14, 2026 12:44
@gemmaro gemmaro marked this pull request as draft April 17, 2026 12:04
@gemmaro gemmaro force-pushed the mkmf/deterministic branch from dd1690d to f8deeb3 Compare May 8, 2026 09:29
@gemmaro gemmaro closed this May 8, 2026
@gemmaro gemmaro force-pushed the mkmf/deterministic branch from f8deeb3 to c9ee9c1 Compare May 8, 2026 09:55
@gemmaro gemmaro reopened this May 8, 2026
@gemmaro gemmaro force-pushed the mkmf/deterministic branch from c3008e7 to 798033e Compare May 8, 2026 11:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant