I need help please. I'm writing a Perl script to configure, compile and install MPICH. The initial two tasks require calling configure
and make
commands. I'm struggling to pass the options to configure
command. Please find my minimal example below:
#!/usr/local/bin/perl
use v5.38;
use autodie;
use strict;
use warnings;
use IPC::System::Simple qw(capturex);
# Writes text into given file
sub writef($fname, $txt) {
open my $fh, ">:encoding(UTF-8)", $fname;
print $fh $txt;
close $fh;
}
my $gnubin ='/opt/local/bin';
my $prefix ='/opt/mpich-4.1.2';
my $np = 8;
my $txt;
print "Setting environment variables...\n";
$ENV{'FC'} = $gnubin . '/gfortran';
$ENV{'F77'} = $ENV{'FC'};
$ENV{'CC'} = $gnubin . '/gcc';
$ENV{'CXX'} = $gnubin . '/g++';
$ENV{'FFLAGS'} = '-m64 -fallow-argument-mismatch';
$ENV{'CFLAGS'} = '-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -m64';
mkdir 'build';
chdir 'build';
print "Configuring MPICH...\n";
my $conf_options = "--prefix=$prefix --enable-shared=no --enable-fast=O3,ndebug --disable-error-checking --enable-fortran=all --enable-cxx --disable-opencl --enable-romio --without-timing --without-mpit-pvars";
$txt = capturex('../configure', $conf_options);
&writef('c.txt', $txt);
print "Compiling MPICH...\n";
$txt = capturex('make', '-j', $np);
&writef('m.txt', $txt);
Configuration is done correctly, but compilation fails with the following error messages:
gcc: error: unrecognized command-line option '--without-timing'
gcc: error: unrecognized command-line option '--without-mpit-pvars/etc"'
gcc: error: unrecognized command-line option '--without-mpit-pvars/lib/libfabric"'
It seems I have a problem in the capturex
call. I suspect there are no spaces in between the $conf_options
when they are passed to capturex
command. I tried declaring configure options as an array my @conf_options
and passing the strings in the qq()
operator. But that fails with a similar set of errors. Any help would be greatly appreciated.
Instead of passing arguments, you are passing part of a shell command to a sub that doesn't invoke a shell.
Replace
my $conf_options = "--prefix=$prefix --enable-shared=no ...";
my $txt = capturex( "../configure", $conf_options );
with
my @conf_options = ( "--prefix=$prefix", "--enable-shared=no", "..." );
my $txt = capturex( "../configure", @conf_options );
or
use String::ShellQuote qw( shell_quote );
my $prefix_lit = shell_quote( $prefix );
my $conf_options = "--prefix=$prefix_lit --enable-shared=no ...";
my $txt = capture( "../configure $conf_options" );
The former doesn't use a shell, while the latter does.