From b9accddbe92a799b9843874fc6ce4a4964cf39bd Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Mon, 28 Sep 2026 11:10:21 -0700 Subject: [PATCH 1/5] draft change to use lipo to merge odbc installer --- .github/workflows/cpp_extra.yml | 50 +++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/.github/workflows/cpp_extra.yml b/.github/workflows/cpp_extra.yml index 046e95292b04..7d226d9cee91 100644 --- a/.github/workflows/cpp_extra.yml +++ b/.github/workflows/cpp_extra.yml @@ -664,6 +664,13 @@ jobs: name: flight-sql-odbc-pkg-installer-${{ matrix.architecture }} path: build/cpp/ArrowFlightSQLODBC-*.pkg if-no-files-found: error + - name: Upload ODBC dylib to the job + if: matrix.build-type == 'release' && matrix.architecture == 'AMD64' + uses: actions/upload-artifact@v7 + with: + name: flight-sql-odbc-dylib-${{ matrix.architecture }} + path: build/cpp/${{ matrix.build-type }}/libarrow_flight_sql_odbc.dylib + if-no-files-found: error - name: Register Flight SQL ODBC Driver run: | sudo cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc.sh $(pwd)/build/cpp/${{ matrix.build-type }}/libarrow_flight_sql_odbc.dylib @@ -678,6 +685,48 @@ jobs: sudo chown -R $USER /Library/ODBC ci/scripts/cpp_test.sh $(pwd) $(pwd)/build + odbc-macos-universal: + needs: odbc-macos + if: needs.check-enabled.outputs.is_enabled == 'true' + name: ODBC universal macOS installer + runs-on: macos-14 + timeout-minutes: 30 + steps: + - name: Download ARM64 PKG + uses: actions/download-artifact@v8 + with: + name: flight-sql-odbc-pkg-installer-ARM64 + path: arm64-pkg + - name: Download AMD64 dylib + uses: actions/download-artifact@v8 + with: + name: flight-sql-odbc-dylib-AMD64 + path: amd64-dylib + - name: Build universal installer + run: | + set -euo pipefail + + pkg_path="$(ls arm64-pkg/ArrowFlightSQLODBC-*.pkg)" + pkg_name="$(basename "${pkg_path}" .pkg)" + + # Re-use the arm64 CPack-generated .pkg as-is (scripts, resources, + # component layout, identifiers) and only swap in a universal + # dylib, instead of reconfiguring/rebuilding CMake just to package. + pkgutil --expand-full "${pkg_path}" expanded + + dylib_path="$(find expanded -name libarrow_flight_sql_odbc.dylib)" + lipo -create "${dylib_path}" amd64-dylib/libarrow_flight_sql_odbc.dylib \ + -output "${dylib_path}" + lipo -archs "${dylib_path}" + + pkgutil --flatten expanded "${pkg_name}-universal.pkg" + - name: Upload universal ODBC PKG + uses: actions/upload-artifact@v7 + with: + name: flight-sql-odbc-pkg-installer-universal + path: ArrowFlightSQLODBC-*-universal.pkg + if-no-files-found: error + odbc-msvc: needs: check-enabled if: needs.check-enabled.outputs.is_enabled == 'true' @@ -844,6 +893,7 @@ jobs: - msvc-arm64 - odbc-linux - odbc-macos + - odbc-macos-universal - odbc-msvc - odbc-nightly uses: ./.github/workflows/report_ci.yml From 1c01d60cb7f3180405815fa83e9e913b54cf2291 Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Mon, 28 Sep 2026 11:20:02 -0700 Subject: [PATCH 2/5] Add check for archs to have both builds --- .github/workflows/cpp_extra.yml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/.github/workflows/cpp_extra.yml b/.github/workflows/cpp_extra.yml index 7d226d9cee91..521cbb895f6a 100644 --- a/.github/workflows/cpp_extra.yml +++ b/.github/workflows/cpp_extra.yml @@ -717,7 +717,15 @@ jobs: dylib_path="$(find expanded -name libarrow_flight_sql_odbc.dylib)" lipo -create "${dylib_path}" amd64-dylib/libarrow_flight_sql_odbc.dylib \ -output "${dylib_path}" - lipo -archs "${dylib_path}" + + archs="$(lipo -archs "${dylib_path}")" + echo "Universal dylib architectures: ${archs}" + for arch in arm64 x86_64; do + if ! grep -qw "${arch}" <<< "${archs}"; then + echo "::error::Universal dylib is missing '${arch}' (got: ${archs})" + exit 1 + fi + done pkgutil --flatten expanded "${pkg_name}-universal.pkg" - name: Upload universal ODBC PKG From d9b7bab62592ee1c5110bb9c4ac11687d56182fe Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Mon, 28 Sep 2026 11:25:15 -0700 Subject: [PATCH 3/5] Add macOS installer check --- .github/workflows/cpp_extra.yml | 49 ++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/.github/workflows/cpp_extra.yml b/.github/workflows/cpp_extra.yml index 521cbb895f6a..f1f6f05ee041 100644 --- a/.github/workflows/cpp_extra.yml +++ b/.github/workflows/cpp_extra.yml @@ -722,7 +722,7 @@ jobs: echo "Universal dylib architectures: ${archs}" for arch in arm64 x86_64; do if ! grep -qw "${arch}" <<< "${archs}"; then - echo "::error::Universal dylib is missing '${arch}' (got: ${archs})" + echo "Universal dylib is missing '${arch}' (got: ${archs})" exit 1 fi done @@ -735,6 +735,52 @@ jobs: path: ArrowFlightSQLODBC-*-universal.pkg if-no-files-found: error + odbc-macos-universal-verify: + needs: odbc-macos-universal + if: needs.check-enabled.outputs.is_enabled == 'true' + name: ODBC universal installer verify ${{ matrix.architecture }} macOS ${{ matrix.macos-version }} + runs-on: macos-${{ matrix.macos-version }} + timeout-minutes: 30 + strategy: + fail-fast: false + matrix: + include: + - architecture: AMD64 + macos-version: "15-intel" + - architecture: ARM64 + macos-version: "14" + steps: + - name: Download universal PKG + uses: actions/download-artifact@v8 + with: + name: flight-sql-odbc-pkg-installer-universal + - name: Install ODBC PKG + run: | + set -euo pipefail + + pkg_path="$(ls ArrowFlightSQLODBC-*-universal.pkg)" + sudo installer -pkg "${pkg_path}" -target / -verbose + - name: Check ODBC dylib installation + run: | + set -euo pipefail + + dylib="/Library/ODBC/arrow-odbc/lib/libarrow_flight_sql_odbc.dylib" + + if [ ! -f "${dylib}" ]; then + echo "ODBC dylib not found at ${dylib}" + exit 1 + fi + echo "Found ODBC dylib: ${dylib}" + + local_arch="$(uname -m)" + archs="$(lipo -archs "${dylib}")" + echo "Local architecture: ${local_arch}" + echo "Installed dylib architectures: ${archs}" + if ! grep -qw "${local_arch}" <<< "${archs}"; then + echo "Installed ODBC dylib does not support local architecture '${local_arch}' (got: ${archs})" + exit 1 + fi + odbc-msvc: needs: check-enabled if: needs.check-enabled.outputs.is_enabled == 'true' @@ -902,6 +948,7 @@ jobs: - odbc-linux - odbc-macos - odbc-macos-universal + - odbc-macos-universal-verify - odbc-msvc - odbc-nightly uses: ./.github/workflows/report_ci.yml From 1c3b7a36f13cb63ae86cc0cefaa5769463760ab8 Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Mon, 28 Sep 2026 14:09:07 -0700 Subject: [PATCH 4/5] Attempt to fix pkgutil command --- .github/workflows/cpp_extra.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cpp_extra.yml b/.github/workflows/cpp_extra.yml index f1f6f05ee041..e7c7d8487763 100644 --- a/.github/workflows/cpp_extra.yml +++ b/.github/workflows/cpp_extra.yml @@ -727,7 +727,7 @@ jobs: fi done - pkgutil --flatten expanded "${pkg_name}-universal.pkg" + pkgutil --flatten-full expanded "${pkg_name}-universal.pkg" - name: Upload universal ODBC PKG uses: actions/upload-artifact@v7 with: From 9f10f1969e6088102cee1da28fd5e0c85108331f Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Mon, 28 Sep 2026 14:13:47 -0700 Subject: [PATCH 5/5] Minor changes - comments, package name remove `-universal` from package name --- .github/workflows/cpp_extra.yml | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/.github/workflows/cpp_extra.yml b/.github/workflows/cpp_extra.yml index e7c7d8487763..6bb591e37526 100644 --- a/.github/workflows/cpp_extra.yml +++ b/.github/workflows/cpp_extra.yml @@ -664,7 +664,7 @@ jobs: name: flight-sql-odbc-pkg-installer-${{ matrix.architecture }} path: build/cpp/ArrowFlightSQLODBC-*.pkg if-no-files-found: error - - name: Upload ODBC dylib to the job + - name: Upload Intel ODBC dylib to the job if: matrix.build-type == 'release' && matrix.architecture == 'AMD64' uses: actions/upload-artifact@v7 with: @@ -702,37 +702,36 @@ jobs: with: name: flight-sql-odbc-dylib-AMD64 path: amd64-dylib - - name: Build universal installer + - name: Build universal macOS installer run: | set -euo pipefail pkg_path="$(ls arm64-pkg/ArrowFlightSQLODBC-*.pkg)" pkg_name="$(basename "${pkg_path}" .pkg)" - # Re-use the arm64 CPack-generated .pkg as-is (scripts, resources, - # component layout, identifiers) and only swap in a universal - # dylib, instead of reconfiguring/rebuilding CMake just to package. + # Use the ARM64 .pkg and swap in a universal ODBC dylib + # that works on ARM64 and AMD64. pkgutil --expand-full "${pkg_path}" expanded dylib_path="$(find expanded -name libarrow_flight_sql_odbc.dylib)" lipo -create "${dylib_path}" amd64-dylib/libarrow_flight_sql_odbc.dylib \ -output "${dylib_path}" - archs="$(lipo -archs "${dylib_path}")" - echo "Universal dylib architectures: ${archs}" + dylib_archs="$(lipo -archs "${dylib_path}")" + echo "Universal dylib architectures: ${dylib_archs}" for arch in arm64 x86_64; do - if ! grep -qw "${arch}" <<< "${archs}"; then - echo "Universal dylib is missing '${arch}' (got: ${archs})" + if ! grep -qw "${arch}" <<< "${dylib_archs}"; then + echo "Universal dylib is missing '${arch}' (got: ${dylib_archs})" exit 1 fi done - pkgutil --flatten-full expanded "${pkg_name}-universal.pkg" + pkgutil --flatten-full expanded "${pkg_name}.pkg" - name: Upload universal ODBC PKG uses: actions/upload-artifact@v7 with: name: flight-sql-odbc-pkg-installer-universal - path: ArrowFlightSQLODBC-*-universal.pkg + path: ArrowFlightSQLODBC-*.pkg if-no-files-found: error odbc-macos-universal-verify: @@ -758,7 +757,7 @@ jobs: run: | set -euo pipefail - pkg_path="$(ls ArrowFlightSQLODBC-*-universal.pkg)" + pkg_path="$(ls ArrowFlightSQLODBC-*.pkg)" sudo installer -pkg "${pkg_path}" -target / -verbose - name: Check ODBC dylib installation run: |