Nokia Networks Home

Nokia nmake Product Builder

Quick Links

Related Products

Release Notes -- Nokia nmake 3.0

1994
[Table of Contents] [Previous Section] [Next Section]

2. New Features

The following new features are included in this release.

2.1 Variables

  1. Auxiliary Values in Variables and New :VP and :VA Edit Operators
    Each variable in 3.0 may have both a primary value and an auxiliary (hidden) value. The new variable assignment operator &= is used to set the auxiliary value. The edit operator :VP gives the primary value of the token, and :VA gives the auxiliary value of the token. For example:
        X = dummy
        X &= dummy2
        
    at this point, $(X) expands to dummy dummy2. If X is assigned a new primary value:
        X = xyz
        
    then $(X) expands to xyz dummy2, $(X:VP) expands to xyz, and $(X:VA) expands to dummy2. If X is assigned a new auxiliary value:
        x &= abc
        
    then $(X) expands to xyz abc, $(X:VP) expands to xyz, and $(X:VA) expands to abc.
     
    Both the :VP and the :VA edit operators return variable values without expansion. For example,
        Y = $(X)
        Y &= efg
        
    The primary and auxiliary values of Y are $(X) and efg respectively. Please note that in this example X's auxiliary value becomes Y's primary value.
     
    Note: the auxiliary value is not saved in the state file (*.ms file).
  2. Scoped Variables
    If X=x is added to a prerequisite list, X is set to x while the action is being expanded. This will not affect other targets in the same makefile because X is already frozen. For example:
        x.o : .IMPLICIT CCFLAGS=-g
        
    Here, -g is only applied to generating x.o. This feature allows user to apply certain flags only on those specified files.
  3. New Base Rule Variables ancestor_list and ancestor_source
    Two base rule variables, ancestor_list and ancestor_source have been added to parameterize lib and include directories used with ancestor. nmake searches for libraries and headers in the directory names lib and include from current working directory up to the level specified in ancestor. One may redefine ancestor_list or ancestor_source to have nmake search files in other directory names.
     
    The default value for ancestor_source is null. The default value for ancestor_list is:
        ancestor_list = $(ancestor_source) .SOURCE.a lib .SOURCE.h include
        
    ancestor_list contains the .SOURCE.x search_dirname_for_.x pairs. .SOURCE.a lib .SOURCE.h include are the default pairs where nmake searches for libraries and headers when ancestor is not null.
     
    For example, if one wants nmake to find headers in the directory named hdrs and find libraries in the directory named LIB using the ancestor concept, one may redefine ancestor_list in the makefile to be:
        ancestor_list = .SOURCE.h hdrs .SOURCE.a LIB
        
    If one also wants nmake to search headers and libraries in the default directories (i.e. include and lib), one should use ancestor_source to define the .SOURCE.x search_dirname_for_.x pairs, since ancestor_list includes the include and lib directory names by default.
  4. New Base Rule Variable: cleanignore
    Files matched by the value of this variable will not be deleted by clean common action.
  5. New Base Rule Variable: force_shared
    If this variable is set to 1, it will cause the re-link of executables with shared libraries when linked shared libraries are out of date. If it is not set, the shared libraries time stamps are ignored.
  6. New Base Rule Variable: prefixinclude
    This variable is used to support C #include "..." compatibility. The default value of this variable is set to 1. If main.c includes a file as #include "prefix/file1.h" (where prefix is at least one level of a directory structure), and if file1.h includes another file as #include "file2.h". By default, nmake first looks in prefix directory for file2.h where the prefix directory is inherited from file1.h. If nmake cannot find file2.h in prefix directory, it searches for it in .SOURCE.h. If prefixinclude is not set, nmake relies exclusively on .SOURCE.h to search for including files; no directory structure is inherited.
  7. New Base Rule Variable: preserve
    When preserve is set to non-null (either 1 or a file match pattern), the install common action will rename the old install target to filename#inodenumber.
  8. New Base Rule Variable: instrument
    This variable supports software packages, such as purify, sentinel, or insight. When instrument is set to one of those packages (e.g., instrument=purify), nmake builds targets with the package. By default, nmake searches /usr/add-on, /usr/addon, and /usr/local directories for the software packages. If the packages are not installed in those directories, a full path name has to be specified (e.g., instrument=/tools/purify).
  9. New Base Rule Variable: arclean
    The generated files (e.g., *.o's) of an archive target can be specified by this variable. The value of this variable can be edit operator expression. The files specified by this variable will be removed after the archive target is made. For example, the Makefile is:
        arclean = N!=a.o|b.o
        lib.a :: a.c b.c c.c d.c
        
    In this example, all the *.o's except a.o and b.o will be removed.
  10. New Environment Variable COTEMP
    The COTEMP environment variable is generated and set to a different value for each shell command. COTEMP is a 10-character hash name, so names of the form:
        <prefix>.$COTEMP.<suffix>
        
    can be up to 14 characters or fewer to satisfy the system V file name length restriction.
     
    If COSHELL is set to ksh or sh, the value of COTEMP is
        <nmake-pid><job-pid>
        
    If COSHELL is set to coshell, the value of COTEMP is
        <job-host-inet-addr-base-32><job-pid-base-32>
        
    Since internet addresses must be unique between all hosts accessible to coshell, the COTEMP value will be unique for all jobs on all hosts in the local area network.
  11. New Environment Variable MAKECONVERT
    This variable is for compile time makefile conversion. For example, if you have a conversion program nmkgen to convert makefiles from other build tools, such as build, to makefiles, you can do the following:
        export MAKECONVERT='make.in "nmkgen $(>)"'
        
    where make.in is a makefile of build. nmake will produce .mo and .ms files from make.in by using nmkgen. make.in remains as a build makefile.
  12. New Environment Variables PACKAGE_id, PACKAGE_id_INCLUDE, PACKAGE_id_LIB
    See "New Assertion Operator :PACKAGE:" in Section 2.3.3.
  13. New Variables in the probe Configuration Files
    The following variables, CC.DYNAMIC, CC.LD, CC.MEMBERS, CC.NM, CC.NMEDIT, CC.NMFLAGS, CC.PIC, CC.SHARED, CC.SO, CC.STATIC and CC.SYMPREFIX have been added to the probe configuration files and can be accessed in makefiles.
     
    Some of the variables are to support different shared library suffixes, different options to link shared/static libraries, and different options to generate shared libraries among UNIX based operating systems. For example, on HP-UX, the shared library suffix is .sl, the option to link shared library is -ashared, the option to link static library is -aarchive, and the option to generate shared libraries is +z or +Z. Those flags are different on SunOS.
     
    Since CC.DYNAMIC, CC.STATIC, CC.SHARED and CC.PIC are compiler options, these variables can be used with CCFLAGS. For example, CCFLAGS = -O $(CC.PIC). Thus the makefile can be portable to different machines.
     
    CC.SYMPREFIX is for the symbol prefix in library symbol table. (See detail discussion of the variables in Appendix B of nmake User's Manual and Reference Guide).
     
    The following is the probe configuration file of /usr/ucb/cc for nmake on a SUN4, running SunOS4.1.1:
        CC.CC = /usr/ucb/cc
        CC.ALTPP.FLAGS = -Qpath $(CPP:D)
        CC.ALTPP.ENV =
        CC.DIALECT = DYNAMIC
        CC.DYNAMIC = -Bdynamic
        CC.LD = ld
        CC.MEMBERS = `$(NM) $(NMFLAGS) $(*:N=*.a) | \
                      $(SED) $(NMEDIT) -e "s/^/-u /"`
        CC.NM = nm
        CC.NMEDIT = -e '/[      ][TDB][         ]/!d' \
                    -e 's/.*[         ] [TDB][      ][      ]*//'
        CC.NMFLAGS =
        CC.PIC = -pic
        CC.READONLY = -R
        CC.SHARED =
        CC.SO = .so.1
        CC.STATIC = -Bstatic
        CC.STDINCLUDE = /usr/include
        CC.STDLIB = $(LD_LIBRARY_PATH:/:/ /G) /usr/lib /lib /usr/local/lib
        CC.SYMPREFIX = _
        CC.PREROOT =
        CC.UNIVERSE =
        

2.2 Common Actions

  1. New Common Action: list.symbols
    The list.symbols common action lists the sorted archive symbol names.

2.3 Assertion Operators

  1. New Assertion Operator :FUNCTION:
    The left-hand side (lhs will be used hereafter) is a functional variable, whose value is determined by the action of this assertion at execution time.
        t :FUNCTION: p
    	    action
        
    This is the same as
        t : p .SPECIAL .FUNCTION
    	    action
        
    However, :FUNCTION: is more readable and should be used. For example,
        view :FUNCTION: 
    	    return $(%:T=F)
        
    where $(%) is the arguments of the functional variable.
  2. New Assertion Operator :INSTALLPROTO:
    This assertion operator installs $(PROTO) output of right-hand side (rhs will be used hereafter) files into the lhs directory by the install common action. $(PROTO) is a conversion program that converts a prototyped C file to a file that is compatible with ANSI, K&R and C++ dialects of C. rhs files must have #pragma prototyped as the first line and must be valid ANSI C. In the base rules, PROTO is set to proto, which is included in the bin directory of the nmake software package.
  3. New Assertion Operator :PACKAGE: and New Environment Variables
    This assertion operator and the environment variables, PACKAGE_id, PACKAGE_id_INCLUDE, and PACKAGE_id_LIB, facilitate locating include files and libraries of a specified package id. The assertion operator and the environment variables add the directories to be searched for include files and libraries to .SOURCE.h and .SOURCE.a respectively, and eliminate the need for many .SOURCE.h and .SOURCE.a assertions. The package is searched in /usr/add-on, /usr/local, and /home by default when :PACKAGE: is used.
     
    For example, if one owns and builds a package called ast, which is installed in /usr/add-on, one can specify it in the makefile as:
        :PACKAGE: ast
        
    nmake will search /usr/add-on/ast/include for include files and /usr/add-on/ast/lib for libraries. One also can use other ast versions (say /home/my/ast), or a different version of include files or libraries by exporting in the environment:
        export PACKAGE_ast=/home/build/ast
        
    or:
        export PACKAGE_ast_INCLUDE=/home/build/ast/include
        export PACKAGE_ast_LIB=/home/build/ast/lib
        

     
    Note: the :PACKAGE: changes the variable INCLUDEDIR to be $(INSTALLROOT)/include/id by default. Thus, header files of ast package by default are installed in $(INSTALLROOT)/include/ast. A "-" as the first character of the rhs inhibits the INCLUDEDIR redefinition. If one uses a third-party software package, one should specify it as:
        :PACKAGE: - X11
        

     
    :PACKAGE: can be multiply defined, but the most recent :PACKAGE: assertion takes the highest precedence. A "+" in rhs will append the package(s) at the end of the package list, which means it would take the lowest precedence. For example,
        :PACKAGE: ast
        :PACKAGE: xast yast +
        
    nmake will look for headers and libraries first in the ast package, then in the xast and yast packages.
     
    When :PACKAGE: is used, nmake automatically links the package library to all the executable targets. For example, if the package is specified as
        :PACKAGE: xx
        
    all the exectable targets will be linked with a library, -lxx. If there is no libraries in the package named libxx, the following line has to be added in the makefile.
        -lxx : .DONTCARE
        
  4. More Functionality in the :LIBRARY: Assertion Operator
    The assertion operator :LIBRARY: is used to generate shared libraries and has been changed to support different shared library suffixes.
     
    The syntax of :LIBRARY: now is
        name [major.minor] :LIBRARY: source [required-libraries]
        
    major.minor would be the version number of shared libraries if the compiler of the machine supports them. required-libraries are the libraries that have to be linked in conjunction with the current target library when the library is in use. The required libraries can be specified as -llibrary_name format. nmake will generate a file called name containing the required libraries information, and install it in $(LIBDIR)/lib directory. For example, if one builds a library, libcs.a, which has to be used in conjunction with libnsl and libsocket, it can be specified as:
        cs 2.0 :LIBRARY: source.c -lnsl -lsocket
        
    In addition to generating the target library, libcs.a (and libcs.so.2.0 if the :ALL: is specified in the makefile, or if the all or install common action is specified on the command line), a file called cs will be generated, which contains the required libraries information:
        -lcs -lnsl -lsocket
        
    and install it by the install common action to $(LIBDIR)/lib directory. Each time -lcs is specified in makefiles, it automatically expanded to -lcs -lnsl -lsocket. Any required library not found on the current host machine is silently omitted.

2.4 Special Atoms

  1. New .LOCAL Special Atom
    The $(MAKE) command has to be executed on the local machine if coshell is used, so that jobs can be distributed among other idle machines in the LAN. To make sure of this, .LOCAL has to be one of the target's attributes. 2.2 makefiles used .ALWAYS as a work around, which should be changed to .LOCAL. For example:
        t : .LOCAL
    	    $(MAKE) $(=) $(-)
        
  2. New .FUNCTIONAL syntax
    The arguments of a functional variable are specified as $(%) in the action block and the return value is set by the return statement. For example:
        var : .MAKE .FUNCTIONAL .FORCE .REPEAT
    	    return $(%:T=F)
        
    The syntax for a functional variable with arguments has been changed from:
        $(var(arg ...))
        
    to:
        $(var arg ...)
        
  3. New .MAKEDONE Special Atom
    The new special atom .MAKEDONE has been added. The action of .MAKEDONE is executed after the execution of .DONE.
  4. Extended Functionality of .TERMINAL
    The .TERMINAL special atom is asserted to regular files in nmake 2.2; now it can also be asserted to directories that do not have subdirectories. This is used as an optimization in searching directories for binding files when there are many directories and many file names specified with directory prefix:
        .SOURCE.c : src1 src2
        src1 : .TERMINAL
        SRC = subdir/foo.c
        foo :: $(SRC)
        
    In this example, foo.c will not be searched in src1 directory because src1 does not have sub-directories. The benefit of asserting .TERMINAL to directoies will only be noticeable in large projects.
  5. .SCANNED Can Be Removed
    This special atom can be removed from files being scanned by an assertion such as,
        a.c : -SCANNED
        
    This will cause rescan the files at a later time.

2.5 Edit Operators

  1. Extended Functionality of Edit Operator :A
    This edit operator can return the selected target tokens with specific prerequisites or attributes. The syntax now is :A[!]=expression, where expression can now be either attributes or prerequisites:
        TARGETS = a b c
    
        a : x y
        b : y z
        c : x z
    
        .DONE:
    	    : $(TARGET:A=y)
        
    produces
        : a b
        
  2. New Edit Operator :F=V
    :F=V a string is converted to be the valid nmake variable name. For example, if STRING=S$T*U:
        $(STRING:F=V)
        
    would give S.T.U. The invalid variable name characters (i.e. "$" and "*") are converted to the valid character ".".
  3. Changed Functionality of Edit Operator :G
    :G now returns file names that can be generated to match the specified metarule pattern. For example:
        FILES = g.sch main.c
    
        %.c c_%.c %.h: %.sch
    	    cat  $(>) > $(>:B:S=.c)
    	    echo "#include '$(>:B).h'" > c_$(>:B:S=.c)
    	    cat $(>) >> c_$(>:B:S=.c)
    	    echo "#define $(>:B)_x 1" >$(>:B:S=.h)
    
        tst:
    	    : $(FILES:G=%.h)
    	    : $(FILES:G=%.o)
    	    : $(FILES:G!=%.h)
        
    The output is:
        + : g.h
        + : g.o c_g.o main.o
        + : main.c
        
    where g.h can be generated from g.sch, g.o, c_g.o and main.o are the files that can be generated from the files listed in $(FILES), and main.c is the file that cannot generated a .h file.
  4. Extended Functionality of Edit Operator :H
    :H<= gives a low-to-high numeric sort, and :H>= gives a high-to-low numeric sort. :H[<>][=]U gives a unique sorted list:
        V1 = 1 2 3
        V2 = 1 2 4
        V3 = $(V1) $(V2)
    
        t :
    	    : $(V3:H<=U)
        
    produces
        : 1 2 3 4
        
  5. New Edit Operator :K=[pfx]
    This operator acts like xargs(1) and splits long lines into separate token group, and prepends the optional pfx to each group of tokens:
        LIST = <a_long_list>
    
        t :
    	    $(LIST:K=echo)
        
    produces
        echo <the_first_block_of_the_list>
        echo <the_second_block_of_the_list>
    	    ...
        echo <the_last_block_of_the_list>
        
  6. Extended Functionality of Edit Operator :O
    :O gives the number count of tokens, and :O! gives the string length of each token:
        FILES= a bb c
        t :
    	    : $(FILES:O) 
    	    : $(FILES:O!)
        
    produces
        : 3
        : 1 2 1
        
  7. New Edit Operator :P=A
    This operator gives the absolute path name for files specified:
        FILE = a.c
        t:
    	    : $(FILE:P=A)
        
    if the file a.c is in the current directory /home/test, then the output will be:
        : /home/test/a.c
        
  8. New Edit Operator :P=H[=suffix]
    This operator generates 9-character hash file names (or up to 14 characters if suffix is used) for the given token:
        FILE = a.c
        t :
    	    : $(FILE:P=H=.hash)
        
    produces
        : ME707F6A4.hash
        
  9. Extended Functionality of Edit Operator :P=L
    :P=L* returns all views of a bound file, and :P=L! returns the first occurrence of a bound file from all the views. For example, assume the VPATH=/n1:/n2:/n3, and a.c exists in /n1 and /n2, and b.c exists in /n2 and /n3:
        SRC = a.c b.c
        t:
    	    : $(SRC:P=L*)
    	    : $(SRC:P=L!)	
        
    produces
        : /n1/a.c /n2/a.c /n2/b.c /n3/b.c
        : /n1.a.c /n2/b.c
        
  10. New Edit Operator :T=M
    :T=M generates the parentage chain of each active token:
        t : a.x
        a.x : a.z
        a.z : 
    	    : $(<:T=M)
        
    produces
        : t a.x a.z
        
  11. New Edit Operator :T=O
    :T=O[-][+][=data] complements :T=I[-] to give output:
        IFILES = in.list 	/* contains: main.c a.c b.c c.c */
        OFILE = out.list
        t :
    	    $(OFILE:T=O=$(IFILES:T=I))
        
  12. New Edit Operator :VP and :VA
    See "Auxiliary Values and Variables" in Section 2.1.1.

2.6 Scan Rules

  1. Non-Line-Oriented Scan Rule
    nmake 3.0 introduces the notation of @ for repeated patterns in scan rules:
        .SCAN.4gl : .SCAN
    	    I| include @ "%"|
    	    I| global @ "%" @ endglobal|
        
    this scan rule can scan source lines such as:
        include "a" "b" "c"
        global
    	    "a"
    	    "b"
    	    "c"
        endglobal
        
  2. New Function .INCLUDE. for Flags
    In nmake Scanrules.mk, the function .INCLUDE. is written for generating the flags for locating included files of specified languages. It takes the form of
        $(.INCLUDE. <lang> <flag>)
        
    For example, to generate flags for awk scripts:
        AWKFLAGS += $$(.INCLUDE. awk -I)
        

2.7 Enhancement in cpp

  1. New cpp Options
    -Aarg has been added for SVR4 assertions. -D-R is to preprocess for transition mode. -H is to print the included references in stderr. -I-C is to mark any following -Idir as C source. -M is to output the file dependencies in makefile dependency relationship format.
  2. New cpp Pragmas
    The following mentioned pragmas are generated as needed by probe. Here listed is for completeness.
     
    pp:cdir <dir_list> marks files in dir_list as C source. This is for preprocessing C++ source. For processing C++ source, nmake cpp will put extern C { ... } around C system headers and put extern C++ { ... } around C++ system headers. The new option -I-C and the new pragma pp:cdir are added for handling this.
     
    pp:elseif allows non-standard #else if, #else ifdef, and #else ifndef directives.
     
    pp:splicecat has been added to allow newline in macro definitions. This is to make cases such as
        #define a b \
        c
        
    be handled equivalently to the old (Reiser) cpp handling:
        #define a b /**/ c
        
    or ANSI cpp handling:
        #define a b ## c
        

     
    pp:stringspan allows newline line in a double quoted string.
     
    pp:transition is to set transition mode.
     
    pp:truncate [n] is to truncate macro names to n characters if specified, otherwise, to 8 characters. This is for compatibility with non-flexname compilation systems.
  3. New Directives
    #rename has been added to rename an old macro name to a new one.
        #define oldname aaa
        #rename oldname newname
        

2.8 Enhancement in probe

  1. CC Can Be Set with Particular Options
    Now user can add compiler option(s) to CC so that probe generates a separate configuration file just for the specified option(s). For example, CC = cc -Aa and CC = cc -g will reference different configuration files.
  2. Handling C++'s -l++
    nmake now expands -l++ to a set of libraries to match the expansion done in some C++ language processors. For example, using C++3.0, nmake expands -l++ properly to be -lg2++ -lGA -lGraph -l++ for some C++ language processors. The probe variable CC.REQUIRE.++ generated by probe contains the expanded value.
  3. New Options for <nmake_root>/lib/probe/probe
    probe now has three new options: -d, -D and -t. -d is for deleting the configuration files. -D is for debugging, which shows the steps that probe used in generating the configuration files for the language processor specified. -t is for testing, which generates a new configuration file on stdout without modifying the existing configuration file.
     
    The general usage is as the following:
        <nmake_root>/lib/probe/probe -[dDt] C [make|pp] path_of_compiler
        
    For example, one can delete the probe configuration files generated for language processors (e.g. compilers) by giving the command of:
        <nmake_root>/lib/probe/probe -d C make path_of_compiler
        
    or
        <nmake_root>/lib/probe/probe -d C pp path_of_compiler
        
    To delete the configuration files, one has to be the owner of the files or the owner of the language processor.
  4. New Option -d for <nmake_root>/lib/probe/C/make/probe
    The probe shell script (Note: different probe from the one mentioned in the previous section) can be run standalone in debug mode by using -d flag to examine the steps of probing information for nmake.
        <nmake_root>/lib/probe/C/make/probe -d path_of_compiler
        
  5. New Option -d for <nmake_root>/lib/probe/C/pp/probe
    The probe shell script (Note: different probe from the ones mentioned in the previous sections) can now be run standalone in debug mode by using -d flag to examine the steps of probing information for nmake cpp.
        <nmake_root>/lib/probe/C/pp/probe -d path_of_compiler
        

2.9 Miscellaneous

  1. Rules for Supporting the C++ Ptrepository Feature
    Rules have been added to the default base rules (Makerules.mk) to support the Template Instantiation feature in C++ release 3.0. The CC.DIALECT in the probe configuration file will contain PTREPOSITORY. The special atom .SOURCE.ptr can be used to specify directory name other than ptrepository. If .SOURCE.ptr is not specified in a makefile, nmake searches the ptrepository directory.
  2. Archive Format
    Users can specify ARSCAN (default to "ar"), ARSCANFLAGS (default to "tv"), and RANLIB (default to ranlib) in the project-wide rules for unusual archive formats.
     
    nmake now handles archive member file names with >= 15 characters, and also support AIX archive format.
  3. New Syntax for Library Link Flag
    The new library link flag +llibrary_name has been added for selective static linking. If this flag is specified, nmake will try to bind the archive library first.
        t :: main.c -la +lb
        
    where libb.a will be linked even if the shared version of the library (e.g., libb.so.*) exists in the same directory. Please recall that -la will cause to link the shared library first.
  4. User-defined Attributes Name
    User-defined attribute names are no longer required to start with dot (".").
  5. Searching for User-defined Operators
    User-defined operators can be specified in a separate file called op.mk where op is the operator's name, and the file can be placed in the <nmake_install_root>/lib/make directory. For example:
        t :MYOP: a b c
        
    The user-defined operator rule, :MYOP: can be specified in a file called MYOP.mk and the file can be placed in <nmake_install_root>/lib/make directory. In this way, user can provide additional rules to the base rules without modifying the base rule file (e.g., Makerules.mk).
  6. Enhancement in Documentation
    The "nmake User's Reference Guide" has been revised. The index has been augmented considerably. Scan rules have newly been documented as the Appendix G.

[Table of Contents] [Previous Section] [Next Section]

Last Update: Friday,12-Aug-2016 12:29:00 EDT