| OLD | NEW |
| 1 # Copyright (c) 2013 Google Inc. All rights reserved. | 1 # Copyright (c) 2013 Google Inc. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 | 4 |
| 5 import collections | 5 import collections |
| 6 import copy | 6 import copy |
| 7 import hashlib | 7 import hashlib |
| 8 import json | 8 import json |
| 9 import multiprocessing | 9 import multiprocessing |
| 10 import os.path | 10 import os.path |
| (...skipping 357 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 368 def WriteSpec(self, spec, config_name, generator_flags): | 368 def WriteSpec(self, spec, config_name, generator_flags): |
| 369 """The main entry point for NinjaWriter: write the build rules for a spec. | 369 """The main entry point for NinjaWriter: write the build rules for a spec. |
| 370 | 370 |
| 371 Returns a Target object, which represents the output paths for this spec. | 371 Returns a Target object, which represents the output paths for this spec. |
| 372 Returns None if there are no outputs (e.g. a settings-only 'none' type | 372 Returns None if there are no outputs (e.g. a settings-only 'none' type |
| 373 target).""" | 373 target).""" |
| 374 | 374 |
| 375 self.config_name = config_name | 375 self.config_name = config_name |
| 376 self.name = spec['target_name'] | 376 self.name = spec['target_name'] |
| 377 self.toolset = spec['toolset'] | 377 self.toolset = spec['toolset'] |
| 378 |
| 379 if self.toolset == 'target' and generator_supports_multiple_toolsets: |
| 380 self.flavor = 'linux' # lol |
| 381 |
| 378 config = spec['configurations'][config_name] | 382 config = spec['configurations'][config_name] |
| 379 self.target = Target(spec['type']) | 383 self.target = Target(spec['type']) |
| 380 self.is_standalone_static_library = bool( | 384 self.is_standalone_static_library = bool( |
| 381 spec.get('standalone_static_library', 0)) | 385 spec.get('standalone_static_library', 0)) |
| 382 # Track if this target contains any C++ files, to decide if gcc or g++ | 386 # Track if this target contains any C++ files, to decide if gcc or g++ |
| 383 # should be used for linking. | 387 # should be used for linking. |
| 384 self.uses_cpp = False | 388 self.uses_cpp = False |
| 385 | 389 |
| 386 self.is_mac_bundle = gyp.xcode_emulation.IsMacBundle(self.flavor, spec) | 390 self.is_mac_bundle = gyp.xcode_emulation.IsMacBundle(self.flavor, spec) |
| 387 self.xcode_settings = self.msvs_settings = None | 391 self.xcode_settings = self.msvs_settings = None |
| (...skipping 548 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 936 input = self.GypPathToNinja(source) | 940 input = self.GypPathToNinja(source) |
| 937 output = self.GypPathToUniqueOutput(filename + obj_ext) | 941 output = self.GypPathToUniqueOutput(filename + obj_ext) |
| 938 if arch is not None: | 942 if arch is not None: |
| 939 output = AddArch(output, arch) | 943 output = AddArch(output, arch) |
| 940 implicit = precompiled_header.GetObjDependencies([input], [output], arch) | 944 implicit = precompiled_header.GetObjDependencies([input], [output], arch) |
| 941 variables = [] | 945 variables = [] |
| 942 if self.flavor == 'win': | 946 if self.flavor == 'win': |
| 943 variables, output, implicit = precompiled_header.GetFlagsModifications( | 947 variables, output, implicit = precompiled_header.GetFlagsModifications( |
| 944 input, output, implicit, command, cflags_c, cflags_cc, | 948 input, output, implicit, command, cflags_c, cflags_cc, |
| 945 self.ExpandSpecial) | 949 self.ExpandSpecial) |
| 950 # hosting on win will need this too: |
| 951 #if self.toolset == 'host': |
| 952 #command += '_host' |
| 946 ninja_file.build(output, command, input, | 953 ninja_file.build(output, command, input, |
| 947 implicit=[gch for _, _, gch in implicit], | 954 implicit=[gch for _, _, gch in implicit], |
| 948 order_only=predepends, variables=variables) | 955 order_only=predepends, variables=variables) |
| 949 outputs.append(output) | 956 outputs.append(output) |
| 950 | 957 |
| 951 if has_rc_source: | 958 if has_rc_source: |
| 952 resource_include_dirs = config.get('resource_include_dirs', include_dirs) | 959 resource_include_dirs = config.get('resource_include_dirs', include_dirs) |
| 953 self.WriteVariableList(ninja_file, 'resource_includes', | 960 self.WriteVariableList(ninja_file, 'resource_includes', |
| 954 [QuoteShellArgument('-I' + self.GypPathToNinja(i, env), self.flavor) | 961 [QuoteShellArgument('-I' + self.GypPathToNinja(i, env), self.flavor) |
| 955 for i in resource_include_dirs]) | 962 for i in resource_include_dirs]) |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 996 def WriteLinkForArch(self, ninja_file, spec, config_name, config, | 1003 def WriteLinkForArch(self, ninja_file, spec, config_name, config, |
| 997 link_deps, arch=None): | 1004 link_deps, arch=None): |
| 998 """Write out a link step. Fills out target.binary. """ | 1005 """Write out a link step. Fills out target.binary. """ |
| 999 command = { | 1006 command = { |
| 1000 'executable': 'link', | 1007 'executable': 'link', |
| 1001 'loadable_module': 'solink_module', | 1008 'loadable_module': 'solink_module', |
| 1002 'shared_library': 'solink', | 1009 'shared_library': 'solink', |
| 1003 }[spec['type']] | 1010 }[spec['type']] |
| 1004 command_suffix = '' | 1011 command_suffix = '' |
| 1005 | 1012 |
| 1013 if self.toolset == 'host': |
| 1014 # This is on command_suffix instead of command_suffix so that notoc |
| 1015 # versions become solink_notoc_host, not solink_host_notoc. |
| 1016 command_suffix += '_host' |
| 1017 |
| 1006 implicit_deps = set() | 1018 implicit_deps = set() |
| 1007 solibs = set() | 1019 solibs = set() |
| 1008 | 1020 |
| 1009 if 'dependencies' in spec: | 1021 if 'dependencies' in spec: |
| 1010 # Two kinds of dependencies: | 1022 # Two kinds of dependencies: |
| 1011 # - Linkable dependencies (like a .a or a .so): add them to the link line. | 1023 # - Linkable dependencies (like a .a or a .so): add them to the link line. |
| 1012 # - Non-linkable dependencies (like a rule that generates a file | 1024 # - Non-linkable dependencies (like a rule that generates a file |
| 1013 # and writes a stamp file): add them to implicit_deps | 1025 # and writes a stamp file): add them to implicit_deps |
| 1014 extra_link_deps = set() | 1026 extra_link_deps = set() |
| 1015 for dep in spec['dependencies']: | 1027 for dep in spec['dependencies']: |
| (...skipping 474 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1490 self.ninja.newline() | 1502 self.ninja.newline() |
| 1491 | 1503 |
| 1492 return rule_name, args | 1504 return rule_name, args |
| 1493 | 1505 |
| 1494 | 1506 |
| 1495 def CalculateVariables(default_variables, params): | 1507 def CalculateVariables(default_variables, params): |
| 1496 """Calculate additional variables for use in the build (called by gyp).""" | 1508 """Calculate additional variables for use in the build (called by gyp).""" |
| 1497 global generator_additional_non_configuration_keys | 1509 global generator_additional_non_configuration_keys |
| 1498 global generator_additional_path_sections | 1510 global generator_additional_path_sections |
| 1499 flavor = gyp.common.GetFlavor(params) | 1511 flavor = gyp.common.GetFlavor(params) |
| 1500 if flavor == 'mac': | 1512 # Bleh, SHARED_LIB_SUFFIX is per-toolset; gyp doesn't expect that as of yet. |
| 1513 if False and flavor == 'mac': |
| 1501 default_variables.setdefault('OS', 'mac') | 1514 default_variables.setdefault('OS', 'mac') |
| 1502 default_variables.setdefault('SHARED_LIB_SUFFIX', '.dylib') | 1515 default_variables.setdefault('SHARED_LIB_SUFFIX', '.dylib') |
| 1503 default_variables.setdefault('SHARED_LIB_DIR', | 1516 default_variables.setdefault('SHARED_LIB_DIR', |
| 1504 generator_default_variables['PRODUCT_DIR']) | 1517 generator_default_variables['PRODUCT_DIR']) |
| 1505 default_variables.setdefault('LIB_DIR', | 1518 default_variables.setdefault('LIB_DIR', |
| 1506 generator_default_variables['PRODUCT_DIR']) | 1519 generator_default_variables['PRODUCT_DIR']) |
| 1507 | 1520 |
| 1508 # Copy additional generator configuration data from Xcode, which is shared | 1521 # Copy additional generator configuration data from Xcode, which is shared |
| 1509 # by the Mac Ninja generator. | 1522 # by the Mac Ninja generator. |
| 1510 import gyp.generator.xcode as xcode_generator | 1523 import gyp.generator.xcode as xcode_generator |
| (...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1912 command=('%s gyp-win-tool rc-wrapper ' | 1925 command=('%s gyp-win-tool rc-wrapper ' |
| 1913 '$arch $rc $defines $resource_includes $rcflags /fo$out $in' % | 1926 '$arch $rc $defines $resource_includes $rcflags /fo$out $in' % |
| 1914 sys.executable)) | 1927 sys.executable)) |
| 1915 master_ninja.rule( | 1928 master_ninja.rule( |
| 1916 'asm', | 1929 'asm', |
| 1917 description='ASM $out', | 1930 description='ASM $out', |
| 1918 command=('%s gyp-win-tool asm-wrapper ' | 1931 command=('%s gyp-win-tool asm-wrapper ' |
| 1919 '$arch $asm $defines $includes $asmflags /c /Fo $out $in' % | 1932 '$arch $asm $defines $includes $asmflags /c /Fo $out $in' % |
| 1920 sys.executable)) | 1933 sys.executable)) |
| 1921 | 1934 |
| 1922 if flavor != 'mac' and flavor != 'win': | 1935 if True or flavor != 'mac' and flavor != 'win': |
| 1923 master_ninja.rule( | 1936 master_ninja.rule( |
| 1924 'alink', | 1937 'alink', |
| 1925 description='AR $out', | 1938 description='AR $out', |
| 1926 command='rm -f $out && $ar rcs $out $in') | 1939 command='rm -f $out && $ar rcs $out $in') |
| 1927 master_ninja.rule( | 1940 master_ninja.rule( |
| 1928 'alink_thin', | 1941 'alink_thin', |
| 1929 description='AR $out', | 1942 description='AR $out', |
| 1930 command='rm -f $out && $ar rcsT $out $in') | 1943 command='rm -f $out && $ar rcsT $out $in') |
| 1931 | 1944 |
| 1932 # This allows targets that only need to depend on $lib's API to declare an | 1945 # This allows targets that only need to depend on $lib's API to declare an |
| (...skipping 29 matching lines...) Expand all Loading... |
| 1962 command=mtime_preserving_solink_base % {'suffix': '@$link_file_list'}, | 1975 command=mtime_preserving_solink_base % {'suffix': '@$link_file_list'}, |
| 1963 rspfile='$link_file_list', | 1976 rspfile='$link_file_list', |
| 1964 rspfile_content='-Wl,--start-group $in -Wl,--end-group $solibs $libs', | 1977 rspfile_content='-Wl,--start-group $in -Wl,--end-group $solibs $libs', |
| 1965 pool='link_pool') | 1978 pool='link_pool') |
| 1966 master_ninja.rule( | 1979 master_ninja.rule( |
| 1967 'link', | 1980 'link', |
| 1968 description='LINK $out', | 1981 description='LINK $out', |
| 1969 command=('$ld $ldflags -o $out ' | 1982 command=('$ld $ldflags -o $out ' |
| 1970 '-Wl,--start-group $in -Wl,--end-group $solibs $libs'), | 1983 '-Wl,--start-group $in -Wl,--end-group $solibs $libs'), |
| 1971 pool='link_pool') | 1984 pool='link_pool') |
| 1972 elif flavor == 'win': | 1985 |
| 1986 if flavor == 'win': |
| 1973 master_ninja.rule( | 1987 master_ninja.rule( |
| 1974 'alink', | 1988 'alink', |
| 1975 description='LIB $out', | 1989 description='LIB $out', |
| 1976 command=('%s gyp-win-tool link-wrapper $arch False ' | 1990 command=('%s gyp-win-tool link-wrapper $arch False ' |
| 1977 '$ar /nologo /ignore:4221 /OUT:$out @$out.rsp' % | 1991 '$ar /nologo /ignore:4221 /OUT:$out @$out.rsp' % |
| 1978 sys.executable), | 1992 sys.executable), |
| 1979 rspfile='$out.rsp', | 1993 rspfile='$out.rsp', |
| 1980 rspfile_content='$in_newline $libflags') | 1994 rspfile_content='$in_newline $libflags') |
| 1981 _AddWinLinkRules(master_ninja, embed_manifest=True) | 1995 _AddWinLinkRules(master_ninja, embed_manifest=True) |
| 1982 _AddWinLinkRules(master_ninja, embed_manifest=False) | 1996 _AddWinLinkRules(master_ninja, embed_manifest=False) |
| 1983 else: | 1997 elif flavor == 'mac': |
| 1984 master_ninja.rule( | 1998 master_ninja.rule( |
| 1985 'objc', | 1999 'objc', |
| 1986 description='OBJC $out', | 2000 description='OBJC $out', |
| 1987 command=('$cc -MMD -MF $out.d $defines $includes $cflags $cflags_objc ' | 2001 command=('$cc -MMD -MF $out.d $defines $includes $cflags $cflags_objc ' |
| 1988 '$cflags_pch_objc -c $in -o $out'), | 2002 '$cflags_pch_objc -c $in -o $out'), |
| 1989 depfile='$out.d', | 2003 depfile='$out.d', |
| 1990 deps=deps) | 2004 deps=deps) |
| 1991 master_ninja.rule( | 2005 master_ninja.rule( |
| 1992 'objcxx', | 2006 'objcxx', |
| 1993 description='OBJCXX $out', | 2007 description='OBJCXX $out', |
| 1994 command=('$cxx -MMD -MF $out.d $defines $includes $cflags $cflags_objcc ' | 2008 command=('$cxx -MMD -MF $out.d $defines $includes $cflags $cflags_objcc ' |
| 1995 '$cflags_pch_objcc -c $in -o $out'), | 2009 '$cflags_pch_objcc -c $in -o $out'), |
| 1996 depfile='$out.d', | 2010 depfile='$out.d', |
| 1997 deps=deps) | 2011 deps=deps) |
| 1998 master_ninja.rule( | 2012 master_ninja.rule( |
| 1999 'alink', | 2013 'alink_host', |
| 2000 description='LIBTOOL-STATIC $out, POSTBUILDS', | 2014 description='LIBTOOL-STATIC $out, POSTBUILDS', |
| 2001 command='rm -f $out && ' | 2015 command='rm -f $out && ' |
| 2002 './gyp-mac-tool filter-libtool libtool $libtool_flags ' | 2016 './gyp-mac-tool filter-libtool libtool $libtool_flags ' |
| 2003 '-static -o $out $in' | 2017 '-static -o $out $in' |
| 2004 '$postbuilds') | 2018 '$postbuilds') |
| 2005 master_ninja.rule( | 2019 master_ninja.rule( |
| 2006 'lipo', | 2020 'lipo_host', |
| 2007 description='LIPO $out, POSTBUILDS', | 2021 description='LIPO $out, POSTBUILDS', |
| 2008 command='rm -f $out && lipo -create $in -output $out$postbuilds') | 2022 command='rm -f $out && lipo -create $in -output $out$postbuilds') |
| 2009 | 2023 |
| 2010 # Record the public interface of $lib in $lib.TOC. See the corresponding | 2024 # Record the public interface of $lib in $lib.TOC. See the corresponding |
| 2011 # comment in the posix section above for details. | 2025 # comment in the posix section above for details. |
| 2012 solink_base = '$ld %(type)s $ldflags -o $lib %(suffix)s' | 2026 solink_base = '$ld %(type)s $ldflags -o $lib %(suffix)s' |
| 2013 mtime_preserving_solink_base = ( | 2027 mtime_preserving_solink_base = ( |
| 2014 'if [ ! -e $lib -o ! -e $lib.TOC ] || ' | 2028 'if [ ! -e $lib -o ! -e $lib.TOC ] || ' |
| 2015 # Always force dependent targets to relink if this library | 2029 # Always force dependent targets to relink if this library |
| 2016 # reexports something. Handling this correctly would require | 2030 # reexports something. Handling this correctly would require |
| 2017 # recursive TOC dumping but this is rare in practice, so punt. | 2031 # recursive TOC dumping but this is rare in practice, so punt. |
| 2018 'otool -l $lib | grep -q LC_REEXPORT_DYLIB ; then ' | 2032 'otool -l $lib | grep -q LC_REEXPORT_DYLIB ; then ' |
| 2019 '%(solink)s && %(extract_toc)s > $lib.TOC; ' | 2033 '%(solink)s && %(extract_toc)s > $lib.TOC; ' |
| 2020 'else ' | 2034 'else ' |
| 2021 '%(solink)s && %(extract_toc)s > $lib.tmp && ' | 2035 '%(solink)s && %(extract_toc)s > $lib.tmp && ' |
| 2022 'if ! cmp -s $lib.tmp $lib.TOC; then ' | 2036 'if ! cmp -s $lib.tmp $lib.TOC; then ' |
| 2023 'mv $lib.tmp $lib.TOC ; ' | 2037 'mv $lib.tmp $lib.TOC ; ' |
| 2024 'fi; ' | 2038 'fi; ' |
| 2025 'fi' | 2039 'fi' |
| 2026 % { 'solink': solink_base, | 2040 % { 'solink': solink_base, |
| 2027 'extract_toc': | 2041 'extract_toc': |
| 2028 '{ otool -l $lib | grep LC_ID_DYLIB -A 5; ' | 2042 '{ otool -l $lib | grep LC_ID_DYLIB -A 5; ' |
| 2029 'nm -gP $lib | cut -f1-2 -d\' \' | grep -v U$$; true; }'}) | 2043 'nm -gP $lib | cut -f1-2 -d\' \' | grep -v U$$; true; }'}) |
| 2030 | 2044 |
| 2031 | 2045 |
| 2032 solink_suffix = '@$link_file_list$postbuilds' | 2046 solink_suffix = '@$link_file_list$postbuilds' |
| 2033 master_ninja.rule( | 2047 master_ninja.rule( |
| 2034 'solink', | 2048 'solink_host', |
| 2035 description='SOLINK $lib, POSTBUILDS', | 2049 description='SOLINK $lib, POSTBUILDS', |
| 2036 restat=True, | 2050 restat=True, |
| 2037 command=mtime_preserving_solink_base % {'suffix': solink_suffix, | 2051 command=mtime_preserving_solink_base % {'suffix': solink_suffix, |
| 2038 'type': '-shared'}, | 2052 'type': '-shared'}, |
| 2039 rspfile='$link_file_list', | 2053 rspfile='$link_file_list', |
| 2040 rspfile_content='$in $solibs $libs', | 2054 rspfile_content='$in $solibs $libs', |
| 2041 pool='link_pool') | 2055 pool='link_pool') |
| 2042 master_ninja.rule( | 2056 master_ninja.rule( |
| 2043 'solink_notoc', | 2057 'solink_notoc_host', |
| 2044 description='SOLINK $lib, POSTBUILDS', | 2058 description='SOLINK $lib, POSTBUILDS', |
| 2045 restat=True, | 2059 restat=True, |
| 2046 command=solink_base % {'suffix':solink_suffix, 'type': '-shared'}, | 2060 command=solink_base % {'suffix':solink_suffix, 'type': '-shared'}, |
| 2047 rspfile='$link_file_list', | 2061 rspfile='$link_file_list', |
| 2048 rspfile_content='$in $solibs $libs', | 2062 rspfile_content='$in $solibs $libs', |
| 2049 pool='link_pool') | 2063 pool='link_pool') |
| 2050 | 2064 |
| 2051 master_ninja.rule( | 2065 master_ninja.rule( |
| 2052 'solink_module', | 2066 'solink_module_host', |
| 2053 description='SOLINK(module) $lib, POSTBUILDS', | 2067 description='SOLINK(module) $lib, POSTBUILDS', |
| 2054 restat=True, | 2068 restat=True, |
| 2055 command=mtime_preserving_solink_base % {'suffix': solink_suffix, | 2069 command=mtime_preserving_solink_base % {'suffix': solink_suffix, |
| 2056 'type': '-bundle'}, | 2070 'type': '-bundle'}, |
| 2057 rspfile='$link_file_list', | 2071 rspfile='$link_file_list', |
| 2058 rspfile_content='$in $solibs $libs', | 2072 rspfile_content='$in $solibs $libs', |
| 2059 pool='link_pool') | 2073 pool='link_pool') |
| 2060 master_ninja.rule( | 2074 master_ninja.rule( |
| 2061 'solink_module_notoc', | 2075 'solink_module_notoc_host', |
| 2062 description='SOLINK(module) $lib, POSTBUILDS', | 2076 description='SOLINK(module) $lib, POSTBUILDS', |
| 2063 restat=True, | 2077 restat=True, |
| 2064 command=solink_base % {'suffix': solink_suffix, 'type': '-bundle'}, | 2078 command=solink_base % {'suffix': solink_suffix, 'type': '-bundle'}, |
| 2065 rspfile='$link_file_list', | 2079 rspfile='$link_file_list', |
| 2066 rspfile_content='$in $solibs $libs', | 2080 rspfile_content='$in $solibs $libs', |
| 2067 pool='link_pool') | 2081 pool='link_pool') |
| 2068 | 2082 |
| 2069 master_ninja.rule( | 2083 master_ninja.rule( |
| 2070 'link', | 2084 'link_host', |
| 2071 description='LINK $out, POSTBUILDS', | 2085 description='LINK $out, POSTBUILDS', |
| 2072 command=('$ld $ldflags -o $out ' | 2086 command=('$ld $ldflags -o $out ' |
| 2073 '$in $solibs $libs$postbuilds'), | 2087 '$in $solibs $libs$postbuilds'), |
| 2074 pool='link_pool') | 2088 pool='link_pool') |
| 2089 |
| 2075 master_ninja.rule( | 2090 master_ninja.rule( |
| 2076 'preprocess_infoplist', | 2091 'preprocess_infoplist', |
| 2077 description='PREPROCESS INFOPLIST $out', | 2092 description='PREPROCESS INFOPLIST $out', |
| 2078 command=('$cc -E -P -Wno-trigraphs -x c $defines $in -o $out && ' | 2093 command=('$cc -E -P -Wno-trigraphs -x c $defines $in -o $out && ' |
| 2079 'plutil -convert xml1 $out $out')) | 2094 'plutil -convert xml1 $out $out')) |
| 2080 master_ninja.rule( | 2095 master_ninja.rule( |
| 2081 'copy_infoplist', | 2096 'copy_infoplist', |
| 2082 description='COPY INFOPLIST $in', | 2097 description='COPY INFOPLIST $in', |
| 2083 command='$env ./gyp-mac-tool copy-info-plist $in $out $keys') | 2098 command='$env ./gyp-mac-tool copy-info-plist $in $out $keys') |
| 2084 master_ninja.rule( | 2099 master_ninja.rule( |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2228 arglists.append( | 2243 arglists.append( |
| 2229 (target_list, target_dicts, data, params, config_name)) | 2244 (target_list, target_dicts, data, params, config_name)) |
| 2230 pool.map(CallGenerateOutputForConfig, arglists) | 2245 pool.map(CallGenerateOutputForConfig, arglists) |
| 2231 except KeyboardInterrupt, e: | 2246 except KeyboardInterrupt, e: |
| 2232 pool.terminate() | 2247 pool.terminate() |
| 2233 raise e | 2248 raise e |
| 2234 else: | 2249 else: |
| 2235 for config_name in config_names: | 2250 for config_name in config_names: |
| 2236 GenerateOutputForConfig(target_list, target_dicts, data, params, | 2251 GenerateOutputForConfig(target_list, target_dicts, data, params, |
| 2237 config_name) | 2252 config_name) |
| OLD | NEW |