home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume14 / dmake / part14 < prev    next >
Text File  |  1990-07-26  |  40KB  |  1,134 lines

  1. Newsgroups: comp.sources.misc
  2. subject: v14i024: dmake version 3.5 part 14/21
  3. From: dvadura@watdragon.waterloo.edu (Dennis Vadura)
  4. Sender: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  5.  
  6. Posting-number: Volume 14, Issue 24
  7. Submitted-by: dvadura@watdragon.waterloo.edu (Dennis Vadura)
  8. Archive-name: dmake/part14
  9.  
  10. #!/bin/sh
  11. # this is part 14 of a multipart archive
  12. # do not concatenate these parts, unpack them in order with /bin/sh
  13. # file man/dmake.nc continued
  14. #
  15. CurArch=14
  16. if test ! -r s2_seq_.tmp
  17. then echo "Please unpack part 1 first!"
  18.      exit 1; fi
  19. ( read Scheck
  20.   if test "$Scheck" != $CurArch
  21.   then echo "Please unpack part $Scheck next!"
  22.        exit 1;
  23.   else exit 0; fi
  24. ) < s2_seq_.tmp || exit 1
  25. echo "x - Continuing file man/dmake.nc"
  26. sed 's/^X//' << 'SHAR_EOF' >> man/dmake.nc
  27. X     when that rule is bound to a target as the result of an
  28. X     inference, the target's set of attributes is augmented by
  29. X     the attributes from the above set that are specified in the
  30. X     bound %-rule.  Other attributes specified for %-meta rules
  31. X     are not inherited by the target.  The .SETDIR attribute is
  32. X     treated in a special way.  If the target already had a .SET-
  33. X     DIR attribute set and the bound %-rule also specified a
  34. X     .SETDIR attribute then the one originally specified with the
  35. X     target prevails.  During inference any .SETDIR attributes
  36. X     for the inferred prerequisite are honored.  The directories
  37. X     must exist for a %-meta rule to be selected as a possible
  38. X     inference path.  If the directories do not exist no error
  39. X     message is issued, instead the corresponding path in the
  40. X     inference graph is simply rejected.
  41. X
  42. X     dmake also supports the old format special target
  43. X     .<suffix>.<suffix> by identifying any rules of this form and
  44. X     mapping them to the appropriate %-rule.  So for example if
  45. X     an old makefile contains the construct:
  46. X
  47. X          .c.o :; cc -c $< -o $@
  48. X
  49. X     dmake maps this into the following %-rule:
  50. X
  51. X          %.o : %.c; cc -c $< -o $@
  52. X
  53. X     Furthermore, dmake understands several SYSV AUGMAKE special
  54. X     targets and maps them into corresponding %-meta rules.
  55. X     These transformation must be enabled by providing the -A
  56. X     flag on the command line or by setting the value of AUGMAKE
  57. X     to non NULL.  The construct
  58. X
  59. X          .suff :; recipe
  60. X
  61. X     gets mapped into:
  62. X
  63. X
  64. X
  65. X
  66. XVersion 3.50                    UW                             31
  67. X
  68. X
  69. X
  70. X
  71. XDMAKE(p)               Unsupported Software               DMAKE(p)
  72. X
  73. X
  74. X
  75. X          % : %.suff; recipe
  76. X
  77. X     and the construct
  78. X
  79. X          .c~.o :; recipe
  80. X
  81. X     gets mapped into:
  82. X
  83. X          %.o : s.%.c ; recipe
  84. X
  85. X     In general, a special target of the form .<str>~ is replaced
  86. X     by the %-rule construct s.%.<str>, thereby providing support
  87. X     for the syntax used by SYSV AUGMAKE for providing SCCS sup-
  88. X     port.  When enabled, these mappings allow to processing of
  89. X     existing SYSV makefiles without modifications.
  90. X
  91. X     dmake bases all of it's inferences on the inference graph
  92. X     constructed from the %-rules defined in the makefile.  It
  93. X     knows exactly which targets can be made from which prere-
  94. X     quisites by making queries on the inference graph.  For this
  95. X     reason .SUFFIXES is not needed and is completely ignored.
  96. X
  97. X     For a %-meta rule to be inferred as the rule whose recipe
  98. X     will be used to make a target, the target's name must match
  99. X     the %-target pattern, and any inferred %-prerequisite must
  100. X     already exist or have an explicit recipe so that the prere-
  101. X     quisite can be made.  Without transitive closure on the
  102. X     inference graph the above rule describes precisely when an
  103. X     inference match terminates the search.  If transitive clo-
  104. X     sure is enabled (the usual case), and a prerequisite does
  105. X     not exist or cannot be made, then dmake invokes the infer-
  106. X     ence algorithm recursively on the prerequisite to see if
  107. X     there is some way the prerequisite can be manufactured.  For
  108. X     if the prerequisite can be made then the current target can
  109. X     also be made using the current %-meta rule.  This means that
  110. X     there is no longer a need to give a rule for making a .o
  111. X     from a .y if you have already given a rule for making a .o
  112. X     from a .c and a .c from a .y.  In such cases dmake can infer
  113. X     how to make the .o from the .y via the intermediary .c and
  114. X     will remove the .c when the .o is made.  Transitive closure
  115. X     can be disabled by giving the -T switch on the command line.
  116. X
  117. X     A word of caution.  dmake bases its transitive closure on
  118. X     the %-meta rule targets.  When it performs transitive clo-
  119. X     sure it infers how to make a target from a prerequisite by
  120. X     performing a pattern match as if the potential prerequisite
  121. X     were a new target.  The set of rules:
  122. X
  123. X          %.o : %.c :; rule for making .o from .c
  124. X          %.c : %.y :; rule for making .c from .y
  125. X          % : RCS/%,v :; check out of RCS file
  126. X
  127. X
  128. X
  129. X
  130. XVersion 3.50                    UW                             32
  131. X
  132. X
  133. X
  134. X
  135. XDMAKE(p)               Unsupported Software               DMAKE(p)
  136. X
  137. X
  138. X
  139. X     will, by performing transitive closure, allow dmake to infer
  140. X     how to make a .o from a .y using a .c as an intermediate
  141. X     temporary file.  Additionally it will be able to infer how
  142. X     to make a .y from an RCS file, as long as that RCS file is
  143. X     in the RCS directory and has a name which ends in .y,v.  The
  144. X     transitivity computation is performed dynamically for each
  145. X     target that does not have a recipe.  This has potential to
  146. X     be very slow if the %-meta rules are not carefully speci-
  147. X     fied.  The .NOINFER attribute is used to mark a %-meta node
  148. X     as being a final target during inference.  Any node with
  149. X     this attribute set will not be used for subsequent infer-
  150. X     ences.  As an example the node RCS/%,v is marked as a final
  151. X     node since we know that if the RCS file does not exist there
  152. X     likely is no other way to make it.  Thus the standard
  153. X     startup makefile contains the entry:
  154. X          .NOINFER : RCS/%,v
  155. X     Thereby indicating that the RCS file is the end of the
  156. X     inference chain.
  157. X
  158. X     dmake tries to remove intermediate files resulting from
  159. X     transitive closure if the file is not marked as being PRE-
  160. X     CIOUS, or the -u flag was not given on the command line, and
  161. X     if the inferred intermediate did not previously exist.
  162. X     Intermediate targets that existed prior to being made are
  163. X     never removed.  This is in keeping with the philosophy that
  164. X     dmake should never remove things from the file system that
  165. X     it did not add.  If the special target .REMOVE is defined
  166. X     and has a recipe then dmake constructs a list of the inter-
  167. X     mediate files to be removed and makes them prerequisites of
  168. X     .REMOVE.  It then makes .REMOVE thereby removing the prere-
  169. X     quisites if the recipe of .REMOVE says to.  Typically
  170. X     .REMOVE is defined in the startup file as:
  171. X
  172. X          ".REMOVE :; $(RM) $<".
  173. X
  174. XMAKING TARGETS
  175. X     In order to update a target dmake must execute a recipe.
  176. X     When a recipe needs to be executed it is first expanded so
  177. X     that any macros in the recipe text are expanded, and it is
  178. X     then either executed directly or passed to a shell.  dmake
  179. X     supports two types of recipes.  The regular recipes and
  180. X     group recipes.
  181. X
  182. X     When a regular recipe is invoked dmake executes each line of
  183. X     the recipe separately using a new copy of a shell if a shell
  184. X     is required.  Thus effects of commands do not generally per-
  185. X     sist across recipe lines.  (e.g. cd requests in a recipe
  186. X     line do not carry over to the next recipe line) The decision
  187. X     on whether a shell is required to execute a command is based
  188. X     on the value of the macro SHELLMETAS.  If any character in
  189. X     the value of SHELLMETAS is found in the expanded recipe
  190. X     text-line then the command is executed using a shell,
  191. X
  192. X
  193. X
  194. XVersion 3.50                    UW                             33
  195. X
  196. X
  197. X
  198. X
  199. XDMAKE(p)               Unsupported Software               DMAKE(p)
  200. X
  201. X
  202. X
  203. X     otherwise the command is executed directly.  The shell that
  204. X     is used for execution is given by the value of the macro
  205. X     SHELL.  The flags that are passed to the shell are given by
  206. X     the value of SHELLFLAGS.  Thus dmake constructs the command
  207. X     line:
  208. X
  209. X          $(SHELL) $(SHELLFLAGS) $(expanded_recipe_command)
  210. X
  211. X     Normally dmake writes the command line that it is about to
  212. X     invoke to standard output.  If the .SILENT attribute is set
  213. X     for the target or for the recipe line (via @), then the
  214. X     recipe line is not echoed.
  215. X
  216. X     Group recipe processing is similar to that of regular
  217. X     recipes, except that a shell is always invoked.  The shell
  218. X     that is invoked is given by the value of the macro GROUP-
  219. X     SHELL, and its flags are taken from the value of the macro
  220. X     GROUPFLAGS.  If a target has the .PROLOG attribute set then
  221. X     dmake prepends to the shell script the recipe associated
  222. X     with the special target .GROUPPROLOG, and if the attribute
  223. X     .EPILOG is set as well, then the recipe associated with the
  224. X     special target .GROUPEPILOG is appended to the script file.
  225. X     This facility can be used to always prepend a common header
  226. X     and common trailer to group recipes.  Group recipes are
  227. X     echoed to standard output just like standard recipes, but
  228. X     are enclosed by lines beginning with [ and ].
  229. X
  230. XMAKING LIBRARIES
  231. X     Libraries are easy to maintain using dmake.  A library is a
  232. X     file containing a collection of object files.  Thus to make
  233. X     a library you simply specify it as a target with the
  234. X     .LIBRARY attribute set and specify its list of prere-
  235. X     quisites.  The prerequisites should be the object members
  236. X     that are to go into the library.  When dmake makes the
  237. X     library target it uses the .LIBRARY attribute to pass to the
  238. X     prerequisites the .LIBMEMBER attribute and the name of the
  239. X     library.  This enables the file binding mechanism to look
  240. X     for the member in the library if an appropriate object file
  241. X     cannot be found. A small example best illustrates this.
  242. X
  243. X          mylib.a .LIBRARY : mem1.o mem2.o mem3.o
  244. X               rules for making library...
  245. X               # remember to remove .o's when lib is made
  246. X
  247. X          # equivalent to:  '%.o : %.c ; ...'
  248. X          .c.o :; rules for making .o from .c say
  249. X
  250. X     dmake will use the .c.o rule for making the library members
  251. X     if appropriate .c files can be found using the search rules.
  252. X     NOTE:  this is not specific in any way to C programs, they
  253. X     are simply used as an example.
  254. X
  255. X
  256. X
  257. X
  258. XVersion 3.50                    UW                             34
  259. X
  260. X
  261. X
  262. X
  263. XDMAKE(p)               Unsupported Software               DMAKE(p)
  264. X
  265. X
  266. X
  267. X     dmake tries to handle the old library construct format in a
  268. X     sensible way.  The construct lib(member.o) is separated and
  269. X     the lib portion is declared as a library target.  The new
  270. X     target is defined with the .LIBRARY attribute set and the
  271. X     member.o portion of the construct is declared as a prere-
  272. X     quisite of the lib target.  If the construct lib(member.o)
  273. X     appears as a prerequisite of a target in the makefile, that
  274. X     target has the new name of the lib assigned as it's prere-
  275. X     quisite.  Thus the following example:
  276. X
  277. X          a.out : ml.a(a.o) ml.a(b.o); $(CC) -o $@  $<
  278. X
  279. X          .c.o :; $(CC) -c $(CFLAGS) -o $@  $<
  280. X          %.a:
  281. X               ar rv $@ $<
  282. X               ranlib $@
  283. X               rm -rf $<
  284. X
  285. X     constructs the following dependency graph.
  286. X
  287. X          a.out : ml.a; $(CC) -o $@  $<
  288. X          ml.a .LIBRARY : a.o b.o
  289. X
  290. X          %.o : %.c ; $(CC) -c $(CFLAGS) -o $@  $<
  291. X          %.a :
  292. X               ar rv $@ $<
  293. X               ranlib $@
  294. X               rm -rf $<
  295. X
  296. X     and making a.out then works as expected.
  297. X
  298. X     The same thing happens for any target of the form
  299. X     lib((entry)).  These targets have an additional feature in
  300. X     that the entry target has the .SYMBOL attribute set automat-
  301. X     ically.
  302. X
  303. X     NOTE:  If the notion of entry points is supported by the
  304. X     archive and by dmake (currently not the case) then dmake
  305. X     will search the archive for the entry point and return not
  306. X     only the modification time of the member which defines the
  307. X     entry but also the name of the member file.  This name will
  308. X     then replace entry and will be used for making the member
  309. X     file.  Once bound to an archive member the .SYMBOL attribute
  310. X     is removed from the target.  This feature is presently dis-
  311. X     abled as there is little standardization among archive for-
  312. X     mats, and we have yet to find a makefile utilizing this
  313. X     feature (possibly due to the fact that it is unimplemented
  314. X     in most versions of UNIX Make).
  315. X
  316. XMULTI PROCESSING
  317. X     If the architecture supports it then dmake is capable of
  318. X     making a target's prerequisites in parallel.  dmake will
  319. X
  320. X
  321. X
  322. XVersion 3.50                    UW                             35
  323. X
  324. X
  325. X
  326. X
  327. XDMAKE(p)               Unsupported Software               DMAKE(p)
  328. X
  329. X
  330. X
  331. X     make as much in parallel as it can and use a number of child
  332. X     processes up to the maximum specified by MAXPROCESS or by
  333. X     the value supplied to the -P command line flag.  A parallel
  334. X     make is enabled by setting the value of MAXPROCESS (either
  335. X     directly or via -P option) to a value which is > 1.  dmake
  336. X     guarantees that all dependencies as specified in the
  337. X     makefile are honored.  A target will not be made until all
  338. X     of its prerequisites have been made.  If a parallel make is
  339. X     being performed then the following restrictions on parallel-
  340. X     ism are enforced.
  341. X
  342. X          1.   Individual recipe lines in a non-group recipe are
  343. X               performed sequentially in the order in which they
  344. X               are specified within the makefile and in parallel
  345. X               with the recipes of other targets.
  346. X
  347. X          2.   If a target contains multiple recipe definitions
  348. X               (cf. :: rules) then these are performed sequen-
  349. X               tially in the order in which the :: rules are
  350. X               specified within the makefile and in parallel with
  351. X               the recipes of other targets.
  352. X
  353. X          3.   If a target rule contains the `!' modifier, then
  354. X               the recipe is performed sequentially for the list
  355. X               of outdated prerequisites and in parallel with the
  356. X               recipes of other targets.
  357. X
  358. X          4.   If a target has the .SEQUENTIAL attribute set then
  359. X               all of its prerequisites are made sequentially
  360. X               relative to one another (as if MAXPROCESS=1), but
  361. X               in parallel with other targets in the makefile.
  362. X
  363. X     Note:  If you specify a parallel make then the order of tar-
  364. X     get update and the order in which the associated recipes are
  365. X     invoked will not correspond to that displayed by the -n
  366. X     flag.
  367. X
  368. XCONDITIONALS
  369. X     dmake supports a makefile construct called a conditional.
  370. X     It allows the user to conditionally select portions of
  371. X     makefile text for input processing and to discard other por-
  372. X     tions.  This becomes useful for writing makefiles that are
  373. X     intended to function for more than one target host and
  374. X     environment.  The conditional expression is specified as
  375. X     follows:
  376. X
  377. X          .IF  expression
  378. X             ... if text ...
  379. X          .ELSE
  380. X             ... else text ...
  381. X          .END
  382. X
  383. X
  384. X
  385. X
  386. XVersion 3.50                    UW                             36
  387. X
  388. X
  389. X
  390. X
  391. XDMAKE(p)               Unsupported Software               DMAKE(p)
  392. X
  393. X
  394. X
  395. X     The .ELSE portion is optional, and the conditionals may be
  396. X     nested (ie.  the text may contain another conditional).
  397. X     .IF, .ELSE, and .END may appear anywhere in the makefile,
  398. X     but a single conditional expression may not span multiple
  399. X     makefiles.
  400. X
  401. X     expression can be one of the following three forms:
  402. X
  403. X          <text> | <text> == <text> | <text> != <text>
  404. X
  405. X     where text is either text or a macro expression.  In any
  406. X     case, before the comparison is made, the expression is
  407. X     expanded.  The text portions are then selected and compared.
  408. X     White space at the start and end of the text portion is dis-
  409. X     carded before the comparison.  This means that a macro that
  410. X     evaluates to nothing but white space is considered a NULL
  411. X     value for the purpose of the comparison.  In the first case
  412. X     the expression evaluates TRUE if the text is not NULL other-
  413. X     wise it evaluates FALSE.  The remaining two cases both
  414. X     evaluate the expression on the basis of a string comparison.
  415. X     If a macro expression needs to be equated to a NULL string
  416. X     then compare it to the value of the macro $(NULL).
  417. X
  418. XEXAMPLES
  419. X          # A simple example showing how to use make
  420. X          #
  421. X          prgm : a.o b.o
  422. X               cc a.o b.o -o prgm
  423. X          a.o : a.c g.h
  424. X               cc a.c -o $@
  425. X          b.o : b.c g.h
  426. X               cc b.c -o $@
  427. X
  428. X     In the previous example prgm is remade only if a.o and/or
  429. X     b.o is out of date with respect to prgm.  These dependencies
  430. X     can be stated more concisely by using the inference rules
  431. X     defined in the standard startup file.  The default rule for
  432. X     making .o's from .c's looks something like this:
  433. X
  434. X          %.o : %.c; cc -c $(CFLAGS) -o $@ $<
  435. X
  436. X     Since there exists a rule (defined in the startup file) for
  437. X     making .o's from .c's dmake will use that rule for manufac-
  438. X     turing a .o from a .c and we can specify our dependencies
  439. X     more concisely.
  440. X
  441. X          prgm : a.o b.o
  442. X               cc -o prgm $<
  443. X          a.o b.o : g.h
  444. X
  445. X     A more general way to say the above using the new macro
  446. X     expansions would be:
  447. X
  448. X
  449. X
  450. XVersion 3.50                    UW                             37
  451. X
  452. X
  453. X
  454. X
  455. XDMAKE(p)               Unsupported Software               DMAKE(p)
  456. X
  457. X
  458. X
  459. X          SRC = a b
  460. X          OBJ = {$(SRC)}.o
  461. X
  462. X          prgm : $(OBJ)
  463. X               cc -o $@ $<
  464. X
  465. X          $(OBJ) : g.h
  466. X
  467. X     If we want to keep the objects in a separate directory,
  468. X     called objdir, then we would write something like this.
  469. X
  470. X          SRC = a b
  471. X          OBJ = {$(SRC)}.o
  472. X
  473. X          prgm : $(OBJ)
  474. X               cc $< -o $@
  475. X
  476. X          $(OBJ) : g.h
  477. X          %.o : %.c
  478. X               $(CC) -c $(CFLAGS) -o $(@:f) $<
  479. X               mv $(@:f) objdir
  480. X
  481. X          .SOURCE.o : objdir       # tell make to look here for .o's
  482. X
  483. X     An example of building library members would go something
  484. X     like this: (NOTE:  The same rules as above will be used to
  485. X     produce .o's from .c's)
  486. X
  487. X          SRC  = a b
  488. X          LIB  = lib
  489. X          LIBm = { $(SRC) }.o
  490. X
  491. X          prgm: $(LIB)
  492. X               cc -o $@ $(LIB)
  493. X
  494. X          $(LIB) .LIBRARY : $(LIBm)
  495. X               ar rv $@ $<
  496. X               rm $<
  497. X
  498. X     Finally, suppose that each of the source files in the previ-
  499. X     ous example had the `:' character in their target name.
  500. X     Then we would write the above example as:
  501. X
  502. X          SRC  = f:a f:b
  503. X          LIB  = lib
  504. X          LIBm = "{ $(SRC) }.o"         # put quotes around each token
  505. X
  506. X          prgm: $(LIB)
  507. X               cc -o $@ $(LIB)
  508. X
  509. X          $(LIB) .LIBRARY : $(LIBm)
  510. X               ar rv $@ $<
  511. X
  512. X
  513. X
  514. XVersion 3.50                    UW                             38
  515. X
  516. X
  517. X
  518. X
  519. XDMAKE(p)               Unsupported Software               DMAKE(p)
  520. X
  521. X
  522. X
  523. X               rm $<
  524. X
  525. XCOMPATIBILITY
  526. X     There are two notable differences between dmake and the
  527. X     standard version of BSD UNIX 4.2/4.3 Make.
  528. X
  529. X          1. BSD UNIX 4.2/4.3 Make supports wild card filename
  530. X             expansion for prerequisite names.  Thus if a direc-
  531. X             tory contains a.h, b.h and c.h, then a line like
  532. X
  533. X                  target: *.h
  534. X
  535. X             will cause UNIX make to expand the *.h into "a.h b.h
  536. X             c.h".  dmake does not support this type of filename
  537. X             expansion.
  538. X
  539. X          2. Unlike UNIX make, touching a library member causes
  540. X             dmake to search the library for the member name and
  541. X             to update the library time stamp.  This is only
  542. X             implemented in the UNIX version.  MSDOS and other
  543. X             versions may not have librarians that keep file time
  544. X             stamps, as a result dmake touches the library file
  545. X             itself, and prints a warning.
  546. X
  547. X     dmake is not compatible with GNU Make.  In particular it
  548. X     does not understand GNU Make's macro expansions that query
  549. X     the file system.
  550. X
  551. X     dmake is fully compatible with SYSV AUGMAKE, and supports
  552. X     the following AUGMAKE features:
  553. X
  554. X          1. The word include appearing at the start of a line
  555. X             can be used instead of the ".INCLUDE :" construct
  556. X             understood by dmake.
  557. X
  558. X          2. The macro modifier expression $(macro:str=sub) is
  559. X             understood and is equivalent to the expression
  560. X             $(macro:s/str/sub), with the restriction that str
  561. X             must match the following regular expression:
  562. X
  563. X                  str[ |\t][ |\t]*
  564. X
  565. X             (ie. str only matches at the end of a token where
  566. X             str is a suffix and is terminated by a space, a tab,
  567. X             or end of line)
  568. X
  569. X          3. The macro % is defined to be $@ (ie. $% expands to
  570. X             the same value as $@).
  571. X
  572. X          4. The AUGMAKE notion of libraries is handled
  573. X             correctly.
  574. X
  575. X
  576. X
  577. X
  578. XVersion 3.50                    UW                             39
  579. X
  580. X
  581. X
  582. X
  583. XDMAKE(p)               Unsupported Software               DMAKE(p)
  584. X
  585. X
  586. X
  587. X          5. When defining special targets for the inference
  588. X             rules and the AUGMAKE special target mapping is
  589. X             enabled then the special target .X is equivalent to
  590. X             the %-rule "% : %.X".
  591. X
  592. XLIMITS
  593. X     In some environments the length of an argument string is
  594. X     restricted.  (e.g. MSDOS command line arguments cannot be
  595. X     longer than 128 bytes if you are using the standard
  596. X     command.com command interpreter as your shell, dmake text
  597. X     diversions may help in these situations.)
  598. X
  599. XPORTABILITY
  600. X     To write makefiles that can be moved from one environment to
  601. X     another requires some forethought.  In particular you must
  602. X     define as macros all those things that may be different in
  603. X     the new environment.  dmake has two facilities that help to
  604. X     support writing portable makefiles, recursive macros and
  605. X     conditional expressions.  The recursive macros, allow one to
  606. X     define environment configurations that allow different
  607. X     environments for similar types of operating systems.  For
  608. X     example the same make script can be used for SYSV and BSD
  609. X     but with different macro definitions.
  610. X
  611. X     To write a makefile that is portable between UNIX and MSDOS
  612. X     requires both features since in almost all cases you will
  613. X     need to define new recipes for making targets.  The recipes
  614. X     will probably be quite different since the capabilities of
  615. X     the tools on each machine are different.  Different macros
  616. X     will be needed to help handle the smaller differences in the
  617. X     two environments.
  618. X
  619. X     NOTE:  Unlike UNIX, MSDOS does maintain cd requests cross
  620. X     single recipe lines.  This is not portable, and your
  621. X     makefiles will not work the same way if you depend on it.
  622. X     Use the .IF ... .ELSE ... .END conditionals to supply dif-
  623. X     ferent make scripts as necessary.
  624. X
  625. XFILES
  626. X     Makefile, makefile, startup.mk (use dmake -V to tell you
  627. X     where the startup file is)
  628. X
  629. XSEE ALSO
  630. X     sh(1), csh(1), touch(1), f77(1), pc(1), cc(1)
  631. X     S.I. Feldman  Make - A Program for Maintaining Computer Pro-
  632. X     grams
  633. X
  634. XAUTHOR
  635. X     Dennis Vadura, CS Dept. University of Waterloo.
  636. X     dvadura@watdragon.uwaterloo.ca
  637. X     Many thanks to Carl Seger for his helpful suggestions, and
  638. X     to Trevor John Thompson for his many excellent ideas and
  639. X
  640. X
  641. X
  642. XVersion 3.50                    UW                             40
  643. X
  644. X
  645. X
  646. X
  647. XDMAKE(p)               Unsupported Software               DMAKE(p)
  648. X
  649. X
  650. X
  651. X     informative bug reports.
  652. X
  653. XBUGS
  654. X     Some system commands return non-zero status inappropriately.
  655. X     Use -i (`-' within the makefile) to overcome the difficulty.
  656. X
  657. X     Some systems do not have easily accessible time stamps for
  658. X     library members (MSDOS, AMIGA, etc) for these dmake uses the
  659. X     time stamp of the library instead and prints a warning the
  660. X     first time it does so.  This is almost always ok, except
  661. X     when multiple makefiles update a single library file.  In
  662. X     these instances it is possible to miss an update if one is
  663. X     not careful.
  664. X
  665. X
  666. X
  667. X
  668. X
  669. X
  670. X
  671. X
  672. X
  673. X
  674. X
  675. X
  676. X
  677. X
  678. X
  679. X
  680. X
  681. X
  682. X
  683. X
  684. X
  685. X
  686. X
  687. X
  688. X
  689. X
  690. X
  691. X
  692. X
  693. X
  694. X
  695. X
  696. X
  697. X
  698. X
  699. X
  700. X
  701. X
  702. X
  703. X
  704. X
  705. X
  706. XVersion 3.50                    UW                             41
  707. SHAR_EOF
  708. echo "File man/dmake.nc is complete"
  709. chmod 0640 man/dmake.nc || echo "restore of man/dmake.nc fails"
  710. echo "x - extracting makefile (Text)"
  711. sed 's/^X//' << 'SHAR_EOF' > makefile &&
  712. X# Default makefile for the various versions of dmake that we
  713. X# have available.  This is a bootstrap version and uses /bin/sh to
  714. X# execute a script which compiles dmake.
  715. X#
  716. X# Note the DOS commands actually invoke command.com to run the .bat file
  717. X# to make the script.
  718. X
  719. Xall:
  720. X    @echo "You must issue one of:"
  721. X    @echo "   make bsd43uw       - Generic BSD 4.3 at U of Waterloo"
  722. X    @echo "   make bsd43         - Generic BSD 4.3"
  723. X    @echo "   make sysvr3        - Generic SysV R3 UNIX"
  724. X    @echo "   make dynix         - Sequent DYNIX system"
  725. X    @echo "   make tccdos        - DOS with tcc 2.0"
  726. X    @echo "   make 386ix         - 386/ix (SysV R3) [NOTE: not tested]"
  727. X    @echo "   make mscdos        - DOS with MSC 4.0 [NOTE: not tested]"
  728. X
  729. Xbsd43uw        :; /bin/sh -x < unix/bsd43/uw/make.sh
  730. Xdynix              :; /bin/sh -x < unix/bsd43/dynix/make.sh
  731. Xsysvr3 bsd43 386ix :; /bin/sh -x < unix/$@/make.sh
  732. X
  733. X# DOS with some form of make and sh
  734. X# Note if you do not have a 'make and/or sh' program under MSDOS then
  735. X# typing 'make' in the dmake distribution directory will invoke the make.bat
  736. X# batch file which will issue the appropriate instructions.
  737. Xmscdos tccdos :; make.bat $@
  738. SHAR_EOF
  739. chmod 0440 makefile || echo "restore of makefile fails"
  740. echo "x - extracting makefile.mk (Text)"
  741. sed 's/^X//' << 'SHAR_EOF' > makefile.mk &&
  742. X#             //// Makefile for DMAKE. \\\\
  743. X# The target system is characterized by the following macros imported from
  744. X# the environment.
  745. X#
  746. X#    OS          - gives the class of operating system
  747. X#    OSRELEASE     - optionally gives the particular release of the OS above.
  748. X#    OSENVIRONMENT - optionally gives the environment under which the above
  749. X#            OS is in use.
  750. X#
  751. X# Valid values for the above macros are:
  752. X#
  753. X#    OS            - unix, msdos
  754. X#       OSRELEASE     - bsd43, sysvr3, 386ix
  755. X#              - tccdos, mscdos  (valid only of OS == msdos)
  756. X#       OSENVIRONMENT - uw {valid for unix, bsd43 configuration only.}
  757. X#            dynix (valid for unix, bsd43 configuration only.)
  758. X#
  759. X# See the config.mk file in the relevant subdirectories for additional
  760. X# comments describing when a setting is applicable.
  761. X
  762. X# First target in the makefile, do this so that targets declared in the
  763. X# included files are never marked as being the first *default* target.
  764. Xfirst : all ;
  765. X
  766. X# Pull in the configuration macros, from the environment.  OS is required,
  767. X# OSRELEASE, and OSENVIRONMENT are optional.
  768. X.IMPORT         : OS
  769. X.IMPORT .IGNORE : OSRELEASE OSENVIRONMENT TMPDIR
  770. X
  771. X# Define the source files
  772. XSRC =\
  773. X    infer.c make.c stat.c expand.c string.c hash.c dag.c dmake.c\
  774. X    path.c imacs.c sysintf.c parse.c getinp.c quit.c\
  775. X    basename.c dump.c macparse.c rulparse.c percent.c
  776. X
  777. X# Common Include files.
  778. XHDR = dmake.h extern.h struct.h vextern.h patchlvl.h version.h
  779. X
  780. X# Define the TARGET we are making, and where the OBJECT files go.
  781. XOBJDIR := objects
  782. XTARGET  = dmake$E
  783. XCFLAGS += -DHELP -I. -Icommon
  784. X
  785. X# Pull in the proper configuration file, based on the value of OS.
  786. X.INCLUDE : $(OS)/config.mk
  787. X
  788. X# Set the .SOURCE targets so that we look for things in the right place.
  789. X.SOURCE.c :^ .NULL
  790. X.SOURCE.h :^ .NULL
  791. X.SOURCE$O :^ $(OBJDIR)
  792. X.PRECIOUS : $(HDR)
  793. X
  794. X# Must come after the above INCLUDE so that it gets ALL objects.
  795. XOBJECTS    := {$(SRC:b)}$O
  796. X
  797. X# The main target, make sure the objects directory exists first.
  798. X# LDARGS is defined in config.mk file of each OS/OSRELEASE combination.
  799. Xall : $(TARGET);
  800. X$(TARGET) : $(OBJDIR)
  801. X$(TARGET) : $(OBJECTS); $(LD) $(LDARGS)
  802. X
  803. X# Other obvious targets...
  804. X$(OBJDIR):;- mkdir $@
  805. X
  806. X# Meta rule for making .o's from .c's (give our own so we can move object
  807. X# to objects directory in a portable, compiler independent way)
  808. X%$O: %.c
  809. X    $(CC) -c $(CFLAGS) $<
  810. X    mv $(@:f) $(OBJDIR)
  811. X
  812. X# remaining dependencies should be automatically generated
  813. Xsysintf$O  : $(OS)/sysintf.h
  814. X$(OBJECTS) : $(HDR)
  815. X.SOURCE.h  : common
  816. X
  817. X# Define the macros for printing the source, and pull in the 
  818. X# makefile portion.
  819. XPRINTEXCLUDE = $(OBJDIR) $(OBJDIR).dbg test RCS control man common
  820. X.INCLUDE : common/print.mk
  821. X
  822. Xclean:; $(RM) -rf dmake dbdmake objects*
  823. X
  824. X
  825. X#--------------------------------------------------------------------------
  826. X# Make the various archives for shipping the thing around.
  827. X#
  828. Xzoo   : dmake.zoo ;
  829. Xshar  : dmake.shar;
  830. Xtar   : dmake.tar;
  831. Xunzoo : dmake.zoo ; zoo xO// dmake.zoo
  832. Xdmake.zoo  .SILENT: src-list
  833. X[
  834. X    echo "" >> $<
  835. X    echo -n '$@ : $$(ALLSRC);@ zoo aI $$@ < ' >> $<
  836. X        echo -n '<' >> $<
  837. X        echo -n '+' >> $<
  838. X        echo -n '$$(ALLSRC:t"\n")\n' >> $<
  839. X        echo -n '+' >> $<
  840. X        echo '>' >> $<
  841. X    $(MAKECMD) -f $< $@
  842. X    $(RM) -f $<
  843. X]
  844. X
  845. Xdmake.shar .SILENT : src-list-shar
  846. X[
  847. X    echo '$@:$$(ALLSRC) ;xshar -vc -o$@ -l40 $$(ALLSRC)' >> $<
  848. X    $(MAKECMD) -f $< $@
  849. X    $(RM) -f $<
  850. X]
  851. X
  852. Xdmake.tar .SILENT : src-list
  853. X[
  854. X    echo '$@:$$(ALLSRC) ;tar -cvf $@ $$(ALLSRC)' >> $<
  855. X    $(MAKECMD) -f $< $@
  856. X    $(RM) -f $<
  857. X]
  858. X
  859. Xsrc-list .SILENT: clean
  860. X    echo 'ALLSRC = \' >$@
  861. X    find . -type f -print |\
  862. X    sed -e 's/RCS\///' -e 's/,v//' -e 's/$$/\\/' -e 's/^\.\// /'|\
  863. X    sort -u |\
  864. X    grep -v tst | grep -v $@ | grep -v LICENSE |\
  865. X    grep -v '\.zoo' | grep -v '\.tar'| grep -v '\.shar' >> $@
  866. X    echo ' LICENSE' >> $@
  867. X
  868. Xsrc-list-shar .SILENT: clean
  869. X    echo 'ALLSRC = \' >$@
  870. X    find . -print |\
  871. X    sed -e 's/RCS\///' -e 's/,v//' -e 's/$$/\\/' -e 's/^\.\// /'|\
  872. X    sort -ur |\
  873. X    grep -v tst | grep -v $@ | grep -v LICENSE | grep -v RCS |\
  874. X    grep -v '^\.\\$$' | grep -v '\.zoo' | grep -v '\.tar'|\
  875. X    grep -v '\.shar' >> $@
  876. X    echo ' LICENSE' >> $@
  877. X
  878. X
  879. X#--------------------------------------------------------------------------
  880. X# This section can be used to make the necessary script files so that dmake
  881. X# can be bootstrapped.
  882. X#
  883. X#    dmake scripts    -- makes all the script files at once.
  884. X#
  885. XSH = $(@:s,-,/,:s/scripts/${SCRIPTFILE})
  886. XMS = MAKESTARTUP=$(@:s,-,/,:s/scripts/startup.mk)
  887. X
  888. Xscripts: unix-scripts msdos-scripts
  889. X
  890. X# To add a new environment for UNIX, simply create the appropriate entry
  891. X# in the style below for the macro which contains the OS, OSRELEASE and
  892. X# OSENVIRONMENT flags.  Then add the entry as a recipe line for the target
  893. X# unix-scripts.
  894. X#
  895. Xunix-bsd43-scripts-flags       = OS=unix OSRELEASE=bsd43  OSENVIRONMENT=
  896. Xunix-sysvr3-scripts-flags      = OS=unix OSRELEASE=sysvr3 OSENVIRONMENT=
  897. Xunix-386ix-scripts-flags       = OS=unix OSRELEASE=386ix  OSENVIRONMENT=
  898. Xunix-bsd43-uw-scripts-flags    = OS=unix OSRELEASE=bsd43  OSENVIRONMENT=uw
  899. Xunix-bsd43-dynix-scripts-flags = OS=unix OSRELEASE=bsd43  OSENVIRONMENT=dynix
  900. X
  901. Xunix-scripts:
  902. X    $(MAKE) SCRIPTFILE=make.sh unix-bsd43-scripts
  903. X    $(MAKE) SCRIPTFILE=make.sh unix-bsd43-uw-scripts
  904. X    $(MAKE) SCRIPTFILE=make.sh unix-bsd43-dynix-scripts
  905. X    $(MAKE) SCRIPTFILE=make.sh unix-sysvr3-scripts
  906. X    $(MAKE) SCRIPTFILE=make.sh unix-386ix-scripts
  907. X
  908. Xunix-%-scripts:; $(MAKECMD) -nus $(MS) $($@-flags) >$(SH)
  909. X
  910. X# We make the standard dos scripts here, but we have to go and fix up the
  911. X# make.bat file since it contains names of temporary files for the response
  912. X# files required by the linker.  We need to also construct the response file
  913. X# contents.  These two functions are performed by the fix-msdos-%-scripts
  914. X# meta-target.
  915. X#
  916. X# To add a new DOS environment just do what is described for adding a new
  917. X# unix environment, and then make certain that the fix-msdos-%-scripts target
  918. X# performs the correct function for the new environment.
  919. Xmsdos-tccdos-scripts-flags = OS=msdos OSRELEASE=tccdos  OSENVIRONMENT=
  920. Xmsdos-mscdos-scripts-flags = OS=msdos OSRELEASE=mscdos  OSENVIRONMENT=
  921. X
  922. Xmsdos-scripts:
  923. X    $(MAKE) SCRIPTFILE=make.bat msdos-tccdos-scripts
  924. X    $(MAKE) SCRIPTFILE=make.bat msdos-mscdos-scripts
  925. X
  926. Xmsdos-%-scripts:
  927. X    $(MAKE) -nus $(MS) $($@-flags) >$(SH)
  928. X    $(MAKE) -s $(MAKEMACROS) $(MS) $($@-flags) fix-msdos-$*-scripts
  929. X
  930. XOBJRSP = $(SH:s,fix/,,:s,${SCRIPTFILE},${*:s/dos/obj/}.rsp,)
  931. XLIBRSP = $(SH:s,fix/,,:s,${SCRIPTFILE},${*:s/dos/lib/}.rsp,)
  932. XDOSOBJ = $(CSTARTUP) $(OBJDIR)/{$(OBJECTS)}
  933. Xfix-msdos-%-scripts:
  934. X    sed -e 's,/tmp/mkA..[0-9]*,$(SH:s,fix/,,:d)$(*:s/dos/obj).rsp,'\
  935. X        -e 's,/tmp/mkB..[0-9]*,$(SH:s,fix/,,:d)$(*:s/dos/lib).rsp,'\
  936. X        -e 's,/,\\,g' <$(SH:s,fix/,,) >tmp-out
  937. X    mv -f tmp-out $(SH:s,fix/,,)
  938. X    mv <+$(DOSOBJ:s,/,\\,:t"+\n")\n+> $(OBJRSP)
  939. X    mv <+$(LDLIBS:s,/,\\,:t"+\n")\n+> $(LIBRSP)
  940. SHAR_EOF
  941. chmod 0640 makefile.mk || echo "restore of makefile.mk fails"
  942. echo "x - extracting make.c (Text)"
  943. sed 's/^X//' << 'SHAR_EOF' > make.c &&
  944. X/* RCS      -- $Header: /u2/dvadura/src/generic/dmake/src/RCS/make.c,v 1.1 90/07/20 16:53:12 dvadura Exp $
  945. X-- SYNOPSIS -- perform the update of all outdated targets.
  946. X-- 
  947. X-- DESCRIPTION
  948. X--    This is where we traverse the make graph looking for targets that
  949. X--    are out of date, and we try to infer how to make them if we can.
  950. X--    The usual make macros are understood, as well as some new ones:
  951. X--
  952. X--        $$    - expands to $
  953. X--        $@      - full target name
  954. X--        $*      - target name with no suffix, same as $(@:db)
  955. X--              or, the value of % in % meta rule recipes
  956. X--        $?      - list of out of date prerequisites
  957. X--        $<      - all prerequisites associated with rules line
  958. X--        $&    - all prerequisites associated with target
  959. X--        $>      - library name for target (if any)
  960. X--        $^    - out of date prerequisites taken from value of $<
  961. X--        {{    - expands to {
  962. X--        }}    - expands to }
  963. X--        \#    - expands to #
  964. X-- 
  965. X-- AUTHOR
  966. X--      Dennis Vadura, dvadura@watdragon.uwaterloo.ca
  967. X--      CS DEPT, University of Waterloo, Waterloo, Ont., Canada
  968. X--
  969. X-- COPYRIGHT
  970. X--      Copyright (c) 1990 by Dennis Vadura.  All rights reserved.
  971. X-- 
  972. X--      This program is free software; you can redistribute it and/or
  973. X--      modify it under the terms of the GNU General Public License
  974. X--      (version 1), as published by the Free Software Foundation, and
  975. X--      found in the file 'LICENSE' included with this distribution.
  976. X-- 
  977. X--      This program is distributed in the hope that it will be useful,
  978. X--      but WITHOUT ANY WARRANTY; without even the implied warrant of
  979. X--      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  980. X--      GNU General Public License for more details.
  981. X-- 
  982. X--      You should have received a copy of the GNU General Public License
  983. X--      along with this program;  if not, write to the Free Software
  984. X--      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  985. X--
  986. X-- LOG
  987. X--     $Log:    make.c,v $
  988. X * Revision 1.1  90/07/20  16:53:12  dvadura
  989. X * Initial Revision of Version 3.5
  990. X * 
  991. X*/
  992. X
  993. X#include "extern.h"
  994. X#include "alloc.h"
  995. X#include "db.h"
  996. X
  997. Xstatic    int    _exec_commands ANSI((CELLPTR, HOWPTR));
  998. Xstatic    void    _drop_mac ANSI((HASHPTR));
  999. Xstatic    void    _print_cmnd ANSI((char*, int, int));
  1000. Xstatic    void    _set_recipe ANSI((char*, int));
  1001. Xstatic    void    _set_tmd ANSI(());
  1002. Xstatic    void    _append_line ANSI((char*, int, FILE*, char*, int));
  1003. Xstatic    void    _append_file ANSI((STRINGPTR, FILE*, char*, int));
  1004. Xstatic    void    _add_here ANSI((char*, FILE*, int));
  1005. X
  1006. X#define RP_GPPROLOG    0
  1007. X#define RP_RECIPE    1
  1008. X#define RP_GPEPILOG    2
  1009. X#define NUM_RECIPES    3
  1010. X
  1011. Xstatic STRINGPTR _recipes[ NUM_RECIPES ];
  1012. Xstatic CELLPTR     Root;        /* root cell for make graph */
  1013. X
  1014. X
  1015. X
  1016. Xint
  1017. XMake_targets()/*
  1018. X================
  1019. X   Actually go and make the targets on the target list */
  1020. X{
  1021. X   LINKPTR        lp;
  1022. X   int            done = 0;
  1023. X
  1024. X   DB_ENTER( "Make_targets" );
  1025. X
  1026. X   /* Make sure the graph gets blown up for .SETDIR targets.
  1027. X    * Only required for architectures that support parallel  
  1028. X    * makes. */
  1029. X   Explode_prq( Fringe_hd, NIL(CELL), FALSE );
  1030. X
  1031. X   _set_recipe( ".GROUPPROLOG", RP_GPPROLOG );
  1032. X   _set_recipe( ".GROUPEPILOG", RP_GPEPILOG );
  1033. X
  1034. X   while( !done ) {
  1035. X      done = F_MADE;
  1036. X      for( lp = Fringe_hd; lp != NIL(LINK); lp = lp->cl_next ) {
  1037. X     int rval = 0;
  1038. X
  1039. X     Root = lp->cl_prq;
  1040. X     if( (rval |= Make(Root, Root->CE_HOW, NIL(CELL))) == -1 )
  1041. X        DB_RETURN(1);
  1042. X     else
  1043. X        done &= (Root->ce_flag & F_MADE);
  1044. X
  1045. X     if( !rval && !done ) Wait_for_child( FALSE, -1 );
  1046. X      }
  1047. X   }
  1048. X
  1049. X   for( lp = Fringe_hd; lp != NIL(LINK); lp = lp->cl_next ) {
  1050. X      Root = lp->cl_prq;
  1051. X      if( !(Root->ce_attr & A_UPDATED) )
  1052. X     printf( "`%s' is up to date\n", Root->CE_NAME );
  1053. X   }
  1054. X
  1055. X   DB_RETURN( 0 );
  1056. X}
  1057. X
  1058. X
  1059. X
  1060. Xint
  1061. XMake( cp, how, setdirroot )/*
  1062. X=============================  Make a specified target */
  1063. XCELLPTR cp;
  1064. XHOWPTR  how;
  1065. XCELLPTR setdirroot;
  1066. X{
  1067. X   register LINKPTR dp;
  1068. X   register CELLPTR tcp;
  1069. X   char            *name, *lib;
  1070. X   HASHPTR        m_at    = NIL(HASH);
  1071. X   char             *all    = NIL(char);
  1072. X   char             *inf    = NIL(char);
  1073. X   char             *outall = NIL(char);
  1074. X   char             *imm    = NIL(char);
  1075. X   int              rval    = 0;
  1076. X   int            push    = 0;
  1077. X   time_t           otime   = (time_t) 1L;
  1078. X
  1079. X   DB_ENTER( "Make" );
  1080. X   DB_PRINT( "mem", ("%s:-> mem %ld", cp->CE_NAME, (long) coreleft()) );
  1081. X
  1082. X   /* NOTE:  The only time we are called with a NIL how pointer is for
  1083. X    *         cells that are to be statted only or for cells that are destined
  1084. X    *         to have a set of rules inferred for them. */
  1085. X
  1086. X   if( how == NIL(HOW) ) {
  1087. X      TALLOC( cp->CE_HOW, 1, HOW );
  1088. X      how = cp->CE_HOW;
  1089. X   }
  1090. X
  1091. X   /* Check to see if we have made the node already.  If so then don't do
  1092. X    * it again, except if the cell's ce_setdir field is set to something other
  1093. X    * than the value of setdirroot.  If they differ then, and we have made it
  1094. X    * already, then make it again and set the cell's stat bit to off so that
  1095. X    * we do it again. */
  1096. X
  1097. X   if( how->hw_flag & F_VISITED ) {
  1098. X      /* we may return if we made it already from the same setdir location,
  1099. X       * or if it is not a library member whose lib field is non NULL.  (if
  1100. X       * it is such a member then we have a line of the form:
  1101. X       *    lib1 lib2 .LIBRARY : member_list...
  1102. X       * and we have to make sure all members are up to date in both libs. */
  1103. X
  1104. X      if( cp->ce_setdir == setdirroot &&
  1105. X      !((cp->ce_attr & A_LIBRARYM) && (cp->ce_lib != NIL(char))) )
  1106. X     DB_RETURN( 0 );
  1107. X
  1108. X      /* We check to make sure that we are comming from a truly different
  1109. X       * directory, ie. ".SETDIR=joe : a.c b.c d.c" are all assumed to come
  1110. X       * from the same directory, even though setdirroot is different when
  1111. X       * making dependents of each of these targets. */
  1112. X
  1113. X      if( cp->ce_setdir != NIL(CELL) && setdirroot != NIL(CELL) &&
  1114. X          cp->ce_setdir->ce_dir == setdirroot->ce_dir )
  1115. X         DB_RETURN( 0 );
  1116. X
  1117. X      cp->ce_flag  &= ~(F_STAT|F_VISITED|F_MADE);
  1118. X      how->hw_flag &= ~(F_VISITED|F_MADE);
  1119. X   }
  1120. X
  1121. X   if( how->hw_next != NIL(HOW))
  1122. X      if( (rval = Make(cp, how->hw_next, setdirroot)) == -1 ||
  1123. X      !(how->hw_next->hw_flag & F_MADE) )
  1124. X     goto stop_making_it;
  1125. X
  1126. X   /* If we are supposed to change directories for this target then do so.
  1127. X    * If we do change dir, then modify the setdirroot variable to reflect
  1128. SHAR_EOF
  1129. echo "End of part 14"
  1130. echo "File make.c is continued in part 15"
  1131. echo "15" > s2_seq_.tmp
  1132. exit 0
  1133.  
  1134.