summaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
Diffstat (limited to 'doc')
-rw-r--r--doc/contributing.texi100
-rw-r--r--doc/guix-cookbook.texi377
-rw-r--r--doc/guix.texi13
3 files changed, 456 insertions, 34 deletions
diff --git a/doc/contributing.texi b/doc/contributing.texi
index 6d3f1622f30..c801ba5950a 100644
--- a/doc/contributing.texi
+++ b/doc/contributing.texi
@@ -1635,34 +1635,78 @@ dashes and prepend the prefix @code{java-}. So the class
1635@subsection Rust Crates 1635@subsection Rust Crates
1636 1636
1637@cindex rust 1637@cindex rust
1638Rust programs standing for themselves are named as any other package, using the 1638Rust applications (binary crates) and libraries (library crates) are packaged
1639lowercase upstream name. 1639separately. We put our main efforts into applications and only package
1640 1640libraries as sources, utilizing automation with a manual focus on unbundling
1641To prevent namespace collisions we prefix all other Rust packages with the 1641vendored dependencies.
1642@code{rust-} prefix. The name should be changed to lowercase as appropriate and 1642
1643dashes should remain in place. 1643Rust applications are treated like any other package and named using the
1644 1644lowercase upstream name. When using the Cargo build system (@pxref{Build
1645In the rust ecosystem it is common for multiple incompatible versions of a 1645Systems, @code{cargo-build-system}}), Rust applications should have the
1646package to be used at any given time, so all package definitions should have a 1646@code{#:install-source?} parameter set to @code{#f}, as this parameter only
1647versioned suffix. The versioned suffix is the left-most non-zero digit (and 1647makes sense for libraries. When the package source is a Cargo workspace,
1648any leading zeros, of course). This follows the ``caret'' version scheme 1648@code{#:cargo-install-paths} must be set to enable relevant support.
1649intended by Cargo. Examples@: @code{rust-clap-2}, @code{rust-rand-0.6}. 1649
1650 1650Rust libraries are hidden from the user interface and managed in two modules:
1651Because of the difficulty in reusing rust packages as pre-compiled inputs for 1651
1652other packages the Cargo build system (@pxref{Build Systems, 1652@table @code
1653@code{cargo-build-system}}) presents the @code{#:cargo-inputs} and 1653@item (gnu packages rust-crates)
1654@code{cargo-development-inputs} keywords as build system arguments. It would be 1654Source definitions imported from Rust packages' @file{Cargo.lock} via the
1655helpful to think of these as similar to @code{propagated-inputs} and 1655@code{crate} importer (@pxref{Invoking guix import}).
1656@code{native-inputs}. Rust @code{dependencies} and @code{build-dependencies} 1656
1657should go in @code{#:cargo-inputs}, and @code{dev-dependencies} should go in 1657Imported definitions must be checked and have vendored dependencies unbundled
1658@code{#:cargo-development-inputs}. If a Rust package links to other libraries 1658before being contributed to Guix.
1659then the standard placement in @code{inputs} and the like should be used. 1659
1660 1660@item (gnu packages rust-sources)
1661Care should be taken to ensure the correct version of dependencies are used; to 1661More complex definitions that need to be full packages. This includes Rust
1662this end we try to refrain from skipping the tests or using @code{#:skip-build?} 1662libraries requiring external inputs to unbundle and Cargo workspaces.
1663when possible. Of course this is not always possible, as the package may be 1663
1664developed for a different Operating System, depend on features from the Nightly 1664These libraries should have the @code{#:skip-build?} parameter set to @code{#t}.
1665Rust compiler, or the test suite may have atrophied since it was released. 1665For Cargo workspaces, @code{#:cargo-package-crates} must be set.
1666
1667Since they are added manually, they follow the usual naming convention for Guix
1668packages (@pxref{Package Naming}), with a @code{rust-} prefix.
1669
1670In the Rust community it is common for multiple incompatible versions of a
1671package to be used at any given time, so all libraries should have a versioned
1672suffix. The versioned suffix is the left-most non-zero digit (and any leading
1673zeros, of course). This follows the ``caret'' version scheme intended by Cargo.
1674Examples@: @code{rust-clap-2}, @code{rust-rand-0.6}.
1675
1676In practice we often package development snapshots of Rust libraries and can't
1677simply identify them by version. In this case, the complete version information
1678can be turned into a version string via @code{git-version}, for example
1679@code{rust-pipewire-0.8.0.fd3d8f7} and @code{rust-pubgrub-0.3.0.b70cf70}.
1680@end table
1681
1682To avoid merge conflicts with changes from multiple branches, these two modules
1683are maintained by the Rust team (@pxref{Teams}).
1684
1685Rust libraries are not referenced directly. @code{(guix build-sytem cargo)}
1686provides a @code{cargo-inputs} procedure to lookup input lists generated by the
1687lockfile importer.
1688
1689@cindex cargo inputs
1690@findex define-cargo-inputs
1691@findex lookup-cargo-inputs
1692@deffn {Procedure} cargo-inputs name [#:module '(gnu packages rust-crates)]
1693Lookup Cargo inputs for @var{name} in @var{module}, return an empty list if
1694unavailable.
1695
1696@var{name} must be consistent with the one used in lockfile importer invocation,
1697usually matching the variable name of the package:
1698
1699@example
1700$ guix import -i @file{gnu/packages/rust-crates.scm} crate -f @file{/path/to/Cargo.lock} @var{name}
1701@end example
1702
1703@var{module} must export a public interface @code{lookup-cargo-inputs}, a
1704template is available in the @file{etc/teams/rust} directory of Guix source
1705tree.
1706@end deffn
1707
1708@xref{Packaging Rust Crates,,, guix-cookbook, GNU Guix Cookbook}, for
1709packaging workflow.
1666 1710
1667 1711
1668@node Elm Packages 1712@node Elm Packages
diff --git a/doc/guix-cookbook.texi b/doc/guix-cookbook.texi
index b0567047033..bd2add42856 100644
--- a/doc/guix-cookbook.texi
+++ b/doc/guix-cookbook.texi
@@ -106,6 +106,7 @@ Scheme tutorials
106Packaging 106Packaging
107 107
108* Packaging Tutorial:: A tutorial on how to add packages to Guix. 108* Packaging Tutorial:: A tutorial on how to add packages to Guix.
109* Packaging Workflows:: Real life examples on working with specific build systems.
109 110
110Packaging Tutorial 111Packaging Tutorial
111 112
@@ -130,6 +131,16 @@ Programmable and automated package definition
130* Automatic update:: 131* Automatic update::
131* Inheritance:: 132* Inheritance::
132 133
134Packaging Workflows
135
136* Packaging Rust Crates::
137
138Packaging Rust Crates
139
140* Common Workflow for Rust Packaging::
141* Cargo Workspaces and Development Snapshots::
142* Using Rust Libraries in Other Build Systems::
143
133System Configuration 144System Configuration
134 145
135* Auto-Login to a Specific TTY:: Automatically Login a User to a Specific TTY 146* Auto-Login to a Specific TTY:: Automatically Login a User to a Specific TTY
@@ -519,6 +530,7 @@ them.
519 530
520@menu 531@menu
521* Packaging Tutorial:: A tutorial on how to add packages to Guix. 532* Packaging Tutorial:: A tutorial on how to add packages to Guix.
533* Packaging Workflows:: Real life examples on working with specific build systems.
522@end menu 534@end menu
523 535
524@node Packaging Tutorial 536@node Packaging Tutorial
@@ -1599,6 +1611,371 @@ The @uref{https://guix.gnu.org/manual/en/html_node/Defining-Packages.html, packa
1599@uref{https://guix.gnu.org/guix-ghm-andreas-20130823.pdf, ``GNU Guix: Package without a scheme!''}, by Andreas Enge 1611@uref{https://guix.gnu.org/guix-ghm-andreas-20130823.pdf, ``GNU Guix: Package without a scheme!''}, by Andreas Enge
1600@end itemize 1612@end itemize
1601 1613
1614@node Packaging Workflows
1615@section Packaging Workflows
1616
1617The following sections provide real-life examples on working with specific build
1618systems, serving as extensions to the concise packaging guidelines
1619(@pxref{Packaging Guidelines,,, guix, GNU Guix Reference Manual}).
1620
1621@menu
1622* Packaging Rust Crates::
1623@end menu
1624
1625@node Packaging Rust Crates
1626@subsection Packaging Rust Crates
1627
1628In preparation, add the following packages to our environment:
1629
1630@example
1631$ guix shell rust rust:cargo cargo-audit cargo-license
1632@end example
1633
1634@menu
1635* Common Workflow for Rust Packaging::
1636* Cargo Workspaces and Development Snapshots::
1637* Using Rust Libraries in Other Build Systems::
1638@end menu
1639
1640@node Common Workflow for Rust Packaging
1641@subsubsection Common Workflow for Rust Packaging
1642
1643In this example, we'll package @code{cargo-audit}, which is published on the
1644@uref{https://crates.io, crates.io} Rust package repository. All its
1645dependencies are on crates.io as well.
1646
1647@enumerate
1648@item
1649Since @code{cargo-audit} is available on crates.io, we can generate a template
1650via the crates.io importer (@pxref{Invoking guix import,,, guix, GNU Guix
1651Reference Manual}):
1652
1653@example
1654$ guix import crate cargo-audit
1655@end example
1656
1657After manual editing, we'll have the following definiton:
1658
1659@lisp
1660(define-public cargo-audit
1661 (package
1662 (name "cargo-audit")
1663 (version "0.21.2")
1664 (source
1665 (origin
1666 (method url-fetch)
1667 (uri (crate-uri "cargo-audit" version))
1668 (file-name (string-append name "-" version ".tar.gz"))
1669 (sha256
1670 (base32 "1a00yqpckkw86zh2hg7ra82c5fx0ird5766dyynimbvqiwg2ps0n"))))
1671 (build-system cargo-build-system)
1672 (arguments (list #:install-source? #f))
1673 (inputs (cargo-inputs 'cargo-audit))
1674 (home-page "https://rustsec.org/")
1675 (synopsis "Audit Cargo.lock for crates with security vulnerabilities")
1676 (description
1677 "This package provides a Cargo subcommand, @@command@{cargo audit@}, to
1678audit @@file@{Cargo.lock@} for crates with security vulnerabilities.")
1679 (license (list license:asl2.0 license:expat))))
1680@end lisp
1681
1682The identifier used to invoke @code{cargo-inputs}, in this case
1683@code{'cargo-audit}, must be unique, usually matching the variable name of the
1684package.
1685
1686@item
1687Unpack package source and navigate to the unpacked directory, then run the
1688following commands:
1689
1690@example
1691$ cargo generate-lockfile
1692$ cargo audit
1693$ cargo license
1694@end example
1695
1696@command{cargo generate-lockfile} updates dependencies to compatible versions.
1697Applying it to all Rust applications helps reduce a great number of Rust
1698libraries we need to check later. Although sometimes libraries may fail to
1699follow the @uref{https://semver.org/, semantic versioning} scheme, it's still
1700acceptable.
1701
1702@command{cargo audit} checks known vulnerabilities and @command{cargo license}
1703checks licenses, for all the dependencies. We must have an acceptable output of
1704@command{cargo audit} and ensure all dependencies are licensed with our
1705supported licenses (@pxref{Defining Packages,,, guix, GNU Guix Reference
1706Manual}).
1707
1708@item
1709Import dependencies from the generated lockfile:
1710
1711@example
1712$ guix import --insert=gnu/packages/rust-crates.scm \
1713 crate --lockfile=/path/to/Cargo.lock cargo-audit
1714
1715# Or use short options, in this case the shell processes file names
1716# before passing them to Guix, allowing tilde expansion, for example.
1717$ guix import -i gnu/packages/rust-crates.scm \
1718 crate -f /path/to/Cargo.lock cargo-audit
1719@end example
1720
1721@code{cargo-audit} here must be consistent with the identifier used for
1722@code{cargo-inputs} invocation in the package definition.
1723
1724At this stage, the package @code{cargo-audit} is buildable.
1725
1726@item
1727Finally we'll unbundle the vendored dependencies. The lockfile importer
1728inserts @code{TODO:} comments for libraries with high probability of
1729bundled dependencies. @code{cargo-build-system} also performs
1730additional check for binary files in its
1731@code{check-for-pregenerated-files} phase, which usually indicates
1732bundling:
1733
1734@example
1735$ ./pre-inst-env guix build cargo-audit
1736@dots{}
1737starting phase `check-for-pregenerated-files'
1738Searching for binary files...
1739./guix-vendor/rust-async-compression-0.4.21.tar.gz/tests/artifacts/dictionary-rust
1740./guix-vendor/rust-async-compression-0.4.21.tar.gz/tests/artifacts/dictionary-rust-other
1741./guix-vendor/rust-async-compression-0.4.21.tar.gz/tests/artifacts/lib.rs.zst
1742./guix-vendor/rust-async-compression-0.4.21.tar.gz/tests/artifacts/long-window-size-lib.rs.zst
1743./guix-vendor/rust-winapi-i686-pc-windows-gnu-0.4.0.tar.gz/lib/libwinapi_aclui.a
1744./guix-vendor/rust-winapi-i686-pc-windows-gnu-0.4.0.tar.gz/lib/libwinapi_activeds.a
1745./guix-vendor/rust-winapi-i686-pc-windows-gnu-0.4.0.tar.gz/lib/libwinapi_asycfilt.a
1746./guix-vendor/rust-winapi-i686-pc-windows-gnu-0.4.0.tar.gz/lib/libwinapi_amsi.a
1747@dots{}
1748@end example
1749
1750Although Rust libraries are not publicly exported, we can still select them via
1751the Guix command-line interface via a Guile expression:
1752
1753@example
1754$ guix build --expression='(@@@@ (gnu packages rust-crates) rust-ring-0.17.14)'
1755@end example
1756
1757To unbundle most dependencies, a snippet is sufficient:
1758
1759@lisp
1760(define rust-curl-sys-0.4.80+curl-8.12.1
1761 (crate-source "curl-sys" "0.4.80+curl-8.12.1"
1762 "0d7ppx4kq77hc5nyff6jydmfabpgd0i3ppjvn8x0q833mhpdzxsm"
1763 #:snippet '(delete-file-recursively "curl")))
1764@end lisp
1765
1766@lisp
1767(define rust-bzip2-sys-0.1.13+1.0.8
1768 (crate-source "bzip2-sys" "0.1.13+1.0.8"
1769 "056c39pgjh4272bdslv445f5ry64xvb0f7nph3z7860ln8rzynr2"
1770 #:snippet
1771 '(begin
1772 (delete-file-recursively "bzip2-1.0.8")
1773 (delete-file "build.rs")
1774 (with-output-to-file "build.rs"
1775 (lambda _
1776 (format #t "fn main() @{~@@
1777 println!(\"cargo:rustc-link-lib=bz2\");~@@
1778 @}~%"))))))
1779@end lisp
1780
1781In a more complex case, where unbundling one dependency requires a build process
1782that involves other packages, we should make a full package in @code{(gnu
1783packages rust-sources)} first and reference it in the imported definition.
1784
1785For example, we have defined a @code{rust-ring-0.17} in @code{(gnu packages
1786rust-sources)}, then the imported definition in @code{(gnu packages
1787rust-crates)} should be modified to reference it.
1788
1789@lisp
1790(define rust-ring-0.17.14 rust-ring-0.17)
1791@end lisp
1792
1793When one dependency can be safely removed, modify it to @code{#f}.
1794
1795@lisp
1796(define rust-openssl-src-300.4.2+3.4.1 #f)
1797@end lisp
1798
1799To facilitate various tasks in the common workflow, several scripts are provided
1800in the @file{etc/teams/rust} directory of Guix source tree.
1801@end enumerate
1802
1803@node Cargo Workspaces and Development Snapshots
1804@subsubsection Cargo Workspaces and Development Snapshots
1805
1806In this example, we'll package @code{niri}, which depends on development
1807snapshots (also Cargo workspaces here).
1808
1809As we can't ensure compatibility of a development snapshot, before executing
1810@command{cargo generate-lockfile}, we should modify @file{Cargo.toml} to pin it
1811to a known working revision.
1812
1813To use our packaged development snapshots, it's also necessary to modify
1814@file{Cargo.toml} in a build phase, with a package-specific substitution
1815pattern.
1816
1817@lisp
1818(define-public niri
1819 (package
1820 (name "niri")
1821 (version "25.02")
1822 (source (origin
1823 (method git-fetch)
1824 (uri (git-reference
1825 (url "https://github.com/YaLTeR/niri")
1826 (commit (string-append "v" version))))
1827 (file-name (git-file-name name version))
1828 (sha256
1829 (base32
1830 "0vzskaalcz6pcml687n54adjddzgf5r07gggc4fhfsa08h1wfd4r"))))
1831 (build-system cargo-build-system)
1832 (arguments
1833 (list #:install-source? #f
1834 #:phases
1835 #~(modify-phases %standard-phases
1836 (add-after 'unpack 'use-guix-vendored-dependencies
1837 (lambda _
1838 (substitute* "Cargo.toml"
1839 (("# version =.*")
1840 "version = \"*\"")
1841 (("git.*optional")
1842 "version = \"*\", optional")
1843 (("^git = .*")
1844 "")))))))
1845 (native-inputs
1846 (list pkg-config))
1847 (inputs
1848 (cons* clang
1849 libdisplay-info
1850 libinput-minimal
1851 libseat
1852 libxkbcommon
1853 mesa
1854 pango
1855 pipewire
1856 wayland
1857 (cargo-inputs 'niri)))
1858 (home-page "https://github.com/YaLTeR/niri")
1859 (synopsis "Scrollable-tiling Wayland compositor")
1860 (description
1861 "Niri is a scrollable-tiling Wayland compositor which arranges windows in a
1862scrollable format. It is considered stable for daily use and performs most
1863functions expected of a Wayland compositor.")
1864 (license license:gpl3+)))
1865@end lisp
1866
1867@code{niri} has Cargo workspace dependencies. When packaging a Cargo
1868workspace dependency, parameter @code{#:cargo-package-crates} is
1869required.
1870
1871@lisp
1872(define-public rust-pipewire-0.8.0.fd3d8f7
1873 (let ((commit "fd3d8f7861a29c2eeaa4c393402e013578bb36d9")
1874 (revision "0"))
1875 (package
1876 (name "rust-pipewire")
1877 (version (git-version "0.8.0" revision commit))
1878 (source
1879 (origin
1880 (method git-fetch)
1881 (uri (git-reference
1882 (url "https://gitlab.freedesktop.org/pipewire/pipewire-rs.git")
1883 (commit commit)))
1884 (file-name (git-file-name name version))
1885 (sha256
1886 (base32 "1hzyhz7xg0mz8a5y9j6yil513p1m610q3j9pzf6q55vdh5mcn79v"))))
1887 (build-system cargo-build-system)
1888 (arguments
1889 (list #:skip-build? #t
1890 #:cargo-package-crates
1891 ''("libspa-sys" "libspa" "pipewire-sys" "pipewire")))
1892 (inputs (cargo-inputs 'rust-pipewire-0.8.0.fd3d8f7))
1893 (home-page "https://pipewire.org/")
1894 (synopsis "Rust bindings for PipeWire")
1895 (description "This package provides Rust bindings for PipeWire.")
1896 (license license:expat))))
1897@end lisp
1898
1899Don't forget to modify all workspace members in @code{(gnu packages
1900rust-crates)}:
1901
1902@lisp
1903(define rust-pipewire-0.8.0.fd3d8f7 rust-pipewire-0.8.0.fd3d8f7)
1904(define rust-pipewire-sys-0.8.0.fd3d8f7 rust-pipewire-0.8.0.fd3d8f7)
1905@dots{}
1906(define rust-libspa-0.8.0.fd3d8f7 rust-pipewire-0.8.0.fd3d8f7)
1907(define rust-libspa-sys-0.8.0.fd3d8f7 rust-pipewire-0.8.0.fd3d8f7)
1908@end lisp
1909
1910@node Using Rust Libraries in Other Build Systems
1911@subsubsection Using Rust Libraries in Other Build Systems
1912
1913In this example, we'll package @code{libchewing}, which combines two build
1914systems.
1915
1916When building Rust packages in other build systems, we need to add @code{rust},
1917and @code{rust:cargo} to @code{native-inputs}, import and use modules from both
1918build systems, and apply necessary build phases from @code{cargo-build-system}.
1919
1920For cross-compilation support, we'll also add @code{rust-sysroot} created with
1921@code{(make-rust-sysroot (%current-target-system))} to @code{native-inputs}, and
1922set @code{#:cargo-target} for @code{cargo-build-system}'s build phases.
1923
1924@lisp
1925(define-public libchewing
1926 (package
1927 (name "libchewing")
1928 (version "0.9.1")
1929 (source
1930 (origin
1931 (method git-fetch)
1932 (uri (git-reference
1933 (url "https://github.com/chewing/libchewing")
1934 (commit (string-append "v" version))))
1935 (file-name (git-file-name name version))
1936 (sha256
1937 (base32 "0gh64wvrk5pn0fhmpvj1j99d5g7f7697rk96zbkc8l72yjr819z5"))))
1938 (build-system cmake-build-system)
1939 (arguments
1940 (list #:imported-modules
1941 (append %cmake-build-system-modules
1942 %cargo-build-system-modules)
1943 #:modules
1944 '(((guix build cargo-build-system) #:prefix cargo:)
1945 (guix build cmake-build-system)
1946 (guix build utils))
1947 #:phases
1948 #~(modify-phases %standard-phases
1949 (add-after 'unpack 'prepare-cargo-build-system
1950 (lambda args
1951 (for-each
1952 (lambda (phase)
1953 (format #t "Running cargo phase: ~a~%" phase)
1954 (apply (assoc-ref cargo:%standard-phases phase)
1955 ;; For cross-compilation.
1956 #:cargo-target #$(cargo-triplet)
1957 args))
1958 '(unpack-rust-crates
1959 configure
1960 check-for-pregenerated-files
1961 patch-cargo-checksums)))))))
1962 (native-inputs
1963 (append
1964 (list rust `(,rust "cargo") )
1965 ;; For cross-compilation.
1966 (or (and=> (%current-target-system)
1967 (compose list make-rust-sysroot))
1968 '())))
1969 (inputs
1970 (cons* corrosion ncurses sqlite (cargo-inputs 'libchewing)))
1971 (synopsis "Chinese phonetic input method")
1972 (description "Chewing is an intelligent phonetic (Zhuyin/Bopomofo) input
1973method, one of the most popular choices for Traditional Chinese users.")
1974 (home-page "https://chewing.im/")
1975 (license license:lgpl2.1+)))
1976@end lisp
1977
1978
1602@c ********************************************************************* 1979@c *********************************************************************
1603@node System Configuration 1980@node System Configuration
1604@chapter System Configuration 1981@chapter System Configuration
diff --git a/doc/guix.texi b/doc/guix.texi
index 9147cd61ca6..e2d546be0a0 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -9573,12 +9573,13 @@ crate. Unless @code{install-source? #f} is defined it will also install a
9573source crate repository of itself and unpacked sources, to ease in future 9573source crate repository of itself and unpacked sources, to ease in future
9574hacking on Rust packages. 9574hacking on Rust packages.
9575 9575
9576This build system supports Cargo workspaces. Parameter 9576This build system supports
9577@code{#:cargo-package-crates} (default: @code{''()}) allows specifying names of 9577@url{https://doc.rust-lang.org/cargo/reference/workspaces.html, Cargo
9578library crates to package in the @code{package} phase. Specified crates are 9578workspaces}. Parameter @code{#:cargo-package-crates} (default: @code{''()})
9579packaged from left to right, in case there's dependency among them. For 9579allows specifying names of library crates to package in the @code{package}
9580example, specifying @code{''("pcre2-sys" "pcre2")} will package 9580phase. Specified crates are packaged from left to right, in case there's
9581@code{"pcre2-sys"} first and then @code{"pcre2"}. Parameter 9581dependency among them. For example, specifying @code{''("pcre2-sys" "pcre2")}
9582will package @code{"pcre2-sys"} first and then @code{"pcre2"}. Parameter
9582@code{#:cargo-install-paths} (default: @code{''()}) allows specifying paths of 9583@code{#:cargo-install-paths} (default: @code{''()}) allows specifying paths of
9583binary crates to install in the @code{install} phase, @code{''("crates/atuin")}, 9584binary crates to install in the @code{install} phase, @code{''("crates/atuin")},
9584for example. 9585for example.