コード例 #1
0
    def run(self):
        # If the build starts with the project name, we know this is a game project being built
        is_game_project = self.build_name.startswith(self.config.uproject_name)

        print_action('{} {}'.format(
            'Building' if not self.config.clean else 'Cleaning',
            self.build_name))

        cmd_args = [
            self.build_name, self.config.platform, self.config.configuration
        ]
        if is_game_project:
            cmd_args.append(self.config.uproject_file_path)
        cmd_args += ['-NoHotReload', '-waitmutex']
        if get_visual_studio_version() == 2017:
            cmd_args.append('-2017')

        # Do any pre cleaning
        if self.config.clean or self.force_clean:
            if is_game_project:
                self.clean_game_project_folder()
            else:
                if launch(self.config.UE4CleanBatchPath, cmd_args) != 0:
                    self.error = 'Failed to clean project {}'.format(
                        self.build_name)
                    return False

        # Do the actual build
        if launch(self.config.UE4BuildBatchPath, cmd_args) != 0:
            self.error = 'Failed to build "{}"!'.format(self.build_name)
            return False
        return True
コード例 #2
0
    def run(self):
        if not self.config.automated:
            # First make sure we actually have git credentials
            ssh_path = os.path.join(os.environ['USERPROFILE'], '.ssh')
            if not os.path.exists(ssh_path) and self.rsa_path != '':
                rsa_file = os.path.join(self.config.uproject_dir_path, self.rsa_path)
                if not os.path.isfile(rsa_file):
                    self.error = 'No git credentials exists at rsa_path! ' \
                                 'Check rsa_path is relative to the project path and exists.'
                    return False
                os.mkdir(ssh_path)
                shutil.copy2(rsa_file, ssh_path)

            # To get around the annoying user prompt, lets just set github to be trusted, no key checking
            if self.disable_strict_hostkey_check:
                if not os.path.isfile(os.path.join(ssh_path, 'config')):
                    with open(os.path.join(ssh_path, 'config'), 'w') as fp:
                        fp.write('Host github.com\nStrictHostKeyChecking no')

        output_dir = os.path.join(self.config.uproject_dir_path, self.output_folder)

        if self.force_repull and os.path.exists(output_dir):
            print_action("Deleting Unreal Engine Folder for a complete re-pull")

            def on_rm_error(func, path, exc_info):
                # path contains the path of the file that couldn't be removed
                # let's just assume that it's read-only and unlink it.
                del func  # unused
                if exc_info[0] is not FileNotFoundError:
                    os.chmod(path, stat.S_IWRITE)
                    os.unlink(path)

            # Forcing a re-pull, delete the whole engine directory!
            shutil.rmtree(output_dir, onerror=on_rm_error)

        if not os.path.isdir(output_dir):
            os.makedirs(output_dir)

        if not os.path.isdir(os.path.join(output_dir, '.git')):
            print_action("Cloning from Git '{}' branch '{}'".format(self.repo_name, self.branch_name))
            cmd_args = ['clone', '-b', self.branch_name, self.repo_name, output_dir]
            err = launch('git', cmd_args)
            if err != 0:
                self.error = 'Git clone failed!'
                return False
        else:
            with push_directory(output_dir):
                print_action("Pulling from Git '{}' branch '{}'".format(self.repo_name, self.branch_name))
                err = launch('git', ['pull', 'origin', self.branch_name], silent=True)
                if err != 0:
                    self.error = 'Git pull failed!'
                    return False
        return True
コード例 #3
0
ファイル: tools.py プロジェクト: rfsheffer/PyUE4Builder
def client(config: ProjectConfig, extra, ip):
    """ Run the client """
    print_action('Running Client')
    cmd_args = ['-game', '-windowed', '-ResX=1280', '-ResY=720']
    cmd_args.extend(['-' + arg.strip() for arg in extra.split('-')[1:]])

    if ip != '':
        cmd_args.insert(0, ip)

    client_exe_path = os.path.join(
        config.uproject_dir_path, 'builds\\WindowsNoEditor\\{0}\\Binaries\\'
        'Win64\\{0}.exe'.format(config.uproject_name))
    if not os.path.isfile(client_exe_path):
        error_exit('Client is not built!', not config.automated)

    launch(client_exe_path, cmd_args, True, should_wait=False)
コード例 #4
0
ファイル: tools.py プロジェクト: rfsheffer/PyUE4Builder
def server(config: ProjectConfig, extra, umap):
    """ Run a server """
    print_action('Running Server')
    cmd_args = []
    cmd_args.extend(['-' + arg.strip() for arg in extra.split('-')[1:]])

    if umap != '':
        cmd_args.insert(0, umap)

    server_exe_path = os.path.join(
        config.uproject_dir_path, 'builds\\WindowsServer\\{0}\\Binaries\\'
        'Win64\\{0}Server.exe'.format(config.uproject_name))
    if not os.path.isfile(server_exe_path):
        error_exit('Server is not built!', not config.automated)

    launch(server_exe_path, cmd_args, True, should_wait=False)
コード例 #5
0
    def run(self):
        exe_path = 'UE4Editor-Win64-Debug-Cmd.exe' if self.config.debug else 'UE4Editor-Cmd.exe'
        exe_path = os.path.join(self.config.UE4EnginePath, 'Engine/Binaries/Win64', exe_path)
        if not os.path.isfile(exe_path):
            self.error = 'Unable to resolve path to unreal cmd "{}"'.format(exe_path)
            return False

        # Cook command parameters
        cmd_args = ['-run=Cook']

        for map_name in self.maps:
            cmd_args.append('-Map={}'.format(map_name))

        for dir_name in self.cook_dirs:
            cmd_args.append('-CookDir={}'.format(dir_name))

        if len(self.cultures) > 0:
            cmd_args.append('-CookCultures={}'.format('+'.join(self.cultures)))

        cmd_args.append('-NoLogTimes')

        # General Parameters
        cmd_args.extend(['-TargetPlatform={}'.format(self.config.platform), '-Unversioned'])

        cmd_args.append('-output_dir={}'.format(self.output_dir))

        if self.config.debug:
            cmd_args.append('-debug')

        if launch(exe_path, cmd_args) != 0:
            self.error = 'Unable to complete cook action. Check output.'
            return False

        return True
コード例 #6
0
ファイル: tools.py プロジェクト: rfsheffer/PyUE4Builder
def standalone_func(config: ProjectConfig, extra, ip, waittime, umap):
    """ Run a standalone build of the game """
    print_action('Running Standalone')
    cmd_args = [
        config.uproject_file_path, '-game', '-windowed', '-ResX=1280',
        '-ResY=720'
    ]
    cmd_args.extend(['-' + arg.strip() for arg in extra.split('-')[1:]])

    if ip != '':
        time.sleep(waittime)
        cmd_args.insert(1, ip)

    if umap != '':
        cmd_args.insert(1, umap)

    launch(config.UE4EditorPath, cmd_args, True, should_wait=False)
コード例 #7
0
ファイル: tools.py プロジェクト: RomanSolomatin/PyUE4Builder
def genloc(config):
    """ Generate localization """
    print_action('Generating Localization')
    cmd_args = [
        config.uproject_file_path, '-Run=GatherText',
        '-config={}'.format(config.proj_localization_script), '-log'
    ]
    if launch(config.UE4EditorPath, cmd_args) != 0:
        error_exit('Failed to generate localization, see errors...')

    click.pause()
コード例 #8
0
ファイル: tools.py プロジェクト: RomanSolomatin/PyUE4Builder
def genproj(config):
    """ Generate project file """
    print_action('Generating Project Files')

    cmd_args = [
        '-ProjectFiles', '-project={}'.format(config.uproject_file_path),
        '-game', '-engine'
    ]
    if get_visual_studio_version() == 2017:
        cmd_args.append('-2017')
    if launch(config.UE4UBTPath, cmd_args) != 0:
        error_exit('Failed to generate project files, see errors...')
コード例 #9
0
ファイル: tools.py プロジェクト: rfsheffer/PyUE4Builder
def genproj_func(config: ProjectConfig, run_it):
    """ Generate project file """
    print_action('Generating Project Files')

    cmd_args = [
        '-ProjectFiles', '-project={}'.format(config.uproject_file_path),
        '-game', '-engine'
    ]
    if config.engine_minor_version <= 25:
        cmd_args.append('-VS{}'.format(
            get_visual_studio_version(config.get_suitable_vs_versions())))

    if launch(config.UE4UBTPath, cmd_args) != 0:
        error_exit('Failed to generate project files, see errors...',
                   not config.automated)

    if run_it:
        launch(os.path.join(config.uproject_dir_path,
                            config.uproject_name + '.sln'),
               separate_terminal=True,
               should_wait=False)
コード例 #10
0
ファイル: tools.py プロジェクト: rfsheffer/PyUE4Builder
def compile_all_blueprints(config: ProjectConfig):
    print_action('Compiling All Blueprints')
    cmd_args = [
        config.uproject_file_path, '-run=CompileAllBlueprints',
        '-autocheckout', '-projectonly', '-unattended'
    ]
    if launch(config.UE4EditorPath, cmd_args) != 0:
        error_exit('Failed to compile all blueprints, see errors...',
                   not config.automated)

    if not config.automated:
        click.pause()
コード例 #11
0
ファイル: tools.py プロジェクト: rfsheffer/PyUE4Builder
def fix_redirects(config: ProjectConfig):
    print_action('Fixing Redirectors')
    cmd_args = [
        config.uproject_file_path, '-run=ResavePackages', '-fixupredirects',
        '-autocheckout', '-projectonly', '-unattended'
    ]
    if launch(config.UE4EditorPath, cmd_args) != 0:
        error_exit('Failed to fixup redirectors, see errors...',
                   not config.automated)

    if not config.automated:
        click.pause()
コード例 #12
0
    def run(self):
        if self.config.clean:
            return True

        if self.config.clean:
            return True

        template_file_path = os.path.join(self.config.uproject_dir_path,
                                          self.steam_app_template)

        auto_file_path = os.path.join(
            self.config.uproject_dir_path, self.steam_app_dir,
            '{}_build.vdf'.format(self.config.uproject_name.lower()))

        self.create_app_build_script(
            template_file_path, auto_file_path,
            '..\\..\\..\\..\\..\\builds\\{}'.format(self.build_name),
            '{} Version {}'.format(self.config.uproject_name,
                                   self.config.version_str), self.set_live)

        try:
            steam_app_id_name = 'steam_appid.txt'
            shutil.copy2(
                os.path.join(self.config.uproject_dir_path, steam_app_id_name),
                os.path.join(self.config.builds_path,
                             '{}\\steam_appid.txt'.format(self.build_name)))
            if self.install_script_rel_path != '':
                shutil.copy2(
                    os.path.join(self.config.uproject_dir_path,
                                 'steam_redist_installscript.vdf'),
                    os.path.join(self.config.builds_path,
                                 self.install_script_rel_path))
            print_action('Steam required files inserted into build')
        except Exception:
            pass

        print_action('Uploading {} Build to Steam'.format(
            self.config.uproject_name))
        cmd_args = [
            '+login', os.environ[STEAMWORKS_USER_ENV_VAR],
            os.environ[STEAMWORKS_PASS_ENV_VAR], '+run_app_build',
            '..\\scripts\\{}_build.vdf'.format(
                self.config.uproject_name.lower()), '+quit'
        ]

        if launch(
                os.path.join(self.config.uproject_dir_path,
                             self.builder_exe_path), cmd_args) != 0:
            self.error = 'Unable to upload build {} to steam!'.format(
                self.config.uproject_name)
            return False
        return True
コード例 #13
0
ファイル: tools.py プロジェクト: rfsheffer/PyUE4Builder
def do_project_build(extra_args=None):
    args = [
        os.path.join(os.path.dirname(__file__), 'build_script.py'), '-s',
        '{}'.format(script_file_path), '-t', 'Editor'
    ]
    if extra_args is not None:
        args.extend(extra_args)
    result = launch(os.path.join(
        os.environ.get("PYTHON_HOME", ".").replace('"', ''), "python.exe"),
                    args,
                    False,
                    should_wait=True)
    return result == 0
コード例 #14
0
    def do_build(self, build_name):
        # If the build starts with the project name, we know this is a game project being built
        is_game_project = build_name.startswith(self.config.uproject_name)

        print_action('{} {}'.format(
            'Building' if not self.config.clean else 'Cleaning', build_name))

        cmd_args = [
            build_name, self.config.platform, self.config.configuration
        ]
        if is_game_project:
            cmd_args.append(self.config.uproject_file_path)
        cmd_args += ['-NoHotReload', '-waitmutex']
        if self.config.engine_minor_version <= 25:
            cmd_args.append('-VS{}'.format(
                get_visual_studio_version(
                    self.config.get_suitable_vs_versions())))
        else:
            # Engine versions greater than 25 can determine visual studios location and will do it automatically.
            # We include -FromMsBuild which is common beyond version 25 but it is just a format specifier.
            cmd_args.append('-FromMsBuild')

        # Do any pre cleaning
        if self.config.clean or self.force_clean:
            if is_game_project:
                self.clean_game_project_folder()
            else:
                if launch(self.config.UE4CleanBatchPath, cmd_args) != 0:
                    self.error = 'Failed to clean project {}'.format(
                        build_name)
                    return False

        # Do the actual build
        if launch(self.config.UE4BuildBatchPath, cmd_args) != 0:
            self.error = 'Failed to build "{}"!'.format(build_name)
            return False
        return True
コード例 #15
0
    def run(self):
        pak_list_file_path = os.path.join(
            os.getcwd(), '{}_pak_list.txt'.format(self.pak_name))
        with open(pak_list_file_path, 'w') as fp:
            for content_path in self.content_paths:
                asset_paths = glob.glob(
                    os.path.join(self.content_dir, content_path) +
                    os.path.sep + '**',
                    recursive=True)
                for asset_path in asset_paths:
                    if os.path.isdir(asset_path):
                        continue
                    reduced_root = asset_path.replace(self.content_dir, '')
                    if reduced_root[0] == '\\' or reduced_root[0] == '/':
                        reduced_root = reduced_root[1:]
                    content_asset_path = os.path.join(self.asset_root_path,
                                                      reduced_root)
                    write_line = '"{0}" "{1}" -compress\n'.format(
                        asset_path, content_asset_path.replace('\\', '/'))
                    fp.write(write_line)

        unreal_pak_path = os.path.join(
            self.config.UE4EnginePath,
            'Engine\\Binaries\\Win64\\UnrealPak.exe')
        if not os.path.isfile(unreal_pak_path):
            self.error = 'Unable to find path to UnrealPak.exe. Is it compiled?'
            return False

        cmd_args = [
            os.path.join(self.config.uproject_dir_path, self.output_dir,
                         self.pak_name + '.pak'),
            '-create={}'.format(pak_list_file_path), '-encryptionini',
            '-enginedir={}'.format(self.config.UE4EnginePath),
            '-projectdir={}'.format(self.config.uproject_dir_path),
            '-platform={}'.format(self.config.platform), '-UTF8Output',
            '-multiprocess'
        ]

        if launch(unreal_pak_path, cmd_args) != 0:
            self.error = 'Unable to pak!'
            return False
        return True
コード例 #16
0
    def run(self):
        if self.config.editor_running:
            self.warning('You are packaging while also running the editor. '
                         'This could fail because of memory contraints.')

        # click.secho('Building for client version {}'.format(self.config.version_str))

        def on_rm_error(func, path, exc_info):
            # path contains the path of the file that couldn't be removed
            # let's just assume that it's read-only and unlink it.
            del func  # Unused
            if exc_info[0] is not FileNotFoundError:
                os.chmod(path, stat.S_IWRITE)
                os.unlink(path)

        if self.config.clean:
            # Kill the build directories
            if self.build_type == 'client':
                shutil.rmtree(os.path.join(
                    self.config.builds_path, '{}Client'.format(
                        platform_long_names[self.config.platform])),
                              onerror=on_rm_error)
            elif self.build_type == 'server':
                shutil.rmtree(os.path.join(
                    self.config.builds_path, '{}Server'.format(
                        platform_long_names[self.config.platform])),
                              onerror=on_rm_error)
            else:
                shutil.rmtree(os.path.join(
                    self.config.builds_path, '{}{}'.format(
                        platform_long_names[self.config.platform],
                        'NoEditor' if self.no_compile_editor else '')),
                              onerror=on_rm_error)

        # cap_build_name = self.config.uproject_name.title()
        # print_action('Building {} Build'.format(cap_build_name))

        build_blacklist_file_path = os.path.join(
            self.config.uproject_dir_path,
            self.build_blacklist_dir.format(self.config.platform),
            self.blacklist_file_name.format(self.config.configuration))
        if self.content_black_list != '':
            print_action(
                'Setting up content blacklist for configuration {}'.format(
                    self.config.configuration))
            if os.path.isfile(build_blacklist_file_path):
                os.unlink(build_blacklist_file_path)
            os.makedirs(os.path.join(
                self.config.uproject_dir_path,
                self.build_blacklist_dir.format(self.config.platform)),
                        exist_ok=True)
            shutil.copyfile(
                os.path.join(self.config.uproject_dir_path,
                             self.content_black_list),
                build_blacklist_file_path)

        cmd_args = [
            '-ScriptsForProject={}'.format(self.config.uproject_file_path),
            'BuildCookRun', '-NoHotReload', '-nop4',
            '-project={}'.format(self.config.uproject_file_path),
            '-archivedirectory={}'.format(self.config.builds_path),
            '-clientconfig={}'.format(self.config.configuration),
            '-serverconfig={}'.format(self.config.configuration),
            '-ue4exe={}'.format('UE4Editor-Win64-Debug-Cmd.exe' if self.config.
                                debug else 'UE4Editor-Cmd.exe'), '-prereqs',
            '-targetplatform={}'.format(self.config.platform),
            '-platform={}'.format(self.config.platform),
            '-servertargetplatform={}'.format(self.config.platform),
            '-serverplatform={}'.format(self.config.platform),
            '-CrashReporter', '-utf8output'
        ]

        if self.no_compile_editor:
            cmd_args.append('-nocompileeditor')

        if self.build:
            cmd_args.append('-build')
        if self.cook:
            cmd_args.append('-cook')
        if self.package:
            cmd_args.append('-package')
        if self.stage:
            cmd_args.append('-stage')
        if self.archive:
            cmd_args.append('-archive')

        if self.build_type == 'client':
            cmd_args.append('-client')
        elif self.build_type == 'server':
            cmd_args.extend(['-server', '-noclient'])

        if self.nativize_assets:
            cmd_args.append('-nativizeAssets')
        if self.pak_assets and self.stage:
            cmd_args.append('-pak')
        if self.compressed_assets:
            cmd_args.append('-compressed')
        if self.no_debug_info:
            cmd_args.append('-nodebuginfo')
        if self.no_editor_content:
            cmd_args.append('-SkipCookingEditorContent')
        if self.ignore_cook_errors:
            cmd_args.append('-IgnoreCookErrors')

        if len(self.cook_output_dir) > 0:
            cmd_args.append('-CookOutputDir={}'.format(
                os.path.join(self.config.uproject_dir_path,
                             self.cook_output_dir)))

        if len(self.maps) > 0:
            cmd_args.append('-map={}'.format('+'.join(self.maps)))

        if len(self.cook_dirs) > 0:
            cmd_args.append('-cookdir={}'.format('+'.join(self.cook_dirs)))

        # TODO: determine engine bug or issue in this script. Fails if previous cooked content exists already.
        if len(self.cook_output_dir) > 0:
            # manual clean everytime because of bug...
            shutil.rmtree(os.path.join(self.config.uproject_dir_path,
                                       self.cook_output_dir),
                          onerror=on_rm_error)
            cmd_args.extend(['-iterate', '-iterativecooking'])
        else:
            if self.config.clean or self.full_rebuild:
                cmd_args.append('-clean')
            else:
                cmd_args.extend(['-iterate', '-iterativecooking'])

        cmd_args.append('-compile')

        # print_action('Building, Cooking, and Packaging {} Build'.format(cap_build_name))
        if launch(self.config.UE4RunUATBatPath, cmd_args) != 0:
            self.error = 'Unable to build {}!'.format(
                self.config.uproject_name)
            return False

        # Don't leave blacklist around
        if os.path.isfile(build_blacklist_file_path):
            os.unlink(build_blacklist_file_path)

        return True
コード例 #17
0
ファイル: tools.py プロジェクト: rfsheffer/PyUE4Builder
def runeditor_func(config: ProjectConfig):
    """ Run the editor with the registered project """
    print_action('Running Editor')
    launch(config.UE4EditorPath, [config.uproject_file_path],
           True,
           should_wait=False)
コード例 #18
0
    def run(self):
        if not self.config.automated:
            # First make sure we actually have git credentials
            ssh_path = os.path.join(os.environ['USERPROFILE'], '.ssh')
            if not os.path.exists(ssh_path) and self.rsa_path != '':
                rsa_file = os.path.join(self.config.uproject_dir_path,
                                        self.rsa_path)
                if not os.path.isfile(rsa_file):
                    self.error = 'No git credentials exists at rsa_path! ' \
                                 'Check rsa_path is relative to the project path and exists.'
                    return False
                os.mkdir(ssh_path)
                shutil.copy2(rsa_file, ssh_path)

            # To get around the annoying user prompt, lets just set github to be trusted, no key checking
            if self.disable_strict_hostkey_check:
                if not os.path.isfile(os.path.join(ssh_path, 'config')):
                    with open(os.path.join(ssh_path, 'config'), 'w') as fp:
                        fp.write('Host github.com\nStrictHostKeyChecking no')

        output_dir = os.path.join(self.config.uproject_dir_path,
                                  self.output_folder)

        if not os.path.isdir(output_dir):
            os.makedirs(output_dir)
        elif os.path.isdir(os.path.join(output_dir, '.git')):
            # check if the repo in the folder is on the correct branch. If not, delete the folder so we can
            # start over.
            with push_directory(output_dir, False):
                cur_branch = self.get_current_branch()
                if cur_branch != self.branch_name:
                    if cur_branch in self.similar_branches and self.branch_name in self.similar_branches:
                        do_branch_switch = click.confirm(
                            'Branch mismatch but both branches are similar. '
                            'Do branch switch? (If you have unsaved changes in this repo '
                            'this will clobber them!)')
                        if not do_branch_switch:
                            self.error = 'Clean up your repo manually so a branch switch can be made.'
                            return False
                        err = launch('git', ['fetch', 'origin'])
                        if err != 0:
                            self.error = 'Git fetch failed...'
                            return False
                        # Cleanup before branch switch
                        launch('git', ['checkout', '--', '*'])
                        cmd_args = [
                            'checkout', '-b', self.branch_name,
                            'origin/{}'.format(self.branch_name)
                        ]
                        err = launch('git', cmd_args)
                        if err != 0:
                            ask_do_repull = click.confirm(
                                'Tried to switch branches but failed. '
                                'Would you like to clobber and re-pull?')
                            if ask_do_repull:
                                self.force_repull = True
                            else:
                                self.error = 'Please correct the issue manually. Check the errors above for hints.'
                                return False
                        else:
                            # Cleanup again just in case
                            launch('git', ['checkout', '--', '*'])
                            self.branch_switched = True
                    else:
                        ask_do_repull = click.confirm(
                            'Branch mismatch ("{}" should equal "{}"). Clobber this entire '
                            'repo and do a re-pull?'.format(
                                cur_branch, self.branch_name),
                            default=False)
                        if ask_do_repull:
                            self.force_repull = True
                        else:
                            self.error = 'Branch mismatch caused pull to be halted. Please correct the issue manually.'
                            return False

        if self.force_repull:
            print_action(
                "Deleting the folder '{}' for a complete re-pull".format(
                    self.output_folder))

            def on_rm_error(func, path, exc_info):
                # path contains the path of the file that couldn't be removed
                # let's just assume that it's read-only and unlink it.
                del func  # unused
                if exc_info[0] is not FileNotFoundError:
                    os.chmod(path, stat.S_IWRITE)
                    os.unlink(path)

            # Forcing a re-pull, delete the whole directory!
            try:
                shutil.rmtree(output_dir, onerror=on_rm_error)
            except Exception:
                self.error = 'Unable to delete the repo directory for a re-pull. ' \
                             'Check that the files are not open / held by another process and try again.'
                return False
            os.makedirs(output_dir)

        if not os.path.isdir(os.path.join(output_dir, '.git')):
            print_action("Cloning from Git '{}' branch '{}'".format(
                self.repo_name, self.branch_name))
            cmd_args = [
                'clone', '-b', self.branch_name, self.repo_name, output_dir
            ]
            err = launch('git', cmd_args)
            if err != 0:
                self.error = 'Git clone failed!'
                return False
        else:
            with push_directory(output_dir, False):
                print_action("Pulling from Git '{}' branch '{}'".format(
                    self.repo_name, self.branch_name))
                err = launch('git', ['pull', 'origin', self.branch_name],
                             silent=True)
                if err != 0:
                    self.error = 'Git pull failed!'
                    return False
        return True
コード例 #19
0
ファイル: build_script.py プロジェクト: VREALITY/PyUE4Builder
def ensure_engine(config, engine_override):
    """
    Pre-work step of ensuring we have a valid engine and enough components exist to do work
    :param config: The project configuration (may not point to a valid engine yet)
    :param engine_override: The desired engine directory path to use
    """
    can_pull_engine = config.git_repo != '' and config.git_proj_branch != ''

    if config.UE4EnginePath == '':
        if not can_pull_engine and engine_override == '':
            error_exit(
                'Static engine placement required for non-git pulled engine. '
                'You can specify a path using the -e param, or specify git configuration.',
                not config.automated)

        if engine_override != '':
            config.setup_engine_paths(os.path.abspath(engine_override))
        elif not config.automated:
            result = click.confirm(
                'Would you like to specify the location of the engine install?',
                default=False)
            if result:
                result = click.prompt(
                    'Where would you like to install the engine?')
                if not os.path.exists(result):
                    try:
                        os.makedirs(result)
                    except Exception:
                        error_exit(
                            'Unable to create engine directory! Tried @ {}'.
                            format(result), not config.automated)
                config.setup_engine_paths(result)
            else:
                # Find an ideal location to put the engine
                if len(config.engine_path_name) == 0:
                    # Put the engine one directory down from the uproject
                    engine_path = os.path.abspath(
                        os.path.join(
                            config.uproject_dir_path,
                            '..\\UnrealEngine_{}'.format(
                                config.uproject_name)))
                else:
                    if os.path.isabs(config.engine_path_name):
                        engine_path = config.engine_path_name
                    else:
                        engine_path = os.path.normpath(
                            os.path.join(config.uproject_dir_path,
                                         config.engine_path_name))

                if not os.path.exists(engine_path):
                    try:
                        os.makedirs(engine_path)
                    except Exception:
                        error_exit(
                            'Unable to create engine directory! Tried @ {}'.
                            format(engine_path), not config.automated)
                config.setup_engine_paths(engine_path)
        else:
            error_exit(
                'No engine available for automated case! Either fill out git info or supply engine directory',
                not config.automated)
    elif config.UE4EnginePath != engine_override and engine_override != '':
        error_exit(
            'Specific engine path requested, but engine path for this project already exists?',
            not config.automated)

    # Before doing anything, make sure we have all build dependencies ready
    if can_pull_engine:
        git_action = Git(config)
        git_action.branch_name = config.git_proj_branch
        git_action.repo_name = config.git_repo
        git_action.output_folder = config.UE4EnginePath
        git_action.disable_strict_hostkey_check = True
        git_action.force_repull = False
        if not git_action.run():
            error_exit(git_action.error, not config.automated)

    if not config.setup_engine_paths(engine_override):
        error_exit('Could not setup valid engine paths!', not config.automated)

    # Register the engine (might do nothing if already registered)
    # If no key name, this is an un-keyed static engine.
    if config.UE4EngineKeyName != '' and not config.automated:
        register_project_engine(config, False)

    if not config.editor_running:
        print_action('Checking engine dependencies up-to-date')

        def add_dep_exclude(path_name, args):
            args.append('-exclude={}'.format(path_name))

        cmd_args = []
        if config.exclude_samples:
            for sample_pack in ['FeaturePacks', 'Samples']:
                add_dep_exclude(sample_pack, cmd_args)
        for extra_exclude in config.extra_dependency_excludes:
            add_dep_exclude(extra_exclude, cmd_args)

        if launch(config.UE4GitDependenciesPath, cmd_args) != 0:
            error_exit('Engine dependencies Failed to Sync!',
                       not config.automated)

        if not os.path.isfile(config.UE4UBTPath):
            # The unreal build tool does not exist, we need to build it first
            # We use the generate project files batch script because it ensures the build tool exists,
            # and builds it if not.
            print_action(
                "Build tool doesn't exist yet, generating project and building..."
            )
            if launch(config.UE4GenProjFilesPath, ['-2017']
                      if get_visual_studio_version() == 2017 else []) != 0:
                error_exit('Failed to build UnrealBuildTool.exe!',
                           not config.automated)