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
08d079f6
Unverified
Commit
08d079f6
authored
Feb 27, 2020
by
Jonah Williams
Committed by
GitHub
Feb 27, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[flutter_tools] wire up complete support for Dart obfuscation (#50509)
parent
baa4b783
Changes
25
Hide whitespace changes
Inline
Side-by-side
Showing
25 changed files
with
393 additions
and
19 deletions
+393
-19
android_obfuscate_test.dart
dev/devicelab/bin/tasks/android_obfuscate_test.dart
+62
-0
ios_obfuscate_test.dart
dev/devicelab/bin/tasks/ios_obfuscate_test.dart
+58
-0
manifest.yaml
dev/devicelab/manifest.yaml
+14
-0
macos_assemble.sh
packages/flutter_tools/bin/macos_assemble.sh
+6
-0
xcode_backend.sh
packages/flutter_tools/bin/xcode_backend.sh
+6
-0
flutter.gradle
packages/flutter_tools/gradle/flutter.gradle
+10
-0
gradle.dart
packages/flutter_tools/lib/src/android/gradle.dart
+3
-0
aot.dart
packages/flutter_tools/lib/src/aot.dart
+2
-0
build.dart
packages/flutter_tools/lib/src/base/build.dart
+18
-13
build_info.dart
packages/flutter_tools/lib/src/build_info.dart
+4
-0
android.dart
...s/flutter_tools/lib/src/build_system/targets/android.dart
+2
-0
dart.dart
...ages/flutter_tools/lib/src/build_system/targets/dart.dart
+7
-2
ios.dart
packages/flutter_tools/lib/src/build_system/targets/ios.dart
+2
-0
macos.dart
...ges/flutter_tools/lib/src/build_system/targets/macos.dart
+2
-0
build_apk.dart
packages/flutter_tools/lib/src/commands/build_apk.dart
+1
-0
build_appbundle.dart
packages/flutter_tools/lib/src/commands/build_appbundle.dart
+2
-0
build_ios.dart
packages/flutter_tools/lib/src/commands/build_ios.dart
+1
-0
build_ios_framework.dart
...s/flutter_tools/lib/src/commands/build_ios_framework.dart
+2
-0
build_macos.dart
packages/flutter_tools/lib/src/commands/build_macos.dart
+1
-0
xcodeproj.dart
packages/flutter_tools/lib/src/ios/xcodeproj.dart
+5
-0
flutter_command.dart
packages/flutter_tools/lib/src/runner/flutter_command.dart
+33
-3
.gitignore.tmpl
packages/flutter_tools/templates/app/.gitignore.tmpl
+3
-0
.gitignore.tmpl
...ges/flutter_tools/templates/module/common/.gitignore.tmpl
+3
-0
build_test.dart
...lutter_tools/test/commands.shard/hermetic/build_test.dart
+41
-0
build_test.dart
...ges/flutter_tools/test/general.shard/base/build_test.dart
+105
-1
No files found.
dev/devicelab/bin/tasks/android_obfuscate_test.dart
0 → 100644
View file @
08d079f6
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'dart:async'
;
import
'package:flutter_devicelab/framework/apk_utils.dart'
;
import
'package:flutter_devicelab/framework/framework.dart'
;
import
'package:flutter_devicelab/framework/utils.dart'
;
import
'package:path/path.dart'
as
path
;
Future
<
void
>
main
()
async
{
await
task
(()
async
{
try
{
bool
foundProjectName
=
false
;
await
runProjectTest
((
FlutterProject
flutterProject
)
async
{
section
(
'APK content for task assembleRelease with --obfuscate'
);
await
inDirectory
(
flutterProject
.
rootPath
,
()
async
{
await
flutter
(
'build'
,
options:
<
String
>[
'apk'
,
'--target-platform=android-arm'
,
'--obfuscate'
,
'--split-debug-info=foo/'
,
]);
});
final
String
outputDirectory
=
path
.
join
(
flutterProject
.
rootPath
,
'build/app/outputs/apk/release/app-release.apk'
,
);
final
Iterable
<
String
>
apkFiles
=
await
getFilesInApk
(
outputDirectory
);
checkCollectionContains
<
String
>(<
String
>[
...
flutterAssets
,
...
baseApkFiles
,
'lib/armeabi-v7a/libapp.so'
,
],
apkFiles
);
// Verify that an identifier from the Dart project code is not present
// in the compiled binary.
await
inDirectory
(
flutterProject
.
rootPath
,
()
async
{
await
exec
(
'unzip'
,
<
String
>[
outputDirectory
]);
final
String
response
=
await
eval
(
'grep'
,
<
String
>[
flutterProject
.
name
,
'lib/armeabi-v7a/libapp.so'
],
canFail:
true
,
);
if
(
response
.
trim
().
contains
(
'matches'
))
{
foundProjectName
=
true
;
}
});
});
if
(
foundProjectName
)
{
return
TaskResult
.
failure
(
'Found project name in obfuscated dart library'
);
}
return
TaskResult
.
success
(
null
);
}
on
TaskResult
catch
(
taskResult
)
{
return
taskResult
;
}
catch
(
e
)
{
return
TaskResult
.
failure
(
e
.
toString
());
}
});
}
dev/devicelab/bin/tasks/ios_obfuscate_test.dart
0 → 100644
View file @
08d079f6
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'dart:async'
;
import
'dart:io'
;
import
'package:flutter_devicelab/framework/apk_utils.dart'
;
import
'package:flutter_devicelab/framework/framework.dart'
;
import
'package:flutter_devicelab/framework/utils.dart'
;
import
'package:path/path.dart'
as
path
;
Future
<
void
>
main
()
async
{
await
task
(()
async
{
try
{
bool
foundProjectName
=
false
;
await
runProjectTest
((
FlutterProject
flutterProject
)
async
{
section
(
'iOS Framework content with --obfuscate'
);
await
inDirectory
(
flutterProject
.
rootPath
,
()
async
{
await
flutter
(
'build'
,
options:
<
String
>[
'ios'
,
'--release'
,
'--obfuscate'
,
'--split-debug-info=foo/'
,
]);
});
final
String
outputFramework
=
path
.
join
(
flutterProject
.
rootPath
,
'build/ios/iphoneos/Runner.app/Frameworks/App.framework/App'
,
);
if
(!
File
(
outputFramework
).
existsSync
())
{
fail
(
'Failed to produce expected output at
$outputFramework
'
);
}
// Verify that an identifier from the Dart project code is not present
// in the compiled binary.
await
inDirectory
(
flutterProject
.
rootPath
,
()
async
{
final
String
response
=
await
eval
(
'grep'
,
<
String
>[
flutterProject
.
name
,
outputFramework
],
canFail:
true
,
);
if
(
response
.
trim
().
contains
(
'matches'
))
{
foundProjectName
=
true
;
}
});
});
if
(
foundProjectName
)
{
return
TaskResult
.
failure
(
'Found project name in obfuscated dart library'
);
}
return
TaskResult
.
success
(
null
);
}
on
TaskResult
catch
(
taskResult
)
{
return
taskResult
;
}
catch
(
e
)
{
return
TaskResult
.
failure
(
e
.
toString
());
}
});
}
dev/devicelab/manifest.yaml
View file @
08d079f6
...
...
@@ -319,6 +319,13 @@ tasks:
stage
:
devicelab
required_agent_capabilities
:
[
"
mac/android"
]
android_obfuscate_test
:
description
:
>
Builds an obfuscated APK and verifies a dart identifier cannot be found
stage
:
devicelab
flaky
:
true
required_agent_capabilities
:
[
"
linux/android"
]
complex_layout_semantics_perf
:
description
:
>
Measures duration of building the initial semantics tree.
...
...
@@ -390,6 +397,13 @@ tasks:
# iOS on-device tests
ios_obfuscate_test
:
description
:
>
Builds an obfuscated APK and verifies a dart identifier cannot be found
stage
:
devicelab
flaky
:
true
required_agent_capabilities
:
[
"
mac/ios"
]
tiles_scroll_perf_ios__timeline_summary
:
description
:
>
Measures the runtime performance of the tiles tab in the Complex Layout sample app on iPhone 6.
...
...
packages/flutter_tools/bin/macos_assemble.sh
View file @
08d079f6
...
...
@@ -67,6 +67,11 @@ if [[ -n "$TREE_SHAKE_ICONS" ]]; then
icon_tree_shaker_flag
=
"true"
fi
dart_obfuscation_flag
=
"false"
if
[[
-n
"
$DART_OBFUSCATION
"
]]
;
then
dart_obfuscation_flag
=
"true"
fi
RunCommand
"
${
FLUTTER_ROOT
}
/bin/flutter"
--suppress-analytics
\
${
verbose_flag
}
\
${
flutter_engine_flag
}
\
...
...
@@ -76,6 +81,7 @@ RunCommand "${FLUTTER_ROOT}/bin/flutter" --suppress-analytics \
-dTargetFile
=
"
${
target_path
}
"
\
-dBuildMode
=
"
${
build_mode
}
"
\
-dTreeShakeIcons
=
"
${
icon_tree_shaker_flag
}
"
\
-dDartObfuscation
=
"
${
dart_obfuscation_flag
}
"
\
-dSplitDebugInfo
=
"
${
SPLIT_DEBUG_INFO
}
"
\
--build-inputs
=
"
${
build_inputs_path
}
"
\
--build-outputs
=
"
${
build_outputs_path
}
"
\
...
...
packages/flutter_tools/bin/xcode_backend.sh
View file @
08d079f6
...
...
@@ -166,6 +166,11 @@ BuildApp() {
icon_tree_shaker_flag
=
"true"
fi
dart_obfuscation_flag
=
"false"
if
[[
-n
"
$DART_OBFUSCATION
"
]]
;
then
dart_obfuscation_flag
=
"true"
fi
RunCommand
"
${
FLUTTER_ROOT
}
/bin/flutter"
\
${
verbose_flag
}
\
${
flutter_engine_flag
}
\
...
...
@@ -179,6 +184,7 @@ BuildApp() {
-dSplitDebugInfo
=
"
${
SPLIT_DEBUG_INFO
}
"
\
-dTreeShakeIcons
=
"
${
icon_tree_shaker_flag
}
"
\
-dTrackWidgetCreation
=
"
${
track_widget_creation_flag
}
"
\
-dDartObfuscation
=
"
${
dart_obfuscation_flag
}
"
\
-dEnableBitcode
=
"
${
bitcode_flag
}
"
\
"
${
build_mode
}
_ios_bundle_flutter_assets"
...
...
packages/flutter_tools/gradle/flutter.gradle
View file @
08d079f6
...
...
@@ -607,6 +607,10 @@ class FlutterPlugin implements Plugin<Project> {
if
(
project
.
hasProperty
(
'split-debug-info'
))
{
splitDebugInfoValue
=
project
.
property
(
'split-debug-info'
)
}
Boolean
dartObfuscationValue
=
false
if
(
project
.
hasProperty
(
'dart-obfuscation'
))
{
dartObfuscationValue
=
project
.
property
(
'dart-obfuscation'
).
toBoolean
();
}
Boolean
treeShakeIconsOptionsValue
=
false
if
(
project
.
hasProperty
(
'tree-shake-icons'
))
{
treeShakeIconsOptionsValue
=
project
.
property
(
'tree-shake-icons'
).
toBoolean
()
...
...
@@ -647,6 +651,7 @@ class FlutterPlugin implements Plugin<Project> {
extraGenSnapshotOptions
extraGenSnapshotOptionsValue
splitDebugInfo
splitDebugInfoValue
treeShakeIcons
treeShakeIconsOptionsValue
dartObfuscation
dartObfuscationValue
doLast
{
project
.
exec
{
if
(
Os
.
isFamily
(
Os
.
FAMILY_WINDOWS
))
{
...
...
@@ -792,6 +797,8 @@ abstract class BaseFlutterTask extends DefaultTask {
String
splitDebugInfo
@Optional
@Input
Boolean
treeShakeIcons
@Optional
@Input
Boolean
dartObfuscation
@OutputFiles
FileCollection
getDependenciesFiles
()
{
...
...
@@ -854,6 +861,9 @@ abstract class BaseFlutterTask extends DefaultTask {
if
(
treeShakeIcons
==
true
)
{
args
"-dTreeShakeIcons=true"
}
if
(
dartObfuscation
==
true
)
{
args
"-dDartObfuscation=true"
}
if
(
extraGenSnapshotOptions
!=
null
)
{
args
"--ExtraGenSnapshotOptions=${extraGenSnapshotOptions}"
}
...
...
packages/flutter_tools/lib/src/android/gradle.dart
View file @
08d079f6
...
...
@@ -344,6 +344,9 @@ Future<void> buildGradleApp({
if
(
androidBuildInfo
.
buildInfo
.
treeShakeIcons
)
{
command
.
add
(
'-Ptree-shake-icons=true'
);
}
if
(
androidBuildInfo
.
buildInfo
.
dartObfuscation
)
{
command
.
add
(
'-Pdart-obfuscation=true'
);
}
command
.
add
(
assembleTask
);
GradleHandledError
detectedGradleError
;
...
...
packages/flutter_tools/lib/src/aot.dart
View file @
08d079f6
...
...
@@ -93,6 +93,7 @@ class AotBuilder {
bitcode:
bitcode
,
quiet:
quiet
,
splitDebugInfo:
null
,
dartObfuscation:
false
,
).
then
<
int
>((
int
buildExitCode
)
{
return
buildExitCode
;
});
...
...
@@ -130,6 +131,7 @@ class AotBuilder {
extraGenSnapshotOptions:
extraGenSnapshotOptions
,
bitcode:
false
,
splitDebugInfo:
null
,
dartObfuscation:
false
,
);
if
(
snapshotExitCode
!=
0
)
{
status
?.
cancel
();
...
...
packages/flutter_tools/lib/src/base/build.dart
View file @
08d079f6
...
...
@@ -42,6 +42,16 @@ class GenSnapshot {
Artifact
.
genSnapshot
,
platform:
snapshotType
.
platform
,
mode:
snapshotType
.
mode
);
}
/// Ignored warning messages from gen_snapshot.
static
const
Set
<
String
>
kIgnoredWarnings
=
<
String
>{
// --strip on elf snapshot.
'Warning: Generating ELF library without DWARF debugging information.'
,
// --strip on ios-assembly snapshot.
'Warning: Generating assembly code without DWARF debugging information.'
,
// A fun two-part message with spaces for obfuscation.
'Warning: This VM has been configured to obfuscate symbol information which violates the Dart standard.'
,
' See dartbug.com/30524 for more information.'
,
};
Future
<
int
>
run
({
@required
SnapshotType
snapshotType
,
DarwinArch
darwinArch
,
...
...
@@ -59,18 +69,9 @@ class GenSnapshot {
snapshotterPath
+=
'_'
+
getNameForDarwinArch
(
darwinArch
);
}
StringConverter
outputFilter
;
if
(
additionalArgs
.
contains
(
'--strip'
))
{
// Filter out gen_snapshot's warning message about stripping debug symbols
// from ELF library snapshots.
const
String
kStripWarning
=
'Warning: Generating ELF library without DWARF debugging information.'
;
const
String
kAssemblyStripWarning
=
'Warning: Generating assembly code without DWARF debugging information.'
;
outputFilter
=
(
String
line
)
=>
line
!=
kStripWarning
&&
line
!=
kAssemblyStripWarning
?
line
:
null
;
}
return
processUtils
.
stream
(
<
String
>[
snapshotterPath
,
...
args
],
mapFunction:
outputFilter
,
mapFunction:
(
String
line
)
=>
kIgnoredWarnings
.
contains
(
line
)
?
null
:
line
,
);
}
}
...
...
@@ -94,6 +95,7 @@ class AOTSnapshotter {
List
<
String
>
extraGenSnapshotOptions
=
const
<
String
>[],
@required
bool
bitcode
,
@required
String
splitDebugInfo
,
@required
bool
dartObfuscation
,
bool
quiet
=
false
,
})
async
{
if
(
bitcode
&&
platform
!=
TargetPlatform
.
ios
)
{
...
...
@@ -147,7 +149,8 @@ class AOTSnapshotter {
// multiple debug files.
final
String
archName
=
getNameForTargetPlatform
(
platform
,
darwinArch:
darwinArch
);
final
String
debugFilename
=
'app.
$archName
.symbols'
;
if
(
splitDebugInfo
?.
isNotEmpty
??
false
)
{
final
bool
shouldSplitDebugInfo
=
splitDebugInfo
?.
isNotEmpty
??
false
;
if
(
shouldSplitDebugInfo
)
{
globals
.
fs
.
directory
(
splitDebugInfo
)
.
createSync
(
recursive:
true
);
}
...
...
@@ -157,10 +160,12 @@ class AOTSnapshotter {
// Faster async/await
'--no-causal-async-stacks'
,
'--lazy-async-stacks'
,
if
(
s
plitDebugInfo
?.
isNotEmpty
??
false
)
...<
String
>[
if
(
s
houldSplitDebugInfo
)
...<
String
>[
'--dwarf-stack-traces'
,
'--save-debugging-info=
${globals.fs.path.join(splitDebugInfo, debugFilename)}
'
]
],
if
(
dartObfuscation
)
'--obfuscate'
,
]);
genSnapshotArgs
.
add
(
mainPath
);
...
...
packages/flutter_tools/lib/src/build_info.dart
View file @
08d079f6
...
...
@@ -22,6 +22,7 @@ class BuildInfo {
this
.
buildNumber
,
this
.
buildName
,
this
.
splitDebugInfoPath
,
this
.
dartObfuscation
=
false
,
@required
this
.
treeShakeIcons
,
});
...
...
@@ -68,6 +69,9 @@ class BuildInfo {
/// executable.
final
String
splitDebugInfoPath
;
/// Whether to apply dart source code obfuscation.
final
bool
dartObfuscation
;
static
const
BuildInfo
debug
=
BuildInfo
(
BuildMode
.
debug
,
null
,
treeShakeIcons:
false
);
static
const
BuildInfo
profile
=
BuildInfo
(
BuildMode
.
profile
,
null
,
treeShakeIcons:
kIconTreeShakerEnabledDefault
);
static
const
BuildInfo
jitRelease
=
BuildInfo
(
BuildMode
.
jitRelease
,
null
,
treeShakeIcons:
kIconTreeShakerEnabledDefault
);
...
...
packages/flutter_tools/lib/src/build_system/targets/android.dart
View file @
08d079f6
...
...
@@ -222,6 +222,7 @@ class AndroidAot extends AotElfBase {
final
List
<
String
>
extraGenSnapshotOptions
=
environment
.
defines
[
kExtraGenSnapshotOptions
]?.
split
(
','
)
??
const
<
String
>[];
final
BuildMode
buildMode
=
getBuildModeForName
(
environment
.
defines
[
kBuildMode
]);
final
bool
dartObfuscation
=
environment
.
defines
[
kDartObfuscation
]
==
'true'
;
final
int
snapshotExitCode
=
await
snapshotter
.
build
(
platform:
targetPlatform
,
buildMode:
buildMode
,
...
...
@@ -231,6 +232,7 @@ class AndroidAot extends AotElfBase {
bitcode:
false
,
extraGenSnapshotOptions:
extraGenSnapshotOptions
,
splitDebugInfo:
splitDebugInfo
,
dartObfuscation:
dartObfuscation
,
);
if
(
snapshotExitCode
!=
0
)
{
throw
Exception
(
'AOT snapshotter exited with code
$snapshotExitCode
'
);
...
...
packages/flutter_tools/lib/src/build_system/targets/dart.dart
View file @
08d079f6
...
...
@@ -66,6 +66,9 @@ const String kDartDefines = 'DartDefines';
/// The other supported value is armv7, the 32-bit iOS architecture.
const
String
kIosArchs
=
'IosArchs'
;
/// Whether to enable Dart obfuscation and where to save the symbol map.
const
String
kDartObfuscation
=
'DartObfuscation'
;
/// Copies the pre-built flutter bundle.
// This is a one-off rule for implementing build bundle in terms of assemble.
class
CopyFlutterBundle
extends
Target
{
...
...
@@ -270,7 +273,8 @@ abstract class AotElfBase extends Target {
??
const
<
String
>[];
final
BuildMode
buildMode
=
getBuildModeForName
(
environment
.
defines
[
kBuildMode
]);
final
TargetPlatform
targetPlatform
=
getTargetPlatformForName
(
environment
.
defines
[
kTargetPlatform
]);
final
String
saveDebuggingInformation
=
environment
.
defines
[
kSplitDebugInfo
];
final
String
splitDebugInfo
=
environment
.
defines
[
kSplitDebugInfo
];
final
bool
dartObfuscation
=
environment
.
defines
[
kDartObfuscation
]
==
'true'
;
final
int
snapshotExitCode
=
await
snapshotter
.
build
(
platform:
targetPlatform
,
buildMode:
buildMode
,
...
...
@@ -279,7 +283,8 @@ abstract class AotElfBase extends Target {
outputPath:
outputPath
,
bitcode:
false
,
extraGenSnapshotOptions:
extraGenSnapshotOptions
,
splitDebugInfo:
saveDebuggingInformation
splitDebugInfo:
splitDebugInfo
,
dartObfuscation:
dartObfuscation
,
);
if
(
snapshotExitCode
!=
0
)
{
throw
Exception
(
'AOT snapshotter exited with code
$snapshotExitCode
'
);
...
...
packages/flutter_tools/lib/src/build_system/targets/ios.dart
View file @
08d079f6
...
...
@@ -40,6 +40,7 @@ abstract class AotAssemblyBase extends Target {
final
BuildMode
buildMode
=
getBuildModeForName
(
environment
.
defines
[
kBuildMode
]);
final
TargetPlatform
targetPlatform
=
getTargetPlatformForName
(
environment
.
defines
[
kTargetPlatform
]);
final
String
splitDebugInfo
=
environment
.
defines
[
kSplitDebugInfo
];
final
bool
dartObfuscation
=
environment
.
defines
[
kDartObfuscation
]
==
'true'
;
final
List
<
DarwinArch
>
iosArchs
=
environment
.
defines
[
kIosArchs
]
?.
split
(
' '
)
?.
map
(
getIOSArchForName
)
...
...
@@ -63,6 +64,7 @@ abstract class AotAssemblyBase extends Target {
bitcode:
bitcode
,
quiet:
true
,
splitDebugInfo:
splitDebugInfo
,
dartObfuscation:
dartObfuscation
,
));
}
final
List
<
int
>
results
=
await
Future
.
wait
(
pending
);
...
...
packages/flutter_tools/lib/src/build_system/targets/macos.dart
View file @
08d079f6
...
...
@@ -201,6 +201,7 @@ class CompileMacOSFramework extends Target {
throw
Exception
(
'precompiled macOS framework only supported in release/profile builds.'
);
}
final
String
splitDebugInfo
=
environment
.
defines
[
kSplitDebugInfo
];
final
bool
dartObfuscation
=
environment
.
defines
[
kDartObfuscation
]
==
'true'
;
final
int
result
=
await
AOTSnapshotter
(
reportTimings:
false
).
build
(
bitcode:
false
,
buildMode:
buildMode
,
...
...
@@ -210,6 +211,7 @@ class CompileMacOSFramework extends Target {
darwinArch:
DarwinArch
.
x86_64
,
packagesPath:
environment
.
projectDir
.
childFile
(
'.packages'
).
path
,
splitDebugInfo:
splitDebugInfo
,
dartObfuscation:
dartObfuscation
,
);
if
(
result
!=
0
)
{
throw
Exception
(
'gen shapshot failed.'
);
...
...
packages/flutter_tools/lib/src/commands/build_apk.dart
View file @
08d079f6
...
...
@@ -27,6 +27,7 @@ class BuildApkCommand extends BuildSubCommand {
usesBuildNameOption
();
addShrinkingFlag
();
addSplitDebugInfoOption
();
addDartObfuscationOption
();
argParser
..
addFlag
(
'split-per-abi'
,
negatable:
false
,
...
...
packages/flutter_tools/lib/src/commands/build_appbundle.dart
View file @
08d079f6
...
...
@@ -24,6 +24,8 @@ class BuildAppBundleCommand extends BuildSubCommand {
usesBuildNumberOption
();
usesBuildNameOption
();
addShrinkingFlag
();
addSplitDebugInfoOption
();
addDartObfuscationOption
();
argParser
..
addFlag
(
'track-widget-creation'
,
negatable:
false
,
hide:
!
verboseHelp
)
...
...
packages/flutter_tools/lib/src/commands/build_ios.dart
View file @
08d079f6
...
...
@@ -26,6 +26,7 @@ class BuildIOSCommand extends BuildSubCommand {
usesPubOption
();
usesBuildNumberOption
();
usesBuildNameOption
();
addDartObfuscationOption
();
argParser
..
addFlag
(
'simulator'
,
help:
'Build for the iOS simulator instead of the device.'
,
...
...
packages/flutter_tools/lib/src/commands/build_ios_framework.dart
View file @
08d079f6
...
...
@@ -49,6 +49,8 @@ class BuildIOSFrameworkCommand extends BuildSubCommand {
usesFlavorOption
();
usesPubOption
();
usesDartDefines
();
addSplitDebugInfoOption
();
addDartObfuscationOption
();
argParser
..
addFlag
(
'debug'
,
negatable:
true
,
...
...
packages/flutter_tools/lib/src/commands/build_macos.dart
View file @
08d079f6
...
...
@@ -21,6 +21,7 @@ class BuildMacosCommand extends BuildSubCommand {
addSplitDebugInfoOption
();
usesTargetOption
();
addBuildModeFlags
();
addDartObfuscationOption
();
}
@override
...
...
packages/flutter_tools/lib/src/ios/xcodeproj.dart
View file @
08d079f6
...
...
@@ -172,6 +172,11 @@ List<String> _xcodeBuildSettingsLines({
xcodeBuildSettings
.
add
(
'SPLIT_DEBUG_INFO=
${buildInfo.splitDebugInfoPath}
'
);
}
// This is an optional path to obfuscate and output a mapping.
if
(
buildInfo
.
dartObfuscation
)
{
xcodeBuildSettings
.
add
(
'DART_OBFUSCATION=true'
);
}
// The build outputs directory, relative to FLUTTER_APPLICATION_PATH.
xcodeBuildSettings
.
add
(
'FLUTTER_BUILD_DIR=
${buildDirOverride ?? getBuildDirectory()}
'
);
...
...
packages/flutter_tools/lib/src/runner/flutter_command.dart
View file @
08d079f6
...
...
@@ -108,6 +108,7 @@ class FlutterOptions {
static
const
String
kFileSystemRoot
=
'filesystem-root'
;
static
const
String
kFileSystemScheme
=
'filesystem-scheme'
;
static
const
String
kSplitDebugInfoOption
=
'split-debug-info'
;
static
const
String
kDartObfuscationOption
=
'obfuscate'
;
}
abstract
class
FlutterCommand
extends
Command
<
void
>
{
...
...
@@ -393,6 +394,18 @@ abstract class FlutterCommand extends Command<void> {
);
}
void
addDartObfuscationOption
()
{
argParser
.
addFlag
(
FlutterOptions
.
kDartObfuscationOption
,
help:
'In a release build, this flag removes identifiers and replaces them '
'with randomized values for the purposes of source code obfuscation. This '
'flag must always be combined with "--split-debug-info" option, the '
'mapping between the values and the original identifiers is stored in the '
'symbol map created in the specified directory. For an app built with this '
'flag, the
\'
flutter symbolize
\'
command with the right program '
'symbol file is required to obtain a human readable stack trace.'
,
);
}
void
addTreeShakeIconsFlag
()
{
argParser
.
addFlag
(
'tree-shake-icons'
,
negatable:
true
,
...
...
@@ -483,6 +496,10 @@ abstract class FlutterCommand extends Command<void> {
);
}
/// Compute the [BuildInfo] for the current flutter command.
///
/// Throws a [ToolExit] if the current set of options is not compatible with
/// eachother.
BuildInfo
getBuildInfo
()
{
final
bool
trackWidgetCreation
=
argParser
.
options
.
containsKey
(
'track-widget-creation'
)
&&
boolArg
(
'track-widget-creation'
);
...
...
@@ -507,6 +524,20 @@ abstract class FlutterCommand extends Command<void> {
}
}
final
bool
dartObfuscation
=
argParser
.
options
.
containsKey
(
FlutterOptions
.
kDartObfuscationOption
)
&&
boolArg
(
FlutterOptions
.
kDartObfuscationOption
);
final
String
splitDebugInfoPath
=
argParser
.
options
.
containsKey
(
FlutterOptions
.
kSplitDebugInfoOption
)
?
stringArg
(
FlutterOptions
.
kSplitDebugInfoOption
)
:
null
;
if
(
dartObfuscation
&&
(
splitDebugInfoPath
==
null
||
splitDebugInfoPath
.
isEmpty
))
{
throwToolExit
(
'"--
${FlutterOptions.kDartObfuscationOption}
" can only be used in '
'combination with "--
${FlutterOptions.kSplitDebugInfoOption}
"'
,
);
}
return
BuildInfo
(
getBuildMode
(),
argParser
.
options
.
containsKey
(
'flavor'
)
?
stringArg
(
'flavor'
)
...
...
@@ -526,12 +557,11 @@ abstract class FlutterCommand extends Command<void> {
buildName:
argParser
.
options
.
containsKey
(
'build-name'
)
?
stringArg
(
'build-name'
)
:
null
,
splitDebugInfoPath:
argParser
.
options
.
containsKey
(
FlutterOptions
.
kSplitDebugInfoOption
)
?
stringArg
(
FlutterOptions
.
kSplitDebugInfoOption
)
:
null
,
treeShakeIcons:
argParser
.
options
.
containsKey
(
'tree-shake-icons'
)
?
boolArg
(
'tree-shake-icons'
)
:
kIconTreeShakerEnabledDefault
,
splitDebugInfoPath:
splitDebugInfoPath
,
dartObfuscation:
dartObfuscation
,
);
}
...
...
packages/flutter_tools/templates/app/.gitignore.tmpl
View file @
08d079f6
...
...
@@ -36,5 +36,8 @@ lib/generated_plugin_registrant.dart
# Symbolication related
app.*.symbols
# Obfuscation related
app.*.map.json
# Exceptions to above rules.
!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
packages/flutter_tools/templates/module/common/.gitignore.tmpl
View file @
08d079f6
...
...
@@ -43,3 +43,6 @@ build/
# Symbolication related
app.*.symbols
# Obfuscation related
app.*.map.json
packages/flutter_tools/test/commands.shard/hermetic/build_test.dart
0 → 100644
View file @
08d079f6
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'package:args/command_runner.dart'
;
import
'package:flutter_tools/src/base/common.dart'
;
import
'package:flutter_tools/src/runner/flutter_command.dart'
;
import
'../../src/common.dart'
;
import
'../../src/context.dart'
;
void
main
(
)
{
testUsingContext
(
'obfuscate requires split-debug-info'
,
()
{
final
FakeBuildCommand
command
=
FakeBuildCommand
();
final
CommandRunner
<
void
>
commandRunner
=
createTestCommandRunner
(
command
);
expect
(()
=>
commandRunner
.
run
(<
String
>[
'build'
,
'--obfuscate'
,
]),
throwsA
(
isA
<
ToolExit
>()));
});
}
class
FakeBuildCommand
extends
FlutterCommand
{
FakeBuildCommand
()
{
addSplitDebugInfoOption
();
addDartObfuscationOption
();
}
@override
String
get
description
=>
throw
UnimplementedError
();
@override
String
get
name
=>
'build'
;
@override
Future
<
FlutterCommandResult
>
runCommand
()
async
{
getBuildInfo
();
return
FlutterCommandResult
.
success
();
}
}
packages/flutter_tools/test/general.shard/base/build_test.dart
View file @
08d079f6
...
...
@@ -267,6 +267,7 @@ void main() {
outputPath:
outputPath
,
bitcode:
false
,
splitDebugInfo:
null
,
dartObfuscation:
false
,
),
isNot
(
equals
(
0
)));
},
overrides:
contextOverrides
);
...
...
@@ -280,6 +281,7 @@ void main() {
outputPath:
outputPath
,
bitcode:
false
,
splitDebugInfo:
null
,
dartObfuscation:
false
,
),
isNot
(
0
));
},
overrides:
contextOverrides
);
...
...
@@ -293,6 +295,7 @@ void main() {
outputPath:
outputPath
,
bitcode:
false
,
splitDebugInfo:
null
,
dartObfuscation:
false
,
),
isNot
(
0
));
},
overrides:
contextOverrides
);
...
...
@@ -320,6 +323,7 @@ void main() {
darwinArch:
DarwinArch
.
armv7
,
bitcode:
true
,
splitDebugInfo:
null
,
dartObfuscation:
false
,
);
expect
(
genSnapshotExitCode
,
0
);
...
...
@@ -381,6 +385,7 @@ void main() {
darwinArch:
DarwinArch
.
armv7
,
bitcode:
true
,
splitDebugInfo:
null
,
dartObfuscation:
false
,
);
expect
(
genSnapshotExitCode
,
0
);
...
...
@@ -441,6 +446,7 @@ void main() {
darwinArch:
DarwinArch
.
armv7
,
bitcode:
false
,
splitDebugInfo:
null
,
dartObfuscation:
false
,
);
expect
(
genSnapshotExitCode
,
0
);
...
...
@@ -469,7 +475,7 @@ void main() {
expect
(
assemblyFile
.
readAsStringSync
().
contains
(
'.section __DWARF'
),
true
);
},
overrides:
contextOverrides
);
testUsingContext
(
'builds iOS armv7 profile AOT snapshot with dwar
f stack t
races'
,
()
async
{
testUsingContext
(
'builds iOS armv7 profile AOT snapshot with dwar
StackT
races'
,
()
async
{
globals
.
fs
.
file
(
'main.dill'
).
writeAsStringSync
(
'binary magic'
);
final
String
outputPath
=
globals
.
fs
.
path
.
join
(
'build'
,
'foo'
);
...
...
@@ -494,6 +500,7 @@ void main() {
darwinArch:
DarwinArch
.
armv7
,
bitcode:
false
,
splitDebugInfo:
'foo'
,
dartObfuscation:
false
,
);
expect
(
genSnapshotExitCode
,
0
);
...
...
@@ -524,6 +531,60 @@ void main() {
expect
(
assemblyFile
.
readAsStringSync
().
contains
(
'.section __DWARF'
),
true
);
},
overrides:
contextOverrides
);
testUsingContext
(
'builds iOS armv7 profile AOT snapshot with obfuscate'
,
()
async
{
globals
.
fs
.
file
(
'main.dill'
).
writeAsStringSync
(
'binary magic'
);
final
String
outputPath
=
globals
.
fs
.
path
.
join
(
'build'
,
'foo'
);
globals
.
fs
.
directory
(
outputPath
).
createSync
(
recursive:
true
);
final
String
assembly
=
globals
.
fs
.
path
.
join
(
outputPath
,
'snapshot_assembly.S'
);
genSnapshot
.
outputs
=
<
String
,
String
>{
assembly:
'blah blah
\n
.section __DWARF
\n
blah blah
\n
'
,
};
final
RunResult
successResult
=
RunResult
(
ProcessResult
(
1
,
0
,
''
,
''
),
<
String
>[
'command name'
,
'arguments...'
]);
when
(
mockXcode
.
cc
(
any
)).
thenAnswer
((
_
)
=>
Future
<
RunResult
>.
value
(
successResult
));
when
(
mockXcode
.
clang
(
any
)).
thenAnswer
((
_
)
=>
Future
<
RunResult
>.
value
(
successResult
));
final
int
genSnapshotExitCode
=
await
snapshotter
.
build
(
platform:
TargetPlatform
.
ios
,
buildMode:
BuildMode
.
profile
,
mainPath:
'main.dill'
,
packagesPath:
'.packages'
,
outputPath:
outputPath
,
darwinArch:
DarwinArch
.
armv7
,
bitcode:
false
,
splitDebugInfo:
null
,
dartObfuscation:
true
,
);
expect
(
genSnapshotExitCode
,
0
);
expect
(
genSnapshot
.
callCount
,
1
);
expect
(
genSnapshot
.
snapshotType
.
platform
,
TargetPlatform
.
ios
);
expect
(
genSnapshot
.
snapshotType
.
mode
,
BuildMode
.
profile
);
expect
(
genSnapshot
.
additionalArgs
,
<
String
>[
'--deterministic'
,
'--snapshot_kind=app-aot-assembly'
,
'--assembly=
$assembly
'
,
'--strip'
,
'--no-sim-use-hardfp'
,
'--no-use-integer-division'
,
'--no-causal-async-stacks'
,
'--lazy-async-stacks'
,
'--obfuscate'
,
'main.dill'
,
]);
verifyNever
(
mockXcode
.
cc
(
argThat
(
contains
(
'-fembed-bitcode'
))));
verifyNever
(
mockXcode
.
clang
(
argThat
(
contains
(
'-fembed-bitcode'
))));
verify
(
mockXcode
.
cc
(
argThat
(
contains
(
'-isysroot'
)))).
called
(
1
);
verify
(
mockXcode
.
clang
(
argThat
(
contains
(
'-isysroot'
)))).
called
(
1
);
final
File
assemblyFile
=
globals
.
fs
.
file
(
assembly
);
expect
(
assemblyFile
.
existsSync
(),
true
);
expect
(
assemblyFile
.
readAsStringSync
().
contains
(
'.section __DWARF'
),
true
);
},
overrides:
contextOverrides
);
testUsingContext
(
'builds iOS arm64 profile AOT snapshot'
,
()
async
{
globals
.
fs
.
file
(
'main.dill'
).
writeAsStringSync
(
'binary magic'
);
...
...
@@ -547,6 +608,7 @@ void main() {
darwinArch:
DarwinArch
.
arm64
,
bitcode:
false
,
splitDebugInfo:
null
,
dartObfuscation:
false
,
);
expect
(
genSnapshotExitCode
,
0
);
...
...
@@ -587,6 +649,7 @@ void main() {
darwinArch:
DarwinArch
.
armv7
,
bitcode:
false
,
splitDebugInfo:
null
,
dartObfuscation:
false
,
);
expect
(
genSnapshotExitCode
,
0
);
...
...
@@ -629,6 +692,7 @@ void main() {
darwinArch:
DarwinArch
.
arm64
,
bitcode:
false
,
splitDebugInfo:
null
,
dartObfuscation:
false
,
);
expect
(
genSnapshotExitCode
,
0
);
...
...
@@ -660,6 +724,7 @@ void main() {
outputPath:
outputPath
,
bitcode:
false
,
splitDebugInfo:
null
,
dartObfuscation:
false
,
);
expect
(
genSnapshotExitCode
,
0
);
...
...
@@ -694,6 +759,7 @@ void main() {
outputPath:
outputPath
,
bitcode:
false
,
splitDebugInfo:
'foo'
,
dartObfuscation:
false
,
);
expect
(
genSnapshotExitCode
,
0
);
...
...
@@ -715,6 +781,41 @@ void main() {
]);
},
overrides:
contextOverrides
);
testUsingContext
(
'builds shared library for android-arm with obfuscate'
,
()
async
{
globals
.
fs
.
file
(
'main.dill'
).
writeAsStringSync
(
'binary magic'
);
final
String
outputPath
=
globals
.
fs
.
path
.
join
(
'build'
,
'foo'
);
globals
.
fs
.
directory
(
outputPath
).
createSync
(
recursive:
true
);
final
int
genSnapshotExitCode
=
await
snapshotter
.
build
(
platform:
TargetPlatform
.
android_arm
,
buildMode:
BuildMode
.
release
,
mainPath:
'main.dill'
,
packagesPath:
'.packages'
,
outputPath:
outputPath
,
bitcode:
false
,
splitDebugInfo:
null
,
dartObfuscation:
true
,
);
expect
(
genSnapshotExitCode
,
0
);
expect
(
genSnapshot
.
callCount
,
1
);
expect
(
genSnapshot
.
snapshotType
.
platform
,
TargetPlatform
.
android_arm
);
expect
(
genSnapshot
.
snapshotType
.
mode
,
BuildMode
.
release
);
expect
(
genSnapshot
.
additionalArgs
,
<
String
>[
'--deterministic'
,
'--snapshot_kind=app-aot-elf'
,
'--elf=build/foo/app.so'
,
'--strip'
,
'--no-sim-use-hardfp'
,
'--no-use-integer-division'
,
'--no-causal-async-stacks'
,
'--lazy-async-stacks'
,
'--obfuscate'
,
'main.dill'
,
]);
},
overrides:
contextOverrides
);
testUsingContext
(
'builds shared library for android-arm without dwarf stack traces due to empty string'
,
()
async
{
globals
.
fs
.
file
(
'main.dill'
).
writeAsStringSync
(
'binary magic'
);
...
...
@@ -729,6 +830,7 @@ void main() {
outputPath:
outputPath
,
bitcode:
false
,
splitDebugInfo:
''
,
dartObfuscation:
false
,
);
expect
(
genSnapshotExitCode
,
0
);
...
...
@@ -762,6 +864,7 @@ void main() {
outputPath:
outputPath
,
bitcode:
false
,
splitDebugInfo:
null
,
dartObfuscation:
false
,
);
expect
(
genSnapshotExitCode
,
0
);
...
...
@@ -801,6 +904,7 @@ void main() {
outputPath:
outputPath
,
bitcode:
false
,
splitDebugInfo:
null
,
dartObfuscation:
false
,
);
expect
(
genSnapshotExitCode
,
0
);
...
...
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