diff --git a/compiler/cutils.pas b/compiler/cutils.pas index 79e4809bef..760df2ced7 100644 --- a/compiler/cutils.pas +++ b/compiler/cutils.pas @@ -133,7 +133,6 @@ interface function DePascalQuote(var s: ansistring): Boolean; function CompareStr(const S1, S2: string): Integer; function CompareText(S1, S2: string): integer; - function CompareVersionStrings(s1,s2: string): longint; { releases the string p and assignes nil to p } { if p=nil then freemem isn't called } @@ -1275,72 +1274,6 @@ implementation end; - function CompareVersionStrings(s1,s2: string): longint; - var - start1, start2, - i1, i2, - num1,num2, - res, - err : longint; - begin - i1:=1; - i2:=1; - repeat - start1:=i1; - start2:=i2; - while (i1<=length(s1)) and - (s1[i1] in ['0'..'9']) do - inc(i1); - while (i2<=length(s2)) and - (s2[i2] in ['0'..'9']) do - inc(i2); - { one of the strings misses digits -> other is the largest version } - if i1=start1 then - if i2=start2 then - exit(0) - else - exit(-1) - else if i2=start2 then - exit(1); - { get version number part } - val(copy(s1,start1,i1-start1),num1,err); - val(copy(s2,start2,i2-start2),num2,err); - { different -> done } - res:=num1-num2; - if res<>0 then - exit(res); - { if one of the two is at the end while the other isn't, add a '.0' } - if (i1>length(s1)) and - (i2<=length(s2)) then - s1:=s1+'.0'; - if (i2>length(s2)) and - (i1<=length(s1)) then - s2:=s2+'.0'; - { compare non-numerical characters normally } - while (i1<=length(s1)) and - not(s1[i1] in ['0'..'9']) and - (i2<=length(s2)) and - not(s2[i2] in ['0'..'9']) do - begin - res:=ord(s1[i1])-ord(s2[i2]); - if res<>0 then - exit(res); - inc(i1); - inc(i2); - end; - { both should be digits again now, otherwise pick the one with the - digits as the largest (it more likely means that the input was - ill-formatted though) } - if (i1<=length(s1)) and - not(s1[i1] in ['0'..'9']) then - exit(-1); - if (i2<=length(s2)) and - not(s2[i2] in ['0'..'9']) then - exit(1); - until false; - end; - - {***************************************************************************** Ansistring (PChar+Length) *****************************************************************************} diff --git a/compiler/globals.pas b/compiler/globals.pas index 0035f812cd..a15e960a38 100644 --- a/compiler/globals.pas +++ b/compiler/globals.pas @@ -47,7 +47,7 @@ interface {$if defined(LLVM) or defined(GENERIC_CPU)} llvminfo, {$endif LLVM or GENERIC_CPU} - globtype,version,systems; + globtype,version,versioncmp,systems; const delphimodeswitches = @@ -352,8 +352,9 @@ interface GenerateImportSection, GenerateImportSectionSetExplicitly, RelocSection : boolean; + MacOSXVersionMin, - iPhoneOSVersionMin: string[15]; + iPhoneOSVersionMin: tversion; RelocSectionSetExplicitly : boolean; current_tokenpos, { position of the last token } @@ -1706,8 +1707,8 @@ implementation GenerateImportSection:=false; RelocSection:=false; RelocSectionSetExplicitly:=false; - MacOSXVersionMin:=''; - iPhoneOSVersionMin:=''; + MacOSXVersionMin.invalidate; + iPhoneOSVersionMin.invalidate; { memory sizes, will be overridden by parameter or default for target in options or init_parser } stacksize:=0; diff --git a/compiler/llvm/nllvmutil.pas b/compiler/llvm/nllvmutil.pas index 3cdb2fe17d..3afedee6f3 100644 --- a/compiler/llvm/nllvmutil.pas +++ b/compiler/llvm/nllvmutil.pas @@ -49,7 +49,7 @@ interface implementation uses - verbose,cutils,globals,fmodule,systems,finput, + verbose,cutils,globals,fmodule,systems,finput,versioncmp, aasmtai,cpubase,llvmbase,aasmllvm, aasmcnst,nllvmtcon, symbase,symtable,defutil, @@ -295,7 +295,7 @@ implementation begin { Objective-C ABI version } if not(target_info.system in [system_powerpc_darwin,system_powerpc64_darwin,system_i386_darwin,system_x86_64_darwin]) or - (CompareVersionStrings(MacOSXVersionMin,'10.5')>=0) then + (MacOSXVersionMin.relationto(10,5,0)>=0) then objcabiversion:=2 else objcabiversion:=1; diff --git a/compiler/options.pas b/compiler/options.pas index 8629761a55..ae4f0baafb 100644 --- a/compiler/options.pas +++ b/compiler/options.pas @@ -26,7 +26,7 @@ unit options; interface uses - cfileutl,cclasses, + cfileutl,cclasses,versioncmp, globtype,globals,verbose,systems,cpuinfo,comprsrc; Type @@ -80,7 +80,7 @@ Type MacVersionSet: boolean; IdfVersionSet: boolean; processorstr: TCmdStr; - function ParseMacVersionMin(out minstr, emptystr: string; const compvarname, value: string; ios: boolean): boolean; + function ParseMacVersionMin(out minversion, invalidateversion: tversion; const compvarname, value: string; ios: boolean): boolean; procedure MaybeSetDefaultMacVersionMacro; {$ifdef XTENSA} function ParseVersionStr(out ver: longint; const compvarname, value: string): boolean; @@ -1095,7 +1095,7 @@ begin end; -function toption.ParseMacVersionMin(out minstr, emptystr: string; const compvarname, value: string; ios: boolean): boolean; +function toption.ParseMacVersionMin(out minversion, invalidateversion: tversion; const compvarname, value: string; ios: boolean): boolean; function subval(start,maxlen: longint; out stop: longint): string; var @@ -1116,12 +1116,14 @@ function toption.ParseMacVersionMin(out minstr, emptystr: string; const compvarn var temp, - compvarvalue: string[15]; - i: longint; + compvarvalue, + versionstr: string[15]; + major, minor, patch: cardinal; + i, err: longint; osx_minor_two_digits: boolean; begin - minstr:=value; - emptystr:=''; + invalidateversion.invalidate; + versionstr:=value; MacVersionSet:=false; { check whether the value is a valid version number } if value='' then @@ -1138,10 +1140,16 @@ function toption.ParseMacVersionMin(out minstr, emptystr: string; const compvarn if (i>=length(value)) or (value[i]<>'.') then exit(false); + val(compvarvalue,major,err); + if err<>0 then + exit(false); { minor version number } temp:=subval(i+1,2,i); if temp='' then exit(false); + val(temp,minor,err); + if err<>0 then + exit(false); { on Mac OS X, the minor version number was originally limited to 1 digit; with 10.10 the format changed and two digits were also supported; on iOS, the minor version number always takes up two digits } @@ -1158,6 +1166,7 @@ function toption.ParseMacVersionMin(out minstr, emptystr: string; const compvarn temp:='0'+temp; compvarvalue:=compvarvalue+temp; { optional patch level } + patch:=0; if i<=length(value) then begin if value[i]<>'.' then @@ -1188,19 +1197,23 @@ function toption.ParseMacVersionMin(out minstr, emptystr: string; const compvarn { must be the end } if i<=length(value) then exit(false); + val(temp,patch,err); + if err<>0 then + exit(false); end else if not ios and not osx_minor_two_digits then begin compvarvalue:=compvarvalue+'0'; - minstr:=minstr+'.0' + versionstr:=versionstr+'.0' end else begin compvarvalue:=compvarvalue+'00'; { command line versions still only use one 0 though } - minstr:=minstr+'.0' + versionstr:=versionstr+'.0' end; + minversion.init(versionstr,major,minor,patch); set_system_compvar(compvarname,compvarvalue); MacVersionSet:=true; result:=true; @@ -1306,7 +1319,7 @@ begin begin {$ifdef llvm} { We only support libunwind as part of libsystem, which happened in Mac OS X 10.6 } - if CompareVersionStrings(MacOSXVersionMin,'10.6')<=0 then + if MacOSXVersionMin.relationto(10,6,0)<0 then Message1(option_invalid_macosx_deployment_target,envstr); {$endif} exit; @@ -1325,36 +1338,36 @@ begin case target_info.system of system_powerpc_darwin: begin - set_system_compvar('MAC_OS_X_VERSION_MIN_REQUIRED','1030'); - MacOSXVersionMin:='10.3.0'; + if not ParseMacVersionMin(MacOSXVersionMin,iPhoneOSVersionMin,'MAC_OS_X_VERSION_MIN_REQUIRED','10.3.0',false) then + internalerror(2022090910); end; system_powerpc64_darwin: begin - set_system_compvar('MAC_OS_X_VERSION_MIN_REQUIRED','1040'); - MacOSXVersionMin:='10.4.0'; + if not ParseMacVersionMin(MacOSXVersionMin,iPhoneOSVersionMin,'MAC_OS_X_VERSION_MIN_REQUIRED','10.4.0',false) then + internalerror(2022090911); end; system_i386_darwin, system_x86_64_darwin: begin - set_system_compvar('MAC_OS_X_VERSION_MIN_REQUIRED','1080'); - MacOSXVersionMin:='10.8.0'; + if not ParseMacVersionMin(MacOSXVersionMin,iPhoneOSVersionMin,'MAC_OS_X_VERSION_MIN_REQUIRED','10.8.0',false) then + internalerror(2022090912); end; system_arm_ios, system_i386_iphonesim: begin - set_system_compvar('IPHONE_OS_VERSION_MIN_REQUIRED','90000'); - iPhoneOSVersionMin:='9.0.0'; + if not ParseMacVersionMin(iPhoneOSVersionMin,MacOSXVersionMin,'IPHONE_OS_VERSION_MIN_REQUIRED','9.0.0',false) then + internalerror(2022090913); end; system_aarch64_ios, system_x86_64_iphonesim: begin - set_system_compvar('IPHONE_OS_VERSION_MIN_REQUIRED','90000'); - iPhoneOSVersionMin:='9.0.0'; + if not ParseMacVersionMin(iPhoneOSVersionMin,MacOSXVersionMin,'IPHONE_OS_VERSION_MIN_REQUIRED','9.0.0',false) then + internalerror(2022090914); end; system_aarch64_darwin: begin - set_system_compvar('MAC_OS_X_VERSION_MIN_REQUIRED','110000'); - MacOSXVersionMin:='11.0.0'; + if not ParseMacVersionMin(MacOSXVersionMin,iPhoneOSVersionMin,'MAC_OS_X_VERSION_MIN_REQUIRED','11.00.0',false) then + internalerror(2022090915); end else internalerror(2012031001); diff --git a/compiler/systems/t_darwin.pas b/compiler/systems/t_darwin.pas index 112e1d5d37..2e003bdf05 100644 --- a/compiler/systems/t_darwin.pas +++ b/compiler/systems/t_darwin.pas @@ -173,14 +173,14 @@ implementation system_x86_64_darwin: begin { 10.8 and later: no crt1.* } - if CompareVersionStrings(MacOSXVersionMin,'10.8')>=0 then + if MacOSXVersionMin.relationto(10,8,0)>=0 then exit(''); { x86: crt1.10.6.o -> crt1.10.5.o -> crt1.o } { others: crt1.10.5 -> crt1.o } if (target_info.system in [system_i386_darwin,system_x86_64_darwin]) and - (CompareVersionStrings(MacOSXVersionMin,'10.6')>=0) then + (MacOSXVersionMin.relationto(10,6,0)>=0) then exit('crt1.10.6.o'); - if CompareVersionStrings(MacOSXVersionMin,'10.5')>=0 then + if MacOSXVersionMin.relationto(10,5,0)>=0 then exit('crt1.10.5.o'); end; system_arm_ios: @@ -190,9 +190,9 @@ implementation iOS 3.1 - 5.x: crt1.3.1.o pre-iOS 3.1: crt1.o } - if (CompareVersionStrings(iPhoneOSVersionMin,'6.0')>=0) then + if iPhoneOSVersionMin.relationto(6,0,0)>=0 then exit(''); - if (CompareVersionStrings(iPhoneOSVersionMin,'3.1')>=0) then + if iPhoneOSVersionMin.relationto(3,1,0)>=0 then exit('crt1.3.1.o'); end; system_i386_iphonesim, @@ -202,7 +202,7 @@ implementation What those recent versions could be, is anyone's guess. It still seems to work with 8.1 and no longer with 8.3, so use 8.1 as a cut-off point } - if (CompareVersionStrings(iPhoneOSVersionMin,'8.1')>0) then + if iPhoneOSVersionMin.relationto(8,1,0)>0 then exit(''); end; system_aarch64_ios, @@ -220,7 +220,7 @@ implementation result:='gcrt1.o'; { 10.8 and later: tell the linker to use 'start' instead of "_main" as entry point } - if CompareVersionStrings(MacOSXVersionMin,'10.8')>=0 then + if MacOSXVersionMin.relationto(10,8,0)>=0 then Info.ExeCmd[1]:=Info.ExeCmd[1]+' -no_new_main'; end; end @@ -236,7 +236,7 @@ implementation begin { < 10.6: bundle1.o >= 10.6: nothing } - if CompareVersionStrings(MacOSXVersionMin,'10.6')>=0 then + if MacOSXVersionMin.relationto(10,6,0)>=0 then exit(''); end; system_arm_ios, @@ -244,14 +244,14 @@ implementation begin { iOS: < 3.1: bundle1.o >= 3.1: nothing } - if (CompareVersionStrings(iPhoneOSVersionMin,'3.1')>=0) then + if iPhoneOSVersionMin.relationto(3,1,0)>=0 then exit(''); end; system_i386_iphonesim, system_x86_64_iphonesim: begin { see rule for crt1.o } - if (CompareVersionStrings(iPhoneOSVersionMin,'8.1')>0) then + if iPhoneOSVersionMin.relationto(8,1,0)>0 then exit(''); end; system_aarch64_darwin: @@ -273,9 +273,9 @@ implementation = 10.5: dylib1.10.5.o < 10.5: dylib1.o } - if CompareVersionStrings(MacOSXVersionMin,'10.6')>=0 then + if MacOSXVersionMin.relationto(10,6,0)>=0 then exit(''); - if CompareVersionStrings(MacOSXVersionMin,'10.5')>=0 then + if MacOSXVersionMin.relationto(10,5,0)>=0 then exit('dylib1.10.5.o'); end; system_arm_ios, @@ -283,14 +283,14 @@ implementation begin { iOS: < 3.1: dylib1.o >= 3.1: nothing } - if (CompareVersionStrings(iPhoneOSVersionMin,'3.1')>=0) then + if iPhoneOSVersionMin.relationto(3,1,0)>=0 then exit(''); end; system_i386_iphonesim, system_x86_64_iphonesim: begin { see rule for crt1.o } - if (CompareVersionStrings(iPhoneOSVersionMin,'8.1')>0) then + if iPhoneOSVersionMin.relationto(8,1,0)>0 then exit(''); end; system_aarch64_darwin: @@ -348,20 +348,20 @@ implementation function tlinkerdarwin.GetLinkVersion: TCmdStr; begin - if MacOSXVersionMin<>'' then + if MacOSXVersionMin.isvalid then begin - result:='-macosx_version_min '+MacOSXVersionMin; + result:='-macosx_version_min '+MacOSXVersionMin.str; end - else if iPhoneOSVersionMin<>'' then + else if iPhoneOSVersionMin.isvalid then begin if target_info.system in [system_i386_iphonesim,system_x86_64_iphonesim] then - result:='-ios_simulator_version_min '+iPhoneOSVersionMin + result:='-ios_simulator_version_min '+iPhoneOSVersionMin.str else - result:='-iphoneos_version_min '+iPhoneOSVersionMin; + result:='-iphoneos_version_min '+iPhoneOSVersionMin.str; end else begin - result:=''; + internalerror(2022090920) end; end; diff --git a/compiler/triplet.pas b/compiler/triplet.pas index 99d064ce4f..e910bf35fc 100644 --- a/compiler/triplet.pas +++ b/compiler/triplet.pas @@ -45,9 +45,9 @@ uses begin result:=result+'-apple'; if target_info.system in systems_macosx then - result:=result+'-macosx'+MacOSXVersionMin + result:=result+'-macosx'+MacOSXVersionMin.str else - result:=result+'-ios'+iPhoneOSVersionMin; + result:=result+'-ios'+iPhoneOSVersionMin.str; end else if target_info.system in (systems_linux+systems_android) then result:=result+'-unknown-linux'