Eu tenho um projeto onde a estrutura de diretórios é assim:
$projectroot
|
+---------------+----------------+
| | |
part1/ part2/ part3/
| | |
+------+-----+ +---+----+ +---+-----+
| | | | | | |
data/ src/ inc/ src/ inc/ src/ inc/
Como devo escrever um makefile que estaria na parte / src (ou onde quer que realmente) pudesse complementar / vincular os arquivos de origem c / c ++ na parte? / Src?
Posso fazer algo como -I $ projectroot / part1 / src -I $ projectroot / part1 / inc -I $ projectroot / part2 / src ...
Se isso funcionar, existe uma maneira mais fácil de fazer isso. Já vi projetos em que há um makefile em cada parte correspondente? pastas [neste post eu usei o ponto de interrogação como na sintaxe do bash]
recursive invocation
, que pode ser bastante elegante.Respostas:
A forma tradicional é ter um
Makefile
em cada um dos subdiretórios (part1
,part2
, etc.) que lhe permite construí-los de forma independente. Além disso, tenha umMakefile
no diretório raiz do projeto que cria tudo. A "raiz"Makefile
seria algo como o seguinte:Como cada linha em um destino make é executada em seu próprio shell, não há necessidade de se preocupar em fazer o backup da árvore de diretórios ou de outros diretórios.
Sugiro dar uma olhada na seção 5.7 do GNU make manual ; é muito útil.
fonte
+$(MAKE) -C part1
etc. Isso permite que o controle de tarefas do Make trabalhe nos subdiretórios.Se você tiver código em um subdiretório dependente do código em outro subdiretório, provavelmente será melhor ter um único makefile no nível superior.
Consulte Consideração sobre a recursividade considerada prejudicial para obter a justificativa completa, mas basicamente você quer ter todas as informações necessárias para decidir se um arquivo precisa ou não ser reconstruído, e isso não acontecerá se você contar apenas um terço dos seu projecto.
O link acima parece não estar acessível. O mesmo documento é acessível aqui:
fonte
A opção VPATH pode ser útil, o que indica para que diretórios procurar o código-fonte. Você ainda precisaria de uma opção -I para cada caminho de inclusão. Um exemplo:
Isso localizará automaticamente os arquivos partXapi.cpp correspondentes em qualquer um dos diretórios especificados pelo VPATH e os compilará. No entanto, isso é mais útil quando o diretório src é dividido em subdiretórios. Pelo que você descreve, como outros já disseram, provavelmente você está melhor com um makefile para cada parte, especialmente se cada parte puder ficar sozinha.
fonte
VPATH=..
funcionou para mim!Você pode adicionar regras ao Makefile raiz para compilar os arquivos cpp necessários em outros diretórios. O exemplo do Makefile abaixo deve ser um bom começo para você chegar onde deseja estar.
fonte
Se as fontes estão espalhadas em muitas pastas e faz sentido ter Makefiles individuais, como sugerido anteriormente, a composição recursiva é uma boa abordagem, mas para projetos menores, acho mais fácil listar todos os arquivos de origem no Makefile com seu caminho relativo para o Makefile assim:
Posso então definir
VPATH
desta maneira:Então eu construo os objetos:
Agora a regra é simples:
E construir a saída é ainda mais fácil:
Pode-se até tornar a
VPATH
geração automatizada por:Ou usando o fato de
sort
remover duplicatas (embora não deva importar):fonte
Eu acho que é melhor ressaltar que usar Make (recursivo ou não) é algo que geralmente você deseja evitar, porque, comparado às ferramentas atuais, é difícil aprender, manter e dimensionar.
É uma ferramenta maravilhosa, mas seu uso direto deve ser considerado obsoleto em mais de 2010.
A menos, claro, que você esteja trabalhando em um ambiente especial, ou seja, com um projeto herdado, etc.
Use um IDE, CMake ou, se você for mais experiente, o Autotools .
(editado devido a votos negativos, digite Honza por apontar)
fonte
A publicação de RC foi SUPER útil. Eu nunca pensei em usar a função $ (dir $ @), mas ela fez exatamente o que eu precisava.
No parentDir, existem vários diretórios com arquivos de origem: dirA, dirB, dirC. Vários arquivos dependem dos arquivos de objeto em outros diretórios, então eu queria poder criar um arquivo de dentro de um diretório e fazê-lo fazer essa dependência chamando o makefile associado a essa dependência.
Essencialmente, criei um Makefile no parentDir que tinha (entre muitas outras coisas) uma regra genérica semelhante à do RC:
Cada subdiretório incluía esse makefile de nível superior para herdar esta regra genérica. No Makefile de cada subdiretório, escrevi uma regra personalizada para cada arquivo, para poder acompanhar tudo o que cada arquivo individual dependia.
Sempre que precisei criar um arquivo, usei (essencialmente) essa regra para fazer recursivamente qualquer / todas as dependências. Perfeito!
OBSERVAÇÃO: existe um utilitário chamado "makepp" que parece executar essa tarefa ainda mais intuitivamente, mas por uma questão de portabilidade e não dependendo de outra ferramenta, eu escolhi fazê-lo dessa maneira.
Espero que isto ajude!
fonte
Uso Recursivo da Marca
Isso permite
make
dividir em tarefas e usar vários núcleosfonte
make -j4
?make
usar o controle do trabalho. Ao executar um processo separado de make, ele não está sujeito ao controle do trabalho.Eu estava procurando por algo assim e, depois de algumas tentativas e quedas, crio meu próprio makefile, sei que essa não é a "maneira idiomática", mas é um começo para entender o make e isso funciona para mim, talvez você possa tentar em seu projeto.
Eu sei que é simples e para algumas pessoas minhas bandeiras estão erradas, mas como eu disse, este é o meu primeiro Makefile a compilar meu projeto em vários diretórios e vincular todos juntos para criar minha lixeira.
Estou aceitando sugestões: D
fonte
Sugiro usar
autotools
://##
Coloque os arquivos de objeto gerados (.o) no mesmo diretório que os arquivos de origem, para evitar colisões quando a criação não recursiva for usada.apenas incluí-lo
Makefile.am
com outras coisas bastante simples.Aqui está o tutorial .
fonte