# Documentation about hardcore tools

- update_vcproj.py
  - The expected project file structure
  - Command line options
  - Example wingogi
- References

## update_vcproj.py

The script `update_vcproj.py` reads the sources setup which is generated by the operasetup script and updates the source file entries in a Visual Studio 2005 or 2008 project file according to the source's configuration.

### The expected project file structure

The script can handle Visual Studio 2005 or 2008 project files. The project file is stored as an xml file. The xml file has several sections:

- A `<Configurations>` section which contains all available configurations for the project. The configurations of this section are parsed and if a single file is updated with an individual configuration, a `<FileConfiguration>` section is added for all found configurations.
- A `<Files>` section, which contains all source files. The files are organized in "Filter" entries.

The script expects the project file to have the following structure:

- The `<Files>` node should have a top-level `<Filter>` node with name "`Source Files`". If that filter is not available, the scripts fails with an error message.

- All `<Configurations>` are expected to use `"core/pch.h"` as precompiled header file. I.e. all configurations should set the attributes

  UsePrecompiledHeader | "Use Precompiled Header File" (this corresponds to the compiler command line argument "`/Yu`" or the xml attribute value "`2`").
  PrecompiledHeaderThrough | `"core/pch.h"`
  PrecompiledHeaderFile | should specify in which file the precompiled header file is stored. `wingogi` uses the following value: `"$(IntDir)/wingogi/wingogi.pch"`.

  Any `#include "core/pch.h"` statement is then processed by including the precompiled header file.
- There should be one source-file in the project which generates the precompiled header file. The source-file usually only includes the header file:

      #include "core/pch.h"

  and is configured as

  UsePrecompiledHeader | "Create Precompiled Header File" (this corresponds to the compiler command line argument "`/Yc`" or the xml attribute value "`1`").

  That source-file should receive the option no-jumbo in the corresponding `module.sources` file.

- Optionally the project file may have additional source-files which generate precompiled header files for `"core/pch_jumbo.h"` and `core/pch_system_includes.h`. For each precompiled header file a source-file is needed that includes the header file. The source-file should be configured like

  UsePrecompiledHeader | "Create Precompiled Header File" (this corresponds to the compiler command line argument "`/Yc`" or the xml attribute value "`1`").
  PrecompiledHeaderThrough | `"core/pch_jumbo.h"` respectively `"core/pch_system_includes.h"`
  PrecompiledHeaderFile | should specify in which file the precompiled header file is stored. `wingogi` uses the following value for `"core/pch_jumbo.h"`: `"$(IntDir)/wingogi/wingogi_jumbo.pch"`.

  The corresponding source-file should receive the option no-jumbo in the corresponding `module.sources` file.

The script recognizes source-file entries with "Create Precompiled Header File" option for `"core/pch_jumbo.h"` and `"core/pch_system_includes.h"` and uses the corresponding `PrecompiledHeaderThrough` and `PrecompiledHeaderFile` settings to update the file-configuration for jumbo compile units or source files with option system_includes.

The script updates the structure of the "`Source Files`" filter node in the following way:

- Each sub-directory of the source-root is represented as a `<Filter>` node with the name of the sub-directory. The parent node of a filter is the filter node of the parent directory. The parent node of the top-level directories (like `modules/` or `platforms/`) is the filter with name "`Source Files`".
  E.g. there is a filter with name "`modules`" as a direct child of the filter "`Source Files`" and all sub-directories in `modules/` are represented by children of that node.
  If the filter node of any of the subdirectories is not available, the filter is inserted.

- Each source-file is represented as a `<File>` node with a "`RelativePath`" relative to the location of the project file. The file node is child of the `<Filter>` node which represents the file's directory.
  If the file node is not available, it is created. If there is a file node which does not belong to any file of the Sources Setup, the file node is removed.

- If a precompiled header file is configured for `"core/pch_system_incudes.h"`, then a source-file with option pch and system_includes receives the configuration

  UsePrecompiledHeader | "Use Precompiled Header File" (this corresponds to the compiler command line argument "`/Yu`" or the xml attribute value "`2`").
  PrecompiledHeaderThrough | `"core/pch_system_includes.h"`
  PrecompiledHeaderFile | As configured for the corresponding "Create Precompiled Header File" node.

  If no precompiled header file is configured for `"core/pch_system_incudes.h"`, then a source-file with option pch and system_includes is configured to not use a precompiled header file.

- If a precompiled header file is configured for `"core/pch_jumbo.h"`, then a jumbo-compile-unit with option pch receives the configuration

  UsePrecompiledHeader | "Use Precompiled Header File" (this corresponds to the compiler command line argument "`/Yu`" or the xml attribute value "`2`").
  PrecompiledHeaderThrough | `"core/pch_jumbo.h"`
  PrecompiledHeaderFile | As configured for the corresponding "Create Precompiled Header File" node.

  If no precompiled header file is configured for `"core/pch_jumbo.h"`, then the jumbo-compile-unit is configured to not use a precompiled header file.

Note: Instead of adding a source-file with option "Create Precompiled Header File" for `"core/pch_jumbo.h"` (see above) you can use the command line option `--pch_jumbo`.

### Command line options

Usage:

    update_vcproj.py [options] [project_file]

[project_file]
  should be a Visual Studio 2005 or 2008 project file. If no project file is specified, the file `wingogi.vcproj` is used.

The commandline options are:

--template=TEMPLATE_FILE
  generate the project-file from the specifed template filename. Instead of parsing the project file, updating the xml structure and writing the output, a simple template file can be used. The template file needs to contain only the configuration, and the source-files that are needed to generate the precompiled header files. Using a template speeds up the parsing and helps to silence git when the project file has changed. See also The expected project file structure.
--exclude_module branch/module
--exclude_module=branch/module
  Removes the source files of the specified module from the project file. Usually all sources files of all modules are included in the project file. By using this option some modules can be excluded. E.g. wingogi builds call this script with arguments like:

        --exclude_module platforms/lingogi

--include_module branch/module
--include_module=branch/module
  Includes only the source files of the specified modules in the project file. Usually all sources files of all modules are included in the project file. By using this option all but the specified modules are excluded.
--force_update
  To skip the dependency check. Usually the project file is only parsed and updated if any of the source.* files that are created by operasetup.py are newer than the project file. This saves a lot of time on parsing the project file.

  Note: even if force_update is specified, the project file might not be written, because its content might not have changed.

--jumbo
  To enable compiling with jumbo compile units. All module source files which are included in a jumbo compile unit are kept in the project file, but they are excluded from the build process.

  To remove the excluded files, use the argument `--remove_excluded_files`.

  Note: the jumbo-compile-units are generated by operasetup.py. This script only enables or disables the jumbo compile units. To disable jumbo compilation, don't use the `--jumbo` argument.

--remove_excluded_files
  To remove all files from the project file, that are excluded from the build. By default both the jumbo compile units and the plain files are added to the project file and the files that are not used are marked with the attribute `ExcludedFromBuild`. This allows to use a jumbo compilation and still keep fast access to all source files, but the project file will grow very big and updating it takes much more time. With this option, only the files that are required for the build are added to the project file, i.e. for a jumbo-build only the jumbo compile units are added to the project file and for a plain-build only the plain sources are added to the project file. This keeps the project file small and thus it can also be updated fast.
--keep_excluded_files
  Is the opposite to option `--remove_excluded_files`. Both the jumbo compile units and the plain files are added to the project file and the files that are not used are marked with the attribute `ExcludedFromBuild`. This is the default setting.
--pch_jumbo=FILENAME
  Specifies the pch file which is the precompiled header file that was generated for the `#include "core/pch_jumbo.h"` statement. If this argument is not specified, this script parses the specifed project file for an entry with configuration `UsePrecompiledHeader=1` and `PrecompiledHeaderThrough=core/pch_jumbo.h`, i.e. create a precompiled header file for `"core/pch_jumbo.h"`. The filename is used for the `PrecompiledHeaderFile` attribute in the project file.
--sources_filter=NAME
  add the source files to the filter with the specified name. The default filter name is "`Source Files`". If an empty string is specifed, the source files are added directly to project; eg: `--sources_filter=`.
--no-error_on_update
  Don't exit with an error-code when the project file was updated. The default is to exit with an error code; thus Visual Studio stops compilation and has time to reload the project file before compilation continues.
--quiet
--no-quiet
  Print some debug messages about the progress.

### Example wingogi

The wingogi project has two source-files which are used to generate precompiled header files:

- `platforms/wingogi/pch.cpp`:

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

- `platforms/wingogi/pch_jumbo.cpp`:

      /* ... some copyright header ... */
      #include "core/pch_jumbo.h"

The corresponding `platforms/wingogi/module.sources` file contains entries for both files with option no-jumbo:

    pch.cpp # [no-jumbo]
    pch_jumbo.cpp # [no-jumbo]
    ...

The visual studio project file configures the default precompiled header settings as (i.e. these setting are configured inside the `<Configurations>` node of the project file):

UsePrecompiledHeader | "Use Precompiled Header File" (this corresponds to the compiler command line argument "`/Yu`" or the xml attribute value "`2`").
PrecompiledHeaderThrough | `"core/pch.h"`
PrecompiledHeaderFile | `"$(IntDir)/wingogi/wingogi.pch"`

The precompiled header configuration of the source-file `platforms/wingogi/pch.cpp` (i.e. in the `<FileConfiguration>` node of the `<File>`) is

UsePrecompiledHeader | "Create Precompiled Header File" (this corresponds to the compiler command line argument "`/Yc`" or the xml attribute value "`1`").

Note: the other setting `PrecompiledHeaderFile` and `PrecompiledHeaderThrough` are obtained through the default configuration.

The precompiled header configuration of the source-file `platforms/wingogi/pch_jumbo.cpp` (i.e. in the `<FileConfiguration>` node of the `<File>`) is

UsePrecompiledHeader | "Create Precompiled Header File" (this corresponds to the compiler command line argument "`/Yc`" or the xml attribute value "`1`").
PrecompiledHeaderThrough | `"core/pch_jumbo.h"`
PrecompiledHeaderFile | `"$(IntDir)/wingogi/wingogi_jumbo.pch"`

The wingogi solution file has a "sources" project which calls the `update_vcproj.py` as

    .\modules\hardcore\tools\update_vcproj.py --jumbo \
        --exclude_module=platforms/lingogi \
        --template=platforms\wingogi\build\wingogi_vc2008.vcproj.template platforms\wingogi\build\wingogi_vc2008.vcproj

## References

- [1] MSDN: MSDN Library: Development Tools and Languages: Visual Studio 2008: Visual Studio: Visual C++: Building a C/C++ Program: C/C++ Building Reference: Compiling a C/C++ Program: "Creating Precompiled Header Files" http://msdn.microsoft.com/en-us/library/szfdksca.aspx