Merge branch 'master' into add-newer-xcode-hashes

This commit is contained in:
Steven Pease 2021-01-19 20:42:30 -08:00
commit 0fdab8d560
15260 changed files with 305844 additions and 169000 deletions

View File

@ -47,9 +47,10 @@ indent_style = space
insert_final_newline = unset
trim_trailing_whitespace = unset
[*.{key,ovpn}]
[*.{asc,key,ovpn}]
insert_final_newline = unset
end_of_line = unset
trim_trailing_whitespace = unset
[*.lock]
indent_size = unset
@ -62,12 +63,7 @@ insert_final_newline = unset
[eggs.nix]
trim_trailing_whitespace = unset
[gemset.nix]
insert_final_newline = unset
[node-{composition,packages}.nix]
insert_final_newline = unset
[node-packages-generated.nix]
[gemset*.nix]
insert_final_newline = unset
[nixos/modules/services/networking/ircd-hybrid/*.{conf,in}]
@ -76,37 +72,28 @@ trim_trailing_whitespace = unset
[nixos/tests/systemd-networkd-vrf.nix]
trim_trailing_whitespace = unset
[pkgs/applications/editors/emacs-modes/recipes-archive-melpa.json]
indent_size = unset
[pkgs/build-support/dotnetenv/Wrapper/**]
end_of_line = unset
indent_style = unset
insert_final_newline = unset
trim_trailing_whitespace = unset
[pkgs/build-support/upstream-updater/**]
indent_style = unset
trim_trailing_whitespace = unset
[pkgs/development/compilers/elm/registry.dat]
end_of_line = unset
insert_final_newline = unset
[pkgs/development/lisp-modules/quicklisp-to-nix.nix]
indent_size = unset
[pkgs/development/haskell-modules/hackage-packages.nix]
indent_style = unset
indent_size = unset
trim_trailing_whitespace = unset
[pkgs/development/mobile/androidenv/generated/{addons,packages}.nix]
trim_trailing_whitespace = unset
[pkgs/development/node-packages/composition.nix]
insert_final_newline = unset
[pkgs/development/{perl-modules,ocaml-modules,tools/ocaml}/**]
indent_style = unset
[pkgs/servers/dict/wordnet_structures.py]
indent_size = unset
trim_trailing_whitespace = unset
[pkgs/tools/misc/timidity/timidity.cfg]
@ -118,6 +105,3 @@ trim_trailing_whitespace = unset
[pkgs/top-level/emscripten-packages.nix]
trim_trailing_whitespace = unset
[pkgs/top-level/perl-packages.nix]
indent_size = unset

47
.github/CODEOWNERS vendored
View File

@ -12,6 +12,7 @@
# GitHub actions
/.github/workflows @Mic92 @zowoq
/.github/workflows/merge-staging @FRidh
# EditorConfig
/.editorconfig @Mic92 @zowoq
@ -25,17 +26,18 @@
/lib/asserts.nix @edolstra @nbp @Profpatsch
# Nixpkgs Internals
/default.nix @nbp
/pkgs/top-level/default.nix @nbp @Ericson2314
/pkgs/top-level/impure.nix @nbp @Ericson2314
/pkgs/top-level/stage.nix @nbp @Ericson2314 @matthewbauer
/pkgs/top-level/splice.nix @Ericson2314 @matthewbauer
/pkgs/top-level/release-cross.nix @Ericson2314 @matthewbauer
/pkgs/stdenv/generic @Ericson2314 @matthewbauer
/pkgs/stdenv/cross @Ericson2314 @matthewbauer
/pkgs/build-support/cc-wrapper @Ericson2314 @orivej
/pkgs/build-support/bintools-wrapper @Ericson2314 @orivej
/pkgs/build-support/setup-hooks @Ericson2314
/default.nix @nbp
/pkgs/top-level/default.nix @nbp @Ericson2314
/pkgs/top-level/impure.nix @nbp @Ericson2314
/pkgs/top-level/stage.nix @nbp @Ericson2314 @matthewbauer
/pkgs/top-level/splice.nix @Ericson2314 @matthewbauer
/pkgs/top-level/release-cross.nix @Ericson2314 @matthewbauer
/pkgs/stdenv/generic @Ericson2314 @matthewbauer
/pkgs/stdenv/cross @Ericson2314 @matthewbauer
/pkgs/build-support/cc-wrapper @Ericson2314 @orivej
/pkgs/build-support/bintools-wrapper @Ericson2314 @orivej
/pkgs/build-support/setup-hooks @Ericson2314
/pkgs/build-support/setup-hooks/auto-patchelf.sh @aszlig
# Nixpkgs build-support
/pkgs/build-support/writers @lassulus @Profpatsch
@ -96,8 +98,8 @@
/pkgs/development/ruby-modules @alyssais
# Rust
/pkgs/development/compilers/rust @Mic92 @LnL7
/pkgs/build-support/rust @andir
/pkgs/development/compilers/rust @Mic92 @LnL7 @zowoq
/pkgs/build-support/rust @andir @zowoq
# Darwin-related
/pkgs/stdenv/darwin @NixOS/darwin-maintainers
@ -156,8 +158,8 @@
/nixos/modules/services/networking/ntp @thoughtpolice
# Dhall
/pkgs/development/dhall-modules @Gabriel439 @Profpatsch
/pkgs/development/interpreters/dhall @Gabriel439 @Profpatsch
/pkgs/development/dhall-modules @Gabriel439 @Profpatsch @ehmry
/pkgs/development/interpreters/dhall @Gabriel439 @Profpatsch @ehmry
# Idris
/pkgs/development/idris-modules @Infinisil
@ -176,6 +178,10 @@
/pkgs/applications/editors/emacs @adisbladis
/pkgs/top-level/emacs-packages.nix @adisbladis
# Neovim
/pkgs/applications/editors/neovim @jonringer
/pkgs/applications/editors/neovim @teto
# VimPlugins
/pkgs/misc/vim-plugins @jonringer @softinio
@ -202,10 +208,19 @@
/nixos/tests/cri-o.nix @NixOS/podman @zowoq
/nixos/tests/podman.nix @NixOS/podman @zowoq
# Docker tools
/pkgs/build-support/docker @roberth @utdemir
/nixos/tests/docker-tools-overlay.nix @roberth
/nixos/tests/docker-tools.nix @roberth
/doc/builders/images/dockertools.xml @roberth
# Blockchains
/pkgs/applications/blockchains @mmahut
/pkgs/applications/blockchains @mmahut @RaghavSood
# Go
/pkgs/development/compilers/go @kalbasit @Mic92 @zowoq
/pkgs/development/go-modules @kalbasit @Mic92 @zowoq
/pkgs/development/go-packages @kalbasit @Mic92 @zowoq
# Cinnamon
/pkgs/desktops/cinnamon @mkg20001

View File

@ -53,10 +53,11 @@ For package version upgrades and such a one-line commit message is usually suffi
Follow these steps to backport a change into a release branch in compliance with the [commit policy](https://nixos.org/nixpkgs/manual/#submitting-changes-stable-release-branches).
1. Take note of the commits in which the change was introduced into `master` branch.
2. Check out the target _release branch_, e.g. `release-20.03`. Do not use a _channel branch_ like `nixos-20.03` or `nixpkgs-20.03`.
2. Check out the target _release branch_, e.g. `release-20.09`. Do not use a _channel branch_ like `nixos-20.09` or `nixpkgs-20.09`.
3. Create a branch for your change, e.g. `git checkout -b backport`.
4. When the reason to backport is not obvious from the original commit message, use `git cherry-pick -xe <original commit>` and add a reason. Otherwise use `git cherry-pick -x <original commit>`. That's fine for minor version updates that only include security and bug fixes, commits that fixes an otherwise broken package or similar. Please also ensure the commits exists on the master branch; in the case of squashed or rebased merges, the commit hash will change and the new commits can be found in the merge message at the bottom of the master pull request.
5. Push to GitHub and open a backport pull request. Make sure to select the release branch (e.g. `release-20.03`) as the target branch of the pull request, and link to the pull request in which the original change was comitted to `master`. The pull request title should be the commit title with the release version as prefix, e.g. `[20.03]`.
5. Push to GitHub and open a backport pull request. Make sure to select the release branch (e.g. `release-20.09`) as the target branch of the pull request, and link to the pull request in which the original change was comitted to `master`. The pull request title should be the commit title with the release version as prefix, e.g. `[20.09]`.
6. When the backport pull request is merged and you have the necessary privileges you can also replace the label `9.needs: port to stable` with `8.has: port to stable` on the original pull request. This way maintainers can keep track of missing backports easier.
## Reviewing contributions

View File

@ -0,0 +1,48 @@
---
name: Out-of-date package reports
about: For packages that are out-of-date
title: ''
labels: '9.needs: package (update)'
assignees: ''
---
###### Checklist
<!-- Note that these are hard requirements -->
<!--
You can use the "Go to file" functionality on github to find the package
Then you can go to the history for this package
Find the latest "package_name: old_version -> new_version" commit
The "new_version" is the the current version of the package
-->
- [ ] Checked the [nixpkgs master branch](https://github.com/NixOS/nixpkgs)
<!--
Type the name of your package and try to find an open pull request for the package
If you find an open pull request, you can review it!
There's a high chance that you'll have the new version right away while helping the community!
-->
- [ ] Checked the [nixpkgs pull requests](https://github.com/NixOS/nixpkgs/pulls)
###### Project name
`nix search` name:
<!--
The current version can be found easily with the same process than above for checking the master branch
If an open PR is present for the package, take this version as the current one and link to the PR
-->
current version:
desired version:
###### Notify maintainers
<!--
Search your package here: https://search.nixos.org/packages?channel=unstable
If no maintainer is listed for your package, tag the person that last updated the package
-->
maintainers:
###### Note for maintainers
Please tag this issue in your PR.

View File

@ -5,7 +5,7 @@ comment describing what you have tested in the relevant package/service.
Reviewing helps to reduce the average time-to-merge for everyone.
Thanks a lot if you do!
List of open PRs: https://github.com/NixOS/nixpkgs/pulls
Reviewing guidelines: https://hydra.nixos.org/job/nixpkgs/trunk/manual/latest/download/1/nixpkgs/manual.html#chap-reviewing-contributions
Reviewing guidelines: https://nixos.org/manual/nixpkgs/unstable/#chap-reviewing-contributions
-->
###### Motivation for this change

35
.github/STALE-BOT.md vendored Normal file
View File

@ -0,0 +1,35 @@
# Stale bot information
- Thanks for your contribution!
- To remove the stale label, just leave a new comment.
- _How to find the right people to ping?_ &rarr; [`git blame`](https://git-scm.com/docs/git-blame) to the rescue! (or GitHub's history and blame buttons.)
- You can always ask for help on [our Discourse Forum](https://discourse.nixos.org/) or on the [#nixos IRC channel](https://webchat.freenode.net/#nixos).
## Suggestions for PRs
1. GitHub sometimes doesn't notify people who commented / reviewed a PR previously, when you (force) push commits. If you have addressed the reviews you can [officially ask for a review](https://docs.github.com/en/free-pro-team@latest/github/collaborating-with-issues-and-pull-requests/requesting-a-pull-request-review) from those who commented to you or anyone else.
2. If it is unfinished but you plan to finish it, please mark it as a draft.
3. If you don't expect to work on it any time soon, closing it with a short comment may encourage someone else to pick up your work.
4. To get things rolling again, rebase the PR against the target branch and address valid comments.
5. If you need a review to move forward, ask in [the Discourse thread for PRs that need help](https://discourse.nixos.org/t/prs-in-distress/3604).
6. If all you need is a merge, check the git history to find and [request reviews](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/requesting-a-pull-request-review) from people who usually merge related contributions.
## Suggestions for issues
1. If it is resolved (either for you personally, or in general), please consider closing it.
2. If this might still be an issue, but you are not interested in promoting its resolution, please consider closing it while encouraging others to take over and reopen an issue if they care enough.
3. If you still have interest in resolving it, try to ping somebody who you believe might have an interest in the topic. Consider discussing the problem in [our Discourse Forum](https://discourse.nixos.org/).
4. As with all open source projects, your best option is to submit a Pull Request that addresses this issue. We :heart: this attitude!
**Memorandum on closing issues**
Don't be afraid to close an issue that holds valuable information. Closed issues stay in the system for people to search, read, cross-reference, or even reopen--nothing is lost! Closing obsolete issues is an important way to help maintainers focus their time and effort.
## Useful GitHub search queries
- [Open PRs with any stale-bot interaction](https://github.com/NixOS/nixpkgs/pulls?q=is%3Apr+is%3Aopen+commenter%3Aapp%2Fstale+)
- [Open PRs with any stale-bot interaction and `2.status: stale`](https://github.com/NixOS/nixpkgs/pulls?q=is%3Apr+is%3Aopen+commenter%3Aapp%2Fstale+label%3A%222.status%3A+stale%22)
- [Open PRs with any stale-bot interaction and NOT `2.status: stale`](https://github.com/NixOS/nixpkgs/pulls?q=is%3Apr+is%3Aopen+commenter%3Aapp%2Fstale+-label%3A%222.status%3A+stale%22+)
- [Open Issues with any stale-bot interaction](https://github.com/NixOS/nixpkgs/issues?q=is%3Aissue+is%3Aopen+commenter%3Aapp%2Fstale+)
- [Open Issues with any stale-bot interaction and `2.status: stale`](https://github.com/NixOS/nixpkgs/issues?q=is%3Aissue+is%3Aopen+commenter%3Aapp%2Fstale+label%3A%222.status%3A+stale%22+)
- [Open Issues with any stale-bot interaction and NOT `2.status: stale`](https://github.com/NixOS/nixpkgs/issues?q=is%3Aissue+is%3Aopen+commenter%3Aapp%2Fstale+-label%3A%222.status%3A+stale%22+)

37
.github/stale.yml vendored
View File

@ -1,41 +1,10 @@
# Configuration for probot-stale - https://github.com/probot/stale
# Number of days of inactivity before an issue becomes stale
daysUntilStale: 180
# Number of days of inactivity before a stale issue is closed
daysUntilClose: false
# Issues with these labels will never be considered stale
exemptLabels:
- "1.severity: security"
# Label to use when marking an issue as stale
- "2.status: never-stale"
staleLabel: "2.status: stale"
# Comment to post when marking an issue as stale. Set to `false` to disable
pulls:
markComment: |
Hello, I'm a bot and I thank you in the name of the community for your contributions.
Nixpkgs is a busy repository, and unfortunately sometimes PRs get left behind for too long. Nevertheless, we'd like to help committers reach the PRs that are still important. This PR has had no activity for 180 days, and so I marked it as stale, but you can rest assured it will never be closed by a non-human.
If this is still important to you and you'd like to remove the stale label, we ask that you leave a comment. Your comment can be as simple as "still important to me". But there's a bit more you can do:
If you received an approval by an unprivileged maintainer and you are just waiting for a merge, you can @ mention someone with merge permissions and ask them to help. You might be able to find someone relevant by using [Git blame](https://git-scm.com/docs/git-blame) on the relevant files, or via [GitHub's web interface](https://docs.github.com/en/github/managing-files-in-a-repository/tracking-changes-in-a-file). You can see if someone's a member of the [nixpkgs-committers](https://github.com/orgs/NixOS/teams/nixpkgs-committers) team, by hovering with the mouse over their username on the web interface, or by searching them directly on [the list](https://github.com/orgs/NixOS/teams/nixpkgs-committers).
If your PR wasn't reviewed at all, it might help to find someone who's perhaps a user of the package or module you are changing, or alternatively, ask once more for a review by the maintainer of the package/module this is about. If you don't know any, you can use [Git blame](https://git-scm.com/docs/git-blame) on the relevant files, or [GitHub's web interface](https://docs.github.com/en/github/managing-files-in-a-repository/tracking-changes-in-a-file) to find someone who touched the relevant files in the past.
If your PR has had reviews and nevertheless got stale, make sure you've responded to all of the reviewer's requests / questions. Usually when PR authors show responsibility and dedication, reviewers (privileged or not) show dedication as well. If you've pushed a change, it's possible the reviewer wasn't notified about your push via email, so you can always [officially request them for a review](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/requesting-a-pull-request-review), or just @ mention them and say you've addressed their comments.
Lastly, you can always ask for help at [our Discourse Forum](https://discourse.nixos.org/), or more specifically, [at this thread](https://discourse.nixos.org/t/prs-in-distress/3604) or at [#nixos' IRC channel](https://webchat.freenode.net/#nixos).
issues:
markComment: |
Hello, I'm a bot and I thank you in the name of the community for opening this issue.
To help our human contributors focus on the most-relevant reports, I check up on old issues to see if they're still relevant. This issue has had no activity for 180 days, and so I marked it as stale, but you can rest assured it will never be closed by a non-human.
The community would appreciate your effort in checking if the issue is still valid. If it isn't, please close it.
If the issue persists, and you'd like to remove the stale label, you simply need to leave a comment. Your comment can be as simple as "still important to me". If you'd like it to get more attention, you can ask for help by searching for maintainers and people that previously touched related code and @ mention them in a comment. You can use [Git blame](https://git-scm.com/docs/git-blame) or [GitHub's web interface](https://docs.github.com/en/github/managing-files-in-a-repository/tracking-changes-in-a-file) on the relevant files to find them.
Lastly, you can always ask for help at [our Discourse Forum](https://discourse.nixos.org/) or at [#nixos' IRC channel](https://webchat.freenode.net/#nixos).
# Comment to post when closing a stale issue. Set to `false` to disable
markComment: |
I marked this as stale due to inactivity. &rarr; [More info](https://github.com/NixOS/nixpkgs/blob/master/.github/STALE-BOT.md)
closeComment: false

View File

@ -2,26 +2,36 @@ name: "Checking EditorConfig"
on:
pull_request:
branches-ignore:
- 'release-**'
jobs:
tests:
runs-on: ubuntu-latest
if: github.repository_owner == 'NixOS'
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- uses: technote-space/get-diff-action@v4.0.0
- name: Fetch editorconfig-checker
if: env.GIT_DIFF
- name: Get list of changed files from PR
env:
ECC_VERSION: "2.1.0"
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
echo 'PR_DIFF<<EOF' >> $GITHUB_ENV
gh api \
repos/NixOS/nixpkgs/pulls/${{github.event.number}}/files --paginate \
| jq '.[] | select(.status != "removed") | .filename' \
>> $GITHUB_ENV
echo 'EOF' >> $GITHUB_ENV
- uses: actions/checkout@v2
if: env.PR_DIFF
- name: Fetch editorconfig-checker
if: env.PR_DIFF
env:
ECC_VERSION: "2.3.1"
ECC_URL: "https://github.com/editorconfig-checker/editorconfig-checker/releases/download"
run: |
curl -sSf -O -L -C - "$ECC_URL/$ECC_VERSION/ec-linux-amd64.tar.gz" && \
tar xzf ec-linux-amd64.tar.gz && \
mv ./bin/ec-linux-amd64 ./bin/editorconfig-checker
- name: Checking EditorConfig
if: env.GIT_DIFF
if: env.PR_DIFF
run: |
./bin/editorconfig-checker -disable-indentation \
${{ env.GIT_DIFF }}
echo "$PR_DIFF" | xargs ./bin/editorconfig-checker -disable-indent-size

28
.github/workflows/manual-nixos.yml vendored Normal file
View File

@ -0,0 +1,28 @@
name: "Build NixOS manual"
on:
pull_request_target:
branches:
- master
paths:
- 'nixos/**'
jobs:
nixos:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
# pull_request_target checks out the base branch by default
ref: refs/pull/${{ github.event.pull_request.number }}/merge
- uses: cachix/install-nix-action@v12
with:
# explicitly enable sandbox
extra_nix_config: sandbox = true
- uses: cachix/cachix-action@v8
with:
# This cache is for the nixos/nixpkgs manual builds and should not be trusted or used elsewhere.
name: nixpkgs-ci
signingKey: '${{ secrets.CACHIX_SIGNING_KEY }}'
- name: Building NixOS manual
run: NIX_PATH=nixpkgs=$(pwd) nix-build --option restrict-eval true nixos/release.nix -A manual.x86_64-linux

28
.github/workflows/manual-nixpkgs.yml vendored Normal file
View File

@ -0,0 +1,28 @@
name: "Build Nixpkgs manual"
on:
pull_request_target:
branches:
- master
paths:
- 'doc/**'
jobs:
nixpkgs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
# pull_request_target checks out the base branch by default
ref: refs/pull/${{ github.event.pull_request.number }}/merge
- uses: cachix/install-nix-action@v12
with:
# explicitly enable sandbox
extra_nix_config: sandbox = true
- uses: cachix/cachix-action@v8
with:
# This cache is for the nixos/nixpkgs manual builds and should not be trusted or used elsewhere.
name: nixpkgs-ci
signingKey: '${{ secrets.CACHIX_SIGNING_KEY }}'
- name: Building Nixpkgs manual
run: NIX_PATH=nixpkgs=$(pwd) nix-build --option restrict-eval true pkgs/top-level/release.nix -A manual

39
.github/workflows/merge-staging.yml vendored Normal file
View File

@ -0,0 +1,39 @@
name: "merge staging(-next)"
on:
schedule:
# * is a special character in YAML so you have to quote this string
# Merge every 6 hours
- cron: '0 */6 * * *'
jobs:
sync-branch:
if: github.repository == 'NixOS/nixpkgs'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Merge master into staging-next
uses: devmasx/merge-branch@v1.3.1
with:
type: now
from_branch: master
target_branch: staging-next
github_token: ${{ secrets.GITHUB_TOKEN }}
- name: Merge staging-next into staging
uses: devmasx/merge-branch@v1.3.1
with:
type: now
from_branch: staging-next
target_branch: staging
github_token: ${{ secrets.GITHUB_TOKEN }}
- name: Comment on failure
uses: peter-evans/create-or-update-comment@v1
if: ${{ failure() }}
with:
issue-number: 105153
body: |
An automatic merge [failed](https://github.com/NixOS/nixpkgs/actions/runs/${{ github.run_id }}).

60
.github/workflows/rebase-staging.yml vendored Normal file
View File

@ -0,0 +1,60 @@
on:
issue_comment:
types:
- created
# This action allows people with write access to the repo to rebase a PRs base branch from
# master to staging by commenting `/rebase-staging` on the PR while avoiding CODEOWNER notifications.
jobs:
rebase:
runs-on: ubuntu-latest
if: github.repository_owner == 'NixOS' && github.event.issue.pull_request != '' && contains(github.event.comment.body, '/rebase-staging')
steps:
- uses: peter-evans/create-or-update-comment@v1
with:
comment-id: ${{ github.event.comment.id }}
reactions: eyes
- uses: scherermichael-oss/action-has-permission@1.0.6
id: check-write-access
with:
required-permission: write
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: check base branch is master
if: steps.check-write-access.outputs.has-permission
run: |
if [ "$(curl https://api.github.com/repos/NixOS/nixpkgs/pulls/${{ github.event.issue.number }} | jq -r '.base.ref')" != "master" ]; then
echo "This action only works when the current base branch is master."
exit 1
fi
- uses: actions/checkout@v2
with:
fetch-depth: 0
if: steps.check-write-access.outputs.has-permission
- name: rebase pull request
if: steps.check-write-access.outputs.has-permission
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PULL_REQUEST: ${{ github.event.issue.number }}
run: |
git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
git config --global user.name "github-actions[bot]"
git fetch origin
gh pr checkout "$PULL_REQUEST"
git rebase \
--onto="$(git merge-base origin/master origin/staging)" \
"HEAD~$(git rev-list --count HEAD ^master)"
git push --force
curl \
-X POST \
-H "Accept: application/vnd.github.v3+json" \
-H "Authorization: token $GITHUB_TOKEN" \
-d '{ "base": "staging" }' \
"https://api.github.com/repos/NixOS/nixpkgs/pulls/$PULL_REQUEST"
- uses: peter-evans/create-or-update-comment@v1
if: ${{ failure() }}
with:
issue-number: ${{ github.event.issue.number }}
body: |
[Failed to rebase on `staging`](https://github.com/NixOS/nixpkgs/actions/runs/${{ github.run_id }})

View File

@ -1,4 +1,4 @@
Copyright (c) 2003-2020 Eelco Dolstra and the Nixpkgs/NixOS contributors
Copyright (c) 2003-2021 Eelco Dolstra and the Nixpkgs/NixOS contributors
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the

View File

@ -8,7 +8,7 @@
</p>
[Nixpkgs](https://github.com/nixos/nixpkgs) is a collection of over
40,000 software packages that can be installed with the
60,000 software packages that can be installed with the
[Nix](https://nixos.org/nix/) package manager. It also implements
[NixOS](https://nixos.org/nixos/), a purely-functional Linux distribution.
@ -46,9 +46,9 @@ Nixpkgs and NixOS are built and tested by our continuous integration
system, [Hydra](https://hydra.nixos.org/).
* [Continuous package builds for unstable/master](https://hydra.nixos.org/jobset/nixos/trunk-combined)
* [Continuous package builds for the NixOS 20.03 release](https://hydra.nixos.org/jobset/nixos/release-20.03)
* [Continuous package builds for the NixOS 20.09 release](https://hydra.nixos.org/jobset/nixos/release-20.09)
* [Tests for unstable/master](https://hydra.nixos.org/job/nixos/trunk-combined/tested#tabs-constituents)
* [Tests for the NixOS 20.03 release](https://hydra.nixos.org/job/nixos/release-20.03/tested#tabs-constituents)
* [Tests for the NixOS 20.09 release](https://hydra.nixos.org/job/nixos/release-20.09/tested#tabs-constituents)
Artifacts successfully built with Hydra are published to cache at
https://cache.nixos.org/. When successful build and test criteria are
@ -60,7 +60,7 @@ channels](https://nixos.org/nix/manual/#sec-channels).
Nixpkgs is among the most active projects on GitHub. While thousands
of open issues and pull requests might seem a lot at first, it helps
consider it in the context of the scope of the project. Nixpkgs
describes how to build over 40,000 pieces of software and implements a
describes how to build tens of thousands of pieces of software and implements a
Linux distribution. The [GitHub Insights](https://github.com/NixOS/nixpkgs/pulse)
page gives a sense of the project activity.

View File

@ -39,6 +39,7 @@ out/html/index.html: doc-support/result manual-full.xml style.css highlightjs
mkdir -p out/html/highlightjs/
cp -r highlightjs out/html/
cp -r media out/html/
cp ./overrides.css out/html/
cp ./style.css out/html/style.css
@ -53,6 +54,7 @@ out/epub/manual.epub: manual-full.xml
doc-support/result/epub.xsl \
./manual-full.xml
cp -r media out/epub/scratch/OEBPS
cp ./overrides.css out/epub/scratch/OEBPS
cp ./style.css out/epub/scratch/OEBPS
mkdir -p out/epub/scratch/OEBPS/images/callouts/
@ -87,24 +89,16 @@ functions/library/generated: doc-support/result
ln -rfs ./doc-support/result/function-docs functions/library/generated
%.section.xml: %.section.md
pandoc $^ -w docbook \
pandoc $^ -t docbook \
--extract-media=media \
--lua-filter=$(PANDOC_LUA_FILTERS_DIR)/diagram-generator.lua \
-f markdown+smart \
| sed -e 's|<ulink url=|<link xlink:href=|' \
-e 's|</ulink>|</link>|' \
-e 's|<sect. id=|<section xml:id=|' \
-e 's|</sect[0-9]>|</section>|' \
-e '1s| id=| xml:id=|' \
-e '1s|\(<[^ ]* \)|\1xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" |' \
| cat > $@
%.chapter.xml: %.chapter.md
pandoc $^ -w docbook \
pandoc $^ -t docbook \
--top-level-division=chapter \
--extract-media=media \
--lua-filter=$(PANDOC_LUA_FILTERS_DIR)/diagram-generator.lua \
-f markdown+smart \
| sed -e 's|<ulink url=|<link xlink:href=|' \
-e 's|</ulink>|</link>|' \
-e 's|<sect. id=|<section xml:id=|' \
-e 's|</sect[0-9]>|</section>|' \
-e '1s| id=| xml:id=|' \
-e '1s|\(<[^ ]* \)|\1|' \
| cat > $@

View File

@ -0,0 +1,70 @@
# Fetchers {#chap-pkgs-fetchers}
When using Nix, you will frequently need to download source code and other files from the internet. Nixpkgs comes with a few helper functions that allow you to fetch fixed-output derivations in a structured way.
The two fetcher primitives are `fetchurl` and `fetchzip`. Both of these have two required arguments, a URL and a hash. The hash is typically `sha256`, although many more hash algorithms are supported. Nixpkgs contributors are currently recommended to use `sha256`. This hash will be used by Nix to identify your source. A typical usage of fetchurl is provided below.
```nix
{ stdenv, fetchurl }:
stdenv.mkDerivation {
name = "hello";
src = fetchurl {
url = "http://www.example.org/hello.tar.gz";
sha256 = "1111111111111111111111111111111111111111111111111111";
};
}
```
The main difference between `fetchurl` and `fetchzip` is in how they store the contents. `fetchurl` will store the unaltered contents of the URL within the Nix store. `fetchzip` on the other hand will decompress the archive for you, making files and directories directly accessible in the future. `fetchzip` can only be used with archives. Despite the name, `fetchzip` is not limited to .zip files and can also be used with any tarball.
`fetchpatch` works very similarly to `fetchurl` with the same arguments expected. It expects patch files as a source and and performs normalization on them before computing the checksum. For example it will remove comments or other unstable parts that are sometimes added by version control systems and can change over time.
Other fetcher functions allow you to add source code directly from a VCS such as subversion or git. These are mostly straightforward nambes based on the name of the command used with the VCS system. Because they give you a working repository, they act most like `fetchzip`.
## `fetchsvn`
Used with Subversion. Expects `url` to a Subversion directory, `rev`, and `sha256`.
## `fetchgit`
Used with Git. Expects `url` to a Git repo, `rev`, and `sha256`. `rev` in this case can be full the git commit id (SHA1 hash) or a tag name like `refs/tags/v1.0`.
## `fetchfossil`
Used with Fossil. Expects `url` to a Fossil archive, `rev`, and `sha256`.
## `fetchcvs`
Used with CVS. Expects `cvsRoot`, `tag`, and `sha256`.
## `fetchhg`
Used with Mercurial. Expects `url`, `rev`, and `sha256`.
A number of fetcher functions wrap part of `fetchurl` and `fetchzip`. They are mainly convenience functions intended for commonly used destinations of source code in Nixpkgs. These wrapper fetchers are listed below.
## `fetchFromGitHub`
`fetchFromGitHub` expects four arguments. `owner` is a string corresponding to the GitHub user or organization that controls this repository. `repo` corresponds to the name of the software repository. These are located at the top of every GitHub HTML page as `owner`/`repo`. `rev` corresponds to the Git commit hash or tag (e.g `v1.0`) that will be downloaded from Git. Finally, `sha256` corresponds to the hash of the extracted directory. Again, other hash algorithms are also available but `sha256` is currently preferred.
## `fetchFromGitLab`
This is used with GitLab repositories. The arguments expected are very similar to fetchFromGitHub above.
## `fetchFromGitiles`
This is used with Gitiles repositories. The arguments expected are similar to fetchgit.
## `fetchFromBitbucket`
This is used with BitBucket repositories. The arguments expected are very similar to fetchFromGitHub above.
## `fetchFromSavannah`
This is used with Savannah repositories. The arguments expected are very similar to fetchFromGitHub above.
## `fetchFromRepoOrCz`
This is used with repo.or.cz repositories. The arguments expected are very similar to fetchFromGitHub above.

View File

@ -1,150 +0,0 @@
<chapter xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xml:id="chap-pkgs-fetchers">
<title>Fetchers</title>
<para>
When using Nix, you will frequently need to download source code and other files from the internet. Nixpkgs comes with a few helper functions that allow you to fetch fixed-output derivations in a structured way.
</para>
<para>
The two fetcher primitives are <function>fetchurl</function> and <function>fetchzip</function>. Both of these have two required arguments, a URL and a hash. The hash is typically <literal>sha256</literal>, although many more hash algorithms are supported. Nixpkgs contributors are currently recommended to use <literal>sha256</literal>. This hash will be used by Nix to identify your source. A typical usage of fetchurl is provided below.
</para>
<programlisting><![CDATA[
{ stdenv, fetchurl }:
stdenv.mkDerivation {
name = "hello";
src = fetchurl {
url = "http://www.example.org/hello.tar.gz";
sha256 = "1111111111111111111111111111111111111111111111111111";
};
}
]]></programlisting>
<para>
The main difference between <function>fetchurl</function> and <function>fetchzip</function> is in how they store the contents. <function>fetchurl</function> will store the unaltered contents of the URL within the Nix store. <function>fetchzip</function> on the other hand will decompress the archive for you, making files and directories directly accessible in the future. <function>fetchzip</function> can only be used with archives. Despite the name, <function>fetchzip</function> is not limited to .zip files and can also be used with any tarball.
</para>
<para>
<function>fetchpatch</function> works very similarly to <function>fetchurl</function> with the same arguments expected. It expects patch files as a source and and performs normalization on them before computing the checksum. For example it will remove comments or other unstable parts that are sometimes added by version control systems and can change over time.
</para>
<para>
Other fetcher functions allow you to add source code directly from a VCS such as subversion or git. These are mostly straightforward names based on the name of the command used with the VCS system. Because they give you a working repository, they act most like <function>fetchzip</function>.
</para>
<variablelist>
<varlistentry>
<term>
<literal>fetchsvn</literal>
</term>
<listitem>
<para>
Used with Subversion. Expects <literal>url</literal> to a Subversion directory, <literal>rev</literal>, and <literal>sha256</literal>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<literal>fetchgit</literal>
</term>
<listitem>
<para>
Used with Git. Expects <literal>url</literal> to a Git repo, <literal>rev</literal>, and <literal>sha256</literal>. <literal>rev</literal> in this case can be full the git commit id (SHA1 hash) or a tag name like <literal>refs/tags/v1.0</literal>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<literal>fetchfossil</literal>
</term>
<listitem>
<para>
Used with Fossil. Expects <literal>url</literal> to a Fossil archive, <literal>rev</literal>, and <literal>sha256</literal>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<literal>fetchcvs</literal>
</term>
<listitem>
<para>
Used with CVS. Expects <literal>cvsRoot</literal>, <literal>tag</literal>, and <literal>sha256</literal>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<literal>fetchhg</literal>
</term>
<listitem>
<para>
Used with Mercurial. Expects <literal>url</literal>, <literal>rev</literal>, and <literal>sha256</literal>.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
A number of fetcher functions wrap part of <function>fetchurl</function> and <function>fetchzip</function>. They are mainly convenience functions intended for commonly used destinations of source code in Nixpkgs. These wrapper fetchers are listed below.
</para>
<variablelist>
<varlistentry>
<term>
<literal>fetchFromGitHub</literal>
</term>
<listitem>
<para>
<function>fetchFromGitHub</function> expects four arguments. <literal>owner</literal> is a string corresponding to the GitHub user or organization that controls this repository. <literal>repo</literal> corresponds to the name of the software repository. These are located at the top of every GitHub HTML page as <literal>owner</literal>/<literal>repo</literal>. <literal>rev</literal> corresponds to the Git commit hash or tag (e.g <literal>v1.0</literal>) that will be downloaded from Git. Finally, <literal>sha256</literal> corresponds to the hash of the extracted directory. Again, other hash algorithms are also available but <literal>sha256</literal> is currently preferred.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<literal>fetchFromGitLab</literal>
</term>
<listitem>
<para>
This is used with GitLab repositories. The arguments expected are very similar to fetchFromGitHub above.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<literal>fetchFromGitiles</literal>
</term>
<listitem>
<para>
This is used with Gitiles repositories. The arguments expected
are similar to fetchgit.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<literal>fetchFromBitbucket</literal>
</term>
<listitem>
<para>
This is used with BitBucket repositories. The arguments expected are very similar to fetchFromGitHub above.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<literal>fetchFromSavannah</literal>
</term>
<listitem>
<para>
This is used with Savannah repositories. The arguments expected are very similar to fetchFromGitHub above.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<literal>fetchFromRepoOrCz</literal>
</term>
<listitem>
<para>
This is used with repo.or.cz repositories. The arguments expected are very similar to fetchFromGitHub above.
</para>
</listitem>
</varlistentry>
</variablelist>
</chapter>

View File

@ -1,4 +1,4 @@
# Cataclysm: Dark Days Ahead
# Cataclysm: Dark Days Ahead {#cataclysm-dark-days-ahead}
## How to install Cataclysm DDA

View File

@ -0,0 +1,119 @@
# Emacs {#sec-emacs}
## Configuring Emacs {#sec-emacs-config}
The Emacs package comes with some extra helpers to make it easier to configure. `emacs.pkgs.withPackages` allows you to manage packages from ELPA. This means that you will not have to install that packages from within Emacs. For instance, if you wanted to use `company` `counsel`, `flycheck`, `ivy`, `magit`, `projectile`, and `use-package` you could use this as a `~/.config/nixpkgs/config.nix` override:
```nix
{
packageOverrides = pkgs: with pkgs; {
myEmacs = emacs.pkgs.withPackages (epkgs: (with epkgs.melpaStablePackages; [
company
counsel
flycheck
ivy
magit
projectile
use-package
]));
}
}
```
You can install it like any other packages via `nix-env -iA myEmacs`. However, this will only install those packages. It will not `configure` them for us. To do this, we need to provide a configuration file. Luckily, it is possible to do this from within Nix! By modifying the above example, we can make Emacs load a custom config file. The key is to create a package that provide a `default.el` file in `/share/emacs/site-start/`. Emacs knows to load this file automatically when it starts.
```nix
{
packageOverrides = pkgs: with pkgs; rec {
myEmacsConfig = writeText "default.el" ''
;; initialize package
(require 'package)
(package-initialize 'noactivate)
(eval-when-compile
(require 'use-package))
;; load some packages
(use-package company
:bind ("&lt;C-tab&gt;" . company-complete)
:diminish company-mode
:commands (company-mode global-company-mode)
:defer 1
:config
(global-company-mode))
(use-package counsel
:commands (counsel-descbinds)
:bind (([remap execute-extended-command] . counsel-M-x)
("C-x C-f" . counsel-find-file)
("C-c g" . counsel-git)
("C-c j" . counsel-git-grep)
("C-c k" . counsel-ag)
("C-x l" . counsel-locate)
("M-y" . counsel-yank-pop)))
(use-package flycheck
:defer 2
:config (global-flycheck-mode))
(use-package ivy
:defer 1
:bind (("C-c C-r" . ivy-resume)
("C-x C-b" . ivy-switch-buffer)
:map ivy-minibuffer-map
("C-j" . ivy-call))
:diminish ivy-mode
:commands ivy-mode
:config
(ivy-mode 1))
(use-package magit
:defer
:if (executable-find "git")
:bind (("C-x g" . magit-status)
("C-x G" . magit-dispatch-popup))
:init
(setq magit-completing-read-function 'ivy-completing-read))
(use-package projectile
:commands projectile-mode
:bind-keymap ("C-c p" . projectile-command-map)
:defer 5
:config
(projectile-global-mode))
'';
myEmacs = emacs.pkgs.withPackages (epkgs: (with epkgs.melpaStablePackages; [
(runCommand "default.el" {} ''
mkdir -p $out/share/emacs/site-lisp
cp ${myEmacsConfig} $out/share/emacs/site-lisp/default.el
'')
company
counsel
flycheck
ivy
magit
projectile
use-package
]));
};
}
```
This provides a fairly full Emacs start file. It will load in addition to the user's presonal config. You can always disable it by passing `-q` to the Emacs command.
Sometimes `emacs.pkgs.withPackages` is not enough, as this package set has some priorities imposed on packages (with the lowest priority assigned to Melpa Unstable, and the highest for packages manually defined in `pkgs/top-level/emacs-packages.nix`). But you can't control this priorities when some package is installed as a dependency. You can override it on per-package-basis, providing all the required dependencies manually - but it's tedious and there is always a possibility that an unwanted dependency will sneak in through some other package. To completely override such a package you can use `overrideScope'`.
```nix
overrides = self: super: rec {
haskell-mode = self.melpaPackages.haskell-mode;
...
};
((emacsPackagesFor emacs).overrideScope' overrides).emacs.pkgs.withPackages
(p: with p; [
# here both these package will use haskell-mode of our own choice
ghc-mod
dante
])
```

View File

@ -1,131 +0,0 @@
<section xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xml:id="sec-emacs">
<title>Emacs</title>
<section xml:id="sec-emacs-config">
<title>Configuring Emacs</title>
<para>
The Emacs package comes with some extra helpers to make it easier to configure. <varname>emacsWithPackages</varname> allows you to manage packages from ELPA. This means that you will not have to install that packages from within Emacs. For instance, if you wanted to use <literal>company</literal>, <literal>counsel</literal>, <literal>flycheck</literal>, <literal>ivy</literal>, <literal>magit</literal>, <literal>projectile</literal>, and <literal>use-package</literal> you could use this as a <filename>~/.config/nixpkgs/config.nix</filename> override:
</para>
<screen>
{
packageOverrides = pkgs: with pkgs; {
myEmacs = emacsWithPackages (epkgs: (with epkgs.melpaStablePackages; [
company
counsel
flycheck
ivy
magit
projectile
use-package
]));
}
}
</screen>
<para>
You can install it like any other packages via <command>nix-env -iA myEmacs</command>. However, this will only install those packages. It will not <literal>configure</literal> them for us. To do this, we need to provide a configuration file. Luckily, it is possible to do this from within Nix! By modifying the above example, we can make Emacs load a custom config file. The key is to create a package that provide a <filename>default.el</filename> file in <filename>/share/emacs/site-start/</filename>. Emacs knows to load this file automatically when it starts.
</para>
<screen>
{
packageOverrides = pkgs: with pkgs; rec {
myEmacsConfig = writeText "default.el" ''
;; initialize package
(require 'package)
(package-initialize 'noactivate)
(eval-when-compile
(require 'use-package))
;; load some packages
(use-package company
:bind ("&lt;C-tab&gt;" . company-complete)
:diminish company-mode
:commands (company-mode global-company-mode)
:defer 1
:config
(global-company-mode))
(use-package counsel
:commands (counsel-descbinds)
:bind (([remap execute-extended-command] . counsel-M-x)
("C-x C-f" . counsel-find-file)
("C-c g" . counsel-git)
("C-c j" . counsel-git-grep)
("C-c k" . counsel-ag)
("C-x l" . counsel-locate)
("M-y" . counsel-yank-pop)))
(use-package flycheck
:defer 2
:config (global-flycheck-mode))
(use-package ivy
:defer 1
:bind (("C-c C-r" . ivy-resume)
("C-x C-b" . ivy-switch-buffer)
:map ivy-minibuffer-map
("C-j" . ivy-call))
:diminish ivy-mode
:commands ivy-mode
:config
(ivy-mode 1))
(use-package magit
:defer
:if (executable-find "git")
:bind (("C-x g" . magit-status)
("C-x G" . magit-dispatch-popup))
:init
(setq magit-completing-read-function 'ivy-completing-read))
(use-package projectile
:commands projectile-mode
:bind-keymap ("C-c p" . projectile-command-map)
:defer 5
:config
(projectile-global-mode))
'';
myEmacs = emacsWithPackages (epkgs: (with epkgs.melpaStablePackages; [
(runCommand "default.el" {} ''
mkdir -p $out/share/emacs/site-lisp
cp ${myEmacsConfig} $out/share/emacs/site-lisp/default.el
'')
company
counsel
flycheck
ivy
magit
projectile
use-package
]));
};
}
</screen>
<para>
This provides a fairly full Emacs start file. It will load in addition to the user's presonal config. You can always disable it by passing <command>-q</command> to the Emacs command.
</para>
<para>
Sometimes <varname>emacsWithPackages</varname> is not enough, as this package set has some priorities imposed on packages (with the lowest priority assigned to Melpa Unstable, and the highest for packages manually defined in <filename>pkgs/top-level/emacs-packages.nix</filename>). But you can't control this priorities when some package is installed as a dependency. You can override it on per-package-basis, providing all the required dependencies manually - but it's tedious and there is always a possibility that an unwanted dependency will sneak in through some other package. To completely override such a package you can use <varname>overrideScope'</varname>.
</para>
<screen>
overrides = self: super: rec {
haskell-mode = self.melpaPackages.haskell-mode;
...
};
((emacsPackagesGen emacs).overrideScope' overrides).emacsWithPackages (p: with p; [
# here both these package will use haskell-mode of our own choice
ghc-mod
dante
])
</screen>
</section>
</section>

View File

@ -0,0 +1,49 @@
# Firefox {#sec-firefox}
## Build wrapped Firefox with extensions and policies
The `wrapFirefox` function allows to pass policies, preferences and extension that are available to firefox. With the help of `fetchFirefoxAddon` this allows build a firefox version that already comes with addons pre-installed:
```nix
{
myFirefox = wrapFirefox firefox-unwrapped {
nixExtensions = [
(fetchFirefoxAddon {
name = "ublock"; # Has to be unique!
url = "https://addons.mozilla.org/firefox/downloads/file/3679754/ublock_origin-1.31.0-an+fx.xpi";
sha256 = "1h768ljlh3pi23l27qp961v1hd0nbj2vasgy11bmcrlqp40zgvnr";
})
];
extraPolicies = {
CaptivePortal = false;
DisableFirefoxStudies = true;
DisablePocket = true;
DisableTelemetry = true;
DisableFirefoxAccounts = true;
FirefoxHome = {
Pocket = false;
Snippets = false;
};
UserMessaging = {
ExtensionRecommendations = false;
SkipOnboarding = true;
};
};
extraPrefs = ''
// Show more ssl cert infos
lockPref("security.identityblock.show_extended_validation", true);
'';
};
}
```
If `nixExtensions != null` then all manually installed addons will be uninstalled from your browser profile.
To view available enterprise policies visit [enterprise policies](https://github.com/mozilla/policy-templates#enterprisepoliciesenabled)
or type into the Firefox url bar: `about:policies#documentation`.
Nix installed addons do not have a valid signature, which is why signature verification is disabled. This does not compromise security because downloaded addons are checksumed and manual addons can't be installed. Also make sure that the `name` field of fetchFirefoxAddon is unique. If you remove an addon from the nixExtensions array, rebuild and start Firefox the removed addon will be completly removed with all of its settings.
## Troubleshooting {#sec-firefox-troubleshooting}
If addons do not appear installed although they have been defined in your nix configuration file reset the local addon state of your Firefox profile by clicking `help -> restart with addons disabled -> restart -> refresh firefox`. This can happen if you switch from manual addon mode to nix addon mode and then back to manual mode and then again to nix addon mode.

View File

@ -0,0 +1,50 @@
# Fish {#sec-fish}
Fish is a "smart and user-friendly command line shell" with support for plugins.
## Vendor Fish scripts {#sec-fish-vendor}
Any package may ship its own Fish completions, configuration snippets, and
functions. Those should be installed to
`$out/share/fish/vendor_{completions,conf,functions}.d` respectively.
When the `programs.fish.enable` and
`programs.fish.vendor.{completions,config,functions}.enable` options from the
NixOS Fish module are set to true, those paths are symlinked in the current
system environment and automatically loaded by Fish.
## Packaging Fish plugins {#sec-fish-plugins-pkg}
While packages providing standalone executables belong to the top level,
packages which have the sole purpose of extending Fish belong to the
`fishPlugins` scope and should be registered in
`pkgs/shells/fish/plugins/default.nix`.
The `buildFishPlugin` utility function can be used to automatically copy Fish
scripts from `$src/{completions,conf,conf.d,functions}` to the standard vendor
installation paths. It also sets up the test environment so that the optional
`checkPhase` is executed in a Fish shell with other already packaged plugins
and package-local Fish functions specified in `checkPlugins` and
`checkFunctionDirs` respectively.
See `pkgs/shells/fish/plugins/pure.nix` for an example of Fish plugin package
using `buildFishPlugin` and running unit tests with the `fishtape` test runner.
## Fish wrapper {#sec-fish-wrapper}
The `wrapFish` package is a wrapper around Fish which can be used to create
Fish shells initialised with some plugins as well as completions, configuration
snippets and functions sourced from the given paths. This provides a convenient
way to test Fish plugins and scripts without having to alter the environment.
```nix
wrapFish {
pluginPkgs = with fishPlugins; [ pure foreign-env ];
completionDirs = [];
functionDirs = [];
confDirs = [ "/path/to/some/fish/init/dir/" ];
}
```

View File

@ -9,17 +9,19 @@
<xi:include href="dlib.xml" />
<xi:include href="eclipse.xml" />
<xi:include href="elm.xml" />
<xi:include href="emacs.xml" />
<xi:include href="emacs.section.xml" />
<xi:include href="firefox.section.xml" />
<xi:include href="fish.section.xml" />
<xi:include href="ibus.xml" />
<xi:include href="kakoune.xml" />
<xi:include href="linux.xml" />
<xi:include href="locales.xml" />
<xi:include href="nginx.xml" />
<xi:include href="opengl.xml" />
<xi:include href="shell-helpers.xml" />
<xi:include href="steam.xml" />
<xi:include href="kakoune.section.xml" />
<xi:include href="linux.section.xml" />
<xi:include href="locales.section.xml" />
<xi:include href="nginx.section.xml" />
<xi:include href="opengl.section.xml" />
<xi:include href="shell-helpers.section.xml" />
<xi:include href="steam.section.xml" />
<xi:include href="cataclysm-dda.section.xml" />
<xi:include href="urxvt.xml" />
<xi:include href="weechat.xml" />
<xi:include href="xorg.xml" />
<xi:include href="urxvt.section.xml" />
<xi:include href="weechat.section.xml" />
<xi:include href="xorg.section.xml" />
</chapter>

View File

@ -0,0 +1,9 @@
# Kakoune {#sec-kakoune}
Kakoune can be built to autoload plugins:
```nix
(kakoune.override {
plugins = with pkgs.kakounePlugins; [ parinfer-rust ];
})
```

View File

@ -1,14 +0,0 @@
<section xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xml:id="sec-kakoune">
<title>Kakoune</title>
<para>
Kakoune can be built to autoload plugins:
<programlisting>(kakoune.override {
configure = {
plugins = with pkgs.kakounePlugins; [ parinfer-rust ];
};
})</programlisting>
</para>
</section>

View File

@ -0,0 +1,41 @@
# Linux kernel {#sec-linux-kernel}
The Nix expressions to build the Linux kernel are in [`pkgs/os-specific/linux/kernel`](https://github.com/NixOS/nixpkgs/blob/master/pkgs/os-specific/linux/kernel).
The function that builds the kernel has an argument `kernelPatches` which should be a list of `{name, patch, extraConfig}` attribute sets, where `name` is the name of the patch (which is included in the kernels `meta.description` attribute), `patch` is the patch itself (possibly compressed), and `extraConfig` (optional) is a string specifying extra options to be concatenated to the kernel configuration file (`.config`).
The kernel derivation exports an attribute `features` specifying whether optional functionality is or isnt enabled. This is used in NixOS to implement kernel-specific behaviour. For instance, if the kernel has the `iwlwifi` feature (i.e. has built-in support for Intel wireless chipsets), then NixOS doesnt have to build the external `iwlwifi` package:
```nix
modulesTree = [kernel]
++ pkgs.lib.optional (!kernel.features ? iwlwifi) kernelPackages.iwlwifi
++ ...;
```
How to add a new (major) version of the Linux kernel to Nixpkgs:
1. Copy the old Nix expression (e.g. `linux-2.6.21.nix`) to the new one (e.g. `linux-2.6.22.nix`) and update it.
2. Add the new kernel to `all-packages.nix` (e.g., create an attribute `kernel_2_6_22`).
3. Now were going to update the kernel configuration. First unpack the kernel. Then for each supported platform (`i686`, `x86_64`, `uml`) do the following:
1. Make an copy from the old config (e.g. `config-2.6.21-i686-smp`) to the new one (e.g. `config-2.6.22-i686-smp`).
2. Copy the config file for this platform (e.g. `config-2.6.22-i686-smp`) to `.config` in the kernel source tree.
3. Run `make oldconfig ARCH={i386,x86_64,um}` and answer all questions. (For the uml configuration, also add `SHELL=bash`.) Make sure to keep the configuration consistent between platforms (i.e. dont enable some feature on `i686` and disable it on `x86_64`).
4. If needed you can also run `make menuconfig`:
```ShellSession
$ nix-env -i ncurses
$ export NIX_CFLAGS_LINK=-lncurses
$ make menuconfig ARCH=arch
```
5. Copy `.config` over the new config file (e.g. `config-2.6.22-i686-smp`).
4. Test building the kernel: `nix-build -A kernel_2_6_22`. If it compiles, ship it! For extra credit, try booting NixOS with it.
5. It may be that the new kernel requires updating the external kernel modules and kernel-dependent packages listed in the `linuxPackagesFor` function in `all-packages.nix` (such as the NVIDIA drivers, AUFS, etc.). If the updated packages arent backwards compatible with older kernels, you may need to keep the older versions around.

View File

@ -1,85 +0,0 @@
<section xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xml:id="sec-linux-kernel">
<title>Linux kernel</title>
<para>
The Nix expressions to build the Linux kernel are in <link
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/pkgs/os-specific/linux/kernel"><filename>pkgs/os-specific/linux/kernel</filename></link>.
</para>
<para>
The function that builds the kernel has an argument <varname>kernelPatches</varname> which should be a list of <literal>{name, patch, extraConfig}</literal> attribute sets, where <varname>name</varname> is the name of the patch (which is included in the kernels <varname>meta.description</varname> attribute), <varname>patch</varname> is the patch itself (possibly compressed), and <varname>extraConfig</varname> (optional) is a string specifying extra options to be concatenated to the kernel configuration file (<filename>.config</filename>).
</para>
<para>
The kernel derivation exports an attribute <varname>features</varname> specifying whether optional functionality is or isnt enabled. This is used in NixOS to implement kernel-specific behaviour. For instance, if the kernel has the <varname>iwlwifi</varname> feature (i.e. has built-in support for Intel wireless chipsets), then NixOS doesnt have to build the external <varname>iwlwifi</varname> package:
<programlisting>
modulesTree = [kernel]
++ pkgs.lib.optional (!kernel.features ? iwlwifi) kernelPackages.iwlwifi
++ ...;
</programlisting>
</para>
<para>
How to add a new (major) version of the Linux kernel to Nixpkgs:
<orderedlist>
<listitem>
<para>
Copy the old Nix expression (e.g. <filename>linux-2.6.21.nix</filename>) to the new one (e.g. <filename>linux-2.6.22.nix</filename>) and update it.
</para>
</listitem>
<listitem>
<para>
Add the new kernel to <filename>all-packages.nix</filename> (e.g., create an attribute <varname>kernel_2_6_22</varname>).
</para>
</listitem>
<listitem>
<para>
Now were going to update the kernel configuration. First unpack the kernel. Then for each supported platform (<literal>i686</literal>, <literal>x86_64</literal>, <literal>uml</literal>) do the following:
<orderedlist>
<listitem>
<para>
Make an copy from the old config (e.g. <filename>config-2.6.21-i686-smp</filename>) to the new one (e.g. <filename>config-2.6.22-i686-smp</filename>).
</para>
</listitem>
<listitem>
<para>
Copy the config file for this platform (e.g. <filename>config-2.6.22-i686-smp</filename>) to <filename>.config</filename> in the kernel source tree.
</para>
</listitem>
<listitem>
<para>
Run <literal>make oldconfig ARCH=<replaceable>{i386,x86_64,um}</replaceable></literal> and answer all questions. (For the uml configuration, also add <literal>SHELL=bash</literal>.) Make sure to keep the configuration consistent between platforms (i.e. dont enable some feature on <literal>i686</literal> and disable it on <literal>x86_64</literal>).
</para>
</listitem>
<listitem>
<para>
If needed you can also run <literal>make menuconfig</literal>:
<screen>
<prompt>$ </prompt>nix-env -i ncurses
<prompt>$ </prompt>export NIX_CFLAGS_LINK=-lncurses
<prompt>$ </prompt>make menuconfig ARCH=<replaceable>arch</replaceable></screen>
</para>
</listitem>
<listitem>
<para>
Copy <filename>.config</filename> over the new config file (e.g. <filename>config-2.6.22-i686-smp</filename>).
</para>
</listitem>
</orderedlist>
</para>
</listitem>
<listitem>
<para>
Test building the kernel: <literal>nix-build -A kernel_2_6_22</literal>. If it compiles, ship it! For extra credit, try booting NixOS with it.
</para>
</listitem>
<listitem>
<para>
It may be that the new kernel requires updating the external kernel modules and kernel-dependent packages listed in the <varname>linuxPackagesFor</varname> function in <filename>all-packages.nix</filename> (such as the NVIDIA drivers, AUFS, etc.). If the updated packages arent backwards compatible with older kernels, you may need to keep the older versions around.
</para>
</listitem>
</orderedlist>
</para>
</section>

View File

@ -0,0 +1,5 @@
# Locales {#locales}
To allow simultaneous use of packages linked against different versions of `glibc` with different locale archive formats Nixpkgs patches `glibc` to rely on `LOCALE_ARCHIVE` environment variable.
On non-NixOS distributions this variable is obviously not set. This can cause regressions in language support or even crashes in some Nixpkgs-provided programs. The simplest way to mitigate this problem is exporting the `LOCALE_ARCHIVE` variable pointing to `${glibcLocales}/lib/locale/locale-archive`. The drawback (and the reason this is not the default) is the relatively large (a hundred MiB) size of the full set of locales. It is possible to build a custom set of locales by overriding parameters `allLocales` and `locales` of the package.

View File

@ -1,13 +0,0 @@
<section xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xml:id="locales">
<title>Locales</title>
<para>
To allow simultaneous use of packages linked against different versions of <literal>glibc</literal> with different locale archive formats Nixpkgs patches <literal>glibc</literal> to rely on <literal>LOCALE_ARCHIVE</literal> environment variable.
</para>
<para>
On non-NixOS distributions this variable is obviously not set. This can cause regressions in language support or even crashes in some Nixpkgs-provided programs. The simplest way to mitigate this problem is exporting the <literal>LOCALE_ARCHIVE</literal> variable pointing to <literal>${glibcLocales}/lib/locale/locale-archive</literal>. The drawback (and the reason this is not the default) is the relatively large (a hundred MiB) size of the full set of locales. It is possible to build a custom set of locales by overriding parameters <literal>allLocales</literal> and <literal>locales</literal> of the package.
</para>
</section>

View File

@ -0,0 +1,11 @@
# Nginx {#sec-nginx}
[Nginx](https://nginx.org) is a reverse proxy and lightweight webserver.
## ETags on static files served from the Nix store {#sec-nginx-etag}
HTTP has a couple different mechanisms for caching to prevent clients from having to download the same content repeatedly if a resource has not changed since the last time it was requested. When nginx is used as a server for static files, it implements the caching mechanism based on the [`Last-Modified`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Last-Modified) response header automatically; unfortunately, it works by using filesystem timestamps to determine the value of the `Last-Modified` header. This doesn't give the desired behavior when the file is in the Nix store, because all file timestamps are set to 0 (for reasons related to build reproducibility).
Fortunately, HTTP supports an alternative (and more effective) caching mechanism: the [`ETag`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag) response header. The value of the `ETag` header specifies some identifier for the particular content that the server is sending (e.g. a hash). When a client makes a second request for the same resource, it sends that value back in an `If-None-Match` header. If the ETag value is unchanged, then the server does not need to resend the content.
As of NixOS 19.09, the nginx package in Nixpkgs is patched such that when nginx serves a file out of `/nix/store`, the hash in the store path is used as the `ETag` header in the HTTP response, thus providing proper caching functionality. This happens automatically; you do not need to do modify any configuration to get this behavior.

View File

@ -1,25 +0,0 @@
<section xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xml:id="sec-nginx">
<title>Nginx</title>
<para>
<link xlink:href="https://nginx.org/">Nginx</link> is a reverse proxy and lightweight webserver.
</para>
<section xml:id="sec-nginx-etag">
<title>ETags on static files served from the Nix store</title>
<para>
HTTP has a couple different mechanisms for caching to prevent clients from having to download the same content repeatedly if a resource has not changed since the last time it was requested. When nginx is used as a server for static files, it implements the caching mechanism based on the <link xlink:href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Last-Modified"><literal>Last-Modified</literal></link> response header automatically; unfortunately, it works by using filesystem timestamps to determine the value of the <literal>Last-Modified</literal> header. This doesn't give the desired behavior when the file is in the Nix store, because all file timestamps are set to 0 (for reasons related to build reproducibility).
</para>
<para>
Fortunately, HTTP supports an alternative (and more effective) caching mechanism: the <link xlink:href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag"><literal>ETag</literal></link> response header. The value of the <literal>ETag</literal> header specifies some identifier for the particular content that the server is sending (e.g. a hash). When a client makes a second request for the same resource, it sends that value back in an <literal>If-None-Match</literal> header. If the ETag value is unchanged, then the server does not need to resend the content.
</para>
<para>
As of NixOS 19.09, the nginx package in Nixpkgs is patched such that when nginx serves a file out of <filename>/nix/store</filename>, the hash in the store path is used as the <literal>ETag</literal> header in the HTTP response, thus providing proper caching functionality. This happens automatically; you do not need to do modify any configuration to get this behavior.
</para>
</section>
</section>

View File

@ -0,0 +1,15 @@
# OpenGL {#sec-opengl}
OpenGL support varies depending on which hardware is used and which drivers are available and loaded.
Broadly, we support both GL vendors: Mesa and NVIDIA.
## NixOS Desktop
The NixOS desktop or other non-headless configurations are the primary target for OpenGL libraries and applications. The current solution for discovering which drivers are available is based on [libglvnd](https://gitlab.freedesktop.org/glvnd/libglvnd). `libglvnd` performs "vendor-neutral dispatch", trying a variety of techniques to find the system's GL implementation. In practice, this will be either via standard GLX for X11 users or EGL for Wayland users, and supporting either NVIDIA or Mesa extensions.
## Nix on GNU/Linux
If you are using a non-NixOS GNU/Linux/X11 desktop with free software video drivers, consider launching OpenGL-dependent programs from Nixpkgs with Nixpkgs versions of `libglvnd` and `mesa.drivers` in `LD_LIBRARY_PATH`. For Mesa drivers, the Linux kernel version doesn't have to match nixpkgs.
For proprietary video drivers you might have luck with also adding the corresponding video driver package.

View File

@ -1,9 +0,0 @@
<section xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xml:id="sec-opengl">
<title>OpenGL</title>
<para>
Packages that use OpenGL have NixOS desktop as their primary target. The current solution for loading the GPU-specific drivers is based on <literal>libglvnd</literal> and looks for the driver implementation in <literal>LD_LIBRARY_PATH</literal>. If you are using a non-NixOS GNU/Linux/X11 desktop with free software video drivers, consider launching OpenGL-dependent programs from Nixpkgs with Nixpkgs versions of <literal>libglvnd</literal> and <literal>mesa_drivers</literal> in <literal>LD_LIBRARY_PATH</literal>. For proprietary video drivers you might have luck with also adding the corresponding video driver package.
</para>
</section>

View File

@ -0,0 +1,12 @@
# Interactive shell helpers {#sec-shell-helpers}
Some packages provide the shell integration to be more useful. But unlike other systems, nix doesn't have a standard `share` directory location. This is why a bunch `PACKAGE-share` scripts are shipped that print the location of the corresponding shared folder. Current list of such packages is as following:
- `fzf` : `fzf-share`
E.g. `fzf` can then used in the `.bashrc` like this:
```bash
source "$(fzf-share)/completion.bash"
source "$(fzf-share)/key-bindings.bash"
```

View File

@ -1,25 +0,0 @@
<section xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xml:id="sec-shell-helpers">
<title>Interactive shell helpers</title>
<para>
Some packages provide the shell integration to be more useful. But unlike other systems, nix doesn't have a standard share directory location. This is why a bunch <command>PACKAGE-share</command> scripts are shipped that print the location of the corresponding shared folder. Current list of such packages is as following:
<itemizedlist>
<listitem>
<para>
<literal>autojump</literal>: <command>autojump-share</command>
</para>
</listitem>
<listitem>
<para>
<literal>fzf</literal>: <command>fzf-share</command>
</para>
</listitem>
</itemizedlist>
E.g. <literal>autojump</literal> can then used in the .bashrc like this:
<screen>
source "$(autojump-share)/autojump.bash"
</screen>
</para>
</section>

View File

@ -0,0 +1,69 @@
# Steam {#sec-steam}
## Steam in Nix {#sec-steam-nix}
Steam is distributed as a `.deb` file, for now only as an i686 package (the amd64 package only has documentation). When unpacked, it has a script called `steam` that in Ubuntu (their target distro) would go to `/usr/bin`. When run for the first time, this script copies some files to the user's home, which include another script that is the ultimate responsible for launching the steam binary, which is also in \$HOME.
Nix problems and constraints:
- We don't have `/bin/bash` and many scripts point there. Similarly for `/usr/bin/python`.
- We don't have the dynamic loader in `/lib`.
- The `steam.sh` script in \$HOME can not be patched, as it is checked and rewritten by steam.
- The steam binary cannot be patched, it's also checked.
The current approach to deploy Steam in NixOS is composing a FHS-compatible chroot environment, as documented [here](http://sandervanderburg.blogspot.nl/2013/09/composing-fhs-compatible-chroot.html). This allows us to have binaries in the expected paths without disrupting the system, and to avoid patching them to work in a non FHS environment.
## How to play {#sec-steam-play}
Use `programs.steam.enable = true;` if you want to add steam to systemPackages and also enable a few workarrounds aswell as Steam controller support or other Steam supported controllers such as the DualShock 4 or Nintendo Switch Pr.
## Troubleshooting {#sec-steam-troub}
- **Steam fails to start. What do I do?**
Try to run
```ShellSession
strace steam
```
to see what is causing steam to fail.
- **Using the FOSS Radeon or nouveau (nvidia) drivers**
- The `newStdcpp` parameter was removed since NixOS 17.09 and should not be needed anymore.
- Steam ships statically linked with a version of libcrypto that conflics with the one dynamically loaded by radeonsi_dri.so. If you get the error
```
steam.sh: line 713: 7842 Segmentation fault (core dumped)
```
have a look at [this pull request](https://github.com/NixOS/nixpkgs/pull/20269).
- **Java**
1. There is no java in steam chrootenv by default. If you get a message like
```
/home/foo/.local/share/Steam/SteamApps/common/towns/towns.sh: line 1: java: command not found
```
You need to add
```nix
steam.override { withJava = true; };
```
## steam-run {#sec-steam-run}
The FHS-compatible chroot used for steam can also be used to run other linux games that expect a FHS environment. To do it, add
```nix
pkgs.steam.override ({
nativeOnly = true;
newStdcpp = true;
}).run
```
to your configuration, rebuild, and run the game with
```
steam-run ./foo
```

View File

@ -1,125 +0,0 @@
<section xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xml:id="sec-steam">
<title>Steam</title>
<section xml:id="sec-steam-nix">
<title>Steam in Nix</title>
<para>
Steam is distributed as a <filename>.deb</filename> file, for now only as an i686 package (the amd64 package only has documentation). When unpacked, it has a script called <filename>steam</filename> that in Ubuntu (their target distro) would go to <filename>/usr/bin </filename>. When run for the first time, this script copies some files to the user's home, which include another script that is the ultimate responsible for launching the steam binary, which is also in $HOME.
</para>
<para>
Nix problems and constraints:
<itemizedlist>
<listitem>
<para>
We don't have <filename>/bin/bash</filename> and many scripts point there. Similarly for <filename>/usr/bin/python</filename> .
</para>
</listitem>
<listitem>
<para>
We don't have the dynamic loader in <filename>/lib </filename>.
</para>
</listitem>
<listitem>
<para>
The <filename>steam.sh</filename> script in $HOME can not be patched, as it is checked and rewritten by steam.
</para>
</listitem>
<listitem>
<para>
The steam binary cannot be patched, it's also checked.
</para>
</listitem>
</itemizedlist>
</para>
<para>
The current approach to deploy Steam in NixOS is composing a FHS-compatible chroot environment, as documented <link xlink:href="http://sandervanderburg.blogspot.nl/2013/09/composing-fhs-compatible-chroot.html">here</link>. This allows us to have binaries in the expected paths without disrupting the system, and to avoid patching them to work in a non FHS environment.
</para>
</section>
<section xml:id="sec-steam-play">
<title>How to play</title>
<para>
Use <programlisting>programs.steam.enable = true;</programlisting> if you want to add steam to systemPackages and also enable a few workarrounds aswell as Steam controller support or other Steam supported controllers such as the DualShock 4 or Nintendo Switch Pr.
</para>
</section>
<section xml:id="sec-steam-troub">
<title>Troubleshooting</title>
<para>
<variablelist>
<varlistentry>
<term>
Steam fails to start. What do I do?
</term>
<listitem>
<para>
Try to run
<programlisting>strace steam</programlisting>
to see what is causing steam to fail.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
Using the FOSS Radeon or nouveau (nvidia) drivers
</term>
<listitem>
<itemizedlist>
<listitem>
<para>
The <literal>newStdcpp</literal> parameter was removed since NixOS 17.09 and should not be needed anymore.
</para>
</listitem>
<listitem>
<para>
Steam ships statically linked with a version of libcrypto that conflics with the one dynamically loaded by radeonsi_dri.so. If you get the error
<programlisting>steam.sh: line 713: 7842 Segmentation fault (core dumped)</programlisting>
have a look at <link xlink:href="https://github.com/NixOS/nixpkgs/pull/20269">this pull request</link>.
</para>
</listitem>
</itemizedlist>
</listitem>
</varlistentry>
<varlistentry>
<term>
Java
</term>
<listitem>
<orderedlist>
<listitem>
<para>
There is no java in steam chrootenv by default. If you get a message like
<programlisting>/home/foo/.local/share/Steam/SteamApps/common/towns/towns.sh: line 1: java: command not found</programlisting>
You need to add
<programlisting> steam.override { withJava = true; };</programlisting>
to your configuration.
</para>
</listitem>
</orderedlist>
</listitem>
</varlistentry>
</variablelist>
</para>
</section>
<section xml:id="sec-steam-run">
<title>steam-run</title>
<para>
The FHS-compatible chroot used for steam can also be used to run other linux games that expect a FHS environment. To do it, add
<programlisting>pkgs.(steam.override {
nativeOnly = true;
newStdcpp = true;
}).run</programlisting>
to your configuration, rebuild, and run the game with
<programlisting>steam-run ./foo</programlisting>
</para>
</section>
</section>

View File

@ -0,0 +1,71 @@
# Urxvt {#sec-urxvt}
Urxvt, also known as rxvt-unicode, is a highly customizable terminal emulator.
## Configuring urxvt {#sec-urxvt-conf}
In `nixpkgs`, urxvt is provided by the package `rxvt-unicode`. It can be configured to include your choice of plugins, reducing its closure size from the default configuration which includes all available plugins. To make use of this functionality, use an overlay or directly install an expression that overrides its configuration, such as
```nix
rxvt-unicode.override {
configure = { availablePlugins, ... }: {
plugins = with availablePlugins; [ perls resize-font vtwheel ];
};
}
```
If the `configure` function returns an attrset without the `plugins` attribute, `availablePlugins` will be used automatically.
In order to add plugins but also keep all default plugins installed, it is possible to use the following method:
```nix
rxvt-unicode.override {
configure = { availablePlugins, ... }: {
plugins = (builtins.attrValues availablePlugins) ++ [ custom-plugin ];
};
}
```
To get a list of all the plugins available, open the Nix REPL and run
```ShellSession
$ nix repl
:l <nixpkgs>
map (p: p.name) pkgs.rxvt-unicode.plugins
```
Alternatively, if your shell is bash or zsh and have completion enabled, simply type `nixpkgs.rxvt-unicode.plugins.<tab>`.
In addition to `plugins` the options `extraDeps` and `perlDeps` can be used to install extra packages. `extraDeps` can be used, for example, to provide `xsel` (a clipboard manager) to the clipboard plugin, without installing it globally:
```nix
rxvt-unicode.override {
configure = { availablePlugins, ... }: {
pluginsDeps = [ xsel ];
};
}
```
`perlDeps` is a handy way to provide Perl packages to your custom plugins (in `$HOME/.urxvt/ext`). For example, if you need `AnyEvent` you can do:
```nix
rxvt-unicode.override {
configure = { availablePlugins, ... }: {
perlDeps = with perlPackages; [ AnyEvent ];
};
}
```
## Packaging urxvt plugins {#sec-urxvt-pkg}
Urxvt plugins resides in `pkgs/applications/misc/rxvt-unicode-plugins`. To add a new plugin create an expression in a subdirectory and add the package to the set in `pkgs/applications/misc/rxvt-unicode-plugins/default.nix`.
A plugin can be any kind of derivation, the only requirement is that it should always install perl scripts in `$out/lib/urxvt/perl`. Look for existing plugins for examples.
If the plugin is itself a perl package that needs to be imported from other plugins or scripts, add the following passthrough:
```nix
passthru.perlPackages = [ "self" ];
```
This will make the urxvt wrapper pick up the dependency and set up the perl path accordingly.

View File

@ -1,115 +0,0 @@
<section xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xml:id="sec-urxvt">
<title>Urxvt</title>
<para>
Urxvt, also known as rxvt-unicode, is a highly customizable terminal emulator.
</para>
<section xml:id="sec-urxvt-conf">
<title>Configuring urxvt</title>
<para>
In <literal>nixpkgs</literal>, urxvt is provided by the package
<literal>rxvt-unicode</literal>. It can be configured to include your choice
of plugins, reducing its closure size from the default configuration which
includes all available plugins. To make use of this functionality, use an
overlay or directly install an expression that overrides its configuration,
such as
<programlisting>
rxvt-unicode.override {
configure = { availablePlugins, ... }: {
plugins = with availablePlugins; [ perls resize-font vtwheel ];
};
}
</programlisting>
If the <literal>configure</literal> function returns an attrset without the
<literal>plugins</literal> attribute, <literal>availablePlugins</literal>
will be used automatically.
</para>
<para>
In order to add plugins but also keep all default plugins installed, it is
possible to use the following method:
<programlisting>
rxvt-unicode.override {
configure = { availablePlugins, ... }: {
plugins = (builtins.attrValues availablePlugins) ++ [ custom-plugin ];
};
}
</programlisting>
</para>
<para>
To get a list of all the plugins available, open the Nix REPL and run
<screen>
<prompt>$ </prompt>nix repl
:l &lt;nixpkgs&gt;
map (p: p.name) pkgs.rxvt-unicode.plugins
</screen>
Alternatively, if your shell is bash or zsh and have completion enabled,
simply type <literal>nixpkgs.rxvt-unicode.plugins.&lt;tab&gt;</literal>.
</para>
<para>
In addition to <literal>plugins</literal> the options
<literal>extraDeps</literal> and <literal>perlDeps</literal> can be used
to install extra packages.
<literal>extraDeps</literal> can be used, for example, to provide
<literal>xsel</literal> (a clipboard manager) to the clipboard plugin,
without installing it globally:
<programlisting>
rxvt-unicode.override {
configure = { availablePlugins, ... }: {
pluginsDeps = [ xsel ];
};
}
</programlisting>
<literal>perlDeps</literal> is a handy way to provide Perl packages to
your custom plugins (in <literal>$HOME/.urxvt/ext</literal>). For example,
if you need <literal>AnyEvent</literal> you can do:
<programlisting>
rxvt-unicode.override {
configure = { availablePlugins, ... }: {
perlDeps = with perlPackages; [ AnyEvent ];
};
}
</programlisting>
</para>
</section>
<section xml:id="sec-urxvt-pkg">
<title>Packaging urxvt plugins</title>
<para>
Urxvt plugins resides in
<literal>pkgs/applications/misc/rxvt-unicode-plugins</literal>.
To add a new plugin create an expression in a subdirectory and add the
package to the set in
<literal>pkgs/applications/misc/rxvt-unicode-plugins/default.nix</literal>.
</para>
<para>
A plugin can be any kind of derivation, the only requirement is that it
should always install perl scripts in <literal>$out/lib/urxvt/perl</literal>.
Look for existing plugins for examples.
</para>
<para>
If the plugin is itself a perl package that needs to be imported from
other plugins or scripts, add the following passthrough:
<programlisting>
passthru.perlPackages = [ "self" ];
</programlisting>
This will make the urxvt wrapper pick up the dependency and set up the perl
path accordingly.
</para>
</section>
</section>

View File

@ -0,0 +1,85 @@
# Weechat {#sec-weechat}
Weechat can be configured to include your choice of plugins, reducing its closure size from the default configuration which includes all available plugins. To make use of this functionality, install an expression that overrides its configuration such as
```nix
weechat.override {configure = {availablePlugins, ...}: {
plugins = with availablePlugins; [ python perl ];
}
}
```
If the `configure` function returns an attrset without the `plugins` attribute, `availablePlugins` will be used automatically.
The plugins currently available are `python`, `perl`, `ruby`, `guile`, `tcl` and `lua`.
The python and perl plugins allows the addition of extra libraries. For instance, the `inotify.py` script in `weechat-scripts` requires D-Bus or libnotify, and the `fish.py` script requires `pycrypto`. To use these scripts, use the plugin's `withPackages` attribute:
```nix
weechat.override { configure = {availablePlugins, ...}: {
plugins = with availablePlugins; [
(python.withPackages (ps: with ps; [ pycrypto python-dbus ]))
];
};
}
```
In order to also keep all default plugins installed, it is possible to use the following method:
```nix
weechat.override { configure = { availablePlugins, ... }: {
plugins = builtins.attrValues (availablePlugins // {
python = availablePlugins.python.withPackages (ps: with ps; [ pycrypto python-dbus ]);
});
}; }
```
WeeChat allows to set defaults on startup using the `--run-command`. The `configure` method can be used to pass commands to the program:
```nix
weechat.override {
configure = { availablePlugins, ... }: {
init = ''
/set foo bar
/server add freenode chat.freenode.org
'';
};
}
```
Further values can be added to the list of commands when running `weechat --run-command "your-commands"`.
Additionally it's possible to specify scripts to be loaded when starting `weechat`. These will be loaded before the commands from `init`:
```nix
weechat.override {
configure = { availablePlugins, ... }: {
scripts = with pkgs.weechatScripts; [
weechat-xmpp weechat-matrix-bridge wee-slack
];
init = ''
/set plugins.var.python.jabber.key "val"
'':
};
}
```
In `nixpkgs` there's a subpackage which contains derivations for WeeChat scripts. Such derivations expect a `passthru.scripts` attribute which contains a list of all scripts inside the store path. Furthermore all scripts have to live in `$out/share`. An exemplary derivation looks like this:
```nix
{ stdenv, fetchurl }:
stdenv.mkDerivation {
name = "exemplary-weechat-script";
src = fetchurl {
url = "https://scripts.tld/your-scripts.tar.gz";
sha256 = "...";
};
passthru.scripts = [ "foo.py" "bar.lua" ];
installPhase = ''
mkdir $out/share
cp foo.py $out/share
cp bar.lua $out/share
'';
}
```

View File

@ -1,85 +0,0 @@
<section xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xml:id="sec-weechat">
<title>Weechat</title>
<para>
Weechat can be configured to include your choice of plugins, reducing its closure size from the default configuration which includes all available plugins. To make use of this functionality, install an expression that overrides its configuration such as
<programlisting>weechat.override {configure = {availablePlugins, ...}: {
plugins = with availablePlugins; [ python perl ];
}
}</programlisting>
If the <literal>configure</literal> function returns an attrset without the <literal>plugins</literal> attribute, <literal>availablePlugins</literal> will be used automatically.
</para>
<para>
The plugins currently available are <literal>python</literal>, <literal>perl</literal>, <literal>ruby</literal>, <literal>guile</literal>, <literal>tcl</literal> and <literal>lua</literal>.
</para>
<para>
The python and perl plugins allows the addition of extra libraries. For instance, the <literal>inotify.py</literal> script in weechat-scripts requires D-Bus or libnotify, and the <literal>fish.py</literal> script requires pycrypto. To use these scripts, use the plugin's <literal>withPackages</literal> attribute:
<programlisting>weechat.override { configure = {availablePlugins, ...}: {
plugins = with availablePlugins; [
(python.withPackages (ps: with ps; [ pycrypto python-dbus ]))
];
};
}
</programlisting>
</para>
<para>
In order to also keep all default plugins installed, it is possible to use the following method:
<programlisting>weechat.override { configure = { availablePlugins, ... }: {
plugins = builtins.attrValues (availablePlugins // {
python = availablePlugins.python.withPackages (ps: with ps; [ pycrypto python-dbus ]);
});
}; }
</programlisting>
</para>
<para>
WeeChat allows to set defaults on startup using the <literal>--run-command</literal>. The <literal>configure</literal> method can be used to pass commands to the program:
<programlisting>weechat.override {
configure = { availablePlugins, ... }: {
init = ''
/set foo bar
/server add freenode chat.freenode.org
'';
};
}</programlisting>
Further values can be added to the list of commands when running <literal>weechat --run-command "your-commands"</literal>.
</para>
<para>
Additionally it's possible to specify scripts to be loaded when starting <literal>weechat</literal>. These will be loaded before the commands from <literal>init</literal>:
<programlisting>weechat.override {
configure = { availablePlugins, ... }: {
scripts = with pkgs.weechatScripts; [
weechat-xmpp weechat-matrix-bridge wee-slack
];
init = ''
/set plugins.var.python.jabber.key "val"
'':
};
}</programlisting>
</para>
<para>
In <literal>nixpkgs</literal> there's a subpackage which contains derivations for WeeChat scripts. Such derivations expect a <literal>passthru.scripts</literal> attribute which contains a list of all scripts inside the store path. Furthermore all scripts have to live in <literal>$out/share</literal>. An exemplary derivation looks like this:
<programlisting>{ stdenv, fetchurl }:
stdenv.mkDerivation {
name = "exemplary-weechat-script";
src = fetchurl {
url = "https://scripts.tld/your-scripts.tar.gz";
sha256 = "...";
};
passthru.scripts = [ "foo.py" "bar.lua" ];
installPhase = ''
mkdir $out/share
cp foo.py $out/share
cp bar.lua $out/share
'';
}</programlisting>
</para>
</section>

View File

@ -0,0 +1,34 @@
# X.org {#sec-xorg}
The Nix expressions for the X.org packages reside in `pkgs/servers/x11/xorg/default.nix`. This file is automatically generated from lists of tarballs in an X.org release. As such it should not be modified directly; rather, you should modify the lists, the generator script or the file `pkgs/servers/x11/xorg/overrides.nix`, in which you can override or add to the derivations produced by the generator.
## Katamari Tarballs
X.org upstream releases used to include [katamari](https://en.wiktionary.org/wiki/%E3%81%8B%E3%81%9F%E3%81%BE%E3%82%8A) releases, which included a holistic recommended version for each tarball, up until 7.7. To create a list of tarballs in a katamari release:
```ShellSession
export release="X11R7.7"
export url="mirror://xorg/$release/src/everything/"
cat $(PRINT_PATH=1 nix-prefetch-url $url | tail -n 1) \
| perl -e 'while (<>) { if (/(href|HREF)="([^"]*.bz2)"/) { print "$ENV{'url'}$2\n"; }; }' \
| sort > "tarballs-$release.list"
```
## Individual Tarballs
The upstream release process for [X11R7.8](https://x.org/wiki/Releases/7.8/) does not include a planned katamari. Instead, each component of X.org is released as its own tarball. We maintain `pkgs/servers/x11/xorg/tarballs.list` as a list of tarballs for each individual package. This list includes X.org core libraries and protocol descriptions, extra newer X11 interface libraries, like `xorg.libxcb`, and classic utilities which are largely unused but still available if needed, like `xorg.imake`.
## Generating Nix Expressions
The generator is invoked as follows:
```ShellSession
cd pkgs/servers/x11/xorg
<tarballs.list perl ./generate-expr-from-tarballs.pl
```
For each of the tarballs in the `.list` files, the script downloads it, unpacks it, and searches its `configure.ac` and `*.pc.in` files for dependencies. This information is used to generate `default.nix`. The generator caches downloaded tarballs between runs. Pay close attention to the `NOT FOUND: $NAME` messages at the end of the run, since they may indicate missing dependencies. (Some might be optional dependencies, however.)
## Overriding the Generator
If the expression for a package requires derivation attributes that the generator cannot figure out automatically (say, `patches` or a `postInstall` hook), you should modify `pkgs/servers/x11/xorg/overrides.nix`.

View File

@ -1,34 +0,0 @@
<section xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xml:id="sec-xorg">
<title>X.org</title>
<para>
The Nix expressions for the X.org packages reside in <filename>pkgs/servers/x11/xorg/default.nix</filename>. This file is automatically generated from lists of tarballs in an X.org release. As such it should not be modified directly; rather, you should modify the lists, the generator script or the file <filename>pkgs/servers/x11/xorg/overrides.nix</filename>, in which you can override or add to the derivations produced by the generator.
</para>
<para>
The generator is invoked as follows:
<screen>
<prompt>$ </prompt>cd pkgs/servers/x11/xorg
<prompt>$ </prompt>cat tarballs-7.5.list extra.list old.list \
| perl ./generate-expr-from-tarballs.pl
</screen>
For each of the tarballs in the <filename>.list</filename> files, the script downloads it, unpacks it, and searches its <filename>configure.ac</filename> and <filename>*.pc.in</filename> files for dependencies. This information is used to generate <filename>default.nix</filename>. The generator caches downloaded tarballs between runs. Pay close attention to the <literal>NOT FOUND: <replaceable>name</replaceable></literal> messages at the end of the run, since they may indicate missing dependencies. (Some might be optional dependencies, however.)
</para>
<para>
A file like <filename>tarballs-7.5.list</filename> contains all tarballs in a X.org release. It can be generated like this:
<screen>
<prompt>$ </prompt>export i="mirror://xorg/X11R7.4/src/everything/"
<prompt>$ </prompt>cat $(PRINT_PATH=1 nix-prefetch-url $i | tail -n 1) \
| perl -e 'while (&lt;>) { if (/(href|HREF)="([^"]*.bz2)"/) { print "$ENV{'i'}$2\n"; }; }' \
| sort > tarballs-7.4.list
</screen>
<filename>extra.list</filename> contains libraries that arent part of X.org proper, but are closely related to it, such as <literal>libxcb</literal>. <filename>old.list</filename> contains some packages that were removed from X.org, but are still needed by some people or by other packages (such as <varname>imake</varname>).
</para>
<para>
If the expression for a package requires derivation attributes that the generator cannot figure out automatically (say, <varname>patches</varname> or a <varname>postInstall</varname> hook), you should modify <filename>pkgs/servers/x11/xorg/overrides.nix</filename>.
</para>
</section>

View File

@ -5,6 +5,6 @@
<para>
This chapter describes several special builders.
</para>
<xi:include href="special/fhs-environments.xml" />
<xi:include href="special/mkshell.xml" />
<xi:include href="special/fhs-environments.section.xml" />
<xi:include href="special/mkshell.section.xml" />
</chapter>

View File

@ -0,0 +1,45 @@
# buildFHSUserEnv {#sec-fhs-environments}
`buildFHSUserEnv` provides a way to build and run FHS-compatible lightweight sandboxes. It creates an isolated root with bound `/nix/store`, so its footprint in terms of disk space needed is quite small. This allows one to run software which is hard or unfeasible to patch for NixOS -- 3rd-party source trees with FHS assumptions, games distributed as tarballs, software with integrity checking and/or external self-updated binaries. It uses Linux namespaces feature to create temporary lightweight environments which are destroyed after all child processes exit, without root user rights requirement. Accepted arguments are:
- `name`
Environment name.
- `targetPkgs`
Packages to be installed for the main host's architecture (i.e. x86_64 on x86_64 installations). Along with libraries binaries are also installed.
- `multiPkgs`
Packages to be installed for all architectures supported by a host (i.e. i686 and x86_64 on x86_64 installations). Only libraries are installed by default.
- `extraBuildCommands`
Additional commands to be executed for finalizing the directory structure.
- `extraBuildCommandsMulti`
Like `extraBuildCommands`, but executed only on multilib architectures.
- `extraOutputsToInstall`
Additional derivation outputs to be linked for both target and multi-architecture packages.
- `extraInstallCommands`
Additional commands to be executed for finalizing the derivation with runner script.
- `runScript`
A command that would be executed inside the sandbox and passed all the command line arguments. It defaults to `bash`.
One can create a simple environment using a `shell.nix` like that:
```nix
{ pkgs ? import <nixpkgs> {} }:
(pkgs.buildFHSUserEnv {
name = "simple-x11-env";
targetPkgs = pkgs: (with pkgs;
[ udev
alsaLib
]) ++ (with pkgs.xorg;
[ libX11
libXcursor
libXrandr
]);
multiPkgs = pkgs: (with pkgs;
[ udev
alsaLib
]);
runScript = "bash";
}).env
```
Running `nix-shell` would then drop you into a shell with these libraries and binaries available. You can use this to run closed-source applications which expect FHS structure without hassles: simply change `runScript` to the application path, e.g. `./bin/start.sh` -- relative paths are supported.

View File

@ -1,122 +0,0 @@
<section xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xml:id="sec-fhs-environments">
<title>buildFHSUserEnv</title>
<para>
<function>buildFHSUserEnv</function> provides a way to build and run FHS-compatible lightweight sandboxes. It creates an isolated root with bound <filename>/nix/store</filename>, so its footprint in terms of disk space needed is quite small. This allows one to run software which is hard or unfeasible to patch for NixOS -- 3rd-party source trees with FHS assumptions, games distributed as tarballs, software with integrity checking and/or external self-updated binaries. It uses Linux namespaces feature to create temporary lightweight environments which are destroyed after all child processes exit, without root user rights requirement. Accepted arguments are:
</para>
<variablelist>
<varlistentry>
<term>
<literal>name</literal>
</term>
<listitem>
<para>
Environment name.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<literal>targetPkgs</literal>
</term>
<listitem>
<para>
Packages to be installed for the main host's architecture (i.e. x86_64 on x86_64 installations). Along with libraries binaries are also installed.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<literal>multiPkgs</literal>
</term>
<listitem>
<para>
Packages to be installed for all architectures supported by a host (i.e. i686 and x86_64 on x86_64 installations). Only libraries are installed by default.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<literal>extraBuildCommands</literal>
</term>
<listitem>
<para>
Additional commands to be executed for finalizing the directory structure.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<literal>extraBuildCommandsMulti</literal>
</term>
<listitem>
<para>
Like <literal>extraBuildCommands</literal>, but executed only on multilib architectures.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<literal>extraOutputsToInstall</literal>
</term>
<listitem>
<para>
Additional derivation outputs to be linked for both target and multi-architecture packages.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<literal>extraInstallCommands</literal>
</term>
<listitem>
<para>
Additional commands to be executed for finalizing the derivation with runner script.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<literal>runScript</literal>
</term>
<listitem>
<para>
A command that would be executed inside the sandbox and passed all the command line arguments. It defaults to <literal>bash</literal>.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
One can create a simple environment using a <literal>shell.nix</literal> like that:
</para>
<programlisting><![CDATA[
{ pkgs ? import <nixpkgs> {} }:
(pkgs.buildFHSUserEnv {
name = "simple-x11-env";
targetPkgs = pkgs: (with pkgs;
[ udev
alsaLib
]) ++ (with pkgs.xorg;
[ libX11
libXcursor
libXrandr
]);
multiPkgs = pkgs: (with pkgs;
[ udev
alsaLib
]);
runScript = "bash";
}).env
]]></programlisting>
<para>
Running <literal>nix-shell</literal> would then drop you into a shell with these libraries and binaries available. You can use this to run closed-source applications which expect FHS structure without hassles: simply change <literal>runScript</literal> to the application path, e.g. <filename>./bin/start.sh</filename> -- relative paths are supported.
</para>
</section>

View File

@ -0,0 +1,15 @@
# pkgs.mkShell {#sec-pkgs-mkShell}
`pkgs.mkShell` is a special kind of derivation that is only useful when using it combined with `nix-shell`. It will in fact fail to instantiate when invoked with `nix-build`.
## Usage {#sec-pkgs-mkShell-usage}
```nix
{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
# this will make all the build inputs from hello and gnutar
# available to the shell environment
inputsFrom = with pkgs; [ hello gnutar ];
buildInputs = [ pkgs.gnumake ];
}
```

View File

@ -1,24 +0,0 @@
<section xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xml:id="sec-pkgs-mkShell">
<title>pkgs.mkShell</title>
<para>
<function>pkgs.mkShell</function> is a special kind of derivation that is only useful when using it combined with <command>nix-shell</command>. It will in fact fail to instantiate when invoked with <command>nix-build</command>.
</para>
<section xml:id="sec-pkgs-mkShell-usage">
<title>Usage</title>
<programlisting><![CDATA[
{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
# this will make all the build inputs from hello and gnutar
# available to the shell environment
inputsFrom = with pkgs; [ hello gnutar ];
buildInputs = [ pkgs.gnumake ];
}
]]></programlisting>
</section>
</section>

View File

@ -0,0 +1,52 @@
# Trivial builders {#chap-trivial-builders}
Nixpkgs provides a couple of functions that help with building derivations. The most important one, `stdenv.mkDerivation`, has already been documented above. The following functions wrap `stdenv.mkDerivation`, making it easier to use in certain cases.
## `runCommand` {#trivial-builder-runCommand}
This takes three arguments, `name`, `env`, and `buildCommand`. `name` is just the name that Nix will append to the store path in the same way that `stdenv.mkDerivation` uses its `name` attribute. `env` is an attribute set specifying environment variables that will be set for this derivation. These attributes are then passed to the wrapped `stdenv.mkDerivation`. `buildCommand` specifies the commands that will be run to create this derivation. Note that you will need to create `$out` for Nix to register the command as successful.
An example of using `runCommand` is provided below.
```nix
(import <nixpkgs> {}).runCommand "my-example" {} ''
echo My example command is running
mkdir $out
echo I can write data to the Nix store > $out/message
echo I can also run basic commands like:
echo ls
ls
echo whoami
whoami
echo date
date
''
```
## `runCommandCC` {#trivial-builder-runCommandCC}
This works just like `runCommand`. The only difference is that it also provides a C compiler in `buildCommand`'s environment. To minimize your dependencies, you should only use this if you are sure you will need a C compiler as part of running your command.
## `runCommandLocal` {#trivial-builder-runCommandLocal}
Variant of `runCommand` that forces the derivation to be built locally, it is not substituted. This is intended for very cheap commands (<1s execution time). It saves on the network roundrip and can speed up a build.
::: note
This sets [`allowSubstitutes` to `false`](https://nixos.org/nix/manual/#adv-attr-allowSubstitutes), so only use `runCommandLocal` if you are certain the user will always have a builder for the `system` of the derivation. This should be true for most trivial use cases (e.g. just copying some files to a different location or adding symlinks), because there the `system` is usually the same as `builtins.currentSystem`.
:::
## `writeTextFile`, `writeText`, `writeTextDir`, `writeScript`, `writeScriptBin` {#trivial-builder-writeText}
These functions write `text` to the Nix store. This is useful for creating scripts from Nix expressions. `writeTextFile` takes an attribute set and expects two arguments, `name` and `text`. `name` corresponds to the name used in the Nix store path. `text` will be the contents of the file. You can also set `executable` to true to make this file have the executable bit set.
Many more commands wrap `writeTextFile` including `writeText`, `writeTextDir`, `writeScript`, and `writeScriptBin`. These are convenience functions over `writeTextFile`.
## `symlinkJoin` {#trivial-builder-symlinkJoin}
This can be used to put many derivations into the same directory structure. It works by creating a new derivation and adding symlinks to each of the paths listed. It expects two arguments, `name`, and `paths`. `name` is the name used in the Nix store path for the created derivation. `paths` is a list of paths that will be symlinked. These paths can be to Nix store derivations or any other subdirectory contained within.

View File

@ -1,90 +0,0 @@
<chapter xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xml:id="chap-trivial-builders">
<title>Trivial builders</title>
<para>
Nixpkgs provides a couple of functions that help with building derivations. The most important one, <function>stdenv.mkDerivation</function>, has already been documented above. The following functions wrap <function>stdenv.mkDerivation</function>, making it easier to use in certain cases.
</para>
<variablelist>
<varlistentry xml:id="trivial-builder-runCommand">
<term>
<literal>runCommand</literal>
</term>
<listitem>
<para>
This takes three arguments, <literal>name</literal>, <literal>env</literal>, and <literal>buildCommand</literal>. <literal>name</literal> is just the name that Nix will append to the store path in the same way that <literal>stdenv.mkDerivation</literal> uses its <literal>name</literal> attribute. <literal>env</literal> is an attribute set specifying environment variables that will be set for this derivation. These attributes are then passed to the wrapped <literal>stdenv.mkDerivation</literal>. <literal>buildCommand</literal> specifies the commands that will be run to create this derivation. Note that you will need to create <literal>$out</literal> for Nix to register the command as successful.
</para>
<para>
An example of using <literal>runCommand</literal> is provided below.
</para>
<programlisting>
(import &lt;nixpkgs&gt; {}).runCommand "my-example" {} ''
echo My example command is running
mkdir $out
echo I can write data to the Nix store > $out/message
echo I can also run basic commands like:
echo ls
ls
echo whoami
whoami
echo date
date
''
</programlisting>
</listitem>
</varlistentry>
<varlistentry xml:id="trivial-builder-runCommandCC">
<term>
<literal>runCommandCC</literal>
</term>
<listitem>
<para>
This works just like <literal>runCommand</literal>. The only difference is that it also provides a C compiler in <literal>buildCommand</literal>s environment. To minimize your dependencies, you should only use this if you are sure you will need a C compiler as part of running your command.
</para>
</listitem>
</varlistentry>
<varlistentry xml:id="trivial-builder-runCommandLocal">
<term>
<literal>runCommandLocal</literal>
</term>
<listitem>
<para>
Variant of <literal>runCommand</literal> that forces the derivation to be built locally, it is not substituted. This is intended for very cheap commands (&lt;1s execution time). It saves on the network roundrip and can speed up a build.
</para>
<note><para>
This sets <link xlink:href="https://nixos.org/nix/manual/#adv-attr-allowSubstitutes"><literal>allowSubstitutes</literal> to <literal>false</literal></link>, so only use <literal>runCommandLocal</literal> if you are certain the user will always have a builder for the <literal>system</literal> of the derivation. This should be true for most trivial use cases (e.g. just copying some files to a different location or adding symlinks), because there the <literal>system</literal> is usually the same as <literal>builtins.currentSystem</literal>.
</para></note>
</listitem>
</varlistentry>
<varlistentry xml:id="trivial-builder-writeText">
<term>
<literal>writeTextFile</literal>, <literal>writeText</literal>, <literal>writeTextDir</literal>, <literal>writeScript</literal>, <literal>writeScriptBin</literal>
</term>
<listitem>
<para>
These functions write <literal>text</literal> to the Nix store. This is useful for creating scripts from Nix expressions. <literal>writeTextFile</literal> takes an attribute set and expects two arguments, <literal>name</literal> and <literal>text</literal>. <literal>name</literal> corresponds to the name used in the Nix store path. <literal>text</literal> will be the contents of the file. You can also set <literal>executable</literal> to true to make this file have the executable bit set.
</para>
<para>
Many more commands wrap <literal>writeTextFile</literal> including <literal>writeText</literal>, <literal>writeTextDir</literal>, <literal>writeScript</literal>, and <literal>writeScriptBin</literal>. These are convenience functions over <literal>writeTextFile</literal>.
</para>
</listitem>
</varlistentry>
<varlistentry xml:id="trivial-builder-symlinkJoin">
<term>
<literal>symlinkJoin</literal>
</term>
<listitem>
<para>
This can be used to put many derivations into the same directory structure. It works by creating a new derivation and adding symlinks to each of the paths listed. It expects two arguments, <literal>name</literal>, and <literal>paths</literal>. <literal>name</literal> is the name used in the Nix store path for the created derivation. <literal>paths</literal> is a list of paths that will be symlinked. These paths can be to Nix store derivations or any other subdirectory contained within.
</para>
</listitem>
</varlistentry>
</variablelist>
</chapter>

View File

@ -178,6 +178,15 @@ args.stdenv.mkDerivation (args // {
</programlisting>
</para>
</listitem>
<listitem>
<para>
Prefer using the top-level <varname>lib</varname> over its alias
<literal>stdenv.lib</literal>. <varname>lib</varname> is unrelated to
<varname>stdenv</varname>, and so <literal>stdenv.lib</literal> should only
be used as a convenience alias when developing to avoid having to modify
the function inputs just to test something out.
</para>
</listitem>
</itemizedlist>
</section>
<section xml:id="sec-package-naming">
@ -522,6 +531,16 @@ args.stdenv.mkDerivation (args // {
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
If its a <emphasis>terminal emulator</emphasis>:
</term>
<listitem>
<para>
<filename>applications/terminal-emulators</filename> (e.g. <filename>alacritty</filename> or <filename>rxvt</filename> or <filename>termite</filename>)
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
If its for <emphasis>video playback / editing</emphasis>:

View File

@ -7,8 +7,8 @@
<warning>
<para>
The following section is a draft, and the policy for reviewing is still being discussed in issues such as <link
xlink:href="https://github.com/NixOS/nixpkgs/issues/11166">#11166 </link> and <link
xlink:href="https://github.com/NixOS/nixpkgs/issues/20836">#20836 </link>.
xlink:href="https://github.com/NixOS/nixpkgs/issues/11166">#11166 </link> and <link
xlink:href="https://github.com/NixOS/nixpkgs/issues/20836">#20836 </link>.
</para>
</warning>
<para>
@ -47,18 +47,6 @@
</para>
<itemizedlist>
<listitem>
<para>
Add labels to the pull request. (Requires commit rights)
</para>
<itemizedlist>
<listitem>
<para>
<literal>8.has: package (update)</literal> and any topic label that fit the updated package.
</para>
</listitem>
</itemizedlist>
</listitem>
<listitem>
<para>
Ensure that the package versioning fits the guidelines.
@ -186,18 +174,6 @@
</para>
<itemizedlist>
<listitem>
<para>
Add labels to the pull request. (Requires commit rights)
</para>
<itemizedlist>
<listitem>
<para>
<literal>8.has: package (new)</literal> and any topic label that fit the new package.
</para>
</listitem>
</itemizedlist>
</listitem>
<listitem>
<para>
Ensure that the package versioning is fitting the guidelines.
@ -302,18 +278,6 @@
</para>
<itemizedlist>
<listitem>
<para>
Add labels to the pull request. (Requires commit rights)
</para>
<itemizedlist>
<listitem>
<para>
<literal>8.has: module (update)</literal> and any topic label that fit the module.
</para>
</listitem>
</itemizedlist>
</listitem>
<listitem>
<para>
Ensure that the module maintainers are notified.
@ -406,18 +370,6 @@
</para>
<itemizedlist>
<listitem>
<para>
Add labels to the pull request. (Requires commit rights)
</para>
<itemizedlist>
<listitem>
<para>
<literal>8.has: module (new)</literal> and any topic label that fit the module.
</para>
</listitem>
</itemizedlist>
</listitem>
<listitem>
<para>
Ensure that the module tests, if any, are succeeding.
@ -515,12 +467,8 @@
It is possible for community members that have enough knowledge and experience on a special topic to contribute by merging pull requests.
</para>
<para>
TODO: add the procedure to request merging rights.
</para>
<!--
The following paragraph about how to deal with unactive contributors is just a
The following paragraphs about how to deal with unactive contributors is just a
proposition and should be modified to what the community agrees to be the right
policy.
@ -528,6 +476,10 @@ policy.
three months will have their commit rights revoked.</para>
-->
<para>
Please see the discussion in <link xlink:href="https://github.com/NixOS/nixpkgs/issues/50105">GitHub nixpkgs issue #50105</link> for information on how to proceed to be granted this level of access.
</para>
<para>
In a case a contributor definitively leaves the Nix community, they should create an issue or post on <link
xlink:href="https://discourse.nixos.org">Discourse</link> with references of packages and modules they maintain so the maintainership can be taken over by other contributors.

View File

@ -0,0 +1,217 @@
# Submitting changes {#chap-submitting-changes}
## Making patches {#submitting-changes-making-patches}
- Read [Manual (How to write packages for Nix)](https://nixos.org/nixpkgs/manual/).
- Fork [the Nixpkgs repository](https://github.com/nixos/nixpkgs/) on GitHub.
- Create a branch for your future fix.
- You can make branch from a commit of your local `nixos-version`. That will help you to avoid additional local compilations. Because you will receive packages from binary cache. For example
```ShellSession
$ nixos-version --hash
0998212
$ git checkout 0998212
$ git checkout -b 'fix/pkg-name-update'
```
- Please avoid working directly on the `master` branch.
- Make commits of logical units.
- If you removed pkgs or made some major NixOS changes, write about it in the release notes for the next stable release. For example `nixos/doc/manual/release-notes/rl-2003.xml`.
- Check for unnecessary whitespace with `git diff --check` before committing.
- Format the commit in a following way:
```
(pkg-name | nixos/<module>): (from -> to | init at version | refactor | etc)
Additional information.
```
- Examples:
- `nginx: init at 2.0.1`
- `firefox: 54.0.1 -> 55.0`
- `nixos/hydra: add bazBaz option`
- `nixos/nginx: refactor config generation`
- Test your changes. If you work with
- nixpkgs:
- update pkg
- `nix-env -i pkg-name -f <path to your local nixpkgs folder>`
- add pkg
- Make sure its in `pkgs/top-level/all-packages.nix`
- `nix-env -i pkg-name -f <path to your local nixpkgs folder>`
- _If you dont want to install pkg in you profile_.
- `nix-build -A pkg-attribute-name <path to your local nixpkgs folder>/default.nix` and check results in the folder `result`. It will appear in the same directory where you did `nix-build`.
- If you did `nix-env -i pkg-name` you can do `nix-env -e pkg-name` to uninstall it from your system.
- NixOS and its modules:
- You can add new module to your NixOS configuration file (usually its `/etc/nixos/configuration.nix`). And do `sudo nixos-rebuild test -I nixpkgs=<path to your local nixpkgs folder> --fast`.
- If you have commits `pkg-name: oh, forgot to insert whitespace`: squash commits in this case. Use `git rebase -i`.
- [Rebase](https://git-scm.com/book/en/v2/Git-Branching-Rebasing) your branch against current `master`.
## Submitting changes {#submitting-changes-submitting-changes}
- Push your changes to your fork of nixpkgs.
- Create the pull request
- Follow [the contribution guidelines](https://github.com/NixOS/nixpkgs/blob/master/.github/CONTRIBUTING.md#submitting-changes).
## Submitting security fixes {#submitting-changes-submitting-security-fixes}
Security fixes are submitted in the same way as other changes and thus the same guidelines apply.
If the security fix comes in the form of a patch and a CVE is available, then the name of the patch should be the CVE identifier, so e.g. `CVE-2019-13636.patch` in the case of a patch that is included in the Nixpkgs tree. If a patch is fetched the name needs to be set as well, e.g.:
```nix
(fetchpatch {
name = "CVE-2019-11068.patch";
url = "https://gitlab.gnome.org/GNOME/libxslt/commit/e03553605b45c88f0b4b2980adfbbb8f6fca2fd6.patch";
sha256 = "0pkpb4837km15zgg6h57bncp66d5lwrlvkr73h0lanywq7zrwhj8";
})
```
If a security fix applies to both master and a stable release then, similar to regular changes, they are preferably delivered via master first and cherry-picked to the release branch.
Critical security fixes may by-pass the staging branches and be delivered directly to release branches such as `master` and `release-*`.
## Pull Request Template {#submitting-changes-pull-request-template}
The pull request template helps determine what steps have been made for a contribution so far, and will help guide maintainers on the status of a change. The motivation section of the PR should include any extra details the title does not address and link any existing issues related to the pull request.
When a PR is created, it will be pre-populated with some checkboxes detailed below:
### Tested using sandboxing {#submitting-changes-tested-with-sandbox}
When sandbox builds are enabled, Nix will setup an isolated environment for each build process. It is used to remove further hidden dependencies set by the build environment to improve reproducibility. This includes access to the network during the build outside of `fetch*` functions and files outside the Nix store. Depending on the operating system access to other resources are blocked as well (ex. inter process communication is isolated on Linux); see [sandbox](https://nixos.org/nix/manual/#conf-sandbox) in Nix manual for details.
Sandboxing is not enabled by default in Nix due to a small performance hit on each build. In pull requests for [nixpkgs](https://github.com/NixOS/nixpkgs/) people are asked to test builds with sandboxing enabled (see `Tested using sandboxing` in the pull request template) because in<https://nixos.org/hydra/> sandboxing is also used.
Depending if you use NixOS or other platforms you can use one of the following methods to enable sandboxing **before** building the package:
- **Globally enable sandboxing on NixOS**: add the following to `configuration.nix`
```nix
nix.useSandbox = true;
```
- **Globally enable sandboxing on non-NixOS platforms**: add the following to: `/etc/nix/nix.conf`
```ini
sandbox = true
```
### Built on platform(s) {#submitting-changes-platform-diversity}
Many Nix packages are designed to run on multiple platforms. As such, its important to let the maintainer know which platforms your changes have been tested on. Its not always practical to test a change on all platforms, and is not required for a pull request to be merged. Only check the systems you tested the build on in this section.
### Tested via one or more NixOS test(s) if existing and applicable for the change (look inside nixos/tests) {#submitting-changes-nixos-tests}
Packages with automated tests are much more likely to be merged in a timely fashion because it doesnt require as much manual testing by the maintainer to verify the functionality of the package. If there are existing tests for the package, they should be run to verify your changes do not break the tests. Tests only apply to packages with NixOS modules defined and can only be run on Linux. For more details on writing and running tests, see the [section in the NixOS manual](https://nixos.org/nixos/manual/index.html#sec-nixos-tests).
### Tested compilation of all pkgs that depend on this change using `nixpkgs-review` {#submitting-changes-tested-compilation}
If you are updating a packages version, you can use nixpkgs-review to make sure all packages that depend on the updated package still compile correctly. The `nixpkgs-review` utility can look for and build all dependencies either based on uncommited changes with the `wip` option or specifying a github pull request number.
review changes from pull request number 12345:
```ShellSession
nix run nixpkgs.nixpkgs-review -c nixpkgs-review pr 12345
```
review uncommitted changes:
```ShellSession
nix run nixpkgs.nixpkgs-review -c nixpkgs-review wip
```
review changes from last commit:
```ShellSession
nix run nixpkgs.nixpkgs-review -c nixpkgs-review rev HEAD
```
### Tested execution of all binary files (usually in `./result/bin/`) {#submitting-changes-tested-execution}
Its important to test any executables generated by a build when you change or create a package in nixpkgs. This can be done by looking in `./result/bin` and running any files in there, or at a minimum, the main executable for the package. For example, if you make a change to texlive, you probably would only check the binaries associated with the change you made rather than testing all of them.
### Meets Nixpkgs contribution standards {#submitting-changes-contribution-standards}
The last checkbox is fits [CONTRIBUTING.md](https://github.com/NixOS/nixpkgs/blob/master/.github/CONTRIBUTING.md). The contributing document has detailed information on standards the Nix community has for commit messages, reviews, licensing of contributions you make to the project, etc\... Everyone should read and understand the standards the community has for contributing before submitting a pull request.
## Hotfixing pull requests {#submitting-changes-hotfixing-pull-requests}
- Make the appropriate changes in you branch.
- Dont create additional commits, do
- `git rebase -i`
- `git push --force` to your branch.
## Commit policy {#submitting-changes-commit-policy}
- Commits must be sufficiently tested before being merged, both for the master and staging branches.
- Hydra builds for master and staging should not be used as testing platform, its a build farm for changes that have been already tested.
- When changing the bootloader installation process, extra care must be taken. Grub installations cannot be rolled back, hence changes may break peoples installations forever. For any non-trivial change to the bootloader please file a PR asking for review, especially from \@edolstra.
```{.graphviz caption="Staging workflow"}
digraph {
"small changes" [shape=none]
"mass-rebuilds and other large changes" [shape=none]
"critical security fixes" [shape=none]
"broken staging-next fixes" [shape=none]
"small changes" -> master
"mass-rebuilds and other large changes" -> staging
"critical security fixes" -> master
"broken staging-next fixes" -> "staging-next"
"staging-next" -> master [color="#E85EB0"] [label="stabilization ends"] [fontcolor="#E85EB0"]
"staging" -> "staging-next" [color="#E85EB0"] [label="stabilization starts"] [fontcolor="#E85EB0"]
master -> "staging-next" -> staging [color="#5F5EE8"] [label="every six hours/any time"] [fontcolor="#5F5EE8"]
}
```
### Master branch {#submitting-changes-master-branch}
The `master` branch is the main development branch. It should only see non-breaking commits that do not cause mass rebuilds.
### Staging branch {#submitting-changes-staging-branch}
The `staging` branch is a development branch where mass-rebuilds go. It should only see non-breaking mass-rebuild commits. That means it is not to be used for testing, and changes must have been well tested already. If the branch is already in a broken state, please refrain from adding extra new breakages.
### Staging-next branch {#submitting-changes-staging-next-branch}
The `staging-next` branch is for stabilizing mass-rebuilds submitted to the `staging` branch prior to merging them into `master`. Mass-rebuilds should go via the `staging` branch. It should only see non-breaking commits that are fixing issues blocking it from being merged into the `master ` branch.
If the branch is already in a broken state, please refrain from adding extra new breakages. Stabilize it for a few days and then merge into master.
### Stable release branches {#submitting-changes-stable-release-branches}
For cherry-picking a commit to a stable release branch (“backporting”), use `git cherry-pick -x <original commit>` so that the original commit id is included in the commit.
Add a reason for the backport by using `git cherry-pick -xe <original commit>` instead when it is not obvious from the original commit message. It is not needed when it's a minor version update that includes security and bug fixes but don't add new features or when the commit fixes an otherwise broken package.
Here is an example of a cherry-picked commit message with good reason description:
```
zfs: Keep trying root import until it works
Works around #11003.
(cherry picked from commit 98b213a11041af39b39473906b595290e2a4e2f9)
Reason: several people cannot boot with ZFS on NVMe
```
Other examples of reasons are:
- Previously the build would fail due to, e.g., `getaddrinfo` not being defined
- The previous download links were all broken
- Crash when starting on some X11 systems

View File

@ -1,455 +0,0 @@
<chapter xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xml:id="chap-submitting-changes">
<title>Submitting changes</title>
<section xml:id="submitting-changes-making-patches">
<title>Making patches</title>
<itemizedlist>
<listitem>
<para>
Read <link xlink:href="https://nixos.org/nixpkgs/manual/">Manual (How to write packages for Nix)</link>.
</para>
</listitem>
<listitem>
<para>
Fork <link xlink:href="https://github.com/nixos/nixpkgs/">the Nixpkgs repository</link> on GitHub.
</para>
</listitem>
<listitem>
<para>
Create a branch for your future fix.
<itemizedlist>
<listitem>
<para>
You can make branch from a commit of your local <command>nixos-version</command>. That will help you to avoid additional local compilations. Because you will receive packages from binary cache. For example
<screen>
<prompt>$ </prompt>nixos-version --hash
0998212
<prompt>$ </prompt>git checkout 0998212
<prompt>$ </prompt>git checkout -b 'fix/pkg-name-update'
</screen>
</para>
</listitem>
<listitem>
<para>
Please avoid working directly on the <command>master</command> branch.
</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para>
Make commits of logical units.
</para>
</listitem>
<listitem>
<para>
If you removed pkgs or made some major NixOS changes, write about it in the release notes for the next stable release. For example <command>nixos/doc/manual/release-notes/rl-2003.xml</command>.
</para>
</listitem>
<listitem>
<para>
Check for unnecessary whitespace with <command>git diff --check</command> before committing.
</para>
</listitem>
<listitem>
<para>
Format the commit in a following way:
</para>
<programlisting>
(pkg-name | nixos/&lt;module>): (from -> to | init at version | refactor | etc)
Additional information.
</programlisting>
<itemizedlist>
<listitem>
<para>
Examples:
<itemizedlist>
<listitem>
<para>
<command>nginx: init at 2.0.1</command>
</para>
</listitem>
<listitem>
<para>
<command>firefox: 54.0.1 -> 55.0</command>
</para>
</listitem>
<listitem>
<para>
<command>nixos/hydra: add bazBaz option</command>
</para>
</listitem>
<listitem>
<para>
<command>nixos/nginx: refactor config generation</command>
</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</listitem>
<listitem>
<para>
Test your changes. If you work with
<itemizedlist>
<listitem>
<para>
nixpkgs:
<itemizedlist>
<listitem>
<para>
update pkg ->
<itemizedlist>
<listitem>
<para>
<command>nix-env -i pkg-name -f &lt;path to your local nixpkgs folder&gt;</command>
</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para>
add pkg ->
<itemizedlist>
<listitem>
<para>
Make sure it's in <command>pkgs/top-level/all-packages.nix</command>
</para>
</listitem>
<listitem>
<para>
<command>nix-env -i pkg-name -f &lt;path to your local nixpkgs folder&gt;</command>
</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para>
<emphasis>If you don't want to install pkg in you profile</emphasis>.
<itemizedlist>
<listitem>
<para>
<command>nix-build -A pkg-attribute-name &lt;path to your local nixpkgs folder&gt;/default.nix</command> and check results in the folder <command>result</command>. It will appear in the same directory where you did <command>nix-build</command>.
</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para>
If you did <command>nix-env -i pkg-name</command> you can do <command>nix-env -e pkg-name</command> to uninstall it from your system.
</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para>
NixOS and its modules:
<itemizedlist>
<listitem>
<para>
You can add new module to your NixOS configuration file (usually it's <command>/etc/nixos/configuration.nix</command>). And do <command>sudo nixos-rebuild test -I nixpkgs=&lt;path to your local nixpkgs folder&gt; --fast</command>.
</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para>
If you have commits <command>pkg-name: oh, forgot to insert whitespace</command>: squash commits in this case. Use <command>git rebase -i</command>.
</para>
</listitem>
<listitem>
<para>
<link xlink:href="https://git-scm.com/book/en/v2/Git-Branching-Rebasing">Rebase</link> your branch against current <command>master</command>.
</para>
</listitem>
</itemizedlist>
</section>
<section xml:id="submitting-changes-submitting-changes">
<title>Submitting changes</title>
<itemizedlist>
<listitem>
<para>
Push your changes to your fork of nixpkgs.
</para>
</listitem>
<listitem>
<para>
Create the pull request
</para>
</listitem>
<listitem>
<para>
Follow <link xlink:href="https://github.com/NixOS/nixpkgs/blob/master/.github/CONTRIBUTING.md#submitting-changes">the contribution guidelines</link>.
</para>
</listitem>
</itemizedlist>
</section>
<section xml:id="submitting-changes-submitting-security-fixes">
<title>Submitting security fixes</title>
<para>
Security fixes are submitted in the same way as other changes and thus the same guidelines apply.
</para>
<para>
If the security fix comes in the form of a patch and a CVE is available, then the name of the patch should be the CVE identifier, so e.g. <literal>CVE-2019-13636.patch</literal> in the case of a patch that is included in the Nixpkgs tree. If a patch is fetched the name needs to be set as well, e.g.:
</para>
<programlisting>
(fetchpatch {
name = "CVE-2019-11068.patch";
url = "https://gitlab.gnome.org/GNOME/libxslt/commit/e03553605b45c88f0b4b2980adfbbb8f6fca2fd6.patch";
sha256 = "0pkpb4837km15zgg6h57bncp66d5lwrlvkr73h0lanywq7zrwhj8";
})
</programlisting>
<para>
If a security fix applies to both master and a stable release then, similar to regular changes, they are preferably delivered via master first and cherry-picked to the release branch.
</para>
<para>
Critical security fixes may by-pass the staging branches and be delivered directly to release branches such as <literal>master</literal> and <literal>release-*</literal>.
</para>
</section>
<section xml:id="submitting-changes-pull-request-template">
<title>Pull Request Template</title>
<para>
The pull request template helps determine what steps have been made for a contribution so far, and will help guide maintainers on the status of a change. The motivation section of the PR should include any extra details the title does not address and link any existing issues related to the pull request.
</para>
<para>
When a PR is created, it will be pre-populated with some checkboxes detailed below:
</para>
<section xml:id="submitting-changes-tested-with-sandbox">
<title>Tested using sandboxing</title>
<para>
When sandbox builds are enabled, Nix will setup an isolated environment for each build process. It is used to remove further hidden dependencies set by the build environment to improve reproducibility. This includes access to the network during the build outside of <function>fetch*</function> functions and files outside the Nix store. Depending on the operating system access to other resources are blocked as well (ex. inter process communication is isolated on Linux); see <link
xlink:href="https://nixos.org/nix/manual/#conf-sandbox">sandbox</link> in Nix manual for details.
</para>
<para>
Sandboxing is not enabled by default in Nix due to a small performance hit on each build. In pull requests for <link
xlink:href="https://github.com/NixOS/nixpkgs/">nixpkgs</link> people are asked to test builds with sandboxing enabled (see <literal>Tested using sandboxing</literal> in the pull request template) because in<link
xlink:href="https://nixos.org/hydra/">https://nixos.org/hydra/</link> sandboxing is also used.
</para>
<para>
Depending if you use NixOS or other platforms you can use one of the following methods to enable sandboxing <emphasis role="bold">before</emphasis> building the package:
<itemizedlist>
<listitem>
<para>
<emphasis role="bold">Globally enable sandboxing on NixOS</emphasis>: add the following to <filename>configuration.nix</filename>
<screen>nix.useSandbox = true;</screen>
</para>
</listitem>
<listitem>
<para>
<emphasis role="bold">Globally enable sandboxing on non-NixOS platforms</emphasis>: add the following to: <filename>/etc/nix/nix.conf</filename>
<screen>sandbox = true</screen>
</para>
</listitem>
</itemizedlist>
</para>
</section>
<section xml:id="submitting-changes-platform-diversity">
<title>Built on platform(s)</title>
<para>
Many Nix packages are designed to run on multiple platforms. As such, it's important to let the maintainer know which platforms your changes have been tested on. It's not always practical to test a change on all platforms, and is not required for a pull request to be merged. Only check the systems you tested the build on in this section.
</para>
</section>
<section xml:id="submitting-changes-nixos-tests">
<title>Tested via one or more NixOS test(s) if existing and applicable for the change (look inside nixos/tests)</title>
<para>
Packages with automated tests are much more likely to be merged in a timely fashion because it doesn't require as much manual testing by the maintainer to verify the functionality of the package. If there are existing tests for the package, they should be run to verify your changes do not break the tests. Tests only apply to packages with NixOS modules defined and can only be run on Linux. For more details on writing and running tests, see the <link
xlink:href="https://nixos.org/nixos/manual/index.html#sec-nixos-tests">section in the NixOS manual</link>.
</para>
</section>
<section xml:id="submitting-changes-tested-compilation">
<title>Tested compilation of all pkgs that depend on this change using <command>nixpkgs-review</command></title>
<para>
If you are updating a package's version, you can use nixpkgs-review to make sure all packages that depend on the updated package still compile correctly. The <command>nixpkgs-review</command> utility can look for and build all dependencies either based on uncommited changes with the <literal>wip</literal> option or specifying a github pull request number.
</para>
<para>
review changes from pull request number 12345:
<screen>nix run nixpkgs.nixpkgs-review -c nixpkgs-review pr 12345</screen>
</para>
<para>
review uncommitted changes:
<screen>nix run nixpkgs.nixpkgs-review -c nixpkgs-review wip</screen>
</para>
<para>
review changes from last commit:
<screen>nix run nixpkgs.nixpkgs-review -c nixpkgs-review rev HEAD</screen>
</para>
</section>
<section xml:id="submitting-changes-tested-execution">
<title>Tested execution of all binary files (usually in <filename>./result/bin/</filename>)</title>
<para>
It's important to test any executables generated by a build when you change or create a package in nixpkgs. This can be done by looking in <filename>./result/bin</filename> and running any files in there, or at a minimum, the main executable for the package. For example, if you make a change to <package>texlive</package>, you probably would only check the binaries associated with the change you made rather than testing all of them.
</para>
</section>
<section xml:id="submitting-changes-contribution-standards">
<title>Meets Nixpkgs contribution standards</title>
<para>
The last checkbox is fits <link
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/.github/CONTRIBUTING.md">CONTRIBUTING.md</link>. The contributing document has detailed information on standards the Nix community has for commit messages, reviews, licensing of contributions you make to the project, etc... Everyone should read and understand the standards the community has for contributing before submitting a pull request.
</para>
</section>
</section>
<section xml:id="submitting-changes-hotfixing-pull-requests">
<title>Hotfixing pull requests</title>
<itemizedlist>
<listitem>
<para>
Make the appropriate changes in you branch.
</para>
</listitem>
<listitem>
<para>
Don't create additional commits, do
<itemizedlist>
<listitem>
<para>
<command>git rebase -i</command>
</para>
</listitem>
<listitem>
<para>
<command>git push --force</command> to your branch.
</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</section>
<section xml:id="submitting-changes-commit-policy">
<title>Commit policy</title>
<itemizedlist>
<listitem>
<para>
Commits must be sufficiently tested before being merged, both for the master and staging branches.
</para>
</listitem>
<listitem>
<para>
Hydra builds for master and staging should not be used as testing platform, it's a build farm for changes that have been already tested.
</para>
</listitem>
<listitem>
<para>
When changing the bootloader installation process, extra care must be taken. Grub installations cannot be rolled back, hence changes may break people's installations forever. For any non-trivial change to the bootloader please file a PR asking for review, especially from @edolstra.
</para>
</listitem>
</itemizedlist>
<section xml:id="submitting-changes-master-branch">
<title>Master branch</title>
<para>
The <literal>master</literal> branch is the main development branch.
It should only see non-breaking commits that do not cause mass rebuilds.
</para>
</section>
<section xml:id="submitting-changes-staging-branch">
<title>Staging branch</title>
<para>
The <literal>staging</literal> branch is a development branch where mass-rebuilds go.
It should only see non-breaking mass-rebuild commits.
That means it is not to be used for testing, and changes must have been well tested already.
If the branch is already in a broken state, please refrain from adding extra new breakages.
</para>
</section>
<section xml:id="submitting-changes-staging-next-branch">
<title>Staging-next branch</title>
<para>
The <literal>staging-next</literal> branch is for stabilizing mass-rebuilds submitted to the <literal>staging</literal> branch prior to merging them into <literal>master</literal>.
Mass-rebuilds should go via the <literal>staging</literal> branch.
It should only see non-breaking commits that are fixing issues blocking it from being merged into the <literal>master </literal> branch.
</para>
<para>
If the branch is already in a broken state, please refrain from adding extra new breakages. Stabilize it for a few days and then merge into master.
</para>
</section>
<section xml:id="submitting-changes-stable-release-branches">
<title>Stable release branches</title>
<para>
For cherry-picking a commit to a stable release branch (<quote>backporting</quote>), use <literal>git cherry-pick -x &lt;original commit&gt;</literal> so that the original commit id is included in the commit.
</para>
<para>
Add a reason for the backport by using <literal>git cherry-pick -xe &lt;original commit&gt;</literal> instead when it is not obvious from the original commit message. It is not needed when its a minor version update that includes security and bug fixes but dont add new features or when the commit fixes an otherwise broken package.
</para>
<para>
Here is an example of a cherry-picked commit message with good reason description:
</para>
<screen>
zfs: Keep trying root import until it works
Works around #11003.
(cherry picked from commit 98b213a11041af39b39473906b595290e2a4e2f9)
Reason: several people cannot boot with ZFS on NVMe
</screen>
<para>
Other examples of reasons are:
</para>
<itemizedlist spacing="compact">
<listitem>
<para>
Previously the build would fail due to, e.g., <literal>getaddrinfo</literal> not being defined
</para>
</listitem>
<listitem>
<para>
The previous download links were all broken
</para>
</listitem>
<listitem>
<para>
Crash when starting on some X11 systems
</para>
</listitem>
</itemizedlist>
</section>
</section>
</chapter>

View File

@ -5,10 +5,22 @@ let
in pkgs.stdenv.mkDerivation {
name = "nixpkgs-manual";
buildInputs = with pkgs; [ pandoc libxml2 libxslt zip jing xmlformat ];
nativeBuildInputs = with pkgs; [
pandoc
graphviz
libxml2
libxslt
zip
jing
xmlformat
];
src = ./.;
makeFlags = [
"PANDOC_LUA_FILTERS_DIR=${pkgs.pandoc-lua-filters}/share/pandoc/filters"
];
postPatch = ''
ln -s ${doc-support} ./doc-support/result
'';

View File

@ -1,9 +1,4 @@
---
title: Agda
author: Alex Rice (alexarice)
date: 2020-01-06
---
# Agda
# Agda {#agda}
## How to use Agda

View File

@ -1,9 +1,4 @@
---
title: Android
author: Sander van der Burg
date: 2018-11-18
---
# Android
# Android {#android}
The Android build environment provides three major features and a number of
supporting features.
@ -18,21 +13,19 @@ with import <nixpkgs> {};
let
androidComposition = androidenv.composeAndroidPackages {
toolsVersion = "25.2.5";
platformToolsVersion = "27.0.1";
buildToolsVersions = [ "27.0.3" ];
toolsVersion = "26.1.1";
platformToolsVersion = "30.0.5";
buildToolsVersions = [ "30.0.3" ];
includeEmulator = false;
emulatorVersion = "27.2.0";
platformVersions = [ "24" ];
emulatorVersion = "30.3.4";
platformVersions = [ "28" "29" "30" ];
includeSources = false;
includeDocs = false;
includeSystemImages = false;
systemImageTypes = [ "default" ];
abiVersions = [ "armeabi-v7a" ];
lldbVersions = [ "2.0.2558144" ];
cmakeVersions = [ "3.6.4111459" ];
includeNDK = false;
ndkVersion = "16.1.4479499";
systemImageTypes = [ "google_apis_playstore" ];
abiVersions = [ "armeabi-v7a" "arm64-v8a" ];
cmakeVersions = [ "3.10.2" ];
includeNDK = true;
ndkVersion = "22.0.7026061";
useGoogleAPIs = false;
useGoogleTVAddOns = false;
includeExtras = [
@ -51,13 +44,11 @@ The following parameters are supported:
* `toolsVersion`, specifies the version of the tools package to use
* `platformsToolsVersion` specifies the version of the `platform-tools` plugin
* `buildToolsVersion` specifies the versions of the `build-tools` plugins to
* `buildToolsVersions` specifies the versions of the `build-tools` plugins to
use.
* `includeEmulator` specifies whether to deploy the emulator package (`false`
by default). When enabled, the version of the emulator to deploy can be
specified by setting the `emulatorVersion` parameter.
* `includeDocs` specifies whether the documentation catalog should be included.
* `lldbVersions` specifies what LLDB versions should be deployed.
* `cmakeVersions` specifies which CMake versions should be deployed.
* `includeNDK` specifies that the Android NDK bundle should be included.
Defaults to: `false`.
@ -87,6 +78,38 @@ For each requested system image we can specify the following options:
Most of the function arguments have reasonable default settings.
You can specify license names:
* `extraLicenses` is a list of of license names.
You can get these names from repo.json or `querypackages.sh licenses`. The SDK
license (`android-sdk-license`) is accepted for you if you set accept_license
to true. If you are doing something like working with preview SDKs, you will
want to add `android-sdk-preview-license` or whichever license applies here.
Additionally, you can override the repositories that composeAndroidPackages will
pull from:
* `repoJson` specifies a path to a generated repo.json file. You can generate this
by running `generate.sh`, which in turn will call into `mkrepo.rb`.
* `repoXmls` is an attribute set containing paths to repo XML files. If specified,
it takes priority over `repoJson`, and will trigger a local build writing out a
repo.json to the Nix store based on the given repository XMLs.
```nix
repoXmls = {
packages = [ ./xml/repository2-1.xml ];
images = [
./xml/android-sys-img2-1.xml
./xml/android-tv-sys-img2-1.xml
./xml/android-wear-sys-img2-1.xml
./xml/android-wear-cn-sys-img2-1.xml
./xml/google_apis-sys-img2-1.xml
./xml/google_apis_playstore-sys-img2-1.xml
];
addons = [ ./xml/addon2-1.xml ];
};
```
When building the above expression with:
```bash
@ -109,8 +132,8 @@ in
androidComposition.platform-tools
```
Using predefine Android package compositions
--------------------------------------------
Using predefined Android package compositions
---------------------------------------------
In addition to composing an Android package set manually, it is also possible
to use a predefined composition that contains all basic packages for a specific
Android version, such as version 9.0 (API-level 28).
@ -214,27 +237,104 @@ androidenv.emulateApp {
In addition to prebuilt APKs, you can also bind the APK parameter to a
`buildApp {}` function invocation shown in the previous example.
Notes on environment variables in Android projects
--------------------------------------------------
* `ANDROID_SDK_ROOT` should point to the Android SDK. In your Nix expressions, this should be
`${androidComposition.androidsdk}/libexec/android-sdk`. Note that `ANDROID_HOME` is deprecated,
but if you rely on tools that need it, you can export it too.
* `ANDROID_NDK_ROOT` should point to the Android NDK, if you're doing NDK development.
In your Nix expressions, this should be `${ANDROID_SDK_ROOT}/ndk-bundle`.
If you are running the Android Gradle plugin, you need to export GRADLE_OPTS to override aapt2
to point to the aapt2 binary in the Nix store as well, or use a FHS environment so the packaged
aapt2 can run. If you don't want to use a FHS environment, something like this should work:
```nix
let
buildToolsVersion = "30.0.3";
# Use buildToolsVersion when you define androidComposition
androidComposition = <...>;
in
pkgs.mkShell rec {
ANDROID_SDK_ROOT = "${androidComposition.androidsdk}/libexec/android-sdk";
ANDROID_NDK_ROOT = "${ANDROID_SDK_ROOT}/ndk-bundle";
# Use the same buildToolsVersion here
GRADLE_OPTS = "-Dorg.gradle.project.android.aapt2FromMavenOverride=${ANDROID_SDK_ROOT}/build-tools/${buildToolsVersion}/aapt2";
}
```
If you are using cmake, you need to add it to PATH in a shell hook or FHS env profile.
The path is suffixed with a build number, but properly prefixed with the version.
So, something like this should suffice:
```nix
let
cmakeVersion = "3.10.2";
# Use cmakeVersion when you define androidComposition
androidComposition = <...>;
in
pkgs.mkShell rec {
ANDROID_SDK_ROOT = "${androidComposition.androidsdk}/libexec/android-sdk";
ANDROID_NDK_ROOT = "${ANDROID_SDK_ROOT}/ndk-bundle";
# Use the same cmakeVersion here
shellHook = ''
export PATH="$(echo "$ANDROID_SDK_ROOT/cmake/${cmakeVersion}".*/bin):$PATH"
'';
}
```
Note that running Android Studio with ANDROID_SDK_ROOT set will automatically write a
`local.properties` file with `sdk.dir` set to $ANDROID_SDK_ROOT if one does not already
exist. If you are using the NDK as well, you may have to add `ndk.dir` to this file.
An example shell.nix that does all this for you is provided in examples/shell.nix.
This shell.nix includes a shell hook that overwrites local.properties with the correct
sdk.dir and ndk.dir values. This will ensure that the SDK and NDK directories will
both be correct when you run Android Studio inside nix-shell.
Notes on improving build.gradle compatibility
---------------------------------------------
Ensure that your buildToolsVersion and ndkVersion match what is declared in androidenv.
If you are using cmake, make sure its declared version is correct too.
Otherwise, you may get cryptic errors from aapt2 and the Android Gradle plugin warning
that it cannot install the build tools because the SDK directory is not writeable.
```gradle
android {
buildToolsVersion "30.0.3"
ndkVersion = "22.0.7026061"
externalNativeBuild {
cmake {
version "3.10.2"
}
}
}
```
Querying the available versions of each plugin
----------------------------------------------
When using any of the previously shown functions, it may be a bit inconvenient
to find out what options are supported, since the Android SDK provides many
plugins.
repo.json provides all the options in one file now.
A shell script in the `pkgs/development/mobile/androidenv/` sub directory can be used to retrieve all
A shell script in the `pkgs/development/mobile/androidenv/` subdirectory can be used to retrieve all
possible options:
```bash
sh ./querypackages.sh packages build-tools
./querypackages.sh packages
```
The above command-line instruction queries all build-tools versions in the
generated `packages.nix` expression.
The above command-line instruction queries all package versions in repo.json.
Updating the generated expressions
----------------------------------
Most of the Nix expressions are generated from XML files that the Android
package manager uses. To update the expressions run the `generate.sh` script
that is stored in the `pkgs/development/mobile/androidenv/` sub directory:
repo.json is generated from XML files that the Android Studio package manager uses.
To update the expressions run the `generate.sh` script that is stored in the
`pkgs/development/mobile/androidenv/` subdirectory:
```bash
./generate.sh

View File

@ -0,0 +1,84 @@
# BEAM Languages (Erlang, Elixir & LFE) {#sec-beam}
## Introduction {#beam-introduction}
In this document and related Nix expressions, we use the term, *BEAM*, to describe the environment. BEAM is the name of the Erlang Virtual Machine and, as far as we're concerned, from a packaging perspective, all languages that run on the BEAM are interchangeable. That which varies, like the build system, is transparent to users of any given BEAM package, so we make no distinction.
## Structure {#beam-structure}
All BEAM-related expressions are available via the top-level `beam` attribute, which includes:
- `interpreters`: a set of compilers running on the BEAM, including multiple Erlang/OTP versions (`beam.interpreters.erlangR19`, etc), Elixir (`beam.interpreters.elixir`) and LFE (`beam.interpreters.lfe`).
- `packages`: a set of package builders (Mix and rebar3), each compiled with a specific Erlang/OTP version, e.g. `beam.packages.erlangR19`.
The default Erlang compiler, defined by `beam.interpreters.erlang`, is aliased as `erlang`. The default BEAM package set is defined by `beam.packages.erlang` and aliased at the top level as `beamPackages`.
To create a package builder built with a custom Erlang version, use the lambda, `beam.packagesWith`, which accepts an Erlang/OTP derivation and produces a package builder similar to `beam.packages.erlang`.
Many Erlang/OTP distributions available in `beam.interpreters` have versions with ODBC and/or Java enabled or without wx (no observer support). For example, there's `beam.interpreters.erlangR22_odbc_javac`, which corresponds to `beam.interpreters.erlangR22` and `beam.interpreters.erlangR22_nox`, which corresponds to `beam.interpreters.erlangR22`.
## Build Tools {#build-tools}
### Rebar3 {#build-tools-rebar3}
We provide a version of Rebar3, under `rebar3`. We also provide a helper to fetch Rebar3 dependencies from a lockfile under `fetchRebar3Deps`.
### Mix & Erlang.mk {#build-tools-other}
Both Mix and Erlang.mk work exactly as expected. There is a bootstrap process that needs to be run for both, however, which is supported by the `buildMix` and `buildErlangMk` derivations, respectively.
## How to Install BEAM Packages {#how-to-install-beam-packages}
BEAM builders are not registered at the top level, simply because they are not relevant to the vast majority of Nix users. To install any of those builders into your profile, refer to them by their attribute path `beamPackages.rebar3`:
```ShellSession
$ nix-env -f "<nixpkgs>" -iA beamPackages.rebar3
```
## Packaging BEAM Applications {#packaging-beam-applications}
### Erlang Applications {#packaging-erlang-applications}
#### Rebar3 Packages {#rebar3-packages}
The Nix function, `buildRebar3`, defined in `beam.packages.erlang.buildRebar3` and aliased at the top level, can be used to build a derivation that understands how to build a Rebar3 project.
If a package needs to compile native code via Rebar3's port compilation mechanism, add `compilePort = true;` to the derivation.
#### Erlang.mk Packages {#erlang-mk-packages}
Erlang.mk functions similarly to Rebar3, except we use `buildErlangMk` instead of `buildRebar3`.
#### Mix Packages {#mix-packages}
Mix functions similarly to Rebar3, except we use `buildMix` instead of `buildRebar3`.
Alternatively, we can use `buildHex` as a shortcut:
## How to Develop {#how-to-develop}
### Creating a Shell {#creating-a-shell}
Usually, we need to create a `shell.nix` file and do our development inside of the environment specified therein. Just install your version of erlang and other interpreter, and then user your normal build tools. As an example with elixir:
```nix
{ pkgs ? import "<nixpkgs"> {} }:
with pkgs;
let
elixir = beam.packages.erlangR22.elixir_1_9;
in
mkShell {
buildInputs = [ elixir ];
ERL_INCLUDE_PATH="${erlang}/lib/erlang/usr/include";
}
```
#### Building in a Shell (for Mix Projects) {#building-in-a-shell}
Using a `shell.nix` as described (see <xref linkend="creating-a-shell"/>) should just work.

View File

@ -1,159 +0,0 @@
<section xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xml:id="sec-beam">
<title>BEAM Languages (Erlang, Elixir &amp; LFE)</title>
<section xml:id="beam-introduction">
<title>Introduction</title>
<para>
In this document and related Nix expressions, we use the term, <emphasis>BEAM</emphasis>, to describe the environment. BEAM is the name of the Erlang Virtual Machine and, as far as we're concerned, from a packaging perspective, all languages that run on the BEAM are interchangeable. That which varies, like the build system, is transparent to users of any given BEAM package, so we make no distinction.
</para>
</section>
<section xml:id="beam-structure">
<title>Structure</title>
<para>
All BEAM-related expressions are available via the top-level <literal>beam</literal> attribute, which includes:
</para>
<itemizedlist>
<listitem>
<para>
<literal>interpreters</literal>: a set of compilers running on the BEAM, including multiple Erlang/OTP versions (<literal>beam.interpreters.erlangR19</literal>, etc), Elixir (<literal>beam.interpreters.elixir</literal>) and LFE (<literal>beam.interpreters.lfe</literal>).
</para>
</listitem>
<listitem>
<para>
<literal>packages</literal>: a set of package builders (Mix and rebar3), each compiled with a specific Erlang/OTP version, e.g. <literal>beam.packages.erlangR19</literal>.
</para>
</listitem>
</itemizedlist>
<para>
The default Erlang compiler, defined by <literal>beam.interpreters.erlang</literal>, is aliased as <literal>erlang</literal>. The default BEAM package set is defined by <literal>beam.packages.erlang</literal> and aliased at the top level as <literal>beamPackages</literal>.
</para>
<para>
To create a package builder built with a custom Erlang version, use the lambda, <literal>beam.packagesWith</literal>, which accepts an Erlang/OTP derivation and produces a package builder similar to <literal>beam.packages.erlang</literal>.
</para>
<para>
Many Erlang/OTP distributions available in <literal>beam.interpreters</literal> have versions with ODBC and/or Java enabled or without wx (no observer support). For example, there's <literal>beam.interpreters.erlangR22_odbc_javac</literal>, which corresponds to <literal>beam.interpreters.erlangR22</literal> and <literal>beam.interpreters.erlangR22_nox</literal>, which corresponds to <literal>beam.interpreters.erlangR22</literal>.
</para>
</section>
<section xml:id="build-tools">
<title>Build Tools</title>
<section xml:id="build-tools-rebar3">
<title>Rebar3</title>
<para>
We provide a version of Rebar3, under <literal>rebar3</literal>. We also provide a helper to fetch Rebar3 dependencies from a lockfile under <literal>fetchRebar3Deps</literal>.
</para>
</section>
<section xml:id="build-tools-other">
<title>Mix &amp; Erlang.mk</title>
<para>
Both Mix and Erlang.mk work exactly as expected. There is a bootstrap process that needs to be run for both, however, which is supported by the <literal>buildMix</literal> and <literal>buildErlangMk</literal> derivations, respectively.
</para>
</section>
</section>
<section xml:id="how-to-install-beam-packages">
<title>How to Install BEAM Packages</title>
<para>
BEAM builders are not registered at the top level, simply because they are not relevant to the vast majority of Nix users.
To install any of those builders into your profile, refer to them by their attribute path <literal>beamPackages.rebar3</literal>:
</para>
<screen>
<prompt>$ </prompt>nix-env -f &quot;&lt;nixpkgs&gt;&quot; -iA beamPackages.rebar3
</screen>
</section>
<section xml:id="packaging-beam-applications">
<title>Packaging BEAM Applications</title>
<section xml:id="packaging-erlang-applications">
<title>Erlang Applications</title>
<section xml:id="rebar3-packages">
<title>Rebar3 Packages</title>
<para>
The Nix function, <literal>buildRebar3</literal>, defined in <literal>beam.packages.erlang.buildRebar3</literal> and aliased at the top level, can be used to build a derivation that understands how to build a Rebar3 project.
</para>
<para>
If a package needs to compile native code via Rebar3's port compilation mechanism, add <literal>compilePort = true;</literal> to the derivation.
</para>
</section>
<section xml:id="erlang-mk-packages">
<title>Erlang.mk Packages</title>
<para>
Erlang.mk functions similarly to Rebar3, except we use <literal>buildErlangMk</literal> instead of <literal>buildRebar3</literal>.
</para>
</section>
<section xml:id="mix-packages">
<title>Mix Packages</title>
<para>
Mix functions similarly to Rebar3, except we use <literal>buildMix</literal> instead of <literal>buildRebar3</literal>.
</para>
<para>
Alternatively, we can use <literal>buildHex</literal> as a shortcut:
</para>
</section>
</section>
</section>
<section xml:id="how-to-develop">
<title>How to Develop</title>
<section xml:id="creating-a-shell">
<title>Creating a Shell</title>
<para>
Usually, we need to create a <literal>shell.nix</literal> file and do our development inside of the environment specified therein. Just install your version of erlang and other interpreter, and then user your normal build tools.
As an example with elixir:
</para>
<programlisting>
{ pkgs ? import &quot;&lt;nixpkgs&quot;&gt; {} }:
with pkgs;
let
elixir = beam.packages.erlangR22.elixir_1_9;
in
mkShell {
buildInputs = [ elixir ];
ERL_INCLUDE_PATH="${erlang}/lib/erlang/usr/include";
}
</programlisting>
<section xml:id="building-in-a-shell">
<title>Building in a Shell (for Mix Projects)</title>
<para>
Using a <literal>shell.nix</literal> as described (see <xref
linkend="creating-a-shell"/>) should just work.
</para>
</section>
</section>
</section>
</section>

View File

@ -0,0 +1,158 @@
# Bower {#sec-bower}
[Bower](https://bower.io) is a package manager for web site front-end components. Bower packages (comprising of build artefacts and sometimes sources) are stored in `git` repositories, typically on Github. The package registry is run by the Bower team with package metadata coming from the `bower.json` file within each package.
The end result of running Bower is a `bower_components` directory which can be included in the web app's build process.
Bower can be run interactively, by installing `nodePackages.bower`. More interestingly, the Bower components can be declared in a Nix derivation, with the help of `nodePackages.bower2nix`.
## bower2nix usage {#ssec-bower2nix-usage}
Suppose you have a `bower.json` with the following contents:
### Example bower.json {#ex-bowerJson}
```json
"name": "my-web-app",
"dependencies": {
"angular": "~1.5.0",
"bootstrap": "~3.3.6"
}
```
Running `bower2nix` will produce something like the following output:
```nix
{ fetchbower, buildEnv }:
buildEnv { name = "bower-env"; ignoreCollisions = true; paths = [
(fetchbower "angular" "1.5.3" "~1.5.0" "1749xb0firxdra4rzadm4q9x90v6pzkbd7xmcyjk6qfza09ykk9y")
(fetchbower "bootstrap" "3.3.6" "~3.3.6" "1vvqlpbfcy0k5pncfjaiskj3y6scwifxygfqnw393sjfxiviwmbv")
(fetchbower "jquery" "2.2.2" "1.9.1 - 2" "10sp5h98sqwk90y4k6hbdviwqzvzwqf47r3r51pakch5ii2y7js1")
];
```
Using the `bower2nix` command line arguments, the output can be redirected to a file. A name like `bower-packages.nix` would be fine.
The resulting derivation is a union of all the downloaded Bower packages (and their dependencies). To use it, they still need to be linked together by Bower, which is where `buildBowerComponents` is useful.
## buildBowerComponents function {#ssec-build-bower-components}
The function is implemented in [pkgs/development/bower-modules/generic/default.nix](https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/bower-modules/generic/default.nix).
### Example buildBowerComponents {#ex-buildBowerComponents}
```{=docbook}
<programlisting language="nix">
bowerComponents = buildBowerComponents {
name = "my-web-app";
generated = ./bower-packages.nix; <co xml:id="ex-buildBowerComponents-1" />
src = myWebApp; <co xml:id="ex-buildBowerComponents-2" />
};
</programlisting>
```
In ["buildBowerComponents" example](#ex-buildBowerComponents) the following arguments are of special significance to the function:
```{=docbook}
<calloutlist>
<callout arearefs="ex-buildBowerComponents-1">
<para>
<varname>generated</varname> specifies the file which was created by <command>bower2nix</command>.
</para>
</callout>
<callout arearefs="ex-buildBowerComponents-2">
<para>
<varname>src</varname> is your project's sources. It needs to contain a <filename>bower.json</filename> file.
</para>
</callout>
</calloutlist>
```
`buildBowerComponents` will run Bower to link together the output of `bower2nix`, resulting in a `bower_components` directory which can be used.
Here is an example of a web frontend build process using `gulp`. You might use `grunt`, or anything else.
### Example build script (gulpfile.js) {#ex-bowerGulpFile}
```javascript
var gulp = require('gulp');
gulp.task('default', [], function () {
gulp.start('build');
});
gulp.task('build', [], function () {
console.log("Just a dummy gulp build");
gulp
.src(["./bower_components/**/*"])
.pipe(gulp.dest("./gulpdist/"));
});
```
### Example Full example — default.nix {#ex-buildBowerComponentsDefaultNix}
```{=docbook}
<programlisting language="nix">
{ myWebApp ? { outPath = ./.; name = "myWebApp"; }
, pkgs ? import &lt;nixpkgs&gt; {}
}:
pkgs.stdenv.mkDerivation {
name = "my-web-app-frontend";
src = myWebApp;
buildInputs = [ pkgs.nodePackages.gulp ];
bowerComponents = pkgs.buildBowerComponents { <co xml:id="ex-buildBowerComponentsDefault-1" />
name = "my-web-app";
generated = ./bower-packages.nix;
src = myWebApp;
};
buildPhase = ''
cp --reflink=auto --no-preserve=mode -R $bowerComponents/bower_components . <co xml:id="ex-buildBowerComponentsDefault-2" />
export HOME=$PWD <co xml:id="ex-buildBowerComponentsDefault-3" />
${pkgs.nodePackages.gulp}/bin/gulp build <co xml:id="ex-buildBowerComponentsDefault-4" />
'';
installPhase = "mv gulpdist $out";
}
</programlisting>
```
A few notes about [Full example — `default.nix`](#ex-buildBowerComponentsDefaultNix):
```{=docbook}
<calloutlist>
<callout arearefs="ex-buildBowerComponentsDefault-1">
<para>
The result of <varname>buildBowerComponents</varname> is an input to the frontend build.
</para>
</callout>
<callout arearefs="ex-buildBowerComponentsDefault-2">
<para>
Whether to symlink or copy the <filename>bower_components</filename> directory depends on the build tool in use. In this case a copy is used to avoid <command>gulp</command> silliness with permissions.
</para>
</callout>
<callout arearefs="ex-buildBowerComponentsDefault-3">
<para>
<command>gulp</command> requires <varname>HOME</varname> to refer to a writeable directory.
</para>
</callout>
<callout arearefs="ex-buildBowerComponentsDefault-4">
<para>
The actual build command. Other tools could be used.
</para>
</callout>
</calloutlist>
```
## Troubleshooting {#ssec-bower2nix-troubleshooting}
### ENOCACHE errors from buildBowerComponents
This means that Bower was looking for a package version which doesn't exist in the generated `bower-packages.nix`.
If `bower.json` has been updated, then run `bower2nix` again.
It could also be a bug in `bower2nix` or `fetchbower`. If possible, try reformulating the version specification in `bower.json`.

View File

@ -1,196 +0,0 @@
<section xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xml:id="sec-bower">
<title>Bower</title>
<para>
<link xlink:href="http://bower.io">Bower</link> is a package manager for web site front-end components. Bower packages (comprising of build artefacts and sometimes sources) are stored in <command>git</command> repositories, typically on Github. The package registry is run by the Bower team with package metadata coming from the <filename>bower.json</filename> file within each package.
</para>
<para>
The end result of running Bower is a <filename>bower_components</filename> directory which can be included in the web app's build process.
</para>
<para>
Bower can be run interactively, by installing <varname>nodePackages.bower</varname>. More interestingly, the Bower components can be declared in a Nix derivation, with the help of <varname>nodePackages.bower2nix</varname>.
</para>
<section xml:id="ssec-bower2nix-usage">
<title><command>bower2nix</command> usage</title>
<para>
Suppose you have a <filename>bower.json</filename> with the following contents:
<example xml:id="ex-bowerJson">
<title><filename>bower.json</filename></title>
<programlisting language="json">
<![CDATA[{
"name": "my-web-app",
"dependencies": {
"angular": "~1.5.0",
"bootstrap": "~3.3.6"
}
}]]>
</programlisting>
</example>
</para>
<para>
Running <command>bower2nix</command> will produce something like the following output:
<programlisting language="nix">
<![CDATA[{ fetchbower, buildEnv }:
buildEnv { name = "bower-env"; ignoreCollisions = true; paths = [
(fetchbower "angular" "1.5.3" "~1.5.0" "1749xb0firxdra4rzadm4q9x90v6pzkbd7xmcyjk6qfza09ykk9y")
(fetchbower "bootstrap" "3.3.6" "~3.3.6" "1vvqlpbfcy0k5pncfjaiskj3y6scwifxygfqnw393sjfxiviwmbv")
(fetchbower "jquery" "2.2.2" "1.9.1 - 2" "10sp5h98sqwk90y4k6hbdviwqzvzwqf47r3r51pakch5ii2y7js1")
]; }]]>
</programlisting>
</para>
<para>
Using the <command>bower2nix</command> command line arguments, the output can be redirected to a file. A name like <filename>bower-packages.nix</filename> would be fine.
</para>
<para>
The resulting derivation is a union of all the downloaded Bower packages (and their dependencies). To use it, they still need to be linked together by Bower, which is where <varname>buildBowerComponents</varname> is useful.
</para>
</section>
<section xml:id="ssec-build-bower-components">
<title><varname>buildBowerComponents</varname> function</title>
<para>
The function is implemented in <link xlink:href="https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/bower-modules/generic/default.nix"> <filename>pkgs/development/bower-modules/generic/default.nix</filename></link>. Example usage:
<example xml:id="ex-buildBowerComponents">
<title>buildBowerComponents</title>
<programlisting language="nix">
bowerComponents = buildBowerComponents {
name = "my-web-app";
generated = ./bower-packages.nix; <co xml:id="ex-buildBowerComponents-1" />
src = myWebApp; <co xml:id="ex-buildBowerComponents-2" />
};
</programlisting>
</example>
</para>
<para>
In <xref linkend="ex-buildBowerComponents" />, the following arguments are of special significance to the function:
<calloutlist>
<callout arearefs="ex-buildBowerComponents-1">
<para>
<varname>generated</varname> specifies the file which was created by <command>bower2nix</command>.
</para>
</callout>
<callout arearefs="ex-buildBowerComponents-2">
<para>
<varname>src</varname> is your project's sources. It needs to contain a <filename>bower.json</filename> file.
</para>
</callout>
</calloutlist>
</para>
<para>
<varname>buildBowerComponents</varname> will run Bower to link together the output of <command>bower2nix</command>, resulting in a <filename>bower_components</filename> directory which can be used.
</para>
<para>
Here is an example of a web frontend build process using <command>gulp</command>. You might use <command>grunt</command>, or anything else.
</para>
<example xml:id="ex-bowerGulpFile">
<title>Example build script (<filename>gulpfile.js</filename>)</title>
<programlisting language="javascript">
<![CDATA[var gulp = require('gulp');
gulp.task('default', [], function () {
gulp.start('build');
});
gulp.task('build', [], function () {
console.log("Just a dummy gulp build");
gulp
.src(["./bower_components/**/*"])
.pipe(gulp.dest("./gulpdist/"));
});]]>
</programlisting>
</example>
<example xml:id="ex-buildBowerComponentsDefaultNix">
<title>Full example — <filename>default.nix</filename></title>
<programlisting language="nix">
{ myWebApp ? { outPath = ./.; name = "myWebApp"; }
, pkgs ? import &lt;nixpkgs&gt; {}
}:
pkgs.stdenv.mkDerivation {
name = "my-web-app-frontend";
src = myWebApp;
buildInputs = [ pkgs.nodePackages.gulp ];
bowerComponents = pkgs.buildBowerComponents { <co xml:id="ex-buildBowerComponentsDefault-1" />
name = "my-web-app";
generated = ./bower-packages.nix;
src = myWebApp;
};
buildPhase = ''
cp --reflink=auto --no-preserve=mode -R $bowerComponents/bower_components . <co xml:id="ex-buildBowerComponentsDefault-2" />
export HOME=$PWD <co xml:id="ex-buildBowerComponentsDefault-3" />
${pkgs.nodePackages.gulp}/bin/gulp build <co xml:id="ex-buildBowerComponentsDefault-4" />
'';
installPhase = "mv gulpdist $out";
}
</programlisting>
</example>
<para>
A few notes about <xref linkend="ex-buildBowerComponentsDefaultNix" />:
<calloutlist>
<callout arearefs="ex-buildBowerComponentsDefault-1">
<para>
The result of <varname>buildBowerComponents</varname> is an input to the frontend build.
</para>
</callout>
<callout arearefs="ex-buildBowerComponentsDefault-2">
<para>
Whether to symlink or copy the <filename>bower_components</filename> directory depends on the build tool in use. In this case a copy is used to avoid <command>gulp</command> silliness with permissions.
</para>
</callout>
<callout arearefs="ex-buildBowerComponentsDefault-3">
<para>
<command>gulp</command> requires <varname>HOME</varname> to refer to a writeable directory.
</para>
</callout>
<callout arearefs="ex-buildBowerComponentsDefault-4">
<para>
The actual build command. Other tools could be used.
</para>
</callout>
</calloutlist>
</para>
</section>
<section xml:id="ssec-bower2nix-troubleshooting">
<title>Troubleshooting</title>
<variablelist>
<varlistentry>
<term>
<literal>ENOCACHE</literal> errors from <varname>buildBowerComponents</varname>
</term>
<listitem>
<para>
This means that Bower was looking for a package version which doesn't exist in the generated <filename>bower-packages.nix</filename>.
</para>
<para>
If <filename>bower.json</filename> has been updated, then run <command>bower2nix</command> again.
</para>
<para>
It could also be a bug in <command>bower2nix</command> or <command>fetchbower</command>. If possible, try reformulating the version specification in <filename>bower.json</filename>.
</para>
</listitem>
</varlistentry>
</variablelist>
</section>
</section>

View File

@ -0,0 +1,79 @@
# Coq and coq packages {#sec-language-coq}
## Coq derivation: `coq`
The Coq derivation is overridable through the `coq.override overrides`, where overrides is an attribute set which contains the arguments to override. We recommend overriding either of the following
* `version` (optional, defaults to the latest version of Coq selected for nixpkgs, see `pkgs/top-level/coq-packages` to witness this choice), which follows the conventions explained in the `coqPackages` section below,
* `customOCamlPackage` (optional, defaults to `null`, which lets Coq choose a version automatically), which can be set to any of the ocaml packages attribute of `ocaml-ng` (such as `ocaml-ng.ocamlPackages_4_10` which is the default for Coq 8.11 for example).
* `coq-version` (optional, defaults to the short version e.g. "8.10"), is a version number of the form "x.y" that indicates which Coq's version build behavior to mimic when using a source which is not a release. E.g. `coq.override { version = "d370a9d1328a4e1cdb9d02ee032f605a9d94ec7a"; coq-version = "8.10"; }`.
## Coq packages attribute sets: `coqPackages`
The recommended way of defining a derivation for a Coq library, is to use the `coqPackages.mkCoqDerivation` function, which is essentially a specialization of `mkDerivation` taking into account most of the specifics of Coq libraries. The following attributes are supported:
* `pname` (required) is the name of the package,
* `version` (optional, defaults to `null`), is the version to fetch and build,
this attribute is interpreted in several ways depending on its type and pattern:
* if it is a known released version string, i.e. from the `release` attribute below, the according release is picked, and the `version` attribute of the resulting derivation is set to this release string,
* if it is a majorMinor `"x.y"` prefix of a known released version (as defined above), then the latest `"x.y.z"` known released version is selected (for the ordering given by `versionAtLeast`),
* if it is a path or a string representing an absolute path (i.e. starting with `"/"`), the provided path is selected as a source, and the `version` attribute of the resulting derivation is set to `"dev"`,
* if it is a string of the form `owner:branch` then it tries to download the `branch` of owner `owner` for a project of the same name using the same vcs, and the `version` attribute of the resulting derivation is set to `"dev"`, additionally if the owner is not provided (i.e. if the `owner:` prefix is missing), it defaults to the original owner of the package (see below),
* if it is a string of the form `"#N"`, and the domain is github, then it tries to download the current head of the pull request `#N` from github,
* `defaultVersion` (optional). Coq libraries may be compatible with some specific versions of Coq only. The `defaultVersion` attribute is used when no `version` is provided (or if `version = null`) to select the version of the library to use by default, depending on the context. This selection will mainly depend on a `coq` version number but also possibly on other packages versions (e.g. `mathcomp`). If its value ends up to be `null`, the package is marked for removal in end-user `coqPackages` attribute set.
* `release` (optional, defaults to `{}`), lists all the known releases of the library and for each of them provides an attribute set with at least a `sha256` attribute (you may use the shell command `nix-prefetch-url --unpack <archive-url>` to find it, where `<archive-url>` is for example `https://github.com/owner/repo/archive/version.tar.gz`), each attribute set of the list of releases also takes optional overloading arguments for the fetcher as below (i.e.`domain`, `owner`, `repo`, `rev` assuming the default fetcher is used) and optional overrides for the result of the fetcher (i.e. `version` and `src`).
* `fetcher` (optional, default to a generic fetching mechanism supporting github or gitlab based infrastructures), is a function that takes at least an `owner`, a `repo`, a `rev`, and a `sha256` and returns an attribute set with a `version` and `src`.
* `repo` (optional, defaults to the value of `pname`),
* `owner` (optional, defaults to `"coq-community"`).
* `domain` (optional, defaults to `"github.com"`), domains including the strings `"github"` or `"gitlab"` in their names are automatically supported, otherwise, one must change the `fetcher` argument to support them (cf `pkgs/development/coq-modules/heq/default.nix` for an example),
* `releaseRev` (optional, defaults to `(v: v)`), provides a default mapping from release names to revision hashes/branch names/tags,
* `displayVersion` (optional), provides a way to alter the computation of `name` from `pname`, by explaining how to display version numbers,
* `namePrefix` (optional), provides a way to alter the computation of `name` from `pname`, by explaining which dependencies must occur in `name`,
* `extraBuildInputs` (optional), by default `buildInputs` just contains `coq`, this allows to add more build inputs,
* `mlPlugin` (optional, defaults to `false`). Some extensions (plugins) might require OCaml and sometimes other OCaml packages. Standard dependencies can be added by setting the current option to `true`. For a finer grain control, the `coq.ocamlPackages` attribute can be used in `extraBuildInputs` to depend on the same package set Coq was built against.
* `enableParallelBuilding` (optional, defaults to `true`), since it is activated by default, we provide a way to disable it.
* `extraInstallFlags` (optional), allows to extend `installFlags` which initializes the variable `COQMF_COQLIB` so as to install in the proper subdirectory. Indeed Coq libraries should be installed in `$(out)/lib/coq/${coq.coq-version}/user-contrib/`. Such directories are automatically added to the `$COQPATH` environment variable by the hook defined in the Coq derivation.
* `setCOQBIN` (optional, defaults to `true`), by default, the environment variable `$COQBIN` is set to the current Coq's binary, but one can disable this behavior by setting it to `false`,
* `useMelquiondRemake` (optional, default to `null`) is an attribute set, which, if given, overloads the `preConfigurePhases`, `configureFlags`, `buildPhase`, and `installPhase` attributes of the derivation for a specific use in libraries using `remake` as set up by Guillaume Melquiond for `flocq`, `gappalib`, `interval`, and `coquelicot` (see the corresponding derivation for concrete examples of use of this option). For backward compatibility, the attribute `useMelquiondRemake.logpath` must be set to the logical root of the library (otherwise, one can pass `useMelquiondRemake = {}` to activate this without backward compatibility).
* `dropAttrs`, `keepAttrs`, `dropDerivationAttrs` are all optional and allow to tune which attribute is added or removed from the final call to `mkDerivation`.
It also takes other standard `mkDerivation` attributes, they are added as such, except for `meta` which extends an automatically computed `meta` (where the `platform` is the same as `coq` and the homepage is automatically computed).
Here is a simple package example. It is a pure Coq library, thus it depends on Coq. It builds on the Mathematical Components library, thus it also takes some `mathcomp` derivations as `extraBuildInputs`.
```nix
{ coq, mkCoqDerivation, mathcomp, mathcomp-finmap, mathcomp-bigenough,
lib, version ? null }:
with lib; mkCoqDerivation {
/* namePrefix leads to e.g. `name = coq8.11-mathcomp1.11-multinomials-1.5.2` */
namePrefix = [ "coq" "mathcomp" ];
pname = "multinomials";
owner = "math-comp";
inherit version;
defaultVersion = with versions; switch [ coq.version mathcomp.version ] [
{ cases = [ (range "8.7" "8.12") "1.11.0" ]; out = "1.5.2"; }
{ cases = [ (range "8.7" "8.11") (range "1.8" "1.10") ]; out = "1.5.0"; }
{ cases = [ (range "8.7" "8.10") (range "1.8" "1.10") ]; out = "1.4"; }
{ cases = [ "8.6" (range "1.6" "1.7") ]; out = "1.1"; }
] null;
release = {
"1.5.2".sha256 = "15aspf3jfykp1xgsxf8knqkxv8aav2p39c2fyirw7pwsfbsv2c4s";
"1.5.1".sha256 = "13nlfm2wqripaq671gakz5mn4r0xwm0646araxv0nh455p9ndjs3";
"1.5.0".sha256 = "064rvc0x5g7y1a0nip6ic91vzmq52alf6in2bc2dmss6dmzv90hw";
"1.5.0".rev = "1.5";
"1.4".sha256 = "0vnkirs8iqsv8s59yx1fvg1nkwnzydl42z3scya1xp1b48qkgn0p";
"1.3".sha256 = "0l3vi5n094nx3qmy66hsv867fnqm196r8v605kpk24gl0aa57wh4";
"1.2".sha256 = "1mh1w339dslgv4f810xr1b8v2w7rpx6fgk9pz96q0fyq49fw2xcq";
"1.1".sha256 = "1q8alsm89wkc0lhcvxlyn0pd8rbl2nnxg81zyrabpz610qqjqc3s";
"1.0".sha256 = "1qmbxp1h81cy3imh627pznmng0kvv37k4hrwi2faa101s6bcx55m";
};
propagatedBuildInputs =
[ mathcomp.ssreflect mathcomp.algebra mathcomp-finmap mathcomp-bigenough ];
meta = {
description = "A Coq/SSReflect Library for Monoidal Rings and Multinomials";
license = licenses.cecill-c;
};
}
```

View File

@ -1,52 +0,0 @@
<section xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xml:id="sec-language-coq">
<title>Coq</title>
<para>
Coq libraries should be installed in <literal>$(out)/lib/coq/${coq.coq-version}/user-contrib/</literal>. Such directories are automatically added to the <literal>$COQPATH</literal> environment variable by the hook defined in the Coq derivation.
</para>
<para>
Some extensions (plugins) might require OCaml and sometimes other OCaml packages. The <literal>coq.ocamlPackages</literal> attribute can be used to depend on the same package set Coq was built against.
</para>
<para>
Coq libraries may be compatible with some specific versions of Coq only. The <literal>compatibleCoqVersions</literal> attribute is used to precisely select those versions of Coq that are compatible with this derivation.
</para>
<para>
Here is a simple package example. It is a pure Coq library, thus it depends on Coq. It builds on the Mathematical Components library, thus it also takes <literal>mathcomp</literal> as <literal>buildInputs</literal>. Its <literal>Makefile</literal> has been generated using <literal>coq_makefile</literal> so we only have to set the <literal>$COQLIB</literal> variable at install time.
</para>
<programlisting>
{ stdenv, fetchFromGitHub, coq, mathcomp }:
stdenv.mkDerivation rec {
name = "coq${coq.coq-version}-multinomials-${version}";
version = "1.0";
src = fetchFromGitHub {
owner = "math-comp";
repo = "multinomials";
rev = version;
sha256 = "1qmbxp1h81cy3imh627pznmng0kvv37k4hrwi2faa101s6bcx55m";
};
buildInputs = [ coq ];
propagatedBuildInputs = [ mathcomp ];
installFlags = "COQLIB=$(out)/lib/coq/${coq.coq-version}/";
meta = {
description = "A Coq/SSReflect Library for Monoidal Rings and Multinomials";
inherit (src.meta) homepage;
license = stdenv.lib.licenses.cecill-b;
inherit (coq.meta) platforms;
};
passthru = {
compatibleCoqVersions = v: builtins.elem v [ "8.5" "8.6" "8.7" ];
};
}
</programlisting>
</section>

View File

@ -1,4 +1,4 @@
# Crystal
# Crystal {#crystal}
## Building a Crystal package

View File

@ -64,9 +64,9 @@ $ dotnet --info
The `dotnetCorePackages.sdk_X_Y` is preferred over the old dotnet-sdk as both major and minor version are very important for a dotnet environment. If a given minor version isn't present (or was changed), then this will likely break your ability to build a project.
## dotnetCorePackages.sdk vs dotnetCorePackages.netcore vs dotnetCorePackages.aspnetcore
## dotnetCorePackages.sdk vs vs dotnetCorePackages.net vs dotnetCorePackages.netcore vs dotnetCorePackages.aspnetcore
The `dotnetCorePackages.sdk` contains both a runtime and the full sdk of a given version. The `netcore` and `aspnetcore` packages are meant to serve as minimal runtimes to deploy alongside already built applications.
The `dotnetCorePackages.sdk` contains both a runtime and the full sdk of a given version. The `net`, `netcore` and `aspnetcore` packages are meant to serve as minimal runtimes to deploy alongside already built applications. For runtime versions >= .NET 5 `net` is used while `netcore` is used for older .NET Core runtime version.
## Packaging a Dotnet Application

View File

@ -1,4 +1,4 @@
# Emscripten
# Emscripten {#emscripten}
[Emscripten](https://github.com/kripken/emscripten): An LLVM-to-JavaScript Compiler
@ -60,7 +60,7 @@ See the `zlib` example:
stdenv = pkgs.emscriptenStdenv;
}).overrideDerivation
(old: rec {
buildInputs = old.buildInputs ++ [ pkgconfig ];
buildInputs = old.buildInputs ++ [ pkg-config ];
# we need to reset this setting!
NIX_CFLAGS_COMPILE="";
configurePhase = ''
@ -102,7 +102,7 @@ See the `zlib` example:
echo "================= /testing zlib using node ================="
'';
postPatch = pkgs.stdenv.lib.optionalString pkgs.stdenv.isDarwin ''
postPatch = pkgs.lib.optionalString pkgs.stdenv.isDarwin ''
substituteInPlace configure \
--replace '/usr/bin/libtool' 'ar' \
--replace 'AR="libtool"' 'AR="ar"' \
@ -117,8 +117,8 @@ This `xmlmirror` example features a emscriptenPackage which is defined completel
xmlmirror = pkgs.buildEmscriptenPackage rec {
name = "xmlmirror";
buildInputs = [ pkgconfig autoconf automake libtool gnumake libxml2 nodejs openjdk json_c ];
nativeBuildInputs = [ pkgconfig zlib ];
buildInputs = [ pkg-config autoconf automake libtool gnumake libxml2 nodejs openjdk json_c ];
nativeBuildInputs = [ pkg-config zlib ];
src = pkgs.fetchgit {
url = "https://gitlab.com/odfplugfest/xmlmirror.git";

View File

@ -0,0 +1,186 @@
# GNOME {#sec-language-gnome}
## Packaging GNOME applications {#ssec-gnome-packaging}
Programs in the GNOME universe are written in various languages but they all use GObject-based libraries like GLib, GTK or GStreamer. These libraries are often modular, relying on looking into certain directories to find their modules. However, due to Nixs specific file system organization, this will fail without our intervention. Fortunately, the libraries usually allow overriding the directories through environment variables, either natively or thanks to a patch in nixpkgs. [Wrapping](#fun-wrapProgram) the executables to ensure correct paths are available to the application constitutes a significant part of packaging a modern desktop application. In this section, we will describe various modules needed by such applications, environment variables needed to make the modules load, and finally a script that will do the work for us.
### Settings {#ssec-gnome-settings}
[GSettings](https://developer.gnome.org/gio/stable/GSettings.html) API is often used for storing settings. GSettings schemas are required, to know the type and other metadata of the stored values. GLib looks for `glib-2.0/schemas/gschemas.compiled` files inside the directories of `XDG_DATA_DIRS`.
On Linux, GSettings API is implemented using [dconf](https://wiki.gnome.org/Projects/dconf) backend. You will need to add `dconf` GIO module to `GIO_EXTRA_MODULES` variable, otherwise the `memory` backend will be used and the saved settings will not be persistent.
Last you will need the dconf database D-Bus service itself. You can enable it using `programs.dconf.enable`.
Some applications will also require `gsettings-desktop-schemas` for things like reading proxy configuration or user interface customization. This dependency is often not mentioned by upstream, you should grep for `org.gnome.desktop` and `org.gnome.system` to see if the schemas are needed.
### GdkPixbuf loaders {#ssec-gnome-gdk-pixbuf-loaders}
GTK applications typically use [GdkPixbuf](https://developer.gnome.org/gdk-pixbuf/stable/) to load images. But `gdk-pixbuf` package only supports basic bitmap formats like JPEG, PNG or TIFF, requiring to use third-party loader modules for other formats. This is especially painful since GTK itself includes SVG icons, which cannot be rendered without a loader provided by `librsvg`.
Unlike other libraries mentioned in this section, GdkPixbuf only supports a single value in its controlling environment variable `GDK_PIXBUF_MODULE_FILE`. It is supposed to point to a cache file containing information about the available loaders. Each loader package will contain a `lib/gdk-pixbuf-2.0/2.10.0/loaders.cache` file describing the default loaders in `gdk-pixbuf` package plus the loader contained in the package itself. If you want to use multiple third-party loaders, you will need to create your own cache file manually. Fortunately, this is pretty rare as [not many loaders exist](https://gitlab.gnome.org/federico/gdk-pixbuf-survey/blob/master/src/modules.md).
`gdk-pixbuf` contains [a setup hook](#ssec-gnome-hooks-gdk-pixbuf) that sets `GDK_PIXBUF_MODULE_FILE` from dependencies but as mentioned in further section, it is pretty limited. Loaders should propagate this setup hook.
### Icons {#ssec-gnome-icons}
When an application uses icons, an icon theme should be available in `XDG_DATA_DIRS` during runtime. The package for the default, icon-less [hicolor-icon-theme](https://www.freedesktop.org/wiki/Software/icon-theme/) (should be propagated by every icon theme) contains [a setup hook](#ssec-gnome-hooks-hicolor-icon-theme) that will pick up icon themes from `buildInputs` and pass it to our wrapper. Unfortunately, relying on that would mean every user has to download the theme included in the package expression no matter their preference. For that reason, we leave the installation of icon theme on the user. If you use one of the desktop environments, you probably already have an icon theme installed.
To avoid costly file system access when locating icons, GTK, [as well as Qt](https://woboq.com/blog/qicon-reads-gtk-icon-cache-in-qt57.html), can rely on `icon-theme.cache` files from the themes' top-level directories. These files are generated using `gtk-update-icon-cache`, which is expected to be run whenever an icon is added or removed to an icon theme (typically an application icon into `hicolor` theme) and some programs do indeed run this after icon installation. However, since packages are installed into their own prefix by Nix, this would lead to conflicts. For that reason, `gtk3` provides a [setup hook](#ssec-gnome-hooks-gtk-drop-icon-theme-cache) that will clean the file from installation. Since most applications only ship their own icon that will be loaded on start-up, it should not affect them too much. On the other hand, icon themes are much larger and more widely used so we need to cache them. Because we recommend installing icon themes globally, we will generate the cache files from all packages in a profile using a NixOS module. You can enable the cache generation using `gtk.iconCache.enable` option if your desktop environment does not already do that.
### Packaging icon themes {#ssec-icon-theme-packaging}
Icon themes may inherit from other icon themes. The inheritance is specified using the `Inherits` key in the `index.theme` file distributed with the icon theme. According to the [icon theme specification](https://specifications.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html), icons not provided by the theme are looked for in its parent icon themes. Therefore the parent themes should be installed as dependencies for a more complete experience regarding the icon sets used.
The package `hicolor-icon-theme` provides a setup hook which makes symbolic links for the parent themes into the directory `share/icons` of the current theme directory in the nix store, making sure they can be found at runtime. For that to work the packages providing parent icon themes should be listed as propagated build dependencies, together with `hicolor-icon-theme`.
Also make sure that `icon-theme.cache` is installed for each theme provided by the package, and set `dontDropIconThemeCache` to `true` so that the cache file is not removed by the `gtk3` setup hook.
### GTK Themes {#ssec-gnome-themes}
Previously, a GTK theme needed to be in `XDG_DATA_DIRS`. This is no longer necessary for most programs since GTK incorporated Adwaita theme. Some programs (for example, those designed for [elementary HIG](https://elementary.io/docs/human-interface-guidelines#human-interface-guidelines)) might require a special theme like `pantheon.elementary-gtk-theme`.
### GObject introspection typelibs {#ssec-gnome-typelibs}
[GObject introspection](https://wiki.gnome.org/Projects/GObjectIntrospection) allows applications to use C libraries in other languages easily. It does this through `typelib` files searched in `GI_TYPELIB_PATH`.
### Various plug-ins {#ssec-gnome-plugins}
If your application uses [GStreamer](https://gstreamer.freedesktop.org/) or [Grilo](https://wiki.gnome.org/Projects/Grilo), you should set `GST_PLUGIN_SYSTEM_PATH_1_0` and `GRL_PLUGIN_PATH`, respectively.
## Onto `wrapGAppsHook` {#ssec-gnome-hooks}
Given the requirements above, the package expression would become messy quickly:
```nix
preFixup = ''
for f in $(find $out/bin/ $out/libexec/ -type f -executable); do
wrapProgram "$f" \
--prefix GIO_EXTRA_MODULES : "${getLib dconf}/lib/gio/modules" \
--prefix XDG_DATA_DIRS : "$out/share" \
--prefix XDG_DATA_DIRS : "$out/share/gsettings-schemas/${name}" \
--prefix XDG_DATA_DIRS : "${gsettings-desktop-schemas}/share/gsettings-schemas/${gsettings-desktop-schemas.name}" \
--prefix XDG_DATA_DIRS : "${hicolor-icon-theme}/share" \
--prefix GI_TYPELIB_PATH : "${lib.makeSearchPath "lib/girepository-1.0" [ pango json-glib ]}"
done
'';
```
Fortunately, there is [`wrapGAppsHook`]{#ssec-gnome-hooks-wrapgappshook}. It works in conjunction with other setup hooks that populate environment variables, and it will then wrap all executables in `bin` and `libexec` directories using said variables.
For convenience, it also adds `dconf.lib` for a GIO module implementing a GSettings backend using `dconf`, `gtk3` for GSettings schemas, and `librsvg` for GdkPixbuf loader to the closure. In case you are packaging a program without a graphical interface, you might want to use [`wrapGAppsNoGuiHook`]{#ssec-gnome-hooks-wrapgappsnoguihook}, which runs the same script as `wrapGAppsHook` but does not bring `gtk3` and `librsvg` into the closure.
- `wrapGAppsHook` itself will add the packages `share` directory to `XDG_DATA_DIRS`.
- []{#ssec-gnome-hooks-glib} `glib` setup hook will populate `GSETTINGS_SCHEMAS_PATH` and then `wrapGAppsHook` will prepend it to `XDG_DATA_DIRS`.
- []{#ssec-gnome-hooks-gdk-pixbuf} `gdk-pixbuf` setup hook will populate `GDK_PIXBUF_MODULE_FILE` with the path to biggest `loaders.cache` file from the dependencies containing [GdkPixbuf loaders](ssec-gnome-gdk-pixbuf-loaders). This works fine when there are only two packages containing loaders (`gdk-pixbuf` and e.g. `librsvg`) it will choose the second one, reasonably expecting that it will be bigger since it describes extra loader in addition to the default ones. But when there are more than two loader packages, this logic will break. One possible solution would be constructing a custom cache file for each package containing a program like `services/x11/gdk-pixbuf.nix` NixOS module does. `wrapGAppsHook` copies the `GDK_PIXBUF_MODULE_FILE` environment variable into the produced wrapper.
- []{#ssec-gnome-hooks-gtk-drop-icon-theme-cache} One of `gtk3`s setup hooks will remove `icon-theme.cache` files from packages icon theme directories to avoid conflicts. Icon theme packages should prevent this with `dontDropIconThemeCache = true;`.
- []{#ssec-gnome-hooks-dconf} `dconf.lib` is a dependency of `wrapGAppsHook`, which then also adds it to the `GIO_EXTRA_MODULES` variable.
- []{#ssec-gnome-hooks-hicolor-icon-theme} `hicolor-icon-theme`s setup hook will add icon themes to `XDG_ICON_DIRS` which is prepended to `XDG_DATA_DIRS` by `wrapGAppsHook`.
- []{#ssec-gnome-hooks-gobject-introspection} `gobject-introspection` setup hook populates `GI_TYPELIB_PATH` variable with `lib/girepository-1.0` directories of dependencies, which is then added to wrapper by `wrapGAppsHook`. It also adds `share` directories of dependencies to `XDG_DATA_DIRS`, which is intended to promote GIR files but it also [pollutes the closures](https://github.com/NixOS/nixpkgs/issues/32790) of packages using `wrapGAppsHook`.
::: warning
The setup hook [currently](https://github.com/NixOS/nixpkgs/issues/56943) does not work in expressions with `strictDeps` enabled, like Python packages. In those cases, you will need to disable it with `strictDeps = false;`.
:::
- []{#ssec-gnome-hooks-gst-grl-plugins} Setup hooks of `gst_all_1.gstreamer` and `gnome3.grilo` will populate the `GST_PLUGIN_SYSTEM_PATH_1_0` and `GRL_PLUGIN_PATH` variables, respectively, which will then be added to the wrapper by `wrapGAppsHook`.
You can also pass additional arguments to `makeWrapper` using `gappsWrapperArgs` in `preFixup` hook:
```nix
preFixup = ''
gappsWrapperArgs+=(
# Thumbnailers
--prefix XDG_DATA_DIRS : "${gdk-pixbuf}/share"
--prefix XDG_DATA_DIRS : "${librsvg}/share"
--prefix XDG_DATA_DIRS : "${shared-mime-info}/share"
)
'';
```
## Updating GNOME packages {#ssec-gnome-updating}
Most GNOME package offer [`updateScript`](#var-passthru-updateScript), it is therefore possible to update to latest source tarball by running `nix-shell maintainers/scripts/update.nix --argstr package gnome3.nautilus` or even en masse with `nix-shell maintainers/scripts/update.nix --argstr path gnome3`. Read the packages `NEWS` file to see what changed.
## Frequently encountered issues {#ssec-gnome-common-issues}
#### `GLib-GIO-ERROR **: 06:04:50.903: No GSettings schemas are installed on the system` {#ssec-gnome-common-issues-no-schemas}
There are no schemas available in `XDG_DATA_DIRS`. Temporarily add a random package containing schemas like `gsettings-desktop-schemas` to `buildInputs`. [`glib`](#ssec-gnome-hooks-glib) and [`wrapGAppsHook`](#ssec-gnome-hooks-wrapgappshook) setup hooks will take care of making the schemas available to application and you will see the actual missing schemas with the [next error](#ssec-gnome-common-issues-missing-schema). Or you can try looking through the source code for the actual schemas used.
#### `GLib-GIO-ERROR **: 06:04:50.903: Settings schema org.gnome.foo is not installed` {#ssec-gnome-common-issues-missing-schema}
Package is missing some GSettings schemas. You can find out the package containing the schema with `nix-locate org.gnome.foo.gschema.xml` and let the hooks handle the wrapping as [above](#ssec-gnome-common-issues-no-schemas).
#### When using `wrapGAppsHook` with special derivers you can end up with double wrapped binaries. {#ssec-gnome-common-issues-double-wrapped}
This is because derivers like `python.pkgs.buildPythonApplication` or `qt5.mkDerivation` have setup-hooks automatically added that produce wrappers with makeWrapper. The simplest way to workaround that is to disable the `wrapGAppsHook` automatic wrapping with `dontWrapGApps = true;` and pass the arguments it intended to pass to makeWrapper to another.
In the case of a Python application it could look like:
```nix
python3.pkgs.buildPythonApplication {
pname = "gnome-music";
version = "3.32.2";
nativeBuildInputs = [
wrapGAppsHook
gobject-introspection
...
];
dontWrapGApps = true;
# Arguments to be passed to `makeWrapper`, only used by buildPython*
preFixup = ''
makeWrapperArgs+=("''${gappsWrapperArgs[@]}")
'';
}
```
And for a QT app like:
```nix
mkDerivation {
pname = "calibre";
version = "3.47.0";
nativeBuildInputs = [
wrapGAppsHook
qmake
...
];
dontWrapGApps = true;
# Arguments to be passed to `makeWrapper`, only used by qt5s mkDerivation
preFixup = ''
qtWrapperArgs+=("''${gappsWrapperArgs[@]}")
'';
}
```
#### I am packaging a project that cannot be wrapped, like a library or GNOME Shell extension. {#ssec-gnome-common-issues-unwrappable-package}
You can rely on applications depending on the library setting the necessary environment variables but that is often easy to miss. Instead we recommend to patch the paths in the source code whenever possible. Here are some examples:
- []{#ssec-gnome-common-issues-unwrappable-package-gnome-shell-ext} [Replacing a `GI_TYPELIB_PATH` in GNOME Shell extension](https://github.com/NixOS/nixpkgs/blob/7bb8f05f12ca3cff9da72b56caa2f7472d5732bc/pkgs/desktops/gnome-3/core/gnome-shell-extensions/default.nix#L21-L24) we are using `substituteAll` to include the path to a typelib into a patch.
- []{#ssec-gnome-common-issues-unwrappable-package-gsettings} The following examples are hardcoding GSettings schema paths. To get the schema paths we use the functions
* `glib.getSchemaPath` Takes a nix package attribute as an argument.
* `glib.makeSchemaPath` Takes a package output like `$out` and a derivation name. You should use this if the schemas you need to hardcode are in the same derivation.
[]{#ssec-gnome-common-issues-unwrappable-package-gsettings-vala} [Hard-coding GSettings schema path in Vala plug-in (dynamically loaded library)](https://github.com/NixOS/nixpkgs/blob/7bb8f05f12ca3cff9da72b56caa2f7472d5732bc/pkgs/desktops/pantheon/apps/elementary-files/default.nix#L78-L86) here, `substituteAll` cannot be used since the schema comes from the same package preventing us from pass its path to the function, probably due to a [Nix bug](https://github.com/NixOS/nix/issues/1846).
[]{#ssec-gnome-common-issues-unwrappable-package-gsettings-c} [Hard-coding GSettings schema path in C library](https://github.com/NixOS/nixpkgs/blob/29c120c065d03b000224872251bed93932d42412/pkgs/development/libraries/glib-networking/default.nix#L31-L34) nothing special other than using [Coccinelle patch](https://github.com/NixOS/nixpkgs/pull/67957#issuecomment-527717467) to generate the patch itself.
#### I need to wrap a binary outside `bin` and `libexec` directories. {#ssec-gnome-common-issues-weird-location}
You can manually trigger the wrapping with `wrapGApp` in `preFixup` phase. It takes a path to a program as a first argument; the remaining arguments are passed directly to [`wrapProgram`](#fun-wrapProgram) function.

View File

@ -1,299 +0,0 @@
<section xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="sec-language-gnome">
<title>GNOME</title>
<section xml:id="ssec-gnome-packaging">
<title>Packaging GNOME applications</title>
<para>
Programs in the GNOME universe are written in various languages but they all use GObject-based libraries like GLib, GTK or GStreamer. These libraries are often modular, relying on looking into certain directories to find their modules. However, due to Nixs specific file system organization, this will fail without our intervention. Fortunately, the libraries usually allow overriding the directories through environment variables, either natively or thanks to a patch in nixpkgs. <link xlink:href="#fun-wrapProgram">Wrapping</link> the executables to ensure correct paths are available to the application constitutes a significant part of packaging a modern desktop application. In this section, we will describe various modules needed by such applications, environment variables needed to make the modules load, and finally a script that will do the work for us.
</para>
<section xml:id="ssec-gnome-settings">
<title>Settings</title>
<para>
<link xlink:href="https://developer.gnome.org/gio/stable/GSettings.html">GSettings</link> API is often used for storing settings. GSettings schemas are required, to know the type and other metadata of the stored values. GLib looks for <filename>glib-2.0/schemas/gschemas.compiled</filename> files inside the directories of <envar>XDG_DATA_DIRS</envar>.
</para>
<para>
On Linux, GSettings API is implemented using <link xlink:href="https://wiki.gnome.org/Projects/dconf">dconf</link> backend. You will need to add <literal>dconf</literal> GIO module to <envar>GIO_EXTRA_MODULES</envar> variable, otherwise the <literal>memory</literal> backend will be used and the saved settings will not be persistent.
</para>
<para>
Last you will need the dconf database D-Bus service itself. You can enable it using <option>programs.dconf.enable</option>.
</para>
<para>
Some applications will also require <package>gsettings-desktop-schemas</package> for things like reading proxy configuration or user interface customization. This dependency is often not mentioned by upstream, you should grep for <literal>org.gnome.desktop</literal> and <literal>org.gnome.system</literal> to see if the schemas are needed.
</para>
</section>
<section xml:id="ssec-gnome-icons">
<title>Icons</title>
<para>
When an application uses icons, an icon theme should be available in <envar>XDG_DATA_DIRS</envar> during runtime. The package for the default, icon-less <link xlink:href="https://www.freedesktop.org/wiki/Software/icon-theme/">hicolor-icon-theme</link> (should be propagated by every icon theme) contains <link linkend="ssec-gnome-hooks-hicolor-icon-theme">a setup hook</link> that will pick up icon themes from <literal>buildInputs</literal> and pass it to our wrapper. Unfortunately, relying on that would mean every user has to download the theme included in the package expression no matter their preference. For that reason, we leave the installation of icon theme on the user. If you use one of the desktop environments, you probably already have an icon theme installed.
</para>
<para>
To avoid costly file system access when locating icons, GTK, <link xlink:href="https://woboq.com/blog/qicon-reads-gtk-icon-cache-in-qt57.html">as well as Qt</link>, can rely on <filename>icon-theme.cache</filename> files from the themes top-level directories. These files are generated using <command>gtk-update-icon-cache</command>, which is expected to be run whenever an icon is added or removed to an icon theme (typically an application icon into <literal>hicolor</literal> theme) and some programs do indeed run this after icon installation. However, since packages are installed into their own prefix by Nix, this would lead to conflicts. For that reason, <package>gtk3</package> provides a <link xlink:href="#ssec-gnome-hooks-gtk-drop-icon-theme-cache">setup hook</link> that will clean the file from installation. Since most applications only ship their own icon that will be loaded on start-up, it should not affect them too much. On the other hand, icon themes are much larger and more widely used so we need to cache them. Because we recommend installing icon themes globally, we will generate the cache files from all packages in a profile using a NixOS module. You can enable the cache generation using <option>gtk.iconCache.enable</option> option if your desktop environment does not already do that.
</para>
</section>
<section xml:id="ssec-icon-theme-packaging">
<title>Packaging icon themes</title>
<para>
Icon themes may inherit from other icon themes. The inheritance is specified using the <literal>Inherits</literal> key in the <filename>index.theme</filename> file distributed with the icon theme. According to the <link xlink:href="https://specifications.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html">icon theme specification</link>, icons not provided by the theme are looked for in its parent icon themes. Therefore the parent themes should be installed as dependencies for a more complete experience regarding the icon sets used.
</para>
<para>
The package <package>hicolor-icon-theme</package> provides a setup hook which makes symbolic links for the parent themes into the directory <filename>share/icons</filename> of the current theme directory in the nix store, making sure they can be found at runtime. For that to work the packages providing parent icon themes should be listed as propagated build dependencies, together with <package>hicolor-icon-theme</package>.
</para>
<para>
Also make sure that <filename>icon-theme.cache</filename> is installed for each theme provided by the package, and set <code>dontDropIconThemeCache</code> to <code>true</code> so that the cache file is not removed by the <package>gtk3</package> setup hook.
</para>
</section>
<section xml:id="ssec-gnome-themes">
<title>GTK Themes</title>
<para>
Previously, a GTK theme needed to be in <envar>XDG_DATA_DIRS</envar>. This is no longer necessary for most programs since GTK incorporated Adwaita theme. Some programs (for example, those designed for <link xlink:href="https://elementary.io/docs/human-interface-guidelines#human-interface-guidelines">elementary HIG</link>) might require a special theme like <package>pantheon.elementary-gtk-theme</package>.
</para>
</section>
<section xml:id="ssec-gnome-typelibs">
<title>GObject introspection typelibs</title>
<para>
<link xlink:href="https://wiki.gnome.org/Projects/GObjectIntrospection">GObject introspection</link> allows applications to use C libraries in other languages easily. It does this through <literal>typelib</literal> files searched in <envar>GI_TYPELIB_PATH</envar>.
</para>
</section>
<section xml:id="ssec-gnome-plugins">
<title>Various plug-ins</title>
<para>
If your application uses <link xlink:href="https://gstreamer.freedesktop.org/">GStreamer</link> or <link xlink:href="https://wiki.gnome.org/Projects/Grilo">Grilo</link>, you should set <envar>GST_PLUGIN_SYSTEM_PATH_1_0</envar> and <envar>GRL_PLUGIN_PATH</envar>, respectively.
</para>
</section>
</section>
<section xml:id="ssec-gnome-hooks">
<title>Onto <package>wrapGAppsHook</package></title>
<para>
Given the requirements above, the package expression would become messy quickly:
<programlisting>
preFixup = ''
for f in $(find $out/bin/ $out/libexec/ -type f -executable); do
wrapProgram "$f" \
--prefix GIO_EXTRA_MODULES : "${getLib dconf}/lib/gio/modules" \
--prefix XDG_DATA_DIRS : "$out/share" \
--prefix XDG_DATA_DIRS : "$out/share/gsettings-schemas/${name}" \
--prefix XDG_DATA_DIRS : "${gsettings-desktop-schemas}/share/gsettings-schemas/${gsettings-desktop-schemas.name}" \
--prefix XDG_DATA_DIRS : "${hicolor-icon-theme}/share" \
--prefix GI_TYPELIB_PATH : "${lib.makeSearchPath "lib/girepository-1.0" [ pango json-glib ]}"
done
'';
</programlisting>
Fortunately, there is <package>wrapGAppsHook</package>, that does the wrapping for us. In particular, it works in conjunction with other setup hooks that will populate the variable:
<itemizedlist>
<listitem xml:id="ssec-gnome-hooks-wrapgappshook">
<para>
<package>wrapGAppsHook</package> itself will add the packages <filename>share</filename> directory to <envar>XDG_DATA_DIRS</envar>.
</para>
</listitem>
<listitem xml:id="ssec-gnome-hooks-glib">
<para>
<package>glib</package> setup hook will populate <envar>GSETTINGS_SCHEMAS_PATH</envar> and then <package>wrapGAppsHook</package> will prepend it to <envar>XDG_DATA_DIRS</envar>.
</para>
</listitem>
<listitem xml:id="ssec-gnome-hooks-gtk-drop-icon-theme-cache">
<para>
One of <package>gtk3</package>s setup hooks will remove <filename>icon-theme.cache</filename> files from packages icon theme directories to avoid conflicts. Icon theme packages should prevent this with <code>dontDropIconThemeCache = true;</code>.
</para>
</listitem>
<listitem xml:id="ssec-gnome-hooks-dconf">
<para>
<package>dconf.lib</package> is a dependency of <package>wrapGAppsHook</package>, which then also adds it to the <envar>GIO_EXTRA_MODULES</envar> variable.
</para>
</listitem>
<listitem xml:id="ssec-gnome-hooks-hicolor-icon-theme">
<para>
<package>hicolor-icon-theme</package>s setup hook will add icon themes to <envar>XDG_ICON_DIRS</envar> which is prepended to <envar>XDG_DATA_DIRS</envar> by <package>wrapGAppsHook</package>.
</para>
</listitem>
<listitem xml:id="ssec-gnome-hooks-gobject-introspection">
<para>
<package>gobject-introspection</package> setup hook populates <envar>GI_TYPELIB_PATH</envar> variable with <filename>lib/girepository-1.0</filename> directories of dependencies, which is then added to wrapper by <package>wrapGAppsHook</package>. It also adds <filename>share</filename> directories of dependencies to <envar>XDG_DATA_DIRS</envar>, which is intended to promote GIR files but it also <link xlink:href="https://github.com/NixOS/nixpkgs/issues/32790">pollutes the closures</link> of packages using <package>wrapGAppsHook</package>.
</para>
<warning>
<para>
The setup hook <link xlink:href="https://github.com/NixOS/nixpkgs/issues/56943">currently</link> does not work in expressions with <literal>strictDeps</literal> enabled, like Python packages. In those cases, you will need to disable it with <code>strictDeps = false;</code>.
</para>
</warning>
</listitem>
<listitem xml:id="ssec-gnome-hooks-gst-grl-plugins">
<para>
Setup hooks of <package>gst_all_1.gstreamer</package> and <package>gnome3.grilo</package> will populate the <envar>GST_PLUGIN_SYSTEM_PATH_1_0</envar> and <envar>GRL_PLUGIN_PATH</envar> variables, respectively, which will then be added to the wrapper by <literal>wrapGAppsHook</literal>.
</para>
</listitem>
</itemizedlist>
</para>
<para>
You can also pass additional arguments to <literal>makeWrapper</literal> using <literal>gappsWrapperArgs</literal> in <literal>preFixup</literal> hook:
<programlisting>
preFixup = ''
gappsWrapperArgs+=(
# Thumbnailers
--prefix XDG_DATA_DIRS : "${gdk-pixbuf}/share"
--prefix XDG_DATA_DIRS : "${librsvg}/share"
--prefix XDG_DATA_DIRS : "${shared-mime-info}/share"
)
'';
</programlisting>
</para>
</section>
<section xml:id="ssec-gnome-updating">
<title>Updating GNOME packages</title>
<para>
Most GNOME package offer <link linkend="var-passthru-updateScript"><literal>updateScript</literal></link>, it is therefore possible to update to latest source tarball by running <command>nix-shell maintainers/scripts/update.nix --argstr package gnome3.nautilus</command> or even en masse with <command>nix-shell maintainers/scripts/update.nix --argstr path gnome3</command>. Read the packages <filename>NEWS</filename> file to see what changed.
</para>
</section>
<section xml:id="ssec-gnome-common-issues">
<title>Frequently encountered issues</title>
<variablelist>
<varlistentry xml:id="ssec-gnome-common-issues-no-schemas">
<term>
<computeroutput>GLib-GIO-ERROR **: <replaceable>06:04:50.903</replaceable>: No GSettings schemas are installed on the system</computeroutput>
</term>
<listitem>
<para>
There are no schemas avalable in <envar>XDG_DATA_DIRS</envar>. Temporarily add a random package containing schemas like <package>gsettings-desktop-schemas</package> to <literal>buildInputs</literal>. <link linkend="ssec-gnome-hooks-glib"><package>glib</package></link> and <link linkend="ssec-gnome-hooks-wrapgappshook"><package>wrapGAppsHook</package></link> setup hooks will take care of making the schemas available to application and you will see the actual missing schemas with the <link linkend="ssec-gnome-common-issues-missing-schema">next error</link>. Or you can try looking through the source code for the actual schemas used.
</para>
</listitem>
</varlistentry>
<varlistentry xml:id="ssec-gnome-common-issues-missing-schema">
<term>
<computeroutput>GLib-GIO-ERROR **: <replaceable>06:04:50.903</replaceable>: Settings schema <replaceable>org.gnome.foo</replaceable> is not installed</computeroutput>
</term>
<listitem>
<para>
Package is missing some GSettings schemas. You can find out the package containing the schema with <command>nix-locate <replaceable>org.gnome.foo</replaceable>.gschema.xml</command> and let the hooks handle the wrapping as <link linkend="ssec-gnome-common-issues-no-schemas">above</link>.
</para>
</listitem>
</varlistentry>
<varlistentry xml:id="ssec-gnome-common-issues-double-wrapped">
<term>
When using <package>wrapGAppsHook</package> with special derivers you can end up with double wrapped binaries.
</term>
<listitem>
<para>
This is because derivers like <function>python.pkgs.buildPythonApplication</function> or <function>qt5.mkDerivation</function> have setup-hooks automatically added that produce wrappers with <package>makeWrapper</package>. The simplest way to workaround that is to disable the <package>wrapGAppsHook</package> automatic wrapping with <code>dontWrapGApps = true;</code> and pass the arguments it intended to pass to <package>makeWrapper</package> to another.
</para>
<para>
In the case of a Python application it could look like:
<programlisting>
python3.pkgs.buildPythonApplication {
pname = "gnome-music";
version = "3.32.2";
nativeBuildInputs = [
wrapGAppsHook
gobject-introspection
...
];
dontWrapGApps = true;
# Arguments to be passed to `makeWrapper`, only used by buildPython*
preFixup = ''
makeWrapperArgs+=("''${gappsWrapperArgs[@]}")
'';
}
</programlisting>
And for a QT app like:
<programlisting>
mkDerivation {
pname = "calibre";
version = "3.47.0";
nativeBuildInputs = [
wrapGAppsHook
qmake
...
];
dontWrapGApps = true;
# Arguments to be passed to `makeWrapper`, only used by qt5s mkDerivation
preFixup = ''
qtWrapperArgs+=("''${gappsWrapperArgs[@]}")
'';
}
</programlisting>
</para>
</listitem>
</varlistentry>
<varlistentry xml:id="ssec-gnome-common-issues-unwrappable-package">
<term>
I am packaging a project that cannot be wrapped, like a library or GNOME Shell extension.
</term>
<listitem>
<para>
You can rely on applications depending on the library setting the necessary environment variables but that is often easy to miss. Instead we recommend to patch the paths in the source code whenever possible. Here are some examples:
<itemizedlist>
<listitem xml:id="ssec-gnome-common-issues-unwrappable-package-gnome-shell-ext">
<para>
<link xlink:href="https://github.com/NixOS/nixpkgs/blob/7bb8f05f12ca3cff9da72b56caa2f7472d5732bc/pkgs/desktops/gnome-3/core/gnome-shell-extensions/default.nix#L21-L24">Replacing a <envar>GI_TYPELIB_PATH</envar> in GNOME Shell extension</link> we are using <function>substituteAll</function> to include the path to a typelib into a patch.
</para>
</listitem>
<listitem xml:id="ssec-gnome-common-issues-unwrappable-package-gsettings">
<para>
The following examples are hardcoding GSettings schema paths. To get the schema paths we use the functions
<itemizedlist>
<listitem>
<para>
<function>glib.getSchemaPath</function> Takes a nix package attribute as an argument.
</para>
</listitem>
<listitem>
<para>
<function>glib.makeSchemaPath</function> Takes a package output like <literal>$out</literal> and a derivation name. You should use this if the schemas you need to hardcode are in the same derivation.
</para>
</listitem>
</itemizedlist>
</para>
<para xml:id="ssec-gnome-common-issues-unwrappable-package-gsettings-vala">
<link xlink:href="https://github.com/NixOS/nixpkgs/blob/7bb8f05f12ca3cff9da72b56caa2f7472d5732bc/pkgs/desktops/pantheon/apps/elementary-files/default.nix#L78-L86">Hard-coding GSettings schema path in Vala plug-in (dynamically loaded library)</link> here, <function>substituteAll</function> cannot be used since the schema comes from the same package preventing us from pass its path to the function, probably due to a <link xlink:href="https://github.com/NixOS/nix/issues/1846">Nix bug</link>.
</para>
<para xml:id="ssec-gnome-common-issues-unwrappable-package-gsettings-c">
<link xlink:href="https://github.com/NixOS/nixpkgs/blob/29c120c065d03b000224872251bed93932d42412/pkgs/development/libraries/glib-networking/default.nix#L31-L34">Hard-coding GSettings schema path in C library</link> nothing special other than using <link xlink:href="https://github.com/NixOS/nixpkgs/pull/67957#issuecomment-527717467">Coccinelle patch</link> to generate the patch itself.
</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</varlistentry>
<varlistentry xml:id="ssec-gnome-common-issues-weird-location">
<term>
I need to wrap a binary outside <filename>bin</filename> and <filename>libexec</filename> directories.
</term>
<listitem>
<para>
You can manually trigger the wrapping with <function>wrapGApp</function> in <literal>preFixup</literal> phase. It takes a path to a program as a first argument; the remaining arguments are passed directly to <function xlink:href="#fun-wrapProgram">wrapProgram</function> function.
</para>
</listitem>
</varlistentry>
</variablelist>
</section>
</section>

View File

@ -0,0 +1,140 @@
# Go {#sec-language-go}
## Go modules {#ssec-language-go}
The function `buildGoModule` builds Go programs managed with Go modules. It builds a [Go Modules](https://github.com/golang/go/wiki/Modules) through a two phase build:
- An intermediate fetcher derivation. This derivation will be used to fetch all of the dependencies of the Go module.
- A final derivation will use the output of the intermediate derivation to build the binaries and produce the final output.
### Example for `buildGoModule` {#ex-buildGoModule}
In the following is an example expression using `buildGoModule`, the following arguments are of special significance to the function:
- `vendorSha256`: is the hash of the output of the intermediate fetcher derivation. `vendorSha256` can also take `null` as an input. When `null` is used as a value, rather than fetching the dependencies and vendoring them, we use the vendoring included within the source repo. If you'd like to not have to update this field on dependency changes, run `go mod vendor` in your source repo and set `vendorSha256 = null;`
- `runVend`: runs the vend command to generate the vendor directory. This is useful if your code depends on c code and go mod tidy does not include the needed sources to build.
```nix
pet = buildGoModule rec {
pname = "pet";
version = "0.3.4";
src = fetchFromGitHub {
owner = "knqyf263";
repo = "pet";
rev = "v${version}";
sha256 = "0m2fzpqxk7hrbxsgqplkg7h2p7gv6s1miymv3gvw0cz039skag0s";
};
vendorSha256 = "1879j77k96684wi554rkjxydrj8g3hpp0kvxz03sd8dmwr3lh83j";
runVend = true;
meta = with lib; {
description = "Simple command-line snippet manager, written in Go";
homepage = "https://github.com/knqyf263/pet";
license = licenses.mit;
maintainers = with maintainers; [ kalbasit ];
platforms = platforms.linux ++ platforms.darwin;
};
}
```
## `buildGoPackage` (legacy) {#ssec-go-legacy}
The function `buildGoPackage` builds legacy Go programs, not supporting Go modules.
### Example for `buildGoPackage`
In the following is an example expression using buildGoPackage, the following arguments are of special significance to the function:
- `goPackagePath` specifies the package's canonical Go import path.
- `goDeps` is where the Go dependencies of a Go program are listed as a list of package source identified by Go import path. It could be imported as a separate `deps.nix` file for readability. The dependency data structure is described below.
```nix
deis = buildGoPackage rec {
pname = "deis";
version = "1.13.0";
goPackagePath = "github.com/deis/deis";
src = fetchFromGitHub {
owner = "deis";
repo = "deis";
rev = "v${version}";
sha256 = "1qv9lxqx7m18029lj8cw3k7jngvxs4iciwrypdy0gd2nnghc68sw";
};
goDeps = ./deps.nix;
}
```
The `goDeps` attribute can be imported from a separate `nix` file that defines which Go libraries are needed and should be included in `GOPATH` for `buildPhase`:
```nix
# deps.nix
[ # goDeps is a list of Go dependencies.
{
# goPackagePath specifies Go package import path.
goPackagePath = "gopkg.in/yaml.v2";
fetch = {
# `fetch type` that needs to be used to get package source.
# If `git` is used there should be `url`, `rev` and `sha256` defined next to it.
type = "git";
url = "https://gopkg.in/yaml.v2";
rev = "a83829b6f1293c91addabc89d0571c246397bbf4";
sha256 = "1m4dsmk90sbi17571h6pld44zxz7jc4lrnl4f27dpd1l8g5xvjhh";
};
}
{
goPackagePath = "github.com/docopt/docopt-go";
fetch = {
type = "git";
url = "https://github.com/docopt/docopt-go";
rev = "784ddc588536785e7299f7272f39101f7faccc3f";
sha256 = "0wwz48jl9fvl1iknvn9dqr4gfy1qs03gxaikrxxp9gry6773v3sj";
};
}
]
```
To extract dependency information from a Go package in automated way use [go2nix](https://github.com/kamilchm/go2nix). It can produce complete derivation and `goDeps` file for Go programs.
You may use Go packages installed into the active Nix profiles by adding the following to your ~/.bashrc:
```bash
for p in $NIX_PROFILES; do
GOPATH="$p/share/go:$GOPATH"
done
```
## Attributes used by the builders {#ssec-go-common-attributes}
Both `buildGoModule` and `buildGoPackage` can be tweaked to behave slightly differently, if the following attributes are used:
### `buildFlagsArray` and `buildFlags`: {#ex-goBuildFlags-noarray}
These attributes set build flags supported by `go build`. We recommend using `buildFlagsArray`. The most common use case of these attributes is to make the resulting executable aware of its own version. For example:
```nix
buildFlagsArray = [
# Note: single quotes are not needed.
"-ldflags=-X main.Version=${version} -X main.Commit=${version}"
];
```
```nix
buildFlagsArray = ''
-ldflags=
-X main.Version=${version}
-X main.Commit=${version}
'';
```
### `deleteVendor` {#var-go-deleteVendor}
Removes the pre-existing vendor directory. This should only be used if the dependencies included in the vendor folder are broken or incomplete.
### `subPackages` {#var-go-subPackages}
Limits the builder from building child packages that have not been listed. If <varname>subPackages</varname> is not specified, all child packages will be built.

View File

@ -1,248 +0,0 @@
<section xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xml:id="sec-language-go">
<title>Go</title>
<section xml:id="ssec-go-modules">
<title>Go modules</title>
<para>
The function <varname> buildGoModule </varname> builds Go programs managed with Go modules. It builds a <link xlink:href="https://github.com/golang/go/wiki/Modules">Go modules</link> through a two phase build:
<itemizedlist>
<listitem>
<para>
An intermediate fetcher derivation. This derivation will be used to fetch all of the dependencies of the Go module.
</para>
</listitem>
<listitem>
<para>
A final derivation will use the output of the intermediate derivation to build the binaries and produce the final output.
</para>
</listitem>
</itemizedlist>
</para>
<example xml:id='ex-buildGoModule'>
<title>buildGoModule</title>
<programlisting>
pet = buildGoModule rec {
pname = "pet";
version = "0.3.4";
src = fetchFromGitHub {
owner = "knqyf263";
repo = "pet";
rev = "v${version}";
sha256 = "0m2fzpqxk7hrbxsgqplkg7h2p7gv6s1miymv3gvw0cz039skag0s";
};
vendorSha256 = "1879j77k96684wi554rkjxydrj8g3hpp0kvxz03sd8dmwr3lh83j"; <co xml:id='ex-buildGoModule-1' />
runVend = true; <co xml:id='ex-buildGoModule-2' />
meta = with lib; {
description = "Simple command-line snippet manager, written in Go";
homepage = "https://github.com/knqyf263/pet";
license = licenses.mit;
maintainers = with maintainers; [ kalbasit ];
platforms = platforms.linux ++ platforms.darwin;
};
}
</programlisting>
</example>
<para>
<xref linkend='ex-buildGoModule'/> is an example expression using buildGoModule, the following arguments are of special significance to the function:
<calloutlist>
<callout arearefs='ex-buildGoModule-1'>
<para>
<varname>vendorSha256</varname> is the hash of the output of the intermediate fetcher derivation.
</para>
</callout>
<callout arearefs='ex-buildGoModule-2'>
<para>
<varname>runVend</varname> runs the vend command to generate the vendor directory. This is useful if your code depends on c code and go mod tidy does not include the needed sources to build.
</para>
</callout>
</calloutlist>
</para>
<para>
<varname>vendorSha256</varname> can also take <varname>null</varname> as an input. When `null` is used as a value, rather than fetching the dependencies and vendoring them, we use the vendoring included within the source repo. If you'd like to not have to update this field on dependency changes, run `go mod vendor` in your source repo and set 'vendorSha256 = null;'
</para>
</section>
<section xml:id="ssec-go-legacy">
<title>Go legacy</title>
<para>
The function <varname> buildGoPackage </varname> builds legacy Go programs, not supporting Go modules.
</para>
<example xml:id='ex-buildGoPackage'>
<title>buildGoPackage</title>
<programlisting>
deis = buildGoPackage rec {
pname = "deis";
version = "1.13.0";
goPackagePath = "github.com/deis/deis"; <co xml:id='ex-buildGoPackage-1' />
src = fetchFromGitHub {
owner = "deis";
repo = "deis";
rev = "v${version}";
sha256 = "1qv9lxqx7m18029lj8cw3k7jngvxs4iciwrypdy0gd2nnghc68sw";
};
goDeps = ./deps.nix; <co xml:id='ex-buildGoPackage-2' />
}
</programlisting>
</example>
<para>
<xref linkend='ex-buildGoPackage'/> is an example expression using buildGoPackage, the following arguments are of special significance to the function:
<calloutlist>
<callout arearefs='ex-buildGoPackage-1'>
<para>
<varname>goPackagePath</varname> specifies the package's canonical Go import path.
</para>
</callout>
<callout arearefs='ex-buildGoPackage-2'>
<para>
<varname>goDeps</varname> is where the Go dependencies of a Go program are listed as a list of package source identified by Go import path. It could be imported as a separate <varname>deps.nix</varname> file for readability. The dependency data structure is described below.
</para>
</callout>
</calloutlist>
</para>
<para>
The <varname>goDeps</varname> attribute can be imported from a separate <varname>nix</varname> file that defines which Go libraries are needed and should be included in <varname>GOPATH</varname> for <varname>buildPhase</varname>.
</para>
<example xml:id='ex-goDeps'>
<title>deps.nix</title>
<programlisting>
[ <co xml:id='ex-goDeps-1' />
{
goPackagePath = "gopkg.in/yaml.v2"; <co xml:id='ex-goDeps-2' />
fetch = {
type = "git"; <co xml:id='ex-goDeps-3' />
url = "https://gopkg.in/yaml.v2";
rev = "a83829b6f1293c91addabc89d0571c246397bbf4";
sha256 = "1m4dsmk90sbi17571h6pld44zxz7jc4lrnl4f27dpd1l8g5xvjhh";
};
}
{
goPackagePath = "github.com/docopt/docopt-go";
fetch = {
type = "git";
url = "https://github.com/docopt/docopt-go";
rev = "784ddc588536785e7299f7272f39101f7faccc3f";
sha256 = "0wwz48jl9fvl1iknvn9dqr4gfy1qs03gxaikrxxp9gry6773v3sj";
};
}
]
</programlisting>
</example>
<para>
<calloutlist>
<callout arearefs='ex-goDeps-1'>
<para>
<varname>goDeps</varname> is a list of Go dependencies.
</para>
</callout>
<callout arearefs='ex-goDeps-2'>
<para>
<varname>goPackagePath</varname> specifies Go package import path.
</para>
</callout>
<callout arearefs='ex-goDeps-3'>
<para>
<varname>fetch type</varname> that needs to be used to get package source. If <varname>git</varname> is used there should be <varname>url</varname>, <varname>rev</varname> and <varname>sha256</varname> defined next to it.
</para>
</callout>
</calloutlist>
</para>
<para>
To extract dependency information from a Go package in automated way use <link xlink:href="https://github.com/kamilchm/go2nix">go2nix</link>. It can produce complete derivation and <varname>goDeps</varname> file for Go programs.
</para>
<para>
You may use Go packages installed into the active Nix profiles by adding the following to your ~/.bashrc:
<screen>
for p in $NIX_PROFILES; do
GOPATH="$p/share/go:$GOPATH"
done
</screen>
</para>
</section>
<section xml:id="ssec-go-common-attributes">
<title>Attributes used by the builders</title>
<para>
Both <link xlink:href="#ssec-go-modules"><varname>buildGoModule</varname></link> and <link xlink:href="#ssec-go-modules"><varname>buildGoPackage</varname></link> can be tweaked to behave slightly differently, if the following attributes are used:
</para>
<variablelist>
<varlistentry xml:id="var-go-buildFlagsArray">
<term>
<varname>buildFlagsArray</varname> and <varname>buildFlags</varname>
</term>
<listitem>
<para>
These attributes set build flags supported by <varname>go build</varname>. We recommend using <varname>buildFlagsArray</varname>. The most common use case of these attributes is to make the resulting executable aware of its own version. For example:
</para>
<example xml:id='ex-goBuildFlags-nospaces'>
<title>buildFlagsArray</title>
<programlisting>
buildFlagsArray = [
"-ldflags=-X main.Version=${version} -X main.Commit=${version}" <co xml:id='ex-goBuildFlags-1' />
];
</programlisting>
</example>
<calloutlist>
<callout arearefs='ex-goBuildFlags-1'>
<para>
Note: single quotes are not needed.
</para>
</callout>
</calloutlist>
<example xml:id='ex-goBuildFlags-noarray'>
<title>buildFlagsArray</title>
<programlisting>
buildFlagsArray = ''
-ldflags=
-X main.Version=${version}
-X main.Commit=${version}
'';
</programlisting>
</example>
</listitem>
</varlistentry>
<varlistentry xml:id="var-go-deleteVendor">
<term>
<varname>deleteVendor</varname>
</term>
<listitem>
<para>
Removes the pre-existing vendor directory. This should only be used if the dependencies included in the vendor folder are broken or incomplete.
</para>
</listitem>
</varlistentry>
<varlistentry xml:id="var-go-subPackages">
<term>
<varname>subPackages</varname>
</term>
<listitem>
<para>
Limits the builder from building child packages that have not been listed. If <varname>subPackages</varname> is not specified, all child packages will be built.
</para>
</listitem>
</varlistentry>
</variablelist>
</section>
</section>

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
# Idris
# Idris {#idris}
## Installing Idris

View File

@ -7,28 +7,29 @@
</para>
<xi:include href="agda.section.xml" />
<xi:include href="android.section.xml" />
<xi:include href="beam.xml" />
<xi:include href="bower.xml" />
<xi:include href="coq.xml" />
<xi:include href="beam.section.xml" />
<xi:include href="bower.section.xml" />
<xi:include href="coq.section.xml" />
<xi:include href="crystal.section.xml" />
<xi:include href="emscripten.section.xml" />
<xi:include href="gnome.xml" />
<xi:include href="go.xml" />
<xi:include href="gnome.section.xml" />
<xi:include href="go.section.xml" />
<xi:include href="haskell.section.xml" />
<xi:include href="idris.section.xml" />
<xi:include href="ios.section.xml" />
<xi:include href="java.xml" />
<xi:include href="java.section.xml" />
<xi:include href="lua.section.xml" />
<xi:include href="maven.section.xml" />
<xi:include href="node.section.xml" />
<xi:include href="ocaml.xml" />
<xi:include href="perl.xml" />
<xi:include href="ocaml.section.xml" />
<xi:include href="perl.section.xml" />
<xi:include href="php.section.xml" />
<xi:include href="python.section.xml" />
<xi:include href="qt.xml" />
<xi:include href="qt.section.xml" />
<xi:include href="r.section.xml" />
<xi:include href="ruby.xml" />
<xi:include href="ruby.section.xml" />
<xi:include href="rust.section.xml" />
<xi:include href="texlive.xml" />
<xi:include href="texlive.section.xml" />
<xi:include href="titanium.section.xml" />
<xi:include href="vim.section.xml" />
</chapter>

View File

@ -1,9 +1,4 @@
---
title: iOS
author: Sander van der Burg
date: 2019-11-10
---
# iOS
# iOS {#ios}
This component is basically a wrapper/workaround that makes it possible to
expose an Xcode installation as a Nix package by means of symlinking to the

View File

@ -0,0 +1,91 @@
# Java {#sec-language-java}
Ant-based Java packages are typically built from source as follows:
```nix
stdenv.mkDerivation {
name = "...";
src = fetchurl { ... };
nativeBuildInputs = [ jdk ant ];
buildPhase = "ant";
}
```
Note that `jdk` is an alias for the OpenJDK (self-built where available,
or pre-built via Zulu). Platforms with OpenJDK not (yet) in Nixpkgs
(`Aarch32`, `Aarch64`) point to the (unfree) `oraclejdk`.
JAR files that are intended to be used by other packages should be
installed in `$out/share/java`. JDKs have a stdenv setup hook that add
any JARs in the `share/java` directories of the build inputs to the
`CLASSPATH` environment variable. For instance, if the package `libfoo`
installs a JAR named `foo.jar` in its `share/java` directory, and
another package declares the attribute
```nix
buildInputs = [ libfoo ];
nativeBuildInputs = [ jdk ];
```
then `CLASSPATH` will be set to
`/nix/store/...-libfoo/share/java/foo.jar`.
Private JARs should be installed in a location like
`$out/share/package-name`.
If your Java package provides a program, you need to generate a wrapper
script to run it using a JRE. You can use `makeWrapper` for this:
```nix
nativeBuildInputs = [ makeWrapper ];
installPhase = ''
mkdir -p $out/bin
makeWrapper ${jre}/bin/java $out/bin/foo \
--add-flags "-cp $out/share/java/foo.jar org.foo.Main"
'';
```
Since the introduction of the Java Platform Module System in Java 9,
Java distributions typically no longer ship with a general-purpose JRE:
instead, they allow generating a JRE with only the modules required for
your application(s). Because we can't predict what modules will be
needed on a general-purpose system, the default jre package is the full
JDK. When building a minimal system/image, you can override the
`modules` parameter on `jre_minimal` to build a JRE with only the
modules relevant for you:
```nix
let
my_jre = pkgs.jre_minimal.override {
modules = [
# The modules used by 'something' and 'other' combined:
"java.base"
"java.logging"
];
};
something = (pkgs.something.override { jre = my_jre; });
other = (pkgs.other.override { jre = my_jre; });
in
...
```
Note all JDKs passthru `home`, so if your application requires
environment variables like `JAVA_HOME` being set, that can be done in a
generic fashion with the `--set` argument of `makeWrapper`:
```bash
--set JAVA_HOME ${jdk.home}
```
It is possible to use a different Java compiler than `javac` from the
OpenJDK. For instance, to use the GNU Java Compiler:
```nix
nativeBuildInputs = [ gcj ant ];
```
Here, Ant will automatically use `gij` (the GNU Java Runtime) instead of
the OpenJRE.

View File

@ -1,63 +0,0 @@
<section xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xml:id="sec-language-java">
<title>Java</title>
<para>
Ant-based Java packages are typically built from source as follows:
<programlisting>
stdenv.mkDerivation {
name = "...";
src = fetchurl { ... };
nativeBuildInputs = [ jdk ant ];
buildPhase = "ant";
}
</programlisting>
Note that <varname>jdk</varname> is an alias for the OpenJDK (self-built where available, or pre-built via Zulu). Platforms with OpenJDK not (yet) in Nixpkgs (<literal>Aarch32</literal>, <literal>Aarch64</literal>) point to the (unfree) <literal>oraclejdk</literal>.
</para>
<para>
JAR files that are intended to be used by other packages should be installed in <filename>$out/share/java</filename>. JDKs have a stdenv setup hook that add any JARs in the <filename>share/java</filename> directories of the build inputs to the <envar>CLASSPATH</envar> environment variable. For instance, if the package <literal>libfoo</literal> installs a JAR named <filename>foo.jar</filename> in its <filename>share/java</filename> directory, and another package declares the attribute
<programlisting>
buildInputs = [ libfoo ];
nativeBuildInputs = [ jdk ];
</programlisting>
then <envar>CLASSPATH</envar> will be set to <filename>/nix/store/...-libfoo/share/java/foo.jar</filename>.
</para>
<para>
Private JARs should be installed in a location like <filename>$out/share/<replaceable>package-name</replaceable></filename>.
</para>
<para>
If your Java package provides a program, you need to generate a wrapper script to run it using the OpenJRE. You can use <literal>makeWrapper</literal> for this:
<programlisting>
nativeBuildInputs = [ makeWrapper ];
installPhase =
''
mkdir -p $out/bin
makeWrapper ${jre}/bin/java $out/bin/foo \
--add-flags "-cp $out/share/java/foo.jar org.foo.Main"
'';
</programlisting>
Note the use of <literal>jre</literal>, which is the part of the OpenJDK package that contains the Java Runtime Environment. By using <literal>${jre}/bin/java</literal> instead of <literal>${jdk}/bin/java</literal>, you prevent your package from depending on the JDK at runtime.
</para>
<para>
Note all JDKs passthru <literal>home</literal>, so if your application requires environment variables like <envar>JAVA_HOME</envar> being set, that can be done in a generic fashion with the <literal>--set</literal> argument of <literal>makeWrapper</literal>:
<programlisting>
--set JAVA_HOME ${jdk.home}
</programlisting>
</para>
<para>
It is possible to use a different Java compiler than <command>javac</command> from the OpenJDK. For instance, to use the GNU Java Compiler:
<programlisting>
nativeBuildInputs = [ gcj ant ];
</programlisting>
Here, Ant will automatically use <command>gij</command> (the GNU Java Runtime) instead of the OpenJRE.
</para>
</section>

View File

@ -1,10 +1,4 @@
---
title: Lua
author: Matthieu Coudron
date: 2019-02-05
---
# User's Guide to Lua Infrastructure
# User's Guide to Lua Infrastructure {#users-guide-to-lua-infrastructure}
## Using Lua
@ -187,7 +181,7 @@ luaposix = buildLuarocksPackage {
disabled = (luaOlder "5.1") || (luaAtLeast "5.4");
propagatedBuildInputs = [ bit32 lua std_normalize ];
meta = with stdenv.lib; {
meta = with lib; {
homepage = "https://github.com/luaposix/luaposix/";
description = "Lua bindings for POSIX";
maintainers = with maintainers; [ vyp lblasc ];
@ -249,4 +243,3 @@ Following rules should be respected:
* Make sure libraries build for all Lua interpreters.
* Commit names of Lua libraries should reflect that they are Lua libraries, so write for example `luaPackages.luafilesystem: 1.11 -> 1.12`.

View File

@ -0,0 +1,348 @@
# Maven {#maven}
Maven is a well-known build tool for the Java ecosystem however it has some challenges when integrating into the Nix build system.
The following provides a list of common patterns with how to package a Maven project (or any JVM language that can export to Maven) as a Nix package.
For the purposes of this example let's consider a very basic Maven project with the following `pom.xml` with a single dependency on [emoji-java](https://github.com/vdurmont/emoji-java).
```xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>io.github.fzakaria</groupId>
<artifactId>maven-demo</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<name>NixOS Maven Demo</name>
<dependencies>
<dependency>
<groupId>com.vdurmont</groupId>
<artifactId>emoji-java</artifactId>
<version>5.1.1</version>
</dependency>
</dependencies>
</project>
```
Our main class file will be very simple:
```java
import com.vdurmont.emoji.EmojiParser;
public class Main {
public static void main(String[] args) {
String str = "NixOS :grinning: is super cool :smiley:!";
String result = EmojiParser.parseToUnicode(str);
System.out.println(result);
}
}
```
You find this demo project at https://github.com/fzakaria/nixos-maven-example
## Solving for dependencies
### buildMaven with NixOS/mvn2nix-maven-plugin
> ⚠️ Although `buildMaven` is the "blessed" way within nixpkgs, as of 2020, it hasn't seen much activity in quite a while.
`buildMaven` is an alternative method that tries to follow similar patterns of other programming languages by generating a lock file. It relies on the maven plugin [mvn2nix-maven-plugin](https://github.com/NixOS/mvn2nix-maven-plugin).
First you generate a `project-info.json` file using the maven plugin.
> This should be executed in the project's source repository or be told which `pom.xml` to execute with.
```bash
# run this step within the project's source repository
mvn org.nixos.mvn2nix:mvn2nix-maven-plugin:mvn2nix
cat project-info.json | jq | head
{
"project": {
"artifactId": "maven-demo",
"groupId": "org.nixos",
"version": "1.0",
"classifier": "",
"extension": "jar",
"dependencies": [
{
"artifactId": "maven-resources-plugin",
```
This file is then given to the `buildMaven` function, and it returns 2 attributes.
**`repo`**:
A Maven repository that is a symlink farm of all the dependencies found in the `project-info.json`
**`build`**:
A simple derivation that runs through `mvn compile` & `mvn package` to build the JAR. You may use this as inspiration for more complicated derivations.
Here is an [example](https://github.com/fzakaria/nixos-maven-example/blob/main/build-maven-repository.nix) of building the Maven repository
```nix
{ pkgs ? import <nixpkgs> { } }:
with pkgs;
(buildMaven ./project-info.json).repo
```
The benefit over the _double invocation_ as we will see below, is that the _/nix/store_ entry is a _linkFarm_ of every package, so that changes to your dependency set doesn't involve downloading everything from scratch.
```bash
tree $(nix-build --no-out-link build-maven-repository.nix) | head
/nix/store/g87va52nkc8jzbmi1aqdcf2f109r4dvn-maven-repository
├── antlr
│   └── antlr
│   └── 2.7.2
│   ├── antlr-2.7.2.jar -> /nix/store/d027c8f2cnmj5yrynpbq2s6wmc9cb559-antlr-2.7.2.jar
│   └── antlr-2.7.2.pom -> /nix/store/mv42fc5gizl8h5g5vpywz1nfiynmzgp2-antlr-2.7.2.pom
├── avalon-framework
│   └── avalon-framework
│   └── 4.1.3
│   ├── avalon-framework-4.1.3.jar -> /nix/store/iv5fp3955w3nq28ff9xfz86wvxbiw6n9-avalon-framework-4.1.3.jar
```
### Double Invocation
> ⚠️ This pattern is the simplest but may cause unnecessary rebuilds due to the output hash changing.
The double invocation is a _simple_ way to get around the problem that `nix-build` may be sandboxed and have no Internet connectivity.
It treats the entire Maven repository as a single source to be downloaded, relying on Maven's dependency resolution to satisfy the output hash. This is similar to fetchers like `fetchgit`, except it has to run a Maven build to determine what to download.
The first step will be to build the Maven project as a fixed-output derivation in order to collect the Maven repository -- below is an [example](https://github.com/fzakaria/nixos-maven-example/blob/main/double-invocation-repository.nix).
> Traditionally the Maven repository is at `~/.m2/repository`. We will override this to be the `$out` directory.
```nix
{ stdenv, lib, maven }:
stdenv.mkDerivation {
name = "maven-repository";
buildInputs = [ maven ];
src = ./.; # or fetchFromGitHub, cleanSourceWith, etc
buildPhase = ''
mvn package -Dmaven.repo.local=$out
'';
# keep only *.{pom,jar,sha1,nbm} and delete all ephemeral files with lastModified timestamps inside
installPhase = ''
find $out -type f \
-name \*.lastUpdated -or \
-name resolver-status.properties -or \
-name _remote.repositories \
-delete
'';
# don't do any fixup
dontFixup = true;
outputHashAlgo = "sha256";
outputHashMode = "recursive";
# replace this with the correct SHA256
outputHash = lib.fakeSha256;
}
```
The build will fail, and tell you the expected `outputHash` to place. When you've set the hash, the build will return with a `/nix/store` entry whose contents are the full Maven repository.
> Some additional files are deleted that would cause the output hash to change potentially on subsequent runs.
```bash
tree $(nix-build --no-out-link double-invocation-repository.nix) | head
/nix/store/8kicxzp98j68xyi9gl6jda67hp3c54fq-maven-repository
├── backport-util-concurrent
│   └── backport-util-concurrent
│   └── 3.1
│   ├── backport-util-concurrent-3.1.pom
│   └── backport-util-concurrent-3.1.pom.sha1
├── classworlds
│   └── classworlds
│   ├── 1.1
│   │   ├── classworlds-1.1.jar
```
If your package uses _SNAPSHOT_ dependencies or _version ranges_; there is a strong likelihood that over-time your output hash will change since the resolved dependencies may change. Hence this method is less recommended then using `buildMaven`.
## Building a JAR
Regardless of which strategy is chosen above, the step to build the derivation is the same.
```nix
{ stdenv, lib, maven, callPackage }:
# pick a repository derivation, here we will use buildMaven
let repository = callPackage ./build-maven-repository.nix { };
in stdenv.mkDerivation rec {
pname = "maven-demo";
version = "1.0";
src = builtins.fetchTarball "https://github.com/fzakaria/nixos-maven-example/archive/main.tar.gz";
buildInputs = [ maven ];
buildPhase = ''
echo "Using repository ${repository}"
mvn --offline -Dmaven.repo.local=${repository} package;
'';
installPhase = ''
install -Dm644 target/${pname}-${version}.jar $out/share/java
'';
}
```
> We place the library in `$out/share/java` since JDK package has a _stdenv setup hook_ that adds any JARs in the `share/java` directories of the build inputs to the CLASSPATH environment.
```bash
tree $(nix-build --no-out-link build-jar.nix)
/nix/store/7jw3xdfagkc2vw8wrsdv68qpsnrxgvky-maven-demo-1.0
└── share
└── java
└── maven-demo-1.0.jar
2 directories, 1 file
```
## Runnable JAR
The previous example builds a `jar` file but that's not a file one can run.
You need to use it with `java -jar $out/share/java/output.jar` and make sure to provide the required dependencies on the classpath.
The following explains how to use `makeWrapper` in order to make the derivation produce an executable that will run the JAR file you created.
We will use the same repository we built above (either _double invocation_ or _buildMaven_) to setup a CLASSPATH for our JAR.
The following two methods are more suited to Nix then building an [UberJar](https://imagej.net/Uber-JAR) which may be the more traditional approach.
### CLASSPATH
> This is ideal if you are providing a derivation for _nixpkgs_ and don't want to patch the project's `pom.xml`.
We will read the Maven repository and flatten it to a single list. This list will then be concatenated with the _CLASSPATH_ separator to create the full classpath.
We make sure to provide this classpath to the `makeWrapper`.
```nix
{ stdenv, lib, maven, callPackage, makeWrapper, jre }:
let
repository = callPackage ./build-maven-repository.nix { };
in stdenv.mkDerivation rec {
pname = "maven-demo";
version = "1.0";
src = builtins.fetchTarball
"https://github.com/fzakaria/nixos-maven-example/archive/main.tar.gz";
buildInputs = [ maven makeWrapper ];
buildPhase = ''
echo "Using repository ${repository}"
mvn --offline -Dmaven.repo.local=${repository} package;
'';
installPhase = ''
mkdir -p $out/bin
classpath=$(find ${repository} -name "*.jar" -printf ':%h/%f');
install -Dm644 target/${pname}-${version}.jar $out/share/java
# create a wrapper that will automatically set the classpath
# this should be the paths from the dependency derivation
makeWrapper ${jre}/bin/java $out/bin/${pname} \
--add-flags "-classpath $out/share/java/${pname}-${version}.jar:''${classpath#:}" \
--add-flags "Main"
'';
}
```
### MANIFEST file via Maven Plugin
> This is ideal if you are the project owner and want to change your `pom.xml` to set the CLASSPATH within it.
Augment the `pom.xml` to create a JAR with the following manifest:
```xml
<build>
<plugins>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>../../repository/</classpathPrefix>
<classpathLayoutType>repository</classpathLayoutType>
<mainClass>Main</mainClass>
</manifest>
<manifestEntries>
<Class-Path>.</Class-Path>
</manifestEntries>
</archive>
</configuration>
</plugin>
</plugins>
</build>
```
The above plugin instructs the JAR to look for the necessary dependencies in the `lib/` relative folder. The layout of the folder is also in the _maven repository_ style.
```bash
unzip -q -c $(nix-build --no-out-link runnable-jar.nix)/share/java/maven-demo-1.0.jar META-INF/MANIFEST.MF
Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Built-By: nixbld
Class-Path: . ../../repository/com/vdurmont/emoji-java/5.1.1/emoji-jav
a-5.1.1.jar ../../repository/org/json/json/20170516/json-20170516.jar
Created-By: Apache Maven 3.6.3
Build-Jdk: 1.8.0_265
Main-Class: Main
```
We will modify the derivation above to add a symlink to our repository so that it's accessible to our JAR during the `installPhase`.
```nix
{ stdenv, lib, maven, callPackage, makeWrapper, jre }:
# pick a repository derivation, here we will use buildMaven
let repository = callPackage ./build-maven-repository.nix { };
in stdenv.mkDerivation rec {
pname = "maven-demo";
version = "1.0";
src = builtins.fetchTarball
"https://github.com/fzakaria/nixos-maven-example/archive/main.tar.gz";
buildInputs = [ maven makeWrapper ];
buildPhase = ''
echo "Using repository ${repository}"
mvn --offline -Dmaven.repo.local=${repository} package;
'';
installPhase = ''
mkdir -p $out/bin
# create a symbolic link for the repository directory
ln -s ${repository} $out/repository
install -Dm644 target/${pname}-${version}.jar $out/share/java
# create a wrapper that will automatically set the classpath
# this should be the paths from the dependency derivation
makeWrapper ${jre}/bin/java $out/bin/${pname} \
--add-flags "-jar $out/share/java/${pname}-${version}.jar"
'';
}
```
> Our script produces a dependency on `jre` rather than `jdk` to restrict the runtime closure necessary to run the application.
This will give you an executable shell-script that launches your JAR with all the dependencies available.
```bash
tree $(nix-build --no-out-link runnable-jar.nix)
/nix/store/8d4c3ibw8ynsn01ibhyqmc1zhzz75s26-maven-demo-1.0
├── bin
│   └── maven-demo
├── repository -> /nix/store/g87va52nkc8jzbmi1aqdcf2f109r4dvn-maven-repository
└── share
└── java
└── maven-demo-1.0.jar
$(nix-build --no-out-link --option tarball-ttl 1 runnable-jar.nix)/bin/maven-demo
NixOS 😀 is super cool 😃!
```

View File

@ -1,5 +1,5 @@
Node.js
=======
# Node.js {#node.js}
The `pkgs/development/node-packages` folder contains a generated collection of
[NPM packages](https://npmjs.com/) that can be installed with the Nix package
manager.

View File

@ -0,0 +1,70 @@
# OCaml {#sec-language-ocaml}
OCaml libraries should be installed in `$(out)/lib/ocaml/${ocaml.version}/site-lib/`. Such directories are automatically added to the `$OCAMLPATH` environment variable when building another package that depends on them or when opening a `nix-shell`.
Given that most of the OCaml ecosystem is now built with dune, nixpkgs includes a convenience build support function called `buildDunePackage` that will build an OCaml package using dune, OCaml and findlib and any additional dependencies provided as `buildInputs` or `propagatedBuildInputs`.
Here is a simple package example. It defines an (optional) attribute `minimumOCamlVersion` that will be used to throw a descriptive evaluation error if building with an older OCaml is attempted. It uses the `fetchFromGitHub` fetcher to get its source. It sets the `doCheck` (optional) attribute to `true` which means that tests will be run with `dune runtest -p angstrom` after the build (`dune build -p angstrom`) is complete. It uses `alcotest` as a build input (because it is needed to run the tests) and `bigstringaf` and `result` as propagated build inputs (thus they will also be available to libraries depending on this library). The library will be installed using the `angstrom.install` file that dune generates.
```nix
{ lib
, fetchFromGitHub
, buildDunePackage
, alcotest
, result
, bigstringaf
}:
buildDunePackage rec {
pname = "angstrom";
version = "0.10.0";
minimumOCamlVersion = "4.03";
src = fetchFromGitHub {
owner = "inhabitedtype";
repo = pname;
rev = version;
sha256 = "0lh6024yf9ds0nh9i93r9m6p5psi8nvrqxl5x7jwl13zb0r9xfpw";
};
buildInputs = [ alcotest ];
propagatedBuildInputs = [ bigstringaf result ];
doCheck = true;
meta = {
homepage = "https://github.com/inhabitedtype/angstrom";
description = "OCaml parser combinators built for speed and memory efficiency";
license = lib.licenses.bsd3;
maintainers = with lib.maintainers; [ sternenseemann ];
};
}
```
Here is a second example, this time using a source archive generated with `dune-release`. It is a good idea to use this archive when it is available as it will usually contain substituted variables such as a `%%VERSION%%` field. This library does not depend on any other OCaml library and no tests are run after building it.
```nix
{ lib
, fetchurl
, buildDunePackage
}:
buildDunePackage rec {
pname = "wtf8";
version = "1.0.1";
minimumOCamlVersion = "4.01";
src = fetchurl {
url = "https://github.com/flowtype/ocaml-${pname}/releases/download/v${version}/${pname}-${version}.tbz";
sha256 = "1msg3vycd3k8qqj61sc23qks541cxpb97vrnrvrhjnqxsqnh6ygq";
};
meta = with lib; {
homepage = "https://github.com/flowtype/ocaml-wtf8";
description = "WTF-8 is a superset of UTF-8 that allows unpaired surrogates.";
license = licenses.mit;
maintainers = [ maintainers.eqyiel ];
};
}
```

View File

@ -1,73 +0,0 @@
<section xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xml:id="sec-language-ocaml">
<title>OCaml</title>
<para>
OCaml libraries should be installed in <literal>$(out)/lib/ocaml/${ocaml.version}/site-lib/</literal>. Such directories are automatically added to the <literal>$OCAMLPATH</literal> environment variable when building another package that depends on them or when opening a <literal>nix-shell</literal>.
</para>
<para>
Given that most of the OCaml ecosystem is now built with dune, nixpkgs includes a convenience build support function called <literal>buildDunePackage</literal> that will build an OCaml package using dune, OCaml and findlib and any additional dependencies provided as <literal>buildInputs</literal> or <literal>propagatedBuildInputs</literal>.
</para>
<para>
Here is a simple package example. It defines an (optional) attribute <literal>minimumOCamlVersion</literal> that will be used to throw a descriptive evaluation error if building with an older OCaml is attempted. It uses the <literal>fetchFromGitHub</literal> fetcher to get its source. It sets the <literal>doCheck</literal> (optional) attribute to <literal>true</literal> which means that tests will be run with <literal>dune runtest -p angstrom</literal> after the build (<literal>dune build -p angstrom</literal>) is complete. It uses <literal>alcotest</literal> as a build input (because it is needed to run the tests) and <literal>bigstringaf</literal> and <literal>result</literal> as propagated build inputs (thus they will also be available to libraries depending on this library). The library will be installed using the <literal>angstrom.install</literal> file that dune generates.
</para>
<programlisting>
{ stdenv, fetchFromGitHub, buildDunePackage, alcotest, result, bigstringaf }:
buildDunePackage rec {
pname = "angstrom";
version = "0.10.0";
minimumOCamlVersion = "4.03";
src = fetchFromGitHub {
owner = "inhabitedtype";
repo = pname;
rev = version;
sha256 = "0lh6024yf9ds0nh9i93r9m6p5psi8nvrqxl5x7jwl13zb0r9xfpw";
};
buildInputs = [ alcotest ];
propagatedBuildInputs = [ bigstringaf result ];
doCheck = true;
meta = {
homepage = "https://github.com/inhabitedtype/angstrom";
description = "OCaml parser combinators built for speed and memory efficiency";
license = stdenv.lib.licenses.bsd3;
maintainers = with stdenv.lib.maintainers; [ sternenseemann ];
};
}
</programlisting>
<para>
Here is a second example, this time using a source archive generated with <literal>dune-release</literal>. It is a good idea to use this archive when it is available as it will usually contain substituted variables such as a <literal>%%VERSION%%</literal> field. This library does not depend on any other OCaml library and no tests are run after building it.
</para>
<programlisting>
{ stdenv, fetchurl, buildDunePackage }:
buildDunePackage rec {
pname = "wtf8";
version = "1.0.1";
minimumOCamlVersion = "4.01";
src = fetchurl {
url = "https://github.com/flowtype/ocaml-${pname}/releases/download/v${version}/${pname}-${version}.tbz";
sha256 = "1msg3vycd3k8qqj61sc23qks541cxpb97vrnrvrhjnqxsqnh6ygq";
};
meta = with stdenv.lib; {
homepage = "https://github.com/flowtype/ocaml-wtf8";
description = "WTF-8 is a superset of UTF-8 that allows unpaired surrogates.";
license = licenses.mit;
maintainers = [ maintainers.eqyiel ];
};
}
</programlisting>
</section>

View File

@ -0,0 +1,163 @@
# Perl {#sec-language-perl}
## Running perl programs on the shell {#ssec-perl-running}
When executing a Perl script, it is possible you get an error such as `./myscript.pl: bad interpreter: /usr/bin/perl: no such file or directory`. This happens when the script expects Perl to be installed at `/usr/bin/perl`, which is not the case when using Perl from nixpkgs. You can fix the script by changing the first line to:
```perl
#!/usr/bin/env perl
```
to take the Perl installation from the `PATH` environment variable, or invoke Perl directly with:
```ShellSession
$ perl ./myscript.pl
```
When the script is using a Perl library that is not installed globally, you might get an error such as `Can't locate DB_File.pm in @INC (you may need to install the DB_File module)`. In that case, you can use `nix-shell` to start an ad-hoc shell with that library installed, for instance:
```ShellSession
$ nix-shell -p perl perlPackages.DBFile --run ./myscript.pl
```
If you are always using the script in places where `nix-shell` is available, you can embed the `nix-shell` invocation in the shebang like this:
```perl
#!/usr/bin/env nix-shell
#! nix-shell -i perl -p perl perlPackages.DBFile
```
## Packaging Perl programs {#ssec-perl-packaging}
Nixpkgs provides a function `buildPerlPackage`, a generic package builder function for any Perl package that has a standard `Makefile.PL`. Its implemented in [pkgs/development/perl-modules/generic](https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/perl-modules/generic).
Perl packages from CPAN are defined in [pkgs/top-level/perl-packages.nix](https://github.com/NixOS/nixpkgs/blob/master/pkgs/top-level/perl-packages.nix) rather than `pkgs/all-packages.nix`. Most Perl packages are so straight-forward to build that they are defined here directly, rather than having a separate function for each package called from `perl-packages.nix`. However, more complicated packages should be put in a separate file, typically in `pkgs/development/perl-modules`. Here is an example of the former:
```nix
ClassC3 = buildPerlPackage rec {
name = "Class-C3-0.21";
src = fetchurl {
url = "mirror://cpan/authors/id/F/FL/FLORA/${name}.tar.gz";
sha256 = "1bl8z095y4js66pwxnm7s853pi9czala4sqc743fdlnk27kq94gz";
};
};
```
Note the use of `mirror://cpan/`, and the `${name}` in the URL definition to ensure that the name attribute is consistent with the source that were actually downloading. Perl packages are made available in `all-packages.nix` through the variable `perlPackages`. For instance, if you have a package that needs `ClassC3`, you would typically write
```nix
foo = import ../path/to/foo.nix {
inherit stdenv fetchurl ...;
inherit (perlPackages) ClassC3;
};
```
in `all-packages.nix`. You can test building a Perl package as follows:
```ShellSession
$ nix-build -A perlPackages.ClassC3
```
`buildPerlPackage` adds `perl-` to the start of the name attribute, so the package above is actually called `perl-Class-C3-0.21`. So to install it, you can say:
```ShellSession
$ nix-env -i perl-Class-C3
```
(Of course you can also install using the attribute name: `nix-env -i -A perlPackages.ClassC3`.)
So what does `buildPerlPackage` do? It does the following:
1. In the configure phase, it calls `perl Makefile.PL` to generate a Makefile. You can set the variable `makeMakerFlags` to pass flags to `Makefile.PL`
2. It adds the contents of the `PERL5LIB` environment variable to `#! .../bin/perl` line of Perl scripts as `-Idir` flags. This ensures that a script can find its dependencies. (This can cause this shebang line to become too long for Darwin to handle; see the note below.)
3. In the fixup phase, it writes the propagated build inputs (`propagatedBuildInputs`) to the file `$out/nix-support/propagated-user-env-packages`. `nix-env` recursively installs all packages listed in this file when you install a package that has it. This ensures that a Perl package can find its dependencies.
`buildPerlPackage` is built on top of `stdenv`, so everything can be customised in the usual way. For instance, the `BerkeleyDB` module has a `preConfigure` hook to generate a configuration file used by `Makefile.PL`:
```nix
{ buildPerlPackage, fetchurl, db }:
buildPerlPackage rec {
name = "BerkeleyDB-0.36";
src = fetchurl {
url = "mirror://cpan/authors/id/P/PM/PMQS/${name}.tar.gz";
sha256 = "07xf50riarb60l1h6m2dqmql8q5dij619712fsgw7ach04d8g3z1";
};
preConfigure = ''
echo "LIB = ${db.out}/lib" > config.in
echo "INCLUDE = ${db.dev}/include" >> config.in
'';
}
```
Dependencies on other Perl packages can be specified in the `buildInputs` and `propagatedBuildInputs` attributes. If something is exclusively a build-time dependency, use `buildInputs`; if its (also) a runtime dependency, use `propagatedBuildInputs`. For instance, this builds a Perl module that has runtime dependencies on a bunch of other modules:
```nix
ClassC3Componentised = buildPerlPackage rec {
name = "Class-C3-Componentised-1.0004";
src = fetchurl {
url = "mirror://cpan/authors/id/A/AS/ASH/${name}.tar.gz";
sha256 = "0xql73jkcdbq4q9m0b0rnca6nrlvf5hyzy8is0crdk65bynvs8q1";
};
propagatedBuildInputs = [
ClassC3 ClassInspector TestException MROCompat
];
};
```
On Darwin, if a script has too many `-Idir` flags in its first line (its “shebang line”), it will not run. This can be worked around by calling the `shortenPerlShebang` function from the `postInstall` phase:
```nix
{ stdenv, lib, buildPerlPackage, fetchurl, shortenPerlShebang }:
ImageExifTool = buildPerlPackage {
pname = "Image-ExifTool";
version = "11.50";
src = fetchurl {
url = "https://www.sno.phy.queensu.ca/~phil/exiftool/Image-ExifTool-11.50.tar.gz";
sha256 = "0d8v48y94z8maxkmw1rv7v9m0jg2dc8xbp581njb6yhr7abwqdv3";
};
buildInputs = lib.optional stdenv.isDarwin shortenPerlShebang;
postInstall = lib.optional stdenv.isDarwin ''
shortenPerlShebang $out/bin/exiftool
'';
};
```
This will remove the `-I` flags from the shebang line, rewrite them in the `use lib` form, and put them on the next line instead. This function can be given any number of Perl scripts as arguments; it will modify them in-place.
### Generation from CPAN {#ssec-generation-from-CPAN}
Nix expressions for Perl packages can be generated (almost) automatically from CPAN. This is done by the program `nix-generate-from-cpan`, which can be installed as follows:
```ShellSession
$ nix-env -i nix-generate-from-cpan
```
This program takes a Perl module name, looks it up on CPAN, fetches and unpacks the corresponding package, and prints a Nix expression on standard output. For example:
```ShellSession
$ nix-generate-from-cpan XML::Simple
XMLSimple = buildPerlPackage rec {
name = "XML-Simple-2.22";
src = fetchurl {
url = "mirror://cpan/authors/id/G/GR/GRANTM/${name}.tar.gz";
sha256 = "b9450ef22ea9644ae5d6ada086dc4300fa105be050a2030ebd4efd28c198eb49";
};
propagatedBuildInputs = [ XMLNamespaceSupport XMLSAX XMLSAXExpat ];
meta = {
description = "An API for simple XML files";
license = with lib.licenses; [ artistic1 gpl1Plus ];
};
};
```
The output can be pasted into `pkgs/top-level/perl-packages.nix` or wherever else you need it.
### Cross-compiling modules {#ssec-perl-cross-compilation}
Nixpkgs has experimental support for cross-compiling Perl modules. In many cases, it will just work out of the box, even for modules with native extensions. Sometimes, however, the Makefile.PL for a module may (indirectly) import a native module. In that case, you will need to make a stub for that module that will satisfy the Makefile.PL and install it into `lib/perl5/site_perl/cross_perl/${perl.version}`. See the `postInstall` for `DBI` for an example.

View File

@ -1,195 +0,0 @@
<section xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xml:id="sec-language-perl">
<title>Perl</title>
<section xml:id="ssec-perl-running">
<title>Running perl programs on the shell</title>
<para>
When executing a Perl script, it is possible you get an error such as <literal>./myscript.pl: bad interpreter: /usr/bin/perl: no such file or directory</literal>. This happens when the script expects Perl to be installed at <filename>/usr/bin/perl</filename>, which is not the case when using Perl from nixpkgs. You can fix the script by changing the first line to:
<programlisting>
#!/usr/bin/env perl
</programlisting>
to take the Perl installation from the <literal>PATH</literal> environment variable, or invoke Perl directly with:
<screen>
<prompt>$ </prompt>perl ./myscript.pl
</screen>
</para>
<para>
When the script is using a Perl library that is not installed globally, you might get an error such as <literal>Can't locate DB_File.pm in @INC (you may need to install the DB_File module)</literal>. In that case, you can use <command>nix-shell</command> to start an ad-hoc shell with that library installed, for instance:
<screen>
<prompt>$ </prompt>nix-shell -p perl perlPackages.DBFile --run ./myscript.pl
</screen>
</para>
<para>
If you are always using the script in places where <command>nix-shell</command> is available, you can embed the <command>nix-shell</command> invocation in the shebang like this:
<programlisting>
#!/usr/bin/env nix-shell
#! nix-shell -i perl -p perl perlPackages.DBFile
</programlisting>
</para>
</section>
<section xml:id="ssec-perl-packaging">
<title>Packaging Perl programs</title>
<para>
Nixpkgs provides a function <varname>buildPerlPackage</varname>, a generic package builder function for any Perl package that has a standard <varname>Makefile.PL</varname>. Its implemented in <link
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/perl-modules/generic"><filename>pkgs/development/perl-modules/generic</filename></link>.
</para>
<para>
Perl packages from CPAN are defined in <link
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/pkgs/top-level/perl-packages.nix"><filename>pkgs/top-level/perl-packages.nix</filename></link>, rather than <filename>pkgs/all-packages.nix</filename>. Most Perl packages are so straight-forward to build that they are defined here directly, rather than having a separate function for each package called from <filename>perl-packages.nix</filename>. However, more complicated packages should be put in a separate file, typically in <filename>pkgs/development/perl-modules</filename>. Here is an example of the former:
<programlisting>
ClassC3 = buildPerlPackage rec {
name = "Class-C3-0.21";
src = fetchurl {
url = "mirror://cpan/authors/id/F/FL/FLORA/${name}.tar.gz";
sha256 = "1bl8z095y4js66pwxnm7s853pi9czala4sqc743fdlnk27kq94gz";
};
};
</programlisting>
Note the use of <literal>mirror://cpan/</literal>, and the <literal>${name}</literal> in the URL definition to ensure that the name attribute is consistent with the source that were actually downloading. Perl packages are made available in <filename>all-packages.nix</filename> through the variable <varname>perlPackages</varname>. For instance, if you have a package that needs <varname>ClassC3</varname>, you would typically write
<programlisting>
foo = import ../path/to/foo.nix {
inherit stdenv fetchurl ...;
inherit (perlPackages) ClassC3;
};
</programlisting>
in <filename>all-packages.nix</filename>. You can test building a Perl package as follows:
<screen>
<prompt>$ </prompt>nix-build -A perlPackages.ClassC3
</screen>
<varname>buildPerlPackage</varname> adds <literal>perl-</literal> to the start of the name attribute, so the package above is actually called <literal>perl-Class-C3-0.21</literal>. So to install it, you can say:
<screen>
<prompt>$ </prompt>nix-env -i perl-Class-C3
</screen>
(Of course you can also install using the attribute name: <literal>nix-env -i -A perlPackages.ClassC3</literal>.)
</para>
<para>
So what does <varname>buildPerlPackage</varname> do? It does the following:
<orderedlist>
<listitem>
<para>
In the configure phase, it calls <literal>perl Makefile.PL</literal> to generate a Makefile. You can set the variable <varname>makeMakerFlags</varname> to pass flags to <filename>Makefile.PL</filename>
</para>
</listitem>
<listitem>
<para>
It adds the contents of the <envar>PERL5LIB</envar> environment variable to <literal>#! .../bin/perl</literal> line of Perl scripts as <literal>-I<replaceable>dir</replaceable></literal> flags. This ensures that a script can find its dependencies. (This can cause this shebang line to become too long for Darwin to handle; see the note below.)
</para>
</listitem>
<listitem>
<para>
In the fixup phase, it writes the propagated build inputs (<varname>propagatedBuildInputs</varname>) to the file <filename>$out/nix-support/propagated-user-env-packages</filename>. <command>nix-env</command> recursively installs all packages listed in this file when you install a package that has it. This ensures that a Perl package can find its dependencies.
</para>
</listitem>
</orderedlist>
</para>
<para>
<varname>buildPerlPackage</varname> is built on top of <varname>stdenv</varname>, so everything can be customised in the usual way. For instance, the <literal>BerkeleyDB</literal> module has a <varname>preConfigure</varname> hook to generate a configuration file used by <filename>Makefile.PL</filename>:
<programlisting>
{ buildPerlPackage, fetchurl, db }:
buildPerlPackage rec {
name = "BerkeleyDB-0.36";
src = fetchurl {
url = "mirror://cpan/authors/id/P/PM/PMQS/${name}.tar.gz";
sha256 = "07xf50riarb60l1h6m2dqmql8q5dij619712fsgw7ach04d8g3z1";
};
preConfigure = ''
echo "LIB = ${db.out}/lib" > config.in
echo "INCLUDE = ${db.dev}/include" >> config.in
'';
}
</programlisting>
</para>
<para>
Dependencies on other Perl packages can be specified in the <varname>buildInputs</varname> and <varname>propagatedBuildInputs</varname> attributes. If something is exclusively a build-time dependency, use <varname>buildInputs</varname>; if its (also) a runtime dependency, use <varname>propagatedBuildInputs</varname>. For instance, this builds a Perl module that has runtime dependencies on a bunch of other modules:
<programlisting>
ClassC3Componentised = buildPerlPackage rec {
name = "Class-C3-Componentised-1.0004";
src = fetchurl {
url = "mirror://cpan/authors/id/A/AS/ASH/${name}.tar.gz";
sha256 = "0xql73jkcdbq4q9m0b0rnca6nrlvf5hyzy8is0crdk65bynvs8q1";
};
propagatedBuildInputs = [
ClassC3 ClassInspector TestException MROCompat
];
};
</programlisting>
</para>
<para>
On Darwin, if a script has too many <literal>-I<replaceable>dir</replaceable></literal> flags in its first line (its “shebang line”), it will not run. This can be worked around by calling the <literal>shortenPerlShebang</literal> function from the <literal>postInstall</literal> phase:
<programlisting>
{ stdenv, buildPerlPackage, fetchurl, shortenPerlShebang }:
ImageExifTool = buildPerlPackage {
pname = "Image-ExifTool";
version = "11.50";
src = fetchurl {
url = "https://www.sno.phy.queensu.ca/~phil/exiftool/Image-ExifTool-11.50.tar.gz";
sha256 = "0d8v48y94z8maxkmw1rv7v9m0jg2dc8xbp581njb6yhr7abwqdv3";
};
buildInputs = stdenv.lib.optional stdenv.isDarwin shortenPerlShebang;
postInstall = stdenv.lib.optional stdenv.isDarwin ''
shortenPerlShebang $out/bin/exiftool
'';
};
</programlisting>
This will remove the <literal>-I</literal> flags from the shebang line, rewrite them in the <literal>use lib</literal> form, and put them on the next line instead. This function can be given any number of Perl scripts as arguments; it will modify them in-place.
</para>
<section xml:id="ssec-generation-from-CPAN">
<title>Generation from CPAN</title>
<para>
Nix expressions for Perl packages can be generated (almost) automatically from CPAN. This is done by the program <command>nix-generate-from-cpan</command>, which can be installed as follows:
</para>
<screen>
<prompt>$ </prompt>nix-env -i nix-generate-from-cpan
</screen>
<para>
This program takes a Perl module name, looks it up on CPAN, fetches and unpacks the corresponding package, and prints a Nix expression on standard output. For example:
<screen>
<prompt>$ </prompt>nix-generate-from-cpan XML::Simple
XMLSimple = buildPerlPackage rec {
name = "XML-Simple-2.22";
src = fetchurl {
url = "mirror://cpan/authors/id/G/GR/GRANTM/${name}.tar.gz";
sha256 = "b9450ef22ea9644ae5d6ada086dc4300fa105be050a2030ebd4efd28c198eb49";
};
propagatedBuildInputs = [ XMLNamespaceSupport XMLSAX XMLSAXExpat ];
meta = {
description = "An API for simple XML files";
license = with stdenv.lib.licenses; [ artistic1 gpl1Plus ];
};
};
</screen>
The output can be pasted into <filename>pkgs/top-level/perl-packages.nix</filename> or wherever else you need it.
</para>
</section>
<section xml:id="ssec-perl-cross-compilation">
<title>Cross-compiling modules</title>
<para>
Nixpkgs has experimental support for cross-compiling Perl modules. In many cases, it will just work out of the box, even for modules with native extensions. Sometimes, however, the Makefile.PL for a module may (indirectly) import a native module. In that case, you will need to make a stub for that module that will satisfy the Makefile.PL and install it into <filename>lib/perl5/site_perl/cross_perl/${perl.version}</filename>. See the <varname>postInstall</varname> for <varname>DBI</varname> for an example.
</para>
</section>
</section>
</section>

View File

@ -135,3 +135,21 @@ Example of building `composer` with additional extensions:
enabled ++ (with all; [ imagick redis ]))
).packages.composer
```
### Overriding PHP packages {#ssec-php-user-guide-overriding-packages}
`php-packages.nix` form a scope, allowing us to override the packages defined within. For example, to apply a patch to a `mysqlnd` extension, you can simply pass an overlay-style function to `php`s `packageOverrides` argument:
```nix
php.override {
packageOverrides = final: prev: {
extensions = prev.extensions // {
mysqlnd = prev.extensions.mysqlnd.overrideAttrs (attrs: {
patches = attrs.patches or [] ++ [
];
});
};
};
}
```

View File

@ -1,4 +1,4 @@
# Python
# Python {#python}
## User Guide
@ -153,7 +153,7 @@ The dot product of [1 2] and [3 4] is: 11
But if we maintain the script ourselves, and if there are more dependencies, it
may be nice to encode those dependencies in source to make the script re-usable
without that bit of knowledge. That can be done by using `nix-shell` as a
[shebang](https://en.wikipedia.org/wiki/Shebang_(Unix), like so:
[shebang](https://en.wikipedia.org/wiki/Shebang_(Unix)), like so:
```python
#!/usr/bin/env nix-shell

View File

@ -0,0 +1,135 @@
# Qt {#sec-language-qt}
This section describes the differences between Nix expressions for Qt libraries and applications and Nix expressions for other C++ software. Some knowledge of the latter is assumed.
There are primarily two problems which the Qt infrastructure is designed to address: ensuring consistent versioning of all dependencies and finding dependencies at runtime.
## Nix expression for a Qt package (default.nix) {#qt-default-nix}
```{=docbook}
<programlisting>
{ mkDerivation, lib, qtbase }: <co xml:id='qt-default-nix-co-1' />
mkDerivation { <co xml:id='qt-default-nix-co-2' />
pname = "myapp";
version = "1.0";
buildInputs = [ qtbase ]; <co xml:id='qt-default-nix-co-3' />
}
</programlisting>
<calloutlist>
<callout arearefs='qt-default-nix-co-1'>
<para>
Import <literal>mkDerivation</literal> and Qt (such as <literal>qtbase</literal> modules directly. <emphasis>Do not</emphasis> import Qt package sets; the Qt versions of dependencies may not be coherent, causing build and runtime failures.
</para>
</callout>
<callout arearefs='qt-default-nix-co-2'>
<para>
Use <literal>mkDerivation</literal> instead of <literal>stdenv.mkDerivation</literal>. <literal>mkDerivation</literal> is a wrapper around <literal>stdenv.mkDerivation</literal> which applies some Qt-specific settings. This deriver accepts the same arguments as <literal>stdenv.mkDerivation</literal>; refer to <xref linkend='chap-stdenv' /> for details.
</para>
<para>
To use another deriver instead of <literal>stdenv.mkDerivation</literal>, use <literal>mkDerivationWith</literal>:
<programlisting>
mkDerivationWith myDeriver {
# ...
}
</programlisting>
If you cannot use <literal>mkDerivationWith</literal>, please refer to <xref linkend='qt-runtime-dependencies' />.
</para>
</callout>
<callout arearefs='qt-default-nix-co-3'>
<para>
<literal>mkDerivation</literal> accepts the same arguments as <literal>stdenv.mkDerivation</literal>, such as <literal>buildInputs</literal>.
</para>
</callout>
</calloutlist>
```
## Locating runtime dependencies {#qt-runtime-dependencies}
Qt applications need to be wrapped to find runtime dependencies. If you cannot use `mkDerivation` or `mkDerivationWith` above, include `wrapQtAppsHook` in `nativeBuildInputs`:
```nix
stdenv.mkDerivation {
# ...
nativeBuildInputs = [ wrapQtAppsHook ];
}
```
Entries added to `qtWrapperArgs` are used to modify the wrappers created by `wrapQtAppsHook`. The entries are passed as arguments to [wrapProgram executable makeWrapperArgs](#fun-wrapProgram).
```nix
mkDerivation {
# ...
qtWrapperArgs = [ ''--prefix PATH : /path/to/bin'' ];
}
```
Set `dontWrapQtApps` to stop applications from being wrapped automatically. It is required to wrap applications manually with `wrapQtApp`, using the syntax of [wrapProgram executable makeWrapperArgs](#fun-wrapProgram):
```nix
mkDerivation {
# ...
dontWrapQtApps = true;
preFixup = ''
wrapQtApp "$out/bin/myapp" --prefix PATH : /path/to/bin
'';
}
```
> Note: `wrapQtAppsHook` ignores files that are non-ELF executables. This means that scripts won't be automatically wrapped so you'll need to manually wrap them as previously mentioned. An example of when you'd always need to do this is with Python applications that use PyQT.
Libraries are built with every available version of Qt. Use the `meta.broken` attribute to disable the package for unsupported Qt versions:
```nix
mkDerivation {
# ...
# Disable this library with Qt &lt; 5.9.0
meta.broken = builtins.compareVersions qtbase.version "5.9.0" &lt; 0;
}
```
## Adding a library to Nixpkgs
Qt libraries are added to `qt5-packages.nix` and are made available for every Qt
version supported.
### Example adding a Qt library {#qt-library-all-packages-nix}
The following represents the contents of `qt5-packages.nix`.
```
{
# ...
mylib = callPackage ../path/to/mylib {};
# ...
}
```
## Adding an application to Nixpkgs
Applications that use Qt are also added to `qt5-packages.nix`. An alias is added
in the top-level `all-packages.nix` pointing to the package with the desired Qt5 version.
### Example adding a Qt application {#qt-application-all-packages-nix}
The following represents the contents of `qt5-packages.nix`.
```
{
# ...
myapp = callPackage ../path/to/myapp {};
# ...
}
```
The following represents the contents of `all-packages.nix`.
```
{
# ...
myapp = libsForQt5.myapp;
# ...
}
```

View File

@ -1,149 +0,0 @@
<section xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xml:id="sec-language-qt">
<title>Qt</title>
<para>
This section describes the differences between Nix expressions for Qt libraries and applications and Nix expressions for other C++ software. Some knowledge of the latter is assumed. There are primarily two problems which the Qt infrastructure is designed to address: ensuring consistent versioning of all dependencies and finding dependencies at runtime.
</para>
<example xml:id='qt-default-nix'>
<title>Nix expression for a Qt package (<filename>default.nix</filename>)</title>
<programlisting>
{ mkDerivation, lib, qtbase }: <co xml:id='qt-default-nix-co-1' />
mkDerivation { <co xml:id='qt-default-nix-co-2' />
pname = "myapp";
version = "1.0";
buildInputs = [ qtbase ]; <co xml:id='qt-default-nix-co-3' />
}
</programlisting>
</example>
<calloutlist>
<callout arearefs='qt-default-nix-co-1'>
<para>
Import <literal>mkDerivation</literal> and Qt (such as <literal>qtbase</literal> modules directly. <emphasis>Do not</emphasis> import Qt package sets; the Qt versions of dependencies may not be coherent, causing build and runtime failures.
</para>
</callout>
<callout arearefs='qt-default-nix-co-2'>
<para>
Use <literal>mkDerivation</literal> instead of <literal>stdenv.mkDerivation</literal>. <literal>mkDerivation</literal> is a wrapper around <literal>stdenv.mkDerivation</literal> which applies some Qt-specific settings. This deriver accepts the same arguments as <literal>stdenv.mkDerivation</literal>; refer to <xref linkend='chap-stdenv' /> for details.
</para>
<para>
To use another deriver instead of <literal>stdenv.mkDerivation</literal>, use <literal>mkDerivationWith</literal>:
<programlisting>
mkDerivationWith myDeriver {
# ...
}
</programlisting>
If you cannot use <literal>mkDerivationWith</literal>, please refer to <xref linkend='qt-runtime-dependencies' />.
</para>
</callout>
<callout arearefs='qt-default-nix-co-3'>
<para>
<literal>mkDerivation</literal> accepts the same arguments as <literal>stdenv.mkDerivation</literal>, such as <literal>buildInputs</literal>.
</para>
</callout>
</calloutlist>
<formalpara xml:id='qt-runtime-dependencies'>
<title>Locating runtime dependencies</title>
<para>
Qt applications need to be wrapped to find runtime dependencies. If you cannot use <literal>mkDerivation</literal> or <literal>mkDerivationWith</literal> above, include <literal>wrapQtAppsHook</literal> in <literal>nativeBuildInputs</literal>:
<programlisting>
stdenv.mkDerivation {
# ...
nativeBuildInputs = [ wrapQtAppsHook ];
}
</programlisting>
</para>
</formalpara>
<para>
Entries added to <literal>qtWrapperArgs</literal> are used to modify the wrappers created by <literal>wrapQtAppsHook</literal>. The entries are passed as arguments to <xref linkend='fun-wrapProgram' />.
<programlisting>
mkDerivation {
# ...
qtWrapperArgs = [ ''--prefix PATH : /path/to/bin'' ];
}
</programlisting>
</para>
<para>
Set <literal>dontWrapQtApps</literal> to stop applications from being wrapped automatically. It is required to wrap applications manually with <literal>wrapQtApp</literal>, using the syntax of <xref linkend='fun-wrapProgram' />:
<programlisting>
mkDerivation {
# ...
dontWrapQtApps = true;
preFixup = ''
wrapQtApp "$out/bin/myapp" --prefix PATH : /path/to/bin
'';
}
</programlisting>
</para>
<note>
<para>
<literal>wrapQtAppsHook</literal> ignores files that are non-ELF executables. This means that scripts won't be automatically wrapped so you'll need to manually wrap them as previously mentioned. An example of when you'd always need to do this is with Python applications that use PyQT.
</para>
</note>
<para>
Libraries are built with every available version of Qt. Use the <literal>meta.broken</literal> attribute to disable the package for unsupported Qt versions:
<programlisting>
mkDerivation {
# ...
# Disable this library with Qt &lt; 5.9.0
meta.broken = builtins.compareVersions qtbase.version "5.9.0" &lt; 0;
}
</programlisting>
</para>
<formalpara>
<title>Adding a library to Nixpkgs</title>
<para>
Add a Qt library to <filename>all-packages.nix</filename> by adding it to the collection inside <literal>mkLibsForQt5</literal>. This ensures that the library is built with every available version of Qt as needed.
<example xml:id='qt-library-all-packages-nix'>
<title>Adding a Qt library to <filename>all-packages.nix</filename></title>
<programlisting>
{
# ...
mkLibsForQt5 = self: with self; {
# ...
mylib = callPackage ../path/to/mylib {};
};
# ...
}
</programlisting>
</example>
</para>
</formalpara>
<formalpara>
<title>Adding an application to Nixpkgs</title>
<para>
Add a Qt application to <filename>all-packages.nix</filename> using <literal>libsForQt5.callPackage</literal> instead of the usual <literal>callPackage</literal>. The former ensures that all dependencies are built with the same version of Qt.
<example xml:id='qt-application-all-packages-nix'>
<title>Adding a Qt application to <filename>all-packages.nix</filename></title>
<programlisting>
{
# ...
myapp = libsForQt5.callPackage ../path/to/myapp/ {};
# ...
}
</programlisting>
</example>
</para>
</formalpara>
</section>

View File

@ -1,5 +1,4 @@
R
=
# R {#r}
## Installation
@ -106,6 +105,12 @@ mv cran-packages.nix.new cran-packages.nix
Rscript generate-r-packages.R bioc > bioc-packages.nix.new
mv bioc-packages.nix.new bioc-packages.nix
Rscript generate-r-packages.R bioc-annotation > bioc-annotation-packages.nix.new
mv bioc-annotation-packages.nix.new bioc-annotation-packages.nix
Rscript generate-r-packages.R bioc-experiment > bioc-experiment-packages.nix.new
mv bioc-experiment-packages.nix.new bioc-experiment-packages.nix
```
`generate-r-packages.R <repo>` reads `<repo>-packages.nix`, therefor the renaming.

View File

@ -1,74 +1,38 @@
---
title: Ruby
author: Michael Fellinger
date: 2019-05-23
---
# Ruby {#sec-language-ruby}
# Ruby
## Using Ruby
## User Guide
Several versions of Ruby interpreters are available on Nix, as well as over 250 gems and many applications written in Ruby. The attribute `ruby` refers to the default Ruby interpreter, which is currently MRI 2.6. It's also possible to refer to specific versions, e.g. `ruby_2_y`, `jruby`, or `mruby`.
### Using Ruby
In the Nixpkgs tree, Ruby packages can be found throughout, depending on what they do, and are called from the main package set. Ruby gems, however are separate sets, and there's one default set for each interpreter (currently MRI only).
#### Overview
There are two main approaches for using Ruby with gems. One is to use a specifically locked `Gemfile` for an application that has very strict dependencies. The other is to depend on the common gems, which we'll explain further down, and rely on them being updated regularly.
Several versions of Ruby interpreters are available on Nix, as well as over 250 gems and many applications written in Ruby.
The attribute `ruby` refers to the default Ruby interpreter, which is currently
MRI 2.5. It's also possible to refer to specific versions, e.g. `ruby_2_6`, `jruby`, or `mruby`.
The interpreters have common attributes, namely `gems`, and `withPackages`. So you can refer to `ruby.gems.nokogiri`, or `ruby_2_6.gems.nokogiri` to get the Nokogiri gem already compiled and ready to use.
In the nixpkgs tree, Ruby packages can be found throughout, depending on what
they do, and are called from the main package set. Ruby gems, however are
separate sets, and there's one default set for each interpreter (currently MRI
only).
Since not all gems have executables like `nokogiri`, it's usually more convenient to use the `withPackages` function like this: `ruby.withPackages (p: with p; [ nokogiri ])`. This will also make sure that the Ruby in your environment will be able to find the gem and it can be used in your Ruby code (for example via `ruby` or `irb` executables) via `require "nokogiri"` as usual.
There are two main approaches for using Ruby with gems.
One is to use a specifically locked `Gemfile` for an application that has very strict dependencies.
The other is to depend on the common gems, which we'll explain further down, and
rely on them being updated regularly.
### Temporary Ruby environment with `nix-shell`
The interpreters have common attributes, namely `gems`, and `withPackages`. So
you can refer to `ruby.gems.nokogiri`, or `ruby_2_5.gems.nokogiri` to get the
Nokogiri gem already compiled and ready to use.
Rather than having a single Ruby environment shared by all Ruby development projects on a system, Nix allows you to create separate environments per project. `nix-shell` gives you the possibility to temporarily load another environment akin to a combined `chruby` or `rvm` and `bundle exec`.
Since not all gems have executables like `nokogiri`, it's usually more
convenient to use the `withPackages` function like this:
`ruby.withPackages (p: with p; [ nokogiri ])`. This will also make sure that the
Ruby in your environment will be able to find the gem and it can be used in your
Ruby code (for example via `ruby` or `irb` executables) via `require "nokogiri"`
as usual.
There are two methods for loading a shell with Ruby packages. The first and recommended method is to create an environment with `ruby.withPackages` and load that.
#### Temporary Ruby environment with `nix-shell`
Rather than having a single Ruby environment shared by all Ruby
development projects on a system, Nix allows you to create separate
environments per project. `nix-shell` gives you the possibility to
temporarily load another environment akin to a combined `chruby` or
`rvm` and `bundle exec`.
There are two methods for loading a shell with Ruby packages. The first and
recommended method is to create an environment with `ruby.withPackages` and load
that.
```shell
nix-shell -p "ruby.withPackages (ps: with ps; [ nokogiri pry ])"
```ShellSession
$ nix-shell -p "ruby.withPackages (ps: with ps; [ nokogiri pry ])"
```
The other method, which is not recommended, is to create an environment and list
all the packages directly.
The other method, which is not recommended, is to create an environment and list all the packages directly.
```shell
nix-shell -p ruby.gems.nokogiri ruby.gems.pry
```ShellSession
$ nix-shell -p ruby.gems.nokogiri ruby.gems.pry
```
Again, it's possible to launch the interpreter from the shell. The Ruby
interpreter has the attribute `gems` which contains all Ruby gems for that
specific interpreter.
Again, it's possible to launch the interpreter from the shell. The Ruby interpreter has the attribute `gems` which contains all Ruby gems for that specific interpreter.
##### Load environment from `.nix` expression
#### Load Ruby environment from `.nix` expression
As explained in the Nix manual, `nix-shell` can also load an expression from a
`.nix` file. Say we want to have Ruby 2.5, `nokogori`, and `pry`. Consider a
`shell.nix` file with:
As explained in the Nix manual, `nix-shell` can also load an expression from a `.nix` file. Say we want to have Ruby 2.6, `nokogori`, and `pry`. Consider a `shell.nix` file with:
```nix
with import <nixpkgs> {};
@ -77,43 +41,33 @@ ruby.withPackages (ps: with ps; [ nokogiri pry ])
What's happening here?
1. We begin with importing the Nix Packages collections. `import <nixpkgs>`
imports the `<nixpkgs>` function, `{}` calls it and the `with` statement
brings all attributes of `nixpkgs` in the local scope. These attributes form
the main package set.
1. We begin with importing the Nix Packages collections. `import <nixpkgs>` imports the `<nixpkgs>` function, `{}` calls it and the `with` statement brings all attributes of `nixpkgs` in the local scope. These attributes form the main package set.
2. Then we create a Ruby environment with the `withPackages` function.
3. The `withPackages` function expects us to provide a function as an argument
that takes the set of all ruby gems and returns a list of packages to include
in the environment. Here, we select the packages `nokogiri` and `pry` from
the package set.
3. The `withPackages` function expects us to provide a function as an argument that takes the set of all ruby gems and returns a list of packages to include in the environment. Here, we select the packages `nokogiri` and `pry` from the package set.
##### Execute command with `--run`
#### Execute command with `--run`
A convenient flag for `nix-shell` is `--run`. It executes a command in the
`nix-shell`. We can e.g. directly open a `pry` REPL:
A convenient flag for `nix-shell` is `--run`. It executes a command in the `nix-shell`. We can e.g. directly open a `pry` REPL:
```shell
nix-shell -p "ruby.withPackages (ps: with ps; [ nokogiri pry ])" --run "pry"
```ShellSession
$ nix-shell -p "ruby.withPackages (ps: with ps; [ nokogiri pry ])" --run "pry"
```
Or immediately require `nokogiri` in pry:
```shell
nix-shell -p "ruby.withPackages (ps: with ps; [ nokogiri pry ])" --run "pry -rnokogiri"
```ShellSession
$ nix-shell -p "ruby.withPackages (ps: with ps; [ nokogiri pry ])" --run "pry -rnokogiri"
```
Or run a script using this environment:
```shell
nix-shell -p "ruby.withPackages (ps: with ps; [ nokogiri pry ])" --run "ruby example.rb"
```ShellSession
$ nix-shell -p "ruby.withPackages (ps: with ps; [ nokogiri pry ])" --run "ruby example.rb"
```
##### Using `nix-shell` as shebang
#### Using `nix-shell` as shebang
In fact, for the last case, there is a more convenient method. You can add a
[shebang](https://en.wikipedia.org/wiki/Shebang_(Unix)) to your script
specifying which dependencies `nix-shell` needs. With the following shebang, you
can just execute `./example.rb`, and it will run with all dependencies.
In fact, for the last case, there is a more convenient method. You can add a [shebang](<https://en.wikipedia.org/wiki/Shebang_(Unix)>) to your script specifying which dependencies `nix-shell` needs. With the following shebang, you can just execute `./example.rb`, and it will run with all dependencies.
```ruby
#! /usr/bin/env nix-shell
@ -126,35 +80,24 @@ body = RestClient.get('http://example.com').body
puts Nokogiri::HTML(body).at('h1').text
```
### Developing with Ruby
## Developing with Ruby
#### Using an existing Gemfile
### Using an existing Gemfile
In most cases, you'll already have a `Gemfile.lock` listing all your dependencies.
This can be used to generate a `gemset.nix` which is used to fetch the gems and
combine them into a single environment.
The reason why you need to have a separate file for this, is that Nix requires
you to have a checksum for each input to your build.
Since the `Gemfile.lock` that `bundler` generates doesn't provide us with
checksums, we have to first download each gem, calculate its SHA256, and store
it in this separate file.
In most cases, you'll already have a `Gemfile.lock` listing all your dependencies. This can be used to generate a `gemset.nix` which is used to fetch the gems and combine them into a single environment. The reason why you need to have a separate file for this, is that Nix requires you to have a checksum for each input to your build. Since the `Gemfile.lock` that `bundler` generates doesn't provide us with checksums, we have to first download each gem, calculate its SHA256, and store it in this separate file.
So the steps from having just a `Gemfile` to a `gemset.nix` are:
```shell
bundle lock
bundix
```ShellSession
$ bundle lock
$ bundix
```
If you already have a `Gemfile.lock`, you can simply run `bundix` and it will
work the same.
If you already have a `Gemfile.lock`, you can simply run `bundix` and it will work the same.
To update the gems in your `Gemfile.lock`, you may use the `bundix -l` flag,
which will create a new `Gemfile.lock` in case the `Gemfile` has a more recent
time of modification.
To update the gems in your `Gemfile.lock`, you may use the `bundix -l` flag, which will create a new `Gemfile.lock` in case the `Gemfile` has a more recent time of modification.
Once the `gemset.nix` is generated, it can be used in a
`bundlerEnv` derivation. Here is an example you could use for your `shell.nix`:
Once the `gemset.nix` is generated, it can be used in a `bundlerEnv` derivation. Here is an example you could use for your `shell.nix`:
```nix
# ...
@ -166,41 +109,26 @@ let
in mkShell { buildInputs = [ gems gems.wrappedRuby ]; }
```
With this file in your directory, you can run `nix-shell` to build and use the gems.
The important parts here are `bundlerEnv` and `wrappedRuby`.
With this file in your directory, you can run `nix-shell` to build and use the gems. The important parts here are `bundlerEnv` and `wrappedRuby`.
The `bundlerEnv` is a wrapper over all the gems in your gemset. This means that
all the `/lib` and `/bin` directories will be available, and the executables of
all gems (even of indirect dependencies) will end up in your `$PATH`.
The `wrappedRuby` provides you with all executables that come with Ruby itself,
but wrapped so they can easily find the gems in your gemset.
The `bundlerEnv` is a wrapper over all the gems in your gemset. This means that all the `/lib` and `/bin` directories will be available, and the executables of all gems (even of indirect dependencies) will end up in your `$PATH`. The `wrappedRuby` provides you with all executables that come with Ruby itself, but wrapped so they can easily find the gems in your gemset.
One common issue that you might have is that you have Ruby 2.6, but also
`bundler` in your gemset. That leads to a conflict for `/bin/bundle` and
`/bin/bundler`. You can resolve this by wrapping either your Ruby or your gems
in a `lowPrio` call. So in order to give the `bundler` from your gemset
priority, it would be used like this:
One common issue that you might have is that you have Ruby 2.6, but also `bundler` in your gemset. That leads to a conflict for `/bin/bundle` and `/bin/bundler`. You can resolve this by wrapping either your Ruby or your gems in a `lowPrio` call. So in order to give the `bundler` from your gemset priority, it would be used like this:
```nix
# ...
mkShell { buildInputs = [ gems (lowPrio gems.wrappedRuby) ]; }
```
### Gem-specific configurations and workarounds
#### Gem-specific configurations and workarounds
In some cases, especially if the gem has native extensions, you might need to modify the way the gem is built.
In some cases, especially if the gem has native extensions, you might need to
modify the way the gem is built.
This is done via a common configuration file that includes all of the workarounds for each gem.
This is done via a common configuration file that includes all of the
workarounds for each gem.
This file lives at `/pkgs/development/ruby-modules/gem-config/default.nix`, since it already contains a lot of entries, it should be pretty easy to add the modifications you need for your needs.
This file lives at `/pkgs/development/ruby-modules/gem-config/default.nix`,
since it already contains a lot of entries, it should be pretty easy to add the
modifications you need for your needs.
In the meanwhile, or if the modification is for a private gem, you can also add
the configuration to only your own environment.
In the meanwhile, or if the modification is for a private gem, you can also add the configuration to only your own environment.
Two places that allow this modification are the `ruby` derivation, or `bundlerEnv`.
@ -261,10 +189,9 @@ let
in pkgs.ruby.withPackages (ps: with ps; [ pg ])
```
Then we can get whichever postgresql version we desire and the `pg` gem will
always reference it correctly:
Then we can get whichever postgresql version we desire and the `pg` gem will always reference it correctly:
```shell
```ShellSession
$ nix-shell --argstr pg_version 9_4 --run 'ruby -rpg -e "puts PG.library_version"'
90421
@ -272,24 +199,15 @@ $ nix-shell --run 'ruby -rpg -e "puts PG.library_version"'
100007
```
Of course for this use-case one could also use overlays since the configuration
for `pg` depends on the `postgresql` alias, but for demonstration purposes this
has to suffice.
Of course for this use-case one could also use overlays since the configuration for `pg` depends on the `postgresql` alias, but for demonstration purposes this has to suffice.
#### Adding a gem to the default gemset
### Adding a gem to the default gemset
Now that you know how to get a working Ruby environment with Nix, it's time to
go forward and start actually developing with Ruby.
We will first have a look at how Ruby gems are packaged on Nix. Then, we will
look at how you can use development mode with your code.
Now that you know how to get a working Ruby environment with Nix, it's time to go forward and start actually developing with Ruby. We will first have a look at how Ruby gems are packaged on Nix. Then, we will look at how you can use development mode with your code.
All gems in the standard set are automatically generated from a single
`Gemfile`. The dependency resolution is done with `bundler` and makes it more
likely that all gems are compatible to each other.
All gems in the standard set are automatically generated from a single `Gemfile`. The dependency resolution is done with `bundler` and makes it more likely that all gems are compatible to each other.
In order to add a new gem to nixpkgs, you can put it into the
`/pkgs/development/ruby-modules/with-packages/Gemfile` and run
`./maintainers/scripts/update-ruby-packages`.
In order to add a new gem to nixpkgs, you can put it into the `/pkgs/development/ruby-modules/with-packages/Gemfile` and run `./maintainers/scripts/update-ruby-packages`.
To test that it works, you can then try using the gem with:
@ -297,16 +215,11 @@ To test that it works, you can then try using the gem with:
NIX_PATH=nixpkgs=$PWD nix-shell -p "ruby.withPackages (ps: with ps; [ name-of-your-gem ])"
```
#### Packaging applications
### Packaging applications
A common task is to add a ruby executable to nixpkgs, popular examples would be
`chef`, `jekyll`, or `sass`. A good way to do that is to use the `bundlerApp`
function, that allows you to make a package that only exposes the listed
executables, otherwise the package may cause conflicts through common paths like
`bin/rake` or `bin/bundler` that aren't meant to be used.
A common task is to add a ruby executable to nixpkgs, popular examples would be `chef`, `jekyll`, or `sass`. A good way to do that is to use the `bundlerApp` function, that allows you to make a package that only exposes the listed executables, otherwise the package may cause conflicts through common paths like `bin/rake` or `bin/bundler` that aren't meant to be used.
The absolute easiest way to do that is to write a
`Gemfile` along these lines:
The absolute easiest way to do that is to write a `Gemfile` along these lines:
```ruby
source 'https://rubygems.org' do
@ -314,10 +227,7 @@ source 'https://rubygems.org' do
end
```
If you want to package a specific version, you can use the standard Gemfile
syntax for that, e.g. `gem 'mdl', '0.5.0'`, but if you want the latest stable
version anyway, it's easier to update by simply running the `bundle lock` and
`bundix` steps again.
If you want to package a specific version, you can use the standard Gemfile syntax for that, e.g. `gem 'mdl', '0.5.0'`, but if you want the latest stable version anyway, it's easier to update by simply running the `bundle lock` and `bundix` steps again.
Now you can also also make a `default.nix` that looks like this:
@ -331,20 +241,15 @@ bundlerApp {
}
```
All that's left to do is to generate the corresponding `Gemfile.lock` and
`gemset.nix` as described above in the `Using an existing Gemfile` section.
All that's left to do is to generate the corresponding `Gemfile.lock` and `gemset.nix` as described above in the `Using an existing Gemfile` section.
##### Packaging executables that require wrapping
#### Packaging executables that require wrapping
Sometimes your app will depend on other executables at runtime, and tries to
find it through the `PATH` environment variable.
Sometimes your app will depend on other executables at runtime, and tries to find it through the `PATH` environment variable.
In this case, you can provide a `postBuild` hook to `bundlerApp` that wraps the
gem in another script that prefixes the `PATH`.
In this case, you can provide a `postBuild` hook to `bundlerApp` that wraps the gem in another script that prefixes the `PATH`.
Of course you could also make a custom `gemConfig` if you know exactly how to
patch it, but it's usually much easier to maintain with a simple wrapper so the
patch doesn't have to be adjusted for each version.
Of course you could also make a custom `gemConfig` if you know exactly how to patch it, but it's usually much easier to maintain with a simple wrapper so the patch doesn't have to be adjusted for each version.
Here's another example:

View File

@ -1,107 +0,0 @@
<section xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xml:id="sec-language-ruby">
<title>Ruby</title>
<para>
There currently is support to bundle applications that are packaged as Ruby gems. The utility "bundix" allows you to write a <filename>Gemfile</filename>, let bundler create a <filename>Gemfile.lock</filename>, and then convert this into a nix expression that contains all Gem dependencies automatically.
</para>
<para>
For example, to package sensu, we did:
</para>
<screen>
<prompt>$ </prompt>cd pkgs/servers/monitoring
<prompt>$ </prompt>mkdir sensu
<prompt>$ </prompt>cd sensu
<prompt>$ </prompt>cat > Gemfile
source 'https://rubygems.org'
gem 'sensu'
<prompt>$ </prompt>$(nix-build '&lt;nixpkgs>' -A bundix --no-out-link)/bin/bundix --magic
<prompt>$ </prompt>cat > default.nix
{ lib, bundlerEnv, ruby }:
bundlerEnv rec {
name = "sensu-${version}";
version = (import gemset).sensu.version;
inherit ruby;
# expects Gemfile, Gemfile.lock and gemset.nix in the same directory
gemdir = ./.;
meta = with lib; {
description = "A monitoring framework that aims to be simple, malleable, and scalable";
homepage = "http://sensuapp.org/";
license = with licenses; mit;
maintainers = with maintainers; [ theuni ];
platforms = platforms.unix;
};
}
</screen>
<para>
Please check in the <filename>Gemfile</filename>, <filename>Gemfile.lock</filename> and the <filename>gemset.nix</filename> so future updates can be run easily.
</para>
<para>
Updating Ruby packages can then be done like this:
</para>
<screen>
<prompt>$ </prompt>cd pkgs/servers/monitoring/sensu
<prompt>$ </prompt>nix-shell -p bundler --run 'bundle lock --update'
<prompt>$ </prompt>nix-shell -p bundix --run 'bundix'
</screen>
<para>
For tools written in Ruby - i.e. where the desire is to install a package and then execute e.g. <command>rake</command> at the command line, there is an alternative builder called <literal>bundlerApp</literal>. Set up the <filename>gemset.nix</filename> the same way, and then, for example:
</para>
<programlisting>
<![CDATA[{ lib, bundlerApp }:
bundlerApp {
pname = "corundum";
gemdir = ./.;
exes = [ "corundum-skel" ];
meta = with lib; {
description = "Tool and libraries for maintaining Ruby gems.";
homepage = "https://github.com/nyarly/corundum";
license = licenses.mit;
maintainers = [ maintainers.nyarly ];
platforms = platforms.unix;
};
}]]>
</programlisting>
<para>
The chief advantage of <literal>bundlerApp</literal> over <literal>bundlerEnv</literal> is the executables introduced in the environment are precisely those selected in the <literal>exes</literal> list, as opposed to <literal>bundlerEnv</literal> which adds all the executables made available by gems in the gemset, which can mean e.g. <command>rspec</command> or <command>rake</command> in unpredictable versions available from various packages.
</para>
<para>
Resulting derivations for both builders also have two helpful attributes, <literal>env</literal> and <literal>wrappedRuby</literal>. The first one allows one to quickly drop into <command>nix-shell</command> with the specified environment present. E.g. <command>nix-shell -A sensu.env</command> would give you an environment with Ruby preset so it has all the libraries necessary for <literal>sensu</literal> in its paths. The second one can be used to make derivations from custom Ruby scripts which have <filename>Gemfile</filename>s with their dependencies specified. It is a derivation with <command>ruby</command> wrapped so it can find all the needed dependencies. For example, to make a derivation <literal>my-script</literal> for a <filename>my-script.rb</filename> (which should be placed in <filename>bin</filename>) you should run <command>bundix</command> as specified above and then use <literal>bundlerEnv</literal> like this:
</para>
<programlisting>
<![CDATA[let env = bundlerEnv {
name = "my-script-env";
inherit ruby;
gemfile = ./Gemfile;
lockfile = ./Gemfile.lock;
gemset = ./gemset.nix;
};
in stdenv.mkDerivation {
name = "my-script";
buildInputs = [ env.wrappedRuby ];
script = ./my-script.rb;
buildCommand = ''
install -D -m755 $script $out/bin/my-script
patchShebangs $out/bin/my-script
'';
}]]>
</programlisting>
</section>

View File

@ -1,10 +1,4 @@
---
title: Rust
author: Matthias Beyer
date: 2017-03-05
---
# Rust
# Rust {#rust}
To install the rust compiler and cargo put
@ -16,9 +10,9 @@ cargo
into the `environment.systemPackages` or bring them into
scope with `nix-shell -p rustc cargo`.
For daily builds (beta and nightly) use either rustup from
nixpkgs or use the [Rust nightlies
overlay](#using-the-rust-nightlies-overlay).
For other versions such as daily builds (beta and nightly),
use either `rustup` from nixpkgs (which will manage the rust installation in your home directory),
or use Mozilla's [Rust nightlies overlay](#using-the-rust-nightlies-overlay).
## Compiling Rust applications with Cargo
@ -27,18 +21,18 @@ Rust applications are packaged by using the `buildRustPackage` helper from `rust
```
rustPlatform.buildRustPackage rec {
pname = "ripgrep";
version = "11.0.2";
version = "12.1.1";
src = fetchFromGitHub {
owner = "BurntSushi";
repo = pname;
rev = version;
sha256 = "1iga3320mgi7m853la55xip514a3chqsdi1a1rwv25lr9b1p7vd3";
sha256 = "1hqps7l5qrjh9f914r5i6kmcz6f1yb951nv4lby0cjnp5l253kps";
};
cargoSha256 = "17ldqr3asrdcsh4l29m3b5r37r5d0b3npq1lrgjmxb6vlx6a36qh";
cargoSha256 = "03wf9r2csi6jpa7v5sw5lpxkrk4wfzwmzx7k3991q3bdjzcwnnwp";
meta = with stdenv.lib; {
meta = with lib; {
description = "A fast line-oriented regex search tool, similar to ag and ack";
homepage = "https://github.com/BurntSushi/ripgrep";
license = licenses.unlicense;
@ -47,10 +41,31 @@ rustPlatform.buildRustPackage rec {
}
```
`buildRustPackage` requires a `cargoSha256` attribute which is computed over
all crate sources of this package. Currently it is obtained by inserting a
fake checksum into the expression and building the package once. The correct
checksum can then be taken from the failed build.
`buildRustPackage` requires either the `cargoSha256` or the
`cargoHash` attribute which is computed over all crate sources of this
package. `cargoHash256` is used for traditional Nix SHA-256 hashes,
such as the one in the example above. `cargoHash` should instead be
used for [SRI](https://www.w3.org/TR/SRI/) hashes. For example:
```
cargoHash = "sha256-l1vL2ZdtDRxSGvP0X/l3nMw8+6WF67KPutJEzUROjg8=";
```
Both types of hashes are permitted when contributing to nixpkgs. The
Cargo hash is obtained by inserting a fake checksum into the
expression and building the package once. The correct checksum can
then be taken from the failed build. A fake hash can be used for
`cargoSha256` as follows:
```
cargoSha256 = lib.fakeSha256;
```
For `cargoHash` you can use:
```
cargoHash = lib.fakeHash;
```
Per the instructions in the [Cargo Book](https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html)
best practices guide, Rust applications should always commit the `Cargo.lock`
@ -63,9 +78,52 @@ The fetcher will verify that the `Cargo.lock` file is in sync with the `src`
attribute, and fail the build if not. It will also will compress the vendor
directory into a tar.gz archive.
### Building a crate for a different target
### Cross compilation
To build your crate with a different cargo `--target` simply specify the `target` attribute:
By default, Rust packages are compiled for the host platform, just like any
other package is. The `--target` passed to rust tools is computed from this.
By default, it takes the `stdenv.hostPlatform.config` and replaces components
where they are known to differ. But there are ways to customize the argument:
- To choose a different target by name, define
`stdenv.hostPlatform.rustc.config` as that name (a string), and that
name will be used instead.
For example:
```nix
import <nixpkgs> {
crossSystem = (import <nixpkgs/lib>).systems.examples.armhf-embedded // {
rustc.config = "thumbv7em-none-eabi";
};
}
```
will result in:
```shell
--target thumbv7em-none-eabi
```
- To pass a completely custom target, define
`stdenv.hostPlatform.rustc.config` with its name, and
`stdenv.hostPlatform.rustc.platform` with the value. The value will be
serialized to JSON in a file called
`${stdenv.hostPlatform.rustc.config}.json`, and the path of that file
will be used instead.
For example:
```nix
import <nixpkgs> {
crossSystem = (import <nixpkgs/lib>).systems.examples.armhf-embedded // {
rustc.config = "thumb-crazy";
rustc.platform = { foo = ""; bar = ""; };
};
}
will result in:
```shell
--target /nix/store/asdfasdfsadf-thumb-crazy.json # contains {"foo":"","bar":""}
```
Finally, as an ad-hoc escape hatch, a computed target (string or JSON file
path) can be passed directly to `buildRustPackage`:
```nix
pkgs.rustPlatform.buildRustPackage {
@ -74,6 +132,15 @@ pkgs.rustPlatform.buildRustPackage {
}
```
This is useful to avoid rebuilding Rust tools, since they are actually target
agnostic and don't need to be rebuilt. But in the future, we should always
build the Rust tools and standard library crates separately so there is no
reason not to take the `stdenv.hostPlatform.rustc`-modifying approach, and the
ad-hoc escape hatch to `buildRustPackage` can be removed.
Note that currently custom targets aren't compiled with `std`, so `cargo test`
will fail. This can be ignored by adding `doCheck = false;` to your derivation.
### Running package tests
When using `buildRustPackage`, the `checkPhase` is enabled by default and runs
@ -413,7 +480,7 @@ stdenv.mkDerivation {
rustc cargo
# Example Build-time Additional Dependencies
pkgconfig
pkg-config
];
buildInputs = [
# Example Run-time Additional Dependencies
@ -455,7 +522,7 @@ stdenv.mkDerivation {
latest.rustChannels.nightly.rust
# Add some extra dependencies from `pkgs`
pkgconfig openssl
pkg-config openssl
];
# Set Environment Variables
@ -478,8 +545,15 @@ Mozilla provides an overlay for nixpkgs to bring a nightly version of Rust into
This overlay can _also_ be used to install recent unstable or stable versions
of Rust, if desired.
To use this overlay, clone
[nixpkgs-mozilla](https://github.com/mozilla/nixpkgs-mozilla),
### Rust overlay installation
You can use this overlay by either changing your local nixpkgs configuration,
or by adding the overlay declaratively in a nix expression, e.g. in `configuration.nix`.
For more information see [#sec-overlays-install](the manual on installing overlays).
#### Imperative rust overlay installation
Clone [nixpkgs-mozilla](https://github.com/mozilla/nixpkgs-mozilla),
and create a symbolic link to the file
[rust-overlay.nix](https://github.com/mozilla/nixpkgs-mozilla/blob/master/rust-overlay.nix)
in the `~/.config/nixpkgs/overlays` directory.
@ -488,14 +562,43 @@ in the `~/.config/nixpkgs/overlays` directory.
$ mkdir -p ~/.config/nixpkgs/overlays
$ ln -s $(pwd)/nixpkgs-mozilla/rust-overlay.nix ~/.config/nixpkgs/overlays/rust-overlay.nix
The latest version can be installed with the following command:
### Declarative rust overlay installation
$ nix-env -Ai nixos.latest.rustChannels.stable.rust
Add the following to your `configuration.nix`, `home-configuration.nix`, `shell.nix`, or similar:
```
{ pkgs ? import <nixpkgs> {
overlays = [
(import (builtins.fetchTarball https://github.com/mozilla/nixpkgs-mozilla/archive/master.tar.gz))
# Further overlays go here
];
};
};
```
Note that this will fetch the latest overlay version when rebuilding your system.
### Rust overlay usage
The overlay contains attribute sets corresponding to different versions of the rust toolchain, such as:
* `latest.rustChannels.stable`
* `latest.rustChannels.nightly`
* a function `rustChannelOf`, called as `(rustChannelOf { date = "2018-04-11"; channel = "nightly"; })`, or...
* `(nixpkgs.rustChannelOf { rustToolchain = ./rust-toolchain; })` if you have a local `rust-toolchain` file (see https://github.com/mozilla/nixpkgs-mozilla#using-in-nix-expressions for an example)
Each of these contain packages such as `rust`, which contains your usual rust development tools with the respective toolchain chosen.
For example, you might want to add `latest.rustChannels.stable.rust` to the list of packages in your configuration.
Imperatively, the latest stable version can be installed with the following command:
$ nix-env -Ai nixpkgs.latest.rustChannels.stable.rust
Or using the attribute with nix-shell:
$ nix-shell -p nixos.latest.rustChannels.stable.rust
$ nix-shell -p nixpkgs.latest.rustChannels.stable.rust
Substitute the `nixpkgs` prefix with `nixos` on NixOS.
To install the beta or nightly channel, "stable" should be substituted by
"nightly" or "beta", or
use the function provided by this overlay to pull a version based on a

View File

@ -0,0 +1,127 @@
# TeX Live {#sec-language-texlive}
Since release 15.09 there is a new TeX Live packaging that lives entirely under attribute `texlive`.
## User's guide {#sec-language-texlive-user-guide}
- For basic usage just pull `texlive.combined.scheme-basic` for an environment with basic LaTeX support.
- It typically won't work to use separately installed packages together. Instead, you can build a custom set of packages like this:
```nix
texlive.combine {
inherit (texlive) scheme-small collection-langkorean algorithms cm-super;
}
```
- There are all the schemes, collections and a few thousand packages, as defined upstream (perhaps with tiny differences).
- By default you only get executables and files needed during runtime, and a little documentation for the core packages. To change that, you need to add `pkgFilter` function to `combine`.
```nix
texlive.combine {
# inherit (texlive) whatever-you-want;
pkgFilter = pkg:
pkg.tlType == "run" || pkg.tlType == "bin" || pkg.pname == "cm-super";
# elem tlType [ "run" "bin" "doc" "source" ]
# there are also other attributes: version, name
}
```
- You can list packages e.g. by `nix repl`.
```ShellSession
$ nix repl
nix-repl> :l <nixpkgs>
nix-repl> texlive.collection-[TAB]
```
- Note that the wrapper assumes that the result has a chance to be useful. For example, the core executables should be present, as well as some core data files. The supported way of ensuring this is by including some scheme, for example `scheme-basic`, into the combination.
## Custom packages {#sec-language-texlive-custom-packages}
You may find that you need to use an external TeX package. A derivation for such package has to provide contents of the "texmf" directory in its output and provide the `tlType` attribute. Here is a (very verbose) example:
```nix
with import <nixpkgs> {};
let
foiltex_run = stdenvNoCC.mkDerivation {
pname = "latex-foiltex";
version = "2.1.4b";
passthru.tlType = "run";
srcs = [
(fetchurl {
url = "http://mirrors.ctan.org/macros/latex/contrib/foiltex/foiltex.dtx";
sha256 = "07frz0krpz7kkcwlayrwrj2a2pixmv0icbngyw92srp9fp23cqpz";
})
(fetchurl {
url = "http://mirrors.ctan.org/macros/latex/contrib/foiltex/foiltex.ins";
sha256 = "09wkyidxk3n3zvqxfs61wlypmbhi1pxmjdi1kns9n2ky8ykbff99";
})
];
unpackPhase = ''
runHook preUnpack
for _src in $srcs; do
cp "$_src" $(stripHash "$_src")
done
runHook postUnpack
'';
nativeBuildInputs = [ texlive.combined.scheme-small ];
dontConfigure = true;
buildPhase = ''
runHook preBuild
# Generate the style files
latex foiltex.ins
runHook postBuild
'';
installPhase = ''
runHook preInstall
path="$out/tex/latex/foiltex"
mkdir -p "$path"
cp *.{cls,def,clo} "$path/"
runHook postInstall
'';
meta = with lib; {
description = "A LaTeX2e class for overhead transparencies";
license = licenses.unfreeRedistributable;
maintainers = with maintainers; [ veprbl ];
platforms = platforms.all;
};
};
foiltex = { pkgs = [ foiltex_run ]; };
latex_with_foiltex = texlive.combine {
inherit (texlive) scheme-small;
inherit foiltex;
};
in
runCommand "test.pdf" {
nativeBuildInputs = [ latex_with_foiltex ];
} ''
cat >test.tex <<EOF
\documentclass{foils}
\title{Presentation title}
\date{}
\begin{document}
\maketitle
\end{document}
EOF
pdflatex test.tex
cp test.pdf $out
''
```

View File

@ -1,152 +0,0 @@
<section xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xml:id="sec-language-texlive">
<title>TeX Live</title>
<para>
Since release 15.09 there is a new TeX Live packaging that lives entirely under attribute <varname>texlive</varname>.
</para>
<section xml:id="sec-language-texlive-users-guide">
<title>User's guide</title>
<itemizedlist>
<listitem>
<para>
For basic usage just pull <varname>texlive.combined.scheme-basic</varname> for an environment with basic LaTeX support.
</para>
</listitem>
<listitem>
<para>
It typically won't work to use separately installed packages together. Instead, you can build a custom set of packages like this:
<programlisting>
texlive.combine {
inherit (texlive) scheme-small collection-langkorean algorithms cm-super;
}
</programlisting>
There are all the schemes, collections and a few thousand packages, as defined upstream (perhaps with tiny differences).
</para>
</listitem>
<listitem>
<para>
By default you only get executables and files needed during runtime, and a little documentation for the core packages. To change that, you need to add <varname>pkgFilter</varname> function to <varname>combine</varname>.
<programlisting>
texlive.combine {
# inherit (texlive) whatever-you-want;
pkgFilter = pkg:
pkg.tlType == "run" || pkg.tlType == "bin" || pkg.pname == "cm-super";
# elem tlType [ "run" "bin" "doc" "source" ]
# there are also other attributes: version, name
}
</programlisting>
</para>
</listitem>
<listitem>
<para>
You can list packages e.g. by <command>nix repl</command>.
<programlisting>
<prompt>$ </prompt>nix repl
<prompt>nix-repl> </prompt>:l &lt;nixpkgs>
<prompt>nix-repl> </prompt>texlive.collection-<keycap function="tab" />
</programlisting>
</para>
</listitem>
<listitem>
<para>
Note that the wrapper assumes that the result has a chance to be useful. For example, the core executables should be present, as well as some core data files. The supported way of ensuring this is by including some scheme, for example <varname>scheme-basic</varname>, into the combination.
</para>
</listitem>
</itemizedlist>
</section>
<section xml:id="sec-language-texlive-custom-packages">
<title>Custom packages</title>
<para>
You may find that you need to use an external TeX package. A derivation for such package has to provide contents of the "texmf" directory in its output and provide the <varname>tlType</varname> attribute. Here is a (very verbose) example:
<programlisting><![CDATA[
with import <nixpkgs> {};
let
foiltex_run = stdenvNoCC.mkDerivation {
pname = "latex-foiltex";
version = "2.1.4b";
passthru.tlType = "run";
srcs = [
(fetchurl {
url = "http://mirrors.ctan.org/macros/latex/contrib/foiltex/foiltex.dtx";
sha256 = "07frz0krpz7kkcwlayrwrj2a2pixmv0icbngyw92srp9fp23cqpz";
})
(fetchurl {
url = "http://mirrors.ctan.org/macros/latex/contrib/foiltex/foiltex.ins";
sha256 = "09wkyidxk3n3zvqxfs61wlypmbhi1pxmjdi1kns9n2ky8ykbff99";
})
];
unpackPhase = ''
runHook preUnpack
for _src in $srcs; do
cp "$_src" $(stripHash "$_src")
done
runHook postUnpack
'';
nativeBuildInputs = [ texlive.combined.scheme-small ];
dontConfigure = true;
buildPhase = ''
runHook preBuild
# Generate the style files
latex foiltex.ins
runHook postBuild
'';
installPhase = ''
runHook preInstall
path="$out/tex/latex/foiltex"
mkdir -p "$path"
cp *.{cls,def,clo} "$path/"
runHook postInstall
'';
meta = with lib; {
description = "A LaTeX2e class for overhead transparencies";
license = licenses.unfreeRedistributable;
maintainers = with maintainers; [ veprbl ];
platforms = platforms.all;
};
};
foiltex = { pkgs = [ foiltex_run ]; };
latex_with_foiltex = texlive.combine {
inherit (texlive) scheme-small;
inherit foiltex;
};
in
runCommand "test.pdf" {
nativeBuildInputs = [ latex_with_foiltex ];
} ''
cat >test.tex <<EOF
\documentclass{foils}
\title{Presentation title}
\date{}
\begin{document}
\maketitle
\end{document}
EOF
pdflatex test.tex
cp test.pdf $out
''
]]></programlisting>
</para>
</section>
</section>

View File

@ -1,9 +1,4 @@
---
title: Titanium
author: Sander van der Burg
date: 2018-11-18
---
# Titanium
# Titanium {#titanium}
The Nixpkgs repository contains facilities to deploy a variety of versions of
the [Titanium SDK](https://www.appcelerator.com) versions, a cross-platform

View File

@ -1,9 +1,4 @@
---
title: User's Guide for Vim in Nixpkgs
author: Marc Weber
date: 2016-06-25
---
# Vim
# Vim {#vim}
Both Neovim and Vim can be configured to include your favorite plugins
and additional libraries.
@ -265,6 +260,20 @@ To add a new plugin, run `./update.py --add "[owner]/[name]"`. **NOTE**: This sc
Finally, there are some plugins that are also packaged in nodePackages because they have Javascript-related build steps, such as running webpack. Those plugins are not listed in `vim-plugin-names` or managed by `update.py` at all, and are included separately in `overrides.nix`. Currently, all these plugins are related to the `coc.nvim` ecosystem of Language Server Protocol integration with vim/neovim.
## Updating plugins in nixpkgs
Run the update script with a GitHub API token that has at least `public_repo` access. Running the script without the token is likely to result in rate-limiting (429 errors). For steps on creating an API token, please refer to [GitHub's token documentation](https://docs.github.com/en/free-pro-team@latest/github/authenticating-to-github/creating-a-personal-access-token).
```sh
GITHUB_API_TOKEN=my_token ./pkgs/misc/vim-plugins/update.py
```
Alternatively, set the number of processes to a lower count to avoid rate-limiting.
```sh
./pkgs/misc/vim-plugins/update.py --proc 1
```
## Important repositories
- [vim-pi](https://bitbucket.org/vimcommunity/vim-pi) is a plugin repository

View File

@ -18,13 +18,13 @@
<xi:include href="stdenv/stdenv.xml" />
<xi:include href="stdenv/meta.xml" />
<xi:include href="stdenv/multiple-output.xml" />
<xi:include href="stdenv/cross-compilation.xml" />
<xi:include href="stdenv/cross-compilation.chapter.xml" />
<xi:include href="stdenv/platform-notes.xml" />
</part>
<part>
<title>Builders</title>
<xi:include href="builders/fetchers.xml" />
<xi:include href="builders/trivial-builders.xml" />
<xi:include href="builders/fetchers.chapter.xml" />
<xi:include href="builders/trivial-builders.chapter.xml" />
<xi:include href="builders/special.xml" />
<xi:include href="builders/images.xml" />
<xi:include href="languages-frameworks/index.xml" />
@ -34,7 +34,7 @@
<title>Contributing to Nixpkgs</title>
<xi:include href="contributing/quick-start.xml" />
<xi:include href="contributing/coding-conventions.xml" />
<xi:include href="contributing/submitting-changes.xml" />
<xi:include href="contributing/submitting-changes.chapter.xml" />
<xi:include href="contributing/reviewing-contributions.xml" />
<xi:include href="contributing/contributing-to-documentation.xml" />
</part>

View File

@ -1,10 +1,4 @@
---
title: Preface
author: Frederik Rietdijk
date: 2015-11-25
---
# Preface
# Preface {#preface}
The Nix Packages collection (Nixpkgs) is a set of thousands of packages for the
[Nix package manager](https://nixos.org/nix/), released under a

View File

@ -1,5 +1,3 @@
{ pkgs ? import ../. {} }:
(import ./default.nix {}).overrideAttrs (x: {
buildInputs = x.buildInputs ++ [ pkgs.xmloscopy pkgs.ruby ];
})
{ pkgs ? import ../. { } }:
(import ./default.nix { }).overrideAttrs
(x: { buildInputs = (x.buildInputs or [ ]) ++ [ pkgs.xmloscopy pkgs.ruby ]; })

View File

@ -0,0 +1,197 @@
# Cross-compilation {#chap-cross}
## Introduction {#sec-cross-intro}
"Cross-compilation" means compiling a program on one machine for another type of machine. For example, a typical use of cross-compilation is to compile programs for embedded devices. These devices often don't have the computing power and memory to compile their own programs. One might think that cross-compilation is a fairly niche concern. However, there are significant advantages to rigorously distinguishing between build-time and run-time environments! Significant, because the benefits apply even when one is developing and deploying on the same machine. Nixpkgs is increasingly adopting the opinion that packages should be written with cross-compilation in mind, and Nixpkgs should evaluate in a similar way (by minimizing cross-compilation-specific special cases) whether or not one is cross-compiling.
This chapter will be organized in three parts. First, it will describe the basics of how to package software in a way that supports cross-compilation. Second, it will describe how to use Nixpkgs when cross-compiling. Third, it will describe the internal infrastructure supporting cross-compilation.
## Packaging in a cross-friendly manner {#sec-cross-packaging}
### Platform parameters {#ssec-cross-platform-parameters}
Nixpkgs follows the [conventions of GNU autoconf](https://gcc.gnu.org/onlinedocs/gccint/Configure-Terms.html). We distinguish between 3 types of platforms when building a derivation: _build_, _host_, and _target_. In summary, _build_ is the platform on which a package is being built, _host_ is the platform on which it will run. The third attribute, _target_, is relevant only for certain specific compilers and build tools.
In Nixpkgs, these three platforms are defined as attribute sets under the names `buildPlatform`, `hostPlatform`, and `targetPlatform`. They are always defined as attributes in the standard environment. That means one can access them like:
```nix
{ stdenv, fooDep, barDep, .. }: ...stdenv.buildPlatform...
```
`buildPlatform`
: The "build platform" is the platform on which a package is built. Once someone has a built package, or pre-built binary package, the build platform should not matter and can be ignored.
`hostPlatform`
: The "host platform" is the platform on which a package will be run. This is the simplest platform to understand, but also the one with the worst name.
`targetPlatform`
: The "target platform" attribute is, unlike the other two attributes, not actually fundamental to the process of building software. Instead, it is only relevant for compatibility with building certain specific compilers and build tools. It can be safely ignored for all other packages.
: The build process of certain compilers is written in such a way that the compiler resulting from a single build can itself only produce binaries for a single platform. The task of specifying this single "target platform" is thus pushed to build time of the compiler. The root cause of this is that the compiler (which will be run on the host) and the standard library/runtime (which will be run on the target) are built by a single build process.
: There is no fundamental need to think about a single target ahead of time like this. If the tool supports modular or pluggable backends, both the need to specify the target at build time and the constraint of having only a single target disappear. An example of such a tool is LLVM.
: Although the existence of a "target platform" is arguably a historical mistake, it is a common one: examples of tools that suffer from it are GCC, Binutils, GHC and Autoconf. Nixpkgs tries to avoid sharing in the mistake where possible. Still, because the concept of a target platform is so ingrained, it is best to support it as is.
The exact schema these fields follow is a bit ill-defined due to a long and convoluted evolution, but this is slowly being cleaned up. You can see examples of ones used in practice in `lib.systems.examples`; note how they are not all very consistent. For now, here are few fields can count on them containing:
`system`
: This is a two-component shorthand for the platform. Examples of this would be "x86_64-darwin" and "i686-linux"; see `lib.systems.doubles` for more. The first component corresponds to the CPU architecture of the platform and the second to the operating system of the platform (`[cpu]-[os]`). This format has built-in support in Nix, such as the `builtins.currentSystem` impure string.
`config`
: This is a 3- or 4- component shorthand for the platform. Examples of this would be `x86_64-unknown-linux-gnu` and `aarch64-apple-darwin14`. This is a standard format called the "LLVM target triple", as they are pioneered by LLVM. In the 4-part form, this corresponds to `[cpu]-[vendor]-[os]-[abi]`. This format is strictly more informative than the "Nix host double", as the previous format could analogously be termed. This needs a better name than `config`!
`parsed`
: This is a Nix representation of a parsed LLVM target triple with white-listed components. This can be specified directly, or actually parsed from the `config`. See `lib.systems.parse` for the exact representation.
`libc`
: This is a string identifying the standard C library used. Valid identifiers include "glibc" for GNU libc, "libSystem" for Darwin's Libsystem, and "uclibc" for µClibc. It should probably be refactored to use the module system, like `parse`.
`is*`
: These predicates are defined in `lib.systems.inspect`, and slapped onto every platform. They are superior to the ones in `stdenv` as they force the user to be explicit about which platform they are inspecting. Please use these instead of those.
`platform`
: This is, quite frankly, a dumping ground of ad-hoc settings (it's an attribute set). See `lib.systems.platforms` for examples—there's hopefully one in there that will work verbatim for each platform that is working. Please help us triage these flags and give them better homes!
### Theory of dependency categorization {#ssec-cross-dependency-categorization}
::: note
This is a rather philosophical description that isn't very Nixpkgs-specific. For an overview of all the relevant attributes given to `mkDerivation`, see <xref linkend="ssec-stdenv-dependencies"/>. For a description of how everything is implemented, see <xref linkend="ssec-cross-dependency-implementation"/>.
:::
In this section we explore the relationship between both runtime and build-time dependencies and the 3 Autoconf platforms.
A run time dependency between two packages requires that their host platforms match. This is directly implied by the meaning of "host platform" and "runtime dependency": The package dependency exists while both packages are running on a single host platform.
A build time dependency, however, has a shift in platforms between the depending package and the depended-on package. "build time dependency" means that to build the depending package we need to be able to run the depended-on's package. The depending package's build platform is therefore equal to the depended-on package's host platform.
If both the dependency and depending packages aren't compilers or other machine-code-producing tools, we're done. And indeed `buildInputs` and `nativeBuildInputs` have covered these simpler cases for many years. But if the dependency does produce machine code, we might need to worry about its target platform too. In principle, that target platform might be any of the depending package's build, host, or target platforms, but we prohibit dependencies from a "later" platform to an earlier platform to limit confusion because we've never seen a legitimate use for them.
Finally, if the depending package is a compiler or other machine-code-producing tool, it might need dependencies that run at "emit time". This is for compilers that (regrettably) insist on being built together with their source languages' standard libraries. Assuming build != host != target, a run-time dependency of the standard library cannot be run at the compiler's build time or run time, but only at the run time of code emitted by the compiler.
Putting this all together, that means we have dependencies in the form "host → target", in at most the following six combinations:
#### Possible dependency types
| Dependency's host platform | Dependency's target platform |
| -- | -- |
| build | build |
| build | host |
| build | target |
| host | host |
| host | target |
| target | target |
Some examples will make this table clearer. Suppose there's some package that is being built with a `(build, host, target)` platform triple of `(foo, bar, baz)`. If it has a build-time library dependency, that would be a "host → build" dependency with a triple of `(foo, foo, *)` (the target platform is irrelevant). If it needs a compiler to be built, that would be a "build → host" dependency with a triple of `(foo, foo, *)` (the target platform is irrelevant). That compiler, would be built with another compiler, also "build → host" dependency, with a triple of `(foo, foo, foo)`.
### Cross packaging cookbook {#ssec-cross-cookbook}
Some frequently encountered problems when packaging for cross-compilation should be answered here. Ideally, the information above is exhaustive, so this section cannot provide any new information, but it is ludicrous and cruel to expect everyone to spend effort working through the interaction of many features just to figure out the same answer to the same common problem. Feel free to add to this list!
#### What if my package's build system needs to build a C program to be run under the build environment? {#cross-qa-build-c-program-in-build-environment}
Add the following to your `mkDerivation` invocation.
```nix
depsBuildBuild = [ buildPackages.stdenv.cc ];
```
#### My package fails to find `ar`. {#cross-qa-fails-to-find-ar}
Many packages assume that an unprefixed `ar` is available, but Nix doesn't provide one. It only provides a prefixed one, just as it only does for all the other binutils programs. It may be necessary to patch the package to fix the build system to use a prefixed `ar`.
#### My package's testsuite needs to run host platform code. {#cross-testsuite-runs-host-code}
Add the following to your `mkDerivation` invocation.
```nix
doCheck = stdenv.hostPlatform == stdenv.buildPlatfrom;
```
## Cross-building packages {#sec-cross-usage}
Nixpkgs can be instantiated with `localSystem` alone, in which case there is no cross-compiling and everything is built by and for that system, or also with `crossSystem`, in which case packages run on the latter, but all building happens on the former. Both parameters take the same schema as the 3 (build, host, and target) platforms defined in the previous section. As mentioned above, `lib.systems.examples` has some platforms which are used as arguments for these parameters in practice. You can use them programmatically, or on the command line:
```ShellSession
$ nix-build '<nixpkgs>' --arg crossSystem '(import <nixpkgs/lib>).systems.examples.fooBarBaz' -A whatever
```
::: note
Eventually we would like to make these platform examples an unnecessary convenience so that
```ShellSession
$ nix-build '<nixpkgs>' --arg crossSystem '{ config = "<arch>-<os>-<vendor>-<abi>"; }' -A whatever
```
works in the vast majority of cases. The problem today is dependencies on other sorts of configuration which aren't given proper defaults. We rely on the examples to crudely to set those configuration parameters in some vaguely sane manner on the users behalf. Issue [\#34274](https://github.com/NixOS/nixpkgs/issues/34274) tracks this inconvenience along with its root cause in crufty configuration options.
:::
While one is free to pass both parameters in full, there's a lot of logic to fill in missing fields. As discussed in the previous section, only one of `system`, `config`, and `parsed` is needed to infer the other two. Additionally, `libc` will be inferred from `parse`. Finally, `localSystem.system` is also _impurely_ inferred based on the platform evaluation occurs. This means it is often not necessary to pass `localSystem` at all, as in the command-line example in the previous paragraph.
::: note
Many sources (manual, wiki, etc) probably mention passing `system`, `platform`, along with the optional `crossSystem` to Nixpkgs: `import <nixpkgs> { system = ..; platform = ..; crossSystem = ..; }`. Passing those two instead of `localSystem` is still supported for compatibility, but is discouraged. Indeed, much of the inference we do for these parameters is motivated by compatibility as much as convenience.
:::
One would think that `localSystem` and `crossSystem` overlap horribly with the three `*Platforms` (`buildPlatform`, `hostPlatform,` and `targetPlatform`; see `stage.nix` or the manual). Actually, those identifiers are purposefully not used here to draw a subtle but important distinction: While the granularity of having 3 platforms is necessary to properly *build* packages, it is overkill for specifying the user's *intent* when making a build plan or package set. A simple "build vs deploy" dichotomy is adequate: the sliding window principle described in the previous section shows how to interpolate between the these two "end points" to get the 3 platform triple for each bootstrapping stage. That means for any package a given package set, even those not bound on the top level but only reachable via dependencies or `buildPackages`, the three platforms will be defined as one of `localSystem` or `crossSystem`, with the former replacing the latter as one traverses build-time dependencies. A last simple difference is that `crossSystem` should be null when one doesn't want to cross-compile, while the `*Platform`s are always non-null. `localSystem` is always non-null.
## Cross-compilation infrastructure {#sec-cross-infra}
### Implementation of dependencies {#ssec-cross-dependency-implementation}
The categories of dependencies developed in <xref linkend="ssec-cross-dependency-categorization"/> are specified as lists of derivations given to `mkDerivation`, as documented in <xref linkend="ssec-stdenv-dependencies"/>. In short, each list of dependencies for "host → target" of "foo → bar" is called `depsFooBar`, with exceptions for backwards compatibility that `depsBuildHost` is instead called `nativeBuildInputs` and `depsHostTarget` is instead called `buildInputs`. Nixpkgs is now structured so that each `depsFooBar` is automatically taken from `pkgsFooBar`. (These `pkgsFooBar`s are quite new, so there is no special case for `nativeBuildInputs` and `buildInputs`.) For example, `pkgsBuildHost.gcc` should be used at build-time, while `pkgsHostTarget.gcc` should be used at run-time.
Now, for most of Nixpkgs's history, there were no `pkgsFooBar` attributes, and most packages have not been refactored to use it explicitly. Prior to those, there were just `buildPackages`, `pkgs`, and `targetPackages`. Those are now redefined as aliases to `pkgsBuildHost`, `pkgsHostTarget`, and `pkgsTargetTarget`. It is acceptable, even recommended, to use them for libraries to show that the host platform is irrelevant.
But before that, there was just `pkgs`, even though both `buildInputs` and `nativeBuildInputs` existed. \[Cross barely worked, and those were implemented with some hacks on `mkDerivation` to override dependencies.\] What this means is the vast majority of packages do not use any explicit package set to populate their dependencies, just using whatever `callPackage` gives them even if they do correctly sort their dependencies into the multiple lists described above. And indeed, asking that users both sort their dependencies, _and_ take them from the right attribute set, is both too onerous and redundant, so the recommended approach (for now) is to continue just categorizing by list and not using an explicit package set.
To make this work, we "splice" together the six `pkgsFooBar` package sets and have `callPackage` actually take its arguments from that. This is currently implemented in `pkgs/top-level/splice.nix`. `mkDerivation` then, for each dependency attribute, pulls the right derivation out from the splice. This splicing can be skipped when not cross-compiling as the package sets are the same, but still is a bit slow for cross-compiling. We'd like to do something better, but haven't come up with anything yet.
### Bootstrapping {#ssec-bootstrapping}
Each of the package sets described above come from a single bootstrapping stage. While `pkgs/top-level/default.nix`, coordinates the composition of stages at a high level, `pkgs/top-level/stage.nix` "ties the knot" (creates the fixed point) of each stage. The package sets are defined per-stage however, so they can be thought of as edges between stages (the nodes) in a graph. Compositions like `pkgsBuildTarget.targetPackages` can be thought of as paths to this graph.
While there are many package sets, and thus many edges, the stages can also be arranged in a linear chain. In other words, many of the edges are redundant as far as connectivity is concerned. This hinges on the type of bootstrapping we do. Currently for cross it is:
1. `(native, native, native)`
2. `(native, native, foreign)`
3. `(native, foreign, foreign)`
In each stage, `pkgsBuildHost` refers to the previous stage, `pkgsBuildBuild` refers to the one before that, and `pkgsHostTarget` refers to the current one, and `pkgsTargetTarget` refers to the next one. When there is no previous or next stage, they instead refer to the current stage. Note how all the invariants regarding the mapping between dependency and depending packages' build host and target platforms are preserved. `pkgsBuildTarget` and `pkgsHostHost` are more complex in that the stage fitting the requirements isn't always a fixed chain of "prevs" and "nexts" away (modulo the "saturating" self-references at the ends). We just special case each instead. All the primary edges are implemented is in `pkgs/stdenv/booter.nix`, and secondarily aliases in `pkgs/top-level/stage.nix`.
::: note
The native stages are bootstrapped in legacy ways that predate the current cross implementation. This is why the bootstrapping stages leading up to the final stages are ignored in the previous paragraph.
:::
If one looks at the 3 platform triples, one can see that they overlap such that one could put them together into a chain like:
```
(native, native, native, foreign, foreign)
```
If one imagines the saturating self references at the end being replaced with infinite stages, and then overlays those platform triples, one ends up with the infinite tuple:
```
(native..., native, native, native, foreign, foreign, foreign...)
```
On can then imagine any sequence of platforms such that there are bootstrap stages with their 3 platforms determined by "sliding a window" that is the 3 tuple through the sequence. This was the original model for bootstrapping. Without a target platform (assume a better world where all compilers are multi-target and all standard libraries are built in their own derivation), this is sufficient. Conversely if one wishes to cross compile "faster", with a "Canadian Cross" bootstrapping stage where `build != host != target`, more bootstrapping stages are needed since no sliding window provides the pesky `pkgsBuildTarget` package set since it skips the Canadian cross stage's "host".
::: note
It is much better to refer to `buildPackages` than `targetPackages`, or more broadly package sets that do not mention "target". There are three reasons for this.
First, it is because bootstrapping stages do not have a unique `targetPackages`. For example a `(x86-linux, x86-linux, arm-linux)` and `(x86-linux, x86-linux, x86-windows)` package set both have a `(x86-linux, x86-linux, x86-linux)` package set. Because there is no canonical `targetPackages` for such a native (`build == host == target`) package set, we set their `targetPackages`
Second, it is because this is a frequent source of hard-to-follow "infinite recursions" / cycles. When only package sets that don't mention target are used, the package set forms a directed acyclic graph. This means that all cycles that exist are confined to one stage. This means they are a lot smaller, and easier to follow in the code or a backtrace. It also means they are present in native and cross builds alike, and so more likely to be caught by CI and other users.
Thirdly, it is because everything target-mentioning only exists to accommodate compilers with lousy build systems that insist on the compiler itself and standard library being built together. Of course that is bad because bigger derivations means longer rebuilds. It is also problematic because it tends to make the standard libraries less like other libraries than they could be, complicating code and build systems alike. Because of the other problems, and because of these innate disadvantages, compilers ought to be packaged another way where possible.
:::
::: note
If one explores Nixpkgs, they will see derivations with names like `gccCross`. Such `*Cross` derivations is a holdover from before we properly distinguished between the host and target platforms—the derivation with "Cross" in the name covered the `build = host != target` case, while the other covered the `host = target`, with build platform the same or not based on whether one was using its `.nativeDrv` or `.crossDrv`. This ugliness will disappear soon.
:::

View File

@ -1,394 +0,0 @@
<chapter xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xml:id="chap-cross">
<title>Cross-compilation</title>
<section xml:id="sec-cross-intro">
<title>Introduction</title>
<para>
"Cross-compilation" means compiling a program on one machine for another type of machine. For example, a typical use of cross-compilation is to compile programs for embedded devices. These devices often don't have the computing power and memory to compile their own programs. One might think that cross-compilation is a fairly niche concern. However, there are significant advantages to rigorously distinguishing between build-time and run-time environments! Significant, because the benefits apply even when one is developing and deploying on the same machine. Nixpkgs is increasingly adopting the opinion that packages should be written with cross-compilation in mind, and nixpkgs should evaluate in a similar way (by minimizing cross-compilation-specific special cases) whether or not one is cross-compiling.
</para>
<para>
This chapter will be organized in three parts. First, it will describe the basics of how to package software in a way that supports cross-compilation. Second, it will describe how to use Nixpkgs when cross-compiling. Third, it will describe the internal infrastructure supporting cross-compilation.
</para>
</section>
<!--============================================================-->
<section xml:id="sec-cross-packaging">
<title>Packaging in a cross-friendly manner</title>
<section xml:id="ssec-cross-platform-parameters">
<title>Platform parameters</title>
<para>
Nixpkgs follows the <link
xlink:href="https://gcc.gnu.org/onlinedocs/gccint/Configure-Terms.html">conventions of GNU autoconf</link>. We distinguish between 3 types of platforms when building a derivation: <wordasword>build</wordasword>, <wordasword>host</wordasword>, and <wordasword>target</wordasword>. In summary, <wordasword>build</wordasword> is the platform on which a package is being built, <wordasword>host</wordasword> is the platform on which it will run. The third attribute, <wordasword>target</wordasword>, is relevant only for certain specific compilers and build tools.
</para>
<para>
In Nixpkgs, these three platforms are defined as attribute sets under the names <literal>buildPlatform</literal>, <literal>hostPlatform</literal>, and <literal>targetPlatform</literal>. They are always defined as attributes in the standard environment. That means one can access them like:
<programlisting>{ stdenv, fooDep, barDep, .. }: ...stdenv.buildPlatform...</programlisting>
.
</para>
<variablelist>
<varlistentry>
<term>
<varname>buildPlatform</varname>
</term>
<listitem>
<para>
The "build platform" is the platform on which a package is built. Once someone has a built package, or pre-built binary package, the build platform should not matter and can be ignored.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<varname>hostPlatform</varname>
</term>
<listitem>
<para>
The "host platform" is the platform on which a package will be run. This is the simplest platform to understand, but also the one with the worst name.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<varname>targetPlatform</varname>
</term>
<listitem>
<para>
The "target platform" attribute is, unlike the other two attributes, not actually fundamental to the process of building software. Instead, it is only relevant for compatibility with building certain specific compilers and build tools. It can be safely ignored for all other packages.
</para>
<para>
The build process of certain compilers is written in such a way that the compiler resulting from a single build can itself only produce binaries for a single platform. The task of specifying this single "target platform" is thus pushed to build time of the compiler. The root cause of this is that the compiler (which will be run on the host) and the standard library/runtime (which will be run on the target) are built by a single build process.
</para>
<para>
There is no fundamental need to think about a single target ahead of time like this. If the tool supports modular or pluggable backends, both the need to specify the target at build time and the constraint of having only a single target disappear. An example of such a tool is LLVM.
</para>
<para>
Although the existence of a "target platfom" is arguably a historical mistake, it is a common one: examples of tools that suffer from it are GCC, Binutils, GHC and Autoconf. Nixpkgs tries to avoid sharing in the mistake where possible. Still, because the concept of a target platform is so ingrained, it is best to support it as is.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
The exact schema these fields follow is a bit ill-defined due to a long and convoluted evolution, but this is slowly being cleaned up. You can see examples of ones used in practice in <literal>lib.systems.examples</literal>; note how they are not all very consistent. For now, here are few fields can count on them containing:
</para>
<variablelist>
<varlistentry>
<term>
<varname>system</varname>
</term>
<listitem>
<para>
This is a two-component shorthand for the platform. Examples of this would be "x86_64-darwin" and "i686-linux"; see <literal>lib.systems.doubles</literal> for more. The first component corresponds to the CPU architecture of the platform and the second to the operating system of the platform (<literal>[cpu]-[os]</literal>). This format has built-in support in Nix, such as the <varname>builtins.currentSystem</varname> impure string.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<varname>config</varname>
</term>
<listitem>
<para>
This is a 3- or 4- component shorthand for the platform. Examples of this would be <literal>x86_64-unknown-linux-gnu</literal> and <literal>aarch64-apple-darwin14</literal>. This is a standard format called the "LLVM target triple", as they are pioneered by LLVM. In the 4-part form, this corresponds to <literal>[cpu]-[vendor]-[os]-[abi]</literal>. This format is strictly more informative than the "Nix host double", as the previous format could analogously be termed. This needs a better name than <varname>config</varname>!
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<varname>parsed</varname>
</term>
<listitem>
<para>
This is a Nix representation of a parsed LLVM target triple with white-listed components. This can be specified directly, or actually parsed from the <varname>config</varname>. See <literal>lib.systems.parse</literal> for the exact representation.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<varname>libc</varname>
</term>
<listitem>
<para>
This is a string identifying the standard C library used. Valid identifiers include "glibc" for GNU libc, "libSystem" for Darwin's Libsystem, and "uclibc" for µClibc. It should probably be refactored to use the module system, like <varname>parse</varname>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<varname>is*</varname>
</term>
<listitem>
<para>
These predicates are defined in <literal>lib.systems.inspect</literal>, and slapped onto every platform. They are superior to the ones in <varname>stdenv</varname> as they force the user to be explicit about which platform they are inspecting. Please use these instead of those.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<varname>platform</varname>
</term>
<listitem>
<para>
This is, quite frankly, a dumping ground of ad-hoc settings (it's an attribute set). See <literal>lib.systems.platforms</literal> for examples—there's hopefully one in there that will work verbatim for each platform that is working. Please help us triage these flags and give them better homes!
</para>
</listitem>
</varlistentry>
</variablelist>
</section>
<section xml:id="ssec-cross-dependency-categorization">
<title>Theory of dependency categorization</title>
<note>
<para>
This is a rather philosophical description that isn't very Nixpkgs-specific. For an overview of all the relevant attributes given to <varname>mkDerivation</varname>, see <xref
linkend="ssec-stdenv-dependencies"/>. For a description of how everything is implemented, see <xref linkend="ssec-cross-dependency-implementation" />.
</para>
</note>
<para>
In this section we explore the relationship between both runtime and build-time dependencies and the 3 Autoconf platforms.
</para>
<para>
A run time dependency between two packages requires that their host platforms match. This is directly implied by the meaning of "host platform" and "runtime dependency": The package dependency exists while both packages are running on a single host platform.
</para>
<para>
A build time dependency, however, has a shift in platforms between the depending package and the depended-on package. "build time dependency" means that to build the depending package we need to be able to run the depended-on's package. The depending package's build platform is therefore equal to the depended-on package's host platform.
</para>
<para>
If both the dependency and depending packages aren't compilers or other machine-code-producing tools, we're done. And indeed <varname>buildInputs</varname> and <varname>nativeBuildInputs</varname> have covered these simpler build-time and run-time (respectively) changes for many years. But if the dependency does produce machine code, we might need to worry about its target platform too. In principle, that target platform might be any of the depending package's build, host, or target platforms, but we prohibit dependencies from a "later" platform to an earlier platform to limit confusion because we've never seen a legitimate use for them.
</para>
<para>
Finally, if the depending package is a compiler or other machine-code-producing tool, it might need dependencies that run at "emit time". This is for compilers that (regrettably) insist on being built together with their source langauges' standard libraries. Assuming build != host != target, a run-time dependency of the standard library cannot be run at the compiler's build time or run time, but only at the run time of code emitted by the compiler.
</para>
<para>
Putting this all together, that means we have dependencies in the form "host → target", in at most the following six combinations:
<table>
<caption>Possible dependency types</caption>
<thead>
<tr>
<th>Dependency's host platform</th>
<th>Dependency's target platform</th>
</tr>
</thead>
<tbody>
<tr>
<td>build</td>
<td>build</td>
</tr>
<tr>
<td>build</td>
<td>host</td>
</tr>
<tr>
<td>build</td>
<td>target</td>
</tr>
<tr>
<td>host</td>
<td>host</td>
</tr>
<tr>
<td>host</td>
<td>target</td>
</tr>
<tr>
<td>target</td>
<td>target</td>
</tr>
</tbody>
</table>
</para>
<para>
Some examples will make this table clearer. Suppose there's some package that is being built with a <literal>(build, host, target)</literal> platform triple of <literal>(foo, bar, baz)</literal>. If it has a build-time library dependency, that would be a "host → build" dependency with a triple of <literal>(foo, foo, *)</literal> (the target platform is irrelevant). If it needs a compiler to be built, that would be a "build → host" dependency with a triple of <literal>(foo, foo, *)</literal> (the target platform is irrelevant). That compiler, would be built with another compiler, also "build → host" dependency, with a triple of <literal>(foo, foo, foo)</literal>.
</para>
</section>
<section xml:id="ssec-cross-cookbook">
<title>Cross packaging cookbook</title>
<para>
Some frequently encountered problems when packaging for cross-compilation should be answered here. Ideally, the information above is exhaustive, so this section cannot provide any new information, but it is ludicrous and cruel to expect everyone to spend effort working through the interaction of many features just to figure out the same answer to the same common problem. Feel free to add to this list!
</para>
<qandaset>
<qandaentry xml:id="cross-qa-build-c-program-in-build-environment">
<question>
<para>
What if my package's build system needs to build a C program to be run under the build environment?
</para>
</question>
<answer>
<para>
<programlisting>depsBuildBuild = [ buildPackages.stdenv.cc ];</programlisting>
Add it to your <function>mkDerivation</function> invocation.
</para>
</answer>
</qandaentry>
<qandaentry xml:id="cross-qa-fails-to-find-ar">
<question>
<para>
My package fails to find <command>ar</command>.
</para>
</question>
<answer>
<para>
Many packages assume that an unprefixed <command>ar</command> is available, but Nix doesn't provide one. It only provides a prefixed one, just as it only does for all the other binutils programs. It may be necessary to patch the package to fix the build system to use a prefixed <command>ar</command>.
</para>
</answer>
</qandaentry>
<qandaentry xml:id="cross-testsuite-runs-host-code">
<question>
<para>
My package's testsuite needs to run host platform code.
</para>
</question>
<answer>
<para>
<programlisting>doCheck = stdenv.hostPlatform == stdenv.buildPlatfrom;</programlisting>
Add it to your <function>mkDerivation</function> invocation.
</para>
</answer>
</qandaentry>
</qandaset>
</section>
</section>
<!--============================================================-->
<section xml:id="sec-cross-usage">
<title>Cross-building packages</title>
<para>
Nixpkgs can be instantiated with <varname>localSystem</varname> alone, in which case there is no cross-compiling and everything is built by and for that system, or also with <varname>crossSystem</varname>, in which case packages run on the latter, but all building happens on the former. Both parameters take the same schema as the 3 (build, host, and target) platforms defined in the previous section. As mentioned above, <literal>lib.systems.examples</literal> has some platforms which are used as arguments for these parameters in practice. You can use them programmatically, or on the command line:
<programlisting>
nix-build '&lt;nixpkgs&gt;' --arg crossSystem '(import &lt;nixpkgs/lib&gt;).systems.examples.fooBarBaz' -A whatever</programlisting>
</para>
<note>
<para>
Eventually we would like to make these platform examples an unnecessary convenience so that
<programlisting>
nix-build '&lt;nixpkgs&gt;' --arg crossSystem '{ config = "&lt;arch&gt;-&lt;os&gt;-&lt;vendor&gt;-&lt;abi&gt;"; }' -A whatever</programlisting>
works in the vast majority of cases. The problem today is dependencies on other sorts of configuration which aren't given proper defaults. We rely on the examples to crudely to set those configuration parameters in some vaguely sane manner on the users behalf. Issue <link xlink:href="https://github.com/NixOS/nixpkgs/issues/34274">#34274</link> tracks this inconvenience along with its root cause in crufty configuration options.
</para>
</note>
<para>
While one is free to pass both parameters in full, there's a lot of logic to fill in missing fields. As discussed in the previous section, only one of <varname>system</varname>, <varname>config</varname>, and <varname>parsed</varname> is needed to infer the other two. Additionally, <varname>libc</varname> will be inferred from <varname>parse</varname>. Finally, <literal>localSystem.system</literal> is also <emphasis>impurely</emphasis> inferred based on the platform evaluation occurs. This means it is often not necessary to pass <varname>localSystem</varname> at all, as in the command-line example in the previous paragraph.
</para>
<note>
<para>
Many sources (manual, wiki, etc) probably mention passing <varname>system</varname>, <varname>platform</varname>, along with the optional <varname>crossSystem</varname> to nixpkgs: <literal>import &lt;nixpkgs&gt; { system = ..; platform = ..; crossSystem = ..; }</literal>. Passing those two instead of <varname>localSystem</varname> is still supported for compatibility, but is discouraged. Indeed, much of the inference we do for these parameters is motivated by compatibility as much as convenience.
</para>
</note>
<para>
One would think that <varname>localSystem</varname> and <varname>crossSystem</varname> overlap horribly with the three <varname>*Platforms</varname> (<varname>buildPlatform</varname>, <varname>hostPlatform,</varname> and <varname>targetPlatform</varname>; see <varname>stage.nix</varname> or the manual). Actually, those identifiers are purposefully not used here to draw a subtle but important distinction: While the granularity of having 3 platforms is necessary to properly *build* packages, it is overkill for specifying the user's *intent* when making a build plan or package set. A simple "build vs deploy" dichotomy is adequate: the sliding window principle described in the previous section shows how to interpolate between the these two "end points" to get the 3 platform triple for each bootstrapping stage. That means for any package a given package set, even those not bound on the top level but only reachable via dependencies or <varname>buildPackages</varname>, the three platforms will be defined as one of <varname>localSystem</varname> or <varname>crossSystem</varname>, with the former replacing the latter as one traverses build-time dependencies. A last simple difference is that <varname>crossSystem</varname> should be null when one doesn't want to cross-compile, while the <varname>*Platform</varname>s are always non-null. <varname>localSystem</varname> is always non-null.
</para>
</section>
<!--============================================================-->
<section xml:id="sec-cross-infra">
<title>Cross-compilation infrastructure</title>
<section xml:id="ssec-cross-dependency-implementation">
<title>Implementation of dependencies</title>
<para>
The categorizes of dependencies developed in <xref
linkend="ssec-cross-dependency-categorization"/> are specified as lists of derivations given to <varname>mkDerivation</varname>, as documented in <xref linkend="ssec-stdenv-dependencies"/>. In short, each list of dependencies for "host → target" of "foo → bar" is called <varname>depsFooBar</varname>, with exceptions for backwards compatibility that <varname>depsBuildHost</varname> is instead called <varname>nativeBuildInputs</varname> and <varname>depsHostTarget</varname> is instead called <varname>buildInputs</varname>. Nixpkgs is now structured so that each <varname>depsFooBar</varname> is automatically taken from <varname>pkgsFooBar</varname>. (These <varname>pkgsFooBar</varname>s are quite new, so there is no special case for <varname>nativeBuildInputs</varname> and <varname>buildInputs</varname>.) For example, <varname>pkgsBuildHost.gcc</varname> should be used at build-time, while <varname>pkgsHostTarget.gcc</varname> should be used at run-time.
</para>
<para>
Now, for most of Nixpkgs's history, there were no <varname>pkgsFooBar</varname> attributes, and most packages have not been refactored to use it explicitly. Prior to those, there were just <varname>buildPackages</varname>, <varname>pkgs</varname>, and <varname>targetPackages</varname>. Those are now redefined as aliases to <varname>pkgsBuildHost</varname>, <varname>pkgsHostTarget</varname>, and <varname>pkgsTargetTarget</varname>. It is acceptable, even recommended, to use them for libraries to show that the host platform is irrelevant.
</para>
<para>
But before that, there was just <varname>pkgs</varname>, even though both <varname>buildInputs</varname> and <varname>nativeBuildInputs</varname> existed. [Cross barely worked, and those were implemented with some hacks on <varname>mkDerivation</varname> to override dependencies.] What this means is the vast majority of packages do not use any explicit package set to populate their dependencies, just using whatever <varname>callPackage</varname> gives them even if they do correctly sort their dependencies into the multiple lists described above. And indeed, asking that users both sort their dependencies, <emphasis>and</emphasis> take them from the right attribute set, is both too onerous and redundant, so the recommended approach (for now) is to continue just categorizing by list and not using an explicit package set.
</para>
<para>
To make this work, we "splice" together the six <varname>pkgsFooBar</varname> package sets and have <varname>callPackage</varname> actually take its arguments from that. This is currently implemented in <filename>pkgs/top-level/splice.nix</filename>. <varname>mkDerivation</varname> then, for each dependency attribute, pulls the right derivation out from the splice. This splicing can be skipped when not cross-compiling as the package sets are the same, but still is a bit slow for cross-compiling. We'd like to do something better, but haven't come up with anything yet.
</para>
</section>
<section xml:id="ssec-bootstrapping">
<title>Bootstrapping</title>
<para>
Each of the package sets described above come from a single bootstrapping stage. While <filename>pkgs/top-level/default.nix</filename>, coordinates the composition of stages at a high level, <filename>pkgs/top-level/stage.nix</filename> "ties the knot" (creates the fixed point) of each stage. The package sets are defined per-stage however, so they can be thought of as edges between stages (the nodes) in a graph. Compositions like <literal>pkgsBuildTarget.targetPackages</literal> can be thought of as paths to this graph.
</para>
<para>
While there are many package sets, and thus many edges, the stages can also be arranged in a linear chain. In other words, many of the edges are redundant as far as connectivity is concerned. This hinges on the type of bootstrapping we do. Currently for cross it is:
<orderedlist>
<listitem>
<para>
<literal>(native, native, native)</literal>
</para>
</listitem>
<listitem>
<para>
<literal>(native, native, foreign)</literal>
</para>
</listitem>
<listitem>
<para>
<literal>(native, foreign, foreign)</literal>
</para>
</listitem>
</orderedlist>
In each stage, <varname>pkgsBuildHost</varname> refers to the previous stage, <varname>pkgsBuildBuild</varname> refers to the one before that, and <varname>pkgsHostTarget</varname> refers to the current one, and <varname>pkgsTargetTarget</varname> refers to the next one. When there is no previous or next stage, they instead refer to the current stage. Note how all the invariants regarding the mapping between dependency and depending packages' build host and target platforms are preserved. <varname>pkgsBuildTarget</varname> and <varname>pkgsHostHost</varname> are more complex in that the stage fitting the requirements isn't always a fixed chain of "prevs" and "nexts" away (modulo the "saturating" self-references at the ends). We just special case each instead. All the primary edges are implemented is in <filename>pkgs/stdenv/booter.nix</filename>, and secondarily aliases in <filename>pkgs/top-level/stage.nix</filename>.
</para>
<note>
<para>
Note the native stages are bootstrapped in legacy ways that predate the current cross implementation. This is why the bootstrapping stages leading up to the final stages are ignored inthe previous paragraph.
</para>
</note>
<para>
If one looks at the 3 platform triples, one can see that they overlap such that one could put them together into a chain like:
<programlisting>
(native, native, native, foreign, foreign)
</programlisting>
If one imagines the saturating self references at the end being replaced with infinite stages, and then overlays those platform triples, one ends up with the infinite tuple:
<programlisting>
(native..., native, native, native, foreign, foreign, foreign...)
</programlisting>
On can then imagine any sequence of platforms such that there are bootstrap stages with their 3 platforms determined by "sliding a window" that is the 3 tuple through the sequence. This was the original model for bootstrapping. Without a target platform (assume a better world where all compilers are multi-target and all standard libraries are built in their own derivation), this is sufficient. Conversely if one wishes to cross compile "faster", with a "Canadian Cross" bootstraping stage where <literal>build != host != target</literal>, more bootstrapping stages are needed since no sliding window providess the pesky <varname>pkgsBuildTarget</varname> package set since it skips the Canadian cross stage's "host".
</para>
<note>
<para>
It is much better to refer to <varname>buildPackages</varname> than <varname>targetPackages</varname>, or more broadly package sets that do not mention "target". There are three reasons for this.
</para>
<para>
First, it is because bootstrapping stages do not have a unique <varname>targetPackages</varname>. For example a <literal>(x86-linux, x86-linux, arm-linux)</literal> and <literal>(x86-linux, x86-linux, x86-windows)</literal> package set both have a <literal>(x86-linux, x86-linux, x86-linux)</literal> package set. Because there is no canonical <varname>targetPackages</varname> for such a native (<literal>build == host == target</literal>) package set, we set their <varname>targetPackages</varname>
</para>
<para>
Second, it is because this is a frequent source of hard-to-follow "infinite recursions" / cycles. When only package sets that don't mention target are used, the package set forms a directed acyclic graph. This means that all cycles that exist are confined to one stage. This means they are a lot smaller, and easier to follow in the code or a backtrace. It also means they are present in native and cross builds alike, and so more likely to be caught by CI and other users.
</para>
<para>
Thirdly, it is because everything target-mentioning only exists to accommodate compilers with lousy build systems that insist on the compiler itself and standard library being built together. Of course that is bad because bigger derivations means longer rebuilds. It is also problematic because it tends to make the standard libraries less like other libraries than they could be, complicating code and build systems alike. Because of the other problems, and because of these innate disadvantages, compilers ought to be packaged another way where possible.
</para>
</note>
<note>
<para>
If one explores Nixpkgs, they will see derivations with names like <literal>gccCross</literal>. Such <literal>*Cross</literal> derivations is a holdover from before we properly distinguished between the host and target platforms—the derivation with "Cross" in the name covered the <literal>build = host != target</literal> case, while the other covered the <literal>host = target</literal>, with build platform the same or not based on whether one was using its <literal>.nativeDrv</literal> or <literal>.crossDrv</literal>. This ugliness will disappear soon.
</para>
</note>
</section>
</section>
</chapter>

Some files were not shown because too many files have changed in this diff Show More