conan入门(十六):profile template功能实现不同平台下profile的统一

本文介绍了如何利用Conan的profile模板功能和jinja2模板引擎,实现Windows、Linux、macOS不同平台上Android NDK交叉编译的profile统一。通过定义一个android_armv7a_clang.jinja模板文件,动态获取系统信息和环境变量,自动生成适应当前平台的profile,简化了同事间的分享和维护。

conan: profile template功能实现不同平台下profile的统一

之前我写过的两篇博客《conan入门(十):Windows下Android NDK交叉编译Boost》,.《conan入门(十一):Linux下Android NDK交叉编译Boost》中介绍了在Linux和Windows下NDK交叉编译boost的过程

在这两篇博客中针对Linux和Windows平台我定义了不同的profile文件,因为Linux和Windows的路径换行符不同,而且Linux和Windows下clang编译器可执行文件的后缀也不同(Windows下为.cmd)。更重要的是不同的平台下Android NDK的安装位置也不同。

但因为这些平台的微小差异就要定义不同的profile,也是不方便维护的。如果我把这个profile给我的同事,他必须根据平台和NDK安装位置,修改profile才能正常使用。

有没有办法使用不同平台使用同一个profile来实现NDK交叉编译呢?

有的,这就要用到Conan profile文件支持的模板功能(template)–《Profile templates》

从Conan 1.38 开始,可以使用jinja2模板引擎进行配置文件。通过使用.jinja扩展名命名配置文件来启用此功能。当conan加载带有.jinja扩展名的配置文件时,立即解析并渲染模板生成标准的profile。

jinja2支持基本的if-else条件判断以及字符操作,也就是说可以完全使用jinja2语法改造动态生成适应当前平台的profile

所以代价就是要学会使用jinja2模板

在网上找到了jinja2模板的使用文档–《Template Designer Documentation》,花了点时间学习了一下,将原来的android_armv7a_clang 模板改名为android_armv7a_clang.jinja,以下是profile完整内容:

android_armv7a_clang.jinja

include(default)
# 获取当前平台名并转为小写,linux,windows,darwin....
{% set osname = platform.system() | lower %}
# 获取当前CPU架构名称:x86,x86_64,
# 如果在windows平台返回的是AMD64则转为x86_64
{% set arch = {"AMD64": "x86_64"}.get(platform.machine(), platform.machine()) %}
{% if platform.system() == "Windows" %}
{% set exe_suffix = ".cmd" %}
{% endif %}
# 从环境变量ANDROID_NDK中读取Android NDK安装位置
android_ndk={{ os.getenv("ANDROID_NDK") }}
target_host=armv7a-linux-androideabi
api_level=16
[settings]
arch=armv7
build_type=Release
compiler=clang
compiler.libcxx=c++_static
#compiler.libcxx=c++_shared
compiler.version=8
os=Android
os.api_level=$api_level
#[tool_requires]
[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]
# 根据前面的osname和arch变量拼接生成交叉编译器路径
{% set bin_path = "$android_ndk/toolchains/llvm/prebuilt/"~osname~"-"~arch~"/bin" %}
{% if platform.system() == "Windows" %}
# windows下替换路径分割符
PATH=[{{ bin_path | replace("/","\\") }}]
{% else %}
PATH=[{{ bin_path }}]
{% endif %}
CHOST=$target_host
AR=arm-linux-androideabi-ar
AS=arm-linux-androideabi-as
RANLIB=arm-linux-androideabi-ranlib
CC=$target_host$api_level-clang{{ exe_suffix }}
CXX=$target_host$api_level-clang++{{ exe_suffix }}
LD=arm-linux-androideabi-ld
STRIP=arm-linux-androideabi-strip
{% set toolchain = "$android_ndk/build/cmake/android.toolchain.cmake" %}
{% if platform.system() == "Windows" %}
# 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_NDK环境变量,android_armv7a_clang.jinja 在Windows,Linux,macOS下都可以正常使用

$ conan install boost/1.69.0@ -pr:h android_armv7a.jinja -pr:b default --build boost --build zlib --build bzip2 --build  libiconv

参考资料

conan 文档:《Profile templates》

jinja2语法:《Template Designer Documentation》

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入门(十八):Cannot recognize the Windows subsystem, install MSYS2/cygwin or specify a build_require》
《conan入门(十九):封装第三方开源库cpp_redis示例》
《conan入门(二十):封装只包含头文件(header_only)的库示例》
《conan入门(二十一):解决MinGW编译Openssl的编译错误:crypto/dso/dso_win32.c》
《conan入门(二十二):编译 openssl要求python 3.7以上版本》
《conan入门(二十三):Windows下MinGW编译libcurl》
《conan入门(二十四):通过CONAN_DISABLE_CHECK_COMPILER禁用编译器检查》
《conan入门(二十五):imports将包安装到本地项目或其他指定位置》
《conan入门(二十六):使用make编译makefile》
《conan入门(二十七):因profile [env]字段废弃导致的boost/1.81.0 在aarch64-linux-gnu下交叉编译失败》
《conan入门(二十八):解决conan 1.60.0下 arch64-linux-gnu交叉编译openssl/3.1.2报错问题》
《conan入门(二十九):对阿里mnn进行Conan封装塈conans.CMake和conan.tools.cmake.CMake的区别》
《conan入门(三十):对腾讯ncnn进行Conan封装》
《conan入门(三十一):在命令行(shell)中从profile中读取配置参数》
《conan 入门(三十二):package_info中配置禁用CMakeDeps生成使用项目自己生成的config.cmake》
《conan 入门(三十三):requirements()指定header的可见性(transitive_headers)》
《conan 入门(三十四):conan 2.x实现对只有Makefile的项目(erpcgen)的封装示例》
《conan 入门(三十五):在conanfile.py中获取C++编译器完整路径的方法》
《conan入门(三十六):在set_version方法中从pom.xml中读取版本号实现动态版本定义》
《conan 入门(三十七):conan 2.x通过定义环境变量(environment)执行make编译只有Makefile的项目(erpcgen)》
《conan 入门(三十八):conan二进制包的兼容性及自定义package_id的方式》
《conan入门(三十九):conan 2.x 引用第三方库示例》

1、我知道一个conan包的版本信息,protobuf/3.19.3@saturnv_test/stable,格式是固定的,包名/版本号@用户名/通道号。 2、怎么知道这个包对应的conanfile.py中他的依赖包有哪些? 3、我的conan版本是2.3.2,不支持info参数。 4、提供的方法没问题可以获取到依赖包版本信息的话,后面还会通过在脚本用此方法批量获取很多个conan包的依赖包信息,要考虑通用性。 5、这是我的本地2.3.2的conan版本跟命令帮助信息: wenhao.zheng_docker@3a6a58c20a5b:/mnt/wenhao.zheng_docker/workspace_C/app$ conan -v Conan version 2.3.2 wenhao.zheng_docker@3a6a58c20a5b:/mnt/wenhao.zheng_docker/workspace_C/app$ conan -h Consumer commands cache Perform file operations in the local cache (of recipes and/or packages). config Manage the Conan configuration in the Conan home. graph Compute a dependency graph, without installing or building the binaries. inspect Inspect a conanfile.py to return its public fields. install Install the requirements specified in a recipe (conanfile.py or conanfile.txt). list List existing recipes, revisions, or packages in the cache (by default) or the remotes. lock Create or manage lockfiles. pkglist Several operations over package lists profile Manage profiles. remote Manage the remote list and the users authenticated on them. remove Remove recipes or packages from local cache or a remote. search Search for package recipes in all the remotes (by default), or a remote. version Give information about the Conan client version. Creator commands build Install dependencies and call the build() method. create Create a package. download Download (without installing) a single conan package from a remote server. editable Allow working with a package that resides in user folder. export Export a recipe to the Conan package cache. export-pkg Create a package directly from pre-compiled binaries. new Create a new example recipe and source files from a template. source Call the source() method. test Test a package from a test_package folder. upload Upload packages to a remote. Type "conan <command> -h" for help
06-18
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

10km

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值