如何為不同目錄中的項目創建 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)我必須手動移動文件。
我該怎麼做?你能幫我嗎?
更新:
謝謝 Gilles,它幫了我很多,但我仍然在最後一部分掙扎。我從 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'
Upd2:從 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
你有命令,所以把它們放在一個腳本中!
要對不同的數據執行一堆命令,請將變化的數據放入一個變數中。
要在所有文件上執行
gcov
和mv
處理,有幾種可能的方法,包括:
- 在所有文件上執行
gcov
,然後移動它們。- 在一個文件上執行
gcov
,然後移動其輸出。gconv
對目錄中的文件執行,然後移動它們。第一種方法不起作用,因為
gcov
需要在包含源文件的目錄中執行。第三種基於目錄的方法實際上是三種方法中最複雜的:最簡單的方法是一次執行gcov
一個文件。在 bash 中,您可以使用萬用字元模式 遞歸地列舉目錄及其子目錄中的所有 C 文件
**/*.c
。**
需要使用選項globstar
啟用萬用字元。要遍歷文件,請使用for loop
.要更改為僅執行一個命令的目錄,請在子shell
cd
中執行該命令:。(cd … && gcov …)
您需要另一種類型的 shell 構造:對文件名進行一些操作以提取目錄部分。參數擴展構造擴展為具有與已刪除模式匹配的最短後綴
${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