{
  pname,
  version,
  branch,
  compat-list,
  src,
  lib,
  stdenv,
  cmake,
  boost,
  pkg-config,
  libusb1,
  glslang,
  zstd,
  libressl,
  enableSdl2 ? true,
  SDL2,
  enableQt ? true,
  qtbase,
  qtmultimedia,
  wrapQtAppsHook,
  enableQtTranslation ? enableQt,
  qttools,
  enableWebService ? true,
  enableCubeb ? true,
  cubeb,
  enableFfmpegAudioDecoder ? true,
  enableFfmpegVideoDumper ? true,
  ffmpeg_4,
  useDiscordRichPresence ? true,
  rapidjson,
  enableFdk ? false,
  fdk_aac,
  python3,
}:
assert lib.assertMsg (
  !enableFfmpegAudioDecoder || !enableFdk
) "Can't enable both enableFfmpegAudioDecoder and enableFdk";

stdenv.mkDerivation {
  inherit pname version src;

  nativeBuildInputs = [
    cmake
    glslang
    pkg-config
    python3
  ]
  ++ lib.optionals enableQt [ wrapQtAppsHook ];

  buildInputs = [
    boost
    libusb1
  ]
  ++ lib.optionals enableQt [
    qtbase
    qtmultimedia
  ]
  ++ lib.optional enableSdl2 SDL2
  ++ lib.optional enableQtTranslation qttools
  ++ lib.optionals enableCubeb cubeb.passthru.backendLibs
  ++ lib.optional (enableFfmpegAudioDecoder || enableFfmpegVideoDumper) ffmpeg_4
  ++ lib.optional useDiscordRichPresence rapidjson
  ++ lib.optional enableFdk fdk_aac;

  cmakeFlags = [
    "-DUSE_SYSTEM_BOOST=ON"
    "-DCITRA_WARNINGS_AS_ERRORS=OFF"
    "-DCITRA_USE_BUNDLED_FFMPEG=OFF"
    "-DCITRA_USE_BUNDLED_QT=OFF"
    "-DUSE_SYSTEM_SDL2=ON"
    "-DCMAKE_INSTALL_INCLUDEDIR=include"
    "-DCMAKE_INSTALL_LIBDIR=lib"

    # We dont want to bother upstream with potentially outdated compat reports
    "-DCITRA_ENABLE_COMPATIBILITY_REPORTING=ON"
    "-DENABLE_COMPATIBILITY_LIST_DOWNLOAD=OFF" # We provide this deterministically
  ]
  ++ lib.optional (!enableSdl2) "-DENABLE_SDL2=OFF"
  ++ lib.optional (!enableQt) "-DENABLE_QT=OFF"
  ++ lib.optional enableQtTranslation "-DENABLE_QT_TRANSLATION=ON"
  ++ lib.optional (!enableWebService) "-DENABLE_WEB_SERVICE=OFF"
  ++ lib.optional (!enableCubeb) "-DENABLE_CUBEB=OFF"
  ++ lib.optional enableFfmpegAudioDecoder "-DENABLE_FFMPEG_AUDIO_DECODER=ON"
  ++ lib.optional enableFfmpegVideoDumper "-DENABLE_FFMPEG_VIDEO_DUMPER=ON"
  ++ lib.optional useDiscordRichPresence "-DUSE_DISCORD_PRESENCE=ON"
  ++ lib.optional enableFdk "-DENABLE_FDK=ON";

  postPatch =
    let
      branchCaptialized = lib.toUpper (lib.substring 0 1 branch) + lib.substring 1 (-1) branch;
    in
    ''
      # Fix file not found when looking in var/empty instead of opt
      mkdir externals/dynarmic/src/dynarmic/ir/var
      ln -s ../opt externals/dynarmic/src/dynarmic/ir/var/empty

      # Prep compatibilitylist
      ln -s ${compat-list} ./dist/compatibility_list/compatibility_list.json

      # We already know the submodules are present
      substituteInPlace CMakeLists.txt \
        --replace "check_submodules_present()" ""

      # Add versions
      echo 'set(BUILD_FULLNAME "${branchCaptialized} ${version}")' >> CMakeModules/GenerateBuildInfo.cmake

      # Devendoring
      rm -rf externals/zstd externals/libressl
      cp -r ${zstd.src} externals/zstd
      tar xf ${libressl.src} -C externals/
      mv externals/${libressl.name} externals/libressl
      chmod -R a+w externals/zstd
    '';

  # Fixes https://github.com/NixOS/nixpkgs/issues/171173
  postInstall = lib.optionalString (enableCubeb && enableSdl2) ''
    wrapProgram "$out/bin/citra" \
      --prefix LD_LIBRARY_PATH : ${lib.makeLibraryPath cubeb.passthru.backendLibs}
  '';

  meta = {
    homepage = "https://citra-emu.org";
    description = "The ${branch} branch of an open-source emulator for the Ninteno 3DS";
    longDescription = ''
      A Nintendo 3DS Emulator written in C++
      Using the nightly branch is recommended for general usage.
      Using the canary branch is recommended if you would like to try out
      experimental features, with a cost of stability.
    '';
    mainProgram = if enableQt then "citra-qt" else "citra";
    platforms = lib.platforms.linux;
    license = lib.licenses.gpl2Plus;
    maintainers = with lib.maintainers; [
      abbradar
      ashley
      ivar
    ];
  };
}
