My program is extremely simple and I'm just learning how to work with prototypes by making header files.
My folder setup is like this:
other.cpp
other.h
entry.cpp
My file, entry.cpp, looks like this:
#include "other.h"
int main(){
doSomething();
return 0;
}
doSomething is a function declared in other.cpp and is prototyped in other.h like so:
//ifndefine pre-processor statements
void doSomething();
Building is where I run into trouble. Runningg++ main_c_file.cpp -o name.exe in the console is supposed to create the executable. The problem I am having is that it doesn't know what doSomething is.
I suspect it's because the processor is not searching for other.cpp. I assumed, based on the tutorial I am following, that I didn't actually need to specify this file; it worked fairly well in their video to simply include just the header file and have the cpp file in the same directory.
further: I downloaded their source code and the problem remained. It is not my code, it is how I am trying to build my files. I am not using an IDE to build my programs (I am using Atom IDE to write programs if you know of a shortcut through there), and like stated earlier I am just running the Mingw g++ cppfile.cpp -o command.
Besides the straight answer, if there is a way that can make building cpp projects easier please link me to it or write it here. I have had nothing but trouble in the past trying to learn this language.
Related
I am trying to add a cpp file to arduino project that has the following setup...
project
--folder
--foo.h
--foo.cpp
--project.ino
I have a #include "folder/foo.h at the top of project.ino. However while the header provides the prototype of the function, the function definition is in the cpp file. When I try to compile the code using the Arduino IDE, it fails with error
Undefined reference to 'bar()'
and bar() is located in foo.cpp
I looked at this but I do not have a setting for sketch/import library (however I do have sketch/include library, however I did not see anything close to using a custom folder location)
I looked at this too. But same as above, that setting does not exist in my ide. (Which I downloaded recently)
Code
//project.ino
#include "folder/foo.h"
void setup() {
Serial.begin(9600);
}
void loop() {
bar();
}
//folder/foo.h
#include "Arduino.h"
void bar();
//folder/foo.cpp
#include "foo.h"
void bar() {
Serial.println("bar");
}
Error
/tmp/ccNTRFfU.ltrans0.ltrans.o: In function `loop':
/home/temporary/project/project.ino:9: undefined reference to `bar()'
collect2: error: ld returned 1 exit status
exit status 1
What I would expect to happened is a way to link the cpp folder without having to put all the files in the same root folder of the project.
--Edit 1:
added code
--Edit 2:
added #include "Arduino.h"
--Edit 3:
added Serial.begin(9600);
How to properly include C/C++ headers and source files in your Arduino Project.
This answer has been tested and compiled to ensure it works. (Completed in Linux Ubuntu with the Arduino 1.8.7 IDE).
You have 2 problems.
1st: Arduino's unusual build process (described here) doesn't allow including from sub-folders in your project directory where your .ino file for this project is located.
[UPDATE: THIS ONE MAY HAVE BEEN MY MISTAKE ONLY, NOT YOURS, when I was duplicating your code on my PC: I accidentally used foo.c instead of foo.cpp]
2nd: C++ can only be used inside C++ source files, so you must change foo.c to foo.cpp, since Serial.println() is a C++ call to a C++ class's (Serial's) println() method.
To fix 1, simply change your folder structure to have everything in a single folder:
project
├── foo.cpp
├── foo.hh
└── project.ino
I present an alternate fix for #1 below too.
To fix 2, (this is mandatory!) make foo.c --> foo.cpp and (optionally, but recommended, to show it is a C++ header file) foo.h --> foo.hh. Update your includes in the .ino and .cpp file now too to #include "foo.hh".
That's it! Now close the Arduino IDE, then reopen it and reopen your project, and you'll see the following new tabs show up:
It now compiles just fine!
Learning: how did I figure this out?
First, turn on verbose compilation in the Arduino IDE: File --> Preferences --> check the box for "Show verbose output during 'compilation'".
Now, when you compile, all errors will show up in the bottom of the IDE window, as well as the exact compilation or linking commands which throw the error.
Once I fixed the folder structure, but your files were still C instead of C++ files, I saw this error:
Compiling sketch...
/home/gabriel/Downloads/Install_Files/Arduino/arduino-1.8.7/hardware/tools/avr/bin/avr-gcc -c -g -Os -w -std=gnu11 -ffunction-sections -fdata-sections -MMD -flto -fno-fat-lto-objects -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10807 -DARDUINO_AVR_NANO -DARDUINO_ARCH_AVR -I/home/gabriel/Downloads/Install_Files/Arduino/arduino-1.8.7/hardware/arduino/avr/cores/arduino -I/home/gabriel/Downloads/Install_Files/Arduino/arduino-1.8.7/hardware/arduino/avr/variants/eightanaloginputs /tmp/arduino_build_233569/sketch/foo.c -o /tmp/arduino_build_233569/sketch/foo.c.o
/tmp/arduino_build_233569/sketch/foo.c: In function 'bar':
foo.c:9:5: error: 'Serial' undeclared (first use in this function)
Serial.println("bar");
^
/tmp/arduino_build_233569/sketch/foo.c:9:5: note: each undeclared identifier is reported only once for each function it appears in
exit status 1
'Serial' undeclared (first use in this function)
Notice the file it failed to compile was /tmp/arduino_build_233569/sketch/foo.c, and that the avr-gcc C compiler (rather than the avr-g++ C++ compiler) was in use at the time.
I then opened the /tmp/arduino_build_233569/sketch/foo.c file to examine it and look for anything unusual about it.
Next, I used Eclipse to start tracking down includes, to see where Serial gets pulled in (it should have been obvious to me already what the problem was, but I didn't see it yet). I found the following:
Arduino.h is found in "Arduino/Source/Arduino/hardware/arduino/avr/cores/arduino/Arduino.h". It includes "HardwareSerial.h". This header externs the Serial object:
#if defined(UBRRH) || defined(UBRR0H)
extern HardwareSerial Serial;
#define HAVE_HWSERIAL0
#endif
HOWEVER, looking back at Arduino.h you'll see that HardwareSerial.h is ONLY included if you are compiling with C++:
#ifdef __cplusplus <========= This means that the following headers are ONLY included if you are compiling with C++! BOOM! That's when it hit me! You're compiling a C file with the C compiler to access a C++ object. That's not ok. Use the C++ compiler!
#include "WCharacter.h"
#include "WString.h"
#include "HardwareSerial.h"
#include "USBAPI.h"
#if defined(HAVE_HWSERIAL0) && defined(HAVE_CDCSERIAL)
#error "Targets with both UART0 and CDC serial not supported"
#endif
#ifdef __cplusplus means that the headers above are ONLY included if you are compiling with C++! That's when it hit me! You're compiling a C file with the C compiler to access a C++ object. That's not ok. You must use the C++ compiler instead. Do this simply by changing foo.c to foo.cpp. Done.
Alternate fix for your problem #1 (the folder structure):
Find your "Sketchbook location" from Arduino IDE: File --> Preferences. Mine, for example, is /home/gabriel/dev/Arduino/Sketches.
Now, go there and create a "libraries" folder. For me that would now be /home/gabriel/dev/Arduino/Sketches/libraries. Everything inside this folder is now considered an Arduino "library", and can be included. Move foo.h [do NOT use foo.hh in this case] and foo.cpp there, like this:
/home/gabriel/dev/Arduino/Sketches/libraries/foo
├── foo.cpp
└── foo.h <==== NOT foo.hh in this case!
Now close and reopen the Arduino IDE, then go to Sketch --> Include Library --> foo, and it will automatically add the following line for you:
#include <foo.h>
The reason you can't use foo.hh in this case is simply because Arduino is looking for .h files only when you add your library include using the menus in this way. That's a bug as far as I'm concerned, and should probably be reported to the Arduino developers. Feel free to take that on.
Addendum:
16 Apr. 2019:
A google search for "arduino add include path" led me to this: https://forum.arduino.cc/index.php?topic=445230.0, where user #pert says:
In recent versions of the Arduino IDE(including 1.6.10) if you want to include libraries from the sketch folder you need to put them in a src subfolder. For example:
Blink
|_Blink.ino
|_src
|_BlinkLib
|_BlinkLib.h
He then says you can include like this:
#include "src/BlinkLib/BlinkLib.h"
I haven't tried this, but that'd be super useful if it works. Give it a shot and let me know if it works. Be sure to tell us which OS and Arduino IDE version you are using.
See Also:
Additional discussion on Github here: https://github.com/arduino/Arduino/issues/5186.
The official Arduino Library specification here: https://arduino.github.io/arduino-cli/latest/library-specification/.
Open a tab in your project for each file.
You can create a new file or import an existing file into your project.
This way you can use multiple *.ino, *.c, *.cpp and *.h files. I didn't find a way to import a local directory or to configure your project structure.
Place your folder inside libraries folder that is a subdirectory of your sketchbook directory.
Open Arduino IDE (if it is already open, quit it and reopen).
Go to Sketch->Include Library. You will find folder under Contributed Libraries section.
Choose folder and you are good to go.
According to "Sketch specification":
In Arduino IDE 1.6.5-r5 and older, no recursive compilation was done.
In Arduino IDE 1.6.6 - 1.6.9, recursive compilation was done of all subfolders of the sketch folder.
In Arduino IDE 1.6.10 and newer, recursive compilation is limited to the src subfolder of the sketch folder.
So, putting your source code files into 'src' subfolder should solve the problem. Tested in "Arduino IDE" v2.0.3.
First of all, I am a beginner programmer so, please give simple answers that are understandable.
I am suing Code::Blocks and I am trying to make a multiple file project in C++. I am using SDL2. My problem is that when I put all my codes and functions altogether, they run and when I seperate them, they don't. This is because the execution file requires object files to be built which it don't get. It don't get them because compiler don't form them. In other words, there are problems with linking. The compiler simply, said that there are not ".o" files. These files are in the project as "Link Files" and not "Compile Files". And when I make them "Compile Files" as well as "Link Files", they produces errors that various variables inside the file where I mentioned them, are not declared. But when I include that file in the file using the variables, it gets deeply nested.
Following are the two ways:
First way which is not working, with seperate files.
In main.cpp:
#include <SDL.h>
#include <other.h>
int var;
int linkVar;
int link1Var;
int link2Var;
#include "link.cpp"
#include "link1.cpp"
#include "link2.cpp"
int main( int argc, char* args[] )
{
linkFunc();
link1Func();
link2Func();
}
In link.cpp/ link1.cpp/ link2.cpp:
void linkFunc()/void link1Func()/void link2Func() //Just a reference
{
//Code associated with var, link1Var, link2Var and link3Var.
}
Second way which is working, with all functions in a single file.
First thing is that I don't want to learn makefile thing. If there is any other way to solve it then be it!
Code::Blocks makes object files for each file that it compiles as separate compilation units. It will compile and link together any files that are part of the project which it identifies as a source file.
First, remove your #includes of the cpp files. Then try the Project > Add files... menu option to add those other cpp files to the project.
First of all, you should not use #include on other cpp files, you can read about it here:
include cpp
Secondly when you are trying to compile a project composed of separate files you should use the g++ command like this: g++ main.cpp link.cpp link2.cpp etc'
you can read a basic explanation about it here: use the g++ command
To do exactly what you asked you should do:
# get rid of including any cpp files
# use forward declerations on any function belonging in other cpp files, before your main function like this:
void linkfunc();
void linkfunc2();
etc
.
.
.
int main()
{
}
# specify the direct path to your .h files like this:
#include <C:/MinGW/SDL2/SDL.h>
# use this command:
g++ -I C:/MinGW/SDL2/ main.cpp link.cpp link2.cpp link3.cpp
I am using the terminal and gedit editor to learn QT C++. Do not mind my approach of programming, I do not like to depend on IDE's, but plain text editors. However I seem to be having some issues compiling. I created a basic simple snippet, then after saving as a .cpp extension file I type the command lines;
qmake -project
qmake
make
qmake main.cpp
All this is being done in a directory folder on my desktop called "qt". I try to run the file with:
qmake main.cpp
and all it shows is: Unknown test function: int main.
I check the error and the int main looks fine. The int main contains two arguments an int argc, and a char *argv[] which is passed to the QApplication() function parameters in the local scope. Obviously I am doing something wrong and cannot seem to figure out what.
Also as I mentioned above about using a .cpp extension, I also tried replacing the .cpp with .pro that also did not seem to work out, it displayed the same exact errors.
I have to develop my project in text-mode debian linux. I'm using Vim and I installed the clang_completion plugin on it. I made .clang_completion file in root of my project :
-I.
-I/usr/include
-I/usr/include/c++/4.6
When I write a program like below, the completion works fine.
//#include <stdio.h>
int main()
{
struct A
{
int x, y;
};
A a;
a. // After putting dot, the suggestion popup appears
return 0;
}
However, after removing the comment of first line, it doesn't work! How can I overcome this issue?
I found the easiest way to get clang_complete to work is to use the provided cc_args.py file.
when compiling a project use clang_complete/bin/cc_args.py instead of gcc/g++
This will generate the correct .clang_complete file with all libraries and dependencies.
Provided the clang_complete source directory in your home folder.
Example Makefile:
CXX=$(HOME)/clang_complete/bin/cc_args.py g++
all:
$(CXX) main.cpp
I've successfully used the clang_complete plugin in the past (now I just use cscope and ctags, which I consider enough).
Including external headers worked fine in my configuration, but, as the clang complete plugin page specifies, the file in which to put include paths (or any other flag you may want to pass to the clang compiler), must be named .clang_complete and not .clang_completion.
Also, I used to put the options on a single line, just as I was going to pass the plain content of the .clang_complete file as a command line option (don't know if separating lines with \ will work).
Hope this helps.
I am really new to C++, and I am trying to create a class in a separate file, and I ran into a problem. I basically copied the tutorial http://thenewboston.org/watch.php?cat=16&number=15 from the newboston word for word. However, for the things don't work. I am getting this error when I am trying to run the main file:
C:\Users\Akavall\Desktop\C++ Stuff\New C++ stuff\class_try.o:class_try.cpp|| undefined reference to `Burrito::Burrito()'|
||=== Build finished: 1 errors, 0 warnings ===|
Also, when I am creating the class. The Workspace icon is sitting by itself, while it is supposed to (I believe) include my .cpp and .h folders of the just created class.
My guess is that my paths are not set correctly somewhere, but I have no idea how to fix that. Any suggestions?
Here is the code that I am using:
Main file (class_try.cpp)
#include <iostream>
#include "Burrito.h"
using namespace std;
int main()
{
Burrito bo;
return 0;
}
The class files:
Burrito.h
#ifndef BURRITO_H
#define BURRITO_H
class Burrito
{
public:
Burrito();
};
#endif // BURRITO_H
Burrito.cpp
#include "Burrito.h"
#include <iostream>
using namespace std;
Burrito::Burrito()
{
cout<<"something silly"<<endl;
}
What should I do to fix the this problem?
Thank You in Advance
Edit:
I am using CodeBlocks, and I am on 32bit windows.
If you are using MSVC like that tutorial you linked, you need to first create a project. After creating the project, add all the header (.h) and source (.cpp/.cxx) files that you want to include/compile in it. Now, MSVC makes this easy from this point; you can simply compile (as long as everything is properly added to your project) and it will compile things in order for you.
Extra Information
The information below is not directly pertinent to this issue (or at least doesn't seem that way since you're on Windows), but is intended to help your growth as a developer if you want it.
If, however, you ever decide to use a command line compiler (i.e. MingW) or work in a *nix environment, it is important to note that you need to explicitly compile each object (without linking; in gcc/mingw this flag is -c). Then at the end of compiling several unlinked object, you compile all the objects and the main source file together (with linking this time) and it will create one executable.
I would recommend, however, before trying a command line compiler that you get comfortable/familiar with doing this process through an IDE. Since it is generally an automated process anyway (i.e. most developers end up writing Makefile's for this kind of thing, realistically) you do not really lose too much (immediately, anyway) by not doing this. It is just something to be aware of as you learn.
Using command line compiler you can try this:
g++ class_try.cpp Burrito.cpp -o executable_name
This will link your two .cpp files and create an executable file and you can run that executable file just by typing
./executable_name