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
andself.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
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 ..
它会提示:
这是因为我们是在windows上打包的,而且打包时默认是编译的静态库,所以我们在Ubuntu下要求依赖动态库,它是本来不存在的,于是它就会建议你使用 --build LZString
进行源码构建,于是我们重新运行:
conan install .. --build LZStringcpp -s compiler.libcxx=libstdc++11
结果:
这样我们就能在Linux上直接使用,是不是非常方便。只要conanfile.py的settings
字段中的属性不能完全匹配,就可以从源码进行构建。
能够直接从源码构建,这是非常好的一个特性,能够让我们避免维护众多的版本。
注:在Linux上重新使用conan编译库时请加上-s compiler.libcxx=libstdc++11
编译参数,否则容易出现链接的问题。