Skip to content

Latest commit

 

History

History
104 lines (79 loc) · 7.15 KB

DEVELOPMENT_GUIDE.md

File metadata and controls

104 lines (79 loc) · 7.15 KB

Development guide

In this document you can find some technical details about the inside of the project that might help you develop or extend it.

Created from the Gradle-plugins template

First of all, this repository is based on the kotlin-gradle-plugin-template.

That means the following items are organized the same:

  • project's structure;
  • tasks to lint, build and publish the plugin;
  • GitHub CI.

Therefore, you can read more about them in the template's README.md. Nevertheless, the most important notes can be found in the next sections of this document.

Experiment with the latest build

If you'd like to experiment with the very latest project's version in the repo — it is definitely possible to do even without waiting for the new release to be published.

Clone project locally

Clone this repository into a new directory locally. It's recommended not to make it a subproject of some Gradle project, since it may require additional configuration.

# clones the repo into a new folder `bitcode-analysis-plugin`
git clone https://github.com/JetBrains-Research/bitcode-tools bitcode-analysis-plugin

Now link the folder with the plugin repository to your Kotlin/Native project. To do that, add the following code into the settings.gradle.kts file of your project.

pluginManagement {
    includeBuild("absolute-path-to-the-bitcode-analysis-plugin")
}

Apply by id

Finally, add the plugin to your build.gradle.kts by its id. Here is an example.

plugins {
    kotlin("multiplatform")
    // ... other plugins you might have
    id("org.jetbrains.bitcodetools.plugin")
}

Project's structure

Here is a brief overview of where different modules of the project currently live.

  • plugin-build is the directory devoted to the implementation and the build processes of the plugin.
    • In its plugin subfolder you can find the implementation code of the plugin, together with its tests. The actual code lives in the src subfolder.
    • The implementation code of the plugin, the extensions and the tasks it provides is located in the main/java directory, while in the main/resources folder you can find the Python script for the ExtractBitcodeTask implementation.
  • example is an actual small Kotlin/Native example project that applies the implemented plugin. Although the project can be used for demonstration purposes, it is especially useful for testing. So far all the tests executed in CI call the plugin tasks of the example project.

The other directories and files are devoted to the build processes of the project. They should work out-of-the-box, so hopefully you'll never need to explore them.

Useful Gradle tasks

To run all linters and tests before you commit new code, call the preMerge task.

gradle preMerge --continue

Convenient way to resolve most of the issues found by Ktlint is to call the ktlintFormat task in the subproject you want.

# automatically format the code of the plugin implementation
gradle :plugin-build:plugin:ktlintFormat

GitHub CI

In the .github/workflows/ folder you can find scripts for the GitHub CI. The checking ones are being executed on each pull-request or push to main.

  • The most important one is the checks.yaml: it installs the necessary dependencies, runs the linters and implemented tests, and, finally, executes several checks to make sure the plugin actually provides the tasks in the example project.
  • The gradle-wrapper-validation.yaml also runs on each pull-request: it simply checks that the gradle wrapper has a valid checksum.
  • The publish-plugin.yaml one automatically publishes the plugin whenever new tag is pushed.
    • It requires some environment set-up to finish successfully. Namely, two GitHub secrets should be set: GRADLE_PUBLISH_KEY and GRADLE_PUBLISH_SECRET with the credentials that can be found in the Gradle Portal profile. However, it should be done only once for the repo.
    • Moreover, before publishing the plugin don't forget to get acquainted with the Gradle Portal publishing rules. There exist many limitations on plugin's metainformation and project's appearance.

Future plans

In this section you can find the tasks waiting to be done in order to make the plugin more powerful and well-maintained. If you'd like to solve some of them, we'll appreciate your help 🤍

  • Write actual tests for the plugin. So far the test folder contains only a mock one.
  • Support –no-std-lib option. The basic implemention is just to ignore the kfun:kotlin.* functions.
  • Optimize the linePatterns search. Current Python implementation takes some noticeable time when executed on the huge projects due to regexes being used too straightforwardly.
  • Build the complete graph of the functions calls. That will allow to implement the following features.
    • Implement the recursive extraction of the functions being called, but in the other direction: traversing through ancestors (the functions that call the functions that call target function etc...).
    • Get rid of the code from the standard library more efficiently: not only kfun:kotlin.* functions can be ignored, but also the ones that are reachable only from them.
    • Output the needed part of the graph to the user. It may be helpful to analyze the dependencies quickly. The best way is to make it interactive (for example, via html): so the click on the element redirects to its description.
  • Support modes of verbosity. For example, currently the python script provides more logging at the DEBUG level, but there is no way to set it from the plugin so far.
  • Create a Gradle task that checks that all necessary dependencies for the projects are properly set.
  • Find the way to show the bitcode of the requested piece of the source code. That will make possible to analyze bitcode interactively (the same way as decompilation to the Java bytecode works).
    • Implement this tooling as IntelliJ IDEA / VSCode plugins, so as to make possible to analyze the bitcode together with the source code in the most convenient manner.
  • Extend the plugin with the tools for the assembly language analysis. Some optimizations tend to occur only at the compilation-to-the-object-files stage, so it could be useful for user to conveniently inspect them too.