From 2a29462a04dabad3fc20dc922227c46b36459912 Mon Sep 17 00:00:00 2001 From: dpranke Date: Thu, 6 Aug 2015 22:23:01 -0700 Subject: [PATCH] patch from chinmaygarde@ to make progress on mac, ios. I've taken https://github.com/chinmaygarde/sky_engine/commit/ad591c629a295936206dcfde37f63c8c82bc2838 and merged it onto Chromium ToT, with a few lint and other cleanups, and one fix to make sure that Mac still compiled (which may have broken iOS, haven't tested yet). R=brettw@chromium.org, sdfresne@chromium.org BUG=459705 CQ_EXTRA_TRYBOTS=tryserver.chromium.mac:mac_chromium_gn_rel,mac_chromium_gn_dbg Review URL: https://codereview.chromium.org/1250913002 Cr-Commit-Position: refs/heads/master@{#342297} --- BUILD.gn | 11 +- base/BUILD.gn | 13 +- base/memory/BUILD.gn | 5 +- base/process/BUILD.gn | 5 +- base/test/BUILD.gn | 25 ++-- build/config/BUILD.gn | 4 +- build/config/BUILDCONFIG.gn | 2 +- build/config/compiler/BUILD.gn | 5 +- build/config/features.gni | 2 +- build/config/ios/BUILD.gn | 2 + build/config/ios/find_signing_identity.py | 35 +++++ build/config/ios/ios_app.py | 99 ++++++++++++++ build/config/ios/ios_sdk.gni | 37 +++++- build/config/ios/ios_sim.py | 106 +++++++++++++++ build/config/ios/lldb_start_commands.txt | 4 + build/config/ios/rules.gni | 169 ++++++++++++++++++++++++ build/config/mac/BUILD.gn | 3 +- build/config/mac/mac_app.py | 99 ++++++++++++++ build/config/mac/rules.gni | 212 ++++++++++++++++++++++++++++++ build/secondary/testing/gtest/BUILD.gn | 13 +- build/secondary/third_party/nss/BUILD.gn | 1 - build/toolchain/mac/BUILD.gn | 20 ++- testing/test.gni | 75 +++++++++++ 23 files changed, 910 insertions(+), 37 deletions(-) create mode 100644 build/config/ios/find_signing_identity.py create mode 100644 build/config/ios/ios_app.py create mode 100755 build/config/ios/ios_sim.py create mode 100644 build/config/ios/lldb_start_commands.txt create mode 100644 build/config/ios/rules.gni create mode 100644 build/config/mac/mac_app.py create mode 100644 build/config/mac/rules.gni diff --git a/BUILD.gn b/BUILD.gn index 466e15e77af6..386145a852cd 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -65,9 +65,11 @@ group("both_gn_and_gyp") { testonly = true deps = [ "//base:base_unittests", - "//sync:sync_unit_tests", ] + if (!is_ios) { + # TODO(GYP): Figure out which of these should actually build on iOS, + # and whether there should be other targets that are iOS-only and missing. deps += [ "//cc:cc_unittests", "//chrome", @@ -134,6 +136,7 @@ group("both_gn_and_gyp") { "//printing:printing_unittests", "//skia:skia_unittests", "//sql:sql_unittests", + "//sync:sync_unit_tests", "//third_party/WebKit/Source/platform:heap_unittests", "//third_party/WebKit/Source/platform:platform_unittests", "//third_party/WebKit/Source/web:webkit_unit_tests", @@ -599,10 +602,10 @@ group("both_gn_and_gyp") { group("gn_only") { testonly = true + deps = [] + if (!is_ios) { - deps = [ - "//mandoline:all", - ] + deps += [ "//mandoline:all" ] } if (!is_android && !is_ios) { diff --git a/base/BUILD.gn b/base/BUILD.gn index da16ec3bdc35..b8ae3a9e5c39 100644 --- a/base/BUILD.gn +++ b/base/BUILD.gn @@ -11,6 +11,11 @@ if (is_android) { config("base_implementation") { defines = [ "BASE_IMPLEMENTATION" ] + + if (is_ios) { + # base uses routines deprecated in iOS 8 + cflags = [ "-Wno-deprecated-declarations" ] + } } if (is_win) { @@ -643,7 +648,6 @@ component("base") { ] if (is_ios) { - sources += [ "process/memory_stubs.cc" ] sources -= [ "message_loop/message_pump_libevent.cc", "message_loop/message_pump_libevent.h", @@ -1339,7 +1343,6 @@ test("base_unittests") { "process/process_metrics_unittest_ios.cc", "process/process_unittest.cc", "process/process_util_unittest.cc", - "process/process_util_unittest_ios.cc", "profiler/stack_sampling_profiler_unittest.cc", "profiler/tracked_time_unittest.cc", "rand_util_unittest.cc", @@ -1466,6 +1469,8 @@ test("base_unittests") { if (is_ios) { sources -= [ + "memory/discardable_shared_memory_unittest.cc", + "memory/shared_memory_unittest.cc", "process/memory_unittest.cc", "process/process_unittest.cc", "process/process_util_unittest.cc", @@ -1479,7 +1484,7 @@ test("base_unittests") { "mac/foundation_util_unittest.mm", "mac/objc_property_releaser_unittest.mm", "mac/scoped_nsobject_unittest.mm", - "sys_string_conversions_mac_unittest.mm", + "strings/sys_string_conversions_mac_unittest.mm", ] set_sources_assignment_filter(sources_assignment_filter) @@ -1500,7 +1505,7 @@ test("base_unittests") { sources -= [ "message_loop/message_pump_glib_unittest.cc" ] } - if (is_posix || is_ios) { + if (is_posix && !is_ios) { sources += [ "message_loop/message_pump_libevent_unittest.cc" ] deps += [ "//third_party/libevent" ] } diff --git a/base/memory/BUILD.gn b/base/memory/BUILD.gn index abbfa64202ef..93e464c2227e 100644 --- a/base/memory/BUILD.gn +++ b/base/memory/BUILD.gn @@ -47,7 +47,10 @@ source_set("memory") { "weak_ptr.h", ] if (is_ios) { - sources -= [ "shared_memory_posix.cc" ] + sources -= [ + "discardable_shared_memory.cc", + "shared_memory_posix.cc", + ] } if (is_nacl) { diff --git a/base/process/BUILD.gn b/base/process/BUILD.gn index 3978b2e58cf8..202316266520 100644 --- a/base/process/BUILD.gn +++ b/base/process/BUILD.gn @@ -96,7 +96,10 @@ source_set("process") { } if (is_ios) { - sources += [ "process_metrics.cc" ] + sources += [ + "memory_stubs.cc", + "process_metrics.cc", + ] } configs += [ "//base:base_implementation" ] diff --git a/base/test/BUILD.gn b/base/test/BUILD.gn index c36d2664b0d9..3239915aef82 100644 --- a/base/test/BUILD.gn +++ b/base/test/BUILD.gn @@ -37,15 +37,11 @@ source_set("test_support") { "histogram_tester.h", "ios/wait_util.h", "ios/wait_util.mm", - "launcher/test_launcher.cc", "launcher/test_launcher.h", "launcher/test_result.cc", "launcher/test_result.h", - "launcher/test_results_tracker.cc", "launcher/test_results_tracker.h", - "launcher/unit_test_launcher.cc", "launcher/unit_test_launcher.h", - "launcher/unit_test_launcher_ios.cc", "mock_chrome_application_mac.h", "mock_chrome_application_mac.mm", "mock_devices_changed_observer.cc", @@ -54,9 +50,7 @@ source_set("test_support") { "mock_entropy_provider.h", "mock_log.cc", "mock_log.h", - "multiprocess_test.cc", "multiprocess_test.h", - "multiprocess_test_android.cc", "null_task_runner.cc", "null_task_runner.h", "opaque_ref_counted.cc", @@ -126,6 +120,18 @@ source_set("test_support") { "values_test_util.h", ] + if (is_ios) { + sources += [ "launcher/unit_test_launcher_ios.cc" ] + } else { + sources += [ + "launcher/test_launcher.cc", + "launcher/test_results_tracker.cc", + "launcher/unit_test_launcher.cc", + "multiprocess_test.cc", + "multiprocess_test_android.cc", + ] + } + configs += [ "//build/config:precompiled_headers" ] data = [ @@ -154,14 +160,11 @@ source_set("test_support") { "scoped_locale.h", ] } - if (is_ios) { - # iOS uses its own unit test launcher. - sources -= [ "launcher/unit_test_launcher.cc" ] - # Pull in specific Mac files for iOS (which have been filtered out - # by file name rules). + if (is_ios) { set_sources_assignment_filter([]) sources += [ "test_file_util_mac.cc" ] + set_sources_assignment_filter(sources_assignment_filter) } if (is_android) { diff --git a/build/config/BUILD.gn b/build/config/BUILD.gn index ca1e4ec21f8d..e5bba162f3e3 100644 --- a/build/config/BUILD.gn +++ b/build/config/BUILD.gn @@ -398,15 +398,17 @@ config("default_libs") { "CoreFoundation.framework", "Foundation.framework", "IOKit.framework", + "OpenGL.framework", "Security.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" ] diff --git a/build/config/BUILDCONFIG.gn b/build/config/BUILDCONFIG.gn index 337aaf58b29c..c91db167b34d 100644 --- a/build/config/BUILDCONFIG.gn +++ b/build/config/BUILDCONFIG.gn @@ -595,7 +595,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 diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn index 0424ca519355..1db19c1b557b 100644 --- a/build/config/compiler/BUILD.gn +++ b/build/config/compiler/BUILD.gn @@ -284,9 +284,12 @@ config("compiler") { "i386", ] } else if (current_cpu == "arm") { + # TODO(GYP): we may need to distinguish between "arm64", "armv7", + # and "armv7s" for iOS, and hence need multiple current_cpu values + # rather than just "arm". common_mac_flags += [ "-arch", - "armv7", + "arm64", ] } diff --git a/build/config/features.gni b/build/config/features.gni index 6d8f25afb556..8ca446dd43d9 100644 --- a/build/config/features.gni +++ b/build/config/features.gni @@ -60,7 +60,7 @@ declare_args() { # TODO(GYP) The GYP build has || chromecast==1 for this: proprietary_codecs = is_android || is_chrome_branded - # TODO(gyp) true + # TODO(GYP) This should be enabled on ios as well. enable_configuration_policy = !is_ios # Enables support for background apps. diff --git a/build/config/ios/BUILD.gn b/build/config/ios/BUILD.gn index 0539810f818d..d69f423a0bdb 100644 --- a/build/config/ios/BUILD.gn +++ b/build/config/ios/BUILD.gn @@ -9,6 +9,8 @@ config("sdk") { common_flags = [ "-isysroot", sysroot, + + "-stdlib=libc++", ] if (use_ios_simulator) { diff --git a/build/config/ios/find_signing_identity.py b/build/config/ios/find_signing_identity.py new file mode 100644 index 000000000000..9c3d493d5416 --- /dev/null +++ b/build/config/ios/find_signing_identity.py @@ -0,0 +1,35 @@ +# 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('[0-9]+\) ([A-F0-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() diff --git a/build/config/ios/ios_app.py b/build/config/ios/ios_app.py new file mode 100644 index 000000000000..54a68ac238f1 --- /dev/null +++ b/build/config/ios/ios_app.py @@ -0,0 +1,99 @@ +# 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 errno +import os +import subprocess +import sys + + +def ProcessInfoPlist(args): + output_plist_file = os.path.abspath(os.path.join(args.output, 'Info.plist')) + return subprocess.check_call( [ + '/usr/bin/env', + 'xcrun', + '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()) diff --git a/build/config/ios/ios_sdk.gni b/build/config/ios/ios_sdk.gni index cb2708b76c10..ebbb7c9c57e1 100644 --- a/build/config/ios/ios_sdk.gni +++ b/build/config/ios/ios_sdk.gni @@ -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. @@ -7,14 +7,16 @@ declare_args() { # value of use_ios_simulator. ios_sdk_path = "" - # Set to true when targeting a simulator build on iOS. False means that the - # target is for running on the device. The default value is to use the - # Simulator except when targeting GYP's Xcode builds (for compat with the - # existing GYP build). - use_ios_simulator = true + use_ios_simulator = target_cpu == "x86" || target_cpu == "x64" # Version of iOS that we're targeting. - ios_deployment_target = "6.0" + ios_deployment_target = "7.0" + + # The iOS Code signing identity to use + # TODO(GYP), TODO(sdfresne): Consider having a separate + # ios_enable_code_signing_flag= flag to make the invocation clearer. + ios_enable_code_signing = true + ios_code_signing_identity = "" } if (ios_sdk_path == "") { @@ -28,3 +30,24 @@ 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_enable_code_signing = false + ios_code_signing_identity = "" +} + +if (ios_enable_code_signing) { + # 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) + } +} diff --git a/build/config/ios/ios_sim.py b/build/config/ios/ios_sim.py new file mode 100755 index 000000000000..371719d5a31f --- /dev/null +++ b/build/config/ios/ios_sim.py @@ -0,0 +1,106 @@ +#!/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 errno +import os +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_arg).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()) diff --git a/build/config/ios/lldb_start_commands.txt b/build/config/ios/lldb_start_commands.txt new file mode 100644 index 000000000000..42e0b14c747d --- /dev/null +++ b/build/config/ios/lldb_start_commands.txt @@ -0,0 +1,4 @@ +breakpoint set --name UIApplicationMain +breakpoint set --name objc_exception_throw +continue +script print "........ Debugger break on main() ........" diff --git a/build/config/ios/rules.gni b/build/config/ios/rules.gni new file mode 100644 index 000000000000..37563746865d --- /dev/null +++ b/build/config/ios/rules.gni @@ -0,0 +1,169 @@ +# 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), + ] + + forward_variables_from(invoker, + [ + "deps", + "public_deps", + "testonly", + ]) + } +} + +# TODO(GYP), TODO(dpranke): Should this be part of ios_app? +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.entitlements_path), + "The entitlements path must be specified for $target_name") + assert(defined(invoker.code_signing_identity), + "The code_signing_identity must be specified for $target_name") + + # We just create a variable so we can use the same in interpolation + if (defined(invoker.app_name)) { + _app_name = invoker.app_name + } else { + _app_name = target_name + } + + forward_variables_from(invoker, [ "testonly" ]) + + plist_gen_target_name = target_name + "_plist" + bin_gen_target_name = target_name + "_bin" + group_target_name = target_name + + # Generate the executable + executable(bin_gen_target_name) { + visibility = [ ":$group_target_name" ] + + output_name = "${_app_name}.app/${_app_name}" + + if (defined(invoker.libs)) { + libs = invoker.libs + } else { + libs = [] + } + libs += [ + "UIKit.framework", + "QuartzCore.framework", + "OpenGLES.framework", + ] + + if (defined(invoker.deps)) { + deps = invoker.deps + } else { + deps = [] + } + deps += [ ":$plist_gen_target_name" ] + } + + # Process the Info.plist + action(plist_gen_target_name) { + visibility = [ + ":$group_target_name", + ":$bin_gen_target_name", + ] + + script = ios_app_script + + sources = [ + invoker.info_plist, + ] + outputs = [ + "$root_build_dir/${_app_name}.app/Info.plist", + ] + + args = [ + "plist", + "-i", + rebase_path(invoker.info_plist, root_build_dir), + "-o", + rebase_path("$root_build_dir/${_app_name}.app"), + ] + } + + # Perform Code Signing + entitlements_path = invoker.entitlements_path + if (invoker.code_signing_identity != "") { + code_sign_gen_target_name = target_name + "_codesign" + code_sign_ios(code_sign_gen_target_name) { + visibility = [ ":$target_name" ] + + identity = invoker.code_signing_identity + application_path = "$root_build_dir/$app_name.app" + deps = [ + ":$plist_gen_target_name", + ":$bin_gen_target_name", + ] + } + } else { + # This avoids a potential unused variable warning in the caller. + entitlements_path = entitlements_path + } + + # Top level group + group(target_name) { + deps = [ + ":$plist_gen_target_name", + ":$bin_gen_target_name", + ] + if (invoker.code_signing_identity != "") { + deps += [ ":$code_sign_gen_target_name" ] + } + } +} diff --git a/build/config/mac/BUILD.gn b/build/config/mac/BUILD.gn index 9288add13952..858ad8895ff2 100644 --- a/build/config/mac/BUILD.gn +++ b/build/config/mac/BUILD.gn @@ -3,12 +3,13 @@ # found in the LICENSE file. import("//build/config/sysroot.gni") +import("//build/config/mac/mac_sdk.gni") config("sdk") { common_flags = [ "-isysroot", sysroot, - "-mmacosx-version-min=10.6", + "-mmacosx-version-min=$mac_sdk_min", ] cflags = common_flags diff --git a/build/config/mac/mac_app.py b/build/config/mac/mac_app.py new file mode 100644 index 000000000000..70c313a65e68 --- /dev/null +++ b/build/config/mac/mac_app.py @@ -0,0 +1,99 @@ +# 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 errno +import os +import subprocess +import sys + +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([ + '/usr/bin/env', + 'xcrun', + '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([ + '/usr/bin/env', + 'xcrun', + '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') + + args = parser.parse_args() + return args.func(args) + + +if __name__ == '__main__': + sys.exit(main()) diff --git a/build/config/mac/rules.gni b/build/config/mac/rules.gni new file mode 100644 index 000000000000..8baad60597b9 --- /dev/null +++ b/build/config/mac/rules.gni @@ -0,0 +1,212 @@ +# 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), + ] + + forward_variables_from(invoker, + [ + "deps", + "public_deps", + "visibility", + ]) + } +} + +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, + ] + } + + forward_variables_from(invoker, + [ + "deps", + "public_deps", + "visibility", + ]) +} + +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") + + if (defined(invoker.app_name)) { + _app_name = invoker.app_name + } else { + _app_name = target_name + } + + _bundle_directory = invoker.bundle_directory + _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.xibs), + "The list of XIB files must be specified for $target_name") + + group_gen_target_name = target_name + copy_all_target_name = target_name + "_all_copy" + + # We just create a variable so we can use the same in interpolation + if (defined(invoker.app_name)) { + _app_name = invoker.app_name + } else { + _app_name = target_name + } + + # Generate the executable + bin_gen_target_name = target_name + "_bin" + executable(bin_gen_target_name) { + visibility = [ ":$group_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) { + visibility = [ ":$group_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) { + visibility = [ ":$group_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) { + visibility = [ ":$group_gen_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) { + visibility = [ ":$group_gen_target_name" ] + sources = invoker.xibs + module = app_name + output_dir = "$app_name.app/Contents/Resources" + } + + group(copy_all_target_name) { + visibility = [ ":$group_gen_target_name" ] + deps = [ + ":$struct_gen_target_name", + ":$copy_plist_gen_target_name", + ":$copy_bin_target_name", + ":$copy_xib_target_name", + ] + } + + # Top level group + + group(group_gen_target_name) { + deps = [ + ":$copy_all_target_name", + ] + } +} diff --git a/build/secondary/testing/gtest/BUILD.gn b/build/secondary/testing/gtest/BUILD.gn index 073faec56294..a9f5007b2670 100644 --- a/build/secondary/testing/gtest/BUILD.gn +++ b/build/secondary/testing/gtest/BUILD.gn @@ -96,12 +96,23 @@ static_library("gtest") { "src/gtest.cc", ] - if (is_mac) { + if (is_mac || is_ios) { + if (is_ios) { + set_sources_assignment_filter([]) + } sources += [ "../gtest_mac.h", "../gtest_mac.mm", "../platform_test_mac.mm", ] + set_sources_assignment_filter(sources_assignment_filter) + } + + if (is_ios) { + sources += [ + "../coverage_util_ios.cc", + "../coverage_util_ios.h", + ] } include_dirs = [ "." ] diff --git a/build/secondary/third_party/nss/BUILD.gn b/build/secondary/third_party/nss/BUILD.gn index c2648f44ea2d..e51fb21ac625 100644 --- a/build/secondary/third_party/nss/BUILD.gn +++ b/build/secondary/third_party/nss/BUILD.gn @@ -913,7 +913,6 @@ if (is_linux) { if (include_nss_libpkix) { sources += [ "nss/lib/certhigh/certvfypkix.c", - "nss/lib/certhigh/certvfypkixprint.c", "nss/lib/libpkix/include/pkix.h", "nss/lib/libpkix/include/pkix_certsel.h", "nss/lib/libpkix/include/pkix_certstore.h", diff --git a/build/toolchain/mac/BUILD.gn b/build/toolchain/mac/BUILD.gn index 237f6416cbf5..7f63f6f15ca4 100644 --- a/build/toolchain/mac/BUILD.gn +++ b/build/toolchain/mac/BUILD.gn @@ -7,6 +7,7 @@ # Linux. import("../goma.gni") +import("//build/config/ios/ios_sdk.gni") assert(host_os == "mac") @@ -81,7 +82,7 @@ template("mac_toolchain") { tool("objc") { depfile = "{{output}}.d" - command = "$cxx -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_objc}} -c {{source}} -o {{output}}" + command = "$cxx -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_c}} {{cflags_objc}} -c {{source}} -o {{output}}" depsformat = "gcc" description = "OBJC {{output}}" outputs = [ @@ -91,7 +92,7 @@ template("mac_toolchain") { tool("objcxx") { depfile = "{{output}}.d" - command = "$cxx -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_objcc}} -c {{source}} -o {{output}}" + command = "$cxx -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_cc}} {{cflags_objcc}} -c {{source}} -o {{output}}" depsformat = "gcc" description = "OBJCXX {{output}}" outputs = [ @@ -204,6 +205,21 @@ mac_toolchain("clang_arm") { is_clang = true } +mac_toolchain("ios_clang_arm") { + # TODO(GYP): Do we need ios_clang_armv7 and ios_clang_arm64 ? + toolchain_cpu = "arm" + toolchain_os = "mac" + + # TODO(GYP): We need to support being able to use the version of clang + # shipped w/ XCode instead of the one pulled from upstream. + 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 +} + mac_toolchain("arm") { toolchain_cpu = "arm" toolchain_os = "mac" diff --git a/testing/test.gni b/testing/test.gni index cfdb2de98554..28a9e550df84 100644 --- a/testing/test.gni +++ b/testing/test.gni @@ -105,6 +105,81 @@ template("test") { ":$apk_name", ] } + } else if (is_ios) { + if (is_ios) { + import("//build/config/ios/rules.gni") + } + + target__sources_name = "${target_name}__sources" + if (defined(invoker.sources)) { + source_set(target__sources_name) { + sources = invoker.sources + testonly = true + + configs = [] # Prevent list overwriting warning. + configs += invoker.configs + + forward_variables_from(invoker, + [ + "data", + "deps", + "data_deps", + "datadeps", + "defines", + "includes", + ]) + } + } + + ios_app(target_name) { + # TODO(GYP): Make this configurable and only provide a default + # that can be overridden. + info_plist = "//testing/gtest_ios/unittest-Info.plist" + app_name = target_name + entitlements_path = "//testing/gtest_ios" + code_signing_identity = "" + testonly = true + + # See above call. + set_sources_assignment_filter([]) + + forward_variables_from(invoker, + [ + "all_dependent_configs", + "allow_circular_includes_from", + "cflags", + "cflags_c", + "cflags_cc", + "cflags_objc", + "cflags_objcc", + "check_includes", + "forward_dependent_configs_from", + "include_dirs", + "ldflags", + "libs", + "output_extension", + "output_name", + "public", + "public_configs", + "public_deps", + "visibility", + ]) + + if (defined(invoker.deps)) { + deps = invoker.deps + } else { + deps = [] + } + deps += [ + # All shared libraries must have the sanitizer deps to properly link in + # asan mode (this target will be empty in other cases). + "//build/config/sanitizers:deps", + ] + + if (defined(invoker.sources)) { + deps += [ ":${target__sources_name}" ] + } + } } else { executable(target_name) { forward_variables_from(invoker, "*") -- 2.11.4.GIT