GCOV - gcda file generated in different folder - c++

Folder structure
~/sandbox/dev
~/sandbox/test
I have main.cpp in dev directory. I compiled the code using --coverage flag to generate code coverage.
Now a.out and main.gcno files are generated.
Now I copy main.cpp, main.gcno and a.out to test directory
When I run the a.out from test directory, the main.gcda file is generated at the dev folder instead of current working directory.
It seems like the path is hardcoded in the binary/gcno.
What changes are required so that the gcda file will be generated in test directory ?

By default, the .gcda files are also stored in the same directory as the object file, but the GCC -fprofile-dir option may be used to store the .gcda files in a separate directory.
https://gcc.gnu.org/onlinedocs/gcc/Gcov-Data-Files.html
-fprofile-dir tag in GCOV utility

Kind of a late answer - but you can use environment variables GCOV_PREFIX and GCOV_PREFIX_STRIP to direct the .gcda files to some other path.
You do need to copy (or link) the .gcno files and .gcda files to the same directory in order to run gcov, though.

Related

MSBuild output directory

I'm trying to get absolute control over the output of MSBuild. If I run:
msbuild project.msbuild
or:
msbuild project.msbuild /p:configuration=Debug
I will get the folder:
Debug
If I run:
msbuild project.msbuild /p:configuration=Release
I will get the folder:
Release
The output directory structure I want is the following:
Win32\Debug
Win32\Release
x64\Debug
x64\Release
I first tried OutputPath but nothing happened. Then I tried the following:
<OutDir>$(Platform)\$(Configuration)\</OutDir>
Now I get the compiled binaries in the specified folder but for some reason the old directory structure is created to contain the object files. So if I run:
msbuild project.msbuild
What I end up with is:
Debug (contains object files)
Win32\Debug (contains binaries)
I want everything in the same folder, the one I specified, not the default MSBuild decides upon.
Object files are stored in 'Intermediate' directory.
By specifying OutDir - you specify location of binaries.
To specify location of .obj files you should additionally try specifying IntermediateOutputPath to the desired location of .obj files.
See reference, for example: https://blogs.msdn.microsoft.com/kirillosenkov/2015/04/04/using-a-common-intermediate-and-output-directory-for-your-solution/

How to pick source from build dir if available otherwise use source dir?

is there a way to force CMAKE pick sources form current build folder if file(s) is available otherwise take it from the source directory?
My project has following structure:
ROOT/lib/a.cpp
/BUILD
the BUILD folder is where I run cmake ... I've got an optional custom target which generates a source BUILD/lib/a.cpp file: cmake generate.
I'd like to build a library in ROOT/lib that automatically picks up the generated source file BUILD/lib/a.cpp in case it exists otherwise use ROOT/lib/a.cpp.
The library is generated with ROOT/lib/CMakeLists.txt in the following way:
add_library(test a.cpp)
(the custom rule is omitted).
you can just use the full path to generated file:
add_library(test ${CMAKE_CURRENT_BINARY_DIR}/a.cpp)
and if file doesn't exists, your custom command will be executed to generate it.
make sure that generated file produced by add_custom_command() and not by add_custom_target().

cmake: read and compile dynamically-generated list of cpp files

I have a custom tool that processes a given list of IDL files and produces a number of .cpp and .h files as output. I want to add those files to the list of things to compile in my CMakeLists, and also model the dependencies those files have on the IDL.
To keep things simple, I will state that any change to any of the IDL files should trigger a regeneration of all cpp/h.
I have a custom command that takes care of running the generator tool and listing all the IDL files as dependencies.
My issue is getting the subsequent list of cpp/h files into cmake at build-time. It is not possible to infer from the name of the IDL files what cpp files will be generated. My generator tool will, however, output the list of generated files to a text file.
So my question is: how do I instruct cmake to "read from this text file and add the contents as extra source and header files to be compiled", also bearing in mind that the said text file only exists during a certain point of the build?
CMake needs to be able to infer the names of all .cpp files participating in the build at configure time. It is not possible to add files afterwards without re-running CMake.
One possible approach would be to use a two-phase CMake build: Instead of building the generated source files directly from your main project, you create a separate CMake project for building just the generated sources.
Then in your main CMake project you add a custom target that runs after the code generation and invokes CMake to both configure and build the generated files project.
The disadvantage here is that the generated files no longer appear as part of the main project. Also some trickery is required if you don't want to rebuild the generated sources every time - custom targets are always considered out-of-date, so you might want to use a script here that only runs CMake on the subproject if the generated files changed.
This is a few years late but this works just fine:
#run whatever tool that generates the cpp files
execute_process(COMMAND "./your_tool.sh")
#read files from files.txt and make a cmake 'list' out of them
file(READ "files.txt" SOURCES)
#found this technique to build the cmake list here:
#http://public.kitware.com/pipermail/cmake/2007-May/014236.html
#maybe there is a better way...
STRING(REGEX REPLACE ";" "\\\\;" SOURCES "${SOURCES}")
STRING(REGEX REPLACE "\n" ";" SOURCES "${SOURCES}")
#at this point you have your source files inside ${SOURCES}
#build a static library...?
add_library(mylib STATIC ${SOURCES})
There is a function that build the list directly from file:
file(STRINGS <filename> <variable> [<options>...])
source: https://cmake.org/cmake/help/v3.11/command/file.html

CMake and Qt : directory for moc files / clean rules

I find CMake a little difficult to understand, and I currently have a problem with directories.
For the example, let's suppose that I have the following directory organisation :
project/
project/bin
project/obj
project/src
project/src/main.cpp
project/src/mainwindow.cpp
project/src/mainwindow.h
project/CMakeLists.txt
The project uses Qt 4.8 and CMake 2.8.8.
I want to do the following things :
At the beginning of all compilation, all previous temporary files are cleaned (.o and .moc)
All the .o and .moc are put in the obj directory
The executable is put in bin
What is the simplest CMakeLists.txt to do that ?
Thank you very much.
It is recommended to use out of source build where all the generated files are outside of the source folder. Is there any reason you are not doing that approach?

How to compile multiple files in ROOT

I wrote a C++ program (with a main.cpp, and various header and implementation files) that compiles fine under g++. Now I am trying to compile it in Cern's ROOT library, but I do not know how to, since the only way I know how to compile files in ROOT is by using .L main.cpp.
How can I include multiple files in ROOT?
The most reliable way to use ROOT (at least historically and currently) is to ignore the interpreter other than for the simplest explorations and explicitly compile your C++ programs against the ROOT libraries. For example, use
g++ MySource.cc `root-config --libs --cflags` -o foo
to compile an executable "foo" from a single source file. For more info on that helper script run "root-config --help".
Multi-file programs/libraries are nothing special provided that you supply the required args to point at the ROOT libraries and headers (and that the libs are available in LD_LIBRARY_PATH at runtime.) Standard C++ guides will explain that step if needed. You can safely put this into a makefile, too.
For my money this is both easier and more reliable than using the .L etc. commands in the CINT interpreter. Last time I tried, ACLiC was actually compiling against a temporary (and mangled) version of the specified source file, so any error messages from the compiler were pretty much useless!
I use CMake to compile my ROOT-based projects.
If you have a project directory proj/ and it contains src/ and bin/, you'll need 3 CMakeList.txt files, one in each directory.
A simple example CMakeList.txt in the main project directory:
cmake_minimum_required(VERSION 2.6)
project (SOME_PROJ_NAME)
add_subdirectory(src)
add_subdirectory(bin)
src/ directory is where you keep your .h and .cxx proj. library files. Example CMakeList.txt file:
# get all the *.cxx filenames, to compile them into a lib
file(GLOB SOME_PROJ_LIB_SRCS "${PROJECT_SOURCE_DIR}/src/*.cxx")
# include ROOT library and include files
include_directories(/path/to/root/dir/include/dir)
link_directories(/path/to/root/dir/lib/dir)
# and compile src into a library
add_library(Proj_lib_name ${SOME_PROJ_LIB_SRCS})
# here, list the ROOT libraries you require
target_link_libraries(Proj_lib_name dl Core Cint RIO Net Hist Graf Graf3d Gpad Tree Rint Postscript Matrix Physics MathCore Thread Gui pthread m)
bin/ directory is where you keep your app .cxx files and it has a CMakeList.txt file:
include_directories(${PROJECT_SOURCE_DIR}/src)
link_directories(${PROJECT_SOURCE_DIR}/src)
include_directories(/path/to/root/dir/include/dir)
link_directories(/path/to/root/dir/lib/dir)
add_executable(example_app.exe example_app.cxx)
target_link_libraries(example_app.exe Proj_lib_name dl Core Cint RIO Net Hist Graf Graf3d Gpad Tree Rint Postscript Matrix Physics MathCore Thread Gui pthread m)
Finally, to compile ROOT-based code with CMake, out of source, you create a "build" dir in your top level project dir, so that your dir structure looks like this:
proj/
bin/
build/
src/
Then
cd build
cmake ..
Your binaries will be located in build/bin/ directory
Hope this helps.
It appears that I would simply .L <filename> for each file I want, since .L tells ROOT to "load the contents of file in memory." Though now I am not too sure which order to load the files in, as they are giving me errors.