Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple files and "undefined reference" #2

Closed
ramboza opened this issue Dec 3, 2018 · 12 comments
Closed

Multiple files and "undefined reference" #2

ramboza opened this issue Dec 3, 2018 · 12 comments

Comments

@ramboza
Copy link

ramboza commented Dec 3, 2018

Hi !

Nice plugin, thanks!!!

I have some problem to compile more than one source (ino) file.

example:
CLion 2018.3, plugin v1.4.0

I have simple project with one additional cpp file..

demo.ino

#include <Arduino.h>
#include "User_Setup.h"
#include "xxx.h"

void setup() {
	XXX xx;
	xx.Test();
}

void loop() {}

xxx.cpp

#include "xxx.h"
void XXX::Test() {}

xxx.h

#ifndef DEMO_XXX_H
#define DEMO_XXX_H

class XXX {
public:
	void Test();
};
#endif //DEMO_XXX_H

and result is


[ 92%] Linking CXX executable demo.elf
CMakeFiles/untitledz.dir/demo_demo.ino.cpp.obj: In function `setup':
/Users/jenya/Projects/Temp/demo/demo.ino:9: undefined reference to `XXX::Test()'
collect2: error: ld returned 1 exit status
make[3]: *** [demo.elf] Error 1
make[2]: *** [CMakeFiles/demo.dir/all] Error 2
make[1]: *** [CMakeFiles/demo.dir/rule] Error 2
make: *** [untitledz] Error 2

I tried to use different ways from CMakeLists.txt, result the same ..

#Define additional source and header files or default arduino sketch files
set(${PROJECT_NAME}_SRCS xxx.cpp)
set(${PROJECT_NAME}_HDRS User_Setup.h xxx.h)

so, this is some problem of compiling xxx.cpp and linking together with demo.ino

any ideas how to solve it ?

Thanks a lot!
Jev.

@vsch
Copy link
Owner

vsch commented Dec 3, 2018

@ramboza, this is one weirdness of the Arduino CMake but you need to add linked directories which hold additional "library" files locally that will be scanned to find included .h/.cpp combinations where the names match. In your case the files are in the root of your project so add this line and it should fix it:

# Extra library directories
link_directories(${CMAKE_CURRENT_SOURCE_DIR})

BTW, I missed a few bugs in the last release which are now fixed. Until now I did not know if anyone was using the plugin. Thank you for being the first one.

@ramboza
Copy link
Author

ramboza commented Dec 3, 2018

Result the same :(
if you want - you can try to open my empty project (just 1 file added to the project) (attached)

demo.zip

@vsch
Copy link
Owner

vsch commented Dec 3, 2018

@ramboza, I'll try it now.

@ramboza
Copy link
Author

ramboza commented Dec 3, 2018

My setup - macOS Mojave, Arduino IDE 1.8.7, tried CMake version 3.13.1 and 3.12.3 (bundled with CLion)

Thanks !!!

@vsch
Copy link
Owner

vsch commented Dec 3, 2018

@ramboza, forgot that the included lib files should be in a sub-directory with the same name as the files. In your case create xxx sub-directory and move the xxx.h and xxx.cpp to it.

You can include the xxx.h as "xxx.h" or <xxx.h> or <xxx/xxx.h> or "xxx/xxx.h" in your main sketch.

⚠️ One caveat is if you add a new #include to your source you will need to "Reload
CMake project" so the new "library" will be detected and added to the build.

@ramboza
Copy link
Author

ramboza commented Dec 3, 2018

👍 awesome!! It works now!!

Thank you Vladimir!

@MicheleSaltori
Copy link

Exists a more elegant solution for compile multiple cpp sources?

@mweber-ovt
Copy link

I just installed Clion 2019.2 and no matter what I try, I am not able to get this simple example to work.

The outcome is always (the name of my .ino file is CLion_Demo):
CMakeFiles/CLion_Demo.dir/CLion_Demo_clion_demo.ino.cpp.obj: In function setup': /Users/michael/Dropbox/onVector/Projects/BG-Counter/Firmware Development/CLion_Demo/clion_demo.ino:7: undefined reference to XXX::Test()'
collect2: error: ld returned 1 exit status
make[3]: *** [CLion_Demo.elf] Error 1
make[2]: *** [CMakeFiles/CLion_Demo.dir/all] Error 2
make[1]: *** [CMakeFiles/CLion_Demo.dir/rule] Error 2
make: *** [CLion_Demo] Error 2

Please help!

@vsch
Copy link
Owner

vsch commented Sep 6, 2019

@ramboza, the easiest way to make multi-file projects work is to rename the .ino to .cpp and add all your .cpp files to project sources in CMakeLists.txt and .h files to project headers. See: #17

Otherwise, you need to add your xxx files to a subdirectory named xxx located in your source directory if you use to add current source to linked directories with CMakeLists.txt config:

# Extra library directories
link_directories(${CMAKE_CURRENT_SOURCE_DIR})

This is the weirdness of Arduino CMake and this plugin uses that project to make it work in CLion.

@mweber-ovt
Copy link

@vsch , unfortunately, this doesn't work. While everything compiles properly, there is the linker error: undefined reference. I am sure there is something really simple that I am overlooking. Could you possibly try this out and let me know what's wrong?
CLion 2019.2
Arduino Support 1.4.4

clion_demo.cpp
#include <Arduino.h>
#include "User_Setup.h"
#include <xxx.h>

void setup() {
XXX xx;
xx.Test();
}

void loop() {}

xxx.h:
#ifndef CLION_DEMO_XXX_H
#define CLION_DEMO_XXX_H

class XXX {
public:
void Test();
};

#endif //CLION_DEMO_XXX_H

My CMakeLists.txt:
cmake_minimum_required(VERSION 2.8.4)
set(CMAKE_TOOLCHAIN_FILE ${CMAKE_SOURCE_DIR}/cmake/ArduinoToolchain.cmake)
set(CMAKE_CXX_STANDARD 98)
set(PROJECT_NAME CLion_Demo)

set(${PROJECT_NAME}_BOARD mega)
set(ARDUINO_CPU atmega2560)
project(${PROJECT_NAME})

Define additional source and header files or default arduino sketch files

set(${PROJECT_NAME}_SRCS clion_demo.cpp xxx.cpp)
set(${PROJECT_NAME}_HDRS User_Setup.h xxx.h)

Additional static libraries to include in the target.

set(${PROJECT_NAME}_LIBS)

Main sketch file

set(${PROJECT_NAME}_SKETCH clion_demo.cpp)

Add project directories into the build

#add_subdirectory()

Additional settings to add non-standard or your own Arduino libraries.

For this example (libs will contain additional arduino libraries)

An Arduino library my_lib will contain files in libs/my_lib/: my_lib.h, my_lib.cpp + any other cpp files

link_directories(${CMAKE_CURRENT_SOURCE_DIR}/libraries)

For nested library sources replace ${LIB_NAME} with library name for each library

set(_RECURSE true)

Additional settings for programmer. From programmers.txt

set(${PROJECT_NAME}_PROGRAMMER avrispmkii)
set(${PROJECT_NAME}_PORT /dev/cu.usbmodem141101)

set(mega.upload.speed 9600)

Verbose build process

set(${PROJECT_NAME}_AFLAGS -v)

generate_arduino_firmware(${CMAKE_PROJECT_NAME})

@vsch
Copy link
Owner

vsch commented Sep 6, 2019

@mweber-ovt, try commenting out the SKETCH defining line in CMakeLists.txt. If it is defined it will still try to process the project as a sketch and ignore the extra cop files. I’m guessing but the sketch line definitely has to be commented out for multi file project to work.

@jord1e
Copy link

jord1e commented Mar 9, 2021

For future reference (edit these two lines in your own project): francoiscampbell/arduino-cmake#10

After this de _SKETCH, _SRCS and _HDRS all work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants