Création de mon premier paquet Nix

Hello à tous les Nixiens francophone !

Je suis un dev (webdev à la base mais branché surtout par les langages python et Rust) et je cherche à packager mes softs pour nix.

Mon premier essai se ferais pour https://github.com/mothsART/fluxboxlauncher que je considère comme un cas d’école : peu de code, pas de “compilation” et très peu de dépendances.

J’ai créé le fichier default.nix suivant :

{ lib, python, buildPythonPackage, pygtk }:

buildPythonPackage rec {
  pname = "fluxoblauncher";
  format = "other";
  version = "0.1";

  buildInputs = [ python pygtk ];

  meta = with lib; {
    description = "Fluxboxlauncher";
    homepage = "https://github.com/mothsART/fluxboxlauncher";
    maintainers = with maintainers; [ mothsart ];
    license = licenses.bsdOriginal;
    platforms = platforms.unix;
  };
}

et ça me renvoi :

nix-build -A fluxboxlauncher
error: cannot auto-call a function that has an argument without a default value ('lib')

Merci d’avance

Sorry to reply in English, but I cant understand French, and therefore would be unable to check correctness of my translator.

Basically you need to provide defaults for your arguments:

{
  pkgs ? import <nixpkgs> {},
  lib ? pkgs.lib,
  # and so on
  ...
}:

# remaining default.nix

Also the buildPythonPackage builder is meant for libraries. If your project creates an executable then buildPythonApplication is probably more appropriate.

Though as far as I know, both expect a setup.py to be available.

Nix ne sais pas d’ou viennent les arguments comme lib.

Une maniere de faire c’est d’utiliser nixpkgs.callPackage pour remplire les arguments pour toi. Par example en creeant un deuxieme fichier build.nix:

let pkgs = import <nixpkgs> {}; in
pkgs.callPackage ./. {}

Et apres au lieu de lancer nix-build default.nix tu lances nix-build build.nix.

1 Like

Thanks @NobbZ and @zimbatm

Grâce à vous j’ai pu avancer en concaténant vos réponses : voir https://github.com/mothsart/fluxboxlauncher

J’ai désormais un autre soucis :

nix-build built.nix
...
  File "/build/fluxboxlauncher/lib/dialog.py", line 1, in <module>
    import gi
ModuleNotFoundError: No module named 'gi'

Donc, pas d’accès à la lib “gobject-introspection” si je comprend bien.
J’ai un peu de mal à savoir si il manque quelque chose dans mon fichier .nix ou dans mon setup.py.

Est-ce qu’il ne manque pas un setup.py dans le projet?

Voila l’output que j’ai quand j’essaie de repoduire ton probleme:

Executing setuptoolsBuildPhase
Traceback (most recent call last):
  File "nix_run_setup", line 8, in <module>
    exec(compile(getattr(tokenize, 'open', open)(__file__).read().replace('\\r\\n', '\\n'), __file__, 'exec'))
  File "/nix/store/s7vw8y02cqzx8bnjxl4bkhlnwvz6ws1s-python3-3.7.6/lib/python3.7/tokenize.py", line 447, in open
    buffer = _builtin_open(filename, 'rb')
FileNotFoundError: [Errno 2] No such file or directory: 'setup.py'
builder for '/nix/store/7fqjns2ch4zvjill55my5wnp5rm85lqy-fluxboxlauncher-0.1.drv' failed with exit code 1
error: build of '/nix/store/7fqjns2ch4zvjill55my5wnp5rm85lqy-fluxboxlauncher-0.1.drv' failed

Si, j’ai oublié de le push, désolé. (c’est fait désormais)

Voila j’ai fixer ton build: fix the nix build by zimbatm · Pull Request #1 · mothsART/fluxboxlauncher · GitHub

Ce que j’ai fait c’est chercher gobject-introspection dans nixpkgs pour trouver d’autres exemples.

Il manque un binaire dans l’output, je crois qu’il faut definire l’entry-point dans setup.py pour qu’il en genere un. Essaies de fixer ca, c’est possible que tu aies plus de problemes de build apres.

Alors, je gère désormais bien mon entrypoint mais j’ai un message lors du lancement du soft :

<class 'ValueError'> Namespace Gtk not available()

ça se lance bien avec

nix-shell --run fluxboxlauncher

mais pas avec

nix run -c fluxboxlauncher

Sorry for another English reply (I could do German, si vous préférez ça). I can mostly follow along with what you’re saying, but my French is way too rusty to answer.

The reason why this works with nix-shell but doesn’t work with nix run is that nix-shell sets the PYTHONPATH environment variable. I couldn’t come up with a quick fix, though. Excuse-moi.

2 Likes

thanks @ajs124 for your answer.

Je cherche, parallèlement à ce soucis de PYTHONPATH à utiliser le fichier .desktop de mon app.
Quel est la bonne pratique. (je vois des exemples avec makeDesktopItem mais ça semble être destiné à des paquets qui n’ont pas de .desktop)

Salut j’ai une petite question sur votre fichier nix fix the nix build by zimbatm · Pull Request #1 · mothsART/fluxboxlauncher · GitHub . En fait, tous les fichiers nix que j’ai fait pour l’instant ne sont pas des fonction {a,b,c, ...} : { definitionDeMaDerivation } , mais des sets plus simple du style with import <nixpkgs> (); { definitionDeMaDerivation } et qui va contenir buildInputs etc. Dans votre cas les paramètres a b et c sont par expemple lib, python3, gtk3. Quel est le mechanisme qui va fournir des valeur à ces variables pour votre fonction, (quand moi je n’ai pas besoin parce que c’est déjà une dérivation ce que contient mon fichier default.nix)? On peut passer des variables avec import, mais avec nix-shell ou nix-build ?

Quand tu apelles nix-build sur un fichier il evaluate le code nix en premier et essaie de trouver une ou plusieur derivations a construire. Tant que le code nix retourne des fonctions, nix vas appeler la fonction avec un attrset vide.

{ name ? "foo" }: {}: {}: builtins.derivation { name = name; system = "..."; builder = "..."; }

par exemple ici, il vas appeler les 3 fonctions, name prends la valeur par defaut. Apres c’est possible d’appeler nix-build -argstr name bar pour passer un autre argument. Donc ca c’est pour les entry-point, le fichiers nix sur lequels tu vas appeler nix-build dessus. Dans nixpkgs il n’y a que un-seul fichier sur lequel tu peux appeler nix-build, c’est celui qui est tout en haut du repertoire.

Apres les autres default.nix de nixpkgs sont construits differemment. Ils sont importer avec pkgs.callPackage qui vas remplire tous les arguments avec des valeurs qui viennent de pkgs, et attachers a l’attribute set qui vas etre retourner. Par exemple pour le package hello, l’attribut c’est hello et tu peux le construire en appelant nix-build -A hello sur le default.nix tout en haut. Apres c’est aussi possible de remplire les arguments a la main en appelant import et appelant la fonction qui est retournee avec les argument. Ca marche aussi est c’est plus explicite, ca demande juste de tapper un peu plus de characteres.

1 Like

Alors, bonne nouvelle : j’ai résolu mes soucis de PYTHONPATH.
J’ai changé le "buildPythonApplication rec " en “python3.pkgs.buildPythonApplication rec”.

Après m’être battu avec la maj de mon .deb, j’aimerais désormais gérer l’i18n.
J’utilise mon setup.py à bon escient pour passer les fichier dans /nix/store/{hash}/share/locale/fr/LC_MESSAGES/fluxboxlauncher.mo mais je suis pas certain de savoir comment passer le bon chemin dans mon app.

Normalement, je devrais pas toucher au code pour packager…

Pour les locales, j’utilise au final :

    postPatch = ''
    substituteInPlace flxl/lib/i18n.py \
      --replace "/usr" "$out"
  '';

C’est peut-être pas la meilleur solution mais ça marche !

1 Like

Alors, en me plongeant dans les sources de Guake, je me suis rendu compte qu’il y avait possibilité d’avoir un chemin relatif vers les locales et donc supprimer le patch existant.
Ca m’a aussi permis de débusquer un soucis sur les locales. Du coup, je propose mon paquet sur nixpkgs : https://github.com/NixOS/nixpkgs/pull/78492

Alors, je pensais être arriver au bout mais non : je me confronte à un autre soucis.
on soft en python appel l’utilitaire “rox” : https://github.com/mothsART/fluxboxlauncher/blob/20955f96062a1ff9a8772121925fc67f7f4a59d4/flxl/main.py#L152
J’ai bien trouvé comment l’installer (il s’appelle rox-filer) mais comment corriger mon code python pour qu’il marche aussi bien sur nix que sur un autre système tel que debian ?
Même embarras pour /usr/share/applications : sur nixos, y’a un rép qui centraliser les .desktop ?

En définitive, j’ai eu une proposition intéressante sur le chan IRC que j’ai appliqué :sweat_smile:

remplacer rox par GtkAppChooserDialog

Hosted by Flying Circus.