1#!/usr/bin/env perl 2# 3# Copyright (c) 2009-2021 Cisco Systems, Inc. All rights reserved 4# Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved. 5# Copyright (c) 2013 Mellanox Technologies, Inc. 6# All rights reserved. 7# Copyright (c) 2013-2014 Intel, Inc. All rights reserved. 8# Copyright (c) 2015-2020 Research Organization for Information Science 9# and Technology (RIST). All rights reserved. 10# Copyright (c) 2015 IBM Corporation. All rights reserved. 11# 12# $COPYRIGHT$ 13# 14# Additional copyrights may follow 15# 16# $HEADER$ 17# 18 19use strict; 20 21use Cwd; 22use File::Basename; 23use File::Find; 24use Data::Dumper; 25use Getopt::Long; 26 27# 28# Global variables 29# 30 31# Sentinel file to remove if we fail 32my $sentinel; 33 34# The m4 file we'll write at the end 35my $m4_output_file = "config/autogen_found_items.m4"; 36my $m4; 37# Sanity check file 38my $topdir_file = "opal/include/opal_config_bottom.h"; 39my $dnl_line = "dnl ---------------------------------------------------------------------------"; 40 41# Data structures to fill up with all the stuff we find 42my $mca_found; 43my $mpiext_found; 44my $mpicontrib_found; 45my @subdirs; 46 47# Command line parameters 48my $no_ompi_arg = 0; 49my $no_orte_arg = 0; 50my $no_oshmem_arg = 0; 51my $quiet_arg = 0; 52my $debug_arg = 0; 53my $help_arg = 0; 54my $platform_arg = 0; 55my $include_arg = 0; 56my $exclude_arg = 0; 57my $force_arg = 0; 58 59# Include/exclude lists 60my $include_list; 61my $exclude_list; 62 63# Minimum versions 64my $ompi_automake_version = "1.12.2"; 65my $ompi_autoconf_version = "2.69"; 66my $ompi_libtool_version = "2.4.2"; 67 68# Search paths 69my $ompi_autoconf_search = "autoconf"; 70my $ompi_automake_search = "automake"; 71my $ompi_libtoolize_search = "libtoolize;glibtoolize"; 72 73# One-time setup 74my $username; 75my $hostname; 76my $full_hostname; 77 78# Patch program 79my $patch_prog = "patch"; 80# Solaris "patch" doesn't understand unified diffs, and will cause 81# autogen.pl to hang with a "File to patch:" prompt. Default to Linux 82# "patch", but use "gpatch" on Solaris. 83if ($^O eq "solaris") { 84 $patch_prog = "gpatch"; 85} 86 87$username = getpwuid($>); 88$full_hostname = `hostname`; 89chomp($full_hostname); 90$hostname = $full_hostname; 91$hostname =~ s/^([\w\-]+)\..+/\1/; 92 93############################################################################## 94 95sub my_die { 96 unlink($sentinel) 97 if ($sentinel); 98 die @_; 99} 100 101sub my_exit { 102 my ($ret) = @_; 103 unlink($sentinel) 104 if ($sentinel && $ret != 0); 105 exit($ret); 106} 107 108############################################################################## 109 110sub verbose { 111 print @_ 112 if (!$quiet_arg); 113} 114 115sub debug { 116 print @_ 117 if ($debug_arg); 118} 119 120sub debug_dump { 121 my $d = new Data::Dumper([@_]); 122 $d->Purity(1)->Indent(1); 123 debug $d->Dump; 124} 125 126############################################################################## 127 128sub read_config_params { 129 my ($filename, $dir_prefix) = @_; 130 131 my $dir = dirname($filename); 132 open(FILE, $filename) || 133 my_die "Can't open $filename"; 134 my $file; 135 $file .= $_ 136 while(<FILE>); 137 close(FILE); 138 139 # Save all lines of the form "foo = bar" in a hash 140 my $ret; 141 while ($file =~ s/^\s*(\w+)\s*=\s*(.+)\s*$//m) { 142 my $key = $1; 143 my $val = $2; 144 145 # Strip off any leading and trailing "'s 146 $val = $1 147 if ($val =~ m/^\"(.+)\"$/); 148 149 $ret->{$key} = $val; 150 } 151 152 # Split PARAM_CONFIG_FILES into an array 153 if (exists($ret->{PARAM_CONFIG_FILES})) { 154 my @out; 155 foreach my $f (split(/\s+/, $ret->{PARAM_CONFIG_FILES})) { 156 push(@out, "$dir_prefix/$f"); 157 } 158 $ret->{PARAM_CONFIG_FILES} = \@out; 159 } 160 161 debug_dump($ret); 162 return $ret; 163} 164 165############################################################################## 166 167# Process a "subdir", meaning that the directory isn't a component or 168# an extension; it probably just needs an autoreconf, autogen, etc. 169sub process_subdir { 170 my ($dir) = @_; 171 172 # Chdir to the subdir 173 print "\n=== Processing subdir: $dir\n"; 174 my $start = Cwd::cwd(); 175 chdir($dir); 176 177 # Run an action depending on what we find in that subdir 178 if (-x "autogen.pl") { 179 print "--- Found autogen.pl; running...\n"; 180 safe_system("./autogen.pl"); 181 } elsif (-x "autogen.sh") { 182 print "--- Found autogen.sh; running...\n"; 183 safe_system("./autogen.sh"); 184 } elsif (-f "configure.in" || -f "configure.ac") { 185 print "--- Found configure.in|ac; running autoreconf...\n"; 186 safe_system("autoreconf -ivf"); 187 print "--- Patching autotools output... :-(\n"; 188 } else { 189 my_die "Found subdir, but no autogen.sh or configure.in|ac to do anything"; 190 } 191 192 # Ensure that we got a good configure executable. 193 my_die "Did not generate a \"configure\" executable in $dir.\n" 194 if (! -x "configure"); 195 196 # Fix known issues in Autotools output 197 patch_autotools_output($start); 198 199 # Chdir back to where we came from 200 chdir($start); 201} 202 203############################################################################## 204 205sub process_autogen_subdirs { 206 my ($dir) = @_; 207 208 my $file = "$dir/autogen.subdirs"; 209 if (-f $file) { 210 open(FILE, $file) || my_die "Can't open $file"; 211 while (<FILE>) { 212 chomp; 213 $_ =~ s/#.*$//; 214 $_ =~ s/^\s*//; 215 $_ =~ s/\s*$//; 216 if ($_ ne "") { 217 print " Found subdir: $_ (will process later)\n"; 218 219 # Note: there's no real technical reason to defer 220 # processing the subdirs. It's more of an aesthetic 221 # reason -- don't interrupt the current flow of 222 # finding mca / ext / contribs (which is a nice, fast 223 # process). Then process the subdirs (which is a slow 224 # process) all at once. 225 push(@subdirs, "$dir/$_"); 226 } 227 } 228 close(FILE); 229 } 230} 231 232############################################################################## 233 234sub mca_process_component { 235 my ($topdir, $project, $framework, $component) = @_; 236 237 my $pname = $project->{name}; 238 my $pdir = $project->{dir}; 239 my $cdir = "$topdir/$pdir/mca/$framework/$component"; 240 241 return 242 if (! -d $cdir); 243 244 # Process this directory (pretty much the same treatment as for 245 # mpiext, so it's in a sub). 246 my $found_component; 247 248 # Does this directory have a configure.m4 file? 249 if (-f "$cdir/configure.m4") { 250 $found_component->{"configure.m4"} = 1; 251 verbose " Found configure.m4 file\n"; 252 } 253 254 $found_component->{"name"} = $component; 255 256 # Push the results onto the $mca_found hash array 257 push(@{$mca_found->{$pname}->{$framework}->{"components"}}, 258 $found_component); 259 260 # Is there an autogen.subdirs in here? 261 process_autogen_subdirs($cdir); 262} 263 264############################################################################## 265 266sub ignored { 267 my ($dir) = @_; 268 269 # If this directory does not have .opal_ignore, or if it has a 270 # .opal_unignore that has my username in it, then add it to the 271 # list of components. 272 my $ignored = 0; 273 274 if (-f "$dir/.opal_ignore") { 275 $ignored = 1; 276 } 277 if (-f "$dir/.opal_unignore") { 278 open(UNIGNORE, "$dir/.opal_unignore") || 279 my_die "Can't open $dir/.opal_unignore file"; 280 my $unignore; 281 $unignore .= $_ 282 while (<UNIGNORE>); 283 close(UNIGNORE); 284 285 $ignored = 0 286 if ($unignore =~ /^$username$/m || 287 $unignore =~ /^$username\@$hostname$/m || 288 $unignore =~ /^$username\@$full_hostname$/m); 289 } 290 291 return $ignored; 292} 293 294############################################################################## 295 296sub mca_process_framework { 297 my ($topdir, $project, $framework) = @_; 298 299 my $pname = $project->{name}; 300 my $pdir = $project->{dir}; 301 302 # Does this framework have a configure.m4 file? 303 my $dir = "$topdir/$pdir/mca/$framework"; 304 if (-f "$dir/configure.m4") { 305 $mca_found->{$pname}->{$framework}->{"configure.m4"} = 1; 306 verbose " Found framework configure.m4 file\n"; 307 } 308 309 # Did we exclude all components for this framework? 310 if (exists($exclude_list->{$framework}) && 311 $exclude_list->{$framework}[0] eq "AGEN_EXCLUDE_ALL") { 312 verbose " => Excluded\n"; 313 } else { 314 # Look for component directories in this framework 315 if (-d $dir) { 316 $mca_found->{$pname}->{$framework}->{found} = 1; 317 opendir(DIR, $dir) || 318 my_die "Can't open $dir directory"; 319 foreach my $d (sort(readdir(DIR))) { 320 # Skip any non-directory, "base", or any dir that 321 # begins with "." 322 next 323 if (! -d "$dir/$d" || $d eq "base" || 324 substr($d, 0, 1) eq "."); 325 326 # Skip any component that doesn't have a configure.m4 327 # or Makefile.am as we couldn't build it anyway 328 if (! -f "$dir/$d/configure.m4" && 329 ! -f "$dir/$d/Makefile.am" && 330 ! -f "$dir/$d/configure.ac" && 331 ! -f "$dir/$d/configure.in") { 332 verbose " => No sentinel file found in $dir/$d -> Excluded\n"; 333 next; 334 } 335 336 verbose "--- Found $pname / $framework / $d component\n"; 337 338 # Skip if specifically excluded 339 if (exists($exclude_list->{$framework}) && 340 $exclude_list->{$framework}[0] eq $d) { 341 verbose " => Excluded\n"; 342 next; 343 } 344 345 # Skip if the framework is on the include list, but 346 # doesn't contain this component 347 if (exists($include_list->{$framework})) { 348 my $tst = 0; 349 foreach my $ck (@{$include_list->{$framework}}) { 350 if ($ck ne $d) { 351 verbose " => Not included\n"; 352 $tst = 1; 353 last; 354 } 355 } 356 if ($tst) { 357 next; 358 } 359 } 360 361 # Check ignore status 362 if (ignored("$dir/$d")) { 363 verbose " => Ignored (found .opal_ignore file)\n"; 364 } else { 365 mca_process_component($topdir, $project, $framework, $d); 366 } 367 } 368 } 369 closedir(DIR); 370 } 371} 372 373############################################################################## 374 375sub mca_generate_framework_header(\$\@) { 376 my ($project, @frameworks) = @_; 377 my $framework_array_output=""; 378 my $framework_decl_output=""; 379 380 foreach my $framework (@frameworks) { 381 # There is no common framework object 382 if ($framework ne "common") { 383 my $framework_name = "${project}_${framework}_base_framework"; 384 $framework_array_output .= " &$framework_name,\n"; 385 $framework_decl_output .= "extern mca_base_framework_t $framework_name;\n"; 386 } 387 } 388 389 my $ifdef_string = uc "${project}_FRAMEWORKS_H"; 390 open(FRAMEWORKS_OUT, ">$project/include/$project/frameworks.h"); 391 printf FRAMEWORKS_OUT "%s", "/* 392 * This file is autogenerated by autogen.pl. Do not edit this file by hand. 393 */ 394#ifndef $ifdef_string 395#define $ifdef_string 396 397#include <opal/mca/base/mca_base_framework.h> 398 399$framework_decl_output 400static mca_base_framework_t *${project}_frameworks[] = { 401$framework_array_output NULL 402}; 403 404#endif /* $ifdef_string */\n\n"; 405 close(FRAMEWORKS_OUT); 406} 407 408############################################################################## 409 410sub mca_process_project { 411 my ($topdir, $project) = @_; 412 413 my $pname = $project->{name}; 414 my $pdir = $project->{dir}; 415 416 # Does this project have a configure.m4 file? 417 if (-f "$topdir/$pdir/configure.m4") { 418 $mca_found->{$pname}->{"configure.m4"} = 1; 419 verbose " Found $topdir/$pdir/configure.m4 file\n"; 420 } 421 422 # Look for framework directories in this project 423 my $dir = "$topdir/$pdir/mca"; 424 if (-d $dir) { 425 opendir(DIR, $dir) || 426 my_die "Can't open $dir directory"; 427 my @my_dirs = readdir(DIR); 428 @my_dirs = sort(@my_dirs); 429 430 foreach my $d (@my_dirs) { 431 # Skip any non-directory, "base", or any dir that begins with "." 432 next 433 if (! -d "$dir/$d" || $d eq "base" || substr($d, 0, 1) eq "."); 434 435 my $framework_header = "$dir/$d/$d.h"; 436 437 # If there's a $dir/$d/autogen.options file, read it 438 my $ao_file = "$dir/$d/autogen.options"; 439 if (-r $ao_file) { 440 verbose "\n>>> Found $dir/$d/autogen.options file\n"; 441 open(IN, $ao_file) || 442 die "$ao_file present, but cannot open it"; 443 while (<IN>) { 444 if (m/\s*framework_header\s*=\s*(.+?)\s*$/) { 445 verbose " Framework header entry: $1\n"; 446 $framework_header = "$dir/$d/$1"; 447 } 448 } 449 close(IN); 450 } 451 452 # If this directory has a framework header and a base/ 453 # subdirectory, or its name is "common", then it's a 454 # framework. 455 if ("common" eq $d || !$project->{need_base} || 456 (-f $framework_header && -d "$dir/$d/base")) { 457 verbose "\n=== Found $pname / $d framework\n"; 458 mca_process_framework($topdir, $project, $d); 459 } 460 } 461 closedir(DIR); 462 } 463} 464 465############################################################################## 466 467sub mca_run_global { 468 my ($projects) = @_; 469 470 # For each project, go find a list of frameworks, and for each of 471 # those, go find a list of components. 472 my $topdir = Cwd::cwd(); 473 foreach my $p (@$projects) { 474 if (-d "$topdir/$p->{dir}") { 475 verbose "\n*** Found $p->{name} project\n"; 476 mca_process_project($topdir, $p); 477 } 478 } 479 480 # Debugging output 481 debug_dump($mca_found); 482 483 # Save (just) the list of MCA projects in the m4 file 484 my $str; 485 foreach my $p (@$projects) { 486 my $pname = $p->{name}; 487 # Check if this project is an MCA project (contains MCA framework) 488 if (exists($mca_found->{$pname})) { 489 $str .= "$p->{name}, "; 490 } 491 } 492 $str =~ s/, $//; 493 $m4 .= "\ndnl List of MCA projects found by autogen.pl 494m4_define([mca_project_list], [$str])\n"; 495 496 #----------------------------------------------------------------------- 497 498 $m4 .= "\n$dnl_line 499$dnl_line 500$dnl_line 501 502dnl MCA information\n"; 503 504 # Array for all the m4_includes that we'll need to pick up the 505 # configure.m4's. 506 my @includes; 507 508 # Next, for each project, write the list of frameworks 509 foreach my $p (@$projects) { 510 511 my $pname = $p->{name}; 512 my $pdir = $p->{dir}; 513 514 if (exists($mca_found->{$pname})) { 515 my $frameworks_comma; 516 517 # Does this project have a configure.m4 file? 518 push(@includes, "$pdir/configure.m4") 519 if (exists($mca_found->{$p}->{"configure.m4"})); 520 521 # Print out project-level info 522 my @mykeys = keys(%{$mca_found->{$pname}}); 523 @mykeys = sort(@mykeys); 524 525 # Ensure that the "common" framework is listed first 526 # (if it exists) 527 my @tmp; 528 push(@tmp, "common") 529 if (grep(/common/, @mykeys)); 530 foreach my $f (@mykeys) { 531 push(@tmp, $f) 532 if ($f ne "common"); 533 } 534 @mykeys = @tmp; 535 536 foreach my $f (@mykeys) { 537 $frameworks_comma .= ", $f"; 538 539 # Does this framework have a configure.m4 file? 540 push(@includes, "$pdir/mca/$f/configure.m4") 541 if (exists($mca_found->{$pname}->{$f}->{"configure.m4"})); 542 543 # This framework does have a Makefile.am (or at least, 544 # it should!) 545 my_die "Missing $pdir/mca/$f/Makefile.am" 546 if (! -f "$pdir/mca/$f/Makefile.am"); 547 } 548 $frameworks_comma =~ s/^, //; 549 550 &mca_generate_framework_header($pname, @mykeys); 551 552 $m4 .= "$dnl_line 553 554dnl Frameworks in the $pname project and their corresponding directories 555m4_define([mca_${pname}_framework_list], [$frameworks_comma]) 556 557"; 558 559 # Print out framework-level info 560 foreach my $f (@mykeys) { 561 my $components; 562 my $m4_config_component_list; 563 my $no_config_component_list; 564 565 # Troll through each of the found components 566 foreach my $comp (@{$mca_found->{$pname}->{$f}->{components}}) { 567 my $c = $comp->{name}; 568 $components .= "$c "; 569 570 # Does this component have a configure.m4 file? 571 if (exists($comp->{"configure.m4"})) { 572 push(@includes, "$pdir/mca/$f/$c/configure.m4"); 573 $m4_config_component_list .= ", $c"; 574 } else { 575 $no_config_component_list .= ", $c"; 576 } 577 } 578 $m4_config_component_list =~ s/^, //; 579 $no_config_component_list =~ s/^, //; 580 581 $m4 .= "dnl Components in the $pname / $f framework 582m4_define([mca_${pname}_${f}_m4_config_component_list], [$m4_config_component_list]) 583m4_define([mca_${pname}_${f}_no_config_component_list], [$no_config_component_list]) 584 585"; 586 } 587 } 588 } 589 590 # List out all the m4_include 591 $m4 .= "$dnl_line 592 593dnl List of configure.m4 files to include\n"; 594 foreach my $i (@includes) { 595 $m4 .= "m4_include([$i])\n"; 596 } 597} 598 599############################################################################## 600 601sub mpiext_process_extension { 602 my ($topdir, $ext_prefix, $extdir) = @_; 603 604 my $edir = "$topdir/$ext_prefix/$extdir"; 605 return 606 if (! -d $edir); 607 608 # Process this directory (pretty much the same treatment as for 609 # MCA components, so it's in a sub). 610 my $found_ext; 611 612 $found_ext->{"name"} = $extdir; 613 614 # Push the results onto the hash array 615 push(@{$mpiext_found}, $found_ext); 616 617 # Is there an autogen.subdirs in here? 618 process_autogen_subdirs($edir); 619} 620 621############################################################################## 622 623sub mpiext_run_global { 624 my ($ext_prefix) = @_; 625 626 my $topdir = Cwd::cwd(); 627 628 my $dir = "$topdir/$ext_prefix"; 629 opendir(DIR, $dir) || 630 my_die "Can't open $dir directory"; 631 foreach my $d (sort(readdir(DIR))) { 632 # Skip any non-directory, "base", or any dir that begins with "." 633 next 634 if (! -d "$dir/$d" || $d eq "base" || substr($d, 0, 1) eq "."); 635 636 # If this directory has a configure.m4, then it's an 637 # extension. 638 if (-f "$dir/$d/configure.m4") { 639 verbose "=== Found $d MPI extension"; 640 641 # Check ignore status 642 if (ignored("$dir/$d")) { 643 verbose " (ignored)\n"; 644 } else { 645 verbose "\n"; 646 mpiext_process_extension($topdir, $ext_prefix, $d); 647 } 648 } 649 } 650 closedir(DIR); 651 debug_dump($mpiext_found); 652 653 #----------------------------------------------------------------------- 654 655 $m4 .= "\n$dnl_line 656$dnl_line 657$dnl_line 658 659dnl Open MPI extensions information 660$dnl_line\n\n"; 661 662 # Array for all the m4_includes that we'll need to pick up the 663 # configure.m4's. 664 my @includes; 665 my $m4_config_ext_list; 666 667 # Troll through each of the found exts 668 foreach my $ext (@{$mpiext_found}) { 669 my $e = $ext->{name}; 670 push(@includes, "$ext_prefix/$e/configure.m4"); 671 $m4_config_ext_list .= ", $e"; 672 } 673 674 $m4_config_ext_list =~ s/^, //; 675 676 # List the M4 and no configure exts 677 $m4 .= "dnl List of all MPI extensions 678m4_define([ompi_mpiext_list], [$m4_config_ext_list])\n"; 679 # List out all the m4_include 680 $m4 .= "\ndnl List of configure.m4 files to include\n"; 681 foreach my $i (@includes) { 682 $m4 .= "m4_include([$i])\n"; 683 } 684} 685 686############################################################################## 687 688sub mpicontrib_process { 689 my ($topdir, $contrib_prefix, $contribdir) = @_; 690 691 my $cdir = "$topdir/$contrib_prefix/$contribdir"; 692 return 693 if (! -d $cdir); 694 695 # Process this directory (pretty much the same treatment as for 696 # MCA components, so it's in a sub). 697 my $found_contrib; 698 699 $found_contrib->{"name"} = $contribdir; 700 701 # Push the results onto the hash array 702 push(@{$mpicontrib_found}, $found_contrib); 703 704 # Is there an autogen.subdirs in here? 705 process_autogen_subdirs($cdir); 706} 707 708############################################################################## 709 710sub mpicontrib_run_global { 711 my ($contrib_prefix) = @_; 712 713 my $topdir = Cwd::cwd(); 714 715 my $dir = "$topdir/$contrib_prefix"; 716 opendir(DIR, $dir) || 717 my_die "Can't open $dir directory"; 718 foreach my $d (sort(readdir(DIR))) { 719 # Skip any non-directory, "base", or any dir that begins with "." 720 next 721 if (! -d "$dir/$d" || $d eq "base" || substr($d, 0, 1) eq "."); 722 723 # If this directory has a configure.m4, then it's an 724 # contrib. 725 if (-f "$dir/$d/configure.m4") { 726 verbose "=== Found $d MPI contrib"; 727 728 # Check ignore status 729 if (ignored("$dir/$d")) { 730 verbose " (ignored)\n"; 731 } else { 732 verbose "\n"; 733 mpicontrib_process($topdir, $contrib_prefix, $d); 734 } 735 } 736 } 737 closedir(DIR); 738 debug_dump($mpicontrib_found); 739 740 #----------------------------------------------------------------------- 741 742 $m4 .= "\n$dnl_line 743$dnl_line 744$dnl_line 745 746dnl Open MPI contrib information 747$dnl_line\n\n"; 748 749 # Array for all the m4_includes that we'll need to pick up the 750 # configure.m4's. 751 my @includes; 752 my $m4_config_contrib_list; 753 754 # Troll through each of the found contribs 755 foreach my $contrib (@{$mpicontrib_found}) { 756 my $c = $contrib->{name}; 757 push(@includes, "$contrib_prefix/$c/configure.m4"); 758 $m4_config_contrib_list .= ", $c"; 759 } 760 761 $m4_config_contrib_list =~ s/^, //; 762 763 # List the M4 and no configure contribs 764 $m4 .= "dnl List of all MPI contribs 765m4_define([ompi_mpicontrib_list], [$m4_config_contrib_list])\n"; 766 # List out all the m4_include 767 $m4 .= "\ndnl List of configure.m4 files to include\n"; 768 foreach my $i (@includes) { 769 $m4 .= "m4_include([$i])\n"; 770 } 771} 772 773############################################################################## 774# Find and remove stale files 775 776sub find_and_delete { 777 foreach my $file (@_) { 778 my $removed = 0; 779 if (-f $file) { 780 unlink($file); 781 $removed = 1; 782 } 783 if (-f "config/$file") { 784 unlink("config/$file"); 785 $removed = 1; 786 } 787 debug " Removed stale copy of $file\n" 788 if ($removed); 789 } 790} 791 792############################################################################## 793# Find a specific executable and ensure that it is a recent enough 794# version. 795 796sub find_and_check { 797 my ($app, $app_name, $req_version) = @_; 798 799 my @search_path = split(/;/, $app_name); 800 my @min_version = split(/\./, $req_version); 801 my @versions_found = (); 802 803 foreach (@search_path) { 804 verbose " Searching for $_\n"; 805 my $version = `$_ --version`; 806 if (!defined($version)) { 807 verbose " $_ not found\n"; 808 next; 809 } 810 811 # Matches a version string with 1 or more parts possibly prefixed with a letter (ex: 812 # v2.2) or followed by a letter (ex: 2.2.6b). This regex assumes there is a space 813 # before the version string and that the version is ok if there is no version. 814 if (!($version =~ m/\s[vV]?(\d[\d\.]*\w?)/m)) { 815 verbose " WARNING: $_ does not appear to support --version. Assuming it is ok\n"; 816 817 return; 818 } 819 820 $version = $1; 821 822 verbose " Found $_ version $version; checking version...\n"; 823 push(@versions_found, $version); 824 825 my @parts = split(/\./, $version); 826 my $i = 0; 827 # Check every component of the version number 828 while ($i <= $#min_version) { 829 verbose " Found version component $parts[$i] -- need $min_version[$i]\n"; 830 831 # Check to see if there are any characters (!) in the 832 # version number (e.g., Libtool's "2.2.6b" -- #%@#$%!!!). 833 # Do separate comparisons between the number and any 834 # trailing digits. You can't just "lt" compare the whole 835 # string because "10 lt 2b" will return true. #@$@#$#@$ 836 # Libtool!! 837 $parts[$i] =~ m/(\d+)([a-z]*)/i; 838 my $pn = $1; 839 my $pa = $2; 840 $min_version[$i] =~ m/(\d+)([a-z]*)/i; 841 my $mn = $1; 842 my $ma = $2; 843 844 # If the version is higher, we're done. 845 if ($pn > $mn) { 846 verbose " ==> ACCEPTED\n"; 847 return; 848 } 849 # If the version is lower, we're done. 850 elsif ($pn < $mn || 851 ($pn == $mn && $pa lt $ma)) { 852 verbose " ==> Too low! Skipping this version\n"; 853 last; 854 } 855 856 # If the version was equal, keep checking. 857 ++$i; 858 } 859 860 # If we found a good version, return. 861 if ($i > $#min_version) { 862 verbose " ==> ACCEPTED\n"; 863 return; 864 } 865 } 866 867 # if no acceptable version found, reject it 868 print " 869================================================================= 870I could not find a recent enough copy of $app. 871I need at least $req_version, but only found the following versions:\n\n"; 872 873 my $i = 0; 874 foreach (@search_path) { 875 print " $_: $versions_found[$i]\n"; 876 $i++; 877 } 878 879 print "\nI am gonna abort. :-( 880 881Please make sure you are using at least the following versions of the 882tools: 883 884 GNU Autoconf: $ompi_autoconf_version 885 GNU Automake: $ompi_automake_version 886 GNU Libtool: $ompi_libtool_version 887=================================================================\n"; 888 my_exit(1); 889} 890 891############################################################################## 892 893sub safe_system { 894 print "Running: " . join(/ /, @_) . "\n"; 895 my $ret = system(@_); 896 $ret >>= 8; 897 if (0 != $ret) { 898 print "Command failed: @_\n"; 899 my_exit($ret); 900 } 901 $ret; 902} 903 904############################################################################## 905 906sub patch_autotools_output { 907 my ($topdir) = @_; 908 909 # Set indentation string for verbose output depending on current directory. 910 my $indent_str = " "; 911 if ($topdir eq ".") { 912 $indent_str = "=== "; 913 } 914 915 # Patch ltmain.sh error for PGI version numbers. Redirect stderr to 916 # /dev/null because this patch is only necessary for some versions of 917 # Libtool (e.g., 2.2.6b); it'll [rightfully] fail if you have a new 918 # enough Libtool that doesn't need this patch. But don't alarm the 919 # user and make them think that autogen failed if this patch fails -- 920 # make the errors be silent. 921 # Also patch ltmain.sh for NAG compiler 922 if (-f "config/ltmain.sh") { 923 verbose "$indent_str"."Patching PGI compiler version numbers in ltmain.sh\n"; 924 system("$patch_prog -N -p0 < $topdir/config/ltmain_pgi_tp.diff >/dev/null 2>&1"); 925 unlink("config/ltmain.sh.rej"); 926 927 verbose "$indent_str"."Patching \"-pthread\" option for NAG compiler in ltmain.sh\n"; 928 system("$patch_prog -N -p0 < $topdir/config/ltmain_nag_pthread.diff >/dev/null 2>&1"); 929 unlink("config/ltmain.sh.rej"); 930 } 931 932 # If there's no configure script, there's nothing else to do. 933 return 934 if (! -f "configure"); 935 my @verbose_out; 936 937 # Total ugh. We have to patch the configure script itself. See below 938 # for explanations why. 939 open(IN, "configure") || my_die "Can't open configure"; 940 my $c; 941 $c .= $_ 942 while(<IN>); 943 close(IN); 944 my $c_orig = $c; 945 946 # LT <=2.2.6b need to be patched for the PGI 10.0 fortran compiler 947 # name (pgfortran). The following comes from the upstream LT patches: 948 # http://lists.gnu.org/archive/html/libtool-patches/2009-11/msg00012.html 949 # http://lists.gnu.org/archive/html/bug-libtool/2009-11/msg00045.html 950 # Note that that patch is part of Libtool (which is not in this OMPI 951 # source tree); we can't fix it. So all we can do is patch the 952 # resulting configure script. :-( 953 push(@verbose_out, $indent_str . "Patching configure for Libtool PGI 10 fortran compiler name\n"); 954 $c =~ s/gfortran g95 xlf95 f95 fort ifort ifc efc pgf95 lf95 ftn/gfortran g95 xlf95 f95 fort ifort ifc efc pgfortran pgf95 lf95 ftn/g; 955 $c =~ s/pgcc\* \| pgf77\* \| pgf90\* \| pgf95\*\)/pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)/g; 956 $c =~ s/pgf77\* \| pgf90\* \| pgf95\*\)/pgf77* | pgf90* | pgf95* | pgfortran*)/g; 957 958 # Similar issue as above -- the PGI 10 version number broke <=LT 959 # 2.2.6b's version number checking regexps. Again, we can't fix the 960 # Libtool install; all we can do is patch the resulting configure 961 # script. :-( The following comes from the upstream patch: 962 # http://lists.gnu.org/archive/html/libtool-patches/2009-11/msg00016.html 963 push(@verbose_out, $indent_str . "Patching configure for Libtool PGI version number regexps\n"); 964 $c =~ s/\*pgCC\\ \[1-5\]\* \| \*pgcpp\\ \[1-5\]\*/*pgCC\\ [1-5]\.* | *pgcpp\\ [1-5]\.*/g; 965 966 # Similar issue as above -- fix the case statements that handle the Sun 967 # Fortran version strings. 968 # 969 # Note: we have to use octal escapes to match '*Sun\ F*) and the 970 # four succeeding lines in the bourne shell switch statement. 971 # \ = 134 972 # ) = 051 973 # * = 052 974 # 975 # Below is essentially an upstream patch for Libtool which we want 976 # made available to Open MPI users running older versions of Libtool 977 978 foreach my $tag (("", "_FC")) { 979 980 # We have to change the search pattern and substitution on each 981 # iteration to take into account the tag changing 982 my $search_string = '# icc used to be incompatible with GCC.\n\s+' . 983 '# ICC 10 doesn\047t accept -KPIC any more.\n.*\n\s+' . 984 "lt_prog_compiler_wl${tag}="; 985 my $replace_string = "# Flang compiler 986 *flang) 987 lt_prog_compiler_wl${tag}='-Wl,' 988 lt_prog_compiler_pic${tag}='-fPIC -DPIC' 989 lt_prog_compiler_static${tag}='-static' 990 ;; 991 # icc used to be incompatible with GCC. 992 # ICC 10 doesn't accept -KPIC any more. 993 icc* | ifort*) 994 lt_prog_compiler_wl${tag}="; 995 996 push(@verbose_out, $indent_str . "Patching configure for flang Fortran ($tag)\n"); 997 $c =~ s/$search_string/$replace_string/; 998 } 999 1000 foreach my $tag (("", "_FC")) { 1001 1002 # We have to change the search pattern and substitution on each 1003 # iteration to take into account the tag changing 1004 my $search_string = '\052Sun\134 F\052.*\n.*\n\s+' . 1005 "lt_prog_compiler_pic${tag}" . '.*\n.*\n.*\n.*\n'; 1006 my $replace_string = " 1007 *Sun\\ Ceres\\ Fortran* | *Sun*Fortran*\\ [[1-7]].* | *Sun*Fortran*\\ 8.[[0-3]]*) 1008 # Sun Fortran 8.3 passes all unrecognized flags to the linker 1009 lt_prog_compiler_pic${tag}='-KPIC' 1010 lt_prog_compiler_static${tag}='-Bstatic' 1011 lt_prog_compiler_wl${tag}='' 1012 ;; 1013 *Sun\\ F* | *Sun*Fortran*) 1014 lt_prog_compiler_pic${tag}='-KPIC' 1015 lt_prog_compiler_static${tag}='-Bstatic' 1016 lt_prog_compiler_wl${tag}='-Qoption ld ' 1017 ;; 1018"; 1019 1020 push(@verbose_out, $indent_str . "Patching configure for Sun Studio Fortran version strings ($tag)\n"); 1021 $c =~ s/$search_string/$replace_string/; 1022 } 1023 1024 foreach my $tag (("", "_FC")) { 1025 1026 # We have to change the search pattern and substitution on each 1027 # iteration to take into account the tag changing 1028 my $search_string = 'lf95\052.*# Lahey Fortran 8.1\n\s+' . 1029 "whole_archive_flag_spec${tag}=" . '\n\s+' . 1030 "tmp_sharedflag='--shared' ;;" . '\n\s+' . 1031 'xl'; 1032 my $replace_string = "lf95*) # Lahey Fortran 8.1 1033 whole_archive_flag_spec${tag}= 1034 tmp_sharedflag='--shared' ;; 1035 nagfor*) # NAGFOR 5.3 1036 tmp_sharedflag='-Wl,-shared';; 1037 xl"; 1038 1039 push(@verbose_out, $indent_str . "Patching configure for NAG compiler ($tag)\n"); 1040 $c =~ s/$search_string/$replace_string/; 1041 } 1042 1043 # Oracle has apparently begun (as of 12.5-beta) removing the "Sun" branding. 1044 # So this patch (cumulative over the previous one) is required. 1045 push(@verbose_out, $indent_str . "Patching configure for Oracle Studio Fortran version strings\n"); 1046 $c =~ s/\*Sun\*Fortran\*\)/*Sun*Fortran* | *Studio*Fortran*)/g; 1047 $c =~ s/\*Sun\\ F\*\)(.*\n\s+tmp_sharedflag=)/*Sun\\ F* | *Studio*Fortran*)$1/g; 1048 1049 # See http://git.savannah.gnu.org/cgit/libtool.git/commit/?id=v2.2.6-201-g519bf91 for details 1050 # Note that this issue was fixed in LT 2.2.8, however most distros are still using 2.2.6b 1051 1052 push(@verbose_out, $indent_str . "Patching configure for IBM xlf libtool bug\n"); 1053 $c =~ s/(\$LD -shared \$libobjs \$deplibs \$)compiler_flags( -soname \$soname)/$1linker_flags$2/g; 1054 1055 #Check if we are using a recent enough libtool that supports PowerPC little endian 1056 if(index($c, 'powerpc64le-*linux*)') == -1) { 1057 push(@verbose_out, $indent_str . "Patching configure for PowerPC little endian support\n"); 1058 my $replace_string = "x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*|"; 1059 $c =~ s/x86_64-\*kfreebsd\*-gnu\|x86_64-\*linux\*\|ppc\*-\*linux\*\|powerpc\*-\*linux\*\|/$replace_string/g; 1060 $replace_string = 1061 "powerpc64le-*linux*)\n\t LD=\"\${LD-ld} -m elf32lppclinux\"\n\t ;;\n\t powerpc64-*linux*)"; 1062 $c =~ s/ppc64-\*linux\*\|powerpc64-\*linux\*\)/$replace_string/g; 1063 $replace_string = 1064 "powerpcle-*linux*)\n\t LD=\"\${LD-ld} -m elf64lppc\"\n\t ;;\n\t powerpc-*linux*)"; 1065 $c =~ s/ppc\*-\*linux\*\|powerpc\*-\*linux\*\)/$replace_string/g; 1066 } 1067 1068 # Fix consequence of broken libtool.m4 1069 # see http://lists.gnu.org/archive/html/bug-libtool/2015-07/msg00002.html and 1070 # https://github.com/open-mpi/ompi/issues/751 1071 push(@verbose_out, $indent_str . "Patching configure for -L/-R libtool.m4 bug\n"); 1072 # patch for libtool < 2.4.3 1073 $c =~ s/# Some compilers place space between "-\{L,R\}" and the path.\n # Remove the space.\n if test \$p = \"-L\" \|\|/# Some compilers place space between "-\{L,-l,R\}" and the path.\n # Remove the spaces.\n if test \$p = \"-L\" \|\|\n test \$p = \"-l\" \|\|/g; 1074 # patch for libtool >= 2.4.3 1075 $c =~ s/# Some compilers place space between "-\{L,R\}" and the path.\n # Remove the space.\n if test x-L = \"\$p\" \|\|\n test x-R = \"\$p\"\; then/# Some compilers place space between "-\{L,-l,R\}" and the path.\n # Remove the spaces.\n if test x-L = \"x\$p\" \|\|\n test x-l = \"x\$p\" \|\|\n test x-R = \"x\$p\"\; then/g; 1076 1077 # Fix OS X Big Sur (11.0.x) support 1078 # From https://lists.gnu.org/archive/html/libtool-patches/2020-06/msg00001.html 1079 push(@verbose_out, $indent_str . "Patching configure for MacOS Big Sur libtool.m4 bug\n"); 1080 # Some versions of Libtool use ${wl} consistently, but others did 1081 # not (e.g., they used $wl). Make the regexp be able to handle 1082 # both. Additionally, the case string searching for 10.[012]* 1083 # changed over time. So make sure it can handle both of the case 1084 # strings that we're aware of. 1085 my $WL = '(\$\{wl\}|\$wl)'; 1086 my $SOMETIMES = '(\[,.\])*'; 1087 my $search_string = 'darwin\*\) # darwin 5.x on 1088 # if running on 10.5 or later, the deployment target defaults 1089 # to the OS version, if on x86, and 10.4, the deployment 1090 # target defaults to 10.4. Don\'t you love it\? 1091 case \$\{MACOSX_DEPLOYMENT_TARGET-10.0\},\$host in 1092 10.0,\*86\*-darwin8\*\|10.0,\*-darwin\[91\]\*\) 1093 _lt_dar_allow_undefined=\'' . $WL . '-undefined ' . $WL . 'dynamic_lookup\' ;; 1094 10.\[012\]' . $SOMETIMES . '\*\) 1095 _lt_dar_allow_undefined=\'' . $WL . '-flat_namespace ' . $WL . '-undefined ' . $WL . 'suppress\' ;; 1096 10.\*\)'; 1097 my $replace_string = 'darwin*) 1098 # Open MPI patched for Darwin / MacOS Big Sur. See 1099 # http://lists.gnu.org/archive/html/bug-libtool/2015-07/msg00001.html 1100 case ${MACOSX_DEPLOYMENT_TARGET},$host in 1101 10.[012],*|,*powerpc*) 1102 _lt_dar_allow_undefined=\'${wl}-flat_namespace ${wl}-undefined ${wl}suppress\' ;; 1103 *)'; 1104 $c =~ s/$search_string/$replace_string/g; 1105 1106 # Only write out verbose statements and a new configure if the 1107 # configure content actually changed 1108 return 1109 if ($c eq $c_orig); 1110 foreach my $str (@verbose_out) { 1111 verbose($str); 1112 } 1113 1114 open(OUT, ">configure.patched") || my_die "Can't open configure.patched"; 1115 print OUT $c; 1116 close(OUT); 1117 # Use cp so that we preserve permissions on configure 1118 safe_system("cp configure.patched configure"); 1119 unlink("configure.patched"); 1120} 1121 1122sub in_tarball { 1123 my $tarball = 0; 1124 open(IN, "VERSION") || my_die "Can't open VERSION"; 1125 # If repo_rev is not an empty string, we are in a tarball 1126 while (<IN>) { 1127 my $line = $_; 1128 my @fields = split(/=/,$line); 1129 if ($fields[0] eq "repo_rev") { 1130 if ($fields[1] ne "\n") { 1131 $tarball = 1; 1132 last; 1133 } 1134 } 1135 } 1136 close(IN); 1137 return $tarball; 1138} 1139 1140############################################################################## 1141 1142sub replace_config_sub_guess { 1143 # This could be simpler if we could use some Perl modules for this 1144 # functionality (e.g., DateTime). But I don't want to introduce 1145 # any CPAN dependencies here, so just do sometime simple, even if 1146 # it's a bit laborious. Use a few private helper functions for 1147 # this kind of functionality. 1148 1149 sub _get_timestamp { 1150 my $filename = shift; 1151 1152 my $ret; 1153 if (-x $filename) { 1154 my $out = `$filename --version`; 1155 $out =~ m/GNU config\.[a-z]+ \((.+)\)/; 1156 $ret = $1; 1157 } 1158 1159 return $ret; 1160 } 1161 1162 sub _split_timestamp { 1163 my $ts = shift; 1164 1165 $ts =~ m/(\d+)-(\d+)-(\d+)/; 1166 return $1, $2, $3; 1167 } 1168 1169 # Returns true if timestamp $a > timestamp $b. 1170 sub _timestamp_gt { 1171 my ($a, $b) = @_; 1172 1173 my ($year_a, $month_a, $day_a) = _split_timestamp($a); 1174 my ($year_b, $month_b, $day_b) = _split_timestamp($b); 1175 1176 # Don't try to be clever -- just do a simple set of explicit 1177 # comparisons. 1178 if ($year_a > $year_b) { 1179 return 1; 1180 } elsif ($year_a < $year_b) { 1181 return 0; 1182 } else { 1183 if ($month_a > $month_b) { 1184 return 1; 1185 } elsif ($month_a < $month_b) { 1186 return 0; 1187 } else { 1188 if ($day_a > $day_b) { 1189 return 1; 1190 } else { 1191 return 0; 1192 } 1193 } 1194 } 1195 } 1196 1197 my ($topdir) = @_; 1198 1199 # Find the stashed known-good files, and get their version 1200 # timestamps. 1201 my $cached_dir = "$topdir/config/from-savannah"; 1202 my @files = qw/config.guess config.sub/; 1203 my %known_good_timestamps; 1204 foreach my $file (@files) { 1205 my $filename = "$cached_dir/upstream-$file"; 1206 my_die("Cannot find $filename") 1207 if (! -f $filename); 1208 1209 my $ts = _get_timestamp($filename); 1210 $known_good_timestamps{$file} = $ts; 1211 } 1212 1213 # Find all config.guess/config.sub files in the tree. If their 1214 # versions are older than the stashed known-good files, update 1215 # them from the stash. 1216 my @files; 1217 File::Find::find(sub { 1218 push(@files, $File::Find::name) 1219 if ($_ eq "config.guess" || 1220 $_ eq "config.sub") }, $topdir); 1221 1222 foreach my $file (@files) { 1223 # Skip anything in the 3rd-party tree 1224 next 1225 if ($file =~ /\/3rd-party\//); 1226 1227 my $base = basename($file); 1228 my $ts = _get_timestamp($file); 1229 if (_timestamp_gt($known_good_timestamps{$base}, $ts)) { 1230 print("=== Replacing $file with newer version\n"); 1231 safe_system("cp -f $cached_dir/upstream-$base $file"); 1232 } 1233 } 1234} 1235 1236############################################################################## 1237############################################################################## 1238## main - do the real work... 1239############################################################################## 1240############################################################################## 1241 1242# Command line parameters 1243 1244my $ok = Getopt::Long::GetOptions("no-ompi" => \$no_ompi_arg, 1245 "no-orte" => \$no_orte_arg, 1246 "no-oshmem" => \$no_oshmem_arg, 1247 "quiet|q" => \$quiet_arg, 1248 "debug|d" => \$debug_arg, 1249 "help|h" => \$help_arg, 1250 "platform=s" => \$platform_arg, 1251 "include=s" => \$include_arg, 1252 "exclude=s" => \$exclude_arg, 1253 "force|f" => \$force_arg, 1254 ); 1255 1256if (!$ok || $help_arg) { 1257 print "Invalid command line argument.\n\n" 1258 if (!$ok); 1259 print "Options: 1260 --no-ompi | -no-ompi Do not build the Open MPI layer 1261 --no-orte | -no-orte Do not build the ORTE layer 1262 --no-oshmem | -no-oshmem Do not build the OSHMEM layer 1263 --quiet | -q Do not display normal verbose output 1264 --debug | -d Output lots of debug information 1265 --help | -h This help list 1266 --platform | -p Specify a platform file to be parsed for no_build 1267 and only_build directives 1268 --include | -i Comma-separated list of framework-component pairs 1269 to be exclusively built - i.e., all other components 1270 will be ignored and only those specified will be marked 1271 to build 1272 --exclude | -e Comma-separated list of framework or framework-component 1273 to be excluded from the build 1274 --force | -f Run even if invoked from the source tree of an expanded 1275 distribution tarball\n"; 1276 my_exit($ok ? 0 : 1); 1277} 1278 1279#--------------------------------------------------------------------------- 1280 1281# Check for project existence 1282my $project_name_long = "Open MPI"; 1283my $project_name_short = "openmpi"; 1284 1285if (! -e "ompi") { 1286 $no_ompi_arg = 1; 1287 debug "No ompi subdirectory found - will not build MPI layer\n"; 1288} 1289if (! -e "orte") { 1290 $no_orte_arg = 1; 1291 debug "No orte subdirectory found - will not build ORTE\n"; 1292} 1293if (! -e "oshmem") { 1294 $no_oshmem_arg = 1; 1295 debug "No oshmem subdirectory found - will not build OSHMEM\n"; 1296} 1297 1298if (-e "orcm") { 1299 # bozo check - ORCM requires ORTE 1300 if ($no_orte_arg == 1) { 1301 print "Cannot build ORCM without ORTE\n"; 1302 my_exit(1); 1303 } 1304 $project_name_long = "Open Resilient Cluster Manager"; 1305 $project_name_short = "open-rcm"; 1306} elsif ($no_ompi_arg == 1) { 1307 if ($no_orte_arg == 0) { 1308 $project_name_long = "Open MPI Run Time Environment"; 1309 $project_name_short = "open-rte"; 1310 } else { 1311 $project_name_long = "Open Portability Access Layer"; 1312 $project_name_short = "open-pal"; 1313 } 1314} 1315 1316#--------------------------------------------------------------------------- 1317 1318$full_hostname = `hostname`; 1319chomp($full_hostname); 1320 1321$m4 = "dnl 1322dnl \$HEADER\$ 1323dnl 1324$dnl_line 1325dnl This file is automatically created by autogen.pl; it should not 1326dnl be edited by hand!! 1327dnl 1328dnl Generated by $username at " . localtime($ENV{SOURCE_DATE_EPOCH} || time) . " 1329dnl on $full_hostname. 1330$dnl_line\n\n"; 1331 1332#--------------------------------------------------------------------------- 1333 1334# Verify that we're in the OMPI root directorty by checking for a token file. 1335 1336my_die "Not at the root directory of an OMPI source tree" 1337 if (! -f "config/opal_try_assemble.m4"); 1338 1339my_die "autogen.pl has been invoked in the source tree of an Open MPI distribution tarball; aborting... 1340You likely do not need to invoke \"autogen.pl\" -- you can probably run \"configure\" directly. 1341If you really know what you are doing, and really need to run autogen.pl, use the \"--force\" flag." 1342 if (!$force_arg && in_tarball()); 1343 1344# Now that we've verified that we're in the top-level OMPI directory, 1345# set the sentinel file to remove if we abort. 1346$sentinel = Cwd::cwd() . "/configure"; 1347 1348#--------------------------------------------------------------------------- 1349 1350my $step = 1; 1351verbose "Open MPI autogen (buckle up!) 1352 1353$step. Checking tool versions\n\n"; 1354 1355# Check the autotools revision levels 1356&find_and_check("autoconf", $ompi_autoconf_search, $ompi_autoconf_version); 1357&find_and_check("libtool", $ompi_libtoolize_search, $ompi_libtool_version); 1358&find_and_check("automake", $ompi_automake_search, $ompi_automake_version); 1359 1360#--------------------------------------------------------------------------- 1361 1362# Save the platform file in the m4 1363$m4 .= "dnl Platform file\n"; 1364 1365# Process platform arg, if provided 1366if ($platform_arg) { 1367 $m4 .= "m4_define([autogen_platform_file], [$platform_arg])\n\n"; 1368 open(IN, $platform_arg) || my_die "Can't open $platform_arg"; 1369 # Read all lines from the file 1370 while (<IN>) { 1371 my $line = $_; 1372 my @fields = split(/=/,$line); 1373 if ($fields[0] eq "enable_mca_no_build") { 1374 if ($exclude_arg) { 1375 print "The specified platform file includes an 1376enable_mca_no_build line. However, your command line 1377also contains an exclude specification. Only one of 1378these directives can be given.\n"; 1379 my_exit(1); 1380 } 1381 $exclude_arg = $fields[1]; 1382 } elsif ($fields[0] eq "enable_mca_only_build") { 1383 if ($include_arg) { 1384 print "The specified platform file includes an 1385enable_mca_only_build line. However, your command line 1386also contains an include specification. Only one of 1387these directives can be given.\n"; 1388 my_exit(1); 1389 } 1390 $include_arg = $fields[1]; 1391 } 1392 } 1393 close(IN); 1394} else { 1395 # No platform file -- write an empty list 1396 $m4 .= "m4_define([autogen_platform_file], [])\n\n"; 1397} 1398 1399if ($exclude_arg) { 1400 debug "Using exclude list: $exclude_arg"; 1401 my @list = split(/,/, $exclude_arg); 1402 foreach (@list) { 1403 my @pairs = split(/-/, $_); 1404 if (exists($pairs[1])) { 1405 # Remove any trailing newlines 1406 chomp($pairs[1]); 1407 debug " Adding ".$pairs[0]."->".$pairs[1]." to exclude list\n"; 1408 push(@{$exclude_list->{$pairs[0]}}, $pairs[1]); 1409 } else { 1410 debug " Adding $pairs[0] to exclude list\n"; 1411 push(@{$exclude_list->{$pairs[0]}}, "AGEN_EXCLUDE_ALL"); 1412 } 1413 } 1414} 1415if ($include_arg) { 1416 debug "Using include list: $include_arg"; 1417 my @list = split(/,/, $include_arg); 1418 foreach (@list) { 1419 my @pairs = split(/-/, $_); 1420 if (exists($pairs[1])) { 1421 # Remove any trailing newlines 1422 chomp($pairs[1]); 1423 debug " Adding ".$pairs[0]."->".$pairs[1]." to include list\n"; 1424 push(@{$include_list->{$pairs[0]}}, $pairs[1]); 1425 } 1426 # NOTE: it makes no sense to include all as that is the default 1427 # so ignore that scenario here, if given 1428 } 1429} 1430 1431#--------------------------------------------------------------------------- 1432 1433++$step; 1434verbose "\n$step. Running template-generating scripts\n\n"; 1435 1436# These scripts generate fortran header files of different types, but 1437# guaranteed to have the same value (i.e., so humans don't have to 1438# maintain two sets of files, and potentially have values get out of 1439# sync). 1440 1441my @scripts; 1442push(@scripts, "ompi/include/mpif-values.pl"); 1443 1444foreach my $s (@scripts) { 1445 verbose "=== $s\n"; 1446 if (! -x $s) { 1447 print "Cannot find executable $s!\nAborting.\n"; 1448 my_exit(1); 1449 } 1450 if (system($s) != 0) { 1451 print "Script failed: $s\n"; 1452 my_exit(1); 1453 } 1454} 1455 1456#--------------------------------------------------------------------------- 1457 1458# Find projects, frameworks, components 1459++$step; 1460verbose "\n$step. Searching for projects, MCA frameworks, and MCA components\n"; 1461 1462my $ret; 1463 1464# Figure out if we're at the top level of the OMPI tree or not. 1465if (! (-f "VERSION" && -f "configure.ac" && -f $topdir_file)) { 1466 print("\n\nYou must run this script from the top-level directory of the Open MPI tree.\n\n"); 1467 my_exit(1); 1468} 1469 1470# Top-level projects to examine 1471my $projects; 1472push(@{$projects}, { name => "opal", dir => "opal", need_base => 1 }); 1473push(@{$projects}, { name => "orte", dir => "orte", need_base => 1 }) 1474 if (!$no_orte_arg); 1475push(@{$projects}, { name => "ompi", dir => "ompi", need_base => 1 }) 1476 if (!$no_ompi_arg); 1477push(@{$projects}, { name => "oshmem", dir => "oshmem", need_base => 1 }) 1478 if (!$no_ompi_arg && !$no_orte_arg && !$no_oshmem_arg); 1479push(@{$projects}, { name => "orcm", dir => "orcm", need_base => 1 }) 1480 if (-e "orcm"); 1481 1482$m4 .= "dnl Separate m4 define for each project\n"; 1483foreach my $p (@$projects) { 1484 $m4 .= "m4_define([project_$p->{name}], [1])\n"; 1485} 1486 1487$m4 .= "\ndnl Project names 1488m4_define([project_name_long], [$project_name_long]) 1489m4_define([project_name_short], [$project_name_short])\n"; 1490 1491# Setup MCA 1492mca_run_global($projects); 1493 1494#--------------------------------------------------------------------------- 1495 1496# Find MPI extensions and contribs 1497if (!$no_ompi_arg) { 1498 ++$step; 1499 verbose "\n$step. Searching for Open MPI extensions\n\n"; 1500 mpiext_run_global("ompi/mpiext"); 1501 1502 ++$step; 1503 verbose "\n$step. Searching for Open MPI contribs\n\n"; 1504 mpicontrib_run_global("ompi/contrib"); 1505} 1506 1507#--------------------------------------------------------------------------- 1508 1509# Process all subdirs that we found in previous steps 1510++$step; 1511verbose "\n$step. Processing autogen.subdirs directories\n"; 1512 1513if ($#subdirs >= 0) { 1514 foreach my $d (@subdirs) { 1515 process_subdir($d); 1516 } 1517} else { 1518 print "<none found>\n"; 1519} 1520 1521#--------------------------------------------------------------------------- 1522 1523# If we got here, all was good. Run the auto tools. 1524++$step; 1525verbose "\n$step. Running autotools on top-level tree\n\n"; 1526 1527# Remove old versions of the files (this is probably overkill, but...) 1528verbose "==> Remove stale files\n"; 1529find_and_delete(qw/config.guess config.sub depcomp compile install-sh ltconfig 1530 ltmain.sh missing mkinstalldirs libtool/); 1531 1532# Remove the old m4 file and write the new one 1533verbose "==> Writing m4 file with autogen.pl results\n"; 1534unlink($m4_output_file); 1535open(M4, ">$m4_output_file") || 1536 my_die "Can't open $m4_output_file"; 1537print M4 $m4; 1538close(M4); 1539 1540# Generate the version checking script with autom4te 1541verbose "==> Generating opal_get_version.sh\n"; 1542chdir("config"); 1543safe_system("autom4te --language=m4sh opal_get_version.m4sh -o opal_get_version.sh"); 1544 1545# Run autoreconf 1546verbose "==> Running autoreconf\n"; 1547chdir(".."); 1548my $cmd = "autoreconf -ivf --warnings=all,no-obsolete,no-override -I config"; 1549foreach my $project (@{$projects}) { 1550 $cmd .= " -I $project->{dir}/config" 1551 if (-d "$project->{dir}/config"); 1552} 1553safe_system($cmd); 1554 1555patch_autotools_output("."); 1556 1557# Per https://github.com/open-mpi/ompi/issues/8410, replace config.sub 1558# and config.guess with known-good versions if the Autoconf-installed 1559# versions are older. 1560replace_config_sub_guess("."); 1561 1562#--------------------------------------------------------------------------- 1563 1564verbose " 1565================================================ 1566Open MPI autogen: completed successfully. w00t! 1567================================================\n\n"; 1568 1569# Done! 1570exit(0); 1571