Skip to content

Commit 9550f91

Browse files
committed
Add support for building confluent-kafka-python on Windows ARM64
1 parent 1a91492 commit 9550f91

5 files changed

Lines changed: 121 additions & 23 deletions

File tree

requirements/requirements-examples.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,4 @@ hvac
3333
jsonata-python
3434
# Dependency of cel-python. Use version 6 due to https://github.com/yaml/pyyaml/issues/601
3535
pyyaml>=6.0.0
36-
tink
36+
tink; sys_platform != "win32" or platform_machine != "ARM64"

requirements/requirements-rules.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,4 @@ hvac
1212
jsonata-python
1313
# Dependency of cel-python. Use version 6 due to https://github.com/yaml/pyyaml/issues/601
1414
pyyaml>=6.0.0
15-
tink
15+
tink; sys_platform != "win32" or platform_machine != "ARM64"

setup.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import os
44
import platform
5+
import shutil
56

67
from setuptools import Extension, setup
78

@@ -16,9 +17,37 @@
1617
else:
1718
librdkafka_libname = 'rdkafka'
1819

20+
# Use LIBRDKAFKA_DIR environment variable on Windows ARM64
21+
include_dirs = []
22+
library_dirs = []
23+
24+
librdkafka_dir = os.environ.get('LIBRDKAFKA_DIR')
25+
if platform.system() == 'Windows' and librdkafka_dir:
26+
include_dirs = [os.path.join(librdkafka_dir, 'include', 'librdkafka'),
27+
os.path.join(librdkafka_dir, 'include')]
28+
library_dirs = [os.path.join(librdkafka_dir, 'lib')]
29+
30+
# Auto-detect library name[CMake uses 'rdkafka', NuGet uses 'librdkafka']
31+
lib_dir = library_dirs[0]
32+
if os.path.exists(os.path.join(lib_dir, 'rdkafka.lib')):
33+
librdkafka_libname = 'rdkafka'
34+
35+
# Copy DLLs to package directory for bundling
36+
dll_dir = os.path.join(librdkafka_dir, 'bin')
37+
if os.path.exists(dll_dir):
38+
for dll_file in os.listdir(dll_dir):
39+
if dll_file.endswith('.dll'):
40+
src = os.path.join(dll_dir, dll_file)
41+
dst = os.path.join(mod_dir, dll_file)
42+
if not os.path.exists(dst) or os.path.getmtime(src) > os.path.getmtime(dst):
43+
print(f"Copying {dll_file} to package directory")
44+
shutil.copy2(src, dst)
45+
1946
module = Extension(
2047
'confluent_kafka.cimpl',
2148
libraries=[librdkafka_libname],
49+
include_dirs=include_dirs,
50+
library_dirs=library_dirs,
2251
sources=[
2352
os.path.join(ext_dir, 'confluent_kafka.c'),
2453
os.path.join(ext_dir, 'Producer.c'),

tools/windows-build.bat

Lines changed: 43 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,43 +8,65 @@ set PATH=%PATH%;c:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin
88
set
99

1010
rem Download and install librdkafka from NuGet.
11-
call tools\windows-install-librdkafka.bat %LIBRDKAFKA_NUGET_VERSION% dest || exit /b 1
11+
rem Check if LIBRDKAFKA_DIR is already set for Windows ARM64
12+
if not defined LIBRDKAFKA_DIR (
13+
rem Download and install librdkafka from NuGet.
14+
call tools\windows-install-librdkafka.bat %LIBRDKAFKA_NUGET_VERSION% dest || exit /b 1
15+
) else (
16+
call tools\windows-install-librdkafka-arm64.bat %LIBRDKAFKA_VERSION% %LIBRDKAFKA_DIR% || exit /b 1
17+
)
1218

1319
pip install -r requirements\requirements-tests-install.txt || exit /b 1
1420
pip install cibuildwheel==3.2.1 || exit /b 1
1521

1622
rem Build wheels (without tests)
17-
cibuildwheel --platform windows --output-dir wheelhouse || exit /b 1
18-
23+
if defined LIBRDKAFKA_DIR (
24+
cibuildwheel --platform windows --archs ARM64 --output-dir wheelhouse || exit /b 1
25+
) else (
26+
cibuildwheel --platform windows --output-dir wheelhouse || exit /b 1
27+
)
1928
dir wheelhouse
2029

2130
rem cibuildwheel installs the generated packages, but they're not ready yet,
2231
rem so remove them.
2332
rem FIXME: this only covers python27 (default)
2433
pip uninstall -y confluent_kafka[dev]
2534

26-
27-
rem Copy the librdkafka DLLs to a path structure that is identical to cimpl.pyd's location
28-
md stage\x86\confluent_kafka
29-
copy dest\librdkafka.redist.%LIBRDKAFKA_VERSION%\runtimes\win-x86\native\*.dll stage\x86\confluent_kafka\ || exit /b 1
30-
31-
md stage\x64\confluent_kafka
32-
copy dest\librdkafka.redist.%LIBRDKAFKA_VERSION%\runtimes\win-x64\native\*.dll stage\x64\confluent_kafka\ || exit /b 1
33-
34-
rem For each wheel, add the corresponding x86 or x64 dlls to the wheel zip file
35-
cd stage\x86
36-
for %%W in (..\..\wheelhouse\*win32.whl) do (
37-
7z a -r %%~W confluent_kafka\*.dll || exit /b 1
38-
unzip -l %%~W
35+
rem Only copy x86/x64 DLLs if building from NuGet
36+
for %%A in (x86 x64 arm64) do (
37+
md stage\%%A\confluent_kafka 2>nul
38+
)
39+
if not defined LIBRDKAFKA_DIR (
40+
copy dest\librdkafka.redist.%LIBRDKAFKA_VERSION%\runtimes\win-x86\native\*.dll stage\x86\confluent_kafka\ || exit /b 1
41+
copy dest\librdkafka.redist.%LIBRDKAFKA_VERSION%\runtimes\win-x64\native\*.dll stage\x64\confluent_kafka\ || exit /b 1
3942
)
4043

41-
cd ..\x64
42-
for %%W in (..\..\wheelhouse\*amd64.whl) do (
43-
7z a -r %%~W confluent_kafka\*.dll || exit /b 1
44-
unzip -l %%~W
44+
rem Handle Windows ARM64 if LIBRDKAFKA_DIR is defined
45+
if defined LIBRDKAFKA_DIR (
46+
copy %LIBRDKAFKA_DIR%\bin\*.dll stage\arm64\confluent_kafka\ || exit /b 1
4547
)
4648

47-
cd ..\..
49+
rem Only process x86/x64 wheels if not ARM64 build
50+
if not defined LIBRDKAFKA_DIR (
51+
cd stage\x86
52+
for %%W in (..\..\wheelhouse\*win32.whl) do (
53+
7z a -r %%~W confluent_kafka\*.dll || exit /b 1
54+
unzip -l %%~W
55+
)
56+
cd ..\x64
57+
for %%W in (..\..\wheelhouse\*amd64.whl) do (
58+
7z a -r %%~W confluent_kafka\*.dll || exit /b 1
59+
unzip -l %%~W
60+
)
61+
cd ..\..
62+
) else (
63+
cd stage\arm64
64+
for %%W in (..\..\wheelhouse\*arm64.whl) do (
65+
7z a -r %%~W confluent_kafka\*.dll || exit /b 1
66+
unzip -l %%~W
67+
)
68+
cd ..\..
69+
)
4870

4971
rem Basic testing
5072
for %%W in (wheelhouse\confluent_kafka-*cp%PYTHON_SHORTVER%*win*%PYTHON_ARCH%.whl) do (
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
@echo off
2+
setlocal enabledelayedexpansion
3+
4+
set VERSION=v2.13.0
5+
set dest=C:\librdkafka-ARM64
6+
7+
if not "%~1"=="" set VERSION=%~1
8+
if not "%~2"=="" set dest=%~2
9+
10+
if exist "%dest%" (
11+
set LIBRDKAFKA_DIR=%dest%
12+
exit /b 0
13+
)
14+
15+
set TEMP_DIR=%TEMP%\librdkafka-build-%RANDOM%
16+
mkdir "%TEMP_DIR%" 2>nul
17+
18+
cd /d "%TEMP_DIR%"
19+
20+
git clone --depth 1 --branch %VERSION% https://github.com/confluentinc/librdkafka.git
21+
if errorlevel 1 goto :error
22+
23+
cd librdkafka
24+
mkdir build-arm64
25+
cd build-arm64
26+
27+
cmake .. -G "Visual Studio 17 2022" -A ARM64 -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=%dest% -DRDKAFKA_BUILD_STATIC=OFF -DRDKAFKA_BUILD_EXAMPLES=OFF -DRDKAFKA_BUILD_TESTS=OFF -DWITH_SSL=OFF -DWITH_ZLIB=OFF -DWITH_ZSTD=OFF -DWITH_SASL=OFF -DENABLE_LZ4_EXT=OFF
28+
if errorlevel 1 goto :error
29+
30+
cmake --build . --config Release --parallel
31+
if errorlevel 1 goto :error
32+
33+
cmake --install . --config Release
34+
if errorlevel 1 goto :error
35+
36+
set LIBRDKAFKA_DIR=%dest%
37+
goto :cleanup
38+
39+
:error
40+
cd /d %TEMP%
41+
if exist "%TEMP_DIR%" rd /s /q "%TEMP_DIR%" 2>nul
42+
exit /b 1
43+
44+
:cleanup
45+
cd /d %TEMP%
46+
if exist "%TEMP_DIR%" rd /s /q "%TEMP_DIR%" 2>nul
47+
exit /b 0

0 commit comments

Comments
 (0)