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
d2e87a5d
Unverified
Commit
d2e87a5d
authored
Nov 06, 2019
by
xster
Committed by
GitHub
Nov 06, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Build ios framework (#44065)
parent
028ed712
Changes
14
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
951 additions
and
283 deletions
+951
-283
test.dart
dev/bots/test.dart
+1
-0
build_ios_framework_module_test.dart
dev/devicelab/bin/tasks/build_ios_framework_module_test.dart
+143
-0
utils.dart
dev/devicelab/lib/framework/utils.dart
+7
-0
aot.dart
packages/flutter_tools/lib/src/aot.dart
+239
-0
build.dart
packages/flutter_tools/lib/src/base/build.dart
+6
-1
file_system.dart
packages/flutter_tools/lib/src/base/file_system.dart
+1
-1
ios.dart
packages/flutter_tools/lib/src/build_system/targets/ios.dart
+54
-7
build.dart
packages/flutter_tools/lib/src/commands/build.dart
+2
-0
build_aar.dart
packages/flutter_tools/lib/src/commands/build_aar.dart
+4
-4
build_aot.dart
packages/flutter_tools/lib/src/commands/build_aot.dart
+21
-268
build_ios.dart
packages/flutter_tools/lib/src/commands/build_ios.dart
+5
-1
build_ios_framework.dart
...s/flutter_tools/lib/src/commands/build_ios_framework.dart
+400
-0
bitcode.dart
packages/flutter_tools/lib/src/ios/bitcode.dart
+67
-0
build_aot_test.dart
...ter_tools/test/general.shard/commands/build_aot_test.dart
+1
-1
No files found.
dev/bots/test.dart
View file @
d2e87a5d
...
...
@@ -761,6 +761,7 @@ Future<void> _runHostOnlyDeviceLabTests() async {
// TODO(jmagman): Re-enable once flakiness is resolved, https://github.com/flutter/flutter/issues/37525
// if (Platform.isMacOS) () => _runDevicelabTest('module_test_ios'),
if
(
Platform
.
isMacOS
)
()
=>
_runDevicelabTest
(
'build_ios_framework_module_test'
),
if
(
Platform
.
isMacOS
)
()
=>
_runDevicelabTest
(
'plugin_lint_mac'
),
()
=>
_runDevicelabTest
(
'plugin_test'
,
environment:
gradleEnvironment
),
]..
shuffle
(
math
.
Random
(
0
));
...
...
dev/devicelab/bin/tasks/build_ios_framework_module_test.dart
0 → 100644
View file @
d2e87a5d
// Copyright (c) 2019 The Chromium 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
;
/// Tests that iOS .frameworks can be built on module projects.
Future
<
void
>
main
()
async
{
await
task
(()
async
{
section
(
'Create module project'
);
final
Directory
tempDir
=
Directory
.
systemTemp
.
createTempSync
(
'flutter_module_test.'
);
final
Directory
projectDir
=
Directory
(
path
.
join
(
tempDir
.
path
,
'hello'
));
try
{
await
inDirectory
(
tempDir
,
()
async
{
await
flutter
(
'create'
,
options:
<
String
>[
'--org'
,
'io.flutter.devicelab'
,
'--template'
,
'module'
,
'hello'
],
);
});
section
(
'Add plugins'
);
final
File
pubspec
=
File
(
path
.
join
(
projectDir
.
path
,
'pubspec.yaml'
));
String
content
=
pubspec
.
readAsStringSync
();
content
=
content
.
replaceFirst
(
'
\n
dependencies:
\n
'
,
'
\n
dependencies:
\n
device_info: 0.4.1
\n
package_info: 0.4.0+9
\n
'
,
);
pubspec
.
writeAsStringSync
(
content
,
flush:
true
);
await
inDirectory
(
projectDir
,
()
async
{
await
flutter
(
'packages'
,
options:
<
String
>[
'get'
],
);
});
// This builds all build modes' frameworks by default
section
(
'Build frameworks'
);
await
inDirectory
(
projectDir
,
()
async
{
await
flutter
(
'build'
,
options:
<
String
>[
'ios-framework'
],
);
});
final
String
outputPath
=
path
.
join
(
projectDir
.
path
,
'build'
,
'ios'
,
'framework'
,
);
section
(
'Check debug build has Dart snapshot as asset'
);
checkFileExists
(
path
.
join
(
outputPath
,
'Debug'
,
'App.framework'
,
'flutter_assets'
,
'vm_snapshot_data'
,
));
section
(
'Check profile, release builds has Dart dylib'
);
for
(
String
mode
in
<
String
>[
'Profile'
,
'Release'
])
{
checkFileExists
(
path
.
join
(
outputPath
,
mode
,
'App.framework'
,
'App'
,
));
checkFileNotExists
(
path
.
join
(
outputPath
,
mode
,
'App.framework'
,
'flutter_assets'
,
'vm_snapshot_data'
,
));
}
section
(
"Check all modes' engine dylib"
);
for
(
String
mode
in
<
String
>[
'Debug'
,
'Profile'
,
'Release'
])
{
checkFileExists
(
path
.
join
(
outputPath
,
mode
,
'Flutter.framework'
,
'Flutter'
,
));
}
section
(
"Check all modes' engine header"
);
for
(
String
mode
in
<
String
>[
'Debug'
,
'Profile'
,
'Release'
])
{
checkFileContains
(
<
String
>[
'#include "FlutterEngine.h"'
],
path
.
join
(
outputPath
,
mode
,
'Flutter.framework'
,
'Headers'
,
'Flutter.h'
),
);
}
section
(
"Check all modes' have plugin dylib"
);
for
(
String
mode
in
<
String
>[
'Debug'
,
'Profile'
,
'Release'
])
{
checkFileExists
(
path
.
join
(
outputPath
,
mode
,
'device_info.framework'
,
'device_info'
,
));
}
section
(
"Check all modes' have generated plugin registrant"
);
for
(
String
mode
in
<
String
>[
'Debug'
,
'Profile'
,
'Release'
])
{
checkFileExists
(
path
.
join
(
outputPath
,
mode
,
'FlutterPluginRegistrant.framework'
,
'Headers'
,
'GeneratedPluginRegistrant.h'
,
));
}
return
TaskResult
.
success
(
null
);
}
on
TaskResult
catch
(
taskResult
)
{
return
taskResult
;
}
catch
(
e
)
{
return
TaskResult
.
failure
(
e
.
toString
());
}
finally
{
rmTree
(
tempDir
);
}
});
}
dev/devicelab/lib/framework/utils.dart
View file @
d2e87a5d
...
...
@@ -625,6 +625,13 @@ void checkFileExists(String file) {
}
}
/// Checks that the file does not exists, otherwise throws a [FileSystemException].
void
checkFileNotExists
(
String
file
)
{
if
(
exists
(
File
(
file
)))
{
throw
FileSystemException
(
'Expected file to exit.'
,
file
);
}
}
void
_checkExitCode
(
int
code
)
{
if
(
code
!=
0
)
{
throw
Exception
(
...
...
packages/flutter_tools/lib/src/aot.dart
0 → 100644
View file @
d2e87a5d
// Copyright 2019 The Chromium 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:meta/meta.dart'
;
import
'base/build.dart'
;
import
'base/common.dart'
;
import
'base/file_system.dart'
;
import
'base/io.dart'
;
import
'base/logger.dart'
;
import
'base/process.dart'
;
import
'build_info.dart'
;
import
'build_system/build_system.dart'
;
import
'build_system/targets/dart.dart'
;
import
'dart/package_map.dart'
;
import
'globals.dart'
;
import
'ios/bitcode.dart'
;
import
'project.dart'
;
/// Builds AOT snapshots given a platform, build mode and a path to a Dart
/// library.
class
AotBuilder
{
Future
<
void
>
build
({
@required
TargetPlatform
platform
,
@required
String
outputPath
,
@required
BuildMode
buildMode
,
@required
String
mainDartFile
,
bool
bitcode
=
kBitcodeEnabledDefault
,
bool
quiet
=
true
,
bool
reportTimings
=
false
,
Iterable
<
DarwinArch
>
iosBuildArchs
=
defaultIOSArchs
,
List
<
String
>
extraFrontEndOptions
,
List
<
String
>
extraGenSnapshotOptions
,
})
async
{
if
(
platform
==
null
)
{
throwToolExit
(
'No AOT build platform specified'
);
}
if
(
_canUseAssemble
(
platform
)
&&
extraGenSnapshotOptions
?.
isEmpty
!=
false
&&
extraFrontEndOptions
?.
isEmpty
!=
false
)
{
await
_buildWithAssemble
(
targetFile:
mainDartFile
,
outputDir:
outputPath
,
targetPlatform:
platform
,
buildMode:
buildMode
,
quiet:
quiet
,
);
return
;
}
if
(
bitcode
)
{
if
(
platform
!=
TargetPlatform
.
ios
)
{
throwToolExit
(
'Bitcode is only supported on iOS (TargetPlatform is
$platform
).'
);
}
await
validateBitcode
(
buildMode
,
platform
);
}
Status
status
;
if
(!
quiet
)
{
final
String
typeName
=
artifacts
.
getEngineType
(
platform
,
buildMode
);
status
=
logger
.
startProgress
(
'Building AOT snapshot in
${getFriendlyModeName(buildMode)}
mode (
$typeName
)...'
,
timeout:
timeoutConfiguration
.
slowOperation
,
);
}
try
{
final
AOTSnapshotter
snapshotter
=
AOTSnapshotter
(
reportTimings:
reportTimings
);
// Compile to kernel.
final
String
kernelOut
=
await
snapshotter
.
compileKernel
(
platform:
platform
,
buildMode:
buildMode
,
mainPath:
mainDartFile
,
packagesPath:
PackageMap
.
globalPackagesPath
,
trackWidgetCreation:
false
,
outputPath:
outputPath
,
extraFrontEndOptions:
extraFrontEndOptions
,
);
if
(
kernelOut
==
null
)
{
throwToolExit
(
'Compiler terminated unexpectedly.'
);
return
;
}
// Build AOT snapshot.
if
(
platform
==
TargetPlatform
.
ios
)
{
// Determine which iOS architectures to build for.
final
Map
<
DarwinArch
,
String
>
iosBuilds
=
<
DarwinArch
,
String
>{};
for
(
DarwinArch
arch
in
iosBuildArchs
)
{
iosBuilds
[
arch
]
=
fs
.
path
.
join
(
outputPath
,
getNameForDarwinArch
(
arch
));
}
// Generate AOT snapshot and compile to arch-specific App.framework.
final
Map
<
DarwinArch
,
Future
<
int
>>
exitCodes
=
<
DarwinArch
,
Future
<
int
>>{};
iosBuilds
.
forEach
((
DarwinArch
iosArch
,
String
outputPath
)
{
exitCodes
[
iosArch
]
=
snapshotter
.
build
(
platform:
platform
,
darwinArch:
iosArch
,
buildMode:
buildMode
,
mainPath:
kernelOut
,
packagesPath:
PackageMap
.
globalPackagesPath
,
outputPath:
outputPath
,
extraGenSnapshotOptions:
extraGenSnapshotOptions
,
bitcode:
bitcode
,
quiet:
quiet
,
).
then
<
int
>((
int
buildExitCode
)
{
return
buildExitCode
;
});
});
// Merge arch-specific App.frameworks into a multi-arch App.framework.
if
((
await
Future
.
wait
<
int
>(
exitCodes
.
values
)).
every
((
int
buildExitCode
)
=>
buildExitCode
==
0
))
{
final
Iterable
<
String
>
dylibs
=
iosBuilds
.
values
.
map
<
String
>(
(
String
outputDir
)
=>
fs
.
path
.
join
(
outputDir
,
'App.framework'
,
'App'
));
fs
.
directory
(
fs
.
path
.
join
(
outputPath
,
'App.framework'
))..
createSync
();
await
processUtils
.
run
(
<
String
>[
'lipo'
,
...
dylibs
,
'-create'
,
'-output'
,
fs
.
path
.
join
(
outputPath
,
'App.framework'
,
'App'
),
],
throwOnError:
true
,
);
}
else
{
status
?.
cancel
();
exitCodes
.
forEach
((
DarwinArch
iosArch
,
Future
<
int
>
exitCodeFuture
)
async
{
final
int
buildExitCode
=
await
exitCodeFuture
;
printError
(
'Snapshotting (
$iosArch
) exited with non-zero exit code:
$buildExitCode
'
);
});
}
}
else
{
// Android AOT snapshot.
final
int
snapshotExitCode
=
await
snapshotter
.
build
(
platform:
platform
,
buildMode:
buildMode
,
mainPath:
kernelOut
,
packagesPath:
PackageMap
.
globalPackagesPath
,
outputPath:
outputPath
,
extraGenSnapshotOptions:
extraGenSnapshotOptions
,
bitcode:
false
,
);
if
(
snapshotExitCode
!=
0
)
{
status
?.
cancel
();
throwToolExit
(
'Snapshotting exited with non-zero exit code:
$snapshotExitCode
'
);
}
}
}
on
ProcessException
catch
(
error
)
{
// Catch the String exceptions thrown from the `runSync` methods below.
status
?.
cancel
();
printError
(
error
.
toString
());
return
;
}
status
?.
stop
();
if
(
outputPath
==
null
)
{
throwToolExit
(
null
);
}
final
String
builtMessage
=
'Built to
$outputPath${fs.path.separator}
.'
;
if
(
quiet
)
{
printTrace
(
builtMessage
);
}
else
{
printStatus
(
builtMessage
);
}
return
;
}
bool
_canUseAssemble
(
TargetPlatform
targetPlatform
)
{
switch
(
targetPlatform
)
{
case
TargetPlatform
.
android_arm
:
case
TargetPlatform
.
android_arm64
:
case
TargetPlatform
.
android_x86
:
case
TargetPlatform
.
darwin_x64
:
return
true
;
case
TargetPlatform
.
android_x64
:
case
TargetPlatform
.
ios
:
case
TargetPlatform
.
linux_x64
:
case
TargetPlatform
.
windows_x64
:
case
TargetPlatform
.
fuchsia_arm64
:
case
TargetPlatform
.
fuchsia_x64
:
case
TargetPlatform
.
tester
:
case
TargetPlatform
.
web_javascript
:
default
:
return
false
;
}
}
Future
<
void
>
_buildWithAssemble
({
TargetPlatform
targetPlatform
,
BuildMode
buildMode
,
String
targetFile
,
String
outputDir
,
bool
quiet
})
async
{
Status
status
;
if
(!
quiet
)
{
final
String
typeName
=
artifacts
.
getEngineType
(
targetPlatform
,
buildMode
);
status
=
logger
.
startProgress
(
'Building AOT snapshot in
${getFriendlyModeName(buildMode)}
mode (
$typeName
)...'
,
timeout:
timeoutConfiguration
.
slowOperation
,
);
}
final
FlutterProject
flutterProject
=
FlutterProject
.
current
();
// Currently this only supports android, per the check above.
final
Target
target
=
buildMode
==
BuildMode
.
profile
?
const
ProfileCopyFlutterAotBundle
()
:
const
ReleaseCopyFlutterAotBundle
();
final
BuildResult
result
=
await
buildSystem
.
build
(
target
,
Environment
(
projectDir:
flutterProject
.
directory
,
outputDir:
fs
.
directory
(
outputDir
),
buildDir:
flutterProject
.
directory
.
childDirectory
(
'.dart_tool'
)
.
childDirectory
(
'flutter_build'
),
defines:
<
String
,
String
>{
kBuildMode:
getNameForBuildMode
(
buildMode
),
kTargetPlatform:
getNameForTargetPlatform
(
targetPlatform
),
kTargetFile:
targetFile
,
}
));
status
?.
stop
();
if
(!
result
.
success
)
{
for
(
ExceptionMeasurement
measurement
in
result
.
exceptions
.
values
)
{
printError
(
measurement
.
exception
.
toString
());
printError
(
measurement
.
stackTrace
.
toString
());
}
throwToolExit
(
'Failed to build aot.'
);
}
final
String
builtMessage
=
'Built to
$outputDir${fs.path.separator}
.'
;
if
(
quiet
)
{
printTrace
(
builtMessage
);
}
else
{
printStatus
(
builtMessage
);
}
}
}
packages/flutter_tools/lib/src/base/build.dart
View file @
d2e87a5d
...
...
@@ -94,6 +94,7 @@ class AOTSnapshotter {
DarwinArch
darwinArch
,
List
<
String
>
extraGenSnapshotOptions
=
const
<
String
>[],
@required
bool
bitcode
,
bool
quiet
=
false
,
})
async
{
if
(
bitcode
&&
platform
!=
TargetPlatform
.
ios
)
{
printError
(
'Bitcode is only supported for iOS.'
);
...
...
@@ -208,6 +209,7 @@ class AOTSnapshotter {
assemblyPath:
stripSymbols
?
'
$assembly
.stripped.S'
:
assembly
,
outputPath:
outputDir
.
path
,
bitcode:
bitcode
,
quiet:
quiet
,
);
if
(
result
.
exitCode
!=
0
)
{
return
result
.
exitCode
;
...
...
@@ -224,9 +226,12 @@ class AOTSnapshotter {
@required
String
assemblyPath
,
@required
String
outputPath
,
@required
bool
bitcode
,
@required
bool
quiet
})
async
{
final
String
targetArch
=
getNameForDarwinArch
(
appleArch
);
if
(!
quiet
)
{
printStatus
(
'Building App.framework for
$targetArch
...'
);
}
final
List
<
String
>
commonBuildOptions
=
<
String
>[
'-arch'
,
targetArch
,
...
...
packages/flutter_tools/lib/src/base/file_system.dart
View file @
d2e87a5d
...
...
@@ -173,7 +173,7 @@ bool isOlderThanReference({ @required FileSystemEntity entity, @required File re
return
true
;
}
return
referenceFile
.
existsSync
()
&&
referenceFile
.
lastModifiedSync
()
.
isAfter
(
entity
.
statSync
().
modified
);
&&
referenceFile
.
statSync
().
modified
.
isAfter
(
entity
.
statSync
().
modified
);
}
/// Exception indicating that a file that was expected to exist was not found.
...
...
packages/flutter_tools/lib/src/build_system/targets/ios.dart
View file @
d2e87a5d
...
...
@@ -4,10 +4,13 @@
import
'../../artifacts.dart'
;
import
'../../base/build.dart'
;
import
'../../base/common.dart'
;
import
'../../base/file_system.dart'
;
import
'../../base/io.dart'
;
import
'../../base/process.dart'
;
import
'../../base/process_manager.dart'
;
import
'../../build_info.dart'
;
import
'../../macos/xcode.dart'
;
import
'../build_system.dart'
;
import
'../exceptions.dart'
;
import
'dart.dart'
;
...
...
@@ -22,7 +25,7 @@ abstract class AotAssemblyBase extends Target {
@override
Future
<
void
>
build
(
Environment
environment
)
async
{
final
AOTSnapshotter
snapshotter
=
AOTSnapshotter
(
reportTimings:
false
);
final
String
o
utputPath
=
environment
.
buildDir
.
path
;
final
String
buildO
utputPath
=
environment
.
buildDir
.
path
;
if
(
environment
.
defines
[
kBuildMode
]
==
null
)
{
throw
MissingDefineException
(
kBuildMode
,
'aot_assembly'
);
}
...
...
@@ -45,7 +48,7 @@ abstract class AotAssemblyBase extends Target {
buildMode:
buildMode
,
mainPath:
environment
.
buildDir
.
childFile
(
'app.dill'
).
path
,
packagesPath:
environment
.
projectDir
.
childFile
(
'.packages'
).
path
,
outputPath:
outputP
ath
,
outputPath:
environment
.
outputDir
.
p
ath
,
darwinArch:
iosArchs
.
single
,
bitcode:
bitcode
,
);
...
...
@@ -62,7 +65,7 @@ abstract class AotAssemblyBase extends Target {
buildMode:
buildMode
,
mainPath:
environment
.
buildDir
.
childFile
(
'app.dill'
).
path
,
packagesPath:
environment
.
projectDir
.
childFile
(
'.packages'
).
path
,
outputPath:
fs
.
path
.
join
(
o
utputPath
,
getNameForDarwinArch
(
iosArch
)),
outputPath:
fs
.
path
.
join
(
buildO
utputPath
,
getNameForDarwinArch
(
iosArch
)),
darwinArch:
iosArch
,
bitcode:
bitcode
,
));
...
...
@@ -74,10 +77,10 @@ abstract class AotAssemblyBase extends Target {
final
ProcessResult
result
=
await
processManager
.
run
(<
String
>[
'lipo'
,
...
iosArchs
.
map
((
DarwinArch
iosArch
)
=>
fs
.
path
.
join
(
o
utputPath
,
getNameForDarwinArch
(
iosArch
),
'App.framework'
,
'App'
)),
fs
.
path
.
join
(
buildO
utputPath
,
getNameForDarwinArch
(
iosArch
),
'App.framework'
,
'App'
)),
'-create'
,
'-output'
,
fs
.
path
.
join
(
outputP
ath
,
'App.framework'
,
'App'
),
fs
.
path
.
join
(
environment
.
outputDir
.
p
ath
,
'App.framework'
,
'App'
),
]);
if
(
result
.
exitCode
!=
0
)
{
throw
Exception
(
'lipo exited with code
${result.exitCode}
'
);
...
...
@@ -108,7 +111,7 @@ class AotAssemblyRelease extends AotAssemblyBase {
@override
List
<
Source
>
get
outputs
=>
const
<
Source
>[
Source
.
pattern
(
'{
BUILD
_DIR}/App.framework/App'
),
Source
.
pattern
(
'{
OUTPUT
_DIR}/App.framework/App'
),
];
@override
...
...
@@ -140,7 +143,7 @@ class AotAssemblyProfile extends AotAssemblyBase {
@override
List
<
Source
>
get
outputs
=>
const
<
Source
>[
Source
.
pattern
(
'{
BUILD
_DIR}/App.framework/App'
),
Source
.
pattern
(
'{
OUTPUT
_DIR}/App.framework/App'
),
];
@override
...
...
@@ -148,3 +151,47 @@ class AotAssemblyProfile extends AotAssemblyBase {
KernelSnapshot
(),
];
}
/// Create an App.framework for debug iOS targets.
///
/// This framework needs to exist for the Xcode project to link/bundle,
/// but it isn't actually executed. To generate something valid, we compile a trivial
/// constant.
Future
<
RunResult
>
createStubAppFramework
(
Directory
appFrameworkDirectory
)
async
{
File
outputFile
;
try
{
if
(!
appFrameworkDirectory
.
existsSync
())
{
appFrameworkDirectory
.
createSync
(
recursive:
true
);
}
outputFile
=
appFrameworkDirectory
.
childFile
(
'App'
);
outputFile
.
createSync
(
recursive:
true
);
}
catch
(
e
)
{
throwToolExit
(
'Failed to create App.framework stub at
${appFrameworkDirectory.path}
'
);
}
final
Directory
tempDir
=
fs
.
systemTempDirectory
.
createTempSync
(
'flutter_tools_stub_source.'
);
try
{
final
File
stubSource
=
tempDir
.
childFile
(
'debug_app.cc'
)
..
writeAsStringSync
(
r''
'
static const int Moo = 88;
'''
);
return
await
xcode
.
clang
(<
String
>[
'-x'
,
'c'
,
stubSource
.
path
,
'-dynamiclib'
,
'-Xlinker'
,
'-rpath'
,
'-Xlinker'
,
'@executable_path/Frameworks'
,
'-Xlinker'
,
'-rpath'
,
'-Xlinker'
,
'@loader_path/Frameworks'
,
'-install_name'
,
'@rpath/App.framework/App'
,
'-o'
,
outputFile
.
path
,
]);
}
finally
{
try
{
tempDir
.
deleteSync
(
recursive:
true
);
}
on
FileSystemException
catch
(
_
)
{
// Best effort. Sometimes we can't delete things from system temp.
}
}
}
packages/flutter_tools/lib/src/commands/build.dart
View file @
d2e87a5d
...
...
@@ -16,6 +16,7 @@ import 'build_appbundle.dart';
import
'build_bundle.dart'
;
import
'build_fuchsia.dart'
;
import
'build_ios.dart'
;
import
'build_ios_framework.dart'
;
import
'build_web.dart'
;
class
BuildCommand
extends
FlutterCommand
{
...
...
@@ -25,6 +26,7 @@ class BuildCommand extends FlutterCommand {
addSubcommand
(
BuildAppBundleCommand
(
verboseHelp:
verboseHelp
));
addSubcommand
(
BuildAotCommand
(
verboseHelp:
verboseHelp
));
addSubcommand
(
BuildIOSCommand
());
addSubcommand
(
BuildIOSFrameworkCommand
());
addSubcommand
(
BuildBundleCommand
(
verboseHelp:
verboseHelp
));
addSubcommand
(
BuildWebCommand
());
addSubcommand
(
BuildMacosCommand
(
verboseHelp:
verboseHelp
));
...
...
packages/flutter_tools/lib/src/commands/build_aar.dart
View file @
d2e87a5d
...
...
@@ -36,13 +36,13 @@ class BuildAarCommand extends BuildSubCommand {
@override
Future
<
Map
<
CustomDimensions
,
String
>>
get
usageValues
async
{
final
Map
<
CustomDimensions
,
String
>
usage
=
<
CustomDimensions
,
String
>{};
final
FlutterProject
futterProject
=
_getProject
();
if
(
futterProject
==
null
)
{
final
FlutterProject
f
l
utterProject
=
_getProject
();
if
(
f
l
utterProject
==
null
)
{
return
usage
;
}
if
(
futterProject
.
manifest
.
isModule
)
{
if
(
f
l
utterProject
.
manifest
.
isModule
)
{
usage
[
CustomDimensions
.
commandBuildAarProjectType
]
=
'module'
;
}
else
if
(
futterProject
.
manifest
.
isPlugin
)
{
}
else
if
(
f
l
utterProject
.
manifest
.
isPlugin
)
{
usage
[
CustomDimensions
.
commandBuildAarProjectType
]
=
'plugin'
;
}
else
{
usage
[
CustomDimensions
.
commandBuildAarProjectType
]
=
'app'
;
...
...
packages/flutter_tools/lib/src/commands/build_aot.dart
View file @
d2e87a5d
This diff is collapsed.
Click to expand it.
packages/flutter_tools/lib/src/commands/build_ios.dart
View file @
d2e87a5d
...
...
@@ -6,6 +6,7 @@ import 'dart:async';
import
'../application_package.dart'
;
import
'../base/common.dart'
;
import
'../base/platform.dart'
;
import
'../base/utils.dart'
;
import
'../build_info.dart'
;
import
'../globals.dart'
;
...
...
@@ -13,6 +14,9 @@ import '../ios/mac.dart';
import
'../runner/flutter_command.dart'
show
DevelopmentArtifact
,
FlutterCommandResult
;
import
'build.dart'
;
/// Builds an .app for an iOS app to be used for local testing on an iOS device
/// or simulator. Can only be run on a macOS host. For producing deployment
/// .ipas, see https://flutter.dev/docs/deployment/ios.
class
BuildIOSCommand
extends
BuildSubCommand
{
BuildIOSCommand
()
{
usesTargetOption
();
...
...
@@ -59,7 +63,7 @@ class BuildIOSCommand extends BuildSubCommand {
final
bool
forSimulator
=
argResults
[
'simulator'
];
defaultBuildMode
=
forSimulator
?
BuildMode
.
debug
:
BuildMode
.
release
;
if
(
getCurrentHostPlatform
()
!=
HostPlatform
.
darwin_x64
)
{
if
(
!
platform
.
isMacOS
)
{
throwToolExit
(
'Building for iOS is only supported on the Mac.'
);
}
...
...
packages/flutter_tools/lib/src/commands/build_ios_framework.dart
0 → 100644
View file @
d2e87a5d
This diff is collapsed.
Click to expand it.
packages/flutter_tools/lib/src/ios/bitcode.dart
0 → 100644
View file @
d2e87a5d
// Copyright 2019 The Chromium 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
'../artifacts.dart'
;
import
'../base/common.dart'
;
import
'../base/context.dart'
;
import
'../base/file_system.dart'
;
import
'../base/process.dart'
;
import
'../base/version.dart'
;
import
'../build_info.dart'
;
import
'../ios/plist_parser.dart'
;
import
'../macos/xcode.dart'
;
const
bool
kBitcodeEnabledDefault
=
false
;
Future
<
void
>
validateBitcode
(
BuildMode
buildMode
,
TargetPlatform
targetPlatform
)
async
{
final
Artifacts
artifacts
=
Artifacts
.
instance
;
final
String
flutterFrameworkPath
=
artifacts
.
getArtifactPath
(
Artifact
.
flutterFramework
,
mode:
buildMode
,
platform:
targetPlatform
,
);
if
(!
fs
.
isDirectorySync
(
flutterFrameworkPath
))
{
throwToolExit
(
'Flutter.framework not found at
$flutterFrameworkPath
'
);
}
final
Xcode
xcode
=
context
.
get
<
Xcode
>();
final
RunResult
clangResult
=
await
xcode
.
clang
(<
String
>[
'--version'
]);
final
String
clangVersion
=
clangResult
.
stdout
.
split
(
'
\n
'
).
first
;
final
String
engineClangVersion
=
PlistParser
.
instance
.
getValueFromFile
(
fs
.
path
.
join
(
flutterFrameworkPath
,
'Info.plist'
),
'ClangVersion'
,
);
final
Version
engineClangSemVer
=
_parseVersionFromClang
(
engineClangVersion
);
final
Version
clangSemVer
=
_parseVersionFromClang
(
clangVersion
);
if
(
engineClangSemVer
>
clangSemVer
)
{
throwToolExit
(
'The Flutter.framework at
$flutterFrameworkPath
was built '
'with "
${engineClangVersion ?? 'unknown'}
", but the current version '
'of clang is "
$clangVersion
". This will result in failures when trying to'
'archive an IPA. To resolve this issue, update your version of Xcode to '
'at least
$engineClangSemVer
.'
,
);
}
}
Version
_parseVersionFromClang
(
String
clangVersion
)
{
final
RegExp
pattern
=
RegExp
(
r'Apple (LLVM|clang) version (\d+\.\d+\.\d+) '
);
void
_invalid
()
{
throwToolExit
(
'Unable to parse Clang version from "
$clangVersion
". '
'Expected a string like "Apple (LLVM|clang) #.#.# (clang-####.#.##.#)".'
);
}
if
(
clangVersion
==
null
||
clangVersion
.
isEmpty
)
{
_invalid
();
}
final
RegExpMatch
match
=
pattern
.
firstMatch
(
clangVersion
);
if
(
match
==
null
||
match
.
groupCount
!=
2
)
{
_invalid
();
}
final
Version
version
=
Version
.
parse
(
match
.
group
(
2
));
if
(
version
==
null
)
{
_invalid
();
}
return
version
;
}
packages/flutter_tools/test/general.shard/commands/build_aot_test.dart
View file @
d2e87a5d
...
...
@@ -7,8 +7,8 @@ import 'package:flutter_tools/src/artifacts.dart';
import
'package:flutter_tools/src/base/logger.dart'
;
import
'package:flutter_tools/src/base/process.dart'
;
import
'package:flutter_tools/src/build_info.dart'
;
import
'package:flutter_tools/src/commands/build_aot.dart'
;
import
'package:flutter_tools/src/base/file_system.dart'
;
import
'package:flutter_tools/src/ios/bitcode.dart'
;
import
'package:flutter_tools/src/ios/plist_parser.dart'
;
import
'package:flutter_tools/src/macos/xcode.dart'
;
import
'package:mockito/mockito.dart'
;
...
...
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