构建系统的嵌入式C / C ++项目 [英] Build system for an embedded C/C++ project

查看:114
本文介绍了构建系统的嵌入式C / C ++项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我要寻找一个高层次的构建系统/工具,可以帮助组织我的嵌入式C项目成模块和组件。请注意,这两个词是非常主观的,所以我的定义如下。

I am looking for a high-level build system/tool that can help organise my embedded C project into "modules" and "components". Note that these two terms are highly subjective so my definitions are given below.


  • 系统模块的C和H文件,但只有一个公共.h文件是对其它模块可见一个有凝聚力的集合。

  • 在另一方面的组件(或层)模块(例如应用层,图书馆层,驱动层,RTOS层等)的集合。

构建系统/工具应该 -

The build system/tool should -


  • 组件和模块之间prevent循环依赖(循环依赖内部模块是好的)

  • prevent访问模块的私有障碍。如果其他模块尽量包含头文件是私有的模块,构建系统必须抛出一个错误。然而,一个私人屏障内的文件必须能够包括屏障内的其它文件。

  • 支持建设和单元测试主机自动执行(TDD的快速反馈回路)

  • 支持单元测试要对目标模拟器运行

  • 支持code静态分析

  • 支持code代

  • 支持code重复检测(执行DRY原则)

  • 支持code美化

  • 单元测试code覆盖度量的支持代

  • 的code质量指标支持代

  • 与平台无关

我可以写我自己的构建工具,花了很多时间就可以了。然而,这不是我的专业领域,我宁愿没有,如果有人已经创建了一个这样的工具重新发明轮子。

I could write my own build tool and spend a lot of time on it. However, that is not my area of expertise and I'd rather not re-invent the wheel if someone has already created such a tool.

推荐答案

实现,这将是对源$ C ​​$ C每个模块放在一个单独的目录的传统方式。每个目录可以包含所有的源文件和头文件的模块。

The conventional way of achieving that would be to place the source code for each module into a separate directory. Each directory can contain all the source and header files for the module.

每个模块的公共头可以置于头的一个单独的,共同的目录。我可能会用一个符号链接从公共目录的相关模块的目录为每个标题。

The public header for each module can be placed into a separate, common directory of headers. I'd probably use a symlink from the common directory to the relevant module directory for each header.

的编译规则简单地指出,任何模块可以包括来自除了在共同目录中的报头的其他模块标题。这实现的结果是没有模块可以包括从另一个模块头 - 除了公共头(从而强制私人障碍)

The compilation rules simply state that no module may include headers from other modules except for the headers in the common directory. This achieves the result that no module can include headers from another module - except for the public header (thus enforcing the private barriers).

preventing循环依赖自动是不平凡的。问题是,你只能建立有通过查看多个源文件在同一时间循环依赖,编译器只查看一次。

Preventing cyclic dependencies automatically is not trivial. The problem is that you can only establish that there is a cyclic dependency by looking at several source files at a time, and the compiler only looks at one at a time.

考虑一对模块,ModuleA和ModuleB以及程序,PROGRAM1,同时使用的模块。

Consider a pair of modules, ModuleA and ModuleB, and a program, Program1, that uses both modules.

base/include
        ModuleA.h
        ModuleB.h
base/ModuleA
        ModuleA.h
        ModuleA1.c
        ModuleA2.c
base/ModuleB
        ModuleB.h
        ModuleB1.c
        ModuleB2.c
base/Program1
        Program1.c

在编译Program1.c,这是完全合法的它包括ModuleA.h和ModuleB.h如果利用两个模块的服务。这样,ModuleA.h不能抱怨如果ModuleB.h被包括在相同的翻译单元(TU),并且也不能ModuleB.h如果ModuleA.h被包含在相同的恩抱怨

When compiling Program1.c, it is perfectly legitimate for it to include both ModuleA.h and ModuleB.h if it makes use of the services of both modules. So, ModuleA.h cannot complain if ModuleB.h is included in the same translation unit (TU), and neither can ModuleB.h complain if ModuleA.h is included in the same TU.

让我们假设它是合法的ModuleA使用ModuleB的设施。因此,编译或ModuleA1.c时ModuleA2.c,可以有与同时具有ModuleA.h和ModuleB.h没有包括的问题。

Let us suppose it is legitimate for ModuleA to use the facilities of ModuleB. Therefore, when compiling ModuleA1.c or ModuleA2.c, there can be no issue with having both ModuleA.h and ModuleB.h included.

然而,prevent循环依赖,你必须能够使用ModuleA.h禁止ModuleB1.c和ModuleB2.c的code。

However, to prevent cyclic dependencies, you must be able to prohibit the code in ModuleB1.c and ModuleB2.c from using ModuleA.h.

据我所看到的,要做到这一点的唯一方法就是一些技术,需要ModuleB,上面写着一个私人标题ModuleA已经包含即使它不是,这是包含前ModuleA.h是以往包括在内。

As far as I can see, the only way to do this is some technique that requires a private header for ModuleB that says "ModuleA is already included" even though it isn't, and this is included before ModuleA.h is ever included.

ModuleA.h的骨架将成为标准格式(和ModuleB.h将类似):

The skeleton of ModuleA.h will be the standard format (and ModuleB.h will be similar):

#ifndef MODULEA_H_INCLUDED
#define MODULEA_H_INCLUDED
...contents of ModuleA.h...
#endif

现在,如果ModuleB1.c的code包含:

Now, if the code in ModuleB1.c contains:

#define MODULEA_H_INCLUDED
#include "ModuleB.h"
...if ModuleA.h is also included, it will declare nothing...
...so anything that depends on its contents will fail to compile...

这是远远自动的。

您可以做的包括文件的分析,并要求有环路少拓扑排序的依赖关系。曾经有一个节目 tsort对在UNIX系统上(和伴侣程序, lorder ),它们共同提供所需的服务使静态( .A )库可以创建包含在没有要求档案的重新扫描命令的目标文​​件。在 ranlib的程序,并最终 AR LD 承担了管理单个库的重新扫描,从而使 lorder 尤其是多余的职责。但 tsort对有更广泛的用途;它可在某些系统(MacOS X系统中,例如,RHEL 5的Linux太)。

You could do an analysis of the included files, and require that there is a loop-less topological sort of the dependencies. There used to be a program tsort on UNIX systems (and a companion program, lorder) which together provided the services needed so that a static (.a) library could be created that contained the object files in an order that did not require rescanning of the archive. The ranlib program, and eventually ar and ld took on the duties of managing the rescanning of a single library, thus making lorder in particular redundant. But tsort has more general uses; it is available on some systems (MacOS X, for instance; RHEL 5 Linux too).

因此​​,使用依赖从GCC跟踪加上 tsort对,你应该能够检查是否有模块之间循环。但是,这将有一些小心处理。

So, using the dependency tracking from GCC plus tsort, you should be able to check whether there are cycles between modules. But that would have to be handled with some care.

有可能会出现一些IDE或其他工具集,自动处理这些东西。但通常程序员可以了足够的训练,以避免出现问题 - 只要需求和模块间的依赖关系是认真地记录

There may be some IDE or other toolset that handles this stuff automatically. But normally programmers can be disciplined enough to avoid problems - as long as the requirements and inter-module dependencies are carefully documented.

这篇关于构建系统的嵌入式C / C ++项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆