Makefile to compile java and c program

Java class needs to call through jni the library compiled from the c program.
The following Makefile will compile / run Hello.java and hello.c

Makefile
# Names of the Java class and C source files
JAVA_CLASS = Hello
C_SOURCE = hello.c
 
# Name of the shared library (different between Windows and Unix)
UNAME_S := $(shell uname -s)
ifeq ($(UNAME_S),Linux)
    LIB_NAME = libhello.so
endif
ifeq ($(UNAME_S),Darwin)
    LIB_NAME = libhello.dylib
endif
ifeq ($(UNAME_S),Windows)
    LIB_NAME = hello.dll
endif
 
# Compilers for C and Java
CC = gcc
JAVA_HOME = $(shell readlink -f /usr/bin/javac | sed "s:/bin/javac::")
JAVA_INCLUDE = -I$(JAVA_HOME)/include -I$(JAVA_HOME)/include/linux # Modify this depending on the OS
 
# Options for the C compiler
CFLAGS = -shared -fPIC
 
# Defining targets
.PHONY: all clean
 
all: $(JAVA_CLASS).class $(LIB_NAME)
 
# Compiling the Java class and generating the JNI header
$(JAVA_CLASS).class: $(JAVA_CLASS).java
	javac -h . $(JAVA_CLASS).java
 
# Compiling the C code into a shared library
$(LIB_NAME): $(C_SOURCE) $(JAVA_CLASS).class
	$(CC) $(CFLAGS) $(JAVA_INCLUDE) -o $(LIB_NAME) $(C_SOURCE)
 
# Running the Java program
run: all
	java -Djava.library.path=. $(JAVA_CLASS)
 
# Cleaning up generated files
clean:
	rm -f $(JAVA_CLASS).class $(JAVA_CLASS_NAME)_*.h $(LIB_NAME)

To compile the programs:

make

To run the program:

make run

To cleanup the built files:

make clean

Hello.java:

Hello.java
public class Hello {
    private native void sayHello();
 
    static {
        System.loadLibrary("hello");
    }
 
    public static void main(String[] args) {
        new Hello().sayHello();
    }
}
hello.c
#include <jni.h>
#include "Hello.h"
 
JNIEXPORT void JNICALL Java_Hello_sayHello(JNIEnv *env, jobject obj) {
    printf("Hello from C!\n");
}