/* Jar Rules ------------------------------------------------------------- */ /* ** updated ** 08/22/2000: changed .PKGDIRS. to allow "." on RHS of :JAR: ** (ie. 'abc.jar :JAR: .') ** 03/26/2002: changed :JAR:, .JARSETUP, .VJARFILES to allow multiple ** targets with same basename (not same suffix) in the makefile. ** ie. abc.jar :JAR: classes JARTYPES=*.class ** abc.war :JAR: . JARTYPES=*.jar|*.html|*.xml ** 04/01/2003: :JAR: changed, added :Q to list of files/dirs to be archived ** to prevent the shell from expanding $blah as a shell variable ** in xyz$blah class filenames. */ JAR = jar JARFLAGS = cf /* ** These rules are from nmake newsletter no. 5 - May, 12 2000. ** http://www.stc.lucent.com/nmake/newsletters/issue005.html ** http://www.bell-labs.com/projects/nmake/newsletters/issue005.html ** ** The only one of these jar rules that is used in the local makefiles is ** :JAR:. The other rules are supporting the :JAR: action and should ** not be referenced directly by the user. ** ** Do not use :JAR: in the same makefile that builds the .class files. ** Due to the way nmake caches directory contents, and the java compiler ** outputs "unknown" class files, it is easier for everyone if :JAR: ** is used in a separate Makefile. To do both in the same directory we ** recommend the following: ** Makefile ":MAKE: java.mk - jar.mk" ** java.mk build your .class files. ** jar.mk build jar files. ** ** Usage: ** name.jar :JAR: [dir1 ... dirn] [file1 ... filen] [JARTYPES=] ** [JARROOT=] ** where ** name.jar ** The target jar file to be created. ** dir1 ... dirn ** A list of relative directories containing files to be archived ** in the jar file. All files in the VPATH matching ** will be archived. ** file1 ... filen ** A list of specific files to be archived in the jar file. In ** cases where you do not want all the files in a given directory ** you can specify which files you do want. These do not have ** to match the JARTYPES pattern. ** JARTYPES= ** The types of files to be archived in the jar file. When ** listing prerequisite directories all the files matching this ** pattern will be archived. Use shell pattern matching with a ** pipe ("|") separating each type (ie. *.class|*.jpg). Default ** is "*.class". Never use "+=" to set JARTYPES. ** JARROOT= ** The root of the package of class files for the jar archive. ** The default is the current directory, so any package directory ** would be a subdirectory under the directory holding the ** Makefile. For example, if the Makefile is in src/java/ ** but the classes are under src/java/pkgs//, then ** use JARROOT=$(VROOT)/src/java/pkgs or JARROOT=pkgs to get ** /file.class in the archive. If the Makefile is in ** src/java/pkgs then no setting is required. ** ** If JARTYPES or JARROOT is set as a standard variable in the Makefile ** they will be used for all jar files created in the Makefile. If set ** in the prerequisite list of a jar file they will be used only for that ** jar file. ** ** Here is an example jar Makefile: ** ** :ALL: stc.jar test.jar extern.jar ** ** stc.jar :JAR: \ ** com/lucent/stc/client \ ** com/lucent/stc/gui \ ** com/lucent/stc/gui/map \ ** com/lucent/stc/server \ ** com/lucent/switch \ ** com/lucent/stc/test/demo.class \ ** com/lucent/stc/test/common.class \ ** JARTYPES=*.class|*.png ** ** test.jar :JAR: com/lucent/stc/test ** ** extern.jar :JAR: \ ** $(VROOT)/prod/classes/mlc \ ** $(VROOT)/prod/classes/pop \ ** $(VROOT)/prod/classes/images/pop.png \ ** $(VROOT)/prod/classes/images/mlc.png \ ** JARROOT=$(VROOT)/prod/classes ** */ /* ------------------------------------------------------------------------- */ /* -- anything below this line is for the extremely bored or curious only -- */ /* ** Used by .VJARFILES. ** Usage: $(.PKGDIRS. []) ** ex: $(.PKGDIRS. com/lucent/stc *.class|*.jpg) ** ** Given a directory .PKGDIRS. will recursively list directories underneath ** that contain one or more .java or .class files. We assume the only files ** that would be in these directories are passed in as the second argument ** (ie. JARTYPES), plus .mk or Makefile. If a second argument is not ** specified then *.class and *.java are assumed. Anything else might be ** intrepreted as a directory. */ .PKGDIRS. :FUNCTION: local L PD D A1 A2 PD = A1 = $(%:O=1) A2 := $(%:O=2:Y??*.java|*.class?o) .SOURCE.pkgdirs : .CLEAR $(A1) L := $(*.SOURCE.pkgdirs:L:N!=*.tmpjar) PD += $(L:N=$(A2):D=$(A1):O=1:Y??$(A1:N=.)?o) for D $(L:N!=$(A2)|*.m[kosl]|Makefile:H<=U) PD += $(.PKGDIRS. $(A1)/$(D) $(A2)) end return $(PD:H<=U) /* ** Used by :JAR: ** List all the JARTYPES that exist down the vpath in each prerequisite ** directory. Directories are searched recursively, so JARTYPES in ** subdirectories will also be returned. */ .VJARFILES. : .MAKE .FUNCTIONAL .VIRTUAL .FORCE .REPEAT local jarfiles jardir D for D $(%) /* if the item is a file then add to the list of files */ if "$(D:T=F:A=.REGULAR)" jarfiles += $(D) else /* otherwise assume directory, ** recursively get all class files (or JARTYPES) */ for jardir $(.PKGDIRS. $(D) $(.$(<<:F=U:B:S).TYPES.):H<=U) .SOURCE.tmp : .CLEAR $(jardir) jarfiles += $(*.SOURCE.tmp:L<=$(.$(<<:F=U:B:S).TYPES.):D=$(jardir):B:S) end end end return $(jarfiles:H) /* ** NAME: :JAR: ** WHAT: Operator to make a .jar java archive file ** LHS: target .jar file ** RHS: directories or files to be archived ** ** Usage: my.jar :JAR: dir1 dir2 dir3/file.class ** ** the :JAR: operator actually makes the .jar file using the java jar command. ** See .JARSETUP below to understand the $$CUTHERE$$ stuff. */ ":JAR:" : .OPERATOR .MAKE .FORCE .REPEAT if ! "$(VPATH)" error 3 ERROR: :JAR: requires a proper VPATH. VPATH is either not set or the current directory is not inside first VPATH node. end if "$(~:N=JARROOT=*)" /* for the root we really need the relative directory ** inside the build node... ** - get JARROOT setting from prereq list. ** - strip "JARROOT=" to get the value. ** - convert to full path (will be as top vpath node) ** - strip top VPATH node from full path. ** we now have relative directory. */ .$(<:F=U:B:S).ROOT. := $(~:N=JARROOT=*:C/^JARROOT=//:P=A:C|^$(VPATH:C|:| |G:O=1)/||) else /* if none is specified then use VOFFSET */ .$(<:F=U:B:S).ROOT. := $(JARROOT:Y??$(VOFFSET)?o) end if "$(~:N=JARTYPES=*)" .$(<:F=U:B:S).TYPES. := $(~:N=JARTYPES=*:C/^JARTYPES=//) else /* default to pick up only .class files */ .$(<:F=U:B:S).TYPES. := $(JARTYPES:Y??*.class?o) end $(<) : $$(.VJARFILES. $(*:N!=JARTYPES=*|JARROOT=*)) .JARSETUP (JAR) (JARFLAGS) .SCAN_AGAIN cd $(<:B:S=.tmpjar) $(JAR) $(JARFLAGS) ../$(<) $(*:P=A:C|/$(.$(<:F=U:B:S).ROOT.)/|/$(.$(<:F=U:B:S).ROOT.)$$CUTHERE$$/ |:N!=*/$(.$(<:F=U:B:S).ROOT.)$$CUTHERE$$/:C|/.*||G:H=U:Q) /* ** remove the .tmpjar directory before making a new .jar file. we ** do this before rather than clean up after just so the area still ** exists in case someone wants to look at it for some reason after ** createing a .jar file. you know, to keep a record of what really ** is in the last .jar file. */ .JARCLEAN : .VIRTUAL .REPEAT .ALWAYS .FORCE .BEFORE silent test ! -d $(<<<:B:S=.tmpjar) || ignore /bin/rm -rf $(<<<:B:S=.tmpjar) /* ** this rule actually copies the files for the .jar archive to the ** .tmpjar directory where the archive is created. all the files ** need to be in a common area so they can be archived with jar. in effect ** this will "collapse" the VPATH for the desired files and put them all in ** the .tmpjar directory. a dependency assertion is set up with the ** destination .tmpjar/.../file as the target and the real file as ** found in the VPATH as the prerequisite. The action for this assertion ** makes the destination directory under .tmpjar if it does ** not already exist, and then it copies the file to the tmpjar area. ** ** $$ expands to the process id. The :C and :N edit operators change ** "//" to "/CUTHERE/ " (notice the space) ** to split the path at the offset and then ignores the offset piece. ** The same thing can be done using a straight :C edit but there are ** problems if the string appears more than once in the path, ** it strips to the last occurrence of the string, we want the first. */ .JARSETUP : .VIRTUAL .MAKE .REPEAT .ALWAYS .FORCE .BEFORE .JARCLEAN for file $(**) $(<<:B:S=.tmpjar)/$(file:P=A:C|/$(.$(<<:F=U:B:S).ROOT.)/|/$(.$(<<:F=U:B:S).ROOT.)$$CUTHERE$$/ |:N!=*/$(.$(<<:F=U:B:S).ROOT.)$$CUTHERE$$/) : $(file) .ACCEPT .IMMEDIATE .FORCE .VIRTUAL silent test ! -d $(<:D) && mkdir -p $(<:D) $(CP) $(*:Q) $(<:Q) end /* ** rescan current directory to udpate directory cache */ .SCAN_AGAIN : .MAKE .VIRTUAL .FORCE .REPEAT .AFTER . : -SCANNED