diff --git a/CHANGELOG.md b/CHANGELOG.md index 64c26ab..d2e80d8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,22 @@ uses [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +## [0.6.1] - 2026-09-25 + +### Fixed + +- Public headers compile without warnings under `-Wall -Wextra -Wpedantic`, + so projects that build with `-Werror` can include them. `Error` values in + `error.hpp` and `fixed_point.hpp` left a field uninitialized, which + `-Wmissing-field-initializers` reported. The consumer check now builds with + those flags. +- A request refused by the local rate limiter reports `http_status` 0, since + no server answered; it reported 429. +- README's examples copy the `Signer` instead of moving it, so later snippets + still have a key, and its Ubuntu setup installs a compiler and a new enough + CMake. The docs, comments, and pre-commit hook were corrected where the + final review found them out of date. + ## [0.6.0] - 2026-09-25 0.6.0 rebuilds the SDK from Kalshi's published specs. `KalshiClient` covers all @@ -22,7 +38,7 @@ the 0.5 API; "Migrating from 0.5" below lists what changed. document: all 13 channels, `update_subscription` for markets, snapshots, CF Benchmarks indices, and Pyth underlyings, and `list_subscriptions`. Message types in `kalshi/ws_models.hpp` are generated from `spec/asyncapi.yaml`, and - [docs/channels.md](docs/channels.md) maps channels to them. + [docs/channels.md](https://github.com/Reddimus/kalshi-cpp/blob/main/docs/channels.md) maps channels to them. - The WebSocket client reconnects with backoff after a dropped connection, signs each attempt, and resubscribes with each subscription's current markets. `ws::Subscription` handles survive reconnects, and every @@ -40,7 +56,7 @@ the 0.5 API; "Migrating from 0.5" below lists what changed. up from 70. New areas include historical data, live data, fee changes, event candlesticks and forecasts, order-group triggers and limits, intra-exchange transfers, target balance allocation, block trades, API usage levels, search - filters, and FCM. [docs/operations.md](docs/operations.md) lists every one. + filters, and FCM. [docs/operations.md](https://github.com/Reddimus/kalshi-cpp/blob/main/docs/operations.md) lists every one. - `tools/codegen/generate.py` generates the client, models, route tests, and operation list from the vendored `spec/openapi.yaml`. CI fails if they drift. - Requests are validated before sending: required fields must be set and @@ -763,7 +779,8 @@ the 0.5 API; "Migrating from 0.5" below lists what changed. ## [0.0.2] — initial public release -[Unreleased]: https://github.com/Reddimus/kalshi-cpp/compare/v0.6.0...HEAD +[Unreleased]: https://github.com/Reddimus/kalshi-cpp/compare/v0.6.1...HEAD +[0.6.1]: https://github.com/Reddimus/kalshi-cpp/compare/v0.6.0...v0.6.1 [0.6.0]: https://github.com/Reddimus/kalshi-cpp/compare/v0.5.2...v0.6.0 [0.5.2]: https://github.com/Reddimus/kalshi-cpp/compare/v0.5.1...v0.5.2 [0.5.1]: https://github.com/Reddimus/kalshi-cpp/compare/v0.5.0...v0.5.1 diff --git a/CLAUDE.md b/CLAUDE.md index a044f0b..016402d 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -8,8 +8,8 @@ User-visible changes also require a `CHANGELOG.md` entry. The CI workflow is the source of truth for Linux, macOS, Windows, sanitizer, clang-tidy, Markdown, and consumer gates. -Examples make authenticated network calls. Keep automated tests offline by -using an injected `HttpTransport`. +Examples call the live API, and most need a key. Keep automated tests offline +by injecting an `HttpTransport` or using the local servers in `tests/`. ## Architecture @@ -33,8 +33,9 @@ using an injected `HttpTransport`. ## Conventions -- Use explicit local types. The permitted `auto` cases are recorded in - `tools/cpp_auto_allowlist.txt` and enforced by `tools/cpp_auto_audit.py`. +- Use explicit local types. `tools/cpp_auto_audit.py` allows `auto` for + structured bindings, lambdas, and iterators; anything else needs an + `// auto-ok: reason` comment. - `tools/codegen/generate.py` writes the REST client from `spec/openapi.yaml` and the WebSocket types from `spec/asyncapi.yaml`. Edit a spec, the generator, or a `tools/codegen/*.in` template, then run `make codegen`; diff --git a/CMakeLists.txt b/CMakeLists.txt index 0702884..c68c3b5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ # Fetching Glaze needs CMake 3.31; an installed Glaze works with 3.21. cmake_minimum_required(VERSION 3.21...4.4) project(kalshi-cpp - VERSION 0.6.0 + VERSION 0.6.1 DESCRIPTION "C++23 client for the Kalshi Predictions API" HOMEPAGE_URL "https://github.com/Reddimus/kalshi-cpp" LANGUAGES CXX) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 381a2f5..0db1217 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -46,11 +46,20 @@ make docs # Doxygen API reference in build-docs/html (needs Doxygen) make bench # Google Benchmark suite make consumers # Build installed and FetchContent consumers make coverage # lcov report (needs lcov) +make lint-docs # markdownlint (needs markdownlint-cli2) ``` -Run `make format lint test` before pushing. `make install-hooks` runs format -and lint on every commit. CI adds the sanitizers, clang-tidy, and the consumer -check, on Linux, macOS, and Windows. +Run `make format lint test` before pushing, and `make lint-docs` (needs +`markdownlint-cli2`) after editing Markdown. `make install-hooks` runs +`make lint` on every commit. CI builds and tests on Linux, macOS, and Windows, +and runs the sanitizers, clang-tidy, and the consumer check on Linux. + +`make tidy` needs clang-tidy 18. On Ubuntu, build with the matching clang and +libc++, as CI does: + +```bash +make tidy CMAKE_ARGS="-DCMAKE_CXX_COMPILER=clang++-18 -DCMAKE_CXX_FLAGS=-stdlib=libc++" +``` ## Generated code @@ -90,7 +99,9 @@ explains how to refresh the specs. ## Releases 1. Set `VERSION` in `CMakeLists.txt`, move the `[Unreleased]` notes into a new - `[X.Y.Z]` section, and update the `GIT_TAG` in `README.md`. + `[X.Y.Z]` section, update the compare links at the bottom of + `CHANGELOG.md`, and update the `GIT_TAG` in `README.md`. Release notes + come from that section, so link with absolute URLs. 2. Merge that change to `main`. 3. Run `git tag vX.Y.Z && git push origin vX.Y.Z`. `release.yml` publishes the GitHub release after CI passes on the tagged commit, and `docs.yml` diff --git a/Makefile b/Makefile index ec4f842..e23f243 100644 --- a/Makefile +++ b/Makefile @@ -73,10 +73,11 @@ format: pre-commit: format lint -# Installs a hook that runs `make pre-commit`. Works in worktrees too. +# Installs a hook that runs `make lint` on every commit, so unformatted code +# fails instead of being formatted after it is staged. Works in worktrees too. install-hooks: @hook="$$(git rev-parse --git-path hooks)/pre-commit"; \ - printf '#!/bin/sh\nexec make pre-commit\n' > "$$hook" && chmod +x "$$hook" && \ + printf '#!/bin/sh\nexec make lint\n' > "$$hook" && chmod +x "$$hook" && \ echo "Installed $$hook" # Needs lcov and genhtml. @@ -113,7 +114,7 @@ help: @echo "make lint-docs markdownlint" @echo "make format Format C++ sources in place" @echo "make pre-commit format + lint" - @echo "make install-hooks Run pre-commit on every git commit" + @echo "make install-hooks Run make lint on every git commit" @echo "make coverage lcov report in build-coverage/html" @echo "make run-NAME Run examples/NAME.cpp with .env loaded (ARGS=...)" @echo "make clean Remove build directories" diff --git a/README.md b/README.md index 602ac84..1688e38 100644 --- a/README.md +++ b/README.md @@ -18,11 +18,14 @@ scope. ## Build You need a C++23 compiler, CMake 3.31+, OpenSSL 3, libcurl, and libwebsockets. -Ubuntu 24.04's apt CMake is older; `pipx install cmake` gets a current one. ```bash -brew install cmake openssl curl libwebsockets pkg-config # macOS -sudo apt install cmake libssl-dev libcurl4-openssl-dev libwebsockets-dev pkg-config # Ubuntu +# macOS +brew install cmake openssl curl libwebsockets pkg-config + +# Ubuntu 24.04, whose apt CMake is older than 3.31 +sudo apt install build-essential pkg-config pipx libssl-dev libcurl4-openssl-dev libwebsockets-dev +pipx install cmake && pipx ensurepath # then open a new shell cmake -S . -B build -DCMAKE_BUILD_TYPE=Release cmake --build build --parallel @@ -35,7 +38,7 @@ ctest --test-dir build --output-on-failure include(FetchContent) FetchContent_Declare(kalshi GIT_REPOSITORY https://github.com/Reddimus/kalshi-cpp.git - GIT_TAG v0.6.0) + GIT_TAG v0.6.1) FetchContent_MakeAvailable(kalshi) target_link_libraries(myapp PRIVATE kalshi::kalshi) ``` @@ -73,9 +76,10 @@ int main() { ## Authenticate -Create a key under API keys at . Kalshi -recommends Ed25519; generating the pair yourself keeps the private key off the -website: +Create a key under API keys at and save +the private key file Kalshi gives you. Kalshi recommends Ed25519 keys. If the +page offers to use your own public key, you can generate the pair locally so +the private key never leaves your machine: ```bash openssl genpkey -algorithm ed25519 -out kalshi.key @@ -84,7 +88,11 @@ openssl pkey -in kalshi.key -pubout # paste this public key into Kalshi ```cpp kalshi::Result signer = kalshi::Signer::from_pem_file(key_id, "kalshi.key"); -kalshi::KalshiClient client{kalshi::HttpClient{std::move(*signer)}}; +if (!signer) { + std::cerr << signer.error().message << '\n'; + return 1; +} +kalshi::KalshiClient client{kalshi::HttpClient{*signer}}; // Signer is cheap to copy kalshi::Result balance = client.get_balance(); ``` @@ -121,7 +129,7 @@ Kalshi's status and error code, and `Error::message` includes its explanation. Both are transports you stack under the client: ```cpp -std::shared_ptr http = std::make_shared(std::move(*signer)); +std::shared_ptr http = std::make_shared(*signer); std::shared_ptr paced = std::make_shared(http, kalshi::RateLimitConfig{}); kalshi::KalshiClient client{std::make_shared(paced)}; diff --git a/include/README.md b/include/README.md index 8d479c5..ecc1065 100644 --- a/include/README.md +++ b/include/README.md @@ -17,6 +17,8 @@ | `kalshi/error.hpp` | `Error`, `ErrorCode`, and `Result` | | `kalshi/environment.hpp` | Production and demo URLs | | `kalshi/fixed_point.hpp` | Exact decimal parsing | +| `kalshi/raw_json.hpp` | `RawJson`, free-form JSON kept as text | +| `kalshi/version.hpp` | `kalshi::VERSION` (generated at configure time) | Headers under `kalshi/detail/` support the implementation and tests. They are not a stable interface. diff --git a/include/kalshi/api.hpp b/include/kalshi/api.hpp index 97cadeb..ad16ae0 100644 --- a/include/kalshi/api.hpp +++ b/include/kalshi/api.hpp @@ -18,8 +18,9 @@ namespace kalshi { /// operation in Kalshi's OpenAPI document, named after its operationId. /// /// Failures come back as `Error`: `InvalidRequest` for a request the SDK -/// rejects before sending (or HTTP 400/409/422), `AuthenticationError`, -/// `NotFound`, `RateLimited`, `ServerError`, `NetworkError`, or `ParseError`. +/// rejects before sending or another HTTP 4xx, `AuthenticationError`, +/// `NotFound`, `RateLimited`, `ServerError`, `NetworkError`, `ParseError`, +/// or `SigningError`. /// `Error::api_code` carries Kalshi's machine-readable code when it sends one. class KalshiClient { public: diff --git a/include/kalshi/detail/http_path.hpp b/include/kalshi/detail/http_path.hpp index 7d09656..208b823 100644 --- a/include/kalshi/detail/http_path.hpp +++ b/include/kalshi/detail/http_path.hpp @@ -18,7 +18,7 @@ namespace kalshi::detail { return result; } -/// Build the URL path covered by Kalshi's RSA-PSS signature. +/// Build the URL path covered by Kalshi's request signature. /// /// Kalshi signs the full path from the host root, including the base URL's /// `/trade-api/v2` prefix, but excludes the query string. diff --git a/include/kalshi/error.hpp b/include/kalshi/error.hpp index 402577f..67face8 100644 --- a/include/kalshi/error.hpp +++ b/include/kalshi/error.hpp @@ -29,19 +29,19 @@ struct Error { std::string api_code; [[nodiscard]] static Error network(std::string msg) { - return {ErrorCode::NetworkError, std::move(msg)}; + return {ErrorCode::NetworkError, std::move(msg), 0, {}}; } [[nodiscard]] static Error auth(std::string msg) { - return {ErrorCode::AuthenticationError, std::move(msg)}; + return {ErrorCode::AuthenticationError, std::move(msg), 0, {}}; } [[nodiscard]] static Error parse(std::string msg) { - return {ErrorCode::ParseError, std::move(msg)}; + return {ErrorCode::ParseError, std::move(msg), 0, {}}; } [[nodiscard]] static Error signing(std::string msg) { - return {ErrorCode::SigningError, std::move(msg)}; + return {ErrorCode::SigningError, std::move(msg), 0, {}}; } }; diff --git a/include/kalshi/fixed_point.hpp b/include/kalshi/fixed_point.hpp index a755b11..3f07291 100644 --- a/include/kalshi/fixed_point.hpp +++ b/include/kalshi/fixed_point.hpp @@ -14,13 +14,14 @@ class FixedPoint { public: [[nodiscard]] static Result parse(std::string_view value) { if (value.empty()) { - return std::unexpected(Error{ErrorCode::InvalidRequest, "fixed-point value is empty"}); + return std::unexpected( + Error{ErrorCode::InvalidRequest, "fixed-point value is empty", 0, {}}); } std::size_t index = value.front() == '-' ? 1 : 0; if (index == value.size()) { return std::unexpected( - Error{ErrorCode::InvalidRequest, "fixed-point value has no digits"}); + Error{ErrorCode::InvalidRequest, "fixed-point value has no digits", 0, {}}); } bool saw_digit = false; @@ -37,10 +38,12 @@ class FixedPoint { saw_decimal = true; continue; } - return std::unexpected(Error{ErrorCode::InvalidRequest, "invalid fixed-point value"}); + return std::unexpected( + Error{ErrorCode::InvalidRequest, "invalid fixed-point value", 0, {}}); } if (!saw_digit || (saw_decimal && !fractional_digit)) { - return std::unexpected(Error{ErrorCode::InvalidRequest, "invalid fixed-point value"}); + return std::unexpected( + Error{ErrorCode::InvalidRequest, "invalid fixed-point value", 0, {}}); } return FixedPoint(std::string(value)); } @@ -51,8 +54,8 @@ class FixedPoint { /// Returns InvalidRequest instead of rounding or saturating. [[nodiscard]] Result scaled_integer(std::uint8_t scale) const { if (scale > 18) { - return std::unexpected( - Error{ErrorCode::InvalidRequest, "fixed-point scale exceeds int64 capacity"}); + return std::unexpected(Error{ + ErrorCode::InvalidRequest, "fixed-point scale exceeds int64 capacity", 0, {}}); } const bool negative = wire_.front() == '-'; @@ -67,7 +70,9 @@ class FixedPoint { for (std::size_t i = fractional_start + scale; i < wire_.size(); ++i) { if (wire_[i] != '0') { return std::unexpected(Error{ErrorCode::InvalidRequest, - "fixed-point conversion would lose precision"}); + "fixed-point conversion would lose precision", + 0, + {}}); } } } @@ -109,7 +114,7 @@ class FixedPoint { [[nodiscard]] static Result overflow_error() { return std::unexpected( - Error{ErrorCode::InvalidRequest, "fixed-point value does not fit in int64"}); + Error{ErrorCode::InvalidRequest, "fixed-point value does not fit in int64", 0, {}}); } std::string wire_; diff --git a/include/kalshi/version.hpp.in b/include/kalshi/version.hpp.in index 531f502..21fb845 100644 --- a/include/kalshi/version.hpp.in +++ b/include/kalshi/version.hpp.in @@ -1,28 +1,19 @@ #pragma once /// @file version.hpp -/// @brief Version constants for the Kalshi C++ SDK. -/// -/// This header is generated at CMake configure time from -/// `version.hpp.in` via `configure_file()`. The substituted values -/// come from CMakeLists.txt's `project(kalshi-cpp VERSION ...)` -/// declaration — that's the single source of truth. -/// -/// Do NOT edit the generated copy in the build directory. Edit -/// CMakeLists.txt to change the version; this header re-generates. +/// @brief The SDK version, generated from `project(... VERSION)` in CMakeLists.txt. namespace kalshi { /// Full SDK version, "MAJOR.MINOR.PATCH". constexpr const char* VERSION = "@PROJECT_VERSION@"; -/// Major version component (incompatible API changes). constexpr int VERSION_MAJOR = @PROJECT_VERSION_MAJOR@; -/// Minor version component (backwards-compatible additions). +/// While VERSION_MAJOR is 0, a new minor version may break the API. constexpr int VERSION_MINOR = @PROJECT_VERSION_MINOR@; -/// Patch version component (backwards-compatible fixes). +/// Patch releases fix bugs without changing the API. constexpr int VERSION_PATCH = @PROJECT_VERSION_PATCH@; } // namespace kalshi diff --git a/src/http/rate_limited_transport.cpp b/src/http/rate_limited_transport.cpp index 13d4059..e49500f 100644 --- a/src/http/rate_limited_transport.cpp +++ b/src/http/rate_limited_transport.cpp @@ -117,8 +117,9 @@ Result RateLimitedTransport::request(HttpMethod method, std::strin std::to_string(bucket.config().capacity) + "; split the batch"}); } if (!bucket.acquire_for(tokens, config_.max_wait)) { - return std::unexpected(Error{ErrorCode::RateLimited, - "Rate-limit tokens would not refill within max_wait", 429}); + // No server answered, so http_status stays 0. + return std::unexpected(Error{ + ErrorCode::RateLimited, "Rate-limit tokens would not refill within max_wait", 0, {}}); } return inner_->request(method, path, body); } diff --git a/tests/README.md b/tests/README.md index 6714072..03d607b 100644 --- a/tests/README.md +++ b/tests/README.md @@ -13,6 +13,11 @@ memory. | `test_http_client.cpp` | The libcurl transport, POSIX only | | `test_transports.cpp` | Retries, token buckets, rate limiting | | `test_signer.cpp` | Ed25519 and RSA-PSS signing | +| `test_helpers.cpp` | Cents, contracts, timestamps, order directions, pagination | +| `test_fixed_point.cpp` | Exact decimal parsing and scaling | +| `test_features.cpp` | Defaults for configs and enums | +| `test_version.cpp` | `kalshi::VERSION` and its components | +| `parse_benchmark.cpp` | A coarse throughput guard, run as its own test | | `test_ws_messages.cpp` | Every example frame in the AsyncAPI spec (generated) | | `test_ws_frames.cpp` | Control frames, discriminated types, nulls, unknown values | | `test_ws_subscriptions.cpp` | Command frames, held commands, resubscribing, gaps | diff --git a/tests/parse_benchmark.cpp b/tests/parse_benchmark.cpp index e20c4b5..27b860a 100644 --- a/tests/parse_benchmark.cpp +++ b/tests/parse_benchmark.cpp @@ -62,7 +62,7 @@ int main(int argc, char** argv) { } if (glaze_checksum == 0) { - std::fprintf(stderr, "checksum is zero — render_body emitted nothing\n"); + std::fprintf(stderr, "checksum is zero: encode() produced nothing\n"); return 1; } @@ -73,10 +73,7 @@ int main(int argc, char** argv) { std::printf("parse_benchmark: payload=%zuB iters=%d\n", sample.size(), kIterations); std::printf(" glaze (serialize): %8.3f ms total (%8.3f us/op)\n", glaze_ms, us_per_op); - // Regression guard: at migration time, Glaze rendered a 50-order - // batch in ~30-60 us/op on x86_64-v3 / -O3 / LTO. Cap at 500 us/op - // — that's ~10x the measured baseline and accounts for slower CI - // runners, Debug builds, and AddressSanitizer overhead. + // About 10x the measured cost of encoding a 50-order batch, to absorb slow runners. constexpr double kMaxUsPerOp = 500.0; if (check_timing && us_per_op > kMaxUsPerOp) { std::fprintf(stderr, "REGRESSION: %.3f us/op exceeds cap of %.0f us/op\n", us_per_op, diff --git a/tools/README.md b/tools/README.md index 7f9fe28..433ddfa 100644 --- a/tools/README.md +++ b/tools/README.md @@ -7,7 +7,7 @@ | `project_version.sh` | Prints the version declared in `CMakeLists.txt` | | `test_consumers.sh` | Builds installed and FetchContent consumers (`make consumers`) | -The generator needs PyYAML (`python3 -m pip install pyyaml`) and clang-format +The generator needs PyYAML (`python3-yaml`, or pip in a virtual environment) and clang-format 18. `make codegen` runs it, and `make lint` fails when its output is stale. `codegen/api.hpp.in` and `codegen/ws_models.hpp.in` hold the hand-written parts of the generated headers; `codegen/ws.py` maps the AsyncAPI document. diff --git a/tools/codegen/api.hpp.in b/tools/codegen/api.hpp.in index 4dd5cb7..821e2a1 100644 --- a/tools/codegen/api.hpp.in +++ b/tools/codegen/api.hpp.in @@ -17,8 +17,9 @@ namespace kalshi { /// operation in Kalshi's OpenAPI document, named after its operationId. /// /// Failures come back as `Error`: `InvalidRequest` for a request the SDK -/// rejects before sending (or HTTP 400/409/422), `AuthenticationError`, -/// `NotFound`, `RateLimited`, `ServerError`, `NetworkError`, or `ParseError`. +/// rejects before sending or another HTTP 4xx, `AuthenticationError`, +/// `NotFound`, `RateLimited`, `ServerError`, `NetworkError`, `ParseError`, +/// or `SigningError`. /// `Error::api_code` carries Kalshi's machine-readable code when it sends one. class KalshiClient { public: diff --git a/tools/codegen/generate.py b/tools/codegen/generate.py index 64380d9..161c469 100644 --- a/tools/codegen/generate.py +++ b/tools/codegen/generate.py @@ -4,7 +4,7 @@ python3 tools/codegen/generate.py # rewrite the generated files python3 tools/codegen/generate.py --check # exit 1 if they are out of date -Needs PyYAML (`python3 -m pip install pyyaml`). Generated files start with a +Needs PyYAML (`python3-yaml`, or pip in a virtual environment). Generated files start with a "Generated by" banner; edit this script, not them. Mapping rules: @@ -35,7 +35,7 @@ try: import yaml except ImportError: # pragma: no cover - guidance for developers - sys.exit("PyYAML is required: python3 -m pip install pyyaml") + sys.exit("PyYAML is required: install python3-yaml, or pip install pyyaml in a virtual environment") from common import (CPP_RESERVED, ROOT, EnumType, Member, StructType, check_enums, clang_format, doc_lines, emit_enum, emit_enum_adapter, emit_enum_parser, emit_struct, diff --git a/tools/cpp_auto_audit.py b/tools/cpp_auto_audit.py index 30d2137..5e9b0d4 100644 --- a/tools/cpp_auto_audit.py +++ b/tools/cpp_auto_audit.py @@ -7,9 +7,8 @@ - allow ``auto`` for iterator-like values - allow explicit one-off exceptions marked with ``auto-ok`` -Everything else is expected to spell out the type directly. Repos can -carry a local allowlist while older files are being burned down. The -allowlist format is one rule per line: +Everything else is expected to spell out the type directly. The optional +allowlist takes one rule per line: relative/path.cpp|line snippet diff --git a/tools/test_consumers.sh b/tools/test_consumers.sh index efd1552..a6eff43 100755 --- a/tools/test_consumers.sh +++ b/tools/test_consumers.sh @@ -58,6 +58,8 @@ project(kalshi_installed_consumer LANGUAGES CXX) find_package(kalshi $minor CONFIG REQUIRED) add_executable(consumer main.cpp) target_link_libraries(consumer PRIVATE kalshi::kalshi) +# Public headers must stay warning-free for projects that build with -Werror. +target_compile_options(consumer PRIVATE -Wall -Wextra -Wpedantic -Werror) CMAKE cmake -S "$scratch_dir/installed" -B "$scratch_dir/installed-build" \ -DCMAKE_PREFIX_PATH="$scratch_dir/prefix" @@ -77,6 +79,8 @@ if(TARGET kalshi_tests OR TARGET example_market_data) endif() add_executable(consumer main.cpp) target_link_libraries(consumer PRIVATE kalshi::kalshi) +# Public headers must stay warning-free for projects that build with -Werror. +target_compile_options(consumer PRIVATE -Wall -Wextra -Wpedantic -Werror) CMAKE cmake -S "$scratch_dir/fetched" -B "$scratch_dir/fetched-build" cmake --build "$scratch_dir/fetched-build" --parallel