mirror of
https://git.rwth-aachen.de/acs/public/villas/node/
synced 2025-03-09 00:00:00 +01:00
packaging-nix: improve packaging + cross-compilation
- Adds and documents some simple cross-compiling support. - More documentation in the `flake.nix`. - Add nixpkgs overlay (though undocumented). Signed-off-by: Philipp Jungkamp <Philipp.Jungkamp@opal-rt.com>
This commit is contained in:
parent
c5606d7ac9
commit
03ad3a77aa
4 changed files with 214 additions and 82 deletions
|
@ -56,10 +56,23 @@ You can also install `villas` into your local profile and have it available in
|
|||
nix profile install 'github:VILLASframework/node?dir=packaging/nix#villas'
|
||||
```
|
||||
|
||||
If you don't want to add it directly into the global path you could add it into
|
||||
the flake registry as well.
|
||||
|
||||
```shell
|
||||
nix registy add 'github:VILLASframework/node?dir=packaging/nix#villas'
|
||||
```
|
||||
|
||||
This allows you to substitue all references to
|
||||
`github:VILLASframework/node?dir=packaging/nix#villas` with a simple `villas`.
|
||||
I'll be using the `villas` registry entry in the following sections.
|
||||
|
||||
## Development
|
||||
|
||||
You can easily setup a development shell environment for `villas` by using the
|
||||
`devShells` provided in the [`flake.nix`] using `nix develop`.
|
||||
Try for example these commands in the repository root to create a new shell with
|
||||
all required dependecies to build various configurations of `villas`.
|
||||
|
||||
```shell
|
||||
# create a shell with all required build dependecies but without most optional ones
|
||||
|
@ -87,6 +100,7 @@ images without worrying about missing dependencies or Copying things inbetween
|
|||
nothing else can be done using only a few lines of Nix.
|
||||
|
||||
Here we build a docker image containing the `#villas` flake output:
|
||||
|
||||
```shell
|
||||
# `docker load` reads OCI images from stdin
|
||||
# `nix build --impure --expr` builds a derivation from an impure Nix expression
|
||||
|
@ -94,8 +108,7 @@ Here we build a docker image containing the `#villas` flake output:
|
|||
# `--print-out-paths` prints the built image's path to stdout
|
||||
docker load < $(nix build --no-link --print-out-paths --impure --expr '
|
||||
let
|
||||
ref = "github:VILLASframework/node?dir=packaging/nix";
|
||||
villas = (builtins.getFlake ref).packages.x86_64-linux.villas;
|
||||
villas = (builtins.getFlake "villas").packages.x86_64-linux.villas;
|
||||
pkgs = (builtins.getFlake "nixpkgs").legacyPackages.x86_64-linux;
|
||||
in
|
||||
pkgs.dockerTools.buildImage {
|
||||
|
@ -110,6 +123,40 @@ docker load < $(nix build --no-link --print-out-paths --impure --expr '
|
|||
|
||||
See https://nixos.org/manual/nixpkgs/stable/#sec-pkgs-dockerTools
|
||||
|
||||
## Simple cross-compilation to aarch64
|
||||
|
||||
The flake currently supports `x86_64-linux` and `aarch64-linux` systems. But
|
||||
especially on some weaker `aarch64` target machines, compiling `villas` from
|
||||
source is rather cumbersome. This flake has a non-standard `crossPackages`
|
||||
flake output. This is currently only useful for cross-compiling from `x86_64`
|
||||
to `aarch64`.
|
||||
|
||||
```shell
|
||||
nix build villas#crossPackages.x86_64-linux.aarch64-multiplatform.villas
|
||||
```
|
||||
|
||||
If your target has a nix installation you can directly build and copy the
|
||||
cross-compiled package using `nix copy`.
|
||||
|
||||
```shell
|
||||
# build and copy in one
|
||||
nix copy villas#crossPackages.x86_64-linux.aarch64-multiplatform.villas --to ssh-ng://target-system
|
||||
```
|
||||
|
||||
```shell
|
||||
# build the cross-compiled package
|
||||
nix build villas#crossPackages.x86_64-linux.aarch64-multiplatform.villas
|
||||
|
||||
# copy it over
|
||||
nix copy $(readlink result) --to ssh-ng://target
|
||||
|
||||
# add the cross-compiled package to the target's PATH
|
||||
ssh target nix profile add $(readlink result)
|
||||
```
|
||||
|
||||
Further parameters for port or user of the ssh connection can only be specified
|
||||
in the ssh configuration files.
|
||||
|
||||
## Customization
|
||||
|
||||
The [`villas.nix`] file contains the Nix "derivation" used to
|
||||
|
@ -134,11 +181,10 @@ See https://nixos.org/manual/nixpkgs/stable/#chap-overrides
|
|||
# `pkgs` is the set of `x86_64-linux` packages provided by the flake
|
||||
nix build --impure --expr '
|
||||
let
|
||||
ref = "github:VILLASframework/node?dir=packaging/nix";
|
||||
pkgs = (builtins.getFlake ref).packages.x86_64-linux;
|
||||
pkgs = (builtins.getFlake "villas").packages.x86_64-linux;
|
||||
in
|
||||
pkgs.villas-minimal.override {
|
||||
withConfig = true;
|
||||
withExtraConfig = true;
|
||||
withNodeIec60870 = true;
|
||||
}
|
||||
'
|
||||
|
@ -180,7 +226,8 @@ Here is a basic flake to build upon:
|
|||
packages.x86_64-linux = rec {
|
||||
default = villas-custom;
|
||||
villas-custom = villas-pkgs.villas-minimal.override {
|
||||
withConfig = true;
|
||||
version = "custom";
|
||||
withExtraConfig = true;
|
||||
withNodeIec60870 = true;
|
||||
};
|
||||
};
|
||||
|
@ -228,7 +275,8 @@ typical Nix usage. A more interesting use of Nix would be a custom Nix shell
|
|||
environment containing your `villas-custom` and other tools of your choice.
|
||||
|
||||
Here is a more complete `flake.nix` containing `devShells` available to
|
||||
`nix develop` and an OCI image:
|
||||
`nix develop` and an OCI image.
|
||||
|
||||
```nix
|
||||
# flake.nix
|
||||
{
|
||||
|
|
19
packaging/nix/flake.lock
generated
19
packaging/nix/flake.lock
generated
|
@ -16,6 +16,24 @@
|
|||
"type": "github"
|
||||
}
|
||||
},
|
||||
"fpga": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1679417867,
|
||||
"narHash": "sha256-HHIsOnuQOq0Ytd22VMSHpTbecHpcheF1xLkslqxXOsk=",
|
||||
"ref": "refs/heads/master",
|
||||
"rev": "29f81016b2317667a2b21fbcf74ea66986a84c03",
|
||||
"revCount": 530,
|
||||
"submodules": true,
|
||||
"type": "git",
|
||||
"url": "https://github.com/VILLASframework/fpga.git"
|
||||
},
|
||||
"original": {
|
||||
"submodules": true,
|
||||
"type": "git",
|
||||
"url": "https://github.com/VILLASframework/fpga.git"
|
||||
}
|
||||
},
|
||||
"lib60870": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
|
@ -68,6 +86,7 @@
|
|||
"root": {
|
||||
"inputs": {
|
||||
"common": "common",
|
||||
"fpga": "fpga",
|
||||
"lib60870": "lib60870",
|
||||
"libiec61850": "libiec61850",
|
||||
"nixpkgs": "nixpkgs"
|
||||
|
|
|
@ -5,7 +5,12 @@
|
|||
nixpkgs.url = "github:NixOS/nixpkgs";
|
||||
|
||||
common = {
|
||||
url = "github:VILLASframework/common?submodules=1";
|
||||
url = "github:VILLASframework/common";
|
||||
flake = false;
|
||||
};
|
||||
|
||||
fpga = {
|
||||
url = "git+https://github.com/VILLASframework/fpga.git?submodules=1";
|
||||
flake = false;
|
||||
};
|
||||
|
||||
|
@ -26,46 +31,80 @@
|
|||
...
|
||||
} @ inputs: let
|
||||
inherit (nixpkgs) lib;
|
||||
|
||||
# supported systems for native compilation
|
||||
supportedSystems = ["x86_64-linux" "aarch64-linux"];
|
||||
|
||||
# supported systems to cross compile to
|
||||
supportedCrossSystems = ["aarch64-multiplatform"];
|
||||
|
||||
# generate attributes corresponding to all the supported systems
|
||||
forSupportedSystems = lib.genAttrs supportedSystems;
|
||||
legacyPackages = forSupportedSystems (
|
||||
system:
|
||||
import nixpkgs {
|
||||
inherit system;
|
||||
overlays = [(final: prev: self.packages.${system})];
|
||||
}
|
||||
);
|
||||
|
||||
# generate attributes corresponding to all supported combinations of system and crossSystem
|
||||
forSupportedCrossSystems = f: forSupportedSystems (system: lib.genAttrs supportedCrossSystems (f system));
|
||||
|
||||
# this overlay can be applied to nixpkgs (see `pkgsFor` below for an example)
|
||||
overlay = final: prev: packagesWith final;
|
||||
|
||||
# initialize nixpkgs for the specified `system`
|
||||
pkgsFor = system:
|
||||
import nixpkgs {
|
||||
inherit system;
|
||||
overlays = [overlay];
|
||||
};
|
||||
|
||||
# initialize nixpkgs for cross-compiling from `system` to `crossSystem`
|
||||
crossPkgsFor = system: crossSystem: (pkgsFor system).pkgsCross.${crossSystem};
|
||||
|
||||
# build villas and its dependencies for the specified `pkgs`
|
||||
packagesWith = pkgs: rec {
|
||||
default = villas;
|
||||
|
||||
villas-minimal = pkgs.callPackage ./villas.nix {
|
||||
src = ../..;
|
||||
version = "minimal";
|
||||
inherit (inputs) fpga common;
|
||||
};
|
||||
|
||||
villas = villas-minimal.override {
|
||||
version = "full";
|
||||
withAllExtras = true;
|
||||
withAllFormats = true;
|
||||
withAllHooks = true;
|
||||
withAllNodes = true;
|
||||
};
|
||||
|
||||
lib60870 = pkgs.callPackage ./lib60870.nix {
|
||||
src = inputs.lib60870;
|
||||
};
|
||||
|
||||
libiec61850 = pkgs.callPackage ./libiec61850.nix {
|
||||
src = inputs.libiec61850;
|
||||
};
|
||||
};
|
||||
in {
|
||||
formatter = forSupportedSystems (system: legacyPackages.${system}.alejandra);
|
||||
# standard flake attribute for normal packages (not cross-compiled)
|
||||
packages = forSupportedSystems (
|
||||
system: let
|
||||
pkgs = legacyPackages.${system};
|
||||
in rec {
|
||||
default = villas;
|
||||
|
||||
villas-minimal = pkgs.callPackage ./villas.nix {
|
||||
src = ../..;
|
||||
common = inputs.common;
|
||||
};
|
||||
|
||||
villas = villas-minimal.override {
|
||||
withConfig = true;
|
||||
withProtobuf = true;
|
||||
withAllNodes = true;
|
||||
};
|
||||
|
||||
lib60870 = pkgs.callPackage ./lib60870.nix {
|
||||
src = inputs.lib60870;
|
||||
};
|
||||
|
||||
libiec61850 = pkgs.callPackage ./libiec61850.nix {
|
||||
src = inputs.libiec61850;
|
||||
};
|
||||
}
|
||||
system:
|
||||
packagesWith (pkgsFor system)
|
||||
);
|
||||
|
||||
# non-standard attribute for cross-compilated packages
|
||||
crossPackages = forSupportedCrossSystems (
|
||||
system: crossSystem:
|
||||
packagesWith (crossPkgsFor system crossSystem)
|
||||
);
|
||||
|
||||
# standard flake attribute allowing you to add the villas packages to your nixpkgs
|
||||
overlays = {
|
||||
default = overlay;
|
||||
};
|
||||
|
||||
# standard flake attribute for defining developer environments
|
||||
devShells = forSupportedSystems (
|
||||
system: let
|
||||
pkgs = legacyPackages.${system};
|
||||
pkgs = pkgsFor system;
|
||||
shellHook = ''
|
||||
[ -z "$PS1" ] || exec $SHELL
|
||||
'';
|
||||
|
@ -85,9 +124,11 @@
|
|||
};
|
||||
}
|
||||
);
|
||||
|
||||
# standard flake attribute to add additional checks to `nix flake check`
|
||||
checks = forSupportedSystems (
|
||||
system: let
|
||||
pkgs = legacyPackages.${system};
|
||||
pkgs = pkgsFor system;
|
||||
in {
|
||||
fmt = pkgs.runCommand "check-fmt" {} ''
|
||||
cd ${self}
|
||||
|
@ -95,5 +136,8 @@
|
|||
'';
|
||||
}
|
||||
);
|
||||
|
||||
# standard flake attribute specifying the formatter invoked on `nix fmt`
|
||||
formatter = forSupportedSystems (system: (pkgsFor system).alejandra);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,72 +1,87 @@
|
|||
{
|
||||
# build dependencies
|
||||
cmake,
|
||||
common,
|
||||
lib,
|
||||
makeWrapper,
|
||||
pkg-config,
|
||||
stdenv,
|
||||
# general configuration
|
||||
src,
|
||||
# configuration
|
||||
withConfig ? false,
|
||||
withProtobuf ? false,
|
||||
version,
|
||||
withAllExtras ? false,
|
||||
withAllFormats ? false,
|
||||
withAllHooks ? false,
|
||||
withAllNodes ? false,
|
||||
withExtraConfig ? withAllExtras,
|
||||
withExtraGraphviz ? false, # unknown type boolean in villas-graph
|
||||
withFormatProtobuf ? withAllFormats,
|
||||
withHookLua ? false, # deprecated functions
|
||||
withNodeAmqp ? false, # deprecated functions
|
||||
withNodeComedi ? withAllNodes,
|
||||
withNodeFpga ? false, # spdlog formatting error
|
||||
withNodeIec60870 ? withAllNodes,
|
||||
withNodeIec61850 ? withAllNodes,
|
||||
withNodeInfiniband ? withAllNodes,
|
||||
withNodeKafka ? withAllNodes,
|
||||
withNodeMqtt ? withAllNodes,
|
||||
withNodeRedis ? withAllNodes,
|
||||
withNodeNanomsg ? withAllNodes,
|
||||
withNodeRedis ? false, # spdlog formatting error
|
||||
withNodeRtp ? withAllNodes,
|
||||
withNodeSocket ? withAllNodes,
|
||||
withNodeTemper ? withAllNodes,
|
||||
withNodeUldaq ? withAllNodes,
|
||||
withNodeZeromq ? withAllNodes,
|
||||
withNodeNanomsg ? withAllNodes,
|
||||
withNodeRtp ? withAllNodes,
|
||||
withNodeTemper ? withAllNodes,
|
||||
withNodeSocket ? withAllNodes,
|
||||
# dependencies
|
||||
comedilib,
|
||||
# minimal dependencies
|
||||
cmake,
|
||||
common,
|
||||
coreutils,
|
||||
fpga,
|
||||
graphviz,
|
||||
lib,
|
||||
makeWrapper,
|
||||
pkg-config,
|
||||
stdenv,
|
||||
# optional dependencies
|
||||
comedilib,
|
||||
curl,
|
||||
czmq,
|
||||
gnugrep,
|
||||
graphviz,
|
||||
jansson,
|
||||
lib60870,
|
||||
libconfig,
|
||||
libiec61850,
|
||||
libre,
|
||||
libnl,
|
||||
libre,
|
||||
libsodium,
|
||||
libuldaq,
|
||||
libusb,
|
||||
libuuid,
|
||||
libwebsockets,
|
||||
lua,
|
||||
mosquitto,
|
||||
nanomsg,
|
||||
openssl,
|
||||
protobuf,
|
||||
pkgsBuildBuild,
|
||||
protobufc,
|
||||
protobufcBuildBuild ? pkgsBuildBuild.protobufc,
|
||||
rabbitmq-c,
|
||||
rdkafka,
|
||||
rdma-core,
|
||||
redis-plus-plus,
|
||||
spdlog,
|
||||
}:
|
||||
stdenv.mkDerivation {
|
||||
inherit src version;
|
||||
pname = "villas";
|
||||
version = "release";
|
||||
src = src;
|
||||
cmakeFlags = [
|
||||
"-DWITH_FPGA=OFF"
|
||||
"-DDOWNLOAD_GO=OFF"
|
||||
"-DCMAKE_BUILD_TYPE=Release"
|
||||
# the default -O3 causes g++ warning false positives on
|
||||
# 'array-bounds' and 'stringop-overflow' for villas-relay
|
||||
"-DCMAKE_CXX_FLAGS_RELEASE=-Wno-error"
|
||||
];
|
||||
cmakeFlags =
|
||||
[
|
||||
"-DDOWNLOAD_GO=OFF"
|
||||
"-DCMAKE_BUILD_TYPE=Release"
|
||||
"-DCMAKE_CXX_FLAGS_RELEASE=-Wno-error=maybe-uninitialized"
|
||||
]
|
||||
++ lib.optionals withFormatProtobuf ["-DCMAKE_FIND_ROOT_PATH=${protobufcBuildBuild}/bin"];
|
||||
preConfigure = ''
|
||||
rm -d common && ln -sf ${common} common
|
||||
rm -df common
|
||||
rm -df fpga
|
||||
ln -s ${common} common
|
||||
${lib.optionalString withNodeFpga "ln -s ${fpga} fpga"}
|
||||
'';
|
||||
postInstall = ''
|
||||
patchShebangs --build $out/bin/villas
|
||||
wrapProgram $out/bin/villas \
|
||||
--set PATH ${lib.makeBinPath [(placeholder "out") gnugrep coreutils]}
|
||||
'';
|
||||
|
@ -75,6 +90,7 @@ stdenv.mkDerivation {
|
|||
makeWrapper
|
||||
pkg-config
|
||||
];
|
||||
depsBuildBuild = lib.optionals withFormatProtobuf [protobufcBuildBuild];
|
||||
buildInputs =
|
||||
[
|
||||
jansson
|
||||
|
@ -84,21 +100,26 @@ stdenv.mkDerivation {
|
|||
curl
|
||||
spdlog
|
||||
]
|
||||
++ lib.optionals withConfig [libconfig]
|
||||
++ lib.optionals withProtobuf [protobuf protobufc]
|
||||
++ lib.optionals withExtraConfig [libconfig]
|
||||
++ lib.optionals withExtraGraphviz [graphviz]
|
||||
++ lib.optionals withFormatProtobuf [protobufc]
|
||||
++ lib.optionals withHookLua [lua]
|
||||
++ lib.optionals withNodeAmqp [rabbitmq-c]
|
||||
++ lib.optionals withNodeComedi [comedilib]
|
||||
++ lib.optionals withNodeZeromq [czmq libsodium]
|
||||
++ lib.optionals withNodeIec60870 [lib60870]
|
||||
++ lib.optionals withNodeIec61850 [libiec61850]
|
||||
++ lib.optionals withNodeSocket [libnl]
|
||||
++ lib.optionals withNodeRtp [libre]
|
||||
++ lib.optionals withNodeUldaq [libuldaq]
|
||||
++ lib.optionals withNodeTemper [libusb]
|
||||
++ lib.optionals withNodeInfiniband [rdma-core]
|
||||
++ lib.optionals withNodeKafka [rdkafka]
|
||||
++ lib.optionals withNodeMqtt [mosquitto]
|
||||
++ lib.optionals withNodeNanomsg [nanomsg]
|
||||
++ lib.optionals withNodeKafka [rdkafka]
|
||||
++ lib.optionals withNodeInfiniband [rdma-core];
|
||||
++ lib.optionals withNodeRedis [redis-plus-plus]
|
||||
++ lib.optionals withNodeRtp [libre]
|
||||
++ lib.optionals withNodeSocket [libnl]
|
||||
++ lib.optionals withNodeTemper [libusb]
|
||||
++ lib.optionals withNodeUldaq [libuldaq]
|
||||
++ lib.optionals withNodeZeromq [czmq libsodium];
|
||||
meta = with lib; {
|
||||
mainProgram = "villas";
|
||||
description = "a tool connecting real-time power grid simulation equipment";
|
||||
homepage = "https://villas.fein-aachen.org/";
|
||||
license = licenses.asl20;
|
||||
|
|
Loading…
Add table
Reference in a new issue