При сборке программы с включенными опциями для GCOV можно получить ошибку на этапе линковки следующего вида:
/usr/bin/ld: ./a.out: hidden symbol `__gcov_merge_add' in /usr/lib/gcc/i486-linux-gnu/4.1.3/libgcov.a(_gcov_merge_add.o) is referenced by DSO
/usr/bin/ld: final link failed: Nonrepresentable section on output
Скорее всего причина заключается в том, что к исполняемому модулю линкуются библиотеки, которые тоже были скомпилированы с опциями
-fprofile-arcs -ftest-coverage
.
Простой пример, иллюстрирующий проблему.
Даны два файла:
=== a.cpp
#include <stdio.h>
extern unsigned long myfunc ();
int main (int argc, char **argv)
{
unsigned long z = myfunc();
printf("%08x\n", z);
return 0;
}
=== b.cpp
#include <time.h>
unsigned long myfunc ()
{
return time(0);
}
Из файла
b.cpp
делаем статическую библиотеку
libmy.a
, а из файла
a.cpp
— исполняемый модуль
a.out
:
g++ -c -fprofile-arcs -ftest-coverage b.cpp
g++ -shared -o libmy.a ./b.o
g++ -c -fprofile-arcs -ftest-coverage a.cpp
g++ -o a.out a.o -L. -lmy
Получаем ошибку вида "
undefined reference to `__gcov_init'" — забыли подключить библиотеку libgcov.a.
Подключаем к сборке требуемую библиотеку как обычно:
g++ -c -fprofile-arcs -ftest-coverage b.cpp
g++ -shared -o libmy.a ./b.o
g++ -c -fprofile-arcs -ftest-coverage a.cpp
g++ -o a.out a.o -L. -lmy -lgcov
Вот здесь-то и получаем странную ошибку:
/usr/bin/ld: ./a.out: hidden symbol `__gcov_merge_add' in /usr/lib/gcc/i486-linux-gnu/4.1.3/libgcov.a(_gcov_merge_add.o) is referenced by DSO
/usr/bin/ld: final link failed: Nonrepresentable section on output
Исправить это просто. Нужно подключить библиотеку libgcov.a не только к сборке исполняемого модуля, но и к сборке статической библиотеки:
g++ -c -fprofile-arcs -ftest-coverage b.cpp
g++ -shared -o libmy.a ./b.o -lgcov
g++ -c -fprofile-arcs -ftest-coverage a.cpp
g++ -o a.out a.o -L. -lmy -lgcov
Вот и всё. Так нужно поступить с каждой библиотекой, исходный код которой скомпилирован с опциями
-fprofile-arcs -ftest-coverage
.