mirror of
https://github.com/NixOS/mobile-nixos.git
synced 2024-09-11 12:05:26 +03:00
Merge pull request #310 from samueldr-wip/fix/more-hermetic-release.nix
More hermetic release.nix and examples
This commit is contained in:
commit
0d9c6ce207
118
default.nix
118
default.nix
@ -1,113 +1,41 @@
|
||||
let
|
||||
# Selection of the device can be made either through the environment or through
|
||||
# using `--argstr device [...]`.
|
||||
deviceFromEnv = builtins.getEnv "MOBILE_NIXOS_DEVICE";
|
||||
{ device ? null, configuration ? null, pkgs ? null }@args:
|
||||
|
||||
let
|
||||
# Selection of the configuration can by made either through NIX_PATH,
|
||||
# through local.nix or as a parameter.
|
||||
default_configuration =
|
||||
defaultConfiguration =
|
||||
let
|
||||
configPathFromNixPath = (builtins.tryEval <mobile-nixos-configuration>).value;
|
||||
in
|
||||
if configPathFromNixPath != false then [ configPathFromNixPath ]
|
||||
else if (builtins.pathExists ./local.nix) then builtins.trace "WARNING: evaluation includes ./local.nix" [ (import ./local.nix) ]
|
||||
else []
|
||||
;
|
||||
|
||||
# "a" nixpkgs we're using for its lib.
|
||||
pkgs' = import <nixpkgs> {};
|
||||
inherit (pkgs'.lib) optional strings;
|
||||
inherit (strings) concatStringsSep stringAsChars;
|
||||
in
|
||||
{
|
||||
pkgs ? import <nixpkgs> {}
|
||||
# The identifier of the device this should be built for.
|
||||
# (This gets massaged later on)
|
||||
# This allows using `default.nix` as a pass-through function.
|
||||
# See usage in examples folder.
|
||||
, device ? null
|
||||
, configuration ? default_configuration
|
||||
# Internally used to tack on configuration by release.nix
|
||||
, additionalConfiguration ? {}
|
||||
}:
|
||||
let
|
||||
# Either use:
|
||||
# The given `device`.
|
||||
# The environment variable.
|
||||
final_device =
|
||||
if device != null then device
|
||||
else if deviceFromEnv == "" then
|
||||
throw "Please pass a device name or set the MOBILE_NIXOS_DEVICE environment variable."
|
||||
else deviceFromEnv
|
||||
;
|
||||
|
||||
inherit (import ./lib/release-tools.nix { inherit pkgs; }) evalWith;
|
||||
|
||||
# The "default" eval.
|
||||
eval = evalWith {
|
||||
device = final_device;
|
||||
modules = configuration;
|
||||
inherit additionalConfiguration;
|
||||
};
|
||||
|
||||
# Makes a mostly useless header.
|
||||
# This is mainly useful for batch evals.
|
||||
header = str:
|
||||
let
|
||||
str' = "* ${str} *";
|
||||
line = stringAsChars (x: "*") str';
|
||||
in
|
||||
builtins.trace (concatStringsSep "\ntrace: " [line str' line])
|
||||
if configPathFromNixPath != false then
|
||||
[ configPathFromNixPath ]
|
||||
else if configuration != null then
|
||||
[ configuration ]
|
||||
else if (builtins.pathExists ./local.nix) then
|
||||
builtins.trace ''
|
||||
${"\n"}
|
||||
********************************************
|
||||
* WARNING: evaluation includes ./local.nix *
|
||||
********************************************
|
||||
'' [ (import ./local.nix) ]
|
||||
else
|
||||
[]
|
||||
;
|
||||
in
|
||||
(
|
||||
# Don't break if `device` is not set.
|
||||
if device == null then (id: id) else
|
||||
if device ? special
|
||||
then header "Evaluating: ${device.name}"
|
||||
else if (builtins.tryEval (builtins.isPath device && builtins.pathExists device)).value
|
||||
then header "Evaluating device from path: ${toString device}"
|
||||
else header "Evaluating device: ${device}"
|
||||
)
|
||||
{
|
||||
# The build artifacts from the modules system.
|
||||
inherit (eval.config.system) build;
|
||||
|
||||
# The evaluated config
|
||||
inherit (eval) config;
|
||||
|
||||
# The final pkgs set, usable as -A pkgs.[...] on the CLI.
|
||||
inherit (eval) pkgs;
|
||||
|
||||
# The whole (default) eval
|
||||
inherit eval;
|
||||
|
||||
# Evaluating this whole set is counter-productive.
|
||||
# It'll put a *bunch* of build products from the misc. inherits we added.
|
||||
|
||||
# (We're also using `device` to force the other throw to happen first.)
|
||||
# TODO : We may want to produce an internal list of available outputs, so that
|
||||
# each platform can document what it makes available. This would allow
|
||||
# the message to be more user-friendly by displaying a choice.
|
||||
__please-fail = throw ''
|
||||
Cannot directly build for ${final_device}...
|
||||
|
||||
Building this whole set is counter-productive, and not likely to be what
|
||||
is desired.
|
||||
|
||||
import ./lib/eval-with-configuration.nix (args // {
|
||||
configuration = defaultConfiguration;
|
||||
additionalHelpInstructions = ''
|
||||
You can build the `-A build.default` attribute to build an empty and
|
||||
un-configured image. That image can be configured using `local.nix`.
|
||||
**Note that an unconfigured image may appear to hang at boot.**
|
||||
|
||||
** Note that an unconfigured image may appear to hang at boot. **
|
||||
|
||||
An alternative is to use one of the `examples` system. They differ in their
|
||||
configuration. An example that should be building, and working using
|
||||
cross-compilation is the `examples/hello` system. Read its README for more
|
||||
information.
|
||||
|
||||
$ nix-build examples/hello --argstr device ${final_device} -A build.default
|
||||
|
||||
*************************************************************************
|
||||
* Please also read your device's documentation for further usage notes. *
|
||||
*************************************************************************
|
||||
$ nix-build examples/hello --argstr device ${device} -A build.default
|
||||
'';
|
||||
}
|
||||
})
|
||||
|
@ -15,7 +15,7 @@ let
|
||||
devicesDir = ../../../devices;
|
||||
devicesInfo = symlinkJoin {
|
||||
name = "devices-metadata";
|
||||
paths = (map (device: (evalFor device).build.device-metadata) all-devices);
|
||||
paths = (map (device: (evalFor device).config.system.build.device-metadata) all-devices);
|
||||
};
|
||||
in
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
> **WARNING**: This is still highly experimental. This is not usable as a daily
|
||||
> driver.
|
||||
> **WARNING**: This is not usable as a daily driver.
|
||||
|
||||
This system is meant as *something* that is usable (barely) on mobile devices,
|
||||
while waiting for a more proper phone environment to be packaged.
|
||||
|
||||
## Building
|
||||
|
||||
@ -8,29 +10,12 @@ armv7, aarch64 on aarch64).
|
||||
|
||||
(Though the tooling will try to build it through cross-compilation!)
|
||||
|
||||
> Note that this has been verified to work on `asus-z00t` on September 24th 2019,
|
||||
> using nixpkgs commit `d484f2b7fc0834a068e8ace851faa449a03963f5`.
|
||||
|
||||
It should be possible to build both boot images via cross-compilation.
|
||||
|
||||
## Burning
|
||||
|
||||
To burn the image, build the android-burn-tool, then fastboot it.
|
||||
This will differ depending on the device.
|
||||
|
||||
```
|
||||
nix-build examples/demo/ --argstr device asus-flo -A android-burn-tool
|
||||
fastboot boot result
|
||||
```
|
||||
|
||||
Once booting, it will show a yellow screen, then either a red or a green screen.
|
||||
The green screen means that it has found the expected partition to flash. A red
|
||||
screen means that the user will need to check what is up.
|
||||
|
||||
The command will look like:
|
||||
|
||||
```
|
||||
dd if=system.img bs=2M status=progress | bin/ssh-initrd dd of=/dev/[...] bs=2M
|
||||
```
|
||||
A common issue with android-based devices is the `system` partition being too
|
||||
small. To work around this issue, flash to `userdata`.
|
||||
|
||||
## Booting
|
||||
|
||||
@ -41,4 +26,4 @@ The `boot.img` boot image is expecting to find the system partition using its
|
||||
label.
|
||||
|
||||
It should also be possible to do this entirely statelessly by burning to an SD
|
||||
card, and fastboot booting the device.
|
||||
card, and using `fastboot boot`.
|
||||
|
@ -1,46 +0,0 @@
|
||||
# This is intended to be used to produce a bootable `boot.img` with adbd, and
|
||||
# dropbear enabled. You would, in turn, use it to "flash" a dumb system.img file
|
||||
# to a partition, like userdata.
|
||||
#
|
||||
# *CAUTION* : there is no protection against flashing over the wrong partition.
|
||||
# Read about the usual pitfalls in the Android section of the documentation.
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
device_info = config.mobile.device.info;
|
||||
in
|
||||
{
|
||||
# Ensures we don't quit stage-1
|
||||
mobile.boot.stage-1.shell.enable = true;
|
||||
# Only enable `adb` if we know how to.
|
||||
# FIXME: relies on implementation details. Poor separation of concerns.
|
||||
mobile.adbd.enable = (config.mobile.system.type == "android") &&
|
||||
(config.mobile.usb.mode != "gadgetfs" || config.mobile.usb.gadgetfs.functions ? ffs)
|
||||
;
|
||||
|
||||
# Enables networking and ssh in stage-1 !
|
||||
mobile.boot.stage-1.networking.enable = true;
|
||||
mobile.boot.stage-1.ssh.enable = true;
|
||||
mobile.boot.stage-1.fbterm.enable = true;
|
||||
mobile.boot.stage-1.tasks = [
|
||||
(pkgs.writeText "adjust-brightness-task.rb" ''
|
||||
class Tasks::AdjustBrightness < SingletonTask
|
||||
def initialize()
|
||||
add_dependency(:Target, :Environment)
|
||||
add_dependency(:Target, :Graphics)
|
||||
end
|
||||
|
||||
def run()
|
||||
["lcd-backlight", "wled"].each do |file|
|
||||
# This can fail to write, ignore...
|
||||
begin
|
||||
max = File.read("/sys/class/leds/#{file}/max_brightness").to_i
|
||||
System.write("/sys/class/leds/#{file}/brightness", (max * 0.1).to_i)
|
||||
rescue
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
'')
|
||||
];
|
||||
}
|
@ -1,23 +1,11 @@
|
||||
{ device ? null }:
|
||||
let
|
||||
system-build = import ../../. {
|
||||
inherit device;
|
||||
configuration = [ { imports = [ ./configuration.nix ]; } ];
|
||||
};
|
||||
burn-tool-build = import ../../. {
|
||||
inherit device;
|
||||
configuration = [ { imports = [ ./android-burn-tool.nix ]; } ];
|
||||
};
|
||||
in
|
||||
{
|
||||
inherit (system-build) build;
|
||||
inherit (system-build.build)
|
||||
# Android devices
|
||||
android-bootimg android-device
|
||||
# QEMU VM
|
||||
vm
|
||||
# Depthcharge
|
||||
disk-image
|
||||
;
|
||||
android-burn-tool = burn-tool-build.build.android-bootimg;
|
||||
}
|
||||
{ device ? null, pkgs ? null }@args:
|
||||
|
||||
import ../../lib/eval-with-configuration.nix (args // {
|
||||
configuration = [ (import ./configuration.nix) ];
|
||||
additionalHelpInstructions = ''
|
||||
You can build the `-A build.default` attribute to build the default output
|
||||
for your device.
|
||||
|
||||
$ nix-build examples/demo --argstr device ${device} -A build.default
|
||||
'';
|
||||
})
|
||||
|
@ -1,22 +1,11 @@
|
||||
{ device ? null }:
|
||||
|
||||
let
|
||||
system-build = import ../../. {
|
||||
inherit device;
|
||||
configuration = [ { imports = [ ./configuration.nix ]; } ];
|
||||
};
|
||||
in
|
||||
system-build // {
|
||||
___readme-default = throw ''
|
||||
Cannot directly build for ${device}...
|
||||
{ device ? null, pkgs ? null }@args:
|
||||
|
||||
import ../../lib/eval-with-configuration.nix (args // {
|
||||
configuration = [ (import ./configuration.nix) ];
|
||||
additionalHelpInstructions = ''
|
||||
You can build the `-A build.default` attribute to build the default output
|
||||
for your device.
|
||||
|
||||
$ nix-build examples/hello --argstr device ${device} -A build.default
|
||||
|
||||
*************************************************************************
|
||||
* Please also read your device's documentation for further usage notes. *
|
||||
*************************************************************************
|
||||
'';
|
||||
}
|
||||
})
|
||||
|
@ -1,11 +1,20 @@
|
||||
{ device }:
|
||||
{ device ? null, pkgs ? null }@args:
|
||||
|
||||
let
|
||||
system-build = import ../../. {
|
||||
inherit device;
|
||||
configuration = [ (import ./configuration.nix) ];
|
||||
};
|
||||
in
|
||||
{
|
||||
inherit (system-build) build;
|
||||
}
|
||||
import ../../lib/eval-with-configuration.nix (args // {
|
||||
configuration = [ (import ./configuration.nix) ];
|
||||
additionalHelpInstructions = ''
|
||||
The build output to choose depends on the target.
|
||||
|
||||
Pinephone, other u-boot, and depthcharge devices:
|
||||
|
||||
$ nix-build examples/target-disk-mode --argstr device ${device} -A build.default
|
||||
|
||||
Android-based devices:
|
||||
|
||||
$ nix-build examples/target-disk-mode --argstr device ${device} -A build.android-bootimg
|
||||
|
||||
App "simulator":
|
||||
|
||||
$ nix-build examples/target-disk-mode --argstr device uefi-x86_64 -A build.app-simulator
|
||||
'';
|
||||
})
|
||||
|
@ -1,11 +1,12 @@
|
||||
{ device ? "uefi-x86_64" }:
|
||||
{ pkgs ? null }@args:
|
||||
|
||||
let
|
||||
system-build = import ../../../. {
|
||||
inherit device;
|
||||
system-build = import ../../../lib/eval-with-configuration.nix (args // {
|
||||
device = "uefi-x86_64";
|
||||
configuration = [ { imports = [
|
||||
../../hello/configuration.nix
|
||||
./configuration.nix
|
||||
]; } ];
|
||||
};
|
||||
});
|
||||
in
|
||||
system-build.build.vm
|
||||
|
@ -1,11 +1,12 @@
|
||||
{ pkgs ? null }@args:
|
||||
|
||||
let
|
||||
device = "uefi-x86_64";
|
||||
system-build = import ../../../. {
|
||||
inherit device;
|
||||
system-build = import ../../../lib/eval-with-configuration.nix (args // {
|
||||
device = "uefi-x86_64";
|
||||
configuration = [ { imports = [
|
||||
../../hello/configuration.nix
|
||||
./configuration.nix
|
||||
]; } ];
|
||||
};
|
||||
});
|
||||
in
|
||||
system-build.build.vm
|
||||
|
@ -4,7 +4,7 @@ let
|
||||
# Original `evalConfig`
|
||||
evalConfig = import "${toString pkgs.path}/nixos/lib/eval-config.nix";
|
||||
in
|
||||
{
|
||||
rec {
|
||||
# This should *never* rely on lib or pkgs.
|
||||
all-devices =
|
||||
builtins.filter
|
||||
@ -36,7 +36,7 @@ in
|
||||
;
|
||||
};
|
||||
|
||||
# These can rely freely on lib, avoir depending on pkgs.
|
||||
# These can rely freely on lib, avoid depending on pkgs.
|
||||
withPkgs = pkgs:
|
||||
let
|
||||
inherit (pkgs) lib;
|
||||
@ -67,10 +67,13 @@ in
|
||||
armv7l-linux = lib.systems.examples.armv7l-hf-multiplatform;
|
||||
};
|
||||
|
||||
# Given a device compatible with `default.nix`, eval.
|
||||
# Eval with a configuration, for the given device.
|
||||
evalWithConfiguration = configuration: device: evalWith {
|
||||
modules = [ configuration ];
|
||||
inherit device;
|
||||
};
|
||||
|
||||
# The simplest eval for a device, with an empty configuration.
|
||||
evalFor = evalWithConfiguration {};
|
||||
evalWithConfiguration = additionalConfiguration: device:
|
||||
import ../. { inherit device additionalConfiguration; }
|
||||
;
|
||||
};
|
||||
}
|
||||
|
@ -105,7 +105,7 @@ let
|
||||
lib.genAttrs systems (system:
|
||||
(evalWithConfiguration {
|
||||
nixpkgs.localSystem = knownSystems.${system};
|
||||
} device).build.default
|
||||
} device).config.system.build.default
|
||||
)
|
||||
);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user