From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 5239 invoked by alias); 29 Jan 2013 14:07:55 -0000 Received: (qmail 5168 invoked by uid 22791); 29 Jan 2013 14:07:52 -0000 X-SWARE-Spam-Status: No, hits=-1.7 required=5.0 tests=AWL,BAYES_00,KHOP_SPAMHAUS_DROP,RCVD_IN_HOSTKARMA_NO X-Spam-Check-By: sourceware.org Received: from rock.gnat.com (HELO rock.gnat.com) (205.232.38.15) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 29 Jan 2013 14:07:43 +0000 Received: from localhost (localhost.localdomain [127.0.0.1]) by filtered-rock.gnat.com (Postfix) with ESMTP id 829982E715; Tue, 29 Jan 2013 09:07:42 -0500 (EST) Received: from rock.gnat.com ([127.0.0.1]) by localhost (rock.gnat.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id 8wTArE97RJhp; Tue, 29 Jan 2013 09:07:42 -0500 (EST) Received: from kwai.gnat.com (kwai.gnat.com [205.232.38.4]) by rock.gnat.com (Postfix) with ESMTP id 608572E2AB; Tue, 29 Jan 2013 09:07:42 -0500 (EST) Received: by kwai.gnat.com (Postfix, from userid 4192) id 608BD919E3; Tue, 29 Jan 2013 09:07:42 -0500 (EST) Date: Tue, 29 Jan 2013 14:07:00 -0000 From: Arnaud Charlet To: gcc-patches@gcc.gnu.org Cc: Vincent Celier Subject: [Ada] gnatmake find old ALI files in wrong object directory Message-ID: <20130129140742.GA24692@adacore.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="OXfL5xGRrasGEqWY" Content-Disposition: inline User-Agent: Mutt/1.5.20 (2009-06-14) Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org X-SW-Source: 2013-01/txt/msg01380.txt.bz2 --OXfL5xGRrasGEqWY Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-length: 1348 When gnatmake is invoked with project files and a source has been moved from one project A to another project B in the project tree, but the ALI and object files has not be removed from the object directory of A, gnatmake may always recompile the source moved to project B, even when it is up to date. This patch is fixing this. The test is to have 3 projects: Prj that withs A that withs B. The object directories of the 3 projects are different. A package Pkg in project A is used by the main in Prj. Invoke gnatmake to build the main in Prj. Move package Pkg from project A to project B, without removing the ALI and object files in the object directory of A. Invoke gnatmake to build the main in Prj. Invoke again gnatmake to build the main in Prj: gnatmake should report that everything is up to date. Tested on x86_64-pc-linux-gnu, committed on trunk 2013-01-29 Vincent Celier * clean.adb (Clean_Executables): Add Sid component when calling Queue.Insert. * make.adb: When inserting in the Queue, add the Source_Id (Sid) when it is known (Start_Compile_If_Possible): When the Source_Id is known (Sid), get the path name of the ALI file (Full_Lib_File) from it, to avoid finding old ALI files in other object directories. * makeutl.ads (Source_Info): New Source_Id component Sid in Format_Gnatmake variant. --OXfL5xGRrasGEqWY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=difs Content-length: 10057 Index: make.adb =================================================================== --- make.adb (revision 195533) +++ make.adb (working copy) @@ -2746,7 +2746,8 @@ File => Sfile, Unit => No_Unit_Name, Project => No_Project, - Index => 0)) + Index => 0, + Sid => No_Source)) then if Is_In_Obsoleted (Sfile) then Executable_Obsolete := True; @@ -3091,6 +3092,7 @@ ALI : ALI_Id; Source_Index : Int; Sfile : File_Name_Type; + Sid : Prj.Source_Id; Uname : Unit_Name_Type; Unit_Name : Name_Id; Uid : Prj.Unit_Index; @@ -3137,6 +3139,7 @@ loop Sfile := Withs.Table (K).Sfile; Uname := Withs.Table (K).Uname; + Sid := No_Source; -- If project files are used, find the proper source to -- compile in case Sfile is the spec but there is a body. @@ -3154,12 +3157,14 @@ then Sfile := Uid.File_Names (Impl).File; Source_Index := Uid.File_Names (Impl).Index; + Sid := Uid.File_Names (Impl); elsif Uid.File_Names (Spec) /= null and then not Uid.File_Names (Spec).Locally_Removed then Sfile := Uid.File_Names (Spec).File; Source_Index := Uid.File_Names (Spec).Index; + Sid := Uid.File_Names (Spec); end if; end if; end if; @@ -3187,7 +3192,8 @@ File => Sfile, Project => ALI_P.Project, Unit => Withs.Table (K).Uname, - Index => Source_Index)); + Index => Source_Index, + Sid => Sid)); end if; end if; end loop; @@ -3308,16 +3314,16 @@ is In_Lib_Dir : Boolean; Need_To_Compile : Boolean; - Pid : Process_Id; + Pid : Process_Id := Invalid_Pid; Process_Created : Boolean; Source : Queue.Source_Info; - Full_Source_File : File_Name_Type; + Full_Source_File : File_Name_Type := No_File; Source_File_Attr : aliased File_Attributes; -- The full name of the source file and its attributes (size, ...) Lib_File : File_Name_Type; - Full_Lib_File : File_Name_Type; + Full_Lib_File : File_Name_Type := No_File; Lib_File_Attr : aliased File_Attributes; Read_Only : Boolean := False; ALI : ALI_Id; @@ -3335,24 +3341,50 @@ then Queue.Extract (Found, Source); - Osint.Full_Source_Name - (Source.File, - Full_File => Full_Source_File, - Attr => Source_File_Attr'Access); + -- If it is a source in a project, first look for the ALI file + -- in the object directory. When the project is extending another + -- the ALI file may not be found, but the source does not + -- necessarily need to be compiled, as it may already be up to + -- date in the project being extended. In this case, look for an + -- ALI file in all the object directories, as is done when + -- gnatmake is not invoked with a project file. - Lib_File := Osint.Lib_File_Name (Source.File, Source.Index); + if Source.Sid /= No_Source then + Initialize_Source_Record (Source.Sid); + Full_Source_File := + File_Name_Type (Source.Sid.Path.Display_Name); + Lib_File := Source.Sid.Dep_Name; + Full_Lib_File := File_Name_Type (Source.Sid.Dep_Path); + Lib_File_Attr := Unknown_Attributes; - -- ??? This call could be avoided when using projects, since we - -- know where the ALI file is supposed to be. That would avoid - -- searches in the object directories, including in the runtime - -- dir. However, that would require getting access to the - -- Source_Id. + if Full_Lib_File /= No_File then + declare + FLF : constant String := + Get_Name_String (Full_Lib_File) & ASCII.NUL; + begin + if not Is_Regular_File + (FLF'Address, Lib_File_Attr'Access) + then + Full_Lib_File := No_File; + end if; + end; + end if; + end if; - Osint.Full_Lib_File_Name - (Lib_File, - Lib_File => Full_Lib_File, - Attr => Lib_File_Attr); + if Full_Lib_File = No_File then + Osint.Full_Source_Name + (Source.File, + Full_File => Full_Source_File, + Attr => Source_File_Attr'Access); + Lib_File := Osint.Lib_File_Name (Source.File, Source.Index); + + Osint.Full_Lib_File_Name + (Lib_File, + Lib_File => Full_Lib_File, + Attr => Lib_File_Attr); + end if; + -- If source has already been compiled, executable is obsolete if Is_In_Obsoleted (Source.File) then @@ -3734,7 +3766,8 @@ File => Main_Source, Project => Main_Project, Unit => No_Unit_Name, - Index => Main_Index)); + Index => Main_Index, + Sid => No_Source)); First_Compiled_File := No_File; Most_Recent_Obj_File := No_File; @@ -6650,6 +6683,7 @@ Put_In_Q : Boolean := Into_Q; Unit : Unit_Index; Sfile : File_Name_Type; + Sid : Prj.Source_Id; Index : Int; Project : Project_Id; @@ -6659,6 +6693,7 @@ Unit := Units_Htable.Get_First (Project_Tree.Units_HT); while Unit /= null loop Sfile := No_File; + Sid := No_Source; Index := 0; Project := No_Project; @@ -6704,15 +6739,18 @@ if Sinput.P.Source_File_Is_Subunit (Src_Ind) then Sfile := No_File; Index := 0; + Sid := No_Source; else Sfile := Unit.File_Names (Impl).Display_File; Index := Unit.File_Names (Impl).Index; + Sid := Unit.File_Names (Impl); end if; end; else Sfile := Unit.File_Names (Impl).Display_File; Index := Unit.File_Names (Impl).Index; + Sid := Unit.File_Names (Impl); end if; end if; @@ -6728,6 +6766,7 @@ Sfile := Unit.File_Names (Spec).Display_File; Index := Unit.File_Names (Spec).Index; + Sid := Unit.File_Names (Spec); Project := Unit.File_Names (Spec).Project; end if; @@ -6744,7 +6783,8 @@ File => Sfile, Project => Project, Unit => No_Unit_Name, - Index => Index)); + Index => Index, + Sid => Sid)); end if; if not Put_In_Q and then Sfile /= No_File then Index: makeutl.ads =================================================================== --- makeutl.ads (revision 195533) +++ makeutl.ads (working copy) @@ -485,14 +485,15 @@ record case Format is when Format_Gprbuild => - Tree : Project_Tree_Ref := null; - Id : Source_Id := null; + Tree : Project_Tree_Ref := No_Project_Tree; + Id : Source_Id := No_Source; when Format_Gnatmake => File : File_Name_Type := No_File; Unit : Unit_Name_Type := No_Unit_Name; Index : Int := 0; Project : Project_Id := No_Project; + Sid : Source_Id := No_Source; end case; end record; -- Information about files stored in the queue. The exact information Index: clean.adb =================================================================== --- clean.adb (revision 195533) +++ clean.adb (working copy) @@ -397,7 +397,8 @@ File => Main_Lib_File, Unit => No_Unit_Name, Index => 0, - Project => No_Project)); + Project => No_Project, + Sid => No_Source)); end if; while not Queue.Is_Empty loop @@ -440,7 +441,8 @@ File => Withs.Table (K).Afile, Unit => No_Unit_Name, Index => 0, - Project => No_Project)); + Project => No_Project, + Sid => No_Source)); end if; end loop; end loop; --OXfL5xGRrasGEqWY--