对make(Linux)和nmake使用相同的makefile(Windows)

j0k*_*ker 20 c nmake makefile

我有一个简单的C-Programm(1源文件),我想在Linux和Windows上通过make resp编译.NMAKE.是否有可能使用单个makefile完成此操作?

我想到了类似的东西

ifeq($(MAKE), nmake)
    // nmake code here
else
    // make code here
endif
Run Code Online (Sandbox Code Playgroud)

不幸的是nmake似乎不明白ifeq,所以我不能用它.我有一个工作的makefile,但会产生非常难看的结果:

hello: hello.c
    $(CC) hello.c
Run Code Online (Sandbox Code Playgroud)

这适用于两个系统.问题是结果取决于各个编译器的默认行为.在Linux下,我得到一个可执行的名为'a.out'而不是'hello'.在Windows下,我得到'hello.exe',但也有'hello.obj',我不想拥有它.

有没有人知道另一种方式?或者我正在尝试绝对不可能的事情?

Som*_*ude 11

这可能并非不可能,但最有可能的是,无论如何写两个makefile会更容易.

GNU make(在Linux中使用)和nmake都包含指令,因此一些常见的东西可以放在主makefile包含的公共makefile中.


mev*_*ron 8

你应该考虑使用CMake.有一个源文件应该很容易!

编辑:

以下是如何设置一个简单的项目:

cmake_minimum_required(VERSION 2.8)

project(Simple)

include_directories("${PROJECT_BINARY_DIR}")

add_executable(Simple simple.cpp)
Run Code Online (Sandbox Code Playgroud)

要构建简单项目,您将执行以下操作(假设您的源和CMakeLists.txt文件位于~/src/simple:

foo@bar~/src/simple$ mkdir build
foo@bar~/src/simple$ cd build
foo@bar~/src/simple$ cmake ..
foo@bar~/src/simple$ make
Run Code Online (Sandbox Code Playgroud)

  • @JohanBezem当我发布这个答案时,该评论不可用.但是,我认为这个答案是在不受家庭作业的人为限制的情况下解决问题的正确方法...... (4认同)
  • -1在对OP提出问题的评论中说,他需要使用NMAKE。 (2认同)

Bev*_*ins 8

我想使用make和nmake使用的相同makefile include.由于make在注释行上识别行继续但nmake没有,这意味着我们可以为make和nmake分别指定.例如:

# \
!ifndef 0 # \
# NMAKE code here \
MV=move # \
RM=del # \
CP=copy # \
!else
# Make code here
MV=mv -f
RM=rm -f
CP=cp -f
# \
!endif
Run Code Online (Sandbox Code Playgroud)

只需确保nmake特定代码被#终止


小智 7

我无法找到一种方法来使用通用的 makefile 为 GNU Make 和 Microsoft NMAKE 工作,主要是因为它们的“include”和/或“if”指令的语法不兼容。微软NMAKE需要使用!指令的前缀。例如,!if、!include 等...

然而,如果允许它有单独的宏,它可能会被欺骗。在这里,我通过观察以下内容,介绍了迄今为止我发现的使 makefile 兼容 GNU Make 和 Microsoft NMAKE 的最佳方法:

  1. Microsoft NMAKE 读取默认宏的 TOOLS.ini 文件。
  2. Microsoft 套件使用 .obj 作为目标文件扩展名。
  3. GNU Make 读取在 MAKEFILES 环境变量中定义的文件。
  4. GNU 套件使用 .o 作为目标文件扩展名。
  5. GNU make 不需要为目标提供可执行文件扩展名 .exe。

注意:以下已使用 Microsoft Visual Studio 2015 和 MINGW32 进行测试。

第 1 步:创建以下 DOS 批处理文件,并在调用 CMD 提示时让它运行。

set MAKEFILES=TOOLS.gcc
call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat"
Run Code Online (Sandbox Code Playgroud)

步骤 2:在您的工作目录下创建一个 TOOLS.ini 文件,如下所示:(该文件独立于您的项目依赖项,可能除了库之外)

[NMAKE]
LDLIBS  =
CDEBUG  = /Zi
LDEBUG  = /debug:full
WDFLAGS = /wd4996 /wd4774 /wd4018 /wd4710 /wd4820
CFLAGS  = /nologo $(CDEBUG) /EHsc /Wall $(WDFLAGS)
LDFLAGS = /nologo $(LDEBUG)
RM      = del /F /Q
LINK     = "$(VCINSTALLDIR)bin\link" $(LDFLAGS)
CP    = copy
CC    = cl
CPP = $(CC) /P
X    = .exe
O    = .obj

.obj.exe:
    $(LINK) $** $(LOADLIBES) $(LDLIBS) /Out:$@
Run Code Online (Sandbox Code Playgroud)

第 3 步:在您的工作目录下创建一个 TOOLS.gcc,如下所示:(该文件与您的项目依赖项无关,可能除了库之外)

LD_LIBS =
LDLIBS  =
CDEBUG  = -g
LDEBUG  = -g
CFLAGS  = $(CDEBUG)
LDFLAGS = $(LDEBUG)
RM      = rm -f
LINK     = gcc $(LDFLAGS)
CP        = cp
CC        = gcc
CPP     = $(CC) -E
X        =
O        = .o

%: %.o
    $(LINK) $^ $(LOADLIBES) $(LDLIBS) -o $@
Run Code Online (Sandbox Code Playgroud)

第 4 步:如下编辑您的 makefile(注意 $(X) 和 $(O)),其中仅指定了依赖项。

SHELL    = /usr/bin/sh
app: app1$(X) app2$(X)
app1$(X): app1$(O)
app2$(X): app2$(O)

clean:
    $(RM) *.exe *.o *.obj *.ilk *.pdb *.tmp *.i *~
Run Code Online (Sandbox Code Playgroud)

第 5 步:使用相同的 makefile 享受 GNU Make 和 Microsoft NMAKE

$ nmake
$ make clean
$ nmake clean
$ make
Run Code Online (Sandbox Code Playgroud)


ala*_*850 5

我的解决方案是使用两个不同的文件名。(因为不同操作系统中Makefile名称搜索优先级不会相同)

对于 Windows,我使用普通的“Makefile”。

对于Linux,我根据这篇文章使用特殊的“GNUmakefile” 。

这样 nmake (Win) 将找到“Makefile”,而 make (Linux) 将找到“GNUmakefile”。

  • 关于您的回复是否回答了发布的问题,我同意和不同意@Das_Geek 的观点。我认为您暗示“是否有可能使用单个 makefile 来完成此任务?”的答案。没有。然后你继续提供解决问题的替代方法——我认为这很好,但严格来说并不是OP所要求的。IMO,这个问题有点松散,你的答案也有点松散。吉高 (2认同)