Step 3a - Resolve Missing Header Files

When the Imagix 4D source analyzer processes source code, it handles header files the same way that a compiler does. While C and C++ source files are analyzed directly by being explicitly specified in the project settings, header files are analyzed only when #included by a source file.

When the Imagix 4D source analyzer encounters such a #include directive, it searches for the appropriate header file the same way that a compiler does. It checks the local directory and then any additional include directories that have been specified in the project settings. When the source analyzer fails to find the appropriate header file, it generates an error message of the format:

Analyzing c:/dev/project/vers-r1/power.c
   c:/dev/project/vers-r1/assist.h, 24: error - cannot open "drive/understeer.h"

At this point, unlike many compilers, the source analyzer continues with its analysis of the original source file. However, despite the source analyzer's built-in error correction, the failure to locate and analyze the header file can have repercussions. The semantic analysis of the source file's downstream code can result in warnings and errors as a result of missing the class, type and other definitions from the header file.

Modifying the project set-up to correctly specify the include directories so that the missing headers are located often results in more precise project databases.
Resolving the missing header files consists of reviewing the error messages and then modifying the project settings, generally in the following order.

Is the missing header part of the application or the system headers?

Imagix 4D divides the universe of header files between those that are part of your source code, and those, such as stdio.h, that are part of the compiler or operating system environment. Generally, you'll be interested in understanding the contents of your application header files, while you'll less interested in the system header files. So while both sets are required to semantically analyze your code, the default behavior of Imagix 4D is to leave information about the system header files out of the resulting database.

For purposes of organization and efficiency, the include directories for the system header files are typically specified in the .inc compiler configuration file, while the location of your application's own headers are specified as part of the project's specific settings. Headers for third-party libraries might be grouped with either set, depending on how much they are used across projects and, to a lesser extent, how interested you are in their contents.

The first step in resolving missing headers involves reviewing the error messages. These appear in the Analysis Results tab on the main Imagix 4D display. While you are refining this part of your project settings, you might want to set Display > Show File Error Messages in the tab's local menu.

Consider the following Analyzer Results message:

Analyzing c:/dev/project/vers-r1/power.c
   c:/dev/project/vers-r1/assist.h, 24: error - cannot open "drive/understeer.h"

The message indicates that a problem occurred while the source file power.c was being analyzed. Somewhere, directly or indirectly, power.c included assist.h. In turn, assist.h (at line 24) tried to include understeer.h and an error message was generated when understeer.h could not be found.

Depending on the name of the missing header and of the file that contains the #include directive, it may be evident whether the missing file is an application header or a system header. Or you might not be able to determine that yet. Eventually you will need that knowledge to resolve the missing header.

Where does the header file exist in your environment?

If you know whether the missing file is an application header or a system header, you'll know more precisely where to look for it. Otherwise, you'll need to explore more broadly. Either way, you'll need to search the appropriate directories for the missing header file.

Once you find the header, you'll know with more certainty which type of header it is.

However, your search may not be successful. You may not be able to find a header file with the right name. Or if you do find one, it might have the wrong path. For example, from the error message above, you know that the include directive was #include "drive/understeer.h". Therefore, understeer.h needs to reside in a directory named drive. So instances of understeer.h in directories other than drive do not satisfy the #include directive.

When the specified header file can't be found, there are some potential causes to consider. Does your source code compile? In its current location? Did you copy your source code over from another location? Is the header generated on the fly and deleted after the compilation? Do you have all of the system and compiler header files that exist on the machine where the code is compiled? One additional question to consider is whether the header file is actually meant to be included.

Should the header file actually be included?

Sometimes the missing header file is not meant to be included. This can be the case if the #include directive is in a conditional part of the source code.

If you suspect that the missing header should perhaps not be included, you can check this by inspecting the source code where the #include statement occurs.

#include "drive/understeer.h"

In the above example, the reason that understeer.h is missing could be that the project setup failed to include a -DBUILDHYBRID among the preprocessor flags. You'll need to review how your code is compiled and decide whether the issue is in the include directories (-I) or the preprocessor flags (-D) portion of your project settings.

What include directory needs to be specified for the header file to be found?

Normally, the required include directory is the directory location where the header file is located.

However, as explained above, the error message may indicate the #include directive contains a relative path as part of the file name, such as:

#include "drive/understeer.h"

When this occurs, the required include directory is the directory that contains the top of the relative path name. In this example, if the actual location of the header file is c:/dev/project/include/drive/understeer.h then the directory c:/dev/project/include needs to be specified as one of the include directories for the project.

Why isn't the system header file found as a result of the .inc file?

If you've determined that the missing header is a part of your compiler or operating system environment, you'll need to refine the .inc compiler configuration file that you are using with your project. Specifically, you'll need to review the include directories that are specified in the .inc file.

Here's a simple example from the file:

/* ##################### USER-MODIFIED SECTION ##################### */
/* normally, you'll make changes here to reflect your environment    */

/* specify the location of the system header files */
#pragma cmdflag -S/usr/arm/include

The content of the .inc file is processed as C code. The include directories are specified by the #pragma cmdflag -S... lines. Together, the #pragma cmdflag specify that what follows on the line is to be processed as an option by Imagix 4D's source analyzer. The -S option is used to specify system include directories. This distinguishes them from normal (application) include directories specified with the standard -I option.

In this example, only one include directory, /usr/arm/include, is specified. If you're running under Windows, you would need to change this to the appropriate Windows directory, which, depending on your environment, might be something like:

/* specify the location of the system header files */
#pragma cmdflag -Sc:/tools/arm/include

Adding an additional include directory is done by inserting a new line into the .inc file:

/* specify the location of the system header files */
#pragma cmdflag -Sc:/tools/arm/include
#pragma cmdflag -Sc:/tools/thirdparty/include

When multiple include directories are listed, they searched in the order that they appear in the file.

Why isn't the application header file found as a result of the project settings?

If you've determined that the missing header is a part of your application code, you'll need to refine your project settings in order to cause the header file to be found. How you do this will depend on the approach you're using for loading in your code.

Dialog Based Approach - Include directories are specified on the Include Dirs tab of the Project > Data Sources dialog. This is done in two parts. The top half of the tab specifies a root include directory. As long as the Search subdirectories for header files checkbox is checked, all of the directories underneath the root directory are also treated as include directories. Internally, Imagix 4D generates a -I option for each of these directories. At the bottom of the tab, specific additional include directories can be added by explicitly specifying -I and -S options in the entry field.

In general, specifying include directories is a balancing act using these two controls. Specifying a root directory in the top half that is too low in the directory hierarchy leaves too many include directories to be individually specified in the bottom half of the tab. Specifying a root directory in the top half that is too high in the directory hierarchy results in meaningless or even inappropriate directories being specified as include directories. Too many meaningless directories slows down the source analyzer. Inappropriate directories can result in a wrong header file being included due to spurious file name match.

With the identified missing include directory in mind, review the Include Dirs settings along with the directory structure of your environment, and make the appropriate changes. Typically this will be to set the root directory to a point higher in the directory hierarchy or to add an -Idir option to the entry field at the bottom of the tab.

Extract from Makelog Approach - Include directory settings are generated from -I flags in the logfile, according to the makelog processing rules that you have set. If a required include directory is missing, first select the Extract from Makelog data source on the Project > Data Sources dialog. This will be the first data source listed on the left of the dialog. Review the settings you have made in the Processing Rules tab of the dialog.

If you're confident that those are correct, you can manually add the required include directory option. Switch to the Makelog tab, and enter the required -Idir into the Options entry field. Then click the Process Makelog button. The -Idir option that you entered will be propogated to all of the individual Dialog Based (C/C++) data sources that are created.

Microsoft Visual Studio-Based Approach - Include directory settings are generated automatically from Visual Studio's .sln and .vcproj project files.

First make sure that you have the Visual Studio settings and the Configuration correctly set on the Project or Solution tab of the Project > Data Sources dialog. If that doesn't resolve the missing header file, add a -Idir option into the tab's Options entry field so that the required include directory is explicitly added to those extracted from the Visual Studio project files.