def enable_embedded_python(self):

    # Only win_x64 builds support embedding Python.
    #
    # We assume 'project_generator' (the result of doing a lmbr_waf configure) is
    # also for a win_x64 build so that the include directory is configured property
    # for Visual Studio.

    platform = self.env['PLATFORM'].lower()
    config = self.env['CONFIGURATION'].lower()

    if platform in ['win_x64_vs2013', 'win_x64_vs2015', 'win_x64_test', 'linux_x64', 'project_generator']:

        # Set the USE_DEBUG_PYTHON environment variable to the location of 
        # a debug build of python if you want to use one for debug builds.
        #
        # This does NOT work with the boost python helpers, which are used
        # by the Editor, since the boost headers always undef _DEBUG before 
        # including the python headers.
        #
        # Any code that includes python headers directly should also undef 
        # _DEBUG before including those headers except for when USE_DEBUG_PYTHON 
        # is defined.

        if 'debug' in config and 'USE_DEBUG_PYTHON' in os.environ:
            
            python_home = os.environ['USE_DEBUG_PYTHON']
            python_dll = '{}/python27_d.dll'.format(python_home)

            self.env['DEFINES'] += ['USE_DEBUG_PYTHON']

        else:

            python_version = '2.7.12'
            if platform == 'linux_x64':
                python_variant = 'linux_x64'
                python_libs = 'lib'
                python_dll_name = 'lib/libpython2.7.so'
            else:
                python_variant = 'windows'
                python_libs = 'libs'
                python_dll_name = 'python27.dll'
            python_home = os.path.join('Tools', 'Python', python_version, python_variant)
            python_dll = os.path.join(python_home, python_dll_name)

        python_include_dir = os.path.join(python_home, 'include')

        if platform == 'linux_x64':
            python_include_dir = os.path.join(python_include_dir, 'python2.7')

        python_libs_dir = os.path.join(python_home, python_libs)

        self.includes += [self.bld.CreateRootRelativePath(python_include_dir)]
        self.env['LIBPATH'] += [self.bld.CreateRootRelativePath(python_libs_dir)]

        # Save off the python home for use from within code (BoostPythonHelpers.cpp).  This allows us to control exactly which version of
        # python the editor uses.
        # Also, standardize on forward-slash through the entire path.  We specifically don't use backslashes to avoid an interaction with compiler 
        # response-file generation in msvcdeps.py and mscv_helper.py that "fixes up" all the compiler flags, in part by replacing backslashes 
        # with double-backslashes.  If we tried to replace backslashes with double-backslashes here to make it a valid C++ string, it would
        # get double-fixed-up in the case that a response file gets used (long directory path names).  
        # Side note - BoostPythonHelpers.cpp, which uses this define, apparently goes through and replaces forward-slashes with backslashes anyways.
        self.env['DEFINES'] += ['DEFAULT_LY_PYTHONHOME="@root@/{}"'.format(python_home.replace('\\', '/'))] 
        if 'LIBPATH_BOOSTPYTHON' in self.env:
            self.env['LIBPATH'] += self.env['LIBPATH_BOOSTPYTHON']
        elif self.env['PLATFORM'] != 'project_generator':
            Logs.warn('[WARN] Required 3rd party boostpython not detected.  This may cause a link error in project {}.'.format(self.name))

        # Ideally we would load python27.dll from the python home directory. The best way
        # to do that may be to delay load python27.dll and use SetDllDirectory to insert
        # the python home directory into the DLL search path. However that doesn't work 
        # because the boost python helpers import a data symbol.
        self.source_artifacts_include = getattr(self, 'source_artifacts_include', []) + [python_dll]

    if platform in ['darwin_x64']:
        python_version = '2.7.13'
        python_variant = 'mac'
        python_home = 'Tools/Python/{}/{}/Python.framework'.format(python_version, python_variant)

        python_include_dir = '{}/Headers/'.format(python_home)
        python_lib_dir = '{}/Versions/Current/lib'.format(python_home)

        # TODO: figure out what needs to be set for OSX builds.
        self.includes += [self.bld.CreateRootRelativePath(python_include_dir)]
        self.env['LIBPATH'] += [self.bld.CreateRootRelativePath(python_lib_dir)]
def load_win_x64_clang_common_settings(conf):
    """
    Setup all compiler and linker settings shared over all win_x64_win_x64 configurations
    """
    v = conf.env

    if not conf.find_program('clang', mandatory=False, silent_output=True):
        raise Errors.WafError("Unable to detect Clang for windows")

    v['PLATFORM'] = PLATFORM

    # Load MSVC settings for non-build stuff (AzCG, CrcFix, etc)
    # load_win_x64_win_x64_vs2017_common_settings(conf)
    conf.load_windows_common_settings()

    conf.load_win_x64_vs2017_common_settings()

    windows_kit = conf.options.win_vs2017_winkit
    try:
        _, _, _, system_includes, _, _ = conf.detect_msvc(windows_kit, True)
    except:
        Logs.warn(
            'Unable to find Windows Kit {}, removing build target'.format(
                windows_kit))
        conf.disable_target_platform(PLATFORM)
        return

    restricted_tool_list_macro_header = 'AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS='
    restricted_tool_list_macro = restricted_tool_list_macro_header

    # Start with a blank platform slate
    conf.undefine('AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS')

    tool_list_macro_parts = conf.update_host_tool_env_for_restricted_platforms(
        'win_x64_vs2015', v)
    if tool_list_macro_parts:
        restricted_tool_list_macro += ''.join(tool_list_macro_parts)

    if len(restricted_tool_list_macro) > len(
            restricted_tool_list_macro_header):
        v['DEFINES'] += [restricted_tool_list_macro]

    if len(restricted_tool_list_macro) > len(
            restricted_tool_list_macro_header):
        v['DEFINES'] += [restricted_tool_list_macro]

    # Remove MSVC/clang specific settings
    v['CFLAGS'] = []
    v['CXXFLAGS'] = []
    v['LINKFLAGS'] = []

    # Linker
    v['CCLNK_SRC_F'] = v['CXXLNK_SRC_F'] = []
    v['CCLNK_TGT_F'] = v['CXXLNK_TGT_F'] = '/OUT:'

    v['LIB_ST'] = '%s.lib'
    v['LIBPATH_ST'] = '/LIBPATH:%s'
    v['STLIB_ST'] = '%s.lib'
    v['STLIBPATH_ST'] = '/LIBPATH:%s'

    v['cprogram_PATTERN'] = '%s.exe'
    v['cxxprogram_PATTERN'] = '%s.exe'

    v['cstlib_PATTERN'] = '%s.lib'
    v['cxxstlib_PATTERN'] = '%s.lib'

    v['cshlib_PATTERN'] = '%s.dll'
    v['cxxshlib_PATTERN'] = '%s.dll'

    v['LINKFLAGS_cshlib'] = ['/DLL']
    v['LINKFLAGS_cxxshlib'] = ['/DLL']

    # AR Tools
    v['ARFLAGS'] = ['/NOLOGO']
    v['AR_TGT_F'] = '/OUT:'

    # Delete the env variables so that they can be replaced with the clang versions
    del v['AR']
    del v['CC']
    del v['CXX']
    del v['LINK']

    conf.find_program('clang', var='CC', silent_output=True)
    conf.find_program('clang++', var='CXX', silent_output=True)
    conf.find_program('llvm-lib', var='AR', silent_output=True)
    conf.find_program('lld-link', var='LINK', silent_output=True)

    v['LINK_CC'] = v['LINK_CXX'] = v['LINK']

    # Moved to platform.win_x64_clang.json
    """
    clang_FLAGS = [
        '-mcx16',
        '-msse3',
        
        '-Wno-macro-redefined',
        '-Wno-microsoft-cast',
        '-Wno-ignored-pragma-intrinsic',
        # Clang doens't need #pragma intrinsic anyway, so don't whine when one isn't recognized
    ]
    """
    clang_FLAGS = []

    # Path to clang.exe is [clang]/bin/clang.exe, but the include path is [clang]/lib/clang/7.0.0/include
    clang_include_path = os.path.join(
        os.path.dirname(os.path.dirname(v['CXX'])), 'lib', 'clang',
        CLANG_VERSION, 'include')

    system_includes = [clang_include_path] + system_includes

    # Treat all MSVC include paths as system headers
    for include in system_includes:
        clang_FLAGS += ['-isystem', include]

    v['CFLAGS'] += clang_FLAGS
    v['CXXFLAGS'] += clang_FLAGS
    # Moved to platform.win_x64_clang.json
    """
    v['DEFINES'] += [
        '_CRT_SECURE_NO_WARNINGS',
        '_CRT_NONSTDC_NO_WARNINGS',
    ]
    """

    # Moved to platform.win_x64_clang.json
    """
    v['LINKFLAGS'] += [
        '/MACHINE:x64',
        '/MANIFEST',  # Create a manifest file
        '/OPT:REF', '/OPT:ICF',  # Always optimize for size, there's no reason not to
        '/LARGEADDRESSAWARE',  # tell the linker that the application can handle addresses larger than 2 gigabytes.
    ]
    """
    v['WINDOWS_CLANG_SUPPORTED'] = True

    conf.load_clang_common_settings()

    conf.load_cryengine_common_settings()
Example #3
0
def load_win_x64_win_x64_vs2015_common_settings(conf):
    """
    Setup all compiler and linker settings shared over all win_x64_win_x64 configurations
    """
    v = conf.env

    global PLATFORM

    # Add defines to indicate a win64 build
    v['DEFINES'] += ['_WIN32', '_WIN64', 'NOMINMAX']

    restricted_tool_list_macro_header = 'AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS='
    restricted_tool_list_macro = restricted_tool_list_macro_header
    if len(restricted_tool_list_macro) > len(
            restricted_tool_list_macro_header):
        v['DEFINES'] += [restricted_tool_list_macro]

    # Make sure this is a supported platform
    if PLATFORM not in conf.get_supported_platforms():
        return

    # Attempt to detect the C++ compiler for VS 2015 ( msvs version 14.0 )
    windows_kit = conf.options.win_vs2015_winkit
    try:
        conf.auto_detect_msvc_compiler('msvc 14.0', 'x64', windows_kit)
    except:
        Logs.warn(
            'Unable to find Visual Studio 2015 C++ compiler and/or Windows Kit {}, removing build target'
            .format(windows_kit))
        conf.mark_supported_platform_for_removal(PLATFORM)
        return

    # Detect the QT binaries, if the current capabilities selected requires it.
    _, enabled, _, _ = conf.tp.get_third_party_path(PLATFORM, 'qt')
    if enabled:
        conf.find_qt5_binaries(PLATFORM)

    # Introduce the linker to generate 64 bit code
    v['LINKFLAGS'] += ['/MACHINE:X64']
    v['ARFLAGS'] += ['/MACHINE:X64']

    VS2015_FLAGS = [
        '/FS',  # Fix for issue writing to pdb files
        '/Wv:18'  # Stick with 2013 warnings for the time being...
    ]

    v['CFLAGS'] += VS2015_FLAGS
    v['CXXFLAGS'] += VS2015_FLAGS

    if conf.options.use_uber_files:
        v['CFLAGS'] += ['/bigobj']
        v['CXXFLAGS'] += ['/bigobj']

    azcg_dir = conf.Path('Tools/AzCodeGenerator/bin/vc140')
    if not os.path.exists(azcg_dir):
        conf.fatal(
            'Unable to locate the AzCodeGenerator subfolder.  Make sure that you have VS2015 AzCodeGenerator binaries available'
        )
    v['CODE_GENERATOR_PATH'] = [azcg_dir]

    crcfix_dir = conf.Path('Tools/crcfix/bin/vc140')
    if not os.path.exists(crcfix_dir):
        Logs.warn(
            'Unable to locate the crcfix subfolder.  Make sure that you have VS2015 crcfix binaries available'
        )
    v['CRCFIX_PATH'] = [crcfix_dir]

    conf.find_dx12(windows_kit)
Example #4
0
def load_msvc_common_settings(conf):
    """
    Setup all compiler/linker flags with are shared over all targets using the microsoft compiler
    
    !!! But not the actual compiler, since the compiler depends on the target !!!
    """
    v = conf.env

    # MT Tool
    v['MTFLAGS'] = ['/NOLOGO']

    # AR Tools
    v['ARFLAGS'] += ['/NOLOGO']
    v['AR_TGT_F'] = '/OUT:'

    # CC/CXX Compiler
    v['CC_NAME'] = v['CXX_NAME'] = 'msvc'
    v['CC_SRC_F'] = v['CXX_SRC_F'] = []
    v['CC_TGT_F'] = v['CXX_TGT_F'] = ['/c', '/Fo']

    v['CPPPATH_ST'] = '/I%s'
    v['SYSTEM_CPPPATH_ST'] = '/external:I%s'
    v['DEFINES_ST'] = '/D%s'

    v['PCH_FILE_ST'] = '/Fp%s'
    v['PCH_CREATE_ST'] = '/Yc%s'
    v['PCH_USE_ST'] = '/Yu%s'

    v['ARCH_ST'] = ['/arch:']

    # Linker
    v['CCLNK_SRC_F'] = v['CXXLNK_SRC_F'] = []
    v['CCLNK_TGT_F'] = v['CXXLNK_TGT_F'] = '/OUT:'

    v['LIB_ST'] = '%s.lib'
    v['LIBPATH_ST'] = '/LIBPATH:%s'
    v['STLIB_ST'] = '%s.lib'
    v['STLIBPATH_ST'] = '/LIBPATH:%s'

    v['cprogram_PATTERN'] = '%s.exe'
    v['cxxprogram_PATTERN'] = '%s.exe'

    # shared library settings
    v['CFLAGS_cshlib'] = v['CFLAGS_cxxshlib'] = []
    v['CXXFLAGS_cshlib'] = v['CXXFLAGS_cxxshlib'] = []

    v['LINKFLAGS_cshlib'] = ['/DLL']
    v['LINKFLAGS_cxxshlib'] = ['/DLL']

    v['cshlib_PATTERN'] = '%s.dll'
    v['cxxshlib_PATTERN'] = '%s.dll'

    # static library settings
    v['CFLAGS_cstlib'] = v['CFLAGS_cxxstlib'] = []
    v['CXXFLAGS_cstlib'] = v['CXXFLAGS_cxxstlib'] = []

    v['LINKFLAGS_cxxstlib'] = []
    v['LINKFLAGS_cxxshtib'] = []

    v['cstlib_PATTERN'] = '%s.lib'
    v['cxxstlib_PATTERN'] = '%s.lib'

    # Compile options appended if compiler optimization is disabled
    v['COMPILER_FLAGS_DisableOptimization'] = ['/Od']

    # Compile options appended if debug symbols are generated
    # Create a external Program Data Base (PDB) for debugging symbols
    #v['COMPILER_FLAGS_DebugSymbols'] = [ '/Zi' ]
    v['COMPILER_FLAGS_DebugSymbols'] = ['/Z7']

    # Linker flags when building with debug symbols
    v['LINKFLAGS_DebugSymbols'] = ['/DEBUG', '/PDBALTPATH:%_PDB%']

    # Store settings for show includes option
    v['SHOWINCLUDES_cflags'] = ['/showIncludes']
    v['SHOWINCLUDES_cxxflags'] = ['/showIncludes']

    # Store settings for preprocess to file option
    v['PREPROCESS_cflags'] = ['/P', '/C']
    v['PREPROCESS_cxxflags'] = ['/P', '/C']
    v['PREPROCESS_cc_tgt_f'] = ['/c', '/Fi']
    v['PREPROCESS_cxx_tgt_f'] = ['/c', '/Fi']

    # Store settings for preprocess to file option
    v['DISASSEMBLY_cflags'] = ['/FAcs']
    v['DISASSEMBLY_cxxflags'] = ['/FAcs']
    v['DISASSEMBLY_cc_tgt_f'] = ['/c', '/Fa']
    v['DISASSEMBLY_cxx_tgt_f'] = ['/c', '/Fa']

    # ASAN and ASLR
    v['LINKFLAGS_ASLR'] = ['/DYNAMICBASE']
    v['ASAN_cflags'] = ['/GS']
    v['ASAN_cxxflags'] = ['/GS']
    """
    LTCG defaults to 4 threads, and can be set as high as 8.  Any setting over 8 is overridden to 1 by the linker.
    Any setting over the number of available hw threads incurs some thread scheduling overhead in a multiproc system.
    If the hw thread count is > 4, scale the setting up to 8.  This is independent of jobs or link_jobs running, and
    these threads are only active during the LTCG portion of the linker.  The overhead is ~50k/thread, and execution
    time doesn't scale linearly with threads.  Use the undocument linkflag /Time+ for extended information on the amount
    of time the linker spends in link time code generation
    """

    hw_thread_count = Options.options.jobs
    if hw_thread_count > 4:
        v['SET_LTCG_THREADS_FLAG'] = True
        ltcg_thread_count = min(hw_thread_count, 8)
        v['LTCG_THREADS_COUNT'] = str(ltcg_thread_count)
    else:
        v['SET_LTCG_THREADS_FLAG'] = False

    # Bullseye code coverage
    if conf.is_option_true('use_bullseye_coverage'):
        # TODO: Error handling for this is opaque. This will fail the MSVS 2015 tool check,
        # and not say anything about bullseye being missing.
        try:
            path = v['PATH']
            covc = conf.find_program('covc',
                                     var='BULL_COVC',
                                     path_list=path,
                                     silent_output=True)
            covlink = conf.find_program('covlink',
                                        var='BULL_COVLINK',
                                        path_list=path,
                                        silent_output=True)
            covselect = conf.find_program('covselect',
                                          var='BULL_COVSELECT',
                                          path_list=path,
                                          silent_output=True)
            v['BULL_COVC'] = covc
            v['BULL_COVLINK'] = covlink
            v['BULL_COV_FILE'] = conf.CreateRootRelativePath(
                conf.options.bullseye_cov_file)
            # Update the coverage file with the region selections detailed in the settings regions parameters
            # NOTE: should we clear other settings at this point, or allow them to accumulate?
            # Maybe we need a flag for that in the setup?
            regions = conf.options.bullseye_coverage_regions.replace(
                ' ', '').split(',')
            conf.cmd_and_log(
                ([covselect] + ['--file', v['BULL_COV_FILE'], '-a'] + regions))
        except Exception as e:
            Logs.error(
                'Could not find the Bullseye Coverage tools on the path, or coverage tools '
                'are not correctly installed. Coverage build disabled. '
                'Error: {}'.format(e))

    # Adds undocumented time flags for cl.exe and link.exe for measuring compiler frontend, code generation and link time code generation
    # timings
    compile_timing_flags = []

    if conf.is_option_true('report_compile_timing'):
        compile_timing_flags.append('/Bt+')
    if conf.is_option_true('report_cxx_frontend_timing'):
        compile_timing_flags.append('/d1reportTime')
    if conf.is_option_true('output_msvc_code_generation_summary'):
        compile_timing_flags.append('/d2cgsummary')
    v['CFLAGS'] += compile_timing_flags
    v['CXXFLAGS'] += compile_timing_flags

    link_timing_flags = []
    if conf.is_option_true('report_link_timing'):
        link_timing_flags.append('/time+')
    v['LINKFLAGS'] += link_timing_flags
Example #5
0
def enable_embedded_python(self):
    # Only win_x64 builds support embedding Python.
    #
    # We assume 'project_generator' (the result of doing a lmbr_waf configure) is
    # also for a win_x64 build so that the include directory is configured property
    # for Visual Studio.

    platform = self.env['PLATFORM'].lower()
    config = self.env['CONFIGURATION'].lower()

    if platform in [
            'win_x64_vs2013', 'win_x64_vs2015', 'win_x64_vs2017',
            'win_x64_clang', 'win_x64_test', 'linux_x64', 'project_generator'
    ]:

        # Set the USE_DEBUG_PYTHON environment variable to the location of
        # a debug build of python if you want to use one for debug builds.
        #
        # This does NOT work with the boost python helpers, which are used
        # by the Editor, since the boost headers always undef _DEBUG before
        # including the python headers.
        #
        # Any code that includes python headers directly should also undef
        # _DEBUG before including those headers except for when USE_DEBUG_PYTHON
        # is defined.

        if 'debug' in config and 'USE_DEBUG_PYTHON' in os.environ:

            python_home = os.environ['USE_DEBUG_PYTHON']
            python_dll = '{}/python27_d.dll'.format(python_home)

            self.env['DEFINES'] += ['USE_DEBUG_PYTHON']

        else:
            python_home, python_include_dir, python_libs_dir, python_dll = get_python_home_lib_and_dll(
                self.bld, platform)

        self.includes += [python_include_dir]
        self.env['LIBPATH'] += [python_libs_dir]

        # Save off the python home for use from within code (BoostPythonHelpers.cpp).  This allows us to control exactly which version of
        # python the editor uses.
        # Also, standardize on forward-slash through the entire path.  We specifically don't use backslashes to avoid an interaction with compiler
        # response-file generation in msvcdeps.py and mscv_helper.py that "fixes up" all the compiler flags, in part by replacing backslashes
        # with double-backslashes.  If we tried to replace backslashes with double-backslashes here to make it a valid C++ string, it would
        # get double-fixed-up in the case that a response file gets used (long directory path names).
        # Side note - BoostPythonHelpers.cpp, which uses this define, apparently goes through and replaces forward-slashes with backslashes anyways.
        if python_home.startswith(self.bld.engine_path):
            python_home_define = '@root@{}'.format(
                python_home[len(self.bld.engine_path):])
        else:
            python_home_define = python_home

        self.env['DEFINES'] += [
            'DEFAULT_LY_PYTHONHOME="{}"'.format(
                python_home_define.replace('\\', '/'))
        ]
        if 'LIBPATH_BOOSTPYTHON' in self.env:
            self.env['LIBPATH'] += self.env['LIBPATH_BOOSTPYTHON']
        elif self.env['PLATFORM'] != 'project_generator':
            Logs.warn(
                '[WARN] Required 3rd party boostpython not detected.  This may cause a link error in project {}.'
                .format(self.name))

    if platform in ['darwin_x64']:
        _, python_include_dir, python_libs_dir, _ = get_python_home_lib_and_dll(
            self.bld, platform)

        # TODO: figure out what needs to be set for OSX builds.
        self.includes += [python_include_dir]
        self.env['LIBPATH'] += [python_libs_dir]
def load_win_x64_host_settings(conf):
    """
    Setup any environment settings you want to apply globally any time the host doing the building is win x64
    """
    v = conf.env

    # Setup the environment for the AZ Code Generator

    # Look for the most recent version of the code generator subfolder.  This should be either installed or built by the bootstrap process at this point
    global AZCG_VALIDATED_PATH
    if AZCG_VALIDATED_PATH is None:
        az_code_gen_subfolders = ['bin/windows']
        validated_azcg_dir = None
        for az_code_gen_subfolder in az_code_gen_subfolders:
            azcg_dir = conf.Path(
                'Tools/AzCodeGenerator/{}'.format(az_code_gen_subfolder))
            azcg_exe = os.path.join(azcg_dir, AZ_CODE_GEN_EXECUTABLE)
            if os.path.exists(azcg_exe):
                Logs.debug(
                    'lumberyard: Found AzCodeGenerator at {}'.format(azcg_dir))
                validated_azcg_dir = azcg_dir
                break
        AZCG_VALIDATED_PATH = validated_azcg_dir
        if validated_azcg_dir is None:
            conf.fatal(
                'Unable to locate the AzCodeGenerator subfolder.  Make sure that the Windows binaries are available'
            )

    v['CODE_GENERATOR_EXECUTABLE'] = AZ_CODE_GEN_EXECUTABLE
    v['CODE_GENERATOR_PATH'] = [AZCG_VALIDATED_PATH]
    v['CODE_GENERATOR_PYTHON_PATHS'] = [
        conf.Path('Tools/Python/3.7.10/windows/Lib'),
        conf.Path('Tools/Python/3.7.10/windows/libs'),
        conf.Path('Tools/Python/3.7.10/windows/DLLs'),
        conf.ThirdPartyPath('markupsafe', 'x64'),
        conf.ThirdPartyPath('jinja2', 'x64')
    ]
    v['CODE_GENERATOR_PYTHON_DEBUG_PATHS'] = [
        conf.Path('Tools/Python/3.7.10/windows/Lib'),
        conf.Path('Tools/Python/3.7.10/windows/libs'),
        conf.Path('Tools/Python/3.7.10/windows/DLLs'),
        conf.ThirdPartyPath('markupsafe', 'x64'),
        conf.ThirdPartyPath('jinja2', 'x64')
    ]
    v['EMBEDDED_PYTHON_HOME_RELATIVE_PATH'] = 'Tools/Python/3.7.10/windows'
    v['CODE_GENERATOR_PYTHON_HOME'] = conf.Path(
        v['EMBEDDED_PYTHON_HOME_RELATIVE_PATH'])
    v['CODE_GENERATOR_PYTHON_HOME_DEBUG'] = conf.Path(
        'Tools/Python/3.7.10/windows')
    v['CODE_GENERATOR_INCLUDE_PATHS'] = []

    v['EMBEDDED_PYTHON_HOME'] = v['CODE_GENERATOR_PYTHON_HOME']
    v['EMBEDDED_PYTHON_INCLUDE_PATH'] = os.path.join(v['EMBEDDED_PYTHON_HOME'],
                                                     'include')
    v['EMBEDDED_PYTHON_LIBPATH'] = os.path.join(v['EMBEDDED_PYTHON_HOME'],
                                                'libs')
    v['EMBEDDED_PYTHON_SHARED_OBJECT'] = os.path.join(
        v['EMBEDDED_PYTHON_HOME'], 'python37.dll')

    crcfix_dir = conf.Path('Tools/crcfix/bin/windows')
    if not os.path.exists(crcfix_dir):
        Logs.warn(
            'Unable to locate the crcfix subfolder.  Make sure that the Windows crcfix binaries are available'
        )
    v['CRCFIX_PATH'] = [crcfix_dir]
    v['CRCFIX_EXECUTABLE'] = 'crcfix.exe'
Example #7
0
    def __init__(self, local_3rd_party_root, config_file):
        """
        Initialize the sync settings object to a config file.  This will also attempt to connect to the perforce host
        via the settings if any to determine the local workspace root as well.  If all goes well, then the object
        will be marked as valid (see is_valid())
        """
        self.valid = False

        if not os.path.exists(config_file):
            return

        try:
            config_parser = configparser.ConfigParser()
            config_parser.read(config_file)

            self.p4_exe = config_parser.get(P4_SYNC_CONFIG_SECTION,
                                            P4_SYNC_CONFIG_EXECUTABLE)
            self.p4_port = config_parser.get(P4_SYNC_CONFIG_SECTION,
                                             P4_SYNC_CONFIG_HOST_PORT)
            self.p4_workspace = config_parser.get(P4_SYNC_CONFIG_SECTION,
                                                  P4_SYNC_CONFIG_WORKSPACE)
            self.p4_repo = config_parser.get(P4_SYNC_CONFIG_SECTION,
                                             P4_SYNC_CONFIG_REPOSITORY)
        except configparser.Error as err:
            Logs.warn(
                '[WARN] Error reading p4 sync settings file {}.  ({}).  '
                'Missing 3rd party libraries will not be synced from perforce'.
                format(config_file, str(err)))
            return

        try:
            proc = subprocess.Popen([
                self.p4_exe, '-p', self.p4_port, 'client', '-o',
                self.p4_workspace
            ],
                                    stdout=subprocess.PIPE,
                                    stderr=subprocess.PIPE)
            for line in [
                    line_decoded.decode(sys.stdout.encoding or 'iso8859-1',
                                        'replace')
                    for line_decoded in iter(proc.stdout.readline, b'')
            ]:
                if line.startswith("Root:"):
                    self.client_root = line.replace("Root:", "").strip()
                    break
        except OSError as err:
            Logs.warn(
                '[WARN] Invalid values in the p4 sync settings file {}.  ({}).  '
                'Missing 3rd party libraries will not be synced from perforce'.
                format(config_file, str(err)))
            return

        normalized_client_root = os.path.normcase(self.client_root)
        normalized_3rd_party_root = os.path.normcase(local_3rd_party_root)
        if not normalized_3rd_party_root.startswith(normalized_client_root):
            Logs.warn(
                '[WARN] Local 3rd Party root ({}) does not match the root from workspace "{}" ({})'
                'Missing 3rd party libraries will not be synced from perforce'.
                format(local_3rd_party_root, self.p4_workspace,
                       self.client_root))
            return
        self.valid = True
Example #8
0
def load_win_x64_win_x64_vs2017_common_settings(conf):
    """
    Setup all compiler and linker settings shared over all win_x64_win_x64 configurations
    """
    v = conf.env

    global PLATFORM

    # Add defines to indicate a win64 build and configure VS2017 warnings
    v['DEFINES'] += [
        '_WIN32', '_WIN64', 'NOMINMAX',
        '_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING',
        '_ENABLE_EXTENDED_ALIGNED_STORAGE'
    ]

    restricted_tool_list_macro_header = 'AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS='
    restricted_tool_list_macro = restricted_tool_list_macro_header
    if len(restricted_tool_list_macro) > len(
            restricted_tool_list_macro_header):
        v['DEFINES'] += [restricted_tool_list_macro]

    # Make sure this is a supported platform
    if PLATFORM not in conf.get_supported_platforms():
        return

    # Attempt to detect the C++ compiler for VS 2017 ( msvs version 15.0 )
    windows_kit = conf.options.win_vs2017_winkit
    vcvarsall_args = windows_kit + ' ' + conf.options.win_vs2017_vcvarsall_args
    try:
        conf.auto_detect_msvc_compiler('msvc 15', 'x64', vcvarsall_args)
    except:
        Logs.warn(
            'MSVS 2017 will be removed as a build target. We were unable to find an installation of Visual Studio 2017 that matches win_vs2017_vswhere_args=({}), Windows Kit with win_vs2017_winkit=({}), and win_vs2017_vcvarsall_args=({}).'
            .format(conf.options.win_vs2017_vswhere_args, windows_kit,
                    conf.options.win_vs2017_vcvarsall_args))
        Logs.warn(
            'Lumberyard defaults use a known good set of options at the time of product release. If your project requires different configuration for MSVS 2017, you can modify these settings in _WAF_/user_settings.options under [Windows Options].'
        )
        conf.mark_supported_platform_for_removal(PLATFORM)
        return

    # Detect the QT binaries, if the current capabilities selected requires it.
    _, enabled, _, _ = conf.tp.get_third_party_path(PLATFORM, 'qt')
    if enabled:
        conf.find_qt5_binaries(PLATFORM)

    # Introduce the linker to generate 64 bit code
    v['LINKFLAGS'] += ['/MACHINE:X64']
    v['ARFLAGS'] += ['/MACHINE:X64']

    VS2017_FLAGS = [
        '/FS'  # Fix for issue writing to pdb files
    ]

    v['CFLAGS'] += VS2017_FLAGS
    v['CXXFLAGS'] += VS2017_FLAGS

    if conf.options.use_uber_files:
        v['CFLAGS'] += ['/bigobj']
        v['CXXFLAGS'] += ['/bigobj']

    azcg_dir = conf.Path('Tools/AzCodeGenerator/bin/vc141')
    if not os.path.exists(azcg_dir):
        azcg_dir = conf.Path('Tools/AzCodeGenerator/bin/vc140')
        if not os.path.exists(azcg_dir):
            conf.fatal(
                'Unable to locate the AzCodeGenerator subfolder.  Make sure that you have VS2017 AzCodeGenerator binaries available'
            )
    v['CODE_GENERATOR_PATH'] = [azcg_dir]

    crcfix_dir = conf.Path('Tools/crcfix/bin/vc141')
    if not os.path.exists(crcfix_dir):
        crcfix_dir = conf.Path('Tools/crcfix/bin/vc140')
        if not os.path.exists(crcfix_dir):
            Logs.warn(
                'Unable to locate the crcfix subfolder.  Make sure that you have VS2017 crcfix binaries available'
            )
    v['CRCFIX_PATH'] = [crcfix_dir]

    conf.find_dx12(windows_kit)
Example #9
0
def enable_embedded_python(self):
    # Only win_x64 builds support embedding Python.
    #
    # We assume 'project_generator' (the result of doing a lmbr_waf configure) is
    # using the host waf platform build so that the include directory is configured property
    # for that host platform.

    platform = self.env['PLATFORM'].lower()
    config = self.env['CONFIGURATION'].lower()

    if self.bld.is_windows_platform(platform) or self.bld.is_linux_platform(
            platform) or self.bld.is_mac_platform(
                platform) or platform == 'project_generator':

        env = self.bld.env
        # If the platform is project generator, the default environment will not have the EMBEDDED_PYTHON_*
        # env varaiable set. Therefore the first platform environment which contains the host_platform name is used instead
        if platform == 'project_generator':
            host_platform = self.bld.get_waf_host_platform()
            for platform_env in self.bld.all_envs:
                if host_platform in platform_env:
                    env = self.bld.all_envs[platform_env]
                    break

        # Set the USE_DEBUG_PYTHON environment variable to the location of
        # a debug build of python if you want to use one for debug builds.
        #
        # This does NOT work with the boost python helpers, which are used
        # by the Editor, since the boost headers always undef _DEBUG before
        # including the python headers.
        #
        # Any code that includes python headers directly should also undef
        # _DEBUG before including those headers except for when USE_DEBUG_PYTHON
        # is defined.

        if 'debug' in config and 'USE_DEBUG_PYTHON' in os.environ:

            python_home = os.environ['USE_DEBUG_PYTHON']
            python_dll = '{}/python37_d.dll'.format(python_home)

            self.env['DEFINES'] += ['USE_DEBUG_PYTHON']

        else:
            python_home, python_include_dir, python_libs_dir, python_dll, python_home_relative = get_python_home_lib_and_dll(
                self.bld, env)

        self.env['SYSTEM_INCLUDES'] += [python_include_dir]
        self.env['LIBPATH'] += [python_libs_dir]

        # Standardize on forward-slash through the entire path.  We specifically don't use backslashes to avoid an interaction with compiler
        # response-file generation in msvcdeps.py and msvc_helper.py that "fixes up" all the compiler flags, in part by replacing backslashes
        # with double-backslashes.  If we tried to replace backslashes with double-backslashes here to make it a valid C++ string, it would
        # get double-fixed-up in the case that a response file gets used (long directory path names).
        self.env['DEFINES'] += [
            'DEFAULT_LY_PYTHONHOME="{}"'.format(python_home.replace('\\', '/'))
        ]
        self.env['DEFINES'] += [
            'DEFAULT_LY_PYTHONHOME_RELATIVE="{}"'.format(
                python_home_relative.replace('\\', '/'))
        ]

        if 'LIBPATH_BOOSTPYTHON' in self.env:
            self.env['LIBPATH'] += self.env['LIBPATH_BOOSTPYTHON']
        elif 'STLIBPATH_BOOSTPYTHON' in self.env:
            self.env['LIBPATH'] += self.env['STLIBPATH_BOOSTPYTHON']
        elif self.env['PLATFORM'] != 'project_generator':
            Logs.warn(
                '[WARN] Required 3rd party boostpython not detected.  This may cause a link error in project {}.'
                .format(self.name))