Skip to content

Latest commit

 

History

History
294 lines (224 loc) · 10.4 KB

File metadata and controls

294 lines (224 loc) · 10.4 KB

DiffKemp development

This document will guide you through DiffKemp development. It contains information about:

To learn about how to contribute your changes to the main repository, read contributing guide.

Development environment

For developing DiffKemp, you can use:

Nix

We provide Nix flakes for building and testing DiffKemp.

First, it is necessary to install Nix and enable flakes:

mkdir -p ~/.config/nix
echo "experimental-features = nix-command flakes" >> ~/.config/nix/nix.conf

Then, building DiffKemp is as simple as running one of the following commands:

nix build                    # <- uses latest LLVM
nix build .#diffkemp-llvm14

This will create a new folder result/ containing the pre-built DiffKemp which can be then executed by:

result/bin/diffkemp ...

Tip

Rather than building DiffKemp with Nix, it is better to use Nix development environment described below, because the DiffKemp build created by Nix has following drawbacks:

  • Currently it is not possible to run view subcommand (the result viewer).
  • You still need to have some dependencies installed on your system to be able to use it (clang, llvm, and dependencies specific to the project you want to analyse).

Nix as development environment

It is also possible to use Nix as a development environment:

nix develop                   # <- uses latest LLVM
nix develop .#diffkemp-llvm14

This will enter a development shell with all DiffKemp dependencies pre-installed. You can then follow the standard build instructions to build and install DiffKemp. The only difference is that you do not need to install the Python dependencies because they are already preinstalled.

The generated executable is then located in BUILD_DIR/bin/diffkemp.

We also provide a special Nix environment for retrieving and preparing kernel versions necessary for running regression tests (nix develop .#test-kernel-buildenv).

Local development environment

You can also develop DiffKemp directly. For this you need to install the necessary dependencies to your system and then you may build DiffKemp.

The generated executable is then located in BUILD_DIR/bin/diffkemp.

Build

To build DiffKemp, use the following commands:

cmake -S . -B build -GNinja -DBUILD_VIEWER=On
ninja -C build
  • -DBUILD_VIEWER=On: This flag will install packages and build the result viewer. It will try to install the packages on every cmake run, so you may want to use -DBUILD_VIEWER=Off instead.

If you make changes to the SimpLL library, you will need to rebuild it by running ninja -C <BUILD_DIR>. We are using CFFI for accessing the library from the Python.

To be able to use DiffKemp, it is also necessary to install Python dependencies, you can install them:

  • by running pip install . && pip uninstall -y diffkemp or
  • install them manually by using pip install <DEPENDENCIES> (dependencies are specified in packages field in pyproject.toml file).

Note

If you used different than the default build directory (build) and want to use pip install . for installing python dependencies, then you need to specify the build directory when running pip by using SIMPLL_BUILD_DIR=<BUILD_DIR> pip install ..

Coding style

We require that the code is according to a certain coding style, which can be checked with the following tools:

  • For Python code: flake8 diffkemp tests.
  • For C++ code: it is necessary to have clang-format installed and the coding style can be checked with tools/check-clang-format.sh -d (it can be also automatically fixed by running tools/check-clang-format.sh -di).
  • For JavaScript code: npm --prefix view run lint.

Tests

The project contains multiple tests:

Python tests

By default, the DiffKemp generates its own test runner executable located in BUILD_DIR/bin/run_pytest_tests.py.

In addition to the standard diffkemp package you also have to install the development dependencies by running:

pip instal .[dev]

In a case where you have installed both the diffkemp package and development dependencies you can run the tests by:

pytest tests

There are 2 types of tests:

  • Unit tests (located in tests/unit_tests/)
  • Regression tests (located in tests/regression/)

The tests require the sources of the following kernel versions to be stored and configured in kernel/linux-{version} directories:

  • 3.10 (upstream kernel)
  • 4.11 (upstream kernel)
  • 3.10.0-514.el7 (CentOS 7.3 kernel)
  • 3.10.0-693.el7 (CentOS 7.4 kernel)
  • 3.10.0-862.el7 (CentOS 7.5 kernel)
  • 3.10.0-957.el7 (CentOS 7.6 kernel)
  • 4.18.0-80.el8 (RHEL 8.0 kernel)
  • 4.18.0-147.el8 (RHEL 8.1 kernel)
  • 4.18.0-193.el8 (RHEL 8.2 kernel)
  • 4.18.0-240.el8 (RHEL 8.3 kernel)

The required configuration of each kernel can be done by running:

make prepare
make modules_prepare

The rhel-kernel-get script can also be used to download and configure the aforementioned kernels.

Tip

Since CentOS 7 kernels require a rather old GCC 7, the most convenient way to download the kernels is to use the prepared Nix environment by running

nix develop .#test-kernel-buildenv

and using rhel-kernel-get inside the environment to retrieve the above kernels.

Tests for the SimpLL library

Tests are located in tests/unit_tests/simpll/ directory and they can be run by:

ninja -C build test

In case the tests fail, enabling logger can simplify the debugging process. The logger is enabled by setting the SIMPLL_VERBOSITY environment variable to a number, where:

  • 0: No logging
  • 1: Minimal logging
  • 2: Moderate logging
  • 3 and more: Detailed logging (the most verbose)

For example, to enable moderate logging while running tests with ninja, use the following command:

SIMPLL_VERBOSITY=2 ninja -C build test

Tests for the result viewer

The result viewer contains unit tests and integration tests located in view/src/tests/ directory and they can be run by:

npm --prefix view test -- --watchAll
npm --prefix view run cypress:run

Adding a new version of LLVM to the project

Diffkemp is based on augmentation of the FunctionComparator; however, this class is not polymorphic in the upstream and because of that we have to add it to the project manually. The steps required to do so are:

  1. Extract the FunctionComparator.cpp and FunctionComparator.h from the LLVM project monorepo, take the most recent release of your target major version (i.e., prefer 19.1.7 over 19.1.6).
  2. Create a new subdirectory at path diffkemp/simpll/llvm-lib/<MAJOR VERSION>, where MAJOR VERSION is the major version of the LLVM that you want to support.
  3. Move all private methods of FunctionComparator to protected scope.
  4. Make all methods of FunctionComparator and GlobalNumberState virtual.
  5. Change the path to FunctionComparator header in the source file of the version that you are adding (it has to be made local, instead of including the LLVM one).
    - #include "llvm/Transforms/Utils/FunctionComparator.h"
    + #include "FunctionComparator.h"
  6. Update CI (i.e., add the new version to the list here and change the most recent LLVM version here and in the code style check) and Nix (change the range of supported version here) files with your new version. You also have to update the docs.
  7. Make the project compilable and resolve any performance issues. However, you have to make sure that the source code of the whole project is working with all supported LLVM versions. This is usually achieved by introduction of preprocessor directives into the code, an example can found here.

Tools for performing experiments

We have some tools which can be handy when developing DiffKemp:

Useful links