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
  1. Gcov report с целью нашей статичной библиотеки s21_string.a

  2. Затем мы компилируем все наши си файлы и статичную библиотеку. В main.c находиться запуск юнит тестов для проверки нашей библиотеки, он является главным тестовым файлом. С помощью флага coverage мы как бы говорим компилятору сделать отчет по тому что мы будем в дальше ему передавать. Флаг -L указывает на то что наша статичная библиотека находиться в этой же папки где и make. -o $(build_path)$(exe) указывает выходной файл и папку в которой он будет создаваться.

  3. Затем запускаем скомпилированное исполняемое тестовое приложение, что необходимо для генерации файлов данных покрытия (.gcda и .gcno).

  4. lcov — инструмент для сбора данных о покрытии. -t «Report» заголовок для отчета покрытия. -с сбор данных о покрытии. -d $(build_path) — там где искать те самые файлы .gcda и .gcno.  --output-file $(BUILD_PATH)coverage.info — имя выходного файла с собранными данными покрытия.

  5. gentml — инструмент для создания html файла с данными о покрытии

  6. Открытие готового файла

Таким образом выглядит отчет о покрытии

Таким образом выглядит отчет о покрытии

Вот так выглядит мой мейк целиком

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.

© Habrahabr.ru