blob: 32e5f3cea387606b1792f3b73d62d719f3364003 [file] [log] [blame]
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Copyright (C) 2019 Apple Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# BaseGenerator is the base class for generating new .xcfilelist content. Most
# of the implementation is provided in this base class. Subclasses are created
# to provide project-specific information, such as the path to the project file
# and valid platform and configuration information.
#
# Instances of this class are create for each project/platform/configuration
# triple. For each triple, .xcfilelist content is generated and compared to the
# file that ultimately will contain that information. Any new lines are
# determined and remembered for later addition to that destination file.
#
# Instances of this class can operate in either of two contexts. First, it's
# possible for Xcode projects to invoke this script in order to keep their
# .xcfilelist files up-to-date. In that case, this script starts out running in
# the context of Xcode and it can just go ahead and generate the new content.
# Alternatively, it's possible for someone to invoke this script from the
# command line. In that case, this script needs to sublaunch itself in order to
# expose itself to the environment variables that Xcode establishes during
# builds. This script thus starts out as a free-standing script, creates a
# BaseGenerator for the .xcfilelist content it needs to create, sub-launches
# itself, and then creates another BaseGenerator to do the actual generation.
# When this inner instance of the script exits, it writes the results of the
# BaseGenerators to a temporary file. When the outer instance of the script
# resumes, it reads the information from that temporary file. That information
# is actually just a serialized (pickled) BaseGenerator instance and is
# restored as such. This restored BaseGenerator now replaces the original
# BaseGenerator in the outer script that caused it to be created, since the
# inner one is the one with all the xcfilelist information.
from __future__ import print_function
import os
import pickle
import tempfile
import traceback
import webkitpy.generate_xcfilelists_lib.util as util
from webkitpy.xcode import xcode_hash_for_path
from webkitpy.xcode.sdk import SDK
from webkitpy.common.attribute_saver import AttributeSaver
class BaseGenerator(object):
__slots__ = (
"application", "project_tag", "platform", "configuration", "triple",
"ex_type", "ex_value", "ex_traceback",
"added_lines_input_derived", "added_lines_output_derived", "added_lines_input_unified", "added_lines_output_unified",
"cached_build_dirs")
VALID_PLATFORMS = None
VALID_CONFIGURATIONS = None
@util.LogEntryExit
def __init__(self, application, project_tag, platform, configuration):
self.application = application
self.project_tag = project_tag
self.platform = platform
self.configuration = configuration
self.triple = (project_tag, platform, configuration)
self.ex_type = None
self.ex_value = None
self.ex_traceback = None
self.added_lines_input_derived = None
self.added_lines_output_derived = None
self.added_lines_input_unified = None
self.added_lines_output_unified = None
self.cached_build_dirs = None
def __str__(self):
return "project_tag = {}, platform = {}, configuration = {}, ex_type = {}, ex_value = {}, ex_traceback = {}, added_lines_input_derived = {}, added_lines_output_derived = {}, added_lines_input_unified = {}, added_lines_output_unified = {}, cached_build_dirs = {}".format(
self.project_tag, self.platform, self.configuration,
self.ex_type, self.ex_value, self.ex_traceback,
self.added_lines_input_derived, self.added_lines_output_derived, self.added_lines_input_unified, self.added_lines_output_unified,
self.cached_build_dirs)
# Generate new .xcfilist list contents and return any new lines. This
# generation is performed by relaunching ourselves under Xcode so that we
# can operate in the context of its environment variables. When we relaunch
# ourselves, we do so in a way that invokes this class's generate()
# method. Any results from generate are written to a temporary file that
# we set up here. When the relaunched instance completes, we reads those
# results from the temporary file.
@util.LogEntryExit
def set_environment_and_generate(self):
with tempfile.NamedTemporaryFile() as pickle_file, tempfile.NamedTemporaryFile() as debug_file:
sublaunch_args = [
"PATH=\"{}:${{PATH}}\"".format(self._getenv("PATH")), # Xcode will "sanitize" PATH, such that Python is no longer on it, so get /usr/bin back in PATH.
"PYTHONPATH=\"{}\"".format(self._getenv("PYTHONPATH", "")),
self.application.get_generate_xcfilelists_script_path(),
"generate-inner",
"--project", self.project_tag,
"--platform", self.platform,
"--configuration", self.configuration,
"--pickle-file", pickle_file.name]
if self.application.cmd_line_args.debug:
sublaunch_args += [
"--debug",
"--debug-file", debug_file.name]
if self.application.cmd_line_args.quiet:
sublaunch_args.append("--quiet")
try:
self._sublaunch_under_xcode(sublaunch_args)
finally:
# If xcodebuild returns an error, we want to at least display the
# debugging information.
if self.application.cmd_line_args.debug:
for line in debug_file:
util.debug_log("{}".format(line.rstrip()))
generators = []
while True:
try:
generator = pickle.load(pickle_file)
generator.application = self.application
generators.append(generator)
except EOFError as e:
break
return generators
# Relaunch this script under Xcode. This is performed by launching Xcode,
# pointing it to the project that we are processing as well as a build
# target that will re-execute us as a custom build step.
@util.LogEntryExit
def _sublaunch_under_xcode(self, sublaunch_args):
xcode_parameters = [
"xcodebuild",
"-project", self._get_project_file_path(),
"-sdk", SDK.get_preferred_sdk_for_platform(self.platform).as_xcode_specification(),
"-configuration", self.configuration,
"-target", "Apply Configuration to XCFileLists",
"SYMROOT={}".format(self._get_sym_root()),
"OBJROOT={}".format(self._get_obj_root()),
"SHARED_PRECOMPS_DIR={}".format(self._get_shared_precomps_dir())]
# TODO: sublaunch_args will contain the path to the script to
# sublaunch. There might be a problem if there's a space in that path.
util.subprocess_run(xcode_parameters,
env={"WK_SUBLAUNCH_SCRIPT_PARAMETERS": " ".join(sublaunch_args)})
# Generate the .xcfilelist content. Save the results internally as sets of
# new lines to be added to the .xcfilelist files. These new lines can be
# merged into those files if the user specified a "generate" command, or
# can be reported in a "check" command.
@util.LogEntryExit
def generate(self):
self._generate_derived()
self._generate_unified()
# Merge any saved added lines to their ultimate destinations.
@util.LogEntryExit
def merge(self):
self._merge_derived()
self._merge_unified()
@util.LogEntryExit
def pickle_to_file(self, f):
# We don't want to pickle the application reference
# We can't seem to pickle ex_traceback: PicklingError: Can't pickle <type 'traceback'>: it's not found as __builtin__.traceback
with AttributeSaver(self, "application"), AttributeSaver(self, "ex_traceback"):
pickle.dump(self, f, pickle.HIGHEST_PROTOCOL)
# Return whether or not any new lines for any .xcfilelist files were
# discovered.
@util.LogEntryExit
def has_action(self):
return (self.added_lines_input_derived or
self.added_lines_output_derived or
self.added_lines_input_unified or
self.added_lines_output_unified)
# If any errors occur during the generation of .xcfilelist content, they
# are remembered internally for later processing. This function returns
# whether or not any such error occurred with this generator.
@util.LogEntryExit
def has_error(self):
return self.ex_type
# Return whether or not the combination of project, platform, and
# configuration is valid (which is to say, if, for example, the given
# project can be built for the given platform and configuration).
@util.LogEntryExit
def is_valid(self):
return (self.platform in self.__class__.VALID_PLATFORMS and
self.configuration in self.__class__.VALID_CONFIGURATIONS)
# If an error/exception occurred and was recorded (that is, if has_error()
# returns true), report that error to the console.
@util.LogEntryExit
def report_error(self):
try:
if self.ex_value:
raise self.ex_value
except KeyboardInterrupt:
print("### Canceled")
except util.CalledProcessError as e:
print("### Error {} calling subprocess: {}".format(e.args[0], e.args[1]))
if e.args[2]:
print("### stdout = {}".format(e.args[2]))
if e.args[3]:
print("### stderr = {}".format(e.args[3]))
except util.InvalidConfigurationError as e:
print("### Invalid configuration: {}".format(e))
return os.EX_USAGE
except BaseException:
traceback.print_exception(self.ex_type, self.ex_value, self.ex_traceback)
return os.EX_SOFTWARE
# Generate .xcfilelist content for the "Generate Derived Sources" build
# phase.
@util.LogEntryExit
def _generate_derived(self):
script = self._get_generate_derived_sources_script()
if not script:
return
with tempfile.NamedTemporaryFile() as input, tempfile.NamedTemporaryFile() as output:
(stdout, stderr) = util.subprocess_run(
[script,
"NO_SUPPLEMENTAL_FILES=1",
"--no-builtin-rules",
"--dry-run",
"--always-make",
"--debug=abvijm",
"all"])
stdout = stdout.encode() if isinstance(stdout, str) else stdout
(stdout, stderr) = util.subprocess_run(
[self.application.get_extract_dependencies_from_makefile_script(),
"--input", input.name,
"--output", output.name],
input=stdout)
# TODO: Make this generator-specific (there's no need to reference
# WebCore, for example, when processing the JavaScriptCore
# project).
self._replace(input.name, "^JavaScriptCore/", "$(PROJECT_DIR)/")
self._replace(input.name, "^JavaScriptCorePrivateHeaders/", "$(JAVASCRIPTCORE_PRIVATE_HEADERS_DIR)/")
self._replace(input.name, "^WebCore/", "$(PROJECT_DIR)/")
self._replace(input.name, "^WebKit2PrivateHeaders/", "$(WEBKIT2_PRIVATE_HEADERS_DIR)/")
self._unexpand(input.name, "JAVASCRIPTCORE_PRIVATE_HEADERS_DIR")
self._unexpand(input.name, "PROJECT_DIR")
self._unexpand(input.name, "WEBCORE_PRIVATE_HEADERS_DIR")
self._unexpand(input.name, "WEBKIT2_PRIVATE_HEADERS_DIR")
self._unexpand(input.name, "WEBKITADDITIONS_HEADERS_FOLDER_PATH")
self._unexpand(input.name, "BUILT_PRODUCTS_DIR") # Do this last, since it's a prefix of some other variables and will "intercept" them if executed earlier than them.
self._replace(output.name, "^", self._get_derived_sources_dir() + "/")
self._unexpand(output.name, "BUILT_PRODUCTS_DIR")
self.added_lines_input_derived = self._find_added_lines(input.name, self._get_input_derived_xcfilelist_project_path())
self.added_lines_output_derived = self._find_added_lines(output.name, self._get_output_derived_xcfilelist_project_path())
@util.LogEntryExit
def _merge_derived(self):
self._merge_added_lines(self.added_lines_input_derived, self._get_input_derived_xcfilelist_project_path())
self._merge_added_lines(self.added_lines_output_derived, self._get_output_derived_xcfilelist_project_path())
# Generate .xcfilelist content for the "Generate Unified Sources" build
# phase.
@util.LogEntryExit
def _generate_unified(self):
script = self._get_generate_unified_sources_script()
if not script:
return
with tempfile.NamedTemporaryFile() as output:
# We need to define BUILD_SCRIPTS_DIR so that the bash script we're
# invoking can find the ruby script that it invokes. If we don't
# define BUILD_SCRIPTS_DIR, the bash script we're invoking with try
# to define its own value for BUILD_SCRIPTS_DIR, but it will do so
# incorrectly for our purposes, leading to dire results.
env = os.environ.copy()
env["BUILD_SCRIPTS_DIR"] = self.application.get_build_scripts_dir()
util.subprocess_run(
[script,
"--generate-xcfilelists",
"--output-xcfilelist-path", output.name],
env=env)
self._unexpand(output.name, "BUILT_PRODUCTS_DIR")
self.added_lines_input_unified = self._find_added_lines(None, self._get_input_unified_xcfilelist_project_path())
self.added_lines_output_unified = self._find_added_lines(output.name, self._get_output_unified_xcfilelist_project_path())
@util.LogEntryExit
def _merge_unified(self):
self._merge_added_lines(self.added_lines_input_unified, self._get_input_unified_xcfilelist_project_path())
self._merge_added_lines(self.added_lines_output_unified, self._get_output_unified_xcfilelist_project_path())
# Utility for post-processing the initial .xcfilelist content. Used to
# replace text in the file.
@util.LogEntryExit
def _replace(self, file_name, to_replace, replace_with):
util.subprocess_run([
"sed", "-E", "-e",
"s|{}|{}|".format(to_replace, replace_with),
"-i", "''", file_name])
# Utility for post-processing the initial .xcfilelist content. Used to
# replace file path segments with the variables that represent those path
# segments.
@util.LogEntryExit
def _unexpand(self, file_name, variable_name):
to_replace = self._getenv(variable_name)
if not to_replace:
return
self._replace(file_name, "^{}/".format(to_replace), "$({})/".format(variable_name))
# Given a source file with new .xcfilelist content and a dest file that
# contains the original/previous .xcfilelist content (that is, likely the
# file that's checked into the repo), determine what, if any, new lines
# there are in source that aren't in dest.
@util.LogEntryExit
def _find_added_lines(self, source, dest):
if not source:
return set()
source_lines = set(source) if isinstance(source, list) else self._get_file_lines(source)
dest_lines = set(dest) if isinstance(dest, list) else self._get_file_lines(dest)
delta_lines = source_lines - dest_lines
return delta_lines
# Bottleneck routine for taking a set of new lines of .xcfilelist content
# and adding them to their ultimate file/destination.
@util.LogEntryExit
def _merge_added_lines(self, added_lines, dest):
if not added_lines:
return
dest_lines = self._get_file_lines(dest)
merged_lines = sorted(set(added_lines) | dest_lines)
merged_lines = [line + "\n" for line in merged_lines if line and not line.startswith("#")]
merged_lines[0:0] = ["# This file is generated by the generate-xcfilelists script.\n"]
with open(dest, "w") as f:
f.writelines(merged_lines)
# Utility to read a file and results the contents as a set of lines with
# EOLs removed.
@util.LogEntryExit
def _get_file_lines(self, file):
try:
with open(file, "r") as f:
return set([line.strip() for line in f])
except:
return set()
# Wrapper to return environment variable values.
@util.LogEntryExit
def _getenv(self, variable_name, default=None):
return os.environ.get(variable_name, default)
# Return the path to the project file (the *.xcodeproj "file).
@util.LogEntryExit
def _get_project_file_path(self):
assert False, """\
Override this to return full path to the project file (e.g.,
".../Source/JavaScriptCore/JavaScriptCode.xcodeproj")."""
# Return the path to the directory containing the project file and its
# supporting files and directories (e.g., ".../Source/JavaScriptCore").
@util.LogEntryExit
def _get_project_dir(self):
return os.path.dirname(self._get_project_file_path())
# Return the project file name (e.g., "JavaScriptCore.xcodeproj").
@util.LogEntryExit
def _get_project_file_name(self):
return os.path.basename(self._get_project_file_path())
# Return the project name (e.g., "JavaScriptCore").
@util.LogEntryExit
def _get_project_name(self):
return os.path.splitext(self._get_project_file_name())[0]
# Return the path to the build output directory to use when the user has
# indicated that they are building from the command line. Be sure to
# support default command-line users, command-line users that set
# WEBKIT_OUTPUTDIR, default Xcode users, and people like Jeff Miller who
# configure a custom build output location for Xcode.
@util.LogEntryExit
def _get_sym_root(self):
return self._get_build_dirs()[0]
@util.LogEntryExit
def _get_obj_root(self):
return self._get_build_dirs()[1]
@util.LogEntryExit
def _get_shared_precomps_dir(self):
return os.path.join(self._get_build_dirs()[1], "PrecompiledHeaders")
# From Xcode;
#
# export SYMROOT =/Users/keith/Library/Developer/Xcode/DerivedData/Safari-bmjhivzkbpxamlajyexvkivfjbmb/Build/Products
# export OBJROOT =/Users/keith/Library/Developer/Xcode/DerivedData/Safari-bmjhivzkbpxamlajyexvkivfjbmb/Build/Intermediates.noindex
# export SHARED_PRECOMPS_DIR=/Users/keith/Library/Developer/Xcode/DerivedData/Safari-bmjhivzkbpxamlajyexvkivfjbmb/Build/Intermediates.noindex/PrecompiledHeaders
#
# From command-line:
#
# export SYMROOT =/Volumes/Data/dev/webkit/OpenSource/WebKitBuild
# export OBJROOT =/Volumes/Data/dev/webkit/OpenSource/WebKitBuild
# export SHARED_PRECOMPS_DIR=/Volumes/Data/dev/webkit/OpenSource/WebKitBuild/PrecompiledHeaders
@util.LogEntryExit
def _get_build_dirs(self):
def define_xcode_build_dirs(self):
# Delete any spurious ~/Library/Preferences/xcodebuild.plist, as this
# file will interfere with any preferences set in the IDE. This
# .plist file shouldn't really ever exist, so nuking it doesn't
# cause any problems.
xcodebuild_plist = os.path.join(os.path.expanduser("~"), "Library", "Preferences", "xcodebuild.plist")
try:
os.unlink(xcodebuild_plist)
except:
pass
def read_xcode_user_default(key):
try:
(stdout, stderr) = util.subprocess_run(["defaults", "read", "com.apple.dt.Xcode", key])
return stdout.strip()
except util.CalledProcessError:
return None
# The following is based on the logic in determineBaseProductDir()
# in webkitdirs.pm and https://pewpewthespells.com/blog/xcode_build_locations.html.
# Get the base directory for the build output. This will be some
# default location (e.g., ~/Library/Developer/Xcode/DerivedData),
# an absolute path, or a project-relative path.
ide_custom_derived_data_location = read_xcode_user_default("IDECustomDerivedDataLocation")
# Path not specified; use the default.
if not ide_custom_derived_data_location:
base_dir = os.path.join(os.path.expanduser("~"), "Library", "Developer", "Xcode", "DerivedData")
# An absolute path is specified; use it.
elif os.path.isabs(ide_custom_derived_data_location):
base_dir = ide_custom_derived_data_location
# A relative path is specified; append it to the project path.
else:
base_dir = os.path.join(self._get_project_dir(), ide_custom_derived_data_location)
# Get the specification for how the build output should be stored
# withing that base directory. This will be some unique directory
# based on the hash of the project file path (e.g.,
# "Safari-sdlfkhasalksdjfhsdfhlksf"), some shared directory (e.g.,
# "Build"), or even something that might be an absolute path.
ide_build_location_style = read_xcode_user_default("IDEBuildLocationStyle")
# Create a unique directory within the base directory based on
# project name and hash of its full path.
#
# IDEBuildLocationStyle = Unique; # This is the default if not specified.
if ide_build_location_style == "Unique" or not ide_build_location_style:
workspace = os.path.abspath(self.application.cmd_line_args.xcode)
build_dir = os.path.join(
base_dir,
os.path.splitext(os.path.basename(workspace))[0] + "-" + xcode_hash_for_path(workspace),
"Build")
products_dir = os.path.join(build_dir, "Products")
intermediates_dir = os.path.join(build_dir, "Intermediates.noindex")
# Use a shared subdirectory; use the specified directory name.
#
# IDEBuildLocationStyle = Shared;
# IDESharedBuildFolderName = Build; # Relative to DerivedDataLocation
elif ide_build_location_style == "Shared":
build_dir = os.path.join(base_dir, read_xcode_user_default("IDESharedBuildFolderName"))
products_dir = os.path.join(build_dir, "Products")
intermediates_dir = os.path.join(build_dir, "Intermediates.noindex")
# Use the saved products and intermediates paths and either use
# them as relative to the DerivedData directory or the project
# folder, or just use them as absolute addresses.
#
# IDEBuildLocationStyle = Custom;
elif ide_build_location_style == "Custom":
ide_build_location_type = read_xcode_user_default("IDECustomBuildLocationType")
products_dir = read_xcode_user_default("IDECustomBuildProductsPath")
intermediates_dir = read_xcode_user_default("IDECustomBuildIntermediatesPath")
# IDECustomBuildLocationType = RelativeToDerivedData;
# IDECustomBuildIntermediatesPath = "Build/Intermediates.noindex";
# IDECustomBuildProductsPath = "Build/Products";
# IDECustomIndexStorePath = "Index/DataStore";
if ide_build_location_type == "RelativeToDerivedData":
products_dir = os.path.join(base_dir, products_dir)
intermediates_dir = os.path.join(base_dir, intermediates_dir)
# IDECustomBuildLocationType = RelativeToWorkspace;
# IDECustomBuildIntermediatesPath = "Build/Intermediates.noindex";
# IDECustomBuildProductsPath = "Build/Products";
# IDECustomIndexStorePath = "Index/DataStore";
elif ide_build_location_type == "RelativeToWorkspace":
base_dir = self._get_project_dir(),
products_dir = os.path.join(base_dir, products_dir)
intermediates_dir = os.path.join(base_dir, intermediates_dir)
# IDECustomBuildLocationType = Absolute;
# IDECustomBuildIntermediatesPath = "/Users/joedeveloper/Desktop/Build/Intermediates.noindex";
# IDECustomBuildProductsPath = "/Users/joedeveloper/Desktop/Build/Products";
# IDECustomIndexStorePath = "/Users/joedeveloper/Desktop/Index/DataStore";
# IDECustomDerivedDataLocation = "/Users/joedeveloper/Library/Developer/Xcode/DerivedData";
elif ide_build_location_type == "Absolute":
pass
else:
assert False, "Unknown/unsupported location type"
else:
assert False, "Unknown/unsupported style"
return (products_dir, intermediates_dir)
def define_command_line_build_dirs(self):
products_dir = self._getenv("WEBKIT_OUTPUTDIR")
if not products_dir:
products_dir = os.path.join(self.application.get_opensource_dir(), "WebKitBuild")
return (products_dir, products_dir)
if not self.cached_build_dirs and self.application.cmd_line_args.xcode:
self.cached_build_dirs = define_xcode_build_dirs(self)
if not self.cached_build_dirs:
self.cached_build_dirs = define_command_line_build_dirs(self)
return self.cached_build_dirs
# Return the location of the DerivedSources directory. Conventionally, we
# use $BUILT_PRODUCTS/DerivedSources/$PROJECT_NAME, but we may some day use
# $DERIVED_FILE_DIR aka $DERIVED_FILES_DIR aka $DERIVED_SOURCES_DIR, when
# the projects have been updated to use them.
@util.LogEntryExit
def _get_derived_sources_dir(self):
return os.path.join(self.application.get_xcode_built_products_dir(), "DerivedSources", self._get_project_name())
# Return the location for the xcfilelists.
@util.LogEntryExit
def _get_xcfilelist_dir(self):
return self._get_project_dir()
# Return the paths to the actual xcfilelists.
@util.LogEntryExit
def _get_input_derived_xcfilelist_project_path(self):
return os.path.join(self._get_xcfilelist_dir(), "DerivedSources-input.xcfilelist")
@util.LogEntryExit
def _get_output_derived_xcfilelist_project_path(self):
return os.path.join(self._get_xcfilelist_dir(), "DerivedSources-output.xcfilelist")
@util.LogEntryExit
def _get_input_unified_xcfilelist_project_path(self):
return os.path.join(self._get_xcfilelist_dir(), "UnifiedSources-input.xcfilelist")
@util.LogEntryExit
def _get_output_unified_xcfilelist_project_path(self):
return os.path.join(self._get_xcfilelist_dir(), "UnifiedSources-output.xcfilelist")
# Return the paths to the scripts that generate the derived sources.
@util.LogEntryExit
def _get_generate_derived_sources_script(self):
return None
@util.LogEntryExit
def _get_generate_unified_sources_script(self):
return None
class JavaScriptCoreGenerator(BaseGenerator):
VALID_PLATFORMS = ("macosx", "iosmac", "iphoneos", "watchos")
VALID_CONFIGURATIONS = ("Debug", "Release", "Production", "Profiling")
@util.LogEntryExit
def _get_project_file_path(self):
return os.path.join(self.application.get_opensource_dir(), "Source", "JavaScriptCore", "JavaScriptCore.xcodeproj")
@util.LogEntryExit
def _get_generate_derived_sources_script(self):
return os.path.join(self._get_project_dir(), "Scripts", "generate-derived-sources.sh")
@util.LogEntryExit
def _get_generate_unified_sources_script(self):
return os.path.join(self._get_project_dir(), "Scripts", "generate-unified-sources.sh")
class WebCoreGenerator(BaseGenerator):
VALID_PLATFORMS = ("macosx", "iosmac", "iphoneos", "watchos")
VALID_CONFIGURATIONS = ("Debug", "Release", "Production")
@util.LogEntryExit
def _get_project_file_path(self):
return os.path.join(self.application.get_opensource_dir(), "Source", "WebCore", "WebCore.xcodeproj")
@util.LogEntryExit
def _get_generate_derived_sources_script(self):
return os.path.join(self._get_project_dir(), "Scripts", "generate-derived-sources.sh")
@util.LogEntryExit
def _get_generate_unified_sources_script(self):
return os.path.join(self._get_project_dir(), "Scripts", "generate-unified-sources.sh")
class WebKitGenerator(BaseGenerator):
VALID_PLATFORMS = ("macosx", "iosmac", "iphoneos", "watchos")
VALID_CONFIGURATIONS = ("Debug", "Release", "Production")
@util.LogEntryExit
def _get_project_file_path(self):
return os.path.join(self.application.get_opensource_dir(), "Source", "WebKit", "WebKit.xcodeproj")
@util.LogEntryExit
def _get_derived_sources_dir(self):
return os.path.join(self.application.get_xcode_built_products_dir(), "DerivedSources", "WebKit2")
@util.LogEntryExit
def _get_generate_derived_sources_script(self):
return os.path.join(self._get_project_dir(), "Scripts", "generate-derived-sources.sh")
@util.LogEntryExit
def _get_generate_unified_sources_script(self):
return os.path.join(self._get_project_dir(), "Scripts", "generate-unified-sources.sh")
class DumpRenderTreeGenerator(BaseGenerator):
VALID_PLATFORMS = ("macosx", )
VALID_CONFIGURATIONS = ("Debug", "Release", "Production")
@util.LogEntryExit
def _get_project_file_path(self):
return os.path.join(self.application.get_opensource_dir(), "Tools", "DumpRenderTree", "DumpRenderTree.xcodeproj")
@util.LogEntryExit
def _get_generate_derived_sources_script(self):
return os.path.join(self._get_project_dir(), "Scripts", "generate-derived-sources.sh")
class WebKitTestRunnerGenerator(BaseGenerator):
VALID_PLATFORMS = ("macosx", )
VALID_CONFIGURATIONS = ("Debug", "Release", "Production")
@util.LogEntryExit
def _get_project_file_path(self):
return os.path.join(self.application.get_opensource_dir(), "Tools", "WebKitTestRunner", "WebKitTestRunner.xcodeproj")
@util.LogEntryExit
def _get_generate_derived_sources_script(self):
return os.path.join(self._get_project_dir(), "Scripts", "generate-derived-sources.sh")