summary refs log blame commit diff
path: root/pkgs/applications/terminal-emulators/foot/default.nix
blob: a58e45e50dc35ecf60b1bd9dc41e0b80c05872b0 (plain) (tree)
1
2
3
4
5

        
                
          
            











                   
                 
            
          

                    



                        

  
   
                     




                                                                  

                                                              
                                           
                                             


                                                                                                      
                                                                      










                              
                                                     


















                                                                                         

                                                       


                       
                                          








                                                                   

                                                           
  

                         
                  
 




                            
                                                                    

    



                                                   



                    
                       
                   



           
              


                                                
 
                 

                     





                
            

    







                                                                             
                   
                     

     

                             
                                                                       
                
             
                  

                                         

                              
                                                                       
                                                       
    
 




                                                                  


                                                              
                       
                                                   

                                                      
                                                               


                                                                  






                                                                         
 







                                               



                           






                                                                              

    
                    
                                                 
                                                                         



                                                                                   












                                                                     

    
{ stdenv
, lib
, fetchFromGitea
, fetchurl
, runCommand
, fcft
, freetype
, pixman
, libxkbcommon
, fontconfig
, wayland
, meson
, ninja
, ncurses
, scdoc
, tllist
, wayland-protocols
, wayland-scanner
, pkg-config
, utf8proc
, allowPgo ? true
, python3  # for PGO
# for clang stdenv check
, foot
, llvmPackages
, llvmPackages_latest
}:

let
  version = "1.11.0";

  # build stimuli file for PGO build and the script to generate it
  # independently of the foot's build, so we can cache the result
  # and avoid unnecessary rebuilds as it can take relatively long
  # to generate
  #
  # For every bump, make sure that the hash is still accurate.
  stimulusGenerator = stdenv.mkDerivation {
    name = "foot-generate-alt-random-writes";

    src = fetchurl {
      url = "https://codeberg.org/dnkl/foot/raw/tag/${version}/scripts/generate-alt-random-writes.py";
      sha256 = "0w4d0rxi54p8lvbynypcywqqwbbzmyyzc0svjab27ngmdj1034ii";
    };

    dontUnpack = true;

    buildInputs = [ python3 ];

    installPhase = ''
      install -Dm755 $src $out
    '';
  };

  stimuliFile = runCommand "pgo-stimulus-file" { } ''
    ${stimulusGenerator} \
      --rows=67 --cols=135 \
      --scroll --scroll-region \
      --colors-regular --colors-bright --colors-256 --colors-rgb \
      --attr-bold --attr-italic --attr-underline \
      --sixel \
      --seed=2305843009213693951 \
      $out
  '';

  compilerName =
    if stdenv.cc.isClang
    then "clang"
    else if stdenv.cc.isGNU
    then "gcc"
    else "unknown";

  # https://codeberg.org/dnkl/foot/src/branch/master/INSTALL.md#performance-optimized-pgo
  pgoCflags = {
    "clang" = "-O3 -Wno-ignored-optimization-argument";
    "gcc" = "-O3";
  }."${compilerName}";

  # ar with lto support
  ar = stdenv.cc.bintools.targetPrefix + {
    "clang" = "llvm-ar";
    "gcc" = "gcc-ar";
    "unknown" = "ar";
  }."${compilerName}";

  # PGO only makes sense if we are not cross compiling and
  # using a compiler which foot's PGO build supports (clang or gcc)
  doPgo = allowPgo && (stdenv.hostPlatform == stdenv.buildPlatform)
    && compilerName != "unknown";

  terminfoDir = "${placeholder "terminfo"}/share/terminfo";
in
stdenv.mkDerivation rec {
  pname = "foot";
  inherit version;

  src = fetchFromGitea {
    domain = "codeberg.org";
    owner = "dnkl";
    repo = pname;
    rev = version;
    sha256 = "1d9bk8lhmw5lc8k0mw80g0vbwgxyh3gw5c7ppy3sir07s9y0y0fn";
  };

  patches = [
    ./Add-support-for-opening-an-existing-PTY.patch
  ];

  depsBuildBuild = [
    pkg-config
  ];

  nativeBuildInputs = [
    wayland-scanner
    meson
    ninja
    ncurses
    scdoc
    pkg-config
  ] ++ lib.optionals (compilerName == "clang") [
    stdenv.cc.cc.libllvm.out
  ];

  buildInputs = [
    tllist
    wayland-protocols
    fontconfig
    freetype
    pixman
    wayland
    libxkbcommon
    fcft
    utf8proc
  ];

  # recommended build flags for performance optimized foot builds
  # https://codeberg.org/dnkl/foot/src/branch/master/INSTALL.md#release-build
  CFLAGS =
    if !doPgo
    then "-O3 -fno-plt"
    else pgoCflags;

  # ar with gcc plugins for lto objects
  preConfigure = ''
    export AR="${ar}"
  '';

  mesonBuildType = "release";

  # See https://codeberg.org/dnkl/foot/src/tag/1.9.2/INSTALL.md#options
  mesonFlags = [
    # Use lto
    "-Db_lto=true"
    # “Build” and install terminfo db
    "-Dterminfo=enabled"
    # Ensure TERM=foot is used
    "-Ddefault-terminfo=foot"
    # Tell foot to set TERMINFO and where to install the terminfo files
    "-Dcustom-terminfo-install-location=${terminfoDir}"
  ];

  # build and run binary generating PGO profiles,
  # then reconfigure to build the normal foot binary utilizing PGO
  preBuild = lib.optionalString doPgo ''
    meson configure -Db_pgo=generate
    ninja
    # make sure there is _some_ profiling data on all binaries
    ./footclient --version
    ./foot --version
    ./tests/test-config
    # generate pgo data of wayland independent code
    ./pgo ${stimuliFile} ${stimuliFile} ${stimuliFile}
    meson configure -Db_pgo=use
  '' + lib.optionalString (doPgo && compilerName == "clang") ''
    llvm-profdata merge default_*profraw --output=default.profdata
  '';

  # Install example themes which can be added to foot.ini via the include
  # directive to a separate output to save a bit of space
  postInstall = ''
    moveToOutput share/foot/themes "$themes"
  '';

  outputs = [ "out" "terminfo" "themes" ];

  passthru.tests = {
    clang-default-compilation = foot.override {
      inherit (llvmPackages) stdenv;
    };

    clang-latest-compilation = foot.override {
      inherit (llvmPackages_latest) stdenv;
    };

    noPgo = foot.override {
      allowPgo = false;
    };

    # By changing name, this will get rebuilt everytime we change version,
    # even if the hash stays the same. Consequently it'll fail if we introduce
    # a hash mismatch when updating.
    stimulus-script-is-current = stimulusGenerator.src.overrideAttrs (_: {
      name = "generate-alt-random-writes-${version}.py";
    });
  };

  meta = with lib; {
    homepage = "https://codeberg.org/dnkl/foot/";
    changelog = "https://codeberg.org/dnkl/foot/releases/tag/${version}";
    description = "A fast, lightweight and minimalistic Wayland terminal emulator";
    license = licenses.mit;
    maintainers = [ maintainers.sternenseemann ];
    platforms = platforms.linux;
    # From (presumably) ncurses version 6.3, it will ship a foot
    # terminfo file. This however won't include some non-standard
    # capabilities foot's bundled terminfo file contains. Unless we
    # want to have some features in e. g. vim or tmux stop working,
    # we need to make sure that the foot terminfo overwrites ncurses'
    # one. Due to <nixpkgs/nixos/modules/config/system-path.nix>
    # ncurses is always added to environment.systemPackages on
    # NixOS with its priority increased by 3, so we need to go
    # one bigger.
    # This doesn't matter a lot for local use since foot sets
    # TERMINFO to a store path, but allows installing foot.terminfo
    # on remote systems for proper foot terminfo support.
    priority = (ncurses.meta.priority or 5) + 3 + 1;
  };
}