module.sources

$Id$

Introduction

Each module has a file module.sources which lists all sources in the module. Each source-file is listed with its full path relative to the module directory on a single line. The path-separator must be a slash "/".

Example:

Suppose you have a module foo which has the source files foo_module.cpp, src/foo_file_1.cpp and src/foo_file_2.cpp, then the corresponding module.sources should be

foo_module.cpp
src/foo_file_1.cpp
src/foo_file_2.cpp

Empty lines are ignored and everything after a hash character ("#") is regarded as a comment.

Adding Source-File Options

Some source-files need special attention. They must be compiled with different options. The module.sources file allows to specify a set of options to one single source-file or to a group of source-files.

The options are specified as a semicolon (";") separated lists of key-value pairs. A single key-value pair is specified as "key" or "key=value". If the value is omitted, it is assumed to be "1". So the option "key" is the same as "key=1". The options are specified in square-brackets after a hash character:

# [option_1;option_2=some_value;option_3=0]

Note:

Options can be specified for a single file by adding the option specification "# [options]" to the line with the source-file:

src/foo_file_1.cpp # [foo=bar]

Options can also be specified for a group of files by adding the option specification "# [options]" to a single line before the files:

# no option for file_1.cpp:
file_1.cpp
# specify option_1 and option_2 for file_2.cpp and file_3.cpp:
# [option_1;option_2=value_1]
file_2.cpp
file_3.cpp
# specify only option_2 for file_4.cpp and file_5.cpp
# [option_2=value_2]
file_4.cpp
file_5.cpp

Note:

Options

The following options are supported by core:

Precompiled header (pch)

Opera's source-code has many header files that are included in every source file. The time the compiler takes to process these header files over and over again can account for nearly all of the time required to build the project. To make builds faster, many compilers allow to "precompile" a header file; then, if builds can use the precompiled header file they will be much faster.

Opera's precompiled header is core/pch.h. Each source-file starts with including the precompiled header:

/**
 * Some copyright header...
 */
#include "core/pch.h"
...

For some source files it might be necessary for some reason to not use a precompiled header. Those files should have the option no-pch. The option pch (= use precompiled header) is default.

Note:

Jumbo compile (jumbo)

A big overhead on compiling source-files is to start the compiler and load the (precompiled) header files for each source-file. One way to optimize compile time is to use a precompiled header. Another step is to combine multiple source files of one module into one jumbo-compile-unit by #includeing the source-files. In this case the jumbo-compile-unit uses a different pre-compiled header file core/pch_jumbo.h, because some compilers don't support to include the same precompiled header file twice.

The jumbo-compile-units are automatically generated by the operasetup script. In the simplest case all source-files of a module are included in one jumbo-compile-unit.

Example: If the module "foo" defines the foo/module.sources file as:

src/file_1.cpp
src/file_2.cpp
src/file_3.cpp
Then a single jumbo-compile unit foo/foo_jumbo.cpp is created:
/**
 * Some copyright header...
 */
#include "core/pch_jumbo.h"

#include "modules/foo/src/file_1.cpp"
#include "modules/foo/src/file_2.cpp"
#include "modules/foo/src/file_3.cpp"

It is possible to exclude a single file (or multiple files) from a jumbo-compile-unit by adding the option "jumbo=0" or "no-jumbo".

It is also possible to split several files into different jumbo-compile-units, e.g. to hide some declarations from some other source-files. This is done by specifying a filename as the value of the "jumbo" option.

Example: If the module "foo" defines the foo/module.sources file as:

src/file_1.cpp # [no-jumbo]
# [jumbo=src/foo_jumbo_1.cpp]
src/file_2.cpp
src/file_3.cpp
# [jumbo=src/foo_jumbo_2.cpp]
src/file_4.cpp
src/file_5.cpp
Then two jumbo-compile units foo/src/foo_jumbo_1.cpp and foo/src/foo_jumbo_2.cpp are created:
foo/src/foo_jumbo_1.cpp:
/**
 * Some copyright header...
 */
#include "core/pch_jumbo.h"

#include "modules/foo/src/file_2.cpp"
#include "modules/foo/src/file_3.cpp"
foo/src/foo_jumbo_2.cpp:
/**
 * Some copyright header...
 */
#include "core/pch_jumbo.h"

#include "modules/foo/src/file_4.cpp"
#include "modules/foo/src/file_5.cpp"

Note:

Allow System Includes

If the option system_includes is set, then the source-file includes core/pch_system_includes.h instead of core/pch.h. The only difference between those two files is, that core/pch_system_includes.h defines ALLOW_SYSTEM_INCLUDES.

This is currently used for different purposes:

Sources Setup

The operasetup script parses all module.sources files and generates list of files depending on the options pch, jumbo and system_includes in modules/hardcore/setup/plain/sources/ and modules/hardcore/setup/jumbo/sources/.

In each of those directories the files sources.all, sources.nopch, sources.pch, sources.pch_jumbo and sources.pch_system_includes are generated. The format of these files is simple:
The files are plain text files, each line of the file contains a single path to a source file. The path is relative the source root. The file contains no comments.

The generated sources files are used by the update_vcproj tool to update the list of sources in Visual Studio project files.

The following table shows to which source.* files a source-file is added, depending on the different combinations of the pch, jumbo and system_includes options.

pch: yesyesyesyes nononono
jumbo: yesyesnono yesyesnono
system_includes: yesnoyesno yesnoyesno
plain/sources.all ++++ ++++
plain/sources.nopch ---- ++++
plain/sources.pch -+-+ ----
plain/sources.pch_jumbo ---- ----
plain/sources.pch_system_includes +-+- ----
jumbo/sources.all ++++ ++++
jumbo/sources.nopch +--- ++++
jumbo/sources.pch ---+ ----
jumbo/sources.pch_jumbo -+-- ----
jumbo/sources.pch_system_includes --+- ----

Note: the intersection of the source-files listed in sources.nopch, sources.pch, sources.pch_jumbo and sources.pch_system_includes is empty, because a single source file may only be compiled with a single preceompiled header.

Note: the union of the source-files listed in sources.nopch, sources.pch, sources.pch_jumbo and sources.pch_system_includes is equal to the set of source-files listed in sources.all.

Sources Setup for module developer

A module developer who needs to maintain a module should set the options according to the following rules:

Usually a source-file does not need an option. It should be compiled with the default options (i.e. pch, jumbo and no-system_includes). The file should #include "core/pch.h". And the file will be added to the module's default jumbo-compile-unit.

If a source-file needs to include some system header file (like <sdtio.h>) then the option system_includes should be set and the source-file should #include "core/pch_system_includes.h".
Note: Files with different system_includes options cannot be compiled in the same jumbo-compile-unit, so you may have to use the option jumbo to organize the source files of the module into different jumbo-compile-units.

If a source-file cannot be compiled with a precompiled header file (neither with core/pch.h nor with core/pch_system_includes.h), e.g. because the source-file needs to #define something before #including the pch header file, then the source-file should get the option no-pch.
Note: In addition the option system_includes may (or may not) be set, see the paragraph above.
Note: Files with different pch options cannot be compiled in the same jumbo-compile-unit, so you may have to use the option jumbo to organize the source files of the module into different jumbo-compile-units.

Sources Setup for platform developer

A platform developer who needs to compile all opera sources can use the sources setup to get a list of all files to compile.

First the platform developer should consider whether to use jumbo compile or plain compilation:
Jumbo compilation is usually faster than plain compilation because the compiler does not need to be started and it does not need to load the header files for each single file.
Jumbo compilation was tested with gcc and visual studio, but there may be compilers for which the source files grow too big.

If jumbo compilation should be used, then the sources.* files from modules/hardcore/setup/jumbo/sources/ should be used.
If plain compilation should be used, then the sources.* files from modules/hardcore/setup/plain/sources/ should be used.

If a compiler supports precompiled headers, then

If a compiler does not support precompiled headers, then comile all files in sources.all.

Overriding Configuration Locally

If a module has a file module.sources.override in its root directory, this file fully overrides the contents of the module.sources file; that is, it is read instead and the module.sources file is completely ignored. The file format and interpretation of the contents is identical.

The purpose of this exception is to allow developers to locally override the configuration in the modules.sources file without having to have locally modified version controlled files. An example of changes a developer might want to do locally is to fully or partially disable jumbo compilation for some modules. Since the idea is to avoid having locally modified version controlled files, a modules.sources.override file should of course never be checked in.

References