【问题标题】:Windows and *nix compilation detectionWindows 和 *nix 编译检测
【发布时间】:2010-02-12 17:29:00
【问题描述】:

应该为 Windows、Linux 和嵌入式目标编译一个项目。应用程序在主机或嵌入式目标上运行时存在行为差异。总结一下我的要求,下表是:

   Target               Compiler      Behavior
   Windows              MSVC, gcc         A
   Host Linux           gcc               A
   Embedded Linux       cross pltf gcc    B

我希望创建一个可以自动识别编译器和环境差异的 Makefile(无需手动传递参数/定义)。仅在 C 源文件级别使用条件编译是否可以解决此类问题?
到目前为止,我还没有使用 automake。

【问题讨论】:

    标签: c windows linux makefile embedded-linux


    【解决方案1】:

    autotools 就是为了解决这个问题。 Makefile 本身无法做到这一点。

    对于条件编译,这些编译器定义了几个可用的宏(例如,_MSC_VER 用于 MSVC++,_WIN32 用于 Windows,__linux__ 用于 Linux)。另外,gcc 提供了assertions for handling different CPU targets

    Target         Compiler     Conditional
    Windows        MSVC++       #ifdef _MSC_VER
    Windows        gcc          #if defined(_WIN32) && defined(__GNUC__)
    Linux          gcc          #if defined(__linux__) && defined(__GNUC__)
    Platform (x86) gcc          #if #cpu(i386)
    Platform (arm) gcc          #if #cpu(arm)
    

    这对于您的目的应该足够了。

    【讨论】:

    • Autotools 可以处理这类事情,但对于某些项目来说,这可能是一笔非常大的开销。
    • 我同意马特的观点。在我拥有的这种(和规模)项目中涉及自动工具是一项开销。
    • 您不必使用 Makefile。还有其他选择。
    • 仅供参考:#cpu 预处理器指令对于新的 GCC 版本来说是一个废弃的指令。 "echo | gcc -E -dM -" 显示内置定义列表
    • @Serge 有确定目标架构的新方法吗?
    【解决方案2】:

    我的答案是:可能。这取决于您的环境之间的差异。

    我会为您的每个环境生成一个由 gcc 中的预处理器预定义的宏列表。您需要做的就是创建一个空文件,比如foo.h,然后为每个环境运行以下命令:gcc -E -dM foo.h。我会将输出重定向到每个环境的不同文件。

    然后,比较预定义的宏并寻找符合要求的宏。在您的问题中,您指出嵌入式环境具有与 Windows 和主机 Linux 平台不同的行为。假设您为嵌入式环境使用不同的芯片架构,则应该定义一个宏来指示该架构。例如,在我的 64 位 linux 机器上,定义了 __x86_64__

    获得该信息后,使用该宏作为条件值:

    #ifdef MACRO_INDICATING_EMBEDDED
    // Behavior B
    #else
    // Behavior A
    #endif
    

    【讨论】:

    • 你实际上并不需要一个虚拟文件 - 你可以这样做:$ gcc -dM -E - < /dev/null
    • 谢谢,@Paul。忘记了从标准输入读取的所有内容。当然,/dev/null 不能在 Windows 上运行。
    【解决方案3】:

    gcc 将定义

     __linux__
    

    在 linux 上编译时。 MSVC 定义了类似的东西——我忘记了,但我相信文档会告诉你

    但实际上您需要学习如何使用配置。这就是它的用途。学习起来很痛苦,但非常有用(automake、autoconf 等)

    【讨论】:

      【解决方案4】:

      您可以尝试为operating systemsarchitectures 组合使用预定义的宏;也许也很有趣:compiler ids

      如果您不想使用更复杂的构建系统,您可以在 makefile 中解析命令行参数。一个简单的例子是将.exe 添加到Windows 上的可执行文件名称中。为此,我在 makefile 中有这样的代码

      ifeq ($(target),win32)
          foo_binary := $(foo_binary).exe
      endif
      

      并通过包含

      make.bat文件调用make
      @make.exe target=win32 %*
      

      【讨论】:

        猜你喜欢
        • 2017-01-02
        • 2016-07-20
        • 1970-01-01
        • 1970-01-01
        • 2012-04-24
        • 2018-11-13
        • 1970-01-01
        • 2011-04-05
        • 1970-01-01
        相关资源
        最近更新 更多