Skip to content

Commit 27c80e3

Browse files
chore: use the same logic for toolchain detection
1 parent 1c7f3ec commit 27c80e3

File tree

4 files changed

+153
-44
lines changed

4 files changed

+153
-44
lines changed

core/BUILD

Lines changed: 2 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -71,45 +71,16 @@ cc_library(
7171
# Generate a header with C++ toolchain information
7272
genrule(
7373
name = "toolchain_info_gen",
74+
srcs = ["scripts/detect_toolchain.sh"],
7475
outs = ["toolchain_info.h"],
7576
cmd = """
76-
set -e
77-
COMPILER="$(CC)"
78-
FULL_VERSION=$$($$COMPILER --version 2>/dev/null | head -n1) || FULL_VERSION="unknown"
79-
80-
COMPILER_ID="unknown"
81-
COMPILER_VERSION="unknown"
82-
83-
if echo "$$FULL_VERSION" | grep -qi "clang"; then
84-
COMPILER_ID="Clang"
85-
COMPILER_VERSION=$$(echo "$$FULL_VERSION" | grep -oP '\\d+\\.\\d+\\.\\d+' | head -n1) || COMPILER_VERSION="unknown"
86-
elif echo "$$FULL_VERSION" | grep -qi "gcc\\|g++\\|GNU"; then
87-
COMPILER_ID="GNU"
88-
COMPILER_VERSION=$$(echo "$$FULL_VERSION" | grep -oP '\\d+\\.\\d+\\.\\d+' | head -n1) || COMPILER_VERSION="unknown"
89-
elif echo "$$FULL_VERSION" | grep -qi "MSVC\\|Microsoft"; then
90-
COMPILER_ID="MSVC"
91-
COMPILER_VERSION=$$(echo "$$FULL_VERSION" | grep -oP '\\d+\\.\\d+\\.\\d+' | head -n1) || COMPILER_VERSION="unknown"
92-
fi
93-
9477
case "$(COMPILATION_MODE)" in
9578
opt) BUILD_TYPE="Release" ;;
9679
dbg) BUILD_TYPE="Debug" ;;
9780
fastbuild) BUILD_TYPE="FastBuild" ;;
9881
*) BUILD_TYPE="$(COMPILATION_MODE)" ;;
9982
esac
100-
101-
cat > $@ << HEADER_EOF
102-
// Auto-generated by Bazel - do not edit
103-
#ifndef CODSPEED_TOOLCHAIN_INFO_H
104-
#define CODSPEED_TOOLCHAIN_INFO_H
105-
106-
#define CODSPEED_CXX_COMPILER_ID "$$COMPILER_ID"
107-
#define CODSPEED_CXX_COMPILER_VERSION "$$COMPILER_VERSION"
108-
#define CODSPEED_CXX_COMPILER_FULL_VERSION "$$FULL_VERSION"
109-
#define CODSPEED_BUILD_TYPE "$$BUILD_TYPE"
110-
111-
#endif // CODSPEED_TOOLCHAIN_INFO_H
112-
HEADER_EOF
83+
bash $(location scripts/detect_toolchain.sh) "$(CC)" "$$BUILD_TYPE" > $@
11384
""",
11485
toolchains = ["@bazel_tools//tools/cpp:current_cc_toolchain"],
11586
)

core/CMakeLists.txt

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -97,23 +97,20 @@ target_link_libraries(codspeed PRIVATE instrument_hooks)
9797
add_compile_definitions(CODSPEED_VERSION="${CODSPEED_VERSION}")
9898

9999
# Collect compiler toolchain information for environment reporting
100+
# Use the shared detect_toolchain.sh script (same as Bazel) for consistent output
100101
execute_process(
101-
COMMAND ${CMAKE_CXX_COMPILER} --version
102-
OUTPUT_VARIABLE CODSPEED_CXX_COMPILER_FULL_VERSION
102+
COMMAND bash "${CMAKE_CURRENT_SOURCE_DIR}/scripts/detect_toolchain.sh"
103+
"${CMAKE_CXX_COMPILER}" "${CMAKE_BUILD_TYPE}"
104+
OUTPUT_VARIABLE CODSPEED_TOOLCHAIN_HEADER
103105
OUTPUT_STRIP_TRAILING_WHITESPACE
104-
ERROR_QUIET
106+
RESULT_VARIABLE DETECT_TOOLCHAIN_RESULT
105107
)
106-
# Extract first line only
107-
if(CODSPEED_CXX_COMPILER_FULL_VERSION)
108-
string(REGEX REPLACE "\n.*" "" CODSPEED_CXX_COMPILER_FULL_VERSION "${CODSPEED_CXX_COMPILER_FULL_VERSION}")
108+
if(DETECT_TOOLCHAIN_RESULT EQUAL 0)
109+
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/toolchain_info.h" "${CODSPEED_TOOLCHAIN_HEADER}\n")
110+
else()
111+
message(WARNING "detect_toolchain.sh failed, toolchain info will not be available")
109112
endif()
110-
111-
target_compile_definitions(codspeed PRIVATE
112-
CODSPEED_CXX_COMPILER_ID="${CMAKE_CXX_COMPILER_ID}"
113-
CODSPEED_CXX_COMPILER_VERSION="${CMAKE_CXX_COMPILER_VERSION}"
114-
CODSPEED_CXX_COMPILER_FULL_VERSION="${CODSPEED_CXX_COMPILER_FULL_VERSION}"
115-
CODSPEED_BUILD_TYPE="${CMAKE_BUILD_TYPE}"
116-
)
113+
target_include_directories(codspeed PRIVATE "${CMAKE_CURRENT_BINARY_DIR}")
117114

118115
# Specify the include directories for users of the library
119116
target_include_directories(

core/scripts/detect_toolchain.sh

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#!/usr/bin/env bash
2+
# Detect C++ compiler toolchain information from `<compiler> --version` output.
3+
# Used by Bazel genrule to generate toolchain_info.h.
4+
#
5+
# Usage: detect_toolchain.sh <compiler_path> <build_type>
6+
# Output: Writes a C header to stdout with CODSPEED_CXX_* defines.
7+
8+
set -e
9+
10+
COMPILER="${1:?Usage: detect_toolchain.sh <compiler_path> <build_type>}"
11+
BUILD_TYPE="${2:?Usage: detect_toolchain.sh <compiler_path> <build_type>}"
12+
13+
FULL_VERSION=$("$COMPILER" --version 2>/dev/null | head -n1) || FULL_VERSION="unknown"
14+
15+
COMPILER_ID="unknown"
16+
COMPILER_VERSION="unknown"
17+
18+
if echo "$FULL_VERSION" | grep -qi "clang"; then
19+
COMPILER_ID="Clang"
20+
COMPILER_VERSION=$(echo "$FULL_VERSION" | grep -oP '\d+\.\d+\.\d+' | head -n1) || COMPILER_VERSION="unknown"
21+
elif echo "$FULL_VERSION" | grep -qi "gcc\|g++\|GNU"; then
22+
COMPILER_ID="GNU"
23+
COMPILER_VERSION=$(echo "$FULL_VERSION" | grep -oP '\d+\.\d+\.\d+' | head -n1) || COMPILER_VERSION="unknown"
24+
elif echo "$FULL_VERSION" | grep -qi "MSVC\|Microsoft"; then
25+
COMPILER_ID="MSVC"
26+
COMPILER_VERSION=$(echo "$FULL_VERSION" | grep -oP '\d+\.\d+\.\d+' | head -n1) || COMPILER_VERSION="unknown"
27+
fi
28+
29+
cat << HEADER_EOF
30+
// Auto-generated - do not edit
31+
#ifndef CODSPEED_TOOLCHAIN_INFO_H
32+
#define CODSPEED_TOOLCHAIN_INFO_H
33+
34+
#define CODSPEED_CXX_COMPILER_ID "$COMPILER_ID"
35+
#define CODSPEED_CXX_COMPILER_VERSION "$COMPILER_VERSION"
36+
#define CODSPEED_CXX_COMPILER_FULL_VERSION "$FULL_VERSION"
37+
#define CODSPEED_BUILD_TYPE "$BUILD_TYPE"
38+
39+
#endif // CODSPEED_TOOLCHAIN_INFO_H
40+
HEADER_EOF
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
#!/usr/bin/env bash
2+
# Manual tests for detect_toolchain.sh
3+
# Run: bash core/scripts/test_detect_toolchain.sh
4+
#
5+
# Uses mock compiler scripts to simulate different --version outputs.
6+
7+
set -e
8+
9+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
10+
DETECT_SCRIPT="$SCRIPT_DIR/detect_toolchain.sh"
11+
TMPDIR=$(mktemp -d)
12+
trap 'rm -rf "$TMPDIR"' EXIT
13+
14+
PASS=0
15+
FAIL=0
16+
17+
assert_contains() {
18+
local label="$1"
19+
local expected="$2"
20+
local actual="$3"
21+
if echo "$actual" | grep -qF "$expected"; then
22+
PASS=$((PASS + 1))
23+
else
24+
FAIL=$((FAIL + 1))
25+
echo "FAIL: $label"
26+
echo " expected to contain: $expected"
27+
echo " got: $actual"
28+
fi
29+
}
30+
31+
# Create a mock compiler that outputs a given --version string
32+
make_mock_compiler() {
33+
local name="$1"
34+
local version_output="$2"
35+
local path="$TMPDIR/$name"
36+
cat > "$path" << EOF
37+
#!/usr/bin/env bash
38+
echo "$version_output"
39+
EOF
40+
chmod +x "$path"
41+
echo "$path"
42+
}
43+
44+
# --- Test cases ---
45+
46+
echo "Running detect_toolchain.sh tests..."
47+
echo
48+
49+
# Test: GCC
50+
mock=$(make_mock_compiler "gcc-mock" "gcc (GCC) 14.3.0")
51+
output=$(bash "$DETECT_SCRIPT" "$mock" "Release")
52+
assert_contains "GCC compiler_id" 'CODSPEED_CXX_COMPILER_ID "GNU"' "$output"
53+
assert_contains "GCC version" 'CODSPEED_CXX_COMPILER_VERSION "14.3.0"' "$output"
54+
assert_contains "GCC full_version" 'CODSPEED_CXX_COMPILER_FULL_VERSION "gcc (GCC) 14.3.0"' "$output"
55+
assert_contains "GCC build_type" 'CODSPEED_BUILD_TYPE "Release"' "$output"
56+
57+
# Test: g++
58+
mock=$(make_mock_compiler "gpp-mock" "g++ (GCC) 13.2.1 20230801")
59+
output=$(bash "$DETECT_SCRIPT" "$mock" "Debug")
60+
assert_contains "g++ compiler_id" 'CODSPEED_CXX_COMPILER_ID "GNU"' "$output"
61+
assert_contains "g++ version" 'CODSPEED_CXX_COMPILER_VERSION "13.2.1"' "$output"
62+
assert_contains "g++ build_type" 'CODSPEED_BUILD_TYPE "Debug"' "$output"
63+
64+
# Test: Clang
65+
mock=$(make_mock_compiler "clang-mock" "clang version 19.1.7 (https://github.com/llvm/llvm-project abc123)")
66+
output=$(bash "$DETECT_SCRIPT" "$mock" "Release")
67+
assert_contains "Clang compiler_id" 'CODSPEED_CXX_COMPILER_ID "Clang"' "$output"
68+
assert_contains "Clang version" 'CODSPEED_CXX_COMPILER_VERSION "19.1.7"' "$output"
69+
70+
# Test: Apple Clang
71+
mock=$(make_mock_compiler "apple-clang-mock" "Apple clang version 15.0.0 (clang-1500.0.40.1)")
72+
output=$(bash "$DETECT_SCRIPT" "$mock" "Release")
73+
assert_contains "Apple Clang compiler_id" 'CODSPEED_CXX_COMPILER_ID "Clang"' "$output"
74+
assert_contains "Apple Clang version" 'CODSPEED_CXX_COMPILER_VERSION "15.0.0"' "$output"
75+
76+
# Test: Ubuntu GCC
77+
mock=$(make_mock_compiler "ubuntu-gcc-mock" "gcc (Ubuntu 13.3.0-6ubuntu2~24.04) 13.3.0")
78+
output=$(bash "$DETECT_SCRIPT" "$mock" "Release")
79+
assert_contains "Ubuntu GCC compiler_id" 'CODSPEED_CXX_COMPILER_ID "GNU"' "$output"
80+
assert_contains "Ubuntu GCC version" 'CODSPEED_CXX_COMPILER_VERSION "13.3.0"' "$output"
81+
82+
# Test: Unknown compiler
83+
mock=$(make_mock_compiler "unknown-mock" "some-compiler v2.0")
84+
output=$(bash "$DETECT_SCRIPT" "$mock" "Release")
85+
assert_contains "Unknown compiler_id" 'CODSPEED_CXX_COMPILER_ID "unknown"' "$output"
86+
assert_contains "Unknown version" 'CODSPEED_CXX_COMPILER_VERSION "unknown"' "$output"
87+
88+
# Test: Header guard present
89+
assert_contains "Header guard" '#ifndef CODSPEED_TOOLCHAIN_INFO_H' "$output"
90+
assert_contains "Header guard endif" '#endif' "$output"
91+
92+
# --- Summary ---
93+
94+
echo
95+
TOTAL=$((PASS + FAIL))
96+
if [ "$FAIL" -eq 0 ]; then
97+
echo "All $TOTAL tests passed."
98+
else
99+
echo "$FAIL/$TOTAL tests FAILED."
100+
exit 1
101+
fi

0 commit comments

Comments
 (0)