Quais são os diferentes métodos para executar um executável não-nixos no NixOs? (Por exemplo, binários proprietários.) Eu gostaria de ver também os métodos manuais.
relate perguntas
-
aponte $NIX_PATH para ~/.nix-defexpr/channels
-
Defina dois ou mais arquivos para execução (via fonte) de forma confortável para leitura
-
O scanner é detectado apenas uma vez
-
Limpe o cache do gerenciador de pacotes no nixos com partição raiz completa
-
Altere o executável padrão para arquivo com shebang potencialmente ausente
Versão curta
Rápido e sujo: verifique se
steam-run
está instalado (nome estranho, não tem nada a ver com steam), por exemplonix-shell -p steam-run
, então:Aqui está uma explicação mais longa e detalhada, juntamente com vários métodos, muitas vezes menos sujos. Desde a criação desta resposta, outras alternativas ao steam-run foram desenvolvidas, veja por exemplo nix-ld (que basicamente recria os carregadores ausentes em
/lib
) e nix-alien / nix-autobahn que também tenta adicionar automaticamente as bibliotecas ausentes. Finalmente, você pode usar o distrobox que fornece qualquer distribuição em um contêiner docker/podman totalmente integrado ao host.Versão longa
Aqui estão vários métodos (os manuais são principalmente para fins educacionais, pois na maioria das vezes é melhor escrever uma derivação adequada). Não sou especialista em nada, e fiz essa lista também para aprender nix, então se você tiver métodos melhores, me avise!
Portanto, o principal problema é que o executável chama primeiro um carregador e, em seguida, precisa de algumas bibliotecas para funcionar, e o nixos coloca o carregador e as bibliotecas em arquivos
/nix/store/
.Esta lista fornece todos os métodos que encontrei até agora. Existem basicamente três "grupos":
Eu recomendaria o método 4
autoPatchelfHook
para uma configuração real e adequada, e se você não tiver tempo e quiser apenas executar um binário em uma linha, poderá estar interessado na solução rápida e suja baseada emsteam-run
(método 7 ).Método 1) Método manual sujo, sem patch
Você precisa primeiro encontrar o carregador com, por exemplo
file
:Aqui está o carregador
/lib64/ld-linux-x86-64.so.2
. Para encontrar o carregador de nixos, você pode fazer:Você também precisa encontrar para encontrar as bibliotecas que seu programa requer, por exemplo com
ldd
ouLD_DEBUG=libs
:Aqui, você vê que a maioria das bibliotecas são encontradas, exceto
libstdc++.so.6
. Então vamos encontrá-los! Uma primeira maneira rápida e suja de encontrá-los é verificar se eles já estão presentes em seu sistema:Caso a biblioteca ainda não esteja instalada, você certamente preferirá usar o
nix-index
programa mais envolvido para buscar esses arquivos em um banco de dados muito maior (obrigado hydra). Para isso, primeiro instalenix-index
e gere o banco de dados (isso só é necessário na primeira vez, mas pode levar alguns minutos para ser executado):(você também pode usar nix
nix-index-update
- alien para baixar o cache automaticamente do nix-index-database ) então, para procurar uma biblioteca, você pode fazer algo como (observe que--top-level
remove algumas entradas):Então você pode instalar essas bibliotecas para este exemplo rápido e sujo (mais tarde veremos soluções melhores).
Bom. Agora, só precisamos executar o programa com o
LD_LIBRARY_PATH
configurado para apontar para este arquivo (veja tambémmakeLibraryPath
para gerar esta string em uma derivação), e chamar o loader que determinamos no primeiro passo neste arquivo:(certifique-se de usar
./
antes do nome do script, e de manter apenas o diretório das bibliotecas. Se você tiver várias bibliotecas, basta usar concat o caminho com dois pontos)Método 2) Método manual sujo, com patch
Depois de instalar (com
nixenv -i
ou no seuconfiguration.nix
)patchelf
, você também pode modificar diretamente o executável para empacotar o bom carregador e as bibliotecas. Para alterar o carregador basta executar:e para verificar:
e para alterar o caminho para as bibliotecas codificadas no executável, primeiro verifique qual é o rpath atual (vazio para mim):
e anexá-los ao caminho da biblioteca que você determinou antes, eventualmente separados por dois pontos:
Método 3) Patch em uma derivação nix
Podemos reproduzir mais ou menos a mesma coisa em uma derivação nix inspirada no skypeforlinux
Este exemplo apresenta também uma alternativa, você pode usar:
(que deve ficar bem claro quando você entender o método "manual"), ou
Este segundo método é um pouco mais sutil, mas se você executar:
você verá que o arquivo
$NIX_CC/nix-support/dynamic-linker
contém um caminho para o carregadorld-linux-x86-64.so.2
.Coloque
derivation.nix
, isso ée
default.nix
colocando:Compile e execute com
Método 4) Use autoPatchElf: mais simples
Todos os métodos anteriores precisam de um pouco de trabalho (você precisa encontrar os executáveis, corrigi-los...). NixOs fez para nós um "gancho" especial
autoPatchelfHook
que automaticamente corrige tudo para você! Você só precisa especificá-lo em(native)BuildInputs
, e nix faz a mágica.Método 5) Use o FHS para simular um shell linux clássico e execute manualmente os arquivos
Alguns softwares podem ser difíceis de empacotar dessa maneira porque podem depender muito da estrutura da árvore de arquivos FHS ou podem verificar se o binário não foi alterado. Você também pode usar buildFHSUserEnv para fornecer uma estrutura de arquivo FHS (leve, usando namespaces) para seu aplicativo. Observe que esse método é mais pesado que os métodos baseados em patch e adiciona um tempo de inicialização significativo, portanto, evite-o quando possível
Você pode apenas gerar um shell e extrair manualmente o arquivo e executar o arquivo, ou empacotar diretamente seu programa para o FHS. Vamos primeiro ver como obter um shell. Coloque em um arquivo (digamos
fhs-env.nix
) o seguinte:e corra:
Você obterá um bash em um linux com aparência mais padrão e poderá executar comandos para executar seu executável, como:
Se você precisar de mais bibliotecas/programas como dependências, basta adicioná-los a
multiPkgs
(para todos os arcos suportados) outargetPkgs
(somente para o arco atual).Bônus: você também pode iniciar um shell fhs com um comando de uma linha, sem criar um arquivo específico:
Método 6) Use o FHS para simular um shell linux clássico e empacote os arquivos dentro
fonte: https://reflexivereflection.com/posts/2015-02-28-deb-installation-nixos.html
Método 7) a vapor
Com
buildFHSUserEnv
você pode executar muitos softwares, mas você precisará especificar manualmente todas as bibliotecas necessárias. Se você deseja uma solução rápida e não tem tempo para verificar exatamente quais são as bibliotecas necessárias, tentesteam-run
(apesar do nome, não está vinculado diretamente ao steam e apenas contém muitas bibliotecas), o que é comobuildFHSUserEnv
com muitas bibliotecas comuns pré-instaladas (algumas delas podem ser não-livres comosteamrt
aquela que contém algum código nvidia, obrigado simpson!). Para usá-lo, basta instalarsteam-run
e depois:ou se você quiser um shell completo:
Observe que você pode precisar adicionar
nixpkgs.config.allowUnfree = true;
(ou colocar na lista de permissões este pacote específico ) se quiser instalá-lo comnixos-rebuild
, e se quiser executá-lo/instalá-lo comnix-shell
/nix-env
você precisa colocar .{ allowUnfree = true; }
~/.config/nixpkgs/config.nix
Não é fácil "sobrescrever" pacotes ou bibliotecas no nix-shell, mas se você quiser criar um wrapper em torno de seu script, poderá criar manualmente um script wrapper:
ou escreva-o diretamente em uma derivação nixos:
ou se você começar a partir do .deb (aqui eu usei
makeWrapper
):(se você está muito cansado para escrever o usual
default.nix
, você pode executar diretamentenix-build -E "with import <nixpkgs> {}; callPackage ./derivation.nix {}"
)Método 8) Usando
nix-ld
Se você não quiser gerar um sandbox como fizemos para o steam-run (em sandboxes é impossível executar aplicativos setuid, sandboxes não podem ser aninhados, integração ruim com os pacotes do sistema incluídos direnv), você pode recriar o sistema de carregador ausente -wide colocando em seu
configuration.nix
:Você pode ver que o arquivo agora está presente:
No entanto, ainda é impossível executar binários, pois o novo
ld-linux-x86-64.so.2
arquivo redireciona apenas para o carregadorNIX_LD
(desta forma, vários programas podem usar carregadores diferentes enquanto estão no mesmo sistema):Para criar localmente essa variável de ambiente, você pode fazer algo como:
ou em todo o sistema usando:
Observe que você precisa reiniciar sua sessão do X11 toda vez que alterar este arquivo ou fizer:
Note that (contrary to
steam-run
)nix-ld
does not come with any library by default but you can add your own or use tools to do that automatically, see below. You can also get inspired by the list of libraries that steam-run packs here: https://github.com/NixOS/nixpkgs/blob/master/pkgs/games/steam/fhsenv.nix Here is for example the file I'm using for now, it is enough to run blender:You can also find the name of the libraries, see above
nix-index
. You can also use nix-alien-ld or nix-autobahn to automatically find and load the libraries for you. Note that if you don't have the right libraries you will get an error likeYou can see at once all the libraries that are not yet available using:
Method 9) nix-alien
nix-alien automatically builds a FHS with the appropriates libraries. If you have flake enabled (otherwise just add replace
nix run
withnix --extra-experimental-features "nix-command flakes" run
) you can simply run it this way (nix-alien is not yet packaged in 2022)It will then automatically find the library using nix-index, asking you some questions when it is not sure (this is cached).
Note that programs that rely on openGl need to use nixGl to run (this certainly apply to other methods here):
Note that you may need to change the version of
nixos-21.11
to ensure that the version of openGl matches your program.Note that you can also see the automatically generated file (the path is given the first time the program is run):
See also the other version working with nix-ld and nix-autobahn.
Method 9) Using containers/Docker (heavier)
TODO
Note that the project distrobox allows you to simply create new containers tightly integrated with the host installing any distribution you want.
Method 10) Rely on flatpack/appimage
https://nixos.org/nixos/manual/index.html#module-services-flatpak
appimage-run : To test with, ex, musescore
Sources or examples
Also, for people wanting to get started in packaging, I wrote recently a similar tutorial here.