Exemplo n.º 1
0
    def build(self):
        source_dir = self.subject.getSourceDir()
        output_dir = self.subject.getOutputDir()
        if not wabt_dir:
            mx.abort(
                "No WABT_DIR specified - the source programs will not be compiled to .wasm."
            )
        wat2wasm_cmd = os.path.join(wabt_dir, "wat2wasm")

        mx.log("Building files from the source dir: " + source_dir)
        for root, filename in self.subject.getProgramSources():
            subdir = os.path.relpath(root, self.subject.getSourceDir())
            mx.ensure_dir_exists(os.path.join(output_dir, subdir))

            basename = remove_extension(filename)
            source_path = os.path.join(root, filename)
            output_wasm_path = os.path.join(output_dir, subdir,
                                            basename + ".wasm")
            output_wat_path = os.path.join(output_dir, subdir,
                                           basename + ".wat")
            timestamped_source = mx.TimeStampFile(source_path)
            timestamped_output = mx.TimeStampFile(output_wasm_path)
            must_rebuild = timestamped_source.isNewerThan(
                timestamped_output) or not timestamped_output.exists()

            if must_rebuild:
                build_cmd_line = [wat2wasm_cmd
                                  ] + [source_path, "-o", output_wasm_path]
                if mx.run(build_cmd_line, nonZeroIsFatal=False) != 0:
                    mx.abort("Could not build the wasm binary of '" +
                             filename + "' with wat2wasm.")
                shutil.copyfile(source_path, output_wat_path)
Exemplo n.º 2
0
 def clean(self, forBuild=False):
     if forBuild:
         output_dir = self.subject.getOutputDir()
         for root, filename in self.subject.getProgramSources():
             output_wasm = mx.TimeStampFile(os.path.join(output_dir, remove_extension(filename) + ".wasm"))
             if mx.TimeStampFile(os.path.join(root, filename)).isNewerThan(output_wasm):
                 mx.logv(str(output_wasm) + " is older than " + os.path.join(root, filename) + ", removing.")
                 os.remove(output_wasm.path)
     else:
         mx.rmtree(self.subject.output_dir(), ignore_errors=True)
Exemplo n.º 3
0
 def _need_configure(self):
     source_dir = self.subject.source_dirs()[0]
     cmake_lists = os.path.join(source_dir, "CMakeLists.txt")
     guard_file = self.guard_file()
     cmake_config = self.subject.cmake_config()
     if not os.path.exists(guard_file):
         return True, "No CMake configuration found - reconfigure"
     if os.path.exists(cmake_lists) and mx.TimeStampFile(cmake_lists).isNewerThan(mx.TimeStampFile(guard_file)):
         return True, cmake_lists + " is newer than the configuration - reconfigure"
     with open(guard_file, 'r') as fp:
         if fp.read() != self._guard_data(source_dir, cmake_config):
             return True, "CMake configuration changed - reconfigure"
         return False, None
Exemplo n.º 4
0
def _netbeansinit_suite(args, jdks, suite, refreshOnly=False, buildProcessorJars=True):
    netbeans_dir = mx.ensure_dir_exists(suite.get_mx_output_dir())
    configZip = mx.TimeStampFile(join(netbeans_dir, 'netbeans-config.zip'))
    configLibsZip = join(netbeans_dir, 'netbeans-config-libs.zip')
    if refreshOnly and not configZip.exists():
        return

    if mx_ideconfig._check_ide_timestamp(suite, configZip, 'netbeans'):
        mx.logv('[NetBeans configurations are up to date - skipping]')
        return

    files = []
    libFiles = []
    for p in suite.projects:
        if not p.isJavaProject():
            continue

        if exists(join(p.dir, 'plugin.xml')):  # eclipse plugin project
            continue

        includedInDists = [d for d in suite.dists if p in d.archived_deps()]
        _netbeansinit_project(p, jdks, files, libFiles, includedInDists)

    mx_ideconfig._zip_files(files, suite.dir, configZip.path)
    mx_ideconfig._zip_files(libFiles, suite.dir, configLibsZip)
Exemplo n.º 5
0
def _newest(path):
    """
    Computes the newest timestamp for `path`. This is simply the timestamp of
    `path` if it is a file. Otherwise, it's the timestamp of the newest file
    in the `path` directory.
    """
    ts = mx.TimeStampFile(path)
    if isdir(path):
        for dirpath, _, filenames in os.walk(path):
            for filename in filenames:
                if filename.endswith('.class') and filename not in (
                        'module-info.class', 'package-info.class'):
                    file_ts = mx.TimeStampFile(join(dirpath, filename))
                    if file_ts.isNewerThan(ts):
                        ts = file_ts
    return ts
Exemplo n.º 6
0
    def needsBuild(self, newestInput):
        if not exists(self.jvm_args_file):
            return (True, self.jvm_args_file + " does not exist")

        jvm_args = mx.TimeStampFile(self.jvm_args_file)
        # Depends on mx.truffleruby/env which can change which suites are binary
        if exists(self.mx_env) and jvm_args.isOlderThan(self.mx_env):
            return (True, self.jvm_args_file + " is older than " + self.mx_env)
        # and on suite.py which can change dependencies and the classpath
        if jvm_args.isOlderThan(self.suite_py):
            return (True, self.jvm_args_file + " is older than " + self.suite_py)
        # and on this file which can change the list of distributions for the classpath
        if jvm_args.isOlderThan(self.mx_truffleruby):
            return (True, self.jvm_args_file + " is older than " + self.mx_truffleruby)

        if sys.platform.startswith('darwin'):
            return (mx.TimeStampFile(self.launcher).isOlderThan(self.binary), self.launcher)
        else:
            return (not exists(self.launcher), self.launcher)
Exemplo n.º 7
0
    def needsBuild(self, newestInput):
        is_needed, reason = super(GraalWasmSourceFileTask, self).needsBuild(newestInput)
        if is_needed:
            return True, reason

        tsNewestSource = mx.TimeStampFile.newest([os.path.join(root, f) for root, f in self.subject.getSources()])
        for result in self.subject.getResults():
            tsResult = mx.TimeStampFile(result)
            if tsResult.isOlderThan(tsNewestSource):
                return (True, "File " + result + " is older than the newest source file " + str(tsNewestSource))

        return (False, "Build outputs are up-to-date.")
Exemplo n.º 8
0
 def needsBuild(self, newestInput):
     sup = super(GraalVmSymLinksBuildTask, self).needsBuild(newestInput)
     if sup[0]:
         return sup
     if mx.get_os() != 'windows':
         for src, dest in self.subject.links:
             if not os.path.lexists(dest):
                 return True, '{} does not exist'.format(dest)
             link_file = mx.TimeStampFile(dest, False)
             if newestInput and link_file.isOlderThan(newestInput):
                 return True, '{} is older than {}'.format(dest, newestInput)
             if src != os.readlink(dest):
                 return True, '{} points to the wrong file'.format(dest)
     return False, None
Exemplo n.º 9
0
def _build_aot_images(benchmarks):
    print('---------------- BEGIN BUILDING AOT IMAGES ----------------')
    output_dir = mx.join(_suite.get_output_root(), 'bin')
    mx.ensure_dir_exists(output_dir)
    for bench_name, bench in benchmarks.items():
        witness = mx.TimeStampFile(mx.join(output_dir, bench_name))
        if not witness.exists() or witness.isOlderThan(bench.src_file):
            cmd = [
                jdk.aot_image, '-cp', bench.classpath,
                '-H:Name={}'.format(bench_name),
                '-H:Class={}'.format(bench.class_file)
            ]
            cmd.extend(bench.build_args)
            print(' '.join(cmd))
            mx.run(cmd, cwd=output_dir)
    print('---------------- END BUILDING AOT IMAGES ----------------')
Exemplo n.º 10
0
def _read_cached_testclasses(cachesDir, jar):
    """
    Reads the cached list of test classes in `jar`.

    :param str cachesDir: directory containing files with cached test lists
    :return: the cached list of test classes in `jar` or None if the cache doesn't
             exist or is out of date
    """
    cache = join(cachesDir, basename(jar) + '.testclasses')
    if exists(cache) and mx.TimeStampFile(cache).isNewerThan(jar):
        # Only use the cached result if the source jar is older than the cache file
        try:
            with open(cache) as fp:
                return [line.strip() for line in fp.readlines()]
        except IOError as e:
            mx.warn('Error reading from ' + cache + ': ' + str(e))
    return None
Exemplo n.º 11
0
def _build_aot_images(project, benchmarks):
    print('---------------- BEGIN BUILDING AOT IMAGES ----------------')
    output_dir = project.output_dir()
    class_files = {}
    for bench in benchmarks:
        bench_class, (bench_src, _) = project.find_classes_with_annotations(
            None, ['@AOTBench("{}")'.format(bench)]).popitem()
        class_files[bench] = bench_class
        witness = mx.TimeStampFile(mx.join(output_dir, bench))
        if not witness.exists() or witness.isOlderThan(bench_src):
            cmd = [
                jdk.aot_image, '-cp', '.', '-H:Name={}'.format(bench),
                '-H:Class={}'.format(bench_class)
            ]
            cmd.extend(benchmarks[bench][1])
            print(' '.join(cmd))
            mx.run(cmd, cwd=output_dir)
    print('---------------- END BUILDING AOT IMAGES ----------------')
    return class_files
Exemplo n.º 12
0
def _read_cached_testclasses(cachesDir, jar, jdk):
    """
    Reads the cached list of test classes in `jar`.

    :param str cachesDir: directory containing files with cached test lists
    :param JDKConfig jdk: the JDK for which the cached list of classes must be found
    :return: the cached list of test classes in `jar` or None if the cache doesn't
             exist or is out of date
    """
    jdkVersion = '.jdk' + str(jdk.javaCompliance)
    cache = join(cachesDir, basename(jar) + jdkVersion + '.testclasses')
    if exists(cache) and mx.TimeStampFile(cache).isNewerThan(jar):
        # Only use the cached result if the source jar is older than the cache file
        try:
            with open(cache) as fp:
                return [line.strip() for line in fp.readlines()]
        except IOError as e:
            mx.warn('Error reading from ' + cache + ': ' + str(e))
    return None
Exemplo n.º 13
0
def _netbeansinit_suite(args,
                        suite,
                        refreshOnly=False,
                        buildProcessorJars=True):
    mxOutputDir = mx.ensure_dir_exists(suite.get_mx_output_dir())
    configZip = mx.TimeStampFile(join(mxOutputDir, 'netbeans-config.zip'))
    configLibsZip = join(mxOutputDir, 'eclipse-config-libs.zip')
    if refreshOnly and not configZip.exists():
        return

    if mx_ideconfig._check_ide_timestamp(suite, configZip, 'netbeans'):
        mx.logv('[NetBeans configurations are up to date - skipping]')
        return

    files = []
    libFiles = []
    jdks = set()
    for p in suite.projects:
        if not p.isJavaProject():
            continue

        if exists(join(p.dir, 'plugin.xml')):  # eclipse plugin project
            continue

        includedInDists = [d for d in suite.dists if p in d.archived_deps()]
        _netbeansinit_project(p, jdks, files, libFiles, includedInDists)
    mx.log('If using NetBeans:')
    # http://stackoverflow.com/questions/24720665/cant-resolve-jdk-internal-package
    mx.log(
        '  1. Edit etc/netbeans.conf in your NetBeans installation and modify netbeans_default_options variable to include "-J-DCachingArchiveProvider.disableCtSym=true"'
    )
    mx.log(
        '  2. Ensure that the following platform(s) are defined (Tools -> Java Platforms):'
    )
    for jdk in jdks:
        mx.log('        JDK_' + str(jdk.version))
    mx.log(
        '  3. Open/create a Project Group for the directory containing the projects (File -> Project Group -> New Group... -> Folder of Projects)'
    )

    mx_ideconfig._zip_files(files, suite.dir, configZip.path)
    mx_ideconfig._zip_files(libFiles, suite.dir, configLibsZip)
Exemplo n.º 14
0
def get_library_as_module(dep, jdk):
    """
    Converts a (modular or non-modular) jar library to a module descriptor.

    :param Library dep: a library dependency
    :param JDKConfig jdk: a JDK with a version >= 9 that can be used to describe the module
    :return: a module descriptor
    """
    assert dep.isLibrary()

    def is_valid_module_name(name):
        identRE = re.compile(r"^[A-Za-z][A-Za-z0-9]*$")
        return all(identRE.match(ident) for ident in name.split('.'))

    if hasattr(dep, 'moduleName'):
        moduleName = dep.moduleName
    else:
        moduleName = jdk.get_automatic_module_name(dep.path)
        if not is_valid_module_name(moduleName):
            mx.abort(
                "Invalid identifier in automatic module name derived for library {}: {} (path: {})"
                .format(dep.name, moduleName, dep.path))
        dep.moduleName = moduleName

    modulesDir = mx.ensure_dir_exists(
        join(mx.primary_suite().get_output_root(), 'modules'))
    cache = join(modulesDir, moduleName + '.desc')
    fullpath = dep.get_path(resolve=True)
    save = False
    if not exists(cache) or mx.TimeStampFile(fullpath).isNewerThan(
            cache) or mx.TimeStampFile(__file__).isNewerThan(cache):
        out = mx.LinesOutputCapture()
        rc = mx.run([
            jdk.java, '--module-path', fullpath, '--describe-module',
            moduleName
        ],
                    out=out,
                    err=out,
                    nonZeroIsFatal=False)
        lines = out.lines
        if rc != 0:
            mx.abort(
                "java --describe-module {} failed. Please verify the moduleName attribute of {}.\n{}"
                .format(moduleName, dep.name, "\n".join(lines)))
        save = True
    else:
        with open(cache) as fp:
            lines = fp.read().splitlines()

    assert lines and lines[0].startswith(moduleName), (dep.name, moduleName,
                                                       lines)

    accepted_modifiers = set(['transitive'])
    requires = {}
    exports = {}
    provides = {}
    uses = set()
    packages = set()

    for line in lines[1:]:
        parts = line.strip().split()
        assert len(parts) >= 2, '>>>' + line + '<<<'
        if parts[0:2] == ['qualified', 'exports']:
            parts = parts[1:]
        a = parts[0]
        if a == 'requires':
            module = parts[1]
            modifiers = parts[2:]
            requires[module] = set(m for m in modifiers
                                   if m in accepted_modifiers)
        elif a == 'exports':
            source = parts[1]
            if len(parts) > 2:
                assert parts[2] == 'to'
                targets = parts[3:]
            else:
                targets = []
            exports[source] = targets
        elif a == 'uses':
            uses.update(parts[1:])
        elif a == 'contains':
            packages.update(parts[1:])
        elif a == 'provides':
            assert len(parts) >= 4 and parts[2] == 'with'
            service = parts[1]
            providers = parts[3:]
            provides.setdefault(service, []).extend(providers)
        else:
            mx.abort('Cannot parse module descriptor line: ' + str(parts))
    packages.update(exports.keys())

    if save:
        try:
            with open(cache, 'w') as fp:
                fp.write('\n'.join(lines) + '\n')
        except IOError as e:
            mx.warn('Error writing to ' + cache + ': ' + str(e))
            os.remove(cache)

    return JavaModuleDescriptor(moduleName,
                                exports,
                                requires,
                                uses,
                                provides,
                                packages,
                                jarpath=fullpath)
Exemplo n.º 15
0
    def build(self):
        source_dir = self.subject.getSourceDir()
        output_dir = self.subject.getOutputDir()
        if not emcc_dir:
            mx.abort("No EMCC_DIR specified - the source programs will not be compiled to .wasm.")
        emcc_cmd = os.path.join(emcc_dir, "emcc")
        gcc_cmd = os.path.join(gcc_dir, "gcc")
        if mx.run([emcc_cmd, "-v"], nonZeroIsFatal=False) != 0:
            mx.abort("Could not check the emcc version.")
        if mx.run([gcc_cmd, "--version"], nonZeroIsFatal=False) != 0:
            mx.abort("Could not check the gcc version.")
        if not wabt_dir:
            mx.abort("Set WABT_DIR if you want the binary to include .wat files.")
        mx.log("Building files from the source dir: " + source_dir)
        cc_flags = ["-O3", "-g2"]
        include_flags = []
        disable_test_api_flags = ["-DDISABLE_TEST_API"]
        if hasattr(self.project, "includeset"):
            include_flags = ["-I", os.path.join(_suite.dir, "includes", self.project.includeset)]
        emcc_flags = cc_flags
        if self.project.isBenchmarkProject():
            emcc_flags = emcc_flags + ["-s", "EXPORTED_FUNCTIONS=" + str(benchmark_methods).replace("'", "\"") + ""]
        subdir_program_names = defaultdict(lambda: [])
        for root, filename in self.subject.getProgramSources():
            subdir = os.path.relpath(root, self.subject.getSourceDir())
            mx.ensure_dir_exists(os.path.join(output_dir, subdir))

            basename = remove_extension(filename)
            source_path = os.path.join(root, filename)
            output_wasm_path = os.path.join(output_dir, subdir, basename + ".wasm")
            timestampedSource = mx.TimeStampFile(source_path)
            timestampedOutput = mx.TimeStampFile(output_wasm_path)
            mustRebuild = timestampedSource.isNewerThan(timestampedOutput) or not timestampedOutput.exists()

            # Step 1: build the .wasm binary.
            if mustRebuild:
                if filename.endswith(".c"):
                    # Step 1a: compile with the JS file, and store as files for running Node, if necessary.
                    output_js_path = os.path.join(output_dir, subdir, basename + ".js")
                    build_cmd_line = [emcc_cmd] + emcc_flags + disable_test_api_flags + [source_path, "-o", output_js_path] + include_flags
                    if mx.run(build_cmd_line, nonZeroIsFatal=False) != 0:
                        mx.abort("Could not build the JS output of " + filename + " with emcc.")
                    if self.subject.isBenchmarkProject():
                        node_dir = os.path.join(output_dir, subdir, NODE_BENCH_DIR)
                        mx.ensure_dir_exists(node_dir)
                        shutil.copyfile(output_js_path, os.path.join(node_dir, basename + ".js"))
                        shutil.copyfile(output_wasm_path, os.path.join(node_dir, basename + ".wasm"))

                    # Step 1b: extract the relevant information out of the JS file, and record it into an initialization file.
                    init_info = self.extractInitialization(output_js_path)
                    with open(os.path.join(output_dir, subdir, basename + ".init"), "w") as f:
                        f.write(init_info)

                    # Step 1c: compile to just a .wasm file, to avoid name mangling.
                    build_cmd_line = [emcc_cmd] + emcc_flags + ["-s", "ERROR_ON_UNDEFINED_SYMBOLS=0"] + [source_path, "-o", output_wasm_path] + include_flags
                    if mx.run(build_cmd_line, nonZeroIsFatal=False) != 0:
                        mx.abort("Could not build the wasm-only output of " + filename + " with emcc.")
                elif filename.endswith(".wat"):
                    # Step 1: compile the .wat file to .wasm.
                    wat2wasm_cmd = os.path.join(wabt_dir, "wat2wasm")
                    build_cmd_line = [wat2wasm_cmd, "-o", output_wasm_path, source_path]
                    if mx.run(build_cmd_line, nonZeroIsFatal=False) != 0:
                        mx.abort("Could not translate " + filename + " to binary format.")
            else:
                mx.logv("skipping, file is up-to-date: " + source_path)

            # Step 2: copy the result file if it exists.
            result_path = os.path.join(root, basename + ".result")
            if os.path.isfile(result_path):
                result_output_path = os.path.join(output_dir, subdir, basename + ".result")
                shutil.copyfile(result_path, result_output_path)

            # Step 3: copy the opts file if it exists.
            opts_path = os.path.join(root, basename + ".opts")
            if os.path.isfile(opts_path):
                opts_output_path = os.path.join(output_dir, subdir, basename + ".opts")
                shutil.copyfile(opts_path, opts_output_path)

            output_wat_path = os.path.join(output_dir, subdir, basename + ".wat")
            if mustRebuild:
                if filename.endswith(".c"):
                    # Step 4: produce the .wat files, for easier debugging.
                    wasm2wat_cmd = os.path.join(wabt_dir, "wasm2wat")
                    if mx.run([wasm2wat_cmd, "-o", output_wat_path, output_wasm_path], nonZeroIsFatal=False) != 0:
                        mx.abort("Could not compile .wat file for " + filename)
                elif filename.endswith(".wat"):
                    # Step 4: copy the .wat file, for easier debugging.
                    wat_path = os.path.join(root, basename + ".wat")
                    shutil.copyfile(wat_path, output_wat_path)

            # Step 5: if this is a benchmark project, create native binaries too.
            if mustRebuild:
                mx.ensure_dir_exists(os.path.join(output_dir, subdir, NATIVE_BENCH_DIR))
                if filename.endswith(".c"):
                    output_path = os.path.join(output_dir, subdir, NATIVE_BENCH_DIR, mx.exe_suffix(basename))
                    link_flags = ["-lm"]
                    gcc_cmd_line = [gcc_cmd] + cc_flags + disable_test_api_flags + [source_path, "-o", output_path] + include_flags + link_flags
                    if mx.run(gcc_cmd_line, nonZeroIsFatal=False) != 0:
                        mx.abort("Could not build the native binary of " + filename + ".")
                    os.chmod(output_path, stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR)
                elif filename.endswith(".wat"):
                    mx.warn("The .wat files are not translated to native binaries: " + filename)

            # Remember the source name.
            subdir_program_names[subdir].append(basename)
        for subdir in subdir_program_names:
            with open(os.path.join(output_dir, subdir, "wasm_test_index"), "w") as f:
                for name in subdir_program_names[subdir]:
                    f.write(name)
                    f.write("\n")
Exemplo n.º 16
0
def _update_JVMCI_library():
    """
    Updates the "path" and "sha1" attributes of the "JVMCI" library to
    refer to a jvmci.jar created from the JVMCI classes in JDK9.
    """
    suiteDict = _suite.suiteDict
    jvmciLib = suiteDict['libraries']['JVMCI']
    d = join(_suite.get_output_root(), abspath(_jdk.home)[1:])
    path = join(d, 'jvmci.jar')

    explodedModule = join(_jdk.home, 'modules', 'jdk.vm.ci')
    if exists(explodedModule):
        jarInputs = {}
        newestJarInput = None
        for root, _, files in os.walk(explodedModule):
            relpath = root[len(explodedModule) + 1:]
            for f in files:
                arcname = join(relpath, f).replace(os.sep, '/')
                jarInput = join(root, f)
                jarInputs[arcname] = jarInput
                t = mx.TimeStampFile(jarInput)
                if newestJarInput is None or t.isNewerThan(newestJarInput):
                    newestJarInput = t
        if not exists(path) or newestJarInput.isNewerThan(path):
            with mx.Archiver(path, kind='zip') as arc:
                for arcname, jarInput in jarInputs.iteritems():
                    with open(jarInput, 'rb') as fp:
                        contents = fp.read()
                        arc.zf.writestr(arcname, contents)
    else:
        # Use the jdk.internal.jimage utility since it's the only way
        # to partially read .jimage files as the JDK9 jimage tool
        # does not support partial extraction.
        bootmodules = join(_jdk.home, 'lib', 'modules', 'bootmodules.jimage')
        if not exists(bootmodules):
            mx.abort('Could not find JVMCI classes at ' + bootmodules + ' or ' + explodedModule)
        if not exists(path) or mx.TimeStampFile(bootmodules).isNewerThan(path):
            mx.ensure_dir_exists(d)
            javaSource = join(d, 'ExtractJVMCI.java')
            with open(javaSource, 'w') as fp:
                print >> fp, """import java.io.FileOutputStream;
    import java.util.jar.JarEntry;
    import java.util.jar.JarOutputStream;
    import jdk.internal.jimage.BasicImageReader;

    public class ExtractJVMCI {
    public static void main(String[] args) throws Exception {
        BasicImageReader image = BasicImageReader.open(args[0]);
        String[] names = image.getEntryNames();
        if (names.length == 0) {
            return;
        }
        try (JarOutputStream jos = new JarOutputStream(new FileOutputStream(args[1]))) {
            for (String name : names) {
                if (name.startsWith("/jdk.vm.ci/")) {
                    String ename = name.substring("/jdk.vm.ci/".length());
                    JarEntry je = new JarEntry(ename);
                    jos.putNextEntry(je);
                    jos.write(image.getResource(name));
                    jos.closeEntry();
                }
            }
        }
    }
    }
    """
            mx.run([_jdk.javac, '-d', d, javaSource])
            mx.run([_jdk.java, '-cp', d, 'ExtractJVMCI', bootmodules, path])
            if not exists(path):
                mx.abort('Could not find the JVMCI classes in ' + bootmodules)

    jvmciLib['path'] = path
    jvmciLib['sha1'] = mx.sha1OfFile(path)
Exemplo n.º 17
0
 def newestOutput(self):
     return mx.TimeStampFile(
         native_image_path(self.subject.native_image_root))
Exemplo n.º 18
0
    def build(self):
        source_dir = self.subject.getSourceDir()
        output_dir = self.subject.getOutputDir()
        if not emcc_dir:
            mx.abort(
                "No EMCC_DIR specified - the source programs will not be compiled to .wasm."
            )
        emcc_cmd = os.path.join(emcc_dir, "emcc")
        gcc_cmd = os.path.join(gcc_dir, "gcc")
        if mx.run([emcc_cmd, "-v"], nonZeroIsFatal=False) != 0:
            mx.abort("Could not check the emcc version.")
        if mx.run([gcc_cmd, "--version"], nonZeroIsFatal=False) != 0:
            mx.abort("Could not check the gcc version.")
        if not wabt_dir:
            mx.abort(
                "Set WABT_DIR if you want the binary to include .wat files.")
        mx.log("Building files from the source dir: " + source_dir)
        cc_flags = ["-g2", "-O3"]
        include_flags = []
        if hasattr(self.project, "includeset"):
            include_flags = [
                "-I",
                os.path.join(_suite.dir, "includes", self.project.includeset)
            ]
        emcc_flags = [
            "-s", "EXIT_RUNTIME=1", "-s", "STANDALONE_WASM", "-s",
            "WASM_BIGINT"
        ] + cc_flags
        if self.project.isBenchmarkProject():
            emcc_flags = emcc_flags + [
                "-s", "EXPORTED_FUNCTIONS=" +
                str(self.benchmark_methods()).replace("'", "\"") + ""
            ]
        subdir_program_names = defaultdict(lambda: [])
        for root, filename in self.subject.getProgramSources():
            if filename.startswith("_"):
                # Ignore files starting with an underscore
                continue

            subdir = os.path.relpath(root, self.subject.getSourceDir())
            mx.ensure_dir_exists(os.path.join(output_dir, subdir))

            basename = remove_extension(filename)
            source_path = os.path.join(root, filename)
            output_wasm_path = os.path.join(output_dir, subdir,
                                            basename + ".wasm")
            output_js_path = os.path.join(output_dir, subdir, basename + ".js")
            timestampedSource = mx.TimeStampFile(source_path)
            timestampedOutput = mx.TimeStampFile(output_wasm_path)
            mustRebuild = timestampedSource.isNewerThan(
                timestampedOutput) or not timestampedOutput.exists()

            # Step 1: build the .wasm binary.
            if mustRebuild:
                if filename.endswith(".c"):
                    # This generates both a js file and a wasm file.
                    # See https://github.com/emscripten-core/emscripten/wiki/WebAssembly-Standalone
                    build_cmd_line = [emcc_cmd] + emcc_flags + [
                        source_path, "-o", output_js_path
                    ] + include_flags
                    if mx.run(build_cmd_line, nonZeroIsFatal=False) != 0:
                        mx.abort("Could not build the wasm-only output of " +
                                 filename + " with emcc.")
                elif filename.endswith(".wat"):
                    # Step 1: compile the .wat file to .wasm.
                    wat2wasm_cmd = os.path.join(wabt_dir, "wat2wasm")
                    build_cmd_line = [
                        wat2wasm_cmd, "-o", output_wasm_path, source_path
                    ]
                    if mx.run(build_cmd_line, nonZeroIsFatal=False) != 0:
                        mx.abort("Could not translate " + filename +
                                 " to binary format.")
                elif filename.endswith(".wasm"):
                    shutil.copyfile(source_path, output_wasm_path)

            else:
                mx.logv("skipping, file is up-to-date: " + source_path)

            # Step 2: copy the result file if it exists.
            result_path = os.path.join(root, basename + ".result")
            if os.path.isfile(result_path):
                result_output_path = os.path.join(output_dir, subdir,
                                                  basename + ".result")
                shutil.copyfile(result_path, result_output_path)

            # Step 3: copy the opts file if it exists.
            opts_path = os.path.join(root, basename + ".opts")
            if os.path.isfile(opts_path):
                opts_output_path = os.path.join(output_dir, subdir,
                                                basename + ".opts")
                shutil.copyfile(opts_path, opts_output_path)

            output_wat_path = os.path.join(output_dir, subdir,
                                           basename + ".wat")
            if mustRebuild:
                if filename.endswith(".c"):
                    # Step 4: produce the .wat files, for easier debugging.
                    wasm2wat_cmd = os.path.join(wabt_dir, "wasm2wat")
                    if mx.run([
                            wasm2wat_cmd, "-o", output_wat_path,
                            output_wasm_path
                    ],
                              nonZeroIsFatal=False) != 0:
                        mx.abort("Could not compile .wat file for " + filename)
                elif filename.endswith(".wat"):
                    # Step 4: copy the .wat file, for easier debugging.
                    wat_path = os.path.join(root, basename + ".wat")
                    shutil.copyfile(wat_path, output_wat_path)

            # Step 5: if this is a benchmark project, create native binaries too.
            if mustRebuild:
                if filename.endswith(".c"):
                    mx.ensure_dir_exists(
                        os.path.join(output_dir, subdir, NATIVE_BENCH_DIR))
                    output_path = os.path.join(output_dir, subdir,
                                               NATIVE_BENCH_DIR,
                                               mx.exe_suffix(basename))
                    link_flags = ["-lm"]
                    gcc_cmd_line = [gcc_cmd] + cc_flags + [
                        source_path, "-o", output_path
                    ] + include_flags + link_flags
                    if mx.run(gcc_cmd_line, nonZeroIsFatal=False) != 0:
                        mx.abort("Could not build the native binary of " +
                                 filename + ".")
                    os.chmod(output_path,
                             stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR)
                elif filename.endswith(".wat"):
                    mx.warn(
                        "The .wat files are not translated to native binaries: "
                        + filename)

            # Remember the source name.
            subdir_program_names[subdir].append(basename)
        for subdir in subdir_program_names:
            with open(os.path.join(output_dir, subdir, "wasm_test_index"),
                      "w") as f:
                for name in subdir_program_names[subdir]:
                    f.write(name)
                    f.write("\n")
Exemplo n.º 19
0
 def needsBuild(self, newestInput):
     if sys.platform.startswith('darwin'):
         return (mx.TimeStampFile(self.launcher).isOlderThan(self.binary),
                 self.launcher)
     else:
         return (not exists(self.launcher), self.launcher)
Exemplo n.º 20
0
 def newestOutput(self):
     return mx.TimeStampFile(self.subject.image_file())