Reputation: 18229
I have about 20 .cpp files and and as many .h files. When I compile I do
g++ -std=c++11 main.cpp -o main
in main.cpp I start by some forward declarations and then I include all .h and .cpp files.
As a result, at every compilation, all the files must be recompiled which it uncomfortably slow. I think I would need to use .so
and/or .dll
files so that at future compilation, only the modified code need to be recompiled. I don't really know how to do that. Could you give me some advice?
Upvotes: 3
Views: 2652
Reputation: 1
You generally want each translation unit to be compiled separately and you might even compile them in parallel (e.g. with make -j
, see below).
(I am guessing and hoping that you are on Linux and using GCC as g++
; adapt this answer to your compiler and operating system if not.)
If you have src1.cpp src2.cpp src3.cpp
(each containing appropriate #include
directives, probably with a common header file) you would compile src1.cpp
into an object file src1.o
using GCC as:
g++ -Wall -Wextra -g src1.cpp -c -o src1.o
The -Wall -Wextra
options asks for all warnings and some extra ones, and you really want them (to improve your code to get no warnings). The -g
option asks for DWARF debugging information (to be able to use the gdb
debugger later, and also to use valgrind). The -c
option requires only the compilation step without linking. The -o src1.o
explicits the output object file.
Likewise, you'll compile src2.cpp
into src2.o
g++ -Wall -Wextra -g src2.cpp -c -o src2.o
and src3.cpp
g++ -Wall -Wextra -g src3.cpp -c -o src3.o
BTW I prefer the shorter .cc
suffix to .cpp
. For benchmarking purposes, enable optimizations in your compiler, e.g. by adding -O2 -march=native
after -g
.
Finally you want to link all your three objects files src1.o
, src2.o
and src3.o
into a myprog
executable:
g++ -g src1.o src2.o src3.o -o myprog
you might add additional options, e.g. to link external libraries.
Beware that C++14 (and also C++11 and even C++17) has no real modules (in contrast to Ocaml or Go). So the preprocessor is used a lot, and you practically need to include a lot of code; for example, #include <vector>
is pulling more than ten thousand lines of C++ code from standard and internal header files on my Linux/Debian desktop. This explains why C++ compilers are slow, hence I recommend avoiding too small C++ files (e.g. a source file of only a hundred C++ lines including several header files, that would in practice pull dozens of thousands of C++ lines from various internal headers). My preference is to define several related functions (and perhaps classes) in each .cc
(or .cpp
) source file of one or a few thousands lines of C++.
(future C++ standards, perhaps C++20, might add modules to the language; but this could be postponed...)
My recommendation is to learn to use GNU make or ninja. Indeed you need a build automation tool.
You certainly should learn how to invoke your compiler on the command line. Read about invoking GCC if you use g++
. Order of arguments to g++
matters a big lot.
You could use tools like cmake or meson which generates configuration files (for make
or ninja
). But I recommend simpler things than cmake
or meson
(e.g. code your Makefile
by hand and just use make
). Here is an example of Makefile
for make
. You need to understand your build process. In some cases, you might generate some (simple) C++ file(s) during your build (e.g. with GNU bison or Qt moc or your own script or program emitting some C++ file).
I think I would need to use
.so
Not necessarily. .so
files are shared objects, used in shared libraries. See this. You could (and probably at first, you want to) have several object files, as explained above. You might later consider making your own software libraries, but that is worthwhile only for reusable source code.
To link external libraries, you might even want to use pkg-config (for those packages knowing about it) which expands to appropriate build options for g++
.
Look also into existing free software projects for inspiration, and study their source code (including their build process). You'll find many of them in Linux distributions, and on github, sourceforge and elsewhere.
Upvotes: 2
Reputation: 8018
... and then I include all .h and .cpp files.
.cpp
files (aka translation units) aren't meant to be included. You should use a script or any other kind of build system, that compiles each of the .cpp
files separately, and links all the produced .o
object files together into the executable program.
This can be enabled to avoid to recompile all the .cpp
files, if they aren't affected by changes in header files.
Upvotes: 2