Support *.h/*.cpp files in sketch directory
When using the Arduino IDE you can add *.h and *.cpp files in the same directory as the sketch (ino file), and they are included by default in the build. For compatibility, this should be supported out of the box by the CLion plugin as well.
In the meanwhile, if there is a manual workaround please do share... from what I could tell when specifying a sketch file it ignores the src/hdr configuration, though there's probably some other way to do this.
When using the Arduino IDE you can add *.h and *.cpp files in the same directory as the sketch (ino file), and they are included by default in the build. For compatibility, this should be supported out of the box by the CLion plugin as well.
In the meanwhile, if there is a manual workaround please do share... from what I could tell when specifying a sketch file it ignores the src/hdr configuration, though there's probably some other way to do this.
I found this solution but it doesn't work for me, maybe because it has all files in /src
https://stackoverflow.com/questions/48361713/clion-arduino-undefined-reference
Here is a simple fix: https://github.com/francoiscampbell/arduino-cmake/pull/10/files
Here is a simple fix: https://github.com/francoiscampbell/arduino-cmake/pull/10/files
Although it works for a simple .c / .cpp / .h file it seems that I can't use the built in Arduino libraries. Here is an example:
In my CMakeLists.txt:
# Link the built-in libraries and enable Wire recurse:
link_directories("C:/Program Files (x86)/Arduino/hardware/arduino/avr/libraries")
set(Wire_RECURSE True)
# Add other extra files
link_directories(${CMAKE_CURRENT_SOURCE_DIR})
link_directories(${CMAKE_CURRENT_SOURCE_DIR}/lib)
If I go into project.ino and use the Wire.h lib it works just fine. Here is an example of an I2C scanner:
#include <Arduino.h>
#include <Wire.h>
///... init serial and other stuff
void loop() {
Wire.begin();
byte error, address;
int nDevices;
Serial.println("Scanning...");
nDevices = 0;
for (address = 1; address < 127; address++) {
Wire.beginTransmission(address);
error = Wire.endTransmission();
if (error == 0) {
Serial.print("I2C device found at address 0x");
if (address < 16)
Serial.print("0");
Serial.print(address, HEX);
Serial.println(" !");
nDevices++;
} else if (error == 4) {
Serial.print("Unknown error at address 0x");
if (address < 16)
Serial.print("0");
Serial.println(address, HEX);
}
}
if (nDevices == 0)
Serial.println("No I2C devices found\n");
else
Serial.println("done\n");
delay(5000);;
}
However if I try to use the Wire lib from my own .cpp/.h files it doesn't work.
devhelpers/devhelpers.h:
#ifndef ENVCONTROL_DEVHELPERS_H
#define ENVCONTROL_DEVHELPERS_H
#include <Arduino.h>
#include <HardwareSerial.h>
#include <Wire.h>
void wiredetect();
#endif //ENVCONTROL_DEVHELPERS_H
devhelpers/devhelpers.cpp:
#include "devhelpers.h"
void wiredetect() {
Wire.begin();
byte error, address;
int nDevices;
Serial.println("Scanning...");
nDevices = 0;
for (address = 1; address < 127; address++) {
Wire.beginTransmission(address);
error = Wire.endTransmission();
if (error == 0) {
Serial.print("I2C device found at address 0x");
if (address < 16)
Serial.print("0");
Serial.print(address, HEX);
Serial.println(" !");
nDevices++;
} else if (error == 4) {
Serial.print("Unknown error at address 0x");
if (address < 16)
Serial.print("0");
Serial.println(address, HEX);
}
}
if (nDevices == 0)
Serial.println("No I2C devices found\n");
else
Serial.println("done\n");
delay(5000);;
}
and then in my project.ino:
#include <Arduino.h>
#include "devhelpers.h"
///... init serial and other stuff
void loop() {
wiredetect();
}
I get this compiler error:
[ 97%] Linking CXX executable EnvControl.elf
libmega_devhelpers.a(devhelpers.cpp.obj): In function `wiredetect()':
C:\Users\...project\devhelpers/devhelpers.cpp:5: undefined reference to `Wire'
C:\Users\...project\devhelpers/devhelpers.cpp:5: undefined reference to `Wire'
C:\Users\...project\devhelpers/devhelpers.cpp:5: undefined reference to `TwoWire::begin()'
C:\Users\...project\devhelpers/devhelpers.cpp:18: undefined reference to `Wire'
C:\Users\...project\devhelpers/devhelpers.cpp:18: undefined reference to `Wire'
C:\Users\...project\devhelpers/devhelpers.cpp:18: undefined reference to `TwoWire::beginTransmission(unsigned char)'
C:\Users\...project\devhelpers/devhelpers.cpp:19: undefined reference to `Wire'
C:\Users\...project\devhelpers/devhelpers.cpp:19: undefined reference to `Wire'
C:\Users\...project\devhelpers/devhelpers.cpp:19: undefined reference to `TwoWire::endTransmission()'
collect2.exe: error: ld returned 1 exit status
mingw32-make[3]: *** [CMakeFiles\EnvControl.dir\build.make:105: EnvControl.elf] Error 1
mingw32-make[2]: *** [CMakeFiles\Makefile2:201: CMakeFiles/EnvControl.dir/all] Error 2
mingw32-make[1]: *** [CMakeFiles\Makefile2:286: CMakeFiles/upload.dir/rule] Error 2
mingw32-make: *** [Makefile:214: upload] Error 2
It seems unable to deal with Wire.h defined in devhelpers.h.
Anyone knows how to fix this? Thank you.
Anyone knows how to fix this? Thank you.
Apparently it can be fixed by changing a few things in CMakeLists.txt. Seems sketchy but works:
include_directories(${PROJECT_SOURCE_DIR})
file(GLOB SRC_FILES ${PROJECT_SOURCE_DIR}/devhelpers/*.cpp)
file(GLOB HDR_FILES ${PROJECT_SOURCE_DIR}/devhelpers/*.h)
set(PROJ_SRC ${SRC_FILES})
set(PROJ_HDR ${HDR_FILES})
generate_arduino_firmware(${CMAKE_PROJECT_NAME}
SRCS ${PROJ_SRC}
HDRS ${PROJ_HDR}
)
Note that you'll have to add a GLOB for each folder with .cpp/.h files.