Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
115 changes: 93 additions & 22 deletions Backend/CaseConversionAPI/CppLib/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,11 +1,71 @@
# -----------------------------------------------------------------------------
# CMake Configuration - Hardware-Aware Case Conversion Engine
# Project : StringConversion
# Component : Cross-Platform Native Core + GoogleTest Harness
# Architecture : Static Core + Shared DLL Bridge + CLI + Test Runtime
# -----------------------------------------------------------------------------
# VERSION HISTORY
# Version | Date | Author | Description
# --------|------------|---------------|----------------------------------------
# 1.0.0 | 2026-04-14 | Nitish Singh | Initial native orchestration baseline.
# 1.1.0 | 2026-05-09 | Nitish Singh | Added Apple Silicon optimization flags
# | and AddressSanitizer integration.
# 1.2.0 | 2026-05-20 | Nitish Singh | Added Windows MinGW static runtime
# | linking for containerized execution.
# 1.3.0 | 2026-05-28 | Nitish Singh | Added clang-format automation target
# | and cross-platform formatting support.
# -----------------------------------------------------------------------------
# BUILD STRATEGY
# * Static Core Library : Shared reusable conversion engine
# * Shared DLL Bridge : .NET interoperability export layer
# * CLI Runtime : Standalone native execution target
# * GoogleTest Harness : Integrated validation framework
# * MinGW Static Linking : Portable Windows runtime generation
# * Clang-Format Integration : Automated source formatting pipeline
# * AddressSanitizer Support : Native debug-time memory diagnostics
# -----------------------------------------------------------------------------

cmake_minimum_required(VERSION 3.14)

set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreadedDLL")

if(POLICY CMP0135)
cmake_policy(SET CMP0135 NEW)
endif()

# Add this near the top, after project()
if(CMAKE_BUILD_TYPE STREQUAL "Debug" OR NOT CMAKE_BUILD_TYPE)
# 1. Initialize the project profile first so system variables exist
project(StringConversion)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
enable_testing()

# 2. Apply explicit static linking constraints globally for cross-compilation
# --------------------------------------------------------
# Runtime / Linking Strategy
# --------------------------------------------------------

if(MSVC)

# Using dynamic MSVC runtime consistently across all targets
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreadedDLL")

# GoogleTest must match the same runtime model
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)

elseif(MINGW)

# MinGW-specific static runtime linking
set(CMAKE_EXE_LINKER_FLAGS
"${CMAKE_EXE_LINKER_FLAGS} -static -static-libgcc -static-libstdc++")

set(CMAKE_SHARED_LINKER_FLAGS
"${CMAKE_SHARED_LINKER_FLAGS} -static -static-libgcc -static-libstdc++")

endif()

# 3. Restrict AddressSanitizer strictly to native explicit Debug builds
if(CMAKE_BUILD_TYPE MATCHES Debug)
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
message(STATUS "Enabling AddressSanitizer for Debug build")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fno-omit-frame-pointer -g")
Expand All @@ -14,17 +74,10 @@ if(CMAKE_BUILD_TYPE STREQUAL "Debug" OR NOT CMAKE_BUILD_TYPE)
endif()
endif()

project(StringConversion)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
enable_testing()

# ---------------------------
# Global Settings
# ---------------------------
include_directories(include)
# Required for linking static code into a shared library on some platforms
set(CMAKE_POSITION_INDEPENDENT_CODE ON)

# ---------------------------
Expand Down Expand Up @@ -54,20 +107,10 @@ target_include_directories(StringConversionLib PUBLIC include)
# ---------------------------
# 2. The Bridge DLL: ProcessStringDLL (SHARED)
# ---------------------------
# This creates the actual file (libProcessStringDLL.dylib / .so) for .NET
add_library(ProcessStringDLL SHARED src/ProcessStringDLL.cpp)

# This tells the compiler "We are BUILDING the DLL, not using it"
target_compile_definitions(ProcessStringDLL PRIVATE PROCESSSTRING_EXPORTS)

# This silences the 'strcpy' warning (C4996) seen in your logs
if(WIN32)
target_compile_definitions(ProcessStringDLL PRIVATE _CRT_SECURE_NO_WARNINGS)
endif()

target_link_libraries(ProcessStringDLL PRIVATE StringConversionLib)

# Ensure the "lib" prefix is consistent for your scripts
set_target_properties(ProcessStringDLL PROPERTIES PREFIX "lib")

# ---------------------------
Expand All @@ -80,8 +123,6 @@ target_link_libraries(app StringConversionLib)
# 4. GoogleTest Setup
# ---------------------------
include(FetchContent)
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)

FetchContent_Declare(
googletest
URL https://github.com/google/googletest/archive/main.zip
Expand All @@ -97,4 +138,34 @@ add_executable(runTests
)
target_link_libraries(runTests StringConversionLib gtest gtest_main)

add_test(NAME AllTests COMMAND runTests)
# Force the test runner to link dependencies statically under MinGW
if(MINGW)
target_link_options(runTests PRIVATE
"-static"
"-static-libgcc"
"-static-libstdc++"
)
endif()

add_test(NAME AllTests COMMAND runTests)

# ---------------------------
# 6. Code Formatting (Clang-Format Automation)
# ---------------------------
find_program(CLANG_FORMAT_EXE
NAMES clang-format
HINTS /opt/homebrew/bin /usr/local/bin
)

if(CLANG_FORMAT_EXE)
message(STATUS "Found clang-format: ${CLANG_FORMAT_EXE}")
file(GLOB_RECURSE ALL_FORMAT_FILES
"${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/include/*.hpp"
"${PROJECT_SOURCE_DIR}/../Tests/CppTests/*.cpp"
)
add_custom_target(format
COMMAND ${CLANG_FORMAT_EXE} -i -style=LLVM ${ALL_FORMAT_FILES}
COMMENT "Auto-formatting all C++ engine source..."
)
endif()
44 changes: 44 additions & 0 deletions Backend/CaseConversionAPI/CppLib/CMakeListsLocalApp.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,24 @@
# -----------------------------------------------------------------------------
# CMake Configuration - StringConversion Native Engine
# Project : StringConversion
# Component : Core Library + CLI + GoogleTest Validation
# -----------------------------------------------------------------------------
# VERSION HISTORY
# Version | Date | Author | Description
# --------|------------|---------------|----------------------------------------
# 1.0.0 | 2026-04-14 | Nitish Singh | Initial native CMake orchestration
# | with GoogleTest integration.
# 1.1.0 | 2026-05-28 | Nitish Singh | Added automated clang-format target
# | for recursive source/test formatting.
# -----------------------------------------------------------------------------
# BUILD ARCHITECTURE
# * Static Core Library : Shared string conversion engine
# * CLI Runtime : Native executable entry point
# * GoogleTest Integration : Unit + advanced validation suite
# * Clang-Format Automation : Consistent code-style enforcement
# * Recursive Source Discovery : Automated formatting coverage
# -----------------------------------------------------------------------------

cmake_minimum_required(VERSION 3.14)

cmake_policy(SET CMP0135 NEW)
Expand Down Expand Up @@ -77,4 +98,27 @@ target_link_libraries(runTests StringConversionLib gtest gtest_main)
# ---------------------------
add_test(NAME AllTests COMMAND runTests)

# ===================================================================
# 6. Code Formatting (Clang-Format Automation)
# ===================================================================
find_program(CLANG_FORMAT_EXE
NAMES clang-format
HINTS /opt/homebrew/bin /usr/local/bin
)

if(CLANG_FORMAT_EXE)
message(STATUS "Found clang-format: ${CLANG_FORMAT_EXE}")

file(GLOB_RECURSE ALL_FORMAT_FILES
"${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/include/*.hpp"
"${PROJECT_SOURCE_DIR}/../Tests/CppTests/*.cpp"
)

add_custom_target(format
COMMAND ${CLANG_FORMAT_EXE} -i -style=LLVM ${ALL_FORMAT_FILES}
COMMENT "Auto-formatting C++ engine, application, and test suites..."
)
else()
message(WARNING "clang-format executable not found. 'format' target will not be available.")
endif()
46 changes: 39 additions & 7 deletions Backend/CaseConversionAPI/CppLib/Scripts/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,34 @@
# --------|------------|--------------|----------------------------------------
# 1.0.0 | 2026-05-14 | Nitish Singh | Initial Orchestration Layer.
# 1.1.0 | 2026-05-14 | Nitish Singh | Integrated MinGW-w64 for Windows cross-builds.
# 1.2.0 | 2026-05-30 | Nitish Singh | Added Wine + Xvfb validation pipeline for
# | Windows GoogleTest execution inside Linux
# | containers with cross-platform verification.
# -----------------------------------------------------------------------------
# ARCHITECTURAL STRATEGY:
# * Headless Build Vessel: Designed to output binaries, not to run as a service.
# * Cross-Compilation: Leverages MinGW-w64 to target Windows from a Linux host.
# * Artifact Extraction: Exposes the build directory for host-side consumption.
# -----------------------------------------------------------------------------

# --- STAGE 1: Build Environment (Native Toolchains Only) ---
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build-env
ARG TARGET_PLATFORM=linux/amd64
FROM --platform=${TARGET_PLATFORM} mcr.microsoft.com/dotnet/sdk:8.0 AS build-env

# Install C++ Native Toolchains (GCC for Linux, MinGW for Windows)
RUN apt-get update && apt-get install -y \
# Install C++ Native Toolchains, Wine, and Xvfb for testing
RUN dpkg --add-architecture i386 && \
apt-get update && apt-get install -y \
build-essential \
cmake \
mingw-w64 \
wine \
wine32 \
wine64 \
xvfb \
&& rm -rf /var/lib/apt/lists/*

WORKDIR /src

# Copy the entire repo context to preserve script and source paths
# Copy the entire repo context
COPY . .

# Ensure orchestrator script is executable
Expand All @@ -40,14 +48,38 @@ RUN ./Backend/CaseConversionAPI/CppLib/Scripts/orchestrate-native.sh ubuntu-late
# --- STEP 2: Build Windows Artifacts (.dll via MinGW) ---
RUN ./Backend/CaseConversionAPI/CppLib/Scripts/orchestrate-native.sh windows-latest

# --- STEP 3: Verification Layer (Internal Tests) ---
WORKDIR /src/Backend/CaseConversionAPI/CppLib/build/windows-latest

ENV WINEPREFIX=/root/.wine
ENV WINEARCH=win64
ENV WINEDEBUG=-all
ENV WINEDLLOVERRIDES="mscoree,mshtml="

# Run Windows test suite via Wine
# Using absolute path to /usr/bin/xvfb-run ensures command execution
RUN echo "===== Running Windows GoogleTests via Wine =====" && \
/usr/bin/xvfb-run --server-args="-screen 0 1024x768x24" \
/usr/lib/wine/wine64 ./runTests.exe --gtest_color=yes 2>&1 | tee gtest_internal.log && \
echo "===== Windows GoogleTests Passed =====" \
|| { \
echo "=== WINDOWS GOOGLETEST CRASH LOG ==="; \
cat gtest_internal.log; \
exit 1; \
}

# Reset context for artifact extraction
WORKDIR /src

# -----------------------------------------------------------------------------
# STAGE 2: Export Layer (Minimal Delivery Vessel)
# -----------------------------------------------------------------------------
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS runtime
# Re-import target architecture variable for the final runtime stage context
ARG TARGET_PLATFORM=linux/amd64
FROM --platform=${TARGET_PLATFORM} mcr.microsoft.com/dotnet/aspnet:8.0 AS runtime
WORKDIR /app

# Export the raw C++ build artifacts for the host to extract via 'docker cp'
# This bypasses managed code publish to focus on native binary delivery.
COPY --from=build-env /src/Backend/CaseConversionAPI/CppLib/build /src/Backend/CaseConversionAPI/CppLib/build

# Note: No ENTRYPOINT defined as this container is utilized as an artifact source.
Loading
Loading