How to use multiple source files to create a single object file with gcc
Asked Answered
C

9

12

I'm using the -c option with g++ to create a bunch of object files, and it's only letting me specify one source file for each object file. I want to have multiple files go into some of them. Is there any way to do this?

Consanguineous answered 27/6, 2011 at 7:5 Comment(4)
Can you explain why? Are you looking to make a library?Legra
If you really want that, just create a empty C file and include all the other C files.Celebrant
I'm using a linker script to link it and I need object files to use it. I just don't want to have to run so many commands to build it.Consanguineous
You could consider writing a simple Makefile if you don't want to run so many commands each time.Hardily
P
15

Others have mentioned archive, but another option is Unity builds.

Instead of:

g++ -c file1.cpp file2.cpp

Create a separate "unity file"

// This is the entire file (unity.cpp)
#include "file1.cpp"
#include "file2.cpp"
// more if you want...

Then

g++ -c unity.cpp

This also has the advantage of faster compilation and linking in many cases (because headers used by both file1.cpp and file2.cpp are only parsed once). However, if you put too many files in a single unity however then you'll find that you need to rebuild more sources than you wanted to, so you need to try and strike a balance.

Prattle answered 27/6, 2011 at 7:24 Comment(1)
Too bad that simple "unity build implementation" still exposes info about all internal symbols which could be static when compiled as a single object. Any cross-platform solution for this?Ossified
K
7

You can use ld -r to combine the objects while keeping relocation information and leaving constructors unresolved:

ld -r -o everything.o object1.o object2.o ...
Kenji answered 27/6, 2011 at 7:30 Comment(0)
A
4

You can create archive which is a set of object files.

ar mylib.a file1.o file2.o

So effectively you have combined file1.cpp and file2.cpp into mylib.a.

Ambitendency answered 27/6, 2011 at 7:13 Comment(2)
But then I still have to make file1.o and file2.o instead of just files.oConsanguineous
@David, In this case, yes. I am not aware if we can combine multiple files in one object file. You can also think of writing a smart script: g++ -c file1.cpp file2.cpp ; ar files.a file1.o file2.oAmbitendency
R
2

You can utilize the ar command to create an archive for use by your program.

Repp answered 27/6, 2011 at 7:10 Comment(1)
That doesn't help me lower the amount of object files to begin with.Consanguineous
F
1

Using the solution from Peter Alexander is the main one that comes to mind.

But, keep in mind that by using this method, you'll have to compile your whole sources files each time. When your project grows bigger, compilation time can become a pain.

Furthermore, compiling several files on their own enable the use of the various cores on modern CPUs: each source file will be compiled in its own process, at full speed. Do not under-use the power of the multi cores.

Fingerbreadth answered 27/6, 2011 at 7:40 Comment(0)
S
1

I know you are asking about how to combine .cpp files into one object file. I assume your goal for doing this is to link the combined object at a later time with other individual object files. If this is the case you may be able to use a static or dynamic library instead. For your goals I suggest the dynamic library since you can do a single compile and link step skipping the generation of object files altogether. Using a command such as g++ -shared -fpic file1.cpp file2.cpp file3.cpp -o libtest.so you can combine your .cpp files that need combining into libraries. To compile the library(s) with your individual object files use a command such as g++ -ltest individual1.o individual2.o individual3.o -o myexecutable. In that final linking step I assume libtest.so is in your current directory. If its not in your current directory add a -L flag and the directory libtest.so is in.

Soulsearching answered 24/3, 2015 at 15:5 Comment(1)
True - though I guess the goal is to increase performance to avoid PLT (Process Linkage Table) overhead which is required whenever a symbol may be in another object than the one that references it.Ariew
G
1

In a sense, you can't. The compiler only compiles one file at a time. When you give it a list of files, either with -c or to turn into a single executable or shared library, it actually calls the compiler a bunch of times with some temporary output files (usually in /tmp or similar), and then links them after the fact.

The solution, then, is to only ask it to compile one file. Already mentioned is writing a file to compile

tocompile.cpp
--------------------
#include "file1.cpp"
#include "file2.cpp"

You could even autogenerate this file in your Makefile, but it turns out there is no need to do so, because the compiler is quite happy to read from - (standard input).

This means you can simply run

printf '#include "%s"\n' ./*.cpp | $CXX $CXXFLAGS -o combined.o -x c++ -

Note that the -x tells the compiler what language the input is, normally it guesses based on the compiler called (gcc vs g++ or similar), and the filename, but since the filename is -, we have to specify.

When doing this, assuming you are including your whole project, -fwhole-program in gcc is a good way to decrease the generated output size, note that for that to work, you need to also list all libraries needed.

Gromyko answered 28/10, 2019 at 21:36 Comment(0)
F
0

The only solution I know of is to create a separate C++ file, which includes all of the files you want to compile, and compile that. A pretty bad solution, in my mind; generally, you want to increase the granularity of the object files, not reduce it.

The real question, I suppose, is what are you trying to achieve. Why do you want only a single object file?

Floor answered 27/6, 2011 at 8:19 Comment(0)
O
-5

We use -o option to create an object file...... By Default when we compile file using gcc or g++ we get object file named as a.out but we can change its name.... use following to compile file

gcc Filename.c -o NewFilename.out

then to run file you can use ./NewFilename.out

Overthecounter answered 24/1, 2013 at 6:36 Comment(3)
That is not what the OP was asking. He/she is asking to compile multiple source files into a single object file.Microwave
the option to create an object file is -c not -oSummation
As Andry is saying -c is for object files. -o is for specifying the name of output file. Format: -o <OutputFileName>Mitsue

© 2022 - 2024 — McMap. All rights reserved.