nmake 基于目标修改宏



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

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

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会更容易。我没有那个选择。

我将提出两种解决方案:一种是按照您的要求执行,即根据目标修改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) = %dn", multiply(2, 3));
}
#endif

您希望将其添加到静态库my_lib.lib,并用作独立的单元测试。

CFLAGS添加-DMAIN的一种标准方法是递归使用 NMAKE。NMAKE 的第二次调用可以使用不同的生成文件,或者如此处所示,使用相同的生成文件和标志以防止无限递归循环。

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

尝试直接从.c文件创建.exe文件,如下所示:

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

不起作用,因为这仍然会创建一个.obj文件,该文件会破坏其他版本。

编辑:似乎不需要.SUFFIXES: .TEST_obj

相关内容

  • 没有找到相关文章

最新更新