1#! @PERL@ -w
2# -*- perl -*-
3#
4# Note that we use an interpreter value ("PERL") from configure
5# because even "#!/usr/bin/env perl" to all systems (e.g., NetBSD).
6#
7# Copyright (c) 2009-2012 Cisco Systems, Inc.  All rights reserved.
8# Copyright (c) 2010      Oracle and/or its affiliates.  All rights reserved.
9# Copyright (c) 2013      Sandia National Laboratories.  All rights reserved.
10# Copyright (c) 2016      IBM Corporation.  All rights reserved.
11# Copyright (c) 2016      Research Organization for Information Science
12#                         and Technology (RIST). All rights reserved.
13# $COPYRIGHT$
14#
15# Additional copyrights may follow
16#
17# $HEADER$
18#
19
20use File::Basename;
21use File::Spec::Functions;
22
23my $includedir = "@OMPI_WRAPPER_INCLUDEDIR@";
24my $libdir = "@OMPI_WRAPPER_LIBDIR@";
25
26# obey the OPAL_DESTDIR environment variable
27if (exists($ENV{'OPAL_DESTDIR'})
28  && defined($ENV{'OPAL_DESTDIR'})
29  && (length($ENV{'OPAL_DESTDIR'}) > 0)) {
30    my $ddir = $ENV{'OPAL_DESTDIR'};
31
32    $includedir = catdir($ddir, $includedir);
33    $libdir = catdir($ddir, $libdir);
34}
35
36my $CC = "@WRAPPER_CC@";
37my $CXX = "@CXX@";
38my $FC = "@FC@";
39my $extra_cppflags = "@OMPI_WRAPPER_EXTRA_CPPFLAGS@";
40my $extra_cflags = "@OMPI_WRAPPER_EXTRA_CFLAGS@";
41my $extra_cflags_prefix = "@OMPI_WRAPPER_EXTRA_CFLAGS_PREFIX@";
42my $extra_cxxflags = "@OMPI_WRAPPER_EXTRA_CXXFLAGS@";
43my $extra_cxxflags_prefix = "@OMPI_WRAPPER_EXTRA_CXXFLAGS_PREFIX@";
44my $extra_fcflags = "@OMPI_WRAPPER_EXTRA_FCFLAGS@";
45my $extra_fcflags_prefix = "@OMPI_WRAPPER_EXTRA_FCFLAGS_PREFIX@";
46my $extra_ldflags = "@OMPI_PKG_CONFIG_LDFLAGS@";
47my $extra_libs = "@OMPI_WRAPPER_EXTRA_LIBS@";
48my $cxx_lib = "@OMPI_WRAPPER_CXX_LIB@";
49my $fc_module_flag = "@OMPI_FC_MODULE_FLAG@";
50my $dynamic_lib_suffix = "@OPAL_DYN_LIB_SUFFIX@";
51my $fortran_libs = "@OMPI_FORTRAN_USEMPIF08_LIB@ @OMPI_FORTRAN_USEMPI_LIB@";
52my $ompi_libmpi_name = "@OMPI_LIBMPI_NAME@";
53
54# Someone might want to fix for windows
55my $include_flag = "-I";
56my $libdir_flag = "-L";
57
58my $lang = "none";
59my $comp = ""; # this is a sentinal from configure
60my $preproc_flags = $include_flag . $includedir;
61my $comp_flags = "";
62my $comp_flags_prefix = "";
63my $linker_flags = $libdir_flag . $libdir . " " . $extra_ldflags;
64# Note that per https://svn.open-mpi.org/trac/ompi/ticket/3422, we
65# intentionally only link in the MPI libraries (ORTE, OPAL, etc. are
66# pulled in implicitly) because we intend MPI applications to only use
67# the MPI API.
68my $libs = "-l".$ompi_libmpi_name." " . $extra_libs;
69my $libs_static = "-l".$ompi_libmpi_name." -lopen-rte -lopen-pal " . $extra_libs;
70
71my $have_dynamic = 0;
72if (-e $libdir . "/lib".$ompi_libmpi_name."." . $dynamic_lib_suffix) {
73    $have_dynamic = 1;
74}
75my $have_static = 0;
76if (-e $libdir . "/lib".$ompi_libmpi_name.".a") {
77    $have_static = 1;
78}
79
80# run flags through regex to fix directories...
81$extra_cppflags =~ s/\$\{includedir\}/$includedir/g;
82$extra_cflags =~ s/\$\{includedir\}/$includedir/g;
83$extra_cflags_prefix =~ s/\$\{includedir\}/$includedir/g;
84$extra_cxxflags =~ s/\$\{includedir\}/$includedir/g;
85$extra_cxxflags_prefix =~ s/\$\{includedir\}/$includedir/g;
86$extra_fcflags =~ s/\$\{includedir\}/$includedir/g;
87$extra_fcflags_prefix =~ s/\$\{includedir\}/$includedir/g;
88$extra_ldflags =~ s/\$\{libdir\}/$libdir/g;
89$extra_libs =~ s/\$\{libdir\}/$libdir/g;
90
91sub check_env {
92    my $envvar = shift;
93    my $str = shift;
94
95    foreach my $var (("OMPI_MPI", "OMPI_")) {
96        my $testvar = $var . $envvar;
97        if (exists($ENV{$testvar})) {
98            $str = $ENV{$testvar};
99            return $str;
100        }
101    }
102
103    return $str;
104}
105
106
107if (basename($0) eq "mpicc") {
108    $lang = "C";
109    $comp = check_env("CC", $CC);
110    $preproc_flags .= " " . $extra_cppflags;
111    $comp_flags = $extra_cflags;
112    $comp_flags_prefix = $extra_cflags_prefix;
113    # no special libs for C
114} elsif (basename($0) eq "mpic++" || basename($0) eq "mpiCC" || basename($0) eq "mpicxx") {
115    $lang = "C++";
116    $comp = check_env("CXX", $CXX);
117    $preproc_flags .= " " . $extra_cppflags;
118    $comp_flags = $extra_cxxflags;
119    $comp_flags_prefix = $extra_cxxflags_prefix;
120    $libs = $cxx_lib . " " . $libs;
121}
122# mpifort is now preferred; mpif77/mpif90 are legacy names
123elsif (basename($0) eq "mpifort" ||
124         basename($0) eq "mpif77" || basename($0) eq "mpif90") {
125    $lang = "Fortran";
126    $comp = check_env("FC", $FC);
127    # no extra includes for Fortran.
128    $comp_flags = $extra_fcflags;
129    $comp_flags_prefix = $extra_fcflags_prefix;
130    $libs = $fortran_libs . " -l".$ompi_libmpi_name."_mpifh " . $libs;
131}
132
133if ($lang eq "none") {
134    print "Could not determine requested language\n";
135    exit 1;
136}
137if ($comp eq "") {
138    print "Unfortunately, this installation of Open MPI was not compiled with\n";
139    print $lang . " support.  As such, the " . $lang . " compiler is non-functional.\n";
140    exit 1;
141}
142
143# figure out what user wants
144my @args = @ARGV;
145my $want_preproc = 1;
146my $want_compile = 1;
147my $want_link = 1;
148my $want_pmpi = 0;
149my $dry_run = 0;
150my $disable_flags = 1;
151my $real_flag = 0;
152my @appargs = ();
153my $want_static = 0;
154
155while (scalar(@args) > 0) {
156    my $arg = shift(@args);
157
158    if ($arg eq "-showme" || $arg eq "--showme") {
159        $dry_run = 1;
160    } elsif ($arg eq "-lpmpi") {
161        $want_pmpi = 1;
162    } elsif ($arg eq "--openmpi:linkall") {
163        $libs = $libs_static;
164    } else {
165        if ($arg eq "-c") {
166            $want_link = 0;
167            $real_flag = 1;
168        } elsif ($arg eq "-E" || $arg eq "-M") {
169            $want_compile = 0;
170            $want_link = 0;
171            $real_flag = 1;
172        } elsif ($arg eq "-S") {
173            $want_link = 0;
174            $real_flag = 1;
175        } elsif ($arg eq "-static" ||
176                  $arg eq "--static" ||
177                  $arg eq "-Bstatic" ||
178                  $arg eq "-Wl,-static" ||
179                  $arg eq "-Wl,--static" ||
180                  $arg eq "-Wl,-Bstatic") {
181            $want_static = 1;
182            $real_flag = 1;
183        } elsif ($arg eq "-dynamic" ||
184                  $arg eq "--dynamic" ||
185                  $arg eq "-Bdynamic" ||
186                  $arg eq "-Wl,-dynamic" ||
187                  $arg eq "-Wl,--dynamic" ||
188                  $arg eq "-Wl,-Bdynamic") {
189            $want_static = 0;
190            $real_flag = 1;
191        } elsif ($arg =~ /^-.*/) {
192            $real_flag = 1;
193        } else {
194            $real_flag = 1;
195            $disable_flags = 0;
196        }
197        push(@appargs, $arg);
198    }
199}
200
201if ($disable_flags == 1 && !($dry_run == 1 && $real_flag == 0)) {
202    $want_preproc = $want_compile = $want_link = 0;
203}
204
205if ($want_static == 1 || $have_dynamic == 0) {
206    $libs = $libs_static;
207}
208
209my @exec_argv = ();
210
211# assemble command
212push(@exec_argv, split(' ', $comp));
213# Per tickets https://svn.open-mpi.org/trac/ompi/ticket/2474, and
214# https://svn.open-mpi.org/trac/ompi/ticket/2201, construct command
215# with some system arguments before user arguments and some after.
216if ($want_compile == 1) {
217    push(@exec_argv, split(' ', $comp_flags_prefix));
218}
219push(@exec_argv, @appargs);
220if ($want_preproc == 1) {
221    push(@exec_argv, split(' ', $preproc_flags));
222}
223if ($want_compile == 1) {
224    push(@exec_argv, split(' ', $comp_flags));
225}
226if ($want_link == 1) {
227    push(@exec_argv, split(' ', $linker_flags));
228    push(@exec_argv, split(' ', $libs));
229}
230
231if ($dry_run == 1) {
232    print join(" ", @exec_argv) . "\n";
233    exit 0;
234}
235
236$cmd = shift(@exec_argv);
237if ($real_flag == 0) {
238    @exec_argv = ();
239}
240exec($cmd, (@exec_argv)) || die "Could not exec " . $exec_argv[0] . ": $!\n";
241