Swift-java command line subcommands refactor

Hi everyone,
I'd like to share an update about how we're approaching the tooling side of swift-java.

Previously we had a number of SwiftPM plugins and separate command line tools:

  • Java2Swift (generate Swift bindings for Java code based on some jar)
  • and jextract-swift (generate Java bindings for Swift code, similar to what jextract from the OpenJDK project does to C headers).

As you may have noticed in our WWDC talk about swift-java: https://www.youtube.com/watch?v=QSHO-GUGidA...

We are converging the command line tools and plugins a bit, and just now I have finished a big refactoring of all the command line tools into one CLI to rule them all: swift-java.

-> % ./.build/debug/swift-java
error: Must specify mode subcommand (e.g. configure, resolve, jextract, ...).

OVERVIEW: Generate sources and configuration for Swift and Java interoperability.

USAGE: swift-java <subcommand>

OPTIONS:
  -h, --help              Show help information.

SUBCOMMANDS:
  configure               Configure and emit a swift-java.config file based on an input dependency or jar file
  resolve                 Resolve dependencies and write the resulting swift-java.classpath file
  wrap-java               Wrap Java classes with corresponding Swift bindings.
  jextract                Wrap Swift functions and types with Java bindings, making them available to be called from Java

  See 'swift-java help <subcommand>' for detailed help.

With subcommands like these: swift-java help jextract

OVERVIEW: Wrap Swift functions and types with Java bindings, making them available to be called from Java

USAGE: swift-java jextract [--output-directory <output-directory>] [--input-swift <input-swift>] [--log-level <log-level>] [--mode <mode>] --swift-module <swift-module> [--java-package <java-package>] --output-swift <output-swift> --output-java <output-java> [--write-empty-files]

OPTIONS:
  -o, --output-directory <output-directory>
                          The directory in which to output generated SwiftJava configuration files.
  --input-swift <input-swift>
                          Directory containing Swift files which should be extracted into Java bindings. Also known as 'jextract' mode. Must be paired with --output-java and --output-swift.
  -l, --log-level <log-level>
                          Configure the level of logs that should be printed (values: trace, debug, info, notice, warning, error, critical; default: log level)
  --mode <mode>           The mode of generation to use for the output files. Used with jextract mode. (default: ffm)
  --swift-module <swift-module>
                          The name of the Swift module into which the resulting Swift types will be generated.
  --java-package <java-package>
                          The Java package the generated Java code should be emitted into.
  --output-swift <output-swift>
                          The directory where generated Swift files should be written. Generally used with jextract mode.
  --output-java <output-java>
                          The directory where generated Java files should be written. Generally used with jextract mode.
  --write-empty-files     Some build systems require an output to be present when it was 'expected', even if empty. This is used by the JExtractSwiftPlugin build plugin, but otherwise should not be necessary.
  -h, --help              Show help information.

Most notably, this brings clarity to which option is required for which mode. It is now also clear which options are required for a specific mode.

All the options used to be all in a single bag of options which was somewhat confusing to choose from when trying to get the tool to work in a specific mode (e.g. the presence of -jar caused the "wrap-java" mode previously).


I wanted to share this update as a forums post because it marks a significant "re-think" how we're structuring this library. Rather than many tools, it is a single tool with various modes. We also will try to package most operations up into the new SwiftJavaPlugin SwiftPM build plugin. However right now there still is an JExtractPlugin as well; this is still subject to change.

For example, we're now very consistent about --output-<LANGUAGE> and similar prefixing so that command line options are easier to discover. If people would be interested in having a look at the options and giving feedback if they seem understandable I'd welcome the feedback! You can get the project from main, swift build it and play around with the swift-java help ... command.

Otherwise we continue to improve the set of supported operations and types, and are focusing on jextract and efficient byte buffer / data access currently.

We also have @madsodgaard -- our GSoC student this year! -- working on adding the --mode jni to jextract, which would allow the use of this mode on platforms which do not have FFM APIs (such as Android :eyes:).

Hope you enjoyed this mini progress update

15 Likes