Nix Flakes와 그에 대응하는 Guix 기능들
2 hours ago
3
Nix Flakes 는 프로젝트 의존성, 잠금, 출력 스키마, 개발 환경을 flake.nix와 flake.lock 중심으로 묶고, Guix는 channels, manifests, guix describe, guix shell, operating-system 같은 직교 도구 조합으로 같은 종류의 기능을 제공함
Flakes 는 프로젝트별 inputs와 자동 flake.lock으로 의존성을 고정하고, Guix는 사용자별 guix describe와 프로젝트에 커밋을 적은 channels.scm, guix time-machine으로 재현 가능한 환경을 구성함
순수성 은 Flakes에서 restricted evaluation으로 강제되고, Guix에서는 Scheme 모듈 구조와 명시적 입력, 격리된 빌드 컨테이너를 통해 설계상 달성됨
출력 구조 는 Flakes가 packages, devShells, nixosConfigurations 같은 표준 attrset을 제공하는 반면, Guix는 <package>, manifest, operating-system, service 같은 투명한 Scheme 레코드와 파일을 각 명령이 직접 소비함
선택 기준 은 단일 진입점과 표준 스키마를 선호하면 Flakes가 맞고, 작고 독립적인 도구를 조합하는 방식을 선호하면 Guix가 더 잘 맞음
핵심 비교
Nix flake에 해당하는 단일 Guix 기능은 없으며, Nix Flakes가 여러 문제를 하나의 큰 기능으로 해결하는 반면 Guix는 더 작고 직교적인 도구들의 조합으로 대응함
Guix는 Nix daemon을 재사용했으며, build isolation과 store management를 담당하는 C++ 구성요소를 공유함
Guix는 Nix daemon 위의 언어, 패키지 정의, 서비스 시스템 등 대부분을 Guile Scheme으로 새로 구현함
Guix와 Nix는 derivation format인 ATerm과 daemon 계보를 공유하지만, daemon 위의 구조는 Guix 자체 방식으로 구성됨
Guix는 Flakes가 제공하는 capabilities를 갖고 있지만, 이를 다른 형태로 제공함
Nix Flake의 기본 구조
Nix flake 는 root에 flake.nix 파일을 가진 source tree이며, 보통 Git repository 형태임
flake.nix의 존재가 source tree를 flake로 만들며, 파일은 description, inputs, outputs 같은 구조를 가짐
description은 사람이 읽을 수 있는 문자열로 flake가 제공하는 내용을 나타냄
inputs는 다른 flakes, Git repos, tarballs 같은 dependencies를 선언하며, Nix가 이를 fetch하고 evaluate한 뒤 outputs 함수에 전달함
outputs는 resolved inputs와 특별한 self input을 받아 packages, dev shells, NixOS configurations, overlays 등을 담은 structured attrset을 반환하는 함수임
예시 구조와 실행 대상
예시 inputs의 nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";는 GitHub의 NixOS/nixpkgs 저장소에서 nixos-unstable branch를 가져온다는 의미임
예시 flake는 supportedSystems = [ "x86_64-linux" "aarch64-linux" "x86_64-darwin" ];와 nixpkgs.lib.genAttrs를 사용해 여러 CPU architecture별 outputs를 생성함
Flakes는 packages.<system> 수준을 요구하며, 예시에서는 packages 아래 default package를 pkgs.buildGoModule로 정의함
src = ./.;는 전체 Git repository를 source로 사용함
devShells는 nix develop이 참조하는 개발 shell 정의이며, 예시에서는 pkgs.mkShell과 buildInputs = with pkgs; [ go gopls gotools ];를 사용함
flake.lock과 순수 평가
Nix 명령을 flake에 대해 실행하면 Nix는 모든 input과 transitive input을 정확한 revision으로 고정하는 JSON 파일 flake.lock을 생성함
flake.lock은 machine과 시간에 걸쳐 build reproducibility를 가능하게 하는 lock file임
Flakes는 pure evaluation을 강제하며, $NIX_PATH, builtins.currentSystem, environment variables가 암묵적으로 들어오지 못하고 모든 것이 explicit해야 함
Flakes가 수행하는 기능은 dependencies 선언, dependencies pinning, purity 강제, standard output schema 제공, reproducible sharing, development environments 정의로 정리됨
Guix의 대응 방식
Guix는 Nix 2.4에서 Flakes가 2021년 11월 1일 도입되기 전에 Flakes 기능 상당수에 대한 해법을 이미 갖고 있었음
Guix channels mechanism은 2018~2019년경 도입됨
Guix의 해법은 orthogonal 하며, 단일 monolithic abstraction을 채택하지 않고 각 도구를 독립적으로 사용할 수 있음
Channels와 의존성 선언
Flake에서는 flake.nix 안에 dependencies를 직접 선언하며, 예시에서 nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.11";와 home-manager.url = "github:nix-community/home-manager";를 사용함
Flake input의 inputs.nixpkgs.follows = "nixpkgs";는 home-manager 자체의 nixpkgs input을 가져오지 않고 현재 flake의 nixpkgs를 사용하게 해 서로 다른 nixpkgs copy 두 개가 생기는 상황을 피함
Guix의 channels 는 Guile modules를 포함하는 Git repository이며, 보통 package definitions를 담지만 services, system configurations, 임의 Scheme code도 포함할 수 있음
Guix channels는 ~/.config/guix/channels.scm에 선언하며, 이 Scheme 파일은 channel records의 list를 반환함
guix pull은 모든 channels를 fetch하고 compile하며, 해당 modules를 모든 guix command에서 사용할 수 있게 함
Channels는 repository root의 .guix-channel 파일을 사용해 다른 channels에 대한 dependencies를 선언할 수 있음
Guix channels의 channel dependency는 flake의 inputs와 대략 유사하며, guix pull 실행 시 transitive channel dependencies가 함께 fetch됨
프로젝트별 의존성과 사용자별 의존성
Flakes는 per-project 방식으로 각 repository가 자체 flake.nix와 inputs를 가지며, channels는 system-wide 또는 per-user 방식으로 channels.scm이 모든 guix invocations에 적용됨
Flakes는 서로 다른 프로젝트가 서로 다른 dependency set을 자연스럽게 갖도록 지원하며, Guix에서는 같은 효과를 위해 보통 guix time-machine 또는 separate profiles를 사용함
Flakes는 github:NixOS/nixpkgs, git+https://... 같은 URL-like syntax를 사용하며, channels는 plain Git URLs를 사용함
Flake syntax는 quick references에 더 ergonomic하고, channels는 더 단순하고 explicit함
Flakes는 flake = false;로 flake.nix가 없는 repositories를 non-flake inputs로 지원함
Guix에서 channel은 Scheme files가 들어 있는 Git repository이므로 특별한 opt-in이 필요 없으며, Guile modules가 있는 어떤 repository도 channel이 될 수 있음
고정, 재현성, 시간 이동
flake.lock
flake.lock은 JSON graph이며, 모든 input은 정확한 commit hash로 pinning되고 Nix는 fetch한 source tree 전체의 hash인 narHash를 검증함
flake.lock은 repository에 commit되므로, clone한 사람은 동일한 dependency versions를 받음
flake.lock의 original은 요청한 대상이고 locked는 실제로 얻은 대상임
flake.lock의 two-layer system은 nix flake lock --update-input nixpkgs처럼 특정 input만 업데이트하고 나머지는 유지하는 selective update를 가능하게 함
guix describe와 guix time-machine
Guix는 guix pull 실행 시 모든 channels의 정확한 commits를 기록하며, guix describe가 이 정보를 보여줌
guix describe 출력은 generation 번호, 날짜, current 표시, channel 이름, repository URL, branch, commit을 포함함
Guix의 recorded channel commits는 lock file에 해당하지만, project directory의 파일이 아니라 ~/.config/guix/current에 Guile profile로 존재함
재현 가능한 환경을 공유하려면 Guix에서 guix time-machine 을 사용할 수 있음
guix time-machine --commit=8a1ab328 -- shell -m manifest.scm은 Guix 자체를 특정 revision으로 pinning한 뒤 그 revision의 package definitions를 사용해 guix shell을 실행함
guix time-machine은 필요한 경우 해당 revision을 download하고 compile하며, package definitions가 정확히 해당 commit 상태인 isolated environment를 생성함
프로젝트 repository에 pinned commits를 가진 channels.scm을 check in하는 Guix 패턴도 있음
guix time-machine -C channels.scm -- shell -m manifest.scm은 repository에 포함된 channels.scm을 사용해 exact environment를 재현함
두 방식의 차이
flake.lock은 per-project이면서 automatic이고, guix describe는 per-user이면서 automatic임
Pinned commits가 들어간 channels.scm은 Guix에서 per-project pinning을 제공하지만 manual 방식임
Guix는 per-project pinning ergonomics를 개선 중이지만, 현재 workflow는 더 explicit setup이 필요함
flake.lock은 machine-readable JSON graph이고, Guix의 대응물은 commit hashes를 가진 channels를 나열한 Scheme file임
두 방식 모두 dependency pinning 목표를 달성하지만, flake lock은 모든 transitive input에 original과 locked entries를 가진 full dependency graph라 더 structured함
guix time-machine은 direct flake equivalent가 없는 기능이며, pinned dependency versions뿐 아니라 package collection의 완전히 다른 historical state로 이동할 수 있음
순수성 모델
Flakes는 restricted evaluation context에서 실행되며, builtins.currentSystem, builtins.getEnv, $NIX_PATH 사용이 금지되거나 무시됨
Flakes에서 모든 것은 declared inputs에서 와야 하며, implicit state에 accidental dependency가 생기기 어렵게 함
Flakes의 pure evaluation trade-off는 system detection을 위해 명시적 system parameters가 곳곳에 필요하고, environment variables 읽기가 불가능하다는 점임
Flakes에서 impure escape hatch가 필요할 때는 --impure를 명시적으로 전달해야 함
Guix는 별도 pure evaluation mode가 필요 없으며, evaluation이 convention상 이미 pure함
Guile modules는 environment variables에 명시적으로 전달하지 않는 한 접근하지 않음
Guix에는 $NIX_PATH에 해당하는 것이 없으며, packages를 search path가 아니라 module system을 통해 resolve함
Guix에는 builtins.currentSystem에 해당하는 개념이 없고, systems는 package metadata와 --system flag로 명시함
Guix의 build도 pure하며, builds는 explicitly declared inputs만 보이는 isolated containers에서 실행됨
Guix builds에서는 /usr/bin, /etc, network access가 없으며, network access 예외는 fixed-output derivations에 한정됨
Build sandboxing 방식은 Nix와 Guix가 본질적으로 같은 접근을 공유함
Guix는 Scheme modules 구조를 통해 architecture 차원에서 purity를 달성하고, Flakes는 원래 impure한 system 위에 restricted evaluation mode를 얹어 purity를 강제함
출력 스키마와 데이터 모델
Flake output schema
Flakes는 outputs에 대한 standard schema를 정의하며, packages.<system>.<name>은 nix build, devShells.<system>.<name>은 nix develop, apps.<system>.<name>은 nix run에서 사용됨
Flake output schema에는 nixosConfigurations.<name>, overlays.<name>, nixosModules.<name>, formatter.<system>, templates.<name>, checks.<system>.<name>도 있음
Flake output schema의 standardization은 nix build ., nix run, nix flake show가 일관된 위치를 참조하게 해 discoverability를 높임
Flake output schema의 단점은 rigid하다는 점이며, 임의 output types를 추가하려면 Nix 자체 수정이 필요하지만 작은 extension mechanism은 존재함
Flake의 <system> parameter 때문에 multi-platform support를 explicit하게 처리해야 하며, forAllSystems, flake-utils, flake-parts 같은 helper functions 또는 libraries가 사용됨
Guix의 first-class data types
Guix에는 Flakes처럼 단일 output schema가 없고, 여러 command가 소비할 수 있는 first-class data types가 있음
Guix에서 packages는 <package> records로 정의되고 guix install, guix build가 사용함
Guix에서 manifests는 Scheme files로 정의되고 guix shell -m, guix package가 사용함
Guix에서 system configs는 operating-system으로 정의되고 guix system reconfigure가 사용함
Guix에서 home configs는 home-environment로 정의되고 guix home reconfigure가 사용함
Guix에서 services는 <service> records로 정의되고 operating-system의 services field가 사용함
Guix에서 channels는 Git repos이며 guix pull이 사용함
Guix에서 package variants는 Scheme procedures이며 --with-input, --transform이 사용함
파일과 패키지 정의
Guix project는 package definitions가 있는 channel, development용 manifest.scm, deployment용 system.scm, operating-system 또는 home-environment declaration 등을 조합해 제공할 수 있음
Guix에서는 이런 파일들이 special entry point file을 요구하지 않으며, Scheme values를 정의하는 Scheme files일 뿐임
Guix에서는 관련 guix subcommand에 파일을 지정하면 command가 처리하며, 별도 ceremony나 schema validation이 필요 없음
예시 manifest.scm은 specifications->manifest에 "guile", "guile-git", "guile-json" package names list를 넘겨 development environment를 선언함
예시 mylib.scm은 Guix의 Nix derivation 대응물인 <package> record를 정의하며, package fields를 programmatically query할 수 있음
예시 package definition은 (name "mylib"), (version "0.1.0"), (source (local-file ".")), (build-system gnu-build-system), (inputs (list guile guile-git)), (home-page "https://example.com" ;), (license gpl3+)를 가짐
Guix의 local-file은 build time에 current directory의 files를 가져오며, Nix의 src = ./.;와 유사함
Guix의 gnu-build-system은 ./configure && make && make install 방식이며, Guix에는 cmake-build-system, python-build-system 등 다른 build systems도 있음
Guix는 Nix에서 stdenv가 gcc와 coreutils를 implicit하게 제공하는 것과 달리 dependencies를 모두 explicit하게 둠
개발 환경
Flakes의 devShells 예시에서는 devShells.x86_64-linux.default = pkgs.mkShell { buildInputs = with pkgs; [ go gopls gotools ]; shellHook = '' echo "Welcome to the devShell!" ''; };를 사용함
mkShell은 build될 때 shell environment를 만드는 derivation을 생성하며, buildInputs는 shell 안의 PATH에 들어가고 shellHook은 shell 진입 시 arbitrary bash를 실행함
Flake dev shell에는 nix develop 또는 named shell용 nix develop .#my-shell로 진입함
Guix development environment는 manifest.scm에서 specifications->manifest에 package specification strings list를 넘겨 정의할 수 있음
예시 Guix manifest는 "go", "gopls", "go-tools"를 선언함
Guix manifest 기반 shell에는 guix shell -m manifest.scm으로 진입함
Guix는 ad-hoc environment에서 파일 없이 guix shell go gopls go-tools처럼 command line package names만 전달할 수 있음
guix shell은 full isolation을 위한 --container, standard Linux filesystem layout을 기대하는 프로그램 실행용 --emulate-fhs, Guix container 안에서 Guix를 실행하는 --nesting을 지원함
Guix manifests는 더 큰 flake.nix 구조에 embedded되지 않은 standalone Scheme files임
guix shell은 파일 없이도 동작할 수 있지만, nix develop은 flake 또는 legacy interface의 shell.nix가 필요함
Flakes는 devShells.x86_64-linux.test, devShells.x86_64-linux.default 같은 named dev shells를 제공함
Guix manifests는 named dev shells 대신 manifest.scm, test-manifest.scm 같은 별도 파일을 나란히 두는 방식임
Nix Flakes와 Guix 모두 containerized development를 지원함
시스템 구성
NixOS와 Flakes
Flakes의 nixosConfigurations 예시에서는 nixpkgs.lib.nixosSystem이 NixOS modules list를 받아 kernel, services, config files 등을 포함한 full system derivation을 생성함
Flake 기반 NixOS 배포 예시 명령은 nixos-rebuild switch --flake .#myhost임
예시 nixosConfigurations.myhost는 system = "x86_64-linux";와 modules = [ ./configuration.nix home-manager.nixosModules.home-manager ];를 포함함
NixOS modules는 options, config, mkIf, mkDefault, mkForce를 통한 priority-based merging을 사용하는 module system임
NixOS 모듈 시스템은 여러 모듈이 같은 옵션을 설정해도 시스템이 우선순위를 해소하며, 수십 개 모듈이 같은 구성에 기여해도 충돌을 피하기 쉬움
Guix operating-system
Guix의 operating-system은 function이 아니라 Scheme record이며, 각 field는 named typed value로 Guix가 validate함
Guix system 배포 예시 명령은 guix system reconfigure config.scm임
예시 operating-system record는 (host-name "myhost"), (timezone "Etc/UTC"), bootloader configuration, file systems, services를 포함함
Guix bootloader configuration 예시는 grub-efi-bootloader와 target "/boot/efi"를 사용하며, Guix는 GRUB, U-Boot 등을 지원함
Guix file systems는 list로 선언되며, %base-file-systems는 /dev, /proc, /sys 등에 대한 defaults를 제공함
Guix services는 directed acyclic graph(DAG)를 이루며, 각 service는 다른 services를 extend할 수 있음
%base-services는 Shepherd init system, syslog, networking 등 필수 services를 제공함
Guix system configuration에는 special output type이 필요 없고, operating-system record를 반환하는 파일을 guix system에 지정하면 됨
Guix의 서비스 조합은 기존 시스템에 임의의 방식으로 연결되는 새 서비스를 작성하기 쉽게 만듦
탐색성과 레지스트리
Flakes에는 프로젝트 의존성, 출력, 발견 가능한 스키마를 한 파일에서 선언하는 표준 진입점 flake.nix가 있음
Guix 프로젝트는 manifest.scm, channels.scm, guix.scm, package.scm 등 관례 기반 파일을 사용할 수 있음
guix shell이 자동으로 인식하는 프로젝트 파일로 guix.scm를 표준화하려는 움직임이 있지만, flake.nix만큼 확립되지는 않았음
Flakes에는 짧은 이름을 URL에 매핑하는 전역 레지스트리 flake-registry 가 있으며, 예시는 nix run nixpkgs#hello, nix build github:NixOS/nixpkgs#firefox임
Guix는 비슷한 편의성을 위해 패키지 명세를 사용하며, 예시는 guix shell hello, guix install firefox임
Guix에는 임의의 Git 저장소를 짧은 이름으로 가리키는 레지스트리 대응물이 없고 URL을 직접 사용함
Nix 레지스트리는 nixpkgs가 레지스트리 항목인지, 로컬 경로인지, 다른 대상인지 항상 명확하지 않아 혼란의 원천이 된 적이 있음
nix flake show는 flake가 제공하는 모든 항목을 트리 뷰로 보여주는 명령임
Guix에는 패키지용 guix search와 서비스용 guix system search가 있지만, 특정 프로젝트나 저장소가 제공하는 모든 항목을 보여주는 대응 명령은 없으며 Scheme 파일을 직접 확인해야 함
Flakes는 nix flake show가 project가 제공하는 것들을 consistent view로 보여준다는 점에서 discoverability가 강함
Guix projects는 더 ad-hoc하며, 어떤 파일을 봐야 하는지 알아야 하고 standard single-entry-point file이 없음
Guix는 모든 것이 Scheme이기 때문에 schema 없이 원하는 것을 정의하고 조합할 수 있어 flexibility가 강함
패키지 모델과 그래프 재작성
Nix에서 패키지는 stdenv.mkDerivation { ... } 호출로 derivation을 반환하는 함수이며, 그 결과는 불투명한 attribute set임
Guix에서 패키지는 <package> 레코드이며, 이름이 붙은 필드를 가진 투명한 데이터 구조라 표준 Scheme 절차로 검사, 변환, 조합할 수 있음
Guix package definitions는 opaque functions가 아니라 transparent records이므로 special tooling 없이 inspect와 transform을 programmatically 수행할 수 있음
Guix에서는 packages가 data이므로 graph rewrites를 쉽게 수행할 수 있음
Guix에서는 package-input-rewriting으로 전체 의존성 그래프를 순회해 perl을 perl-minimal로 바꾸는 작업을 표현할 수 있음
Guix의 inherit 키워드는 coreutils의 모든 필드를 물려받고 지정한 필드만 덮어쓰는 방식으로 패키지를 재정의함
Nix에는 비슷한 목적의 overlays가 있지만, 불투명한 함수 인터페이스 때문에 검사와 변환이 더 어려워 사용성이 떨어짐
보안 업데이트, 부트스트랩, 인증
Guix의 grafting 은 모든 의존 패키지를 다시 빌드하지 않고 의존성 트리에 보안 업데이트를 적용할 수 있게 함
glibc 같은 저수준 라이브러리에 취약점이 있을 때 Guix는 저장소 경로를 다시 작성해 수정 버전으로 교체할 수 있음
Nix는 보안 업데이트 상황에서 모든 것을 다시 빌드하며, 큰 의존성 트리에서는 빌드 시간이 몇 시간 차이 날 수 있음
Guix는 소스 기반 부트스트래핑 에 강하게 집중하며, 전체 시스템을 작은 신뢰 기반에서 빌드할 수 있음
Guix의 부트스트랩 체인은 약 500바이트 hex assembler에서 시작해 Scheme으로 작성된 mes C 컴파일러, tcc, 전체 GNU toolchain으로 이어짐
bootstrappable builds 프로젝트는 전체 소스 부트스트랩 세부 사항을 다룸
Nix는 Guix보다 더 많은 바이너리 시드에 의존함
부트스트랩 체인을 감사할 수 없으면 시스템이 실제로 의도한 소스에서 빌드됐는지 완전히 검증할 수 없으므로, 전체 소스 부트스트래핑은 신뢰와 검증 가능성에 중요함
Guix channels는 암호학적 인증 을 기본 지원함
Guix channel은 특정 커밋과 그 Ed25519 서명으로 구성된 “introduction”을 지정하며, Guix는 해당 introduction부터 현재 커밋까지 전체 서명 체인을 검증함
Flakes는 신뢰 모델로 HTTPS와 GitHub 인프라를 사용하며, 이는 Guix의 Ed25519 channel authentication과 다른 보안 모델임
요약 표의 핵심 대응 관계
의존성 선언은 Flakes가 flake.nix의 inputs, Guix가 channels.scm과 .guix-channel을 사용함
의존성 고정은 Flakes가 자동·프로젝트별 flake.lock을 사용하고, Guix가 사용자별 자동 guix describe와 프로젝트별 수동 커밋 지정 channels.scm을 사용함
순수 평가는 flake mode에서 강제되고, Guix에서는 설계상 내재된 특성임
출력 스키마는 Flakes가 outputs의 구조화된 attrset을 쓰고, Guix가 ad-hoc Scheme records를 씀
개발 환경은 Flakes가 devShells와 nix develop, Guix가 manifest.scm와 guix shell을 씀
시스템 구성은 Flakes가 nixosConfigurations와 모듈 시스템, Guix가 operating-system과 서비스 DAG를 씀
한 명령 재현성은 Flakes가 nix build github:foo/bar, Guix가 guix time-machine -C channels.scm -- build 형태임
프로젝트별 고정은 Flakes가 flake.lock으로 자동 처리하고, Guix가 커밋이 들어간 channels.scm으로 수동 처리함
탐색성은 Flakes가 nix flake show, Guix가 Scheme 모듈 검사에 의존함
패키지 모델은 Flakes/Nix가 불투명 함수, Guix가 투명 레코드임
init system은 Nix가 systemd, Guix가 GNU Shepherd를 사용함
보안 업데이트는 Nix가 전체 재빌드, Guix가 빠른 grafting을 사용함
부트스트랩 신뢰는 Nix가 바이너리 시드, Guix가 전체 소스 부트스트랩에 기반함
인증된 업데이트는 Flakes가 HTTPS/GitHub 신뢰, Guix가 Ed25519 channel authentication을 사용함
FHS 지원은 Nix가 buildFHSUserEnv, Guix가 --emulate-fhs를 제공함
비 Linux 지원은 Nix가 macOS용 nix-darwin, Guix가 GNU Hurd로 정리됨
자유 소프트웨어 전용 여부는 Nix가 전용이 아니며 구성 가능하고, Guix는 FSDG를 준수함
결론
Flakes와 Guix는 재현성, 의존성 관리, 시스템 선언이라는 같은 종류의 문제를 서로 다른 아키텍처 철학으로 해결함
Flakes는 하나의 파일, 하나의 스키마, 하나의 잠금 파일, 하나의 관례 집합을 갖춘 단일 기능에 가까움
Guix는 배포용 channels, 환경용 manifests, 구성용 operating-system, 재현성용 guix time-machine, 기타 구조를 위한 Scheme records 같은 직교 도구들의 조합임
하나의 표준 방식, 하나의 진입점 파일, 하나의 출력 스키마, 하나의 잠금 형식을 선호하면 Flakes가 자연스럽게 맞음
작고 독립적인 도구를 조합해 각 도구가 한 가지를 잘하게 하는 Unix 철학을 패키지 관리에 적용하는 방식을 선호하면 Guix가 잘 맞음
두 생태계는 패키지 관리가 함수형, 선언적, 재현 가능해야 한다는 아이디어를 중심으로 발전했으며, 서로 다른 구현으로 같은 아이디어를 밀어붙이고 있음
Homepage
Tech blog
Nix Flakes와 그에 대응하는 Guix 기능들
🔉 볼륨 줄이기
🔊 볼륨 키우기
🔇 음소거
⏭️ 다음 곡