android stuido跨平台,Android跨平台编译 —— BOOST

本文介绍了在Android Studio中使用CMake进行跨平台编译时,针对Boost库的编译过程及遇到的问题。在Boost 1.65.1版本中,通过设置特定参数来解决find_package失败的问题。在编译armeabi-v7a时,由于错误的gcc-toolchain路径导致失败,通过对user-config.jam文件的修改解决了该问题。此外,还提到了在使用Boost时遇到的链接错误,通过检查符号表发现是由于编译时定义的BOOST_ERROR_CODE_HEADER_ONLY与使用时不一致导致,添加编译定义后问题解决。最后,提到了使用bcp工具裁剪Boost库以减少头文件数量的方法。
摘要由CSDN通过智能技术生成

前言

android studio在2.2开始已经全面接入了cmake,用来编译jni代码。所以我们的跨平台编译同样需要与时俱进,使用cmake来完成工作。如果你不是很了解cmake,也不用担心,跟着本文探索下去,能够了解一些最基本的用法(PS:博主之前也是完全不会,摸着石头过河的,现在也还是不会……)。

另外ndk版本使用了最新的r16b(16.1.4479499),这给之后带来了一些些问题。在最新的ndk版本中,已经将编译工具从gcc迁移到了clang,默认会使用clang进行编译。

toolchain地址位于 ${ANDROID_SDK}/ndk-bundle/toolchains/llvm内。关于llvm和clang的关系可以参考这张图。(更详细的内容就需要自己查了,不是本文内容。)

c896eb46bbf99d27be38d2cdefc5ac22.png

ok既然使用到了clang,那么使用的c++标准库STL自然是libc++标准库。

我们在代码中使用的头文件,比如string.h,都会位于${ANDROID_SDK}/ndk-bundle/source文件夹内,不同的stl库会使用不同的文件路径。

还有一部分在sysroot文件夹中,比如jni.h这个文件。

还有一个非常重要的东西在platforms文件夹中,这个文件夹包含了不同的android版本,同时每个版本中都有不同的指令集文件夹。每一个文件夹模拟了一个真机运行环境。

另外在开始之前,建议自己阅读下面几篇文章:

当然也请打开cmake的官方文档以便查阅。

正文

boost的编译实际上并不算复杂,比如我们可以直接使用

这个github项目已经替你实现了,这里我使用了1.65.1的版本。主要问题还是集中在如何放到自己项目中。

我们知道cmake提供了一个方法叫做find_package,具体参数请参见官方文档。作用是使用cmake提供的脚本自动搜索并载入相关的库。比如我们需要载入boost的库:

FIND_PACKAGE(Boost COMPONENTS filesystem REQUIRED)

Boost是库的名字,我们只需要载入其中一个组件filesystem。REQUIRED表示必须载入,没找到就报错。

实际上当调用find_package之后,cmake就回去寻找一个cmake的脚本,比如boost就回去寻找FindBoost.cmake的脚本。在android studio的环境下,他会到/Users/yxwang/Library/Android/sdk/cmake/3.6.4111459/share/cmake-3.6/Modules 这个文件夹下寻找。

正常情况,我们可以使用

set(Boost_ADDITIONAL_VERSIONS "1.65" "1.65.1")

set(Boost_NO_SYSTEM_PATHS ON)

set(BOOST_ROOT ${PROJECT_SOURCE_DIR}/src/main/cpp/boost/${ANDROID_ABI})

set(Boost_USE_STATIC_LIBS ON)

FIND_PACKAGE(Boost COMPONENTS filesystem REQUIRED)

这几行代码来设置一些先决条件,然后findboost.cmake脚本就能正常运行,并且替我们设置好一些变量。(其中BOOST_ROOT 表示boost的地址)

但是我发现我这边运行会出现问题,最后导致find失败,于是read the fucking source code!!

最终发现,问题出在了其中一行find_path命令上,理论上能根据设置的路径能够最终找到需要的头文件地址,并且存放在变量Boost_INCLUDE_DIR中。

但是我mac上发现find_path失效了。一定是缺失了某个配置,导致寻找路径出现了错误。甚至连find_path(VAL NAMES a.jpg PATH /somepath) 这种的绝对寻找都找不到…… PS在非ndk环境中似乎运行成功。如果有知道的朋友请一定留言告诉我……毕竟我是个小白

那么怎么办呢?既然你找不到,那就我直接来告诉你,所以代码就变成了这样

set(Boost_ADDITIONAL_VERSIONS "1.65" "1.65.1")

set(Boost_NO_SYSTEM_PATHS ON)

set(BOOST_ROOT ${PROJECT_SOURCE_DIR}/src/main/cpp/boost/${ANDROID_ABI})

set(Boost_INCLUDE_DIR ${BOOST_ROOT}/include/boost-1_65_1 )

set(Boost_LIBRARY_DIR ${BOOST_ROOT}/lib )

set(Boost_USE_STATIC_LIBS ON)

FIND_PACKAGE(Boost COMPONENTS filesystem REQUIRED)

我手动设置了Boost_INCLUDE_DIR的位置和 Boost_LIBRARY_DIR的位置。 (请注意大小写,这个大小写多浪费了我半天时间……)

好的,然后就可以像引入其他静态或者动态那样使用了比如,引入头文件

include_directories(${Boost_INCLUDE_DIR})

比如引入Link库

target_link_libraries(TKAT PRIVATE ${Boost_LIBRARIES} )

实际上调用了find_package之后还给你定义很多components的变量规则都一样,比如BOOST_FILESYSTEM_LIBRARY就表示filesystem单个库。

问题

这里笔者遇到了一个非常严重的问题,armeabi-v7a指令集的库打包失败。这是一个很严重的问题,如果这个使用最广的指令集包打不出来,基本上就等于没有作用。

看了build-android.sh,发现其中有一部分

if [ "$TOOLSET" = "cla

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值