-
Notifications
You must be signed in to change notification settings - Fork 19
/
Copy pathmetaconfig.html
1869 lines (1732 loc) · 114 KB
/
metaconfig.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<HTML>
<HEAD>
<base href="http://linux.com.hk:80/penguin/" />
<TITLE>metaconfig - a Configure script generator
Linux Man Page</TITLE>
<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
<META name="GENERATOR" content="IBM WebSphere Studio">
<LINK rel="stylesheet" href="theme/Master.css" type="text/css">
<LINK rel="stylesheet" href="theme/layout.css" type="text/css">
<script type="text/javascript" src="js/common.js"></script>
<!-- google analytics -->
<script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
</script>
<script type="text/javascript">
_uacct = "UA-90513-1";
urchinTracker();
</script>
</HEAD>
<BODY>
<DIV class="container">
<TABLE class="container">
<TR class="container_up">
<TD class="container_up"><!-- topbar -->
<DIV class="topbar"><A href="index.jsp"> <IMG border="0"
src="images/logo.png" /> </A>
<!--topbar ad area-->
<DIV id="topbaradv">
<script type="text/javascript"><!--
google_ad_client = "pub-2404433452734258";
google_ad_width = 468;
google_ad_height = 60;
google_ad_format = "468x60_as";
google_ad_channel ="5458575456";
google_ad_type = "text_image";
//--></script>
<script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>
</DIV>
</DIV>
<!--- navbar --->
<CENTER class=navbar><TABLE width="100%" class="navtable">
<TR align="center" class="navtable">
<TD class="navtable"><a href=about.jsp class="navtable"> Company</a></TD>
<TD class="navtable"><a href=products.jsp class="navtable"> Products</a></TD>
<TD class="navtable"><a href=innovation.jsp class="navtable"> Innovation</a></TD>
<TD class="navtable"><a href=manpages.jsp class="navtable"> Man pages</a></TD>
<TD class="navtable"><a href=developer.jsp class="navtable"> Developer</a></TD>
<TD class="navtable"><a href=mirrors.jsp class="navtable"> Mirrors</a></TD>
<TD class="navtable"><a href=search.jsp class="navtable"> Search</a></TD>
</TR>
</TABLE></CENTER>
<DIV class="sidebar">
<!--sidebar --->
</DIV>
<DIV class="bodypart">
<STYLE>
DIV.bodypart {
margin-left:5px;
}
</STYLE>
<a href="http://linux.com.hk:80/penguin/man?action=print"><img src='images/printer.gif'></a>
<a href="http://linux.com.hk:80/penguin/man/1/m/" class="mannavlink">back to section</a>
<script type="text/javascript"><!--
google_ad_client = "pub-2404433452734258";
google_ad_width = 468;
google_ad_height = 15;
google_ad_format = "468x15_0ads_al";
google_ad_channel ="5458575456";
google_color_border = "336699";
google_color_bg = "FFFFFF";
google_color_link = "0000FF";
google_color_url = "008000";
google_color_text = "000000";
//--></script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</br>
<HTML><HEAD>
<link rel="stylesheet" type="text/css" href="theme/manpage.css">
<TITLE>
METACONFIG (1) manpage
</TITLE></HEAD><BODY>
<div class='man_header'><div class='man_header_left'>METACONFIG</div>
<div class='man_header_left'>1</div>
<div class='man_header_right'>Version 3.0 PL70</div>
</div>
<UL>
<LI> <span class="section"> NAME</span> <BR> <UL> metaconfig - a Configure script generator
</UL> </LI> <LI> <span class="section"> SYNOPSIS</span> <BR> <UL> <span class="B"> metaconfig</span> [ -<B>dhkmostvwGMV</B><R> ]
[ -</R><B>L </B><I><FONT color=#001050>dir</I></FONT><R> ]
</UL> </R></LI> <LI> <span class="section"> DESCRIPTION</span> <BR> <UL> <span class="I"> Metaconfig</span> is a program that generates Configure scripts. If you don't know what a
Configure script is, please skip to the <B>TUTORIAL</B><R> section of this
manual page. If you want a full (formal) description of the way to
use </R><I><FONT color=#001050>metaconfig</I></FONT><R> and its units, please look at the </R><B>REFERENCE</B><R>
section. The following is a quick introduction and reference for
knowledgeable users.
<span class="paragraph_brs"> <BR><BR> </span> </R>
<span class="B"> Metaconfig</span> operates from set of
<span class="I"> units</span> which define everything that metaconfig knows about portability.
Each unit is self-contained, and does not have to be registered anywhere
other than by inclusion in either the public U directory or your private
U directory.
If the dist package (of which metaconfig is a part) is installed in LIB,
then the public U directory is LIB/dist/mcon/U. On this machine, the
LIB directory is /usr/share/dist.
Your private U directory, if you have one,
is in the top level directory of your package.
Before you can run <I><FONT color=#001050>metaconfig</I></FONT><R> you must do a several things:
<DL><DT> <span class="ip"> <img src="images/bullet.gif"></span> <DD> Create a .package file in the package's top level directory by running
<I><FONT color=#001050>packinit</I></FONT><R>.
This program will ask you about your package and remember what you tell
it so that all the dist programs can be smart.
</DD> </R></DT></DL> <DL><DT> <span class="ip"> <img src="images/bullet.gif"></span> <DD> Consult the Glossary (in LIB/dist/mcon) and write your shell scripts and
C programs in terms of the symbols that metaconfig knows how to define.
You don't need to tell metaconfig which symbols you used, since metaconfig
will figure that out for you.
</DD> </DT></DL> <DL><DT> <span class="ip"> <img src="images/bullet.gif"></span> <DD> Generate any .SH scripts needed to write Makefiles or shell scripts that
will depend on values defined by Configure.
There is a program called <I><FONT color=#001050>makeSH</I></FONT><R> that will help you convert a plain
script into a script.SH template; some editing will still need to be performed
on the resulting .SH file to move the variable configuration part in the
top part of the script (see inline comments generated by </R><I><FONT color=#001050>makeSH</I></FONT><R> within
your .SH file).
</DD> </R></DT></DL> <DL><DT> <span class="ip"> <img src="images/bullet.gif"></span> <DD> Create a MANIFEST.new file in your top level directory that lists all the
files in your package. This file will remain private and will not be
part of the final distribution.
The filename should be the first field on each line.
After some whitespace you can add a short comment describing your file.
Only source files should be listed in there. The special file
<I><FONT color=#001050>patchlevel.h</I></FONT><R> (which is handled and maintained by the patching tools --
see <a href="man/1/pat.html">pat(1)</a> ) should be part of the MANIFEST.new file, but may be
silently ignored by some tools. As a rule of
thumb, only files maintained by RCS should be listed in there,
the </R><I><FONT color=#001050>patchlevel.h</I></FONT><R> file being one important exception.
</DD> </R></DT></DL> <DL><DT> <span class="ip"> <img src="images/bullet.gif"></span> <DD> Optionally, you may wish to create a MANIFEST file, which will be an
exported version of your MANIFEST.new. That file must be made part of
the release, i.e. listed in both your MANIFEST.new and MANIFEST itself.
One of the <I><FONT color=#001050>metaconfig</I></FONT><R> units knows about this file and will force
Configure to perform a release check, ensuring all the files listed
there are part of the distribution. The MANIFEST and MANIFEST.new
files should be distinct, not links.
</DD> </R></DT></DL> <DL><DT> <span class="ip"> <img src="images/bullet.gif"></span> <DD> Copy any .U files that you want to modify to your private U directory.
Any .U files in your private U directory will be used in preference to
the one in the public U directory.
For example, one way to force inclusion of any unit is to copy the End.U
file to your .U directory and add the name of the unit you want as
a dependency on the end of the ?MAKE: line.
Certain units can ONLY be forced in this way, namely those of the form
Warn_*.U and Chk_*.U.
You can also customize certain default Configure variables by copying
Myinit.U to your package's private U directory and setting the variables in
that unit.
<span class="paragraph_brs"> <BR><BR> </span>
Now you are ready to run <I><FONT color=#001050>metaconfig</I></FONT><R>. That will create a </R><I><FONT color=#001050>Configure</I></FONT><R>
file, and optionally a </R><I><FONT color=#001050>config_h.SH</I></FONT><R> file (if your sources make any use
of C symbols).
The generated files will automatically be added to your MANIFEST.new
if necessary. Do not forget to update your MANIFEST file though.
<span class="paragraph_brs"> <BR><BR> </span> </R>
In order to create new units, do the following:
</DD> </DT></DL> <DL><DT> <span class="ip"> <img src="images/bullet.gif"></span> <DD> Copy a similar unit to a new .U file.
The name you choose should be the name of a variable generated by the unit,
although this is only a convenience for you, not a requirement.
It should be 12 or less characters to prevent filename chopping.
Actually, it should probably be 10 or less so that those who want to use RCS
can have a .U,v on the end without chopping.
Metaconfig uses the case of the first letter to determine if any variable is
actually produced by this unit, so don't Capitalize your unit
name if it is supposed to produce a shell variable.
</DD> </DT></DL> <DL><DT> <span class="ip"> <img src="images/bullet.gif"></span> <DD> Edit the new .U file to do what you want.
The first ?MAKE: line indicates the dependencies; before the final list
colon all the variables this unit defines, and after the final colon
all the variables (or other units) on which this unit depends.
It is very important that these lists be accurate. If a dependency is
optional and a default value can be used, you should prefix the dependency
with a '+' sign. The corresponding unit will not be loaded to compute the
symbol, unless really required by another unit.
</DD> </DT></DL> <DL><DT> <span class="ip"> <img src="images/bullet.gif"></span> <DD> To the extent possible, parameterize your unit based on shell
variable defined on ?INIT: lines.
This will move the variable definitions up to the Init.U unit,
where they can be overridden by definitions in Myinit.U, which is
included after Init.U.
</DD> </DT></DL> <DL><DT> <span class="ip"> <img src="images/bullet.gif"></span> <DD> Add the definition of any C symbols desired as ?H: lines.
A line beginning with ?H:?%<: in the .U file will be added to the eventual
config.h file if and only if metaconfig decides that this unit is needed.
The %< stands for the unit's name, which happens to be the name of
the file too (without .U) if you followed the convention.
Always put a comment on each ?H: line in case one of the variable
substitutions earlier on the line starts a comment without finishing it.
Any shell variable starting with d_ may do this, so beware.
If you ommit the ?%<:, then metaconfig will try to intuit the symbol whose
definition is needed prior any inclusion in config.h.
</DD> </DT></DL> <DL><DT> <span class="ip"> <img src="images/bullet.gif"></span> <DD> Add glossary definitions as ?S: lines for shell variables and ?C:
lines for C preprocessor variables.
See a current unit for examples.
It is VERY important to start each entry with a left justified symbol
name, and end each entry with a ?C:. or ?S:. line. The algorithm
that translates C preprocessor symbol entries for the Glossary into
comments for config.h depends on this.
</DD> </DT></DL> <DL><DT> <span class="ip"> <img src="images/bullet.gif"></span> <DD> Make sure the order of all your ? lines is right. The correct order is:
<BR><BR> <!-- --> </DD> </DT></DL> <div class='RS'> <!-- +10--> <DL><DT> <!-- 15--> ?RCS: and ?X:
<DD> basically just comments
</DD> </DT></DL> <DL><DT> <!-- --> ?MAKE:
<DD> metaconfig dependencies
</DD> </DT></DL> <DL><DT> <!-- --> ?Y:
<DD> unit layout directive
</DD> </DT></DL> <DL><DT> <!-- --> ?S:
<DD> glossary shell definitions
</DD> </DT></DL> <DL><DT> <!-- --> ?C:
<DD> glossary C definitions
</DD> </DT></DL> <DL><DT> <!-- --> ?H:
<DD> config.h definitions
</DD> </DT></DL> <DL><DT> <!-- --> ?M:
<DD> confmagic.h definitions
</DD> </DT></DL> <DL><DT> <!-- --> ?W:
<DD> wanted symbols
</DD> </DT></DL> <DL><DT> <!-- --> ?V:
<DD> visible symbols
</DD> </DT></DL> <DL><DT> <!-- --> ?F:
<DD> files created by this unit
</DD> </DT></DL> <DL><DT> <!-- --> ?T:
<DD> temporary shell symbols used
</DD> </DT></DL> <DL><DT> <!-- --> ?D:
<DD> optional dependencies default value
</DD> </DT></DL> <DL><DT> <!-- --> ?O:
<DD> used to mark obsolete units
</DD> </DT></DL> <DL><DT> <!-- --> ?LINT:
<DD> metalint hints
</DD> </DT></DL> <DL><DT> <!-- --> ?INIT:
<DD> shell symbols initializations
</DD> </DT></DL> </div> <!-- --> <span class="paragraph_brs"> <BR><BR> </span>
Here is an example to show the ordering of the lines and the various
formats allowed:
?RCS: $RCS-Id$
?RCS: Copyright information
?RCS: $RCS-Log$
?X:
?X: A contrived example
?X:
?MAKE:d_one two: three +four Five
?MAKE: -pick add $@ %<
?Y:DEFAULT
?S:d_one:
?S: First shell symbol, conditionally defines ONE.
?S:.
?S:two:
?S: Second shell symbol, value for TWO.
?S:.
?C:ONE:
?C: First C symbol.
?C:.
?C:TWO:
?C: Second C symbol.
?C:.
?H:#$d_one ONE /**/
?H:#define TWO "$two"
?H:#$d_one ONE_TWO "$two"
?H:.
?M:flip: HAS_FLIP
?M:#ifndef HAS_FLIP
?M:#define flip(x) flop(x)
?M:#endif
?M:.
?W:%<:one_two
?V:p_one p_two:p_three
?F:file ./ftest !tmp
?T:tmp var
?D:two='undef'
?LINT:change three
?INIT:two_init='2'
: shell code implementing the unit follows
p_one='one'
p_two='two'
p_three=""
Let me state it one more time: the above unit definition is a <I><FONT color=#001050>fake</I></FONT><R>
one to only show the different possibilities. Such a unit would serve
little purpose anyway... Some more advanced features are not described
here. Please refer to the </R><B>REFERENCE</B><R> section for more complete
information.
</R> <DL><DT> <span class="ip"> <img src="images/bullet.gif"></span> <DD> Put the unit into the public or private U directory as appropriate.
</DD> </DT></DL> <DL><DT> <span class="ip"> <img src="images/bullet.gif"></span> <DD> Rerun <I><FONT color=#001050>metaconfig</I></FONT><R>.
</DD> </R></DT></DL> <DL><DT> <span class="ip"> <img src="images/bullet.gif"></span> <DD> Send your unit to [email protected] (Raphael Manfredi) for inclusion
in the master copy, if you think it's of general interest.
<span class="paragraph_brs"> <BR><BR> </span>
In order to add a new program to be located:
</DD> </DT></DL> <DL><DT> <span class="ip"> <img src="images/bullet.gif"></span> <DD> Edit Loc.U, and add the name of the program both to the ?MAKE: line
(between the two colons) and to either loclist or trylist (depending
on whether the program is mandatory or not).
</DD> </DT></DL> <DL><DT> <span class="ip"> <img src="images/bullet.gif"></span> <DD> Rerun metaconfig.
</DD> </DT></DL> <DL><DT> <span class="ip"> <img src="images/bullet.gif"></span> <DD> Send your unit to me for inclusion in the master copy, if you think it's
of general interest.
<span class="paragraph_brs"> <BR><BR> </span>
Notes for writing .U files:
</DD> </DT></DL> <DL><DT> <span class="ip"> *</span> <DD> Always use "rm -f" because there are systems where rm is interactive by
default.
</DD> </DT></DL> <DL><DT> <span class="ip"> *</span> <DD> Do not use "set -- ..." because '--' does not work with every shell. Use
"set x ...; shift".
</DD> </DT></DL> <DL><DT> <span class="ip"> *</span> <DD> Always use echo " " (with a space) because of Eunice systems.
</DD> </DT></DL> <DL><DT> <span class="ip"> *</span> <DD> Use only programs that came with V7, so that you know everyone has them.
</DD> </DT></DL> <DL><DT> <span class="ip"> *</span> <DD> Use $contains when you want to grep conditionally, since not all
greps return a reasonable status.
Be sure to redirect the output to /dev/null, by using '>/dev/null 2>&1'.
</DD> </DT></DL> <DL><DT> <span class="ip"> *</span> <DD> Use "if test" rather than "if [...]" since not every sh knows the
latter construct.
</DD> </DT></DL> <DL><DT> <span class="ip"> *</span> <DD> Use the myread script for inputs so that they can do shell escapes
and default evaluation. The general form is
case "$grimble" in
'') dflt=452;;
*) dflt="$grimble";;
esac
rp='How many grimbles do you have?'
. ./myread
grimble="$ans"
</DD> </DT></DL> <DL><DT> <span class="ip"> *</span> <DD> Use the getfile script when asking for a file pathname in order to
have optional ~name expansion and sanity checks. See the Getfile.U
unit for a full decription.
</DD> </DT></DL> <DL><DT> <span class="ip"> *</span> <DD> Always put a
$startsh
at the top of every generated script that is going to be launched
or sourced by <I><FONT color=#001050>Configure</I></FONT><R>.
</DD> </R></DT></DL> <DL><DT> <span class="ip"> *</span> <DD> Never assume common UNIX-isms like the fact that an object file ends
with a <I><FONT color=#001050>.o</I></FONT><R> and that a library name ends with </R><I><FONT color=#001050>.a</I></FONT><R>.
Use the </R><I><FONT color=#001050>$_o</I></FONT><R> and </R><I><FONT color=#001050>$_a</I></FONT><R> variables instead (see Unix.U).
</DD> </R></DT></DL> <DL><DT> <span class="ip"> *</span> <DD> When doing a compile-link-execute test, always write it like this:
$cc $ccflags $ldflags try.c -o try $libs
because some systems require that linking flags be specified before
the compiled target (with the exception of trailing linking libraries).
</DD> </DT></DL> <DL><DT> <span class="ip"> *</span> <DD> Issue important messages on file descriptor #4, by using '>&4' to redirect
output. Only those messages will appear when the <B>-s</B><R> switch is
given to </R><I><FONT color=#001050>Configure</I></FONT><R> on the command line (silent mode).
</DD> </R></DT></DL> <DL><DT> <span class="ip"> *</span> <DD> Always try to determine whether a feature is present in the most
specific way--don't say "if bsd" when you can grep libc. There
are many hybrid systems out there, and each feature should stand
or fall by itself.
</DD> </DT></DL> <DL><DT> <span class="ip"> *</span> <DD> Always try to determine whether a feature is present in the most
general way, so that other packages can use your unit.
</DD> </DT></DL> <DL><DT> <span class="ip"> *</span> <DD> When in doubt, set a default and ask. Don't assume anything.
</DD> </DT></DL> <DL><DT> <span class="ip"> *</span> <DD> If you think the user is wrong, allow for the fact that he may be right.
For instance, he could be running Configure on a different system than
he is going to use the final product on.
<span class="paragraph_brs"> <BR><BR> </span>
Metaconfig reserves the following names in your directory, and if you use such
a name it may get clobbered or have other unforeseen effects:
Configure
Wanted
Obsolete
configure
config_h.SH
confmagic.h
U/*
MANIFEST.new
Additionally, Configure may clobber these names in the directory it is run in:
UU/*
config.sh
config.h
</DD> </DT></DL>
</UL> </LI> <LI> <span class="section"> OPTIONS</span> <BR> <UL> The following options are recognized by <I><FONT color=#001050>metaconfig</I></FONT><R>:
<DL><DT> <!-- 15--> <span class="B"> -d</span> <DD> Turn on debug mode. Not really useful unless you are debugging <I><FONT color=#001050>metaconfig</I></FONT><R>
itself.
</DD> </R></DT></DL> <DL><DT> <!-- --> <span class="B"> -h</span> <DD> Print help message and exit.
</DD> </DT></DL> <DL><DT> <!-- --> <span class="B"> -k</span> <DD> Keep temporary directory, so that you may examine the working files used
by <I><FONT color=#001050>metaconfig</I></FONT><R> to build your </R><I><FONT color=#001050>Configure</I></FONT><R> script. Useful only when
debugging the units.
</DD> </R></DT></DL> <DL><DT> <!-- --> <span class="B"> -m</span> <DD> Assume lots of memory and swap space. This will speed up symbol lookup in
source files by a significant amount of time, at the expense of memory
consumption...
</DD> </DT></DL> <DL><DT> <!-- --> <span class="B"> -o</span> <DD> Map obsolete symbols on new ones. Use this switch if you still have some
obsolete symbols in your source code and do not want (or cannot) remove
them for now. The obsolete symbols are otherwise ignored, although that
will give you a warning from <I><FONT color=#001050>metaconfig</I></FONT><R>.
</DD> </R></DT></DL> <DL><DT> <!-- --> <span class="B"> -s</span> <DD> Turn silent mode on.
</DD> </DT></DL> <DL><DT> <!-- --> <span class="B"> -t</span> <DD> Trace symbols as they are found.
</DD> </DT></DL> <DL><DT> <!-- --> <span class="B"> -v</span> <DD> Turn verbose mode on.
</DD> </DT></DL> <DL><DT> <!-- --> <span class="B"> -w</span> <DD> Assume Wanted file is up-to-date. This will skip the time and memory
consuming phase of source code scanning, looking for known symbols.
Use it only when you know your source file have not changed with respect
to the pool of <I><FONT color=#001050>metaconfig</I></FONT><R> symbols used.
</DD> </R></DT></DL> <DL><DT> <!-- --> <span class="B"> -G</span> <DD> Also provide a GNU <I><FONT color=#001050>configure</I></FONT><R>-like front end to the generated
<span class="I"> Configure</span> </R>script, to be included in the distribution as well. This is only
a wrapper around the
<span class="I"> Configure</span> script naturally, but it lets people familiar with the GNU tool to
not be lost when facing a new distribution.
</DD> </DT></DL> <DL><DT> <!-- --> <B>-L</B><I><FONT color=#001050> dir</I></FONT><R>
<DD> Override default library location. Normally only useful for metaconfig
maintainers to locally use the units being developped instead of the
publicly available ones. The <I><FONT color=#001050>dir</I></FONT><R> specified is the one containing the
units </R><I><FONT color=#001050>U</I></FONT><R> directory.
</DD> </R></DT></DL> </R><DL><DT> <!-- --> <span class="B"> -M</span> <DD> Allow production of a <I><FONT color=#001050>confmagic.h</I></FONT><R> file to automagically remap some
well-known symbols to some other alternative, like </R><I><FONT color=#001050>bcopy</I></FONT><R>() being
remapped transparently to </R><I><FONT color=#001050>memcpy()</I></FONT><R> when not available. This option
is turned on automatically when a </R><I><FONT color=#001050>confmagic.h</I></FONT><R> file exists in the
top-level directory. Simply remove that file if you wish to disable this
option permanently.
</DD> </R></DT></DL> <DL><DT> <!-- --> <span class="B"> -V</span> <DD> Print version number and exit.
</DD> </DT></DL>
</UL> </LI> <LI> <span class="section"> TUTORIAL</span> <BR> <UL> This (long) section is an introduction to <I><FONT color=#001050>metaconfig</I></FONT><R>, in which we will
learn all the basics. If you already know how to use </R><I><FONT color=#001050>metaconfig</I></FONT><R>, you
may safely skip to the next section.
<span class="SS"> Overview</span> </R><span class="paragraph_brs"> <BR><BR> </span>
Usually when you want to get some source package to compile on a given
platform you have to edit the main Makefile (assuming there is one!),
choose a C compiler, make sure you have the proper libraries, and then
fire the <I><FONT color=#001050>make</I></FONT><R> command. If the package is reasonably well written, it
will compile (without a warning being an option :-). In itself, the last
sentence is a real performance, since given the variety of UNIX platforms
available today and the diversity of flavours, that means the author of the
package has gone into deep trouble to figure out the right choices given
some standard trial, guessing and messing around with system includes and
types.
<span class="paragraph_brs"> <BR><BR> </span> </R>
However, despite all his talent, the author cannot possibly know that
some system has a broken system call, or that some sytem structure lacks
one otherwise standard field, or simply wheter a given include file exists
or not. And I'm not considering the implicit assumptions, like the type
returned by the <I><FONT color=#001050>malloc()</I></FONT><R> function or the presence of the </R><I><FONT color=#001050>rename()</I></FONT><R>
system call to name a few. But that knowledge is necessary to achieve real
portability.
<span class="paragraph_brs"> <BR><BR> </span> </R>
Now let's not abuse ourselves. Using that information requires greater
skills, yet it can lead to more portable programs since it is then
written in a system-independant fashion and relies only on the fact that
some assumption is true or false on a particular system, each assumption
being unrelated with each other. That is to say, we do not say: We're on
a BSD system or we are on a USG system. That's too fuzzy anyway nowadays.
No, we want to say to the source code: this system does not have the
<span class="I"> rename()</span> system call and <I><FONT color=#001050>malloc()</I></FONT><R> returns a </R><I><FONT color=#001050>(void *)</I></FONT><R>
value.
<span class="paragraph_brs"> <BR><BR> </span> </R>
Metaconfig is a tool that will let you do just that, with the additional
benefit of not having to hand-edit the Makefile if all goes well. By
running <I><FONT color=#001050>metaconfig</I></FONT><R>, you create a shell script named </R><I><FONT color=#001050>Configure</I></FONT><R>.
Lots of efforts have been devoted to the Configure script internals to ensure
it will run on 99% of the existing shells available as of this writing.
Configure will probe the target system, asking questions when in doubt and
gather all the answers in one single shell file, which in turn can be used
to automatically generate configured Makefiles and C include files.
<span class="paragraph_brs"> <BR><BR> </span> </R>
There is only a limited (but quite large) set of symbols available for your
shell scripts and C programs. They are all documented in the Glossary file.
All you need to do is learn about them and start using them to address
portability and configuration problems. Then, by running <I><FONT color=#001050>metaconfig</I></FONT><R>,
a suitable Configure script will be generated for your package.
<span class="paragraph_brs"> <BR><BR> </span> </R>
The Configure script is built out several units (more than 300), each
unit being responsible for defining a small number of shell and/or C
symbols. Units are assembled together at the final stage, honoring
the dependency graph (one unit may need the result of several other
units which are then placed before in the script).
<span class="SS"> Symbols</span> <span class="paragraph_brs"> <BR><BR> </span>
Symbols are the most important thing in the <I><FONT color=#001050>metaconfig</I></FONT><R> world. They
are the smallest recognized entity, usually a word, and can be granted
a value at the end of the Configure execution. For instance, the C
pre-processor symbol </R><I><FONT color=#001050>HAS_RENAME</I></FONT><R> is a </R><I><FONT color=#001050>metaconfig</I></FONT><R> symbol that is
guranteed to be defined if, and only if, the </R><I><FONT color=#001050>rename()</I></FONT><R> system call
is present. Likewise, the </R><I><FONT color=#001050>$ranlib</I></FONT><R> shell variable will be set to
either ':' or 'ranlib' depending on whether the call to the </R><I><FONT color=#001050>ranlib</I></FONT><R>
program is needed to order a library file. How this works is not important
for now, what is important is to understand that those symbols are given
a </R><I><FONT color=#001050>life</I></FONT><R> (i.e. a value) upon </R><I><FONT color=#001050>Configure</I></FONT><R> execution.
<span class="paragraph_brs"> <BR><BR> </span> </R>
Using symbols is relatively straightforward. In a C source file, you simply
use the symbol value, as a pre-processor directive (for instance an: <I><FONT color=#001050>#ifdef
HAS_RENAME</I></FONT><R>) or, if the symbol value is a string, directly as you would use
a macro in C. And in a shell file or a Makefile, you may reference a shell
symbol directly.
<span class="paragraph_brs"> <BR><BR> </span> </R>
Actually, I'm lying, because that's not completely as magic as the previous
paragraph could sound. In a C file, you need to include the Configure-produced
<I><FONT color=#001050>config.h</I></FONT><R> file, and you must wrap your shell script or Makefile in a .SH
file and you may reference the shell symbol only in the variable
substitution part of that .SH file. More on this later.
<span class="SS"> Source Files</span> </R><span class="paragraph_brs"> <BR><BR> </span>
Symbols may only appear in a limited set of source files, because
<I><FONT color=#001050>metaconfig</I></FONT><R> will only scan those when looking for known symbols, trying
to figure out which units it will need. You may use C symbols in C source
files, i.e. files with a </R><I><FONT color=#001050>.c</I></FONT><R>, </R><I><FONT color=#001050>.h</I></FONT><R>, </R><I><FONT color=#001050>.y</I></FONT><R> or </R><I><FONT color=#001050>.l</I></FONT><R> extension,
and shell symbols are looked for only in .SH files.
<span class="paragraph_brs"> <BR><BR> </span> </R>
In order to get the value of a symbol, a C file needs to include the special
<I><FONT color=#001050>config.h</I></FONT><R> file, which is produced by </R><I><FONT color=#001050>Configure</I></FONT><R> when C symbols
are present. And .SH files are run through a shell, producing a new file.
However, in the top section of the .SH file, the special </R><I><FONT color=#001050>config.sh</I></FONT><R>
file (also produced by running </R><I><FONT color=#001050>Configure</I></FONT><R>) is sourced, and variable
substitutions apply. Actually, </R><I><FONT color=#001050>config.h</I></FONT><R> is produced by running the
</R><I><FONT color=#001050>metaconfig</I></FONT><R>-produced </R><I><FONT color=#001050>config_h.SH</I></FONT><R> file, again using variable
substitution. So we're going to look at that a little more closely since
this is the heart of the whole </R><I><FONT color=#001050>configuration</I></FONT><R> scheme...
<span class="SS"> Variable Substitution</span> </R><span class="paragraph_brs"> <BR><BR> </span>
There is shell construct called <I><FONT color=#001050>here document</I></FONT><R> which enables a
command to take an input specified within the script itself. That
input is interpreted by the shell as a double-quoted string or a
single quoted string depending on the form of the here document
specification.
<span class="paragraph_brs"> <BR><BR> </span> </R>
To specify a here document, the '<<' token is used, followed by a single
identifier. From then on, the remaining script lines form the input for
the command, until the here document is found on a line by itself.
Shell substitution (including shell variable substitutions) is done
unless the identifier is surrounded by single quotes. For instance:
var='first'
tar='second'
echo "--> first here document:"
cat <<EOM
var='$var'
tar='$tar'
EOM
echo "--> second here document:"
cat <<'EOM'
echo $var
echo $tar
EOM
echo "--> end."
will produce, when run through a shell:
--> first here document:
var='first'
tar='second'
--> second here document:
echo $var
echo $tar
--> end.
The first here document has its content interpreted whilst the second
one is output as-is. Both are useful in a .SH script, as we are about to see.
<span class="SS"> Using .SH Scripts</span> <span class="paragraph_brs"> <BR><BR> </span>
A .SH script is usually produced by running the <I><FONT color=#001050>MakeSH</I></FONT><R> script other
an existing file, transforming </R><I><FONT color=#001050>file</I></FONT><R> into a </R><I><FONT color=#001050>file.SH</I></FONT><R>. Let's take
a single example. Here is a little script (let's call it </R><I><FONT color=#001050>intsize</I></FONT><R>)
which prints a single message, the size of the </R><B>int</B><R> datatype in C.
Unfortunately, it has the value hardwired in it, thusly:
#!/bin/sh
intsize='4'
echo "On this machine, the int type is $intsize bytes"
Let's run </R><I><FONT color=#001050>makeSH</I></FONT><R> on it by typing '</R><I><FONT color=#001050>makeSH intsize</I></FONT><R>'. We get a single
</R><I><FONT color=#001050>intsize.SH</I></FONT><R> file that looks like this:
case $CONFIG in
'')
if test -f config.sh; then TOP=.;
elif test -f ../config.sh; then TOP=..;
elif test -f ../../config.sh; then TOP=../..;
elif test -f ../../../config.sh; then TOP=../../..;
elif test -f ../../../../config.sh; then TOP=../../../..;
else
echo "Can't find config.sh."; exit 1
fi
. $TOP/config.sh
;;
esac
: This forces SH files to create target in same directory as SH file.
: This is so that make depend always knows where to find SH derivatives.
case "$0" in
*/*) cd `expr X$0 : 'X\(.*\)/'` ;;
esac
echo "Extracting intsize (with variable substitutions)"
: This section of the file will have variable substitutions done on it.
: Move anything that needs config subs from !NO!SUBS! section to !GROK!THIS!.
: Protect any dollar signs and backticks that you do not want interpreted
: by putting a backslash in front. You may delete these comments.
$spitshell >intsize <<!GROK!THIS!
$startsh
!GROK!THIS!
<BR>
: In the following dollars and backticks do not need the extra backslash.
$spitshell >>intsize <<'!NO!SUBS!'
intsize='4'
echo "On this machine, the int type is $intsize bytes"
!NO!SUBS!
chmod 755 intsize
$eunicefix intsize
The first part of this script (in the </R><I><FONT color=#001050>case</I></FONT><R> statement) is trying to
locate the </R><I><FONT color=#001050>config.sh</I></FONT><R> file, in order to source it. The </R><I><FONT color=#001050>$CONFIG</I></FONT><R>
variable is false by default, by true when </R><I><FONT color=#001050>config.sh</I></FONT><R> has been sourced
already (which would be the case if this file was executed from within
</R><I><FONT color=#001050>Configure</I></FONT><R> itself, but let's not confuse the issue here).
<span class="paragraph_brs"> <BR><BR> </span> </R>
Once the <I><FONT color=#001050>config.sh</I></FONT><R> file has been sources, all the shell symbols
defined by </R><I><FONT color=#001050>Configure</I></FONT><R> are set. We know reach a second case statement,
used to change the current directory should a path be used to
reach this program (for instance if we said '</R><I><FONT color=#001050>sh ../scripts/intsize.SH</I></FONT><R>',
we would first run '</R><I><FONT color=#001050>cd ../scripts</I></FONT><R>' before continuing). If you do not
understand this, don't worry about it.
<span class="paragraph_brs"> <BR><BR> </span> </R>
Here comes the intersting stuff. This script uses the <I><FONT color=#001050>$spitshell</I></FONT><R>
variable, and it's not something we know about...yet. If you look through
the Glossary file, you will see that this is a variable known by
</R><I><FONT color=#001050>metaconfig</I></FONT><R>. If you make this file part of your distribution (by including
it in the MANIFEST.new file, we'll come back to that later on) and run
</R><I><FONT color=#001050>metaconfig</I></FONT><R>, then the </R><I><FONT color=#001050>Configure</I></FONT><R> script will determine a suitable
value for this variable and it will be set in </R><I><FONT color=#001050>config.sh</I></FONT><R>. Same goes for
</R><I><FONT color=#001050>$startsh</I></FONT><R> and the mysterious </R><I><FONT color=#001050>$eunicefix</I></FONT><R> at the end. On a
reasonable system, the relevant part of </R><I><FONT color=#001050>config.sh</I></FONT><R> would look like this:
spitshell='cat'
startsh='#!/bin/sh'
eunicefix=':'
Ah! We're getting there. Now it looks familiar. We're facing a single
</R><I><FONT color=#001050>cat</I></FONT><R> command whose input comes from a variable-interpolated here
document and whose output is redirected to </R><I><FONT color=#001050>intsize</I></FONT><R>. The value
will be that of </R><I><FONT color=#001050>$startsh</I></FONT><R>, i.e. '#!/bin/sh'. Fine so far.
<span class="paragraph_brs"> <BR><BR> </span> </R>
Then we reach the second here document expansion, to get the remaining of
the script. This time, the here document symbol is surrounded by single
quotes so the contents will be appended verbatim to the <I><FONT color=#001050>intsize</I></FONT><R> file.
So, by running '</R><I><FONT color=#001050>sh intsize.SH</I></FONT><R>', we get the following output:
Extracting intsize (with variable substitutions)
and by looking at the produced intsize file, we see:
#!/bin/sh
intsize='4'
echo "On this machine, the int type is $intsize bytes"
which is exactly what we had at the beginning. So far, it's a no-operation
procedure... But, how marvelous! It so happens (pure coincidence, trust me!),
that </R><I><FONT color=#001050>metaconfig</I></FONT><R> knows about the </R><I><FONT color=#001050>$intsize</I></FONT><R> shell symbol. By moving
the initialization of intsize to the variable-interpolated area of the .SH
script and initializing it with the </R><I><FONT color=#001050>Configure</I></FONT><R>-computed value,
and removing the now useless comments added by </R><I><FONT color=#001050>makeSH</I></FONT><R>, we get:
case $CONFIG in
'')
if test -f config.sh; then TOP=.;
elif test -f ../config.sh; then TOP=..;
elif test -f ../../config.sh; then TOP=../..;
elif test -f ../../../config.sh; then TOP=../../..;
elif test -f ../../../../config.sh; then TOP=../../../..;
else
echo "Can't find config.sh."; exit 1
fi
. $TOP/config.sh
;;
esac
case "$0" in
*/*) cd `expr X$0 : 'X\(.*\)/'` ;;
esac
echo "Extracting intsize (with variable substitutions)"
$spitshell >intsize <<!GROK!THIS!
$startsh
intsize='$intsize'
!GROK!THIS!
<BR>
$spitshell >>intsize <<'!NO!SUBS!'
echo "On this machine, the int type is $intsize bytes"
!NO!SUBS!
chmod 755 intsize
$eunicefix intsize
Of course, running this script through a shell will again output the same
script. But if we run </R><I><FONT color=#001050>Configure</I></FONT><R> on a machine where an </R><B>int</B><R> is
stored as a 64 bits quantity, </R><I><FONT color=#001050>config.sh</I></FONT><R> will set </R><I><FONT color=#001050>intsize</I></FONT><R> to
8 and the </R><I><FONT color=#001050>intsize</I></FONT><R> script will bear the right value and print:
On this machine, the int type is 8 bytes
which is correct. Congratulations! We have just configured a shell script!!
<span class="SS"> Producing config.h</span> </R><span class="paragraph_brs"> <BR><BR> </span>
We can now have a look at the way <I><FONT color=#001050>config.h</I></FONT><R> is produced out of
</R><I><FONT color=#001050>config_h.SH</I></FONT><R>. We know that running </R><I><FONT color=#001050>Configure</I></FONT><R> produces a
</R><I><FONT color=#001050>config.sh</I></FONT><R> script (how exactly this is done is not strictly
relevant here, but for the curious, it's another here document
substitution within </R><I><FONT color=#001050>Configure</I></FONT><R> itself). The </R><I><FONT color=#001050>config_h.SH</I></FONT><R>
itself is built by </R><I><FONT color=#001050>metaconfig</I></FONT><R> at the same time </R><I><FONT color=#001050>Configure</I></FONT><R>
is, provided you make use of at least one C symbol within your sources.
<span class="paragraph_brs"> <BR><BR> </span> </R>
Let's have a look at some random <I><FONT color=#001050>config_h.SH</I></FONT><R> file to see what
really happens:
case $CONFIG in
'')
if test -f config.sh; then TOP=.;
elif test -f ../config.sh; then TOP=..;
elif test -f ../../config.sh; then TOP=../..;
elif test -f ../../../config.sh; then TOP=../../..;
elif test -f ../../../../config.sh; then TOP=../../../..;
else
echo "Can't find config.sh."; exit 1
fi
. $TOP/config.sh
;;
esac
case "$0" in
*/*) cd `expr X$0 : 'X\(.*\)/'` ;;
esac
echo "Extracting config.h (with variable substitutions)"
sed <<!GROK!THIS! >config.h -e 's!^#undef!/#define!' -e 's!^#un-def!#undef!'
/*
* This file was produced by running the config_h.SH script, which
* gets its values from config.sh, which is generally produced by
* running Configure.
*
* Feel free to modify any of this as the need arises. Note, however,
* that running config.h.SH again will wipe out any changes you've made.
* For a more permanent change edit config.sh and rerun config.h.SH.
*/
<BR>
/* Configuration time: $cf_time
* Configured by: $cf_by
* Target system: $myuname
*/
<BR>
#ifndef _config_h_
#define _config_h_
<BR>
/* bcopy:
* This symbol is maped to memcpy if the bcopy() routine is not
* available to copy strings.
*/
/* HAS_BCOPY:
* This symbol is defined if the bcopy() routine is available to
* copy blocks of memory. You should not use this symbol under
* normal circumstances and use bcopy() directly instead, which
* will get mapped to memcpy() if bcopy is not available.
*/
#$d_bcopy HAS_BCOPY /**/
#ifndef HAS_BCOPY
#ifdef bcopy
#un-def bcopy
#endif
#define bcopy(s,d,l) memcpy((d),(s),(l)) /* mapped to memcpy */
#endif
<BR>
/* HAS_DUP2:
* This symbol, if defined, indicates that the dup2 routine is
* available to duplicate file descriptors.
*/
#$d_dup2 HAS_DUP2 /**/
<BR>
/* I_STRING:
* This symbol, if defined, indicates to the C program that it should
* include <string.h> (USG systems) instead of <strings.h> (BSD systems).
*/
#$i_string I_STRING /**/
<BR>
#endif
!GROK!THIS!
At the top of the file, we recognize the standard .SH construct that we
have already studied in detail. Next comes the extraction of the file
itself, via a here document with variable substitutions. However, here
we do not use a plain </R><I><FONT color=#001050>cat</I></FONT><R> but a </R><I><FONT color=#001050>sed</I></FONT><R> instead, since we need
to do some further editing on-the-fly. We'll see why later on, so let's
forget about it right now.
<span class="paragraph_brs"> <BR><BR> </span> </R>
We now reach the leading comment, and the file is tagged with the
configuration time, the target system, etc... (those variables coming
from the sourced <I><FONT color=#001050>config.sh</I></FONT><R> file have been set up by </R><I><FONT color=#001050>Configure</I></FONT><R>).
That comment header is followed by a '#ifndef' protection to guard against
multiple inclusions of this file. Then comes the heart of the file...
<span class="paragraph_brs"> <BR><BR> </span> </R>
It helps to know that <I><FONT color=#001050>$d_*</I></FONT><R> and </R><I><FONT color=#001050>$i_*</I></FONT><R> variables are set to
either '</R><I><FONT color=#001050>define</I></FONT><R>' or '</R><I><FONT color=#001050>undef</I></FONT><R>' by </R><I><FONT color=#001050>Configure</I></FONT><R>, depending on
wether a function or an include file is present on the system or not.
That means the:
#$d_bcopy HAS_BCOPY /**/
line will be expanded to either:
#define HAS_BCOPY /**/
if the $d_bcopy variable is set to 'define' or:
#undef HAS_BCOPY /**/
if $d_bcopy was set to 'undef', because the feature was not there. However,
that's not what gets written in the </R><I><FONT color=#001050>config.h</I></FONT><R> file because of the
</R><I><FONT color=#001050>sed</I></FONT><R> filter we have already seen, which will transform the second form
into:
/*#define HAS_BCOPY /**/
That's a handy form for later editing of </R><I><FONT color=#001050>config.h</I></FONT><R> because you only need
to remove the leading '/*' if you want to override </R><I><FONT color=#001050>Configure</I></FONT><R>'s choice.
Likewise, you may add a single '/*' at the beginning of a '#define' line
to avoid the definition of a particular symbol. This is why each symbol
definition is protected by a trailing '/**/', to close the leading
comment opened by '/*' (comments are not nested in C).
<span class="paragraph_brs"> <BR><BR> </span> </R>
Now transforming '#undef' into '/*#define' is nice, but if we want to actually
write a '#undef', we're stuck... unless we write it as '#un-def' and let
<I><FONT color=#001050>sed</I></FONT><R> fix that to '#undef' while producing </R><I><FONT color=#001050>config.h</I></FONT><R>, which is what
is actually done here.
<span class="paragraph_brs"> <BR><BR> </span> </R>
The same kind of reasoning applies to those two lines:
#$d_dup2 HAS_DUP2 /**/
#$i_string I_STRING /**/
and assuming <I><FONT color=#001050>config.sh</I></FONT><R> defines:
d_dup2='define'
i_string='undef'
we'll get in the produced </R><I><FONT color=#001050>config.h</I></FONT><R>:
#define HAS_DUP2 /**/
/*#define I_STRING /**/
Clear as running water? Good!
<span class="paragraph_brs"> <BR><BR> </span> </R>
Now it should be obvious that by including <I><FONT color=#001050>config.h</I></FONT><R> in all your
C source files, you get to know what </R><I><FONT color=#001050>Configure</I></FONT><R> has guessed on
your system. In effect, by using those symbols, you are writing
configured C code, since </R><I><FONT color=#001050>metaconfig</I></FONT><R> will know that you need
those symbols and will generate a suitable </R><I><FONT color=#001050>config_h.SH</I></FONT><R> file as
well as all the necessary code in </R><I><FONT color=#001050>Configure</I></FONT><R> to compute a
proper value for them (by assigning values to associated shell variables).
<span class="SS"> Running Metaconfig</span> </R><span class="paragraph_brs"> <BR><BR> </span>
Let's focus on the <I><FONT color=#001050>metaconfig</I></FONT><R> program for a while to understand how
it uses its units and your source code to produce all the needed configuration
files. If you intend to write new units, you should have a good understanding
of the whole scheme.
<span class="paragraph_brs"> <BR><BR> </span> </R>
Assuming your MANIFEST.new file is properly set and lists all the source
files you wish to configure, and that you have run <I><FONT color=#001050>packint</I></FONT><R> in your
root source directory to create a </R><I><FONT color=#001050>.package</I></FONT><R> file, you may run
</R><I><FONT color=#001050>metaconfig</I></FONT><R> and you'll get the following:
$ metaconfig
Locating units...
Extracting dependency lists from 312 units...
Extracting filenames (*.[chyl] and *.SH) from MANIFEST.new...
Building a Wanted file...
Scanning .[chyl] files for symbols...
Scanning .SH files for symbols...
Computing optimal dependency graph...
Building private make file...
Determining loadable units...
Updating make file...
Determining the correct order for the units...
Creating Configure...
Done.
The first phase looks for all the units files (ending with .U) in the public
directory first, then in your private one. If you copy a public file in your
private U directory (i.e. a directory named U at the top level of your package),
it will override the public version. Once it has a list of all the available
units, it parses them and extracts all the ?MAKE: lines to know about the
dependencies and the known shell symbols. It also focuses on the ?H: lines to
learn about the C symbols and which shell symbols needs to be computed to get
a proper value for that C symbol (so we have another level of dependencies
here).
<span class="paragraph_brs"> <BR><BR> </span> </R>
Next, the proper filenames are extracted from the MANIFEST.new files and a
<I><FONT color=#001050>Wanted</I></FONT><R> file is built: that file lists all the C symbols and the shell
symbols needed for that package. We first scan the C-type files for C symbols,
then propagate the dependencies to their associated shell symbols (gathered
from ?H: lines). Next .SH files are scanned and finally all the shell symbols
are known.
<span class="paragraph_brs"> <BR><BR> </span> </R>
A temporary Makefile is built and metaconfig tries to <I><FONT color=#001050>make</I></FONT><R> all the shell
symbols to see what commands (listed on the second ?MAKE: lines) are
executed, and thus which units are really needed. Optional units not otherwise
required are removed and a second Makefile is generated. This time, we know
about all the units and their respective orders, optional units having been
removed and default values computed for their shell symbols. The </R><I><FONT color=#001050>Configure</I></FONT><R>
script can then be generated, along with </R><I><FONT color=#001050>config_h.SH</I></FONT><R>. We're done.
<span class="SS"> Conventions</span> </R><span class="paragraph_brs"> <BR><BR> </span>
Proper conventions needs to be followed to make the whole process sound.
There is a case convention for units and a variable naming convention.
<span class="paragraph_brs"> <BR><BR> </span>
All units should have their first letter lower-cased, unless they are
special units. By special, we mean they do not really define new
shell variables that can be used by the user in his .SH files, but rather
units producing scripts or shell variables that are to be used internally
by the <I><FONT color=#001050>Configure</I></FONT><R> script. Typical examples are the </R><I><FONT color=#001050>Init.U</I></FONT><R>
file which is the main variable initialization, or </R><I><FONT color=#001050>Myread.U</I></FONT><R> which
produces the </R><I><FONT color=#001050>myread</I></FONT><R> script used almost everywhere in </R><I><FONT color=#001050>Configure</I></FONT><R>
when a question is to be asked to the user.
<span class="paragraph_brs"> <BR><BR> </span> </R>
Non-special units then subdivise in two distinct groups: units defining
variables associated to a C symbol and units defining shell variables of
their own. The first group is further divided in variables related to
include files (their name begin with <I><FONT color=#001050>i_</I></FONT><R>) and variables related to
other definitions (name starting with </R><I><FONT color=#001050>d_</I></FONT><R>). The second group have
names standing for itself, for instance </R><I><FONT color=#001050>cc.U</I></FONT><R> defines the </R><I><FONT color=#001050>$cc</I></FONT><R>
shell variable whose value is the C compiler to be used.
<span class="paragraph_brs"> <BR><BR> </span> </R>
Special units sometimes reserve themselves some pre-defined variable and
return "results" in other well-known variables. For instance, the <I><FONT color=#001050>myread</I></FONT><R>
script produced by Myread.U expects the prompt in </R><I><FONT color=#001050>$rp</I></FONT><R>, the default
answer in </R><I><FONT color=#001050>$dflt</I></FONT><R> and places the user answer in </R><I><FONT color=#001050>$ans</I></FONT><R>. This is
not documented in this manual page: you have to go and look at the unit
itself to understand which variables are used and how the unit is to be
used.
<span class="SS"> Using The Glossary</span> </R><span class="paragraph_brs"> <BR><BR> </span>
The Glossary file is automatically produced by the <I><FONT color=#001050>makegloss</I></FONT><R> script,
which extracts the information from ?S:, ?C: and ?MAKE: lines and reformats
them into an alphabetically sorted glossary.
It is important to read the Glossary to know about the symbols you are
allowed to use. However, the Glossary will not tell you how to use them.
Usually, that's up to you.
<span class="paragraph_brs"> <BR><BR> </span> </R>
One day, you will probably write your own units and you will know enough
about <I><FONT color=#001050>metaconfig</I></FONT><R> to do so quickly and efficiently. However, never
forget to properly document your work in the ?S: and ?C: lines, or other
people will not be able to reuse it. Remember about the time where you
had only the Glossary and this manual page to get started.
<span class="SS"> Conclusion</span> </R><span class="paragraph_brs"> <BR><BR> </span>
Now that you know the <I><FONT color=#001050>metaconfig</I></FONT><R> basics, you should read the
</R><I><FONT color=#001050>DESCRIPTION</I></FONT><R> section, then skip to the </R><I><FONT color=#001050>REFERENCE</I></FONT><R> section
to learn about all the gory details such as the allowed syntax for
unit control lines (lines starting with a '?') or the distinct MAKE
commands you are allowed to use.