About the basic operation of gcc and library functions in Liunx


Foreword: Since Linux is divided into server version and desktop version, this content requires that the first and second modules use the server version, and the third and fourth modules use desktop.

One, use gcc to generate static and dynamic libraries

1. Edit the generated programs hello.h, hello.c and main.c

⑴Create and enter the test folder

Insert picture description here
⑵Use the vim editor to create the three files needed

Program 1: hello.h

#ifndef HELLO_H 
#define HELLO_H 
void hello(const char *name); 
#endif //HELLO_H

Insert picture description here

⑶ Program 2: hello.c

#include <stdio.h>
 void hello(const char *name
 {
    
    
      printf("Hello %s!\n", name); 
 }

Insert picture description here

⑷Program 3: main.c

#include "hello.h"
int main() 
{
    
    
       hello("everyone"); 
       return 0;
}

Insert picture description here

2. Compile hello.c into .o file

⑴ Output code in the command input line

gcc -c hello.c

⑵ Output the ls command to see if the creation is successful

Insert picture description here

3. Create static library files from .o files

The naming convention of the static library file name is lib as the prefix, followed by the static library name, the extension is .a. For example, if the static library we will create is named myhello, the static library file name is libmyhello.a. You need to pay attention to this when creating and using static libraries. Create a static library with the ar command. Type the following command at the system prompt to create the static library file libmyhello.a, the command is as follows:

ar -crv libmyhello.a hello.o

Finally, use the ls command again to see if the creation is successful

Insert picture description here

4. The method of using static library in the program

After making the static library, how to use its internal functions? You only need to include the prototype declaration of these common functions in the source program that uses these common functions, and then specify the static library name when generating the object file with the gcc command, and gcc will link the common functions from the static library to the object file. Note that gcc will prefix the static library name with lib, and then append the static library file name obtained with the extension .a to find the static library file. In program 3: main.c, we include the header file hello.h of the static library, and then directly call the public function hello in the main program main. Next, first generate the target program hello, and then run the hello program to see the result.

method one

Enter the following code

gcc -o hello main.c -L. –lmyhello 

Insert picture description here

In the case of a custom library, main.c can also be placed between -L. and -lmyhello, but cannot be placed after them, otherwise it will prompt that myhello is not defined, but it is a system library, such as g++ -o main( -L/usr/lib) -lpthread main.cpp will not go wrong.
Then we enter ./hello to see the results of the operation

Insert picture description here

Method Two

gcc main.c libmyhello.a -o hello

Insert picture description here

Method Three

First generate main.o:

 gcc -c main.c 

Then generate the executable file:

gcc -o hello main.o libmyhello.a 

Insert picture description here

You can also do the same when linking dynamic libraries.
Run the executable program hello, the command is as follows:

./hello

View Results

Insert picture description here
Let's delete the static library file and try whether the public function hello is really connected to the target file hello.
Insert picture description here
From the result, we can see that the hello file has been successfully connected.

5. Create a dynamic library file from the .o file

The dynamic library file name naming convention is similar to the static library file name naming convention, and the prefix lib is added to the dynamic library name, but the file extension is .so. For example: we will create a dynamic library named myhello, then the dynamic library file name is libmyh ello.so. Use gcc to create dynamic libraries. Type the following command at the system prompt to get the dynamic library file libmyhello.so. The command is as follows:

gcc -shared -fPIC -o libmyhello.so hello.o  //-o 不能缺失

Insert picture description here

We also use the ls command to check whether the dynamic library file is generated
Insert picture description here

6. Use dynamic libraries in the program

Using a dynamic library in a program is exactly the same as using a static library. It also includes the prototype declaration of these public functions in the source program that uses these public functions, and then specifies the dynamic library name for compilation when generating the object file with the gcc command.
First, we first copy the libmyhello.so file to the directory /sur/lib

sudo mv libmyhello.so /usr/lib

Insert picture description here

Then run the gcc command to generate the object file, and then run it to see the result. The command is as follows:

gcc main.c libmyhello.so -o hallo

Insert picture description here
Finally, we enter the ./hello command to see if the file is generated successfully
Insert picture description here

2. The generation and use of static library .a and .so library files

1. Create and enter the test file

Insert picture description here

2. Use the vim editor to edit and generate the four files needed

⑴A1.c:

#include <stdio.h>
void print1(int arg)
{
    
     
 printf("A1 print arg:%d\n",arg);
}

Insert picture description here

⑵A2.c:

#include <stdio.h> 
void print2(char *arg)
{
    
    
 printf("A2 printf arg:%s\n", arg); 
}

Insert picture description here

⑶A.h:

#ifndef A_H 
#define A_H 
void print1(int); 
void print2(char *); 
#endif

Insert picture description here

⑷test.c:

#include <stdlib.h>
#include "A.h" 
int main()
{
    
     
 print1(1); 
 print2("test"); 
 exit(0); 
}

Insert picture description here

3. The generation and use of static library .a files

⑴ Generate target .o file

gcc -c A1.c A2.c

⑵ Generate static library .a file

ar crv libafile.a A1.o A2.o

Insert picture description here
(3) Use the .a library file to create an executable program
(if this method is used, make sure that the generated .a file and the .c file are stored in the same directory, that is, both are in the current directory)

gcc -o test test.c libafile.a
./test

Insert picture description here
So far, the static library file is created successfully

4. Generation and use of shared library .so files

⑴Generate the target file (xxx.o() The .o file generated here must add "-fpic" (small mode, less code), otherwise there will be an error when generating the .so file), the command is as follows:
⑴⑵⑶⑷

gcc -c -fpic A1.c A2.c

⑵Generate the shared library .so file The
command is as follows:

gcc -shared *.o -o libsofile.so

(3) Use the .so library file to create an executable program. The
commands are as follows:

gcc -o test test.c libsofile.so

⑷As before, we need to copy the libmyhello.so file to the directory /sur/lib

sudo cp libsofile.so /usr/lib

Insert picture description here
Take a look at the running results:
Insert picture description here

Three, examples of the use of gcc's dynamic library and static library

1. Write the x2x and x2y functions, whose function is to add two numbers and return the value.
Use the vim editor to write the following:
Insert picture description here
Insert picture description here
2. Write the main function
Insert picture description here
3. Apply the previous operations to generate .c and .o files

Insert picture description here
Insert picture description here
4. Then use gcc to link the target file of the main function with this static library file to generate the final executable program.
Insert picture description here
5. View the execution result
Insert picture description here
. 6. The size of the executable file at this time
Insert picture description here

Four, Linux GCC commonly used commands

1. One-step compilation instructions

gcc test.c -o test

Sample program:
Insert picture description here
Run result:
Insert picture description here
In essence, the above compilation process is divided into four stages, namely preprocessing (also known as preprocessing), compilation, assembly and linking

2. Pretreatment

The command is as follows

 gcc -E test.c

Insert picture description here
Because the compiled content is too long, not all of them are shown

3. Compile to assembly code

The command is as follows:

gcc -S test.c

Insert picture description here

4. Compilation

The command is as follows:

gcc -c test.s -o test.o

Insert picture description here

5. Connect

The command is as follows:

gcc test.o -o test

Insert picture description here

Five, the story behind the GCC compiler

1. Preparation

Since the GCC tool chain is mainly used in the Linux environment, this article will also use the Linux system as the working environment. In order to demonstrate the entire process of compilation, first create a working directory test0, and then use a text editor to generate a simple Hello.c program written in C language as an example, the source code is as follows:

#include <stdio.h> 
 int main(void) 
 {
    
     
 printf("Hello World! \n"); 
 return 0; 
 }

2. Compilation process

2.1 Pretreatment

The pretreatment process mainly includes the following processes:

(1) Delete all #defines, expand all macro definitions, and process all conditional precompilation instructions, such as #if #ifdef #elif #else #endif, etc.
(2) Process the #include precompiled directive, and insert the included file into the position of the precompiled directive.
(3) Delete all comments "//" and "/* */".
(4) Add line numbers and file identifiers to generate line numbers for debugging and compile error warning line numbers during compilation.
(5) All #pragma compiler directives are reserved, and they are needed in the subsequent compilation process.
The commands for preprocessing using gcc are as follows:
Insert picture description here

2.2 Compile

The compilation process is to perform a series of lexical analysis, syntax analysis, semantic analysis and optimization on the preprocessed file to generate the corresponding assembly code.
The command to compile with gcc is as follows:
Insert picture description here

2.3 Assembly

The assembly process is called to process the assembly code, generate instructions that the processor can recognize, and save them in an object file with a suffix of .o. Since each assembly statement almost corresponds to a processor instruction, the assembly is relatively simple compared to the compilation process. It can be translated one by one according to the comparison table of assembly instructions and processor instructions by calling the assembler as in Binutils. When the program is composed of multiple source code files, each file must first complete the assembly work and generate the .o object file before entering the next step of linking work. Note: The target file is already a part of the final program, but it cannot be executed before the link.
The commands for assembly using gcc are as follows:
Insert picture description here

2.4 link

Linking is also divided into static linking and dynamic linking. The main points are as follows:
(1) Static linking refers to adding the static library directly to the executable file during the compilation stage, so that the executable file will be larger. The linker copies the code of the function from its location (in a different object file or static link library) to the final executable program. In order to create an executable file, the main tasks that the linker must complete are: symbol resolution (associate the definition and reference of the symbol in the object file) and relocation (correlate the symbol definition with the memory address and then modify all references to the symbol ).
(2) Dynamic linking means that only some description information is added in the linking stage, and the corresponding dynamic library is loaded into the memory from the system when the program is executed.
In the Linux system, the order of the dynamic library search path during gcc compilation and linking is usually: first search from the path specified by the parameter -L of the gcc command and then address the path specified by the environment variable LIBRARY_PATH; then from the default path /lib, /usr /lib, /usr/local/lib search.
In a Linux system, the order of the dynamic library search path when executing binary files is usually: first search the dynamic library search path specified when compiling the target code; then address from the path specified by the environment variable LD_LIBRARY_PATH; then from the configuration file /etc/ The dynamic library search path specified in ld.so.conf; then search from the default path /lib, /usr/lib.
In a Linux system, you can use the ldd command to view a shared library that an executable program depends on.
Since the paths for linking dynamic libraries and static libraries may overlap, if there are static library files and dynamic library files with the same name in the path, such as libtest.a and libtest.so, the dynamic library is selected by default when gcc is linked, and libtest will be linked. .so, if you want gcc to choose to link libtest.a, you can specify the gcc option -static, which will force the use of static libraries for linking. Take Hello World as an example: If you use the command "gcc hello.c -o hello", the dynamic library will be used for linking. The size of the generated ELF executable file (use the Binutils size command to view) and the linked dynamic library (use Binutils) Ldd command view) as shown below
Insert picture description here

3. Analyze the ELF file

3.1 Section of ELF file

In the ELF file format, the sections between the ELF Header and Section Header Table are all sections. A typical ELF file contains the following sections:
.text: The instruction code section of the compiled program. .
rodata: ro stands for read only, that is, read-only data (such as constant const). .
data: initialized C program global variables and static local variables.
.bss: Uninitialized C program global variables and static local variables. .
debug: debug symbol table, the debugger uses the information in this section to help debugging.

You can use readelf -S to view the information of each section as follows:
Insert picture description here

3.2 Disassemble ELF

Since an ELF file cannot be opened as a normal text file, if you want to directly view the instructions and data contained in an ELF file, you need to use the disassembly method.

Use objdump -D to disassemble it as follows:
Insert picture description here

Six, nasm compilation example

The as assembler is aimed at the AT&T assembler code style, and the Intel-style assembler code can be compiled with the nasm assembler to generate an executive program. Download nasm on Ubuntu. The command is as follows:

sudo apt install nasm

1>, use vim to edit an .asm file, the code is as follows

; hello.asm
section .data            ; 数据段声明
        msg db "Hello, world!", 0xA     ; 要输出的字符串
        len equ $ - msg                 ; 字串长度
section .text            ; 代码段声明
global _start            ; 指定入口函数
_start:                  ; 在屏幕上显示一个字符串
        mov edx, len     ; 参数三:字符串长度
        mov ecx, msg     ; 参数二:要显示的字符串
        mov ebx, 1       ; 参数一:文件描述符(stdout)
        mov eax, 4       ; 系统调用号(sys_write)
        int 0x80         ; 调用内核功能
                         ; 退出程序
        mov ebx, 0       ; 参数一:退出代码
        mov eax, 1       ; 系统调用号(sys_exit)
        int 0x80         ; 调用内核功能

2>, use nasm -f elf64 hello.asm, will generate a hello.o file
3>, use ld -s -o hello hello.o, generate an executable file hello
4>, execute ./hello output
Insert picture description here

The size of the executable file at this time: the size of the
Insert picture description here
previous gcc compiled file: It

can be seen that the size of the executable file edited with nasm is much smaller than the size of the executable file compiled with gcc.

7. The main functions of the most commonly used cursor library (curses) in the terminal program of the Linux system

1. Read from the screen

chtype inch(void);  //返回光标位置字符
int instr(char *string);  //读取字符到string所指向的字符串中
int innstr(char *string, int numbers);//读取numbers个字符到string所指向的字符串中

2. Clear the screen

int erase(void);//在屏幕的每个位置写上空白字符
int clear(void);//使用一个终端命令来清除整个屏幕,相当于vi内的Ctrl+L
//内部调用了clearok来执行清屏操作,(在下次调用refresh时可以重现屏幕原文)
int clrtobot(void);//清除光标位置到屏幕结尾的内容
int clrtoeol(void);//清除光标位置到该行行尾的内容

3. Window movement and screen update

int mvwin(WINDOW *win, int new_y, int new_x);   //移动窗口
int wrefresh(WINDOW *win);
int wclear(WINDOW *win);
int werase(WINDOW *win);
//类似于上面的refresh, clear, erase,但是此时针对特定窗口操作,而不是stdcur
int touchwin(WINDOW *win);     //指定该窗口内容已改变、
//下次wrefresh时,需重绘窗口。利用该函数,安排要显示的窗口
 
int scrollok(WINDOW *win, bool flag);    //指定是否允许窗口卷屏
int scroll(WINDOW *win);   //把窗口内容上卷一行

8. As a tourist, experience the BBS of the ancient era that is about to disappear

1. In win10 system, "Control Panel" -> "Programs" -> "Enable or Close Windows Functions"
Insert picture description here
2. Enable "telnet client" and "Windows Subsystem for Linux" (will be used later)
Insert picture description here
Insert picture description here
3. Then Open a cmd command line window and enter telnet bbs.newsmth.net on the command line to experience

10. C language compilation under Linux environment to realize snake-eating game

Reference website link: C language compilation under Linux environment to realize the snake game.
Copy the above code into the linux file, and enter
gcc mysnake1.0.c -lcurses -o mysnake1.0 in the terminal, and finally run the executable file , You can experience the snake game.

Guess you like

Origin blog.csdn.net/weixin_47357131/article/details/109114655