forked from espressif/esp-idf
ci: add job to check for C++ guards in header files
This commit is contained in:
committed by
David Cermak
parent
c7738f24fc
commit
c6d6fe0316
127
tools/ci/check_cpp_guards.sh
Executable file
127
tools/ci/check_cpp_guards.sh
Executable file
@@ -0,0 +1,127 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# This script finds all files which do not contain "#ifdef __cplusplus", except the ones listed in check_cpp_guards_exceptions.txt
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
if [ -z "${IDF_PATH:-}" ]; then
|
||||||
|
echo "Please run export.sh before invoking this script"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
##################### helper functions #####################
|
||||||
|
|
||||||
|
# check_one_header <filename>
|
||||||
|
#
|
||||||
|
# Function used to implement the logic of checking a single header.
|
||||||
|
# Returns 0 on success (as a normal bash function would).
|
||||||
|
# Ideally shouldn't print anything.
|
||||||
|
function check_one_header
|
||||||
|
{
|
||||||
|
include_file=$1
|
||||||
|
grep -q '#ifdef __cplusplus' ${include_file}
|
||||||
|
}
|
||||||
|
|
||||||
|
# get_include_dir_list
|
||||||
|
#
|
||||||
|
# Get the list of public include directories from compile_commands.json.
|
||||||
|
# Stores the result in INCLUDE_DIRS variable.
|
||||||
|
function get_include_dirs_list
|
||||||
|
{
|
||||||
|
pushd $IDF_PATH/examples/get-started/blink
|
||||||
|
idf.py reconfigure
|
||||||
|
|
||||||
|
# Get the compiler command line from compile_commands.json
|
||||||
|
# Poor man's replacement of `jq` in Python.
|
||||||
|
extract_build_command_py='import json; print(json.load(open("build/compile_commands.json", "r"))[0]["command"])'
|
||||||
|
build_command=$(python -c "${extract_build_command_py}")
|
||||||
|
|
||||||
|
# build the list of include directories, only considering the directories in "components/"
|
||||||
|
include_dirs=""
|
||||||
|
for token in ${build_command}; do
|
||||||
|
if [[ ! "${token}" =~ ^-I.*/components/.* ]]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
newline=$'\n'
|
||||||
|
include_dirs="${include_dirs}${token##-I}${newline}"
|
||||||
|
done
|
||||||
|
|
||||||
|
export INCLUDE_DIRS=${include_dirs}
|
||||||
|
}
|
||||||
|
|
||||||
|
# check_include_dirs <include_dirs> <failed_headers_list_file>
|
||||||
|
#
|
||||||
|
# Check all header files in directories listed in include_dirs variable.
|
||||||
|
# Places the list of header files with some issues into <failed_headers_list_file> file.
|
||||||
|
# Calls check_one_header function to check a single header file.
|
||||||
|
function check_include_dirs
|
||||||
|
{
|
||||||
|
local include_dirs="$1"
|
||||||
|
local failed_headers_list_file="$2"
|
||||||
|
|
||||||
|
rm -f ${failed_headers_list_file}
|
||||||
|
touch ${failed_headers_list_file}
|
||||||
|
|
||||||
|
for include_dir in ${include_dirs}; do
|
||||||
|
echo "Processing include directory: ${include_dir}"
|
||||||
|
include_files=$(find ${include_dir} -name '*.h')
|
||||||
|
for include_file in ${include_files}; do
|
||||||
|
printf " Processing ${include_file}"
|
||||||
|
if ! check_one_header ${include_file}; then
|
||||||
|
printf " FAIL!\n"
|
||||||
|
echo ${include_file##${IDF_PATH}/} >> ${failed_headers_list_file}
|
||||||
|
else
|
||||||
|
printf " OK\n"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# filter_exclusions <input_list_file> <exclusions_list_file> <filtered_list_file>
|
||||||
|
#
|
||||||
|
# Takes the list of files in <input_list_file> file, and removes all files which
|
||||||
|
# are listed in <exclusions_list_file> file.
|
||||||
|
# Saves the final (filtered) list in <filtered_list_file> file.
|
||||||
|
# The exclusions list file may contain comments and empty lines.
|
||||||
|
function filter_exclusions
|
||||||
|
{
|
||||||
|
local input_list_file=$1
|
||||||
|
local exclusions_list_file=$2
|
||||||
|
local filtered_list_file=$3
|
||||||
|
local temp_list=$(mktemp)
|
||||||
|
|
||||||
|
cp ${input_list_file} ${filtered_list_file}
|
||||||
|
touch ${temp_list}
|
||||||
|
|
||||||
|
while read -r line; do
|
||||||
|
if [[ "${line}" =~ ^\# || -z "${line}" ]]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
echo "Excluding ${line}"
|
||||||
|
grep -vE "${line}" ${filtered_list_file} > ${temp_list} || true
|
||||||
|
mv ${temp_list} ${filtered_list_file}
|
||||||
|
done < ${exclusions_list_file}
|
||||||
|
|
||||||
|
rm -f ${temp_list}
|
||||||
|
}
|
||||||
|
|
||||||
|
##################### main logic starts here #####################
|
||||||
|
|
||||||
|
EXCLUSIONS_LIST=${IDF_PATH}/tools/ci/check_cpp_guards_exceptions.txt
|
||||||
|
MISSING_GUARDS_LIST=missing.txt
|
||||||
|
FILTERED_LIST=filtered.txt
|
||||||
|
LINE=---------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
get_include_dirs_list
|
||||||
|
check_include_dirs "${INCLUDE_DIRS}" ${MISSING_GUARDS_LIST}
|
||||||
|
filter_exclusions ${MISSING_GUARDS_LIST} ${EXCLUSIONS_LIST} ${FILTERED_LIST}
|
||||||
|
|
||||||
|
if [ -s ${FILTERED_LIST} ]; then
|
||||||
|
echo "The following files don't have C++ guards:"
|
||||||
|
echo ""
|
||||||
|
cat ${FILTERED_LIST}
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "No errors found"
|
118
tools/ci/check_cpp_guards_exceptions.txt
Normal file
118
tools/ci/check_cpp_guards_exceptions.txt
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
components/xtensa/include/xtensa/*
|
||||||
|
components/xtensa/include/*
|
||||||
|
components/xtensa/esp32/include/xtensa/config/*
|
||||||
|
|
||||||
|
components/newlib/platform_include/*
|
||||||
|
|
||||||
|
components/freertos/include/freertos/*
|
||||||
|
|
||||||
|
components/log/include/esp_log_internal.h
|
||||||
|
|
||||||
|
components/soc/esp32/include/hal/*
|
||||||
|
components/soc/esp32/include/soc/*
|
||||||
|
components/soc/include/hal/*
|
||||||
|
components/soc/include/soc/*
|
||||||
|
|
||||||
|
components/esp_rom/include/esp32s2beta/rom/rsa_pss.h
|
||||||
|
|
||||||
|
components/esp_common/include/esp_types.h
|
||||||
|
components/esp_common/include/esp_assert.h
|
||||||
|
components/esp_common/include/esp_bit_defs.h
|
||||||
|
components/esp_common/include/esp_task.h
|
||||||
|
components/esp_common/include/esp_private/*
|
||||||
|
|
||||||
|
components/esp32/include/esp32/*
|
||||||
|
components/esp32/include/rom/*
|
||||||
|
components/esp32/include/esp_clk.h
|
||||||
|
components/esp32/include/esp_intr.h
|
||||||
|
components/esp32/include/esp_himem.h
|
||||||
|
components/esp32/include/esp_spiram.h
|
||||||
|
components/driver/include/driver/touch_pad.h
|
||||||
|
|
||||||
|
components/driver/include/driver/sdmmc_defs.h
|
||||||
|
components/driver/include/driver/sdmmc_types.h
|
||||||
|
components/driver/include/driver/rtc_cntl.h
|
||||||
|
components/driver/include/driver/sigmadelta.h
|
||||||
|
|
||||||
|
components/esp_event/include/esp_event_loop.h
|
||||||
|
|
||||||
|
components/lwip/include/apps/dhcpserver/*
|
||||||
|
components/lwip/include/apps/esp_sntp.h
|
||||||
|
components/lwip/lwip/src/include/compat/*
|
||||||
|
components/lwip/lwip/src/include/lwip/*
|
||||||
|
components/lwip/lwip/src/include/netif/*
|
||||||
|
components/lwip/port/esp32/include/*
|
||||||
|
|
||||||
|
components/vfs/include/sys/dirent.h
|
||||||
|
|
||||||
|
components/esp_wifi/include/esp_private/*
|
||||||
|
components/esp_wifi/include/esp_wifi_netif.h
|
||||||
|
components/esp_wifi/include/esp_wifi_default.h
|
||||||
|
components/esp_wifi/esp32/include/phy_init_data.h
|
||||||
|
|
||||||
|
components/tcpip_adapter/include/tcpip_adapter_compatible/tcpip_adapter_compat.h
|
||||||
|
components/tcpip_adapter/include/tcpip_adapter.h
|
||||||
|
components/tcpip_adapter/include/tcpip_adapter_types.h
|
||||||
|
|
||||||
|
components/spi_flash/include/spi_flash_chip_issi.h
|
||||||
|
components/spi_flash/include/spi_flash_chip_gd.h
|
||||||
|
components/spi_flash/include/memspi_host_driver.h
|
||||||
|
components/spi_flash/include/spi_flash_chip_driver.h
|
||||||
|
components/spi_flash/include/spi_flash_chip_generic.h
|
||||||
|
|
||||||
|
components/bootloader_support/include/esp_flash_data_types.h
|
||||||
|
components/bootloader_support/include/esp_app_format.h
|
||||||
|
|
||||||
|
components/wpa_supplicant/include/*
|
||||||
|
components/wpa_supplicant/port/*
|
||||||
|
|
||||||
|
components/mbedtls/port/include/*
|
||||||
|
components/mbedtls/mbedtls/include/mbedtls/*
|
||||||
|
|
||||||
|
components/espcoredump/include/esp_core_dump.h
|
||||||
|
|
||||||
|
components/perfmon/include/perfmon.h
|
||||||
|
|
||||||
|
components/asio/*
|
||||||
|
components/coap/*
|
||||||
|
components/nghttp/*
|
||||||
|
components/cbor/*
|
||||||
|
|
||||||
|
components/esp-tls/private_include/*
|
||||||
|
|
||||||
|
components/esp_http_server/include/http_server.h
|
||||||
|
|
||||||
|
components/protobuf-c/*
|
||||||
|
|
||||||
|
components/mdns/include/mdns_console.h
|
||||||
|
|
||||||
|
components/esp_serial_slave_link/include/esp_serial_slave_link/essl.h
|
||||||
|
components/esp_serial_slave_link/include/esp_serial_slave_link/essl_sdio.h
|
||||||
|
|
||||||
|
components/expat/*
|
||||||
|
|
||||||
|
components/fatfs/vfs/vfs_fat_internal.h
|
||||||
|
components/fatfs/src/ffconf.h
|
||||||
|
|
||||||
|
components/freemodbus/common/include/esp_modbus_common.h
|
||||||
|
components/freemodbus/common/include/mbcontroller.h
|
||||||
|
components/freemodbus/common/include/esp_modbus_master.h
|
||||||
|
components/freemodbus/common/include/esp_modbus_slave.h
|
||||||
|
|
||||||
|
components/idf_test/include/idf_performance.h
|
||||||
|
|
||||||
|
components/json/cJSON/*
|
||||||
|
|
||||||
|
components/libsodium/*
|
||||||
|
|
||||||
|
components/mqtt/esp-mqtt/include/mqtt_supported_features.h
|
||||||
|
components/mqtt/esp-mqtt/include/mqtt_config.h
|
||||||
|
|
||||||
|
components/openssl/include/platform/ssl_opt.h
|
||||||
|
|
||||||
|
components/spiffs/include/spiffs_config.h
|
||||||
|
|
||||||
|
components/unity/unity/src/unity_internals.h
|
||||||
|
components/unity/include/priv/setjmp.h
|
||||||
|
|
||||||
|
|
@@ -151,3 +151,19 @@ build_template_app:
|
|||||||
- for dir in esp32 esp32s2beta; do test $(xtensa-esp32-elf-nm $dir/*.a | grep -w printf | wc -l) -eq 0; done;
|
- for dir in esp32 esp32s2beta; do test $(xtensa-esp32-elf-nm $dir/*.a | grep -w printf | wc -l) -eq 0; done;
|
||||||
- for dir in esp32 esp32s2beta; do test $(xtensa-esp32-elf-nm $dir/*.a | grep -w ets_printf | wc -l) -eq 0; done;
|
- for dir in esp32 esp32s2beta; do test $(xtensa-esp32-elf-nm $dir/*.a | grep -w ets_printf | wc -l) -eq 0; done;
|
||||||
- popd
|
- popd
|
||||||
|
|
||||||
|
check_header_files_cpp_guards:
|
||||||
|
stage: pre_check
|
||||||
|
image: $CI_DOCKER_REGISTRY/esp32-ci-env$BOT_DOCKER_IMAGE_TAG
|
||||||
|
tags:
|
||||||
|
- build
|
||||||
|
variables:
|
||||||
|
BATCH_BUILD: "1"
|
||||||
|
only:
|
||||||
|
variables:
|
||||||
|
- $BOT_TRIGGER_WITH_LABEL == null
|
||||||
|
- $BOT_LABEL_BUILD
|
||||||
|
- $BOT_LABEL_REGULAR_TEST
|
||||||
|
script:
|
||||||
|
- tools/ci/check_cpp_guards.sh
|
||||||
|
|
||||||
|
@@ -36,6 +36,7 @@ tools/ci/build_examples_cmake.sh
|
|||||||
tools/ci/check-executable.sh
|
tools/ci/check-executable.sh
|
||||||
tools/ci/check-line-endings.sh
|
tools/ci/check-line-endings.sh
|
||||||
tools/ci/check_build_warnings.py
|
tools/ci/check_build_warnings.py
|
||||||
|
tools/ci/check_cpp_guards.sh
|
||||||
tools/ci/check_deprecated_kconfigs.py
|
tools/ci/check_deprecated_kconfigs.py
|
||||||
tools/ci/check_examples_cmake_make.sh
|
tools/ci/check_examples_cmake_make.sh
|
||||||
tools/ci/check_examples_rom_header.sh
|
tools/ci/check_examples_rom_header.sh
|
||||||
|
Reference in New Issue
Block a user