다른 디렉터리에 있는 프로젝트에 대한 gcov 파일을 만드는 방법은 무엇입니까?

다른 디렉터리에 있는 프로젝트에 대한 gcov 파일을 만드는 방법은 무엇입니까?

코드 커버리지 데이터를 분석하고 싶습니다. 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/*xxfoobar/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

관련 정보