niklasfi
niklasfi

Reputation: 15931

Difference between compiling with object and source files

I have a file main.cpp containing an implementation of int main() and a library foo split up between foo.h and foo.cpp.

What is the difference (if any) between

g++ main.cpp foo.cpp -o main

and

g++ -c foo.cpp -o foo.o && g++ main.cpp foo.o

?

Edit: of course there is a third version:

g++ -c foo.cpp -o foo.o && g++ -c main.cpp -o main.o && g++ main.o foo.o -o main

Upvotes: 1

Views: 651

Answers (2)

user3416290
user3416290

Reputation:

If you type something like this:

g++ -o main main.cpp foo.cpp 

You are compiling and linking two cpp files at once and generating an executable file called main (you get it with -o)

If you type this:

g++ main.cpp foo.cpp

You are compiling and linking two cpp files at once, generating an executable file with the default name a.out.

Finally, if you type this:

g++ -c foo.cpp

You will generate an object file called foo.o which can later be linked with g++ -o executable_name file1.o ... fileN.o

Using options -c and -o allows you to perform separately two of the tasks performed by the g++ compiler and getting the corresponding preprocessed and object files respectively. I have found a link which may provide you helpful information about it. It talks about gcc (C compiler), but both g++ and gcc work similarly after all:

http://www3.ntu.edu.sg/home/ehchua/programming/cpp/gcc_make.html

Be careful with the syntax of the commands you are using. If you work with Linux and you have problems with commands, just open a cmd window and type "man name_of_the_command", in order to read about, syntax, options, return values and some more relevant information about commands, system calls, user library functions and many other issues.

Hope it helps!

Upvotes: 2

Mats Petersson
Mats Petersson

Reputation: 129374

The total work that the compiler & linker (and other tools used by the compiler) has to do is exactly the same (give or take a few minor things like deleting the temporary object file created for foo.o and main.o that the compiler makes in the first example, which remains in the second example, and both remain in the third example).

The main difference comes when you have a larger project, and you use a Makefile to build the code. Here the advantage is that, since the Makefile only recompiles things that need to be recompiled, you don't have to wait for the compiler to compile code that don't need to recompile. Assuming of course, we choose to use the g++ -c file.cpp -o file.o variant in the makefile (which is the typical way to do it), and not the g++ file.cpp main.cpp ... -o main.

Of course, there are other possible scenarios - for example in unit testing, you may want to use the same object file to build a test around, as you were using to build the main application. Again, this makes more of a difference when the project is large and has half a dozen or more source files.

On a modern machine, compiling doesn't take that long - my compiler project (~5500 lines of C++ code) that links with LLVM takes about 10 seconds to compile the source files, and another 10 seconds to link with all the LLVM files. That's a debug version of the llvm libraries, so it produces a 120+ MB executable.

Once you get onto commercial (or corresponding open source type projects) level of software, the number of sourcefiles and other things involved in a project can be hundreds, and the number of lines of the sources can often be in the 100k-several million lines range. And now it starts to matter if you just recompile foo.cpp or "everything", because compiling everything takes an hour of CPU time. Sure, with multicore machines, it still is only a few minutes, but it's not ideal to spend minutes, when you could just spend a few seconds.

Upvotes: 2

Related Questions