Now the compiler options are extracted from "./build charm++ arch help".
[charm.git] / smart-build.pl
1 #!/usr/bin/perl
2
3
4 # This is an interactive script that knows
5 # common ways to build Charm++ and AMPI.
6 #
7 # Authors: dooley, becker
8
9
10
11 # Turn off I/O buffering
12 $| = 1;
13
14 print "Begin interactive charm configuration\n\n";
15
16 # Use uname to get the cpu type and OS information
17 $os = `uname -s`;
18 $cpu = `uname -m`;
19
20 #Variables to hold the portions of the configuration:
21 $nobs = "";
22 $arch = "";
23 $compilers = "";
24 $options = "";
25
26 #remove newlines from these strings:
27 chomp($os);
28 chomp ($cpu);
29
30
31 # Determine OS kernel
32 if ($os eq "Linux") {
33   print "Detected a linux kernel\n";
34   $arch_os = "linux";
35 } elsif ($os eq "Darwin") {
36   print "Detected a darwin kernel\n";
37   $arch_os = "darwin";
38 } elsif ($os =~ m/BSD/ ) {
39   print "Detected a BSD kernel\n";
40   $arch_os = "linux";
41 } elsif ($os =~ m/OSF1/ ) {
42   print "Detected an OSF1 kernel\n";
43   $arch_os = "linux";
44 } elsif ($os =~ m/AIX/ ) {
45   print "Detected an AIX kernel\n";
46   $arch = "mpi-sp";
47 }
48
49
50
51 # Determine architecture (x86, ppc, ...)
52 if($cpu =~ m/i[0-9]86/){
53   print "Detected architecture x86\n";
54   $x86 = 1;
55 } elsif($cpu =~ m/x86\_64/){
56   print "Detected architecture x86_64\n";
57   $amd64 = 1;
58 } elsif($cpu =~ m/ia64/){
59   print "Detected architecture ia64\n";
60   $ia64 = 1;
61   $nobs = "--no-build-shared";
62 } elsif($cpu =~ m/powerpc/){
63   print "Detected architecture ppc\n";
64   $ppc = 1;
65 } elsif($cpu =~ m/Power Mac/){
66   print "Detected architecture ppc\n";
67   $ppc = 1;
68 } elsif($cpu =~ m/alpha/){
69   print "Detected architecture alpha\n";
70   $alpha = 1;
71 }
72
73 # Determine converse architecture (net, mpi, ...)
74 print "Do you have a special network interconnect? [y/N]";
75 $special_network = "false";
76 while($line = <>){
77         chomp $line;
78         if(lc($line) eq "y" || lc($line) eq "yes" ){
79                 $special_network = "true";
80                 last;
81         } elsif(lc($line) eq "n" || lc($line) eq "no" || $line eq "" ){
82                 last;
83         }
84 }
85
86 # default to net
87 $converse_network_type = "net";
88         
89 if($special_network eq "true"){
90         print << "EOF";
91         
92 Choose an interconnect from below: [1-11]
93          1) MPI
94          2) Infiniband (native ibverbs alpha version)
95          3) Myrinet GM
96          4) Myrinet MX
97      5) LAPI
98          6) Cray XT3, XT4 (not yet tested on CNL)
99          7) Bluegene/L Native (only at T. J. Watson)
100          8) Bluegene/L MPI
101          9) Bluegene/P Native (only at T. J. Watson)
102         10) Bluegene/P MPI
103         11) VMI
104
105 EOF
106         
107         while($line = <>){
108                 chomp $line;
109                 if($line eq "1"){
110                         $converse_network_type = "mpi";
111                         last;
112                 } elsif($line eq "2"){
113                         $converse_network_type = "net";
114                         $options = "$options ibverbs ";
115                         last;
116                 } elsif($line eq "3"){
117                         $converse_network_type = "net";
118                         $options = $options . "gm ";
119                         last;
120                 } elsif($line eq "4"){
121                         $converse_network_type = "net";
122                         $options = $options . "mx ";
123                         last;
124                 } elsif($line eq "5"){
125                         $arch = "lapi";
126                         last;
127                 } elsif($line eq "6"){
128                         $arch = "mpi-crayxt3";
129                         last;
130                 } elsif($line eq "7"){
131                         $arch = "bluegenel";
132                         $compilers = "xlc ";
133                         $nobs = "--no-build-shared";
134                         last;
135                 } elsif($line eq "8"){
136                     $arch = "mpi-bluegenel";
137                         $compilers = "xlc ";
138                         $nobs = "--no-build-shared";
139                         last;
140                 } elsif($line eq "9"){
141                     $arch = "bluegenep";
142                         $compilers = "xlc ";
143                         last;
144                 } elsif($line eq "10"){
145                     $arch = "mpi-bluegenep";
146                         $compilers = "xlc ";
147                         last;
148                   } elsif($line eq "11"){
149                         $converse_network_type = "vmi";
150                         last;
151                 } else {
152                         print "Invalid option, DOES NOT COMPUTE, please try again :P\n"
153                 }
154         }       
155 }
156
157
158 if($arch eq ""){
159           $arch = "${converse_network_type}-${arch_os}";
160           if($amd64) {
161                 $arch = $arch . "-amd64";
162           } elsif($ia64){
163                 $arch = $arch . "-ia64";
164           } elsif($ppc){
165                 $arch = $arch . "-ppc";
166           } elsif($alpha){
167                 $arch = $arch . "-axp";
168           }
169 }
170   
171 #Cleanup the architectures to match the horrible real world inconsistent src/archs
172
173 if($arch eq "net-darwin"){
174         $arch = "net-darwin-x86";
175 } elsif($arch eq "net-darwin-ppc"){
176         $arch = "net-ppc-darwin";
177 } elsif($arch eq "mpi-darwin-ppc"){
178         $arch = "mpi-ppc-darwin";
179
180
181
182
183
184
185 # Determine whether to support SMP / Multicore
186 print "Do you want SMP or multicore support? [y/N]";
187 $smp = "";
188 while($line = <>){
189         chomp $line;
190         if(lc($line) eq "y" || lc($line) eq "yes" ){
191                 $options = "$options smp ";
192                 last;
193         } elsif(lc($line) eq "n" || lc($line) eq "no" || $line eq ""){
194                 last;
195         } else {
196                 print "Invalid option, DOES NOT COMPUTE, please try again :P\n"
197         }
198 }
199
200
201 #================ Choose Compiler =================================
202
203
204 print "Do you want to specify a compiler? [y/N]";
205 $special_compiler = "false";
206 while($line = <>){
207         chomp $line;
208         if(lc($line) eq "y" || lc($line) eq "yes" ){
209                 $special_compiler = "true";
210                 last;
211         } elsif(lc($line) eq "n" || lc($line) eq "no" || $line eq ""){
212                 last;
213         } else {
214                 print "Invalid option, DOES NOT COMPUTE, please try again :P\n"
215         }
216 }
217
218
219
220 # Produce list of compilers
221
222 $cs = `./build charm++ $arch help | grep "Supported compilers"`;
223 # prune away beginning of the line
224 $cs =~ m/Supported compilers: (.*)/;
225 $cs = $1;
226 # split the line into an array
227 @c_list = split(" ", $cs);
228
229
230 # Choose compiler
231 if($special_compiler eq "true"){
232     $numc = @c_list;
233         print "Choose a compiler: [1-$numc] \n";
234
235         $i = 1;
236         foreach $c (@c_list){
237           print "\t$i)\t$c\n";
238           $i++;
239         }
240
241         while($line = <>){
242           chomp $line;
243           if($line =~ m/([0-9]*)/ && $1 > 0 && $1 <= $numc){
244                 $compilers = $compilers . " " . $c_list[$1-1] . " ";
245                 last;
246           } else {
247                 print "Invalid option, DOES NOT COMPUTE, please try again :P\n"
248           }
249         }
250 }
251
252
253
254
255 #================ Choose Options =================================
256
257 print "Do you want to specify any Charm++ build options such as fortran compilers? [y/N]";
258 $special_options = "false";
259 while($line = <>){
260         chomp $line;
261         if(lc($line) eq "y" || lc($line) eq "yes" ){
262                 $special_options = "true";
263                 last;
264         } elsif(lc($line) eq "n" || lc($line) eq "no" || $line eq ""){
265                 last;
266         } else {
267                 print "Invalid option, DOES NOT COMPUTE, please try again :P\n"
268         }
269 }
270
271
272 if($special_options eq "true"){
273
274   # Produce list of options
275
276   $opts = `./build charm++ $arch help | grep "Supported options"`;
277   # prune away beginning of line
278   $opts =~ m/Supported options: (.*)/;
279   $opts = $1;
280
281   @option_list = split(" ", $opts);
282   
283   print "Please enter one or more numbers separated by spaces\n";
284   print "Choices:\n";
285
286   # Prune out entries that would already have been chosen above, such as smp
287   @option_list_pruned = ();
288   foreach $o (@option_list){
289         if($o ne "smp" && $o ne "ibverbs"){
290           @option_list_pruned = (@option_list_pruned , $o);
291         }
292   }
293
294   # sort the list
295   @option_list_pruned = sort @option_list_pruned;
296
297   # print out list for user to select from
298   $i = 1;
299   foreach $o (@option_list_pruned){
300         print "\t$i)\t$o\n";
301         $i++;
302   }
303   print "\t$i)\tNone Of The Above\n";
304
305   $num_options = @option_list_pruned;
306
307   while($line = <>){
308         chomp $line;
309     $line =~ m/([0-9 ]*)/;
310     @entries = split(" ",$1);
311     @entries = sort(@entries);
312
313         $additional_options = "";
314         foreach $e (@entries) {
315           if($e>=1 && $e<= $num_options){
316                 $estring = $option_list_pruned[$e-1];
317                 $additional_options = "$additional_options $estring";
318           } elsif ($e == $num_options+1){
319                 # user chose "None of the above"
320                 # clear the options we may have seen before
321                 $additional_options = " ";
322           }
323         }
324
325         # if the user input something reasonable, we can break out of this loop
326         if($additional_options ne ""){
327           $options = "$options ${additional_options} ";
328           last;
329         }
330
331   }
332
333 }
334
335
336
337
338 # Choose compiler flags
339 print << "EOF";
340         
341 Choose a set of compiler flags [1-4]
342         1) none
343         2) debug
344         3) optimized [default]
345         4) custom
346         
347 EOF
348
349 $compiler_flags = "";
350
351 while($line = <>){
352         chomp $line;
353         if($line eq "1"){
354                 last;
355         } elsif($line eq "2"){
356                 $compiler_flags = "-g -O0";
357                 last;
358         } elsif($line eq "3" || $line eq ""){
359                 $compiler_flags = "-O2 -DCMK_OPTIMIZE";
360                 last;
361         } elsif($line eq "4"){
362
363                 print "Enter compiler options: ";
364                 $input_line = <>;
365                 chomp($input_line);
366                 $compiler_flags = $input_line;
367                 
368                 last;
369         } else {
370                 print "Invalid option, DOES NOT COMPUTE, please try again :P\n"
371         }
372 }
373
374
375
376
377 # Determine the target to build.
378 # We want this simple so we just give 2 options
379 $target = "";
380
381 print << "EOF";
382
383 What do you want to build?
384         1) Charm++ [default] (choose this if you are building NAMD)
385         2) Charm++, AMPI, ParFUM, FEM and other libraries
386
387 EOF
388
389 while($line = <>){
390         chomp $line;
391         if($line eq "1" || $line eq ""){
392                 $target = "charm++";
393                 last;
394         } elsif($line eq "2"){
395                 $target = "LIBS";
396                 last;
397         } else {
398                 print "Invalid option, DOES NOT COMPUTE, please try again :P\n"
399         }
400         
401 }
402
403 # Determine whether to use a -j4 flag for faster building
404 # Currently LIBS cannot be safely built with -j4
405 if($target eq "charm++"){
406         print "Do you want to do a parallel build (-j4)?[Y/n]";
407         while($line = <>){
408                 chomp $line;
409                 if(lc($line) eq "y" || lc($line) eq "yes" || $line eq ""){
410                         $j = "-j4";
411                   last;
412                 } elsif(lc($line) eq "n" || lc($line) eq "no" ){
413                         $j = "";
414                         last;
415                 } else {
416                         print "Invalid option, DOES NOT COMPUTE, please try again :P\n"
417                 }
418         }
419 }
420
421
422 # Compose the build line
423 $build_line = "./build $target $arch $compilers $options $smp $j ${compiler_flags}\n";
424
425
426 # Save the build line in the log
427 open(BUILDLINE, ">>smart-build.log");
428 print BUILDLINE `date`;
429 print BUILDLINE "Using the following build command:\n";
430 print BUILDLINE "$build_line\n";
431 close(BUILDLINE);
432
433
434 print "We have determined a suitable build line is:\n";
435 print "\t$build_line\n\n";
436
437
438 # Execute the build line if the appropriate architecture directory exists
439 print "Do you want to start the build now? [Y/n]";
440 while($line = <>){
441   chomp $line;
442   if(lc($line) eq "y" || lc($line) eq "yes" || $line eq ""){
443         
444         if(-e "src/arch/$arch"){
445           print "Building with: ${build_line}\n";       
446           # Execute the build line
447           system($build_line);
448         } else {
449           print "We could not figure out how to build charm with those options on this platform, please manually build\n";
450           print "Try something similar to: ${build_line}\n";
451         }
452         
453         last;
454   } elsif(lc($line) eq "n" || lc($line) eq "no" ){
455         last;
456   } else {
457         print "Invalid option, DOES NOT COMPUTE, please try again :P\n"
458   }
459 }
460
461
462