Skip to content

Commit b14bda3

Browse files
committed
feat: add macOS build support
Add macOS platform support with .app bundle packaging, build script, and documentation. All changes are additive and do not affect existing Windows or Linux build paths.
1 parent 1e8c8a1 commit b14bda3

7 files changed

Lines changed: 266 additions & 2 deletions

File tree

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

src/CMakeLists.txt

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,15 @@ file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/docs)
338338
find_program(QHELP_GENERATOR_EXECUTABLE qhelpgenerator
339339
HINTS "${QT_BINARY_DIR}" "${QT_LIBEXEC_DIR}" "${QT_INSTALL_LIBEXECS}")
340340

341+
if(NOT QHELP_GENERATOR_EXECUTABLE)
342+
# Homebrew on macOS installs qhelpgenerator in share/qt/libexec
343+
get_filename_component(_qt_share_libexec "${QT_BINARY_DIR}/../share/qt/libexec" REALPATH)
344+
find_program(QHELP_GENERATOR_EXECUTABLE qhelpgenerator
345+
HINTS "${_qt_share_libexec}"
346+
"${CMAKE_PREFIX_PATH}/share/qt/libexec"
347+
"${CMAKE_PREFIX_PATH}/libexec")
348+
endif()
349+
341350
if(NOT QHELP_GENERATOR_EXECUTABLE)
342351
find_program(QHELP_GENERATOR_EXECUTABLE qhelpgenerator)
343352
endif()
@@ -386,6 +395,25 @@ if(WIN32)
386395

387396
target_sources(${PROJECT_NAME} PRIVATE ${ICON_PATH} "${CMAKE_BINARY_DIR}/omodsim.rc")
388397
set_target_properties(${PROJECT_NAME} PROPERTIES WIN32_EXECUTABLE ON)
398+
elseif(APPLE)
399+
set(MACOSX_ICON "${CMAKE_CURRENT_SOURCE_DIR}/res/omodsim.icns")
400+
set_source_files_properties(${MACOSX_ICON} PROPERTIES MACOSX_PACKAGE_LOCATION "Resources")
401+
target_sources(${PROJECT_NAME} PRIVATE ${MACOSX_ICON})
402+
403+
configure_file(
404+
"${CMAKE_CURRENT_SOURCE_DIR}/omodsim.plist.in"
405+
"${CMAKE_BINARY_DIR}/Info.plist"
406+
@ONLY
407+
)
408+
409+
set_target_properties(${PROJECT_NAME} PROPERTIES
410+
MACOSX_BUNDLE ON
411+
MACOSX_BUNDLE_INFO_PLIST "${CMAKE_BINARY_DIR}/Info.plist"
412+
MACOSX_BUNDLE_ICON_FILE omodsim.icns
413+
MACOSX_BUNDLE_BUNDLE_NAME "${PRODUCT_NAME}"
414+
MACOSX_BUNDLE_BUNDLE_VERSION "${PROJECT_VERSION}"
415+
MACOSX_BUNDLE_SHORT_VERSION_STRING "${PROJECT_VERSION}"
416+
)
389417
elseif(LINUX)
390418
target_link_options(${PROJECT_NAME} PRIVATE -static-libgcc -static-libstdc++)
391419
endif()
@@ -405,7 +433,9 @@ add_custom_command(
405433
add_custom_target(helpgenerator ALL DEPENDS ${JSHELP_QCH} ${JSHELP_QHC})
406434
add_dependencies(${PROJECT_NAME} helpgenerator)
407435

408-
if(LINUX)
436+
if(APPLE)
437+
install(TARGETS ${PROJECT_NAME} BUNDLE DESTINATION .)
438+
elseif(LINUX)
409439
configure_file(
410440
"${CMAKE_CURRENT_SOURCE_DIR}/omodsim.desktop.in"
411441
"${CMAKE_CURRENT_BINARY_DIR}/omodsim.desktop"

src/dialogs/dialogabout.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,13 @@ DialogAbout::DialogAbout(QWidget *parent) :
109109
tr("Underlying platform."));
110110
#endif
111111

112+
#ifdef Q_OS_MAC
113+
addComponent(vboxLayout,
114+
QSysInfo::prettyProductName(),
115+
QSysInfo::currentCpuArchitecture(),
116+
tr("Underlying platform."));
117+
#endif
118+
112119
vboxLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding));
113120
ui->scrollAreaComponentsWidget->setLayout(vboxLayout);
114121
}

src/omodsim.plist.in

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3+
<plist version="1.0">
4+
<dict>
5+
<key>CFBundleExecutable</key>
6+
<string>@PROJECT_NAME@</string>
7+
<key>CFBundleIconFile</key>
8+
<string>omodsim.icns</string>
9+
<key>CFBundleIdentifier</key>
10+
<string>org.ananev.omodsim</string>
11+
<key>CFBundleInfoDictionaryVersion</key>
12+
<string>6.0</string>
13+
<key>CFBundleName</key>
14+
<string>@PRODUCT_NAME@</string>
15+
<key>CFBundlePackageType</key>
16+
<string>APPL</string>
17+
<key>CFBundleShortVersionString</key>
18+
<string>@PROJECT_VERSION@</string>
19+
<key>CFBundleVersion</key>
20+
<string>@VERSION_MAJOR@.@VERSION_MINOR@.@VERSION_PATCH@</string>
21+
<key>NSHighResolutionCapable</key>
22+
<true/>
23+
<key>NSHumanReadableCopyright</key>
24+
<string>Copyright 2023-@CURRENT_YEAR@ Alexandr Ananev. All rights reserved.</string>
25+
<key>LSMinimumSystemVersion</key>
26+
<string>11.0</string>
27+
</dict>
28+
</plist>

src/res/omodsim.icns

29.2 KB
Binary file not shown.

0 commit comments

Comments
 (0)