ENH: Reorganize images of UserGuide
[freefoam.git] / doc / UserGuide / applications / compiling.txt
blob76b2af2f704f22b149fe5cde88a87f6ab454acf5
1 === Compiling applications and libraries
3 Compilation is an integral part of application development that requires
4 careful management since every piece of code requires its own set of
5 instructions to access dependent components of the {project} library. In
6 `UNIX/Linux` systems these instructions are often organised and delivered to
7 the compiler using the standard `Make` (((`make` script/alias)))
8 (((script/alias,`make`))) utility. {project}, however, is based
9 on the http://www.cmake.org['CMake'] ((('CMake' script/alias)))
10 (((script/alias,'CMake'))) build system that is considerably more versatile and
11 easier to use. To understand the compilation process, we first need to explain
12 certain aspects of {cpp} and its file structure, shown schematically in
13 <<fig_compilingCode>>. A class is defined through a set of instructions such as
14 object construction, data storage and class member functions. The file
15 containing the class 'definition' takes a filename:.C[] extension, 'e.g.' a
16 class `nc` would be written in the file filename:nc.C[]. This file can be
17 compiled independently of other code into a binary executable library file
18 known as a shared object library with a filename:lib[] prefix and a
19 filename:.so[] file extension, 'i.e.' filename:libnc.so[]. When compiling a
20 piece of code, say filename:newApp.C[], that uses the `nc` class,
21 filename:nc.C[] need not be recompiled, rather filename:newApp.C[] calls
22 filename:libnc.so[] at runtime. This is known as 'dynamic linking'.
24 [[fig_compilingCode]]
25 .Header files, source files, compilation and linking
26 image::images/app_compiling.{gfx-fmt}[scaledwidth="40%"]
28 ==== Header filename:.H[] files
30 As a means of checking errors, the piece of code being compiled must know that
31 the classes it uses and the operations they perform actually exist. Therefore
32 each class requires a class 'declaration', contained in a header file with a
33 filename:.H[] file extension, 'e.g.' filename:nc.H[], that includes the names
34 of the class and its functions. This file is included at the beginning of any
35 piece of code using the class, including the class definition code itself. Any
36 piece of filename:.C[] code can resource any number of classes and must begin
37 with all the filename:.H[] files required to declare these classes. The classes
38 in turn can resource other classes and begin with the relevant filename:.H[]
39 files. By searching recursively down the class hierarchy we can produce a
40 complete list of header files for all the classes on which the top level
41 filename:.C[] code ultimately depends; these filename:.H[] files are known as
42 the 'dependencies'. With a dependency list, the build system check whether the
43 source files have been updated since their last compilation and selectively
44 compile only those that need to be.
46 Header files are included in the code using `#include`
47 (((`#include`,{cpp} syntax)))((({cpp} syntax,`#include`))) statements, 'e.g.'
49 [source,c++]
50 -------------------------------------------------------------------------------
51 #include <someHeader.H>
52 #include "someHeader.H"
53 -------------------------------------------------------------------------------
55 causes the compiler to suspend reading from the current file to read the file
56 specified. The difference between the two forms is that the second one (with
57 the straight quotation marks) causes the compiler to additionally first search
58 the directory containing the including file for the specified header, and only
59 then proceed to directories specified via compiler flags and system
60 directories.
62 Any self-contained piece of code can be put into a header file and included at
63 the relevant location in the main code in order to improve code readability.
64 For example, in most {project} applications the code for creating fields and
65 reading field input data is included in a file filename:createFields.H[] which
66 is called at the beginning of the code. In this way, header files are not
67 solely used as class declarations. It is 'CMake' that performs the task of
68 maintaining file dependency lists amongst other functions listed below.
70 - Automatic generation and maintenance of file dependency lists,
71   (((dependency lists)))(((dependencies))) 'i.e.' lists of files which are
72   included in the source files and hence on which they depend.
73 - Multi-platform compilation and linkage, handled through appropriate directory
74   structure.
75 - Multi-language compilation and linkage,'e.g.' C, {cpp}, Java.
76 - Multi-option compilation and linkage, 'e.g.' debug, optimised, parallel and
77   profiling.
78 - Support for source code generation programs, 'e.g.' lex, yacc, IDL, MOC.
79 - Simple syntax for source file lists.
80 - Automatic creation of source file lists for new codes.
81 - Simple handling of multiple shared or static libraries.
82 - Extensible to new machine types.
83 - Extremely portable.
85 ==== Compiling with 'CMake'
87 {project} applications are organised using a standard convention that the
88 source code of each application is placed in a directory whose name is that of
89 the application with the word 'Foam' appended. The notable exception to this
90 rule are applications whose name already ends on 'Foam'. Usually these are
91 conversion-utilities, such as `cfx4ToFoam`. The top level source file takes the
92 same name with the filename:.C[] extension. For example, the source code for a
93 simple solver called `T`, solving the heat transport problem, would reside is a
94 directory filename:TFoam[] and the top level file would be filename:TFoam.C[]
95 as shown in <<fig_applicationDirectoryStructure>>.
97 [[fig_applicationDirectoryStructure]]
98 .Directory structure for the `T` solver
99 image::images/app_directoryStructure.{gfx-fmt}[]
101 The directory must also contain the filename:CMakeLists.txt[]
102 (((filename:CMakeListst.txt[] file)))(((file,filename:CMakeLists.txt[]))) file
103 and, optionally, the filename:files.cmake[](((filename:files.cmake[] file)))
104 (((file,filename:files.cmake[]))) file, which are described in the following
105 sections.
107 ===== Running 'CMake'
109 With 'CMake' it is common to do a (('out-of-source' build)), 'i.e.' the build
110 is started in a separate, empty directory. This ensures that the (('source
111 tree')) does not get polluted and that all the build products can easily be
112 removed by deleting that directory. In this section we will use 'CMake' from
113 the command line only, refer to the official 'CMake' documentation on how to
114 use the other interfaces.
116 It is often easiest to just create an empty directory, 'e.g.' called `build`
117 inside the source directory, change directory to it and then invoke 'CMake' as
118 illustrated below.
120 ------------------------------------------------------------------------------
121 $ cd '<path/to/source>'
122 $ mkdir build
123 $ cd build
124 $ cmake ..
125 ------------------------------------------------------------------------------
127 On `UNIX`/`Linux` operating systems, 'CMake' will generate standard
128 __Makefile__'s.(((Makefile))) The build can then be started by typing
130 ------------------------------------------------------------------------------
131 $ make
132 ------------------------------------------------------------------------------
134 ==== Compilation example: the `simpleWind` application
136 The source code for application `simpleWind` is in the
137 dirname:<tutorials>/incompressible/simpleWindFoam/simpleWindFoam[] directory
138 and the top level source file is named filename:simpleWindFoam.C[]. The
139 filename:simpleWindFoam.C[] source code is:
141 [source,c++]
142 -------------------------------------------------------------------------------
143 /*---------------------------------------------------------------------------*\
144 [... omitted ...]
146 Application
147     simpleWindFoam
149 Description
150     Steady-state solver for incompressible, turbulent flow with external
151     source in the momentum equation to approximate, e.g. wind turbines.
153 [... omitted ...]
154 \*---------------------------------------------------------------------------*/
155 include::{builddir}applications/assets/simpleWindFoam.C[]
156 -------------------------------------------------------------------------------
158 The code begins with a brief description of the application contained within
159 ((comments)) over 1 line (++//++)(((`//`,{cpp} syntax)))((({cpp} syntax,`//`)))
160 and multiple lines (`/*...*/`). (((`/*...*/`,{cpp} syntax)))
161 ((({cpp} syntax,`/*...*/`))) Following that, the code contains several
162 `#include`(((`#include`,{cpp} syntax)))((({cpp} syntax,`#include`)))
163 statements, 'e.g.' `#include <finiteVolume/fvCFD.H>`, which causes the compiler
164 to suspend reading from the current file, filename:simpleWindFoam.C[] to read
165 the filename:finiteVolume/fvCFD.H[].
167 `simpleWind` includes headers from the `finiteVolume`,
168 `incompressibleTransportModels` and `incompressibleRASModels` libraries and
169 therefore requires to be linked against them. The filename:CMakeLists.txt[]
170 file contains the following:
172 [subs='verbatim']
173 -------------------------------------------------------------------------------
174 cmake_minimum_required(VERSION 2.8)               <1>
175 project(simpleWind)                               <2>
177 find_package(FreeFOAM REQUIRED)                   <3>
178 include(${FOAM_USE_FILE})                         <4>
180 foam_add_executable(simpleWind simpleWindFoam.C)  <5>
181 target_link_libraries(simpleWind                  <6>
182   FOAM_incompressibleTransportModels
183   FOAM_incompressibleRASModels
184   FOAM_finiteVolume
185   )
186 -------------------------------------------------------------------------------
187 <1> Require that 'CMake' is version 2.8 or newer
188 <2> Declare a new 'CMake' project named `simpleWind`
189 <3> Find the `FreeFOAM` package
190 <4> Include a file that provides useful functions used later on
191 <5> Compile filename:simpleWindFoam.C[] into the executable `simpleWind`
192 <6> Link the target `simpleWind` against the listed libraries. Although the
193 `FOAM_finiteVolume` library would get automatically pulled in by the other
194 libraries, it is still listed here because filename:simpleWindFoam.C[] still
195 directly includes a header from the `FOAM_finiteVolume` library.
197 The user can compile `simpleWind` by going to the
198 filename:<tutorials>/incompressible/simpleWindFoam/simpleWindFoam[] directory
199 and typing:
201 -------------------------------------------------------------------------------
202 $ mkdir build
203 $ cd build
204 $ cmake ..
205 $ make
206 -------------------------------------------------------------------------------
208 ==== Debug messaging and optimisation switches
210 {project} provides a system of messaging that is
211 written during runtime, most of which are to help debugging
212 problems encountered during running of a {project} case. The
213 switches are listed in the
214 filename:<prefix>/etc/{project}-{fullver}/controlDict[] file; should the user
215 wish to change the settings they should make a copy to their
216 filename:$HOME[] directory, 'i.e.'
217 filename:$HOME/.{project}/{fullver}/controlDict[] file. The list of possible
218 switches is extensive and can be viewed by running the
219 `foamDebugSwitches` application. Most of
220 the switches correspond to a class or range of functionality and
221 can be switched on by their inclusion in the filename:controlDict[] file, and
222 by being set to `1`. For example, {project} can perform the checking of
223 dimensional units in all calculations by setting the `dimensionSet` switch to
224 `1`. There are some switches that control messaging at a higher level than
225 most, listed in <<tab_messageSwitches>>.
227 In addition, there are some switches that control certain operational and
228 optimisation issues. These switches are also listed in <<tab_messageSwitches>>.
229 Of particular importance is `fileModificationSkew`. {project} scans the write
230 time of data files to check for modification. When running over a NFS with some
231 disparity in the clock settings on different machines, field data files appear
232 to be modified ahead of time. This can cause a problem if {project} views the
233 files as newly modified and attempting to re-read this data. The
234 `fileModificationSkew` keyword is the time in seconds that {project} will
235 subtract from the file write time when assessing whether the file has been
236 newly modified.
238 [[tab_messageSwitches]]
239 .Runtime switches
240 [grid="none",frame="topbot",cols="1,2"]
241 |=============================================================================
242 2+h| High level debugging switches &mdash; sub-dictionary `DebugSwitches`
243 | `level`     | Overall level of debugging messaging; between 0 and 2
244 | `lduMatrix` | Messaging for solver convergence during a run; between 0 and 2
245 2+h| Optimisation switches &mdash; sub-dictionary `OptimisationSwitches`
246 | `fileModificationSkew` | A time in seconds that should be set higher than
247 the maximum delay in NFS updates and clock difference for running {project}
248 over a NFS.
249 | `nProcsSimpleSum` | Optimises global sum for parallel processing; sets number
250 of processors above which hierarchical sum is performed rather than a linear
251 sum (default 16)
252 |=============================================================================
254 ==== Linking new user-defined libraries to existing applications
256 The situation may arise that a user creates a new library, say `new`, and
257 wishes the features within that library to be available across a range of
258 applications. For example, the user may create a new boundary condition,
259 compiled into `new`, that would need to be recognised by a range of solver
260 applications, pre- and post-processing utilities, mesh tools, 'etc.' Under
261 normal circumstances, the user would need to recompile every application with
262 the `new` linked to it.
264 Instead there is a simple mechanism to link one or more shared object libraries
265 dynamically at run-time in {project}. Simply add the optional keyword entry
266 `libs` (((`libs` keyword)))(((keyword,`libs`))) to the
267 filename:system/controlDict[] file for a case and enter the full names of the
268 libraries within a list (as quoted string entries). For example, if a user
269 wished to link the libraries `new1` and `new2` at run-time, they would simply
270 need to add the following to the case filename:system/controlDict[] file:
272 -------------------------------------------------------------------------------
273 libs
275     "libnew1.so"
276     "libnew2.so"
278 -------------------------------------------------------------------------------
280 Even if the real suffix is not filename:.so[], but 'e.g.' filename:.dylib[] (as
281 on Mac OS X (R)), you can still use filename:.so[] in the
282 filename:system/controlDict[] file, {project} will substitute the correct
283 suffix automatically.