Android.mk中LOCAL_EXPORT_C_INCLUDES的作用

Android.mk中LOCAL_EXPORT_C_INCLUDES的作用

      NDK中的说明是这样说明的:

     

III. Exporting headers for prebuilt libraries:
----------------------------------------------

The example above was called 'naive' because, in practice, the code in
foo-user.c is going to depend on specific declarations that are normally
found in a header file distributed with the prebuilt library (e.g. "foo.h").

In other words, foo-user.c is going to have a line like:

  #include <foo.h>

And you need to provide the header and its include path to the compiler
when building the foo-user module.

A simple way to deal with that is to use exports in the prebuilt module
definition. For example, assuming that a file "foo.h" is located under
the 'include' directory relative to the prebuilt module, we can write:

   include $(CLEAR_VARS)
   LOCAL_MODULE := foo-prebuilt
   LOCAL_SRC_FILES := libfoo.so
   LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
   include $(PREBUILT_SHARED_LIBRARY)

The LOCAL_EXPORT_C_INCLUDES definition here ensures that any module that
depends on the prebuilt one will have its LOCAL_C_INCLUDES automatically
prepended with the path to the prebuilt's include directory, and will thus
be able to find headers inside that.

        如果看不懂就看这个博客的翻译吧,非常好:

        http://www.cnblogs.com/qq78292959/archive/2011/11/02/2232962.html

       感谢这哥们将NDK的文档都翻译了,高质量,高水平。

       我当时情况是,如果我们自己的c或cpp中如果引用了其他库使用的头文件,那么例如:

      我的jni_main.cpp中#include "openssl/ssl.h",那么我拷贝到jni下的应该是openssl目录,里面包含这这个

ssl.h头文件,那么我就不用使用这个LOCAL_EXPORT_C_INCLUDES也可以正常编译使用。很明显是正确的。

        那么这个东西是干嘛用的呢?我就猜想,一般大家都把头文件放到叫include的目录中,比如Android源码里的external/openssl/下面的include中有/openssl/ssl.h,看来如果尊重这个习惯的话,那么使用这个变量不就很好了嘛,可以让ndk去include下面去找openssl啊,如果还要其他的模块,把他们的头文件也放到include中,也能集中啊,多么美好的东西啊。

        实践一下吧:

        1.先将external/openssl/下面的include目录整体拷贝到工程的jni目录下,然后在Android.mk中修改如下:

        

#使用动态库
include $(CLEAR_VARS)
LOCAL_MODULE := openssl_ssl
LOCAL_SRC_FILES := ./openssllibs/libssl.so
# 导出头动态库的文件
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
# 预编译动态库
include $(PREBUILT_SHARED_LIBRARY)

#使用动态库
include $(CLEAR_VARS)
LOCAL_MODULE := openssl_crypto
LOCAL_SRC_FILES := ./openssllibs/libcrypto.so
# 导出头动态库的文件
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
# 预编译动态库
include $(PREBUILT_SHARED_LIBRARY)

     用ndk编译之,ok结果如下:

     

dr@dr-OptiPlex-3010:~/workspace/OpensslTest/jni$ ~/android-ndk-r5b/ndk-build
Compile++ thumb  : jni_openssltest <= jni_main.cpp
StaticLibrary  : libstdc++.a
Prebuilt       : libssl.so <= jni/./openssllibs/
Prebuilt       : libcrypto.so <= jni/./openssllibs/
SharedLibrary  : libjni_openssltest.so
Install        : libjni_openssltest.so => libs/armeabi/libjni_openssltest.so
Install        : libcrypto.so => libs/armeabi/libcrypto.so
Install        : libssl.so => libs/armeabi/libssl.so
dr@dr-OptiPlex-3010:~/workspace/OpensslTest/jni$ 

     那如果不使用这个LOCAL_EXPORT_C_INCLUDES呢?结果当然不行了,如下:

    

dr@dr-OptiPlex-3010:~/workspace/OpensslTest/jni$ ~/android-ndk-r5b/ndk-build
Compile++ thumb  : jni_openssltest <= jni_main.cpp
/home/dr/workspace/OpensslTest/jni/jni_main.cpp:3:25: error: openssl/ssl.h: No such file or directory
/home/dr/workspace/OpensslTest/jni/jni_main.cpp: In function 'jint Java_com_example_openssltest_JniTest_getInit(JNIEnv*, _jobject*)':
/home/dr/workspace/OpensslTest/jni/jni_main.cpp:15: error: 'SSL_library_init' was not declared in this scope
make: *** [/home/dr/workspace/OpensslTest/obj/local/armeabi/objs/jni_openssltest/jni_main.o] Error 1
dr@dr-OptiPlex-3010:~/workspace/OpensslTest/jni$ 

        好了,验证了。再次感谢那哥们的翻译,真是太好了。

猜你喜欢

转载自dingran.iteye.com/blog/1797305