Project

General

Profile

Actions

Bug #22311

closed

Build crashes on macOS 26 with the macOS 27 SDK because pipe2() and dup3() are unavailable

Bug #22311: Build crashes on macOS 26 with the macOS 27 SDK because pipe2() and dup3() are unavailable

Added by himura467 (Akito Shitara) 7 days ago. Updated 4 days ago.

Status:
Closed
Assignee:
-
Target version:
-
[ruby-core:126678]

Description

Environment

  • macOS 26.6.2
  • Command Line Tools with MacOSX27.0.sdk (default MacOSX.sdk)
  • Apple clang version 21.0.0 (clang-2100.3.34.2)

Steps to reproduce

./autogen.sh
mkdir build && cd build
../configure
make

Result

The build warns about dup3 and pipe2, and then miniruby crashes:

../io.c:389:19: warning: 'dup3' is only available on macOS 27.0 or newer [-Wunguarded-availability-new]
../io.c:432:18: warning: 'pipe2' is only available on macOS 27.0 or newer [-Wunguarded-availability-new]
../io.c:8141:18: warning: 'pipe2' is only available on macOS 27.0 or newer [-Wunguarded-availability-new]
...
make: *** [uncommon.mk:1331: builtin_binary.rbbin] Segmentation fault: 11

Cause

The macOS 27 SDK declares dup3() and pipe2() as available since macOS 27.0.
AC_CHECK_FUNCS links them without including headers, so configure defines HAVE_DUP3 and HAVE_PIPE2.
In io.c, they are weakly linked through the header and are NULL at runtime on macOS 26.

$ nm -m miniruby | grep -E '_(pipe2|dup3) '
                 (undefined) weak external _dup3 (from libSystem)
                 (undefined) weak external _pipe2 (from libSystem)

Notes

Autoconf 2.73 makes AC_CHECK_DECL report "no" for such functions on macOS.

https://github.com/autotools-mirror/autoconf/blob/0a51305fff8847edd3e9da9e538e40c539027aed/NEWS#L125-L126

Updated by nobu (Nobuyoshi Nakada) 7 days ago Actions #1 [ruby-core:126688]

Thank you for the info.

What should/can we do?
Use autoconf 2.73 to make the tarballs?
Or upgrade AC_PREREQ(2.67) to 2.73?

Updated by himura467 (Akito Shitara) 7 days ago Actions #2 [ruby-core:126694]

Using autoconf 2.73 with AC_CHECK_DECL as you suggested would fix it.
However, requiring 2.73 seems difficult for now, since the release tarballs are generated by 2.71, and Ubuntu 24.04/26.04 ship 2.71/2.72.

So I think a runtime check would be more practical, either:

  1. using __builtin_available(macOS 27.0, *), or
  2. checking the weakly linked symbols, as done for utimensat in file.c (b6b9a619) and pthread_threadid_np in thread_pthread.c (45177129).

Ref: https://blog.himura467.com/entry/2026/09/14/062404

Updated by etienne (Étienne Barrié) 7 days ago 1Actions #3 [ruby-core:126696]

For already released tarballs, I just want to mention for people out there looking for a solution, that the easiest way I found to get a working build is to use SDKROOT.

Tarball:

./configure SDKROOT=/Library/Developer/CommandLineTools/SDKs/MacOSX26.sdk

ruby-build:

ruby-build 4.0.6 ~/.ruby/ruby-4.0.6 -- SDKROOT=/Library/Developer/CommandLineTools/SDKs/MacOSX26.sdk

ruby-install:

ruby-install 4.0.6 -- SDKROOT=/Library/Developer/CommandLineTools/SDKs/MacOSX26.sdk

Updated by nobu (Nobuyoshi Nakada) 6 days ago Actions #4

  • Status changed from Open to Closed

Applied in changeset git|6bfde8d2a239a9e8549de1ae29acecdefdfb8086.


[Bug #22311] Check the availability of APIs added in macOS 27

To account for cases where binaries for older OS versions are built
using the new SDK, check at runtime whether the API functions are
available actually.

Updated by hsbt (Hiroshi SHIBATA) 5 days ago Actions #5 [ruby-core:126732]

The same report came to ruby-build as https://github.com/rbenv/ruby-build/issues/2640, and I worked it around there in https://github.com/rbenv/ruby-build/pull/2641. When the build host is older than macOS 27, ruby-build now exports ac_cv_func_dup3=no and ac_cv_func_pipe2=no before running configure. Neither function is callable at runtime on such a host whatever SDK is installed, so this only restores what the macOS 26 SDK used to produce.

The same two cache variables are enough when building a released tarball by hand.

ac_cv_func_dup3=no ac_cv_func_pipe2=no ./configure

Unlike SDKROOT, this needs no older SDK on the machine. A fresh Command Line Tools 27 install ships only MacOSX.sdk, which is 27.

In case a backport is considered, 6bfde8d2a239a9e8549de1ae29acecdefdfb8086 applies cleanly to v4.0.7 and v3_4_10. On v3_3_12 only the last hunk fails, and it is unnecessary there because ruby_popen_writer already goes through rb_cloexec_pipe.

Updated by hsbt (Hiroshi SHIBATA) 5 days ago Actions #6

  • Backport changed from 3.3: UNKNOWN, 3.4: UNKNOWN, 4.0: UNKNOWN to 3.3: REQUIRED, 3.4: REQUIRED, 4.0: REQUIRED

Updated by hsbt (Hiroshi SHIBATA) 4 days ago Actions #7 [ruby-core:126749]

  • Backport changed from 3.3: REQUIRED, 3.4: REQUIRED, 4.0: REQUIRED to 3.3: DONE, 3.4: DONE, 4.0: DONE
Actions

Also available in: PDF Atom