[FEAT]: VCPKG

This commit is contained in:
2025-12-21 07:49:28 +05:30
parent 74678d4c4f
commit a956f7b770
13 changed files with 226 additions and 110 deletions

View File

@ -98,19 +98,16 @@ set(EXPECTED_BUILD_TESTS OFF CACHE BOOL "" FORCE)
set(HTTPLIB_REQUIRE_OPENSSL OFF CACHE BOOL "" FORCE) set(HTTPLIB_REQUIRE_OPENSSL OFF CACHE BOOL "" FORCE)
set(HTTPLIB_REQUIRE_ZLIB OFF CACHE BOOL "" FORCE) set(HTTPLIB_REQUIRE_ZLIB OFF CACHE BOOL "" FORCE)
set(HTTPLIB_NO_EXCEPTIONS ON CACHE BOOL "" FORCE)
set(ZSTD_BUILD_SHARED OFF CACHE BOOL "" FORCE) set(ZSTD_BUILD_SHARED OFF CACHE BOOL "" FORCE)
set(ZSTD_BUILD_STATIC ON CACHE BOOL "" FORCE) set(ZSTD_BUILD_STATIC ON CACHE BOOL "" FORCE)
set(ZLIB_COMPAT ON CACHE BOOL "" FORCE) set(ZLIB_COMPAT ON CACHE BOOL "" FORCE)
set(ZLIB_ENABLE_TESTS OFF CACHE BOOL "" FORCE) set(BUILD_TESTING OFF CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(ZLIB zstd) FetchContent_MakeAvailable(ZLIB zstd)
if(TARGET libzstd_static AND NOT TARGET zstd::libzstd)
add_library(zstd::libzstd ALIAS libzstd_static)
endif()
FetchContent_MakeAvailable(httplib pugixml nlohmann_json glaze simdjson tl-expected unordered_dense mimalloc) FetchContent_MakeAvailable(httplib pugixml nlohmann_json glaze simdjson tl-expected unordered_dense mimalloc)
find_package(OpenSSL REQUIRED) find_package(OpenSSL REQUIRED)

View File

@ -0,0 +1,7 @@
set(VCPKG_TARGET_ARCHITECTURE arm64)
set(VCPKG_CRT_LINKAGE dynamic)
set(VCPKG_LIBRARY_LINKAGE static)
set(VCPKG_CMAKE_SYSTEM_NAME Linux)
set(VCPKG_C_FLAGS "-march=armv8-a+simd")
set(VCPKG_CXX_FLAGS "-march=armv8-a+simd")

View File

@ -0,0 +1,9 @@
set(VCPKG_TARGET_ARCHITECTURE arm64)
set(VCPKG_CRT_LINKAGE dynamic)
set(VCPKG_LIBRARY_LINKAGE static)
set(VCPKG_CMAKE_SYSTEM_NAME Windows)
set(VCPKG_POLICY_EMPTY_PACKAGE enabled)
set(VCPKG_C_FLAGS "--target=arm64-pc-windows-msvc")
set(VCPKG_CXX_FLAGS "--target=arm64-pc-windows-msvc")

View File

@ -0,0 +1,9 @@
set(VCPKG_TARGET_ARCHITECTURE wasm32)
set(VCPKG_CRT_LINKAGE dynamic)
set(VCPKG_LIBRARY_LINKAGE static)
set(VCPKG_CMAKE_SYSTEM_NAME Emscripten)
set(VCPKG_C_FLAGS "-msimd128 -pthread")
set(VCPKG_CXX_FLAGS "-msimd128 -pthread")
set(VCPKG_CHAINLOAD_TOOLCHAIN_FILE "$ENV{EMSDK}/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake")

View File

@ -0,0 +1,7 @@
set(VCPKG_TARGET_ARCHITECTURE x64)
set(VCPKG_CRT_LINKAGE dynamic)
set(VCPKG_LIBRARY_LINKAGE static)
set(VCPKG_CMAKE_SYSTEM_NAME Linux)
set(VCPKG_C_FLAGS "-mavx2 -mfma")
set(VCPKG_CXX_FLAGS "-mavx2 -mfma")

View File

@ -12,103 +12,74 @@
"binaryDir": "${sourceDir}/out/build/${presetName}", "binaryDir": "${sourceDir}/out/build/${presetName}",
"cacheVariables": { "cacheVariables": {
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON", "CMAKE_EXPORT_COMPILE_COMMANDS": "ON",
"CMAKE_C_COMPILER": "clang", "WITH_AVX2": "ON",
"CMAKE_CXX_COMPILER": "clang++" "WITH_NEON": "ON",
"VCPKG_OVERLAY_TRIPLETS": "${sourceDir}/CMake/Triplets",
"CMAKE_TOOLCHAIN_FILE": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake"
} }
}, },
{ {
"name": "windows-base", "name": "linux-x64",
"hidden": true, "displayName": "Linux x64 (AVX2)",
"inherits": "base-common", "inherits": "base-common",
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Windows"
},
"cacheVariables": { "cacheVariables": {
"CMAKE_SYSTEM_NAME": "Linux",
"CMAKE_SYSTEM_PROCESSOR": "x86_64",
"CMAKE_C_FLAGS": "-mavx2 -mfma",
"CMAKE_CXX_FLAGS": "-mavx2 -mfma",
"VCPKG_TARGET_TRIPLET": "x64-linux"
}
},
{
"name": "linux-arm64",
"displayName": "Linux ARM64 (NEON)",
"inherits": "base-common",
"cacheVariables": {
"CMAKE_SYSTEM_NAME": "Linux",
"CMAKE_SYSTEM_PROCESSOR": "aarch64",
"CMAKE_C_COMPILER_TARGET": "aarch64-linux-gnu",
"CMAKE_CXX_COMPILER_TARGET": "aarch64-linux-gnu",
"CMAKE_CXX_FLAGS": "-march=armv8-a+simd",
"CMAKE_SYSROOT": "/usr/aarch64-linux-gnu",
"VCPKG_TARGET_TRIPLET": "arm64-linux"
}
},
{
"name": "windows-x64",
"displayName": "Windows x64 (AVX2)",
"inherits": "base-common",
"cacheVariables": {
"CMAKE_SYSTEM_NAME": "Windows",
"CMAKE_SYSTEM_PROCESSOR": "x86_64",
"CMAKE_C_COMPILER": "clang-cl", "CMAKE_C_COMPILER": "clang-cl",
"CMAKE_CXX_COMPILER": "clang-cl", "CMAKE_CXX_COMPILER": "clang-cl",
"CMAKE_TOOLCHAIN_FILE": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake", "CMAKE_CXX_FLAGS": "/arch:AVX2",
"VCPKG_TARGET_TRIPLET": "x64-windows" "VCPKG_TARGET_TRIPLET": "x64-windows"
} }
}, },
{ {
"name": "linux-base", "name": "windows-arm64",
"hidden": true, "displayName": "Windows ARM64 (NEON)",
"inherits": "base-common", "inherits": "base-common",
"condition": {
"type": "notEquals",
"lhs": "${hostSystemName}",
"rhs": "Windows"
}
},
{
"name": "windows-default",
"displayName": "Windows (Clang-CL + VCPKG)",
"description": "Windows build using Clang-CL and VCPKG dependencies",
"inherits": "windows-base"
},
{
"name": "linux-default",
"displayName": "Linux (Clang)",
"description": "Linux build using Clang",
"inherits": "linux-base"
},
{
"name": "linux-ci",
"displayName": "Linux CI Build",
"description": "Linux CI Build",
"inherits": "linux-base",
"cacheVariables": { "cacheVariables": {
"IS_CI_BUILD": "ON" "CMAKE_SYSTEM_NAME": "Windows",
"CMAKE_SYSTEM_PROCESSOR": "aarch64",
"CMAKE_C_COMPILER": "clang",
"CMAKE_CXX_COMPILER": "clang++",
"CMAKE_CXX_FLAGS": "--target=arm64-pc-windows-msvc -fuse-ld=lld-link",
"VCPKG_TARGET_TRIPLET": "arm64-windows"
} }
}, },
{ {
"name": "wasm-default", "name": "wasm",
"displayName": "WebAssembly (Emscripten)", "displayName": "WebAssembly (SIMD)",
"description": "Build using Emscripten toolchain", "inherits": "base-common",
"generator": "Ninja",
"binaryDir": "${sourceDir}/out/build/wasm-release",
"toolchainFile": "$env{EMSDK}/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake",
"cacheVariables": { "cacheVariables": {
"CMAKE_CXX_FLAGS": "-msimd128 -pthread" "CMAKE_SYSTEM_NAME": "Emscripten",
} "CMAKE_SYSTEM_PROCESSOR": "wasm32",
} "VCPKG_TARGET_TRIPLET": "wasm32-emscripten-simd",
], "VCPKG_HOST_TRIPLET": "x64-linux",
"buildPresets": [ "VCPKG_CHAINLOAD_TOOLCHAIN_FILE": "$env{EMSDK}/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake"
{
"name": "windows-debug",
"configurePreset": "windows-default",
"configuration": "Debug",
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Windows"
}
},
{
"name": "linux-debug",
"configurePreset": "linux-default",
"configuration": "Debug",
"condition": {
"type": "notEquals",
"lhs": "${hostSystemName}",
"rhs": "Windows"
}
},
{
"name": "linux-wasm-debug",
"configurePreset": "wasm-default",
"configuration": "Debug"
},
{
"name": "linux-ci-release",
"configurePreset": "linux-ci",
"configuration": "Release",
"condition": {
"type": "notEquals",
"lhs": "${hostSystemName}",
"rhs": "Windows"
} }
} }
] ]

View File

@ -146,8 +146,8 @@ namespace IACore
namespace IACore namespace IACore
{ {
CONSTEXPR UINT32 XXH_PRIME32_1 = 0x9E3779B1U; CONSTEXPR UINT32 XXH_PRIME32_1 = 0x9E3779B1U;
CONSTEXPR UINT32 XXH_PRIME32_2 = 0x85EBCA6BU; CONSTEXPR UINT32 XXH_PRIME32_2 = 0x85EBCA77U;
CONSTEXPR UINT32 XXH_PRIME32_3 = 0xC2B2AE35U; CONSTEXPR UINT32 XXH_PRIME32_3 = 0xC2B2AE3DU;
CONSTEXPR UINT32 XXH_PRIME32_4 = 0x27D4EB2FU; CONSTEXPR UINT32 XXH_PRIME32_4 = 0x27D4EB2FU;
CONSTEXPR UINT32 XXH_PRIME32_5 = 0x165667B1U; CONSTEXPR UINT32 XXH_PRIME32_5 = 0x165667B1U;
@ -159,12 +159,12 @@ namespace IACore
return seed; return seed;
} }
UINT32 DataOps::Hash_xxHash(IN CONST String &string) UINT32 DataOps::Hash_xxHash(IN CONST String &string, IN UINT32 seed)
{ {
return Hash_xxHash(Span<CONST UINT8>(reinterpret_cast<PCUINT8>(string.data()), string.size())); return Hash_xxHash(Span<CONST UINT8>(reinterpret_cast<PCUINT8>(string.data()), string.length()), seed);
} }
UINT32 DataOps::Hash_xxHash(IN Span<CONST UINT8> data) UINT32 DataOps::Hash_xxHash(IN Span<CONST UINT8> data, IN UINT32 seed)
{ {
CONST UINT8 *p = data.data(); CONST UINT8 *p = data.data();
CONST UINT8 *CONST bEnd = p + data.size(); CONST UINT8 *CONST bEnd = p + data.size();
@ -174,10 +174,10 @@ namespace IACore
{ {
const UINT8 *const limit = bEnd - 16; const UINT8 *const limit = bEnd - 16;
UINT32 v1 = XXH_PRIME32_1 + XXH_PRIME32_2; UINT32 v1 = seed + XXH_PRIME32_1 + XXH_PRIME32_2;
UINT32 v2 = XXH_PRIME32_2; UINT32 v2 = seed + XXH_PRIME32_2;
UINT32 v3 = 0; UINT32 v3 = seed + 0;
UINT32 v4 = -XXH_PRIME32_1; UINT32 v4 = seed - XXH_PRIME32_1;
do do
{ {
@ -194,13 +194,14 @@ namespace IACore
h32 = std::rotl(v1, 1) + std::rotl(v2, 7) + std::rotl(v3, 12) + std::rotl(v4, 18); h32 = std::rotl(v1, 1) + std::rotl(v2, 7) + std::rotl(v3, 12) + std::rotl(v4, 18);
} }
else else
h32 = XXH_PRIME32_5; h32 = seed + XXH_PRIME32_5;
h32 += (UINT32) data.size(); h32 += (UINT32) data.size();
while (p + 4 <= bEnd) while (p + 4 <= bEnd)
{ {
h32 += ReadUnaligned<UINT32>(p) * XXH_PRIME32_3; const auto t = ReadUnaligned<UINT32>(p) * XXH_PRIME32_3;
h32 += t;
h32 = std::rotl(h32, 17) * XXH_PRIME32_4; h32 = std::rotl(h32, 17) * XXH_PRIME32_4;
p += 4; p += 4;
} }

View File

@ -228,6 +228,7 @@ namespace IACore
case EHeaderType::WARNING: case EHeaderType::WARNING:
return "Warning"; return "Warning";
} }
return "<Unknown>";
} }
BOOL HttpClient::IsSuccessResponseCode(IN EResponseCode code) BOOL HttpClient::IsSuccessResponseCode(IN EResponseCode code)

View File

@ -191,7 +191,7 @@ namespace IACore
{ {
for (auto &session : m_activeSessions) for (auto &session : m_activeSessions)
{ {
ProcessOps::TerminateProcess(session->ProcessHandle); ProcessOps::TerminateProcess(session->NodeProcess);
FileOps::UnmapFile(session->MappedPtr); FileOps::UnmapFile(session->MappedPtr);
FileOps::UnlinkSharedMemory(session->SharedMemName); FileOps::UnlinkSharedMemory(session->SharedMemName);
SocketOps::Close(session->DataSocket); SocketOps::Close(session->DataSocket);
@ -200,7 +200,7 @@ namespace IACore
for (auto &session : m_pendingSessions) for (auto &session : m_pendingSessions)
{ {
ProcessOps::TerminateProcess(session->ProcessHandle); ProcessOps::TerminateProcess(session->NodeProcess);
FileOps::UnmapFile(session->MappedPtr); FileOps::UnmapFile(session->MappedPtr);
FileOps::UnlinkSharedMemory(session->SharedMemName); FileOps::UnlinkSharedMemory(session->SharedMemName);
SocketOps::Close(session->ListenerSocket); SocketOps::Close(session->ListenerSocket);
@ -221,7 +221,7 @@ namespace IACore
if (now - session->CreationTime > std::chrono::seconds(5)) if (now - session->CreationTime > std::chrono::seconds(5))
{ {
ProcessOps::TerminateProcess(session->ProcessHandle); ProcessOps::TerminateProcess(session->NodeProcess);
FileOps::UnmapFile(session->MappedPtr); FileOps::UnmapFile(session->MappedPtr);
FileOps::UnlinkSharedMemory(session->SharedMemName); FileOps::UnlinkSharedMemory(session->SharedMemName);
@ -249,7 +249,7 @@ namespace IACore
SocketOps::Close(session->ListenerSocket); SocketOps::Close(session->ListenerSocket);
session->ListenerSocket = INVALID_SOCKET; session->ListenerSocket = INVALID_SOCKET;
const auto sessionID = session->ProcessHandle->ID.load(); const auto sessionID = session->NodeProcess->ID.load();
const auto sessionPtr = session.get(); const auto sessionPtr = session.get();
m_activeSessions.push_back(std::move(session)); m_activeSessions.push_back(std::move(session));
m_pendingSessions.erase(m_pendingSessions.begin() + i); m_pendingSessions.erase(m_pendingSessions.begin() + i);
@ -261,7 +261,7 @@ namespace IACore
{ {
auto &node = m_activeSessions[i]; auto &node = m_activeSessions[i];
auto nodeID = node->ProcessHandle->ID.load(); auto nodeID = node->NodeProcess->ID.load();
RingBufferView::PacketHeader header; RingBufferView::PacketHeader header;
@ -275,7 +275,7 @@ namespace IACore
OnSignal(nodeID, signal); OnSignal(nodeID, signal);
else if (res == 0 || (res < 0 && !SocketOps::IsWouldBlock())) else if (res == 0 || (res < 0 && !SocketOps::IsWouldBlock()))
{ {
ProcessOps::TerminateProcess(node->ProcessHandle); ProcessOps::TerminateProcess(node->NodeProcess);
FileOps::UnmapFile(node->MappedPtr); FileOps::UnmapFile(node->MappedPtr);
FileOps::UnlinkSharedMemory(node->SharedMemName); FileOps::UnlinkSharedMemory(node->SharedMemName);
@ -355,7 +355,7 @@ namespace IACore
String args = std::format("\"{}\"", desc.Serialize()); String args = std::format("\"{}\"", desc.Serialize());
session->ProcessHandle = ProcessOps::SpawnProcessAsync( session->NodeProcess = ProcessOps::SpawnProcessAsync(
FileOps::NormalizeExecutablePath(executablePath).string(), args, FileOps::NormalizeExecutablePath(executablePath).string(), args,
[sid](IN StringView line) { [sid](IN StringView line) {
UNUSED(sid); UNUSED(sid);
@ -379,10 +379,10 @@ namespace IACore
// Give some time for child node to stablize // Give some time for child node to stablize
std::this_thread::sleep_for(std::chrono::seconds(1)); std::this_thread::sleep_for(std::chrono::seconds(1));
if (!session->ProcessHandle->IsActive()) if (!session->NodeProcess->IsActive())
return MakeUnexpected(std::format("Failed to spawn the child process \"{}\"", executablePath.string())); return MakeUnexpected(std::format("Failed to spawn the child process \"{}\"", executablePath.string()));
auto processID = session->ProcessHandle->ID.load(); auto processID = session->NodeProcess->ID.load();
session->CreationTime = SteadyClock::now(); session->CreationTime = SteadyClock::now();
m_pendingSessions.push_back(std::move(session)); m_pendingSessions.push_back(std::move(session));
@ -398,7 +398,7 @@ namespace IACore
isPending = false; isPending = false;
for (auto it = m_pendingSessions.begin(); it != m_pendingSessions.end(); it++) for (auto it = m_pendingSessions.begin(); it != m_pendingSessions.end(); it++)
{ {
if (it->get()->ProcessHandle->ID.load() == nodeID) if (it->get()->NodeProcess->ID.load() == nodeID)
{ {
isPending = true; isPending = true;
break; break;
@ -417,7 +417,7 @@ namespace IACore
auto &node = itNode->second; auto &node = itNode->second;
ProcessOps::TerminateProcess(node->ProcessHandle); ProcessOps::TerminateProcess(node->NodeProcess);
FileOps::UnmapFile(node->MappedPtr); FileOps::UnmapFile(node->MappedPtr);
FileOps::UnlinkSharedMemory(node->SharedMemName); FileOps::UnlinkSharedMemory(node->SharedMemName);
SocketOps::Close(node->DataSocket); SocketOps::Close(node->DataSocket);

View File

@ -33,8 +33,8 @@ namespace IACore
STATIC UINT32 Hash_FNV1A(IN CONST String &string); STATIC UINT32 Hash_FNV1A(IN CONST String &string);
STATIC UINT32 Hash_FNV1A(IN Span<CONST UINT8> data); STATIC UINT32 Hash_FNV1A(IN Span<CONST UINT8> data);
STATIC UINT32 Hash_xxHash(IN CONST String &string); STATIC UINT32 Hash_xxHash(IN CONST String &string, IN UINT32 seed = 0);
STATIC UINT32 Hash_xxHash(IN Span<CONST UINT8> data); STATIC UINT32 Hash_xxHash(IN Span<CONST UINT8> data, IN UINT32 seed = 0);
STATIC UINT32 CRC32(IN Span<CONST UINT8> data); STATIC UINT32 CRC32(IN Span<CONST UINT8> data);

View File

@ -101,7 +101,7 @@ namespace IACore
struct NodeSession struct NodeSession
{ {
SteadyTimePoint CreationTime{}; SteadyTimePoint CreationTime{};
SharedPtr<ProcessHandle> ProcessHandle; SharedPtr<ProcessHandle> NodeProcess;
Mutex SendMutex; Mutex SendMutex;

View File

@ -16,6 +16,7 @@ set(TEST_SOURCES
Main.cpp Main.cpp
Utils.cpp Utils.cpp
Environment.cpp Environment.cpp
DataOps.cpp
ProcessOps.cpp ProcessOps.cpp
StreamReader.cpp StreamReader.cpp
RingBuffer.cpp RingBuffer.cpp

113
Tests/Unit/DataOps.cpp Normal file
View File

@ -0,0 +1,113 @@
// IACore-OSS; The Core Library for All IA Open Source Projects
// Copyright (C) 2025 IAS (ias@iasoft.dev)
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <IACore/DataOps.hpp>
#include <IACore/IATest.hpp>
using namespace IACore;
// -----------------------------------------------------------------------------
// Test Block Definition
// -----------------------------------------------------------------------------
IAT_BEGIN_BLOCK(Core, DataOps)
BOOL TestCRC32()
{
{
String s = "123456789";
Span<CONST UINT8> span(reinterpret_cast<PCUINT8>(s.data()), s.size());
UINT32 result = DataOps::CRC32(span);
IAT_CHECK_EQ(result, 0xE3069283);
}
{
UINT32 result = DataOps::CRC32({});
IAT_CHECK_EQ(result, 0);
}
{
std::vector<UINT8> buffer(33);
for (size_t i = 1; i < 33; ++i)
buffer[i] = (UINT8) i;
std::vector<UINT8> refData(32);
for (size_t i = 0; i < 32; ++i)
refData[i] = (UINT8) (i + 1);
UINT32 hashRef = DataOps::CRC32(Span<CONST UINT8>(refData.data(), refData.size()));
UINT32 hashUnaligned = DataOps::CRC32(Span<CONST UINT8>(buffer.data() + 1, 32));
IAT_CHECK_EQ(hashRef, hashUnaligned);
}
return TRUE;
}
BOOL TestHash_xxHash()
{
{
String s = "123456789";
UINT32 result = DataOps::Hash_xxHash(s);
IAT_CHECK_EQ(result, 0x937bad67);
}
{
String s = "The quick brown fox jumps over the lazy dog";
UINT32 result = DataOps::Hash_xxHash(s);
IAT_CHECK_EQ(result, 0xE85EA4DE);
}
{
String s = "Test";
UINT32 r1 = DataOps::Hash_xxHash(s);
UINT32 r2 = DataOps::Hash_xxHash(Span<CONST UINT8>((PCUINT8) s.data(), s.size()));
IAT_CHECK_EQ(r1, r2);
}
return TRUE;
}
BOOL TestHash_FNV1A()
{
{
String s = "123456789";
UINT32 result = DataOps::Hash_FNV1A(Span<CONST UINT8>((PCUINT8) s.data(), s.size()));
IAT_CHECK_EQ(result, 0xbb86b11c);
}
{
UINT32 result = DataOps::Hash_FNV1A(Span<CONST UINT8>{});
IAT_CHECK_EQ(result, 0x811C9DC5);
}
return TRUE;
}
// -------------------------------------------------------------------------
// Registration
// -------------------------------------------------------------------------
IAT_BEGIN_TEST_LIST()
IAT_ADD_TEST(TestCRC32);
IAT_ADD_TEST(TestHash_FNV1A);
IAT_ADD_TEST(TestHash_xxHash);
IAT_END_TEST_LIST()
IAT_END_BLOCK()
IAT_REGISTER_ENTRY(Core, DataOps)