Dear all,
I have an issue which relates to the parsing of libraries for the linking step.
To reproduce this error, I have used automake 2.71 and OpenMPI 4.1.2
Consider this configure.ac:
AC_INIT([bug_mpi], [0], [dummy])
AM_INIT_AUTOMAKE
AC_PROG_CC
AC_PROG_FC
AC_PROG_CXX
LT_INIT
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
And Makefile.am:
lib_LTLIBRARIES = libtest.la
libtest_la_SOURCES = test_f.f90 test_c.c
i.e. a library is supposed to be created from a C and a Fortran source file. The explicit form of the source files is irrelevant.
I configure and build with MPI: ./configure CC=mpicc FC=mpif90 CXX=mpic++
Which leads to the following error message:
/usr/bin/ld: cannot find -l-L/opt/bm/gcc-10.2.0/lib/gcc/x86_64-pc-linux-gnu/10.2.0
This is due to empty “-l” commands in the linker command. I could find out that this originates from the call of “mpif90 -v”, which configure uses to create the list of libraries to link. Explicitly, in my case I get
mpif90 -v test.f90 2>&1 | grep Driving
Driving: /opt/bm/gcc-10.2.0/bin/gfortran -v test.f90 -I/opt/bm/hpcx-v2.10-gcc-MLNX_OFED_LINUX-5-redhat8-cuda11-gdrcopy2-nccl2.11-x86_64/hpcx-rebuild-gcc-9.2.0-mt.sh/include -pthread -I/opt/bm/hpcx-v2.10-gcc-MLNX_OFED_LINUX-5-redhat8-cuda11-gdrcopy2-nccl2.11-x86_64/hpcx-rebuild-gcc-9.2.0-mt.sh/lib
-L/opt/bm/hpcx-v2.10-gcc-MLNX_OFED_LINUX-5-redhat8-cuda11-gdrcopy2-nccl2.11-x86_64/hpcx-rebuild-gcc-9.2.0-mt.sh/lib -Wl,-rpath -Wl,/opt/bm/hpcx-v2.10-gcc-MLNX_OFED_LINUX-5-redhat8-cuda11-gdrcopy2-nccl2.11-x86_64/hpcx-rebuild-gcc-9.2.0-mt.sh/lib -Wl,--enable-new-dtags
-lmpi_usempif08 -lmpi_usempi_ignore_tkr -lmpi_mpifh -lmpi -l gfortran -l m
-shared-libgcc
Note the highlighted libraries which have a space between the “-l” and the library name. This string occurs in the postdeps variable of the libtool script.
I am aware that the existence of that extra space originates from OpenMPI. I have observed this with a few other OpenMPI installations, but other MPI implementations might not have it.
However, I found the following in the configure script:
for p in `eval "$output_verbose_link_cmd"`; do
case ${prev}${p} in
-L* | -R* | -l*)
# Some compilers place space between "-{L,R}" and the path.
# Remove the space.
if test $p = "-L" ||
test $p = "-R"; then
prev=$p
continue
fi
Here, you explicitly check for spaces within -L and -R statements. If I add “-l” to this, the build succeeds.
Maybe this check could be automatically generated, too?
Best regards,
Christian
Dr. Christian Weiss
Benchmark Analyst
Tel: +49 211 5369 126
NEC Deutschland GmbH
Geschäftsführer Yuichi Kojima
Handelsregister Düsseldorf HRB 57941; VAT ID DE129424743