예제 #1
0
def set_rc_flags(self, kw, ctx):

    rc_defines = [
        'RESOURCE_COMPILER', 'FORCE_STANDARD_ASSERT',
        '_CRT_SECURE_NO_DEPRECATE=1', '_CRT_NONSTDC_NO_DEPRECATE=1'
    ]

    append_unique_kw_entry(kw, 'defines', rc_defines)
    append_unique_kw_entry(kw, 'win_defines', 'WIN32')
def set_rc_flags(self, kw, ctx):

    prepend_kw_entry(kw,'includes',['.',
                                    self.CreateRootRelativePath('Code/CryEngine/CryCommon'),
                                    self.CreateRootRelativePath('Code/Sandbox/Plugins/EditorCommon')])
    rc_defines = ['RESOURCE_COMPILER',
                  'FORCE_STANDARD_ASSERT',
                  '_CRT_SECURE_NO_DEPRECATE=1',
                  '_CRT_NONSTDC_NO_DEPRECATE=1']

    append_unique_kw_entry(kw, 'defines', rc_defines)
    append_unique_kw_entry(kw, 'win_defines', 'WIN32')
예제 #3
0
def apply_gem_to_kw(ctx, kw, gem):
    """
    Apply a gem to the kw
    """
    gem_include_path = gem.get_include_path()
    if os.path.exists(gem_include_path):
        append_unique_kw_entry(kw, 'includes', gem_include_path)

    for module in gem.modules:
        if module.requires_linking(ctx):
            append_unique_kw_entry(kw, 'use', module.target_name)

    if (gem.export_uselibs
            or ctx.is_monolithic_build()) and len(gem.local_uselibs) > 0:
        configuration = ctx.env['CONFIGURATION']
        if not (gem.local_uselib_non_release and configuration.lower() in [
                "release", "release_dedicated", "performance",
                "performance_dedicated"
        ]):
            append_unique_kw_entry(kw, 'uselib', gem.local_uselibs)
예제 #4
0
def apply_gems_to_kw(ctx, kw, gems, game_name):
    """
    Apply gems to the kw
    """
    for gem in gems:
        gem_include_path = gem.get_include_path()
        if os.path.exists(gem_include_path):
            append_unique_kw_entry(kw, 'includes', gem_include_path)

        if (gem.export_uselibs
                or ctx.is_monolithic_build()) and len(gem.local_uselibs) > 0:
            configuration = ctx.env['CONFIGURATION']
            if not (gem.local_uselib_non_release and configuration.lower() in [
                    "release", "release_dedicated", "performance",
                    "performance_dedicated"
            ]):
                append_unique_kw_entry(kw, 'uselib', gem.local_uselibs)

    append_unique_kw_entry(kw, 'use',
                           _get_linked_module_targets(gems, game_name, ctx))
예제 #5
0
def DefineGem(ctx, *k, **kw):
    """
    Gems behave very similarly to engine modules, but with a few extra options
    """
    manager = GemManager.GetInstance(ctx)

    gem = manager.get_gem_by_path(ctx.path.parent.abspath())
    if not gem:
        ctx.cry_error(
            "DefineGem must be called by a wscript file in a Gem's 'Code' folder. Called from: {}"
            .format(ctx.path.abspath()))

    manager.current_gem = gem

    # Generate list of resolved dependencies
    dependency_objects = []
    for dep_id in gem.dependencies:
        dep = manager.get_gem_by_spec(dep_id)
        if not dep:
            unmet_name = find_gem_name_by_id(ctx, dep_id)
            if unmet_name is None:
                ctx.cry_error(
                    'Gem {}({}) has an unmet dependency with ID {} (Unable to locate in disk).'
                    .format(gem.id, gem.name, dep_id))
            else:
                ctx.cry_error(
                    'Gem {}({}) has an unmet dependency with ID {}({}). Please use the Project Configurator to correct this.'
                    .format(gem.id, gem.name, dep_id, unmet_name))

            continue
        dependency_objects.append(dep)

    # Applies dependencies to args list
    def apply_dependencies(args):
        for dep in dependency_objects:
            dep_include = dep.get_include_path()
            if os.path.exists(dep_include):
                append_to_unique_list(args['includes'], dep_include)
            for module in dep.modules:
                if module.requires_linking(ctx):
                    append_to_unique_list(args['use'], module.target_name)

    # Iterate over each module and setup build
    for module in gem.modules:
        if module.name:
            module_kw = kw.get(module.name, None)

            # If no based on name, try lowercasing
            if module_kw == None:
                module_kw = kw.get(module.name.lower(), None)

            # If still no kw, error
            if module_kw == None:
                ctx.cry_error(
                    "Gem {0}'s wscript missing definition for module {1} (valid dict names are {1} and {2}."
                    .format(gem.name, module.name, module.name.lower()))
        else:
            module_kw = kw

        module_file_list_base = module.target_name.replace('.', '_').lower()

        # Set default properties
        default_settings = {
            'target': module.target_name,
            'output_file_name': module.file_name,
            'vs_filter': gem.name if gem.is_game_gem else 'Gems',
            'file_list': ["{}.waf_files".format(module_file_list_base)],
            'platforms': ['all'],
            'configurations': ['all'],
            'defines': [],
            'includes': [],
            'export_includes': [],
            'lib': [],
            'libpath': [],
            'features': [],
            'use': [],
            'uselib': []
        }

        # Builders have some special settings
        if module.type in [
                Gem.Module.Type.Builder, Gem.Module.Type.EditorModule
        ]:
            default_settings['platforms'] = ['win', 'darwin']
            default_settings['configurations'] = [
                'debug', 'debug_test', 'profile', 'profile_test'
            ]

        if module.parent:
            parent_module = None
            for parent_module_itr in gem.modules:
                if (parent_module_itr.name == module.parent or
                    (module.parent == 'GameModule'
                     and parent_module_itr.type == Gem.Module.Type.GameModule
                     and parent_module_itr.name == None)):
                    parent_module = parent_module_itr
                    break
            if not parent_module:
                ctx.cry_error(
                    '{}\'s Gem.json Module "{}" "Extends" non-existent module {}.'
                    .format(gem.name, module.name, module.parent))

            parent_kw = getattr(parent_module, 'kw', None)
            if not parent_kw:
                ctx.cry_error(
                    '{}\'s wscript defines module {} before parent {}, please reverse the order.'
                    .format(gem.name, module.name, module.parent))

            EXTENDABLE_FIELDS = [
                'file_list', 'defines', 'includes', 'features', 'lib',
                'libpath', 'use', 'uselib'
            ]

            INHERITABLE_FIELDS = [
                'pch',
            ]

            for field in EXTENDABLE_FIELDS:
                default_settings[field].extend(parent_kw.get(field, []))

            for field in INHERITABLE_FIELDS:
                parent_value = parent_kw.get(field, None)
                if parent_value:
                    default_settings[field] = parent_value

        # Apply defaults to the project
        for key, value in default_settings.iteritems():
            if key not in module_kw:
                module_kw[key] = value

    # Make it so gems can be replaced while executable is still running
        append_to_unique_list(module_kw['features'], ['link_running_program'])

        # Add tools stuff to the editor modules
        if module.type == Gem.Module.Type.EditorModule:
            append_unique_kw_entry(module_kw, 'features', ['qt5'])
            append_unique_kw_entry(module_kw, 'use',
                                   ['AzToolsFramework', 'AzQtComponents'])
            append_unique_kw_entry(
                module_kw, 'uselib',
                ['QT5CORE', 'QT5QUICK', 'QT5GUI', 'QT5WIDGETS'])

        # If the Gem is a game gem, we may need to apply enabled gems for all of the enabled game projects so it will build
        if gem.is_game_gem and module.type != Gem.Module.Type.Builder:

            # We need to let cryengine_modules.RunTaskGenerator know that this is a game gem and must be built always
            setattr(ctx, 'is_game_gem', True)

            # The gem only builds once, so we need apply the union of all non-game-gem gems enabled for all enabled game projects
            unique_gems = []
            enabled_projects = ctx.get_enabled_game_project_list()
            for enabled_project in enabled_projects:
                gems_for_project = ctx.get_game_gems(enabled_project)
                for gem_for_project in gems_for_project:
                    if gem_for_project.name != gem.name and not gem_for_project.is_game_gem:
                        append_to_unique_list(unique_gems, gem_for_project)

            is_android = ctx.is_android_platform(ctx.env['PLATFORM'])

            for unique_gem in unique_gems:
                if unique_gem.id in gem.dependencies or unique_gem.is_required or is_android:
                    apply_gem_to_kw(ctx, kw, unique_gem)

        working_path = ctx.path.abspath()
        dir_contents = os.listdir(working_path)

        # Setup PCH if disable_pch is false (default), and pch is not set (default)
        if not module_kw.get('disable_pch', False) and module_kw.get(
                'pch', None) == None:

            # default casing for the relative path to the pch file
            source_dir = 'Source'
            pch_file = 'StdAfx.cpp'

            for entry in dir_contents:
                if entry.lower() == 'source':
                    source_dir = entry
                    break

            source_contents = os.listdir(os.path.join(working_path,
                                                      source_dir))
            # see if they have a legacy stdafx precompiled header
            for entry in source_contents:
                if entry.lower() == 'stdafx.cpp':
                    pch_file = entry
                    break
            # if they have a precompiled file then we will prefer that
            for entry in source_contents:
                if entry.lower().endswith('precompiled.cpp'):
                    pch_file = entry
                    break

            # has to be forward slash because the pch is string compared with files
            # in the waf_files which use forward slashes
            module_kw['pch'] = "{}/{}".format(source_dir, pch_file)

        # Apply any additional 3rd party uselibs
        if len(gem.local_uselibs) > 0:
            append_unique_kw_entry(module_kw, 'uselib', gem.local_uselibs)

        # Link the auto-registration symbols so that Flow Node registration will work
        if module.type in [
                Gem.Module.Type.GameModule, Gem.Module.Type.EditorModule
        ]:
            append_unique_kw_entry(module_kw, 'use',
                                   ['CryAction_AutoFlowNode', 'AzFramework'])

        append_unique_kw_entry(module_kw, 'features', ['link_running_program'])

        # If disable_tests=False or disable_tests isn't specified, enable Google test
        disable_test_settings = ctx.GetPlatformSpecificSettings(
            module_kw, 'disable_tests', ctx.env['PLATFORM'],
            ctx.env['CONFIGURATION'])
        disable_tests = module_kw.get('disable_tests',
                                      False) or any(disable_test_settings)
        # Disable tests when doing monolithic build, except when doing project generation (which is always monolithic)
        disable_tests = disable_tests or (
            ctx.env['PLATFORM'] != 'project_generator'
            and ctx.spec_monolithic_build())
        # Disable tests on non-test configurations, except when doing project generation
        disable_tests = disable_tests or (
            ctx.env['PLATFORM'] != 'project_generator'
            and 'test' not in ctx.env['CONFIGURATION'])
        if not disable_tests:
            append_unique_kw_entry(module_kw, 'use', 'AzTest')
            test_waf_files = "{}_tests.waf_files".format(module_file_list_base)
            if ctx.path.find_node(test_waf_files):
                append_unique_kw_entry(module_kw, 'file_list', test_waf_files)

        # Setup includes
        include_paths = []

        # Most gems use the upper case directories, however some have lower case source directories.
        # This will add the correct casing of those include directories
        local_includes = [
            entry for entry in dir_contents
            if entry.lower() in ['include', 'source']
        ]

        # Add local includes
        for local_path in local_includes:
            node = ctx.path.find_node(local_path)
            if node:
                include_paths.append(node)

        # if the gem includes aren't already in the list, ensure they are prepended in order
        gem_includes = []
        for include_path in include_paths:
            if not include_path in module_kw['includes']:
                gem_includes.append(include_path)
        module_kw['includes'] = gem_includes + module_kw['includes']

        # Take the gems include folder if it exists and add it to the export_includes in case the gem is being 'used'
        export_include_node = ctx.path.find_node('Include')
        if export_include_node:
            module_kw['export_includes'] = [export_include_node.abspath()
                                            ] + module_kw['export_includes']

        apply_dependencies(module_kw)

        # Save the build settings so we can access them later
        module.kw = module_kw

        append_unique_kw_entry(module_kw, 'is_gem', True)

        if gem.is_game_gem and ctx.is_monolithic_build(
        ) and ctx.is_android_platform(
                ctx.env['PLATFORM']
        ) and module.type == Gem.Module.Type.GameModule:

            # Special case for android & monolithic builds.  If this is the game gem for the project, it needs to apply the
            # enabled gems here instead of the launcher where its normally applied.  (see cryengine_modules.CryLauncher_Impl
            # for details).  In legacy game projects, this the game dll is declared as a CryEngineModule
            setattr(ctx, 'game_project', gem.name)
            ctx.CryEngineModule(**module_kw)
        else:
            if module.type in [
                    Gem.Module.Type.GameModule, Gem.Module.Type.EditorModule
            ]:
                ctx.CryEngineSharedLibrary(**module_kw)
            elif module.type == Gem.Module.Type.StaticLib:
                ctx.CryEngineStaticLibrary(**module_kw)
            elif module.type == Gem.Module.Type.Builder:
                ctx.BuilderPlugin(**module_kw)

        # INTERNAL USE ONLY
        # Apply export_defines to ENTIRE BUILD. USE LIGHTLY.
        if module.type == Gem.Module.Type.GameModule:
            export_defines = module_kw.get(
                'export_defines', []) + ctx.GetPlatformSpecificSettings(
                    module_kw, 'export_defines', ctx.env['PLATFORM'],
                    ctx.env['CONFIGURATION'])
            append_to_unique_list(ctx.env['DEFINES'], export_defines)

    manager.current_gem = None