Elaboration circularity detected

Hi, I am new in this forum.
I have a problem porting ada code from Red Hat 8 (gnat 8.5.0) to Red Hat 9 (gnat 11.3.1).
The linking phase on RHEL9 fails for “Elaboration circularity detected”.
I let the ada compiler to choose the module compilation order using the following instruction:
gnatmake -c
The reason is: “unit depends on its own elaboration”
The circularity detected is: "unit invokes a construct of unit at elaboration time.
What shall I do to find the exact location of the problem?
And why this problem was not detected before using other gnat versions?
Thanks a lot

Please show the whole gnatmake command and the whole output from that command. The name(s) of the unit(s) in the elaboration circle should appear in the output.

This sometimes occurs because of a task; the compiler thinks it might start executing, and invoking other elements of the package, during elaboration. If that’s it, you might try specifying a task type and creating the instance later (e.g. in an externally-called Init procedure).

A long time ago, I had a case where the list of units involved in the circularity was longer than the number of units :unamused:

Sorry, the post was incomplete beacause there were special characters that, probably, have a special meaning in publishing the text.

The program is an ada program (the main is an ada unit) that uses c libraries.

The compilation of the ada part is:
gnatmake -c sim (sim is the ada main procedure name).
Therefore, I let the compiler choosing the compilation order of ada modules.

After that, the generation of the executable file is done by:
gnatbind sim
gnatlink -o sim_exe sim (plus list of c files and c libraries to be linked)

The generated error is:

Elaborate circularity detected
Reason:
unit “ex_status_han (body)” depends on its own elaboration
Circularity:
unit “ex_status_han (body)” invokes a construct of unit “ex_status_han (body)” at elaboration time

ex_status_han contains only a task with 3 entries invoked by other tasks

Thanks for showing the complete build commands and error messages. I think Simon’s suggestion to remove the actual task creation to another unit might help, but it is hard to say for sure without seeing more of the code.

For large multi-task programs I try to put all task creations in their own packages, on which no other units depend, except for the main subprogram. This lets the compiler put these “task packages” close to last in the elaboration order. It also makes testing easier because the test-main subprogram can choose to “with” only a subset of the task packages and thus control which tasks are active in each test.

By the way, when linking to C code I find it convenient to use pragma Linker_Options to tell the linker which .o files from C code to include in the link, instead of listing those .o files in a gnatlink command. I put the Linker_Options pragma next to the declaration of the C function(s) in the Ada code. You can have several Linker_Options pragmas with cumulative effect. See Interfacing Aspects.

Thanks for your answers.
The allocation/activation of the ex_status_han task is in the ads file.
The ads file contains only “with” of general packages defining constant and data types.
There is not an (off loop) “init” activation entry because this task shall be ready to be called from other tasks whenever they need to use any of the services made available by it.
Remains the question of why this circularity has not been detected up to now by all previous compilers used.

As message say, there is some constructs in the task that use construct outside of the task but in the same package. It might be anything, even library level constant declaration might require elaboration, thus reference to the constant from the task might raise this issue.

Elaboration procedure is complicated, it is compiler dependent and configuration dependent, so it is usual that different version of the compiler generates different machine code for elaboration of the same Ada code.