Categories
graalvm Quarkus

Integrate Quarkus with C language without an issue

Imagine that your team used C language for few decades and written many different applications and tools with it. For some reason team switches to Java and now hundreds of hundreds of C logic will be abandoned? No, with Quarkus, you can execute any of this logic without leaving your Java environment.

When you use GraalVM with Quarkus(or any other environment), you have access to wide range of supported languages, starting from Python, R, and going as deep as C++ and C. In this article we’ll start looking into C language that powers many ISS software.

Getting started

Firstly, we need to prepare our machine to handle all the logic we have. This article will use Ubuntu 16. We assume that you’ve installed GraalVM already, let’s install additional software.

Install llvm toolchain

This can be done as simple as calling one line:

gu install llvm-toolchain

This command will install the required LLVM compiler and many more tools required to compile your C.

Install libpng library

This step is optional and is required only to compile our example of image generation, to do this, you need to install some apt dependencies, for Ubuntu 16 its:

sudo apt-get update && sudo apt-get install libpng-dev

Hello world from Hello world

Let’s write simple app that will call C function from Java.

Firstly, let’s init simple Quarkus project

mvn io.quarkus:quarkus-maven-plugin:1.3.2.Final:create \
    -DprojectGroupId=tech.donau.quarkify \
    -DprojectArtifactId=quarkus-cpp \
    -DclassName="tech.donau.quarkify.ExampleResource" \
    -Dpath="/hello"

Next, let’s create our first C example. I use src/main/cpp folder to hold all the C sources, feel free to use any other place. We’ll create src/main/cpp/hello.c, here’s content:

#include <stdio.h>
int main() {
   // printf() displays the string inside quotation
   printf("Hello, World!\n");
   return 0;
}

Perfect, next step is to compile this C code into bytecode.

GraalVM C compilation

If you’ll look into example root folder, you’ll can find handy shell script called buildc.sh. This script will build c code and move it into corresponding folder.

export LLVM_TOOLCHAIN=$(lli --print-toolchain-path)
$LLVM_TOOLCHAIN/gcc -I/usr/local/include -L/usr/local/lib ./src/main/cpp/example.c -o example
mv example ./src/main/resources/

Firstly, we import LLVM_TOOLCHAIN env variable that has such executables as gcc. Next, we compile with GraalVM’s gcc our C code into binaries. And finally we move it to resources folder, that we will use later.

Execute C from Java

Final step is to execute our C code from Java, which is super simple:

Testing execution

Now that everything is in place, we can call our C code. Go to http://localhost:8080/hello, you’ll see See terminal output :). Now go to output and you’ll see expected result from C code:

As you’ve seen, we don’t have any Java code that outputs hello world string, only in C.

Practical example(maybe)

Best part of using C language is that you’re not limited to any default libraries, but can use any. I initially wanted to show you Tensorflow example, but turns out it’s too much code for example. Instead, I’ll show you how you can generate avatar from C code and output it to user.

Firstly, let’s add one more c file called hello.c, here’s whole code for it:

I found and combined this example from some stackoverflow answer.

Next, let’s modify our build.c example as next:

export LLVM_TOOLCHAIN=$(lli --print-toolchain-path)
$LLVM_TOOLCHAIN/gcc -I/usr/local/include -L/usr/local/lib ./src/main/cpp/hello.c -lpng -o hello
$LLVM_TOOLCHAIN/gcc -I/usr/local/include -L/usr/local/lib ./src/main/cpp/example.c -lpng -o example
mv hello ./src/main/resources/
mv example ./src/main/resources/

This will build both hello and example, feel free to optimise this scrip 🙂

And, finally, let’s create new resource in our Quarkus project called AvatarResource.java

Now you can test it by executing ./mvnw quarkus:dev and going to http://localhost:8080/avatar

This is output of our endpoint if you run it few times. Each avatar is a little bit different in green color.

In conclusion

GraalVM provides full support for LLVM compatible languages such as C. If you have some logic that you want to serve via Java, Quarkus is a great option.

There’s even more that you can do with C++, and we’ll cover it in a next topic

Leave a Reply

Connect with




Your email address will not be published. Required fields are marked *