1 {
2     Copyright (c) 1998-2008 by Florian Klaempfl and Peter Vreman
3 
4     Reads command line options and config files
5 
6     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10 
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15 
16     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software
18     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 
20  ****************************************************************************
21 }
22 unit options;
23 
24 {$i fpcdefs.inc}
25 
26 interface
27 
28 uses
29   cfileutl,cclasses,
30   globtype,globals,verbose,systems,cpuinfo,comprsrc;
31 
32 Type
33   TOption=class
34     FirstPass,
35     ParaLogo,
36     NoPressEnter,
37     FPCHelpLines,
38     LogoWritten,
39     ABISetExplicitly,
40     FPUSetExplicitly,
41     CPUSetExplicitly,
42     OptCPUSetExplicitly: boolean;
43     FileLevel : longint;
44     QuickInfo : string;
45     FPCBinaryPath: string;
46     ParaIncludeCfgPath,
47     ParaIncludePath,
48     ParaUnitPath,
49     ParaObjectPath,
50     ParaLibraryPath,
51     ParaFrameworkPath,
52     parapackagepath : TSearchPathList;
53     paranamespaces : TCmdStrList;
54     ParaAlignment   : TAlignmentInfo;
55     parapackages : tfphashobjectlist;
56     paratarget        : tsystem;
57     paratargetasm     : tasm;
58     paratargetdbg     : tdbg;
59     LinkTypeSetExplicitly : boolean;
60     LinkerSetExplicitly : boolean;
61     Constructor Create;
62     Destructor Destroy;override;
63     procedure WriteLogo;
64     procedure WriteInfo (More: string);
65     procedure WriteHelpPages;
66     procedure WriteQuickInfo;
67     procedure IllegalPara(const opt:TCmdStr);
68     procedure UnsupportedPara(const opt:TCmdStr);
69     procedure IgnoredPara(const opt:TCmdStr);
Unsetboolnull70     function  Unsetbool(var Opts:TCmdStr; Pos: Longint; const FullPara: TCmdStr; RequireBoolPara: Boolean):boolean;
71     procedure interpret_option(const opt :TCmdStr;ispara:boolean);
72     procedure Interpret_envvar(const envname : TCmdStr);
73     procedure Interpret_file(const filename : TPathStr);
74     procedure Read_Parameters;
75     procedure parsecmd(cmd:TCmdStr);
76     procedure TargetOptions(def:boolean);
77     procedure CheckOptionsCompatibility;
78     procedure ForceStaticLinking;
79    protected
80     MacVersionSet: boolean;
81     processorstr: TCmdStr;
ParseMacVersionMinnull82     function ParseMacVersionMin(out minstr, emptystr: string; const compvarname, value: string; ios: boolean): boolean;
83     procedure MaybeSetDefaultMacVersionMacro;
84     procedure VerifyTargetProcessor;
85   end;
86 
87   TOptionClass=class of toption;
88 
89 var
90   coption : TOptionClass;
91 
92 procedure read_arguments(cmd:TCmdStr);
93 
94 implementation
95 
96 uses
97   widestr,
98   {$if FPC_FULLVERSION<20700}ccharset{$else}charset{$endif},
99   SysUtils,
100   version,
101   cutils,cmsgs,
102   comphook,
103   symtable,scanner,rabase,
104   symconst,
105 {$ifdef llvm}
106   { override supported optimizer transformations at the compiler level }
107   llvminfo,
108 {$endif llvm}
109   dirparse,
110   pkgutil;
111 
112 const
113   page_size = 24;
114   page_width = 80;
115 
116 var
117   option     : toption;
118   read_configfile,        { read config file, set when a cfgfile is found }
119   disable_configfile : boolean;
120   fpcdir,
121   ppccfg,
122   param_file    : string;   { file to compile specified on the commandline }
123 
124 
125 {****************************************************************************
126                      Options not supported on all platforms
127 ****************************************************************************}
128 
129 const
130   { gprof (requires implementation of g_profilecode in the code generator) }
131   supported_targets_pg = [system_i386_linux,system_x86_64_linux,system_mipseb_linux,system_mipsel_linux,system_arm_linux]
132                         + [system_i386_win32]
133                         + [system_powerpc_darwin,system_x86_64_darwin]
134                         + [system_i386_GO32V2]
135                         + [system_i386_freebsd]
136                         + [system_i386_netbsd]
137                         + [system_i386_wdosx];
138 
139   suppported_targets_x_smallr = systems_linux + systems_solaris + systems_android
140                              + [system_i386_haiku,system_x86_64_haiku]
141                              + [system_i386_beos]
142                              + [system_m68k_amiga];
143 
144 {****************************************************************************
145                                  Defines
146 ****************************************************************************}
147 
148 procedure set_default_link_type;
149 begin
150   undef_system_macro('FPC_LINK_SMART');
151   def_system_macro('FPC_LINK_STATIC');
152   undef_system_macro('FPC_LINK_DYNAMIC');
153   init_settings.globalswitches:=init_settings.globalswitches+[cs_link_static];
154   init_settings.globalswitches:=init_settings.globalswitches-[cs_link_shared,cs_link_smart];
155 {$ifdef AIX}
156   init_settings.globalswitches:=init_settings.globalswitches+[cs_link_native];
157 {$endif}
158 end;
159 
160 
161 {****************************************************************************
162                                  Toption
163 ****************************************************************************}
164 
165 procedure StopOptions(err:longint);
166 begin
167   if assigned(Option) then
168    begin
169      Option.free;
170      Option:=nil;
171    end;
172   raise ECompilerAbortSilent.Create;
173 end;
174 
175 
is_identifiernull176 function is_identifier(const s: TCmdStr): boolean;
177 var
178   i: longint;
179 begin
180   result:=false;
181   if (s='') or not (s[1] in ['A'..'Z','a'..'z','_']) then
182     exit;
183   for i:=2 to length(s) do
184     if not (s[I] in ['A'..'Z','a'..'z','0'..'9','_']) then
185       exit;
186   result:=true;
187 end;
188 
189 
190 procedure Toption.WriteLogo;
191 var
192   msg : TMsgStr;
193   p : pchar;
194 begin
195   if not LogoWritten then
196     begin
197       msg:=MessageStr(option_logo);
198       p:=pchar(msg);
199       while assigned(p) do
200         Comment(V_Normal,GetMsgLine(p));
201       LogoWritten:= true;
202     end;
203 end;
204 
205 
206 procedure Toption.WriteInfo (More: string);
207 var
208   msg_str: TMsgStr;
209   p : pchar;
210   hs,hs1,hs3,s : TCmdStr;
211   J: longint;
212 const
213   NewLineStr = '$\n';
214   OSTargetsPlaceholder = '$OSTARGETS';
215   CPUListPlaceholder = '$INSTRUCTIONSETS';
216   FPUListPlaceholder = '$FPUINSTRUCTIONSETS';
217   ABIListPlaceholder = '$ABITARGETS';
218   OptListPlaceholder = '$OPTIMIZATIONS';
219   WPOListPlaceholder = '$WPOPTIMIZATIONS';
220   AsmModeListPlaceholder = '$ASMMODES';
221   ControllerListPlaceholder = '$CONTROLLERTYPES';
222   FeatureListPlaceholder = '$FEATURELIST';
223 
224   procedure SplitLine (var OrigString: TCmdStr; const Placeholder: TCmdStr;
225                                                  var RemainderString: TCmdStr);
226   var
227     I: longint;
228     HS2: TCmdStr;
229   begin
230     RemainderString := '';
231     if OrigString = '' then
232      Exit;
233     repeat
234      I := Pos (NewLineStr, OrigString);
235      if I > 0 then
236       begin
237        HS2 := Copy (OrigString, 1, Pred (I));
238 { Stop if this line contains the placeholder for list replacement }
239        if Pos (Placeholder, HS2) > 0 then
240         begin
241          RemainderString := Copy (OrigString, I + Length (NewLineStr),
242                                 Length (OrigString) - I - Length (NewLineStr));
243 { Special case - NewLineStr at the end of the line }
244          if RemainderString = '' then
245           RemainderString := NewLineStr;
246          OrigString := HS2;
247          Exit;
248         end;
249        Comment (V_Normal, HS2);
250        Delete (OrigString, 1, Pred (I) + Length (NewLineStr));
251       end;
252     until I = 0;
253     if (OrigString <> '') and (Pos (Placeholder, OrigString) = 0) then
254      Comment (V_Normal, OrigString);
255   end;
256 
257   procedure ListOSTargets (OrigString: TCmdStr);
258   var
259     target : tsystem;
260   begin
261     SplitLine (OrigString, OSTargetsPlaceholder, HS3);
262     for target:=low(tsystem) to high(tsystem) do
263     if assigned(targetinfos[target]) then
264      begin
265       hs1:=targetinfos[target]^.shortname;
266       if OrigString = '' then
267        WriteLn (hs1)
268       else
269        begin
270         hs := OrigString;
271         hs1:=hs1 + ': ' + targetinfos[target]^.name;
272         if tf_under_development in targetinfos[target]^.flags then
273          hs1:=hs1+' {*}';
274         Replace(hs,OSTargetsPlaceholder,hs1);
275         Comment(V_Normal,hs);
276        end;
277      end;
278     OrigString := HS3;
279     SplitLine (OrigString, OSTargetsPlaceholder, HS3);
280   end;
281 
282   procedure ListCPUInstructionSets (OrigString: TCmdStr);
283   var
284     cpu : tcputype;
285   begin
286     SplitLine (OrigString, CPUListPlaceholder, HS3);
287     hs1:='';
288     for cpu:=low(tcputype) to high(tcputype) do
289      begin
290       if (OrigString = '') then
291        begin
292         if CPUTypeStr [CPU] <> '' then
293          WriteLn (CPUTypeStr [CPU]);
294        end
295       else
296        begin
297         if length(hs1+cputypestr[cpu])>70 then
298          begin
299           hs:=OrigString;
300           Replace(hs,CPUListPlaceholder,hs1);
301           Comment(V_Normal,hs);
302           hs1:=''
303          end
304         else if hs1<>'' then
305          hs1:=hs1+',';
306         if cputypestr[cpu]<>'' then
307          hs1:=hs1+cputypestr[cpu];
308        end;
309      end;
310     if (OrigString <> '') and (hs1 <> '') then
311      begin
312       hs:=OrigString;
313       Replace(hs,CPUListPlaceholder,hs1);
314       Comment(V_Normal,hs);
315       hs1:=''
316      end;
317     OrigString := HS3;
318     SplitLine (OrigString, CPUListPlaceholder, HS3);
319   end;
320 
321   procedure ListFPUInstructionSets (OrigString: TCmdStr);
322   var
323     fpu : tfputype;
324   begin
325     SplitLine (OrigString, FPUListPlaceholder, HS3);
326     hs1:='';
327     for fpu:=low(tfputype) to high(tfputype) do
328      begin
329       if (OrigString = '') then
330        begin
331         if FPUTypeStr [FPU] <> '' then
332          WriteLn (FPUTypeStr [FPU]);
333        end
334       else
335        begin
336         if length(hs1+fputypestr[fpu])>70 then
337          begin
338           hs:=OrigString;
339           Replace(hs,FPUListPlaceholder,hs1);
340           Comment(V_Normal,hs);
341           hs1:=''
342          end
343         else if hs1<>'' then
344          hs1:=hs1+',';
345         if fputypestr[fpu]<>'' then
346          hs1:=hs1+fputypestr[fpu];
347        end;
348      end;
349     if (OrigString <> '') and (hs1 <> '') then
350      begin
351       hs:=OrigString;
352       Replace(hs,FPUListPlaceholder,hs1);
353       Comment(V_Normal,hs);
354       hs1:=''
355      end;
356     OrigString := HS3;
357     SplitLine (OrigString, FPUListPlaceholder, HS3);
358   end;
359 
360   procedure ListABITargets (OrigString: TCmdStr);
361   var
362     abi : tabi;
363   begin
364     SplitLine (OrigString, ABIListPlaceholder, HS3);
365     for abi:=low(abi) to high(abi) do
366      begin
367       if not abiinfo[abi].supported then
368        continue;
369       hs1:=abiinfo[abi].name;
370       if hs1<>'' then
371        begin
372         if OrigString = '' then
373          WriteLn (HS1)
374         else
375          begin
376           hs:=OrigString;
377           Replace(hs,ABIListPlaceholder,hs1);
378           Comment(V_Normal,hs);
379          end;
380        end;
381      end;
382     OrigString := HS3;
383     SplitLine (OrigString, ABIListPlaceholder, HS3);
384   end;
385 
386   procedure ListOptimizations (OrigString: TCmdStr);
387   var
388     opt : toptimizerswitch;
389   begin
390     SplitLine (OrigString, OptListPlaceholder, HS3);
391     for opt:=low(toptimizerswitch) to high(toptimizerswitch) do
392      begin
393       if opt in supported_optimizerswitches then
394        begin
395         hs1:=OptimizerSwitchStr[opt];
396         if hs1<>'' then
397          begin
398           if OrigString = '' then
399            WriteLn (hs1)
400           else
401            begin
402             hs:=OrigString;
403             Replace(hs,OptListPlaceholder,hs1);
404             Comment(V_Normal,hs);
405            end;
406          end;
407        end;
408      end;
409     OrigString := HS3;
410     SplitLine (OrigString, OptListPlaceholder, HS3);
411   end;
412 
413   procedure ListWPOptimizations (OrigString: TCmdStr);
414   var
415     wpopt: twpoptimizerswitch;
416   begin
417     SplitLine (OrigString, WPOListPlaceholder, HS3);
418     for wpopt:=low(twpoptimizerswitch) to high(twpoptimizerswitch) do
419      begin
420 {     currently all whole program optimizations are platform-independent
421       if opt in supported_wpoptimizerswitches then
422 }
423        begin
424         hs1:=WPOptimizerSwitchStr[wpopt];
425         if hs1<>'' then
426          begin
427           if OrigString = '' then
428            WriteLn (hs1)
429           else
430            begin
431             hs:=OrigString;
432             Replace(hs,WPOListPlaceholder,hs1);
433             Comment(V_Normal,hs);
434            end;
435          end;
436        end;
437      end;
438     OrigString := HS3;
439     SplitLine (OrigString, WPOListPlaceholder, HS3);
440   end;
441 
442   procedure ListAsmModes (OrigString: TCmdStr);
443   var
444     asmmode : tasmmode;
445   begin
446     SplitLine (OrigString, AsmModeListPlaceholder, HS3);
447     for asmmode:=low(tasmmode) to high(tasmmode) do
448     if assigned(asmmodeinfos[asmmode]) then
449      begin
450       hs1:=asmmodeinfos[asmmode]^.idtxt;
451       if hs1<>'' then
452        begin
453         if OrigString = '' then
454          WriteLn (hs1)
455         else
456          begin
457           hs:=OrigString;
458           Replace(hs,AsmModeListPlaceholder,hs1);
459           Comment(V_Normal,hs);
460          end;
461        end;
462      end;
463     OrigString := HS3;
464     SplitLine (OrigString, AsmModeListPlaceholder, HS3);
465   end;
466 
467   procedure ListControllerTypes (OrigString: TCmdStr);
468   var
469     controllertype : tcontrollertype;
470   begin
471 {$PUSH}
472  {$WARN 6018 OFF} (* Unreachable code due to compile time evaluation *)
473     if (ControllerSupport) then
474      begin
475       SplitLine (OrigString, ControllerListPlaceholder, HS3);
476       hs1:='';
477       for controllertype:=low(tcontrollertype) to high(tcontrollertype) do
478        begin
479         if (OrigString = '') then
480          begin
481           if Embedded_Controllers [ControllerType].ControllerTypeStr <> '' then
482            WriteLn (Embedded_Controllers [ControllerType].ControllerTypeStr);
483          end
484         else
485          begin
486           if length(hs1+embedded_controllers[controllertype].ControllerTypeStr)
487                                                                        >70 then
488            begin
489             hs:=OrigString;
490             Replace(hs,ControllerListPlaceholder,hs1);
491             Comment(V_Normal,hs);
492             hs1:=''
493            end
494           else if hs1<>'' then
495            hs1:=hs1+',';
496           if embedded_controllers[controllertype].ControllerTypeStr<>'' then
497            hs1:=hs1+embedded_controllers[controllertype].ControllerTypeStr;
498          end;
499        end;
500       if (OrigString <> '') and (hs1<>'') then
501        begin
502         hs:=OrigString;
503         Replace(hs,ControllerListPlaceholder,hs1);
504         Comment(V_Normal,hs);
505         hs1:=''
506        end;
507       OrigString := HS3;
508       SplitLine (OrigString, ControllerListPlaceholder, HS3);
509      end;
510 {$POP}
511   end;
512 
513   procedure ListFeatures (OrigString: TCmdStr);
514   var
515     Feature: TFeature;
516   begin
517     SplitLine (OrigString, FeatureListPlaceholder, HS3);
518     HS1 := '';
519     for Feature := Low (TFeature) to High (TFeature) do
520      begin
521       if (OrigString = '') then
522        begin
523         if FeatureStr [Feature] <> '' then
524          WriteLn (FeatureStr [Feature]);
525        end
526       else
527        begin
528         if Length (HS1 + FeatureStr [Feature]) > 70 then
529          begin
530           HS := OrigString;
531           Replace (HS, FeatureListPlaceholder, HS1);
532           Comment (V_Normal, HS);
533           HS1 := ''
534          end
535         else if HS1 <> '' then
536          HS1 := HS1 + ',';
537         if FeatureStr [Feature] <> '' then
538          HS1 := HS1 + FeatureStr [Feature];
539        end;
540      end;
541     if (OrigString <> '') and (HS1 <> '') then
542      begin
543       HS := OrigString;
544       Replace (HS, FeatureListPlaceholder, HS1);
545       Comment (V_Normal, HS);
546       HS1 := ''
547      end;
548     OrigString := HS3;
549     SplitLine (OrigString, FeatureListPlaceholder, HS3);
550   end;
551 
552 begin
553   if More = '' then
554    begin
555     msg_str:=MessageStr(option_info);
556     p:=pchar(msg_str);
557     while assigned(p) do
558      begin
559       s:=GetMsgLine(p);
560       { list permitted values for certain options }
561       if pos(OSTargetsPlaceholder,s)>0 then
562        ListOSTargets (S)
563       else if pos(CPUListPlaceholder,s)>0 then
564        ListCPUInstructionSets (S)
565       else if pos(FPUListPlaceholder,s)>0 then
566        ListFPUInstructionSets (S)
567       else if pos(ABIListPlaceholder,s)>0 then
568        ListABITargets (S)
569       else if pos(OptListPlaceholder,s)>0 then
570        ListOptimizations (S)
571       else if pos(WPOListPlaceholder,s)>0 then
572        ListWPOptimizations (S)
573       else if pos(AsmModeListPlaceholder,s)>0 then
574        ListAsmModes (S)
575       else if pos(ControllerListPlaceholder,s)>0 then
576        ListControllerTypes (S)
577       else if pos(FeatureListPlaceholder,s)>0 then
578        ListFeatures (S)
579       else
580        Comment(V_Normal,s);
581      end;
582    end
583   else
584    begin
585     J := 1;
586     while J <= Length (More) do
587      begin
588       if J > 1 then
589        WriteLn;  (* Put empty line between multiple sections *)
590       case More [J] of
591        'a': ListABITargets ('');
592        'c': ListCPUInstructionSets ('');
593        'f': ListFPUInstructionSets ('');
594        'i': ListAsmModes ('');
595        'o': ListOptimizations ('');
596        'r': ListFeatures ('');
597        't': ListOSTargets ('');
598        'u': ListControllerTypes ('');
599        'w': ListWPOptimizations ('');
600       else
601        IllegalPara ('-i' + More);
602       end;
603       Inc (J);
604      end;
605    end;
606   StopOptions(0);
607 end;
608 
609 
610 procedure Toption.WriteHelpPages;
611 
PadEndnull612   function PadEnd(s:string;i:longint):string;
613   begin
614     if length(s) >= i then
615      S := S + ' '
616     else
617      while (length(s)<i) do
618       s:=s+' ';
619     PadEnd:=s;
620   end;
621 
622 var
623   lastident,
624   j,outline,
625   ident,
626   HelpLineHeight,
627   lines : longint;
628   show  : boolean;
629   opt   : string[32];
630   input,
631   HelpLine,
632   s     : string;
633   p     : pchar;
634   msg_str: TMsgStr;
635 begin
636   WriteLogo;
637   Lines:=4;
638   if FPCHelpLines then
639    Message1(option_usage,FixFileName(FPCBinaryPath))
640   else
641    Message1(option_usage,FixFileName(system.paramstr(0)));
642   lastident:=0;
643   msg_str:=MessageStr(option_help_pages);
644   p:=pchar(msg_str);
645   while assigned(p) do
646    begin
647    { get a line and reset }
648      s:=GetMsgLine(p);
649      ident:=0;
650      show:=false;
651    { parse options }
652      case s[1] of
653       'F': if FPCHelpLines then
654             Show := true;
655 {$ifdef UNITALIASES}
656       'a',
657 {$endif}
658 {$ifdef EXTDEBUG}
659       'e',
660 {$endif EXTDEBUG}
661 {$ifdef i386}
662       '3',
663 {$endif}
664 {$ifdef x86_64}
665       '4',
666 {$endif}
667 {$ifdef m68k}
668       '6',
669 {$endif}
670 {$ifdef i8086}
671       '8',
672 {$endif}
673 {$ifdef aarch64}
674       'a',
675 {$endif}
676 {$ifdef arm}
677       'A',
678 {$endif}
679 {$ifdef mipsel}
680       'm',
681 {$endif}
682 {$ifdef mipseb}
683       'M',
684 {$endif}
685 {$ifdef powerpc}
686       'P',
687 {$endif}
688 {$ifdef powerpc64}
689       'p',
690 {$endif}
691 {$ifdef sparc}
692       'S',
693 {$endif}
694 {$ifdef sparc64}
695       's',
696 {$endif}
697 {$ifdef avr}
698       'V',
699 {$endif}
700 {$ifdef jvm}
701       'J',
702 {$endif}
703       '*' : show:=true;
704      end;
705      if show then
706       begin
707         case s[2] of
708          'g',
709 {$ifdef Unix}
710          'L',
711 {$endif}
712 {$ifdef os2}
713          'O',
714 {$endif}
715          '*' : show:=true;
716         else
717          show:=false;
718         end;
719       end;
720    { now we may show the message or not }
721      if show then
722       begin
723         case s[3] of
724          '0' : begin
725                  ident:=0;
726                  outline:=0;
727                end;
728          '1' : begin
729                  ident:=2;
730                  outline:=7;
731                end;
732          '2' : begin
733                  ident:=6;
734                  outline:=11;
735                end;
736          '3' : begin
737                  ident:=9;
738                  outline:=11;
739                end;
740          else
741            internalerror(2013112906);
742         end;
743         j:=pos('_',s);
744         opt:=Copy(s,4,j-4);
745         if opt='*' then
746          opt:=''
747         else
748         if (opt=' ') or (opt[1]='@') then
749          opt:=PadEnd(opt,outline)
750         else
751          opt:=PadEnd('-'+opt,outline);
752         if (ident=0) and (lastident<>0) then
753          begin
754            Comment(V_Normal,'');
755            inc(Lines);
756          end;
757         HelpLine := PadEnd('',ident)+opt+Copy(s,j+1,255);
758         if HelpLine = '' then
759          HelpLineHeight := 1
760         else
761          HelpLineHeight := Succ (CharLength (HelpLine) div Page_Width);
762       { page full ? }
763         if (lines + HelpLineHeight >= page_size - 1) then
764          begin
765            if not NoPressEnter then
766             begin
767               Message(option_help_press_enter);
768               readln(input);
769               if upper(input)='Q' then
770                StopOptions(0);
771             end;
772            lines:=0;
773          end;
774         Comment(V_Normal,HelpLine);
775         LastIdent:=Ident;
776         Inc (Lines, HelpLineHeight);
777       end;
778    end;
779   StopOptions(0);
780 end;
781 
782 
783 procedure Toption.IllegalPara(const opt:TCmdStr);
784 begin
785   Message1(option_illegal_para,opt);
786   Message(option_help_pages_para);
787   StopOptions(1);
788 end;
789 
790 
791 procedure toption.UnsupportedPara(const opt: TCmdStr);
792 begin
793   Message1(option_unsupported_target,opt);
794   StopOptions(1);
795 end;
796 
797 
798 procedure toption.IgnoredPara(const opt: TCmdStr);
799 begin
800   Message1(option_ignored_target,opt);
801 end;
802 
803 
804 procedure toption.ForceStaticLinking;
805 begin
806   def_system_macro('FPC_LINK_STATIC');
807   undef_system_macro('FPC_LINK_SMART');
808   undef_system_macro('FPC_LINK_DYNAMIC');
809   include(init_settings.globalswitches,cs_link_static);
810   exclude(init_settings.globalswitches,cs_link_smart);
811   exclude(init_settings.globalswitches,cs_link_shared);
812   LinkTypeSetExplicitly:=true;
813 end;
814 
815 
toption.ParseMacVersionMinnull816 function toption.ParseMacVersionMin(out minstr, emptystr: string; const compvarname, value: string; ios: boolean): boolean;
817 
subvalnull818   function subval(start,maxlen: longint; out stop: longint): string;
819     var
820       i: longint;
821     begin
822       result:='';
823       i:=start;
824       while (i<=length(value)) and
825             (value[i] in ['0'..'9']) do
826         inc(i);
827       { sufficient amount of digits? }
828       if (i=start) or
829          (i-start>maxlen) then
830         exit;
831       result:=copy(value,start,i-start);
832       stop:=i;
833     end;
834 
835   var
836     temp,
837     compvarvalue: string[15];
838     i: longint;
839     osx_minor_two_digits: boolean;
840   begin
841     minstr:=value;
842     emptystr:='';
843     MacVersionSet:=false;
844     { check whether the value is a valid version number }
845     if value='' then
846       begin
847         undef_system_macro(compvarname);
848         exit(true);
849       end;
850     { major version number }
851     compvarvalue:=subval(1,2,i);
852     { not enough digits -> invalid }
853     if compvarvalue='' then
854       exit(false);
855     { already end of string -> invalid }
856     if (i>=length(value)) or
857        (value[i]<>'.') then
858       exit(false);
859     { minor version number }
860     temp:=subval(i+1,2,i);
861     if temp='' then
862       exit(false);
863     { on Mac OS X, the minor version number was originally limited to 1 digit;
864       with 10.10 the format changed and two digits were also supported; on iOS,
865       the minor version number always takes up two digits }
866     osx_minor_two_digits:=false;
867     if not ios then
868       begin
869         { if the minor version number is two digits on OS X (the case since
870           OS X 10.10), we also have to add two digits for the patch level}
871         if length(temp)=2 then
872           osx_minor_two_digits:=true;
873       end
874     { the minor version number always takes up two digits on iOS }
875     else if length(temp)=1 then
876       temp:='0'+temp;
877     compvarvalue:=compvarvalue+temp;
878     { optional patch level }
879     if i<=length(value) then
880       begin
881         if value[i]<>'.' then
882           exit(false);
883         temp:=subval(i+1,2,i);
884         if temp='' then
885           exit(false);
886         { there's only room for a single digit patch level in the version macro
887           for Mac OS X. gcc sets it to zero if there are more digits, but that
888           seems worse than clamping to 9 (don't declare as invalid like with
889           minor version number, because there is a precedent like 10.4.11).
890 
891           As of OS X 10.10 there are two digits for the patch level
892         }
893         if not ios and
894            not osx_minor_two_digits then
895           begin
896             if length(temp)<>1 then
897               temp:='9';
898           end
899         else
900           begin
901             { on iOS, the patch level is always two digits }
902             if length(temp)=1 then
903               temp:='0'+temp;
904           end;
905         compvarvalue:=compvarvalue+temp;
906         { must be the end }
907         if i<=length(value) then
908           exit(false);
909       end
910     else if not ios and
911        not osx_minor_two_digits then
912       compvarvalue:=compvarvalue+'0'
913     else
914       compvarvalue:=compvarvalue+'00';
915     set_system_compvar(compvarname,compvarvalue);
916     MacVersionSet:=true;
917     result:=true;
918   end;
919 
920 
921 procedure TOption.MaybeSetDefaultMacVersionMacro;
922 var
923   envstr: ansistring;
924 begin
925   if not(target_info.system in systems_darwin) then
926     exit;
927   if MacVersionSet then
928     exit;
929   { check for deployment target set via environment variable }
930   if not(target_info.system in [system_i386_iphonesim,system_arm_ios,system_aarch64_ios,system_x86_64_iphonesim]) then
931     begin
932       envstr:=GetEnvironmentVariable('MACOSX_DEPLOYMENT_TARGET');
933       if envstr<>'' then
934         if not ParseMacVersionMin(MacOSXVersionMin,iPhoneOSVersionMin,'MAC_OS_X_VERSION_MIN_REQUIRED',envstr,false) then
935           Message1(option_invalid_macosx_deployment_target,envstr)
936         else
937           begin
938 {$ifdef llvm}
939              { We only support libunwind as part of libsystem, which happened in Mac OS X 10.6 }
940             if CompareVersionStrings(MacOSXVersionMin,'10.6')<=0 then
941               Message1(option_invalid_macosx_deployment_target,envstr);
942 {$endif}
943             exit;
944           end;
945     end
946   else
947     begin
948       envstr:=GetEnvironmentVariable('IPHONEOS_DEPLOYMENT_TARGET');
949       if envstr<>'' then
950         if not ParseMacVersionMin(iPhoneOSVersionMin,MacOSXVersionMin,'IPHONE_OS_VERSION_MIN_REQUIRED',envstr,true) then
951           Message1(option_invalid_iphoneos_deployment_target,envstr)
952         else
953           exit;
954     end;
955   { nothing specified -> defaults }
956   case target_info.system of
957     system_powerpc_darwin:
958       begin
959         set_system_compvar('MAC_OS_X_VERSION_MIN_REQUIRED','1030');
960         MacOSXVersionMin:='10.3.0';
961       end;
962     system_powerpc64_darwin:
963       begin
964         set_system_compvar('MAC_OS_X_VERSION_MIN_REQUIRED','1040');
965         MacOSXVersionMin:='10.4.0';
966       end;
967     system_i386_darwin,
968     system_x86_64_darwin:
969       begin
970         set_system_compvar('MAC_OS_X_VERSION_MIN_REQUIRED','1080');
971         MacOSXVersionMin:='10.8.0';
972       end;
973     system_arm_ios,
974     system_i386_iphonesim:
975       begin
976         set_system_compvar('IPHONE_OS_VERSION_MIN_REQUIRED','90000');
977         iPhoneOSVersionMin:='9.0.0';
978       end;
979     system_aarch64_ios,
980     system_x86_64_iphonesim:
981       begin
982         set_system_compvar('IPHONE_OS_VERSION_MIN_REQUIRED','90000');
983         iPhoneOSVersionMin:='9.0.0';
984       end;
985     system_aarch64_darwin:
986       begin
987         set_system_compvar('MAC_OS_X_VERSION_MIN_REQUIRED','110000');
988         MacOSXVersionMin:='11.0.0';
989       end
990     else
991       internalerror(2012031001);
992   end;
993 end;
994 
995 procedure TOption.VerifyTargetProcessor;
996   begin
997     { no custom target processor specified -> ok }
998     if processorstr='' then
999       exit;
1000     { custom target processor specified -> verify it's the one we support }
1001     if upcase(processorstr)<>upcase(target_cpu_string) then
1002       Message1(option_invalid_target_architecture,processorstr);
1003   end;
1004 
1005 
Unsetboolnull1006 function Toption.Unsetbool(var Opts:TCmdStr; Pos: Longint; const FullPara: TCmdStr; RequireBoolPara: boolean):boolean;
1007 { checks if the character after pos in Opts is a + or a - and returns resp.
1008   false or true. If it is another character (or none), it also returns false }
1009 begin
1010   UnsetBool := false;
1011   if Length(Opts)>Pos then
1012    begin
1013     inc(Pos);
1014     UnsetBool := Opts[Pos] = '-';
1015     if Opts[Pos] in ['-','+']then
1016      delete(Opts,Pos,1)
1017     else if RequireBoolPara then
1018      IllegalPara(FullPara);
1019    end;
1020 end;
1021 
1022 procedure TOption.interpret_option(const opt:TCmdStr;ispara:boolean);
1023 var
1024   code : integer;
1025   c    : char;
1026   more : TCmdStr;
1027   major,minor : longint;
1028   error : integer;
1029   j,l   : longint;
1030   d,s   : TCmdStr;
1031   hs    : TCmdStr;
1032   unicodemapping : punicodemap;
1033 begin
1034   if opt='' then
1035    exit;
1036 
1037   { only parse define,undef,target,verbosity,link etc options the firsttime
1038     -Us must now also be first-passed to avoid rejection of -Sf options
1039     earlier in command line }
1040   if firstpass and
1041      not(
1042          (opt[1]='-') and
1043          (
1044           ((length(opt)>1) and (opt[2] in ['i','d','v','T','u','n','X','l','U'])) or
1045           ((length(opt)>3) and (opt[2]='F') and (opt[3]='e')) or
1046           ((length(opt)>3) and (opt[2]='C') and (opt[3]='p')) or
1047           ((length(opt)>3) and (opt[2]='W') and (opt[3] in ['m','p']))
1048          )
1049         ) then
1050     exit;
1051 
1052   Message1(option_handling_option,opt);
1053   case opt[1] of
1054     '-' :
1055       begin
1056          more:=Copy(opt,3,2147483647);
1057          if firstpass then
1058            Message1(option_interpreting_firstpass_option,opt)
1059          else
1060            Message1(option_interpreting_option,opt);
1061          case opt[2] of
1062            '?' :
1063              begin
1064                if (More <> '') and (More [1] = 'F') then
1065                  begin
1066                    FPCHelpLines := true;
1067                    Delete (More, 1, 1);
1068                    FPCBinaryPath := More;
1069                  end;
1070                WriteHelpPages;
1071              end;
1072 
1073            'a' :
1074              begin
1075                include(init_settings.globalswitches,cs_asm_leave);
1076                j:=1;
1077                while j<=length(more) do
1078                 begin
1079                   case more[j] of
1080                     '5' :
1081                       if target_info.system in systems_all_windows+systems_nativent-[system_i8086_win16] then
1082                         begin
1083                           if UnsetBool(More, j, opt, false) then
1084                             exclude(init_settings.globalswitches,cs_asm_pre_binutils_2_25)
1085                           else
1086                             include(init_settings.globalswitches,cs_asm_pre_binutils_2_25);
1087                         end
1088                       else
1089                         IllegalPara(opt);
1090                     'l' :
1091                       include(init_settings.globalswitches,cs_asm_source);
1092                     'r' :
1093                       include(init_settings.globalswitches,cs_asm_regalloc);
1094                     't' :
1095                       include(init_settings.globalswitches,cs_asm_tempalloc);
1096                     'n' :
1097                       include(init_settings.globalswitches,cs_asm_nodes);
1098                     { -ao option must be the last, everything behind it is passed directly to
1099                       external assembler, it is ignored if internal assembler is used. }
1100                     'o' :
1101                       begin
1102                         asmextraopt:=copy(more,j+1,length(more)-j);
1103                         break;
1104                       end;
1105                     'p' :
1106                       begin
1107                         exclude(init_settings.globalswitches,cs_asm_leave);
1108                         if UnsetBool(More, 0, opt, false) then
1109                           exclude(init_settings.globalswitches,cs_asm_pipe)
1110                         else
1111                           include(init_settings.globalswitches,cs_asm_pipe);
1112                       end;
1113                     '-' :
1114                       init_settings.globalswitches:=init_settings.globalswitches -
1115                           [cs_asm_leave, cs_asm_source,cs_asm_regalloc, cs_asm_tempalloc,
1116                            cs_asm_nodes, cs_asm_pipe];
1117                     else
1118                       IllegalPara(opt);
1119                   end;
1120                   inc(j);
1121                 end;
1122              end;
1123 
1124            'A' :
1125              begin
1126                paratargetasm:=find_asm_by_string(More);
1127                if paratargetasm=as_none then
1128                  IllegalPara(opt);
1129              end;
1130 
1131            'b' :
1132              begin
1133                // Message1(option_obsolete_switch,'-b');
1134                if UnsetBool(More,0,opt,false) then
1135                  begin
1136                    init_settings.moduleswitches:=init_settings.moduleswitches-[cs_browser];
1137                    init_settings.moduleswitches:=init_settings.moduleswitches-[cs_local_browser];
1138                  end
1139                else
1140                  begin
1141                    init_settings.moduleswitches:=init_settings.moduleswitches+[cs_browser];
1142                  end;
1143                if More<>'' then
1144                  if (More='l') or (More='l+') then
1145                    init_settings.moduleswitches:=init_settings.moduleswitches+[cs_local_browser]
1146                  else if More='l-' then
1147                    init_settings.moduleswitches:=init_settings.moduleswitches-[cs_local_browser]
1148                  else
1149                    IllegalPara(opt);
1150              end;
1151 
1152            'B' :
1153              do_build:=not UnSetBool(more,0,opt,true);
1154 
1155            'C' :
1156              begin
1157                j:=1;
1158                while j<=length(more) do
1159                 begin
1160                   case more[j] of
1161                     '3' :
1162                       If UnsetBool(More, j, opt, false) then
1163                         exclude(init_settings.localswitches,cs_ieee_errors)
1164                       Else
1165                         include(init_settings.localswitches,cs_ieee_errors);
1166                     'a' :
1167                       begin
1168                         s:=upper(copy(more,j+1,length(more)-j));
1169                         if not(SetAbiType(s,target_info.abi)) then
1170                           IllegalPara(opt);
1171                         ABISetExplicitly:=true;
1172                         break;
1173                       end;
1174 
1175                     'b' :
1176                        begin
1177                          if UnsetBool(More, j, opt, false) then
1178                            target_info.endian:=endian_little
1179                          else
1180                            target_info.endian:=endian_big;
1181                        end;
1182 
1183                     'c' :
1184                        begin
1185                          if not SetAktProcCall(upper(copy(more,j+1,length(more)-j)),init_settings.defproccall) then
1186                           IllegalPara(opt);
1187                          break;
1188                        end;
1189 {$ifdef cpufpemu}
1190                     'e' :
1191                        begin
1192                          If UnsetBool(More, j, opt, false) then
1193                            exclude(init_settings.moduleswitches,cs_fp_emulation)
1194                          Else
1195                            include(init_settings.moduleswitches,cs_fp_emulation);
1196                        end;
1197 {$endif cpufpemu}
1198                     'E' :
1199                       If UnsetBool(More, j, opt, false) then
1200                         exclude(init_settings.localswitches,cs_check_fpu_exceptions)
1201                       Else
1202                         include(init_settings.localswitches,cs_check_fpu_exceptions);
1203                     'f' :
1204                       begin
1205                         s:=upper(copy(more,j+1,length(more)-j));
1206                         if not(SetFpuType(s,init_settings.fputype)) then
1207                           IllegalPara(opt);
1208                         FPUSetExplicitly:=True;
1209                         break;
1210                       end;
1211                     'F' :
1212                        begin
1213                          if not SetMinFPConstPrec(copy(more,j+1,length(more)-j),init_settings.minfpconstprec) then
1214                            IllegalPara(opt);
1215                          break;
1216                        end;
1217                     'g' :
1218                        begin
1219                          if tf_no_pic_supported in target_info.flags then
1220                            begin
1221                              { consume a possible '-' coming after it }
1222                              UnsetBool(More, j, opt, false);
1223                              message(scan_w_pic_ignored);
1224                            end
1225                          else if UnsetBool(More, j, opt, false) then
1226                            exclude(init_settings.moduleswitches,cs_create_pic)
1227                          else
1228                            include(init_settings.moduleswitches,cs_create_pic);
1229                       end;
1230                     'h' :
1231                       begin
1232                          l:=pos(',',copy(more,j+1,length(more)-j));
1233                          if l=0 then
1234                            l:=length(more)-j+1;
1235                          val(copy(more,j+1,l-1),heapsize,code);
1236                          if (code<>0)
1237 {$ifdef AVR}
1238                          or (heapsize<32)
1239 {$else AVR}
1240                          or (heapsize<1024)
1241 {$endif AVR}
1242                          then
1243                            IllegalPara(opt)
1244                          else if l<=length(more)-j then
1245                            begin
1246                              val(copy(more,j+l+1,length(more)),maxheapsize,code);
1247                              if code<>0 then
1248                                IllegalPara(opt)
1249                              else if (maxheapsize<heapsize) then
1250                                begin
1251                                  message(scan_w_heapmax_lessthan_heapmin);
1252                                  maxheapsize:=heapsize;
1253                                end;
1254                            end;
1255                          break;
1256                       end;
1257                     'i' :
1258                       If UnsetBool(More, j, opt, false) then
1259                         exclude(init_settings.localswitches,cs_check_io)
1260                       else
1261                         include(init_settings.localswitches,cs_check_io);
1262 {$ifdef arm}
1263                     'I' :
1264                       begin
1265                         if (upper(copy(more,j+1,length(more)-j))='THUMB') and
1266                           { does selected CPU really understand thumb? }
1267                           (init_settings.cputype in cpu_has_thumb) then
1268                           init_settings.instructionset:=is_thumb
1269                         else if upper(copy(more,j+1,length(more)-j))='ARM' then
1270                           init_settings.instructionset:=is_arm
1271                         else
1272                           IllegalPara(opt);
1273                         break;
1274                       end;
1275 {$endif arm}
1276                     'n' :
1277                       If UnsetBool(More, j, opt, false) then
1278                         exclude(init_settings.globalswitches,cs_link_nolink)
1279                       Else
1280                         include(init_settings.globalswitches,cs_link_nolink);
1281                     'N' :
1282                       If UnsetBool(More, j, opt, false) then
1283                         exclude(init_settings.localswitches,cs_check_low_addr_load)
1284                       Else
1285                         include(init_settings.localswitches,cs_check_low_addr_load);
1286                     'o' :
1287                       If UnsetBool(More, j, opt, false) then
1288                         exclude(init_settings.localswitches,cs_check_overflow)
1289                       Else
1290                         include(init_settings.localswitches,cs_check_overflow);
1291                     'O' :
1292                       If UnsetBool(More, j, opt, false) then
1293                         exclude(init_settings.localswitches,cs_check_ordinal_size)
1294                       Else
1295                         include(init_settings.localswitches,cs_check_ordinal_size);
1296                     'p' :
1297                       begin
1298                         s:=upper(copy(more,j+1,length(more)-j));
1299                         if not(Setcputype(s,init_settings)) then
1300                           IllegalPara(opt);
1301                         CPUSetExplicitly:=true;
1302                         break;
1303                       end;
1304                     'P':
1305                       begin
1306                         delete(more,1,1);
1307                         case upper(copy(more,1,pos('=',more)-1)) of
1308                           'PACKSET':
1309                             begin
1310                               delete(more,1,pos('=',more));
1311                               case more of
1312                                 '0','DEFAULT','NORMAL':
1313                                   init_settings.setalloc:=0;
1314                                 '1','2','4','8':
1315                                   init_settings.setalloc:=StrToInt(more);
1316                                 else
1317                                   IllegalPara(opt);
1318                               end
1319                             end;
1320                           'PACKENUM':
1321                             begin
1322                               delete(more,1,pos('=',more));
1323                               case more of
1324                                 '0','DEFAULT','NORMAL':
1325                                   init_settings.packenum:=4;
1326                                 '1','2','4':
1327                                   init_settings.packenum:=StrToInt(more);
1328                                 else
1329                                   IllegalPara(opt);
1330                               end;
1331                             end;
1332                           'PACKRECORD':
1333                             begin
1334                               delete(more,1,pos('=',more));
1335                               case more of
1336                                 '0','DEFAULT','NORMAL':
1337                                   init_settings.packrecords:=default_settings.packrecords;
1338                                 '1','2','4','8','16','32':
1339                                   init_settings.packrecords:=StrToInt(more);
1340                                 else
1341                                   IllegalPara(opt);
1342                               end;
1343                             end
1344                           else
1345                             IllegalPara(opt);
1346                         end;
1347                       end;
1348                     'r' :
1349                       If UnsetBool(More, j, opt, false) then
1350                         exclude(init_settings.localswitches,cs_check_range)
1351                       Else
1352                         include(init_settings.localswitches,cs_check_range);
1353                     'R' :
1354                       If UnsetBool(More, j, opt, false) then
1355                         begin
1356                           exclude(init_settings.localswitches,cs_check_range);
1357                           exclude(init_settings.localswitches,cs_check_object);
1358                         end
1359                       Else
1360                         begin
1361                           include(init_settings.localswitches,cs_check_range);
1362                           include(init_settings.localswitches,cs_check_object);
1363                         end;
1364                     's' :
1365                       begin
1366                          val(copy(more,j+1,length(more)-j),stacksize,code);
1367                          if (code<>0)
1368 {$ifdef cpu16bitaddr}
1369                             or (stacksize>=65521)
1370 {$else cpu16bitaddr}
1371                             or (stacksize>=67107840)
1372 {$endif cpu16bitaddr}
1373                             or (stacksize<1024) then
1374                           IllegalPara(opt);
1375                          break;
1376                       end;
1377                     't' :
1378                        If UnsetBool(More, j, opt, false) then
1379                          exclude(init_settings.localswitches,cs_check_stack)
1380                        Else
1381                          include(init_settings.localswitches,cs_check_stack);
1382                     'D' :
1383                        If UnsetBool(More, j, opt, false) then
1384                          exclude(init_settings.moduleswitches,cs_create_dynamic)
1385                        Else
1386                          include(init_settings.moduleswitches,cs_create_dynamic);
1387                     'X' :
1388                        If UnsetBool(More, j, opt, false) then
1389                          exclude(init_settings.moduleswitches,cs_create_smart)
1390                        Else
1391                          include(init_settings.moduleswitches,cs_create_smart);
1392                     'T' :
1393                       begin
1394                         if not UpdateTargetSwitchStr(copy(more,j+1,length(more)),init_settings.targetswitches,true) then
1395                           IllegalPara(opt);
1396                         break;
1397                       end;
1398                     'v' :
1399                        If target_info.system in systems_jvm then
1400                          If UnsetBool(More, j, opt, false) then
1401                            exclude(init_settings.localswitches,cs_check_var_copyout)
1402                          Else
1403                            include(init_settings.localswitches,cs_check_var_copyout)
1404                        else
1405                          IllegalPara(opt)
1406                     else
1407                        IllegalPara(opt);
1408                   end;
1409                   inc(j);
1410                 end;
1411              end;
1412 
1413            'd' :
1414              begin
1415                l:=Pos(':=',more);
1416                if l>0 then
1417                  hs:=copy(more,1,l-1)
1418                else
1419                  hs:=more;
1420                if (not is_identifier(hs)) then
1421                  begin
1422                    if hs='' then
1423                      Message1(option_missing_arg,'-d')
1424                    else
1425                      Message1(option_malformed_para,opt);
1426                    StopOptions(1);
1427                  end;
1428                if l>0 then
1429                  begin
1430                    if cs_support_macro in init_settings.moduleswitches then
1431                      set_system_macro(hs,Copy(more,l+2,255))
1432                    else
1433                      set_system_compvar(hs,Copy(more,l+2,255));
1434                  end
1435                else
1436                  def_system_macro(hs);
1437              end;
1438            'D' :
1439              begin
1440                include(init_settings.globalswitches,cs_link_deffile);
1441                j:=1;
1442                while j<=length(more) do
1443                 begin
1444                   case more[j] of
1445                     'd' :
1446                       begin
1447                         description:=Copy(more,j+1,255);
1448                         break;
1449                       end;
1450                     'v' :
1451                       begin
1452                         dllversion:=Copy(more,j+1,255);
1453                         l:=pos('.',dllversion);
1454                         dllminor:=0;
1455                         error:=0;
1456                         if l>0 then
1457                          begin
1458                            val(copy(dllversion,l+1,255),minor,error);
1459                            if (error=0) and
1460                               (minor>=0) and (minor<=$ffff) then
1461                              dllminor:=minor
1462                            else
1463                              if error=0 then
1464                                error:=1;
1465                          end;
1466                         if l=0 then
1467                           l:=256;
1468                         dllmajor:=1;
1469                         major:=0;
1470                         if error=0 then
1471                           val(copy(dllversion,1,l-1),major,error);
1472                         if (error=0) and (major>=0) and (major<=$ffff) then
1473                           dllmajor:=major
1474                         else
1475                           if error=0 then
1476                             error:=1;
1477                         if error<>0 then
1478                           Message1(scan_w_wrong_version_ignored,dllversion);
1479                         break;
1480                       end;
1481                     'w' :
1482                       usewindowapi:=true;
1483                     '-' :
1484                       begin
1485                         exclude(init_settings.globalswitches,cs_link_deffile);
1486                         usewindowapi:=false;
1487                       end;
1488                     else
1489                       IllegalPara(opt);
1490                   end;
1491                   inc(j);
1492                 end;
1493              end;
1494 
1495            'e' :
1496              exepath:=FixPath(More,true);
1497 
1498            'E' :
1499              begin
1500                if UnsetBool(More, 0, opt, true) then
1501                  exclude(init_settings.globalswitches,cs_link_nolink)
1502                else
1503                  include(init_settings.globalswitches,cs_link_nolink);
1504              end;
1505 
1506            'f' :
1507              begin
1508                if more='PIC' then
1509                  begin
1510                    if tf_no_pic_supported in target_info.flags then
1511                      message(scan_w_pic_ignored)
1512                    else
1513                      include(init_settings.moduleswitches,cs_create_pic)
1514                  end
1515                else
1516                  IllegalPara(opt);
1517              end;
1518 
1519            'F' :
1520              begin
1521                if more='' then
1522                  IllegalPara(opt);
1523                c:=more[1];
1524                Delete(more,1,1);
1525                DefaultReplacements(More);
1526                case c of
1527                  'a' :
1528                    autoloadunits:=more;
1529                  'c' :
1530                    begin
1531                      { if we first specify that the system code page should be
1532                        used and then explicitly specify a code page, unset the
1533                        flag that we're using the system code page again }
1534                      SetCompileModeSwitch('SYSTEMCODEPAGE-',true);
1535                      if (upper(more)='UTF8') or (upper(more)='UTF-8') then
1536                        init_settings.sourcecodepage:=CP_UTF8
1537                      else if not(cpavailable(more)) then
1538                        Message1(option_code_page_not_available,more)
1539                      else
1540                        init_settings.sourcecodepage:=codepagebyname(more);
1541                      include(init_settings.moduleswitches,cs_explicit_codepage);
1542                    end;
1543                  'C' :
1544                    RCCompiler:=More;
1545                  'd' :
1546                    if UnsetBool(more, 0, opt, true) then
1547                      init_settings.disabledircache:=false
1548                    else
1549                      init_settings.disabledircache:=true;
1550                  'D' :
1551                    utilsdirectory:=FixPath(More,true);
1552                  'e' :
1553                    SetRedirectFile(More);
1554                  'E' :
1555                    OutputExeDir:=FixPath(More,true);
1556                  'f' :
1557                      if (target_info.system in systems_darwin) then
1558                        if ispara then
1559                          ParaFrameworkPath.AddPath(More,false)
1560                        else
1561                          frameworksearchpath.AddPath(More,true)
1562                      else
1563                        IllegalPara(opt);
1564                  'i' :
1565                    begin
1566                      if ispara then
1567                        ParaIncludePath.AddPath(More,false)
1568                      else
1569                        includesearchpath.AddPath(More,true);
1570                    end;
1571                  'm' :
1572                    begin
1573                      s:=ExtractFileDir(more);
1574                      if TryStrToInt(ExtractFileName(more),j) then
1575                        begin
1576                          unicodemapping:=loadunicodemapping(More,More+'.txt',j);
1577                          if assigned(unicodemapping) then
1578                            registermapping(unicodemapping)
1579                          else
1580                            IllegalPara(opt);
1581                        end
1582                      else
1583                        IllegalPara(opt);
1584                    end;
1585                  'M' :
1586                    unicodepath:=FixPath(More,true);
1587                  'g' :
1588                    Message2(option_obsolete_switch_use_new,'-Fg','-Fl');
1589                  'l' :
1590                    begin
1591                      if ispara then
1592                        ParaLibraryPath.AddLibraryPath(sysrootpath,More,false)
1593                      else
1594                        LibrarySearchPath.AddLibraryPath(sysrootpath,More,true)
1595                    end;
1596                  'L' :
1597                    begin
1598                      if More<>'' then
1599                        ParaDynamicLinker:=More
1600                      else
1601                        IllegalPara(opt);
1602                    end;
1603                  'N' :
1604                    begin
1605                      if more<>'' then
1606                        paranamespaces.insert(more)
1607                      else
1608                        illegalpara(opt);
1609                    end;
1610                  'o' :
1611                    begin
1612                      if ispara then
1613                        ParaObjectPath.AddPath(More,false)
1614                      else
1615                        ObjectSearchPath.AddPath(More,true);
1616                    end;
1617                  'P' :
1618                    begin
1619                      if ispara then
1620                        parapackages.add(more,nil)
1621                      else
1622                        add_package(more,true,true);
1623                    end;
1624                  'p' :
1625                    begin
1626                      if ispara then
1627                        parapackagepath.AddPath(More,false)
1628                      else
1629                        packagesearchpath.AddPath(More,true);
1630                    end;
1631                  'r' :
1632                    Msgfilename:=More;
1633                  'R' :
1634                    ResCompiler:=More;
1635                  'u' :
1636                    begin
1637                      if ispara then
1638                        ParaUnitPath.AddPath(More,false)
1639                      else
1640                        unitsearchpath.AddPath(More,true);
1641                    end;
1642                  'U' :
1643                    OutputUnitDir:=FixPath(More,true);
1644                  'W',
1645                  'w':
1646                    begin
1647                      if More<>'' then
1648                        begin
1649                          DefaultReplacements(More);
1650                          D:=ExtractFilePath(More);
1651                          if (D<>'') then
1652                            D:=FixPath(D,True);
1653                          D:=D+ExtractFileName(More);
1654                          if (c='W') then
1655                            WpoFeedbackOutput:=D
1656                          else
1657                            WpoFeedbackInput:=D;
1658                        end
1659                      else
1660                        IllegalPara(opt);
1661                    end;
1662                  else
1663                    IllegalPara(opt);
1664                end;
1665              end;
1666 
1667            'g' :
1668              begin
1669                if UnsetBool(More, 0, opt, false) then
1670                 begin
1671                   exclude(init_settings.moduleswitches,cs_debuginfo);
1672                   exclude(init_settings.globalswitches,cs_use_heaptrc);
1673                   exclude(init_settings.globalswitches,cs_use_lineinfo);
1674                   exclude(init_settings.localswitches,cs_checkpointer);
1675                   localvartrashing := -1;
1676                 end
1677                else
1678                 begin
1679                   include(init_settings.moduleswitches,cs_debuginfo);
1680                   if paratargetdbg=dbg_none then
1681                     paratargetdbg:=target_info.dbg;
1682                 end;
1683                if not RelocSectionSetExplicitly then
1684                  RelocSection:=false;
1685                j:=1;
1686                while j<=length(more) do
1687                  begin
1688                    case more[j] of
1689                      'c' :
1690                        begin
1691                          if UnsetBool(More, j, opt, false) then
1692                            exclude(init_settings.localswitches,cs_checkpointer)
1693                          else if (target_info.system in systems_support_checkpointer) then
1694                            begin
1695                              if do_release then
1696                                Message(option_gc_incompatible_with_release_flag)
1697                              else
1698                                include(init_settings.localswitches,cs_checkpointer);
1699                            end
1700                          else
1701                            UnsupportedPara('-gc');
1702                        end;
1703                      'h' :
1704                        begin
1705                          if UnsetBool(More, j, opt, false) then
1706                            exclude(init_settings.globalswitches,cs_use_heaptrc)
1707                          else begin
1708                            if cs_gdb_valgrind in init_settings.globalswitches then
1709                              Message2(option_valgrind_heaptrc_mismatch,'-gh', '-gv');
1710                            include(init_settings.globalswitches,cs_use_heaptrc);
1711                          end;
1712                        end;
1713                      'l' :
1714                        begin
1715                          if UnsetBool(More, j, opt, false) then
1716                            exclude(init_settings.globalswitches,cs_use_lineinfo)
1717                          else
1718                            include(init_settings.globalswitches,cs_use_lineinfo);
1719                        end;
1720                      'm' :
1721                        begin
1722                          paratargetdbg:=dbg_codeview;
1723                        end;
1724                      'o' :
1725                        begin
1726                          if not UpdateDebugStr(copy(more,j+1,length(more)),init_settings.debugswitches) then
1727                            IllegalPara(opt);
1728                          break;
1729                        end;
1730                      'p' :
1731                        begin
1732                          if UnsetBool(More, j, opt, false) then
1733                            exclude(init_settings.globalswitches,cs_stabs_preservecase)
1734                          else
1735                            include(init_settings.globalswitches,cs_stabs_preservecase);
1736                        end;
1737                      's' :
1738                        begin
1739                          paratargetdbg:=dbg_stabs;
1740                        end;
1741                      't' :
1742                        begin
1743                          if UnsetBool(More, j, opt, false) then
1744                             localvartrashing := -1
1745                          else
1746                            localvartrashing := (localvartrashing + 1) mod nroftrashvalues;
1747                        end;
1748                      'v' :
1749                        begin
1750                          if UnsetBool(More, j, opt, false) then
1751                            exclude(init_settings.globalswitches,cs_gdb_valgrind)
1752                          else begin
1753                            if cs_use_heaptrc in init_settings.globalswitches then
1754                              Message2(option_valgrind_heaptrc_mismatch,'-gh', '-gv');
1755                            include(init_settings.globalswitches,cs_gdb_valgrind);
1756                          end;
1757                        end;
1758                      'w' :
1759                        begin
1760                          if (j<length(more)) and (more[j+1] in ['2','3','4']) then
1761                            begin
1762                              case more[j+1] of
1763                                '2': paratargetdbg:=dbg_dwarf2;
1764                                '3': paratargetdbg:=dbg_dwarf3;
1765                                '4': paratargetdbg:=dbg_dwarf4;
1766                              end;
1767                              inc(j);
1768                            end
1769                          else
1770                            paratargetdbg:=dbg_dwarf2;
1771                        end;
1772                      else
1773                        IllegalPara(opt);
1774                    end;
1775                    inc(j);
1776                  end;
1777              end;
1778 
1779            'h' :
1780              begin
1781                NoPressEnter:=true;
1782                if (More <> '') and (More [1] = 'F') then
1783                  begin
1784                    FPCHelpLines := true;
1785                    Delete (More, 1, 1);
1786                    FPCBinaryPath := More;
1787                  end;
1788                WriteHelpPages;
1789              end;
1790 
1791            'i' :
1792              begin
1793                if (More='') or
1794                     (More [1] in ['a', 'c', 'f', 'i', 'o', 'r', 't', 'u', 'w']) then
1795                  WriteInfo (More)
1796                else
1797                  QuickInfo:=QuickInfo+More;
1798              end;
1799 
1800            'I' :
1801              begin
1802                if ispara then
1803                  ParaIncludePath.AddPath(More,false)
1804                else
1805                 includesearchpath.AddPath(More,false);
1806              end;
1807 
1808            'k' :
1809              begin
1810                if more<>'' then
1811                  ParaLinkOptions:=ParaLinkOptions+' '+More
1812                else
1813                  IllegalPara(opt);
1814              end;
1815 
1816            'l' :
1817              ParaLogo:=not UnSetBool(more,0,opt,true);
1818 
1819 {$ifdef PREPROCWRITE}
1820            'm' :
1821              parapreprocess:=not UnSetBool(more,0,opt,true);
1822 {$endif PREPROCWRITE}
1823 
1824            'M' :
1825              begin
1826                more:=Upper(more);
1827                if not SetCompileMode(more, true) then
1828                  if not SetCompileModeSwitch(more, true) then
1829                    IllegalPara(opt);
1830              end;
1831 
1832            'n' :
1833              begin
1834                if More='' then
1835                  disable_configfile:=true
1836                else
1837                  IllegalPara(opt);
1838              end;
1839 
1840            'o' :
1841              begin
1842                if More<>'' then
1843                  begin
1844                    DefaultReplacements(More);
1845                    D:=ExtractFilePath(More);
1846                    if (D<>'') then
1847                      OutputExeDir:=FixPath(D,True);
1848                    OutputFileName:=ExtractFileName(More);
1849                  end
1850                else
1851                  IllegalPara(opt);
1852              end;
1853 
1854            'O' :
1855              begin
1856                j:=1;
1857                while j<=length(more) do
1858                 begin
1859                   case more[j] of
1860                     '1' :
1861                       init_settings.optimizerswitches:=init_settings.optimizerswitches+level1optimizerswitches;
1862                     '2' :
1863                       init_settings.optimizerswitches:=init_settings.optimizerswitches+level2optimizerswitches;
1864                     '3' :
1865                       init_settings.optimizerswitches:=init_settings.optimizerswitches+level3optimizerswitches;
1866                     '4' :
1867                       init_settings.optimizerswitches:=init_settings.optimizerswitches+level4optimizerswitches;
1868                     'a' :
1869                       begin
1870                         if not(UpdateAlignmentStr(Copy(Opt,j+3,255),ParaAlignment)) then
1871                           IllegalPara(opt);
1872                         break;
1873                       end;
1874                     's' :
1875                       include(init_settings.optimizerswitches,cs_opt_size);
1876                     'p' :
1877                       begin
1878                         if not Setoptimizecputype(copy(more,j+1,length(more)),init_settings.optimizecputype) then
1879                           begin
1880                             OptCPUSetExplicitly:=true;
1881                             { Give warning for old i386 switches }
1882                             if (Length(More)-j=1) and
1883                                (More[j+1]>='1') and (More[j+1]<='5')then
1884                               Message2(option_obsolete_switch_use_new,'-Op<nr>','-Op<name>')
1885                             else
1886                               IllegalPara(opt);
1887                           end;
1888                         break;
1889                       end;
1890                     'o' :
1891                       begin
1892                         if not UpdateOptimizerStr(copy(more,j+1,length(more)),init_settings.optimizerswitches) then
1893                          IllegalPara(opt);
1894                         break;
1895                       end;
1896                     '-' :
1897                       begin
1898                         init_settings.optimizerswitches:=[];
1899                         FillChar(ParaAlignment,sizeof(ParaAlignment),0);
1900                       end;
1901                     { Obsolete switches }
1902                     'g' :
1903                       Message2(option_obsolete_switch_use_new,'-Og','-Os');
1904                     'G' :
1905                       Message1(option_obsolete_switch,'-OG');
1906                     'r' :
1907                       Message2(option_obsolete_switch_use_new,'-Or','-O2 or -Ooregvar');
1908                     'u' :
1909                       Message2(option_obsolete_switch_use_new,'-Ou','-Oouncertain');
1910                     'w' :
1911                       begin
1912                         if not UpdateWpoStr(copy(more,j+1,length(more)),init_settings.dowpoptimizerswitches) then
1913                           IllegalPara(opt);
1914                         break;
1915                       end;
1916                     'W' :
1917                       begin
1918                         if not UpdateWpoStr(copy(more,j+1,length(more)),init_settings.genwpoptimizerswitches) then
1919                           IllegalPara(opt);
1920                         break;
1921                       end;
1922                     else
1923                       IllegalPara(opt);
1924                   end;
1925                   inc(j);
1926                 end;
1927              end;
1928 
1929            'p' :
1930              begin
1931                if UnsetBool(More, 0, opt, false) then
1932                  begin
1933                    init_settings.moduleswitches:=init_settings.moduleswitches-[cs_profile];
1934                    undef_system_macro('FPC_PROFILE');
1935                  end
1936                else
1937                  if Length(More)=0 then
1938                    IllegalPara(opt)
1939                  else
1940                  case more[1] of
1941                   'g' : if UnsetBool(more, 1, opt, false) then
1942                          begin
1943                            exclude(init_settings.moduleswitches,cs_profile);
1944                            undef_system_macro('FPC_PROFILE');
1945                          end
1946                         else if (target_info.system in supported_targets_pg) then
1947                          begin
1948                            include(init_settings.moduleswitches,cs_profile);
1949                            def_system_macro('FPC_PROFILE');
1950                          end
1951                         else
1952                           UnsupportedPara('-pg');
1953                  else
1954                    IllegalPara(opt);
1955                  end;
1956              end;
1957 
1958            'P' :
1959              begin
1960                { used to select the target processor with the "fpc" binary;
1961                  give an error if it's not the target architecture supported by
1962                  this compiler binary (will be verified after the target_info
1963                  is set) }
1964                processorstr:=More;
1965              end;
1966 
1967            'R' :
1968              begin
1969                if not SetAsmReadMode(More,init_settings.asmmode) then
1970                  IllegalPara(opt);
1971              end;
1972 
1973            's' :
1974              begin
1975                if UnsetBool(More, 0, opt, false) then
1976                  begin
1977                    init_settings.globalswitches:=init_settings.globalswitches-[cs_asm_extern,cs_link_extern,cs_link_nolink];
1978                    if more<>'' then
1979                      IllegalPara(opt);
1980                  end
1981                else
1982                  begin
1983                    init_settings.globalswitches:=init_settings.globalswitches+[cs_asm_extern,cs_link_extern,cs_link_nolink];
1984                    if more='h' then
1985                      init_settings.globalswitches:=init_settings.globalswitches-[cs_link_on_target]
1986                    else if more='t' then
1987                      init_settings.globalswitches:=init_settings.globalswitches+[cs_link_on_target]
1988                    else if more='r' then
1989                      init_settings.globalswitches:=init_settings.globalswitches+[cs_asm_leave,cs_no_regalloc]
1990                    else if more<>'' then
1991                      IllegalPara(opt);
1992                  end;
1993              end;
1994 
1995            'S' :
1996              begin
1997                if more='' then
1998                  IllegalPara(opt);
1999                if more[1]='I' then
2000                  begin
2001 {$ifdef jvm}
2002                    UnsupportedPara('-SI');
2003 {$endif}
2004                    if upper(more)='ICOM' then
2005                      init_settings.interfacetype:=it_interfacecom
2006                    else if upper(more)='ICORBA' then
2007                      init_settings.interfacetype:=it_interfacecorba
2008                    else
2009                      IllegalPara(opt);
2010                  end
2011                else
2012                 begin
2013                   j:=1;
2014                   while j<=length(more) do
2015                    begin
2016                      case more[j] of
2017                        '2' : //an alternative to -Mobjfpc
2018                          SetCompileMode('OBJFPC',true);
2019                        'a' :
2020                          If UnsetBool(More, j, opt, false) then
2021                            exclude(init_settings.localswitches,cs_do_assertion)
2022                          else
2023                            include(init_settings.localswitches,cs_do_assertion);
2024                        'c' :
2025                          If UnsetBool(More, j, opt, false) then
2026                            exclude(init_settings.moduleswitches,cs_support_c_operators)
2027                          else
2028                            include(init_settings.moduleswitches,cs_support_c_operators);
2029                        'd' : //an alternative to -Mdelphi
2030                          SetCompileMode('DELPHI',true);
2031                        'e' :
2032                          begin
2033                            SetErrorFlags(copy(more,j+1,length(more)));
2034                            break;
2035                          end;
2036                        'f' :
2037                          begin
2038                            if not(cs_compilesystem in init_settings.moduleswitches) then
2039                              Message(option_features_only_for_system_unit);
2040                            inc(j);
2041                            if more[j]='-' then
2042                              begin
2043                                if length(more)>j then
2044                                  IllegalPara(opt)
2045                                else
2046                                  features:=[];
2047                              end
2048                            else
2049                              begin
2050                                if (HandleFeature(upper(copy(more,j,length(more)-j+1)))) then
2051                                  j:=length(more)
2052                                else
2053                                  IllegalPara(opt);
2054                              end;
2055                          end;
2056                        'g' :
2057                          If UnsetBool(More, j, opt, false) then
2058                            exclude(init_settings.moduleswitches,cs_support_goto)
2059                          else
2060                            include(init_settings.moduleswitches,cs_support_goto);
2061                        'h' :
2062                          If UnsetBool(More, j, opt, false) then
2063                            exclude(init_settings.localswitches,cs_refcountedstrings)
2064                          else
2065                            include(init_settings.localswitches,cs_refcountedstrings);
2066                        'i' :
2067                          If UnsetBool(More, j, opt, false) then
2068                            exclude(init_settings.localswitches,cs_do_inline)
2069                          else
2070                            include(init_settings.localswitches,cs_do_inline);
2071                        'j' :
2072                          If UnsetBool(More, j, opt, false) then
2073                            exclude(init_settings.localswitches,cs_typed_const_writable)
2074                          else
2075                            include(init_settings.localswitches,cs_typed_const_writable);
2076                        'k' :
2077                          If UnsetBool(More, j, opt, false) then
2078                            exclude(init_settings.globalswitches,cs_load_fpcylix_unit)
2079                          else
2080                            include(init_settings.globalswitches,cs_load_fpcylix_unit);
2081                        'm' :
2082                          If UnsetBool(More, j, opt, false) then
2083                            exclude(init_settings.moduleswitches,cs_support_macro)
2084                          else
2085                            include(init_settings.moduleswitches,cs_support_macro);
2086                        'o' : //an alternative to -Mtp
2087                          SetCompileMode('TP',true);
2088                        'r' :
2089                          If UnsetBool(More, j, opt, false) then
2090                            exclude(init_settings.globalswitches,cs_transparent_file_names)
2091                          else
2092                            include(init_settings.globalswitches,cs_transparent_file_names);
2093 {$ifdef gpc_mode}
2094                        'p' : //an alternative to -Mgpc
2095                          SetCompileMode('GPC',true);
2096 {$endif}
2097                        's' :
2098                          If UnsetBool(More, j, opt, false) then
2099                            exclude(init_settings.globalswitches,cs_constructor_name)
2100                          else
2101                            include(init_settings.globalswitches,cs_constructor_name);
2102                        't' :
2103                          Message1(option_obsolete_switch,'-St');
2104                        'v' :
2105                          If UnsetBool(More, j, opt, false) then
2106                            exclude(init_settings.globalswitches,cs_support_vectors)
2107                          else
2108                            include(init_settings.globalswitches,cs_support_vectors);
2109                        'x' :
2110                          If UnsetBool(More, j, opt, false) then
2111                            SetCompileModeSwitch('EXCEPTIONS-',true)
2112                          else
2113                            SetCompileModeSwitch('EXCEPTIONS',true);
2114                        'y' :
2115                          If UnsetBool(More, j, opt, false) then
2116                            exclude(init_settings.localswitches,cs_typed_addresses)
2117                          else
2118                            include(init_settings.localswitches,cs_typed_addresses);
2119                        '-' :
2120                          begin
2121                            init_settings.globalswitches:=init_settings.globalswitches - [cs_constructor_name,cs_support_exceptions,
2122                                                                                          cs_support_vectors,cs_load_fpcylix_unit];
2123 
2124                            init_settings.localswitches:=init_settings.localswitches - [cs_do_assertion,cs_do_inline, cs_refcountedstrings,
2125                                                                                        cs_typed_addresses];
2126 
2127                            init_settings.moduleswitches:=init_settings.moduleswitches - [cs_support_c_operators, cs_support_goto,
2128                                                                                          cs_support_macro];
2129                          end;
2130                        else
2131                          IllegalPara(opt);
2132                      end;
2133                      inc(j);
2134                    end;
2135                 end;
2136              end;
2137 
2138            'T' :
2139              begin
2140                more:=Upper(More);
2141                if paratarget=system_none then
2142                 begin
2143                   { remove old target define }
2144                   TargetOptions(false);
2145                   { load new target }
2146                   paratarget:=find_system_by_string(More);
2147                   if paratarget<>system_none then
2148                     set_target(paratarget)
2149                   else
2150                     IllegalPara(opt);
2151                   { set new define }
2152                   TargetOptions(true);
2153                 end
2154                else
2155                 if More<>upper(target_info.shortname) then
2156                  Message1(option_target_is_already_set,target_info.shortname);
2157              end;
2158 
2159            'u' :
2160              if is_identifier(more) then
2161                undef_system_macro(more)
2162              else
2163                begin
2164                  if (more='') then
2165                    Message1(option_missing_arg,'-u')
2166                  else
2167                    Message1(option_malformed_para,opt);
2168                  StopOptions(1);
2169                end;
2170            'U' :
2171              begin
2172                j:=1;
2173                while j<=length(more) do
2174                 begin
2175                   case more[j] of
2176 {$ifdef UNITALIASES}
2177                     'a' :
2178                        begin
2179                          AddUnitAlias(Copy(More,j+1,255));
2180                          break;
2181                        end;
2182 {$endif UNITALIASES}
2183                     'n' :
2184                       exclude(init_settings.globalswitches,cs_check_unit_name);
2185                     'p' :
2186                        begin
2187                          Message2(option_obsolete_switch_use_new,'-Up','-Fu');
2188                          break;
2189                        end;
2190                     'r' :
2191                       begin
2192                         do_release:=true;
2193                         if (cs_checkpointer in init_settings.localswitches) then
2194                           begin
2195                             Message(option_gc_incompatible_with_release_flag);
2196                             exclude(init_settings.localswitches,cs_checkpointer);
2197                           end;
2198                       end;
2199                     's' :
2200                       include(init_settings.moduleswitches,cs_compilesystem);
2201                     '-' :
2202                       begin
2203                         exclude(init_settings.moduleswitches,cs_compilesystem);
2204                         exclude(init_settings.globalswitches,cs_check_unit_name);
2205                       end;
2206                     else
2207                       IllegalPara(opt);
2208                   end;
2209                   inc(j);
2210                 end;
2211              end;
2212 
2213            'v' :
2214              begin
2215                if not setverbosity(More) then
2216                  IllegalPara(opt);
2217              end;
2218 
2219            'V' : ; { Ignore used by fpc }
2220 
2221            'W' :
2222              begin
2223                j:=1;
2224                while j<=length(More) do
2225                 begin
2226                   case More[j] of
2227                     'A':
2228                       begin
2229                         if target_info.system in systems_all_windows then
2230                           begin
2231                             if UnsetBool(More, j, opt, false) then
2232                               SetApptype(app_cui)
2233                             else
2234                               SetApptype(app_native);
2235                           end
2236                         else
2237                           IllegalPara(opt);
2238                       end;
2239                     'b':
2240                       begin
2241                         if target_info.system in systems_darwin then
2242                           begin
2243                             if UnsetBool(More, j, opt, false) then
2244                               SetApptype(app_cui)
2245                             else
2246                               SetApptype(app_bundle)
2247                           end
2248                         else
2249                           IllegalPara(opt);
2250                       end;
2251                     'B':
2252                       begin
2253                         if target_info.system in systems_all_windows+systems_symbian then
2254                           begin
2255                             {  -WB200000 means set trefered base address
2256                               to $200000, but does not change relocsection boolean
2257                               this way we can create both relocatble and
2258                               non relocatable DLL at a specific base address PM }
2259                             if (length(More)>j) then
2260                               begin
2261                                 val('$'+Copy(More,j+1,255),imagebase,code);
2262                                 if code<>0 then
2263                                   IllegalPara(opt);
2264                                 ImageBaseSetExplicity:=true;
2265                               end
2266                             else
2267                               begin
2268                                 RelocSection:=true;
2269                                 RelocSectionSetExplicitly:=true;
2270                               end;
2271                             break;
2272                           end
2273                         else
2274                           IllegalPara(opt);
2275                       end;
2276                     'C':
2277                       begin
2278                         if target_info.system in systems_all_windows+systems_os2+systems_macos then
2279                           begin
2280                             if UnsetBool(More, j, opt, false) then
2281                               SetApptype(app_gui)
2282                             else
2283                               SetApptype(app_cui);
2284                           end
2285                         else
2286                           IllegalPara(opt);
2287                       end;
2288                     'D':
2289                       begin
2290                         if target_info.system in systems_all_windows then
2291                           begin
2292                             UseDeffileForExports:=not UnsetBool(More, j, opt, false);
2293                             UseDeffileForExportsSetExplicitly:=true;
2294                           end
2295                         else
2296                           IllegalPara(opt);
2297                       end;
2298                     'e':
2299                       begin
2300                         if (target_info.system in systems_darwin) then
2301                           begin
2302                             set_target_res(res_ext);
2303                             target_info.resobjext:='.fpcres';
2304                           end
2305                         else
2306                           IllegalPara(opt);
2307                       end;
2308                     'F':
2309                       begin
2310                         if target_info.system in systems_os2 then
2311                           begin
2312                             if UnsetBool(More, j, opt, false) then
2313                               SetApptype(app_cui)
2314                             else
2315                               SetApptype(app_fs);
2316                           end
2317                         else
2318                           IllegalPara(opt);
2319                       end;
2320                     'G':
2321                       begin
2322                         if target_info.system in systems_all_windows+systems_os2+systems_macos then
2323                           begin
2324                             if UnsetBool(More, j, opt, false) then
2325                               SetApptype(app_cui)
2326                             else
2327                               SetApptype(app_gui);
2328                           end
2329                         else
2330                           IllegalPara(opt);
2331                       end;
2332 {$if defined(i8086)}
2333                     'h':
2334                       begin
2335                         if UnsetBool(More, j, opt, false) then
2336                           exclude(init_settings.moduleswitches,cs_huge_code)
2337                          else
2338                           include(init_settings.moduleswitches,cs_huge_code);
2339                       end;
2340 {$endif defined(i8086)}
2341                     'I':
2342                       begin
2343                         if target_info.system in systems_all_windows then
2344                           begin
2345                             GenerateImportSection:=not UnsetBool(More,j,opt,false);
2346                             GenerateImportSectionSetExplicitly:=true;
2347                           end
2348                         else
2349                           IllegalPara(opt);
2350                       end;
2351                     'i':
2352                       begin
2353                         if (target_info.system in systems_darwin) then
2354                           begin
2355                             set_target_res(res_macho);
2356                             target_info.resobjext:=
2357                               targetinfos[target_info.system]^.resobjext;
2358                           end
2359                         else
2360                           IllegalPara(opt);
2361                       end;
2362                     'm':
2363                       begin
2364 {$if defined(i8086)}
2365                         if (target_info.system in [system_i8086_msdos,system_i8086_win16,system_i8086_embedded]) then
2366                           begin
2367                             case Upper(Copy(More,j+1,255)) of
2368                               'TINY':    init_settings.x86memorymodel:=mm_tiny;
2369                               'SMALL':   init_settings.x86memorymodel:=mm_small;
2370                               'MEDIUM':  init_settings.x86memorymodel:=mm_medium;
2371                               'COMPACT': init_settings.x86memorymodel:=mm_compact;
2372                               'LARGE':   init_settings.x86memorymodel:=mm_large;
2373                               'HUGE':    init_settings.x86memorymodel:=mm_huge;
2374                               else
2375                                 IllegalPara(opt);
2376                             end;
2377                             break;
2378                           end
2379                         else
2380 {$endif defined(i8086)}
2381                           IllegalPara(opt);
2382                       end;
2383                     'M':
2384                       begin
2385                         if (target_info.system in (systems_darwin-[system_i386_iphonesim,system_arm_ios,system_aarch64_ios,system_x86_64_iphonesim])) and
2386                            ParseMacVersionMin(MacOSXVersionMin,iPhoneOSVersionMin,'MAC_OS_X_VERSION_MIN_REQUIRED',copy(More,2,255),false) then
2387                           begin
2388                             break;
2389                           end
2390                         else
2391                           IllegalPara(opt);
2392                       end;
2393                     'N':
2394                       begin
2395                         if target_info.system in systems_all_windows then
2396                           begin
2397                             RelocSection:=UnsetBool(More,j,opt,false);
2398                             RelocSectionSetExplicitly:=true;
2399                           end
2400                         else
2401                           IllegalPara(opt);
2402                       end;
2403                     'p':
2404                       begin
2405 {$push}
2406 {$warn 6018 off} { Unreachable code due to compile time evaluation }
2407                         if (target_info.system in systems_embedded) and
2408                                                          ControllerSupport then
2409                           begin
2410                             s:=upper(copy(more,j+1,length(more)-j));
2411                             if not(SetControllerType(s,init_settings.controllertype)) then
2412                               IllegalPara(opt)
2413                             else
2414                               begin
2415                                 if init_settings.cputype<>embedded_controllers[init_settings.controllertype].cputype then
2416                                 begin
2417                                   Message(scan_n_changecputype);
2418                                   init_settings.cputype:=embedded_controllers[init_settings.controllertype].cputype;
2419                                 end;
2420                               end;
2421                             break;
2422                           end
2423                         else
2424                           IllegalPara(opt);
2425 {$pop}
2426                       end;
2427                     'P':
2428                       begin
2429                         if (target_info.system in [system_i386_iphonesim,system_arm_ios,system_aarch64_ios,system_x86_64_iphonesim]) and
2430                            ParseMacVersionMin(iPhoneOSVersionMin,MacOSXVersionMin,'IPHONE_OS_VERSION_MIN_REQUIRED',copy(More,2,255),true) then
2431                           begin
2432                             break;
2433                           end
2434                         else
2435                           IllegalPara(opt);
2436                       end;
2437                     'R':
2438                       begin
2439                         if target_info.system in systems_all_windows then
2440                           begin
2441                             { support -WR+ / -WR- as synonyms to -WR / -WN }
2442                             RelocSection:=not UnsetBool(More,j,opt,false);
2443                             RelocSectionSetExplicitly:=true;
2444                           end
2445                         else
2446                           IllegalPara(opt);
2447                       end;
2448                     't':
2449                       begin
2450 {$if defined(i8086)}
2451                         if (target_info.system in [system_i8086_msdos,system_i8086_embedded]) then
2452                           begin
2453                             case Upper(Copy(More,j+1,255)) of
2454                               'EXE': SetAppType(app_cui);
2455                               'COM': SetAppType(app_com);
2456                               else
2457                                 IllegalPara(opt);
2458                             end;
2459                             break;
2460                           end
2461                         else
2462 {$endif defined(i8086)}
2463                           IllegalPara(opt);
2464                       end;
2465                     'T':
2466                       begin
2467                         if target_info.system in systems_macos then
2468                           begin
2469                             if UnsetBool(More, j, opt, false) then
2470                               SetApptype(app_cui)
2471                             else
2472                               SetApptype(app_tool);
2473                           end
2474                         else
2475                           IllegalPara(opt);
2476                       end;
2477                     'X':
2478                       begin
2479                         if (target_info.system in systems_linux) then
2480                           begin
2481                             if UnsetBool(More, j, opt, false) then
2482                               exclude(init_settings.moduleswitches,cs_executable_stack)
2483                             else
2484                               include(init_settings.moduleswitches,cs_executable_stack)
2485                           end
2486                         else
2487                           IllegalPara(opt);
2488                       end;
2489                     else
2490                       IllegalPara(opt);
2491                   end;
2492                   inc(j);
2493                 end;
2494              end;
2495 
2496            'X' :
2497              begin
2498                j:=1;
2499                while j<=length(more) do
2500                 begin
2501                   case More[j] of
2502                     '9' :
2503                       begin
2504                         if target_info.system in systems_linux then
2505                           begin
2506                             if UnsetBool(More, j, opt, false) then
2507                               exclude(init_settings.globalswitches,cs_link_pre_binutils_2_19)
2508                             else
2509                               include(init_settings.globalswitches,cs_link_pre_binutils_2_19);
2510                           end
2511                         else
2512                           IllegalPara(opt);
2513                       end;
2514                     'c' : Cshared:=TRUE;
2515                     'd' : Dontlinkstdlibpath:=TRUE;
2516                     'e' :
2517                       begin
2518                         If UnsetBool(More, j, opt, false) then
2519                           exclude(init_settings.globalswitches,cs_link_extern)
2520                         else
2521                           include(init_settings.globalswitches,cs_link_extern);
2522                       end;
2523                     'f' :
2524                       include(init_settings.globalswitches,cs_link_pthread);
2525                     'g' :
2526                       begin
2527                         If UnsetBool(More, j, opt, false) then
2528                           exclude(init_settings.globalswitches,cs_link_separate_dbg_file)
2529                         else
2530                           include(init_settings.globalswitches,cs_link_separate_dbg_file);
2531                       end;
2532                     'i' :
2533                       begin
2534                         If UnsetBool(More, j, opt, false) then
2535                           include(init_settings.globalswitches,cs_link_extern)
2536                         else
2537                           exclude(init_settings.globalswitches,cs_link_extern);
2538                       end;
2539                     'n' :
2540                       begin
2541                         If UnsetBool(More, j, opt, false) then
2542                           exclude(init_settings.globalswitches,cs_link_native)
2543                         else
2544                           include(init_settings.globalswitches,cs_link_native);
2545                       end;
2546 
2547                     'm' :
2548                       begin
2549                         If UnsetBool(More, j, opt, false) then
2550                           exclude(init_settings.globalswitches,cs_link_map)
2551                         else
2552                           include(init_settings.globalswitches,cs_link_map);
2553                       end;
2554                     'p' : ; { Ignore used by fpc.pp }
2555                     'r' :
2556                       begin
2557                         if (target_info.system in suppported_targets_x_smallr) then
2558                           begin
2559                             rlinkpath:=Copy(more,2,length(More)-1);
2560                             DefaultReplacements(rlinkpath);
2561                           end
2562                         else
2563                           IgnoredPara('-Xr');
2564                         more:='';
2565                       end;
2566                     'R' :
2567                       begin
2568                         sysrootpath:=copy(more,2,length(more)-1);
2569                         defaultreplacements(sysrootpath);
2570                         more:='';
2571                       end;
2572                     's' :
2573                       begin
2574                         If UnsetBool(More, j, opt, false) then
2575                           exclude(init_settings.globalswitches,cs_link_strip)
2576                         else
2577                           include(init_settings.globalswitches,cs_link_strip);
2578                       end;
2579                     't' :
2580                       include(init_settings.globalswitches,cs_link_staticflag);
2581                     'v' :
2582                       begin
2583                         If UnsetBool(More, j, opt, false) then
2584                           exclude(init_settings.globalswitches,cs_link_opt_vtable)
2585                         else
2586                           include(init_settings.globalswitches,cs_link_opt_vtable);
2587                       end;
2588                     'D' :
2589                       begin
2590                         def_system_macro('FPC_LINK_DYNAMIC');
2591                         undef_system_macro('FPC_LINK_SMART');
2592                         undef_system_macro('FPC_LINK_STATIC');
2593                         exclude(init_settings.globalswitches,cs_link_static);
2594                         exclude(init_settings.globalswitches,cs_link_smart);
2595                         include(init_settings.globalswitches,cs_link_shared);
2596                         LinkTypeSetExplicitly:=true;
2597                       end;
2598                     'M' :
2599                       begin
2600                         mainaliasname:=Copy(more,2,length(More)-1);
2601                         More:='';
2602                       end;
2603                     'P' :
2604                       begin
2605                         utilsprefix:=Copy(more,2,length(More)-1);
2606                         DefaultReplacements(utilsprefix);
2607                         More:='';
2608                       end;
2609                     'L' : begin  // -XLO is link order -XLA is link alias. -XLD avoids load defaults.
2610                                  // these are not aggregable.
2611                             if (j=length(more)) or not (more[j+1] in ['O','A','D']) then
2612                               IllegalPara(opt)
2613                             else
2614                               begin
2615                                 case more[j+1] of
2616                                  'A' : begin
2617                                         s:=Copy(more,3,length(More)-2);
2618                                         if not LinkLibraryAliases.AddDep(s) Then
2619                                            IllegalPara(opt);
2620                                        end;
2621                                  'O' : begin
2622                                         s:=Copy(more,3,length(More)-2);
2623                                         if not LinkLibraryOrder.AddWeight(s) Then
2624                                            IllegalPara(opt);
2625                                        end;
2626                                  'D' : include(init_settings.globalswitches,cs_link_no_default_lib_order)
2627                                 else
2628                                   IllegalPara(opt);
2629                                  end; {case}
2630                                 j:=length(more);
2631                               end; {else begin}
2632                           end;
2633                     'S' :
2634                       begin
2635                         ForceStaticLinking;
2636                       end;
2637                     'V' :
2638                       begin
2639                         if UnsetBool(More, j, opt, false) then
2640                           exclude(init_settings.globalswitches,cs_link_vlink)
2641                         else
2642                           begin
2643                             include(init_settings.globalswitches,cs_link_vlink);
2644                             include(init_settings.globalswitches,cs_link_extern);
2645                           end;
2646                         LinkerSetExplicitly:=true;
2647                       end;
2648                     'X' :
2649                       begin
2650                         def_system_macro('FPC_LINK_SMART');
2651                         undef_system_macro('FPC_LINK_STATIC');
2652                         undef_system_macro('FPC_LINK_DYNAMIC');
2653                         exclude(init_settings.globalswitches,cs_link_static);
2654                         include(init_settings.globalswitches,cs_link_smart);
2655                         exclude(init_settings.globalswitches,cs_link_shared);
2656                         LinkTypeSetExplicitly:=true;
2657                       end;
2658                     '-' :
2659                       begin
2660                         exclude(init_settings.globalswitches,cs_link_staticflag);
2661                         exclude(init_settings.globalswitches,cs_link_strip);
2662                         exclude(init_settings.globalswitches,cs_link_map);
2663                         set_default_link_type;
2664                       end;
2665                     else
2666                       IllegalPara(opt);
2667                   end;
2668                   inc(j);
2669                 end;
2670              end;
2671            else
2672              IllegalPara(opt);
2673          end;
2674        end;
2675 
2676     '@' :
2677       begin
2678         Message(option_no_nested_response_file);
2679         StopOptions(1);
2680       end;
2681 
2682     else
2683       begin
2684         if (length(param_file)<>0) then
2685           Message2(option_only_one_source_support,param_file,opt);
2686         param_file:=opt;
2687         Message1(option_found_file,opt);
2688       end;
2689   end;
2690 end;
2691 
2692 
2693 procedure Toption.Interpret_file(const filename : TPathStr);
2694 
2695   procedure RemoveSep(var fn:TPathStr);
2696   var
2697     i : longint;
2698   begin
2699     i:=0;
2700     while (i<length(fn)) and (fn[i+1] in [',',' ',#9]) do
2701       inc(i);
2702     Delete(fn,1,i);
2703     i:=length(fn);
2704     while (i>0) and (fn[i] in [',',' ',#9]) do
2705       dec(i);
2706     fn:=copy(fn,1,i);
2707   end;
2708 
GetNamenull2709   function GetName(var fn:TPathStr):TPathStr;
2710   var
2711     i : longint;
2712   begin
2713     i:=0;
2714     while (i<length(fn)) and (fn[i+1] in ['a'..'z','A'..'Z','0'..'9','_','-']) do
2715      inc(i);
2716     GetName:=Copy(fn,1,i);
2717     Delete(fn,1,i);
2718   end;
2719 
2720 const
2721   maxlevel = 15;
2722 var
2723   f     : text;
2724   s, tmp,
2725   opts  : TCmdStr;
2726   skip  : array[0..maxlevel] of boolean;
2727   line,
2728   level : longint;
2729   option_read : boolean;
2730   oldfilemode : byte;
2731   ConfigFile: TPathStr;
2732 begin
2733 { avoid infinite loop }
2734   Inc(FileLevel);
2735   Option_read:=false;
2736   If FileLevel>MaxLevel then
2737    Message(option_too_many_cfg_files);
2738   if not ParaIncludeCfgPath.FindFile(fileName,true,ConfigFile) then
2739     ConfigFile := ExpandFileName(filename);
2740 { Maybe It's Directory ?}   //Jaro Change:
2741   if PathExists(ConfigFile,false) then
2742     begin
2743        Message1(option_config_is_dir,filename);
2744        exit;
2745     end;
2746 { open file }
2747   Message1(option_using_file,filename);
2748   oldfilemode:=filemode;
2749   filemode:=0;
2750   assign(f,ConfigFile);
2751   {$push}{$I-}
2752    reset(f);
2753   {$pop}
2754   filemode:=oldfilemode;
2755   if ioresult<>0 then
2756    begin
2757      Message1(option_unable_open_file,filename);
2758      exit;
2759    end;
2760   Message1(option_start_reading_configfile,filename);
2761   fillchar(skip,sizeof(skip),0);
2762   level:=0;
2763   line:=0;
2764   while not eof(f) do
2765    begin
2766      readln(f,opts);
2767      inc(line);
2768      RemoveSep(opts);
2769      if (opts<>'') and (opts[1]<>';') then
2770       begin
2771         if opts[1]='#' then
2772          begin
2773            Message1(option_interpreting_file_option,opts);
2774            Delete(opts,1,1);
2775            s:=upper(GetName(opts));
2776            if (s='SECTION') then
2777             begin
2778               RemoveSep(opts);
2779               s:=upper(GetName(opts));
2780               if level=0 then
2781                skip[level]:=not defined_macro(s) or (s='COMMON');
2782             end
2783            else
2784             if (s='IFDEF') then
2785              begin
2786                RemoveSep(opts);
2787                if Level>=maxlevel then
2788                 begin
2789                   Message2(option_too_many_ifdef,filename,tostr(line));
2790                   stopOptions(1);
2791                 end;
2792                inc(Level);
2793                skip[level]:=(skip[level-1] or not defined_macro(upper(GetName(opts))));
2794              end
2795            else
2796             if (s='IFNDEF') then
2797              begin
2798                RemoveSep(opts);
2799                if Level>=maxlevel then
2800                 begin
2801                   Message2(option_too_many_ifdef,filename,tostr(line));
2802                   stopOptions(1);
2803                 end;
2804                inc(Level);
2805                skip[level]:=(skip[level-1] or defined_macro(upper(GetName(opts))));
2806              end
2807            else
2808             if (s='ELSE') then
2809               begin
2810                 if Level=0 then
2811                   begin
2812                     Message2(option_else_without_if,filename,tostr(line));
2813                     stopOptions(1);
2814                   end
2815                 else
2816                   skip[level]:=skip[level-1] or (not skip[level])
2817               end
2818            else
2819             if (s='ENDIF') then
2820              begin
2821                skip[level]:=false;
2822                if Level=0 then
2823                 begin
2824                   Message2(option_too_many_endif,filename,tostr(line));
2825                   stopOptions(1);
2826                 end;
2827                dec(level);
2828              end
2829            else
2830             if (not skip[level]) then
2831              begin
2832                if (s='DEFINE') then
2833                 begin
2834                   RemoveSep(opts);
2835                   tmp:= GetName(opts);
2836                   if tmp <> '' then
2837                     def_system_macro(tmp);
2838                   Option_read:=true;
2839                 end
2840               else
2841                if (s='UNDEF') then
2842                 begin
2843                   RemoveSep(opts);
2844                   tmp:= GetName(opts);
2845                   if tmp <> '' then
2846                     undef_system_macro(tmp);
2847                   Option_read:=true;
2848                 end
2849               else
2850                if (s='WRITE') then
2851                 begin
2852                   Delete(opts,1,1);
2853                   DefaultReplacements(opts);
2854                   WriteLn(opts);
2855                   Option_read:=true;
2856                 end
2857               else
2858                if (s='INCLUDE') then
2859                 begin
2860                   Delete(opts,1,1);
2861                   DefaultReplacements(opts);
2862                   Interpret_file(opts);
2863                   Option_read:=true;
2864                 end
2865               else
2866                if (s='CFGDIR') then
2867                 begin
2868                   Delete(opts,1,1);
2869                   DefaultReplacements(opts);
2870                   ParaIncludeCfgPath.AddPath(opts,false);
2871                   Option_read:=true;
2872                 end;
2873             end;
2874          end
2875         else
2876          begin
2877            if (opts[1]='-') or (opts[1]='@') then
2878             begin
2879               if (not skip[level]) then
2880                 interpret_option(opts,false);
2881               Option_read:=true;
2882             end
2883            else
2884              Message1(option_illegal_para,opts);
2885          end;
2886       end;
2887    end;
2888   if Level>0 then
2889    Message(option_too_less_endif);
2890   if Not Option_read then
2891     Message1(option_no_option_found,filename)
2892   else
2893     Message1(option_end_reading_configfile,filename);
2894   Close(f);
2895   Dec(FileLevel);
2896 end;
2897 
2898 
2899 procedure Toption.Interpret_envvar(const envname : TCmdStr);
2900 var
2901   argstart,
2902   env,
2903   pc     : pchar;
2904   arglen : longint;
2905   quote  : set of char;
2906   hs     : TCmdStr;
2907 begin
2908   Message1(option_using_env,envname);
2909   env:=GetEnvPChar(envname);
2910   pc:=env;
2911   hs:='';
2912   if assigned(pc) then
2913    begin
2914      repeat
2915        { skip leading spaces }
2916        while pc^ in [' ',#9,#13] do
2917         inc(pc);
2918        case pc^ of
2919          #0 :
2920            break;
2921          '"' :
2922            begin
2923              quote:=['"'];
2924              inc(pc);
2925            end;
2926          '''' :
2927            begin
2928               quote:=[''''];
2929               inc(pc);
2930            end;
2931          else
2932            quote:=[' ',#9,#13];
2933        end;
2934      { scan until the end of the argument }
2935        argstart:=pc;
2936        while (pc^<>#0) and not(pc^ in quote) do
2937         inc(pc);
2938      { create argument }
2939        arglen:=pc-argstart;
2940 { TODO: FIXME: silent truncation of environment parameters }
2941        if (arglen > 255) then
2942          arglen := 255;
2943        setlength(hs,arglen);
2944        move(argstart^,hs[1],arglen);
2945        interpret_option(hs,true);
2946      { skip quote }
2947        if pc^ in quote then
2948         inc(pc);
2949      until false;
2950    end
2951   else
2952    Message1(option_no_option_found,'(env) '+envname);
2953   FreeEnvPChar(env);
2954 end;
2955 
2956 
2957 procedure toption.read_parameters;
2958 var
2959   opts       : TCmdStr;
2960   paramindex : longint;
2961 begin
2962   paramindex:=0;
2963   while paramindex<paramcount do
2964    begin
2965      inc(paramindex);
2966      opts:=objpas.paramstr(paramindex);
2967      if length(opts)>0 then
2968        case opts[1] of
2969          '@' :
2970            if not firstpass then
2971            begin
2972              Delete(opts,1,1);
2973              Message1(option_reading_further_from,opts);
2974              interpret_file(opts);
2975            end;
2976          '!' :
2977            if not firstpass then
2978            begin
2979              Delete(opts,1,1);
2980              Message1(option_reading_further_from,'(env) '+opts);
2981              interpret_envvar(opts);
2982            end;
2983          else
2984            interpret_option(opts,true);
2985        end;
2986    end;
2987 end;
2988 
2989 
2990 procedure toption.parsecmd(cmd:TCmdStr);
2991 var
2992   i,ps  : longint;
2993   opts  : TCmdStr;
2994 begin
2995   while (cmd<>'') do
2996    begin
2997      while cmd[1]=' ' do
2998       delete(cmd,1,1);
2999      i:=pos(' ',cmd);
3000      if i=0 then
3001        i:=2147483647;
3002      opts:=Copy(cmd,1,i-1);
3003      Delete(cmd,1,i);
3004      case opts[1] of
3005        '@' :
3006          if not firstpass then
3007          begin
3008            Delete(opts,1,1);
3009            Message1(option_reading_further_from,opts);
3010            interpret_file(opts);
3011          end;
3012        '!' :
3013          if not firstpass then
3014          begin
3015            Delete(opts,1,1);
3016            Message1(option_reading_further_from,'(env) '+opts);
3017            interpret_envvar(opts);
3018          end;
3019        '"' :
3020          begin
3021            Delete(opts,1,1);
3022            ps:=pos('"',cmd);
3023            if (i<>256) and (ps>0) then
3024              begin
3025                opts:=opts + ' '+ copy(cmd,1,ps-1);
3026                cmd:=copy(cmd,ps+1,255);
3027              end;
3028            interpret_option(opts,true);
3029          end;
3030        else
3031          interpret_option(opts,true);
3032      end;
3033    end;
3034 end;
3035 
3036 
3037 procedure toption.writequickinfo;
3038 var
3039   s : string;
3040   i : longint;
3041 
3042   procedure addinfo(const hs:string);
3043   begin
3044     if s<>'' then
3045      s:=s+' '+hs
3046     else
3047      s:=hs;
3048   end;
3049 
3050 begin
3051   s:='';
3052   i:=0;
3053   while (i<length(quickinfo)) do
3054    begin
3055      inc(i);
3056      case quickinfo[i] of
3057       'S' :
3058         begin
3059           inc(i);
3060           case quickinfo[i] of
3061            'O' :
3062              addinfo(lower(source_info.shortname));
3063            'P' :
3064              addinfo(source_cpu_string);
3065            else
3066              IllegalPara('-i'+QuickInfo);
3067           end;
3068         end;
3069       'T' :
3070         begin
3071           inc(i);
3072           case quickinfo[i] of
3073            'O' :
3074              addinfo(lower(target_info.shortname));
3075            'P' :
3076              AddInfo(target_cpu_string);
3077            else
3078              IllegalPara('-i'+QuickInfo);
3079           end;
3080         end;
3081       'V' :
3082         AddInfo(version_string);
3083       'W' :
3084         AddInfo(full_version_string);
3085       'D' :
3086         AddInfo(date_string);
3087       '_' :
3088         ;
3089       else
3090         IllegalPara('-i'+QuickInfo);
3091     end;
3092   end;
3093   if s<>'' then
3094    begin
3095      writeln(s);
3096      stopoptions(0);
3097    end;
3098 end;
3099 
3100 
3101 procedure TOption.TargetOptions(def:boolean);
3102 var
3103   s : string;
3104   i : integer;
3105   target_unsup_features : tfeatures;
3106 begin
3107   if def then
3108    def_system_macro(target_info.shortname)
3109   else
3110    undef_system_macro(target_info.shortname);
3111 
3112   s:=target_info.extradefines;
3113   while (s<>'') do
3114    begin
3115      i:=pos(';',s);
3116      if i=0 then
3117       i:=length(s)+1;
3118      if def then
3119       def_system_macro(Copy(s,1,i-1))
3120      else
3121       undef_system_macro(Copy(s,1,i-1));
3122      delete(s,1,i);
3123    end;
3124 
3125   if (tf_winlikewidestring in target_info.flags) then
3126     if def then
3127       def_system_macro('FPC_WINLIKEWIDESTRING')
3128     else
3129       undef_system_macro('FPC_WINLIKEWIDESTRING');
3130 
3131   if (tf_requires_proper_alignment in target_info.flags) then
3132     if def then
3133       def_system_macro('FPC_REQUIRES_PROPER_ALIGNMENT')
3134     else
3135       undef_system_macro('FPC_REQUIRES_PROPER_ALIGNMENT');
3136 
3137   if source_info.system<>target_info.system then
3138     if def then
3139       def_system_macro('FPC_CROSSCOMPILING')
3140     else
3141       undef_system_macro('FPC_CROSSCOMPILING');
3142 
3143   if source_info.cpu<>target_info.cpu then
3144     if def then
3145       def_system_macro('FPC_CPUCROSSCOMPILING')
3146     else
3147       def_system_macro('FPC_CPUCROSSCOMPILING');
3148 
3149   if (tf_no_generic_stackcheck in target_info.flags) then
3150     if def then
3151       def_system_macro('FPC_NO_GENERIC_STACK_CHECK')
3152     else
3153       undef_system_macro('FPC_NO_GENERIC_STACK_CHECK');
3154 
3155   if (tf_section_threadvars in target_info.flags) then
3156     if def then
3157       def_system_macro('FPC_SECTION_THREADVARS')
3158     else
3159       undef_system_macro('FPC_SECTION_THREADVARS');
3160 
3161   { Code generation flags }
3162   if (tf_pic_default in target_info.flags) then
3163     if def then
3164       include(init_settings.moduleswitches,cs_create_pic)
3165     else
3166       exclude(init_settings.moduleswitches,cs_create_pic);
3167 
3168   { Resources support }
3169   if (tf_has_winlike_resources in target_info.flags) then
3170     if def then
3171       def_system_macro('FPC_HAS_WINLIKERESOURCES')
3172     else
3173       undef_system_macro('FPC_HAS_WINLIKERESOURCES');
3174 
3175   { Features }
3176   case target_info.system of
3177     system_arm_gba:
3178       target_unsup_features:=[f_dynlibs];
3179     system_arm_nds:
3180       target_unsup_features:=[f_threading,f_commandargs,f_fileio,f_textio,f_consoleio,f_dynlibs];
3181     system_i386_nativent:
3182       // until these features are implemented, they are disabled in the compiler
3183       target_unsup_features:=[f_stackcheck];
3184     system_i8086_msdos:
3185       target_unsup_features:=[f_threading,f_dynlibs];
3186     system_i8086_win16:
3187       target_unsup_features:=[f_threading];
3188     system_jvm_java32,
3189     system_jvm_android32:
3190       target_unsup_features:=[f_heap,f_textio,f_consoleio,f_fileio,
3191          f_variants,f_objects,f_commandargs,
3192          f_processes,f_stackcheck,f_dynlibs,f_softfpu,f_objectivec1,f_resources];
3193     system_arm_palmos,
3194     system_m68k_palmos:
3195       target_unsup_features:=[f_threading];
3196     system_m68k_atari:
3197       target_unsup_features:=[f_threading];
3198     { classic amiga has dynamic libraries, but they cannot be integrated in the
3199       normal dynlibs infrastructure due to architectural differences, so therefore
3200       lets disable the feature. }
3201     system_m68k_amiga:
3202       target_unsup_features:=[f_dynlibs];
3203     else
3204       target_unsup_features:=[];
3205   end;
3206   if def then
3207     features:=features-target_unsup_features
3208   else
3209     features:=features+target_unsup_features;
3210 
3211 {$if defined(atari) or defined(hasamiga)}
3212    { enable vlink as default linker on Atari, Amiga, and MorphOS, but not for cross compilers (for now) }
3213    if (target_info.system in [system_m68k_amiga,system_m68k_atari,
3214                               system_powerpc_amiga,system_powerpc_morphos]) and
3215       not LinkerSetExplicitly then
3216      include(init_settings.globalswitches,cs_link_vlink);
3217 {$endif}
3218 end;
3219 
3220 procedure TOption.checkoptionscompatibility;
3221 begin
3222 {$ifdef i8086}
3223   if (apptype=app_com) and (init_settings.x86memorymodel<>mm_tiny) then
3224     begin
3225       Message(option_com_files_require_tiny_model);
3226       StopOptions(1);
3227     end;
3228 {$endif i8086}
3229 
3230 {$ifndef i8086_link_intern_debuginfo}
3231   if (cs_debuginfo in init_settings.moduleswitches) and
3232      (target_info.system in [system_i8086_msdos,system_i8086_win16,system_i8086_embedded]) and
3233      not (cs_link_extern in init_settings.globalswitches) then
3234     begin
3235       Message(option_debug_info_requires_external_linker);
3236       include(init_settings.globalswitches,cs_link_extern);
3237     end;
3238 {$endif i8086_link_intern_debuginfo}
3239 
3240   if (paratargetdbg in [dbg_dwarf2,dbg_dwarf3]) and
3241      not(target_info.system in (systems_darwin+[system_i8086_msdos,system_i8086_embedded])) then
3242     begin
3243       { smartlink creation does not yet work with DWARF
3244         debug info on most targets, but it works in internal assembler }
3245       if (cs_create_smart in init_settings.moduleswitches) and
3246          not (af_outputbinary in target_asm.flags) then
3247         begin
3248           Message(option_dwarf_smartlink_creation);
3249           exclude(init_settings.moduleswitches,cs_create_smart);
3250         end;
3251 
3252       { smart linking does not yet work with DWARF debug info on most targets }
3253       if (cs_link_smart in init_settings.globalswitches) then
3254         begin
3255           Message(option_dwarf_smart_linking);
3256           ForceStaticLinking;
3257         end;
3258     end;
3259 
3260   { external debug info is only supported for DWARF on darwin }
3261   if (target_info.system in systems_darwin) and
3262      (cs_link_separate_dbg_file in init_settings.globalswitches) and
3263      not(paratargetdbg in [dbg_dwarf2,dbg_dwarf3]) then
3264     begin
3265       Message(option_debug_external_unsupported);
3266       exclude(init_settings.globalswitches,cs_link_separate_dbg_file);
3267     end;
3268   { Also create a smartlinked version, on an assembler that
3269     does not support smartlink sections like nasm?
3270     This is not compatible with using internal linker. }
3271   if ((cs_link_smart in init_settings.globalswitches) or
3272       (cs_create_smart in init_settings.moduleswitches)) and
3273      (af_needar in target_asm.flags) and
3274      not (af_smartlink_sections in target_asm.flags) and
3275      not (cs_link_extern in init_settings.globalswitches) and
3276      (target_info.link<>ld_none) and
3277       not (cs_link_nolink in init_settings.globalswitches) then
3278     begin
3279       Message(option_smart_link_requires_external_linker);
3280       include(init_settings.globalswitches,cs_link_extern);
3281     end;
3282 end;
3283 
3284 
3285 constructor TOption.create;
3286 begin
3287   LogoWritten:=false;
3288   NoPressEnter:=false;
3289   FirstPass:=false;
3290   ABISetExplicitly:=false;
3291   FPUSetExplicitly:=false;
3292   CPUSetExplicitly:=false;
3293   OptCPUSetExplicitly:=false;
3294   FileLevel:=0;
3295   Quickinfo:='';
3296   ParaIncludeCfgPath:=TSearchPathList.Create;
3297   ParaIncludePath:=TSearchPathList.Create;
3298   ParaObjectPath:=TSearchPathList.Create;
3299   ParaUnitPath:=TSearchPathList.Create;
3300   ParaLibraryPath:=TSearchPathList.Create;
3301   ParaFrameworkPath:=TSearchPathList.Create;
3302   parapackagepath:=TSearchPathList.Create;
3303   parapackages:=TFPHashObjectList.Create;
3304   paranamespaces:=TCmdStrList.Create;
3305   FillChar(ParaAlignment,sizeof(ParaAlignment),0);
3306   MacVersionSet:=false;
3307   paratarget:=system_none;
3308   paratargetasm:=as_none;
3309   paratargetdbg:=dbg_none;
3310   LinkTypeSetExplicitly:=false;
3311   LinkerSetExplicitly:=false;
3312 end;
3313 
3314 
3315 destructor TOption.destroy;
3316 begin
3317   ParaIncludeCfgPath.Free;
3318   ParaIncludePath.Free;
3319   ParaObjectPath.Free;
3320   ParaUnitPath.Free;
3321   ParaLibraryPath.Free;
3322   ParaFrameworkPath.Free;
3323   parapackagepath.Free;
3324   ParaPackages.Free;
3325   paranamespaces.free;
3326 end;
3327 
3328 
3329 {****************************************************************************
3330                               Callable Routines
3331 ****************************************************************************}
3332 
check_configfilenull3333 function check_configfile(fn:string; var foundfn:string):boolean;
3334 
CfgFileExistsnull3335   function CfgFileExists(const fn:string):boolean;
3336   begin
3337     Comment(V_Tried,'Configfile search: '+fn);
3338     CfgFileExists:=FileExists(fn);
3339   end;
3340 
3341 var
3342 {$ifdef Unix}
3343   hs,
3344 {$endif Unix}
3345   configpath : string;
3346 begin
3347   foundfn:=fn;
3348   check_configfile:=true;
3349   { retrieve configpath }
3350   configpath:=FixPath(GetEnvironmentVariable('PPC_CONFIG_PATH'),false);
3351 {$ifdef Unix}
3352   if configpath='' then
3353    configpath:=ExpandFileName(FixPath(exepath+'../etc/',false));
3354 {$endif}
3355   {
3356     Order to read configuration file :
3357     try reading fpc.cfg in :
3358      1 - current dir
3359      2 - configpath
3360      3 - compiler path
3361   }
3362   if not FileExists(fn) then
3363    begin
3364 {$ifdef Unix}
3365      hs:=GetEnvironmentVariable('HOME');
3366      if (hs<>'') and CfgFileExists(FixPath(hs,false)+'.'+fn) then
3367       foundfn:=FixPath(hs,false)+'.'+fn
3368      else
3369 {$endif}
3370       if CfgFileExists(configpath+fn) then
3371        foundfn:=configpath+fn
3372      else
3373 {$ifdef WINDOWS}
3374        if (GetEnvironmentVariable('USERPROFILE')<>'') and CfgFileExists(FixPath(GetEnvironmentVariable('USERPROFILE'),false)+fn) then
3375          foundfn:=FixPath(GetEnvironmentVariable('USERPROFILE'),false)+fn
3376      else
3377        if (GetEnvironmentVariable('ALLUSERSPROFILE')<>'') and CfgFileExists(FixPath(GetEnvironmentVariable('ALLUSERSPROFILE'),false)+fn) then
3378          foundfn:=FixPath(GetEnvironmentVariable('ALLUSERSPROFILE'),false)+fn
3379      else
3380 {$endif WINDOWS}
3381 {$ifndef Unix}
3382       if CfgFileExists(exepath+fn) then
3383        foundfn:=exepath+fn
3384      else
3385 {$else}
3386       if CfgFileExists('/etc/'+fn) then
3387        foundfn:='/etc/'+fn
3388      else
3389 {$endif}
3390       check_configfile:=false;
3391    end;
3392 end;
3393 
3394 procedure read_arguments(cmd:TCmdStr);
3395 
3396   procedure def_cpu_macros;
3397     var
3398       abi : tabi;
3399       fputype : tfputype;
3400       cputype : tcputype;
3401       controller: tcontrollertype;
3402       s: string;
3403     begin
3404       for cputype:=low(tcputype) to high(tcputype) do
3405         undef_system_macro('CPU'+Cputypestr[cputype]);
3406       def_system_macro('CPU'+Cputypestr[init_settings.cputype]);
3407 
3408       for fputype:=low(tfputype) to high(tfputype) do
3409         undef_system_macro('FPU'+fputypestr[fputype]);
3410       def_system_macro('FPU'+fputypestr[init_settings.fputype]);
3411 
3412 {$PUSH}
3413 {$WARN 6018 OFF} { Unreachable code due to compile time evaluation }
3414       if ControllerSupport then
3415         begin
3416           for controller:=low(tcontrollertype) to high(tcontrollertype) do
3417             begin
3418               s:=embedded_controllers[controller].controllertypestr;
3419               if s<>'' then
3420                 undef_system_macro('FPC_MCU_'+s);
3421             end;
3422           s:=embedded_controllers[init_settings.controllertype].controllertypestr;
3423           if s<>'' then
3424             def_system_macro('FPC_MCU_'+s);
3425         end;
3426 {$POP}
3427 
3428       { define abi }
3429       for abi:=low(tabi) to high(tabi) do
3430         undef_system_macro('FPC_ABI_'+abiinfo[abi].name);
3431       def_system_macro('FPC_ABI_'+abiinfo[target_info.abi].name);
3432 
3433 
3434       { Define FPC_ABI_EABI in addition to FPC_ABI_EABIHF on EABI VFP hardfloat
3435         systems since most code needs to behave the same on both}
3436       if target_info.abi = abi_eabihf then
3437         def_system_macro('FPC_ABI_EABI');
3438 
3439       { using a case is pretty useless here (FK) }
3440       { some stuff for TP compatibility }
3441       {$ifdef i386}
3442         def_system_macro('CPU86');
3443         def_system_macro('CPU87');
3444         def_system_macro('CPU386');
3445       {$endif}
3446 
3447       { new processor stuff }
3448       {$ifdef i386}
3449         def_system_macro('CPUI386');
3450         def_system_macro('CPU32');
3451         def_system_macro('CPUX86');
3452         def_system_macro('FPC_HAS_TYPE_EXTENDED');
3453         def_system_macro('FPC_HAS_TYPE_DOUBLE');
3454         def_system_macro('FPC_HAS_TYPE_SINGLE');
3455       {$endif}
3456 
3457       {$ifdef m68k}
3458         def_system_macro('CPU68');
3459         def_system_macro('CPU68K');
3460         def_system_macro('CPUM68K');
3461         def_system_macro('CPU32');
3462         def_system_macro('FPC_CURRENCY_IS_INT64');
3463         def_system_macro('FPC_COMP_IS_INT64');
3464       {$endif}
3465 
3466       {$ifdef powerpc}
3467         def_system_macro('CPUPOWERPC');
3468         def_system_macro('CPUPOWERPC32');
3469         def_system_macro('CPU32');
3470         def_system_macro('FPC_CURRENCY_IS_INT64');
3471         def_system_macro('FPC_COMP_IS_INT64');
3472       {$endif}
3473 
3474       {$ifdef POWERPC64}
3475         def_system_macro('CPUPOWERPC');
3476         def_system_macro('CPUPOWERPC64');
3477         def_system_macro('CPU64');
3478         def_system_macro('FPC_CURRENCY_IS_INT64');
3479         def_system_macro('FPC_COMP_IS_INT64');
3480       {$endif}
3481 
3482       {$ifdef x86_64}
3483         def_system_macro('CPUX86_64');
3484         def_system_macro('CPUAMD64');
3485         def_system_macro('CPU64');
3486         def_system_macro('CPUX64');
3487         { not supported for now, afaik (FK)
3488          def_system_macro('FPC_HAS_TYPE_FLOAT128'); }
3489       {$ifndef FPC_SUPPORT_X87_TYPES_ON_WIN64}
3490         { normally, win64 doesn't support the legacy fpu }
3491         if target_info.system=system_x86_64_win64 then
3492           begin
3493             def_system_macro('FPC_CURRENCY_IS_INT64');
3494             def_system_macro('FPC_COMP_IS_INT64');
3495           end;
3496       {$endif FPC_SUPPORT_X87_TYPES_ON_WIN64}
3497       {$endif}
3498 
3499       {$ifdef sparc}
3500         def_system_macro('CPUSPARCGEN');
3501         def_system_macro('CPUSPARC');
3502         def_system_macro('CPUSPARC32');
3503         def_system_macro('CPU32');
3504         def_system_macro('FPC_CURRENCY_IS_INT64');
3505         def_system_macro('FPC_COMP_IS_INT64');
3506       {$endif}
3507 
3508       {$ifdef sparc64}
3509         def_system_macro('CPUSPARCGEN');
3510         def_system_macro('CPUSPARC64');
3511         def_system_macro('CPU64');
3512         def_system_macro('FPC_CURRENCY_IS_INT64');
3513         def_system_macro('FPC_COMP_IS_INT64');
3514       {$endif}
3515 
3516       {$ifdef arm}
3517         def_system_macro('CPUARM');
3518         def_system_macro('CPU32');
3519         def_system_macro('FPC_CURRENCY_IS_INT64');
3520         def_system_macro('FPC_COMP_IS_INT64');
3521       {$endif arm}
3522 
3523       {$ifdef avr}
3524         def_system_macro('CPUAVR');
3525         def_system_macro('CPU16');
3526         def_system_macro('FPC_CURRENCY_IS_INT64');
3527         def_system_macro('FPC_COMP_IS_INT64');
3528       {$endif avr}
3529 
3530       {$ifdef jvm}
3531         def_system_macro('CPUJVM');
3532         def_system_macro('CPU32');
3533         def_system_macro('FPC_CURRENCY_IS_INT64');
3534         def_system_macro('FPC_COMP_IS_INT64');
3535       {$endif jvm}
3536 
3537       {$ifdef mipsel}
3538         def_system_macro('CPUMIPS');
3539         def_system_macro('CPUMIPS32');
3540         def_system_macro('CPUMIPSEL');
3541         def_system_macro('CPUMIPSEL32');
3542         def_system_macro('CPU32');
3543         def_system_macro('FPC_HAS_TYPE_DOUBLE');
3544         def_system_macro('FPC_HAS_TYPE_SINGLE');
3545         def_system_macro('FPC_INCLUDE_SOFTWARE_INT64_TO_DOUBLE');
3546         def_system_macro('FPC_CURRENCY_IS_INT64');
3547         def_system_macro('FPC_COMP_IS_INT64');
3548         def_system_macro('FPC_REQUIRES_PROPER_ALIGNMENT');
3549         { On most systems, locals are accessed relative to base pointer,
3550           but for MIPS cpu, they are accessed relative to stack pointer.
3551           This needs adaptation for so low level routines,
3552           like MethodPointerLocal and related objects unit functions. }
3553         def_system_macro('FPC_LOCALS_ARE_STACK_REG_RELATIVE');
3554       {$endif mipsel}
3555 
3556       {$ifdef mipseb}
3557         def_system_macro('CPUMIPS');
3558         def_system_macro('CPUMIPS32');
3559         def_system_macro('CPUMIPSEB');
3560         def_system_macro('CPUMIPSEB32');
3561         def_system_macro('CPU32');
3562         def_system_macro('FPC_HAS_TYPE_DOUBLE');
3563         def_system_macro('FPC_HAS_TYPE_SINGLE');
3564         def_system_macro('FPC_INCLUDE_SOFTWARE_INT64_TO_DOUBLE');
3565         def_system_macro('FPC_CURRENCY_IS_INT64');
3566         def_system_macro('FPC_COMP_IS_INT64');
3567         def_system_macro('FPC_REQUIRES_PROPER_ALIGNMENT');
3568         { See comment above for mipsel }
3569         def_system_macro('FPC_LOCALS_ARE_STACK_REG_RELATIVE');
3570       {$endif}
3571 
3572       {$ifdef i8086}
3573         def_system_macro('CPU86');  { Borland compatibility }
3574         def_system_macro('CPU87');  { Borland compatibility }
3575         def_system_macro('CPUI8086');
3576         def_system_macro('CPU16');
3577         def_system_macro('FPC_HAS_TYPE_EXTENDED');
3578         def_system_macro('FPC_HAS_TYPE_DOUBLE');
3579         def_system_macro('FPC_HAS_TYPE_SINGLE');
3580         case init_settings.x86memorymodel of
3581           mm_tiny:    def_system_macro('FPC_MM_TINY');
3582           mm_small:   def_system_macro('FPC_MM_SMALL');
3583           mm_medium:  def_system_macro('FPC_MM_MEDIUM');
3584           mm_compact: def_system_macro('FPC_MM_COMPACT');
3585           mm_large:   def_system_macro('FPC_MM_LARGE');
3586           mm_huge:    def_system_macro('FPC_MM_HUGE');
3587         end;
3588       {$endif i8086}
3589 
3590       {$ifdef aarch64}
3591         def_system_macro('CPUAARCH64');
3592         def_system_macro('CPU64');
3593         def_system_macro('FPC_CURRENCY_IS_INT64');
3594         def_system_macro('FPC_COMP_IS_INT64');
3595       {$endif aarch64}
3596 
3597       {$if defined(cpu8bitalu)}
3598         def_system_macro('CPUINT8');
3599       {$elseif defined(cpu16bitalu)}
3600         def_system_macro('CPUINT16');
3601       {$elseif defined(cpu32bitalu)}
3602         def_system_macro('CPUINT32');
3603       {$elseif defined(cpu64bitalu)}
3604         def_system_macro('CPUINT64');
3605       {$endif defined(cpu64bitalu)}
3606 
3607       {$if defined(avr)}
3608         def_system_macro('FPC_HAS_INTERNAL_ABS_SHORTINT');
3609       {$endif}
3610       {$if defined(i8086) or defined(avr)}
3611         def_system_macro('FPC_HAS_INTERNAL_ABS_SMALLINT');
3612       {$endif i8086 or avr}
3613       { abs(long) is handled internally on all CPUs }
3614         def_system_macro('FPC_HAS_INTERNAL_ABS_LONG');
3615       {$if defined(i8086) or defined(i386) or defined(x86_64) or defined(powerpc64) or defined(aarch64)}
3616         def_system_macro('FPC_HAS_INTERNAL_ABS_INT64');
3617       {$endif i8086 or i386 or x86_64 or powerpc64 or aarch64}
3618 
3619         def_system_macro('FPC_HAS_UNICODESTRING');
3620         def_system_macro('FPC_RTTI_PACKSET1');
3621         def_system_macro('FPC_HAS_CPSTRING');
3622       {$ifdef x86_64}
3623         def_system_macro('FPC_HAS_RIP_RELATIVE');
3624       {$endif x86_64}
3625         def_system_macro('FPC_HAS_CEXTENDED');
3626         def_system_macro('FPC_HAS_RESSTRINITS');
3627 
3628       { these cpus have an inline rol/ror implementaion }
3629       {$ifdef cpurox}
3630       {$ifdef m68k}
3631         if CPUM68K_HAS_ROLROR in cpu_capabilities[init_settings.cputype] then
3632           def_system_macro('FPC_HAS_INTERNAL_ROX');
3633       {$else}
3634         def_system_macro('FPC_HAS_INTERNAL_ROX');
3635       {$endif}
3636       {$endif}
3637 
3638       {$ifdef powerpc64}
3639         def_system_macro('FPC_HAS_LWSYNC');
3640       {$endif}
3641 
3642       { currently, all supported CPUs have an internal sar implementation }
3643         def_system_macro('FPC_HAS_INTERNAL_SAR');
3644       {$ifdef SUPPORT_GET_FRAME}
3645         def_system_macro('INTERNAL_BACKTRACE');
3646       {$endif SUPPORT_GET_FRAME}
3647         def_system_macro('STR_CONCAT_PROCS');
3648       {$warnings off}
3649         if pocall_default = pocall_register then
3650           def_system_macro('REGCALL');
3651       {$warnings on}
3652     end;
3653 
3654 var
3655   env: ansistring;
3656   i : tfeature;
3657   j : longint;
3658   abi : tabi;
3659   tmplist : TCmdStrList;
3660   cmditem,
3661   tmpcmditem : TCmdStrListItem;
3662   cmdstr : TCmdStr;
3663 {$if defined(cpucapabilities)}
3664   cpuflag : tcpuflags;
3665   hs : string;
3666 {$endif defined(cpucapabilities)}
3667 begin
3668   option:=coption.create;
3669   disable_configfile:=false;
3670 
3671   { Non-core target defines }
3672   Option.TargetOptions(true);
3673 
3674 { get default messagefile }
3675   msgfilename:=GetEnvironmentVariable('PPC_ERROR_FILE');
3676 
3677 { default configfile can be specified on the commandline,
3678    remove it first }
3679   if (cmd<>'') and (cmd[1]='[') then
3680     begin
3681       ppccfg:=Copy(cmd,2,pos(']',cmd)-2);
3682       Delete(cmd,1,pos(']',cmd));
3683     end
3684   else
3685     ppccfg:='fpc.cfg';
3686 
3687 { first pass reading of parameters, only -i -v -T etc.}
3688   option.firstpass:=true;
3689   if cmd<>'' then
3690     option.parsecmd(cmd)
3691   else
3692     begin
3693       option.read_parameters;
3694       { Write only quickinfo }
3695       if option.quickinfo<>'' then
3696         option.writequickinfo;
3697     end;
3698   option.firstpass:=false;
3699 
3700   { redefine target options so all defines are written even if no -Txxx is passed on the command line }
3701   Option.TargetOptions(true);
3702 
3703 { target is set here, for wince the default app type is gui }
3704   if target_info.system in systems_wince then
3705     SetApptype(app_gui)
3706   else
3707     SetApptype(apptype);
3708 
3709 { default defines }
3710   def_system_macro(target_info.shortname);
3711   def_system_macro('FPC');
3712   def_system_macro('VER'+version_nr);
3713   def_system_macro('VER'+version_nr+'_'+release_nr);
3714   def_system_macro('VER'+version_nr+'_'+release_nr+'_'+patch_nr);
3715 
3716 { Temporary defines, until things settle down }
3717   def_system_macro('FPC_HAS_OPERATOR_ENUMERATOR');
3718   def_system_macro('FPC_HAS_CONSTREF');
3719   def_system_macro('FPC_STATICRIPFIXED');
3720   def_system_macro('FPC_VARIANTCOPY_FIXED');
3721   def_system_macro('FPC_DYNARRAYCOPY_FIXED');
3722   def_system_macro('FPC_HAS_MEMBAR');
3723   def_system_macro('FPC_SETBASE_USED');
3724 
3725   { don't remove this, it's also for fpdoc necessary (FK) }
3726   def_system_macro('FPC_HAS_FEATURE_SUPPORT');
3727 
3728   { make cpu makros available when reading the config files the second time }
3729   def_cpu_macros;
3730 
3731   if tf_cld in target_info.flags then
3732     if not UpdateTargetSwitchStr('CLD', init_settings.targetswitches, true) then
3733       InternalError(2013092801);
3734   if tf_x86_far_procs_push_odd_bp in target_info.flags then
3735     if not UpdateTargetSwitchStr('FARPROCSPUSHODDBP', init_settings.targetswitches, true) then
3736       InternalError(2013092801);
3737 
3738   { Use standard Android NDK prefixes when cross-compiling }
3739   if (source_info.system<>target_info.system) and (target_info.system in systems_android) then
3740     case target_info.system of
3741       system_arm_android:
3742         utilsprefix:='arm-linux-androideabi-';
3743       system_i386_android:
3744         utilsprefix:='i686-linux-android-';
3745       else
3746         utilsprefix:=target_cpu_string + '-linux-android-';
3747     end;
3748 
3749   { Set up default value for the heap }
3750   if target_info.system in systems_embedded then
3751     begin
3752       case target_info.system of
3753 {$ifdef AVR}
3754         system_avr_embedded:
3755           if init_settings.controllertype=ct_avrsim then
3756             heapsize:=8192
3757           else
3758             heapsize:=128;
3759 {$endif AVR}
3760         system_arm_embedded:
3761           heapsize:=256;
3762         system_mipsel_embedded:
3763           heapsize:=256;
3764         else
3765           heapsize:=256;
3766       end;
3767     end;
3768 
3769   { read configuration file }
3770   if (not disable_configfile) and
3771      (ppccfg<>'') then
3772     read_configfile:=check_configfile(ppccfg,ppccfg)
3773   else
3774     read_configfile := false;
3775 
3776 { Read commandline and configfile }
3777   param_file:='';
3778 
3779   { read configfile }
3780   if read_configfile then
3781     option.interpret_file(ppccfg);
3782 
3783   { read parameters again to override config file }
3784   if cmd<>'' then
3785     option.parsecmd(cmd)
3786   else
3787     begin
3788       { Write help pages if no parameters are passed }
3789       if (paramcount=0) then
3790         Option.WriteHelpPages;
3791       option.read_parameters;
3792       { Write only quickinfo }
3793       if option.quickinfo<>'' then
3794         option.writequickinfo;
3795     end;
3796 
3797   { check the compatibility of different options and adjust them if necessary
3798     (and print possible errors)
3799   }
3800   option.checkoptionscompatibility;
3801 
3802   { uses the CPUXXX-defines and target_info to determine whether the selected
3803     target processor, if any, is supported }
3804   Option.VerifyTargetProcessor;
3805 
3806   { Stop if errors in options }
3807   if ErrorCount>0 then
3808    StopOptions(1);
3809 
3810   { endian define }
3811   case target_info.endian of
3812     endian_little :
3813       begin
3814         def_system_macro('ENDIAN_LITTLE');
3815         def_system_macro('FPC_LITTLE_ENDIAN');
3816       end;
3817     endian_big :
3818       begin
3819         def_system_macro('ENDIAN_BIG');
3820         def_system_macro('FPC_BIG_ENDIAN');
3821       end;
3822   end;
3823 
3824   { Write logo }
3825   if option.ParaLogo then
3826     option.writelogo;
3827 
3828 { Check file to compile }
3829   if param_file='' then
3830    begin
3831      Message(option_no_source_found);
3832      StopOptions(1);
3833    end;
3834 {$ifndef Unix}
3835   param_file:=FixFileName(param_file);
3836 {$endif not unix}
3837   inputfilepath:=ExtractFilePath(param_file);
3838   inputfilename:=ExtractFileName(param_file);
3839   if ExtractFileExt(inputfilename)='' then
3840     begin
3841       if FileExists(inputfilepath+ChangeFileExt(inputfilename,sourceext)) then
3842         inputfilename:=ChangeFileExt(inputfilename,sourceext)
3843       else if FileExists(inputfilepath+ChangeFileExt(inputfilename,pasext)) then
3844         inputfilename:=ChangeFileExt(inputfilename,pasext)
3845       else if ((m_mac in current_settings.modeswitches) or
3846               (tf_p_ext_support in target_info.flags))
3847              and FileExists(inputfilepath+ChangeFileExt(inputfilename,pext)) then
3848         inputfilename:=ChangeFileExt(inputfilename,pext);
3849     end;
3850 
3851   { Check output dir }
3852   if (OutputExeDir<>'') and
3853      not PathExists(OutputExeDir,false) then
3854     begin
3855       Message1(general_e_path_does_not_exist,OutputExeDir);
3856       StopOptions(1);
3857     end;
3858 
3859   { Add paths specified with parameters to the searchpaths }
3860   UnitSearchPath.AddList(option.ParaUnitPath,true);
3861   ObjectSearchPath.AddList(option.ParaObjectPath,true);
3862   IncludeSearchPath.AddList(option.ParaIncludePath,true);
3863   LibrarySearchPath.AddList(option.ParaLibraryPath,true);
3864   FrameworkSearchPath.AddList(option.ParaFrameworkPath,true);
3865   packagesearchpath.addlist(option.parapackagepath,true);
3866   for j:=0 to option.parapackages.count-1 do
3867     add_package(option.parapackages.NameOfIndex(j),true,true);
3868 
3869   { add default namespaces }
3870   tmplist:=TCmdStrList.Create;
3871   cmditem:=TCmdStrListItem(option.paranamespaces.First);
3872   while assigned(cmditem) do
3873     begin
3874       { use a temporary list cause if ";" are involved we need to reverse the
3875         order due to how TCmdStrList behaves }
3876       cmdstr:=cmditem.str;
3877       repeat
3878         j:=Pos(';',cmdstr);
3879         if j>0 then
3880           begin
3881             tmplist.insert(copy(cmdstr,1,j-1));
3882             delete(cmdstr,1,j);
3883           end
3884         else
3885           tmplist.insert(cmdstr);
3886       until j=0;
3887       tmpcmditem:=TCmdStrListItem(tmplist.First);
3888       while assigned(tmpcmditem) do
3889         begin
3890           namespacelist.insert(tmpcmditem.Str);
3891           tmpcmditem:=TCmdStrListItem(tmpcmditem.Next);
3892         end;
3893       tmplist.clear;
3894       cmditem:=TCmdStrListItem(cmditem.Next);
3895     end;
3896   tmplist.Free;
3897 
3898   { add unit environment and exepath to the unit search path }
3899   if inputfilepath<>'' then
3900    Unitsearchpath.AddPath(inputfilepath,true);
3901   if not disable_configfile then
3902     begin
3903       env:=GetEnvironmentVariable(target_info.unit_env);
3904       if env<>'' then
3905         UnitSearchPath.AddPath(GetEnvironmentVariable(target_info.unit_env),false);
3906     end;
3907 
3908 {$ifdef Unix}
3909   fpcdir:=FixPath(GetEnvironmentVariable('FPCDIR'),false);
3910   if fpcdir='' then
3911     begin
3912       if PathExists('/usr/local/lib/fpc/'+version_string,true) then
3913         fpcdir:='/usr/local/lib/fpc/'+version_string+'/'
3914       else
3915         fpcdir:='/usr/lib/fpc/'+version_string+'/';
3916     end;
3917 {$else unix}
3918   fpcdir:=FixPath(GetEnvironmentVariable('FPCDIR'),false);
3919   if fpcdir='' then
3920     begin
3921       fpcdir:=ExePath+'../';
3922       if not(PathExists(fpcdir+'units',true)) and
3923          not(PathExists(fpcdir+'rtl',true)) then
3924         fpcdir:=fpcdir+'../';
3925     end;
3926 {$endif unix}
3927   { first try development RTL, else use the default installation path }
3928   if not disable_configfile then
3929     begin
3930       if PathExists(FpcDir+'rtl',true) then
3931         if (tf_use_8_3 in Source_Info.Flags) or
3932            (tf_use_8_3 in Target_Info.Flags) then
3933           UnitSearchPath.AddPath(FpcDir+'rtl/'+target_os_string,false)
3934         else
3935           UnitSearchPath.AddPath(FpcDir+'rtl/'+target_full_string,false)
3936       else
3937         if (tf_use_8_3 in Source_Info.Flags) or
3938            (tf_use_8_3 in Target_Info.Flags) then
3939           UnitSearchPath.AddPath(FpcDir+'units/'+target_os_string+'/rtl',false)
3940         else
3941           UnitSearchPath.AddPath(FpcDir+'units/'+target_full_string+'/rtl',false);
3942     end;
3943   { Add exepath if the exe is not in the current dir, because that is always searched already.
3944     Do not add it when linking on the target because then we can maybe already find
3945     .o files that are not for the target }
3946   if (ExePath<>cfileutl.GetCurrentDir) and
3947      not(cs_link_on_target in init_settings.globalswitches) then
3948    UnitSearchPath.AddPath(ExePath,false);
3949   { Add unit dir to the object and library path }
3950   objectsearchpath.AddList(unitsearchpath,false);
3951   librarysearchpath.AddList(unitsearchpath,false);
3952 
3953 {$ifdef llvm}
3954   { default to clang }
3955   if (option.paratargetasm=as_none) then
3956     begin
3957       option.paratargetasm:=as_clang_llvm;
3958     end;
3959 {$endif llvm}
3960   { maybe override assembler }
3961   if (option.paratargetasm<>as_none) then
3962     begin
3963       if not set_target_asm(option.paratargetasm) then
3964         begin
3965           if assigned(asminfos[option.paratargetasm]) then
3966             Message2(option_incompatible_asm,asminfos[option.paratargetasm]^.idtxt,target_info.name)
3967           else
3968             Message2(option_incompatible_asm,'<invalid assembler>',target_info.name);
3969           set_target_asm(target_info.assemextern);
3970           Message1(option_asm_forced,target_asm.idtxt);
3971         end;
3972       if (af_no_debug in asminfos[option.paratargetasm]^.flags) and
3973          (option.paratargetdbg<>dbg_none) then
3974         begin
3975           Message1(option_confict_asm_debug,
3976             asminfos[option.paratargetasm]^.idtxt);
3977           option.paratargetdbg:=dbg_none;
3978           exclude(init_settings.moduleswitches,cs_debuginfo);
3979         end;
3980       { Some assemblers, like clang, do not support
3981         stabs debugging format, switch to dwardé in that case }
3982       if (af_no_stabs in asminfos[option.paratargetasm]^.flags) and
3983          (option.paratargetdbg=dbg_stabs) then
3984         begin
3985           option.paratargetdbg:=dbg_dwarf2;
3986         end;
3987 
3988     end;
3989   {TOptionheck a second time as we might have changed assembler just above }
3990   option.checkoptionscompatibility;
3991 
3992   { maybe override debug info format }
3993   if (option.paratargetdbg<>dbg_none) then
3994     if not set_target_dbg(option.paratargetdbg) then
3995       Message(option_w_unsupported_debug_format);
3996 
3997   { switch assembler if it's binary and we got -a on the cmdline }
3998   if (cs_asm_leave in init_settings.globalswitches) and
3999      (af_outputbinary in target_asm.flags) then
4000    begin
4001      Message(option_switch_bin_to_src_assembler);
4002 {$ifdef llvm}
4003      set_target_asm(as_clang_llvm);
4004 {$else}
4005      set_target_asm(target_info.assemextern);
4006 {$endif}
4007      { At least i8086 needs that for nasm and -CX
4008        which is incompatible with internal linker }
4009      option.checkoptionscompatibility;
4010    end;
4011 
4012   { Force use of external linker if there is no
4013     internal linker or the linking is skipped }
4014   if not(cs_link_extern in init_settings.globalswitches) and
4015      ((target_info.link=ld_none) or
4016       (cs_link_nolink in init_settings.globalswitches)) then
4017     begin
4018       include(init_settings.globalswitches,cs_link_extern);
4019     end;
4020 
4021   { turn off stripping if compiling with debuginfo or profile }
4022   if (
4023       (cs_debuginfo in init_settings.moduleswitches) or
4024       (cs_profile in init_settings.moduleswitches)
4025      ) and
4026      not(cs_link_separate_dbg_file in init_settings.globalswitches) then
4027     exclude(init_settings.globalswitches,cs_link_strip);
4028 
4029   { set Mac OS X version default macros if not specified explicitly }
4030   option.MaybeSetDefaultMacVersionMacro;
4031 
4032   { force fpu emulation on arm/wince, arm/gba, arm/embedded and arm/nds
4033     if fpu type not explicitly set }
4034   if not(option.FPUSetExplicitly) and
4035      ((target_info.system in [system_arm_wince,system_arm_gba,
4036          system_m68k_amiga,system_m68k_atari,
4037          system_arm_nds,system_arm_embedded])
4038 {$ifdef arm}
4039       or (target_info.abi=abi_eabi)
4040 {$endif arm}
4041      )
4042 {$if defined(arm) or defined (m68k)}
4043      or (init_settings.fputype=fpu_soft)
4044 {$endif arm or m68k}
4045   then
4046     begin
4047 {$ifdef cpufpemu}
4048       include(init_settings.moduleswitches,cs_fp_emulation);
4049       { cs_fp_emulation and fpu_soft are equal on arm and m68k }
4050       init_settings.fputype:=fpu_soft;
4051 {$endif cpufpemu}
4052     end;
4053 
4054 {$ifdef i386}
4055   case target_info.system of
4056     system_i386_android:
4057       begin
4058         { set default cpu type to PentiumM for Android unless specified otherwise }
4059         if not option.CPUSetExplicitly then
4060           init_settings.cputype:=cpu_PentiumM;
4061         if not option.OptCPUSetExplicitly then
4062           init_settings.optimizecputype:=cpu_PentiumM;
4063         { set default fpu type to SSSE3 for Android unless specified otherwise }
4064         if not option.FPUSetExplicitly then
4065           init_settings.fputype:=fpu_ssse3;
4066       end;
4067   end;
4068 {$endif i386}
4069 
4070 {$ifdef arm}
4071   case target_info.system of
4072     system_arm_ios:
4073       begin
4074         { set default cpu type to ARMv7 for Darwin unless specified otherwise, and fpu
4075           to VFPv3 (that's what all 32 bit ARM iOS devices use nowadays)
4076         }
4077         if not option.CPUSetExplicitly then
4078           init_settings.cputype:=cpu_armv7;
4079         if not option.OptCPUSetExplicitly then
4080           init_settings.optimizecputype:=cpu_armv7;
4081         if not option.FPUSetExplicitly then
4082           init_settings.fputype:=fpu_vfpv3;
4083       end;
4084     system_arm_android:
4085       begin
4086         { set default cpu type to ARMv5T for Android unless specified otherwise }
4087         if not option.CPUSetExplicitly then
4088           init_settings.cputype:=cpu_armv5t;
4089         if not option.OptCPUSetExplicitly then
4090           init_settings.optimizecputype:=cpu_armv5t;
4091       end;
4092   end;
4093 
4094   { ARMHF defaults }
4095   if (target_info.abi = abi_eabihf) then
4096     { set default cpu type to ARMv7a for ARMHF unless specified otherwise }
4097     begin
4098     {$ifdef CPUARMV6}
4099       { if the compiler is built for armv6, then
4100         inherit this setting, e.g. Raspian is armhf but
4101         only armv6, this makes rebuilds of the compiler
4102         easier }
4103       if not option.CPUSetExplicitly then
4104         init_settings.cputype:=cpu_armv6;
4105       if not option.OptCPUSetExplicitly then
4106         init_settings.optimizecputype:=cpu_armv6;
4107     {$else CPUARMV6}
4108       if not option.CPUSetExplicitly then
4109         init_settings.cputype:=cpu_armv7a;
4110       if not option.OptCPUSetExplicitly then
4111         init_settings.optimizecputype:=cpu_armv7a;
4112     {$endif CPUARMV6}
4113 
4114       { Set FPU type }
4115       if not(option.FPUSetExplicitly) then
4116         begin
4117           if init_settings.cputype < cpu_armv7 then
4118             init_settings.fputype:=fpu_vfpv2
4119           else
4120             init_settings.fputype:=fpu_vfpv3_d16;
4121         end
4122       else
4123         begin
4124           if not (init_settings.fputype in [fpu_vfpv2,fpu_vfpv3,fpu_vfpv3_d16,fpu_vfpv4])
4125 	     or (target_info.system = system_arm_ios) then
4126             begin
4127               Message(option_illegal_fpu_eabihf);
4128               StopOptions(1);
4129             end;
4130         end;
4131     end;
4132 
4133   if (init_settings.instructionset=is_thumb) and not(CPUARM_HAS_THUMB2 in cpu_capabilities[init_settings.cputype]) then
4134     begin
4135       def_system_macro('CPUTHUMB');
4136       if not option.FPUSetExplicitly then
4137         init_settings.fputype:=fpu_soft;
4138 {$if defined(FPC_ARMEL) or defined(FPC_ARMHF)}
4139       target_info.llvmdatalayout:='e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:64:128-a0:0:32-n32-S64';
4140 {$else FPC_ARMAL or FPC_ARMHF}
4141       if target_info.endian=endian_little then
4142         target_info.llvmdatalayout:='e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:32:64-v128:32:128-a0:0:32-n32-S32';
4143 {$endif FPC_ARMAL or FPC_ARMHF}
4144     end;
4145 
4146   if (init_settings.instructionset=is_thumb) and (CPUARM_HAS_THUMB2 in cpu_capabilities[init_settings.cputype]) then
4147     def_system_macro('CPUTHUMB2');
4148 {$endif arm}
4149 
4150 {$ifdef jvm}
4151   { set default CPU type to Dalvik when targeting Android }
4152   if target_info.system=system_jvm_android32 then
4153     begin
4154       if not option.CPUSetExplicitly then
4155         init_settings.cputype:=cpu_dalvik;
4156     end;
4157 {$endif jvm}
4158 
4159 {$ifdef llvm}
4160   { standard extension for llvm bitcode files }
4161   target_info.asmext:='.ll';
4162   { don't generate dwarf cfi, llvm will do that }
4163   exclude(target_info.flags,tf_needs_dwarf_cfi);
4164 {$endif llvm}
4165 {$ifdef mipsel}
4166   case target_info.system of
4167     system_mipsel_android:
4168       begin
4169         { set default cpu type to MIPS32 rev. 1 and hard float for MIPS-Android unless specified otherwise }
4170         if not option.CPUSetExplicitly then
4171           init_settings.cputype:=cpu_mips32;
4172         if not option.OptCPUSetExplicitly then
4173           init_settings.optimizecputype:=cpu_mips32;
4174         if not option.FPUSetExplicitly then
4175           init_settings.fputype:=fpu_mips2;
4176       end;
4177     system_mipsel_embedded:
4178       begin
4179         { set default cpu type to PIC32MX and softfloat for MIPSEL-EMBEDDED target unless specified otherwise }
4180         if not option.CPUSetExplicitly then
4181           init_settings.cputype:=cpu_pic32mx;
4182         if not option.OptCPUSetExplicitly then
4183           init_settings.optimizecputype:=cpu_pic32mx;
4184         if not option.FPUSetExplicitly then
4185           init_settings.fputype:=fpu_soft;
4186       end;
4187   end;
4188 {$endif mipsel}
4189 {$ifdef m68k}
4190   if init_settings.cputype in cpu_coldfire then
4191     def_system_macro('CPUCOLDFIRE');
4192 
4193   case target_info.system of
4194     system_m68k_linux,
4195     system_m68k_netbsd:
4196       begin
4197         if not (option.FPUSetExplicitly) and
4198            not (init_settings.cputype in cpu_coldfire) then
4199           begin
4200             { enable HW FPU for UNIX by default, but only for
4201               original 68k, not Coldfire }
4202             exclude(init_settings.moduleswitches,cs_fp_emulation);
4203             init_settings.fputype:=fpu_68881;
4204           end;
4205       end;
4206     system_m68k_palmos:
4207       begin
4208         if not option.CPUSetExplicitly then
4209           init_settings.cputype:=cpu_mc68000;
4210         if not (option.FPUSetExplicitly) then
4211           begin
4212             { No FPU for PalmOS by default }
4213             exclude(init_settings.moduleswitches,cs_fp_emulation);
4214             init_settings.fputype:=fpu_none;
4215           end;
4216       end;
4217   end;
4218 {$endif m68k}
4219 
4220   { now we can define cpu and fpu type }
4221   def_cpu_macros;
4222 
4223   { Use init_settings cpu type for asm cpu type,
4224     if asmcputype is cpu_none,
4225     at least as long as there is no explicit
4226     option to set it on command line PM }
4227   if init_settings.asmcputype = cpu_none then
4228     init_settings.asmcputype:=init_settings.cputype;
4229 
4230 {$ifdef llvm}
4231   def_system_macro('CPULLVM');
4232 {$endif llvm}
4233 
4234 {$if defined(cpucapabilities)}
4235   for cpuflag:=low(cpuflag) to high(cpuflag) do
4236     begin
4237       str(cpuflag,hs);
4238       if cpuflag in cpu_capabilities[init_settings.cputype] then
4239         def_system_macro(hs)
4240       else
4241         undef_system_macro(hs);
4242     end;
4243 {$endif defined(cpucapabilities)}
4244 
4245   if init_settings.fputype<>fpu_none then
4246     begin
4247 {$if defined(i386) or defined(i8086)}
4248       def_system_macro('FPC_HAS_TYPE_EXTENDED');
4249 {$endif}
4250       def_system_macro('FPC_HAS_TYPE_SINGLE');
4251       def_system_macro('FPC_HAS_TYPE_DOUBLE');
4252 {$if not defined(i386) and not defined(x86_64) and not defined(i8086) and not defined(aarch64)}
4253       def_system_macro('FPC_INCLUDE_SOFTWARE_INT64_TO_DOUBLE');
4254 {$endif}
4255 {$if defined(m68k)}
4256       def_system_macro('FPC_INCLUDE_SOFTWARE_LONGWORD_TO_DOUBLE');
4257 {$endif}
4258 {$ifdef x86_64}
4259 {$ifndef FPC_SUPPORT_X87_TYPES_ON_WIN64}
4260       { normally, win64 doesn't support the legacy fpu }
4261       if target_info.system=system_x86_64_win64 then
4262         undef_system_macro('FPC_HAS_TYPE_EXTENDED')
4263       else
4264 {$endif FPC_SUPPORT_X87_TYPES_ON_WIN64}
4265         def_system_macro('FPC_HAS_TYPE_EXTENDED');
4266 {$endif}
4267     end;
4268     { Enable now for testing }
4269 {$ifndef DISABLE_TLS_DIRECTORY}
4270     if target_info.system in systems_windows then
4271       def_system_macro('FPC_USE_TLS_DIRECTORY');
4272 {$endif not DISABLE_TLS_DIRECTORY}
4273 
4274 {$ifndef DISABLE_WIN64_SEH}
4275     if target_info.system=system_x86_64_win64 then
4276       def_system_macro('FPC_USE_WIN64_SEH');
4277 {$endif DISABLE_WIN64_SEH}
4278 
4279 {$ifndef DISABLE_WIN32_SEH}
4280     if target_info.system=system_i386_win32 then
4281       def_system_macro('FPC_USE_WIN32_SEH');
4282 {$endif not DISABLE_WIN32_SEH}
4283 
4284 {$ifdef ARM}
4285   { define FPC_DOUBLE_HILO_SWAPPED if needed to properly handle doubles in RTL }
4286   if (init_settings.fputype in [fpu_fpa,fpu_fpa10,fpu_fpa11]) and
4287     not(cs_fp_emulation in init_settings.moduleswitches) then
4288     def_system_macro('FPC_DOUBLE_HILO_SWAPPED');
4289 {$endif ARM}
4290 
4291 { inline bsf/bsr implementation }
4292 {$if not defined(llvm) and (defined(i386) or defined(x86_64) or defined(aarch64) or defined(powerpc) or defined(powerpc64))}
4293   def_system_macro('FPC_HAS_INTERNAL_BSF');
4294   def_system_macro('FPC_HAS_INTERNAL_BSR');
4295 {$endif}
4296 
4297 { hardware FMA support }
4298 {$if defined(i386) or defined(x86_64)}
4299   if (cpu_capabilities[current_settings.cputype]*[CPUX86_HAS_FMA,CPUX86_HAS_FMA4])<>[] then
4300     begin
4301       def_system_macro('FPC_HAS_FAST_FMA_SINGLE');
4302       def_system_macro('FPC_HAS_FAST_FMA_DOUBLE');
4303     end;
4304 {$endif defined(i386) or defined(x86_64)}
4305 
4306 {$if defined(arm)}
4307   { it is determined during system unit compilation if clz is used for bsf or not,
4308     this is not perfect but the current implementation bsf/bsr does not allow another
4309     solution }
4310   if (CPUARM_HAS_CLZ in cpu_capabilities[init_settings.cputype]) and
4311      ((init_settings.instructionset=is_arm) or
4312       (CPUARM_HAS_THUMB2 in cpu_capabilities[init_settings.cputype])) then
4313     begin
4314       def_system_macro('FPC_HAS_INTERNAL_BSR');
4315       if CPUARM_HAS_RBIT in cpu_capabilities[init_settings.cputype] then
4316         def_system_macro('FPC_HAS_INTERNAL_BSF');
4317     end;
4318 {$endif}
4319 
4320 {$if defined(powerpc64)}
4321   { on sysv targets, default to elfv2 for little endian and to elfv1 for
4322     big endian (unless specified otherwise). As the gcc man page says:
4323     "Overriding the default ABI requires special system support and is
4324      likely to fail in spectacular ways" }
4325   if not option.ABISetExplicitly then
4326     begin
4327       if (target_info.abi=abi_powerpc_sysv) and
4328          (target_info.endian=endian_little) then
4329         target_info.abi:=abi_powerpc_elfv2
4330       else
4331         if (target_info.abi=abi_powerpc_elfv2) and
4332          (target_info.endian=endian_big) then
4333         target_info.abi:=abi_powerpc_sysv
4334     end;
4335 {$endif}
4336 
4337 {$if defined(powerpc) or defined(powerpc64)}
4338   { define _CALL_ELF symbol like gcc }
4339   case target_info.abi of
4340     abi_powerpc_sysv:
4341       set_system_compvar('_CALL_ELF','1');
4342     abi_powerpc_elfv2:
4343       set_system_compvar('_CALL_ELF','2');
4344     end;
4345 {$endif}
4346 
4347   { Section smartlinking conflicts with import sections on Windows }
4348   if GenerateImportSection and
4349      (target_info.system in [system_i386_win32,system_x86_64_win64]) then
4350     exclude(target_info.flags,tf_smartlink_sections);
4351 
4352   if not option.LinkTypeSetExplicitly then
4353     set_default_link_type;
4354 
4355   { Default alignment settings,
4356     1. load the defaults for the target
4357     2. override with generic optimizer setting (little size)
4358     3. override with the user specified -Oa }
4359   UpdateAlignment(init_settings.alignment,target_info.alignment);
4360   if (cs_opt_size in init_settings.optimizerswitches) then
4361    begin
4362      init_settings.alignment.procalign:=1;
4363      init_settings.alignment.jumpalign:=1;
4364      init_settings.alignment.loopalign:=1;
4365 {$ifdef x86}
4366      { constalignmax=1 keeps the executable and thus the memory foot print small but
4367        all processors except x86 are really hurt by this or might even crash }
4368      init_settings.alignment.constalignmax:=1;
4369 {$endif x86}
4370    end;
4371 
4372   UpdateAlignment(init_settings.alignment,option.paraalignment);
4373 
4374   set_system_macro('FPC_VERSION',version_nr);
4375   set_system_macro('FPC_RELEASE',release_nr);
4376   set_system_macro('FPC_PATCH',patch_nr);
4377   set_system_macro('FPC_FULLVERSION',Format('%d%.02d%.02d',[StrToInt(version_nr),StrToInt(release_nr),StrToInt(patch_nr)]));
4378 
4379   if target_info.system in systems_indirect_entry_information then
4380     def_system_macro('FPC_HAS_INDIRECT_ENTRY_INFORMATION');
4381 
4382   if not (tf_winlikewidestring in target_info.flags) then
4383     def_system_macro('FPC_WIDESTRING_EQUAL_UNICODESTRING');
4384 
4385   if tf_supports_packages in target_info.flags then
4386     def_system_macro('FPC_HAS_DYNAMIC_PACKAGES');
4387 
4388   if target_info.system in systems_indirect_var_imports then
4389     def_system_macro('FPC_HAS_INDIRECT_VAR_ACCESS');
4390 
4391   if cs_compilesystem in init_settings.moduleswitches then
4392     for i:=low(tfeature) to high(tfeature) do
4393       if i in features then
4394         def_system_macro('FPC_HAS_FEATURE_'+featurestr[i]);
4395 
4396 {$push}
4397 {$warn 6018 off} { Unreachable code due to compile time evaluation }
4398   if ControllerSupport and (target_info.system in systems_embedded) and
4399     (init_settings.controllertype<>ct_none) then
4400     begin
4401       with embedded_controllers[init_settings.controllertype] do
4402         begin
4403           set_system_macro('FPC_FLASHBASE',tostr(flashbase));
4404           set_system_macro('FPC_FLASHSIZE',tostr(flashsize));
4405           set_system_macro('FPC_SRAMBASE',tostr(srambase));
4406           set_system_macro('FPC_SRAMSIZE',tostr(sramsize));
4407           set_system_macro('FPC_EEPROMBASE',tostr(eeprombase));
4408           set_system_macro('FPC_EEPROMSIZE',tostr(eepromsize));
4409           set_system_macro('FPC_BOOTBASE',tostr(bootbase));
4410           set_system_macro('FPC_BOOTSIZE',tostr(bootsize));
4411         end;
4412     end;
4413 {$pop}
4414   { as stackalign is not part of the alignment record, we do not need to define the others alignments for symmetry yet }
4415   set_system_macro('FPC_STACKALIGNMENT',tostr(target_info.stackalign));
4416 
4417   option.free;
4418   Option:=nil;
4419 
4420   clearstack_pocalls := [pocall_cdecl,pocall_cppdecl,pocall_syscall,pocall_mwpascal,pocall_sysv_abi_cdecl,pocall_ms_abi_cdecl];
4421   cdecl_pocalls := [pocall_cdecl, pocall_cppdecl, pocall_mwpascal, pocall_sysv_abi_cdecl, pocall_ms_abi_cdecl];
4422   if (tf_safecall_clearstack in target_info.flags) then
4423     begin
4424       include (cdecl_pocalls, pocall_safecall);
4425       include (clearstack_pocalls, pocall_safecall)
4426     end;
4427 end;
4428 
4429 
4430 initialization
4431   coption:=toption;
4432 finalization
4433   if assigned(option) then
4434    option.free;
4435 end.
4436