前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >conan入门(七):将自己的项目生成conan包

conan入门(七):将自己的项目生成conan包

作者头像
10km
发布2022-04-13 12:02:22
1.5K0
发布2022-04-13 12:02:22
举报
文章被收录于专栏:10km的专栏

conan 将自己的项目生成conan包

在之前的博客《conan入门(四):conan 引用第三方库示例》中我们以cJSON为例说明了如何在项目中引用一个conan 包。

如何将自己设计的模块以conan包形式打包提供给第三方(客户/同事)使用?

本文将以一个基于 cJSON 库实现字符串解析的模块 jsonlib,说明如何将自己的模块封装成conan提供给第三方使用。

jsonlib示例程序

示例的所有源码都保存在GIT仓库 conan_example的jsonlib分支,请直接克隆代码到本地:

代码语言:javascript
复制
git clone https://gitee.com/l0km/conan_example.git -b jsonlib
# -b jsonlib 切换到 jsonlib 分支,等价于 'git checkout jsonlib' 命令 

jsonlib是个很简单的库,只有两个文件:jsonlib.h,jsonlib.c,只实现了一个功能从JSON字符串中解析name指定的字段内容,结果保存到输出缓冲区,JSON解析的工作实际上是调用cJSON来实现的。以下是实现源码。

src/jsonlib.h

代码语言:javascript
复制
/*
 * jsonlib.h
 *  conan example for library
 *  Created on: 2022/02/18
 *      Author: guyadong
 */

#ifndef SRC_JSONLIB_H_
#define SRC_JSONLIB_H_
#ifndef JSONLIB_DLL_DECL
#  if defined(_WIN32) && !defined(__CYGWIN__) && defined(JSONLIB_IS_DLL)
#    if defined(JSONLIB_EXPORTS)
#      define JSONLIB_DLL_DECL  __declspec(dllexport)
#    else
#      define JSONLIB_DLL_DECL  __declspec(dllimport)
#    endif
#  else
#    define JSONLIB_DLL_DECL
#  endif
#endif
#include <stddef.h>
#ifdef __cplusplus
extern "C"
{
#endif

//************************************
// 从JSON字符串中解析name指定的字段内容,结果保存到输出缓冲区
// @param    const char * cjs JSON 字符串
// @param    const char * name 字段名
// @param    char * buffer [out] 输出缓冲区
// @param    size_t bufsz 输出缓冲区长度
// @return   int 成功返回0,否则返回-1
//************************************
JSONLIB_DLL_DECL int jlib_parse_field(const char* cjs,const char*name, char*buffer,size_t bufsz);
#ifdef __cplusplus
}
#endif
#endif /* SRC_JSONLIB_H_ */

src/jsonlib.c

代码语言:javascript
复制
#include "jsonlib.h"
#include <cjson/cJSON.h>
#include <string.h>
#include <stdlib.h>

JSONLIB_DLL_DECL int jlib_parse_field(const char* cjs,const char*name, char*buffer,size_t bufsz)
{
    int c = -1;
    if(cjs && name && buffer && bufsz)
    {
        cJSON* j = cJSON_Parse(cjs);
        if(j)
        {
            cJSON* item = cJSON_GetObjectItem(j,name);
            if(item)
            {
                char* s = cJSON_PrintUnformatted(item);
                if(s && strlen(s) < bufsz)
                {
					strncpy(buffer, s, bufsz);
					c = 0;
                }
                free(s);
            }
        }
        cJSON_Delete(j);
    }
    return c;
}

CMakeLists.txt

代码语言:javascript
复制
cmake_minimum_required(VERSION 3.10.3)
# 3.0以上版本才允许使用VERSION option
project(JsonTest VERSION 1.0.0 LANGUAGES C)
find_package(cJSON REQUIRED)
add_library(jsonlib src/jsonlib.c)
set_target_properties(jsonlib PROPERTIES PUBLIC_HEADER "src/jsonlib.h")
target_link_libraries(jsonlib PUBLIC cjson)
target_compile_definitions(jsonlib 
    PRIVATE $<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,SHARED_LIBRARY>:JSONLIB_EXPORTS>
    PUBLIC $<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,SHARED_LIBRARY>:JSONLIB_IS_DLL>
)

conan new

现在 jsonlib.h,jsonlib.c,CMakeLists.txt三个文件构成了一个简单但完整的标准CMake项目。

代码语言:javascript
复制
conan_example
│  CMakeLists.txt
│      
└─src
       jsonlib.c
       jsonlib.h

怎么把这个小项目封装为conan包呢?如果你看过我的上一篇博客《conan入门(六):conanfile.txt conanfile.py的区别》以及《conan入门(一):conan 及 JFrog Artifactory 安装》就差不多可以知道,一个conan包最关键的就是需要有一个conanfile.py脚本来定义包的各种配置。

但是要手写一个conanfile.py好像还挺麻烦的,我对python也是只知皮毛。

显然手写是不可能的,conan new 命令就是用于创建一个新的conan配置文件模板。有了模板,在之上修改就可以了:

代码语言:javascript
复制
$ conan new jsonlib/1.0.0 --template cmake_lib
File saved: CMakeLists.txt
File saved: conanfile.py
File saved: src/jsonlib.cpp
File saved: src/jsonlib.h
File saved: test_package/CMakeLists.txt
File saved: test_package/conanfile.py
File saved: test_package/src/example.cpp

conan new jsonlib/1.0.0 --template cmake_lib执行后生成的目录结构如下,可以看到conan很贴心的生成了conanfile.py,jsonlib的源码文件及CMakeLists.txt以及对应的测试代码(test_package)—这是一个完整的conan包项目框架,虽然它不是想我们需要的内容,但有了这个框架总比从头开始写要方便得多:

代码语言:javascript
复制
conan_example
│  CMakeLists.txt
│  conanfile.py
│  
├─src
│      jsonlib.cpp
│      jsonlib.h
│      
└─test_package
    │  CMakeLists.txt
    │  conanfile.py
    │  
    └─src
            example.cpp

上面执行 conan new 命令使用的 --template cmake_lib 参数是Conan的一项目还在实验中的功能,根据指定模板生成Conan项目框架,详细说明参见Conan官方文档:《Package scaffolding for conan new commandconan new命令的详细说明参见Conan官方文档《conan new》

update jsonlib

现在我们在Conan生成的项目框架上,把jsonlib装进去。

conanfile.py

首先如下图修改conanfile.py

CMakeLists.txt

如下图将conan new 生成的CMakeLists.txt的内容合并到jsonlib的CMakeLists.txt中

jsonlib.h jsonlib.c

src/jsonlib.c替换conan new 生成的src/jsonlib.cpp,

src/jsonlib.h 替换conan new生成的src/jsonlib.h

example.cpp

conan new生成的test_package/src/example.cpp替换为如下代码,实现简单的jsonlib接口测试

test_package/src/example.cpp

代码语言:javascript
复制
#include <stdio.h>
#include <jsonlib.h>

int main(int argc, char** argv)
{
    char jstr[] = "{\"hello\":\"world\"}";
    printf("JSON:%s\n",jstr);

    char fieldbuf[32];
    int c = jlib_parse_field(jstr,"hello",fieldbuf,sizeof(fieldbuf));
    if(0 == c){
        printf("parsed 'hello' field:  %s\n",fieldbuf);
    }

    return 0;
}

conan create (编译jsonlib)

创建了conanfile.py后,编译conan包非常简单

代码语言:javascript
复制
# 注意是 conan_example jsonlib分支
$ cd conan_example
$ conan create .
Exporting package recipe
jsonlib/1.0.0 exports_sources: Copied 1 '.txt' file: CMakeLists.txt
jsonlib/1.0.0 exports_sources: Copied 1 '.c' file: jsonlib.c
jsonlib/1.0.0 exports_sources: Copied 1 '.h' file: jsonlib.h
jsonlib/1.0.0: A new conanfile.py version was exported
jsonlib/1.0.0: Folder: C:\Users\guyadong\.conan\data\jsonlib\1.0.0\_\_\export
jsonlib/1.0.0: Exported revision: 5f5439068d01c7592ebbcb724712ce89
.....
.....
Capturing current environment in deactivate_conanrunenv-release-x86_64.bat
Configuring environment variables
JSON:{"hello":"world"}
parsed 'hello' field:  "world"

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

conan create执行成功后,就会将生成的二进制包保存在本地仓库$HOME/.conan/data/jsonlib/1.0.0/_/_package

执行conan search jsonlib/1.0.0@会显示二进制包的信息

conan upload(上传到私有制品库)

项目编译成功就可以上执行conan upload传到私有制品库了:

代码语言:javascript
复制
conan upload jsonlib/1.0.0  -r ${repo} --all
# ${repo}为私有制品库的名字

–all 指定上传所有内容(配置文件conanfile.py,源码和二进制包),如果不指定些选项,只上传除二进制包之外的所有文件 关于 conan upload命令的详细说明参见Conan官方文档:《conan upload》

上传成功进入JFrog Artifactory后台就可以看到已经上传的package

总结

上面一套流程做完,可以总结一下,将一个已经有项目封装为conan包的过程:

开始麻烦些,需要用conan new 创建一个模板,然后修改模板,将自己的代码装进去。如果你对python很熟,可以不需要conan new创建模板项目,自己手工改就好了。

后面就很简单 :

conan create 完成conan 二进制包编译

conan upload 负责 conan包的上传发布

参考资料

《conan new》

《conan upload》

《conan create》

Package scaffolding for conan new command

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022/04/06 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • conan 将自己的项目生成conan包
    • jsonlib示例程序
      • src/jsonlib.h
      • src/jsonlib.c
      • CMakeLists.txt
    • conan new
      • update jsonlib
        • conanfile.py
        • CMakeLists.txt
        • jsonlib.h jsonlib.c
        • example.cpp
      • conan create (编译jsonlib)
        • conan upload(上传到私有制品库)
          • 总结
            • 参考资料
            相关产品与服务
            制品库
            CODING 制品库(CODING Artifact Repositories,CODING-AR)用以管理源代码编译后的构建产物,支持 Docker、Maven、Helm、Npm 包等常见制品库类型,制品库可以跟源代码协同进行版本化控制,可以与本地各构建工具和云上的持续集成,持续部署无缝结合,并支持漏洞扫描等特性。为研发团队提供优质高效的构建物管理服务,把控构建物质量。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档