This question already has answers here:
Why should I not include cpp files and instead use a header?
(14 answers)
Closed 3 years ago.
As i said in the title i want to know if is an error to include .cpp files in their respectively .h
I'm compiling using cygwin on windows. The g++ compiler was installed in cygwin using apt-cyg install g++.
Then i added the cygwin path to env and now the g++ command is reachable from a windows cmd.
Here's a basic example to reproduce the problem.
main.cpp
#include <iostream>
#include "tezt.h"
int main(int argc, char const *argv[])
{
tezt();
return 0;
}
tezt.h
#ifndef TEZT_H
#define TEZT_H
void tezt();
#endif
tezt.cpp
#include <iostream>
#include "tezt.h"
void tezt()
{
std::cout<<"tezt"<<std::endl;
}
If i compile using simply g++ main.cpp i get errors.
So in order to compile correctly i should type g++ main.cpp tezt.cpp or define libraries.
It can be a trivial task when managing with multiple .cpp files stored in different folders.
So i'm proposing this approach:
if i modify the content of tezt.h, like follow, compilation is successfully! It can be a good "workaround" or it's not recommended? It's a colossal stupidity?
#ifndef TEZT_H
#define TEZT_H
#include "tezt.cpp"
void tezt();
#endif
Thanks for the attention.
Generally it is a bad idea to have an implementation in the header file.
if you include tezt.h file in different files in the same project it may have compilation error, with multiple definitions for the same symbol.
Including *.cpp works.
But the real solution is to use the tool make.
Create a makefile, which defines the dependencies, then call make, which then calls the compiler appropriatly.
Related
I am a C++ learner and I came across a concept of separating code into multiple files to speed up compiling process on bigger projects.
However what the book doesn't tell me and I have tried to find it in other books and on the web, but with no luck is how does linker (during compilation) knows what files to include.
When I make new file I connect its header to the main file with #include "newfile.h", however in this header I don't write where to find definitions of functions.
So how I imagine the process is that it starts in the main file and there it finds "connections" to other files. The question is how it finds those .cpp files that as far as I see don't need to be named the same as its header file.
Exmple:
Main file:
#include <iostream>
#include "krneki_H.h"
using namespace std;
int main()
{
krneki1();
krneki2();
krneki3();
}
And header file:
void krneki1();
void krneki2();
void krneki3();
And new .cpp file:
#include <iostream>
#include "krneki_H.h"
using namespace std;
void krneki1() {
cout<<"Krneki1"<<endl;}
void krneki2() {
cout<<"Krneki2"<<endl;}
void krneki3() {
cout<<"Krneki3"<<endl;}
Notice that there is no indication to use second cpp file. It just knows to use it. Does it search all .cpp files in the map?
Thank you for answer.
You compile both .cpp files using gcc -c or a similar command line, and then pass both of the .o files produced to the linker. The linker does not magically figure out that you want to compile another .cpp file.
For example
gcc -c main.cpp -o main.o # compile
gcc -c krneki_H.cpp -o krneki_H.o # compile
gcc main.o krneki_H.o -o main # link
Your IDE may take care of these details automatically, in which case it compiles all .cpp files you added to your project, then links all the .o files produced by the compilation step.
No. It doesn't just know to use it. In your example, if you compile with main.cpp and without that new cpp file, you'll get an "undefined reference" error.
What happens is that you're using a fancy IDE that automatically compiles all cpp files. It includes them all by default in your makefile.
I recommend that you try to design a makefile from scratch, and see for yourself how you'll get that "undefined reference" error if you don't include the cpp file that has the implementations of your functions.
This question already has an answer here:
"undefined reference to" errors when linking static C library with C++ code
(1 answer)
Closed 6 years ago.
I realize this question has been asked in a number of ways including this very comprehensive answer but I have looked at many and tried fixing my error to no avail.
I am using .cpp and .c files to create a program. I compiled all files with g++, it seemed to have no more linking errors, though it gave me a bunch of C++ errors related to the C syntax. This was the command I used:
g++ -o program main.cpp /data/*.c -l[...libs]
The main.cpp calls functions in the .c files.
I then understood that one should not try to compile both .c and .cpp files with one compiler, instead to use gcc for one, g++ for the other, and thereafter to simply link the object files.
So I did this (the .c files are part of a library, and already have .o files)
g++ -c main.cpp
g++ -o program main.o /data/*.o -l[..libs]
But then here I will get "undefined reference to" errors for functions called from main.cpp to the precompiled .c files, errors which I didn't get previously.
Could anyone help? Or do I maybe need to provide more information?
EDIT (a more in depth excerpt of code, I've tried to simplify otherwise this will be impossible to read, but let me know if I still need to add stuff, I'll try to remove unnecessary code):
main.cpp :
#include "header.h"
int main(int argc, char** argv) {
string s1 = argv[2];
fn1(s1)
}
header.h
void fn1(string s1)
mycfile.c
#include "header.h"
void fn1(string s1){
fprintf(stdout, " you entered %s", s1);
fflush(stdout);
}
ANSWER:
#Smeehey helped me figure out the solution, it was actually that I was still including the old headers in an .hpp file I was using. But the core solution was indeed to use the external C{}.
This is highly likely to do with C-vs-C++ linkage. In your main.cpp, you probably have something like this:
#include <data/header.h>
where header.h refers to your c library. Replace it as follows:
extern "C" {
#include <data/header.h>
}
This tells your c++ compiler not to use c++-style name mangling when defining the required symbols from the header, allowing the linker to successfully find them in the c-compiled .o files.
You have to compile C files with the gcc command, C++ files with either gcc or g++, and link with the g++ command. This sequence will probably work:
gcc -c data/*.c main.cpp
g++ -o program *.o -l <libs...>
Next step: learn to write proper makefiles.
This is a shot in the dark but the problem might be the way C and
Cpp files are compiled is simillar yet slightly different....
Due to name spaces the function foo would generate the symbol some_prefix#foo
Unlike C whereas goo generates the symbol goo
Try doing the following in your .cpp files
extern "C"
{
#include "yourcfilesheader.h"
}
And please attach your code
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
The problem I am having is that, when I call a constructor for a class I have created I get the following error.
main.cpp:20: undefined reference to
`StaticObject::StaticObject(Graphics*, sf::String,
sf::Vector2)'
This problem can be 'fixed' adding an include for the .cpp file in main.cpp like so.
...
#include "GameObjects/StaticObject.cpp"
...
Although this solves the problem, this seems like a poor solution and goes against what I have been previously told. Is there any other way to solve this problem? I'm using Netbeans 7.3 with g++ to code/compile this program. Below is the relevant code.
main.cpp
...
#include <SFML/Graphics.hpp>
#include "Graphics/Graphics.hpp"
#include "GameObjects/StaticObject.hpp"
int main(int argc, char** argv) {
//SETUP
Graphics graphics;
background = new StaticObject(&graphics, "Data/Images/BackgroundPlaceholder.png", sf::Vector2f(0,0));
...
main.hpp
...
#include <SFML/Graphics.hpp>
#include "GameObjects/StaticObject.hpp"
...
// Objects
StaticObject *background;
...
StaticObject.hpp
#include <SFML/Graphics.hpp>
#include "../Graphics/Graphics.hpp"
class StaticObject{
public:
StaticObject();
StaticObject(Graphics *_graphics, sf::String texture_filename, sf::Vector2f _position);
StaticObject(const StaticObject& orig);
virtual ~StaticObject();
private:
// The sprite stores the position
sf::Sprite *sprite;
sf::Texture *texture;
};
StaticObject.cpp
#include "StaticObject.hpp"
#include <SFML/Graphics.hpp>
#include "../Graphics/Graphics.hpp"
StaticObject::StaticObject(){
}
StaticObject::StaticObject(Graphics *_graphics, sf::String texture_filename, sf::Vector2f _position) {
sprite = _graphics->AddSprite(texture_filename);
sprite->setPosition(_position);
}
StaticObject::StaticObject(const StaticObject& orig) {
}
StaticObject::~StaticObject() {
}
If I add the following line to main.cpp, the error disappears.
#include "GameObject/StaticObject.cpp"
Can anyone please explain:
Why this fixes the problem?
Why the .cpp was not implicitly included through including the .hpp
file?
Is there a better way of doing this?
The undefined reference error indicates that the definition of a function/method (i.e constructor here) was not found by the linker.
StaticObject::StaticObject(Graphics*, sf::String, sf::Vector2<float>)
And the reason that adding the following line:
#include "GameObject/StaticObject.cpp"
fixes the issue, is it brings in the implementation as part of the main.cpp whereas your actual implementation is in StaticObject.cpp. This is an incorrect way to fix this problem.
I haven't used Netbeans much, but there should be an option to add all the .cpp files into a single project, so that Netbeans takes care of linking all the .o files into a single executable.
If StaticObject.cpp is built into a library of its own (I highly doubt that is the case here), then you might have to specify the path to the location of this library, so that the linker can find the implementation.
This is what ideally happens when you build your program:
Compile: StaticObject.cpp -> StaticObject.o
Compile: main.cpp -> main.o
Link: StaticObject.o, main.o -> main_program
Although there are ways in gcc/g++ to skip all the intermediate .o file generations and directly generate the main_program, if you specify all the source files (and any libraries) in the same command line.
The linker cannot find the definition for StaticObject, which means you have not compiled and linked StaticObject.cpp. Each .cpp file needs to be separately compiled, and the object files the compiler produces for each one needs to be given to the linker.
The reason including StaticObject.cpp in Main.cpp works is that you are telling the preprocessor to insert the contents of StaticObject.cpp into Main.cpp, which you are compiling, so the definitions become part of Main.cpp's compiled output.
including the cpp file causes the compiler to build that code as part of that file (which you should not do), what you need to do is compile the GameObject/StaticObject.cpp file as its own object, and link the 2 objects together.
I dont know much of netbeans, but probably GameObject/StaticObject.cpp is not included as part of the sources to compile.
That's why if you include it manually at main.cpp he found source code and everything is ok.
I had the same issue but mine was because I'm using Eclipse CDT with and Autotools project. So I had to manually add the new .h and .cpp files to the corresponding Makefile.am, and then do a project > reconfigure project, rebuild, an that was it.
I had the same issue in Qt, where I forgot to add the class to the pro file. Apparently, without adding it to the pro file, the compiler doesn't recognize it. So I added it in, and then ran qmake again, and that silved the problem.
Basically, you need to add the file in the sources.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How do I add a directory to C header include path?
I have run into this problem several times, and I thought it would be good to get an explanation from an experienced C or C++ programmer. In the example below I use a sample library name, but the actual name could be anything.
Say I want to run the following MWE:
#include <stdio.h>
#include <mylib/mylib.h> /* Also try mylib2/mylib/mylib.h */
int main (int argc, char **argv) {
printf ("Hello, World!\n");
return 0;
}
Further, assume that I have a Linux distribution that, instead of placing mylib.h in /usr/include/mylib/, chooses the directory /usr/include/mylib2/mylib/. So the straightforward command:
$ gcc test.c
would fail with the error:
fatal error: mylib.h: No such file or directory
But I might try to fix the include statement by writing:
#include <mylib2/mylib.h>
This gets me past the first error. But internally, mylib.h refers to other header files in the "usual" way: #include <mylib/anotherheader.h>. So now, even after I have fixed the original include statement in the MWE as #include <mylib2/mylib/mylib.h> the build breaks because mylib.h is attempting to include #include <mylib/anotherheader.h> instead of #include <mylib2/mylib/anotherheader.h>.
What is the standard way around this problem? There must be a simple compilation flag that I am missing. Thank you in advance.
You set up the include path so that it contains /usr/include/mylib2, usually with a command line option to the compiler like -I/usr/include/mylib2.
Note that usually an header includes related files from the same package using the
#include "another.h"
syntax, so that it is first searched in a relative to where it is installed. If your library had done this, there would be no problem with
#include <mylib2/mylib/mylib.h>
but even if it was the case you don't want your code to depend on where the libraries you use are installed. That dependence should be kept in the build system.
See the -I compiler flag on gcc and g++ it allows you to specify additional include paths:
http://gcc.gnu.org/onlinedocs/cpp/Search-Path.html
In this case you could specify:
-I /usr/include/mylib2
and #include "mylib/mylib.h" everywhere
Also, this is not part of your question but I thought I would throw it in there anyways, but there is a slight difference between include statements with quotes, and angle brackets:
http://msdn.microsoft.com/en-us/library/36k2cdd4(v=vs.80).aspx
I would recommend the following pattern:
/usr/libs/lib15 - is the directory where your library resides.
In the code:
#include <stdio.h>
#include <mylib1.h> // Header from your lib.
#include <mylib2.h> // Other header from your lib.
#include <mygraphs/defines.h> // Headers in your lib have even subdirectories.
In the command line:
cl -I /usr/libs/lib15 .....
You specify the search path for your headers.