2010-04-19 78 views
3

依靠预处理器和预定义的编译器宏实现可移植性似乎很难管理。什么是更好的方式来实现C项目的可移植性?我想将特定于环境的代码放在表现相同方式的标头中。有没有办法让构建环境选择包含哪些头文件?C代码的可靠可移植性不依赖于预处理器

我在想我会把环境特定的标题放到特定环境的目录中。然后,构建环境会将平台目录中的标题复制到根目录中,构建项目,然后删除副本。

回答

6

这完全取决于您的构建环境,当然与C本身无关。

有一两件事你可以尝试是建立你的包含路径在您的makefile文件这样的:

INCDIRS=-I ./solaris 
#INCDIRS=-I ./windows 
#INCDIRS=-I ./linux 
: 
CC=gcc $(INCDIRS) ... 

,并取消你的工作之一。然后把你的平台特定的头文件在这些目录:

你可以,在必要的时候,甚至有不同平台的makefile如solaris.mkwindows.mk,而不必在所有编辑的任何文件。

但我不认为你对预处理器的反感,这是它擅长的事情之一,人们几十年来一直在成功地做到这一点。最重要的是,当您的代码需要更改每个平台时会发生什么情况。你可以将代码抽象成头文件,但这对我来说似乎难以管理。

3

这基本上是一个配置脚本的功能 - 即计算出系统的细节,然后修改该系统的makefile。看看GNU autoconf的文档,它可能会做你想做的,虽然我不确定如果有必要的话,它是多么的可移植。

2

pax's answer是好的,但我会补充一点,你可以

  1. 混合和匹配处理在构建系统中的一些系统依赖(大的事情,一般),并与其他预处理器(小东西)
  2. 关注麻烦在代码和系统相关位之间定义一个精简的粘合层,并将所有的预处理器废话粘在那里。所以你总是打电话MyFileOpen(),其中调用fopen上的unix和其他窗口上的东西。现在,您的代码中只有与文件打开相关的任何预处理程序的部分是MyFileOps模块。
+0

这就是我将要做的,但我试图避免在独立于平台的代码中放置太多样板。拥有特定于平台的头文件中的大部分/所有平台特定的代码对我来说似乎更好。这样,如果某个平台上的某些内容发生更改/中断,我可以更改标题以反映该更改。抽象是很好的,在这种情况下。 – Yktula 2010-04-19 02:16:52

+0

我会建议你的目标是零主要源代码中的ifdefs。每个平台变体应该隐藏在头文件中,或者隐藏在具有多个实现的API后面。 (我也同意@ dmckee的建议,即将大型平台选择放入makefile或构建配置脚本。) – 2010-04-19 02:26:42