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編譯參數,否則容易出現鏈接的問題。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM