Confusion surrounding preprocessor build flags / #ifdefs with cmake and clion


#1

I’ve been stuck for a few days on porting a Clion (Arduino cmake) project for use with Clion and PlatformIO.

After much back and forth, I think I found my first issue – it appears that PlatformIO’s “build_flags” are the only thing the preprocessor pays attention to.

For instance, in my CMakeLists.txt file I may have:

add_definitions(-DUSE_NEOPIXEL_LEDS)`

This is confirmed when I have cmake message out the COMPILE_DEFINITIONS. This was working very well under CLion with Arduino CMake.

However, after lots of trial and error, under platformIO 3.4.0b12 (CLion 2017 1.3 / CMake 3.7) the following include guard code was not working:

#ifdef USE_NEOPIXEL_LEDS
    #include "Adafruit_NeoPixel.h"
#endif
#ifdef USE_WS2801_LEDS
    #include "Adafruit_WS2801.h"
#endif

I even put the add_definitions() call in various places in the CMakeLists.txt file, to no avail.

Finally, I stumbled upon a topic on the Dependency Manager and found that by using:

[env:nanoatmega328]
build_flags = -D USE_NEOPIXEL_LEDS -D 
platform = atmelavr
board = nanoatmega328
framework = arduino

Now the include guard works.

And now I have questions and there seems to be very little documentation.

  1. What is the relationship between cmake and platformIO?
  2. Can platformIO’s build_flags derive from cmake in some way?
  3. Does platformIO have anything similar to cmake’s option() method followed by if/endif? Or is the preferred method to simply setup multiple environments with the different build settings already built up?
  4. How come build_flags does not work in the [common] section in platformio.ini ?

#2

Please take a look at documentation and “Warning” blocks:

The same, see documentation for Dynamic Flags:

If you put options to a custom section, then it should be used in appropriate build environment via build_flags = ${common.build_flags}.


#3

ivankravets,

Thanks! Our other thread seemed to answer many of the questions. For those watching

  1. Use platformIO and the platformio.ini file. Jump in, and leave the thought of controlling cmake behind.
  2. No. Don’t attempt to drive build flags into platformIO from a cmake file. Use the platformio.ini file for that.
  3. I think the the section on dynamic variables is key for really driving the platformio.ini file. This means creating a lot of environments (for debug / release). This raises a question: SEE BELOW
  4. Same as #3

Defining CLion Targets for Specific Builds

Let’s assume I get my platformio.ini file all setup with various environments: e.g.

[env:nanoatmega328]
build_flags =  USE_NEOPIXEL_LEDS -D USE_U8GLIB_GRAPHICS 
lib_ldf_mode = chain+
platform = atmelavr
board = nanoatmega328
framework = arduino
upload_port = /dev/cu.usbmodem1421
lib_deps_external = Adafruit_NeoPixel, U8glib_mizraith
[env:nanoatmega328-debug]
build_flags = -D DEBUG_MODE=1 -D USE_NEOPIXEL_LEDS -D USE_U8GLIB_GRAPHICS -Wno-unknown-pragmas
lib_ldf_mode = chain+
platform = atmelavr
board = nanoatmega328
framework = arduino
upload_port = /dev/cu.usbmodem1421
lib_deps_external = Adafruit_NeoPixel, U8glib_mizraith

Looking in the CMakeLists.txt file, the targets setup by platformIO look like this:

add_custom_target(
    PLATFORMIO_BUILD ALL
    COMMAND ${PLATFORMIO_CMD} -f -c clion run
    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)

But what if I would like two different targets: PLATFORMIO_BUILD and PLATFORMIO_BUILD_DEBUG? I don’t want to build ALL each time. I would like to instead build and upload one or the other. For instance:

add_custom_target(
    PLATFORMIO_BUILD nanoatmega328
    COMMAND ${PLATFORMIO_CMD} -f -c clion run
    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)
add_custom_target(
    PLATFORMIO_BUILD_DEBUG nanoatmega328-debug
    COMMAND ${PLATFORMIO_CMD} -f -c clion run
    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)

My options to achieve this appear to be:

  1. Modify the cmake file. But this is pointless (platformIO will overwrite it).
  2. Add the target specifically in CLion, but I’m not sure how too go about calling the COMMAND correctly.
  3. Ask you for advice… put it in CMakeListsPrivate.txt?

Thanks in advance


#4

I hope we will introduce Project Templates and new Project Generator which will have better behavior and will not overwrite all configuration files.

PlatformIO IDE for Atom and VSCode has different tasks/targets where you can switch between them. In your case, the easiest way is a switching of environment using http://docs.platformio.org/en/latest/projectconf/section_platformio.html#env-default

P.S: According to the new Cmake target, the correct format is

add_custom_target(
    PLATFORMIO_BUILD_DEBUG ALL
    COMMAND ${PLATFORMIO_CMD} -f -c clion run -e nanoatmega328-debug
    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)

P.S.S: Also, you can run directly from Clion Terminal pio run -e nanoatmega328-debug