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
36 changes: 36 additions & 0 deletions .clang-tidy
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Shared clang-tidy baseline for dd-trace-cpp, httpd-datadog, and nginx-datadog.
# Keep this file in sync across those repositories.
Checks: >
-*,
bugprone-assert-side-effect,
bugprone-bool-pointer-implicit-conversion,
bugprone-copy-constructor-init,
bugprone-dangling-handle,
bugprone-forwarding-reference-overload,
bugprone-inaccurate-erase,
bugprone-infinite-loop,
bugprone-macro-repeated-side-effects,
bugprone-move-forwarding-reference,
bugprone-parent-virtual-call,
bugprone-posix-return,
bugprone-string-constructor,
bugprone-undelegated-constructor,
bugprone-unused-raii,
bugprone-virtual-near-miss,
misc-unused-using-decls,
readability-delete-null-pointer,
readability-redundant-control-flow,
readability-redundant-string-cstr
# Deferred until existing findings are cleaned up:
# bugprone-argument-comment
# bugprone-use-after-move
# misc-redundant-expression
# misc-static-assert
# modernize-redundant-void-arg
# performance-move-const-arg
# performance-noexcept-move-constructor
# readability-redundant-member-init
# readability-simplify-boolean-expr
WarningsAsErrors: '*'

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Make the new hard-error baseline pass

This setting turns existing diagnostics in configured translation units into CI failures. Running the configured checks against src/datadog/tracer.cpp reports readability-redundant-member-init and performance-move-const-arg, while src/datadog/remote_config/product.cpp reports two misc-static-assert diagnostics; therefore the new check cannot pass even after its input list is limited to compilation-database entries. Fix or suppress the baseline findings before making all warnings fatal.

Useful? React with 👍 / 👎.

HeaderFilterRegex: '^src/'

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems this never matches because CMake passes absolute paths, so Clang Tidy sees /…/src/datadog/[xxx].h.
I think we should rather remove this HeaderFilterRegex option and add the header option to run-clang-tidy:

run-clang-tidy-$CLANG_TIDY_VERSION -p "$build_dir" -clang-tidy-binary "$tidy" \
    -header-filter "^$REPO_ROOT/(src|include)/" -quiet "^$REPO_ROOT/src/"

FormatStyle: file
2 changes: 2 additions & 0 deletions .github/workflows/dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ jobs:
run: bin/check-environment-variables
- name: Configure
run: bin/with-toolchain llvm cmake . -B ${BUILD_DIR} --preset ci-clang
- name: clang-tidy
run: bin/check-tidy
- name: Build
run: cmake --build ${BUILD_DIR} -j --target config-inversion -v
- name: Verify supported configurations metadata
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.build/
.clang-tidy-build/
.cache/
.coverage/
.cursor/
Expand Down
7 changes: 7 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
option(DD_TRACE_BUILD_BENCHMARK "Build benchmark binaries" OFF)
option(DD_TRACE_ENABLE_COVERAGE "Build code with code coverage profiling instrumentation" OFF)
option(DD_TRACE_ENABLE_SANITIZE "Build with address sanitizer and undefined behavior sanitizer" OFF)
option(DD_TRACE_ENABLE_CLANG_TIDY "Run clang-tidy on first-party sources during build" OFF)
set(DD_TRACE_CLANG_TIDY "clang-tidy-14" CACHE STRING "clang-tidy executable when DD_TRACE_ENABLE_CLANG_TIDY is ON")
endif()

# Include mandatory files
Expand Down Expand Up @@ -258,6 +260,11 @@ set_target_properties(dd-trace-cpp-objects
POSITION_INDEPENDENT_CODE ${BUILD_SHARED_LIBS}
)

if(DD_TRACE_ENABLE_CLANG_TIDY)
set_property(TARGET dd-trace-cpp-objects PROPERTY CXX_CLANG_TIDY
"${DD_TRACE_CLANG_TIDY};--quiet;--use-color")
endif()

install(
TARGETS dd-trace-cpp-objects dd-trace-cpp-specs
EXPORT dd-trace-cpp-targets
Expand Down
1 change: 1 addition & 0 deletions CMakePresets.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"displayName": "CI Clang",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug",
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON",
"DD_TRACE_ENABLE_SANITIZE": "ON",
"DD_TRACE_BUILD_TOOLS": "ON",
"DD_TRACE_BUILD_TESTING": "ON"
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ run apt-get update && apt-get install --yes software-properties-common && \
add-apt-repository ppa:git-core/ppa --yes && \
apt-get update && apt-get upgrade --yes && \
apt-get install --yes \
wget build-essential clang sed gdb clang-format git ssh shellcheck \
wget build-essential clang sed gdb clang-format clang-tidy git ssh shellcheck \

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit, opt, pedantic: By the way, please sort packages alphabetically.

libc++-dev libc++abi-dev python3 pip coreutils curl gnupg nodejs

# bazelisk, a launcher for bazel. `bazelisk --help` will cause the latest
Expand Down
3 changes: 3 additions & 0 deletions bin/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ This directory contains scripts that are useful during development.
before pushing changes.
- [check-format](check-format) verifies that the source code is formatted as
[format](format) prefers.
- [check-tidy](check-tidy) runs **clang-tidy-14** (pinned, same major as the

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I would prefer a much simpler and terser comment, without bold, without version, without internal technical details: runs Clang Tidy.

CI Clang) through CMake's `CXX_CLANG_TIDY` on `dd-trace-cpp-objects`. Do
not point it at a host `compile_commands.json`.
- [check-version](check-version) accepts a version string as a command line
argument (e.g. "v1.2.3") and checks whether the version within the source code
matches. This is a good check to perform before publishing a source release.
Expand Down
95 changes: 95 additions & 0 deletions bin/check-tidy
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
#!/bin/sh
# Run the pinned clang-tidy through CMake in the CI container.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I find this comment a bit complicated. I suggest:

# Run clang-tidy through CMake in the CI container.
#
# This builds dd-trace-cpp-objects with DD_TRACE_ENABLE_CLANG_TIDY=ON.
# CMakeLists.txt sets CXX_CLANG_TIDY on that target, so tidy runs with
# the real compile line.
#
# Usage: bin/check-tidy

#
# clang-tidy must use the same compiler, flags, and stdlib as the real
# build (ci-clang + libc++). CMake's CXX_CLANG_TIDY on
# dd-trace-cpp-objects does that: it invokes tidy with the exact compile
# line after `--`. Do not run tidy against a host compilation database.
#
# Usage: bin/check-tidy

set -e

SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd)
REPO_ROOT=$(cd "$SCRIPT_DIR/.." && pwd)
cd "$REPO_ROOT"

# Keep this in sync with .github/workflows/dev.yml and cmake/compiler/clang.cmake.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit:

  • I think that stating that the clang version must be the same everywhere is obvious for C++ developers, and so could be dropped.
  • It seems to me that the cmake/compiler/clang.cmake reference is a mistake.
  • I would rather state that the CI image digest must be in sync with .github/workflows/*.yml (this digest is duplicated many times, this is bad, but this was made long ago and is out of scope ;-) ).

CLANG_TIDY_VERSION=14
CI_IMAGE_BASE=datadog/docker-library:dd-trace-cpp-ci-23768e9

in_container() {
[ -f /.dockerenv ] || [ -n "${KUBERNETES_SERVICE_HOST:-}" ] || \
[ "${DD_TRACE_CPP_TIDY_IN_CONTAINER:-}" = "1" ]
}

docker_arch() {
case "$(uname -m)" in
arm64|aarch64) echo arm64 ;;
*) echo amd64 ;;
esac
}

if ! in_container; then
if ! command -v docker >/dev/null 2>&1; then
>&2 echo "docker is required to run clang-tidy-$CLANG_TIDY_VERSION."
exit 1
fi
if ! docker info >/dev/null 2>&1; then
>&2 echo "Docker is not running. Please start Docker."
exit 1
fi
arch=$(docker_arch)
image="${CI_IMAGE_BASE}-${arch}"
exec docker run --rm -t \
--platform "linux/${arch}" \
-e DD_TRACE_CPP_TIDY_IN_CONTAINER=1 \
-e BUILD_DIR=.clang-tidy-build \
-v "$REPO_ROOT:$REPO_ROOT" \
-w "$REPO_ROOT" \
"$image" \
bin/check-tidy
fi

build_dir=${BUILD_DIR:-.clang-tidy-build}
tidy=clang-tidy-$CLANG_TIDY_VERSION

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit, opt, personal preference: I would prefer to name this variable clang_tidy, I think it would be clearer for C++ developers


if ! command -v "$tidy" >/dev/null 2>&1; then
if [ -f /etc/debian_version ]; then
apt-get update
DEBIAN_FRONTEND=noninteractive apt-get install --yes "$tidy"
else
>&2 echo "$tidy is required (pinned). Install it in this container."
exit 1
fi
fi

if ! command -v "$tidy" >/dev/null 2>&1; then
>&2 echo "$tidy is not installed."
exit 1
fi

compiler=${CXX:-clang++}
if ! command -v "$compiler" >/dev/null 2>&1; then
>&2 echo "$compiler is required (same toolchain as CMake)."
exit 1
fi

compiler_major=$("$compiler" -dumpversion | cut -d. -f1)
tidy_major=$("$tidy" --version | sed -n 's/.*version \([0-9][0-9]*\).*/\1/p' | head -n 1)
if [ "$compiler_major" != "$CLANG_TIDY_VERSION" ] || [ "$tidy_major" != "$CLANG_TIDY_VERSION" ]; then
>&2 echo "clang-tidy and the CMake compiler must both be LLVM $CLANG_TIDY_VERSION."
>&2 echo " $compiler: $compiler_major"
>&2 echo " $tidy: $tidy_major"
exit 1
fi

# Reconfigure so CXX_CLANG_TIDY is attached to dd-trace-cpp-objects, then

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of compiling with clang-tidy step, I think we could rather only run clang-tidy directly.
This would remove the added lines in CMakeLists.txt.
Here also, the call would be simpler:

bin/with-toolchain llvm cmake . -B "$build_dir" --preset ci-clang

run-clang-tidy-$CLANG_TIDY_VERSION -p "$build_dir" -clang-tidy-binary "$tidy" \
    -quiet "^$REPO_ROOT/src/"

By the way, it seems that files in include/ are currently not checked.

Moreover, I think this would ease adding, possibly incrementally, the test/ folder. We need to add this, probably in a follow-up PR.

What do you think?

# compile that target. CMake passes the exact ci-clang compile line
# (including -stdlib=libc++) to tidy. First-party src/ only; no extra-args.
bin/with-toolchain llvm cmake . -B "$build_dir" --preset ci-clang \
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON \

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems this is redundant with the added line (line 42) in CMakePresets.json.

-DDD_TRACE_ENABLE_CLANG_TIDY=ON \
-DDD_TRACE_CLANG_TIDY="$tidy"

cmake --build "$build_dir" --target dd-trace-cpp-objects -j
24 changes: 24 additions & 0 deletions docs/development.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,27 @@ command:
```shell
bin/format
```

To check formatting without writing files:

```shell
bin/check-format
```

## Static Analysis

C++ is analyzed with **clang-tidy-14** (pinned; same major as `clang-format-14`)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need a much simpler and direct documentation, without internal technical details. I suggest:

C++ code is analyzed with Clang Tidy. Run this with the following command:

\```shell
bin/check-tidy
\```

using the shared `.clang-tidy` baseline. Warnings are errors.

Do not run clang-tidy on the host. Tidy must use the same compiler, flags, and
stdlib as the real build (`ci-clang` + libc++). `bin/check-tidy` re-execs in
`datadog/docker-library:dd-trace-cpp-ci-23768e9-*`, configures CMake there with
`DD_TRACE_ENABLE_CLANG_TIDY`, and builds `dd-trace-cpp-objects` so CMake
invokes `clang-tidy-14` with the exact compile line (first-party `src/` only):

```shell
bin/check-tidy
```

CI runs the same script in that image. A finding fails the pull request.

Loading