How to create a make file ?

Discussão sobre linux para plataformas Intel x86 ou x64 (PC)

Moderadores: 51, guest2003, Renie, gpenga

How to create a make file ?

Mensagempor fabim » 20 Abr 2012 15:52

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
Mano, ve só.
Sou responsável pelo que escrevo!!! E não pelo que você entende !!!
fabim
Dword
 
Mensagens: 5001
Registrado em: 16 Out 2006 10:18
Localização: aqui uái!!!?

Mensagempor m3t4l3ir0 » 20 Abr 2012 21:58

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.
m3t4l3ir0
Bit
 
Mensagens: 13
Registrado em: 30 Ago 2009 12:35

Mensagempor fabim » 21 Abr 2012 16:48

não entendi uma virgula sequer !!
Mano, ve só.
Sou responsável pelo que escrevo!!! E não pelo que você entende !!!
fabim
Dword
 
Mensagens: 5001
Registrado em: 16 Out 2006 10:18
Localização: aqui uái!!!?

Mensagempor m3t4l3ir0 » 21 Abr 2012 18:46

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
m3t4l3ir0
Bit
 
Mensagens: 13
Registrado em: 30 Ago 2009 12:35

Mensagempor m3t4l3ir0 » 21 Abr 2012 18:49

Tambem usei muito o manual... http://web.mit.edu/gnu/doc/html/make_3.html
m3t4l3ir0
Bit
 
Mensagens: 13
Registrado em: 30 Ago 2009 12:35

Mensagempor fabim » 21 Abr 2012 20:43

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 !!
Mano, ve só.
Sou responsável pelo que escrevo!!! E não pelo que você entende !!!
fabim
Dword
 
Mensagens: 5001
Registrado em: 16 Out 2006 10:18
Localização: aqui uái!!!?

Mensagempor m3t4l3ir0 » 21 Abr 2012 21:22

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
}
m3t4l3ir0
Bit
 
Mensagens: 13
Registrado em: 30 Ago 2009 12:35

Mensagempor m3t4l3ir0 » 21 Abr 2012 21:31

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
m3t4l3ir0
Bit
 
Mensagens: 13
Registrado em: 30 Ago 2009 12:35

Mensagempor m3t4l3ir0 » 21 Abr 2012 21:39

Nem tudo ai deve estar certo, mais basicamente e isso que to usando aqui e me atende bem.
m3t4l3ir0
Bit
 
Mensagens: 13
Registrado em: 30 Ago 2009 12:35

Mensagempor fabim » 22 Abr 2012 14:30

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
Mano, ve só.
Sou responsável pelo que escrevo!!! E não pelo que você entende !!!
fabim
Dword
 
Mensagens: 5001
Registrado em: 16 Out 2006 10:18
Localização: aqui uái!!!?

Mensagempor xultz » 23 Abr 2012 08:46

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.
98% das vezes estou certo, e não estou nem aí pros outros 3%.
Avatar do usuário
xultz
Dword
 
Mensagens: 3001
Registrado em: 13 Out 2006 18:41
Localização: Curitiba

Mensagempor fabim » 23 Abr 2012 09:13

É 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 !!
Mano, ve só.
Sou responsável pelo que escrevo!!! E não pelo que você entende !!!
fabim
Dword
 
Mensagens: 5001
Registrado em: 16 Out 2006 10:18
Localização: aqui uái!!!?

Mensagempor m3t4l3ir0 » 23 Abr 2012 18:54

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.
m3t4l3ir0
Bit
 
Mensagens: 13
Registrado em: 30 Ago 2009 12:35

Mensagempor msamsoniuk » 24 Abr 2012 00:08

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.
Avatar do usuário
msamsoniuk
Dword
 
Mensagens: 2935
Registrado em: 13 Out 2006 18:04

Mensagempor fabim » 24 Abr 2012 10:25

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 !!
Mano, ve só.
Sou responsável pelo que escrevo!!! E não pelo que você entende !!!
fabim
Dword
 
Mensagens: 5001
Registrado em: 16 Out 2006 10:18
Localização: aqui uái!!!?

Próximo

Voltar para Linux ( x86 ou x64 )

Quem está online

Usuários navegando neste fórum: Nenhum usuário registrado e 1 visitante

x