ecmwf / ecbuild

A CMake-based build system, consisting of a collection of CMake macros and functions that ease the managing of software build systems
https://ecbuild.readthedocs.io
Apache License 2.0
26 stars 25 forks source link

ecbuild_find_mpi() failures with cmake > 3.9.0 #3

Closed christopherwharrop-noaa closed 5 years ago

christopherwharrop-noaa commented 5 years ago

I have run into a confusing behavior when trying to use ecbuild with versions of cmake newer than 3.9.0. I believe this behavior may have something to do with changes made by the cmake developers to their FindMPI.cmake code, starting in cmake version 3.10. See this link for some explanation:

https://github.com/dealii/dealii/issues/5510#issuecomment-349761025

The behavior I am observing is as follows, and only happens when using cmake newer than 3.9.0. When using the ecbuild bundle feature, and there is more than one bundle component that looks for MPI, the first component will find MPI just fine, but the second one claims that MPI is not found. This causes the cmake configuration step to fail. Switching to cmake version 3.9.0 without changing anything else fixes the issue.

I don't know enough about cmake and ecbuild to determine the exact cause, but I suspect some change to ecbuild_find_mpi() is necessary to accommodate updates to cmake's FindMPI that were made in version 3.10.

I have a very minimal reproducer for this issue that I can send, but here are the basics.

Top-level CMakeLists.txt file:

project( FooBar-bundle Fortran )

cmake_minimum_required( VERSION 3.3.2 FATAL_ERROR )

include( ecbuild_bundle )

ecbuild_bundle_initialize()

ecbuild_requires_macro_version( 2.9 )

ecbuild_bundle( PROJECT foo ./foo )
ecbuild_bundle( PROJECT bar ./bar )

ecbuild_bundle_finalize()

CMakeLists.txt for projects foo and bar:

project (Foo Fortran)

cmake_minimum_required (VERSION 2.6)

# MPI
ecbuild_find_mpi( COMPONENTS Fortran REQUIRED )
ecbuild_include_mpi()
link_libraries(${MPI_Fortran_LIBRARIES})

add_executable(foo.exe foo.f90)
project (Bar Fortran)

cmake_minimum_required (VERSION 2.6)

# MPI
ecbuild_find_mpi( COMPONENTS Fortran REQUIRED )
ecbuild_include_mpi()
link_libraries(${MPI_Fortran_LIBRARIES})

add_executable(bar.exe bar.f90)

To build:

mkdir build
cd build
export FC=mpiifort
ecbuild ..

cmake 3.10 and higher will succeed in finding MPI for "foo", but will fail to find it for "bar". Both manage to find MPI just fine for cmake 3.9.0. I have only tested with ifort 17.0.5.239 using impi 5.1.2.150. I do not know if the behavior is compiler/mpi dependent.

mmiesch commented 5 years ago

I can confirm that this error also occurs on Mac OS using gfortran and openmpi

wdeconinck commented 5 years ago

This error is due to a new FindMPI.cmake file within cmake from 3.10 onwards. My findings are that mpi is found when not explicitly making the fortran compiler an mpi wrapper as done with export FC=mpiifort . Instead, you can use the environment variable MPI_HOME to point to the root of your MPI distribution. e.g.

export FC=ifort
export MPI_HOME=$(which mpiifort)/..
wdeconinck commented 5 years ago

I have fixed this issue anyhow with commit https://github.com/ecmwf/ecbuild/commit/f4623f22d6fc80f3a7d321254ced5a2fb96063c6 Thanks for the reproducer! I still recommend to use MPI_HOME environment variable regardless :)