前言
正文
磕磕绊绊终于弄上了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)