Gcov/Lcov — покрытие кода и отчет по нему
Gcov — свободно распространяемая утилита для исследования покрытия кода. Gcov генерирует точное количество исполнений для каждого оператора в программе и позволяет добавить аннотации к исходному коду. Gcov поставляется как стандартная утилита в составе пакета GCC.
При создании Makefile для проекта (String+) в школе 21 я все никак не понимал, как мне сделать это самое покрытие и сделать по нему отчет с помощью lcov.
Давайте разберем как я в итоге решил этот вопрос
SRC_C_FILES := $(shell find $(SRC_DIR) -name "s21_*.c")
TEST_C_FILES := $(shell find $(TEST_DIR) -name "test_*.c")
OBJS_TEST_FILES := $(addprefix $(TEST_OBJ_DIR)/, $(notdir $(TEST_C_FILES:.c=.o)))
SRC_C_FILES — поиск в папке src всех си файлов которые начинаются с s21_
OBJS_C_FILES — преобразование си файлов в объектные, и их запись в папку objs
По такой же аналогии я сделал с тестовыми файлами
Затем основная часть gcov_report цель моего мейк файла
gcov_report: s21_string.a
gcc $(GCC_FLAGS) --coverage main.c $(TEST_C_FILES) $(SRC_C_FILES) s21_string.a -L. s21_string.a $(TEST_FLAGS) -o $(BUILD_PATH)$(EXE)
$(BUILD_PATH)$(EXE)
lcov -t "Report" -c -d $(BUILD_PATH) --output-file $(BUILD_PATH)coverage.info
genhtml $(BUILD_PATH)coverage.info --output-directory $(BUILD_PATH)report/
open $(BUILD_PATH)report/index.html
Gcov report с целью нашей статичной библиотеки s21_string.a
Затем мы компилируем все наши си файлы и статичную библиотеку. В main.c находиться запуск юнит тестов для проверки нашей библиотеки, он является главным тестовым файлом. С помощью флага coverage мы как бы говорим компилятору сделать отчет по тому что мы будем в дальше ему передавать. Флаг -L указывает на то что наша статичная библиотека находиться в этой же папки где и make. -o $(build_path)$(exe) указывает выходной файл и папку в которой он будет создаваться.
Затем запускаем скомпилированное исполняемое тестовое приложение, что необходимо для генерации файлов данных покрытия (
.gcda
и.gcno
).lcov — инструмент для сбора данных о покрытии. -t «Report» заголовок для отчета покрытия. -с сбор данных о покрытии. -d $(build_path) — там где искать те самые файлы .gcda и .gcno. --output-file $(BUILD_PATH)coverage.info — имя выходного файла с собранными данными покрытия.
gentml — инструмент для создания html файла с данными о покрытии
Открытие готового файла
Таким образом выглядит отчет о покрытии
Вот так выглядит мой мейк целиком
GCC_FLAGS = -Wall -Werror -Wextra -std=c11
SANITAIZER = -g -fsanitize=address
TEST_FLAGS = -lcheck -lm -lpthread
GCOV_FLAGS = -fprofile-arcs -ftest-coverage
EXE=test.out
# Папки поиска
SRC_DIR = .
TEST_DIR = ./test
OBJ_DIR = ./objs
TEST_OBJ_DIR = ./test/objs
BUILD_PATH=./
SRC_C_FILES := $(shell find $(SRC_DIR) -name "s21_*.c")
OBJS_C_FILES := $(addprefix $(OBJ_DIR)/, $(notdir $(SRC_C_FILES:.c=.o)))
TEST_C_FILES := $(shell find $(TEST_DIR) -name "test_*.c")
OBJS_TEST_FILES := $(addprefix $(TEST_OBJ_DIR)/, $(notdir $(TEST_C_FILES:.c=.o)))
all: s21_string.a test gcov_report
rebuild: clean all
test: $(OBJS_TEST_FILES) s21_string.a main.o
gcc $(TEST_FLAGS) $(OBJS_TEST_FILES) $(OBJS_C_FILES) main.o
./a.out
s21_string.a: $(OBJS_C_FILES)
ar rcs s21_string.a $(OBJS_C_FILES)
ranlib s21_string.a
main.o: main.c
gcc -c $(GCC_FLAGS) -o $@ $<
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c | $(OBJ_DIR)
gcc $(GCC_FLAGS) -c $< -o $@
$(TEST_OBJ_DIR)/%.o: $(TEST_DIR)/%.c | $(TEST_OBJ_DIR)
gcc $(GCC_FLAGS) -c $< -o $@
$(OBJ_DIR):
mkdir -p $(OBJ_DIR)
$(TEST_OBJ_DIR):
mkdir -p $(TEST_OBJ_DIR)
gcov_report: s21_string.a
gcc $(GCC_FLAGS) --coverage main.c $(TEST_C_FILES) $(SRC_C_FILES) s21_string.a -L. s21_string.a $(TEST_FLAGS) -o $(BUILD_PATH)$(EXE)
$(BUILD_PATH)$(EXE)
lcov -t "Report" -c -d $(BUILD_PATH) --output-file $(BUILD_PATH)coverage.info
genhtml $(BUILD_PATH)coverage.info --output-directory $(BUILD_PATH)report/
open $(BUILD_PATH)report/index.html
clean:
rm -rf *.a *.out *.info
rm -rf $(OBJ_DIR)/*.o
rm -rf $(TEST_OBJ_DIR)/*.o
rm -rf $(OBJ_DIR)
rm -rf $(TEST_OBJ_DIR)
rm -rf *.o
rm -rf *.gcno *.gcov *.gcda
rm -rf report/
Эта статья будет полезна тем, кто столкнулся с проблемой создания отчета о покрытии с помощью gcov и lcov.