前面總結過如何打包一個存頭文件庫,那種情況下非常簡單,因為只需要將源文件拷貝就行了。現在來研究下如何打包一個正常情況下會生成動態庫或靜態庫的包。參考文檔: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
編譯參數,否則容易出現鏈接的問題。