Ninja: Caminhos subninja relativos não resolvem

Criado em 21 jun. 2015  ·  8Comentários  ·  Fonte: ninja-build/ninja

Eu tentaria um PR para isso, mas não tenho certeza se isso é um bug ou se é intencional.

Ao incluir um subninja, recebo

ninja: erro: 'mod.c', necessário para 'mod.o', ausente e nenhuma regra conhecida para fazê-lo

embora executar o ninja diretamente nesse diretório funcione bem. Sob a suspeita de que os caminhos relativos podem ser os culpados, copiei a estrutura do projeto para um novo diretório, anexei cada entrada/saída com o caminho absoluto e executei o ninja do diretório pai (contendo o build.ninja que subninja do módulo). Construiu muito bem.

Isso está sugerindo que devemos gerar nossas configurações ninja com caminhos absolutos? Isso tem muitos problemas, além do fato de que nem todo gerador que eu vi faz isso. Além disso, a documentação não faz distinção, e o Ninja funciona bem de outra forma.

Eu quero errar do lado de _é um bug_, mas eu sinto que um PR que faz canonização de caminho de tempo de execução pode introduzir um impacto no desempenho (embora eu esteja acenando minhas mãos aqui sem quaisquer benchmarks para apoiar essa suspeita).

Comentários muito úteis

Eu não tenho certeza se entendi. Subninjas, no caso de uso que descrevi em particular, normalmente não sabem sobre a estrutura do ninja pai (pelo menos, não precisam saber). Tenho certeza de que alguém lá fora poderia encontrar um caso onde eles fazem, no entanto.

O problema que estou enfrentando agora são dependências (bibliotecas de terceiros, etc.) que não usam meu gerador (que é 100% deles) atualmente precisam ser construídas usando um bootstrapper e precisam ser inicializadas toda vez que 'são atualizados ou alterados, etc. A maioria dos geradores com os quais trabalho tem as opções de saída para uma configuração ninja, mas todos eles são configurados apenas para esse diretório (ou seja, em relação a esse diretório).

Ser capaz de realizar reconstruções seletivas usando suas configurações e gráficos seria enorme. Atualmente, não posso fazer isso devido ao fato de subninja assumir caminhos relativos ao diretório de compilação.

Todos 8 comentários

Todos os caminhos são relativos ao diretório de construção, não ao arquivo que contém a linha subninja.

Isso não faz sentido, no entanto. Isso significa que os geradores terão que _todos_ implementar alguma maneira de prefixar um prefixo aos arquivos, o que significa alterar os comandos do diretório de trabalho executados (o que pode alterar a intenção original da configuração de compilação, dependendo de como o gerador/comandos são executados).

O que, então, são casos de uso contrastantes para subninja vs include ?

Um subninja com caminhos relativos ao arquivo de compilação seria útil porque as dependências configuradas para serem executadas em seu próprio diretório podem fazê-lo sem ter que modificar seus caminhos, mas ainda podem contribuir para o gráfico de dependência da configuração do ninja pai.

A funcionalidade include não seria modificada e agiria exatamente como os subninjas agem, exceto que os nomes das regras de fato estariam agora em um namespace combinado (conforme #921). Atualmente, subninja e include alcançam essencialmente a mesma coisa, exceto variáveis ​​de escopo e nomes de regras...

A ideia é que o gerador gere todos os arquivos .ninja, para que eles possam escrever caminhos relativos ao diretório de construção. É uma ideia interessante combinar arquivos ninja gerados por diferentes geradores (parece que é isso que você quer fazer?), mas isso não é algo suportado no momento.

Correto, a diferença entre subninja e include é que o primeiro adiciona um escopo e o segundo não. O caso de uso para isso é que o ninja de nível superior pode definir regras de compilação comuns, como cc, que referenciam variáveis ​​como cflags , e cada subninja pode definir cflags para o que é apropriado para esse destino, e há pode haver ações pontuais lá. Para ver um exemplo, você pode executar python misc/write_fake_manifests.py /tmp/foo` para gravar vários arquivos .ninja em /tmp/foo que usam esse padrão.

Isso faz sentido, embora eu ainda não veja muito benefício (além do escopo).

É uma ideia interessante combinar arquivos ninja gerados por diferentes geradores (parece que é isso que você quer fazer?)

Exatamente. Ser capaz de incluir o próprio Ninja como um submódulo para meu gerador e, em seguida, outro projeto CMake (que está configurado para gerar arquivos de compilação do Ninja) e, em seguida, gerar os arquivos de configuração do Ninja para ambos e incluí-los como subninja s em arquivo build.ninja do projeto _my_ para poder construí-los como se estivessem por conta própria, mas ainda permitir que meu projeto use suas saídas (e, portanto, seus gráficos de dependência) para construir todo o projeto de uma só vez .

Se isso faz sentido. O caso de uso imediato que vejo com meu gerador em particular é que ele está emprestando alguns conceitos do Tup (que o IIRC influenciou algumas decisões de design dentro do próprio Ninja) em que posso incluir N subprojetos, todos com seus próprios build.ninja arquivos e, em seguida, toque em seus gráficos para permitir que eu construa automaticamente um gráfico de dependência muito maior.

Pessoalmente, acho que isso tornaria subninja muito mais útil, embora eu possa ver que é uma mudança potencialmente inovadora. No entanto, não vejo uma maneira de contornar isso a menos que 1) eu modifique os arquivos build.ninja das dependências com um patch ou 2) sacrifique a capacidade de aproveitar os gráficos de dependência das dependências.

Pensamentos?

E quanto a:

subninja path/to/build.ninja relative path/to

e um relative ausente é padronizado para ./ . Isso o tornaria ininterrupto, mas ainda forneceria a funcionalidade se um gerador assim o desejar.

Ou, seguindo os passos de outras construções Ninja, talvez

subninja path/to/build.ninja
  relative = path/to

Suponha que você tenha um projeto em .../foo e tenha uma barra de subdiretório, e que Ninja tenha a lógica de caminho relativo que você sugere.

Se o seu sistema de compilação deseja gravar todas as saídas de compilação em /foo/obj, um subninja em /foo/bar que usa caminhos relativos ao diretório precisa saber para gravar sua saída em ../obj/bar, pois esse é o caminho para o arquivo desse subdiretório. Portanto, o que quer que esteja gerando seus arquivos build.ninja já deve estar ciente da hierarquia global de caminhos, caso em que tornar todos os caminhos relativos é efetivamente o mesmo problema que preceder um bar/ aos caminhos no diretório bar/.

Talvez haja pessoas suficientes que escrevem a saída de compilação em seus diretórios de origem para que o acima não importe. Eu ouço principalmente de pessoas que querem uma separação ainda mais forte - como as pessoas que enviaram patches para o Ninja para que eles possam compilar o Ninja com a saída da compilação em um diretório totalmente não relacionado.

Eu não tenho certeza se entendi. Subninjas, no caso de uso que descrevi em particular, normalmente não sabem sobre a estrutura do ninja pai (pelo menos, não precisam saber). Tenho certeza de que alguém lá fora poderia encontrar um caso onde eles fazem, no entanto.

O problema que estou enfrentando agora são dependências (bibliotecas de terceiros, etc.) que não usam meu gerador (que é 100% deles) atualmente precisam ser construídas usando um bootstrapper e precisam ser inicializadas toda vez que 'são atualizados ou alterados, etc. A maioria dos geradores com os quais trabalho tem as opções de saída para uma configuração ninja, mas todos eles são configurados apenas para esse diretório (ou seja, em relação a esse diretório).

Ser capaz de realizar reconstruções seletivas usando suas configurações e gráficos seria enorme. Atualmente, não posso fazer isso devido ao fato de subninja assumir caminhos relativos ao diretório de compilação.

Evan: A maneira como eu entendi isso é que você criaria uma árvore assim:

  subbuild1
  subbuild2

e como os geradores geralmente suportam colocar o diretório de compilação em locais arbitrários, a construção do projeto 1 na subcompilação1 e do projeto 2 na subcompilação 2 deve funcionar. Depois, há um arquivo ninja de nível superior em builddir que Qix- quer conduzir a construção dos subprojetos.

Não relacionado: esse recurso relative também precisa alterar o cwd para seu argumento se alguma regra depender do diretório atual ser igual ao seu diretório de construção (digamos, se uma regra remover artefatos construídos ou algo assim).

Esta página foi útil?
0 / 5 - 0 avaliações