cppc = meson.get_compiler('cpp') fs = import('fs') # --- minimum supported versions ------------------------------------------ gridfire_gcc_min = '14.0' # g++ gridfire_clang_min = '17.0' # upstream LLVM clang++ gridfire_appleclang_min = '16.0' # Apple clang (Xcode 16 toolchain) # --- identify the active toolchain ---------------------------------------- compiler_id = cppc.get_id() compiler_version = cppc.version() is_apple_clang = false if compiler_id == 'clang' and cppc.get_define('__apple_build_version__') != '' is_apple_clang = true endif if is_apple_clang toolchain_desc = 'Apple clang (Xcode) ' + compiler_version required_min = gridfire_appleclang_min elif compiler_id == 'clang' toolchain_desc = 'LLVM clang ' + compiler_version required_min = gridfire_clang_min elif compiler_id == 'gcc' toolchain_desc = 'GCC ' + compiler_version required_min = gridfire_gcc_min else toolchain_desc = compiler_id + ' ' + compiler_version required_min = '' warning('GridFire is developed and tested with GCC and Clang; compiler "' + compiler_id + '" is untested. Proceeding, but the capability ' + 'checks below must pass.') endif message('C++ toolchain: ' + toolchain_desc) message('C++ standard set to: ' + get_option('cpp_std')) # --- per-compiler warning tweaks (unchanged behavior) ---------------------- if compiler_id == 'clang' message('disabling bitwise-instead-of-logical warnings for clang') add_project_arguments('-Wno-bitwise-instead-of-logical', language: 'cpp') endif if compiler_id == 'gcc' message('disabling psabi warnings for gcc') add_project_arguments('-Wno-psabi', language: 'cpp') endif # --- functional capability probes (authoritative) -------------------------- have_print_hdr = cppc.has_header('print') have_format_hdr = cppc.has_header('format') println_works = cppc.compiles( '''#include #include int main() { std::println("gridfire toolchain probe {}", 23); }''', args: ['-std=c++23'], name: 'std::println usable at -std=c++23', ) toolchain_functional = have_print_hdr and have_format_hdr and println_works version_sufficient = required_min == '' ? true : compiler_version.version_compare('>=' + required_min) # --- failure analysis and reporting ---------------------------------------- if toolchain_functional and not version_sufficient # Works in practice; don't break a functioning setup over a number. warning(toolchain_desc + ' is below the minimum GridFire tests against (' + required_min + '), but all C++23 capability probes passed. ' + 'Proceeding; if you hit compiler errors deep in the build, ' + 'upgrade your toolchain before reporting a bug.') endif if not toolchain_functional # 1) Name the failure precisely. failure_detail = '' if not have_print_hdr failure_detail += '\n * C++ standard library header not found.' endif if not have_format_hdr failure_detail += '\n * C++ standard library header not found.' endif if have_print_hdr and have_format_hdr and not println_works failure_detail += '\n * Headers exist but std::println failed to compile at -std=c++23 (incomplete library support).' endif if not version_sufficient failure_detail += '\n * ' + toolchain_desc + ' is below the required minimum (' + required_min + ').' elif compiler_id == 'clang' and not is_apple_clang # New-enough clang but probes failed: almost always the C++ stdlib # underneath it, not clang itself. failure_detail += ('\n * clang itself is new enough; on Linux clang uses the system ' + 'libstdc++, so the GNU C++ runtime is likely too old. Install GCC >= ' + gridfire_gcc_min + ' (clang will pick up its libstdc++), or use -Dcpp_args=-stdlib=libc++ with libc++ >= 17 installed.') endif # 2) Search for a suitable already-installed alternate. candidate_names = [] if compiler_id == 'gcc' candidate_names += ['g++-16', 'g++-15', 'g++-14', 'clang++-21', 'clang++-20', 'clang++-19', 'clang++-18', 'clang++-17'] else candidate_names += ['clang++-21', 'clang++-20', 'clang++-19', 'clang++-18', 'clang++-17', 'g++-16', 'g++-15', 'g++-14'] endif if host_machine.system() == 'darwin' candidate_names += [ '/opt/homebrew/opt/llvm/bin/clang++', '/usr/local/opt/llvm/bin/clang++', ] endif suitable_cxx = '' candidates_report = '' foreach cand : candidate_names p = find_program(cand, required: false) if p.found() cand_ver = p.version() # Decide the applicable minimum from the candidate's family. cand_min = cand.contains('clang') ? gridfire_clang_min : gridfire_gcc_min if cand_ver != 'unknown' and cand_ver.version_compare('>=' + cand_min) candidates_report += '\n [OK] ' + p.full_path() + ' (version ' + cand_ver + ')' if suitable_cxx == '' suitable_cxx = p.full_path() endif else candidates_report += '\n [too old] ' + p.full_path() + ' (version ' + cand_ver + ')' endif endif endforeach # 3) OS-specific install guidance. os_help = '' if host_machine.system() == 'darwin' os_help = ''' How to get a suitable compiler on macOS: * Apple clang: update Xcode / Command Line Tools to Xcode 16 or newer softwareupdate --list (or install from developer.apple.com) * Homebrew LLVM: brew install llvm -> /opt/homebrew/opt/llvm/bin/clang++ * Homebrew GCC: brew install gcc -> g++-14 (or newer) on your PATH''' elif host_machine.system() == 'linux' distro_hint = '' if fs.exists('/etc/os-release') os_release = fs.read('/etc/os-release') if os_release.contains('ubuntu') or os_release.contains('debian') distro_hint = ''' Detected Debian/Ubuntu: sudo apt install g++-14 (or newer) sudo apt install clang-18 libstdc++-14-dev (clang needs a modern libstdc++ too)''' elif os_release.contains('fedora') or os_release.contains('rhel') or os_release.contains('centos') distro_hint = ''' Detected Fedora/RHEL family: sudo dnf install gcc-c++ (Fedora 40+ ships GCC 14) sudo dnf install clang''' elif os_release.contains('arch') distro_hint = ''' Detected Arch: sudo pacman -S gcc clang (both current in the repos)''' endif endif os_help = ''' How to get a suitable compiler on Linux:''' + distro_hint + ''' Generic: install GCC >= ''' + gridfire_gcc_min + ''' or LLVM clang >= ''' + gridfire_clang_min + ''' from your package manager; many distros package versioned binaries (g++-14, clang++-18).''' else os_help = '\nInstall GCC >= ' + gridfire_gcc_min + ' or LLVM clang >= ' + gridfire_clang_min + ' for your platform.' endif # 4) Assemble the verdict. if suitable_cxx != '' action = ('\nA suitable compiler IS already installed. Meson cannot switch compilers ' + 'after configuration starts, so re-run setup pointing at it:\n\n' + ' CXX=' + suitable_cxx + ' meson setup --wipe \n') else action = ('\nNo suitable alternate compiler was found on this system.\n' + os_help + '\n\n' + 'After installing one, configure with:\n\n' + ' CXX= meson setup --wipe \n') endif scanned = candidates_report == '' ? '\n (none of the common versioned compiler names were found on PATH)' : candidates_report error('GridFire requires a C++23 toolchain (GCC >= ' + gridfire_gcc_min + ', LLVM clang >= ' + gridfire_clang_min + ', or Apple clang >= ' + gridfire_appleclang_min + ').\n' + 'Active compiler: ' + toolchain_desc + '\n' + '\nProblems detected:' + failure_detail + '\n' + '\nAlternate compilers scanned:' + scanned + '\n' + action) endif # --- everything below unchanged from the original check --------------------- # For Eigen add_project_arguments('-Wno-deprecated-declarations', language: 'cpp') if get_option('build_python') message('enabling hidden visibility for C++ symbols when building Python extension. This reduces the size of the resulting shared library.') add_project_arguments('-fvisibility=hidden', language: 'cpp') else message('enabling default visibility for C++ symbols') add_project_arguments('-fvisibility=default', language: 'cpp') endif if get_option('openmp_support') gridfire_args += ['-DGF_USE_OPENMP'] endif if get_option('asan') and get_option('buildtype') != 'debug' and get_option('buildtype') != 'debugoptimized' error('AddressSanitizer (ASan) can only be enabled for debug or debugoptimized builds') endif if get_option('asan') and (get_option('buildtype') == 'debugoptimized' or get_option('buildtype') == 'debug') message('enabling AddressSanitizer (ASan) support') add_project_arguments('-fsanitize=address,undefined', language: 'cpp') add_project_arguments('-fno-omit-frame-pointer', language: 'cpp') add_project_link_arguments('-fsanitize=address,undefined', language: 'cpp') add_project_link_arguments('-fno-omit-frame-pointer', language: 'cpp') endif