コードカバレッジデータを分析したいです。 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
/*
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