zoukankan      html  css  js  c++  java
  • C++中的头文件发布

    所谓头文件发布,就是在build某个工程的build过程中,把头文件发布到特定的输出目录,而依赖于此工程的代码,则需要从此特定的输出目录来include头文件。换句话说,在这种做法下,头文件与最终产生的library/binary具有同等地位,它也是build过程的一个产出。

    我们写C++代码,一般都是直接从source目录包含所需要的头文件的,那么为什么要使用这种头文件发布的方式呢? 我们可以先分析一下不发布头文件可能带来的问题:

    1. 因为直接从source目录包含头文件,我们无法控制哪些头文件可以include,而哪些不可以。因为很多情况下,我们很可能只想对用户暴露某个层次的api,但对于用户来说,因为他们在同一目录下,包含任何头文件都是同等方便的。这明显提高了犯错的可能性。
    2. 如果build不完整,有些问题要到链接时才能发现。 
      举个例子,如果A依赖于B,你在B中新增加了个函数,在A中使用。然后你在没有build B的情况下直接build了A,这个错误无法在编译期检测出来,而只有把所有源文件编译完了链接的时候你才被通知有这么个错误,对于大工程,这会是个问题。
    3. 如果build不完整,有些问题在运行时才能发现 - 这就是bug了
      举个例子,还是A依赖于B,你在B中修改了一个宏定义或者常量定义,如把#define PI 3.14改成了#define PI 3.1415926,然后你又忘了build B而直接去build A了,此时编译没有问题,但是此时模块B与模块A中对PI的定义就不一致了,必然会造成运行时问题,这种问题要更难发现。

    所以,为了保证C++代码中接口与binary的完全统一,包括可见性与行为上的统一,使用头文件发布是非常有效的一个方法,对于上述问题:

    1. 通过只把需要暴露的头文件发布到特定目录,有效的杜绝了用户”包含不该包含“的头文件的问题
    2. 因为B中被更新的头文件未被发布,该问题被提前到编译期被发现
    3. 因为B中被更新的头文件未被发布,此时A与B的binary中使用的PI,都是未更新的3.14,从而保证了一致性。

    要实现头文件发布,其实也蛮简单,主要是编译设置上的事,对源代码并没有影响:
    为方便说明,还是用A依赖于B为例:

    • 在build B时,把B的头文件拷贝到与输出目录bin同级的目录,比如include目录
    • 在build A时,把上面提到的include目录作为包含目录

    如果你用Visual Studio的话,可以用post build event;用gmake的话,可以新加一个publish header的rule。

    当然,如果你有一个高度智能的build system,这个过程可以完全自动化,比如我们team现在实现的一个,只需指明dependency关系,发布头文件,设置包含目录都自动完成,大大简化了build的维护。

  • 相关阅读:
    Oracle-11g ASM Fast Mirror Resync特性
    Oracle
    Oracle-19C中的DML重定向(DML Redirection)
    Oracle-重建oraInventory仓库
    Oracle-输出存储在ASM中当前数据库客户端未打开的文件列表
    Oracle-19c特性之刷新数据库缓存中的密码文件信息
    Oracle-DG环境进行failover故障演练
    Oracle-switchover转换DG角色
    论衡中校长郗会锁儿子高考移民西藏事件反映出的诸多问题
    退役后记:春夏篇
  • 原文地址:https://www.cnblogs.com/baiyanhuang/p/2256314.html
Copyright © 2011-2022 走看看