Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Defining preprocessor in modern CMake

I'm currently learning CMake and don't want to get bad habits since there is always 2 ways to do something in CMake (old way and modern way from what I have seen)

After reading some documentation about preprocessor in CMake and checking this post: Define preprocessor macro through cmake

I've come to the conclusion that I could either define a preprocessor as :

  • add_compile_definitions(FOO)
  • target_compile_definitions(myTarget PRIVATE FOO)
  • add_definitions(-DFOO)

and after some test they does actually all works as intended and define FOO

But now my question is what's the most "modern" way that I should use and what is really the difference between each functions, the only difference I noticed is that if I use target_compile_definitions(myTarget PUBLIC FOO) it then define FOOin parent target.

like image 833
Roknus Avatar asked Mar 05 '23 05:03

Roknus


1 Answers

The general trend in modern CMake is to move from global settings to target-centric settings. Based on this rule alone, target_compile_definitions() is the most modern approach. It also allows control of whether the settings are used in the target only (PRIVATE), in other targets consuming this target (INTERFACE), or both (PUBLIC). Internally, it works by modifying the target's properties COMPILE_DEFINITIONS and INTERFACE_COMPILE_DEFINITIONS.

Next down in terms of being modern is add_compile_definitions(). It adds the macro definitions to all targets defined in the current directory and subdirectories; its scope is similar to include_directories() in this regard. Internally, it works by modifying the COMPILE_DEFINITIONS property of the current directory. So: it's still using the correct "modern" mechanisms, but is directory-oriented instead of target-oriented.

At the bottom of the list, we have the very old function add_definitions(). This is really best avoided in modern CMake. While intended for specifying preprocessor definitions (hence its name), it actually allows passing arbitrary compiler options in (which is also why you need to specify -DFOO instead of just FOO as its argument). It tries to figure out whether the things passed in are actually preprocessor macro definitions, in which case they are moved into the directory's COMPILE_DEFINTIIONS property. If they are not identified as such (which can happen for macros with complicated replacement strings), they are left in the list of flags.

like image 53
Angew is no longer proud of SO Avatar answered Mar 23 '23 00:03

Angew is no longer proud of SO