gcov cannot open graph file - gcc

I'm getting the following error when trying to run gcov as part of my Travis CI build:
$ gcov src/bgrep.c
bgrep.gcno:cannot open graph file
My .travis.yml:
language: c
compiler: gcc
sudo: false
before_script:
- uname -a
- printenv
- gcov --version
script:
- scons coverage=1
- ls -l src/
- test/run_test.py
- ls -l src/
- gcov src/bgrep.c
- ls -l src/
- ls -l
after_success:
- bash <(curl -s https://codecov.io/bash)
I can run the exact sequence of commands (scons, test/run_test.py, gcov src/bgrep.c) on my Fedora machine, and gcov produces grep.gcov as expected.
Travis is using gcov (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3. You can see an example build log here.
What am I (or Travis) doing wrong?

I had the same problem with gcov and travis. It seems that gcov indeed requires that the *.gcda and *.gcno files must be in the same directory as the *.c files. And additionally the -o option must be given which points then to the same directory...
So, I have the source files in folder src/ and the binaries in build/coverage/. First, I tried with 'gcov -o build/coverage/ src/*.c' which did not work. Second attempt was with copying the *.gc* files to src/ and executing 'gcov src/*.c' which also did not work. It finally worked with 'gcov -o src/ src/*.c'.

Related

How to extract all file in a .tar.gz to specific folder with cmake add_custom_target?

To decrease library size, used cmake -E tar "zcvf" "lib.tar.gz" out.lib in cmake to automatically create .tar.gz then lib.tar.gz is moved to folder f, ie. f/lib.tar.gz.
However, to use this library in another project, it's needed to extract to specific folder. The command without cmake is clear: tar -xzf f/lib.tar.gz -C target-folder.
The problem is that, in cmake, how to combine cmake -E tar "xzf" f/lib.tar.gz with -C option? Commands such as cmake -E tar "xzf" f/lib.tar.gz -C f/ will result error.
Ideal script would be sth. like
add_custom_target(PrepareLib
COMMAND ${CMAKE_COMMAND} -E tar "xzf" command....
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} ## note, this line must not be modified
)
Tools version: Visual Studio 2017, Windows 10 and CMake 3.17.1.

Download and move file only if it does not exist on destination directory, otherwise do nothing

I am trying to install an executable command (terraform) by downloading the zip file, then extract it to the ~/bin directory using a Makefile.
I would like to do this only if the terraform file is not already there.
According to the GNU Make docs I think I should use an "order-only prerequisite" with a pipe | (https://www.gnu.org/software/make/manual/make.html#Prerequisite-Types) although I don't completely understand that documentation.
I've written the following target rule with the purpose of running it as make install-tf, when the file ~/bin/terraform being already there, then doing nothing and returning. However this does not work as expected and I keep seeing the body of that target rule being executed no matter the file is already there.
What's wrong with the following target?
How could I install terraform only if the command is not already there using a Makefile?
This is the target:
TERRAFORM_VERSION=0.11.11
install-tf: | ~/bin/terraform
echo "Installing terraform version ${TERRAFORM_VERSION}"
mkdir -p ~/tmp/
wget https://releases.hashicorp.com/terraform/${TERRAFORM_VERSION}/terraform_${TERRAFORM_VERSION}_linux_amd64.zip -P ~/tmp/
mkdir -p ~/bin/
unzip ~/tmp/terraform_${TERRAFORM_VERSION}_linux_amd64.zip -d ~/bin/
echo "Done installing terraform version ${TERRAFORM_VERSION}"
PATH=~/bin/:$$PATH terraform --version
What's wrong with the following target?
The target is install-tf. make install-tf will always run the recipe to make this
target if no such file as install-tf exists. The recipe never creates
that file. Therefore the recipe will always be run.
You require a recipe to make the file $(HOME)/bin/terraform if and only if it
does not exist. To a first approximation, this will do it:
Makefile (1)
TERRAFORM_VERSION=0.11.11
$(HOME)/bin/terraform:
echo "Installing terraform version ${TERRAFORM_VERSION}"
mkdir -p $(HOME)/tmp/
wget https://releases.hashicorp.com/terraform/${TERRAFORM_VERSION}/terraform_${TERRAFORM_VERSION}_linux_amd64.zip -P $(HOME)/tmp/
mkdir -p $(HOME)/bin/
unzip ~/tmp/terraform_${TERRAFORM_VERSION}_linux_amd64.zip -d $(HOME)/bin/
echo "Done installing terraform version ${TERRAFORM_VERSION}"
PATH=$(HOME)/bin/:$$PATH terraform --version
which runs first time like:
$ make
echo "Installing terraform version 0.11.11"
Installing terraform version 0.11.11
mkdir -p /home/imk/tmp/
wget https://releases.hashicorp.com/terraform/0.11.11/terraform_0.11.11_linux_amd64.zip -P /home/imk/tmp/
--2019-01-29 11:09:11-- https://releases.hashicorp.com/terraform/0.11.11/terraform_0.11.11_linux_amd64.zip
Resolving releases.hashicorp.com (releases.hashicorp.com)... 151.101.17.183, 2a04:4e42:4::439
Connecting to releases.hashicorp.com (releases.hashicorp.com)|151.101.17.183|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 20971661 (20M) [application/zip]
Saving to: ‘/home/imk/tmp/terraform_0.11.11_linux_amd64.zip’
terraform_0.11.11_l 100%[===================>] 20.00M 8.86MB/s in 2.3s
2019-01-29 11:09:14 (8.86 MB/s) - ‘/home/imk/tmp/terraform_0.11.11_linux_amd64.zip’ saved [20971661/20971661]
mkdir -p /home/imk/bin/
unzip ~/tmp/terraform_0.11.11_linux_amd64.zip -d /home/imk/bin/
Archive: /home/imk/tmp/terraform_0.11.11_linux_amd64.zip
inflating: /home/imk/bin/terraform
echo "Done installing terraform version 0.11.11"
Done installing terraform version 0.11.11
PATH=/home/imk/bin/:$PATH terraform --version
Terraform v0.11.11
and second time like:
$ make
make: '/home/imk/bin/terraform' is up to date.
And with a little improvement:
Makefile (2)
TERRAFORM_VERSION := 0.11.11
.PHONY: all clean
all: $(HOME)/bin/terraform
$(HOME)/bin/terraform: | $(HOME)/tmp/ $(HOME)/bin/
echo "Installing terraform version ${TERRAFORM_VERSION}"
wget https://releases.hashicorp.com/terraform/${TERRAFORM_VERSION}/terraform_${TERRAFORM_VERSION}_linux_amd64.zip -P $(HOME)/tmp/
unzip ~/tmp/terraform_${TERRAFORM_VERSION}_linux_amd64.zip -d $(HOME)/bin/
echo "Done installing terraform version ${TERRAFORM_VERSION}"
PATH=$(HOME)/bin/:$$PATH terraform --version
$(HOME)/tmp/ $(HOME)/bin/:
mkdir -p $#
clean:
$(RM) $(HOME)/bin/terraform
which runs like:
$ make clean
rm -f /home/imk/bin/terraform
$ make
echo "Installing terraform version 0.11.11"
Installing terraform version 0.11.11
wget https://releases.hashicorp.com/terraform/0.11.11/terraform_0.11.11_linux_amd64.zip -P /home/imk/tmp/
--2019-01-29 11:38:32-- https://releases.hashicorp.com/terraform/0.11.11/terraform_0.11.11_linux_amd64.zip
Resolving releases.hashicorp.com (releases.hashicorp.com)... 151.101.17.183, 2a04:4e42:4::439
Connecting to releases.hashicorp.com (releases.hashicorp.com)|151.101.17.183|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 20971661 (20M) [application/zip]
Saving to: ‘/home/imk/tmp/terraform_0.11.11_linux_amd64.zip.1’
terraform_0.11.11_l 100%[===================>] 20.00M 8.88MB/s in 2.3s
2019-01-29 11:38:34 (8.88 MB/s) - ‘/home/imk/tmp/terraform_0.11.11_linux_amd64.zip.1’ saved [20971661/20971661]
unzip ~/tmp/terraform_0.11.11_linux_amd64.zip -d /home/imk/bin/
Archive: /home/imk/tmp/terraform_0.11.11_linux_amd64.zip
inflating: /home/imk/bin/terraform
echo "Done installing terraform version 0.11.11"
Done installing terraform version 0.11.11
PATH=/home/imk/bin/:$PATH terraform --version
Terraform v0.11.11
$ make
make: Nothing to be done for 'all'.
Note the use of order-only prerequisites in:
$(HOME)/bin/terraform: | $(HOME)/tmp/ $(HOME)/bin/
That says: Before considering whether the target $(HOME)/bin/terraform is out of date, make $(HOME)/tmp/ and $(HOME)/bin.
Then consider whether $(HOME)/bin/terraform is out of date but do not count $(HOME)/tmp/ or $(HOME)/bin as prerequisites.
See also 4.6 Phony Targets

How do I properly invoke MSYS2 Bash commands using CMake execute_process()?

Problem Description
I am having trouble setting up a CMake external_process() command that executes a MSYS2 bash command. When I am in the MSYS2 shell if I run the command $ bash -v ./bootstrap.sh the command works correctly. But if I run the CMake script in the MSYS2 shell using $ cmake -P Run_bash_command.cmake the command errors out part way through the process. An important piece of information I found in the CMake Documentation makes me think that I am not invoking bash correctly or missing an environmental variable:
CMake executes the child process using operating system APIs directly. All arguments are passed VERBATIM to the child process. No intermediate shell is used, so shell operators such as > are treated as normal arguments.
I would like to be able to do this command using CMake if possible as this problem is part of a much larger CMake superbuild project. If there is another approach to solving the problem I am open to suggestions as long as I can include it into the automation of the superbuild project. Any help will be appreciated.
Run_bash_command.cmake contents:
SET( ENV{MSYSTEM} MINGW64 )
SET( DIR_CONTAINING_BOOTSTRAP_SH C:/bash_test )
SET( BASH_COMMAND_TO_RUN bash -v ./bootstrap.sh )
EXECUTE_PROCESS( COMMAND ${BASH_COMMAND_TO_RUN}
WORKING_DIRECTORY ${DIR_CONTAINING_BOOTSTRAP_SH} RESULT_VARIABLE command_result )
IF( NOT "${command_result}" STREQUAL "0" )
MESSAGE( FATAL_ERROR "Error: command_result='${command_result}'" )
ENDIF()
Environment Setup
I followed the directions to setup MSYS2 64bit and added the mingw-w64 toolchain as well as cmake using the command pacman -S base-devel git mingw-w64-x86_64-cmake mingw-w64-x86_64-toolchain
To run the commands I use the MinGW-w64 Win64 Shell that is installed with MSYS2
The file bootstrap.sh comes from the libusb github repository and the folder c:/bash_test contains a clone of the master branch
Output
$ bash -v ./bootstrap.sh output:
$ bash -v ./bootstrap.sh
#!/bin/sh
if ! test -d m4 ; then
mkdir m4
fi
autoreconf -ivf || exit 1
autoreconf: Entering directory `.'
autoreconf: configure.ac: not using Gettext
autoreconf: running: aclocal --force -I m4
autoreconf: configure.ac: tracing
autoreconf: running: libtoolize --copy --force
libtoolize: putting auxiliary files in '.'.
libtoolize: copying file './ltmain.sh''
...<clipped output due to length>...
configure.ac:29: installing './install-sh'
configure.ac:29: installing './missing'
examples/Makefile.am: installing './depcomp'
autoreconf: Leaving directory `.'
$ cmake -P Run_bash_command.cmake output:
$ cmake -P Run_bash_command.cmake
#!/bin/sh
if ! test -d m4 ; then
mkdir m4
fi
autoreconf -ivf || exit 1
autoreconf: Entering directory `.'
autoreconf: configure.ac: not using Gettext
autoreconf: running: aclocal --force -I m4
aclocal-1.15: error: aclocal: file '/msys64/usr/share/aclocal/xsize.m4' does not exist
autoreconf: aclocal failed with exit status: 1
CMake Error at Run_bash_command.cmake:10 (MESSAGE):
Error: command_result='1'
Things I have tried:
Substituting bash -l -c but this causes the shell to default to the home directory and then it is unable to find the file bootstrap.sh
Verified the correct version of bash is found by inspecting my environmental PATH varaiable
Verified MSYS2 and its packages are up to date
Using sh instead of bash
Calling autoreconf -ivf directly, but the same issue occurs
Using Unix style paths instead of Windows style
I was able to fix the issue using the code below.
Run_bash_command.cmake contents:
SET( DIR_CONTAINING_BOOTSTRAP_SH /C/bash_test )
SET( BASH_COMMAND_TO_RUN bash -l -c "cd ${DIR_CONTAINING_BOOTSTRAP_SH} && sh ./bootstrap.sh" )
EXECUTE_PROCESS( COMMAND ${BASH_COMMAND_TO_RUN}
WORKING_DIRECTORY ${DIR_CONTAINING_BOOTSTRAP_SH} RESULT_VARIABLE command_result )
IF( NOT "${command_result}" STREQUAL "0" )
MESSAGE( FATAL_ERROR "Error: command_result='${command_result}'" )
ENDIF()
Important Notes:
Using bash -l causes the shell to default to the home directory, to get around this I added a change directory cd <path> command to get us back to the directory where we want to issue the bash command.
Using -c causes bash to read a command from a string. Since we want to issue two commands, one for change directory and one for running the shell script, we need to use && to chain the commands together as well as use "quotation marks" to make sure the entire command is read properly as a string.

Error installing flite on Mac OSX

I have downloaded the latest source distribution of flite, and went about the usual process of installing it.
$ ./configure
$ make
$ sudo make install
However, I run into a strange error when I try to install the library to my system.
$ sudo make install
Installing
mkdir -p /usr/local/bin
mkdir -p /usr/local/lib
mkdir -p /usr/local/include/flite
/usr/bin/install -c -m 644 include/*.h /usr/local/include/flite
/usr/bin/install -c -m 755 ../bin/flite_time /usr/local/bin
cp -pd ../build/i386-darwin13.1.0/lib/libflite_cmu_us_kal.a ../build/i386-darwin13.1.0/lib/libflite_cmu_time_awb.a ../build/i386-darwin13.1.0/lib/libflite_cmu_us_kal16.a ../build/i386-darwin13.1.0/lib/libflite_cmu_us_awb.a ../build/i386-darwin13.1.0/lib/libflite_cmu_us_rms.a ../build/i386-darwin13.1.0/lib/libflite_cmu_us_slt.a ../build/i386-darwin13.1.0/lib/libflite_usenglish.a ../build/i386-darwin13.1.0/lib/libflite_cmulex.a ../build/i386-darwin13.1.0/lib/libflite.a /usr/local/lib
cp: illegal option -- d
usage: cp [-R [-H | -L | -P]] [-fi | -n] [-apvX] source_file target_file
cp [-R [-H | -L | -P]] [-fi | -n] [-apvX] source_file ... target_directory
make[1]: *** [install] Error 64
make: *** [install] Error 2
How can I fix this?
There a few subtle differences between the BSD cp that Mac uses and the GNU cp of most linux distributions.
Consider the following snippet of man cp from a linux box:
-d same as --no-dereference --preserve=links
-P, --no-dereference
never follow symbolic links in SOURCE
--preserve[=ATTR_LIST]
preserve the specified attributes (default: mode,ownership,timestamps), if possible additional attributes: context,
links, xattr, all
So basically what it's trying to do is "copy the following paths, and if they're links, just copy the link, not the underlying file."
The p option exists under Mac and is equivalent to the linux behavior. The d option, however, is absent.
I've tried to figure out a way to mimic the behavior of "copy links, not targets" with the Mac cp, and as far as I can tell, there's no pleasant way to do it.
There is, fortunately, a gross work around. From man cp under Mac:
Symbolic links are always followed unless the -R flag is set, in which case symbolic links are not followed, by default.
In other words, since we know we're only copying files, you can simply replace the d flag with the R flag. The behavior is technically different (very different), but it won't matter in this specific case. You'll need to find the cp flags used in the Makefile (hopefully in a CP variable at the top of the file) and simply change them.
If you're sure the cp is the last thing to be executed in the Makefile, you could also just copy and paste it instead of changing the Makefile.
I was able to solve this problem using Corbin's suggestion. After searching the Makefile, I was able to spot where the error originated.
I am using flite-2.0.0-release and the Makefile was located in the following directory:
/flite-2.0.0-release/main/.
The last couple lines has the following:
# The libraries: static and shared (if built)
cp -pd $(flite_LIBS_deps) $(INSTALLLIBDIR)
ifdef SHFLAGS
cp -pd $(SHAREDLIBS) $(VERSIONSHAREDLIBS) $(INSTALLLIBDIR)
endif
I've changed the to the following:
# The libraries: static and shared (if built)
cp -pR $(flite_LIBS_deps) $(INSTALLLIBDIR)
ifdef SHFLAGS
cp -pR $(SHAREDLIBS) $(VERSIONSHAREDLIBS) $(INSTALLLIBDIR)
endif
By replacing the cp -pd to cp -pR, I was able to successfully install flite. I hope this advice helps.
I ran into this same issue recently, TJ Rana put me in the right direction but here's the whole process of installing flite on MacOS (original article here):
Flitevox or Flitelib is an open source small run time speech engine. Pass it text and create an audio file with a robot saying it. Really cool and useful for some projects.
Flitelib is not a native filter available in FFmpeg build nor inside the source. Although the documentation states that –enable-libflite is required for config, installing flitelib is required before installing FFmpeg. If you do try to enable the filter you’ll get this error:
$ ./configure --disable-indevs --enable-libflite --enable-cross-compile
ERROR: libflite not found
If you think configure made a mistake, make sure you are using the latest
version from Git. If the latest version fails, report the problem to the
ffmpeg-user#ffmpeg.org mailing list or IRC #ffmpeg on irc.freenode.net.
Include the log file "ffbuild/config.log" produced by configure as this will help
solve the problem.
In this post, I’ll show you how to install flite and get it working with FFmpeg
First download flitevox from source and install:
$ git clone https://github.com/festvox/flite.git
$ cd flite/
$ ./configure
$ make
$ sudo make install
If you’re running linux this installation works perfectly. If you’re running MacOS, you’ll get this error:
$ sudo make install
Password:
Installing
mkdir -p /usr/local/bin
mkdir -p /usr/local/lib
mkdir -p /usr/local/include/flite
/usr/bin/install -c -m 644 include/*.h /usr/local/include/flite
/usr/bin/install -c -m 755 ../bin/flite_time /usr/local/bin
cp -pd ../build/x86_64-darwin19.0.0/lib/libflite_cmu_us_kal.a ../build/x86_64-darwin19.0.0/lib/libflite_cmu_time_awb.a ../build/x86_64-darwin19.0.0/lib/libflite_cmu_us_kal16.a ../build/x86_64-darwin19.0.0/lib/libflite_cmu_us_awb.a ../build/x86_64-darwin19.0.0/lib/libflite_cmu_us_rms.a ../build/x86_64-darwin19.0.0/lib/libflite_cmu_us_slt.a ../build/x86_64-darwin19.0.0/lib/libflite_usenglish.a ../build/x86_64-darwin19.0.0/lib/libflite_cmu_indic_lang.a ../build/x86_64-darwin19.0.0/lib/libflite_cmu_grapheme_lang.a ../build/x86_64-darwin19.0.0/lib/libflite_cmulex.a ../build/x86_64-darwin19.0.0/lib/libflite_cmu_indic_lex.a ../build/x86_64-darwin19.0.0/lib/libflite_cmu_grapheme_lex.a ../build/x86_64-darwin19.0.0/lib/libflite.a /usr/local/lib
cp: illegal option -- d
usage: cp [-R [-H | -L | -P]] [-fi | -n] [-apvXc] source_file target_file
cp [-R [-H | -L | -P]] [-fi | -n] [-apvXc] source_file ... target_directory
make[1]: *** [install] Error 64
make: *** [install] Error 2
That’s because MacOS uses different “cp” variables then linux. I found this Stack Overflow answer with the solution: https://stackoverflow.com/a/29075638/525576 but here’s the steps to fix it.
In the folder “flite/main” you’ll need to edit the Makefile with the MacOS version of the command:
$ cd main/
$ vim Makefile
Replace the following (from TJ Rana):
# The libraries: static and shared (if built)
cp -pd $(flite_LIBS_deps) $(INSTALLLIBDIR)
ifdef SHFLAGS
cp -pd $(SHAREDLIBS) $(VERSIONSHAREDLIBS) $(INSTALLLIBDIR)
endif
to (-pd to -pR):
# The libraries: static and shared (if built)
cp -pR $(flite_LIBS_deps) $(INSTALLLIBDIR)
ifdef SHFLAGS
cp -pR $(SHAREDLIBS) $(VERSIONSHAREDLIBS) $(INSTALLLIBDIR)
endif
How we can try installing flite again:
$ sudo make install
flite should not show any errors and the installation should be complete.
Now back in ffmpeg source filter:
$ ./configure --enable-libflite --enable-cross-compile
$ make install
Installation will complete. To test if flite is working open a new terminal and type:
$ ffplay -f lavfi -i flite=text='Hello World!'
Hello world will speak!

Why does following makefile rebuilt target "build" everytime

I have the following code to untar all the files in a directory and move it to build directory. If I call make multiple times, it tries to execute "build" target everytime even if build directory already exists. Has anyone comes across this?
I found this question but it is not the same.
Makefile always running target
OS: Ubuntu 12.04
Program: GNU Make 3.81
build: mkBuildDir untar
chmod 700 build
.PHONY: mkBuildDir untar
mkBuildDir:
mkdir build
untar: *.tar.gz
for prefix in *.tar.gz; do \
tar xvf $$prefix --directory=build; \
done
clean:
rm -Rf build
This is pretty much the same as the question you've linked. You never create a file called mkBuildDir, so it's always out-of-date, so build is always out of date.
Your mkBuildDir target isn't doing anything useful (though I presume this is a cut-down makefile). If instead you did
# it'd be better to list the TARFILES explicitly, though this will probably work
TARFILES=`ls *.tar.gz`
all: build untar
build: $(TARFILES)
test -d build || mkdir build
chmod 700 build
for prefix in $(TARFILES); do \
tar xvf $$prefix --directory=build; \
done
clean:
rm -Rf build
that would probably accomplish what you're looking for.
Having too many phony targets in a Makefile is usually a makefile 'code smell'. They are rarely the best/idiomatic way of doing things.

Resources