Android跨平台编译 —— ICONV

2018-02-12 10:50:59来源:oschina作者:街角的小丑人点击

分享
前言

前言都在 Android跨平台编译 —— BOOST

正文

磕磕绊绊终于弄上了boost,今个很高兴!!边上眼睛就是一同编译!然后醒来发现出问题了……


undefined reference to `libiconv_open'
undefined reference to `libiconv'
undefined reference to `libiconv_close'
undefined reference to `libiconv_open'

赶紧看下源文件,没问题啊,也包含了iconv.h,并且跳转之后链接到了


ndk-bundle/sysroot/usr/include


为何没定义?仔细看,发现问题出在


#if __ANDROID_API__ >= __ANDROID_API_FUTURE__


你可以继续进入__ANDROID_API_FUTURE__的定义


/*
* Magic version number for a current development build, which has
* not yet turned into an official release.
*/
#ifndef __ANDROID_API_FUTURE__
#define __ANDROID_API_FUTURE__ 10000
#endif

呵呵,发现iconv已经在ndk r16b 中裁剪掉了,所以如果我们需要使用iconv,那么就需要自己重新打包放上去。


自己如何打包,网上搜索,也许你会找到一些资料,不过基本上都是挺重复了,写一个android.mk,然后使用ndk-build去打包。


不过笔者照着做的时候失败了,还有一篇文章是


https://medium.com/@zw3rk/building-iconv-for-android-e3581a52668f


也说了一个编译方法,不过我跟着做的时候还是失败了。可能的原因在于ndk r16b已经把gcc的编译工具转移到了llvm导致这里编译失败。


那么怎么办?只能自己动手编译了……首先创建一个android studio的项目,添加c++支持。修改gradle加入如下编译选项。


externalNativeBuild {
cmake {
cppFlags "-frtti -fexceptions --std=c++1z"
arguments "-DANDROID_STL=c++_static"
}
}

然后将最新的iconv代码全部复制到项目的cpp目录下。


然后打开命令行,在cpp目录下运行


./configure


他会配置很多东西。然后在项目的Cmakelists.txt中输入如下代码


cmake_minimum_required(VERSION 3.4.1)
project(mylib)
add_compile_options(
-Wno-multichar
-DANDROID
-DLIBDIR=/"c/"
-DBUILDING_LIBICONV
-DIN_LIBRARY
)
include_directories(src/main/cpp/)
include_directories(src/main/cpp/include)
include_directories(src/main/cpp/libcharset)
include_directories(src/main/cpp/lib)
include_directories(src/main/cpp/libcharset/include)
include_directories(src/main/cpp/srclib)
add_library( # Sets the name of the library.
iconv
# Sets the library as a static library.
SHARED
# Provides a relative path to your source file(s).
src/main/cpp/libcharset/lib/localcharset.c src/main/cpp/lib/iconv.c src/main/cpp/lib/relocatable.c
)

运行,应该会遇到如下错误


Error:(403) undefined reference to 'nl_langinfo'


我们跟过去看一下


# if HAVE_LANGINFO_CODESET
/* Most systems support nl_langinfo (CODESET) nowadays.*/
codeset = nl_langinfo (CODESET);

发现了一个宏HAVE_LANGINFO_CODESET 这个宏用来定义是否已经拥有nl_langinfo这个函数。


看来是我们直接调用./configure 漏掉了某些配置。导致生成的config.h有些问题。问题不大,我们直接修改这个config.h即可。(可能在src/main/cpp/lib/config.h中和src/main/cpp/config.h中都有定义,都改一下……)


找个这个宏的定义,并且把它改成0


#define HAVE_LANGINFO_CODESET 0

再次运行。编译成功,并且放到了build/intermediates/cmake/debug/obj/${ANDROID_ABI}/libiconv.so目录下。


使用方便就更简单了。拷贝这些文件



这是我的结构目录,大家可以自己用想用的,然后在cmake中使用


add_library( iconv_lib
SHARED
IMPORTED )
set_target_properties( # Specifies the target library.
iconv_lib
# Specifies the parameter you want to define.
PROPERTIES IMPORTED_LOCATION
# Provides the path to the library you want to import.
${PROJECT_SOURCE_DIR}/src/main/cpp/iconv/${ANDROID_ABI}/libiconv.so )
target_link_libraries(TKAT PRIVATE iconv_lib)

最新文章

123

最新摄影

闪念基因

微信扫一扫

第七城市微信公众平台