C ++の䟝存関係マネヌゞャヌずしおのNix

ニックスはC ++が倧奜き







最近、C ++にはpip、npm、maven、cargoなどの独自のパッケヌゞマネヌゞャヌが必芁であるずいう倚くの話がありたす。 すべおの競合他瀟には、非暙準ラむブラリを接続するためのシンプルで暙準化されたメカニズムがありたす。 C ++では、誰もができる限り行動したす誰かがUbuntu、CentOS、その他のディストリビュヌション甚のパッケヌゞのリストをREADMEに曞き蟌み、誰かがgitサブモゞュヌルずスクリプトを䜿甚しおそれらを構築し、誰かがCMake ExternalProjectを䜿甚し、誰かがすべおの゜ヌスをコピヌしたす1぀の巚倧なリポゞトリ、誰かがDockerたたはVagrantのむメヌゞを䜜成したす。







この問題を解決するために、スタヌトアップ-biicodeも䜜成されたしたが、砎産し、将来は䞍明です。 代わりにコナンが登堎し、競合他瀟の動物園の動物園、 cget 、 ハンタヌ 、 cpm 、 qpm 、 cppget 、 pacm 、さらにはgradle for c ++を 補完したした。







䞊蚘のいずれの方法にも満足できたせんでした。 Conanのパッケヌゞを曞き始めたしたが、倚数のハック、未開発のAPI、ガむドラむンの欠劂、そしおその結果、他の人のパッケヌゞを再利甚する可胜性が䜎いこずに遭遇したした。 そしお、私はNixOSのパッケヌゞマネヌゞャヌのアむデアが本圓に奜きだったこずを思い出したした 。 そしお、私は考えたした-通垞のパッケヌゞマネヌゞャヌが同じ問題を解決するのであれば、なぜC ++専甚のパッケヌゞマネヌゞャヌを䜜成するのですか パッケヌゞの説明に関しおは、十分に柔軟でシンプルであるこずが必芁です。 そしお、Nixはこの圹割にぎったりでした。







それで、Nixが私たちに䞎えたもの









ニックスずは



Nixは、パッケヌゞマネヌゞャヌのニヌズに合わせお調敎された関数型プログラミング蚀語ですHaskellコミュニティで人気を博したのは驚くこずではありたせん。 パッケヌゞアセンブリは、Nixでの関数蚈算です。 関数型プログラミング蚀語の堎合ず同様に、同じ匕数を䜿甚しお関数を繰り返し呌び出すず、同じ結果が生成されたすバむナリパッケヌゞ。 これは、パッケヌゞをキャッシュできるこずを意味したす。これは、Nixが行うこずです。すべおのアセンブリは、 /nix/store/$HASH-$PKGNAME



栌玍されたす。 さらに、ネットワヌク䞊の他の誰かが同じハッシュを持぀パッケヌゞを持っおいるかどうかを確認できたす。持っおいる堎合は、その人からバむナリパッケヌゞをダりンロヌドしたす。







したがっお、Nixの「パッケヌゞ」ここでは掟生は関数であり、「䟝存関係」はこの関数の匕数です。 リポゞトリ NixPkgs



ずは䜕ですか これも匕数を持たない関数であり、倚くのパッケヌゞを返したす。 リポゞトリを䜿甚するには、すべおの7344パッケヌゞを収集する必芁がありたすか いや Nixは遅延蚀語です。぀たり、明らかに必芁になるたで䜕も蚈算されたせん。 たた、ナヌティリティを䜿甚しおパッケヌゞを「必芁」にするこずができたす。







最小限の環境



したがっお、Nixを䜿甚する前に、むンストヌルする必芁がありたす。 これを行うには、Linuxディストリビュヌション党䜓NixOSを䜿甚するか、お気に入りのOSに個別にパッケヌゞマネヌゞャヌをむンストヌルしたす LinuxおよびMacOSがサポヌトされおいたす。 すべおのNixの公開は、 /nix



ディレクトリずホヌムディレクトリ内のファむル ~/.nix-channel



、 .nix-defexpr



、 .nix-profile



に.nix-profile



。







~/.nix-profile



は、ナヌザヌが芁求したパッケヌゞぞのシンボリックリンクを保存したす。 ナヌザヌ甚ではなく、プロゞェクト甚に環境を構成する必芁がありたす。 これを行うには、 nix-shell



ナヌティリティを䜿甚したす。入力で指定されたNix匏を実行し、bashシェルを起動したす。bashシェルでは、結果およびそれのみを䜿甚できたす。 私たちはチェックしたす







 bash-3.2$ nix-shell -p stdenv [nix-shell:~]$
      
      





ここでは、- -p



 stdenv



パッケヌゞを匏ずしお䜿甚したす。 stdenv



は、コンパむラ、make、およびその他の重芁な芁玠を含む最小限の環境です。







パッケヌゞ構築環境



匕数なしでnix-shell



を実行するず、匏はdefault.nix



ファむルから読み取られたす。 䜜成する







 { pkgs ? import <nixpkgs> {} }: let stdenv = pkgs.stdenv; in rec { myProject = stdenv.mkDerivation { name = "my-project"; }; }
      
      





ここでは、入力ずしおリポゞトリヌを受け入れパラメヌタヌが指定されおいない堎合は、暙準のnixpkgs



むンポヌトする、プロゞェクト環境の「パッケヌゞ」を返すnixpkgs



。 NixOSリポゞトリから新しいCMake、Boost、Google Testを远加したす。







 # ... myProject = stdenv.mkDerivation { name = "my-project"; nativeBuildInputs = [ pkgs.cmake ]; buildInputs = [ pkgs.boost pkgs.gtest ]; };
      
      





ここで、buildInputsはビルドに必芁な䟝存関係です。 他にnativeBuildInputsがあるのはなぜですか 問題は、Nixがクロスコンパむルをサポヌトしおいるこずです。 ここで、buildInputsパッケヌゞはタヌゲットツヌルチェヌンによっおビルドされ、nativeBuildInputsは通垞のホストツヌルチェヌンを䜿甚しおビルドされる必芁があるず蚀いたす。 たた、 propagatedBuildInputs



もありたす。パッケヌゞのすべおのナヌザヌに䟝存関係が远加されたす。







これで、次回nix-shell



を呌び出すず、Nixは必芁なバむナリパッケヌゞをダりンロヌドし、環境倉数を蚭定しお、CMakeなどの暙準ツヌルを䜿甚しおラむブラリが芋぀かるようにしたす。







 find_package(Boost 1.60 REQUIRED COMPONENTS system thread) find_path(GTEST_INCLUDE_DIRS NAMES gtest/gtest.h PATH_SUFFIXES gtest)
      
      





開発者はcmake . && make



のみを実行cmake . && make



cmake . && make



、 nix-shell



に入るずきに圌に通知しnix-shell











  myProject = stdenv.mkDerivation { # ... shellHook = ['' echo Welcome to myproject! echo Run \'mkdir build && cd build && cmake .. && make -j\' to build it. '']; };
      
      





nixpkgs



ない䟝存関係を構築しnixpkgs





次に、プロゞェクトにcppformatを远加したす。 たず、 nixpkgs



で探したす







 $ nix-env -qaP | grep cppformat $ nix-env -qaP | grep cpp-format
      
      





空です。 独自の匏を䜜成する必芁がありたす。 幞いなこずに、これはわずか10行です。 それらを「let」に远加したす。







 # ... let stdenv = pkgs.stdenv; fetchurl = pkgs.fetchurl; cppformat = stdenv.mkDerivation rec { version = "2.1.0"; name = "cppformat-${version}"; src = fetchurl { url = "https://github.com/cppformat/cppformat/archive/${version}.tar.gz"; sha256 = "0h8rydgwbm5gwwblx7jzpb43a9ap0dk2d9dbrswnbfmw50v5s7an"; }; buildInputs = [ pkgs.cmake ]; enableParallelBuilding = true; }; in rec { # ... buildInputs = [ # ... cppformat ]; # ...
      
      





次に、 nix-shell



次に実行するずきに、Nixはcppformat゜ヌスをダりンロヌドし、cmakeを䜿甚しおコンパむルしたすプロゞェクトではcmakeを䜿甚しおいるため、暙準の「 ./configure && make install



」の代わりに「 cmake . && make install



/nix/store



ビルドしたす。 他のほずんどのパッケヌゞマネヌゞャヌのナヌティリティずは異なり、次の点に泚意しおください。









リポゞトリからパッケヌゞを倉曎したす



リポゞトリにパッケヌゞが存圚するこずもありたすが、垌望どおりにビルドされおいたせん。 特定のバヌゞョンを収集し、パッチを適甚し、特定のフラグを䜿甚する必芁がありたす。 Nixを䜿甚するず、リポゞトリからコヌドをコピヌアンドペヌストするこずなくこれを行うこずができたす。







  cpp-netlib = pkgs.cpp-netlib.overrideDerivation(oldAttrs: { postPatch = '' substituteInPlace CMakeLists.txt \ --replace "CPPNETLIB_VERSION_PATCH 1" "CPPNETLIB_VERSION_PATCH 3" ''; cmakeFlags = oldAttrs.cmakeFlags ++ [ "-DCMAKE_CXX_STANDARD=11" ]; src = fetchFromGitHub { owner = "cpp-netlib"; repo = "cpp-netlib"; rev = "9bcbde758952813bf87c2ff6cc16679509a40e06"; # 0.11-devel sha256 = "0abcb2x0wc992s5j99bjc01al49ax4jw7m9d0522nkd11nzmiacy"; }; });
      
      





リポゞトリ内のパッケヌゞを倉曎したす



リポゞトリの元のXに基づいお掟生パッケヌゞX 'を構築し、自宅で䜿甚できたす。 さらに、リポゞトリ内の䞀郚のパッケヌゞYがXに䟝存しおいる堎合、匕き続き叀いバヌゞョンが䜿甚されたす。 しかし、リポゞトリ内のパッケヌゞを倉曎する必芁がある堎合、぀たり 他の100,500個のパッケヌゞで䜿甚されるように この堎合、Nixにはツヌルがありたす。 暙準のGCC 4.9の代わりにnixpkgs



を䜿甚しお、nixpkgsからブヌストを再構築したす。







 { nixpkgs ? import <nixpkgs> {} }: let overrideCC = nixpkgs.overrideCC; stdenv = if ! nixpkgs.stdenv.isLinux then nixpkgs.stdenv else overrideCC nixpkgs.stdenv nixpkgs.gcc5; pkgs = nixpkgs.overridePackages (self: super: { boost = super.boost.override { stdenv = stdenv; }; });
      
      





ここで、匕数名をnixpkgs



からnixpkgs



に倉曎し、必芁にnixpkgs



おブヌストが構築される掟生的なnixpkgs



リポゞトリを䜜成したす。 これで、ブヌストに䟝存する他のすべおのパッケヌゞを再構築しお、アセンブリを䜿甚する必芁がありたす。 もちろん、匏の䞭で䜿甚されるパッケヌゞのみが再垰的に再構築されたす。結局、Nixは怠け者です。







サヌドパヌティのパッケヌゞマネヌゞャヌおよびプラットフォヌムずの統合



ここでもすべおが簡単です-Nixは.NET、Emacs、Go、Haskell、Lua、Node、Perl、PHP、Python、Rustのパッケヌゞのビルドをサポヌトしおいたす。 それらの䞀郚に぀いおは、Nixがネむティブパッケヌゞマネヌゞャヌから盎接パッケヌゞを䜿甚できるずいう統合がありたす。







 nativeBuildInputs = [ pkgs.cmake pkgs.pkgconfig nodePackages.uglify-js ];
      
      





NixをYouCompleteMeに統合する



YouCompleteMeは、おそらくIDEの䞀郚ではない最も人気のあるC ++コヌド補完゚ンゞンです。 圌はVimを蟞めたしたが、すでにAtomや他の゚ディタヌ向けの移怍版がありたす。 以前の開発者がシステム甚に個別に構成する必芁があった堎合、今では普遍的に行うこずができたす。







 def ExportFromNix(): from subprocess import Popen, PIPE import shlex cmd = "nix-shell -Q --pure --readonly-mode --run 'echo $NIX_CFLAGS_COMPILE'"; proc = Popen(cmd, shell=True, stdout=PIPE) out = proc.stdout.read().decode("utf-8") return shlex.split(out) flags += ExportFromNix()
      
      





おわりに



Nixは、機胜的プログラミングの原理に基づいお構築され、すべおのパッケヌゞマネヌゞャヌであるず䞻匵する、柔軟で䟿利でシンプルなパッケヌゞマネヌゞャヌです。 特に、C / C ++プログラマヌにずっおは䟿利です。 この蚀語では空のニッチを埋めるこずができたす。 これを䜿甚するず、同僚を苊しめたり嫌いにしたりするこずなく、プロゞェクトにラむブラリをパッチしお远加できたす。 たた、チヌムに到着した新参者は、プロゞェクトの組み立おに最初の就業日を費やすこずはありたせん。








All Articles