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
01feddbe
Unverified
Commit
01feddbe
authored
Aug 15, 2019
by
Jonah Williams
Committed by
GitHub
Aug 15, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Support for macOS release mode (1 of 3) (#37425)
parent
57f1508b
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
282 additions
and
244 deletions
+282
-244
macos_build_flutter_assets.sh
packages/flutter_tools/bin/macos_build_flutter_assets.sh
+18
-23
build_system.dart
...ages/flutter_tools/lib/src/build_system/build_system.dart
+9
-6
dart.dart
...ages/flutter_tools/lib/src/build_system/targets/dart.dart
+1
-0
macos.dart
...ges/flutter_tools/lib/src/build_system/targets/macos.dart
+170
-85
assemble.dart
packages/flutter_tools/lib/src/commands/assemble.dart
+2
-3
desktop.dart
packages/flutter_tools/lib/src/desktop.dart
+3
-0
application_package.dart
...ages/flutter_tools/lib/src/macos/application_package.dart
+1
-1
build_macos.dart
packages/flutter_tools/lib/src/macos/build_macos.dart
+7
-0
macos_test.dart
...s/test/general.shard/build_system/targets/macos_test.dart
+70
-125
assemble_test.dart
...tter_tools/test/general.shard/commands/assemble_test.dart
+1
-1
No files found.
packages/flutter_tools/bin/macos_build_flutter_assets.sh
View file @
01feddbe
...
...
@@ -33,18 +33,6 @@ if [[ -n "$FLUTTER_TARGET" ]]; then
target_path
=
"
${
FLUTTER_TARGET
}
"
fi
# Set the track widget creation flag.
track_widget_creation_flag
=
""
if
[[
-n
"
$TRACK_WIDGET_CREATION
"
]]
;
then
track_widget_creation_flag
=
"--track-widget-creation"
fi
# Copy the framework and handle local engine builds.
framework_name
=
"FlutterMacOS.framework"
ephemeral_dir
=
"
${
SOURCE_ROOT
}
/Flutter/ephemeral"
framework_path
=
"
${
FLUTTER_ROOT
}
/bin/cache/artifacts/engine/darwin-x64"
flutter_framework
=
"
${
framework_path
}
/
${
framework_name
}
"
if
[[
-n
"
$FLUTTER_ENGINE
"
]]
;
then
flutter_engine_flag
=
"--local-engine-src-path=
${
FLUTTER_ENGINE
}
"
fi
...
...
@@ -63,22 +51,29 @@ if [[ -n "$LOCAL_ENGINE" ]]; then
exit
-1
fi
local_engine_flag
=
"--local-engine=
${
LOCAL_ENGINE
}
"
flutter_framework
=
"
${
FLUTTER_ENGINE
}
/out/
${
LOCAL_ENGINE
}
/
${
framework_name
}
"
fi
RunCommand
mkdir
-p
--
"
$ephemeral_dir
"
RunCommand
rm
-rf
--
"
${
ephemeral_dir
}
/
${
framework_name
}
"
RunCommand
cp
-Rp
--
"
${
flutter_framework
}
"
"
${
ephemeral_dir
}
"
# Set the build mode
build_mode
=
"
$(
echo
"
${
FLUTTER_BUILD_MODE
:-${
CONFIGURATION
}}
"
|
tr
"[:upper:]"
"[:lower:]"
)
"
# The path where the input/output xcfilelists are stored. These are used by xcode
# to conditionally skip this script phase if neither have changed.
ephemeral_dir
=
"
${
SOURCE_ROOT
}
/Flutter/ephemeral"
build_inputs_path
=
"
${
ephemeral_dir
}
/FlutterInputs.xcfilelist"
build_outputs_path
=
"
${
ephemeral_dir
}
/FlutterOutputs.xcfilelist"
# TODO(jonahwilliams): connect AOT rules once engine artifacts are published.
# The build mode is currently hard-coded to debug only. Since this does not yet
# support AOT, we need to ensure that we compile the kernel file in debug so that
# the VM can load it.
RunCommand
"
${
FLUTTER_ROOT
}
/bin/flutter"
--suppress-analytics
\
${
verbose_flag
}
\
build bundle
\
--target-platform
=
darwin-x64
\
--target
=
"
${
target_path
}
"
\
--
${
build_mode
}
\
${
track_widget_creation_flag
}
\
${
flutter_engine_flag
}
\
${
local_engine_flag
}
${
local_engine_flag
}
\
assemble
\
-dTargetPlatform
=
darwin-x64
\
-dTargetFile
=
"
${
target_path
}
"
\
-dBuildMode
=
debug
\
--build-inputs
=
"
${
build_inputs_path
}
"
\
--build-outputs
=
"
${
build_outputs_path
}
"
\
debug_bundle_flutter_assets
packages/flutter_tools/lib/src/build_system/build_system.dart
View file @
01feddbe
...
...
@@ -485,16 +485,18 @@ class BuildSystem {
// timestamps to track files, this leads to unecessary rebuilds if they
// are included. Once all the places that write these files have been
// tracked down and moved into assemble, these checks should be removable.
// We also remove files under .dart_tool, since these are intermediaries
// and don't need to be tracked by external systems.
{
buildInstance
.
inputFiles
.
removeWhere
((
String
path
,
File
file
)
{
return
path
.
contains
(
'
pubspec.yaml
'
)
||
path
.
contains
(
'.flutter-plugins
'
)
||
path
.
contains
(
'xcconfig
'
);
return
path
.
contains
(
'
.flutter-plugins
'
)
||
path
.
contains
(
'xcconfig
'
)
||
path
.
contains
(
'.dart_tool
'
);
});
buildInstance
.
outputFiles
.
removeWhere
((
String
path
,
File
file
)
{
return
path
.
contains
(
'
pubspec.yaml
'
)
||
path
.
contains
(
'.flutter-plugins
'
)
||
path
.
contains
(
'xcconfig
'
);
return
path
.
contains
(
'
.flutter-plugins
'
)
||
path
.
contains
(
'xcconfig
'
)
||
path
.
contains
(
'.dart_tool
'
);
});
}
return
BuildResult
(
...
...
@@ -509,6 +511,7 @@ class BuildSystem {
}
}
/// An active instance of a build.
class
_BuildInstance
{
_BuildInstance
(
this
.
environment
,
this
.
fileCache
,
this
.
buildSystemConfig
)
...
...
packages/flutter_tools/lib/src/build_system/targets/dart.dart
View file @
01feddbe
...
...
@@ -64,6 +64,7 @@ class KernelSnapshot extends Target {
@override
List
<
Source
>
get
inputs
=>
const
<
Source
>[
Source
.
pattern
(
'{PROJECT_DIR}/.packages'
),
Source
.
pattern
(
'{FLUTTER_ROOT}/packages/flutter_tools/lib/src/build_system/targets/dart.dart'
),
Source
.
function
(
listDartSources
),
// <- every dart file under {PROJECT_DIR}/lib and in .packages
Source
.
artifact
(
Artifact
.
platformKernelDill
),
...
...
packages/flutter_tools/lib/src/build_system/targets/macos.dart
View file @
01feddbe
...
...
@@ -2,21 +2,65 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'package:pool/pool.dart'
;
import
'../../artifacts.dart'
;
import
'../../asset.dart'
;
import
'../../base/file_system.dart'
;
import
'../../base/io.dart'
;
import
'../../base/process.dart'
;
import
'../../base/process_manager.dart'
;
import
'../../build_info.dart'
;
import
'../../devfs.dart'
;
import
'../../globals.dart'
;
import
'../../macos/
cocoapods
.dart'
;
import
'../../macos/
xcode
.dart'
;
import
'../../project.dart'
;
import
'../build_system.dart'
;
import
'../exceptions.dart'
;
import
'assets.dart'
;
import
'dart.dart'
;
const
String
_kOutputPrefix
=
'{PROJECT_DIR}/macos/Flutter/ephemeral/FlutterMacOS.framework'
;
/// The copying logic for flutter assets in macOS.
// TODO(jonahwilliams): remove once build planning lands.
class
MacOSAssetBehavior
extends
SourceBehavior
{
const
MacOSAssetBehavior
();
@override
List
<
File
>
inputs
(
Environment
environment
)
{
final
AssetBundle
assetBundle
=
AssetBundleFactory
.
instance
.
createBundle
();
assetBundle
.
build
(
manifestPath:
environment
.
projectDir
.
childFile
(
'pubspec.yaml'
).
path
,
packagesPath:
environment
.
projectDir
.
childFile
(
'.packages'
).
path
,
);
// Filter the file type to remove the files that are generated by this
// command as inputs.
final
List
<
File
>
results
=
<
File
>[];
final
Iterable
<
DevFSFileContent
>
files
=
assetBundle
.
entries
.
values
.
whereType
<
DevFSFileContent
>();
for
(
DevFSFileContent
devFsContent
in
files
)
{
results
.
add
(
fs
.
file
(
devFsContent
.
file
.
path
));
}
return
results
;
}
@override
List
<
File
>
outputs
(
Environment
environment
)
{
final
AssetBundle
assetBundle
=
AssetBundleFactory
.
instance
.
createBundle
();
assetBundle
.
build
(
manifestPath:
environment
.
projectDir
.
childFile
(
'pubspec.yaml'
).
path
,
packagesPath:
environment
.
projectDir
.
childFile
(
'.packages'
).
path
,
);
final
FlutterProject
flutterProject
=
FlutterProject
.
fromDirectory
(
environment
.
projectDir
);
final
String
prefix
=
fs
.
path
.
join
(
flutterProject
.
macos
.
ephemeralDirectory
.
path
,
'App.framework'
,
'flutter_assets'
);
final
List
<
File
>
results
=
<
File
>[];
for
(
String
key
in
assetBundle
.
entries
.
keys
)
{
final
File
file
=
fs
.
file
(
fs
.
path
.
join
(
prefix
,
key
));
results
.
add
(
file
);
}
return
results
;
}
}
/// Copy the macOS framework to the correct copy dir by invoking 'cp -R'.
///
/// The shelling out is done to avoid complications with preserving special
...
...
@@ -41,18 +85,21 @@ class UnpackMacOS extends Target {
List
<
Source
>
get
outputs
=>
const
<
Source
>[
Source
.
pattern
(
'
$_kOutputPrefix
/FlutterMacOS'
),
// Headers
Source
.
pattern
(
'
$_kOutputPrefix
/Headers/FLEViewController.h'
),
Source
.
pattern
(
'
$_kOutputPrefix
/Headers/FlutterDartProject.h'
),
Source
.
pattern
(
'
$_kOutputPrefix
/Headers/FlutterEngine.h'
),
Source
.
pattern
(
'
$_kOutputPrefix
/Headers/FlutterViewController.h'
),
Source
.
pattern
(
'
$_kOutputPrefix
/Headers/FlutterBinaryMessenger.h'
),
Source
.
pattern
(
'
$_kOutputPrefix
/Headers/FlutterChannels.h'
),
Source
.
pattern
(
'
$_kOutputPrefix
/Headers/FlutterCodecs.h'
),
Source
.
pattern
(
'
$_kOutputPrefix
/Headers/FlutterMac
OS
.h'
),
Source
.
pattern
(
'
$_kOutputPrefix
/Headers/FlutterMac
ros
.h'
),
Source
.
pattern
(
'
$_kOutputPrefix
/Headers/FlutterPluginMacOS.h'
),
Source
.
pattern
(
'
$_kOutputPrefix
/Headers/FlutterPluginRegistrarMacOS.h'
),
Source
.
pattern
(
'
$_kOutputPrefix
/Headers/FlutterMacOS.h'
),
// Modules
Source
.
pattern
(
'
$_kOutputPrefix
/Modules/module.modulemap'
),
// Resources
Source
.
pattern
(
'
$_kOutputPrefix
/Resources/icudtl.dat'
),
Source
.
pattern
(
'
$_kOutputPrefix
/Resources/
i
nfo.plist'
),
Source
.
pattern
(
'
$_kOutputPrefix
/Resources/
I
nfo.plist'
),
// Ignore Versions folder for now
];
...
...
@@ -62,11 +109,9 @@ class UnpackMacOS extends Target {
@override
Future
<
void
>
build
(
List
<
File
>
inputFiles
,
Environment
environment
)
async
{
final
String
basePath
=
artifacts
.
getArtifactPath
(
Artifact
.
flutterMacOSFramework
);
final
Directory
targetDirectory
=
environment
.
projectDir
.
childDirectory
(
'macos'
)
.
childDirectory
(
'Flutter'
)
.
childDirectory
(
'ephemeral'
)
final
FlutterProject
flutterProject
=
FlutterProject
.
fromDirectory
(
environment
.
projectDir
);
final
Directory
targetDirectory
=
flutterProject
.
macos
.
ephemeralDirectory
.
childDirectory
(
'FlutterMacOS.framework'
);
if
(
targetDirectory
.
existsSync
())
{
targetDirectory
.
deleteSync
(
recursive:
true
);
...
...
@@ -83,111 +128,151 @@ class UnpackMacOS extends Target {
}
}
/// Tell cocoapods to re-fetch dependencies.
class
DebugMacOSPodInstall
extends
Target
{
const
DebugMacOSPodInstall
();
/// Create an App.framework for debug macOS 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.
class
DebugMacOSFramework
extends
Target
{
const
DebugMacOSFramework
();
@override
String
get
name
=>
'debug_macos_framework'
;
@override
Future
<
void
>
build
(
List
<
File
>
inputFiles
,
Environment
environment
)
async
{
final
FlutterProject
flutterProject
=
FlutterProject
.
fromDirectory
(
environment
.
projectDir
);
final
File
outputFile
=
fs
.
file
(
fs
.
path
.
join
(
flutterProject
.
macos
.
ephemeralDirectory
.
path
,
'App.framework'
,
'App'
));
outputFile
.
createSync
(
recursive:
true
);
final
File
debugApp
=
environment
.
buildDir
.
childFile
(
'debug_app.cc'
)
..
writeAsStringSync
(
r''
'
static const int Moo = 88;
'''
);
final
RunResult
result
=
await
xcode
.
clang
(<
String
>[
'-x'
,
'c'
,
debugApp
.
path
,
'-arch'
,
'x86_64'
,
'-dynamiclib'
,
'-Xlinker'
,
'-rpath'
,
'-Xlinker'
,
'@executable_path/Frameworks'
,
'-Xlinker'
,
'-rpath'
,
'-Xlinker'
,
'@loader_path/Frameworks'
,
'-install_name'
,
'@rpath/App.framework/App'
,
'-o'
,
'macos/Flutter/ephemeral/App.framework/App'
,
]);
if
(
result
.
exitCode
!=
0
)
{
throw
Exception
(
'Failed to compile debug App.framework'
);
}
}
@override
String
get
name
=>
'debug_macos_pod_install'
;
List
<
Target
>
get
dependencies
=>
const
<
Target
>[]
;
@override
List
<
Source
>
get
inputs
=>
const
<
Source
>[
Source
.
artifact
(
Artifact
.
flutterMacOSPodspec
,
platform:
TargetPlatform
.
darwin_x64
,
mode:
BuildMode
.
debug
),
Source
.
pattern
(
'{PROJECT_DIR}/macos/Podfile'
,
optional:
true
),
Source
.
pattern
(
'{PROJECT_DIR}/macos/Runner.xcodeproj/project.pbxproj'
),
Source
.
pattern
(
'{PROJECT_DIR}/macos/Flutter/ephemeral/Flutter-Generated.xcconfig'
),
Source
.
pattern
(
'{FLUTTER_ROOT}/packages/flutter_tools/lib/src/build_system/targets/macos.dart'
),
];
@override
List
<
Source
>
get
outputs
=>
const
<
Source
>[
// TODO(jonahwilliams): introduce configuration/planning phase to build.
// No outputs because Cocoapods is fully responsible for tracking. plus there
// is no concept of an optional output. Instead we will need a build config
// phase to conditionally add this rule so that it can be written properly.
Source
.
pattern
(
'{PROJECT_DIR}/macos/Flutter/ephemeral/App.framework/App'
),
];
}
/// Bundle the flutter assets, app.dill, and precompiled runtimes into the App.framework.
class
DebugBundleFlutterAssets
extends
Target
{
const
DebugBundleFlutterAssets
();
@override
List
<
Target
>
get
dependencies
=>
const
<
Target
>[
UnpackMacOS
(),
FlutterPlugins
(),
];
String
get
name
=>
'debug_bundle_flutter_assets'
;
@override
Future
<
void
>
build
(
List
<
File
>
inputFiles
,
Environment
environment
)
async
{
if
(
environment
.
defines
[
kBuildMode
]
==
null
)
{
throw
MissingDefineException
(
kBuildMode
,
'debug_macos_pod_install'
);
final
FlutterProject
flutterProject
=
FlutterProject
.
fromDirectory
(
environment
.
projectDir
);
final
Directory
outputDirectory
=
flutterProject
.
macos
.
ephemeralDirectory
.
childDirectory
(
'App.framework'
);
if
(!
outputDirectory
.
existsSync
())
{
throw
Exception
(
'App.framework must exist to bundle assets.'
);
}
// If there is no podfile do not perform any pods actions.
if
(!
environment
.
projectDir
.
childDirectory
(
'macos'
)
.
childFile
(
'Podfile'
).
existsSync
())
{
return
;
// Copy assets into asset directory.
final
Directory
assetDirectory
=
outputDirectory
.
childDirectory
(
'flutter_assets'
);
// We're not smart enough to only remove assets that are removed. If
// anything changes blow away the whole directory.
if
(
assetDirectory
.
existsSync
())
{
assetDirectory
.
deleteSync
(
recursive:
true
);
}
final
BuildMode
buildMode
=
getBuildModeForName
(
environment
.
defines
[
kBuildMode
]);
final
FlutterProject
project
=
FlutterProject
.
fromDirectory
(
environment
.
projectDir
);
final
String
enginePath
=
artifacts
.
getArtifactPath
(
Artifact
.
flutterMacOSPodspec
,
mode:
buildMode
,
platform:
TargetPlatform
.
darwin_x64
);
await
cocoaPods
.
processPods
(
xcodeProject:
project
.
macos
,
engineDir:
enginePath
,
isSwift:
true
,
dependenciesChanged:
true
,
assetDirectory
.
createSync
();
final
AssetBundle
assetBundle
=
AssetBundleFactory
.
instance
.
createBundle
();
final
int
result
=
await
assetBundle
.
build
(
manifestPath:
environment
.
projectDir
.
childFile
(
'pubspec.yaml'
).
path
,
packagesPath:
environment
.
projectDir
.
childFile
(
'.packages'
).
path
,
);
}
}
/// Build all of the artifacts for a debug macOS application.
class
DebugMacOSApplication
extends
Target
{
const
DebugMacOSApplication
();
@override
Future
<
void
>
build
(
List
<
File
>
inputFiles
,
Environment
environment
)
async
{
final
File
sourceFile
=
environment
.
buildDir
.
childFile
(
'app.dill'
);
final
File
destinationFile
=
environment
.
buildDir
.
childDirectory
(
'flutter_assets'
)
.
childFile
(
'kernel_blob.bin'
);
if
(!
destinationFile
.
parent
.
existsSync
())
{
destinationFile
.
parent
.
createSync
(
recursive:
true
);
if
(
result
!=
0
)
{
throw
Exception
(
'Failed to create asset bundle:
$result
'
);
}
// Limit number of open files to avoid running out of file descriptors.
try
{
final
Pool
pool
=
Pool
(
64
);
await
Future
.
wait
<
void
>(
assetBundle
.
entries
.
entries
.
map
<
Future
<
void
>>((
MapEntry
<
String
,
DevFSContent
>
entry
)
async
{
final
PoolResource
resource
=
await
pool
.
request
();
try
{
final
File
file
=
fs
.
file
(
fs
.
path
.
join
(
assetDirectory
.
path
,
entry
.
key
));
file
.
parent
.
createSync
(
recursive:
true
);
await
file
.
writeAsBytes
(
await
entry
.
value
.
contentsAsBytes
());
}
finally
{
resource
.
release
();
}
}));
}
catch
(
err
,
st
){
throw
Exception
(
'Failed to copy assets:
$st
'
);
}
// Copy dill file.
try
{
final
File
sourceFile
=
environment
.
buildDir
.
childFile
(
'app.dill'
);
sourceFile
.
copySync
(
assetDirectory
.
childFile
(
'kernel_blob.bin'
).
path
);
}
catch
(
err
)
{
throw
Exception
(
'Failed to copy app.dill:
$err
'
);
}
// Copy precompiled runtimes.
try
{
final
String
vmSnapshotData
=
artifacts
.
getArtifactPath
(
Artifact
.
vmSnapshotData
,
platform:
TargetPlatform
.
darwin_x64
,
mode:
BuildMode
.
debug
);
final
String
isolateSnapshotData
=
artifacts
.
getArtifactPath
(
Artifact
.
isolateSnapshotData
,
platform:
TargetPlatform
.
darwin_x64
,
mode:
BuildMode
.
debug
);
fs
.
file
(
vmSnapshotData
).
copySync
(
assetDirectory
.
childFile
(
'vm_snapshot_data'
).
path
);
fs
.
file
(
isolateSnapshotData
).
copySync
(
assetDirectory
.
childFile
(
'isolate_snapshot_data'
).
path
);
}
catch
(
err
)
{
throw
Exception
(
'Failed to copy precompiled runtimes:
$err
'
);
}
sourceFile
.
copySync
(
destinationFile
.
path
);
}
@override
List
<
Target
>
get
dependencies
=>
const
<
Target
>[
FlutterPlugins
(),
UnpackMacOS
(),
KernelSnapshot
(),
CopyAssets
(),
DebugMacOSPodInstall
(),
DebugMacOSFramework
(),
UnpackMacOS
(),
];
@override
List
<
Source
>
get
inputs
=>
const
<
Source
>[
Source
.
pattern
(
'{BUILD_DIR}/app.dill'
)
Source
.
pattern
(
'{PROJECT_DIR}/pubspec.yaml'
),
Source
.
behavior
(
MacOSAssetBehavior
()),
Source
.
pattern
(
'{BUILD_DIR}/app.dill'
),
Source
.
artifact
(
Artifact
.
isolateSnapshotData
,
platform:
TargetPlatform
.
darwin_x64
,
mode:
BuildMode
.
debug
),
Source
.
artifact
(
Artifact
.
vmSnapshotData
,
platform:
TargetPlatform
.
darwin_x64
,
mode:
BuildMode
.
debug
),
];
@override
String
get
name
=>
'debug_macos_application'
;
@override
List
<
Source
>
get
outputs
=>
const
<
Source
>[
Source
.
pattern
(
'{BUILD_DIR}/flutter_assets/kernel_blob.bin'
),
Source
.
behavior
(
MacOSAssetBehavior
()),
Source
.
pattern
(
'{PROJECT_DIR}/macos/Flutter/ephemeral/App.framework/flutter_assets/AssetManifest.json'
),
Source
.
pattern
(
'{PROJECT_DIR}/macos/Flutter/ephemeral/App.framework/flutter_assets/FontManifest.json'
),
Source
.
pattern
(
'{PROJECT_DIR}/macos/Flutter/ephemeral/App.framework/flutter_assets/LICENSE'
),
Source
.
pattern
(
'{PROJECT_DIR}/macos/Flutter/ephemeral/App.framework/flutter_assets/kernel_blob.bin'
),
Source
.
pattern
(
'{PROJECT_DIR}/macos/Flutter/ephemeral/App.framework/flutter_assets/vm_snapshot_data'
),
Source
.
pattern
(
'{PROJECT_DIR}/macos/Flutter/ephemeral/App.framework/flutter_assets/isolate_snapshot_data'
),
];
}
// TODO(jonahwilliams): real AOT implementation.
class
ReleaseMacOSApplication
extends
DebugMacOSApplication
{
const
ReleaseMacOSApplication
();
@override
String
get
name
=>
'release_macos_application'
;
}
class
ProfileMacOSApplication
extends
DebugMacOSApplication
{
const
ProfileMacOSApplication
();
@override
String
get
name
=>
'profile_macos_application'
;
}
packages/flutter_tools/lib/src/commands/assemble.dart
View file @
01feddbe
...
...
@@ -32,9 +32,8 @@ const List<Target> _kDefaultTargets = <Target>[
AotElfRelease
(),
AotAssemblyProfile
(),
AotAssemblyRelease
(),
DebugMacOSApplication
(),
ProfileMacOSApplication
(),
ReleaseMacOSApplication
(),
DebugMacOSFramework
(),
DebugBundleFlutterAssets
(),
];
/// Assemble provides a low level API to interact with the flutter tool build
...
...
packages/flutter_tools/lib/src/desktop.dart
View file @
01feddbe
...
...
@@ -11,6 +11,9 @@ import 'device.dart';
/// Kills a process on linux or macOS.
Future
<
bool
>
killProcess
(
String
executable
)
async
{
if
(
executable
==
null
)
{
return
false
;
}
final
RegExp
whitespace
=
RegExp
(
r'\s+'
);
bool
succeeded
=
true
;
try
{
...
...
packages/flutter_tools/lib/src/macos/application_package.dart
View file @
01feddbe
...
...
@@ -141,7 +141,7 @@ class BuildableMacOSApp extends MacOSApp {
return
null
;
}
final
_ExecutableAndId
executableAndId
=
MacOSApp
.
_executableFromBundle
(
fs
.
directory
(
directory
));
return
executableAndId
.
executable
;
return
executableAndId
?
.
executable
;
}
}
...
...
packages/flutter_tools/lib/src/macos/build_macos.dart
View file @
01feddbe
...
...
@@ -36,6 +36,13 @@ Future<void> buildMacOS({
setSymroot:
false
,
);
await
processPodsIfNeeded
(
flutterProject
.
macos
,
getMacOSBuildDirectory
(),
buildInfo
.
mode
);
// If the xcfilelists do not exist, create empty version.
if
(!
flutterProject
.
macos
.
inputFileList
.
existsSync
())
{
flutterProject
.
macos
.
inputFileList
.
createSync
(
recursive:
true
);
}
if
(!
flutterProject
.
macos
.
outputFileList
.
existsSync
())
{
flutterProject
.
macos
.
outputFileList
.
createSync
(
recursive:
true
);
}
// Set debug or release mode.
String
config
=
'Debug'
;
...
...
packages/flutter_tools/test/general.shard/build_system/targets/macos_test.dart
View file @
01feddbe
...
...
@@ -2,22 +2,48 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'package:flutter_tools/src/base/build.dart'
;
import
'package:flutter_tools/src/base/file_system.dart'
;
import
'package:flutter_tools/src/base/io.dart'
;
import
'package:flutter_tools/src/base/platform.dart'
;
import
'package:flutter_tools/src/base/process_manager.dart'
;
import
'package:flutter_tools/src/build_system/build_system.dart'
;
import
'package:flutter_tools/src/build_system/exceptions.dart'
;
import
'package:flutter_tools/src/build_system/targets/dart.dart'
;
import
'package:flutter_tools/src/build_system/targets/macos.dart'
;
import
'package:flutter_tools/src/cache.dart'
;
import
'package:flutter_tools/src/macos/cocoapods.dart'
;
import
'package:flutter_tools/src/macos/xcode.dart'
;
import
'package:mockito/mockito.dart'
;
import
'package:process/process.dart'
;
import
'../../../src/common.dart'
;
import
'../../../src/testbed.dart'
;
const
String
_kInputPrefix
=
'bin/cache/artifacts/engine/darwin-x64/FlutterMacOS.framework'
;
const
String
_kOutputPrefix
=
'macos/Flutter/ephemeral/FlutterMacOS.framework'
;
final
List
<
File
>
inputs
=
<
File
>[
fs
.
file
(
'
$_kInputPrefix
/FlutterMacOS'
),
// Headers
fs
.
file
(
'
$_kInputPrefix
/Headers/FlutterDartProject.h'
),
fs
.
file
(
'
$_kInputPrefix
/Headers/FlutterEngine.h'
),
fs
.
file
(
'
$_kInputPrefix
/Headers/FlutterViewController.h'
),
fs
.
file
(
'
$_kInputPrefix
/Headers/FlutterBinaryMessenger.h'
),
fs
.
file
(
'
$_kInputPrefix
/Headers/FlutterChannels.h'
),
fs
.
file
(
'
$_kInputPrefix
/Headers/FlutterCodecs.h'
),
fs
.
file
(
'
$_kInputPrefix
/Headers/FlutterMacros.h'
),
fs
.
file
(
'
$_kInputPrefix
/Headers/FlutterPluginMacOS.h'
),
fs
.
file
(
'
$_kInputPrefix
/Headers/FlutterPluginRegistrarMacOS.h'
),
fs
.
file
(
'
$_kInputPrefix
/Headers/FlutterMacOS.h'
),
// Modules
fs
.
file
(
'
$_kInputPrefix
/Modules/module.modulemap'
),
// Resources
fs
.
file
(
'
$_kInputPrefix
/Resources/icudtl.dat'
),
fs
.
file
(
'
$_kInputPrefix
/Resources/Info.plist'
),
// Ignore Versions folder for now
fs
.
file
(
'packages/flutter_tools/lib/src/build_system/targets/macos.dart'
),
];
void
main
(
)
{
Testbed
testbed
;
Environment
environment
;
...
...
@@ -37,44 +63,11 @@ void main() {
testbed
=
Testbed
(
setup:
()
{
environment
=
Environment
(
projectDir:
fs
.
currentDirectory
,
);
final
List
<
File
>
inputs
=
<
File
>[
fs
.
file
(
'bin/cache/artifacts/engine/darwin-x64/FlutterMacOS.framework/FlutterMacOS'
),
fs
.
file
(
'bin/cache/artifacts/engine/darwin-x64/FlutterMacOS.framework/Headers/FLEOpenGLContextHandling.h'
),
fs
.
file
(
'bin/cache/artifacts/engine/darwin-x64/FlutterMacOS.framework/Headers/FLEReshapeListener.h'
),
fs
.
file
(
'bin/cache/artifacts/engine/darwin-x64/FlutterMacOS.framework/Headers/FLEView.h'
),
fs
.
file
(
'bin/cache/artifacts/engine/darwin-x64/FlutterMacOS.framework/Headers/FLEViewController.h'
),
fs
.
file
(
'bin/cache/artifacts/engine/darwin-x64/FlutterMacOS.framework/Headers/FlutterBinaryMessenger.h'
),
fs
.
file
(
'bin/cache/artifacts/engine/darwin-x64/FlutterMacOS.framework/Headers/FlutterChannels.h'
),
fs
.
file
(
'bin/cache/artifacts/engine/darwin-x64/FlutterMacOS.framework/Headers/FlutterCodecs.h'
),
fs
.
file
(
'bin/cache/artifacts/engine/darwin-x64/FlutterMacOS.framework/Headers/FlutterMacOS.h'
),
fs
.
file
(
'bin/cache/artifacts/engine/darwin-x64/FlutterMacOS.framework/Headers/FlutterPluginMacOS.h'
),
fs
.
file
(
'bin/cache/artifacts/engine/darwin-x64/FlutterMacOS.framework/Headers/FlutterPluginRegisrarMacOS.h'
),
fs
.
file
(
'bin/cache/artifacts/engine/darwin-x64/FlutterMacOS.framework/Modules/module.modulemap'
),
fs
.
file
(
'bin/cache/artifacts/engine/darwin-x64/FlutterMacOS.framework/Resources/icudtl.dat'
),
fs
.
file
(
'bin/cache/artifacts/engine/darwin-x64/FlutterMacOS.framework/Resources/info.plist'
),
fs
.
file
(
'packages/flutter_tools/lib/src/build_system/targets/macos.dart'
),
];
for
(
File
input
in
inputs
)
{
input
.
createSync
(
recursive:
true
);
}
when
(
processManager
.
run
(
any
)).
thenAnswer
((
Invocation
invocation
)
async
{
final
List
<
String
>
arguments
=
invocation
.
positionalArguments
.
first
;
final
Directory
source
=
fs
.
directory
(
arguments
[
arguments
.
length
-
2
]);
final
Directory
target
=
fs
.
directory
(
arguments
.
last
)
..
createSync
(
recursive:
true
);
for
(
FileSystemEntity
entity
in
source
.
listSync
(
recursive:
true
))
{
if
(
entity
is
File
)
{
final
String
relative
=
fs
.
path
.
relative
(
entity
.
path
,
from:
source
.
path
);
final
String
destination
=
fs
.
path
.
join
(
target
.
path
,
relative
);
if
(!
fs
.
file
(
destination
).
parent
.
existsSync
())
{
fs
.
file
(
destination
).
parent
.
createSync
();
}
entity
.
copySync
(
destination
);
}
defines:
<
String
,
String
>{
kBuildMode:
'debug'
,
kTargetPlatform:
'darwin-x64'
,
}
return
FakeProcessResult
()..
exitCode
=
0
;
});
);
},
overrides:
<
Type
,
Generator
>{
ProcessManager:
()
=>
MockProcessManager
(),
Platform:
()
=>
mockPlatform
,
...
...
@@ -82,115 +75,69 @@ void main() {
});
test
(
'Copies files to correct cache directory'
,
()
=>
testbed
.
run
(()
async
{
for
(
File
input
in
inputs
)
{
input
.
createSync
(
recursive:
true
);
}
when
(
processManager
.
run
(
any
)).
thenAnswer
((
Invocation
invocation
)
async
{
final
List
<
String
>
arguments
=
invocation
.
positionalArguments
.
first
;
final
Directory
source
=
fs
.
directory
(
arguments
[
arguments
.
length
-
2
]);
final
Directory
target
=
fs
.
directory
(
arguments
.
last
)
..
createSync
(
recursive:
true
);
for
(
FileSystemEntity
entity
in
source
.
listSync
(
recursive:
true
))
{
if
(
entity
is
File
)
{
final
String
relative
=
fs
.
path
.
relative
(
entity
.
path
,
from:
source
.
path
);
final
String
destination
=
fs
.
path
.
join
(
target
.
path
,
relative
);
if
(!
fs
.
file
(
destination
).
parent
.
existsSync
())
{
fs
.
file
(
destination
).
parent
.
createSync
();
}
entity
.
copySync
(
destination
);
}
}
return
FakeProcessResult
()..
exitCode
=
0
;
});
await
const
UnpackMacOS
().
build
(<
File
>[],
environment
);
expect
(
fs
.
directory
(
'macos/Flutter/ephemeral/FlutterMacOS.framework'
).
existsSync
(),
true
);
expect
(
fs
.
file
(
'macos/Flutter/ephemeral/FlutterMacOS.framework/FlutterMacOS'
).
existsSync
(),
true
);
expect
(
fs
.
file
(
'macos/Flutter/ephemeral/FlutterMacOS.framework/Headers/FLEViewController.h'
).
existsSync
(),
true
);
expect
(
fs
.
file
(
'macos/Flutter/ephemeral/FlutterMacOS.framework/Headers/FlutterBinaryMessenger.h'
).
existsSync
(),
true
);
expect
(
fs
.
file
(
'macos/Flutter/ephemeral/FlutterMacOS.framework/Headers/FlutterChannels.h'
).
existsSync
(),
true
);
expect
(
fs
.
file
(
'macos/Flutter/ephemeral/FlutterMacOS.framework/Headers/FlutterCodecs.h'
).
existsSync
(),
true
);
expect
(
fs
.
file
(
'macos/Flutter/ephemeral/FlutterMacOS.framework/Headers/FlutterMacOS.h'
).
existsSync
(),
true
);
expect
(
fs
.
file
(
'macos/Flutter/ephemeral/FlutterMacOS.framework/Headers/FlutterPluginMacOS.h'
).
existsSync
(),
true
);
expect
(
fs
.
file
(
'macos/Flutter/ephemeral/FlutterMacOS.framework/Headers/FlutterPluginRegisrarMacOS.h'
).
existsSync
(),
true
);
expect
(
fs
.
file
(
'macos/Flutter/ephemeral/FlutterMacOS.framework/Modules/module.modulemap'
).
existsSync
(),
true
);
expect
(
fs
.
file
(
'macos/Flutter/ephemeral/FlutterMacOS.framework/Resources/icudtl.dat'
).
existsSync
(),
true
);
expect
(
fs
.
file
(
'macos/Flutter/ephemeral/FlutterMacOS.framework/Resources/info.plist'
).
existsSync
(),
true
);
expect
(
fs
.
directory
(
'
$_kOutputPrefix
'
).
existsSync
(),
true
);
for
(
File
file
in
inputs
)
{
expect
(
fs
.
file
(
file
.
path
.
replaceFirst
(
_kInputPrefix
,
_kOutputPrefix
)).
existsSync
(),
true
);
}
}));
test
(
'debug macOS application
copies kernel blob
'
,
()
=>
testbed
.
run
(()
async
{
test
(
'debug macOS application
fails if App.framework missing
'
,
()
=>
testbed
.
run
(()
async
{
final
String
inputKernel
=
fs
.
path
.
join
(
environment
.
buildDir
.
path
,
'app.dill'
);
final
String
outputKernel
=
fs
.
path
.
join
(
environment
.
buildDir
.
path
,
'flutter_assets'
,
'kernel_blob.bin'
);
fs
.
file
(
inputKernel
)
..
createSync
(
recursive:
true
)
..
writeAsStringSync
(
'testing'
);
await
const
DebugMacOSApplication
().
build
(<
File
>[],
environment
);
expect
(
fs
.
file
(
outputKernel
).
readAsStringSync
(),
'testing'
);
}));
test
(
'profile macOS application copies kernel blob'
,
()
=>
testbed
.
run
(()
async
{
final
String
inputKernel
=
fs
.
path
.
join
(
environment
.
buildDir
.
path
,
'app.dill'
);
final
String
outputKernel
=
fs
.
path
.
join
(
environment
.
buildDir
.
path
,
'flutter_assets'
,
'kernel_blob.bin'
);
fs
.
file
(
inputKernel
)
..
createSync
(
recursive:
true
)
..
writeAsStringSync
(
'testing'
);
await
const
ProfileMacOSApplication
().
build
(<
File
>[],
environment
);
expect
(
fs
.
file
(
outputKernel
).
readAsStringSync
(),
'testing'
);
expect
(()
async
=>
await
const
DebugBundleFlutterAssets
().
build
(<
File
>[],
environment
),
throwsA
(
isInstanceOf
<
Exception
>()));
}));
test
(
'release macOS application copies kernel blob'
,
()
=>
testbed
.
run
(()
async
{
test
(
'debug macOS application copies kernel blob'
,
()
=>
testbed
.
run
(()
async
{
fs
.
file
(
fs
.
path
.
join
(
'bin'
,
'cache'
,
'artifacts'
,
'engine'
,
'darwin-x64'
,
'vm_isolate_snapshot.bin'
)).
createSync
(
recursive:
true
);
fs
.
file
(
fs
.
path
.
join
(
'bin'
,
'cache'
,
'artifacts'
,
'engine'
,
'darwin-x64'
,
'isolate_snapshot.bin'
)).
createSync
(
recursive:
true
);
final
String
frameworkPath
=
fs
.
path
.
join
(
environment
.
projectDir
.
path
,
'macos'
,
'Flutter'
,
'ephemeral'
,
'App.framework'
);
final
String
inputKernel
=
fs
.
path
.
join
(
environment
.
buildDir
.
path
,
'app.dill'
);
final
String
outputKernel
=
fs
.
path
.
join
(
environment
.
buildDir
.
path
,
'flutter_assets'
,
'kernel_blob.bin'
);
fs
.
directory
(
frameworkPath
).
createSync
(
recursive:
true
);
final
String
outputKernel
=
fs
.
path
.
join
(
frameworkPath
,
'flutter_assets'
,
'kernel_blob.bin'
);
fs
.
file
(
inputKernel
)
..
createSync
(
recursive:
true
)
..
writeAsStringSync
(
'testing'
);
await
const
ReleaseMacOSApplication
().
build
(<
File
>[],
environment
);
await
const
DebugBundleFlutterAssets
().
build
(<
File
>[],
environment
);
expect
(
fs
.
file
(
outputKernel
).
readAsStringSync
(),
'testing'
);
}));
// Changing target names will require a corresponding update in flutter_tools/bin/macos_build_flutter_assets.sh.
test
(
'Target names match those expected by bin scripts'
,
()
=>
testbed
.
run
(()
async
{
expect
(
const
DebugMacOSApplication
().
name
,
'debug_macos_application'
);
expect
(
const
ProfileMacOSApplication
().
name
,
'profile_macos_application'
);
expect
(
const
ReleaseMacOSApplication
().
name
,
'release_macos_application'
);
}));
test
(
'DebugMacOSPodInstall throws if missing build mode'
,
()
=>
testbed
.
run
(()
async
{
expect
(()
=>
const
DebugMacOSPodInstall
().
build
(<
File
>[],
environment
),
throwsA
(
isInstanceOf
<
MissingDefineException
>()));
}));
test
(
'DebugMacOSPodInstall skips if podfile does not exist'
,
()
=>
testbed
.
run
(()
async
{
await
const
DebugMacOSPodInstall
().
build
(<
File
>[],
Environment
(
projectDir:
fs
.
currentDirectory
,
defines:
<
String
,
String
>{
kBuildMode:
'debug'
}
));
verifyNever
(
cocoaPods
.
processPods
(
xcodeProject:
anyNamed
(
'xcodeProject'
),
engineDir:
anyNamed
(
'engineDir'
),
isSwift:
true
,
dependenciesChanged:
true
));
},
overrides:
<
Type
,
Generator
>{
CocoaPods:
()
=>
MockCocoaPods
(),
}));
test
(
'DebugMacOSPodInstall invokes processPods with podfile'
,
()
=>
testbed
.
run
(()
async
{
fs
.
file
(
fs
.
path
.
join
(
'macos'
,
'Podfile'
)).
createSync
(
recursive:
true
);
await
const
DebugMacOSPodInstall
().
build
(<
File
>[],
Environment
(
projectDir:
fs
.
currentDirectory
,
defines:
<
String
,
String
>{
kBuildMode:
'debug'
}
));
verify
(
cocoaPods
.
processPods
(
xcodeProject:
anyNamed
(
'xcodeProject'
),
engineDir:
anyNamed
(
'engineDir'
),
isSwift:
true
,
dependenciesChanged:
true
)).
called
(
1
);
},
overrides:
<
Type
,
Generator
>{
CocoaPods:
()
=>
MockCocoaPods
(),
}));
test
(
'b'
,
()
=>
testbed
.
run
(()
async
{
}));
}
class
MockPlatform
extends
Mock
implements
Platform
{}
class
MockCocoaPods
extends
Mock
implements
CocoaPods
{}
class
MockProcessManager
extends
Mock
implements
ProcessManager
{}
class
MockGenSnapshot
extends
Mock
implements
GenSnapshot
{}
class
MockXCode
extends
Mock
implements
Xcode
{}
class
FakeProcessResult
implements
ProcessResult
{
@override
int
exitCode
;
...
...
@@ -204,5 +151,3 @@ class FakeProcessResult implements ProcessResult {
@override
String
stdout
=
''
;
}
packages/flutter_tools/test/general.shard/commands/assemble_test.dart
View file @
01feddbe
...
...
@@ -73,7 +73,7 @@ void main() {
return
BuildResult
(
success:
true
,
inputFiles:
<
File
>[
fs
.
file
(
'foo'
),
fs
.
file
(
'fizz'
)..
createSync
()],
outputFiles:
<
File
>[
fs
.
file
(
'bar'
)]);
outputFiles:
<
File
>[
fs
.
file
(
'bar'
)
,
fs
.
file
(
fs
.
path
.
join
(
'.dart_tool'
,
'fizz2'
))..
createSync
(
recursive:
true
)
]);
});
await
commandRunner
.
run
(<
String
>[
'assemble'
,
'--build-outputs=outputs'
,
'--build-inputs=inputs'
,
'unpack_macos'
]);
...
...
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