Índice
1. O que é make/Makefile
Makefile
No Windows, depois de usar ides como VS e VS Code para escrever programas C/C++ para implementar um projeto, esses ides nos ajudarão a processar e gerar arquivos executáveis para esses programas.
Mas no Linux, se precisarmos implementar este projeto por nós mesmos através de instruções, os arquivos de origem em um projeto não são contados e são colocados em vários diretórios de acordo com o tipo, função e módulo. É muito inconveniente conectá-los um por um. conveniente.
E o Linux fornece uma ferramenta de compilação automática de projetos - Makefile
, que define uma série de regras para especificar, quais arquivos precisam ser compilados primeiro, quais arquivos precisam ser compilados depois, quais arquivos precisam ser recompilados e até mesmo executar operações funcionais mais complexas. Depois que o Makefile é escrito, apenas um comando make é necessário e todo o projeto é compilado automaticamente, o que melhora muito a eficiência do desenvolvimento de software.
Portanto, se você pode escrever um Makefile ou não, mostra se uma pessoa tem a capacidade de concluir projetos de grande escala.
fazer
make é uma ferramenta de comando que explica as instruções no makefile.De modo geral, a maioria dos IDEs tem esse comando, como: make no Delphi, nmake no Visual C++, make no GNU no Linux. Pode-se ver que o Makefile se tornou um método de compilação na engenharia.
Da seguinte forma: Usamos Makefile para gerar o arquivo executável do arquivo de linguagem C hello.c.
Quando o ambiente de desenvolvimento de um programador c é apenas um Linux conectado pelo terminal, Makefile é quase a única opção para construir projetos complexos, e é também se o projeto tem um projeto.Um divisor de águas da globalização, apesar de tudo, para aprender Linux, Makefile é importante o suficiente.
Resumir:
No Linux, make é um comando e Makefile é um arquivo.Os dois se complementam e realizam conjuntamente a "compilação automatizada" do projeto.
2. Lógica do Makefile
1. Dependência simples
Makefile consiste principalmente em e 依赖关系
, 依赖方法
enquanto as dependências consistem 目标
em依赖
O formato mais clássico é o seguinte:
target:dependence #依赖关系
command #依赖方法
Entre eles, target
está o destino a ser gerado, e dependence
é gerar as dependências exigidas pelo destino.Os dois formam uma relação de dependência, command
e é gerar os comandos a serem executados pelo destino.
Perceber:
- Pode haver várias ou nenhuma das dependências nas dependências
- Makefile também pode ser escrito como makefile, que não pode ser reconhecido por outro make. (Este artigo é Makefile)
- Cada dependência deve começar com a tecla [Tab]
Tome nosso código de teste acima como exemplo:
Para gerar o arquivo hello, você precisa depender do arquivo hello.c e, finalmente, gerar o arquivo de destino hello por meio das seguintes dependências.
2. Dependências complexas
No caso de teste acima, é um arquivo neste diretório. Se o arquivo nele não 依赖关系
estiver neste diretório , o sistema irá procurar automaticamente pelo mesmo arquivo no Makefile quando ele for gerado. Se o arquivo encontrado ainda não estiver em este diretório Em seguida, repita a operação acima. (O sistema usa o resultado da pilha para operar)依赖
依赖关系
依赖
目标文件
其它目标文件
Vamos primeiro modificar o caso de teste acima da seguinte maneira:
- Gera o arquivo hello e depende do arquivo hello.o
- Gera o arquivo hello.o e depende do arquivo hello.s
- Gera o arquivo hello.s e depende do arquivo hello.i
- Gera o arquivo hello.i e depende do arquivo hello.c
- O arquivo hello.c é encontrado neste diretório, use-o diretamente
Quando geramos um arquivo hello, os outros três são gerados 目标文件
e armazenados neste diretório
As dependências são as seguintes:
- Alterações em outros
目标文件
locais não afetarãotarget1
a geração,依赖
é a mesma pesquisa no arquivo Makefile目标文件
e não tem nada a ver com o arquivo de destino位置
. Ainda use o método acima para gerar arquivos.
Três. faça o comando
1. Uso de make
No Linux, após inserirmos o comando make, o sistema buscará o Makefile no diretório atual, executará a primeira dependência e o método dependente no arquivo após encontrá-lo, imprimirá o método dependente na tela e gerará o arquivo de destino.
Modificamos o caso de teste Makefile acima da seguinte maneira:
Gere dois conjuntos de dependências. (limpeza será discutido abaixo)
Da seguinte forma, para passarmos no teste de make
Quando queremos excluir outros arquivos de destino no Makefile gerado, precisamos especificar o arquivo de destino
make target1 target2 #make后可以有多个target目标文件
- fazer alvo
- tornar alvo1 alvo2
2. limpar
Em um projeto, alguns arquivos desnecessários são sempre limpos e geralmente os usamos clean
como arquivos de destino para a limpeza do projeto.
Como os arquivos de limpeza não precisam depender de outros arquivos, clean não tem dependências.
Quando clean não é o primeiro arquivo de destino no Makefile, precisamos adicionar clean após make para compilá-lo, assim como no teste anterior.
3. Alvo falso
Use .PHONY
alvos modificados, chamados de pseudo-alvos, no seguinte formato
.PHONY:target
Função : Tornar o arquivo sempre executável
Quando usamos make várias vezes para gerar o mesmo arquivo de destino, a compilação pode passar pela primeira vez, mas depois disso não pode passar, e os seguintes resultados serão fornecidos:
Neste momento, podemos usar .PHONY
para modificar o arquivo de destino hello para torná-lo um pseudo-alvo, que sempre pode ser compilado
Nota: Além .PHONY
de poder ser compilado sempre após a modificação ser usada, o arquivo de objeto limpo também pode ser compilado sempre, como segue:
4. Como o make determina se deve compilar
Testamos acima, se não for usado .PHONY
, make só pode ser usado uma vez e não pode ser compilado, então como make determina se deve compilar?
Quando terminarmos de escrever um projeto e quisermos implementá-lo (geralmente o projeto é muito grande, não é o ponto que testamos), vai perder muito tempo e performance. Não podemos deixar executar sem escrúpulos, só quando Depois da fonte arquivo for modificado, o projeto pode ser reimplementado para gerar um arquivo executável.
faça juízes se deve recompilar, com base na comparação do tempo de modificação do arquivo de origem e do arquivo de destino.
- Quando o tempo de modificação do arquivo de origem for menor que o do arquivo de destino, não compile
- Compilar quando o tempo de modificação do arquivo de origem for maior que o do arquivo de destino
No Linux, cada arquivo possui três vezes, conforme segue:
- Hora de acesso (Access): a hora do acesso mais recente ao conteúdo do arquivo, como cat, vim, less;
- Hora de modificação (Modify): a hora em que o conteúdo do arquivo foi modificado pela última vez, como nano, vim;
- Change time (Change): A hora em que os atributos do arquivo foram alterados recentemente, incluindo nome do arquivo, tamanho, conteúdo, permissões, proprietário, grupo etc., como nano/vim (alterações no tamanho do arquivo),
Podemos stat
visualizar esses três tempos do arquivo através de comandos
Impacto do tempo de acesso
Por que é necessário comparar o tempo de modificação de dois números para julgar se o make compila repetidamente?
No Linux, o acesso a um arquivo pode ser feito por meio cat、less
de instruções, e o arquivo acessado por essas duas instruções não modificará seu próprio tempo de acesso, pelos dois motivos a seguir:
- No Linux, acessar arquivos é uma operação muito frequente, e modificar o tempo de acesso ao arquivo requer operações de E/S todas as vezes. Se o tempo de acesso for modificado todas as vezes, isso aumentará a carga do sistema.
- Se um arquivo pode ser lido é determinado pela permissão do arquivo. Como o arquivo é legível, isso significa que o proprietário e o grupo do arquivo não recomendam sua leitura e não há necessidade de modificar o tempo de acesso a cada Tempo.
Portanto, o horário de acesso do Linux muda nos dois casos a seguir:
- Será atualizado quando as visitas se acumularem para um determinado número de vezes ou se acumularem por um período de tempo
- Quando o tempo de modificação do arquivo muda, ele muda de acordo
- A imagem acima usa apenas o arquivo de check-in do vim e não o modificou, mas o tempo de modificação também mudará de tempos em tempos
Resumindo: Se você quiser julgar se um arquivo foi modificado, você pode julgar se o tempo de modificação mudou.
Nota: O tempo de modificação muda e o arquivo não muda necessariamente
Efeito do tempo de modificação
Quando o tempo de modificação do arquivo de origem muda, isso significa que o arquivo de origem foi modificado. Neste momento, use make para compilar novamente. Primeiro usamos o vim para atualizar o tempo de modificação para julgar
que estamos usando o comando touch para atualizar o tempo todo do arquivo de origem (toque no arquivo: arquivo Não há criação de arquivo, o arquivo existe para atualizar o arquivo o tempo todo), julgar se o make é executado não tem nada a ver com modificar o conteúdo do arquivo de origem .
A partir do conhecimento acima, podemos concluir que se make é compilado está relacionado ao tempo de modificação do arquivo de origem , então podemos saber ,PHONY
que se o arquivo de destino é compilado não é julgado de acordo com o tempo de modificação, de modo a alcançar o efeito de estar sempre compilado.