Creating Optimal Configuration Files

VisualAge C++ Professional Version 4 for AIX introduces an entirely different paradigm for C++ application development:  An incremental build environment promising increased productivity through decreased build times.  As a new user, when you created a new project you naturally listed only the .C and .cpp source files because they are the only files that you passed to the xlC command.  As you have probably discovered, such projects are the worst case scenario for the incremental build environment, resulting in builds that take several times longer than what you experienced with the previous compilers. This document describes a process which will allow you to create projects that will provide the best possible initial and incremental build times.

The information in this document is based on the actual experiences of our VisualAge C++ Consulting Services team while on customer engagements. The VisualAge C++ Consulting Services team offers an educational workshop for developers moving to VisualAge C++ Professional Version 4, as well as other mentoring, planning, and migration services.

The sample application shown in the screen shots of this document is an older version of Jikes, IBM's Open Source Java compiler.

This document assumes that you have already created a configuration file that lists all of the .C and .cpp source files  in your project, either manually or using the Project SmartGuide, and have already determined the correct options for your project using the information in the Compile Options from Earlier AIX C or C++ Compilers and Link Options from Earlier AIX C or C++ Compilers sections of the documentation.

The next figure shows the Source page of the Configuration section of the IDE after having created the configuration file for Jikes and adding the options equivalent to those listed in its makefile.

Instead of starting with all of the source files in the project, start with just one source file.  If you have already created a configuration file containing all of the source files in your project, simply comment out all but the first source file using the /* */ or // style comments that the configuration file syntax allows.

Comment out the target directive(s) in the configuration file using // style comments in order to prevent the link step of the build from occurring and resulting in many unresolved symbol messages because not all of the source files are included.  Ensure that you do not comment out the opening brace, {,  of the target block.

Add three empty source groups to the configuration file named MACRO_SOURCES, PRIMARY_SOURCES, and SYSTEM_INCLUDES.

The PRIMARY_SOURCES source group will contain the header files of your project that do not define macros that are used in other source files in your project.  A primary source is any C++ source file that is listed in a source directive in the configuration file.  Once an included source is listed in the configuration file, any #include statements which reference it are not processed.  This results in improved build times as the source is then only processed once per build.  Also, if a source file is changed, the time to rebuild the project is improved if all of its included sources are listed in the configuration file because only the source file needs to be reprocessed, not the source file plus all of its included sources.  Therefore in order to get the best build times one should list as many included sources as possible in the configuration file.  The act of making an included source a primary source is called promotion.

The MACRO_SOURCES source group will contain the header files of your project that define macros which are used in other source files in your project.  These source files require that the option macros(global) be applied to them in order that the macros defined in them are visible to all of the source files in your project.  By default, a macro defined in a primary source file is visible only within that file.  A primary source that has the option macros(global) applied to it is known as a macro source.

The SYSTEM_INCLUDES source group will contain the header files of your project that come with the compiler and with the operating system. You will assume that all of these source files are macro sources when optimizing the configuration file.

Add source statements for these three source groups inside of the target block as shown in the following screen shot.

Now do a build of the project.  Turn to the Source Files page of the Project section of the IDE.  In the upper left pane, which contains a Source Files view of the project, change the filter from the My Objects filter to the Show All filter as illustrated in the following screen shot.  This results in all of the header files that are included with the compiler and with the operating system appearing in this view.

Notice in the Source Files view that there is one file listed with the  glyph to its left.  This is the single primary source file that is listed in the configuration file at this point.

Note that the configuration file is listed in this view with the  glyph to its left.  The source files in the view with the  glyph to their left are included sources, that is files that have been included in the project via #include statements. To optimize the project and achieve the best possible build times, you need to have as few of these included source files as possible. To achieve this you will promote these files by listing as many of them as possible in the configuration file.

Select all of the compiler include files from the /usr/vacpp/include directory using Ctrl+LMB.

Use the RMB to get the popup menu shown in the following screen shot and select the Add Source to Source Directive item.

The Add to Source dialog appears. Click on the  which appears at the top of the dialog and you will see one choice for each source group in the configuration file.  Choose to add these included sources to the SYSTEM_INCLUDES group.  Ensure that the Use Relative Path option is not selected.  This will cause the full path of the included sources to be entered in the configuration file.  Select the Apply button.

The included sources in the dialog have now been added to the configuration file.  If you were to look at the configuration file at this point you would see that the files have been added to the SYSTEM_INCLUDES source group.
 
group MACRO_SOURCES = ""
group PRIMARY_SOURCES = ""
group SYSTEM_INCLUDES = "", "/usr/vacpp/include/assert.h",
"/usr/vacpp/include/cstddef", "/usr/vacpp/include/exception",
"/usr/vacpp/include/iostream.h", "/usr/vacpp/include/irtllock.h",
"/usr/vacpp/include/locale.h", "/usr/vacpp/include/math.h",
"/usr/vacpp/include/math_aix.h", "/usr/vacpp/include/new",
"/usr/vacpp/include/new.h", "/usr/vacpp/include/stddef.h",
"/usr/vacpp/include/stdio.h", "/usr/vacpp/include/stdlib.h",
"/usr/vacpp/include/string.h", "/usr/vacpp/include/sys/signal.h",
"/usr/vacpp/include/sys/time.h", "/usr/vacpp/include/sys/types.h",
"/usr/vacpp/include/sys/wait.h", "/usr/vacpp/include/time.h",
"/usr/vacpp/include/xstddef", "/usr/vacpp/include/yvals.h"
option gen(inlinepointerglue, "yes"), define("UNIX"), define("BIGENDIAN"),
       define("cerr", "cout"), define("TYPE_bool"), report("disable", "CPPC1104"),
       report("disable", "CPPC1105")
{
//   target "jikes"
   {
      source type("cpp") PRIMARY_SOURCES
      option macros(global)
      {
         source type("cpp") SYSTEM_INCLUDES, MACRO_SOURCES
      }
      source "ast.cpp"
/*
      source "body.cpp"
      source "bytecode.cpp"
      source "case.cpp"
      source "code.cpp"
      source "config.cpp"
      source "control.cpp"
      source "decl.cpp"
      source "definite.cpp"
      source "depend.cpp"
      source "diagnose.cpp"
      source "double.cpp"
      source "dump.cpp"
      source "error.cpp"
      source "expr.cpp"
      source "getclass.cpp"
      source "incrmnt.cpp"
      source "init.cpp"
      source "javaact.cpp"
      source "jikes.cpp"
      source "lcase.cpp"
      source "long.cpp"
      source "lookup.cpp"
      source "lpginput.cpp"
      source "modifier.cpp"
      source "op.cpp"
      source "option.cpp"
      source "parser.cpp"
      source "scanner.cpp"
      source "set.cpp"
      source "stream.cpp"
      source "symbol.cpp"
      source "system.cpp"
      source "unzip.cpp"
      source "zip.cpp"
*/
   }
}

Do a build and ensure that that there are no included compiler source files from the /usr/vacpp/include directory remaining.

Now, select all of the operating system include files from the /usr/include directory using Ctrl+LMB.

Use the RMB to get the popup menu shown in the following screen shot and select the Add Source to Source Directive item.

The Add to Source dialog appears. Click on the  which appears at the top of the dialog and you will see one choice for each source group in the configuration file.  Again, choose to add these included sources to the SYSTEM_INCLUDES group.  Ensure that the Use Relative Path option is not selected.  This will cause the full path of the included sources to be entered in the configuration file.  Select the Apply button.

The included sources in the dialog have now been added to the configuration file.  If you were to look at the configuration file at this point you would see that the files have been added to the SYSTEM_INCLUDES source group.
 
group MACRO_SOURCES = ""

group PRIMARY_SOURCES = ""

group SYSTEM_INCLUDES = "", "/usr/vacpp/include/assert.h", 
"/usr/vacpp/include/cstddef", "/usr/vacpp/include/exception", 
"/usr/vacpp/include/iostream.h", "/usr/vacpp/include/irtllock.h", 
"/usr/vacpp/include/locale.h", "/usr/vacpp/include/math.h", 
"/usr/vacpp/include/math_aix.h", "/usr/vacpp/include/new", 
"/usr/vacpp/include/new.h", "/usr/vacpp/include/stddef.h", 
"/usr/vacpp/include/stdio.h", "/usr/vacpp/include/stdlib.h", 
"/usr/vacpp/include/string.h", "/usr/vacpp/include/sys/signal.h", 
"/usr/vacpp/include/sys/time.h", "/usr/vacpp/include/sys/types.h", 
"/usr/vacpp/include/sys/wait.h", "/usr/vacpp/include/time.h", 
"/usr/vacpp/include/xstddef", "/usr/vacpp/include/yvals.h", 
"/usr/include/ctype.h", "/usr/include/float.h", "/usr/include/limits.h", 
"/usr/include/locale.h", "/usr/include/math.h", "/usr/include/memory.h", 
"/usr/include/standards.h", "/usr/include/stddef.h", "/usr/include/stdio.h", 
"/usr/include/stdlib.h", "/usr/include/string.h", "/usr/include/sys/context.h", 
"/usr/include/sys/lc_core.h", "/usr/include/sys/limits.h", 
"/usr/include/sys/localedef.h", "/usr/include/sys/localedef31.h", 
"/usr/include/sys/m_param.h", "/usr/include/sys/m_types.h", 
"/usr/include/sys/mode.h", "/usr/include/sys/mstsave.h", 
"/usr/include/sys/resource.h", "/usr/include/sys/signal.h", 
"/usr/include/sys/stat.h", "/usr/include/sys/time.h", "/usr/include/sys/types.h", 
"/usr/include/sys/wait.h", "/usr/include/time.h", "/usr/include/va_list.h", 
"/usr/include/wchar.h"

option gen(inlinepointerglue, "yes"), define("UNIX"), define("BIGENDIAN"),
       define("cerr", "cout"), define("TYPE_bool"), report("disable", "CPPC1104"),
       report("disable", "CPPC1105")
{
//   target "jikes"
   {

      source type("cpp") PRIMARY_SOURCES
      option macros(global)
      {
         source type("cpp") SYSTEM_INCLUDES, MACRO_SOURCES
      }

      source "ast.cpp"
/*
      source "body.cpp"
      source "bytecode.cpp"
      source "case.cpp"
      source "code.cpp"
      source "config.cpp"
      source "control.cpp"
      source "decl.cpp"
      source "definite.cpp"
      source "depend.cpp"
      source "diagnose.cpp"
      source "double.cpp"
      source "dump.cpp"
      source "error.cpp"
      source "expr.cpp"
      source "getclass.cpp"
      source "incrmnt.cpp"
      source "init.cpp"
      source "javaact.cpp"
      source "jikes.cpp"
      source "lcase.cpp"
      source "long.cpp"
      source "lookup.cpp"
      source "lpginput.cpp"
      source "modifier.cpp"
      source "op.cpp"
      source "option.cpp"
      source "parser.cpp"
      source "scanner.cpp"
      source "set.cpp"
      source "stream.cpp"
      source "symbol.cpp"
      source "system.cpp"
      source "unzip.cpp"
      source "zip.cpp"
*/
   }
}

Do a build and ensure that that there are no included operating system source files from the /usr/include directory remaining.

Select  all of the remaining included source files using Ctrl+RMB. Use the RMB to get the popup menu  and select the Add Source to Source Directive item.  Add these included source files to the PRIMARY_SOURCES source group.  You should ensure that the Use Relative Path option is selected when adding these source files. Do a build and ensure that there are no included sources remaining.

In same cases when included source files are added to the PRIMARY_SOURCES source group, the next build will end with errors.

This is usually because an included source added to the PRIMARY_SOURCES source group contains macro definitions that need to be visible to other source files in the project.  The source needs to have the option macros(global) applied to it and become a macro source.  In the above example, an error results because the macro HEADERS is not defined.  You can use the Search page of the Project section to find which source contains the definition of the macro.

In this example, the definition of the macro HEADERS is in the source parser.h.  It needs to be moved from the PRIMARY_SOURCES source group to the MACRO_SOURCES source group.  This can be done in the IDE from the Source and Groups view of the Configuration.  Select "parser.h" from the view and use the RMB to get the popup menu shown in the following screen shot.

Select the Move to Source menu item and the Move to Source dialog appears.  Select the MACRO_SOURCES source group and press the Apply button to move the source from the PRIMARY_SOURCES source group to the MACRO_SOURCES source group.

Once you have a successful build go back and uncomment another one of the .cpp source files from your project and repeat the steps above until you have a successful build with no included sources in the Source Files view.

Once all of the .cpp files from your project have been included in the build go back and remove the comment from the target directive in the configuration file.  Do a build.  At this point you will need to fix any link errors that occur.  You may need to add libraries as sources to the configuration file or you may have forgotten to uncomment some of the source files for your target.


Please send feedback about this document to Dwayne Moore (dwayne@ca.ibm.com).