使用 CLion 與 CMake 開發 Fortran

Fortran 作為一個打孔卡時代就存在的古老程式語言,除了學校教的 Vim 或 Notepad 以外,其實可以使用較為現代的 IDE 來減少開發上的阻力,有很多不錯的功能像是一鍵編譯、語法檢查等等。傳統使用指令編譯與 Vim 編輯的方法還是得先了解過,以備不時之需。

CLion 是由 PyCharm 的母公司 JetBrains 所開發的 C/C++ IDE,裝上插件後也可以拿來寫 Fortran。

Generate by Midjourney niji 5

在這裡先假設已經灌好 Fortran 跟 CLion 了,如果 Fortran 還沒安裝可以看看這篇:Installing GFortran

第一次安裝好 CLion 後要先灌 Fortran 插件,從歡迎頁面中左邊選單有個 Plugins,到 Marketplace 尋找這個 Fortran 插件

在創立新 Project 時就有 Fortran executable 可以選

創立好 Project 後,裡面就會發現系統預先建立好的 CMakeLists.txt 模板

CLion 主要就是靠這個 CMakeLists 讓電腦知道要編譯什麼程式碼,將 進入 Vim > 改程式 > 存檔退出 Vim > 指令編譯 > 執行 這繁瑣的步驟變成一鍵完成


前面三行是系統產生的模板,注意 Fortran 關鍵字不能刪掉,系統才會知道要用 Fortran 編譯器。

要編譯程式碼很簡單,語法是 add_executable(執行檔 程式碼)

1
2
3
4
cmake_minimum_required(VERSION 3.26)
project(Example Fortran)
enable_language(Fortran)
add_executable(Example main.f90)

如果改動 CMakeLists 後 CLion 會提醒要重整 Cmake,如果提示跳太快也可以對 CMakeLists.txt 按右鍵選取 Reload CMake Project 重整。

重整成功的話,會在右上角看到對應的執行檔,要先選擇要執行動作的程式,按鐵鎚圖示可以編譯,按播放鍵圖示可以執行。


由於 CMake 會先把程式碼複製到 cmake-build-debug 的資料夾裡面再編譯,所以其他依賴的外部程式也要先複製過去,在編譯的時候才會找得到。

1
2
3
4
5
6
7
configure_file(pgfont.txt pgfont.txt COPYONLY)
configure_file(seisdata.txt seisdata.txt COPYONLY)
configure_file(pgplot.inc pgplot.inc COPYONLY)
configure_file(grpckg1.inc grpckg1.inc COPYONLY)
file(COPY data DESTINATION .)
add_executable(plot_seismogram plot_seismogram.f90 pgplotl.for)
add_executable(plot_epicenter plot_epicenter.f90 pgplotl.for)

如上面第 1 行使用 configure_file(來源檔名 目的檔名 COPYONLY) 複製單一檔案,或是利用如上面第 5file(COPY 資料夾 DESTINATION 目的地)複製整個資料夾,最後如上面第 7 行一樣在編譯的時候把所有的外部程式都加到主程式的後面。


完整的 CMakeList 範例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
cmake_minimum_required(VERSION 3.23)
project(Geo5101 Fortran)
enable_language(Fortran)
add_executable(hw01_1 hw01_1.f90)
add_executable(hw01_2 hw01_2.f90)
add_executable(hw01_3 hw01_3.f90)
add_executable(hw02_1 hw02_1.f90)
add_executable(hw02_2 hw02_2.f90)
add_executable(hw03_1 hw03_1.f90)
add_executable(hw03_2 hw03_2.f90)
configure_file(pgfont.txt pgfont.txt COPYONLY)
configure_file(seisdata.txt seisdata.txt COPYONLY)
configure_file(pgplot.inc pgplot.inc COPYONLY)
configure_file(grpckg1.inc grpckg1.inc COPYONLY)
file(COPY data DESTINATION .)
add_executable(plot_seismogram plot_seismogram.f90 pgplotl.for)
add_executable(plot_epicenter plot_epicenter.f90 pgplotl.for)
add_executable(plot_regression plot_regression.f90 pgplotl.for)
add_executable(plot_vp plot_vp.f90 pgplotl.for)
add_executable(plot_vp_pert plot_vp_pert.f90 pgplotl.for)
configure_file(XYFIT.f90 XYFIT.f90 COPYONLY)
configure_file(locpt.f90 locpt.f90 COPYONLY)
add_executable(hw06_1 hw06_1.f90 locpt.f90 pgplotl.for)
add_executable(hw06_2 hw06_2.f90 XYFIT.f90 pgplotl.for)
configure_file(matinv.f90 matinv.f90 COPYONLY)
add_executable(hw06_3 hw06_3.f90 matinv.f90)
add_executable(hw08_1 hw08_1.f90 pgplotl.for)
configure_file(proj.f90 proj.f90 COPYONLY)
add_executable(hw09_1 hw09_1.f90 proj.f90 pgplotl.for)
add_executable(hw09_2 hw09_2.f90 FFT.FOR pgplotl.for)
add_executable(hw10_1 hw10_1.f90 FFT.FOR bpfilter.f pgplotl.for)
add_executable(hw10_2 hw10_2.f90 FFT.FOR bpfilter.f pgplotl.for)

整個 Project 資料夾結構如圖:


討論

Q:是不是可以叫 CMakeList 自己找出 .f90 的檔案自己編譯?

A:技術上是可以做得到的,但是不建議這麼做,因為這樣沒有辦法控制哪些程式碼會被編譯,甚至會執行了不該執行的程式。


發表迴響