3 Copyright (c) 1998-2000 by Peter Vreman
5 This unit handles the assemblerfile write and assembler calls of FPC
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 ****************************************************************************}
33 cobjects
,globtype
,globals
,aasm
;
46 procedure CreateSmartLinkPath(const s
:string);
51 asmfile
, { current .s and .o file }
55 smarthcount
: longint
;
56 place
: TCutPlace
; { special 'end' file for import dir ? }
61 outbuf
: array
[0..AsmOutSize
-1] of char
;
63 Constructor Init
(smart:boolean
);
65 Function
FindAssembler:string
;
66 Function CallAssembler
(const command
,para:string
):Boolean
;
67 Function
DoAssemble:boolean
;
69 procedure NextSmartName
;
72 Procedure AsmWrite
(const
s:string
);
73 Procedure AsmWritePChar
(p:pchar
);
74 Procedure AsmWriteLn
(const
s:string
);
76 procedure AsmCreate
(Aplace:tcutplace
);
78 procedure Synchronize
;
79 procedure WriteTree
(p:paasmoutput
);virtual;
80 procedure WriteAsmList
;virtual;
84 SmartLinkFilesCnt
: longint;
86 Procedure GenerateAsm(smart
:boolean);
93 script
,files
,systems
,verbose
132 {*****************************************************************************
134 *****************************************************************************}
136 Function DoPipe
:boolean;
138 DoPipe
:=(cs_asm_pipe
in aktglobalswitches
) and
139 not(cs_asm_leave
in aktglobalswitches
)
141 and (aktoutputformat
=as_i386_as
)
144 and (aktoutputformat
=as_m68k_as
);
153 Function TAsmList
.FindAssembler
:string;
157 if lastas
<>ord(target_asm
.id
) then
159 lastas
:=ord(target_asm
.id
);
160 { is an assembler passed ? }
161 if utilsdirectory
<>'' then
162 LastASBin
:=FindFile(target_asm
.asmbin
+source_os.exeext
,utilsdirectory
,asfound
)+
163 target_asm.asmbin
+source_os.exeext
;
165 LastASBin:=FindExe
(target_asm.asmbin
,asfound
);
166 if
(not asfound
) and not(cs_asm_extern
in aktglobalswitches
) then
168 Message1
(exec_w_assembler_not_found
,LastASBin
);
169 aktglobalswitches:=aktglobalswitches
+[cs_asm_extern
];
172 Message1(exec_t_using_assembler
,LastASBin
);
174 FindAssembler
:=LastASBin
;
178 Function TAsmList
.CallAssembler(const command
,para
:string):Boolean;
181 if not(cs_asm_extern
in aktglobalswitches
) then
186 if (doserror
<>0) then
188 Message1(exec_w_cant_call_assembler
,tostr(doserror
));
189 aktglobalswitches
:=aktglobalswitches
+[cs_asm_extern
];
190 callassembler
:=false;
193 if (dosexitcode
<>0) then
195 Message1(exec_w_error_while_assembling
,tostr(dosexitcode
));
196 callassembler
:=false;
200 AsmRes
.AddAsmCommand(command
,para
,name
);
204 procedure TAsmList
.RemoveAsm
;
208 if cs_asm_leave
in aktglobalswitches
then
210 if cs_asm_extern
in aktglobalswitches
then
211 AsmRes
.AddDeleteCommand(AsmFile
)
223 Function TAsmList
.DoAssemble
:boolean;
230 if not(cs_asm_extern
in aktglobalswitches
) then
234 if (SmartLinkFilesCnt
<=1) then
235 Message1(exec_i_assembling_smart
,name
);
238 Message1(exec_i_assembling
,name
);
240 s
:=target_asm
.asmcmd
;
241 Replace
(s
,'$ASM',AsmFile
);
242 Replace
(s
,'$OBJ',ObjFile
);
243 if CallAssembler
(FindAssembler
,s
) then
253 procedure TAsmList
.NextSmartName
;
257 inc(SmartLinkFilesCnt
);
258 if SmartLinkFilesCnt
>999999 then
259 Message(asmw_f_too_many_asm_files
);
264 s:=current_module^.asmprefix^
+tostr
(smarthcount
)+'h';
267 s
:=current_module
^.asmprefix^
+tostr
(smarthcount
)+'s';
269 s:=current_module^.asmprefix^
+tostr
(smarthcount
)+'t';
271 AsmFile
:=Path
+FixFileName(s
+tostr(SmartLinkFilesCnt
)+target_info
.asmext
);
272 ObjFile:=Path
+FixFileName
(s
+tostr
(SmartLinkFilesCnt
)+target_info.objext
);
273 { insert in container so it can be cleared after the linking }
274 SmartLinkOFiles.Insert
(Objfile
);
278 {*****************************************************************************
279 TAsmList AsmFile Writing
280 *****************************************************************************}
282 Procedure TAsmList
.AsmFlush
;
286 BlockWrite(outfile
,outbuf
,outcnt
);
292 Procedure TAsmList
.AsmClear
;
298 Procedure TAsmList
.AsmWrite(const s
:string);
300 if OutCnt
+length(s
)>=AsmOutSize
then
302 Move(s
[1],OutBuf
[OutCnt
],length(s
));
303 inc(OutCnt
,length(s
));
304 inc(AsmSize
,length(s
));
308 Procedure TAsmList
.AsmWriteLn(const s
:string);
315 Procedure TAsmList
.AsmWritePChar(p
:pchar
);
323 i
:=min(j
,AsmOutSize
);
324 if OutCnt
+i
>=AsmOutSize
then
326 Move(p
[0],OutBuf
[OutCnt
],i
);
335 Procedure TAsmList
.AsmLn
;
337 if OutCnt
>=AsmOutSize
-2 then
339 OutBuf
[OutCnt
]:=target_os
.newline
[1];
342 if length(target_os
.newline
)>1 then
344 OutBuf
[OutCnt
]:=target_os
.newline
[2];
351 procedure TAsmList
.AsmCreate(Aplace
:tcutplace
);
359 Message1(exec_i_assembling_pipe
,asmfile
);
360 POpen
(outfile
,'as -o '+objfile
,'W');
365 Assign
(outfile
,asmfile
);
370 Message1
(exec_d_cant_create_asmfile
,asmfile
);
378 procedure TAsmList
.AsmClose
;
390 {Touch Assembler time to ppu time is there is a ppufilename}
391 if Assigned(current_module
^.ppufilename
) then
393 Assign(f
,current_module
^.ppufilename
^);
410 {Touch Assembler and object time to ppu time is there is a ppufilename}
411 procedure TAsmList
.Synchronize
;
413 {Touch Assembler time to ppu time is there is a ppufilename}
414 if Assigned(current_module
^.ppufilename
) then
416 SynchronizeFileTime(current_module
^.ppufilename
^,asmfile
);
417 if
not(cs_asm_extern
in aktglobalswitches
) then
418 SynchronizeFileTime
(current_module^.ppufilename^
,objfile
);
423 procedure TAsmList
.WriteTree(p
:paasmoutput
);
428 procedure TAsmList
.WriteAsmList
;
433 procedure TAsmList
.CreateSmartLinkPath(const s
:string);
437 if PathExists(s
) then
439 { the path exists, now we clean only all the .o and .s files }
441 findfirst(s
+dirsep
+'*'+target_info
.objext
,anyfile
,dir
);
442 while (doserror
=0) do
444 RemoveFile(s
+dirsep
+dir
.name
);
451 findfirst(s
+dirsep
+'*'+target_info
.asmext
,anyfile
,dir
);
452 while
(doserror
=0) do
454 RemoveFile
(s
+dirsep
+dir.
name);
471 Constructor TAsmList
.Init(smart
:boolean);
473 { load start values }
474 asmfile
:=current_module^.asmfilename^
;
475 objfile:=current_module^.objfilename^
;
476 name:=FixFileName
(current_module^.modulename^
);
478 SmartLinkFilesCnt:=0;
479 SmartLinkOFiles.Clear
;
483 { Which path will be used ? }
486 path:=current_module^.outputpath^
+FixFileName
(current_module^.modulename^
)+target_info.smartext
;
487 CreateSmartLinkPath
(path
);
488 path:=FixPath
(path
,false
);
491 path:=current_module^.outputpath^
;
495 Destructor TAsmList
.Done
;
500 {*****************************************************************************
501 Generate Assembler Files Main Procedure
502 *****************************************************************************}
504 Procedure GenerateAsm(smart
:boolean);
513 case aktoutputformat
of
521 case aktoutputformat
of
523 b
:=new(pi386binasmlist
,Init(og_dbg
,smart
));
525 b
:=new(pi386binasmlist
,Init(og_coff
,smart
));
527 b
:=new(pi386binasmlist
,Init(og_pecoff
,smart
));
531 if assigned(current_module
^.ppufilename
) then
534 SynchronizeFileTime(current_module
^.ppufilename
^,current_module
^.staticlibfilename
^)
536 SynchronizeFileTime(current_module
^.ppufilename
^,current_module
^.objfilename
^);
545 a
:=new(pi386attasmlist
,Init(smart
));
552 a
:=new(pi386nasmasmlist
,Init(smart
));
556 a
:=new(pi386intasmlist
,Init(smart
));
563 a
:=new(pm68kgasasmlist
,Init(smart
));
567 a
:=new(pm68kmotasmlist
,Init(smart
));
571 a
:=new(pm68kmitasmlist
,Init(smart
));
575 a
:=new(pm68kmpwasmlist
,Init(smart
));
582 Message(asmw_f_assembler_output_not_supported
);
585 a
^.AsmCreate(cut_normal
);
598 a
:=new(pasmlist
,Init(false));
606 Revision 1.1 2002/02/19 08:21:28 sasu
609 Revision 1.1 2000/07/13 06:29:44 michael
612 Revision 1.65 2000/06/01 19:11:19 peter
613 * added ifdef fpc around findclose
615 Revision 1.64 2000/06/01 13:02:45 peter
616 * clean .o and .s from smartlinkpath when starting the writer
618 Revision 1.63 2000/04/04 15:05:03 pierre
619 + accept nasmwin32 output
621 Revision 1.62 2000/02/24 18:41:38 peter
622 * removed warnings/notes
624 Revision 1.61 2000/02/09 13:22:45 peter
627 Revision 1.60 2000/01/11 09:52:06 peter
628 * fixed placing of .sl directories
629 * use -b again for base-file selection
630 * fixed group writing for linux with smartlinking
632 Revision 1.59 2000/01/07 01:14:19 peter
633 * updated copyright to 2000
635 Revision 1.58 1999/11/12 11:03:49 peter
636 * searchpaths changed to stringqueue object
638 Revision 1.57 1999/11/08 10:37:12 peter
639 * filename fixes for win32 imports for units with multiple needed dll's
641 Revision 1.56 1999/11/06 14:34:17 peter
642 * truncated log to 20 revs
644 Revision 1.55 1999/11/02 15:06:57 peter
645 * import library fixes for win32
646 * alignment works again
648 Revision 1.54 1999/09/16 11:34:44 pierre
651 Revision 1.53 1999/09/02 18:47:44 daniel
652 * Could not compile with TP, some arrays moved to heap
653 * NOAG386BIN default for TP
654 * AG386* files were not compatible with TP, fixed.