diff --git a/.github/actions/build-lib/action.yml b/.github/actions/build-lib/action.yml index a4a9b913..7924734e 100644 --- a/.github/actions/build-lib/action.yml +++ b/.github/actions/build-lib/action.yml @@ -1,5 +1,14 @@ name: Build OS description: Build for the current OS +inputs: + build-type: + description: 'Build type: normal, asan, or all' + required: false + default: 'normal' + enable-asan: + description: 'Enable Address Sanitizer build (deprecated: use build-type instead)' + required: false + default: 'false' runs: using: composite steps: @@ -9,14 +18,27 @@ runs: registry-url: "https://npm.pkg.github.com" scope: "@mvrdevelopment" + # Normal builds (when build-type is 'normal' or 'all') - name: Build Linux - if: runner.os == 'Linux' + if: runner.os == 'Linux' && (inputs.build-type == 'normal' || inputs.build-type == 'all') uses: ./libMvrGdtf/.github/actions/build-ubuntu - name: Build Windows - if: runner.os == 'Windows' + if: runner.os == 'Windows' && (inputs.build-type == 'normal' || inputs.build-type == 'all') uses: ./libMvrGdtf/.github/actions/build-windows - name: Build macOS - if: runner.os == 'macOS' + if: runner.os == 'macOS' && (inputs.build-type == 'normal' || inputs.build-type == 'all') uses: ./libMvrGdtf/.github/actions/build-macos + + - name: Build Windows with ASAN + if: runner.os == 'Windows' && (inputs.build-type == 'asan' || inputs.build-type == 'all' || inputs.enable-asan == 'true') + uses: ./libMvrGdtf/.github/actions/build-windows-asan + + - name: Build macOS ARM64 with ASAN + if: runner.os == 'macOS' && (inputs.build-type == 'asan' || inputs.build-type == 'all' || inputs.enable-asan == 'true') + uses: ./libMvrGdtf/.github/actions/build-macos-arm-asan + + - name: Build Linux with ASAN + if: runner.os == 'Linux' && (inputs.build-type == 'asan' || inputs.build-type == 'all' || inputs.enable-asan == 'true') + uses: ./libMvrGdtf/.github/actions/build-ubuntu \ No newline at end of file diff --git a/.github/actions/build-macos-arm-asan/action.yml b/.github/actions/build-macos-arm-asan/action.yml new file mode 100644 index 00000000..c1481504 --- /dev/null +++ b/.github/actions/build-macos-arm-asan/action.yml @@ -0,0 +1,101 @@ +name: 'Build macOS ARM64 with ASAN' +description: 'Build the package for macOS ARM64 with Address Sanitizer using Clang' +runs: + using: "composite" + steps: + # Cache Xerces-C to avoid rebuilding (saves ~5-8 minutes on cache hit) + - name: Cache Xerces-C ARM64 ASAN build + uses: actions/cache@v4 + id: cache-xerces + with: + path: xerces-c/_build_mac_arm_asan + key: xerces-c-3.3.0-macos-arm64-asan-${{ runner.os }}-v1 + restore-keys: | + xerces-c-3.3.0-macos-arm64-asan-${{ runner.os }}- + + - name: Xerces-C - prepare + if: steps.cache-xerces.outputs.cache-hit != 'true' + shell: bash + run: | + mkdir -p xerces-c + cd xerces-c + curl -sL -o xerces-c.zip https://dlcdn.apache.org/xerces/c/3/sources/xerces-c-3.3.0.zip + tar -xf xerces-c.zip --strip-components=1 + + - name: Xerces-C - build arm64 with ASAN + if: steps.cache-xerces.outputs.cache-hit != 'true' + shell: bash + working-directory: xerces-c + run: | + ./configure --disable-shared --prefix=$(pwd)/_build_mac_arm_asan CFLAGS="-arch arm64 -fsanitize=address -g -O2" CXXFLAGS="-arch arm64 -fsanitize=address -g -O2" LDFLAGS="-fsanitize=address" --enable-xmlch-uint16_t + make -j$(sysctl -n hw.ncpu) + make install + + # Note: BUILD_MVR_XCHANGE is disabled - Boost not needed for ASAN builds + + # Boost - prepare (needed for MVR_XCHANGE) + - name: Boost - prepare + shell: bash + run: | + mkdir boost + cd boost + curl -o boost.zip https://archives.boost.io/release/1.86.0/source/boost_1_86_0.zip + tar -xf boost.zip --strip-components=1 + + - name: libMVRGdtf - build ARM64 with ASAN [NO-MZ] + shell: bash + working-directory: libMvrGdtf + run: | + mkdir build_mac_arm_asan_no_mz + cd build_mac_arm_asan_no_mz + cmake .. \ + -DCMAKE_C_FLAGS="-arch arm64 -fsanitize=address -g -O2" \ + -DCMAKE_CXX_FLAGS="-arch arm64 -fsanitize=address -g -O2" \ + -DCMAKE_EXE_LINKER_FLAGS="-fsanitize=address" \ + -DCMAKE_SHARED_LINKER_FLAGS="-fsanitize=address" \ + -DENABLE_ASAN=TRUE \ + -DDO_NOT_INCLUDE_MINI_ZIP=true \ + -DCMAKE_INSTALL_PREFIX:PATH=libs \ + -DXERCES_INCLUDE_PATH="../xerces-c/_build_mac_arm_asan/include;../xerces/src" \ + -DXERCES_LIB_PATH="../xerces/_build_mac_arm_asan/lib" \ + -DXERCES_ROOT_PATH="../xerces-c/_build_mac_arm_asan" \ + -DLIB_OUTPUT_NAME="MvrGdtf_ASAN" + make -j$(sysctl -n hw.ncpu) + make install + echo "Built library with ASAN for ARM64" + lipo -archs ../libs/libMvrGdtf_ASAN_NO_MZ.a + libtool -static -o ../libs/libMvrGdtf_ASAN_NO_MZ-all.a ../libs/libMvrGdtf_ASAN_NO_MZ.a ./libs/lib/libmdns_cpp.a ../../xerces-c/_build_mac_arm_asan/lib/libxerces-c.a + mv -f ../libs/libMvrGdtf_ASAN_NO_MZ-all.a ../libs/libMvrGdtf_ASAN_NO_MZ.a + + - name: libMVRGdtf - build ARM64 with ASAN + shell: bash + working-directory: libMvrGdtf + run: | + mkdir build_mac_arm_asan + cd build_mac_arm_asan + cmake .. \ + -DCMAKE_C_FLAGS="-arch arm64 -fsanitize=address -g -O2" \ + -DCMAKE_CXX_FLAGS="-arch arm64 -fsanitize=address -g -O2" \ + -DCMAKE_EXE_LINKER_FLAGS="-fsanitize=address" \ + -DCMAKE_SHARED_LINKER_FLAGS="-fsanitize=address" \ + -DENABLE_ASAN=TRUE \ + -DCMAKE_INSTALL_PREFIX:PATH=libs \ + -DXERCES_INCLUDE_PATH="../xerces-c/_build_mac_arm_asan/include;../xerces/src" \ + -DXERCES_LIB_PATH="../xerces/_build_mac_arm_asan/lib" \ + -DXERCES_ROOT_PATH="../xerces-c/_build_mac_arm_asan" \ + -DLIB_OUTPUT_NAME="MvrGdtf_ASAN" + make -j$(sysctl -n hw.ncpu) + make install + echo "Built library with ASAN for ARM64" + lipo -archs ../libs/libMvrGdtf_ASAN.a + libtool -static -o ../libs/libMvrGdtf_ASAN-all.a ../libs/libMvrGdtf_ASAN.a ./libs/lib/libmdns_cpp.a ../../xerces-c/_build_mac_arm_asan/lib/libxerces-c.a + mv -f ../libs/libMvrGdtf_ASAN-all.a ../libs/libMvrGdtf_ASAN.a + + - name: Prepare package + shell: bash + working-directory: libMvrGdtf + run: | + mkdir -p output/include + cp -r src/include/* output/include/ + mkdir -p output/lib + cp -r libs/* output/lib/ diff --git a/.github/actions/build-windows-asan/action.yml b/.github/actions/build-windows-asan/action.yml new file mode 100644 index 00000000..a5f16648 --- /dev/null +++ b/.github/actions/build-windows-asan/action.yml @@ -0,0 +1,256 @@ +name: 'Build Windows with ASAN' +description: 'Build the packages for Windows with Address Sanitizer (MSVC)' +runs: + using: "composite" + steps: + # Prepare Visual Studio + - name: Set up Visual Studio + uses: microsoft/setup-msbuild@v2 + with: + msbuild-architecture: x64 + + # -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + # Xerces-C - setup + - name: Xerces-C - prepare + shell: cmd + run: | + mkdir xerces-c + cd xerces-c + curl -o xerces-c.zip https://dlcdn.apache.org//xerces/c/3/sources/xerces-c-3.3.0.zip + tar -xf xerces-c.zip --strip-components=1 + + # Xerces-C - build MD + - name: Xerces-C - configure + working-directory: xerces-c + shell: cmd + run: | + mkdir build + cd build + cmake .. -G "Visual Studio 17 2022" -A x64 -T v142,version=14.29 -DCMAKE_INSTALL_PREFIX:PATH=libs -DCMAKE_CXX_FLAGS="/DWIN32 /D_WINDOWS -O2 -Ob2 -DNDEBUG" -DCMAKE_C_FLAGS="/DWIN32 /D_WINDOWS /W3" -DBUILD_SHARED_LIBS:BOOL=FALSE -Dxmlch-type=wchar_t + + - name: Xerces-C - build MinSizeRel + working-directory: xerces-c/build + shell: cmd + run: | + msbuild /m ALL_BUILD.vcxproj /p:Configuration=MinSizeRel + msbuild /m INSTALL.vcxproj /p:Configuration=MinSizeRel + + - name: Xerces-C - build Debug + working-directory: xerces-c/build + shell: cmd + run: | + msbuild /m ALL_BUILD.vcxproj /p:Configuration=Debug + msbuild /m INSTALL.vcxproj /p:Configuration=Debug + + # Xerces-C - build MT + - name: Xerces-C - configure [MT] + working-directory: xerces-c + shell: cmd + run: | + mkdir build_mt + cd build_mt + cmake .. -G "Visual Studio 17 2022" -A x64 -T v142,version=14.29 -DCMAKE_INSTALL_PREFIX:PATH=libs -DCMAKE_CXX_FLAGS_DEBUG="/MTd /Zi /Ob0 /Od /RTC1" -DCMAKE_CXX_FLAGS_MINSIZEREL="/MT /O1 /Ob1 /DNDEBUG" -DCMAKE_C_FLAGS_DEBUG="/MTd /Zi /Ob0 /Od /RTC1" -DCMAKE_C_FLAGS_MINSIZEREL="/MT /O1 /Ob1 /DNDEBUG" -DCMAKE_C_FLAGS="/DWIN32 /D_WINDOWS /W3" -DBUILD_SHARED_LIBS:BOOL=FALSE -Dxmlch-type=wchar_t + + - name: Xerces-C - build MinSizeRel [MT] + working-directory: xerces-c/build_mt + shell: cmd + run: | + msbuild /m ALL_BUILD.vcxproj /p:Configuration=MinSizeRel + msbuild /m INSTALL.vcxproj /p:Configuration=MinSizeRel + + - name: Xerces-C - build Debug [MT] + working-directory: xerces-c/build_mt + shell: cmd + run: | + msbuild /m ALL_BUILD.vcxproj /p:Configuration=Debug + msbuild /m INSTALL.vcxproj /p:Configuration=Debug + + # -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + # Boost - setup and build + - name: Boost - prepare + shell: cmd + run: | + mkdir boost + cd boost + curl -o boost.zip https://archives.boost.io/release/1.86.0/source/boost_1_86_0.zip + tar -xf boost.zip --strip-components=1 + + # -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + # libMVRGdtf - setup + - name: libMVRGdtf - checkout repository + uses: actions/checkout@v4 + with: + path: libMvrGdtf + + # -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + - name: libMVRGdtf [MD_NO_MZ] - configure + working-directory: libMvrGdtf + shell: cmd + run: | + mkdir build_MD_NO_MZ + cd build_MD_NO_MZ + cmake .. -DCMAKE_INSTALL_PREFIX:PATH=libs -T v142,version=14.29 -DWIN_RUNTIME_LIB=-MD -DENABLE_ASAN=TRUE -DXERCES_INCLUDE_PATH="..\xerces-c\build\libs\include;..\xerces\src" -DXERCES_LIB_PATH="..\xerces\build\libs\lib" -DXERCES_ROOT_PATH="..\xerces-c" -DDO_NOT_INCLUDE_MINI_ZIP=TRUE + ren MvrGdtf.vcxproj MvrGdtf_ORG.vcxproj + + # libMVRGdtf - build Debug + - name: libMVRGdtf [MD_NO_MZ] - Debug - add lib dependencies + working-directory: libMvrGdtf/build_MD_NO_MZ + shell: pwsh + run: | + $xml = [xml](Get-Content MvrGdtf_ORG.vcxproj) + $xml.Project.ItemDefinitionGroup | ForEach-Object { + $node = $xml.CreateElement("AdditionalDependencies", "http://schemas.microsoft.com/developer/msbuild/2003") + $node.InnerText = 'iphlpapi.lib;..\..\xerces-c\build\libs\lib\xerces-c_3D.lib;mdns_cpp\lib\Debug\mdns_cpp.lib;%(AdditionalDependencies)' + $_.Lib.AppendChild($node) | Out-Null + } + Set-Content -Path "MvrGdtf.vcxproj" -Value $xml.OuterXml + + - name: libMVRGdtf [MD_NO_MZ] - compile Debug + working-directory: libMvrGdtf/build_MD_NO_MZ + shell: cmd + run: | + msbuild /m ALL_BUILD.vcxproj /p:Configuration=Debug + msbuild /m INSTALL.vcxproj /p:Configuration=Debug + + # libMVRGdtf - build MinSizeRel + - name: libMVRGdtf [MD_NO_MZ] - MinSizeRel - add lib dependencies + working-directory: libMvrGdtf/build_MD_NO_MZ + shell: pwsh + run: | + $xml = [xml](Get-Content MvrGdtf_ORG.vcxproj) + $xml.Project.ItemDefinitionGroup | ForEach-Object { + $node = $xml.CreateElement("AdditionalDependencies", "http://schemas.microsoft.com/developer/msbuild/2003") + $node.InnerText = 'iphlpapi.lib;..\..\xerces-c\build\libs\lib\xerces-c_3.lib;mdns_cpp\lib\MinSizeRel\mdns_cpp.lib;%(AdditionalDependencies)' + $_.Lib.AppendChild($node) | Out-Null + } + Set-Content -Path "MvrGdtf.vcxproj" -Value $xml.OuterXml + + - name: libMVRGdtf [MD_NO_MZ] - compile MinSizeRel + working-directory: libMvrGdtf/build_MD_NO_MZ + shell: cmd + run: | + msbuild /m ALL_BUILD.vcxproj /p:Configuration=MinSizeRel + msbuild /m INSTALL.vcxproj /p:Configuration=MinSizeRel + + # -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + - name: libMVRGdtf [MD] - configure + working-directory: libMvrGdtf + shell: cmd + run: | + mkdir build_MD + cd build_MD + cmake .. -DCMAKE_INSTALL_PREFIX:PATH=libs -T v142,version=14.29 -DWIN_RUNTIME_LIB=-MD -DENABLE_ASAN=TRUE -DXERCES_INCLUDE_PATH="..\xerces-c\build\libs\include;..\xerces\src" -DXERCES_LIB_PATH="..\xerces\build\libs\lib" -DXERCES_ROOT_PATH="..\xerces-c\build" + ren MvrGdtf.vcxproj MvrGdtf_ORG.vcxproj + + # libMVRGdtf - build Debug + - name: libMVRGdtf [MD] - Debug - add lib dependencies + working-directory: libMvrGdtf/build_MD + shell: pwsh + run: | + $xml = [xml](Get-Content MvrGdtf_ORG.vcxproj) + $xml.Project.ItemDefinitionGroup | ForEach-Object { + $node = $xml.CreateElement("AdditionalDependencies", "http://schemas.microsoft.com/developer/msbuild/2003") + $node.InnerText = 'iphlpapi.lib;..\..\xerces-c\build\libs\lib\xerces-c_3D.lib;mdns_cpp\lib\Debug\mdns_cpp.lib;%(AdditionalDependencies)' + $_.Lib.AppendChild($node) | Out-Null + } + Set-Content -Path "MvrGdtf.vcxproj" -Value $xml.OuterXml + + - name: libMVRGdtf [MD] - compile Debug + working-directory: libMvrGdtf/build_MD + shell: cmd + run: | + msbuild /m ALL_BUILD.vcxproj /p:Configuration=Debug + msbuild /m INSTALL.vcxproj /p:Configuration=Debug + + # libMVRGdtf - build MinSizeRel + - name: libMVRGdtf [MD] - MinSizeRel - add lib dependencies + working-directory: libMvrGdtf/build_MD + shell: pwsh + run: | + $xml = [xml](Get-Content MvrGdtf_ORG.vcxproj) + $xml.Project.ItemDefinitionGroup | ForEach-Object { + $node = $xml.CreateElement("AdditionalDependencies", "http://schemas.microsoft.com/developer/msbuild/2003") + $node.InnerText = 'iphlpapi.lib;..\..\xerces-c\build\libs\lib\xerces-c_3.lib;mdns_cpp\lib\MinSizeRel\mdns_cpp.lib;%(AdditionalDependencies)' + $_.Lib.AppendChild($node) | Out-Null + } + Set-Content -Path "MvrGdtf.vcxproj" -Value $xml.OuterXml + + - name: libMVRGdtf [MD] - compile MinSizeRel + working-directory: libMvrGdtf/build_MD + shell: cmd + run: | + msbuild /m ALL_BUILD.vcxproj /p:Configuration=MinSizeRel + msbuild /m INSTALL.vcxproj /p:Configuration=MinSizeRel + + # -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + - name: libMVRGdtf [MT] - configure + working-directory: libMvrGdtf + shell: cmd + run: | + mkdir build_MT + cd build_MT + cmake .. -DCMAKE_INSTALL_PREFIX:PATH=libs -T v142,version=14.29 -DWIN_RUNTIME_LIB=-MT -DENABLE_ASAN=TRUE -DXERCES_INCLUDE_PATH="..\xerces-c\build_mt\libs\include;..\xerces\src" -DXERCES_LIB_PATH="..\xerces\build_mt\libs\lib" -DXERCES_ROOT_PATH="..\xerces-c\build_mt" + ren MvrGdtf.vcxproj MvrGdtf_ORG.vcxproj + + # libMVRGdtf - build Debug + - name: libMVRGdtf [MT] - Debug - add lib dependencies + working-directory: libMvrGdtf/build_MT + shell: pwsh + run: | + $xml = [xml](Get-Content MvrGdtf_ORG.vcxproj) + $xml.Project.ItemDefinitionGroup | ForEach-Object { + $node = $xml.CreateElement("AdditionalDependencies", "http://schemas.microsoft.com/developer/msbuild/2003") + $node.InnerText = 'iphlpapi.lib;..\..\xerces-c\build_mt\libs\lib\xerces-c_3D.lib;mdns_cpp\lib\Debug\mdns_cpp.lib;%(AdditionalDependencies)' + $_.Lib.AppendChild($node) | Out-Null + } + Set-Content -Path "MvrGdtf.vcxproj" -Value $xml.OuterXml + + - name: libMVRGdtf [MT] - compile Debug + working-directory: libMvrGdtf/build_MT + shell: cmd + run: | + msbuild /m ALL_BUILD.vcxproj /p:Configuration=Debug + msbuild /m INSTALL.vcxproj /p:Configuration=Debug + + # libMVRGdtf - build MinSizeRel + - name: libMVRGdtf [MT] - MinSizeRel - add lib dependencies + working-directory: libMvrGdtf/build_MT + shell: pwsh + run: | + $xml = [xml](Get-Content MvrGdtf_ORG.vcxproj) + $xml.Project.ItemDefinitionGroup | ForEach-Object { + $node = $xml.CreateElement("AdditionalDependencies", "http://schemas.microsoft.com/developer/msbuild/2003") + $node.InnerText = 'iphlpapi.lib;..\..\xerces-c\build_mt\libs\lib\xerces-c_3.lib;mdns_cpp\lib\MinSizeRel\mdns_cpp.lib;%(AdditionalDependencies)' + $_.Lib.AppendChild($node) | Out-Null + } + Set-Content -Path "MvrGdtf.vcxproj" -Value $xml.OuterXml + + - name: libMVRGdtf [MT] - compile MinSizeRel + working-directory: libMvrGdtf/build_MT + shell: cmd + run: | + msbuild /m ALL_BUILD.vcxproj /p:Configuration=MinSizeRel + msbuild /m INSTALL.vcxproj /p:Configuration=MinSizeRel + + # -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + - name: libMVRGdtf - Generate output library + working-directory: libMvrGdtf + shell: pwsh + run: | + if (Test-Path -Path "output") { + Remove-Item -Path "output" -Recurse -Force + } + New-Item -Path "output\libMvrGdtf\lib" -ItemType Directory -Force + Copy-Item -Path "libs\MinSizeRel\*" -Destination "output\libMvrGdtf\lib" -Recurse + Copy-Item -Path "libs\Debug\*" -Destination "output\libMvrGdtf\lib" -Recurse + + New-Item -Path "output\libMvrGdtf\include" -ItemType Directory -Force + Copy-Item -Path "src\Include\*" -Destination "output\libMvrGdtf\include" -Recurse + + if (Test-Path -Path "libs\MinSizeRel") { + Remove-Item -Path "libs\MinSizeRel" -Recurse -Force + } + + if (Test-Path -Path "libs\Debug") { + Remove-Item -Path "libs\Debug" -Recurse -Force + } diff --git a/.github/workflows/artifact.yml b/.github/workflows/artifact.yml index 8a9083e8..af6d34f6 100644 --- a/.github/workflows/artifact.yml +++ b/.github/workflows/artifact.yml @@ -11,6 +11,15 @@ on: - ubuntu-22.04 - windows-latest - macos-latest + build-type: + description: 'Build type' + required: false + default: 'normal' + type: choice + options: + - normal + - asan + - all jobs: build_artifact: @@ -24,6 +33,8 @@ jobs: - name: Build uses: ./libMvrGdtf/.github/actions/build-lib + with: + build-type: ${{ inputs.build-type }} - name: Upload artifact uses: actions/upload-artifact@v4 diff --git a/CMakeLists.txt b/CMakeLists.txt index 957e7a08..4c48b7b4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -251,9 +251,27 @@ add_compile_options($ENV{CXX_FLAGS_CUSTOM}) if (ENABLE_ASAN) if (MSVC) - message(STATUS "ASAN aktiviert für RelWithDebInfo") - target_compile_options(MvrGdtf PRIVATE /fsanitize=address) - target_compile_options(MvrGdtf PRIVATE /MTd) + message(STATUS "ASAN enabled for MSVC") + # MSVC ASAN: /fsanitize=address is incompatible with /RTC1 + # Explicitly disable /RTC1 and use static runtime /MTd + target_compile_options(MvrGdtf PRIVATE /fsanitize=address /Zi /MTd) + # Disable runtime checks which are incompatible with ASAN + target_compile_options(MvrGdtf PRIVATE /RTC1-) + + if(${UNITTEST}) + target_compile_options(MvrGdtfUnitTest PRIVATE /fsanitize=address /Zi /MTd /RTC1-) + endif() + else() + # GCC and Clang support for Address Sanitizer + message(STATUS "ASAN enabled for GCC/Clang") + target_compile_options(MvrGdtf PRIVATE -fsanitize=address -fno-omit-frame-pointer -g) + target_link_options(MvrGdtf PRIVATE -fsanitize=address) + + # Also enable ASAN for unit tests if they are being built + if(${UNITTEST}) + target_compile_options(MvrGdtfUnitTest PRIVATE -fsanitize=address -fno-omit-frame-pointer -g) + target_link_options(MvrGdtfUnitTest PRIVATE -fsanitize=address) + endif() endif() endif()