conan使用(四)--打包二进制库

前面总结过如何打包一个存头文件库,那种情况下非常简单,因为只需要将源文件拷贝就行了。现在来研究下如何打包一个正常情况下会生成动态库或静态库的包。参考文档:https://docs.conan.io/en/latest/creating_packages/getting_started.html#creating-the-package-recipe 。

1. 准备源码

这里使用我之前写的一个小工具:https://github.com/243286065/lz-string-cpp/tree/dev 。 在dev分支上将其改成了库。

2. 打包

在windows上,同样,我们需要使用conan命令先创建一个conanfile.py模板出来:

conan new LZStringcpp/1.0.0 

然后修改confile.py:

from conans import ConanFile, CMake, tools


class LzstringcppConan(ConanFile):
    name = "LZStringcpp"
    version = "1.0.0"
    license = "MIT"
    author = "xl"
    url = "https://github.com/243286065/lz-string-cpp/tree/dev"
    description = "C++ Class implementation of lz-string (based on https://github.com/pieroxy/lz-string)"
    topics = ("LZS", "Compress")
    settings = "os", "compiler", "build_type", "arch"
    options = {"shared": [True, False]}
    default_options = {"shared": False}
    generators = "cmake"

    def source(self):
        self.run("git clone -b dev https://github.com/243286065/lz-string-cpp.git")
        # This small hack might be useful to guarantee proper /MT /MD linkage
        # in MSVC if the packaged project doesn't have variables to set it
        # properly
        tools.replace_in_file("lz-string-cpp/CMakeLists.txt", "project(LZStringcpp)",
                              '''project(LZStringcpp)
include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
conan_basic_setup()''')

    def build(self):
        cmake = CMake(self)
        cmake.configure(source_folder="lz-string-cpp")
        cmake.build()

        # Explicit way:
        # self.run('cmake %s/lz-string-cpp %s'
        #          % (self.source_folder, cmake.command_line))
        # self.run("cmake --build . %s" % cmake.build_config)

    def package(self):
        self.copy("LZString.h", dst="include", src="lz-string-cpp/src")
        self.copy("*.lib", dst="lib", keep_path=False)
        self.copy("*.dll", dst="bin", keep_path=False)
        self.copy("*.so", dst="lib", keep_path=False)
        self.copy("*.dylib", dst="lib", keep_path=False)
        self.copy("*.a", dst="lib", keep_path=False)

    def package_info(self):
        self.cpp_info.libs = ["LZStringcpp"]

这里先解释下上述脚本的含义:

  • settings 字段定义了不同的二进制包的配置,不同的配置都将需要产生不同的二进制包。如果你想要做交叉编译,可以使用self.settings.os and self.settings.arc
    if platform.system() == "Windows":
        cmake = CMake(self)
        cmake.configure(source_folder="hello")
        cmake.build()
    else:
        env_build = AutoToolsBuildEnvironment(self)
        env_build.configure()
        env_build.make()
  • default_options 字段中表示默认提供的是静态库;
  • source 函数用于进行源码准备,这里是执行了 git clone ,你也可以执行http下载什么的。
  • build 中使用cmake来进行构建,你也可以直接调用make、MSBuild等进行构建。
  • package 方法拷贝头文件、库文件到最终的包里。
  • package_info 方法定义了使用者使用这个包时必须链接LZStringcpp这个库。

然后执行执行:

conan create . xl/stable

正常情况下会执行成功,然后可以去.conan目录下查看,可以看到一个新的库,而且是编译好lib文件的。
我们可以把它上传到服务器上:

conan upload LZStringcpp/1.0.0@xl/stable -r develope --all

image.png

3. 测试

我们去Ubuntu上,修改上次我们测试rapidjson的测试程序的conanfile.txt:

[requires]
rapidjson/1.1.0@tencent/stable
LZStringcpp/1.0.0@xl/stable

[generators]
cmake

[imports]
include, * -> ./include
lib, * -> ./lib

[options]
LZStringcpp:shared=True

同样在build目录下执行:

conan install ..

它会提示:
image.png
这是因为我们是在windows上打包的,而且打包时默认是编译的静态库,所以我们在Ubuntu下要求依赖动态库,它是本来不存在的,于是它就会建议你使用 --build LZString 进行源码构建,于是我们重新运行:

conan install .. --build LZStringcpp -s compiler.libcxx=libstdc++11

结果:
image.png
这样我们就能在Linux上直接使用,是不是非常方便。只要conanfile.py的settings字段中的属性不能完全匹配,就可以从源码进行构建。

能够直接从源码构建,这是非常好的一个特性,能够让我们避免维护众多的版本。

注:在Linux上重新使用conan编译库时请加上-s compiler.libcxx=libstdc++11编译参数,否则容易出现链接的问题。

posted @ 2019-11-21 16:01  星星,风,阳光  阅读(3646)  评论(0编辑  收藏  举报