From c854485b9cffe50a875a07169e5352778adeb899 Mon Sep 17 00:00:00 2001 From: Brian Ward Date: Wed, 16 Oct 2024 11:54:09 -0400 Subject: [PATCH] Try windows --- .github/workflows/main.yaml | 20 ++++++++++++++++++++ c-example/Makefile | 2 +- c-example/runtime_loading.c | 28 ++++++++++++++++++++++++++-- 3 files changed, 47 insertions(+), 3 deletions(-) diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index f2a21d5d..6a637010 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -37,6 +37,26 @@ jobs: path: ./stan/ key: ${{ runner.os }}-stan-${{ hashFiles('stan/src/stan/version.hpp') }}-v${{ env.CACHE_VERSION }} + + - name: Set up TBB for C example + if: matrix.os == 'windows-latest' + run: | + Add-Content $env:GITHUB_PATH "$(pwd)/stan/lib/stan_math/lib/tbb" + + - name: Build C example (Windows) + if: matrix.os == 'windows-latest' + run: | + cd c-example/ + make -j4 example.exe example_static.exe example_runtime.exe + rm ../src/bridgestan.o ../test_models/full/*.a + + echo "Dynamically linked example" + ./example.exe + echo "Statically linked example" + ./example_static.exe + echo "Runtime loading example" + ./example_runtime.exe ../test_models/full/full_model.so + - name: Build C example (Unix) if: matrix.os != 'windows-latest' run: | diff --git a/c-example/Makefile b/c-example/Makefile index e8d34b4d..a353555e 100644 --- a/c-example/Makefile +++ b/c-example/Makefile @@ -30,4 +30,4 @@ example_static$(EXE): example.c ../test_models/$(MODEL)/$(MODEL)_model.a $(RM) example.o example_runtime$(EXE): runtime_loading.c - $(CC) -I ../src runtime_loading.c -o example_runtime$(EXE) -ldl + $(CC) -I ../src runtime_loading.c -o example_runtime$(EXE) diff --git a/c-example/runtime_loading.c b/c-example/runtime_loading.c index 6965f908..feb9ee8e 100644 --- a/c-example/runtime_loading.c +++ b/c-example/runtime_loading.c @@ -1,6 +1,24 @@ #include "bridgestan.h" #include + +#ifdef _WIN32 +// hacky way to get dlopen and friends on Windows + +#include +#include +#define dlopen(lib, flags) LoadLibraryA(lib) +#define dlsym(handle, sym) GetProcAddress(handle, sym) + +char* dlerror() { + DWORD err = GetLastError(); + int length = snprintf(NULL, 0, "%d", err); + char* str = malloc(length + 1); + snprintf(str, length + 1, "%d", err); + return str; +} +#else #include +#endif #if __STDC_VERSION__ < 202000 #define typeof __typeof__ @@ -34,8 +52,8 @@ int main(int argc, char** argv) { int patch = *(int*)dlsym(handle, "bs_patch_version"); fprintf(stderr, "Using BridgeStan version %d.%d.%d\n", major, minor, patch); - // Get function pointers. Uses C23's typeof to re-use bridgestan.h definitions. - // We could also write out the types and not include bridgestan.h + // Get function pointers. Uses C23's typeof to re-use bridgestan.h + // definitions. We could also write out the types and not include bridgestan.h typeof(&bs_model_construct) bs_model_construct = dlsym(handle, "bs_model_construct"); typeof(&bs_free_error_msg) bs_free_error_msg @@ -45,6 +63,12 @@ int main(int argc, char** argv) { typeof(&bs_name) bs_name = dlsym(handle, "bs_name"); typeof(&bs_param_num) bs_param_num = dlsym(handle, "bs_param_num"); + if (!bs_model_construct || !bs_free_error_msg || !bs_model_destruct || + !bs_name || !bs_param_num) { + fprintf(stderr, "Error: %s\n", dlerror()); + return 1; + } + // from here on, the code is exactly the same as example.c // this could potentially error, and we may get information back about why.