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 |
|
|
# <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 |
|
|
# <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 |
|
|
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 |
|
|
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 |
|
|
} |
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 |
|
|
$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 |
|
|
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 |
|
|
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 |
|
|
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 |
|
|
|
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 |
|
|
{ |
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__ |