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:
-
gdk-reliability - e.g. When a GDK action fails to complete. -
gdk-usability - e.g. Improvements or suggestions around how the GDK functions. -
gdk-performance - e.g. When a GDK action is slow or times out.
Steps to replicate (optional)
- Upgrade to XCode 16.
- 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
sudo rm -rf /Library/Developer/CommandLineTools
- 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