Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
4dffc851
Unverified
Commit
4dffc851
authored
Oct 13, 2020
by
Jenn Magder
Committed by
GitHub
Oct 13, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Detect ARM macOS arch with sysctl hw.optional.arm64 (#67970)
parent
0343555a
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
287 additions
and
53 deletions
+287
-53
application_package.dart
packages/flutter_tools/lib/src/application_package.dart
+1
-1
os.dart
packages/flutter_tools/lib/src/base/os.dart
+58
-12
build_info.dart
packages/flutter_tools/lib/src/build_info.dart
+4
-0
os_test.dart
packages/flutter_tools/test/general.shard/base/os_test.dart
+220
-40
context.dart
packages/flutter_tools/test/src/context.dart
+4
-0
No files found.
packages/flutter_tools/lib/src/application_package.dart
View file @
4dffc851
...
...
@@ -328,7 +328,7 @@ abstract class IOSApp extends ApplicationPackage {
}
static
Future
<
IOSApp
>
fromIosProject
(
IosProject
project
,
BuildInfo
buildInfo
)
{
if
(
getCurrentHostPlatform
()
!=
HostPlatform
.
darwin_x64
)
{
if
(
!
globals
.
platform
.
isMacOS
)
{
return
null
;
}
if
(!
project
.
exists
)
{
...
...
packages/flutter_tools/lib/src/base/os.dart
View file @
4dffc851
...
...
@@ -7,6 +7,7 @@ import 'package:file/file.dart';
import
'package:meta/meta.dart'
;
import
'package:process/process.dart'
;
import
'../build_info.dart'
;
import
'../globals.dart'
as
globals
;
import
'common.dart'
;
import
'file_system.dart'
;
...
...
@@ -29,6 +30,13 @@ abstract class OperatingSystemUtils {
platform:
platform
,
processManager:
processManager
,
);
}
else
if
(
platform
.
isMacOS
)
{
return
_MacOSUtils
(
fileSystem:
fileSystem
,
logger:
logger
,
platform:
platform
,
processManager:
processManager
,
);
}
else
{
return
_PosixUtils
(
fileSystem:
fileSystem
,
...
...
@@ -112,6 +120,8 @@ abstract class OperatingSystemUtils {
return
osNames
.
containsKey
(
osName
)
?
osNames
[
osName
]
:
osName
;
}
HostPlatform
get
hostPlatform
;
List
<
File
>
_which
(
String
execName
,
{
bool
all
=
false
});
/// Returns the separator between items in the PATH environment variable.
...
...
@@ -246,30 +256,63 @@ class _PosixUtils extends OperatingSystemUtils {
return
_fileSystem
.
file
(
path
);
}
@override
String
get
pathVarSeparator
=>
':'
;
@override
HostPlatform
hostPlatform
=
HostPlatform
.
linux_x64
;
}
class
_MacOSUtils
extends
_PosixUtils
{
_MacOSUtils
({
@required
FileSystem
fileSystem
,
@required
Logger
logger
,
@required
Platform
platform
,
@required
ProcessManager
processManager
,
})
:
super
(
fileSystem:
fileSystem
,
logger:
logger
,
platform:
platform
,
processManager:
processManager
,
);
String
_name
;
@override
String
get
name
{
if
(
_name
==
null
)
{
if
(
_platform
.
isMacOS
)
{
final
List
<
RunResult
>
results
=
<
RunResult
>[
_processUtils
.
runSync
(<
String
>[
'sw_vers'
,
'-productName'
]),
_processUtils
.
runSync
(<
String
>[
'sw_vers'
,
'-productVersion'
]),
_processUtils
.
runSync
(<
String
>[
'sw_vers'
,
'-buildVersion'
]),
_processUtils
.
runSync
(<
String
>[
'uname'
,
'-m'
]),
];
if
(
results
.
every
((
RunResult
result
)
=>
result
.
exitCode
==
0
))
{
_name
=
'
${results[0].stdout.trim()}
${results[1].stdout
.trim()}
${results[2].stdout.trim()}
${results[3].stdout.trim()}
'
;
}
final
List
<
RunResult
>
results
=
<
RunResult
>[
_processUtils
.
runSync
(<
String
>[
'sw_vers'
,
'-productName'
]),
_processUtils
.
runSync
(<
String
>[
'sw_vers'
,
'-productVersion'
]),
_processUtils
.
runSync
(<
String
>[
'sw_vers'
,
'-buildVersion'
]),
];
if
(
results
.
every
((
RunResult
result
)
=>
result
.
exitCode
==
0
))
{
_name
=
'
${results[0].stdout.trim()}
${results[1].stdout.trim()}
${results[2].stdout.trim()}
${getNameForHostPlatform(hostPlatform)}
'
;
}
_name
??=
super
.
name
;
}
return
_name
;
}
HostPlatform
_hostPlatform
;
// On ARM returns arm64, even when this process is running in Rosetta.
@override
String
get
pathVarSeparator
=>
':'
;
HostPlatform
get
hostPlatform
{
if
(
_hostPlatform
==
null
)
{
final
RunResult
arm64Check
=
_processUtils
.
runSync
(<
String
>[
'sysctl'
,
'hw.optional.arm64'
]);
// hw.optional.arm64 is unavailable on < macOS 11 and exits with 1, assume x86 on failure.
// On arm64 stdout is "sysctl hw.optional.arm64: 1"
if
(
arm64Check
.
exitCode
==
0
&&
arm64Check
.
stdout
.
trim
().
endsWith
(
'1'
))
{
_hostPlatform
=
HostPlatform
.
darwin_arm
;
}
else
{
_hostPlatform
=
HostPlatform
.
darwin_x64
;
}
}
return
_hostPlatform
;
}
}
class
_WindowsUtils
extends
OperatingSystemUtils
{
...
...
@@ -285,6 +328,9 @@ class _WindowsUtils extends OperatingSystemUtils {
processManager:
processManager
,
);
@override
HostPlatform
hostPlatform
=
HostPlatform
.
windows_x64
;
@override
void
makeExecutable
(
File
file
)
{}
...
...
packages/flutter_tools/lib/src/build_info.dart
View file @
4dffc851
...
...
@@ -398,6 +398,7 @@ bool isEmulatorBuildMode(BuildMode mode) {
enum
HostPlatform
{
darwin_x64
,
darwin_arm
,
linux_x64
,
windows_x64
,
}
...
...
@@ -406,6 +407,8 @@ String getNameForHostPlatform(HostPlatform platform) {
switch
(
platform
)
{
case
HostPlatform
.
darwin_x64
:
return
'darwin-x64'
;
case
HostPlatform
.
darwin_arm
:
return
'darwin-arm'
;
case
HostPlatform
.
linux_x64
:
return
'linux-x64'
;
case
HostPlatform
.
windows_x64
:
...
...
@@ -418,6 +421,7 @@ String getNameForHostPlatform(HostPlatform platform) {
enum
TargetPlatform
{
android
,
ios
,
// darwin_arm64 not yet supported, macOS desktop targets run in Rosetta as x86.
darwin_x64
,
linux_x64
,
windows_x64
,
...
...
packages/flutter_tools/test/general.shard/base/os_test.dart
View file @
4dffc851
...
...
@@ -6,10 +6,10 @@ import 'package:file/file.dart';
import
'package:file/memory.dart'
;
import
'package:flutter_tools/src/base/common.dart'
;
import
'package:flutter_tools/src/base/file_system.dart'
;
import
'package:flutter_tools/src/base/io.dart'
;
import
'package:flutter_tools/src/base/logger.dart'
;
import
'package:flutter_tools/src/base/os.dart'
;
import
'package:flutter_tools/src/base/platform.dart'
;
import
'package:flutter_tools/src/build_info.dart'
;
import
'package:mockito/mockito.dart'
;
import
'package:process/process.dart'
;
...
...
@@ -22,9 +22,11 @@ const String kPath2 = '/another/bin/$kExecutable';
void
main
(
)
{
MockProcessManager
mockProcessManager
;
FakeProcessManager
fakeProcessManager
;
setUp
(()
{
mockProcessManager
=
MockProcessManager
();
fakeProcessManager
=
FakeProcessManager
.
list
(<
FakeCommand
>[]);
});
OperatingSystemUtils
createOSUtils
(
Platform
platform
)
{
...
...
@@ -32,28 +34,50 @@ void main() {
fileSystem:
MemoryFileSystem
.
test
(),
logger:
BufferLogger
.
test
(),
platform:
platform
,
processManager:
mock
ProcessManager
,
processManager:
fake
ProcessManager
,
);
}
group
(
'which on POSIX'
,
()
{
testWithoutContext
(
'returns null when executable does not exist'
,
()
async
{
when
(
mockProcessManager
.
runSync
(<
String
>[
'which'
,
kExecutable
]))
.
thenReturn
(
ProcessResult
(
0
,
1
,
null
,
null
));
fakeProcessManager
.
addCommand
(
const
FakeCommand
(
command:
<
String
>[
'which'
,
kExecutable
,
],
exitCode:
1
,
),
);
final
OperatingSystemUtils
utils
=
createOSUtils
(
FakePlatform
(
operatingSystem:
'linux'
));
expect
(
utils
.
which
(
kExecutable
),
isNull
);
});
testWithoutContext
(
'returns exactly one result'
,
()
async
{
when
(
mockProcessManager
.
runSync
(<
String
>[
'which'
,
'foo'
]))
.
thenReturn
(
ProcessResult
(
0
,
0
,
kPath1
,
null
));
fakeProcessManager
.
addCommand
(
const
FakeCommand
(
command:
<
String
>[
'which'
,
'foo'
,
],
stdout:
kPath1
,
),
);
final
OperatingSystemUtils
utils
=
createOSUtils
(
FakePlatform
(
operatingSystem:
'linux'
));
expect
(
utils
.
which
(
kExecutable
).
path
,
kPath1
);
});
testWithoutContext
(
'returns all results for whichAll'
,
()
async
{
when
(
mockProcessManager
.
runSync
(<
String
>[
'which'
,
'-a'
,
kExecutable
]))
.
thenReturn
(
ProcessResult
(
0
,
0
,
'
$kPath1
\n
$kPath2
'
,
null
));
fakeProcessManager
.
addCommand
(
const
FakeCommand
(
command:
<
String
>[
'which'
,
'-a'
,
kExecutable
,
],
stdout:
'
$kPath1
\n
$kPath2
'
,
),
);
final
OperatingSystemUtils
utils
=
createOSUtils
(
FakePlatform
(
operatingSystem:
'linux'
));
final
List
<
File
>
result
=
utils
.
whichAll
(
kExecutable
);
expect
(
result
,
hasLength
(
2
));
...
...
@@ -66,27 +90,55 @@ void main() {
testWithoutContext
(
'throws tool exit if where throws an argument error'
,
()
async
{
when
(
mockProcessManager
.
runSync
(<
String
>[
'where'
,
kExecutable
]))
.
thenThrow
(
ArgumentError
(
'Cannot find executable for where'
));
final
OperatingSystemUtils
utils
=
createOSUtils
(
FakePlatform
(
operatingSystem:
'windows'
));
final
OperatingSystemUtils
utils
=
OperatingSystemUtils
(
fileSystem:
MemoryFileSystem
.
test
(),
logger:
BufferLogger
.
test
(),
platform:
FakePlatform
(
operatingSystem:
'windows'
),
processManager:
mockProcessManager
,
);
expect
(()
=>
utils
.
which
(
kExecutable
),
throwsA
(
isA
<
ToolExit
>()));
});
testWithoutContext
(
'returns null when executable does not exist'
,
()
async
{
when
(
mockProcessManager
.
runSync
(<
String
>[
'where'
,
kExecutable
]))
.
thenReturn
(
ProcessResult
(
0
,
1
,
null
,
null
));
fakeProcessManager
.
addCommand
(
const
FakeCommand
(
command:
<
String
>[
'where'
,
kExecutable
,
],
exitCode:
1
,
),
);
final
OperatingSystemUtils
utils
=
createOSUtils
(
FakePlatform
(
operatingSystem:
'windows'
));
expect
(
utils
.
which
(
kExecutable
),
isNull
);
});
testWithoutContext
(
'returns exactly one result'
,
()
async
{
when
(
mockProcessManager
.
runSync
(<
String
>[
'where'
,
'foo'
]))
.
thenReturn
(
ProcessResult
(
0
,
0
,
'
$kPath1
\n
$kPath2
'
,
null
));
fakeProcessManager
.
addCommand
(
const
FakeCommand
(
command:
<
String
>[
'where'
,
'foo'
,
],
stdout:
'
$kPath1
\n
$kPath2
'
,
),
);
final
OperatingSystemUtils
utils
=
createOSUtils
(
FakePlatform
(
operatingSystem:
'windows'
));
expect
(
utils
.
which
(
kExecutable
).
path
,
kPath1
);
});
testWithoutContext
(
'returns all results for whichAll'
,
()
async
{
when
(
mockProcessManager
.
runSync
(<
String
>[
'where'
,
kExecutable
]))
.
thenReturn
(
ProcessResult
(
0
,
0
,
'
$kPath1
\n
$kPath2
'
,
null
));
fakeProcessManager
.
addCommand
(
const
FakeCommand
(
command:
<
String
>[
'where'
,
kExecutable
,
],
stdout:
'
$kPath1
\n
$kPath2
'
,
),
);
final
OperatingSystemUtils
utils
=
createOSUtils
(
FakePlatform
(
operatingSystem:
'windows'
));
final
List
<
File
>
result
=
utils
.
whichAll
(
kExecutable
);
expect
(
result
,
hasLength
(
2
));
...
...
@@ -95,34 +147,162 @@ void main() {
});
});
testWithoutContext
(
'macos name'
,
()
async
{
when
(
mockProcessManager
.
runSync
(
<
String
>[
'sw_vers'
,
'-productName'
],
)).
thenReturn
(
ProcessResult
(
0
,
0
,
'product'
,
''
));
when
(
mockProcessManager
.
runSync
(
<
String
>[
'sw_vers'
,
'-productVersion'
],
)).
thenReturn
(
ProcessResult
(
0
,
0
,
'version'
,
''
));
when
(
mockProcessManager
.
runSync
(
<
String
>[
'sw_vers'
,
'-buildVersion'
],
)).
thenReturn
(
ProcessResult
(
0
,
0
,
'build'
,
''
));
when
(
mockProcessManager
.
runSync
(
<
String
>[
'uname'
,
'-m'
],
)).
thenReturn
(
ProcessResult
(
0
,
0
,
'arch'
,
''
));
final
MockFileSystem
fileSystem
=
MockFileSystem
();
final
OperatingSystemUtils
utils
=
OperatingSystemUtils
(
fileSystem:
fileSystem
,
logger:
BufferLogger
.
test
(),
platform:
FakePlatform
(
operatingSystem:
'macos'
),
processManager:
mockProcessManager
,
);
expect
(
utils
.
name
,
'product version build arch'
);
group
(
'host platform'
,
()
{
testWithoutContext
(
'unknown defaults to Linux'
,
()
async
{
final
OperatingSystemUtils
utils
=
createOSUtils
(
FakePlatform
(
operatingSystem:
'fuchsia'
));
expect
(
utils
.
hostPlatform
,
HostPlatform
.
linux_x64
);
});
testWithoutContext
(
'Windows'
,
()
async
{
final
OperatingSystemUtils
utils
=
createOSUtils
(
FakePlatform
(
operatingSystem:
'windows'
));
expect
(
utils
.
hostPlatform
,
HostPlatform
.
windows_x64
);
});
testWithoutContext
(
'Linux'
,
()
async
{
final
OperatingSystemUtils
utils
=
createOSUtils
(
FakePlatform
(
operatingSystem:
'linux'
));
expect
(
utils
.
hostPlatform
,
HostPlatform
.
linux_x64
);
});
testWithoutContext
(
'macOS ARM'
,
()
async
{
fakeProcessManager
.
addCommand
(
const
FakeCommand
(
command:
<
String
>[
'sysctl'
,
'hw.optional.arm64'
,
],
stdout:
'hw.optional.arm64: 1'
,
),
);
final
OperatingSystemUtils
utils
=
createOSUtils
(
FakePlatform
(
operatingSystem:
'macos'
));
expect
(
utils
.
hostPlatform
,
HostPlatform
.
darwin_arm
);
});
testWithoutContext
(
'macOS 11 x86'
,
()
async
{
fakeProcessManager
.
addCommand
(
const
FakeCommand
(
command:
<
String
>[
'sysctl'
,
'hw.optional.arm64'
,
],
stdout:
'hw.optional.arm64: 0'
,
),
);
final
OperatingSystemUtils
utils
=
createOSUtils
(
FakePlatform
(
operatingSystem:
'macos'
));
expect
(
utils
.
hostPlatform
,
HostPlatform
.
darwin_x64
);
});
testWithoutContext
(
'macOS 10 x86'
,
()
async
{
fakeProcessManager
.
addCommand
(
const
FakeCommand
(
command:
<
String
>[
'sysctl'
,
'hw.optional.arm64'
,
],
exitCode:
1
,
),
);
final
OperatingSystemUtils
utils
=
createOSUtils
(
FakePlatform
(
operatingSystem:
'macos'
));
expect
(
utils
.
hostPlatform
,
HostPlatform
.
darwin_x64
);
});
testWithoutContext
(
'macOS ARM name'
,
()
async
{
fakeProcessManager
.
addCommands
(<
FakeCommand
>[
const
FakeCommand
(
command:
<
String
>[
'sw_vers'
,
'-productName'
,
],
stdout:
'product'
,
),
const
FakeCommand
(
command:
<
String
>[
'sw_vers'
,
'-productVersion'
,
],
stdout:
'version'
,
),
const
FakeCommand
(
command:
<
String
>[
'sw_vers'
,
'-buildVersion'
,
],
stdout:
'build'
,
),
const
FakeCommand
(
command:
<
String
>[
'sysctl'
,
'hw.optional.arm64'
,
],
stdout:
'hw.optional.arm64: 1'
,
),
]);
final
OperatingSystemUtils
utils
=
createOSUtils
(
FakePlatform
(
operatingSystem:
'macos'
));
expect
(
utils
.
name
,
'product version build darwin-arm'
);
});
testWithoutContext
(
'macOS x86 name'
,
()
async
{
fakeProcessManager
.
addCommands
(<
FakeCommand
>[
const
FakeCommand
(
command:
<
String
>[
'sw_vers'
,
'-productName'
,
],
stdout:
'product'
,
),
const
FakeCommand
(
command:
<
String
>[
'sw_vers'
,
'-productVersion'
,
],
stdout:
'version'
,
),
const
FakeCommand
(
command:
<
String
>[
'sw_vers'
,
'-buildVersion'
,
],
stdout:
'build'
,
),
const
FakeCommand
(
command:
<
String
>[
'sysctl'
,
'hw.optional.arm64'
,
],
exitCode:
1
,
),
]);
final
OperatingSystemUtils
utils
=
createOSUtils
(
FakePlatform
(
operatingSystem:
'macos'
));
expect
(
utils
.
name
,
'product version build darwin-x64'
);
});
});
testWithoutContext
(
'If unzip fails, include stderr in exception text'
,
()
{
const
String
exceptionMessage
=
'Something really bad happened.'
;
when
(
mockProcessManager
.
runSync
(
<
String
>[
'unzip'
,
'-o'
,
'-q'
,
null
,
'-d'
,
null
],
)).
thenReturn
(
ProcessResult
(
0
,
1
,
''
,
exceptionMessage
));
fakeProcessManager
.
addCommand
(
const
FakeCommand
(
command:
<
String
>[
'unzip'
,
'-o'
,
'-q'
,
null
,
'-d'
,
null
,
],
exitCode:
1
,
stderr:
exceptionMessage
),
);
final
MockFileSystem
fileSystem
=
MockFileSystem
();
final
MockFile
mockFile
=
MockFile
();
final
MockDirectory
mockDirectory
=
MockDirectory
();
...
...
@@ -134,7 +314,7 @@ void main() {
fileSystem:
fileSystem
,
logger:
BufferLogger
.
test
(),
platform:
FakePlatform
(
operatingSystem:
'linux'
),
processManager:
mock
ProcessManager
,
processManager:
fake
ProcessManager
,
);
expect
(
...
...
packages/flutter_tools/test/src/context.dart
View file @
4dffc851
...
...
@@ -17,6 +17,7 @@ import 'package:flutter_tools/src/base/signals.dart';
import
'package:flutter_tools/src/base/template.dart'
;
import
'package:flutter_tools/src/base/terminal.dart'
;
import
'package:flutter_tools/src/base/time.dart'
;
import
'package:flutter_tools/src/build_info.dart'
;
import
'package:flutter_tools/src/isolated/mustache_template.dart'
;
import
'package:flutter_tools/src/cache.dart'
;
import
'package:flutter_tools/src/context_runner.dart'
;
...
...
@@ -294,6 +295,9 @@ class FakeOperatingSystemUtils implements OperatingSystemUtils {
@override
ProcessResult
makeExecutable
(
File
file
)
=>
null
;
@override
HostPlatform
hostPlatform
=
HostPlatform
.
linux_x64
;
@override
void
chmod
(
FileSystemEntity
entity
,
String
mode
)
{
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment