Skip to content
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
186 changes: 186 additions & 0 deletions .github/workflows/ResInsightMac.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
name: ResInsight Mac Build

on:
push:
pull_request:
workflow_dispatch:
schedule:
# 02:00 UTC daily, offset from ResInsightWithCache.yml's 01:00 slot
# so the two workflows do not contend for the same Actions runners.
- cron: '0 2 * * *'

permissions:
contents: read

# Cancel a still-running build when a new push lands on the same ref --
# otherwise two simultaneous Mac runs race on the same daily cache keys
# (vcpkg-clang/macOS-..., macOS-appleclang-...-buildcache-v01-<date>,
# macOS-buildcache-tool-v0.33.0) and one reports
# "Failed to save: Unable to reserve cache with key ..., another job may
# be creating this cache." Mirrors the pattern in ResInsightWithCache.yml.
concurrency:
group: mac-build-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

jobs:
build:
runs-on: macos-latest
env:
BUILD_TYPE: Release
VCPKG_BINARY_SOURCES: "clear;x-gha,readwrite"
BUILDCACHE_DIR: ${{ github.workspace }}/buildcache_dir
BUILDCACHE_ACCURACY: SLOPPY

steps:
- name: Checkout
uses: actions/checkout@v6
with:
submodules: true

- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.12"

- name: Display Python version
run: python -c "import sys; print(sys.version)"

- name: Get Python executable path
id: python-path
run: echo "PYTHON_EXECUTABLE=$(python -c 'import sys; import pathlib; print(pathlib.PurePath(sys.executable).as_posix())')" >> $GITHUB_OUTPUT

- name: Install dependencies
run: |
python -m pip install --upgrade pip
# rips/_version.py is normally generated by CMake; create a dev
# fallback so the editable install below can resolve the version.
echo '__version__ = "0.0.0.dev"' > GrpcInterface/Python/rips/_version.py
pip install -e GrpcInterface/Python[dev]

- name: Restore buildcache tool binary
uses: actions/cache@v5
with:
path: ${{ github.workspace }}/buildcache-tool
key: ${{ runner.os }}-buildcache-tool-v0.33.0

- name: Build buildcache from source if needed
# CeetronSolutions/setup-buildcache-action has no macOS support, so
# build the binary from the upstream source release and add it to
# PATH. Source build (~30 s) only happens on cache miss; subsequent
# runs restore the binary from the cache step above.
env:
BUILDCACHE_VERSION: v0.33.0
BUILDCACHE_PREFIX: ${{ github.workspace }}/buildcache-tool
run: |
if [ ! -x "$BUILDCACHE_PREFIX/bin/buildcache" ]; then
workdir="$RUNNER_TEMP/buildcache-src"
mkdir -p "$workdir" "$BUILDCACHE_PREFIX"
cd "$workdir"
curl -sSL "https://gitlab.com/bits-n-bites/buildcache/-/archive/${BUILDCACHE_VERSION}/buildcache-${BUILDCACHE_VERSION}.tar.gz" \
| tar xz --strip-components=1
cmake -S src -B build -G Ninja \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX="$BUILDCACHE_PREFIX"
cmake --build build --target install
fi
echo "$BUILDCACHE_PREFIX/bin" >> "$GITHUB_PATH"
"$BUILDCACHE_PREFIX/bin/buildcache" --version

- name: Get current date
id: current-time
shell: bash
run: echo "formattedTime=$(date -u +%Y-%m-%d)" >> $GITHUB_OUTPUT

- name: Cache buildcache contents
id: cache-buildcache
uses: actions/cache@v5
with:
path: ${{ env.BUILDCACHE_DIR }}
key: ${{ runner.os }}-appleclang-6.7.0-buildcache-v01-${{ steps.current-time.outputs.formattedTime }}
restore-keys: |
${{ runner.os }}-appleclang-6.7.0-buildcache-v01-

- name: Create folder for buildcache
run: mkdir -p "${{ env.BUILDCACHE_DIR }}"

- name: Install Homebrew build tools
# vcpkg's thrift port (transitive dep of arrow) requires bison > 2.5;
# macOS ships an ancient /usr/bin/bison (2.3). Install Homebrew's
# bison and put it ahead on PATH so the port build finds it.
run: |
brew install bison
echo "$(brew --prefix bison)/bin" >> "$GITHUB_PATH"
"$(brew --prefix bison)/bin/bison" --version | head -1

- name: Install Qt
# cache: false on macOS: the 1.1 GB Qt tarball eats most of the
# 10 GB per-repo Actions cache quota; downloading fresh each run
# is ~30 s on the runner-internal mirror and leaves room for the
# buildcache + vcpkg caches which actually save build time.
uses: CeetronSolutions/install-qt-action@bump-node24
with:
version: 6.7.0
dir: "${{ github.workspace }}/Qt/"
cache: false
setup-python: false
modules: "qtnetworkauth"

- name: vcpkg bootstrap
run: |
ThirdParty/vcpkg/bootstrap-vcpkg.sh

- name: Get vcpkg submodule SHA
id: vcpkg-sha
shell: bash
run: echo "sha=$(git rev-parse HEAD:ThirdParty/vcpkg)" >> $GITHUB_OUTPUT

- name: Restore vcpkg cache
id: vcpkg-cache
uses: CeetronSolutions/vcpkg-cache@copilot/optimize-cache-storage-structure
with:
cache-key: ${{ runner.os }}-clang-${{ steps.vcpkg-sha.outputs.sha }}-${{ hashFiles('vcpkg.json', 'vcpkg-configuration.json') }}
prefix: vcpkg-clang/

- name: Configure
shell: bash
env:
VCPKG_FEATURE_FLAGS: "binarycaching"
VCPKG_BINARY_SOURCES: "clear;files,${{ steps.vcpkg-cache.outputs.path }},readwrite"
run: >
cmake -S . -B cmakebuild
-DVCPKG_BUILD_TYPE=release
-DCMAKE_INSTALL_PREFIX=cmakebuild/install
-DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }}
-DCMAKE_POLICY_VERSION_MINIMUM=3.5
-DCMAKE_C_COMPILER_LAUNCHER=buildcache
-DCMAKE_CXX_COMPILER_LAUNCHER=buildcache
-DRESINSIGHT_INCLUDE_APPLICATION_UNIT_TESTS=true
-DRESINSIGHT_TREAT_WARNINGS_AS_ERRORS=false
-DRESINSIGHT_ENABLE_PRECOMPILED_HEADERS=false
-DRESINSIGHT_ENABLE_UNITY_BUILD=false
-DRESINSIGHT_ENABLE_GRPC=false
-DRESINSIGHT_ENABLE_HDF5=false
-DCMAKE_TOOLCHAIN_FILE=ThirdParty/vcpkg/scripts/buildsystems/vcpkg.cmake
-G Ninja

- name: Build
run: |
cmake --build cmakebuild --target install

- name: Stats for buildcache
run: buildcache -s

- name: Run Unit Tests
shell: bash
run: |
echo "Content of unit test folder"
ls cmakebuild/ResInsight-tests
cmakebuild/ResInsight-tests

- name: Upload artifacts
if: always()
uses: actions/upload-artifact@v7
with:
name: ResInsight-macOS
path: ${{ runner.workspace }}/ResInsight/cmakebuild/install
retention-days: 5
35 changes: 34 additions & 1 deletion ApplicationExeCode/RiaMainTools.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,30 @@

#include <map>
#include <sstream>

// std::stacktrace is C++23; libc++ in Homebrew llvm@19 (and older) does not
// ship it. Without it we skip stack-trace capture in the crash path but
// still log the signal. See #14045.
#if __has_include( <stacktrace> )
Comment thread
magnesj marked this conversation as resolved.
Outdated
#include <stacktrace>
#define RIA_HAS_STD_STACKTRACE 1
#else
#define RIA_HAS_STD_STACKTRACE 0
#endif

#ifndef WIN32
#include <signal.h>
// macOS marks <ucontext.h> as deprecated and the mcontext layout
// (gregs[REG_RIP]) is Linux-only — skip the program-counter capture
// path on Apple platforms. See #14045.
#ifndef __APPLE__
#include <ucontext.h>
#endif
#endif

namespace internal
{
#if RIA_HAS_STD_STACKTRACE
// Custom formatter for stacktrace
std::string formatStacktrace( const std::stacktrace& st )
{
Expand All @@ -55,6 +70,7 @@ std::string formatStacktrace( const std::stacktrace& st )
}
return ss.str();
}
#endif

#ifndef WIN32
static std::string signalCodeDescription( int signo, int siCode )
Expand Down Expand Up @@ -144,7 +160,9 @@ static std::string signalCodeDescription( int signo, int siCode )
//--------------------------------------------------------------------------------------------------
static void performCrashLogging( int signalCode, const std::map<std::string, std::string>& extraAttrs )
{
auto st = std::stacktrace::current();
#if RIA_HAS_STD_STACKTRACE
auto st = std::stacktrace::current();
#endif
auto loggers = RiaLogging::loggerInstances();

for ( auto logger : loggers )
Expand All @@ -161,8 +179,12 @@ static void performCrashLogging( int signalCode, const std::map<std::string, std
fileLogger->error( line.data() );
}

#if RIA_HAS_STD_STACKTRACE
std::string message = "Stack trace:\n" + internal::formatStacktrace( st );
logger->error( message.data() );
#else
logger->error( "Stack trace: not available (compiled without <stacktrace>)" );
#endif

fileLogger->flush();
}
Expand All @@ -171,7 +193,9 @@ static void performCrashLogging( int signalCode, const std::map<std::string, std
auto& otelManager = RiaOpenTelemetryManager::instance();
if ( otelManager.isEnabled() )
{
#if RIA_HAS_STD_STACKTRACE
otelManager.reportCrash( signalCode, st, extraAttrs );
#endif
}
}

Expand Down Expand Up @@ -206,6 +230,12 @@ void manageSegFailureSA( int signalCode, siginfo_t* info, void* ucontext )
}
}

// Program-counter capture relies on the Linux ucontext layout
// (gregs[REG_RIP] for x86_64, mcontext.pc for aarch64). macOS exposes
// a different layout and marks <ucontext.h> as deprecated, so skip it
// there; remaining crash attributes (signal code, fault address) are
// still recorded. See #14045.
#if !defined( __APPLE__ )
#if defined( __x86_64__ )
if ( ucontext )
{
Expand All @@ -223,6 +253,9 @@ void manageSegFailureSA( int signalCode, siginfo_t* info, void* ucontext )
extraAttrs["crash.program_counter"] = pcStr.str();
}
#endif
#else
(void)ucontext;
#endif

performCrashLogging( signalCode, extraAttrs );
exit( 1 );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,7 @@ static std::string extractRelevantPath( const std::string& fullPath )
return fullPath;
}

#if RIA_HAS_STD_STACKTRACE
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -420,6 +421,7 @@ void RiaOpenTelemetryManager::reportCrash( int signalCode, const std::stacktrace

RiaLogging::error( std::format( "Crash reported to OpenTelemetry (signal: {})", signalCode ) );
}
#endif // RIA_HAS_STD_STACKTRACE

//--------------------------------------------------------------------------------------------------
///
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,18 @@
#include <memory>
#include <mutex>
#include <queue>
#include <stacktrace>
#include <string>

// std::stacktrace is C++23. libc++ shipped with Homebrew llvm@19 (and
// older toolchains) does not provide it yet, so guard the include + the
// reportCrash overload that uses it. See #14045.
#if __has_include( <stacktrace> )
#include <stacktrace>
#define RIA_HAS_STD_STACKTRACE 1
#else
#define RIA_HAS_STD_STACKTRACE 0
#endif

class QString;
class QNetworkAccessManager;
class QTimer;
Expand Down Expand Up @@ -88,7 +97,9 @@ class RiaOpenTelemetryManager : public QObject

// Event reporting
void reportEventAsync( const std::string& eventName, const std::map<std::string, std::string>& attributes );
#if RIA_HAS_STD_STACKTRACE
void reportCrash( int signalCode, const std::stacktrace& trace, const std::map<std::string, std::string>& extraAttributes = {} );
#endif

// Configuration
bool isEnabled() const;
Expand Down
21 changes: 20 additions & 1 deletion ApplicationLibCode/FileInterface/RifVtkImportUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,21 @@

#include <cstring>
#include <filesystem>
#include <spanstream>
#include <string>
#include <vector>

// std::ispanstream is C++23. libc++ on Homebrew llvm@19 does not ship
// <spanstream>; fall back to std::istringstream when unavailable. Only
// difference: the fallback copies the string_view into an owning string.
// See #14045.
#if __has_include( <spanstream> )
#include <spanstream>
#define RIA_HAS_STD_SPANSTREAM 1
#else
#include <sstream>
#define RIA_HAS_STD_SPANSTREAM 0
#endif

//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -204,7 +215,11 @@ std::vector<RifVtkImportUtil::PvdDataset> RifVtkImportUtil::parsePvdDatasets( co
//--------------------------------------------------------------------------------------------------
std::vector<cvf::Vec3d> RifVtkImportUtil::parseVec3ds( std::string_view text )
{
#if RIA_HAS_STD_SPANSTREAM
std::ispanstream iss( text );
#else
std::istringstream iss{ std::string{ text } };
#endif

std::vector<cvf::Vec3d> vecs;

Expand All @@ -228,7 +243,11 @@ std::vector<cvf::Vec3d> RifVtkImportUtil::parseVec3ds( std::string_view text )
//--------------------------------------------------------------------------------------------------
std::vector<cvf::Vec3f> RifVtkImportUtil::parseVec3fs( std::string_view text )
{
#if RIA_HAS_STD_SPANSTREAM
std::ispanstream iss( text );
#else
std::istringstream iss{ std::string{ text } };
#endif

std::vector<cvf::Vec3f> vecs;

Expand Down
1 change: 0 additions & 1 deletion ApplicationLibCode/UserInterface/RiuMainWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,6 @@

#include <algorithm>
#include <csignal>
#include <stacktrace>

//==================================================================================================
///
Expand Down
Loading
Loading