Ninja: Documentar como definir variáveis ​​de ambiente em subprocessos

Criado em 9 ago. 2015  ·  10Comentários  ·  Fonte: ninja-build/ninja

Veja a discussão em
https://groups.google.com/d/topic/ninja-build/ZGZ2Ewxsxaw/discussion
e tópico anterior vinculado lá.

Comentários muito úteis

O projeto estaria interessado em um PR que implemente isso? É um bloqueador problemático downstream para https://github.com/mesonbuild/meson/ , pois temos que adicionar scripts de wrapper para qualquer comando que precise de conjunto de variáveis ​​de ambiente, o que está lentamente se tornando bastante.

Até mesmo os arquivos de projeto Makefiles e Visual Studio suportam isso, então o Ninja se destaca por não suportar isso. :)

Ficaríamos felizes em implementar isso se houver interesse em ter esse recurso no Ninja.

Todos 10 comentários

Lendo essa discussão, parece que as variáveis ​​de ambiente não são suportadas no Ninja porque CreateProcess não suporta a configuração PATH para encontrar o executável a ser executado ao usar lpCommandLine em vez de lpApplicationName ? O problema é que execvpe e execle têm a mesma restrição, então não entendo qual é o problema aqui.

É muito simples configurar o ambiente herdado por um processo em todas as plataformas, então gostaria de entender qual é o bloqueador aqui. Saúde!

FWIW, nós realmente faríamos bom uso desse recurso no Meson: https://github.com/mesonbuild/meson/issues/266 , https://github.com/mesonbuild/meson/issues/384 , etc.

O projeto estaria interessado em um PR que implemente isso? É um bloqueador problemático downstream para https://github.com/mesonbuild/meson/ , pois temos que adicionar scripts de wrapper para qualquer comando que precise de conjunto de variáveis ​​de ambiente, o que está lentamente se tornando bastante.

Até mesmo os arquivos de projeto Makefiles e Visual Studio suportam isso, então o Ninja se destaca por não suportar isso. :)

Ficaríamos felizes em implementar isso se houver interesse em ter esse recurso no Ninja.

Em plataformas POSIXy, você pode fazer

rule foo
  command = ENV1=env1 ENV2=env2 my_command

ou

rule foo
  command = $env my_command
foo out: in
  env = ENV1=env1 ENV2=env2

Isso não é suficiente para você? A maioria dos comandos não deve precisar de env vars, e geralmente suportando menos coisas mantém o ninja simples.

Sim, essa parte está documentada , mas o Meson é um sistema de compilação multiplataforma (destinado a ter paridade de recursos em todas as plataformas suportadas) e atualmente temos que usar wrappers de script Python sempre que precisamos definir variáveis ​​de ambiente ou argumentos com caracteres especiais (especialmente novas linhas).

No início, também pensamos que definir env vars é um caso de uso de nicho e adiamos quando os usuários solicitavam, mas um número surpreendentemente grande de pessoas precisa disso. Por exemplo, gobject-introspection no GNOME requer que você defina CC / CXX /etc enquanto invoca suas ferramentas, caso contrário, ele usa um mecanismo de detecção automática que acaba usando o compilador errado. "Destinos personalizados" no Meson podem executar comandos arbitrários, e as pessoas geralmente aparecem perguntando como podem definir variáveis ​​de ambiente enquanto executam alguma ferramenta da qual não podem alterar o comportamento.

A solução alternativa do script Python está ok, mas invocar o interpretador python para cada comando realmente torna as coisas mais lentas às vezes.

Talvez o gobject-introspection possa aceitá-los via argumentos de linha de comando? (Na minha experiência, compilações que dependem de env vars em vez de sinalizadores tendem a ser muito mais vulneráveis ​​a devs estragando seu env local, etc.)

O cl.exe do MSVC requer algumas variáveis ​​de ambiente para localizar includes e outros enfeites; para esse ninja tem ninja -t msvc que tem um sinalizador -e que pode carregar um ambiente a partir de um arquivo. Então, o meson teoricamente poderia usar isso no Windows e as coisas posix em outros lugares.

Mas usar wrappers python para o caso raro "precisa ser flexível" e fazer os comandos comuns funcionarem sem depender do env parece ser a melhor abordagem para mim.

Acho que me deparei com esse problema. Estou tentando construir um executável FIPS na janela e preciso seguir estas instruções:

https://www.openssl.org/docs/fips/UserGuide-2.0.pdf , seção 5.3.2:

For the Windows®
 environment a perl script fipslink.pl is provided which performs a
function similar to fipsld for Unix®
/Linux®
. Several environment variables need to be set:
FIPS_LINK is the linker name, normally “link”
FIPS_CC is the C compiler name, normally “cl”
FIPS_CC_ARGS is a string of C compiler arguments for compiling fips_premain.c
PREMAIN_DSO_EXE should be set to the path to fips_premain_dso.exe if a DLL is
being linked (can be omitted otherwise)
PREMAIN_SHA1_EXE is the full path to fips_standalone_sha1.exe
FIPS_TARGET is the path of the target executable or DLL file

Embora FIPS_CC esteja definido no meu ambiente, parece que o ninja não está passando o env para o processo filho ( perl fipslink.pl ... ). Vou ver se -e funciona para mim.

Outro caso de uso para isso é definir LD_LIBRARY_PATH antes de executar executáveis ​​embutidos no projeto. Isso geralmente é necessário com executáveis ​​vinculados a bibliotecas compartilhadas criadas no projeto para garantir que as versões já existentes em um prefixo personalizado não sejam usadas ( -Wl,-rpath não funciona em distribuições que definem DT_RUNPATH de DT_RPATH como Debian e Ubuntu). Autotools (libtool) usa scripts de shell para isso. Seria uma desaceleração significativa da compilação se tivéssemos que gerar um interpretador Python ou executar um script de shell para esses casos.

Como outro ponto de dados, o cmake se deparou tanto com esse caso de uso que eles têm um wrapper C para ele, que define o ambiente e, em seguida, chama o processo. Eles precisam disso de qualquer maneira para o back-end de criação, mas os sistemas de compilação somente ninja se beneficiariam muito desse recurso.

Não tenho mais certeza sobre o que esse bug está discutindo, pois parece que era originalmente sobre a atualização dos documentos. :)

Para LD_LIBRARY_PATH , configurá-lo através da linha de comando já funciona como Nico mencionou acima. Não envolve outro processo; devemos usar um shell para analisar a linha de comando de qualquer maneira. (Subprocessos no Linux são muito baratos de qualquer maneira; você não pode nem medir /bin/sh -c "echo hello" porque é muito rápido.)

No Windows temos ninja -t msvc . Você pode tentar escrever seu recurso meson usando isso e, assim que tivermos alguma experiência com isso, poderemos descobrir como melhorá-lo.

O Kconfiglib tem um requisito difícil de $srctree para compilações fora do código-fonte. Ele usa algumas outras variáveis:
https://github.com/ulfalizer/Kconfiglib/blob/424d0d38e7/kconfiglib.py#L108

atualmente temos que usar wrappers de script Python sempre que precisamos definir variáveis ​​de ambiente

De: https://github.com/ulfalizer/Kconfiglib/tree/424d0d38e7be15c5#overview

A biblioteca inteira está contida em kconfiglib.py. Os scripts empacotados são implementados em cima dele. Implementar seus próprios scripts deve ser relativamente fácil, se necessário.

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