Handling preprocessor macro in a single header file? - c++

In my c++ project, I have some preprocessor macro commands.As an example:
#define ENABLE_PHOTO_SENSOR //will be put in three source file (.cc file)
#define SAVE_ROOT_FILE //will be placed 6 source file
...
Should I have to put all these macro commands in a single header file? If I do like this, when I change one of the macro commands(example undef one macro) and compile the program again, all the source files including those header files are compiled again. If I use separate header file for each macro command, only related source file compiled. But what I want is to control all the macro commands from a single file and when I change a macro command, only the files related to that macro commands are changed.
Finally, I am using cmake to generate make files. Is it possible to change these macro commands in the build directory?If it is how?

Related

Make a version file of macros which run at compile time

I want to ask if I can make a file of macros that basically defined at compile time and use these macros in my c++ code which compiles specific code if the condition is true. SO what is basically the extension for that file is it a .txt file or a .h file. and how to put this file in CmakeList.txt to make it executable at compile time. for example like this in a specific file?
#define melodic 1
#define noetic 2
A C++ macro is a shortcut for writing code, what happens when you compile your project is that this code:
#define SOMETHING 32
int i = SOMETHING
Is changed to before it is compiled:
int i = 32
So a macro just substitutes text wherever you place it. There is also another use of macros that maybe is what you are looking for. You can use the preprocessing directive #ifdef MACRO to compile some code conditionally. For example, let's say that you have a function that is only there for debugging, but you don't want that code to make it to release. You could define it like:
void hello() {
#ifdef DEBUG
print("debug");
#endif
}
Then, if that file has a #define DEBUG before the #ifdef macro, the code will be included. Otherwise, the code will be discarded. Note that to use #ifdef the macro body may be empty or not, it just checks if the defined directive was used.
What you might want to accomplish is to have a series of preprocessor macros that you either set or don't in a separate configuration file to change the code produced. They are a very powerful tool, but they must be use with caution since having too many can make code not very readable.
To accomplish that, you need to include the #define MACRO in the same file that you are checking if it is defined, and before you check it. If you are only using that macro in that file, it would be good to place it at the top of it, but if you use it on multiple files you can create a header file (.h) and use #include "name.h", since include copies the contents of the header file there, therefore adding the macro definitions to your file.
The preprocessor directives are dependent on the compiler, so the version and type of compiler you use (gcc, clang...) will have different support for them. However, defined and ifdef are very widely spread and most if not all compilers have them. I recommend reading more about directives, for example here.
Finally, in case you go the route of the .h file, you would add it like any other header file you have in your project to the CmakeList.txt.

compile a cpp file with multiple different header files

I have a single cpp file and multiple hpp files. For each hpp file, I want to create an executable using the same cpp file. The header files have different names. Can I do this in CMake?
So I have
source_1.cpp
header_1.hpp
header_2.hpp
...
and I want to create
executable_1
executable_2
...
The C++ preprocessor can use macros for #include.
That is, you can have something like:
#include HEADER_FILE_TO_INCLUDE
Then when building the source file you could define the macro on the command-line:
g++ -DHEADER_FILE_TO_INCLUDE="\"header_1.hpp\"" source_1.cpp
To do this with CMake you first of all need multiple executable targets, where you specify the same source file for each target.
Then you can use target_compile_definitions to specify the macro and the header file to use.
Something like
add_executable(executable_1 source_1.cpp)
target_compile_definitions(executable_1 HEADER_FILE_TO_INCLUDE="header_1.hpp")
add_executable(executable_2 source_1.cpp)
target_compile_definitions(executable_2 HEADER_FILE_TO_INCLUDE="header_2.hpp")
If all header files are named header_X.hpp, with X just being a sequence number, then you could easily create a loop from 1 to the max value of header file numbers.

how to use macro definitions that are defined in a headerfile(.h) file in a makefile in linux

I have written certain macros in a headerfile(.h)file. I want those macros to be used in a makefile in linux OS. How can i declare (or) get that macro definitions from a header file in to a makefile.
I have added the file using "-include" in a makefile, but i could not read the macro definitions.
You can't. Header files are for C code.

Eclipse C exclude header file in build configuration

In Eclipse, using CDT.
Is there a quick way to have two identical build configurations, but in one configuration to use only src/foo.h and in the other only src/bar/foo.h ?
The src/ dir has lots of other header files, and I am optimistically hoping to not have to add them all one by one when only one file is actually different.
I also don't really want to move either of the files or modify them, since they are not libraries or directory structures that I have written myself.
(If i really have to, then I guess I have to sort it out)
I suppose some sort of "exclude" list would be ideal. Does that exist?
Define a macro which tells you which build configuration your are building for and then use that to decide which file to include.
Right-click on your project, choose Properties. Then in the dialog which pops up choose C/C++ Build, then Settings. You should end up in a view which let's you define preprocessor definitions (macros).
Then in your header file either do the following:
#ifndef MY_MACRO
// contents of header file only available when MY_MACRO is NOT defined
#endif
Or you can (and should probably) do at the point of inclusion instead, so for this is a source file:
#ifdef MY_MACRO
# include "bar.h"
#else
# include "foo/bar.h"
#endif
If you include the header file from several source files and do not want to copy the above-mentioned lines you can add another header which does the inclusion for you by just copy-pasting the lines above and then including that header everywhere.

Preprocessor switch determining version of a class

I have a class with two possible implementations, depending on a preprocessor switch. The way I have handled this is to create "src\CompSwitch1\class.h" and "src\CompSwitch2\class.h". In my standard include file, I use
#ifdef CompSwitch1
#include "CompSwitch1\class.h"
#elif CompSwitch2
#include "CompSwitch2\class.h"
#else
#error "Specify CompSwitch1 or CompSwitch2"
#endif
This works for most of my classes that need two versions. However, on one of them, I get a linker error (lnk2019: unresolved external symbol). I'm using MS Visual Studio 2005 and 2008, and it appears on both of them.
At the top of the .h file, I test against the preprocessor option.
Also, although I only referenced the .h file for brevity, there is also a .cpp file for each of these, in the appropriate directory.
It sounds like you might have included the header file for one of the classes, but linked the object file for for the other one, or neither
it should really be #ELIF DEFINED( CompSwitch2 ) really. Otherwise you are assuming "CompSwitch2" has been defined with a value of 1 ...
Try to put in the cpp implementation files after they include your header the following preprocessor line(s):
//in compswitch1.cpp
#ifndef CompSwitch1
# error "inconsistent header included"
#endif
//in compswitch2.cpp
#ifndef CompSwitch2
# error "inconsistent header included"
#endif
If you compile wrong header/cpp pairs you should get at least compilation errors and not linking errors. There are much easier to identify/fix ;)
Another possibility is that the cpp-files are not included into compilation at all. Put a message pragma inside the cpp file to see if they get compiled at all:
#pragma message( "Compiling " __FILE__ )
Or try to identify in the build directory if there object files created, which relate to cpp-compilation units.
Hope that helps,
Ovanes
You can use preprocessed cpp file (stage where all includes and macros are expanded).
In VS 2008 right click on your file in Solution Explorer->Properties->C++->Preprocessor and set "Generate Preprocessed File" set "With Line Numbers (/P)".
After that right click again your file and choose "Compile". File with extension "i") (e.g. main.i) will be created in the same directory where cpp resides. Open it and see which include file is included.
This method is very handful to solve hard compilation problems (e.g. some macro from system header files replaces something in your code).