Background​

When a source file ( .prg or .arc) is compiled, then an intermediate file ( .obj or .res ) is created that is finally linked to an executable ( .exe ) or library ( .dll ). The Xbase++ compilers xpp.exe and arc.exe create the intermediates next to their source files. This behavior is often not desired because it quickly clutters the directory with the source files. Furthermore, an object file and consequently also the target ultimately depend on whether a debug or release target is to be created and on the compiler settings specified for the target.

OBJ_DIR​

In the Xbase++ project file ( .xpj ), a directory in which the intermediate files are created can be specified with the define OBJ_DIR. This way, the directory with the source files remains clear. However, the OBJ_DIR directory is the same for both debug and release builds. If you switch between a Debug and a Release build, it is therefore essential to delete and rebuild all intermediates to avoid mixing of debug and release objects. This is crucial because both versions may contain different code, for example, code sections included/excluded using
Code:
#ifdef DEBUG
.

INTERMEDIATE_DEBUG and INTERMEDIATE_RELEASE​

To avoid mixing of debug and release objects, the definitions INTERMEDIATE_DEBUG and INTERMEDIATE_RELEASE were introduced in the Xbase++ project file. By convention, the values of these defines should be ".debug" and ".release" and both definitions must be present to take effect.
Code:
[PROJECT]
    ...

[PROJECT.XPJ]
    mdidemo.exe

[mdidemo.exe]
    ...
    INTERMEDIATE_DEBUG   = .debug
    INTERMEDIATE_RELEASE = .release
    ...
If these definitions are specified, Pbuild creates a sub-directory with the name of the target in the specified ".debug" or ".release" directory when the target is built. The target name is preceded by a dot ("."). The intermediates are then created in this target-specific sub-directory. In addition, Pbuild creates the target EXE or DLL in this sub-directory.
Example for the INTERMEDIATE_DEBUG directory of the MDIDMO application:

Anmerkung 2020-08-05 152351.png



Benefits​

Easily switch between Debug and Release builds​

If you want to switch between a Debug and Release build, it is no longer necessary to delete the intermediates. If the project is rebuilt after such a switch, only those sources are compiled whose intermediates are outdated. Also, because the target binary is stored in the target-specific subdirectory, linking the EXE or DLL is no longer necessary after such a switch when the source files are up-to-date. Instead, the ProjectBuilder simply copies the target binary from its intermediate directory into the target directory.

Target-specific defines are safe​

// $TW: Is this a good example? I thought we don't want to promote this scenario!
Since it is possible to use the same source file in several targets which may use different define values for COMPILE_FLAGS, for example, each target build possibly produces a different intermediate ( .obj ) file. Consider the following example in which target-specific source code is compiled into the target using preprocessor defines.
Code:
[PROJECT]
    ...
[PROJECT.XPJ]
    app-customer-a.exe
    app-customer-b.exe
[app-customer-a.exe]
    ...
    INTERMEDIATE_DEBUG   = .debug
    INTERMEDIATE_RELEASE = .release
    COMPILE_FLAGS = /q /dMODULE_CALENDER /dMODULE_MAIL
    ...
    // The menu will have an entry for calender and mailing
    main-menu.prg
[app-customer-b.exe]
    ...
    INTERMEDIATE_DEBUG   = .debug
    INTERMEDIATE_RELEASE = .release
    COMPILE_FLAGS = /q /dMODULE_CKALENDER
    ...
    // The menu will have an entry for calender only.
    main-menu.prg
Because the intermediates are created in target-specific sub-directories, it is impossible that intermediates are linked to a target which were originally built for the other target.
Note: Although the last example demonstrates a viable scenario, using the same .prg in more than one target is not recommended. Better compile such commonly used functions and classes into a separate dll which can then be linked to as required.

Summary​

The intermediates of a target depend on whether they were created with or without debug information. However, they also depend on which definitions were passed to the compiler. Other than OBJ_DIR, using the defines INTERMEDIATE_DEBUG and INTERMEDIATE_RELEASE in the project file guarantees that the correct intermediates are linked to the target.

References​