CMake:Fortran模块和编译顺序

时间:2019-06-17 15:46:33

标签: cmake fortran

我有一个很大的Fortran程序,其中包含许多目录。每个目录都是在伪库中单独编译的,但是仍然存在相互依赖的混乱,因此最后,所有伪库都组合在一个可用的库中。我想使用Fortran模块,但是它非常脆弱,因为我不能依靠自动依赖检查,并且编译可能会失败,具体取决于顺序。

例如,考虑以下CMakeLists.txt文件:

project (test Fortran)
add_library (lib1 dir1/lib1.f90)
add_library (lib2 dir2/lib2.f90 dir2/mod.f90)
add_executable (exe dir3/exe.f90)
target_link_libraries (exe lib1 lib2)

来源:

dir1/lib1.f90

subroutine bar
use foo, only: foofoo
implicit none
write(6,*) foofoo
end subroutine bar

dir2/lib2.f90

subroutine bar2
use foo, only: foofoo
implicit none
write(6,*) foofoo,' again'
end subroutine bar2

dir2/mod.f90

module foo
implicit none
integer :: foofoo=3
end module foo

dir3/exe.f90

program meh
implicit none
call bar()
call bar2()
end program meh

从头开始编译失败:

$ make
[ 25%] Building Fortran object CMakeFiles/lib1.dir/dir1/lib1.f90.o
/home/user/cmake/dir1/lib1.f90:2.4:

use foo, only: foofoo
    1
Fatal Error: Can't open module file 'foo.mod' for reading at (1): No such file or directory
make[2]: *** [CMakeFiles/lib1.dir/dir1/lib1.f90.o] Error 1
make[1]: *** [CMakeFiles/lib1.dir/all] Error 2
make: *** [all] Error 2

但按正确的顺序进行操作可以

$ make lib2
Scanning dependencies of target lib2
[ 50%] Building Fortran object CMakeFiles/lib2.dir/dir2/mod.f90.o
[100%] Building Fortran object CMakeFiles/lib2.dir/dir2/lib2.f90.o
Linking Fortran static library liblib2.a
[100%] Built target lib2
$ make
[ 25%] Building Fortran object CMakeFiles/lib1.dir/dir1/lib1.f90.o
Linking Fortran static library liblib1.a
[ 25%] Built target lib1
[ 75%] Built target lib2
Scanning dependencies of target exe
[100%] Building Fortran object CMakeFiles/exe.dir/dir3/exe.f90.o
Linking Fortran executable exe
[100%] Built target exe

CMake有什么方法可以找出依赖性并在lib2之前编译mod.f90(或至少lib1)?

ETA:无论在lib1文件中定义lib2CMakeLists.txt的顺序如何,并且一旦编译了程序,运行{{ 1}}。

2 个答案:

答案 0 :(得分:4)

这里的问题是lib1目标mod.f90的必需对象文件。但是CMakeLists.txt中没有提及创建mod.f90.o时创建liblib1.a的规则。为lib2创建了目标mod.f90.o

可能有以下两种可能的解决方案。

解决方案1 ​​

mod.f90添加到两个库中。

project (test Fortran)
add_library (lib1 dir1/lib1.f90 dir2/mod.f90)
add_library (lib2 dir2/lib2.f90 dir2/mod.f90)
add_executable (exe dir3/exe.f90)
target_link_libraries (exe lib1 lib2)

解决方案2

使用mod.f90.o将库链接到其他库。

project (test Fortran)
add_library (lib1 dir1/lib1.f90)
add_library (lib2 dir2/lib2.f90 dir2/mod.f90)
add_dependencies(lib1 lib2)
add_executable (exe dir3/exe.f90)
target_link_libraries (exe lib1 lib2)

答案 1 :(得分:0)

upcoming ninja build system version (1.10.0)支持动态依赖关系,可以正确解析模块的编译顺序。

要将其与CMake一起使用,必须指定Ninja生成器:

cmake .. -DCMAKE_GENERATOR=Ninja # generate project
ninja # build the project