计算化学公社

标题: CMake如何支持Fortran中的USE声明 [打印本页]

作者
Author:
万里云    时间: 2018-4-21 10:38
标题: CMake如何支持Fortran中的USE声明
本帖最后由 万里云 于 2018-4-21 15:39 编辑

先拿C举个例子,说明问题。

比如我们有一个程序,可以根据氢原子薛定谔方程解析解,给定量子数nlm,输出对应波函数到cube格式文件。

现在这个程序由三个c源码文件和两个头文件组成:
psi.c:主函数所在文件
rnl.c:实现径向分布函数Rnl,其函数原型声明放在rnl.h中
ylm.c:实现球谐函数Ylm,其函数原型声明放在ylm.h中

每个c源码中所包含的头文件为:
psi.c: rnl.h ylm.h
rnl.c: rnl.h
ylm.c: ylm.h

假设我们修改了rnl.h,因为rnl.c和psi.c都包含了这个头文件,因此我们需要重新编译这两个文件。这种依赖关系在CMake中只需
  1. add_executable(psi.x psi.c rnl.c ylm.c)
复制代码
即可。CMake会自动搜索每个c文件依赖的头文件,并在Makefile中为其创建规则。运行结果也正是我们所设想的:psi.c和rnl.c被重新编译,最后重新链接生成psi.x。
> touch rnl.h
> make
Scanning dependencies of target psi.x
[ 20%] Building C object CMakeFiles/psi.x.dir/psi.c.o
[ 40%] Building C object CMakeFiles/psi.x.dir/rnl.c.o
[ 60%] Linking C executable psi.x

[100%] Built target psi.x

但是同样的方法对于Fortran却不行。

假设我们有一个程序由三个文件组成:
analyldos.f90:主程序
sumldos.f90:提供了一个子程序sumldos
shareddata.f90:提供了一个模块shareddata,用于在主程序和子程序中共享数据(如果以参数形式传递给子程序,参数列表就太长了)

正确的编译过程应该是:
先编译shareddata.f90,生成shareddata.o和shareddata.mod
analyldos.f90和sumldos.f90可以同时编译,编译时需要shareddata.mod
最后链接shareddata.o sumldos.o analyldos.o生成可执行文件

如果我们修改了shareddata.f90,就需要重新编译生成shareddata.o和shareddata.mod。因为所依赖的模块变动,analyldos.f90和sumldos.f90也需要重新编译。仿照上面的C语言程序
  1. add_executable(analyldos.x analyldos.f90 sumldos.f90 shareddata.f90)
复制代码
然后
> touch shareddata.f90
> make
Scanning dependencies of target analyldos.x
[ 25%] Building Fortran object CMakeFiles/analyldos.x.dir/shareddata.f90.o
[ 50%] Linking Fortran executable analyldos.x

[100%] Built target analyldos.x
然而只重新编译了shareddata.f90,并没有编译另外两个模块。

把sumldos和shareddata声明为library,再用add_dependencies声明sumldos依赖shareddata也不行
  1. add_executable(analyldos.x analyldos.f90)  
  2. add_library(sumldos sumldos.f90)
  3. add_library(shareddata shareddata.f90)

  4. target_link_libraries(analyldos.x sumldos shareddata)
  5. add_dependencies(sumldos shareddata)
复制代码
> touch shareddata.f90
> make
Scanning dependencies of target shareddata
[ 16%] Building Fortran object CMakeFiles/shareddata.dir/shareddata.f90.o
[ 33%] Linking Fortran static library libshareddata.a

[ 33%] Built target shareddata
[ 66%] Built target sumldos
[ 83%] Linking Fortran executable analyldos.x
[100%] Built target analyldos.x
依然是只重新编译了shareddata.f90。

有什么办法解决吗?

========================2018-04-21更新========================
已找到解决方案scons http://www.scons.org/,不用自己造轮子了。





欢迎光临 计算化学公社 (http://bbs.keinsci.com/) Powered by Discuz! X3.3