Unit test Java class that loads native library

前端 未结 8 635
自闭症患者
自闭症患者 2021-02-01 11:49

I\'m running unit tests in Android Studio. I have a Java class that loads a native library with the following code

 static
    {
       System.loadLibrary(\"myli         


        
8条回答
  •  旧时难觅i
    2021-02-01 12:40

    There is a way to configure library path of Gradle-run VM for local unit tests, and I'm going to describe it below, but spoiler: in my expericence, @ThanosFisherman is right: local unit tests for stuff that uses the Android NDK seem to be a fools errand right now.

    So, for anyone else looking for a way to load shared (i.e. .so) libraries into unit tests with gradle, here's the somewhat lengthy abstract:

    The goal is to set the shared library lookup path for the JVM running the unit tests.

    Althoug many people suggest putting the lib path into java.library.path, I found that it doesn't work, at least not on my linux machine. (also, same results in this CodeRanch thread)

    What does work though is setting the LD_LIBRARY_PATH os environment variable (or PATH is the closest synonym in Windows)

    Using Gradle:

    // module-level build.gradle
    apply plugin: 'com.android.library' // or application
    
    android {
        ...
    
        testOptions {
            unitTests {
                all {
                    // This is where we have access to the properties of gradle's Test class,
                    // look it  up if you want to customize more test parameters
    
                    // next we take our cmake output dir for whatever architecture
                    // you can also put some 3rd party libs here, or override
                    // the implicitly linked stuff (libc, libm and others)
    
                    def libpath = '' + projectDir + '/build/intermediates/cmake/debug/obj/x86_64/'
                        +':/home/developer/my-project/some-sdk/lib'
    
                    environment 'LD_LIBRARY_PATH', libpath
                }
            }
        }
    }
    

    With that, you can run, e.g. ./gradlew :mymodule:testDebugUnitTest and the native libs will be looked for in the paths that you specified.

    Using Android Studio JUnit plugin For the Android Studio's JUnit plugin, you can specify the VM options and the environment variables in the test configuration's settings, so just run a JUnit test (right-clicking on a test method or whatever) and then edit the Run Configuration:

    Although it sounds like "mission accomplished", I found that when using libc.so, libm.so and others from my os /usr/lib gives me version errors (probably because my own library is compiled by cmake with the android ndk toolkit against it's own platform libs). And using the platform libs from the ndk packages brought down the JVM wih a SIGSEGV error (due to incompatibility of the ndk platform libs with the host os environment)

    Update As @AlexCohn incisively pointed out in the comments, one has to build against the host environment libs for this to work; even though your machine most likely is x86_64, the x86_64 binaries built against NDK environment will not do.

    There may be something I overlooked, obviously, and I'll appreciate any feedback, but for now I'm dropping the whole idea in favor of instrumented tests.

提交回复
热议问题