Darwin version comparisons: factored out into object

Use numeric instead of string comparisons
This commit is contained in:
Jonas Maebe 2022-09-09 15:00:43 +02:00
parent 657b9a6203
commit b26703feaa
6 changed files with 64 additions and 117 deletions

View File

@ -133,7 +133,6 @@ interface
function DePascalQuote(var s: ansistring): Boolean; function DePascalQuote(var s: ansistring): Boolean;
function CompareStr(const S1, S2: string): Integer; function CompareStr(const S1, S2: string): Integer;
function CompareText(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 } { releases the string p and assignes nil to p }
{ if p=nil then freemem isn't called } { if p=nil then freemem isn't called }
@ -1275,72 +1274,6 @@ implementation
end; 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) Ansistring (PChar+Length)
*****************************************************************************} *****************************************************************************}

View File

@ -47,7 +47,7 @@ interface
{$if defined(LLVM) or defined(GENERIC_CPU)} {$if defined(LLVM) or defined(GENERIC_CPU)}
llvminfo, llvminfo,
{$endif LLVM or GENERIC_CPU} {$endif LLVM or GENERIC_CPU}
globtype,version,systems; globtype,version,versioncmp,systems;
const const
delphimodeswitches = delphimodeswitches =
@ -352,8 +352,9 @@ interface
GenerateImportSection, GenerateImportSection,
GenerateImportSectionSetExplicitly, GenerateImportSectionSetExplicitly,
RelocSection : boolean; RelocSection : boolean;
MacOSXVersionMin, MacOSXVersionMin,
iPhoneOSVersionMin: string[15]; iPhoneOSVersionMin: tversion;
RelocSectionSetExplicitly : boolean; RelocSectionSetExplicitly : boolean;
current_tokenpos, { position of the last token } current_tokenpos, { position of the last token }
@ -1706,8 +1707,8 @@ implementation
GenerateImportSection:=false; GenerateImportSection:=false;
RelocSection:=false; RelocSection:=false;
RelocSectionSetExplicitly:=false; RelocSectionSetExplicitly:=false;
MacOSXVersionMin:=''; MacOSXVersionMin.invalidate;
iPhoneOSVersionMin:=''; iPhoneOSVersionMin.invalidate;
{ memory sizes, will be overridden by parameter or default for target { memory sizes, will be overridden by parameter or default for target
in options or init_parser } in options or init_parser }
stacksize:=0; stacksize:=0;

View File

@ -49,7 +49,7 @@ interface
implementation implementation
uses uses
verbose,cutils,globals,fmodule,systems,finput, verbose,cutils,globals,fmodule,systems,finput,versioncmp,
aasmtai,cpubase,llvmbase,aasmllvm, aasmtai,cpubase,llvmbase,aasmllvm,
aasmcnst,nllvmtcon, aasmcnst,nllvmtcon,
symbase,symtable,defutil, symbase,symtable,defutil,
@ -295,7 +295,7 @@ implementation
begin begin
{ Objective-C ABI version } { Objective-C ABI version }
if not(target_info.system in [system_powerpc_darwin,system_powerpc64_darwin,system_i386_darwin,system_x86_64_darwin]) or 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 objcabiversion:=2
else else
objcabiversion:=1; objcabiversion:=1;

View File

@ -26,7 +26,7 @@ unit options;
interface interface
uses uses
cfileutl,cclasses, cfileutl,cclasses,versioncmp,
globtype,globals,verbose,systems,cpuinfo,comprsrc; globtype,globals,verbose,systems,cpuinfo,comprsrc;
Type Type
@ -80,7 +80,7 @@ Type
MacVersionSet: boolean; MacVersionSet: boolean;
IdfVersionSet: boolean; IdfVersionSet: boolean;
processorstr: TCmdStr; 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; procedure MaybeSetDefaultMacVersionMacro;
{$ifdef XTENSA} {$ifdef XTENSA}
function ParseVersionStr(out ver: longint; const compvarname, value: string): boolean; function ParseVersionStr(out ver: longint; const compvarname, value: string): boolean;
@ -1095,7 +1095,7 @@ begin
end; 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; function subval(start,maxlen: longint; out stop: longint): string;
var var
@ -1116,12 +1116,14 @@ function toption.ParseMacVersionMin(out minstr, emptystr: string; const compvarn
var var
temp, temp,
compvarvalue: string[15]; compvarvalue,
i: longint; versionstr: string[15];
major, minor, patch: cardinal;
i, err: longint;
osx_minor_two_digits: boolean; osx_minor_two_digits: boolean;
begin begin
minstr:=value; invalidateversion.invalidate;
emptystr:=''; versionstr:=value;
MacVersionSet:=false; MacVersionSet:=false;
{ check whether the value is a valid version number } { check whether the value is a valid version number }
if value='' then if value='' then
@ -1138,10 +1140,16 @@ function toption.ParseMacVersionMin(out minstr, emptystr: string; const compvarn
if (i>=length(value)) or if (i>=length(value)) or
(value[i]<>'.') then (value[i]<>'.') then
exit(false); exit(false);
val(compvarvalue,major,err);
if err<>0 then
exit(false);
{ minor version number } { minor version number }
temp:=subval(i+1,2,i); temp:=subval(i+1,2,i);
if temp='' then if temp='' then
exit(false); 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; { 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, with 10.10 the format changed and two digits were also supported; on iOS,
the minor version number always takes up two digits } 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; temp:='0'+temp;
compvarvalue:=compvarvalue+temp; compvarvalue:=compvarvalue+temp;
{ optional patch level } { optional patch level }
patch:=0;
if i<=length(value) then if i<=length(value) then
begin begin
if value[i]<>'.' then if value[i]<>'.' then
@ -1188,19 +1197,23 @@ function toption.ParseMacVersionMin(out minstr, emptystr: string; const compvarn
{ must be the end } { must be the end }
if i<=length(value) then if i<=length(value) then
exit(false); exit(false);
val(temp,patch,err);
if err<>0 then
exit(false);
end end
else if not ios and else if not ios and
not osx_minor_two_digits then not osx_minor_two_digits then
begin begin
compvarvalue:=compvarvalue+'0'; compvarvalue:=compvarvalue+'0';
minstr:=minstr+'.0' versionstr:=versionstr+'.0'
end end
else else
begin begin
compvarvalue:=compvarvalue+'00'; compvarvalue:=compvarvalue+'00';
{ command line versions still only use one 0 though } { command line versions still only use one 0 though }
minstr:=minstr+'.0' versionstr:=versionstr+'.0'
end; end;
minversion.init(versionstr,major,minor,patch);
set_system_compvar(compvarname,compvarvalue); set_system_compvar(compvarname,compvarvalue);
MacVersionSet:=true; MacVersionSet:=true;
result:=true; result:=true;
@ -1306,7 +1319,7 @@ begin
begin begin
{$ifdef llvm} {$ifdef llvm}
{ We only support libunwind as part of libsystem, which happened in Mac OS X 10.6 } { 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); Message1(option_invalid_macosx_deployment_target,envstr);
{$endif} {$endif}
exit; exit;
@ -1325,36 +1338,36 @@ begin
case target_info.system of case target_info.system of
system_powerpc_darwin: system_powerpc_darwin:
begin begin
set_system_compvar('MAC_OS_X_VERSION_MIN_REQUIRED','1030'); if not ParseMacVersionMin(MacOSXVersionMin,iPhoneOSVersionMin,'MAC_OS_X_VERSION_MIN_REQUIRED','10.3.0',false) then
MacOSXVersionMin:='10.3.0'; internalerror(2022090910);
end; end;
system_powerpc64_darwin: system_powerpc64_darwin:
begin begin
set_system_compvar('MAC_OS_X_VERSION_MIN_REQUIRED','1040'); if not ParseMacVersionMin(MacOSXVersionMin,iPhoneOSVersionMin,'MAC_OS_X_VERSION_MIN_REQUIRED','10.4.0',false) then
MacOSXVersionMin:='10.4.0'; internalerror(2022090911);
end; end;
system_i386_darwin, system_i386_darwin,
system_x86_64_darwin: system_x86_64_darwin:
begin begin
set_system_compvar('MAC_OS_X_VERSION_MIN_REQUIRED','1080'); if not ParseMacVersionMin(MacOSXVersionMin,iPhoneOSVersionMin,'MAC_OS_X_VERSION_MIN_REQUIRED','10.8.0',false) then
MacOSXVersionMin:='10.8.0'; internalerror(2022090912);
end; end;
system_arm_ios, system_arm_ios,
system_i386_iphonesim: system_i386_iphonesim:
begin begin
set_system_compvar('IPHONE_OS_VERSION_MIN_REQUIRED','90000'); if not ParseMacVersionMin(iPhoneOSVersionMin,MacOSXVersionMin,'IPHONE_OS_VERSION_MIN_REQUIRED','9.0.0',false) then
iPhoneOSVersionMin:='9.0.0'; internalerror(2022090913);
end; end;
system_aarch64_ios, system_aarch64_ios,
system_x86_64_iphonesim: system_x86_64_iphonesim:
begin begin
set_system_compvar('IPHONE_OS_VERSION_MIN_REQUIRED','90000'); if not ParseMacVersionMin(iPhoneOSVersionMin,MacOSXVersionMin,'IPHONE_OS_VERSION_MIN_REQUIRED','9.0.0',false) then
iPhoneOSVersionMin:='9.0.0'; internalerror(2022090914);
end; end;
system_aarch64_darwin: system_aarch64_darwin:
begin begin
set_system_compvar('MAC_OS_X_VERSION_MIN_REQUIRED','110000'); if not ParseMacVersionMin(MacOSXVersionMin,iPhoneOSVersionMin,'MAC_OS_X_VERSION_MIN_REQUIRED','11.00.0',false) then
MacOSXVersionMin:='11.0.0'; internalerror(2022090915);
end end
else else
internalerror(2012031001); internalerror(2012031001);

View File

@ -173,14 +173,14 @@ implementation
system_x86_64_darwin: system_x86_64_darwin:
begin begin
{ 10.8 and later: no crt1.* } { 10.8 and later: no crt1.* }
if CompareVersionStrings(MacOSXVersionMin,'10.8')>=0 then if MacOSXVersionMin.relationto(10,8,0)>=0 then
exit(''); exit('');
{ x86: crt1.10.6.o -> crt1.10.5.o -> crt1.o } { x86: crt1.10.6.o -> crt1.10.5.o -> crt1.o }
{ others: crt1.10.5 -> crt1.o } { others: crt1.10.5 -> crt1.o }
if (target_info.system in [system_i386_darwin,system_x86_64_darwin]) and 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'); 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'); exit('crt1.10.5.o');
end; end;
system_arm_ios: system_arm_ios:
@ -190,9 +190,9 @@ implementation
iOS 3.1 - 5.x: crt1.3.1.o iOS 3.1 - 5.x: crt1.3.1.o
pre-iOS 3.1: crt1.o pre-iOS 3.1: crt1.o
} }
if (CompareVersionStrings(iPhoneOSVersionMin,'6.0')>=0) then if iPhoneOSVersionMin.relationto(6,0,0)>=0 then
exit(''); exit('');
if (CompareVersionStrings(iPhoneOSVersionMin,'3.1')>=0) then if iPhoneOSVersionMin.relationto(3,1,0)>=0 then
exit('crt1.3.1.o'); exit('crt1.3.1.o');
end; end;
system_i386_iphonesim, system_i386_iphonesim,
@ -202,7 +202,7 @@ implementation
What those recent versions could be, is anyone's guess. It 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 still seems to work with 8.1 and no longer with 8.3, so use
8.1 as a cut-off point } 8.1 as a cut-off point }
if (CompareVersionStrings(iPhoneOSVersionMin,'8.1')>0) then if iPhoneOSVersionMin.relationto(8,1,0)>0 then
exit(''); exit('');
end; end;
system_aarch64_ios, system_aarch64_ios,
@ -220,7 +220,7 @@ implementation
result:='gcrt1.o'; result:='gcrt1.o';
{ 10.8 and later: tell the linker to use 'start' instead of "_main" { 10.8 and later: tell the linker to use 'start' instead of "_main"
as entry point } 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'; Info.ExeCmd[1]:=Info.ExeCmd[1]+' -no_new_main';
end; end;
end end
@ -236,7 +236,7 @@ implementation
begin begin
{ < 10.6: bundle1.o { < 10.6: bundle1.o
>= 10.6: nothing } >= 10.6: nothing }
if CompareVersionStrings(MacOSXVersionMin,'10.6')>=0 then if MacOSXVersionMin.relationto(10,6,0)>=0 then
exit(''); exit('');
end; end;
system_arm_ios, system_arm_ios,
@ -244,14 +244,14 @@ implementation
begin begin
{ iOS: < 3.1: bundle1.o { iOS: < 3.1: bundle1.o
>= 3.1: nothing } >= 3.1: nothing }
if (CompareVersionStrings(iPhoneOSVersionMin,'3.1')>=0) then if iPhoneOSVersionMin.relationto(3,1,0)>=0 then
exit(''); exit('');
end; end;
system_i386_iphonesim, system_i386_iphonesim,
system_x86_64_iphonesim: system_x86_64_iphonesim:
begin begin
{ see rule for crt1.o } { see rule for crt1.o }
if (CompareVersionStrings(iPhoneOSVersionMin,'8.1')>0) then if iPhoneOSVersionMin.relationto(8,1,0)>0 then
exit(''); exit('');
end; end;
system_aarch64_darwin: system_aarch64_darwin:
@ -273,9 +273,9 @@ implementation
= 10.5: dylib1.10.5.o = 10.5: dylib1.10.5.o
< 10.5: dylib1.o < 10.5: dylib1.o
} }
if CompareVersionStrings(MacOSXVersionMin,'10.6')>=0 then if MacOSXVersionMin.relationto(10,6,0)>=0 then
exit(''); exit('');
if CompareVersionStrings(MacOSXVersionMin,'10.5')>=0 then if MacOSXVersionMin.relationto(10,5,0)>=0 then
exit('dylib1.10.5.o'); exit('dylib1.10.5.o');
end; end;
system_arm_ios, system_arm_ios,
@ -283,14 +283,14 @@ implementation
begin begin
{ iOS: < 3.1: dylib1.o { iOS: < 3.1: dylib1.o
>= 3.1: nothing } >= 3.1: nothing }
if (CompareVersionStrings(iPhoneOSVersionMin,'3.1')>=0) then if iPhoneOSVersionMin.relationto(3,1,0)>=0 then
exit(''); exit('');
end; end;
system_i386_iphonesim, system_i386_iphonesim,
system_x86_64_iphonesim: system_x86_64_iphonesim:
begin begin
{ see rule for crt1.o } { see rule for crt1.o }
if (CompareVersionStrings(iPhoneOSVersionMin,'8.1')>0) then if iPhoneOSVersionMin.relationto(8,1,0)>0 then
exit(''); exit('');
end; end;
system_aarch64_darwin: system_aarch64_darwin:
@ -348,20 +348,20 @@ implementation
function tlinkerdarwin.GetLinkVersion: TCmdStr; function tlinkerdarwin.GetLinkVersion: TCmdStr;
begin begin
if MacOSXVersionMin<>'' then if MacOSXVersionMin.isvalid then
begin begin
result:='-macosx_version_min '+MacOSXVersionMin; result:='-macosx_version_min '+MacOSXVersionMin.str;
end end
else if iPhoneOSVersionMin<>'' then else if iPhoneOSVersionMin.isvalid then
begin begin
if target_info.system in [system_i386_iphonesim,system_x86_64_iphonesim] then 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 else
result:='-iphoneos_version_min '+iPhoneOSVersionMin; result:='-iphoneos_version_min '+iPhoneOSVersionMin.str;
end end
else else
begin begin
result:=''; internalerror(2022090920)
end; end;
end; end;

View File

@ -45,9 +45,9 @@ uses
begin begin
result:=result+'-apple'; result:=result+'-apple';
if target_info.system in systems_macosx then if target_info.system in systems_macosx then
result:=result+'-macosx'+MacOSXVersionMin result:=result+'-macosx'+MacOSXVersionMin.str
else else
result:=result+'-ios'+iPhoneOSVersionMin; result:=result+'-ios'+iPhoneOSVersionMin.str;
end end
else if target_info.system in (systems_linux+systems_android) then else if target_info.system in (systems_linux+systems_android) then
result:=result+'-unknown-linux' result:=result+'-unknown-linux'