copying fortran .mod files in different directories

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

copying fortran .mod files in different directories

Lukas van de Wiel
Dear more experienced cmake user,

we are running a Fortran code containing several dozen modules. These are build in two versions, differentiated by #ifdef statements. The archive files of the two versions are being kept apart by different file names, but the .mod files have fixed names, based on the name of the module. During a parallel build, a .mod file of one version may be overwritten by the partner .mod file while the first one is still required by other bits of ode that depends on it.

To circumvent it, I wrote .mod files of each variety in their own directory using

target_compile_option(moduleTarget PUBLIC -JdirectoryName)

but then, during the copy phase, cmake cannot find the module, because I circumvented the cmake way with the -J option of gfortran, which gives the option to direct .mod files to a different directory, which works, but when those modules are actually used, I get:

Error copying Fortran module "modulename.mod. Tried "MODULENAME.mod" and "modulename.mod"

To illustrate the problem I have written a simple test case that is conceptually the same, that consist of two tiny Fortran snippets and the CMakeLists.txt failing to build it. In this simple case, the program is idiotic. It has a cat version and a dog version, and it does the cat variety with -Dcat, otherwise it does the dog variety. cmake runs well, but making shows cmake in trouble:

>make VERBOSE=1
.
.
/usr/bin/cmake -E cmake_copy_f90_mod pets.mod CMakeFiles/dogModule.dir/pets.mod.stamp GNU
Error copying Fortran module "pets.mod".  Tried "PETS.mod" and "pets.mod".

So in short, how can the location of these .mod files in a target specific version, in stead of with the generic
CMAKE_Fortran_MODULE_DIRECTORY that will just cause the /mod files to overwrite each other in a different directory?

Also adding the directories where the mod files are as target specific include directories does not help cmake...

I am very curious what would be the cmake way of doing this properly.

Thank you very much for your time and expertise!

Lukas

############ the module file; pets.F

module pets
implicit none
contains

#ifdef cat
subroutine cattalk()
write(*,*) "meow"
#else
subroutine dogtalk()
write(*,*) "woof"
#endif
end subroutine

end module

############ the main.F

program main
#ifdef cat
use pets, only: cattalk
implicit none
call cattalk()
#else
use pets, only: dogtalk
implicit none
call dogtalk()
#endif
end program

############ and CMakeLists.txt

project(pets LANGUAGES Fortran)

file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/catdir)
file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/dogdir)

set(catdir ${CMAKE_BINARY_DIR}/catdir)
set(dogdir ${CMAKE_BINARY_DIR}/dogdir)

set(CMAKE_Fortran_SOURCE_FILES_EXTENSIONS F)
set(CMAKE_Fortran_FLAGS "-cpp -std=f2008 -ffree-form")

add_library(catModule STATIC "src/pets.F")
target_compile_options(catModule PUBLIC "-Dcat -J${catdir}")

add_library(dogModule STATIC "src/pets.F")
target_compile_options(dogModule PUBLIC "-J${dogdir}")

add_executable(cat "src/main.F")
add_dependencies(cat catModule)
target_link_libraries(cat catModule)
target_compile_options(cat PUBLIC "-Dcat")

add_executable(dog "src/main.F")
add_dependencies(dog dogModule)
target_link_libraries(dog dogModule)

####################################


--

Powered by kitware.com/cmake

Kitware offers various services to support the CMake community. For more information on each offering, please visit https://cmake.org/services

Visit other Kitware open-source projects at https://www.kitware.com/platforms

Follow this link to subscribe/unsubscribe:
https://cmake.org/mailman/listinfo/cmake

This mailing list is deprecated in favor of https://discourse.cmake.org
Reply | Threaded
Open this post in threaded view
|

Re: copying fortran .mod files in different directories

Bill Somerville
On 04/03/2020 09:24, Lukas van de Wiel wrote:

> we are running a Fortran code containing several dozen modules. These
> are build in two versions, differentiated by #ifdef statements. The
> archive files of the two versions are being kept apart by different
> file names, but the .mod files have fixed names, based on the name of
> the module. During a parallel build, a .mod file of one version may be
> overwritten by the partner .mod file while the first one is still
> required by other bits of ode that depends on it.
>
> To circumvent it, I wrote .mod files of each variety in their own
> directory using
>
> target_compile_option(moduleTarget PUBLIC -JdirectoryName)
>
Hi Lukas,

we do something similar. We have it working by setting the target
property Fortran_MODULE_DIRECTORY, in our case that is on a static
library which contains the Fortran object code. We have two versions,
one built with OpenMP and another without. One library has a default
module directory and for the other we set the property above to a
sub-directory of the binary directory, e.g.
"set_target_properties(<target>, Fortran_MODULE_DIRECTORY,
${CMAKE_BINARY_DIR}/fortran_modules_omp)". We also set the property on
the final executables where required so I assume it does not propagate
outwards from the static library to executables linking it :(

Regards
Bill Somerville.

--

Powered by kitware.com/cmake

Kitware offers various services to support the CMake community. For more information on each offering, please visit https://cmake.org/services

Visit other Kitware open-source projects at https://www.kitware.com/platforms

Follow this link to subscribe/unsubscribe:
https://cmake.org/mailman/listinfo/cmake

This mailing list is deprecated in favor of https://discourse.cmake.org
Reply | Threaded
Open this post in threaded view
|

Re: copying fortran .mod files in different directories

Lukas van de Wiel
Hi Bill,

Thanks a lot for your quick response! Using your idea I could set the Fortran module directory per module target, and add those directories as target_include_directories to the executables. Worked like a charm!

Lukas

PS. As example, I adapted my cat/dog CMakeLists.txt to this to get to work, in parallel build 'n all:

project(pets LANGUAGES Fortran)

file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/catdir)
file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/dogdir)

set(catdir "${CMAKE_BINARY_DIR}/catdir")
set(dogdir "${CMAKE_BINARY_DIR}/dogdir")

set(CMAKE_Fortran_SOURCE_FILES_EXTENSIONS F)
set(CMAKE_Fortran_FLAGS "-cpp -std=f2008 -ffree-form")

add_library(catModule STATIC "src/pets.F")
target_compile_options(catModule PUBLIC "-Dcat")
set_target_properties(catModule PROPERTIES Fortran_MODULE_DIRECTORY ${catdir})

add_library(dogModule STATIC "src/pets.F")
set_target_properties(dogModule PROPERTIES Fortran_MODULE_DIRECTORY ${dogdir})

add_executable(cat "src/main.F")
target_include_directories(cat PUBLIC ${catdir})
add_dependencies(cat catModule)
target_link_libraries(cat catModule)
target_compile_options(cat PUBLIC "-Dcat")

add_executable(dog "src/main.F")
target_include_directories(dog PUBLIC ${dogdir})
add_dependencies(dog dogModule)
target_link_libraries(dog dogModule)







On Wed, Mar 4, 2020 at 11:10 AM Bill Somerville <[hidden email]> wrote:
On 04/03/2020 09:24, Lukas van de Wiel wrote:
> we are running a Fortran code containing several dozen modules. These
> are build in two versions, differentiated by #ifdef statements. The
> archive files of the two versions are being kept apart by different
> file names, but the .mod files have fixed names, based on the name of
> the module. During a parallel build, a .mod file of one version may be
> overwritten by the partner .mod file while the first one is still
> required by other bits of ode that depends on it.
>
> To circumvent it, I wrote .mod files of each variety in their own
> directory using
>
> target_compile_option(moduleTarget PUBLIC -JdirectoryName)
>
Hi Lukas,

we do something similar. We have it working by setting the target
property Fortran_MODULE_DIRECTORY, in our case that is on a static
library which contains the Fortran object code. We have two versions,
one built with OpenMP and another without. One library has a default
module directory and for the other we set the property above to a
sub-directory of the binary directory, e.g.
"set_target_properties(<target>, Fortran_MODULE_DIRECTORY,
${CMAKE_BINARY_DIR}/fortran_modules_omp)". We also set the property on
the final executables where required so I assume it does not propagate
outwards from the static library to executables linking it :(

Regards
Bill Somerville.

--

Powered by kitware.com/cmake

Kitware offers various services to support the CMake community. For more information on each offering, please visit https://cmake.org/services

Visit other Kitware open-source projects at https://www.kitware.com/platforms

Follow this link to subscribe/unsubscribe:
https://cmake.org/mailman/listinfo/cmake

This mailing list is deprecated in favor of https://discourse.cmake.org

--

Powered by kitware.com/cmake

Kitware offers various services to support the CMake community. For more information on each offering, please visit https://cmake.org/services

Visit other Kitware open-source projects at https://www.kitware.com/platforms

Follow this link to subscribe/unsubscribe:
https://cmake.org/mailman/listinfo/cmake

This mailing list is deprecated in favor of https://discourse.cmake.org