Skip to content

Commit

Permalink
Merge pull request #70 from vanderhe/condaForgePreparations
Browse files Browse the repository at this point in the history
Prepare infrastructure for conda-forge packaging
  • Loading branch information
vanderhe authored Sep 15, 2022
2 parents 9e50108 + c894347 commit 2010be1
Show file tree
Hide file tree
Showing 16 changed files with 300 additions and 16 deletions.
43 changes: 28 additions & 15 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,17 @@ project(fortnet VERSION ${FORTNET_VERSION} LANGUAGES Fortran C)
fnet_setup_build_type()
fnet_load_toolchain_settings()
fnet_setup_global_compiler_flags()
fnet_ensure_config_consistency()
fnet_get_release_name(RELEASE)

find_package(HDF5 REQUIRED COMPONENTS Fortran_HL)

find_package(MPI QUIET)
if(WITH_MPI AND NOT MPI_FORTRAN_FOUND)
message(FATAL_ERROR "Compiler ${CMAKE_Fortran_COMPILER} is not MPI capable but is specified for "
"a WITH_MPI=TRUE build")
elseif(NOT WITH_MPI AND MPI_FORTRAN_FOUND)
message(WARNING "MPI enabled compiler ${CMAKE_Fortran_COMPILER} found for a non-MPI build. Your "
"build will NOT be MPI-parallelised. Set WITH_MPI=TRUE in order to obtain an MPI-parallelised "
"build.")
if(WITH_MPI)
find_package(MPI REQUIRED)
if(NOT MPI_FORTRAN_FOUND)
message(FATAL_ERROR "Compiler ${CMAKE_Fortran_COMPILER} is not MPI capable but is specified "
"for a WITH_MPI=TRUE build")
endif()
endif()

#
Expand All @@ -43,6 +42,10 @@ set(PKG_CONFIG_REQUIRES)
set(PKG_CONFIG_LIBS)
set(PKG_CONFIG_LIBS_PRIVATE)

find_package(CustomBlas REQUIRED)
find_package(CustomLapack REQUIRED)
list(APPEND PKG_CONFIG_LIBS_PRIVATE ${BLAS_LIBRARY} ${LAPACK_LIBRARY})


#
# Preprocessor details
Expand All @@ -62,28 +65,36 @@ set(PYTHON_INTERPRETER "python3" CACHE STRING
#
# Add optional external components
#
if(BUILD_SHARED_LIBS)
set(exclude)
option(INSTALL_INCLUDE_FILES "Whether include files should be installed" FALSE)
else()
set(exclude EXCLUDE_FROM_ALL)
option(INSTALL_INCLUDE_FILES "Whether include files should be installed" FALSE)
endif()


# Follow GNU conventions for installing directories
include(GNUInstallDirs)

add_subdirectory(external/xmlf90 EXCLUDE_FROM_ALL)

if(WITH_SOCKETS)
add_subdirectory(external/fsockets EXCLUDE_FROM_ALL)
endif()

# If INCLUDE_INDIRECT_DEPS is non-empty, indirect dependencies must also be explicitely treated
string(REGEX MATCH "(^|;)[Ss]ubmodule(^|;)" INCLUDE_INDIRECT_DEPS "${HYBRID_CONFIG_METHODS}")

# Note: GIT_TAG hashes below must be updated with the utils/test/check_submodule_commits script!

if(WITH_MPI)
set(MPIFX_GIT_REPOSITORY "https://github.com/dftbplus/mpifx.git")
set(MPIFX_GIT_TAG "0cb07ee08cbb20f3f7bb2527152a4ec317c579ad") # do not change manually!
set(MPIFX_GIT_TAG "da51073aa87831a91ae756a9773e39ea000d1c3a") # do not change manually!
fnet_config_hybrid_dependency(MpiFx MpiFx::MpiFx "${HYBRID_CONFIG_METHODS}" "QUIET"
external/mpifx "${exclude}" "${MPIFX_GIT_REPOSITORY}" "${MPIFX_GIT_TAG}")
endif()

find_package(CustomBlas REQUIRED)
find_package(CustomLapack REQUIRED)

add_subdirectory(external/xmlf90 EXCLUDE_FROM_ALL)


#
# Add internal components
Expand All @@ -96,4 +107,6 @@ add_subdirectory(prog)
#
string(CONFIGURE "${TEST_RUNNER_TEMPLATE}" TEST_RUNNER)
enable_testing()
add_subdirectory(test)
if(NOT BUILD_EXPORTED_TARGETS_ONLY)
add_subdirectory(test)
endif()
45 changes: 45 additions & 0 deletions cmake/FortnetUtils.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ function (fnet_add_fypp_defines fyppflags)
list(APPEND _fyppflags -DWITH_SOCKETS)
endif()

if(BUILD_SHARED_LIBS)
list(APPEND _fyppflags -DBUILD_SHARED_LIBS)
endif()

set(${fyppflags} ${_fyppflags} PARENT_SCOPE)

endfunction()
Expand Down Expand Up @@ -193,6 +197,25 @@ function(fnet_library_linking_flags libraries linkflags)
endfunction()


# Checks the build configuration on consistency and stops in case of inconsistencies
function (fnet_ensure_config_consistency)

# Check minimal compiler versions
set(fortran_minimal_versions "GNU;8.3" "Intel;20.2")
fnet_check_minimal_compiler_version("Fortran" "${fortran_minimal_versions}")

set(pkgconfig_languages C Fortran)
list(FIND pkgconfig_languages "${PKGCONFIG_LANGUAGE}" pos)
if(pos EQUAL -1)
string(REPLACE ";" "\", \"" pkgconfig_languages_str "${pkgconfig_languages}")
set(pkgconfig_languages_str "\"${pkgconfig_languages_str}\"")
message(FATAL_ERROR
"Invalid language \"${PKGCONFIG_LANGUAGE}\" for PKGCONFIG_LANGUAGE (possible choices: ${pkgconfig_languages_str})")
endif()

endfunction()


# Stops the code if the source and the build folders are identical.
#
function(fnet_ensure_out_of_source_build)
Expand Down Expand Up @@ -443,3 +466,25 @@ macro(fnet_config_hybrid_dependency package target config_methods findpkgopts su
unset(_config_lower)

endmacro()


# Checks whether the current compiler fullfills minimal version requirements.
#
#
# Arguments:
# lang [in]: Language for which the compiler should be checked (e.g. Fortran, C, CXX)
# compiler_versions [in]: List with alternating compiler ids and minimal version numbers, e.g.
# "Intel;19.0;GNU;9.0". If the compiler is amoung the listed ones and its version number is
# less than the specified one, a fatal error message will be issued. Otherwise the function
# returns silently.
#
function (fnet_check_minimal_compiler_version lang compiler_versions)
while(compiler_versions)
list(POP_FRONT compiler_versions compiler version)
if("${CMAKE_${lang}_COMPILER_ID}" STREQUAL "${compiler}"
AND CMAKE_${lang}_COMPILER_VERSION VERSION_LESS "${version}")
message(FATAL_ERROR "${compiler} ${lang} compiler is too old "
"(found \"${CMAKE_${lang}_COMPILER_VERSION}\", required >= \"${version}\")")
endif()
endwhile()
endfunction()
8 changes: 7 additions & 1 deletion config.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,13 @@

option(WITH_MPI "Whether Fortnet should support MPI-parallelism" TRUE)

option(WITH_SOCKETS "Whether socket communication should be allowed for" FALSE)
option(WITH_SOCKETS "Whether socket communication should be allowed for" TRUE)

option(BUILD_SHARED_LIBS "Whether the libraries built should be shared" FALSE)
# Turn this on, if the Fortnet library (and other compiled libraries) should be shared libraries and
# dynamically linked to their applications. This results in smaller applications, but the libraries
# must be present at run-time (and the correct LD_LIBRARY_PATH environment variable must be set, so
# that they can be found by the operating system).


#
Expand Down
1 change: 1 addition & 0 deletions external/fsockets/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ add_library(fsockets_objlib OBJECT ${sources})
set(includedir ${CMAKE_CURRENT_BINARY_DIR}/include)

set_target_properties(fsockets_objlib PROPERTIES Fortran_MODULE_DIRECTORY ${includedir})
set_target_properties(fsockets_objlib PROPERTIES POSITION_INDEPENDENT_CODE ${BUILD_SHARED_LIBS})

target_include_directories(fsockets_objlib PUBLIC ${includedir})
1 change: 1 addition & 0 deletions external/xmlf90/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,6 @@ add_library(xmlf90_objlib OBJECT ${sources})
set(includedir ${CMAKE_CURRENT_BINARY_DIR}/include)

set_target_properties(xmlf90_objlib PROPERTIES Fortran_MODULE_DIRECTORY ${includedir})
set_target_properties(xmlf90_objlib PROPERTIES POSITION_INDEPENDENT_CODE ${BUILD_SHARED_LIBS})

target_include_directories(xmlf90_objlib PUBLIC ${includedir})
4 changes: 4 additions & 0 deletions prog/fortnet/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ target_include_directories(fortnet PUBLIC ${OTHER_INCLUDE_DIRS})
#
# Installation
#
if(BUILD_SHARED_LIBS)
install(TARGETS fortnet DESTINATION "${CMAKE_INSTALL_LIBDIR}" EXPORT fortnet-targets)
endif()

list(APPEND PKG_CONFIG_LIBS fortnet)
set(PKG_CONFIG_LIBS "${PKG_CONFIG_LIBS}" PARENT_SCOPE)

Expand Down
10 changes: 10 additions & 0 deletions test/prog/fortnet/integration/cmake/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
cmake_minimum_required(VERSION 3.16)

project(TestFortnetBuild LANGUAGES Fortran)

find_package(Fortnet REQUIRED)

add_executable(test_build test_build.f90)
target_link_libraries(test_build Fortnet::Fortnet)


28 changes: 28 additions & 0 deletions test/prog/fortnet/integration/cmake/runtest.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#!/usr/bin/env bash
#
# Tests whether the installed Fortnet library can be used within a CMake project.
#
# Arguments:
#
# - building directory (will be created, should not exist)
#
# Requirements:
#
# - Environment variables FC & CC contain the same compiler as used for Fortnet
#
# - Environment variable CMAKE_PREFIX_PATH contains the Fortnet install root.
#
SCRIPTDIR=$(dirname $0)
SCRIPTNAME=$(basename $0)
BUILDDIR=$1
shift

if [ -d ${BUILDDIR} ]; then
echo "${SCRIPTNAME}: Test build directory '${BUILDDIR}' already exists." >&2
exit 1
fi

FC=$FC CC=$CC cmake -B ${BUILDDIR} ${SCRIPTDIR} -DCMAKE_MODULE_PATH=${CMAKE_MODULE_PATH} "$@" \
|| { echo "Configuration step failed" >&2; exit 1; }
cmake --build ${BUILDDIR} -- VERBOSE=1 || { echo "Build step failed" >&2; exit 1; }
echo "CMake build succeeded!"
5 changes: 5 additions & 0 deletions test/prog/fortnet/integration/cmake/test_build.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
program test_build
use fortnet
implicit none

end program test_build
45 changes: 45 additions & 0 deletions test/prog/fortnet/integration/pkgconfig/runtest.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#!/usr/bin/env bash
#
# Tests whether the installed Fortnet library can be used with pkg-config based builds.
#
# Arguments:
#
# - building directory (will be created if it does not exist)
#
# Requirements:
#
# - Environment variables FC and CC contain the same Fortran and C compilers as used for Fortnet
#
# - Environment variable PKG_CONFIG_PATH contains the lib/pkgconfig folder within
# the installed Fortnet tree.
#
# - You pass all linker options as arguments, which are needed to link an MPI-binary
# with your compiler. Alternatively, you can specify the name of the MPI-wrappers
# as your compilers in FC and CC.
#
SCRIPTDIR=$(dirname $0)
SCRIPTNAME=$(basename $0)
BUILDDIR=$1
shift
CUSTOMLIBS=$*

if [ ! -d ${BUILDDIR} ]; then
mkdir ${BUILDDIR} || { echo "Could not create build dir '${BUILDDIR}'" >&2; exit 1; }
fi

# Make sure scriptdir is absolute
cd ${SCRIPTDIR}
SCRIPTDIR=${PWD}
cd -

cd ${BUILDDIR} || { echo "Could not change to build dir '${BUILDDIR}'" >&2; exit 1; }
pkg-config --exists fortnet || { echo "No PKG-CONFIG found for Fortnet" >&2; exit 1; }

cflags=$(pkg-config --cflags fortnet)
libs=$(pkg-config --libs fortnet)

cmd="${FC} ${cflags} ${SCRIPTDIR}/test_build.f90 ${libs} ${CUSTOMLIBS}"

echo "Build command: ${cmd}"
${cmd} || { echo "Build command failed" >&2; exit 1; }
echo "PKG-CONFIG build succeeded."
5 changes: 5 additions & 0 deletions test/prog/fortnet/integration/pkgconfig/test_build.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
program test_build
use fortnet
implicit none

end program test_build
27 changes: 27 additions & 0 deletions utils/export/fortnet-config.cmake.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
@PACKAGE_INIT@

# Global Fortnet config options
set(Fortnet_WITH_MPI @WITH_MPI@)
set(Fortnet_WITH_SOCKETS @WITH_SOCKETS@)

include(CMakeFindDependencyMacro)

list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/Modules)

if(NOT TARGET Fortnet::Fortnet)

if(NOT TARGET BLAS::BLAS)
find_dependency(CustomBlas)
endif()

if(NOT TARGET LAPACK::LAPACK)
find_dependency(CustomLapack)
endif()

if(Fortnet_WITH_MPI AND NOT TARGET MpiFx::MpiFx)
find_dependency(MpiFx)
endif()

include("${CMAKE_CURRENT_LIST_DIR}/fortnet-targets.cmake")

endif()
9 changes: 9 additions & 0 deletions utils/export/fortnet.pc.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Name: Fortnet
Description: Library interface to Fortnet, a software package for training Behler-Parrinello neural networks
Version: @PROJECT_VERSION@
URL: https://github.com/vanderhe/fortnet

Requires: @PKGCONFIG_REQUIRES@
Libs: @PKGCONFIG_LIBS@
Libs.private: @PKGCONFIG_LIBS_PRIVATE@
Cflags: @PKGCONFIG_C_FLAGS@
36 changes: 36 additions & 0 deletions utils/test/travis-extbuild.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#!/usr/bin/env bash
#
# Build external components first and uses them as external dependencies during build
#
# Expects following env-vars:
#
# WITH_MPI ("false"/"true"), SOURCE_DIR, BUILD_DIR, INSTALL_DIR
#
set -ex

if [ "${WITH_MPI}" == "true" ]; then

cmake -DCMAKE_INSTALL_PREFIX=${INSTALL_DIR} \
-DBUILD_EXPORTED_TARGETS_ONLY=True -DCMAKE_BUILD_TYPE=Debug \
-B ${BUILD_DIR}/mpifx ${SOURCE_DIR}/external/mpifx/origin
cmake --build ${BUILD_DIR}/mpifx -- -j
cmake --install ${BUILD_DIR}/mpifx

cmake -DWITH_MPI=True \
-DHYBRID_CONFIG_METHODS='Find' \
-DCMAKE_INSTALL_PREFIX=${INSTALL_DIR} \
-DCMAKE_BUILD_TYPE=Debug \
-B ${BUILD_DIR}/fortnet ${SOURCE_DIR}
cmake --build ${BUILD_DIR}/fortnet -- VERBOSE=1 fnet

else

cmake -DWITH_MPI=False \
-DHYBRID_CONFIG_METHODS='Find' \
-DBUILD_SHARED_LIBS=False \
-DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_INSTALL_PREFIX=${INSTALL_DIR} \
-B ${BUILD_DIR}/fortnet ${SOURCE_DIR}
cmake --build ${BUILD_DIR}/fortnet -- VERBOSE=1 fnet

fi
19 changes: 19 additions & 0 deletions utils/test/travis-integration.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#!/usr/bin/env bash
#
# Must be called, after Fortnet had been installed
#
# Expects following env-vars:
#
# FC, CC, ("false"/"true")
# SOURCE_DIR (Fortnet source dir), BUILD_DIR,
# INSTALL_DIR (Fortnet install dir with already installed Fortnet)
#
set -ex

# Integration test for CMake builds
CMAKE_PREFIX_PATH="${INSTALL_DIR}:${CMAKE_PREFIX_PATH}" \
${SOURCE_DIR}/test/prog/fortnet/integration/cmake/runtest.sh ${BUILD_DIR}/cmake

# Integration test for PKG-CONFIG builds
PKG_CONFIG_PATH="${INSTALL_DIR}/lib/pkgconfig:$PKG_CONFIG_PATH" \
${SOURCE_DIR}/test/prog/fortnet/integration/pkgconfig/runtest.sh ${BUILD_DIR}/pkgconfig
Loading

0 comments on commit 2010be1

Please sign in to comment.