{ lib, callPackage, fetchFromGitHub, fetchpatch, makeWrapper, pkg-config, stdenv, makeDesktopItem, copyDesktopItems, # pkg-config dependencies libpng, freetype, fontconfig, xorg, expat, gtk3, libnotify, # other dependencies libclang, openssl, }: let buildMethod = if stdenv.cc.isClang then "CLANG" else "GCC"; uppsrcDependencies = [ expat fontconfig freetype gtk3 libnotify libpng openssl xorg.libX11 xorg.libXdmcp xorg.libXext xorg.libXft xorg.libXinerama xorg.libXrender xorg.libxcb ]; in stdenv.mkDerivation (self: let selfBootstrap = self.overrideAttrs (selfAttrs: superAttrs: { passthru = superAttrs.passthru // { bootstrap = true; }; }); in { pname = "upp"; version = "2025.1"; src = fetchFromGitHub { owner = "ultimatepp"; repo = "ultimatepp"; tag = "2025.1"; hash = "sha256-/hsjQvc5+HxyaytZ5kryhSxbuaAx0eXuH285q7NPiiw="; }; enableParallelBuilding = true; nativeBuildInputs = [ makeWrapper pkg-config ] ++ lib.optional (!self.passthru.bootstrap) copyDesktopItems; buildInputs = uppsrcDependencies ++ lib.optional (!self.passthru.bootstrap) libclang; patches = [ ./no-build-info.patch (fetchpatch { # https://github.com/ultimatepp/ultimatepp/pull/271 url = "https://github.com/ultimatepp/ultimatepp/commit/db5cad68673f9571e6571116e0570e22e3e44fe8.patch"; hash = "sha256-t2PducjE6b5MjDSAIKvEMdHnT8oTGmI073qYuhLFCh0="; }) ]; postPatch = '' patchShebangs ./configure_makefile echo "#define IDE_VERSION \"${self.version}\"" > uppsrc/ide/version.h '' + lib.optionalString (!self.passthru.bootstrap) '' mkdir -p .home export HOME=$(realpath .home) ''; NIX_LDFLAGS = [ "-L${libclang.lib}/lib" "-lclang" ]; NIX_CFLAGS_COMPILE = [ "-DflagLCLANG" ]; UPP_NO_BUILD_INFO = true; buildPhase = '' runHook preBuild '' + ( # Don't build theide in bootstrap to save resources if self.passthru.bootstrap then '' make -f umkMakefile -j $NIX_BUILD_CORES "$makeFlagsArray" '' else '' ${lib.getExe' selfBootstrap "umk"} uppsrc ide ${buildMethod} -rvs "-H$NIX_BUILD_CORES" ${lib.getExe' selfBootstrap "umk"} uppsrc umk ${buildMethod} -rvs "-H$NIX_BUILD_CORES" '') + '' runHook postBuild ''; installPhase = '' runHook preInstall mkdir -p $out/bin '' + (if self.passthru.bootstrap then '' mv ./umk $out/bin/umk '' else '' mv $HOME/.cache/upp.out/umk/${buildMethod}.Main.Shared/umk $out/bin/umk mv $HOME/.cache/upp.out/ide/${buildMethod}.Gui.Main.Shared/ide $out/bin/theide wrapProgram $out/bin/theide \ --unset WAYLAND_DISPLAY mkdir -p $out/share/icons/hicolor/scalable/apps cp uppsrc/ide/icon.svg $out/share/icons/hicolor/scalable/apps/upp-theide.svg for size in 16 32 64 128 256 512; do mkdir -p $out/share/icons/hicolor/''${size}x''${size}/apps cp uppsrc/ide/icon''${size}x''${size}.png $out/share/icons/hicolor/''${size}x''${size}/apps/upp-theide.png done '') + '' runHook postInstall ''; desktopItems = [ (makeDesktopItem { name = "upp-theide"; exec = "theide"; icon = "upp-theide"; desktopName = "TheIDE"; comment = "The U++ Framework IDE"; categories = [ "Development" "IDE" ]; terminal = false; }) ]; passthru = { bootstrap = false; inherit uppsrcDependencies; buildUppPackage = callPackage ./buildUppPackage.nix {}; tests = lib.genAttrs [ "AddressBookXML2" "Bombs" "Days" "SQLApp" "httpcli" ] (examplePackageName: self.passthru.buildUppPackage { pname = examplePackageName; version = self.version; package = examplePackageName; src = self.src; includeUppsrcAssembly = false; buildInputs = self.passthru.uppsrcDependencies; assembly = "examples"; extraAssemblies = [ "uppsrc" ]; }); }; meta = { homepage = "https://www.ultimatepp.org"; description = "C++ cross-platform rapid application development framework"; license = lib.licenses.bsd2; mainProgram = "umk"; }; })