This is not actual code i am working on but sample code i had written to understand what i am doing wrong. So i have three files main.cpp, favourite.cpp and favourite.h. I am trying to compile main.cpp but get some weird error.
// main.cpp File
#include <iostream>
#include "favourite.h"
using namespace std;
int main()
{
favNum(12);
}
// favourite.cpp File
#include "favourite.h"
#include <iostream>
using namespace std;
void favNum(int num)
{
cout << "My Favourate number is " << num << endl;
}
// favourite.h File
#ifndef FAVOURITE_H
#define FAVOURITE_H
void favNum(int num);
#endif
This all files are in same folder and i am compiling it normally like g++ main.cpp I am not sure if i need to compile it diffrently as i am using custom header files.
If you say g++ main.cpp and this is your whole command line, the error is a linker error that it can't find favNum, right? In that case, try:
g++ main.cpp favourite.cpp
or split compilation and linking:
g++ -c main.cpp -o main.o
g++ -c favourite.cpp -o favourite.o
g++ main.o favourite.o
Where -c means: Compile only, no linking and -ofilename is required because you want to write the output to two different object files to link them with the last command.
You might also add additional flag, the most important ones are:
-Wall -Wextra -O3
Oh I guess I see the error although you should have included it in your question.
When compiling multiple source files you need to list them all on the GCC command line. Or you can use a Makefile.
So you could do this:
g++ favourite.cpp main.cpp
Or you could write a Makefile like this:
all: program
program: main.o favourite.o
And then just type:
make
Related
I have main.cpp, MyClass.cpp and MyClass.h files.
main.cpp
#include <iostream>
#include "MyClass.h"
int main(){
MyClass foo(123);
std::cout << foo.getNumber();
}
MyClass.h
#ifndef MYCLASS_H
#define MYCLASS_H
class MyClass
{
public:
MyClass(int n);
int getNumber();
private:
int fav_number;
};
#endif // MYCLASS_H
MyClass.cpp
#include "MyClass.h"
MyClass::MyClass(int n) {
fav_number = n;
}
MyClass::getNumber(){
return fav_number;
}
Now this program compiles and works fine as a project in CodeBlocks, but if I try to compile main seperately (not in a project) I get undefined reference to MyClass::MyClass(int). I think it is because in MyClass.h there is no body for the functions as they're in the cpp file.
So my question is: how does this program compile as a project even though MyClass.cpp isn't included anywhere in the main or the header?
When you add your cpp file to IDE it adds it to compile sources.
Depends on your IDE, for example XCode has section compile sources:
If you compile in console with g++, you need to type in console:
g++ main.cpp MyClass.cpp
This means which source files to compile, after that linker should link their main.o MyClass.o files. IDE just do all this stuff by himself.
You compile each .cpp file independently (indeed, if you look at your compiler output, you should see main.o and MyClass.o). The header files simply tell the code that the definitions exist somewhere and after compiling, a linker is used to "link" the two .o files together. It is during the linking stage that the definitions are resolved, so when main.o refers to code in MyClass.o, the linker is what puts these together.
CodeBlocks hides this from you, but its calling out to your compiler and linker to do this. (Actually, if you call gcc with all of your .cpp files, it will call the linker for you too, but this is simply a convenience and you can do it in multiple steps too. If you are using gcc to compile, your linker is usually ld)
You tell it to.
When using an IDE, the list of files in the "project" determines what list of filenames the IDE sends to the compiler, in a build command.
When invoking the build command manually, you have to do that yourself.
For example:
g++ -o myprogram main.cpp MyClass.cpp
Or:
g++ -c main.cpp
g++ -c MyClass.cpp
g++ -o myprogram main.o MyClass.o
Obviously add other flags as needed (include paths etc).
On MyClass.cpp you've forgotten return type specified on its header MyClass.h as follows
int MyClass::getNumber(){
return fav_number;
}
From a terminal console you must pass to the compiler g++ as argument all the files *.cpp which main depends on otherwise you will have an error as follows:
$ g++ main.cpp
/tmp/ccDTbMs5.o: In function `main':
main.cpp:(.text+0x15): undefined reference to `MyClass::MyClass(int)'
main.cpp:(.text+0x21): undefined reference to `MyClass::getNumber()'
collect2: error: ld returned 1 exit status
As you can see the compiler is trying to look for object code that is not found. When you compile main.cpp along with all the cpp files corresponding to the includes on your main. In this manner it will work for you as follows:
$ g++ main.cpp MyClass.cpp -o myprogram
$
$ ./myprogram
123
Option -o change the output program to "myprogram".
More complex situations can be treat using builders such as "Makefile".
In case you do not have the implementation files .cpp for each of your header files .h , you should have instead the binary object code. This should be passed to the g++ accordanly.
$ g++ -c MyClass.cpp
$ g++ -c main.cpp
The previous lines creates MyClass.o and main.o. Notice that the -c is passed to the compiler to indicate that only compilation will be done. Now you can pass the objects to the compiler as follows linking all of then together:
$ g++ -o prog MyClass.o main.o
$ ./prog
123
This is my first go at making my own header file. I am trying to make a simple Hello World program in C++ on Ubuntu. made 3 files as follows :
//hello.h file
#ifndef HELLO_H
#define HELLO_H
//my own code
void hello();
#endif
//hello.cpp file
#include <iostream>
#include "hello.h"
using namespace std;
void hello()
{
cout << "This line is printed from header.";
}
//main.cpp file
#include <iostream>
#include "hello.h"
using namespace std;
int main()
{
cout << "in main" << endl << endl;
hello();
return 0;
}
I've tried
g++ -I /home/Desktop/hello/ -c hello.cpp -o hello.o
to compile header file and this command worked.
then, while doing
g++ -o main main.cpp
I am ending up with following error:
/tmp/ccb0DwHP.o: In function `main':
main.cpp:(.text+0x2e): undefined reference to `hello()'
collect2: error: ld returned 1 exit status
Please suggest whether changes need to be made in any file or in any command in the terminal?
thank you
You don't link to hello.o in the command below:
g++ -o main main.cpp
Try this:
g++ -o main main.cpp hello.o
Or for such simple program, just issue the command below:
g++ -o main main.cpp hello.cpp
For ease of use, create a makefile, then you just run make:
make
A simple makefile:
helloprogram: hello.h hello.cpp main.cpp
g++ -o helloprogram main.cpp hello.cpp
clean:
rm helloprogram
Put hello.h in Path2Hello;
g++ -o main -I Path2Hello main.cpp hello.cpp
ps: -I option to specify an alternate include directory (for header files).
To compile and run a C language program, you need a C compiler. To setup a C language compiler in your Computer/laptop, there are two ways:
Download a full fledged IDE like Turbo C or Microsoft Visual C++, which comes along with a C language compiler.
Or, you use any text editor to edit the program files and download the C compiler separately.
(hopefully) quick question that I can't find the answer to:
I have been given a brief assignment in C++. We are to write a 3-file program. There will be a function file, a header file, and a driver file. Here's what I've got so far:
Header (test.h):
#include <iostream>
using namespace std;
#ifndef TEST_H
#define TEST_H
int foo (int bar);
#endif
Function (test.cpp):
#include <iostream>
#include "test.h"
using namespace std;
int foo (int bar){
bar++;
}
Driver (drive.cpp):
#include <iostream>
#include "test.h"
using namespace std;
int main(){
int x = foo(2);
cout << x << endl;
return x;
}
When I try to compile drive.cpp, I get the following error:
drive.cpp:(.text+0xe): undefined reference to `foo(int)'
So...what am I doing wrong?
For a small project like this, simply compile all .cpp files at once:
g++ main.cpp driver.cpp
For a larger project, you separate the compile and link steps:
compile:
g++ -c main.cpp -o main.o
g++ -c driver.cpp -o driver.o
link:
g++ main.o driver.o
Or rather, you'd have a makefile or IDE do this for you.
In drive.cpp, instead of
#include <test.h>
make it
#include "test.h"
This is the variant of #include syntax that is used for header files of your own program (not system header files). When you use this version the preprocessor searches for include files in the following order:
In the same directory as the file that contains the #include statement.
In the directories of any previously opened include files in the reverse order in which they were opened. The search starts from the directory of the include file that was opened last and continues through the directory of the include file that was opened first.
You need to do one of two things:
Compile all the files at once
# replace 'driver.exe' with what you want your executable called
g++ -Wall -ggdb -o driver.exe main.cpp driver.cpp
Compile all the files to object files and then link the object files:
# again, replace 'driver.exe' with what you want your executable called
g++ -Wall -ggdb -o main.o -c main.cpp
g++ -Wall -ggdb -o driver.o -c driver.cpp
g++ -Wall -ggdb -o driver.exe main.o driver.o
As a side note, you should probably change
#include <test.h>
to
#include "test.h"
and putting "using namespace std;" in a header file is going to cause you copious grief later on.
in test.cpp, change the return line to this:
return bar++;
I have 3 files to compile with G++, the main file is like this:
//main.cpp
#include "test.hpp"
int main(int argc,char** args) {
//
}
The second file is the header file:
//test.hpp
namespace shared {
class test {
//constructor
test();
};
}
The last file is the code file for test.hpp
//test.cpp
shared::test::test() {
//
}
And I compile using G++ this way:
g++ -c main.cpp test.cpp
However, G++ complains about undefined identifier 'shared' in the file 'test.cpp'. In the command line I already pass in file 'main.cpp', which includes the header file. How to fix this? I only want to have all the '#include's be in main.cpp, and no where else.
Add #include "test.hpp" at the beggining of test.cpp.
Compiler doesn't care about the order of files in the commandline. It only affects the linker.
Please also note, that the usual way of compiling multi-file projects is to compile each of them to different sub-object like so:
g++ main.cpp -o main.o
g++ test.cpp -o test.o
ld main.o test.o -o program[.exe]
This allows you to recompile only the files that really did change. If you think about it for a while, you'll find out that a .cpp file can contain many headers without a problem; however, the compilation time will increase when your headers will start to have many headers included. Forward declarations can help solve those issues, yet with your simple example simple solution will work.
You have to say #include "test.hpp" in your test.cpp file. The namespace declaration has to be known.
I'm currently trying to compile an existing project which is a mix of cpp and c.
My makefile is as follows;
execute: mgnsvd.o multifit.o cit.o main.o
g++ -Wall -g multifit.o cit.o main.o mgnsvd.o -lgsl -lgslcblas -o execute
main.o: main.cpp cit.cpp
g++ -Wall -g -c main.cpp
cit.o: cit.cpp mgnsvd.c multifit.h
g++ -Wall -g -c cit.cpp
multifit.o: multifit.c mgnsvd.c multifit.h
g++ -Wall -g -c multifit.c
mgnsvd.o: mgnsvd.c
g++ -Wall -g -c mgnsvd.c
And my main is a rather plain
// global libraries
#include <iostream>
// local files
#include "cit.cpp"
// using directives
using std::endl;
using std::cout;
// main
int main(){
cout << "Hello, world" << endl;
return 0;
}
If is comment out #include "cit.cpp" it compiles fine. However, if i include it the following error happens;
ld: duplicate symbol _first_function_in_cit in main.o and cit.o for architecture x86_64
_first_function is always the first function, and is not defined or even declared/used anywhere else. A grep of the object files confirms the function seems to be incorporated into main.o, but why? I've not worked on a C++/C project before, so maybe I'm making some canonical error? I'm also in OSX, if that makes a difference.
For the record, there are no classes - the .h file contains a few structs and some macros.
cit.cpp is being compiled by itself, and is also included in main.cpp so you're getting two copies of all the code in it.
There is no need for
#include "cit.cpp"
cit.cpp is compiled as a separate unit and later linked.
With the above include you get the code twice with results in duplicate symbols
YOu are compiling cit.cpp to yield cit.o, and you are compiling it again with that #include "cit.cpp" attrocity in your main.cpp. So of course you are getting duplicate symbols.