Skip to content

Update building programs book #156

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Dec 1, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
594 changes: 537 additions & 57 deletions learn/building_programs/build_tools.md

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions learn/building_programs/compiling_source.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ permalink: /learn/building_programs/compiling_source
---

The first step in the build process is to compile the source code. The
output from this step is generally known as the object code - a set of
output from this step is generally known as the object code a set of
instructions for the computer generated from the human-readable source
code. Different compilers will produce different object codes from the
same source code and the naming conventions are different.
Expand Down Expand Up @@ -54,7 +54,7 @@ Windows.
Some remarks:

* The compiler may complain about the contents of the source file, if it
finds something wrong with it - a typo for instance or an unknown
finds something wrong with it a typo for instance or an unknown
keyword. In that case the compilation process is broken off and you will
not get an object file or an executable program. For instance, if
the word "program" was inadvertently typed as "prgoram":
Expand All @@ -78,7 +78,7 @@ Using this compilation report you can correct the source code and try
again.

* The step without "-c" can only succeed if the source file contains a
main program - characterised by the `program` statement in Fortran.
main program characterised by the `program` statement in Fortran.
Otherwise the link step will complain about a missing "symbol", something
along these lines:

Expand All @@ -98,9 +98,9 @@ compiler running in a Cygwin environment on Windows.

Compilers also differ in the options they support, but in general:

* Options for optimising the code - resulting in faster programs or
* Options for optimising the code resulting in faster programs or
smaller memory footprints;
* Options for checking the source code - checks that a variable is not
* Options for checking the source code checks that a variable is not
used before it has been given a value, for instance or checks if some
extension to the language is used;
* Options for the location of include or module files, see below;
Expand Down
10 changes: 5 additions & 5 deletions learn/building_programs/distributing.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ choose from:

__Option 1: Distribute the entire source code__

By far the simplest - for you as a programmer - is this one: you leave it
By far the simplest for you as a programmer is this one: you leave it
up to the user to build it on their own machine. Unfortunately, that
means you will have to have a user-friendly build system in place and
the user will have to have access to suitable compilers. For build systems:
Expand Down Expand Up @@ -79,17 +79,17 @@ end module user_functions
* Provide a basic build script with a command like:

```shell
gfortran -o function.dll function.f90 -shared
gfortran -o functions.dll functions.f90 -shared
```

or:

```shell
ifort -exe:function.dll function.f90 -dll
ifort -exe:functions.dll functions.f90 -dll
```

As said, you cannot control that the user has done the right thing - any
DLL "function.dll" with a function `f` would be accepted, but not necessarily
As said, you cannot control that the user has done the right thing any
DLL "functions.dll" with a function `f` would be accepted, but not necessarily
lead to a successful run.

An alternative set-up would be to change the main program into a subroutine
Expand Down
22 changes: 11 additions & 11 deletions learn/building_programs/include_files.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,14 @@ tabulate/
main/
tabulate.f90
sub/
function.f90
functions.f90
```

Compiling the file "function.f90" with the commands
Compiling the file "functions.f90" with the commands

```shell
$ cd sub
$ gfortran -c function.f90
$ gfortran -c functions.f90
```

leads to this structure:
Expand All @@ -51,18 +51,18 @@ tabulate/
main/
tabulate.f90
sub/
function.f90
function.mod
function.o
functions.f90
user_functions.mod
functions.o
```

To successfully compile and subsequently build the program we need to
tell the compiler where it can find the file "function.mod":
tell the compiler where it can find the file "user\_functions.mod":

```shell
$ cd main
$ gfortran -c tabulate.f90 -I ../sub
$ gfortran -o tabulate tabulate.o ../sub/function.o
$ gfortran -o tabulate tabulate.o ../sub/functions.o
```

The result:
Expand All @@ -74,9 +74,9 @@ tabulate/
tabulate.o
tabulate (or tabulate.exe on Windows)
sub/
function.f90
function.mod
function.o
functions.f90
functions.o
user_functions.mod
```

Notes:
Expand Down
4 changes: 2 additions & 2 deletions learn/building_programs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ author: Arjen Markus, Ondřej Čertík, Milan Curcic, Laurence Kedward, Brad Ric
Languages like Fortran, C, C++ and Java, to name but a few, share
certain characteristics: you write code in your language of choice but
then you have to build an executable program from that source code.
Other languages are interpreted - the source code is analysed by a
Other languages are interpreted the source code is analysed by a
special program and taken as direct instructions. Two very simple
examples of that type of language: Windows batch files and Linux shell
scripts.
Expand Down Expand Up @@ -38,7 +38,7 @@ it is simple to express in source code, a lot of things actually happen
when the executable that is built from this code runs:

* A process is started on the computer in such a way that it can write
to the console - the window (DOS-box, xterm, ...) at which you type the
to the console the window (DOS-box, xterm, ...) at which you type the
program's name.
* It writes the text "Hello!" to the console. To do so it must properly
interact with the console.
Expand Down
16 changes: 8 additions & 8 deletions learn/building_programs/linking_pieces.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@ program tabulate
end program tabulate
```

Note the `use` statement - this will be where we define the function `f`.
Note the `use` statement this will be where we define the function `f`.

We want to make the program general, so keep the
specific source code - the implementation of the function `f` -
specific source code the implementation of the function `f`
separated from the general source code. There are several ways to
achieve this, but one is to put it in a different source file. We can
give the general program to a user and they provide a specific source code.
Expand Down Expand Up @@ -60,12 +60,12 @@ program. Because the program "tabulate" depends on the module
first. A sequence of commands to do this is:

```shell
$ gfortran -c function.f90
$ gfortran tabulate.f90 function.o
$ gfortran -c functions.f90
$ gfortran tabulate.f90 functions.o
```

The first step compiles the module, resulting in an object file
"function.o" and a module intermediate file, "function.mod". This module
"functions.o" and a module intermediate file, "user\_functions.mod". This module
file contains all the information the compiler needs to determine that
the function `f` is defined in this module and what its interface is. This
information is important: it enables the compiler to check that you call
Expand All @@ -77,13 +77,13 @@ check anything.
The second step invokes the compiler in such a way that:

* it compiles the file "tabulate.f90" (using the module file);
* it invokes the linker to combine the object files tabulate.o and function.o into an
executable program - with the default name "a.out" or "a.exe" (if you
* it invokes the linker to combine the object files tabulate.o and functions.o into an
executable program with the default name "a.out" or "a.exe" (if you
want a different name, use the option "-o").

What you do not see in general is that the linker also adds a number of
extra files in this link step, the run-time libraries. These run-time
libraries contain all the "standard" stuff - low-level routines that do
libraries contain all the "standard" stuff low-level routines that do
the input and output to screen, the `sin` function and much more.

If you want to see the gory details, add the option "-v". This instructs
Expand Down
36 changes: 18 additions & 18 deletions learn/building_programs/managing_libraries.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Libraries contain any number of object files in a compact form, so that
the command-line becomes far shorter:

```shell
$ gfortran -o tabulate tabulate.f90 function.o supportlib.a
$ gfortran -o tabulate tabulate.f90 functions.o supportlib.a
```

where "supportlib.a" is a collection of one, two or many object files,
Expand Down Expand Up @@ -104,8 +104,8 @@ a dynamic link library)

There is one more thing to be aware of: On Windows you must
explicitly specify that a procedure is to be _exported_, i.e. is visible
in the dynamic library. There are several ways - depending on the
compiler you use - to achieve this. One method is via a so-called
in the dynamic library. There are several ways depending on the
compiler you use to achieve this. One method is via a so-called
compiler directive:

```fortran
Expand All @@ -129,26 +129,26 @@ we look at the `tabulate` program in the file "tabulate.f90".

## GNU/Linux and gfortran
The `tabulate` program requires a user-defined routine `f`. If we
let it reside in a dynamic library, say "function.dll", we can simply
let it reside in a dynamic library, say "functions.dll", we can simply
replace the implementation of the function by putting another dynamic
library in the directory. No need to rebuild the program as such.

On Cygwin it is not necessary to explicitly export a procedure - all
On Cygwin it is not necessary to explicitly export a procedure all
publically visible routines are exported when you build a dynamic library.
Also, no import library is generated.

Since our dynamic library can be built from a single source file, we
can take a shortcut:

```shell
$ gfortran -shared -o function.dll function.f90
$ gfortran -shared -o functions.dll functions.f90
```

This produces the files "function.dll" and "function.mod". The
This produces the files "functions.dll" and "user\_functions.mod". The
utility `nm` tells us the exact name of the function `f`:

```shell
$ nm function.dll
$ nm functions.dll
...
000000054f9d7000 B __dynamically_loaded
U __end__
Expand All @@ -165,21 +165,21 @@ other routine "f" that might be defined in another module.
The next step is to build the program:

```shell
$ gfortran -o tabulate tabulate.f90 function.dll
$ gfortran -o tabulate tabulate.f90 functions.dll
```

The DLL and the .mod file are used to build the executable program
with checks on the function's interface, the right name and the reference
to "a" DLL, called "function.dll".
to "a" DLL, called "functions.dll".

You can replace the shared library "function.dll" by another one, implementing
You can replace the shared library "functions.dll" by another one, implementing
a different function "f". Of course, you need to be careful to use the correct
interface for this function. The compiler/linker are not invoked anymore, so they
can do no checking.

## Windows and Intel Fortran
The setup is the same as with Linux, but on Windows it is necessary
to explicitly export the routines. And an import library is generated -
to explicitly export the routines. And an import library is generated
this is the library that should be used in the link step.

The source file must contain the compiler directive, otherwise the function `f`
Expand All @@ -193,27 +193,27 @@ real function f( x )
Again we take a shortcut:

```shell
$ ifort -exe:function.dll function.f90 -dll
$ ifort -exe:functions.dll functions.f90 -dll
```

This produces the files "function.dll", "function.mod" as well as "function.lib" (and two
This produces the files "functions.dll", "user\_functions.mod" as well as "functions.lib" (and two
other files of no importance here). The "dependency walker" program tells us
that the exact name of the function "f" is `FUNCTION_mp_F`. It is also exported, so that
it can be found by the linker in the next step:

```
$ ifort tabulate.f90 function.lib
$ ifort tabulate.f90 functions.lib
```

Note that we need to specify the name of the export library, not the DLL!

(Note also: the Intel Fortran compiler uses the name of the first source file as the
name for the executable - here we do without the `-exe` option.)
name for the executable here we do without the `-exe` option.)

Just as under Cygwin, the DLL and the .mod file are used to build the executable program
with checks on the function's interface, the right name and the reference
to "a" DLL, called "function.dll".
to "a" DLL, called "functions.dll".

You can replace the shared library "function.dll" by another one, but the same
You can replace the shared library "functions.dll" by another one, but the same
caution is required: while the implementation can be quite different, the
function's interface must be the same.
6 changes: 3 additions & 3 deletions learn/building_programs/runtime_libraries.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ $ ldd tabulate.exe

Other compilers or other versions of the same compiler will probably
require different dynamic libraries. As long as you run the program on
the same computer - or, more accurately, within the same environment -
the same computer or, more accurately, within the same environment
there should be no problem. However, when such a library cannot be
found, you will get (hopefully) an error message and the program stops
immediately.
Expand All @@ -39,7 +39,7 @@ _On Linux:_

* The environment variable `LD_LIBRARY_PATH` is used. It consists of a
list of directories to be searched, each directory separated via colons
(:) from the others. For instance: `/usr/lib:/usr/local/lib` - typical
(:) from the others. For instance: `/usr/lib:/usr/local/lib` typical
system directories.
* At the link step you can also use an option to set `RPATH`, a list
of directories that is put into the executable file itself.
Expand All @@ -54,7 +54,7 @@ to be searched, but now the separating character is the semicolon (;).
* A set of system directories is searched.

Unfortunately, the details can change from one version of the operating
system to the next. The above is merely an indication - use tools like
system to the next. The above is merely an indication use tools like
"ldd" or "dependency walker" to find out what libraries are loaded and
where they are found.

Expand Down