Build DFTFringe on macOS and publish DMGs from CI - #348
Conversation
|
Hi,
On the choices made, the biggest are that it isn’t an universal intel + arm build but two builds, and that it only produces executables for Mac OS > 15. I’m willing to put as much time on this as needed. Best, |
atsju
left a comment
There was a problem hiding this comment.
Thank you very much for this work ! It's really valuable for Mac users.
I see no problem having a different installer between windows and Mac.
| arch: x86_64 | ||
| runs-on: ${{ matrix.os }} | ||
| steps: | ||
| - uses: actions/checkout@v4 |
There was a problem hiding this comment.
Please update to latest version. I'm working on updating the rest of the workflows and will do a PR soon.
| "DFTFringe-${WORKFLOW_VERSION}-${{ matrix.arch }}.dmg" | ||
|
|
||
| - name: Upload Artifact | ||
| uses: actions/upload-artifact@v4 |
| name: DFTFringe-windows-build-artifact | ||
| - uses: actions/download-artifact@v4 | ||
| with: | ||
| pattern: DFTFringe-macos-*-build-artifact |
There was a problem hiding this comment.
I know nothing about MAC.
AI told me you could do an universal installer : lipo -create arm64_app x86_64_app -output universal_app
I let you judge what is best
There was a problem hiding this comment.
Honestly I'm torn on this one. My personal preference is to just grab the ARM build when there is both universal and arch-specific offered, but I don't know what people actually prefer. Maybe we could offer both the fat package with lipo and the two arch-specific builds ? Most software available for Mac does that.
There was a problem hiding this comment.
I would recommend the universal build. Remember we are developpers but most users prefer something simple over something optimized. They won't see the difference and is will be misleading.
I you want to distribute all 3, it's also possible.
- Universal build (main download)
- ARM64 build (alternative)
- x86_64 build (alternative)
|
@atsju I'll wait for your CI-related PRs to land before rebasing and finishing |
The macx block had not been touched since the Qt5 era and no longer matched the file it lives in: - pkg-config names were opencv (OpenCV 3) and Qt5Qwt6, but DFTFringe.pro is now the Qt6 project file - zlib was missing from LIBS, which cnpy.cpp needs since npz support landed - QMAKE_MKDIR and QMAKE_PKG_CONFIG hard coded conflicting Homebrew prefixes, one Intel and one Apple silicon - QMAKE_FULL_VERSION was set to the literal string APP_VERSION - INCLUDEPATH had an -I prefix and pointed at the plugins directory The new build-macos workflow builds one disk image per architecture on macos-15 and macos-15-intel. A universal binary would require rebuilding every Homebrew dependency for both architectures, so it is left out. The bundle is ad-hoc signed only; notarisation needs an Apple Developer ID. Refs githubdoe#24, githubdoe#118 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Homebrew's opencv formula moved to OpenCV 5, whose pkg-config name is opencv5, so the configure step could not find opencv4. The CI now installs opencv@4 to stay on the same major version as the Linux and Windows builds. The project file falls back to opencv5 when opencv4 is absent so that a local checkout with only the current opencv formula still configures. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Homebrew builds qwt as a macOS framework. Its pkg-config file advertises an include directory that does not hold the headers, so every translation unit including <qwt_plot.h> failed to compile. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Boost.Stacktrace guards _Unwind_Backtrace behind _GNU_SOURCE, which is a glibc convention. On macOS the function comes from Apple's libunwind and needs no such define, so main.cpp was the only translation unit that failed to compile. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
qmake only templates CFBundleShortVersionString and CFBundleVersion when VERSION is a dotted number. Untagged builds carry a commit sha, so the keys are absent rather than wrong and PlistBuddy Set had nothing to act on. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
opencv4.pc lists every module, so the bundle carried dnn, gapi and the OpenVINO stack and weighed 112 MB on arm64 and 141 MB on x86_64. Link the same six modules as the Linux and Windows builds instead. make-release now builds macOS alongside Windows and attaches both disk images to the draft release. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Apple deprecates --deep for signing and it can leave nested code invalidly signed. This bundle nests around twenty frameworks plus the Qt plugins, so sign those first and the app last, then verify the result. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Covers the Homebrew dependencies, why opencv@4 rather than opencv, the PKG_CONFIG_PATH needed for the keg-only and split kegs, bundling with macdeployqt, and the Gatekeeper workaround the unsigned disk images need. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Contents/MacOS may hold nothing but code. Copying ColorMaps beside the executable made codesign report the .cmp files as unsigned code objects and invalidated the whole bundle signature, which is why macOS killed the app when it was launched from the Finder while running the binary directly still worked. colormapviewerdlg falls back to Contents/Resources on macOS, where the maps now live. The dialog looked next to the executable, which no macOS build has ever had, so this also makes the colour map viewer work for the first time. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Follows the review: a single download is less confusing than asking users to pick an architecture, and they cannot tell the difference anyway. The two matrix jobs now build a bundle each and a third job lipos every Mach-O file in them into one universal application, signs it and wraps it in a disk image. Signing happens only after the merge, since lipo invalidates it. The merge refuses to run if the two bundles do not contain the same files. Homebrew resolves formulae independently on the two runners, so a version bump landing between the jobs would otherwise silently produce an application built against two different sets of libraries. Also updates the action versions to match githubdoe#350 and drops the working branch from the push trigger. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
32376dd to
9b8ffad
Compare
Rewritten with less fluff, and updated for the universal disk image. Drops the notes about OpenCV module selection and the qwt framework headers, which are explained where they are done in DFTFringe.pro rather than repeated here. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
It looks like the lipo'd DMG will be 169MB. As of today's standards it's okay for me. I'll continue cleaning up and check if I manage to handle the missing color maps. |
|
The software won't open unless the user adds a security exception, this is normal unless signed with a valid Apple Developer ID (99$/year). I don't have one as of today. If noone in the team has one, it will have to stay that way. I added shorter instructions in the Readme. |
|
I'm not a MAC person, so no. Possibly @Interferometry has one? He did some work to get DFTF to build on the Mac a few years ago. |
|
I re-downloaded their 6.2 build and it looks like it was indeed signed, I don't get a security exemption request. |
|
Is it possible/easy to explain how to do this in the installer for mac people who don't know how? Or am I being silly? As a minimum please explain how to do it here so that I can mention this on the interferometry group when we release this. Or maybe a link to a youtube video on how to do it. |
|
Another issue to fix before considering the build correct, I did not try to launch it graphically (by double-clicking) before today, and it crashes due to a non-writable root directory issue : #354 |
| make -j4 | ||
| ``` | ||
|
|
||
| # How to install DFTFringe on MacOS |
There was a problem hiding this comment.
It's quite strange to have
- install Win
- build Linux
- install Mac
- build Mac
- build Win
Maybe reorder to :
- install Win
- install Mac
- build Linux (there is no install)
- build Mac or Win
- build Win or Mac
Note : this was done by Opus 5, picking up Dan's work in 75d9cc6. I'm happy to work and help as long as needed on it but will be AI-assisted since QT isn't my cup of tea.
---- BEGIN AI-assisted summary ----
Problems since the 2023 Mac build :
opencv(OpenCV 3) andQt5Qwt6(qwt built against Qt5), butDFTFringe.prois now the Qt6 project file.-lzwas missing, whichcnpy.cpphas needed since npz support landed. The linkcould not have succeeded.
QMAKE_MKDIRandQMAKE_PKG_CONFIGhard coded two different Homebrew prefixes, oneIntel and one Apple silicon, so the block could not work on either machine.
QMAKE_FULL_VERSIONwas set to the literal stringAPP_VERSION.INCLUDEPATHhad a stray-Iprefix and pointed at the plugins directory.Everything now comes from pkg-config, so no Homebrew prefix is hard coded and the same project file works on both architectures.
CI
build-macos.ymlbuilds onmacos-15andmacos-15-inteland uploads one disk imageper architecture.
make-release.ymlattaches both to the draft release alongside theWindows installer.
Not an universal binary. Homebrew ships single-architecture libraries, so a universal
build would mean rebuilding opencv, armadillo and qwt for both architectures and merging
them with
lipo.opencv@4, notopencv. Homebrew'sopencvformula is now OpenCV 5.opencv@4keeps all three platforms on the same major version.
Potential problems
Minimum macOS is 15.
macos-13andmacos-14github runners are retired or deprecated, so the binaryinherits that floor. The 6.2 release required Ventura. Going lower means building the
dependencies from source with an explicit deployment target.
The disk images are not notarised. That needs a paid Apple Developer ID. macOS
refuses to open the app from the Finder, users have to clear the quarantine flag once.
This is documented in the README. The workflow has no signing machinery, so adding notarisation later is purely additive.
The bundle is ad-hoc signed, which is a separate matter: arm64 code must carry at least an ad-hoc signature to execute at all, and
macdeployqtinvalidates the linker's signature when it rewrites install names.Single source change
colormapviewerdlglooked forColorMapsinapplicationDirPath(), which inside abundle is
Contents/MacOS. That directory may hold nothing but code:codesignreportsthe
.cmpfiles as unsigned code objects and the whole bundle signature is rejected. Themaps ship in
Contents/Resourcesand the lookup falls back there underQ_OS_MAC. The6.2 bundle has them in neither location, so the colour map viewer has never worked on
macOS.
Correctness
This branch makes DFTFringe build, it does not produce correct results on its
own without the bool mask PR.