aboutsummaryrefslogtreecommitdiff
path: root/rakelib
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2026-08-08 12:50:43 +0200
committerEugen Wissner <belka@caraus.de>2026-08-08 12:50:43 +0200
commitae29de96c94e5c582f4424804464cdd29bf2a013 (patch)
tree10936bcf8e4feef83de5f8aed70aab11a1e46668 /rakelib
parenteaf5934f81dcd8ce5705f13b651d7b93ca8c459f (diff)
downloadelna-cpp.tar.gz
Fix GCC 16 compatibility with MacOSHEADcpp
Diffstat (limited to 'rakelib')
-rw-r--r--rakelib/gcc.rake70
1 files changed, 56 insertions, 14 deletions
diff --git a/rakelib/gcc.rake b/rakelib/gcc.rake
index 558c8a2..7b6bf44 100644
--- a/rakelib/gcc.rake
+++ b/rakelib/gcc.rake
@@ -3,11 +3,36 @@
# obtain one at https://mozilla.org/MPL/2.0/. -}
# frozen_string_literal: true
+require 'fileutils'
require 'uri'
require 'net/http'
require 'open3'
require 'pathname'
+# Use Homebrew GCC if available (it uses libstdc++, avoiding
+# macOS-specific libc++ incompatibilities in GCC's own sources).
+class GCCConfiguration
+ attr_reader :target
+
+ def initialize(suffix, target, sysroot_sdk)
+ @suffix = suffix
+ @target = target
+ @sysroot_sdk = sysroot_sdk
+ end
+
+ def cc
+ "gcc#{@suffix}"
+ end
+
+ def cxx
+ "g++#{@suffix}"
+ end
+
+ def configure
+ @sysroot_sdk.nil? ? [] : ["--with-sysroot=#{@sysroot_sdk}"]
+ end
+end
+
def gcc_verbose(gcc_binary)
read, write = IO.pipe
sh({'LC_ALL' => 'C'}, gcc_binary, '--verbose', err: write)
@@ -17,13 +42,21 @@ def gcc_verbose(gcc_binary)
output
end
-def find_build_target
- gcc_verbose(ENV.fetch 'CC', 'gcc')
+def find_build_target(gcc_version)
+ if RUBY_PLATFORM =~ /darwin/
+ suffix = '-' + gcc_version.split('.').first
+ mac_os_sdk = '/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk'
+ else
+ suffix = ''
+ end
+ build_target = gcc_verbose(ENV.fetch 'CC', "gcc#{suffix}")
.lines
.find { |line| line.start_with? 'Target: ' }
.split(' ')
.last
.strip
+
+ GCCConfiguration.new suffix, build_target, mac_os_sdk
end
def download_and_pipe(url, target, command)
@@ -66,11 +99,12 @@ namespace :gcc do
# Dependencies.
GCC_VERSION = "16.1.0"
HOST_GCC = 'build/host/gcc'
+ HOST_INSTALL = Pathname.new 'build/host/install'
GCC_TREE = Pathname.new "build/tools/gcc-#{GCC_VERSION}"
GCC_PATCH = 'https://raw.githubusercontent.com/Homebrew/homebrew-core/refs/heads/main/Patches/gcc/gcc-16.1.0.diff'
directory HOST_GCC
- directory 'build/host/install'
+ directory HOST_INSTALL.to_path
directory 'build/tools'
desc 'Download the bootstrap compiler and its prerequisites'
@@ -81,7 +115,7 @@ namespace :gcc do
download_and_pipe URI.parse(GCC_PATCH), GCC_TREE, ['patch', '-p1']
# GCC 16.1.0 registers 17 languages but CL_PARAMS is at bit 16,
- # which collides with the 17th language class (CL_Rust). Shift
+ # which collides with the 17th language class (CL_Rust). Shift
# every CL_* constant from bit 16 upward by one position.
File.open(GCC_TREE + 'gcc/opts.h', 'r+') do |opts_h|
content = opts_h.read.gsub(/\(1U << (\d+)\)/) do |m|
@@ -116,8 +150,8 @@ namespace :gcc do
end
desc 'Configure the bootstrap compiler'
- task configure: [HOST_GCC, 'build/host/install'] do |t|
- build_target = find_build_target
+ task configure: [HOST_GCC, HOST_INSTALL.to_path] do |t|
+ build_target = find_build_target GCC_VERSION
configure_options = [
"--prefix=#{File.realpath t.prerequisites.last}",
'--enable-languages=c,c++,jit,elna',
@@ -125,14 +159,15 @@ namespace :gcc do
'--disable-multilib',
'--enable-host-shared',
'--with-system-zlib',
- "--target=#{build_target}",
- "--build=#{build_target}",
- "--host=#{build_target}"
+ "--target=#{build_target.target}",
+ "--build=#{build_target.target}",
+ "--host=#{build_target.target}",
+ *build_target.configure
]
- mac_os_sdk = '/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk'
- configure_options << "--with-sysroot=#{mac_os_sdk}" if File.symlink? mac_os_sdk
-
- env = ENV.slice 'CC', 'CXX'
+ env = {
+ 'CC' => ENV['CC'] || build_target.cc,
+ 'CXX' => ENV['CXX'] || build_target.cxx
+ }
env['CFLAGS'] = env['CXXFLAGS'] = '-O0 -g -fPIC -I/opt/homebrew/opt/flex/include'
configure = GCC_TREE.relative_path_from(HOST_GCC) + 'configure'
@@ -163,7 +198,14 @@ namespace :gcc do
.reject do |file|
['/elna1.', '/elna-spec.'].any? { |pattern| file.include? pattern }
end
- sh 'clang-tidy', '-p', compile_db.to_path, '--extra-arg=-w', '--warnings-as-errors=*', *sources
+ build_target = find_build_target GCC_VERSION
+ includes = ['.', build_target.target].collect do |inc|
+ HOST_INSTALL + 'include/c++' + GCC_VERSION + inc
+ end
+
+ sh 'clang-tidy', '-p', compile_db.to_path, '--extra-arg=-w', '--warnings-as-errors=*',
+ *includes.collect { |inc| "--extra-arg=-cxx-isystem#{inc.realpath}" },
+ '--extra-arg=-stdlib=libstdc++', *sources
end
desc 'Build documentation'