nmake 根据目标修改宏

问题描述 投票:0回答:2

我有一个 Makefile.mak,我可以选择从基于 C 的源代码创建 test.exe 或 DLL。我正在使用 CL.EXE 和 NMAKE。

当目标是 TEST.EXE 时,我想像这样修改我的 CFLAGS 宏:

CFLAGS = $(CFLAGS) -DMAIN

当然,我在我的 C 代码中使用了它:

#ifdef MAIN
... int main()... yada yada
#endif

我试过了

!IF $@ == "test.exe"

但是它崩溃了并且无法按逻辑工作,因为 $@ 目标在 makefile 的该部分中不是确定性的。

定义附加宏的逻辑位置是在定义目标时,但我不知道如何在 NMAKE 将其解释为 DOS 命令的情况下做到这一点。

test.exe: test.obj
  CFLAGS = $(CFLAGS) -DMAIN
  $(LINKER) /out:$@ $(LIB) $*.obj $(LIBS)

我知道,使用 gmake 会更容易。我没有这个选项。

macros nmake targets
2个回答
1
投票

我将提出两种解决方案:一种可以满足您的要求,即根据目标修改

CFLAGS
,另一种可能是更好的方法。

假设你有一个文件

multiply.c
:

#include <stdio.h>

int multiply(int a, int b) {
   return a * b;
}

#ifdef MAIN
int main() {
   printf("Unit test: multiply(2, 3) = %d\n", multiply(2, 3));
}
#endif

您想将其添加到静态库

my_lib.lib
,也可以用作独立的单元测试。

-DMAIN
添加到
CFLAGS
的一种标准方法是递归使用 NMAKE。 NMAKE 的第二次调用可以使用不同的 makefile,或者如此处所示,使用带有标志的 same makefile 以防止无限递归循环。

TARGETS = my_lib.lib multiply.exe
CFLAGS  = -W4 -O2 -nologo -Zi

all: $(TARGETS)
my_lib.lib: multiply.obj

my_lib.lib:
    lib -nologo -out:$@ $**

!ifndef RECURSE
multiply.exe:
    nmake -nologo CFLAGS="-DMAIN $(CFLAGS)" RECURSE= $@
!endif

multiply.obj: .FORCE

.FORCE:

如果定义了

RECURSE
,则使用内置规则来创建测试程序
multiply.exe

这个解决方案有效。但每次使用时都需要重新制作

multiply.obj
,因为它有两个版本:一种带有
main
,一种没有。

第二种解决方案区分这些目标文件。

TARGETS = my_lib.lib multiply.exe
CFLAGS  = -W4 -O2 -nologo -Zi

all: $(TARGETS)
my_lib.lib: multiply.obj
multiply.exe: $*.TEST_obj

my_lib.lib:
    lib -nologo -out:$@ $**

multiply.exe:
    link -nologo -out:$@ $**

.c.TEST_obj:
    $(CC) -DMAIN $(CFLAGS) -c $< -Fo$@

这给出:

>nmake -nologo
        cl -W4 -O2 -nologo -Zi /c multiply.c
multiply.c
        lib -nologo -out:my_lib.lib multiply.obj
        cl -DMAIN -W4 -O2 -nologo -Zi -c multiply.c -Fomultiply.TEST_obj
multiply.c
        link -nologo -out:multiply.exe multiply.TEST_obj

尝试直接从

.exe
文件创建
.c
文件,如下所示:

.c.exe:
    $(CC) -DMAIN $(CFLAGS) $<

不起作用,因为这仍然会创建一个

.obj
文件,该文件会破坏其他版本。

编辑:

.SUFFIXES: .TEST_obj
似乎不需要。


0
投票

这是我的第二个答案。它没有直接解决OP的问题,但更短并且与标题匹配,并且可以帮助任何通过搜索到达的人。

例如,假设您有两个文件

aaa.c
bbb.c
,并且您希望在编译第二个文件时使用 MSVC 开关
-fp:fast
。使用 GNU
make
,您可以使用两行 Makefile 来解决这个问题:

CFLAGS = -O3 -Wall
bbb.o: CFLAGS += -ffast-math

根据需要给出:

make aaa.o bbb.o
cc -O3 -Wall   -c -o aaa.o aaa.c
cc -O3 -Wall -ffast-math   -c -o bbb.o bbb.c

对于

nmake
,要获得相同的结果,您可以使用递归。五行 Makefile:

CFLAGS = -W3 -O2 -nologo -Zi
!ifndef HAVE_ADDED_FP_FAST
bbb.obj:
        @nmake -nologo HAVE_ADDED_FP_FAST= CFLAGS="$(CFLAGS) -fp:fast" $@
!endif

将给予:

nmake -nologo aaa.obj bbb.obj
        cl -W3 -O2 -nologo -Zi /c aaa.c
aaa.c
        cl -W3 -O2 -nologo -Zi -fp:fast /c bbb.c
bbb.c

HAVE_ADDED_FP_FAST=yes
放在递归调用中可能会更清楚。其目的是防止无限循环。

© www.soinside.com 2019 - 2024. All rights reserved.