Woo*_*low 5 c gcc unit-testing gcov
我正在构建一个动态链接库,并正在设置一个简单的测试套件。我想使用 gcov 生成静态代码分析覆盖率报告。
我的库是一个包含函数实现的 C 文件和一个包含函数原型的头文件。我的测试套件只是一个应用程序,它以各种方式调用函数并确认输出的有效性。
-fprofile-arcs我正在使用和标志编译库和测试套件-ftest-coverage,如GNU GCOV 指南中所述。我还包括-O0禁用编译器优化的标志和-g启用调试符号的标志。从测试套件生成的可执行文件动态链接到库。
所有文件都干净地编译且没有警告,但它无法将测试套件链接到库 - 引用“隐藏符号__gcov_merge_add”。如果我在没有-fprofile-arcs和-ftest-coverage标志的情况下进行编译,则链接成功并且我能够运行测试套件可执行文件。
因此,在阅读 GNU GCOV 指南后,我还有一些问题仍未解决。
这是我的inc/mylib.h文件:
#ifndef __MYLIB_H__
#define __MYLIB_H__
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
int
foo (int a);
int
bar (int a);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __MYLIB_H__ */
Run Code Online (Sandbox Code Playgroud)
这是我的src/mylib.c文件:
#include <stdio.h>
#include "mylib.h"
int foo(int a) {
if (a > 5) {
return 5;
}
return a;
}
int bar(int a) {
if (a < 0) {
return 0;
}
return a;
}
Run Code Online (Sandbox Code Playgroud)
这是我的test/unittests.c文件:
#include <stdio.h>
#include "mylib.h"
void run_foo_tests() {
int inputs[] = {3, 6};
int expected_results[] = {3, 5};
int i, actual_result;
for ( i = 0; i < sizeof(inputs) / sizeof(int); i++ ) {
actual_result = foo(inputs[i]);
if (actual_result == expected_results[i]) {
printf("Test %d passed!\n", i + 1);
} else {
printf("Test %d failed!\n", i + 1);
printf(" Expected result: %d\n", expected_results[i]);
printf(" Actual result: %d\n", actual_result);
}
}
}
void run_bar_tests() {
int inputs[] = {3, -1};
int expected_results[] = {3, 0};
int i, actual_result;
for ( i = 0; i < sizeof(inputs) / sizeof(int); i++ ) {
actual_result = bar(inputs[i]);
if (actual_result == expected_results[i]) {
printf("Test %d passed!\n", i + 1);
} else {
printf("Test %d failed!\n", i + 1);
printf(" Expected result: %d\n", expected_results[i]);
printf(" Actual result: %d\n", actual_result);
}
}
}
int main(int argc, char *argv[]) {
run_foo_tests();
run_bar_tests();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这是我的Makefile:
CC=gcc
CFLAGS=-Wall -std=c89 -g -O0 -Iinc -fprofile-arcs -ftest-coverage
all: clean build run_tests
build:
$(CC) $(CFLAGS) -fPIC -c src/*.c -o lib/mylib.o
$(CC) -shared lib/mylib.o -o lib/libmylib.so
$(CC) $(CFLAGS) test/*.c -o bin/unittests -Llib -lmylib
run_tests:
LD_LIBRARY_PATH=lib bin/unittests
gcov src/*.c
clean:
rm -f *.gcda *.gcno *.gcov
rm -rf bin lib ; mkdir bin lib
Run Code Online (Sandbox Code Playgroud)
当我运行时make,我会看到以下输出:
rm -f *.gcda *.gcno *.gcov
rm -rf bin lib ; mkdir bin lib
gcc -Wall -std=c89 -g -O0 -Iinc -fprofile-arcs -ftest-coverage -fPIC -c src/*.c -o lib/mylib.o
gcc -shared lib/mylib.o -o lib/libmylib.so
gcc -Wall -std=c89 -g -O0 -Iinc -fprofile-arcs -ftest-coverage test/*.c -o bin/unittests -Llib -lmylib
/usr/bin/ld: bin/unittests: hidden symbol `__gcov_merge_add' in /usr/lib/gcc/x86_64-redhat-linux/4.8.5/libgcov.a(_gcov_merge_add.o) is referenced by DSO
/usr/bin/ld: final link failed: Bad value
collect2: error: ld returned 1 exit status
make: *** [build] Error 1
Run Code Online (Sandbox Code Playgroud)
您需要-lgcov为链接器提供命令行参数(通常-ftest-coverage意味着-lgcov,但您有一个单独的链接步骤,其中-ftest-coverage不作为命令行参数给出)。或者,您可以只使用--coverage命令行参数,这也是-fprofile-arcsand的快捷方式-ftest-coverage,如下所述:http ://www.univ-orleans.fr/sciences/info/ressources/webada/doc/gnat/gcc_3.html :
--覆盖范围
此选项用于编译和链接用于覆盖率分析的代码。该选项是“-fprofile-arcs”、“-ftest-coverage”(编译时)和“-lgcov”(链接时)的同义词。有关更多详细信息,请参阅这些选项的文档。
顺便说一句,在同一地方,还解释了您不必使用这些选项编译所有文件,这有望回答您的问题 2。
| 归档时间: |
|
| 查看次数: |
2916 次 |
| 最近记录: |