Wiki
Download
Manual
Eggs
API
Tests
Bugs
show
edit
history
You can edit this page using
wiki syntax
for markup.
Article contents:
== Beaker Lab supplies for CHICKEN Scheme. [[toc:]] == Description Beaker is a collection of development tools. It is currently fairly limited, containing only a few programs, a handful of extension libraries, and Nix helpers to make common development tasks easier. If you have an idea for something that would be useful to include, don't hesitate to contact the [[#author|author]]. The project's source is available [[https://git.sr.ht/~evhan/beaker|here]]. == Dependencies * [[/eggref/5/module-declarations|module-declarations]] * [[/eggref/5/begin-syntax|begin-syntax]] * [[/eggref/5/debugger-protocol|debugger-protocol]] * [[/eggref/5/schematic|schematic]] * [[/eggref/5/srfi-1|srfi-1]] * [[/eggref/5/srfi-13|srfi-13]] * [[/eggref/5/srfi-14|srfi-14]] * [[/eggref/5/srfi-69|srfi-69]] * [[/eggref/5/vector-lib|vector-lib]] * [[/eggref/5/with-current-directory|with-current-directory]] == Programs === chicken-clean Usage: chicken-clean [-interactive | -quiet | -verbose] [filename ...] The {{chicken-clean}} program deletes egg build artifacts. A simple set of file patterns is used to determine what should be deleted. This includes compiled programs, binary objects ({{o}}, {{obj}}, {{so}}, {{dll}}), and files generated by the CHICKEN toolchain ({{build.sh}}, {{install.sh}}, {{import.scm}}, {{inline}}, {{profile}}, {{types}}). When run with the {{-interactive}} flag, a confirmation prompt will be displayed before any files are deleted. === chicken-lint Usage: chicken-lint [csc-options ...] filename ... The {{chicken-lint}} program checks a source file with a set of simple lint rules. Potential problems are written as S-expressions to standard error. Note that this program invokes {{csc}}, so any compile-time code in the program will be executed. === chicken-lock Usage: chicken-lock [egg ...] [-output file] [-command arg ...] The {{chicken-lock}} program generates a snapshot of all dependency versions for the given eggs, or for any egg files in the current directory. The output is an override file that can then be used to install those same versions later on via the "-override" or "-from-list" flags to {{chicken-install}}. For example, you can record the current version of the r7rs egg and all of its dependencies, and then restore them later, like this: $ chicken-lock r7rs > r7rs.lock ... time passes... $ chicken-install -from-list r7rs.lock If no egg names are given on the command line, this program will look for egg files in the current directory. This can be used to record the current version of all dependencies for an egg in local development: $ cat example.egg ((synopsis "A nice example library") (build-dependencies matchable) (dependencies r7rs) (components (extension example))) $ chicken-lock > example.egg.lock ... time passes ... $ chicken-install -override example.egg.lock This program works by fetching eggs into a temporary directory, so network access is required. If a {{-command}} flag is given, the remaining arguments will be called with the temporary egg cache directory name as a single argument. In this case, the cache directory will not be removed automatically flag, and. This feature can be used to print the directory name, for example, or to hash the directory for use with Nix: $ chicken-lock r7rs -command nix hash path ... some output ... sha256-ggZvueP0uJYl87AwTuTLYtRr2SmP3PeJqpMMFyDfS+U= Any extra arguments are passed through to {{chicken-install}} when fetching eggs. So, you can use "-override" to fix some subset of an egg's dependency versions when generating the snapshot, as well as other options like "-verbose" to print more information about what's happening or "-test" to include test dependencies. == Extensions === Repository Management The {{(beaker repository)}} library provides a handful of procedures to help manage egg repositories. <procedure>(chicken-install)</procedure> Returns the full pathname of the {{chicken-install}} command. <procedure>(chicken-status)</procedure> Returns the full pathname of the {{chicken-status}} command. <procedure>(egg-files #!optional (path repository-path))</procedure> Returns a list of all egg-info files in the repository path. The {{path}} argument can be used to specify an alternative repository path, which should be a thunk returning a list of pathname strings. <procedure>(repair-repository #!optional (path repository-path))</procedure> Installs any missing dependencies for the eggs in the repository path. The {{path}} argument can be used to specify an alternative repository path, which should be a thunk returning a list of pathname strings. If there are any missing dependencies, they are installed into the first repository in the path and a list of newly-installed eggs is returned. If there are no missing dependencies, nothing is done and an empty list is returned. <procedure>(create-repository destination #!optional source)</procedure> Initialises a new egg repository at the pathname {{destination}}. If the directory {{destination}} doesn't exist, it is created. The core CHICKEN libraries are then installed into the repository and a new modules database is generated If a {{source}} repository is given, its contents are also copied into the new repository. This can be used to copy an existing repository to another location. === Systems The {{(beaker system)}} library provides an API for dynamically building, loading, and reloading extension libraries. It's intended to help enable rapid development in a manner similar to [[https://common-lisp.net/project/asdf/asdf/index.html|asdf]] from Common Lisp or the [[https://wiki.call-cc.org/eggref/4/system|system]] egg from CHICKEN 4. Rather than introduce a new way to define a system's components and dependencies, this library reuses the [[http://wiki.call-cc.org/man/5/Egg%20specification%20format|egg]] specification format. In fact, you can generally think of a "system" and an "egg" as one and the same. An example {{csi}} session that loads, edits, and reloads an example system might look like the following: #;> (import (beaker system)) #;> (load-system "example.egg") building example ... output ... ; loading /tmp/temp70d6.29489.example.import.so ... ; loading /tmp/temp4871.29489.example.so ... #;> (load-system "example.egg") building example #;> ,e example.scm #;> (load-system "example.egg") building example ... output ... ; loading /tmp/temp44a2.29609.example.so ... Modules are imported automatically and import libraries are reloaded whenever a module's exports list changes. Note that removing a value from a module's export list does not remove it from the session when the extension is reloaded. <procedure>(compile-system egg-file #!key (flags (quote ())))</procedure> Compiles all out-of-date components for the given egg. This is equivalent to running {{chicken-install -no-install [flags ...]}}. <procedure>(clean-system egg-file)</procedure> Deletes all compiled programs and extension libraries for the given egg. Auxiliary files such as import libraries are preserved. <procedure>(load-system #!optional (egg-file .) #!key (skip (quote ())) (flags (quote ())))</procedure> Builds and loads the given egg. When called for the first time, all out-of-date components are recompiled, the egg's extension libraries are loaded into the calling program and its modules are immediately imported. Subsequent calls cause the components to be recompiled and reloaded as necessary. == Nix Helpers This project also includes some helper functions for the [[https://nixos.org/|Nix]] package manager that make it easy to build CHICKEN programs. === Usage The helpers can be imported directly from the Git repository archive: let beaker = import (fetchTarball https://git.sr.ht/~evhan/beaker/archive/master.tar.gz) {}; in doStuff { with beaker; ... } This library only includes three attributes, so it's also relatively harmless to pull into scope, for example: with import (fetchTarball https://git.sr.ht/~evhan/beaker/archive/e9a0d500.tar.gz) {}; eggProgram { name = "example"; src = ./.; eggCache = eggCache { eggs = ./example.egg.lock; hash = "sha256-rbTfihyt6XfHP8VhaLmA8xBAneuUj7oDJXZ/BxY1OZU="; }; } You can use a specific version of the Nix packages collection by setting the {{pkgs}} property of the library. By default, the {{<nixpkgs>}} path is used: with import (fetchTarball https://git.sr.ht/~evhan/beaker/archive/master.tar.gz) { pkgs = your.nixpkgs.collection; }; ==== Using Flakes To use this project with Nix flakes, add the archive URL as an input. The following example will pin a version of this project as an input and force it to use the same version of {{nixpkgs}} as the flake itself. The {{beaker}} library is passed to your {{outputs}} function, and you can access the helpers for a specific system via {{beaker.lib.${system}}} or the egg itself as {{beaker.packages.${system}.beaker}}: { inputs = { beaker.url = "https://git.sr.ht/~evhan/beaker/archive/0.0.20.tar.gz"; beaker.inputs.nixpkgs.follows = "nixpkgs"; }; outputs = { self, nixpkgs, beaker }: let system = "x86_64-linux"; in { packages.${system}.default = beaker.lib.${system}.eggProgram { name = "example-using-flakes"; src = ./.; buildInputs = [ beaker.packages.${system}.beaker ]; }; }; } ==== Using Niv To use this project with [[https://github.com/nmattia/niv|Niv]], add it to your project sources: niv init niv add beaker -t "https://git.sr.ht/~evhan/beaker/archive/<rev>.tar.gz" -r 0.0.20 Then create a {{default.nix}} with the following contents: let pkgs = import <nixpkgs> {}; sources = import ./nix/sources.nix; beaker = import sources.beaker { inherit pkgs; }; in beaker.eggProgram { name = "example-using-niv"; src = ./.; } === Fetching Egg Dependencies <procedure>eggCache attrSet</procedure> A fixed-output derivation that fetches a set of eggs for installation. The list of eggs to cache should be specified via {{eggs}}, which expects a path to a file in "override" format specifying a list of egg names and versions. This file can be generated via {{chicken-status -list}} (for all installed eggs) or {{chicken-lock}} (for a specific egg's dependencies). eggCache { name = "example-egg-cache"; hash = "sha256-XbwSzGUJfKgiKcrYuu9Y3gwRTYmoesM9KZlIhdII2AU="; eggs = ./eggs.lock; } Alternatively, you can specify the list of eggs directly: eggCache { name = "example-egg-cache"; hash = "sha256-pQpattmS9VmO3ZIQUFn66az8GSmB4IvYhTTCFn6SUmo="; eggs = [ { name = "srfi-18"; version = "0.1"; } { name = "srfi-69"; version = "0.4"; } ]; } You can print the hash for a set of eggs using the {{-command}} flag to the {{chicken-lock}} program, to hash the resulting egg cache: # for the egg in the current directory chicken-lock -command nix hash path # for a few specific eggs and versions chicken-lock srfi-18:0.1 srfi-69:0.4 -command nix hash path # for the given override file chicken-lock -from-list ./eggs.lock -command nix hash path ==== Combining Multiple Egg Caches To merge multiple egg caches, you can use {{symlinkJoin}}: pkgs.symlinkJoin { name = "example-egg-caches"; paths = [ (eggCache { ... }) (eggCache { ... }) ]; } The result will be a single egg cache containing all of the specified eggs. Note that if any input paths contain different versions of the same egg, the first one listed takes precedence. === Building Eggs <procedure>eggRepository attrSet</procedure> Builds any eggs in the given {{src}} directory, producing a compiled egg repository under {{<path>/lib/chicken/<version>}} and placing any resulting binaries under {{<path>/bin}}. Apart from {{eggCache}}, this derivation accepts all the same attributes as {{stdenv.mkDerivation}}. If no {{name}} is given, the string {{"eggs"}} is used. The result is suitable for use in the {{buildInputs}} of an {{eggProgram}}, in order to satisfy its egg dependencies. Any dependencies not satisfied by a compiled {{eggRepository}} must be provided as sources via {{eggCache}} so that all inputs are known at build time. # create an extension repository from source eggRepository { src = ./.; eggCache = eggCache { ... }; } If any dependencies are missing from both the inputs and cache, the build will fail with the error message {{"extension or version not found: <egg>"}}. <procedure>eggProgram attrSet</procedure> Builds any eggs in the given {{src}} directory, bundling all dependencies and placing the resulting binaries into {{<path>/bin}}. The {{name}} attribute is required. Apart from that, this derivation accepts all the same attributes as {{eggRepository}}. # build a program entirely from source eggProgram { name = "example-program"; src = ./.; eggCache = eggCache { ... }; } Unlike {{eggRepository}}, this derivation only preserves shared object files in the repository path, and it does not expose the output repository to downstream derivations. This means that all {{egg-info}}, {{inline}}, {{link}} and {{types}} files are removed, and the result is unsuitable for use in the {{builtInputs}} of another {{eggProgram}}. It should only be used to produce executables, not extension repositories intended for reuse. Combining the {{eggRepository}} and {{eggProgram}} derivations is useful to stage build operations, for example to avoid rebuilding all egg dependencies whenever the current source directory changes. let # pre-compile egg dependencies compiledEggs = eggRepository { src = eggCache { ... }; }; in # build program from source eggProgram { name = "example-program"; src = ./.; buildInputs = [ compiledEggs ]; } ==== Linking With External Libraries When linking to external libraries, it's usually enough to use {{buildInputs}}. For eggs, this can either be done when compiling the egg itself, or when building a program that uses the cached egg from source. For example, to build a program using the openssl egg, you can either build the program and its dependencies (including the OpenSSL library) from source all at once, or you can compile the openssl egg first, then link to the result. In either case, the {{openssl}} package should be provided in {{buildInputs}} when building the egg: let opensslEggDependencies = [ pkgs.openssl pkgs.pkg-config ]; opensslEggSources = eggCache { hash = "sha256-RCjCBvKOFmz92RIP1lP0svxjAC00gAmOLdeAB9PxE+8="; eggs = [ { name = "openssl"; version = "2.2.4"; } { name = "srfi-18"; version = "0.1.6"; } { name = "address-info"; version = "1.0.5"; } { name = "srfi-1"; version = "0.5.1"; } { name = "srfi-14"; version = "0.2.1"; } { name = "srfi-13"; version = "0.3.3"; } ]; }; compiledOpensslEgg = eggRepository { src = opensslEggSources; buildInputs = opensslEggDependencies; }; in { # build a program using the openssl egg sources fromSourceEgg = eggProgram { name = "example-from-source"; src = ./.; eggCache = opensslEggSources; buildInputs = opensslEggDependencies; }; # build a program linking to the compiled openssl egg fromCompiledEgg = eggProgram { name = "example-from-compiled"; src = ./.; buildInputs = [ compiledOpensslEgg ]; }; } === Development Shell When using {{eggProgram}}, the {{nix develop}} command will start a development shell that causes CHICKEN to use an isolated build environment. In this shell, environment variables are set so that CHICKEN will install all files under a temporary build root, and the {{chicken-install}} program will attempt to fetch dependencies from the given {{eggCache}} before any network locations (which will fail during sandboxed builds). === Examples These eggs provide examples of using these Nix functions: * [[https://git.sr.ht/~evhan/dust/tree/master/item/default.nix|dust]] * [[https://git.sr.ht/~evhan/chicken-sourcehut/tree/master/item/default.nix|sourcehut]] * [[https://hg.sr.ht/~evhan/sq/browse/default.nix?rev=tip|sq]] In each of these projects, the lock file that's used to populate the {{eggCache}} has been created by running {{chicken-lock > ${name}.egg.lock}}, and then checking that file in to source control. == Links * Sources: [[https://git.sr.ht/~evhan/beaker]] * Issues: [[https://todo.sr.ht/~evhan/beaker]] * Documentation: [[https://api.call-cc.org/5/doc/beaker]] == Author [[/users/evan-hanson|Evan Hanson]] == License Copyright (c) 2015-2022, Evan Hanson <evhan@foldling.org> All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. [[tags: egg]]
Description of your changes:
I would like to authenticate
Authentication
Username:
Password:
Spam control
What do you get when you add 11 to 11?