From 6560a7fee0a0e5319295328077408dacb3558e13 Mon Sep 17 00:00:00 2001 From: Sameer Rahmani Date: Sun, 17 Mar 2024 21:31:20 +0000 Subject: [PATCH] Setup a basic statically linked build system --- .envrc | 2 + .gitignore | 3 + CMakeLists.txt | 104 +++++++++++++++ feynman/CMakeLists.txt | 126 ++++++++++++++++++ feynman/src/CMakeLists.txt | 19 +++ feynman/src/config.h.in | 27 ++++ feynman/src/main.cpp | 26 ++++ flake.lock | 94 +++++++++++++ flake.nix | 198 ++++++++++++++++++++++++++++ nix/patches/p11-kit_skip_test.patch | 27 ++++ nix/utils.nix | 47 +++++++ 11 files changed, 673 insertions(+) create mode 100644 .envrc create mode 100644 CMakeLists.txt create mode 100644 feynman/CMakeLists.txt create mode 100644 feynman/src/CMakeLists.txt create mode 100644 feynman/src/config.h.in create mode 100644 feynman/src/main.cpp create mode 100644 flake.lock create mode 100644 flake.nix create mode 100644 nix/patches/p11-kit_skip_test.patch create mode 100644 nix/utils.nix diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..9384931 --- /dev/null +++ b/.envrc @@ -0,0 +1,2 @@ +strict_env +use flake . \ No newline at end of file diff --git a/.gitignore b/.gitignore index cdc4938..2bae49e 100644 --- a/.gitignore +++ b/.gitignore @@ -155,3 +155,6 @@ flycheck_*.el /network-security.data +build/ +.cache/ +.direnv/ \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..a53a8cd --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,104 @@ +# FeynmanDB +# +# Copyright (c) 2023-2024 Sameer Rahmani +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, version 2. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +#A git plugin to manage journal entries in git +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +cmake_minimum_required(VERSION 3.19) + +project(Feynman + VERSION 0.1.0 + DESCRIPTION "A single user and local graph database" + LANGUAGES CXX) + +# Clangd command file +set(CMAKE_EXPORT_COMPILE_COMMANDS 1) + +# ============================================================================= +# Policies +# ============================================================================= +cmake_policy(SET CMP0116 OLD) + +# ============================================================================= +# User Options +# ============================================================================= +option(CPP_20_SUPPORT "C++20 Support" ON) +option(ENABLE_CCACHE "Enable ccache support" ON) +option(ENABLE_DOCS "Enable docs" OFF) +option(ENABLE_TESTS "Enable testing" OFF) +option(ENABLE_LIBCXX "Enable libcxx" ON) +option(ENABLE_COMPILER_RT "Enable compiler-rt" ON) + +# Let's ensure -std=c++xx instead of -std=g++xx +set(CMAKE_CXX_EXTENSIONS OFF) + +set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") +set(MemoryCheckCommand "valgrind") + +# Let's nicely support folders in IDEs +set_property(GLOBAL PROPERTY USE_FOLDERS ON) + +# Setup the basic compiler flags +add_compile_options( + -Wall + -Wextra + -Werror + -Wpedantic + -Wabstract-final-class + -Walloca + -Warray-bounds-pointer-arithmetic + -Warray-parameter + -Wassign-enum + -Wsign-conversion + -Wnon-virtual-dtor + -Wold-style-cast + -Wcast-align + -Wunused + -Woverloaded-virtual + -Wdouble-promotion + -Wno-error=unused-command-line-argument + -Wformat=2) + +add_link_options(-Wl,-Map=output.map) + +# CCache support ============================== +if(ENABLE_CCACHE) + find_program(CCACHE_PROGRAM ccache) + + if(CCACHE_PROGRAM) + message(STATUS "Found CCache") + set(CCACHE_MAXSIZE "" CACHE STRING "Size of ccache") + set(CCACHE_DIR "" CACHE STRING "Directory to keep ccached data") + set(CCACHE_PARAMS "CCACHE_CPP2=yes CCACHE_HASHDIR=yes" + CACHE STRING "Parameters to pass through to ccache") + + set(CCACHE_PROGRAM "${CCACHE_PARAMS} ${CCACHE_PROGRAM}") + + if (CCACHE_MAXSIZE) + set(CCACHE_PROGRAM "CCACHE_MAXSIZE=${CCACHE_MAXSIZE} ${CCACHE_PROGRAM}") + endif() + if (CCACHE_DIR) + set(CCACHE_PROGRAM "CCACHE_DIR=${CCACHE_DIR} ${CCACHE_PROGRAM}") + endif() + message(STATUS "Using CCACHE: ${CCACHE_PROGRAM}") + set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ${CCACHE_PROGRAM}) + + else() + message(FATAL_ERROR "Unable to find the program ccache. Set ENABLE_CCACHE to OFF") + endif() +endif() + +if (ENABLE_DOCS) + add_subdirectory(docs) +endif() + +add_subdirectory(feynman) diff --git a/feynman/CMakeLists.txt b/feynman/CMakeLists.txt new file mode 100644 index 0000000..1ecee9f --- /dev/null +++ b/feynman/CMakeLists.txt @@ -0,0 +1,126 @@ +# FeynmanDB +# +# Copyright (c) 2023-2024 Sameer Rahmani +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, version 2. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +find_program(iwyu NAMES include-what-you-use iwyu REQUIRED) +set(iwyu_path ${iwyu}) + +find_program(lld NAMES lld REQUIRED) + +add_executable(feynman) + +set_target_properties(feynman PROPERTIES + VERSION ${PROJECT_VERSION} + SOVERSION ${PROJECT_VERSION_MAJOR} + C_INCLUDE_WHAT_YOU_USE ${iwyu} + CXX_INCLUDE_WHAT_YOU_USE ${iwyu} + # Warn on unused libs + LINK_WHAT_YOU_USE TRUE +) + +target_compile_features(feynman PRIVATE cxx_std_20) + +# Setup header directory and auto generated headers +target_include_directories(feynman + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} +) + +target_include_directories(feynman SYSTEM PUBLIC + # We don't want the generated files from table gen + # to be treated as local since the contain warnings + ${PROJECT_BINARY_DIR}/include) + + +# target_link_libraries(feynman PRIVATE + +# ) + +# Autogenerate the `config.h` file +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/src/config.h.in include/config.h) + +target_compile_options(feynman + PRIVATE + # $<$:-stdlib=libc++> + + -fno-builtin-strlen + + # Dedicate a section to each function, so the linker + # can do a better job on dead code elimination + -ffunction-sections + -fdata-sections + + $<$:-fsanitize=address> + $<$:-static-libsan> + $<$:-g3> + $<$:-O0> + $<$:-ggdb> + # For the sake of debugging + $<$:-fno-inline> + # To make the local ccache happy + $<$:-fdebug-prefix-map=${PROJECT_SOURCE_DIR}=.> + + # No tail call elimination on Debug to let asan provide + # better stacktrackes + $<$:-fno-optimize-sibling-calls> + + $<$:-fno-omit-frame-pointer> + $<$:-fomit-frame-pointer> + $<$:-O3> + $<$:-fmerge-all-constants> +) + +target_link_options(feynman PRIVATE + -Wl,--gc-sections + -Wl,-fuse-ld=lld + $<$:-s> + + $<$:-fsanitize=address> + $<$:-static-libsan> + + # Do not link against shared libraries + -static-pie +) + +if (CMAKE_BUILD_TYPE EQUAL "DEBUG") + find_program(CLANG_TIDY_PATH NAMES clang-tidy REQUIRED) + set_target_properties(feynman PROPERTIES CXX_CLANG_TIDY ${CLANG_TIDY_PATH}) +endif() + +include(CheckIPOSupported) +set_property(TARGET feynman PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE) + +include(CheckPIESupported) +check_pie_supported() +set_property(TARGET feynman PROPERTY POSITION_INDEPENDENT_CODE TRUE) + +include(GNUInstallDirs) + +install(TARGETS feynman EXPORT FeynmanTargets + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) + + +if(ENABLE_TESTS) + enable_testing() + find_package(GTest REQUIRED) + add_subdirectory(tests) + # For Windows: Prevent overriding the parent project's compiler/linker settings + set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) +endif() + +add_subdirectory(src) diff --git a/feynman/src/CMakeLists.txt b/feynman/src/CMakeLists.txt new file mode 100644 index 0000000..95af0c0 --- /dev/null +++ b/feynman/src/CMakeLists.txt @@ -0,0 +1,19 @@ +# FeynmanDB +# +# Copyright (c) 2023-2024 Sameer Rahmani +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, version 2. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +target_sources(feynman PRIVATE + main.cpp +) diff --git a/feynman/src/config.h.in b/feynman/src/config.h.in new file mode 100644 index 0000000..823ef7a --- /dev/null +++ b/feynman/src/config.h.in @@ -0,0 +1,27 @@ +/* -*- C++ -*- + * FeynmanDB + * + * Copyright (c) 2019-2024 Sameer Rahmani + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef CONFIG_H +#define CONFIG_H + +#if __cplusplus < 202002L +# error "C++20 or better is required" +#endif + +#define FEYNMAN_VERSION "@PROJECT_VERSION@" + +#endif diff --git a/feynman/src/main.cpp b/feynman/src/main.cpp new file mode 100644 index 0000000..ab4249f --- /dev/null +++ b/feynman/src/main.cpp @@ -0,0 +1,26 @@ +/* -*- C++ -*- + * FeynmanDB + * + * Copyright (c) 2019-2024 Sameer Rahmani + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include // for ArgumentParser +#include // for allocator + +//int argc, char *argv[] +int main() { + argparse::ArgumentParser program("git-journal"); + return 0; +} diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..54c0046 --- /dev/null +++ b/flake.lock @@ -0,0 +1,94 @@ +{ + "nodes": { + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1710146030, + "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", + "type": "github" + }, + "original": { + "id": "flake-utils", + "type": "indirect" + } + }, + "flake_utils": { + "inputs": { + "systems": "systems_2" + }, + "locked": { + "lastModified": 1710146030, + "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1705092417, + "narHash": "sha256-01pTqprf3NvQijvxkQjwx2c6uevB4MZKooIcf+RTYHA=", + "owner": "lxsameer", + "repo": "nixpkgs", + "rev": "e1f7865bce4d52d30dd1d61e79798ee2765cc2b0", + "type": "github" + }, + "original": { + "owner": "lxsameer", + "repo": "nixpkgs", + "rev": "e1f7865bce4d52d30dd1d61e79798ee2765cc2b0", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "flake_utils": "flake_utils", + "nixpkgs": "nixpkgs" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_2": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..7eb76ae --- /dev/null +++ b/flake.nix @@ -0,0 +1,198 @@ +# FeynmanDB +# +# Copyright (c) 2024 Sameer Rahmani +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, version 2. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +{ + description = "A single user and local graph database"; + + inputs = { + #nixpkgs.url = "github:nixos/nixpkgs/442d407992384ed9c0e6d352de75b69079904e4e"; + nixpkgs.url = "github:lxsameer/nixpkgs/e1f7865bce4d52d30dd1d61e79798ee2765cc2b0"; + flake_utils.url = "github:numtide/flake-utils"; + }; + + outputs = { self, nixpkgs, flake-utils, ... } @ inputs: + flake-utils.lib.eachDefaultSystem (system: + let + overlays = [ + (final: prev: { + p11-kit = prev.p11-kit.overrideAttrs (old: { + patches = [ + ./nix/patches/p11-kit_skip_test.patch + ]; + }); + + cpio = prev.cpio.overrideAttrs (old: { + nativeBuildInputs = [ prev.autoreconfHook ]; + NIX_CFLAGS_COMPILE = "-Wno-implicit-function-declaration"; + }); + + libedit = prev.libedit.overrideAttrs (old: { + # Musl is ISO 10646 compliant but doesn't define __STDC_ISO_10646__ we need to do it ourselves + NIX_CFLAGS_COMPILE = "-D__STDC_ISO_10646__=201103L"; + }); + + elfutils = prev.elfutils.overrideAttrs (old: { + # libcxx does not have __cxa_demangle + configureFlags = old.configureFlags ++ [ "--disable-demangler" ]; + }); + + ccache = prev.ccache.overrideAttrs (old: { + nativeBuildInputs = old.nativeBuildInputs ++ [ final.elfutils ]; + }); + + # We don't need systemd at all + util-linux = prev.util-linux.override { systemdSupport = false; }; + + # libpam exmaples use glibc. We need to disable them + linux-pam = prev.linux-pam.overrideAttrs (old: { + postConfigure = '' + sed 's/examples//' -i Makefile + ''; + }); + + #============================================================= + # Since we're using lld-17, and --no-undefined-version is the + # default in lld-17. We need to explicitely turn it off for + # these problematic packages untill they fix it upstream. + libgcrypt = prev.libgcrypt.overrideAttrs (old: { + NIX_LDFLAGS = if prev.stdenv.cc.isClang + then [ "--undefined-version" ] + else []; + }); + libxcrypt = prev.libxcrypt.overrideAttrs (old: { + NIX_LDFLAGS = if prev.stdenv.cc.isClang + then [ "--undefined-version" ] + else []; + }); + ncurses = prev.ncurses.overrideAttrs (old: { + NIX_LDFLAGS = if prev.stdenv.cc.isClang + then [ "--undefined-version" ] + else []; + }); + + libbsd = prev.libbsd.overrideAttrs (old: { #old.NIX_LDFLAGS ++ + NIX_LDFLAGS = if prev.stdenv.cc.isClang + then [ "--undefined-version" ] + else []; + }); + libidn2 = prev.libidn2.overrideAttrs (old: { #old.NIX_LDFLAGS ++ + NIX_LDFLAGS = if prev.stdenv.cc.isClang + then [ "--undefined-version" ] + else []; + }); + + fmt = prev.fmt.overrideAttrs (old: { + doCheck = false; + }); + + # libapparmor = prev.libapparmor.overrideAttrs (old: { + # NIX_CFLAGS_COMPILE = "--no-" + # }); + #============================================================== + + iwyu = (prev.include-what-you-use.overrideAttrs (old: + let + version = "0.21"; + in { + inherit version; + + src = prev.fetchurl { + url = "${old.meta.homepage}/downloads/${old.pname}-${version}.src.tar.gz"; + hash = "sha256-ajUZGf+JvafJXIlUcmAYaNs9qrlqlYs44DYokNWHYLY="; + }; + cmakeFlags = [ "-DCMAKE_PREFIX_PATH=${prev.llvmPackages_17.llvm.dev}" ]; + + })).override { + llvmPackages = prev.__splicedPackages.llvmPackages_17; + }; + }) + ]; + + get_pkgs = overlays: + if system == "x86_64-linux" + then import nixpkgs { + inherit system overlays; + linker = "lld"; + crossSystem = nixpkgs.lib.systems.examples.musl64; + } + else import nixpkgs { + inherit system overlays; + }; + + pkgs = get_pkgs overlays; + # Just disabling the tests that fails under musl + git' = pkgs.git.overrideAttrs (old: { + preInstallCheck = + pkgs.lib.replaceStrings [ ''disable_test t0201-gettext-fallbacks'' ] + [ '' + disable_test t0201-gettext-fallbacks + disable_test t2082-parallel-checkout-attributes + '' ] + old.preInstallCheck; + }); + + stdenv = pkgs.overrideCC pkgs.stdenv pkgs.llvmPackages_17.clangUseLLVM; + + buildToolsDeps = (with pkgs; [ + cmake + ninja + clang_17 + lld_17 + clang-tools + ccache + iwyu + git' + valgrind + gtest + bashInteractive + ]); + + deps = (with pkgs; [ + fmt + rocksdb + gtest + argparse + ]); + + utils = pkgs.callPackage ./nix/utils.nix { deps = buildToolsDeps ++ deps; }; + + devCommands = (with utils; [ + build + run + compile + ]); + + shell = args: (pkgs.mkShell.override { inherit stdenv; }) { + nativeBuildInputs = buildToolsDeps ++ devCommands; + buildInputs = deps; + } // args; + + in { + + packages.default = stdenv.mkDerivation { + pname = "feynmanDB"; + version = "0.1.0"; + + src = ./.; + + cmakeFlags = []; + + nativeBuildInputs = buildToolsDeps; + buildInputs = deps; + }; + + devShells.default = shell {}; + }); +} diff --git a/nix/patches/p11-kit_skip_test.patch b/nix/patches/p11-kit_skip_test.patch new file mode 100644 index 0000000..34da908 --- /dev/null +++ b/nix/patches/p11-kit_skip_test.patch @@ -0,0 +1,27 @@ +From 132b779414c2236c1350b578b59c8edcfc4c5a14 Mon Sep 17 00:00:00 2001 +From: Sameer Rahmani +Date: Sat, 25 Nov 2023 13:14:42 +0000 +Subject: [PATCH] test + +--- + common/test.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/common/test.c b/common/test.c +index 6cdbd1fa2118..6cd6f84bcdc7 100644 +--- a/common/test.c ++++ b/common/test.c +@@ -614,8 +614,9 @@ p11_test_copy_setgid (const char *input, + assert (fd >= 0); + + copy_file (input, fd); +- if (fchown (fd, getuid (), group) < 0) +- assert_not_reached (); ++ if (fchown (fd, getuid (), group) < 0) { ++ return NULL; ++ } + if (fchmod (fd, 02750) < 0) + assert_not_reached (); + if (close (fd) < 0) +-- +2.41.0 diff --git a/nix/utils.nix b/nix/utils.nix new file mode 100644 index 0000000..2bb2d2d --- /dev/null +++ b/nix/utils.nix @@ -0,0 +1,47 @@ +# FeynmanDB +# +# Copyright (c) 2024 Sameer Rahmani +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, version 2. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +{ deps, writeShellApplication, cmake, ninja, ...}: +let + compile = writeShellApplication { + name = "compile"; + runtimeInputs = deps; + text = '' + mkdir -p ./build + cd build + ${cmake}/bin/cmake -GNinja .. "$@" + ${ninja}/bin/ninja -j32 -v + ''; + }; + + run = writeShellApplication { + name = "run"; + text = '' + "$(pwd)/build/feynman/feynman" "$@" + ''; + }; + + build = writeShellApplication { + name = "build"; + runtimeInputs = [ compile ] ++ deps; + + text = '' + rm -rf ./build + ${compile}/bin/compile "$@" + ''; + }; +in { + inherit compile run build; +}