This question already has answers here:
One definition rule in c++
(4 answers)
Closed 7 years ago.
I'm a newcomer to C++. I'm having trouble building a simple multi-file project with g++. Here are my files:
something.h
class Something
{
public:
void do_something() const;
} thing;
something.cpp
#include <iostream>
#include "something.h"
void Something::do_something() const
{
std::cout << "Hello!" << std::endl;
}
main.cpp
#include "something.h"
int main()
{
thing.do_something();
}
Here is what I tried:
g++ main.cpp gives an error that do_something is an undefined reference, which makes sense because the compiler has no idea something.cpp has anything to do with something.h.
g++ main.cpp something.cpp: there are 'multiple definitions' of thing, even though I clearly defined it only once.
g++ -c main.cpp something.cpp: no errors! However, when I try running g++ *.o it gives me the same error as above, so I'm thinking this is a linker error.
Can anyone explain how to compile a multi-file project, and why my approach isn't working? I'm pretty confused right now because above is what most of the C++ examples on Stack Overflow look like.
Sidenotes:
I did try the suggestions here, but they didn't address linking issues with headers specifically.
I'm not trying to redefine thing in main; if I wanted to do that, I would have typed up Something thing.
g++ main.cpp gives an error that do_something is an undefined reference, which makes sense because the compiler has no idea something.cpp [...]
... which contains the definition of the member function do_something exists. So you reference an undefined function.
g++ -c main.cpp something.cpp: no errors! [...]
... since you're only compiling the files, not linking them together.
When you link them together, you end up with
[...] 'multiple definitions' of thing [...]
which is exactly what you're doing:
class Something {
// content
} thing;
is the same as
class Something {
// content
};
Something thing;
And since #include "something.h" works by effectively copying the contents of the included file right into the including file, you end up with 2 files with a line
Something thing;
in each of them. And this is what the linker (called from the compiler frontend) is telling you: There are multiple definitions of the global variable thing.
To solve this: Don't put definitions for global variables into header files, only declarations:
extern Something thing;
And then add a definition in a single source file:
Something thing;
Or, better, try to avoid global variables.
One more thing: If you aren't doing it already, use include guards for your headers.
make sure you have added all files to the project.
Like if you are using IDE e.g, DEV C++ you have to add each .cpp or .h file to the project.
Related
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
I want to compile different files with a common *.c file. Like I want to compile A.c common.c xor B.c common.c but I can't figure out how to achieve that.
Can you please tell me how do I make common.c use different headers without using my text editor to change the headers list every time I want to compile
So let's say I have 3 files: A.c, B.c and common.c.
A.h and B.h define an enum enum {Mon, Tues, Wed...} in different ways. And that enum is used in common.c. So I can't just do in common.c:
#include "A.h"
#include "B.h"
What I thought of doing is to use preprocessor directives:
In common.h
#define A 1
#define B 2
In A.c
#define COMPILE_HEADER A
And in common.c
#if COMPILE_HEADER == A
#include A.h
#end
This doesn't work, of course, because the compiler didn't visit the A.c file to find #define COMPILE_HEADER A
So can you please tell me how do I make common.c use different headers without using my text editor to change the headers list every time I want to compile?
It's pretty complicated to explain, but I'll give it a try.
Explaination
The compiler, for example gcc, gets the input files provided, includes (literally just copy-pastes) the header files into their respective places (where the #include directive is located) in the *.c file, then compiles the file to the object (*.o) file. No executable is created. Here comes the linker, which is included in gcc. It takes the *.o files and links them into one executable.
The problem is, that the files are compiled independently, and then linked together. I mean, that predefinition like int func(int param); is like saying to compiler "Hey man, don't worry about any usage of func in the code, the linker will care". Compiler then just saves this usage as external symbol in the corresponding *.o file, and when linker is doing his job, he firstly finds the location of the symbol definition (the function implementation) and then just points to it whenever the func is called.
Try to include function definition in header file, then include it in 2 or more files from same project (compiled/linked together). Compiler will say it's ok, since the code is correct and the generated code is valid. Then, the linker will try to link it into one executable and he would have to decide which version of the same name-param function should it link to. Since most developer tools are not really good at making the right choices, he will just yell at you saying "hey man, you gave me two definitions of same function, what to do now?". This results with an error like this:
obj\Release\b.o:b.cpp:(.text+0x0): multiple definition of 'func(int)'
obj\Release\a.o:a.cpp:(.text+0xc): first defined here
What about having two main in one project?
obj\Release\b.o:b.cpp:(.text.startup+0x0): multiple definition of 'main'
obj\Release\a.o:a.cpp:(.text.startup+0x0): first defined here
Both files compile, but they cannot be linked together.
The header files are meant to contain class definitions and function predefinitions to allow you to write them only once, and then share between all files that want to use them. You can always just type class definitions for each file separately (as long as they stay same) and use them just like you would use them in .h file, same applies for function predefinitions.
There comes your problem. You have to compile only one file, not include only one. You can do this by using the preprocessor trick, but I wouldn't reccomend as solution, since it can be solved much easier (I'll tell you how in a moment).
TL;DR; (The actual answer without explaination)
You can #ifdef / #ifndef both files, then in another *.c define (or not define) some value. For example:
A.cpp
#include "t.h"
#ifdef USE_A
int func(int a)
{
return a + 5;
}
#endif
B.cpp
#include "t.h"
#ifndef USE_A
int func(int a)
{
return a * 10;
}
#endif
T.h
#ifndef T_H
#define T_H
//Or comment to use B
#define USE_A
int func(int a);
#endif // T_H
main.cpp
#include <iostream>
#include "t.h"
using namespace std;
int main()
{
cout << func(3);
}
Notice that the #ifdef/#ifndef are after the #include, so the preprocessor knows which one to compile. Also, it's not possible (at least I can't think of any way) to make the definition in any .c file, because they are compiled separately (as described above). You could use the -D switch, but that involves messing with build configurations in environments and if you want to do that it's better to try the second solution presented bellow.
Better answer
You should choose one file to compile with each version. It hardly depends on your needs, but basically instead of using g++ main.cpp a.cpp b.cpp you should compile either a.cpp or b.cpp. If you are using integrated environment like Visual Studio or Code Blocks, the configuration managers allow you to decide which file to include. I mean, those Debug/Release dropdowns can contain your own entries, which will customize your project. Then, switching between the A.cpp and B.cpp is just a question of choosing appropiate option in the always-visible bar in your environment.
If you want a more detailed tutorial on how to manage configurations on Code::Blocks or Visual Studio create appropiate question on stackoverflow and it will be answered in no time :)
This is a really basic question, and I have found a lot of conceptual answers online, but failed to actually make it work.
Here is what I have:
file source.cc
#include <iostream>
int myfunc() {
return 42;
}
int main() {
return 0;
}
and then I create an object file source.o via:
g++ -c source.cc
finally, I use
ar rvs source.a source.o
to get the source.a static library.
Now, here comes trouble.
file user.cc looks like this:
#include <iostream>
#include <source.a>
int main() {
std::cout << myfunc();
}
where I evidently want to use the function defined in the library, but when trying to compile the user.cc:
g++ user.cc -o user
the error I get is:
user.cc:2:22: fatal error: source.a: No such file or directory
compilation terminated.
#include is compile time and must be C/C++ header (not library) containing e.g this
extern int myfunc();
than you have to use linker to compile it all togehter (specify all the files needed on the command line)
In addition to what others already wrote on the syntax to properly use g++ on the command line, you may want to consider the following notes on your code organization.
In your library code, you should not define the main() function. The definition of main() should instead be part of the code that uses your library, i.e the file user.cc in your example.
Moreover, you may want to distribute to the clients of the library a header file, that they can use to import the declarations of the functions exported by the library.
So, consider defining some files like this:
Header File:
// library.h -- Public header for your library's clients
#pragma once // or use #ifndef/#define/#endif "header guards"
// Functions exported by your library:
// their *declarations* go in the library's public header file;
// their *definitions* go in the library's implementation file(s) (.cc, .cpp)
// (exception: inline functions/methods, that are implemented in headers).
int myfunc();
// Add some other exported functions...
// NOTE: "extern" not needed in C++!
Implementation File:
// library.cc -- Library implementation code
#include "library.h" // library public header
#include <...> // headers required by this implementation code
// *Define* functions exported by the library
int myfunc() {
return 42;
}
// ...other function implementations...
Then, the library's client will just do:
File containing main() and using your library:
// main.cc (or user.cc or whatever you call it)
#include <iostream> // For std::cout, std::endl
...#include any other required header file...
#include "library.h" // Your library public header file
int main() {
// Call library's function
std::cout << myfunc() << std::endl;
}
// NOTE: main() is special: "return 0;" can be omitted.
Don't #include a library archive. It does not contain source code. It contains object code. Put it on the linker's command line.
Compile with g++ -c user.cc.
Link with g++ -o user user.o source.a.
In C++ (and C99), every function you call much be declared ahead of time. To do this you provide the "signature" of the function, without the the definition. In your case, this would be the statement
int myfunc();
which tells the compiler that myfunc is a function which takes no arguments and returns an int. Typically you would include this function declaration in a header.
A .a file is a compiled archive which does not contain C or C++ code, so #include-ing it into a C++ file will not work. Instead you need to create a C or C++ header, and add the .a archive to the list of files to be linked into the final executable. With g++, this is quite easy, you can say
g++ user.cc source.a -o executable
for example.
By default the #include <...> construct (with angle brackets) search system directories to find the specified files. To search other directories you can use the -L option, and to link with your library you need to use source.a in the command line. Like this:
g++ user.cc -L/path/to/library source.a -o user
A couple of ideas to add to the discussion
1) You should create a header file called source.h that contains the line
int myfunc();
or,
extern int myfunc();
2) In user.cc at the top should be a line
include "source.h"
This will tell the compiler the function is defined
3) I think you should take the main function out of source.cc, or at least make it static
As others have pointed out, you can't include a library file (source.a)
your compile and link process should work as is.
You can use headear files using #include. If you want to use libraries you have to tell the linker where to look for library files.
Check these articles for static and dynamic libraries:
Static and dynamic libraries
Using libraries in VS2005
Using libraries in Code::Blocks
I have a c++ program that compiled previously, but after mucking with the Jamfiles, the program no longer compiled and ld emitted a duplicate symbol error. This persisted after successively reverting to the original Jamfiles, running bjam clean, removing the objects by hand, and switching from clang with the gcc front end to gcc 4.2.1 on MacOs 10.6.7.
A simplified description of the program is that there is main.cpp and four files, a.h,cpp and b.h,cpp, which are compiled into a static library which is linked to main.o. Both, main.cpp and b.cpp depend on the file containing the offending symbol, off.h, through two different intermediate files, but neither a.h nor a.cpp depend in any way on off.h.
Before you ask, I made sure that all files were wrapped in multiple definition guards (#ifndef, #define, #endif), and while I did find a file that was missing them, it did not reference off.h. More importantly, b.h does not include anything that references off.h, only the implementation, b.cpp, makes any reference to off.h. This alone had me puzzled.
To add to my confusion, I was able to remove the reference to off.h from b.cpp and, as expected, it recompiled successfully. However, when I added the reference back in, it also compiled successfully, and continued to do so after cleaning out the object files. I am still at a loss for why it was failing to compile, especially considering that the symbols should not have conflicted, I had prevented symbol duplication, and I had gotten rid of any prior/incomplete builds.
Since I was able to successfully compile my program, I doubt I'll be able to reproduce it to test out any suggestions. However, I am curious as to how this can happen, and if I run across this behavior in the future, what, if anything beyond what I've done, might I do to fix it?
This is often the result of defining an object in a header file, rather than merely declaring it. Consider:
h.h :
#ifndef H_H_
#define H_H_
int i;
#endif
a.cpp :
#include "h.h"
b.cpp :
#include "h.h"
int main() {}
This will produce a duplicate symbol i. The solution is to declare the object in the header file: extern int i; and to define it in exactly one of the source-code files: int i;.
I have recently become aware that I have no idea, genericly speaking, how a c/c++ compiler works. I will admit this initialy came from trying to understand header guards but came to the realization that I am lacking in how compiling works.
Take Visual C++ for instance; Theres the "Header Files" folder, the "Resources Files" folder, and "Source Files" folder. Is there any significance to the separation of these folders and what you put in them? To me, they are all source files. Take the code snippets:
Snippet 1
//a1.h
int r=4;
and
//a1.cpp
int b //<--semicolon left out on purpose
and
//main.cpp
#include <iostream>
#include "a1.h"
void main()
{
cout << r;
}
The compiler errors out saying "a1.cpp(3) : fatal error C1004: unexpected end-of-file found" where I would expect it wouldn't because the a1.cpp file is not #included where the main method exists where in the next code snippet
Snippet 2
//a1.h
int r=4 //<--semicolon left out on purpose
and
//a1.cpp
int b = 4;
and
//main.cpp
#include <iostream>
void main()
{
cout << b;
}
Errors out because "main.cpp(6) : error C2065: 'b' : undeclared identifier". If you include the a1.cpp like so
Snippet 3
//a1.h
int r=4 //<--semicolon left out on purpose
and
//a1.cpp
int b = 4;
and
//main.cpp
#include <iostream>
#include "a1.cpp"
void main()
{
cout << b;
}
the compiler complains "a1.obj : error LNK2005: "int b" (?b##3HA) already defined in main.obj". Both snippets 2 and 3 ignore the fact that int r = 4 does not have a semicolon missing as I suspect that it has something to do with its a xxxx.h file. If I remove the a1.cpp file from the project on snippet 1, then it compiles fine. Clearly what I have expected is not what I am getting. Theres plenty of books and tutorials on how to code in cpp, but not much in the way cpp handles files and source code in the complition process. What on earth is going on here?
Your questions aren't really about the compiler, but about how your IDE is handling the entire build system. The build systems for most C/C++ projects compile each .c or .cpp file separately, and then link the resulting object files together into a final executable. In your case, your IDE is compiling any file you have in the project with a filename extension of .cpp and then linking the resulting objects. The behaviour you're seeing can be explained as follows:
a1.cpp is missing a ;, so when the IDE tries to compile that file, you get the error about 'unexpected end of file'.
b isn't declared anywhere in the main.cpp compilation unit, so you get an error about an undefined identifier.
b exists in both the main.cpp and a1.cpp compilation units (obviously in a1.cpp, and via your #include for main.cpp). Your IDE compiles both of those files - now a1.o and main.o each contain an object called b. When linking, you get a duplicate symbol error.
The important point to take away here, which explains all of the behaviour you see, is that your IDE compiles every .cpp file - not just main.cpp and the files it includes - and then links the resulting objects.
I recommend setting up a command-line test project with a makefile you create yourself - that will teach you all about the inner workings of build systems, and you can then apply that knowledge to the inner workings of your IDE.
header files are not compiled
an #include directive literally pastes the contents of the includable file instead of the #include line
All source files (redargless of main) are compiled into .o or .obj files.
All obj files are linked together along with external .lib files if there are any
You get an executable.
Regarding point 2:
example
//a.h
int
//b.h
x =
//c.h
5
//main.cpp
#include <iostream>
int main()
{
#include "a.h"
#include "b.h"
#include "c.h"
;
std::cout << x << std::endl; //prints 5 :)
}
This isn't a full answer, but hth, my2c, etc :)
Since it seems that there are two ways of understanding your question, I will answer to the understanding C++ compilation part.
I suggest that you start by reading the "compiler" definition in Wikipedia. After that, try Google search for compiler tutorials to build up your comprenhension about compilers. More specific to C++, you can read about #include and preprocessor directives (try Google search for those terms.)
If you still want to understand compilers further, I suggest a compiler book. You'll find a good list of books on StackOverflow.
The #include statement inserts that file into the file making the #include. Your snippet 3 main.cpp thus becomes the following before compilation.
// main.cpp
// All sorts of stuff from iostream
//a1.cpp
int b = 4;
void main()
{
cout << b;
}
The reason you are getting a linker error is that you are defining b twice. It is defined in a.cpp and in main.cpp.
You may wish to read about declaring and defining.
You tell the build system what files to compile. In the case of Visual C++, it will automatically compile any file named "*.cpp" that you add to the project. Though you can go into the project settings and tell it not to.
It will not compile files named *.h (though it can if you explicity tell it to.
The #include directive, is something the compiler processes before it does any compilation (it's called the pre-processor). It basically takes the file that it is pointing it to and sticks it in the source file being compiled at the point the #include directive appears in the file. The compiler then compiles that whole thing as one complete unit.
So, in your example cases:
Snippet 1
Bote a1.cpp and main.cpp are compiled seperately by the build system. SO, when it encounters the error om a1.cpp, it reports it.
Snippet 2
Note that it compiles these files seperately, with no knowledge of each other, so when your reference b in main.cpp, it does not know that b is defined in a1.cpp.
Snippet 3
Now you've included a1.cpp in main.cpp, so it compiles main.cpp, sees a definition for b and says, OK I have a b at global scope. Then it compiles a1.cpp, and says OK, I have a b at global scope.
Now the linker steps in and =tries to put a1 and main together, it;'s now telling you, hey I have 2 b's ate global scope. No good.
The compiler picks up source files from where you tell it to. In the case of Visual C++ there's an IDE telling the compiler what to do, and the different folders are there because that's how the IDE organises the files.
Also, the error in snippet 2 is from the linker, not from the compiler.
The compiler has compiled main.cpp and a1.cpp into object files main.obj and a1.obj and then the linker is trying to make an executable combining these object files, but the variable b is in both a1.obj (directly) and main.obj (via the include of a1.cpp), so you get the "already defined" error.
The problems you see in case 1 and 3 are VS specific. VS apparently tries to compile both main.cpp and a1.cpp.
Case 1: As VS tries to compile a1.cpp, which has an syntax error (the missing semicolon), the compilation fails.
Case 2: You have not declared the variable b in your main.cpp or in any included files. Thus the compilation fails.
Case 3: This is a linker error. Due to the include, int b has been declared in main.cpp as well as in a1.cpp. Since none of them is either static or extern, two global variables with the same identifier have been declared in the same scope. This is no allowed.