Skip to content

Commit 0e37230

Browse files
alinaliBQvic-tsang
andauthored
GH-47876: [C++][FlightRPC] ODBC: macOS .PKG installer for Intel and ARM (#49766)
### Rationale for this change Generate and upload macOS .pkg installer in CI. The installer is unsigned. ### What changes are included in this PR? Adds in support for macOS `.PKG` Installer for Intel and ARM. It will install: ``` /Library/ODBC/arrow-odbc ├── doc │   ├── Connection-Options.md │   └── LICENSE.txt └── lib ├── libarrow_flight_sql_odbc.2400.0.0.dylib ├── libarrow_flight_sql_odbc.2400.dylib -> libarrow_flight_sql_odbc.2400.0.0.dylib └── libarrow_flight_sql_odbc.dylib -> libarrow_flight_sql_odbc.2400.dylib 3 directories, 5 files ``` If Apache Arrow Flight SQL ODBC is already registered in the system DSN on the user machine, the installer will not overwrite the registration. ### Are these changes tested? Tested on Intel macOS. Team will test ARM installer using ARM machine later. ### Are there any user-facing changes? Developers can download the `.pkg` installers for usage. * GitHub Issue: #47876 Lead-authored-by: justing-bq <62349012+justing-bq@users.noreply.github.com> Co-authored-by: Alina (Xi) Li <96995091+alinaliBQ@users.noreply.github.com> Co-authored-by: vic-tsang <victor.tsang@improving.com> Signed-off-by: Sutou Kouhei <kou@clear-code.com>
1 parent 1ef5e4a commit 0e37230

9 files changed

Lines changed: 250 additions & 20 deletions

File tree

.github/workflows/cpp_extra.yml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -428,6 +428,7 @@ jobs:
428428
ARROW_DEPENDENCY_SOURCE: BUNDLED
429429
ARROW_DEPENDENCY_USE_SHARED: OFF
430430
ARROW_FLIGHT_SQL_ODBC: ON
431+
ARROW_FLIGHT_SQL_ODBC_INSTALLER: ON
431432
ARROW_HOME: /tmp/local
432433
ARROW_MIMALLOC: OFF
433434
steps:
@@ -503,6 +504,19 @@ jobs:
503504
--allow libresolv \
504505
--allow libz \
505506
"$(pwd)/build/cpp/${{ matrix.build-type }}/libarrow_flight_sql_odbc.dylib"
507+
- name: Generate macOS Installer
508+
if: matrix.build-type == 'release'
509+
shell: bash
510+
run: |
511+
cd $(pwd)/build/cpp
512+
cpack
513+
- name: Upload ODBC PKG to the job
514+
if: matrix.build-type == 'release'
515+
uses: actions/upload-artifact@v7
516+
with:
517+
name: flight-sql-odbc-pkg-installer-${{ matrix.architecture }}
518+
path: build/cpp/ArrowFlightSQLODBC-*.pkg
519+
if-no-files-found: error
506520
- name: Register Flight SQL ODBC Driver
507521
run: |
508522
sudo cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc.sh $(pwd)/build/cpp/${{ matrix.build-type }}/libarrow_flight_sql_odbc.dylib

.pre-commit-config.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,9 @@ repos:
347347
?^cpp/build-support/update-thrift\.sh$|
348348
?^cpp/examples/minimal_build/run\.sh$|
349349
?^cpp/examples/tutorial_examples/run\.sh$|
350+
?^cpp/src/arrow/flight/sql/odbc/install/mac/postinstall$|
350351
?^cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc\.sh$|
352+
?^cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc_ini\.sh$|
351353
?^dev/release/05-binary-upload\.sh$|
352354
?^dev/release/07-flightsqlodbc-upload\.sh$|
353355
?^dev/release/09-binary-verify\.sh$|

cpp/src/arrow/flight/sql/odbc/CMakeLists.txt

Lines changed: 70 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -132,13 +132,11 @@ if(ARROW_FLIGHT_SQL_ODBC_INSTALLER)
132132
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Apache Arrow Flight SQL ODBC Driver")
133133
set(CPACK_PACKAGE_CONTACT "dev@arrow.apache.org")
134134

135-
# GH-47876 TODO: set up `arrow_flight_sql_odbc` component for macOS Installer
136-
# GH-47877 TODO: set up `arrow_flight_sql_odbc` component for Linux Installer
137135
if(WIN32)
138136
# Install ODBC and its Arrow dependencies
139137
install(PROGRAMS ${CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS}
140138
DESTINATION bin
141-
COMPONENT arrow_flight_sql_odbc)
139+
COMPONENT ArrowFlightSQLODBC)
142140
install(TARGETS arrow_shared
143141
arrow_compute_shared
144142
arrow_flight_shared
@@ -150,7 +148,7 @@ if(ARROW_FLIGHT_SQL_ODBC_INSTALLER)
150148
"ext-ms-.*"
151149
POST_EXCLUDE_REGEXES
152150
".*system32/.*\\.dll"
153-
RUNTIME DESTINATION bin COMPONENT arrow_flight_sql_odbc)
151+
RUNTIME DESTINATION bin COMPONENT ArrowFlightSQLODBC)
154152

155153
set(CPACK_WIX_EXTRA_SOURCES
156154
"${CMAKE_CURRENT_SOURCE_DIR}/install/windows/arrow-flight-sql-odbc.wxs")
@@ -159,10 +157,69 @@ if(ARROW_FLIGHT_SQL_ODBC_INSTALLER)
159157

160158
set(CPACK_WIX_UI_BANNER
161159
"${CMAKE_CURRENT_SOURCE_DIR}/install/windows/arrow-wix-banner.bmp")
160+
else()
161+
if(APPLE)
162+
set(CPACK_PACKAGE_FILE_NAME
163+
"ArrowFlightSQLODBC-${CPACK_PACKAGE_VERSION_MAJOR}.${ODBC_PACKAGE_VERSION_MINOR}.${ODBC_PACKAGE_VERSION_PATCH}"
164+
)
165+
set(CPACK_PACKAGE_INSTALL_DIRECTORY "${CPACK_PACKAGE_NAME}")
166+
167+
set(CPACK_SET_DESTDIR ON)
168+
set(CPACK_INSTALL_PREFIX "/Library/ODBC")
169+
# Register ODBC after install
170+
set(CPACK_POSTFLIGHT_ARROWFLIGHTSQLODBC_SCRIPT
171+
"${CMAKE_CURRENT_SOURCE_DIR}/install/mac/postinstall")
172+
set(CPACK_RESOURCE_FILE_README "${CMAKE_CURRENT_SOURCE_DIR}/install/mac/README.txt")
173+
set(CPACK_RESOURCE_FILE_WELCOME
174+
"${CMAKE_CURRENT_SOURCE_DIR}/install/mac/welcome.txt")
175+
176+
set(ODBC_INSTALL_DIR "arrow-odbc/lib")
177+
set(ODBC_DOC_INSTALL_DIR "arrow-odbc/doc")
178+
else()
179+
# Linux
180+
# GH-49595: TODO implement DEB installer
181+
# GH-47977: TODO implement RPM installer
182+
message(STATUS "ODBC_PACKAGE_FORMAT DEB not implemented, see GH-49595")
183+
message(STATUS "ODBC_PACKAGE_FORMAT RPM not implemented, see GH-47977")
184+
endif()
185+
186+
# Install ODBC
187+
install(TARGETS arrow_flight_sql_odbc_shared
188+
DESTINATION "${ODBC_INSTALL_DIR}"
189+
COMPONENT ArrowFlightSQLODBC)
190+
191+
# Install temporary driver registration scripts, they will be removed after driver registration is complete
192+
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/install/unix/install_odbc.sh"
193+
DESTINATION "${ODBC_INSTALL_DIR}"
194+
COMPONENT ArrowFlightSQLODBC
195+
PERMISSIONS OWNER_EXECUTE
196+
OWNER_WRITE
197+
OWNER_READ
198+
GROUP_EXECUTE
199+
GROUP_READ
200+
WORLD_EXECUTE
201+
WORLD_READ)
202+
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/install/unix/install_odbc_ini.sh"
203+
DESTINATION "${ODBC_INSTALL_DIR}"
204+
COMPONENT ArrowFlightSQLODBC
205+
PERMISSIONS OWNER_EXECUTE
206+
OWNER_WRITE
207+
OWNER_READ
208+
GROUP_EXECUTE
209+
GROUP_READ
210+
WORLD_EXECUTE
211+
WORLD_READ)
212+
213+
# Install documentation files
214+
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../LICENSE.txt"
215+
"${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../NOTICE.txt"
216+
"${CMAKE_CURRENT_SOURCE_DIR}/connection-options.md"
217+
DESTINATION "${ODBC_DOC_INSTALL_DIR}"
218+
COMPONENT Docs)
162219
endif()
163220

164221
get_cmake_property(CPACK_COMPONENTS_ALL COMPONENTS)
165-
set(CPACK_COMPONENTS_ALL "arrow_flight_sql_odbc")
222+
set(CPACK_COMPONENTS_ALL "ArrowFlightSQLODBC" "Docs")
166223

167224
if(WIN32)
168225
# WiX msi installer on Windows
@@ -173,14 +230,20 @@ if(ARROW_FLIGHT_SQL_ODBC_INSTALLER)
173230
# Upgrade GUID is required to be unchanged for ODBC installer to upgrade
174231
set(CPACK_WIX_UPGRADE_GUID "DBF27A18-F8BF-423F-9E3A-957414D52C4B")
175232
set(CPACK_WIX_PRODUCT_GUID "279D087B-93B5-4DC3-BA69-BCF485022A26")
233+
elseif(APPLE)
234+
# macOS and Linux
235+
set(CPACK_GENERATOR "productbuild")
176236
endif()
177-
# GH-47876 TODO: create macOS Installer using cpack
178237
# GH-47877 TODO: create Linux Installer using cpack
179238

180239
# Load CPack after all CPACK* variables are set
181240
include(CPack)
182-
cpack_add_component(arrow_flight_sql_odbc
241+
cpack_add_component(ArrowFlightSQLODBC
183242
DISPLAY_NAME "ODBC library"
184243
DESCRIPTION "Apache Arrow Flight SQL ODBC library bin, required to install"
185244
REQUIRED)
245+
cpack_add_component(Docs
246+
DISPLAY_NAME "Documentation"
247+
DESCRIPTION "Documentation for Apache Arrow Flight SQL ODBC Driver"
248+
REQUIRED)
186249
endif()
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
Files are available in '/Library/ODBC/arrow-odbc' after installation.
2+
3+
To set up a connection, you can use DSN to store your data source connection information.
4+
1. Open 'iODBC Data Source Administrator'.
5+
2. To create a user DSN, go to 'User DSN' tab and click 'Add'.
6+
3. Select 'Apache Arrow Flight SQL ODBC Driver' and click 'Finish'.
7+
4. Enter DSN name and connection string values.
8+
For the list of all supported options, check '/Library/ODBC/arrow-odbc/doc/connection-options.md'.
9+
5. Click 'OK' to save the DSN.
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
#!/bin/bash
2+
#
3+
# Licensed to the Apache Software Foundation (ASF) under one
4+
# or more contributor license agreements. See the NOTICE file
5+
# distributed with this work for additional information
6+
# regarding copyright ownership. The ASF licenses this file
7+
# to you under the Apache License, Version 2.0 (the
8+
# "License"); you may not use this file except in compliance
9+
# with the License. You may obtain a copy of the License at
10+
#
11+
# http://www.apache.org/licenses/LICENSE-2.0
12+
#
13+
# Unless required by applicable law or agreed to in writing,
14+
# software distributed under the License is distributed on an
15+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16+
# KIND, either express or implied. See the License for the
17+
# specific language governing permissions and limitations
18+
# under the License.
19+
20+
set -euo pipefail
21+
22+
odbc_install_script="/Library/ODBC/arrow-odbc/lib/install_odbc.sh"
23+
dsn_install_script="/Library/ODBC/arrow-odbc/lib/install_odbc_ini.sh"
24+
driver_lib="/Library/ODBC/arrow-odbc/lib/libarrow_flight_sql_odbc.dylib"
25+
dsn_file="/Library/ODBC/odbc.ini"
26+
27+
if [[ ! -x "$odbc_install_script" ]]; then
28+
echo "ERROR: ODBC install script $odbc_install_script not found" >&2
29+
exit 1
30+
fi
31+
32+
"$odbc_install_script" "$driver_lib" || {
33+
echo "ERROR: Failed to register ODBC driver ($driver_lib)" >&2
34+
exit 1
35+
}
36+
37+
if [[ ! -x "$dsn_install_script" ]]; then
38+
echo "ERROR: DSN install script $dsn_install_script not found" >&2
39+
exit 1
40+
fi
41+
42+
"$dsn_install_script" "$dsn_file" || {
43+
echo "ERROR: Failed to register DSN to ($dsn_file)" >&2
44+
exit 1
45+
}
46+
47+
# clean temporary script
48+
rm -f "$odbc_install_script" "$dsn_install_script"
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Apache Arrow Flight SQL ODBC Driver is a read-only ODBC driver for connecting to data sources that support Arrow Flight SQL.

cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc.sh

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
# specific language governing permissions and limitations
1818
# under the License.
1919

20-
# Used by macOS ODBC installer script `install_odbc_ini.sh` and macOS ODBC testing
20+
# Used by cpp/src/arrow/flight/sql/odbc/install/mac/postinstall
2121

2222
set -euo pipefail
2323

@@ -42,44 +42,51 @@ fi
4242

4343
case "$(uname)" in
4444
Linux)
45-
USER_ODBCINST_FILE="/etc/odbcinst.ini"
45+
SYSTEM_ODBCINST_FILE="/etc/odbcinst.ini"
4646
;;
4747
*)
4848
# macOS
49-
USER_ODBCINST_FILE="$HOME/Library/ODBC/odbcinst.ini"
50-
mkdir -p "$HOME"/Library/ODBC
49+
SYSTEM_ODBCINST_FILE="/Library/ODBC/odbcinst.ini"
50+
mkdir -p /Library/ODBC
5151
;;
5252
esac
5353

5454
DRIVER_NAME="Apache Arrow Flight SQL ODBC Driver"
5555

56-
touch "$USER_ODBCINST_FILE"
56+
touch "$SYSTEM_ODBCINST_FILE"
5757

58-
if grep -q "^\[$DRIVER_NAME\]" "$USER_ODBCINST_FILE"; then
58+
if grep -q "^\[$DRIVER_NAME\]" "$SYSTEM_ODBCINST_FILE"; then
5959
echo "Driver [$DRIVER_NAME] already exists in odbcinst.ini"
6060
else
6161
echo "Adding [$DRIVER_NAME] to odbcinst.ini..."
6262
echo "
6363
[$DRIVER_NAME]
6464
Description=An ODBC Driver for Apache Arrow Flight SQL
6565
Driver=$ODBC_64BIT
66-
" >>"$USER_ODBCINST_FILE"
66+
" >>"$SYSTEM_ODBCINST_FILE"
6767
fi
6868

6969
# Check if [ODBC Drivers] section exists
70-
if grep -q '^\[ODBC Drivers\]' "$USER_ODBCINST_FILE"; then
70+
if grep -q '^\[ODBC Drivers\]' "$SYSTEM_ODBCINST_FILE"; then
7171
# Section exists: check if driver entry exists
72-
if ! grep -q "^${DRIVER_NAME}=" "$USER_ODBCINST_FILE"; then
72+
if ! grep -q "^${DRIVER_NAME}=" "$SYSTEM_ODBCINST_FILE"; then
7373
# Driver entry does not exist, add under [ODBC Drivers]
74-
sed -i '' "/^\[ODBC Drivers\]/a\\
75-
${DRIVER_NAME}=Installed
76-
" "$USER_ODBCINST_FILE"
74+
75+
awk -v driver="$DRIVER_NAME" '
76+
$0 ~ /^\[ODBC Drivers\]/ && !inserted {
77+
print
78+
print driver "=Installed"
79+
inserted=1
80+
next
81+
}
82+
{ print }
83+
' "$SYSTEM_ODBCINST_FILE" > "${SYSTEM_ODBCINST_FILE}.tmp" && mv "${SYSTEM_ODBCINST_FILE}.tmp" "$SYSTEM_ODBCINST_FILE"
7784
fi
7885
else
7986
# Section doesn't exist, append both section and driver entry at end
8087
{
8188
echo ""
8289
echo "[ODBC Drivers]"
8390
echo "${DRIVER_NAME}=Installed"
84-
} >>"$USER_ODBCINST_FILE"
91+
} >>"$SYSTEM_ODBCINST_FILE"
8592
fi
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
#!/bin/bash
2+
#
3+
# Licensed to the Apache Software Foundation (ASF) under one
4+
# or more contributor license agreements. See the NOTICE file
5+
# distributed with this work for additional information
6+
# regarding copyright ownership. The ASF licenses this file
7+
# to you under the Apache License, Version 2.0 (the
8+
# "License"); you may not use this file except in compliance
9+
# with the License. You may obtain a copy of the License at
10+
#
11+
# http://www.apache.org/licenses/LICENSE-2.0
12+
#
13+
# Unless required by applicable law or agreed to in writing,
14+
# software distributed under the License is distributed on an
15+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16+
# KIND, either express or implied. See the License for the
17+
# specific language governing permissions and limitations
18+
# under the License.
19+
20+
set -euo pipefail
21+
22+
SYSTEM_ODBC_FILE="${1:-}"
23+
24+
if [[ -z "$SYSTEM_ODBC_FILE" ]]; then
25+
echo "ERROR: path to system ODBC DSN is not specified." >&2
26+
echo "Usage: install_odbc_ini.sh <abs_path_to_odbc_dsn_ini>" >&2
27+
exit 1
28+
fi
29+
30+
DRIVER_NAME="Apache Arrow Flight SQL ODBC Driver"
31+
DSN_NAME="Apache Arrow Flight SQL ODBC DSN"
32+
33+
if ! touch "$SYSTEM_ODBC_FILE"; then
34+
echo "ERROR: Cannot access or create $SYSTEM_ODBC_FILE" >&2
35+
exit 1
36+
fi
37+
38+
if grep -q "^\[$DSN_NAME\]" "$SYSTEM_ODBC_FILE"; then
39+
echo "DSN [$DSN_NAME] already exists in $SYSTEM_ODBC_FILE"
40+
else
41+
echo "Adding [$DSN_NAME] to $SYSTEM_ODBC_FILE..."
42+
cat >> "$SYSTEM_ODBC_FILE" <<EOF
43+
44+
[$DSN_NAME]
45+
Description = An ODBC Driver DSN for Apache Arrow Flight SQL
46+
Driver = $DRIVER_NAME
47+
Host =
48+
Port =
49+
UID =
50+
PWD =
51+
EOF
52+
fi
53+
54+
# Check if [ODBC Data Sources] section exists
55+
if grep -q '^\[ODBC Data Sources\]' "$SYSTEM_ODBC_FILE"; then
56+
# Section exists: check if DSN entry exists
57+
if ! grep -Eq "^${DSN_NAME}[[:space:]]*=" "$SYSTEM_ODBC_FILE"; then
58+
# Add DSN entry under [ODBC Data Sources] section
59+
tmp_file="$(mktemp "${SYSTEM_ODBC_FILE}.XXXX")"
60+
61+
# Use awk to insert the line immediately after [ODBC Data Sources]
62+
awk -v dsn="$DSN_NAME" -v driver="$DRIVER_NAME" '
63+
$0 ~ /^\[ODBC Data Sources\]/ && !inserted {
64+
print
65+
print dsn "=" driver
66+
inserted=1
67+
next
68+
}
69+
{ print }
70+
' "$SYSTEM_ODBC_FILE" > "$tmp_file"
71+
72+
mv "$tmp_file" "$SYSTEM_ODBC_FILE"
73+
74+
# Restore expected permissions/ownership for system ODBC config
75+
chmod 644 "$SYSTEM_ODBC_FILE"
76+
fi
77+
else
78+
# Section doesn't exist, append section and DSN entry at end
79+
{
80+
echo ""
81+
echo "[ODBC Data Sources]"
82+
echo "${DSN_NAME}=${DRIVER_NAME}"
83+
} >> "$SYSTEM_ODBC_FILE"
84+
fi

dev/release/rat_exclude_files.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ ci/vcpkg/*.patch
1313
CHANGELOG.md
1414
cpp/CHANGELOG_PARQUET.md
1515
cpp/src/arrow/c/dlpack_abi.h
16+
cpp/src/arrow/flight/sql/odbc/install/mac/README.txt
17+
cpp/src/arrow/flight/sql/odbc/install/mac/welcome.txt
1618
cpp/src/arrow/io/mman.h
1719
cpp/src/arrow/util/random.h
1820
cpp/src/arrow/status.cc

0 commit comments

Comments
 (0)