From a6233f04220f26cbe129c162facda56f165ba03c Mon Sep 17 00:00:00 2001 From: GlebSolovev Date: Mon, 26 Feb 2024 12:33:57 +0100 Subject: [PATCH 1/4] Write friendly readme-s --- DEVELOPMENT_GUIDE.md | 70 +++++++ README.md | 435 ++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 476 insertions(+), 29 deletions(-) create mode 100644 DEVELOPMENT_GUIDE.md diff --git a/DEVELOPMENT_GUIDE.md b/DEVELOPMENT_GUIDE.md new file mode 100644 index 0000000..40ab33d --- /dev/null +++ b/DEVELOPMENT_GUIDE.md @@ -0,0 +1,70 @@ +# 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. + +- [Development guide](#development-guide) + - [Created from the Gradle-plugins template](#created-from-the-gradle-plugins-template) + - [Project's structure](#projects-structure) + - [Useful Gradle tasks](#useful-gradle-tasks) + - [GitHub CI](#github-ci) + - [Future plans](#future-plans) + + +## Created from the Gradle-plugins template + +First of all, this repository is based on the [kotlin-gradle-plugin-template](https://github.com/cortinico/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](https://github.com/cortinico/kotlin-gradle-plugin-template/blob/main/README.md). Nevertheless, the most important notes can be found in the next sections of this document. + +## Project's structure + +Here is a brief overview of where different modules of the project currently live. +* [`plugin-build`](./plugin-build/) is the directory devoted to the implementation and the build processes of the plugin. + * In its [`plugin`](./plugin-build/plugin/) subfolder you can find the implementation code of the plugin, together with its tests. The actual code lives in the [`src`](./plugin-build/plugin/src/) subfolder. + * The implementation code of the plugin, the extensions and the tasks it provides is located in the [`main/java`](./plugin-build/plugin/src/main/java/) directory, while in the [`main/resources`](./plugin-build/plugin/src/main/resources/) folder you can find the Python script for the `ExtractBitcodeTask` implementation. +* [`example`](./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. +```bash +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. +```bash +# automatically format the code of the plugin implementation +gradle :plugin-build:plugin:ktlintFormat +``` + +## GitHub CI + +In the [.github/workflows/](.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`](.github/workflows/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`](.github/workflows/gradle-wrapper-validation.yml) also runs on each pull-request: it simply checks that the gradle wrapper has a valid checksum. +* The [`publish-plugin.yaml`](.github/workflows/publish-plugin.yaml) one automatically publishes the plugin whenever new tag is pushed. It requires some environment set-up, check the publish plugin section for the details (TODO). + +## 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](plugin-build/plugin/src/test/java/com/glebsolovev/kotlin/bitcodetools/gradle/plugin/) 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. diff --git a/README.md b/README.md index 77f83bc..3af6995 100644 --- a/README.md +++ b/README.md @@ -1,64 +1,441 @@ # Bitcode tools for Kotlin/Native projects πŸ„ΊπŸ„½πŸ˜ -[![Pre Merge Checks](https://github.com/cortinico/kotlin-gradle-plugin-template/workflows/Pre%20Merge%20Checks/badge.svg)](https://github.com/cortinico/kotlin-gradle-plugin-template/actions?query=workflow%3A%22Pre+Merge+Checks%22) [![License](https://img.shields.io/github/license/cortinico/kotlin-android-template.svg)](LICENSE) ![Language](https://img.shields.io/github/languages/top/cortinico/kotlin-android-template?color=blue&logo=kotlin) +[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE) +[![Contributions welcome](https://img.shields.io/badge/Contributions-welcome-brightgreen.svg?style=flat)](#contributing--developing) +[![Checks](https://github.com/GlebSolovev/bitcode-tools/actions/workflows/checks.yaml/badge.svg?branch=main)](https://github.com/GlebSolovev/bitcode-tools/actions/workflows/checks.yaml) A simple **Gradle plugin** that provides tasks **to obtain and analyze bitcode** for any Kotlin/Native projects. -This repoistory is based on the [kotlin-gradle-plugin-template](https://github.com/cortinico/kotlin-gradle-plugin-template). +*Authors:* Gleb Solovev, Evgenii Moiseenko, and Anton Podkopaev, [Programming Languages and Program Analysis (PLAN) Lab](https://lp.jetbrains.com/research/plt_lab/) at JetBrains Research. -## How to use plugin +- [Bitcode tools for Kotlin/Native projects πŸ„ΊπŸ„½πŸ˜](#bitcode-tools-for-kotlinnative-projects-) + - [TL;DR](#tldr) + - [Why analyze bitcode?](#why-analyze-bitcode) + - [Key features](#key-features) + - [Set up necessary dependencies](#set-up-necessary-dependencies) + - [Python dependencies](#python-dependencies) + - [LLVM dependency](#llvm-dependency) + - [Apply plugin](#apply-plugin) + - [Clone project locally](#clone-project-locally) + - [Apply by id](#apply-by-id) + - [Set up plugin](#set-up-plugin) + - [Required set-up](#required-set-up) + - [Access debug tasks](#access-debug-tasks) + - [Select `extractBitcode` targets](#select-extractbitcode-targets) + - [Set up `extractBitcode` working mode](#set-up-extractbitcode-working-mode) + - [Configure directories and file names](#configure-directories-and-file-names) + - [Plugin configuration examples](#plugin-configuration-examples) + - [Minimal configuration](#minimal-configuration) + - [Enable debug tasks](#enable-debug-tasks) + - [Select which targets and how to extract](#select-which-targets-and-how-to-extract) + - [Customize directories and file names](#customize-directories-and-file-names) + - [Call tasks in the command line](#call-tasks-in-the-command-line) + - [Examples](#examples) + - [Advanced customization](#advanced-customization) + - [Configure stand-alone tasks](#configure-stand-alone-tasks) + - [Create your own tasks](#create-your-own-tasks) + - [Contributing \& developing](#contributing--developing) -TODO, coming soon! +## TL;DR -## About template setup & capabilities +Run through the README quickly! ⚑️ -### Composite Build πŸ“¦ +* Get to know the [key features](#key-features) of the plugin. +* Make sure all [necessary dependencies](#set-up-necessary-dependencies) are set. +* [Apply the plugin](#apply-plugin) to your Kotlin/Native project. +* Check the examples of the [plugin configuration](#plugin-configuration-examples) and [task calls](#examples) to quickly master the plugin. + * An [example Kotlin/Native project](./example/build.gradle.kts) configured with the plugin might also be helpful. -This template is using a [Gradle composite build](https://docs.gradle.org/current/userguide/composite_builds.html) to build, test and publish the plugin. This means that you don't need to run Gradle twice to test the changes on your Gradle plugin (no more `publishToMavenLocal` tricks or so). +## Why analyze bitcode? -The included build is inside the [plugin-build](plugin-build) folder. +The pipeline for compiling Kotlin/Native code into an executable binary is as follows: first, the code is compiled into LLVM bitcode — a special assembly-like language used by the framework — and then LLVM converts the bitcode into the final output file. -#### `preMerge` task +While some optimizations happen at the very last stage, a huge number of them (including all Kotlin-specific optimizations) happen during compilation to bitcode. Therefore, bitcode analysis of Kotlin/Native code ***becomes especially useful for***: +* exploration of optimizations and transformations applied to the code; +* debugging the compilation process. -A `preMerge` task on the top level build is already provided in the template. This allows you to run all the `check` tasks both in the top level and in the included build. +In general, bitcode analysis of Kotlin/Native projects is in some ways quite similar to bytecode analysis of Kotlin/JVM code. However, since the first one is much more difficult to obtain and explore manually, the current plugin is here to help you! 🦸 -You can easily invoke it with: +## Key features +Use consice Kotlin DSL syntax to configure the plugin in your `build.gradle.kts` file and get bitcode analysis tasks in return. +* ***Analyze bitcode of your Kotlin/Native project.*** + * `decompileBitcode` — builds a human-readable `.ll` bitcode file of your source code; + * `extractBitcode` — extracts the specified elements from the project's bitcode; + * *(optional)* `decompileBitcodeDebug` and `extractBitcodeDebug` — additional versions of above tasks to analyze bitcode of your project built in the debug mode. +* ***Analyze any bitcode files.*** + * `decompileSomeBitcode` — decompiles a bitcode `*.bc` file into a human-readable `*.ll` one; + * `extractSomeBitcode` — extracts the specified elements from a bitcode `*.ll` file. +* ***Create your own custom tasks*** using `DecompileBitcodeTask` and `ExtractBitcodeTask` classes. + +Of course, all tasks provided by the plugin... +* ...support accurate inputs/outputs tracking — meaning that actual work will only be done when necessary 😴; +* ...are properly linked to the project's build tasks — so no thinking about working pipeline is needed, just call the tasks 🀝; +* ...provide set-up of their parameters both in the build file and in the command line — communicate with the plugin in the most convenient way for you πŸ«‚. + +## Set up necessary dependencies + +The plugin requires two dependencies installed on your machine to work properly: **Python with necessary modules** and **LLVM**. + +### Python dependencies + +First, make sure you have Python compatible with the `3.10` version on your computer. +```bash +python3 --version +``` + +Then install the `llvmlite` module. +```bash +pip3 install llvmlite~=0.41.0 +``` + +### LLVM dependency + +The key and the only one dependency needed from LLVM is the `llvm-dis` tool. Unfortunately, that requires installing the complete LLVM distribution and, unfortunately, we don't know any way to do it easily on the *Windows* machines so far. + +To install the LLVM on your machine it is recommended to check the various guides on the Internet. + +Once you finish, make sure LLVM is accessible and is compatible with the `14.0.0` version. +```bash +llvm-config --version +``` + +## Apply plugin + +The standard way to install a Gradle plugin is to obtain it from *Maven Repository* automatically. Unfortunately, the bitcode-analysis plugin has not been published there so far. Therefore, the only way to install it is to clone this repository locally. + +### 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. +```bash +# clones the repo into a new folder `bitcode-analysis-plugin` +git clone https://github.com/GlebSolovev/bitcode-tools.git 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. +```kotlin +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. +```kotlin +plugins { + kotlin("multiplatform") + // ... other plugins you might have + id("com.glebsolovev.kotlin.bitcodetools.gradle.plugin") +} +``` +If your working in IDE, it'd better to rebuild Gradle at this point, so to access lovely DSL auto-completion. + +## Set up plugin + +The next step is plugin configuration. There are two extensions available in `build.gradle.kts` to do this: `decompileBitcodeConfig` and `extractFromDecompiledBitcodeConfig`. + +### Required set-up + +The only set-up being required is the following one: +```kotlin +decompileBitcodeConfig { + linkTaskName = "the name of the task to link your Kotlin/Native sources" + setCompilerFlags = { compilerFlags: List -> + // add `compilerFlags` to your Kotlin/Native compiler + } +} +``` +Check [examples section](#plugin-configuration-examples) to see ready-to-use code snippets. + +Now plugin already provides `decompileBitcode` and `extractBitcode` tasks to analyze your project's bitcode and `decompileSomeBitcode` and `extractSomeBitcode` tasks to analyze some standalone bitcode files. + +### Access debug tasks + +To get `decompileBitcodeDebug` and `extractBitcodeDebug` tasks to analyze debug build of your project, the `linkDebugTaskName` should be set too. +```kotlin +decompileBitcodeConfig { + // ... other properties set-up + linkDebugTaskName = "the name of the task to link your Kotlin/Native sources in the debug mode" +} +``` + +### Select `extractBitcode` targets + +`extractBitcode` and `extractBitcodeDebug` tasks extracts the target functions defined in the `extractFromDecompiledBitcodeConfig`. So far, you can select the targets in the following way. +```kotlin +extractFromDecompiledBitcodeConfig { + functionNames = listOf("name of the function, specified exactly as in the bitcode file") + functionPatterns = listOf("regex pattern to match the desired function names") + linePatterns = listOf("regex pattern to match at least one line of bitcode of the desired functions") + ignorePatterns = listOf("regex pattern to ignore functions with their name matching it") +} +``` +Since all these properties are `ListProperty`-s, you can always add new elements to them with `.add(...)` syntax. +```kotlin +functionNames.add("desired function names") +``` +See more examples in the [examples section](#plugin-configuration-examples). + +### Set up `extractBitcode` working mode + +Extract-bitcode tasks provide several properties, to configure the way the perform the extraction. + +The property `recursionDepth` enables ***recursive exraction*** of all called functions up to the specified depth (relative to the target functions). Zero value (the default one) means recursive extraction is disabled: only target functions will be extracted. +```kotlin +extractFromDecompiledBitcodeConfig { + // ... other properties set-up + recursionDepth = 1u // additionaly extracts all functions called from the target functions +} +``` + +The property `verbose` simply enables logging printed to the stdout. It can be useful to track the extraction process thoroughly, but might be too verbose in case you extract a lot of functions at a time. +```kotlin +extractFromDecompiledBitcodeConfig { + // ... other properties set-up + verbose = true // enables logging (disabled by default) +} +``` + +### Configure directories and file names + +Even though the plugin by default uses the most common names and paths for the input and output files, you still might want to customize them. To do this, consider the following properties. + +```kotlin +decompileBitcodeConfig { + // ... other properties set-up + artifactsDirectoryPath = "path to the directory to store all the input and output bitcode artifacts (relative to the project directory), 'build/bitcode' by default" + bcInputFileName = "name of the '*.bc' file produced by the link task, 'out.bc' by default" + llOutputFileName = "name of the '*.ll' file to decompile bitcode into, 'bitcode.ll' by default" + llDebugOutputFileName = "name of the '*.ll' file to decompile debug bitcode into, 'bitcode-debug.ll' by default" +} + +extractFromDecompiledBitcodeConfig { + // ... other properties set-up + outputFileName = "name of the file to save extracted bitcode into, 'extracted-bitcode.ll' by default" + debugOutputFileName = "name of the file to save extracted debug bitcode into, 'extracted-bitcode-debug.ll' by default" +} +``` +However, if you experiment with bitcode a lot generating many different result files for different configurations, it might be more convenient to set up the names of the files via command line flags. Check the [command-line section](#call-tasks-in-the-command-line). + +## Plugin configuration examples + +Here you can find several ready-to-use code snippets, which also clarify the syntax described above. Besides, you can find *an example Kotlin/Native project configured with the plugin* at the [`example`](example/build.gradle.kts) directory. + +### Minimal configuration + +Minimal configuration to build and analyze bitcode of a standard Kotlin/Native project on a `LinuxX64` machine. + +```kotlin +decompileBitcodeConfig { + linkTaskName = "linkReleaseExecutableLinuxX64" + setCompilerFlags = { compilerFlags -> + kotlin { + linuxX64().compilations.getByName("main") { + kotlinOptions.freeCompilerArgs += compilerFlags + } + } + } +} ``` -./gradlew preMerge + +Minimal configuration for a standard Kotlin/Native project to support any machine architecture. +```kotlin +decompileBitcodeConfig { + val hostOs: String = System.getProperty("os.name") + val arch: String = System.getProperty("os.arch") + linkTaskName = when { + hostOs == "Linux" -> "linkReleaseExecutableLinuxX64" + hostOs == "Mac OS X" && arch == "x86_64" -> "linkReleaseExecutableMacosX64" + hostOs == "Mac OS X" && arch == "aarch64" -> "linkReleaseExecutableMacosArm64" + hostOs.startsWith("Windows") -> throw GradleException("Windows is currently unsupported: unable to install `llvm-dis` tool") + else -> throw GradleException("Unsupported target platform: $hostOs / $arch") + } + setCompilerFlags = { compilerFlags -> + kotlin { + listOf(macosX64(), macosArm64(), mingwX64(), linuxX64()).forEach { + it.compilations.getByName("main") { + kotlinOptions.freeCompilerArgs += compilerFlags + } + } + } + } +} ``` -If you need to invoke a task inside the included build with: +### Enable debug tasks +An easy way to get the debug tasks for a standard Kotlin/Native project. +```kotlin +decompileBitcodeConfig { + // ... other properties set-up + linkDebugTaskName = linkTaskName.replace("Release", "Debug") +} ``` -./gradlew -p plugin-build + +### Select which targets and how to extract + +An example of selecting the targets to extract from the project's bitcode. +```kotlin +extractFromDecompiledBitcodeConfig { + // extract these two functions: main and exception-throwing + functionNames = listOf("kfun:#main(){}", "ThrowIllegalArgumentException") + + // additionally, extract all the functions that contain `main` in their names as a substring + functionPatterns = listOf(".*main.*") + + // also extract functions that either contain the following exact code line or rather any call to some `hashCode` function + linePatterns.add("%2 = icmp eq i64 %1, 0") + linePatterns.add(".*call.*kfun:.*#hashCode\\(\\)\\{\\}kotlin\\.Int.*") + + // ignore functions from the standard library, otherwise they most likely litter the analysis + ignorePatterns.add("kfun:kotlin.*") +} ``` +Tune the behaviour of the `extractBitcode` and `extractBitcodeDebug` tasks. +```kotlin +extractFromDecompiledBitcodeConfig { + // ... other properties set-up + + // choose which depth makes sense for you to examine the calls inside the target functions + recursionDepth = 3u -#### Dependency substitution + // track the extraction process via the log messages + verbose = true +} +``` -Please note that the project relies on module name/group in order for [dependency substitution](https://docs.gradle.org/current/userguide/resolution_rules.html#sec:dependency_substitution_rules) to work properly. If you change only the plugin ID everything will work as expected. If you change module name/group, things might break and you probably have to specify a [substitution rule](https://docs.gradle.org/current/userguide/resolution_rules.html#sub:project_to_module_substitution). +### Customize directories and file names +Define custom file directories and file names for the tasks. +```kotlin +decompileBitcodeConfig { + // ... other properties set-up + + // defines the parent directory for all the bitcode artifacts generated by the pipeline tasks, relative to the project's root + artifactsDirectoryPath = "build/customBitcodeDir" -### Publishing πŸš€ + // be careful changing this file name: your task provided in the `linkTask` should generate exactly this file in the provided directory via `-Xtemporary-files-dir` flag (it's easier just to check it on practice by running the `decompileBitcode` task) + bcInputFileName = "main.bc" -This template is ready to let you publish to [Gradle Portal](https://plugins.gradle.org/). + // choose the file names you like, the decompiled bitcode will appear in these files in the `artifactsDirectoryPath` directory + llOutputFileName = "decompiled-bitcode.ll" + llDebugOutputFileName = "decompiled-bitcode-debug.ll" +} -The [![Publish Plugin to Portal](https://github.com/cortinico/kotlin-gradle-plugin-template/workflows/Publish%20Plugin%20to%20Portal/badge.svg?branch=1.0.0)](https://github.com/cortinico/kotlin-gradle-plugin-template/actions?query=workflow%3A%22Publish+Plugin+to+Portal%22) Github Action will take care of the publishing whenever you **push a tag**. +extractFromDecompiledBitcodeConfig { + // ... other properties set-up -Please note that you need to configure two secrets: `GRADLE_PUBLISH_KEY` and `GRADLE_PUBLISH_SECRET` with the credetials you can get from your profile on the Gradle Portal. + // simple customization of the output files names, they will be generated in the `artifactsDirectoryPath` too + outputFileName = "extracted-bitcode.ll" + debugOutputFileName = "extracted-bitcode-debug.ll" -### Static Analysis πŸ” + // P.S. you can't change the input file name, because `extractBitcode` / `extractBitcodeDebug` tasks are pipeline ones: they accept `llOutputFileName` / `llDebugOutputFileName` from the `decompileBitcode` / `decompileBitcodeDebug` tasks as an input +} +``` + +## Call tasks in the command line + +As for any other Gradle tasks, one of the easiest way to run the bitcode ones is to call them via `gradle` / `./gradlew` from the command line. Also if your IDE supports Gradle tasks execution from the GUI, this could also be an option. + +```bash +# runs `decompileBitcode` task found in the project +gradle decompileBitcode + +# does the same, you just use the script in the root directory to call Gradle +./gradlew decompileBitcode + +# runs `decompileBitcode` task for the `example` subproject +gradle :example:decompileBitcode +``` + +While the plugin set-up defines the default arguments of the tasks (so they can be called just as-is), these arguments can be overriden by ones specified in the command line. + +Almost all settings from the set-up section can be passed by the command line flags. To check their full list just call the `help` task. + +```bash +gradle help --task decompileBitcode +gradle help --task extractBitcode +``` -This template is using [**ktlint**](https://github.com/pinterest/ktlint) with the [ktlint-gradle](https://github.com/jlleitschuh/ktlint-gradle) plugin to format your code. To reformat all the source code as well as the buildscript you can run the `ktlintFormat` gradle task. +### Examples -This template is also using [**detekt**](https://github.com/arturbosch/detekt) to analyze the source code, with the configuration that is stored in the [detekt.yml](config/detekt/detekt.yml) file (the file has been generated with the `detektGenerateConfig` task). +Calling `decompileBitcode` / `decompileDebugBitcode` / `decompileSomeBitcode` tasks. + +```bash +# call with arguments configured in the build files +gradle decompileBitcode + +# override input and output file paths +gradle decompileBitcode --input build/bitcode/releaseSources/out.bc --output build/bitcode/bitcode.ll +``` + +Calling `extractBitcode` / `extractBitcodeDebug` / `extractSomeBitcode` tasks. + +```bash +# call with arguments configured in the build files +gradle extractBitcode + +# override input (*) and output file paths +# note: the input path should match the output file of the corresponding `decompileBitcode` task +gradle extractBitcode --input build/bitcode/bitcode.ll --output build/bitcode/extracted-bitcode.ll + +# select targets to extract: + # main and exception-throwing functions; + # all the functions that contain `main` in their names as a substring; + # all the functions that contain call to some `hashCode` function; + # ignoring functions from the standard library +# note: don't forget to quote the arguments, otherwise your console may try to interpret them as regexes by itself +gradle extractBitcode --function 'kfun:#main(){}' --function 'ThrowIllegalArgumentException' --function-pattern '.*main.*' --line-pattern '.*call.*kfun:.*#hashCode\(\)\{\}kotlin\.Int.*' --ignore-function-pattern 'kfun:kotlin.*' + +# extract main function and all functions that are called from its body with the detailed logging enabled +gradle extractBitcode --function-pattern 'kfun:#main\(.*' --recursion-depth=1 --verbose +``` + +## Advanced customization + +Two Gradle extensions `decompileBitcodeConfig` and `extractFromDecompiledBitcodeConfig` provide a great way to set up the pipeline tasks to analyze your project's bitcode. But there is still place for the customization of the stand-alone `decompileSomeBitcode` and `extractSomeBitcode` tasks and even creating your own Gradle machinery. + +### Configure stand-alone tasks + +If you tend to use the same arguments of the stand-alone task frequently, they can be moved to the `build.gradle.kts` as default ones just for convenience. Here is an example. + +```kotlin +tasks.named("decompileSomeBitcode") { + outputFilePath = "build/bitcode/bitcode.ll" +} + +tasks.named("extractSomeBitcode") { + recursionDepth = 1u + verbose = true +} +``` + +### Create your own tasks + +All tasks provided by the plugin are of the task classes `DecompileBitcodeTask` and `ExtractBitcodeTask`, actually the plugin only makes their set-up easier. Thus, if you feel the provided tasks are not enough for your goals, you can always register your own ones and freely configure them with all the power of Gradle! + +```kotlin +tasks.register("decompileMyBitcode") {} + +tasks.register("extractMyBitcode") { + verbose = True +} + +tasks.register("extractBitcodePolitely") { + dependsOn("decompileBitcode") + doFirst { + println("It's impolite not to say hello at the very beginning. So, hello!") + } + inputFilePath = "build/bitcode/bitcode.ll" + outputFilePath = "build/bitcode/custom-bitcode.ll" + functionNames = listOf("kfun:#main(){}") +} +``` +Of course, all the `DecompileBitcodeTaks` and `ExtractBitcodeTask` tasks get command-line flags support just out-of-the-box, so there is no limitations on calling your custom tasks in the command line. -### CI βš™οΈ +## Contributing & developing -This template is using [**GitHub Actions**](https://github.com/cortinico/kotlin-android-template/actions) as CI. You don't need to setup any external service and you should have a running CI once you start using this template. +If you have any ideas on improving the project or found any bugs, you're always welcome to contact any of the authors or support an issue πŸ«‚ -There are currently the following workflows available: -- [Validate Gradle Wrapper](.github/workflows/gradle-wrapper-validation.yml) - Will check that the gradle wrapper has a valid checksum -- [Pre Merge Checks](.github/workflows/pre-merge.yaml) - Will run the `preMerge` tasks as well as trying to run the Gradle plugin. -- [Publish to Plugin Portal](.github/workflows/publish-plugin.yaml) - Will run the `publishPlugin` task when pushing a new tag. +In case you're interested in the more development details of this project, make sure to check the [DEVELOPMENT_GUIDE.md](./DEVELOPMENT_GUIDE.md). From 4f4d00d0ca69df71dc71ef956b36396f19f456da Mon Sep 17 00:00:00 2001 From: GlebSolovev Date: Mon, 4 Mar 2024 04:54:10 +0100 Subject: [PATCH 2/4] Write docs for public classes and properties --- .../gradle/plugin/BitcodeAnalysisPlugin.kt | 3 ++ .../plugin/DecompileBitcodeExtension.kt | 24 +++++++++++++++ .../gradle/plugin/DecompileBitcodeTask.kt | 12 ++++++++ .../gradle/plugin/ExtractBitcodeExtension.kt | 24 +++++++++++++++ .../gradle/plugin/ExtractBitcodeTask.kt | 29 +++++++++++++++++++ 5 files changed, 92 insertions(+) diff --git a/plugin-build/plugin/src/main/java/com/glebsolovev/kotlin/bitcodetools/gradle/plugin/BitcodeAnalysisPlugin.kt b/plugin-build/plugin/src/main/java/com/glebsolovev/kotlin/bitcodetools/gradle/plugin/BitcodeAnalysisPlugin.kt index 11977b8..793379f 100644 --- a/plugin-build/plugin/src/main/java/com/glebsolovev/kotlin/bitcodetools/gradle/plugin/BitcodeAnalysisPlugin.kt +++ b/plugin-build/plugin/src/main/java/com/glebsolovev/kotlin/bitcodetools/gradle/plugin/BitcodeAnalysisPlugin.kt @@ -8,6 +8,9 @@ import org.gradle.api.file.Directory import org.gradle.kotlin.dsl.* import java.nio.file.Files.createDirectories +/** + * Gradle plugin that provides various tasks to perform bitcode analysis + * of the Kotlin/Native code and Kotlin/Native projects. */ abstract class BitcodeAnalysisPlugin : Plugin { companion object { diff --git a/plugin-build/plugin/src/main/java/com/glebsolovev/kotlin/bitcodetools/gradle/plugin/DecompileBitcodeExtension.kt b/plugin-build/plugin/src/main/java/com/glebsolovev/kotlin/bitcodetools/gradle/plugin/DecompileBitcodeExtension.kt index 54321d5..deea03b 100644 --- a/plugin-build/plugin/src/main/java/com/glebsolovev/kotlin/bitcodetools/gradle/plugin/DecompileBitcodeExtension.kt +++ b/plugin-build/plugin/src/main/java/com/glebsolovev/kotlin/bitcodetools/gradle/plugin/DecompileBitcodeExtension.kt @@ -3,18 +3,42 @@ package com.glebsolovev.kotlin.bitcodetools.gradle.plugin import org.gradle.api.Project import javax.inject.Inject +/** + * Gradle extension to set up the bitcode-analysis pipeline of the project: + * namely, general parameters and the `decompileBitcode` & `decompileBitcodeDebug` tasks. + */ abstract class DecompileBitcodeExtension @Inject constructor(project: Project) { @Suppress("unused") // required to initialize properties of type Property<*> correctly private val objects = project.objects + /** Name of the Gradle task to link the project. */ abstract var linkTaskName: String + + /** + * Function that specifies how flags are passed + * to the Kotlin/Native compiler used in build. + */ abstract var setCompilerFlags: (compilerFlags: List) -> Unit + /** + * Path to the directory to store all the input and output bitcode artifacts + * (relative to the project directory). It is set to `"build/bitcode"` by default. + */ var artifactsDirectoryPath: String = "build/bitcode" + + /** + * Name of the `*.bc` file produced by + * the [linkTaskName] and [linkDebugTaskName] tasks, `"out.bc"` by default. + */ var bcInputFileName: String = "out.bc" + + /** Name of the `*.ll` file to decompile bitcode into, `"bitcode.ll"` by default. */ var llOutputFileName: String = "bitcode.ll" + /** Name of the Gradle task to link the project in the debug mode. It is not set by default. */ var linkDebugTaskName: String? = null + + /** Name of the `*.ll` file to decompile debug bitcode into, `"bitcode-debug.ll"` by default. */ var llDebugOutputFileName: String = "bitcode-debug.ll" } diff --git a/plugin-build/plugin/src/main/java/com/glebsolovev/kotlin/bitcodetools/gradle/plugin/DecompileBitcodeTask.kt b/plugin-build/plugin/src/main/java/com/glebsolovev/kotlin/bitcodetools/gradle/plugin/DecompileBitcodeTask.kt index 460eabc..10282b5 100644 --- a/plugin-build/plugin/src/main/java/com/glebsolovev/kotlin/bitcodetools/gradle/plugin/DecompileBitcodeTask.kt +++ b/plugin-build/plugin/src/main/java/com/glebsolovev/kotlin/bitcodetools/gradle/plugin/DecompileBitcodeTask.kt @@ -11,6 +11,7 @@ import org.gradle.api.tasks.TaskAction import org.gradle.api.tasks.options.Option import javax.inject.Inject +/** Gradle task that decompiles a bitcode `.bc` file into a human-readable `.ll` one. */ abstract class DecompileBitcodeTask @Inject constructor(project: Project) : DefaultTask() { init { @@ -20,6 +21,7 @@ abstract class DecompileBitcodeTask @Inject constructor(project: Project) : Defa private val objects = project.objects + /** Path (relative to the project's root) to the input bitcode `.bc` file. */ @get:Internal @get:Option( option = "input", @@ -27,6 +29,7 @@ abstract class DecompileBitcodeTask @Inject constructor(project: Project) : Defa ) val inputFilePath: Property = objects.property(String::class.java) + /** Path (relative to the project's root) to the output human-readable `.ll` file. */ @get:Internal @get:Option( option = "output", @@ -34,16 +37,25 @@ abstract class DecompileBitcodeTask @Inject constructor(project: Project) : Defa ) val outputFilePath: Property = objects.property(String::class.java) + /** + * By default, stores [inputFilePath] resolved to the project's directory. + * This property is expected to be readonly. + */ @get:InputFile val actualInputFile: RegularFileProperty = objects.fileProperty().value( project.layout.projectDirectory.file(inputFilePath) ) + /** + * By default, stores [outputFilePath] resolved to the project's directory. + * This property is expected to be readonly. + */ @get:OutputFile val actualOutputFile: RegularFileProperty = objects.fileProperty().value( project.layout.projectDirectory.file(outputFilePath) ) + /** Decompiles bitcode file to its human-readable version. */ @TaskAction fun produce() { val bcFilePath = actualInputFile.get().asFile.absolutePath diff --git a/plugin-build/plugin/src/main/java/com/glebsolovev/kotlin/bitcodetools/gradle/plugin/ExtractBitcodeExtension.kt b/plugin-build/plugin/src/main/java/com/glebsolovev/kotlin/bitcodetools/gradle/plugin/ExtractBitcodeExtension.kt index f6b79a8..b984ed7 100644 --- a/plugin-build/plugin/src/main/java/com/glebsolovev/kotlin/bitcodetools/gradle/plugin/ExtractBitcodeExtension.kt +++ b/plugin-build/plugin/src/main/java/com/glebsolovev/kotlin/bitcodetools/gradle/plugin/ExtractBitcodeExtension.kt @@ -4,19 +4,43 @@ import org.gradle.api.Project import org.gradle.api.provider.ListProperty import javax.inject.Inject +/** + * Gradle extension to set up the bitcode-analysis pipeline of the project: + * namely, the `extractBitcode` & `extractBitcodeDebug` tasks. + */ @Suppress("UnnecessaryAbstractClass") abstract class ExtractBitcodeExtension @Inject constructor(project: Project) { private val objects = project.objects + /** Names of the functions to extract (should be specified exactly the same as in the bitcode file). */ val functionNames: ListProperty = objects.listProperty(String::class.java) + + /** Extract all functions with the names matching the specified regex patterns. */ val functionPatterns: ListProperty = objects.listProperty(String::class.java) + + /** Extract all functions that contain at least one code line matching the specified regex patterns. */ val linePatterns: ListProperty = objects.listProperty(String::class.java) + + /** Ignore all functions with the names matching the specified regex patterns. */ val ignorePatterns: ListProperty = objects.listProperty(String::class.java) + /** + * Enables recursive extraction of all called functions + * up to the specified depth, relative to the target functions. + * Default depth is `0`, meaning recursive extraction is disabled. + */ var recursionDepth: UInt = 0u + + /** + * Enables logging: prints extra info messages to the console + * to track the extraction process. It is disabled by default. + */ var verbose: Boolean = false + /** Name of the file to save extracted bitcode into, `"extracted-bitcode.ll"` by default. */ var outputFileName: String = "extracted-bitcode.ll" + + /** Name of the file to save extracted debug bitcode into, `"extracted-bitcode-debug.ll"` by default. */ var debugOutputFileName: String = "extracted-bitcode-debug.ll" } diff --git a/plugin-build/plugin/src/main/java/com/glebsolovev/kotlin/bitcodetools/gradle/plugin/ExtractBitcodeTask.kt b/plugin-build/plugin/src/main/java/com/glebsolovev/kotlin/bitcodetools/gradle/plugin/ExtractBitcodeTask.kt index ebab886..8d42822 100644 --- a/plugin-build/plugin/src/main/java/com/glebsolovev/kotlin/bitcodetools/gradle/plugin/ExtractBitcodeTask.kt +++ b/plugin-build/plugin/src/main/java/com/glebsolovev/kotlin/bitcodetools/gradle/plugin/ExtractBitcodeTask.kt @@ -15,6 +15,7 @@ import java.nio.file.Path import javax.inject.Inject import kotlin.io.path.writeText +/** Gradle task that extracts the specified elements from a bitcode `.ll` file effectively. */ abstract class ExtractBitcodeTask @Inject constructor(project: Project) : DefaultTask() { init { @@ -28,6 +29,7 @@ abstract class ExtractBitcodeTask @Inject constructor(project: Project) : Defaul private const val EXTRACT_BITCODE_SCRIPT_PATH = "/extract-bitcode.py" } + /** Path (relative to the project's root) to the input `.ll` file. */ @get:Internal @get:Option( option = "input", @@ -35,6 +37,7 @@ abstract class ExtractBitcodeTask @Inject constructor(project: Project) : Defaul ) val inputFilePath: Property = objects.property(String::class.java) + /** Path (relative to the project's root) to the output `.ll` file with the extracted bitcode. */ @get:Internal @get:Option( option = "output", @@ -42,9 +45,15 @@ abstract class ExtractBitcodeTask @Inject constructor(project: Project) : Defaul ) val outputFilePath: Property = objects.property(String::class.java) + /** + * Enables recursive extraction of all called functions + * up to the specified depth, relative to the target functions. + * Default depth is `0`, meaning recursive extraction is disabled. + */ @get:Internal var recursionDepth: UInt = 0u + /** Names of the functions to extract (should be specified exactly the same as in the bitcode file). */ @get:Input @get:Option( option = "function", @@ -54,6 +63,7 @@ abstract class ExtractBitcodeTask @Inject constructor(project: Project) : Defaul ) val functionNames: ListProperty = objects.listProperty(String::class.java).convention(emptyList()) + /** Extract all functions with the names matching the specified regex patterns. */ @get:Input @get:Option( option = "function-pattern", @@ -66,6 +76,7 @@ abstract class ExtractBitcodeTask @Inject constructor(project: Project) : Defaul val functionPatterns: ListProperty = objects.listProperty(String::class.java).convention(emptyList()) + /** Extract all functions that contain at least one code line matching the specified regex patterns. */ @get:Input @get:Option( option = "line-pattern", @@ -80,6 +91,7 @@ abstract class ExtractBitcodeTask @Inject constructor(project: Project) : Defaul val linePatterns: ListProperty = objects.listProperty(String::class.java).convention(emptyList()) + /** Ignore all functions with the names matching the specified regex patterns. */ @get:Input @get:Option( option = "ignore-function-pattern", @@ -92,6 +104,10 @@ abstract class ExtractBitcodeTask @Inject constructor(project: Project) : Defaul val ignorePatterns: ListProperty = objects.listProperty(String::class.java).convention(emptyList()) + /** + * Property that is used to support [recursionDepth] parameter in the command line. + * It uses [recursionDepth] value by default properly, + * so it is not recommended to modify this property. */ @get:Input @get:Option( option = "recursion-depth", @@ -109,6 +125,10 @@ abstract class ExtractBitcodeTask @Inject constructor(project: Project) : Defaul } ) + /** + * Enables logging: prints extra info messages to the console + * to track the extraction process. It is disabled by default. + */ @get:Input @get:Option( option = "verbose", @@ -116,11 +136,19 @@ abstract class ExtractBitcodeTask @Inject constructor(project: Project) : Defaul ) val verbose: Property = objects.property(Boolean::class.java).convention(false) + /** + * By default, stores [inputFilePath] resolved to the project's directory. + * This property is expected to be readonly. + */ @get:InputFile val actualInputFile: RegularFileProperty = objects.fileProperty().value( project.layout.projectDirectory.file(inputFilePath) ) + /** + * By default, stores [outputFilePath] resolved to the project's directory. + * This property is expected to be readonly. + */ @get:OutputFile val actualOutputFile: RegularFileProperty = objects.fileProperty().value( project.layout.projectDirectory.file(outputFilePath) @@ -155,6 +183,7 @@ abstract class ExtractBitcodeTask @Inject constructor(project: Project) : Defaul } } + /** Performs bitcode extraction. */ @TaskAction fun produce() { validateArguments() From 911f010f5ab51e9289bde17804ad8b24240c797a Mon Sep 17 00:00:00 2001 From: GlebSolovev Date: Mon, 4 Mar 2024 05:09:33 +0100 Subject: [PATCH 3/4] Move plugin to `org.jetbrains.bitcodetools.plugin` --- DEVELOPMENT_GUIDE.md | 2 +- README.md | 2 +- example/build.gradle.kts | 6 +++--- plugin-build/gradle.properties | 8 ++++---- .../bitcodetools}/plugin/BitcodeAnalysisException.kt | 2 +- .../bitcodetools}/plugin/BitcodeAnalysisPlugin.kt | 2 +- .../bitcodetools}/plugin/DecompileBitcodeExtension.kt | 2 +- .../bitcodetools}/plugin/DecompileBitcodeTask.kt | 2 +- .../bitcodetools}/plugin/ExtractBitcodeExtension.kt | 2 +- .../jetbrains/bitcodetools}/plugin/ExtractBitcodeTask.kt | 2 +- .../bitcodetools}/plugin/BitcodeAnalysisPluginTest.kt | 2 +- plugin-build/settings.gradle.kts | 2 +- 12 files changed, 17 insertions(+), 17 deletions(-) rename plugin-build/plugin/src/main/java/{com/glebsolovev/kotlin/bitcodetools/gradle => org/jetbrains/bitcodetools}/plugin/BitcodeAnalysisException.kt (66%) rename plugin-build/plugin/src/main/java/{com/glebsolovev/kotlin/bitcodetools/gradle => org/jetbrains/bitcodetools}/plugin/BitcodeAnalysisPlugin.kt (99%) rename plugin-build/plugin/src/main/java/{com/glebsolovev/kotlin/bitcodetools/gradle => org/jetbrains/bitcodetools}/plugin/DecompileBitcodeExtension.kt (96%) rename plugin-build/plugin/src/main/java/{com/glebsolovev/kotlin/bitcodetools/gradle => org/jetbrains/bitcodetools}/plugin/DecompileBitcodeTask.kt (97%) rename plugin-build/plugin/src/main/java/{com/glebsolovev/kotlin/bitcodetools/gradle => org/jetbrains/bitcodetools}/plugin/ExtractBitcodeExtension.kt (97%) rename plugin-build/plugin/src/main/java/{com/glebsolovev/kotlin/bitcodetools/gradle => org/jetbrains/bitcodetools}/plugin/ExtractBitcodeTask.kt (99%) rename plugin-build/plugin/src/test/java/{com/glebsolovev/kotlin/bitcodetools/gradle => org/jetbrains/bitcodetools}/plugin/BitcodeAnalysisPluginTest.kt (61%) diff --git a/DEVELOPMENT_GUIDE.md b/DEVELOPMENT_GUIDE.md index 40ab33d..4a9c0c1 100644 --- a/DEVELOPMENT_GUIDE.md +++ b/DEVELOPMENT_GUIDE.md @@ -56,7 +56,7 @@ In the [.github/workflows/](.github/workflows/) folder you can find scripts for 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](plugin-build/plugin/src/test/java/com/glebsolovev/kotlin/bitcodetools/gradle/plugin/) contains only a mock one. +* Write actual tests for the plugin. So far [the test folder](plugin-build/plugin/src/test/java/org/jetbrains/bitcodetools/plugin/) 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. diff --git a/README.md b/README.md index 3af6995..fdb53e5 100644 --- a/README.md +++ b/README.md @@ -125,7 +125,7 @@ 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("com.glebsolovev.kotlin.bitcodetools.gradle.plugin") + id("org.jetbrains.bitcodetools.plugin") } ``` If your working in IDE, it'd better to rebuild Gradle at this point, so to access lovely DSL auto-completion. diff --git a/example/build.gradle.kts b/example/build.gradle.kts index f71af73..b385881 100644 --- a/example/build.gradle.kts +++ b/example/build.gradle.kts @@ -1,9 +1,9 @@ -import com.glebsolovev.kotlin.bitcodetools.gradle.plugin.DecompileBitcodeTask -import com.glebsolovev.kotlin.bitcodetools.gradle.plugin.ExtractBitcodeTask +import org.jetbrains.bitcodetools.plugin.DecompileBitcodeTask +import org.jetbrains.bitcodetools.plugin.ExtractBitcodeTask plugins { kotlin("multiplatform") - id("com.glebsolovev.kotlin.bitcodetools.gradle.plugin") + id("org.jetbrains.bitcodetools.plugin") } group = "me.user" diff --git a/plugin-build/gradle.properties b/plugin-build/gradle.properties index bd53733..b355224 100644 --- a/plugin-build/gradle.properties +++ b/plugin-build/gradle.properties @@ -1,8 +1,8 @@ -ID=com.glebsolovev.kotlin.bitcodetools.gradle.plugin +ID=org.jetbrains.bitcodetools.plugin VERSION=1.0.0 -GROUP=com.glebsolovev.kotlin.bitcodetools.gradle +GROUP=org.jetbrains.bitcodetools DISPLAY_NAME=Gradle tools to analyze bitcode of a Kotlin/Native project -DESCRIPTION=Gradle plugin providing tools for KN-bitcode-analysis: obtain bitcode, make it human-readable, extract its desired part. +DESCRIPTION=Gradle plugin providing tools for KN-bitcode-analysis: obtain bitcode, make it human-readable, extract its desired parts. WEBSITE=https://github.com/GlebSolovev/bitcode-tools VCS_URL=https://github.com/GlebSolovev/bitcode-tools -IMPLEMENTATION_CLASS=com.glebsolovev.kotlin.bitcodetools.gradle.plugin.BitcodeAnalysisPlugin +IMPLEMENTATION_CLASS=org.jetbrains.bitcodetools.plugin.BitcodeAnalysisPlugin diff --git a/plugin-build/plugin/src/main/java/com/glebsolovev/kotlin/bitcodetools/gradle/plugin/BitcodeAnalysisException.kt b/plugin-build/plugin/src/main/java/org/jetbrains/bitcodetools/plugin/BitcodeAnalysisException.kt similarity index 66% rename from plugin-build/plugin/src/main/java/com/glebsolovev/kotlin/bitcodetools/gradle/plugin/BitcodeAnalysisException.kt rename to plugin-build/plugin/src/main/java/org/jetbrains/bitcodetools/plugin/BitcodeAnalysisException.kt index 43e5768..a24b052 100644 --- a/plugin-build/plugin/src/main/java/com/glebsolovev/kotlin/bitcodetools/gradle/plugin/BitcodeAnalysisException.kt +++ b/plugin-build/plugin/src/main/java/org/jetbrains/bitcodetools/plugin/BitcodeAnalysisException.kt @@ -1,4 +1,4 @@ -package com.glebsolovev.kotlin.bitcodetools.gradle.plugin +package org.jetbrains.bitcodetools.plugin import org.gradle.api.GradleException diff --git a/plugin-build/plugin/src/main/java/com/glebsolovev/kotlin/bitcodetools/gradle/plugin/BitcodeAnalysisPlugin.kt b/plugin-build/plugin/src/main/java/org/jetbrains/bitcodetools/plugin/BitcodeAnalysisPlugin.kt similarity index 99% rename from plugin-build/plugin/src/main/java/com/glebsolovev/kotlin/bitcodetools/gradle/plugin/BitcodeAnalysisPlugin.kt rename to plugin-build/plugin/src/main/java/org/jetbrains/bitcodetools/plugin/BitcodeAnalysisPlugin.kt index 793379f..6faba0b 100644 --- a/plugin-build/plugin/src/main/java/com/glebsolovev/kotlin/bitcodetools/gradle/plugin/BitcodeAnalysisPlugin.kt +++ b/plugin-build/plugin/src/main/java/org/jetbrains/bitcodetools/plugin/BitcodeAnalysisPlugin.kt @@ -1,4 +1,4 @@ -package com.glebsolovev.kotlin.bitcodetools.gradle.plugin +package org.jetbrains.bitcodetools.plugin import org.gradle.api.Plugin import org.gradle.api.Project diff --git a/plugin-build/plugin/src/main/java/com/glebsolovev/kotlin/bitcodetools/gradle/plugin/DecompileBitcodeExtension.kt b/plugin-build/plugin/src/main/java/org/jetbrains/bitcodetools/plugin/DecompileBitcodeExtension.kt similarity index 96% rename from plugin-build/plugin/src/main/java/com/glebsolovev/kotlin/bitcodetools/gradle/plugin/DecompileBitcodeExtension.kt rename to plugin-build/plugin/src/main/java/org/jetbrains/bitcodetools/plugin/DecompileBitcodeExtension.kt index deea03b..f414ced 100644 --- a/plugin-build/plugin/src/main/java/com/glebsolovev/kotlin/bitcodetools/gradle/plugin/DecompileBitcodeExtension.kt +++ b/plugin-build/plugin/src/main/java/org/jetbrains/bitcodetools/plugin/DecompileBitcodeExtension.kt @@ -1,4 +1,4 @@ -package com.glebsolovev.kotlin.bitcodetools.gradle.plugin +package org.jetbrains.bitcodetools.plugin import org.gradle.api.Project import javax.inject.Inject diff --git a/plugin-build/plugin/src/main/java/com/glebsolovev/kotlin/bitcodetools/gradle/plugin/DecompileBitcodeTask.kt b/plugin-build/plugin/src/main/java/org/jetbrains/bitcodetools/plugin/DecompileBitcodeTask.kt similarity index 97% rename from plugin-build/plugin/src/main/java/com/glebsolovev/kotlin/bitcodetools/gradle/plugin/DecompileBitcodeTask.kt rename to plugin-build/plugin/src/main/java/org/jetbrains/bitcodetools/plugin/DecompileBitcodeTask.kt index 10282b5..d730905 100644 --- a/plugin-build/plugin/src/main/java/com/glebsolovev/kotlin/bitcodetools/gradle/plugin/DecompileBitcodeTask.kt +++ b/plugin-build/plugin/src/main/java/org/jetbrains/bitcodetools/plugin/DecompileBitcodeTask.kt @@ -1,4 +1,4 @@ -package com.glebsolovev.kotlin.bitcodetools.gradle.plugin +package org.jetbrains.bitcodetools.plugin import org.gradle.api.DefaultTask import org.gradle.api.Project diff --git a/plugin-build/plugin/src/main/java/com/glebsolovev/kotlin/bitcodetools/gradle/plugin/ExtractBitcodeExtension.kt b/plugin-build/plugin/src/main/java/org/jetbrains/bitcodetools/plugin/ExtractBitcodeExtension.kt similarity index 97% rename from plugin-build/plugin/src/main/java/com/glebsolovev/kotlin/bitcodetools/gradle/plugin/ExtractBitcodeExtension.kt rename to plugin-build/plugin/src/main/java/org/jetbrains/bitcodetools/plugin/ExtractBitcodeExtension.kt index b984ed7..e94cc7b 100644 --- a/plugin-build/plugin/src/main/java/com/glebsolovev/kotlin/bitcodetools/gradle/plugin/ExtractBitcodeExtension.kt +++ b/plugin-build/plugin/src/main/java/org/jetbrains/bitcodetools/plugin/ExtractBitcodeExtension.kt @@ -1,4 +1,4 @@ -package com.glebsolovev.kotlin.bitcodetools.gradle.plugin +package org.jetbrains.bitcodetools.plugin import org.gradle.api.Project import org.gradle.api.provider.ListProperty diff --git a/plugin-build/plugin/src/main/java/com/glebsolovev/kotlin/bitcodetools/gradle/plugin/ExtractBitcodeTask.kt b/plugin-build/plugin/src/main/java/org/jetbrains/bitcodetools/plugin/ExtractBitcodeTask.kt similarity index 99% rename from plugin-build/plugin/src/main/java/com/glebsolovev/kotlin/bitcodetools/gradle/plugin/ExtractBitcodeTask.kt rename to plugin-build/plugin/src/main/java/org/jetbrains/bitcodetools/plugin/ExtractBitcodeTask.kt index 8d42822..c059045 100644 --- a/plugin-build/plugin/src/main/java/com/glebsolovev/kotlin/bitcodetools/gradle/plugin/ExtractBitcodeTask.kt +++ b/plugin-build/plugin/src/main/java/org/jetbrains/bitcodetools/plugin/ExtractBitcodeTask.kt @@ -1,4 +1,4 @@ -package com.glebsolovev.kotlin.bitcodetools.gradle.plugin +package org.jetbrains.bitcodetools.plugin import org.gradle.api.DefaultTask import org.gradle.api.Project diff --git a/plugin-build/plugin/src/test/java/com/glebsolovev/kotlin/bitcodetools/gradle/plugin/BitcodeAnalysisPluginTest.kt b/plugin-build/plugin/src/test/java/org/jetbrains/bitcodetools/plugin/BitcodeAnalysisPluginTest.kt similarity index 61% rename from plugin-build/plugin/src/test/java/com/glebsolovev/kotlin/bitcodetools/gradle/plugin/BitcodeAnalysisPluginTest.kt rename to plugin-build/plugin/src/test/java/org/jetbrains/bitcodetools/plugin/BitcodeAnalysisPluginTest.kt index 5246df3..8f65766 100644 --- a/plugin-build/plugin/src/test/java/com/glebsolovev/kotlin/bitcodetools/gradle/plugin/BitcodeAnalysisPluginTest.kt +++ b/plugin-build/plugin/src/test/java/org/jetbrains/bitcodetools/plugin/BitcodeAnalysisPluginTest.kt @@ -1,4 +1,4 @@ -package com.glebsolovev.kotlin.bitcodetools.gradle.plugin +package org.jetbrains.bitcodetools.plugin import org.junit.Test diff --git a/plugin-build/settings.gradle.kts b/plugin-build/settings.gradle.kts index 6f0a4df..5f29b68 100644 --- a/plugin-build/settings.gradle.kts +++ b/plugin-build/settings.gradle.kts @@ -31,6 +31,6 @@ gradleEnterprise { } } -rootProject.name = ("com.glebsolovev.kotlin.bitcodetools.gradle") +rootProject.name = ("org.jetbrains.bitcodetools") include(":plugin") From 25fc9dd961bdc41c0ca509175338f598cdbe8e9b Mon Sep 17 00:00:00 2001 From: GlebSolovev Date: Mon, 4 Mar 2024 05:19:34 +0100 Subject: [PATCH 4/4] Add "JetBrains Research" badge --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index fdb53e5..9913d25 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,9 @@ # Bitcode tools for Kotlin/Native projects πŸ„ΊπŸ„½πŸ˜ +[![JetBrains Research](https://jb.gg/badges/research.svg)](https://confluence.jetbrains.com/display/ALL/JetBrains+on+GitHub) +[![Checks](https://github.com/GlebSolovev/bitcode-tools/actions/workflows/checks.yaml/badge.svg?branch=main)](https://github.com/GlebSolovev/bitcode-tools/actions/workflows/checks.yaml) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE) [![Contributions welcome](https://img.shields.io/badge/Contributions-welcome-brightgreen.svg?style=flat)](#contributing--developing) -[![Checks](https://github.com/GlebSolovev/bitcode-tools/actions/workflows/checks.yaml/badge.svg?branch=main)](https://github.com/GlebSolovev/bitcode-tools/actions/workflows/checks.yaml) A simple **Gradle plugin** that provides tasks **to obtain and analyze bitcode** for any Kotlin/Native projects.