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
723b82e4
Unverified
Commit
723b82e4
authored
Sep 05, 2022
by
Ivan Dlugos
Committed by
GitHub
Sep 05, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Feat: dSYM debug info for iOS & macOS builds (#101586)
parent
96345a4b
Changes
15
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
602 additions
and
82 deletions
+602
-82
build_ios_framework_module_test.dart
dev/devicelab/bin/tasks/build_ios_framework_module_test.dart
+79
-0
module_test_ios.dart
dev/devicelab/bin/tasks/module_test_ios.dart
+10
-0
build.dart
packages/flutter_tools/lib/src/base/build.dart
+57
-14
common.dart
...es/flutter_tools/lib/src/build_system/targets/common.dart
+46
-0
ios.dart
packages/flutter_tools/lib/src/build_system/targets/ios.dart
+57
-15
macos.dart
...ges/flutter_tools/lib/src/build_system/targets/macos.dart
+62
-13
symbolize.dart
packages/flutter_tools/lib/src/commands/symbolize.dart
+24
-3
xcode.dart
packages/flutter_tools/lib/src/macos/xcode.dart
+9
-8
symbolize_test.dart
...er_tools/test/commands.shard/hermetic/symbolize_test.dart
+15
-1
build_test.dart
...ges/flutter_tools/test/general.shard/base/build_test.dart
+60
-4
common_test.dart
.../test/general.shard/build_system/targets/common_test.dart
+30
-2
ios_test.dart
...ols/test/general.shard/build_system/targets/ios_test.dart
+14
-0
macos_test.dart
...s/test/general.shard/build_system/targets/macos_test.dart
+68
-2
ios_content_validation_test.dart
...st/host_cross_arch.shard/ios_content_validation_test.dart
+39
-4
macos_content_validation_test.dart
.../host_cross_arch.shard/macos_content_validation_test.dart
+32
-16
No files found.
dev/devicelab/bin/tasks/build_ios_framework_module_test.dart
View file @
723b82e4
...
@@ -189,6 +189,23 @@ Future<void> _testBuildIosFramework(Directory projectDir, { bool isModule = fals
...
@@ -189,6 +189,23 @@ Future<void> _testBuildIosFramework(Directory projectDir, { bool isModule = fals
'vm_snapshot_data'
,
'vm_snapshot_data'
,
));
));
final
String
appFrameworkDsymPath
=
path
.
join
(
outputPath
,
mode
,
'App.xcframework'
,
'ios-arm64'
,
'dSYMs'
,
'App.framework.dSYM'
);
checkDirectoryExists
(
appFrameworkDsymPath
);
await
_checkDsym
(
path
.
join
(
appFrameworkDsymPath
,
'Contents'
,
'Resources'
,
'DWARF'
,
'App'
,
));
checkFileExists
(
path
.
join
(
checkFileExists
(
path
.
join
(
outputPath
,
outputPath
,
mode
,
mode
,
...
@@ -404,6 +421,25 @@ Future<void> _testBuildIosFramework(Directory projectDir, { bool isModule = fals
...
@@ -404,6 +421,25 @@ Future<void> _testBuildIosFramework(Directory projectDir, { bool isModule = fals
'App'
,
'App'
,
));
));
if
(
mode
!=
'Debug'
)
{
final
String
appFrameworkDsymPath
=
path
.
join
(
cocoapodsOutputPath
,
mode
,
'App.xcframework'
,
'ios-arm64'
,
'dSYMs'
,
'App.framework.dSYM'
);
checkDirectoryExists
(
appFrameworkDsymPath
);
await
_checkDsym
(
path
.
join
(
appFrameworkDsymPath
,
'Contents'
,
'Resources'
,
'DWARF'
,
'App'
,
));
}
if
(
Directory
(
path
.
join
(
if
(
Directory
(
path
.
join
(
cocoapodsOutputPath
,
cocoapodsOutputPath
,
mode
,
mode
,
...
@@ -582,6 +618,23 @@ Future<void> _testBuildMacOSFramework(Directory projectDir) async {
...
@@ -582,6 +618,23 @@ Future<void> _testBuildMacOSFramework(Directory projectDir) async {
'Resources'
,
'Resources'
,
'Info.plist'
,
'Info.plist'
,
));
));
final
String
appFrameworkDsymPath
=
path
.
join
(
outputPath
,
mode
,
'App.xcframework'
,
'macos-arm64_x86_64'
,
'dSYMs'
,
'App.framework.dSYM'
);
checkDirectoryExists
(
appFrameworkDsymPath
);
await
_checkDsym
(
path
.
join
(
appFrameworkDsymPath
,
'Contents'
,
'Resources'
,
'DWARF'
,
'App'
,
));
}
}
section
(
"Check all modes' engine dylib"
);
section
(
"Check all modes' engine dylib"
);
...
@@ -712,6 +765,25 @@ Future<void> _testBuildMacOSFramework(Directory projectDir) async {
...
@@ -712,6 +765,25 @@ Future<void> _testBuildMacOSFramework(Directory projectDir) async {
'App'
,
'App'
,
));
));
if
(
mode
!=
'Debug'
)
{
final
String
appFrameworkDsymPath
=
path
.
join
(
cocoapodsOutputPath
,
mode
,
'App.xcframework'
,
'macos-arm64_x86_64'
,
'dSYMs'
,
'App.framework.dSYM'
);
checkDirectoryExists
(
appFrameworkDsymPath
);
await
_checkDsym
(
path
.
join
(
appFrameworkDsymPath
,
'Contents'
,
'Resources'
,
'DWARF'
,
'App'
,
));
}
await
_checkStatic
(
path
.
join
(
await
_checkStatic
(
path
.
join
(
cocoapodsOutputPath
,
cocoapodsOutputPath
,
mode
,
mode
,
...
@@ -750,6 +822,13 @@ Future<void> _checkDylib(String pathToLibrary) async {
...
@@ -750,6 +822,13 @@ Future<void> _checkDylib(String pathToLibrary) async {
}
}
}
}
Future
<
void
>
_checkDsym
(
String
pathToSymbolFile
)
async
{
final
String
binaryFileType
=
await
fileType
(
pathToSymbolFile
);
if
(!
binaryFileType
.
contains
(
'dSYM companion file'
))
{
throw
TaskResult
.
failure
(
'
$pathToSymbolFile
is not a dSYM, found:
$binaryFileType
'
);
}
}
Future
<
void
>
_checkStatic
(
String
pathToLibrary
)
async
{
Future
<
void
>
_checkStatic
(
String
pathToLibrary
)
async
{
final
String
binaryFileType
=
await
fileType
(
pathToLibrary
);
final
String
binaryFileType
=
await
fileType
(
pathToLibrary
);
if
(!
binaryFileType
.
contains
(
'current ar archive random library'
))
{
if
(!
binaryFileType
.
contains
(
'current ar archive random library'
))
{
...
...
dev/devicelab/bin/tasks/module_test_ios.dart
View file @
723b82e4
...
@@ -440,6 +440,16 @@ end
...
@@ -440,6 +440,16 @@ end
'Frameworks'
,
'Frameworks'
,
'url_launcher_ios.framework'
,
'url_launcher_ios.framework'
,
));
));
checkFileExists
(
path
.
join
(
'
${objectiveCBuildArchiveDirectory.path}
.xcarchive'
,
'dSYMs'
,
'App.framework.dSYM'
,
'Contents'
,
'Resources'
,
'DWARF'
,
'App'
));
});
});
section
(
'Run platform unit tests'
);
section
(
'Run platform unit tests'
);
...
...
packages/flutter_tools/lib/src/base/build.dart
View file @
723b82e4
...
@@ -139,10 +139,17 @@ class AOTSnapshotter {
...
@@ -139,10 +139,17 @@ class AOTSnapshotter {
'--deterministic'
,
'--deterministic'
,
];
];
final
bool
targetingApplePlatform
=
platform
==
TargetPlatform
.
ios
||
platform
==
TargetPlatform
.
darwin
;
_logger
.
printTrace
(
'targetingApplePlatform =
$targetingApplePlatform
'
);
final
bool
extractAppleDebugSymbols
=
buildMode
==
BuildMode
.
profile
||
buildMode
==
BuildMode
.
release
;
_logger
.
printTrace
(
'extractAppleDebugSymbols =
$extractAppleDebugSymbols
'
);
// We strip snapshot by default, but allow to suppress this behavior
// We strip snapshot by default, but allow to suppress this behavior
// by supplying --no-strip in extraGenSnapshotOptions.
// by supplying --no-strip in extraGenSnapshotOptions.
bool
shouldStrip
=
true
;
bool
shouldStrip
=
true
;
if
(
extraGenSnapshotOptions
!=
null
&&
extraGenSnapshotOptions
.
isNotEmpty
)
{
if
(
extraGenSnapshotOptions
!=
null
&&
extraGenSnapshotOptions
.
isNotEmpty
)
{
_logger
.
printTrace
(
'Extra gen_snapshot options:
$extraGenSnapshotOptions
'
);
_logger
.
printTrace
(
'Extra gen_snapshot options:
$extraGenSnapshotOptions
'
);
for
(
final
String
option
in
extraGenSnapshotOptions
)
{
for
(
final
String
option
in
extraGenSnapshotOptions
)
{
...
@@ -168,8 +175,20 @@ class AOTSnapshotter {
...
@@ -168,8 +175,20 @@ class AOTSnapshotter {
]);
]);
}
}
if
(
shouldStrip
)
{
// When buiding for iOS and splitting out debug info, we want to strip
genSnapshotArgs
.
add
(
'--strip'
);
// manually after the dSYM export, instead of in the `gen_snapshot`.
final
bool
stripAfterBuild
;
if
(
targetingApplePlatform
)
{
stripAfterBuild
=
shouldStrip
;
if
(
stripAfterBuild
)
{
_logger
.
printTrace
(
'Will strip AOT snapshot manual after build and dSYM generation.'
);
}
}
else
{
stripAfterBuild
=
false
;
if
(
shouldStrip
)
{
genSnapshotArgs
.
add
(
'--strip'
);
_logger
.
printTrace
(
'Will strip AOT snapshot during build.'
);
}
}
}
if
(
platform
==
TargetPlatform
.
android_arm
)
{
if
(
platform
==
TargetPlatform
.
android_arm
)
{
...
@@ -218,8 +237,8 @@ class AOTSnapshotter {
...
@@ -218,8 +237,8 @@ class AOTSnapshotter {
// On iOS and macOS, we use Xcode to compile the snapshot into a dynamic library that the
// On iOS and macOS, we use Xcode to compile the snapshot into a dynamic library that the
// end-developer can link into their app.
// end-developer can link into their app.
if
(
platform
==
TargetPlatform
.
ios
||
platform
==
TargetPlatform
.
darwin
)
{
if
(
targetingApplePlatform
)
{
final
RunResult
result
=
await
_buildFramework
(
return
_buildFramework
(
appleArch:
darwinArch
!,
appleArch:
darwinArch
!,
isIOS:
platform
==
TargetPlatform
.
ios
,
isIOS:
platform
==
TargetPlatform
.
ios
,
sdkRoot:
sdkRoot
,
sdkRoot:
sdkRoot
,
...
@@ -227,24 +246,26 @@ class AOTSnapshotter {
...
@@ -227,24 +246,26 @@ class AOTSnapshotter {
outputPath:
outputDir
.
path
,
outputPath:
outputDir
.
path
,
bitcode:
bitcode
,
bitcode:
bitcode
,
quiet:
quiet
,
quiet:
quiet
,
stripAfterBuild:
stripAfterBuild
,
extractAppleDebugSymbols:
extractAppleDebugSymbols
);
);
if
(
result
.
exitCode
!=
0
)
{
}
else
{
return
result
.
exitCode
;
return
0
;
}
}
}
return
0
;
}
}
/// Builds an iOS or macOS framework at [outputPath]/App.framework from the assembly
/// Builds an iOS or macOS framework at [outputPath]/App.framework from the assembly
/// source at [assemblyPath].
/// source at [assemblyPath].
Future
<
RunResul
t
>
_buildFramework
({
Future
<
in
t
>
_buildFramework
({
required
DarwinArch
appleArch
,
required
DarwinArch
appleArch
,
required
bool
isIOS
,
required
bool
isIOS
,
String
?
sdkRoot
,
String
?
sdkRoot
,
required
String
assemblyPath
,
required
String
assemblyPath
,
required
String
outputPath
,
required
String
outputPath
,
required
bool
bitcode
,
required
bool
bitcode
,
required
bool
quiet
required
bool
quiet
,
required
bool
stripAfterBuild
,
required
bool
extractAppleDebugSymbols
})
async
{
})
async
{
final
String
targetArch
=
getNameForDarwinArch
(
appleArch
);
final
String
targetArch
=
getNameForDarwinArch
(
appleArch
);
if
(!
quiet
)
{
if
(!
quiet
)
{
...
@@ -278,7 +299,7 @@ class AOTSnapshotter {
...
@@ -278,7 +299,7 @@ class AOTSnapshotter {
]);
]);
if
(
compileResult
.
exitCode
!=
0
)
{
if
(
compileResult
.
exitCode
!=
0
)
{
_logger
.
printError
(
'Failed to compile AOT snapshot. Compiler terminated with exit code
${compileResult.exitCode}
'
);
_logger
.
printError
(
'Failed to compile AOT snapshot. Compiler terminated with exit code
${compileResult.exitCode}
'
);
return
compileResult
;
return
compileResult
.
exitCode
;
}
}
final
String
frameworkDir
=
_fileSystem
.
path
.
join
(
outputPath
,
'App.framework'
);
final
String
frameworkDir
=
_fileSystem
.
path
.
join
(
outputPath
,
'App.framework'
);
...
@@ -294,11 +315,33 @@ class AOTSnapshotter {
...
@@ -294,11 +315,33 @@ class AOTSnapshotter {
'-o'
,
appLib
,
'-o'
,
appLib
,
assemblyO
,
assemblyO
,
];
];
final
RunResult
linkResult
=
await
_xcode
.
clang
(
linkArgs
);
final
RunResult
linkResult
=
await
_xcode
.
clang
(
linkArgs
);
if
(
linkResult
.
exitCode
!=
0
)
{
if
(
linkResult
.
exitCode
!=
0
)
{
_logger
.
printError
(
'Failed to link AOT snapshot. Linker terminated with exit code
${compileResult.exitCode}
'
);
_logger
.
printError
(
'Failed to link AOT snapshot. Linker terminated with exit code
${linkResult.exitCode}
'
);
return
linkResult
.
exitCode
;
}
if
(
extractAppleDebugSymbols
)
{
final
RunResult
dsymResult
=
await
_xcode
.
dsymutil
(<
String
>[
'-o'
,
'
$frameworkDir
.dSYM'
,
appLib
]);
if
(
dsymResult
.
exitCode
!=
0
)
{
_logger
.
printError
(
'Failed to generate dSYM - dsymutil terminated with exit code
${dsymResult.exitCode}
'
);
return
dsymResult
.
exitCode
;
}
if
(
stripAfterBuild
)
{
// See https://www.unix.com/man-page/osx/1/strip/ for arguments
final
RunResult
stripResult
=
await
_xcode
.
strip
(<
String
>[
'-S'
,
appLib
,
'-o'
,
appLib
]);
if
(
stripResult
.
exitCode
!=
0
)
{
_logger
.
printError
(
'Failed to strip debugging symbols from the generated AOT snapshot - strip terminated with exit code
${stripResult.exitCode}
'
);
return
stripResult
.
exitCode
;
}
}
}
else
{
assert
(
stripAfterBuild
==
false
);
}
}
return
linkResult
;
return
0
;
}
}
bool
_isValidAotPlatform
(
TargetPlatform
platform
,
BuildMode
buildMode
)
{
bool
_isValidAotPlatform
(
TargetPlatform
platform
,
BuildMode
buildMode
)
{
...
...
packages/flutter_tools/lib/src/build_system/targets/common.dart
View file @
723b82e4
...
@@ -7,6 +7,7 @@ import 'package:package_config/package_config.dart';
...
@@ -7,6 +7,7 @@ import 'package:package_config/package_config.dart';
import
'../../artifacts.dart'
;
import
'../../artifacts.dart'
;
import
'../../base/build.dart'
;
import
'../../base/build.dart'
;
import
'../../base/file_system.dart'
;
import
'../../base/file_system.dart'
;
import
'../../base/io.dart'
;
import
'../../build_info.dart'
;
import
'../../build_info.dart'
;
import
'../../compile.dart'
;
import
'../../compile.dart'
;
import
'../../dart/package_map.dart'
;
import
'../../dart/package_map.dart'
;
...
@@ -394,3 +395,48 @@ abstract class CopyFlutterAotBundle extends Target {
...
@@ -394,3 +395,48 @@ abstract class CopyFlutterAotBundle extends Target {
environment
.
buildDir
.
childFile
(
'app.so'
).
copySync
(
outputFile
.
path
);
environment
.
buildDir
.
childFile
(
'app.so'
).
copySync
(
outputFile
.
path
);
}
}
}
}
/// Lipo CLI tool wrapper shared by iOS and macOS builds.
class
Lipo
{
/// Static only.
Lipo
.
_
();
/// Create a "fat" binary by combining multiple architecture-specific ones.
/// `skipMissingInputs` can be changed to `true` to first check whether
/// the expected input paths exist and ignore the command if they don't.
/// Otherwise, `lipo` would fail if the given paths didn't exist.
static
Future
<
void
>
create
(
Environment
environment
,
List
<
DarwinArch
>
darwinArchs
,
{
required
String
relativePath
,
required
String
inputDir
,
bool
skipMissingInputs
=
false
,
})
async
{
final
String
resultPath
=
environment
.
fileSystem
.
path
.
join
(
environment
.
buildDir
.
path
,
relativePath
);
environment
.
fileSystem
.
directory
(
resultPath
).
parent
.
createSync
(
recursive:
true
);
Iterable
<
String
>
inputPaths
=
darwinArchs
.
map
(
(
DarwinArch
iosArch
)
=>
environment
.
fileSystem
.
path
.
join
(
inputDir
,
getNameForDarwinArch
(
iosArch
),
relativePath
)
);
if
(
skipMissingInputs
)
{
inputPaths
=
inputPaths
.
where
(
environment
.
fileSystem
.
isFileSync
);
if
(
inputPaths
.
isEmpty
)
{
return
;
}
}
final
List
<
String
>
lipoArgs
=
<
String
>[
'lipo'
,
...
inputPaths
,
'-create'
,
'-output'
,
resultPath
,
];
final
ProcessResult
result
=
await
environment
.
processManager
.
run
(
lipoArgs
);
if
(
result
.
exitCode
!=
0
)
{
throw
Exception
(
'lipo exited with code
${result.exitCode}
.
\n
${result.stderr}
'
);
}
}
}
packages/flutter_tools/lib/src/build_system/targets/ios.dart
View file @
723b82e4
...
@@ -112,19 +112,24 @@ abstract class AotAssemblyBase extends Target {
...
@@ -112,19 +112,24 @@ abstract class AotAssemblyBase extends Target {
if
(
results
.
any
((
int
result
)
=>
result
!=
0
))
{
if
(
results
.
any
((
int
result
)
=>
result
!=
0
))
{
throw
Exception
(
'AOT snapshotter exited with code
${results.join()}
'
);
throw
Exception
(
'AOT snapshotter exited with code
${results.join()}
'
);
}
}
final
String
resultPath
=
environment
.
fileSystem
.
path
.
join
(
environment
.
buildDir
.
path
,
'App.framework'
,
'App'
);
environment
.
fileSystem
.
directory
(
resultPath
).
parent
.
createSync
(
recursive:
true
);
// Combine the app lib into a fat framework.
final
ProcessResult
result
=
await
environment
.
processManager
.
run
(<
String
>[
await
Lipo
.
create
(
'lipo'
,
environment
,
...
darwinArchs
.
map
((
DarwinArch
iosArch
)
=>
darwinArchs
,
environment
.
fileSystem
.
path
.
join
(
buildOutputPath
,
getNameForDarwinArch
(
iosArch
),
'App.framework'
,
'App'
)),
relativePath:
'App.framework/App'
,
'-create'
,
inputDir:
buildOutputPath
,
'-output'
,
);
resultPath
,
]);
// And combine the dSYM for each architecture too, if it was created.
if
(
result
.
exitCode
!=
0
)
{
await
Lipo
.
create
(
throw
Exception
(
'lipo exited with code
${result.exitCode}
.
\n
${result.stderr}
'
);
environment
,
}
darwinArchs
,
relativePath:
'App.framework.dSYM/Contents/Resources/DWARF/App'
,
inputDir:
buildOutputPath
,
// Don't fail if the dSYM wasn't created (i.e. during a debug build).
skipMissingInputs:
true
,
);
}
}
}
}
...
@@ -489,6 +494,26 @@ abstract class IosAssetBundle extends Target {
...
@@ -489,6 +494,26 @@ abstract class IosAssetBundle extends Target {
.
copySync
(
frameworkBinaryPath
);
.
copySync
(
frameworkBinaryPath
);
}
}
// Copy the dSYM
if
(
environment
.
buildDir
.
childDirectory
(
'App.framework.dSYM'
).
existsSync
())
{
final
File
dsymOutputBinary
=
environment
.
outputDir
.
childDirectory
(
'App.framework.dSYM'
)
.
childDirectory
(
'Contents'
)
.
childDirectory
(
'Resources'
)
.
childDirectory
(
'DWARF'
)
.
childFile
(
'App'
);
dsymOutputBinary
.
parent
.
createSync
(
recursive:
true
);
environment
.
buildDir
.
childDirectory
(
'App.framework.dSYM'
)
.
childDirectory
(
'Contents'
)
.
childDirectory
(
'Resources'
)
.
childDirectory
(
'DWARF'
)
.
childFile
(
'App'
)
.
copySync
(
dsymOutputBinary
.
path
);
}
// Copy the assets.
// Copy the assets.
final
Depfile
assetDepfile
=
await
copyAssets
(
final
Depfile
assetDepfile
=
await
copyAssets
(
environment
,
environment
,
...
@@ -547,8 +572,25 @@ class DebugIosApplicationBundle extends IosAssetBundle {
...
@@ -547,8 +572,25 @@ class DebugIosApplicationBundle extends IosAssetBundle {
];
];
}
}
/// IosAssetBundle with debug symbols, used for Profile and Release builds.
abstract
class
_IosAssetBundleWithDSYM
extends
IosAssetBundle
{
const
_IosAssetBundleWithDSYM
();
@override
List
<
Source
>
get
inputs
=>
<
Source
>[
...
super
.
inputs
,
const
Source
.
pattern
(
'{BUILD_DIR}/App.framework.dSYM/Contents/Resources/DWARF/App'
),
];
@override
List
<
Source
>
get
outputs
=>
<
Source
>[
...
super
.
outputs
,
const
Source
.
pattern
(
'{OUTPUT_DIR}/App.framework.dSYM/Contents/Resources/DWARF/App'
),
];
}
/// Build a profile iOS application bundle.
/// Build a profile iOS application bundle.
class
ProfileIosApplicationBundle
extends
IosAssetBundle
{
class
ProfileIosApplicationBundle
extends
_IosAssetBundleWithDSYM
{
const
ProfileIosApplicationBundle
();
const
ProfileIosApplicationBundle
();
@override
@override
...
@@ -561,7 +603,7 @@ class ProfileIosApplicationBundle extends IosAssetBundle {
...
@@ -561,7 +603,7 @@ class ProfileIosApplicationBundle extends IosAssetBundle {
}
}
/// Build a release iOS application bundle.
/// Build a release iOS application bundle.
class
ReleaseIosApplicationBundle
extends
IosAssetBundle
{
class
ReleaseIosApplicationBundle
extends
_IosAssetBundleWithDSYM
{
const
ReleaseIosApplicationBundle
();
const
ReleaseIosApplicationBundle
();
@override
@override
...
...
packages/flutter_tools/lib/src/build_system/targets/macos.dart
View file @
723b82e4
...
@@ -302,19 +302,23 @@ class CompileMacOSFramework extends Target {
...
@@ -302,19 +302,23 @@ class CompileMacOSFramework extends Target {
throw
Exception
(
'AOT snapshotter exited with code
${results.join()}
'
);
throw
Exception
(
'AOT snapshotter exited with code
${results.join()}
'
);
}
}
final
String
resultPath
=
environment
.
fileSystem
.
path
.
join
(
environment
.
buildDir
.
path
,
'App.framework'
,
'App'
);
// Combine the app lib into a fat framework.
environment
.
fileSystem
.
directory
(
resultPath
).
parent
.
createSync
(
recursive:
true
);
await
Lipo
.
create
(
final
ProcessResult
result
=
await
environment
.
processManager
.
run
(<
String
>[
environment
,
'lipo'
,
darwinArchs
,
...
darwinArchs
.
map
((
DarwinArch
iosArch
)
=>
relativePath:
'App.framework/App'
,
environment
.
fileSystem
.
path
.
join
(
buildOutputPath
,
getNameForDarwinArch
(
iosArch
),
'App.framework'
,
'App'
)),
inputDir:
buildOutputPath
,
'-create'
,
);
'-output'
,
resultPath
,
// And combine the dSYM for each architecture too, if it was created.
]);
await
Lipo
.
create
(
if
(
result
.
exitCode
!=
0
)
{
environment
,
throw
Exception
(
'lipo exited with code
${result.exitCode}
.
\n
${result.stderr}
'
);
darwinArchs
,
}
relativePath:
'App.framework.dSYM/Contents/Resources/DWARF/App'
,
inputDir:
buildOutputPath
,
// Don't fail if the dSYM wasn't created (i.e. during a debug build).
skipMissingInputs:
true
,
);
}
}
@override
@override
...
@@ -332,6 +336,7 @@ class CompileMacOSFramework extends Target {
...
@@ -332,6 +336,7 @@ class CompileMacOSFramework extends Target {
@override
@override
List
<
Source
>
get
outputs
=>
const
<
Source
>[
List
<
Source
>
get
outputs
=>
const
<
Source
>[
Source
.
pattern
(
'{BUILD_DIR}/App.framework/App'
),
Source
.
pattern
(
'{BUILD_DIR}/App.framework/App'
),
Source
.
pattern
(
'{BUILD_DIR}/App.framework.dSYM/Contents/Resources/DWARF/App'
),
];
];
}
}
...
@@ -382,6 +387,26 @@ abstract class MacOSBundleFlutterAssets extends Target {
...
@@ -382,6 +387,26 @@ abstract class MacOSBundleFlutterAssets extends Target {
.
childFile
(
'App'
)
.
childFile
(
'App'
)
.
copySync
(
outputDirectory
.
childFile
(
'App'
).
path
);
.
copySync
(
outputDirectory
.
childFile
(
'App'
).
path
);
// Copy the dSYM
if
(
environment
.
buildDir
.
childDirectory
(
'App.framework.dSYM'
).
existsSync
())
{
final
File
dsymOutputBinary
=
environment
.
outputDir
.
childDirectory
(
'App.framework.dSYM'
)
.
childDirectory
(
'Contents'
)
.
childDirectory
(
'Resources'
)
.
childDirectory
(
'DWARF'
)
.
childFile
(
'App'
);
dsymOutputBinary
.
parent
.
createSync
(
recursive:
true
);
environment
.
buildDir
.
childDirectory
(
'App.framework.dSYM'
)
.
childDirectory
(
'Contents'
)
.
childDirectory
(
'Resources'
)
.
childDirectory
(
'DWARF'
)
.
childFile
(
'App'
)
.
copySync
(
dsymOutputBinary
.
path
);
}
// Copy assets into asset directory.
// Copy assets into asset directory.
final
Directory
assetDirectory
=
outputDirectory
final
Directory
assetDirectory
=
outputDirectory
.
childDirectory
(
'Resources'
)
.
childDirectory
(
'Resources'
)
...
@@ -530,6 +555,18 @@ class ProfileMacOSBundleFlutterAssets extends MacOSBundleFlutterAssets {
...
@@ -530,6 +555,18 @@ class ProfileMacOSBundleFlutterAssets extends MacOSBundleFlutterAssets {
CompileMacOSFramework
(),
CompileMacOSFramework
(),
ProfileUnpackMacOS
(),
ProfileUnpackMacOS
(),
];
];
@override
List
<
Source
>
get
inputs
=>
<
Source
>[
...
super
.
inputs
,
const
Source
.
pattern
(
'{BUILD_DIR}/App.framework.dSYM/Contents/Resources/DWARF/App'
),
];
@override
List
<
Source
>
get
outputs
=>
<
Source
>[
...
super
.
outputs
,
const
Source
.
pattern
(
'{OUTPUT_DIR}/App.framework.dSYM/Contents/Resources/DWARF/App'
),
];
}
}
...
@@ -546,6 +583,18 @@ class ReleaseMacOSBundleFlutterAssets extends MacOSBundleFlutterAssets {
...
@@ -546,6 +583,18 @@ class ReleaseMacOSBundleFlutterAssets extends MacOSBundleFlutterAssets {
ReleaseUnpackMacOS
(),
ReleaseUnpackMacOS
(),
];
];
@override
List
<
Source
>
get
inputs
=>
<
Source
>[
...
super
.
inputs
,
const
Source
.
pattern
(
'{BUILD_DIR}/App.framework.dSYM/Contents/Resources/DWARF/App'
),
];
@override
List
<
Source
>
get
outputs
=>
<
Source
>[
...
super
.
outputs
,
const
Source
.
pattern
(
'{OUTPUT_DIR}/App.framework.dSYM/Contents/Resources/DWARF/App'
),
];
@override
@override
Future
<
void
>
build
(
Environment
environment
)
async
{
Future
<
void
>
build
(
Environment
environment
)
async
{
bool
buildSuccess
=
true
;
bool
buildSuccess
=
true
;
...
...
packages/flutter_tools/lib/src/commands/symbolize.dart
View file @
723b82e4
...
@@ -68,8 +68,11 @@ class SymbolizeCommand extends FlutterCommand {
...
@@ -68,8 +68,11 @@ class SymbolizeCommand extends FlutterCommand {
if
(
argResults
?.
wasParsed
(
'debug-info'
)
!=
true
)
{
if
(
argResults
?.
wasParsed
(
'debug-info'
)
!=
true
)
{
throwToolExit
(
'"--debug-info" is required to symbolize stack traces.'
);
throwToolExit
(
'"--debug-info" is required to symbolize stack traces.'
);
}
}
if
(!
_fileSystem
.
isFileSync
(
stringArgDeprecated
(
'debug-info'
)!))
{
final
String
debugInfoPath
=
stringArgDeprecated
(
'debug-info'
)!;
throwToolExit
(
'
${stringArgDeprecated('debug-info')}
does not exist.'
);
if
(
debugInfoPath
.
endsWith
(
'.dSYM'
)
?
!
_fileSystem
.
isDirectorySync
(
debugInfoPath
)
:
!
_fileSystem
.
isFileSync
(
debugInfoPath
))
{
throwToolExit
(
'
$debugInfoPath
does not exist.'
);
}
}
if
((
argResults
?.
wasParsed
(
'input'
)
??
false
)
&&
!
_fileSystem
.
isFileSync
(
stringArgDeprecated
(
'input'
)!))
{
if
((
argResults
?.
wasParsed
(
'input'
)
??
false
)
&&
!
_fileSystem
.
isFileSync
(
stringArgDeprecated
(
'input'
)!))
{
throwToolExit
(
'
${stringArgDeprecated('input')}
does not exist.'
);
throwToolExit
(
'
${stringArgDeprecated('input')}
does not exist.'
);
...
@@ -105,7 +108,25 @@ class SymbolizeCommand extends FlutterCommand {
...
@@ -105,7 +108,25 @@ class SymbolizeCommand extends FlutterCommand {
input
=
_stdio
.
stdin
;
input
=
_stdio
.
stdin
;
}
}
final
Uint8List
symbols
=
_fileSystem
.
file
(
stringArgDeprecated
(
'debug-info'
)).
readAsBytesSync
();
String
debugInfoPath
=
stringArgDeprecated
(
'debug-info'
)!;
// If it's a dSYM container, expand the path to the actual DWARF.
if
(
debugInfoPath
.
endsWith
(
'.dSYM'
))
{
final
Directory
debugInfoDir
=
_fileSystem
.
directory
(
debugInfoPath
)
.
childDirectory
(
'Contents'
)
.
childDirectory
(
'Resources'
)
.
childDirectory
(
'DWARF'
);
final
List
<
FileSystemEntity
>
dwarfFiles
=
debugInfoDir
.
listSync
().
whereType
<
File
>().
toList
();
if
(
dwarfFiles
.
length
==
1
)
{
debugInfoPath
=
dwarfFiles
.
first
.
path
;
}
else
{
throwToolExit
(
'Expected a single DWARF file in a dSYM container.'
);
}
}
final
Uint8List
symbols
=
_fileSystem
.
file
(
debugInfoPath
).
readAsBytesSync
();
await
_dwarfSymbolizationService
.
decode
(
await
_dwarfSymbolizationService
.
decode
(
input:
input
,
input:
input
,
output:
output
,
output:
output
,
...
...
packages/flutter_tools/lib/src/macos/xcode.dart
View file @
723b82e4
...
@@ -165,16 +165,17 @@ class Xcode {
...
@@ -165,16 +165,17 @@ class Xcode {
/// See [XcodeProjectInterpreter.xcrunCommand].
/// See [XcodeProjectInterpreter.xcrunCommand].
List
<
String
>
xcrunCommand
()
=>
_xcodeProjectInterpreter
.
xcrunCommand
();
List
<
String
>
xcrunCommand
()
=>
_xcodeProjectInterpreter
.
xcrunCommand
();
Future
<
RunResult
>
cc
(
List
<
String
>
args
)
{
Future
<
RunResult
>
cc
(
List
<
String
>
args
)
=>
_run
(
'cc'
,
args
);
return
_processUtils
.
run
(
<
String
>[...
xcrunCommand
(),
'cc'
,
...
args
],
Future
<
RunResult
>
clang
(
List
<
String
>
args
)
=>
_run
(
'clang'
,
args
);
throwOnError:
true
,
);
Future
<
RunResult
>
dsymutil
(
List
<
String
>
args
)
=>
_run
(
'dsymutil'
,
args
);
}
Future
<
RunResult
>
strip
(
List
<
String
>
args
)
=>
_run
(
'strip'
,
args
);
Future
<
RunResult
>
clang
(
List
<
String
>
args
)
{
Future
<
RunResult
>
_run
(
String
command
,
List
<
String
>
args
)
{
return
_processUtils
.
run
(
return
_processUtils
.
run
(
<
String
>[...
xcrunCommand
(),
'clang'
,
...
args
],
<
String
>[...
xcrunCommand
(),
command
,
...
args
],
throwOnError:
true
,
throwOnError:
true
,
);
);
}
}
...
...
packages/flutter_tools/test/commands.shard/hermetic/symbolize_test.dart
View file @
723b82e4
...
@@ -69,7 +69,7 @@ void main() {
...
@@ -69,7 +69,7 @@ void main() {
OutputPreferences:
()
=>
OutputPreferences
.
test
(),
OutputPreferences:
()
=>
OutputPreferences
.
test
(),
});
});
testUsingContext
(
'symbolize exits when --debug-info file is missing'
,
()
async
{
testUsingContext
(
'symbolize exits when --debug-info
dwarf
file is missing'
,
()
async
{
final
SymbolizeCommand
command
=
SymbolizeCommand
(
final
SymbolizeCommand
command
=
SymbolizeCommand
(
stdio:
stdio
,
stdio:
stdio
,
fileSystem:
fileSystem
,
fileSystem:
fileSystem
,
...
@@ -83,6 +83,20 @@ void main() {
...
@@ -83,6 +83,20 @@ void main() {
OutputPreferences:
()
=>
OutputPreferences
.
test
(),
OutputPreferences:
()
=>
OutputPreferences
.
test
(),
});
});
testUsingContext
(
'symbolize exits when --debug-info dSYM is missing'
,
()
async
{
final
SymbolizeCommand
command
=
SymbolizeCommand
(
stdio:
stdio
,
fileSystem:
fileSystem
,
dwarfSymbolizationService:
DwarfSymbolizationService
.
test
(),
);
final
Future
<
void
>
result
=
createTestCommandRunner
(
command
)
.
run
(
const
<
String
>[
'symbolize'
,
'--debug-info=app.dSYM'
]);
expect
(
result
,
throwsToolExit
(
message:
'app.dSYM does not exist.'
));
},
overrides:
<
Type
,
Generator
>{
OutputPreferences:
()
=>
OutputPreferences
.
test
(),
});
testUsingContext
(
'symbolize exits when --input file is missing'
,
()
async
{
testUsingContext
(
'symbolize exits when --input file is missing'
,
()
async
{
final
SymbolizeCommand
command
=
SymbolizeCommand
(
final
SymbolizeCommand
command
=
SymbolizeCommand
(
stdio:
stdio
,
stdio:
stdio
,
...
...
packages/flutter_tools/test/general.shard/base/build_test.dart
View file @
723b82e4
...
@@ -210,7 +210,6 @@ void main() {
...
@@ -210,7 +210,6 @@ void main() {
'--deterministic'
,
'--deterministic'
,
'--snapshot_kind=app-aot-assembly'
,
'--snapshot_kind=app-aot-assembly'
,
'--assembly=
$assembly
'
,
'--assembly=
$assembly
'
,
'--strip'
,
'main.dill'
,
'main.dill'
,
]),
]),
kWhichSysctlCommand
,
kWhichSysctlCommand
,
...
@@ -253,6 +252,21 @@ void main() {
...
@@ -253,6 +252,21 @@ void main() {
'build/foo/App.framework/App'
,
'build/foo/App.framework/App'
,
'build/foo/snapshot_assembly.o'
,
'build/foo/snapshot_assembly.o'
,
]),
]),
const
FakeCommand
(
command:
<
String
>[
'xcrun'
,
'dsymutil'
,
'-o'
,
'build/foo/App.framework.dSYM'
,
'build/foo/App.framework/App'
,
]),
const
FakeCommand
(
command:
<
String
>[
'xcrun'
,
'strip'
,
'-S'
,
'build/foo/App.framework/App'
,
'-o'
,
'build/foo/App.framework/App'
,
]),
]);
]);
final
int
genSnapshotExitCode
=
await
snapshotter
.
build
(
final
int
genSnapshotExitCode
=
await
snapshotter
.
build
(
...
@@ -285,7 +299,6 @@ void main() {
...
@@ -285,7 +299,6 @@ void main() {
'--deterministic'
,
'--deterministic'
,
'--snapshot_kind=app-aot-assembly'
,
'--snapshot_kind=app-aot-assembly'
,
'--assembly=
$assembly
'
,
'--assembly=
$assembly
'
,
'--strip'
,
'--dwarf-stack-traces'
,
'--dwarf-stack-traces'
,
'--save-debugging-info=
$debugPath
'
,
'--save-debugging-info=
$debugPath
'
,
'main.dill'
,
'main.dill'
,
...
@@ -312,6 +325,21 @@ void main() {
...
@@ -312,6 +325,21 @@ void main() {
'arm64'
,
'arm64'
,
...
kDefaultClang
,
...
kDefaultClang
,
]),
]),
const
FakeCommand
(
command:
<
String
>[
'xcrun'
,
'dsymutil'
,
'-o'
,
'build/foo/App.framework.dSYM'
,
'build/foo/App.framework/App'
,
]),
const
FakeCommand
(
command:
<
String
>[
'xcrun'
,
'strip'
,
'-S'
,
'build/foo/App.framework/App'
,
'-o'
,
'build/foo/App.framework/App'
,
]),
]);
]);
final
int
genSnapshotExitCode
=
await
snapshotter
.
build
(
final
int
genSnapshotExitCode
=
await
snapshotter
.
build
(
...
@@ -344,7 +372,6 @@ void main() {
...
@@ -344,7 +372,6 @@ void main() {
'--deterministic'
,
'--deterministic'
,
'--snapshot_kind=app-aot-assembly'
,
'--snapshot_kind=app-aot-assembly'
,
'--assembly=
$assembly
'
,
'--assembly=
$assembly
'
,
'--strip'
,
'--obfuscate'
,
'--obfuscate'
,
'main.dill'
,
'main.dill'
,
]),
]),
...
@@ -370,6 +397,21 @@ void main() {
...
@@ -370,6 +397,21 @@ void main() {
'arm64'
,
'arm64'
,
...
kDefaultClang
,
...
kDefaultClang
,
]),
]),
const
FakeCommand
(
command:
<
String
>[
'xcrun'
,
'dsymutil'
,
'-o'
,
'build/foo/App.framework.dSYM'
,
'build/foo/App.framework/App'
,
]),
const
FakeCommand
(
command:
<
String
>[
'xcrun'
,
'strip'
,
'-S'
,
'build/foo/App.framework/App'
,
'-o'
,
'build/foo/App.framework/App'
,
]),
]);
]);
final
int
genSnapshotExitCode
=
await
snapshotter
.
build
(
final
int
genSnapshotExitCode
=
await
snapshotter
.
build
(
...
@@ -400,7 +442,6 @@ void main() {
...
@@ -400,7 +442,6 @@ void main() {
'--deterministic'
,
'--deterministic'
,
'--snapshot_kind=app-aot-assembly'
,
'--snapshot_kind=app-aot-assembly'
,
'--assembly=
${fileSystem.path.join(outputPath, 'snapshot_assembly.S')}
'
,
'--assembly=
${fileSystem.path.join(outputPath, 'snapshot_assembly.S')}
'
,
'--strip'
,
'main.dill'
,
'main.dill'
,
]),
]),
kWhichSysctlCommand
,
kWhichSysctlCommand
,
...
@@ -425,6 +466,21 @@ void main() {
...
@@ -425,6 +466,21 @@ void main() {
'arm64'
,
'arm64'
,
...
kDefaultClang
,
...
kDefaultClang
,
]),
]),
const
FakeCommand
(
command:
<
String
>[
'xcrun'
,
'dsymutil'
,
'-o'
,
'build/foo/App.framework.dSYM'
,
'build/foo/App.framework/App'
,
]),
const
FakeCommand
(
command:
<
String
>[
'xcrun'
,
'strip'
,
'-S'
,
'build/foo/App.framework/App'
,
'-o'
,
'build/foo/App.framework/App'
,
]),
]);
]);
final
int
genSnapshotExitCode
=
await
snapshotter
.
build
(
final
int
genSnapshotExitCode
=
await
snapshotter
.
build
(
...
...
packages/flutter_tools/test/general.shard/build_system/targets/common_test.dart
View file @
723b82e4
...
@@ -477,7 +477,6 @@ void main() {
...
@@ -477,7 +477,6 @@ void main() {
'--deterministic'
,
'--deterministic'
,
kAssemblyAot
,
kAssemblyAot
,
'--assembly=
$build
/arm64/snapshot_assembly.S'
,
'--assembly=
$build
/arm64/snapshot_assembly.S'
,
'--strip'
,
'
$build
/app.dill'
,
'
$build
/app.dill'
,
]),
]),
FakeCommand
(
command:
<
String
>[
FakeCommand
(
command:
<
String
>[
...
@@ -520,6 +519,21 @@ void main() {
...
@@ -520,6 +519,21 @@ void main() {
'
$build
/arm64/App.framework/App'
,
'
$build
/arm64/App.framework/App'
,
'
$build
/arm64/snapshot_assembly.o'
,
'
$build
/arm64/snapshot_assembly.o'
,
]),
]),
FakeCommand
(
command:
<
String
>[
'xcrun'
,
'dsymutil'
,
'-o'
,
'
$build
/arm64/App.framework.dSYM'
,
'
$build
/arm64/App.framework/App'
,
]),
FakeCommand
(
command:
<
String
>[
'xcrun'
,
'strip'
,
'-S'
,
'
$build
/arm64/App.framework/App'
,
'-o'
,
'
$build
/arm64/App.framework/App'
,
]),
FakeCommand
(
command:
<
String
>[
FakeCommand
(
command:
<
String
>[
'lipo'
,
'lipo'
,
'
$build
/arm64/App.framework/App'
,
'
$build
/arm64/App.framework/App'
,
...
@@ -553,7 +567,6 @@ void main() {
...
@@ -553,7 +567,6 @@ void main() {
'--trace-precompiler-to=code_size_1/trace.arm64.json'
,
'--trace-precompiler-to=code_size_1/trace.arm64.json'
,
kAssemblyAot
,
kAssemblyAot
,
'--assembly=
$build
/arm64/snapshot_assembly.S'
,
'--assembly=
$build
/arm64/snapshot_assembly.S'
,
'--strip'
,
'
$build
/app.dill'
,
'
$build
/app.dill'
,
]),
]),
FakeCommand
(
command:
<
String
>[
FakeCommand
(
command:
<
String
>[
...
@@ -596,6 +609,21 @@ void main() {
...
@@ -596,6 +609,21 @@ void main() {
'
$build
/arm64/App.framework/App'
,
'
$build
/arm64/App.framework/App'
,
'
$build
/arm64/snapshot_assembly.o'
,
'
$build
/arm64/snapshot_assembly.o'
,
]),
]),
FakeCommand
(
command:
<
String
>[
'xcrun'
,
'dsymutil'
,
'-o'
,
'
$build
/arm64/App.framework.dSYM'
,
'
$build
/arm64/App.framework/App'
,
]),
FakeCommand
(
command:
<
String
>[
'xcrun'
,
'strip'
,
'-S'
,
'
$build
/arm64/App.framework/App'
,
'-o'
,
'
$build
/arm64/App.framework/App'
,
]),
FakeCommand
(
command:
<
String
>[
FakeCommand
(
command:
<
String
>[
'lipo'
,
'lipo'
,
'
$build
/arm64/App.framework/App'
,
'
$build
/arm64/App.framework/App'
,
...
...
packages/flutter_tools/test/general.shard/build_system/targets/ios_test.dart
View file @
723b82e4
...
@@ -239,6 +239,14 @@ void main() {
...
@@ -239,6 +239,14 @@ void main() {
.
childFile
(
'App'
)
.
childFile
(
'App'
)
.
createSync
(
recursive:
true
);
.
createSync
(
recursive:
true
);
// Input dSYM
environment
.
buildDir
.
childDirectory
(
'App.framework.dSYM'
)
.
childDirectory
(
'Contents'
)
.
childDirectory
(
'Resources'
)
.
childDirectory
(
'DWARF'
)
.
childFile
(
'App'
)
.
createSync
(
recursive:
true
);
final
Directory
frameworkDirectory
=
environment
.
outputDir
.
childDirectory
(
'App.framework'
);
final
Directory
frameworkDirectory
=
environment
.
outputDir
.
childDirectory
(
'App.framework'
);
final
File
frameworkDirectoryBinary
=
frameworkDirectory
.
childFile
(
'App'
);
final
File
frameworkDirectoryBinary
=
frameworkDirectory
.
childFile
(
'App'
);
...
@@ -257,6 +265,12 @@ void main() {
...
@@ -257,6 +265,12 @@ void main() {
expect
(
frameworkDirectoryBinary
,
exists
);
expect
(
frameworkDirectoryBinary
,
exists
);
expect
(
frameworkDirectory
.
childFile
(
'Info.plist'
),
exists
);
expect
(
frameworkDirectory
.
childFile
(
'Info.plist'
),
exists
);
expect
(
environment
.
outputDir
.
childDirectory
(
'App.framework.dSYM'
)
.
childDirectory
(
'Contents'
)
.
childDirectory
(
'Resources'
)
.
childDirectory
(
'DWARF'
)
.
childFile
(
'App'
),
exists
);
final
Directory
assetDirectory
=
frameworkDirectory
.
childDirectory
(
'flutter_assets'
);
final
Directory
assetDirectory
=
frameworkDirectory
.
childDirectory
(
'flutter_assets'
);
expect
(
assetDirectory
.
childFile
(
'kernel_blob.bin'
),
isNot
(
exists
));
expect
(
assetDirectory
.
childFile
(
'kernel_blob.bin'
),
isNot
(
exists
));
...
...
packages/flutter_tools/test/general.shard/build_system/targets/macos_test.dart
View file @
723b82e4
...
@@ -295,6 +295,28 @@ void main() {
...
@@ -295,6 +295,28 @@ void main() {
ProcessManager:
()
=>
processManager
,
ProcessManager:
()
=>
processManager
,
});
});
testUsingContext
(
'release macOS application creates App.framework.dSYM'
,
()
async
{
fileSystem
.
file
(
'bin/cache/artifacts/engine/darwin-x64/vm_isolate_snapshot.bin'
)
.
createSync
(
recursive:
true
);
fileSystem
.
file
(
'bin/cache/artifacts/engine/darwin-x64/isolate_snapshot.bin'
)
.
createSync
(
recursive:
true
);
fileSystem
.
file
(
'
${environment.buildDir.path}
/App.framework/App'
)
.
createSync
(
recursive:
true
);
fileSystem
.
file
(
'
${environment.buildDir.path}
/App.framework.dSYM/Contents/Resources/DWARF/App'
)
.
createSync
(
recursive:
true
);
await
const
ReleaseMacOSBundleFlutterAssets
()
.
build
(
environment
..
defines
[
kBuildMode
]
=
'release'
);
expect
(
fileSystem
.
file
(
'App.framework.dSYM/Contents/Resources/DWARF/App'
),
exists
,
);
},
overrides:
<
Type
,
Generator
>{
FileSystem:
()
=>
fileSystem
,
ProcessManager:
()
=>
processManager
,
});
testUsingContext
(
'release/profile macOS application updates when App.framework updates'
,
()
async
{
testUsingContext
(
'release/profile macOS application updates when App.framework updates'
,
()
async
{
fileSystem
.
file
(
'bin/cache/artifacts/engine/darwin-x64/vm_isolate_snapshot.bin'
)
fileSystem
.
file
(
'bin/cache/artifacts/engine/darwin-x64/vm_isolate_snapshot.bin'
)
.
createSync
(
recursive:
true
);
.
createSync
(
recursive:
true
);
...
@@ -415,13 +437,20 @@ void main() {
...
@@ -415,13 +437,20 @@ void main() {
environment
.
defines
[
kDarwinArchs
]
=
'arm64 x86_64'
;
environment
.
defines
[
kDarwinArchs
]
=
'arm64 x86_64'
;
environment
.
defines
[
kBuildMode
]
=
'release'
;
environment
.
defines
[
kBuildMode
]
=
'release'
;
// Input dSYMs need to exist for `lipo` to combine them
environment
.
buildDir
.
childFile
(
'arm64/App.framework.dSYM/Contents/Resources/DWARF/App'
)
.
createSync
(
recursive:
true
);
environment
.
buildDir
.
childFile
(
'x86_64/App.framework.dSYM/Contents/Resources/DWARF/App'
)
.
createSync
(
recursive:
true
);
processManager
.
addCommands
(<
FakeCommand
>[
processManager
.
addCommands
(<
FakeCommand
>[
FakeCommand
(
command:
<
String
>[
FakeCommand
(
command:
<
String
>[
'Artifact.genSnapshot.TargetPlatform.darwin.release_arm64'
,
'Artifact.genSnapshot.TargetPlatform.darwin.release_arm64'
,
'--deterministic'
,
'--deterministic'
,
'--snapshot_kind=app-aot-assembly'
,
'--snapshot_kind=app-aot-assembly'
,
'--assembly=
${environment.buildDir.childFile('arm64/snapshot_assembly.S').path}
'
,
'--assembly=
${environment.buildDir.childFile('arm64/snapshot_assembly.S').path}
'
,
'--strip'
,
environment
.
buildDir
.
childFile
(
'app.dill'
).
path
,
environment
.
buildDir
.
childFile
(
'app.dill'
).
path
,
]),
]),
FakeCommand
(
command:
<
String
>[
FakeCommand
(
command:
<
String
>[
...
@@ -429,7 +458,6 @@ void main() {
...
@@ -429,7 +458,6 @@ void main() {
'--deterministic'
,
'--deterministic'
,
'--snapshot_kind=app-aot-assembly'
,
'--snapshot_kind=app-aot-assembly'
,
'--assembly=
${environment.buildDir.childFile('x86_64/snapshot_assembly.S').path}
'
,
'--assembly=
${environment.buildDir.childFile('x86_64/snapshot_assembly.S').path}
'
,
'--strip'
,
environment
.
buildDir
.
childFile
(
'app.dill'
).
path
,
environment
.
buildDir
.
childFile
(
'app.dill'
).
path
,
]),
]),
FakeCommand
(
command:
<
String
>[
FakeCommand
(
command:
<
String
>[
...
@@ -458,6 +486,36 @@ void main() {
...
@@ -458,6 +486,36 @@ void main() {
'-o'
,
environment
.
buildDir
.
childFile
(
'x86_64/App.framework/App'
).
path
,
'-o'
,
environment
.
buildDir
.
childFile
(
'x86_64/App.framework/App'
).
path
,
environment
.
buildDir
.
childFile
(
'x86_64/snapshot_assembly.o'
).
path
,
environment
.
buildDir
.
childFile
(
'x86_64/snapshot_assembly.o'
).
path
,
]),
]),
FakeCommand
(
command:
<
String
>[
'xcrun'
,
'dsymutil'
,
'-o'
,
environment
.
buildDir
.
childFile
(
'arm64/App.framework.dSYM'
).
path
,
environment
.
buildDir
.
childFile
(
'arm64/App.framework/App'
).
path
,
]),
FakeCommand
(
command:
<
String
>[
'xcrun'
,
'dsymutil'
,
'-o'
,
environment
.
buildDir
.
childFile
(
'x86_64/App.framework.dSYM'
).
path
,
environment
.
buildDir
.
childFile
(
'x86_64/App.framework/App'
).
path
,
]),
FakeCommand
(
command:
<
String
>[
'xcrun'
,
'strip'
,
'-S'
,
environment
.
buildDir
.
childFile
(
'arm64/App.framework/App'
).
path
,
'-o'
,
environment
.
buildDir
.
childFile
(
'arm64/App.framework/App'
).
path
,
]),
FakeCommand
(
command:
<
String
>[
'xcrun'
,
'strip'
,
'-S'
,
environment
.
buildDir
.
childFile
(
'x86_64/App.framework/App'
).
path
,
'-o'
,
environment
.
buildDir
.
childFile
(
'x86_64/App.framework/App'
).
path
,
]),
FakeCommand
(
command:
<
String
>[
FakeCommand
(
command:
<
String
>[
'lipo'
,
'lipo'
,
environment
.
buildDir
.
childFile
(
'arm64/App.framework/App'
).
path
,
environment
.
buildDir
.
childFile
(
'arm64/App.framework/App'
).
path
,
...
@@ -466,6 +524,14 @@ void main() {
...
@@ -466,6 +524,14 @@ void main() {
'-output'
,
'-output'
,
environment
.
buildDir
.
childFile
(
'App.framework/App'
).
path
,
environment
.
buildDir
.
childFile
(
'App.framework/App'
).
path
,
]),
]),
FakeCommand
(
command:
<
String
>[
'lipo'
,
environment
.
buildDir
.
childFile
(
'arm64/App.framework.dSYM/Contents/Resources/DWARF/App'
).
path
,
environment
.
buildDir
.
childFile
(
'x86_64/App.framework.dSYM/Contents/Resources/DWARF/App'
).
path
,
'-create'
,
'-output'
,
environment
.
buildDir
.
childFile
(
'App.framework.dSYM/Contents/Resources/DWARF/App'
).
path
,
]),
]);
]);
await
const
CompileMacOSFramework
().
build
(
environment
);
await
const
CompileMacOSFramework
().
build
(
environment
);
...
...
packages/flutter_tools/test/host_cross_arch.shard/ios_content_validation_test.dart
View file @
723b82e4
...
@@ -5,6 +5,7 @@
...
@@ -5,6 +5,7 @@
import
'package:file_testing/file_testing.dart'
;
import
'package:file_testing/file_testing.dart'
;
import
'package:flutter_tools/src/base/file_system.dart'
;
import
'package:flutter_tools/src/base/file_system.dart'
;
import
'package:flutter_tools/src/base/io.dart'
;
import
'package:flutter_tools/src/base/io.dart'
;
import
'package:flutter_tools/src/base/utils.dart'
;
import
'package:flutter_tools/src/build_info.dart'
;
import
'package:flutter_tools/src/build_info.dart'
;
import
'../integration.shard/test_utils.dart'
;
import
'../integration.shard/test_utils.dart'
;
...
@@ -75,7 +76,7 @@ void main() {
...
@@ -75,7 +76,7 @@ void main() {
for
(
final
BuildMode
buildMode
in
<
BuildMode
>[
BuildMode
.
debug
,
BuildMode
.
release
])
{
for
(
final
BuildMode
buildMode
in
<
BuildMode
>[
BuildMode
.
debug
,
BuildMode
.
release
])
{
group
(
'build in
${buildMode.name}
mode'
,
()
{
group
(
'build in
${buildMode.name}
mode'
,
()
{
late
Directory
build
Path
;
late
Directory
output
Path
;
late
Directory
outputApp
;
late
Directory
outputApp
;
late
Directory
frameworkDirectory
;
late
Directory
frameworkDirectory
;
late
Directory
outputFlutterFramework
;
late
Directory
outputFlutterFramework
;
...
@@ -83,6 +84,9 @@ void main() {
...
@@ -83,6 +84,9 @@ void main() {
late
Directory
outputAppFramework
;
late
Directory
outputAppFramework
;
late
File
outputAppFrameworkBinary
;
late
File
outputAppFrameworkBinary
;
late
File
outputPluginFrameworkBinary
;
late
File
outputPluginFrameworkBinary
;
late
Directory
buildPath
;
late
Directory
buildAppFrameworkDsym
;
late
File
buildAppFrameworkDsymBinary
;
late
ProcessResult
buildResult
;
late
ProcessResult
buildResult
;
setUpAll
(()
{
setUpAll
(()
{
...
@@ -98,14 +102,14 @@ void main() {
...
@@ -98,14 +102,14 @@ void main() {
'--split-debug-info=foo debug info/'
,
'--split-debug-info=foo debug info/'
,
],
workingDirectory:
projectRoot
);
],
workingDirectory:
projectRoot
);
build
Path
=
fileSystem
.
directory
(
fileSystem
.
path
.
join
(
output
Path
=
fileSystem
.
directory
(
fileSystem
.
path
.
join
(
projectRoot
,
projectRoot
,
'build'
,
'build'
,
'ios'
,
'ios'
,
'iphoneos'
,
'iphoneos'
,
));
));
outputApp
=
build
Path
.
childDirectory
(
'Runner.app'
);
outputApp
=
output
Path
.
childDirectory
(
'Runner.app'
);
frameworkDirectory
=
outputApp
.
childDirectory
(
'Frameworks'
);
frameworkDirectory
=
outputApp
.
childDirectory
(
'Frameworks'
);
outputFlutterFramework
=
frameworkDirectory
.
childDirectory
(
'Flutter.framework'
);
outputFlutterFramework
=
frameworkDirectory
.
childDirectory
(
'Flutter.framework'
);
...
@@ -115,6 +119,16 @@ void main() {
...
@@ -115,6 +119,16 @@ void main() {
outputAppFrameworkBinary
=
outputAppFramework
.
childFile
(
'App'
);
outputAppFrameworkBinary
=
outputAppFramework
.
childFile
(
'App'
);
outputPluginFrameworkBinary
=
frameworkDirectory
.
childDirectory
(
'hello.framework'
).
childFile
(
'hello'
);
outputPluginFrameworkBinary
=
frameworkDirectory
.
childDirectory
(
'hello.framework'
).
childFile
(
'hello'
);
buildPath
=
fileSystem
.
directory
(
fileSystem
.
path
.
join
(
projectRoot
,
'build'
,
'ios'
,
'
${sentenceCase(buildMode.name)}
-iphoneos'
,
));
buildAppFrameworkDsym
=
buildPath
.
childDirectory
(
'App.framework.dSYM'
);
buildAppFrameworkDsymBinary
=
buildAppFrameworkDsym
.
childFile
(
'Contents/Resources/DWARF/App'
);
});
});
testWithoutContext
(
'flutter build ios builds a valid app'
,
()
{
testWithoutContext
(
'flutter build ios builds a valid app'
,
()
{
...
@@ -128,6 +142,8 @@ void main() {
...
@@ -128,6 +142,8 @@ void main() {
expect
(
outputAppFrameworkBinary
,
exists
);
expect
(
outputAppFrameworkBinary
,
exists
);
expect
(
outputAppFramework
.
childFile
(
'Info.plist'
),
exists
);
expect
(
outputAppFramework
.
childFile
(
'Info.plist'
),
exists
);
expect
(
buildAppFrameworkDsymBinary
.
existsSync
(),
buildMode
!=
BuildMode
.
debug
);
final
File
vmSnapshot
=
fileSystem
.
file
(
fileSystem
.
path
.
join
(
final
File
vmSnapshot
=
fileSystem
.
file
(
fileSystem
.
path
.
join
(
outputAppFramework
.
path
,
outputAppFramework
.
path
,
'flutter_assets'
,
'flutter_assets'
,
...
@@ -190,6 +206,25 @@ void main() {
...
@@ -190,6 +206,25 @@ void main() {
expect
(
aotSymbolsFound
,
buildMode
!=
BuildMode
.
debug
);
expect
(
aotSymbolsFound
,
buildMode
!=
BuildMode
.
debug
);
});
});
// dSYM is not created for a debug build so nothing to check.
if
(
buildMode
!=
BuildMode
.
debug
)
{
testWithoutContext
(
'check symbols in dSYM'
,
()
{
final
ProcessResult
nm
=
processManager
.
runSync
(
<
String
>[
'nm'
,
'--debug-syms'
,
'--defined-only'
,
'--just-symbol-name'
,
buildAppFrameworkDsymBinary
.
path
,
'-arch'
,
'arm64'
,
],
);
final
List
<
String
>
symbols
=
(
nm
.
stdout
as
String
).
split
(
'
\n
'
);
expect
(
symbols
,
contains
(
'_kDartVmSnapshotInstructions'
));
});
}
testWithoutContext
(
'xcode_backend embed_and_thin'
,
()
{
testWithoutContext
(
'xcode_backend embed_and_thin'
,
()
{
outputFlutterFramework
.
deleteSync
(
recursive:
true
);
outputFlutterFramework
.
deleteSync
(
recursive:
true
);
outputAppFramework
.
deleteSync
(
recursive:
true
);
outputAppFramework
.
deleteSync
(
recursive:
true
);
...
@@ -219,7 +254,7 @@ void main() {
...
@@ -219,7 +254,7 @@ void main() {
'ios'
,
'ios'
,
'Release-iphoneos'
,
'Release-iphoneos'
,
),
),
'TARGET_BUILD_DIR'
:
build
Path
.
path
,
'TARGET_BUILD_DIR'
:
output
Path
.
path
,
'FRAMEWORKS_FOLDER_PATH'
:
'Runner.app/Frameworks'
,
'FRAMEWORKS_FOLDER_PATH'
:
'Runner.app/Frameworks'
,
'VERBOSE_SCRIPT_LOGGING'
:
'1'
,
'VERBOSE_SCRIPT_LOGGING'
:
'1'
,
'FLUTTER_BUILD_MODE'
:
'release'
,
'FLUTTER_BUILD_MODE'
:
'release'
,
...
...
packages/flutter_tools/test/host_cross_arch.shard/macos_content_validation_test.dart
View file @
723b82e4
...
@@ -67,18 +67,18 @@ void main() {
...
@@ -67,18 +67,18 @@ void main() {
expect
(
result
.
exitCode
,
0
);
expect
(
result
.
exitCode
,
0
);
expect
(
result
.
stdout
,
contains
(
'Running pod install'
));
expect
(
result
.
stdout
,
contains
(
'Running pod install'
));
expect
(
podfile
.
lastModifiedSync
().
isBefore
(
podfileLock
.
lastModifiedSync
()),
isTrue
);
final
Directory
outputApp
=
fileSystem
.
directory
(
fileSystem
.
path
.
join
(
final
Directory
buildPath
=
fileSystem
.
directory
(
fileSystem
.
path
.
join
(
workingDirectory
,
workingDirectory
,
'build'
,
'build'
,
'macos'
,
'macos'
,
'Build'
,
'Build'
,
'Products'
,
'Products'
,
buildMode
,
buildMode
,
'flutter_gallery.app'
,
));
));
expect
(
podfile
.
lastModifiedSync
().
isBefore
(
podfileLock
.
lastModifiedSync
()),
isTrue
);
final
Directory
outputApp
=
buildPath
.
childDirectory
(
'flutter_gallery.app'
);
final
Directory
outputAppFramework
=
final
Directory
outputAppFramework
=
fileSystem
.
directory
(
fileSystem
.
path
.
join
(
fileSystem
.
directory
(
fileSystem
.
path
.
join
(
outputApp
.
path
,
outputApp
.
path
,
...
@@ -87,19 +87,19 @@ void main() {
...
@@ -87,19 +87,19 @@ void main() {
'App.framework'
,
'App.framework'
,
));
));
final
File
outputAppFrameworkBinary
=
outputAppFramework
.
childFile
(
'App'
);
_checkFatBinary
(
final
String
archs
=
processManager
.
runSync
(
outputAppFramework
.
childFile
(
'App'
),
<
String
>[
'file'
,
outputAppFrameworkBinary
.
path
]
,
buildModeLower
,
).
stdout
as
String
;
'dynamically linked shared library'
,
);
final
bool
containsX64
=
archs
.
contains
(
'Mach-O 64-bit dynamically linked shared library x86_64'
);
final
bool
containsArm
=
archs
.
contains
(
'Mach-O 64-bit dynamically linked shared library arm64'
);
// dSYM is not created for a debug build so nothing to check.
if
(
buildMode
Lower
==
'd
ebug'
)
{
if
(
buildMode
!=
'D
ebug'
)
{
// Only build the architecture matching the machine running this test, not both.
_checkFatBinary
(
expect
(
containsX64
^
containsArm
,
isTrue
,
reason:
'Unexpected architecture
$archs
'
);
buildPath
.
childFile
(
'App.framework.dSYM/Contents/Resources/DWARF/App'
),
}
else
{
buildModeLower
,
expect
(
containsX64
,
isTrue
,
reason:
'Unexpected architecture
$archs
'
);
'dSYM companion file'
,
expect
(
containsArm
,
isTrue
,
reason:
'Unexpected architecture
$archs
'
);
);
}
}
expect
(
outputAppFramework
.
childLink
(
'Resources'
),
exists
);
expect
(
outputAppFramework
.
childLink
(
'Resources'
),
exists
);
...
@@ -172,3 +172,19 @@ void main() {
...
@@ -172,3 +172,19 @@ void main() {
},
skip:
!
platform
.
isMacOS
);
// [intended] only makes sense for macos platform.
},
skip:
!
platform
.
isMacOS
);
// [intended] only makes sense for macos platform.
}
}
}
}
void
_checkFatBinary
(
File
file
,
String
buildModeLower
,
String
expectedType
)
{
final
String
archs
=
processManager
.
runSync
(
<
String
>[
'file'
,
file
.
path
],
).
stdout
as
String
;
final
bool
containsX64
=
archs
.
contains
(
'Mach-O 64-bit
$expectedType
x86_64'
);
final
bool
containsArm
=
archs
.
contains
(
'Mach-O 64-bit
$expectedType
arm64'
);
if
(
buildModeLower
==
'debug'
)
{
// Only build the architecture matching the machine running this test, not both.
expect
(
containsX64
^
containsArm
,
isTrue
,
reason:
'Unexpected architecture
$archs
'
);
}
else
{
expect
(
containsX64
,
isTrue
,
reason:
'Unexpected architecture
$archs
'
);
expect
(
containsArm
,
isTrue
,
reason:
'Unexpected architecture
$archs
'
);
}
}
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