arduino-cmake
arduino-cmake copied to clipboard
Would not work under CLion with Arduino Nano 328 -- workaround found
I'm putting this here to help others that may be struggling with the same issue. I'm working on identifying a fix for arduino-cmake Downloaded CLion and the CLion-Arduino 1.2.1 plugin (which uses arduino-cmake), but wanted to get down my workaround for others to find.
I'll follow up with a possible workaround, but the crux of it is that the arduino-cmake doesn't seem to be able to process the new boards.txt format when there are core variants. I'm on a Mac (10.11) and have several Arduino SDK installs (1.06, 1.56, 1.6x) under /Applications. [ I truly wish the Arduino maintainers would reign in development efforts so that the SDKs don't all behave so differently and have arbitrarily different internal workings! ]
First Lesson -- arduino-cmake looks for /Applications/Arduino.app So rename your preferred SDK as "Arduino.app". Arduino 1.06 and 1.5+ have a different internal structure...but Arduino-Cmake seem stop handle this okay.
Second Lesson -- I tried at least a dozen different settings (CFLAGS, CXXFLAGS, ARDUINO FLAGS, etc etc), but kept getting a warning the the avr-g++ compiler was not getting the "-mmcu" flag. Sure enough, when you look at the cmake log, the line contains "-mmcu= " (nothing afterwards. Again, tried every setting....but was only able to compile under 1.06.
QUESTION: Is there an Arduino-Cmake setting that allows you to pass in a -mmcu flag to the avr-g++ compiler without deleting the other flags already built up?
Third Lesson -- something about the Clion-Arduino or the Arduino-Cmake process retains too much info, even after a quit. When I found a clear workaround, it was not reloading the boards.txt file. I seem to also not see a result from print_board_list() every time either. This inconsistency makes it very hard to debug. Workaround: I ended up going into the CMakeFiles directory and selectively deleting stuff (your mileage will vary).
Workaround steps to compile for nano328 on Arduino 1.5+ I opened the 1.08 boards.txt file and simply copied the nano328 section into the 1.5+ boards.txt file. It looks like this:
``
nano328b.name=Arduino Nano w/ ATmega328
nano328b.upload.protocol=arduino
nano328b.upload.maximum_size=30720
nano328b.upload.speed=57600
nano328b.bootloader.low_fuses=0xFF
nano328b.bootloader.high_fuses=0xDA
nano328b.bootloader.extended_fuses=0x05
nano328b.bootloader.path=atmega
nano328b.bootloader.file=ATmegaBOOT_168_atmega328.hex
nano328b.bootloader.unlock_bits=0x3F
nano328b.bootloader.lock_bits=0x0F
nano328b.build.mcu=atmega328p
nano328b.build.f_cpu=16000000L
nano328b.build.core=arduino
nano328b.build.variant=eightanaloginputs
Again -- if you don't see "nano328" from your print_board_list() call, then you'll need to do some cleaning of CMakeFiles
With the above workaround, I don't need to edit any of the internal arduino-cmake files and my CMakeLists.txt file looks like:
cmake_minimum_required(VERSION 2.8.4)
set(CMAKE_TOOLCHAIN_FILE ${CMAKE_SOURCE_DIR}/cmake/ArduinoToolchain.cmake)
set(PROJECT_NAME test_clion3)
project(${PROJECT_NAME})
print_board_list()
set(ARDUINO_SKETCH_FOLDER /Users/mizraith/Documents/ARDUINO_DEVELOPMENT)
link_directories(${ARDUINO_SKETCH_FOLDER}/libraries )
set(ARDUINO_DEFAULT_BAORD nano328)
set(ARDUINO_DEFAULT_PORT /dev/tty.usbmodem1411)
set(${CMAKE_PROJECT_NAME}_SKETCH test_clion3.ino)
generate_arduino_firmware(${CMAKE_PROJECT_NAME}
BOARD nano328
PORT /dev/tty.usbmodem1411)
`
Looking at the Arduino.cmake file, around line 822, inside the function get_arduino_flags, there is the line:
set(COMPILE_FLAGS "-DF_CPU=${${BOARD_ID}${ARDUINO_CPUMENU}.build.f_cpu} -DARDUINO=${ARDUINO_VERSION_DEFINE} -DARDUINO_${${BOARD_ID}.build.board} -DARDUINO_ARCH_AVR -mmcu=${${BOARD_ID}${ARDUINO_CPUMENU}.build.mcu}")
The worked for the old Arduino nano328 definition (see earlier post), as there is a "nano328.build.mcu=atmeta328p" line.
However, the new Arduino 1.6 boards.txt looks like this:
nano.name=Arduino Nano
nano.upload.tool=avrdude
nano.upload.protocol=arduino
nano.bootloader.tool=avrdude
nano.bootloader.unlock_bits=0x3F
nano.bootloader.lock_bits=0x0F
nano.build.f_cpu=16000000L
nano.build.board=AVR_NANO
nano.build.core=arduino
nano.build.variant=eightanaloginputs
## Arduino Nano w/ ATmega328
## -------------------------
nano.menu.cpu.atmega328=ATmega328
nano.menu.cpu.atmega328.upload.maximum_size=30720
nano.menu.cpu.atmega328.upload.maximum_data_size=2048
nano.menu.cpu.atmega328.upload.speed=57600
nano.menu.cpu.atmega328.bootloader.low_fuses=0xFF
nano.menu.cpu.atmega328.bootloader.high_fuses=0xDA
nano.menu.cpu.atmega328.bootloader.extended_fuses=0x05
nano.menu.cpu.atmega328.bootloader.file=atmega/ATmegaBOOT_168_atmega328.hex
nano.menu.cpu.atmega328.build.mcu=atmega328p
## Arduino Nano w/ ATmega168
## -------------------------
nano.menu.cpu.atmega168=ATmega168
nano.menu.cpu.atmega168.upload.maximum_size=14336
nano.menu.cpu.atmega168.upload.maximum_data_size=1024
nano.menu.cpu.atmega168.upload.speed=19200
nano.menu.cpu.atmega168.bootloader.low_fuses=0xff
nano.menu.cpu.atmega168.bootloader.high_fuses=0xdd
nano.menu.cpu.atmega168.bootloader.extended_fuses=0x00
nano.menu.cpu.atmega168.bootloader.file=atmega/ATmegaBOOT_168_diecimila.hex
nano.menu.cpu.atmega168.build.mcu=atmega168
But at this point, I lack the CMAKE knowledge to make it handle the .menu cases in the new boards.txt file format.
Thank you for sharing your experience! Do you know how I can include the libs of the Arduino SDK. Like eg. 'Servo.h' For now I use the Arduino SDK 1.6.7
In the Arduino IDE the code below compiles fine, while in CLion/CMake there is the following error message:
undefined reference to `Servo::Servo()'
#include
void setup() {
Servo one;
}
void loop() {
}
Thank you very much
Looking at the example, shouldn't the code read:
#include <Servo.h>
That said, I tried to use the Servo Sweep example within CLion using CMake, and even though I set the ARDLIBS Servo flag, it still wouldn't compile. I also tried various link_directories options, pointing directly to my Servo.h location. Variations include directory locations and ARDLIBS (Servo, Servo.h, Servo.cpp) options.
link_directories(/Applications/Arduino.app/Contents/Resources/Java/libraries)
set(${CMAKE_PROJECT_NAME}_ARDLIBS Servo)
And I still got the cmake error: undefined reference to `Servo::Servo()'
Anyone else out there that can help?
Got Servo to Work with the following addition to CMakeLists.txt
link_directories(/Applications/Arduino.app/Contents/Resources/Java/libraries/Servo/src/avr)
set(Servo_RECURSE True)
This also worked:
link_directories(/Applications/Arduino.app/Contents/Resources/Java/libraries)
set(Servo_RECURSE True)
This also worked, without the link directories.
set(Servo_RECURSE True)
This also work for Stepper library set(Stepper_RECURSE True)
@mizraith Thanks for your answer it helped me to find another workaround which I will put here just for people if needed.
The workaround ressembles a lot, but instead of changing the platform files, I only change the CMakeList.txt file, by settings the cmake variables.
I add the following in the CMakeList.txt file. This comes from the installed boards.txt file in the arduino cmake tools so you might need to check that yours is the same.
set(nano.upload.maximum_size 30720)
set(nano.upload.maximum_data_size 2048)
set(nano.upload.speed 57600)
set(nano.bootloader.low_fuses 0xFF)
set(nano.bootloader.high_fuses 0xDA)
set(nano.bootloader.extended_fuses 0x05)
set(nano.bootloader.file atmega/ATmegaBOOT_168_atmega328.hex)
set(nano.build.mcu atmega328p)
Then the entire project file looks like this :
cmake_minimum_required(VERSION 2.8.4)
set(CMAKE_TOOLCHAIN_FILE ${CMAKE_SOURCE_DIR}/cmake/ArduinoToolchain.cmake)
set(PROJECT_NAME Arduino101)
project(${PROJECT_NAME})
print_board_list()
set(${CMAKE_PROJECT_NAME}_BOARD nano)
set(${CMAKE_PROJECT_NAME}_PORT COM4)
set(nano.upload.maximum_size 30720)
set(nano.upload.maximum_data_size 2048)
set(nano.upload.speed 57600)
set(nano.bootloader.low_fuses 0xFF)
set(nano.bootloader.high_fuses 0xDA)
set(nano.bootloader.extended_fuses 0x05)
set(nano.bootloader.file atmega/ATmegaBOOT_168_atmega328.hex)
set(nano.build.mcu atmega328p)
set(${CMAKE_PROJECT_NAME}_SKETCH Arduino101.ino)
generate_arduino_firmware(${CMAKE_PROJECT_NAME})
Again, thanks for your findings !