Skip to content

Commit 2f37bb7

Browse files
authored
Merge pull request #3 from sqliteai/add-win-builds
add Windows CPU builds
2 parents 43b9519 + 707362d commit 2f37bb7

4 files changed

Lines changed: 95 additions & 42 deletions

File tree

.github/workflows/main.yml

Lines changed: 54 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -44,39 +44,55 @@ jobs:
4444
# Linux ARM64 builds
4545
- os: LinuxARM64
4646
arch: arm64
47-
name: linux-arm64-cpu
47+
name: linux-cpu
4848
make: LLAMA="-DGGML_NATIVE=ON"
4949
- os: LinuxARM64
5050
arch: arm64
51-
name: linux-arm64-neon
51+
name: linux-neon
5252
make: LLAMA="-DGGML_NATIVE=OFF -DGGML_CPU_ARM_ARCH=armv8.2-a"
5353
- os: LinuxARM64
5454
arch: arm64
55-
name: linux-arm64-openblas
55+
name: linux-openblas
5656
make: LLAMA="-DGGML_NATIVE=ON -DGGML_BLAS=ON -DGGML_BLAS_VENDOR=OpenBLAS"
5757
- os: LinuxARM64
5858
arch: arm64
59-
name: linux-arm64-vulkan
59+
name: linux-vulkan
6060
make: LLAMA="-DGGML_NATIVE=OFF -DGGML_VULKAN=ON"
6161
- os: LinuxARM64
6262
arch: arm64
63-
name: linux-arm64-opencl
63+
name: linux-opencl
6464
make: LLAMA="-DGGML_NATIVE=ON -DGGML_OPENCL=ON"
6565

6666
# macOS builds
6767
- os: macos-latest
6868
name: macos
6969
make: LLAMA="-DGGML_NATIVE=ON -DGGML_METAL=ON -DGGML_ACCELERATE=ON -DGGML_BLAS=ON -DGGML_BLAS_VENDOR=Apple" WHISPER="-DGGML_METAL=ON -DGGML_ACCELERATE=ON -DGGML_BLAS=ON -DGGML_BLAS_VENDOR=Apple -DWHISPER_COREML=ON -DWHISPER_COREML_ALLOW_FALLBACK=ON"
7070

71-
# Windows builds (commented out but ready to enable)
71+
# Windows builds
72+
- os: windows-latest
73+
arch: x86_64
74+
name: windows-cpu
75+
make: LLAMA="-DGGML_NATIVE=ON"
76+
- os: windows-latest
77+
arch: x86_64
78+
name: windows-cpu-avx2
79+
make: LLAMA="-DGGML_NATIVE=OFF -DGGML_AVX2=ON -DGGML_FMA=ON -DGGML_F16C=ON -DGGML_BMI2=ON -DGGML_SSE42=ON"
80+
- os: windows-latest
81+
arch: x86_64
82+
name: windows-cpu-avx512
83+
make: LLAMA="-DGGML_NATIVE=OFF -DGGML_AVX512=ON -DGGML_AVX512_VNNI=ON -DGGML_AVX512_VBMI=ON -DGGML_AVX512_BF16=ON"
7284
# - os: windows-latest
7385
# arch: x86_64
74-
# name: windows-cpu
75-
# make: LLAMA="-DGGML_NATIVE=ON"
86+
# name: windows-openblas
87+
# make: LLAMA="-DGGML_NATIVE=ON -DGGML_BLAS=ON -DGGML_BLAS_VENDOR=OpenBLAS"
7688
# - os: windows-latest
7789
# arch: x86_64
7890
# name: windows-vulkan
7991
# make: LLAMA="-DGGML_NATIVE=OFF -DGGML_VULKAN=ON"
92+
# - os: windows-latest
93+
# arch: x86_64
94+
# name: windows-opencl
95+
# make: LLAMA="-DGGML_NATIVE=ON -DGGML_OPENCL=ON"
8096

8197
# Android builds
8298
- os: ubuntu-latest
@@ -112,28 +128,30 @@ jobs:
112128
with:
113129
msystem: mingw64
114130
install: >-
131+
git
132+
make
133+
sqlite
115134
mingw-w64-x86_64-cc
116135
mingw-w64-x86_64-cmake
117-
make
118-
119-
- name: linux install dependencies
120-
if: startsWith(matrix.name, 'linux-')
121-
run: |
122-
sudo apt-get update -y
123-
sudo apt-get install -y build-essential wget git cmake sqlite3 libcurl4-openssl-dev
136+
${{ contains(matrix.name, 'vulkan') && 'mingw-w64-x86_64-vulkan-headers' || '' }}
137+
${{ contains(matrix.name, 'vulkan') && 'mingw-w64-x86_64-vulkan-loader' || '' }}
138+
${{ contains(matrix.name, 'vulkan') && 'mingw-w64-x86_64-shaderc' || '' }}
139+
${{ contains(matrix.name, 'openblas') && 'mingw-w64-x86_64-openblas' || '' }}
140+
${{ contains(matrix.name, 'opencl') && 'mingw-w64-x86_64-opencl-headers' || '' }}
141+
${{ contains(matrix.name, 'opencl') && 'mingw-w64-x86_64-opencl-icd' || '' }}
124142
125143
- name: linux install openblas
126-
if: contains(matrix.name, 'openblas')
144+
if: matrix.name == 'linux-openblas'
127145
run: |
128146
sudo apt-get install -y libopenblas-dev
129147
130148
- name: linux install opencl
131-
if: contains(matrix.name, 'opencl')
149+
if: matrix.name == 'linux-opencl'
132150
run: |
133151
sudo apt-get install -y opencl-headers ocl-icd-opencl-dev
134152
135-
- name: linux install vulkan (x86_64)
136-
if: contains(matrix.name, 'vulkan') && matrix.arch == 'x86_64'
153+
- name: linux-x86_64 install vulkan
154+
if: matrix.name == 'linux-vulkan' && matrix.arch == 'x86_64'
137155
run: |
138156
wget -qO - https://packages.lunarg.com/lunarg-signing-key-pub.asc | sudo apt-key add -
139157
sudo wget -qO /etc/apt/sources.list.d/lunarg-vulkan-jammy.list https://packages.lunarg.com/vulkan/lunarg-vulkan-jammy.list
@@ -149,8 +167,8 @@ jobs:
149167
echo "LD_LIBRARY_PATH=$LD_LIBRARY_PATH" >> $GITHUB_ENV
150168
echo "VK_ADD_LAYER_PATH=$VK_ADD_LAYER_PATH" >> $GITHUB_ENV
151169
152-
- name: linux install vulkan (arm64)
153-
if: contains(matrix.name, 'vulkan') && matrix.arch == 'arm64'
170+
- name: linux-arm64 install vulkan
171+
if: matrix.name == 'linux-vulkan' && matrix.arch == 'arm64'
154172
run: |
155173
sudo dpkg --add-architecture arm64
156174
@@ -170,19 +188,22 @@ jobs:
170188
crossbuild-essential-arm64 \
171189
libvulkan-dev:arm64
172190
191+
- name: windows setup vulkan environment
192+
if: matrix.name == 'windows-vulkan'
193+
run: |
194+
# MSYS2 Vulkan packages are already installed, just set up environment
195+
echo "VULKAN_SDK=C:/msys64/mingw64" >> $GITHUB_ENV
196+
shell: bash
197+
173198
- name: windows build sqlite-ai
174-
if: matrix.name == 'windows'
199+
if: matrix.os == 'windows-latest'
175200
run: make extension ${{ matrix.make && matrix.make || ''}}
176201
shell: msys2 {0}
177202

178203
- name: build sqlite-ai
179-
if: matrix.name != 'windows'
204+
if: matrix.os != 'windows-latest'
180205
run: make extension ${{ matrix.make && matrix.make || ''}}
181206

182-
- name: windows install sqlite3
183-
if: matrix.os == 'windows-latest'
184-
run: choco install sqlite -y
185-
186207
- name: macos install sqlite3 without SQLITE_OMIT_LOAD_EXTENSION
187208
if: matrix.name == 'macos'
188209
run: brew link sqlite --force
@@ -229,8 +250,13 @@ jobs:
229250
adb push ${{ github.workspace }}/. /data/local/tmp/
230251
adb shell "sh /data/local/tmp/commands.sh"
231252
253+
- name: windows test sqlite-ai
254+
if: startsWith(matrix.name, 'windows-')
255+
run: make test
256+
shell: msys2 {0}
257+
232258
- name: test sqlite-ai
233-
if: startsWith(matrix.name, 'linux-') || startsWith(matrix.name, 'windows-') || matrix.name == 'macos'
259+
if: startsWith(matrix.name, 'linux-') || matrix.name == 'macos'
234260
run: make test
235261

236262
- uses: actions/upload-artifact@v4.6.2

Makefile

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,15 @@ CFLAGS = -Wall -Wextra -Wno-unused-parameter -I$(SRC_DIR) -I$(LLAMA_DIR)/ggml/in
4343
LLAMA_OPTIONS = $(LLAMA) -DBUILD_SHARED_LIBS=OFF -DLLAMA_CURL=OFF -DLLAMA_BUILD_EXAMPLES=OFF -DLLAMA_BUILD_TESTS=OFF -DLLAMA_BUILD_TOOLS=OFF -DLLAMA_BUILD_SERVER=OFF -DGGML_RPC=OFF
4444
WHISPER_OPTIONS = $(WHISPER) -DBUILD_SHARED_LIBS=OFF -DWHISPER_BUILD_EXAMPLES=OFF -DWHISPER_BUILD_TESTS=OFF -DWHISPER_BUILD_SERVER=OFF -DWHISPER_RPC=OFF
4545
MINIAUDIO_OPTIONS = $(MINIAUDIO) -DBUILD_SHARED_LIBS=OFF -DMINIAUDIO_BUILD_EXAMPLES=OFF -DMINIAUDIO_BUILD_TESTS=OFF
46+
# MinGW produces .a files without lib prefix, use -l:filename.a syntax
47+
ifeq ($(PLATFORM),windows)
48+
L = -l:
49+
A = .a
50+
else
51+
L = -l
52+
endif
4653
# Module-specific linker flags
47-
LLAMA_LDFLAGS = -L./$(BUILD_LLAMA)/common -L./$(BUILD_LLAMA)/ggml/src -L./$(BUILD_LLAMA)/src -lcommon -lllama -lggml -lggml-base -lggml-cpu
54+
LLAMA_LDFLAGS = -L./$(BUILD_LLAMA)/common -L./$(BUILD_LLAMA)/ggml/src -L./$(BUILD_LLAMA)/src -lcommon -lllama $(L)ggml$(A) $(L)ggml-base$(A) $(L)ggml-cpu$(A)
4855
WHISPER_LDFLAGS = -L./$(BUILD_WHISPER)/src -lwhisper
4956
MINIAUDIO_LDFLAGS = -L./$(BUILD_MINIAUDIO) -lminiaudio
5057
LDFLAGS = $(LLAMA_LDFLAGS) $(WHISPER_LDFLAGS) $(MINIAUDIO_LDFLAGS)
@@ -62,6 +69,7 @@ ifeq ($(PLATFORM),windows)
6269
LDFLAGS += -shared
6370
# Create .def file for Windows
6471
DEF_FILE := $(BUILD_DIR)/ai.def
72+
LDFLAGS += -lbcrypt -lgomp -lstdc++
6573
STRIP = strip --strip-unneeded $@
6674
else ifeq ($(PLATFORM),macos)
6775
TARGET := $(DIST_DIR)/ai.dylib
@@ -94,9 +102,10 @@ else ifeq ($(PLATFORM),android)
94102
CXX = $(CC)++
95103
TARGET := $(DIST_DIR)/ai.so
96104
LDFLAGS += -static-libstdc++ -shared
97-
LLAMA_OPTIONS += -DCMAKE_TOOLCHAIN_FILE=$(ANDROID_NDK)/build/cmake/android.toolchain.cmake -DANDROID_ABI=$(if $(filter aarch64,$(ARCH)),arm64-v8a,$(ARCH)) -DANDROID_PLATFORM=android-26 -DCMAKE_C_FLAGS="-march=$(if $(filter aarch64,$(ARCH)),armv8.7a,x86-64)" -DCMAKE_CXX_FLAGS="-march=$(if $(filter aarch64,$(ARCH)),armv8.7a,x86-64)" -DGGML_OPENMP=OFF -DGGML_LLAMAFILE=OFF -DCMAKE_POSITION_INDEPENDENT_CODE=ON
98-
WHISPER_OPTIONS += -DCMAKE_TOOLCHAIN_FILE=$(ANDROID_NDK)/build/cmake/android.toolchain.cmake -DANDROID_ABI=$(if $(filter aarch64,$(ARCH)),arm64-v8a,$(ARCH)) -DANDROID_PLATFORM=android-26 -DCMAKE_C_FLAGS="-march=$(if $(filter aarch64,$(ARCH)),armv8.7a,x86-64)" -DCMAKE_CXX_FLAGS="-march=$(if $(filter aarch64,$(ARCH)),armv8.7a,x86-64)" -DGGML_OPENMP=OFF -DGGML_LLAMAFILE=OFF -DCMAKE_POSITION_INDEPENDENT_CODE=ON
99-
MINIAUDIO_OPTIONS += -DCMAKE_TOOLCHAIN_FILE=$(ANDROID_NDK)/build/cmake/android.toolchain.cmake -DANDROID_ABI=$(if $(filter aarch64,$(ARCH)),arm64-v8a,$(ARCH)) -DANDROID_PLATFORM=android-26 -DCMAKE_C_FLAGS="-march=$(if $(filter aarch64,$(ARCH)),armv8.7a,x86-64)" -DCMAKE_CXX_FLAGS="-march=$(if $(filter aarch64,$(ARCH)),armv8.7a,x86-64)" -DCMAKE_POSITION_INDEPENDENT_CODE=ON
105+
ANDROID_OPTIONS = -DCMAKE_TOOLCHAIN_FILE=$(ANDROID_NDK)/build/cmake/android.toolchain.cmake -DANDROID_ABI=$(if $(filter aarch64,$(ARCH)),arm64-v8a,$(ARCH)) -DANDROID_PLATFORM=android-26 -DCMAKE_C_FLAGS="-march=$(if $(filter aarch64,$(ARCH)),armv8.7a,x86-64)" -DCMAKE_CXX_FLAGS="-march=$(if $(filter aarch64,$(ARCH)),armv8.7a,x86-64)" -DCMAKE_POSITION_INDEPENDENT_CODE=ON
106+
LLAMA_OPTIONS += $(ANDROID_OPTIONS) -DGGML_OPENMP=OFF -DGGML_LLAMAFILE=OFF
107+
WHISPER_OPTIONS += $(ANDROID_OPTIONS) -DGGML_OPENMP=OFF -DGGML_LLAMAFILE=OFF
108+
MINIAUDIO_OPTIONS += $(ANDROID_OPTIONS)
100109
STRIP = $(BIN)/llvm-strip --strip-unneeded $@
101110
else ifeq ($(PLATFORM),ios)
102111
TARGET := $(DIST_DIR)/ai.dylib
@@ -129,21 +138,25 @@ endif
129138
# Backend specific settings
130139
ifneq (,$(findstring VULKAN,$(LLAMA)))
131140
LLAMA_LIBS += $(BUILD_LLAMA)/ggml/src/ggml-vulkan/libggml-vulkan.a
132-
LLAMA_LDFLAGS += -L./$(BUILD_LLAMA)/ggml/src/ggml-vulkan -lggml-vulkan
141+
LLAMA_LDFLAGS += -L./$(BUILD_LLAMA)/ggml/src/ggml-vulkan $(L)ggml-vulkan$(A)
142+
# Vulkan variations
143+
ifeq ($(PLATFORM),windows)
144+
VULKAN_VAR = -1
145+
endif
133146
# Add Vulkan SDK library path if available
134147
ifdef VULKAN_SDK
135-
LLAMA_LDFLAGS += -L$(VULKAN_SDK)/lib -lvulkan
148+
LLAMA_LDFLAGS += -L$(VULKAN_SDK)/lib -lvulkan$(VULKAN_VAR)
136149
else # system Vulkan library locations
137-
LLAMA_LDFLAGS += -lvulkan -ldl
150+
LLAMA_LDFLAGS += -lvulkan$(VULKAN_VAR) -ldl
138151
endif
139152
endif
140153
ifneq (,$(findstring OPENCL,$(LLAMA)))
141154
LLAMA_LIBS += $(BUILD_LLAMA)/ggml/src/ggml-opencl/libggml-opencl.a
142-
LLAMA_LDFLAGS += -L./$(BUILD_LLAMA)/ggml/src/ggml-opencl -lggml-opencl -lOpenCL
155+
LLAMA_LDFLAGS += -L./$(BUILD_LLAMA)/ggml/src/ggml-opencl $(L)ggml-opencl$(A) -lOpenCL -ldl
143156
endif
144157
ifneq (,$(findstring BLAS,$(LLAMA)))
145158
LLAMA_LIBS += $(BUILD_LLAMA)/ggml/src/ggml-blas/libggml-blas.a
146-
LLAMA_LDFLAGS += -L./$(BUILD_LLAMA)/ggml/src/ggml-blas -lggml-blas
159+
LLAMA_LDFLAGS += -L./$(BUILD_LLAMA)/ggml/src/ggml-blas $(L)ggml-blas$(A)
147160
# Link against specific BLAS implementations
148161
ifneq (,$(findstring OpenBLAS,$(LLAMA)))
149162
LLAMA_LDFLAGS += -lopenblas
@@ -193,19 +206,24 @@ test: $(TARGET)
193206
$(SQLITE3) ":memory:" -cmd ".bail on" ".load ./dist/ai" "SELECT ai_version();"
194207

195208
# Build submodules
209+
ifeq ($(PLATFORM),windows)
210+
ARGS = --parallel $(CPUS)
211+
else
212+
ARGS = -- -j$(CPUS)
213+
endif
196214
build/llama.cpp.stamp:
197215
cmake -B $(BUILD_LLAMA) $(LLAMA_OPTIONS) $(LLAMA_DIR)
198-
cmake --build $(BUILD_LLAMA) --config Release -- -j$(CPUS)
216+
cmake --build $(BUILD_LLAMA) --config Release $(ARGS)
199217
touch $@
200218

201219
build/whisper.cpp.stamp:
202220
cmake -B $(BUILD_WHISPER) $(WHISPER_OPTIONS) $(WHISPER_DIR)
203-
cmake --build $(BUILD_WHISPER) --config Release -- -j$(CPUS)
221+
cmake --build $(BUILD_WHISPER) --config Release $(ARGS)
204222
touch $@
205223

206224
build/miniaudio.stamp:
207225
cmake -B $(BUILD_MINIAUDIO) $(MINIAUDIO_OPTIONS) $(MINIAUDIO_DIR)
208-
cmake --build $(BUILD_MINIAUDIO) --config Release -- -j$(CPUS)
226+
cmake --build $(BUILD_MINIAUDIO) --config Release $(ARGS)
209227
touch $@
210228

211229
$(LLAMA_LIBS): build/llama.cpp.stamp

src/sqlite-ai.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
extern "C" {
2525
#endif
2626

27-
#define SQLITE_AI_VERSION "0.5.2"
27+
#define SQLITE_AI_VERSION "0.5.3"
2828

2929
SQLITE_AI_API int sqlite3_ai_init (sqlite3 *db, char **pzErrMsg, const sqlite3_api_routines *pApi);
3030

src/utils.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,16 @@ int ai_uuid_v7_generate (uint8_t value[UUID_LEN]) {
370370

371371
// get current timestamp in ms
372372
struct timespec ts;
373-
#ifdef __ANDROID__
373+
#ifdef _WIN32
374+
// Windows doesn't have timespec_get in MinGW, use GetSystemTimeAsFileTime
375+
FILETIME ft;
376+
GetSystemTimeAsFileTime(&ft);
377+
uint64_t wintime = ((uint64_t)ft.dwHighDateTime << 32) + ft.dwLowDateTime;
378+
// Convert from 100ns intervals since 1601 to seconds since 1970
379+
wintime = wintime / 10000000ULL - 11644473600ULL;
380+
ts.tv_sec = (time_t)wintime;
381+
ts.tv_nsec = ((((uint64_t)ft.dwHighDateTime << 32) + ft.dwLowDateTime) % 10000000ULL) * 100;
382+
#elif defined(__ANDROID__)
374383
if (clock_gettime(CLOCK_REALTIME, &ts) != 0) return -1;
375384
#else
376385
if (timespec_get(&ts, TIME_UTC) == 0) return -1;

0 commit comments

Comments
 (0)