ci: add clang code coverage check #10
					 6 changed files with 112 additions and 14 deletions
				
			
		
							
								
								
									
										17
									
								
								.drone.yml
									
										
									
									
									
								
							
							
						
						
									
										17
									
								
								.drone.yml
									
										
									
									
									
								
							|  | @ -25,13 +25,13 @@ trigger: | |||
| 
 | ||||
| steps: | ||||
| - name: unit tests | ||||
|   image: unit_tests:latest | ||||
|   image: amd64_gcc_unit_tests:latest | ||||
|   pull: if-not-exists | ||||
|   commands: | ||||
|     - ./tools/ci/amd64/gcc/unit_tests.sh | ||||
| 
 | ||||
| - name: valgrind | ||||
|   image: valgrind:latest | ||||
|   image: amd64_gcc_valgrind:latest | ||||
|   pull: if-not-exists | ||||
|   commands: | ||||
|     - ./tools/ci/amd64/gcc/valgrind.sh | ||||
|  | @ -45,14 +45,23 @@ trigger: | |||
|   - main | ||||
| 
 | ||||
| steps: | ||||
| - name: code coverage | ||||
|   image: amd64_clang_coverage:latest | ||||
|   pull: if-not-exists | ||||
|   environment: | ||||
|     CODECOV_TOKEN: | ||||
|       from_secret: CODECOV_TOKEN  | ||||
|   commands: | ||||
|     - ./tools/ci/amd64/clang/coverage.sh | ||||
| 
 | ||||
| - name: leak sanitizer | ||||
|   image: leak_sanitizer:latest | ||||
|   image: amd64_clang_lsan:latest | ||||
|   pull: if-not-exists | ||||
|   commands: | ||||
|     - ./tools/ci/amd64/clang/lsan.sh | ||||
| 
 | ||||
| - name: memory sanitizer | ||||
|   image: memory_sanitizer:latest | ||||
|   image: amd64_clang_msan:latest | ||||
|   pull: if-not-exists | ||||
|   commands: | ||||
|     - ./tools/ci/amd64/clang/msan.sh | ||||
|  |  | |||
|  | @ -1,16 +1,42 @@ | |||
| cmake_minimum_required(VERSION 3.14) | ||||
| project(Light) | ||||
| set(CMAKE_CXX_STANDARD 23) | ||||
| set(CMAKE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/tools/cmake) | ||||
| 
 | ||||
| include(${CMAKE_CURRENT_SOURCE_DIR}/tools/cmake/functions.cmake) | ||||
| include(${CMAKE_CURRENT_SOURCE_DIR}/tools/cmake/definitions.cmake) | ||||
| include(${CMAKE_CURRENT_SOURCE_DIR}/tools/cmake/dependencies.cmake) | ||||
| include(CheckCXXSourceCompiles) | ||||
| include(${CMAKE_DIR}/functions.cmake) | ||||
| include(${CMAKE_DIR}/definitions.cmake) | ||||
| include(${CMAKE_DIR}/dependencies.cmake) | ||||
| 
 | ||||
| add_option(ENABLE_STATIC_ANALYSIS "Performs static analysis via clang-tidy and fails build on failing checks") | ||||
| add_option(ENABLE_TESTS "Enables the building of the test modules") | ||||
| 
 | ||||
| add_option(ENABLE_STATIC_ANALYSIS "Makes clang-tidy checks mandatory for compilation") | ||||
| if (ENABLE_STATIC_ANALYSIS) | ||||
|     set(CMAKE_CXX_CLANG_TIDY "clang-tidy;--warnings-as-errors=*;--allow-no-checks") | ||||
| endif () | ||||
| 
 | ||||
| add_option(ENABLE_TESTS "Enables the building of the test modules") | ||||
| add_option(ENABLE_LLVM_COVERAGE "Enables the code coverage instrumentation for clang") | ||||
| if(ENABLE_LLVM_COVERAGE) | ||||
|     if (NOT "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") | ||||
|         message(FATAL_ERROR "ENABLE_LLVM_COVERAGE only supports the clang compiler") | ||||
|     endif () | ||||
| 
 | ||||
|     # Check for libc++ | ||||
|     check_cxx_source_compiles(" | ||||
|         #include <string> | ||||
|         #ifdef _LIBCPP_VERSION | ||||
|         int main() { return 0; } | ||||
|         #else | ||||
|         #error Not using libc++ | ||||
|         #endif | ||||
|     " USING_LIBCXX) | ||||
|     if(NOT USING_LIBCXX) | ||||
|         message(FATAL_ERROR "ENABLE_LLVM_COVERAGE requires libc++, please compile with -stdlib=libc++") | ||||
|     endif() | ||||
| 
 | ||||
|     add_compile_options(-fprofile-instr-generate -fcoverage-mapping) | ||||
|     add_link_options(-fprofile-instr-generate -fcoverage-mapping) | ||||
| endif () | ||||
| 
 | ||||
| add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/modules) | ||||
| add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/external/glad) | ||||
|  |  | |||
|  | @ -12,6 +12,7 @@ class LightRecipe(ConanFile): | |||
| 
 | ||||
|     options = { | ||||
|         "enable_tests": [True, False], | ||||
|         "enable_llvm_coverage": [True, False], | ||||
|         "enable_static_analysis": [True, False], | ||||
|         "use_mold": [True, False], | ||||
|         "export_compile_commands": [True, False], | ||||
|  | @ -19,6 +20,7 @@ class LightRecipe(ConanFile): | |||
| 
 | ||||
|     default_options = { | ||||
|         "enable_tests": True, | ||||
|         "enable_llvm_coverage": False, | ||||
|         "enable_static_analysis": False, | ||||
|         "use_mold": False, | ||||
|         "export_compile_commands": True, | ||||
|  | @ -44,8 +46,9 @@ class LightRecipe(ConanFile): | |||
|             tc.cache_variables["CMAKE_LINKER_TYPE"] = "MOLD" | ||||
| 
 | ||||
|         tc.cache_variables["CMAKE_EXPORT_COMPILE_COMMANDS"] = self.options.export_compile_commands | ||||
|         tc.cache_variables["ENABLE_STATIC_ANALYSIS"] = self.options.enable_static_analysis | ||||
|         tc.cache_variables["ENABLE_TESTS"] = self.options.enable_tests | ||||
|         tc.cache_variables["ENABLE_LLVM_COVERAGE"] = self.options.enable_llvm_coverage | ||||
|         tc.cache_variables["ENABLE_STATIC_ANALYSIS"] = self.options.enable_static_analysis | ||||
| 
 | ||||
|         repo = git.Repo(search_parent_directories=True) | ||||
|         tc.cache_variables["GIT_HASH"] = repo.head.object.hexsha | ||||
|  |  | |||
							
								
								
									
										48
									
								
								tools/ci/amd64/clang/coverage.dockerfile
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								tools/ci/amd64/clang/coverage.dockerfile
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,48 @@ | |||
| FROM archlinux:latest | ||||
| 
 | ||||
| RUN pacman -Syu --noconfirm && \ | ||||
|     pacman -S --noconfirm \ | ||||
|     bash \ | ||||
|     base-devel \ | ||||
|     git \ | ||||
|     cmake \ | ||||
|     ninja \ | ||||
|     python \ | ||||
|     python-pip \ | ||||
|     clang \ | ||||
|     llvm \ | ||||
|     mesa \ | ||||
|     mold \ | ||||
|     ninja \ | ||||
|     curl \ | ||||
|     wget \ | ||||
|     zlib | ||||
| 
 | ||||
| RUN pip install --no-cache-dir --break-system-packages conan gitpython \ | ||||
|     && conan profile detect | ||||
| 
 | ||||
| RUN clang --version  \ | ||||
|     && pip --version \ | ||||
|     && conan --version \ | ||||
|     && cmake --version \ | ||||
|     && g++ --version \ | ||||
|     && clang --version \ | ||||
|     && ninja --version \ | ||||
|     && mold --version \ | ||||
|     && llvm-profdata --version \ | ||||
|     && llvm-cov --version | ||||
| 
 | ||||
| RUN git clone 'https://git.light7734.com/light7734/light.git' \ | ||||
|     && cd light; git checkout 'ci/code_cov' \ | ||||
|     && conan build . \ | ||||
|         -c tools.system.package_manager:mode=install \ | ||||
|         -c tools.cmake.cmaketoolchain:generator=Ninja \ | ||||
|         -c tools.build:compiler_executables='{"c": "clang", "cpp": "clang++"}' \ | ||||
|         -s build_type=Release \ | ||||
|         -s compiler=clang \ | ||||
|         -s compiler.version=20 \ | ||||
|         -s compiler.libcxx=libc++ \ | ||||
|         -o use_mold=True \ | ||||
|         -o enable_lcov=True \ | ||||
|         --build=missing \ | ||||
|     && rm -r ../light/ | ||||
|  | @ -7,16 +7,13 @@ rm -rf ./build | |||
| conan build . \ | ||||
|     -c tools.system.package_manager:mode=install \ | ||||
|     -c tools.cmake.cmaketoolchain:generator=Ninja \ | ||||
|     -c tools.build:cxxflags='["-fprofile-instr-generate", "-fcoverage-mapping"]' \ | ||||
|     -c tools.build:sharedlinkflags='["-fprofile-instr-generate", "-fcoverage-mapping"]' \ | ||||
|     -c tools.build:exelinkflags='["-fprofile-instr-generate", "-fcoverage-mapping"]' \ | ||||
|     -c tools.info.package_id:confs='["tools.build:cxxflags","tools.build:sharedlinkflags","tools.build:exelinkflags"]' \ | ||||
|     -c tools.build:compiler_executables='{"c": "clang", "cpp": "clang++"}' \ | ||||
|     -s build_type=Release \ | ||||
|     -s compiler=clang \ | ||||
|     -s compiler.version=20 \ | ||||
|     -s compiler.libcxx=libc++ \ | ||||
|     -o use_mold=True \ | ||||
|     -o enable_llvm_coverage=True \ | ||||
|     --build=missing | ||||
| 
 | ||||
| for test in $(find ./build -type f -name '*_tests' -executable); do | ||||
|  | @ -24,3 +21,15 @@ for test in $(find ./build -type f -name '*_tests' -executable); do | |||
|   "$test" | ||||
| done | ||||
| 
 | ||||
| mkdir -p ./build/coverage/  | ||||
| for test in $(find ./build -type f -name '*_tests' -executable); do | ||||
|     export LLVM_PROFILE_FILE="./build/coverage/$(basename "$(dirname "{}")").profraw"; | ||||
|     echo ${LLVM_PROFILE_FILE} >> ./build/coverage/list; | ||||
|     "$test" | ||||
| done | ||||
| 
 | ||||
| llvm-profdata merge --input-files './build/coverage/list' -o "./build/coverage/merged.profdata"  | ||||
| find ./modules -type f -name "*.profraw" -exec rm -fv {} + | ||||
| LLVM_COV_SHOW=$(llvm-cov show -instr-profile='./build/coverage/merged.profdata' $(find ./build -type f -name '*_tests' -executable -exec printf -- '-object %s ' {} \;) -ignore-filename-regex='./modules/[^/]+/*_tests') | ||||
| echo "${LLVM_COV_SHOW}" > './build/coverage/coverage.txt' | ||||
| wget -qO- "https://codecov.io/bash" | bash | ||||
|  |  | |||
|  | @ -15,6 +15,9 @@ docker build -t amd64_gcc_unit_tests -f $CI_DIR/amd64/gcc/unit_tests.dockerfile | |||
| echo "==> Building image: amd64_gcc_valgrind" | ||||
| docker build -t amd64_gcc_valgrind -f $CI_DIR/amd64/gcc/valgrind.dockerfile . | ||||
| 
 | ||||
| echo "==> Building image: amd64_clang_coverage" | ||||
| docker build -t amd64_clang_coverage -f $CI_DIR/amd64/clang/coverage.dockerfile . | ||||
| 
 | ||||
| echo "==> Building image: amd64_clang_lsan" | ||||
| docker build -t amd64_clang_lsan -f $CI_DIR/amd64/clang/lsan.dockerfile . | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue