conan入门(二十):封装只包含头文件(header_only)的库示例

conan: 封装只包含头文件(header_only)的库示例

有的C/C++项目只包含头文件,不需要编译,对于这种情况如何封装为Conan的包呢?

Conan官方文档 《Package scaffolding for conan new command》给出了样例

我就有这样一个项目 common_source_cpp收集了工作中常用的代码,以C/C++头文件形式为主,本文就以common_source_cpp为例说明如何实现conanfile.py将它封装为一个不需要编译只有头文件的Conan包。

conanfile.py

conanfile.py 码云地址: https://gitee.com/l0km/common_source_cpp/blob/master/conanfile.py

import os,re
from conan import ConanFile
from conan.tools.files import copy
from os.path import join

class CommonSourceCppConan(ConanFile):
    name = "common_source_cpp"
    version = "1.0.2-dev"
    description = "C/C++/C++11公用代码"
    url = "https://gitee.com/l0km/common_source_cpp"
    license = "BSD-2-Clause"
    author = "guyadong 10km0811@sohu.com"
    topics = ("C", "C++", "C++11", "common")

    package_type = "header-library"
    settings = "compiler"
    exports_sources = "*.h", "*.cpp", "*.hpp", "*.hh", "*.c", "LICENSE"

    def package(self):
        copy(self,"*.h", self.source_folder, join(self.package_folder, "include"))
        copy(self,"*.cpp", self.source_folder, join(self.package_folder, "include"))
        copy(self,"*.hpp", self.source_folder, join(self.package_folder, "include"))
        copy(self,"*.hh", self.source_folder, join(self.package_folder, "include"))
        copy(self,"*.c", self.source_folder, join(self.package_folder, "include"))
        copy(self,"LICENSE", self.source_folder, join(self.package_folder, "include"))

    def package_id(self):
        # 重要:指定项目只有头文件
        # self.info.header_only() # conan 2.x中该方法已经废弃
        self.info.clear()

    def package_info(self):
        if self.settings.compiler == "msvc":
            self.cpp_info.includedirs.append("include/dirent")

    def is_true(self,str):
        return re.match(r'^(?:true|on|1|y(es))?$',str,re.I)

    def configure(self):
		# 指定 common_source_cpp为纯C项目
        if self.is_true(os.getenv("COMMON_SOURCE_CPP_ONLY_C","False")) :
            del self.settings.compiler.libcxx
            del self.settings.compiler.cppstd

conanfile_master.py

如果需要项目的最新版本则实现如下

conanfile_master.py 码云地址: https://gitee.com/l0km/common_source_cpp/blob/master/conanfile_master.py

import os,re
from conans import ConanFile
from conan.tools.scm import Git

class CommonSourceCppConanConan(ConanFile):
    name = "common_source_cpp"
    version = "master"
    description = "C/C++/C++11公用代码"
    url = "https://gitee.com/l0km/common_source_cpp"
    license = "BSD-2-Clause"
    author = "guyadong 10km0811@sohu.com"
    topics = ("C", "C++", "C++11", "common")

    settings = "compiler"

    def export(self):
        self.copy("conanfile.py",src="conanfile_master.py")
        
    def source(self):
        # 从远端仓库下载指定分支代码
        # self.run("git clone -b " + self.version + " " + self.url + ".git")
        git = Git(self)
        clone_args = ['--branch', self.version]
        git.clone(url=self.url + ".git", args=clone_args, target=".")

    def package(self):
        # 确保当前仓库与远程仓库同步
        git = Git(self)
        self.output.info(git.run("pull"))
        self.copy("*.h", dst="include", src=".")
        self.copy("*.cpp", dst="include", src=".")
        self.copy("*.hpp", dst="include", src=".")
        self.copy("*.hh", dst="include", src=".")
        self.copy("*.c", dst="include", src=".")
        self.copy("LICENSE", dst="include", src=".")

    def package_id(self):
        # 重要:指定项目只有头文件
        # self.info.header_only() # conan 2.x中该方法已经废弃
        self.info.clear()

    def package_info(self):
        if self.settings.compiler == "Visual Studio":
            self.cpp_info.includedirs.append("include/dirent")

    def is_true(self,str):
        return re.match(r'^(?:true|on|1|y(es))?$',str,re.I)

    def configure(self):
		# 指定 common_source_cpp为纯C项目
        if self.is_true(os.getenv("COMMON_SOURCE_CPP_ONLY_C","False")) :
            del self.settings.compiler.libcxx
            del self.settings.compiler.cppstd

conan create

有了上面的conanfile.py,就可以执行conan create 命令将cpp_redis生成到本地的conan仓库了

$ conan create .
Exporting package recipe
common_source_cpp/0.0.0-DEV exports_sources: Copied 43 '.h' files
common_source_cpp/0.0.0-DEV exports_sources: Copied 8 '.cpp' files
common_source_cpp/0.0.0-DEV exports_sources: Copied 11 '.hpp' files
common_source_cpp/0.0.0-DEV exports_sources: Copied 1 '.hh' file: uri.hh
common_source_cpp/0.0.0-DEV exports_sources: Copied 2 '.c' files: debug_printf.c, if_utilits_c.c
common_source_cpp/0.0.0-DEV exports_sources: Copied 1 file: LICENSE
common_source_cpp/0.0.0-DEV: The stored package has not changed
common_source_cpp/0.0.0-DEV: Exported revision: 50a7e6024f11c1e9b6bbab7e45c4253e
Configuration:
[settings]
arch=x86_64
arch_build=x86_64
build_type=Release
compiler=Visual Studio
compiler.runtime=MD
compiler.version=14
os=Windows
os_build=Windows
[options]
[build_requires]
[env]

common_source_cpp/0.0.0-DEV: Forced build from source
Installing package: common_source_cpp/0.0.0-DEV
Requirements
    common_source_cpp/0.0.0-DEV from local cache - Cache
Packages
    common_source_cpp/0.0.0-DEV:5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9 - Build

Installing (downloading, building) binaries...
common_source_cpp/0.0.0-DEV: Copying sources to build folder
。。。
common_source_cpp/0.0.0-DEV: Calling package()
common_source_cpp/0.0.0-DEV package(): Packaged 43 '.h' files
common_source_cpp/0.0.0-DEV package(): Packaged 11 '.hpp' files
common_source_cpp/0.0.0-DEV package(): Packaged 2 '.c' files: debug_printf.c, if_utilits_c.c
common_source_cpp/0.0.0-DEV package(): Packaged 8 '.cpp' files
common_source_cpp/0.0.0-DEV package(): Packaged 1 file: LICENSE
common_source_cpp/0.0.0-DEV package(): Packaged 1 '.hh' file: uri.hh
common_source_cpp/0.0.0-DEV: Package '5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9' created
common_source_cpp/0.0.0-DEV: Created package revision 6b32a82748a8366bb24b66daef5296df
common_source_cpp/0.0.0-DEV: WARN: This conanfile has no build step

conan create .根据配置文件 (同级文件夹下的conanfile.py) 构建二进制包
conan create 命令行用法参见Conan官方文档《conan create》

执行 conann create指定conanfile_master.py则会从远端仓库下载最新的maste分支代码

$ conan create conanfile_master.py
Exporting package recipe
common_source_cpp/master: Calling export()
common_source_cpp/master: The stored package has not changed
common_source_cpp/master: Exported revision: 4115d7716d69dce3edff00b6da3560ab
Configuration:
[settings]
arch=x86_64
arch_build=x86_64
build_type=Release
compiler=Visual Studio
compiler.runtime=MD
compiler.version=14
os=Windows
os_build=Windows
[options]
[build_requires]
[env]

common_source_cpp/master: Forced build from source
Installing package: common_source_cpp/master
Requirements
    common_source_cpp/master from local cache - Cache
Packages
    common_source_cpp/master:5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9 - Build

Installing (downloading, building) binaries...
common_source_cpp/master: Copying sources to build folder
common_source_cpp/master: Building your package in 
。。。
common_source_cpp/master: Calling package()
Already on 'master'
Your branch is up to date with 'origin/master'.
Already up to date.
common_source_cpp/master package(): Packaged 43 '.h' files
common_source_cpp/master package(): Packaged 11 '.hpp' files
common_source_cpp/master package(): Packaged 2 '.c' files: debug_printf.c, if_utilits_c.c
common_source_cpp/master package(): Packaged 8 '.cpp' files
common_source_cpp/master package(): Packaged 1 file: LICENSE
common_source_cpp/master package(): Packaged 1 '.hh' file: uri.hh
common_source_cpp/master: Package '5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9' created
common_source_cpp/master: Created package revision 778c04901c633169b88ac94242cc152f
common_source_cpp/master: WARN: This conanfile has no build step

执行conan search会显示本地仓库二进制包的信息

$ conan search common_source_cpp/0.0.0-DEV@
Existing packages for recipe common_source_cpp/0.0.0-DEV:

    Package_ID: 5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9
        Outdated from recipe: False

$ conan search common_source_cpp/master@
Existing packages for recipe common_source_cpp/master:

    Package_ID: 5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9
        Outdated from recipe: False

conan upload

执行conan upload上传到私有制品库了:

conan upload common_source_cpp/0.0.0-DEV  -r ${repo} -all
# ${repo}为私有制品库的名字

–all 指定上传所有内容(配置文件conanfile.py,源码和打包的文件–package),如果不指定些选项,只上传除package之外的所有文件

执行conan upload上传到私有制品库了:

conan upload common_source_cpp/master  -r ${repo} 
# ${repo}为私有制品库的名字

注意:因为我们需要common_source_cpp/master保持与远程端同步的最新代码,所以这里没有使用–all 指定上传所有内容(配置文件conanfile.py,源码和package),只上传了conanfile.py,引用该项目时执行conan install common_source_cpp/master@ --build common_source_cpp会自动从远程仓库克隆代码在本地仓库生成package

关于 conan upload命令的详细说明参见Conan官方文档:《conan upload》

参考资料

《Recipe and Sources in a Different Repo》

conan create

package()

source()

self.info.header_only()

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
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

10km

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

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

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

打赏作者

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

抵扣说明:

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

余额充值