Compare commits

..
Author SHA1 Message Date
gronod 0672ab7fea Merge pull request 'ci(gitea): build intel and arm64 in matrix and merge into universal binary' (#46) from development into main
macOS Release Build / build (arm64, macOS_arm64_bin, arm64-apple-darwin) (push) Successful in 5m23s
Linux x86_64 Release Build / build (push) Successful in 9m0s
Windows x86_64 Release Build / build (push) Successful in 8m25s
macOS Release Build / build (x86_64, macOS_x86_64_bin, x86_64-apple-darwin) (push) Successful in 5m35s
macOS Release Build / universal (push) Failing after 19s
Reviewed-on: #46
2026-09-05 17:51:58 +01:00
gronod f837314f5c ci(gitea): build intel and arm64 in matrix and merge into universal binary 2026-09-05 17:48:53 +01:00
gronod e80e41beb9 Merge pull request 'Development' (#45) from development into main
Linux x86_64 Release Build / build (push) Successful in 11m36s
Windows x86_64 Release Build / build (push) Canceled after 2m47s
macOS x86_64 Release Build / build (push) Canceled after 0s
Reviewed-on: #45
2026-09-05 16:23:16 +01:00
gronod 851c7eece3 chore: update macos runner to use macos label in build workflow 2026-09-05 16:22:41 +01:00
gronod b67c7ca318 Merge pull request 'Amended gitea runner tag to macos-latest' (#44) from fix/dispcal_SIGSEV into development
Reviewed-on: #44
2026-09-05 16:19:49 +01:00
gronod 7744518b87 Amended gitea runner tag to macos-latest 2026-09-05 16:18:31 +01:00
gronod c5c06f5dc6 Merge pull request 'Merge development into main (CCOPTFLAG fix)' (#43) from development into main
Windows x86_64 Release Build / build (push) Failing after 1m27s
macOS x86_64 Release Build / build (push) Successful in 4m23s
Linux x86_64 Release Build / build (push) Successful in 10m53s
Merge pull request #43 from development into main
2026-09-05 16:05:24 +01:00
gronod 18c6a4c89d Merge pull request 'Add CCOPTFLAG warning tolerance to macOS Gitea workflow' (#42) from fix/dispcal_SIGSEV into development
Merge pull request #42 from fix/dispcal_SIGSEV into development
2026-09-05 16:05:15 +01:00
Gordon Bolton c4cc3de0ec ci(gitea): pass compiler warning tolerance flags in CCOPTFLAG for modern Apple Clang 2026-09-05 16:05:07 +01:00
gronod 931d92cddf Merge pull request 'Merge development into main (macOS CI fix)' (#41) from development into main
Windows x86_64 Release Build / build (push) Failing after 1m22s
macOS x86_64 Release Build / build (push) Failing after 2m47s
Linux x86_64 Release Build / build (push) Successful in 9m52s
Merge pull request #41 from development into main
2026-09-05 15:59:11 +01:00
gronod 16eb647b1a Merge pull request 'Fix macOS ftjam setup in Gitea Actions workflow' (#40) from fix/dispcal_SIGSEV into development
Merge pull request #40 from fix/dispcal_SIGSEV into development
2026-09-05 15:59:02 +01:00
Gordon Bolton 20bce9dff4 ci(gitea): use curl, make jam0, and non-root install for macOS ftjam setup 2026-09-05 15:58:54 +01:00
gronod edeb6dcf67 Merge pull request 'Merge development into main (v3.5.0-ICCery1.7)' (#39) from development into main
macOS x86_64 Release Build / build (push) Failing after 12s
Windows x86_64 Release Build / build (push) Successful in 8m22s
Linux x86_64 Release Build / build (push) Successful in 11m48s
Merge pull request #39 from development into main
2026-09-05 15:43:27 +01:00
gronod cb5e740688 Merge pull request 'Fix: dispcal SIGSEGV and add Gitea macOS runner workflow' (#38) from fix/dispcal_SIGSEV into development
Merge pull request #38 from fix/dispcal_SIGSEV into development
2026-09-05 15:43:14 +01:00
Gordon Bolton 5392458515 ci(gitea): add macos-14 x86_64 runner workflow using upload-artifact@v3 2026-09-05 15:42:50 +01:00
Gordon Bolton 39cad74c43 Fix SIGSEGV in i1Pro 2 teardown and cleanup
Windows x86_64 Release Build / build (push) Successful in 8m50s
Linux x86_64 Release Build / build (push) Successful in 21m53s
- Relocate LED turn-off to i1pro_close_port() before closing communication port
- Guard LED turn-off and log updates against NULL pointers and closed ports in del_i1proimp()
- Ensure clean termination, unblock, and joining of i1pro switch and trigger threads in both i1pro_close_port() and del_i1proimp()
- Protect against NULL terminate callback on Unix/macOS
2026-09-04 14:39:59 +01:00
gronod d271bb603d Merge pull request 'Development' (#36) from development into main
Windows x86_64 Release Build / build (push) Successful in 8m5s
Linux x86_64 Release Build / build (push) Successful in 9m22s
Reviewed-on: #36
2026-09-01 12:10:31 +01:00
gronod d1bf83928d Merge pull request 'Fix update macos runners' (#35) from fix-update-macos-runners into development
Reviewed-on: #35
2026-09-01 12:10:00 +01:00
gronod e194514264 Update .github/workflows/build-macos.yml 2026-09-01 12:09:14 +01:00
gronod 2261ebd331 Merge pull request 'Development' (#34) from development into main
Windows x86_64 Release Build / build (push) Failing after 1m10s
Linux x86_64 Release Build / build (push) Successful in 9m58s
Reviewed-on: #34
2026-09-01 11:22:12 +01:00
gronod de3065f4cc Merge pull request 'Update .github/workflows/build-macos.yml' (#33) from update-macos-act-runner into development
Reviewed-on: #33
2026-09-01 11:21:15 +01:00
gronod 9c3982354d Update .github/workflows/build-macos.yml
Update action runner for MacOS to macos-latest
2026-09-01 11:20:43 +01:00
gronod 86e692ecda ci(macos): add ad-hoc codesigning and signature verification to macOS workflow 2026-09-01 10:18:18 +01:00
gronod f30d16816f fix(package): apply ad-hoc code signatures to macOS Mach-O binaries in makepackagebin.sh 2026-09-01 10:18:10 +01:00
gronod cf93305fdd ci(macos): add ad-hoc codesigning and signature verification to macOS workflow
Windows x86_64 Release Build / build (push) Successful in 8m21s
Linux x86_64 Release Build / build (push) Successful in 49m44s
2026-09-01 10:17:34 +01:00
gronod 1eb72e865b fix(package): apply ad-hoc code signatures to macOS Mach-O binaries in makepackagebin.sh 2026-09-01 10:17:06 +01:00
gronod e0f86eec29 Merge development into main (v3.5.0-ICCery.1.4)
Linux x86_64 Release Build / build (push) Successful in 9m37s
Windows x86_64 Release Build / build (push) Successful in 9m38s
Merge pull request 'Merge development into main (v3.5.0-ICCery.1.4)' (#31) from development into main
2026-09-01 00:16:56 +01:00
gronod c196912bed Fix: Handle non-Mach-O files during macOS universal binary lipo assembly
Merge pull request 'Fix: Handle non-Mach-O files during macOS universal binary lipo assembly' (#30) from fix/macos-universal-non-macho-lipo into development
2026-09-01 00:16:49 +01:00
gronod ebbc675297 fix(ci): handle non-Mach-O files like metainfo.xml during universal lipo assembly 2026-09-01 00:16:11 +01:00
gronod 21d59d891c Merge development into main (v3.5.0-ICCery.1.3)
Windows x86_64 Release Build / build (push) Failing after 1m12s
Linux x86_64 Release Build / build (push) Successful in 8m34s
Merge pull request 'Merge development into main (v3.5.0-ICCery.1.3)' (#29) from development into main
2026-09-01 00:03:47 +01:00
gronod 7b3ebf4c87 Feature: Build and publish macOS Universal Binary release archive
Merge pull request 'Feature: Build and publish macOS Universal Binary release archive' (#28) from feature/issue-27-macos-universal-binaries into development
2026-09-01 00:03:36 +01:00
gronod cc61e2aa4c feat(ci): build and publish macOS universal binary release archive (fixes #27) 2026-09-01 00:02:53 +01:00
gronod a07a5d638d Merge pull request 'Merge development into main (v3.5.0-ICCery.1.2)' (#26) from development into main
Windows x86_64 Release Build / build (push) Successful in 9m11s
Linux x86_64 Release Build / build (push) Successful in 9m26s
Merge pull request #26 from development into main
2026-08-29 14:39:39 +01:00
gronod 5b75dd4284 Merge pull request 'Fix: Use PeekNamedPipe to prevent blocking ReadFile on anonymous stdin pipes' (#25) from fix/win32-pipe-peek-named-pipe into development
Merge pull request #25 from fix/win32-pipe-peek-named-pipe into development
2026-08-29 14:39:29 +01:00
gronod fb6b37bade fix(spectro): use PeekNamedPipe to prevent blocking ReadFile on anonymous stdin pipes (fixes #24) 2026-08-29 14:39:08 +01:00
gronod b02df94744 Merge pull request 'Merge development into main (v3.5.0-ICCery.1.1)' (#23) from development into main
Windows x86_64 Release Build / build (push) Successful in 9m34s
Linux x86_64 Release Build / build (push) Successful in 9m41s
Merge pull request #23 from development into main
2026-08-28 20:23:45 +01:00
gronod 429c772e4a Merge pull request 'Fix: Sanitize manifest CRLF line endings and complete Windows release packaging' (#22) from fix/windows-package-crlf-manifests into development
Merge pull request #22 from fix/windows-package-crlf-manifests into development
2026-08-28 20:23:35 +01:00
gronod d843716e8b fix(packaging): sanitize CRLF line endings in manifest files and ensure catalog files exist (fixes #21) 2026-08-28 20:23:09 +01:00
gronod fe0230b3d5 Merge branch 'development' into main
Windows x86_64 Release Build / build (push) Successful in 7m43s
Linux x86_64 Release Build / build (push) Successful in 10m3s
2026-08-26 01:11:26 +01:00
gronod 885fa3fee8 Merge pull request 'Development' (#18) from development into main
Windows x86_64 Release Build / build (push) Has been cancelled
Linux x86_64 Release Build / build (push) Has been cancelled
Reviewed-on: #18
2026-08-26 01:02:30 +01:00
12 changed files with 525 additions and 69 deletions
+198
View File
@@ -0,0 +1,198 @@
name: macOS Release Build
on:
push:
tags:
- 'v*'
workflow_dispatch:
jobs:
build:
strategy:
matrix:
include:
- arch: x86_64
machtype: x86_64-apple-darwin
artifact: macOS_x86_64_bin
- arch: arm64
machtype: arm64-apple-darwin
artifact: macOS_arm64_bin
runs-on: macos
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install ftjam
run: |
curl -fsSL -o ftjam.tar.gz https://sourceforge.net/projects/freetype/files/ftjam/2.5.2/ftjam-2.5.2.tar.gz/download || wget --no-check-certificate -q -O ftjam.tar.gz https://sourceforge.net/projects/freetype/files/ftjam/2.5.2/ftjam-2.5.2.tar.gz/download
tar -xzf ftjam.tar.gz
cd ftjam-2.5.2
make jam0 CC="cc -Wno-implicit-function-declaration -Wno-incompatible-pointer-types -Wno-int-conversion -Wno-implicit-int"
mkdir -p "$HOME/.local/bin"
cp jam0 "$HOME/.local/bin/jam"
echo "$HOME/.local/bin" >> $GITHUB_PATH
cp jam0 /usr/local/bin/jam 2>/dev/null || true
- name: Build ArgyllCMS
run: |
export PATH="$HOME/.local/bin:/usr/local/bin:$PATH"
export OSTYPE=darwin
export MACHTYPE=${{ matrix.machtype }}
export HOSTTYPE=${{ matrix.arch }}
export CCOPTFLAG="-O0 -Wno-error=implicit-function-declaration -Wno-error=incompatible-pointer-types -Wno-error=int-conversion -Wno-error=implicit-int"
jam -q -d2 -fJambase -j1 -sBUILTIN_TIFF=true -sBUILTIN_JPEG=true -sBUILTIN_PNG=true -sBUILTIN_Z=true -sBUILTIN_SSL=true install
- name: Ad-hoc Sign & Verify Binaries
run: |
for f in bin/*; do
if [ -f "$f" ] && file "$f" | grep -q "Mach-O"; then
echo "Ad-hoc signing $f"
codesign -f -s - "$f"
codesign -dvv "$f"
fi
done
- name: Smoke Tests
env:
ARGYLL_NOT_INTERACTIVE: "1"
ARGYLL_EXCLUDE_SERIAL_SCAN: "1"
run: |
./bin/dispcal -? || true
./bin/chartread -? || true
./bin/colprof -? || true
./bin/targen -? || true
- name: Package Release
run: |
export PATH="$HOME/.local/bin:/usr/local/bin:$PATH"
export OSTYPE=darwin
export MACHTYPE=${{ matrix.machtype }}
export HOSTTYPE=${{ matrix.arch }}
export CCOPTFLAG="-O0 -Wno-error=implicit-function-declaration -Wno-error=incompatible-pointer-types -Wno-error=int-conversion -Wno-error=implicit-int"
export NO_BUILD=1
./makepackagebin.sh
TAG="${{ github.ref_name }}"
SHORT_SHA="$(git rev-parse --short HEAD)"
echo "SHORT_SHA=${SHORT_SHA}" >> $GITHUB_ENV
mv Argyll_V*_${{ matrix.artifact }}.tgz "Argyll_${TAG}_${SHORT_SHA}_${{ matrix.artifact }}.tgz"
- name: Upload Raw Binaries
uses: actions/upload-artifact@v3
with:
name: raw-bin-${{ matrix.arch }}
path: bin/
- name: Upload Artifact
uses: actions/upload-artifact@v3
with:
name: Argyll_${{ github.ref_name }}_${{ env.SHORT_SHA }}_${{ matrix.artifact }}
path: Argyll_*_${{ matrix.artifact }}.tgz
- name: Upload Release Asset
if: startsWith(github.ref, 'refs/tags/')
uses: akkuman/gitea-release-action@v1
with:
token: ${{ secrets.GITHUB_TOKEN }}
name: Release ${{ github.ref_name }}
body: "Release ${{ github.ref_name }} built from commit ${{ github.sha }}"
files: Argyll_*_${{ matrix.artifact }}.tgz
universal:
needs: build
runs-on: macos
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Download x86_64 binaries
uses: actions/download-artifact@v3
with:
name: raw-bin-x86_64
path: raw-bin-x86_64
- name: Download arm64 binaries
uses: actions/download-artifact@v3
with:
name: raw-bin-arm64
path: raw-bin-arm64
- name: Create Universal Binaries
run: |
mkdir -p bin
for file in raw-bin-arm64/*; do
bin_name=$(basename "$file")
if [ -f "raw-bin-x86_64/$bin_name" ]; then
if file "raw-bin-arm64/$bin_name" | grep -q "Mach-O" && file "raw-bin-x86_64/$bin_name" | grep -q "Mach-O"; then
echo "Creating universal binary with lipo: $bin_name"
lipo -create "raw-bin-x86_64/$bin_name" "raw-bin-arm64/$bin_name" -output "bin/$bin_name"
chmod +x "bin/$bin_name"
codesign -f -s - "bin/$bin_name"
else
echo "Non Mach-O file, copying directly: $bin_name"
cp "$file" "bin/$bin_name"
fi
else
echo "Warning: $bin_name not found in raw-bin-x86_64, copying arm64 version"
cp "$file" "bin/$bin_name"
if file "bin/$bin_name" | grep -q "Mach-O"; then
codesign -f -s - "bin/$bin_name"
fi
fi
done
for file in raw-bin-x86_64/*; do
bin_name=$(basename "$file")
if [ ! -f "bin/$bin_name" ]; then
echo "Warning: $bin_name only found in raw-bin-x86_64, copying x86_64 version"
cp "$file" "bin/$bin_name"
if file "bin/$bin_name" | grep -q "Mach-O"; then
codesign -f -s - "bin/$bin_name"
fi
fi
done
- name: Verify Architecture & Code Signatures
env:
ARGYLL_NOT_INTERACTIVE: "1"
ARGYLL_EXCLUDE_SERIAL_SCAN: "1"
run: |
echo "=== Binary Architecture & Signature Verification ==="
for file in bin/*; do
if [ -f "$file" ] && file "$file" | grep -q "Mach-O"; then
file "$file"
codesign -dvv "$file"
fi
done
echo "=== Smoke Tests ==="
./bin/dispcal -? || true
./bin/chartread -? || true
./bin/colprof -? || true
./bin/targen -? || true
- name: Package Universal Release
run: |
export OSTYPE=darwin
export MACHTYPE=universal-apple-darwin
export HOSTTYPE=universal
export NO_BUILD=1
./makepackagebin.sh
TAG="${{ github.ref_name }}"
SHORT_SHA="$(git rev-parse --short HEAD)"
echo "SHORT_SHA=${SHORT_SHA}" >> $GITHUB_ENV
mv Argyll_V*_macOS_universal_bin.tgz "Argyll_${TAG}_${SHORT_SHA}_macOS_universal_bin.tgz"
- name: Upload Universal Artifact
uses: actions/upload-artifact@v3
with:
name: Argyll_${{ github.ref_name }}_${{ env.SHORT_SHA }}_macOS_universal_bin
path: Argyll_*_macOS_universal_bin.tgz
- name: Upload Universal Release Asset
if: startsWith(github.ref, 'refs/tags/')
uses: akkuman/gitea-release-action@v1
with:
token: ${{ secrets.GITHUB_TOKEN }}
name: Release ${{ github.ref_name }}
body: "Release ${{ github.ref_name }} built from commit ${{ github.sha }}"
files: Argyll_*_macOS_universal_bin.tgz
+9
View File
@@ -63,6 +63,15 @@ jobs:
echo "SHORT_SHA=${SHORT_SHA}" >> $GITHUB_ENV echo "SHORT_SHA=${SHORT_SHA}" >> $GITHUB_ENV
mv Argyll_V*_win64_exe.zip "Argyll_${TAG}_${SHORT_SHA}_win64_exe.zip" mv Argyll_V*_win64_exe.zip "Argyll_${TAG}_${SHORT_SHA}_win64_exe.zip"
- name: Verify Package Contents
run: |
ZIP_FILE=$(ls Argyll_*_win64_exe.zip)
echo "Verifying contents of ${ZIP_FILE}..."
unzip -l "${ZIP_FILE}" | grep "usb/ArgyllCMS.inf"
unzip -l "${ZIP_FILE}" | grep "usb/bin/amd64/libusb0.sys"
unzip -l "${ZIP_FILE}" | grep "doc/ArgyllDoc.html"
unzip -l "${ZIP_FILE}" | grep "ReadMe.txt"
- name: Upload Artifact - name: Upload Artifact
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v3
with: with:
+118 -2
View File
@@ -11,11 +11,11 @@ jobs:
strategy: strategy:
matrix: matrix:
include: include:
- os: macos-15-intel - os: macos-26-intel
arch: x86_64 arch: x86_64
machtype: x86_64-apple-darwin machtype: x86_64-apple-darwin
artifact: macOS_x86_64_bin artifact: macOS_x86_64_bin
- os: macos-15 - os: macos-latest
arch: arm64 arch: arm64
machtype: arm64-apple-darwin machtype: arm64-apple-darwin
artifact: macOS_arm64_bin artifact: macOS_arm64_bin
@@ -43,6 +43,16 @@ jobs:
export CCOPTFLAG="-O0" export CCOPTFLAG="-O0"
jam -q -d2 -fJambase -j1 -sBUILTIN_TIFF=true -sBUILTIN_JPEG=true -sBUILTIN_PNG=true -sBUILTIN_Z=true -sBUILTIN_SSL=true install jam -q -d2 -fJambase -j1 -sBUILTIN_TIFF=true -sBUILTIN_JPEG=true -sBUILTIN_PNG=true -sBUILTIN_Z=true -sBUILTIN_SSL=true install
- name: Ad-hoc Sign & Verify Binaries
run: |
for f in bin/*; do
if [ -f "$f" ] && file "$f" | grep -q "Mach-O"; then
echo "Ad-hoc signing $f"
codesign -f -s - "$f"
codesign -dvv "$f"
fi
done
- name: Smoke Tests - name: Smoke Tests
env: env:
ARGYLL_NOT_INTERACTIVE: "1" ARGYLL_NOT_INTERACTIVE: "1"
@@ -64,6 +74,12 @@ jobs:
echo "SHORT_SHA=${SHORT_SHA}" >> $GITHUB_ENV echo "SHORT_SHA=${SHORT_SHA}" >> $GITHUB_ENV
mv Argyll_V*_${{ matrix.artifact }}.tgz "Argyll_${TAG}_${SHORT_SHA}_${{ matrix.artifact }}.tgz" mv Argyll_V*_${{ matrix.artifact }}.tgz "Argyll_${TAG}_${SHORT_SHA}_${{ matrix.artifact }}.tgz"
- name: Upload Raw Binaries
uses: actions/upload-artifact@v4
with:
name: raw-bin-${{ matrix.arch }}
path: bin/
- name: Upload Artifact - name: Upload Artifact
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
@@ -77,3 +93,103 @@ jobs:
name: Release ${{ github.ref_name }} name: Release ${{ github.ref_name }}
body: "Release ${{ github.ref_name }} built from commit ${{ github.sha }}" body: "Release ${{ github.ref_name }} built from commit ${{ github.sha }}"
files: Argyll_*_${{ matrix.artifact }}.tgz files: Argyll_*_${{ matrix.artifact }}.tgz
universal:
needs: build
runs-on: macos-latest
permissions:
contents: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Download x86_64 binaries
uses: actions/download-artifact@v4
with:
name: raw-bin-x86_64
path: raw-bin-x86_64
- name: Download arm64 binaries
uses: actions/download-artifact@v4
with:
name: raw-bin-arm64
path: raw-bin-arm64
- name: Create Universal Binaries
run: |
mkdir -p bin
for file in raw-bin-arm64/*; do
bin_name=$(basename "$file")
if [ -f "raw-bin-x86_64/$bin_name" ]; then
if file "raw-bin-arm64/$bin_name" | grep -q "Mach-O" && file "raw-bin-x86_64/$bin_name" | grep -q "Mach-O"; then
echo "Creating universal binary with lipo: $bin_name"
lipo -create "raw-bin-x86_64/$bin_name" "raw-bin-arm64/$bin_name" -output "bin/$bin_name"
chmod +x "bin/$bin_name"
codesign -f -s - "bin/$bin_name"
else
echo "Non Mach-O file, copying directly: $bin_name"
cp "$file" "bin/$bin_name"
fi
else
echo "Warning: $bin_name not found in raw-bin-x86_64, copying arm64 version"
cp "$file" "bin/$bin_name"
if file "bin/$bin_name" | grep -q "Mach-O"; then
codesign -f -s - "bin/$bin_name"
fi
fi
done
for file in raw-bin-x86_64/*; do
bin_name=$(basename "$file")
if [ ! -f "bin/$bin_name" ]; then
echo "Warning: $bin_name only found in raw-bin-x86_64, copying x86_64 version"
cp "$file" "bin/$bin_name"
if file "bin/$bin_name" | grep -q "Mach-O"; then
codesign -f -s - "bin/$bin_name"
fi
fi
done
- name: Verify Architecture & Code Signatures
env:
ARGYLL_NOT_INTERACTIVE: "1"
ARGYLL_EXCLUDE_SERIAL_SCAN: "1"
run: |
echo "=== Binary Architecture & Signature Verification ==="
for file in bin/*; do
if [ -f "$file" ] && file "$file" | grep -q "Mach-O"; then
file "$file"
codesign -dvv "$file"
fi
done
echo "=== Smoke Tests ==="
./bin/dispcal -? || true
./bin/chartread -? || true
./bin/colprof -? || true
./bin/targen -? || true
- name: Package Universal Release
run: |
export OSTYPE=darwin
export MACHTYPE=universal-apple-darwin
export HOSTTYPE=universal
export NO_BUILD=1
./makepackagebin.sh
TAG="${{ github.ref_name }}"
SHORT_SHA="$(git rev-parse --short HEAD)"
echo "SHORT_SHA=${SHORT_SHA}" >> $GITHUB_ENV
mv Argyll_V*_macOS_universal_bin.tgz "Argyll_${TAG}_${SHORT_SHA}_macOS_universal_bin.tgz"
- name: Upload Universal Artifact
uses: actions/upload-artifact@v4
with:
name: Argyll_${{ github.ref_name }}_${{ env.SHORT_SHA }}_macOS_universal_bin
path: Argyll_*_macOS_universal_bin.tgz
- name: Upload Universal Release Asset
if: startsWith(github.ref, 'refs/tags/')
uses: softprops/action-gh-release@v2
with:
name: Release ${{ github.ref_name }}
body: "Release ${{ github.ref_name }} built from commit ${{ github.sha }}"
files: Argyll_*_macOS_universal_bin.tgz
+9
View File
@@ -65,6 +65,15 @@ jobs:
echo "SHORT_SHA=${SHORT_SHA}" >> $GITHUB_ENV echo "SHORT_SHA=${SHORT_SHA}" >> $GITHUB_ENV
mv Argyll_V*_win64_exe.zip "Argyll_${TAG}_${SHORT_SHA}_win64_exe.zip" mv Argyll_V*_win64_exe.zip "Argyll_${TAG}_${SHORT_SHA}_win64_exe.zip"
- name: Verify Package Contents
run: |
ZIP_FILE=$(ls Argyll_*_win64_exe.zip)
echo "Verifying contents of ${ZIP_FILE}..."
unzip -l "${ZIP_FILE}" | grep "usb/ArgyllCMS.inf"
unzip -l "${ZIP_FILE}" | grep "usb/bin/amd64/libusb0.sys"
unzip -l "${ZIP_FILE}" | grep "doc/ArgyllDoc.html"
unzip -l "${ZIP_FILE}" | grep "ReadMe.txt"
- name: Upload Artifact - name: Upload Artifact
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
+2
View File
@@ -19,6 +19,8 @@
<h1>[V3.4.1 -&gt; V3.5.0] 4th February 2026<br> <h1>[V3.4.1 -&gt; V3.5.0] 4th February 2026<br>
</h1> </h1>
<ul> <ul>
<li>Added macOS Universal Binary release archive (Intel x86_64 + Apple Silicon arm64).</li>
<li>Fixed non-blocking stdin polling deadlock on MSWindows anonymous pipes when running interactive measurement tools in subprocess mode.</li>
<li>Added -d switch to printtarg to allow custom chart label strings or omit labelling entirely.</li> <li>Added -d switch to printtarg to allow custom chart label strings or omit labelling entirely.</li>
<li>Added MSWindows ARM release.</li> <li>Added MSWindows ARM release.</li>
<li>Added Mac ARM release.</li> <li>Added Mac ARM release.</li>
+52 -24
View File
@@ -7,7 +7,7 @@ echo "Script to invoke Jam and then package the binary release."
PRODUCT=Argyll PRODUCT=Argyll
# Set the environment string VERSION from the #define, ie 1.0.0 # Set the environment string VERSION from the #define, ie 1.0.0
VERSION=`grep ARGYLL_VERSION_STR h/aconfig.h | head -1 | sed 's/# define ARGYLL_VERSION_STR //' | sed 's/"//g'` VERSION=`grep ARGYLL_VERSION_STR h/aconfig.h | head -1 | sed 's/# define ARGYLL_VERSION_STR //' | sed 's/\"//g'`
# Typical environment variables: # Typical environment variables:
# (NOTE some systems don't export these ENV vars. by default !!!) # (NOTE some systems don't export these ENV vars. by default !!!)
@@ -113,6 +113,13 @@ else if [ "${OSTYPE#*darwin*}" != "$OSTYPE" ] ; then
echo "We're on MacOS arm64!" echo "We're on MacOS arm64!"
PACKAGE=${PRODUCT}_V${VERSION}_macOS_arm64_bin.tgz PACKAGE=${PRODUCT}_V${VERSION}_macOS_arm64_bin.tgz
export MACOSX_DEPLOYMENT_TARGET="11.0" # Minimum target platform version export MACOSX_DEPLOYMENT_TARGET="11.0" # Minimum target platform version
else if [ X$HOSTTYPE = "Xuniversal" \
-o X$MACHTYPE = "Xuniversal-apple-darwin" \
-o X$COMPILER = "XUNIVERSAL" ] ; then
echo "We're on MacOS Universal!"
PACKAGE=${PRODUCT}_V${VERSION}_macOS_universal_bin.tgz
export MACOSX_DEPLOYMENT_TARGET="10.15" # Minimum target platform version
fi
fi fi
fi fi
fi fi
@@ -145,35 +152,56 @@ fi
echo "Making GNU $PRODUCT binary distribution $PACKAGE for Version $VERSION" echo "Making GNU $PRODUCT binary distribution $PACKAGE for Version $VERSION"
# Clean up so we get a solid build if [ X$NO_BUILD = "X" ] ; then
# .sp come from profile, .cht from scanin and .ti3 from spectro # Clean up so we get a solid build
rm -f bin/*.exe bin/*.dll # .sp come from profile, .cht from scanin and .ti3 from spectro
rm -f ref/*.sp ref/*.cht ref/*.ti2 rm -f bin/*.exe bin/*.dll
rm -f ref/*.sp ref/*.cht ref/*.ti2
if [ X$CROSS_COMPILE = "X" ] ; then # If not cross compiling if [ X$CROSS_COMPILE = "X" ] ; then # If not cross compiling
echo "Cleaning before build ..." echo "Cleaning before build ..."
if ! jam -fJambase -sBUILTIN_TIFF=true -sBUILTIN_JPEG=true -sBUILTIN_PNG=true -sBUILTIN_Z=true -sBUILTIN_SSL=true clean ; then if ! jam -fJambase -sBUILTIN_TIFF=true -sBUILTIN_JPEG=true -sBUILTIN_PNG=true -sBUILTIN_Z=true -sBUILTIN_SSL=true clean ; then
echo "Clean failed!" echo "Clean failed!"
exit 1 exit 1
fi fi
fi fi
# Make sure it's built and installed # Make sure it's built and installed
if ! jam -q -fJambase -j${NUMBER_OF_PROCESSORS:-1} -sBUILTIN_TIFF=true -sBUILTIN_JPEG=true -sBUILTIN_PNG=true -sBUILTIN_Z=true -sBUILTIN_SSL=true install ; then if ! jam -q -fJambase -j${NUMBER_OF_PROCESSORS:-1} -sBUILTIN_TIFF=true -sBUILTIN_JPEG=true -sBUILTIN_PNG=true -sBUILTIN_Z=true -sBUILTIN_SSL=true install ; then
echo "Build failed!" echo "Build failed!"
exit 1 exit 1
fi
fi fi
# Apply ad-hoc code signatures to macOS Mach-O binaries before staging
if [ "${OSTYPE#*darwin*}" != "$OSTYPE" ] ; then
echo "=== Applying ad-hoc code signatures to macOS Mach-O binaries ==="
for f in bin/* ; do
if [ -f "$f" ] && file "$f" | grep -q "Mach-O" ; then
echo "Signing $f..."
codesign -f -s - "$f" || true
fi
done
fi
rm -rf $TOPDIR rm -rf $TOPDIR
mkdir $TOPDIR mkdir $TOPDIR
# Ensure catalog copies exist if needed for Windows packaging
if [ -d usb ] ; then
if [ -f usb/ArgyllCMS.cat ] ; then
[ ! -f usb/ArgyllCMS_x64.cat ] && cp usb/ArgyllCMS.cat usb/ArgyllCMS_x64.cat
[ ! -f usb/ArgyllCMS_arm64.cat ] && cp usb/ArgyllCMS.cat usb/ArgyllCMS_arm64.cat
fi
fi
# Collect the names of all the files that we're going to package # Collect the names of all the files that we're going to package
unset topfiles; for i in `cat binfiles`; do topfiles="$topfiles ${i}"; done unset topfiles; for i in `tr -d '\r' < binfiles`; do topfiles="$topfiles ${i}"; done
unset docfiles; for i in `cat doc/afiles`; do docfiles="$docfiles doc/${i}"; done unset docfiles; for i in `tr -d '\r' < doc/afiles`; do docfiles="$docfiles doc/${i}"; done
unset usbfiles; unset usbfiles;
for j in ${USBDIRS}; do for j in ${USBDIRS}; do
if [ ${j} ]; then if [ ${j} ]; then
for i in `cat ${j}/${USBBINFILES}`; do usbfiles="$usbfiles ${j}/${i}"; done for i in `tr -d '\r' < ${j}/${USBBINFILES}`; do usbfiles="$usbfiles ${j}/${i}"; done
fi fi
done done
@@ -183,16 +211,16 @@ allfiles="${topfiles} bin/* ref/* ${docfiles} ${usbfiles}"
for i in ${allfiles}; do for i in ${allfiles}; do
path=${i%/*} # extract path without filename path=${i%/*} # extract path without filename
file=${i##*/} # extract filename file=${i##*/} # extract filename
if [ $path = $i ] ; then if [ "$path" = "$i" ] ; then
path= path=
fi fi
if [ X$path != "X" ] ; then if [ X"$path" != "X" ] ; then
mkdir -p $TOPDIR/${path} mkdir -p "$TOPDIR/${path}"
fi fi
if [ X${file} = "Xafiles" ] ; then if [ X"${file}" = "Xafiles" ] ; then
continue continue
fi fi
cp $i $TOPDIR/$i cp "$i" "$TOPDIR/$i" || { echo "Failed to copy $i to $TOPDIR/$i"; exit 1; }
done done
# Create the package # Create the package
+13 -12
View File
@@ -203,36 +203,37 @@ static int con_char(int wait) {
/* We assume pipe has been set to NOWAIT mode. */ /* We assume pipe has been set to NOWAIT mode. */
} else if (stdin_type == FILE_TYPE_PIPE) { } else if (stdin_type == FILE_TYPE_PIPE) {
int i, bib; int i, bib;
//fprintf(stderr,"~1 top of pipe\n"); DWORD bytes_avail = 0;
/* Check available bytes in pipe before blocking */
if (!PeekNamedPipe(stdinh, NULL, 0, NULL, &bytes_avail, NULL) || bytes_avail == 0) {
if (!wait) {
return 0;
}
}
for (bib = 0; bib < 10;) { for (bib = 0; bib < 10;) {
//fprintf(stderr,"~1 got %d in buf\n",bib); if (!wait) {
if (!PeekNamedPipe(stdinh, NULL, 0, NULL, &bytes_avail, NULL) || bytes_avail == 0) {
break;
}
}
if ((!ReadFile(stdinh, buf + bib, 10 - bib, &bread, NULL) || bread == 0) if ((!ReadFile(stdinh, buf + bib, 10 - bib, &bread, NULL) || bread == 0)
&& !wait) { && !wait) {
//fprintf(stderr,"~1 no chars waiting\n");
break; break;
} }
bib += bread; bib += bread;
for (i = 0; i < bib; i++) { for (i = 0; i < bib; i++) {
if (buf[i] == '\n' || buf[i] == '\r' || buf[i] == 0x3) { if (buf[i] == '\n' || buf[i] == '\r' || buf[i] == 0x3) {
//fprintf(stderr,"~1 found lf at ix %d\n",i);
break; break;
} }
} }
if (i < bib) { if (i < bib) {
//fprintf(stderr,"~1 found lf\n");
break; /* Found '\n' */ break; /* Found '\n' */
} }
Sleep(100); /* Wait for a line ending in '\n' */ Sleep(100); /* Wait for a line ending in '\n' */
} }
//if (bread > 0) {
//fprintf(stderr,"~1 read %d: ",bread);
//for (i = 0; i < bread; i++)
//fprintf(stderr," 0x%x",buf[i]);
//fprintf(stderr,"\n//");
//}
rv = buf[0]; rv = buf[0];
/* Assume a file. This will have very limited functionality. */ /* Assume a file. This will have very limited functionality. */
+2
View File
@@ -948,6 +948,8 @@ static void
i1pro_del(inst *pp) { i1pro_del(inst *pp) {
i1pro *p = (i1pro *)pp; i1pro *p = (i1pro *)pp;
/* Shut down instrument hardware and close the port, then free state */
i1pro_close_port(p);
del_i1proimp(p); del_i1proimp(p);
if (p->icom != NULL) if (p->icom != NULL)
p->icom->del(p->icom); p->icom->del(p->icom);
+119 -31
View File
@@ -389,8 +389,106 @@ i1pro_code add_i1proimp(i1pro *p) {
return I1PRO_OK; return I1PRO_OK;
} }
/* Shutdown instrument, and then destroy */ /* Stop background threads (switch monitoring & delayed trigger) */
/* implementation structure */ static void
i1pro_stop_threads(i1pro *p) {
i1proimp *m;
int i;
if (p == NULL || p->m == NULL)
return;
m = (i1proimp *)p->m;
/* Stop the switch monitoring thread first so it isn't using the */
/* communication channel while we shut down the instrument. */
if (m->th != NULL) {
m->th_term = 1; /* Tell thread to exit on error */
/* Ask the instrument to stop sending switch events and cancel */
/* any outstanding switch read. Only do this if the port is still */
/* open and the required method pointers are valid. */
if (p->icom != NULL && p->icom->is_open
&& p->icom->usb_control != NULL
&& p->icom->usb_cancel_io != NULL) {
i1pro_terminate_switch(p);
}
/* Give the thread a chance to exit cleanly (up to 5 seconds). */
for (i = 0; m->th_termed == 0 && i < 100; i++)
msec_sleep(50);
if (m->th_termed == 0) {
a1logd(p->log,3,"i1pro switch thread did not terminate, forcing\n");
if (m->th->terminate != NULL)
m->th->terminate(m->th);
}
if (m->th->wait != NULL)
m->th->wait(m->th);
if (m->th->del != NULL)
m->th->del(m->th);
m->th = NULL;
usb_uninit_cancel(&m->sw_cancel); /* Don't need cancel token now */
usb_uninit_cancel(&m->rd_sync); /* Don't need sync token now */
a1logd(p->log,5,"i1pro switch thread terminated\n");
}
/* Stop the delayed trigger thread if it is still running */
if (m->trig_thread != NULL) {
if (m->trig_thread->wait != NULL)
m->trig_thread->wait(m->trig_thread);
if (m->trig_thread->del != NULL)
m->trig_thread->del(m->trig_thread);
m->trig_thread = NULL;
a1logd(p->log,5,"i1pro trigger thread terminated\n");
}
}
/* Stop any pending I/O, shut down the instrument hardware, and close the */
/* communication port. This is separate from freeing the implementation data. */
i1pro_code
i1pro_close_port(i1pro *p) {
i1pro_code ev = I1PRO_OK;
i1proimp *m;
a1logd(p->log,3,"i1pro_close_port: called\n");
if (p->m == NULL)
return I1PRO_OK;
m = (i1proimp *)p->m;
/* Stop the switch monitoring thread and trigger thread first so they */
/* aren't using the communication channel while we shut down the instrument. */
i1pro_stop_threads(p);
/* Update usage log/calibration for Rev A..D before closing the port */
if (p->dtype != instI1Pro2 && p->icom != NULL && p->icom->is_open
&& p->icom->usb_control != NULL && p->icom->usb_write != NULL) {
i1pro_code uev;
if ((uev = i1pro_update_log(p)) != I1PRO_OK) {
a1logd(p->log,2,"i1pro_update_log: Updating the cal and log parameters to"
" EEProm failed failed\n");
}
}
/* Turn off i1Pro2/Rev E indicator LEDs before closing the port. */
/* Only attempt the write if the port is still actively open and the */
/* required USB method pointers are valid. Rev A..D do not have LEDs. */
if (p->dtype == instI1Pro2 && p->icom != NULL && p->icom->is_open
&& p->icom->usb_control != NULL && p->icom->usb_write != NULL) {
i1pro2_indLEDoff(p); /* Ignore error - we're shutting down */
}
/* Close the underlying communication port */
if (p->icom != NULL && p->icom->is_open && p->icom->close_port != NULL) {
p->icom->close_port(p->icom);
}
return ev;
}
/* Destroy implementation structure */
void del_i1proimp(i1pro *p) { void del_i1proimp(i1pro *p) {
a1logd(p->log,5,"i1pro_del called\n"); a1logd(p->log,5,"i1pro_del called\n");
@@ -404,38 +502,28 @@ void del_i1proimp(i1pro *p) {
int i, j; int i, j;
i1proimp *m = (i1proimp *)p->m; i1proimp *m = (i1proimp *)p->m;
i1pro_state *s; i1pro_state *s;
i1pro_code ev;
if (p->dtype != instI1Pro2 && (ev = i1pro_update_log(p)) != I1PRO_OK) { /* Defensive guard: ensure background threads are terminated and joined */
a1logd(p->log,2,"i1pro_update_log: Updating the cal and log parameters to" /* before freeing state, in case i1pro_close_port() was not called. */
" EEProm failed failed\n"); i1pro_stop_threads(p);
/* Defensive guard: update usage log/cal for Rev A..D if port is still open */
if (p->dtype != instI1Pro2 && p->icom != NULL && p->icom->is_open
&& p->icom->usb_control != NULL && p->icom->usb_write != NULL) {
i1pro_code uev;
if ((uev = i1pro_update_log(p)) != I1PRO_OK) {
a1logd(p->log,2,"i1pro_update_log: Updating the cal and log parameters to"
" EEProm failed failed\n");
}
} }
/* i1pro_terminate_switch() seems to fail on a rev A & Rev C ?? */ /* Defensive guard: if the com port is still open and this is an */
if (m->th != NULL) { /* Terminate switch monitor thread */ /* i1Pro2, make sure the indicator LEDs are turned off before any */
m->th_term = 1; /* Tell thread to exit on error */ /* memory is freed. In normal teardown i1pro_close_port() has */
i1pro_terminate_switch(p); /* already done this, but the guard protects any direct call paths. */
if (p->dtype == instI1Pro2 && p->icom != NULL && p->icom->is_open
for (i = 0; m->th_termed == 0 && i < 5; i++) && p->icom->usb_control != NULL && p->icom->usb_write != NULL) {
msec_sleep(50); /* Wait for thread to terminate */ i1pro2_indLEDoff(p);
if (i >= 5) {
a1logd(p->log,5,"i1pro switch thread termination failed\n");
m->th->terminate(m->th); /* Try and force thread to terminate */
}
/* Strange Mac M2/rosetta bug ?? */
if (m->th->del == NULL) {
a1logd(p->log,1,"i1pro_del: ,m->th-del is NULL!!!");
} else {
m->th->del(m->th);
}
usb_uninit_cancel(&m->sw_cancel); /* Don't need cancel token now */
usb_uninit_cancel(&m->rd_sync); /* Don't need sync token now */
a1logd(p->log,5,"i1pro switch thread terminated\n");
}
if (m->trig_thread != NULL) {
m->trig_thread->del(m->trig_thread);
a1logd(p->log,5,"i1pro trigger thread terminated\n");
} }
/* Free any per mode data */ /* Free any per mode data */
+3
View File
@@ -348,6 +348,9 @@ i1pro_code add_i1proimp(i1pro *p);
/* Destroy implementation structure */ /* Destroy implementation structure */
void del_i1proimp(i1pro *p); void del_i1proimp(i1pro *p);
/* Close instrument (stop threads, update log, turn off LEDs, close coms) */
i1pro_code i1pro_close_port(i1pro *p);
/* ============================================================ */ /* ============================================================ */
/* Error codes returned from i1pro_imp */ /* Error codes returned from i1pro_imp */
Binary file not shown.
Binary file not shown.