这几天在做一个项目,在Mac、Linux、Android下都是使用make系统进行编译管理的,但是到了Windows下很多正常的make“指令”不被Nmake识别,很是苦恼。看了一天的Nmake解释终于有点入门了,记录下一些两者的异同点,便于以后查阅。
Archive-maintaining program; default ‘
ar’.
Program for compiling assembly files; default ‘
as’.
Program for compiling C programs; default ‘
cc’.
Program for compiling C++ programs; default ‘
g++’.
Program for running the C preprocessor, with results to standard output; default ‘
$(CC) -E’.
Flags to give the archive-maintaining program; default ‘
rv’.
Extra flags to give to the assembler (when explicitly invoked on a ‘
.s’ or ‘
.S’ file).
Extra flags to give to the C compiler.
Extra flags to give to the C++ compiler.
Extra flags to give to the C preprocessor and programs that use it (the C and Fortran compilers).
Extra flags to give to the SCCS
Extra flags to give to compilers when they are supposed to invoke the linker, ‘
ld’.
1. 自动变量的区别
GNU make的自动变量 | Windows Nmake自动变量 |
$@ The file name of the target of the rule. If the target is an archive member, then ‘$@’ is the name of the archive file. $%: The target member name, when the target is an archive member. For example, if the target is foo.a(bar.o) then ‘$%’ is bar.o and ‘$@’ is foo.a. ‘$%’ is empty when the target is not an archive member. | $(@) Current target's full name (path, base name, extension), as currently specified. |
$$@ | $$@ Current target's full name (path, base name, extension), as currently specified. Valid only as a dependent in a dependency. |
$* 这个变量表示目标模式中"%"及其之前的部分 (少用) | $* Current target's path and base name except file extension. |
$? The names of all the prerequisites that are newer than the target, with spaces between them. $^ The names of all the prerequisites, with spaces between them. $| The names of all the order-only prerequisites, with spaces between them. | $? All dependent files in the dependency with a later timestamp than the target $** All dependents of the current target. |
$< The name of the first prerequisite. If the target got its recipe from an implicit rule, this will be the first prerequisite added by the implicit rule | $< Dependent file with a later timestamp than the current target. Valid only in commands in inference rules. |
2. 内置宏的一些区别
NMAKE GNU MAKE ======= ========== !MESSAGE hello world $(info hello world) !ERROR message $(error message) !INCLUDE filename include filename $(MAKEDIR) $(CURDIR) $(@D) $(@D:\=) $(@F) $(@F) $(@B) $(basename $(@F)) $(@R) $(basename $@) $(var:find=replace) $(subst find,replace,$(var)) !IF "a" == "b" (also !=) ifeq (a, b) (also ifneq) ... ... !ELSE else ... ... !ENDIF endif !IFDE var (also !IFNDEF) ifdef var (also ifndef) ... ... !ELSE else ... ... !ENDIF endif
http://msdn.microsoft.com/en-us/library/7y32zxwh.aspx
!IF EXIST("filename") ifeq ($(wildcard filename), filename) (NOTE: Case-sensitive!) ... ... !ELSE else ... ... !ENDIF endif doit: define runit_cmd @echo <<runit.cmd >nul ...$(1), $(2), $(3),... ...%1,%2,%3,... endef << doit: @call runit.cmd x y z $(call runit_cmd, x, y, z)
3. 内嵌函数
1. 替换函数
$(subst, find, replace, $(var))
等价于
$(var :string1=string2)
特别注意":"前面不能有空格:
No spaces or tabs precede the colon; any after the colon are interpreted as literal.
Macro substitution is case sensitive and is literal;
string1 and string2
cannot invoke macros. Substitution does not modify the original definition. You can substitute text in any predefined macro except
$$@
.
2. Nmake 很遗憾没有其他的了。这点造成Nmake确实非常(不是一般的)难以在命令行使用,特别是你要生成多个目标文件时。
4. 文件处理
Windows:
Use
%s
to represent the complete filename. Use
%|
[
parts
]
F
(a vertical bar character follows the percent symbol)
Letter | Description |
---|---|
No letter | Complete name (same as %s) |
d | Drive |
p | Path |
f | File base name |
e | File extension |
For example, if the filename is c:\prog.exe:
-
%s will be c:\prog.exe
-
%|F will be c:\prog.exe
-
%|dF will be c
-
%|pF will be c:\
-
%|fF will be prog
-
%|eF will be exe
而在Linux下,
使用函数"dir"或"notdir" 函数就可以做到上述功能。比如
5. 内置的常用的宏:
Windows--Nmake
Microsoft product | Command macro | Defined as | Options macro |
---|---|---|---|
Macro Assembler | AS | ml | AFLAGS |
Basic Compiler | BC | bc | BFLAGS |
C Compiler | CC | cl | CFLAGS |
C++ Compiler | CPP | cl | CPPFLAGS |
C++ Compiler | CXX | cl | CXXFLAGS |
Resource Compiler | RC | rc | RFLAGS |
Linux-make
AR
AS
CC
CXX
CPP
ARFLAGS
ASFLAGS
CFLAGS
CXXFLAGS
CPPFLAGS
GFLAGS
get
program.
LDFLAGS
6. 特殊字符
Windows:
A number sign (#) after a definition specifies a comment. To specify a literal number sign in a macro, use a caret (^), as in ^#.
A dollar sign ($) specifies a macro invocation. To specify a literal $, use $$.
7. 例子:
一个简单的例子(多个目标) --- 目前除了使用间接方式外,没有找到更好的方法(在gmake中可以使用 $(foreach ))。
TMP_DIR=$(F_HOME)\tmp
BIN_DIR=$(F_HOME)\bin
T1=FskTimeTest FskStringTest
all: $(T1)
$(T1): $(BIN_DIR)\$$@.t
{$(F_HOME)\test\}.cpp{$(BIN_DIR)\}.t:
@echo $<
@echo $@
@copy $< $@
原文地址:
点击打开链接