Build configuration and toolchain updates for iOS and Mac targets
This commit is contained in:
@@ -386,14 +386,16 @@ config("default_libs") {
|
||||
"Foundation.framework",
|
||||
"IOKit.framework",
|
||||
"Security.framework",
|
||||
"OpenGL.framework",
|
||||
]
|
||||
} else if (is_ios) {
|
||||
# The libraries listed here will be specified for both the target and the
|
||||
# host. Only the common ones should be listed here.
|
||||
libs = [
|
||||
"CoreFoundation.framework",
|
||||
"CoreGraphics.framework",
|
||||
"CoreText.framework",
|
||||
"Foundation.framework",
|
||||
"UIKit.framework",
|
||||
]
|
||||
} else if (is_linux) {
|
||||
libs = [ "dl" ]
|
||||
|
||||
@@ -579,7 +579,7 @@ if (is_win) {
|
||||
set_default_toolchain(host_toolchain)
|
||||
} else if (is_ios) {
|
||||
host_toolchain = "//build/toolchain/mac:clang_x64"
|
||||
set_default_toolchain("//build/toolchain/mac:clang_$current_cpu")
|
||||
set_default_toolchain("//build/toolchain/mac:ios_clang_arm")
|
||||
} else if (is_nacl) {
|
||||
# TODO(GYP): This will need to change when we get NaCl working
|
||||
# on multiple platforms, but this whole block of code (how we define
|
||||
|
||||
@@ -260,7 +260,7 @@ config("compiler") {
|
||||
} else if (current_cpu == "arm") {
|
||||
common_mac_flags += [
|
||||
"-arch",
|
||||
"armv7",
|
||||
"arm64",
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@@ -6,17 +6,4 @@ import("//build/config/sysroot.gni")
|
||||
import("//build/config/ios/ios_sdk.gni")
|
||||
|
||||
config("sdk") {
|
||||
common_flags = [
|
||||
"-isysroot",
|
||||
sysroot,
|
||||
]
|
||||
|
||||
if (use_ios_simulator) {
|
||||
common_flags += [ "-mios-simulator-version-min=$ios_deployment_target" ]
|
||||
} else {
|
||||
common_flags += [ "-miphoneos-version-min=$ios_deployment_target" ]
|
||||
}
|
||||
|
||||
cflags = common_flags
|
||||
ldflags = common_flags
|
||||
}
|
||||
|
||||
36
engine/src/flutter/build/config/ios/find_signing_identity.py
Normal file
36
engine/src/flutter/build/config/ios/find_signing_identity.py
Normal file
@@ -0,0 +1,36 @@
|
||||
#!/usr/bin/python
|
||||
# Copyright (c) 2015 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 subprocess
|
||||
import sys
|
||||
import re
|
||||
|
||||
def ListIdentities():
|
||||
return subprocess.check_output([
|
||||
'/usr/bin/env',
|
||||
'xcrun',
|
||||
'security',
|
||||
'find-identity',
|
||||
'-v',
|
||||
'-p',
|
||||
'codesigning',
|
||||
]).strip()
|
||||
|
||||
|
||||
def FindValidIdentity():
|
||||
lines = ListIdentities().splitlines()
|
||||
# Look for something like "2) XYZ "iPhone Developer: Name (ABC)""
|
||||
exp = re.compile('.*\) ([A-F|0-9]*)(.*)')
|
||||
for line in lines:
|
||||
res = exp.match(line)
|
||||
if res is None:
|
||||
continue
|
||||
if "iPhone Developer" in res.group(2):
|
||||
return res.group(1)
|
||||
return ""
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print FindValidIdentity()
|
||||
110
engine/src/flutter/build/config/ios/ios_app.py
Normal file
110
engine/src/flutter/build/config/ios/ios_app.py
Normal file
@@ -0,0 +1,110 @@
|
||||
#!/usr/bin/python
|
||||
# Copyright (c) 2015 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 argparse
|
||||
import os
|
||||
import errno
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
PLUTIL = [
|
||||
'/usr/bin/env',
|
||||
'xcrun',
|
||||
'plutil'
|
||||
]
|
||||
|
||||
|
||||
def ProcessInfoPlist(args):
|
||||
output_plist_file = os.path.abspath(os.path.join(args.output, 'Info.plist'))
|
||||
return subprocess.check_call( PLUTIL + [
|
||||
'-convert',
|
||||
'binary1',
|
||||
'-o',
|
||||
output_plist_file,
|
||||
'--',
|
||||
args.input,
|
||||
])
|
||||
|
||||
|
||||
def PerformCodeSigning(args):
|
||||
return subprocess.check_call([
|
||||
'/usr/bin/env',
|
||||
'xcrun',
|
||||
'codesign',
|
||||
'--entitlements',
|
||||
args.entitlements_path,
|
||||
'--sign',
|
||||
args.identity,
|
||||
'-f',
|
||||
args.application_path,
|
||||
])
|
||||
|
||||
|
||||
def MakeDirectories(path):
|
||||
try:
|
||||
os.makedirs(path)
|
||||
except OSError as exc:
|
||||
if exc.errno == errno.EEXIST and os.path.isdir(path):
|
||||
return 0
|
||||
else:
|
||||
return -1
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
def GenerateProjectStructure(args):
|
||||
application_path = os.path.join( args.dir, args.name + ".app" )
|
||||
return MakeDirectories( application_path )
|
||||
|
||||
|
||||
def Main():
|
||||
parser = argparse.ArgumentParser(description='A script that aids in '
|
||||
'the creation of an iOS application')
|
||||
|
||||
subparsers = parser.add_subparsers()
|
||||
|
||||
# Plist Parser
|
||||
|
||||
plist_parser = subparsers.add_parser('plist',
|
||||
help='Process the Info.plist')
|
||||
plist_parser.set_defaults(func=ProcessInfoPlist)
|
||||
|
||||
plist_parser.add_argument('-i', dest='input', help='The input plist path')
|
||||
plist_parser.add_argument('-o', dest='output', help='The output plist dir')
|
||||
|
||||
# Directory Structure Parser
|
||||
|
||||
dir_struct_parser = subparsers.add_parser('structure',
|
||||
help='Creates the directory of an iOS application')
|
||||
|
||||
dir_struct_parser.set_defaults(func=GenerateProjectStructure)
|
||||
|
||||
dir_struct_parser.add_argument('-d', dest='dir', help='Out directory')
|
||||
dir_struct_parser.add_argument('-n', dest='name', help='App name')
|
||||
|
||||
# Code Signing
|
||||
|
||||
code_signing_parser = subparsers.add_parser('codesign',
|
||||
help='Code sign the specified application')
|
||||
|
||||
code_signing_parser.set_defaults(func=PerformCodeSigning)
|
||||
|
||||
code_signing_parser.add_argument('-p', dest='application_path', required=True,
|
||||
help='The application path')
|
||||
code_signing_parser.add_argument('-i', dest='identity', required=True,
|
||||
help='The code signing identity to use')
|
||||
code_signing_parser.add_argument('-e', dest='entitlements_path',
|
||||
required=True,
|
||||
help='The path to the entitlements .xcent')
|
||||
|
||||
# Engage!
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
return args.func(args)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(Main())
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2014 The Chromium Authors. All rights reserved.
|
||||
# Copyright 2015 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.
|
||||
|
||||
@@ -15,6 +15,9 @@ declare_args() {
|
||||
|
||||
# Version of iOS that we're targeting.
|
||||
ios_deployment_target = "6.0"
|
||||
|
||||
# The iOS Code signing identity to use
|
||||
ios_code_signing_identity = ""
|
||||
}
|
||||
|
||||
if (ios_sdk_path == "") {
|
||||
@@ -28,3 +31,22 @@ if (ios_sdk_path == "") {
|
||||
exec_script("ios_sdk.py", [ _ios_sdk_to_query ], "list lines")
|
||||
ios_sdk_path = _ios_sdk_result[0]
|
||||
}
|
||||
|
||||
if (use_ios_simulator) {
|
||||
# Always disable code signing on the simulator
|
||||
ios_code_signing_identity = ""
|
||||
} else {
|
||||
# If an identity is not provided, look for one on the host
|
||||
if (ios_code_signing_identity == "") {
|
||||
_ios_identities = exec_script("find_signing_identity.py",
|
||||
[], "list lines")
|
||||
ios_code_signing_identity = _ios_identities[0]
|
||||
}
|
||||
|
||||
if (ios_code_signing_identity == "") {
|
||||
print("Tried to prepare a device build without specifying a code signing")
|
||||
print("identity and could not detect one automatically either.")
|
||||
print("TIP: Simulator builds dont require code signing...")
|
||||
assert(false)
|
||||
}
|
||||
}
|
||||
|
||||
108
engine/src/flutter/build/config/ios/ios_sim.py
Executable file
108
engine/src/flutter/build/config/ios/ios_sim.py
Executable file
@@ -0,0 +1,108 @@
|
||||
#!/usr/bin/python
|
||||
# Copyright (c) 2015 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 argparse
|
||||
import os
|
||||
import errno
|
||||
import subprocess
|
||||
import sys
|
||||
import re
|
||||
|
||||
SIMCTL_PATH = [
|
||||
'/usr/bin/env',
|
||||
'xcrun',
|
||||
'simctl',
|
||||
]
|
||||
|
||||
PLIST_BUDDY_PATH = [
|
||||
'/usr/bin/env',
|
||||
'xcrun',
|
||||
'PlistBuddy',
|
||||
]
|
||||
|
||||
|
||||
def ApplicationIdentifier(path):
|
||||
identifier = subprocess.check_output( PLIST_BUDDY_PATH + [
|
||||
'-c',
|
||||
'Print CFBundleIdentifier',
|
||||
'%s/Info.plist' % path,
|
||||
])
|
||||
|
||||
return identifier.strip()
|
||||
|
||||
|
||||
def Install(args):
|
||||
return subprocess.check_call( SIMCTL_PATH + [
|
||||
'install',
|
||||
'booted',
|
||||
args.path,
|
||||
])
|
||||
|
||||
|
||||
def InstallLaunchAndWait(args, wait):
|
||||
res = Install(args)
|
||||
|
||||
if res != 0:
|
||||
return res
|
||||
|
||||
identifier = ApplicationIdentifier(args.path)
|
||||
|
||||
launch_args = [ 'launch' ]
|
||||
|
||||
if wait:
|
||||
launch_args += [ '-w' ]
|
||||
|
||||
launch_args += [
|
||||
'booted',
|
||||
identifier,
|
||||
]
|
||||
|
||||
return subprocess.check_output( SIMCTL_PATH + launch_args ).strip()
|
||||
|
||||
|
||||
def Launch(args):
|
||||
InstallLaunchAndWait(args, False)
|
||||
|
||||
|
||||
def Debug(args):
|
||||
launch_res = InstallLaunchAndWait(args, True)
|
||||
launch_pid = re.search('.*: (\d+)', launch_res).group(1)
|
||||
return os.system(' '.join([
|
||||
'/usr/bin/env',
|
||||
'xcrun',
|
||||
'lldb',
|
||||
'-s',
|
||||
os.path.join(os.path.dirname(__file__), 'lldb_start_commands.txt'),
|
||||
'-p',
|
||||
launch_pid,
|
||||
]))
|
||||
|
||||
|
||||
def Main():
|
||||
parser = argparse.ArgumentParser(description='A script that launches an'
|
||||
' application in the simulator and attaches'
|
||||
' the debugger to the same')
|
||||
|
||||
parser.add_argument('-p', dest='path', required=True,
|
||||
help='Path the the simulator application')
|
||||
|
||||
subparsers = parser.add_subparsers()
|
||||
|
||||
launch_parser = subparsers.add_parser('launch', help='Launch')
|
||||
launch_parser.set_defaults(func=Launch)
|
||||
|
||||
install_parser = subparsers.add_parser('install', help='Install')
|
||||
install_parser.set_defaults(func=Install)
|
||||
|
||||
debug_parser = subparsers.add_parser('debug', help='Debug')
|
||||
debug_parser.set_defaults(func=Debug)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
return args.func(args)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(Main())
|
||||
@@ -0,0 +1,4 @@
|
||||
breakpoint set --name UIApplicationMain
|
||||
breakpoint set --name objc_exception_throw
|
||||
continue
|
||||
script print "........ Debugger break on main() ........"
|
||||
172
engine/src/flutter/build/config/ios/rules.gni
Normal file
172
engine/src/flutter/build/config/ios/rules.gni
Normal file
@@ -0,0 +1,172 @@
|
||||
# Copyright 2015 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.
|
||||
|
||||
ios_app_script = "//build/config/ios/ios_app.py"
|
||||
|
||||
template("code_sign_ios") {
|
||||
assert(defined(invoker.entitlements_path),
|
||||
"The path to the entitlements .xcent file")
|
||||
assert(defined(invoker.identity),
|
||||
"The code signing identity")
|
||||
assert(defined(invoker.application_path),
|
||||
"The application to code sign")
|
||||
assert(defined(invoker.deps))
|
||||
|
||||
action(target_name) {
|
||||
sources = [
|
||||
invoker.entitlements_path,
|
||||
]
|
||||
|
||||
_application_path = invoker.application_path
|
||||
|
||||
script = ios_app_script
|
||||
|
||||
outputs = [
|
||||
"$_application_path/_CodeSignature/CodeResources"
|
||||
]
|
||||
|
||||
args = [
|
||||
"codesign",
|
||||
"-p",
|
||||
rebase_path(invoker.application_path, root_build_dir),
|
||||
"-i",
|
||||
invoker.identity,
|
||||
"-e",
|
||||
rebase_path(invoker.entitlements_path, root_build_dir),
|
||||
]
|
||||
|
||||
deps = invoker.deps
|
||||
}
|
||||
}
|
||||
|
||||
template("resource_copy_ios") {
|
||||
assert(defined(invoker.resources),
|
||||
"The source list of resources to copy over")
|
||||
assert(defined(invoker.bundle_directory),
|
||||
"The directory within the bundle to place the sources in")
|
||||
assert(defined(invoker.app_name),
|
||||
"The name of the application")
|
||||
|
||||
_bundle_directory = invoker.bundle_directory
|
||||
_app_name = invoker.app_name
|
||||
_resources = invoker.resources
|
||||
|
||||
copy(target_name) {
|
||||
set_sources_assignment_filter([])
|
||||
sources = _resources
|
||||
outputs = [ "$root_build_dir/$_app_name.app/$_bundle_directory/{{source_file_part}}" ]
|
||||
}
|
||||
}
|
||||
|
||||
template("ios_app") {
|
||||
|
||||
assert(defined(invoker.deps),
|
||||
"Dependencies must be specified for $target_name")
|
||||
assert(defined(invoker.info_plist),
|
||||
"The application plist file must be specified for $target_name")
|
||||
assert(defined(invoker.app_name),
|
||||
"The name of iOS application for $target_name")
|
||||
assert(defined(invoker.entitlements_path),
|
||||
"The entitlements path must be specified for $target_name")
|
||||
assert(defined(invoker.code_signing_identity),
|
||||
"The entitlements path must be specified for $target_name")
|
||||
|
||||
# We just create a variable so we can use the same in interpolation
|
||||
app_name = invoker.app_name
|
||||
|
||||
# Generate the project structure
|
||||
|
||||
struct_gen_target_name = target_name + "_struct"
|
||||
|
||||
action(struct_gen_target_name) {
|
||||
|
||||
script = ios_app_script
|
||||
|
||||
sources = []
|
||||
outputs = [ "$root_build_dir/$app_name.app" ]
|
||||
|
||||
args = [
|
||||
"structure",
|
||||
"-d",
|
||||
rebase_path(root_build_dir),
|
||||
"-n",
|
||||
app_name
|
||||
]
|
||||
|
||||
}
|
||||
|
||||
# Generate the executable
|
||||
|
||||
bin_gen_target_name = target_name + "_bin"
|
||||
|
||||
executable(bin_gen_target_name) {
|
||||
libs = [ "UIKit.framework", "QuartzCore.framework", "OpenGLES.framework" ]
|
||||
deps = invoker.deps
|
||||
output_name = app_name
|
||||
}
|
||||
|
||||
# Process the Info.plist
|
||||
|
||||
plist_gen_target_name = target_name + "_plist"
|
||||
|
||||
action(plist_gen_target_name) {
|
||||
|
||||
script = ios_app_script
|
||||
|
||||
sources = [ invoker.info_plist ]
|
||||
outputs = [ "$root_build_dir/Info.plist" ]
|
||||
|
||||
args = [
|
||||
"plist",
|
||||
"-i",
|
||||
rebase_path(invoker.info_plist, root_build_dir),
|
||||
"-o",
|
||||
rebase_path(root_build_dir),
|
||||
]
|
||||
}
|
||||
|
||||
# Copy the generated binaries and assets to their appropriate locations
|
||||
|
||||
copy_gen_target_name = target_name + "_copy"
|
||||
copy(copy_gen_target_name) {
|
||||
sources = [
|
||||
"$root_build_dir/Info.plist",
|
||||
"$root_build_dir/$app_name",
|
||||
]
|
||||
|
||||
outputs = [
|
||||
"$root_build_dir/$app_name.app/{{source_file_part}}"
|
||||
]
|
||||
|
||||
deps = [
|
||||
":$struct_gen_target_name",
|
||||
":$bin_gen_target_name",
|
||||
":$plist_gen_target_name",
|
||||
]
|
||||
}
|
||||
|
||||
# Perform Code Signing
|
||||
|
||||
code_sign_gen_target_name = target_name + "_codesign"
|
||||
code_sign_ios(code_sign_gen_target_name) {
|
||||
entitlements_path = invoker.entitlements_path
|
||||
identity = invoker.code_signing_identity
|
||||
application_path = "$root_build_dir/$app_name.app"
|
||||
deps = [ ":$copy_gen_target_name" ]
|
||||
}
|
||||
|
||||
# Top level group
|
||||
|
||||
group(target_name) {
|
||||
# Skip code signing if no identity is provided. This is useful for simulator
|
||||
# builds
|
||||
deps = []
|
||||
if (invoker.code_signing_identity == "") {
|
||||
deps += [ ":$copy_gen_target_name" ]
|
||||
} else {
|
||||
deps += [ ":$code_sign_gen_target_name" ]
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -8,7 +8,8 @@ config("sdk") {
|
||||
common_flags = [
|
||||
"-isysroot",
|
||||
sysroot,
|
||||
"-mmacosx-version-min=10.6",
|
||||
"-mmacosx-version-min=$mac_sdk_min",
|
||||
"-stdlib=libc++",
|
||||
]
|
||||
|
||||
cflags = common_flags
|
||||
|
||||
113
engine/src/flutter/build/config/mac/mac_app.py
Normal file
113
engine/src/flutter/build/config/mac/mac_app.py
Normal file
@@ -0,0 +1,113 @@
|
||||
#!/usr/bin/python
|
||||
# Copyright (c) 2015 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 argparse
|
||||
import os
|
||||
import errno
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
PLUTIL = [
|
||||
'/usr/bin/env',
|
||||
'xcrun',
|
||||
'plutil'
|
||||
]
|
||||
|
||||
IBTOOL = [
|
||||
'/usr/bin/env',
|
||||
'xcrun',
|
||||
'ibtool',
|
||||
]
|
||||
|
||||
|
||||
def MakeDirectories(path):
|
||||
try:
|
||||
os.makedirs(path)
|
||||
except OSError as exc:
|
||||
if exc.errno == errno.EEXIST and os.path.isdir(path):
|
||||
return 0
|
||||
else:
|
||||
return -1
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
def ProcessInfoPlist(args):
|
||||
output_plist_file = os.path.abspath(os.path.join(args.output, 'Info.plist'))
|
||||
return subprocess.check_call( PLUTIL + [
|
||||
'-convert',
|
||||
'binary1',
|
||||
'-o',
|
||||
output_plist_file,
|
||||
'--',
|
||||
args.input,
|
||||
])
|
||||
|
||||
|
||||
def ProcessNIB(args):
|
||||
output_nib_file = os.path.join(os.path.abspath(args.output),
|
||||
"%s.nib" % os.path.splitext(os.path.basename(args.input))[0])
|
||||
|
||||
return subprocess.check_call(IBTOOL + [
|
||||
'--module',
|
||||
args.module,
|
||||
'--auto-activate-custom-fonts',
|
||||
'--target-device',
|
||||
'mac',
|
||||
'--compile',
|
||||
output_nib_file,
|
||||
os.path.abspath(args.input),
|
||||
])
|
||||
|
||||
|
||||
def GenerateProjectStructure(args):
|
||||
application_path = os.path.join( args.dir, args.name + ".app", "Contents" )
|
||||
return MakeDirectories( application_path )
|
||||
|
||||
|
||||
def Main():
|
||||
parser = argparse.ArgumentParser(description='A script that aids in '
|
||||
'the creation of an Mac application')
|
||||
|
||||
subparsers = parser.add_subparsers()
|
||||
|
||||
# Plist Parser
|
||||
|
||||
plist_parser = subparsers.add_parser('plist',
|
||||
help='Process the Info.plist')
|
||||
plist_parser.set_defaults(func=ProcessInfoPlist)
|
||||
|
||||
plist_parser.add_argument('-i', dest='input', help='The input plist path')
|
||||
plist_parser.add_argument('-o', dest='output', help='The output plist dir')
|
||||
|
||||
# NIB Parser
|
||||
|
||||
plist_parser = subparsers.add_parser('nib',
|
||||
help='Process a NIB file')
|
||||
plist_parser.set_defaults(func=ProcessNIB)
|
||||
|
||||
plist_parser.add_argument('-i', dest='input', help='The input nib path')
|
||||
plist_parser.add_argument('-o', dest='output', help='The output nib dir')
|
||||
plist_parser.add_argument('-m', dest='module', help='The module name')
|
||||
|
||||
# Directory Structure Parser
|
||||
|
||||
dir_struct_parser = subparsers.add_parser('structure',
|
||||
help='Creates the directory of an Mac application')
|
||||
|
||||
dir_struct_parser.set_defaults(func=GenerateProjectStructure)
|
||||
|
||||
dir_struct_parser.add_argument('-d', dest='dir', help='Out directory')
|
||||
dir_struct_parser.add_argument('-n', dest='name', help='App name')
|
||||
|
||||
# Engage!
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
return args.func(args)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(Main())
|
||||
216
engine/src/flutter/build/config/mac/rules.gni
Normal file
216
engine/src/flutter/build/config/mac/rules.gni
Normal file
@@ -0,0 +1,216 @@
|
||||
# Copyright 2015 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.
|
||||
|
||||
mac_app_script = "//build/config/mac/mac_app.py"
|
||||
|
||||
template("code_sign_mac") {
|
||||
assert(defined(invoker.entitlements_path),
|
||||
"The path to the entitlements .xcent file")
|
||||
assert(defined(invoker.identity),
|
||||
"The code signing identity")
|
||||
assert(defined(invoker.application_path),
|
||||
"The application to code sign")
|
||||
assert(defined(invoker.deps))
|
||||
|
||||
action(target_name) {
|
||||
sources = [
|
||||
invoker.entitlements_path,
|
||||
]
|
||||
|
||||
_application_path = invoker.application_path
|
||||
|
||||
script = mac_app_script
|
||||
|
||||
outputs = [
|
||||
"$_application_path/_CodeSignature/CodeResources"
|
||||
]
|
||||
|
||||
args = [
|
||||
"codesign",
|
||||
"-p",
|
||||
rebase_path(invoker.application_path, root_build_dir),
|
||||
"-i",
|
||||
invoker.identity,
|
||||
"-e",
|
||||
rebase_path(invoker.entitlements_path, root_build_dir),
|
||||
]
|
||||
|
||||
deps = invoker.deps
|
||||
}
|
||||
}
|
||||
|
||||
template("process_nibs_mac") {
|
||||
assert(defined(invoker.sources),
|
||||
"The nib sources must be specified")
|
||||
assert(defined(invoker.module),
|
||||
"The nib module must be specified")
|
||||
assert(defined(invoker.output_dir),
|
||||
"The output directory must be specified")
|
||||
|
||||
action_foreach(target_name) {
|
||||
sources = invoker.sources
|
||||
|
||||
script = mac_app_script
|
||||
|
||||
invoker_out_dir = invoker.output_dir
|
||||
|
||||
outputs = [
|
||||
"$root_build_dir/$invoker_out_dir/{{source_name_part}}.nib"
|
||||
]
|
||||
|
||||
args = [
|
||||
"nib",
|
||||
"-i",
|
||||
"{{source}}",
|
||||
"-o",
|
||||
invoker_out_dir,
|
||||
"-m",
|
||||
invoker.module,
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
template("resource_copy_mac") {
|
||||
assert(defined(invoker.resources),
|
||||
"The source list of resources to copy over")
|
||||
assert(defined(invoker.bundle_directory),
|
||||
"The directory within the bundle to place the sources in")
|
||||
assert(defined(invoker.app_name),
|
||||
"The name of the application")
|
||||
|
||||
_bundle_directory = invoker.bundle_directory
|
||||
_app_name = invoker.app_name
|
||||
_resources = invoker.resources
|
||||
|
||||
copy(target_name) {
|
||||
set_sources_assignment_filter([])
|
||||
sources = _resources
|
||||
outputs = [ "$root_build_dir/$_app_name.app/$_bundle_directory/Contents/Resources/{{source_file_part}}" ]
|
||||
}
|
||||
}
|
||||
|
||||
template("mac_app") {
|
||||
|
||||
assert(defined(invoker.deps),
|
||||
"Dependencies must be specified for $target_name")
|
||||
assert(defined(invoker.info_plist),
|
||||
"The application plist file must be specified for $target_name")
|
||||
assert(defined(invoker.app_name),
|
||||
"The name of Mac application for $target_name")
|
||||
assert(defined(invoker.xibs),
|
||||
"The list of XIB files must be specified for $target_name")
|
||||
# assert(defined(invoker.entitlements_path),
|
||||
# "The entitlements path must be specified for $target_name")
|
||||
# assert(defined(invoker.code_signing_identity),
|
||||
# "The entitlements path must be specified for $target_name")
|
||||
|
||||
# We just create a variable so we can use the same in interpolation
|
||||
app_name = invoker.app_name
|
||||
|
||||
# Generate the project structure
|
||||
|
||||
struct_gen_target_name = target_name + "_struct"
|
||||
|
||||
action(struct_gen_target_name) {
|
||||
|
||||
script = mac_app_script
|
||||
|
||||
sources = []
|
||||
outputs = [ "$root_build_dir/$app_name.app" ]
|
||||
|
||||
args = [
|
||||
"structure",
|
||||
"-d",
|
||||
rebase_path(root_build_dir),
|
||||
"-n",
|
||||
app_name
|
||||
]
|
||||
|
||||
}
|
||||
|
||||
# Generate the executable
|
||||
|
||||
bin_gen_target_name = target_name + "_bin"
|
||||
|
||||
executable(bin_gen_target_name) {
|
||||
deps = invoker.deps
|
||||
output_name = app_name
|
||||
}
|
||||
|
||||
# Process the Info.plist
|
||||
|
||||
plist_gen_target_name = target_name + "_plist"
|
||||
|
||||
action(plist_gen_target_name) {
|
||||
|
||||
script = mac_app_script
|
||||
|
||||
sources = [ invoker.info_plist ]
|
||||
outputs = [ "$root_build_dir/Info.plist" ]
|
||||
|
||||
args = [
|
||||
"plist",
|
||||
"-i",
|
||||
rebase_path(invoker.info_plist, root_build_dir),
|
||||
"-o",
|
||||
rebase_path(root_build_dir),
|
||||
]
|
||||
}
|
||||
|
||||
# Copy the generated binaries and assets to their appropriate locations
|
||||
|
||||
copy_plist_gen_target_name = target_name + "_plist_copy"
|
||||
copy(copy_plist_gen_target_name) {
|
||||
sources = [
|
||||
"$root_build_dir/Info.plist",
|
||||
]
|
||||
|
||||
outputs = [
|
||||
"$root_build_dir/$app_name.app/Contents/{{source_file_part}}"
|
||||
]
|
||||
|
||||
deps = [
|
||||
":$plist_gen_target_name",
|
||||
]
|
||||
}
|
||||
|
||||
copy_bin_target_name = target_name + "_bin_copy"
|
||||
copy(copy_bin_target_name) {
|
||||
sources = [
|
||||
"$root_build_dir/$app_name",
|
||||
]
|
||||
|
||||
outputs = [
|
||||
"$root_build_dir/$app_name.app/Contents/MacOS/{{source_file_part}}"
|
||||
]
|
||||
|
||||
deps = [
|
||||
":$bin_gen_target_name",
|
||||
]
|
||||
}
|
||||
|
||||
copy_xib_target_name = target_name + "_xib_copy"
|
||||
process_nibs_mac(copy_xib_target_name) {
|
||||
sources = invoker.xibs
|
||||
module = app_name
|
||||
output_dir = "$app_name.app/Contents/Resources"
|
||||
}
|
||||
|
||||
copy_all_target_name = target_name + "_all_copy"
|
||||
group(copy_all_target_name) {
|
||||
deps = [
|
||||
":$struct_gen_target_name",
|
||||
":$copy_plist_gen_target_name",
|
||||
":$copy_bin_target_name",
|
||||
":$copy_xib_target_name",
|
||||
]
|
||||
}
|
||||
|
||||
# Top level group
|
||||
|
||||
group(target_name) {
|
||||
deps = [ ":$copy_all_target_name" ]
|
||||
}
|
||||
|
||||
}
|
||||
@@ -7,11 +7,13 @@
|
||||
# Linux.
|
||||
|
||||
import("../goma.gni")
|
||||
import("//build/config/ios/ios_sdk.gni")
|
||||
|
||||
assert(host_os == "mac")
|
||||
|
||||
import("//build/toolchain/clang.gni")
|
||||
import("//build/toolchain/goma.gni")
|
||||
import("//build/config/sysroot.gni")
|
||||
|
||||
if (use_goma) {
|
||||
goma_prefix = "$goma_dir/gomacc "
|
||||
@@ -36,6 +38,8 @@ template("mac_toolchain") {
|
||||
"mac_toolchain() must specify a \"toolchain_cpu\"")
|
||||
assert(defined(invoker.toolchain_os),
|
||||
"mac_toolchain() must specify a \"toolchain_os\"")
|
||||
assert(defined(invoker.switch_sysroot),
|
||||
"mac_toolchain() must specify a \"switch_sysroot\"")
|
||||
|
||||
# We can't do string interpolation ($ in strings) on things with dots in
|
||||
# them. To allow us to use $cc below, for example, we create copies of
|
||||
@@ -48,9 +52,23 @@ template("mac_toolchain") {
|
||||
lib_switch = "-l"
|
||||
lib_dir_switch = "-L"
|
||||
|
||||
sysroot_flags = ""
|
||||
|
||||
if (invoker.switch_sysroot) {
|
||||
version_flags = ""
|
||||
|
||||
if (use_ios_simulator) {
|
||||
version_flags = "-mios-simulator-version-min=$ios_deployment_target"
|
||||
} else {
|
||||
version_flags = "-miphoneos-version-min=$ios_deployment_target"
|
||||
}
|
||||
|
||||
sysroot_flags = "-isysroot $sysroot $version_flags"
|
||||
}
|
||||
|
||||
tool("cc") {
|
||||
depfile = "{{output}}.d"
|
||||
command = "$cc -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_c}} -c {{source}} -o {{output}}"
|
||||
command = "$cc -MMD -MF $depfile {{defines}} {{include_dirs}} $sysroot_flags {{cflags}} {{cflags_c}} -c {{source}} -o {{output}}"
|
||||
depsformat = "gcc"
|
||||
description = "CC {{output}}"
|
||||
outputs = [
|
||||
@@ -60,7 +78,7 @@ template("mac_toolchain") {
|
||||
|
||||
tool("cxx") {
|
||||
depfile = "{{output}}.d"
|
||||
command = "$cxx -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_cc}} -c {{source}} -o {{output}}"
|
||||
command = "$cxx -MMD -MF $depfile {{defines}} {{include_dirs}} $sysroot_flags {{cflags}} {{cflags_cc}} -c {{source}} -o {{output}}"
|
||||
depsformat = "gcc"
|
||||
description = "CXX {{output}}"
|
||||
outputs = [
|
||||
@@ -71,7 +89,7 @@ template("mac_toolchain") {
|
||||
tool("asm") {
|
||||
# For GCC we can just use the C compiler to compile assembly.
|
||||
depfile = "{{output}}.d"
|
||||
command = "$cc -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_c}} -c {{source}} -o {{output}}"
|
||||
command = "$cc -MMD -MF $depfile {{defines}} {{include_dirs}} $sysroot_flags {{cflags}} {{cflags_c}} -c {{source}} -o {{output}}"
|
||||
depsformat = "gcc"
|
||||
description = "ASM {{output}}"
|
||||
outputs = [
|
||||
@@ -81,7 +99,7 @@ template("mac_toolchain") {
|
||||
|
||||
tool("objc") {
|
||||
depfile = "{{output}}.d"
|
||||
command = "$cxx -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_c}} {{cflags_objc}} -c {{source}} -o {{output}}"
|
||||
command = "$cxx -MMD -MF $depfile {{defines}} {{include_dirs}} $sysroot_flags {{cflags}} {{cflags_c}} {{cflags_objc}} -c {{source}} -o {{output}}"
|
||||
depsformat = "gcc"
|
||||
description = "OBJC {{output}}"
|
||||
outputs = [
|
||||
@@ -91,7 +109,7 @@ template("mac_toolchain") {
|
||||
|
||||
tool("objcxx") {
|
||||
depfile = "{{output}}.d"
|
||||
command = "$cxx -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_cc}} {{cflags_objcc}} -c {{source}} -o {{output}}"
|
||||
command = "$cxx -MMD -MF $depfile {{defines}} {{include_dirs}} $sysroot_flags {{cflags}} {{cflags_cc}} {{cflags_objcc}} -c {{source}} -o {{output}}"
|
||||
depsformat = "gcc"
|
||||
description = "OBJCXX {{output}}"
|
||||
outputs = [
|
||||
@@ -125,7 +143,7 @@ template("mac_toolchain") {
|
||||
temporary_tocname = dylib + ".tmp"
|
||||
|
||||
does_reexport_command = "[ ! -e $dylib -o ! -e $tocname ] || otool -l $dylib | grep -q LC_REEXPORT_DYLIB"
|
||||
link_command = "$ld -shared {{ldflags}} -o $dylib -Wl,-filelist,$rspfile {{solibs}} {{libs}}"
|
||||
link_command = "$ld -shared $sysroot_flags {{ldflags}} -o $dylib -Wl,-filelist,$rspfile {{solibs}} {{libs}}"
|
||||
replace_command = "if ! cmp -s $temporary_tocname $tocname; then mv $temporary_tocname $tocname"
|
||||
extract_toc_command = "{ otool -l $dylib | grep LC_ID_DYLIB -A 5; nm -gP $dylib | cut -f1-2 -d' ' | grep -v U\$\$; true; }"
|
||||
|
||||
@@ -160,7 +178,7 @@ template("mac_toolchain") {
|
||||
tool("link") {
|
||||
outfile = "{{root_out_dir}}/{{target_output_name}}{{output_extension}}"
|
||||
rspfile = "$outfile.rsp"
|
||||
command = "$ld {{ldflags}} -o $outfile -Wl,-filelist,$rspfile {{solibs}} {{libs}}"
|
||||
command = "$ld $sysroot_flags {{ldflags}} -o $outfile -Wl,-filelist,$rspfile {{solibs}} {{libs}}"
|
||||
description = "LINK $outfile"
|
||||
rspfile_content = "{{inputs_newline}}"
|
||||
outputs = [
|
||||
@@ -202,6 +220,19 @@ mac_toolchain("clang_arm") {
|
||||
cxx = "${goma_prefix}$prefix/clang++"
|
||||
ld = cxx
|
||||
is_clang = true
|
||||
switch_sysroot = false
|
||||
}
|
||||
|
||||
mac_toolchain("ios_clang_arm") {
|
||||
toolchain_cpu = "arm"
|
||||
toolchain_os = "mac"
|
||||
prefix = rebase_path("//third_party/llvm-build/Release+Asserts/bin",
|
||||
root_build_dir)
|
||||
cc = "${goma_prefix}$prefix/clang"
|
||||
cxx = "${goma_prefix}$prefix/clang++"
|
||||
ld = cxx
|
||||
is_clang = true
|
||||
switch_sysroot = true
|
||||
}
|
||||
|
||||
mac_toolchain("arm") {
|
||||
@@ -211,6 +242,7 @@ mac_toolchain("arm") {
|
||||
cxx = "${goma_prefix}/g++"
|
||||
ld = cxx
|
||||
is_clang = false
|
||||
switch_sysroot = false
|
||||
}
|
||||
|
||||
mac_toolchain("clang_x64") {
|
||||
@@ -222,6 +254,7 @@ mac_toolchain("clang_x64") {
|
||||
cxx = "${goma_prefix}$prefix/clang++"
|
||||
ld = cxx
|
||||
is_clang = true
|
||||
switch_sysroot = false
|
||||
}
|
||||
|
||||
mac_toolchain("x64") {
|
||||
@@ -231,4 +264,5 @@ mac_toolchain("x64") {
|
||||
cxx = "${goma_prefix}/g++"
|
||||
ld = cxx
|
||||
is_clang = false
|
||||
switch_sysroot = false
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user