โŒ About FreshRSS

Normal view

There are new articles available, click to refresh the page.
Before yesterdayNewest questions tagged ada - Stack Overflow

Gcc 13.1.0 macOS Sonoma not compiling Ada or any languages on Intel or M1 Macs

I just upgraded to macOS Sonoma on my Intel and M1 Macs, and Gcc and Alire cannot compile simple Ada programs or any others so I suspect it's a compatibility issue. I am using Gcc 13.1.0 aarch64 and x86_64 on the MacBook Pro/Air M1 and MacBook Pro Core i9 respectively. The error I see among others is "-macosx_version_min has been renamed to -macosx_version_min" also: "exited with code 4" Since I cannot compile Ada programs which is most important, is there a workaround or hack until there are upgraded versions to fix it? The same errors are present on both the Intel and M1 Macs, and I had no issues at all on macOS Ventura.

I tried using Gcc 13.1.0 aarch64 and x86_64 on my MacBook M1s and only the x86_64 version on my Intel MacBook Pro Core i9. I tried using Alire with it's native compilers on both type Macs and its matching gprbuild version. The same errors are present using the terminal editing with "nano" and compiling with "gnatmake" or Gnat Studio using the Gcc 13.1.0 toolchain. It obviously is a compatibility issue between Gcc/Alire and macOS Sonoma. It's not just Ada "Hello, World!", but C and C++ "Hello, World!"

Unable to link C source code with Ada static library (Error: libnewapi.a(unit1.o):unit1.adb:undefined reference to `__gnat_rcheck_CE_Overflow_Check')

I want to integrate my Ada static library (libnewapi.a) with my C source code (main.c). I do not have any issues generating the static library but when trying to link it with main.c. I get the below link error, libnewapi.a(unit1.o):unit1.adb:(.text+0x31): undefined reference to `__gnat_rcheck_CE_Overflow_Check' I am not using this reference in my main.c not in any of my Ada files. I do not know why this reference was added automatically. It is crucial that I need to link my main.c using a static Ada library for my project. I do not know where I am going wrong. Help is much appreciated. Thanks!

I am generating libnewapi.a using a GPR as below,

    -- ada_gen_a.gpr
    project ada_gen_a is
       for Languages use ("Ada");
       for Source_Dirs use ("./");
       for Library_Name use "newapi";
       for Library_Dir use "./Lib/";
       for Library_Kind use "static";

       package Naming is
          for Spec_Suffix ("ada") use ".ads";
          for Body_Suffix ("ada") use ".adb";
          for Separate_Suffix use ".adb";
          for Dot_Replacement use ".";
          for Casing use "mixedcase";
       end Naming;

       Ada_Switches := ("-gnato", "-O2");

       package Compiler is
          for Default_Switches ("ada") use Ada_Switches;
       end Compiler;

       package Binder is
          for Default_Switches ("Ada") use ("-n","-Lada");
       end Binder;
    end ada_gen_a;

Ada Sourcefiles:

    --  unit1.ads
    package Unit1 is
       function Add (A, B : Integer) return Integer;
       pragma Export (C, Add, "ada_add");
    end Unit1;
    -- unit1.adb
    package body Unit1 is
       function Add (A, B : Integer) return Integer is
       begin
          return A + B;
       end Add;
    end Unit1;

C Source File:

    /* main.c */
    #include <stdio.h>
    extern void ada_add (void);
    int main (int argc, char *argv[])
    {
       int a = 21, b = 7, c = 0;
       printf ("%d", a);
       printf ("%d", b);
       c = ada_add(a,b);
       printf ("%d", c);
       return 0;
    }

I am using the below GPR to link the above main.c with the Ada static library generated using ada_gen_a.gpr.

    -- Ada_Use_A.gpr
    with "newapi.gpr";
    project Ada_Use_A is

       for Languages use ("C");
       for Source_Dirs use (".");
       for Source_Files use ("main.c");

       package Naming is
          for Casing use "mixedcase";
       end Naming;

       Ada_Switches := ("-gnato", "-O2");

       package Compiler is
          for Default_Switches ("C") use ("-O2", "-Wall");
          for Default_Switches ("Ada") use Ada_Switches;
       end Compiler;

       package Binder is
          for Default_Switches ("Ada") use ("-n","-Lada");
       end Binder;

       for Main use ("main.c");

    end Ada_Use_A;
    -- newapi.gpr
    project newapi is
       for Externally_Built use "true";
       for Source_Files use ();
       for Library_Dir use ".\lib\";
       for Library_Name use "newapi";
       for Library_Kind use "static";
    end newapi;

When I try to build the Ada_Use_A.gpr GPS I get the below linker error, libnewapi.a(unit1.o):unit1.adb:(.text+0x31): undefined reference to __gnat_rcheck_CE_Overflow_Check' gprbuild: link of main.c failed`

Stack corruption in Ada C binding to OpenGL function

I'm using SDL to retrieve the address of the function. That much seems to be working, since I'm using the same subprogram that's working for all my other function calls.

Here are all the relevant code snippits in the spec:

type GLenum is new Uint32;

subtype glTexImage2D_Target is GLenum with Static_Predicate => glTexImage2D_Target in GL_TEXTURE_2D | GL_TEXTURE_RECTANGLE | GL_PROXY_TEXTURE_RECTANGLE;
subtype glTexImage2D_Dtype is GLenum with Static_Predicate => glTexImage2D_Dtype in GL_BYTE | GL_UNSIGNED_BYTE;
subtype glTexImage2D_InternalFormat is GLenum with Static_Predicate => glTexImage2D_InternalFormat in GL_DEPTH_COMPONENT | GL_DEPTH_STENCIL | GL_RED | GL_RG | GL_RGB | GL_RGBA;
subtype glTexImage2D_Format is GLenum with Static_Predicate => glTexImage2D_Format in GL_RED | GL_RG | GL_RGB | GL_BGR | GL_RGBA | GL_BGRA | GL_RED_INTEGER | GL_RG_INTEGER | GL_RGB_INTEGER | GL_BGR_INTEGER | GL_RGBA_INTEGER | GL_BGRA_INTEGER | GL_STENCIL_INDEX | GL_DEPTH_COMPONENT | GL_DEPTH_STENCIL;

procedure glTexImage2D(target : glTexImage2D_Target; level : Integer; internalFormat : glTexImage2D_InternalFormat; width : Integer; height : Integer; format : glTexImage2D_Format; dtype : glTexImage2D_Dtype; pixels : System.Address) with Pre => (target /= GL_TEXTURE_RECTANGLE and target /= GL_PROXY_TEXTURE_RECTANGLE) or Level = 0;

procedure Set_OpenGL_Subprogram_Address(Addr : in out System.Address; Name : String);

glTexImage2D_C_Address : System.Address := System.Null_Address;

Could_Not_Load_OpenGL_Subprogram : exception;

And here are the relevant snippits in the body:

procedure glTexImage2D(target : glTexImage2D_Target; level : Integer; internalFormat : glTexImage2D_InternalFormat; width : Integer; height : Integer; format : glTexImage2D_Format; dtype : glTexImage2D_Dtype; pixels : System.Address) is
begin
    Set_OpenGL_Subprogram_Address(glTexImage2D_C_Address, "glTexImage2D");
    declare
        procedure glTexImage2D_C(target : GLenum; level : GLint; internalFormat : GLint; width : GLsizei; height : GLsizei; border : GLint; format : GLenum; dtype : GLenum; data : System.Address)
        with Import, Convention => Stdcall, Address => glTexImage2D_C_Address;
    begin
        glTexImage2D_C(GLenum(target), GLint(level), GLint(internalFormat), GLsizei(width), GLsizei(height), GLint'(0), GLenum(format), GLenum(dtype), pixels);
    end;
end glTexImage2D;

--This seems to work... but here it is just in case.
procedure Set_OpenGL_Subprogram_Address(Addr : in out System.Address; Name : String) is
begin
    if Addr = System.Null_Address then
        Addr := SDL_GL_GetProcAddress(Value(New_String(Name)));
        if Addr = System.Null_Address then
            raise Could_Not_Load_OpenGL_Subprogram with Name;
        end if;
    end if;
end Set_OpenGL_Subprogram_Address;

Finally, the pixels I'm passing in is an address indicating an object of type:

type Uc_Array is array(Integer range <>) of aliased Interfaces.C.unsigned_char;

The stack is being corrupted on the call to glTexImage2D_C. I discovered this by using gdb:

enter image description here

Here you can see the parameters I'm passing as well; target 3553, level 0, internalformat 6408, width 63, height 63, format 6408, dtype 5121, non-zero pixels address. The subprogram address is being set to a non-zero value. But after the call to glTexImage2D_C, the value of $sp (the stack pointer) has increased by 16#24#.

I've tried adjusting the height and width I pass to glTexImage2D_C, both to 10 and both to 1000, just to see if giving it more (or less) buffer prevents stack corruption, but in every case, the stack pointer is different before and after the procedure call.

I'm hoping this is a simple matter of an incorrect datatype or something... Here's the prototype of glTexImage2D on the OpenGL side:

void glTexImage2D(  GLenum target,
    GLint level,
    GLint internalformat,
    GLsizei width,
    GLsizei height,
    GLint border,
    GLenum format,
    GLenum type,
    const void * data);

(As a final note, I do intend to clean up the awkward lazy loading tactic you see above, if I can ever get this to actually work. For now I'm leaving it this way so I can eliminate the chance of trying to call a function that hasn't been loaded yet, while I'm still trying to debug the call itself. The tactic of using a nested procedure declared inside a declare...begin...end block is working for other OpenGL functions.)

How to pass complex data types, like records between Ada and C via a DLL?

I am trying to get Ada code to compile to a DLL to be callable in C. So far I have managed to get this to work for simple types such as integers but i'm having difficulty with more complex types such as array's or records/structs.

Below is my Ada code for an record/struct. It is a dynamic library which i compile to a dll using the command "gprbuild -P ./math.gpr -p":

person.adb
with Interfaces.C; use Interfaces.C;

package body Person is

   function Set_Age_To_Five(P : Person_Record) return Person_Record is
      Result : Person_Record;
   begin
      Result := P;
      Result.Age := 5;
      return Result;
   end Set_Age_To_Five;

end Person;

person.ads

with Interfaces.C; use Interfaces.C;

package Person is

   type Person_Record is record
      Name    : String(1 .. 100);
      Age     : Interfaces.C.int;
      Address : String(1 .. 100);
   end record with Convention => C_Pass_By_Copy;

   function Set_Age_To_Five(P : Person_Record) return Person_Record;
   pragma Export (C, Set_Age_To_Five, "Set_Age_To_Five");

end Person;

math.gpr

library project Math is
    for Languages use ("Ada");
    for Library_Name use "Person";
    for Source_Dirs use ("src");
    for Object_Dir use "obj";
    for Library_Dir use "lib";
    for Library_Kind use "Dynamic";
end Math;

I then have a C header file math.h:

#ifndef MATH_H
#define MATH_H

#ifdef __cplusplus
extern "C"
#endif

typedef struct {
    char Name[101];
    int Age;
    char Address[101];
} Person_Record;

Person_Record Set_Age_To_Five(Person_Record P);

#ifdef __cplusplus

#endif

#endif /* MATH_H */

and finally my C code:

#include <stdio.h>
#include "math.h"

int main() {
    Person_Record p, q, r;

    // Initialize the person record
    snprintf(p.Name, sizeof(p.Name), "John");
    p.Age = 25;
    snprintf(p.Address, sizeof(p.Address), "123 Main St");

    // Call the Set_Age_To_Five function from the DLL
    q = Set_Age_To_Five(p);

    // Print the modified person record
    printf("Name: %s\n", q.Name);
    printf("Age: %d\n", q.Age);
    printf("Address: %s\n", q.Address);

    return 0;
}

This should when executed return

Name: John
Age: 5
Address: 123 Main St

Instead its returning:

Name: John
Age: 25
Address: 123 Main St

I've tried passing by variable, passing by reference. using convention C and convention pass by c in ada.

How would I define the __builtin_blendvps256 GCC intrinsic in Ada using GNAT?

I am trying to define a library in Ada (built on GNAT specifically) for x86 ISA extensions. (This question is specific to AVX/AVX2).

Here is some example code below:

-- 256-bit Vector of Single Precision Floating Point Numbers
type Vector_256_Float_32 is array (0 .. 7) of IEEE_Float_32 with
  Alignment => 32, Size => 256, Object_Size => 256;
pragma Machine_Attribute (Vector_256_Float_32, "vector_type");
pragma Machine_Attribute (Vector_256_Float_32, "may_alias");

-- 256-bit Vector of 32-bit Signed Integers
type Vector_256_Integer_32 is array (0 .. 7) of Integer_32 with
  Alignment => 32, Size => 256, Object_Size => 256;
pragma Machine_Attribute (Vector_256_Integer_32, "vector_type");
pragma Machine_Attribute (Vector_256_Integer_32, "may_alias");

-- 256-bit Vector of 32-bit Unsigned Integers
type Vector_256_Unsigned_32 is array (0 .. 7) of Unsigned_32 with
  Alignment => 32, Size => 256, Object_Size => 256;
pragma Machine_Attribute (Vector_256_Unsigned_32, "vector_type");
pragma Machine_Attribute (Vector_256_Unsigned_32, "may_alias");

function vblendvps
  (Left, Right, Mask : Vector_256_Float_32)
   return Vector_256_Float_32 with
  Inline_Always => True, Convention => Intrinsic, Import => True,
  External_Name => "__builtin_ia32_blendvps256";

For the sake of education, I want to know how to do this in assembly.

I have tried to define the vblendvps function using the Asm function from System.Machine_Code. However, as I am not knowledgeable about assembly programming, I am struggling to find resources on how to do this.

This is what I have so far:

with System.Machine_Code; use System.Machine_Code;

function vblendvps
(Left, Right, Mask : Vector_256_Float_32)
return Vector_256_Float_32
is
result : Vector_256_Float_32;
begin
Asm
(Template => "vblendvps %3, %0, %1, %2",
 Outputs  => Vector_256_Float_32'Asm_Output ("=g", result),
 Inputs   =>
   (Vector_256_Float_32'Asm_Input ("g", Left),
    Vector_256_Float_32'Asm_Input ("g", Right),
    Vector_256_Unsigned_32'Asm_Input ("g", Mask)));
return result;
end vblendvps;

When compiling the complete code, I get

Error: too many memory references for `vblendvps'

I believe this means that I need to move the arguments from memory to registers, but I am not sure. If there are some helpful references that explain every instruction, I would greatly appreciate that. (I had quite some trouble looking up the arguments to vblendvps).

My understanding is that the instruction is of the form (from ymm registers in my case)

vblendvps RESULT, LEFT, RIGHT, MASK

Please let me know how I would do this. Even if it is not in Ada, I'm sure I can figure out how to translate it.

A cell phone company is continually building and leasing communication towers. Each tower has one-way, direct communcation links to other tower [closed]

A cell phone company is continually building and leasing communication towers. Each tower has one-way, direct communcation links to other towers. The task is find if there is a communication link from one tower to another, possibly through other towers.

The input to the program is essentially a list of pairs of tower names. Each pair will appear on a single line and will contain distinct names. Some pairs represent one-way communcation links between towers, and other pairs represent queries. Links and queries may be interspersed.

All the communication links of the system are added one link at a time and no links are removed. Here is an example of a link:

Tower_A Tower_B. A link is terminated by a period.

A query asks if a communcation link is possible from one tower to another by any combination of one-way links. If another link is added to the system later in the input, then the answer to the same query may be different. In the output, a plus sign (+) represents an affirmative answer; a minus sign (-) says there is no such link.

Links are distinguished from queries by ending in a question mark and not a period.

Tower_A Tower_B? The program should read from the standard input and and write to the standard output. For each query in the input there should be exactly one line of output. If the query is true (there is a communication channel through the network), the output line should begin with a plus sign (+); otherwise with a minus sign (-). The rest of the output line repeats the towers in the query.

For the following input:

Tower_A Tower_B. Tower_B Tower_C . Tower_A Tower_C? # A query Tower_B Tower_D. Tower_A Tower_D ? # Another query Tower_F Tower_E. Tower_D Tower_B ? # A third query xxxx yyyy? # Unknown tower names Tower_D Tower_B . Tower_D Tower_B ? # Now there is a link the output should be

  • Tower_A -> Tower_C
  • Tower_A -> Tower_D
  • Tower_D -> Tower_B
  • xxxx -> yyyy
  • Tower_D -> Tower_B The names of the towers will contain only the characters [a-zA-Z_0-9], in particular they will have no spaces in them. Names will have at least 1 character and no more than 50 characters. Furthermore the capitialization of the names is significant. That is, WestMelbourneTower is not to be considered the same tower as wESTMeLbOuRnEtOwEr. Characters, if any, after the period (.) or question mark (?) on a line are to be ignored. No line will will contain more than 150 characters.

Please carefully observe spacing. There may, or may not, be a space before the period, the question mark, and the comment in the input. There will be one or more spaces between the tower names in the input. There must be a space after the plus and minus sign in the output. There must be a space before and after the arrow (->) in the output.

You are required to create your own graph package graph.ads graph.adb and name it Graph. The package can be generic or non-generic. The graph is to be a list of adajency lists. You are required to use the generic, doubly-linked list package from the standard library. These requirements are generally reasonable ones for the task anyway. There are more sophisticated approaches and less sophisticated approaches, but these requirements ensure the educational objectives of the assignment are met.

How can I install the ZFP (Zero Foot Print) RTS (Run Time System) for AVR with the Alire package manager for Ada?

How can I install the ZFP (Zero Foot Print) RTS (Run Time System) for AVR with the Alire package manager for Ada?

My project file, I think correctly, contains:

project Avr is
   for Runtime("Ada") use "zfp";
   for Target use "avr-elf";
end Avr;

alire.toml hopefully correction contains:

[[depends-on]]
gnat_avr_elf = ">=11.2.4"

Unfortunately, when running alr build, I get:

gprconfig: can't find a toolchain for the following configuration:
gprconfig: language 'ada', target 'avr-elf', runtime 'zfp'

I found documentation for programming AVR with Ada, but this assumes that I build the tool-chain myself and not have a package manager at least providing the GNU tool-chain.

The same applies to Programming Arduino with Ada.

โŒ
โŒ