Răsfoiți Sursa

[RedCode] Remove legacy bundler scripts (#16160)

* Remove legacy bundler scripts

The bundlers scripts were for the legacy RC.exe and CryRenderer which no longer exist.

Signed-off-by: Alex Peterson <[email protected]>

* Remove legacy gen_shaders smoke test

Signed-off-by: Alex Peterson <[email protected]>

---------

Signed-off-by: Alex Peterson <[email protected]>
Alex Peterson 2 ani în urmă
părinte
comite
9c442be2a5

+ 0 - 40
AutomatedTesting/Gem/PythonTests/smoke/test_StaticTools_GenPakShaders_Works.py

@@ -1,40 +0,0 @@
-"""
-Copyright (c) Contributors to the Open 3D Engine Project.
-For complete copyright and license terms please see the LICENSE at the root of this distribution.
-
-SPDX-License-Identifier: Apache-2.0 OR MIT
-
-
-Static tool scripts
-Launch Static tool and Verify the help message
-"""
-
-import os
-import pytest
-import subprocess
-import sys
-
-
-def verify_help_message(static_tool):
-    help_message = ["--help", "show this help message and exit"]
-    output = subprocess.run([sys.executable, static_tool, "-h"], capture_output=True)
-    assert (
-        len(output.stderr) == 0 and output.returncode == 0
-    ), f"Error occurred while launching {static_tool}: {output.stderr}"
-    #  verify help message
-    for message in help_message:
-        assert message in str(output.stdout), f"Help Message: {message} is not present"
-
-
[email protected]("project", ["AutomatedTesting"])
[email protected]_smoke
-class TestStaticToolsGenPakShadersWorks(object):
-    def test_StaticTools_GenPakShaders_Works(self, editor):
-        static_tools = [
-            os.path.join(editor.workspace.paths.engine_root(), "scripts", "bundler", "gen_shaders.py"),
-            os.path.join(editor.workspace.paths.engine_root(), "scripts", "bundler", "get_shader_list.py"),
-            os.path.join(editor.workspace.paths.engine_root(), "scripts", "bundler", "pak_shaders.py"),
-        ]
-
-        for tool in static_tools:
-            verify_help_message(tool)

+ 0 - 1
scripts/CMakeLists.txt

@@ -7,7 +7,6 @@
 #
 
 if(PAL_TRAIT_BUILD_HOST_TOOLS)
-    add_subdirectory(bundler)
     add_subdirectory(commit_validation)
     add_subdirectory(ctest)
     add_subdirectory(detect_file_changes)

+ 0 - 95
scripts/bundler/BuildReleaseAuxiliaryContent.py

@@ -1,95 +0,0 @@
-"""
-Copyright (c) Contributors to the Open 3D Engine Project.
-For complete copyright and license terms please see the LICENSE at the root of this distribution.
-
-SPDX-License-Identifier: Apache-2.0 OR MIT
-
-Config file for pytest & PythonTestTools. Warns user if the packaged Python is not
-being used.
-"""
-import argparse
-import os
-import pathlib
-import subprocess
-
-# Move upwards twice from the <engine-root>/scripts/bundler directory to get the parent directory
-SCRIPT_PATH = pathlib.Path(__file__).resolve()
-DEFAULT_ENGINE_ROOT = SCRIPT_PATH.parents[2]
-
-def printMessage(message):
-    print(message)
-
-
-def getCommandLineArgs():
-    parser = argparse.ArgumentParser(
-        description='O3DE project release build automation tool, generates auxiliary content for the project specified on the command line.')
-    parser.add_argument('--platforms', required=True,
-                        help='Required: The comma separated platform list to generate auxiliary content for.')
-    parser.add_argument('--buildFolder', required=True,
-                        help='Required: The build folder for your engine, containing AssetProcessorBatch.exe')
-    parser.add_argument('--recompress', action='store_true',
-                        help='If present, the ResourceCompiler (RC.exe) will decompress and compress back each PAK file found as they are transferred from the cache folder to the game_pc_pak folder.')
-    parser.add_argument('--use_fastest', action='store_true',
-                        help='As each file is being added to its PAK file, they will be compressed across all available codecs (ZLIB, ZSTD and LZ4) and the one with the fastest decompression time will be chosen. The default is to always use ZLIB.')
-    parser.add_argument('--skipAssetProcessing', action='store_true',
-                        help='If present, assetprocessorbatch will not be launched before creating the auxiliary content for the current game project specified in the bootstrap.cfg file. The default behavior of processing assets first helps you make sure your auxiliary content will always be generated from the most up to date data for your game.')
-    parser.add_argument('--skiplevelPaks', action='store_true',
-                        help='If present, the ResourceCompiler (RC.exe) will skip putting any level related pak files for e.g level.pak and terraintexture.pak in the auxiliary contents. Consider using this option if your levels are being packaged through some other system, such as the AssetBundler.')
-    parser.add_argument('--project-path', required=True, type=pathlib.Path,
-                        help='Required: specifies the path to the o3de project to use')
-    parser.add_argument('--engine-path', type=pathlib.Path, default=DEFAULT_ENGINE_ROOT,
-                        help='specifies the path to the engine root to use')
-    return parser.parse_args()
-
-
-def subprocessWithPrint(command):
-    printMessage(command)
-    subprocess.check_call(command)
-
-
-def main():
-    args = getCommandLineArgs()
-
-    if not args.project_path:
-        printMessage(
-            "Project-path has not been supplied, it is required to in order to locate a project auxiliary content.")
-        return
-    printMessage(f"Generating auxiliary content for project at path {str(args.project_path)} from build folder {args.buildFolder} for platforms {args.platforms}")
-    # Build paths to tools
-    apBatchExe = os.path.join(args.buildFolder, "AssetProcessorBatch.exe")
-    rcFolder = args.buildFolder
-    rcExe = os.path.join(rcFolder, "rc.exe")
-
-    rc_script_name = 'RCJob_Generic_MakeAuxiliaryContent.xml'
-    rc_script_path = os.path.join(rcFolder, rc_script_name)
-    if not os.path.exists(rc_script_path):
-        rc_script_path = args.engine_path / 'Code' / 'Tools' / 'rc' / 'Config' / 'rc' / rc_script_name
-    if not os.path.exists(rc_script_path):
-        printMessage(f"Could not find {rc_script_name} at {rcFolder} or {str(args.engine_path)}")
-        return
-
-    # Make sure all assets are up to date.
-    if not args.skipAssetProcessing:
-        printMessage("Updating game assets")
-        # Asset processor will read the current project from bootstrap.
-        subprocessWithPrint(f"{apBatchExe} --project-path={str(args.project_path)} --platforms={args.platforms}")
-    else:
-        printMessage("Skipping asset processing")
-
-    platformsSplit = args.platforms.split(',')
-    for platform in platformsSplit:
-        printMessage("Generating auxiliary content for platform {}".format(platform))
-        # Call RC to generate the auxiliary content.
-        recompressArg = 1 if args.recompress else 0
-        useFastestArg = 1 if args.use_fastest else 0
-        skiplevelPaksArg = 1 if args.skiplevelPaks else 0
-        rc_cmd = f"{rcExe} --job={rc_script_path} --platform={platform}" \
-                 f" --regset=/Amazon/AzCore/Bootstrap/project_path={str(args.project_path)} " \
-                 f"--recompress={recompressArg}" \
-                 f" --use_fastest={useFastestArg} --skiplevelPaks={skiplevelPaksArg}"
-
-        subprocessWithPrint(rc_cmd)
-
-
-if __name__ == "__main__":
-    main()

+ 0 - 11
scripts/bundler/CMakeLists.txt

@@ -1,11 +0,0 @@
-#
-# Copyright (c) Contributors to the Open 3D Engine Project.
-# For complete copyright and license terms please see the LICENSE at the root of this distribution.
-#
-# SPDX-License-Identifier: Apache-2.0 OR MIT
-#
-#
-
-ly_install_directory(DIRECTORIES .
-    EXCLUDE_PATTERNS tests
-)

+ 0 - 230
scripts/bundler/gen_shaders.py

@@ -1,230 +0,0 @@
-#
-# Copyright (c) Contributors to the Open 3D Engine Project.
-# For complete copyright and license terms please see the LICENSE at the root of this distribution.
-#
-# SPDX-License-Identifier: Apache-2.0 OR MIT
-#
-#
-import argparse
-import importlib
-import json
-import logging
-import os
-import pathlib
-import shutil
-import subprocess
-import sys
-
-
-ROOT_ENGINE_PATH = os.path.realpath(os.path.join(os.path.dirname(__file__), '..', '..'))
-if ROOT_ENGINE_PATH not in sys.path:
-    sys.path.append(ROOT_ENGINE_PATH)
-
-
-class _Configuration:
-    def __init__(self, platform, asset_platform, core_compiler):
-        self.platform = platform
-        self.asset_platform = asset_platform
-        self.compiler = '{}-{}'.format(platform, core_compiler)
-
-    def __str__(self):
-        return '{} ({})'.format(self.platform, self.asset_platform)
-
-class _ShaderType:
-    def __init__(self, name, base_compiler):
-        self.name = name
-        self.core_compiler = '{}-{}'.format(base_compiler, name)
-        self.configurations = []
-
-    def add_configuration(self, platform, asset_platform):
-        self.configurations.append(_Configuration(platform, asset_platform, self.core_compiler))
-
-def find_shader_type(shader_type_name, shader_types):
-    return next((shader for shader in shader_types if shader.name == shader_type_name), None)
-
-def find_shader_configuration(platform, assets, shader_configurations):
-    if platform:
-        check_func = lambda config: config.platform == platform and config.asset_platform == assets
-    else:
-        check_func = lambda config: config.asset_platform == assets
-
-    return next((config for config in shader_configurations if check_func(config)), None)
-
-def error(msg):
-    print(msg)
-    exit(1)
-
-def is_windows():
-    if os.name == 'nt':
-        return True
-    else:
-        return False
-
-
-def read_project_name_from_project_json(project_path):
-    project_name = None
-    try:
-        with (pathlib.Path(project_path) / 'project.json').open('r') as project_file:
-            project_json = json.load(project_file)
-            project_name = project_json['project_name']
-    except OSError as os_error:
-        logging.warning(f'Unable to open "project.json" file: {os_error}')
-    except json.JSONDecodeError as json_error:
-        logging.warning(f'Unable to decode json in {project_file}: {json_error}')
-    except KeyError as key_error:
-        logging.warning(f'{project_file} is missing project_name key: {key_error}')
-
-    return project_name
-
-
-def gen_shaders(shader_type, shader_config, shader_list, bin_folder, project_path, engine_path, verbose):
-    """
-    Generates the shaders for a specific platform and shader type using a list of shaders using ShaderCacheGen.
-    The generated shaders will be output at Cache/<game_name>/<asset_platform>/user/cache/Shaders/Cache/<shader_type>
-    """
-    platform = shader_config.platform
-    asset_platform = shader_config.asset_platform
-    compiler = shader_config.compiler
-
-    project_name = read_project_name_from_project_json(project_path)
-    asset_cache_root = os.path.join(project_path, 'Cache', asset_platform)
-
-    # Make sure that the <project-path>/user folder exists
-    user_cache_folder = os.path.join(project_path, 'user', 'Cache')
-    if not os.path.isdir(user_cache_folder):
-        try:
-            os.makedirs(user_cache_folder)
-        except os.error as err:
-            error("Unable to create the required cache folder '{}': {}".format(user_cache_folder, err))
-
-    cache_shader_list = os.path.join(user_cache_folder, 'shaders', 'shaderlist.txt')
-
-    if shader_list is None:
-        if is_windows():
-            shader_compiler_platform = 'x64'
-        else:
-            shader_compiler_platform = 'osx'
-
-        shader_list_path = os.path.join(user_cache_folder, shader_compiler_platform, compiler,
-                                        'ShaderList_{}.txt'.format(shader_type))
-        if not os.path.isfile(shader_list_path):
-            shader_list_path = cache_shader_list
-
-        print("Source Shader List not specified, using {} by default".format(shader_list_path))
-    else:
-        shader_list_path = shader_list
-
-    normalized_shaderlist_path = os.path.normpath(os.path.normcase(os.path.realpath(shader_list_path)))
-    normalized_cache_shader_list = os.path.normpath(os.path.normcase(os.path.realpath(cache_shader_list)))
-
-    if normalized_shaderlist_path != normalized_cache_shader_list:
-        cache_shader_list_basename = os.path.split(cache_shader_list)[0]
-        if not os.path.exists(cache_shader_list_basename):
-            os.makedirs(cache_shader_list_basename)
-        print("Copying shader_list from {} to {}".format(shader_list_path, cache_shader_list))
-        shutil.copy2(shader_list_path, cache_shader_list)
-
-    platform_shader_cache_path = os.path.join(user_cache_folder, 'shaders', 'cache', shader_type.lower())
-    shutil.rmtree(platform_shader_cache_path, ignore_errors=True)
-
-    shadergen_path = os.path.join(engine_path, bin_folder, 'ShaderCacheGen')
-    if is_windows():
-        shadergen_path += '.exe'
-
-    if not os.path.isfile(shadergen_path):
-        error("ShaderCacheGen could not be found at {}".format(shadergen_path))
-    else:
-        command_arguments = [
-            shadergen_path,
-            f'--project-path={project_path}',
-            '--BuildGlobalCache',
-            '--ShadersPlatform={}'.format(shader_type),
-            '--TargetPlatform={}'.format(asset_platform)
-        ]
-        if verbose:
-            print('Running: {}'.format(' '.join(command_arguments)))
-        subprocess.call(command_arguments)
-
-def add_shaders_types():
-    """
-    Add the shader types for the non restricted platforms.
-    The compiler argument is used for locating the shader_list file.
-    """
-    shaders = []
-    d3d11 = _ShaderType('D3D11', 'D3D11_FXC')
-    d3d11.add_configuration('PC', 'pc')
-    shaders.append(d3d11)
-
-    gl4 = _ShaderType('GL4', 'GLSL_HLSLcc')
-    gl4.add_configuration('PC', 'pc')
-    shaders.append(gl4)
-
-    gles3 = _ShaderType('GLES3', 'GLSL_HLSLcc')
-    gles3.add_configuration('Android', 'android')
-    shaders.append(gles3)
-
-    metal = _ShaderType('METAL', 'METAL_LLVM_DXC')
-    metal.add_configuration('Mac', 'mac')
-    metal.add_configuration('iOS', 'ios')
-    shaders.append(metal)
-
-    restricted_path = os.path.join(ROOT_ENGINE_PATH, 'restricted')
-    if os.path.exists(restricted_path):
-        restricted_platforms = os.listdir(restricted_path)
-        for platform in restricted_platforms:
-            try:
-                imported_module = importlib.import_module(f'restricted.{platform}.Tools.PakShaders.gen_shaders')
-            except ImportError:
-                continue
-
-            restricted_func = getattr(imported_module, 'get_restricted_platform_shader', lambda: iter(()))
-
-            for shader_type, shader_compiler, platform_name, asset_platform in restricted_func():
-
-                shader = find_shader_type(shader_type, shaders)
-                if shader is None:
-                    shader = _ShaderType(shader_type, shader_compiler)
-                    shaders.append(shader)
-
-                shader.add_configuration(platform_name, asset_platform)
-
-    return shaders
-
-def check_arguments(args, parser, shader_types):
-    """
-    Check that the platform and shader type arguments are correct.
-    """
-    shader_names = [shader.name for shader in shader_types]
-
-    shader_found = find_shader_type(args.shader_type, shader_types)
-    if shader_found is None:
-        parser.error('Invalid shader type {}. Must be one of [{}]'.format(args.shader_type, ' '.join(shader_names)))
-
-    else:
-        config_found = find_shader_configuration(args.shader_platform, args.asset_platform, shader_found.configurations)
-        if config_found is None:
-            parser.error('Invalid configuration for shader type "{}". It must be one of the following: {}'.format(shader_found.name, ', '.join(str(config) for config in shader_found.configurations)))
-
-
-parser = argparse.ArgumentParser(description='Generates the shaders for a specific platform and shader type.')
-parser.add_argument('asset_platform', type=str, help="The asset cache sub folder to use for shader generation")
-parser.add_argument('shader_type', type=str, help="The shader type to use")
-parser.add_argument('-p', '--shader-platform', type=str, required=False, default='', help="The target platform to generate shaders for.")
-parser.add_argument('-b', '--bin-folder', type=str, help="Folder where the ShaderCacheGen executable lives. This is used along the project (ShaderCacheGen)")
-parser.add_argument('-e', '--engine-path', type=str, help="Path to the engine root folder. This the same as game_path for non external projects")
-parser.add_argument('-g', '--project-path', type=str, required=True, help="Path to the game root folder. This the same as engine_path for non external projects")
-parser.add_argument('-s', '--shader-list', type=str, required=False, help="Optional path to the list of shaders. If not provided will use the list generated by the local shader compiler.")
-parser.add_argument('-v', '--verbose', action="store_true", required=False, help="Increase the logging output")
-
-args = parser.parse_args()
-
-shader_types = add_shaders_types()
-
-check_arguments(args, parser, shader_types)
-print('Generating shaders for {} (shaders={}, platform={}, assets={})'.format(args.project_path, args.shader_type, args.shader_platform, args.asset_platform))
-
-shader = find_shader_type(args.shader_type, shader_types)
-shader_config = find_shader_configuration(args.shader_platform, args.asset_platform, shader.configurations)
-gen_shaders(args.shader_type, shader_config, args.shader_list, args.bin_folder, args.project_path, args.engine_path, args.verbose)
-
-print('Finish generating shaders')

+ 0 - 65
scripts/bundler/get_shader_list.py

@@ -1,65 +0,0 @@
-#
-# Copyright (c) Contributors to the Open 3D Engine Project.
-# For complete copyright and license terms please see the LICENSE at the root of this distribution.
-#
-# SPDX-License-Identifier: Apache-2.0 OR MIT
-#
-#
-import argparse
-import os
-import pathlib
-import subprocess
-
-def error(msg):
-    print(msg)
-    exit(1)
-
-def is_windows():
-    if os.name == 'nt':
-        return True
-    else:
-        return False
-
-
-def get_shader_list(project_path, asset_platform, shader_type, shader_platform, shadergen_path):
-    """
-    Gets the shader list for a specific platform using ShaderCacheGen.
-    Right now the shader list will always output at <project-path>/user/Cache/Shaders
-    That will change when this is updated to take a destination path
-    """
-    shadergen_path = os.path.join(shadergen_path, 'ShaderCacheGen')
-    if is_windows():
-        shadergen_path += '.exe'
-
-    command_args = [
-        shadergen_path,
-        f'--project-path={str(project_path)}'
-        '--GetShaderList',
-        '--ShadersPlatform={}'.format(shader_type),
-        '--TargetPlatform={}'.format(asset_platform)
-    ]
-
-    if not os.path.isfile(shadergen_path):
-        error("[ERROR] ShaderCacheGen could not be found at {}".format(shadergen_path))
-    else:
-        command = ' '.join(command_args)
-        print('[INFO] get_shader_list: Running command - {}'.format(command))
-        try:
-            subprocess.check_call(command, shell=True)
-        except subprocess.CalledProcessError:
-            error('[ERROR] Failed to get the shader list for {}'.format(shader_type))
-
-
-parser = argparse.ArgumentParser(description='Gets the shader list for a specific platform from the current shader compiler server')
-
-parser.add_argument('-g', '--project-path', type=pathlib.Path, required=True, help="Path to the project")
-parser.add_argument('asset-platform', type=str, help="The asset cache sub folder to use for shader generation")
-parser.add_argument('shader-type', type=str, help="The shader type to use")
-parser.add_argument('-p', '--shader_platform', type=str, required=False, default='', help="The target platform to generate shaders for.")
-parser.add_argument('-s', '--shadergen_path', type=str, help="Path to where the the ShaderCacheGen executable lives")
-
-args = parser.parse_args()
-
-print('Getting shader list for {}'.format(args.asset_platform))
-get_shader_list(args.project_path, args.asset_platform, args.shader_type, args.shader_platform, args.shadergen_path)
-print('Finish getting shader list')

+ 0 - 139
scripts/bundler/pak_shaders.py

@@ -1,139 +0,0 @@
-#
-# Copyright (c) Contributors to the Open 3D Engine Project.
-# For complete copyright and license terms please see the LICENSE at the root of this distribution.
-#
-# SPDX-License-Identifier: Apache-2.0 OR MIT
-#
-#
-import argparse
-import fnmatch
-import glob
-import os
-import re
-import sys
-import zipfile
-
-
-def _create_zip(source_path, zip_file_path, append, filter_list, ignore_list, compression_level, zip_internal_path = ''):
-    """
-    Internal function for creating a zip file containing the files that match the list of filters provided.
-    File matching is case insensitive.
-    """
-    ignore_list = [filter.lower() for filter in ignore_list]
-    filter_list = [filter.lower() for filter in filter_list]
-    
-    ignore_list = r'|'.join([fnmatch.translate(x) for x in ignore_list])
-    try:
-        mode = 'a' if append else 'w'        
-        with zipfile.ZipFile(zip_file_path, mode, compression_level) as myzip:
-            # Go through all the files in the source path.
-            for root, dirnames, filenames in os.walk(source_path):
-                # Remove files that match the ignore list.
-                files = [os.path.relpath(os.path.join(root, file), source_path).lower() for file in filenames if not re.match(ignore_list, file.lower())]
-                # Match the files we have found against the filters.
-                for filter in filter_list:
-                    for filename in fnmatch.filter(files, filter):
-                        # Add the file to the zip using the specified internal destination.
-                        myzip.write(os.path.join(source_path, filename), os.path.join(zip_internal_path, filename))
-    except IOError as error:
-       print("I/O error({0}) while creating zip file {1}: {2}".format(error.errno, zip_file_path, error.strerror))
-       return False
-    except:
-       print("Unexpected error while creating zip file {0}: {1}".format(zip_file_path, sys.exc_info()[0]))
-       return False
-
-    return True
-
-# Create or append a pak file with all the shaders found in source_path.
-def pak_shaders_in_folder(source_path, output_folder, shader_type, append):
-    """
-    Creates the shadercache.pak and the shadercachestartup.pak using the shader files located at source_path.
-    """
-
-    ignore_list = ['shaderlist.txt', 'shadercachemisses.txt']
-
-    shaders_cache_startup_filters = ['Common.cfib', 'FXConstantDefs.cfib', 'FXSamplerDefs.cfib', 'FXSetupEnvVars.cfib',
-                                     'FXStreamDefs.cfib', 'fallback.cfxb', 'fallback.fxb', 'FixedPipelineEmu.cfxb',
-                                     'FixedPipelineEmu.fxb', 'Stereo.cfxb', 'Stereo.fxb', 'lookupdata.bin',
-                                     'Video.cfxb', 'Video.fxb',
-                                     os.path.join('CGPShaders', 'FixedPipelineEmu@*'),
-                                     os.path.join('CGVShaders', 'FixedPipelineEmu@*'),
-                                     os.path.join('CGPShaders', 'FixedPipelineEmu', '*'),
-                                     os.path.join('CGVShaders', 'FixedPipelineEmu', '*'),
-                                     os.path.join('CGPShaders', 'Stereo@*'),
-                                     os.path.join('CGVShaders', 'Stereo@*'),
-                                     os.path.join('CGPShaders', 'Stereo', '*'),
-                                     os.path.join('CGVShaders', 'Stereo', '*'),
-                                     os.path.join('CGPShaders', 'Video@*'),
-                                     os.path.join('CGVShaders', 'Video@*'),
-                                     os.path.join('CGPShaders', 'Video', '*'),
-                                     os.path.join('CGVShaders', 'Video', '*')
-                                     ]
-
-    print('Packing shader source folder {}'.format(source_path))
-    result = True
-    if os.path.exists(source_path):
-        if not os.path.exists(output_folder):
-            os.makedirs(output_folder)
-
-        # We want the files to be added to the "shaders/cache/$shader_type" path inside the pak file.
-        zip_interal_path = os.path.join('shaders', 'cache', shader_type)
-
-        result &= _create_zip(source_path, os.path.join(output_folder, 'shadercache.pak'), append, ['*.*'], ignore_list, zipfile.ZIP_STORED, zip_interal_path)
-        result &= _create_zip(source_path, os.path.join(output_folder, 'shadercachestartup.pak'), append, shaders_cache_startup_filters, ignore_list, zipfile.ZIP_STORED, zip_interal_path)
-    else:
-        print('[Error] Shader source folder is not available at {}. Shader type: {}.'.format(source_path, shader_type))
-        result = False
-    return result
-
-# Generate a shaders pak file with all the shader types indicated.
-# NOTE: A shader type can specify an specific source path or not. Examples:
-#       - 'metal,specific/path/to/shaders': Use the folder specified as the source path to all metal shaders.
-#       - 'metal': Use source_path/metal as source path to all metal shaders. Wildcard usage is allowed, for example 'gles3*'.
-def pak_shaders(source_path, output_folder, shader_types):
-    shader_flavors_packed = 0
-    for shader_info in shader_types:
-        # First element is the type, the second (if present) is the specific source
-        shader_type = shader_info[0]
-        if len(shader_info) > 1:
-            shader_type_source = shader_info[1]
-            if pak_shaders_in_folder(shader_type_source, output_folder, shader_type, shader_flavors_packed > 0):
-                shader_flavors_packed = shader_flavors_packed + 1
-            else:
-                return False
-        else:
-            # No specific source path for this shader type so use the global source path. Wildcard allowed.
-            listing = glob.glob(os.path.join(source_path, shader_type))
-            for shader_type_source in listing:
-                if os.path.isdir(shader_type_source):
-                    # Since the shader_type can use wildcard we have to obtain the actual shader type found by removing source_path
-                    # Example: If shader_type is 'gl4*' then now will be 'gl4_4'
-                    shader_type = shader_type_source[len(source_path)+1:]
-                    if pak_shaders_in_folder(shader_type_source, output_folder, shader_type, shader_flavors_packed > 0):
-                        shader_flavors_packed = shader_flavors_packed + 1
-                    else:
-                        return False
-
-    if shader_flavors_packed == 0:
-        print('Failed to pack any shader type')
-
-    return shader_flavors_packed > 0
-
-def pair_arg(arg):
-    return [str(x) for x in arg.split(',')]
-
-parser = argparse.ArgumentParser(description='Pack the provided shader files into paks.')
-parser.add_argument("output", type=str, help="specify the output folder")
-parser.add_argument('-r', '--source', type=str, required=False, help="specify global input folder")
-parser.add_argument('-s', '--shaders_types', required=True, nargs='+', type=pair_arg,
-                    help='list of shader types with optional source path')
-
-args = parser.parse_args()
-print('Packing shaders...')
-if not pak_shaders(args.source, args.output, args.shaders_types):
-    print('Failed to pack shaders')
-    exit(1)
-
-print('Packs have been placed at "{}"'.format(args.output))
-print('To use them, deploy them in your assets folder.')
-print('Finish packing shaders')