@@ -86,13 +86,22 @@ libocispec/libocispec.la:
8686
8787libcrun_la_SOURCES = $(libcrun_SOURCES )
8888libcrun_la_CFLAGS = -I $(abs_top_builddir ) /libocispec/src -I $(abs_top_srcdir ) /libocispec/src -fvisibility=hidden
89- libcrun_la_LIBADD = libocispec/libocispec.la $(FOUND_LIBS ) $(maybe_libyajl.la )
89+ if ENABLE_COVERAGE
90+ libcrun_la_CFLAGS += $(COVERAGE_CFLAGS )
91+ libcrun_la_LDFLAGS = -Wl,--version-script=$(abs_top_srcdir ) /libcrun.lds $(COVERAGE_LDFLAGS )
92+ else
9093libcrun_la_LDFLAGS = -Wl,--version-script=$(abs_top_srcdir ) /libcrun.lds
94+ endif
95+ libcrun_la_LIBADD = libocispec/libocispec.la $(FOUND_LIBS ) $(maybe_libyajl.la )
9196
9297# build a version with all the symbols visible for testing
9398if BUILD_TESTS
9499libcrun_testing_la_SOURCES = $(libcrun_SOURCES )
95100libcrun_testing_la_CFLAGS = -I $(abs_top_builddir ) /libocispec/src -I $(abs_top_srcdir ) /libocispec/src -fvisibility=default
101+ if ENABLE_COVERAGE
102+ libcrun_testing_la_CFLAGS += $(COVERAGE_CFLAGS )
103+ libcrun_testing_la_LDFLAGS = $(COVERAGE_LDFLAGS )
104+ endif
96105libcrun_testing_la_LIBADD = libocispec/libocispec.la $(maybe_libyajl.la )
97106endif
98107
@@ -137,16 +146,27 @@ dist-luarock: $(LUACRUN_ROCK)
137146endif
138147
139148crun_CFLAGS = -I $(abs_top_builddir ) /libocispec/src -I $(abs_top_srcdir ) /libocispec/src -D CRUN_LIBDIR="\"$(CRUN_LIBDIR ) \""
149+ if ENABLE_COVERAGE
150+ crun_CFLAGS += $(COVERAGE_CFLAGS )
151+ endif
140152crun_SOURCES = src/crun.c src/run.c src/delete.c src/kill.c src/pause.c src/unpause.c src/oci_features.c src/spec.c \
141153 src/exec.c src/list.c src/create.c src/start.c src/state.c src/update.c src/ps.c \
142154 src/checkpoint.c src/restore.c src/mounts.c src/run_create.c
143155
144156if DYNLOAD_LIBCRUN
157+ if ENABLE_COVERAGE
158+ crun_LDFLAGS = -Wl,--unresolved-symbols=ignore-all $(CRUN_LDFLAGS ) $(COVERAGE_LDFLAGS )
159+ else
145160crun_LDFLAGS = -Wl,--unresolved-symbols=ignore-all $(CRUN_LDFLAGS )
161+ endif
146162else
147163crun_LDADD = libcrun.la $(FOUND_LIBS ) $(maybe_libyajl.la )
164+ if ENABLE_COVERAGE
165+ crun_LDFLAGS = $(CRUN_LDFLAGS ) $(COVERAGE_LDFLAGS )
166+ else
148167crun_LDFLAGS = $(CRUN_LDFLAGS )
149168endif
169+ endif
150170
151171EXTRA_DIST = COPYING COPYING.libcrun README.md NEWS SECURITY.md rpm/crun.spec autogen.sh \
152172 src/libcrun/blake3/blake3_impl.h src/libcrun/blake3/blake3.h \
@@ -187,6 +207,7 @@ TESTS_LDADD = libcrun_testing.la $(FOUND_LIBS) $(maybe_libyajl.la)
187207
188208tests_init_LDADD =
189209tests_init_LDFLAGS = -static-libgcc -all-static
210+ tests_init_CFLAGS = -g -O2
190211tests_init_SOURCES = tests/init.c
191212
192213tests_tests_libcrun_utils_CFLAGS = -I $(abs_top_builddir ) /libocispec/src -I $(abs_top_srcdir ) /libocispec/src -I $(abs_top_builddir ) /src -I $(abs_top_srcdir ) /src
@@ -338,4 +359,105 @@ clang-format:
338359shellcheck :
339360 shellcheck autogen.sh build-aux/release.sh tests/run_all_tests.sh tests/* /* .sh contrib/* .sh
340361
341- .PHONY : coverity sync generate-rust-bindings generate-signals.c generate-mount_flags.c clang-format shellcheck
362+ # Code coverage targets
363+ if ENABLE_COVERAGE
364+
365+ # Clean coverage data
366+ coverage-clean :
367+ @rm -rf coverage-html coverage.info coverage.xml
368+ @find . -name " *.gcda" -delete
369+ @find . -name " *.gcno" -delete
370+
371+ # Reset coverage counters
372+ coverage-reset :
373+ @if test -n " $( LCOV) " ; then \
374+ $(LCOV ) --zerocounters --directory . ; \
375+ fi
376+
377+ # Run tests and collect coverage data
378+ coverage-check : coverage-reset
379+ @echo " Running tests for coverage (single-threaded to avoid race conditions)..."
380+ $(MAKE ) -j1 check
381+ @echo " Collecting coverage data..."
382+
383+ # Generate HTML coverage report (preferred method with lcov)
384+ coverage-html : coverage-check
385+ @if test -n " $( LCOV) " ; then \
386+ echo " Generating coverage report with lcov..." ; \
387+ $(LCOV ) --capture --directory . --output-file coverage.info; \
388+ $(LCOV ) --remove coverage.info ' /usr/*' --output-file coverage.info; \
389+ $(LCOV ) --remove coverage.info ' */libocispec/*' --output-file coverage.info; \
390+ $(LCOV ) --remove coverage.info ' */tests/test_*.py*' --output-file coverage.info; \
391+ $(LCOV ) --remove coverage.info ' */tests/init*' --output-file coverage.info; \
392+ genhtml coverage.info --output-directory coverage-html; \
393+ echo " Coverage report generated in coverage-html/index.html" ; \
394+ elif test -n " $( GCOVR) " ; then \
395+ echo " Generating coverage report with gcovr..." ; \
396+ $(GCOVR ) --html --html-details -o coverage.html \
397+ --exclude ' /usr/.*' --exclude ' .*/libocispec/.*' --exclude ' .*/tests/test_.*\.py.*' --exclude ' .*/tests/init.*' ; \
398+ echo " Coverage report generated in coverage.html" ; \
399+ else \
400+ echo " Generating coverage report with gcov..." ; \
401+ mkdir -p coverage-html; \
402+ for src in $( libcrun_SOURCES) $( crun_SOURCES) ; do \
403+ if test -f " $$ {src}.gcno" ; then \
404+ $(GCOV ) -o . $$ src || true ; \
405+ fi ; \
406+ done ; \
407+ mv * .gcov coverage-html/ 2> /dev/null || true ; \
408+ echo " Coverage files generated in coverage-html/" ; \
409+ fi
410+
411+ # Generate XML coverage report (for CI tools)
412+ coverage-xml : coverage-check
413+ @if test -n " $( GCOVR) " ; then \
414+ echo " Generating XML coverage report with gcovr..." ; \
415+ $(GCOVR ) --xml -o coverage.xml \
416+ --exclude ' /usr/.*' --exclude ' .*/libocispec/.*' --exclude ' .*/tests/test_.*\.py.*' --exclude ' .*/tests/init.*' ; \
417+ echo " Coverage report generated in coverage.xml" ; \
418+ elif test -n " $( LCOV) " ; then \
419+ echo " Generating XML coverage report with lcov..." ; \
420+ $(LCOV ) --capture --directory . --output-file coverage.info; \
421+ $(LCOV ) --remove coverage.info ' /usr/*' --output-file coverage.info; \
422+ $(LCOV ) --remove coverage.info ' */libocispec/*' --output-file coverage.info; \
423+ $(LCOV ) --remove coverage.info ' */tests/test_*.py*' --output-file coverage.info; \
424+ $(LCOV ) --remove coverage.info ' */tests/init*' --output-file coverage.info; \
425+ echo " Coverage data collected in coverage.info" ; \
426+ else \
427+ echo " XML coverage requires gcovr or lcov" ; \
428+ exit 1; \
429+ fi
430+
431+ # Generate coverage summary
432+ coverage-summary : coverage-check
433+ @if test -n " $( LCOV) " ; then \
434+ echo " Coverage summary (lcov):" ; \
435+ $(LCOV ) --capture --directory . --output-file coverage.info; \
436+ $(LCOV ) --remove coverage.info ' /usr/*' --output-file coverage.info; \
437+ $(LCOV ) --remove coverage.info ' */libocispec/*' --output-file coverage.info; \
438+ $(LCOV ) --remove coverage.info ' */tests/test_*.py*' --output-file coverage.info; \
439+ $(LCOV ) --remove coverage.info ' */tests/init*' --output-file coverage.info; \
440+ $(LCOV ) --summary coverage.info; \
441+ elif test -n " $( GCOVR) " ; then \
442+ echo " Coverage summary (gcovr):" ; \
443+ $(GCOVR ) --exclude ' /usr/.*' --exclude ' .*/libocispec/.*' --exclude ' .*/tests/test_.*\.py.*' --exclude ' .*/tests/init.*' ; \
444+ else \
445+ echo " Coverage summary requires lcov or gcovr" ; \
446+ fi
447+
448+ else
449+
450+ coverage-clean :
451+ @echo " Coverage support not enabled. Reconfigure with --enable-coverage"
452+
453+ coverage-reset coverage-check coverage-html coverage-xml coverage-summary :
454+ @echo " Coverage support not enabled. Reconfigure with --enable-coverage"
455+
456+ endif
457+
458+ clean-local : coverage-clean
459+
460+ # Coverage targets must not run in parallel due to race conditions in .gcda file writes
461+ .NOTPARALLEL : coverage-reset coverage-check coverage-html coverage-xml coverage-summary
462+
463+ .PHONY : coverity sync generate-rust-bindings generate-signals.c generate-mount_flags.c clang-format shellcheck coverage-clean coverage-reset coverage-check coverage-html coverage-xml coverage-summary
0 commit comments