【问题标题】:Compiling C library for android为android编译C库
【发布时间】:2017-07-14 16:26:30
【问题描述】:

作为概念证明,我正在尝试编译并利用 this 库的强大功能用于 android 应用程序。我正在使用安卓工作室。到目前为止我所做的是:

  1. 已安装 NDK 和 SDK(如果可能,我希望以 android 版本 4.0.3 及更高版本为目标)
  2. 在 Android Studio 中创建了一个 android 项目
  3. 中创建了 JNI 文件夹
  4. 将库的所有内容存储在我的 JNI 文件夹中
  5. 将我的 build.gradle 链接到源代码中存在的 Android.MK 文件

    externalNativeBuild {
         ndkBuild {
             path 'src/main/jni/Android.mk'
         }
    }
    
  6. 设置 ProductFlavors 以避免尝试为库不支持的架构进行构建(我可能已经错了)

    productFlavors {
        dev { ndk.abiFilters 'x86', 'armeabi', 'armeabi-v7a' }
        develx86 { ndk.abiFilters 'x86', 'armeabi', 'armeabi-v7a' }
        production { ndk.abiFilters 'x86', 'armeabi', 'armeabi-v7a' }
        productionx86 { ndk.abiFilters 'x86', 'armeabi', 'armeabi-v7a' }
    }
    
  7. 此时,我注意到像 cpu-miner.c 这样的一些文件丢失了一些,包括将它们突出显示为丢失,特别是

    #include <curl/curl.h>
    #include <openssl/sha.h>`
    

于是我去这两个库的官网下载了源码,创建了两个对应的文件夹,把所有的文件都放在那里。在OpenSSL 中有一个 h.in 文件——据我所知是一个配置。我能够从here 得到一个配置好的(也可能是我犯错的地方)

  1. 我已将 Application.mk 添加到 JNI 文件夹根目录,其中包含以下内容 APP_ABI:= armeabi armeabi-v7a x86 以排除一些我不支持的架构。

此时,我遇到了一些问题——其中一个问题是我实际上无法使用 NDK-build 构建我的 JNI 东西——sched.h 没有得到解决(即使我将 API 版本增加到 20)。这会导致如下错误:

JNI/cpu-miner.c:473:2: error: use of undeclared identifier 'cpu_set_t'
    cpu_set_t set;
jni/cpu-miner.c:474:12: error: use of undeclared identifier 'set'
    CPU_ZERO(&set);

所以问题是:

  1. 如何强制构建解决sched.h
  2. 下载和添加缺失库的源代码时我的方法是否正确,或者还有其他选项 - 我认为确实有一个选项,因为它们未包含在库源代码中?如果是这样 - 有人可以提供说明如何使用 NDK 执行此操作(或者我使用什么并不重要?)
  3. 一旦我修复了库构建,只需为我的 c 文件生成 java 接口并开始使用它们就足够了吗?还是需要考虑其他步骤?

    如果您需要任何其他详细信息,请随时询问,在此先感谢您。
    免责声明:我是 a.NET 开发人员,因此请在适用的情况下更具体地了解 android/C 的内容。
    免责声明 2:该程序是为教育目的而制作的,作为概念证明。

【问题讨论】:

  • 包含看起来像工作。它类型的问题没有定义。如果你看看android.googlesource.com/platform/development/+/73a5a3b/ndk/… - 有一个有趣的宏守卫_GNU_SOURCE
  • 我实际上在 cpu-miner.c 的开头有这个#define _GNU_SOURCE
  • 只是说问题可能与 NDK 上下文中 _GNU_SOURCE 宏的含义有关。
  • 不幸的是看起来不像,因为我不知道让 ndk 看到这个宏的另一种方法,它已经在文件的开头定义了
  • 1) 让我们将 ndk-build 和 Android Studio 集成的问题分开。从前者开始,然后在命令行上运行 ndk-build -B V=1 APP_ABI=armeabi(使用 jni 作为当前目录)。

标签: android c android-studio android-ndk


【解决方案1】:

尝试在包含 &lt;sched.h&gt; 之前添加此内容

#define _GNU_SOURCE

如果它不起作用,只需在 cpu-miner.c 文件中添加以下结构:

#define CPU_SETSIZE 1024
#define __NCPUBITS  (8 * sizeof (unsigned long))
typedef struct
{
   unsigned long __bits[CPU_SETSIZE / __NCPUBITS];
} cpu_set_t;

【讨论】:

  • 谢谢。这帮助我走得更远,但现在我有很多错误,例如 jni/cpu-miner.c:1487: error: undefined reference to 'json_object_get'jni/compat/jansson/jansson.h:109: error: undefined reference to 'json_delete'jni/cpu-miner.c:2900: error: undefined reference to 'json_load_file' 等等。
  • 你有 json 库吗?尝试在您的 Android.mk 中添加 LOCAL_LDLIBS := -ljson
  • 再次感谢您的意见。添加此行开始导致错误error: cannot find -ljson。附言即使没有这一行,我也可以从代码中导航到指定的类型,它存储在jansson.h,所以我猜问题可能出在其他地方
【解决方案2】:

看起来 cpu_set_t 直到 android-21 才进入 NDK 标头。

NDK r14(未发布,但下周应该会发布)已完全重做标题,以便您可以访问结构定义和常量(无论您需要的 API 在 android-21 之前是否可用是一个不同的问题)。要使用它们,请抓住r14 beta 并按照unified headers 的说明进行操作。

【讨论】:

  • 将 api 版本提高到 21 使代码不是红色的,但是构建过程中的错误仍然存​​在,并且包含本身是灰色的。我已经检查过,它现在指向版本 21
  • 我的猜测是它只对某些 ABI 失败。试试@AlexCohn 直接运行ndk-build 的建议。如果可行,请尝试扩展 APP_ABI 以包括 armeabi-v7a 和 x86,直到找到失败的一个。任何这些失败命令的输出都会有所帮助。
猜你喜欢
  • 2012-12-28
  • 1970-01-01
  • 2020-04-23
  • 2020-11-09
  • 2018-06-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多