diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cd7a358..3a293b1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,8 +7,6 @@ on: branches: [main] jobs: - # Windows/MSVC is intentionally out of scope here - the Boost.Asio/Beast + current CMake setup - # would be a bigger lift than adding another *nix compiler, so it's left for a follow-up. build-and-test: strategy: fail-fast: false @@ -23,9 +21,16 @@ jobs: - os: macos-latest cc: clang cxx: clang++ + - os: windows-latest + cc: msvc + cxx: msvc name: Build & Test (${{ matrix.os }}, ${{ matrix.cc }}) runs-on: ${{ matrix.os }} + defaults: + run: + shell: bash + env: VCPKG_ROOT: ${{ github.workspace }}/vcpkg VCPKG_DEFAULT_BINARY_CACHE: ${{ github.workspace }}/vcpkg-bincache @@ -55,11 +60,17 @@ jobs: - name: Configure (CMake preset "default") run: cmake --preset default -DHYPERLIQUID_WARNINGS_AS_ERRORS=ON + # --config/-C are no-ops on the single-config Makefiles generator Linux/macOS use, and + # select Release on Windows' multi-config Visual Studio generator. --parallel with no + # number is unbounded on the Makefiles generator (bare `make -j`, not "one job per core") - + # this repo's ~80 independent test/example targets all become ready at once after the + # shared library links, and firing all of them at once reliably OOMs a standard hosted + # runner (reproduced locally under a matching memory cgroup - not flakiness). - name: Build - run: cmake --build build -j"$(getconf _NPROCESSORS_ONLN)" + run: cmake --build build --config Release --parallel 4 - name: Test - run: ctest --test-dir build --output-on-failure + run: ctest --test-dir build -C Release --output-on-failure sanitize: name: Sanitizers (ASan+UBSan, ubuntu-latest, gcc) diff --git a/CMakeLists.txt b/CMakeLists.txt index d0ec630..8dc3f99 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -98,6 +98,22 @@ if(NOT MSVC) target_compile_options(hyperliquid-sdk PRIVATE ${HYPERLIQUID_WARNING_FLAGS}) endif() +if(WIN32) + # Boost.Asio pulls in transitively; NOMINMAX/WIN32_LEAN_AND_MEAN avoid its + # min/max macros colliding with std::min/std::max and cut unneeded header bloat. + # _WIN32_WINNT pins the target Windows API version Asio otherwise has to guess at (with a + # build warning) - 0x0A00 is Windows 10, matching CI's windows-latest runner. + target_compile_definitions(hyperliquid-sdk PUBLIC NOMINMAX WIN32_LEAN_AND_MEAN _WIN32_WINNT=0x0A00) + target_link_libraries(hyperliquid-sdk PUBLIC ws2_32 mswsock) +endif() + +if(MSVC) + # /EHsc: MSVC needs the exception model spelled out explicitly (this codebase throws/catches + # throughout). /bigobj: Boost.Asio/Beast's heavy template instantiation blows past MSVC's + # default COFF section-table limit (C1128) in translation units like WebsocketRunner.cpp. + target_compile_options(hyperliquid-sdk PUBLIC /EHsc /bigobj) +endif() + if(HYPERLIQUID_SANITIZE) target_compile_options(hyperliquid-sdk PUBLIC ${HYPERLIQUID_SANITIZE_FLAGS}) target_link_options(hyperliquid-sdk PUBLIC ${HYPERLIQUID_SANITIZE_FLAGS}) diff --git a/include/hyperliquid/types/ResponseTypes.h b/include/hyperliquid/types/ResponseTypes.h index 0eb9b5a..8882ca2 100644 --- a/include/hyperliquid/types/ResponseTypes.h +++ b/include/hyperliquid/types/ResponseTypes.h @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -619,7 +620,11 @@ namespace hyperliquid tm.tm_min = std::stoi(s.substr(11, 2)); tm.tm_sec = 0; tm.tm_isdst = 0; +#ifdef _WIN32 + std::time_t t = _mkgmtime(&tm); +#else std::time_t t = timegm(&tm); +#endif return std::chrono::system_clock::from_time_t(t); }