Conan——C++包管理工具——使用踩坑记录
使用conan所遇到的大部分问题都可以在conan官方文档中找到答案,
参考官方文档地址:
https://docs.conan.io/en/latest/
虽然大多数情况下,答案不是那么显然。
不过也正是如此,本文把那些可能有点绕的问题的解决办法和原理,尽可能详细的记录下来,
以便后人遇到相同问题时能节省一点定位的时间。
创建一个包的最简步骤
1. conan new 生成一个conanfile.py
2. 编辑conanfile.py
一般的,代码的版本控制不在conan中进行,也不推荐这么做,你有更好的选择:git
from conans import ConanFile, CMake, tools
class BgyArTopicConan(ConanFile):
name = "bgy_ar_topic"
version = "v1.0.0"
........some informations........
settings = "os", "compiler", "build_type", "arch"
requires = ["myjson/v1.0.0@ar/stable"]
def source(self):
self.run("git clone git@10.8.202.206:agricultural_robot/ros/common/bgy_ar_topic.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("bgy_ar_topic/CMakeLists.txt", "project(bgy_ar_topic)",
'''project(bgy_ar_topic)
include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
conan_basic_setup()''')
def build(self):
cmake = CMake(self)
cmake.configure(source_folder="bgy_ar_topic")
cmake.build()
def package(self):
self.copy("*.h", dst="include", src="bgy_ar_topic/include")
self.copy("*.so", dst="lib", src="lib", keep_path=False)
self.copy("*.a", dst="lib", src="lib", keep_path=False)
def package_info(self):
self.cpp_info.libs = tools.collect_libs(self)
很显然,在conanfile.py文件中定义了几个方法,并且依赖了一个包:myjson
其中source方法是用来获取代码用的,比如在上面示例中,source方法正是将代码拉取到了本地仓库的source目录下
~/.conan/data/bgy_ar_topic/v1.0.0/ar/stable/source$ ls
bgy_ar_topic
在拉取到代码之后,将bgy_ar_topic中的CMakeLists.txt文件中的内容
project(bgy_ar_topic)
# other configures
....
替换成如下内容
project(bgy_ar_topic)
include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
conan_basic_setup()
# other configures
....
这conanbuildinfo.cmake正是conan生成的让bgy_ar_topic找到myjson包的头文件和lib的文件。
conan_basic_setup() 是conanbuildinfo.cmake到处的cmake方法。
通过调用这个方法,可以使bgy_ar_topic工程在编译时能够找到其依赖的包的头文件和库。
3. conan create
通过下面指令创建包bgy_ar_topic/v1.0.0@ar/stable
$conan create --profile=ros . ar/stable
创建后,在conan本地仓库中会多出这个目录:
~/.conan/data/bgy_ar_topic/v1.0.0/ar/stable
构造过程
创建时执行的构建将在 ~/.conan/data/bgy_ar_topic/v1.0.0/ar/stable/build/中进行,回顾一下前面的conanfile.py
def build(self):
cmake = CMake(self)
cmake.configure(source_folder="bgy_ar_topic")
cmake.build()
在定义build方法时,这里暗示执行cmake指令的工作目录为
~/.conan/data/bgy_ar_topic/v1.0.0/ar/stable/build/c023db9fc677d4d0b3bd0c20f71385e4cf8a1220
注意到这一串很长的代码了吧,这就是构造标识码,这个码也会在 ~/.conan/data/bgy_ar_topic/v1.0.0/ar/stable/package中出现。
这个build方法相当于执行以下shell指令
~/.conan/data/bgy_ar_topic/v1.0.0/ar/stable/build/c023db9fc677d4d0b3bd0c20f71385e4cf8a1220$ cmake bgy_ar_topic
...
something outputs
...
~/.conan/data/bgy_ar_topic/v1.0.0/ar/stable/build/c023db9fc677d4d0b3bd0c20f71385e4cf8a1220$ make
...
something outputs
...
打包过程
打包bgy_ar_topic包的时候,将在 ~/.conan/data/bgy_ar_topic/v1.0.0/ar/stable/build/中进行,回顾一下前面的conanfile.py
def package(self):
self.copy("*.h", dst="include", src="bgy_ar_topic/include")
self.copy("*.so", dst="lib", src="lib", keep_path=False)
self.copy("*.a", dst="lib", src="lib", keep_path=False)
注意这里使用的self.copy方法,其中dst暗示的工作目录为~/.conan/data/bgy_ar_topic/v1.0.0/ar/stable/package/
而src所暗示的工作目录则是~/.conan/data/bgy_ar_topic/v1.0.0/ar/stable/build/
所以说,package中做的就是将你想要打包的文件从~/.conan/data/bgy_ar_topic/v1.0.0/ar/stable/build/中,拷贝到~/.conan/data/bgy_ar_topic/v1.0.0/ar/stable/package/中
在本例中,会将~/.conan/data/bgy_ar_topic/v1.0.0/ar/stable/build/bgy_ar_topic/include中的所有头文件复制到~/.conan/data/bgy_ar_topic/v1.0.0/ar/stable/package/include中
将~/.conan/data/bgy_ar_topic/v1.0.0/ar/stable/build/lib中的所有动态库和静态库拷贝到~/.conan/data/bgy_ar_topic/v1.0.0/ar/stable/package/lib中
发布自己的包
发布包需要使用conan upload指令
conan upload bgy_ar_topic/v1.0.0@ar/stable
使用这一条指令的时候,会将本地conan仓库中的bgy_ar_topic/v1.0.0@ar/stable上传到远程库
远程仓库在哪里,怎么添加私有的远程仓库?怎么看到当前支持的远程仓库?
$ conan remote add ar-conan-host http://10.8.203.98:8081/repository/ar-conan-host/
$ conan remote list
ar-conan-host: http://10.8.203.98:8081/repository/ar-conan-host/ [Verify SSL: True]
conan upload bgy_ar_topic/v1.0.0@ar/stable -r ar-conan-host
这样,就指定远程仓库是ar-conan-host仓了,并将b'g'y_ar_conan包的打包信息上传,注意,此时并没有把生成物package目录中的内容上传。
需要注意的是,conan在上传之前是需要登录一下仓库的,因为远程仓库做了安全设置,不是谁都能有权限上传私有包的。所以你需要登录一下:
conan user -p 666666 -r ar-conan-host master
conan 使用用户:master,密码666666, 登录到ar-conan-host仓库,
很多时候,我们的用户并不希望构造我们生成的包,所以上传包的时候,把我们打包好的生成物上传是一个好的选择:
$ conan upload bgy_ar_topic/v1.0.0@ar/stable -r ar-conan-host --all
在上传的时候添加一个参数--all即可,现在你的仓库中不止有包的配方,还有一套生成好的包。
了解Conan的本地仓库
所谓的本地仓库,并没有那么神秘,它静静的躺在我们用户目录下,
对于Linux
/home/user/.conan/data/
对于windows
C:/Users/user/.conan/data/
当执行
$conan new task_control/v1.0.0
$conan create --profile=default . test/test
之后,会在本地目录自动生成这个目录
~/.conan/data/task_control/v1.0.0/test/test$ ls
build export_source metadata.json package
export locks metadata.json.lock source
具体的操作对本地仓库会有什么影响,我相信,认真看过”创建一个包的最简步骤“这一节内容之后,你已经有了认识。所以这里我不想过多赘述。