Skip to content

Commit

Permalink
Consolidate build framework
Browse files Browse the repository at this point in the history
- Target based CMake build
- Dropped legacy make build framework
- Export file for CMake based build (exports MpiFx::MpiFx)
- Export file for Pkg-Conf base builds
- Preprocessor fypp is an external dependency now
  • Loading branch information
aradi committed Sep 29, 2020
1 parent 88244ca commit ddf3dbc
Show file tree
Hide file tree
Showing 26 changed files with 426 additions and 4,066 deletions.
25 changes: 17 additions & 8 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,25 +1,34 @@
os: linux
dist: bionic
dist: focal

language: python
python: 3.7


env:
- BUILD_SHARED_LIBS=false
- BUILD_SHARED_LIBS=true
- BUILD_SHARED_LIBS=False
- BUILD_SHARED_LIBS=True

addons:
apt:
packages:
apt:
packages:
- cmake
- gfortran
- libblas-dev
- liblapack-dev
- libopenmpi-dev

install:
- pip install fypp
- pip install fypp

script:
- mkdir -p _build && pushd _build && cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$PWD/install -DBUILD_SHARED_LIBS=${BUILD_SHARED_LIBS} .. && make -j all install && popd
- >
FC=gfortran cmake -DBUILD_SHARED_LIBS=${BUILD_SHARED_LIBS} -B _build .
&& cmake --build _build -- -j
&& cmake --install _build
- >
CMAKE_PREFIX_PATH="${PWD}/_build/install:${CMAKE_PREFIX_PATH}"
./test/integration/cmake/runtest.sh _build_cmake
- >
PKG_CONFIG_PATH="${PWD}/_build/install/lib/pkgconfig:${PKG_CONFIG_PATH}"
FC=mpifort
./test/integration/pkgconfig/runtest.sh _build_pkgconfig
79 changes: 52 additions & 27 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,39 +1,64 @@
cmake_minimum_required(VERSION 3.5)
cmake_minimum_required(VERSION 3.16)

project(mpifx VERSION 0.1 LANGUAGES Fortran)
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
include(${CMAKE_CURRENT_SOURCE_DIR}/config.cmake)

set(LIBRARY_ONLY FALSE CACHE BOOL "Whether only library should be compiled")
project(MpiFx VERSION 0.1 LANGUAGES Fortran)

option(BUILD_SHARED_LIBS "Whether the library should be a shared one" FALSE)
include(MpiFxUtils)
setup_build_type()

option(INSTALL_INCLUDE_FILES "Whether include / module files should be installed" TRUE)
#
# Prerequisites
#
find_package(MPI REQUIRED)
find_program(FYPP fypp)
if(NOT FYPP)
message(FATAL_ERROR "Preprocessor fypp could not be found")
endif()

# Installation paths
set(INSTALL_BIN_DIR "${CMAKE_INSTALL_PREFIX}/bin" CACHE PATH
"Installation directory for executables")
#
# Build instructions
#
add_subdirectory(lib)
if(NOT BUILD_EXPORTED_TARGETS_ONLY)
add_subdirectory(test)
endif()

set(INSTALL_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib" CACHE PATH
"Installation directory for libraries")
#
# Installation
#
add_library(MpiFx INTERFACE)
target_link_libraries(MpiFx INTERFACE mpifx)
install(TARGETS MpiFx EXPORT mpifx-targets)

set(INSTALL_MOD_DIR "${CMAKE_INSTALL_PREFIX}/include" CACHE PATH
"Installation directory for Fortran module files")
install(EXPORT mpifx-targets
FILE mpifx-targets.cmake
NAMESPACE MpiFx::
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/mpifx")

set(INSTALL_CMAKE_DIR "${CMAKE_INSTALL_PREFIX}/lib/cmake" CACHE PATH
"Installation directory for CMake package export files")
include(CMakePackageConfigHelpers)
configure_package_config_file(
${CMAKE_CURRENT_SOURCE_DIR}/utils/export/mpifx-config.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/cmake/mpifx-config.cmake
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/mpifx)

option(BUILD_SHARED_LIBS "Whether the library should be shared" FALSE)
write_basic_package_version_file(
${CMAKE_CURRENT_BINARY_DIR}/cmake/mpifx-config-version.cmake
VERSION ${PROJECT_VERSION}
COMPATIBILITY SameMajorVersion)

option(INSTALL_INCLUDE_FILES "Whether include and module files should be installed" TRUE)
install(
FILES ${CMAKE_CURRENT_BINARY_DIR}/cmake/mpifx-config.cmake
${CMAKE_CURRENT_BINARY_DIR}/cmake/mpifx-config-version.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/mpifx)

find_package(MPI REQUIRED)
find_program(FYPP fypp)
if(FYPP)
message(STATUS "Preprocessor fypp: ${FYPP}")
else()
message(FATAL_ERROR "Prepropcessor fypp not found")
endif()
include(GNUInstallDirs)
GNUInstallDirs_get_absolute_install_dir(CMAKE_INSTALL_FULL_MODULEDIR CMAKE_INSTALL_MODULEDIR)

add_subdirectory(lib)
if(NOT LIBRARY_ONLY)
add_subdirectory(test)
endif()
get_pkgconfig_params(PKGCONFIG_REQUIRES PKGCONFIG_LIBS PKGCONFIG_LIBS_PRIVATE PKGCONFIG_C_FLAGS)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/utils/export/mpifx.pc.in
${CMAKE_CURRENT_BINARY_DIR}/mpifx.pc @ONLY)
install(
FILES "${CMAKE_CURRENT_BINARY_DIR}/mpifx.pc"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Copyright (C) 2018 Bálint Aradi
Copyright (C) 2018 - 2020 DFTB+ developers group
All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
Expand Down
105 changes: 72 additions & 33 deletions README.rst
Original file line number Diff line number Diff line change
@@ -1,55 +1,94 @@
****************************************
MPIFX - Modern Fortran Interface for MPI
MpiFx - Modern Fortran Interface for MPI
****************************************

The open source library `MPIFX <https://github.com/dftbplus/mpifx>`_ is
an effort to provide modern Fortran (Fortran 2003) wrappers around
routines of the MPI library to make their use as simple as possible. The
documentation is included inside the repository, but is also available at
The open source library `MpiFx <https://github.com/dftbplus/mpifx>`_ provides
modern Fortran (Fortran 2003) wrappers around routines of the MPI library to
make their use as simple as possible. Currently several data distribution
routines are covered.

The documentation is included inside the repository, but is also available at
`dftbplus.github.io <https://dftbplus.github.io/>`_.

It currently contains only a few routines so far, but if those happen to be the
ones you need, feel free to use this project. MPIFX is licensed under the
**simplified BSD license**.

If your desired MPI routine is not yet wrapped up, feel free to contribute to
the project to include the target functionality.
Installation
============

Prerequisites
-------------

INSTALL
=======
* CMake (version >= 3.16)

* Fortran 2003 compatible Fortran compiler

* MPI-library and wrappers for your compiler

* `Fypp preprocessor <https://github.com/aradi/fypp>`_.


Building and installing the library
-----------------------------------

The library can be built and installed with the usual CMake-workflow::

Stand-alone building
--------------------
FC=gfortran cmake -B _build
cmake --build _build
cmake --install _build

#. Make a copy of the file `make.arch.template` as `make.arch`::
You can influence the configuration via CMake-variables, which are listed in
`config.cmake <config.cmake>`_. You can either modify the values directly there
or pass them as command line options at the configuration phase, e.g.::

cp make.arch.template make.arch
FC=ifort cmake -B _build -DBUILD_LIBRARY_ONLY=True

#. Configure any settings in `make.arch` in order to adapt it to your
environment.
Testing
-------

#. Issue ::
A few tests / usage examples can be found in the `test/` subdirectory. The
compiled test programs will be in the `test/` subfolder of your build directory.

make

in order to build and library and ::
Using the library
=================

make install
CMake build
-----------

in order to install it.
* Make sure to add the root folder of the installed library to the
``CMAKE_PREFIX_PATH`` environment variable.

#. You may build the examples in the `test/` subfolder with ::
* Use ``find_package()`` in `CMakeLists.txt` to locate the library and link
``MpiFx::MpiFx`` to every target which relies directly on the library ::

make test
cmake_minimum_required(VERSION 3.16)
project(TestMpiFx LANGUAGES Fortran)
find_package(MpiFx REQUIRED)
add_executable(test_mpifx test_mpifx.f90)
target_link_libraries(test_mpifx MpiFx::MpiFx)


Build the library as part of a build process
--------------------------------------------
Pkg-config build
----------------

* Make sure to add the `lib/pkgconfig` folder of the installed library to the
``PKG_CONFIG_PATH`` environment variable.

* Query the include and library options needed for the build with the usual
``pkg-config`` commands::

mpifort $(pkg-config --cflags mpifx) test_mpifx.f90 $(pkg-config --libs mpifx)

Note, that neither ``-cflags`` or ``--libs`` return any options related to
your MPI-framework nor is the MPI-framework specified as dependency in the
pkg-config file. Use the MPI-wrapper of your compiler to compile and link your
executable or pass the additional include and library options by hand.


License
=======

You may build the library on-the-fly during the build of your program. Invoke
the library makefile `lib/make.build` during your build process from the folder
where you wish to build the library. Make sure to pass the necessary
make-variables (as documented in the library makfile). See the `makefile` in
this folder for an example how to invoke the library makefile.
MpiFx is licensed under the `2-Clause BSD License <LICENSE>`_.
58 changes: 58 additions & 0 deletions cmake/MpiFxUtils.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Register custom commands for processing source files with fypp (.fpp -> .f90)
#
# Args:
# oldfiles [in]: List of files to preprocess (must have .fpp suffix)
# newfiles [out]: List of preprocessed files (will have .f90 suffix).
#
function(fypp_preprocess oldfiles newfiles)

set(_newfiles)
foreach(oldfile IN LISTS oldfiles)
string(REGEX REPLACE "\\.fpp" ".f90" newfile ${oldfile})
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${newfile}
COMMAND ${FYPP} ${FYPP_FLAGS} ${CMAKE_CURRENT_SOURCE_DIR}/${oldfile} ${CMAKE_CURRENT_BINARY_DIR}/${newfile}
MAIN_DEPENDENCY ${CMAKE_CURRENT_SOURCE_DIR}/${oldfile})
list(APPEND _newfiles ${CMAKE_CURRENT_BINARY_DIR}/${newfile})
endforeach()
set(${newfiles} ${_newfiles} PARENT_SCOPE)

endfunction()


# Returns the parameters needed to create a pkg-config export file
#
# Args:
# pkgconfig_requires [out]: Value for the Requires field.
# pkgconfig_libs [out]: Value for the Libs field.
# pkgconfig_libs_private [out]: Value for the Libs.private field.
# pkgconfig_c_flags [out]: Value for the cflags field.
# pkgconfig_prefix [out]: Value for the installation prefix.
#
function(get_pkgconfig_params pkgconfig_requires pkgconfig_libs pkgconfig_libs_private
pkgconfig_c_flags)

set(_pkgconfig_requires)

set(_pkgconfig_libs "-L${CMAKE_INSTALL_FULL_LIBDIR} -lmpifx")

set(_pkgconfig_libs_private "${CMAKE_EXE_LINKER_FLAGS}")

set(_pkgconfig_c_flags "-I${CMAKE_INSTALL_FULL_MODULEDIR}")

set(${pkgconfig_requires} "${_pkgconfig_requires}" PARENT_SCOPE)
set(${pkgconfig_libs} "${_pkgconfig_libs}" PARENT_SCOPE)
set(${pkgconfig_libs_private} "${_pkgconfig_libs_private}" PARENT_SCOPE)
set(${pkgconfig_c_flags} "${_pkgconfig_c_flags}" PARENT_SCOPE)

endfunction()


# Sets up the build type.
function (setup_build_type)
set(default_build_type "RelWithDebInfo")
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
message(STATUS "Setting build type to ${default_build_type} as none was specified")
set(CMAKE_BUILD_TYPE "${default_build_type}" CACHE STRING "Build type" FORCE)
endif()
endfunction()
37 changes: 37 additions & 0 deletions config.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#
# Build options
#

# CMAKE_BUILD_TYPE is commented out in order to allow for multi-configuration builds. It will
# automatically default to RelWithDebInfo if used in a single configuration build. Uncomment or
# override it only if you want a non-default single configuration build.
#
#set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Build type (Release|RelWithDebInfo|Debug|MinSizeRel)")

# If set to True, only those public targets (typically the library) will be built, which are usually
# exported via CMake export files. Otherwise all targets all built (default case). Set this option
# to True, if you invoke this project as part of an other CMake project via the add_subdirectory()
# command without the EXCLUDE_FROM_ALL option (e.g. if you want this project to install its targets
# as part of the top projects installation process).
#
option(BUILD_EXPORTED_TARGETS_ONLY
"Whether only exported targets (the library, but no tests) should be built" FALSE)

option(BUILD_SHARED_LIBS "Whether the library should be a shared one" FALSE)

#
# Installation options
#

option(INSTALL_INCLUDE_FILES "Whether include / module files should be installed" TRUE)

set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/install" CACHE STRING
"Directory to install the compiled code into")

set(CMAKE_INSTALL_LIBDIR "lib" CACHE PATH "Installation directory for libraries")

set(CMAKE_INSTALL_INCLUDEDIR "include/mpifx" CACHE PATH
"Installation directory for header and include files")

set(CMAKE_INSTALL_MODULEDIR "${CMAKE_INSTALL_INCLUDEDIR}/modfiles" CACHE PATH
"Installation directory for Fortran module files")
3 changes: 1 addition & 2 deletions doc/doxygen/fyppf90.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#!/bin/bash
srcdir=$(dirname $1)
fyppdir=$srcdir/../external/fypp
$fyppdir/fypp -I$(dirname $1) $1
fypp -I$(dirname $1) $1
24 changes: 0 additions & 24 deletions external/fypp/LICENSE.txt

This file was deleted.

Loading

0 comments on commit ddf3dbc

Please sign in to comment.