管理C++的第三方库以及编译

第三方库这个说法,不知道出自哪里,但一般是指开发者,系统/平台提供商之外的第三个参与者提供的程序库。大多数开源软件库在软件系统中都是第三方库。

完全不使用库的开发,在90年代就已经被放弃了,特别MFC/OWL/QT这些先行者。开源运动的兴起使得第三方库成为主力使用库。

C++领域有一些非常特殊的库,比如早期的STLport和当前的Boost,它们就像是语言的事实标准,基本在每个程序中都可以见到他们的身影。

但第三方库也会导致相当多的问题,主要总是包括:

  1. 版本不一致。同一个软件系统中,如果引用了同一个第三方库的两个不同版本,那一定会暗生问题。
  2. 编译选项不一致。一般为了减少编译时间,第三方库都会以编译后的.a/.lib形式参与软件编译,第三方库的编译选项与软件系统的编译选项不同,也是会有一些潜在的问题。特别是x86/x64,ansi/utf-8这些选项不同,根本就不能用。
  3. 版本管理库变大。在一些大项目中常常会有几个G的版本库,每次clone代价很大。其实很多都是第三方库,不同版本,不同编译选项生成的库引入。

除了把编译的库引入项目,也有人以源代码的形式引入开源软件,比如GCC、SDL、WxWights、QT。如果第三方库本身编译不复杂,原代码也很简单,这么做比较好。

但是像Boost.Thread这样的库,就不行了。它需要编译成动态库,静态引用会有问题。

另一方面,如果第三方库升级,就是一个比较复杂的工程,如果不升级,又只能看着第三方库的问题得不到解决。

在Linux上这个问题并不严重,系统级的软件管理工具可以代管大多数的第三方。比如debian系的,可以使用apt得到大多数的开源库,同时如果需要最新版本,也可以通过第三方源来取得。

在交叉编译和window平台上这个问题就非常头痛了。我们需要从几个层次来解决这个问题。

  1. 需要有中心化的第三方源代码获取平台,这个平台需要支持按用户/组织+第三方库+版本的形式取得源代码,同时还需要保证及时跟踪来源。这个类似于bintray/github都可以。公司内部可以使用gitlab来搭建。
  2. 需要有一个构建脚本平台,存放在不同工具链和平台的情况下,这个脚本可以从源代码中心的源代码,把源代码编译成库。同样可以用github这类工具搭建和管理。
  3. 在项目中提供一个配置文件,需要的开源库(只需指定编译脚本,脚本是针对开源库)。这个只需要一个文本文件即可。
  4. 在开发者的机器和编译服务器上,下载编译脚本,生成库。源代码、最终结果可以缓存在本机上。可以使用项目原本的构建工具。

如果只考虑windows+vc这个工具链,最简单的工具是使用msbuild,即为第三方库构建工程,编译结果生成成为vcprops文件,由项目引用。在项目工程中,可以通过prebuild过程加上下载、编译、安装第三方库的过程,因为有缓存,每台机器上应该只需要做一次。

考虑Boost这个最常用的库,并没有一个msbuild可以调用工程,这个方案通用性很差。但对于只使用vc的公司还是非常实用。因为只需要一个内源的源代码管理工具就可以了,没有git甚至可以用svn。

如果有多平台交叉编译,要考虑先统一项目自己的编译工具,使用CMake/Scons/Gyp这些跨平台编译工具,否则需要在不同的编译工具下都做一套。

以CMake为例,最接近这个系统的是CPM这个工具,它用github做前两个服务器,CMake的脚本来完成下载,编译。但受CMake脚本的能力限制,它无法完成更复杂的版本管理工作,只能做为一个试验原型。

使用CPM,可以先把自己的项目改成使用CMake编译,在CMakeLists.txt中引入CPM语句,再引入需要的第三方库。如果第三方库已经在有一个CPM脚本工程,就很简单直接引用即可。但如果没有,就需要自己先建立CPM脚本工程。即一个CMakeLists.txt,可以下载编译第三方库,再提供CPM一些专用宏,以便后续项目能找到这个第三方库。

一个内源第三方库(指公司内共享库)需要两个git工程(或svn目录),一个提供原始代码和维护工作,另一个提供构建脚本,这个脚本甚至可以是专用于某个项目。最后需一个工具能下载,脚本调用,缓存管理这些工作。

基于C++社区不自己发明工具传统,以及cmake/git的流行程度,我考虑使用bash来完成这个部分。基本数据结构设计如下:

CPM_HOME 做为根目录

sources   源代码下载
    hosts   下载服务器
      groups  用户或组织
         library-name 库
scripts
     hosts   下载服务器
      groups  用户或组织
         library-name 库, 源代码构建完成后会安装到这个目录下
            bin 二进制结果,包括可执行文件
            include 头文件,一般应支持多配置
            lib/xx/ 应对不同的配置,参考boost library
            flags/xx/ 应对不同的配置,需导出一些编译选项
build
     构建目录,对于不支持外部构建目录的开源软件,可以选择复制过来in-source构建
     考虑并发构建,应在这里文件锁定操作。
     除了锁定目录外,其它目录可以删除以减少空间占用。

repos
     project-id 成生特定于项目第三方库包,这样项目只需要引入一个第三方目录。

以上目录都会在本地保存一个hash文件以保持完整和不变性。

类似python我们使用 requirements.txt 项目的需求第三方库,使用cpp_setup requirements.txt来完成预建编译环境。

requirements使用

[host:port/]username/cpm-library-name

全局配置中,可以默认的host:port。这里可以不写host:port。

这里是指向特定的构建脚本,脚本能支持哪些平台,哪些发布版本,哪些运行时库都由脚本自己决定。缺少项目需要的配置时,只会编译失败。

如果项目支持CMake,那么只需要引入CPM即可。

如果项目可以要求生成一个project-id目录来聚合第三方库,方便make/vc++这些工具集成。

创建一个编译脚本也很简单,使用几个原语来完成操作即可。

GET - 下载url,自动会放到缓存目录,如果是压缩包会解压到build目录
CONFIG - 生成build目录,使用CPM_BUILD_PATH来引用这个目录,最后一步会把脚本本生也复制到build目录下去。
RUN - 会自动在build目录下执行。
EXPORT - 指定目录或文件复制回脚本目录。

如果第三方库一次只能编译出一个配置,那可能需要多个CONFIG,RUN,EXPORT。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 201,552评论 5 474
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,666评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 148,519评论 0 334
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,180评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,205评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,344评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,781评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,449评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,635评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,467评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,515评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,217评论 3 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,775评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,851评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,084评论 1 258
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,637评论 2 348
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,204评论 2 341

推荐阅读更多精彩内容

  • 功课 1、每日一抽 第18天·21天OH卡美颜瘦身课 #玩卡不卡·每日一抽# 每一位都可以通过这张卡片觉察自己: ...
    叮噹Vicky阅读 249评论 0 0
  • 2016年六月,从淘气姐姐哪里无意中听到禅绕画,彼时手工空白期,想玩点什么新的东西,又不能添置太多材料,更不能...
    松果2016阅读 451评论 2 7
  • 离乡我少年, 归时鬓斑斑。 再见池边树, 柳老不吹绵。 飒飒秋山风 ,抚面问前缘。 皎皎淮水月 ,触影叹经年。 饮...
    陈广才阅读 435评论 0 1
  • 昨日,转眼已逝,湮没在年轮里。今日,还在继续,是否会将昨日重演。明日,憧憬满怀,谁知该变成怎样的今日? 只是不觉间...
    一剑哥哥阅读 331评论 2 7