Clion: How to define debug level? - c++

I have the following debug statements in my code:
#if (DEBUG_LEVEL > 0)
printf("ITER %d\n", iter);
#endif
How can I define debug level in Clion debugger? And do I need to use CMAKE?

Add the following to your CMakeLists.txt:
if (DEBUG_LEVEL)
add_definitions(-DDEBUG_LEVEL=${DEBUG_LEVEL})
endif()
It basically says: "If you have "DEBUG_LEVEL" CMake variable defined, pass the DEBUG_LEVEL=X preprocessor definition to the compiler"
Pass the desired value of the variable (e.g. -DDEBUG_LEVEL=1) to CMake (in CLion it can be done via Options | Build, Execution, Deployment | CMake | CMake options).
This way you need to edit your CMakeLists.txt once, but then you can change the actual value without touching the source code.
I guess you can hack it around without touching CMakeLists.txt at all, but the approach above seems more straightforward and idiomatic.

Related

CMake command line define macro without value

I have the following line in my CMakeLists.txt
add_compile_definitions(DEBUG=$(DEBUG))
so when I compile my code with Makefile, I can do this
make DEBUG=1
But what I really want is to just define the DEBUG macro without setting any value to it.
Is there a way I can do this on a command line with cmake?
With CMake you can, at configuration time, add some CMake variables. For example you can do this cmake -S <src_folder> -B <build_folder> -DDEBUG=ON. This way you will have access to the variable DEBUG in your CMake.
In your CMake you will have this code
if(DEBUG)
add_compile_definition(DEBUG)
endif()
(Note that instead of add_compile_definitions, it is recommended to use target_compile_definitions which will set your DEBUG macro only for one target and not globally to your project.
Example:
add_executable(my_target main.cpp)
target_compile_definition(my_target PRIVATE DEBUG)
PRIVATE means that this compile_definition will only be used by the target my_target and will not be propagated to others.)
But if you're only concern of the building type, I suggest that you use CMake variables that are already present within CMake. You can use CMAKE_BUILD_TYPE which will contains Debug, Release or whatever depending on what type of build you want. Your code will now be this
if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
add_compile_definition(DEBUG)
endif()
And you can use this command line cmake -S <src_folder> -B <build_folder> -DCMAKE_BUILD_TYPE=Debug
And here the documentation https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type
Note that this solution will only works for Mono-config generators like Makefile or Ninja and will not works with Visual Studio or Xcode

How to use DEBUG macro with cmake?

I'm new to cmake, so up front, my apologies this question is too basic ..
Question is,
I have logs under #ifdef DEBUG which I want to print only for debug build.
Something like this ..
void func () {
// some code here
#ifdef DEBUG
print_log(...) // this portion should execute only for debug builds
#endif
// some code here
}
How can I achieve this with cmake ?
I have already looked at #ifdef DEBUG with CMake independent from platform and cmakelists debug flag not executing code within "ifdef DEBUG", suggestions here don't seem to work for me.
(project is on Linux platform)
Modern CMake uses a target-based approach which allows you to specify settings that are restricted to a target as opposed to being global (and affecting all targets). This then gives you the control to specify how the state from targets propagates transitively to dependent targets so as to reduce the visible scope of the state (include paths, library dependencies, compiler defines, compiler flags, etc) to dependent targets. The approach you decide to go with will depend largely on how complex your application is, for instance, how many targets (executable & libraries) exist in the system. The more complex the system the more benefits you in terms of reduced complexity and compile time that you will get from using the target-based approach. In the simplest case to set this up with the modern target based CMake approach you could use the following (where exe is the name of your executable:
add_executable(exe "")
target_sources(exe
PRIVATE
main.cpp
)
target_compile_definitions(exe
PRIVATE
# If the debug configuration pass the DEBUG define to the compiler
$<$<CONFIG:Debug>:-DDEBUG>>
)
Added set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG") to CMakeLists.txt
Created Debug/ directory & cd Debug
cmake -DCMAKE_BUILD_TYPE="Debug" ../
Worked !

CMake won't build without set_source_files_properties with LANGUAGE CXX

I have a small library that I have made (mostly wrappers for a more obtuse library underneath) which I have been compiling and using no problem in a contained project. I am now using this library in another project and have attempted to change the CMakeLists.txt appropriately (see below).
cmake_minimum_required (VERSION 3.5)
set(project "foobar")
project(${project} LANGUAGES CXX)
set(${project}_VERSION_MAJOR 0)
set(${project}_VERSION_MINOR 1)
add_library(${project} SHARED
./driver/foo.h
./driver/foo.c
./bar.cpp
./bar.hpp)
set_source_files_properties(./driver/foo.c PROPERTIES LANGUAGE CXX)
target_compile_features(${project}
PUBLIC
cxx_std_11)
target_include_directories(${project} PUBLIC ./driver/ .)
set_target_properties(${project} PROPERTIES LINKER_LANGUAGE CXX)
add_executable(bno055-test
./testingProject.cpp
)
target_link_libraries(test ${project})
install(
TARGETS ${project}
RUNTIME DESTINATION bin)
The error I have encountered is with the line set_source_files_properties(./driver/foo.c PROPERTIES LANGUAGE CXX). When it comes to compiling this C file with the C++ flag above I get many warnings of the type clang-8: warning: treating 'c' input as 'c++' when in C++ mode, this behavior is deprecated [-Wdeprecated]. This is expected, as I am using deprecated methods and should not be compiling this file using the C++ flag. However, whenever I remove this line, or alter it to specify C instead of C++, my entire project no longer builds and fails with error:
CMake Error: Error required internal CMake variable not set, cmake may not be built correctly.
Missing variable is:
CMAKE_C_COMPILE_OBJECT
-- Generating done
CMake Generate step failed. Build files cannot be regenerated correctly.
Makefile:283: recipe for target 'cmake_check_build_system' failed
make: *** [cmake_check_build_system] Error 1
"/usr/bin/make -j4 all" terminated with exit code 2. Build might be incomplete.
I'm not familiar enough with CMake to see why this line of code and error are related like this. Is there some alternative piece of code I should include to create the missing variable CMAKE_C_COMPILE_OBJECT?
I assume that when I initially created this project using Eclipse this line was automatically generated and I am unclear as to why it now creates a problem when I had been compiling these files with the same CMakeLists.txt before (without library linking).
This is with clang#8.0.0 on Ubuntu 16.04.
Any help would be much appreciated! Apologies if I have missed something simple!
Is there some alternative piece of code I should include to create the missing variable CMAKE_C_COMPILE_OBJECT?
No, as the CMake error states, this is an "internal CMake variable" which should be initialized by CMake. It is not something you should have to set yourself. It should be set indirectly when you call project(). However, you only tell CMake you are using C++ (with CXX option) in the project() command. If you want CMake to make use of C and C++, you need to add both:
project(${project} LANGUAGES C CXX)
Even better, CMake enables C and C++ by default, so you can simply do:
project(${project})

Appending CXX_FLAGS in cmake invocation [duplicate]

This question already has answers here:
Passing compiler options in CMake
(6 answers)
Closed 5 years ago.
I am wondering if it is possible to append to inferred variables when calling cmake. Due either the compiler or the app supplied CMakeLists.txt C++11 support isn't detected by cmake even though it is supported and the application requires it. If I do:
cmake-DCMAKE_CXX_FLAGS='-std=c++11' ../source_dir
The flags get overwritten and I wouldn't like to lose the inferred flags. I could manually run without overwriting and just copy the flags and append c++11 but I think there must be a better solution.
I have found a number of posts on adding c++11 support to CMakeLists.txt but not in cmake call, so I am wondering if this is possible at all. Please let me know.
Yes, this is possible. First, create a variable called MY_FLAGS in the command line with the flags you want.
cmake -DMY_FLAGS='-std=c++11' ../source_dir
Then, in your CMakeLists.txt, do the following:
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${MY_FLAGS}")
This will effectively amend your flags to the flags that CMake generates. However, if you want to set the C++ standard to C++11, you can just do the following without directly dealing with flags:
cmake -DCMAKE_CXX_STANDARD=11 -DCMAKE_CXX_STANDARD_REQUIRED=ON ../source_dir
On a side note, make sure that the ../source_dir is after the CMake options, since otherwise CMAKE_CXX_STANDARD_REQUIRED would not work. (Read)
I recently did this, when building a dependency for one of the applications I work to.
There are 2 CMake variables that you can make use of, namely:
-DCMAKE_BUILD_TYPE=Debug/Release
-DCMAKE_CXX_FLAGS_[DEBUG/RELEASE]
When specifying a build type, cmake will add to the compiler flags the flags that are specified in that second variable. So for me, using:
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_FLAGS_RELEASE=-fPIC
did the thing.
In your case, you can try the following approaches:
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS_RELEASE=-std=c++11
or
cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_FLAGS_DEBUG=-std=c++11
Of course, this will work if the variables are not overwritten in the script. Try both approaches.
You are probably looking for
set (CMAKE_CXX_STANDARD 11)
set (CMAKE_CXX_STANDARD_REQUIRED ON)
Or via command line:
cmake -DCMAKE_CXX_STANDARD=11 -DCMAKE_CXX_STANDARD_REQUIRED=ON
That being said, CMAKE_CXX_FLAGS is not overridden by cmake, so your CMakeLists.txt must be doing it somewhere.
The polite way of setting the flags from within a script is to append to the variable, that is:
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} stuff")

How to add preprocessor definitions on CMake's command line? [duplicate]

I try to set a preprocessor macro in the command line of CMake. I've tried:
set generator="Visual Studio 8 2005"
set params=-D MY_MACRO=1
cmake.exe -G %generator% %params% ..\some_project
but it's neither defined when I compile nor can I find the name MY_MACRO in the files generated by CMake at all, except for CMakeCache.txt where it's present in the form:
MY_MACRO:UNINITIALIZED=1
How can I do it?
A good alternative would be to define a cmake option:
OPTION(DEFINE_MACRO "Option description" ON) # Enabled by default
Followed by a condition:
IF(DEFINE_MACRO)
ADD_DEFINITIONS(-DMACRO)
ENDIF(DEFINE_MACRO)
Then you can turn that option ON/OFF via command line with cmake using the -D flag. Example:
cmake -DDEFINE_MACRO=OFF ..
To make sure the compiler is receiving the definition right, you can call make in verbose mode and check for the macro being defined or not:
make VERBOSE=1
This is a good solution also because make will recompile your code when any of cmake options changes.
Try this: -D CMAKE_CXX_FLAGS=/DMY_MACRO=1
The motivation behind the question was to batch build 3rd party libraries, which is why I wanted to avoid modifying CMakeLists. So years later, even though I don't need that anymore, I figured out that it's easily achievable by means external to CMake:
Invoke CMake as usual, no special flags.
Then:
With MSVC: The compiler reads the CL environment variable to get extra command line arguments. So
set CL=/DMY_MACRO=1 %CL%
then invoke MSBuild to do its job.
With Makefiles: The generated makefiles use the CFLAGS and CXX_FLAGS variables as makefiles are expected to do. So the build can be started by
make CXX_FLAGS=-DMY_MACRO=1
or by setting the corresponding environment variables.
Unless you have a good reason not to, you should use ADD_DEFINITIONS(<name>=<value>[, ...]).
Just add the following line to your CMakeLists.txt:
ADD_DEFINITIONS("MY_MACRO=1")
CMake will take care of the syntax of the switches (be it -D<name>=<value>, or /D<name>=<value>).