Compilation toolchain
- When we write programs, we use Integrated Development Environment (IDE: Integrated Development Environment), which can be very convenient for us programmers to write programs, but it is also relatively troublesome to configure. In the Linux environment, we use the compilation toolchain, also known as the software development kit (SDK: Software Development Kit). common compilation toolchain in the Linux environment are: GCC and Clang, we use GCC.
compiling
preliminary
- Check if gcc, g++, gdb are installed on the current system.
gcc --version
g++ --version
gdb --version
- Uninstalled can be installed by command.
sudo apt update
sudo apt install gcc g++ gdb
Generate executable program/compile process
gcc -E -o # -E activates preprocessing, generates preprocessed files
gcc -S -o # -S activates preprocessing and compilation, generates assembly code
gcc -c -o # -c activates preprocessing, compilation and assembly, generates target files
gcc -o hello # Execute all phases, generate executable program
gcc -c # Generate the target file, gcc will generate it based on the filename
gcc -o hello # Generate the executable program hello, here we need to specify the name of the executable program, otherwise it will be generated by default
gcc -o hello # Compile the link to generate the executable program hello.
Difference between gcc and g++
-
gcc
cap (a poem)g++
allGNU (organization)
A compiler for the -
Myth 1:
gcc
Only c code can be compiled, g++ can only compile c++ code.- which is suffixed by
.c
The.gcc
Think of it as a C program, andg++
regard asc++
programs - which is suffixed by
.cpp
that both would consider to beC++
Program.C++
The grammatical rules are a bit more rigorous - compilation stage.
g++
will invokegcc
ForC++
code, the two are equivalent, but because thegcc
command does not automatically match theC++
library link used by the program, so it is common to use theg++
to complete the link, for the sake of uniformity, simply compile/link with theg++
up, which gives the illusion as if thecpp
The program can only be used withg++
seems as if
- which is suffixed by
-
Myth 2:
gcc
will not be defined__cplusplus
Macro, andg++
be sure to- In fact, this macro simply indicates whether the compiler will interpret the code in C or C++ syntax
- As mentioned above, if the suffix
.c
and utilizesgcc
compiler, then the macro is undefined, otherwise, it is defined
-
Myth 3: Compiling can only be done with
gcc
The link can only be used with theg++
- Strictly speaking, this sentence is not an error, but it confuses the concept and should be stated as follows: compiling can be done with the
gcc/g++
and the link can be usedg++
orgcc -lstdc++
-
gcc
command does not automatically link with libraries used by C++ programs, so it is common to use theg++
to complete the link. However, during the compilation phase, theg++
will automatically invokegcc
They are equivalent.
- Strictly speaking, this sentence is not an error, but it confuses the concept and should be stated as follows: compiling can be done with the
conditional compilation
preprocessing instruction
1) #if [#elif] [#else] #endif
2) #ifdef [#elif] [#else] #endif
3) #ifndef [#elif] [#else] #endif
command format
1. Format of the #if instruction
#if constant expressions
...
#endif
When the preprocessor encounters a #if directive, it calculates the value of the constant expression that follows. If the value of the expression is 0, the code between #if and #endif is deleted during preprocessing; otherwise, the code between #if and #endif is retained and left to the compiler.
The #if instruction is often used to debug programs, as shown below:
#define DEBUG 1
...
#if DEBUG
printf("i = %d\n", i);
printf("j = %d\n", j);
#endif
2. The defined operator
is a preprocessor operator followed by an identifier. The value is 1 if the identifier is a defined macro, and 0 otherwise. defined operators are often used with #if directives, for example:
#if defined(DEBUG)
...
#endif
The code between #if and #endif is retained in the program only if DEBUG is defined as a macro. the parentheses after defined are not required, so it can be written like this:#if defined DEBUG
The defined operator only detects if the DEBUG has been defined as a macro, so we don't need to assign a value to the DEBUG:#define DEBUG
3. Format of #ifdef
#ifdef identifier
...
#endif
When an identifier has been defined as a macro, the code between #ifdef and #endif is retained; otherwise, the code between #ifdef and #endif is deleted in the preprocessing phase. Equivalent:
#if defined(identifier)
...
#endif
4. Format of #ifndef
#ifndef identifier
...
#endif
It does exactly the opposite of #ifdef: it preserves the code between #ifndef and #endif when the identifier is not defined as a macro.
corresponds English -ity, -ism, -ization
1. Preparation of portable programs
The following examples include the corresponding code in the program depending on whether WIN32, MAC_OS, or LINUX is defined as a macro:
#if defined(WIN32)
...
#elif defined(MAC_OS)
...
#elif defined(LINUX)
...
#endif
We can select a specific operating system by defining one of these three macros at the beginning of the program
2. Providing default definitions for macros
We can detect if a macro is defined, and if not, provide a default definition:
#ifndef BUFFER_SIZE
#define BUFFER_SIZE 1024
#endif
3. Avoiding duplicate header file inclusion
Including the same header file more than once may result in compilation errors (e.g., header files containing definitions of types). Therefore, we should avoid including header files more than once. This is easily accomplished by using #ifndef and #define:
#ifndef __WD_FOO_H
#define __WD_FOO_H
typedef struct {
int id;
char name[25];
char gender;
int chinese;
int math;
int english;
} Student;
#endif
4. Temporary blocking of code containing comments
We can't use /.../"Comment out" already contains /.../commented code, i.e.Cannot nest multi-line commentsBut we can do it with the #if directive. But we can use the #if directive for that:
#if 0
Contains /*... */ commented code
#endif
Note: This type of shielding, which we call"Conditional shielding."。
Links to libraries
storehouse
- A library file is a class of files on a computer that can simply be viewed as a code repository that provides the user with a number ofVariables, functions or classes that can be used directly
- Libraries are a special kind of program, and writing a program for a library is not much different from writing a general program, except that theLibraries can't be run on their own
- There are two types of library files.
static library
cap (a poem)Dynamic libraries (shared libraries)
. The difference is:- static libraryCopied into the program during the linking phase of the program
- dynamic library (computing)Instead of being copied into the program during the linking phase, the program is dynamically loaded into memory by the system at runtime for the program to call.
- Benefits of the library:Code Confidentiality cap (a poem)Ease of deployment and distribution
Static library creation
- rules and regulations
- Example: Have the file shown below (where each sub-file is used to implement the quadratic operations), package it up asstatic library
source code (computing)
#include <>
int add(int a, int b)
{
return a+b;
}
source code (computing)
#include <>
int sub(int a, int b)
{
return a-b;
}
source code (computing)
#include <>
int mul(int a, int b)
{
return a*b;
}
source code (computing)
#include <>
double div(int a, int b)
{
return (double)a/b;
}
header file
#ifndef _HEAD_H
#define _HEAD_H
// Addition
int add(int a, int b); // Subtract.
// Subtraction
int sub(int a, int b); // Multiply.
// Multiplication
int mul(int a, int b); // multiplication
// division
double div(int a, int b); // multiplication
#endif
source file
#include <>
#include ""
int main()
{
int a = 20;
int b = 12;
printf("a = %d, b = %d\n", a, b);
printf("a + b = %d\n", add(a, b));
printf("a - b = %d\n", subtract(a, b));
printf("a * b = %d\n", multiply(a, b));
printf("a / b = %f\n", divide(a, b));
return 0;
}
- Viewing the directory structure
tree
-
generating
.o
Documentation:gcc -c filename
-
commander-in-chief (military)
.o
File Packaging:ar rcs
Use of static libraries
-
requireStatic library files and corresponding header files
-
Compile and run:
gcc -o app -I ./include -l calc -L ./lib
-
-I ./include
: Specify the header file directory, if not, a compilation error occurs. -
-l calc
: Specify the name of the static library, if not, a link error occurs. -
-L ./lib
: Specify the location of the static library, if not, a link error occurs. -
execute correctly(Successfully generated)
app
(executable file) -
test program
-
Dynamic library creation
-
rules and regulations
-
Example: Have the file shown below (where each sub-file is used to implement the quadratic operations), package it up asdynamic library (computing)
-
generating
.o
Documentation:gcc -c -fpic filename
-
commander-in-chief (military)
.o
File Packaging:gcc -shared -o
-
Use of dynamic libraries
-
requireDynamic library files and corresponding header files
-
Locating dynamic libraries (See Workaround for reasons -> How to locate shared library files(where the path is the location of the dynamic library)
-
Method 1: Modify the environment variable thatCurrent Terminal EffectiveThe exit from the current terminal is disabled.
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/u/Desktop/Linux/calc/lib
-
Method 2: Modify environment variables, user level permanent configuration
# Modify ~/.bashrc vim ~/.bashrc # Add the following line to ~/.bashrc, save and exit export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/u/Desktop/Linux/calc/lib # Make the changes take effect source ~/.bashrc
-
Method 3: Modify environment variables, system level permanent configuration
# Modify /etc/profile sudo vim /etc/profile # Add the following line to ~/.bashrc, save and exit export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/u/Desktop/Linux/calc/lib # Make the changes take effect source /etc/profile
-
Method 4: Modification
List of /etc/ files
# Modify /etc/ sudo vim /etc/ # Add the following line to /etc/, save and exit /home/u/Desktop/Linux/calc/lib # Update the configuration sudo ldconfig
-
-
There is the following structure file, where
test file
-
Configuring Environment Variables
-
Compile and run:
gcc -o app -I ./include -l calc -L ./lib
-
test program
-
If the absolute path to the dynamic library file is not added to the environment variable, the following error occurs
Working Principle
-
Static libraries:
GCC
When linking is performed, the code in the static library is packaged into the executable program -
Dynamic libraries:
GCC
When linking, the code of the dynamic library is not packaged into the executable program. -
After the program is started, the dynamic libraries are dynamically loaded into memory via the
ldd (list dynamic dependencies)
command to check dynamic library dependencies -
How do I locate a shared library file?
- When the system loads executable code, it knows the names of the libraries it depends on, but it also needs to know the names of the libraries in theabsolute pathThe system's dynamic loader is then required to obtain the absolute path. The system's dynamic loader is needed to get the absolute path.
- insofar as
elf format
The executable program that is created by theto accomplish this, it successively searches for
elf file
(used form a nominal expression)DT_RPATH
Paragraph =>Environment variable LD_LIBRARY_PATH
=>List of /etc/ files
=>/lib/
,usr/lib
directory and load the library file into memory.