Каковы различные методы запуска исполняемого файла, отличного от Nixos, на NixO? (Например, проприетарные двоичные файлы.) Я бы хотел увидеть также ручные методы.
решение1
Похожие ответы
Если вы планируете упаковать двоичный файл, а не просто запустить его, вам может понравиться этот мой другой ответ:Как упаковать мое программное обеспечение в nix или написать свой собственный пакет для nixpkgs
Укороченная версия
Быстро и грязно: убедитесь, steam-run
что установлен (странное название, оно не имеет никакого отношения к Steam), например nix-shell -p steam-run
, затем:
$ steam-run ./your-binary
С момента создания этого ответа были разработаны другие альтернативы Steam-Run, см., например, nix-ld
который теперь является частью NixOs (который по сути воссоздает отсутствующие загрузчики в /lib
… Iвысокорекомендуем вам настроить его один раз и навсегда, таким образом вам больше не придется беспокоиться о запуске неисправленных двоичных файлов, и вы сможете использовать NPM и т. д. без головной боли):
(предупреждение: после недавнего обновления nix вам нужно только programs.nix-ld.enable = true;
, и переменные можно настроить с помощью
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 ]);
для автоматической установки переменных среды, но приведенный ниже код должен работать и на устаревших системах, поэтому я оставлю его здесь) Обратите внимание, что вам также может потребоваться перезагрузка, чтобы убедиться, что переменные среды установлены правильно, в последнее время не проверялось.
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";
};
А также естьnix-инопланетянин/nix-автобанкоторые также автоматически пытаются добавить недостающие библиотеки. Наконец, вы можете использоватьдистрибутивкоторый предоставляет вам любой дистрибутив в контейнере docker/podman, тесно интегрированный с хостом... но по моему опыту, его сложнее использовать, чтобы nix-ld
он был по-настоящему прозрачным.
Вот более длинное и подробное объяснение, а также различные методы, зачастую менее грязные.
Длинная версия
Вот несколько методов (ручные методы в основном предназначены для образовательных целей, так как в большинстве случаев написание правильного вывода лучше). Я совсем не эксперт, и я также составил этот список, чтобы изучить nix, так что если у вас есть лучшие методы, дайте мне знать!
Итак, главная проблема заключается в том, что исполняемый файл сначала вызывает загрузчик, а затем для работы ему требуются некоторые библиотеки, а Nixos помещает и загрузчик, и библиотеки в /nix/store/
.
В этом списке приведены все методы, которые я нашел до сих пор. В основном есть три "группы":
- полное руководство: интересно в образовательных целях и для понимания того, что происходит, но это все (не используйте их на практике, потому что ничто не помешает впоследствии удалить использованные производные)
- пропатченные версии: эти методы пытаются изменить исполняемый файл (автоматически при использовании рекомендуемого метода 4 с autoPatchelfHook), чтобы напрямую указать на правильную библиотеку
- методы, основанные на FHS, которые по сути имитируют «обычный Linux» (более сложны в запуске, чем пропатченная версия, поэтому их следует по возможности избегать).
Я бы рекомендовал метод 4 autoPatchelfHook
для настоящей, правильной настройки, а если у вас нет времени и вы просто хотите запустить двоичный файл в одну строку, вас может заинтересовать быстрое и грубое решение, основанное на steam-run
(методе 7).
Метод 1) Грязный ручной метод, без патча
Сначала вам нужно найти загрузчик, например 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
Вот загрузчик /lib64/ld-linux-x86-64.so.2
. Чтобы найти загрузчик nixos, вы можете сделать:
$ ls /nix/store/*glibc*/lib/ld-linux-x86-64.so.2
/nix/store/681354n3k44r8z90m35hm8945vsp95h1-glibc-2.27/lib/ld-linux-x86-64.so.2
Вам также необходимо найти библиотеки, которые требуются вашей программе, например, с помощью ldd
или 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)
Здесь вы видите, что найдено большинство библиотек, за исключением libstdc++.so.6
. Так что давайте найдем их! Первый быстрый и грязный способ найти их — проверить, присутствуют ли они уже в вашей системе:
$ find /nix/store -name libstdc++.so.6
/nix/store/12zhmzzhrwszdc8q3fwgifpwjkwi3mzc-gcc-7.3.0-lib/lib/libstdc++.so.6
Если библиотека еще не установлена, вы наверняка предпочтете использовать более сложную версию.nix-index
программа для поиска этих файлов в гораздо большей базе данных (спасибо hydra). Для этого сначала установите nix-index
и сгенерируйте базу данных (это нужно только в первый раз, но запуск может занять несколько минут):
$ nix-index
(Вы также можете использовать nix run github:mic92/nix-index-database yourlib
, чтобы избежать повторного создания базы данных локально. См. nix-index-update
такжеnix-инопланетяниндля автоматической загрузки кэша изnix-индекс-база данных) тогда для поиска библиотеки вы можете сделать что-то вроде этого (обратите внимание, что это --top-level
удалит некоторые записи):
$ 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
…
Затем вы можете установить эти библиотеки для этого быстрого и грубого примера (позже мы увидим лучшие решения).
Хорошо. Теперь нам просто нужно запустить программу с LD_LIBRARY_PATH
настроенным указателем на этот файл (см. также, makeLibraryPath
чтобы сгенерировать эту строку в выводе), и вызвать загрузчик, который мы определили на первом шаге для этого файла:
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
(обязательно используйте ./
перед именем скрипта и оставьте только каталог библиотек. Если у вас несколько библиотек, просто используйте concat пути с двоеточиями)
Метод 2) Грязный ручной метод, с патчем
После установки (с nixenv -i
или в вашем configuration.nix
) patchelf
вы также можете напрямую изменить исполняемый файл, чтобы упаковать хороший загрузчик и библиотеки. Чтобы изменить загрузчик, просто запустите:
patchelf --set-interpreter /nix/store/681354n3k44r8z90m35hm8945vsp95h1-glibc-2.27/lib/ld-linux-x86-64.so.2 wolframscript
и проверить:
$ patchelf --print-interpreter wolframscript
/nix/store/681354n3k44r8z90m35hm8945vsp95h1-glibc-2.27/lib/ld-linux-x86-64.so.
и чтобы изменить путь к библиотекам, жестко закодированным в исполняемом файле, сначала проверьте текущий rpath (у меня он пустой):
$ patchelf --print-rpath wolframscript
и добавьте их к пути к библиотеке, который вы определили ранее, в конечном итоге разделив двоеточиями:
$ patchelf --set-rpath /nix/store/12zhmzzhrwszdc8q3fwgifpwjkwi3mzc-gcc-7.3.0-lib/lib/ wolframscript
$ ./wolframscript
Метод 3) Патч в nix-деривации
Мы можем воспроизвести более или менее то же самое в выводе nix, вдохновленномskypeдляlinux
В этом примере также представлена альтернатива: вы можете использовать:
patchelf --set-interpreter ${glibc}/lib/ld-linux-x86-64.so.2 "$out/bin/wolframscript" || true
(что должно быть совершенно ясно, как только вы поймете «ручной» метод), или
patchelf --set-interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" "$out/bin/wolframscript" || true
Второй метод немного более изощренный, но если вы выполните:
$ 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
вы увидите, что файл $NIX_CC/nix-support/dynamic-linker
содержит путь к загрузчику ld-linux-x86-64.so.2
.
Вставьте derivation.nix
, это
{ 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" ];
};
}
и default.nix
вставьте:
{ pkgs ? import <nixpkgs> {} }:
pkgs.callPackage ./derivation.nix {}
Скомпилируйте и запустите с помощью
nix-build
result/bin/wolframscript
Метод 4) Использование autoPatchElf: проще
Все предыдущие методы требуют немного работы (вам нужно найти исполняемые файлы, пропатчить их...). NixOs сделал для нас специальный "хук", autoPatchelfHook
который автоматически пропатчит все для вас! Вам просто нужно указать его в (native)BuildInputs
, и nix сделает магию.
{ 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" ];
};
}
Метод 5) Используйте FHS для имитации классической оболочки Linux и вручную запустите файлы
Некоторое программное обеспечение может быть трудно упаковать таким образом, поскольку оно может сильно зависеть отФХССтруктура дерева файлов или может проверить, что двоичные файлы не изменяются. Затем вы также можете использоватьbuildFHSUserEnvдля предоставления файловой структуры FHS (облегченной, с использованием пространств имен) для вашего приложения.Обратите внимание, что этот метод сложнее, чем методы на основе патчей, и значительно увеличивает время запуска, поэтому по возможности избегайте его.
Вы можете либо просто создать оболочку, а затем вручную извлечь архив и выполнить файл, либо напрямую упаковать свою программу для FHS. Давайте сначала посмотрим, как получить оболочку. Поместите в файл (например, fhs-env.nix
) следующее:
let nixpkgs = import <nixpkgs> {};
in nixpkgs.buildFHSUserEnv {
name = "fhs";
targetPkgs = pkgs: [];
multiPkgs = pkgs: [ pkgs.dpkg ];
runScript = "bash";
}
и запустите:
nix-build fhs-env.nix
result/bin/fhs
Затем вы получите bash в более стандартном Linux-окружении и сможете выполнять команды для запуска исполняемого файла, например:
mkdir wolf_fhs/
dpkg -x WolframScript_12.0.0_LINUX64_amd64.deb wolf_fhs/
cd wolf_fhs/opt/Wolfram/WolframScript/bin/
./wolfram
Если вам нужны дополнительные библиотеки/программы в качестве зависимостей, просто добавьте их в multiPkgs
(для всех поддерживаемых архитектур) или targetPkgs
(только для текущей архитектуры).
Бонус: вы также можете запустить оболочку fhs с помощью однострочной команды, не создавая специального файла:
nix-build -E '(import <nixpkgs> {}).buildFHSUserEnv {name = "fhs";}' && ./result/bin/fhs
Метод 6) Используйте FHS для имитации классической оболочки Linux и упакуйте файлы внутрь
источник:https://reflexivereflection.com/posts/2015-02-28-deb-installation-nixos.html
Метод 7) паровой запуск
С помощью buildFHSUserEnv
вы можете запустить множество программ, но вам нужно будет вручную указать все требуемые библиотеки. Если вам нужно быстрое решение и у вас нет времени, чтобы точно проверить, какие библиотеки требуются, вы можете попробовать steam-run
(несмотря на название, он не связан напрямую со Steam, а просто упаковывает множество библиотек), что похоже buildFHSUserEnv
на множество предустановленных распространенных библиотек (некоторые из них могут быть несвободными, например, steamrt
этот упаковывает некоторый код nvidia, спасибо, simpson!). Чтобы использовать его, просто установите steam-run
, а затем:
steam-run ./wolframscript
или если вам нужна полная оболочка:
steam-run bash
Обратите внимание, что вам может потребоваться добавить nixpkgs.config.allowUnfree = true;
(или внести в белый список)этот конкретный пакет), если вы хотите установить его с помощью nixos-rebuild
, и если вы хотите запустить/установить его с помощью nix-shell
/, nix-env
вам нужно { allowUnfree = true; }
вставить ~/.config/nixpkgs/config.nix
.
Нелегко «перезаписать» пакеты или библиотеки в nix-shell, но если вы хотите создать оболочку вокруг своего скрипта, вы можете вручную создать скрипт-оболочку:
#!/usr/bin/env nix-shell
#!nix-shell -i bash -p steam-run
exec steam-run ./wolframscript "$@"
или напрямую запишите его в выводе nixos:
{ stdenv, steam-run, writeScriptBin }:
let
src = ./opt/Wolfram/WolframScript/bin/wolframscript;
in writeScriptBin "wolf_wrapped_steam" ''
exec ${steam-run}/bin/steam-run ${src} "$@"
''
или если вы начнете с .deb (здесь я использовал 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
'';
}
(если вы слишком устали, чтобы писать как обычно default.nix
, вы можете сразу бежать nix-build -E "with import <nixpkgs> {}; callPackage ./derivation.nix {}"
)
Метод 8) Использованиеnix-ld
Если вы не хотите создавать песочницу, как мы сделали для Steam-run (в песочницах невозможно запускать приложения setuid, песочницы не могут быть вложенными, плохая интеграция с системными пакетами, включая direnv), вы можете воссоздать отсутствующий загрузчик для всей системы, вставив свой configuration.nix
:
programs.nix-ld.enable = true;
Вы можете видеть, что файл теперь присутствует:
$ ls /lib64/
ld-linux-x86-64.so.2
Однако запуск двоичных файлов по-прежнему невозможен, поскольку новый ld-linux-x86-64.so.2
файл только перенаправляет на загрузчик NIX_LD
(таким образом, несколько программ могут использовать разные загрузчики, находясь в одной системе):
$ ./blender
cannot execute ./blender: NIX_LD or NIX_LD_x86_64-linux is not set
Чтобы локально создать эту переменную среды, вы можете сделать что-то вроде:
$ 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
или в масштабах всей системы с использованием:
(предупреждение: после недавнего обновления nix вам понадобится только programs.nix-ld.enable = true;
, и переменные можно настраивать с помощью programs.nix-ld.libraries = with pkgs; [];
вместо переменных окружения, но приведенный ниже код должен работать и на устаревших системах, поэтому я оставлю его здесь)
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";
};
Обратите внимание, что вам необходимоперезапускваш сеанс X11 каждый раз, когда вы изменяете этот файл или делаете:
$ cat /etc/profile | grep set-environment
. /nix/store/clwf7wsykkjdhbd0v8vb94pvg81lnsba-set-environment
$ . /nix/store/clwf7wsykkjdhbd0v8vb94pvg81lnsba-set-environment
Обратите внимание, что (в отличие от steam-run
) nix-ld
не поставляется с какой-либо библиотекой по умолчанию (на самом деле, это уже не так, см. примечание в верхней части этого файла, чтобы использовать более современный интерфейс со списком по умолчанию... но список довольно маленький), но вы можете добавить свой собственный или использовать инструменты, чтобы сделать это автоматически, см. ниже. Вы также можете вдохновиться списком библиотек, которые запускает steam, здесь:https://github.com/NixOS/nixpkgs/blob/master/pkgs/games/steam/fhsenv.nixВот, например, файл, который я сейчас использую, его достаточно для запуска 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";
};
Вы также можете найти название библиотек, см. выше nix-index
. Вы также можете использоватьnix-alien-ldилиnix-автобанавтоматически находить и загружать библиотеки для вас. Обратите внимание, что если у вас нет нужных библиотек, вы получите ошибку типа
$ ./blender
./blender: error while loading shared libraries: libX11.so.6: cannot open shared object file: No such file or directory
Вы можете сразу увидеть все библиотеки, которые еще недоступны, используя:
$ 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
…
Метод 9) nix-alien
nix-инопланетянинавтоматически создает FHS с соответствующими библиотеками. Если у вас включен flake (иначе просто добавьте replace nix run
на nix --extra-experimental-features "nix-command flakes" run
), вы можете просто запустить его таким образом (nix-alien еще не упакован в 2022)
nix run github:thiagokokada/nix-alien -- yourprogram
Затем он автоматически найдет библиотеку с помощью nix-index, задавая вам несколько вопросов, если он не уверен (эта информация кэшируется).
Обратите внимание, что программы, использующие OpenGl, должны использоватьnixGlдля запуска (это, безусловно, относится и к другим методам здесь):
nix run --impure github:guibou/nixGL --override-input nixpkgs nixpkgs/nixos-21.11 -- nix run github:thiagokokada/nix-alien -- blender
Обратите внимание, что вам может потребоваться изменить версию, nixos-21.11
чтобы убедиться, что версия openGl соответствует вашей программе.
Обратите внимание, что вы также можете увидеть автоматически сгенерированный файл (путь указывается при первом запуске программы):
$ 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";
}
См. также другую версию, работающую с nix-ld иnix-автобан.
Метод 9) Использование контейнеров/Docker (тяжелее)
ДЕЛАТЬ
Обратите внимание, что проектдистрибутивпозволяет вам просто создавать новые контейнеры, тесно интегрированные с хостом, устанавливая любой желаемый вами дистрибутив.
Метод 10) Используйте flatpack/appimage
https://nixos.org/nixos/manual/index.html#module-services-flatpak
appimage-run : Для тестирования с помощью, например, musescore
Источники или примеры
- 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
Также, для тех, кто хочет начать заниматься упаковкой, я недавно написал похожее руководство.здесь.