How to create gcov files for a project in a different dir?
You have the commands, so put them in a script!
To run a bunch of commands on different data, put the changing data in a variable.
To run gcov
and mv
on all the files, there are several possible methods, including:
- Run
gcov
on all files, then move them. - Run
gcov
on one file, then move its output. - Run
gconv
on the files in a directory, then move them.
The first approach doesn't work because gcov
needs to be executed in the directory containing the source files. The third directory-based approach is in fact the most complicated of the three: the simplest method would be to run gcov
on one file at a time.
In bash, you can enumerate all the C files in a directory and its subdirectories recursively with the wildcard pattern **/*.c
. The **
wildcard needs to be enabled with the globstar
option. To iterate over the files, use a for loop
.
To change into a directory just to run one command, run cd
and that command in a subshell: (cd … && gcov …)
.
You need one more type of shell construct: a bit of manipulation of file names to extract the directory part. The parameter expansion construct ${x%/*}
expands to the value of the variable x
with the shortest suffix matching the pattern /*
removed. In other words, that's the directory part of the file name stored in x
. This wouldn't work if x
consisted only of a file name with no directory part (i.e. foo
as opposed to bar/foo
); it so happens that there's no .c
file at the root of the OpenSSL source tree, but a simple way to make sure the file name starts with ./
, which designates the current directory.
Invoke this script at the root of the OpenSSL source tree, after running ./config
with your desired options.
#!/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
To avoid having to move the .gcov
files, an alternative approach would be to create a forest of symbolic links to the compilation directory, and run gcov
in the gcovdata
directory. With GNU coreutils (i.e. on non-embedded Linux or Cygwin), you can do that with cp -al
.
cp -al openssl-1.0.0 gcovdata
cd gcovdata
for x in ./**/*.c; do
(cd "${x%/*}" && gcov "${x##*/}")
done