/usr/share/doc/fcm/user_guide/build.html is in fcm 2016.12.0-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
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 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 | <!DOCTYPE html>
<html>
<head>
<title>FCM: User Guide: Annex: The FCM 1 Build System</title>
<meta name="author" content="FCM team" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="icon" href="../etc/fcm-icon.png" type="image/png" />
<link rel="shortcut icon" href="../etc/fcm-icon.png" type="image/png" />
<link href="../etc/bootstrap/css/bootstrap.min.css" rel="stylesheet" media="screen" />
<link href="../etc/fcm.css" rel="stylesheet" media="screen" />
</head>
<body>
<div class="navbar navbar-inverse">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href=".."><span class="fcm-version">FCM</span></a>
</div>
<div class="collapse navbar-collapse">
<ul class="nav navbar-nav">
<li><a href="../installation/">Installation</a></li>
<li><a class="active" href="#">User Guide</a></li>
</ul>
</div>
</div>
</div>
<div class="page-header">
<div class="fcm-page-content pull-right well well-sm"></div>
<h1>FCM: User Guide: Annex: The FCM 1 Build System</h1>
</div>
<div class="container">
<div class="row">
<div class="col-md-12">
<h2 id="introduction">Introduction</h2>
<p><em>The FCM 1 build system is deprecated. The documentation for the current
build system can be found at <a href="make.html">FCM Make</a>.</em></p>
<p>The build system analyses the directory tree containing a set of source
code, processes the configuration, and invokes <code>make</code> to
compile/build the source code into the project executables. In this chapter,
we shall use many examples to explain how to use the build system. At the end
of this chapter, you should be able to use the build system, either by
defining the build configuration file directly or by using the extract system
to generate a suitable build configuration file.</p>
<h2 id="command">The Build Command</h2>
<p>To invoke the build system, simply issue the command:</p>
<pre>
fcm build
</pre>
<p>By default, the build system searches for a build configuration file
<samp>bld.cfg</samp> in <samp>$PWD</samp> and then <samp>$PWD/cfg</samp>. If
a build configuration file is not found in these directories, the command
fails with an error. If a build configuration file is found, the system will
use the configuration specified in the file to perform the build. If you use
the extract system to extract your source tree, a build configuration should
be written for you automatically at the <samp>cfg/</samp> sub-directory of
the destination root directory.</p>
<p>If the root directory of the build does not exist, the system performs a
new full build at this directory. If a previous build already exists at this
directory, the system performs an incremental build. If a full (fresh) build
is required for whatever reason, you can invoke the build system using the
<code>-f</code> option, (i.e. the command becomes <code>fcm build -f</code>).
If you simply want to remove all the items generated by a previous build in
the destination, you can invoke the build system using the
<code>--clean</code> option.</p>
<p>The build system uses GNU <code>make</code> to perform the majority of the
build. GNU <code>make</code> has a <code>-j jobs</code> option to specify the
number of <var>jobs</var> to run simultaneously. Invoking the build system
with the same option triggers this option when the build system invokes the
<code>make</code> command. The argument to the option <var>jobs</var> must be
an integer. The default is <samp>1</samp>. For example, the command <code>fcm
build -j 4</code> will allow <code>make</code> to perform 4 jobs
simultaneously.</p>
<p>For further information on the build command, please see <a href=
"command_ref.html#fcm-build">FCM Command Reference > fcm build</a>.</p>
<h2 id="basic">Basic Features</h2>
<p>The build configuration file is the user interface of the build system. It
is a line based text file. You can create your own build configuration file
or you can use the extract system to create one for you. For a complete set
of build configuration file declarations, please refer to the <a href=
"annex_bld_cfg.html">Annex: Declarations in FCM build configuration
file</a>.</p>
<h3 id="basic_build">Basic build configuration</h3>
<p>Suppose we have a directory at <samp>$HOME/example</samp>. Its
sub-directory at <samp>$HOME/example/src</samp> contains a source tree to be
built. You may want to have a build configuration file
<samp>$HOME/example/cfg/bld.cfg</samp>, which may contain:</p>
<pre id="example_1">
# Example 1
# ----------------------------------------------------------------------
cfg::type bld # line 1
cfg::version 1.0 # line 2
dest $HOME/example # line 4
target foo.exe bar.exe # line 6
tool::fc ifort # line 8
tool::fflags -O3 # line 9
tool::cc gcc # line 10
tool::cflags -O3 # line 11
tool::ldflags -O3 -L$(HOME)/lib -legg -lham # line 13
</pre>
<p>Here is an explanation of what each line does:</p>
<ul>
<li><dfn>line 1</dfn>: the label <code>CFG::TYPE</code> declares the type
of the configuration file. The value <samp>bld</samp> tells the system that
it is a build configuration file.</li>
<li><dfn>line 2</dfn>: the label <code>CFG::VERSION</code> declares the
version of the build configuration file. The current default is
<samp>1.0</samp>. Although it is not currently used, if we have to change
the format of the configuration file at a later stage, we shall be able to
use this number to determine whether we are reading a file with an older
format or one with a newer format.</li>
<li><dfn>line 4</dfn>: the label <code>DEST</code> declares the root
directory of the current build.</li>
<li><dfn>line 6</dfn>: the label <code>TARGET</code> declares a list of
<em>default</em> targets. The default targets of the current build will be
<samp>foo.exe</samp> and <samp>bar.exe</samp>.</li>
<li><dfn>line 8</dfn>: the label <code>TOOL::FC</code> declares the Fortran
compiler command.</li>
<li><dfn>line 9</dfn>: the label <code>TOOL::FFLAGS</code> declares the
options to be used when invoking the Fortran compiler command.</li>
<li><dfn>line 10</dfn>: the label <code>TOOL::CC</code> declares the C
compiler command.</li>
<li><dfn>line 11</dfn>: the label <code>TOOL::CFLAGS</code> declares the
options to be used when invoking the C compiler command.</li>
<li><dfn>line 13</dfn>: the label <code>TOOL::LDFLAGS</code> declares the
options to be used when invoking the linker command.</li>
</ul>
<p>When we invoke the build system, it reads the above configuration file. It
will go through various internal processes, such as dependency generations,
to obtain the required information to prepare the <samp>Makefile</samp> of
the build. (All of which will be described in later sections.) The
<samp>Makefile</samp> of the build will be placed at
<samp>$HOME/example/bld</samp>. The system will then invoke <code>make</code>
to build the targets specified in line 6, i.e. <samp>foo.exe</samp> and
<samp>bar.exe</samp> using the build tools specified between line 8 to line
13. On a successful build, the target executables will be sent to
<samp>$HOME/example/bin/</samp>. The build system also creates a shell script
called <samp>fcm_env.sh</samp> in <samp>$HOME/example/</samp>. If you source
the shell script, it will export your <var>PATH</var> environment variable to
search the <samp>$HOME/example/bin/</samp> directory for executables.</p>
<p>N.B. You may have noticed that the <code>-c</code> (compile to object file
only) option is missing from the compiler flags declarations. This is because
the option is inserted automatically by the build system, unless it is
already declared.</p>
<p>N.B. You can declare the linker using <code>TOOL::LD</code>. If it is not
specified, the default is to use the compiler command for the source file
containing the main program.</p>
<dl>
<dt>Note - declaration of source files for build</dt>
<dd>
<p>Source files do not have to reside in the <samp>src/</samp>
sub-directory of the build root directory. They can be anywhere, but you
will have to declare them using the label <code>SRC::<pcks></code>,
where <code><pcks></code> is the sub-package name in which the
source belongs. If a directory is specified then the build system
automatically searches for all source files in this directory. E.g.</p>
<pre>
# Declare a source in the sub-package "foo/bar"
src::foo/bar $HOME/foo/bar
</pre>
<p>By default, the build system searches the <samp>src/</samp>
sub-directory of the build root directory for source files. If all source
files are already declared explicitly, you can switch off the automatic
directory search by setting the <code>SEARCH_SRC</code> flag to false.
E.g.</p>
<pre>
search_src false
</pre>
<p>As mentioned in the previous chapter, the name of a sub-package
<pcks> provides a unique namespace for a file. The name of a
sub-package is a list of words delimited by a slash <code>/</code>. (The
system uses the double colons <code>::</code> and the double underscores
<code>__</code> internally. Please avoid using <code>::</code> and
<code>__</code> for naming your files and directories.)</p>
<p>Currently, the build system only supports non-space characters in the
package name, as the space character is used as a delimiter between the
declaration label and its value. If there are spaces in the path name to
a file or directory, you should explicity re-define the package name of
that path to a package name with no space using the above method.
However, we recommend that only non-space characters are used for naming
directories and files to make life simple.</p>
<p>In the build system, the sub-package name also provides an
<em>inheritance</em> relationship for sub-packages. For instance, we may
have a sub-package called <samp>foo/bar/egg</samp>, which belongs to the
sub-package <samp>foo/bar</samp>, which belongs to the package
<samp>foo</samp>.</p>
<ul>
<li>If we declare a global build tool, it applies to all packages.</li>
<li>If we declare a build tool for <samp>foo</samp>, it applies also to
the sub-package <samp>foo/bar</samp> and <samp>foo/bar/egg</samp>.</li>
<li>If we declare a build tool for <samp>foo/bar</samp>, it applies
also to <samp>foo/bar/egg</samp>, but not to other sub-packages in
<samp>foo</samp>.</li>
</ul>
</dd>
</dl>
<h3 id="basic_extract">Build configuration via the extract system</h3>
<p>As mentioned earlier, you can obtain a build configuration file through
the extract system. The following example is what you may have in your
extract configuration in order to obtain a similar configuration as <a href=
"#example_1">example 1</a>:</p>
<pre id="example_2">
# Example 2
# ----------------------------------------------------------------------
cfg::type ext # line 1
cfg::version 1.0 # line 2
dest $HOME/example # line 4
bld::target foo.exe bar.exe # line 6
bld::tool::fc ifort # line 8
bld::tool::fflags -O3 # line 9
bld::tool::cc gcc # line 10
bld::tool::cflags -O3 # line 11
bld::tool::ldflags -O3 -L$(HOME)/lib -legg -lham # line 13
# ... and other declarations for source locations ...
</pre>
<p>It is easy to note the similarities and differences between <a href=
"#example_1">example 1</a> and <a href="#example_2">example 2</a>. <a href=
"#example_2">Example 2</a> is an extract configuration file. It extracts to a
destination root directory that will become the root directory of the build.
Line 6 to line 13 are the same declarations, except that they are now
prefixed with <code>BLD::</code>. In an extract configuration file, any lines
prefixed with <code>BLD::</code> means that they are build configuration
setting. These lines are ignored by the extract system but are parsed down to
the output build configuration file, with the <code>BLD::</code> prefix
removed. (Note: the <code>BLD::</code> prefix is optional for declarations in
a build configuration file.)</p>
<p>N.B. If you use the extract system to mirror an extract to an alternate
location, the extract system will assume that the root directory of the
alternate destination is the root directory of the build, and that the build
will be carried out in that destination.</p>
<h3 id="basic_exename">Naming of executables</h3>
<p>If a source file called <samp>foo.f90</samp> contains a main program, the
default behaviour of the system is to name its executable
<samp>foo.exe</samp>. The root name of the executable is the same as the
original file name, but its file extension is replaced with
<samp>.exe</samp>. The output extension can be altered by re-registering the
extension for output EXE files. How this can be done will be discussed later
in the sub-section <a href="#advanced_file-type">File Type</a>.</p>
<p>If you need to alter the full name of the executable, you can use the
<code>EXE_NAME::</code> declaration. For example, the declaration:</p>
<pre>
bld::exe_name::foo bar
</pre>
<p>will rename the executable of <samp>foo.f90</samp> from
<samp>foo.exe</samp> to <samp>bar</samp>.</p>
<p>Note: the declaration label is <code>bld::exe_name::foo</code> (not
<code>bld::exe_name::foo.exe</code>) and the executable will be named
<samp>bar</samp> (not <samp>bar.exe</samp>).</p>
<h3 id="basic_flags">Setting the compiler flags</h3>
<p>As discussed in the first example, the compiler commands and their flags
can be set via the <code>TOOL::</code> declarations. A simple
<code>TOOL::FFLAGS</code> declaration, for example, alters the compiler
options for compiling all Fortran source files in the build. If you need to
alter the compiler options only for the source files in a particular
sub-package, it is possible to do so by adding the sub-package name to the
declaration label. For example, the declaration label
<code>TOOL::FFLAGS::foo/bar</code> will ensure that the declaration only
applies to the code in the sub-package <samp>foo/bar</samp>. You can even
make declarations down to the individual source file level. For example, the
declaration label <code>TOOL::FFLAGS::foo/bar/egg.f90</code> will ensure that
the declaration applies only for the file <samp>foo/bar/egg.f90</samp>.</p>
<p>N.B. Although the prefix <code>TOOL::</code> and the tool names are
case-insensitive, sub-package names are case sensitive in the declarations.
Internally, tool names are turned into uppercase, and the sub-package
delimiters are changed from the slash <code>/</code> (or double colons
<code>::</code>) to the double underscores <code>__</code>. When the system
generates the <samp>Makefile</samp> for the build, each <code>TOOL</code>
declaration will be exported as an environment variable. For example, the
declaration <code>tool::fflags/foo/bar</code> will be exported as
<samp>FFLAGS__foo__bar</samp>.</p>
<p>N.B. <code>TOOL</code> declarations for sub-packages are only accepted by
the system when it is sensible to do so. For example, it allows you to
declare different compiler flags, linker commands and linker flags for
different sub-packages, but it does not accept different compilers for
different sub-packages. If you attempt to make a <code>TOOL</code>
declaration for a sub-package that does not exist, the build system will exit
with an error.</p>
<p>The following is an example setting in an extract configuration file based
on <a href="#example_2">example 2</a>:</p>
<pre id="example_3">
# Example 3
# ----------------------------------------------------------------------
cfg::type ext
cfg::version 1.0
dest $HOME/example
bld::target foo.exe bar.exe
bld::tool::fc ifort
bld::tool::fflags -O3 # line 9
bld::tool::cc gcc
bld::tool::cflags -O3
bld::tool::ldflags -L$(HOME)/lib -legg -lham
bld::tool::fflags::ops -O1 -C # line 15
bld::tool::fflags::gen -O2 # line 16
# ... and other declarations for repositories and source directories ...
</pre>
<p>In the example above, line 15 alters the Fortran compiler flags for
<samp>ops</samp>, so that all source files in <samp>ops</samp> will be
compiled with optimisation level 1 and will have runtime error checking
switched on. Line 16, alters the Fortran compiler flags for <samp>gen</samp>,
so that all source files in <samp>gen</samp> will be compiled with
optimisation level 2. All other Fortran source files will use the global
setting declared at line 9, so they they will all be compiled with
optimisation level 3.</p>
<dl>
<dt>Note - changing compiler flags in incremental builds</dt>
<dd>
<p>Suppose you have performed a successful build using the configuration
in <a href="#example_3">example 3</a>, and you have decided to change
some of the compiler flags, you can do so by altering the appropriate
flags in the build configuration file. When you trigger an incremental
build, the system will detect changes in compiler flags automatically,
and update only the required targets. The following hierarchy is
followed:</p>
<ul>
<li>If the compiler flags for a particular source file change, only
that source file and any targets depending on that source file are
re-built.</li>
<li>If the compiler flags for a container package change, only source
files within that container package and any targets depending on those
source files are re-built.</li>
<li>If the global compiler flags change, all source files are
re-built.</li>
<li>If the compiler command changes, all source files are
re-built.</li>
</ul>
</dd>
</dl>
<p>N.B. For a full list of build tools declarations, please see <a href=
"annex_bld_cfg.html#tools-list">Annex: Declarations in FCM build
configuration file > list of tools</a>.</p>
<h3 id="basic_interface">Automatic Fortran 9X interface block</h3>
<p>For each Fortran 9X source file containing standalone subroutines and/or
functions, the system generates an interface file and sends it to the
<samp>inc/</samp> sub-directory of the build root. An interface file contains
the interface blocks for the subroutines and functions in the original source
file. In an incremental build, if you have modified a Fortran 9X source file,
its interface file will only be re-generated if the content of the interface
has changed.</p>
<p>Consider a source file <samp>foo.f90</samp> containing a subroutine called
<samp>foo</samp>. In a normal operation, the system writes the interface file
to <samp>foo.interface</samp> in the <samp>inc/</samp> sub-directory of the
build root. By default, the root name of the interface file is the same as
that of the source file, and is case sensitive. You can change this behaviour
using a <code>TOOL::INTERFACE</code> declaration. E.g.:</p>
<pre>
bld::tool::interface program # The default is "file"
</pre>
<p>In such case, the root name of the interface file will be named in lower
case after the first program unit in the file.</p>
<p>The default extension for an interface file is <samp>.interface</samp>.
This can be modified through the input and output file type register, which
will be discussed in a later section on <a href="#advanced_file-type">File
Type</a>.</p>
<p>In most cases, we modify procedures without altering their calling
interfaces. Consider another source file <samp>bar.f90</samp> containing a
subroutine <samp>bar</samp>. If <samp>bar</samp> calls <samp>foo</samp>, it
is good practice for <samp>bar</samp> to have an explicit interface for
<samp>foo</samp>. This can be achieved if the subroutine <samp>bar</samp> has
the following within its declaration section:</p>
<pre>
INCLUDE 'foo.interface'
</pre>
<p>The source file <samp>bar.f90</samp> is now dependent on the interface
file <samp>foo.interface</samp>. This can make incremental build very
efficient, as changes in the <samp>foo.f90</samp> file will not normally
trigger the re-compilation of <samp>bar.f90</samp>, provided that the
interface of the <code>subroutine foo</code> remains unchanged. (However, the
system is clever enough to know that it needs to re-link any executables that
are dependent on the object file for the <code>subroutine bar</code>.)</p>
<p>By default, the system uses its own internal logic to extract the calling
interfaces of top level subroutines and functions in a Fortran source file to
generate an interface block. However, the system can also work with the
interface generator <code>f90aib</code>, which is a freeware obtained from
<a href=
"http://www.ifremer.fr/ditigo/molagnon/fortran90/contenu.html">Fortran 90
texts and programs, assembled by Michel Olagnon</a> at the French Research
Institute for Exploitation of the Sea. To do so, you need to make a
declaration in the build configuration file using the label
<code>TOOL::GENINTERFACE</code>. As for any other <code>TOOL</code>
declarations, you can attach a sub-package name to the label. The change will
then apply only to source files within that sub-package. If
<code>TOOL::GENINTERFACE</code> is declared to have the value
<code>NONE</code>, interface generation will be switched off. The following
are some examples:</p>
<pre id="example_4">
# Example 4
# ----------------------------------------------------------------------
# This is an EXTRACT configuration file ...
# ... some other declarations ...
bld::tool::geninterface f90aib # line 5
bld::tool::geninterface::bar none # line 6
# ... some other declarations ...
</pre>
<p>In line 5, the global interface generator is now set to
<code>f90aib</code>. In line 6, by setting the interface generator for the
package <samp>bar</samp> to the <code>none</code> keyword, no interface file
will be generated for source files under the package <samp>bar</samp>.</p>
<p>Switching off the interface block generator can be useful in many
circumstances. For example, if the interface block is already provided
manually within the source tree, or if the interface block is never used by
other program units, it is worth switching off the interface generator for
the source file to speed up the build process.</p>
<h3 id="basic_dependency">Automatic dependency</h3>
<p>The build system has a built-in dependency scanner, which works out the
dependency relationship between source files, so that they can be built in
the correct order. The system scans all source files of known types for all
supported dependency patterns. Dependencies of source files in a sub-package
are written in a cache, which can be retrieved for incremental builds. (In an
incremental build, only changed source files need to be re-scanned for
dependency information. Dependency information for other files are retrieved
from the cache.) The dependency information is passed to the
<code>make</code> rule generator, which writes the <samp>Makefile</samp>.</p>
<p>The <code>make</code> rule generator generates different <code>make</code>
rules for different dependency types. The following dependency patterns are
automatically detected by the current system:</p>
<ul>
<li>The <code>USE <module></code> statement in a Fortran source file
is the first pattern. The statement has two implications: 1) The current
file compiles only if the module has been successfully compiled, and needs
to be re-compiled if the module has changed. 2) The executable depending on
the current file can only resolve all its externals by linking with the
object file of the compiled module. The executable needs to be re-linked if
the module and its dependencies has changed.</li>
<li>The <code>INCLUDE '<name>.interface'</code> statement in a
Fortran source file is the second pattern. (The default extension for an
interface file is <samp>.interface</samp>. This can be modified through the
input and output file type register, which will be discussed in a later
section on <a href="#advanced_file-type">File Type</a>.) It has two
implications: 1) The current file compiles only if the included interface
file is in the INCLUDE search path, and needs to be re-compiled if the
interface file changes. 2) The executable depending on the current file can
only resolve all its externals by linking with the object file of the
source file that generates the interface file. The executable needs to be
re-linked if the source file (and its dependencies) associated with the
interface file has changed. It is worth noting that for this dependency to
work, the root <name> of the interface file should match with that of
the source file associated with the interface file. (Please note that you
can use pre-processor [#include "<name>.interface] instead of Fortran
INCLUDE, but it will not work if you switch on the <a href=
"#advanced_pp">pre-processing</a> stage, which will be discussed in a later
section.)</li>
<li>The <code>INCLUDE '<file>'</code> statement (excluding the
INCLUDE interface file statement) in a Fortran source file is the third
pattern. It has two implications: 1) The current file compiles only if the
included file is in the INCLUDE search path, and needs to be re-compiled if
the include file changes. 2) The executable needs to be linked with any
objects the include file is dependent on. It needs to be re-linked if these
objects have changed.</li>
<li>The <code>#include '<file>'</code> statement in a Fortran/C
source or header file is the fourth pattern. It has similar implications as
the Fortran INCLUDE statement. However, they have to be handled differently
because <code>#include</code> statements are processed by the
pre-processor, which may be performed in a separate stage of the FCM build
process. This will be further discussed in a later sub-section on <a href=
"#advanced_pp">Pre-processing</a>.</li>
</ul>
<p>If you want your code to be built automatically by the FCM build system,
you should also design your code to conform to the following rules:</p>
<ol>
<li>Single compilable program unit, (i.e. program, subroutine, function or
module), per file.</li>
<li>Unique name for each compilable program unit.</li>
<li>Always supply an interface for subroutines and functions, i.e.:
<ul>
<li>Put them in modules.</li>
<li>Put them in the CONTAINS section within the main program unit.</li>
<li>Use interface files.</li>
</ul>
</li>
<li>If interface files are used, it is good practice to name each source
file after the program unit it contains. It will make life a lot simpler
when using the <a href="#basic_interface">Automatic Fortran 9X interface
block</a> feature, which has already been discussed in the previous
section.
<ul>
<li>The problem is that, by default, the root name of the interface
file is the same as that of the source file rather than the program
unit. If they differ then the build system will create a dependency on
the wrong object file (since the object files are named according to
the program unit).</li>
<li>This problem can be avoided by changing the behaviour of the
interface file generator to use the name of the program unit instead
(using a <code>TOOL::INTERFACE</code> declaration).</li>
</ul>
</li>
</ol>
<dl>
<dt>Note - setting build targets</dt>
<dd>
<p>The <samp>Makefile</samp> generated by the build system contains a
list of targets that can be built. The build system allows you to build
(or perform the actions of) any targets that are present in the generated
<samp>Makefile</samp>. There are two ways to specify the targets to be
built.</p>
<p>Firstly, you can use the <code>TARGET</code> declarations in your
build configuration file to specify the default targets to be built.
These targets will be set as dependencies of the <samp>all</samp> target
in the generated <samp>Makefile</samp>, which is the default target to be
built when <code>make</code> is invoked by FCM. It is worth noting that
<code>TARGET</code> declarations are cumulative. A later declaration does
not override an earlier one - it simply adds more targets to the
list.</p>
<p>Alternatively, you can use the <code>-t</code> option when you invoke
the <code>fcm build</code> command. The option takes an argument, which
should be a colon <code>:</code> separated list of targets to be built.
When the <code>-t</code> option is set, FCM invokes <code>make</code> to
build these targets instead. (E.g. if we invoke the build system with the
command <code>fcm build -t foo.exe:bar.exe</code>, it will invoke
<code>make</code> to build <samp>foo.exe</samp> and
<samp>bar.exe</samp>.)</p>
<p>If you do not specify any explicit targets, the system will search
your source tree for main programs:</p>
<ul>
<li>If there are main programs in your source tree, they will be set as
the default targets automatically.</li>
<li>Otherwise, the default is to build the top level library archive
containing objects compiled from the source files in the current source
tree. (For more information on building library archives, please see
the section on <a href="#advanced_library">Creating library
archives</a>.)</li>
</ul>
</dd>
</dl>
<h2 id="advanced">Advanced Features</h2>
<h3 id="advanced_dependency">Further dependency features</h3>
<p>Apart from the usual dependency patterns described in the previous
sub-section, the automatic dependency scanner also recognises two special
directives when they are inserted into a source file:</p>
<ul>
<li>The directive <code>DEPENDS ON: <object></code> in a comment line
of a Fortran/C source file: It states that the current file is dependent on
the declared external object. The executable depending on the current file
needs to link with this external object in order to resolve all its
external references. It needs to be re-linked if the declared external
object (and its dependencies) has changed.</li>
<li>The directive <code>CALLS: <executable></code> in a comment line
of a script: It states that the current script is dependent on the declared
executable file, which can be another script or a binary executable. The
current script can only function correctly if the declared executable is
found in the search path. This directive is useful to ensure that all
dependent executables are built or copied to the correct path.</li>
</ul>
<p>Another way to specify external dependency is to use the
<code>EXE_DEP</code> declaration to declare extra dependencies. The
declaration normally applies to all main programs, but if the form
<code>EXE_DEP::<target></code> is used, it will only apply to
<target>, (which must be the name of a main program target). If the
declaration is made without a value, the main programs will be set to depend
on all object files. Otherwise, the value can be supplied as a space
delimited list of items. Each item can be either the name of a sub-package or
an object target. For the former, the main programs will be set to depend on
all object files within the sub-package. For the latter, the main programs
will be set to depend on the object target. The following are some
examples:</p>
<pre id="example_5">
# Example 5
# ----------------------------------------------------------------------
cfg::type ext
cfg::version 1.0
bld::exe_dep::foo.exe foo/bar egg.o # line 4
bld::exe_dep # line 5
# ... some other declarations ...
</pre>
<p>Here is an explanation of what each line does:</p>
<ul>
<li><dfn>line 4</dfn>: this line declares the dependency on the sub-package
<samp>foo/bar</samp> and the object target <samp>egg.o</samp> for building
the main program target <samp>foo.exe</samp>. The target
<samp>foo.exe</samp> will now depends on all object files in the
<samp>foo/bar</samp> sub-package as well as the object target
<samp>egg.o</samp>.</li>
<li><dfn>line 5</dfn>: this line declares that all other main program
targets will depend on all (non-program) object files in the build.</li>
</ul>
<dl>
<dt>Note - naming of object files</dt>
<dd>
<p>By default, object files are named with the suffix <samp>.o</samp>.
For a Fortran source file, the build system uses the lower case name of
the first program unit within the file to name its object file. For
example, if the first program unit in the Fortran source file
<samp>foo.f90</samp> is <code>PROGRAM Bar</code>, the object file will be
<samp>bar.o</samp>. For a C source file, the build system uses the lower
case root name of the source file to name its object file. For example, a
C source file called <samp>egg.c</samp> will have its object file named
<samp>egg.o</samp>.</p>
<p>The reason for using lower case to name the object files is because
Fortran is a case insensitive language. Its symbols can either be in
lower or upper case. E.g. the <code>SUBROUTINE Foo</code> is the same as
the <code>SUBROUTINE foo</code>. It can be rather confusing if the
subroutines are stored in different files. When they are compiled and
archived into a library, there will be a clash of namespace, as the
Fortran compiler thinks they are the same. However, this type of error
does not normally get reported. If <samp>Foo</samp> and <samp>foo</samp>
are very different code, the user may end up using the wrong subroutine,
which may lead to a very long debugging session. By naming all object
files in lower case, this type of situation can be avoided. If there is a
clash in names due to the use of upper/lower cases, it will be reported
as warnings by the build system, (as <em>duplicated targets</em> for
building <samp>foo.o</samp>).</p>
</dd>
</dl>
<p>It is realised that there are situations when an automatically detected
dependency should not be written into the <samp>Makefile</samp>. For example,
the dependency may be a standard module provided by the Fortran compiler, and
does not need to be built in the usual way. In such case, we need to have a
way to exclude this module during an automatic dependency scan.</p>
<p>The <code>EXCL_DEP</code> declaration can be used to do just that. The
following extract configuration contains some examples of the basic usage of
the <code>EXCL_DEP</code> declaration:</p>
<pre id="example_6">
# Example 6
# ----------------------------------------------------------------------
cfg::type ext
cfg::version 1.0
bld::excl_dep USE::YourFortranMod # line 4
bld::excl_dep INTERFACE::HerFortran.interface # line 5
bld::excl_dep INC::HisFortranInc.inc # line 6
bld::excl_dep H::TheirHeader.h # line 7
bld::excl_dep OBJ::ItsObject.o # line 8
# ... some other declarations ...
</pre>
<p>Here is an explanation of what each line does:</p>
<ul>
<li><dfn>line 4</dfn>: this line declares that the Fortran module
<samp>YourFortranMod</samp> should be excluded. The value of each
<code>EXCL_DEP</code> declaration has two parts. The first part is a label
that is used to define the type of dependency to be excluded. For a full
list of these labels, please see the <a href=
"annex_bld_cfg.html#dependency-types">dependency types table</a> in the
<a href="annex_bld_cfg.html">Annex: Declarations in FCM build configuration
file</a>. The label <code>USE</code> denotes a Fortran module. The second
part of the label is the dependency itself. For instance, if a Fortran
source file contains the line: <code>USE YourFortranMod</code>, the
dependency scanner will ignore it.</li>
<li><dfn>line 5</dfn>: this line declares that the include statement for
the Fortran 9X interface file <samp>HerFortran.interface</samp> should be
excluded. The label <code>INTERFACE</code> denotes a Fortran INCLUDE
statement for a Fortran 9X interface block file. For example, if a Fortran
source file contains the line: <code>INCLUDE 'HerFortran.interface'</code>,
the dependency scanner will ignore it.</li>
<li><dfn>line 6</dfn>: this line declares that the include statement for
<samp>HisFortranInc.inc</samp> should be excluded. The label
<code>INC</code> denotes a Fortran INCLUDE statement other than an INCLUDE
statement for an interface block file. For example, if a Fortran source
file contains the line: <code>INCLUDE 'HisFortranInc.inc'</code>, the
dependency scanner will ignore it.</li>
<li><dfn>line 7</dfn>: this line declares that the header include statement
<samp>TheirHeader.h</samp> should be excluded. The label <code>H</code>
denotes a pre-processing #include statement. For example, if a source file
contains the line: <code>#include 'TheirHeader.h'</code>, the dependency
scanner will ignore it.</li>
<li><dfn>line 8</dfn>: this line declares that the external dependency for
<samp>ItsObject.o</samp> should be excluded. The label <code>OBJ</code>
denotes a compiled binary object. These dependencies are normally inserted
into the source files as special comments. For example, if a source file
contains the line: <code>! depends on: ItsObject.o</code>, the dependency
scanner will ignore it.</li>
</ul>
<p>An <code>EXCL_DEP</code> declaration normally applies to all files in the
build. However, you can suffix it with the name of a sub-package, i.e.
<code>EXCL_DEP::<pcks></code>. In such case, the declaration will only
apply while scanning for dependencies in the source files in the sub-package
named <pcks>.</p>
<p>You can also exclude all dependency scan of a particular type. To do so,
simply declare the type in the value. For example, if you do not want the
build system to scan for the <code>CALLS: <executable></code> directive
in the comment lines of your scripts, you can make the following
declaration:</p>
<pre>
bld::excl_dep EXE
</pre>
<p>The opposite of the <code>EXCL_DEP</code> declaration is the
<code>DEP::<pcks></code> declaration, which you can use to add a
dependency to a source file (in the package name <code><pcks></code>).
The syntax of the declaration is similar to that of <code>EXCL_DEP</code>,
but you must specify the package name of a source file for DEP declarations.
Please also note that a <code>DEP</code> declaration only works if the
particular dependency is supported for the particular source file - as it
makes no sense, for example, to specify a USE dependency for a shell
script.</p>
<p>If you need to switch off dependency checking completely, you can use the
<code>NO_DEP</code> declaration. For example, to switch off dependency
checking for all but the <samp>foo/bar</samp> sub-package, you can do:</p>
<pre>
bld::no_dep true
bld::no_dep::foo/bar false
</pre>
<h3 id="advanced_blockdata">Linking a Fortran executable with a BLOCKDATA
program unit</h3>
<p>If it is required to link Fortran executables with BLOCKDATA program
units, you must declare the executable targets and the objects containing the
BLOCKDATA program units using the <code>BLOCKDATA::<target></code>
declarations. For example, if <samp>foo.exe</samp> is an executable target
depending on the objects of the BLOCKDATA program units
<samp>blkdata.o</samp> and <samp>fbk.o</samp>, you will make the following
declarations:</p>
<pre>
bld::blockdata::foo.exe blkdata fbk
</pre>
<p>If all your executables are dependent on <samp>blkdata.o</samp> and
<samp>fbk.o</samp>, you will make the following declarations:</p>
<pre>
bld::blockdata blkdata fbk
</pre>
<h3 id="advanced_library">Creating library archives</h3>
<p>If you are interested in building library archives, the build system
allows you to do it in a relatively simple way. For each sub-package in the
source tree, there is a target to build a library containing all the objects
compiled from the source files (that are not main programs) within the
sub-package. If the sub-package contains children sub-packages, the object
files of the children will also be included recursively. By default, the
library archive is named after the sub-package, in the format
<code>lib<pcks>.a</code>. (For example, the library archive for the
package <samp>foo/bar/egg</samp> will be named
<samp>libfoo__bar__egg.a</samp> by default.) If you do not like the default
name for the sub-package library, you can use the
<code>LIB::<pcks></code> declaration to rename it, as long as the new
name does not clash with other targets. For example, to rename
<samp>libfoo__bar__egg.a</samp> to <samp>libham.a</samp>, you will make the
following declaration in your extract configuration file:</p>
<pre>
bld::lib::foo/bar/egg ham
</pre>
<p>In addition to sub-package libraries, you can also build a global library
archive for the whole source tree. By default, the library is named
<samp>libfcm_default.a</samp>, but you can rename it using the
<code>LIB</code> declaration as above. For example, to rename the library to
<samp>libmy-lib.a</samp>, you will make the following declaration in your
extract configuration file:</p>
<pre>
bld::lib my-lib
</pre>
<p>When a library archive is created successfully, the build system will
automatically generate the relevant exclude dependency configurations in the
<samp>etc/</samp> sub-directory of the build root. You will be able to
include these configurations in subsequent builds that utilise the library.
The root names of the configuration files match those of the library archives
that you can create in the current build, but the extension <samp>*.a</samp>
is replaced with <samp>*.cfg</samp>. For example, the exclude dependency
configuration for <samp>libmy-lib.a</samp> is <samp>libmy-lib.cfg</samp>.</p>
<h3 id="advanced_pp">Pre-processing</h3>
<p>As most modern compilers can handle pre-processing, the build system
leaves pre-processing to the compiler by default. However, it is recognised
that there are code written with pre-processor directives that can alter the
argument list of procedures and/or their dependencies. If a source file
requires pre-processing in such a way, we have to pre-process before running
the interface block generator and the dependency scanner. The <code>PP</code>
declaration can be used to switch on this pre-processing stage. The
pre-processing stage can be switched on globally or for individual
sub-packages only. The following is an example, using an extract
configuration file:</p>
<pre id="example_7">
# Example 7
# ----------------------------------------------------------------------
cfg::type ext
cfg::version 1.0
bld::pp::gen true # line 4
bld::pp::var/foo true # line 5
bld::tool::cppkeys GOOD WEATHER FORECAST # line 7
bld::tool::fppkeys FOO BAR EGG HAM # line 8
# ... some other declarations ...
</pre>
<p>Here is an explanation of what each line does:</p>
<ul>
<li><dfn>line 4-5</dfn>: these switches on the pre-processing stage for all
sub-packages under <samp>gen</samp> and <samp>var/foo</samp>.</li>
<li><dfn>line 7</dfn>: this declares a list of pre-defined macros
<samp>GOOD</samp>, <samp>WEATHER</samp> and <samp>FORECAST</samp> for
pre-processing all C files.</li>
<li><dfn>line 8</dfn>: this declares a list of pre-defined macros
<samp>FOO</samp>, <samp>BAR</samp>, <samp>EGG</samp> and <samp>HAM</samp>
for pre-processing all Fortran files that require processing.</li>
</ul>
<p>Source files requiring pre-processing may contain <code>#include</code>
statements to include header files. For including a local file, its name
should be embedded within a pair of quotes, i.e. <samp>'file.h'</samp> or
<samp>"file.h"</samp>. If the header file is embedded within a pair of
<file.h> angle brackets, the system will assume that the file can be
found in a standard location.</p>
<p>The build system allows header files to be placed anywhere within the
declared source tree. The system uses the dependency scanner, as described in
the previous sub-section to scan for any header file dependencies. All source
files requiring pre-processing and all header files are scanned. Header files
that are required are copied to the <samp>inc/</samp> subdirectory of the
build root, which is automatically added to the pre-processor search path via
the <code>-I<dir></code> option. The build system uses an internal
logic similar to <code>make</code> to perform pre-processing. Header files
are only copied to the <samp>inc/</samp> sub-directory if they are used in
<code>#include</code> statements.</p>
<p>Unlike <code>make</code>, which only uses the timestamp to determine
whether an item is out of date, the internal logic of the build system does
this by inspecting the content of the file as well. In an incremental build,
the pre-processed file is only updated if its content has changed. This
avoids unnecessary updates (and hence unnecessary re-compilation) in an
incremental build if the changed section of the code does not affect the
output file.</p>
<p>Pre-processed code generated during the pre-processing stage are sent to
the <samp>ppsrc/</samp> sub-directory of the build root. It will have a
relative path that reflects the name of the declared sub-package. The
pre-processed source file will have the same root name as the original source
file. For C files, the same extension <samp>.c</samp> will be used. For
Fortran files, the case of the extension will normally be dropped, e.g. from
<samp>.F90</samp> to <samp>.f90</samp>.</p>
<p>Following pre-processing, the system will use the pre-processed source
file as if it is the original source file. The interface generator will
generate the interface file using the pre-processed file, the dependency
scanner will scan the pre-processed file for dependencies, and the compiler
will compile the pre-processed source.</p>
<p>The <code>TOOL::CPPKEYS</code> and <code>TOOL::FPPKEYS</code> declarations
are used to pre-define macros in the C and Fortran pre-processor
respectively. This is implemented by the build system using the pre-processor
<code>-D</code> option on each word in the list. The use of these
declarations are not confined to the pre-process stage. If any source files
requiring pre-processing are left to the compiler, the declarations will be
used to set up the commands for compiling these source files.</p>
<p>The <code>TOOL::CPPKEYS</code> and <code>TOOL::FPPKEYS</code> declarations
normally applies globally, but like any other <code>TOOL</code> declarations,
they can be suffixed with sub-package names. In such cases, the declarations
will apply only to the specified sub-packages.</p>
<dl>
<dt>Note - changing pre-processor flags</dt>
<dd>
<p>As for compiler flags, the build system detects changes in
pre-processor flags (<code>TOOL::CPPFLAGS</code> and
<code>TOOL::FPPFLAGS</code>) and macro definitions
(<code>TOOL::CPPKEYS</code> and <code>TOOL::FPPKEYS</code>). If the
pre-processor flags or the macro definitions have changed in an
incremental build, the system will re-do all the necessary
pre-processing. The following hierarchy is followed:</p>
<ul>
<li>If the pre-processor flags or macro definitions for a particular
source file change, only that source file will be pre-processed
again.</li>
<li>If the pre-processor flags or macro definitions for a particular
container package change, only source files within that container will
be pre-processed again.</li>
<li>If the global pre-processor flags or macro definitions change, all
source files will be pre-processed again.</li>
<li>If the pre-processor command changes, all source files are
pre-processed again.</li>
</ul>
</dd>
</dl>
<h3 id="advanced_file-type">File type</h3>
<p>The build system only knows what to do with an input source file if it
knows what type of file it is. The type of a source file is normally
determined automatically using one of the following three methods (in
order):</p>
<ol>
<li>If the file is named with an extension, its extension will be matched
against a set of registered file extensions. If a match is found, the file
type will be set according to the register.</li>
<li>If a file does not have an extension or does not match with a
registered extension, its name is compared with a set of pre-defined
patterns. If a match is found, the file type will be set according to the
file type associated with the pattern.</li>
<li>If the above two methods failed and if the file is a text file, the
system will attempt to read the first line of the file. If the first line
begins with a <code>#!</code> pattern, the line will be compared with a set
of pre-defined patterns. If a match is found, the file type will be set
according to the file type associated with the pattern.</li>
</ol>
<p>In addition to the above, if a file is a Fortran or C source file, the
system will attempt to open the source file to determine whether it contains
a main program, module (Fortran only) or just standalone procedures. All
these information will be used later by the build system to process the
source file.</p>
<p>The build system registers a file type with a set of type flags delimited
by the double colons <code>::</code>. For example, a Fortran 9X source file
is registered as <code>FORTRAN::FORTRAN9X::SOURCE</code>. (Please note that
the order of the type flags in the list is insignificant. For example,
<code>FORTRAN::SOURCE</code> is the same as <code>SOURCE::FORTRAN</code>.)
For a list of all the type flags used by the build system, please see the
<a href="annex_bld_cfg.html#infile-ext-types">input file extension type flags
table</a> in the <a href="annex_bld_cfg.html">Annex: Declarations in FCM
build configuration file</a>.</p>
<p>The following is a list of default input file extensions and their
associated types:</p>
<dl>
<dt><samp>.f .for .ftn .f77</samp></dt>
<dd><code>FORTRAN::SOURCE</code> Fortran 77 source file (assumed to be
fixed format)</dd>
<dt><samp>.f90 .f95</samp></dt>
<dd><code>FORTRAN::FORTRAN9X::SOURCE</code> Fortran 9X source file (assumed
to be free format)</dd>
<dt><samp>.F .FOR .FTN .F77</samp></dt>
<dd><code>FPP::SOURCE</code> Fortran 77 source file (assumed to be fixed
format) that requires pre-processing</dd>
<dt><samp>.F90 .F95</samp></dt>
<dd><code>FPP::FPP9X::SOURCE</code> Fortran 9X source file (assumed to be
free format) that requires pre-processing</dd>
<dt><samp>.c</samp></dt>
<dd><code>C::SOURCE</code> C source file</dd>
<dt><samp>.h .h90</samp></dt>
<dd><code>CPP::INCLUDE</code> Pre-processor <code>#include</code> header
file</dd>
<dt><samp>.o .obj</samp></dt>
<dd><code>BINARY::OBJ</code> Compiled binary object</dd>
<dt><samp>.exe</samp></dt>
<dd><code>BINARY::EXE</code> Binary executable</dd>
<dt><samp>.a</samp></dt>
<dd><code>BINARY::LIB</code> Binary object library archive</dd>
<dt><samp>.sh .ksh .bash .csh</samp></dt>
<dd><code>SHELL::SCRIPT</code> Unix shell script</dd>
<dt><samp>.pl .pm</samp></dt>
<dd><code>PERL::SCRIPT</code> Perl script</dd>
<dt><samp>.py</samp></dt>
<dd><code>PYTHON::SCRIPT</code> Python script</dd>
<dt><samp>.tcl</samp></dt>
<dd><code>TCL::SCRIPT</code> Tcl/Tk script</dd>
<dt><samp>.pro</samp></dt>
<dd><code>PVWAVE::SCRIPT</code> IDL/PVWave program</dd>
<dt><samp>.cfg</samp></dt>
<dd><code>CFGFILE</code> FCM configuration file</dd>
<dt><samp>.inc</samp></dt>
<dd><code>FORTRAN::FORTRAN9X::INCLUDE</code> Fortran INCLUDE file</dd>
<dt><samp>.interface</samp></dt>
<dd><code>FORTRAN::FORTRAN9X::INCLUDE::INTERFACE</code> Fortran 9X INCLUDE
interface block file</dd>
</dl>
<p>N.B. The extension must be unique. For example, the system does not
support the use of <samp>.inc</samp> files for both <code>#include</code> and
Fortran <code>INCLUDE</code>.</p>
<p>The following is a list of supported file name patterns and their
associated types:</p>
<dl>
<dt><samp>*Scr_* *Comp_* *IF_* *Suite_* *Interface_*</samp></dt>
<dd><code>SHELL::SCRIPT</code> Unix shell script, GEN-based project naming
conventions</dd>
<dt><samp>*List_*</samp></dt>
<dd><code>SHELL::SCRIPT::GENLIST</code> Unix shell script, GEN list
file</dd>
<dt><samp>*Sql_*</samp></dt>
<dd><code>SCRIPT::SQL</code> SQL script, GEN-based project naming
conventions</dd>
</dl>
<p>The following is a list of supported <code>#!</code> line patterns and
their associated types:</p>
<dl>
<dt><samp>*sh* *ksh* *bash* *csh*</samp></dt>
<dd><code>SHELL::SCRIPT</code> Unix shell script</dd>
<dt><samp>*perl*</samp></dt>
<dd><code>PERL::SCRIPT</code> Perl script</dd>
<dt><samp>*python*</samp></dt>
<dd><code>PYTHON::SCRIPT</code> Python script</dd>
<dt><samp>*tclsh* *wish*</samp></dt>
<dd><code>TCL::SCRIPT</code> Tcl/Tk script</dd>
</dl>
<p>The build system allows you to add or modify the register for input file
extensions and their associated type using the
<code>INFILE_EXT::<ext></code> declaration, where <ext> is a file
name extension without the leading dot. If file extension alone is
insufficient for defining the type of your source file, you can use the
<code>SRC_TYPE::<pcks></code> declaration, (where <pcks> is the
package name of the source file). For example, in an extract configuration
file, you may have:</p>
<pre id="example_8">
# Example 8
# ----------------------------------------------------------------------
cfg::type ext
cfg::version 1.0
bld::infile_ext::foo CPP::INCLUDE # line 4
bld::infile_ext::bar FORTRAN::FORTRAN9X::INCLUDE # line 5
bld::src_type::egg/ham.f FORTRAN::FORTRAN9X::INCLUDE # line 6
# ... some other declarations ...
</pre>
<p>Here is an explanation of what each line does:</p>
<ul>
<li><dfn>line 4</dfn>: this line registers the extension <samp>.foo</samp>
to be of type <code>CPP::INCLUDE</code>. This means that any input files
with <samp>.foo</samp> extension will be treated as if they are
pre-processor header files.</li>
<li><dfn>line 5</dfn>: this line registers the extension <samp>.bar</samp>
to be of type <code>FORTRAN::FORTRAN9X::INCLUDE</code>. This means that any
input file with <samp>.bar</samp> extension will be treated as if they are
Fortran 9X INCLUDE files.</li>
<li><dfn>line 6</dfn>: this line declares the type for the source file in
the package <samp>egg::ham.f</samp> to be
<code>FORTRAN::FORTRAN9X::INCLUDE</code>. Without this declaration, this
file would normally be given the type <code>FORTRAN::SOURCE</code>.</li>
</ul>
<p>The <code>INFILE_EXT</code> declarations deal with extensions of input
files. There is also a <code>OUTFILE_EXT::<type></code> declaration
that deals with extensions of output files. The declaration is opposite that
of <code>INFILE_EXT</code>. The file <type> is now declared with the
label, and the extension is declared as the value. It is worth noting that
<code>OUTFILE_EXT</code> declarations use very different syntax for
<type>, and the declared extension must include the leading dot. For a
list of output types used by the build system, please see the <a href=
"annex_bld_cfg.html#outfile-ext-types">output file extension types table</a>
in the <a href="annex_bld_cfg.html">Annex: Declarations in FCM build
configuration file</a>. An example is given below:</p>
<pre id="example_9">
# Example 9
# ----------------------------------------------------------------------
cfg::type ext
cfg::version 1.0
bld::outfile_ext::mod .MOD # line 4
bld::outfile_ext::interface .intfb # line 5
# ... some other declarations ...
</pre>
<p>Here is an explanation of what each line does:</p>
<ul>
<li><dfn>line 4</dfn>: this line modifies the extension of compiled Fortran
9X module information files from the default <samp>.mod</samp> to
<samp>.MOD</samp>.</li>
<li><dfn>line 5</dfn>: this line modifies the extension of INCLUDE Fortran
9X interface block files from the default <samp>.interface</samp> to
<samp>.intfb</samp>.</li>
</ul>
<p>N.B. If you have made changes to the file type registers, whether it is
for input files or output files, it is always worth re-building your code in
full-build mode to avoid unexpected behaviour.</p>
<h3 id="advanced_inherit">Inherit from a previous build</h3>
<p>As you can inherit from previous extracts, you can inherit from previous
builds. The very same <code>USE</code> statement can be used to declare a
build, which the current build will depend on. The only difference is that
the declared location must contain a valid build configuration file. In fact,
if you use the extract system to obtain your build configuration file, any
<code>USE</code> declarations in the extract configuration file will also be
<code>USE</code> declarations in the output build configuration file.</p>
<p>By declaring a previous build with a <code>USE</code> statement, the
current build automatically inherits settings from it. The following points
are worth noting:</p>
<ul>
<li>Build targets are not normally inherited. However, you can switch on
inheritance of build targets using an <code>INHERIT::TARGET</code>
declaration, such as:
<pre>
inherit::target true
</pre>
</li>
<li>The build root directory and its sub-directories of the inherited build
are placed into the search paths. For example, if we have an inherited
build at <samp>/path/to/inherited</samp>, and it is used by a build at
<samp>/path/to/my_build</samp>, the search path of executable files will
become <samp>/path/to/my_build/bin:/path/to/inherited/bin</samp>, so that
the <samp>bin/</samp> sub-directory of the current build is searched before
the <samp>bin/</samp> sub-directory of the inherited build. If two or more
<code>USE</code> statements are declared, the <code>USE</code> statement
declared last will have higher priority. For example, if the current build
is <var>C</var>, and it USEs build <var>A</var> before build <var>B</var>,
the search path will be <samp>C:B:A</samp>.</li>
<li>Source files are inherited by default. If a source file is declared in
the current build that has the same package name as a source file of the
inherited build, it will override that in the inherited build. Any source
files missing from the current build will be taken from the inherited
build.
<p>You can switch off inheritance of source files using an
<code>INHERIT::SRC</code> declaration. This declaration can be suffixed
with the name of a sub-package. In such case, the declaration applies
only to the inheritance of the sub-package. Otherwise, it applies
globally. For example:</p>
<pre>
# Switch off inheritance of source files in the <samp>gen</samp> sub-package
inherit::src::gen false
</pre>
</li>
<li><code>BLOCKDATA</code>, <code>DEP</code>, <code>EXCL_DEP</code>,
<code>EXE_DEP</code>, <code>INFILE_EXT</code>, <code>LIB</code>,
<code>OUTFILE_EXT</code>, <code>PP</code>, <code>TOOL</code> and
<code>SRC_TYPE</code> declarations are automatically inherited. If the same
setting is declared in the current incremental build, it overrides the
inherited declaration.</li>
</ul>
<p>As an example, suppose we have already performed an extract and build
based on the configuration in <a href="#example_2">example 2</a>, we can set
up an extract configuration file as follows:</p>
<pre id="example_10">
# Example 10
# ----------------------------------------------------------------------
cfg::type ext
cfg::version 1.0
use $HOME/example # line 4
dest $HOME/example10 # line 6
bld::inherit::target true # line 8
bld::target ham.exe egg.exe # line 9
bld::tool::fflags -O2 -w # line 11
bld::tool::cflags -O2 # line 12
# ... and other declarations for repositories and source directories ...
</pre>
<p>Here is an explanation of what each line does:</p>
<ul>
<li><dfn>line 4</dfn>: this line declares a previous extract at
<samp>$HOME/example</samp> which the current extract will inherit from. The
same line will be written to the output build configuration file. The
subsequent build will then inherit from the build at
<samp>$HOME/example</samp>.</li>
<li><dfn>line 6</dfn>: this declares the destination root directory of the
current extract, which will become the root directory of the current build.
Search paths of the build sub-directories will be set automatically. For
example, the search path for executable files created by the current build
will be <samp>$HOME/example10/bin:$HOME/example/bin</samp>.</li>
<li><dfn>line 8</dfn>: this line switches on inheritance of build targets.
The build targets in <a href="#example_1">example 1</a>, i.e.
<samp>foo.exe</samp> and <samp>bar.exe</samp> will be built as part of the
current build.</li>
<li><dfn>line 9</dfn>: this declares two new build targets
<samp>ham.exe</samp> and <samp>egg.exe</samp> to be added to the inherited
ones. The default build targets of the current build will now be
<samp>foo.exe</samp>, <samp>bar.exe</samp>, <samp>ham.exe</samp> and
<samp>egg.exe</samp>.</li>
<li><dfn>line 11-12</dfn>: these lines modify options used by the Fortran
and the C compilers, overriding those inherited from <a href=
"#example_1">example 1</a>.</li>
</ul>
<dl>
<dt>Build inheritance limitation: handling of include files</dt>
<dd>
<p>The build system uses the compiler/pre-processor's <code>-I</code>
option to specify the search path for include files. For example, it uses
the option to specify the <samp>inc/</samp> sub-directories of the
current build and its inherited build.</p>
<p>However, some compilers/pre-processors (e.g. <code>cpp</code>) search
for include files from the container directory of the source file before
searching for the paths specified by the <code>-I</code> options. This
behaviour may cause the build to behave incorrectly.</p>
<p>Consider a source file <samp>egg/hen.c</samp> that includes
<samp>fried.h</samp>. If the directory structure looks like:</p>
<pre>
# Sources in inherited build:
egg/hen.c
egg/fried.h
# Sources in current build:
egg/fried.h
</pre>
<p>The system will correctly identify that <samp>fried.h</samp> is out of
date, and trigger a re-compilation of <samp>egg/hen.c</samp>. However, if
the compiler searches for the include files from the container directory
of the source file first, it will wrongly use the include file in the
inherited build instead of the current one.</p>
<p>Some compilers (e.g. <code>gfortran</code>) do not behave this way and
others (e.g. <code>ifort</code>) have options to prevent include file
search in the container directory of the source file. If you are using
such a compiler you can avoid the problem for Fortran compilation
although this does not fix the problem entirely if you have switched on
the pre-processing stage. Otherwise you may have to work around the
problem, (e.g. by making a comment change in the source file, or by not
using an inherited build at all).</p>
</dd>
</dl>
<h3 id="advanced_data">Building data files</h3>
<p>While the usual targets to be built are the executables associated with
source files containing main programs, libraries or scripts, the build system
also allows you to build <em>data</em> files. All files with no registered
type are considered to be <em>data</em> files. For each container
sub-package, there is an automatic target for copying all <em>data</em> files
to the <samp>etc/</samp> sub-directory of the build root. The name of the
target has the form <code><pcks>.etc</code>, where <pcks> is the
name of the sub-package (with package names delimited by the double
underscore <code>__</code>). For example, the target name for sub-package
<samp>foo/bar</samp> is <samp>foo__bar.etc</samp>. This target is
particularly useful for copying, say, all namelists in a sub-package to the
<samp>etc/</samp> sub-directory of the build root.</p>
<p>At the end of a successful build, if the <samp>etc/</samp> sub-directory
is not empty, the <samp>fcm_env.sh</samp> script will export the environment
variable <var>FCM_ETCDIR</var> to point to the <samp>etc/</samp>
sub-directory. You should be able to use this environment variable to locate
your data files.</p>
<h2 id="verbose">Diagnostic verbose level</h2>
<p>The amount of diagnostic messages generated by the build system is
normally set to a level suitable for normal everyday operation. This is the
default diagnostic verbose level 1. If you want a minimum amount of
diagnostic messages, you should set the verbose level to 0. If you want more
diagnostic messages, you can set the verbose level to 2 or 3. You can modify
the verbose level in two ways. The first way is to set the environment
variable <var>FCM_VERBOSE</var> to the desired verbose level. The second way
is to invoke the build system with the <code>-v <level></code> option.
(If set, the command line option overrides the environment variable.)</p>
<p>The following is a list of diagnostic output at each verbose level:</p>
<dl>
<dt>Level 0</dt>
<dd>
<ul>
<li>Report the time taken at the end of each stage of the build
process.</li>
<li>Run the <code>make</code> command in silent mode.</li>
</ul>
</dd>
<dt>Level 1</dt>
<dd>
<ul>
<li>Everything at verbose level 0.</li>
<li>Report the name of the build configuration file.</li>
<li>Report the location of the build destination.</li>
<li>Report date/time at the beginning of each stage of the build
process.</li>
<li>Report removed directories.</li>
<li>Report number of pre-processed files.</li>
<li>Report number of generated F9X interface files.</li>
<li>Report number of source files scanned for dependencies.</li>
<li>Report name of updated <samp>Makefile</samp>.</li>
<li>Print compiler/linker commands.</li>
<li>Report total time.</li>
</ul>
</dd>
<dt>Level 2</dt>
<dd>
<ul>
<li>Everything at verbose level 1.</li>
<li>For incremental build in archive mode, report the commands used to
extract the archives.</li>
<li>Report creation and removal of directories.</li>
<li>Report pre-processor commands.</li>
<li>Print compiler/linker commands with timestamps.</li>
</ul>
</dd>
<dt>Level 3</dt>
<dd>
<ul>
<li>Everything at verbose level 2.</li>
<li>Report update of dummy files.</li>
<li>Report all shell commands.</li>
<li>Report pre-processor commands with timestamps.</li>
<li>Report any F9X interface files generated.</li>
<li>Report number of lines and number of automatic dependencies for
each source file which is scanned.</li>
<li>Run <code>make</code> on normal mode (as opposed to silent
mode).</li>
<li>Report start date/time and time taken of <code>make</code>
commands.</li>
</ul>
</dd>
</dl>
<h2 id="overview">Overview of the build process</h2>
<p>The FCM build process can be summarised in five stages. Here is a summary
of what is done in each stage:</p>
<ol>
<li><dfn>Parse configuration and setup destination</dfn>: in this
pre-requisite stage, the build system parses the configuration file. The
<samp>src/</samp> sub-directory is searched recursively for source files.
For full builds, it ensures that the sub-directories and files created by
the build system are removed. If you invoke <code>fcm build</code> with a
<code>--clean</code> option, the system will not go any further.</li>
<li><dfn>Setup build</dfn>: in this first stage, the system determines
whether any settings have changed by using the cache. If so, the cache is
updated with the current settings.</li>
<li><dfn>Pre-process</dfn>: if any files in any source files require
pre-processing, they will be pre-processed at this stage. The resulting
pre-processed source files will be sent to the <samp>ppsrc/</samp>
sub-directory of the build root.</li>
<li><dfn>Generate dependency</dfn>: the system scans source files of
registered types for dependency information. For an incremental build, the
information is only updated if a source file is changed. The system then
uses the information to write a <samp>Makefile</samp> for the main
build.</li>
<li><dfn>Generate interface</dfn>: if there are Fortran 9X source files
with standalone subroutines and functions, the build system generates
interface blocks for them. The result of which will be written to the
interface files in the <samp>inc/</samp> sub-directory of the build
root.</li>
<li>
<dfn>Make</dfn>: the system invokes <code>make</code> on the
<samp>Makefile</samp> generated in the previous stage to perform the main
build. Following a build, the <em>root</em> directory of the build may
contain the following sub-directories (empty ones are removed
automatically at the end of the build process):
<dl>
<dt><samp>.cache/.bld/</samp></dt>
<dd>Cache files, used internally by FCM.</dd>
<dt><samp>bin/</samp></dt>
<dd>Executable binaries and scripts.</dd>
<dt><samp>cfg/</samp></dt>
<dd>Configuration files.</dd>
<dt><samp>done/</samp></dt>
<dd>Dummy <em>done</em> files used internally by the
<samp>Makefile</samp> generated by FCM.</dd>
<dt><samp>etc/</samp></dt>
<dd>Miscellaneous data files.</dd>
<dt><samp>flags/</samp></dt>
<dd>Dummy <em>flags</em> files used internally by the
<samp>Makefile</samp> generated by FCM.</dd>
<dt><samp>inc/</samp></dt>
<dd>Include files, such as <samp>*.h</samp>, <samp>*.inc</samp>,
<samp>*.interface</samp>, and <samp>*.mod</samp>.</dd>
<dt><samp>lib/</samp></dt>
<dd>Object library archives.</dd>
<dt><samp>obj/</samp></dt>
<dd>Compiled object files.</dd>
<dt><samp>ppsrc/</samp></dt>
<dd>Source directories with pre-processed files.</dd>
<dt><samp>src/</samp></dt>
<dd>Source directories. This directory is not changed by the build
system.</dd>
<dt><samp>tmp/</samp></dt>
<dd>Temporary objects and binaries. Files generated by the
compiler/linker may be left here.</dd>
</dl>
</li>
</ol>
</div>
</div>
</div>
<hr/>
<div class="container-fluid text-center">
<div class="row"><div class="col-md-12">
<address><small>
© British Crown Copyright 2006-16
<a href="http://www.metoffice.gov.uk">Met Office</a>.
See <a href="../etc/fcm-terms-of-use.html">Terms of Use</a>.<br />
This document is released under the British <a href=
"http://www.nationalarchives.gov.uk/doc/open-government-licence/" rel=
"license">Open Government Licence</a>.<br />
</small></address>
</div></div>
</div>
<script type="text/javascript" src="../etc/jquery.min.js"></script>
<script type="text/javascript" src="../etc/bootstrap/js/bootstrap.min.js"></script>
<script type="text/javascript" src="../etc/fcm.js"></script>
<script type="text/javascript" src="../etc/fcm-version.js"></script>
</body>
</html>
|