summaryrefslogtreecommitdiffstats
path: root/third_party/libwebrtc/build/config/mac
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/libwebrtc/build/config/mac')
-rw-r--r--third_party/libwebrtc/build/config/mac/BUILD.gn136
-rw-r--r--third_party/libwebrtc/build/config/mac/BuildInfo.plist16
-rw-r--r--third_party/libwebrtc/build/config/mac/OWNERS1
-rw-r--r--third_party/libwebrtc/build/config/mac/mac_sdk.gni127
-rw-r--r--third_party/libwebrtc/build/config/mac/mac_sdk_overrides.gni16
-rw-r--r--third_party/libwebrtc/build/config/mac/package_framework.py60
-rw-r--r--third_party/libwebrtc/build/config/mac/prepare_framework_version.py42
-rw-r--r--third_party/libwebrtc/build/config/mac/rules.gni628
8 files changed, 1026 insertions, 0 deletions
diff --git a/third_party/libwebrtc/build/config/mac/BUILD.gn b/third_party/libwebrtc/build/config/mac/BUILD.gn
new file mode 100644
index 0000000000..032c77ee34
--- /dev/null
+++ b/third_party/libwebrtc/build/config/mac/BUILD.gn
@@ -0,0 +1,136 @@
+# Copyright (c) 2013 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("//build/config/apple/symbols.gni")
+import("//build/config/c++/c++.gni")
+import("//build/config/mac/mac_sdk.gni")
+import("//build/config/sysroot.gni")
+
+# This is included by reference in the //build/config/compiler config that
+# is applied to all targets. It is here to separate out the logic.
+config("compiler") {
+ # These flags are shared between the C compiler and linker.
+ common_mac_flags = []
+
+ # CPU architecture.
+ if (target_cpu == "x64") {
+ clang_arch = "x86_64"
+ } else if (target_cpu == "x86") {
+ clang_arch = "i386"
+ } else if (target_cpu == "arm64") {
+ clang_arch = target_cpu
+ } else {
+ assert(false, "unknown target_cpu $target_cpu")
+ }
+ if (host_os == "mac") {
+ common_mac_flags += [
+ "-arch",
+ clang_arch,
+ ]
+ } else {
+ common_mac_flags += [ "--target=$clang_arch-apple-macos" ]
+ }
+
+ # This is here so that all files get recompiled after an Xcode update.
+ # (defines are passed via the command line, and build system rebuild things
+ # when their commandline changes). Nothing should ever read this define.
+ defines = [ "CR_XCODE_VERSION=$xcode_version" ]
+
+ asmflags = common_mac_flags
+ cflags = common_mac_flags
+
+ # Without this, the constructors and destructors of a C++ object inside
+ # an Objective C struct won't be called, which is very bad.
+ cflags_objcc = [ "-fobjc-call-cxx-cdtors" ]
+
+ ldflags = common_mac_flags
+
+ if (save_unstripped_output) {
+ ldflags += [ "-Wcrl,unstripped," + rebase_path(root_out_dir) ]
+ }
+
+ if (export_libcxxabi_from_executables) {
+ ldflags += [ "-Wl,-undefined,dynamic_lookup" ]
+ }
+}
+
+# This is included by reference in the //build/config/compiler:runtime_library
+# config that is applied to all targets. It is here to separate out the logic
+# that is Mac-only. Please see that target for advice on what should go in
+# :runtime_library vs. :compiler.
+config("runtime_library") {
+ common_flags = [
+ "-isysroot",
+ rebase_path(sysroot, root_build_dir),
+ "-mmacosx-version-min=$mac_deployment_target",
+ ]
+
+ asmflags = common_flags
+ cflags = common_flags
+ ldflags = common_flags
+
+ # Prevent Mac OS X AssertMacros.h (included by system header) from defining
+ # macros that collide with common names, like 'check', 'require', and
+ # 'verify'.
+ # http://opensource.apple.com/source/CarbonHeaders/CarbonHeaders-18.1/AssertMacros.h
+ defines = [ "__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES=0" ]
+}
+
+# On Mac, this is used for everything except static libraries.
+config("mac_dynamic_flags") {
+ ldflags = [ "-Wl,-ObjC" ] # Always load Objective-C categories and classes.
+
+ if (is_component_build) {
+ ldflags += [
+ # Path for loading shared libraries for unbundled binaries.
+ "-Wl,-rpath,@loader_path/.",
+
+ # Path for loading shared libraries for bundled binaries. Get back from
+ # Binary.app/Contents/MacOS.
+ "-Wl,-rpath,@loader_path/../../..",
+ ]
+ }
+}
+
+# The ldflags referenced below are handled by
+# //build/toolchain/apple/linker_driver.py.
+# Remove this config if a target wishes to change the arguments passed to the
+# strip command during linking. This config by default strips all symbols
+# from a binary, but some targets may wish to specify an exports file to
+# preserve specific symbols.
+config("strip_all") {
+ if (enable_stripping) {
+ ldflags = [ "-Wcrl,strip,-x,-S" ]
+ }
+}
+
+# When building with Goma, all inputs must be relative to the build directory.
+# If using the system Xcode, which typically resides outside the build root, a
+# symlink to the SDK is created in the build directory, and the path to that
+# link is stored in $mac_sdk_path. If an action references a file in the SDK as
+# an input, GN will complain that no target generates the file because it is
+# below the $root_build_dir. The below action lists as outputs the files in the
+# SDK that are referenced as inputs to actions, so that GN thinks a target has
+# generated them. The list is centralized here, as multiple targets need to
+# reference the same files, and an output can only be generated once.
+#
+# The symbolic link for $mac_sdk_path is set up by
+# //build/config/apple/sdk_info.py in //build/config/mac/mac_sdk.gni.
+if (use_system_xcode && use_goma && target_os == "mac" &&
+ current_toolchain == default_toolchain) {
+ action("sdk_inputs") {
+ script = "//build/noop.py"
+ outputs = [
+ "$mac_sdk_path/usr/include/mach/exc.defs",
+ "$mac_sdk_path/usr/include/mach/mach_exc.defs",
+ "$mac_sdk_path/usr/include/mach/notify.defs",
+ ]
+ }
+} else {
+ group("sdk_inputs") {
+ if (current_toolchain != default_toolchain) {
+ public_deps = [ ":sdk_inputs($default_toolchain)" ]
+ }
+ }
+}
diff --git a/third_party/libwebrtc/build/config/mac/BuildInfo.plist b/third_party/libwebrtc/build/config/mac/BuildInfo.plist
new file mode 100644
index 0000000000..bfa3b8d573
--- /dev/null
+++ b/third_party/libwebrtc/build/config/mac/BuildInfo.plist
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>DTCompiler</key>
+ <string>${GCC_VERSION}</string>
+ <key>DTSDKBuild</key>
+ <string>${MAC_SDK_BUILD}</string>
+ <key>DTSDKName</key>
+ <string>${MAC_SDK_NAME}</string>
+ <key>DTXcode</key>
+ <string>${XCODE_VERSION}</string>
+ <key>DTXcodeBuild</key>
+ <string>${XCODE_BUILD}</string>
+</dict>
+</plist>
diff --git a/third_party/libwebrtc/build/config/mac/OWNERS b/third_party/libwebrtc/build/config/mac/OWNERS
new file mode 100644
index 0000000000..6f3324f07c
--- /dev/null
+++ b/third_party/libwebrtc/build/config/mac/OWNERS
@@ -0,0 +1 @@
+file://build/apple/OWNERS
diff --git a/third_party/libwebrtc/build/config/mac/mac_sdk.gni b/third_party/libwebrtc/build/config/mac/mac_sdk.gni
new file mode 100644
index 0000000000..6671893ae8
--- /dev/null
+++ b/third_party/libwebrtc/build/config/mac/mac_sdk.gni
@@ -0,0 +1,127 @@
+# Copyright 2014 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("//build/config/chrome_build.gni")
+import("//build/config/gclient_args.gni")
+import("//build/config/mac/mac_sdk_overrides.gni")
+import("//build/toolchain/goma.gni")
+import("//build/toolchain/toolchain.gni")
+
+assert(current_os == "mac" || current_toolchain == default_toolchain)
+
+declare_args() {
+ # The MACOSX_DEPLOYMENT_TARGET variable used when compiling. This partially
+ # controls the minimum supported version of macOS for Chromium by
+ # affecting the symbol availability rules. This may differ from
+ # mac_min_system_version when dropping support for older macOSes but where
+ # additional code changes are required to be compliant with the availability
+ # rules.
+ # Must be of the form x.x.x for Info.plist files.
+ mac_deployment_target = "10.11.0"
+
+ # The value of the LSMinimmumSystemVersion in Info.plist files. This partially
+ # controls the minimum supported version of macOS for Chromium by
+ # affecting the Info.plist. This may differ from mac_deployment_target when
+ # dropping support for older macOSes. This should be greater than or equal to
+ # the mac_deployment_target version.
+ # Must be of the form x.x.x for Info.plist files.
+ mac_min_system_version = "10.11.0"
+
+ # Path to a specific version of the Mac SDK, not including a slash at the end.
+ # If empty, the path to the lowest version greater than or equal to
+ # mac_sdk_min is used.
+ mac_sdk_path = ""
+
+ # The SDK name as accepted by xcodebuild.
+ mac_sdk_name = "macosx"
+
+ # The SDK version used when making official builds. This is a single exact
+ # version, not a minimum. If this version isn't available official builds
+ # will fail.
+ mac_sdk_official_version = "11.3"
+
+ # Production builds should use hermetic Xcode. If you want to do production
+ # builds with system Xcode to test new SDKs, set this.
+ # Don't set this on any bots.
+ mac_allow_system_xcode_for_official_builds_for_testing = false
+}
+
+# Check that the version of macOS SDK used is the one requested when building
+# a version of Chrome shipped to the users. Disable the check if building for
+# iOS as the version macOS SDK used is not relevant for the tool build for the
+# host (they are not shipped) --- this is required as Chrome on iOS is usually
+# build with the latest version of Xcode that may not ship with the version of
+# the macOS SDK used to build Chrome on mac.
+# TODO(crbug.com/635745): the check for target_os should be replaced by a
+# check that current_toolchain is default_toolchain, and the file should
+# assert that current_os is "mac" once this file is no longer included by
+# iOS toolchains.
+if (is_chrome_branded && is_official_build && target_os != "ios") {
+ assert(!use_system_xcode ||
+ mac_allow_system_xcode_for_official_builds_for_testing,
+ "official branded builds should use hermetic xcode")
+}
+
+# The path to the hermetic install of Xcode. Only relevant when
+# use_system_xcode = false.
+if (!use_system_xcode) {
+ _hermetic_xcode_path = "//build/mac_files/xcode_binaries"
+}
+
+script_name = "//build/config/apple/sdk_info.py"
+sdk_info_args = []
+if (!use_system_xcode) {
+ sdk_info_args += [
+ "--developer_dir",
+ rebase_path(_hermetic_xcode_path, "", root_build_dir),
+ ]
+}
+
+# Goma RBE requires paths relative to source directory. When using system
+# Xcode, this is done by creating symbolic links in root_build_dir.
+if (use_system_xcode && use_goma) {
+ sdk_info_args += [
+ "--get_sdk_info",
+ "--create_symlink_at",
+ "sdk/xcode_links",
+ ]
+}
+sdk_info_args += [ mac_sdk_name ]
+
+#_mac_sdk_result = exec_script(script_name, sdk_info_args, "scope")
+#xcode_version = _mac_sdk_result.xcode_version
+#xcode_build = _mac_sdk_result.xcode_build
+if (mac_sdk_path == "" && use_system_xcode && use_goma) {
+ mac_sdk_path = _mac_sdk_result.sdk_path
+}
+
+if (use_system_xcode) {
+ # The tool will print the SDK path on the first line, and the version on the
+ # second line.
+ find_sdk_args = [
+ "--print_sdk_path",
+ "--print_bin_path",
+ mac_sdk_min,
+ ]
+ find_sdk_lines =
+ exec_script("//build/mac/find_sdk.py", find_sdk_args, "list lines")
+ mac_sdk_version = find_sdk_lines[2]
+ if (mac_sdk_path == "") {
+ mac_sdk_path = find_sdk_lines[0]
+ mac_bin_path = find_sdk_lines[1]
+ } else {
+ mac_bin_path = find_sdk_lines[1]
+ }
+} else {
+ mac_sdk_version = mac_sdk_official_version
+ _dev = _hermetic_xcode_path + "/Contents/Developer"
+ _sdk = "MacOSX${mac_sdk_version}.sdk"
+ mac_sdk_path = _dev + "/Platforms/MacOSX.platform/Developer/SDKs/$_sdk"
+ mac_bin_path = _dev + "/Toolchains/XcodeDefault.xctoolchain/usr/bin/"
+
+ # If we're using hermetic Xcode, then we want the paths to be relative so that
+ # generated ninja files are independent of the directory location.
+ # TODO(thakis): Do this at the uses of this variable instead.
+ mac_bin_path = rebase_path(mac_bin_path, root_build_dir)
+}
diff --git a/third_party/libwebrtc/build/config/mac/mac_sdk_overrides.gni b/third_party/libwebrtc/build/config/mac/mac_sdk_overrides.gni
new file mode 100644
index 0000000000..17eb3d9f62
--- /dev/null
+++ b/third_party/libwebrtc/build/config/mac/mac_sdk_overrides.gni
@@ -0,0 +1,16 @@
+# Copyright 2017 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.
+
+# This file contains arguments that subprojects may choose to override. It
+# asserts that those overrides are used, to prevent unused args warnings.
+
+_sdk_min_from_env = getenv("FORCE_MAC_SDK_MIN")
+declare_args() {
+ # Minimum supported version of the Mac SDK.
+ if (_sdk_min_from_env == "") {
+ mac_sdk_min = "10.15"
+ } else {
+ mac_sdk_min = _sdk_min_from_env
+ }
+}
diff --git a/third_party/libwebrtc/build/config/mac/package_framework.py b/third_party/libwebrtc/build/config/mac/package_framework.py
new file mode 100644
index 0000000000..0026f466b4
--- /dev/null
+++ b/third_party/libwebrtc/build/config/mac/package_framework.py
@@ -0,0 +1,60 @@
+# Copyright 2016 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 shutil
+import sys
+
+def Main():
+ parser = argparse.ArgumentParser(description='Create Mac Framework symlinks')
+ parser.add_argument('--framework', action='store', type=str, required=True)
+ parser.add_argument('--version', action='store', type=str)
+ parser.add_argument('--contents', action='store', type=str, nargs='+')
+ parser.add_argument('--stamp', action='store', type=str, required=True)
+ args = parser.parse_args()
+
+ VERSIONS = 'Versions'
+ CURRENT = 'Current'
+
+ # Ensure the Foo.framework/Versions/A/ directory exists and create the
+ # Foo.framework/Versions/Current symlink to it.
+ if args.version:
+ try:
+ os.makedirs(os.path.join(args.framework, VERSIONS, args.version), 0o755)
+ except OSError as e:
+ if e.errno != errno.EEXIST:
+ raise e
+ _Relink(os.path.join(args.version),
+ os.path.join(args.framework, VERSIONS, CURRENT))
+
+ # Establish the top-level symlinks in the framework bundle. The dest of
+ # the symlinks may not exist yet.
+ if args.contents:
+ for item in args.contents:
+ _Relink(os.path.join(VERSIONS, CURRENT, item),
+ os.path.join(args.framework, item))
+
+ # Write out a stamp file.
+ if args.stamp:
+ with open(args.stamp, 'w') as f:
+ f.write(str(args))
+
+ return 0
+
+
+def _Relink(dest, link):
+ """Creates a symlink to |dest| named |link|. If |link| already exists,
+ it is overwritten."""
+ try:
+ os.remove(link)
+ except OSError as e:
+ if e.errno != errno.ENOENT:
+ shutil.rmtree(link)
+ os.symlink(dest, link)
+
+
+if __name__ == '__main__':
+ sys.exit(Main())
diff --git a/third_party/libwebrtc/build/config/mac/prepare_framework_version.py b/third_party/libwebrtc/build/config/mac/prepare_framework_version.py
new file mode 100644
index 0000000000..db92150698
--- /dev/null
+++ b/third_party/libwebrtc/build/config/mac/prepare_framework_version.py
@@ -0,0 +1,42 @@
+# Copyright 2016 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 os
+import shutil
+import sys
+
+# Ensures that the current version matches the last-produced version, which is
+# stored in the version_file. If it does not, then the framework_root_dir is
+# obliterated.
+# Usage: python prepare_framework_version.py out/obj/version_file \
+# out/Framework.framework \
+# 'A'
+
+def PrepareFrameworkVersion(version_file, framework_root_dir, version):
+ # Test what the current framework version is. Stop if it is up-to-date.
+ try:
+ with open(version_file, 'r') as f:
+ current_version = f.read()
+ if current_version == version:
+ return
+ except IOError:
+ pass
+
+ # The framework version has changed, so clobber the framework.
+ if os.path.exists(framework_root_dir):
+ shutil.rmtree(framework_root_dir)
+
+ # Write out the new framework version file, making sure its containing
+ # directory exists.
+ dirname = os.path.dirname(version_file)
+ if not os.path.isdir(dirname):
+ os.makedirs(dirname, 0o700)
+
+ with open(version_file, 'w+') as f:
+ f.write(version)
+
+
+if __name__ == '__main__':
+ PrepareFrameworkVersion(sys.argv[1], sys.argv[2], sys.argv[3])
+ sys.exit(0)
diff --git a/third_party/libwebrtc/build/config/mac/rules.gni b/third_party/libwebrtc/build/config/mac/rules.gni
new file mode 100644
index 0000000000..7753a97fe7
--- /dev/null
+++ b/third_party/libwebrtc/build/config/mac/rules.gni
@@ -0,0 +1,628 @@
+# 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.
+
+import("//build/apple/apple_info_plist.gni")
+import("//build/config/apple/symbols.gni")
+import("//build/config/mac/mac_sdk.gni")
+
+# Generates Info.plist files for Mac apps and frameworks.
+#
+# Arguments
+#
+# info_plist:
+# (optional) string, path to the Info.plist file that will be used for
+# the bundle.
+#
+# info_plist_target:
+# (optional) string, if the info_plist is generated from an action,
+# rather than a regular source file, specify the target name in lieu
+# of info_plist. The two arguments are mutually exclusive.
+#
+# executable_name:
+# string, name of the generated target used for the product
+# and executable name as specified in the output Info.plist.
+#
+# extra_substitutions:
+# (optional) string array, 'key=value' pairs for extra fields which are
+# specified in a source Info.plist template.
+template("mac_info_plist") {
+ assert(defined(invoker.info_plist) != defined(invoker.info_plist_target),
+ "Only one of info_plist or info_plist_target may be specified in " +
+ target_name)
+
+ if (defined(invoker.info_plist)) {
+ _info_plist = invoker.info_plist
+ } else {
+ _info_plist_target_output = get_target_outputs(invoker.info_plist_target)
+ _info_plist = _info_plist_target_output[0]
+ }
+
+ apple_info_plist(target_name) {
+ format = "xml1"
+ extra_substitutions = []
+ if (defined(invoker.extra_substitutions)) {
+ extra_substitutions = invoker.extra_substitutions
+ }
+ extra_substitutions += [
+ "MAC_SDK_BUILD=$mac_sdk_version",
+ "MAC_SDK_NAME=$mac_sdk_name$mac_sdk_version",
+ "MACOSX_DEPLOYMENT_TARGET=$mac_deployment_target",
+ "CHROMIUM_MIN_SYSTEM_VERSION=$mac_min_system_version",
+ "XCODE_BUILD=$xcode_build",
+ "XCODE_VERSION=$xcode_version",
+ ]
+ plist_templates = [
+ "//build/config/mac/BuildInfo.plist",
+ _info_plist,
+ ]
+ if (defined(invoker.info_plist_target)) {
+ deps = [ invoker.info_plist_target ]
+ }
+ forward_variables_from(invoker,
+ [
+ "testonly",
+ "executable_name",
+ ])
+ }
+}
+
+# Template to package a shared library into a Mac framework bundle.
+#
+# By default, the bundle target this template generates does not link the
+# resulting framework into anything that depends on it. If a dependency wants
+# a link-time (as well as build-time) dependency on the framework bundle,
+# depend against "$target_name+link". If only the build-time dependency is
+# required (e.g., for copying into another bundle), then use "$target_name".
+#
+# Arguments
+#
+# framework_version:
+# string, version of the framework. Typically this is a
+# single letter, like "A".
+#
+# framework_contents:
+# list of string, top-level items in the framework. This is
+# the list of symlinks to create in the .framework directory that link
+# into Versions/Current/.
+#
+# info_plist:
+# (optional) string, path to the Info.plist file that will be used for
+# the bundle.
+#
+# info_plist_target:
+# (optional) string, if the info_plist is generated from an action,
+# rather than a regular source file, specify the target name in lieu
+# of info_plist. The two arguments are mutually exclusive.
+#
+# output_name:
+# (optional) string, name of the generated framework without the
+# .framework suffix. If omitted, defaults to target_name.
+#
+# extra_substitutions:
+# (optional) string array, 'key=value' pairs for extra fields which are
+# specified in a source Info.plist template.
+#
+# This template provides three targets for the resulting framework bundle. The
+# link-time behavior varies depending on which of the two targets below is
+# added as a dependency:
+# - $target_name only adds a build-time dependency. Targets that depend on
+# it will not link against the framework.
+# - $target_name+link adds a build-time and link-time dependency. Targets
+# that depend on it will link against the framework.
+# - $target_name+link_nested adds a build-time and link-time dependency, but
+# only on the shared library and not the fully-assembled framework bundle.
+# This should only be used for other nested binary components of the
+# framework bundle (e.g. Helpers) that themselves depend on the main shared
+# library of the framework bundle.
+#
+# The build-time-only dependency is used for when a target needs to use the
+# framework either only for resources, or because the target loads it at run-
+# time, via dlopen() or NSBundle. The link-time dependency will cause the
+# dependee to have the framework loaded by dyld at launch.
+#
+# Example of build-time only dependency:
+#
+# mac_framework_bundle("CoreTeleportation") {
+# sources = [ ... ]
+# }
+#
+# bundle_data("core_teleportation_bundle_data") {
+# deps = [ ":CoreTeleportation" ]
+# sources = [ "$root_out_dir/CoreTeleportation.framework" ]
+# outputs = [ "{{bundle_contents_dir}}/Frameworks/{{source_file_part}}" ]
+# }
+#
+# app_bundle("GoatTeleporter") {
+# sources = [ ... ]
+# deps = [
+# ":core_teleportation_bundle_data",
+# ]
+# }
+#
+# The GoatTeleporter.app will not directly link against
+# CoreTeleportation.framework, but it will be included in the bundle's
+# Frameworks directory.
+#
+# Example of link-time dependency:
+#
+# mac_framework_bundle("CoreTeleportation") {
+# sources = [ ... ]
+# ldflags = [
+# "-install_name",
+# "@executable_path/../Frameworks/$target_name.framework"
+# ]
+# }
+#
+# bundle_data("core_teleportation_bundle_data") {
+# deps = [ ":CoreTeleportation+link" ]
+# sources = [ "$root_out_dir/CoreTeleportation.framework" ]
+# outputs = [ "{{bundle_contents_dir}}/Frameworks/{{source_file_part}}" ]
+# }
+#
+# app_bundle("GoatTeleporter") {
+# sources = [ ... ]
+# deps = [
+# ":core_teleportation_bundle_data",
+# ]
+# }
+#
+# Note that the framework is still copied to the app's bundle, but dyld will
+# load this library when the app is launched because it uses the "+link"
+# target as a dependency. This also requires that the framework set its
+# install_name so that dyld can locate it.
+#
+# See "gn help shared_library" for more information on arguments supported
+# by shared library target.
+template("mac_framework_bundle") {
+ assert(defined(invoker.deps) || defined(invoker.public_deps),
+ "Dependencies must be specified for $target_name")
+ assert(invoker.framework_version != "", "framework_version is required")
+ assert(defined(invoker.framework_contents), "framework_contents is required")
+
+ _info_plist_target = target_name + "_info_plist"
+
+ mac_info_plist(_info_plist_target) {
+ executable_name = target_name
+ if (defined(invoker.output_name)) {
+ executable_name = invoker.output_name
+ }
+ forward_variables_from(invoker,
+ [
+ "extra_substitutions",
+ "info_plist",
+ "info_plist_target",
+ "testonly",
+ ])
+ }
+
+ _info_plist_bundle_data = _info_plist_target + "_bundle_data"
+
+ bundle_data(_info_plist_bundle_data) {
+ forward_variables_from(invoker, [ "testonly" ])
+ sources = get_target_outputs(":$_info_plist_target")
+ outputs = [ "{{bundle_resources_dir}}/Info.plist" ]
+ public_deps = [ ":$_info_plist_target" ]
+ }
+
+ _target_name = target_name
+ _output_name = target_name
+ if (defined(invoker.output_name)) {
+ _output_name = invoker.output_name
+ }
+
+ # Create a file to track the build dependency on the framework_version and
+ # framework_contents variables.
+ _framework_toc = [
+ "Version=" + invoker.framework_version,
+ _output_name,
+ ] + invoker.framework_contents
+ _framework_contents = [ _output_name ] + invoker.framework_contents
+ _framework_toc_file = "$target_out_dir/${target_name}.toc"
+ write_file(_framework_toc_file, _framework_toc)
+
+ # Create local variables for referencing different parts of the bundle.
+ _framework_target = _target_name
+ _framework_name = _output_name + ".framework"
+ _framework_base_dir = "$root_out_dir/$_framework_name"
+ _framework_root_dir =
+ _framework_base_dir + "/Versions/${invoker.framework_version}"
+
+ # Clean the entire framework if the framework_version changes.
+ _version_file = "$target_out_dir/${target_name}_version"
+ exec_script("//build/config/mac/prepare_framework_version.py",
+ [
+ rebase_path(_version_file),
+ rebase_path(_framework_base_dir),
+ invoker.framework_version,
+ ])
+
+ # Create the symlinks.
+ _framework_package_target = target_name + "_package"
+ action(_framework_package_target) {
+ script = "//build/config/mac/package_framework.py"
+
+ # The TOC file never needs to be read, since its contents are the values
+ # of GN variables. It is only used to trigger this rule when the values
+ # change.
+ inputs = [ _framework_toc_file ]
+
+ _stamp_file = "$target_out_dir/run_${_framework_package_target}.stamp"
+ outputs = [ _stamp_file ]
+
+ visibility = [ ":$_framework_target" ]
+
+ args = [
+ "--framework",
+ rebase_path(_framework_base_dir, root_build_dir),
+ "--stamp",
+ rebase_path(_stamp_file, root_build_dir),
+ "--version",
+ invoker.framework_version,
+ "--contents",
+ ] + _framework_contents
+
+ # It is not possible to list _framework_contents as outputs, since
+ # ninja does not properly stat symbolic links.
+ # https://github.com/ninja-build/ninja/issues/1186
+ }
+
+ _link_shared_library_target = target_name + "_shared_library"
+ _shared_library_bundle_data = target_name + "_shared_library_bundle_data"
+
+ shared_library(_link_shared_library_target) {
+ forward_variables_from(invoker,
+ "*",
+ [
+ "assert_no_deps",
+ "bundle_deps",
+ "code_signing_enabled",
+ "data_deps",
+ "info_plist",
+ "info_plist_target",
+ "output_name",
+ "visibility",
+ ])
+ visibility = [
+ ":$_shared_library_bundle_data",
+ ":${_framework_target}+link_nested",
+ ]
+ output_name = _output_name
+ output_prefix_override = true
+ output_extension = ""
+ output_dir = "$target_out_dir/$_link_shared_library_target"
+ }
+
+ bundle_data(_shared_library_bundle_data) {
+ visibility = [ ":$_framework_target" ]
+ forward_variables_from(invoker, [ "testonly" ])
+ sources = [ "$target_out_dir/$_link_shared_library_target/$_output_name" ]
+ outputs = [ "{{bundle_executable_dir}}/$_output_name" ]
+ public_deps = [ ":$_link_shared_library_target" ]
+ }
+
+ _framework_public_config = _target_name + "_public_config"
+ config(_framework_public_config) {
+ visibility = [ ":$_framework_target+link" ]
+ framework_dirs = [ root_out_dir ]
+ frameworks = [ _framework_name ]
+ }
+
+ create_bundle(_framework_target) {
+ forward_variables_from(invoker,
+ [
+ "data_deps",
+ "deps",
+ "public_deps",
+ "testonly",
+ ])
+
+ if (defined(invoker.visibility)) {
+ visibility = invoker.visibility
+ visibility += [ ":$_target_name+link" ]
+ }
+
+ if (!defined(deps)) {
+ deps = []
+ }
+ deps += [ ":$_info_plist_bundle_data" ]
+
+ if (defined(invoker.bundle_deps)) {
+ deps += invoker.bundle_deps
+ }
+
+ if (!defined(public_deps)) {
+ public_deps = []
+ }
+ public_deps += [
+ ":$_framework_package_target",
+ ":$_shared_library_bundle_data",
+ ]
+
+ if (enable_dsyms) {
+ data = [
+ "$root_out_dir/$_output_name.dSYM/Contents/Info.plist",
+ "$root_out_dir/$_output_name.dSYM/Contents/Resources/DWARF/$_output_name",
+ ]
+ }
+
+ bundle_root_dir = _framework_base_dir
+ bundle_contents_dir = _framework_root_dir
+ bundle_resources_dir = "$bundle_contents_dir/Resources"
+ bundle_executable_dir = bundle_contents_dir
+ }
+
+ group(_target_name + "+link") {
+ forward_variables_from(invoker,
+ [
+ "public_configs",
+ "testonly",
+ "visibility",
+ ])
+ public_deps = [ ":$_target_name" ]
+ if (!defined(public_configs)) {
+ public_configs = []
+ }
+ public_configs += [ ":$_framework_public_config" ]
+ }
+
+ group(_target_name + "+link_nested") {
+ forward_variables_from(invoker,
+ [
+ "public_configs",
+ "testonly",
+ "visibility",
+ ])
+
+ # Depend only on the shared library. Nested code will be a dependency of
+ # the create_bundle target, which would be cyclic with depending on the
+ # framework itself. This is sufficient to link; for loading, a proper
+ # install_name should be set.
+ public_deps = [ ":$_link_shared_library_target" ]
+ }
+}
+
+set_defaults("mac_framework_bundle") {
+ configs = default_shared_library_configs
+}
+
+# Template to create a Mac executable application bundle.
+#
+# Arguments
+#
+# package_type:
+# (optional) string, the product package type to create. Options are:
+# "app" to create a .app bundle (default)
+# "xpc" to create an .xpc service bundle
+#
+# info_plist:
+# (optional) string, path to the Info.plist file that will be used for
+# the bundle.
+#
+# info_plist_target:
+# (optional) string, if the info_plist is generated from an action,
+# rather than a regular source file, specify the target name in lieu
+# of info_plist. The two arguments are mutually exclusive.
+#
+# output_name:
+# (optional) string, name of the generated app without the
+# .app suffix. If omitted, defaults to target_name.
+#
+# extra_configs:
+# (optional) list of label, additional configs to apply to the
+# executable target.
+#
+# remove_configs:
+# (optional) list of label, default configs to remove from the target.
+#
+# extra_substitutions:
+# (optional) string array, 'key=value' pairs for extra fields which are
+# specified in a source Info.plist template.
+template("mac_app_bundle") {
+ _target_name = target_name
+ _output_name = target_name
+ if (defined(invoker.output_name)) {
+ _output_name = invoker.output_name
+ }
+
+ _package_type = "app"
+ if (defined(invoker.package_type)) {
+ _package_type = invoker.package_type
+ }
+
+ if (_package_type == "app") {
+ _output_extension = "app"
+ _product_type = "com.apple.product-type.application"
+ _write_pkg_info = true
+ } else if (_package_type == "xpc") {
+ _output_extension = "xpc"
+ _product_type = "com.apple.product-type.xpc-service"
+ _write_pkg_info = false
+ } else if (_package_type == "bundle") {
+ _output_extension = "bundle"
+ _product_type = "com.apple.product-type.bundle"
+ _write_pkg_info = false
+ } else {
+ assert(false, "Unsupported packge_type: " + packge_type)
+ }
+
+ _executable_target = target_name + "_executable"
+ _executable_bundle_data = _executable_target + "_bundle_data"
+
+ _info_plist_target = target_name + "_info_plist"
+
+ mac_info_plist(_info_plist_target) {
+ executable_name = _output_name
+ forward_variables_from(invoker,
+ [
+ "extra_substitutions",
+ "info_plist",
+ "info_plist_target",
+ "testonly",
+ ])
+ }
+
+ if (_write_pkg_info) {
+ _pkg_info_target = target_name + "_pkg_info"
+
+ action(_pkg_info_target) {
+ forward_variables_from(invoker, [ "testonly" ])
+ script = "//build/apple/write_pkg_info.py"
+ inputs = [ "//build/apple/plist_util.py" ]
+ sources = get_target_outputs(":$_info_plist_target")
+ outputs = [ "$target_gen_dir/$_pkg_info_target" ]
+ args = [ "--plist" ] + rebase_path(sources, root_build_dir) +
+ [ "--output" ] + rebase_path(outputs, root_build_dir)
+ deps = [ ":$_info_plist_target" ]
+ }
+ }
+
+ executable(_executable_target) {
+ visibility = [ ":$_executable_bundle_data" ]
+ forward_variables_from(invoker,
+ "*",
+ [
+ "assert_no_deps",
+ "data_deps",
+ "info_plist",
+ "output_name",
+ "visibility",
+ ])
+ if (defined(extra_configs)) {
+ configs += extra_configs
+ }
+ if (defined(remove_configs)) {
+ configs -= remove_configs
+ }
+ output_name = _output_name
+ output_dir = "$target_out_dir/$_executable_target"
+ }
+
+ bundle_data(_executable_bundle_data) {
+ visibility = [ ":$_target_name" ]
+ forward_variables_from(invoker, [ "testonly" ])
+ sources = [ "$target_out_dir/$_executable_target/$_output_name" ]
+ outputs = [ "{{bundle_executable_dir}}/$_output_name" ]
+ public_deps = [ ":$_executable_target" ]
+ }
+
+ _info_plist_bundle_data = _info_plist_target + "_bundle_data"
+
+ bundle_data(_info_plist_bundle_data) {
+ forward_variables_from(invoker, [ "testonly" ])
+ visibility = [ ":$_target_name" ]
+ sources = get_target_outputs(":$_info_plist_target")
+ outputs = [ "{{bundle_contents_dir}}/Info.plist" ]
+ public_deps = [ ":$_info_plist_target" ]
+ }
+
+ if (_write_pkg_info) {
+ _pkg_info_bundle_data = _pkg_info_target + "_bundle_data"
+
+ bundle_data(_pkg_info_bundle_data) {
+ forward_variables_from(invoker, [ "testonly" ])
+ visibility = [ ":$_target_name" ]
+ sources = get_target_outputs(":$_pkg_info_target")
+ outputs = [ "{{bundle_contents_dir}}/PkgInfo" ]
+ public_deps = [ ":$_pkg_info_target" ]
+ }
+ }
+
+ create_bundle(_target_name) {
+ forward_variables_from(invoker,
+ [
+ "data_deps",
+ "deps",
+ "public_deps",
+ "testonly",
+ ])
+ if (!defined(deps)) {
+ deps = []
+ }
+ deps += [
+ ":$_executable_bundle_data",
+ ":$_info_plist_bundle_data",
+ ]
+ if (_write_pkg_info) {
+ deps += [ ":$_pkg_info_bundle_data" ]
+ }
+
+ if (enable_dsyms) {
+ data = [
+ "$root_out_dir/$_output_name.dSYM/Contents/Info.plist",
+ "$root_out_dir/$_output_name.dSYM/Contents/Resources/DWARF/$_output_name",
+ ]
+ }
+
+ product_type = _product_type
+ bundle_root_dir = "$root_out_dir/${_output_name}.${_output_extension}"
+ bundle_contents_dir = "$bundle_root_dir/Contents"
+ bundle_resources_dir = "$bundle_contents_dir/Resources"
+ bundle_executable_dir = "$bundle_contents_dir/MacOS"
+ }
+}
+
+# Template to package a loadable_module into a .plugin bundle.
+#
+# This takes no extra arguments that differ from a loadable_module.
+template("mac_plugin_bundle") {
+ assert(defined(invoker.deps),
+ "Dependencies must be specified for $target_name")
+
+ _target_name = target_name
+ _loadable_module_target = _target_name + "_loadable_module"
+ _loadable_module_bundle_data = _loadable_module_target + "_bundle_data"
+
+ _output_name = _target_name
+ if (defined(invoker.output_name)) {
+ _output_name = invoker.output_name
+ }
+
+ loadable_module(_loadable_module_target) {
+ visibility = [ ":$_loadable_module_bundle_data" ]
+ forward_variables_from(invoker,
+ "*",
+ [
+ "assert_no_deps",
+ "data_deps",
+ "output_name",
+ "visibility",
+ ])
+ output_dir = "$target_out_dir"
+ output_name = _output_name
+ }
+
+ bundle_data(_loadable_module_bundle_data) {
+ forward_variables_from(invoker, [ "testonly" ])
+ visibility = [ ":$_target_name" ]
+ sources = [ "$target_out_dir/$_output_name.so" ]
+ outputs = [ "{{bundle_executable_dir}}/$_output_name" ]
+ public_deps = [ ":$_loadable_module_target" ]
+ }
+
+ create_bundle(_target_name) {
+ forward_variables_from(invoker,
+ [
+ "data_deps",
+ "deps",
+ "public_deps",
+ "testonly",
+ "visibility",
+ ])
+ if (!defined(deps)) {
+ deps = []
+ }
+ deps += [ ":$_loadable_module_bundle_data" ]
+
+ if (enable_dsyms) {
+ data = [
+ "$root_out_dir/$_output_name.so.dSYM/Contents/Info.plist",
+ "$root_out_dir/$_output_name.so.dSYM/Contents/Resources/DWARF/$_output_name.so",
+ ]
+ }
+
+ bundle_root_dir = "$root_out_dir/$_output_name.plugin"
+ bundle_contents_dir = "$bundle_root_dir/Contents"
+ bundle_executable_dir = "$bundle_contents_dir/MacOS"
+ }
+}