The RM B.1 (39) implementation advice says that the adainit/adafinal routines generated to manage Ada libraries from foreign languages should be idempotent. This adds an elaboration flag to the file generated by the binder and an early return to the routines to ensure that this is the case.
Tested on x86_64-pc-linux-gnu, committed on trunk 2011-08-04 Eric Botcazou <ebotca...@adacore.com> * bindgen.adb (Gen_Adafinal_Ada): Generate an early return if the library has already been finalized. (Gen_Adafinal_C): Likewise. (Gen_Adainit_Ada): Generate an early return if the library has already been elaborated. (Gen_Adainit_C): Likewise. (Gen_Output_File_Ada): Generate an elaboration flag. (Gen_Output_File_C): Likewise.
Index: bindgen.adb =================================================================== --- bindgen.adb (revision 177329) +++ bindgen.adb (working copy) @@ -428,8 +428,20 @@ begin WBI (" procedure " & Ada_Final_Name.all & " is"); + if Bind_Main_Program and then VM_Target = No_VM then + WBI (" procedure s_stalib_adafinal;"); + Set_String (" pragma Import (C, s_stalib_adafinal, "); + Set_String ("""system__standard_library__adafinal"");"); + Write_Statement_Buffer; + end if; + + WBI (" begin"); + WBI (" if not Is_Elaborated then"); + WBI (" return;"); + WBI (" end if;"); + WBI (" Is_Elaborated := False;"); + if not Bind_Main_Program then - WBI (" begin"); if Lib_Final_Built then WBI (" finalize_library;"); else @@ -439,17 +451,12 @@ -- Main program case elsif VM_Target = No_VM then - WBI (" procedure s_stalib_adafinal;"); - WBI (" pragma Import (C, s_stalib_adafinal, " & - """system__standard_library__adafinal"");"); - WBI (" begin"); WBI (" s_stalib_adafinal;"); -- Pragma Import C cannot be used on virtual machine targets, therefore -- call the runtime finalization routine directly. else - WBI (" begin"); WBI (" System.Standard_Library.Adafinal;"); end if; @@ -465,6 +472,10 @@ begin WBI ("void " & Ada_Final_Name.all & " (void) {"); + WBI (" if (!is_elaborated)"); + WBI (" return;"); + WBI (" is_elaborated = 0;"); + if not Bind_Main_Program then if Lib_Final_Built then WBI (" finalize_library ();"); @@ -685,6 +696,11 @@ WBI (" begin"); + WBI (" if Is_Elaborated then"); + WBI (" return;"); + WBI (" end if;"); + WBI (" Is_Elaborated := True;"); + Set_String (" Main_Priority := "); Set_Int (Main_Priority); Set_Char (';'); @@ -941,6 +957,10 @@ WBI ("void " & Ada_Init_Name.all & " (void)"); WBI ("{"); + WBI (" if (is_elaborated)"); + WBI (" return;"); + WBI (" is_elaborated = 1;"); + -- Standard library suppressed if Suppress_Standard_Library_On_Target then @@ -3077,6 +3097,9 @@ WBI (""); end if; + WBI (" Is_Elaborated : Boolean := False;"); + WBI (""); + -- Generate the adafinal routine unless there is no finalization to do if not Cumulative_Restrictions.Set (No_Finalization) then @@ -3300,6 +3323,9 @@ WBI (""); end if; + WBI ("static char is_elaborated = 0;"); + WBI (""); + -- Generate the adafinal routine unless there is no finalization to do if not Cumulative_Restrictions.Set (No_Finalization) then