Windows 和 *nix 编译检测
应针对 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
autotools 就是为了解决这个问题而设计的。 Makefile 本身无法做到这一点。
至于条件编译,这些编译器定义了几个可用的宏(例如,用于 MSVC++ 的
_MSC_VER
、用于 Windows 的_WIN32
和用于 Linux 的__linux__
) 。此外,gcc 还提供用于处理不同 CPU 目标的断言。这应该足以满足您的目的。
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.That should be sufficient for your purposes.
我的回答是:可能。这取决于您的环境之间的差异。
我会为每个环境生成一个由 gcc 中的预处理器预定义的宏列表。您所需要做的就是创建一个空文件,例如
foo.h
,然后为每个环境运行以下命令:gcc -E -dM foo.h
。我会将每个环境的输出重定向到不同的文件。然后,比较预定义的宏并寻找适合的宏。在您的问题中,您指出嵌入式环境与 Windows 和 Host Linux 平台具有不同的行为。假设您在嵌入式环境中使用不同的芯片架构,则应该定义一个宏来指示该架构。例如,在我的 64 位 Linux 机器上,定义了
__x86_64__
。获得该信息后,使用该宏作为条件值:
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:
gcc
在linux上编译时会定义。 MSVC 定义了类似的东西 - 我忘记了哪个,但我相信文档会告诉你,
但实际上你需要学习如何使用配置。这就是它的用途。学习起来很痛苦,但非常有用(automake、autoconf 等)
gcc will define
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)
您可以尝试组合使用操作系统和架构;也许也很有趣:编译器 ID。
如果您不想使用更复杂的构建系统,可以在 makefile 中解析命令行参数。一个简单的示例是将
.exe
添加到 Windows 上的可执行文件名称中。为此,我在 makefile 中有这样的代码,并通过包含以下内容的
make.bat
文件调用 make: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 makefileand invoke make via a
make.bat
file containing