💾 Archived View for misterio.me › notes › c-nix-boilerplate › index.gmi captured on 2022-07-16 at 14:31:57. Gemini links have been rewritten to link to archived content
-=-=-=-=-=-=-
Gabriel Fontes
Last modified on 13 Jul 2022 by Gabriel Fontes
Tags: #nix
Looking to start out a C (or C++) project and wanna some cool and nifty commands to manage it through both make and nix? As a plus, you'll also get nice out of tree builds.
Then look no further, here's all the boilerplate you need.
If you just want it fast without an explanation, it's all available on my repository.
You can just run nix flake init -t github:misterio77/nix-config#templates.c, to quickly init a flake with this template.
We're gonna start by building a flexible (yet simple) Makefile:
# Set default prefix and bin dirs, for non-nixos PREFIX ?= /usr/local BIN_DIR ?= $(PREFIX)/bin # Executable name TARGET_EXEC ?= foo-bar # Build directory BUILD_DIR ?= ./build # Source directory(ies) SRC_DIRS ?= ./src # Use find to get all .c and .cpp files SRCS := $(shell find $(SRC_DIRS) -name *.cpp -or -name *.c) # Map those to their respective .o files OBJS := $(SRCS:%=$(BUILD_DIR)/%.o) # Dependency files generated by gcc DEPS := $(OBJS:.o=.d) # Directories with includes INC_DIRS := $(shell find $(SRC_DIRS) -type d) # Flags for including those INC_FLAGS := $(addprefix -I,$(INC_DIRS)) # Flags for both C and C++ CPPFLAGS ?= $(INC_FLAGS) -MMD -MP # Link executable $(BUILD_DIR)/$(TARGET_EXEC): $(OBJS) $(CXX) $(OBJS) -o $@ $(LDFLAGS) # C source files $(BUILD_DIR)/%.c.o: %.c $(MKDIR_P) $(dir $@) $(CC) $(CPPFLAGS) $(CFLAGS) -c {body}lt; -o $@ # C++ source files $(BUILD_DIR)/%.cpp.o: %.cpp $(MKDIR_P) $(dir $@) $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c {body}lt; -o $@ # Clean built artifacts clean: $(RM) -r $(BUILD_DIR) # Install to prefix/bin path install: $(BUILD_DIR)/$(TARGET_EXEC) install -d $(BIN_DIR) install -t $(BIN_DIR) {body}lt; # Include generated dependencies -include $(DEPS) MKDIR_P ?= mkdir -p
This is heavily based on this post, with the main change being the install directive.
Okay, now we just need a flake for building with nix:
{ description = "Foo Bar C/C++ Project"; inputs = { nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; flake-utils.url = "github:numtide/flake-utils"; }; outputs = { self, nixpkgs, flake-utils }: # For each system flake-utils.lib.eachDefaultSystem (system: let # Derivation and executable name name = "foo-bar"; pkgs = (import nixpkgs { inherit system; }); in rec { # nix build packages.${name} = pkgs.stdenv.mkDerivation rec { inherit name; src = ./.; # Set prefix, so stuff is installed to $out makeFlags = [ "PREFIX=$(out)" ]; }; defaultPackage = packages.${name}; # nix run apps.${name} = { type = "app"; program = "${packages.${name}}/bin/${name}"; }; defaultApp = apps.${name}; # nix develop devShell = pkgs.mkShell { # Add clang and clang-tools for LSP support while editing buildInputs = with pkgs; [ gnumake clang clang-tools ]; }; }); }
And there you go!
Wanna talk? Hit me up on email. Feel free to encrypt, and use plaintext if possible.
PGP: 7088 C742 1873 E0DB 97FF 17C2 245C AB70 B4C2 25E9
This site's code is available under MIT, while its content is CC BY-SA 4.0