Skip to content

Commit be002f3

Browse files
authored
Merge pull request #111 from nashsu/feature/macos-support
feat: add macOS build support
2 parents 5525a67 + bafec2f commit be002f3

8 files changed

Lines changed: 415 additions & 2 deletions

File tree

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
name: Build macOS DMG (Qt6, Universal)
2+
3+
on:
4+
push:
5+
tags:
6+
- "*"
7+
workflow_dispatch:
8+
inputs:
9+
branch:
10+
description: 'Checkout branch'
11+
required: false
12+
default: 'dev'
13+
tag:
14+
description: 'Checkout tag'
15+
required: false
16+
17+
permissions:
18+
contents: write
19+
20+
jobs:
21+
build-omodsim:
22+
name: Build OpenModSim macOS DMG version '${{ github.event.inputs.tag || github.event.inputs.branch || github.ref_name }}' with Qt6
23+
runs-on: macos-latest
24+
25+
env:
26+
QT_VERSION: "6.9.3"
27+
QT_HOST: "mac"
28+
QT_TARGET: "desktop"
29+
QT_ARCH: "clang_64"
30+
QT_INSTALL_DIR: "${{ github.workspace }}/Qt"
31+
CMAKE_GENERATOR: "Ninja"
32+
BUILD_TYPE: "Release"
33+
DMG_PACKAGE_NAME: "qt6-omodsim"
34+
35+
steps:
36+
- name: Checkout repository
37+
uses: actions/checkout@v4
38+
with:
39+
ref: ${{ github.event.inputs.tag || github.event.inputs.branch || github.ref_name }}
40+
41+
- name: Determine ref_type and ref_name
42+
run: |
43+
if [ "${{ github.ref_type }}" = "tag" ] || [ -n "${{ github.event.inputs.tag }}" ]; then
44+
REF_TYPE="tags"
45+
if [ -n "${{ github.event.inputs.tag }}" ]; then
46+
REF_NAME="${{ github.event.inputs.tag }}"
47+
else
48+
REF_NAME="${{ github.ref_name }}"
49+
fi
50+
else
51+
REF_TYPE="heads"
52+
REF_NAME="${{ github.ref_name }}"
53+
fi
54+
echo "REF_TYPE=$REF_TYPE" >> $GITHUB_ENV
55+
echo "REF_NAME=$REF_NAME" >> $GITHUB_ENV
56+
57+
- name: Extract version from CMakeLists.txt
58+
run: |
59+
FULL_VERSION=$(grep -oE 'VERSION\s+[0-9]+\.[0-9]+\.[0-9]+' src/CMakeLists.txt | grep -oE '[0-9]+\.[0-9]+\.[0-9]+')
60+
61+
if [ "${GITHUB_REF_NAME}" = "dev" ] || [ "${{ github.event.inputs.branch }}" = "dev" ]; then
62+
MAJOR_MINOR=$(echo "$FULL_VERSION" | cut -d. -f1,2)
63+
APP_VERSION="${MAJOR_MINOR}~dev"
64+
else
65+
APP_VERSION="$FULL_VERSION"
66+
fi
67+
68+
echo "APP_VERSION=$APP_VERSION" >> $GITHUB_ENV
69+
echo "Extracted version: $APP_VERSION"
70+
71+
- name: Install dependencies
72+
run: |
73+
brew install ninja cmake
74+
75+
- name: Install Python (for aqtinstall)
76+
uses: actions/setup-python@v5
77+
with:
78+
python-version: "3.12"
79+
80+
- name: Install aqtinstall
81+
run: python -m pip install aqtinstall
82+
83+
- name: Download Qt
84+
run: |
85+
mkdir -p ${{ env.QT_INSTALL_DIR }}
86+
aqt install-qt \
87+
${{ env.QT_HOST }} \
88+
${{ env.QT_TARGET }} \
89+
${{ env.QT_VERSION }} \
90+
${{ env.QT_ARCH }} \
91+
-m qt5compat qtpdf qtserialport qtserialbus \
92+
-O ${{ env.QT_INSTALL_DIR }}
93+
94+
- name: Add Qt to PATH
95+
run: echo "${{ env.QT_INSTALL_DIR }}/${{ env.QT_VERSION }}/macos/bin" >> $GITHUB_PATH
96+
97+
- name: Set BUILD_DIR
98+
run: echo "BUILD_DIR=build-omodsim-Qt_${{ env.QT_VERSION }}_clang_64-${{ env.BUILD_TYPE }}" >> $GITHUB_ENV
99+
100+
- name: Configure project
101+
run: |
102+
cmake src -B ${{ env.BUILD_DIR }} \
103+
-G "${{ env.CMAKE_GENERATOR }}" \
104+
-DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} \
105+
-DCMAKE_PREFIX_PATH=${{ env.QT_INSTALL_DIR }}/${{ env.QT_VERSION }}/macos \
106+
-DUSE_QT6=ON
107+
108+
- name: Build
109+
run: cmake --build ${{ env.BUILD_DIR }} --config ${{ env.BUILD_TYPE }} --parallel
110+
111+
- name: Deploy Qt dependencies using macdeployqt
112+
run: |
113+
"${{ env.QT_INSTALL_DIR }}/${{ env.QT_VERSION }}/macos/bin/macdeployqt" \
114+
"${{ env.BUILD_DIR }}/omodsim.app" \
115+
-always-overwrite
116+
117+
- name: Copy docs into app bundle
118+
run: |
119+
mkdir -p "${{ env.BUILD_DIR }}/omodsim.app/Contents/Resources/docs"
120+
cp -R "${{ env.BUILD_DIR }}/docs/"* "${{ env.BUILD_DIR }}/omodsim.app/Contents/Resources/docs/"
121+
122+
- name: Create DMG
123+
run: |
124+
DMG_NAME="${{ env.DMG_PACKAGE_NAME }}_${{ env.APP_VERSION }}_macos.dmg"
125+
echo "DMG_NAME=$DMG_NAME" >> $GITHUB_ENV
126+
127+
hdiutil create -volname "Open ModSim ${{ env.APP_VERSION }}" \
128+
-srcfolder "${{ env.BUILD_DIR }}/omodsim.app" \
129+
-ov -format UDZO \
130+
"$DMG_NAME"
131+
132+
- name: Upload DMG
133+
uses: actions/upload-artifact@v4
134+
if: success()
135+
with:
136+
name: ${{ env.DMG_NAME }}
137+
path: ${{ env.DMG_NAME }}
138+
139+
- name: Create or update GitHub Release and upload DMG
140+
if: success() && github.event_name == 'push' && github.ref_type == 'tag'
141+
uses: softprops/action-gh-release@v2
142+
with:
143+
draft: true
144+
tag_name: ${{ github.ref_name }}
145+
name: Open ModSim ${{ env.APP_VERSION }}
146+
files: |
147+
${{ env.DMG_NAME }}
148+
env:
149+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

README.md

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ Script.onInit(init);
131131
```
132132

133133
# Building
134-
Building is available via cmake (with installed Qt version 5.15 and above) or Qt Creator. Supports both OS Microsoft Windows and Linux.
134+
Building is available via cmake (with installed Qt version 5.15 and above) or Qt Creator. Supports Microsoft Windows, Linux and macOS.
135135

136136
## Microsoft Windows Building
137137

@@ -176,10 +176,41 @@ cd OpenModSim
176176
If you need to specify Qt framework major version (5 or 6), you can do it in the parameters
177177
- `./build.sh -qt5` or `./build.sh -qt6`
178178

179+
## macOS Building
180+
181+
The minimum supported version of macOS for building OpenModSim from sources is macOS 11 (Big Sur).
182+
183+
1. Install [Homebrew](https://brew.sh) if not already installed
184+
2. Install required dependencies:
185+
```bash
186+
brew install qt@6 cmake ninja
187+
```
188+
3. Clone OpenModSim sources from github repository:
189+
```bash
190+
git clone https://github.com/sanny32/OpenModSim.git
191+
```
192+
4. Go to OpenModSim folder:
193+
```bash
194+
cd OpenModSim
195+
```
196+
5. Run the build script:
197+
```bash
198+
./build-macos.sh
199+
```
200+
201+
If you need to specify Qt framework major version (5 or 6), you can do it in the parameters
202+
- `./build-macos.sh -qt5` or `./build-macos.sh -qt6`
203+
204+
The build script generates a macOS application bundle (`omodsim.app`). To run the application:
205+
```bash
206+
open build-omodsim-Qt_*/omodsim.app
207+
```
208+
179209
# About supported operating systems
180210

181211
The following minimum operating system versions are supported for OpenModSim:
182212

213+
- <img src="docs/icons/logo_apple.svg" width="16" height="16" /> **macOS 11 (Big Sur)** and later (Intel and Apple Silicon)
183214
- <img src="docs/icons/logo_windows7.svg" width="16" height="16" /> **Microsoft Windows 7**
184215
- <img src="docs/icons/logo_debian.svg" width="16" height="16" /> **Debian Linux 11**
185216
- <img src="docs/icons/logo_ubuntu.svg" width="16" height="16" /> **Ubuntu Linux 22.04**

build-macos.sh

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
#!/usr/bin/env bash
2+
set -e
3+
4+
echo "=================================="
5+
echo " OpenModSim build script (macOS) "
6+
echo "=================================="
7+
echo ""
8+
9+
# ==========================
10+
# Check macOS
11+
# ==========================
12+
if [[ "$(uname)" != "Darwin" ]]; then
13+
echo "Error: This script is for macOS only."
14+
exit 1
15+
fi
16+
17+
# ==========================
18+
# Parse script arguments
19+
# ==========================
20+
QT_CHOICE=""
21+
for arg in "$@"; do
22+
case "$arg" in
23+
-qt5|qt5)
24+
QT_CHOICE="qt5"
25+
;;
26+
-qt6|qt6)
27+
QT_CHOICE="qt6"
28+
;;
29+
*)
30+
;;
31+
esac
32+
done
33+
34+
if [ -z "$QT_CHOICE" ]; then
35+
QT_CHOICE="qt6"
36+
fi
37+
38+
# ==========================
39+
# Check Xcode Command Line Tools
40+
# ==========================
41+
echo "Checking for Xcode Command Line Tools..."
42+
if ! xcode-select -p >/dev/null 2>&1; then
43+
echo "Error: Xcode Command Line Tools not found."
44+
echo "Install with: xcode-select --install"
45+
exit 1
46+
fi
47+
echo " Found: $(xcode-select -p)"
48+
49+
# ==========================
50+
# Check Homebrew
51+
# ==========================
52+
echo "Checking for Homebrew..."
53+
if ! command -v brew >/dev/null 2>&1; then
54+
echo "Error: Homebrew not found."
55+
echo "Install from: https://brew.sh"
56+
exit 1
57+
fi
58+
echo " Found: $(brew --prefix)"
59+
60+
# ==========================
61+
# Check CMake and Ninja
62+
# ==========================
63+
echo "Checking for CMake..."
64+
if ! command -v cmake >/dev/null 2>&1; then
65+
echo "CMake not found. Installing..."
66+
brew install cmake
67+
fi
68+
echo " Found: $(cmake --version | head -1)"
69+
70+
echo "Checking for Ninja..."
71+
if ! command -v ninja >/dev/null 2>&1; then
72+
echo "Ninja not found. Installing..."
73+
brew install ninja
74+
fi
75+
echo " Found: ninja $(ninja --version)"
76+
77+
# ==========================
78+
# Check Qt
79+
# ==========================
80+
echo "Checking for Qt..."
81+
82+
QT_PREFIX=""
83+
QT_VERSION=""
84+
85+
if [ "$QT_CHOICE" = "qt6" ]; then
86+
QT_PREFIX="$(brew --prefix qt@6 2>/dev/null || brew --prefix qt 2>/dev/null || true)"
87+
if [ -z "$QT_PREFIX" ] || [ ! -d "$QT_PREFIX" ]; then
88+
echo "Qt6 not found. Installing..."
89+
brew install qt@6
90+
QT_PREFIX="$(brew --prefix qt@6 2>/dev/null || brew --prefix qt 2>/dev/null)"
91+
fi
92+
QT_VERSION=$("${QT_PREFIX}/bin/qmake" -query QT_VERSION 2>/dev/null || true)
93+
elif [ "$QT_CHOICE" = "qt5" ]; then
94+
QT_PREFIX="$(brew --prefix qt@5 2>/dev/null || true)"
95+
if [ -z "$QT_PREFIX" ] || [ ! -d "$QT_PREFIX" ]; then
96+
echo "Qt5 not found. Installing..."
97+
brew install qt@5
98+
QT_PREFIX="$(brew --prefix qt@5 2>/dev/null)"
99+
fi
100+
QT_VERSION=$("${QT_PREFIX}/bin/qmake" -query QT_VERSION 2>/dev/null || true)
101+
fi
102+
103+
if [ -z "$QT_VERSION" ]; then
104+
echo "Error: Cannot detect Qt version from ${QT_PREFIX}"
105+
exit 1
106+
fi
107+
108+
echo " Found: Qt ${QT_VERSION} at ${QT_PREFIX}"
109+
110+
# ==========================
111+
# Check minimum Qt version
112+
# ==========================
113+
MIN_QT_VERSION="5.15.0"
114+
verlte() {
115+
[ "$1" = "$(printf '%s\n%s' "$1" "$2" | sort -V | head -n1)" ]
116+
}
117+
verlt() {
118+
[ "$1" != "$2" ] && verlte "$1" "$2"
119+
}
120+
121+
if verlt "$QT_VERSION" "$MIN_QT_VERSION"; then
122+
echo "Error: Qt >= $MIN_QT_VERSION is required, but found $QT_VERSION"
123+
exit 1
124+
fi
125+
126+
# ==========================
127+
# Setup cmake options
128+
# ==========================
129+
CMAKE_QT_OPTION="-DUSE_QT5=OFF -DUSE_QT6=OFF"
130+
if [ "$QT_CHOICE" = "qt5" ]; then
131+
CMAKE_QT_OPTION="-DUSE_QT5=ON"
132+
elif [ "$QT_CHOICE" = "qt6" ]; then
133+
CMAKE_QT_OPTION="-DUSE_QT6=ON"
134+
fi
135+
136+
# ==========================
137+
# Detect architecture
138+
# ==========================
139+
ARCH=$(uname -m)
140+
BUILD_TYPE=Release
141+
142+
# ==========================
143+
# Build project
144+
# ==========================
145+
SANITIZED_QT_VERSION=$(echo "$QT_VERSION" | tr '.' '_')
146+
BUILD_DIR="build-omodsim-Qt_${SANITIZED_QT_VERSION}_clang_${ARCH}-${BUILD_TYPE}"
147+
echo ""
148+
echo "Starting build in: ${BUILD_DIR}"
149+
mkdir -p "$BUILD_DIR"
150+
cd "$BUILD_DIR"
151+
152+
cmake ../src -GNinja \
153+
-DCMAKE_PREFIX_PATH="${QT_PREFIX}" \
154+
-DCMAKE_BUILD_TYPE=${BUILD_TYPE} \
155+
${CMAKE_QT_OPTION}
156+
157+
ninja
158+
159+
echo ""
160+
echo "Build finished successfully!"
161+
echo "Application bundle: ${BUILD_DIR}/omodsim.app"
162+
echo ""
163+
echo "To run:"
164+
echo " open ${BUILD_DIR}/omodsim.app"
165+
echo ""

docs/icons/logo_apple.svg

Lines changed: 3 additions & 0 deletions
Loading

0 commit comments

Comments
 (0)