216 lines
6.7 KiB
Python
216 lines
6.7 KiB
Python
# Copyright (c) 2024 The Chromium Embedded Framework Authors. All rights
|
|
# reserved. Use of this source code is governed by a BSD-style license that
|
|
# can be found in the LICENSE file.
|
|
|
|
load("@bazel_skylib//rules:expand_template.bzl", "expand_template")
|
|
load("@build_bazel_rules_apple//apple:macos.bzl", "macos_application")
|
|
load("//bazel:variables.bzl", "VERSION_PLIST")
|
|
load("//bazel/mac:variables.bzl",
|
|
"MACOS_DEPLOYMENT_TARGET",
|
|
"MACOS_BUNDLE_ID_BASE",
|
|
"CEF_FRAMEWORK_NAME",
|
|
"COMMON_LINKOPTS")
|
|
|
|
def _declare_helper_app(name, info_plist, deps, helper_base_name, helper_suffix, **kwargs):
|
|
"""
|
|
Creates a Helper .app target.
|
|
"""
|
|
helper_name = "{} Helper".format(name)
|
|
bundle_id_suffix = ""
|
|
|
|
if helper_suffix:
|
|
helper_name += " ({})".format(helper_suffix)
|
|
bundle_id_suffix += ".{}".format(helper_suffix.lower())
|
|
|
|
# Helper app bundle Info.plist.
|
|
expand_template(
|
|
name = "{}_InfoPList".format(helper_base_name),
|
|
template = info_plist,
|
|
out = "{}Info.plist".format(helper_base_name),
|
|
substitutions = {
|
|
"${EXECUTABLE_NAME}": helper_name,
|
|
"${PRODUCT_NAME}": name,
|
|
"${BUNDLE_ID_SUFFIX}": bundle_id_suffix,
|
|
"${VERSION_SHORT}": VERSION_PLIST,
|
|
"${VERSION_LONG}": VERSION_PLIST,
|
|
},
|
|
)
|
|
|
|
# Helper app bundle.
|
|
macos_application(
|
|
name = helper_base_name,
|
|
bundle_name = helper_name,
|
|
bundle_id = "{}.{}.helper{}".format(MACOS_BUNDLE_ID_BASE, name.lower(), bundle_id_suffix),
|
|
infoplists = [":{}_InfoPList".format(helper_base_name)],
|
|
minimum_os_version = MACOS_DEPLOYMENT_TARGET,
|
|
deps = deps,
|
|
**kwargs,
|
|
)
|
|
|
|
HELPERS = {
|
|
"HelperBase": "",
|
|
"HelperAlerts": "Alerts",
|
|
"HelperGPU": "GPU",
|
|
"HelperPlugin": "Plugin",
|
|
"HelperRenderer": "Renderer",
|
|
}
|
|
|
|
def declare_all_helper_apps(name, info_plist, deps, **kwargs):
|
|
"""
|
|
Creates all Helper .app targets.
|
|
"""
|
|
[_declare_helper_app(
|
|
name = name,
|
|
info_plist = info_plist,
|
|
deps = deps,
|
|
helper_base_name = h,
|
|
helper_suffix = v,
|
|
**kwargs,
|
|
) for h, v in HELPERS.items()]
|
|
|
|
def _macos_app_with_cef_framework_impl(ctx):
|
|
"""Add versioned CEF framework directory with symlinks in app bundle."""
|
|
base_app = ctx.files.base_app[0]
|
|
final_app = ctx.actions.declare_directory(ctx.attr.name + ".app")
|
|
|
|
script = ctx.actions.declare_file("fix_cef_symlinks.sh")
|
|
ctx.actions.write(
|
|
output = script,
|
|
content = """#!/bin/bash
|
|
set -euo pipefail
|
|
|
|
BASE_APP="{base_app}"
|
|
FINAL_APP="{final_app}"
|
|
CEF_SRC="{cef_src}"
|
|
CEF_FRAMEWORK_NAME="{cef_framework_name}"
|
|
|
|
# Extract the base app bundle (it's a zip file).
|
|
TEMP_DIR="$(dirname "$FINAL_APP")/temp_extract"
|
|
mkdir -p "$TEMP_DIR"
|
|
unzip -q "$BASE_APP" -d "$TEMP_DIR"
|
|
# Find the .app directory that was extracted and move its contents.
|
|
EXTRACTED_APP=$(find "$TEMP_DIR" -name "*.app" -type d | head -1)
|
|
mkdir -p "$FINAL_APP"
|
|
cp -R "$EXTRACTED_APP"/* "$FINAL_APP"/
|
|
rm -rf "$TEMP_DIR"
|
|
|
|
# Copy the CEF framework to the versioned directory in the app bundle.
|
|
FRAMEWORK_DIR="$FINAL_APP/Contents/Frameworks/$CEF_FRAMEWORK_NAME.framework"
|
|
mkdir -p "$FRAMEWORK_DIR/Versions"
|
|
cp -R -L "$CEF_SRC" "$FRAMEWORK_DIR/Versions/A"
|
|
|
|
# Create the necessary symlinks.
|
|
cd "$FRAMEWORK_DIR"
|
|
ln -sf "Versions/A/Chromium Embedded Framework" "Chromium Embedded Framework"
|
|
ln -sf "Versions/A/Libraries" "Libraries"
|
|
ln -sf "Versions/A/Resources" "Resources"
|
|
cd "Versions"
|
|
ln -sf "A" "Current"
|
|
""".format(
|
|
base_app = base_app.path,
|
|
final_app = final_app.path,
|
|
cef_src = ctx.files.cef_framework[0].path,
|
|
cef_framework_name = ctx.attr.cef_framework_name,
|
|
),
|
|
is_executable = True,
|
|
)
|
|
|
|
ctx.actions.run(
|
|
inputs = [base_app] + ctx.files.cef_framework + [script],
|
|
outputs = [final_app],
|
|
executable = script,
|
|
mnemonic = "AddCEFFrameworkWithSymlinks",
|
|
progress_message = "Add CEF framework with symlinks in app bundle",
|
|
)
|
|
|
|
# Create a launcher script for use by bazel run.
|
|
launcher = ctx.actions.declare_file(ctx.label.name)
|
|
ctx.actions.write(
|
|
output = launcher,
|
|
content = """#!/bin/bash
|
|
# App bundle is in the same directory as this script.
|
|
SCRIPT_DIR="$(dirname "$0")"
|
|
APP_PATH="$SCRIPT_DIR/{}.app"
|
|
|
|
if [[ -d "$APP_PATH" ]]; then
|
|
open "$APP_PATH"
|
|
else
|
|
echo "Error: App bundle not found at $APP_PATH"
|
|
exit 1
|
|
fi
|
|
""".format(ctx.label.name),
|
|
is_executable = True,
|
|
)
|
|
|
|
return [DefaultInfo(files = depset([final_app]), executable = launcher)]
|
|
|
|
_macos_app_with_cef_framework = rule(
|
|
implementation = _macos_app_with_cef_framework_impl,
|
|
executable = True,
|
|
attrs = {
|
|
"base_app": attr.label(
|
|
mandatory = True,
|
|
allow_files = True,
|
|
doc = "The base app bundle to post-process",
|
|
),
|
|
"cef_framework": attr.label(
|
|
mandatory = True,
|
|
allow_files = True,
|
|
doc = "The CEF framework source",
|
|
),
|
|
"cef_framework_name": attr.string(
|
|
mandatory = True,
|
|
doc = "Name of the CEF framework",
|
|
),
|
|
},
|
|
doc = "Post-processes app bundle to fix CEF framework symlinks",
|
|
)
|
|
|
|
def declare_main_app(name, info_plist, deps, resources, linkopts=[], **kwargs):
|
|
"""
|
|
Creates the main .app target.
|
|
"""
|
|
|
|
# Main app bundle Info.plist.
|
|
expand_template(
|
|
name = "InfoPList",
|
|
template = info_plist,
|
|
out = "Info.plist",
|
|
substitutions = {
|
|
"${EXECUTABLE_NAME}": name,
|
|
"${PRODUCT_NAME}": name,
|
|
"${VERSION_SHORT}": VERSION_PLIST,
|
|
"${VERSION_LONG}": VERSION_PLIST,
|
|
},
|
|
)
|
|
|
|
# Create base app bundle without CEF framework directory.
|
|
macos_application(
|
|
name = name + "_base",
|
|
additional_contents = {
|
|
":HelperBase": "Frameworks",
|
|
":HelperAlerts": "Frameworks",
|
|
":HelperGPU": "Frameworks",
|
|
":HelperPlugin": "Frameworks",
|
|
":HelperRenderer": "Frameworks",
|
|
},
|
|
bundle_name = name,
|
|
bundle_id = "{}.{}".format(MACOS_BUNDLE_ID_BASE, name.lower()),
|
|
infoplists = [":InfoPList"],
|
|
linkopts = COMMON_LINKOPTS + linkopts,
|
|
minimum_os_version = MACOS_DEPLOYMENT_TARGET,
|
|
resources = resources,
|
|
target_compatible_with = [
|
|
"@platforms//os:macos",
|
|
],
|
|
deps = deps,
|
|
**kwargs,
|
|
)
|
|
|
|
# Post-process to add versioned CEF framework directory with symlinks.
|
|
_macos_app_with_cef_framework(
|
|
name = name,
|
|
base_app = ":" + name + "_base",
|
|
cef_framework = "@cef//:cef_framework",
|
|
cef_framework_name = CEF_FRAMEWORK_NAME,
|
|
)
|