对 make (Linux) 和 nmake (Windows) 使用相同的 makefile
我有一个简单的 C 程序(一个源文件),我想分别通过 make 和 nmake 在 Linux 和 Windows 上编译它。是否有可能使用单个 makefile 来完成此任务?
我想到了类似的事情,
ifeq($(MAKE), nmake)
// nmake code here
else
// make code here
endif
不幸的是 nmake 似乎不理解 ifeq,所以我不能使用它。我有一个可用的 makefile,但这会产生非常丑陋的结果:
hello: hello.c
$(CC) hello.c
这在两个系统上都有效。问题是结果取决于各个编译器的默认行为。在 Linux 下,我得到一个名为“a.out”而不是“hello”的可执行文件。在 Windows 下,我得到“hello.exe”,但也有我不想拥有的“hello.obj”。
还有其他方法吗?或者我正在尝试的事情是绝对不可能的?
I have a simple C program (one source file) which I want to compile on Linux and on Windows via make and nmake, respectively. Is there a possibility to accomplish this with a single makefile?
I thought about something like
ifeq($(MAKE), nmake)
// nmake code here
else
// make code here
endif
Unfortunately nmake seems not to understand ifeq
, so I cannot use that. I have a working makefile, but that produces very ugly results:
hello: hello.c
$(CC) hello.c
That works on both systems. The problem is that the outcome depends on the default behaviors of the respective compilers. Under Linux I get an executeable named 'a.out' rather than 'hello'. Under Windows I get 'hello.exe' but there is also 'hello.obj' which I do not want to have.
Is there an alternative way? Or is what I'm trying absolutely impossible?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(10)
这可能并非不可能,但很可能太难了,无论如何编写两个 makefile 会更容易。
GNU make(在 Linux 中使用)和 nmake 都有 include 指令,因此一些常见的东西可以放在主 makefile 包含的公共 makefile 中。
It's probably not impossible, but most likely so hard that it would be easier to write two makefiles anyway.
Both GNU make (used in Linux) and nmake have include directives though, so some common things can be put in a common makefile that is included by the main makefile.
您应该考虑使用 CMake 来实现此目的。有了一个源文件,这应该是很容易的。以下是如何设置一个简单的项目:
要构建这个简单的项目,您将执行以下操作(假设您的源文件和 CMakeLists.txt 文件与源文件
hello.c
:You should look at using CMake for this. With one source file, it should be quite easy. Here is how you could set up a simple project:
To build the simple project, you would do the following (this assumes your source and CMakeLists.txt files are in the same directory as the source file
hello.c
:我想使用 Make 和 NMAKE 使用的相同 makefile include。由于 make 可以识别注释行上的行继续,但 NMAKE 不能,这意味着我们可以为 Make 和 NMAKE 提供单独的指令。例如:
您只需确保 NMAKE 特定的代码包含在
# \
中。I wanted to use the same makefile include to be used by Make and NMAKE. Since make recognises line continuation on comment lines, but NMAKE doesn't, this means that we can have separate instructions for Make and NMAKE. For example:
You just have to make sure that NMAKE-specific code is encompassed by
# \
.我无法找到一种方法来使用通用的 makefile 同时适用于 GNU Make 和 Microsoft NMAKE,主要是因为它们的“include”和/或“if”指令的语法不兼容。需要使用Microsoft NMAKE!指令的前缀。例如,!if、!include 等...
但是,如果允许有单独的宏,则可能会被欺骗。在这里,我通过观察以下内容介绍了迄今为止我发现的使 makefile 兼容 GNU Make 和 Microsoft NMAKE 的最佳方法:
注意:以下内容已使用 Microsoft Visual Studio 2015 和 MINGW32 进行了测试。
步骤1:创建以下DOS批处理文件,并让它在调用CMD提示符时运行。
步骤 2:在您的工作目录下创建一个 TOOLS.ini 文件,如下所示:(该文件与您的项目依赖项无关,可能除了库)
步骤 3:在您的工作目录下创建一个 TOOLS.gcc,如下所示:(该文件是独立的项目依赖项(可能除了库)
步骤 4:如下编辑 makefile(注意 $(X) 和 $(O)),其中仅指定依赖项。
第 5 步:使用相同的 makefile 享受 GNU Make 和 Microsoft NMAKE
I am not able to find a way to use a common makefile to work for both GNU Make and Microsoft NMAKE, mainly because they have an incompatible syntax for "include" and/or "if" directives. Microsoft NMAKE requires to use ! prefix for directives. For example, !if, !include, etc...
If it is allowed to have separate macros, however, it could be tricked around. Here I presents the best way I found so far for making a makefile compatible for both GNU Make and Microsoft NMAKE by observing the followings:
Note: The following has been tested using Microsoft Visual Studio 2015 and MINGW32.
Step 1: create a following DOS batch file and let it run whenever the CMD prompt is invoked.
Step 2: Create a TOOLS.ini file under your working directory as below: (this file is independent of your project dependencies except the libraries possibly)
Step 3: Create a TOOLS.gcc under your working directory as below: (this file is independent of your project dependencies except the libraries possibly)
Step 4: Edit your makefile as below (note $(X) and $(O)) where only dependencies are specified.
Step 5: Enjoy GNU Make and Microsoft NMAKE with the same makefile
我的解决方案是使用两个不同的文件名。 (因为不同操作系统中Makefile名称搜索优先级不会相同)
对于Windows,我使用普通的“Makefile”。
对于Linux,我根据这篇文章使用特殊的“GNUmakefile”< /a>.
这样 nmake (Win) 将找到“Makefile”,而 make (Linux) 将找到“GNUmakefile”。
My solution is to use two different filenames. (since the Makefile name searching priority in different OSes will not be the same)
For Windows, I use normal "Makefile."
For Linux, I use the special "GNUmakefile" according to this article.
So that nmake (Win) will find "Makefile," and make (Linux) will find "GNUmakefile."
解决方案: https://github.com/jaykrell/w3/blob/master/Makefile< /a>
Solution: https://github.com/jaykrell/w3/blob/master/Makefile
是的,您可以使用单个 Makefile 来完成此操作。此材料的最佳来源是 O'Reilly 的书:
使用 GNU Make 管理项目,第三版,作者:Robert Mecklenburg
请参阅第 7 章:可移植 Makefile。
总之,该技术是测试环境变量 ComSpec,它表示 Windows 命令解释器是否存在:
我用一个便携式 shell 脚本包装它,该脚本使用 sed 编辑 Nmake 或 GNU make 的 makefile...
Yes, you can do this with a single Makefile. The best source for this material is the O'Reilly book:
Managing Projects with GNU Make, Third Edition By Robert Mecklenburg
See chapter 7: Portable Makefiles.
In summary, the technique is to test the environment variable ComSpec which says if the Windows command interpreter is present:
I wrap this with a portable shell script which uses sed to edit the makefile for Nmake or GNU make...
我只是想到了一些完全不同的东西。
如果你坚持使用极其简单的 Makefile,你说它可以工作,并且只是将“标准”变量 CC 和 CFLAGS
分别
放入你各自的环境中,那么
。
它可能会工作
请注意,我对使用的确切选项并不坚定,您必须自己弄清楚。但据我所知,两者都使变体识别同一组标志。您甚至可以在相应的命令行上设置它们(但不能在 makefile 中设置,因为 NMAKE 使用不同的“ifeq”语法...)
I just thought of something completely different.
If you stick to your extremely simple Makefile, which, you say, works, and just put the 'standard' variables CC and CFLAGS in your respective environments, say
respectively
and
respectively
it might just work.
Be aware, I'm not firm in the exact options to use, you'll have to figure them out yourself. But AFAIK both make variants recognize the same set of flags. You may even set those on the respective command lines (but not in the makefile, since NMAKE uses a different 'ifeq' syntax...)
我最近尝试使用 C 预处理器从包含预处理器符号的模板 Makefile.cc 生成可移植的 Makefile。到目前为止,它的效果出奇的好。第一个观察结果是,NMAKE 将预扫描一个 Tools.ini 文件,该文件位于与 Then 相同的目录中,
旁边有一个“真正的”Makefile,该文件仅以 GNU Make 和 NMAKE 的公共子语言编写。
请注意,-E 开关对于编译器(至少是我使用的三大编译器:GCC、Clang 和 CL)来说非常常见,仅用于预处理文件。在 GNU Make 中,$(MAKECONFIG) 扩展为空,但在 NMAKE 中,它提供了声明自身的预处理器变量。由于您的模板 Makefile.cc 可以使用 #ifdef 检查它,以及检查编译器声明自身的公共变量,因此您可以为“make”程序、您的操作系统和您正在使用的编译器。
如果你有任何“make”,你可能也已经有了一个 C 编译器;无需安装额外的软件,如 CMake 或 autotools。它使用旧的机制,因此可能在很多环境中工作。据我目前所知,速度真的很快。至少比在自动工具中运行配置步骤更快。我遇到的唯一缺点是它限制了 Make 规则的样式位于同一行,因为预处理器会更改代码的缩进。此外,预处理器会输出带有 # 标记的行,但由于这些行在 Makefile 中开始注释,因此它们无论如何都会被忽略。
A 有一个较小的 C++ 项目,其中包含 Makefile.cc,如下所示。它可以使用 GCC、Clang 或 CL 在 GNU Make 或 NMAKE 上以及 Windows 或 POSIX 环境中进行编译。不过,我还没有支持 BSD Make 或测试任何其他编译器。
I've recently experimented with using the C preprocessor to generate a portable Makefile from a template Makefile.cc containing preprocessor symbols. So far it's worked surprisingly well. The first observation is that NMAKE will prescan a Tools.ini file, which I provide in the same directory as
Then I have a 'true' Makefile next to it which is written in only the common sub language of GNU Make and NMAKE.
Note that the -E switch is pretty common for compilers (at least the big three I work with: GCC, Clang, and CL) for only preprocessing the file. With GNU Make the $(MAKECONFIG) expands to nothing, but in NMAKE it provides the preprocessor variable declaring itself. Since your template Makefile.cc can check it with #ifdef, as well as check for common variables with which the compiler declares itself, you can customize your Makefile.mk quite a bit for both the 'make' program, your operating system, and the compiler you're using.
If you have any 'make' you probably already have a C compiler too; there's no need to install additional software like CMake or autotools. It uses mechanisms that are old and so likely to work in a lot of environments. And from what I've been able to tell so far, it's really fast. Faster at least than running a configuration step in autotools. The only disadvantage I've faced is that it limits the style of your Make rules to being on the same line, because the preprocessor changes the indentation of the code. Also the preprocessor spits out lines with # tags, but since these start a comment in a Makefile, they get ignored anyway.
A have a somewhat small C++ project with a Makefile.cc that looks like the following snippet. It compiles on GNU Make or NMAKE with either GCC, Clang, or CL and on either Windows or in a POSIX environment. I've yet to support BSD Make or test any other compiler though.
是否可以使用 gnu sed 或 perl 中的脚本将主机的 Makefile 转换为 Microsoft 兼容的 NMakefile?毕竟,Makefile 是文本文件,可为您使用的任何辅助工具提供输入。 Sed 和 Perl 都适用于 Linux 和 Windows。
Wouldn't it be possible to use a script in gnu sed, or perl to translate the host's Makefile to a Microsoft compatible NMakefile? The Makefiles, after all, are text files to provide input for whichever helper tool you're using. Sed and Perl both exist for Linux and Windows.