177 lines
7.9 KiB
Vue
177 lines
7.9 KiB
Vue
<script setup lang="ts">
|
|
|
|
</script>
|
|
|
|
<template>
|
|
<div>
|
|
<h1 class="text-3xl">Setting Up The Environment</h1>
|
|
<hr class="mb-6">
|
|
|
|
<p class="mb-6">If you're familiar with C, then you would feel right at home with Fortran's build environment. There isn't really
|
|
an "official" compiler for the language, only a standard, that has to be implemented by the compilers. But there
|
|
are a lot of great compilers, that might as well be "official."<br><br>
|
|
The top listed compiler on Fortran's website, is the GNU Fortran compiler (gfortran). It's the one I will be using
|
|
throughout the examples on the site. Unless stated otherwise. There are also some other notable compilers, that
|
|
has some rather interesting qualities to them.</p>
|
|
|
|
<p>Compilers:</p>
|
|
<ul class="mb-6">
|
|
<li>> <a class="underline" href="https://lfortran.org/">lfortran</a> (This one can be used as an interactive
|
|
compiler, supports parsing all of the 2018 standard syntax and also compile Fortran to WebAssemply).</li>
|
|
<li>> <a class="underline" href="https://developer.nvidia.com/hpc-sdk">NVIDIA HPC SDK</a> (This one comes with a whole lot of GPU
|
|
accelerated libraries).</li>
|
|
</ul>
|
|
|
|
<p class="mb-6">But we will be using gfortran. Through the examples on this site, I will mainly be focusing on developing on Linux. <br>
|
|
First, we install the compiler.</p>
|
|
|
|
<p>For Fedora.</p>
|
|
<code class="text-red-500 mb-6">$ sudo dnf install gcc-gfortran</code>
|
|
|
|
<p>For ubuntu.</p>
|
|
<code class="text-red-500 mb-6">$ sudo apt install gfortran</code>
|
|
|
|
<p class="mb-6">And that's it. Pretty easy.</p>
|
|
|
|
<h2 class="text-2xl">Project Structure</h2>
|
|
<hr class="mb-6">
|
|
|
|
<p class="mb-6">When creating a Fortran project, or any project in general, you want a structure. There is a lot of different
|
|
layouts for the structure, but equal amongst them, is the <code class="text-red-500">src</code> folder. That's where we keep all of out
|
|
source code. Like <code class="text-red-500">*.f90, *.f95</code> files.<br><br>
|
|
|
|
But other than that, most projects include a <code class="text-red-500">Makefile</code> file, a
|
|
<code class="text-red-500">library</code>, <code class="text-red-500">test</code>
|
|
and <code class="text-red-500">bin</code> folder. Your layout doesn't need to look like this specifically, nor does it have to contain
|
|
the same folders. Each project is different, and so are the requirements. But this layout is simple, and great
|
|
for medium to large projects.<br><br>
|
|
But if we're doing micro-projects, as in like, a hello world application, a test application, or a small tool,
|
|
this layout is rather redundant, and in the examples on this site, we will only use it on bigger projects,
|
|
and we will let you know, when or how we set up the project.</p>
|
|
|
|
<div class="font-mono shadow-lg shadow-slate-500 p-2 mb-6">
|
|
<pre><code class="text-sm">
|
|
project/
|
|
├── src/ # Source files (.f90, .f95, etc.)
|
|
│ ├── modules/ # Module definitions
|
|
│ └── main.f90 # Main program file
|
|
├── include/ # Include files (e.g., interface definitions)
|
|
├── lib/ # Library object files and archives
|
|
├── bin/ # Executable binaries
|
|
├── tests/ # Test cases
|
|
└── Makefile # Build script
|
|
</code></pre>
|
|
</div>
|
|
<br>
|
|
|
|
<p>Notes:</p>
|
|
<ul class="mb-6">
|
|
<li>> <code class="text-red-500">src</code> (This is where we keep all of out source code).</li>
|
|
<li>> <code class="text-red-500">modules</code> (This is where we keep our classes. Or in Fortran-speak, modules).</li>
|
|
<li>> <code class="text-red-500">include</code> (This is where we keep our interfaces, that out modules will inherit from, if we're using Fortran 90 or above).</li>
|
|
<li>> <code class="text-red-500">bin</code> (This is where the compiled program should end up in).</li>
|
|
</ul>
|
|
|
|
|
|
<h2 class="text-2xl">Compiling</h2>
|
|
<hr class="mb-6">
|
|
|
|
<p class="mb-6">Makefiles are very useful, and becomes increasingly useful, the bigger the project gets. A makefile simplifies the
|
|
compilation process, as all of the compile flags can be gathered inside a single file. It makes it possible to
|
|
dynamically change the compilation depending on the system architecture or config. It also removes the need to
|
|
manually compile and link your objects together, every time you make a change.<br><br>
|
|
|
|
And with a bigger project, comes a big count of source files. That's where a makefile helps a lot, as it handles
|
|
and tracks all changes to each file, ensuring that it's only the changed files that gets re-compiled.<br><br>
|
|
|
|
So let's see a makefile in action. Below code is a simple Hello World application, that we will use a makefile to
|
|
compile. Although it's worth noting, that a program this small, a makefile is wildly redundant. But it does show
|
|
how it's set up in a simple environment.</p>
|
|
|
|
|
|
<code class="text-red-500">hello.f90</code>
|
|
<div class="font-mono shadow-lg shadow-slate-500 p-2 mb-6">
|
|
<pre><code class="text-sm">
|
|
program hello
|
|
implicit none
|
|
print *, 'Hello, World!'
|
|
end program hello
|
|
</code></pre>
|
|
</div>
|
|
|
|
|
|
<p class="mb-6">The makefile, in the eyes of a modern programmer (C#, Python, JS, Etc) might look rather repulsive. But be not
|
|
afraid. It will all make sense in a bit.</p>
|
|
|
|
<ul>
|
|
<li>> <code class="text-red-500">hello: hello.o</code></li>
|
|
<li class="pb-2">> > Here, the program "hello" depends on the object file "hello.o".</li>
|
|
<li>> <code class="text-red-500">$(FC) $(FFLAGS) -o $@ $^</code></li>
|
|
<li class="pb-2">> > This one compiles the object files into the program.</li>
|
|
<li>> <code class="text-red-500">hello.o: hello.f90</code></li>
|
|
<li class="pb-2">> > Here, the object file "hello.o" depends on the source file "hello.f90".</li>
|
|
<li>> <code class="text-red-500">$(FC) $(FFLAGS) -c $<</code></li>
|
|
<li class="pb-2">> > This one compiles the source files into the object files.</li>
|
|
<li>> <code class="text-red-500">run: ./hello</code></li>
|
|
<li class="pb-2">> > This runs the program if you execute <code class="text-red-500">make run</code></li>
|
|
<li>> <code class="text-red-500">clean: rm -f *.o hello</code></li>
|
|
<li class="pb-2">> > Here, the object files gets removed when running <code class="text-red-500">make clean</code></li>
|
|
</ul>
|
|
<br>
|
|
|
|
<p class="mb-6">A quick note. It's very important that whenever something is indented in a makefile, that it's indented with a tab,
|
|
and not 4 spaces. It needs to be a tab character.</p>
|
|
|
|
<code class="text-red-500">makefile</code>
|
|
<div class="font-mono shadow-lg shadow-slate-500 p-2 mb-6">
|
|
<pre><code class="text-sm">
|
|
Makefile for hello.f90
|
|
|
|
FC = gfortran # Fortran compiler
|
|
FFLAGS = -O2 # Compiler flags (optimization level)
|
|
|
|
hello: hello.o
|
|
$(FC) $(FFLAGS) -o $@ $^
|
|
|
|
hello.o: hello.f90
|
|
$(FC) $(FFLAGS) -c $<
|
|
|
|
run:
|
|
./hello
|
|
|
|
clean:
|
|
rm -f *.o hello
|
|
</code></pre>
|
|
</div>
|
|
|
|
<p class="mb-6">Now simply run the makefile with the following command.</p>
|
|
|
|
<div class="font-mono shadow-lg shadow-slate-500 p-2 mb-6">
|
|
<pre><code class="text-sm">
|
|
$ make
|
|
gfortran -O2 -c hello.f90
|
|
gfortran -O2 -o hello hello.o
|
|
</code></pre>
|
|
</div>
|
|
|
|
<p class="mb-6">We have now successfully compiled the program with the help of a makefile. Now simply run the program and we'll
|
|
see the output.</p>
|
|
|
|
<div class="font-mono shadow-lg shadow-slate-500 p-2 mb-6">
|
|
<pre><code class="text-sm">
|
|
$ ./hello
|
|
Hello, World!
|
|
</code></pre>
|
|
</div>
|
|
|
|
<p class="mb-6">The exact same should happen, if we run the next command instead.</p>
|
|
|
|
<div class="font-mono shadow-lg shadow-slate-500 p-2 mb-6">
|
|
<pre><code class="text-sm">
|
|
$ make run
|
|
./hello
|
|
Hello, World!
|
|
</code></pre>
|
|
</div>
|
|
</div>
|
|
</template> |