別のディレクトリにあるプロジェクトの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)

しかし、このアプローチには2つの大きな問題があります。

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最初の方法は、ソースファイルを含むディレクトリで実行する必要があるため機能しません。 3番目のディレクトリベースの方法は、実際には3つのうち最も複雑です。最も簡単な方法は、gcov一度に1つのファイルを実行します。

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別のアプローチは、コンパイルディレクトリを指すシンボリックリンクフォレストを作成し、そのディレクトリgcovgcovdata実行することです。 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

関連情報