Skip to content

Commit 8e625d0

Browse files
authored
GH-49219: [C++][FlightRPC] Enable static ODBC build on macOS (#49220)
### Rationale for this change #49219 Support static ODBC build on macOS. Linux support will be in a different PR. ### What changes are included in this PR? - Add unix-specific CMake build commands in CMakeLists.txt to link ODBC DYLIB statically to dependencies. - Header file changes due to switch to static build. - Test file changes due to static macOS linking that caused different behavior in iodbc ### Are these changes tested? Build is tested in CI. ### Are there any user-facing changes? N/A * GitHub Issue: #49219 Lead-authored-by: Alina (Xi) Li <alinal@bitquilltech.com> Co-authored-by: Alina (Xi) Li <alina.li@improving.com> Signed-off-by: Sutou Kouhei <kou@clear-code.com>
1 parent fcf9dd6 commit 8e625d0

File tree

13 files changed

+173
-62
lines changed

13 files changed

+173
-62
lines changed

.github/workflows/cpp_extra.yml

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,8 +355,11 @@ jobs:
355355
macos-version: "14"
356356
env:
357357
ARROW_BUILD_TESTS: ON
358+
ARROW_DEPENDENCY_SOURCE: BUNDLED
359+
ARROW_DEPENDENCY_USE_SHARED: OFF
358360
ARROW_FLIGHT_SQL_ODBC: ON
359361
ARROW_HOME: /tmp/local
362+
ARROW_MIMALLOC: OFF
360363
steps:
361364
- name: Checkout Arrow
362365
uses: actions/checkout@v6.0.1
@@ -366,6 +369,22 @@ jobs:
366369
- name: Install Dependencies
367370
run: |
368371
brew bundle --file=cpp/Brewfile
372+
373+
# We want to use bundled RE2 for static linking. If
374+
# Homebrew's RE2 is installed, its header file may be used.
375+
# We uninstall Homebrew's RE2 to ensure using bundled RE2.
376+
brew uninstall grpc || : # gRPC depends on RE2
377+
brew uninstall grpc@1.54 || : # gRPC 1.54 may be installed too
378+
brew uninstall re2
379+
380+
# We want to use bundled Protobuf for static linking. If
381+
# Homebrew's Protobuf is installed, its library file may be
382+
# used on test We uninstall Homebrew's Protobuf to ensure using
383+
# bundled Protobuf.
384+
brew uninstall protobuf
385+
386+
# We want to use bundled Boost for static linking.
387+
brew uninstall boost
369388
- name: Setup ccache
370389
run: |
371390
ci/scripts/ccache_setup.sh
@@ -395,6 +414,24 @@ jobs:
395414
export ARROW_CMAKE_ARGS="-DODBC_INCLUDE_DIR=$ODBC_INCLUDE_DIR"
396415
export CXXFLAGS="$CXXFLAGS -I$ODBC_INCLUDE_DIR"
397416
ci/scripts/cpp_build.sh $(pwd) $(pwd)/build
417+
- name: Setup Python
418+
uses: actions/setup-python@v6
419+
with:
420+
python-version: 3
421+
- name: Setup Archery
422+
run: python3 -m pip install -e dev/archery
423+
- name: Check ODBC Dependency
424+
run: |
425+
# ODBC dependency should not include other Arrow or third party libraries
426+
archery linking check-dependencies \
427+
--allow CoreFoundation \
428+
--allow libSystem \
429+
--allow libarrow_flight_sql_odbc \
430+
--allow libc++ \
431+
--allow libiconv \
432+
--allow libresolv \
433+
--allow libz \
434+
"$(pwd)/build/cpp/debug/libarrow_flight_sql_odbc.dylib"
398435
- name: Register Flight SQL ODBC Driver
399436
run: |
400437
sudo cpp/src/arrow/flight/sql/odbc/install/mac/install_odbc.sh $(pwd)/build/cpp/debug/libarrow_flight_sql_odbc.dylib

cpp/cmake_modules/ThirdpartyToolchain.cmake

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1114,6 +1114,22 @@ function(build_boost)
11141114
else()
11151115
list(APPEND BOOST_EXCLUDE_LIBRARIES uuid)
11161116
endif()
1117+
if(ARROW_FLIGHT_SQL_ODBC)
1118+
# GH-49244: Replace boost beast with alternatives in ODBC
1119+
# GH-49243: Replace boost variant with std::variant in ODBC
1120+
# GH-49245: Replace boost xpressive with alternatives in ODBC
1121+
list(APPEND
1122+
BOOST_INCLUDE_LIBRARIES
1123+
beast
1124+
variant
1125+
xpressive)
1126+
else()
1127+
list(APPEND
1128+
BOOST_EXCLUDE_LIBRARIES
1129+
beast
1130+
variant
1131+
xpressive)
1132+
endif()
11171133
set(BOOST_SKIP_INSTALL_RULES ON)
11181134
if(NOT ARROW_ENABLE_THREADING)
11191135
set(BOOST_UUID_LINK_LIBATOMIC OFF)
@@ -3025,8 +3041,7 @@ function(build_cares)
30253041
if(APPLE)
30263042
# libresolv must be linked from c-ares version 1.16.1
30273043
find_library(LIBRESOLV_LIBRARY NAMES resolv libresolv REQUIRED)
3028-
set_target_properties(c-ares::cares PROPERTIES INTERFACE_LINK_LIBRARIES
3029-
"${LIBRESOLV_LIBRARY}")
3044+
target_link_libraries(c-ares INTERFACE ${LIBRESOLV_LIBRARY})
30303045
endif()
30313046

30323047
set(ARROW_BUNDLED_STATIC_LIBS

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

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,14 @@
1515
# specific language governing permissions and limitations
1616
# under the License.
1717

18-
# Use C++ 20 for ODBC and its subdirectory
19-
# GH-44792: Arrow will switch to C++ 20
20-
set(CMAKE_CXX_STANDARD 20)
21-
2218
if(WIN32)
2319
if(MSVC_VERSION GREATER_EQUAL 1900)
2420
set(ODBCINST legacy_stdio_definitions odbccp32 shlwapi)
2521
elseif(MINGW)
2622
set(ODBCINST odbccp32 shlwapi)
2723
endif()
2824
elseif(APPLE)
29-
set(ODBCINST iodbcinst)
25+
set(ODBCINST iodbc iodbcinst)
3026
else()
3127
set(ODBCINST odbcinst)
3228
endif()
@@ -61,6 +57,27 @@ if(WIN32)
6157
list(APPEND ARROW_FLIGHT_SQL_ODBC_SRCS odbc.def install/versioninfo.rc)
6258
endif()
6359

60+
# On Windows, dynmaic build for ODBC is supported.
61+
# On unix systems, static build for ODBC is supported, all libraries are linked statically on unix.
62+
set(ARROW_FLIGHT_SQL_ODBC_DEPENDENCIES "")
63+
set(ARROW_FLIGHT_SQL_ODBC_SHARED_INSTALL_INTERFACE_LIBS "")
64+
set(ARROW_FLIGHT_SQL_ODBC_STATIC_INSTALL_INTERFACE_LIBS "")
65+
set(ARROW_FLIGHT_SQL_ODBC_SHARED_PRIVATE_LINK_LIBS "")
66+
if(WIN32)
67+
set(ARROW_FLIGHT_SQL_ODBC_DEPENDENCIES arrow_flight_sql)
68+
set(ARROW_FLIGHT_SQL_ODBC_SHARED_LINK_LIBS arrow_flight_sql_shared arrow_odbc_spi_impl)
69+
set(ARROW_FLIGHT_SQL_ODBC_STATIC_LINK_LIBS arrow_flight_sql_static)
70+
list(APPEND ARROW_FLIGHT_SQL_ODBC_SHARED_INSTALL_INTERFACE_LIBS
71+
ArrowFlight::arrow_flight_sql_shared)
72+
list(APPEND ARROW_FLIGHT_SQL_ODBC_STATIC_INSTALL_INTERFACE_LIBS
73+
ArrowFlight::arrow_flight_sql_static)
74+
list(APPEND ARROW_FLIGHT_SQL_ODBC_SHARED_PRIVATE_LINK_LIBS ODBC::ODBC ${ODBCINST})
75+
else()
76+
# Unix
77+
set(ARROW_FLIGHT_SQL_ODBC_SHARED_LINK_LIBS arrow_odbc_spi_impl)
78+
set(ARROW_FLIGHT_SQL_ODBC_STATIC_LINK_LIBS ODBC::ODBC ${ODBCINST})
79+
endif()
80+
6481
add_arrow_lib(arrow_flight_sql_odbc
6582
CMAKE_PACKAGE_NAME
6683
ArrowFlightSqlOdbc
@@ -70,24 +87,22 @@ add_arrow_lib(arrow_flight_sql_odbc
7087
ARROW_FLIGHT_SQL_ODBC_LIBRARIES
7188
SOURCES
7289
${ARROW_FLIGHT_SQL_ODBC_SRCS}
73-
DEPENDENCIES
74-
arrow_flight_sql
7590
DEFINITIONS
7691
UNICODE
92+
DEPENDENCIES
93+
${ARROW_FLIGHT_SQL_ODBC_DEPENDENCIES}
7794
SHARED_LINK_FLAGS
7895
${ARROW_VERSION_SCRIPT_FLAGS} # Defined in cpp/arrow/CMakeLists.txt
7996
SHARED_LINK_LIBS
80-
arrow_flight_sql_shared
97+
${ARROW_FLIGHT_SQL_ODBC_SHARED_LINK_LIBS}
8198
SHARED_INSTALL_INTERFACE_LIBS
82-
ArrowFlight::arrow_flight_sql_shared
99+
${ARROW_FLIGHT_SQL_ODBC_SHARED_INSTALL_INTERFACE_LIBS}
83100
STATIC_LINK_LIBS
84-
arrow_flight_sql_static
101+
${ARROW_FLIGHT_SQL_ODBC_STATIC_LINK_LIBS}
85102
STATIC_INSTALL_INTERFACE_LIBS
86-
ArrowFlight::arrow_flight_sql_static
103+
${ARROW_FLIGHT_SQL_ODBC_STATIC_INSTALL_INTERFACE_LIBS}
87104
SHARED_PRIVATE_LINK_LIBS
88-
ODBC::ODBC
89-
${ODBCINST}
90-
arrow_odbc_spi_impl)
105+
${ARROW_FLIGHT_SQL_ODBC_SHARED_PRIVATE_LINK_LIBS})
91106

92107
foreach(LIB_TARGET ${ARROW_FLIGHT_SQL_ODBC_LIBRARIES})
93108
target_compile_definitions(${LIB_TARGET} PRIVATE ARROW_FLIGHT_SQL_ODBC_EXPORTING)

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

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
# specific language governing permissions and limitations
1616
# under the License.
1717

18-
add_library(arrow_odbc_spi_impl
18+
add_library(arrow_odbc_spi_impl STATIC
1919
accessors/binary_array_accessor.cc
2020
accessors/binary_array_accessor.h
2121
accessors/boolean_array_accessor.cc
@@ -133,8 +133,11 @@ endif()
133133
if(APPLE)
134134
target_include_directories(arrow_odbc_spi_impl SYSTEM BEFORE PUBLIC ${ODBC_INCLUDE_DIR})
135135
target_link_libraries(arrow_odbc_spi_impl
136-
PUBLIC arrow_flight_sql_shared arrow_compute_shared Boost::locale
137-
iodbc)
136+
PUBLIC arrow_flight_sql_static
137+
arrow_compute_static
138+
Boost::locale
139+
Boost::headers
140+
RapidJSON)
138141
else()
139142
find_package(ODBC REQUIRED)
140143
target_include_directories(arrow_odbc_spi_impl PUBLIC ${ODBC_INCLUDE_DIR})
@@ -143,14 +146,6 @@ else()
143146
${ODBCINST})
144147
endif()
145148

146-
set_target_properties(arrow_odbc_spi_impl
147-
PROPERTIES ARCHIVE_OUTPUT_DIRECTORY
148-
${CMAKE_BINARY_DIR}/$<CONFIG>/lib
149-
LIBRARY_OUTPUT_DIRECTORY
150-
${CMAKE_BINARY_DIR}/$<CONFIG>/lib
151-
RUNTIME_OUTPUT_DIRECTORY
152-
${CMAKE_BINARY_DIR}/$<CONFIG>/lib)
153-
154149
# CLI
155150
add_executable(arrow_odbc_spi_impl_cli main.cc)
156151
set_target_properties(arrow_odbc_spi_impl_cli
@@ -159,6 +154,16 @@ set_target_properties(arrow_odbc_spi_impl_cli
159154
target_link_libraries(arrow_odbc_spi_impl_cli arrow_odbc_spi_impl)
160155

161156
# Unit tests
157+
158+
# On Windows, dynamic linking ODBC is supported.
159+
# On unix systems, static linking ODBC is supported, thus the library linking is static.
160+
if(WIN32)
161+
set(ODBC_SPI_IMPL_TEST_LINK_LIBS arrow_flight_testing_shared)
162+
else()
163+
# unix
164+
set(ODBC_SPI_IMPL_TEST_LINK_LIBS arrow_flight_testing_static)
165+
endif()
166+
162167
add_arrow_test(odbc_spi_impl_test
163168
SOURCES
164169
accessors/boolean_array_accessor_test.cc
@@ -177,4 +182,4 @@ add_arrow_test(odbc_spi_impl_test
177182
util_test.cc
178183
EXTRA_LINK_LIBS
179184
arrow_odbc_spi_impl
180-
arrow_flight_testing_shared)
185+
${ODBC_SPI_IMPL_TEST_LINK_LIBS})

cpp/src/arrow/flight/sql/odbc/odbc_impl/config/connection_string_parser.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020
#include <string>
2121

22-
#include "config/configuration.h"
22+
#include "arrow/flight/sql/odbc/odbc_impl/config/configuration.h"
2323

2424
namespace arrow::flight::sql::odbc {
2525
namespace config {

cpp/src/arrow/flight/sql/odbc/odbc_impl/ui/add_property_window.cc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
// specific language governing permissions and limitations
1616
// under the License.
1717

18-
#include "ui/add_property_window.h"
18+
#include "arrow/flight/sql/odbc/odbc_impl/ui/add_property_window.h"
1919

2020
#include <Windowsx.h>
2121

@@ -25,8 +25,8 @@
2525
#include <commctrl.h>
2626

2727
#include "arrow/flight/sql/odbc/odbc_impl/exceptions.h"
28-
#include "ui/custom_window.h"
29-
#include "ui/window.h"
28+
#include "arrow/flight/sql/odbc/odbc_impl/ui/custom_window.h"
29+
#include "arrow/flight/sql/odbc/odbc_impl/ui/window.h"
3030

3131
namespace arrow::flight::sql::odbc {
3232
namespace config {

cpp/src/arrow/flight/sql/odbc/odbc_impl/ui/custom_window.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
#include <sstream>
2929

3030
#include "arrow/flight/sql/odbc/odbc_impl/exceptions.h"
31-
#include "ui/custom_window.h"
31+
#include "arrow/flight/sql/odbc/odbc_impl/ui/custom_window.h"
3232

3333
namespace arrow::flight::sql::odbc {
3434
namespace config {

cpp/src/arrow/flight/sql/odbc/odbc_impl/ui/custom_window.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
#pragma once
1919

20-
#include "ui/window.h"
20+
#include "arrow/flight/sql/odbc/odbc_impl/ui/window.h"
2121

2222
namespace arrow::flight::sql::odbc {
2323
namespace config {

cpp/src/arrow/flight/sql/odbc/odbc_impl/ui/dsn_configuration_window.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@
1717

1818
#pragma once
1919

20-
#include "config/configuration.h"
21-
#include "ui/custom_window.h"
20+
#include "arrow/flight/sql/odbc/odbc_impl/config/configuration.h"
21+
#include "arrow/flight/sql/odbc/odbc_impl/ui/custom_window.h"
2222

2323
namespace arrow::flight::sql::odbc {
2424
namespace config {

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

Lines changed: 47 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -25,29 +25,57 @@ set(ARROW_FLIGHT_SQL_MOCK_SERVER_SRCS
2525
../../example/sqlite_server.cc
2626
../../example/sqlite_tables_schema_batch_reader.cc)
2727

28+
set(ARROW_FLIGHT_SQL_ODBC_TEST_SRCS
29+
odbc_test_suite.cc
30+
odbc_test_suite.h
31+
columns_test.cc
32+
connection_attr_test.cc
33+
connection_info_test.cc
34+
connection_test.cc
35+
errors_test.cc
36+
get_functions_test.cc
37+
statement_attr_test.cc
38+
statement_test.cc
39+
tables_test.cc
40+
type_info_test.cc
41+
# Enable Protobuf cleanup after test execution
42+
# GH-46889: move protobuf_test_util to a more common location
43+
../../../../engine/substrait/protobuf_test_util.cc)
44+
45+
if(ARROW_TEST_LINKAGE STREQUAL "static")
46+
set(ARROW_FLIGHT_SQL_ODBC_TEST_LINK_LIBS arrow_flight_sql_odbc_static
47+
${ARROW_TEST_STATIC_LINK_LIBS})
48+
else()
49+
set(ARROW_FLIGHT_SQL_ODBC_TEST_LINK_LIBS arrow_flight_sql_odbc_shared
50+
${ARROW_TEST_SHARED_LINK_LIBS})
51+
endif()
52+
53+
set(ARROW_FLIGHT_SQL_ODBC_TEST_LIBS ${ODBC_LIBRARIES} ${ODBCINST} ${SQLite3_LIBRARIES})
54+
55+
# On Windows, dynamic linking ODBC is supported, tests link libraries dynamically.
56+
# On unix systems, static linking ODBC is supported, thus tests link libraries statically.
57+
set(ARROW_FLIGHT_SQL_ODBC_TEST_EXTRA_LINK_LIBS "")
58+
set(ARROW_FLIGHT_SQL_ODBC_TEST_STATIC_LINK_LIBS "")
59+
if(WIN32)
60+
# arrow_odbc_spi_impl is required on Windows due to dynamic linking
61+
list(APPEND ARROW_FLIGHT_SQL_ODBC_TEST_EXTRA_LINK_LIBS arrow_odbc_spi_impl
62+
${ARROW_FLIGHT_SQL_ODBC_TEST_LIBS})
63+
else()
64+
# Unix
65+
list(APPEND ARROW_FLIGHT_SQL_ODBC_TEST_STATIC_LINK_LIBS
66+
${ARROW_FLIGHT_SQL_ODBC_TEST_LIBS} ${ARROW_FLIGHT_SQL_ODBC_TEST_LINK_LIBS})
67+
endif()
68+
2869
add_arrow_test(flight_sql_odbc_test
2970
SOURCES
30-
odbc_test_suite.cc
31-
odbc_test_suite.h
32-
columns_test.cc
33-
connection_attr_test.cc
34-
connection_info_test.cc
35-
connection_test.cc
36-
errors_test.cc
37-
get_functions_test.cc
38-
statement_attr_test.cc
39-
statement_test.cc
40-
tables_test.cc
41-
type_info_test.cc
42-
# Enable Protobuf cleanup after test execution
43-
# GH-46889: move protobuf_test_util to a more common location
44-
../../../../engine/substrait/protobuf_test_util.cc
71+
${ARROW_FLIGHT_SQL_ODBC_TEST_SRCS}
4572
${ARROW_FLIGHT_SQL_MOCK_SERVER_SRCS}
73+
DEFINITIONS
74+
UNICODE
4675
EXTRA_LINK_LIBS
47-
${ODBC_LIBRARIES}
48-
${ODBCINST}
49-
${SQLite3_LIBRARIES}
50-
arrow_odbc_spi_impl)
76+
${ARROW_FLIGHT_SQL_ODBC_TEST_EXTRA_LINK_LIBS}
77+
STATIC_LINK_LIBS
78+
${ARROW_FLIGHT_SQL_ODBC_TEST_STATIC_LINK_LIBS})
5179

5280
find_package(ODBC REQUIRED)
5381
target_link_libraries(arrow-flight-sql-odbc-test PRIVATE ODBC::ODBC)

0 commit comments

Comments
 (0)