Página 1 de 2
How to create a make file ?

Enviado:
20 Abr 2012 15:52
por fabim
Pessoal, antes de ontem eu voltei a brincar com linux novamente.
Tirei a poeira do kit 2440 e pau na máquina, e no LPC1788 também.
Bom, eu estou pensando em fazer um app onde são usados vários .H e vários .C, e não tenho ideia de como funciona a compilação deste tipo fora de alguma IDE que tenha arvore.
Alguém poderia me dar uma breve explicação de como proceder, de exemplos de criação de makefile etc.
Abraços

Enviado:
20 Abr 2012 21:58
por m3t4l3ir0
Estou usando esse.
- Código: Selecionar todos
TARGET = teste
PROJDIRS := src
SRCFILES := $(shell find $(PROJDIRS) -mindepth 1 -maxdepth 3 -name "*.c")
SRSFILES := $(shell find $(PROJDIRS) -mindepth 1 -maxdepth 3 -name "*.s")
OBJFILES := $(patsubst %.s,%.o,$(SRSFILES)) $(patsubst %.c,%.o,$(SRCFILES));
AUXFILES := Makefile link.ld
CC = arm-none-eabi-gcc
AS = arm-none-eabi-as
LD = arm-none-eabi-ld
OBJCOPY = arm-none-eabi-objcopy
CFLAGS := -Wall
ASFLAGS := -Wall
LDFLAGS := -Map $(TARGET).map -T link
all: $(OBJFILES)
$(LD) $(LDFLAGS) -o $(TARGET) $(OBJFILES)
$(OBJCOPY) --output-target ihex $(TARGET) $(TARGET).hex
clean:
rm $(OBJFILES)
rm $(TARGET)
rm $(TARGET).map
rm $(TARGET).hex
Espero que ajude.

Enviado:
21 Abr 2012 16:48
por fabim
não entendi uma virgula sequer !!

Enviado:
21 Abr 2012 18:46
por m3t4l3ir0
Coloquei alguns comentarios espero que ajude, uso esse makefile para alguns projetos com lpc2148 e com algumas modificações pra alguns projetos simples no pc tambem.
- Código: Selecionar todos
# nome do projeto
TARGET = teste
# Pastas contendos os arquivos para compilação
PROJDIRS := src
# Procuras todos os arquivos .c e .h nas pastas listadas em PRJDIRS
SRCFILES := $(shell find $(PROJDIRS) -mindepth 1 -maxdepth 3 -name "*.c")
SRSFILES := $(shell find $(PROJDIRS) -mindepth 1 -maxdepth 3 -name "*.s")
# Muda a extenção para usar com o LD
OBJFILES := $(patsubst %.s,%.o,$(SRSFILES)) $(patsubst %.c,%.o,$(SRCFILES));
# Apenas para listar os arquivos auxiliares
AUXFILES := Makefile link.ld
# Isso aqui ja esta no PATH export PATH=$PATH:/usr/arm/bin
CC = arm-none-eabi-gcc
AS = arm-none-eabi-as
LD = arm-none-eabi-ld
OBJCOPY = arm-none-eabi-objcopy
# Aqui vai as otimização para a cpu que você esta usando
CFLAGS := -Wall
ASFLAGS := -Wall
LDFLAGS := -Map $(TARGET).map -T link
# Aqui faz a ligação e gera o arquivo hex
all: $(OBJFILES)
$(LD) $(LDFLAGS) -o $(TARGET) $(OBJFILES)
$(OBJCOPY) --output-target ihex $(TARGET) $(TARGET).hex
# Faz a limpeza...
clean:
rm $(OBJFILES)
rm $(TARGET)
rm $(TARGET).map
rm $(TARGET).hex

Enviado:
21 Abr 2012 18:49
por m3t4l3ir0

Enviado:
21 Abr 2012 20:43
por fabim
Hum, então pelo que eu imagino.
Eu não vi em lugar algum, o usuários avisando a maquina make sobre o MAIN.
Então acredito que a máquina faz um cache de todos os arquivos e includes, encontra o MAIN, e em função disto ele vai chamando os arquivos, criando os obj e depois vai linkando tudo ?
Agora eu entendi o que o sistema make que você postou faz, mais não entendi como ?
Obrigatoriamente para poder utilizar o make, deverá existir um arquivo main.c ?
Ou conforme mencionei acima, a maquina de compilação descobre sozinho o loop main ?
Eu estou meio confuso, pois, o projeto que eu criei utilizando o keil, possui 9 drives de periféricos, 2 de framework, 2 de abstração de processos, e mais o main.
São 14 arquivos.c e mais uns trocentos arquivos.h que são compartilhados para todos os arquivos.c, haja visto que cada arquivo.c possui o seu arquivo.h de prototipação, constantes, etc.
Fui muito complexo, ou conseguiu me entender ?
Muito obrigado pela atenção !!

Enviado:
21 Abr 2012 21:22
por m3t4l3ir0
Nesse caso quem idica o inicio do programa e o arquivo script de link
a diretiva ENTRY indica o ponto de entrada no programa no caso o simbolo __reset no meu arquivo init2148.s
- Código: Selecionar todos
ENTRY(__reset)
MEMORY
{
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 512K
RAM (rw) : ORIGIN = 0x40000000, LENGTH = 32K
}
SECTIONS
{
.text :
{
* ( .text )
} > FLASH
.data :
{
* ( .data )
} > FLASH
.bss :
{
* ( .bss )
} > RAM
}

Enviado:
21 Abr 2012 21:31
por m3t4l3ir0
Hum, então pelo que eu imagino.
Eu não vi em lugar algum, o usuários avisando a maquina make sobre o MAIN.
Então acredito que a máquina faz um cache de todos os arquivos e includes, encontra o MAIN, e em função disto ele vai chamando os arquivos, criando os obj e depois vai linkando tudo ?
Exatamente ele faz um cache de todos os arquivos e vai criando os obj para no final linkar tudo
Agora eu entendi o que o sistema make que você postou faz, mais não entendi como ?
Obrigatoriamente para poder utilizar o make, deverá existir um arquivo main.c ?
Ou conforme mencionei acima, a maquina de compilação descobre sozinho o loop main ?
Não precisa do main quem indica o inicio do programa e o script de liker
Eu estou meio confuso, pois, o projeto que eu criei utilizando o keil, possui 9 drives de periféricos, 2 de framework, 2 de abstração de processos, e mais o main.
São 14 arquivos.c e mais uns trocentos arquivos.h que são compartilhados para todos os arquivos.c, haja visto que cada arquivo.c possui o seu arquivo.h de prototipação, constantes, etc.
O arquivo main não é obrigatório mais sempre uso pra ficar uma coisa mais organizada
no caso de usar uma ide normalmente ela ja escolhe um script adequado

Enviado:
21 Abr 2012 21:39
por m3t4l3ir0
Nem tudo ai deve estar certo, mais basicamente e isso que to usando aqui e me atende bem.

Enviado:
22 Abr 2012 14:30
por fabim
Bom, então a maquina vai procurar o arquivo .s, assim como no keil por exemplo, e partindo desta premissa, ele vai chamar o que for necessário.
Agora tenho só mais uma duvida mano!!
Sobre o toolchain.
Eu li em algum lugar, mais não me lembro em qual lugar foi !!
Eu tenho dois toolchain's aqui, que foram montados pelo buildroot, um para X86 e outro para ARM.
Como eu ainda não fiz nada na prática, eu estou em dúvida com isto.
Existe algum parâmetro que é passado dentro do make, que diz qual tipo de máquina é utilizada ?
Eu digo, tipo, ARMV9 ARMV7 ARMR4 etc
Sei que a topologia é a mesma, tipo, o BIN é exatamente o mesmo, independente de MMU ou não, mais não sei se é necessário algum tipo de definição.
Abraços, e muito obrigado pelas dicas

Enviado:
23 Abr 2012 08:46
por xultz
Fabim, eu entendo bem pouco do Makefile, mas o pouco que sei é o seguinte:
É um treco extremamente chato e burocrático que só programadores conseguem ver sentido.
Basicamente ele cria uma porrada de variáveis. Por exemplo, a linha
LD = arm-none-eabi-ld
atribui aquilo tudo do lado direito à variável LD.
O que mais tem em arquivo makefile é variável dentro de variável dentro de variável. A justificativa é que se precisa mudar alguma coisinha, muda na declaração da variável que o resto continua funcionando.
Outra coisa é a declaração de comandos. Por exemplo, o trecho
all: $(OBJFILES)
$(LD) $(LDFLAGS) -o $(TARGET) $(OBJFILES)
$(OBJCOPY) --output-target ihex $(TARGET) $(TARGET).hex
é executado quando é digitado o comando make all. O $(LD) ele substitui pelo conteúdo da variável, e faz o mesmo com as demais variáveis da linha, e executa. Se você for na linha de comando e digitar aquilo tudo que tem nas variáveis, o resultado é exatamente o mesmo.
Como eu não sou programador, meus makefiles eram mais simples e toscos, na etapa de compilação eu colocava cada arquivo que ele devia compilar, e na link eu colocava cada um que devia linkar. Se criava um novo .c eu colocava no makefile. Eu sei que tem jeito mais automático, mas eu gosto das coisas assim, mais simples, mesmo que mais trabalhosa.
O make tem umas espertezas, do tipo só compilar arquivo que foi modificado, se não mudar nada num .c, ele usa o .o e passa batido, a menos que você faça um make clean e apague todos os .o
Tem um aplicativo chamado automake que teoricamente analisa teus arquivos .c e gera um makefile, mas não faço ideia como usa.

Enviado:
23 Abr 2012 09:13
por fabim
É eu observei mesmo, que ele cria variaveis para o ambiente.
Bom, hoje eu vou tentar fazer algo do tipo pra ver se tenho resultado bom, caso contrario volto a bostar coisas neste post.
Muito thank you, pra vocês !!

Enviado:
23 Abr 2012 18:54
por m3t4l3ir0
Fabim o tipo de cpu voce muda na linha CFLAGS
CFLAGS := -Wall -mcpu=arm926ej-s
O compilador basta alterar as linhas
CC = arm-none-eabi-gcc
AS = arm-none-eabi-as
LD = arm-none-eabi-ld
OBJCOPY = arm-none-eabi-objcopy
Para
CC = gcc
AS = as
LD = ld
OBJCOPY = objcopy
depende de como você compilou seu toolchain.

Enviado:
24 Abr 2012 00:08
por msamsoniuk
eu acho que seria melhor, por exemplo:
CC=$(CROSS_COMPILE)gcc
AS=$(CROSS_COMPILE)as
LD=$(CROSS_COMPILE)ld
que eh mais ou menos como era (nao sei se ainda eh) usado no makefile do linux. para compilar p/ x86, simplesmente compila direto:
make
para compilar p/ outra plataforma usa:
make CROSS_COMPILE=arm-none-linux-gnueabi-
ou, se for sempre a mesma plataforma, coloca dentro do makefile:
CROSS_COMPILE=arm-none-linux-gnueabi-
e pronto.
m3t4l3ir0 escreveu:Fabim o tipo de cpu voce muda na linha CFLAGS
CFLAGS := -Wall -mcpu=arm926ej-s
O compilador basta alterar as linhas
CC = arm-none-eabi-gcc
AS = arm-none-eabi-as
LD = arm-none-eabi-ld
OBJCOPY = arm-none-eabi-objcopy
Para
CC = gcc
AS = as
LD = ld
OBJCOPY = objcopy
depende de como você compilou seu toolchain.

Enviado:
24 Abr 2012 10:25
por fabim
Uma pergunta tosca.
Quando eu executo o make, ele cria aquelas variáveis de ambiente, após acabar o make, e ele destruir o processo.
Ele limpa as variáveis criadas também, ou ficam carregadas, e transparentes para outras aplicações.?
Abraços, e obrigado !!