前面我們已經能夠使用conan來從公共服務器上拉取C/C++包來集成進我的工程中,但是在實際開發中,我們可能需要自己封裝或使用非公開的庫,那么自己搭建一個私服是個很現實的需求。 搭建conan私服有幾種方式,這里介紹一種目前使用比較多的Artifactory方式。
1. 安裝和配置Artifactory
我們以docker的方式拉取Artifactory鏡像(這一步可能花費時間會比較久):
docker pull docker.bintray.io/jfrog/artifactory-cpp-ce
然后安裝:
sudo docker run -d -p 8081:8081 --name artifactory-cpp-ce docker.bintray.io/jfrog/artifactory-cpp-ce
那么我們就已經創建了一個Artifactory服務器。通過8081端口可以直接訪問。默認賬號密碼:admin(password)。 登錄后我們可以跳過proxy設置,直接創建一個名為develope的conan倉庫:
然后直接點擊develope,它會告訴你怎么在客戶端進行配置: 按照它的提示進行配置,注意替換
2. 本地創建conan包
首先創建一個新的目錄conanpkg,然后在該目錄下執行
conan new Hello/1.0.1 -t
使用-t參數的意義是生成一個測試包。 conanfile.py文件非常關鍵,它定義了如何打包,如何導入源文件:
from conans import ConanFile, CMake, tools
class HelloConan(ConanFile):
name = "Hello"
version = "1.0.1"
license = "<Put the package license here>"
author = "<Put your name here> <And your email here>"
url = "<Package recipe repository url here, for issues about the package>"
description = "<Description of Hello here>"
topics = ("<Put some tag here>", "<here>", "<and here>")
settings = "os", "compiler", "build_type", "arch"
options = {"shared": [True, False]}
default_options = {"shared": False}
generators = "cmake"
def source(self):
self.run("git clone https://github.com/conan-io/hello.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("hello/CMakeLists.txt", "PROJECT(HelloWorld)",
'''PROJECT(HelloWorld)
include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
conan_basic_setup()''')
def build(self):
cmake = CMake(self)
cmake.configure(source_folder="hello")
cmake.build()
# Explicit way:
# self.run('cmake %s/hello %s'
# % (self.source_folder, cmake.command_line))
# self.run("cmake --build . %s" % cmake.build_config)
def package(self):
self.copy("*.h", dst="include", src="hello")
self.copy("*hello.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 = ["hello"]
- source函數是表示如何導入源文件,這里是指明了代碼倉庫;
- build指明要如何編譯;
- package是打包你的項目。
test_package 目錄下的代碼是測試包代碼,創建好包后你可以用它進行測試。 現在執行create命令進行打包:
conan create . demo/testing
create命令會執行以下操作:
- 將conanfile.py從用戶文件夾拷貝到conan的本地緩存中;
- 安裝包,強制從源構建它;
- 移動到test_package文件夾並創建臨時構建文件夾;
- 執行conan install …,以安裝test_package/conanfile.py的要求;
- 構建並啟動示例程序,分別調用test_package/conanfile.py文件的build()和test()方法。
即相當於執行了以下命令:
conan export . demo/testing
$ conan install Hello/1.0.1@demo/testing --build=Hello
# test
$ conan test test_package Hello/1.0.1@demo/testing
如此一個包就已經創建好了。
3. 上傳包到服務器
上傳包命令是:
conan upload <RECIPE> -r <REMOTE> --all
<RECIPE>
即是我們在經常用到的一個包名字:
此時就可以像其它包一樣正常在其它地方使用。
4. 用法補充
4.1 不使用git導入源碼
上面的例子中是在source中使用git拉取代碼,如果我們的代碼不是在git上怎么辦? (1)HTTP下載 同樣是在source函數中,可以使用http下載源碼:
zip_name = "XXX"
tools.download("https://github.com/XXXXXXXXXXXXX/%s" % zip_name, zip_name)
tools.unzip(zip_name)
...
(2)本地代碼 此時就不能使用source函數,需要刪掉它,增加一個exports_sources 配置來代表你的源碼目錄:
class HelloConan(ConanFile):
name = "Hello"
version = "0.1"
license = "<Put the package license here>"
url = "<Package recipe repository url here, for issues about the package>"
description = "<Description of Hello here>"
settings = "os", "compiler", "build_type", "arch"
options = {"shared": [True, False]}
default_options = {"shared": False}
generators = "cmake"
exports_sources = "src/*"
...