完美的makefile

时间:2009-08-07 10:03:16

标签: makefile build-process continuous-integration

我想使用makecontinuous integration自动单元测试多平台构建结合使用模块化构建。类似的设置在Java和.NET中很常见,但是我很难将它们整合到make和C / C ++中。如何实现?

我的要求:

  • 快速建造;非递归make(Stack Overflow question What is your experience with non-recursive make?
  • 模块化系统(即最小依赖项,带有组件的子目录中的makefile)
  • 多平台(通常用于单元测试的PC,用于系统集成/发布的嵌入式目标)
  • 完整依赖性检查
  • 执行(自动)单元测试(敏捷工程)的能力
  • 挂钩到持续集成系统
  • 易于使用

我从non-rec make开始。我仍然觉得这是一个很好的起点。

到目前为止的限制:

  • 没有整合单元测试
  • 基于Windows的ARM编译器与Cygwin路径的不兼容性
  • makefile与Windows \ paths
  • 不兼容
  • 转发依赖

我的结构如下:

    project_root
       /algorithm
                 /src
                     /algo1.c
                     /algo2.c
                 /unit_test
                     /algo1_test.c
                     /algo2_test.c
                 /out
                     algo1_test.exe
                     algo1_test.xml
                     algo2_test.exe
                     algo2_test.xml
             headers.h
       /embunit
       /harnass
   makefile
   Rules.top

我想保持简单;这里的单元测试(algo1_test.exe)依赖于'algorithm'组件(ok)和单元测试框架(在构建它时可能知道也可能不知道)。但是,将构建规则移到顶部make对我没有吸引力,因为这会在整个系统中分发组件的本地知识。

至于Cygwin路径:我正在使用相对路径进行构建。这解决了/cygdrive/c问题(因为编译器通常可以处理/路径)而不会引入C :(这使得不喜欢)。还有其他想法吗?

2 个答案:

答案 0 :(得分:3)

CMake以及相关工具CTest和CDash似乎可以满足您的要求。值得一看。

Bi​​ll Hoffman(一位主要的CMake开发人员)在CMake邮件列表的Recursive Make Considered Harmful中引用了post论文:

  

...因为cmake正在为你创建makefile,许多缺点   避免了递归make,例如你不应该调试   makefile甚至考虑它们是如何工作的。还有其他例子   在那篇论文中,cmake也为你解决了这些问题。

另见this answer“递归制造 - 朋友还是敌人?”这里是stackoverflow。

- Recursive Make - friend or foe?

答案 1 :(得分:0)

好的,这就是我的工作:

我在根和通配符模式下使用一个Makefile来收集目录中的所有文件。请注意,我假设foo / * .c将构成foo.so。这使得Makefile保持最小,因为只需将文件添加到目录就会自动将其添加到构建中。

因为它正在使用我正在假设(我为我的项目执行此操作)使用的编译器使用gcc(cc)兼容的命令行语法。所以MSC出了故障;但是不要感到沮丧,我在Windows上进行大部分开发(不幸的是)并使用MinGW和MSys;奇迹般有效。生成本机二进制文件,但是使用符合Posix的构建环境构建。

使用稍微标准的-MD开关完成依赖性检查。然后我将所有* .d文件包含在Makefile中。我使用自动收集的源文件构建模式。

最后,使用“标准”check目标实施单元测试。检查目标就像所有目标一样,除了它取决于单元测试并在构建完所有内容后执行。我是这样做的,这样你就可以分别构建项目或构建单元测试(以及项目的其余部分)。当我不开发项目时,我想构建它并完成它。

以下是我如何操作的示例:https://github.com/rioki/c9y/blob/master/Makefile 它还包含installuninstalldist目标。

正如你所看到的,一切都是明确的,没有递归的调用,而且一切都相对简单。我使用了automake和autoconf,我再也不会这样做了;还有其他构建工具是不可能的,如果我需要安装foojam或barmake来构建一些东西,我通常会立即抛弃该项目。