Android跨平台编译 —— ICONV

前言

    前言都在 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)

猜你喜欢

转载自my.oschina.net/zzxzzg/blog/1621387