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 |
use constant kEndDiv => "__END__"; |
58 |
use constant kStUnk => 0; |
59 |
use constant kStMake => 1; |
60 |
use constant kStProj => 2; |
61 |
use constant kMakeFile => "make_basic.mk"; |
62 |
use constant kTargetFile => "target.mk"; |
63 |
use constant kRulesFile => "Rules.mk"; |
64 |
use constant kMakeVarCOMPILER => "COMPILER"; |
65 |
use constant kMakeVarFCOMPILER => "FCOMPILER"; |
66 |
use constant kMakeVarJSOC_MACHINE => "JSOC_MACHINE"; |
67 |
use constant kStrproj => "proj"; |
68 |
use constant kStrsubdirs => "subdirs"; |
69 |
use constant kStrsubdir => "subdir"; |
70 |
use constant kStrname => "name"; |
71 |
use constant kStrvalue => "value"; |
72 |
use constant kStrfilters => "filters"; |
73 |
use constant kStrfilter => "filter"; |
74 |
|
75 |
my($err); |
76 |
my($arg); |
77 |
my($pos); |
78 |
my($locdir); # localization dir |
79 |
my($cfgfile); # file containing project directories needed |
80 |
my($st); # current position in configuration file |
81 |
my($proj); |
82 |
my($subdir); |
83 |
my($compiler); |
84 |
my($plat); |
85 |
my($key); |
86 |
my($val); |
87 |
my($mdiv); |
88 |
my($pdiv); |
89 |
my($ediv); |
90 |
my($xml); |
91 |
|
92 |
$err = 0; |
93 |
|
94 |
while ($arg = shift(@ARGV)) |
95 |
{ |
96 |
if (($pos = index($arg, "-d", 0)) == 0) |
97 |
{ |
98 |
$locdir = substr($arg, 2); |
99 |
} |
100 |
elsif (($pos = index($arg, "-c", 0)) == 0) |
101 |
{ |
102 |
$cfgfile = substr($arg, 2); |
103 |
} |
104 |
} |
105 |
|
106 |
if (defined($cfgfile) && -e $cfgfile) |
107 |
{ |
108 |
if (open(CFGFILE, "<$cfgfile")) |
109 |
{ |
110 |
my($makedone); |
111 |
my($projdone); |
112 |
|
113 |
$st = kStUnk; |
114 |
$mdiv = kMakeDiv; |
115 |
$pdiv = kProjDiv; |
116 |
$ediv = kEndDiv; |
117 |
|
118 |
$makedone = 0; |
119 |
$projdone = 0; |
120 |
|
121 |
while (defined($line = <CFGFILE>)) |
122 |
{ |
123 |
chomp($line); |
124 |
|
125 |
if ($line =~ /^\#/ || $line =~ /^\s*$/) |
126 |
{ |
127 |
# Skip blank lines or lines beginning with # (comment lines) |
128 |
next; |
129 |
} |
130 |
elsif ($line =~ /^$mdiv/) |
131 |
{ |
132 |
$st = kStMake; |
133 |
if (!open(MKFILE, ">${locdir}/" . kMakeFile)) |
134 |
{ |
135 |
print STDERR "Unable to open " . kMakeFile . " for writing.\n"; |
136 |
$err = 1; |
137 |
last; |
138 |
} |
139 |
|
140 |
next; |
141 |
} |
142 |
elsif ($line =~ /^$pdiv/) |
143 |
{ |
144 |
$st = kStProj; |
145 |
if (!open(TARGETFILE, ">${locdir}/" . kTargetFile)) |
146 |
{ |
147 |
print STDERR "Unable to open " . kTargetFile . " for writing.\n"; |
148 |
$err = 1; |
149 |
last; |
150 |
} |
151 |
|
152 |
print TARGETFILE "\$(PROJOBJDIR):\n\t+\@[ -d \$\@ ] || mkdir -p \$\@\n"; |
153 |
|
154 |
if (!open(RULESFILE, ">${locdir}/" . kRulesFile)) |
155 |
{ |
156 |
print STDERR "Unable to open " . kRulesFile . " for writing.\n"; |
157 |
$err = 1; |
158 |
last; |
159 |
} |
160 |
|
161 |
# initialize xml string variable |
162 |
$xml = ""; |
163 |
next; |
164 |
} |
165 |
elsif ($line =~ /^$ediv/) |
166 |
{ |
167 |
if ($st == kStMake) |
168 |
{ |
169 |
$makedone = 1; |
170 |
} |
171 |
elsif ($st == kStProj) |
172 |
{ |
173 |
$projdone = 1; |
174 |
} |
175 |
|
176 |
$st = kStUnk; |
177 |
|
178 |
if ($makedone && $projdone) |
179 |
{ |
180 |
last; |
181 |
} |
182 |
|
183 |
next; |
184 |
} |
185 |
|
186 |
if ($st == kStMake) |
187 |
{ |
188 |
# copy verbatim to make_basic.mk |
189 |
print MKFILE "$line\n"; |
190 |
} |
191 |
elsif ($st == kStProj) |
192 |
{ |
193 |
# suck out xml |
194 |
$xml = $xml . "$line\n"; |
195 |
} |
196 |
} # loop over cfg file |
197 |
|
198 |
close(CFGFILE); |
199 |
|
200 |
if (length($xml) > 0) |
201 |
{ |
202 |
# Extract data from xml and write to target and rules files. |
203 |
my($xmlobj) = new XML::Simple; |
204 |
my($xmldata) = $xmlobj->XMLin($xml, ForceArray => 1); |
205 |
my($rulesstr); |
206 |
my($prefix); |
207 |
my($fileprefix); |
208 |
my($filesuffix); |
209 |
my($suffix); |
210 |
|
211 |
my($strproj) = kStrproj; |
212 |
my($strname) = kStrname; |
213 |
my($strsubdirs) = kStrsubdirs; |
214 |
my($strsubdir) = kStrsubdir; |
215 |
my($strfilters) = kStrfilters; |
216 |
my($strfilter) = kStrfilter; |
217 |
my($strvalue) = kStrvalue; |
218 |
|
219 |
#print Dumper($xmldata); |
220 |
|
221 |
# If the config file has at least one project specification, then print the rules file prefix. |
222 |
if ($#{$xmldata->{$strproj}} >= 0) |
223 |
{ |
224 |
my(@filedata) = <DATA>; |
225 |
my($st); |
226 |
|
227 |
$st = 0; |
228 |
foreach $dline (@filedata) |
229 |
{ |
230 |
chomp($dline); |
231 |
|
232 |
if ($st == 0 && $dline =~ /__DATAPREFIX__/) |
233 |
{ |
234 |
$fileprefix = ""; |
235 |
$st = 1; |
236 |
next; |
237 |
} |
238 |
elsif ($st == 1 && $dline =~ /__ENDER__/) |
239 |
{ |
240 |
$st = 2; |
241 |
next; |
242 |
} |
243 |
elsif ($st == 2 && $dline =~ /__DATASUFFIX__/) |
244 |
{ |
245 |
$filesuffix = ""; |
246 |
$st = 3; |
247 |
next; |
248 |
} |
249 |
elsif ($st == 3 && $dline =~ /__ENDER__/) |
250 |
{ |
251 |
$st = 4; |
252 |
last; |
253 |
} |
254 |
|
255 |
if ($st == 1) |
256 |
{ |
257 |
$fileprefix = $fileprefix . "$dline\n"; |
258 |
} |
259 |
elsif ($st == 3) |
260 |
{ |
261 |
$filesuffix = $filesuffix . "$dline\n"; |
262 |
} |
263 |
} |
264 |
} |
265 |
|
266 |
if (defined($fileprefix)) |
267 |
{ |
268 |
print RULESFILE "${fileprefix}\n"; |
269 |
} |
270 |
|
271 |
foreach $proj (@{$xmldata->{$strproj}}) |
272 |
{ |
273 |
$rulesstr = "dir := \$(d)/$proj->{$strname}->[0]\n-include \$(SRCDIR)/\$(dir)/Rules.mk\n"; |
274 |
|
275 |
foreach $subdir (@{$proj->{$strsubdirs}->[0]->{$strsubdir}}) |
276 |
{ |
277 |
# I believe $subdir is now the actual subdirectory string. |
278 |
print TARGETFILE "\t+\@[ -d \$\@/$proj->{$strname}->[0]/$subdir ] || mkdir -p \$\@/$proj->{$strname}->[0]/$subdir\n"; |
279 |
} |
280 |
|
281 |
# make doesn't support logical operations in ifeq conditionals (you can't do ifeq (A AND B)), |
282 |
# so we need to write: |
283 |
# ifeq (A) |
284 |
# ifeq (B) |
285 |
# <do something> |
286 |
# endif |
287 |
# endif |
288 |
|
289 |
$prefix = ""; |
290 |
$suffix = ""; |
291 |
|
292 |
foreach $filter (@{$proj->{$strfilters}->[0]->{$strfilter}}) |
293 |
{ |
294 |
$prefix = $prefix . "ifeq (\$($filter->{$strname}->[0]),$filter->{$strvalue}->[0])\n"; |
295 |
$suffix = $suffix . "endif\n"; |
296 |
} |
297 |
|
298 |
if (defined($prefix) && defined($suffix) && defined($rulesstr)) |
299 |
{ |
300 |
if (length($prefix) > 0) |
301 |
{ |
302 |
print RULESFILE $prefix; |
303 |
} |
304 |
|
305 |
print RULESFILE $rulesstr; |
306 |
|
307 |
if (length($suffix) > 0) |
308 |
{ |
309 |
print RULESFILE $suffix; |
310 |
} |
311 |
} |
312 |
} # loop over projects |
313 |
|
314 |
if (defined($filesuffix)) |
315 |
{ |
316 |
print RULESFILE "${filesuffix}\n"; |
317 |
} |
318 |
} |
319 |
|
320 |
close(TARGETFILE); |
321 |
close(RULESFILE); |
322 |
close(MKFILE); |
323 |
} |
324 |
else |
325 |
{ |
326 |
print STDERR "Unable to open configuration file $cfgfile.\n"; |
327 |
exit(1); |
328 |
} |
329 |
} |
330 |
|
331 |
exit($err); |
332 |
|
333 |
__DATA__ |
334 |
|
335 |
__DATAPREFIX__ |
336 |
# Standard things |
337 |
sp := $(sp).x |
338 |
dirstack_$(sp) := $(d) |
339 |
d := $(dir) |
340 |
|
341 |
# ALWAYS put libs subdirectory before other subdirectories. |
342 |
dir := $(d)/libs |
343 |
-include $(SRCDIR)/$(dir)/Rules.mk |
344 |
__ENDER__ |
345 |
|
346 |
__DATASUFFIX__ |
347 |
# Standard things |
348 |
d := $(dirstack_$(sp)) |
349 |
sp := $(basename $(sp)) |
350 |
__ENDER__ |