Skip to content

Commit e718047

Browse files
Add multi-platform build support for x86_64 and ARM64
1 parent 0359918 commit e718047

File tree

6 files changed

+295
-36
lines changed

6 files changed

+295
-36
lines changed

.github/workflows/build-pull-request.yml

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,8 @@ jobs:
7171
path: mock-trading-server/target/release/mock-trading-server
7272
retention-days: 7
7373

74-
cpp-client:
75-
name: Build C++ Client
74+
cpp-client-linux:
75+
name: Build C++ Client (Linux)
7676
runs-on: ubuntu-latest
7777
defaults:
7878
run:
@@ -100,10 +100,52 @@ jobs:
100100
- name: Upload binary
101101
uses: actions/upload-artifact@v4
102102
with:
103-
name: cpp-client-binary
103+
name: cpp-client-linux-binary
104104
path: cpp-client/build/*
105105
retention-days: 7
106106

107+
cpp-client-windows:
108+
name: Build C++ Client (Windows)
109+
runs-on: windows-latest
110+
defaults:
111+
run:
112+
working-directory: cpp-client
113+
steps:
114+
- name: Checkout code
115+
uses: actions/checkout@v5
116+
with:
117+
submodules: recursive
118+
119+
- name: Setup vcpkg
120+
run: |
121+
git clone https://github.com/Microsoft/vcpkg.git ../vcpkg
122+
cd ../vcpkg
123+
.\bootstrap-vcpkg.bat
124+
.\vcpkg integrate install
125+
126+
- name: Install dependencies (static)
127+
run: |
128+
cd ../vcpkg
129+
.\vcpkg install openssl:x64-windows-static zlib:x64-windows-static
130+
131+
- name: Configure CMake
132+
shell: bash
133+
run: |
134+
cmake -B build \
135+
-DCMAKE_BUILD_TYPE=Release \
136+
-DCMAKE_TOOLCHAIN_FILE=../vcpkg/scripts/buildsystems/vcpkg.cmake \
137+
-DVCPKG_TARGET_TRIPLET=x64-windows-static
138+
139+
- name: Build (static linking)
140+
run: cmake --build build --config Release
141+
142+
- name: Upload binary
143+
uses: actions/upload-artifact@v4
144+
with:
145+
name: cpp-client-windows-binary
146+
path: cpp-client/build/Release/hft_client.exe
147+
retention-days: 7
148+
107149
cdk-infrastructure:
108150
name: Build CDK Infrastructure
109151
runs-on: ubuntu-latest

.github/workflows/release.yml

Lines changed: 149 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -186,51 +186,152 @@ jobs:
186186
name: rust-windows
187187
path: mock-trading-server-${{ steps.get_version.outputs.VERSION }}-windows-x86_64.exe
188188

189-
build-cpp:
190-
name: Build C++ Client
189+
build-cpp-linux:
190+
name: Build C++ Client (Linux)
191191
runs-on: ubuntu-latest
192-
container: public.ecr.aws/amazonlinux/amazonlinux:2023
192+
strategy:
193+
matrix:
194+
include:
195+
- arch: x86_64
196+
platform: linux/amd64
197+
container: public.ecr.aws/amazonlinux/amazonlinux:2023
198+
- arch: aarch64
199+
platform: linux/arm64
200+
container: public.ecr.aws/amazonlinux/amazonlinux:2023
193201
steps:
194-
- name: Install build tools
195-
run: |
196-
yum install -y gcc-c++ make git tar gzip boost-devel openssl-devel python3-pip zlib-devel
197-
# Install newer CMake (AL2023 has 3.22, but we need 3.27+)
198-
pip3 install cmake --upgrade
199-
# Ensure cmake from pip is in PATH
200-
export PATH="/usr/local/bin:$HOME/.local/bin:$PATH"
201-
echo "/usr/local/bin" >> $GITHUB_PATH
202-
echo "$HOME/.local/bin" >> $GITHUB_PATH
203-
cmake --version
202+
- name: Set up QEMU
203+
if: matrix.arch == 'aarch64'
204+
uses: docker/setup-qemu-action@v3
205+
with:
206+
platforms: arm64
207+
208+
- name: Checkout code
209+
uses: actions/checkout@v5
210+
with:
211+
submodules: recursive
212+
213+
- name: Get version
214+
id: get_version
215+
run: echo "VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
204216

217+
- name: Build in container
218+
run: |
219+
docker run --rm --platform ${{ matrix.platform }} \
220+
-v ${{ github.workspace }}:/workspace \
221+
-w /workspace \
222+
${{ matrix.container }} \
223+
bash -c '
224+
yum install -y gcc-c++ make git tar gzip openssl-devel python3-pip zlib-devel
225+
pip3 install cmake --upgrade
226+
export PATH="/usr/local/bin:$HOME/.local/bin:$PATH"
227+
cd cpp-client
228+
cmake -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_POLICY_VERSION_MINIMUM=3.5
229+
cmake --build build --config Release
230+
cd build
231+
tar -czf ../../cpp-client-${{ steps.get_version.outputs.VERSION }}-linux-${{ matrix.arch }}.tar.gz hft_client
232+
'
233+
234+
- name: Upload artifact
235+
uses: actions/upload-artifact@v4
236+
with:
237+
name: cpp-linux-${{ matrix.arch }}
238+
path: cpp-client-${{ steps.get_version.outputs.VERSION }}-linux-${{ matrix.arch }}.tar.gz
239+
240+
build-cpp-macos:
241+
name: Build C++ Client (macOS)
242+
runs-on: ${{ matrix.os }}
243+
strategy:
244+
matrix:
245+
include:
246+
- os: macos-13
247+
arch: x86_64
248+
- os: macos-14
249+
arch: arm64
250+
steps:
205251
- name: Checkout code
206252
uses: actions/checkout@v5
207253
with:
208254
submodules: recursive
209255

256+
- name: Install dependencies
257+
run: |
258+
brew install cmake openssl@3
259+
210260
- name: Get version
211261
id: get_version
212262
run: echo "VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
213263

214264
- name: Build
215265
working-directory: cpp-client
216266
run: |
217-
cmake -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_POLICY_VERSION_MINIMUM=3.5
267+
export OPENSSL_ROOT_DIR=$(brew --prefix openssl@3)
268+
cmake -B build \
269+
-DCMAKE_BUILD_TYPE=Release \
270+
-DOPENSSL_ROOT_DIR=$OPENSSL_ROOT_DIR
218271
cmake --build build --config Release
219272
220273
- name: Create tarball
221274
run: |
222275
cd cpp-client/build
223-
tar -czf ../../cpp-client-${{ steps.get_version.outputs.VERSION }}.tar.gz .
276+
tar -czf ../../cpp-client-${{ steps.get_version.outputs.VERSION }}-macos-${{ matrix.arch }}.tar.gz hft_client
277+
278+
- name: Upload artifact
279+
uses: actions/upload-artifact@v4
280+
with:
281+
name: cpp-macos-${{ matrix.arch }}
282+
path: cpp-client-${{ steps.get_version.outputs.VERSION }}-macos-${{ matrix.arch }}.tar.gz
283+
284+
build-cpp-windows:
285+
name: Build C++ Client (Windows)
286+
runs-on: windows-latest
287+
steps:
288+
- name: Checkout code
289+
uses: actions/checkout@v5
290+
with:
291+
submodules: recursive
292+
293+
- name: Setup vcpkg
294+
run: |
295+
git clone https://github.com/Microsoft/vcpkg.git
296+
cd vcpkg
297+
.\bootstrap-vcpkg.bat
298+
.\vcpkg integrate install
299+
300+
- name: Install dependencies (static)
301+
run: |
302+
cd vcpkg
303+
.\vcpkg install openssl:x64-windows-static zlib:x64-windows-static
304+
305+
- name: Get version
306+
id: get_version
307+
shell: bash
308+
run: echo "VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
224309

225-
- name: Upload tarball
310+
- name: Build (static linking)
311+
shell: bash
312+
working-directory: cpp-client
313+
run: |
314+
cmake -B build \
315+
-DCMAKE_BUILD_TYPE=Release \
316+
-DCMAKE_TOOLCHAIN_FILE=../vcpkg/scripts/buildsystems/vcpkg.cmake \
317+
-DVCPKG_TARGET_TRIPLET=x64-windows-static
318+
cmake --build build --config Release
319+
320+
- name: Create archive
321+
shell: bash
322+
run: |
323+
cd cpp-client/build/Release
324+
7z a ../../../cpp-client-${{ steps.get_version.outputs.VERSION }}-windows-x86_64.zip hft_client.exe
325+
326+
- name: Upload artifact
226327
uses: actions/upload-artifact@v4
227328
with:
228-
name: cpp-client
229-
path: cpp-client-${{ steps.get_version.outputs.VERSION }}.tar.gz
329+
name: cpp-windows-x86_64
330+
path: cpp-client-${{ steps.get_version.outputs.VERSION }}-windows-x86_64.zip
230331

231332
create-release:
232333
name: Create GitHub Release
233-
needs: [build-java, build-rust-linux, build-rust-macos, build-rust-windows, build-cpp]
334+
needs: [build-java, build-rust-linux, build-rust-macos, build-rust-windows, build-cpp-linux, build-cpp-macos, build-cpp-windows]
234335
runs-on: ubuntu-latest
235336
steps:
236337
- name: Checkout code
@@ -284,8 +385,8 @@ jobs:
284385
### 📦 Components
285386
286387
- **Java Trading Client** - ✅ Cross-platform (all architectures)
287-
- **Rust Mock Server** - ✅ Linux (x86_64 & ARM64), macOS (Intel & Apple Silicon), Windows
288-
- **C++ Client** - ✅ Linux x86_64
388+
- **Rust Mock Server** - ✅ Linux (x86_64 & ARM64/Graviton), macOS (Intel & Apple Silicon), Windows
389+
- **C++ Client** - ✅ Multi-platform: Linux (x86_64 & ARM64/Graviton), macOS (Intel & Apple Silicon), Windows
289390
- **Configuration Samples** - 📝 All config files with documentation
290391
291392
### 🚀 Quick Start
@@ -300,6 +401,33 @@ jobs:
300401
java -jar ExchangeFlow-${{ steps.get_version.outputs.VERSION }}.jar
301402
\`\`\`
302403
404+
**C++ Client (choose your platform):**
405+
- **Linux x86_64:**
406+
\`\`\`bash
407+
tar -xzf cpp-client-${{ steps.get_version.outputs.VERSION }}-linux-x86_64.tar.gz
408+
./hft_client
409+
\`\`\`
410+
- **Linux ARM64 (Graviton2/3/4):**
411+
\`\`\`bash
412+
tar -xzf cpp-client-${{ steps.get_version.outputs.VERSION }}-linux-aarch64.tar.gz
413+
./hft_client
414+
\`\`\`
415+
- **macOS Intel:**
416+
\`\`\`bash
417+
tar -xzf cpp-client-${{ steps.get_version.outputs.VERSION }}-macos-x86_64.tar.gz
418+
./hft_client
419+
\`\`\`
420+
- **macOS Apple Silicon:**
421+
\`\`\`bash
422+
tar -xzf cpp-client-${{ steps.get_version.outputs.VERSION }}-macos-arm64.tar.gz
423+
./hft_client
424+
\`\`\`
425+
- **Windows:**
426+
\`\`\`powershell
427+
Expand-Archive cpp-client-${{ steps.get_version.outputs.VERSION }}-windows-x86_64.zip
428+
.\\hft_client.exe
429+
\`\`\`
430+
303431
**Rust Server (choose your platform):**
304432
- **Linux x86_64:** \`./mock-trading-server-${{ steps.get_version.outputs.VERSION }}-linux-x86_64\`
305433
- **Linux ARM64 (Graviton):** \`./mock-trading-server-${{ steps.get_version.outputs.VERSION }}-linux-aarch64\`

cpp-client/CMakeLists.txt

Lines changed: 47 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,38 @@ project(hft_client)
44
set(CMAKE_CXX_STANDARD 17)
55
set(CMAKE_CXX_STANDARD_REQUIRED ON)
66

7+
# Set minimum policy version to allow older CMake syntax in dependencies
8+
set(CMAKE_POLICY_VERSION_MINIMUM 3.5)
9+
10+
# Define ASIO_STANDALONE globally BEFORE fetching any dependencies
11+
# This ensures WebSocket++ uses standalone ASIO instead of Boost.Asio
12+
add_compile_definitions(ASIO_STANDALONE)
13+
14+
# Force WebSocket++ to use C++11 standard library instead of Boost
15+
# This prevents WebSocket++ from trying to include boost headers
16+
add_compile_definitions(_WEBSOCKETPP_CPP11_RANDOM_DEVICE_)
17+
add_compile_definitions(_WEBSOCKETPP_CPP11_TYPE_TRAITS_)
18+
add_compile_definitions(_WEBSOCKETPP_CPP11_FUNCTIONAL_)
19+
add_compile_definitions(_WEBSOCKETPP_CPP11_SYSTEM_ERROR_)
20+
add_compile_definitions(_WEBSOCKETPP_CPP11_MEMORY_)
21+
22+
# Windows-specific: Fix byte ambiguity between Windows SDK and std::byte
23+
if(WIN32)
24+
add_compile_definitions(_HAS_STD_BYTE=0)
25+
endif()
26+
727
# Include FetchContent
828
include(FetchContent)
929

10-
# Find Boost
11-
find_package(Boost 1.74.0 REQUIRED COMPONENTS system)
30+
# Fetch standalone ASIO (replaces Boost.Asio to avoid version compatibility issues)
31+
FetchContent_Declare(
32+
asio
33+
GIT_REPOSITORY https://github.com/chriskohlhoff/asio.git
34+
GIT_TAG asio-1-30-2
35+
)
36+
FetchContent_MakeAvailable(asio)
1237

13-
# Fetch WebSocket++
38+
# Fetch WebSocket++ (configured to use standalone ASIO via ASIO_STANDALONE definition)
1439
FetchContent_Declare(
1540
websocketpp
1641
GIT_REPOSITORY https://github.com/zaphoyd/websocketpp.git
@@ -50,26 +75,42 @@ add_executable(${PROJECT_NAME}
5075
Logger.h
5176
)
5277

78+
# Add Windows resource file with version information
79+
if(WIN32)
80+
target_sources(${PROJECT_NAME} PRIVATE hft_client.rc)
81+
endif()
82+
5383
# Set include directories for the target
5484
target_include_directories(${PROJECT_NAME}
5585
PRIVATE
5686
${CMAKE_CURRENT_SOURCE_DIR}
5787
${CMAKE_CURRENT_SOURCE_DIR}/include
5888
${websocketpp_SOURCE_DIR}
89+
${asio_SOURCE_DIR}/asio/include
5990
${OPENSSL_INCLUDE_DIR}
6091
${hdr_histogram_SOURCE_DIR}/src
6192
${hdr_histogram_SOURCE_DIR}/include
62-
${Boost_INCLUDE_DIRS}
6393
)
6494

65-
# Link libraries
95+
# Define ASIO_STANDALONE to use standalone ASIO instead of Boost.Asio
96+
# Force WebSocket++ to use C++11 standard library instead of Boost
97+
target_compile_definitions(${PROJECT_NAME}
98+
PRIVATE
99+
ASIO_STANDALONE
100+
_WEBSOCKETPP_CPP11_RANDOM_DEVICE_
101+
_WEBSOCKETPP_CPP11_TYPE_TRAITS_
102+
_WEBSOCKETPP_CPP11_FUNCTIONAL_
103+
_WEBSOCKETPP_CPP11_SYSTEM_ERROR_
104+
_WEBSOCKETPP_CPP11_MEMORY_
105+
)
106+
107+
# Link libraries (no Boost needed with standalone ASIO)
66108
target_link_libraries(${PROJECT_NAME}
67109
PRIVATE
68110
OpenSSL::SSL
69111
OpenSSL::Crypto
70112
hdr_histogram_static
71113
nlohmann_json::nlohmann_json
72-
Boost::system
73114
)
74115

75116
# Additional compiler warnings

cpp-client/ExchangeClient.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -108,11 +108,11 @@ void ExchangeClient::disconnect() {
108108
}
109109
}
110110

111-
std::shared_ptr<boost::asio::ssl::context> ExchangeClient::tls_init_handler() {
112-
std::shared_ptr<boost::asio::ssl::context> ctx = std::make_shared<boost::asio::ssl::context>(boost::asio::ssl::context::tlsv12_client);
111+
std::shared_ptr<asio::ssl::context> ExchangeClient::tls_init_handler() {
112+
std::shared_ptr<asio::ssl::context> ctx = std::make_shared<asio::ssl::context>(asio::ssl::context::tlsv12_client);
113113
try {
114-
boost::system::error_code ec;
115-
ctx->set_options(boost::asio::ssl::context::default_workarounds, ec);
114+
asio::error_code ec;
115+
ctx->set_options(asio::ssl::context::default_workarounds, ec);
116116
if (ec) {
117117
std::cout << "Error setting SSL options: " << ec.message() << std::endl;
118118
}
@@ -140,4 +140,4 @@ void ExchangeClient::addBalances(const std::string& qt) {
140140
} catch (const std::exception& e) {
141141
logger("Error: " + std::string(e.what()));
142142
}
143-
}
143+
}

0 commit comments

Comments
 (0)