Gnu make与Windows Nmake的异同点

来源:互联网 发布:三丰轮廓仪怎样编程 编辑:程序博客网 时间:2024/05/17 23:15
这几天在做一个项目,在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 <<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)  
LetterDescription

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 productCommand macroDefined asOptions 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)\$$@.t

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

原文地址:点击打开链接
0 0