Windows 和 *nix 编译检测

发布于 2024-08-21 06:25:16 字数 388 浏览 5 评论 0原文

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

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

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

One project should be compiled for Windows, Linux and an embedded target. The application has behavior differences when running on host or embedded targets. To summarize my requirements, here is the table:

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

I wish to create a Makefile that would recognize the compiler and environmental differences automatically (without need to pass parameters/defines manually). Is it possible to resolve such problem by just using conditional compilation at C source file level?
I don't use automake so far.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

十二 2024-08-28 06:25:16

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

至于条件编译,这些编译器定义了几个可用的宏(例如,用于 MSVC++ 的 _MSC_VER、用于 Windows 的 _WIN32 和用于 Linux 的 __linux__) 。此外,gcc 还提供用于处理不同 CPU 目标的断言

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)

这应该足以满足您的目的。

The autotools were made to solve this problem. A Makefile by itself can't do this.

As for conditional compilation, there are several macros available that these compilers define (e.g. _MSC_VER for MSVC++, _WIN32 for Windows and and __linux__ for Linux). Also, gcc provides 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)

That should be sufficient for your purposes.

送舟行 2024-08-28 06:25:16

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

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

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

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

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

My answer is: probably. It depends on the differences between your environments.

I would generate a list of the macros pre-defined by the preprocessor in gcc for each of your environments. All you need to do is create an empty file, say foo.h, and run the following command: gcc -E -dM foo.h for each environment. I'd redirect the output to a different file for each environment.

Then, compare the predefined macros and look for one that fits the bill. In your question, you indicated that the embedded environment has different behavior from the Windows and Host Linux platforms. Assuming you're using a different chip architecture for the embedded environment, there should be a macro defined that indicates the architecture. For example, on my 64-bit linux box, __x86_64__ is defined.

Once you have that info, use that macro as your conditional value:

#ifdef MACRO_INDICATING_EMBEDDED
// Behavior B
#else
// Behavior A
#endif
回忆那么伤 2024-08-28 06:25:16

gcc

 __linux__

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

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

gcc will define

 __linux__

when compiling on linux. MSVC defines something similar - I forget which but I am sure the docs will tell you

but really you need to learn how to use configure. Thats what its for. Its a pain to learn but highly useful (automake, autoconf etc)

一影成城 2024-08-28 06:25:16

您可以尝试组合使用操作系统架构;也许也很有趣:编译器 ID

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

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

,并通过包含以下内容的 make.bat 文件调用 make:

@make.exe target=win32 %*

You could try a combination of predefined macros for operating systems and architectures; perhaps also interesting: compiler ids.

If you don't want to use a more sophisticated build system, you can parse command line arguments within your makefile. A simple example would be the addition of .exe to executable names on windows. For this I have code like this within the makefile

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

and invoke make via a make.bat file containing

@make.exe target=win32 %*
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文