NMake is a make utility provided by Microsoft and available in Visual Studio. It is a handy tool for creating automated builds. '''Simple Example''' ''"makefile"'' foo.exe:foo.cs csc foo.cs To execute the above makefile use the following command nmake foo.exe What the makefile says is that foo.exe depends on foo.cs and that if foo.cs has changed more recently than foo.exe execute the command "csc foo.cs" : [] Where is the name of a file to be generated or acted upon. is a file that depends on. [] means that optional additional dependencies can be listed on the line. is a literal tab character '''NOTE:''' using spaces will cause the command to fail to execute. is a command line that you would like to execute which usually creates the target from the dependencies. '''Another Example''' ''"makefile"'' TARGET = foo.exe SOURCES = \ foo.cs \ bar.cs all: $(TARGET) $(TARGET):$(SOURCES) csc /out:$@ $** This makefile does a little more. There is an '''all''' which is a psudotarget. A psudotarget represents a missing file and thus will always be out of date. Executing nmake without any parameters will cause nmake to open the file in the local directory called ''makefile'', find the first target defined in it (the '''all''' target in our example), and begin evaluating dependencies. Use the following to build the '''all''' target in the example makefile nmake or optionally nmake all There is a TARGET macro that evaluates to the string "foo.exe" and a SOURCES macro that evaluates to the string "foo.cs bar.cs" the "\" character indicates that the line is continued and must be the last character in the line. To dereference a macro it must be wrapped with $() where is the name of the macro to dereference. Preprocessing the makefile will result in the following substitutions all:foo.exe foo.exe:foo.cs bar.cs csc /out:foo.exe foo.cs bar.cs The '''$@''' macro evaluates to the target to be built on the left of the ''':''' and '''$**''' evaluates to the dependencies to the right of the ''':''' '''Traversing Directories''' ''"makefile"'' DIRS = \ dir1 \ dir2 \ dir3 all: $(DIRS) $(DIRS): pushd $@ & nmake & popd This example creates a macro called DIRS that evaluates to the string "dir1 dir2 dir3". Preprocessing the makefile will result in the following dir1: pushd dir1 & nmake & popd dir2: pushd dir2 & nmake & popd dir3: pushd dir3 & nmake & popd '''NOTE:''' that the targets were split onto separate lines for you. Something to keep in mind is that a command executes in its own shell thus the reason for '''&'''ing together the commands. Running them on separate lines like this: dir1: pushd dir1 nmake popd would not have the desired result because each command would run in its own shell environment and the change directory would not execute in the same shell as the nmake. '''Including Defaults''' ''"default.mk"'' BUILDROOT = C:\Build PROJECT = M''''''yProject O = $(BUILDROOT)\$(PROJECT)\bin RECURSE_DIR = \ pushd $@ & nmake & popd COMPILE_EXE = \ csc /out:$@ $(REFERENCES) $(SOURCES) ''"makefile"'' !include $(DEFAULT) DIRS = bam TARGET = $(O)\foo.exe SOURCES = \ foo.cs \ bar.cs REFERENCES = \ /r:$(O)\bam.dll all: $(DIRS) $(TARGET) $(DIRS): $(RECURSE_DIR) $(TARGET): $(SOURCES) $(COMPILE_EXE) In this example I have two files a ''default.mk'' and ''makefile''. As you can see in the ''makefile'', I am making reference to a macro DEFAULT that doesn't appear to be set. The assumption is that this macro is defined in the environment as follows: set DEFAULT=C:\Build\default.mk You can dereference environment variables with the same syntax as macros. If you define a macro that is also an environment variable the macro wins. As you can see the ''all'' target is going to process DIRS then the TARGET. Preprocessing this makefile will result in the following: all: bam C:\Build\M''''''yProject\bin\foo.exe bam: pushd bam & nmake & popd C:\Build\M''''''yProject\bin\foo.exe: foo.cs bar.cs csc /out:C:\Build\M''''''yProject\bin\foo.exe /r:C:\Build\M''''''yProject\bin\bam.dll foo.cs bar.cs After all the substitutions are made you can see that nmake will traverse the ''bam'' directory then build ''foo.exe'' to the appropriate target location. '''NOTE:''' macros can contain references to other macros but avoid creating circular macro references or nmake will complain. -- JeremyEmerson ---- CategorySoftwareTool