I have a C++ project using CMake. The project is built on CentOS machine. I have configured CLion to build remotely from MacOS. I have unit tests for the project and I am trying to run them from CLion. I can run the tests from CentOS machine using CTest like below
ctest -r utCppProject -v
CLion tries to run the executable directly with gtest flags like below
./utCppProject --gtest_filter=* --gtest_color=no
Process finished with exit code 0
No tests are actually run.
How can I configure CLion to be able to use CTest for running unit tests?
Here is my CMakeLists.txt for the unit test project
cmake_minimum_required(VERSION 3.4.1)
include(../../cmake-dependencies/Boost.cmake)
include(../../cmake-dependencies/GoogleTest.cmake)
set(CMAKE_BINARY_DIR "${CMAKE_CURRENT_LIST_DIR}/../build")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
include_directories(${GOOGLE_TEST_DIR}/googletest/include)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/.)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../include)
set(TARGET utCppProject)
add_executable (
${TARGET}
utCppProject.cpp
)
target_link_libraries (
${TARGET}
CppProject
gtest
boost_system
pthread
)
set(CMAKE_CXX_FLAGS "-fPIC -DPIC -Wall -Werror -std=c++0x")
set(TEST_OUTPUT "${CMAKE_BINARY_DIR}/test_results/${TARGET}.xml")
add_test(${TARGET} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${TARGET})
set_tests_properties(${TARGET} PROPERTIES
ENVIRONMENT
"UT_FOLDER_PATH=${CMAKE_CURRENT_SOURCE_DIR};GTEST_OUTPUT=xml:${TEST_OUTPUT}")
Since CLion 2020.3 EAP CTest is supported from the box.
You can easily configure CLion to use CTest. Simply duplicate the default configuration for the test target and configure it to use the CTest executable and set the working directory to the build directory:
In detail:
Executable > Select other... > Find and select ctest (for me it is /usr/bin/ctest, on UNIX-like systems you can use which ctest to find it)
Set program arguments - -j sets the amount of threads to use, then the name of the executable to test, and --output-on-failure to get the test output when something went wrong - you could simply set it to -r utCppProject -v
Set working directory to cmake-build-debug under the project dir, the default build directory for CLion
There is currently no CTest support in CLion.
The feature request is here.
Since version CLion 2020.3 the CTest is supported from the box for CMake 3.14 and above.
Related
I have a C++ CMake project that is compiled both on Linux and Windows. On Windows, this is done via Visual Studio/MSVCC.
In CMAKE and in VS, the build is set up as Debug, but it seems that no debug symbols are ever being made in the VS build - so debugging is impossible.
When looking over the Detailed output for VS, I saw this:
cl : command line warning D9002: ignoring unknown option '-g'
That suggests to me that it doesn't recognize the -g flag like GCC/Clang do.
Here is the CMake arguments:
SET(CMAKE_CXX_STANDARD 17)
SET(CMAKE_CXX_STANDARD_REQUIRED ON)
SET(BUILD_MODE Debug)
SET(CMAKE_CXX_FLAGS "-Wall")
SET(CMAKE_CXX_FLAGS_DEBUG "-g")
SET(CMAKE_CXX_FLAGS_RELEASE "-O3")
How do I make this compatible with Visual Studio? I've tried looking all over, but most related posts seem to be about C#/.net, or much older versions of VS.
The project does use the QT library if that matters.
UPDATE:
It turns out BUILD_MODE was something added by someone else so that each sub-project would not individually need to be set to release or debug, we could just set it once in the root level Cmakelists. They did all actually use CMAKE_BUILD_TYPE as intended.
Also, the answers here were correct. Setting the CMAKE_CXX_FLAGS directly was wiping away the defaults, causing the Debug build to not have options like /Zi in MSVCC, preventing debug symbols and all debugging. It also introduced an unrecognized flag "-g" which MSVCC couldn't understand.
I completely remove the SET_CXX_FLAGS from every Cmakelists.txt in the project, and everything is working perfectly.
Should I need to add to them, I will use the _INIT option as suggested.
You have to compile with a different mode set with CMAKE_BUILD_TYPE as in
cmake -DCMAKE_BUILD_TYPE=DEBUG <sourcedir>
You never set those flags directly. If you want to add a new flag to a debug mode like for example a stack protector, you should use the *_INIT variables.
You can further distinguish which OS you are running with the UNIX, WIN32 and MSVC cmake boolean predefined constants:
if ( UNIX )
set( CMAKE_CXX_FLAGS_DEBUG_INIT "-fstack-protector" )
elseif( WIN32 )
set( CMAKE_CXX_FLAGS_DEBUG_INIT "/GS" )
endif()
There should be no need to define -O3 and -g explicitly in cmake. Setting those may prevent the code from working with other compilers, as you've seen. Those 2 options are the default anyways.
To build one of the configurations using unix makefiles you simply set the CMAKE_BUILD_TYPE cache variable during configuration:
(I'm assuming the generators mentioned are the default generators below.)
cmake -D CMAKE_BUILD_TYPE=Debug -S ... -B buildDir
or
cmake -D CMAKE_BUILD_TYPE=Debug -S ... -B buildDir
and to build the project you use
cmake --build buildDir
The visual studio is differnet insofar that the generated project covers all configurations at once. You specify the configuration to work with when building (or installing) the project instead:
cmake -A x64 -S ... -B buildDir
cmake --build buildDir --config Release
cmake --build buildDir --config Debug
Alternatively you can simply open the generated solution in the IDE.
cmake --open buildDir
For compiler specific flags you may need to make a case distinction:
if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
add_compile_options(/Wall)
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
add_compile_options(-Wall)
endif()
I am developing an own open source programming language interpreter project and I can make silly mistakes as I am not sophisticated in Cmake and I am trying Travis CI for the first time. My project compiles on my PC (running Ubuntu 16.04LTS, GCC 8.1 and Cmake 3.12.0-rc2) from bash terminal by executing scripts/build_all.sh and tests are executed by scripts/run_tests.sh.
Build script creates a cmake-build-debug directory, runs cmake and than builds and executes simple cmake-build-debug/lexertl_gen/lexert_gen.out program to generate a header file in my include folder for the main project. After that it builds the main project alongside with it's tests all under compiler option std=gnu++2a.
Here are all my CMakeLists.txt (the problem is described bellow):
Root CMakeLists.txt
cmake_minimum_required(VERSION 3.9.0)
set(INCLUDE_ROOT "/usr/local/include")
set(BOOST_ROOT "${INCLUDE_ROOT}/boost_1_67_0")
set(LEXERTL_ROOT "${INCLUDE_ROOT}/lexertl")
set(GTEST_ROOT "${INCLUDE_ROOT}/googletest")
set(CMAKE_CXX_FLAGS "-g -std=gnu++2a -Werror \
-Wno-error=variadic-macros \
-Werror=implicit-fallthrough")
file(GLOB SOURCES "src/*.cpp")
include_directories(include ${BOOST_ROOT} ${LEXERTL_ROOT} ${GTEST_ROOT})
add_library(calamity_core ${SOURCES})
project(lexer.out)
add_executable(${PROJECT_NAME} main_lexer.cpp)
target_link_libraries(${PROJECT_NAME} m calamity_core)
project(parser.out)
add_executable(${PROJECT_NAME} main_parser.cpp)
target_link_libraries(${PROJECT_NAME} m calamity_core)
project(tests.out)
add_subdirectory(tests)
project(lexertl_gen.out)
add_subdirectory(lexertl_gen)
tests/CMakeLists.txt
cmake_minimum_required(VERSION 3.9.0)
set(CMAKE_CXX_FLAGS "-g -std=gnu++2a -Werror \
-Wno-error=variadic-macros \
-Werror=implicit-fallthrough")
add_subdirectory(/usr/local/include/googletest ../gtets-build)
add_executable(${PROJECT_NAME} tests.cpp)
target_link_libraries(${PROJECT_NAME} gtest gtest_main gmock calamity_core)
lexertl_gen/CMakeLists.txt
cmake_minimum_required(VERSION 3.9.0)
set(CMAKE_CXX_FLAGS "-g -std=gnu++2a -Werror \
-Wno-error=variadic-macros \
-Werror=implicit-fallthrough")
set(SOURCES ../src/token.cpp
../src/var_substring.cpp
../src/cui.cpp
../src/message_exception.cpp)
add_executable(lexertl_gen.out main_lexertl_gen.cpp ${SOURCES})
Ultimately, I decided to add Travis CI to my project. I wrote a bootstrap.sh script to install and configure all dependencies (I also install GCC 8.1, because default GCC 4.8.4 installed on Travis CI server doesn't support gnu++2a). This script works well, but when it comes to running scripts/build_all.sh on Travis CI server GCC fails to set gnu++2a for compiling my main project with tests, it complains about using inline variables, std::is_integral and other modern C++ stuff, explicitly mentioning that those features are supported under std=c++17 or std=gnu++17. Here is the link to my latest unsuccessful build on Travis CI.
I don't get it, as I updated GCC and my first simple code generator program runs well (though if I remove set(CMAKE_CXX_FLAGS ...) from tests/CMakeLists.txt this program compiles on my PC but doesn't compile on Travis CI server either). What's wrong am I doing here? Is it because of the Cmake 3.9 which Travis uses?
My .travis.yml configuration file:
language: cpp
sudo: required
dist: trusty
compiler:
- g++
os:
- linux
script:
- ./bootstrap.sh; cd scripts; ./build_all.sh; ./run_tests.sh
env:
global:
- LANG="en_US.UTF-8"
matrix:
include:
- os: linux
addons:
apt:
compiler: gcc
sources:
- ubuntu-toolchain-r-test
packages:
- g++-8
env: COMPILER=g++-8
Link to my project on GitHub. (sorry for empty README.md)
Well I've finally solved a problem by making CMAKE_CXX_FLAGS a cache variable:
set(CMAKE_CXX_FLAGS "-g -std=gnu++2a -Werror \
-Wno-error=variadic-macros \
-Werror=implicit-fallthrough"
CACHE STRING "compiler flags")
Though I don't think it is a beautiful solution and I still can't understand why it compiled on my PC but not on Travis CI
I am trying to get conan working in a test project by following their Geting Started guide so that I can begin using it in a real project. I am attempting to use SDL2 with glew in a C++ project compiled with g++ on Ubuntu 16.10 x64.
My conanfile.txt looks like this:
[requires]
SDL2/2.0.5#lasote/stable
glew/2.0.0#coding3d/stable
[generators]
cmake
My CMakeLists.txt file looks like this:
project(conantest)
cmake_minimum_required(VERSION 3.5)
set(CMAKE_CXX_STANDARD 11)
include(conan/conanbuildinfo.cmake)
conan_basic_setup()
set(SRC_FILES main.cpp Display.cpp)
add_executable(conantest ${SRC_FILES})
My project consists of a directory containing CMakeLists.txt, conanfile.txt, all of my source code, a build directory for Cmake, a conan directory for Conan, and a rebuild.sh. I am using this rebuild.sh script to clean and build the project whenever I make a change to the build environment (the rm -r's, although suboptimal once it is working are there to ensure any errors from the previous setup are removed once I attempt a fix).
My rebuild.sh looks like this:
rm -r ./build/*
rm -r ./conan/*
cd conan
conan install ..
cd ../build
cmake ..
make
When I run this script, everything seems to be working until the
final executable is linked. When this happens, I get Display.cpp:(.text+0x8a): undefined reference to `SDL_Init'. To solve this, I have tried the solutions here and here. Although these are not specific to SDL, I was unable to find any resources that are.
Here is a zip file of the full environment that I am using, including a MCVE.
You need to tell CMake to link against the libraries yourself, since conanbuildinfo.cmake cannot know the name of your target.
Simply adding this line to the bottom of your CMakeLists.txt file will work:
conan_target_link_libraries(conantest)
This command will call target_link_libraries for all dependencies specified in the conanfile.
Here's another CMakeLists.txt example if you would like to use a more "modern" CMake approach which focuses more on targets instead of global settings:
cmake_minimum_required(VERSION 3.5)
project(conantest)
include(conan/conanbuildinfo.cmake)
conan_basic_setup(TARGETS)
add_executable(conantest main.cpp Display.cpp)
set_property(TARGET conantest PROPERTY CXX_STANDARD 11)
target_link_libraries(conantest CONAN_PKG::SDL2 CONAN_PKG::glew)
I want to find GTest via:
find_package(GTest REQUIRED)
But it is not found:
Error:Could NOT find GTest (missing: GTEST_LIBRARY GTEST_INCLUDE_DIR GTEST_MAIN_LIBRARY)
I know from this link that GTest should be distributed via standard CMake.
Can you tell me what I did wrong?
If you're on Ubuntu, you should read /usr/share/doc/libgtest-dev/README.Debian. It says:
The Google C++ Testing Framework uses conditional compilation for some
things. Because of the C++ "One Definition Rule", gtest must be
compiled with exactly the same flags as your C++ code under test.
Because this is hard to manage, upstream no longer recommends using
precompiled libraries
So you should compile and install your own version of the gtest library with the exactly same Compiler Options, and set the GTEST_LIBRARY or GTEST_ROOT variable accordingly.
For example, I did the following:
$ mkdir -p ExternalLibs/gTest
$ cd ExternalLibs/gTest
$ cmake /usr/src/gtest
$ make
Then I added the following lines in my CMakeLists.txt:
set (GTEST_ROOT ${CMAKE_SOURCE_DIR}/ExternalLibs/gTest)
find_package(GTest REQUIRED)
find_package does not look in CMake's installation directory. It only evaluates the PATH and CMAKE_PREFIX_VARIABLES. Just add the path to CMake's GTest to the latter variable, clear your CMake cache and re-run CMake.
If you have gtest installed you can just do:
add_subdirectory("/usr/src/gtest" ${CMAKE_BINARY_DIR}/gtest)
enable_testing()
include_directories(${GTEST_INCLUDE_DIRS})
add_executable(test test.cpp)
target_link_libraries(test gtest gtest_main)
add_test(AllTests test)
I've compiled a C++ static library by using CMake as my building tool and I want to link it to my iOS app.
I created a simple 'Empty' application in Xcode and linked my library called libengine.a to it.
I tried to compile my iOS project and the linker gave me this warning:
ignoring file /Users/.../build/engine/libengine.a,
file was built for archive which is not the architecture being linked (i386):
/Users/.../build/engine/libengine.a
As I understand it, I need to compile my library for ARM processors. The problem is I don't know how.
I think CMake really lacks good tutorials.
Anyways, my CMake scripts are attached below.
Any help would be greatly appreciated.
Thanks, Tal.
Here is my main CMake script:
cmake_minimum_required(VERSION 2.8)
project(movie-night)
if (DEFINED PLATFORM)
include(toolchains/ios.cmake)
endif()
add_definitions(-Wall)
set(DEBUG)
if (DEFINED DEBUG)
add_definitions(-g)
endif()
if (DEFINED RELEASE)
add_definitions(-O3)
endif()
add_subdirectory(engine)
add_subdirectory(ui)
add_subdirectory(test)
Here is my toolchains/ios.cmake file:
set(CMAKE_SYSTEM_NAME Darwin)
set(CMAKE_SYSTEM_PROCESSOR arm)
Just use this toolchain file: http://code.google.com/p/ios-cmake/ and use it as
cmake -DCMAKE_TOOLCHAIN_FILE=path_to_your_toolchain_file
Then, in CMakeLists.txt:
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -arch armv7")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -arch armv7")
By following cmake-toolchains documentation I did like below:
cmake -G Xcode -B build \
-DCMAKE_SYSTEM_NAME=iOS \
-DCMAKE_Swift_COMPILER_FORCED=true \
-DCMAKE_OSX_DEPLOYMENT_TARGET=11.0
Note: That assignment CMAKE_OSX_DEPLOYMENT_TARGET=11.0 is not a mistake when targeting iOS.
I've been using an updated version of the iOS CMake toolchain for quite a while: https://github.com/leetal/ios-cmake
This creates an Xcode project which you can drag into an existing iOS project if necessary.
I wrote a blog post with more details: https://blog.tomtasche.at/2019/05/how-to-include-cmake-project-in-xcode.html
There is a second version of iOS.cmake located at:
https://ceres-solver.googlesource.com
Note: You may find that both versions of iOS.cmake will only build x86 versions of your project. CMake now sets CMAKE_OSX_SYSROOT to the (latest) Mac OS X SDK available on your system. You can fix this by modifying your copy of iOS.cmake to always set CMAKE_OSX_SYSROOT. You can do this by commenting out a couple of lines your copy of iOS.cmake:
# -- Under CMake 3.4.2, CMAKE_OSX_SYSROOT is automatically defined to point to the latest Mac OS X SDK. --
# -- So, the iOS SDK is never found. Grab the correct CMAKE_OS_SYSROOT and ignore any prior setting. --
# If user did not specify the SDK root to use, then query xcodebuild for it.
# if (NOT CMAKE_OSX_SYSROOT)
execute_process(COMMAND xcodebuild -version -sdk ${XCODE_IOS_PLATFORM} Path
OUTPUT_VARIABLE CMAKE_OSX_SYSROOT
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE)
message (STATUS "Using SDK: ${CMAKE_OSX_SYSROOT} for platform: ${IOS_PLATFORM}")
message (STATUS "be sure the previous line points to the correct SDK")
# endif ( )