코드 커버리지 데이터를 분석하고 싶습니다. OpenSSL(및 기타 프로젝트)에서 gcov 파일을 생성하고 싶지만 프로젝트의 동일한 디렉터리에서만 생성할 수 있으며 현재 폴더의 파일에 대해서만 생성할 수 있습니다.
나는 그것들을 다른 디렉토리에 생성하고, 소스의 원래 디렉토리 구조를 유지하고, 전체 프로세스를 가능한 한 자동화하고 싶습니다.
원천:
~/mygcovproject/projects/openssl-1.0.0
산출:
~/mygcovproject/gcovdata/openssl-1.0.0
현재는 다음과 같은 방법으로만 파일을 만들 수 있습니다.
$ cd ~/mygcovproject/projects/openssl-1.0.0
$ make clean
$ export CC="gcc -fprofile-arcs -ftest-coverage"; ./config
$ make
$ make tests
$ cd test
$ gcov *.c
$ mv *.gcov ~/mygcovproject/gcovdata/openssl-1.0.0/test/
$ cd ..
$ cd apps
$ gcov *.c
$ mv *.gcov ~/mygcovproject/gcovdata/openssl-1.0.0/apps/
$ cd ..
$cd crypto
... (for all the folders)
그러나 이 접근 방식에는 두 가지 큰 문제가 있습니다.
1) 많은 폴더와 하위 폴더가 있습니다.
2) 파일을 수동으로 이동해야 합니다.
어떻게 해야 합니까? 도와주세요?
고쳐 쓰다:
Giles에게 감사드립니다. 많은 도움이 되었지만 여전히 마지막 부분을 이해하는 데 어려움을 겪고 있습니다. gcov에서 오류 메시지가 나타납니다.
$ cat dothemagic.sh
#!/bin/bash
shopt -s globstar
gcov_data_dir="../../gcovdata/${PWD##*/}"
mkdir -p "$gcov_data_dir"
#make
#make tests
for x in ./**/*.c; do
gcov "$gcov_data_dir/${x%/*}/$x"
done
exit
$ ./dothemagic.sh
../../gcovdata/openssl-1.0.0/./apps/./apps/app_rand.gcno:cannot open notes file
../../gcovdata/openssl-1.0.0/./apps/./apps/apps.gcno:cannot open notes file
../../gcovdata/openssl-1.0.0/./apps/./apps/asn1pars.gcno:cannot open notes file
../../gcovdata/openssl-1.0.0/./apps/./apps/ca.gcno:cannot open notes file
../../gcovdata/openssl-1.0.0/./apps/./apps/ciphers.gcno:cannot open notes file
../../gcovdata/openssl-1.0.0/./apps/./apps/cms.gcno:cannot open notes file
../../gcovdata/openssl-1.0.0/./apps/./apps/crl2p7.gcno:cannot open notes file
...
나도 이것을 시도했지만 작동하지 않고 오류가 발생합니다.:
for x in ./**/*.c; do
echo $x
gcov $x
done
$ ./run_tests.sh openssl-1.0.0
./apps/app_rand.c
File 'app_rand.c'
Lines executed:37.50% of 40
Creating 'app_rand.c.gcov'
Cannot open source file app_rand.c
./apps/apps.c
File 'apps.c'
Lines executed:33.76% of 939
Creating 'apps.c.gcov'
Cannot open source file apps.c
...
나는 명령을 시도했다:
$ gcov ./apps/app_rand.c
File 'app_rand.c'
Lines executed:37.50% of 40
Creating 'app_rand.c.gcov'
Cannot open source file app_rand.c
같은 폴더에 있는 파일에서만 gcov를 실행할 수 있는 것 같습니다. 이 문제를 어떻게 해결해야 합니까? 루프의 디렉터리로 CD를 넣은 다음 파일을 이동해야 합니까? 아니면 내가 뭔가 잘못하고 있는 걸까요?
폴더에서 -o 옵션을 사용해 보았지만 작동하지 않습니다.
$ pwd
/home/blackcat/gcov_project/projects/openssl-1.0.0/test
$ ls bftest.*
bftest.c bftest.c.gcov bftest.gcda bftest.gcno bftest.o
$ gcov -o ~/gcov_project/gcov/ bftest.c
/home/blackcat/gcov_project/gcov/bftest.gcno:cannot open notes file
$ gcov bftest.c
File 'bftest.c'
Lines executed:47.52% of 101
Creating 'bftest.c.gcov'
File '/usr/include/x86_64-linux-gnu/bits/stdio2.h'
Lines executed:100.00% of 1
Creating 'stdio2.h.gcov'
File '/usr/include/x86_64-linux-gnu/bits/string3.h'
Lines executed:100.00% of 2
Creating 'string3.h.gcov'
업데이트 2: Gilles 솔루션을 시작으로 작동하는 코드를 만들었습니다. 감사해요. 결국 나는 그것들을 모두 같은 디렉토리에 넣었지만, 그들의 경로에서 접두사를 만들었습니다.
### Generate and copy gcov files ###
cd "$TARGET_DIR"
mkdir -p "$OUTPUT_DIR"
CDIR=""
for x in **/*.c; do
if [ "$CDIR" != "$TARGET_DIR/${x%/*}" ]; then
CDIR="$TARGET_DIR/${x%/*}"
cd $CDIR
gcov -p *.c
SUBDIR="${x%/*}"
PREFIX="#${SUBDIR/\//\#}"
for f in *.gcov; do
if [[ $f == \#* ]] ;
then
cp $f "$OUTPUT_DIR/$f"
else
cp $f "$OUTPUT_DIR/$PREFIX#$f"
fi
done
fi
done
답변1
명령이 있으므로 스크립트에 넣으십시오!
다양한 데이터에 대해 여러 명령을 실행하려면 변경되는 데이터를바꾸다.
gcov
모든 파일을 실행하려면 mv
다음을 포함한 여러 가지 방법이 있습니다.
- 모든 파일을 실행
gcov
하고 이동합니다. - 파일에 대해 실행
gcov
한 다음 해당 출력을 이동합니다. gconv
디렉터리의 파일에 대해 실행한 다음 이동합니다.
gcov
첫 번째 방법 은 소스 파일이 포함된 디렉터리에서 실행되어야 하기 때문에 작동하지 않습니다 . 세 번째 디렉터리 기반 방법은 실제로 세 가지 중 가장 복잡합니다. 가장 간단한 방법은 gcov
한 번에 하나의 파일을 실행합니다.
Bash에서는 다음을 사용하여 디렉터리와 해당 하위 디렉터리의 모든 C 파일을 재귀적으로 열거할 수 있습니다.와일드카드 패턴 **/*.c
. **
다음 명령을 사용하여 와일드카드를 활성화해야 합니다.globstar
옵션. 파일을 반복하려면 다음을 사용하십시오.for loop
.
명령을 실행하기 위해 디렉토리로 변경하려면 cd
다음에서 명령을 실행하십시오.서브쉘: (cd … && gcov …)
.
또한 다른 유형의 쉘 구성이 필요합니다. 즉, 디렉토리 부분을 추출하기 위해 파일 이름을 조작하는 것입니다. 이것매개변수 확장구문은 제거된 패턴과 일치하는 가장 짧은 접미사가 있는 ${x%/*}
변수의 값 으로 확장됩니다. 즉, 이것이 에 저장되는 것입니다. OpenSSL 소스 트리의 루트에 파일이 없지만 디렉터리 부분 없이 파일 이름만 포함하면 작동하지 않습니다. 파일 이름이 현재 디렉터리를 지정하는 로 시작하는지 확인하는 쉬운 방법입니다.x
/*
x
x
foo
bar/foo
.c
./
./config
필수 옵션을 사용하여 실행한 후 OpenSSL 소스 트리의 루트에서 이 스크립트를 호출합니다.
#!/bin/bash
shopt -s globstar
gcov_data_dir="../../gcovdata/${PWD##*/}"
make
make tests
for x in ./**/*.c; do
mkdir -p "$gcov_data_dir/${x%/*}"
(cd "${x%/*}" && gcov "${x##*/}") &&
mv "$x.gcov" "$gcov_data_dir/${x%/*}"
done
파일 이동을 방지하기 위한 .gcov
또 다른 접근 방식은 컴파일 디렉터리를 가리키는 심볼릭 링크 포리스트를 만들고 gcov
해당 gcovdata
디렉터리에서 실행하는 것입니다. GNU coreutils(즉, 내장되지 않은 Linux 또는 Cygwin)를 사용하면 cp -al
.
cp -al openssl-1.0.0 gcovdata
cd gcovdata
for x in ./**/*.c; do
(cd "${x%/*}" && gcov "${x##*/}")
done
답변2
gcov를 실행한 후 다음을 수행하세요.
mv *.gcov sub-folder-name
mv *.gcda sub-folder-name
mv *.gcno sub-folder-name