• Build order with gprbuild

    From Gautier write-only address@21:1/5 to All on Tue Feb 28 13:10:59 2023
    When a GNAT project A depends on project B, is there a simple (*) way to make gprbuild build project B before starting the build of A?
    It would be useful when project B generates Ada sources…
    Example:

    with "code_generation.gpr";

    project Main is
    for Source_Dirs use (".", "gen");
    for Object_Dir use "obj";
    for Create_Missing_Dirs use "True"; -- Flips by default the "-p" switch
    for Main use ("main.adb");
    end Main;

    (*) By “simple” I mean simpler than the way described here: https://www.adacore.com/gems/gem-157-gprbuild-and-code-generation

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dmitry A. Kazakov@21:1/5 to Gautier on Tue Feb 28 23:07:48 2023
    On 2023-02-28 22:10, Gautier write-only address wrote:
    When a GNAT project A depends on project B, is there a simple (*) way to make gprbuild build project B before starting the build of A?

    But this is exactly how it works unless B builds a library. I have a
    large number of interdependent projects and everything is built
    automatically as necessary.

    When it comes to a release, I generate the corresponding library
    building projects from a script.

    Another reason not to use libraries during the development phase is that addr2line does not work with dynamic libraries. You must catch exception
    in the program and find where addresses belong to. This cannot be done
    when the program is no more running.

    --
    Regards,
    Dmitry A. Kazakov
    http://www.dmitry-kazakov.de

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Gautier write-only address@21:1/5 to All on Wed Mar 1 12:08:50 2023
    Between normal Ada projects, everything works as you describe (and as expected).
    However, in the special case where project B, instead of transforming Ada files into .o files, transforms other kind of files into Ada files that are with-ed by units of project A, things get off the road: project A doesn't see out-of-date Ada files
    produced by project B.

    Here is a full example. Files are reproduced below (they are meant to land into the same directory).
    Then you do the following commands:

    gprbuild -P fuzzy_gen.gpr
    gprbuild -P code_generation.gpr
    gnatstudio -P main.gpr

    First build launched from GNAT Studio does the following on my machine:

    Compile
    [Ada] main.adb
    [Fuzzy] x789.cfg
    Ada file "fuzzy_x789.adb" is up to date
    [Fuzzy] x456.cfg
    Ada file "fuzzy_x456.adb" is up to date
    [Fuzzy] x123.cfg
    Ada file "fuzzy_x123.adb" is up to date
    [Ada] fuzzy_x123.adb
    [Ada] fuzzy_x456.adb
    [Ada] fuzzy_x789.adb
    Bind
    [gprbind] main.bexch
    [Ada] main.ali
    Link
    [link] main.adb

    Second build has an expected output as well:

    Compile
    [Fuzzy] x789.cfg
    Ada file "fuzzy_x789.adb" is up to date
    [Fuzzy] x456.cfg
    Ada file "fuzzy_x456.adb" is up to date
    [Fuzzy] x123.cfg
    Ada file "fuzzy_x123.adb" is up to date
    gprbuild: "main.exe" up to date

    Now, say you modify x123.cfg and save it.
    Compile
    [Fuzzy] x789.cfg
    Ada file "fuzzy_x789.adb" is up to date
    [Fuzzy] x456.cfg
    Ada file "fuzzy_x456.adb" is up to date
    [Fuzzy] x123.cfg
    Converting "x123.cfg" into "fuzzy_x123.adb"...
    gprbuild: "main.exe" up to date

    That's *not* what I would like: gprbuild did not detect the out-of-date file "fuzzy_x123.adb" in time.
    A second call to gprbuild compiles the changed "fuzzy_x123.adb" and all is well, but it is one step too late.

    The files
    =========

    1) The code generator
    =====================

    fuzzy_gen.gpr:
    -------------

    project Fuzzy_Gen is
    for Object_Dir use "obj";
    for Exec_Dir use "gen";
    for Create_Missing_Dirs use "True";
    for Main use ("fuzzy_gen.adb");
    end Fuzzy_Gen;

    fuzzy_gen.adb:
    -------------

    with Ada.Calendar,
    Ada.Command_Line,
    Ada.Directories,
    Ada.Text_IO;

    procedure Fuzzy_Gen is
    use Ada.Command_Line, Ada.Directories, Ada.Text_IO;

    procedure Convert (arg : String) is
    cfg : constant String := Simple_Name (arg);
    cfg_file_name : constant String := "../" & cfg;
    ada_unit_name : constant String :=
    "fuzzy_" & cfg (cfg'First .. cfg'Last - 4);
    ada_file_name : constant String := ada_unit_name & ".adb";
    cfg_in, ada_out : File_Type;
    use type Ada.Calendar.Time;
    begin
    if Exists (ada_file_name) and then
    Modification_Time (ada_file_name) >=
    Modification_Time (cfg_file_name)
    then
    Put_Line ("Ada file """ & ada_file_name & """ is up to date");
    return;
    end if;
    Put_Line
    ("Converting """ & cfg & """ into """ & ada_file_name & """...");
    Open (cfg_in, In_File, cfg_file_name);
    Create (ada_out, Out_File, ada_file_name);
    Put_Line
    (ada_out, "function " & ada_unit_name & " return String is");
    Put_Line (ada_out, "begin");
    Put_Line (ada_out, " return """ & Get_Line (cfg_in) & """;");
    Put_Line (ada_out, "end;");
    Close (cfg_in);
    Close (ada_out);
    end Convert;


    begin
    if Argument_Count = 0 then
    Put_Line (Current_Error, "config file name missing");
    else
    Convert (Argument (1));
    end if;
    end Fuzzy_Gen;

    2) The project that generates Ada files ("project B") =====================================================

    code_generation.gpr:
    -------------------
    project Code_Generation is

    for Languages use ("Fuzzy");
    for Source_Dirs use (".");
    for Object_Dir use "gen";
    for Objects_Linked ("Fuzzy") use "False";

    package Naming is
    for Body_Suffix ("Fuzzy") use ".cfg";
    end Naming;

    package Compiler is
    for Driver ("Fuzzy") use "fuzzy_gen";
    end Compiler;

    end Code_Generation;

    x123.cfg:
    --------
    123

    x456.cfg:
    --------
    456

    x789.cfg:
    --------
    789

    3) The main project (project A)
    ===============================

    main.gpr:
    --------
    with "code_generation.gpr";

    project Main is
    for Source_Dirs use (".", "gen");
    for Object_Dir use "obj";
    for Create_Missing_Dirs use "True";
    for Main use ("main.adb");
    end Main;

    main.adb:
    --------
    with Ada.Text_IO;
    with Fuzzy_X123,
    Fuzzy_X456,
    Fuzzy_X789;

    procedure Main is
    begin
    Ada.Text_IO.Put
    ("Messages from elsewhere:" &
    " """ & Fuzzy_X123 & '"' &
    " """ & Fuzzy_X456 & '"' &
    " """ & Fuzzy_X789 & '"');
    end;

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From AdaMagica@21:1/5 to All on Thu Mar 2 06:11:58 2023
    I run all the following from the GPS window, not from a terminal (does this matter?).
    I ran this on windows with GNAT CE 2021, one project after the other: OK
    Then I changed one of the .cfg files, the main project did not notice the change as you said.
    I had to run code_generation alone to recreate from tne new cfg file.
    I ran main again: OK
    Then i even deleted one of the generated Ada files and reran main: To my surprise, it did not realize that one Ada file is missing.

    Project view of Gnat Studio for project main:
    Main
    .
    fuzzy_gen.adb
    main.adb
    Code_Generation
    .
    x123.cfg
    x456.cfg
    x789.cfg

    Note that the generated Ada files are not shown, subdirectory gen is not shown. (The > character is used for indentation, the group swallows blanks.)

    Perhaps you have to define some surrogate for the .ali (Ada Library Information) files from the .cfg files additionally.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From AdaMagica@21:1/5 to All on Thu Mar 2 08:54:02 2023
    Project main seems to completely ignore the with clause for code_generation. I added to main
    for Languages use ("Ada", "Fuzzy");
    which results in
    main.gpr:3:9: warning: there are no sources of language "Fuzzy" in this project

    You need to teach gprbuild to look into project code_generation when some Ada files are missing.

    I'm very impressed that you can teach gprbuild a new "language".

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Simon Wright@21:1/5 to Gautier on Thu Mar 2 22:29:37 2023
    Gautier write-only address <gautier_niouzes@hotmail.com> writes:

    When a GNAT project A depends on project B, is there a simple (*) way
    to make gprbuild build project B before starting the build of A? It
    would be useful when project B generates Ada sources…

    I know it's copping out, but I've been using an Alire pre-build action:
    e.g.

    [[actions]]
    type = "pre-build"
    command = ["make", "Simple_Buttons.gen", "Digital_IO.gen"]

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From AdaMagica@21:1/5 to I'm still playing around and have p on Sat Mar 4 11:01:15 2023
    package Compiler is
    for Driver ("Fuzzy") use "fuzzy_gen";
    end Compiler;

    I'm still playing around and have problems with the Driver attribute. The documentation says;
    Driver: single, indexed, case-insensitive index
    Index is a language name. Value is the name of the executable for the compiler of the language.
    However it does not say where the executable is located, how does gprbuild find it?
    I moved fuzzy_gen into another directory and changed accordingly

    for Driver ("Fuzzy") use "path/fuzzy_gen";

    Now I get
    unable to locate fuzzy_gen.

    How do I solve this problem?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From AdaMagica@21:1/5 to AdaMagica on Sun Mar 5 10:35:40 2023
    AdaMagica schrieb am Samstag, 4. März 2023 um 20:01:17 UTC+1:
    for Driver ("Fuzzy") use "path/fuzzy_gen";

    Now I get
    unable to locate fuzzy_gen.

    How do I solve this problem?

    excuse me, I made a mistake in the path. Silly me.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)