proceso de compilación gcc y combate real simple

El proceso de compilación de gcc y el combate de proyectos simple

1. El proceso de compilación de gcc

De hecho, cuando usamos cpp, usamos muchas bibliotecas, que están escritas por otros para que las usemos directamente, lo que nos facilita enormemente, pero cuando hacemos proyectos, a menudo necesitamos separar las funciones nosotros mismos, y luego Main Reference en la función, es necesario utilizar el proceso de compilación.
Como se muestra en la figura: en la
Inserte la descripción de la imagen aquí
figura anterior, nuestro archivo principal y los archivos de entrada y calcu son una carpeta. Los archivos de entrada y calcu se implementan por separado. Uno es de entrada y el otro es de cálculo. Main implementa el cálculo de adición digital, pero para la función Claramente los separaremos, para que sea un rendimiento de bajo acoplamiento en proyectos de gran escala.
Código fuente del proyecto: https://github.com/yjc-123/gcc-compile-process

En primer lugar, debemos comprender el proceso de compilación de gcc:
Inserte la descripción de la imagen aquí

Hay cuatro procesos:
precompilación -> compilación -> ensamblaje -> vinculación.
Aquí hablo principalmente del proceso de vinculación
. La
razón por la que la biblioteca estática se convierte en [biblioteca estática] (.a) es porque en la fase de vinculación, la Se generará el ensamblaje El archivo objeto .o y la biblioteca referenciada están vinculados y empaquetados en un archivo ejecutable. Por lo tanto, el método de enlace correspondiente se denomina enlace estático.

  • La vinculación de la biblioteca estática a la biblioteca de funciones se realiza en tiempo de compilación.
  • El programa no tiene nada que ver con la biblioteca de funciones cuando se está ejecutando y es fácil de trasplantar.
  • Se desperdician espacio y recursos, porque todos los archivos de objetos relacionados y las bibliotecas de funciones involucradas están vinculadas a un archivo ejecutable.
    Reglas de nomenclatura de bibliotecas estáticas de Linux:
    debe ser "lib [your_library_name] .a": lib es el prefijo, el medio es el nombre de la biblioteca estática y la extensión es .a

Biblioteca dinámica
Debido a que el espacio de la biblioteca estática se desperdicia más seriamente, la biblioteca dinámica no se vinculará al código de destino cuando se compile el programa, sino que se cargará cuando el programa se esté ejecutando. Si diferentes aplicaciones llaman a la misma biblioteca, solo se necesita una instancia de la biblioteca compartida en la memoria, evitando el problema del desperdicio de espacio. La biblioteca dinámica se carga cuando el programa se está ejecutando, lo que también resuelve el problema causado por la página de actualización, implementación y lanzamiento del programa por parte de la biblioteca estática. Los usuarios solo necesitan actualizar la biblioteca dinámica. A continuación, veamos la biblioteca dinámica.
Inserte la descripción de la imagen aquí

Inserte la descripción de la imagen aquí

Estas son las dos formas de vincular, y finalmente vemos lo que está sucediendo en el combate real.

2. Combate real

Toma mi ejemplo:
Inserte la descripción de la imagen aquí

Primero escribimos la función principal.
main.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "input.h" //导入库
#include "calcu.h"

extern int input(); //引入input.h中的函数
extern int calcu(int a,int b); //引入calcu中的函数

int main(int argc, char ** argv){
    
    

        int input_num_1 = input();
        int input_num_2 = input();

        printf("input over\n");
        int sum;
        sum = calcu(input_num_1, input_num_2);
        printf("calcu successful ,the sum is :%d\n",sum);
        return 0;
}

input.c

#include <stdio.h>
#include <stdlib.h>
int input(){
        int a;
        printf("input num:");
        scanf("%d",&a);
        return a;
} 

calcu.c

#include <stdio.h>
#include <stdlib.h>

int calcu(int a, int b){
    
    
        int sum;
        sum = a+b;
        return sum;
}

El anterior es el archivo c que implementa principalmente la función, pero el archivo principal no se refiere al archivo c cuando se cita, sino que usa el archivo de encabezado escrito por ellos.
calcu.h

#ifndef _CALCU_H
#define _CALCU_H

int calcu(int a, int b);

#endif

input.h

#ifndef _INPUT_H
#define _INPUT_H

int input();

#endif

Estos dos archivos de encabezado son responsables de declarar la función de la función, porque estos dos archivos de encabezado se introducen en main.c, pero la implementación está en input.cy calcu.c.
El siguiente paso es el Makefile para cada precio de venta.
Makefile_input

CC = gcc

libinput.so:
        $(CC) -fPIC -shared input.c -o libinput.so
        sudo cp libinput.so /usr/lib
        sudo cp libinput.so /usr/bin
clean:
        rm -rf libinput.so

Makefile_calcu

CC = gcc
  
libcalcu.so:
        $(CC) -fPIC -shared calcu.c -o libcalcu.so
        sudo cp libcalcu.so /usr/lib
        sudo cp libcalcu.so /usr/bin

clean:
        rm -rf libcalcu.so                      

La función de los dos archivos MAKE anteriores es generar una biblioteca dinámica y copiar la biblioteca dinámica a la biblioteca del sistema.
A continuación, mire el archivo que genera el Makefile final:

CC = gcc
  
main:
        $(CC) main.c \
                -I ./input -L ./input -linput \
                -I ./calcu -L ./calcu -lcalcu \
                -o main
clean:
        rm -rf main

Aquí debe utilizar los tres parámetros de gcc -I, -L y -l, que son la ubicación del archivo conjunto, la carpeta de la biblioteca dinámica y la biblioteca dinámica, respectivamente.
Por qué debería enfatizar que sudo cp libcalcu.so /usr/libcon esta declaración, porque por defecto cuando ejecutamos, el programa usr/libirá a buscar este archivo de biblioteca dinámica, si el error no existirá, por qué también necesitamos especificar el tiempo de ejecución debido a la necesidad de usar.

Supongo que te gusta

Origin blog.csdn.net/qq_45125250/article/details/112182503
Recomendado
Clasificación