Beispiel #1
0
    def create(final):
        logging.info('building port: harfbuzz')
        ports.clear_project_build('harfbuzz')

        source_path = os.path.join(ports.get_dir(), 'harfbuzz',
                                   'harfbuzz-' + TAG)
        build_path = os.path.join(ports.get_build_dir(), 'harfbuzz')

        freetype_lib = shared.Cache.get_path(
            shared.Cache.get_lib_name('libfreetype.a'))
        freetype_include = os.path.join(ports.get_include_dir(), 'freetype2',
                                        'freetype')
        freetype_include_dirs = freetype_include + ';' + os.path.join(
            freetype_include, 'config')

        cmake_cmd = [
            shared.EMCMAKE, 'cmake', '-B' + build_path, '-H' + source_path,
            '-DCMAKE_BUILD_TYPE=Release',
            '-DCMAKE_INSTALL_PREFIX=' + build_path,
            '-DFREETYPE_INCLUDE_DIRS=' + freetype_include_dirs,
            '-DFREETYPE_LIBRARY=' + freetype_lib, '-DHB_HAVE_FREETYPE=ON'
        ]

        extra_cflags = []

        if settings.RELOCATABLE:
            extra_cflags.append('-fPIC')

        if settings.USE_PTHREADS:
            extra_cflags.append('-pthread')

        if len(extra_cflags):
            cmake_cmd += [
                '-DCMAKE_CXX_FLAGS="{}"'.format(' '.join(extra_cflags))
            ]
            cmake_cmd += [
                '-DCMAKE_C_FLAGS="{}"'.format(' '.join(extra_cflags))
            ]

        shared.run_process(cmake_cmd, env=system_libs.clean_env())
        shared.run_process(
            ['cmake', '--build', build_path, '--target', 'install'])

        ports.install_header_dir(
            os.path.join(build_path, 'include', 'harfbuzz'))

        shutil.copyfile(os.path.join(build_path, 'libharfbuzz.a'), final)
Beispiel #2
0
def inspect_headers(headers, cflags):
    code = ['#include <stdio.h>', '#include <stddef.h>']
    for header in headers:
        code.append('#include "' + header['name'] + '"')

    code.append('int main() {')
    c_descent('structs', code)
    for header in headers:
        for name, struct in header['structs'].items():
            gen_inspect_code([name], struct, code)

    c_ascent(code)
    c_descent('defines', code)
    for header in headers:
        for name, type_ in header['defines'].items():
            # Add the necessary python type, if missing.
            if '%' not in type_:
                if type_[-1] in ('d', 'i', 'u'):
                    # integer
                    type_ = 'i%' + type_
                elif type_[-1] in ('f', 'F', 'e', 'E', 'g', 'G'):
                    # float
                    type_ = 'f%' + type_
                elif type_[-1] in ('x', 'X', 'a', 'A', 'c', 's'):
                    # hexadecimal or string
                    type_ = 's%' + type_

            c_set(name, type_, name, code)

    code.append('return 0;')
    code.append('}')

    # Write the source code to a temporary file.
    src_file = tempfile.mkstemp('.c', text=True)
    show('Generating C code... ' + src_file[1])
    os.write(src_file[0], '\n'.join(code).encode())

    js_file = tempfile.mkstemp('.js')

    # Check sanity early on before populating the cache with libcompiler_rt
    # If we don't do this the parallel build of compiler_rt will run while holding the cache
    # lock and with EM_EXCLUSIVE_CACHE_ACCESS set causing N processes to race to run sanity checks.
    # While this is not in itself serious problem it is wasteful and noise on stdout.
    # For the same reason we run this early in embuilder.py and emcc.py.
    # TODO(sbc): If we can remove EM_EXCLUSIVE_CACHE_ACCESS then this would not longer be needed.
    shared.check_sanity()

    compiler_rt = system_libs.Library.get_usable_variations(
    )['libcompiler_rt'].get_path()

    # Close all unneeded FDs.
    os.close(src_file[0])
    os.close(js_file[0])

    info = []
    # Compile the program.
    show('Compiling generated code...')

    if any('libcxxabi' in f for f in cflags):
        compiler = shared.EMXX
    else:
        compiler = shared.EMCC

    # -Oz optimizes enough to avoid warnings on code size/num locals
    cmd = [compiler] + cflags + [
        '-o',
        js_file[1],
        src_file[1],
        '-O0',
        '-Werror',
        '-Wno-format',
        '-nostdlib',
        compiler_rt,
        '-sMEMORY64=' + str(settings.MEMORY64),
        '-sBOOTSTRAPPING_STRUCT_INFO=1',
        '-sLLD_REPORT_UNDEFINED=1',
        '-sSTRICT',
        # Use SINGLE_FILE=1 so there is only a single
        # file to cleanup.
        '-sSINGLE_FILE'
    ]

    # Default behavior for emcc is to warn for binaryen version check mismatches
    # so we should try to match that behavior.
    cmd += ['-Wno-error=version-check']

    # TODO(sbc): Remove this one we remove the test_em_config_env_var test
    cmd += ['-Wno-deprecated']

    if settings.LTO:
        cmd += ['-flto=' + settings.LTO]

    show(shared.shlex_join(cmd))
    try:
        subprocess.check_call(cmd, env=system_libs.clean_env())
    except subprocess.CalledProcessError as e:
        sys.stderr.write('FAIL: Compilation failed!: %s\n' % e.cmd)
        sys.exit(1)

    # Run the compiled program.
    show('Calling generated program... ' + js_file[1])
    args = []
    if settings.MEMORY64:
        args += ['--experimental-wasm-bigint']
    info = shared.run_js_tool(js_file[1], node_args=args,
                              stdout=shared.PIPE).splitlines()

    if not DEBUG:
        # Remove all temporary files.
        os.unlink(src_file[1])

        if os.path.exists(js_file[1]):
            os.unlink(js_file[1])

    # Parse the output of the program into a dict.
    return parse_c_output(info)