如何在不使用IDE的情况下自动生成/更新cpp文件中的头文件?

时间:2013-04-06 19:36:32

标签: c++ vim ide makefile

我现在使用VIM进行C ++开发很多年了,我不想讨论是否使用IDE或强大的文本编辑器进行软件开发的问题。到目前为止,我主要参与了一个仅限标题的模板库,其中所有内容都是模板或内联声明,因此.cpp文件不起主要作用。

最近我更多地参与“传统”C ++开发,面对头/非头文件同步的旧问题。我想知道是否有任何可以在make目标中使用的命令行工具,或者是否可以集成到VIM中来处理这项工作,即根据.cpp文件更新头文件。基本上,类/结构或(模板和内联)实现的声明应该在头文件中忽略,而函数声明应该根据.cpp文件添加,删除或更新。

我知道lzz工具需要你实际编写一个额外的第三种文件格式,然后在实际编译之前将其预处理为.h / .cpp文件。

周围有什么可以做的吗?其他非IDE开发人员如何处理这个问题?

3 个答案:

答案 0 :(得分:6)

由于我自己对第一个问题的答案非常好奇,遗憾的是我无法在这里给你任何好的建议。

至少给你第二个问题的答案:这是我用来手动添加丢失或调整不同步头文件中的更改声明的半自动方式。

使用启用了警告(!)的编译器来发现缺失/更改的声明:

调整声明

更改函数定义的签名后gcc将抛出如下错误:

  • error: conflicting types for ‘....’
    note: previous declaration of ‘....’ was here

修复这个是相对容易的,因为错误消息中已经给出了对定义的引用和相应的声明。

由于我是emacs用户,我无法告诉您在vi中完成此操作的方式,但我确信有一种同样简单的方法可以自动跳转到此位置。 所有必须做的是:

  • 跳转到位置一行复制

  • 跳转到位置2用副本替换旧行并添加尾随;

缺少声明

如果在另一个上添加了一个新功能,而没有将它的原型添加到相应的头文件gcc,则会抛出类似的内容:

  • warning: implicit declaration of function ...

修复这个标签表就派上用场了。我再也不确定如何在vi中处理这个问题,但我确信有一些方法可以快速跳转到编译器警告中其名称给出的函数定义。

此处的工作流程如下所示:

  • 跳转到函数....的定义,复制行

  • 切换到标题文件,粘贴行并添加尾随;

虽然这种方法不过是优雅的,但它已经证明适用于我忘记调整标题以使其与源文件保持同步的情况,这可以通过几次击键来完成。

一个破碎的例子

通过示例在这里展示其应用程序,需要修复它的标题:

/* main.c */
#include "add.h"

int main (int argc, char *argv[]) {
  int a=0, b=0;

  add (a, b);
  sub (a, b);

  return 0;
}

addsub这两项功能都在add.c中定义,如下所示:

/* add.c */
#include "add.h"

int add (int a, int b) {
  return a + b;
}

int sub (int a, int b) {
  return a - b;
}

罪魁祸首add.h显示函数add的签名不匹配以及函数sub缺少声明:

/* add.h */
long add (long a, long b);

尝试编译将导致:

gcc -Wall main.c add.c
main.c: In function ‘main’:
main.c:7: warning: implicit declaration of function ‘sub’
add.c:3: error: conflicting types for ‘add’
add.h:2: note: previous declaration of ‘add’ was here

修复示例

缺少声明

第一个问题:

  • main.c:7: warning: implicit declaration of function ‘sub’

是由于sub

中缺少add.h声明

找到正确的签名:

  • C-x `(下一个错误)将跳转到错误的位置
  • M - 。(gtags-find-tag)将提示标签进行查找
  • RET 将跳转到sub的定义,因为此处的符号是默认
  • M-z {(zap-to-char) C-y (猛)复制签名

到此为止,所有步骤也可以由键盘宏自动完成,因为不需要干预。下一部分必须手工完成:

  • 打开"更正"头文件
  • 并导航到应该输入声明的地点

选择"正确"头文件和"正确"位置很可能是一个品味的问题,与目前采取的步骤形成对比,我不认为这里有很多自动化。

最后,最后一步是粘贴复制的签名:

  • C-y M-y 粘贴复制的签名
  • DEL ; {替换为;

调整声明

接下来必须修复add声明和定义之间的不匹配。

add.c:3: error: conflicting types for ‘add’
add.h:2: note: previous declaration of ‘add’ was here

从定义中复制新签名:

  • C-x `(next-error)将跳转到定义的位置
  • M-z {(zap-to-char) C-y (猛)复制签名

替换声明:

  • C-x `(next-error)将跳转到声明的位置
  • M-z ; (zap-to-char)删除旧声明
  • C-y M-y 现在粘贴复制的签名
  • DEL ; {替换为;

再回来

由于已经有两个缓冲区:

  • M-2 M-x burry-buffer 应该回到之前访问过的缓冲区

摘要

正如你所看到的,虽然不是太耗时的过程不断地来回使用这种方法来修复缺失或错误的声明仍然是一项相当繁琐的任务我只用它来修复我错误输入或完全错过的声明第一次跑。

手动放置"正确"在标题中的声明仍然是我采取的主要方法。

在实施之前布置API可能不是最糟糕的想法恕我直言,这个策略不应该是一个太糟糕的选择。

答案 1 :(得分:2)

makeheaders 项目中有一个名为 fossil 的程序(git 的 vcs 替代方案)。 你可以很容易地从 source code 编译它。 我还建议您阅读doc

答案 2 :(得分:1)

在UNIX类型的系统上,通常IDE不处理这项工作(根据我的经验)。构建工具(通常不与Eclipse,Emacs等IDE捆绑在一起)将完成这项工作。

在现代系统中,处理此问题的最佳方法是让编译器执行此操作:毕竟,编译器最了解。 GCC和大多数其他UNIX / POSIX编译器具有在编译源文件期间将发出make-style依赖性声明的选项。你只需在你的makefile中安排这个,然后在你的makefile中包含输出文件,这一切都很好。

例如,请参阅:http://make.mad-scientist.net/autodep.html

然后查看GCC选项,例如-MMD -MP(这些是预处理器选项)。