Introduction to conan: generate conan package from your own project

conan generates conan packages from its own projects

Conan is a dependency and package manager for C and C + + languages. It is Free and open source , applicable to all platforms (Windows, Linux, OSX, FreeBSD, Solaris, etc.), and can be used to develop all targets, including embedded, mobile (iOS, Android) and bare metal. It also integrates with CMake, Visual Studio (MSBuild), Makefiles, SCons and other build systems, including proprietary systems.
It is designed and optimized to accelerate the development and continuous integration of C and C + + projects. Through complete binary package management, it can create and reuse any number of different binary files (for different configurations, such as architecture, compiler version, etc.) for any number of different versions of packages, and use the same process on all platforms. Because it is decentralized, it is easy to run your own server to privately host your own packages and binaries without sharing them@ Conan official document

In previous blogs< Introduction to conan (4): conan refers to an example of a third-party library >In, we take cJSON as an example to illustrate how to reference a conan package in the project.

How to package the modules designed by yourself in the form of conan package and provide them to third parties (customers / colleagues)?

This article will use jsonlib, a module that implements string parsing based on cJSON library, to illustrate how to package its own module into conan and provide it to third parties.

jsonlib sample program

All the source code of the example is stored in the GIT repository conan_example For the jsonlib branch of, please clone the code directly to the local:

git clone https://gitee.com/l0km/conan_example.git -b jsonlib
# -B switch jsonlib to the jsonlib branch, which is equivalent to the 'git checkout jsonlib' command 

Jsonlib is a very simple library with only two files: jsonlib h,jsonlib. c. Only one function is implemented to parse the field content specified by name from the JSON string, and the results are saved to the output buffer. The JSON parsing is actually implemented by calling cJSON. The following is the implementation source code.

src/jsonlib.h

/*
 * 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

//************************************
// Parse the content of the field specified by name from the JSON string, and save the result to the output buffer
// @param    const char * cjs JSON character string
// @param    const char * name Field name
// @param    char * buffer [out] Output buffer
// @param    size_t bufsz Output buffer length
// @return   int 0 is returned successfully, otherwise - 1 is returned
//************************************
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

#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

cmake_minimum_required(VERSION 3.10.3)
# VERSION option is only allowed for versions above 3.0
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

Now jsonlib h,jsonlib. c,CMakeLists. Txt three files constitute a simple but complete standard CMake project.

conan_example
│  CMakeLists.txt
│      
└─src
       jsonlib.c
       jsonlib.h

How to package this small project into conan package? If you read my last blog< Introduction to conan (VI): conanfile txt conanfile. The difference between PY >And< Introduction to conan (I): installation of conan and jfrog artifact >You can almost know that the key to a conan package is to have a conan file Py script to define various configurations of the package.

But write a conanfile It seems that Python is quite troublesome. I only know a little about python.

Obviously, handwriting is impossible. The conan new command is used to create a new conan configuration file template. With the template, you can modify it:

$ 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_ The directory structure generated after lib execution is as follows. You can see that Conan has generated conanfile very attentively Py, jsonlib source files and cmakelists Txt and the corresponding test_package - this is a complete Conan package project framework. Although it is not what we need, it is much more convenient to have this framework than to write from scratch:

conan_example
│  CMakeLists.txt
│  conanfile.py
│  
├─src
│      jsonlib.cpp
│      jsonlib.h
│      
└─test_package
    │  CMakeLists.txt
    │  conanfile.py
    │  
    └─src
            example.cpp

The -- template cmake used to execute the conan new command above_ The Lib parameter is a function of Conan's project that is still in experiment. The Conan project framework is generated according to the specified template. For details, see the official Conan document:< Package scaffolding for conan new command>

For detailed description of conan new command, please refer to Conan official document <conan new>

update jsonlib

Install the generated framework on our project, cononjs.

conanfile.py

First, modify conanfile as shown in the figure below py

Insert picture description here

CMakeLists.txt

The following figure shows the cmakelists generated by conan new Txt into CMakeLists.txt of jsonlib Txt

jsonlib.h jsonlib.c

src/jsonlib.c replaces Src / jsonlib. Generated by conan new cpp,

src/jsonlib.h replace the Src / jsonlib. Generated by conan new h

example.cpp

Test generated by conan new_ package/src/example. Replace CPP with the following code to implement a simple jsonlib interface test

test_package/src/example.cpp

#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 (compile jsonlib)

Created conanfile Py, compiling the conan package is very simple

# Notice it's conan_example jsonlib branch
$ 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 . According to the configuration file (under the peer folder) conanfile.py )Building binary packages
See Conan official documentation for the usage of conan create command line <conan create>

After conan create is executed successfully, the generated binary package will be saved in the local warehouse $home / conan/data/jsonlib/1.0.0/_/_ package

Executing conan search jsonlib/1.0.0 @ will display the binary package information

Conan upload (upload to private product library)

After the project is compiled successfully, you can execute conan upload to the private product library:

conan upload jsonlib/1.0.0  -r ${repo} --all
# ${repo} is the name of the private artifact library

– all specifies to upload all contents (configuration file conanfile.py, source code and binary package). If some options are not specified, only all files except binary package will be uploaded

For a detailed description of the conan upload command, see the official Conan document: <conan upload>

After uploading successfully, you can see the uploaded package in the background of jfrog artifact

summary

conan has completed a set of processes, which can be summarized as follows:

At first, it's more troublesome. You need to create a template with conan new, then modify the template and load your own code. If you are familiar with python, you don't need conan new to create a template project. Just change it manually.

The following is simple:

conan create completes the compilation of conan binary package

conan upload is responsible for uploading and publishing conan packages

reference material

<conan new>

<conan upload>

<conan create>

<Package scaffolding for conan new command>

conan series

Introduction to conan (I): installation of conan and jfrog artifact
Introduction to conan (II): conan service configuration - password management and policy
Introduction to conan (III): uploading precompiled artifacts
Introduction to conan (IV): examples of conan referencing third-party libraries
Introduction to conan (V): examples of conan cross compiling and referencing third-party libraries
Introduction to conan (VI): the difference between conanfile.txt and conanfile.py
Introduction to conan (VII): generate conan package from your own project

Keywords: cmake

Added by Zaxnyd on Sat, 19 Feb 2022 09:13:43 +0200