Gnu make与Windows Nmake的异同点

这几天在做一个项目,在Mac、Linux、Android下都是使用make系统进行编译管理的,但是到了Windows下很多正常的make“指令”不被Nmake识别,很是苦恼。看了一天的Nmake解释终于有点入门了,记录下一些两者的异同点,便于以后查阅。

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 targe
t

$**
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 <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 Archive-maintaining program; default ‘ ar’. 
AS Program for compiling assembly files; default ‘ as’. 
CC Program for compiling C programs; default ‘ cc’. 
CXX Program for compiling C++ programs; default ‘ g++’. 
CPP Program for running the C preprocessor, with results to standard output; default ‘ $(CC) -E’. 
ARFLAGS Flags to give the archive-maintaining program; default ‘ rv’. 
ASFLAGS Extra flags to give to the assembler (when explicitly invoked on a ‘ .s’ or ‘ .S’ file). 
CFLAGS Extra flags to give to the C compiler. 
CXXFLAGS Extra flags to give to the C++ compiler.  CPPFLAGS Extra flags to give to the C preprocessor and programs that use it (the C and Fortran compilers).  GFLAGS Extra flags to give to the SCCS  get program. 
LDFLAGS Extra flags to give to compilers when they are supposed to invoke the linker, ‘ ld’. 

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)\[email protected]

{$(F_HOME)\test\}.cpp{$(BIN_DIR)\}.t:
    @echo $<
    @echo $@
    @copy $< $@

原文地址: 点击打开链接

你可能感兴趣的:(贝海拾遗)