Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Set up the cmake fortran compilaion #26

Merged
merged 6 commits into from
Sep 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 20 additions & 2 deletions fortran/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,24 @@
cmake_minimum_required(VERSION 3.20.2)
#This directory can be compiled as an autonomos project

#install file for install-mode plumed
install( FILES plumed_f08.f90 plumed.f90
DESTINATION ${CMAKE_INSTALL_LIBDIR}/${program_name}/fortran
DESTINATION ${DIRS_EXTRA_INSTALL}/fortran
PERMISSIONS
OWNER_WRITE
OWNER_READ GROUP_READ WORLD_READ
)
)

#copy file for build-only plumed
file(COPY plumed_f08.f90 plumed.f90
DESTINATION ${CMAKE_BINARY_DIR}/lib/plumed/fortran
USE_SOURCE_PERMISSIONS
)
include(CheckLanguage)
check_language(Fortran)
if(NOT CMAKE_Fortran_COMPILER)
message(STATUS "Fortran cannot be compiled")
return()
endif()

#project(Plumed2Fortran LANGUAGES CXX Fortran)
1 change: 1 addition & 0 deletions fortran/Makefile
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#To the developer: use this simple makefile to generate the fortran interfaces
all: plumed.f90 plumed_f08.f90

plumed.f90: plumed.f90.template
Expand Down
19 changes: 16 additions & 3 deletions regtest/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,15 @@ if(NOT TARGET Plumed2::plumed_bin)
#when testing in the build environment
set(STANDALONE_TESTS ON)
else()
set (Plumed2_DIR "${CMAKE_BINARY_DIR}/src/cmake")
set (Plumed2_DIR "${CMAKE_BINARY_DIR}/lib/cmake/plumed")
endif()

set(PLUMED_TEST_DIR ${CMAKE_CURRENT_SOURCE_DIR})
set(run_ctest ${CMAKE_CURRENT_SOURCE_DIR}/scripts/run_ctest)

#set (failRegex "FAILURE;ERROR;WARNING")
set (failRegex "FAILURE;ERROR")
set (skipRegex "NOT_APPLICABLE")

set(PLUMED_TEST_KNOWN_TYPES
simplemd
Expand All @@ -39,6 +40,7 @@ function(PLUMED_TEST test_name)
#[EXPORTVARIABLES variable1 value1 variable2 value2 ...]
#[NEEDS component1 component2 ...]
#[MODULES module1 module2 ...]
#[COMPILER_LANGUAGE C11 or Fortran08]
#[LABELS label1 label2 ...]
#)

Expand Down Expand Up @@ -67,13 +69,15 @@ function(PLUMED_TEST test_name)
#
#With EXTRAFILES the user can specify a list of paths to files to be copied in the test directory
#
#
#With NEEDS the user can specify a list needed components, if the specified
#componets are not found by `plumed config has componentname` the test will be skipped.
#
#With MODULES the user can specify a list needed modules, if the specified
#componets are not found by `plumed config module modulename` the test will be skipped.
#
#With COMPILER_LANGUAGE you can specify Fortan08 or C11 and the make test will be skipped if the compiler is not compatible (works ONLY
#for make tests), note the argments are case insensitive
#
#With LABELS the user can specify a collection of keyword that can be use to
#limit the number of test to be runned with ctest. The type and the home
#directory of the test are automatically set up as labels
Expand All @@ -82,7 +86,7 @@ function(PLUMED_TEST test_name)
# will be automatically prepended to the specified arguments

set(options "")
set(oneValueArgs "TYPE;ARGS;MPIPROCS")
set(oneValueArgs "TYPE;ARGS;MPIPROCS;COMPILER_LANGUAGE")
set(multiValueArgs "EXTRAFILES;EXPORTVARIABLES;NEEDS;LABELS;MODULES")
cmake_parse_arguments(PARSE_ARGV 1 PLUMED_TEST "${options}" "${oneValueArgs}"
"${multiValueArgs}" )
Expand All @@ -108,6 +112,13 @@ function(PLUMED_TEST test_name)
if(PLUMED_TEST_MPIPROCS)
set(PLUMED_TEST_MPIPROCS "-p${PLUMED_TEST_MPIPROCS}")
endif()

if(PLUMED_TEST_COMPILER_LANGUAGE)
string(TOLOWER ${PLUMED_TEST_COMPILER_LANGUAGE} PLUMED_TEST_COMPILER_LANGUAGE)
set(PLUMED_TEST_COMPILER_LANGUAGE "-c${PLUMED_TEST_COMPILER_LANGUAGE}")
endif()


if(PLUMED_TEST_EXTRAFILES)
set (t)
foreach(extra IN LISTS PLUMED_TEST_EXTRAFILES)
Expand Down Expand Up @@ -163,6 +174,7 @@ function(PLUMED_TEST test_name)
-d${CMAKE_CURRENT_SOURCE_DIR}
${PLUMED_TEST_MPIPROCS}
${PLUMED_TEST_EXTRAFILES}
${PLUMED_TEST_COMPILER_LANGUAGE}
${nopt} ${PLUMED_TEST_NEEDS}
${mopt} ${PLUMED_TEST_MODULES}
${PLUMED_TEST_EXPORTVARIABLES}
Expand All @@ -180,6 +192,7 @@ function(PLUMED_TEST test_name)

set_tests_properties(${testname} PROPERTIES
FAIL_REGULAR_EXPRESSION "${failRegex}"
SKIP_REGULAR_EXPRESSION "${skipRegex}"
SKIP_RETURN_CODE 125
LABELS "${PLUMED_TEST_LABELS}")
endfunction(PLUMED_TEST)
Expand Down
1 change: 1 addition & 0 deletions regtest/basic/rt-make-c11/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
PLUMED_TEST(rt-make-c11 TYPE make
EXPORTVARIABLES
PLUMED_STACK_TRACE "no"
COMPILER_LANGUAGE C11
)
#the following variable is the original config file
set(originalConfig [[
Expand Down
1 change: 1 addition & 0 deletions regtest/basic/rt-make-fortran/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
PLUMED_TEST(rt-make-fortran TYPE make
COMPILER_LANGUAGE Fortran
)
#the following variable is the original config file
set(originalConfig [[
Expand Down
1 change: 1 addition & 0 deletions regtest/basic/rt-make-fortran08/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
PLUMED_TEST(rt-make-fortran08 TYPE make
EXPORTVARIABLES
PLUMED_STACK_TRACE "no"
COMPILER_LANGUAGE Fortran08
)
#the following variable is the original config file
set(originalConfig [[
Expand Down
89 changes: 87 additions & 2 deletions regtest/scripts/run_ctest
Original file line number Diff line number Diff line change
Expand Up @@ -196,18 +196,101 @@ run_make() {
files=$(ls ./*.cpp ./*.f90 ./*.c 2>/dev/null)
if [[ -n ${filesf90} ]]; then
otherLang="${otherLang}enable_language (Fortran)\n"
if [[ $compiler_language = "fortran08" ]]; then
otherLang=$(
cat <<EOF
${otherLang}
include(CheckSourceCompiles)
check_source_compiles( Fortran [[
module test_fortran08_a
implicit none
type b
contains
final :: c
end type b
contains
impure elemental subroutine c(x)
type(b), intent(inout) :: x
end subroutine c
subroutine sub(x)
integer :: x(:)
write(*,*) is_contiguous(x)
end subroutine sub
end module test_fortran08_a

program test
USE test_fortran08_a
type(b):: x
integer :: y(5)
call c(x)
call sub(y)
end program
]]
HAVE_FORTRAN08
)
if(NOT HAVE_FORTRAN08)
message (FATAL_ERROR "NOT_APPLICABLE (the compiler is not Fortran08 compatible)")
endif()
EOF
)
#alternative sligthly more complex way
#compileLibs="${compileLibs}add_library (PlumedFortran08)\n"
#otherLibs="${otherLibs} PlumedFortran08"
files="${files} \${Plumed2_FORTRAN08}"
else
# TODO maybe test both the compile methods for 08 and non 08 fortran
#alternative sligthly more complex way commented
compileLibs="${compileLibs}add_library (PlumedFortran \${Plumed2_FORTRAN})\n"
otherLibs="${otherLibs} PlumedFortran"
# files="${files} \${Plumed2_FORTRAN}"
fi
fi
if [[ -n ${filesC} ]]; then
otherLang="${otherLang}enable_language (C)\n"
if [[ $compiler_language = "c11" ]]; then
otherLang=$(
cat <<EOF
${otherLang}

include(CheckSourceCompiles)
check_source_compiles( C [[
#ifdef __STDC_VERSION__
#if __STDC_VERSION__ < 201112L
error
#endif
#else
error
#endif

int f(int a){
int x;
x=_Generic( 'a', char: 1, int: 2, long: 3, default: 0);
return a;
}

int main(void){
int x=10;
int k=f(x);
}
]]
HAVE_C11
)
if(NOT HAVE_C11)
message (FATAL_ERROR "NOT_APPLICABLE (the compiler is not C11 compatible)")
endif()
EOF
)
fi
fi
cat <<EOF >CMakeLists.txt
cmake_minimum_required(VERSION 3.20)
project(exe-test CXX)
$(echo -e "$otherLang")
find_package(Plumed2 REQUIRED)
$(echo -e "$compileLibs")
add_executable(exe ${files})
target_link_libraries(exe PUBLIC
Plumed2::sharedplumedMain
Plumed2::sharedplumedMain $otherLibs
#automatically links to the shared kernel Plumed2::sharedplumedKernel
)
install (TARGETS exe
Expand Down Expand Up @@ -287,12 +370,13 @@ set -o pipefail
extra_files=()
valgrind="env"

while getopts "a:d:e:f:l:m:n:p:v" option; do
while getopts "a:c:d:e:f:l:m:n:p:v" option; do
#echo "$option -> ${OPTARG}"
case "$option" in
#the
a) args=${OPTARG} ;;
#the directory with the source of the test
c) compiler_language=${OPTARG} ;;
d) dir=${OPTARG} ;;
e)
name=${OPTARG%=*}
Expand Down Expand Up @@ -334,6 +418,7 @@ EOF
export args
export plumed_modules
export plumed_needs
export compiler_language
export extra_files
export valgind
export plumed
Expand Down
1 change: 1 addition & 0 deletions regtest/testIntegrity/checkMODULESFAIL/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ set_tests_properties(${TEST_DIR}-checkMODULES_SHOULD_FAIL PROPERTIES
WILL_FAIL ON
)
set_property(TEST ${TEST_DIR}-checkMODULES_SHOULD_FAIL PROPERTY SKIP_RETURN_CODE)
set_property(TEST ${TEST_DIR}-checkMODULES_SHOULD_FAIL PROPERTY SKIP_REGULAR_EXPRESSION)
1 change: 1 addition & 0 deletions regtest/testIntegrity/checkNEEDS/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ set_tests_properties(${TEST_DIR}-checkNEEDS_SHOULD_FAIL PROPERTIES
WILL_FAIL ON
)
set_property(TEST ${TEST_DIR}-checkNEEDS_SHOULD_FAIL PROPERTY SKIP_RETURN_CODE)
set_property(TEST ${TEST_DIR}-checkNEEDS_SHOULD_FAIL PROPERTY SKIP_REGULAR_EXPRESSION)
37 changes: 27 additions & 10 deletions src/cmake/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -50,35 +50,51 @@ if(BoostCompontents)
endif()

list(JOIN EXTERNAL_PACKAGES "\n" EXTERNAL_PACKAGES)

#this is the installed version
configure_package_config_file(
PlumedConfig.cmake.in
Plumed2Config.cmake
"Plumed2Config.cmake"
INSTALL_DESTINATION
${DIRS_CMAKE_INSTALL}
PATH_VARS
DIRS_INCLUDE_INSTALL
DIRS_LIB_INSTALL
DIRS_BIN_INSTALL
DIRS_EXTRA_INSTALL
)
#This is the build version
configure_package_config_file(
PlumedConfig.cmake.in
"${CMAKE_BINARY_DIR}/lib/cmake/plumed/Plumed2Config.cmake"
INSTALL_DESTINATION
${DIRS_CMAKE_INSTALL}
PATH_VARS DIRS_INCLUDE_INSTALL
DIRS_LIB_INSTALL
DIRS_BIN_INSTALL
${CMAKE_BINARY_DIR}/lib/cmake/plumed/
PATH_VARS
DIRS_INCLUDE_INSTALL
DIRS_LIB_INSTALL
DIRS_BIN_INSTALL
DIRS_EXTRA_INSTALL
INSTALL_PREFIX
${CMAKE_BINARY_DIR}
)

################################################################################
######################Creating Plumed2ConfigVersion.cmake#######################
################################################################################
write_basic_package_version_file(Plumed2ConfigVersion.cmake
write_basic_package_version_file("${CMAKE_BINARY_DIR}/lib/cmake/plumed/Plumed2ConfigVersion.cmake"
VERSION ${PLUMED_VERSION_MAJOR}.${PLUMED_VERSION_MINOR}.${PLUMED_VERSION_PATCH}
#COMPATIBILITY <AnyNewerVersion|SameMajorVersion|SameMinorVersion|ExactVersion>
COMPATIBILITY SameMinorVersion
)

install(FILES ${CMAKE_CURRENT_BINARY_DIR}/Plumed2Config.cmake
${CMAKE_CURRENT_BINARY_DIR}/Plumed2ConfigVersion.cmake
${CMAKE_BINARY_DIR}/lib/cmake/plumed/Plumed2ConfigVersion.cmake
PlumedUserMacros.cmake #This installs the macros for the user
DESTINATION ${DIRS_CMAKE_INSTALL}
)

#this is needed to have PlumedUserMacros.cmake avaiable in the build configuration
file(COPY PlumedUserMacros.cmake
DESTINATION ${CMAKE_CURRENT_BINARY_DIR}
DESTINATION ${CMAKE_BINARY_DIR}/lib/cmake/plumed/
)

foreach(exportetTargets Plumed2MODULES Plumed2WRAPPERS Plumed2LIBS Plumed2EXEC)
Expand All @@ -88,6 +104,7 @@ foreach(exportetTargets Plumed2MODULES Plumed2WRAPPERS Plumed2LIBS Plumed2EXEC)
)
export(EXPORT ${exportetTargets}
NAMESPACE Plumed2::
FILE "${CMAKE_CURRENT_BINARY_DIR}/${exportetTargets}.cmake"
FILE "${CMAKE_BINARY_DIR}/lib/cmake/plumed/${exportetTargets}.cmake"
)
endforeach(exportetTargets )

37 changes: 34 additions & 3 deletions src/cmake/PlumedConfig.cmake.in
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,40 @@ include("${CMAKE_CURRENT_LIST_DIR}/Plumed2EXEC.cmake")
#user macros are included in this .cmake
include("${CMAKE_CURRENT_LIST_DIR}/PlumedUserMacros.cmake")

#set_and_check(Plumed2_INCLUDE_DIR "@PACKAGE_DIRS_INCLUDE_INSTALL@")
#set_and_check(Plumed2_LIB_DIR "@PACKAGE_DIRS_LIB_INSTALL@")
#set_and_check(Plumed2_BIN_DIR "@PACKAGE_DIRS_BIN_INSTALL@")
#TODO: set up the build dir to work with these in build-only mode
# set_and_check(Plumed2_INCLUDE_DIR "@PACKAGE_DIRS_INCLUDE_INSTALL@")
set_and_check(Plumed2_LIB_DIR "@PACKAGE_DIRS_LIB_INSTALL@")
# set_and_check(Plumed2_BIN_DIR "@PACKAGE_DIRS_BIN_INSTALL@")
set_and_check(Plumed2_EXTRA_DIR "@PACKAGE_DIRS_EXTRA_INSTALL@")
set_and_check(Plumed2_FORTRAN_DIR "@PACKAGE_DIRS_EXTRA_INSTALL@/fortran")
# set_and_check(Plumed2_VIM_DIR "@PACKAGE_DIRS_EXTRA_INSTALL@/vim")
# set_and_check(Plumed2_SCRIPTS_DIR "@PACKAGE_DIRS_EXTRA_INSTALL@/scripts")
# set_and_check(Plumed2_PATCHES_DIR "@PACKAGE_DIRS_EXTRA_INSTALL@/patches")

#TODO: add to the manual:
# To compile a fortran executable with plumed you have (at least) two ways write the CMakeLists.txt:
# Method 1:
# ```
# cmake_minimum_required(VERSION 3.20)
# project(exe-test CXX Fortran)
# find_package(Plumed2 REQUIRED)
# add_executable(exe main.f9 source.f90 ${Plumed2_FORTRAN})
# # and then link the wanted plumed library
# target_link_libraries(exe PUBLIC Plumed2::sharedplumedMain)
# ```
# Method 2:
# ```
# cmake_minimum_required(VERSION 3.20)
# project(exe-test CXX Fortran)
# find_package(Plumed2 REQUIRED)
# #compiling PlumedFortran as a separated library
# add_library (PlumedFortran ${Plumed2_FORTRAN})
# add_executable(exe main.f9 source.f90)
# #and linking it to the exe along with the wanted plumed library
# target_link_libraries(exe PUBLIC Plumed2::sharedplumedKernel PlumedFortran)
# ```
set(Plumed2_FORTRAN "${Plumed2_FORTRAN_DIR}/plumed.f90")
set(Plumed2_FORTRAN08 "${Plumed2_FORTRAN_DIR}/plumed_f08.f90")

set(Plumed2_DIR "${CMAKE_CURRENT_LIST_DIR}")

Expand Down