Failed to use gdb for an executive file generated by cmake - c++

To do debug for C++ codes with cmake, I have a trick to add the following lines before the project (myProjectYY) line of the CMakeLists.txt file in the root directory of the source code.
set(CMAKE_BUILD_TYPE "Debug")
set(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g -ggdb")
set(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall")
So, after cmake and make, I have obtained the executable file mainYY, and I can simply run gdb mainYY to do the debug as I should be able to see the source codes of mainYY.cpp.
I have 2 separated projects that were already cmake and make by the others, namely a simple project (i.e. myProject1) and a complicated project (i.e. myProject2). For myProject1, the above trick works for me, i.e. after I added the above 3 lines and re-do the cmake and make again to obtain main1, I can see the source code of main1.cpp by simply executing l in gdb.
But for myProject2, I do same, i.e. I added the above 3 lines and re-do the cmake and make again to obtain main2, but in gdb there is no source code for main2.cpp. That is, gdb main2 firstly gave me Reading symbols from main2...(no debugging symbols found)...done. And then if I run l in gdb, I have No symbol table is loaded. Use the "file" command.
What are the most probable reasons for such differences between myProject1 and myProject2? How can I find out those probable reasons, and how can I do the fix such that I can debug for myProject2?
Thanks.

As you mentioned, your myProject2 is a complicated project. There could be SET( CMAKE_BUILD_TYPE Release ... FORCE ) somewhere. Check using fgrep -R "CMAKE_BUILD_TYPE" and even better, remove every definition of this everywhere.
Use cmake -DCMAKE_BUILD_TYPE=Debug instead.

Related

How to generate preprocess and assmeble code by cmake?

I am trying to get intermediate .i .s file by CMake when compiling .cpp file, but cmake default only output .o file. Is there any command to manipulate cmake to keep these intermediate file, thanks a lot!
If you are using gcc, try adding this line.
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -save-temps=obj")
Which flag to use depends on the compiler you are using. Also, you should strongly prefer to inject such compiler-and-scenario-specific flags into the build externally, rather than set()-ing them inside the build.
For g++ or clang++, the following invocation would be appropriate:
$ cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_CXX_FLAGS="-save-temps=obj"
For MSVC it would be:
> cmake -S . -B build "-DCMAKE_CXX_FLAGS=/FA"

How to integrate clang-tidy to CMake and GCC?

I want to integrate clang-tidy to our C and C++, CMake based project which is compiled using a custom GCC toolchain.
I've tried following this tutorial, setting CMAKE_CXX_CLANG_TIDY. I've also tried generating a compilation database by setting CMAKE_EXPORT_COMPILE_COMMANDS to ON and pointing run-clang-tidy.py to its directory.
In both cases, I've encountered (the same) few errors that are probably related to differences between Clang and GCC:
Some warning flags that are enabled in the CMake files are not supported in Clang but are supported in GCC (like -Wlogical-op). As the compiler is GCC, the file builds correctly, and the flag is written to the compilation database, but clang-tidy complains about it.
clang-tidy complains some defines and functions are unavailable, even though the code compiles just fine. As an example, the android-cloexec-open check suggested using O_CLOEXEC to improve security and force the closing of files, but trying to use this define leads to an undefined identifier error (even though our GCC compiles the code).
As an example to a function that is not found, there is clock_gettime.
Our code compiles with the C11 standard and C++14 standard, without GNU extensions:
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_C_EXTENSIONS OFF)
set(CMAKE_CXX_EXTENSIONS OFF)
The custom toolchain is a cross-compilation toolchain which runs on Linux and compiles to FreeBSD.
Is there a way to disable the passing of some flags by CMake to clang-tidy? Am I using clang-tidy wrong?
I suspect this issue is related to disabling GNU extensions, using a cross-compilation toolchain, and some feature-test-macro which is not defined by default in Clang but is defined with GCC (e.g. _GNU_SOURCE/_POSIX_SOURCE). If this is the case, how can I check it? If not, should I use clang-tidy differently?
EDIT
As #pablo285 asked, here are 2 warnings I get for a single file, and then as I added --warnings-as-errors=*, the build stops:
error: unknown warning option '-Wlogical-op' ; did you mean '-Wlong-long'? [clang-diagnostic-error]
<file path>: error: use of undeclared identifier 'O_CLOEXEC' [clang-diagnostic-error]
O_WRONLY | O_CLOEXEC
^
I decided to write a python script that will replace clang-tidy, receive the commandline from CMake and edit it to fix various errors. Here are the modification to the commandline I tried:
Remove none clang compile flags
This helps with things like the first warning, as now I don't pass flags that clang doesn't know. It seems like I can't configure CMake to pass different set of flags to GCC and to clang-tidy, so if anyone is familiar with some solution to this problem, I'll be happy to hear!
I changed the include directories that are passed to clang-tidy
As mentioned in the post, I use a custom toolchain (which cross-compiles). I used this post and Python to extract the list of standard include directories, and added them to the flag list as a list of -isystem <dir>. I also added -nostdinc so that clang-tidy won't try to look on his own headers instead of mine
This helped with the issue above, as now various defines such as O_CLOEXEC is defined in the toolchain's headers, but as my toolchain is based on GCC, clang couldn't parse the <type_traits> header which includes calls to many compiler intrinsics
I'm not sure what's the best approach in this case
#shycha: Thanks for the tip, I'll try disabling this specific check and I'll edit this post again
Ok, I think that I have a solution. After a couple of evenings I was able to make it work.
In general I compile like this
rm -rf build
mkdir build
cd build
cmake -C ../cmake-scripts/clang-tidy-all.cmake .. && make
Where cmake-scripts directory contains:
clang-tidy-all.cmake
toolchain_arm_clang.cmake
The two important files are listed below.
But what is more important, is how you need to compile this.
First, toolchain_arm_clang.cmake is referenced directly from clang-tidy-all.cmake via set(CMAKE_TOOLCHAIN_FILE ...). It must be, however, referenced from the point of view of the building directory, so if you use multiple levels of build-dirs, e.g.: build/x86, build/arm, build/darwin, etc., then you must modify that path accordingly.
Second, the purpose of set(CONFIG_SCRIPT_PRELOADED ...) is to be sure that the config script was pre-loaded, i.e., cmake -C ../cmake-scripts/clang-tidy-all.cmake ..
Typically, you would want to have something like this somewhere in your CMakeLists.txt file:
message(STATUS "CONFIG_SCRIPT_PRELOADED: ${CONFIG_SCRIPT_PRELOADED}")
if(NOT CONFIG_SCRIPT_PRELOADED)
message(FATAL_ERROR "Run cmake -C /path/to/cmake.script to preload a config script!")
endif()
Third, there is /lib/ld-musl-armhf.so.1 hard-coded in set(CMAKE_LINKER_ARM_COMPAT_STATIC ...); on the development box that I use, it points to /lib/libc.so, so it might by OK to use /lib/libc.sh instead. I've never tried.
Fourth, using set(CMAKE_C_LINK_EXECUTABLE ...) and set(CMAKE_LINKER_ARM_COMPAT_STATIC ...) was because CMake was complaining about some linking problems during checking the compiler, i.e., before even running make.
Fifth, I was only compiling C++ code, so if you need to compile some C, then it might be required to also properly configure set(CMAKE_C_CREATE_SHARED_LIBRARY ...), but I have no idea whether there is such a config option.
General Advice
Do not integrate it immediately. First test some simple CMake project with one library (preferably a C++ one) and make it work, then add the second library, but in C, tweak it again. And only after that incorporate it into the code base.
Toolchain
I used a custom toolchain with GCC 8.3.0 and musl C library, so locations of some files might be different for other toolchains.
Custom CMake
Some variables, like (already mentioned) CONFIG_SCRIPT_PRELOADED, EXPORT_PACKAGE_TO_GLOBAL_REGISTRY, DO_NOT_BUILD_TESTS, or DO_NOT_BUILD_BENCHMARKS are not generic CMake options, i.e., I use them only in my CMakeLists.txt, so you can safely ignore them.
Variables that are unset at the end of each *.cmake file, e.g., build_test, extra_clang_tidy_unchecks_for_tests_only, don't need to be present in the project's main CMakeLists.txt.
Clang
$ clang --version
clang version 10.0.0 (https://github.com/llvm/llvm-project.git 4650b2f36949407ef25686440e3d65ac47709deb)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /opt/local/bin
Files
clang-tidy-all.cmake:
set(ALL_CXX_WARNING_FLAGS --all-warnings -Weverything -Wno-c++98-compat -Wno-c++98-c++11-compat -Wno-c++98-c++11-c++14-compat -Wno-padded -Wno-c++98-compat-pedantic)
set(CXX_COMPILE_OPTIONS "-std=c++17;-O3;${ALL_CXX_WARNING_FLAGS}" CACHE INTERNAL "description")
set(CMAKE_CROSSCOMPILING True)
set(CMAKE_TOOLCHAIN_FILE "../cmake-scripts/toolchain_arm_clang.cmake" CACHE FILEPATH "CMake toolchain file")
set(CONFIG_SCRIPT_PRELOADED true CACHE BOOL "Ensures that config script was preloaded")
set(build_test False)
if(build_test)
message(STATUS "Using test mode clang-tidy checks!")
set(extra_clang_tidy_unchecks_for_tests_only ",-google-readability-avoid-underscore-in-googletest-name,-cppcoreguidelines-avoid-magic-numbers,-cppcoreguidelines-special-member-functions")
endif()
set(CMAKE_CXX_CLANG_TIDY "clang-tidy;--enable-check-profile;--checks=-*,abseil-string-find-startswith,bugprone-*,cert-*,clang-analyzer-*,cppcoreguidelines-*,google-*,hicpp-*,llvm-*,misc-*,modernize-*,-modernize-use-trailing-return-type,performance-*,readability-*,-readability-static-definition-in-anonymous-namespace,-readability-simplify-boolean-expr,portability-*${extra_clang_tidy_unchecks_for_tests_only}" CACHE INTERNAL "clang-tidy")
message(STATUS "build_test: ${build_test}")
message(STATUS "extra_clang_tidy_unchecks_for_tests_only: ${extra_clang_tidy_unchecks_for_tests_only}")
message(STATUS "CMAKE_CXX_CLANG_TIDY: ${CMAKE_CXX_CLANG_TIDY}")
# We want to skip building tests when clang-tidy is run (it takes too much time and serves nothing)
if(DEFINED CMAKE_CXX_CLANG_TIDY AND NOT build_test)
set(DO_NOT_BUILD_TESTS true CACHE BOOL "Turns OFF building tests")
set(DO_NOT_BUILD_BENCHMARKS true CACHE BOOL "Turns OFF building benchmarks")
endif()
unset(build_test)
unset(extra_clang_tidy_unchecks_for_tests_only)
set(EXPORT_PACKAGE_TO_GLOBAL_REGISTRY "OFF" CACHE INTERNAL "We don't export clang-tidy-all version to global register")
toolchain_arm_clang.cmake:
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_VERSION 4.14.0)
set(CMAKE_SYSTEM_PROCESSOR arm)
set(gcc_version 8.3.0)
set(x_tools "/opt/zynq/xtl")
set(CMAKE_C_COMPILER "clang" CACHE INTERNAL STRING)
set(CMAKE_CXX_COMPILER "clang++" CACHE INTERNAL STRING)
set(CMAKE_RANLIB "llvm-ranlib" CACHE INTERNAL STRING)
set(CMAKE_AR "llvm-ar" CACHE INTERNAL STRING)
set(CMAKE_AS "llvm-as" CACHE INTERNAL STRING)
set(CMAKE_LINKER "ld.lld" CACHE INTERNAL STRING)
execute_process(
COMMAND bash -c "dirname `whereis ${CMAKE_LINKER} | tr -s ' ' '\n' | grep ${CMAKE_LINKER}`"
OUTPUT_VARIABLE cmake_linker_dir
)
string(REGEX REPLACE "\n$" "" cmake_linker_dir "${cmake_linker_dir}")
set(cmake_linker_with_dir "${cmake_linker_dir}/${CMAKE_LINKER}" CACHE INTERNAL STRING)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -iwithsysroot /include/c++/${gcc_version} -iwithsysroot /include/c++/${gcc_version}/arm-linux-musleabihf" CACHE INTERNAL STRING)
set(CMAKE_SYSROOT ${x_tools}/arm-linux-musleabihf)
set(CMAKE_FIND_ROOT_PATH ${x_tools}/arm-linux-musleabihf)
set(CMAKE_INSTALL_PREFIX ${x_tools}/arm-linux-musleabihf)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY BOTH)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE BOTH)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE NEVER)
set(triple arm-linux-musleabihf)
set(CMAKE_LIBRARY_ARCHITECTURE ${triple})
set(CMAKE_C_COMPILER_TARGET ${triple})
set(CMAKE_CXX_COMPILER_TARGET ${triple})
set(lib_path_arm ${x_tools}/arm-linux-musleabihf/lib)
## Bootstrap library stuff:
set(Scrt1_o ${lib_path_arm}/Scrt1.o)
set(crti_o ${lib_path_arm}/crti.o)
set(crtn_o ${lib_path_arm}/crtn.o)
set(lib_path_gcc ${x_tools}/lib/gcc/${triple}/${gcc_version})
set(crtbeginS_o ${lib_path_gcc}/crtbeginS.o)
set(crtendS_o ${lib_path_gcc}/crtendS.o)
# Clang as linker
# --no-pie disable position independent executable, which is required when building
# statically linked executables.
set(CMAKE_CXX_LINK_EXECUTABLE "clang++ --target=${triple} -Wl,--no-pie --sysroot=${CMAKE_SYSROOT} ${CMAKE_CXX_FLAGS} -fuse-ld=${cmake_linker_with_dir} <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES> <OBJECTS> -o <TARGET> ")
set(CMAKE_CXX_CREATE_SHARED_LIBRARY "clang++ -Wl, --target=${triple} --sysroot=${CMAKE_SYSROOT} ${CMAKE_CXX_FLAGS} -fuse-ld=${cmake_linker_with_dir} -shared <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES> <OBJECTS> -o <TARGET> ")
#
# Do not use CMAKE_CXX_CREATE_STATIC_LIBRARY -- it is created automatically
# by cmake using ar and ranlib
#
#set(CMAKE_CXX_CREATE_STATIC_LIBRARY "clang++ -Wl,--no-pie,--no-export-dynamic,-v -v --target=${triple} --sysroot=${CMAKE_SYSROOT} ${CMAKE_CXX_FLAGS} -fuse-ld=ld.lld <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES> <OBJECTS> -o <TARGET> ")
## Linker as linker
set(CMAKE_LINKER_ARM_COMPAT_STATIC "-pie -EL -z relro -X --hash-style=gnu --eh-frame-hdr -m armelf_linux_eabi -dynamic-linker /lib/ld-musl-armhf.so.1 ${Scrt1_o} ${crti_o} ${crtbeginS_o} -lstdc++ -lm -lgcc_s -lgcc -lc ${crtendS_o} ${crtn_o}")
set(CMAKE_C_LINK_EXECUTABLE "${CMAKE_LINKER} ${CMAKE_LINKER_ARM_COMPAT_STATIC} <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES> <OBJECTS> -o <TARGET>")
# Debian bug 708744(?)
#include_directories("${CMAKE_SYSROOT}/usr/include/")
#include_directories("${CMAKE_SYSROOT}/usr/include/c++/${gcc_version}")
#include_directories("${CMAKE_SYSROOT}/usr/include/c++/${gcc_version}/${triple}")
## Clang workarounds:
set(toolchain_lib_dir_0 "${CMAKE_SYSROOT}/lib")
set(toolchain_lib_dir_1 "${CMAKE_SYSROOT}/../lib")
set(toolchain_lib_dir_2 "${CMAKE_SYSROOT}/../lib/gcc/${triple}/${gcc_version}")
set(CMAKE_TOOLCHAIN_LINK_FLAGS "-L${toolchain_lib_dir_0} -L${toolchain_lib_dir_1} -L${toolchain_lib_dir_2}")
## CMake workarounds
set(CMAKE_EXE_LINKER_FLAGS ${CMAKE_TOOLCHAIN_LINK_FLAGS} CACHE INTERNAL "exe link flags")
set(CMAKE_MODULE_LINKER_FLAGS ${CMAKE_TOOLCHAIN_LINK_FLAGS} CACHE INTERNAL "module link flags")
set(CMAKE_SHARED_LINKER_FLAGS ${CMAKE_TOOLCHAIN_LINK_FLAGS} CACHE INTERNAL "shared link flags")
unset(cmake_linker_with_dir)
unset(cmake_linker_dir)
Maybe not exactly what you're looking for but I'm using this in CMakeLists.txt:
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
add_custom_target(lint
COMMAND sh -c "run-clang-tidy -header-filter=.* -checks=`tr '\\n' , <${CMAKE_SOURCE_DIR}/checks.txt` >lint.out 2>lint.err"
COMMAND sh -c "grep warning: lint.out || true"
COMMAND ls -lh ${CMAKE_BINARY_DIR}/lint.out
VERBATIM
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
)
This creates a separate build target (make lint) for the clang-tidy check. clang-tidy takes a long time for my project so I don't want to run it during every build; make lint can be run manually if required, and it's also executed in a CI job after every push to the repo (in a way that makes the CI pipeline fail, blocking the merge, if there are any findings).
The output of make lint is the list of clang-tidy findings with as little context as possible. The full output, including context for findings, is in lint.out, and error messages are in lint.err, both of which I'm saving as CI artefacts.
checks.txt is a text file in the project root that defines which clang-tidy checks to activate, like so:
*
-altera-id-dependent-backward-branch
-altera-struct-pack-align
-altera-unroll-loops
-android-*
The first line enables all available checks, the other lines disable checks that I don't want.
Will only work in a Unix-like system of course.

How to config cmake for strip file

when I use cmake in Release mode I have the following binary:
64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=485ac09b0a3aa879f88b7f5db6c00ea8d8e1eaf6, not stripped
I want the binary to be stripped.
How can I say to cmake in a clean way to add the -s option to my compiler to make it stripped?
Why did the Default Release mode not strip my binary?
Cleanest possible way is to modify CFLAGS or CXXFLAGS (depending on C or C++ code)
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -s")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -s")
But there is one more hack if you do not want to change your build system (figuring out exact place where to put above lines might be tricky). You may just use strip as standalone application, like:
strip -s a.out
and do this after executable is ready to release as a post-build step. I found this way cleaner, then disturbing compiler flags.
You can try
set_target_properties(TARGET_NAME PROPERTIES LINK_FLAGS_RELEASE -s)
Using add_link_options() or set_target_properties() to add -s should work fine, additionally, CMake creates an install/strip target which also could be used for striping the binary if you have at least one install() command for your target (reference).
Example:
$ cmake --build . --config Release --target install/strip
This works fine:
add_link_options($<$<CONFIG:RELEASE>:-s>)

DistCC and CMake - select between local and distributed build when running make

My project is build using CMake and is compiled with DistCC + GCC.
I configure the compiler as follows:
SET(CMAKE_C_COMPILER "distcc variation-of-gcc")
To build the project, I simply run 'cmake' and then 'make -jXX'.
Although distcc really speeds up things, I sometimes want to build without distribution - I want it to build locally on the machine.
I know I can modify DISTCC_HOSTS to include only localhost - but this still has the overhead of distcc networking, although it is faster than the overhead for other machines...
I can also do that by rerunning cmake again and modifying the CMAKE_C_COMPILER using customization flags.
But I am looking for a way to do that by just adding a flag directly to 'make'.
I.e.
# This will use distcc:
make -jXX ...
# This will run locally:
make LOCAL_BUILD=1 -jX ...
Is there a CMake trick I can use?
We use the following to allow make time (rather than cmake time) switching on and off of the -Werror flag.
if(CMAKE_GENERATOR STREQUAL "Unix Makefiles")
# TODO: this approach for the WERROR only works with makefiles not Ninja
set(CMAKE_CXX_COMPILE_OBJECT "<CMAKE_CXX_COMPILER> <DEFINES> <INCLUDES> <FLAGS> $(WERROR) -o <OBJECT> -c <SOURCE>")
endif()
Then we run
make WERROR=-Werror
to turn on warnings as error.
I expect you could do something similar to have whether to use distcc come from a make variable. Like this:
set(CMAKE_CXX_COMPILE_OBJECT "$(USE_DISTCC) <CMAKE_CXX_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT> -c <SOURCE>")
And then run either
make USE_DISTCC=distcc
or just
make
The simplest thing to do (IMO) is write a little script in your project that invokes the compiler, and change your CMake files to run that script instead of containing the name of the compiler directly:
SET(CMAKE_C_COMPILER "my-gcc-script")
Now you can have that script normally run distcc, but (based on an environment variable or something) also run without distcc. There isn't any need to change anything in your CMake files.

gcov with CMake using a separate build directory

I'm struggling to get coverage information for gcov. No errors during compilation and linking, but when I run the executable, no coverage data is produced.
I'm using CMake with a separate build directory, passing flags to the compiler and linker in this way:
add_definitions(--coverage)
set(CMAKE_EXE_LINKER_FLAGS ${CMAKE_EXE_LINKER_FLAGS} " --coverage")
Does the executable expect the source code to be in a specific location?
What do I have to add to my CMakeLists.txt to get things going?
Kind regards,
Bjoern
CMake seems to put the code coverage (*.gcda, *.gcdo) files with the object files of your project. If your executable was named "tester" then they would appear in the following path
${CMAKE_BINARY_DIR}/CMakeFiles/tester.dir/
CMake seems to name the source files in a way that isn't very compatible with gcov though. For example if I had a source file called "mytestprog.cpp" it would be build
mytestprog.cpp.o
mytestprog.cpp.gcda
mytestprog.cpp.gcdno
where as gcov seems to expect
mytestprog.gcda
mytestprog.gcdno
I'm not really sure how to fix it. I've tried using LCov instead and that "appeared" to work but I'm not really sure if it did.
Delcypher pointed out the problem.
Solution 1: you can ask cmake to name object files as main.o instead of main.cpp.o etc. using the undocumented CMAKE_CXX_OUTPUT_EXTENSION_REPLACE switch:
cmake -DCMAKE_CXX_OUTPUT_EXTENSION_REPLACE=ON ...
Solution 2: if you do not need the .gcov files you can call lcov from the build directory:
lcov --capture --directory . --output-file coverage.info
genhtml coverage.info --output-directory out
You will find the coverage information in the out directory in html form.
Not sure where you got --coverage from, but these are the arguments I use on Linux to get coverage information using gcc and gcov:
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs -ftest-coverage")
set(CMAKE_EXE_LINKER_FLAGS
"${CMAKE_EXE_LINKER_FLAGS} -fprofile-arcs -ftest-coverage")
Here's what gcc --help --verbose has to say about those options:
-ftest-coverage Create
data files needed by "gcov"
-fprofile-arcs Insert
arc-based program profiling code
You don't need to pass --coverage to the linker. --coverage will pass -fprofile-arcs -ftest-coverage to the compiler and -lgcov to the linker.
Are you sure that it isn't creating any gcdo or gcda files? Where are you looking for these files? It should put the gcov file for each object file into the same directory as the object file. Do a find for .gcda files at the top of your build directory. If nothing shows up, gcov might not be getting linked in. Run the following command to see if it is:
nm name_of_binary | grep "gcov"
If it is getting linked in, then gcov might not have permission to write files to where you are running the executable. If it has permission, then I am stumped.