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