conan入门(十七):支持android NDK (armv7,armv8,x86,x86_64)交叉编译的统一profile jinja2模板
Posted 10km
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了conan入门(十七):支持android NDK (armv7,armv8,x86,x86_64)交叉编译的统一profile jinja2模板相关的知识,希望对你有一定的参考价值。
conan:支持android NDK (armv7,armv8,x86,x86_64)交叉编译的统一profile jinja2模板
上一篇博客《conan入门(十六):profile template功能实现不同平台下profile的统一》以Android NDK交叉编译为例介绍了jinja模板在conan profile中的应用。如果针对不同的Android目标平台(armv7,armv8,x86,x86_64)都要维护一个profile也是挺麻烦的。本文在此基础上,更进一步改进将android NDK 对不同平台armv7,armv8,x86,x86_64交叉编译的profile基本于同一个模板统一实现
android_clang.jinja
如下是基于jinja2模板语言规范实现的profiel统一模板文件,
$HOME/.conan/profiles/android_clang.jinja
include(default)
####################################################################################
# 基于NDK19C的profile模板 #
####################################################################################
# 获取当前平台名并转为小写,linux,windows,darwin.... #
% set osname = platform.system() | lower %
% set archname = "AMD64": "x86_64".get(platform.machine(), platform.machine()) %
# 编译器执行程序后缀 #
% set exe_suffix = "Windows": ".cmd".get(platform.system(),"") %
####################################################################################
# 从环境变量ANDROID_ABI中读取目标CPU架构,设置target_host,api_level #
# 优先使用上级传入的 android_abi 变量,未定义则使用环境变量ANDROID_ABI #
# 否则使用默认值armeabi-v7a #
####################################################################################
% if not android_abi %
% set android_abi = os.getenv("ANDROID_ABI","armeabi-v7a") %
% endif %
% set target_host,target_arch,default_api_level =
"armeabi-v7a":("armv7a-linux-androideabi","armv7",16),
"arm64-v8a" :("aarch64-linux-android","armv8",21),
"x86" :("i686-linux-android","x86",16),
"x86_64" :("x86_64-linux-android","x86_64",21)
.get(android_abi,("unknow_host","unknow_arch",-1)) %
# 优先使用上级传入的 api_level 变量,未定义则使用环境变量ANDROID_NATIVE_API_LEVEL
否则使用默认值 default_api_level #
% if not api_level %
% set api_level = os.getenv("ANDROID_NATIVE_API_LEVEL",default_api_level) %
% endif %
# 从环境变量ANDROID_NDK中读取Android NDK安装位置
android_ndk= os.getenv("ANDROID_NDK")
[settings]
arch= target_arch
build_type=Release
compiler=clang
compiler.libcxx=c++_static
compiler.version=8
os=Android
os.api_level= api_level
[options]
% if platform.system() == "Windows" %
boost:addr2line_location=$android_ndk\\toolchains\\llvm\\prebuilt\\windows-x86_64\\bin\\x86_64-linux-android-addr2line.exe
% endif %
boost:without_stacktrace=True
[env]
% set bin_path = "$android_ndk/toolchains/llvm/prebuilt/"~osname~"-"~archname~"/bin" %
% if platform.system() == "Windows" %
# windows下替换路径分割符
PATH=[ bin_path | replace("/","\\\\") ]
% else %
PATH=[ bin_path ]
% endif %
CHOST= target_host
CC= target_host api_level -clang exe_suffix
CXX= target_host api_level -clang++ exe_suffix
#########################################################################################
# 对于 32 位 ARM,编译器会使用前缀 armv7a-linux-androideabi, #
# 但 binutils 工具会使用前缀 arm-linux-androideabi。对于其他架构,所有工具的前缀都相同 #
# see also https://developer.android.com/ndk/guides/other_build_systems #
#########################################################################################
% set binutils_prefix = "armv7a-linux-androideabi":"arm-linux-androideabi"
.get(target_host,target_host) %
AR= binutils_prefix -ar
AS= binutils_prefix -as
RANLIB= binutils_prefix -ranlib
LD= binutils_prefix -ld
STRIP= binutils_prefix -strip
# 定义环境变量ANDROID_ABI,ANDROID_NATIVE_API_LEVEL,用于 conan_ndk_toolchain.cmake
ANDROID_ABI= android_abi
ANDROID_NATIVE_API_LEVEL= api_level
#########################################################################################
# 指定./conan/cmake/conan_ndk_toolchain.cmake 为cmake 工具链文件 #
# ANDROID NDK默认提供的android.toolchain.cmake, #
# 如果不指定ANDROID_ABI和 ANDROID_NATIVE_API_LEVEL或ANDROID_PLATFORM, #
# 默认编译的目标平台 armv7,所以不可以直接使用。 #
#########################################################################################
% set toolchain = os.path.join(profile_dir, "..","cmake","conan_ndk_toolchain.cmake") %
% if platform.system() == "Windows" %
CONAN_CMAKE_TOOLCHAIN_FILE= toolchain | replace("/","\\\\")
% else %
CONAN_CMAKE_TOOLCHAIN_FILE= toolchain
% endif %
CONAN_CMAKE_GENERATOR="Unix Makefiles"
[conf]
tools.android:ndk_path=$android_ndk
android_clang.jinja通过读取环境变量ANDROID_ABI
或上级模板文件传入的android_abi
定义来确定目标平台,如果都没有定义则默认为armv7
,对于Android API Level也是同样的处理,通过上级模板文件传入的api_level
定义来确定目标平台,未定义则根据不同的平台有不同的默认值.
android.toolchain.cmake
ANDROID NDK默认提供的工具链文件$ANDROID_NDK/build/cmake/android.toolchain.cmake
, 如果不指定ANDROID_ABI
和 ANDROID_NATIVE_API_LEVEL
或ANDROID_PLATFORM
环境变量,
默认编译的目标平台 armv7,所以对于armv8,x86或x86_64平台不可以直接使用。所以如下需要创建一个自定义的工具链文件,预先设置ANDROID_ABI
和ANDROID_NATIVE_API_LEVEL
变量
$HOME/.conan/cmake/conan_ndk_toolchain.cmake
# 根据环境变量ANDROID_NATIVE_API_LEVEL,ANDROID_ABI定义ANDROID_NATIVE_API_LEVEL,ANDROID_ABI
set(ANDROID_NATIVE_API_LEVEL $ENVANDROID_NATIVE_API_LEVEL)
set(ANDROID_ABI $ENVANDROID_ABI)
include($ENVANDROID_NDK/build/cmake/android.toolchain.cmake)
android_clang.jinja 使用示例
以boost为例,Windows下NDK交叉armv8平台执行如下命令:
$ set ANDROID_ABI=arm64-v8a
$ conan install boost/1.78.0@ -pr:h android_clang.jinja -pr:b default --build missing
独立模板
如果觉得每次编译要多设置一个环境变量还是有点麻烦,那可以如下为armv7,armv8,x86,x86_64分别定义一个简单的模板文件
android_clang_armv7.jinja
% set android_abi = "armeabi-v7a" %
% include 'android_clang.jinja' %
android_clang_armv8.jinja
% set android_abi = "arm64-v8a" %
% include 'android_clang.jinja' %
android_clang_x86.jinja
% set android_abi = "x86" %
% include 'android_clang.jinja' %
android_clang_x86_64.jinja
% set android_abi = "x86_64" %
% include 'android_clang.jinja' %
以如下结构保存到$HOME/.conan
文件夹下:
.conan
├── cmake
│ └── conan_ndk_toolchain.cmake
└── profiles
├── android_clang.jinja
├── android_clang_armv7.jinja
├── android_clang_armv8.jinja
├── android_clang_x86.jinja
├── android_clang_x86_64.jinja
└── default
那么不论是Linux还是Windows都可以如下执行交叉编译
$ conan install boost/1.78.0@ -pr:h android_clang_x86.jinja -pr:b default --build missing
参考资料
《Using toolchain from Android NDK》
conan系列文章
《conan入门(一):conan 及 JFrog Artifactory 安装》
《conan入门(二):conan 服务配置-密码管理及策略》
《conan入门(三):上传预编译的库(artifact)》
《conan入门(四):conan 引用第三方库示例》
《conan入门(五):conan 交叉编译引用第三方库示例》
《conan入门(六):conanfile.txt conanfile.py的区别》
《conan入门(七):将自己的项目生成conan包》
《conan入门(八):交叉编译自己的conan包项目》
《conan入门(九):NDK交叉编译自己的conan包项目塈profile的定义》
《conan入门(十):Windows下Android NDK交叉编译Boost》
《conan入门(十一):Linux下Android NDK交叉编译Boost》
《conan入门(十二):Windows NDK 编译 boost报错:CMake was unable to find a build program … MinGW Makefile》
《conan入门(十三):conan info 命令的基本用法》
《conan入门(十四):conan new 命令的新特性–模板功能(–template)》
《conan入门(十五):AttributeError: ‘CMake‘ object has no attribute ‘definitions‘》
《conan入门(十六):profile template功能实现不同平台下profile的统一》
《conan入门(十七):支持android NDK (armv7,armv8,x86,x86_64)交叉编译的统一profile jinja2模板》
以上是关于conan入门(十七):支持android NDK (armv7,armv8,x86,x86_64)交叉编译的统一profile jinja2模板的主要内容,如果未能解决你的问题,请参考以下文章
conan入门:Windows NDK 编译 boost报错:CMake was unable to find a build program .... MinGW Makefile
conan入门(十六):profile template功能实现不同平台下profile的统一