我有一个很大的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
文件中定义lib2
和CMakeLists.txt
的顺序如何,以及在编译了程序之后,在运行rm foo.mod ; touch ../dir1/lib1.f90
之后定义的顺序,一个可靠的解决方案都应该起作用。 最佳答案
这里的问题是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)
关于cmake - CMake:Fortran模块和编译顺序,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/56634781/