2017-07-26 80 views
1

我嘗試添加C函數到我的Java Android應用程序。
我已經成功地在C.
在這個文件中的hello.c我打電話包含在另一個文件(astart.c)另一個C函數本身在另一個文件調用另一個函數C運行基本功能的Hello World(util.c )在其他文件中調用其他函數。
沒問題,不是嗎?未定義的引用與CMake的功能在Android Studio中

我的庫添加到我的CMakeLists.txt:

# Sets the minimum version of CMake required to build the native 
# library. You should either keep the default value or only pass a 
# value of 3.4.0 or lower. 

cmake_minimum_required(VERSION 3.4.1) 

# Creates and names a library, sets it as either STATIC 
# or SHARED, and provides the relative paths to its source code. 
# You can define multiple libraries, and CMake builds it for you. 
# Gradle automatically packages shared libraries with your APK. 

add_library(# Sets the name of the library. 
     native-lib 

     # Sets the library as a shared library. 
     SHARED 

     # Provides a relative path to your source file(s). 
     # Associated headers in the same location as their source 
     # file are automatically included. 
     src/main/cpp/native-lib.cpp) 

add_library(hello 

     # Sets the library as a shared library. 
     SHARED 

     src/main/myCpp/hello.c) 

add_library(astart 

     # Sets the library as a shared library. 
     SHARED 

     src/main/myCpp/astart.c) 

add_library(ai 

     # Sets the library as a shared library. 
     SHARED 

     src/main/myCpp/lib/ai.c) 

add_library(sha 

     # Sets the library as a shared library. 
     SHARED 

     src/main/myCpp/lib/sha.c) 

add_library(util 

     # Sets the library as a shared library. 
     SHARED 

     src/main/myCpp/lib/util.c) 

add_library(allnet_log 

     # Sets the library as a shared library. 
     SHARED 

     src/main/myCpp/lib/allnet_log.c) 

#add_library(packet 

     # Sets the library as a shared library. 
#   SHARED 

#   src/main/myCpp/lib/packet.c) 

add_library(configfiles 

     # Sets the library as a shared library. 
     SHARED 

     src/main/myCpp/lib/configfiles.c) 

add_library(allnet_queue 

     # Sets the library as a shared library. 
     SHARED 

     src/main/myCpp/lib/allnet_queue.c) 



# Add the directories where the Cpp header files are to let CMake    find them during compile time 
include_directories(src/main/myCpp/) 
include_directories(src/main/myCpp/lib/) 

# Searches for a specified prebuilt library and stores the path as a 
# variable. Because system libraries are included in the search path by 
# default, you only need to specify the name of the public NDK library 
# you want to add. CMake verifies that the library exists before 
# completing its build. 

find_library(# Sets the name of the path variable. 
      log-lib 

      # Specifies the name of the NDK library that 
      # you want CMake to locate. 
      log) 

# Specifies libraries CMake should link to your target library. You 
# can link multiple libraries, such as libraries you define in the 
# build script, prebuilt third-party libraries, or system libraries. 

target_link_libraries(# Specifies the target library. 
        native-lib 

        # Links the target library to the log library 
        # included in the NDK. 
        ${log-lib}) 

我gradle這個文件:

apply plugin: 'com.android.application' 

android { 
compileSdkVersion 25 
buildToolsVersion "25.0.0" 
defaultConfig { 
    applicationId "com.example.hippolytelacassagne.allnet" 
    minSdkVersion 19 
    targetSdkVersion 25 
    versionCode 1 
    versionName "1.0" 
    testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 
    externalNativeBuild { 
     cmake { 
      cppFlags "" 
      cFlags "-fexceptions" 
     } 
    } 
} 
buildTypes { 
    release { 
     minifyEnabled false 
     proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 
    } 
} 
externalNativeBuild { 
    cmake { 
     path "CMakeLists.txt" 
    } 
} 

// If you want Gradle to package prebuilt native libraries 
// with your APK, modify the default source set configuration 
// to include the directory of your prebuilt .so files as follows. 
sourceSets { 
    main { 
     jni.srcDirs = [] 
     jniLibs.srcDirs 'imported-lib/src/', 'more-imported- libs/src/' 
    } 
} 
} 

dependencies { 
compile fileTree(include: ['*.jar'], dir: 'libs') 
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { 
    exclude group: 'com.android.support', module: 'support-annotations' 
}) 
compile 'com.android.support:appcompat-v7:25.3.1' 
testCompile 'junit:junit:4.12' 
} 

我的hello.c稱爲Home.java:

#include <jni.h> 

#include "lib/app_util.h" 
#include "lib/packet.h" 
#include "astart.c" 

JNIEXPORT 
jstring 
JNICALL 
Java_com_example_hippolytelacassagne_allnet_Home_Hello(
JNIEnv *env, 
jobject callingObject) 
{ 
    char * args [] = { "allnet", "-v", "def", NULL }; 
    astart_main(3, args); 
    return (*env)->NewStringUTF(env, "Hello World"); 
} 

的包括如果叫hello.c的astart.c:

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <string.h> 
#include <fcntl.h> 
#include <signal.h> 
#include <pwd.h> 
#include <ifaddrs.h> 
#include <dirent.h> 
#include <unistd.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <sys/wait.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <net/if.h>  /* IFF_LOOPBACK, etc */ 
#include <arpa/inet.h> /* inet_addr */ 

#include "lib/util.h" 
#include "lib/allnet_log.h" 
#include "lib/packet.h" 
#include "lib/configfiles.h" 
#include "lib/allnet_queue.h" 

而且包括util.c叫astart.c的:

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <string.h> 
#include <fcntl.h> 
#include <time.h> 
#include <assert.h> 
#include <errno.h> 
#include <netdb.h> /* h_errno */ 
#include <dirent.h> /* h_errno */ 
#include <sys/time.h> 
#include <sys/stat.h> 
#include <sys/socket.h> 
#include <sys/types.h> 
#include <sys/un.h> 
#include <netinet/in.h> 
#include <arpa/inet.h> 

#include "packet.h" 
#include "mgmt.h" 
#include "allnet_log.h" 
#include "util.h" 
#include "ai.h" 
#include "sha.h" 

這裏是gradle這個控制檯的錯誤消息:

FAILURE: Build failed with an exception. 

* What went wrong: 
Execution failed for task ':app:externalNativeBuildDebug'. 
> Build command failed. 
    Error while executing '/Users/hippolytelacassagne/Library/Android/sdk/cmake/3.6.4111459/bin/cmake' with arguments {--build /Users/hippolytelacassagne/AndroidStudioProjects/Allnet/app/.externalNativeBuild/cmake/debug/mips64 --target util} 
    [1/2] Building C object CMakeFiles/util.dir/src/main/myCpp/lib/util.c.o 
    [2/2] Linking C shared library ../../../../build/intermediates/cmake/debug/obj/mips64/libutil.so 
    FAILED: : && /Users/hippolytelacassagne/Library/Android/sdk/ndk-bundle/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang --target=mips64el-none-linux-android --gcc-toolchain=/Users/hippolytelacassagne/Library/Android/sdk/ndk-bundle/toolchains/mips64el-linux-android-4.9/prebuilt/darwin-x86_64 --sysroot=/Users/hippolytelacassagne/Library/Android/sdk/ndk-bundle/sysroot -fPIC -isystem /Users/hippolytelacassagne/Library/Android/sdk/ndk-bundle/sysroot/usr/include/mips64el-linux-android -D__ANDROID_API__=21 -g -DANDROID -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -fintegrated-as -Wa,--noexecstack -Wformat -Werror=format-security -fexceptions -O0 -fno-limit-debug-info -Wl,--exclude-libs,libgcc.a --sysroot /Users/hippolytelacassagne/Library/Android/sdk/ndk-bundle/platforms/android-21/arch-mips64 -Wl,--build-id -Wl,--warn-shared-textrel -Wl,--fatal-warnings -Wl,--no-undefined -Wl,-z,noexecstack -Qunused-arguments -Wl,-z,relro -Wl,-z,now -shared -Wl,-soname,libutil.so -o ../../../../build/intermediates/cmake/debug/obj/mips64/libutil.so CMakeFiles/util.dir/src/main/myCpp/lib/util.c.o -lm && : 
    CMakeFiles/util.dir/src/main/myCpp/lib/util.c.o: In function `mgmt_to_string': 
    /Users/hippolytelacassagne/AndroidStudioProjects/Allnet/app/src/main/myCpp/lib/util.c:245: undefined reference to `ia_to_string' 
    /Users/hippolytelacassagne/AndroidStudioProjects/Allnet/app/src/main/myCpp/lib/util.c:274: undefined reference to `ia_to_string' 
    CMakeFiles/util.dir/src/main/myCpp/lib/util.c.o: In function `init_packet': 
    /Users/hippolytelacassagne/AndroidStudioProjects/Allnet/app/src/main/myCpp/lib/util.c:532: undefined reference to `sha512_bytes' 
    CMakeFiles/util.dir/src/main/myCpp/lib/util.c.o: In function `print_gethostbyname_error': 
    /Users/hippolytelacassagne/AndroidStudioProjects/Allnet/app/src/main/myCpp/lib/util.c:1554: undefined reference to `log_print' 
    clang: error: linker command failed with exit code 1 (use -v to see invocation) 
    ninja: build stopped: subcommand failed. 


* Try: 
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. 

BUILD FAILED 

這樣看來,這些錯誤來自util.c的一些功能。
我不明白,因爲據說是沒有定義的函數中包含的文件中定義。

有沒有人有想法?謝謝。

回答

0

我發現這個問題。
Android Studio中需要指定CMakeLists文件之間的依賴關係:

target_link_libraries(# Specifies the target library. 
        util 
        sha 
        ai 
        allnet_log 

        # Links the target library to the log library 
        # included in the NDK. 
        ${log-lib}) 

文件#包括是不夠的。