Changeset 245364 in webkit


Ignore:
Timestamp:
May 15, 2019 3:39:57 PM (5 years ago)
Author:
Keith Rollin
Message:

Rewrite generate-xcfilelists in Python
https://bugs.webkit.org/show_bug.cgi?id=197622
<rdar://problem/50508222>

Reviewed by Jonathan Bedard, Alex Christensen.

For a number of reasons, rewrite generate-xcfilelists in Python:

  • The previous bash script was large and unmaintainable.
  • We have more internal expertise with Python than with bash.
  • The bash script used temporary files in /tmp that got stranded and were owned by root, making them awkward to clear out. <rdar://problem/49490262>
  • We needed to complete support for engineers that built with Xcode rather than the command line.
  • There are some bugs leading to mildly corrupted .xcfilelist files. It's not apparent the source of the bugs, but one general reason might be due to approaches born of using bash. Rewriting in Python may clear these up.
  • Scripts/generate-xcfilelists:
  • Scripts/webkitpy/common/attribute_saver.py: Added.

(AttributeSaver):
(AttributeSaver.init):
(AttributeSaver.enter):
(AttributeSaver.exit):

  • Scripts/webkitpy/common/attribute_saver_unittest.py: Added.

(AttributeSaverTest):
(AttributeSaverTest.SimpleTestClass):
(AttributeSaverTest.SimpleTestClass.init):
(AttributeSaverTest.test_class):
(AttributeSaverTest.test_normal_default):
(AttributeSaverTest.test_normal_value):
(AttributeSaverTest.test_normal_value_on_exception):
(AttributeSaverTest.test_normal_value_on_normal_exit):
(AttributeSaverTest.test_normal_value_with_finally_on_exception):
(AttributeSaverTest.test_normal_value_with_finally_on_normal_exit):
(AttributeSaverTest.test_normal_value_with_else_on_exception):
(AttributeSaverTest.test_normal_value_with_else_on_normal_exit):

  • Scripts/webkitpy/generate_xcfilelists_lib/init.py: Added.
  • Scripts/webkitpy/generate_xcfilelists_lib/application.py: Added.

(Application):
(Application.init):
(Application.run):
(Application._initialize):
(Application._initialize.collect_attributes):
(Application._create_parser):
(_validate_args):
(_cmd_generate):
(_cmd_check):
(_cmd_subgenerate):
(_cmd_help):
(_do_generate):
(_do_merge):
(_report_results):
(_report_merge_results):
(_report_remediation_steps):
(_report_remediation_steps.add_to_message):
(_any_have_errors):
(_any_have_actions):
(_log_progress):
(_log_results):
(get_generate_xcfilelists_script_path):
(_get_root_dir):
(get_opensource_dir):
(get_build_scripts_dir):
(get_extract_dependencies_from_makefile_script):
(get_xcode_built_products_dir):
(_getenv):

  • Scripts/webkitpy/generate_xcfilelists_lib/generators.py: Added.

(BaseGenerator):
(BaseGenerator.init):
(BaseGenerator.str):
(BaseGenerator.generate):
(BaseGenerator._sublaunch_under_xcode):
(BaseGenerator.subgenerate):
(BaseGenerator.merge):
(BaseGenerator.pickle_to_file):
(BaseGenerator.has_action):
(BaseGenerator.has_error):
(BaseGenerator.is_valid):
(BaseGenerator.report_error):
(BaseGenerator._generate_derived):
(BaseGenerator._merge_derived):
(BaseGenerator._generate_unified):
(BaseGenerator._merge_unified):
(BaseGenerator._replace):
(BaseGenerator._unexpand):
(BaseGenerator._find_added_lines):
(BaseGenerator._merge_added_lines):
(BaseGenerator._get_file_lines):
(BaseGenerator._getenv):
(BaseGenerator._get_project_file_path):
(BaseGenerator._get_project_dir):
(BaseGenerator._get_project_file_name):
(BaseGenerator._get_project_name):
(BaseGenerator._get_sym_root):
(BaseGenerator._get_obj_root):
(BaseGenerator._get_shared_precomps_dir):
(BaseGenerator._get_build_dirs):
(BaseGenerator._get_build_dirs.define_xcode_build_dirs):
(BaseGenerator._get_build_dirs.define_xcode_build_dirs.read_xcode_user_default):
(BaseGenerator._get_build_dirs.define_command_line_build_dirs):
(BaseGenerator._get_derived_sources_dir):
(BaseGenerator._get_xcfilelist_dir):
(BaseGenerator._get_input_derived_xcfilelist_project_path):
(BaseGenerator._get_output_derived_xcfilelist_project_path):
(BaseGenerator._get_input_unified_xcfilelist_project_path):
(BaseGenerator._get_output_unified_xcfilelist_project_path):
(BaseGenerator._get_generate_derived_sources_script):
(BaseGenerator._get_generate_unified_sources_script):
(JavaScriptCoreGenerator):
(JavaScriptCoreGenerator._get_project_file_path):
(JavaScriptCoreGenerator._get_generate_derived_sources_script):
(JavaScriptCoreGenerator._get_generate_unified_sources_script):
(WebCoreGenerator):
(WebCoreGenerator._get_project_file_path):
(WebCoreGenerator._get_generate_derived_sources_script):
(WebCoreGenerator._get_generate_unified_sources_script):
(WebKitGenerator):
(WebKitGenerator._get_project_file_path):
(WebKitGenerator._get_derived_sources_dir):
(WebKitGenerator._get_generate_derived_sources_script):
(WebKitGenerator._get_generate_unified_sources_script):
(DumpRenderTreeGenerator):
(DumpRenderTreeGenerator._get_project_file_path):
(DumpRenderTreeGenerator._get_generate_derived_sources_script):
(WebKitTestRunnerGenerator):
(WebKitTestRunnerGenerator._get_project_file_path):
(WebKitTestRunnerGenerator._get_generate_derived_sources_script):

  • Scripts/webkitpy/generate_xcfilelists_lib/util.py: Added.

(debug_log):
(LogEntryHelper):
(LogEntryHelper.init):
(LogEntryHelper.log_entry):
(LogEntryHelper.log_result):
(LogEntryHelper.log_exception):
(LogEntryHelper._print):
(LogEntryExit):
(LogEntryExit._show_debug_logging):
(LogEntryExitClass):
(LogEntryExitClass._show_debug_logging):
(LogEntryExitGlobal):
(LogEntryExitGlobal._show_debug_logging):
(subprocess_run):
(is_running_under_xcode):
(CheckValidItemAction):
(CheckValidItemAction.init):
(CheckValidItemAction.call):
(CheckValidItemAction.validate_item):
(CheckCommandAction):
(CheckCommandAction.call):
(InvalidCommandError):
(InvalidArgumentError):
(InvalidConfigurationError):
(CalledProcessError):
(CalledProcessError.str):

  • Scripts/webkitpy/xcode/init.py:

(xcode_hash_for_path):
(xcode_hash_for_path.convert_to_string):

  • Scripts/webkitpy/xcode/sdk.py: Added.

(SDK):
(SDK.init):
(SDK.repr):
(SDK.as_xcode_specification):
(SDK.get_preferred_sdk_for_platform):
(SDK._parse_sdk):

  • Scripts/webkitpy/xcode/sdk_unittest.py: Added.

(SDKTest):

Location:
trunk
Files:
9 added
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/Scripts/check-xcfilelists.sh

    r244987 r245364  
    99
    1010SCRIPT="${BUILD_SCRIPTS_DIR}/generate-xcfilelists"
     11[ -f "${SCRIPT}" ] || SCRIPT="${PROJECT_DIR}/../../../${WK_ADDITIONAL_SCRIPTS_DIR}/generate-xcfilelists"
    1112[ -f "${SCRIPT}" ] || SCRIPT="${PROJECT_DIR}/../../Tools/Scripts/generate-xcfilelists"
    1213[ -f "${SCRIPT}" ] || { echo "### Cannot find generate-xcfilelists script"; exit 1; }
  • trunk/Source/WebCore/Scripts/check-xcfilelists.sh

    r244987 r245364  
    99
    1010SCRIPT="${BUILD_SCRIPTS_DIR}/generate-xcfilelists"
     11[ -f "${SCRIPT}" ] || SCRIPT="${PROJECT_DIR}/../../../${WK_ADDITIONAL_SCRIPTS_DIR}/generate-xcfilelists"
    1112[ -f "${SCRIPT}" ] || SCRIPT="${PROJECT_DIR}/../../Tools/Scripts/generate-xcfilelists"
    1213[ -f "${SCRIPT}" ] || { echo "### Cannot find generate-xcfilelists script"; exit 1; }
  • trunk/Source/WebKit/Scripts/check-xcfilelists.sh

    r244987 r245364  
    99
    1010SCRIPT="${BUILD_SCRIPTS_DIR}/generate-xcfilelists"
     11[ -f "${SCRIPT}" ] || SCRIPT="${PROJECT_DIR}/../../../${WK_ADDITIONAL_SCRIPTS_DIR}/generate-xcfilelists"
    1112[ -f "${SCRIPT}" ] || SCRIPT="${PROJECT_DIR}/../../Tools/Scripts/generate-xcfilelists"
    1213[ -f "${SCRIPT}" ] || { echo "### Cannot find generate-xcfilelists script"; exit 1; }
  • trunk/Tools/ChangeLog

    r245359 r245364  
     12019-05-15  Keith Rollin  <krollin@apple.com>
     2
     3        Rewrite generate-xcfilelists in Python
     4        https://bugs.webkit.org/show_bug.cgi?id=197622
     5        <rdar://problem/50508222>
     6
     7        Reviewed by Jonathan Bedard, Alex Christensen.
     8
     9        For a number of reasons, rewrite generate-xcfilelists in Python:
     10
     11        - The previous bash script was large and unmaintainable.
     12        - We have more internal expertise with Python than with bash.
     13        - The bash script used temporary files in /tmp that got stranded and
     14          were owned by root, making them awkward to clear out.
     15          <rdar://problem/49490262>
     16        - We needed to complete support for engineers that built with Xcode
     17          rather than the command line.
     18        - There are some bugs leading to mildly corrupted .xcfilelist files.
     19          It's not apparent the source of the bugs, but one general reason
     20          might be due to approaches born of using bash. Rewriting in Python
     21          may clear these up.
     22
     23        * Scripts/generate-xcfilelists:
     24        * Scripts/webkitpy/common/attribute_saver.py: Added.
     25        (AttributeSaver):
     26        (AttributeSaver.__init__):
     27        (AttributeSaver.__enter__):
     28        (AttributeSaver.__exit__):
     29        * Scripts/webkitpy/common/attribute_saver_unittest.py: Added.
     30        (AttributeSaverTest):
     31        (AttributeSaverTest.SimpleTestClass):
     32        (AttributeSaverTest.SimpleTestClass.__init__):
     33        (AttributeSaverTest.test_class):
     34        (AttributeSaverTest.test_normal_default):
     35        (AttributeSaverTest.test_normal_value):
     36        (AttributeSaverTest.test_normal_value_on_exception):
     37        (AttributeSaverTest.test_normal_value_on_normal_exit):
     38        (AttributeSaverTest.test_normal_value_with_finally_on_exception):
     39        (AttributeSaverTest.test_normal_value_with_finally_on_normal_exit):
     40        (AttributeSaverTest.test_normal_value_with_else_on_exception):
     41        (AttributeSaverTest.test_normal_value_with_else_on_normal_exit):
     42        * Scripts/webkitpy/generate_xcfilelists_lib/__init__.py: Added.
     43        * Scripts/webkitpy/generate_xcfilelists_lib/application.py: Added.
     44        (Application):
     45        (Application.__init__):
     46        (Application.run):
     47        (Application._initialize):
     48        (Application._initialize.collect_attributes):
     49        (Application._create_parser):
     50        (_validate_args):
     51        (_cmd_generate):
     52        (_cmd_check):
     53        (_cmd_subgenerate):
     54        (_cmd_help):
     55        (_do_generate):
     56        (_do_merge):
     57        (_report_results):
     58        (_report_merge_results):
     59        (_report_remediation_steps):
     60        (_report_remediation_steps.add_to_message):
     61        (_any_have_errors):
     62        (_any_have_actions):
     63        (_log_progress):
     64        (_log_results):
     65        (get_generate_xcfilelists_script_path):
     66        (_get_root_dir):
     67        (get_opensource_dir):
     68        (get_build_scripts_dir):
     69        (get_extract_dependencies_from_makefile_script):
     70        (get_xcode_built_products_dir):
     71        (_getenv):
     72        * Scripts/webkitpy/generate_xcfilelists_lib/generators.py: Added.
     73        (BaseGenerator):
     74        (BaseGenerator.__init__):
     75        (BaseGenerator.__str__):
     76        (BaseGenerator.generate):
     77        (BaseGenerator._sublaunch_under_xcode):
     78        (BaseGenerator.subgenerate):
     79        (BaseGenerator.merge):
     80        (BaseGenerator.pickle_to_file):
     81        (BaseGenerator.has_action):
     82        (BaseGenerator.has_error):
     83        (BaseGenerator.is_valid):
     84        (BaseGenerator.report_error):
     85        (BaseGenerator._generate_derived):
     86        (BaseGenerator._merge_derived):
     87        (BaseGenerator._generate_unified):
     88        (BaseGenerator._merge_unified):
     89        (BaseGenerator._replace):
     90        (BaseGenerator._unexpand):
     91        (BaseGenerator._find_added_lines):
     92        (BaseGenerator._merge_added_lines):
     93        (BaseGenerator._get_file_lines):
     94        (BaseGenerator._getenv):
     95        (BaseGenerator._get_project_file_path):
     96        (BaseGenerator._get_project_dir):
     97        (BaseGenerator._get_project_file_name):
     98        (BaseGenerator._get_project_name):
     99        (BaseGenerator._get_sym_root):
     100        (BaseGenerator._get_obj_root):
     101        (BaseGenerator._get_shared_precomps_dir):
     102        (BaseGenerator._get_build_dirs):
     103        (BaseGenerator._get_build_dirs.define_xcode_build_dirs):
     104        (BaseGenerator._get_build_dirs.define_xcode_build_dirs.read_xcode_user_default):
     105        (BaseGenerator._get_build_dirs.define_command_line_build_dirs):
     106        (BaseGenerator._get_derived_sources_dir):
     107        (BaseGenerator._get_xcfilelist_dir):
     108        (BaseGenerator._get_input_derived_xcfilelist_project_path):
     109        (BaseGenerator._get_output_derived_xcfilelist_project_path):
     110        (BaseGenerator._get_input_unified_xcfilelist_project_path):
     111        (BaseGenerator._get_output_unified_xcfilelist_project_path):
     112        (BaseGenerator._get_generate_derived_sources_script):
     113        (BaseGenerator._get_generate_unified_sources_script):
     114        (JavaScriptCoreGenerator):
     115        (JavaScriptCoreGenerator._get_project_file_path):
     116        (JavaScriptCoreGenerator._get_generate_derived_sources_script):
     117        (JavaScriptCoreGenerator._get_generate_unified_sources_script):
     118        (WebCoreGenerator):
     119        (WebCoreGenerator._get_project_file_path):
     120        (WebCoreGenerator._get_generate_derived_sources_script):
     121        (WebCoreGenerator._get_generate_unified_sources_script):
     122        (WebKitGenerator):
     123        (WebKitGenerator._get_project_file_path):
     124        (WebKitGenerator._get_derived_sources_dir):
     125        (WebKitGenerator._get_generate_derived_sources_script):
     126        (WebKitGenerator._get_generate_unified_sources_script):
     127        (DumpRenderTreeGenerator):
     128        (DumpRenderTreeGenerator._get_project_file_path):
     129        (DumpRenderTreeGenerator._get_generate_derived_sources_script):
     130        (WebKitTestRunnerGenerator):
     131        (WebKitTestRunnerGenerator._get_project_file_path):
     132        (WebKitTestRunnerGenerator._get_generate_derived_sources_script):
     133        * Scripts/webkitpy/generate_xcfilelists_lib/util.py: Added.
     134        (debug_log):
     135        (LogEntryHelper):
     136        (LogEntryHelper.__init__):
     137        (LogEntryHelper.log_entry):
     138        (LogEntryHelper.log_result):
     139        (LogEntryHelper.log_exception):
     140        (LogEntryHelper._print):
     141        (LogEntryExit):
     142        (LogEntryExit._show_debug_logging):
     143        (LogEntryExitClass):
     144        (LogEntryExitClass._show_debug_logging):
     145        (LogEntryExitGlobal):
     146        (LogEntryExitGlobal._show_debug_logging):
     147        (subprocess_run):
     148        (is_running_under_xcode):
     149        (CheckValidItemAction):
     150        (CheckValidItemAction.__init__):
     151        (CheckValidItemAction.__call__):
     152        (CheckValidItemAction.validate_item):
     153        (CheckCommandAction):
     154        (CheckCommandAction.__call__):
     155        (InvalidCommandError):
     156        (InvalidArgumentError):
     157        (InvalidConfigurationError):
     158        (CalledProcessError):
     159        (CalledProcessError.__str__):
     160        * Scripts/webkitpy/xcode/__init__.py:
     161        (xcode_hash_for_path):
     162        (xcode_hash_for_path.convert_to_string):
     163        * Scripts/webkitpy/xcode/sdk.py: Added.
     164        (SDK):
     165        (SDK.__init__):
     166        (SDK.__repr__):
     167        (SDK.as_xcode_specification):
     168        (SDK.get_preferred_sdk_for_platform):
     169        (SDK._parse_sdk):
     170        * Scripts/webkitpy/xcode/sdk_unittest.py: Added.
     171        (SDKTest):
     172
    11732019-05-15  Aakash Jain  <aakash_jain@apple.com>
    2174
  • trunk/Tools/DumpRenderTree/Scripts/check-xcfilelists.sh

    r244987 r245364  
    99
    1010SCRIPT="${BUILD_SCRIPTS_DIR}/generate-xcfilelists"
     11[ -f "${SCRIPT}" ] || SCRIPT="${PROJECT_DIR}/../../../${WK_ADDITIONAL_SCRIPTS_DIR}/generate-xcfilelists"
    1112[ -f "${SCRIPT}" ] || SCRIPT="${PROJECT_DIR}/../../Tools/Scripts/generate-xcfilelists"
    1213[ -f "${SCRIPT}" ] || { echo "### Cannot find generate-xcfilelists script"; exit 1; }
  • trunk/Tools/Scripts/generate-xcfilelists

    r243527 r245364  
    1 #!/bin/bash
     1#!/usr/bin/env python
     2# -*- coding: utf-8 -*-
    23#
    3 # Copyright (C) 2018-2019 Apple Inc.  All rights reserved.
     4# Copyright (C) 2019 Apple Inc.  All rights reserved.
    45#
    56# Redistribution and use in source and binary forms, with or without
     
    4849# As part of its operation, this script can sub-launch itself under Xcode. It
    4950# does this in order to establish the context in which builds occur. In
    50 # particular, it does this in order to set needed environment variables. In
    51 # order to protect against environment variable name collision, all variable
    52 # names in this script start with "GX_".
     51# particular, it does this in order to set needed environment variables.
    5352
     53import sys
    5454
    55 function stdout()
    56 {
    57     (( ${GX_QUIET} )) || echo "$@" >&1
    58 }
     55from webkitpy.generate_xcfilelists_lib.application import Application
     56from webkitpy.port.config import apple_additions
    5957
    60 
    61 function stderr()
    62 {
    63     echo "$@" >&2
    64 }
    65 
    66 
    67 function remove_extra_spaces()
    68 {
    69     echo $1
    70 }
    71 
    72 function print_option()
    73 {
    74     local GX_OPTION="$1"
    75     local GX_MESSAGE="$(remove_extra_spaces "$2")"
    76 
    77     local GX_LINE
    78     local GX_LINE_WIDTH=90
    79     local GX_OPTION_WIDTH=17
    80 
    81     if (( ${#GX_OPTION} <= GX_OPTION_WIDTH ))
    82     then
    83         local GX_MESSAGE_CATENATED=$(printf "  %-${GX_OPTION_WIDTH}s %s" "$GX_OPTION" "$GX_MESSAGE")
    84         if (( ${#GX_MESSAGE_CATENATED} <= GX_LINE_WIDTH ))
    85         then
    86             stderr "${GX_MESSAGE_CATENATED}"
    87             return
    88         fi
    89 
    90         local GX_MESSAGE_FIRST_LINE="${GX_MESSAGE_CATENATED:0:${GX_LINE_WIDTH}}"    # Get the first 80 characters
    91         GX_MESSAGE_FIRST_LINE="${GX_MESSAGE_FIRST_LINE% *}"                         # Trim back to the last space
    92         GX_MESSAGE="${GX_MESSAGE_CATENATED:${#GX_MESSAGE_FIRST_LINE}+1}"            # Get the rest after that space
    93 
    94         stderr "${GX_MESSAGE_FIRST_LINE}"
    95     else
    96         stderr "  ${GX_OPTION}"
    97     fi
    98 
    99     while IFS='' read -r GX_LINE
    100     do
    101         GX_LINE=$(printf "  %${GX_OPTION_WIDTH}s %s" "" "$GX_LINE")
    102         stderr "${GX_LINE}"
    103     done < <(echo "${GX_MESSAGE}" | fold -w $(( GX_LINE_WIDTH - GX_OPTION_WIDTH - 3)) -s)
    104 }
    105 
    106 
    107 function join_by()
    108 {
    109     local GX_DELIM=$1
    110     shift
    111 
    112     echo -n "$1"
    113     shift
    114 
    115     printf "%s" "${@/#/${GX_DELIM}}"
    116 }
    117 
    118 
    119 function usage()
    120 {
    121     local GX_JOINED_PROJECT_TAGS=$(join_by ", " "${GX_PROJECT_TAGS[@]}")
    122 
    123     stderr "Usage: $(basename "${GX_ME}") [OPTION...] COMMAND [PARAMETER...]"
    124     stderr ""
    125     stderr "Generate or check .xcfilelist files"
    126     stderr ""
    127     stderr "Commands:"
    128     stderr ""
    129     print_option "generate" "Generate a complete and up-to-date set of
    130         .xcfilelist files and copy them to their appropriate places in the
    131         project directories."
    132     print_option "generate-xcode" "Generate .xcfilelist files for the current
    133         target configuration an copy them to their appropriate places in the
    134         project directories. Invoked from withing Xcode to update the current
    135         build if needed."
    136     print_option "check" "Generate a complete and up-to-date set of .xcfilelist
    137         files and compare them to their counterparts in the project
    138         directories."
    139     print_option "check-xcode" "Generate .xcfilelist files for the current
    140         target configuration and see if any files appear that aren't in the
    141         checked-in .xcfilelist files. Invoked from within Xcode to validate the
    142         current build."
    143     print_option "subgenerate" "Generate an .xcfilelist file for a particular
    144         combination of project, platform, and configuration. This operation is
    145         performed in the context of an Xcode build in order to inherit the same
    146         environment as that build."
    147     print_option "help" "Print this text and exit."
    148     stderr ""
    149     stderr "Options:"
    150     stderr ""
    151     print_option "--project <project>" "Specify which project for which to
    152         generate .xcfilelist files or to check. Possible values are
    153         (${GX_JOINED_PROJECT_TAGS}). Default is to iterate over all projects."
    154     print_option "--platform <platform>" "Specify which platform for which to
    155         generate .xcfilelist files or to check. Possible values are (macosx,
    156         iphoneos). Default is to iterate over all platforms, filtered to those
    157         platforms that a particular project supports (e.g., you can't specify
    158         'iphoneos' for WebKitTestRunner)."
    159     print_option "--configuration <configuration>" "Specify which configuration
    160         for which to generate .xcfilelist files or to check, Possible values
    161         are (release, debug). Default is to iterate over all configurations."
    162     print_option "--xcode" "Specify that existing build output can be found in
    163         the directory created by the Xcode IDE (in ~/Library/Developer/Xcode)."
    164     print_option "--webkitbuild" "Specify that existing build output can be
    165         found in the directory used by the WebKit make files or the
    166         build-webkit script (that is, in WebKitBuild or in the directory
    167         identified by WEBKIT_OUTPUTDIR). This option is the default, so it
    168         doesn't really get you anything by specifying this option (or by my
    169         implementing it)."
    170     print_option "--nocleanup" "Disable cleaning up temporary files after a
    171         subgenerate operation. Normally these are cleaned up, but if
    172         'subgenerate' is part of an overall 'generate' operation, then the
    173         'generate' operation needs to keep around the temporary files until it
    174         can complete aggregating them."
    175     stderr ""
    176     print_option "--dry-run" "When running through the requested process, don't
    177         make any material changes. For example, for 'generate', create the new
    178         .xcfilelist files, but don't copy them into their final locations"
    179     print_option "--debug" "Provide verbose output."
    180     print_option "--quiet" "Don't print any std output."
    181     print_option "--help" "Print this text and exit."
    182     stderr ""
    183 }
    184 
    185 
    186 function cleanup()
    187 {
    188     if (( ${GX_DO_CLEANUP} )) && (( ${GX_DEFERRED_EXIT_CODE} == 0 ))
    189     then
    190         rm -rf "${GX_TEMP}" &> /dev/null
    191     fi
    192 }
    193 
    194 
    195 function my_exit()
    196 {
    197     local GX_ERR=$1
    198     exit $GX_ERR
    199 }
    200 
    201 
    202 function die()
    203 {
    204     local GX_ERR=$2
    205     [[ "$GX_ERR" == "" ]] && GX_ERR=1
    206     stderr "### (${FUNCNAME[@]}) $1"
    207     my_exit $GX_ERR
    208 }
    209 
    210 
    211 function log_debug()
    212 {
    213     (( "${GX_DEBUG}" > 0 )) && stderr "GXCF: $@"
    214 }
    215 
    216 
    217 function log_debug_var()
    218 {
    219     local GX_VAR_NAME=$1
    220     local GX_IS_ARRAY=$(declare -p ${GX_VAR_NAME} 2> /dev/null | grep -q '^declare -a' && echo 1 || echo 0)
    221 
    222     if (( $GX_IS_ARRAY ))
    223     then
    224         log_debug $(printf "%-47s = (%s)" $GX_VAR_NAME "$(eval echo \$\{${GX_VAR_NAME}\[\@\]\})")
    225     else
    226         log_debug $(printf "%-47s = %s" $GX_VAR_NAME "$(eval echo \$\{${GX_VAR_NAME}\})")
    227     fi
    228 }
    229 
    230 
    231 function log_callstack_and_parameters()
    232 {
    233     if (( "${GX_DEBUG}" > "1" ))
    234     then
    235         local GX_ARGS=("$@")
    236         local GX_CALLSTACK=("${FUNCNAME[@]}")
    237         unset GX_CALLSTACK[0]
    238         stderr "GXCF: (${GX_CALLSTACK[@]}): ${GX_ARGS[@]}"
    239     fi
    240 }
    241 
    242 
    243 function log_progress()
    244 {
    245     stdout "GXCF: $@"
    246 }
    247 
    248 
    249 function log_progress_long()
    250 {
    251     local GX_MESSAGE="$(remove_extra_spaces "$1")"
    252     local GX_LINE
    253     while IFS='' read -r GX_LINE
    254     do
    255         log_progress $GX_LINE
    256     done < <(echo "${GX_MESSAGE}" | fold -w 86 -s)
    257 }
    258 
    259 
    260 function normalize_directory_path()
    261 {
    262     log_callstack_and_parameters "$@"
    263 
    264     [[ -z "$1" ]] && { echo "$1"; return; }
    265     cd "$1" 2> /dev/null || { echo "$1"; return; }
    266     pwd -P
    267 }
    268 
    269 
    270 function normalize_file_path()
    271 {
    272     log_callstack_and_parameters "$@"
    273 
    274     [[ -z "$1" ]] && { echo "$1"; return; }
    275     echo $(normalize_directory_path "$(dirname "$1")")/$(basename "$1")
    276 }
    277 
    278 
    279 function call()
    280 {
    281     log_callstack_and_parameters "$@"
    282 
    283     local GX_FN="$1"
    284     [[ "$(type -t ${GX_FN})" == "function" ]] || return $?
    285     eval "${GX_FN}"
    286 }
    287 
    288 
    289 function set_project_specific_settings_for_JavaScriptCore()
    290 {
    291     log_callstack_and_parameters "$@"
    292 
    293     GX_PS_PROJECT_FILE_PATH="${GX_OPENSOURCE_DIR}/Source/JavaScriptCore/JavaScriptCore.xcodeproj" # Can't use PROJECT_FILE_PATH because this is used pre-Xcode.
    294     GX_PS_DERIVEDSOURCES_GENERATOR_RELATIVE_PATH="Scripts/generate-derived-sources.sh"
    295     GX_PS_UNIFIEDSOURCES_GENERATOR_RELATIVE_PATH="Scripts/generate-unified-sources.sh"
    296     GX_PS_PLATFORM_NAMES=(macosx iphoneos)
    297 }
    298 
    299 
    300 function set_project_specific_settings_for_WebCore()
    301 {
    302     log_callstack_and_parameters "$@"
    303 
    304     GX_PS_PROJECT_FILE_PATH="${GX_OPENSOURCE_DIR}/Source/WebCore/WebCore.xcodeproj" # Can't use PROJECT_FILE_PATH because this is used pre-Xcode.
    305     GX_PS_DERIVEDSOURCES_GENERATOR_RELATIVE_PATH="Scripts/generate-derived-sources.sh"
    306     GX_PS_UNIFIEDSOURCES_GENERATOR_RELATIVE_PATH="Scripts/generate-unified-sources.sh"
    307     GX_PS_PLATFORM_NAMES=(macosx iphoneos)
    308 }
    309 
    310 
    311 function set_project_specific_settings_for_WebKit()
    312 {
    313     log_callstack_and_parameters "$@"
    314 
    315     GX_PS_PROJECT_FILE_PATH="${GX_OPENSOURCE_DIR}/Source/WebKit/WebKit.xcodeproj" # Can't use PROJECT_FILE_PATH because this is used pre-Xcode.
    316     GX_PS_DERIVED_SOURCES_DIR="${BUILT_PRODUCTS_DIR}/DerivedSources/WebKit2"
    317     GX_PS_DERIVEDSOURCES_GENERATOR_RELATIVE_PATH="Scripts/generate-derived-sources.sh"
    318     GX_PS_UNIFIEDSOURCES_GENERATOR_RELATIVE_PATH="Scripts/generate-unified-sources.sh"
    319     GX_PS_PLATFORM_NAMES=(macosx iphoneos)
    320 }
    321 
    322 
    323 function set_project_specific_settings_for_DumpRenderTree()
    324 {
    325     log_callstack_and_parameters "$@"
    326 
    327     GX_PS_PROJECT_FILE_PATH="${GX_OPENSOURCE_DIR}/Tools/DumpRenderTree/DumpRenderTree.xcodeproj" # Can't use PROJECT_FILE_PATH because this is used pre-Xcode.
    328     GX_PS_DERIVEDSOURCES_GENERATOR_RELATIVE_PATH="Scripts/generate-derived-sources.sh"
    329     GX_PS_PLATFORM_NAMES=(macosx)
    330 }
    331 
    332 
    333 function set_project_specific_settings_for_WebKitTestRunner()
    334 {
    335     log_callstack_and_parameters "$@"
    336 
    337     GX_PS_PROJECT_FILE_PATH="${GX_OPENSOURCE_DIR}/Tools/WebKitTestRunner/WebKitTestRunner.xcodeproj" # Can't use PROJECT_FILE_PATH because this is used pre-Xcode.
    338     GX_PS_DERIVEDSOURCES_GENERATOR_RELATIVE_PATH="Scripts/generate-derived-sources.sh"
    339     GX_PS_PLATFORM_NAMES=(macosx)
    340 }
    341 
    342 
    343 function set_project_specific_settings()
    344 {
    345     log_callstack_and_parameters "$@"
    346 
    347     # Unset the variables that the set_project_specific_settings_for_FOO
    348     # functions set. We need to do this in case the function for project BAR
    349     # doesn't define one or more of them, causing it to inherit the settings
    350     # for a previous project FOO.
    351     #
    352     # To achieve this unsetting, we prefix all the variables we want to unset
    353     # with "GX_PS_" ("PS for "project specific"). We can then gather all
    354     # variables that start with this prefix and unset them.
    355 
    356     unset ${!GX_PS_*}
    357 
    358     [[ -n "${GX_PROJECT_TAG}" ]] || die "GX_PROJECT_TAG is not defined."
    359 
    360     call set_project_specific_settings_for_${GX_PROJECT_TAG} || die "Could not set build variables for ${GX_PROJECT_TAG}."
    361 }
    362 
    363 
    364 function set_common_project_settings()
    365 {
    366     log_callstack_and_parameters "$@"
    367 
    368     local GX_EFFECTIVE_PROJECT_FILE_PATH="${GX_PS_PROJECT_FILE_PATH}"
    369     local GX_EFFECTIVE_PROJECT_DIR=$(dirname "${GX_EFFECTIVE_PROJECT_FILE_PATH}")
    370 
    371     [[ -n "${GX_EFFECTIVE_PROJECT_FILE_PATH}" ]] || die "GX_EFFECTIVE_PROJECT_FILE_PATH is not defined."
    372     [[ -d "${GX_EFFECTIVE_PROJECT_FILE_PATH}" ]] || die "${GX_EFFECTIVE_PROJECT_FILE_PATH} is not a directory."
    373     [[ -n "${GX_EFFECTIVE_PROJECT_DIR}" ]] || die "GX_EFFECTIVE_PROJECT_DIR is not defined."
    374     [[ -d "${GX_EFFECTIVE_PROJECT_DIR}" ]] || die "${GX_EFFECTIVE_PROJECT_DIR} is not a directory."
    375 
    376     # Get the paths to the scripts that drive the generation of the
    377     # .xcfilelists or the data going into the .xcfilelists.
    378 
    379     GX_DERIVEDSOURCES_GENERATOR="${GX_PS_DERIVEDSOURCES_GENERATOR_RELATIVE_PATH:+${GX_EFFECTIVE_PROJECT_DIR}/${GX_PS_DERIVEDSOURCES_GENERATOR_RELATIVE_PATH}}"
    380     GX_UNIFIEDSOURCES_GENERATOR="${GX_PS_UNIFIEDSOURCES_GENERATOR_RELATIVE_PATH:+${GX_EFFECTIVE_PROJECT_DIR}/${GX_PS_UNIFIEDSOURCES_GENERATOR_RELATIVE_PATH}}"
    381 
    382     [[ -n "${GX_DERIVEDSOURCES_GENERATOR}" ]] && { [[ -f "${GX_DERIVEDSOURCES_GENERATOR}" ]] || die "${GX_DERIVEDSOURCES_GENERATOR} does not exist."; }
    383     [[ -n "${GX_UNIFIEDSOURCES_GENERATOR}" ]] && { [[ -f "${GX_UNIFIEDSOURCES_GENERATOR}" ]] || die "${GX_UNIFIEDSOURCES_GENERATOR} does not exist."; }
    384 
    385     # Get the paths to the locations of the final .xcfilelist files.
    386 
    387     local GX_BASE_PATH="${GX_EFFECTIVE_PROJECT_DIR}/${GX_PS_XCFILELIST_RELATIVE_PATH}"
    388     GX_INPUT_DERIVED_XCFILELIST_PROJECT_PATH="${GX_BASE_PATH}/DerivedSources-input.xcfilelist"
    389     GX_OUTPUT_DERIVED_XCFILELIST_PROJECT_PATH="${GX_BASE_PATH}/DerivedSources-output.xcfilelist"
    390     GX_OUTPUT_UNIFIED_XCFILELIST_PROJECT_PATH="${GX_BASE_PATH}/UnifiedSources-output.xcfilelist"
    391 
    392     # Get the paths to the locations of the temporary .xcfilelist files (the
    393     # ones being built up before being moved to their final locations).
    394 
    395     GX_INPUT_DERIVED_XCFILELIST_PROJECT_TEMP_PATH="${GX_TEMP}/${GX_INPUT_DERIVED_XCFILELIST_PROJECT_PATH}"
    396     GX_OUTPUT_DERIVED_XCFILELIST_PROJECT_TEMP_PATH="${GX_TEMP}/${GX_OUTPUT_DERIVED_XCFILELIST_PROJECT_PATH}"
    397     GX_OUTPUT_UNIFIED_XCFILELIST_PROJECT_TEMP_PATH="${GX_TEMP}/${GX_OUTPUT_UNIFIED_XCFILELIST_PROJECT_PATH}"
    398 
    399     # Collect the default per-project commands to execute during the generate,
    400     # merge, and compare stages.
    401 
    402     GX_SUBGENERATE_ACTIONS=()
    403     GX_MERGE_ACTIONS=()
    404     GX_CHECK_ACTIONS=()
    405 
    406     if [[ -n "${GX_DERIVEDSOURCES_GENERATOR}" ]]
    407     then
    408         GX_SUBGENERATE_ACTIONS+=(generate_derivedsources_xcfilelists)
    409         GX_MERGE_ACTIONS+=(merge_derivedsources_xcfilelists)
    410         GX_CHECK_ACTIONS+=(check_derivedsources_xcfilelists)
    411     fi
    412 
    413     if [[ -n "${GX_UNIFIEDSOURCES_GENERATOR}" ]]
    414     then
    415         GX_SUBGENERATE_ACTIONS+=(generate_unifiedsources_xcfilelists)
    416         GX_MERGE_ACTIONS+=(merge_unifiedsources_xcfilelists)
    417         GX_CHECK_ACTIONS+=(check_unifiedsources_xcfilelists)
    418     fi
    419 
    420     [[ -z "${GX_PS_DERIVED_SOURCES_DIR}" ]] && GX_PS_DERIVED_SOURCES_DIR="${BUILT_PRODUCTS_DIR}/DerivedSources/${PROJECT_NAME}"
    421 
    422     GX_TEMP_INPUT_XCFILELIST="${GX_TEMP}/input.xcfilelist"
    423     GX_TEMP_OUTPUT_XCFILELIST="${GX_TEMP}/output.xcfilelist"
    424 }
    425 
    426 
    427 function dump_project_settings()
    428 {
    429     log_callstack_and_parameters "$@"
    430 
    431     log_debug_var BUILD_SCRIPTS_DIR
    432     log_debug_var BUILT_PRODUCTS_DIR
    433     log_debug_var CONFIGURATION
    434     log_debug_var DERIVED_SOURCES_DIR
    435     log_debug_var JAVASCRIPTCORE_PRIVATE_HEADERS_DIR
    436     log_debug_var PROJECT_DIR
    437     log_debug_var PROJECT_FILE_PATH
    438     log_debug_var PROJECT_NAME
    439     log_debug_var WEBCORE_PRIVATE_HEADERS_DIR
    440     log_debug_var WEBKIT2_PRIVATE_HEADERS_DIR
    441     log_debug
    442     log_debug_var GX_PS_PROJECT_FILE_PATH
    443     log_debug_var GX_PS_DERIVEDSOURCES_GENERATOR_RELATIVE_PATH
    444     log_debug_var GX_PS_UNIFIEDSOURCES_GENERATOR_RELATIVE_PATH
    445     log_debug_var GX_PS_XCFILELIST_RELATIVE_PATH
    446     log_debug_var GX_PS_PLATFORM_NAMES
    447     log_debug
    448     log_debug_var GX_PROJECT_TAG
    449     log_debug_var GX_PLATFORM_NAME
    450     log_debug_var GX_CONFIGURATION
    451     log_debug
    452     log_debug_var GX_EFFECTIVE_PROJECT_FILE_PATH
    453     log_debug_var GX_EFFECTIVE_PROJECT_DIR
    454     log_debug
    455     log_debug_var GX_DERIVEDSOURCES_GENERATOR
    456     log_debug_var GX_UNIFIEDSOURCES_GENERATOR
    457     log_debug
    458     log_debug_var GX_INPUT_DERIVED_XCFILELIST_PROJECT_TEMP_PATH
    459     log_debug_var GX_OUTPUT_DERIVED_XCFILELIST_PROJECT_TEMP_PATH
    460     log_debug_var GX_OUTPUT_UNIFIED_XCFILELIST_PROJECT_TEMP_PATH
    461     log_debug
    462     log_debug_var GX_INPUT_DERIVED_XCFILELIST_PROJECT_PATH
    463     log_debug_var GX_OUTPUT_DERIVED_XCFILELIST_PROJECT_PATH
    464     log_debug_var GX_OUTPUT_UNIFIED_XCFILELIST_PROJECT_PATH
    465     log_debug
    466     log_debug_var GX_PS_DERIVED_SOURCES_DIR
    467     log_debug
    468     log_debug_var GX_SUBGENERATE_ACTIONS
    469     log_debug_var GX_MERGE_ACTIONS
    470     log_debug_var GX_CHECK_ACTIONS
    471 }
    472 
    473 
    474 function set_project_settings()
    475 {
    476     log_callstack_and_parameters "$@"
    477 
    478     [[ -z "${GX_PROJECT_TAG}" ]] && return
    479 
    480     set_project_specific_settings
    481     set_common_project_settings
    482     dump_project_settings
    483 }
    484 
    485 
    486 function ensure_directories_exist()
    487 {
    488     log_callstack_and_parameters "$@"
    489 
    490     local GX_DIR
    491     for GX_DIR in "$@"
    492     do
    493         log_debug "Creating ${GX_DIR}"
    494         mkdir -p "${GX_DIR}" &> /dev/null || die "Unable to create "${GX_DIR}"."
    495     done
    496 }
    497 
    498 
    499 function create_empty_files()
    500 {
    501     log_callstack_and_parameters "$@"
    502 
    503     local GX_FILE
    504     for GX_FILE in "$@"
    505     do
    506         ensure_directories_exist "$(dirname "${GX_FILE}")"
    507 
    508         log_debug "Creating ${GX_FILE}"
    509         echo -n '' > "${GX_FILE}"
    510     done
    511 }
    512 
    513 
    514 function append_xcfilelist_header()
    515 {
    516     log_callstack_and_parameters "$@"
    517 
    518     local GX_FILE
    519     for GX_FILE in "$@"
    520     do
    521         echo '# This file is generated by the generate-xcfilelists script.' >> "${GX_FILE}"
    522     done
    523 }
    524 
    525 
    526 function sort_and_unique_in_place()
    527 {
    528     sort -u "$1" -o "$1"
    529 }
    530 
    531 
    532 function replace()
    533 {
    534     log_callstack_and_parameters "$@"
    535 
    536     local GX_FILE="$1"
    537     local GX_PATTERN="$2"
    538     local GX_REPLACEMENT="$3"
    539 
    540     [[ -n "${GX_FILE}" ]] || die "GX_FILE is not defined."
    541     [[ -f "${GX_FILE}" ]] || die "${GX_FILE} does not exist."
    542 
    543     sed -E -e "s|${GX_PATTERN}|${GX_REPLACEMENT}|" -i '' "${GX_FILE}"
    544 }
    545 
    546 
    547 function unexpand()
    548 {
    549     log_callstack_and_parameters "$@"
    550 
    551     local GX_FILE="$1"
    552     local GX_VAR="$2"
    553     local GX_VALUE=$(eval echo \$${GX_VAR})
    554 
    555     [[ -n "${GX_VALUE}" ]] && replace "${GX_FILE}" "^${GX_VALUE}/" "\$\($GX_VAR\)/"
    556 }
    557 
    558 
    559 function find_additions()
    560 {
    561     # Find additions and removals so that we can report them.
    562     #
    563     # UPDATE: We can't really report removals. It's possible -- even
    564     # overwhelmingly likely -- that we are generating .xcfilelist information
    565     # for only a subset of the possible configurations for which we build. For
    566     # example, a developer may be building for macOS and iOS, but not watchOS.
    567     # In situations like this, we'll be generating the .xcfilelist for those
    568     # two platforms, but any files specific to watchOS will not be discovered
    569     # and won't be included in the .xcfilelists. If we were to report those
    570     # watchOS files as files that should be removed from the .xcfilelists, then
    571     # the watchOS build may fail. So, for now, let any obsolete files
    572     # accumulate in the .xcfilelist files; they're mostly harmless.
    573 
    574     local GX_NEW="$1"
    575     local GX_ORIG="$2"
    576     local GX_ADDITIONS="$3"
    577 
    578     [[ -f "${GX_NEW}" ]] || die "${GX_NEW} does not exist."
    579     [[ -f "${GX_ORIG}" ]] || die "${GX_ORIG} does not exist."
    580 
    581     comm -2 -3 <(sort "${GX_NEW}") <(sort "${GX_ORIG}") > "${GX_ADDITIONS}"
    582 }
    583 
    584 
    585 function get_sdks()
    586 {
    587     log_callstack_and_parameters "$@"
    588 
    589     (( ${#GX_SDKS[@]} )) && return
    590 
    591     GX_SDKS=($(
    592         xcodebuild -showsdks \
    593         | grep -e '\s-sdk\s' \
    594         | sed -E \
    595             -e 's/.*-sdk ([^[:digit:]]+)$/\1/' \
    596             -e 's/.*-sdk ([^[:digit:]]+)([[:digit:]\.]+)$/\1/' \
    597             -e 's/.*-sdk ([^[:digit:]]+)([[:digit:]\.]+)([^[:digit:]]+)$/\1.\3/' \
    598         | sort -u
    599     ))
    600 
    601     (( ${#GX_SDKS[@]} )) || die "Unable to find any SDKs."
    602 }
    603 
    604 
    605 function get_canonical_configuration()
    606 {
    607     log_callstack_and_parameters "$@"
    608 
    609     local GX_PROVISIONAL_CONFIGURATION=$(echo "$1" | tr '[:upper:]' '[:lower:]')
    610     local GX_RESULT=$2
    611 
    612     [[ "${GX_PROVISIONAL_CONFIGURATION}" == "" ]]           && { eval $GX_RESULT=""; return; }
    613 
    614     [[ "${GX_PROVISIONAL_CONFIGURATION}" == "debug" ]]      && { eval $GX_RESULT="Debug"; return; }
    615     [[ "${GX_PROVISIONAL_CONFIGURATION}" == "release" ]]    && { eval $GX_RESULT="Release"; return; }
    616     [[ "${GX_PROVISIONAL_CONFIGURATION}" == "production" ]] && { eval $GX_RESULT="Production"; return; }
    617     [[ "${GX_PROVISIONAL_CONFIGURATION}" == "profiling" ]]  && { eval $GX_RESULT="Profiling"; return; }
    618 
    619     die "Unrecognized configuration: $1"
    620 }
    621 
    622 
    623 function get_canonical_platform_name()
    624 {
    625     log_callstack_and_parameters "$@"
    626 
    627     local GX_PROVISIONAL_PLATFORM_NAME=$(echo "$1" | tr '[:upper:]' '[:lower:]')
    628     local GX_RESULT=$2
    629 
    630     [[ "${GX_PROVISIONAL_PLATFORM_NAME}" == "" ]]                   && { eval $GX_RESULT=""; return; }
    631 
    632     [[ "${GX_PROVISIONAL_PLATFORM_NAME}" == "ios" ]]                && { eval $GX_RESULT="iphoneos"; return; }
    633     [[ "${GX_PROVISIONAL_PLATFORM_NAME}" == "iphone" ]]             && { eval $GX_RESULT="iphoneos"; return; }
    634     [[ "${GX_PROVISIONAL_PLATFORM_NAME}" == "ipad" ]]               && { eval $GX_RESULT="iphoneos"; return; }
    635     [[ "${GX_PROVISIONAL_PLATFORM_NAME}" == "iphoneos" ]]           && { eval $GX_RESULT="iphoneos"; return; }
    636     [[ "${GX_PROVISIONAL_PLATFORM_NAME}" == "iphonesimulator" ]]    && { eval $GX_RESULT="iphonesimulator"; return; }
    637 
    638     [[ "${GX_PROVISIONAL_PLATFORM_NAME}" == "mac" ]]                && { eval $GX_RESULT="macosx"; return; }
    639     [[ "${GX_PROVISIONAL_PLATFORM_NAME}" == "osx" ]]                && { eval $GX_RESULT="macosx"; return; }
    640     [[ "${GX_PROVISIONAL_PLATFORM_NAME}" == "macos" ]]              && { eval $GX_RESULT="macosx"; return; }
    641     [[ "${GX_PROVISIONAL_PLATFORM_NAME}" == "macosx" ]]             && { eval $GX_RESULT="macosx"; return; }
    642 
    643     [[ "${GX_PROVISIONAL_PLATFORM_NAME}" == "tvos" ]]               && { eval $GX_RESULT="appletvos"; return; }
    644     [[ "${GX_PROVISIONAL_PLATFORM_NAME}" == "appletvos" ]]          && { eval $GX_RESULT="appletvos"; return; }
    645     [[ "${GX_PROVISIONAL_PLATFORM_NAME}" == "tvsimulator" ]]        && { eval $GX_RESULT="appletvsimulator"; return; }
    646     [[ "${GX_PROVISIONAL_PLATFORM_NAME}" == "appletvsimulator" ]]   && { eval $GX_RESULT="appletvsimulator"; return; }
    647 
    648     [[ "${GX_PROVISIONAL_PLATFORM_NAME}" == "watchos" ]]            && { eval $GX_RESULT="watchos"; return; }
    649     [[ "${GX_PROVISIONAL_PLATFORM_NAME}" == "watchsimulator" ]]     && { eval $GX_RESULT="watchsimulator"; return; }
    650 
    651     die "Unrecognized platform name: $1"
    652 }
    653 
    654 
    655 function get_sdk_name()
    656 {
    657     log_callstack_and_parameters "$@"
    658 
    659     local GX_SDK=$1
    660     local GX_RESULT=$2
    661     get_canonical_platform_name "${GX_SDK}" GX_SDK
    662     local GX_INTERNAL_SDK="${GX_SDK}.internal"
    663 
    664     get_sdks
    665 
    666     # Prefer an internal SDK if one exists.
    667 
    668     [[ " ${GX_SDKS[@]} " =~ " ${GX_INTERNAL_SDK} " ]]   && { eval $GX_RESULT="${GX_INTERNAL_SDK}"; return; }
    669     [[ " ${GX_SDKS[@]} " =~ " ${GX_SDK} " ]]            && { eval $GX_RESULT="${GX_SDK}"; return; }
    670 
    671     die "Unsupported SDK: ${GX_SDK}."
    672 }
    673 
    674 
    675 function invoke_each_action()
    676 {
    677     log_callstack_and_parameters "$@"
    678 
    679     local GX_ACTION
    680     for GX_ACTION in "$@"
    681     do
    682         eval "${GX_ACTION}"
    683     done
    684 }
    685 
    686 
    687 function for_each_configuration()
    688 {
    689     log_callstack_and_parameters "$@"
    690 
    691     if [[ -z "${GX_CONFIGURATION}" ]]
    692     then
    693         for GX_CONFIGURATION in "${GX_CONFIGURATIONS[@]}"
    694         do
    695             eval "$@"
    696         done
    697 
    698         GX_CONFIGURATION=
    699     else
    700         eval "$@"
    701     fi
    702 }
    703 
    704 
    705 function for_each_platform()
    706 {
    707     log_callstack_and_parameters "$@"
    708 
    709     if [[ -z "${GX_PLATFORM_NAME}" ]]
    710     then
    711         for GX_PLATFORM_NAME in "${GX_PS_PLATFORM_NAMES[@]}"
    712         do
    713             eval "$@"
    714         done
    715 
    716         GX_PLATFORM_NAME=
    717     else
    718         eval "$@"
    719     fi
    720 }
    721 
    722 
    723 function for_each_project()
    724 {
    725     log_callstack_and_parameters "$@"
    726 
    727     if [[ -z "${GX_PROJECT_TAG}" ]]
    728     then
    729         for GX_PROJECT_TAG in "${GX_PROJECT_TAGS[@]}"
    730         do
    731             set_project_settings
    732             eval "$@"
    733         done
    734 
    735         GX_PROJECT_TAG=
    736     else
    737         set_project_settings
    738         eval "$@"
    739     fi
    740 }
    741 
    742 
    743 function generate_derivedsources_xcfilelists()
    744 {
    745     log_callstack_and_parameters "$@"
    746 
    747     create_empty_files "${GX_TEMP_INPUT_XCFILELIST}" "${GX_TEMP_OUTPUT_XCFILELIST}"
    748 
    749     local GX_DERIVEDSOURCES_EXTRACTOR="${GX_HERE}/extract-dependencies-from-makefile"
    750 
    751     [[ -n "${GX_DERIVEDSOURCES_GENERATOR}" ]] || die "GX_DERIVEDSOURCES_GENERATOR is not defined."
    752     [[ -x "${GX_DERIVEDSOURCES_GENERATOR}" ]] || die "${GX_DERIVEDSOURCES_GENERATOR} does not exist or is not executable."
    753     [[ -x "${GX_DERIVEDSOURCES_EXTRACTOR}" ]] || die "${GX_DERIVEDSOURCES_EXTRACTOR} does not exist or is not executable."
    754 
    755     log_debug "Creating derived .xcfilelists for ${PROJECT_NAME}/${PLATFORM_NAME}/${CONFIGURATION}"
    756 
    757     "${GX_DERIVEDSOURCES_GENERATOR}" \
    758         NO_SUPPLEMENTAL_FILES=1 \
    759         --no-builtin-rules \
    760         --dry-run \
    761         --always-make \
    762         --debug=abvijm all \
    763         1> "${GX_TEMP}/std.out" 2> "${GX_TEMP}/std.err"
    764     local GX_RESULT=$?
    765 
    766     if (( ${GX_RESULT} ))
    767     then
    768         sed -E -e 's/^/GXCF: /' < "${GX_TEMP}/std.err"
    769         die "Error generating derived sources: error = ${GX_RESULT}" ${GX_RESULT}
    770     fi
    771 
    772     cat "${GX_TEMP}/std.out" \
    773     | "${GX_DERIVEDSOURCES_EXTRACTOR}" \
    774         --input "${GX_TEMP_INPUT_XCFILELIST}" \
    775         --output "${GX_TEMP_OUTPUT_XCFILELIST}"
    776     local GX_RESULT=$?
    777 
    778     (( ${GX_RESULT} )) && die "Error extracting dependencies from DerivedSources.make: error = ${GX_RESULT}"
    779     [[ -f "${GX_TEMP_INPUT_XCFILELIST}" ]] || die "${GX_TEMP_INPUT_XCFILELIST} was not generated."
    780     [[ -f "${GX_TEMP_OUTPUT_XCFILELIST}" ]] || die "${GX_TEMP_OUTPUT_XCFILELIST} was not generated."
    781 
    782     replace "${GX_TEMP_INPUT_XCFILELIST}" '^WebCore/'                      '$(PROJECT_DIR)/'
    783     replace "${GX_TEMP_INPUT_XCFILELIST}" '^JavaScriptCore/'               '$(PROJECT_DIR)/'
    784     replace "${GX_TEMP_INPUT_XCFILELIST}" '^JavaScriptCorePrivateHeaders/' '$(JAVASCRIPTCORE_PRIVATE_HEADERS_DIR)/'
    785     replace "${GX_TEMP_INPUT_XCFILELIST}" '^WebKit2PrivateHeaders/'        '$(WEBKIT2_PRIVATE_HEADERS_DIR)/'
    786     unexpand "${GX_TEMP_INPUT_XCFILELIST}" PROJECT_DIR
    787     unexpand "${GX_TEMP_INPUT_XCFILELIST}" WEBKITADDITIONS_HEADERS_FOLDER_PATH
    788     unexpand "${GX_TEMP_INPUT_XCFILELIST}" WEBCORE_PRIVATE_HEADERS_DIR
    789     unexpand "${GX_TEMP_INPUT_XCFILELIST}" WEBKIT2_PRIVATE_HEADERS_DIR
    790     unexpand "${GX_TEMP_INPUT_XCFILELIST}" JAVASCRIPTCORE_PRIVATE_HEADERS_DIR
    791     unexpand "${GX_TEMP_INPUT_XCFILELIST}" BUILT_PRODUCTS_DIR
    792 
    793     replace "${GX_TEMP_OUTPUT_XCFILELIST}" "^" "${GX_PS_DERIVED_SOURCES_DIR}/"
    794     unexpand "${GX_TEMP_OUTPUT_XCFILELIST}" BUILT_PRODUCTS_DIR
    795 
    796     merge_xcfilelists_helper "${GX_TEMP_INPUT_XCFILELIST}" "${GX_INPUT_DERIVED_XCFILELIST_PROJECT_TEMP_PATH}"
    797     merge_xcfilelists_helper "${GX_TEMP_OUTPUT_XCFILELIST}" "${GX_OUTPUT_DERIVED_XCFILELIST_PROJECT_TEMP_PATH}"
    798 }
    799 
    800 
    801 function generate_unifiedsources_xcfilelists()
    802 {
    803     log_callstack_and_parameters "$@"
    804 
    805     create_empty_files "${GX_TEMP_OUTPUT_XCFILELIST}"
    806 
    807     [[ -n "${GX_UNIFIEDSOURCES_GENERATOR}" ]] || die "GX_UNIFIEDSOURCES_GENERATOR is not defined."
    808     [[ -x "${GX_UNIFIEDSOURCES_GENERATOR}" ]] || die "${GX_UNIFIEDSOURCES_GENERATOR} does not exist or is not executable."
    809 
    810     local GX_BUILD_SCRIPTS_DIR="${GX_OPENSOURCE_DIR}/Source/WTF/Scripts"
    811     [[ -d "${GX_BUILD_SCRIPTS_DIR}" ]] || die "${GX_BUILD_SCRIPTS_DIR} does not exist or is not a directory."
    812     [[ -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."
    813 
    814     log_debug "Creating unified .xcfilelists for ${PROJECT_NAME}/${PLATFORM_NAME}/${CONFIGURATION}"
    815 
    816     BUILD_SCRIPTS_DIR="${GX_BUILD_SCRIPTS_DIR}" \
    817     "${GX_UNIFIEDSOURCES_GENERATOR}" \
    818         --generate-xcfilelists \
    819         --output-xcfilelist-path "${GX_TEMP_OUTPUT_XCFILELIST}"
    820     GX_RESULT=$?
    821 
    822     (( ${GX_RESULT} )) && die "Error generating unified sources: error = ${GX_RESULT}"
    823     [[ -f "${GX_TEMP_OUTPUT_XCFILELIST}" ]] || die "${GX_TEMP_OUTPUT_XCFILELIST} was not generated."
    824 
    825     unexpand "${GX_TEMP_OUTPUT_XCFILELIST}" BUILT_PRODUCTS_DIR
    826 
    827     merge_xcfilelists_helper "${GX_TEMP_OUTPUT_XCFILELIST}" "${GX_OUTPUT_UNIFIED_XCFILELIST_PROJECT_TEMP_PATH}"
    828 }
    829 
    830 
    831 function subgenerate_xcfilelists()
    832 {
    833     log_callstack_and_parameters "$@"
    834 
    835     invoke_each_action "${GX_SUBGENERATE_ACTIONS[@]}"
    836 }
    837 
    838 
    839 function sublaunch_under_xcode()
    840 {
    841     log_callstack_and_parameters "$@"
    842 
    843     # Sublaunch the script for the given project, for each platform for which
    844     # the project is built, and for Debug and Release configurations.
    845 
    846     local GX_ARGS=("$@")
    847     (( ${GX_DRY_RUN} )) && GX_ARGS+=("--dry-run")
    848     (( ${GX_DEBUG} )) && { for n in $(seq $GX_DEBUG); do GX_ARGS+=("--debug"); done; }
    849     (( ${GX_QUIET} )) && GX_ARGS+=("--quiet")
    850 
    851     local GX_SDK_NAME
    852     get_sdk_name "${GX_PLATFORM_NAME}" GX_SDK_NAME
    853 
    854     log_debug "Sublaunching for: ${GX_PROJECT_TAG}/${GX_PLATFORM_NAME}/${GX_CONFIGURATION}"
    855 
    856     local GX_XCODE_PARAMETERS=(
    857         -project "${GX_PS_PROJECT_FILE_PATH}"
    858         -sdk "${GX_SDK_NAME}"
    859         -configuration "${GX_CONFIGURATION}"
    860         -target "Apply Configuration to XCFileLists"
    861     )
    862 
    863     if (( ${GX_USE_WEBKITBUILD_BUILD_OUTPUT} ))
    864     then
    865         local GX_WEBKITBUILD_DIR="${WEBKIT_OUTPUTDIR:-${GX_OPENSOURCE_DIR}/WebKitBuild}"
    866         [[ -d "${GX_WEBKITBUILD_DIR}" ]] || die "${GX_WEBKITBUILD_DIR} does not exist."
    867 
    868         GX_XCODE_PARAMETERS+=(
    869             SYMROOT="${GX_WEBKITBUILD_DIR}"
    870             OBJROOT="${GX_WEBKITBUILD_DIR}"
    871             SHARED_PRECOMPS_DIR="${GX_WEBKITBUILD_DIR}/PrecompiledHeaders"
    872         )
    873     fi
    874 
    875     if (( $GX_DEBUG > 0 ))
    876     then
    877         WK_SUBLAUNCH_SCRIPT_PARAMETERS=("${GX_ARGS[@]}") xcodebuild "${GX_XCODE_PARAMETERS[@]}"
    878     else
    879         WK_SUBLAUNCH_SCRIPT_PARAMETERS=("${GX_ARGS[@]}") xcodebuild "${GX_XCODE_PARAMETERS[@]}" | grep '^\.\.\. '
    880     fi
    881 
    882     local GX_RESULT=${PIPESTATUS[0]}
    883     (( ${GX_RESULT} )) && die "Error sub-launching under xcode: error = ${GX_RESULT}"
    884 }
    885 
    886 
    887 function reset_project_specific_temp_files()
    888 {
    889     log_callstack_and_parameters "$@"
    890 
    891     create_empty_files \
    892         "${GX_INPUT_DERIVED_XCFILELIST_PROJECT_TEMP_PATH}" "${GX_OUTPUT_DERIVED_XCFILELIST_PROJECT_TEMP_PATH}" \
    893         "${GX_OUTPUT_UNIFIED_XCFILELIST_PROJECT_TEMP_PATH}"
    894 }
    895 
    896 
    897 function generate_xcfilelists()
    898 {
    899     log_callstack_and_parameters "$@"
    900 
    901     reset_project_specific_temp_files
    902 
    903     for_each_platform \
    904         for_each_configuration \
    905             sublaunch_under_xcode \
    906                 "${GX_SUBEXECUTE_SCRIPT}" subgenerate --nocleanup --project "${GX_PROJECT_TAG}"
    907 }
    908 
    909 
    910 function merge_xcfilelists_helper()
    911 {
    912     log_callstack_and_parameters "$@"
    913 
    914     local GX_SOURCE="$1"
    915     local GX_DEST="$2"
    916     local GX_ADDITIONS="${GX_TEMP}/diff_added.tmp"
    917 
    918     append_xcfilelist_header "${GX_SOURCE}"
    919     sort_and_unique_in_place "${GX_SOURCE}"
    920 
    921     find_additions "${GX_SOURCE}" "${GX_DEST}" "${GX_ADDITIONS}"
    922 
    923     if [[ -s "${GX_ADDITIONS}" ]]
    924     then
    925         cat "${GX_SOURCE}" >> "${GX_DEST}"
    926         sort_and_unique_in_place "${GX_DEST}"
    927         return 0
    928     fi
    929 
    930     return 1
    931 }
    932 
    933 
    934 function merge_derivedsources_xcfilelists()
    935 {
    936     log_callstack_and_parameters "$@"
    937 
    938     log_debug "Merging ${GX_INPUT_DERIVED_XCFILELIST_PROJECT_TEMP_PATH} into ${GX_INPUT_DERIVED_XCFILELIST_PROJECT_PATH}"
    939     log_debug "Merging ${GX_OUTPUT_DERIVED_XCFILELIST_PROJECT_TEMP_PATH} into ${GX_OUTPUT_DERIVED_XCFILELIST_PROJECT_PATH}"
    940 
    941     if (( ! ${GX_DRY_RUN} ))
    942     then
    943         merge_xcfilelists_helper "${GX_INPUT_DERIVED_XCFILELIST_PROJECT_TEMP_PATH}" "${GX_INPUT_DERIVED_XCFILELIST_PROJECT_PATH}" && GX_DEFERRED_EXIT_CODE=3
    944         log_debug "GX_DEFERRED_EXIT_CODE = $GX_DEFERRED_EXIT_CODE"
    945 
    946         merge_xcfilelists_helper "${GX_OUTPUT_DERIVED_XCFILELIST_PROJECT_TEMP_PATH}" "${GX_OUTPUT_DERIVED_XCFILELIST_PROJECT_PATH}" && GX_DEFERRED_EXIT_CODE=3
    947         log_debug "GX_DEFERRED_EXIT_CODE = $GX_DEFERRED_EXIT_CODE"
    948     fi
    949 }
    950 
    951 
    952 function merge_unifiedsources_xcfilelists()
    953 {
    954     log_callstack_and_parameters "$@"
    955 
    956     log_debug "Merging ${GX_OUTPUT_UNIFIED_XCFILELIST_PROJECT_TEMP_PATH} into ${GX_OUTPUT_UNIFIED_XCFILELIST_PROJECT_PATH}"
    957 
    958     if (( ! ${GX_DRY_RUN} ))
    959     then
    960         merge_xcfilelists_helper "${GX_OUTPUT_UNIFIED_XCFILELIST_PROJECT_TEMP_PATH}" "${GX_OUTPUT_UNIFIED_XCFILELIST_PROJECT_PATH}" && GX_DEFERRED_EXIT_CODE=3
    961         log_debug "GX_DEFERRED_EXIT_CODE = $GX_DEFERRED_EXIT_CODE"
    962     fi
    963 }
    964 
    965 
    966 function merge_xcfilelists()
    967 {
    968     log_callstack_and_parameters "$@"
    969 
    970     invoke_each_action "${GX_MERGE_ACTIONS[@]}"
    971 
    972     log_debug "GX_DEFERRED_EXIT_CODE = $GX_DEFERRED_EXIT_CODE"
    973 }
    974 
    975 
    976 function check_xcfilelists_helper()
    977 {
    978     log_callstack_and_parameters "$@"
    979 
    980     local GX_NEW="$1"
    981     local GX_ORIG="$2"
    982     local GX_ADDITIONS="${GX_TEMP}/diff_added.tmp"
    983 
    984     log_debug "Checking ${GX_NEW} against ${GX_ORIG}"
    985 
    986     find_additions "${GX_NEW}" "${GX_ORIG}" "${GX_ADDITIONS}"
    987 
    988     if [[ -s "${GX_ADDITIONS}" ]]
    989     then
    990         log_progress
    991         log_progress "------------------------------------------------------------------------------"
    992         log_progress "Found added files for ${GX_ORIG}:"
    993         log_progress "------------------------------------------------------------------------------"
    994 
    995         local GX_LINE
    996         while IFS='' read -r GX_LINE
    997         do
    998             log_progress "${GX_LINE}"
    999         done < "${GX_ADDITIONS}"
    1000 
    1001         log_progress "------------------------------------------------------------------------------"
    1002 
    1003         GX_DEFERRED_EXIT_CODE=2
    1004     fi
    1005 }
    1006 
    1007 
    1008 function check_derivedsources_xcfilelists()
    1009 {
    1010     log_callstack_and_parameters "$@"
    1011 
    1012     check_xcfilelists_helper "${GX_INPUT_DERIVED_XCFILELIST_PROJECT_TEMP_PATH}" "${GX_INPUT_DERIVED_XCFILELIST_PROJECT_PATH}"
    1013     check_xcfilelists_helper "${GX_OUTPUT_DERIVED_XCFILELIST_PROJECT_TEMP_PATH}" "${GX_OUTPUT_DERIVED_XCFILELIST_PROJECT_PATH}"
    1014 }
    1015 
    1016 
    1017 function check_unifiedsources_xcfilelists()
    1018 {
    1019     log_callstack_and_parameters "$@"
    1020 
    1021     check_xcfilelists_helper "${GX_OUTPUT_UNIFIED_XCFILELIST_PROJECT_TEMP_PATH}" "${GX_OUTPUT_UNIFIED_XCFILELIST_PROJECT_PATH}"
    1022 }
    1023 
    1024 
    1025 function check_xcfilelists()
    1026 {
    1027     log_callstack_and_parameters "$@"
    1028 
    1029     invoke_each_action "${GX_CHECK_ACTIONS[@]}"
    1030 }
    1031 
    1032 
    1033 function report_merge_results()
    1034 {
    1035     log_callstack_and_parameters "$@"
    1036 
    1037     log_debug "GX_DEFERRED_EXIT_CODE = $GX_DEFERRED_EXIT_CODE"
    1038 
    1039     if (( ${GX_DEFERRED_EXIT_CODE} ))
    1040     then
    1041         log_progress
    1042 
    1043         local GX_MESSAGE='".xcfilelist" files tell the build system what files
    1044             are consumed and produced by the "Run Script" build phases in
    1045             Xcode. At least one of these .xcfilelist files was out of date and
    1046             has been updated. You now need to restart your build.'
    1047 
    1048         log_progress_long "${GX_MESSAGE}"
    1049     fi
    1050 }
    1051 
    1052 
    1053 function report_remediation_steps()
    1054 {
    1055     log_callstack_and_parameters "$@"
    1056 
    1057     if (( ${GX_DEFERRED_EXIT_CODE} ))
    1058     then
    1059         log_progress
    1060 
    1061         # We can either be called from within an xcodebuild context (meaning
    1062         # that we are being called during a build to validate the .xcfilelists
    1063         # for the current build configuration) or from the command line (to
    1064         # validate all .xcfilelists). We'll determine which of these is the
    1065         # case by checking $GX_PROJECT_TAG (which will have been set via the
    1066         # --project <TAG> option passed in to us when we're invoked in this
    1067         # context).
    1068         #
    1069         # Further, if called from within xcodebuild, it's important to know if
    1070         # we're being called from within Xcode or being invoked by a Makefile.
    1071         # If the former, the output/build files we are looking for are found in
    1072         # ~/Library/Developer/Xcode/DerivedData. Otherwise, they'll be found in
    1073         # OpenSource/WebKitBuild (or whatever $WEBKIT_OUTPUTDIR points to). We
    1074         # need to distinguish between these so that we can tell the user how to
    1075         # invoke us in a way that finds the right output/build files.
    1076         #
    1077         # If invoked from the command line, we really can't tell where the
    1078         # output files are, so give the user advice in this area.
    1079 
    1080         local GX_MESSAGE='".xcfilelist" files tell the build system what files
    1081             are consumed and produced by the "Run Script" build phases in
    1082             Xcode. At least one of these .xcfilelist files are out of date and
    1083             need to be regenerated. Regenerate these files by running
    1084             `Tools/Scripts/generate-xcfilelists generate'
    1085 
    1086         if [[ -n "${GX_PROJECT_TAG}" ]]
    1087         then
    1088             local GX_MESSAGE+=" --project ${GX_PROJECT_TAG}"
    1089             if [[ "${SYMROOT}" =~ Library/Developer/Xcode/DerivedData ]]
    1090             then
    1091                 local GX_MESSAGE+=" --xcode"
    1092             fi
    1093         else
    1094             if (( ${GX_USE_XCODE_BUILD_OUTPUT} ))
    1095             then
    1096                 local GX_MESSAGE+=" --xcode"
    1097             fi
    1098         fi
    1099 
    1100         local GX_MESSAGE+='`, or manually add the file or files shown above to
    1101         the indicated .xcfilelist files. Then restart your build. When
    1102         submitting, include the updated .xcfilelist files.'
    1103 
    1104         log_progress_long "${GX_MESSAGE}"
    1105     fi
    1106 }
    1107 
    1108 
    1109 function do_generate()
    1110 {
    1111     # Invoked from the command line to generate .xcfilelist files. Use any
    1112     # specified project, platform, and/or configuration. Any of those that
    1113     # aren't specified results in our iterating over all possible values for
    1114     # the unspecified value.
    1115 
    1116     log_callstack_and_parameters "$@"
    1117 
    1118     if [[ -z "${GX_PROJECT_TAG}" ]]
    1119     then
    1120         log_progress "=== Generating all .xcfilelists ==="
    1121     else
    1122         log_progress "=== Generating .xcfilelists for ${GX_PROJECT_TAG} ==="
    1123     fi
    1124 
    1125     for_each_project \
    1126         generate_xcfilelists
    1127 }
    1128 
    1129 
    1130 function do_merge()
    1131 {
    1132     # Implicitly invoked for generate and generate-xcode operations to move the
    1133     # temporary results into the Xcode project.
    1134 
    1135     log_callstack_and_parameters "$@"
    1136 
    1137     if [[ -z "${GX_PROJECT_TAG}" ]]
    1138     then
    1139         log_progress "=== Merging all .xcfilelists into place ==="
    1140     else
    1141         log_progress "=== Merging .xcfilelists for ${GX_PROJECT_TAG} ==="
    1142     fi
    1143 
    1144     for_each_project \
    1145         merge_xcfilelists
    1146 
    1147     log_debug "GX_DEFERRED_EXIT_CODE = $GX_DEFERRED_EXIT_CODE"
    1148 }
    1149 
    1150 
    1151 function do_check()
    1152 {
    1153     # Implicitly invoked for check and check-xcode operations to check the
    1154     # temporary results against the Xcode project.
    1155 
    1156     log_callstack_and_parameters "$@"
    1157 
    1158     # Being invoked from the command-line to check everything.
    1159 
    1160     if [[ -z "${GX_PROJECT_TAG}" ]]
    1161     then
    1162         log_progress "=== Checking all .xcfilelists ==="
    1163     else
    1164         log_progress "=== Checking .xcfilelists for ${GX_PROJECT_TAG} ==="
    1165     fi
    1166 
    1167     for_each_project \
    1168         check_xcfilelists
    1169 }
    1170 
    1171 
    1172 function do_subgenerate()
    1173 {
    1174     # Invoked from within an Xcode context to generate .xcfilelist files. Use
    1175     # the project, platform, an configuration established in the environment.
    1176 
    1177     log_callstack_and_parameters "$@"
    1178 
    1179     [[ -n "${GX_PROJECT_TAG}" ]] || die "GX_PROJECT_TAG is not defined."
    1180     [[ -n "${PROJECT_NAME}" ]] || die "subgenerate should only be invoked in an Xcode context."
    1181 
    1182     log_progress "=== Generating .xcfilelists for ${PROJECT_NAME}/${PLATFORM_NAME}/${CONFIGURATION} ==="
    1183 
    1184     set_project_settings
    1185 
    1186     # We're called during generate-xcode, check-xcode, and subgenerate
    1187     # operations. We need to reset our project-specific temp files for the
    1188     # first two, but not the last one.
    1189 
    1190     (( ${GX_DO_SUBGENERATE} )) || reset_project_specific_temp_files
    1191 
    1192     subgenerate_xcfilelists
    1193 }
    1194 
    1195 
    1196 function main()
    1197 {
    1198     log_callstack_and_parameters "$@"
    1199 
    1200     log_debug_var GX_ME
    1201     log_debug_var GX_HERE
    1202     log_debug_var GX_ROOT_DIR
    1203     log_debug_var GX_OPENSOURCE_DIR
    1204     log_debug_var GX_TEMP
    1205     log_debug_var GX_PROJECT_TAGS
    1206     log_debug_var GX_CONFIGURATIONS
    1207     log_debug_var GX_SUBEXECUTE_SCRIPT
    1208     log_debug_var GX_DO_GENERATE
    1209     log_debug_var GX_DO_GENERATE_XCODE
    1210     log_debug_var GX_DO_CHECK
    1211     log_debug_var GX_DO_CHECK_XCODE
    1212     log_debug_var GX_DO_SUBGENERATE
    1213     log_debug_var GX_DO_CLEANUP
    1214     log_debug_var GX_USE_XCODE_BUILD_OUTPUT
    1215     log_debug_var GX_USE_WEBKITBUILD_BUILD_OUTPUT
    1216     log_debug_var GX_DRY_RUN
    1217     log_debug_var GX_DEBUG
    1218     log_debug_var GX_QUIET
    1219     log_debug_var GX_ORIG_ARGS
    1220 
    1221     if (( ${GX_DO_HELP} ))
    1222     then
    1223         usage
    1224         my_exit 0
    1225     fi
    1226 
    1227     if (( GX_DO_GENERATE + GX_DO_GENERATE_XCODE + GX_DO_CHECK + GX_DO_CHECK_XCODE + GX_DO_SUBGENERATE + GX_DO_HELP < 1 ))
    1228     then
    1229         stderr "### One of generate, generate-xcode, check, check-xcode, subgenerate, or --help must be specified."
    1230         my_exit 1
    1231     fi
    1232 
    1233     if (( GX_DO_GENERATE + GX_DO_GENERATE_XCODE + GX_DO_CHECK + GX_DO_CHECK_XCODE + GX_DO_SUBGENERATE + GX_DO_HELP > 1 ))
    1234     then
    1235         stderr "### Only one of generate, generate-xcode, check, check-xcode, subgenerate, or --help can be specified."
    1236         my_exit 1
    1237     fi
    1238 
    1239     [[ -z "${GX_PROJECT_TAG}" || ( " ${GX_PROJECT_TAGS[@]} " =~ " ${GX_PROJECT_TAG} " ) ]] || { die "Unrecognized project: ${GX_PROJECT_TAG}";  }
    1240     get_canonical_platform_name "${GX_PLATFORM_NAME}" GX_PLATFORM_NAME
    1241     get_canonical_configuration "${GX_CONFIGURATION}" GX_CONFIGURATION
    1242 
    1243     if (( ${GX_DO_GENERATE} ))
    1244     then
    1245         do_generate
    1246         call post_generate_hook
    1247 
    1248         do_merge
    1249         call post_merge_hook
    1250 
    1251         report_merge_results
    1252     elif (( ${GX_DO_GENERATE_XCODE} ))
    1253     then
    1254         do_subgenerate
    1255         call post_generate_hook
    1256 
    1257         do_merge
    1258         call post_merge_hook
    1259 
    1260         report_merge_results
    1261     elif (( ${GX_DO_CHECK} ))
    1262     then
    1263         do_generate
    1264         call post_generate_hook
    1265 
    1266         do_check
    1267         call post_check_hook
    1268 
    1269         report_remediation_steps
    1270     elif (( ${GX_DO_CHECK_XCODE} ))
    1271     then
    1272         do_subgenerate
    1273         call post_generate_hook
    1274 
    1275         do_check
    1276         call post_check_hook
    1277 
    1278         report_remediation_steps
    1279     elif (( ${GX_DO_SUBGENERATE} ))
    1280     then
    1281         do_subgenerate
    1282     else
    1283         stderr "### No subcommand provided"
    1284         usage
    1285         my_exit 1
    1286     fi
    1287 
    1288     my_exit ${GX_DEFERRED_EXIT_CODE}
    1289 }
    1290 
    1291 
    1292 # Initialize and sanity check
    1293 
    1294 GX_ORIG_ARGS=("$@")
    1295 
    1296 GX_DO_GENERATE=0
    1297 GX_DO_GENERATE_XCODE=0
    1298 GX_DO_CHECK=0
    1299 GX_DO_CHECK_XCODE=0
    1300 GX_DO_SUBGENERATE=0
    1301 GX_DO_HELP=0
    1302 GX_DO_CLEANUP=0
    1303 GX_USE_XCODE_BUILD_OUTPUT=0
    1304 GX_USE_WEBKITBUILD_BUILD_OUTPUT=1
    1305 GX_DRY_RUN=0
    1306 GX_DEBUG=0
    1307 GX_QUIET=0
    1308 
    1309 GX_DEFERRED_EXIT_CODE=0
    1310 GX_PROJECT_TAG=
    1311 GX_PLATFORM_NAME=
    1312 GX_CONFIGURATION=
    1313 GX_SDKS=()
    1314 
    1315 GX_ME=$(normalize_file_path "${BASH_SOURCE[0]}")
    1316 GX_HERE=$(dirname "${GX_ME}")
    1317 GX_ROOT_DIR=$(normalize_directory_path "${GX_HERE}/../../..")
    1318 GX_OPENSOURCE_DIR="${GX_ROOT_DIR}/OpenSource"
    1319 GX_TEMP=$(normalize_directory_path /tmp/generate-xcfilelists)
    1320 GX_PROJECT_TAGS=(JavaScriptCore WebCore WebKit DumpRenderTree WebKitTestRunner)
    1321 GX_CONFIGURATIONS=(Release Debug)
    1322 GX_SUBEXECUTE_SCRIPT="${GX_ME}"
    1323 
    1324 [[ -n "${GX_ROOT_DIR}" ]] || die "Could not find GX_ROOT_DIR."
    1325 [[ -n "${GX_OPENSOURCE_DIR}" ]] || die "Could not find GX_OPENSOURCE_DIR."
    1326 [[ -d "${GX_ROOT_DIR}" ]] || die "${GX_ROOT_DIR} does not exist."
    1327 [[ -d "${GX_OPENSOURCE_DIR}" ]] || die "${GX_OPENSOURCE_DIR} does not exist."
    1328 
    1329 trap cleanup EXIT
    1330 
    1331 ensure_directories_exist "${GX_TEMP}"
    1332 
    1333 
    1334 # Process command-line parameters.
    1335 
    1336 while [[ "${1:+x}" ]]
    1337 do
    1338     case "${1}" in
    1339         generate)       GX_DO_GENERATE=1 ;;
    1340         generate-xcode) GX_DO_GENERATE_XCODE=1 ;;
    1341         check)          GX_DO_CHECK=1 ;;
    1342         check-xcode)    GX_DO_CHECK_XCODE=1 ;;
    1343         subgenerate)    GX_DO_SUBGENERATE=1 ;;
    1344         help)           GX_DO_HELP=1 ;;
    1345 
    1346         --project)      shift; GX_PROJECT_TAG="$1" ;;
    1347         --platform)     shift; GX_PLATFORM_NAME="$1" ;;
    1348         --configuration)shift; GX_CONFIGURATION="$1" ;;
    1349         --xcode)        GX_USE_XCODE_BUILD_OUTPUT=1; GX_USE_WEBKITBUILD_BUILD_OUTPUT=0 ;;
    1350         --webkitbuild)  GX_USE_XCODE_BUILD_OUTPUT=0; GX_USE_WEBKITBUILD_BUILD_OUTPUT=1 ;;
    1351         --nocleanup)    GX_DO_CLEANUP=0 ;;
    1352 
    1353         -n | --dry-run) GX_DRY_RUN=1 ;;
    1354         -d | --debug)   GX_DEBUG=$(( $GX_DEBUG + 1 )) ;;
    1355         -q | --quiet)   GX_QUIET=1 ;;
    1356         -h | --help)    GX_DO_HELP=1 ;;
    1357 
    1358         *)              stderr "### Unknown command: $1"
    1359                         usage
    1360                         my_exit 1 ;;
    1361     esac
    1362     shift
    1363 done
    1364 
    1365 
    1366 GX_SOURCED=$([[ "$0" == "${BASH_SOURCE[@]}" ]] && echo 0 || echo 1)
    1367 if (( ! ${GX_SOURCED} ))
    1368 then
    1369     GX_INTERNAL_ME="${GX_ROOT_DIR}/Internal/Tools/Scripts/generate-xcfilelists"
    1370     if [[ -x "${GX_INTERNAL_ME}" ]]
    1371     then
    1372         "${GX_INTERNAL_ME}" "${GX_ORIG_ARGS[@]}"
    1373     else
    1374         main
    1375     fi
    1376 fi
     58if __name__ == "__main__":
     59    application_class = apple_additions().get_generate_xcfilelists_application() if apple_additions() else Application
     60    sys.exit(application_class(__file__).run())
  • trunk/Tools/Scripts/webkitpy/xcode/__init__.py

    r226812 r245364  
    11# Required for Python to search this directory for module files
     2
     3import hashlib
     4import struct
     5
     6
     7# The default location for Xcode's "DerivedData" (build output and intermediate
     8# files) is a unique directory in ~/Library/Developer/Xcode/DerivedData with a
     9# name incorporating a hash based on the full path of the project or workspace
     10# being built. The following function takes that path and returns the
     11# corresponding hash.
     12#
     13# The algorithm is adapted from the following article:
     14#
     15#   <https://pewpewthespells.com/blog/xcode_deriveddata_hashes.pdf>
     16
     17def xcode_hash_for_path(path):
     18    def convert_to_string(n):
     19        s = ''
     20        for _ in range(0, 14):
     21            (n, r) = divmod(n, 26)
     22            s = chr(r + 97) + s
     23        return s
     24
     25    (part1, part2) = struct.unpack(">QQ", hashlib.md5(path.encode()).digest())
     26    return convert_to_string(part1) + convert_to_string(part2)
  • trunk/Tools/WebKitTestRunner/Scripts/check-xcfilelists.sh

    r244987 r245364  
    99
    1010SCRIPT="${BUILD_SCRIPTS_DIR}/generate-xcfilelists"
     11[ -f "${SCRIPT}" ] || SCRIPT="${PROJECT_DIR}/../../../${WK_ADDITIONAL_SCRIPTS_DIR}/generate-xcfilelists"
    1112[ -f "${SCRIPT}" ] || SCRIPT="${PROJECT_DIR}/../../Tools/Scripts/generate-xcfilelists"
    1213[ -f "${SCRIPT}" ] || { echo "### Cannot find generate-xcfilelists script"; exit 1; }
Note: See TracChangeset for help on using the changeset viewer.