ndk-build:即使在LOAD_STATIC_LIBRARY上也找不到静态预构建静态库的头文件

时间:2014-05-25 14:53:52

标签: android android-ndk

我知道这个问题之前已被多次提出过,而且我已经完成了之前的答案,但它仍然没有帮助我。所以我会尽可能明确地问这个问题。

我使用android_ndk的make-standalone-toolchain.sh为x86 arch构建了一个静态库libdivecomputer.a。我把这个.a文件放在project-root / jni / include下。在此存档上运行ar可以获得此输出。

$ ar t libdivecomputer.a 
version.o
descriptor.o
iterator.o
context.o
device.o
parser.o
datetime.o
suunto_common.o
suunto_common2.o
suunto_solution.o
suunto_solution_parser.o
suunto_eon.o
suunto_eon_parser.o
suunto_vyper.o
suunto_vyper_parser.o
suunto_vyper2.o
suunto_d9.o
suunto_d9_parser.o
reefnet_sensus.o
reefnet_sensus_parser.o
reefnet_sensuspro.o
reefnet_sensuspro_parser.o
reefnet_sensusultra.o
reefnet_sensusultra_parser.o
uwatec_aladin.o
uwatec_memomouse.o
uwatec_memomouse_parser.o
uwatec_smart.o
uwatec_smart_parser.o
uwatec_meridian.o
oceanic_common.o
oceanic_atom2.o
oceanic_atom2_parser.o
oceanic_veo250.o
oceanic_veo250_parser.o
oceanic_vtpro.o
oceanic_vtpro_parser.o
mares_common.o
mares_nemo.o
mares_nemo_parser.o
mares_puck.o
mares_darwin.o
mares_darwin_parser.o
mares_iconhd.o
mares_iconhd_parser.o
ihex.o
hw_ostc.o
hw_ostc_parser.o
hw_frog.o
hw_ostc3.o
cressi_edy.o
cressi_edy_parser.o
cressi_leonardo.o
cressi_leonardo_parser.o
zeagle_n2ition3.o
atomics_cobalt.o
atomics_cobalt_parser.o
shearwater_common.o
shearwater_predator.o
shearwater_predator_parser.o
shearwater_petrel.o
diverite_nitekq.o
diverite_nitekq_parser.o
ringbuffer.o
checksum.o
array.o
buffer.o
serial_posix.o
irda_dummy.o

可以看出它包含一个入口设备.o。我打算用它。 现在,我使用javah为应用程序生成了本机头。并制作了一个包含单个函数的相应C文件。我还在这个文件中包含了device.h,因为我打算稍后再使用它。

com_venky_Home.c

#include "com_venky_Home.h"
#include <android/log.h>
#include <device.h>

#define  LOG_TAG    "Native com_venky_Home"

#define  LOGD(...)  __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#define  LOGE(...)  __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
#define  LOGI(...)  __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
#define  LOGV(...)  __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__)
#define  LOGW(...)  __android_log_print(ANDROID_LOG_WARNING, LOG_TAG, __VA_ARGS__)

JNIEXPORT void Java_com_venky_Home_doImport (JNIEnv* pEnv, jobject pThis, jint fd) {
    LOGD ("Native code doImport was called with fd : %d\n", fd);   
}

现在,为了编译这个脚本,我使用的是ndk-build。因此,我已经制作了包含静态库的Android.mk和Application.mk文件。

Android.mk

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE    := dc
LOCAL_SRC_FILES := include/libdivecomputer.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := mylib
LOCAL_SRC_FILES := com_venky_Home.c
LOCAL_LDLIBS := -llog
LOCAL_STATIC_LIBRARIES := dc
include $(BUILD_SHARED_LIBRARY)

Application.mk

APP_PLATFORM := android-19
APP_ABI := x86

现在,只要我使用ndk-build编译它,我就会收到此错误

$ ndk-build
Android NDK: WARNING: APP_PLATFORM android-19 is larger than android:minSdkVersion 12 in ./AndroidManifest.xml
[x86] Compile        : mylib <= com_venky_Home.c
jni/com_venky_Home.c:4:20: fatal error: device.h: No such file or directory
compilation terminated.
make: *** [obj/local/x86/objs/mylib/com_venky_Home.o] Error 1

在运行ndk-build V = 1时,我收到以下消息。

$ ndk-build V=1
Android NDK: WARNING: APP_PLATFORM android-19 is larger than android:minSdkVersion 12 in ./AndroidManifest.xml    
rm -f ./libs/armeabi/lib*.so ./libs/armeabi-v7a/lib*.so ./libs/armeabi-v7a-hard/lib*.so ./libs/mips/lib*.so ./libs/x86/lib*.so
rm -f ./libs/armeabi/gdbserver ./libs/armeabi-v7a/gdbserver ./libs/armeabi-v7a-hard/gdbserver ./libs/mips/gdbserver ./libs/x86/gdbserver
rm -f ./libs/armeabi/gdb.setup ./libs/armeabi-v7a/gdb.setup ./libs/armeabi-v7a-hard/gdb.setup ./libs/mips/gdb.setup ./libs/x86/gdb.setup
[x86] Compile        : mylib <= com_venky_Home.c
/android_ndk/toolchains/x86-4.6/prebuilt/linux-x86_64/bin/i686-linux-android-gcc -MMD -MP -MF ./obj/local/x86/objs/mylib/com_venky_Home.o.d -ffunction-sections -funwind-tables -no-canonical-prefixes -fstack-protector -O2 -g -DNDEBUG -fomit-frame-pointer -fstrict-aliasing -funswitch-loops -finline-limit=300 -Ijni/include -Ijni -DANDROID  -Wa,--noexecstack -Wformat -Werror=format-security    -I/android_ndk/platforms/android-19/arch-x86/usr/include -c  jni/com_venky_Home.c -o ./obj/local/x86/objs/mylib/com_venky_Home.o 
jni/com_venky_Home.c:4:20: fatal error: device.h: No such file or directory
compilation terminated.
make: *** [obj/local/x86/objs/mylib/com_venky_Home.o] Error 1

可以看出,jni / include确实包含在 -Ijni / include 选项中搜索头文件。因此,链接器应该很容易找到device.h.但事实并非如此。为什么?如何解决此错误?

2 个答案:

答案 0 :(得分:1)

您的device.h不是系统标头。因此,请相应地包括它:

#include "device.h"

答案 1 :(得分:1)

我会回答我自己的问题。 正如@alexcohn正确地说的那样,我必须确保标题(* .h)实际存在于那里。在那里骗了我的愚蠢。这里有两件事需要。

1.你必须有一个图书馆。在ndk独立构建的情况下,它应该出现在ndk-arm / sysroot / usr / lib目录中。您的-l选项指定此库。请记住,名称应该是未修饰的。
对于前。 libvenkatesh.so would have -lvenkatesh as the library option.但这仅适用于格式良好的图书馆。如果您有另一个C文件具有所需功能的实现,您可以直接将它们添加到您的gcc命令。
对于前 gcc file1.c file2.c
另外,这也可以用于库文件。如果-l选项对你来说太神秘了,可以直接添加库。
对于ex。 gcc file.c libvenky.a libmy.so但是对于大项目来说,它很容易失控。因此-l选项很有用。
然后有-L选项。此选项指定编译器除标准位置外还应搜索库文件的位置。添加-L选项后,您可以直接链接库而不使用路径。
对于前假设我的项目的lib文件夹中有多个库。

lib
 |--- liba.so  libb.so  libc.a

使用-L选项$gcc file.c -Llib -la -lb -lc是正确的。

2.您必须拥有这些库的头文件。这必须包含在您的代码中。 (#include声明)。

#include <a.h>
#include <b.h>
#include <sample/c.h>

但是这些.h文件可能存在于非标准位置。要指定其位置,请使用-I选项。假设我有一个include文件夹,我保留了所有标题。

include
   |--- a.h  b.h  sample
                     |--- c.h

然后完成编译命令 $gcc file.c -o bin/file.o -Llib -Iinclude -la -lb -lc

我希望这会有所帮助。