Skip to content
Open
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
8 changes: 6 additions & 2 deletions .gitlab/build-appsec.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,18 @@ suffix="${1:-}"
echo "Build nts extension"
switch-php "${PHP_VERSION}"
mkdir -p appsec/build ; cd appsec/build
cmake .. -DCMAKE_BUILD_TYPE=RelWithDebInfo -DDD_APPSEC_BUILD_HELPER=OFF -DDD_APPSEC_TESTING=OFF ; make -j $MAKE_JOBS
cmake .. -DCMAKE_BUILD_TYPE=RelWithDebInfo -DDD_APPSEC_BUILD_HELPER=OFF \
-DDD_APPSEC_TESTING=OFF -DDD_APPSEC_EXTENSION_STATIC_LIBSTDCXX=ON
make -j $MAKE_JOBS
cp -v ddappsec.so "../../appsec_$(uname -m)/ddappsec-$PHP_API${suffix}.so"
cd "../../"

echo "Build zts extension"
switch-php "${PHP_VERSION}-zts"
mkdir -p appsec/build-zts ; cd appsec/build-zts
cmake .. -DCMAKE_BUILD_TYPE=RelWithDebInfo -DDD_APPSEC_BUILD_HELPER=OFF -DDD_APPSEC_TESTING=OFF ; make -j $MAKE_JOBS
cmake .. -DCMAKE_BUILD_TYPE=RelWithDebInfo -DDD_APPSEC_BUILD_HELPER=OFF \
-DDD_APPSEC_TESTING=OFF -DDD_APPSEC_EXTENSION_STATIC_LIBSTDCXX=ON
make -j $MAKE_JOBS
cp -v ddappsec.so "../../appsec_$(uname -m)/ddappsec-$PHP_API${suffix}-zts.so"
cd "../../"

Expand Down
6 changes: 4 additions & 2 deletions .gitlab/generate-appsec.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,12 @@
script:
- switch-php $SWITCH_PHP_VERSION
- cd appsec/build
- if [[ "$SWITCH_PHP_VERSION" == *"asan"* ]]; then ASAN_FLAG=ON; else ASAN_FLAG=OFF; fi
- "cmake .. -DCMAKE_BUILD_TYPE=Debug -DDD_APPSEC_BUILD_HELPER=OFF
-DCMAKE_CXX_FLAGS='-stdlib=libc++' -DCMAKE_CXX_LINK_FLAGS='-stdlib=libc++'
-DDD_APPSEC_TESTING=ON -DBOOST_CACHE_PREFIX=$CI_PROJECT_DIR/boost-cache"
- make -j 4 xtest
-DDD_APPSEC_TESTING=ON -DBOOST_CACHE_PREFIX=$CI_PROJECT_DIR/boost-cache
-DENABLE_ASAN=$ASAN_FLAG"
- ASAN_OPTIONS=malloc_context_size=0 make -j 4 xtest

"appsec integration tests":
stage: test
Expand Down
1 change: 1 addition & 0 deletions appsec/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ option(DD_APPSEC_BUILD_EXTENSION "Whether to builder the extension" ON)
option(DD_APPSEC_ENABLE_COVERAGE "Whether to enable coverage calculation" OFF)
option(DD_APPSEC_TESTING "Whether to enable testing" ON)
option(DD_APPSEC_DDTRACE_ALT "Whether to build appsec with cmake" OFF)
option(DD_APPSEC_EXTENSION_STATIC_LIBSTDCXX "Whether to link the extension with -static-libstdc++ (not available on macOS)" OFF)

add_subdirectory(third_party EXCLUDE_FROM_ALL)

Expand Down
33 changes: 29 additions & 4 deletions appsec/cmake/clang-format.cmake
Original file line number Diff line number Diff line change
@@ -1,7 +1,32 @@
find_program(CLANG_FORMAT clang-format)
if(CLANG_FORMAT STREQUAL CLANG_FORMAT-NOTFOUND)
message(STATUS "Cannot find clang-format, either set CLANG_FORMAT or make it discoverable")
return()
set(_LLVM17_FORMAT /opt/homebrew/opt/llvm@17/bin/clang-format)
if(EXISTS ${_LLVM17_FORMAT})
set(CLANG_FORMAT ${_LLVM17_FORMAT})
message(STATUS "Using Homebrew LLVM 17 clang-format: ${CLANG_FORMAT}")
else()
find_program(_CF_VERSIONED clang-format-17)
if(NOT _CF_VERSIONED STREQUAL _CF_VERSIONED-NOTFOUND)
set(CLANG_FORMAT ${_CF_VERSIONED})
else()
find_program(_CF_UNVERSIONED clang-format)
if(NOT _CF_UNVERSIONED STREQUAL _CF_UNVERSIONED-NOTFOUND)
execute_process(
COMMAND ${_CF_UNVERSIONED} --version
OUTPUT_VARIABLE _CF_VERSION
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET)
if(_CF_VERSION MATCHES " 17\\.")
set(CLANG_FORMAT ${_CF_UNVERSIONED})
endif()
endif()
endif()
if(NOT CLANG_FORMAT)
set(CLANG_FORMAT ${CMAKE_CURRENT_LIST_DIR}/clang-tools/clang-format)
if(NOT EXISTS ${CLANG_FORMAT})
message(STATUS "Cannot find clang-format version 17, either set CLANG_FORMAT or make it discoverable")
return()
endif()
message(STATUS "Using Docker-based clang-format wrapper: ${CLANG_FORMAT}")
endif()
endif()

set(FILE_LIST "")
Expand Down
65 changes: 49 additions & 16 deletions appsec/cmake/clang-tidy.cmake
Original file line number Diff line number Diff line change
@@ -1,7 +1,47 @@
find_program(CLANG_TIDY run-clang-tidy)
if(CLANG_TIDY STREQUAL CLANG_TIDY-NOTFOUND)
message(STATUS "Cannot find clang-tidy, either set CLANG_TIDY or make it discoverable")
return()
# Prefer a locally installed LLVM 17 run-clang-tidy (e.g. via brew install llvm@17)
# over the Docker-based wrapper, since native execution avoids SDK incompatibilities.
set(_LLVM17_BIN /opt/homebrew/opt/llvm@17/bin)
set(_LLVM17_TIDY ${_LLVM17_BIN}/run-clang-tidy)
set(CLANG_TIDY_BINARY_OPT "")
if(EXISTS ${_LLVM17_TIDY})
set(CLANG_TIDY ${_LLVM17_TIDY})
set(CLANG_TIDY_BINARY_OPT -clang-tidy-binary ${_LLVM17_BIN}/clang-tidy)
message(STATUS "Using Homebrew LLVM 17 run-clang-tidy: ${CLANG_TIDY}")
else()
find_program(_RCT_VERSIONED run-clang-tidy-17)
if(NOT _RCT_VERSIONED STREQUAL _RCT_VERSIONED-NOTFOUND)
set(CLANG_TIDY ${_RCT_VERSIONED})
find_program(_CT_VERSIONED clang-tidy-17)
if(NOT _CT_VERSIONED STREQUAL _CT_VERSIONED-NOTFOUND)
set(CLANG_TIDY_BINARY_OPT -clang-tidy-binary ${_CT_VERSIONED})
endif()
else()
find_program(_RCT_UNVERSIONED run-clang-tidy)
if(NOT _RCT_UNVERSIONED STREQUAL _RCT_UNVERSIONED-NOTFOUND)
# Verify version via co-located clang-tidy
get_filename_component(_RCT_DIR ${_RCT_UNVERSIONED} DIRECTORY)
find_program(_CT_COLOCATED clang-tidy HINTS ${_RCT_DIR} NO_DEFAULT_PATH)
if(NOT _CT_COLOCATED STREQUAL _CT_COLOCATED-NOTFOUND)
execute_process(
COMMAND ${_CT_COLOCATED} --version
OUTPUT_VARIABLE _CT_VERSION
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET)
if(_CT_VERSION MATCHES " 17\\.")
set(CLANG_TIDY ${_RCT_UNVERSIONED})
set(CLANG_TIDY_BINARY_OPT -clang-tidy-binary ${_CT_COLOCATED})
endif()
endif()
endif()
endif()
if(NOT CLANG_TIDY)
set(CLANG_TIDY ${CMAKE_CURRENT_LIST_DIR}/clang-tools/run-clang-tidy)
if(NOT EXISTS ${CLANG_TIDY})
message(STATUS "Cannot find clang-tidy version 17, either set CLANG_TIDY or make it discoverable")
return()
endif()
message(STATUS "Using Docker-based run-clang-tidy wrapper: ${CLANG_TIDY}")
endif()
endif()

set(FILE_LIST "")
Expand All @@ -20,27 +60,20 @@ if(DD_APPSEC_BUILD_EXTENSION)
append_target_sources(extension)
endif()

execute_process (
COMMAND bash -c "${CLANG_TIDY} --help | grep -qs 'use-color'"
RESULT_VARIABLE USE_COLOR
)

set(COLOR_OPT "")
if (USE_COLOR EQUAL 0)
set(COLOR_OPT -use-color)
endif()

set(TIDY_DEPS "")
if(DD_APPSEC_BUILD_EXTENSION AND TARGET libxml2_build)
list(APPEND TIDY_DEPS libxml2_build)
endif()
if(TARGET boost_build)
list(APPEND TIDY_DEPS boost_build)
endif()

add_custom_target(tidy
COMMAND ${CLANG_TIDY} ${COLOR_OPT} -p ${CMAKE_BINARY_DIR} ${FILE_LIST}
COMMAND ${CLANG_TIDY} ${CLANG_TIDY_BINARY_OPT} -use-color -p ${CMAKE_BINARY_DIR} ${FILE_LIST}
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
DEPENDS ${TIDY_DEPS})

add_custom_target(tidy_fix
COMMAND ${CLANG_TIDY} ${COLOR_OPT} -fix -p ${CMAKE_BINARY_DIR} ${FILE_LIST}
COMMAND ${CLANG_TIDY} ${CLANG_TIDY_BINARY_OPT} -use-color -fix -p ${CMAKE_BINARY_DIR} ${FILE_LIST}
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
DEPENDS ${TIDY_DEPS})
94 changes: 94 additions & 0 deletions appsec/cmake/clang-tools/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# Minimal Docker image with clang-format and clang-tidy built from LLVM source
# Uses static linking for smallest possible image size
# Based on Alpine Linux 3.21

FROM alpine:3.21 AS builder

RUN apk add --no-cache \
build-base \
cmake \
ninja \
python3 \
git \
linux-headers \
wget \
clang \
clang-dev

# Download and extract LLVM source
ARG LLVM_VERSION=17.0.6
WORKDIR /src
RUN wget -q https://github.com/llvm/llvm-project/releases/download/llvmorg-${LLVM_VERSION}/llvm-project-${LLVM_VERSION}.src.tar.xz && \
tar -xf llvm-project-${LLVM_VERSION}.src.tar.xz && \
mv llvm-project-${LLVM_VERSION}.src llvm-project && \
rm llvm-project-${LLVM_VERSION}.src.tar.xz

# Configure LLVM build with minimal size optimizations
WORKDIR /src/llvm-project/build
RUN cmake -G Ninja ../llvm \
-DCMAKE_BUILD_TYPE=MinSizeRel \
-DCMAKE_INSTALL_PREFIX=/usr/local \
-DCMAKE_C_COMPILER=clang \
-DCMAKE_CXX_COMPILER=clang++ \
-DCMAKE_CXX_STANDARD=17 \
-DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra" \
-DLLVM_TARGETS_TO_BUILD="" \
-DLLVM_INCLUDE_TESTS=OFF \
-DLLVM_INCLUDE_EXAMPLES=OFF \
-DLLVM_INCLUDE_BENCHMARKS=OFF \
-DLLVM_INCLUDE_DOCS=OFF \
-DLLVM_ENABLE_BINDINGS=OFF \
-DLLVM_ENABLE_OCAMLDOC=OFF \
-DLLVM_ENABLE_Z3_SOLVER=OFF \
-DLLVM_ENABLE_LIBXML2=OFF \
-DLLVM_ENABLE_ZLIB=OFF \
-DLLVM_ENABLE_ZSTD=OFF \
-DLLVM_ENABLE_TERMINFO=OFF \
-DLLVM_BUILD_STATIC=ON \
-DLLVM_LINK_LLVM_DYLIB=OFF \
-DLLVM_BUILD_LLVM_DYLIB=OFF \
-DBUILD_SHARED_LIBS=OFF \
-DLLVM_STATIC_LINK_CXX_STDLIB=ON \
-DCMAKE_EXE_LINKER_FLAGS="-static" \
-DCLANG_ENABLE_STATIC_ANALYZER=OFF \
-DCLANG_ENABLE_ARCMT=OFF \
-DCLANG_BUILD_EXAMPLES=OFF

# Build only the required tools
RUN ninja clang-format clang-tidy clang-apply-replacements

# Install binaries
RUN ninja install-clang-format install-clang-tidy install-clang-apply-replacements install-clang-resource-headers

# Copy run-clang-tidy helper script
RUN cp /src/llvm-project/clang-tools-extra/clang-tidy/tool/run-clang-tidy.py /usr/local/bin/run-clang-tidy && \
chmod +x /usr/local/bin/run-clang-tidy

# Strip binaries to reduce size
RUN strip /usr/local/bin/clang-format \
/usr/local/bin/clang-tidy \
/usr/local/bin/clang-apply-replacements

# Final minimal runtime image
FROM alpine:3.21

# Install only Python runtime for run-clang-tidy script
RUN apk add --no-cache python3

# Copy static binaries from builder
COPY --from=builder /usr/local/bin/clang-format /usr/local/bin/
COPY --from=builder /usr/local/bin/clang-tidy /usr/local/bin/
COPY --from=builder /usr/local/bin/clang-apply-replacements /usr/local/bin/
COPY --from=builder /usr/local/bin/run-clang-tidy /usr/local/bin/

# Copy clang resource headers so clang-tidy uses its own headers
COPY --from=builder /usr/local/lib/clang/ /usr/local/lib/clang/

# Verify installations
RUN clang-format --version && \
clang-tidy --version && \
run-clang-tidy --help > /dev/null

WORKDIR /workspace

CMD ["/bin/sh"]
Loading
Loading