nmake FAQ

  1. Is nmake(1) really the greatest thing since sliced bread?

    Well, basing the entire build and packaging process on the AT&T nmake does put us way out on a lonely limb. But the benefits far outweigh the initial learning curve:

    • no need for autoconf, autheader, automake, libtool, or configure makefile generators and support tools
    • no need for make depend or make config; with nmake(1) and iffe(1) all dependencies are brought up to date each time nmake is executed
    • source and binary manifests are a byproduct of the build process
    • maintaining separate source and binary hierarchies requires no makefile change
    • :PACKAGE: assertions place a uniform view on top of a chaotic namespace
    • :MAKE: assertions dynamically determine recursive make order
    • new components (directories controlled by makefiles) can be added and will be built in the proper order

    See nmake for more details.

  2. Is there any online documentation?

    Yes.

  3. Isn't recursive make considered harmful?

    That is a good paper and we agree with the conclusions for the given thesis. Those conclusions, however, are based upon the limitations of /bin/make(1) and its clones. Substitute a different make implementation and the same conclusions can be dead wrong. With nmake(1) and the ast build hierarchy, new component source directories, controlled by an nmake makefile, can be dropped anywhere under $INSTALLROT/src, and the next package make or nmake will make everything, including the new component directories, in the proper order. This is an essential part of the ast build process, and its how we maintain sanity across packages, releases, and architectures. So our response is: Recursive nmake considered essential.

  4. Is there an easy way to build debug (cc -g) binaries?

    You can build -g binaries for debugging by adding --debug-symbols in Makeargs or by adding it to the nmake command line:

         nmake --debug-symbols
    
    Static libraries will be installed with -g appended to the base name, e.g., libast-g.a. In addition, -llib and +llib references will bind to the static lib-g version if possible. Note that --debug-symbols replaces all binaries for the current component with -g versions. You can build -g binaries in a subdirectory by:
         mkdir cc-g
         nmake cc- # or cc-g or install cc-g
    
    This is done for most of the library components on the master ast build machine so that debugging versions are always available.

  5. Are there any other nmake(1) debugging tips?

    To generate the preprocessed output of foo.c in foo.i:

         nmake -n -g debug.mk foo.i
    
    To generate the nested include structure of foo.c in foo.inc:
         nmake -n -g debug.mk foo.inc
    
    To see the binding for a specific file or variable use the interactive interface (make> is the interactive prompt, lines wrapped for readability):
         nmake -n query
         make> bind sys/types.h
         make> sys/types.h
         
         /usr/include/sys/types.h==sys/types.h : [2003-03-06+09:48:05.687128] \
         	.LCL.INCLUDE .STD.INCLUDE .SCAN.c dontcare global regular
         
         ()sys/types.h : [2003-03-06+09:48:05.687128] .LCL.INCLUDE .STD.INCLUDE \
         	.SCAN.c event=[2004-12-15+11:22:05.450622] compiled state
          prerequisites: sys/nodemask.h sys/cpumask.h sys/bsd_types.h sys/pthread.h \
         	sgidefs.h standards.h 
         
         make> print $(CC.HOSTTYPE)
         sgi.mips3
         make> q
    
    Any makefile statement can be entered and >>>>> is the secondary prompt for statements that span more than one line. Action blocks are terminated by a blank line. The example shows that sys/types.h binds to /usr/include/sys/types.h, the file time stamp is 2003-03-06+09:48:05.687128, the time that nmake noticed that the file time changed (the event time) was 2004-12-15+11:22:05.450622, and sys/types.h includes the files listed after prerequisites:.

  6. Why does nmake(1) provide its own cpp(1)?

    nmake generates -I options based on the source and headers visible in its view (i.e., visible in $VPATH), so it is important that the header bindings be exactly specified to the compiler. The #include search rules are notoriously non-portable; the nmake cpp allows them to be completely specified using the -I- option. Since gcc has the -I- (added in the late 80's), nmake does not override the gcc cpp by default. You can force the native preprocessor by adding --nativepp=1 on the nmake command line, or --nativepp=-1 to inhibit the warning.

  7. What is a mamfile?

    A mamfile contains the Make Abstract Machine equivalent of a makefile. Mamfiles are generated by nmake (we also have a version of gmake that generates MAM) and are used to bootstrap nmake on systems that don't have it using the standalone mamake(1) command. See A Make Abstract Machine for details.

  8. The probe(1) information is wrong for my compiler; how can I fix it?

    See probe --?override.


February 17, 2005