C++ Macro defined from outside .cpp or .hpp - c++

I want to do something like an application that is build in debug or release mode.
Is it possible to define a macro outside the .cpp or .hpp?
I am using CMake. I have seen that add_definitions(...) is doing something like this. Shall I create two executables proj and proj_debug and for debug define a macro with add_definitions(...)? Is this a good approach? If not, how would you suggest me to do?

Use something like this:
target_compile_definitions(myproj PRIVATE $<$<CONFIG:Debug>:MY_DEBUG_MACRO>)
http://www.cmake.org/cmake/help/v3.0/manual/cmake-generator-expressions.7.html
http://www.cmake.org/cmake/help/v3.0/command/target_compile_definitions.html
http://www.cmake.org/cmake/help/v3.0/manual/cmake-buildsystem.7.html
This works with all generators and is the documented, right, supported way of doing it (and implemented by me :) ).

Man g++ http://linux.die.net/man/1/g++
Look for the -D option for defining macros
and you can configure your makefiles to set that option http://www.cmake.org/Wiki/CMake_Useful_Variables
set(CMAKE_CXX_FLAGS "-g -Wall -Dxxxx")

To define Macro in the different file can be done by following ways:
1) You can define Macro in any other .h file.
and include the file in .cpp file.
This can help you to define Macro in different file
To check the Macro for Debug and Release version use _Debug or _Release Macro.
2) Another way to do this is By using the way told by #Soren.
using set(CMAKE_CXX_FLAGS "-g -Wall -Dxxxx")

like this. Shall I create two executables proj and proj_debug and for debug
No need.
With cmake you can change the CMAKE_BUILD_TYPE variable when configuring your project. Then in your CMakeLists.txt you can do something like:
if(NOT CMAKE_BUILD_TYPE STREQUAL "Release")
add_definitions(-DMY_DEBUG_MACRO)
endif()
Then you can easily configure your project twice (in two directories): once with CMAKE_BUILD_TYPE set to Debug and once CMAKE_BUILD_TYPE set to Release.

Related

How do I get the C++ standard flag as a string in CMake?

I need to get the compiler flags that will be used to compile a target programmatically in CMake. I need these flags as a string because I need to pass them to an executable in a custom command that needs to know how the parent target was compiled because it propagates those flags. I know enabling compile commands generates a JSON that shows the compile command but I need that output in CMake itself.
project(foo LANGUAGES CXX)
cmake_minimum_required(VERSION 3.22)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
add_executable(bar bar.cpp)
# define COMPILE_FLAGS somehow such that it equals -std=c++17
add_custom_target(external
COMMAND external_exe --flags ${COMPILE_FLAGS}
)
I've looked at these previous questions:
Using something like this or this does print compile flags like "-Werror" but the standard flag is not printed
Setting the standard with set_property and then getting it returns "17". Similarly, I can get the CMAKE_CXX_STANDARD to also return "17"*
This is the exact problem I have but the answer doesn't help in CMake
These questions are also related but unhelpful: one, two, and three
Am I missing something or is there no way to get this information?
*Can I assume that getting the standard number (e.g. 17) and appending that to "-std=c++" will be portably valid? It works with g++ at least but I'm not sure about other compilers/platforms.
If you just need the compiler flag for choosing the C++ standard, try this:
set(COMPILE_FLAG ${CMAKE_CXX${CMAKE_CXX_STANDARD}_STANDARD_COMPILE_OPTION})
Alternatively, replace "STANDARD" in the code above with "EXTENSION" if you want to allow compiler-specific extensions.
I grepped through the CMake source code, and I found that variables like CMAKE_CXX17_STANDARD_COMPILE_OPTION are defined in files that tell CMake how to use different compilers.

Is there a cmake compile feature for c++17's charconv?

I have written some code that make use c++17's charconv, that I can compile just fine with g++ 9. Even though I have set the std to c++17 in my CMakeLists.txt, cmake insists on using c++ 7.5, which does not support charconv.
How do I tell cmake that I need a compiler that supports charconv ?
I see no switch in CMAKE_CXX_KNOWN_FEATURES.
Here is my CMakeLists.txt
cmake_minimum_required(VERSION 3.17)
file(GLOB CLIENT_SRC "srcs/*.cpp")
include_directories("includes")
add_executable(client ${CLIENT_SRC})
set_target_properties(client PROPERTIES OUTPUT_NAME "distff-client")
target_compile_features(client PUBLIC cxx_std_17 )
Not a cmake guy... and I don't really understand cmake's approach to compile features here. But in C++ in general, we now use feature-test macros to detect the presence of features. You're looking specifically for __cpp_lib_to_chars.
I think you want to require compilation of this program:
#if __has_include(<version>)
# include <version>
#elif __has_include(<charconv>)
# include <charconv>
#else
# error "neither <version> nor <charconv> available to test"
#endif
#ifndef __cpp_lib_to_chars
# error "tochars not implemented"
#endif
Which can probably be generalized to something you can configure_file() for an arbitrary library feature (just pull out the header name and the macro name, and probably also check for the macro having the minimum required value).
Either way, if you try_compile() the resultant source file, you could probably get the behavior you want?
Not a CMAKE expert, but the easiest would be to set the CXX environment variable. Like so:
export CXX="/usr/bin/x86_64-linux-gnu-g++-9"
see more at How to specify a compiler in CMake?

How to clear all defines from cmake?

I have project where I need some specific preprocessor definitions. Nothing less nothing more. I tried various solutions:
set(DEFINES MY_DEFINE)
target_compile_definitions(my_target PRIVATE ${DEFINES})
and
set(DEFINES -DMY_DEFINE)
add_definitions(${DEFINES})
even
set(DEFINES MY_DEFINE)
set_property(TARGET my_target PROPERTY CACHE COMPILE_DEFINITIONS ${DEFINES})
Every time cmake still injects some other defines:
WIN32
_WINDOWS
CMAKE_INTDIR="$(CONFIG)"
My target is static library and project generator is Visual Studio 2015 if it might influence anything. How can I get cmake to set only my defines?
Since those are platform specific defines in CMake, you can only remove them "globally" for your current CMakeList.txt scope (not for an idividual taret) with something like:
string(REGEX REPLACE "(-D|/D)[^ ]* " "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
Reference
Is Cmake set variable recursive?
In CMake, you can use remove_definitions for any definitions added via add_definitions. I'm not sure if that will work here, though, because cmake may not be adding them via add_definitions.
You could also potentially #undef those definitions at the very top of your C++ files. This is a little bit dirtier, but it might work.

CMake: Set different name for #cmakedefine variable

I know you can use CMake's configure_file to make CMake variables available to your program. For example, I can use
#define ${CMAKE_BUILD_TYPE}
resulting in
#define Release
However, to keep my code more readible, I would prefer to define
#define BUILD_TYPE_RELEASE
Is there a simple way to achieve this?
Here is a fairly simple way to solve it:
In CMakesLists.txt:
if (NOT CMAKE_BUILD_TYPE)
set (CMAKE_BUILD_TYPE Release)
endif (NOT CMAKE_BUILD_TYPE)
string (TOUPPER ${CMAKE_BUILD_TYPE} BUILD_TYPE_NAME)
configure_file (config.h.in config.h)
And in config.h.in:
#define BUILD_TYPE_${BUILD_TYPE_NAME}
I am, however, still curious if there is a more elegant solution.
This is more a question of your preferred programming style (configuration files vs. compiler definitions).
In your case I would use add_definitions() or directly modify/append COMPILE_DEFINITIONS directory property (using generator expressions also supports multi-configuration environments):
set_property(
DIRECTORY
APPEND
PROPERTY
COMPILE_DEFINITIONS "BUILD_TYPE_$<UPPER_CASE:$<CONFIG>>"
)
Most simplified Debug/Release Check
You can also check what compiler definitions CMake does pre-define. Without having to modify/add something to your CMakeLists.txt files you could simply check for NDEBUG definition (set for Release builds across platforms) in you C/C++ code:
#ifdef NDEBUG
...
#endif
References
CMake: How to pass preprocessor macros
How to check if a CMake build directory build type is Debug or Release?
What predefined macro can be used to detect debug build with clang?

port a variable form make to Cmake

Our Library uses Cmake while the Overall system uses Make file for build.
I want to port the value of a variable (preprocessor macro) defined in the makefile to Cmakefile and use it as preprocessor marco in source codes of my library.
How to do that?
You can define variable at CMake invocation like so:
cmake -DMY_VAR=ON <path_to_CMakeLists.txt>
Then later in your CMake file:
if (MY_VAR)
add_definitions(-DENABLE_MY_VAR)
endif()
And finally in your code:
#ifdef ENABLE_MY_VAR
// Your code
#endif