O uso e desenvolvimento do Linux GCC

Por que compilar o programa?
• Linguagens de programação de alto nível (C, fortran) precisam ser compiladas por um compilador para gerar arquivos executáveis. Linguagens de script (matlab, shell) podem ser executadas apenas pela análise de comandos por meio do interpretador de comandos de script.


1. Uso do GCC

• GCC (compilador GNU de projeto C e C ++)
• GCC é usado para compilar programas C ou C ++, e programas Fortran são compilados com o compilador gfortran ou ifort.
• O programa C / C ++ tem quatro etapas, desde o início da codificação até a geração de arquivos binários executáveis: 1. Pré-processamento; 2. Compilação; 3. Montagem; 4. Vinculação
• Ao definir os parâmetros GCC, as quatro etapas acima podem ser concluídas em etapas. Ou defina os parâmetros para concluir a etapa inteira de uma vez.
• Opções comuns do GCC

Opções significado
-o file Salve o resultado processado pelo GCC como um arquivo. Este arquivo de resultado pode ser um arquivo pré-processado, uma consulta de montagem, um arquivo de destino ou o arquivo executável final. Supondo que o arquivo de origem a ser processado seja source.suffix, se esta opção for omitida, o nome padrão do arquivo executável gerado é a.out; o nome padrão do arquivo de destino source.o; o nome padrão do arquivo de montagem source.s; o arquivo pré-processado gerado é enviado para o dispositivo de saída padrão
-c Compile apenas os arquivos de origem e não crie links para gerar arquivos executáveis. Você pode usar esta opção quando estiver solucionando um arquivo de origem ou quando precisar apenas gerar um arquivo de destino
-g[gdb] Adicione informações de depuração ao arquivo executável para facilitar a depuração do programa. Se você usar as opções entre colchetes, significa adicionar informações de depuração estendidas do gdb, o que é conveniente para depurar com gdb
-O [0、1、2、3] Use a otimização para o código gerado. A parte entre colchetes é o nível de otimização. O padrão é a otimização de nível 2 e 0 significa nenhuma otimização. Observe que o uso de otimizações mais avançadas não resulta necessariamente em um código mais eficiente
-Dname [=definition] Defina o nome da macro com o nome como definição. Se a parte entre colchetes for o padrão, a macro é definida como 1
-Idir Adicionar um diretório adicional para pesquisar arquivos de cabeçalho ao compilar o diretório do programa de origem, ou seja, incluir adiciona um diretório adicional para pesquisar
-Ldir Adicione um diretório adicional para pesquisar arquivos ao compilar arquivos-dir de origem
-llibrary Adicione uma biblioteca adicional ao compilar o arquivo de link, o nome da biblioteca é library.a
-w Suprimir todos os avisos
-Wwarning É permitido gerar avisos do tipo aviso. O aviso pode ter vários valores, como principal e não utilizado. O mais comumente usado é all, o que significa que todos os avisos são gerados. Se o valor de aviso for erro, seu significado é tratar todos os avisos como erros, ou seja, parar de compilar quando ocorrer um aviso

O formato de uso básico do GCC:
gcc [选项] <文件名>

comando significado
gcc -E hello.c -o hello.i Gerar arquivos pré-processadoshello.i
gcc -S hello.c -o hello.s Gerar arquivos de montagemhello.s
gcc -c hello.c -o hello.o Gerar arquivo de objetohello.o
gcc hello.c -o hello Gerar arquivo executávelhello

Preste atenção no caso dos parâmetros! !

2. GCC desenvolve programa de linguagem C

1. Situação do programa de linguagem C de um único arquivo
• Use o comando para gcc hello.c –o hellogerar um arquivo executável o Hello
• use o comando ./hello execute o programa. Observe que o pré-requisito para a operação correta do programa é que o programa de origem não tenha erros.
2. Programa de linguagem C com vários arquivos
• a estrutura de diretório de vários arquivos é a seguinte:
main_function.ce summation.cno diretório atual
summation.hEm um diretório atual includesob
o compilador de linguagem C em execução, vários arquivos:

gcc ‐c main_function.c ‐Iinclude ‐o main_function.o
gcc ‐c summation.c ‐Iinclude ‐o summation.o
gcc main_function.o summation.o ‐o main_function
./main_function

Você também pode colar os códigos acima em um .shscript e executar o script para compilar e executar a linguagem C de vários arquivos.


• O gerenciamento de script de shell é uma maneira de gerenciar a compilação e a operação de vários programas C. No entanto, se houver muitos arquivos C, como gerenciamos a compilação do programa?
• O Linux nos fornece a ferramenta make para compilar o programa. No entanto, a premissa é que precisamos escrever o Makefile com antecedência.
• O que é um makefile? Um makefile é
um conjunto de regras para compilação e vinculação de programas: quais arquivos precisam ser compilados primeiro, quais arquivos precisam ser recompilados e até mesmo executar comandos do sistema operacional. A vantagem é a "compilação automática". Depois que o makefile é escrito, apenas um make é necessário e todo o projeto pode ser compilado automaticamente, o que melhora muito a eficiência do desenvolvimento de software.


Regras de escrita de Makefile:
• Destino: lista de dependências
• Comando (recuo de tabulação)

  • O destino pode ser um arquivo de destino, um arquivo executável ou um rótulo (rótulo)
  • A lista de dependências são os arquivos ou destinos necessários para gerar esse destino.
  • O recuo da tabulação é a distância que o cursor se move para a direita a partir da extremidade esquerda do texto pressionando a tecla tab. Este recuo é obrigatório e exclusivo, e você não pode usar a barra de espaço para mover a mesma distância.
  • O comando é o comando que precisa ser executado. (Como qualquer comando shell)

Esta é uma dependência do arquivo, ou seja, o destino depende dos arquivos da lista, a
regra de geração do destino é definida no comando. Se um ou mais arquivos na lista de dependências forem mais recentes que o arquivo de destino, a parte do comando será executada.
Esta é a regra de execução do makefile e também o conteúdo principal do makefile.

Ok, vamos tentar escrever o .shscript acima em um makefile:

main_function:main_function.o summation.o
	gcc main_function.o summation.o -o main_function
main_function.o:main_function.c ./include/summation.h
	gcc -c main_function.c -I./include -o main_function.o
summation.0:summation.c ./include/summation.h
	gcc -c summation.c -I./include -o summation.o
clean:
	rm -rf *.o

Dependências do arquivo:
1. O arquivo executável main_funciton depende dos arquivos de destino main_function.o e summation.o
2. O arquivo de destino main_function.o depende do arquivo de origem main_function.c e do arquivo de cabeçalho summation.h
3. O resumo do arquivo de destino .o depende de No arquivo de origem summation.c e no arquivo de cabeçalho summation.h
4. O destino limpo é um pseudo-destino, semelhante ao rótulo usado na instrução goto em Fortran.
Atenção especial deve ser dada ao gcc, o espaço antes do comando rm é uma posição de tabulação!


Como você pode ver acima, o arquivo o apareceu muitas vezes, e seu nome de arquivo também é muito longo, o que é mais difícil de representar, portanto, podemos usar uma variável para substituir o nome do arquivo do arquivo o. Por exemplo:

OBJ=main_function.o \ #定义变量OBJ表示o文件,\表示换行符
  summation.o
main_function:$(OBJ) 
	gcc $(OBJ) -o main_function
main_function.o:main_function.c ./include/summation.h
	gcc -c main_function.c -I./include -o main_function.o
summation.0:summation.c ./include/summation.h
	gcc -c summation.c -I./include -o summation.o
clean:
	rm -rf *.o

Nomenclatura de makefile
• Ao inserir o comando make sem parâmetros no terminal, ele irá
procurar por GNUmakefile, makefile, Makefile no diretório atual, e então compilar e vincular para gerar um arquivo executável.
• Quando o makefile tiver outros nomes, como makefile1
. Digite o comando make com parâmetros:make ‐f makefile1

Biblioteca estática
• Quando a biblioteca estática é vinculada durante a fase de vinculação, o arquivo executável gerado não será afetado pela biblioteca, exclua o arquivo da biblioteca e o programa ainda poderá ser executado.

ar ‐r libhello.a hello.o

• convenção de nomenclatura de biblioteca estática libXXX.a
gcc ‐c hello.cpara gerar arquivos de objeto hello.o
ar ‐r libhello.a hello.opara criar um arquivo de link estático libhello.a
gcc ‐o test test.c ‐L. –lhellocompilado e os arquivos vinculados testar
./testa implementação das
bibliotecas de exclusão de arquivo executável libhello.aapós ./testainda executar

Biblioteca dinâmica
• A biblioteca dinâmica é vinculada quando o programa está em execução. Exclua a biblioteca de vínculo dinâmico, e o programa que foi compilado e vinculado não poderá ser executado.
gcc ‐shared hello.c ‐o libhello.so
• A biblioteca dinâmica é criada diretamente do arquivo de origem
• A biblioteca dinâmica é nomeado por convenção libXXX.so
• O programa não pode ser executado se a biblioteca dinâmica for excluída

3. Depuração de programa

A depuração do programa é dividida em depuração estática e depuração dinâmica
• A depuração estática envolve erros gramaticais no programa de origem em tempo de compilação
• A depuração dinâmica envolve erros causados ​​por erros nos algoritmos ou processos do programa quando o programa está em execução, como um loop infinito,
se o o executável foi gerado com sucesso. Você pode usar o gdb para depuração dinâmica:

gdb ./newtest
l        #list 显示源代码
break 4  #第4行设置断点
r        #run  运行源代码,将在有break 的地方停下来
n        #next 执行到下一行
p var    #打印变量var的值
Ctrl+z/c #退出gdb,修改c文件

4. Exemplos

Rápido de usar

gcc hello.c -o hello     #c程序
g++ hello.cpp -o hello   #c++程序

O seguinte fornece um exemplo de compilação do gcc e execução de vários arquivos:
Estrutura do arquivo: Existem dois arquivos c main.c、summation.cno diretório atual:, o diretório atual tem um subdiretório chamado includee há um arquivo h nele:summation.h

1. Conteúdo do arquivo

O conteúdo de cada arquivo é o seguinte:
main.c

#include "stdio.h"
#include "summation.h"

int main()
{
    
    
	double a=1.0;
	double b=2.0;
	double c;
	c=summation(a,b);
	printf("a=%5.1f, b=%5.1f, a+b=%5.1f\n",a,b,c);
}

summation.c

#include "summation.h"
double summation(double a, double b)
{
    
    
	double c;
	c=a+b;
	return c;
}

summation.h

double summation(double a, double b);

2. Depuração e execução

main.sh
Etapas para criar e executar main.sh:

vi main.sh
chmod +x main.sh
./main.sh

O conteúdo de main.sh:

#!/bin/bash
gcc -c main.c -Iinclude -o main.o
gcc -c summation.c -Iinclude -o summation.o
gcc main.o summation.o -o main
./main

O acima é para obter um arquivo .sh, você também pode copiar e colar o conteúdo do arquivo .sh acima linha por linha no shell para executar.
makefile

main:main.o summation.o
	gcc main.o summation.o -o main
main.o:main.c ./include/summation.h
	gcc -c main.c -I./include -o main.o
summation.o:summation.c ./include/summation.h
	gcc -c summation.c -I./include -o summation.o
clean:
	rm -rf *.o

Etapas de operação:

make  #编译运行,直接出结果
make clean  #删除所有o文件

Makefile de versão de variável lenta

mc=main.c
mo=mian.o 
sc=summation.c
so=summation.o 
sh=summation.h
shp=./include/$(sh)
main:$(mo) $(so)
	gcc $(mo) $(so) -o main
$(mo):$(mc) $(shp)
	gcc -c $(mc) -I./include -o $(mo)
$(so):$(sc) $(shp)
	gcc -c $(sc) -I./include -o $(so)
clean:
	rm -rf *.o

Acho que você gosta

Origin blog.csdn.net/Gou_Hailong/article/details/109745963
Recomendado
Clasificación