Makefile to gradle

My Makefile

CC = gcc

C_SRC = c/*.c

INC1 = …/lib

INC2 = c/include

ifeq ($(OS),Windows_NT)
C_FLAGS += -shared -L $(INC1) -I $(INC2) -I $(JAVA_HOME)/include -I $(JAVA_HOME)/include/win32
L_FLAGS = -lwpcap -liphlpapi
TARGET = xxx.dll
else
C_FLAGS += -shared -fPIC -L $(INC1) -I $(INC2) -I $(JAVA_HOME)/include -I $(JAVA_HOME)/include/linux
L_FLAGS = -lpcap
target = libxxx.so
endif

all:
$(CC) $(C_FLAGS) $(C_SRC) -o $(TARGET) $(L_FLAGS)

How to do it in gradle?

Most of your answers you should be able to get from https://docs.gradle.org/current/userguide/native_software.html.

If you want to stick to the same source layout, you need to pay attention to example 72.5,

Also Gradle should detect the corect toolchain by default depedneing on the operating system. So what is left to you is to set the compiler configuratiosn for each toolchain. Once gain in the same document, look at section 72.12.

Hi @ardikars,

this should help you to start work on it :wink:

apply plugin: 'idea'
apply plugin: 'c'

ext {
    /* USER DEFINED SETTINGS */
    // if multimodule build, you can use st like:
    //      thirdPartyLibsDir = project.parent.file('lib')
    thirdPartyLibsDir = file('../lib')
    headersDir = file('c/include')


    currentJvm = org.gradle.internal.jvm.Jvm.current() // I would better like this to be in Gradle's public API
    javaHome = currentJvm.javaHome.absolutePath // or detect the dir whatever way you want, e.g. you can use JAVA_HOME 
}

model {
    platforms {
        linux_x86_64 {
            architecture "x86_64"
            operatingSystem "linux"
        }
        windows_amd64 {
            architecture "x86_64"
            operatingSystem "windows"
        }
    }

    buildTypes {
        debug
        release
    }

    repositories {
        libs(PrebuiltLibraries) {
            jdk {
                headers.srcDirs "${javaHome}/include", "${javaHome}/include/linux", "${javaHome}/include/win32"
            }
        }
    }
}

model {
    components {
        main(NativeLibrarySpec) { // component 'main'

            targetPlatform 'linux_x86_64'
            targetPlatform 'windows_amd64'

            sources.c {
                source {
                    // set explicitely, if the sources are in defalt folder, i.e. src/<component>/c (here <component>='main') you can omit this
                    srcDir 'c'
                    include '*.c'
                }
                lib library: 'jdk', linkage: 'api'
            }

            binaries.withType(StaticLibraryBinarySpec) { buildable = false } // disable static libs generation


            binaries.all {
                /*
                if (buildType == buildTypes.debug) {
                    cCompiler.args '-pg', '-g'
                    cCompiler.define 'DEV'
                } else {
                    cCompiler.args '-O2'
                }
                */

                cCompiler.args '-std=c99' // for all binaries, regardless the platform

                if (targetPlatform.operatingSystem.windows) {
                    cCompiler.args "-L $thirdPartyLibsDir", "-I$headersDir"
                    linker.args '-lwpcap', '-liphlpapi'
                } else if (targetPlatform.operatingSystem.linux) {
                    cCompiler.args '-fPIC' // I don't think this is necessery :)
                    linker.args '-lpcap'
                }

            }
        }
    }
}

It’s in no way a complete solution, but IMHO should give you the overview what can be done with gradle.

Of course, have a look on the samples:

mkdir ~/tmp
cd ~/tmp
wget https://services.gradle.org/distributions/gradle-2.14.1-all.zip 
unzip gradle-2.14.1-all.zip
cd samples/native-binaries/

and consult the documentation as adviced by @Schalk_Cronje, especially chapter 72.11.2. (C sources) for directories layout defaults.

HTH,

2 Likes