Skip to content

Native extensions that need C++ (charlock_holmes, unf_ext, etc.) do not build on XCode 16

Overview

It seems native extensions that need C++ complain with the following error:

fatal error: 'cstdbool' file not found

For example:

block in <main>: checking for icu that compiles with c++20 standard... -------------------- no

DYLD_LIBRARY_PATH=.:/Users/stanhu/.local/share/mise/installs/ruby/3.2.4/lib "clang -I/Users/stanhu/.local/share/mise/installs/ruby/3.2.4/include/ruby-3.2.0/arm64-darwin23 -I/Users/stanhu/.local/share/mise/installs/ruby/3.2.4/include/ruby-3.2.0/ruby/backward -I/Users/stanhu/.local/share/mise/installs/ruby/3.2.4/include/ruby-3.2.0 -I. -I/opt/homebrew/Cellar/icu4c/74.2/include -I/opt/homebrew/Cellar/icu4c/74.2/include -I/opt/homebrew/Cellar/icu4c/74.2/include -I/opt/homebrew/opt/icu4c/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT   -fdeclspec -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wextra-tokens -Wdeprecated-declarations -Wdivision-by-zero -Wdiv-by-zero -Wimplicit-function-declaration -Wimplicit-int -Wmisleading-indentation -Wpointer-arith -Wshorten-64-to-32 -Wwrite-strings -Wold-style-definition -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wunused-variable -Wundef  -fno-common -pipe    -Wall -funroll-loops  -x c++ -std=c++20 -c conftest.c"
In file included from conftest.c:1:
In file included from /Users/stanhu/.local/share/mise/installs/ruby/3.2.4/include/ruby-3.2.0/ruby.h:38:
In file included from /Users/stanhu/.local/share/mise/installs/ruby/3.2.4/include/ruby-3.2.0/ruby/ruby.h:25:
In file included from /Users/stanhu/.local/share/mise/installs/ruby/3.2.4/include/ruby-3.2.0/ruby/defines.h:74:
In file included from /Users/stanhu/.local/share/mise/installs/ruby/3.2.4/include/ruby-3.2.0/ruby/backward/2/bool.h:22:
/Users/stanhu/.local/share/mise/installs/ruby/3.2.4/include/ruby-3.2.0/ruby/internal/stdbool.h:31:12: fatal error: 'cstdbool' file not found
   31 | #  include <cstdbool>
      |            ^~~~~~~~~~
1 error generated.
checked program was:
/* begin */
1: #include "ruby.h"
2:
3: #include <unicode/translit.h>
4: int main() { return 0; }
/* end */
% bundle install
Fetching gem metadata from https://rubygems.org/.......
Installing charlock_holmes 0.7.9 with native extensions
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.

    current directory: /Users/stanhu/.local/share/mise/installs/ruby/3.2.4/lib/ruby/gems/3.2.0/gems/charlock_holmes-0.7.9/ext/charlock_holmes
/Users/stanhu/.local/share/mise/installs/ruby/3.2.4/bin/ruby extconf.rb --enable-static
checking for -licui18n... yes
checking for unicode/ucnv.h... yes
checking for -lz... yes
checking for -licuuc... yes
checking for -licudata... yes
checking for icu that requires explicit C++ version flag... yes
checking for icu that compiles with c++20 standard... no
checking for icu that compiles with c++17 standard... no
checking for icu that compiles with c++11 standard... no
checking for icu that compiles with c++0x standard... no
Cannot compile icu with your compiler: recent versions require C++17 support.
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers.  Check the mkmf.log file for more details.  You may
need configuration options.

Provided configuration options:
	--with-opt-dir
	--without-opt-dir
	--with-opt-include
	--without-opt-include=${opt-dir}/include
	--with-opt-lib
	--without-opt-lib=${opt-dir}/lib
	--with-make-prog
	--without-make-prog
	--srcdir=.
	--curdir
	--ruby=/Users/stanhu/.local/share/mise/installs/ruby/3.2.4/bin/$(RUBY_BASE_NAME)
	--with-icu-dir
	--without-icu-dir
	--with-icu-include
	--without-icu-include=${icu-dir}/include
	--with-icu-lib
	--without-icu-lib=${icu-dir}/lib
	--with-icu-i18n-dir
	--without-icu-i18n-dir
	--with-icu-i18n-include
	--without-icu-i18n-include=${icu-i18n-dir}/include
	--with-icu-i18n-lib
	--without-icu-i18n-lib=${icu-i18n-dir}/lib
	--with-icu-i18n-config
	--without-icu-i18n-config
	--with-pkg-config
	--without-pkg-config
	--with-icu-io-dir
	--without-icu-io-dir
	--with-icu-io-include
	--without-icu-io-include=${icu-io-dir}/include
	--with-icu-io-lib
	--without-icu-io-lib=${icu-io-dir}/lib
	--with-icu-io-config
	--without-icu-io-config
	--with-icu-uc-dir
	--without-icu-uc-dir
	--with-icu-uc-include
	--without-icu-uc-include=${icu-uc-dir}/include
	--with-icu-uc-lib
	--without-icu-uc-lib=${icu-uc-dir}/lib
	--with-icu-uc-config
	--without-icu-uc-config
	--with-icui18n-dir
	--without-icui18n-dir
	--with-icui18n-include
	--without-icui18n-include=${icui18n-dir}/include
	--with-icui18n-lib
	--without-icui18n-lib=${icui18n-dir}/lib
	--with-icui18nlib
	--without-icui18nlib
	--with-unicode-dir
	--without-unicode-dir
	--with-unicode-include
	--without-unicode-include=${unicode-dir}/include
	--with-unicode-lib
	--without-unicode-lib=${unicode-dir}/lib
	--with-z-dir
	--without-z-dir
	--with-z-include
	--without-z-include=${z-dir}/include
	--with-z-lib
	--without-z-lib=${z-dir}/lib
	--with-zlib
	--without-zlib
	--with-icuuc-dir
	--without-icuuc-dir
	--with-icuuc-include
	--without-icuuc-include=${icuuc-dir}/include
	--with-icuuc-lib
	--without-icuuc-lib=${icuuc-dir}/lib
	--with-icuuclib
	--without-icuuclib
	--with-icudata-dir
	--without-icudata-dir
	--with-icudata-include
	--without-icudata-include=${icudata-dir}/include
	--with-icudata-lib
	--without-icudata-lib=${icudata-dir}/lib
	--with-icudatalib
	--without-icudatalib

To see why this extension failed to compile, please check the mkmf.log which can be found here:

  /Users/stanhu/.local/share/mise/installs/ruby/3.2.4/lib/ruby/gems/3.2.0/extensions/arm64-darwin-23/3.2.0/charlock_holmes-0.7.9/mkmf.log

extconf failed, exit code 1

Gem files will remain installed in /Users/stanhu/.local/share/mise/installs/ruby/3.2.4/lib/ruby/gems/3.2.0/gems/charlock_holmes-0.7.9 for inspection.
Results logged to /Users/stanhu/.local/share/mise/installs/ruby/3.2.4/lib/ruby/gems/3.2.0/extensions/arm64-darwin-23/3.2.0/charlock_holmes-0.7.9/gem_make.out

  /Users/stanhu/.local/share/mise/installs/ruby/3.2.4/lib/ruby/3.2.0/rubygems/ext/builder.rb:119:in `run'
  /Users/stanhu/.local/share/mise/installs/ruby/3.2.4/lib/ruby/3.2.0/rubygems/ext/ext_conf_builder.rb:28:in `build'
  /Users/stanhu/.local/share/mise/installs/ruby/3.2.4/lib/ruby/3.2.0/rubygems/ext/builder.rb:187:in `build_extension'
  /Users/stanhu/.local/share/mise/installs/ruby/3.2.4/lib/ruby/3.2.0/rubygems/ext/builder.rb:221:in `block in build_extensions'
  /Users/stanhu/.local/share/mise/installs/ruby/3.2.4/lib/ruby/3.2.0/rubygems/ext/builder.rb:218:in `each'
  /Users/stanhu/.local/share/mise/installs/ruby/3.2.4/lib/ruby/3.2.0/rubygems/ext/builder.rb:218:in `build_extensions'
  /Users/stanhu/.local/share/mise/installs/ruby/3.2.4/lib/ruby/3.2.0/rubygems/installer.rb:846:in `build_extensions'
  /Users/stanhu/.local/share/mise/installs/ruby/3.2.4/lib/ruby/gems/3.2.0/gems/bundler-2.5.11/lib/bundler/rubygems_gem_installer.rb:76:in `build_extensions'
  /Users/stanhu/.local/share/mise/installs/ruby/3.2.4/lib/ruby/gems/3.2.0/gems/bundler-2.5.11/lib/bundler/rubygems_gem_installer.rb:28:in `install'
  /Users/stanhu/.local/share/mise/installs/ruby/3.2.4/lib/ruby/gems/3.2.0/gems/bundler-2.5.11/lib/bundler/source/rubygems.rb:206:in `install'
  /Users/stanhu/.local/share/mise/installs/ruby/3.2.4/lib/ruby/gems/3.2.0/gems/bundler-2.5.11/lib/bundler/installer/gem_installer.rb:54:in `install'
  /Users/stanhu/.local/share/mise/installs/ruby/3.2.4/lib/ruby/gems/3.2.0/gems/bundler-2.5.11/lib/bundler/installer/gem_installer.rb:16:in `install_from_spec'
  /Users/stanhu/.local/share/mise/installs/ruby/3.2.4/lib/ruby/gems/3.2.0/gems/bundler-2.5.11/lib/bundler/installer/parallel_installer.rb:132:in `do_install'
  /Users/stanhu/.local/share/mise/installs/ruby/3.2.4/lib/ruby/gems/3.2.0/gems/bundler-2.5.11/lib/bundler/installer/parallel_installer.rb:123:in `block in worker_pool'
  /Users/stanhu/.local/share/mise/installs/ruby/3.2.4/lib/ruby/gems/3.2.0/gems/bundler-2.5.11/lib/bundler/worker.rb:62:in `apply_func'
  /Users/stanhu/.local/share/mise/installs/ruby/3.2.4/lib/ruby/gems/3.2.0/gems/bundler-2.5.11/lib/bundler/worker.rb:57:in `block in process_queue'
  /Users/stanhu/.local/share/mise/installs/ruby/3.2.4/lib/ruby/gems/3.2.0/gems/bundler-2.5.11/lib/bundler/worker.rb:54:in `loop'
  /Users/stanhu/.local/share/mise/installs/ruby/3.2.4/lib/ruby/gems/3.2.0/gems/bundler-2.5.11/lib/bundler/worker.rb:54:in `process_queue'
  /Users/stanhu/.local/share/mise/installs/ruby/3.2.4/lib/ruby/gems/3.2.0/gems/bundler-2.5.11/lib/bundler/worker.rb:90:in `block (2 levels) in create_threads'

An error occurred while installing charlock_holmes (0.7.9), and Bundler cannot continue.

In Gemfile:
  charlock_holmes

Impacted categories

The following categories relate to this issue:

Steps to replicate (optional)

  1. Upgrade to XCode 16.
  2. Run bundle pristine charlock_holmes

I can reproduce this issue with this simple test file:

#include <cstdbool>

int main() { }
% clang++ test.cc
test.cc:1:10: fatal error: 'cstdbool' file not found
    1 | #include <cstdbool>
      |          ^~~~~~~~~~
1 error generated.

I can see the cstdbool does exist:

% find /Library/Developer/CommandLineTools/SDKs | grep cstdbool
/Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk/usr/include/c++/v1/cstdbool
/Library/Developer/CommandLineTools/SDKs/MacOSX13.1.sdk/usr/include/c++/v1/cstdbool
/Library/Developer/CommandLineTools/SDKs/MacOSX14.5.sdk/usr/include/c++/v1/cstdbool
/Library/Developer/CommandLineTools/SDKs/MacOSX12.3.sdk/usr/include/c++/v1/cstdbool

If I manually add this path, it works:

% clang++ -I/Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk/usr/include/c++/v1 test.cc
%

https://stackoverflow.com/a/77975811/1992201 seems relevant. /Library/Developer/CommandLineTools/usr/include/c++/v1 points to an old directory:

% xcode-select -p
/Library/Developer/CommandLineTools
% ls -al /Library/Developer/CommandLineTools/usr/include/c++/v1
total 24
drwxr-xr-x  13 root  wheel   416 Sep 21  2023 .
drwxr-xr-x   3 root  wheel    96 Oct 18  2022 ..
drwxr-xr-x   3 root  wheel    96 Oct 18  2022 __bit
drwxr-xr-x   5 root  wheel   160 Oct 18  2022 __charconv
drwxr-xr-x   9 root  wheel   288 Oct 18  2022 __compare
drwxr-xr-x  24 root  wheel   768 Oct 18  2022 __concepts
-rw-r--r--   1 root  wheel  3142 Oct 18  2022 __cxxabi_config.h
drwxr-xr-x  14 root  wheel   448 Sep 21  2023 __format
drwxr-xr-x   4 root  wheel   128 Sep 21  2023 __functional
drwxr-xr-x   3 root  wheel    96 Sep 21  2023 __iterator
drwxr-xr-x   9 root  wheel   288 Sep 21  2023 __ranges
drwxr-xr-x   3 root  wheel    96 Sep 21  2023 __utility
-rw-r--r--   1 root  wheel  7215 Oct 18  2022 cxxabi.h

Workaround

  1. sudo rm -rf /Library/Developer/CommandLineTools
  2. Install the XCode Command-Line Tools 16 from https://download.developer.apple.com/Developer_Tools/Command_Line_Tools_for_Xcode_16/Command_Line_Tools_for_Xcode_16.dmg

Environment (optional)

  • Operating system name: <!-- output of `uname -a` command -->
  • Architecture: <!-- output of `arch` command -->
  • The contents of your gdk.yml (if any)
  • Ruby version: <!-- output of `ruby --version` command -->
  • GDK version: <!-- output of `git rev-parse --short HEAD` command -->
Edited by Stan Hu