CLionArduinoPlugin icon indicating copy to clipboard operation
CLionArduinoPlugin copied to clipboard

Support *.h/*.cpp files in sketch directory

Open amichair opened this issue 5 years ago • 4 comments

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.

amichair avatar Apr 22 '20 16:04 amichair

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

slawalata avatar May 18 '20 03:05 slawalata

Here is a simple fix: https://github.com/francoiscampbell/arduino-cmake/pull/10/files

mmontag avatar Jan 18 '22 11:01 mmontag

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.

TCB13 avatar Jan 11 '23 14:01 TCB13

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.

TCB13 avatar Jan 11 '23 15:01 TCB13