1 arta 1.1 #!/usr/bin/perl -w
2
3
4 # Format of the projdirs.cfg file:
5 # __MAKE__
6 # $(CEXESUMS): $(LIBSUMSAPI) $(LIBSUM) $(LIBDSTRUCT)
7 # $(MODEXESUMS): $(LIBSUMSAPI) $(LIBSUM)
8 #
9 # $(MODEXEDROBJ): CF_TGT := $(CF_TGT) -I$(SRCDIR)/proj/libs/dr
10 # $(MODEXEDR) $(MODEXEDR_SOCK): $(LIBDR)
11 # __END__
12 # __PROJ__
13 # proj=mag
14 # subdir=pfss/apps
15 # subdir=ambig/apps
16 # subdir=ident/apps
17 # COMPILER=icc
18 # proj=limbfit
19 # subdir=apps
20 # JSOC_MACHINE=linux_x86_64
21 # <?xml version='1.0'?>
22 arta 1.1 # <projects>
23 # <proj>
24 # <name>mag</name>
25 # <subdirs>
26 # <subdir>pfss/apps</subdir>
27 # <subdir>ambig/apps</subdir>
28 # <subdir>ident/apps</subdir>
29 # </subdirs>
30 # <filters>
31 # <filter>
32 # <name>COMPILER</name>
33 # <value>icc</value>
34 # </filter>
35 # </filters>
36 # </proj>
37 # <proj>
38 # <name>limbfit</name>
39 # <subdirs>
40 # <subdir>apps</subdir>
41 # </subdirs>
42 # <filters>
43 arta 1.1 # <filter>
44 # <name>COMPILER</name>
45 # <value>icc</value>
46 # </filter>
47 # </filters>
48 # </proj>
49 # </projects>
50 # __END__
51
52 use XML::Simple;
53 use Data::Dumper;
54
55 use constant kMakeDiv => "__MAKE__";
56 use constant kProjDiv => "__PROJ__";
|
57 arta 1.4 use constant kProjCfgDiv => "__PROJCFG__";
|
58 arta 1.1 use constant kEndDiv => "__END__";
59 use constant kStUnk => 0;
60 use constant kStMake => 1;
61 use constant kStProj => 2;
|
62 arta 1.4 use constant kStProjCfg => 3;
|
63 arta 1.1 use constant kMakeFile => "make_basic.mk";
64 use constant kTargetFile => "target.mk";
65 use constant kRulesFile => "Rules.mk";
|
66 arta 1.4 use constant kProjCfgFile => "configure";
|
67 arta 1.1 use constant kMakeVarCOMPILER => "COMPILER";
68 use constant kMakeVarFCOMPILER => "FCOMPILER";
69 use constant kMakeVarJSOC_MACHINE => "JSOC_MACHINE";
70 use constant kStrproj => "proj";
71 use constant kStrsubdirs => "subdirs";
72 use constant kStrsubdir => "subdir";
73 use constant kStrname => "name";
74 use constant kStrvalue => "value";
75 use constant kStrfilters => "filters";
76 use constant kStrfilter => "filter";
77
78 my($err);
79 my($arg);
80 my($pos);
81 my($locdir); # localization dir
82 my($cfgfile); # file containing project directories needed
83 my($st); # current position in configuration file
84 my($proj);
85 my($subdir);
86 my($compiler);
87 my($plat);
88 arta 1.1 my($key);
89 my($val);
90 my($mdiv);
91 my($pdiv);
|
92 arta 1.4 my($pcdiv);
|
93 arta 1.1 my($ediv);
94 my($xml);
95
96 $err = 0;
97
98 while ($arg = shift(@ARGV))
99 {
100 if (($pos = index($arg, "-d", 0)) == 0)
101 {
102 $locdir = substr($arg, 2);
103 }
104 elsif (($pos = index($arg, "-c", 0)) == 0)
105 {
106 $cfgfile = substr($arg, 2);
107 }
108 }
109
110 if (defined($cfgfile) && -e $cfgfile)
111 {
112 if (open(CFGFILE, "<$cfgfile"))
113 {
114 arta 1.1 my($makedone);
115 my($projdone);
|
116 arta 1.4 my($projcfgdone);
|
117 arta 1.1
118 $st = kStUnk;
119 $mdiv = kMakeDiv;
120 $pdiv = kProjDiv;
|
121 arta 1.4 $pcdiv = kProjCfgDiv;
|
122 arta 1.1 $ediv = kEndDiv;
123
124 $makedone = 0;
125 $projdone = 0;
|
126 arta 1.4 $projcfgdone = 0;
|
127 arta 1.1
128 while (defined($line = <CFGFILE>))
129 {
130 chomp($line);
131
132 if ($line =~ /^\#/ || $line =~ /^\s*$/)
133 {
134 # Skip blank lines or lines beginning with # (comment lines)
135 next;
136 }
137 elsif ($line =~ /^$mdiv/)
138 {
139 $st = kStMake;
140 if (!open(MKFILE, ">${locdir}/" . kMakeFile))
141 {
142 print STDERR "Unable to open " . kMakeFile . " for writing.\n";
143 $err = 1;
144 last;
145 }
146
147 next;
148 arta 1.1 }
149 elsif ($line =~ /^$pdiv/)
150 {
151 $st = kStProj;
152 if (!open(TARGETFILE, ">${locdir}/" . kTargetFile))
153 {
154 print STDERR "Unable to open " . kTargetFile . " for writing.\n";
155 $err = 1;
156 last;
157 }
158
159 print TARGETFILE "\$(PROJOBJDIR):\n\t+\@[ -d \$\@ ] || mkdir -p \$\@\n";
160
161 if (!open(RULESFILE, ">${locdir}/" . kRulesFile))
162 {
163 print STDERR "Unable to open " . kRulesFile . " for writing.\n";
164 $err = 1;
165 last;
166 }
167
168 # initialize xml string variable
169 arta 1.1 $xml = "";
170 next;
171 }
|
172 arta 1.4 elsif ($line =~ /^$pcdiv/)
173 {
174 $st = kStProjCfg;
175 if (!open(PROJCFGFILE, ">${locdir}/" . kProjCfgFile))
176 {
177 print STDERR "Unable to open " . kProjCfgFile . " for writing.\n";
178 $err = 1;
179 last;
180 }
181
182 next;
183 }
|
184 arta 1.1 elsif ($line =~ /^$ediv/)
185 {
186 if ($st == kStMake)
187 {
188 $makedone = 1;
189 }
190 elsif ($st == kStProj)
191 {
192 $projdone = 1;
193 }
|
194 arta 1.4 elsif ($st == kStProjCfg)
195 {
196 $projcfgdone = 1;
197 }
|
198 arta 1.1
199 $st = kStUnk;
200
|
201 arta 1.4 if ($makedone && $projdone && $projcfgdone)
|
202 arta 1.1 {
203 last;
204 }
205
206 next;
207 }
208
209 if ($st == kStMake)
210 {
211 # copy verbatim to make_basic.mk
212 print MKFILE "$line\n";
213 }
214 elsif ($st == kStProj)
215 {
216 # suck out xml
217 $xml = $xml . "$line\n";
218 }
|
219 arta 1.4 elsif ($st == kStProjCfg)
220 {
221 # copy verbatim to configure
222 print PROJCFGFILE "$line\n";
223 }
|
224 arta 1.1 } # loop over cfg file
225
226 close(CFGFILE);
227
228 if (length($xml) > 0)
229 {
230 # Extract data from xml and write to target and rules files.
231 my($xmlobj) = new XML::Simple;
232 my($xmldata) = $xmlobj->XMLin($xml, ForceArray => 1);
233 my($rulesstr);
234 my($prefix);
235 my($fileprefix);
236 my($filesuffix);
237 my($suffix);
238
239 my($strproj) = kStrproj;
240 my($strname) = kStrname;
241 my($strsubdirs) = kStrsubdirs;
242 my($strsubdir) = kStrsubdir;
243 my($strfilters) = kStrfilters;
244 my($strfilter) = kStrfilter;
245 arta 1.1 my($strvalue) = kStrvalue;
246
247 #print Dumper($xmldata);
248
249 # If the config file has at least one project specification, then print the rules file prefix.
250 if ($#{$xmldata->{$strproj}} >= 0)
251 {
252 my(@filedata) = <DATA>;
253 my($st);
254
255 $st = 0;
256 foreach $dline (@filedata)
257 {
258 chomp($dline);
259
260 if ($st == 0 && $dline =~ /__DATAPREFIX__/)
261 {
262 $fileprefix = "";
263 $st = 1;
264 next;
265 }
266 arta 1.1 elsif ($st == 1 && $dline =~ /__ENDER__/)
267 {
268 $st = 2;
269 next;
270 }
271 elsif ($st == 2 && $dline =~ /__DATASUFFIX__/)
272 {
273 $filesuffix = "";
274 $st = 3;
275 next;
276 }
277 elsif ($st == 3 && $dline =~ /__ENDER__/)
278 {
279 $st = 4;
280 last;
281 }
282
283 if ($st == 1)
284 {
285 $fileprefix = $fileprefix . "$dline\n";
286 }
287 arta 1.1 elsif ($st == 3)
288 {
289 $filesuffix = $filesuffix . "$dline\n";
290 }
291 }
292 }
293
294 if (defined($fileprefix))
295 {
296 print RULESFILE "${fileprefix}\n";
297 }
298
299 foreach $proj (@{$xmldata->{$strproj}})
300 {
301 $rulesstr = "dir := \$(d)/$proj->{$strname}->[0]\n-include \$(SRCDIR)/\$(dir)/Rules.mk\n";
302
303 foreach $subdir (@{$proj->{$strsubdirs}->[0]->{$strsubdir}})
304 {
305 # I believe $subdir is now the actual subdirectory string.
306 print TARGETFILE "\t+\@[ -d \$\@/$proj->{$strname}->[0]/$subdir ] || mkdir -p \$\@/$proj->{$strname}->[0]/$subdir\n";
307 }
308 arta 1.1
309 # make doesn't support logical operations in ifeq conditionals (you can't do ifeq (A AND B)),
310 # so we need to write:
311 # ifeq (A)
312 # ifeq (B)
313 # <do something>
314 # endif
315 # endif
316
317 $prefix = "";
318 $suffix = "";
319
320 foreach $filter (@{$proj->{$strfilters}->[0]->{$strfilter}})
321 {
322 $prefix = $prefix . "ifeq (\$($filter->{$strname}->[0]),$filter->{$strvalue}->[0])\n";
323 $suffix = $suffix . "endif\n";
324 }
325
326 if (defined($prefix) && defined($suffix) && defined($rulesstr))
327 {
328 if (length($prefix) > 0)
329 arta 1.1 {
330 print RULESFILE $prefix;
331 }
332
333 print RULESFILE $rulesstr;
334
335 if (length($suffix) > 0)
336 {
337 print RULESFILE $suffix;
338 }
339 }
340 } # loop over projects
341
342 if (defined($filesuffix))
343 {
344 print RULESFILE "${filesuffix}\n";
345 }
346 }
|
347 arta 1.4
|
348 arta 1.1 close(TARGETFILE);
349 close(RULESFILE);
|
350 arta 1.4 close(PROJCFGFILE);
|
351 arta 1.1 close(MKFILE);
|
352 arta 1.4
353 if (chmod(0744, "${locdir}/" . kProjCfgFile) != 1)
354 {
355 print STDERR "Unable to set file permissions for ${locdir}/" . kProjCfgFile . ".\n";
356 $err = 1;
357 }
|
358 arta 1.1 }
359 else
360 {
361 print STDERR "Unable to open configuration file $cfgfile.\n";
|
362 arta 1.4 $err = 1;
|
363 arta 1.1 }
364 }
365
366 exit($err);
367
368 __DATA__
369
370 __DATAPREFIX__
371 # Standard things
372 sp := $(sp).x
373 dirstack_$(sp) := $(d)
374 d := $(dir)
375
376 __ENDER__
377
378 __DATASUFFIX__
|
379 arta 1.2 dir := $(d)/example
380 -include $(SRCDIR)/$(dir)/Rules.mk
381 dir := $(d)/cookbook
382 -include $(SRCDIR)/$(dir)/Rules.mk
383 dir := $(d)/myproj
384 -include $(SRCDIR)/$(dir)/Rules.mk
385
|
386 arta 1.1 # Standard things
387 d := $(dirstack_$(sp))
388 sp := $(basename $(sp))
389 __ENDER__
|