MantisBT - CMake
View Issue Details
0007590CMakeModulespublic2008-09-02 07:212016-06-10 14:30
Mahendra Ladhe 
Kitware Robot 
normalminoralways
closedmoved 
CMake-2-6 
 
0007590: CHECK_C_COMPILER_FLAG macro not working for gcc's -fprofile-arcs flag
Hi,
  shown below is part of my CMakeLists.txt file.

#To build the code for use with gcov, call cmake as below
#cmake -DGCOV=1 ..
IF (${GCOV})
    CHECK_C_COMPILER_FLAG (-fprofile-arcs FLAG_Gcov1)
    IF (FLAG_Gcov1)
      add_definitions (-fprofile-arcs)
    ELSE (FLAG_Gcov1)
      MESSAGE(FATAL_ERROR "Compiler does not support the -fprofile-arcs flag needed for using gcov")
    ENDIF (FLAG_Gcov1)
    CHECK_C_COMPILER_FLAG (-ftest-coverage FLAG_Gcov2)
    IF (FLAG_Gcov2)
      add_definitions (-ftest-coverage)
    ELSE (FLAG_Gcov2)
      MESSAGE(FATAL_ERROR "Compiler does not support the -ftest-coverage flag needed for using gcov")
    ENDIF (FLAG_Gcov2)
ENDIF (${GCOV})

I want to give user an option to compile the code for use with GCOV:
the GNU code coverage tool. For this the code needs to be compiled with
-fprofile-arcs and -ftest-coverage flags.

    When I invoke cmake as follows
cmake -DGCOV=1 ..
I get the following error
CMake Error: Compiler does not support the -fprofile-arcs flag needed
for using gcov

    Well, the gcc compiler on my Linux box does support -fprofile-arcs
compilation flag.
The CMakeFiles/CMakeError.log shows the cause of error.

=========================================================================================
Performing C SOURCE FILE Test FLAG_Gcov1 failed with the following output:
/usr/bin/gmake -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build
gmake[1]: Entering directory `/proj/magnum/mladhe/p4/L7/bld_x86/CMakeFiles/CMakeTmp'
/home/srgorti/freeware/usr/bin/cmake -E cmake_progress_report /proj/magnum/mladhe/p4/L7/bld_x86/CMakeFiles/CMakeTmp/CMakeFiles 1
Building C object CMakeFiles/cmTryCompileExec.dir/src.o
/usr/local/bin/gcc -DFLAG_Gcov1 -fprofile-arcs -o CMakeFiles/cmTryCompileExec.dir/src.o -c /proj/magnum/mladhe/p4/L7/bld_x86/CMakeFiles/CMakeTmp/src.c
Linking C executable cmTryCompileExec
/home/srgorti/freeware/usr/bin/cmake -P CMakeFiles/cmTryCompileExec.dir/cmake_clean_target.cmake
/usr/local/bin/gcc -DFLAG_Gcov1 -fPIC "CMakeFiles/cmTryCompileExec.dir/src.o" -o cmTryCompileExec -rdynamic
CMakeFiles/cmTryCompileExec.dir/src.o(.text+0x43): In function `global constructors keyed to 0_main':
: undefined reference to `__gcov_init'
CMakeFiles/cmTryCompileExec.dir/src.o(.data+0x24): undefined reference to `__gcov_merge_add'
collect2: ld returned 1 exit status
gmake[1]: *** [cmTryCompileExec] Error 1
gmake[1]: Leaving directory `/proj/magnum/mladhe/p4/L7/bld_x86/CMakeFiles/CMakeTmp'
gmake: *** [cmTryCompileExec/fast] Error 2

Source file was:
int main() { return 0;}
=========================================================================================

So the reason is when source file is compiled with -fprofile-arcs,
the cmake does not supply the same flag while linking which the gcc needs
as the object module has certain gcov related code like functions gcov_init,
gcov_merge_add etc.

So the working of Check_C_Compiler_Flag macro needs enhancement to
detect support for such kinds of compiler flags.
No tags attached.
Issue History
2008-09-02 07:21Mahendra LadheNew Issue
2008-09-03 15:00Bill HoffmanNote Added: 0013280
2008-09-03 15:00Bill HoffmanStatusnew => assigned
2008-09-03 15:00Bill HoffmanAssigned To => Bill Hoffman
2008-09-04 00:04Mahendra LadheNote Added: 0013292
2008-09-09 14:12Bill HoffmanNote Added: 0013384
2008-09-09 14:14Bill HoffmanNote Added: 0013385
2008-09-11 04:24Mahendra LadheNote Added: 0013406
2008-09-11 08:50Bill HoffmanNote Added: 0013411
2008-09-15 23:10Mahendra LadheNote Added: 0013478
2008-10-01 10:17Bill HoffmanNote Added: 0013639
2008-10-01 10:18Bill HoffmanAssigned ToBill Hoffman => Alex Neundorf
2010-08-29 10:23Kovarththanan RajaratnamCategoryCMake => Modules
2012-01-04 16:12Alex NeundorfNote Added: 0028177
2012-01-04 16:12Alex NeundorfAssigned ToAlex Neundorf =>
2012-01-04 16:12Alex NeundorfStatusassigned => backlog
2016-06-10 14:27Kitware RobotNote Added: 0041446
2016-06-10 14:27Kitware RobotStatusbacklog => resolved
2016-06-10 14:27Kitware RobotResolutionopen => moved
2016-06-10 14:27Kitware RobotAssigned To => Kitware Robot
2016-06-10 14:30Kitware RobotStatusresolved => closed

Notes
(0013280)
Bill Hoffman   
2008-09-03 15:00   
You could try this:

SET(CMAKE_REQUIRED_LIBRARIES -fprofile-arcs )
CHECK_C_COMPILER_FLAG (-fprofile-arcs FLAG_Gcov1)
(0013292)
Mahendra Ladhe   
2008-09-04 00:04   
Per Bill's suggestion, when I added one more line
SET(CMAKE_REQUIRED_LIBRARIES -fprofile-arcs )
found that gcc is no longer being passed the flag -fprofile-arcs
during compilation, but only during linking so it has no effect.
i.e. after incorporating the suggestion, my CMakeLists.txt's relevant
portion became as below.

#To build the code for use with gcov, call cmake as below
#cmake -DGCOV=1 ..
IF (${GCOV})
    SET(CMAKE_REQUIRED_LIBRARIES -fprofile-arcs )
    CHECK_C_COMPILER_FLAG (-fprofile-arcs FLAG_Gcov1)
    IF (FLAG_Gcov1)
      add_definitions (-fprofile-arcs)
    ELSE (FLAG_Gcov1)
      MESSAGE(FATAL_ERROR "Compiler does not support the -fprofile-arcs flag needed for using gcov")
    ENDIF (FLAG_Gcov1)
    CHECK_C_COMPILER_FLAG (-ftest-coverage FLAG_Gcov2)
    IF (FLAG_Gcov2)
      add_definitions (-ftest-coverage)
    ELSE (FLAG_Gcov2)
      MESSAGE(FATAL_ERROR "Compiler does not support the -ftest-coverage flag needed for using gcov")
    ENDIF (FLAG_Gcov2)
ENDIF (${GCOV})

After this change I'm not getting the error message
"Compiler does not support the -fprofile-arcs flag needed for using gcov"
But the statement add_definitions (-fprofile-arcs) is not taking effect.
During compilation(e.g. gcc -c a.c -o a.o), gcc is not being passed -fprofile-arcs flag. So code does not get compiled for use with GCOV.

One more observation: While the cmake 2.6 documentation for CHECK_C_SOURCE_COMPILES is as follows.
=======================
CHECK_C_SOURCE_COMPILES(SOURCE VAR)

  SOURCE - source code to try to compile
  VAR - variable to store whether the source code compiled

The following variables may be set before calling this macro to modify the way the check is run:

  CMAKE_REQUIRED_LIBRARIES = list of libraries to link
=======================

the documentation for CHECK_C_COMPILER_FLAG macro does not say that
the variable CMAKE_REQUIRED_LIBRARIES may be set before calling this
macro to modify the way the check is run.
(0013384)
Bill Hoffman   
2008-09-09 14:12   
I have updated the docs to say this:
 
 CheckCCompilerFlag
       Check whether the C compiler supports a given flag.

       CHECK_C_COMPILER_FLAG(FLAG VARIABLE)

         FLAG - the compiler flag
         VARIABLE - variable to store the result

       

         This actually calls the check_c_source_compiles macro.
         See help for CheckCSourceCompiles for a listing of variables
         that can modify the build.



       Defined in: C:/hoffman/My Builds/CMake/Modules/CheckCCompilerFlag.cmake

  CheckCSourceCompiles
       macro which checks if the source code compiles

       CHECK_C_SOURCE_COMPILES(SOURCE VAR)

         SOURCE - source code to try to compile
         VAR - variable to store whether the source code compiled

       

       The following variables may be set before calling this macro to modify
       the way the check is run:

         CMAKE_REQUIRED_FLAGS = string of compile command line flags
         CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
         CMAKE_REQUIRED_INCLUDES = list of include directories
         CMAKE_REQUIRED_LIBRARIES = list of libraries to link



       Defined in: C:/hoffman/My Builds/CMake/Modules/CheckCSourceCompiles.cmake
(0013385)
Bill Hoffman   
2008-09-09 14:14   
Does the add_definition work without the if?

Also, it might be better to modify CMAKE_CXX_FLAGS instead.

Something like this should work:
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs")

Make sure this is done BEFORE the target that you want to build with profile information.
(0013406)
Mahendra Ladhe   
2008-09-11 04:24   
Yes, add_definitions work without the if, but only while compiling.
Consider my following simple CMakeLists.txt file

add_definitions (-fprofile-arcs)
add_definitions (-ftest-coverage)
add_executable(sample_test test.c)

When compiling test.c gcc did receive -fprofile-arcs and -ftest-coverage
flags. But when linking it didn't. So linking failed as gcc needs the
two flags again so that it can link gcov library.

Adding following line instead of 2 add_definitions is helping and giving
the desired behaviour.
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs -ftest-coverage")

Now gcc is being passed these 2 flags while compiling and as well as linking.

Thanks Bill.

But the behaviour of Check_C_Compiler_Flag macro still needs a fix.
(0013411)
Bill Hoffman   
2008-09-11 08:50   
I am not sure, you are confusing link flags and compile flags. In this case you want to test a link flag and a compile flag at the same time. They happen to be the same thing. However, many compile flags are not useful or wanted at link time. add_definition is only used at compile time and is really meant for -D stuff.
(0013478)
Mahendra Ladhe   
2008-09-15 23:10   
Yes, -fprofile-arcs and -ftest-coverage are both compile and link flags.
So is there any way to check if such flags(compile+link) are supported by
the compiler?
(0013639)
Bill Hoffman   
2008-10-01 10:17   
You could do something like this:

set(CMAKE_C_FLAGS_SAVE "${CMAKE_C_FLAGS}")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs")
CHECK_C_COMPILER_FLAG (-fprofile-arcs FLAG_Gcov1)

But that seems kind of silly. I guess the macro could be augmented to support compile and link flags. Maybe a version that just sets CMAKE_C_FLAGS.
(0028177)
Alex Neundorf   
2012-01-04 16:12   
I think I won't work on this.

Alex
(0041446)
Kitware Robot   
2016-06-10 14:27   
Resolving issue as `moved`.

This issue tracker is no longer used. Further discussion of this issue may take place in the current CMake Issues page linked in the banner at the top of this page.