Giter Site home page Giter Site logo

graalvm / mx Goto Github PK

View Code? Open in Web Editor NEW
182.0 44.0 108.0 31.67 MB

Command-line tool used for the development of Graal projects.

License: GNU General Public License v2.0

Java 9.27% Shell 0.23% Batchfile 0.02% Python 88.22% Jsonnet 1.37% C 0.80% Starlark 0.09%

mx's Introduction

README

mx is a command line based tool for managing the development of (primarily) Java code. It includes a mechanism for specifying the dependencies as well as making it simple to build, test, run, update, etc the code and built artifacts. mx contains support for developing code spread across multiple source repositories. mx is written in Python and is extensible.

The organizing principle of mx is a suite. A suite is both a directory and the container for the components of the suite. A suite component is either a project, library or distribution. There are various flavors of each of these. A suite may import and depend on other suites. For an execution of mx, exactly one suite is the primary suite. This is either the suite in whose directory mx is executed or the value of the global -p mx option. The set of suites reachable from the primary suite by transitive closure of the imports relation form the set that mx operates on.

Running mx

mx can be run directly (i.e., python mx/mx.py ...), but is more commonly invoked via the mx/mx bash script. Adding the mx/ directory to your PATH simplifies executing mx. The mx/mx.cmd script should be used on Windows.

The general form of the mx command line is:

mx [global options] [command] [command-specific options]

If no options or command is specified, mx prints information on the available options and commands, which will include any suite-specific options and commands. Help for a specific command is obtained via mx help <command>. Global options are expected to have wide applicability to many commands and as such precede the command to be executed.

For an example of mx usage, see README.md.

Note: There is a Bash completion script for global options and commands, located in bash_completion directory. Install it for example by sourceing this script in your ~/.bashrc file. If used, a temporary file /tmp/mx-bash-completion-<project-path-hash> is created and used for better performance.

mx-honey provides richer completions for zsh users.

Suites

The definition of a suite and its components is in a file named suite.py in the mx metadata directory of the primary suite. This is the directory named mx.<suite name> in the suite's top level directory. For example, for the compiler suite, it is mx.compiler. The format of suite.py is JSON with the following extensions:

  • Python multi-line and single-quoted strings are supported
  • Python hash-prefixed comments are supported

Java projects

Java source code is contained in a project. Here's an example of two Graal compiler projects:

"jdk.graal.compiler.serviceprovider" : {
  "subDir" : "src",
  "sourceDirs" : ["src"],
  "dependencies" : ["JVMCI_SERVICES"],
  "checkstyle" : "jdk.graal.compiler.graph",
  "javaCompliance" : "8",
  "workingSets" : "API,Graal",
},

"jdk.graal.compiler.serviceprovider.jdk9" : {
  "subDir" : "src",
  "sourceDirs" : ["src"],
  "dependencies" : ["jdk.graal.compiler.serviceprovider"],
  "uses" : ["jdk.graal.compiler.serviceprovider.GraalServices.JMXService"],
  "checkstyle" : "jdk.graal.compiler.graph",
  "javaCompliance" : "9+",
  "multiReleaseJarVersion" : "9",
  "workingSets" : "API,Graal",
},

The javaCompliance attribute can be a single number (e.g. 8), the lower bound of a range (e.g. 8+) or a fixed range (e.g. 9..11). This attribute specifies the following information:

  • The maximum Java language level used by the project. This is the lower bound in a range. It is also used as the value for the -source and -target javac options when compiling the project.
  • The JDKs providing any internal JDK API used by the project. A project that does not use any internal JDK API should specify an open range (e.g. 8+). Otherwise, a JDK matching the exact version or range is required to compile the project.

The multiReleaseJarVersion attribute is explained in the "Versioning sources for different JDK releases" section below.

Java distributions

A distribution encompasses one or more Java projects and enables the class files and related resources from projects to be packaged into a jar file. If a distribution declares itself as a module (see Java modules support), a JMOD file will also be produced when the distribution is built. The path to the jar file for a distribution is given by mx paths <distribution name>. For example:

> mx paths GRAAL
/Users/dnsimon/graal/graal/compiler/mxbuild/dists/jdk11/graal.jar

When building the jar for a distribution, mx will create the layout for the jar in a directory that is a sibling of the distribution's jar path. For example:

├── graal.jar
├── graal.jar.files
│   ├── META-INF
│   └── org

For efficiency, the files under the *.files hierarchy will be symlinks where possible. On Windows, creating symlinks is a privileged operation and so if symlinks cannot be created, files are copied instead. There are plenty of internet resources describing how to elevate your privileges on Windows to enable symlinking (e.g. here).

Exploded builds

By default, mx will produce a jar for each distribution. If a distribution defines a module, the jar is further processed to make it a multi-release modular jar and a jmod file is also created. Creating the jar and jmod files increases build time. For faster development, it's possible to leave a distribution in its exploded form, a directory with the same layout as the jar structure. To work in this mode, set MX_BUILD_EXPLODED=true. Also, ensure that exactly one JDK is specified by the union of JAVA_HOME and EXTRA_JAVA_HOMES (required since there is no equivalent of multi-release jar support for directories).

Using MX_BUILD_EXPLODED=true is roughly equivalent to building the OpenJDK with make instead of make images.

Note that MX_BUILD_EXPLODED=true should not be used when building for deployment.

Java modules support

A distribution that has a moduleInfo attribute will result in a Java module being built from the distribution. The moduleInfo attribute must specify the name of the module and can include other parts of a module descriptor.

This is best shown with examples from Truffle and Graal:

Here is an extract from the definition of the TRUFFLE_API distribution which produces the org.graavm.truffle module:

"TRUFFLE_API" : {
    "moduleInfo" : {
        "name" : "org.graalvm.truffle",
        "requires" : [
            "static java.desktop"
        ],
        "exports" : [
            "com.oracle.truffle.api.nodes to jdk.graal.compiler",
            "com.oracle.truffle.api.impl to jdk.graal.compiler, org.graalvm.locator",
            "com.oracle.truffle.api to jdk.graal.compiler, org.graalvm.locator, com.oracle.graal.graal_enterprise",
            "com.oracle.truffle.api.object to jdk.graal.compiler, com.oracle.graal.graal_enterprise",
            "com.oracle.truffle.object to jdk.graal.compiler, com.oracle.graal.graal_enterprise",
        ],
        "uses" : [
          "com.oracle.truffle.api.TruffleRuntimeAccess",
          "java.nio.file.spi.FileTypeDetector",
          "com.oracle.truffle.api.impl.TruffleLocator",
        ],
    },
    ...
    "distDependencies" : [
        # These distributions must also have `moduleInfo` attributes and the corresponding
        # modules will be added to the set of `requires` for this module.
        "sdk:GRAAL_SDK"
    ],
}

The module-info.java created by mx from the above is:

module org.graalvm.truffle {
    requires java.base;
    requires static java.desktop;
    requires java.logging;
    requires jdk.unsupported;
    requires transitive org.graalvm.sdk;
    exports com.oracle.truffle.api to com.oracle.graal.graal_enterprise, jdk.graal.compiler, org.graalvm.locator;
    exports com.oracle.truffle.api.impl to jdk.graal.compiler, org.graalvm.locator;
    exports com.oracle.truffle.api.nodes to jdk.graal.compiler;
    exports com.oracle.truffle.api.object to com.oracle.graal.graal_enterprise, jdk.graal.compiler;
    exports com.oracle.truffle.object to com.oracle.graal.graal_enterprise, jdk.graal.compiler;
    uses com.oracle.truffle.api.TruffleRuntimeAccess;
    uses com.oracle.truffle.api.impl.TruffleLocator;
    uses com.oracle.truffle.api.object.LayoutFactory;
    uses java.nio.file.spi.FileTypeDetector;
    provides com.oracle.truffle.api.object.LayoutFactory with com.oracle.truffle.object.basic.DefaultLayoutFactory;
    provides org.graalvm.polyglot.impl.AbstractPolyglotImpl with com.oracle.truffle.polyglot.PolyglotImpl;
    // conceals: com.oracle.truffle.api.debug
    // conceals: com.oracle.truffle.api.debug.impl
    // conceals: com.oracle.truffle.api.dsl
    // conceals: com.oracle.truffle.api.frame
    // conceals: com.oracle.truffle.api.instrumentation
    // conceals: com.oracle.truffle.api.interop
    // conceals: com.oracle.truffle.api.interop.impl
    // conceals: com.oracle.truffle.api.io
    // conceals: com.oracle.truffle.api.library
    // conceals: com.oracle.truffle.api.object.dsl
    // conceals: com.oracle.truffle.api.profilesLayoutFactory
    // conceals: com.oracle.truffle.api.source
    // conceals: com.oracle.truffle.api.utilities
    // conceals: com.oracle.truffle.object.basic
    // conceals: com.oracle.truffle.polyglot
    // jarpath: /Users/dnsimon/hs/graal/truffle/mxbuild/dists/jdk11/truffle-api.jar
    // dist: TRUFFLE_API
    // modulepath: org.graalvm.sdk
}

The provides clauses are automatically derived from the META-INF/services/ directory in the distribution's jar file. The generation of the provides clauses can be modified by utilizing the ignoredServiceTypes attribute. Here is an extract from the definition of the TRUFFLE_NFI distribution, which prevents adding DefaultExportProvider and EagerExportProvider implementations to provides clauses.

"TRUFFLE_NFI" : {
    "moduleInfo" : {
        "name" : "com.oracle.truffle.truffle_nfi",
        "exports" : [
            "com.oracle.truffle.nfi.api",
            "com.oracle.truffle.nfi.backend.spi",
            "com.oracle.truffle.nfi.backend.spi.types",
            "com.oracle.truffle.nfi.backend.spi.util",
        ],
        "ignoredServiceTypes" : [
            "com.oracle.truffle.api.library.DefaultExportProvider",
            "com.oracle.truffle.api.library.EagerExportProvider",
        ],
    }
    ...
}

The GRAAL distribution shows how a single exports attribute can be used to specify multiple exports clauses:

"GRAAL" : {
    "moduleInfo" : {
        "name" : "jdk.graal.compiler",
        "exports" : [
            # Qualified exports of all packages in GRAAL to modules built from
            # ENTERPRISE_GRAAL and GRAAL_MANAGEMENT distributions
            "* to com.oracle.graal.graal_enterprise,jdk.graal.compiler.management",
        ],
        ...
    },
    ...
},

This results info a module-info.java as that contains qualified exports, a small subset of which are shown below:

module jdk.graal.compiler {
    ...
    exports jdk.graal.compiler.api.directives to com.oracle.graal.graal_enterprise, jdk.graal.compiler.management;
    exports jdk.graal.compiler.api.replacements to com.oracle.graal.graal_enterprise, jdk.graal.compiler.management;
    exports jdk.graal.compiler.api.runtime to com.oracle.graal.graal_enterprise, jdk.graal.compiler.management;
    exports jdk.graal.compiler.asm to com.oracle.graal.graal_enterprise, jdk.graal.compiler.management;
    exports jdk.graal.compiler.asm.aarch64 to com.oracle.graal.graal_enterprise, jdk.graal.compiler.management;
    exports jdk.graal.compiler.asm.amd64 to com.oracle.graal.graal_enterprise, jdk.graal.compiler.management;
    ...

The jars build for a distribution are in <suite>/mxbuild/dists/jdk*/. The modular jars are in the jdk<N> directories where N >= 9. There is a modular jar built for each JDK version denoted by the javaCompliance values of the distribution's constituent projects.

Specifying required modules

If a project with a Java compliance >= 9 uses a package from a module other than java.base, it must specify these additional modules with the requires attribute. For example:

"jdk.graal.compiler.hotspot.management.jdk11" : {
    ...
    "requires" : [
        "jdk.management"
    ],
    "javaCompliance" : "11+",
    ...
},

The requires attribute is used for two purposes:

  • As input to the requires attribute of the descriptor for the module encapsulating the project.
  • To derive a value for the --limit-modules javac option which restricts the modules observable during compilation. This is required to support separate compilation of projects that are part of a JDK module. For example, jdk.graal.compiler.hotspot.amd64 depends on jdk.graal.compiler.hotspot and the classes of both these projects are contained in the jdk.graal.compiler module. When compiling jdk.graal.compiler.hotspot.amd64, we must compile against classes in jdk.graal.compiler.hotspot as they might be different (i.e., newer) than the classes in jdk.graal.compiler. The value of --limit-modules will omit jdk.graal.compiler in this case to achieve this hiding. In the absence of a requires attribute, only the java.base module is observable when compiling on JDK 9+.

Use of concealed packages

Concealed packages are those defined by a module but not exported by the module. If a project uses concealed packages, it must specify a requiresConcealed attribute denoting the concealed packages it accesses. For example:

"jdk.graal.compiler.lir.aarch64.jdk11" : {
    "requiresConcealed" : {
        "jdk.internal.vm.ci" : [
            "jdk.vm.ci.aarch64",
            "jdk.vm.ci.code",
        ],
    },
    "javaCompliance" : "11+",
},

This will result in --add-exports=jdk.internal.vm.ci/jdk.vm.ci.aarch64=ALL-UNNAMED and --add-exports=jdk.internal.vm.ci/jdk.vm.ci.code=ALL-UNNAMED being added to the javac command line when the jdk.graal.compiler.lir.aarch64.jdk11 project is compiled by a JDK 9+ javac.

Note that the requires and requiresConcealed attributes only apply to projects with a minimum javaCompliance value of 9 or greater. When javac from jdk 9+ is used in conjunction with -source 8 (as will be the case for projects with a minimum javaCompliance of 8 or less), all classes in the JDK are observable. However, if an 8 project would need a requires or requiresConcealed attribute were it a 9+ project, then these attributes must be applied to any module containing the project. For example, jdk.graal.compiler.serviceprovider has "javaCompliance" : "8+" and contains code that imports sun.misc.Unsafe. Since jdk.graal.compiler.serviceprovider is part of the jdk.graal.compiler module defined by the GRAAL distribution, GRAAL must include a requires attribute in its moduleInfo attribute:

"GRAAL" : {
    "moduleInfo" : {
        "name" : "jdk.graal.compiler",
        "requires" : ["jdk.unsupported"],
        ...
    }
}

Modules can be removed from the JDK. For example, JDK-8255616 removed the jdk.aot, jdk.internal.vm.compiler and jdk.internal.vm.compiler.management modules from standard JDK binaries as of JDK 16. Any requiresConcealed attributes targeting these modules must use a Java compliance qualifier so that the relevant sources can still be built on JDK 16:

"com.oracle.svm.enterprise.jdk11.test": {
    ...
    "requiresConcealed": {
        "[email protected]": [
            "jdk.graal.compiler.serviceprovider"
        ],
        ...
    }
}

As shown above, a module name in a requiresConcealed attribute can be qualified by appending @ followed by a valid Java compliance specifier. Such a module will be ignored if the JDK version used to compile the sources is not matched by the specified Java compliance. This also works for the regular requires attribute. E.g.

    "requires": [
        ...
        "[email protected]",
    ],
    ...

is needed to ensure that a given module requires module jdk.scripting.nashorn only when the specified compliance matches.

Selecting JDKs

Specifying JDKs to mx is done via the --java-home and --extra-java-homes options or via the JAVA_HOME and EXTRA_JAVA_HOMES environment variables. An option has precedence over the corresponding environment variable. Mx comes with a select_jdk.py helper that simplifies switching between different values for JAVA_HOME and EXTRA_JAVA_HOMES.

Install a JDK with fetch-jdk

The mx fetch-jdk command can download and install JDKs defined in JSON files. See mx fetch-jdk --help for more detail.

Generated artifacts

The build artifacts of mx are in directories separate from the source file directories. Output for platform dependent suite constituents is under a directory whose name reflects the current platform. For example:

<suite>/mxbuild/<project>               # Platform independent project
<suite>/mxbuild/darwin-amd64/<project>  # Platform dependent project

Partitioning build output to take the platform into account has the following advantages:

  • A file system shared between different platforms (e.g. via NFS or virtualization host/guest file system sharing) keeps its platform dependent output separated.

Unless MX_OUTPUT_ROOT_INCLUDES_CONFIG=false then:

  • The output for JDK dependent suite constituents is under a directory reflecting the JDK(s) specified by JAVA_HOME and EXTRA_JAVA_HOMES.
  • The output for platform and JDK dependent suite constituents is under a directory reflecting both the platform and JDKs.

For example:

<suite>/mxbuild/jdk16+8/<project>               # JDK dependent project
<suite>/mxbuild/darwin-amd64/<project>          # Platform dependent project
<suite>/mxbuild/darwin-amd64-jdk16+8/<project>  # Platform and JDK dependent project

Partitioning build output to take JDK configuration into account has the following advantages:

  • Avoids re-compilation after changing the value of JAVA_HOME or EXTRA_JAVA_HOMES in the case where no sources have changed since mx build was last executed with the new values.
  • Avoid issues related to API changes between JDK versions. If only public JDK API was used by Java projects, this could be solved with the --release option introduced by JEP 247. However, a significant number of mx managed projects use JDK internal API in which case --release does not help.

Note that IDE configurations ignore MX_OUTPUT_ROOT_INCLUDES_CONFIG and so must be regenerated after changing the value of JAVA_HOME or EXTRA_JAVA_HOMES if you want output generated by an IDE to be visible to subsequent mx commands.

The JDK configuration dependent layout of build artifacts is best shown by an example. Consider the following directory tree containing graal and truffleruby repositories where graal defines the suites compiler, truffle and sdk and truffleruby defines a single truffleruby suite:

ws
├── graal
│   ├── compiler
│   ├── sdk
│   └── truffle
└── truffleruby

With this layout when working on macOS with $JAVA_HOME set to a JDK 8 and $EXTRA_JAVA_HOMES set to a JDK 16, after running mx build, the layout will be:

ws
├── graal
│   ├── compiler
│   │   └── mxbuild
│   │       ├── darwin-amd64
│   │       │   └── <project>
│   │       └── jdk8+16
│   │           └── <project>
│   ├── sdk
│   │   └── mxbuild
│   │       ├── darwin-amd64
│   │       │   └── <project>
│   │       └── jdk8+16
│   │           └── <project>
│   └── truffle
│       └── mxbuild
│           ├── darwin-amd64
│           │   └── <project>
│           └── jdk8+16
│               └── <project>
└── truffleruby
    └── mxbuild
        ├── darwin-amd64
        │   └── <project>
        └── jdk8+16
            └── <project>

Unit testing with Junit

The unittest command supports running Junit tests in mx suites.

The unit test harness will use any org.junit.runner.notification.RunListener objects available via java.util.ServiceLoader.load().

Executing tests on JDK 9 or later can be complicated if the tests access packages that are publicly available in JDK 8 or earlier but are not public as of JDK 9. That is, the packages are concealed by their declaring module. Such tests can be compiled simply enough by specifying their Java compliance as "1.8=". Running the tests on JDK 9 however requires that the concealed packages are exported to the test classes. To achieve this, an AddExports annotation should be applied to the test class requiring the export or to any of its super classes or super interfaces. To avoid the need for a dependency on mx, unittest harness simply looks for an annotation named AddExports that matches the following definition:

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * Specifies packages concealed in JDK modules used by a test. The mx unit test runner will ensure
 * the packages are exported to the module containing annotated test class.
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface AddExports {
    /**
     * The qualified name of the concealed package(s) in {@code <module>/<package>} format (e.g.,
     * "jdk.vm.ci/jdk.vm.ci.code").
     */
    String[] value() default "";
}

Coverage testing with JaCoCo

To enable code coverage testing with JaCoCo, the JaCoCo agent needs to be injected through VM command line arguments. For this, mx provides the convenience method mx_gate.get_jacoco_agent_args() which returns a list of those arguments if coverage is requested (e.g. by using mx gate --jacocout ...), otherwise None. Here is an example how it is used to enable coverage testing of the sources of the Graal compiler. Running code with the JaCoCo agent enabled outputs a jacoco.exec which can be converted into an HTML or CSV report with the mx jacocoreport command.

The packages or classes to be included in the JaCoCo report can be customized by importing mx_gate and using the helper functions:

  • add_jacoco_includes (adds one or more package patterns to the list of packages to include in the report)
  • add_jacoco_excludes (adds one or more package patterns to the list of packages to exclude from the report)
  • add_jacoco_excluded_annotations (adds one or more annotations to the list of annotations that will cause a class to be excluded from the report)

The include patterns can include an explicit trailing .* wildcard match. The exclude patterns have an implicit trailing wildcard match. Annotation names added to the annotation exclusion list must start with an @ character.

As an example from mx_compiler.py:

mx_gate.add_jacoco_includes(['org.graalvm.*'])
mx_gate.add_jacoco_excludes(['com.oracle.truffle.*'])
mx_gate.add_jacoco_excluded_annotations(['@Snippet', '@ClassSubstitution'])

This adds classes from packages starting with org.graalvm to the report, excludes classes in packages startng with com.oracle.truffle and also excludes classes annotated with @Snippet and @ClassSubstitution.

To omit excluded classes from the JaCoCo data and report use the gate option --jacoco-omit-excluded.

Versioning sources for different JDK releases

Mx includes support for multiple versions of a Java class. The mechanism is inspired by and similar to multi-release jars. A versioned Java class has a base version and one or more versioned copies. The public signature of each copy (i.e., methods and fields accessed from outside the source file) must be identical. Note that the only API that is visible from the JAR is the one from the base version.

Versioned classes for JDK 9 or later need to be in a project with a javaCompliance greater than or equal to 9 and a multiReleaseJarVersion attribute whose value is also greater or equal to 9. The versioned project must have the base project as a dependency.

Versioned classes for JDK 8 or earlier need to be in a project with a javaCompliance less than or equal to 8 and an overlayTarget attribute denoting the base project.

Profiling with proftool

Mx includes proftool, a utility for capturing and examining profiles of Java programs. Further details are here.

URL rewriting

Mx includes support for the primary suite to be able to override the source URLs of imported suites. The suite level urlrewrites attribute allows regular expression URL rewriting, and, optionally, digest rewriting. For example:

  "urlrewrites" : [
    {
      "https://git.acme.com/(.*).git" : {
        "replacement" : r”https://my.company.com/foo-git-cache/\1.git",
        "digest" : "sha1:da39a3ee5e6b4b0d3255bfef95601890afd80709",
      }
    },
    {
      "https://hg.acme.com/(.*)" : {
        "replacement" : r”https://my.company.com/foo-hg-cache/\1",
      }
    }
  ],

The rules are applied in definition order. Only rewrite rules from the primary suite are used meaning a suite may have to replicate the rewrite rules of its suite dependencies. This allows the primary suite to retain full control over where its dependencies are sourced from.

Rewrite rules can also be specified by the MX_URLREWRITES environment variable. The value of this variable must either be a JSON object describing a single rewrite rule, a JSON array describing a list of rewrite rules or a file containing one of these JSON values. Rewrites rules specified by MX_URLREWRITES are applied after rules specified by the primary suite.

IDE configuration generation

Mx supports generating IDE configurations using the mx ideinit command. There are also specific commands that generate configurations for Eclipse (mx eclipseinit), Netbeans (mx netbeansinit) or IntelliJ (mx intellijinit) individually. Please see here for details.

Environment variable processing

Suites might require various environment variables to be defined for the suite to work and mx provides env files to cache this information for a suite. Each suite can have an env file in suite/mx.suite/env and a default env file can be provided for the user in ~/.mx/env. Env files are loaded in the following order and override any value provided by the shell environment.

  1. ~/.mx/env is loaded first.

  2. The primary suite's env file is loaded before loading of the suites begins.

  3. The env files of any subsuites are loaded in a depth first fashion such that subsuite env files are loaded before their dependents.

  4. The primary suite's env file is reloaded so that it overrides any definitions provided by subsuites.

The -v option to mx will show the loading of env files during suite parsing.

Multiple suites per repository

Sometimes it might be convenient to group multiple suites inside a single repository. In particular, this helps ensure that all these suites are synchronized and tested together.

  • A suite inside a 'big repo' must be in a directory that has the same name as the suite
  • If you depend on a suite that is inside a 'big repo', you have to set subdir to True in the suite import.
  • If you depend on a suite that is in the same 'big repo' as the current suite, you should not specify urls in the suite import.
  • In order to sclone something that is inside a 'big repo' you have to use the --subdir argument for sclone which tells in which directory the suite that you want to clone is
  • In order to dynamically import a suite that is inside a 'big repo' you have to use --dynamicimport bigrepo/suite (e.g., --dynamicimport graal-enterprise/substratrevm)

Note that a suite in a "big repo" should not have a dependency to a suite in a different repository that in turn has a transitive dependency to the same "big repo". In other words, there should be no back-and-forth to the same repo.

Preview features

Java projects may use language or runtime features which are considered preview features in certain Java versions, in which case preview features must be enabled for compilation (--enable-preview). This is specified using the javaPreviewNeeded attribute, which is a version specification in the same format as javaCompliance, for example: "javaPreviewNeeded": "19..20" If the compiling JDK matches that version or version range, preview features are enabled for compilation. Given that javac and the JVM must be on the same JDK version for preview features (see here for details), compiling a project with preview features will force the javac -source and -target options to N where N is the minimum of:

  • the version of the JDK being used for compilation (i.e. JAVA_HOME) and
  • the lowest version where --enable-preview is not needed.

The following table of examples should make this clearer:

JDK javaPreviewNeeded -target / -source --enable-preview
19 19+ 19 Yes
20 19+ 20 Yes
20 19 20 No
21 19 20 No
22 20 21 No
22 19..20 21 No

System dependent configuration

A project can specify system dependent configuration options depending on which operating system and architecture are in use. The following example shows how the bar property can be set to A on Windows and B on all other operating systems.

"project" : {
  "foo" : "A",
  "os" : {
    "windows" : {
      "bar" : "A"
    },
    "<others>" : {
      "bar" : "B"
    }
  }
}

Commonly supported operating system names are darwin, linux and windows. The <others> value can be used as a wildcard to match any other operating system. A warning is emitted if no operating system is matched.

The arch property can be used to alter the configuration depending on which system architecture is used. Common examples of examples of system architectures are amd64 and aarch64. The following example shows how the bar property can be set to A on amd64 and to B on all other platforms.

"project" : {
  "foo" : "A",
  "arch" : {
    "amd64" : {
      "bar" : "A"
    },
    "<others>" : {
      "bar" : "B"
    }
  }
}

Configuration options that should depend on both the operating system and the architecture value can be specified using the os_arch property as follows. The following configuration example sets the property bar to A on amd64 linux systems, and to B for all other systems.

"project" : {
  "foo" : "A",
  "os_arch" : {
    "linux" : {
      "amd64" : {
        "bar" : "A"
      },
      "<others>" : {
        "bar" : "B"
      }
    },
    "<others>" : {
      "<others>" : {
        "bar" : "B"
      }
    }
  }
}

It is only possible to specify one of either the os, arch or os_arch options for any project.

Type hints

Code in MX should make a best effort case to include typing information wherever it would otherwise not immediately be clear. Typing information should be compatible with the currently supported Python version. Typing information for built-in types can be taken from the typing package. Where required, __future__ may be imported from the annotations package.

Helpful links:

mx's People

Contributors

ansalond avatar axel22 avatar boris-spas avatar chumer avatar cosminbasca avatar dougxc avatar eregon avatar farquet avatar fniephaus avatar gilles-duboscq avatar imanemamri avatar jirkamarsik avatar lazar-mitrovic avatar lewurm avatar mukel avatar olpaw avatar patrick96 avatar pecimuth avatar pejovica avatar peter-hofer avatar rschatz avatar rudihorn avatar soufianenassih avatar steve-s avatar timfel avatar tkrodriguez avatar tzezula avatar vjovanov avatar woess avatar zapster avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mx's Issues

lack of .git directories results in: AttributeError: 'NoneType' object has no attribute 'parent'

At Twitter our CI system builds from a source bundle which doesn't include .git directories. This has already been an issue a couple times in the past and now again with version 5.86.0:

Traceback (most recent call last):
  File "/Users/cthalinger/jvmci-0.24/mx/mx.py", line 15308, in <module>
    main()
  File "/Users/cthalinger/jvmci-0.24/mx/mx.py", line 15216, in main
    _init_primary_suite(PrimarySuite(primarySuiteMxDir, load=not vc_command))
  File "/Users/cthalinger/jvmci-0.24/mx/mx.py", line 7265, in __init__
    SourceSuite.__init__(self, mxDir, primary=True, load=load, importing_suite=None)
  File "/Users/cthalinger/jvmci-0.24/mx/mx.py", line 6878, in __init__
    self._init_imports()
  File "/Users/cthalinger/jvmci-0.24/mx/mx.py", line 6406, in _init_imports
    suite_import = SuiteImport.parse_specification(import_dict, context=self, importer_version=self.version(), dynamicImport=self.dynamicallyImported, importer_in_subdir=self.dir != self.vc_dir)
  File "/Users/cthalinger/jvmci-0.24/mx/mx.py", line 6888, in version
    return self.vc.parent(self.vc_dir, abortOnError=abortOnError)
AttributeError: 'NoneType' object has no attribute 'parent'

Support embedded snippets in Truffle

There is a discussion in oracle/graal#19 to improve co-location of code snippets to the API that they describe. There are few needed changes in mx to make to current proposal functional:

  • upgrade to new version of the doclet (once released)
  • add additional parameters to javadoc to specify pattern for files that contain the snippets
    -- in Truffle they contain letters Snippets
  • filter out these files from final JARs

Here is the diff that achieves all of that. Can you please tell me how to polish it to be ready for integration into mx repository? Thanks.

diff --git a/mx.mx/suite.py b/mx.mx/suite.py                                                                                                                                                            
index 679dc5b..b9afd6e 100644                                                                                                                                                                           
--- a/mx.mx/suite.py
+++ b/mx.mx/suite.py
diff --git a/mx.mx/suite.py b/mx.mx/suite.py
index 679dc5b..b9afd6e 100644
--- a/mx.mx/suite.py
+++ b/mx.mx/suite.py
@@ -31,9 +31,9 @@ suite = {

     "CODESNIPPET-DOCLET" : {
       "urls" : [
-        "http://repo1.maven.org/maven2/org/apidesign/javadoc/codesnippet-doclet/0.7/codesnippet-doclet-0.7.jar",
+        "file:///home/devel/.m2/repository/org/apidesign/javadoc/codesnippet-doclet/1.0-SNAPSHOT/codesnippet-doclet-1.0-SNAPSHOT.jar",
       ],
-      "sha1" : "28aaf1920d83e1e7d994c50cd23576ef93195434",
+      "sha1" : "fbf655c3f3abdd3d10970f0c5ecf062b6c3c7dc8",
     },

     "JUNIT" : {
diff --git a/mx.py b/mx.py
index 9ae0f6b..99fc75c 100755
--- a/mx.py
+++ b/mx.py
@@ -964,6 +964,8 @@ class JARDistribution(Distribution, ClasspathDependency):
                                         services.setdefault(service, []).extend([provider.strip() for provider in fp.readlines()])
                             else:
                                 for f in files:
+                                    if ('Snippets' in f):
+                                        continue
                                     arcname = join(relpath, f).replace(os.sep, '/')
                                     with open(join(root, f), 'rb') as fp:
                                         contents = fp.read()
@@ -10521,6 +10523,7 @@ def javadoc(args, parser=None, docDir='javadoc', includeDeps=True, stdDoclet=Tru
                      '-doclet', 'org.apidesign.javadoc.codesnippet.Doclet',
                      '-docletpath', snippetslib,
                      '-snippetpath', snippets,
+                     '-snippetclasses', '.*Snippets.*',
                      '-source', str(jdk.javaCompliance)] +
                      jdk.javadocLibOptions([]) +
                      ([] if jdk.javaCompliance < JavaCompliance('1.8') else ['-Xdoclint:none']) +
@@ -10617,6 +10620,7 @@ def javadoc(args, parser=None, docDir='javadoc', includeDeps=True, stdDoclet=Tru
              '-doclet', 'org.apidesign.javadoc.codesnippet.Doclet',
              '-docletpath', snippetslib,
              '-snippetpath', snippets,
+             '-snippetclasses', '.*Snippets.*',
              '-sourcepath', sp] +
              ([] if jdk.javaCompliance < JavaCompliance('1.8') else ['-Xdoclint:none']) +
              (['-overview', overviewFile] if exists(overviewFile) else []) +

mx.py uses os.symlink, which is not supported on Windows

For instance, when running mx build in the graal/vm suite (and after working around oracle/graal#795) I get the error:

Traceback (most recent call last):
  File "J:\Projects\mx\mx.py", line 18829, in <module>
    main()
  File "J:\Projects\mx\mx.py", line 18810, in main
    retcode = c(command_args)
  File "J:\Projects\mx\mx_commands.py", line 132, in __call__
    return self.command_function(*args, **kwargs)
  File "J:\Projects\mx\mx.py", line 12626, in build
    t.execute()
  File "J:\Projects\mx\mx.py", line 905, in execute
    self.build()
  File "J:\Projects\graal\vm\mx.vm\mx_vm.py", line 437, in build
    super(GraalVmLayoutDistributionTask, self).build()
  File "J:\Projects\mx\mx.py", line 1897, in build
    self.subject.make_archive()
  File "J:\Projects\mx\mx.py", line 2561, in make_archive
    self._install_source(source, output, destination, arc)
  File "J:\Projects\mx\mx.py", line 2514, in _install_source
    add_symlink(destination, link_target, absolute_destination, clean_destination)
  File "J:\Projects\mx\mx.py", line 2317, in add_symlink
    os.symlink(src, abs_dest)
AttributeError: 'module' object has no attribute 'symlink'
java.net.SocketException: Connection reset
        at java.net.SocketInputStream.read(SocketInputStream.java:210)
        at java.net.SocketInputStream.read(SocketInputStream.java:141)
        at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
        at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
        at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
        at java.io.InputStreamReader.read(InputStreamReader.java:184)
        at java.io.BufferedReader.fill(BufferedReader.java:161)
        at java.io.BufferedReader.readLine(BufferedReader.java:324)
        at java.io.BufferedReader.readLine(BufferedReader.java:389)
        at com.oracle.mxtool.compilerserver.CompilerDaemon$Connection.run(CompilerDaemon.java:137)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:748)

Which is originating from mx.py.

The problem seems to be that os.symlink is not supported on Windows, at least not before python 3.2 it seems.

Stack Overflow offers some workarounds [1], which I've tested and they seem to work, but later cause problems when trying to use os.unlink on the created links.

[1] : https://stackoverflow.com/a/15043806

`startswith` matching of annotated commands limits options for new commands

The following code segment (from https://github.com/graalvm/mx/blob/master/mx.py#L18557):

    initial_command = _argParser.initialCommandAndArgs[0] if len(_argParser.initialCommandAndArgs) > 0 else None
    if initial_command and initial_command not in _commands:
        hits = [c for c in _commands.iterkeys() if c.startswith(initial_command)]
        if len(hits) == 1:
            initial_command = hits[0]

    is_suite_context_free = initial_command and initial_command in _suite_context_free
    should_discover_suites = not is_suite_context_free and not (initial_command and initial_command in _no_suite_discovery)
    should_load_suites = should_discover_suites and not (initial_command and initial_command in _no_suite_loading)
    is_optional_suite_context = not initial_command or initial_command in _optional_suite_context

forbids the use of commands with names such as test, up, etc. Actually any command that happens to be a prefix of an annotated built-in command. (and as the number of such commands grows, the restrictions become more and more)

I understand that it is simple to work-around this issue by using a different name for the commands in conflict, but I believe it is better to be less restrictive. Maybe avoiding the startswith matching would be enough.

Note: This also breaks backwards compatibility since mx test used to work fine before 5.177.1 but breaks with 5.177.1.

`mx igv` does not recognize java homes as right version.

When running mx igv on the graal/compiler suite I get this error:

PS J:\Projects\graal\compiler> mx igv
Could not find a JDK (< 1.8.0u20 or >= 1.8.0u40) and < 11 for running IGV
The following JDKs are available:
  C:\Program Files\Java\jdk-10
  C:\Program Files\Java\jdk-9.0.4
  C:\Program Files\Java\jdk1.8.0_144
  C:\Program Files\Java\jdk1.8.0_162
Specify one with the --java-home or --extra-java-homes option or with the JAVA_HOME or EXTRA_JAVA_HOMES environment variable.
Or run `J:\Projects\mx/select_jdk.py -p J:\Projects\graal\compiler` to set and persist these variables in J:\Projects\graal\compiler\mx.compiler\env.

It looks to me like I have several usable Java installations, but for some reason they are not being picked up.

Retrying with e.g. --java-home 'C:\Program Files\Java\jdk-10' throws the same error.

mx requires Mercurial and Git

When building in Jenkins we noticed this:

WARNING: no hg executable found
  File "/Users/cthalinger/mx/mx.py", line 14243, in <module>
    main()
  File "/Users/cthalinger/mx/mx.py", line 14121, in main
    _src_suitemodel.set_primary_dir(dirname(primarySuiteMxDir))
  File "/Users/cthalinger/mx/mx.py", line 5430, in set_primary_dir
    self._suiteRootDir = SuiteModel.siblings_dir(d)
  File "/Users/cthalinger/mx/mx.py", line 5400, in siblings_dir
    _, primary_vc_root = VC.get_vc_root(suite_dir)
  File "/Users/cthalinger/mx/mx.py", line 3235, in get_vc_root
    root = vcs.root(directory, abortOnError=False)
  File "/Users/cthalinger/mx/mx.py", line 3946, in root
    self.check_for_hg()
  File "/Users/cthalinger/mx/mx.py", line 3643, in check_for_hg
    abort(self.missing)
  File "/Users/cthalinger/mx/mx.py", line 9029, in abort
    traceback.print_stack()
no hg executable found

mx shouldn't require Mercurial when all your repositories are Git ones.

checkstyle version bound tightly with mx version

Updating the mx version sometimes enforces an update checkstyle version on the user. This leads to a lot of gate failures since things work differently in newer checkstyle version. Why is the checkstyle version bound to the mx version? Isn't this a user setting that should be configurable in suite.py of the corresponding suite? Then, every suite can decide on its own when to switch to a different checkstyle version and to which version to switch to.

Testing mx?

Hello,

I have been fiddling around with a local copy of mx to see what it would take to port to python 3. But testing that the code I've written actually works is tricky, since python is lazily evaluated/parsed.

I'm wondering if there is a test suite for mx? I thought the mx repo was itself an mx suite and would have some tests in there, but running mx unittest from the repo root just freezes my shell (might be a side effect of the changes though...). I'm still figuring out how things fit together.

So, what is the way I should test changes to mx locally?

limit number of parallel builds

It looks like mx either parallelizes the build up to the available number of cpus or doesn't parallelize at all (-n option). It would be great if mx build would support a -j option that allows a user to explicitly specify the level of parallelism.

JaCoCo Code Coverage broken in 5.187.0

c0d2274 by @zapster has introduced changes that let coverage testing fail on our CI servers when mx 5.187.0 is used. Example error:

java.lang.instrument.IllegalClassFormatException: Error while instrumenting class MyClass.
	at org.jacoco.agent.rt.internal_8ff85ea.CoverageTransformer.transform(CoverageTransformer.java:93)
	at sun.instrument.TransformerManager.transform(TransformerManager.java:188)
	at sun.instrument.InstrumentationImpl.transform(InstrumentationImpl.java:428)
	at java.lang.ClassLoader.defineClass1(Native Method)
	at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
	at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
	at java.net.URLClassLoader.defineClass(URLClassLoader.java:467)
	at java.net.URLClassLoader.access$100(URLClassLoader.java:73)
	at java.net.URLClassLoader$1.run(URLClassLoader.java:368)
	at java.net.URLClassLoader$1.run(URLClassLoader.java:362)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.net.URLClassLoader.findClass(URLClassLoader.java:361)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
	at java.lang.ClassLoader.defineClass1(Native Method)
	at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
	at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
	at java.net.URLClassLoader.defineClass(URLClassLoader.java:467)
	at java.net.URLClassLoader.access$100(URLClassLoader.java:73)
	at java.net.URLClassLoader$1.run(URLClassLoader.java:368)
	at java.net.URLClassLoader$1.run(URLClassLoader.java:362)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.net.URLClassLoader.findClass(URLClassLoader.java:361)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
	at java.lang.Class.forName0(Native Method)
	at java.lang.Class.forName(Class.java:348)
	at com.oracle.mxtool.junit.MxJUnitRequest$Builder.resolveClass(MxJUnitRequest.java:72)
	at com.oracle.mxtool.junit.MxJUnitRequest$Builder.addTestSpec(MxJUnitRequest.java:97)
	at com.oracle.mxtool.junit.MxJUnitWrapper.main(MxJUnitWrapper.java:179)
Caused by: java.io.IOException: Error while instrumenting class MyClass.
	at org.jacoco.agent.rt.internal_8ff85ea.core.instr.Instrumenter.instrumentError(Instrumenter.java:166)
	at org.jacoco.agent.rt.internal_8ff85ea.core.instr.Instrumenter.instrument(Instrumenter.java:117)
	at org.jacoco.agent.rt.internal_8ff85ea.CoverageTransformer.transform(CoverageTransformer.java:91)
	... 31 more
Caused by: java.lang.IllegalStateException: Class MyClass is already instrumented.
	at org.jacoco.agent.rt.internal_8ff85ea.core.internal.instr.InstrSupport.assertNotInstrumented(InstrSupport.java:176)
	at org.jacoco.agent.rt.internal_8ff85ea.core.internal.instr.ClassInstrumenter.visitField(ClassInstrumenter.java:55)
	at org.jacoco.agent.rt.internal_8ff85ea.asm.ClassVisitor.visitField(ClassVisitor.java:272)
	at org.jacoco.agent.rt.internal_8ff85ea.asm.ClassReader.readField(ClassReader.java:783)
	at org.jacoco.agent.rt.internal_8ff85ea.asm.ClassReader.accept(ClassReader.java:704)
	at org.jacoco.agent.rt.internal_8ff85ea.asm.ClassReader.accept(ClassReader.java:521)
	at org.jacoco.agent.rt.internal_8ff85ea.core.instr.Instrumenter.instrument(Instrumenter.java:90)
	at org.jacoco.agent.rt.internal_8ff85ea.core.instr.Instrumenter.instrument(Instrumenter.java:114)
	... 32 more

Allow to specify output directory of mx build

We would like to specify the directory where mx build should put files. On larger systems this could be used to place build results on a ramdisk to speed up things. At the moment I cannot specify the root directory, only the build subdirectory for every suite (as far as I see/understand). Please add a command line option to specify the build root directory.

Cygwin

I am trying to run in mx in cygwin, but am getting:

WARNING: No platform-specific definition is available for library NINJA for your OS (cygwin)
library NINJA:
Library without "path" attribute must have a non-empty "urls" list attribute or "maven" attribute

when just doing mx update.

pebl@stationary /cygdrive/d/shared/git/mx
$ which ninja
/usr/bin/ninja
pebl@stationary /cygdrive/d/shared/git/mx
$ ninja --version
1.9.0
pebl@stationary /cygdrive/d/shared/git/mx
$ uname -a
CYGWIN_NT-6.1 stationary 3.0.4(0.338/5/3) 2019-03-16 09:50 x86_64 Cygwin

Adding

       "cygwin" : {
          "amd64" : {
            "urls" : ["https://github.com/ninja-build/ninja/releases/download/v{version}/ninja-win.zip"],
            "sha1" : "637cc6e144f5cc7c6388a30f3c32ad81b2e0442e"
          }
        },

to mx.mx/suite.py, seems to help, but I dont know if this is the right way.

remove support for cygwin

The cygwin environment support in mx has always lagged behind support for other environments. I believe it was only added because that was the way someone first tried to use mx on Windows. In any case, I propose to remove support for this altogether. Otherwise, we will continue to have problems (e.g. #188 ) with people thinking it is fully supported.

Note that this does not mean you cannot use cygwin with mx. It just means you cannot use the cygwin python executable to run mx but must use a standard Windows python instead.

Empty lines on a multi-core system

On a multi-core system (with Python 2.7.13), mx occasionally prints empty lines:

…
Building com.oracle.truffle.nfi.native with GNU Make... [dependency com.oracle.truffle.nfi updated]
Archiving TRUFFLE_DEBUG... [dependency com.oracle.truffle.tools.debug.shell updated]
Compiling com.oracle.truffle.tck with ecj-daemon... [dependency TRUFFLE_DSL_PROCESSOR updated]
Compiling com.oracle.truffle.api.interop.java.test with ecj-daemon... [dependency TRUFFLE_DSL_PROCESSOR updated]JAVAH src_gen/native.h

Compiling com.oracle.truffle.api.dsl.test with ecj-daemon... [dependency TRUFFLE_DSL_PROCESSOR updated]
CC bin/closure.o
CC bin/jni.o
CC bin/lookup.o
CC bin/signature.o
Archiving TRUFFLE_TCK... [dependency com.oracle.truffle.tck updated]
…

add support for running unit tests in binary suite dependencies

Recently the graal-core gate switched to importing the Truffle suite as a binary dependency. This had the unfortunately side effect of stopping the Truffle unit tests from being run on Graal in the gate. To fix this we need:

  • Truffle to export its unit tests as a distribution (like Graal does).
  • mx unittest command to look in distribution jars for tests

Running mx gate on the mx suite throws an error on Windows

When running the mx gate command on the mx repo/suite I'm seeing the following error:

Traceback (most recent call last):
  File "J:\Projects\mx\mx_gate.py", line 411, in gate
    _run_gate(cleanArgs, args, tasks)
  File "J:\Projects\mx\mx_gate.py", line 518, in _run_gate
    mx.command_function('ideinit')([])
  File "J:\Projects\mx\mx_commands.py", line 132, in __call__
    return self.command_function(*args, **kwargs)
  File "J:\Projects\mx\mx.py", line 16194, in ideinit
    intellijinit(args.remainder, refreshOnly=refreshOnly, doFsckProjects=False, mx_python_modules=args.pythonProjects)
  File "J:\Projects\mx\mx.py", line 15373, in intellijinit
    sdks = intellij_read_sdks()
  File "J:\Projects\mx\mx.py", line 15426, in intellij_read_sdks
    xmlSdks.sort(key=verSort)
  File "J:\Projects\mx\mx.py", line 15424, in verSort
    return match.group(2) + (".a" if match.group(1) == "IntellijIC" else ".b")
AttributeError: 'NoneType' object has no attribute 'group'

The full log can be found here: https://gist.github.com/JornVernee/6b4d368d1ff241d40e5b750adab0ce82

Versions not tagged

It'd be great if new versions could be git-tagged. This would make it easier to check out specific versions of mx without having to browse through the commit history.

sforceimports does not fetch from the repository specified in the suite

mx sforceimport does not use the location specified in the suites to fetch new revisions but the default remote of the clone. This is for example a problem if one uses a fork as default but the fork does not contain the revision that is requested.

# clone graal-core
git clone --depth 1 https://github.com/graalvm/graal-core
# clone an old version of truffle from an outdated fork
git clone --depth 1 https://github.com/zapster/truffle-outdated truffle
# sforceimport graal-core
cd graal-core
mx -y sforceimports

results in:

fatal: reference is not a tree: f322868c76f775a399bf96915c95e077c4f2c08c

I think we should per default fetch from the repository specified in the suite and add a flag to disable the behavior for scenarios where we never want to use local mirrors.

Support multiple Eclipse formatter versions

The current release of Eclipse is 4.5.1 and a number of people have expressed they are now using it. One problem though is that the formatter in 4.5 is not 100% backwards compatible with the one in 4.4 and so everyone has to keep a copy of 4.4 around to check that mx eclipseformat will pass integration gates that use Eclipse 4.4 for formatting checks.

To support per-project opt-in adoption of Eclipse 4.5, we need mx to support multiple Eclipse formatter versions. The plan is to add support for a suite level eclipse.formatter.version attribute. Suites missing this attribute or whose mxversion attribute value is lower than the mx version introducing eclipse.formatter.version will use Eclipse 4.4 for formatting. Otherwise, the eclipse.formatter.version value is used to find a compatible Eclipse. The search for a compatible version will use the -e/--eclipse-exe argument of the mx eclipseformat command which will now be interpreted as a search path (like a class path). The version of an Eclipse found on the path is the version property in the .eclipseproduct file. Given that the Eclipse formatter doesn’t ensure backwards compatibility, mx will require an exact match for the major and minor version numbers.

Note that this issue only addresses mx based Eclipse formatting. As far as I know the Eclipse IDE only supports one formatter at a time and so sources should only be edited from within the Eclipse IDE if the associated eclipse.formatter.version value is compatible with the IDE version.

did anyone generate gradle files from mx ?

The code in mx.py is simple to follow to generate gradle files instead of eclipse/intellij. Has anyone done this yet ? and anything i should be worried about ?

I am worried that the conversion might not be as easy as i am thinking it will be ? anything i should watch out for ?

`mx intellijinit` does not work on windows when project dir drive != user's dir drive

Having an mx project in drive "D" and the user's directory in "C" breaks mx intellijiniit on windows.

I have traced the issue to be related to the use of os.path.relpath in _intellij_suite.
mx tries to create relative paths from the project directory to the .mx directory which is on a different drive, thus making the creation of a relative path impossible.

project com.oracle.truffle.api.dsl was removed as JDK 1.8 is not available

My JDK9-based CI builds running mx 5.172.0 are failing because various projects are "removed as JDK 1.8 is not available". AFAICT related changes were introduced with 1c4adb1 and it seems the problem is that Graal's and Truffle's suite.py haven't been updated yet (e.g. with "javaCompliance" : "1.8+"). I have been running CI builds for around 6 months, this is the first time a new version of mx has caused build failures. Locking the mx version until this has been resolved...

[Question] Can you show some examples of passing JVM args via mx

I had a look at the help via --help and it mentions these:

  -J <arg>                      Java VM arguments (e.g. "-J-dsa")
  --J @<args>                   Java VM arguments (e.g. "--J @-dsa")
  -P <arg>                      prefix Java VM arguments (e.g. "-P-dsa")
  --Jp @<args>                  prefix Java VM arguments (e.g. --Jp @-dsa)
  -A <arg>                      suffix Java VM arguments (e.g. "-A-dsa")
  --Ja @<args>                  suffix Java VM arguments (e.g. --Ja @-dsa)

I would like to pass -Xms2g -Xmx2g -XX:+PrintFlagsFinal to the mx command i.e.

mx [some options] --J @"${JAVA_OPTS}" build

if JAVA_OPTS=-Xms2g -Xmx2g -XX:+PrintFlagsFinal then, the above would look like:

mx [some options] --J @"-Xms2g -Xmx2g -XX:+PrintFlagsFinal" build

Is this above syntax correct?

But it does not seem like my command options are accepted by mx.

Can you please provide a few examples.

update checkstyle version to 6.15

When using newer versions of Checkstyle the RedundantModifier module is able to find more code style violations. We need to upgrade the version but have to take care about the following things:

  • The JVMCI, Graal, and Truffle violations need to be fixed. I already fixed the violations in JVMCI and Graal. Probably, we have to fix new violations shortly before using the new Checkstyle version.
  • Projects that have dependencies on older versions of mx still need to use the current Checkstyle version. I opened a branch with a naive update, that does not yet support the older Checkstyle version: https://github.com/graalvm/mx/tree/update-checkstyle

`mx gate` fails on unchanged master when using multiple drives

I've been fiddling around with a local copy of the mx repo and wanted to test my changes using mx gate, but I kept running into the same error.

Then I tried just running mx gate on the unchanged master branch and got the same error. The error is:

gate: 12 Jun 2018 19:06:39(+00:07) END:   IDEConfigCheck [0:00:00.409000]
Traceback (most recent call last):
  File "J:\Projects\graal\mx3\mx_gate.py", line 352, in gate
    _run_gate(cleanArgs, args, tasks)
  File "J:\Projects\graal\mx3\mx_gate.py", line 457, in _run_gate
    mx.command_function('ideinit')([])
  File "J:\Projects\graal\mx3\mx.py", line 15034, in ideinit
    intellijinit(args.remainder, refreshOnly=refreshOnly, doFsckProjects=False, mx_python_modules=args.pythonProjects)
  File "J:\Projects\graal\mx3\mx.py", line 14362, in intellijinit
    _intellij_suite(args, suite, declared_modules, referenced_modules, refreshOnly, mx_python_modules, generate_external_projects, java_modules and not suite.isBinarySuite(), suite != primary_suite())
  File "J:\Projects\graal\mx3\mx.py", line 14694, in _intellij_suite
    path = os.path.relpath(library.get_path(True), s.dir)
  File "J:\Python27\lib\ntpath.py", line 529, in relpath
    % (path_prefix, start_prefix))
ValueError: path is on drive C:, start on drive J:
gate: 12 Jun 2018 19:06:39(+00:07) ABORT: Gate [0:00:07.875000]
path is on drive C:, start on drive J:

This looks like a Windows only problem, so I'll look into fixing it myself as well, but any suggestions are appreciated.

TypeError: can only concatenate tuple (not "str") to tuple

When trying to build graal/tools, I'm getting the following error:

graal/tools (b76cd1450aa) $ mx build
JAVA_HOME:
EXTRA_JAVA_HOMES:
project org.graalvm.options was removed as JDK 1.8 is not available
project org.graalvm.polyglot was removed as JDK 1.8 is not available
project org.graalvm.word was removed as JDK 1.8 is not available
project org.graalvm.nativeimage was removed as JDK 1.8 is not available
project org.graalvm.collections was removed as JDK 1.8 is not available
Traceback (most recent call last):
  File "/Users/fniephaus/dev/graal/mx/mx.py", line 17697, in <module>
    main()
  File "/Users/fniephaus/dev/graal/mx/mx.py", line 17678, in main
    retcode = c(command_args)
  File "/Users/fniephaus/dev/graal/mx/mx.py", line 11570, in build
    log(reason)
  File "/Users/fniephaus/dev/graal/mx/mx.py", line 11097, in log
    print msg + "\n",
TypeError: can only concatenate tuple (not "str") to tuple
[1]    27515 exit 1     mx build

Pass HTTP_PROXY to maven commands in mx

Maven does not respect the HTTP_PROXY environment variable by default. So I think we should pass the proxy directly on each maven call in mx like this.
mvn -DproxySet=true -DproxyHost=myproxy.com -DproxyPort=3128 eclipse:eclipse

Canonicalization Check fails (makes it impossible to depend JavaProject on NativeProject)

The suite.py constellation below causes:

Traceback (most recent call last):
  File "/home/pwoegere/labs/xxx/mx_olpaw/mx_gate.py", line 267, in gate
    if mx.command_function('canonicalizeprojects')([]) != 0:
  File "/home/pwoegere/labs/xxx/mx_olpaw/mx.py", line 8931, in canonicalizeprojects
    if pkg in dep.extended_java_packages():
AttributeError: 'NativeProject' object has no attribute 'extended_java_packages'
gate: 17 Mar 2016 15:07:00: ABORT: Gate [0:00:11.244213] [disk (free/total): 305.7GB/430.1GB]
'NativeProject' object has no attribute 'extended_java_packages'

I think it should be possible for a JavaProject to depend on a NativeProject:

    "com.oracle.xxx.core.dis" : {
      "subDir" : "xxx",
      "sourceDirs" : ["src"],
      "dependencies" : [
        "com.oracle.xxx.core",
        "com.oracle.xxx.core.dis.native",
      ],
      "annotationProcessors" : [
        "graal-core:GRAAL_NODEINFO_PROCESSOR",
        "graal-core:GRAAL_REPLACEMENTS_VERIFIER",
        "graal-core:GRAAL_OPTIONS_PROCESSOR",
        "truffle:TRUFFLE_DSL_PROCESSOR",
      ],
      "javaCompliance" : "1.8",
      "checkstyle" : "com.oracle.xxx.truffle",
      "workingSets" : "XXX",
      "findbugs" : "false",
    },

    "com.oracle.xxx.core.dis.native" : {
      "native" : True,
      "subDir" : "xxx",
      "dependencies" : ["DISTORM"],
      "output" : "clibraries",
      "results" : [
        "libdistorm3.a",
        "include/distorm.h",
        "include/mnemonics.h",
      ]
    },

Here com.oracle.xxx.core.dis depends on com.oracle.xxx.core.dis.native. Unfortunately using the definition above results in the error shown before.

Output directory in _get_jdk_module_jar doesn't work on Windows

The jdkOutputDir path in _get_jdk_module_jar is determined using the jdk.home property, with the leading slash removed:

mx/mx.py

Line 13246 in d14e55a

jdkOutputDir = ensure_dir_exists(join(suite.get_output_root(), os.path.abspath(jdk.home)[1:]))

However on Windows this doesn't work as there is the drive letter also to remove, the following works though there may be a neater implementation:

if get_os() == 'windows':
    jdkOutputDir = ensure_dir_exists(join(suite.get_output_root(), os.path.abspath(jdk.home)[3:]))
else:
    jdkOutputDir = ensure_dir_exists(join(suite.get_output_root(), os.path.abspath(jdk.home)[1:]))

Suite specific global options do not allow spaces in arguments.

Suite specific global options do not allow spaces in arguments, not even if they are quoted.

Without =:

$ mx --vmprefix "echo -n" vm -version
Suite specific global options must use name=value format: --vmprefix=echo -n

With = and space:

$ mx --vmprefix="echo -n" vm -version
Traceback (most recent call last):
  File "/.../mx.py", line 12275, in <module>
    main()
  File "/.../mx.py", line 12197, in main
    commandAndArgs = _argParser._parse_cmd_line(_opts, firstParse=False)
  File "/.../mx.py", line 6505, in _parse_cmd_line
    abort('Suite specific global options must use name=value format: {0}={1}'.format(self.unknown[-1], self.initialCommandAndArgs[0]))
IndexError: list index out of range

With = without space:

$ mx --vmprefix="echo" vm -version
/.../jvmci/jdk1.8.0_45/product/bin/java -jvmci -d64 -Djvmci.compiler=graal -Xbootclasspath/p:/.../truffle/mxbuild/dists/truffle-api.jar -version

Note that the --vmprefix comes from JVMCI. The help information of the option is also misleading:

  --vmprefix <prefix>   prefix for running the VM (e.g. "/usr/bin/gdb --args")
  --gdb                 alias for --vmprefix "/usr/bin/gdb --args"
  --lldb                alias for --vmprefix "lldb --"

Consolidate mx s* commands

Based on Roland's suggestion we should simplify mx version conflict resolution: Allow solving conflicts only by defining a specific version in the primary suite. This way, dependencies still get transitively resolved but conflicts can only be resolved by defining an exact revision for the conflicting dependency on primary suite level.

In addition to that we should remove all s* commands from mx, except for the bare minimum we require. Below a list of commands that should remain (but probably under a better name):

List of mx dependency handling commands
Current command Notes
mx sforceimports We need some command that allows us to get our project dependencies (transitively) in sync with the current definitions in suite.py (right after initial cloning of the primary suite but also after pulling or after local changes to suite.py). Renaming this command to mx dependencies --update might be a good idea.
mx scheckimports A command that tells us if we are currently in sync with the current definitions in suite.py files. Renaming this command to mx dependencies --check might be a good idea.
mx scloneimports --manual This is needed by buildbot to get a list of the direct (non-transitive) dependencies of a suite. Renaming this command to mx dependencies --list might be a good idea.

(Please add to that list if some version control specific command we need is missing)

Python 3 support.

Is python 3 support planned at all?

I was having a problem with paths exceeding max path length on Windows, and this is apparently fixed in python 3.6 (I worked around the problem by moving the suite directory closer to drive root)

I'm not a python expert, but I've seen applications supporting both python 2 and 3 before by using import __future__. Would that be a possible migration path?

Running the mx commands on the jdk/jdk .mx.graal suite throws an error on Windows

When running the mx help (and other) command on the graal suite included with the openjdk [1] I'm seeing the following error:

PS J:\cygwin64\home\Jorn\cygwin-projects\jdk\src\jdk.internal.vm.compiler> mx help
WARNING: project org.graalvm.compiler.microbenchmarks:
`isTestProject` attribute has been renamed to `testProject`
WARNING: project org.graalvm.compiler.virtual.bench:
`isTestProject` attribute has been renamed to `testProject`
Traceback (most recent call last):
  File "J:\Projects\mx\mx.py", line 18821, in <module>
    main()
  File "J:\Projects\mx\mx.py", line 18733, in main
    primary_suite().recursive_post_init()
  File "J:\Projects\mx\mx.py", line 8893, in recursive_post_init
    self._init_metadata()
  File "J:\Projects\mx\mx.py", line 8925, in _init_metadata
    self._load_metadata()
  File "J:\Projects\mx\mx.py", line 9164, in _load_metadata
    self._finish_load_projects()
  File "J:\Projects\mx\mx.py", line 9243, in _finish_load_projects
    with open(configFile) as fp:
  File "J:\Projects\mx\mx.py", line 13582, in open
    return __builtin__.open(name, mode=mode)
IOError: [Errno 22] invalid mode ('r') or filename: '\\\\?\\J:\\cygwin64\\home\\Jorn\\cygwin-projects\\jdk\\src\\jdk.internal.vm.compiler\\share/classes\\org.graalvm.compiler.core.match.processor\\src\\META-INF\\services\\javax.annotation.processing.Processor'

Please note that while the directory is located in the cygwin file system, I'm running this command in PowerShell.

[1] : http://hg.openjdk.java.net/jdk/jdk/file/4547f8303f2d/src/jdk.internal.vm.compiler

addSrcFromDir needs _safe_path() on Windows

Archiving GRAAL_COMPILER_WHITEBOX_MICRO_BENCHMARKS... [dependency org.graalvm.compiler.virtual.bench updated]
Traceback (most recent call last):
  File "C:/msys64/home/cd4mcq/packages/graal/mx/mx.py", line 18330, in <module>
    main()
  File "C:/msys64/home/cd4mcq/packages/graal/mx/mx.py", line 18311, in main
    retcode = c(command_args)
  File "C:/msys64/home/cd4mcq/packages/graal/mx/mx.py", line 12228, in build
    t.execute()
  File "C:/msys64/home/cd4mcq/packages/graal/mx/mx.py", line 810, in execute
    self.build()
  File "C:/msys64/home/cd4mcq/packages/graal/mx/mx.py", line 1722, in build
    self.subject.make_archive()
  File "C:/msys64/home/cd4mcq/packages/graal/mx/mx.py", line 1486, in make_archive
    addSrcFromDir(srcDir, archivePrefix, arcnameCheck=overlay_check)
  File "C:/msys64/home/cd4mcq/packages/graal/mx/mx.py", line 1376, in addSrcFromDir
    info = zipfile.ZipInfo(arcname, time.localtime(os.path.getmtime(join(root, f)))[:6])
  File "C:\msys64\home\cd4mcq\pypy2-latest-win32\lib-python\2.7\genericpath.py", line 62, in getmtime
    return os.stat(filename).st_mtime
WindowsError: [Error 3] The system cannot find the path specified: C:\msys64\home\cd4mcq\packages\graal\graal\compiler\mxbuild\src\org.graalvm.compiler.microbenchmarks\src_gen\org\graalvm\compiler\microbenchmarks\graal\generated\SchedulePhaseBenchmark_ScheduleEarliestIterative_EARLIEST_WITH_GUARD_ORDER_OPTIMAL_jmhType_B1.java

Provide def release_version(self) for BinarySuite

The call to _updateGraalPropertiesFile() in mx.graal-core/mx_graal_8.py line 73 will fail with jvmci imported as binary suite because there is no definition of def release_version(self) for BinarySuite. A proper definition needs to be added.

mx fails with "no primary suite found"

All mx commands fail on my system with:

"no primary suite found for < command name >"

I'm on Windows with the latest release, but I've confirmed it happens on Ubuntu as well.

Bigger problem: there is no documentation anywhere on what a suite is. There is some mention of suites here: https://github.com/graalvm/mx, but it's not enough. Not sure how to fix the problem.

mx gate always clones full history of dependencies

I'm running mx gate on my CI infrastructure and my project depends on graal which has grown a lot recently. Consequently, it takes quite some time to clone the entire history. It'd be great to have an option to tell mx to not clone the full history. I found this related TODO in the code. Any objections to an option, like --git-depth=1 or --fast-clone?

Best,
Fabio

Env variable MX_GIT_CACHE_DIR doesn't behave right?

My goal is to compile graal community edition from sources with mx and I'm trying to do this with the package manager nix. There's already pre-existing patch for pre-fetching jar files for graal build. What I want to achieve, is pre-fetching the git repositories like https://github.com/graalvm/graaljs.git, gather them into a cache directory and force the mx builder to run the whole thing in offline mode. Without going into more details, it seems to me that the wanted behaviour of the envvar MX_GIT_CACHE_DIR is ignored.

So I have

      export MX_GIT_CACHE='refcache'
      export MX_GIT_CACHE_DIR=/nix/store/mx-git-cache
      export DYNAMIC_IMPORTS=/substratevm,/tools,/sulong,/graal-nodejs
      export LIBGRAAL=true
      export GATE="build,test,helloworld"
      mx --primary-suite-path ./vm --java-home=$MY_JAVA_HOME gate --strict-mode --tags $GATE

which results in

fatal: not a git repository (or any of the parent directories): .git
Fetch from https://github.com/graalvm/graaljs.git into cache /nix/store/mx-git-cache
fatal: not a git repository (or any of the parent directories): .git
git fetch failed

bear in mind, that at this point /nix/store/mx-git-cache/graaljs, a clone of graaljs.git, exists.

by patching abortOnError to False

fatal: not a git repository (or any of the parent directories): .git
Fetch from https://github.com/graalvm/graaljs.git into cache /nix/store/mx-git-cache
fatal: not a git repository (or any of the parent directories): .git
Cloning https://github.com/graalvm/graaljs.git revision 999616fb0efbe0494289b23bbec1e0612fb81201 to /build/graaljs with Git
fatal: repository '/nix/store/mx-git-cache' does not exist
Imported suite 'graal-nodejs' not found (binary or source).

This doesn't seem to behave correctly fatal: repository '/nix/store/mx-git-cache' does not exist when /nix/store/mx-git-cache/graaljs is the directory in which the builder can find /nix/store/mx-git-cache/graaljs/graal-nodejs. I can't imagine ~/.mx/git-cache to be a gihub repository?

In general, patching this build process to work with a purely functional package manager has been quite a challenge. I would suggest allowing a file path to the required dependencies listed in the suite.py files.

https://github.com/oracle/graal/blob/master/vm/mx.vm/suite.py#L10-L16

like here (but it has missing version and that also gives me errors).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.