flake.nix 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. {
  2. description = "Dev shell for myBookShelf (Lazarus/FPC)";
  3. inputs = {
  4. nixpkgs.url = "github:NixOS/nixpkgs";
  5. flake-utils.url = "github:numtide/flake-utils";
  6. };
  7. outputs = { self, nixpkgs, flake-utils }:
  8. flake-utils.lib.eachDefaultSystem (system:
  9. let
  10. pkgs = import nixpkgs { inherit system; };
  11. lib = pkgs.lib;
  12. lazGtk =
  13. if pkgs ? lazarus-gtk2 then pkgs.lazarus-gtk2
  14. else if pkgs ? lazarus then pkgs.lazarus
  15. else pkgs.lazarus-qt5;
  16. lazQt5 =
  17. if pkgs ? lazarus-qt5 then pkgs.lazarus-qt5
  18. else if pkgs ? lazarus then pkgs.lazarus
  19. else lazGtk;
  20. fpcSrcOpt = if pkgs ? fpcSrc then pkgs.fpcSrc else null;
  21. gtkLibPath = lib.makeLibraryPath [
  22. pkgs.gtk2 pkgs.glib pkgs.pango pkgs.cairo pkgs.gdk-pixbuf pkgs.atk
  23. pkgs.xorg.libX11 pkgs.xorg.libXext pkgs.xorg.libXrender pkgs.xorg.libXrandr
  24. pkgs.xorg.libXinerama pkgs.xorg.libXcursor pkgs.xorg.libXi pkgs.xorg.libXfixes
  25. ];
  26. qtLibPath = lib.makeLibraryPath [ pkgs.qt5.qtbase pkgs.qt5.qtsvg pkgs.qt5.qtx11extras ];
  27. qtPlugins = "${pkgs.qt5.qtbase}/lib/qt-5/plugins";
  28. commonInputs = [
  29. pkgs.fpc
  30. lazGtk
  31. pkgs.poppler_utils
  32. pkgs.unzip
  33. pkgs.openssl
  34. pkgs.cacert
  35. pkgs.gdb
  36. pkgs.pkg-config
  37. pkgs.gtk2
  38. ] ++ lib.optionals (fpcSrcOpt != null) [ fpcSrcOpt ];
  39. commonHook = ''
  40. : "${LCLWidgetType:=gtk2}"
  41. export LCLWidgetType
  42. export SSL_CERT_FILE=${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt
  43. export NIX_SSL_CERT_FILE=$SSL_CERT_FILE
  44. # Find Lazarus IDE binary and expose a 'lazarus' helper
  45. LAZ_BIN=""
  46. for b in lazarus lazarus-ide startlazarus; do
  47. if command -v "$b" >/dev/null 2>&1; then LAZ_BIN="$b"; break; fi
  48. done
  49. lazarus () { "$LAZ_BIN" "$@"; }
  50. export -f lazarus
  51. # Prefer pkgs.fpcSrc if available; else probe inside pkgs.fpc for sources
  52. if [ -d "${if fpcSrcOpt != null then fpcSrcOpt else ""}" ]; then
  53. export FPCSRC="${if fpcSrcOpt != null then fpcSrcOpt else ""}"
  54. else
  55. FPC_OUT=${pkgs.fpc}
  56. for cand in "$FPC_OUT/share/fpcsrc" "$FPC_OUT/lib/fpc"/*/source "$FPC_OUT/share/fpc/source"; do
  57. [ -d "$cand" ] && export FPCSRC="$cand" && break
  58. done
  59. fi
  60. echo
  61. echo "myBookShelf dev shell"
  62. echo " • Widgetset: $LCLWidgetType"
  63. [ -n "$LAZ_BIN" ] && echo " • Lazarus: $LAZ_BIN (helper: 'lazarus')"
  64. [ -n "$FPCSRC" ] && echo " • FPC source dir: $FPCSRC" || echo " • FPC sources: not found (OK for building)"
  65. echo "Commands:"
  66. echo " lazbuild --ws=\$LCLWidgetType src/myBookShelf.lpi"
  67. echo " lazarus &"
  68. echo
  69. '';
  70. # Build the application using lazbuild and wrap for runtime libs
  71. myBookShelfPkg = pkgs.stdenv.mkDerivation rec {
  72. pname = "myBookShelf";
  73. version = "0.1.0";
  74. src = self;
  75. nativeBuildInputs = [
  76. lazGtk
  77. pkgs.fpc
  78. pkgs.pkg-config
  79. pkgs.makeWrapper
  80. ];
  81. # C/GTK libraries needed at link time (provides .pc files and libs)
  82. buildInputs = [
  83. pkgs.gtk2
  84. pkgs.glib
  85. pkgs.pango
  86. pkgs.cairo
  87. pkgs.gdk-pixbuf
  88. pkgs.atk
  89. pkgs.xorg.libX11
  90. pkgs.xorg.libXext
  91. pkgs.xorg.libXrender
  92. pkgs.xorg.libXrandr
  93. pkgs.xorg.libXinerama
  94. pkgs.xorg.libXcursor
  95. pkgs.xorg.libXi
  96. pkgs.xorg.libXfixes
  97. ];
  98. # Lazarus puts the binary next to the .lpr by default
  99. buildPhase = ''
  100. runHook preBuild
  101. export LAZARUS_DIR=${lazGtk}/share/lazarus
  102. export HOME=$TMPDIR
  103. mkdir -p "$HOME/.lazarus"
  104. echo "Using Lazarus at $LAZARUS_DIR"
  105. # Help the linker find GTK libs at build time
  106. export FPCOPT="$FPCOPT -k-L${gtkLibPath}"
  107. export PKG_CONFIG_PATH
  108. lazbuild --lazarusdir="$LAZARUS_DIR" --ws=gtk2 --build-all src/myBookShelf.lpi
  109. runHook postBuild
  110. '';
  111. installPhase = ''
  112. runHook preInstall
  113. mkdir -p $out/bin
  114. # Try the usual locations for the produced binary
  115. if [ -x src/myBookShelf ]; then
  116. cp -v src/myBookShelf $out/bin/myBookShelf
  117. elif [ -x src/mybookshelf ]; then
  118. cp -v src/mybookshelf $out/bin/myBookShelf
  119. elif [ -x src/lib/*/myBookShelf ]; then
  120. cp -v src/lib/*/myBookShelf $out/bin/myBookShelf
  121. else
  122. echo "error: built binary not found" >&2
  123. ls -R src || true
  124. exit 1
  125. fi
  126. # Wrap with GTK2 runtime libraries and CA bundle for TLS
  127. wrapProgram $out/bin/myBookShelf \
  128. --set LCLWidgetType gtk2 \
  129. --set LD_LIBRARY_PATH "${gtkLibPath}:${pkgs.openssl.out}/lib" \
  130. --prefix PATH : ${pkgs.poppler_utils}/bin \
  131. --prefix PATH : ${pkgs.unzip}/bin \
  132. --set SSL_CERT_FILE ${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt \
  133. --set NIX_SSL_CERT_FILE ${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt
  134. runHook postInstall
  135. '';
  136. meta = with lib; {
  137. description = "Personal bookshelf manager (Lazarus/FPC)";
  138. license = licenses.mit;
  139. platforms = platforms.linux;
  140. };
  141. };
  142. in {
  143. packages.default = myBookShelfPkg;
  144. apps.default = {
  145. type = "app";
  146. program = "${myBookShelfPkg}/bin/myBookShelf";
  147. };
  148. devShells = {
  149. default = pkgs.mkShell {
  150. buildInputs = commonInputs;
  151. shellHook = ''
  152. # GTK2 runtime libs so the app runs *inside* the shell
  153. export LD_LIBRARY_PATH="${gtkLibPath}:${pkgs.openssl.out}/lib:$LD_LIBRARY_PATH"
  154. ${commonHook}
  155. '';
  156. };
  157. qt5 = pkgs.mkShell {
  158. buildInputs = commonInputs ++ [ lazQt5 pkgs.qt5.qtbase pkgs.qt5.qttools pkgs.libqt5pas ];
  159. shellHook = ''
  160. export LCLWidgetType=qt5
  161. # Qt runtime libs + plugin search path
  162. export FPCOPT="$FPCOPT -Fl${pkgs.libqt5pas}/lib"
  163. export LD_LIBRARY_PATH="${qtLibPath}:${pkgs.libqt5pas}/lib:${pkgs.openssl.out}/lib:$LD_LIBRARY_PATH"
  164. export QT_PLUGIN_PATH="${qtPlugins}"
  165. ${commonHook}
  166. '';
  167. };
  168. };
  169. });
  170. }