【问题标题】:Reliable portability for C code without relying on the preprocessorC 代码的可靠可移植性,无需依赖预处理器
【发布时间】:2011-02-09 12:32:35
【问题描述】:

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

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

【问题讨论】:

    标签: c build build-automation makefile


    【解决方案1】:

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

    您可以尝试的一件事是在您的 makefile 中设置包含路径:

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

    并取消注释您正在处理的那个。然后将您的平台特定标头放在这些目录中:

    ./solaris/io.h
    ./windows/io.h
    ./linux/io.h
    

    在紧要关头,您甚至可以拥有不同的平台 makefile,例如 solaris.mkwindows.mk,而根本不必编辑任何文件。

    但我不认为您对预处理器有反感,这是它擅长的事情之一,而且人们已经成功地做了几十年。最重要的是,当您的 代码 需要更改每个平台时会发生什么。您可以将代码抽象为头文件,但在我看来,这比几个#ifdefs 更难管理。

    【讨论】:

      【解决方案2】:

      这基本上就是配置脚本的作用——即确定系统的细节,然后修改该系统的 makefile。看看GNU autoconf 的文档,它可能会做你想做的事,虽然我不确定如果有必要的话它对 Windows 的便携性。

      【讨论】:

        【解决方案3】:

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

        1. 混合搭配处理构建系统中的一些系统依赖项(一般来说是大事)和预处理器处理其他系统依赖项(小事)
        2. 限制麻烦 在您的代码和系统相关位之间定义一个薄粘合层,并将所有预处理器废话粘贴在那里。所以你总是调用MyFileOpen(),它在unix上调用fopen,在windows上调用其他东西。现在,您的代码中唯一与文件打开相关的预处理器部分是 MyFileOps 模块。

        【讨论】:

        • 这是我将要做的,但我试图避免在独立于平台的代码中放置太多样板。在特定于平台的标头中包含大多数/所有特定于平台的代码对我来说似乎更好。这样,如果某个平台中的某些内容发生更改/损坏,我可以更改标题以反映该更改。在这种情况下,抽象很好。
        • 我建议你的目标是在主线源代码中的 ifdefs 为零。每个平台变体都应该隐藏在头文件中,或者隐藏在具有多个实现的 api 后面。 (我也同意 @dmckee 的建议,将大型平台选择放入 makefile 或构建配置脚本。)
        猜你喜欢
        • 2010-09-15
        • 2011-07-21
        • 2010-11-18
        • 1970-01-01
        • 2010-11-28
        • 2013-04-01
        • 1970-01-01
        • 2011-04-19
        • 2010-11-05
        相关资源
        最近更新 更多