GCC/G++ is used to compile and link C/C++ programs, long story short, a compiler. Its history is not described here, so those who are interested can check it out for themselves.
Compilation process of C/C++
Before introducing GCC/G++, let’s briefly explain the process of compiling and linking C/C++ to generate executable files.
-
Source file preprocessing: c preprocessing (cpp.exe) to process macros in source files, etc.
1
cpp hello.c > hello.i
-
Compile: gcc/g++ compiles the preprocessed code into an assembly program, the
-S
option indicates the generation of an assembly program file (.s)1
gcc -S hello.i
-
Generate the target file (.o) from the assembler using as.exe
1
as -o hello.o hello.s
-
Finally, use the connector (ld.exe) to link the target file (.o) to generate the executable file (.out/.exe)
1
ld -o hello.out hello.o ...libraries...
Use of GCC/G++
Let’s take GCC as an example and introduce the basic usage. Create a new hello.c
file and write the following contents.
-
Compile and link the c file
The default is to generate
a.out
(the executable is a.out on linux, a.exe on windows). You can use the-o
option to specify the name of the generated file. -
Separate compilation and linking processes
A file has changed in the actual project and we want to compile it separately and then link its compiled target file (.o) with other target files or library files. The source file can be compiled to the target file (.o) using the
-c
option.Linking a target file into an executable file executes the same commands as compiling and linking. The linking process is executed when the source file is a target file, and the compiling and linking process is executed when the source file is a C file.
-
Multi-file compilation link
The gcc command supports multiple source file input if you want to compile source1.c and source2.c together.
More often than not, you may want to compile them separately.
-
Print all warning messages at compile time
The
-Wall
option prints all warning messages, so it is usually turned on when using gcc.1
$ gcc -Wall -o hello hello.c
-
Debugging
With the
-g
option, you can make the file contain debugging information to be made available to gdb for debugging.1
$ gcc -Wall -g -o hello hello.c
-
Print the complete message at compile time
-v
prints the complete compilation process information.1
$ gcc -v -o hello hello.c
Static and Shared Libraries
Usually we compile some common methods, variables, classes, into a separate library for the business side to call. A library is essentially a file containing one or more object files (object files) for use in the linking phase.
There are two types of libraries: static library and shared library, which is also called dynamic library. What are the differences in their behavior?
- Static libraries are a collection of target files (.o) with the suffix
.a
on linux and mac, and.lib
on windows. It is linked with other target files (.o) to form an executable (.out) during the linking phase of the program compilation process. So the static library only works in the compilation phase, it is not needed at runtime. - Shared libraries are also collections of target files, with the suffix
.so
(shared object) in linux,.dylib
in mac, and.dll
in windows, and play a role in both the linking phase and the running phase of program compilation. During the linking phase, the linker verifies that the symbols (variables, methods, etc.) needed for program execution have been linked into the program or exist in one of the shared libraries. But the target file in the shared library is not linked to the final generated executable. In the Run phase, when the program starts, there is a program in the system - dynamic loader that checks which dynamic libraries are linked into the program and loads these dynamic libraries into memory to be executed with the program. So the shared libraries must be present when the program is running.
Static libraries are equivalent to the code contained in them being copied into the executable at compile time, while the code of shared libraries is loaded into memory at runtime, so if you compile with static libraries, the final generated executable will be larger than the one obtained by compiling with shared libraries.
Static library creation and linking
Use the ar tool to create static libraries. ar has the following functions.
- Create static libraries.
- Change the target files in the static library (as said before a static library is a collection of target files).
- View the names of the target files contained in the static library.
You can use man ar
to see the usage of the ar
command in linux.
-
Create a static library
A static library can be created with the following command.
1
$ ar -rc libutil.a util_file.o util_net.o util_math.o
The above command packages
util_file.o
,util_net.o
andutil_math.o
into the static librarylibutil.a
, and if thelibutil.a
file already exists, then it will add theutil_file.o
,util_net.o
andutil_math.o
files to the static library. files to the static library. Thec
option creates the library file if it does not exist, and ther
option replaces the target file if the target file to be packaged already exists in the library.You can also use gcc’s
-static
to generate static libraries.1
$ gcc *.o -static -o libname.a
Static file names generally start with the
lib
prefix and end with the.a
suffix, because the compiler looks for library files based on this feature when linking (explained below). -
Using static libraries
After we create the static library, we want to use it in our program. The library file can be linked into an executable file along with the target file by using the following command.
|
|
For example, the following example links the target file main.o
with the library libutil.a
into the executable prog.
|
|
It is important to note that.
- The
-L
option is used to indicate the library file directory, and.
indicates the current directory, so the library to be linked is in the current directory. - The
-l
option is used to indicate the name of the library file to be linked. Note that we have removed the prefixlib
and the suffix.a
from the library file name, so the library file name starts withlib
and ends with.a
. - Note that the library file should be placed after the target file, as detailed below
In the execution of gcc main.o -L. -lutil -o prog
, assuming that main.o
uses a function symbol from libutil.a
, such as the add
method, the linker executes as follows.
- The linker scans the target file and the static library from left to right
- when scanning
main.o
, it finds an unresolved symboladd
, remember this unresolved symbol - Scan
libutil.a
and find the previous unresolved symbol, so extract the relevant code - Finally, there are no unresolved symbols, the compilation and linking is completed, and the executable
prog
is generated
If the static library is placed in front of the target file, for example by executing gcc -L. -lutil main.o -o prog
, then the linker will execute as follows.
- the linker scans the static library and the target file in order from left to right
- scan
libutil.a
without extracting any code from the library because there are no unresolved symbols in front of it - When scanning
main.o
, the unresolved symbol exp is found - At the end of the scan, there are unresolved symbols, so the compilation and linking reports an error
Shared library creation and linking
The process of creating a shared library (dynamic library) is not much different from that of a static library, in that a set of target files are compiled and inserted into a library file. However, when linking a dynamic library, instead of “copying” all the required binary code into the executable, only some relocation and symbolic information is “copied”, with which the real linking process will be completed when the program runs.
-
Creating shared libraries The
-shared
argument to gcc creates shared libraries -
Links to shared libraries
The link shared library is the same as the link dynamic library command. Since gcc uses dynamic linking by default, if there are dynamic and static libraries with the same name, gcc will link the dynamic library, and you can use
-static
to specify the static library to be linked.1
$ gcc main.o -L. -lutil -o prog
The above command will link the
libutil.so
file.Normally, when a program is run, the system dynamic loader will look for shared libraries in some directory specified by the system (e.g. /lib, /usr/x11/lib, etc.). When we create a shared library, we can use the
LD_LIBRARY_PATH
environment variable to tell the dynamic loader to look in the specified directory.You can use the ldd command to view the shared libraries on which the executable depends.
1
$ ldd prog