C/C++ Unable to link with JVM library


(Joseph Fota) #1

As part of the compiler args, I’ve included the full path to libjvm.so

/*
 * libhbase_test executable
 */
executables {
    libhbase_test {
        binaries.all {
            lib libraries['libhbase-jni'].shared
            cCompiler.args "-std=gnu99",
"-L/usr/lib/jvm/java-7-openjdk-amd64/jre/lib/amd64/server", "-L/usr/lib/jvm/java-7-openjdk-amd64/jre/lib/amd64/jamvm", "-ljvm", "-MMD", "-MP"
        }
    }
}

Yet the error generated when compiling the executable would seem to indicate that the -L<path_to_libjvm.so> -ljvm is not being seen.

[...]
:linkLibhbase-jniSharedLibrary UP-TO-DATE
:libhbase-jniSharedLibrary UP-TO-DATE
:linkLibhbase_testExecutable
/tmp/private-libhbase/build/binaries/libhbase-jniSharedLibrary/liblibhbase-jni.so: undefined reference to 'JNI_GetCreatedJavaVMs'
/tmp/private-libhbase/build/binaries/libhbase-jniSharedLibrary/liblibhbase-jni.so: undefined reference to 'JNI_CreateJavaVM'
collect2: ld returned 1 exit status
:linkLibhbase_testExecutable FAILED
  FAILURE: Build failed with an exception.
  * What went wrong:
Execution failed for task ':linkLibhbase_testExecutable'.
> Linker failed; see the error output for details.
  * Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
  BUILD FAILED

Clearly, I’m doing something wrong. I just don’t know what.

apply plugin: 'c'
apply plugin: 'cpp'
import org.apache.tools.ant.taskdefs.condition.Os
    ext {
     javaHome = System.getenv('JAVA_HOME')
    javaHomeInclude = javaHome + '/include'
      if (System.properties['os.name'].toLowerCase().contains('linux'))
    {
        javaHomeIncludeOs = javaHomeInclude + '/linux'
    }
    else
    {
        javaHomeIncludeOs = javaHomeInclude + '/win32'
    }
}
    dependencies {
    if (! javaHome) {
        logger.error('JAVA_HOME is not set.')
    }
          println 'JAVA_HOME: ' + javaHome
}
    /*
 * libhbase-jni shared library
 */
libraries {
    'libhbase-jni' {
        binaries.withType(SharedLibraryBinary)
     }
}
    sources {
    'libhbase-jni' {
        cpp {
            source {
                srcDirs "src/jni_impl"
                include "*.cc"
            }
            exportedHeaders {
                srcDirs "include", javaHomeInclude, javaHomeIncludeOs
                include "**/*.h"
            }
        }
        c {
            source {
                srcDirs "src/common"
                include "*.c"
            }
            exportedHeaders {
                srcDirs "include"
                include "*.h"
            }
        }
    }
}
    /*
 * libhbase_test executable
 */
executables {
    libhbase_test {
        binaries.all {
            lib 'libraries.libhbase-jni.shared'
            cCompiler.args "-std=gnu99"
        }
    }
}
    sources {
    libhbase_test {
        c {
            source {
                srcDir "example"
                include "*.c"
            }
              exportedHeaders {
                srcDir "include"
            }
         }
    }
}
    /*
 * Build tasks
 */
task wrapper(type: Wrapper) {
    description 'A wrapper which downloads and/or uses Gradle 1.10-rc-1'
    gradleVersion = '1.10-rc-1'
}
    task 'libhbase-jni' (dependsOn: 'libhbase-jniSharedLibrary') {
    description 'Build libhbase-jni shared library.'
}
    task 'libhbase_test' (dependsOn: 'libhbase_testExecutable') {
    description 'Build libhabase_test executable.'

#2

Additional linker arguments need to be supplied using ‘linker.args’. A good way to debug is to inspect the generated linker options file in ‘build/tmp’.

You are probably better off declaring these dependencies as ‘PrebuiltLibraries’: see the sample included in the latest gradle nightly (not 1.10).


(Joseph Fota) #3

I’m posting this solution for others that may be looking for C/C++ examples.

apply plugin: 'c'
apply plugin: 'cpp'
import org.apache.tools.ant.taskdefs.condition.Os
  model {
    buildTypes {
        release
    }
    repositories {
        libs(PrebuiltLibraries) {
            jvm {
                binaries.withType(SharedLibraryBinary) {
                    sharedLibraryFile = file("/usr/lib/jvm/java-7-openjdk-amd64/jre/lib/amd64/server/libjvm.so")
                }
            }
        }
    }
}
  ext {
     javaHome = System.getenv('JAVA_HOME')
    javaHomeInclude = javaHome + '/include'
      if (System.properties['os.name'].toLowerCase().contains('linux'))
    {
        javaHomeIncludeOs = javaHomeInclude + '/linux'
    }
    else
    {
        javaHomeIncludeOs = javaHomeInclude + '/win32'
    }
}
    dependencies {
    if (! javaHome) {
        logger.error('JAVA_HOME is not set.')
    }
          println 'JAVA_HOME: ' + javaHome
}
    /*
 * libhbase-jni shared library
 */
libraries {
    'libhbase-jni' {
        binaries.withType(SharedLibraryBinary)
     }
}
    sources {
    'libhbase-jni' {
        cpp {
            source {
                srcDirs "src/jni_impl"
                include "*.cc"
            }
            exportedHeaders {
                srcDirs "include", javaHomeInclude, javaHomeIncludeOs
                include "**/*.h"
            }
        }
        c {
            source {
                srcDirs "src/common"
                include "*.c"
            }
            exportedHeaders {
                srcDirs "include"
                include "*.h"
            }
        }
    }
}
    /*
 * libhbase_test executable
 */
executables {
    libhbase_test {
        binaries.all {
            lib libraries['libhbase-jni'].shared
             cCompiler.args "-ljvm", "-std=gnu99"
         }
    }
}
    sources {
    libhbase_test {
        c {
            source {
                srcDir "example"
                include "*.c"
            }
              exportedHeaders {
                srcDir "include"
            }
               lib library: 'jvm'
        }
    }
}
    /*
 * Build tasks
 */
task wrapper(type: Wrapper) {
    description 'A wrapper which downloads and/or uses Gradle 1.11-20140109230012+0000'
    gradleVersion = '1.11-20140109230012+0000'
}
    task 'libhbase-jni' (dependsOn: 'libhbase-jniSharedLibrary') {
    description 'Build libhbase-jni shared library.'
}
    task 'libhbase_test' (dependsOn: 'libhbase_testExecutable') {
    description 'Build libhabase_test executable.'
}