-
Notifications
You must be signed in to change notification settings - Fork 66
Build DFTFringe on macOS and publish DMGs from CI #348
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
Lucassifoni
wants to merge
12
commits into
githubdoe:master
Choose a base branch
from
Lucassifoni:macos-build
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
944681e
Add macOS CI build and refresh the macOS qmake configuration
Lucassifoni 5197d8a
Use opencv@4 on macOS instead of the OpenCV 5 formula
Lucassifoni 1684755
Point the macOS include path at qwt's framework headers
Lucassifoni d3b88f6
Let Boost.Stacktrace build on macOS
Lucassifoni d6daa55
Add the bundle version keys when qmake has not emitted them
Lucassifoni c418048
Link only the OpenCV modules DFTFringe uses and publish the disk images
Lucassifoni 41ce241
Sign the bundle inside out rather than with codesign --deep
Lucassifoni 03dc54b
Document building and installing DFTFringe on macOS
Lucassifoni 8d37493
Ship the colour maps in Contents/Resources so the bundle can be signed
Lucassifoni c69cd77
Merge both architectures into one universal disk image
Lucassifoni e4db87e
Shorten the macOS README sections and add the build badge
Lucassifoni 8446dfe
Rewrites Mac OS Launch section to be clearer
Lucassifoni File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,177 @@ | ||
| name: build-macos | ||
| on: | ||
| push: | ||
| branches: | ||
| - master | ||
| pull_request: | ||
| workflow_dispatch: | ||
| workflow_call: | ||
|
|
||
| jobs: | ||
| # Builds one bundle per architecture. They are merged into a single universal | ||
| # bundle by the job below, so nothing is signed here: lipo would invalidate the | ||
| # signature anyway. | ||
| build-macos: | ||
| strategy: | ||
| fail-fast: false | ||
| matrix: | ||
| include: | ||
| - os: macos-15 | ||
| arch: arm64 | ||
| - os: macos-15-intel | ||
| arch: x86_64 | ||
| runs-on: ${{ matrix.os }} | ||
| steps: | ||
| - uses: actions/checkout@v6 | ||
|
|
||
| # opencv@4 rather than opencv, which is now OpenCV 5, to stay on the same | ||
| # major version as the Linux and Windows builds. | ||
| - name: Install dependencies | ||
| run: brew install qt qwt opencv@4 armadillo | ||
|
|
||
| # Homebrew is in /usr/local on Intel and /opt/homebrew on Apple silicon, | ||
| # and Qt6 is split across several kegs. | ||
| - name: Resolve Homebrew layout | ||
| run: | | ||
| QT_PREFIX="$(brew --prefix qt)" | ||
| if [ ! -x "$QT_PREFIX/bin/qmake" ]; then QT_PREFIX="$(brew --prefix qtbase)"; fi | ||
| echo "QT_PREFIX=$QT_PREFIX" >> "$GITHUB_ENV" | ||
| echo "PKG_CONFIG_PATH=$(brew --prefix qwt)/lib/pkgconfig:$(brew --prefix opencv@4)/lib/pkgconfig:$(brew --prefix armadillo)/lib/pkgconfig:$(brew --prefix)/lib/pkgconfig" >> "$GITHUB_ENV" | ||
|
|
||
| # Same naming as build-windows.yml. | ||
| - name: Resolve version strings | ||
| run: | | ||
| if [ "${{ github.event_name }}" = "pull_request" ]; then | ||
| WORKFLOW_VERSION="${{ github.event.pull_request.head.sha }}_${{ github.event.pull_request.base.sha }}" | ||
| elif [ "${{ startsWith(github.ref, 'refs/tags/v') }}" = "true" ]; then | ||
| WORKFLOW_VERSION="${{ github.ref_name }}" | ||
| else | ||
| WORKFLOW_VERSION="${{ github.sha }}" | ||
| fi | ||
| # CFBundleShortVersionString only accepts a dotted number, so a commit | ||
| # sha cannot go there. | ||
| BUNDLE_VERSION="$(printf '%s' "$WORKFLOW_VERSION" | sed -nE 's/^v?([0-9]+\.[0-9]+\.[0-9]+).*$/\1/p')" | ||
| if [ -z "$BUNDLE_VERSION" ]; then BUNDLE_VERSION="0.0.0"; fi | ||
| echo "WORKFLOW_VERSION=$WORKFLOW_VERSION" >> "$GITHUB_ENV" | ||
| echo "BUNDLE_VERSION=$BUNDLE_VERSION" >> "$GITHUB_ENV" | ||
|
|
||
| - name: Find and Replace MY_AUTOMATED_VERSION_STRING | ||
| run: sed -i '' "s/MY_AUTOMATED_VERSION_STRING/${WORKFLOW_VERSION}/" DFTFringe.pro | ||
|
|
||
| - name: Configure | ||
| run: | | ||
| "$QT_PREFIX/bin/qmake" DFTFringe.pro CONFIG+=release | ||
|
|
||
| - uses: ammaraskar/gcc-problem-matcher@master | ||
| - run: echo "::add-matcher::.github/matcher/uic_matcher.json" | ||
| - name: Build | ||
| run: make -j$(sysctl -n hw.ncpu) | ||
| - run: echo "::remove-matcher owner=uic-problem-matcher::" | ||
|
|
||
| - name: Bundle dependencies | ||
| run: | | ||
| "$QT_PREFIX/bin/macdeployqt" build/release/DFTFringe.app -verbose=1 | ||
| # Contents/MacOS may hold nothing but code or codesign rejects the | ||
| # bundle. colormapviewerdlg falls back to Contents/Resources on macOS. | ||
| cp -R ColorMaps build/release/DFTFringe.app/Contents/Resources/ | ||
| # qmake only templates the version keys when VERSION is a dotted | ||
| # number, so for untagged builds they may be absent rather than wrong. | ||
| PLIST=build/release/DFTFringe.app/Contents/Info.plist | ||
| for key in CFBundleShortVersionString CFBundleVersion; do | ||
| /usr/libexec/PlistBuddy -c "Set :$key $BUNDLE_VERSION" "$PLIST" 2>/dev/null \ | ||
| || /usr/libexec/PlistBuddy -c "Add :$key string $BUNDLE_VERSION" "$PLIST" | ||
| done | ||
|
|
||
| - name: Verify the bundle is self contained | ||
| run: | | ||
| otool -L build/release/DFTFringe.app/Contents/MacOS/DFTFringe \ | ||
| | tail -n +2 | awk '{print $1}' \ | ||
| | grep -vE "^(@rpath|@executable_path|/usr/lib|/System)" \ | ||
| && { echo "bundle references paths outside itself"; exit 1; } || true | ||
|
|
||
| # Tarred because upload-artifact does not preserve the symlinks inside the | ||
| # Qt frameworks. | ||
| - name: Upload bundle | ||
| run: tar czf DFTFringe-${{ matrix.arch }}.tar.gz -C build/release DFTFringe.app | ||
| - uses: actions/upload-artifact@v7 | ||
| with: | ||
| name: DFTFringe-macos-${{ matrix.arch }}-bundle | ||
| path: DFTFringe-${{ matrix.arch }}.tar.gz | ||
| retention-days: 1 | ||
|
|
||
| # Merges the two bundles into one universal application, signs it and wraps it | ||
| # in a disk image. Users get a single download that runs on both architectures. | ||
| universal-dmg: | ||
| needs: build-macos | ||
| runs-on: macos-15 | ||
| steps: | ||
| - uses: actions/download-artifact@v8 | ||
| with: | ||
| pattern: DFTFringe-macos-*-bundle | ||
| merge-multiple: true | ||
|
|
||
| - name: Resolve version strings | ||
| run: | | ||
| if [ "${{ github.event_name }}" = "pull_request" ]; then | ||
| WORKFLOW_VERSION="${{ github.event.pull_request.head.sha }}_${{ github.event.pull_request.base.sha }}" | ||
| elif [ "${{ startsWith(github.ref, 'refs/tags/v') }}" = "true" ]; then | ||
| WORKFLOW_VERSION="${{ github.ref_name }}" | ||
| else | ||
| WORKFLOW_VERSION="${{ github.sha }}" | ||
| fi | ||
| echo "WORKFLOW_VERSION=$WORKFLOW_VERSION" >> "$GITHUB_ENV" | ||
|
|
||
| - name: Merge the two architectures | ||
| run: | | ||
| mkdir arm64 x86_64 | ||
| tar xzf DFTFringe-arm64.tar.gz -C arm64 | ||
| tar xzf DFTFringe-x86_64.tar.gz -C x86_64 | ||
| ARM="$PWD/arm64/DFTFringe.app" | ||
| INTEL="$PWD/x86_64/DFTFringe.app" | ||
|
|
||
| # Homebrew resolves formulae independently on the two runners, so a | ||
| # version bump landing between the jobs would give the bundles | ||
| # different contents. Merging those silently would ship an | ||
| # application half built against two different sets of libraries. | ||
| diff <(cd "$ARM" && find . | sort) <(cd "$INTEL" && find . | sort) \ | ||
| || { echo "the two bundles do not contain the same files"; exit 1; } | ||
|
|
||
| cp -R "$ARM" DFTFringe.app | ||
| UNIVERSAL="$PWD/DFTFringe.app" | ||
| find "$UNIVERSAL" -type f | while read -r f; do | ||
| rel="${f#$UNIVERSAL/}" | ||
| if file -b "$f" | grep -q "Mach-O"; then | ||
| lipo -create "$ARM/$rel" "$INTEL/$rel" -output "$f" | ||
| fi | ||
| done | ||
|
|
||
| echo "--- architectures in the merged executable:" | ||
| lipo -info "$UNIVERSAL/Contents/MacOS/DFTFringe" | ||
|
|
||
| # Signed inside out rather than with --deep, which Apple deprecates for | ||
| # signing. arm64 code has to carry at least an ad-hoc signature to run at | ||
| # all, and lipo invalidated whatever was there before. | ||
| - name: Ad-hoc sign | ||
| run: | | ||
| APP=DFTFringe.app | ||
| find "$APP/Contents/Frameworks" "$APP/Contents/PlugIns" \ | ||
| \( -name "*.dylib" -o -name "*.so" \) \ | ||
| -exec codesign --force --sign - --timestamp=none {} \; 2>/dev/null || true | ||
| find "$APP/Contents/Frameworks" -maxdepth 1 -name "*.framework" \ | ||
| -exec codesign --force --sign - --timestamp=none {} \; 2>/dev/null || true | ||
| codesign --force --sign - --timestamp=none "$APP" | ||
| codesign --verify --deep --strict --verbose=2 "$APP" | ||
|
|
||
| - name: Create disk image | ||
| run: | | ||
| STAGE="$(mktemp -d)/DFTFringe" | ||
| mkdir -p "$STAGE" | ||
| cp -R DFTFringe.app "$STAGE/" | ||
| ln -s /Applications "$STAGE/Applications" | ||
| hdiutil create -volname "DFTFringe" -srcfolder "$STAGE" -ov -format UDZO \ | ||
| "DFTFringe-${WORKFLOW_VERSION}.dmg" | ||
|
|
||
| - uses: actions/upload-artifact@v7 | ||
| with: | ||
| name: DFTFringe-macos-build-artifact | ||
| path: DFTFringe-${{ env.WORKFLOW_VERSION }}.dmg |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,6 @@ | ||
| # DFTFringe | ||
|
|
||
| [](https://github.com/githubdoe/DFTFringe/actions/workflows/build-windows.yml) [](https://github.com/githubdoe/DFTFringe/actions/workflows/build-linux.yml) | ||
| [](https://github.com/githubdoe/DFTFringe/actions/workflows/build-windows.yml) [](https://github.com/githubdoe/DFTFringe/actions/workflows/build-linux.yml) [](https://github.com/githubdoe/DFTFringe/actions/workflows/build-macos.yml) | ||
|
|
||
|
|
||
| # Introduction | ||
|
|
@@ -50,9 +50,57 @@ cd .. | |
| make -j4 | ||
| ``` | ||
|
|
||
| # How to install DFTFringe on MacOS | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's quite strange to have
Maybe reorder to :
|
||
|
|
||
| Download the disk image from the | ||
| [latest release](https://github.com/githubdoe/dftfringe/releases/latest), open it | ||
| and drag DFTFringe into Applications. The required OS is MacOS 15 or later. | ||
|
|
||
| **The app is not notarised yet**, so macOS refuses to open it the first time and | ||
| will just quit without saying anything. To launch it : | ||
|
|
||
| Right-click it -> "Open", then open "System Settings", go to "Privacy & Security", | ||
| find the DFTFringe security warning, and click "Open Anyway" | ||
|
|
||
| Or, from the terminal : | ||
|
|
||
| ``` | ||
| xattr -dr com.apple.quarantine /Applications/DFTFringe.app | ||
|
atsju marked this conversation as resolved.
|
||
| ``` | ||
|
|
||
| # How to build DFTFringe on MacOS | ||
|
|
||
| :building_construction: Under construction :building_construction: | ||
| Dependencies come from [Homebrew](https://brew.sh). Use `opencv@4` and not | ||
| `opencv`, which is OpenCV 5 now: | ||
|
|
||
| ``` | ||
| brew install qt qwt opencv@4 armadillo | ||
| ``` | ||
|
|
||
| qmake finds them through pkg-config, so nothing is hard coded in the project file. | ||
| `opencv@4` is keg-only and Qt6 is split across several kegs, so point | ||
| `PKG_CONFIG_PATH` at them: | ||
|
|
||
| ``` | ||
| export PKG_CONFIG_PATH="$(brew --prefix qwt)/lib/pkgconfig:$(brew --prefix opencv@4)/lib/pkgconfig:$(brew --prefix armadillo)/lib/pkgconfig:$(brew --prefix)/lib/pkgconfig" | ||
| $(brew --prefix qt)/bin/qmake DFTFringe.pro CONFIG+=release | ||
| make -j$(sysctl -n hw.ncpu) | ||
| ``` | ||
|
|
||
| That gives you `build/release/DFTFringe.app`, still linked against Homebrew. | ||
| `macdeployqt` copies the libraries in and rewrites their install names. The colour | ||
| maps have to go in `Contents/Resources`, because `Contents/MacOS` may hold nothing | ||
| but code and `codesign` rejects the bundle otherwise: | ||
|
|
||
| ``` | ||
| $(brew --prefix qt)/bin/macdeployqt build/release/DFTFringe.app | ||
| cp -R ColorMaps build/release/DFTFringe.app/Contents/Resources/ | ||
| open build/release/DFTFringe.app | ||
| ``` | ||
|
|
||
| A build targets the machine it runs on, since Homebrew libraries are single | ||
| architecture. The CI builds both and merges them with `lipo` into the universal | ||
| application that ships. See `.github/workflows/build-macos.yml`. | ||
|
|
||
| # How to build DFTFringe on Windows | ||
|
|
||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.