Quais são os diferentes métodos para executar um executável não-nixos em NixOs? (Por exemplo, binários proprietários.) Gostaria de ver também os métodos manuais.
Responder1
Respostas relacionadas
Se você planeja empacotar um binário e não apenas executá-lo, você pode gostar desta minha outra resposta:Como empacotar meu software no nix ou escrever minha própria derivação de pacote para nixpkgs
Versão curta
Rápido e sujo: certifique-se steam-run
de que está instalado (nome estranho, não tem nada a ver com Steam), por exemplo nix-shell -p steam-run
, então:
$ steam-run ./your-binary
Desde a criação desta resposta, outras alternativas ao steam-run foram desenvolvidas, veja, por exemplo, nix-ld
que agora faz parte do NixOs (que basicamente recria os carregadores ausentes em /lib
… Ialtamenterecomendo que você configure-o de uma vez por todas, desta forma você não precisará mais se preocupar em executar binários não corrigidos, para poder usar o NPM etc sem dores de cabeça):
(aviso: desde a atualização recente do nix, você só precisa programs.nix-ld.enable = true;
, e as variáveis podem ser configuradas usando
programs.nix-ld.enable = true;
## If needed, you can add missing libraries here. nix-index-database is your friend to
## find the name of the package from the error message:
## https://github.com/nix-community/nix-index-database
programs.nix-ld.libraries = options.programs.nix-ld.libraries.default ++ (with pkgs; [ yourlibrary ]);
para definir automaticamente as variáveis de ambiente, mas o código abaixo deve funcionar também em sistemas legados, então deixarei aqui) Observe que você também pode precisar reinicializar para garantir que as variáveis de ambiente estejam definidas corretamente, não testadas recentemente.
programs.nix-ld.enable = true;
environment.variables = {
NIX_LD_LIBRARY_PATH = with pkgs; lib.makeLibraryPath [
stdenv.cc.cc
openssl
xorg.libXcomposite
xorg.libXtst
xorg.libXrandr
xorg.libXext
xorg.libX11
xorg.libXfixes
libGL
libva
pipewire.lib
xorg.libxcb
xorg.libXdamage
xorg.libxshmfence
xorg.libXxf86vm
libelf
# Required
glib
gtk2
bzip2
# Without these it silently fails
xorg.libXinerama
xorg.libXcursor
xorg.libXrender
xorg.libXScrnSaver
xorg.libXi
xorg.libSM
xorg.libICE
gnome2.GConf
nspr
nss
cups
libcap
SDL2
libusb1
dbus-glib
ffmpeg
# Only libraries are needed from those two
libudev0-shim
# Verified games requirements
xorg.libXt
xorg.libXmu
libogg
libvorbis
SDL
SDL2_image
glew110
libidn
tbb
# Other things from runtime
flac
freeglut
libjpeg
libpng
libpng12
libsamplerate
libmikmod
libtheora
libtiff
pixman
speex
SDL_image
SDL_ttf
SDL_mixer
SDL2_ttf
SDL2_mixer
libappindicator-gtk2
libdbusmenu-gtk2
libindicator-gtk2
libcaca
libcanberra
libgcrypt
libvpx
librsvg
xorg.libXft
libvdpau
gnome2.pango
cairo
atk
gdk-pixbuf
fontconfig
freetype
dbus
alsaLib
expat
# Needed for electron
libdrm
mesa
libxkbcommon
];
NIX_LD = lib.fileContents "${pkgs.stdenv.cc}/nix-support/dynamic-linker";
};
Há tambémnix-alienígena/Autobahn nixque também tenta adicionar automaticamente as bibliotecas ausentes. Finalmente você pode usarcaixa de distribuiçãoque fornece qualquer distribuição em um contêiner docker/podman totalmente integrado ao host… mas pela minha experiência é mais complicado usar aquele nix-ld
que é verdadeiramente transparente.
Aqui está uma explicação mais longa e detalhada, juntamente com vários métodos, muitas vezes menos sujos.
Versão longa
Aqui estão vários métodos (os manuais são principalmente para fins educacionais, já que na maioria das vezes é melhor escrever uma derivação adequada). Não sou nenhum especialista 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 depois precisa de algumas bibliotecas para funcionar, e os nixos colocam o carregador e as bibliotecas no arquivo /nix/store/
.
Esta lista fornece todos os métodos que encontrei até agora. Existem basicamente três “grupos”:
- o manual completo: interessante para fins educacionais e para entender o que está acontecendo, mas isso é tudo (não os use na prática porque nada impedirá que as derivações usadas sejam coletadas posteriormente)
- as versões corrigidas: esses métodos tentam modificar o executável (automaticamente ao usar o método recomendado 4 com autoPatchelfHook) para apontar diretamente para a boa biblioteca
- os métodos baseados em FHS, que basicamente falsificam um "linux normal" (mais pesado para rodar que a versão corrigida, então isso deve ser evitado se possível).
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, você pode estar interessado na solução rápida e suja baseada em steam-run
(método 7 ).
Método 1) Método manual sujo, sem patch
Você precisa primeiro encontrar o carregador com, por exemplo file
:
$ file wolframscript
wolframscript: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.18, BuildID[sha1]=079684175aa38e3633b60544681b338c0e8831e0, stripped
Aqui está o carregador /lib64/ld-linux-x86-64.so.2
. Para encontrar o carregador de nixos, você pode fazer:
$ ls /nix/store/*glibc*/lib/ld-linux-x86-64.so.2
/nix/store/681354n3k44r8z90m35hm8945vsp95h1-glibc-2.27/lib/ld-linux-x86-64.so.2
Você também precisa find para encontrar as bibliotecas que seu programa exige, por exemplo, com ldd
ou LD_DEBUG=libs
:
$ ldd wolframscript
linux-vdso.so.1 (0x00007ffe8fff9000)
libpthread.so.0 => /nix/store/sw54ph775lw7b9g4hlfvpx6fmlvdy8qi-glibc-2.27/lib/libpthread.so.0 (0x00007f86aa321000)
librt.so.1 => /nix/store/sw54ph775lw7b9g4hlfvpx6fmlvdy8qi-glibc-2.27/lib/librt.so.1 (0x00007f86aa317000)
libdl.so.2 => /nix/store/sw54ph775lw7b9g4hlfvpx6fmlvdy8qi-glibc-2.27/lib/libdl.so.2 (0x00007f86aa312000)
libstdc++.so.6 => not found
libm.so.6 => /nix/store/sw54ph775lw7b9g4hlfvpx6fmlvdy8qi-glibc-2.27/lib/libm.so.6 (0x00007f86aa17c000)
libgcc_s.so.1 => /nix/store/sw54ph775lw7b9g4hlfvpx6fmlvdy8qi-glibc-2.27/lib/libgcc_s.so.1 (0x00007f86a9f66000)
libc.so.6 => /nix/store/sw54ph775lw7b9g4hlfvpx6fmlvdy8qi-glibc-2.27/lib/libc.so.6 (0x00007f86a9dae000)
/lib64/ld-linux-x86-64.so.2 => /nix/store/sw54ph775lw7b9g4hlfvpx6fmlvdy8qi-glibc-2.27/lib64/ld-linux-x86-64.so.2 (0x00007f86aa344000)
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 no seu sistema:
$ find /nix/store -name libstdc++.so.6
/nix/store/12zhmzzhrwszdc8q3fwgifpwjkwi3mzc-gcc-7.3.0-lib/lib/libstdc++.so.6
Caso a biblioteca ainda não esteja instalada, você certamente preferirá utilizar a mais envolventenix-index
programa para procurar esses arquivos em um banco de dados muito maior (obrigado Hydra). Para isso, primeiro instale nix-index
e gere o banco de dados (isso só é necessário na primeira vez, mas pode demorar alguns minutos para ser executado):
$ nix-index
(você também pode usar nix run github:mic92/nix-index-database yourlib
para evitar a recriação do banco de dados localmente. Veja também nix-index-update
emnix-alienígenapara baixar o cache automaticamente debanco de dados de índice nix) então, para procurar uma biblioteca você pode fazer algo como (observe que --top-level
remove algumas entradas):
$ nix-locate lib/libstdc++.so.6 --top-level
…
gcc-unwrapped.lib 0 s /nix/store/7fv9v6mnlkb4ddf9kz1snknbvbfbcbx0-gcc-10.3.0-lib/lib/libstdc++.so.6
…
Então você pode instalar essas bibliotecas para este exemplo rápido e sujo (mais tarde veremos soluções melhores).
Bom. Agora, basta executar o programa com o LD_LIBRARY_PATH
configurado para apontar para este arquivo (veja também makeLibraryPath
como gerar esta string em uma derivação), e chamar o carregador que determinamos no primeiro passo deste arquivo:
LD_LIBRARY_PATH=/nix/store/12zhmzzhrwszdc8q3fwgifpwjkwi3mzc-gcc-7.3.0-lib/lib/:$LD_LIBRARY_PATH /nix/store/681354n3k44r8z90m35hm8945vsp95h1-glibc-2.27/lib/ld-linux-x86-64.so.2 ./wolframscript
(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
Após a instalação (com nixenv -i
ou em seu configuration.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:
patchelf --set-interpreter /nix/store/681354n3k44r8z90m35hm8945vsp95h1-glibc-2.27/lib/ld-linux-x86-64.so.2 wolframscript
e para verificar:
$ patchelf --print-interpreter wolframscript
/nix/store/681354n3k44r8z90m35hm8945vsp95h1-glibc-2.27/lib/ld-linux-x86-64.so.
e para alterar o caminho das bibliotecas codificadas no executável, primeiro verifique qual é o rpath atual (vazio para mim):
$ patchelf --print-rpath wolframscript
e anexe-os ao caminho da biblioteca que você determinou antes, eventualmente separados por dois pontos:
$ patchelf --set-rpath /nix/store/12zhmzzhrwszdc8q3fwgifpwjkwi3mzc-gcc-7.3.0-lib/lib/ wolframscript
$ ./wolframscript
Método 3) Patch em uma derivação nix
Podemos reproduzir mais ou menos a mesma coisa numa derivação nix inspirada emskypeforlinux
Este exemplo apresenta também uma alternativa, você pode usar:
patchelf --set-interpreter ${glibc}/lib/ld-linux-x86-64.so.2 "$out/bin/wolframscript" || true
(o que deve ficar bem claro quando você entender o método "manual"), ou
patchelf --set-interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" "$out/bin/wolframscript" || true
Este segundo método é um pouco mais sutil, mas se você executar:
$ nix-shell '<nixpkgs>' -A hello --run 'echo $NIX_CC/nix-support/dynamic-linker "->" $(cat $NIX_CC/nix-support/dynamic-linker)'
/nix/store/8zfm4i1aw4c3l5n6ay311ds6l8vd9983-gcc-wrapper-7.4.0/nix-support/dynamic-linker -> /nix/store/sw54ph775lw7b9g4hlfvpx6fmlvdy8qi-glibc-2.27/lib/ld-linux-x86-64.so.2
você verá que o arquivo $NIX_CC/nix-support/dynamic-linker
contém um caminho para o carregador ld-linux-x86-64.so.2
.
Coloque derivation.nix
, isso é
{ stdenv, dpkg,glibc, gcc-unwrapped }:
let
# Please keep the version x.y.0.z and do not update to x.y.76.z because the
# source of the latter disappears much faster.
version = "12.0.0";
rpath = stdenv.lib.makeLibraryPath [
gcc-unwrapped
glibc
];
# What is it for?
# + ":${stdenv.cc.cc.lib}/lib64";
src = ./WolframScript_12.0.0_LINUX64_amd64.deb;
in stdenv.mkDerivation {
name = "wolframscript-${version}";
system = "x86_64-linux";
inherit src;
nativeBuildInputs = [
];
buildInputs = [ dpkg ];
unpackPhase = "true";
# Extract and copy executable in $out/bin
installPhase = ''
mkdir -p $out
dpkg -x $src $out
cp -av $out/opt/Wolfram/WolframScript/* $out
rm -rf $out/opt
'';
postFixup = ''
# Why does the following works?
patchelf --set-interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" "$out/bin/wolframscript" || true
# or
# patchelf --set-interpreter ${glibc}/lib/ld-linux-x86-64.so.2 "$out/bin/wolframscript" || true
patchelf --set-rpath ${rpath} "$out/bin/wolframscript" || true
'';
meta = with stdenv.lib; {
description = "Wolframscript";
homepage = https://www.wolfram.com/wolframscript/;
license = licenses.unfree;
maintainers = with stdenv.lib.maintainers; [ ];
platforms = [ "x86_64-linux" ];
};
}
e default.nix
coloque:
{ pkgs ? import <nixpkgs> {} }:
pkgs.callPackage ./derivation.nix {}
Compilar e executar com
nix-build
result/bin/wolframscript
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 corrige tudo automaticamente para você! Você só precisa especificá-lo (native)BuildInputs
e nix faz a mágica.
{ stdenv, dpkg, glibc, gcc-unwrapped, autoPatchelfHook }:
let
# Please keep the version x.y.0.z and do not update to x.y.76.z because the
# source of the latter disappears much faster.
version = "12.0.0";
src = ./WolframScript_12.0.0_LINUX64_amd64.deb;
in stdenv.mkDerivation {
name = "wolframscript-${version}";
system = "x86_64-linux";
inherit src;
# Required for compilation
nativeBuildInputs = [
autoPatchelfHook # Automatically setup the loader, and do the magic
dpkg
];
# Required at running time
buildInputs = [
glibc
gcc-unwrapped
];
unpackPhase = "true";
# Extract and copy executable in $out/bin
installPhase = ''
mkdir -p $out
dpkg -x $src $out
cp -av $out/opt/Wolfram/WolframScript/* $out
rm -rf $out/opt
'';
meta = with stdenv.lib; {
description = "Wolframscript";
homepage = https://www.wolfram.com/wolframscript/;
license = licenses.mit;
maintainers = with stdenv.lib.maintainers; [ ];
platforms = [ "x86_64-linux" ];
};
}
Método 5) Use FHS para simular um shell Linux clássico e executar manualmente os arquivos
Alguns softwares podem ser difíceis de empacotar dessa forma porque podem depender fortemente doESFestrutura da árvore de arquivos ou pode verificar se o binário está inalterado. Você também pode usarconstruirFHSUserEnvpara fornecer uma estrutura de arquivo FHS (leve, usando namespaces) para seu aplicativo.Observe que este 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 simplesmente gerar um shell e extrair manualmente o arquivo e executá-lo ou empacotar diretamente seu programa para o FHS. Vamos primeiro ver como obter uma concha. Coloque em um arquivo (digamos fhs-env.nix
) o seguinte:
let nixpkgs = import <nixpkgs> {};
in nixpkgs.buildFHSUserEnv {
name = "fhs";
targetPkgs = pkgs: [];
multiPkgs = pkgs: [ pkgs.dpkg ];
runScript = "bash";
}
e corra:
nix-build fhs-env.nix
result/bin/fhs
Você obterá então um bash em um Linux de aparência mais padrão e poderá executar comandos para executar seu executável, como:
mkdir wolf_fhs/
dpkg -x WolframScript_12.0.0_LINUX64_amd64.deb wolf_fhs/
cd wolf_fhs/opt/Wolfram/WolframScript/bin/
./wolfram
Se você precisar de mais bibliotecas/programas como dependências, basta adicioná-los multiPkgs
(para todos os arcos suportados) ou targetPkgs
(apenas 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:
nix-build -E '(import <nixpkgs> {}).buildFHSUserEnv {name = "fhs";}' && ./result/bin/fhs
Método 6) Use FHS para simular um shell Linux clássico e compactar os arquivos dentro
fonte:https://reflexivereflection.com/posts/2015-02-28-deb-installation-nixos.html
Método 7) funcionamento a vapor
Com buildFHSUserEnv
você pode executar muitos softwares, mas 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, você pode tentar steam-run
(apesar do nome, não está vinculado diretamente ao Steam e apenas contém muitas bibliotecas), que é como acontece buildFHSUserEnv
com muitas bibliotecas comuns pré-instaladas (algumas delas podem não ser gratuitas, como steamrt
aquelas que contêm algum código da Nvidia, obrigado Simpson!). Para usá-lo, basta instalar steam-run
e depois:
steam-run ./wolframscript
ou se você quiser um shell completo:
steam-run bash
Observe que pode ser necessário adicionar nixpkgs.config.allowUnfree = true;
(ou colocar na lista de permissõeseste pacote específico) se quiser instalá-lo com nixos-rebuild
, e se quiser executá-lo/instalá-lo com nix-shell
/ nix-env
você precisa { allowUnfree = true; }
colocar ~/.config/nixpkgs/config.nix
.
Não é fácil "sobrescrever" pacotes ou bibliotecas no nix-shell, mas se quiser criar um wrapper em torno do seu script, você pode criar manualmente um script wrapper:
#!/usr/bin/env nix-shell
#!nix-shell -i bash -p steam-run
exec steam-run ./wolframscript "$@"
ou escreva diretamente em uma derivação nixos:
{ stdenv, steam-run, writeScriptBin }:
let
src = ./opt/Wolfram/WolframScript/bin/wolframscript;
in writeScriptBin "wolf_wrapped_steam" ''
exec ${steam-run}/bin/steam-run ${src} "$@"
''
ou se você começar a partir do .deb (aqui usei makeWrapper
):
{ stdenv, steam-run, dpkg, writeScriptBin, makeWrapper }:
stdenv.mkDerivation {
name = "wolframscript";
src = ./WolframScript_12.0.0_LINUX64_amd64.deb;
nativeBuildInputs = [
dpkg makeWrapper
];
unpackPhase = "true";
installPhase = ''
mkdir -p $out/bin
dpkg -x $src $out
cp -av $out/opt/Wolfram/WolframScript/bin/wolframscript $out/bin/.wolframscript-unwrapped
makeWrapper ${steam-run}/bin/steam-run $out/bin/wolframscript --add-flags $out/bin/.wolframscript-unwrapped
rm -rf $out/opt
'';
}
(se você estiver cansado demais para escrever o de costume default.nix
, você pode executar diretamente nix-build -E "with import <nixpkgs> {}; callPackage ./derivation.nix {}"
)
Método 8) Usandonix-ld
Se você não deseja gerar um sandbox como fizemos para o steam-run (em sandboxes é impossível executar aplicativos setuid, sandboxes não podem ser aninhados, integração deficiente com os pacotes do sistema incluídos direnv), você pode recriar o sistema carregador ausente -wide colocando seu configuration.nix
:
programs.nix-ld.enable = true;
Você pode ver que o arquivo agora está presente:
$ ls /lib64/
ld-linux-x86-64.so.2
No entanto, ainda é impossível executar binários, pois o novo ld-linux-x86-64.so.2
arquivo apenas redireciona para o carregador NIX_LD
(desta forma, vários programas podem usar carregadores diferentes enquanto estão no mesmo sistema):
$ ./blender
cannot execute ./blender: NIX_LD or NIX_LD_x86_64-linux is not set
Para criar localmente esta variável de ambiente, você pode fazer algo como:
$ cat shell.nix
with import <nixpkgs> {};
mkShell {
NIX_LD_LIBRARY_PATH = lib.makeLibraryPath [
stdenv.cc.cc
openssl
# ...
];
NIX_LD = lib.fileContents "${stdenv.cc}/nix-support/dynamic-linker";
}
$ nix-shell
[nix-shell:/tmp/blender-3.2.2-linux-x64]$ ./blender
ou em todo o sistema usando:
(aviso: desde a atualização recente do nix, você só precisa de programs.nix-ld.enable = true;
, e as variáveis podem ser configuradas usando programs.nix-ld.libraries = with pkgs; [];
em vez de usar variáveis de ambiente, mas o código abaixo deve funcionar também em sistemas legados, então vou deixar aqui)
environment.variables = {
NIX_LD_LIBRARY_PATH = lib.makeLibraryPath [
pkgs.stdenv.cc.cc
pkgs.openssl
# ...
];
NIX_LD = lib.fileContents "${pkgs.stdenv.cc}/nix-support/dynamic-linker";
};
Observe que você precisareiniciarsua sessão X11 sempre que você alterar este arquivo ou fizer:
$ cat /etc/profile | grep set-environment
. /nix/store/clwf7wsykkjdhbd0v8vb94pvg81lnsba-set-environment
$ . /nix/store/clwf7wsykkjdhbd0v8vb94pvg81lnsba-set-environment
Observe que (ao contrário de steam-run
) nix-ld
não vem com nenhuma biblioteca por padrão (na verdade, isso não é mais verdade, veja a nota no topo deste arquivo para usar a interface mais moderna com uma lista padrão… mas a lista é bem pequena) mas você pode adicionar seus próprios ou usar ferramentas para fazer isso automaticamente, veja abaixo. Você também pode se inspirar na lista de bibliotecas que rodam em pacotes aqui:https://github.com/NixOS/nixpkgs/blob/master/pkgs/games/steam/fhsenv.nixAqui está por exemplo o arquivo que estou usando por enquanto, basta rodar o blender/electron:
programs.nix-ld.enable = true;
environment.variables = {
NIX_LD_LIBRARY_PATH = with pkgs; lib.makeLibraryPath [
stdenv.cc.cc
openssl
xorg.libXcomposite
xorg.libXtst
xorg.libXrandr
xorg.libXext
xorg.libX11
xorg.libXfixes
libGL
libva
pipewire.lib
xorg.libxcb
xorg.libXdamage
xorg.libxshmfence
xorg.libXxf86vm
libelf
# Required
glib
gtk2
bzip2
# Without these it silently fails
xorg.libXinerama
xorg.libXcursor
xorg.libXrender
xorg.libXScrnSaver
xorg.libXi
xorg.libSM
xorg.libICE
gnome2.GConf
nspr
nss
cups
libcap
SDL2
libusb1
dbus-glib
ffmpeg
# Only libraries are needed from those two
libudev0-shim
# Verified games requirements
xorg.libXt
xorg.libXmu
libogg
libvorbis
SDL
SDL2_image
glew110
libidn
tbb
# Other things from runtime
flac
freeglut
libjpeg
libpng
libpng12
libsamplerate
libmikmod
libtheora
libtiff
pixman
speex
SDL_image
SDL_ttf
SDL_mixer
SDL2_ttf
SDL2_mixer
libappindicator-gtk2
libdbusmenu-gtk2
libindicator-gtk2
libcaca
libcanberra
libgcrypt
libvpx
librsvg
xorg.libXft
libvdpau
gnome2.pango
cairo
atk
gdk-pixbuf
fontconfig
freetype
dbus
alsaLib
expat
# Needed for electron
libdrm
mesa
libxkbcommon
];
NIX_LD = lib.fileContents "${pkgs.stdenv.cc}/nix-support/dynamic-linker";
};
Você também pode encontrar o nome das bibliotecas, veja acima nix-index
. Você também pode usarnix-alien-ldouAutobahn nixpara localizar e carregar automaticamente as bibliotecas para você. Observe que se você não tiver as bibliotecas corretas, receberá um erro como
$ ./blender
./blender: error while loading shared libraries: libX11.so.6: cannot open shared object file: No such file or directory
Você pode ver de uma vez todas as bibliotecas que ainda não estão disponíveis usando:
$ LD_LIBRARY_PATH=$NIX_LD_LIBRARY_PATH ldd turtl
libpangocairo-1.0.so.0 => /nix/store/n9h110ffps25rdkkim5k802p3p5w476m-pango-1.50.6/lib/libpangocairo-1.0.so.0 (0x00007f02feb83000)
libatk-1.0.so.0 => not found
…
Método 9) nix-alien
nix-alienígenaconstrói automaticamente uma ESF com as bibliotecas apropriadas. Se você tiver o flake habilitado (caso contrário, basta adicionar replace nix run
with nix --extra-experimental-features "nix-command flakes" run
), você pode simplesmente executá-lo desta forma (nix-alien ainda não está empacotado em 2022)
nix run github:thiagokokada/nix-alien -- yourprogram
Em seguida, ele encontrará automaticamente a biblioteca usando nix-index, fazendo algumas perguntas quando não tiver certeza (isso está armazenado em cache).
Observe que os programas que dependem do openGl precisam usarnixGlpara executar (isso certamente se aplica a outros métodos aqui):
nix run --impure github:guibou/nixGL --override-input nixpkgs nixpkgs/nixos-21.11 -- nix run github:thiagokokada/nix-alien -- blender
Observe que pode ser necessário alterar a versão do nixos-21.11
para garantir que a versão do openGl corresponda ao seu programa.
Observe que você também pode ver o arquivo gerado automaticamente (o caminho é fornecido na primeira vez que o programa é executado):
$ cat /home/leo/.cache/nix-alien/87a5d119-f810-5222-9b47-4809257c60ec/fhs-env/default.nix
{ pkgs ? import <nixpkgs> { } }:
let
inherit (pkgs) buildFHSUserEnv;
in
buildFHSUserEnv {
name = "blender-fhs";
targetPkgs = p: with p; [
xorg.libX11.out
xorg.libXfixes.out
xorg.libXi.out
xorg.libXrender.out
xorg.libXxf86vm.out
xorg_sys_opengl.out
];
runScript = "/tmp/blender-3.2.2-linux-x64/blender";
}
Veja também a outra versão trabalhando com nix-ld eAutobahn nix.
Método 9) Usando contêineres/Docker (mais pesado)
PENDÊNCIA
Observe que o projetocaixa de distribuiçãopermite que você simplesmente crie novos contêineres totalmente integrados ao host, instalando qualquer distribuição desejada.
Método 10) Confie em flatpack/appimage
https://nixos.org/nixos/manual/index.html#module-services-flatpak
appimage-run: Para testar com, ex, musescore
Fontes ou exemplos
- https://github.com/NixOS/nixpkgs/blob/5a9eaf02ae3c6403ce6f23d33ae569be3f9ce644/pkgs/applications/video/lightworks/default.nix
- https://sandervanderburg.blogspot.com/2015/10/deploying-prebuilt-binary-software-with.html
- https://github.com/NixOS/nixpkgs/blob/35c3396f41ec73c5e968a11f46d79a94db4042d7/pkgs/applications/networking/dropbox/default.nix
Além disso, para pessoas que desejam começar com embalagens, escrevi recentemente um tutorial semelhanteaqui.