Ejemplo n.º 1
0
def get_compiler_version(env):
    # Not using this method on clang because it returns 4.2.1 # https://reviews.llvm.org/D56803
    if using_gcc(env):
        version = decode_utf8(subprocess.check_output([env['CXX'], '-dumpversion']).strip())
    else:
        version = decode_utf8(subprocess.check_output([env['CXX'], '--version']).strip())
    match = re.search('[0-9][0-9.]*', version)
    if match is not None:
        return match.group().split('.')
    else:
        return None
Ejemplo n.º 2
0
def get_compiler_version(env):
    if using_gcc(env):
        version = decode_utf8(subprocess.check_output([env['CXX'], '-dumpversion']).strip())
    elif using_clang(env):
        # Not using -dumpversion as it used to return 4.2.1: https://reviews.llvm.org/D56803
        version = decode_utf8(subprocess.check_output([env['CXX'], '--version']).strip())
    else:  # TODO: Implement for MSVC
        return None
    match = re.search('[0-9][0-9.]*', version)
    if match is not None:
        return match.group().split('.')
    else:
        return None
Ejemplo n.º 3
0
def get_compiler_version(env):
    """
    Returns an array of version numbers as ints: [major, minor, patch].
    The return array should have at least two values (major, minor).
    """
    if not env.msvc:
        # Not using -dumpversion as some GCC distros only return major, and
        # Clang used to return hardcoded 4.2.1: # https://reviews.llvm.org/D56803
        try:
            version = decode_utf8(
                subprocess.check_output([env.subst(env["CXX"]),
                                         "--version"]).strip())
        except (subprocess.CalledProcessError, OSError):
            print(
                "Couldn't parse CXX environment variable to infer compiler version."
            )
            return None
    else:  # TODO: Implement for MSVC
        return None
    # First try with x.y.z
    match = re.search("[0-9]+\.[0-9.]+\.[0-9.]+", version)
    # If not found try with last x.y (and skip eg. 2014.3 signatures)
    if match is None:
        match = re.search("[0-9]+\.[0-9.]+$", version)
    if match is not None:
        return list(map(int, match.group().split(".")))
    else:
        return None
Ejemplo n.º 4
0
def get_compiler_version(env):
    version = decode_utf8(subprocess.check_output([env['CXX'], '--version']).strip())
    match = re.search('[0-9][0-9.]*', version)
    if match is not None:
        return match.group().split('.')
    else:
        return None
Ejemplo n.º 5
0
def detect_darwin_sdk_path(platform, env):
    sdk_name = ""
    if platform == "osx":
        sdk_name = "macosx"
        var_name = "MACOS_SDK_PATH"
    elif platform == "iphone":
        sdk_name = "iphoneos"
        var_name = "IPHONESDK"
    elif platform == "iphonesimulator":
        sdk_name = "iphonesimulator"
        var_name = "IPHONESDK"
    else:
        raise Exception(
            "Invalid platform argument passed to detect_darwin_sdk_path")

    if not env[var_name]:
        try:
            sdk_path = decode_utf8(
                subprocess.check_output(
                    ["xcrun", "--sdk", sdk_name, "--show-sdk-path"]).strip())
            if sdk_path:
                env[var_name] = sdk_path
        except (subprocess.CalledProcessError, OSError):
            print(
                "Failed to find SDK path while running xcrun --sdk {} --show-sdk-path."
                .format(sdk_name))
            raise
Ejemplo n.º 6
0
def get_compiler_version(env):
    version = decode_utf8(subprocess.check_output([env['CXX'], '--version']).strip())
    match = re.search('[0-9][0-9.]*', version)
    if match is not None:
        return match.group().split('.')
    else:
        return None
Ejemplo n.º 7
0
def detect_darwin_sdk_path(platform, env):
    sdk_name = ''
    if platform == 'osx':
        sdk_name = 'macosx'
        var_name = 'MACOS_SDK_PATH'
    elif platform == 'iphone':
        sdk_name = 'iphoneos'
        var_name = 'IPHONESDK'
    elif platform == 'iphonesimulator':
        sdk_name = 'iphonesimulator'
        var_name = 'IPHONESDK'
    else:
        raise Exception(
            "Invalid platform argument passed to detect_darwin_sdk_path")

    if not env[var_name]:
        try:
            sdk_path = decode_utf8(
                subprocess.check_output(
                    ['xcrun', '--sdk', sdk_name, '--show-sdk-path']).strip())
            if sdk_path:
                env[var_name] = sdk_path
        except (subprocess.CalledProcessError, OSError):
            print(
                "Failed to find SDK path while running xcrun --sdk {} --show-sdk-path."
                .format(sdk_name))
            raise
Ejemplo n.º 8
0
def mono_root_try_find_mono_version(mono_root):
    from compat import decode_utf8

    output = subprocess.check_output([os.path.join(mono_root, 'bin', 'mono'), '--version'])
    first_line = decode_utf8(output.splitlines()[0])
    try:
        return LooseVersion(first_line.split()[len('Mono JIT compiler version'.split())])
    except (ValueError, IndexError):
        return None
Ejemplo n.º 9
0
def mono_root_try_find_mono_version(mono_root):
    from compat import decode_utf8

    output = subprocess.check_output(
        [os.path.join(mono_root, 'bin', 'mono'), '--version'])
    first_line = decode_utf8(output.splitlines()[0])
    try:
        return LooseVersion(first_line.split()[len(
            'Mono JIT compiler version'.split())])
    except (ValueError, IndexError):
        return None
Ejemplo n.º 10
0
def find_msbuild_tools_path_reg():
    import subprocess

    vswhere = os.getenv('PROGRAMFILES(X86)')
    if not vswhere:
        vswhere = os.getenv('PROGRAMFILES')
    vswhere += r'\Microsoft Visual Studio\Installer\vswhere.exe'

    vswhere_args = [
        '-latest', '-products', '*', '-requires', 'Microsoft.Component.MSBuild'
    ]

    try:
        lines = subprocess.check_output([vswhere] + vswhere_args).splitlines()

        for line in lines:
            parts = decode_utf8(line).split(':', 1)

            if len(parts) < 2 or parts[0] != 'installationPath':
                continue

            val = parts[1].strip()

            if not val:
                raise ValueError('Value of `installationPath` entry is empty')

            # Since VS2019, the directory is simply named "Current"
            msbuild_dir = os.path.join(val, 'MSBuild\\Current\\Bin')
            if os.path.isdir(msbuild_dir):
                return msbuild_dir

            # Directory name "15.0" is used in VS 2017
            return os.path.join(val, 'MSBuild\\15.0\\Bin')

        raise ValueError('Cannot find `installationPath` entry')
    except ValueError as e:
        print('Error reading output from vswhere: ' + e.message)
    except WindowsError:
        pass  # Fine, vswhere not found
    except (subprocess.CalledProcessError, OSError):
        pass

    # Try to find 14.0 in the Registry

    try:
        subkey = r'SOFTWARE\Microsoft\MSBuild\ToolsVersions\14.0'
        with _reg_open_key(winreg.HKEY_LOCAL_MACHINE, subkey) as hKey:
            value = winreg.QueryValueEx(hKey, 'MSBuildToolsPath')[0]
            return value
    except (WindowsError, OSError):
        return ''

    return ''
Ejemplo n.º 11
0
def pkgconfig_try_find_mono_version():
    from compat import decode_utf8

    lines = subprocess.check_output(['pkg-config', 'monosgen-2', '--modversion']).splitlines()
    greater_version = None
    for line in lines:
        try:
            version = LooseVersion(decode_utf8(line))
            if greater_version is None or version > greater_version:
                greater_version = version
        except ValueError:
            pass
    return greater_version
Ejemplo n.º 12
0
def pkgconfig_try_find_mono_version():
    from compat import decode_utf8

    lines = subprocess.check_output(['pkg-config', 'monosgen-2', '--modversion']).splitlines()
    greater_version = None
    for line in lines:
        try:
            version = LooseVersion(decode_utf8(line))
            if greater_version is None or version > greater_version:
                greater_version = version
        except ValueError:
            pass
    return greater_version
Ejemplo n.º 13
0
def find_msbuild_tools_path_reg():
    import subprocess

    vswhere = os.getenv('PROGRAMFILES(X86)')
    if not vswhere:
        vswhere = os.getenv('PROGRAMFILES')
    vswhere += r'\Microsoft Visual Studio\Installer\vswhere.exe'

    vswhere_args = ['-latest', '-products', '*', '-requires', 'Microsoft.Component.MSBuild']

    try:
        lines = subprocess.check_output([vswhere] + vswhere_args).splitlines()

        for line in lines:
            parts = decode_utf8(line).split(':', 1)

            if len(parts) < 2 or parts[0] != 'installationPath':
                continue

            val = parts[1].strip()

            if not val:
                raise ValueError('Value of `installationPath` entry is empty')

            # Since VS2019, the directory is simply named "Current"
            msbuild_dir = os.path.join(val, 'MSBuild\\Current\\Bin')
            if os.path.isdir(msbuild_dir):
                return msbuild_dir

            # Directory name "15.0" is used in VS 2017
            return os.path.join(val, 'MSBuild\\15.0\\Bin')

        raise ValueError('Cannot find `installationPath` entry')
    except ValueError as e:
        print('Error reading output from vswhere: ' + e.message)
    except WindowsError:
        pass # Fine, vswhere not found
    except (subprocess.CalledProcessError, OSError):
        pass

    # Try to find 14.0 in the Registry

    try:
        subkey = r'SOFTWARE\Microsoft\MSBuild\ToolsVersions\14.0'
        with _reg_open_key(winreg.HKEY_LOCAL_MACHINE, subkey) as hKey:
            value = winreg.QueryValueEx(hKey, 'MSBuildToolsPath')[0]
            return value
    except (WindowsError, OSError):
        return ''

    return ''
Ejemplo n.º 14
0
def find_msbuild_tools_path_reg():
    import subprocess

    vswhere = os.getenv("PROGRAMFILES(X86)")
    if not vswhere:
        vswhere = os.getenv("PROGRAMFILES")
    vswhere += r"\Microsoft Visual Studio\Installer\vswhere.exe"

    vswhere_args = [
        "-latest", "-products", "*", "-requires", "Microsoft.Component.MSBuild"
    ]

    try:
        lines = subprocess.check_output([vswhere] + vswhere_args).splitlines()

        for line in lines:
            parts = decode_utf8(line).split(":", 1)

            if len(parts) < 2 or parts[0] != "installationPath":
                continue

            val = parts[1].strip()

            if not val:
                raise ValueError("Value of `installationPath` entry is empty")

            # Since VS2019, the directory is simply named "Current"
            msbuild_dir = os.path.join(val, "MSBuild\\Current\\Bin")
            if os.path.isdir(msbuild_dir):
                return msbuild_dir

            # Directory name "15.0" is used in VS 2017
            return os.path.join(val, "MSBuild\\15.0\\Bin")

        raise ValueError("Cannot find `installationPath` entry")
    except ValueError as e:
        print("Error reading output from vswhere: " + e.message)
    except subprocess.CalledProcessError as e:
        print(e.output)
    except OSError as e:
        print(e)

    # Try to find 14.0 in the Registry

    try:
        subkey = r"SOFTWARE\Microsoft\MSBuild\ToolsVersions\14.0"
        with _reg_open_key(winreg.HKEY_LOCAL_MACHINE, subkey) as hKey:
            value = winreg.QueryValueEx(hKey, "MSBuildToolsPath")[0]
            return value
    except (WindowsError, OSError):
        return ""
Ejemplo n.º 15
0
def mono_root_try_find_mono_version(mono_root):
    from compat import decode_utf8

    mono_bin = os.path.join(mono_root, 'bin')
    if os.path.isfile(os.path.join(mono_bin, 'mono')):
        mono_binary = os.path.join(mono_bin, 'mono')
    elif os.path.isfile(os.path.join(mono_bin, 'mono.exe')):
        mono_binary = os.path.join(mono_bin, 'mono.exe')
    else:
        return None
    output = subprocess.check_output([mono_binary, '--version'])
    first_line = decode_utf8(output.splitlines()[0])
    try:
        return LooseVersion(first_line.split()[len('Mono JIT compiler version'.split())])
    except (ValueError, IndexError):
        return None
Ejemplo n.º 16
0
def mono_root_try_find_mono_version(mono_root):
    from compat import decode_utf8

    mono_bin = os.path.join(mono_root, 'bin')
    if os.path.isfile(os.path.join(mono_bin, 'mono')):
        mono_binary = os.path.join(mono_bin, 'mono')
    elif os.path.isfile(os.path.join(mono_bin, 'mono.exe')):
        mono_binary = os.path.join(mono_bin, 'mono.exe')
    else:
        return None
    output = subprocess.check_output([mono_binary, '--version'])
    first_line = decode_utf8(output.splitlines()[0])
    try:
        return LooseVersion(first_line.split()[len('Mono JIT compiler version'.split())])
    except (ValueError, IndexError):
        return None
Ejemplo n.º 17
0
def get_compiler_version(env):
    """
    Returns an array of version numbers as ints: [major, minor, patch].
    The return array should have at least two values (major, minor).
    """
    if not env.msvc:
        # Not using -dumpversion as some GCC distros only return major, and
        # Clang used to return hardcoded 4.2.1: # https://reviews.llvm.org/D56803
        version = decode_utf8(
            subprocess.check_output([env['CXX'], '--version']).strip())
    else:  # TODO: Implement for MSVC
        return None
    match = re.search('[0-9]+\.[0-9.]+', version)
    if match is not None:
        return list(map(int, match.group().split('.')))
    else:
        return None
Ejemplo n.º 18
0
def get_compiler_architecture(env):
    """
    Returns compiler (default) architecture.
    """
    if not env.msvc:
        try:
            arch = decode_utf8(
                subprocess.check_output(
                    [env.subst(env["CXX"]), "-dumpmachine"]).strip())
        except (subprocess.CalledProcessError, OSError):
            print(
                "Couldn't parse CXX environment variable to infer compiler architecture."
            )
            return None
    else:  # TODO: Implement for MSVC
        return None
    return next(iter(arch.split("-")), None)
Ejemplo n.º 19
0
def detect_darwin_sdk_path(platform, env):
    sdk_name = ''
    if platform == 'osx':
        sdk_name = 'macosx'
        var_name = 'MACOS_SDK_PATH'
    elif platform == 'iphone':
        sdk_name = 'iphoneos'
        var_name = 'IPHONESDK'
    elif platform == 'iphonesimulator':
        sdk_name = 'iphonesimulator'
        var_name = 'IPHONESDK'
    else:
        raise Exception("Invalid platform argument passed to detect_darwin_sdk_path")

    if not env[var_name]:
        try:
            sdk_path = decode_utf8(subprocess.check_output(['xcrun', '--sdk', sdk_name, '--show-sdk-path']).strip())
            if sdk_path:
                env[var_name] = sdk_path
        except (subprocess.CalledProcessError, OSError) as e:
            print("Failed to find SDK path while running xcrun --sdk {} --show-sdk-path.".format(sdk_name))
            raise
Ejemplo n.º 20
0
def get_darwin_sdk_version(platform):
    sdk_name = ""
    if platform == "osx":
        sdk_name = "macosx"
    elif platform == "iphone":
        sdk_name = "iphoneos"
    elif platform == "iphonesimulator":
        sdk_name = "iphonesimulator"
    else:
        raise Exception(
            "Invalid platform argument passed to get_darwin_sdk_version")

    try:
        return float(
            decode_utf8(
                subprocess.check_output(
                    ["xcrun", "--sdk", sdk_name,
                     "--show-sdk-version"]).strip()))
    except (subprocess.CalledProcessError, OSError):
        print(
            "Failed to find SDK version while running xcrun --sdk {} --show-sdk-version."
            .format(sdk_name))
        return 0.0
Ejemplo n.º 21
0
def configure(env):

    ## Build type

    if (env["target"] == "release"):
        if (env["optimize"] == "speed"):  #optimize for speed (default)
            env.Prepend(CCFLAGS=['-O3'])
        else:  #optimize for size
            env.Prepend(CCFLAGS=['-Os'])

        if (env["debug_symbols"] == "yes"):
            env.Prepend(CCFLAGS=['-g1'])
        if (env["debug_symbols"] == "full"):
            env.Prepend(CCFLAGS=['-g2'])

    elif (env["target"] == "release_debug"):
        if (env["optimize"] == "speed"):  #optimize for speed (default)
            env.Prepend(CCFLAGS=['-O2', '-DDEBUG_ENABLED'])
        else:  #optimize for size
            env.Prepend(CCFLAGS=['-Os', '-DDEBUG_ENABLED'])

        if (env["debug_symbols"] == "yes"):
            env.Prepend(CCFLAGS=['-g1'])
        if (env["debug_symbols"] == "full"):
            env.Prepend(CCFLAGS=['-g2'])

    elif (env["target"] == "debug"):
        env.Prepend(
            CCFLAGS=['-g3', '-DDEBUG_ENABLED', '-DDEBUG_MEMORY_ENABLED'])
        env.Append(LINKFLAGS=['-rdynamic'])

    ## Architecture

    is64 = sys.maxsize > 2**32
    if (env["bits"] == "default"):
        env["bits"] = "64" if is64 else "32"

    ## Compiler configuration

    if 'CXX' in env and 'clang' in os.path.basename(env['CXX']):
        # Convenience check to enforce the use_llvm overrides when CXX is clang(++)
        env['use_llvm'] = True

    if env['use_llvm']:
        if ('clang++' not in os.path.basename(env['CXX'])):
            env["CC"] = "clang"
            env["CXX"] = "clang++"
            env["LINK"] = "clang++"
        env.Append(CPPFLAGS=['-DTYPED_METHOD_BIND'])
        env.extra_suffix = ".llvm" + env.extra_suffix

    # leak sanitizer requires (address) sanitizer
    if env['use_sanitizer'] or env['use_leak_sanitizer']:
        env.Append(CCFLAGS=['-fsanitize=address', '-fno-omit-frame-pointer'])
        env.Append(LINKFLAGS=['-fsanitize=address'])
        env.extra_suffix += "s"
        if env['use_leak_sanitizer']:
            env.Append(CCFLAGS=['-fsanitize=leak'])
            env.Append(LINKFLAGS=['-fsanitize=leak'])

    if env['use_lto']:
        env.Append(CCFLAGS=['-flto'])
        if not env['use_llvm'] and env.GetOption("num_jobs") > 1:
            env.Append(LINKFLAGS=['-flto=' + str(env.GetOption("num_jobs"))])
        else:
            env.Append(LINKFLAGS=['-flto'])
        if not env['use_llvm']:
            env['RANLIB'] = 'gcc-ranlib'
            env['AR'] = 'gcc-ar'

    env.Append(CCFLAGS=['-pipe'])
    env.Append(LINKFLAGS=['-pipe'])

    # Check for gcc version > 5 before adding -no-pie
    import re
    import subprocess
    proc = subprocess.Popen([env['CXX'], '--version'], stdout=subprocess.PIPE)
    (stdout, _) = proc.communicate()
    stdout = decode_utf8(stdout)
    match = re.search('[0-9][0-9.]*', stdout)
    if match is not None:
        version = match.group().split('.')
        if (version[0] > '5'):
            env.Append(CCFLAGS=['-fpie'])
            env.Append(LINKFLAGS=['-no-pie'])

    ## Dependencies

    env.ParseConfig('pkg-config x11 --cflags --libs')
    env.ParseConfig('pkg-config xcursor --cflags --libs')
    env.ParseConfig('pkg-config xinerama --cflags --libs')
    env.ParseConfig('pkg-config xrandr --cflags --libs')
    env.ParseConfig('pkg-config xrender --cflags --libs')
    env.ParseConfig('pkg-config xi --cflags --libs')

    if (env['touch']):
        env.Append(CPPFLAGS=['-DTOUCH_ENABLED'])

    # FIXME: Check for existence of the libs before parsing their flags with pkg-config

    # freetype depends on libpng and zlib, so bundling one of them while keeping others
    # as shared libraries leads to weird issues
    if env['builtin_freetype'] or env['builtin_libpng'] or env['builtin_zlib']:
        env['builtin_freetype'] = True
        env['builtin_libpng'] = True
        env['builtin_zlib'] = True

    if not env['builtin_freetype']:
        env.ParseConfig('pkg-config freetype2 --cflags --libs')

    if not env['builtin_libpng']:
        env.ParseConfig('pkg-config libpng --cflags --libs')

    if not env['builtin_bullet']:
        # We need at least version 2.88
        import subprocess
        bullet_version = subprocess.check_output(
            ['pkg-config', 'bullet', '--modversion']).strip()
        if bullet_version < "2.88":
            # Abort as system bullet was requested but too old
            print(
                "Bullet: System version {0} does not match minimal requirements ({1}). Aborting."
                .format(bullet_version, "2.88"))
            sys.exit(255)
        env.ParseConfig('pkg-config bullet --cflags --libs')

    if not env['builtin_enet']:
        env.ParseConfig('pkg-config libenet --cflags --libs')

    if not env['builtin_squish'] and env['tools']:
        env.ParseConfig('pkg-config libsquish --cflags --libs')

    if not env['builtin_zstd']:
        env.ParseConfig('pkg-config libzstd --cflags --libs')

    # Sound and video libraries
    # Keep the order as it triggers chained dependencies (ogg needed by others, etc.)

    if not env['builtin_libtheora']:
        env['builtin_libogg'] = False  # Needed to link against system libtheora
        env['builtin_libvorbis'] = False  # Needed to link against system libtheora
        env.ParseConfig('pkg-config theora theoradec --cflags --libs')
    else:
        list_of_x86 = ['x86_64', 'x86', 'i386', 'i586']
        if any(platform.machine() in s for s in list_of_x86):
            env["x86_libtheora_opt_gcc"] = True

    if not env['builtin_libvpx']:
        env.ParseConfig('pkg-config vpx --cflags --libs')

    if not env['builtin_libvorbis']:
        env['builtin_libogg'] = False  # Needed to link against system libvorbis
        env.ParseConfig('pkg-config vorbis vorbisfile --cflags --libs')

    if not env['builtin_opus']:
        env['builtin_libogg'] = False  # Needed to link against system opus
        env.ParseConfig('pkg-config opus opusfile --cflags --libs')

    if not env['builtin_libogg']:
        env.ParseConfig('pkg-config ogg --cflags --libs')

    if not env['builtin_libwebp']:
        env.ParseConfig('pkg-config libwebp --cflags --libs')

    if not env['builtin_mbedtls']:
        # mbedTLS does not provide a pkgconfig config yet. See https://github.com/ARMmbed/mbedtls/issues/228
        env.Append(LIBS=['mbedtls', 'mbedcrypto', 'mbedx509'])

    if not env['builtin_libwebsockets']:
        env.ParseConfig('pkg-config libwebsockets --cflags --libs')

    if not env['builtin_miniupnpc']:
        # No pkgconfig file so far, hardcode default paths.
        env.Append(CPPPATH=["/usr/include/miniupnpc"])
        env.Append(LIBS=["miniupnpc"])

    # On Linux wchar_t should be 32-bits
    # 16-bit library shouldn't be required due to compiler optimisations
    if not env['builtin_pcre2']:
        env.ParseConfig('pkg-config libpcre2-32 --cflags --libs')

    ## Flags

    if (os.system("pkg-config --exists alsa") == 0):  # 0 means found
        print("Enabling ALSA")
        env.Append(CPPFLAGS=["-DALSA_ENABLED", "-DALSAMIDI_ENABLED"])
        # Don't parse --cflags, we don't need to add /usr/include/alsa to include path
        env.ParseConfig('pkg-config alsa --libs')
    else:
        print("ALSA libraries not found, disabling driver")

    if env['pulseaudio']:
        if (os.system("pkg-config --exists libpulse") == 0):  # 0 means found
            print("Enabling PulseAudio")
            env.Append(CPPFLAGS=["-DPULSEAUDIO_ENABLED"])
            env.ParseConfig('pkg-config --cflags --libs libpulse')
        else:
            print(
                "PulseAudio development libraries not found, disabling driver")

    if (platform.system() == "Linux"):
        env.Append(CPPFLAGS=["-DJOYDEV_ENABLED"])

        if env['udev']:
            if (os.system("pkg-config --exists libudev") == 0
                ):  # 0 means found
                print("Enabling udev support")
                env.Append(CPPFLAGS=["-DUDEV_ENABLED"])
                env.ParseConfig('pkg-config libudev --cflags --libs')
            else:
                print(
                    "libudev development libraries not found, disabling udev support"
                )

    # Linkflags below this line should typically stay the last ones
    if not env['builtin_zlib']:
        env.ParseConfig('pkg-config zlib --cflags --libs')

    env.Append(CPPPATH=['#platform/x11'])
    env.Append(CPPFLAGS=[
        '-DX11_ENABLED', '-DUNIX_ENABLED', '-DOPENGL_ENABLED', '-DGLES_ENABLED'
    ])
    env.Append(LIBS=['GL', 'pthread'])

    if (platform.system() == "Linux"):
        env.Append(LIBS=['dl'])

    if (platform.system().find("BSD") >= 0):
        env["execinfo"] = True

    if env["execinfo"]:
        env.Append(LIBS=['execinfo'])

    ## Cross-compilation

    if (is64 and env["bits"] == "32"):
        env.Append(CPPFLAGS=['-m32'])
        env.Append(LINKFLAGS=['-m32', '-L/usr/lib/i386-linux-gnu'])
    elif (not is64 and env["bits"] == "64"):
        env.Append(CPPFLAGS=['-m64'])
        env.Append(LINKFLAGS=['-m64', '-L/usr/lib/i686-linux-gnu'])

    # Link those statically for portability
    if env['use_static_cpp']:
        env.Append(LINKFLAGS=['-static-libgcc', '-static-libstdc++'])
Ejemplo n.º 22
0
def is_vanilla_clang(env):
    if not using_clang(env):
        return False
    version = decode_utf8(subprocess.check_output([env['CXX'], '--version']).strip())
    return not version.startswith("Apple")
Ejemplo n.º 23
0
def configure(env):

    ## Build type

    if (env["target"] == "release"):
        # -O3 -ffast-math is identical to -Ofast. We need to split it out so we can selectively disable
        # -ffast-math in code for which it generates wrong results.
        if (env["optimize"] == "speed"): #optimize for speed (default)
            env.Prepend(CCFLAGS=['-O3', '-ffast-math'])
        else: #optimize for size
            env.Prepend(CCFLAGS=['-Os'])

        if (env["debug_symbols"] == "yes"):
            env.Prepend(CCFLAGS=['-g1'])
        if (env["debug_symbols"] == "full"):
            env.Prepend(CCFLAGS=['-g2'])

    elif (env["target"] == "release_debug"):
        if (env["optimize"] == "speed"): #optimize for speed (default)
            env.Prepend(CCFLAGS=['-O2', '-ffast-math', '-DDEBUG_ENABLED'])
        else: #optimize for size
            env.Prepend(CCFLAGS=['-Os', '-DDEBUG_ENABLED'])

        if (env["debug_symbols"] == "yes"):
            env.Prepend(CCFLAGS=['-g1'])
        if (env["debug_symbols"] == "full"):
            env.Prepend(CCFLAGS=['-g2'])

    elif (env["target"] == "debug"):
        env.Prepend(CCFLAGS=['-g3', '-DDEBUG_ENABLED', '-DDEBUG_MEMORY_ENABLED'])
        env.Append(LINKFLAGS=['-rdynamic'])

    ## Architecture

    is64 = sys.maxsize > 2**32
    if (env["bits"] == "default"):
        env["bits"] = "64" if is64 else "32"

    ## Compiler configuration

    if 'CXX' in env and 'clang' in os.path.basename(env['CXX']):
        # Convenience check to enforce the use_llvm overrides when CXX is clang(++)
        env['use_llvm'] = True

    if env['use_llvm']:
        if ('clang++' not in os.path.basename(env['CXX'])):
            env["CC"] = "clang"
            env["CXX"] = "clang++"
            env["LINK"] = "clang++"
        env.Append(CPPFLAGS=['-DTYPED_METHOD_BIND'])
        env.extra_suffix = ".llvm" + env.extra_suffix

    # leak sanitizer requires (address) sanitizer
    if env['use_sanitizer'] or env['use_leak_sanitizer']:
        env.Append(CCFLAGS=['-fsanitize=address', '-fno-omit-frame-pointer'])
        env.Append(LINKFLAGS=['-fsanitize=address'])
        env.extra_suffix += "s"
        if env['use_leak_sanitizer']:
            env.Append(CCFLAGS=['-fsanitize=leak'])
            env.Append(LINKFLAGS=['-fsanitize=leak'])

    if env['use_lto']:
        env.Append(CCFLAGS=['-flto'])
        if not env['use_llvm'] and env.GetOption("num_jobs") > 1:
            env.Append(LINKFLAGS=['-flto=' + str(env.GetOption("num_jobs"))])
        else:
            env.Append(LINKFLAGS=['-flto'])
        if not env['use_llvm']:
            env['RANLIB'] = 'gcc-ranlib'
            env['AR'] = 'gcc-ar'

    env.Append(CCFLAGS=['-pipe'])
    env.Append(LINKFLAGS=['-pipe'])

    # Check for gcc version > 5 before adding -no-pie
    import re
    import subprocess
    proc = subprocess.Popen([env['CXX'], '--version'], stdout=subprocess.PIPE)
    (stdout, _) = proc.communicate()
    stdout = decode_utf8(stdout)
    match = re.search('[0-9][0-9.]*', stdout)
    if match is not None:
        version = match.group().split('.')
        if (version[0] > '5'):
            env.Append(CCFLAGS=['-fpie'])
            env.Append(LINKFLAGS=['-no-pie'])

    ## Dependencies

    env.ParseConfig('pkg-config x11 --cflags --libs')
    env.ParseConfig('pkg-config xcursor --cflags --libs')
    env.ParseConfig('pkg-config xinerama --cflags --libs')
    env.ParseConfig('pkg-config xrandr --cflags --libs')
    env.ParseConfig('pkg-config xrender --cflags --libs')

    if (env['touch']):
        x11_error = os.system("pkg-config xi --modversion > /dev/null ")
        if (x11_error):
            print("xi not found.. cannot build with touch. Aborting.")
            sys.exit(255)
        env.ParseConfig('pkg-config xi --cflags --libs')
        env.Append(CPPFLAGS=['-DTOUCH_ENABLED'])

    # FIXME: Check for existence of the libs before parsing their flags with pkg-config

    # freetype depends on libpng and zlib, so bundling one of them while keeping others
    # as shared libraries leads to weird issues
    if env['builtin_freetype'] or env['builtin_libpng'] or env['builtin_zlib']:
        env['builtin_freetype'] = True
        env['builtin_libpng'] = True
        env['builtin_zlib'] = True

    if not env['builtin_freetype']:
        env.ParseConfig('pkg-config freetype2 --cflags --libs')

    if not env['builtin_libpng']:
        env.ParseConfig('pkg-config libpng --cflags --libs')

    if not env['builtin_bullet']:
        # We need at least version 2.88
        import subprocess
        bullet_version = subprocess.check_output(['pkg-config', 'bullet', '--modversion']).strip()
        if bullet_version < "2.88":
            # Abort as system bullet was requested but too old
            print("Bullet: System version {0} does not match minimal requirements ({1}). Aborting.".format(bullet_version, "2.88"))
            sys.exit(255)
        env.ParseConfig('pkg-config bullet --cflags --libs')

    if not env['builtin_enet']:
        env.ParseConfig('pkg-config libenet --cflags --libs')

    if not env['builtin_squish'] and env['tools']:
        env.ParseConfig('pkg-config libsquish --cflags --libs')

    if not env['builtin_zstd']:
        env.ParseConfig('pkg-config libzstd --cflags --libs')

    # Sound and video libraries
    # Keep the order as it triggers chained dependencies (ogg needed by others, etc.)

    if not env['builtin_libtheora']:
        env['builtin_libogg'] = False  # Needed to link against system libtheora
        env['builtin_libvorbis'] = False  # Needed to link against system libtheora
        env.ParseConfig('pkg-config theora theoradec --cflags --libs')
    else:
        list_of_x86 = ['x86_64', 'x86', 'i386', 'i586']
        if any(platform.machine() in s for s in list_of_x86):
            env["x86_libtheora_opt_gcc"] = True

    if not env['builtin_libvpx']:
        env.ParseConfig('pkg-config vpx --cflags --libs')

    if not env['builtin_libvorbis']:
        env['builtin_libogg'] = False  # Needed to link against system libvorbis
        env.ParseConfig('pkg-config vorbis vorbisfile --cflags --libs')

    if not env['builtin_opus']:
        env['builtin_libogg'] = False  # Needed to link against system opus
        env.ParseConfig('pkg-config opus opusfile --cflags --libs')

    if not env['builtin_libogg']:
        env.ParseConfig('pkg-config ogg --cflags --libs')

    if not env['builtin_libwebp']:
        env.ParseConfig('pkg-config libwebp --cflags --libs')

    if not env['builtin_mbedtls']:
        # mbedTLS does not provide a pkgconfig config yet. See https://github.com/ARMmbed/mbedtls/issues/228
        env.Append(LIBS=['mbedtls', 'mbedcrypto', 'mbedx509'])

    if not env['builtin_libwebsockets']:
        env.ParseConfig('pkg-config libwebsockets --cflags --libs')

    if not env['builtin_miniupnpc']:
        # No pkgconfig file so far, hardcode default paths.
        env.Append(CPPPATH=["/usr/include/miniupnpc"])
        env.Append(LIBS=["miniupnpc"])

    # On Linux wchar_t should be 32-bits
    # 16-bit library shouldn't be required due to compiler optimisations
    if not env['builtin_pcre2']:
        env.ParseConfig('pkg-config libpcre2-32 --cflags --libs')

    ## Flags

    if (os.system("pkg-config --exists alsa") == 0): # 0 means found
        print("Enabling ALSA")
        env.Append(CPPFLAGS=["-DALSA_ENABLED", "-DALSAMIDI_ENABLED"])
	# Don't parse --cflags, we don't need to add /usr/include/alsa to include path
        env.ParseConfig('pkg-config alsa --libs')
    else:
        print("ALSA libraries not found, disabling driver")

    if env['pulseaudio']:
        if (os.system("pkg-config --exists libpulse") == 0): # 0 means found
            print("Enabling PulseAudio")
            env.Append(CPPFLAGS=["-DPULSEAUDIO_ENABLED"])
            env.ParseConfig('pkg-config --cflags --libs libpulse')
        else:
            print("PulseAudio development libraries not found, disabling driver")

    if (platform.system() == "Linux"):
        env.Append(CPPFLAGS=["-DJOYDEV_ENABLED"])

        if env['udev']:
            if (os.system("pkg-config --exists libudev") == 0): # 0 means found
                print("Enabling udev support")
                env.Append(CPPFLAGS=["-DUDEV_ENABLED"])
                env.ParseConfig('pkg-config libudev --cflags --libs')
            else:
                print("libudev development libraries not found, disabling udev support")

    # Linkflags below this line should typically stay the last ones
    if not env['builtin_zlib']:
        env.ParseConfig('pkg-config zlib --cflags --libs')

    env.Append(CPPPATH=['#platform/x11'])
    env.Append(CPPFLAGS=['-DX11_ENABLED', '-DUNIX_ENABLED', '-DOPENGL_ENABLED', '-DGLES_ENABLED'])
    env.Append(LIBS=['GL', 'pthread'])

    if (platform.system() == "Linux"):
        env.Append(LIBS=['dl'])

    if (platform.system().find("BSD") >= 0):
        env["execinfo"] = True

    if env["execinfo"]:
        env.Append(LIBS=['execinfo'])

    ## Cross-compilation

    if (is64 and env["bits"] == "32"):
        env.Append(CPPFLAGS=['-m32'])
        env.Append(LINKFLAGS=['-m32', '-L/usr/lib/i386-linux-gnu'])
    elif (not is64 and env["bits"] == "64"):
        env.Append(CPPFLAGS=['-m64'])
        env.Append(LINKFLAGS=['-m64', '-L/usr/lib/i686-linux-gnu'])

    # Link those statically for portability
    if env['use_static_cpp']:
        env.Append(LINKFLAGS=['-static-libgcc', '-static-libstdc++'])