2

I'm looking for a system to be able to configure my C++ project to compile some sections of codes and not others depending on what target hardware I'm compiling for. The area of development is software for computers onboard unmanned vehicles (e.g. drones, small fixed-wings, rovers). So, for example, if I'm building for a drone that has a certain set of sensors, and certain kinematics, I want only the code for the sensors that will be onboard that vehicle to compile. I know I can create feature flags with macros, such as something like:

#define ULTRASONIC_SENSOR_AVAILABLE 1
#define TARGET_VEHICLE_TYPE_DRONE 1
#define TARGET_VEHICLE_TYPE_ROVER 0
#define TARGET_VEHICLE_TYPE_PLANE 0

But this seems clunky and very error prone. There's also no way to store a certain "loadout" -- the exact set of flags that should be turned on or off for a specific, frequently built target.

Do any solutions exist that help with this problem?

4
  • Is it an ironic error that in questioning an error prone practice, that both "Rover" and "Plane" in your example have the same value for "Target_Vehicle_Type"?
    – Peter M
    Oct 21 at 12:52
  • @PeterM 0 is false. There is one true TARGET_VEHICLE_TYPE
    – Caleth
    Oct 22 at 13:47
  • @Caleth Yeah UI see now that they are binary switches - I was thinking in terms of a numerical selection value. But simple binary switches also raises the possibility that you can enable both Rover and Plane at the same time
    – Peter M
    Oct 22 at 15:37
  • @PeterM Precisely the problem I'm trying to solve! :)
    – bream
    Nov 1 at 21:23
3

There's also no way to store a certain "loadout" -- the exact set of flags that should be turned on or off for a specific, frequently built target.

The usual way to group feature flags is by defining (in your build target) a top-level selector macro, and having that enable all the relevant feature flags:

#if defined(SELECT_REAPER_MQ_9A)
#define TARGET_VEHICLE_TYPE_DRONE

#elif defined(SELECT_F22_RAPTOR)
#define TARGET_VEHICLE_TYPE_PLANE

#elif defined(SELECT_CURIOSITY)
#define TARGET_VEHICLE_TYPE_ROVER
#define ULTRASONIC_SENSOR_AVAILABLE

#endif

NB. you don't need to define something as zero to turn it off, you can just leave it undefined, and then check whether a flag is defined or not. This is much less noisy.

3

The usual way to compile code in or out in C++ is by #define. But pretty much every C++ compiler supports a -D flag for passing defines into a compilation, e.g.

-DULTRASONIC_SENSOR_AVAILABLE=1

So the answer is to create a number of different build files, one for each build, and store these under configuration control. Depending on your build environment, these could be makefiles, projects, configurations or whatever.

For example, Microsoft Visual Studio gives you "Debug" and "Release" configurations by default. You can duplicate those to create a series of different configurations.

0
0

If you have say 20 devices, each with a distinct set of features, then you write something like

#if Device_1
  #define Feature_3
  #define Feature_19
#endif

And to avoid mistakes

#if Device_1+Device_2…+Device20 != 1
  #error
#endif

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.