管理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++这些工具集成。

C++程序的目录结构、编译、打包、分发的更多相关文章

  1. Android程序的目录结构

    本篇文章我们将介绍Android应用程序的目录结构.本目录下有如图的目录结构: 下面我们来一 一介绍: 1.     Src:该目录中存放的是该项目的源代码 2.     Gen:该目录下的文件全部都 ...

  2. 3-微信小程序开发(小程序的目录结构说明)

    https://www.cnblogs.com/yangfengwu/p/10050784.html 源码下载链接: 或者 这节先说一下小程序的目录结构 自行根据  https://www.cnblo ...

  3. 微信小程序基本目录结构学习

    今天我们就以firstdemo为例,介绍一下小程序的基本目录结构.当我们打开一个微信小程序项目后,点击进入“编辑”菜单,我们可以看到有以下5个文件/文件夹):pages文件夹,utils文件夹,全局文 ...

  4. 大型Vuex应用程序的目录结构

    译者按: 听前端大佬聊聊Vuex大型项目架构的经验 原文: Large-scale Vuex application structures 译者: Fundebug 为了保证可读性,本文采用意译而非直 ...

  5. 微信小程序之目录结构

    小程序,功能不会太多,页面不会太多. 正常情况下,会包含首页,分类页面,个人中心页面,导航页面,其他页面等等. 我们首先要把页面结构布置好,把架子搭建好. 剩下的就是配置一些内容,小程序的基本信息,接 ...

  6. 小程序的目录结构/配置介绍/视图层wxml数据绑定/双线程模型/小程序的启动流程

    安装好微信小程序开发软件,创建项目 小程序文件结构和传统web对比 结构 传统web 微信小程序 结构 HTML WXML 样式 CSS WXSS 逻辑 Javascript Javascript 配 ...

  7. 微信小程序的目录结构解剖

    在微信小程序当中,我们看到有: .js后缀文件,.json后缀文件,.wxss后缀文件,.wxml后缀文件 .js后缀文件就是我们写的普通的js文件 .json后缀文件就是小程序的配置文件,比如:wi ...

  8. Android开发:程序目录结构详解

    HelloWorld程序的目录结构概述 我们可以在文件夹中看到,HelloWorld程序的目录主要包括:src文件夹.gen文件夹.Android文件夹.assets.res文件夹. AndroidM ...

  9. Tomcat的目录结构及部署应用程序

    下载好的二进制的Tomcat,解压会看到7个目录,如下: bin 目录:Tomcat的脚本存放目录,如启动.关闭脚本等.其中 **.bat用于windows平台,**.sh用于Linux平台 conf ...

随机推荐

  1. 【转】用Jmeter进行接口压力测试的步骤

    1.双击jmeter.bat 2.右键点击测试规划à添加àThreadsà线程组,此时在测试规划下边显露出来线程组选项.点击该选项,显露出来线程组界面.参变量线程数表达若干个烦请,参变量Ramp-Up ...

  2. Maven使用阿里云镜像

    Maven确实是个好用的东西,不过在国内的话下载速度不够快,推荐使用阿里云的镜像,配置方法还是比较简单,这里是全局的配置文件 settings.xml中的内容: <settings xmlns= ...

  3. NoSuchBeanDefinitionException: No bean named 'shiroFilter' is defined

    以前运行正常的项目,过了一段时间再运行时出问题,打开链接无反应,无法访问Tomcat,空白页面. 经检查发现,在Tomcat log中有报错: NoSuchBeanDefinitionExceptio ...

  4. Excel开发学习笔记:根据工作表worksheet内容控制按钮的状态

    开发环境基于VSTO,具体配置:visual studio 2010,VB .Net,excel 2007,文档级别的定制程序. 在Ribbon工具栏中有2个功能按钮,它们是否可用取决于workshe ...

  5. oracle10g Error in invoking target 'install' of makefile

    oracle10g series error error in invoking target 'install' of makefile /u01/app/oracle/oracle/product ...

  6. 「小程序JAVA实战」微信小程序简介(一)

    转自:https://idig8.com/2018/08/09/xiaochengxu-chuji-01/ 一直想学习小程序,苦于比较忙,加班比较多没时间,其实这都是理由,很多时候习惯了搬砖,习惯了固 ...

  7. [原创]Java项目统一UTC时间方案

    Java项目统一UTC时间方案 作者:Gods_巨蚁 引言 近期团队的个别项目在进行框架升级后,部分时间值存在8小时误差,原因是错误的将数据库中的时间数据理解成了UTC时间(旧版本认为是北京时间) 考 ...

  8. springboot整合redis单机及集群

    一.单机配置 properties配置 #单机redis spring.redis.host=127.0.0.1 spring.redis.port=6379 spring.redis.passwor ...

  9. 值得一做》关于并查集的进化题目 BZOJ1015(BZOJ第一页计划)(normal-)

    这道题和以前做过的一道经典的洪水冲桥问题很像,主要做法是逆向思维.(BZOJ第10道非SB题纪念) 先给出题目 Description 很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治者 ...

  10. mfs教程(二)

    mfs文件系统(二) 编译和安装 MooseFS部署的首选方法是从源代码安装 源代码包安装支持标准./configure && make && make install ...