Re: Lancement de script à la fin de la c ompilation avec Gprbuild dans GNATStudio

Stéphane Rivière via Ada-france <[email protected]> Tue, 14 Dec 2021 17:48:13 +0100
Newsgroups gmane.comp.lang.ada.france
Organization La Maison
Message-ID <[email protected]>
Déterrage de thread.

Rappel du contexte : développement de programmes Ada pour serveurs bien
lointains. Les binaires ne peuvent être testés sur la station graphique
locale (les ressources n'y sont pas). Tenté d'utiliser les fonctions
"distantes" de GnatStudio sans succès.

Builder directement sur le serveur tout en ayant GnatStudio est donc
impossible et forcer le build de l'exe à travers un mount sshfs provoque
un build très lent (> 60s). Il serait préférable de builder en local
puis de copier le binaire créé.


Grâce à une très bonne idée de David Sauvage, et à son excellent
utilitaire Gnatgpr, j'ai dérivé, de son script bash (proposé dans cette
thread), un micro programme en Ada.


La nouveauté consiste surtout en la récupération de nouvelles variables
via des paramètres -X sur la ligne de build, pour télécommander le
programme sans quitter GnatStudio.


Ce programme (Gpb) sort un binaire nommé gprbuild. Après avoir renommé
le vrai gprbuild en gprbuild_exe, on y colle ce gprbuild maison dans le
même répertoire /bin de l'install GnatStudio.

Ce bricolage à https://www.la-rache.com est juste du à une limitation de
GnatStudio qui ne propose qu'un choix binaire entre Gnatmake et
Gprbuild, au lieu de proposer une zone libre où on mettrait le builder
de son choix.


Si on ne fait rien de spécial, la seule différence est qu'un ding sympa
va ponctuer la fin du build. Ce ding est désactivable par le paramètre
-XGpb_Beep=off|ansi|[bell] ansi=console beep, bell=neat paplay bell
(default)

Mais si on pose le paramètre
[email protected]:/usr/local/bin, à la fin du build
(premier ding), une copie scp du binaire vas être faite vers
host.domain.tld:/usr/local/bin avec un second ding à la fin du transfert
pour indiquer que le programme est prêt sur le server distant.


En pratique, dans la console GnatStudio :

*** SANS PARAMETRES PARTICULIERS ***

Build local (par défaut)

GnatStudio Build All (with modified F9 shortcut)

%builder -XGpb_Build=Debug -d %eL -P%PP %config %autoconf %X -s
gprbuild -XGpb_Build=Debug -d
-P/home/sr/Seafile/Sowebio/informatique/github/gpb/gpb.gpr -s

------------------
gprbuild -XGpb_Build=Debug -d
-P/home/sr/Seafile/Sowebio/informatique/github/gpb/gpb.gpr
-Xgpb_Build=Debug -s

Gprbuild stub for GnatStudio - gprbuild v0.1
Copyright (C) Sowebio SARL 2020-2021, according to GPLv3.

Gprbuild_Parameters: -XGpb_Build=Debug -d
-P/home/sr/Seafile/Sowebio/informatique/github/gpb/gpb.gpr
-Xgpb_Build=Debug -s
Gprbuild_Project: /home/sr/Seafile/Sowebio/informatique/github/gpb/gpb.gpr
Gprbuild_Gpb_Scp:
Gprbuild_Gpb_Beep: bell

Compile
   [Ada]          gpb.adb
   [Ada]          v20.adb
   [Ada]          v20-fls.adb
   [Ada]          v20-log.adb
   [Ada]          v20-prg.adb
   [Ada]          v20-sys.adb
   [Ada]          v20-tio.adb
   [Ada]          v20-vst.adb
   [Ada]          gnatcoll.ads
   [Ada]          gnatcoll-memory.adb
Bind
   [gprbind]      gpb.bexch
   [Ada]          gpb.ali
Link
   [link]         gpb.adb

Gprbuild_Binary_Orig:
/home/sr/Seafile/Sowebio/informatique/github/gpb/bin/gprbuild

[2021-12-14 14:51:08] process terminated successfully, elapsed time: 03.79s
Output saved in
/home/sr/Seafile/Sowebio/informatique/github/gpb/obj/debug/messages.txt
------------------


*** AVEC PARAMETRE POUR COPIE SCP ***

Build local puis copie SCP vers serveur distant

GnatStudio Build All (with modified F9 shortcut)

%builder -XGpb_Build=Debug [email protected]:/usr/local/bin
-d %eL -P%PP %config %autoconf %X -s
gprbuild -XGpb_Build=Debug [email protected]:/usr/local/bin
-d -P/home/sr/Seafile/Sowebio/informatique/github/gpb/gpb.gpr -s

------------------
gprbuild -XGpb_Build=Debug [email protected]:/usr/local/bin
-d -P/home/sr/Seafile/Sowebio/informatique/github/gpb/gpb.gpr
-Xgpb_Build=Debug -s

Gprbuild stub for GnatStudio - gprbuild v0.1
Copyright (C) Sowebio SARL 2020-2021, according to GPLv3.

Gprbuild_Parameters: -XGpb_Build=Debug -d
-P/home/sr/Seafile/Sowebio/informatique/github/gpb/gpb.gpr
-Xgpb_Build=Debug -s
Gprbuild_Project: /home/sr/Seafile/Sowebio/informatique/github/gpb/gpb.gpr
Gprbuild_Gpb_Scp: [email protected]:/usr/local/bin
Gprbuild_Gpb_Beep: bell

Compile
   [Ada]          gpb.adb
   [Ada]          v20.adb
   [Ada]          v20-fls.adb
   [Ada]          v20-log.adb
   [Ada]          v20-prg.adb
   [Ada]          v20-sys.adb
   [Ada]          v20-tio.adb
   [Ada]          v20-vst.adb
   [Ada]          gnatcoll.ads
   [Ada]          gnatcoll-memory.adb
Bind
   [gprbind]      gpb.bexch
   [Ada]          gpb.ali
Link
   [link]         gpb.adb

Gprbuild_Binary_Orig:
/home/sr/Seafile/Sowebio/informatique/github/gpb/bin/gprbuild
Gprbuild_Binary_Dest: [email protected]:/usr/local/bin/gprbuild

SCP copy (2638Kb) in progress...
SCP copy (15s @ 175Kbps) successful.

[2021-12-14 14:52:25] process terminated successfully, elapsed time: 16.32s
Output saved in
/home/sr/Seafile/Sowebio/informatique/github/gpb/obj/debug/messages.txt
------------------

175 Kbps... oui, c'est pas rapide, pas encore la fibre et en plus à
travers un VPN... (non obligatoire mais c'est juste le contexte).


La commutation "copie locale/copie distante" se fait sans quitter
GnatStudio, à partir de la fenêtre [Build All] puis en choisissant, dans
la liste "drop down" en bas de la fenêtre, la bonne string de build,
puis cliquer sur [Execute].

Ça sera donc le choix, dans la list "drop down", entre (par exemple) :

%builder -XGpb_Build=Debug -d %eL -P%PP %config %autoconf %X -s

%builder -XGpb_Build=Debug [email protected]:/usr/local/bin
-d %eL -P%PP %config %autoconf %X -s


Là, on s'est focalisé sur SCP mais on peut bien sûr étendre les
possibilités en fonction des besoins, voire cumuler tout un tas de
fonctionnalités avec de nouvelles variables...



Le source ci-dessous (je peux poser le tout - avec le .gpr - sur notre
github si ça intéresse quelqu'un). On y trouve aussi dans le header
comment builder Gnatgpr en quelques lignes. v20 est dispo sur le github
aussi.

------------------------------------------------------------------------------
--  ▖▖▄▖▄▖
--  ▌▌▄▌▛▌
--  ▚▘▙▖█▌
--
--  @file      gpb.adb
--  @copyright See authors list below and v20.copyrights file
--  @licence   GPL v3
--  @encoding  UTF-8
------------------------------------------------------------------------------
--  @summary
--  Network copy of the current binary project after build with bell(s)
--  From an idea of David Sauvage - [email protected], author
--  of (among other) https://gitlab.com/adalabs/gnatgpr
--
--  @description
--
--  Ending a successful build with a sound. If the -XScp_Path=
--  parameter is set, copies the binary accordingly to the SCP
destination path.
--  A second sound will be emitted after the end of the SCP copy (useful
with
--  slow links).
--
--  Example of build string (with a ready SSH key):
--  %builder -Xaide_Build=Debug
[email protected]:/usr/local/bin -d %eL -P%PP %config
%autoconf %X -s
--
--  Which is translated as follows:
--  gprbuild -Xaide_Build=Debug
[email protected]:/usr/local/bin -d
-P/home/sr/Seafile/Sowebio/informatique/github/gpb/gpb.gpr -s
--
--  Extra option: -XGpb_Beep=off|ansi|[bell] ansi=console beep,
bell=neat bell through pulseaudio (default).
--
--  HowTo
--  Rename ~/gnat-20xx/bin/gprbuild to gprbuild_exe
--  Copy ~/gpb/bin/gprbuild to ~/gnat-20xx/bin
--
--  Dependencies : gnatgpr (come as standard with AIDE), build reminder:
--  cd ~/opt/gnat-2021-downloads
--  git clone https://gitlab.com/adalabs/gnatgpr
--  cd gnatgpr
--  gprbuild -d -Pgnatgpr-bin.gpr -XLIBRARY_TYPE=static
-XLANGKIT_SUPPORT_LIBRARY_TYPE=static \
--  -XLIBADALANG_LIBRARY_TYPE=static -XGPR_BUILD=static
-XXMLADA_BUILD=static \
--  -XGNATCOLL_CORE_BUILD=static -XGNATCOLL_BUILD=static -XEnv=Production -s
--  cp binaries/gnatgpr ~/opt/gnat-2021/bin
--
--  @authors
--  Stéphane Rivière - sr - [email protected]
--
--  @versions
--  20211213 - 0.1 - sr - initial release
------------------------------------------------------------------------------

with Ada.Calendar;
with Ada.Command_Line;

with v20; use v20;
with v20.Fls;
with v20.Log;
with v20.Prg;
with v20.Tio;
with v20.Sys;
with v20.Vst; use v20.Vst;

procedure Gpb is

   package ACL renames Ada.Command_Line;

   Gprbuild_Parameters : VString := +"";
   Gprbuild_Project : VString := +"";
   Gprbuild_Gpb_Scp : VString := +"";
   Gprbuild_Gpb_Beep : VString := +"bell";
   Gprbuild_Binary_Orig : VString := +"";
   Gprbuild_Binary_Dest : VString := +"";

   SE_Result : Integer := 0;

   Start_Time_SCP : Ada.Calendar.Time;

   procedure Beep_Console is
   begin
      if (Gprbuild_Gpb_Beep = "ansi") then
         Tio.Beep;
      elsif (Gprbuild_Gpb_Beep = "bell") then
         -- Pulseaudio paplay & freedesktop sounds come as standard on
Ubuntu 18.04 LTS
         Sys.Shell_Execute ( +"paplay
/usr/share/sounds/freedesktop/stereo/complete.oga");
      end if;
   end Beep_Console;

begin

   Sys.Set_Memory_Monitor (True);

   Prg.Set_Version (0, 1);

   Log.Line;
   Log.Msg (+"Gprbuild stub for GnatStudio - " & Prg.Get_Version);
   Log.Msg (+"Copyright (C) Sowebio SARL 2020-2021, according to GPLv3.");
   Log.Line;


----------------------------------------------------------------------------
   --  Get parameters, extract and/or remove some specials ones

----------------------------------------------------------------------------

   for A in 1 .. ACL.Argument_Count loop
      if (Vst.Index ( To_VString (ACL.Argument (A)), +"-P") = 1) then
         Gprbuild_Project := Slice ( To_VString (ACL.Argument (A)), 3,
Vst.Length (To_VString (ACL.Argument (A))) );
         Gprbuild_Parameters := Gprbuild_Parameters & ACL.Argument (A) &
" ";
      elsif (Vst.Index ( To_VString (ACL.Argument (A)), +"-XGpb_Scp=") =
1) then
         Gprbuild_Gpb_Scp := Slice ( To_VString (ACL.Argument (A)), 11,
Vst.Length (To_VString (ACL.Argument (A))) );
      elsif (Vst.Index ( To_VString (ACL.Argument (A)), +"-XGpb_Beep=")
= 1) then
         Gprbuild_Gpb_Beep := Slice ( To_VString (ACL.Argument (A)), 12,
Vst.Length (To_VString (ACL.Argument (A))) );
      else
         Gprbuild_Parameters := Gprbuild_Parameters & ACL.Argument (A) &
" ";
      end if;
   end loop;

   Log.Set_Debug (True);

   Log.Dbg ("Gprbuild_Parameters: " & Gprbuild_Parameters);
   Log.Dbg ("Gprbuild_Project: " & Gprbuild_Project);
   Log.Dbg ("Gprbuild_Gpb_Scp: " & Gprbuild_Gpb_Scp);
   Log.Dbg ("Gprbuild_Gpb_Beep: " & Gprbuild_Gpb_Beep);
   Log.Line;


----------------------------------------------------------------------------
   --  Build binary by calling the real gprbuild

----------------------------------------------------------------------------

   Sys.Shell_Execute ("gprbuild_exe " & Gprbuild_Parameters, SE_Result);
   if SE_Result = 0 then

      Beep_Console;

      if not ((Index ( Gprbuild_Parameters, "-c") > 0) or
              (Index ( Gprbuild_Parameters, "-u") > 0)) then

         Sys.Shell_Execute (+"gnatgpr -b " & Gprbuild_Project,
SE_Result, Gprbuild_Binary_Orig);
         if SE_Result = 0 then

            Log.Line;
            Log.Dbg ("Gprbuild_Binary_Orig: " & Gprbuild_Binary_Orig);

            if not (Vst.Empty (Gprbuild_Binary_Orig)) then

               if not (Vst.Empty (Gprbuild_Gpb_Scp)) then

                  Gprbuild_Binary_Dest := Gprbuild_Gpb_Scp & "/" &
Tail_After_Match (Gprbuild_Binary_Orig, '/');
                  Log.Dbg ("Gprbuild_Binary_Dest: " & Gprbuild_Binary_Dest);
                  Log.Line;


----------------------------------------------------------------------------
   --  Scp copy if needed

----------------------------------------------------------------------------

                  Log.Dbg ("SCP copy (" & To_VString (Fls.File_Size
(Gprbuild_Binary_Orig)/1000) & "Kb) in progress...");
                  Start_Time_SCP := Ada.Calendar.Clock;

                  Sys.Shell_Execute ("scp -q " & Gprbuild_Binary_Orig &
" " & Gprbuild_Gpb_Scp);
                  if SE_Result = 0 then
                     Log.Dbg ("SCP copy (" & To_VString
(Prg.Duration_Stamp_Seconds (Start_Time_SCP)) & "s @ " &
                     To_VString ((Fls.File_Size (Gprbuild_Binary_Orig) /
Prg.Duration_Stamp_Seconds (Start_Time_SCP))/1000) &
                     "Kbps) successful.");
                     Beep_Console;
                  end if;

               end if;
            end if;

            Log.Line;

         end if;
      end if;
   end if;

exception

   --  Runtime errors
   when Error : others =>
      v20.Exception_Handling (Error);

-----------------------------------------------------------------------------
end Gpb;
-----------------------------------------------------------------------------

-- 
Stéphane Rivière
Ile d'Oléron - France
_______________________________________________
Ada-france mailing list
[email protected]
https://mail.ada-france.org/cgi-bin/mailman/listinfo/ada-france