blob: 0d869780a7c8f9792c7768b072783c953bcbb01f [file] [log] [blame]
#!/bin/bash
#
# Copyright (C) 2018-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.
# This script generates .xcfilelist files to be used as input and output
# specifications of Run Script build phases.
#
# Currently, this script looks at the Generate Derived Sources and Generate
# Unified Sources build phases. For the former, it invokes the
# DerivedSources.make makefile, passing in options that print out the
# dependency tree and using that information to form the associated input and
# output .xcfilelist files. For the latter, it invokes the same
# generate-unified-bundles.rb script that generates the actual
# UnifiedSources*.cpp/mm files, albeit in a mode that produces .xcfilelist
# files instead.
#
# This script not only generates .xcfilelists, but -- when given a "check"
# command -- it also checks that they are up-to-date. In this mode, the
# .xcfilelist files are created in a temporary location and are then compared
# to the versions checked into the repository. If there are differences, the
# user is notified so that they know that the .xcfilelist files need to be
# regenerated. This facility can be incorporated into a build phase, a check-in
# hook, or into the EWS (perhaps as part of check-webkit-style).
#
# As part of its operation, this script can sub-launch itself under Xcode. It
# does this in order to establish the context in which builds occur. In
# particular, it does this in order to set needed environment variables. In
# order to protect against environment variable name collision, all variable
# names in this script start with "GX_".
function stdout()
{
(( ${GX_QUIET} )) || echo "$@" >&1
}
function stderr()
{
echo "$@" >&2
}
function remove_extra_spaces()
{
echo $1
}
function print_option()
{
local GX_OPTION="$1"
local GX_MESSAGE="$(remove_extra_spaces "$2")"
local GX_LINE
local GX_LINE_WIDTH=90
local GX_OPTION_WIDTH=17
if (( ${#GX_OPTION} <= GX_OPTION_WIDTH ))
then
local GX_MESSAGE_CATENATED=$(printf " %-${GX_OPTION_WIDTH}s %s" "$GX_OPTION" "$GX_MESSAGE")
if (( ${#GX_MESSAGE_CATENATED} <= GX_LINE_WIDTH ))
then
stderr "${GX_MESSAGE_CATENATED}"
return
fi
local GX_MESSAGE_FIRST_LINE="${GX_MESSAGE_CATENATED:0:${GX_LINE_WIDTH}}" # Get the first 80 characters
GX_MESSAGE_FIRST_LINE="${GX_MESSAGE_FIRST_LINE% *}" # Trim back to the last space
GX_MESSAGE="${GX_MESSAGE_CATENATED:${#GX_MESSAGE_FIRST_LINE}+1}" # Get the rest after that space
stderr "${GX_MESSAGE_FIRST_LINE}"
else
stderr " ${GX_OPTION}"
fi
while IFS='' read -r GX_LINE
do
GX_LINE=$(printf " %${GX_OPTION_WIDTH}s %s" "" "$GX_LINE")
stderr "${GX_LINE}"
done < <(echo "${GX_MESSAGE}" | fold -w $(( GX_LINE_WIDTH - GX_OPTION_WIDTH - 3)) -s)
}
function join_by()
{
local GX_DELIM=$1
shift
echo -n "$1"
shift
printf "%s" "${@/#/${GX_DELIM}}"
}
function usage()
{
local GX_JOINED_PROJECT_TAGS=$(join_by ", " "${GX_PROJECT_TAGS[@]}")
stderr "Usage: $(basename "${GX_ME}") [OPTION...] COMMAND [PARAMETER...]"
stderr ""
stderr "Generate or check .xcfilelist files"
stderr ""
stderr "Commands:"
stderr ""
print_option "generate" "Generate a complete and up-to-date set of
.xcfilelist files and copy them to their appropriate places in the
project directories."
print_option "generate-xcode" "Generate .xcfilelist files for the current
target configuration an copy them to their appropriate places in the
project directories. Invoked from withing Xcode to update the current
build if needed."
print_option "check" "Generate a complete and up-to-date set of .xcfilelist
files and compare them to their counterparts in the project
directories."
print_option "check-xcode" "Generate .xcfilelist files for the current
target configuration and see if any files appear that aren't in the
checked-in .xcfilelist files. Invoked from within Xcode to validate the
current build."
print_option "subgenerate" "Generate an .xcfilelist file for a particular
combination of project, platform, and configuration. This operation is
performed in the context of an Xcode build in order to inherit the same
environment as that build."
print_option "help" "Print this text and exit."
stderr ""
stderr "Options:"
stderr ""
print_option "--project <project>" "Specify which project for which to
generate .xcfilelist files or to check. Possible values are
(${GX_JOINED_PROJECT_TAGS}). Default is to iterate over all projects."
print_option "--platform <platform>" "Specify which platform for which to
generate .xcfilelist files or to check. Possible values are (macosx,
iphoneos). Default is to iterate over all platforms, filtered to those
platforms that a particular project supports (e.g., you can't specify
'iphoneos' for WebKitTestRunner)."
print_option "--configuration <configuration>" "Specify which configuration
for which to generate .xcfilelist files or to check, Possible values
are (release, debug). Default is to iterate over all configurations."
print_option "--xcode" "Specify that existing build output can be found in
the directory created by the Xcode IDE (in ~/Library/Developer/Xcode)."
print_option "--webkitbuild" "Specify that existing build output can be
found in the directory used by the WebKit make files or the
build-webkit script (that is, in WebKitBuild or in the directory
identified by WEBKIT_OUTPUTDIR). This option is the default, so it
doesn't really get you anything by specifying this option (or by my
implementing it)."
print_option "--nocleanup" "Disable cleaning up temporary files after a
subgenerate operation. Normally these are cleaned up, but if
'subgenerate' is part of an overall 'generate' operation, then the
'generate' operation needs to keep around the temporary files until it
can complete aggregating them."
stderr ""
print_option "--dry-run" "When running through the requested process, don't
make any material changes. For example, for 'generate', create the new
.xcfilelist files, but don't copy them into their final locations"
print_option "--debug" "Provide verbose output."
print_option "--quiet" "Don't print any std output."
print_option "--help" "Print this text and exit."
stderr ""
}
function cleanup()
{
if (( ${GX_DO_CLEANUP} )) && (( ${GX_DEFERRED_EXIT_CODE} == 0 ))
then
rm -rf "${GX_TEMP}" &> /dev/null
fi
}
function my_exit()
{
local GX_ERR=$1
exit $GX_ERR
}
function die()
{
local GX_ERR=$2
[[ "$GX_ERR" == "" ]] && GX_ERR=1
stderr "### (${FUNCNAME[@]}) $1"
my_exit $GX_ERR
}
function log_debug()
{
(( "${GX_DEBUG}" > 0 )) && stderr "GXCF: $@"
}
function log_debug_var()
{
local GX_VAR_NAME=$1
local GX_IS_ARRAY=$(declare -p ${GX_VAR_NAME} 2> /dev/null | grep -q '^declare -a' && echo 1 || echo 0)
if (( $GX_IS_ARRAY ))
then
log_debug $(printf "%-47s = (%s)" $GX_VAR_NAME "$(eval echo \$\{${GX_VAR_NAME}\[\@\]\})")
else
log_debug $(printf "%-47s = %s" $GX_VAR_NAME "$(eval echo \$\{${GX_VAR_NAME}\})")
fi
}
function log_callstack_and_parameters()
{
if (( "${GX_DEBUG}" > "1" ))
then
local GX_ARGS=("$@")
local GX_CALLSTACK=("${FUNCNAME[@]}")
unset GX_CALLSTACK[0]
stderr "GXCF: (${GX_CALLSTACK[@]}): ${GX_ARGS[@]}"
fi
}
function log_progress()
{
stdout "GXCF: $@"
}
function log_progress_long()
{
local GX_MESSAGE="$(remove_extra_spaces "$1")"
local GX_LINE
while IFS='' read -r GX_LINE
do
log_progress $GX_LINE
done < <(echo "${GX_MESSAGE}" | fold -w 86 -s)
}
function normalize_directory_path()
{
log_callstack_and_parameters "$@"
[[ -z "$1" ]] && { echo "$1"; return; }
cd "$1" 2> /dev/null || { echo "$1"; return; }
pwd -P
}
function normalize_file_path()
{
log_callstack_and_parameters "$@"
[[ -z "$1" ]] && { echo "$1"; return; }
echo $(normalize_directory_path "$(dirname "$1")")/$(basename "$1")
}
function call()
{
log_callstack_and_parameters "$@"
local GX_FN="$1"
[[ "$(type -t ${GX_FN})" == "function" ]] || return $?
eval "${GX_FN}"
}
function set_project_specific_settings_for_JavaScriptCore()
{
log_callstack_and_parameters "$@"
GX_PS_PROJECT_FILE_PATH="${GX_OPENSOURCE_DIR}/Source/JavaScriptCore/JavaScriptCore.xcodeproj" # Can't use PROJECT_FILE_PATH because this is used pre-Xcode.
GX_PS_DERIVEDSOURCES_GENERATOR_RELATIVE_PATH="Scripts/generate-derived-sources.sh"
GX_PS_UNIFIEDSOURCES_GENERATOR_RELATIVE_PATH="Scripts/generate-unified-sources.sh"
GX_PS_PLATFORM_NAMES=(macosx iphoneos)
}
function set_project_specific_settings_for_WebCore()
{
log_callstack_and_parameters "$@"
GX_PS_PROJECT_FILE_PATH="${GX_OPENSOURCE_DIR}/Source/WebCore/WebCore.xcodeproj" # Can't use PROJECT_FILE_PATH because this is used pre-Xcode.
GX_PS_DERIVEDSOURCES_GENERATOR_RELATIVE_PATH="Scripts/generate-derived-sources.sh"
GX_PS_UNIFIEDSOURCES_GENERATOR_RELATIVE_PATH="Scripts/generate-unified-sources.sh"
GX_PS_PLATFORM_NAMES=(macosx iphoneos)
}
function set_project_specific_settings_for_WebKit()
{
log_callstack_and_parameters "$@"
GX_PS_PROJECT_FILE_PATH="${GX_OPENSOURCE_DIR}/Source/WebKit/WebKit.xcodeproj" # Can't use PROJECT_FILE_PATH because this is used pre-Xcode.
GX_PS_DERIVED_SOURCES_DIR="${BUILT_PRODUCTS_DIR}/DerivedSources/WebKit2"
GX_PS_DERIVEDSOURCES_GENERATOR_RELATIVE_PATH="Scripts/generate-derived-sources.sh"
GX_PS_UNIFIEDSOURCES_GENERATOR_RELATIVE_PATH="Scripts/generate-unified-sources.sh"
GX_PS_PLATFORM_NAMES=(macosx iphoneos)
}
function set_project_specific_settings_for_DumpRenderTree()
{
log_callstack_and_parameters "$@"
GX_PS_PROJECT_FILE_PATH="${GX_OPENSOURCE_DIR}/Tools/DumpRenderTree/DumpRenderTree.xcodeproj" # Can't use PROJECT_FILE_PATH because this is used pre-Xcode.
GX_PS_DERIVEDSOURCES_GENERATOR_RELATIVE_PATH="Scripts/generate-derived-sources.sh"
GX_PS_PLATFORM_NAMES=(macosx)
}
function set_project_specific_settings_for_WebKitTestRunner()
{
log_callstack_and_parameters "$@"
GX_PS_PROJECT_FILE_PATH="${GX_OPENSOURCE_DIR}/Tools/WebKitTestRunner/WebKitTestRunner.xcodeproj" # Can't use PROJECT_FILE_PATH because this is used pre-Xcode.
GX_PS_DERIVEDSOURCES_GENERATOR_RELATIVE_PATH="Scripts/generate-derived-sources.sh"
GX_PS_PLATFORM_NAMES=(macosx)
}
function set_project_specific_settings()
{
log_callstack_and_parameters "$@"
# Unset the variables that the set_project_specific_settings_for_FOO
# functions set. We need to do this in case the function for project BAR
# doesn't define one or more of them, causing it to inherit the settings
# for a previous project FOO.
#
# To achieve this unsetting, we prefix all the variables we want to unset
# with "GX_PS_" ("PS for "project specific"). We can then gather all
# variables that start with this prefix and unset them.
unset ${!GX_PS_*}
[[ -n "${GX_PROJECT_TAG}" ]] || die "GX_PROJECT_TAG is not defined."
call set_project_specific_settings_for_${GX_PROJECT_TAG} || die "Could not set build variables for ${GX_PROJECT_TAG}."
}
function set_common_project_settings()
{
log_callstack_and_parameters "$@"
local GX_EFFECTIVE_PROJECT_FILE_PATH="${GX_PS_PROJECT_FILE_PATH}"
local GX_EFFECTIVE_PROJECT_DIR=$(dirname "${GX_EFFECTIVE_PROJECT_FILE_PATH}")
[[ -n "${GX_EFFECTIVE_PROJECT_FILE_PATH}" ]] || die "GX_EFFECTIVE_PROJECT_FILE_PATH is not defined."
[[ -d "${GX_EFFECTIVE_PROJECT_FILE_PATH}" ]] || die "${GX_EFFECTIVE_PROJECT_FILE_PATH} is not a directory."
[[ -n "${GX_EFFECTIVE_PROJECT_DIR}" ]] || die "GX_EFFECTIVE_PROJECT_DIR is not defined."
[[ -d "${GX_EFFECTIVE_PROJECT_DIR}" ]] || die "${GX_EFFECTIVE_PROJECT_DIR} is not a directory."
# Get the paths to the scripts that drive the generation of the
# .xcfilelists or the data going into the .xcfilelists.
GX_DERIVEDSOURCES_GENERATOR="${GX_PS_DERIVEDSOURCES_GENERATOR_RELATIVE_PATH:+${GX_EFFECTIVE_PROJECT_DIR}/${GX_PS_DERIVEDSOURCES_GENERATOR_RELATIVE_PATH}}"
GX_UNIFIEDSOURCES_GENERATOR="${GX_PS_UNIFIEDSOURCES_GENERATOR_RELATIVE_PATH:+${GX_EFFECTIVE_PROJECT_DIR}/${GX_PS_UNIFIEDSOURCES_GENERATOR_RELATIVE_PATH}}"
[[ -n "${GX_DERIVEDSOURCES_GENERATOR}" ]] && { [[ -f "${GX_DERIVEDSOURCES_GENERATOR}" ]] || die "${GX_DERIVEDSOURCES_GENERATOR} does not exist."; }
[[ -n "${GX_UNIFIEDSOURCES_GENERATOR}" ]] && { [[ -f "${GX_UNIFIEDSOURCES_GENERATOR}" ]] || die "${GX_UNIFIEDSOURCES_GENERATOR} does not exist."; }
# Get the paths to the locations of the final .xcfilelist files.
local GX_BASE_PATH="${GX_EFFECTIVE_PROJECT_DIR}/${GX_PS_XCFILELIST_RELATIVE_PATH}"
GX_INPUT_DERIVED_XCFILELIST_PROJECT_PATH="${GX_BASE_PATH}/DerivedSources-input.xcfilelist"
GX_OUTPUT_DERIVED_XCFILELIST_PROJECT_PATH="${GX_BASE_PATH}/DerivedSources-output.xcfilelist"
GX_OUTPUT_UNIFIED_XCFILELIST_PROJECT_PATH="${GX_BASE_PATH}/UnifiedSources-output.xcfilelist"
# Get the paths to the locations of the temporary .xcfilelist files (the
# ones being built up before being moved to their final locations).
GX_INPUT_DERIVED_XCFILELIST_PROJECT_TEMP_PATH="${GX_TEMP}/${GX_INPUT_DERIVED_XCFILELIST_PROJECT_PATH}"
GX_OUTPUT_DERIVED_XCFILELIST_PROJECT_TEMP_PATH="${GX_TEMP}/${GX_OUTPUT_DERIVED_XCFILELIST_PROJECT_PATH}"
GX_OUTPUT_UNIFIED_XCFILELIST_PROJECT_TEMP_PATH="${GX_TEMP}/${GX_OUTPUT_UNIFIED_XCFILELIST_PROJECT_PATH}"
# Collect the default per-project commands to execute during the generate,
# merge, and compare stages.
GX_SUBGENERATE_ACTIONS=()
GX_MERGE_ACTIONS=()
GX_CHECK_ACTIONS=()
if [[ -n "${GX_DERIVEDSOURCES_GENERATOR}" ]]
then
GX_SUBGENERATE_ACTIONS+=(generate_derivedsources_xcfilelists)
GX_MERGE_ACTIONS+=(merge_derivedsources_xcfilelists)
GX_CHECK_ACTIONS+=(check_derivedsources_xcfilelists)
fi
if [[ -n "${GX_UNIFIEDSOURCES_GENERATOR}" ]]
then
GX_SUBGENERATE_ACTIONS+=(generate_unifiedsources_xcfilelists)
GX_MERGE_ACTIONS+=(merge_unifiedsources_xcfilelists)
GX_CHECK_ACTIONS+=(check_unifiedsources_xcfilelists)
fi
[[ -z "${GX_PS_DERIVED_SOURCES_DIR}" ]] && GX_PS_DERIVED_SOURCES_DIR="${BUILT_PRODUCTS_DIR}/DerivedSources/${PROJECT_NAME}"
GX_TEMP_INPUT_XCFILELIST="${GX_TEMP}/input.xcfilelist"
GX_TEMP_OUTPUT_XCFILELIST="${GX_TEMP}/output.xcfilelist"
}
function dump_project_settings()
{
log_callstack_and_parameters "$@"
log_debug_var BUILD_SCRIPTS_DIR
log_debug_var BUILT_PRODUCTS_DIR
log_debug_var CONFIGURATION
log_debug_var DERIVED_SOURCES_DIR
log_debug_var JAVASCRIPTCORE_PRIVATE_HEADERS_DIR
log_debug_var PROJECT_DIR
log_debug_var PROJECT_FILE_PATH
log_debug_var PROJECT_NAME
log_debug_var WEBCORE_PRIVATE_HEADERS_DIR
log_debug_var WEBKIT2_PRIVATE_HEADERS_DIR
log_debug
log_debug_var GX_PS_PROJECT_FILE_PATH
log_debug_var GX_PS_DERIVEDSOURCES_GENERATOR_RELATIVE_PATH
log_debug_var GX_PS_UNIFIEDSOURCES_GENERATOR_RELATIVE_PATH
log_debug_var GX_PS_XCFILELIST_RELATIVE_PATH
log_debug_var GX_PS_PLATFORM_NAMES
log_debug
log_debug_var GX_PROJECT_TAG
log_debug_var GX_PLATFORM_NAME
log_debug_var GX_CONFIGURATION
log_debug
log_debug_var GX_EFFECTIVE_PROJECT_FILE_PATH
log_debug_var GX_EFFECTIVE_PROJECT_DIR
log_debug
log_debug_var GX_DERIVEDSOURCES_GENERATOR
log_debug_var GX_UNIFIEDSOURCES_GENERATOR
log_debug
log_debug_var GX_INPUT_DERIVED_XCFILELIST_PROJECT_TEMP_PATH
log_debug_var GX_OUTPUT_DERIVED_XCFILELIST_PROJECT_TEMP_PATH
log_debug_var GX_OUTPUT_UNIFIED_XCFILELIST_PROJECT_TEMP_PATH
log_debug
log_debug_var GX_INPUT_DERIVED_XCFILELIST_PROJECT_PATH
log_debug_var GX_OUTPUT_DERIVED_XCFILELIST_PROJECT_PATH
log_debug_var GX_OUTPUT_UNIFIED_XCFILELIST_PROJECT_PATH
log_debug
log_debug_var GX_PS_DERIVED_SOURCES_DIR
log_debug
log_debug_var GX_SUBGENERATE_ACTIONS
log_debug_var GX_MERGE_ACTIONS
log_debug_var GX_CHECK_ACTIONS
}
function set_project_settings()
{
log_callstack_and_parameters "$@"
[[ -z "${GX_PROJECT_TAG}" ]] && return
set_project_specific_settings
set_common_project_settings
dump_project_settings
}
function ensure_directories_exist()
{
log_callstack_and_parameters "$@"
local GX_DIR
for GX_DIR in "$@"
do
log_debug "Creating ${GX_DIR}"
mkdir -p "${GX_DIR}" &> /dev/null || die "Unable to create "${GX_DIR}"."
done
}
function create_empty_files()
{
log_callstack_and_parameters "$@"
local GX_FILE
for GX_FILE in "$@"
do
ensure_directories_exist "$(dirname "${GX_FILE}")"
log_debug "Creating ${GX_FILE}"
echo -n '' > "${GX_FILE}"
done
}
function append_xcfilelist_header()
{
log_callstack_and_parameters "$@"
local GX_FILE
for GX_FILE in "$@"
do
echo '# This file is generated by the generate-xcfilelists script.' >> "${GX_FILE}"
done
}
function sort_and_unique_in_place()
{
sort -u "$1" -o "$1"
}
function replace()
{
log_callstack_and_parameters "$@"
local GX_FILE="$1"
local GX_PATTERN="$2"
local GX_REPLACEMENT="$3"
[[ -n "${GX_FILE}" ]] || die "GX_FILE is not defined."
[[ -f "${GX_FILE}" ]] || die "${GX_FILE} does not exist."
sed -E -e "s|${GX_PATTERN}|${GX_REPLACEMENT}|" -i '' "${GX_FILE}"
}
function unexpand()
{
log_callstack_and_parameters "$@"
local GX_FILE="$1"
local GX_VAR="$2"
local GX_VALUE=$(eval echo \$${GX_VAR})
[[ -n "${GX_VALUE}" ]] && replace "${GX_FILE}" "^${GX_VALUE}/" "\$\($GX_VAR\)/"
}
function find_additions()
{
# Find additions and removals so that we can report them.
#
# UPDATE: We can't really report removals. It's possible -- even
# overwhelmingly likely -- that we are generating .xcfilelist information
# for only a subset of the possible configurations for which we build. For
# example, a developer may be building for macOS and iOS, but not watchOS.
# In situations like this, we'll be generating the .xcfilelist for those
# two platforms, but any files specific to watchOS will not be discovered
# and won't be included in the .xcfilelists. If we were to report those
# watchOS files as files that should be removed from the .xcfilelists, then
# the watchOS build may fail. So, for now, let any obsolete files
# accumulate in the .xcfilelist files; they're mostly harmless.
local GX_NEW="$1"
local GX_ORIG="$2"
local GX_ADDITIONS="$3"
[[ -f "${GX_NEW}" ]] || die "${GX_NEW} does not exist."
[[ -f "${GX_ORIG}" ]] || die "${GX_ORIG} does not exist."
comm -2 -3 <(sort "${GX_NEW}") <(sort "${GX_ORIG}") > "${GX_ADDITIONS}"
}
function get_sdks()
{
log_callstack_and_parameters "$@"
(( ${#GX_SDKS[@]} )) && return
GX_SDKS=($(
xcodebuild -showsdks \
| grep -e '\s-sdk\s' \
| sed -E \
-e 's/.*-sdk ([^[:digit:]]+)$/\1/' \
-e 's/.*-sdk ([^[:digit:]]+)([[:digit:]\.]+)$/\1/' \
-e 's/.*-sdk ([^[:digit:]]+)([[:digit:]\.]+)([^[:digit:]]+)$/\1.\3/' \
| sort -u
))
(( ${#GX_SDKS[@]} )) || die "Unable to find any SDKs."
}
function get_canonical_configuration()
{
log_callstack_and_parameters "$@"
local GX_PROVISIONAL_CONFIGURATION=$(echo "$1" | tr '[:upper:]' '[:lower:]')
local GX_RESULT=$2
[[ "${GX_PROVISIONAL_CONFIGURATION}" == "" ]] && { eval $GX_RESULT=""; return; }
[[ "${GX_PROVISIONAL_CONFIGURATION}" == "debug" ]] && { eval $GX_RESULT="Debug"; return; }
[[ "${GX_PROVISIONAL_CONFIGURATION}" == "release" ]] && { eval $GX_RESULT="Release"; return; }
[[ "${GX_PROVISIONAL_CONFIGURATION}" == "production" ]] && { eval $GX_RESULT="Production"; return; }
[[ "${GX_PROVISIONAL_CONFIGURATION}" == "profiling" ]] && { eval $GX_RESULT="Profiling"; return; }
die "Unrecognized configuration: $1"
}
function get_canonical_platform_name()
{
log_callstack_and_parameters "$@"
local GX_PROVISIONAL_PLATFORM_NAME=$(echo "$1" | tr '[:upper:]' '[:lower:]')
local GX_RESULT=$2
[[ "${GX_PROVISIONAL_PLATFORM_NAME}" == "" ]] && { eval $GX_RESULT=""; return; }
[[ "${GX_PROVISIONAL_PLATFORM_NAME}" == "ios" ]] && { eval $GX_RESULT="iphoneos"; return; }
[[ "${GX_PROVISIONAL_PLATFORM_NAME}" == "iphone" ]] && { eval $GX_RESULT="iphoneos"; return; }
[[ "${GX_PROVISIONAL_PLATFORM_NAME}" == "ipad" ]] && { eval $GX_RESULT="iphoneos"; return; }
[[ "${GX_PROVISIONAL_PLATFORM_NAME}" == "iphoneos" ]] && { eval $GX_RESULT="iphoneos"; return; }
[[ "${GX_PROVISIONAL_PLATFORM_NAME}" == "iphonesimulator" ]] && { eval $GX_RESULT="iphonesimulator"; return; }
[[ "${GX_PROVISIONAL_PLATFORM_NAME}" == "mac" ]] && { eval $GX_RESULT="macosx"; return; }
[[ "${GX_PROVISIONAL_PLATFORM_NAME}" == "osx" ]] && { eval $GX_RESULT="macosx"; return; }
[[ "${GX_PROVISIONAL_PLATFORM_NAME}" == "macos" ]] && { eval $GX_RESULT="macosx"; return; }
[[ "${GX_PROVISIONAL_PLATFORM_NAME}" == "macosx" ]] && { eval $GX_RESULT="macosx"; return; }
[[ "${GX_PROVISIONAL_PLATFORM_NAME}" == "tvos" ]] && { eval $GX_RESULT="appletvos"; return; }
[[ "${GX_PROVISIONAL_PLATFORM_NAME}" == "appletvos" ]] && { eval $GX_RESULT="appletvos"; return; }
[[ "${GX_PROVISIONAL_PLATFORM_NAME}" == "tvsimulator" ]] && { eval $GX_RESULT="appletvsimulator"; return; }
[[ "${GX_PROVISIONAL_PLATFORM_NAME}" == "appletvsimulator" ]] && { eval $GX_RESULT="appletvsimulator"; return; }
[[ "${GX_PROVISIONAL_PLATFORM_NAME}" == "watchos" ]] && { eval $GX_RESULT="watchos"; return; }
[[ "${GX_PROVISIONAL_PLATFORM_NAME}" == "watchsimulator" ]] && { eval $GX_RESULT="watchsimulator"; return; }
die "Unrecognized platform name: $1"
}
function get_sdk_name()
{
log_callstack_and_parameters "$@"
local GX_SDK=$1
local GX_RESULT=$2
get_canonical_platform_name "${GX_SDK}" GX_SDK
local GX_INTERNAL_SDK="${GX_SDK}.internal"
get_sdks
# Prefer an internal SDK if one exists.
[[ " ${GX_SDKS[@]} " =~ " ${GX_INTERNAL_SDK} " ]] && { eval $GX_RESULT="${GX_INTERNAL_SDK}"; return; }
[[ " ${GX_SDKS[@]} " =~ " ${GX_SDK} " ]] && { eval $GX_RESULT="${GX_SDK}"; return; }
die "Unsupported SDK: ${GX_SDK}."
}
function invoke_each_action()
{
log_callstack_and_parameters "$@"
local GX_ACTION
for GX_ACTION in "$@"
do
eval "${GX_ACTION}"
done
}
function for_each_configuration()
{
log_callstack_and_parameters "$@"
if [[ -z "${GX_CONFIGURATION}" ]]
then
for GX_CONFIGURATION in "${GX_CONFIGURATIONS[@]}"
do
eval "$@"
done
GX_CONFIGURATION=
else
eval "$@"
fi
}
function for_each_platform()
{
log_callstack_and_parameters "$@"
if [[ -z "${GX_PLATFORM_NAME}" ]]
then
for GX_PLATFORM_NAME in "${GX_PS_PLATFORM_NAMES[@]}"
do
eval "$@"
done
GX_PLATFORM_NAME=
else
eval "$@"
fi
}
function for_each_project()
{
log_callstack_and_parameters "$@"
if [[ -z "${GX_PROJECT_TAG}" ]]
then
for GX_PROJECT_TAG in "${GX_PROJECT_TAGS[@]}"
do
set_project_settings
eval "$@"
done
GX_PROJECT_TAG=
else
set_project_settings
eval "$@"
fi
}
function generate_derivedsources_xcfilelists()
{
log_callstack_and_parameters "$@"
create_empty_files "${GX_TEMP_INPUT_XCFILELIST}" "${GX_TEMP_OUTPUT_XCFILELIST}"
local GX_DERIVEDSOURCES_EXTRACTOR="${GX_HERE}/extract-dependencies-from-makefile"
[[ -n "${GX_DERIVEDSOURCES_GENERATOR}" ]] || die "GX_DERIVEDSOURCES_GENERATOR is not defined."
[[ -x "${GX_DERIVEDSOURCES_GENERATOR}" ]] || die "${GX_DERIVEDSOURCES_GENERATOR} does not exist or is not executable."
[[ -x "${GX_DERIVEDSOURCES_EXTRACTOR}" ]] || die "${GX_DERIVEDSOURCES_EXTRACTOR} does not exist or is not executable."
log_debug "Creating derived .xcfilelists for ${PROJECT_NAME}/${PLATFORM_NAME}/${CONFIGURATION}"
"${GX_DERIVEDSOURCES_GENERATOR}" \
NO_SUPPLEMENTAL_FILES=1 \
--no-builtin-rules \
--dry-run \
--always-make \
--debug=abvijm all \
1> "${GX_TEMP}/std.out" 2> "${GX_TEMP}/std.err"
local GX_RESULT=$?
if (( ${GX_RESULT} ))
then
sed -E -e 's/^/GXCF: /' < "${GX_TEMP}/std.err"
die "Error generating derived sources: error = ${GX_RESULT}" ${GX_RESULT}
fi
cat "${GX_TEMP}/std.out" \
| "${GX_DERIVEDSOURCES_EXTRACTOR}" \
--input "${GX_TEMP_INPUT_XCFILELIST}" \
--output "${GX_TEMP_OUTPUT_XCFILELIST}"
local GX_RESULT=$?
(( ${GX_RESULT} )) && die "Error extracting dependencies from DerivedSources.make: error = ${GX_RESULT}"
[[ -f "${GX_TEMP_INPUT_XCFILELIST}" ]] || die "${GX_TEMP_INPUT_XCFILELIST} was not generated."
[[ -f "${GX_TEMP_OUTPUT_XCFILELIST}" ]] || die "${GX_TEMP_OUTPUT_XCFILELIST} was not generated."
replace "${GX_TEMP_INPUT_XCFILELIST}" '^WebCore/' '$(PROJECT_DIR)/'
replace "${GX_TEMP_INPUT_XCFILELIST}" '^JavaScriptCore/' '$(PROJECT_DIR)/'
replace "${GX_TEMP_INPUT_XCFILELIST}" '^JavaScriptCorePrivateHeaders/' '$(JAVASCRIPTCORE_PRIVATE_HEADERS_DIR)/'
replace "${GX_TEMP_INPUT_XCFILELIST}" '^WebKit2PrivateHeaders/' '$(WEBKIT2_PRIVATE_HEADERS_DIR)/'
unexpand "${GX_TEMP_INPUT_XCFILELIST}" PROJECT_DIR
unexpand "${GX_TEMP_INPUT_XCFILELIST}" WEBKITADDITIONS_HEADERS_FOLDER_PATH
unexpand "${GX_TEMP_INPUT_XCFILELIST}" WEBCORE_PRIVATE_HEADERS_DIR
unexpand "${GX_TEMP_INPUT_XCFILELIST}" WEBKIT2_PRIVATE_HEADERS_DIR
unexpand "${GX_TEMP_INPUT_XCFILELIST}" JAVASCRIPTCORE_PRIVATE_HEADERS_DIR
unexpand "${GX_TEMP_INPUT_XCFILELIST}" BUILT_PRODUCTS_DIR
replace "${GX_TEMP_OUTPUT_XCFILELIST}" "^" "${GX_PS_DERIVED_SOURCES_DIR}/"
unexpand "${GX_TEMP_OUTPUT_XCFILELIST}" BUILT_PRODUCTS_DIR
merge_xcfilelists_helper "${GX_TEMP_INPUT_XCFILELIST}" "${GX_INPUT_DERIVED_XCFILELIST_PROJECT_TEMP_PATH}"
merge_xcfilelists_helper "${GX_TEMP_OUTPUT_XCFILELIST}" "${GX_OUTPUT_DERIVED_XCFILELIST_PROJECT_TEMP_PATH}"
}
function generate_unifiedsources_xcfilelists()
{
log_callstack_and_parameters "$@"
create_empty_files "${GX_TEMP_OUTPUT_XCFILELIST}"
[[ -n "${GX_UNIFIEDSOURCES_GENERATOR}" ]] || die "GX_UNIFIEDSOURCES_GENERATOR is not defined."
[[ -x "${GX_UNIFIEDSOURCES_GENERATOR}" ]] || die "${GX_UNIFIEDSOURCES_GENERATOR} does not exist or is not executable."
local GX_BUILD_SCRIPTS_DIR="${GX_OPENSOURCE_DIR}/Source/WTF/Scripts"
[[ -d "${GX_BUILD_SCRIPTS_DIR}" ]] || die "${GX_BUILD_SCRIPTS_DIR} does not exist or is not a directory."
[[ -f "${GX_BUILD_SCRIPTS_DIR}/generate-unified-source-bundles.rb" ]] || die "${GX_BUILD_SCRIPTS_DIR}/generate-unified-source-bundles.rb does not exist or is not a file."
log_debug "Creating unified .xcfilelists for ${PROJECT_NAME}/${PLATFORM_NAME}/${CONFIGURATION}"
BUILD_SCRIPTS_DIR="${GX_BUILD_SCRIPTS_DIR}" \
"${GX_UNIFIEDSOURCES_GENERATOR}" \
--generate-xcfilelists \
--output-xcfilelist-path "${GX_TEMP_OUTPUT_XCFILELIST}"
GX_RESULT=$?
(( ${GX_RESULT} )) && die "Error generating unified sources: error = ${GX_RESULT}"
[[ -f "${GX_TEMP_OUTPUT_XCFILELIST}" ]] || die "${GX_TEMP_OUTPUT_XCFILELIST} was not generated."
unexpand "${GX_TEMP_OUTPUT_XCFILELIST}" BUILT_PRODUCTS_DIR
merge_xcfilelists_helper "${GX_TEMP_OUTPUT_XCFILELIST}" "${GX_OUTPUT_UNIFIED_XCFILELIST_PROJECT_TEMP_PATH}"
}
function subgenerate_xcfilelists()
{
log_callstack_and_parameters "$@"
invoke_each_action "${GX_SUBGENERATE_ACTIONS[@]}"
}
function sublaunch_under_xcode()
{
log_callstack_and_parameters "$@"
# Sublaunch the script for the given project, for each platform for which
# the project is built, and for Debug and Release configurations.
local GX_ARGS=("$@")
(( ${GX_DRY_RUN} )) && GX_ARGS+=("--dry-run")
(( ${GX_DEBUG} )) && { for n in $(seq $GX_DEBUG); do GX_ARGS+=("--debug"); done; }
(( ${GX_QUIET} )) && GX_ARGS+=("--quiet")
local GX_SDK_NAME
get_sdk_name "${GX_PLATFORM_NAME}" GX_SDK_NAME
log_debug "Sublaunching for: ${GX_PROJECT_TAG}/${GX_PLATFORM_NAME}/${GX_CONFIGURATION}"
local GX_XCODE_PARAMETERS=(
-project "${GX_PS_PROJECT_FILE_PATH}"
-sdk "${GX_SDK_NAME}"
-configuration "${GX_CONFIGURATION}"
-target "Apply Configuration to XCFileLists"
)
if (( ${GX_USE_WEBKITBUILD_BUILD_OUTPUT} ))
then
local GX_WEBKITBUILD_DIR="${WEBKIT_OUTPUTDIR:-${GX_OPENSOURCE_DIR}/WebKitBuild}"
[[ -d "${GX_WEBKITBUILD_DIR}" ]] || die "${GX_WEBKITBUILD_DIR} does not exist."
GX_XCODE_PARAMETERS+=(
SYMROOT="${GX_WEBKITBUILD_DIR}"
OBJROOT="${GX_WEBKITBUILD_DIR}"
SHARED_PRECOMPS_DIR="${GX_WEBKITBUILD_DIR}/PrecompiledHeaders"
)
fi
if (( $GX_DEBUG > 0 ))
then
WK_SUBLAUNCH_SCRIPT_PARAMETERS=("${GX_ARGS[@]}") xcodebuild "${GX_XCODE_PARAMETERS[@]}"
else
WK_SUBLAUNCH_SCRIPT_PARAMETERS=("${GX_ARGS[@]}") xcodebuild "${GX_XCODE_PARAMETERS[@]}" | grep '^\.\.\. '
fi
local GX_RESULT=${PIPESTATUS[0]}
(( ${GX_RESULT} )) && die "Error sub-launching under xcode: error = ${GX_RESULT}"
}
function reset_project_specific_temp_files()
{
log_callstack_and_parameters "$@"
create_empty_files \
"${GX_INPUT_DERIVED_XCFILELIST_PROJECT_TEMP_PATH}" "${GX_OUTPUT_DERIVED_XCFILELIST_PROJECT_TEMP_PATH}" \
"${GX_OUTPUT_UNIFIED_XCFILELIST_PROJECT_TEMP_PATH}"
}
function generate_xcfilelists()
{
log_callstack_and_parameters "$@"
reset_project_specific_temp_files
for_each_platform \
for_each_configuration \
sublaunch_under_xcode \
"${GX_SUBEXECUTE_SCRIPT}" subgenerate --nocleanup --project "${GX_PROJECT_TAG}"
}
function merge_xcfilelists_helper()
{
log_callstack_and_parameters "$@"
local GX_SOURCE="$1"
local GX_DEST="$2"
local GX_ADDITIONS="${GX_TEMP}/diff_added.tmp"
append_xcfilelist_header "${GX_SOURCE}"
sort_and_unique_in_place "${GX_SOURCE}"
find_additions "${GX_SOURCE}" "${GX_DEST}" "${GX_ADDITIONS}"
if [[ -s "${GX_ADDITIONS}" ]]
then
cat "${GX_SOURCE}" >> "${GX_DEST}"
sort_and_unique_in_place "${GX_DEST}"
return 0
fi
return 1
}
function merge_derivedsources_xcfilelists()
{
log_callstack_and_parameters "$@"
log_debug "Merging ${GX_INPUT_DERIVED_XCFILELIST_PROJECT_TEMP_PATH} into ${GX_INPUT_DERIVED_XCFILELIST_PROJECT_PATH}"
log_debug "Merging ${GX_OUTPUT_DERIVED_XCFILELIST_PROJECT_TEMP_PATH} into ${GX_OUTPUT_DERIVED_XCFILELIST_PROJECT_PATH}"
if (( ! ${GX_DRY_RUN} ))
then
merge_xcfilelists_helper "${GX_INPUT_DERIVED_XCFILELIST_PROJECT_TEMP_PATH}" "${GX_INPUT_DERIVED_XCFILELIST_PROJECT_PATH}" && GX_DEFERRED_EXIT_CODE=3
log_debug "GX_DEFERRED_EXIT_CODE = $GX_DEFERRED_EXIT_CODE"
merge_xcfilelists_helper "${GX_OUTPUT_DERIVED_XCFILELIST_PROJECT_TEMP_PATH}" "${GX_OUTPUT_DERIVED_XCFILELIST_PROJECT_PATH}" && GX_DEFERRED_EXIT_CODE=3
log_debug "GX_DEFERRED_EXIT_CODE = $GX_DEFERRED_EXIT_CODE"
fi
}
function merge_unifiedsources_xcfilelists()
{
log_callstack_and_parameters "$@"
log_debug "Merging ${GX_OUTPUT_UNIFIED_XCFILELIST_PROJECT_TEMP_PATH} into ${GX_OUTPUT_UNIFIED_XCFILELIST_PROJECT_PATH}"
if (( ! ${GX_DRY_RUN} ))
then
merge_xcfilelists_helper "${GX_OUTPUT_UNIFIED_XCFILELIST_PROJECT_TEMP_PATH}" "${GX_OUTPUT_UNIFIED_XCFILELIST_PROJECT_PATH}" && GX_DEFERRED_EXIT_CODE=3
log_debug "GX_DEFERRED_EXIT_CODE = $GX_DEFERRED_EXIT_CODE"
fi
}
function merge_xcfilelists()
{
log_callstack_and_parameters "$@"
invoke_each_action "${GX_MERGE_ACTIONS[@]}"
log_debug "GX_DEFERRED_EXIT_CODE = $GX_DEFERRED_EXIT_CODE"
}
function check_xcfilelists_helper()
{
log_callstack_and_parameters "$@"
local GX_NEW="$1"
local GX_ORIG="$2"
local GX_ADDITIONS="${GX_TEMP}/diff_added.tmp"
log_debug "Checking ${GX_NEW} against ${GX_ORIG}"
find_additions "${GX_NEW}" "${GX_ORIG}" "${GX_ADDITIONS}"
if [[ -s "${GX_ADDITIONS}" ]]
then
log_progress
log_progress "------------------------------------------------------------------------------"
log_progress "Found added files for ${GX_ORIG}:"
log_progress "------------------------------------------------------------------------------"
local GX_LINE
while IFS='' read -r GX_LINE
do
log_progress "${GX_LINE}"
done < "${GX_ADDITIONS}"
log_progress "------------------------------------------------------------------------------"
GX_DEFERRED_EXIT_CODE=2
fi
}
function check_derivedsources_xcfilelists()
{
log_callstack_and_parameters "$@"
check_xcfilelists_helper "${GX_INPUT_DERIVED_XCFILELIST_PROJECT_TEMP_PATH}" "${GX_INPUT_DERIVED_XCFILELIST_PROJECT_PATH}"
check_xcfilelists_helper "${GX_OUTPUT_DERIVED_XCFILELIST_PROJECT_TEMP_PATH}" "${GX_OUTPUT_DERIVED_XCFILELIST_PROJECT_PATH}"
}
function check_unifiedsources_xcfilelists()
{
log_callstack_and_parameters "$@"
check_xcfilelists_helper "${GX_OUTPUT_UNIFIED_XCFILELIST_PROJECT_TEMP_PATH}" "${GX_OUTPUT_UNIFIED_XCFILELIST_PROJECT_PATH}"
}
function check_xcfilelists()
{
log_callstack_and_parameters "$@"
invoke_each_action "${GX_CHECK_ACTIONS[@]}"
}
function report_merge_results()
{
log_callstack_and_parameters "$@"
log_debug "GX_DEFERRED_EXIT_CODE = $GX_DEFERRED_EXIT_CODE"
if (( ${GX_DEFERRED_EXIT_CODE} ))
then
log_progress
local GX_MESSAGE='".xcfilelist" files tell the build system what files
are consumed and produced by the "Run Script" build phases in
Xcode. At least one of these .xcfilelist files was out of date and
has been updated. You now need to restart your build.'
log_progress_long "${GX_MESSAGE}"
fi
}
function report_remediation_steps()
{
log_callstack_and_parameters "$@"
if (( ${GX_DEFERRED_EXIT_CODE} ))
then
log_progress
# We can either be called from within an xcodebuild context (meaning
# that we are being called during a build to validate the .xcfilelists
# for the current build configuration) or from the command line (to
# validate all .xcfilelists). We'll determine which of these is the
# case by checking $GX_PROJECT_TAG (which will have been set via the
# --project <TAG> option passed in to us when we're invoked in this
# context).
#
# Further, if called from within xcodebuild, it's important to know if
# we're being called from within Xcode or being invoked by a Makefile.
# If the former, the output/build files we are looking for are found in
# ~/Library/Developer/Xcode/DerivedData. Otherwise, they'll be found in
# OpenSource/WebKitBuild (or whatever $WEBKIT_OUTPUTDIR points to). We
# need to distinguish between these so that we can tell the user how to
# invoke us in a way that finds the right output/build files.
#
# If invoked from the command line, we really can't tell where the
# output files are, so give the user advice in this area.
local GX_MESSAGE='".xcfilelist" files tell the build system what files
are consumed and produced by the "Run Script" build phases in
Xcode. At least one of these .xcfilelist files are out of date and
need to be regenerated. Regenerate these files by running
`Tools/Scripts/generate-xcfilelists generate'
if [[ -n "${GX_PROJECT_TAG}" ]]
then
local GX_MESSAGE+=" --project ${GX_PROJECT_TAG}"
if [[ "${SYMROOT}" =~ Library/Developer/Xcode/DerivedData ]]
then
local GX_MESSAGE+=" --xcode"
fi
else
if (( ${GX_USE_XCODE_BUILD_OUTPUT} ))
then
local GX_MESSAGE+=" --xcode"
fi
fi
local GX_MESSAGE+='`, or manually add the file or files shown above to
the indicated .xcfilelist files. Then restart your build. When
submitting, include the updated .xcfilelist files.'
log_progress_long "${GX_MESSAGE}"
fi
}
function do_generate()
{
# Invoked from the command line to generate .xcfilelist files. Use any
# specified project, platform, and/or configuration. Any of those that
# aren't specified results in our iterating over all possible values for
# the unspecified value.
log_callstack_and_parameters "$@"
if [[ -z "${GX_PROJECT_TAG}" ]]
then
log_progress "=== Generating all .xcfilelists ==="
else
log_progress "=== Generating .xcfilelists for ${GX_PROJECT_TAG} ==="
fi
for_each_project \
generate_xcfilelists
}
function do_merge()
{
# Implicitly invoked for generate and generate-xcode operations to move the
# temporary results into the Xcode project.
log_callstack_and_parameters "$@"
if [[ -z "${GX_PROJECT_TAG}" ]]
then
log_progress "=== Merging all .xcfilelists into place ==="
else
log_progress "=== Merging .xcfilelists for ${GX_PROJECT_TAG} ==="
fi
for_each_project \
merge_xcfilelists
log_debug "GX_DEFERRED_EXIT_CODE = $GX_DEFERRED_EXIT_CODE"
}
function do_check()
{
# Implicitly invoked for check and check-xcode operations to check the
# temporary results against the Xcode project.
log_callstack_and_parameters "$@"
# Being invoked from the command-line to check everything.
if [[ -z "${GX_PROJECT_TAG}" ]]
then
log_progress "=== Checking all .xcfilelists ==="
else
log_progress "=== Checking .xcfilelists for ${GX_PROJECT_TAG} ==="
fi
for_each_project \
check_xcfilelists
}
function do_subgenerate()
{
# Invoked from within an Xcode context to generate .xcfilelist files. Use
# the project, platform, an configuration established in the environment.
log_callstack_and_parameters "$@"
[[ -n "${GX_PROJECT_TAG}" ]] || die "GX_PROJECT_TAG is not defined."
[[ -n "${PROJECT_NAME}" ]] || die "subgenerate should only be invoked in an Xcode context."
log_progress "=== Generating .xcfilelists for ${PROJECT_NAME}/${PLATFORM_NAME}/${CONFIGURATION} ==="
set_project_settings
# We're called during generate-xcode, check-xcode, and subgenerate
# operations. We need to reset our project-specific temp files for the
# first two, but not the last one.
(( ${GX_DO_SUBGENERATE} )) || reset_project_specific_temp_files
subgenerate_xcfilelists
}
function main()
{
log_callstack_and_parameters "$@"
log_debug_var GX_ME
log_debug_var GX_HERE
log_debug_var GX_ROOT_DIR
log_debug_var GX_OPENSOURCE_DIR
log_debug_var GX_TEMP
log_debug_var GX_PROJECT_TAGS
log_debug_var GX_CONFIGURATIONS
log_debug_var GX_SUBEXECUTE_SCRIPT
log_debug_var GX_DO_GENERATE
log_debug_var GX_DO_GENERATE_XCODE
log_debug_var GX_DO_CHECK
log_debug_var GX_DO_CHECK_XCODE
log_debug_var GX_DO_SUBGENERATE
log_debug_var GX_DO_CLEANUP
log_debug_var GX_USE_XCODE_BUILD_OUTPUT
log_debug_var GX_USE_WEBKITBUILD_BUILD_OUTPUT
log_debug_var GX_DRY_RUN
log_debug_var GX_DEBUG
log_debug_var GX_QUIET
log_debug_var GX_ORIG_ARGS
if (( ${GX_DO_HELP} ))
then
usage
my_exit 0
fi
if (( GX_DO_GENERATE + GX_DO_GENERATE_XCODE + GX_DO_CHECK + GX_DO_CHECK_XCODE + GX_DO_SUBGENERATE + GX_DO_HELP < 1 ))
then
stderr "### One of generate, generate-xcode, check, check-xcode, subgenerate, or --help must be specified."
my_exit 1
fi
if (( GX_DO_GENERATE + GX_DO_GENERATE_XCODE + GX_DO_CHECK + GX_DO_CHECK_XCODE + GX_DO_SUBGENERATE + GX_DO_HELP > 1 ))
then
stderr "### Only one of generate, generate-xcode, check, check-xcode, subgenerate, or --help can be specified."
my_exit 1
fi
[[ -z "${GX_PROJECT_TAG}" || ( " ${GX_PROJECT_TAGS[@]} " =~ " ${GX_PROJECT_TAG} " ) ]] || { die "Unrecognized project: ${GX_PROJECT_TAG}"; }
get_canonical_platform_name "${GX_PLATFORM_NAME}" GX_PLATFORM_NAME
get_canonical_configuration "${GX_CONFIGURATION}" GX_CONFIGURATION
if (( ${GX_DO_GENERATE} ))
then
do_generate
call post_generate_hook
do_merge
call post_merge_hook
report_merge_results
elif (( ${GX_DO_GENERATE_XCODE} ))
then
do_subgenerate
call post_generate_hook
do_merge
call post_merge_hook
report_merge_results
elif (( ${GX_DO_CHECK} ))
then
do_generate
call post_generate_hook
do_check
call post_check_hook
report_remediation_steps
elif (( ${GX_DO_CHECK_XCODE} ))
then
do_subgenerate
call post_generate_hook
do_check
call post_check_hook
report_remediation_steps
elif (( ${GX_DO_SUBGENERATE} ))
then
do_subgenerate
else
stderr "### No subcommand provided"
usage
my_exit 1
fi
my_exit ${GX_DEFERRED_EXIT_CODE}
}
# Initialize and sanity check
GX_ORIG_ARGS=("$@")
GX_DO_GENERATE=0
GX_DO_GENERATE_XCODE=0
GX_DO_CHECK=0
GX_DO_CHECK_XCODE=0
GX_DO_SUBGENERATE=0
GX_DO_HELP=0
GX_DO_CLEANUP=0
GX_USE_XCODE_BUILD_OUTPUT=0
GX_USE_WEBKITBUILD_BUILD_OUTPUT=1
GX_DRY_RUN=0
GX_DEBUG=0
GX_QUIET=0
GX_DEFERRED_EXIT_CODE=0
GX_PROJECT_TAG=
GX_PLATFORM_NAME=
GX_CONFIGURATION=
GX_SDKS=()
GX_ME=$(normalize_file_path "${BASH_SOURCE[0]}")
GX_HERE=$(dirname "${GX_ME}")
GX_ROOT_DIR=$(normalize_directory_path "${GX_HERE}/../../..")
GX_OPENSOURCE_DIR="${GX_ROOT_DIR}/OpenSource"
GX_TEMP=$(normalize_directory_path /tmp/generate-xcfilelists)
GX_PROJECT_TAGS=(JavaScriptCore WebCore WebKit DumpRenderTree WebKitTestRunner)
GX_CONFIGURATIONS=(Release Debug)
GX_SUBEXECUTE_SCRIPT="${GX_ME}"
[[ -n "${GX_ROOT_DIR}" ]] || die "Could not find GX_ROOT_DIR."
[[ -n "${GX_OPENSOURCE_DIR}" ]] || die "Could not find GX_OPENSOURCE_DIR."
[[ -d "${GX_ROOT_DIR}" ]] || die "${GX_ROOT_DIR} does not exist."
[[ -d "${GX_OPENSOURCE_DIR}" ]] || die "${GX_OPENSOURCE_DIR} does not exist."
trap cleanup EXIT
ensure_directories_exist "${GX_TEMP}"
# Process command-line parameters.
while [[ "${1:+x}" ]]
do
case "${1}" in
generate) GX_DO_GENERATE=1 ;;
generate-xcode) GX_DO_GENERATE_XCODE=1 ;;
check) GX_DO_CHECK=1 ;;
check-xcode) GX_DO_CHECK_XCODE=1 ;;
subgenerate) GX_DO_SUBGENERATE=1 ;;
help) GX_DO_HELP=1 ;;
--project) shift; GX_PROJECT_TAG="$1" ;;
--platform) shift; GX_PLATFORM_NAME="$1" ;;
--configuration)shift; GX_CONFIGURATION="$1" ;;
--xcode) GX_USE_XCODE_BUILD_OUTPUT=1; GX_USE_WEBKITBUILD_BUILD_OUTPUT=0 ;;
--webkitbuild) GX_USE_XCODE_BUILD_OUTPUT=0; GX_USE_WEBKITBUILD_BUILD_OUTPUT=1 ;;
--nocleanup) GX_DO_CLEANUP=0 ;;
-n | --dry-run) GX_DRY_RUN=1 ;;
-d | --debug) GX_DEBUG=$(( $GX_DEBUG + 1 )) ;;
-q | --quiet) GX_QUIET=1 ;;
-h | --help) GX_DO_HELP=1 ;;
*) stderr "### Unknown command: $1"
usage
my_exit 1 ;;
esac
shift
done
GX_SOURCED=$([[ "$0" == "${BASH_SOURCE[@]}" ]] && echo 0 || echo 1)
if (( ! ${GX_SOURCED} ))
then
GX_INTERNAL_ME="${GX_ROOT_DIR}/Internal/Tools/Scripts/generate-xcfilelists"
if [[ -x "${GX_INTERNAL_ME}" ]]
then
"${GX_INTERNAL_ME}" "${GX_ORIG_ARGS[@]}"
else
main
fi
fi