nmake根据目标

时间:2018-03-01 16:59:52

标签: macros nmake targets

我有一个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"

但由于$ @,target,在makefile的那一部分确定无效,因此它崩溃了并且没有逻辑上的工作。

定义附加宏的逻辑位置是在定义目标时,但我没有看到如何在没有NMAKE将其解释为DOS命令的情况下执行此操作。

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

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

1 个答案:

答案 0 :(得分: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