OS: win7_64
前段时间使用 Sublime Text 3, Build 3114
的 snippet 功能对 fortran 语言 写了一些代码片段。挺好用的,现在如果是单纯的编辑 fortran 文件的话已经能够不需要 EditPlus 了(我在 EditPlus 中写过大量的 自动完成内容(.ACP 文件),其实就是代码片段 编写 Sublime Text 代码片段)
但是有个问题,我在 EP 里面配置了 gfortran 工具,可以直接在 EP 的环境中 使用快捷键对 fortran 文件进行编译(并且可以配置额外的快捷键来运行 生成的可执行文件,有兴趣的可以参考这个链接 使用Editplus配置gfortran编译环境 ,至于为什么那样设置参考 EP 的手册,在手册中搜索 Argument Macros
即可看到相关内容),可是现在 ST 中已经安装了 Fortran 这个插件,并且在 build system
下面也是可以看到 gfortran 的,但是却无法正确完成编译过程,总是提示
gfortran: error: 'C:\Users\DELL\Desktop\demo.f90': Invalid argument
此处 demo.f90
正是我要编译的 fortran 源码文件。
到 ST 的文档里面找找 Build Systems 这里面解释说 build system
可能是一个 .sublime-build
文件,于是找到了,Fortran 插件的目录,在这里我们看到了 他所使用的 编译脚本
位于 C:\Users\DELL\AppData\Roaming\Sublime Text 3\Packages\SublimeFortran\build-systems
目录下面
这是里面的内容:
{
"shell_cmd": "gfortran '${file}' -o '${file_path}/${file_base_name}'",
"file_regex": "^(?xi:( ^[/] [^:]* ) : (\\d+) : (\\d+) :)",
"working_dir": "${file_path}",
"selector": "source.modern-fortran, source.fixedform-fortran",
"syntax": "GFortranBuild.sublime-syntax",
"variants":
[
{
"name": "Run",
"shell_cmd": "gfortran '${file}' -o '${file_path}/${file_base_name}' && '${file_path}/${file_base_name}'"
}
]
}
编译脚本使用的都是 json 语法。
另外我还查看了 这个插件的 .py 文件,唉确实不太好看明白,所以放弃了,而且我认为问题就是出在 编译脚本里面。所以我觉得对这个脚本进行重写。 所参考的资料就是 ST 的一个 非官方手册(Build Systems)。
这里面提到 我们的第一行 shell_cmd 和 cmd 其实是一样的,二者选其一即可。
其实首先要做的是 指定 使用范围 selector
,这个直接照抄 原先的 编译脚本即可。
之后我们要做到才是 指定 命令行的命令与参数,这里使用 cmd
。在 写这一行之前我们先来打开 windows 的命令行来手动编译并运行 fortran 程序的一个示例。
PS C:\Users\DELL\Desktop> cat demo.f90
include 'mod.f90'
program demo
use auto
implicit none
read(*,*) m
allocate(a(m))
a=1
write(*,*) a
end program demo
PS C:\Users\DELL\Desktop> cat mod.f90
!----------------------------------------module auto
module auto
implicit none
integer::m
integer,allocatable :: a(:)
! contains
end module auto
!------------------------------------end module auto
PS C:\Users\DELL\Desktop> gfortran demo -o test
gfortran.exe: error: demo: No such file or directory
PS C:\Users\DELL\Desktop> gfortran demo.f90 -o test
PS C:\Users\DELL\Desktop> .\test
5
1 1 1 1 1
PS C:\Users\DELL\Desktop>
可以看到我们这里包含了 module
,而且使用了 include
,使用命令行利用 gfortran 对源文件进行编译的时候 我们所使用的 命令是 gfortran demo.f90 -o test
,而使用 gfortran demo -o test
也就是输入参数不加后缀名是不可以的,这个我们在配置 EP 的工具时候也是这样的(参数为 $(FileName) -o$(FileNameNoExt)
),因为这个也是在直接使用命令行,所以应该遵循命令行的使用规则。
现在我们回去看看 原先的编译脚本 "shell_cmd": "gfortran '${file}' -o '${file_path}/${file_base_name}'",
显然 '{file_path}/,
多余,我们将他删掉(留着也无妨)。但是使用 Ctrl+B
进行编译的时候会得到这样的提示:
gfortran: error: 'C:\Users\DELL\Desktop\demo.f90': Invalid argument
[Finished in 0.1s with exit code 1]
[cmd: gfortran 'C:\Users\DELL\Desktop\demo.f90' -o 'demo']
[dir: C:\Users\DELL\Desktop]
[path: C:\ProgramData\Oracle\Java\javapath;C:\Program Files\Microsoft HPC Pack 2008 R2\Bin\;C:\Program Files (x86)\Common Files\Intel\Shared Libraries\redist\intel64\mpirt;C:\Program Files (x86)\Common Files\Intel\Shared Libraries\redist\intel64\compiler;C:\Program Files (x86)\Common Files\Intel\Shared Libraries\redist\ia32\mpirt;C:\Program Files (x86)\Common Files\Intel\Shared Libraries\redist\ia32\compiler;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\Windows Kits\8.1\Windows Performance Toolkit\;C:\Program Files\Microsoft SQL Server\110\Tools\Binn\;C:\Program Files (x86)\Simply Fortran 2\mingw-w64\bin;C:\Program Files (x86)\Simply Fortran 2\mingw-w64\x86_64-w64-mingw32\lib32;C:\Program Files (x86)\Simply Fortran 2\mingw-w64\x86_64-w64-mingw32\lib64;C:\SIMULIA\Abaqus\Commands;C:\Program Files\MATLAB\R2014b\runtime\win64;C:\Program Files\MATLAB\R2014b\bin;C:\Program Files\MATLAB\R2014b\polyspace\bin;C:\Program Files\ptchelpWildfire 5.0\bin;C:\Program Files\Git LFS;C:\Program Files\nodejs\;C:\Program Files\Git\cmd;C:\Program Files\MiKTeX 2.9\miktex\bin\;C:\Program Files\proeWildfire 5.0\bin;C:\Program Files\proeWildfire 5.0\mech\bin;C:\Program Files\ptc_distributed_services\bin;C:\Users\DELL\AppData\Local\Pandoc\;C:\Users\DELL\AppData\Roaming\npm]
看到了吧, 错误信息里面的第三行 表明我们在 命令行中输入的完整命令是 gfortran 'C:\Users\DELL\Desktop\demo.f90' -o 'demo'
而编译器给我们的回应是(第一行) gfortran: error: 'C:\Users\DELL\Desktop\demo.f90': Invalid argument
无效参数。
很明显 使用原先的脚本 我们的命令和正确的命令 gfortran demo.f90 -o demo
(输出参数可以任意指定)相比 区别就是在 输入和输出参数上分别加上了单引号,正是单引号的原因我们的参数不能被正确识别,到这里我们已经能够知道这句话在脚本里面应该怎么写了。我所写的脚本很简单,有效内容只有四行。
{
"cmd": "gfortran ${file} -o ${file_base_name}",
"selector": "source.modern-fortran, source.fixedform-fortran",
}
目前来看只有这两个命令是有效的,所以其他的哪些参数我在此并未引入。
好了现在可以愉快的使用 ST 来编写和编译 fortran 代码了。
更多使用方法(比如带参数的编译)还在探索中(目前我本人是用不到的,而且我根本不擅长命令行)
最后总结一下原先的脚本问题出在哪里
命令中进行编译的语句 他的输入和输出参数 包含了多余的 单引号 ' ' ,而这导致了实际中被传入的参数是不正确的。