Skip to content

Commit

Permalink
Fix macOS build (#163)
Browse files Browse the repository at this point in the history
* Input:Quartz: Move DolWindowPositionObserver to header

* Input:Quartz: Fix macOS compile

* GHActions:mac: Fix MoltenVK build

* GHActions: Update SDL to 2.30.2

* GHActions: Update Qt to 6.2.8

* GHActions: Use /archive/ links for Qt

They stay available even if we wait too long to update and official support ends

* GHActions: Add Qt SVG

* GHActions: Update to macOS 14

* GHActions: Disable searching for system libs

We don't want to pick up random homebrew libs

* GHActions: Update actions

* Input: Don't leak mouse inputs

* Input:Quartz: Release cursor during modal popups
  • Loading branch information
TellowKrinkle authored Apr 21, 2024
1 parent 787abb5 commit e763a70
Show file tree
Hide file tree
Showing 12 changed files with 194 additions and 117 deletions.
52 changes: 30 additions & 22 deletions .github/workflows/macos_build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ on: [push, pull_request]
jobs:
build_macos:
name: macOS Build
runs-on: macos-11.0
runs-on: macos-14
env:
CCACHE_BASEDIR: ${{ github.workspace }}
CCACHE_DIR: ${{ github.workspace }}/.ccache
Expand All @@ -15,10 +15,15 @@ jobs:

steps:
- name: Checkout Repository
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
submodules: recursive

# MoltenVK's build process breaks on Python 3.12
- uses: actions/setup-python@v5
with:
python-version: '3.11'

- name: Install Packages
env:
HOMEBREW_NO_INSTALL_CLEANUP: 1
Expand All @@ -31,7 +36,7 @@ jobs:
- name: Cache Dependencies
id: cache-deps
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: ~/deps
key: macOS deps ${{ hashFiles('.github/workflows/scripts/macos/build-dependencies.sh') }}
Expand All @@ -42,7 +47,7 @@ jobs:

- name: Cache MoltenVK
id: cache-moltenvk
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: ~/moltenvk
key: macOS MoltenVK ${{ hashFiles('Externals/MoltenVK') }}
Expand Down Expand Up @@ -72,39 +77,42 @@ jobs:
run: echo "timestamp=$(date -u "+%Y-%m-%d-%H;%M;%S")" >> $GITHUB_OUTPUT

- name: Cache ccache cache
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: .ccache
key: macOS ccache ${{ steps.ccache_cache_timestamp.outputs.timestamp }}
restore-keys: macOS ccache

- name: Generate CMake Files
run: |
COMMON_ARGS=(
-DCMAKE_PREFIX_PATH="$HOME/deps;$HOME/moltenvk"
-DCMAKE_BUILD_TYPE=Release
-DUSE_BUNDLED_MOLTENVK=OFF
-DMACOS_CODE_SIGNING=OFF
-DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON
-DCMAKE_C_COMPILER_LAUNCHER=ccache
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache
-DCMAKE_DISABLE_PRECOMPILE_HEADERS=ON
-DUSE_SYSTEM_LIBS=OFF
-DUSE_SYSTEM_BZIP2=ON
-DUSE_SYSTEM_CURL=ON
-DUSE_SYSTEM_ICONV=ON
-DUSE_SYSTEM_LIBLZMA=ON
-DUSE_SYSTEM_SDL2=ON
)
cmake -DCMAKE_OSX_ARCHITECTURES=x86_64 \
-DCMAKE_SYSTEM_PROCESSOR=x86_64 \
-DCMAKE_SYSTEM_NAME=Darwin \
-DCMAKE_OSX_DEPLOYMENT_TARGET=10.15 \
-DCMAKE_PREFIX_PATH="$HOME/deps;$HOME/moltenvk" \
-DCMAKE_BUILD_TYPE=Release \
-DUSE_BUNDLED_MOLTENVK=OFF \
-DMACOS_CODE_SIGNING=OFF \
-DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON \
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
-DCMAKE_DISABLE_PRECOMPILE_HEADERS=ON \
"${COMMON_ARGS[@]}" \
-B build .
cmake -DCMAKE_OSX_ARCHITECTURES=arm64 \
-DCMAKE_SYSTEM_PROCESSOR=arm64 \
-DCMAKE_SYSTEM_NAME=Darwin \
-DCMAKE_OSX_DEPLOYMENT_TARGET=11.0 \
-DCMAKE_PREFIX_PATH="$HOME/deps;$HOME/moltenvk" \
-DCMAKE_BUILD_TYPE=Release \
-DUSE_BUNDLED_MOLTENVK=OFF \
-DMACOS_CODE_SIGNING=OFF \
-DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON \
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
-DCMAKE_DISABLE_PRECOMPILE_HEADERS=ON \
"${COMMON_ARGS[@]}" \
-B build-arm .
- name: Build Dolphin (x86_64)
Expand Down Expand Up @@ -151,7 +159,7 @@ jobs:
echo "name=$APPNAME" >> "$GITHUB_OUTPUT"
- name: Upload Artifact
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: ${{ steps.create-artifact.outputs.name }}
path: "*.tar.gz"
35 changes: 23 additions & 12 deletions .github/workflows/scripts/macos/build-dependencies.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ set -e
export MACOSX_DEPLOYMENT_TARGET=10.15
INSTALLDIR="$HOME/deps"
NPROCS="$(getconf _NPROCESSORS_ONLN)"
SDL=SDL2-2.26.0
QT=6.2.4
SDL=SDL2-2.30.2
QT=6.2.8
QT_SUFFIX=-opensource

mkdir deps-build
cd deps-build
Expand All @@ -17,17 +18,19 @@ export CFLAGS="-I$INSTALLDIR/include -Os $CFLAGS"
export CXXFLAGS="-I$INSTALLDIR/include -Os $CXXFLAGS"

cat > SHASUMS <<EOF
8000d7169febce93c84b6bdf376631f8179132fd69f7015d4dadb8b9c2bdb295 $SDL.tar.gz
d9924d6fd4fa5f8e24458c87f73ef3dfc1e7c9b877a5407c040d89e6736e2634 qtbase-everywhere-src-$QT.tar.xz
17f40689c4a1706a1b7db22fa92f6ab79f7b698a89e100cab4d10e19335f8267 qttools-everywhere-src-$QT.tar.xz
bd1aac74a892c60b2f147b6d53bb5b55ab7a6409e63097d38198933f8024fa51 qttranslations-everywhere-src-$QT.tar.xz
891d66ac8cae51361d3229e3336ebec1c407a8a2a063b61df14f5fdf3ab5ac31 $SDL.tar.gz
718c91365fc0ab00fb37c262e30285efc7c608d1b7f2b2a3611338ba0799157b qtbase-everywhere$QT_SUFFIX-src-$QT.tar.xz
9ddb0859697de5832f91b85fa20cd9c90d3174c035e9e4b05393969819fd37ec qtsvg-everywhere$QT_SUFFIX-src-$QT.tar.xz
97326f2ce07701316fab45e76510e30f540c23527a7723b0ad98d7ffea76ba14 qttools-everywhere$QT_SUFFIX-src-$QT.tar.xz
46191973fd688e3b9b0eac799a2e3de8fb672874c707b177cf71d8e9198ca77c qttranslations-everywhere$QT_SUFFIX-src-$QT.tar.xz
EOF

curl -L \
-O "https://libsdl.org/release/$SDL.tar.gz" \
-O "https://download.qt.io/official_releases/qt/${QT%.*}/$QT/submodules/qtbase-everywhere-src-$QT.tar.xz" \
-O "https://download.qt.io/official_releases/qt/${QT%.*}/$QT/submodules/qttools-everywhere-src-$QT.tar.xz" \
-O "https://download.qt.io/official_releases/qt/${QT%.*}/$QT/submodules/qttranslations-everywhere-src-$QT.tar.xz" \
-O "https://download.qt.io/archive/qt/${QT%.*}/$QT/submodules/qtbase-everywhere$QT_SUFFIX-src-$QT.tar.xz" \
-O "https://download.qt.io/archive/qt/${QT%.*}/$QT/submodules/qtsvg-everywhere$QT_SUFFIX-src-$QT.tar.xz" \
-O "https://download.qt.io/archive/qt/${QT%.*}/$QT/submodules/qttools-everywhere$QT_SUFFIX-src-$QT.tar.xz" \
-O "https://download.qt.io/archive/qt/${QT%.*}/$QT/submodules/qttranslations-everywhere$QT_SUFFIX-src-$QT.tar.xz" \

shasum -a 256 --check SHASUMS

Expand All @@ -40,15 +43,23 @@ make install
cd ..

echo "Installing Qt Base..."
tar xf "qtbase-everywhere-src-$QT.tar.xz"
tar xf "qtbase-everywhere$QT_SUFFIX-src-$QT.tar.xz"
cd "qtbase-everywhere-src-$QT"
cmake -B build -DCMAKE_OSX_ARCHITECTURES="x86_64;arm64" -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -DCMAKE_BUILD_TYPE=Release -DFEATURE_optimize_size=ON -DFEATURE_dbus=OFF -DFEATURE_framework=OFF -DFEATURE_icu=OFF -DFEATURE_opengl=OFF -DFEATURE_printsupport=OFF -DFEATURE_sql=OFF -DFEATURE_gssapi=OFF -DFEATURE_system_png=OFF -DFEATURE_system_jpeg=OFF -DCMAKE_MESSAGE_LOG_LEVEL=STATUS
make -C build "-j$NPROCS"
make -C build install
cd ..

echo "Installing Qt SVG..."
tar xf "qtsvg-everywhere$QT_SUFFIX-src-$QT.tar.xz"
cd "qtsvg-everywhere-src-$QT"
cmake -B build -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -DCMAKE_BUILD_TYPE=Release
make -C build "-j$NPROCS"
make -C build install
cd ..

echo "Installing Qt Tools..."
tar xf "qttools-everywhere-src-$QT.tar.xz"
tar xf "qttools-everywhere$QT_SUFFIX-src-$QT.tar.xz"
cd "qttools-everywhere-src-$QT"
# Linguist relies on a library in the Designer target, which takes 5-7 minutes to build on the CI
# Avoid it by not building Linguist, since we only need the tools that come with it
Expand All @@ -70,7 +81,7 @@ make -C build install
cd ..

echo "Installing Qt Translations..."
tar xf "qttranslations-everywhere-src-$QT.tar.xz"
tar xf "qttranslations-everywhere$QT_SUFFIX-src-$QT.tar.xz"
cd "qttranslations-everywhere-src-$QT"
cmake -B build -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -DCMAKE_BUILD_TYPE=Release
make -C build "-j$NPROCS"
Expand Down
5 changes: 0 additions & 5 deletions Source/Core/InputCommon/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -122,11 +122,6 @@ elseif(APPLE)
target_sources(inputcommon PRIVATE
QuartzInputMouse.h
QuartzInputMouse.mm
ControllerInterface/OSX/OSX.h
ControllerInterface/OSX/OSX.mm
ControllerInterface/OSX/OSXJoystick.h
ControllerInterface/OSX/OSXJoystick.mm
ControllerInterface/OSX/RunLoopStopper.h
ControllerInterface/Quartz/Quartz.h
ControllerInterface/Quartz/Quartz.mm
ControllerInterface/Quartz/QuartzKeyboardAndMouse.h
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ void ControllerInterface::RefreshDevices(RefreshReason reason)
// device.

// An empty mouse class for when no platform specific one exists.
prime::g_mouse_input = new prime::NullMouse();
prime::g_mouse_input.reset(new prime::NullMouse());

#ifdef CIFACE_USE_WIN32
ciface::Win32::PopulateDevices(m_wsi.render_surface);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,16 @@
#include "InputCommon/ControllerInterface/CoreDevice.h"

#ifdef __OBJC__
@class DolWindowPositionObserver;
/// Helper class to get window position data from threads other than the main thread
@interface DolWindowPositionObserver : NSObject

- (instancetype)initWithView:(NSView*)view;
- (void)addKeyWindowChangeCallback:(void(*)(void*, bool))callback ctx:(void*)ctx;
- (void)removeKeyWindowChangeCallback:(void*)ctx;
@property(readonly) NSRect frame;
@property(readonly, getter=isKeyWindow) bool keyWindow;

@end
#else
class DolWindowPositionObserver;
#endif
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,14 @@
#include "InputCommon/ControllerInterface/ControllerInterface.h"
#include "InputCommon/QuartzInputMouse.h"

/// Helper class to get window position data from threads other than the main thread
@interface DolWindowPositionObserver : NSObject

- (instancetype)initWithView:(NSView*)view;
@property(readonly) NSRect frame;

@end

@implementation DolWindowPositionObserver
{
NSView* _view;
NSWindow* _window;
NSRect _frame;
std::atomic<bool> _is_key;
std::mutex _mtx;
std::vector<std::pair<void(*)(void*, bool), void*>> _key_callbacks;
}

- (NSRect)calcFrame
Expand All @@ -43,7 +37,12 @@ - (instancetype)initWithView:(NSView*)view
_view = view;
_window = [view window];
_frame = [self calcFrame];
_is_key.store([_window isKeyWindow], std::memory_order_relaxed);
[_window addObserver:self forKeyPath:@"frame" options:0 context:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyWindowDidChange:)
name:NSWindowDidBecomeKeyNotification
object:nil];
}
return self;
}
Expand All @@ -54,6 +53,38 @@ - (NSRect)frame
return _frame;
}

- (bool)isKeyWindow
{
return _is_key.load(std::memory_order_relaxed);
}

- (void)addKeyWindowChangeCallback:(void(*)(void*, bool))callback ctx:(void*)ctx;
{
std::lock_guard<std::mutex> guard(_mtx);
_key_callbacks.push_back(std::make_pair(callback, ctx));
}

- (void)removeKeyWindowChangeCallback:(void*)ctx
{
std::lock_guard<std::mutex> guard(_mtx);
_key_callbacks.erase(std::remove_if(_key_callbacks.begin(), _key_callbacks.end(),
[ctx](auto& entry){ return entry.second == ctx; }),
_key_callbacks.end());
}

- (void)keyWindowDidChange:(id)window
{
bool key = [_window isKeyWindow];
bool changed = key != _is_key.load(std::memory_order_relaxed);
_is_key.store(key, std::memory_order_relaxed);
if (changed)
{
std::lock_guard<std::mutex> guard(_mtx);
for (const auto& callback : _key_callbacks)
callback.first(callback.second, key);
}
}

- (void)observeValueForKeyPath:(NSString*)keyPath
ofObject:(id)object
change:(NSDictionary<NSKeyValueChangeKey, id>*)change
Expand All @@ -70,6 +101,7 @@ - (void)observeValueForKeyPath:(NSString*)keyPath
- (void)dealloc
{
[_window removeObserver:self forKeyPath:@"frame"];
[[NSNotificationCenter defaultCenter] removeObserver:self];
}

@end
Expand Down Expand Up @@ -217,7 +249,7 @@ - (void)dealloc
MainThreadInitialization(view);
else
dispatch_sync(dispatch_get_main_queue(), [this, view] { MainThreadInitialization(view); });
prime::InitQuartzInputMouse(&m_windowid);
prime::InitQuartzInputMouse(m_window_pos_observer);

// cursor, with a hax for-loop
for (unsigned int i = 0; i < 4; ++i)
Expand Down
2 changes: 1 addition & 1 deletion Source/Core/InputCommon/DInputMouseAbsolute.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ void InitMouse(IDirectInput8* const idi8)
mo_device->SetProperty(DIPROP_AXISMODE, &dipdw.diph);
auto mouse_input = new DInputMouse();
mouse_input->Init(mo_device);
g_mouse_input = mouse_input;
g_mouse_input.reset(mouse_input);
return;
}
}
Expand Down
2 changes: 1 addition & 1 deletion Source/Core/InputCommon/GenericMouse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,6 @@ int32_t GenericMouse::GetDeltaVerticalAxis() const
return dy;
}

GenericMouse* g_mouse_input;
std::unique_ptr<GenericMouse> g_mouse_input;

} // namespace prime
4 changes: 3 additions & 1 deletion Source/Core/InputCommon/GenericMouse.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include <stdint.h>
#include <memory>

extern int win_w, win_h;

Expand All @@ -10,6 +11,7 @@ namespace prime
class GenericMouse
{
public:
virtual ~GenericMouse() = default;
// Platform dependant implementations are made virtual
virtual void UpdateInput() = 0;
virtual void LockCursorToGameWindow() = 0;
Expand All @@ -31,6 +33,6 @@ class NullMouse : public GenericMouse {
void LockCursorToGameWindow() override {}
};

extern GenericMouse* g_mouse_input;
extern std::unique_ptr<GenericMouse> g_mouse_input;

} // namespace prime
Loading

0 comments on commit e763a70

Please sign in to comment.