Este é um mais um caso no qual uma explicação para uma pessoa nas redes sociais fica tão boa que vira um artigo no blog. O texto vai abaixo:
Um
header, um arquivo .h, NUNCA deverá gerar código ou dados. Pode definir
variáveis, mas somente como extern. Pode ter protótipos de funções,
definição de tipos, enum, macros, mas NUNCA deve definir uma variável
alocando espaço em memória ou ter o código de uma função.
Os .c e .cpp são onde estão as definições de variáveis e código.
Digamos
que vamos fazer um programa que é dividido em partes. A parte "a" que é
usada pela "b" e "c", e a parte "main" seria o programa principal e
depende diretamente das partes "b" e "c".
Então teríamos os arquivos a.h, a.c, b.h, b.c, c.h, c.c e main.c.
a.c
Define
algumas funções e variáveis que também serão vistas por outros módulos.
Inclui alguns headers padrão entre <> e a.h entre aspas.
a.h
Contém os protótipos das funções escritas em a.c, e em extern as variáveis de a.c que precisam ser vistas por outros módulos.
b.c
Define
algumas funções e variáveis que também serão vistas por outros módulos.
Inclui alguns headers padrão entre <>, e a.h e b.h entre aspas.
b.h
Contém os protótipos das funções escritas em b.c, e em extern as variáveis de b.c que precisam ser vistas por outros módulos.
c.c
Define
algumas funções e variáveis que também serão vistas por outros módulos.
Inclui alguns headers padrão entre <>, e a.h e c.h entre aspas.
c.h
Contém os protótipos das funções escritas em c.c, e em extern as variáveis de c.c que precisam ser vistas por outros módulos.
main.c
Já
que este depende diretamente somente de b.c e c.c, então inclui alguns
headers padrão entre <>, e b.h e c.h entre aspas. A dependência do
módulo "a" se faz indiretamente.
O Makefile deste projeto fica aproximadamente assim.
programa: main.c b.o c.o
cc -s -O3 -o programa main.c a.o b.o c.o
a.o: a.c a.h
cc -O3 -c a.c
b.o: b.h b.c a.o
cc -O3 -c b.c
c.o: c.h c.c a.o
cc -O3 -c c.c
E
assim só os módulos necessários é que serão compilados. Se editar o
main.c, só ele será compilado. Se editar o a.h ou o a.c, tudo será
compilado, pois tudo depende diretamente ou indiretamente deles. Se
editar b.c ou b.h, só b.c e main.c serão compilados.
Acho
que dá para fazer um Makefile mais detalhado, de modo que nem main.c
seja compilado do zero se os headers não forem modificados.
Aqui já terminou o texto da rede social, mas tenho este texto falando que vale para ler, pois justamente é sobre como variáveis são alocadas em memória, sobre extern, e sobre funções e variáveis locais a módulos.