def contents(self, tool, exe):
     # platform support
     all_params = '%*' if mx.is_windows() else '"$@"'
     _quote = _quote_windows if mx.is_windows() else pipes.quote
     # build command line
     java = mx.get_jdk().java
     classpath_deps = [
         dep for dep in self.subject.buildDependencies
         if isinstance(dep, mx.ClasspathDependency)
     ]
     extra_props = [
         '-Dorg.graalvm.launcher.executablename="{}"'.format(exe)
     ]
     main_class = self.subject.suite.toolchain._tool_to_main(tool)
     # add jvm args from dependencies
     jvm_args = [
         _quote(arg) for arg in mx.get_runtime_jvm_args(classpath_deps)
     ]
     # add properties from the project
     if hasattr(self.subject, "getJavaProperties"):
         for key, value in sorted(self.subject.getJavaProperties().items()):
             jvm_args.append("-D" + key + "=" + value)
     command = [java] + jvm_args + extra_props + [main_class, all_params]
     # create script
     if mx.is_windows():
         return "@echo off\n" + " ".join(command) + "\n"
     else:
         return "#!/usr/bin/env bash\n" + "exec " + " ".join(command) + "\n"
Esempio n. 2
0
    def asm_rule(self):
        assert mx.is_windows()

        self.n.rule(
            'cpp',
            command=
            'cl -nologo -showIncludes -EP -P $includes $cflags -c $in -Fi$out',
            description='CPP $out',
            deps='msvc')
        self.newline()

        self.n.rule('asm',
                    command='ml64 -nologo -Fo$out -c $in',
                    description='ASM $out')
        self.newline()

        def preprocessed(source_file):
            output = os.path.splitext(source_file)[0] + '.asm'
            return self.n.build(output, 'cpp', self._resolve(source_file))[0]

        def build(source_file):
            output = os.path.splitext(source_file)[0] + '.obj'
            return self.n.build(output, 'asm', preprocessed(source_file))[0]

        return build
Esempio n. 3
0
def _ensure_vm_built():
    # build "jvm" config used by native-image and native-image-configure commands
    config = graalvm_jvm_configs[-1]
    rebuild_vm = False
    mx.ensure_dir_exists(svmbuild_dir())
    if not mx.is_windows():
        vm_link = join(svmbuild_dir(), 'vm')
        if not os.path.exists(vm_link):
            rebuild_vm = True
            if os.path.lexists(vm_link):
                os.unlink(vm_link)
            vm_linkname = os.path.relpath(_vm_home(config), dirname(vm_link))
            os.symlink(vm_linkname, vm_link)
    rev_file_name = join(svmbuild_dir(), 'vm-rev')
    rev_value = svm_suite().vc.parent(svm_suite().vc_dir)
    if not os.path.exists(rev_file_name):
        rebuild_vm = True
    else:
        with open(rev_file_name, 'r') as f:
            if f.read() != rev_value:
                rebuild_vm = True
    if rebuild_vm:
        with open(rev_file_name, 'w') as f:
            f.write(rev_value)
        build_native_image_image(config)
 def launchers(self):
     for tool in self.suite.toolchain._supported_tools():
         for exe in self.suite.toolchain._tool_to_aliases(tool):
             if mx.is_windows() and exe.endswith('.exe'):
                 exe = exe[:-4] + ".cmd"
             result = os.path.join(self.get_output_root(), exe)
             yield result, tool, exe
Esempio n. 5
0
    def cc_rule(self, cxx=False):
        if mx.is_windows():
            command = 'cl -nologo -showIncludes $includes $cflags -c $in -Fo$out'
            depfile = None
            deps = 'msvc'
        else:
            command = '%s -MMD -MF $out.d $includes $cflags -c $in -o $out' % (
                'g++' if cxx else 'gcc')
            depfile = '$out.d'
            deps = 'gcc'

        rule = 'cxx' if cxx else 'cc'
        self.n.rule(rule,
                    command=command,
                    description='%s $out' % rule.upper(),
                    depfile=depfile,
                    deps=deps)
        self.newline()

        def build(source_file):
            output = os.path.splitext(source_file)[0] + (
                '.obj' if mx.is_windows() else '.o')
            return self.n.build(output, rule, self._resolve(source_file))[0]

        return build
Esempio n. 6
0
 def contents(self, tool, exe):
     # platform support
     all_params = '"%*"' if mx.is_windows() else '"$@"'
     _quote = _quote_windows if mx.is_windows() else pipes.quote
     # build command line
     java = mx.get_jdk().java
     classpath_deps = [dep for dep in self.subject.buildDependencies if isinstance(dep, mx.ClasspathDependency)]
     extra_props = ['-Dorg.graalvm.launcher.executablename="{}"'.format(exe)]
     main_class = self.subject.suite.toolchain._tool_to_main(tool)
     jvm_args = [_quote(arg) for arg in mx.get_runtime_jvm_args(classpath_deps)]
     command = [java] + jvm_args + extra_props + [main_class, all_params]
     # create script
     if mx.is_windows():
         return "@echo off\n" + " ".join(command) + "\n"
     else:
         return "#!/usr/bin/env bash\n" + "exec " + " ".join(command) + "\n"
Esempio n. 7
0
 def run(self, *args, **kwargs):
     # Hack: disable autocrlf on Windows but re-use the caching-related code in GitConfig.clone
     if mx.is_windows() and len(args) == 1 and len(args[0]) >= 2 and args[0][0] == 'git' and args[0][1] == 'clone':
         _cmd = args[0]
         _new_cmd = _cmd[:2] + ['-c', 'core.autocrlf=false'] + _cmd[2:]
         return super(NoCRLFGitConfig, self).run(_new_cmd, **kwargs)
     else:
         return super().run(*args, **kwargs)
Esempio n. 8
0
def intellij_read_sdks():
    sdks = dict()
    if mx.is_linux() or mx.is_openbsd() or mx.is_sunos() or mx.is_windows():
        xmlSdks = glob.glob(os.path.expanduser("~/.IdeaIC*/config/options/jdk.table.xml")) + \
          glob.glob(os.path.expanduser("~/.IntelliJIdea*/config/options/jdk.table.xml")) + \
          glob.glob(os.path.expanduser("~/.config/JetBrains/IdeaIC*/options/jdk.table.xml")) + \
          glob.glob(os.path.expanduser("~/.config/JetBrains/IntelliJIdea*/options/jdk.table.xml"))
    elif mx.is_darwin():
        xmlSdks = \
          glob.glob(os.path.expanduser("~/Library/Application Support/JetBrains/IdeaIC*/options/jdk.table.xml")) + \
          glob.glob(os.path.expanduser("~/Library/Application Support/JetBrains/IntelliJIdea*/options/jdk.table.xml")) + \
          glob.glob(os.path.expanduser("~/Library/Preferences/IdeaIC*/options/jdk.table.xml")) + \
          glob.glob(os.path.expanduser("~/Library/Preferences/IntelliJIdea*/options/jdk.table.xml"))
    else:
        mx.warn("Location of IntelliJ SDK definitions on {} is unknown".format(mx.get_os()))
        return sdks
    if len(xmlSdks) == 0:
        mx.warn("IntelliJ SDK definitions not found")
        return sdks

    verRE = re.compile(r'^.*[/\\]\.?(IntelliJIdea|IdeaIC)([^/\\]+)[/\\].*$')
    def verSort(path):
        match = verRE.match(path)
        return match.group(2) + (".a" if match.group(1) == "IntellijIC" else ".b")

    xmlSdks.sort(key=verSort)
    xmlSdk = xmlSdks[-1]  # Pick the most recent IntelliJ version, preferring Ultimate over Community edition.
    mx.log("Using SDK definitions from {}".format(xmlSdk))

    versionRegexes = {}
    versionRegexes[intellij_java_sdk_type] = re.compile(r'^java\s+version\s+"([^"]+)"$|^version\s+(.+)$|^([\d._]+)$')
    versionRegexes[intellij_python_sdk_type] = re.compile(r'^Python\s+(.+)$')
    # Examples:
    #   truffleruby 19.2.0-dev-2b2a7f81, like ruby 2.6.2, Interpreted JVM [x86_64-linux]
    #   ver.2.2.4p230 ( revision 53155) p230
    versionRegexes[intellij_ruby_sdk_type] = re.compile(r'^\D*(\d[^ ,]+)')

    for sdk in etreeParse(xmlSdk).getroot().findall("component[@name='ProjectJdkTable']/jdk[@version='2']"):
        name = sdk.find("name").get("value")
        kind = sdk.find("type").get("value")
        home = realpath(os.path.expanduser(sdk.find("homePath").get("value").replace('$USER_HOME$', '~')))
        if home.find('$APPLICATION_HOME_DIR$') != -1:
            # Don't know how to convert this into a real path so ignore it
            continue
        versionRE = versionRegexes.get(kind)
        if not versionRE or sdk.find("version") is None:
            # ignore unknown kinds
            continue

        match = versionRE.match(sdk.find("version").get("value"))
        if match:
            version = match.group(1)
            sdks[home] = {'name': name, 'type': kind, 'version': version}
            mx.logv("Found SDK {} with values {}".format(home, sdks[home]))
        else:
            mx.warn(u"Couldn't understand Java version specification \"{}\" for {} in {}".format(sdk.find("version").get("value"), home, xmlSdk))
    return sdks
Esempio n. 9
0
    def ar_rule(self):
        if mx.is_windows():
            command = 'lib -nologo -out:$out $in'
        else:
            command = 'ar -rc $out $in'

        self.n.rule('ar', command=command, description='AR $out')
        self.newline()

        return lambda archive, members: self.n.build(archive, 'ar', members)[0]
Esempio n. 10
0
def _lib_versioned(arg):
    name, version = arg.split('.')
    if mx.is_darwin():
        return "lib" + name + "." + version + ".dylib"
    elif mx.is_linux() or mx.is_openbsd() or mx.is_sunos():
        return "lib" + name + ".so." + version
    elif mx.is_windows():
        return name + ".dll"
    else:
        mx.abort('unsupported os')
Esempio n. 11
0
    def cflags(self):
        default_cflags = []
        if mx.is_windows() and mx.get_jdk(tag=mx.DEFAULT_JDK_TAG).javaCompliance >= '11':
            default_cflags += ['-FS']  # necessary until GR-16572 is resolved
        if self._kind == self._kinds['shared_lib']:
            default_cflags += dict(
                windows=['-MD'],
            ).get(mx.get_os(), ['-fPIC'])

        return default_cflags + super(DefaultNativeProject, self).cflags
Esempio n. 12
0
    def generate_manifest(self, path):
        unsupported_source_files = list(self._source['files'].viewkeys() -
                                        {'.h', '.c', '.cc', '.S'})
        if unsupported_source_files:
            mx.abort(
                '{} source files are not supported by default native projects'.
                format(unsupported_source_files))

        with NinjaManifestGenerator(self, open(path, 'w')) as gen:
            gen.comment('Project rules')
            cc = cxx = asm = None
            if self.c_files:
                cc = gen.cc_rule()
            if self.cxx_files:
                cxx = gen.cc_rule(cxx=True)
            if self.asm_sources:
                asm = gen.asm_rule() if mx.is_windows(
                ) else cc if cc else gen.cc_rule()

            ar = link = None
            if self._kind == self._kinds['static_lib']:
                ar = gen.ar_rule()
            else:
                link = gen.link_rule(cxx=bool(self.cxx_files))

            gen.variables(
                cflags=self.cflags,
                ldflags=self.ldflags if link else None,
                ldlibs=self.ldlibs if link else None,
            )
            gen.include(
                collections.OrderedDict.fromkeys(
                    # remove the duplicates while maintaining the ordering
                    [mx.dirname(h_file) for h_file in self.h_files] + list(
                        itertools.chain.from_iterable(
                            getattr(d, 'include_dirs', [])
                            for d in self.buildDependencies))).keys())

            gen.comment('Compiled project sources')
            object_files = [cc(f) for f in self.c_files]
            gen.newline()
            object_files += [cxx(f) for f in self.cxx_files]
            gen.newline()
            object_files += [asm(f) for f in self.asm_sources]
            gen.newline()

            gen.comment('Project deliverable')
            if self._kind == self._kinds['static_lib']:
                ar(self._target, object_files)
            else:
                link(
                    self._target, object_files + list(
                        itertools.chain.from_iterable(
                            getattr(d, 'libs', [])
                            for d in self.buildDependencies)))
Esempio n. 13
0
    def link_rule(self, cxx=False):
        if mx.is_windows():
            command = 'link -nologo $ldflags -out:$out $in $ldlibs'
        else:
            command = '%s $ldflags -o $out $in $ldlibs' % ('g++'
                                                           if cxx else 'gcc')

        self.n.rule('link', command=command, description='LINK $out')
        self.newline()

        return lambda program, files: self.n.build(program, 'link', files)[0]
Esempio n. 14
0
def native_image_configure_on_jvm(args, **kwargs):
    _ensure_vm_built()
    if mx.is_windows():
        config = graalvm_jvm_configs[-1]
        executable = vm_executable_path('native-image-configure', config)
    else:
        vm_link = join(svmbuild_dir(), 'vm')
        executable = join(vm_link, 'bin', 'native-image-configure')
    if not exists(executable):
        mx.abort("Can not find " + executable + "\nDid you forget to build? Try `mx build`")
    mx.run([executable, '-H:CLibraryPath=' + clibrary_libpath()] + args, **kwargs)
Esempio n. 15
0
    def parse_jar_suite_benchmark(self, args):
        if "-cp" not in args:
            mx.abort("Suite must specify -cp.")
        classpath = args[args.index("-cp") + 1]
        delimiter = ";" if mx.is_windows() else ":"
        jars = classpath.split(delimiter)
        jar = next(iter([jar for jar in jars if jar.endswith(BENCHMARK_JAR_SUFFIX)]), None)
        if jar is None:
            mx.abort("No benchmark jar file is specified in the classpath.")

        suite, benchmark = self.parse_suite_benchmark(args)
        return jar, suite, benchmark
Esempio n. 16
0
def build_native_image_image(config=None, args=None):
    config = config or graalvm_config()
    mx.log('Building GraalVM with native-image in ' + _vm_home(config))
    env = os.environ.copy()
    if mx.version < mx.VersionSpec("5.219"):
        mx.warn("mx version is older than 5.219, SVM's GraalVM build will not be built with links.\nConsider updating mx to improve IDE compile-on-save workflow.")
    if not mx.is_windows():
        if 'LINKY_LAYOUT' not in env:
            env['LINKY_LAYOUT'] = '*.jar'
        elif '*.jar' not in env['LINKY_LAYOUT']:
            mx.warn("LINKY_LAYOUT already set")
    _mx_vm(['build'] + (args or []), config, env=env)
Esempio n. 17
0
def _run_mx_suite_tests():
    """
    Mx suite specific tests.
    """
    mx_javacompliance._test()

    if mx.is_windows():
        def win(s, min_length=0):
            extra = min_length - len(s)
            if extra > 0:
                padding = 'X' * extra
                s += padding
            return s.replace('/', '\\')

        def _test(value, expect, open_fp):
            actual = mx._safe_path(value)
            if actual != expect:
                nl = os.linesep
                assert False, 'Failed safe_path test{} input: {} (len={}){}expect: {} (len={}){}actual: {} (len={})'.format(nl,
                    value, len(value), nl,
                    expect, len(expect), nl,
                    actual, len(actual))
            if open_fp and value != open_fp.name:
                try:
                    with mx.open(value, 'w') as fp:
                        fp.write('blah')
                    with mx.open(value, 'r') as fp:
                        contents = fp.read()
                        assert contents == 'blah', contents
                finally:
                    if os.path.exists(value):
                        os.unlink(value)

        with tempfile.NamedTemporaryFile(prefix="safe_path_test", mode="w") as fp:
            cases = {
                win('C:/Home/mydir') : win('C:/Home/mydir'),
                win('C:/Home/mydir', 258) : win('C:/Home/mydir', 258),
                win('C:/Home/mydir', 259) : win('//?/') + win('C:/Home/mydir', 259),
                win('C:/Home/mydir', 260) : win('//?/') + win('C:/Home/mydir', 260),
                win('//Mac/Home/mydir') : win('//Mac/Home/mydir'),
                win('//Mac/Home/mydir', 258) : win('//Mac/Home/mydir', 258),
                win('//Mac/Home/mydir', 259) : win('//?/UNC/') + win('Mac/Home/mydir', 257),
                win('//Mac/Home/mydir', 260) : win('//?/UNC/') + win('Mac/Home/mydir', 258),
                win(fp.name) : win(fp.name),
                win(fp.name, 258) : win(fp.name, 258),
                win(fp.name, 259) : win('//?/') + win(fp.name, 259),
                win(fp.name, 260) : win('//?/') + win(fp.name, 260),
            }
            for value, expect in cases.items():
                _test(value, expect, fp if value.startswith(fp.name) else None)
Esempio n. 18
0
 def build(self):
     super(GraalVmWatBuildTask, self).build()
     output_dir = self.subject.getOutputDir()
     for root, filename in self.subject.getProgramSources():
         src = join(
             output_dir,
             mx_wasm.remove_extension(filename) + ".wasm")
         dst = join(
             root,
             mx_wasm.remove_extension(filename) + ".wasm")
         if mx.is_windows():
             mx.copyfile(src, dst)
         else:
             os.symlink(src, dst)
Esempio n. 19
0
def native_image_on_jvm(args, **kwargs):
    save_args = []
    for arg in args:
        if arg == '--no-server' or arg.startswith('--server'):
            mx.warn('Ignoring server-mode native-image argument ' + arg)
        else:
            save_args.append(arg)

    _ensure_vm_built()
    if mx.is_windows():
        config = graalvm_jvm_configs[-1]
        executable = vm_native_image_path(config)
    else:
        vm_link = join(svmbuild_dir(), 'vm')
        executable = join(vm_link, 'bin', 'native-image')
    if not exists(executable):
        mx.abort("Can not find " + executable + "\nDid you forget to build? Try `mx build`")
    mx.run([executable, '-H:CLibraryPath=' + clibrary_libpath()] + save_args, **kwargs)
Esempio n. 20
0
    def cflags(self):
        default_cflags = []
        if mx.is_windows() and mx.get_jdk(
                tag=mx.DEFAULT_JDK_TAG).javaCompliance >= '11':
            default_cflags += ['-FS']  # necessary until GR-16572 is resolved
        if self._kind == self._kinds['shared_lib']:
            default_cflags += dict(windows=['-MD'
                                            ], ).get(mx.get_os(), ['-fPIC'])

        if mx.is_linux() or mx.is_darwin():
            # Do not leak host paths via dwarf debuginfo
            def add_debug_prefix(prefix_dir):
                return '-fdebug-prefix-map={}={}'.format(
                    prefix_dir, mx.basename(prefix_dir))

            default_cflags += [add_debug_prefix(self.suite.vc_dir)]
            default_cflags += [add_debug_prefix(NinjaProject.get_jdk().home)]
            default_cflags += ['-gno-record-gcc-switches']

        return default_cflags + super(DefaultNativeProject, self).cflags
Esempio n. 21
0
    jackpot = 'jackpot'


def _espresso_gate_runner(args, tasks):
    # Jackpot configuration is inherited from Truffle.
    with Task('Jackpot', tasks, tags=[EspressoDefaultTags.jackpot]) as t:
        if t:
            jackpot(['--fail-on-warnings'], suite=None, nonZeroIsFatal=True)


# REGISTER MX GATE RUNNER
#########################
add_gate_runner(_suite, _espresso_gate_runner)

if mx_sdk_vm.base_jdk_version() > 8:
    if mx.is_windows():
        lib_espresso_cp = '%GRAALVM_HOME%\\lib\\graalvm\\lib-espresso.jar'
    else:
        lib_espresso_cp = '${GRAALVM_HOME}/lib/graalvm/lib-espresso.jar'
else:
    if mx.is_windows():
        lib_espresso_cp = '%GRAALVM_HOME%\\jre\\lib\\graalvm\\lib-espresso.jar'
    else:
        lib_espresso_cp = '${GRAALVM_HOME}/jre/lib/graalvm/lib-espresso.jar'

mx_sdk_vm.register_graalvm_component(
    mx_sdk_vm.GraalVmLanguage(
        suite=_suite,
        name='Java on Truffle',
        short_name='java',
        installable_id='espresso',
Esempio n. 22
0
        license_files=[],
        third_party_license_files=[],
        dependencies=['sdk'],
        jar_distributions=['vm:INSTALLER', 'truffle:TruffleJSON'],
        support_distributions=['vm:INSTALLER_GRAALVM_SUPPORT'],
        launcher_configs=[
            mx_sdk_vm.LauncherConfig(
                destination="bin/<exe:gu>",
                jar_distributions=['vm:INSTALLER', 'truffle:TruffleJSON'],
                dir_jars=True,
                main_class="org.graalvm.component.installer.ComponentInstaller",
                build_args=[],
                # Please see META-INF/native-image in the project for custom build options for native-image
                is_sdk_launcher=True,
                custom_launcher_script="mx.vm/gu.cmd"
                if mx.is_windows() else None,
            ),
        ],
    ))

mx_sdk_vm.register_graalvm_component(
    mx_sdk_vm.GraalVmComponent(
        suite=_suite,
        name='GraalVM license files',
        short_name='gvm',
        dir_name='.',
        license_files=['LICENSE.txt'],
        third_party_license_files=['THIRD_PARTY_LICENSE.txt'],
        dependencies=[],
        support_distributions=['vm:VM_GRAALVM_SUPPORT'],
    ))
Esempio n. 23
0
def jlink_new_jdk(jdk, dst_jdk_dir, module_dists, root_module_names=None, missing_export_target_action='create', with_source=lambda x: True):
    """
    Uses jlink from `jdk` to create a new JDK image in `dst_jdk_dir` with `module_dists` and
    their dependencies added to the JDK image, replacing any existing modules of the same name.

    :param JDKConfig jdk: source JDK
    :param str dst_jdk_dir: path to use for the jlink --output option
    :param list module_dists: list of distributions defining modules
    :param list root_module_names: list of strings naming the module root set for the new JDK image.
                     The named modules must either be in `module_dists` or in `jdk`. If None, then
                     the root set will be all the modules in ``module_dists` and `jdk`.
    :param str missing_export_target_action: the action to perform for a qualifed export target that
                     is not present in `module_dists` and does not have a hash stored in java.base.
                     The choices are:
                       "create" - an empty module is created
                        "error" - raise an error
                           None - do nothing
    :param lambda with_source: returns True if the sources of a module distribution must be included in the new JDK
    """
    assert callable(with_source)

    if jdk.javaCompliance < '9':
        mx.abort('Cannot derive a new JDK from ' + jdk.home + ' with jlink since it is not JDK 9 or later')

    exploded_java_base_module = join(jdk.home, 'modules', 'java.base')
    if exists(exploded_java_base_module):
        mx.abort('Cannot derive a new JDK from ' + jdk.home + ' since it appears to be a developer build with exploded modules')

    jimage = join(jdk.home, 'lib', 'modules')
    jmods_dir = join(jdk.home, 'jmods')
    if not isfile(jimage):
        mx.abort('Cannot derive a new JDK from ' + jdk.home + ' since ' + jimage + ' is missing or is not an ordinary file')
    if not isdir(jmods_dir):
        mx.abort('Cannot derive a new JDK from ' + jdk.home + ' since ' + jmods_dir + ' is missing or is not a directory')

    jdk_modules = {jmd.name : jmd for jmd in jdk.get_modules()}
    modules = [as_java_module(dist, jdk) for dist in module_dists]
    all_module_names = frozenset(list(jdk_modules.keys()) + [m.name for m in modules])

    # Read hashes stored in java.base (the only module in the JDK where hashes are stored)
    out = mx.LinesOutputCapture()
    mx.run([jdk.exe_path('jmod'), 'describe', jdk_modules['java.base'].get_jmod_path()], out=out)
    lines = out.lines
    hashes = {}
    for line in lines:
        if line.startswith('hashes'):
            parts = line.split()
            assert len(parts) == 4, 'expected hashes line to have 4 fields, got {} fields: {}'.format(len(parts), line)
            _, module_name, algorithm, hash_value = parts
            hashes[module_name] = (algorithm, hash_value)

    build_dir = mx.ensure_dir_exists(join(dst_jdk_dir + ".build"))
    try:
        # Handle targets of qualified exports that are not present in `modules`
        target_requires = {}
        for jmd in modules:
            for targets in jmd.exports.values():
                for target in targets:
                    if target not in all_module_names and target not in hashes:
                        target_requires.setdefault(target, set()).add(jmd.name)
        if target_requires and missing_export_target_action is not None:
            if missing_export_target_action == 'error':
                mx.abort('Target(s) of qualified exports cannot be resolved: ' + '.'.join(target_requires.keys()))
            assert missing_export_target_action == 'create', 'invalid value for missing_export_target_action: ' + str(missing_export_target_action)

            extra_modules = []
            for name, requires in target_requires.items():
                module_jar = join(build_dir, name + '.jar')
                jmd = JavaModuleDescriptor(name, {}, requires={module : [] for module in requires}, uses=set(), provides={}, jarpath=module_jar)
                extra_modules.append(jmd)
                module_build_dir = mx.ensure_dir_exists(join(build_dir, name))
                module_info_java = join(module_build_dir, 'module-info.java')
                module_info_class = join(module_build_dir, 'module-info.class')
                with open(module_info_java, 'w') as fp:
                    print(jmd.as_module_info(), file=fp)
                mx.run([jdk.javac, '-d', module_build_dir, \
                        '--limit-modules=java.base,' + ','.join(jmd.requires.keys()), \
                        '--module-path=' + os.pathsep.join((m.jarpath for m in modules)), \
                        module_info_java])
                with ZipFile(module_jar, 'w') as zf:
                    zf.write(module_info_class, basename(module_info_class))
                if exists(jmd.get_jmod_path()):
                    os.remove(jmd.get_jmod_path())
                mx.run([jdk.javac.replace('javac', 'jmod'), 'create', '--class-path=' + module_build_dir, jmd.get_jmod_path()])

            modules.extend(extra_modules)
            all_module_names = frozenset(list(jdk_modules.keys()) + [m.name for m in modules])

        # Extract src.zip from source JDK
        jdk_src_zip = join(jdk.home, 'lib', 'src.zip')
        dst_src_zip_contents = {}
        if isfile(jdk_src_zip):
            mx.logv('[Extracting ' + jdk_src_zip + ']')
            with ZipFile(jdk_src_zip, 'r') as zf:
                for name in zf.namelist():
                    if not name.endswith('/'):
                        dst_src_zip_contents[name] = zf.read(name)
        else:
            mx.warn("'{}' does not exist or is not a file".format(jdk_src_zip))

        for jmd in modules:
            # Remove existing sources for all the modules that we include
            dst_src_zip_contents = {key : dst_src_zip_contents[key] for key in dst_src_zip_contents if not key.startswith(jmd.name)}

            if with_source(jmd.dist):
                # Add the sources that we can share.
                # Extract module sources
                jmd_src_zip = jmd.jarpath[0:-len('.jar')] + '.src.zip'
                if isfile(jmd_src_zip):
                    mx.logv('[Extracting ' + jmd_src_zip + ']')
                    with ZipFile(jmd_src_zip, 'r') as zf:
                        for name in zf.namelist():
                            if not name.endswith('/'):
                                dst_src_zip_contents[jmd.name + '/' + name] = zf.read(name)

                # Add module-info.java to sources
                dst_src_zip_contents[jmd.name + '/module-info.java'] = jmd.as_module_info(extras_as_comments=False)

        # Now build the new JDK image with jlink
        jlink = [jdk.javac.replace('javac', 'jlink')]

        if jdk_enables_jvmci_by_default(jdk):
            # On JDK 9+, +EnableJVMCI forces jdk.internal.vm.ci to be in the root set
            jlink.append('-J-XX:-EnableJVMCI')
        if root_module_names is not None:
            missing = frozenset(root_module_names) - all_module_names
            if missing:
                mx.abort('Invalid module(s): {}.\nAvailable modules: {}'.format(','.join(missing), ','.join(sorted(all_module_names))))
            jlink.append('--add-modules=' + ','.join(root_module_names))
        else:
            jlink.append('--add-modules=' + ','.join(sorted(all_module_names)))

        module_path = jmods_dir
        if modules:
            module_path = os.pathsep.join((m.get_jmod_path(respect_stripping=True) for m in modules)) + os.pathsep + module_path
        jlink.append('--module-path=' + module_path)
        jlink.append('--output=' + dst_jdk_dir)

        # These options are inspired by how OpenJDK runs jlink to produce the final runtime image.
        jlink.extend(['-J-XX:+UseSerialGC', '-J-Xms32M', '-J-Xmx512M', '-J-XX:TieredStopAtLevel=1'])
        jlink.append('-J-Dlink.debug=true')
        jlink.append('--dedup-legal-notices=error-if-not-same-content')
        jlink.append('--keep-packaged-modules=' + join(dst_jdk_dir, 'jmods'))

        # TODO: investigate the options below used by OpenJDK to see if they should be used:
        # --release-info: this allow extra properties to be written to the <jdk>/release file
        # --order-resources: specifies order of resources in generated lib/modules file.
        #       This is apparently not so important if a CDS archive is available.
        # --generate-jli-classes: pre-generates a set of java.lang.invoke classes.
        #       See https://github.com/openjdk/jdk/blob/master/make/GenerateLinkOptData.gmk
        mx.logv('[Creating JDK image]')
        mx.run(jlink)

        dst_src_zip = join(dst_jdk_dir, 'lib', 'src.zip')
        mx.logv('[Creating ' + dst_src_zip + ']')
        with ZipFile(dst_src_zip, 'w', compression=ZIP_DEFLATED, allowZip64=True) as zf:
            for name, contents in sorted(dst_src_zip_contents.items()):
                zf.writestr(name, contents)

        mx.logv('[Copying static libraries]')
        lib_prefix = mx.add_lib_prefix('')
        lib_suffix = '.lib' if mx.is_windows() else '.a'
        lib_directory = join(jdk.home, 'lib')
        dst_lib_directory = join(dst_jdk_dir, 'lib')
        for f in os.listdir(lib_directory):
            if f.startswith(lib_prefix) and f.endswith(lib_suffix):
                lib_path = join(lib_directory, f)
                if isfile(lib_path):
                    shutil.copy2(lib_path, dst_lib_directory)

        # Build the list of modules whose classes might have annotations
        # to be processed by native-image (GR-15192).
        with open(join(dst_jdk_dir, 'lib', 'native-image-modules.list'), 'w') as fp:
            print('# Modules whose classes might have annotations processed by native-image', file=fp)
            for m in modules:
                print(m.name, file=fp)

    finally:
        if not mx.get_opts().verbose:
            # Preserve build directory so that javac command can be re-executed
            # by cutting and pasting verbose output.
            shutil.rmtree(build_dir)

    # Create CDS archive (https://openjdk.java.net/jeps/341).
    out = mx.OutputCapture()
    mx.logv('[Creating CDS shared archive]')
    if mx.run([mx.exe_suffix(join(dst_jdk_dir, 'bin', 'java')), '-Xshare:dump', '-Xmx128M', '-Xms128M'], out=out, err=out, nonZeroIsFatal=False) != 0:
        mx.log(out.data)
        mx.abort('Error generating CDS shared archive')
 def config_entry(key, value):
     value_substitute = mx_subst.path_substitutions.substitute(value)
     if mx.is_windows():
         # cmake does not like backslashes
         value_substitute = value_substitute.replace("\\", "/")
     return '-D{}={}'.format(key, value_substitute)
Esempio n. 25
0
def _netbeansinit_project(p, jdks=None, files=None, libFiles=None, dists=None):
    dists = [] if dists is None else dists
    nb_dir = mx.ensure_dir_exists(join(p.dir))
    nbproject_dir = mx.ensure_dir_exists(join(nb_dir, 'nbproject'))

    jdk = mx.get_jdk(p.javaCompliance)
    assert jdk

    if jdks is not None:
        jdks.add(jdk)

    execDir = mx.primary_suite().dir

    out = mx.XMLDoc()
    out.open('project', {'name' : p.name, 'default' : 'default', 'basedir' : '.'})
    out.element('description', data='Builds, tests, and runs the project ' + p.name + '.')
    out.element('available', {'file' : 'nbproject/build-impl.xml', 'property' : 'build.impl.exists'})
    out.element('import', {'file' : 'nbproject/build-impl.xml', 'optional' : 'true'})
    out.element('extension-point', {'name' : '-mx-init'})
    out.element('available', {'file' : 'nbproject/build-impl.xml', 'property' : 'mx.init.targets', 'value' : 'init'})
    out.element('property', {'name' : 'mx.init.targets', 'value' : ''})
    out.element('bindtargets', {'extensionPoint' : '-mx-init', 'targets' : '${mx.init.targets}'})

    out.open('target', {'name' : '-post-init'})
    out.open('pathconvert', {'property' : 'comma.javac.classpath', 'pathsep' : ','})
    out.element('path', {'path' : '${javac.classpath}'})
    out.close('pathconvert')

    out.open('restrict', {'id' : 'missing.javac.classpath'})
    out.element('filelist', {'dir' : '${basedir}', 'files' : '${comma.javac.classpath}'})
    out.open('not')
    out.element('exists')
    out.close('not')
    out.close('restrict')

    out.element('property', {'name' : 'missing.javac.classpath', 'refid' : 'missing.javac.classpath'})

    out.open('condition', {'property' : 'no.dependencies', 'value' : 'true'})
    out.element('equals', {'arg1' : '${missing.javac.classpath}', 'arg2' : ''})
    out.close('condition')

    out.element('property', {'name' : 'no.dependencies', 'value' : 'false'})

    out.open('condition', {'property' : 'no.deps'})
    out.element('equals', {'arg1' : '${no.dependencies}', 'arg2' : 'true'})
    out.close('condition')

    out.close('target')
    out.open('target', {'name' : 'clean'})
    out.open('exec', {'executable' : sys.executable, 'failonerror' : 'true', 'dir' : execDir})
    out.element('env', {'key' : 'JAVA_HOME', 'value' : jdk.home})
    out.element('arg', {'value' : os.path.abspath(__file__)})
    out.element('arg', {'value' : 'clean'})
    out.element('arg', {'value' : '--projects'})
    out.element('arg', {'value' : p.name})
    out.close('exec')
    out.close('target')
    out.open('target', {'name' : 'compile'})
    out.open('exec', {'executable' : sys.executable, 'failonerror' : 'true', 'dir' : execDir})
    out.element('env', {'key' : 'JAVA_HOME', 'value' : jdk.home})
    out.element('arg', {'value' : os.path.abspath(__file__)})
    out.element('arg', {'value' : 'build'})
    dependsOn = p.name
    for d in dists:
        dependsOn = dependsOn + ',' + d.name
    out.element('arg', {'value' : '--only'})
    out.element('arg', {'value' : dependsOn})
    out.element('arg', {'value' : '--force-javac'})
    out.element('arg', {'value' : '--no-native'})
    out.element('arg', {'value' : '--no-daemon'})
    out.close('exec')
    out.close('target')
    out.open('target', {'name' : 'package', 'if' : 'build.impl.exists'})
    out.element('antcall', {'target': '-package', 'inheritall': 'true', 'inheritrefs': 'true'})
    out.close('target')
    out.open('target', {'name' : '-package', 'depends' : '-mx-init'})
    out.element('loadfile', {'srcFile' : join(p.suite.get_output_root(), 'netbeans.log'), 'property' : 'netbeans.log', 'failonerror' : 'false'})
    out.element('echo', {'message' : '...truncated...${line.separator}', 'output' : join(p.suite.get_output_root(), 'netbeans.log')})
    out.element('echo', {'message' : '${netbeans.log}'})
    for d in dists:
        if d.isDistribution():
            out.element('touch', {'file' : '${java.io.tmpdir}/' + d.name})
            out.element('echo', {'message' : d.name + ' set to now${line.separator}', 'append' : 'true', 'output' : join(p.suite.get_output_root(), 'netbeans.log')})
    out.open('copy', {'todir' : '${build.classes.dir}', 'overwrite' : 'true'})
    out.element('resources', {'refid' : 'changed.files'})
    out.close('copy')
    if len(p.annotation_processors()) > 0:
        out.open('copy', {'todir' : '${src.ap-source-output.dir}'})
        out.open('fileset', {'dir': '${cos.src.dir.internal}/../sources/'})
        out.element('include', {'name': '**/*.java'})
        out.close('fileset')
        out.close('copy')
    out.open('exec', {'executable' : '${ant.home}/bin/ant', 'spawn' : 'true'})
    out.element('arg', {'value' : '-f'})
    out.element('arg', {'value' : '${ant.file}'})
    out.element('arg', {'value' : 'packagelater'})
    out.close('exec')
    out.close('target')
    for d in dists:
        if d.isDistribution():
            out.open('target', {'name' : 'checkpackage-' + d.name})
            out.open('tstamp')
            out.element('format', {'pattern' : 'S', 'unit' : 'millisecond', 'property' : 'at.' + d.name})
            out.close('tstamp')
            out.element('touch', {'file' : '${java.io.tmpdir}/' + d.name, 'millis' : '${at.' + d.name + '}0000'})
            out.element('echo', {'message' : d.name + ' touched to ${at.' + d.name + '}0000${line.separator}', 'append' : 'true', 'output' : join(p.suite.get_output_root(), 'netbeans.log')})
            out.element('sleep', {'seconds' : '3'})
            out.open('condition', {'property' : 'mx.' + d.name, 'value' : sys.executable})
            out.open('islastmodified', {'millis' : '${at.' + d.name + '}0000', 'mode' : 'equals'})
            out.element('file', {'file' : '${java.io.tmpdir}/' + d.name})
            out.close('islastmodified')
            out.close('condition')
            out.element('echo', {'message' : d.name + ' defined as ' + '${mx.' + d.name + '}${line.separator}', 'append' : 'true', 'output' : join(p.suite.get_output_root(), 'netbeans.log')})
            out.close('target')
            out.open('target', {'name' : 'packagelater-' + d.name, 'depends' : 'checkpackage-' + d.name, 'if' : 'mx.' + d.name})
            out.open('exec', {'executable' : '${mx.' + d.name + '}', 'failonerror' : 'true', 'dir' : execDir, 'output' : join(p.suite.get_output_root(), 'netbeans.log'), 'append' : 'true'})
            out.element('env', {'key' : 'JAVA_HOME', 'value' : jdk.home})
            out.element('arg', {'value' : os.path.abspath(__file__)})
            out.element('arg', {'value' : 'build'})
            out.element('arg', {'value' : '-f'})
            out.element('arg', {'value' : '--only'})
            out.element('arg', {'value' : d.name})
            out.element('arg', {'value' : '--force-javac'})
            out.element('arg', {'value' : '--no-native'})
            out.element('arg', {'value' : '--no-daemon'})
            out.close('exec')
            out.close('target')
    dependsOn = ''
    sep = ''
    for d in dists:
        dependsOn = dependsOn + sep + 'packagelater-' + d.name
        sep = ','
    out.open('target', {'name' : 'packagelater', 'depends' : dependsOn})
    out.close('target')
    out.open('target', {'name' : 'jar', 'depends' : 'compile'})
    out.close('target')
    out.element('target', {'name' : 'test', 'depends' : 'run'})
    out.element('target', {'name' : 'test-single', 'depends' : 'run'})
    out.open('target', {'name' : 'run'})
    out.element('property', {'name' : 'test.class', 'value' : p.name})
    out.open('exec', {'executable' : sys.executable, 'failonerror' : 'true', 'dir' : execDir})
    out.element('env', {'key' : 'JAVA_HOME', 'value' : jdk.home})
    out.element('arg', {'value' : os.path.abspath(__file__)})
    out.element('arg', {'value' : 'unittest'})
    out.element('arg', {'value' : '${test.class}'})
    out.close('exec')
    out.close('target')
    out.element('target', {'name' : 'debug-test', 'depends' : 'debug'})
    out.open('target', {'name' : 'debug', 'depends' : '-mx-init'})
    out.element('property', {'name' : 'test.class', 'value' : p.name})
    out.open('nbjpdastart', {'addressproperty' : 'jpda.address', 'name' : p.name})
    out.open('classpath')
    out.open('fileset', {'dir' : '..'})
    out.element('include', {'name' : '*/bin/'})
    out.close('fileset')
    out.close('classpath')
    out.open('sourcepath')
    out.element('pathelement', {'location' : 'src'})
    out.close('sourcepath')
    out.close('nbjpdastart')
    out.open('exec', {'executable' : sys.executable, 'failonerror' : 'true', 'dir' : execDir})
    out.element('env', {'key' : 'JAVA_HOME', 'value' : jdk.home})
    out.element('arg', {'value' : os.path.abspath(__file__)})
    out.element('arg', {'value' : '-d'})
    out.element('arg', {'value' : '--attach'})
    out.element('arg', {'value' : '${jpda.address}'})
    out.element('arg', {'value' : 'unittest'})
    out.element('arg', {'value' : '${test.class}'})
    out.close('exec')
    out.close('target')
    out.open('target', {'name' : 'javadoc'})
    out.open('exec', {'executable' : sys.executable, 'failonerror' : 'true', 'dir' : execDir})
    out.element('env', {'key' : 'JAVA_HOME', 'value' : jdk.home})
    out.element('arg', {'value' : os.path.abspath(__file__)})
    out.element('arg', {'value' : 'javadoc'})
    out.element('arg', {'value' : '--projects'})
    out.element('arg', {'value' : p.name})
    out.element('arg', {'value' : '--force'})
    out.close('exec')
    out.element('nbbrowse', {'file' : 'javadoc/index.html'})
    out.close('target')
    out.close('project')
    mx.update_file(join(nb_dir, 'build.xml'), out.xml(indent='\t', newl='\n'))
    if files is not None:
        files.append(join(nb_dir, 'build.xml'))

    out = mx.XMLDoc()
    out.open('project', {'xmlns' : 'http://www.netbeans.org/ns/project/1'})
    out.element('type', data='org.netbeans.modules.java.j2seproject')
    out.open('configuration')
    out.open('data', {'xmlns' : 'http://www.netbeans.org/ns/j2se-project/3'})
    out.element('name', data=p.name)
    out.element('explicit-platform', {'explicit-source-supported' : 'true'})
    out.open('source-roots')
    out.element('root', {'id' : 'src.dir'})
    if len(p.annotation_processors()) > 0:
        out.element('root', {'id' : 'src.ap-source-output.dir', 'name' : 'Generated Packages'})
    out.close('source-roots')
    out.open('test-roots')
    out.close('test-roots')
    out.close('data')

    firstDep = []

    def processDep(dep, edge):
        if dep is p:
            return

        if dep.isProject():
            n = dep.name.replace('.', '_')
            if not firstDep:
                out.open('references', {'xmlns' : 'http://www.netbeans.org/ns/ant-project-references/1'})
                firstDep.append(dep)

            out.open('reference')
            out.element('foreign-project', data=n)
            out.element('artifact-type', data='jar')
            out.element('script', data='build.xml')
            out.element('target', data='jar')
            out.element('clean-target', data='clean')
            out.element('id', data='jar')
            out.close('reference') #pylint: disable=too-many-function-args
    p.walk_deps(visit=processDep, ignoredEdges=[mx.DEP_EXCLUDED])

    if firstDep:
        out.close('references')

    out.close('configuration')
    out.close('project')
    mx.update_file(join(nbproject_dir, 'project.xml'), out.xml(indent='    ', newl='\n'))
    if files is not None:
        files.append(join(nbproject_dir, 'project.xml'))

    out = StringIO()
    jdkPlatform = 'JDK_' + str(jdk.version)

    annotationProcessorEnabled = "false"
    annotationProcessorSrcFolder = ""
    annotationProcessorSrcFolderRef = ""
    if len(p.annotation_processors()) > 0:
        annotationProcessorEnabled = "true"
        mx.ensure_dir_exists(p.source_gen_dir())
        annotationProcessorSrcFolder = os.path.relpath(p.source_gen_dir(), nb_dir)
        annotationProcessorSrcFolder = annotationProcessorSrcFolder.replace('\\', '\\\\')
        annotationProcessorSrcFolderRef = "src.ap-source-output.dir=" + annotationProcessorSrcFolder

    canSymlink = not (mx.is_windows() or mx.is_cygwin()) and 'symlink' in dir(os)
    if canSymlink:
        nbBuildDir = join(nbproject_dir, 'build')
        apSourceOutRef = "annotation.processing.source.output=" + annotationProcessorSrcFolder
        if os.path.lexists(nbBuildDir):
            os.unlink(nbBuildDir)
        os.symlink(p.output_dir(), nbBuildDir)
    else:
        nbBuildDir = p.output_dir()
        apSourceOutRef = ""
    mx.ensure_dir_exists(p.output_dir())

    mx_ide_eclipse._copy_eclipse_settings(nb_dir, p)

    content = """
annotation.processing.enabled=""" + annotationProcessorEnabled + """
annotation.processing.enabled.in.editor=""" + annotationProcessorEnabled + """
""" + apSourceOutRef + """
annotation.processing.processors.list=
annotation.processing.run.all.processors=true
application.title=""" + p.name + """
application.vendor=mx
auxiliary.de-markiewb-netbeans-plugins-eclipse-formatter.eclipseFormatterActiveProfile=
auxiliary.de-markiewb-netbeans-plugins-eclipse-formatter.eclipseFormatterEnabled=true
auxiliary.de-markiewb-netbeans-plugins-eclipse-formatter.eclipseFormatterLocation=
auxiliary.de-markiewb-netbeans-plugins-eclipse-formatter.enableFormatAsSaveAction=true
auxiliary.de-markiewb-netbeans-plugins-eclipse-formatter.linefeed=
auxiliary.de-markiewb-netbeans-plugins-eclipse-formatter.preserveBreakPoints=true
auxiliary.de-markiewb-netbeans-plugins-eclipse-formatter.SaveActionModifiedLinesOnly=false
auxiliary.de-markiewb-netbeans-plugins-eclipse-formatter.showNotifications=false
auxiliary.de-markiewb-netbeans-plugins-eclipse-formatter.sourcelevel=
auxiliary.de-markiewb-netbeans-plugins-eclipse-formatter.useProjectPref=true
auxiliary.de-markiewb-netbeans-plugins-eclipse-formatter.useProjectSettings=true
auxiliary.de-markiewb-netbeans-plugins-eclipse-formatter.eclipseFormatterActiveProfile=
auxiliary.org-netbeans-spi-editor-hints-projects.perProjectHintSettingsEnabled=true
auxiliary.org-netbeans-spi-editor-hints-projects.perProjectHintSettingsFile=nbproject/cfg_hints.xml
build.classes.dir=${build.dir}
build.classes.excludes=**/*.java,**/*.form
# This directory is removed when the project is cleaned:
build.dir=""" + nbBuildDir + """
$cos.update=package
$cos.update.resources=changed.files
compile.on.save=true
build.generated.sources.dir=${build.dir}/generated-sources
# Only compile against the classpath explicitly listed here:
build.sysclasspath=ignore
build.test.classes.dir=${build.dir}/test/classes
build.test.results.dir=${build.dir}/test/results
# Uncomment to specify the preferred debugger connection transport:
#debug.transport=dt_socket
debug.classpath=\\
${run.classpath}
debug.test.classpath=\\
${run.test.classpath}
# This directory is removed when the project is cleaned:
dist.dir=dist
dist.jar=${dist.dir}/""" + p.name + """.jar
dist.javadoc.dir=${dist.dir}/javadoc
endorsed.classpath=
excludes=
includes=**
jar.compress=false
java.main.action=test
# Space-separated list of extra javac options
javac.compilerargs=-XDignore.symbol.file
javac.deprecation=false
javac.source=""" + str(p.javaCompliance) + """
javac.target=""" + str(p.javaCompliance) + """
javac.test.classpath=\\
${javac.classpath}:\\
${build.classes.dir}
javadoc.additionalparam=
javadoc.author=false
javadoc.encoding=${source.encoding}
javadoc.noindex=false
javadoc.nonavbar=false
javadoc.notree=false
javadoc.private=false
javadoc.splitindex=true
javadoc.use=true
javadoc.version=false
javadoc.windowtitle=
manifest.file=manifest.mf
meta.inf.dir=${src.dir}/META-INF
mkdist.disabled=false
platforms.""" + jdkPlatform + """.home=""" + jdk.home + """
platform.active=""" + jdkPlatform + """
run.classpath=\\
${javac.classpath}:\\
${build.classes.dir}
# Space-separated list of JVM arguments used when running the project
# (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value
# or test-sys-prop.name=value to set system properties for unit tests):
run.jvmargs=
run.test.classpath=\\
${javac.test.classpath}:\\
${build.test.classes.dir}
test.src.dir=./test
""" + annotationProcessorSrcFolderRef + """
source.encoding=UTF-8""".replace(':', os.pathsep).replace('/', os.sep)
    print(content, file=out)

    # Workaround for NetBeans "too clever" behavior. If you want to be
    # able to press F6 or Ctrl-F5 in NetBeans and run/debug unit tests
    # then the project must have its main.class property set to an
    # existing class with a properly defined main method. Until this
    # behavior is remedied, we specify a well known Truffle class
    # that will be on the class path for most Truffle projects.
    # This can be overridden by defining a netbeans.project.properties
    # attribute for a project in suite.py (see below).
    print("main.class=com.oracle.truffle.api.impl.Accessor", file=out)

    # Add extra properties specified in suite.py for this project
    if hasattr(p, 'netbeans.project.properties'):
        properties = getattr(p, 'netbeans.project.properties')
        for prop in [properties] if isinstance(properties, str) else properties:
            print(prop, file=out)

    mainSrc = True
    for src in p.srcDirs:
        srcDir = mx.ensure_dir_exists(join(p.dir, src))
        ref = 'file.reference.' + p.name + '-' + src
        print(ref + '=' + os.path.relpath(srcDir, nb_dir), file=out)
        if mainSrc:
            print('src.dir=${' + ref + '}', file=out)
            mainSrc = False
        else:
            print('src.' + src + '.dir=${' + ref + '}', file=out)

    javacClasspath = []

    def newDepsCollector(into):
        return lambda dep, edge: into.append(dep) if dep.isLibrary() or dep.isJdkLibrary() or dep.isProject() or dep.isClasspathDependency() else None

    deps = []
    p.walk_deps(visit=newDepsCollector(deps))
    annotationProcessorOnlyDeps = []
    if len(p.annotation_processors()) > 0:
        for apDep in p.annotation_processors():
            resolvedApDeps = []
            apDep.walk_deps(visit=newDepsCollector(resolvedApDeps))
            for resolvedApDep in resolvedApDeps:
                if not resolvedApDep in deps:
                    deps.append(resolvedApDep)
                    annotationProcessorOnlyDeps.append(resolvedApDep)

    annotationProcessorReferences = []

    for dep in deps:
        if dep == p:
            continue

        if dep.isLibrary() or dep.isJdkLibrary():
            if dep.isLibrary():
                path = dep.get_path(resolve=True)
                sourcePath = dep.get_source_path(resolve=True)
            else:
                path = dep.classpath_repr(jdk, resolve=True)
                sourcePath = dep.get_source_path(jdk)
            if path:
                if os.sep == '\\':
                    path = path.replace('\\', '\\\\')
                ref = 'file.reference.' + dep.name + '-bin'
                print(ref + '=' + path, file=out)
                if libFiles:
                    libFiles.append(path)
            if sourcePath:
                if os.sep == '\\':
                    sourcePath = sourcePath.replace('\\', '\\\\')
                print('source.reference.' + dep.name + '-bin=' + sourcePath, file=out)
        elif dep.isMavenProject():
            path = dep.get_path(resolve=False)
            if path:
                if os.sep == '\\':
                    path = path.replace('\\', '\\\\')
                ref = 'file.reference.' + dep.name + '-bin'
                print(ref + '=' + path, file=out)
        elif dep.isProject():
            n = dep.name.replace('.', '_')
            relDepPath = os.path.relpath(dep.dir, nb_dir).replace(os.sep, '/')
            if canSymlink:
                depBuildPath = join('nbproject', 'build')
            else:
                depBuildPath = 'dist/' + dep.name + '.jar'
            ref = 'reference.' + n + '.jar'
            print('project.' + n + '=' + relDepPath, file=out)
            print(ref + '=${project.' + n + '}/' + depBuildPath, file=out)
        elif dep.isJreLibrary():
            continue
        elif dep.isClasspathDependency():
            extra = [di for di in dep.deps if di not in deps]
            if dep.isDistribution() and dep.deps and not extra:
                # ignore distribution classpath dependencies that only contain other explicit depedencies
                continue
            path = dep.classpath_repr(resolve=True)
            sourcePath = dep.get_source_path(jdk) if hasattr(dep, 'get_source_path') else None
            if path:
                if os.sep == '\\':
                    path = path.replace('\\', '\\\\')
                ref = 'file.reference.' + dep.name + '-bin'
                print(ref + '=' + path, file=out)
                if libFiles:
                    libFiles.append(path)
                if sourcePath:
                    if os.sep == '\\':
                        sourcePath = sourcePath.replace('\\', '\\\\')
                    print('source.reference.' + dep.name + '-bin=' + sourcePath, file=out)

        if not dep in annotationProcessorOnlyDeps:
            javacClasspath.append('${' + ref + '}')
        else:
            annotationProcessorReferences.append('${' + ref + '}')

    print('javac.classpath=\\\n    ' + (os.pathsep + '\\\n    ').join(javacClasspath), file=out)
    print('javac.processorpath=' + (os.pathsep + '\\\n    ').join(['${javac.classpath}'] + annotationProcessorReferences), file=out)
    print('javac.test.processorpath=' + (os.pathsep + '\\\n    ').join(['${javac.test.classpath}'] + annotationProcessorReferences), file=out)

    mx.update_file(join(nbproject_dir, 'project.properties'), out.getvalue())
    out.close()

    if files is not None:
        files.append(join(nbproject_dir, 'project.properties'))

    for source in p.suite.netbeans_settings_sources().get('cfg_hints.xml'):
        with open(source) as fp:
            content = fp.read()
    mx.update_file(join(nbproject_dir, 'cfg_hints.xml'), content)

    if files is not None:
        files.append(join(p.dir, 'nbproject', 'cfg_hints.xml'))
Esempio n. 26
0
        dir_name='installer',
        license_files=[],
        third_party_license_files=[],
        dependencies=[],
        jar_distributions=['vm:INSTALLER'],
        support_distributions=['vm:INSTALLER_GRAALVM_SUPPORT'],
        launcher_configs=[
            mx_sdk_vm.LauncherConfig(
                destination="bin/<exe:gu>",
                jar_distributions=[],
                dir_jars=True,
                main_class="org.graalvm.component.installer.ComponentInstaller",
                build_args=[],
                # Please see META-INF/native-image in the project for custom build options for native-image
                is_sdk_launcher=True,
                custom_bash_launcher="mx.vm/gu" if mx.is_windows() else None,
            ),
        ],
    ))

mx_sdk_vm.register_graalvm_component(
    mx_sdk_vm.GraalVmComponent(
        suite=_suite,
        name='GraalVM license files',
        short_name='gvm',
        dir_name='.',
        license_files=['LICENSE.txt'],
        third_party_license_files=['3rd_party_licenses.txt'],
        dependencies=[],
        support_distributions=['vm:VM_GRAALVM_SUPPORT'],
    ))
Esempio n. 27
0
class DefaultNativeProject(NinjaProject):
    """A NinjaProject that makes many assumptions when generating a build manifest.

    It is assumed that:
        #. Directory layout is fixed:
            - `include` is a flat subdir containing public headers, and
            - `src` subdir contains sources and private headers.

        #. There is only one deliverable:
            - Kind is the value of the `native` attribute, and
            - Name is the value of the `deliverable` attribute if it is specified,
              otherwise it is derived from the `name` of the project.

        #. All source files are supported and necessary to build the deliverable.

        #. All `include_dirs` and `libs` provided by build dependencies are necessary
           to build the deliverable.

        #. The deliverable and the public headers are intended for distribution.

    Attributes
        native : {'static_lib', 'shared_lib'}
            Kind of the deliverable.

            Depending on the value, the necessary flags will be prepended to `cflags`
            and `ldflags` automatically.
        deliverable : str, optional
            Name of the deliverable. By default, it is derived from the `name` of the
            project.
    """
    include = 'include'
    src = 'src'

    _kinds = dict(
        static_lib=dict(target=lambda name: mx.add_lib_prefix(name) +
                        ('.lib' if mx.is_windows() else '.a'), ),
        shared_lib=dict(
            target=lambda name: mx.add_lib_suffix(mx.add_lib_prefix(name)), ),
        executable=dict(target=mx.exe_suffix, ),
    )

    def __init__(self, suite, name, subDir, srcDirs, deps, workingSets, d,
                 kind, **kwargs):
        self.deliverable = kwargs.pop('deliverable', name.split('.')[-1])
        if srcDirs:
            mx.abort(
                '"sourceDirs" is not supported for default native projects')
        srcDirs += [self.include, self.src]
        super(DefaultNativeProject,
              self).__init__(suite, name, subDir, srcDirs, deps, workingSets,
                             d, **kwargs)
        try:
            self._kind = self._kinds[kind]
        except KeyError:
            mx.abort('"native" should be one of {}, but "{}" is given'.format(
                list(self._kinds.keys()), kind))

        include_dir = mx.join(self.dir, self.include)
        if next(os.walk(include_dir))[1]:
            mx.abort('include directory must have a flat structure')

        self.include_dirs = [include_dir]
        if kind == 'static_lib':
            self.libs = [mx.join(self.out_dir, mx.get_arch(), self._target)]

    @property
    def _target(self):
        return self._kind['target'](self.deliverable)

    @property
    def cflags(self):
        default_cflags = []
        if self._kind == self._kinds['shared_lib']:
            default_cflags += dict(windows=['-MD'
                                            ], ).get(mx.get_os(), ['-fPIC'])

        if mx.is_linux() or mx.is_darwin():
            # Do not leak host paths via dwarf debuginfo
            def add_debug_prefix(prefix_dir):
                return '-fdebug-prefix-map={}={}'.format(
                    prefix_dir, mx.basename(prefix_dir))

            default_cflags += [add_debug_prefix(self.suite.vc_dir)]
            default_cflags += [add_debug_prefix(NinjaProject.get_jdk().home)]
            default_cflags += ['-gno-record-gcc-switches']

        return default_cflags + super(DefaultNativeProject, self).cflags

    @property
    def ldflags(self):
        default_ldflags = []
        if self._kind == self._kinds['shared_lib']:
            default_ldflags += dict(
                darwin=['-dynamiclib', '-undefined', 'dynamic_lookup'],
                windows=['-dll'],
            ).get(mx.get_os(), ['-shared', '-fPIC'])

        return default_ldflags + super(DefaultNativeProject, self).ldflags

    @property
    def h_files(self):
        return self._source['files'].get('.h', [])

    @property
    def c_files(self):
        return self._source['files'].get('.c', [])

    @property
    def cxx_files(self):
        return self._source['files'].get('.cc', [])

    @property
    def asm_sources(self):
        return self._source['files'].get('.S', [])

    def generate_manifest(self, path):
        unsupported_source_files = list(
            set(self._source['files'].keys()) - {'.h', '.c', '.cc', '.S'})
        if unsupported_source_files:
            mx.abort(
                '{} source files are not supported by default native projects'.
                format(unsupported_source_files))

        with NinjaManifestGenerator(self, open(path, 'w')) as gen:
            gen.comment('Project rules')
            cc = cxx = asm = None
            if self.c_files:
                cc = gen.cc_rule()
            if self.cxx_files:
                cxx = gen.cc_rule(cxx=True)
            if self.asm_sources:
                asm = gen.asm_rule() if mx.is_windows(
                ) else cc if cc else gen.cc_rule()

            ar = link = None
            if self._kind == self._kinds['static_lib']:
                ar = gen.ar_rule()
            else:
                link = gen.link_rule(cxx=bool(self.cxx_files))

            gen.variables(
                cflags=[
                    mx_subst.path_substitutions.substitute(cflag)
                    for cflag in self.cflags
                ],
                ldflags=[
                    mx_subst.path_substitutions.substitute(ldflag)
                    for ldflag in self.ldflags
                ] if link else None,
                ldlibs=self.ldlibs if link else None,
            )
            gen.include(
                collections.OrderedDict.fromkeys(
                    # remove the duplicates while maintaining the ordering
                    [mx.dirname(h_file) for h_file in self.h_files] + list(
                        itertools.chain.from_iterable(
                            getattr(d, 'include_dirs', [])
                            for d in self.buildDependencies))).keys())

            gen.comment('Compiled project sources')
            object_files = [cc(f) for f in self.c_files]
            gen.newline()
            object_files += [cxx(f) for f in self.cxx_files]
            gen.newline()
            object_files += [asm(f) for f in self.asm_sources]
            gen.newline()

            gen.comment('Project deliverable')
            if self._kind == self._kinds['static_lib']:
                ar(self._target, object_files)
            else:
                link(
                    self._target, object_files + list(
                        itertools.chain.from_iterable(
                            getattr(d, 'libs', [])
                            for d in self.buildDependencies)))

    def _archivable_results(self, target_arch, use_relpath, single):
        def result(base_dir, file_path):
            assert not mx.isabs(file_path)
            archive_path = file_path if use_relpath else mx.basename(file_path)
            return mx.join(base_dir, file_path), archive_path

        yield result(mx.join(self.out_dir, target_arch), self._target)

        if not single:
            for header in os.listdir(mx.join(self.dir, self.include)):
                yield result(self.dir, mx.join(self.include, header))
Esempio n. 28
0
    ],
    support_distributions=['vm:INSTALLER_GRAALVM_SUPPORT'],
    launcher_configs=[
        mx_sdk_vm.LauncherConfig(
            destination="bin/<exe:gu>",
            jar_distributions=[
                'vm:INSTALLER',
                'truffle:TruffleJSON'
            ],
            dir_jars=True,
            main_class="org.graalvm.component.installer.ComponentInstaller",
            link_at_build_time=False,
            build_args=gu_build_args,
            # Please see META-INF/native-image in the project for custom build options for native-image
            is_sdk_launcher=True,
            custom_launcher_script="mx.vm/gu.cmd" if mx.is_windows() else None,
        ),
    ],
    stability="supported",
))


mx_sdk_vm.register_graalvm_component(mx_sdk_vm.GraalVmComponent(
    suite=_suite,
    name='GraalVM license files',
    short_name='gvm',
    dir_name='.',
    license_files=['LICENSE.txt'],
    third_party_license_files=['THIRD_PARTY_LICENSE.txt'],
    dependencies=[],
    support_distributions=['vm:VM_GRAALVM_SUPPORT'],
Esempio n. 29
0
 def quote(path):
     return '"{}"'.format(path) if mx.is_windows() and (
         ' ' in path or
         ('$project' in path and ' ' in self.project.dir)) else path
Esempio n. 30
0
 def build(source_file):
     output = os.path.splitext(source_file)[0] + (
         '.obj' if mx.is_windows() else '.o')
     return self.n.build(output, rule, self._resolve(source_file))[0]