diff --git a/README.md b/README.md index f8c633c11..068b7c096 100644 --- a/README.md +++ b/README.md @@ -264,6 +264,38 @@ cd c3c-git makepkg -si ``` +#### Installing via Nix + +You can access `c3c` via [flake.nix](./flake.nix), which will contain the latest commit of the compiler. To add `c3c` to your `flake.nix`, do the following: +```nix +{ + inputs = { + nixpkgs.url = "github:nixos/nixpkgs?ref=nixpkgs-unstable"; + flake-utils.url = "github:numtide/flake-utils"; + c3c.url = "github:c3lang/c3c"; + # Those are desired if you don't want to copy extra nixpkgs + c3c.inputs = { + nixpkgs.follows = "nixpkgs"; + flake-utils.follows = "flake-utils"; + }; + }; + + outputs = { self, ... } @ inputs: inputs.flake-utils.lib.eachDefaultSystem (system: + let + pkgs = import inputs.nixpkgs { inherit system; }; + c3c = inputs.c3c.packages.${system}.c3c; + in + { + devShells.default = pkgs.mkShell { + buildInputs = [ + pkgs.c3c + ]; + }; + } + ); +} +``` + #### Building via Docker You can build `c3c` using an Ubuntu container. By default, the script will build through Ubuntu 22.04. You can specify the version by passing the `UBUNTU_VERSION` environment variable. @@ -405,6 +437,14 @@ After compilation, the `c3c` binary will be located in the `build` directory. Yo 6. To install the compiler globally: `sudo cmake --install build` +#### Compiling on NixOS + +1. Enter nix shell, by typing `nix develop` in root directory +2. Configure cmake via `cmake . -Bbuild $=C3_CMAKE_FLAGS`. Note: passing `C3_CMAKE_FLAGS` is needed in due to generate `compile_commands.json` and find missing libs. +4. Build it `cmake --build build` +5. Test it out: `./build/c3c -V` +6. If you use `clangd` lsp server for your editor, it is recommended to make a symbolic link to `compile_command.json` in the root: `ln -s ./build/compile_commands.json compile_commands.json` + #### Compiling on other Linux / Unix variants 1. Install CMake. diff --git a/flake.nix b/flake.nix index cd78b900a..769b40a8c 100644 --- a/flake.nix +++ b/flake.nix @@ -6,29 +6,27 @@ flake-utils.url = "github:numtide/flake-utils"; }; - outputs = { self, ... } @ inputs: inputs.flake-utils.lib.eachDefaultSystem + outputs = { self, ... }@inputs: inputs.flake-utils.lib.eachDefaultSystem (system: let pkgs = import inputs.nixpkgs { inherit system; }; - call = set: pkgs.callPackage ./nix/default.nix ( - set // { - rev = self.rev or "unknown"; - } - ); + c3cBuild = set: pkgs.callPackage ./nix/default.nix (set // { + rev = self.rev or "unknown"; + }); in { packages = { default = self.packages.${system}.c3c; - c3c = call {}; + c3c = c3cBuild {}; - c3c-checks = pkgs.callPackage ./nix/default.nix { + c3c-checks = c3cBuild { checks = true; }; - c3c-debug = pkgs.callPackage ./nix/default.nix { + c3c-debug = c3cBuild { debug = true; }; - c3c-debug-checks = pkgs.callPackage ./nix/default.nix { + c3c-debug-checks = c3cBuild { debug = true; checks = true; }; diff --git a/nix/default.nix b/nix/default.nix index a0d4697ec..cee6d78d7 100644 --- a/nix/default.nix +++ b/nix/default.nix @@ -2,12 +2,11 @@ lib, llvmPackages, cmake, - python3, curl, libxml2, libffi, xar, - rev ? "unknown", + rev, debug ? false, checks ? false, }: let @@ -16,8 +15,8 @@ inherit (lib.lists) findFirst; inherit (lib.asserts) assertMsg; inherit (lib.strings) hasInfix splitString removeSuffix removePrefix optionalString; -in llvmPackages.stdenv.mkDerivation (finalAttrs: { - +in llvmPackages.stdenv.mkDerivation (_: +{ pname = "c3c${optionalString debug "-debug"}"; version = let @@ -28,13 +27,19 @@ in llvmPackages.stdenv.mkDerivation (finalAttrs: { src = ../.; - cmakeBuildType = if debug then "Debug" else "Release"; - - postPatch = '' - substituteInPlace git_hash.cmake \ - --replace-fail "\''${GIT_HASH}" "${rev}" + # Here we substitute GIT_HASH which is not set for cmake in nix builds. + # Similar situation is with __DATE__ and __TIME__ macros, which are + # set to "Jan 01 1980 00:00:00" by default. + patchPhase = '' + substituteInPlace git_hash.cmake --replace-fail "\''${GIT_HASH}" "${rev}" + + local FILE_NAMES="$(find src -type f)" + substituteInPlace $FILE_NAMES --replace-quiet "__DATE__" "\"$(date '+%b %d %Y')\"" + substituteInPlace $FILE_NAMES --replace-quiet "__TIME__" "\"$(date '+%T')\"" ''; + cmakeBuildType = if debug then "Debug" else "Release"; + cmakeFlags = [ "-DC3_ENABLE_CLANGD_LSP=${if debug then "ON" else "OFF"}" "-DC3_LLD_DIR=${llvmPackages.lld.lib}/lib" @@ -54,17 +59,25 @@ in llvmPackages.stdenv.mkDerivation (finalAttrs: { libffi ] ++ lib.optionals llvmPackages.stdenv.hostPlatform.isDarwin [ xar ]; - nativeCheckInputs = [ python3 ]; - - doCheck = llvmPackages.stdenv.system == "x86_64-linux" && checks; + doCheck = checks && lib.elem llvmPackages.stdenv.system [ + "x86_64-linux" + "x86_64-darwin" + "aarch64-darwin" + ]; + # In check phase we preserve BUILD directory as + # we need to return to it before install phase checkPhase = '' - runHook preCheck - ( cd ../resources/testproject; ../../build/c3c build --trust=full ) - ( cd ../test; ../build/c3c compile-run -O1 src/test_suite_runner.c3 -- ../build/c3c test_suite ) - runHook postCheck - ''; + local BUILD_DIR=$(pwd) + + cd ../resources/testproject + ../../build/c3c build --trust=full + cd ../../test + ../build/c3c compile-run -O1 src/test_suite_runner.c3 -- ../build/c3c ./test_suite + + cd $BUILD_DIR + ''; meta = with lib; { description = "Compiler for the C3 language";