I'm on a linux machine, trying to build a project using cmake that does out of source builds. For code coverage, I looked into gcov and followed a simple tutorial that generate appropriate files for a sample helloWorld.cpp program. The only requirement were to compile with -fprofile-arcs -ftest-coverage flags & link with -lgcov flag, which can be done altogether with -coverage flag.
Now here comes the tricky part. I have a CMakeLists.txt wit contents as shown below:
cmake_minimum_required (VERSION 2.8)
project (SomeName)
SET(GCC_COVERAGE_COMPILE_FLAGS "-g -O0 -coverage -fprofile-arcs -ftest-coverage")
SET(GCC_COVERAGE_LINK_FLAGS "-coverage -lgcov")
SET( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${GCC_COVERAGE_COMPILE_FLAGS}" )
SET( CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${GCC_COVERAGE_LINK_FLAGS}" )
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
include_directories(include)
set(CATCH_HEADER_PATH ${PROJECT_SOURCE_DIR}/test/catch.hpp)
add_executable(runTest ${PROJECT_SOURCE_DIR}/test/test.cpp ${CATCH_HEADER_PATH})
So I've included appropriate compile time flags as well as linker flags too and appended them correctly. Another thing to note is set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) line which says that executables will be generated inside bin directory.
Now everything works as intended except that coverage files aren't generated properly. I follow these steps :
mkdir build && cd build
cmake ..
make -j4
./bin/runTest
and no other file is generated inside bin folder. However on more inspection I found out that there is another location build/CMakeFiles/runTest.dir/test where test.cpp.o resides initially and after the final step ./bin/runTest, two new files - test.cpp.gcda & test.cpp.gcno are generated.
I've already tried copying test/test.cpp to build/CMakeFiles/runTest.dir/test and running gcov test.cpp but it fails stating - test.gcno:cannot open notes file
A mismatch in gcov and gcc version was making this happen. gcc symlink /usr/bin/gcc was set to newest gcc, same for g++ but gcov in $PATH was still pointing to older version of gcov.
Related
Work on Ubuntu 16
I used g++ main.cpp -lpq command for compiler my small project. Now I use Clion and wanna do same what I do with g++. But I can't add compiler flags in cmake file and get compile error.
cmake_minimum_required(VERSION 3.5.1)
project(day_g)
set(CMAKE_CXX_FLAGS "-lpq")
add_definitions(-lpq)
message("CMAKE_CXX_FLAGS is ${CMAKE_CXX_FLAGS}")
set(CMAKE_CXX_STANDARD 11)
set(SOURCE_FILES main.cpp)
add_executable(day_g ${SOURCE_FILES})
Also I run only cmake file and get CMAKE_CXX_FLAGS with -lpq flag.
CMAKE_CXX_FLAGS is -lpq
-- Configuring done
-- Generating done
How properly add compiler flags to cmake file?
Flag -l is for linker, not for compiler. This flag is used for link with libraries. CMake has special command target_link_libraries for that purpose:
target_link_libraries(day_g pq)
-lq is not a compiler flag (CFLAGS) but a linker flag.
To pass a library in a CMake project you should use:
target_link_libraries(target_name libraries...)
Note that if you specify 'q' as library the project will link with libq.a or, if you are on windows q.dll.
... in your CMakeLists.txt the correct line to add is:
target_link_libraries(day_g pq)
Note also that when you add a CFLAG you should also "remember" the previous ones that may be added by libraries or by your platform, ie:
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3")
To check the exact flags cmake is passing to compiler or linker you can always run, from the build directory, the following command:
make VERBOSE=1
Work on Ubuntu 16
I used g++ main.cpp -lpq command for compiler my small project. Now I use Clion and wanna do same what I do with g++. But I can't add compiler flags in cmake file and get compile error.
cmake_minimum_required(VERSION 3.5.1)
project(day_g)
set(CMAKE_CXX_FLAGS "-lpq")
add_definitions(-lpq)
message("CMAKE_CXX_FLAGS is ${CMAKE_CXX_FLAGS}")
set(CMAKE_CXX_STANDARD 11)
set(SOURCE_FILES main.cpp)
add_executable(day_g ${SOURCE_FILES})
Also I run only cmake file and get CMAKE_CXX_FLAGS with -lpq flag.
CMAKE_CXX_FLAGS is -lpq
-- Configuring done
-- Generating done
How properly add compiler flags to cmake file?
Flag -l is for linker, not for compiler. This flag is used for link with libraries. CMake has special command target_link_libraries for that purpose:
target_link_libraries(day_g pq)
-lq is not a compiler flag (CFLAGS) but a linker flag.
To pass a library in a CMake project you should use:
target_link_libraries(target_name libraries...)
Note that if you specify 'q' as library the project will link with libq.a or, if you are on windows q.dll.
... in your CMakeLists.txt the correct line to add is:
target_link_libraries(day_g pq)
Note also that when you add a CFLAG you should also "remember" the previous ones that may be added by libraries or by your platform, ie:
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3")
To check the exact flags cmake is passing to compiler or linker you can always run, from the build directory, the following command:
make VERBOSE=1
Work on Ubuntu 16
I used g++ main.cpp -lpq command for compiler my small project. Now I use Clion and wanna do same what I do with g++. But I can't add compiler flags in cmake file and get compile error.
cmake_minimum_required(VERSION 3.5.1)
project(day_g)
set(CMAKE_CXX_FLAGS "-lpq")
add_definitions(-lpq)
message("CMAKE_CXX_FLAGS is ${CMAKE_CXX_FLAGS}")
set(CMAKE_CXX_STANDARD 11)
set(SOURCE_FILES main.cpp)
add_executable(day_g ${SOURCE_FILES})
Also I run only cmake file and get CMAKE_CXX_FLAGS with -lpq flag.
CMAKE_CXX_FLAGS is -lpq
-- Configuring done
-- Generating done
How properly add compiler flags to cmake file?
Flag -l is for linker, not for compiler. This flag is used for link with libraries. CMake has special command target_link_libraries for that purpose:
target_link_libraries(day_g pq)
-lq is not a compiler flag (CFLAGS) but a linker flag.
To pass a library in a CMake project you should use:
target_link_libraries(target_name libraries...)
Note that if you specify 'q' as library the project will link with libq.a or, if you are on windows q.dll.
... in your CMakeLists.txt the correct line to add is:
target_link_libraries(day_g pq)
Note also that when you add a CFLAG you should also "remember" the previous ones that may be added by libraries or by your platform, ie:
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3")
To check the exact flags cmake is passing to compiler or linker you can always run, from the build directory, the following command:
make VERBOSE=1
Work on Ubuntu 16
I used g++ main.cpp -lpq command for compiler my small project. Now I use Clion and wanna do same what I do with g++. But I can't add compiler flags in cmake file and get compile error.
cmake_minimum_required(VERSION 3.5.1)
project(day_g)
set(CMAKE_CXX_FLAGS "-lpq")
add_definitions(-lpq)
message("CMAKE_CXX_FLAGS is ${CMAKE_CXX_FLAGS}")
set(CMAKE_CXX_STANDARD 11)
set(SOURCE_FILES main.cpp)
add_executable(day_g ${SOURCE_FILES})
Also I run only cmake file and get CMAKE_CXX_FLAGS with -lpq flag.
CMAKE_CXX_FLAGS is -lpq
-- Configuring done
-- Generating done
How properly add compiler flags to cmake file?
Flag -l is for linker, not for compiler. This flag is used for link with libraries. CMake has special command target_link_libraries for that purpose:
target_link_libraries(day_g pq)
-lq is not a compiler flag (CFLAGS) but a linker flag.
To pass a library in a CMake project you should use:
target_link_libraries(target_name libraries...)
Note that if you specify 'q' as library the project will link with libq.a or, if you are on windows q.dll.
... in your CMakeLists.txt the correct line to add is:
target_link_libraries(day_g pq)
Note also that when you add a CFLAG you should also "remember" the previous ones that may be added by libraries or by your platform, ie:
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3")
To check the exact flags cmake is passing to compiler or linker you can always run, from the build directory, the following command:
make VERBOSE=1
I am using CMake 3.8.2, GNU make 4.2.1 and GCC 6.4.0 for my C++14 project and I noticed a strange behavior when building. I am using CMake for an out-of-source build in a sub-folder called "build" where I run cmake .. followed by make.
CMake runs fine without any errors and make will build all source files like I expect until it is done compiling and starts linking them. It will then fail with an error
[ 83%] ...
[100%] Linking CXX executable myproject
/usr/bin/ld: some-source-file.cc.o: undefined reference to symbol '_ZNKSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEE3strEv##GLIBCXX_3.4.21'
Interestingly it doesn't show any compiler warnings up to this point and only shows the above mentioned linker error.
Now when I ignore the error and simply run cmake .. and then make again (just like I did before) I get all the compiler warnings that my code should produce and everything links perfectly fine, even though I didn't change any code or CMake-related files in the meantime.
I can reproduce this behavior by deleting all files in the build dir by running rm -r *.
Here is my CMakeLists.txt file:
# Define minimum required CMake version
cmake_minimum_required(VERSION 3.8.2)
# Setting compiler related settings
set(CMAKE_CXX_COMPILER "${CMAKE_SOURCE_DIR}/toolchain/binary/gcc-6.4.0/bin/gcc")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wconversion -O2 -lstdc++")
set(CMAKE_CXX_STANDARD 14)
# Define project name
project(MyProject)
# Find source files
file(GLOB_RECURSE SOURCES application/*.cc)
# Adding third-party sources
set(SOURCES ${SOURCES} "third-party/cpp-base64/base64.cpp")
# Executable to be built from which source files
add_executable(myproject ${SOURCES})
# Find and include and link Botan
find_library(BOTAN botan-2 "third-party/botan/build/lib")
include_directories("third-party/botan/build/include/botan-2")
# Includes that are part of the project
include_directories("${CMAKE_SOURCE_DIR}/application/include")
# Include nlohmann/json
include_directories("third-party/json/src")
# Include cpp-base64 by René Nyffenegger
include_directories("third-party/cpp-base64")
find_package(Boost REQUIRED COMPONENTS program_options)
if(Boost_FOUND)
include_directories(${Boost_INCLUDE_DIRS})
endif()
# Link third-party libraries
target_link_libraries(myproject ${Boost_LIBRARIES} ${BOTAN})
Note: I am required to check-in the compiler and libraries I am using, which is why I specified them in the CMake file.
If it only works the second time it has to do with cached variables.
So I'm pretty sure that it will work the first time if you modify CMAKE_CXX_COMPILER setting by adding set(... CACHE INTERNAL "") to:
set(CMAKE_CXX_COMPILER "${CMAKE_SOURCE_DIR}/toolchain/binary/gcc-6.4.0/bin/gcc" CACHE INTERNAL "")
And move set(CMAKE_CXX_FLAGS ...) after the project() command.
But please also be noted that you shouldn't put the compiler into your CMakeLists.txt.
References
CMake: In which Order are Files parsed (Cache, Toolchain, …)?
Passing compiler options cmake
CMake Error at CMakeLists.txt:30 (project): No CMAKE_C_COMPILER could be found