فهرست منبع

* changed linking: now we will link all objects to a single one and call nlmconv with that one object file. This makes it possible to create nlms without debug info.

armin 22 سال پیش
والد
کامیت
47e09e0c87
1فایلهای تغییر یافته به همراه81 افزوده شده و 56 حذف شده
  1. 81 56
      compiler/systems/t_nwm.pas

+ 81 - 56
compiler/systems/t_nwm.pas

@@ -19,8 +19,6 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    First Implementation 10 Sept 2000 Armin Diehl
-
     Currently generating NetWare-NLM's only work under Linux and win32.
     (see http://home.arcor.de/armin.diehl/fpcnw for binutils working
     with win32) while not included in fpc-releases.
@@ -28,12 +26,13 @@
     The following compiler-swiches are supported for NetWare:
     $DESCRIPTION    : NLM-Description, will be displayed at load-time
     $M              : For Stack-Size, Heap-Size will be ignored
+                      32K is the accepted minimum
     $VERSION x.x.x  : Sets Major, Minor and Revision
     $SCREENNAME     : Sets the ScreenName
-    $THREADNAME     : Sets cirrent threadname
+    $THREADNAME     : Sets current threadname
 
-    Sorry, Displaying copyright does not work with nlmconv from gnu bunutils
-    but there is a patch available.
+    Displaying copyright does not work with nlmconv from gnu bunutils
+    version less that 2.13
 
     Exports will be handled like in win32:
     procedure bla;
@@ -42,20 +41,23 @@
 
     exports foo name 'Bar';
 
-    The path to the import-Files (from netware-sdk, see developer.novell.com)
-    must be specified by the library-path. All external modules are defined
-    as autoload. (Note: the import-files have to be in unix-format for exe2nlm)
+    The path to the import-Files must be specified by the library-path.
+    All external modules are defined as autoload. (Note: the import-files have
+    to be in unix-format for exe2nlm)
     By default, the most import files are included in freepascal.
 
     i.e. Procedure ConsolePrintf (p:pchar); cdecl; external 'clib.nlm';
     sets IMPORT @clib.imp and MODULE clib.
 
+    Function simply defined as external work without generating autoload but
+    you will get a warnung from nlmconv.
+
     If you dont have nlmconv, compile gnu-binutils with
        ./configure --enable-targets=i386-linux,i386-netware
        make all
 
-    Debugging is possible with gdb and a converter from gdb to ndi available 
-    at http://home.arcor.de/armin.diehl/gdbnw (you have to compile with -gg)
+    Debugging is possible with gdb and a converter from gdb to ndi available
+    at http://home.arcor.de/armin.diehl/gdbnw
 
     A sample program:
 
@@ -73,9 +75,7 @@
 
     ToDo:
       - No duplicate imports and autoloads
-      - No debug symbols
       - libc support (needs new target)
-      - prelude support (needs new compiler switch)
 
 ****************************************************************************
 }
@@ -112,6 +112,7 @@ implementation
 
     tlinkernetware=class(texternallinker)
     private
+      NLMConvLinkFile: TLinkRes;  {for second pass, fist pass is ld}
       Function  WriteResponseFile(isdll:boolean) : Boolean;
     public
       constructor Create;override;
@@ -119,6 +120,8 @@ implementation
       function  MakeExecutable:boolean;override;
     end;
 
+Const tmpLinkFileName = 'link~tmp._o_';
+      minStackSize = 32768;
 
 {*****************************************************************************
                                TIMPORTLIBNETWARE
@@ -262,7 +265,8 @@ procedure TLinkerNetware.SetDefaultInfo;
 begin
   with Info do
    begin
-     ExeCmd[1]:='nlmconv -T$RES';
+     ExeCmd[1]:= 'ld -Ur -T $RES $STRIP -o $TMPOBJ';
+     ExeCmd[2]:='nlmconv -T$RES';
    end;
 end;
 
@@ -286,7 +290,8 @@ begin
   NlmNam := ProgNam + target_info.exeext;
 
   { Open link.res file }
-  LinkRes:=TLinkRes.Create(outputexedir+Info.ResName);
+  LinkRes:=TLinkRes.Create(outputexedir+Info.ResName);         {for ld}
+  NLMConvLinkFile:=TLinkRes.Create(outputexedir+Info.ResName); {for nlmconv, written in CreateExeFile}
 
   p := Pos ('"', Description);
   while (p > 0) do
@@ -295,8 +300,8 @@ begin
     p := Pos ('"', Description);
   end;
   if Description <> '' then
-    LinkRes.Add('DESCRIPTION "' + Description + '"');
-  LinkRes.Add('VERSION '+tostr(dllmajor)+','+tostr(dllminor)+','+tostr(dllrevision));
+    NLMConvLinkFile.Add('DESCRIPTION "' + Description + '"');
+  NLMConvLinkFile.Add('VERSION '+tostr(dllmajor)+','+tostr(dllminor)+','+tostr(dllrevision));
 
   p := Pos ('"', nwscreenname);
   while (p > 0) do
@@ -318,39 +323,40 @@ begin
   end;
 
   if nwscreenname <> '' then
-    LinkRes.Add('SCREENNAME "' + nwscreenname + '"');
+    NLMConvLinkFile.Add('SCREENNAME "' + nwscreenname + '"');
   if nwthreadname <> '' then
-    LinkRes.Add('THREADNAME "' + nwthreadname + '"');
+    NLMConvLinkFile.Add('THREADNAME "' + nwthreadname + '"');
   if nwcopyright <> '' then
-    LinkRes.Add('COPYRIGHT "' + nwcopyright + '"');
+    NLMConvLinkFile.Add('COPYRIGHT "' + nwcopyright + '"');
 
-  if stacksize < 32768 then stacksize := 32768;
+  if stacksize < minStackSize then stacksize := minStackSize;
   str (stacksize, s);
-  LinkRes.Add ('STACKSIZE '+s);
+  NLMConvLinkFile.Add ('STACKSIZE '+s);
+  NLMConvLinkFile.Add ('INPUT '+tmpLinkFileName);
 
   { add objectfiles, start with nwpre always }
-  LinkRes.Add ('INPUT '+FindObjectFile('nwpre',''));
+  LinkRes.Add ('INPUT (');
+  LinkRes.Add (FindObjectFile('nwpre',''));
 
-  { main objectfiles }
+  { main objectfiles, add to linker input }
   while not ObjectFiles.Empty do
-   begin
-     s:=ObjectFiles.GetFirst;
-     if s<>'' then
-      LinkRes.Add ('INPUT ' + FindObjectFile (s,''));
-   end;
+  begin
+    s:=ObjectFiles.GetFirst;
+    if s<>'' then
+      LinkRes.Add (FindObjectFile (s,''));
+  end;
 
-  { output file (nlm) }
-  LinkRes.Add ('OUTPUT ' + NlmNam);
+  { output file (nlm), add to nlmconv }
+  NLMConvLinkFile.Add ('OUTPUT ' + NlmNam);
 
   { start and stop-procedures }
-  LinkRes.Add ('START _Prelude');  { defined in rtl/netware/nwpre.as }
-  LinkRes.Add ('EXIT _Stop');
-  LinkRes.Add ('CHECK FPC_NW_CHECKFUNCTION');
+  NLMConvLinkFile.Add ('START _Prelude');  { defined in rtl/netware/nwpre.as }
+  NLMConvLinkFile.Add ('EXIT _Stop');                             { nwpre.as }
+  NLMConvLinkFile.Add ('CHECK FPC_NW_CHECKFUNCTION');            { system.pp }
 
-  if (cs_gdb_dbx in aktglobalswitches) or 
-     (cs_gdb_gsym in aktglobalswitches) then
+  if not (cs_link_strip in aktglobalswitches) then
   begin
-    LinkRes.Add ('DEBUG');
+    NLMConvLinkFile.Add ('DEBUG');
     Comment(V_Debug,'DEBUG');
   end;
 
@@ -368,7 +374,7 @@ begin
          if (pos ('.a',s) <> 0) OR (pos ('.A', s) <> 0) then
          begin
 	   S2 := FindObjectFile(s,'');
-           LinkRes.Add ('INPUT '+S2);
+           LinkRes.Add (S2);
 	   Comment(V_Debug,'INPUT '+S2);
          end else
          begin
@@ -377,7 +383,7 @@ begin
              Delete(S,i,255);
            S := S + '.imp'; S2 := '';
            librarysearchpath.FindFile(S,S2);
-           LinkRes.Add('IMPORT @'+S2);
+           NLMConvLinkFile.Add('IMPORT @'+S2);
 	   Comment(V_Debug,'IMPORT @'+s2);
          end;
         end
@@ -403,8 +409,8 @@ begin
              Delete(S,i,255);
            S := S + '.imp';
            librarysearchpath.FindFile(S,S3);
-           LinkRes.Add('IMPORT @'+S3);
-           LinkRes.Add('MODULE '+s2);
+           NLMConvLinkFile.Add('IMPORT @'+S3);
+           NLMConvLinkFile.Add('MODULE '+s2);
 	   Comment(V_Debug,'MODULE '+S2);
 	   Comment(V_Debug,'IMPORT @'+S3);
          end
@@ -419,7 +425,7 @@ begin
       begin
         { Export the Symbol }
         Comment(V_Debug,'EXPORT '+hp2.name^);
-        LinkRes.Add ('EXPORT '+hp2.name^);
+        NLMConvLinkFile.Add ('EXPORT '+hp2.name^);
       end
      else
       { really, i think it is possible }
@@ -427,7 +433,8 @@ begin
      hp2:=texported_item(hp2.next);
    end;
 
-{ Write and Close response }
+{ Write and Close response for ld, response for nlmconv is in NLMConvLinkFile(not written) }
+  linkres.Add (')');
   linkres.writetodisk;
   LinkRes.Free;
 
@@ -438,37 +445,52 @@ end;
 function TLinkerNetware.MakeExecutable:boolean;
 var
   binstr,
-  cmdstr  : string;
-  success : boolean;
-  DynLinkStr : string[60];
-  StaticStr,
-  StripStr   : string[40];
+  cmdstr   : string;
+  success  : boolean;
+  StripStr : string[2];
 begin
   if not(cs_link_extern in aktglobalswitches) then
    Message1(exec_i_linking,current_module.exefilename^);
 
 { Create some replacements }
-  StaticStr:='';
   StripStr:='';
-  DynLinkStr:='';
 
-{ Write used files and libraries }
+  if (cs_link_strip in aktglobalswitches) then
+   StripStr:='-s';
+
+{ Write used files and libraries and create Headerfile for
+  nlmconv in NLMConvLinkFile }
   WriteResponseFile(false);
 
-{ Call linker }
+{ Call linker, this will generate a new object file that will be passed
+  to nlmconv. Otherwise we could not create nlms without debug info }
   SplitBinCmd(Info.ExeCmd[1],binstr,cmdstr);
   Replace(cmdstr,'$EXE',current_module.exefilename^);
-  Replace(cmdstr,'$OPT',Info.ExtraOptions);
   Replace(cmdstr,'$RES',outputexedir+Info.ResName);
-  Replace(cmdstr,'$STATIC',StaticStr);
   Replace(cmdstr,'$STRIP',StripStr);
-  Replace(cmdstr,'$DYNLINK',DynLinkStr);
+  Replace(cmdstr,'$TMPOBJ',outputexedir+tmpLinkFileName);
+  Comment (v_debug,'Executing '+BinStr+' '+cmdstr);
   success:=DoExec(FindUtil(BinStr),CmdStr,true,false);
 
   { Remove ReponseFile }
   if (success) and not(cs_link_extern in aktglobalswitches) then
     RemoveFile(outputexedir+Info.ResName);
-    
+
+{ Call nlmconv }
+  if success then
+  begin
+    NLMConvLinkFile.writetodisk;
+    NLMConvLinkFile.Free;
+    SplitBinCmd(Info.ExeCmd[2],binstr,cmdstr);
+    Replace(cmdstr,'$RES',outputexedir+Info.ResName);
+    Comment (v_debug,'Executing '+BinStr+' '+cmdstr);
+    success:=DoExec(FindUtil(BinStr),CmdStr,true,false);
+    if success then
+      RemoveFile(outputexedir+Info.ResName);
+    {always remove the temp object file}
+    RemoveFile(outputexedir+tmpLinkFileName);
+  end;
+
   MakeExecutable:=success;   { otherwise a recursive call to link method }
 end;
 
@@ -486,7 +508,10 @@ initialization
 end.
 {
   $Log$
-  Revision 1.4  2003-03-21 19:19:51  armin
+  Revision 1.5  2003-03-21 22:36:42  armin
+  * changed linking: now we will link all objects to a single one and call nlmconv with that one object file. This makes it possible to create nlms without debug info.
+
+  Revision 1.4  2003/03/21 19:19:51  armin
   * search of .imp files was broken, debug only if -gg was specified
 
   Revision 1.3  2002/11/17 16:32:04  carl