can't debug googletests in visual studio in Debug / X64 - cmake

I can't get to run my tests using googletest in visual studio2019 in Debug mode.
actually I have different symptoms on different machines so I tried to build a very simple basic example, which I hope is a good illustration of my issue, and is available here:
https://github.com/Willyam42/mpb
Basically in Release mode it seems to works fine.
In debug mode, the tests are not visible in VisualStudio2019 test window, and I get these messages in the output window:
[13/06/2019 20:47:17 Informational] ------ Discover test started ------
[13/06/2019 20:47:17 Warning] Test run will use DLL(s) built for framework Framework45. Following DLL(s) will not be part of run:
mpblib.lib,testrun.exe are built for Framework None and Platform X64.
Go to http://go.microsoft.com/fwlink/?LinkID=236877&clcid=0x409 for more details on managing these settings.
[13/06/2019 20:47:19 Warning] Could not locate debug symbols for 'C:\Users\guill\build\mpblib\test\Debug\testrun.exe'. To make use of '--list_content' discovery, ensure that debug symbols are available or make use of '<ForceListContent>' via a .runsettings file.
[13/06/2019 20:47:19 Informational] Test Adapter for Google Test: Test discovery starting...
[13/06/2019 20:47:19 Informational] Test discovery completed, overall duration: 00:00:00.0607728
[13/06/2019 20:47:19 Warning] No test is available in C:\Users\guill\build\mpblib\src\Debug\mpblib.lib C:\Users\guill\build\mpblib\test\Debug\testrun.exe. Make sure that test discoverer & executors are registered and platform & framework version settings are appropriate and try again.
I tried the microsoft link, it doesn't seem to do any good.
I don't understand why visual "could not locate debug symbols" since I build in Debug mode.
I tried looking in this direction:
https://social.msdn.microsoft.com/Forums/vstudio/en-US/8a4518be-d0ae-4c4a-9838-9251d346c3a4/test-run-will-use-dlls-built-for-framework-framework45-and-platform-x86
Not sure if it's a visual studio, a cmake or a googletest issue.
here is the CMakeLists.txt used to build the tests if relevant.
file(
GLOB_RECURSE _source_list
LIST_DIRECTORIES false
"${CMAKE_CURRENT_SOURCE_DIR}/*.cpp*"
"${CMAKE_CURRENT_SOURCE_DIR}/*.hpp"
)
set(Boost_USE_STATIC_LIBS OFF)
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)
find_package (Boost COMPONENTS date_time REQUIRED)
message("CMAKE_SOURCE_DIR : ${CMAKE_SOURCE_DIR}")
include_directories (${CMAKE_SOURCE_DIR}/mpblib/src
${Boost_INCLUDE_DIRS}
)
find_package(GTest REQUIRED)
find_package( Threads REQUIRED )
include(GoogleTest)
link_directories(${Boost_LIBRARY_DIRS})
include_directories(${GTEST_INCLUDE_DIRS})
add_executable (testrun ${_source_list})
target_link_libraries (testrun
${Boost_DATE_TIME_LIBRARY}
${GTEST_LIBRARIES}
${GTEST_MAIN_LIBRARIES}
Threads::Threads
mpblib
)
gtest_discover_tests(testrun TEST_PREFIX new:)
foreach(_source IN ITEMS ${_source_list})
get_filename_component(_source_path "${_source}" PATH)
file(RELATIVE_PATH _source_path_rel "${CMAKE_CURRENT_SOURCE_DIR}" "${_source_path}")
string(REPLACE "/" "\\" _group_path "${_source_path_rel}")
source_group("${_group_path}" FILES "${_source}")
endforeach()
any help would be greatly appreciated!

Related

CMake TARGET_RUNTIME_DLLS is empty

I have git cloned, built (with MSVC for both Debug and Release) and then installed wxWidgets:
cmake -B build wxWidgets
cmake --build build --config <CONFIG>
cmake --install build --prefix my_install --config <CONFIG>
with <CONFIG> = Debug and <CONFIG> = Release.
Then I used the following CMake script to link against it, as suggested by the wiki:
cmake_minimum_required(VERSION 3.16)
project(Test)
add_executable(Test WIN32 Main.cpp)
# wxWidgets
SET(wxWidgets_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}/../thirdparty/my_install)
find_package(wxWidgets COMPONENTS core base REQUIRED)
include(${wxWidgets_USE_FILE})
target_link_libraries(Test PRIVATE ${wxWidgets_LIBRARIES})
# Copy runtime DLLs to the directory of the executable.
add_custom_command(TARGET Test POST_BUILD
COMMAND ${CMAKE_COMMAND} -E echo "Runtime Dlls: $<TARGET_RUNTIME_DLLS:Test>"
)
My goal is to automatically copy the DLLs into the directory of the built executable, so that they can be found at runtime. For that I'm using the TARGET_RUNTIME_DLLS generator expression (follwing the sample code in the docs). In the code above, I only print out the expression at build time for testing purposes. The problem is that it is empty.
The approach worked for me before when installing and linking SDL, but SDL provides package configuration files which create imported targets, defining the DLL location(s) via IMPORTED_LOCATION_RELEASE or IMPORTED_LOCATION_DEBUG. For wxWidgets one is apparently supposed to use the FindwxWidgets.cmake script shipped with CMake, which sadly doesn't define the produced binaries. Maybe that's why TARGET_RUNTIME_DLLS isn't populated.
Does anyone know, either how to get TARGET_RUNTIME_DLLS filled or how to obtain the list of built wxWidgets DLLs for the current configuration (Release/Debug) post build copying?
Thanks a lot in advance!
I am dealing with a similar problem.
First sanity checks:
You have to work on windows platform otherwise this feature does not
work.
Your Cmake is 3.21 or above
Next comes fuzzy part. I think the library that you are trying to include have to be a Shared Imported library and you have to set a set_target_properties for IMPORTED_IMPLIB which is a path to a .lib file of sort (dll import library, I think it is called) So you have to make sure that it is all set in the package library that you trying to link with your executable.
If you have those dll avaiable and you just want to use them and not actually build them then you can write your own cmake script that will do just what I said above. Then you can include that cmake file in your project and then link against your app.
Note: I also work on similar issue right now and what I just said have not been working very reliably. I got some dlls to be copied and some do not.
Edit:
Cmake docs give a more detailed explanation on how this library setting should look like if you use find_package feature.
Found here: https://cmake.org/cmake/help/latest/command/add_library.html#imported-libraries
An UNKNOWN library type is typically only used in the implementation
of Find Modules. It allows the path to an imported library (often
found using the find_library() command) to be used without having to
know what type of library it is. This is especially useful on Windows
where a static library and a DLL's import library both have the same
file extension.

CLion: How do I get coverage for the actual library code instead of just the tests

I am testing a C++ library and I want to record coverage when I run the tests. Based on the CLion documentation, I added the necessary compiler switches:
option(CODE_COVERAGE "enable code coverage" OFF)
if(CODE_COVERAGE)
if("${CMAKE_CXX_COMPILER_ID}" MATCHES "(Apple)?[Cc]lang")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-instr-generate -fcoverage-mapping")
else()
message(FATAL_ERROR "Code coverage only available with LLVM/clang.")
endif()
endif()
add_library(libfoo SHARED
# ... snip: source files ...
)
# ... snip: library deps & config
add_executable(libfoo_tests
# ... snip: source files ...
)
target_link_libraries(libfoo_tests gtest_main libfoo) # using Googletest
With this, I can run the tests with coverage in CLion. And I get coverage reports… on the testing code, but not on the library's code. So this is pretty much useless.
I have no idea what CLion actually does when running the tests with coverage, but the docs on LLVM's coverage tool state clearly that
BIN may be an executable, object file, dynamic library, or archive (thin or otherwise).
So it should be possible to get coverage on the library. What do I need to do to make it happen?
I have the same problem. If you remove that code, you would get an error (described here: https://www.jetbrains.com/help/clion/code-coverage-clion.html), that automatically creates a new debug profile with the flags needed for the code coverage. This time the src folder is included (even not perfect), but maybe from there you could find a perfect solution.

CMake test doesn't show up in test explorer on gcc build

Currently looking into testing for windows and linux with cmake. I've made a small project that I want to build and test on both. Building works for me. And I've added a dependency to boost test to add a very simple test.
For windows, this test shows up in the test explorer of visual studio and I can run the test fine from there or use the command line.
For Linux, I can run the testproject from the commandline, but my test don't show up in the Test Explorer.
Question
Is adding boost test for a linux build to the Test Explorer not possible at the moment with visual studio? Or is there something wrong with my approach?
I'll include the CMake of the testproject below. If you'd like to see the whole project pls visit https://github.com/gertkommer/BoostTestCmakeExample
Using Visual Studio 2019 pro 16.5.3
cmake_minimum_required (VERSION 3.16)
find_package( Boost 1.70.0 REQUIRED COMPONENTS system filesystem unit_test_framework)
project(MyProject_test)
add_executable (${PROJECT_NAME}
"BoostTest_test.cpp"
)
add_definitions(-DBOOST_TEST_DYN_LINK)
#set(BOOST_LIBRARIES Boost::unit_test_framework Boost::system Boost::filesystem)
if (WIN32)
if (CMAKE_BUILD_TYPE MATCHES "Debug")
set(BOOST_LIBRARIES ${Boost_LIBRARY_DIR_DEBUG}/boost_unit_test_framework-vc140-mt-gd.lib
${Boost_LIBRARY_DIR_DEBUG}/boost_system-vc140-mt-gd.lib
${Boost_LIBRARY_DIR_DEBUG}/boost_filesystem-vc140-mt-gd.lib
)
endif()
endif()
if(UNIX)
set(BOOST_LIB_DIR ${Boost_LIBRARY_DIRS}/libboost_unit_test_framework.so)
if (CMAKE_BUILD_TYPE MATCHES "Debug")
set(BOOST_LIBRARIES ${Boost_LIBRARY_DIR_DEBUG}/libboost_unit_test_framework.so
${Boost_LIBRARY_DIR_DEBUG}/libboost_system.so
${Boost_LIBRARY_DIR_DEBUG}/libboost_filesystem.so
)
endif()
endif()
target_include_directories(${PROJECT_NAME}
PUBLIC ${Boost_INCLUDE_DIR}
)
target_link_libraries(${PROJECT_NAME}
${BOOST_LIBRARIES}
MyProject
)
add_test(MyBoostModule ${PROJECT_NAME})

How treat `include-what-you-use` warnings as errors with `cmake`

Is it possible to treat include-what-you-use warnings as errors using cmake?
I am playing around with include-what-you-use trying to integrate it into our cmake build process. The desired behaviour is to stop the build process when include-what-you-use generates a report, then print a warning. Currently, the build continues.
The tool is integrated to the cmake build process thanks to:
find_program(IWYU NAMES include-what-you-use)
if(IWYU)
message(STATUS "Using include-what-you-use")
set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE ${IWYU})
endif()
I also add the Werror flag to my cmake target.

Is there a workaround that I can use so that I can test the build type when using CMake in combination with Visual Studio and multiple configurations?

I would like to work with 'Debug', 'Release', 'Debug_Unicode' and 'Release_Unicode'
I have been able to use the DEBUG_CONFIGURATIONS variable so that the 'Debug Unicode' configuration correctly gets used as debug
This is what I tried to do in the CmakeLists.txt file:
target_link_libraries(tests
optimized ${CMAKE_BINARY_DIR}/src/${CMAKE_BUILD_TYPE}/foo.lib
debug ${CMAKE_BINARY_DIR}/src/${CMAKE_BUILD_TYPE}/foo.lib
)
Clearly CMake is able to make a choice between debug and release at this point, as it has to choose the 'optimized' or 'debug' library.
However, CMAKE_BUILD_TYPE is an empty string.
The best that I have been able to come up with is to work with a separate solution file for each of the configurations,
passing in CMAKE_BUILD_TYPE myself:
cmake -G Visual Studio 11 2012 Win64 -DCMAKE_BUILD_TYPE=Debug_Unicode C:\foo
As Antonio was mentioning
target_link_libraries(tests foo)
or just
add_dependencies(tests foo)
would be sufficient to link the correct library from the same configuration.
If you want to do more advanced stuff, take a look at the generator expressions. They are configuration sensitive incl. in Visual Studio's multi-configuration environment and they would work also for the target_link_libraries() command.
So your example would look like:
target_link_libraries(tests ${CMAKE_BINARY_DIR}/src/$<CONFIG>/foo.lib)
I have used generator expression e.g. in custom commands that need to be aware of the output path of my DLL (if foo would be generating an MSTest DLL):
add_test(
NAME RunFooTest
WORKING_DIRECTORY $<TARGET_FILE_DIR:foo>
COMMAND vstest.console.exe /InIsolation /Platform:x86 $<TARGET_FILE:$foo>
)
And - just because you mentioned different solutions - you can use CMake to build a certain configuration from the command line. This would in your case look like e.g.
cmake --build C:\foo --target ALL_BUILD --config Debug_Unicode