nmake 根据目标修改宏
nmake modify macro based on target
我有一个 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 会更容易。我没有那个选项。
我将提出两种解决方案:一种按照您的要求进行,即根据目标修改 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
尝试直接从 .c
文件创建 .exe
文件,如:
.c.exe:
$(CC) -DMAIN $(CFLAGS) $<
不起作用,因为这仍然会创建一个 .obj
文件,该文件会破坏另一个版本。
编辑: .SUFFIXES: .TEST_obj
好像不需要。
我有一个 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 会更容易。我没有那个选项。
我将提出两种解决方案:一种按照您的要求进行,即根据目标修改 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
尝试直接从 .c
文件创建 .exe
文件,如:
.c.exe:
$(CC) -DMAIN $(CFLAGS) $<
不起作用,因为这仍然会创建一个 .obj
文件,该文件会破坏另一个版本。
编辑: .SUFFIXES: .TEST_obj
好像不需要。