Eu tenho um Makefile
que diz:
aaa:bbb
echo 456
bbb:
echo 123
Quando não há nenhum bbb
arquivo no diretório, essas duas regras serão executadas independentemente de haver um aaa
arquivo ou não.
Mas por que?
Eu tenho um Makefile
que diz:
aaa:bbb
echo 456
bbb:
echo 123
Quando não há nenhum bbb
arquivo no diretório, essas duas regras serão executadas independentemente de haver um aaa
arquivo ou não.
Mas por que?
por que quando o make
comando no código do código gera um make: *** No targets. Stop.
código de erro:
NAME := program
FLAG := -std=c11 -Wall -Wextra -Werror -Wpedantic
all: $(NAME)
$(NAME): *.c
clang $(FLAG) -o $(NAME) *.c -lm
clean:
rm -rf $(NAME)
reinstall: clean all
Aqui está a linha de comando que recebi de um fabricante de chips:
make sunxi_defconfig ARCH=arm CROSS_COMPILE=arm-linux-
Certamente falhou com a mensagem de
*** Error during writing of the configuration.
make[1]: *** [scripts/kconfig/Makefile:121: nanopi_h3_defconfig] Error 1
make: *** [Makefile:479: nanopi_h3_defconfig] Error 2
Encontrei sunxi_defconfig
na pasta configs/
. Por que o arquivo de configuração é sunxi_defconfig
colocado na lista de parâmetros como um destino no make
comando? Estudei make
o manual de comandos com atenção e não encontrei o caso de colocar um arquivo de configuração como alvo de criação. A linha de comando está errada? Como posso consertar isso?
Eu tenho isto:
.PHONY: check
check:
script-returning-nearly-always-zero
obj2.img: obj1.img check
make-obj2-from-obj1
Então, a lógica é que eu quero gerar novamente obj2.img
, se for mais antigo que obj1 (ou nem existir). No entanto, quero um erro se o alvo de "verificação" falhar.
Agora meu problema é que o gerador de obj2.img
sempre roda. Eu acho que pode ser porque check
é .PHONY
.
De alguma forma, posso pedir ao make para gerar novamente obj2.img
apenas se obj1.img
for mais recente?
Estou simplesmente estudando make. E me deparo com a pergunta sobre o arquivo intermediário de remoção automática do make. Eu gostaria de prever melhor como o make marcaria o arquivo intermediário (ou seja, responderia "Removê-lo automaticamente?"), Então escrevi um projeto fictício como este para demonstrar minha pergunta:
olá.h
#ifndef HELLO_H
#define HELLO_H
void hello(const char *name);
#endif
olá.c
#include <stdio.h>
void hello(const char *name) {
printf("Hello %s\n", name);
}
main.c
#include "hello.h"
int main() {
hello("world");
return 0;
}
makefile
all: main
./main
clean:
rm -f *.o *.a
rm -f main
hello.o:
gcc -c hello.c
libmyhello.a: hello.o
ar -crv $@ hello.o
main: libmyhello.a
gcc -L. -o $@ [email protected] -lmyhello
.PHONY: all clean
Quando eu faço main
, requer libmyhello.a
. libmyhello.a
requer hello.o
. Se bem entendi, hello.o
deve ser um arquivo intermediário. Mas não foi excluído no make main
processo.
Por que é? Como saber se o make irá tratar um arquivo como arquivo intermediário e removê-lo?
Aqui está o meu Makefile simples:
#create an exe file
run: link
gcc link.o -o run
#sketch link.o
link.o: main.o sum.o
ld -r main.o sum.o -o link.o
#sketch main.o
main.o: main.c
gcc -c main.c -o main.o
#sketch sum.o
sum.o: sum.c
gcc -c sum.c -o sum.o
#make clean recipie
clean:
rm *.o
rm run
Esse makefile pode ser algo meio imaturo ou fraco. Mas minha real preocupação é com o processo que o alvo está sendo atingido. Antes de contar a pergunta real, vamos primeiro ver sua saída.
gcc -c main.c -o main.o
gcc -c sum.c -o sum.o
ld -r main.o sum.o -o link.o
cc link.o -o link
gcc link.o -o run
Minha pergunta é: isso é por causa da link
dependência run
ou por causa da link.o
menção na seção de comando de run
, make
o comando procura link.o
e novamente é por causa main.o
sum.o
das dependências dele link.o
procura por dependências de menção ou por causa main.o
sum.o
da seção de comando e o primeiro comando no destino main.o
é encontrados e sum.o
e link.o
respectivamente? É por causa do arquivo mencionado nas dependências ou menção do arquivo no comando?
Eu preciso criar links para vários diretórios em um Makefile.
Os links (para todos os arquivos em ./topdir/
) devem ir de ./anotherdir/<file>
para ./topdir/<file>
.
Eu tentei:
create-links: ./topdir/*/
@for f in $^; do \
echo "this is my path: [$${f}]" && \
DIR=$(shell basename $${f}) && \
echo "make link from ./anotherdir/$(DIR)" ;\
done
Existem esses arquivos em ./topdir
dir1
dir2
file1
file2
f
é atribuído corretamente com ambos os diretórios e seu caminho relativo (por exemplo ./topdir/dir1
, ).
Eu só preciso do dirname sem o caminho. Isto é o que basename
deve fazer.
Mas DIR está sempre vazio. Por quê?
Estou tentando construir o opendingux a partir do repositório/source do github. https://github.com/OpenDingux/buildroot
OpenDingux é uma distribuição Linux embarcada focada em jogos (retro).
Eu clonei o repositório e executei os comandos abaixo.
cd ./buildroot;
export CONFIG='gcw0'; bash ./rebuild.sh;
A saída do comando acima foi praticamente uma parede de texto, muito longa para postar nesta pergunta, pois tem 22.301 linhas. A saída completa está disponível aqui https://paste.ee/p/UInYW
Eu cortei o erro que estou recebendo no entanto abaixo.
/bin/bash: line 2: 186552 Killed build/genautomata ../../gcc/common.md ../../gcc/config/mips/mips.md insn-conditions.md > tmp-automata.c
make[3]: *** [Makefile:2459: s-automata] Error 137
make[3]: *** Waiting for unfinished jobs....
rm gcc.pod
make[2]: *** [Makefile:4415: all-gcc] Error 2
make[1]: *** [package/pkg-generic.mk:270: /home/vagrant/buildroot/output/gcw0/build/host-gcc-initial-11.1.0/.stamp_built] Error 2
make: *** [Makefile:84: _all] Error 2
make -v return:
GNU Make 4.2.1
Built for x86_64-pc-linux-gnu
Copyright (C) 1988-2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Em um diretório, um arquivo: makefile
ifneq ($(jobserver),T)
$(error This makefile only works with a Make program that supports $$(eval))
endif
invocar make por tipo make
makefile:2: *** This makefile only works with a Make program that supports $(eval). Stop.
até eu tento
ifneq ($(eval),T)
$(error This makefile only works with a Make program that supports $$(eval))
endif
ainda volta
makefile:2: *** This makefile only works with a Make program that supports $(eval). Stop.
Eu sigo o tutorial da internet, esses makefile testam um recurso/função no make está disponível ou não. Não deve dar erro.
Estou executando o debuild e o lintian encontra automaticamente 2 erros que tenho com a página de manual.
a estrutura do projeto depois de executar o comando debuild se parece com isso
hoseopjeong@hoseopjeong-VirtualBox:~/Documents/HoseopJeong_debian_lab9/debianlaboration9-0.0$ tree
.
├── debian
│ ├── changelog
│ ├── compat
│ ├── control
│ ├── copyright
│ ├── debhelper-build-stamp
│ ├── debianlaboration9
│ │ ├── DEBIAN
│ │ │ ├── control
│ │ │ └── md5sums
│ │ └── usr
│ │ ├── bin
│ │ │ └── electrotest_standalone
│ │ └── share
│ │ ├── doc
│ │ │ └── debianlaboration9
│ │ │ ├── changelog.Debian.gz
│ │ │ ├── copyright
│ │ │ └── README.Debian
│ │ └── man
│ │ └── electrotest_standalone.man.gz
│ ├── debianlaboration9.debhelper.log
│ ├── debianlaboration9.substvars
│ ├── files
│ ├── patches
│ │ └── series
│ ├── README.Debian
│ ├── rules
│ ├── source
│ │ ├── format
│ │ └── local-options
│ └── watch
├── electrotest_standalone
├── electrotest_standalone.man
├── Makefile
└── src
└── electrotest_standalone.c
o makefile que o debuild usa se parece com isso
prefix = /usr/local
all: electrotest
electrotest: ./src/electrotest_standalone.c
gcc -o electrotest_standalone ./src/electrotest_standalone.c -lm
install:electrotest
install -D electrotest_standalone \
$(DESTDIR)$(prefix)/bin/electrotest_standalone
mkdir $(DESTDIR)/usr/share
mkdir $(DESTDIR)/usr/share/man
cp electrotest_standalone.man \
$(DESTDIR)/usr/share/man/
clean:
-rm -f electrotest
distclean:clean
uninstall:
-rm -f $(DESTDIR)$(prefix)/bin/electrotest_standalone
.PHONY: all install clean distclean uninstall
Então, até onde eu entendo, um arquivo man deve estar localizado dentro de usr/share/man. É por isso que criei pastas ushare/man manualmente com Makefile e posso ver quando executo o comando debuild, debuild cria essas pastas e com cp electrotest_standalone.man \ $(DESTDIR)/usr/share/man/
, debuild também consegue copiar esse arquivo na pasta man que gerou por debuild. No entanto, lintian ainda não gosta disso.
Quando eu executo o debuild, o lintian mostra
Now running lintian...
W: debianlaboration9: improbable-bug-number-in-closes 10
E: debianlaboration9: manpage-in-wrong-directory usr/share/man/electrotest_standalone.man.gz
W: debianlaboration9: binary-without-manpage usr/bin/electrotest_standalone
Ele diz que meu arquivo man está no lugar errado e o arquivo binário eletrotest_standalone não tem nenhuma página man. O que estou fazendo errado?
Atualmente minha página de manual tem apenas uma única frase
NAME: electrotest_standalone