commit d433ed913427395adad5088ee4c3a8cd593a2b02 Author: Tobias Berger Date: Fri Dec 20 16:26:13 2024 +0100 Initial commit diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..8392d15 --- /dev/null +++ b/.envrc @@ -0,0 +1 @@ +use flake \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2bbdbfe --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.direnv +result diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..89618d2 --- /dev/null +++ b/flake.lock @@ -0,0 +1,48 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1734424634, + "narHash": "sha256-cHar1vqHOOyC7f1+tVycPoWTfKIaqkoe1Q6TnKzuti4=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "d3c42f187194c26d9f0309a8ecc469d6c878ce33", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs", + "treefmt-nix": "treefmt-nix" + } + }, + "treefmt-nix": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1734704479, + "narHash": "sha256-MMi74+WckoyEWBRcg/oaGRvXC9BVVxDZNRMpL+72wBI=", + "owner": "numtide", + "repo": "treefmt-nix", + "rev": "65712f5af67234dad91a5a4baee986a8b62dbf8f", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "treefmt-nix", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..c50ccb3 --- /dev/null +++ b/flake.nix @@ -0,0 +1,143 @@ +{ + description = "An over-engineered Hello World in C"; + + inputs = { + nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; + + treefmt-nix = { + url = "github:numtide/treefmt-nix"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + }; + + outputs = + { + self, + nixpkgs, + treefmt-nix, + }: + let + # to work with older version of flakes + lastModifiedDate = self.lastModifiedDate or self.lastModified or "19700101"; + + # Generate a user-friendly version number. + version = builtins.substring 0 8 lastModifiedDate; + + # System types to support. + supportedSystems = [ + "x86_64-linux" + "x86_64-darwin" + "aarch64-linux" + "aarch64-darwin" + ]; + + forEachSupportedSystem = + f: + nixpkgs.lib.genAttrs supportedSystems ( + system: + f ({ + pkgs = import nixpkgs { + inherit system; + overlays = [ self.overlays.default ]; + }; + }) + ); + in + { + formatter = forEachSupportedSystem ( + { pkgs, ... }: (treefmt-nix.lib.evalModule pkgs ./treefmt.nix).config.build.wrapper + ); + devShells = forEachSupportedSystem ( + { pkgs, ... }: + { + default = pkgs.mkShell { + nativeBuildInputs = with pkgs; [ + gcc14 + ]; + }; + } + ); + packages = forEachSupportedSystem ( + { pkgs, ... }: + { + default = pkgs.hello; + } + ); + overlays.default = final: prev: { + hello = + with final; + gcc14Stdenv.mkDerivation { + pname = "main"; + inherit version; + + src = ./.; + + buildPhase = '' + gcc gcc14 --version + gcc --std=gnu23 main.c -o main + ''; + installPhase = '' + mkdir -p $out/bin + install ./main $out/bin + ''; + }; + }; + + nixosModules.hello = + { pkgs, ... }: + { + nixpkgs.overlays = [ self.overlay ]; + + environment.systemPackages = [ pkgs.hello ]; + }; + + # Tests run by 'nix flake check' and by Hydra. + checks = forEachSupportedSystem ( + { pkgs, ... }: + with pkgs; + { + inherit (self.packages.${system}) hello; + + # Additional tests, if applicable. + test = stdenv.mkDerivation { + pname = "hello-test"; + inherit version; + + buildInputs = [ hello ]; + + dontUnpack = true; + + buildPhase = '' + echo 'running some integration tests' + [[ $(hello) = 'Hello Nixers!' ]] + ''; + + installPhase = "mkdir -p $out"; + }; + } + // lib.optionalAttrs gcc14stdenv.isLinux { + # A VM test of the NixOS module. + vmTest = + with import (nixpkgs + "/nixos/lib/testing-python.nix") { + inherit system; + }; + + makeTest { + nodes = { + client = + { ... }: + { + imports = [ self.nixosModules.hello ]; + }; + }; + + testScript = '' + start_all() + client.wait_for_unit("multi-user.target") + client.succeed("hello") + ''; + }; + } + ); + }; +} diff --git a/main.c b/main.c new file mode 100644 index 0000000..dfe19e7 --- /dev/null +++ b/main.c @@ -0,0 +1,42 @@ +#include +#define Result_t(T, E) \ + struct Result_##T##_##E { \ + bool is_ok; \ + union { \ + T value; \ + E error; \ + }; \ + } + +#define Ok(T, E) \ + (struct Result_##T##_##E) { \ + .is_ok = true, .value = (T)_OK_IMPL +#define _OK_IMPL(...) \ + __VA_ARGS__ \ + } + +#define Err(T, E) \ + (struct Result_##T##_##E) { \ + .is_ok = false, .error = (E)_ERR_IMPL +#define _ERR_IMPL(...) \ + __VA_ARGS__ \ + } + +typedef const char *ErrorMessage_t; + +Result_t(int, ErrorMessage_t) my_func(int i) { + if (i == 42) + return Ok(int, ErrorMessage_t)(100); + else + return Err(int, ErrorMessage_t)("Cannot do the thing"); +} + +int main(void) { + Result_t(int, ErrorMessage_t) x = my_func(42); + + if (x.is_ok) { + printf("%d\n", x.value); + } else { + printf("%s\n", x.error); + } +} diff --git a/treefmt.nix b/treefmt.nix new file mode 100644 index 0000000..ec20712 --- /dev/null +++ b/treefmt.nix @@ -0,0 +1,8 @@ +{ ... }: +{ + projectRootFile = "flake.nix"; + programs = { + nixfmt.enable = true; + clang-format.enable = true; + }; +}