Software development system that presents a logical view of project components, facilitates their selection, and signals missing links prior to compilation6487713
Abstract
A software development system develops a product from core library of source code elements, the core library being categorized into components having one or more features. A configurator develops configuration state data based on a designated platform type and the source code elements. A graphical user interface displays a visual and logical representation of the product according to the configuration state data, includine visual indications of any unresolved dependencies. A product make routine then generates the product from the source code elements according to the configuration state data.
Claims
What is claimed is:
1. A software development system for developing a finished product comprising:
a source code library containing source code elements that include interfaces and dependencies, said interfaces and dependencies including names and class designations and other information, said source code library being organized into objects;
a configurator for developing configuration state data defining the configuration of the finished product based on product configuration data, data scanned from the elements of said source code, including the names and classes and other information relating to dependencies and interfaces, and data about objects and their appropriate use;
a graphical user interface for presenting a visual, logical representation of the product organized in part by class and object, and displaying the configuration data in an expandible tree, the elements of the tree including source code elements, their interfaces and their dependencies, options, indications of any missing elements or linkages graphically, and indications of graphically selected and deselected objects, said graphical user interface accepting commands to select and deselect objects and to adjust options, the effects of the commands being recorded in said configuration state data and in said product configuration data; and
a product make routine for generating the finished product from said source code elements under the guidance of said configuration state data.
2. A software development system in accordance with claim 1 which further includes, as part of the data associated with at least some dependencies, object specification data, wherein the object specification data causes the corresponding dependency to be linked to an interface in a source code element included with the specified object in preference to other interfaces having identical identifiers.
3. A software development system in accordance with claim 1 which includes source code elements which must run in a RAM free environment, wherein the product make routine, when modifying such source code elements at call or jump dependencies, sets up a dummy return stack that does a register branch following a return, and at the point of a call or jump, generates and inserts code that loads the immediate address into said register and then produces a jump to the specified interface.
4. A software development system in accordance with claim 1 wherein the configurator, when encountering a dependency that depends upon the presence of an unselected object with a corresponding interface, automatically selects said object for inclusion in the finished product.
5. A software development system in accordance with claim 1 wherein said other information for at least some interfaces and dependencies includes version numbers, and wherein said graphical user interface gives visual indication of any version incompatibiliy.
6. A software development system in accordance with claim 1 wherein said other information for at least some interfaces may optionally include an intercept designation, and wherein said configurator associates a dependency with an interface having an intercept designation in preference over other identically named interfaces.
7. A software development system in accordance with claim 1 wherein said product make routine, when confronted with at least some dependencies for which there is no corresponding interface due to the non-selection of an object, and where this is not an error condition, modifies the source code element by removing the dependency from the source code element.
8. A software development system in accordance with claim 1 wherein said configurator may cause the graphical user interface to give a visual error indication with respect to at least some dependencies for which there is no interface.
9. A software development system in accordance with claim 1 wherein said product make routine converts class and name references for at least some dependencies into name and library address references as it modifies the source code elements.
10. A software development system in accordance with claim 1 wherein at least some of said source code elements contain list elements, and wherein said product make routine modifies the source code elements by bringing those list elements together and inserts them into the final product at a designated point.
11. A software development system in accordance with claim 1 wherein the data about the appropriate use of objects, in at least some cases, includes an indication that the selection of one object is triggered by the selection of another object; and wherein said configurator, when encountering such data, selects said another object whenever said one object is also selected.
Description
CROSS REFERENCE TO RELATED APPLICATION
Not applicable.
STATEMENT REGARDING FEDERALLY SPONSORED RESEARCH OR DEVELOPMENT
Not applicable.
BACKGROUND OF THE INVENTION
1. Field of the Invention/Overview
The present invention relates generally to methods and systems for developing and integrating a software product by customizing and combining core components and integrating them to form the software product. More particularly and illustratively, the present invention relates to a software system for maintaining and re-using the core components of a Basic Input/Output System (BIOS) for a personal computer (PC) that simplifies BIOS deployment and that provides the architecture for an extensible yet maintainable core which enables rapid product development, enhancement, and modification.
2. Background and State of the Art
A BIOS product is a piece of software code that executes when a PC is started up or "booted" and that is later called upon to provide various services while the PC is running. A development system for BIOS products must support all the peripherals that may be installed on any type of PC from a low-end basic PC up to a state-of-the-art, highly customized, high-end server or portable product. The various aspects of building a BIOS are described below to illustrate the capabilities that a software system for maintaining and using a library of core BIOS software components should provide.
A customer wishing to build a BIOS for a particular machine selects core BIOS software components to support the peripherals installed on that machine from a library of such components. Each software component may include one or more features and may be configured by adding or removing code for features from the set of available features and by specifying the values of optional parameters ("options") for this code. The customer may wish to add special BIOS code for peripherals custom manufactured by the customer and not available from the BIOS vendor.
Configurable features are implemented as separate code in the core BIOS component library that have external references and definitions in the code addressing other code components by name and by directory/subdirectory or by library name so the code for each feature can be linked into the final product only when it is properly configured and addressed. The present state of the art is to replace the code for a called, named, and addressed optional feature that is not selected with a stub routine that merely returns to its caller. Another possibility is to reference the optional feature indirectly through a pointer that can be set to null if the feature is removed; however, this requires each caller to verify that the pointer is valid. Ideally, the code to call an optional feature should be removed from the code when the component is built to realize a savings in both execution time and memory size occupied by the program.
The present state of the art defines the optional parameters of a software component (hereinafter called "options") as manifest constants, e.g., "BUFFER_SIZE EQU 256." The name of a manifest constant (BUFFER_SIZE) and the value it represents (256) are associated when the manifest constant is defined. Each reference to the name of a manifest constant, such as the length of an array or the value of a variable, for example, is replaced with the associated constant value when the source code is compiled. This allows each option to be given a descriptive name and makes it possible to change the option value in all the places it is referenced by changing the one definition. Options such as these are typically set or adjusted by defining or modifying an "include" file by hand. The "include" file is then incorporated by reference into the other source code files. It is easy to miss a file containing a reference to an option name, or to confuse options having the same names in different system components.
The producers and marketers of the core BIOS component library need to respond rapidly to new devices that become available in the marketplace. One tried and true method is to make a copy of the code for a similar existing device and to modify it only where necessary to support the new device. The original code may have supported several configurable features that are now also available for the new device. Copying the code from another core component gives rise to two components in the same library with not only the same features, but also identical external names to reference them. This ambiguity can cause further confusion at compile and link time.
The customer may sell machines that incorporate either an old device or a new device. The customer may therefore create a BIOS that incorporates both an old software component supporting the old device and a new component, generated by modifying the old component and having identical external names, supporting the new device. The BIOS would contain additional code to intercept the calls to each procedure in the old and new components. The customer then would add decision code for each intercepted procedure that decides whether the procedure in the new component or the old component should be called. This gives rise to a BIOS containing two components having identical external names and decision code for each intercepted call that must call one of the two procedures with identical names without being intercepted. Both software components would have to be compiled and linked separately so that the identical external names in each component would not conflict. They would also have to be linked together with the decision code that calls them.
Suppose that both the old component and the new component, generated by modifying the old component and having identical external names, had an initialization feature named INIT. The additional decision code mentioned above must be called in place of the INIT procedure so it can determine whether the INIT procedure in the old or new component should be called. Present art would require that each call to INIT go indirectly through a pointer table so that the pointer could be changed to intercept, or hook, each such call. All calls to INIT throughout the BIOS would be intercepted, or hooked, in this manner. The ability to intercept such calls is also important for debugging purposes.
The producers of the core BIOS component library respond to new devices that become available in the marketplace by rapidly releasing new versions of the library. In the process of maintaining and enhancing the library, they may modify some interfaces to add functionality or to fix bugs. The customer with an existing BIOS will wish to incorporate the new functionality and bug fixes as well as the newly supported devices. The customer must verify that calls to existing interfaces which have changed are still compatible and quickly identify those interfaces that are now incompatible and that must be changed. Present art validates interfaces by matching the number of parameters, the type of each parameter, and the range of values.
The BIOS code for a particular device typically consists of initialization code that executes when the PC is started up and support code that provides services when called upon. There may be no references in the support code to the initialization code, or vice versa, that would cause both pieces of code to be included in the BIOS build; yet the support code clearly depends upon the initialization code. Present art requires manual intervention to insure that both pieces of code are included in the build.
The conventional way of finally testing source code modules for consistency is to compile and/or assemble the separate source code files, identifying and correcting all errors and repeating this process; link the object code files, identifying and correcting all errors and repeating both of these processes; and finally, combine the separately linked system elements into an inter-linked image, identifying and correcting all errors and repeating all three of these processes repeatedly and recursively until no more errors are found. Even then, improper linkages may result from identical names being used to mean different things in different sets of source files, from selection of the wrong set of two very similar sets of source files, or from version incompatibilities that compilers and assemblers cannot detect. All of these problems, in combination, make software system development and integration more time consuming than ideally it should be.
Accordingly, primary objects of the present invention are the achievement of a software development system that can identify, and assist one to correct, the above types of errors prior to any assembly, compilation, or linking; that permits one to view and select components, features, and variations simply and without regard to where the corresponding source code is stored; that permits one to specify globally that the product is to be a "server" or a "portable" and to achieve thereby entirely different system configurations; and that addresses the problems mentioned above of selecting the proper one of several component variations, of adjusting and controlling the values and scope of options, and of automating the selection of needed system components in accordance with source code dependencies.
BRIEF SUMMARY OF THE INVENTION
Briefly described, and in accordance with these and other objects and advantages, the present invention is embodied in a software development system that manages a source code library that is stored as source code files placed into a directory hierarchy. Different subdirectories may correspond to different software "Components." Each "component" in the directory hierarchy, whether it be a true software component or a "hardware component," meaning software supporting the needs of a particular hardware device, may be defined further by one or more "features" stored in lower level subdirectories so that one or more features may comprise each component and there may also be "sub-features" stored in yet lower level subdirectories. One or more source code files may reside in each feature subdirectory. Each component and each feature is further described by an information file that is placed into its corresponding subdirectory defining what type of platform (server, notebook, etc.) a feature is intended for, what class it is assigned to, etc.
In the preferred embodiment of the invention, the source code files call upon special macro routines to define each external procedure and to classify it. as public (callable between components) or private (callable by parents or siblings within one component only). Each call to such an external procedure is also made with a special macro routine, and each source file that contains such a call declares the procedure is being referenced publicly or privately with a call to another special macro routine. These special macro routines may pass, among other things, program revision numberd and program class designations. Special macros are also used to define public and private "include" files and to declare references to them. In addition, special macros may be used to create a list, to define the entries that are to form such a list and that are drawn from separate source code components, and to specify sort criteria for the list entries.
The component information files and feature information files are scanned, and their contents are stored within a special database. These files may relate a component or feature to a particular class and may specify which types of platforms (desktop, portable, server, etc.) for which a component is appropriate or essential. The source code files assigned to each feature are also scanned, and the parameters associated with the special macros such as classes and version numbers are also entered into the database along with each feature's directory address. This database then holds a complete description of the source code library, including the available components, the features each component provides, the way in which features are classed together so that they later may be linked together, and the rules for selecting components and features for inclusion into a particular platform type (portable, server, etc.). The information for each feature includes the source files that must be compiled to provide each feature, the external interfaces to each feature, the dependencies of each feature upon externally-defined subroutines and options, and the class assignments that prevent identical names within different classes from being confused, and cross-linked.
Once a system designer using the present invention has specified a type of platform, the minimum information necessary to specify a configuration for such a platform is extracted from the database, including all components and all features that the specified type of platform requires. This platform specification identifies a preliminary set of source code files that must be compiled and linked to provide the desired system configuration. There is more than enough information from the parameters of the macros of the present invention to associate each procedure call and option with its proper definition.
The present invention acts in the manner of a linker in that it associates each procedure call with its definition and identifies all missing procedures; however, this test "linking" process takes place long before compilation or assembly and linking and makes use of all the information available from the parameters of all the special macros found within the library. This allows the present invention to associate a procedure call with its definition using criteria other than and in addition to just the matching of procedure names and argument counts, and to identify and signal any procedure calls that are using an incompatible interface, such as incompatible versions of programs, as well as differentiating between procedure calls by class designation.
The present invention quickly identifies problems and errors within the current configuration before compilation or assembly and provides a visual interface through which the designer can quickly locate and fix problems by selecting and editing source code files. The same visual interface also allows the designer to add or remove components and features with the click of a mouse button and to add or override source file selections to adjust the configuration as needed.
Once the designer has selected a valid configuration, he or she may direct the present invention to build the configured product. The present invention then compiles or assembles only those source files specified by the configuration data, and links each feature separately to resolve the private external references within the component, converting class designations into specific addresses to resolve ambiguities in public external references, and thereby produces a linked executable file for each component. Finally, a special product component linker is called upon as a second stage linker that can link the separate component executable files together into the final integrated product. Each public procedure call is fixed up with the address of the public procedure that it references. Lists defined by the list macros of the present invention are gathered, sorted and are stored in the code segment where they were defined.
The product component linker is controlled and directed by data associated with the macros and, in the preferred embodiment, passed to the component linker in special code segments which are read and then discarded by the component linker. The resolution of the various options and the linkages between procedure calls and procedure entry points are also controlled in the preferred embodiment by automatically generated, special "include" files which pass information into each source code file to enable each macro to redefine, redirect, or even omit entirely any given procedure call statement, to control the scope of each option, and to permit the designer, through the visual interface, to adjust option values. Program calls made in a RAM-less environment may also be achieved through macros that automatically use a register for return address storage and that automatically provide, in ROM code, dummy stacks and register controlled return jumps to intercept procedure "return" instructions.
Other objects, features, and advantages of the present invention are apparent in the drawings and in the detailed description of the preferred embodiment that follows. The features of novelty that characterize the invention are pointed out with particularity in the claims annexed to and forming a part of this specification.
BRIEF DESCRIPTION OF THE DRAWINGS
FIG. 1 presents an overview block diagram of a program development system 100 designed in accordance with the teachings of the present invention, emphasizing the relationships between the various software elements;
FIG. 2 presents an overview summary of the visual user interface system, listing user executable functions and also listing display functions;
FIG. 3 is a block diagram showing the routine that executes user-initiated commands;
FIG. 4 is a block diagram of the database update routine;
FIG. 5A is a flow diagram illustrating the process of modifying a file, updating the database, determining a revised product configuration, and displaying the newly-revised configuration to the user or system designer;
FIG. 5B is a flow diagram illustrating the process of creating a final product, including scanning all files, updating the database, revising the configuration (if necessary), displaying any configuration revisions to the system designer, and building the finished product;
FIG. 6 is a block diagram of the database access routines;
FIG. 7 is a block diagram of the configurator routine;
FIG. 8 is a flow diagram illustrating an overview of the product make procedure;
FIG. 9A is a flow diagram of the build prepare routine which creates the "feature.inc" file for each feature;
FIG. 9B is a flow diagram of the build prepare routine which creates the component makefiles and which calls upon the routine in FIG. 9A to create the "feature.inc" files;
FIG. 10 is a flow diagram of the steps carried out by the make utility when executing the product and component makefiles, causing source code selection, modification, compilation, assembly, linking, and final component linking by the product component linker;
FIG. 11 is a flow diagram illustrating an overview of the program development system 100, emphasizing the data flow aspects of the invention;
FIG. 12 illustrates an outline of the contents of the component source code library (1200 in FIG. 11);
FIG. 13 illustrates the contents of a typical IBM PC compatible assembly language source code file 1300 occupying the component source code library 1200 shown in FIG. 11;
FIG. 14 illustrates the contents of a typical component information file "compnent.inf" 1400 occupying the component source code library 1200 shown in FIG. 11;
FIG. 15 illustrates an example of what may be placed in component information files;
FIG. 16 illustrates the contents of a typical feature information file "feature.inf" 1600 occupying the component source code library 1200 shown in FIG. 11;
FIG. 17 illustrates an example of what may be placed into feature information files;
FIG. 18 illustrates an outline of the contents of the component database 1800 shown in FIG. 11;
FIG. 19 illustrates an outline of the contents of the configuration state data 1900 shown in FIG. 11;
FIG. 20 illustrates an outline of the portion of data shown in FIG. 19 that is selected and fed into the product make routine 900 shown in FIGS. 8 and 34 to govern the building of the finished product;
FIG. 21 illustrates an exemplary set of product configuration commands contained in the product configuration data file "platform.cfg" 2100 shown in FIG. 11;
FIG. 22 illustrates an outline of what may be placed into this "platform.cfg" file;
FIG. 23 illustrates the contents of an exemplary feature include file "feature.inc" 2300 (FIG. 11), these contents being generated automatically by the product make routine 900 (FIG. 11) and more particularly generated by the build feature include file routine 950 (FIGS. 9A and 35);
FIG. 24 illustrates the contents of an exemplary component make file 2400 (FIG. 11) generated automatically by the product make routine 800 (FIGS. 8 and 34) and more particularly generated by the component build prepare routine 900 (FIGS. 9B and 34);
FIG. 25 illustrates the contents of an exemplary product make file 2500 (FIG. 11) generated automatically by the product make routine 800 (FIGS. 8 and 34);
FIG. 26 is a block diagram of the database update routine 400, also shown in FIG. 4;
FIG. 27 is a block diagram revealing the details of the feature and component file scan routine 2700 shown in FIG. 26 (called by steps in FIGS. 4, 11, and 26);
FIG. 28 is a block diagram of the configurator procedure 2800 shown in FIG. 11, also shown in FIG. 7;
FIG. 29 is a block diagram of the initial activation routine 2900 portion of the configurator procedure 2800 (FIG. 28);
FIG. 30 is a block diagram of the product configure routine 3000 portion of the configurator procedure 2800 (FIG. 28);
FIG. 31 is a block diagram of the resolve external references routine 3100 within the product configure routine 3000 (FIG. 30) of the configurator procedure 2800 (FIG. 28);
FIG. 32 illustrates the internal structuring of the RAM-based product configuration data 1900 (FIG. 11), also shown in FIG. 19);
FIG. 33A presents a system designer view of the graphical user interface of the present invention; including a logical view of a project and windowed views of specific files;
FIG. 33B illustrates how errors are revealed to the system designer in the user interface;
FIG. 33C illustrates how the system designer opens, removes, or overrides a source code file, or learns of its properties from the graphical user interface;
FIG. 33D illustrates how the system designer opens and selects or de-selects a component with the graphical user interface;
FIG. 33E illustrates how a system designer adjusts an option using the graphical user interface;
FIG. 33F illustrates the icons and what they mean in the graphical user interface;
FIG. 34 is an overview block diagram of the product make routine 800 (FIG. 11), also shown in FIG. 8;
FIG. 35 is a block diagram of the build feature include file routine 950, also shown in FIG. 9A;
FIG. 36 presents a block diagram overview of the product component linker routine 3600 (FIG. 11);
FIG. 37 presents a block diagram overview of the list creation and management process 3700; and
FIG. 38 presents a block diagram illustrating the flow of control information through the system 100 to guide the software development process.
DETAILED DESCRIPTION OF THE INVENTION
The preferred embodiment of the invention is optimized for use in an IBM compatible PC ROM code image software development environment in which a shared library of code is used by many vendors to develop ROM BIOS code images for portables, desktops, and servers having a variety of different processors, busses, and peripherals. The invention was developed using conventional, unmodified assemblers, compilers, and linkers, as well as a standard UNIX-style make utility. In addition, a special product component linker 3600 (FIG. 36) was developed for use with the invention. Th component linker 3600 is, in many respects, a conventional linker for combining separately compiled and linked *.exe files into a single, integrated code image suitable for ROM storage. The ways in which it differs from a conventional tool used for this purpose are pointed out below.
The inventors contemplate that the invention has applicability beyond the development of ROM BIOS images to embedded systems of all types, as well as to software development in general. In its more general features, the invention is applicable to any software development environment where software components and features need to be managed, selected, and altered to meet the special requirements of specific clients.
Because conventional compilers, assemblers, and linkers are used in the preferred embodiment of the invention without any special file preprocessors, and because it is desirable and convenient and efficient to have some steps of the present invention (in its preferred embodiment) performed from within such compilers and assembers, some way of altering the performance of these standard components was needed. Accordingly, the preferred embodiment of the present invention contemplates inserting specially-defined macros into the source code at many points where conventional programming commands such as "CALL" or "PROC" or "INCLUDE" or the like would normally appear. These special macros are described in complete detail below, at the end of this specification, following the more general overview explanation of the invention. But it is also possible to utilize preprocessors or to utilize modified compilers and assemblers that can achieve the functionality of the present invention without the need nor the use of some or all such special macros. In effect, the results achieved in the preferred embodiment of the present invention through the use of special macros can be achieved without the authors of source code files having to use special macros by simply having a preprocessor or the compilers and assemblers respond to commands such as "CALL" and "PROC" and "INCLUDE" in substantially the same way in which the present invention has them respond to the macros substituted for these commands. The present invention encompasses such variations in design as fallingwithin its scope.
In addition, the preferred embodiment of the invention places the data that is to control the product component linker into special code segments defined and created by the special macros, a technique that is particularly apt in the IBM PC environment where segmentation is heavily used for other purposes as well. Once again, other equivalent ways can readily be provided for collecting this data (such as the definition and contents of lists) from the many source-code files, for example, at a much earlier stage in the process, and for passing this data to the component linker or its equivalent to thereby achieve the goals of the present invention.
An overview of the program development system 100, which is the preferred embodiment of the present invention, is presented in FIG. 1. FIG. 1 emphasizes the major software routines that form parts of the system and how they call upon and relate to each other.
At the heart of the system 100 is an integrated development environment 102, which includes a user interface 200, the functions of which are set forth in FIG. 2. The user interface itself appears in FIGS. 33A through 33F. With reference to FIG. 33A, the designer is presented with a first window (to the left) in which he or she may view a logical (as shown) or a directory-subdirectory view of a source code library. A "logical view" is a user view of the code library that is organized, and the components and features of the code library are displayed, hierarchically first by class, then by component, then by feature, then by subfeature, and so on, with each individual source code file associated with a corresponding component, feature, and sub-feature.
As shown in FIG. 33A, the logical view includes a root node 3308, which is shown as Platform--Desktop--IA32. In the first level below the root node 3308 are a series of components, such as FDisk 3310, Intel371ab (PIIX4) 3314, POST services 3306, etc. In the levels below each of the components, there may be one or more features. For example, in FIG. 33A, the Post services component 3306 includes several features, such as Decompress Manager 3304, Memory Manager3307, and POST Dispatcher 3309. In addition to being in the level directly below a component, a feature may also be viewed in a lower level as a sub-feature, which is a child feature to a parent feature. In FIG. 33A, the LZINT feature 3311 is a subfeature to the Decompress Manager feature 3304.
Hereinafter, the term "object" will be used generically to mean a "component," "feature," or "subfeature". (This special usage of the term "object" in this patent is not to be confused with the entirely different meaning assigned to the term "object" in the field of object-oriented programming.) The "logical view," with the code subdivided by class (note the class designations "post" 3321 for the component 3306 and "decompmgr" 3323 for the feature Decompress Manager 3304 in FIG. 33A), goes beyond just the user view, however. In source code files, when references are made to the names of externals, such as include files, procedures, and options, class designations may replace these precise directory/subdirectory addresses, used in conventional software development systemws, and accordingly the programmer need not be concerned with precisely where an external procedure or and included file resides--only with the class to which the source code file containing the external procedure is assigned.
FIG. 2 lists the primary functions performed and views provided by the user interface 200. The designer can use the keyboard or mouse 202 to modify a file or directory 302 (FIG. 3), build the product from a valid configuration 306, customize features by forcing them into or out of the build 304, specify custom code (file override) in addition to or in place of code from the component source code library 304, and customize or change option values 304. The updated user view 204, as a result of these changes, then displays the component and feature tree (left side of FIG. 33A): with components and features clearly marked as in (bold) or out (faint) of the build (FIG. 33A); with components and features clearly marked where the designer has forced them into (marked with a check) or out of (marked with a "prohibit" slashed circle) the build, overriding the default configuration (FIG. 33D); with original source files shown plus custom 3332 and override files 3326 clearly marked (FIG. 33C); with dependencies 3325, 3327 listed individually and collapsable into an icon (FIG. 33B); with interface declarations 3329 (FIG. 33B), option declarations 3336 (FIG. 33E) viewable; and with feature/file errors and warnings clearly shown 3318, 3320, 3322, 3324, and 3325 (FIG. 33B).
The user interface 200 permits the designer to issue commands through a command executor routine 300, an overview view of which appears in FIG. 3. In FIG. 3, and in all similar figures to follow, any rectangle that overlies the border of the large rectangle that encompasses the components of the routine 300 contains one or more entry points to the routine--one or more commands that may be issued by the designer or by a calling routine.
If the designer wishes to update or modify a source code file, or move a file into a new directory, or change the directory structure of the system, the designer does so using the user interface shown in FIG. 33A. For example, to revise a source code file, the designer clicks on the file's name 3326 (FIG. 33C) and selects "Open" using the mouse and pointer. The file appears in an editable window (right half of FIG. 33A) where the designer may review and optionally modify the source code file (step 502 in FIG. 5A). When the designer is finished, the designer closes the window and "saves" any modifications in the traditional way. The command executor 300 is then called upon automatically to perform the steps shown, starting at 302, in FIG. 3, and also shown in flow diagram form in FIG. 5A. First, at step 402 in FIGS. 3, 4, and 5A, the database update routine 400 (FIG. 4) is called upon to scan the file, assuming that it has been changed (steps 404, 406, and 408 in FIG. 4). The routine 400 collects information from source-code-resident special macros and from commands found in component and feature information files (step 2700 in FIGS. 4 and 27) defining each source code file's internal names, entry points, and exits, as indicated at 1826 to 1830 in FIG. 18 (source library database 1800). The inforation gathered includes the "class" assigned to each procedure call, to distinguish, for example, "TIMER" class procedures from "DMA" class procedures so that identical procedure names will not be confused ("TIMER.RESET" cannot be confused with "DMA.RESET", for example); version numbers, such as "3.2," for later use to check for incompatible versions; and like information. All this information is stored within the database 1800 (FIGS. 6 and 18) by the data access routine 600 write API routine 602 (FIG. 6).
Next, a configurator routine 700 (FIG. 7), which maintains configuration status data 1900 (FIGS. 19 and 32) in RAM, is called upon at entry 704 to use the database 1800 to update the product configuration state data 1900 and to then configure 3000 (FIG. 30) the product to be built by redetermining which objects (components and features) to include, which to exclude, which objects to make designer options with what default values, depending upon which platform type (server, desktop, etc.) has been selected, what dependencies (options, calls to functions, file inclusions, etc.) need to be satisfied, and so on. Finally, at step 204 (in FIGS. 3, 5A, and 7), the routine UI UPDATE VIEW (FIG. 2) is called upon to regenerate the logical view of the software system within the left-hand window of FIG. 33A to share with the designer the new state of the system, and to permit the designer to change default object selections (see the menu 3334 in FIG. 33D) or to adjust the values of options (see the menu 3338 in FIG. 33E). In this quick and unobtrusive manner, all changes made by the designer are quickly and accurately recorded, the product to be built is reconfigured accordingly, and the designer is presented immediately with the results of all this activity.
If the designer does something, for example, that might cause the final linker in a conventional system to fail because of a dependency that could not be satisfied, such as by the absence within the library of any external procedure to which a "call" statement can be linked (this could, for example, be caused simply by the misspelling of a procedure's name), then, as is shown in FIG. 33B, little "X"s will appear beside the items that are causing the trouble. The designer may then, by simply clicking down through the displayed tree, quickly find, for example, the particular "dependency" that caused the problem (for example, the subroutine name "SendEOI" in the class "pic" shown as "pic.SendEOI" at 3324 in FIG. 33B). A "find" utility enables the file containing this reference to be quickly found, opened, corrected, and closed, with the system again being updated and corrected automatically to reflect the correction (the "X"s would then dissapear).
With reference now to FIGS. 3 and 5B, when it comes time to build the final product, the entry 306 "full product build" in the command executor routine 300 is called upon by the user interface 200 in response to a user keyboard/mouse command 202. Once again, the database update routine 400 (in FIG. 4), entry 402, is called upon to perform a scan, this time of the entire library: source code files; component information files; and feature information files. With brief reference to FIGS. 15 and 17, the "component.inf" and "feature.inf" component and feature information files contain build commands that define the value of options (line 1528, for example), and also contain formal rules to determine logically when a particular object (component or feature) is to be selected (lines 1514, 1516, and 1518 in FIG. 15, for example). These files also provide class designations (line 1504, for example) for the corresponding components and/or features. Such a class designation is automatically applied to procedures and labels within any source code files that are stored in the same subdirectory with a "component.inf" or "feature.inf" file containing such a class designation. this enables, for example, external calls to the procedures specifying a class as if it were a "path" ("class path" designation, such as "TIMER.RESET" where "TIMER" is the class and "RESET" is the procedure name) may be found and linked up properly without the individual calling source code files having to specify the actual path through the source code library tree to the called procedure source code file. This class designation also determines how the objects are organized in the user's "logical," as opposed to "directory/subdirectory," view of the library contents (FIG. 33A). Since dependencies are slways designated as to their class, in addition to the class determining which subroutine or procedure calls link to which subroutines or procedures in which source code files, the class designations also determine other similar linkages whenever any type of external reference by a dependency is satisfied. Identical function and procedure names, and other names (include file names, for example) may accordingly be used in features and objects assigned to different classes without causing any confusion or mis-linking. And class designations enable include files and procedures to be found without regard to where they are actually stored within the component source code library file directory tree. For example, prior to assembly or compilation, include file paths (or addresses) are automatically generated and inserted without user intervention or knowledge of where the include files are actually stored.
Next, the database 1800 (FIG. 6) is updated (step 602 in FIGS. 4, 5B, and 6). Then the configurator 700 is called upon again to revise the product configuration state data (step 706); and if any changes are made, then the routine UI UPDATE VIEW 204 (FIG. 2) is called upon to update the user's view; and if any red "X"s appear (FIG. 33B), the product build is cancelled.
Note, in FIG. 7, that the configurator begins a configuration with product configuration data 2100, which is retrieved from a file "platform.cfg." With reference to FIG. 22, this product configuration file designates such things as PLATFORMTYPE 2201 (server, desktop, etc., and specific architecture), system option values 2202, features to be included or not included 2212, additional files to be included 2215, files to be replaced 2216 (override), option values 2218-2220, and the like. All of this information comes from the user interface, and all of it is created under user. A simple question asking routine (not shown) can be used to create a new configuration by asking the designer simple questions to determine the platform type, the system architecture, and other such fundamental things. The remainder of the data contained in this file is accumulated whenever the designer exercises his or her option to override the default object selections and option values, again through interaction with the user interface. (Of course, this file may also be edited manually; the entire program development system may be run without the user interface, with the routines shown to the right in FIG. 1 executed one-at-a-time manually; but much of the functionality of the invention lies in the interactive user interface.)
The configurator 700 next goes to the database 1800 and loads itself up with all of the data which the database contains, both data obtained from scans of source code files, and in particular the parameters the programmer has supplied to the special macro call statements (such as class, name, version number, and the like taken from each type of macro), and also data gathered from special class and feature files which occupy the same subdirectories as the corresponding class and feature source code files. All of this information, in combination, is called the product configuration state data 1900. As shown in FIG. 19, this data includes component names 1902, 1904, 1906, descriptions of components 1908, feature names 1910 and 1912, and information associated with each feature such as class 1914, files 1916, definitions 1917 and references 1919, etc. This is the information that governs the nature of the user display. Note that the "in" 1922, 1926 and "out" 1924, 1928 status of each object (feature or component) is clearly marked by a flag bit or number in the configuration state data (as is indicated by the presence or absence of Xs in FIG. 19.)
Program control next continues with a call to the product make routine 800 shown in FIG. 8 (step 800 in FIGS. 3 and 5B). The product make routine begins at step 802 by calling upon the configurator 700 to provide a list of all active (or selected) components. The product make routine 800 eventually will retrieve all of the selected (or "X"ed) information shown in FIG. 19. This selected information is shown at 2000 in FIG. 20.
Returning now to the product make routine 800 shown in FIG. 8, at step 900, for each separate component, the product make routine calls upon the component build prepare, routine 900, shown in FIG. 9B. This routine, at step 902, calls upon the configurator 700 and its RAM configuration state data 2100 to provide source code file and file dependency information for the component. Next, at step 950, the build prepare--feature include files routine (FIG. 9A) is called upon to go through each of the feature subdirectories of the component. At step 952, the configurator 700 is again called upon, this time to obtain information about a particular feature. The information provided is compared to the existing information found within the feature's "feature.inc" file, if any exists, at step 954. If the information has changed (step 956), then a new "feature.inc" file 2300 is generated and is written. Next, at step 960, if there are more features, this process is repeated until, at step 962, all the features have been checked out. Then program control returns to step 904, where the component information is compared with the contents of any existing component makefile. If, at step 906, there is any change, a new component makefile 2400 (FIG. 24) is created at step 908 that governs the proper compilation and/or assembly and linkage of the component and all of its features into an "*.obj" object file. The bild prepare--component makefile routine 900 is repeatedly called in this manner, once for each component that has been selected for inclusion in the finished product.
By way of brief explanation, to be supplemented below, the "feature.inc" files are placed into each feature subdirectory along with the source code files that actually define each feature. Each of the feature source code files contains the command "INCLUDE feature.inc". This causes the compiler or assembler to insert a feature's "feature.inc" file into all the source code files for the feature, where they may perform such tasks as changing class references to file path references, define options, and set switches that cause procedure calls to be deleted from the source code, if they call unselected components (see, for example, FIG. 23, where the value TRUE is assigned to "D_TIMER_DELAY" to cause a subroutine call to the "TIMER_DELAY" function to be included in the source code), or to be marked, for example, with a specific component name (to require the procedure linked to a call statement to reside within a feature of the named component). Likewise, a procedure entry point can be marked "override" to cause it to be selected in preference to an identical procedure name in some other source code file. Through the mechanism of the automatically-generated "feature.inc" files, all such user-option mechanisms can be adjusted by the system designer from the graphical user interface without the need to edit or alter the source code files themselves. This gives the system designer unprecedented control over the configuration of the finished product, with minimal effort.
After all components have been processed, program control returns to the product make routine (FIG. 8), step 908, where a product makefile 2500 is created. This product makefile 2500 contains directions that switch the computer's focus to the various component subdirectories and that then cause the computer to execute the component makefiles 2400 found within each such subdirectory, thereby building an object code module for each object. Then it calls upon the product component linker 3600 to link together all the component object code files 1104 (FIG. 11) into the finished product 1106 (FIG. 11).
Next, at step 1000 in FIG. 8, a standard Unix "make" utility is called upon to build the product under the control of the component and product makefiles 2400 and 2500 just described. This process is outlined in FIG. 10. At step 1002, a command is read from the master make file that selects the subdirectory of a component (step 1006). The make utility, governed by the product makefile 2500, then calls upon itself to process the component makefile 2400 found within that component subdirectory which carrys out the steps 1008 to 1016. At step 1008, a command is read from the component makefile 2400 which calls for compiling 1010, assembling 1012, or linking 1014 a feature source code file, and this process continues repetitively until all the commands have been executed (step 1016), thereby producing a built product component file 1104 which also contains special segments that contain "fix-up" data that the product component linker 3600 will later use to patch one or more separately linked executable object code files into a finished, unified product (other special segments may contain list elements, etc.). The make utility, at 1018, sensing more commands in the product make file 2500, continues to read commands from this file 2500, to select additional component subdirectories, and to call upon itself to execute component make commands found in makefiles associated with each additional component, as was just explained, until finally all the component source code files have been compiled or assembled and linked.
At step 1004, the make utility finally reaches the product component linker instructions (2528 and 2530 in FIG. 25), which cause the product component linker 3600 to combine all of the separately linked component executable files to be merged into a single code image, with the addresses fixed up such that class and name references are all replaced with absolute image addresses, ready for incorporation into a ROM-based finished product 1106.
With reference to FIG. 2, there are a number of other user commands available. At entry 304, the designer may force a feature in or out by calling upon the configurator 700 to change the product configuration, and these changes are reflected in and stored within the the project configuration data file 2100 "project.cfg." Option values may be changed in this same way, and files specified for inclusion within the manufacture of a finished product may be overridden and replaced with other files designated by the designer.
Another option is the quick product build or the single component or single file build at entry 308, which bypasses the tree scan and configurator steps 402 and 706. The new source tree entry 312 is used when the source code library tree has never before been processed, thereby making it unnecessary to perform steps such as steps 956 and 904 in FIGS. 9A and 9B that check for whether existing special files need to be corrected (since it is likely no such files exist). The step 402 calls for a scan of the entire tree (FIG. 4). The configure product entry 702 into the configurator 700 is then taken which, at step 604, calls for access to the data in the database 1800 (FIG. 6) and then configures the product in step 3000 (see FIG. 30 for details). At step 204 (FIG. 2) a report is generated for the designer, and the product configuration state data 1900 is written out to disk storage.
The macros are described in full detail towards the end of this specification. Their functioning is described here in overview.
The program development system 100 is useful in resolving dependencies between references and declarations. One way the program development system 100 can resolve these dependencies is with the use of macros. For example, the macros can be used to resolve dependencies in the situation where two routines with the same name exist, and this commonly named routine is being referenced. Such a situation can occur when two or more identical components are used in a system, each component having the same routine names.
To overcome this problem, macros for branching the code execution, EXTJMP and EXTCALL, are used. These macros must be preceded in the file by a PBUEXT public external declaration macro. EXTJMP and EXTCALL are macros used to branch from a routine in one component to routines within another component. Both macros generate fix-up data, destined for the product component linker (and placed into the external segment 3802 shown in FIG. 38) that lists the address of EXTJMP or EXTCALL macro and the name (class plus procedure name) of the routine that is to be branched to. The fix-up data is stored in intermediate libraries, which reside in the external segment 3802 from which it is accessible to the product component linker 3600 which actually performs the fix-ups. The name and class generated by an EXTJMP or EXTCALL macro may be the default name and class; it may be an alternate name and class, if the call or jump is declared by the PUBEXT to have an alternate name and class; or the call or jump may be deleted entirely, and no fix-up data generated, if the call or jump is declared by the PUBEXT to be optional. A data switch passed in as part of the "feature.inc" file, calculated by the product make utility based upon whether the default procedure exists or not, switches the macros between the default name and class and the other two options. IN this manner, an optional call destination can be achhieved if the default destination does not exist, or the call or jump can be automatically deleted if the default destination does not exist.
The PUBEXT, EXTCALL, and EXTJMP macros can a!! designate a component by name. Then, if two components contain the same procedure name, the fixup data generated by the EXTJMP and EXTCALL macros will contain a component name designation, and then the product component linker 3600 will link that call or jump only to a procedure residing within the named component. In this way, the name ambiguity discussed above can be resolved.
A PUBLIC_PROC macro indicates the location of a procedure within a component. One of the arguments that this macro may accept is the key word INTERCEPT, which is added to the "fex-up" data generated by this procedure. Every public procedure macro generates fix-up data, including the name (class plus name) of the procedure, plus its absolute address within the object code, and this fix-up data also identifies the component that contains the procedure. This fix-up data is placed into the public segment 3804 from which it can be accessed by the product component linker 3600, which does the actual fixing up of the data.
If the key work INTERCEPT is present in the fix-up data of a given procedure, and if there are other procedures that have the same name (name plus class), then the product component linker 3600 will link all procedure calls (identified by their fix-up data in the external segment 3802) to the procedure designated the INTERCEPT procedure instead of to other identically named procedures, for example, assigned to the same class and possibly having the same component name.
The following is a more general discussion of macros and system development, and of how macros can be used and of how systems can be designed. It is not fully in accord with the preferred embodiment of the present invention, particularly in not always assuming that the "fix-up" steps are performed by a product component linker. Fix-up data, of course, may be stored in some form of intermediate library, and the fixing up of the code can be done in other ways. (The description of the preferred embodiment will begin again with the detailed description of FIG. 11 which commences some paragraphs below.)
A PUBLIC_PROC macro may used to declare a dispatch routine. The dispatch routine is a routine that acts as a dispatcher to branch to the two different routines. The name and address of the routine will be stored as fix-up data. This fix-up data is also stored in the intermediate libraries. The build tools discard the fix-up data generated by these macros before generating the final binary image.
In addition to the argument in the EXTCALL and EXTJMP macros designating the routine name, another argument in these macros designates the name of the component library used to resolve the specific branch. The name of the component library used to resolve the specific branch can be designated by the designer through the user interface 200. The designer can obtain information from the user interface to determine which component libraries can be designated. Alternatively, an automation utility (a wizard) can parse the components in which the common routine is found and generate a source code template with a dispatch routine for each common routine between the components. This wizard would automate the search for common routines and simplify the coding for the dispatch routines as well as provide a method to automate debugging between the components.
Like the address of every branch, the name of the routine to be branched to, and the name and address of the dispatch routine, the information regarding the designated component library is stored as fix-up data in the intermediate libraries, which the build tools discard before generating the final binary image. The binary linker uses all of this fix-up data stored in the intermediate libraries to patch the branch instruction with the address of the correct routine from the correct component library, thereby resolving the dependency.
By using these macros to resolve such a dependency, existing component routines do not need prior knowledge of the component to which it belongs since routines are automatically distinguished by the component in which they were compiled and linked into the component library. Existing component routines also need not be recompiled. Moreover, all component routines can be encapsulated within a single component library and distinguished via the component, which enhances code encapsulation.
These macros used to resolve a reference to a commonly named routine existing in at least two components are not required. Any method for tracking external references (i.e. branches) can be used. Other tracking mechanisms that can be used include, for example, a preprocessor, assembler or compiler keywords, and a custom linker. Likewise, the invention can utilize any method for tracking public declarations. Any method that allows public declarations to be tracked and the declaration type (i.e. intercept or non-intercept) can be used.
Another way the macros can be used is to select among possible resolutions to unresolved compilation references in the objects of a build. The names of objects and their location are maintained in a database. There may be only one object per file-system directory and each object directory contains either a COMPNENT.INF or a FEATURE.INF file. The database may be updated either by scanning the file system for such INF files or through manipulation of the database using an API.
The objects could be specified explicitly. A directory or list of directories could be specified which would then be searched for objects, not to determine order, but to determine presence or absence. The detection occurs in a timely fashion and can be handled automatically. A database or some other storage means could be used.
The INF file includes ASCII text containing attributes used for browsing the software project and controlling the compilation process. In addition, BaseClass is used to identify that two features have the same interface and provide the same basis functionality. Normally no final software product may contain two features having the same BaseClass.
Since the build can be for numerous types of target hardware platforms, it is useful to classify these platforms into general categories, such as BasicPC, Notebook or embedded. For each of these platform types it is possible to specify the default behavior, which can then be changed by the designer manually. One of these default behaviors is an "OnDemand" attribute, which indicates that the object will be included in the final software product if there is a reference to it by another object, another object with the same BaseClass has not been explicitly included by the system designer, and the system designer has specified that the hardware platform falls into the general category listed in the PlatformType command.
The OnDemand attribute could be placed within a source file (rather than a separate file). The attribute could also be in some sort of master database instead of in the tree. Alternatively, the attribute could be for one or more platform types or not use platform type at all in determining whether or not the OnDemand attribute should be used. The OnDemand attribute could be linked to any number of user specified software project attributes (not just Platform Type) or none at all. The On Demand attribute could also be moved to the interface functions themselves (for function-level exclusion).
Interface functions (i.e. functions which can be called between objects) are declared using the macros PUBLIC_PROC and PRIVATE_PROC. These macros specify the scope and other attributes information for the function. Objects which use interface functions must either be in the same file as the function or else declare its prototype using a PUBEXT or PRVEXT macro. The actual function calls use the EXTCALL macro. Configurator 700 scans the source files before the normal compilation process begins in order to determine the location of all interface functions and all references to such functions. Then, based on the platform type and explicit commands from the system designer, the list of references to interface functions is compared against the list of interface function declarations. When there is a non-optional reference with no declaration, this is considered unresolved.
The detection of unresolved references can be done without the use of the macros. Standard methods could be used including leaving such detection until the link stage of compilation. It could also be used in late binding with dynamic load libraries, using a list of libraries and their attributes.
At this point, all objects listed as OnDemand are checked to see if including them would resolve one or more unresolved references. If so, the object is included. The determination that an object will be included in the final software product is determined before normal compilation begins. This is accomplished by either including or excluding the files in the object from the compilation process. For some objects, all files therein are included or excluded. For other objects, this is done on a file-by-file basis. In either case, the make file is modified. An error condition is detected when two components with the same BaseClass are marked OnDemand and one or both of them would resolve an unresolved reference. Although preferably done before compilation, the decision to include an object in the final make product can alternatively be done using link-stage binding or run-time binding.
This method for resolving references prior to compilation allows a developer of the object to determine which object should be included by default. This lowers the chance of errors and increases productivity. It also allows faster builds, since pre-compilation knowledge of all objects and all dependencies limits the number of files to be assembled to the exact minimum.
The macros can also be used to resolve dependencies based on the versioning of the objects being referenced and declared. The PUBLIC_PROC macro is used to declare public function interfaces. One of the parameters in this macro is a version number in the form x.y, where x is the major version number and y is the minor version number.
Incrementing the major version number indicates a later revision of the interface, which is not backwards compatible with regards to inputs, outputs and/or side effects. Incrementing the minor version number indicates a later revision of the interface, which is backwards compatible with versions of the interface having the same major version number and lower minor version numbers. This indicates that all inputs and outputs expected by lower minor version numbers are supported, as well as similar side effects. However, new inputs may produce new outputs and different side effects. This versioning scheme is just one of many possible, including non-numeric, single version numbers, and dual version numbers with one being the current and one being the backward compatibility version.
The PUBEXT macro is used to declare a reference to a public interface, either function or array. One of the parameters includes the version number expected by the caller. The version number has a similar format to that of the PUBLIC_PROC and LIST_CREATE macros. A warning is generated if the caller and callee differ in major version numbers or if the caller has a higher version number than the callee.
The database is accessed to determine the location of the "callee" and its version. The information in the database is updated using the DBUPDATE (database update) utility, which, when invoked, scans for the previously described macros in all source code files in each object and places the name of the interface and its version in the database. It also finds the references to these interfaces by scanning for PUBEXT and recording the location and the version of the caller in the database.
Then, the database is searched for each caller to see if the version is compatible with the callee. The version is considered compatible if the major version number of caller and callee are the same and the callee minor version number is greater than or equal to the caller version number. This information can be displayed, output to a file, etc. so that the designer is informed of any potential incompatibility.
The database is not required, and the scanning process need not use a database at all. Rather, the version information could be added to the data prototypes as a special keyword handled by a preprocessor or special version of a compiler. For example, in C, the version number of the function could be encoded as a_-style keyword in the function prototype.
In addition, the exact manner by which the version number is attached to the caller and callee could vary from programming language to programming language. For example, in C, it can be attached to the function prototypes if MASM macros are used. For other embodiments, the versions could be attached using an external file. The versioning can also apply to static variables or data structures.
This use of versioning allows large software projects to be built more independently by tracking semantic changes in input parameters (bug fixes-modified parameter definitions). It also gives improved feedback as to whether the software project is likely to work before compilation and run-time. The versioning may also reduce errors because functional changes are readily identifiable by examining the version numbers.
Another use for the macros is to intercept a call to a first routine and have the call to the first routine replace by a second routine, which is the intercept routine. First, the two macros used to branch code execution, EXTJMP and EXTCALL, are used. EXTJMP and EXTCALL are macros used to jump to or call routines between components. Both macros generate fix-up data that lists the address of every call and jump and the name of the routine to be called. The fix-up data is stored in the intermediate libraries and discarded before the build tools generate the final binary image.
A routine that intercepts a call to another routine should have the same name as the routine to be intercepted. The intercept routine uses the PUBLIC_PROC macro to declare itself as an interface routine with an INTERCEPT keyword specified as a macro argument. The PUBLIC_PROC macro generates fix-up information that lists the address of the intercept routine, the name of the intercept routine (identical to the original routine), and the attribute that the routine is used to intercept another routine. Again, the fix-up data is stored in the intermediate libraries and discarded before the build tools generate the final binary image.
Using the generated fix-up data stored in the intermediate libraries, a linking utility is used to correctly link each branch and generate the final binary image. The address of the called routine is directly patched for the branch instruction in the component initiating the branch if a routine is not intercepted. However, the address of the intercept routine will be patched in place of the originally called routine whenever the intercept routine is present.
Although the address of the intercept routine is patched in place of the originally called routine, the originally called routine can be optionally branched to from within the intercept routine using the EXTJMP and EXTCALL macros. The linking utility will perform this by using the fix-up information in the intermediate libraries to correctly link the branch instruction to the original routine. In addition, the originally called routine can be optionally removed if the intercept routine never calls it and no other piece of code in the final binary image would reference it.
This interception process can be extended to replace called routines with referenced variables. It can also be extended to allow calls between routines within the same component to also be intercepted. The process could be modified to allow the intercept routine name to be different than that of the routine intercepted, i.e., the originally called routine. This would simply require an alternate and separate mechanism to couple the intercept routine with that of the caller.
With the use of this interception process, calls can be directly linked to their routine and no indirection is needed. Furthermore, the caller does not need to anticipate or know about any potential routines intercepting a call. The caller simply declares itself as any other procedure. The process also does not require the originally called routine to be in the final image if it is never called or referenced.
The elimination of an intercepted routine from the final binary image allows for a more efficient use of space by eliminating code that is not used. This efficiency can be extended to eliminate code that makes unnecessary calls. When all source files composing a project are present, a scanning and update utility scans each project source file for specific macros that reference declarations in other files. The two branch macros EXTCALL and EXTJMP use the macros PUBEXT and PRVEXT to declare all references. The scanning utility will scan for the PUBEXT and PRVEXT macros. The names of the declarations that the branch instructions refer to (via the PUBEXT and PRVEXT) are then recorded by the scanning utility into a database along with the source file name and location.
The two branch macros EXTCALL and EXTJMP require one of two BIOS external declaration macros: PUBEXT or PRVEXT. The macros have an attribute field allowing the macro to declare the reference to the branch declaration to be "optional." To eliminate unnecessary code from the final binary image, a branch instruction will not be compiled if the declaration that the branch instruction references is optional and the source file defining the declaration is not in the build.
Every branch is reconciled with its public declaration, which is in a different file. For each declaration reference, a flag indicates if a specific declaration is present in the build. A flag will not be generated for any declaration referenced that is not in a project source file. The flag is stored in an include file to be picked-up by the macros during compilation.
The two branch macros EXTCALL and EXTJMP will interpret the data generated by the scan utility (and passed via the include file) and optionally generate the necessary branch instruction for compilation. No branching code will be generated if the declaration is not in the project and the branch was marked as optional using either the PUBEXT or PRVERT macro. The EXTCALL and EXTJMP macros also provide a mechanism to insert additional code to be compiled if the declaration for the branch instruction is resolved. Conversely, additional code in addition to the branch instruction can be removed if the declaration for the branch instruction is not resolved.
This process can be extended to replace branched routines with referenced data types. The mechanism used would be identical to that for code branches. Furthermore, the macros discussed in the implementation of this process are not required for its implementation. Instead of the macros, the process could be implemented by scanning for the declarations dynamically as the project is pieced together as opposed to just before the compilation. The macros used to declare declarations and record declaration references could instead be keywords interpreted by the compiler or other utilities such as a preprocessor. Also as discussed above, a different method other than the formal database can be used to record the declarations and their references. A monolithic file that was parsed for information could be used in addition to other methodologies of recording data. In addition, a mechanism other than an include file could be used to pass the flags.
This process of removing optional branch code allows for the removal of the code before source compilation using prior knowledge of the system, which decreases the compile time. The removal of the declaration reference in addition to the declaration itself is completed without a stub. The process also operates across multiple translation units.
The resolution of declarations and references and the use of versioning can also be applied to labels. Similar to procedures, i.e., routines, the PUBLIC_PROC and the PRIVATE_PROC macros are used to declare each label definition. Labels defined by the PUBLIC_PROC or the PRIVATE_PROC macro may be used to resolve either public or private label references. Each label definition includes the label's name, the label's location, and the version of the label being defined. The PUBEXT and PRVEXT macros are used to declare each label reference. Each label reference includes the label's name, label's location, and the version of the label being referenced.
A validation utility is used to validate each label reference. The function of the validation utility could be integrated with another utility, such as the compiler or the integrated development environment. The utility ensures that each label reference has a respective label definition. The utility then compares the version information for each label. The utility will report an error if either a label being referenced does not exist or if the label being referenced is of an incorrect version. The validation utility reports the resolution status of each label reference once all label references have been resolved. The resolution status for each label can be reported to aid in the debugging of the build process.
This process allows the designer performing the build process to save time by quickly detecting and correcting all build-related label resolution errors before the time consuming build process is performed. It also does not require libraries or components that are external to the software product's code base to be previously built in order to detect build-related label resolution errors.
In the program development system 100, the main data structure is called a "list." A list is an array of fixed size elements, which entries may be added by any source code file. Lists must be created once, using a LIST_CREATE macro. This specifies the name of the list and the size of each list entry. List entries are added in groups. The groups begin with a LIST_START macro and end with a LIST_END macro. Each list entry is assigned a name.
For groups containing replacement list entries, an extra parameter on the LIST_START macro specifies the override priority. The override priority is applied to all list entries within the group. If the software project contains two list entries with the same name but different override priorities, the list entry with the higher priority is retained and the other discarded. Two entries having the same name and priority is an error condition.
The binary linker creates the final list, containing all list entries. The binary linker finds all list entries. For those with the same name, it compares their override priority. The highest priority entry is retained and the others discarded. The list entries for a particular list are placed sequentially, given an address and all references to the list and its entries are resolved.
This list process can be used with any statically initialized data structure. The lists can use different keywords for creating and initializing the data structures or none at all as long as the replacement data structure can be identified. The number of override levels can be changed, from a simple one level to n levels, n being an integer greater than one. The merging of the lists can be performed by the normal linker or even the compiler.
Using the list process, data structures can be created normally. In addition, more than one level of replacement can be done, which allows for "core," "product line" and "platform" distinctions.
Program development system 100 also provides a mechanism for including libraries in the build based on the existence of other libraries within the build. A load library is a dynamically triggered load library similar to prior art load libraries because the library's entire code set is included in the build. A search library is a dynamically triggered load library providing a mechanism similar to prior art search libraries for conditionally including code in the build. The difference between these two types of libraries is seen in the type of reference used.
Search libraries use a "forward" reference to include the library code in a build. For example, if Library A depends upon an object in search Library B, then the object code from search Library B will be included in the build. Dynamically triggered load libraries, on the other hand, use a "backward" reference to include the library code in a build. For example, Library B will declare that it should be included in the build when Library A is in a build--even though Library A has no dependency upon Library B.
Three things are needed to implement the dynamically triggered load library: a configuration script, a trigger command, and a build script generator. A configuration script is necessary to identify which modules are intended to be included in the final product. This may be a simple MAKEFILE, or it may be a custom file that simply lists the module names.
An "External Trigger" command is associated with the library to be loaded based on external criteria. For example, a special file (ModuleY.INF) can be associated with the triggered component. The INF file includes an External Trigger command indicating that "ModuleY" should be included in the final product if, for example, "ModuleX" has been included. Although the trigger declarations in this example is made within a .INF file, the trigger declarations can be included anywhere within the library's code. It is simply the responsibility of the script generator to locate these declarations and use them appropriately.
The build script generator's main task is to generate a MAKEFILE (or appropriate compiler/linker script) for building the executable product. The generator uses all potential library's INF files and the configuration script as input. During the script generation phase, the generator, based on external triggers, will determine if any of the libraries should be included in the final build. The use of a MAKEFILE assumes the use of tools that utilize such a script. This is not a requirement, however, and it may be substituted with any manufacturer's build tools to obtain the same effect.
The use of dynamically triggered load libraries provides the ability to include libraries in a product without the need to directly modify the triggering module code or build scripts. A benefit of dynamically triggered load libraries is also found as the number of libraries and interdependencies among modules increases. For example, when a designer chooses to include modules into a software project build from 400 possible choices, it is difficult to know what "backward" referenced libraries may exist. The externally triggered load library solves this problem because the backward referenced libraries will bring themselves into the final product.
In program development system 100, a utility can scan the source code files of a system to detect and record public declarations and external references. The public declarations and external references are scan-able keywords in the source code files. A list of the source files that will be used as source code libraries (as opposed to those files assumed in the build) is created.
As discussed above, a utility can resolve external references to the public declarations detected in the source code. Like a linker, the utility first finds references to external declarations in files assumed in the build. It tries to resolve them with files assumed in the build, followed by files in libraries. This is a recursive process; a file or module brought into the build may reference other files or modules. This resolution process needs to output the resultant list of source code files that will be part of the build. Normal compilation and linking can follow, and no object libraries need to be created.
In the generated list, files can be listed in a makefile, batch file, or command line application, like it is done for the creation of object libraries. A centralized list can list the library files of a project. The resolution of external references to public declarations can be done at alternate phases of development and build. It can done dynamically during edit of a source code file for real-time feedback to the developer, or it can be done after individual file compilation, using compilation output to provide public and reference information. In addition, the listing of object modules to compile and link can be done form a batch file, or a list input for command line link execution.
The listings and resolution help save development time. First, they help prevent the developer from mistakenly looking at the wrong source code during debug trouble shooting, because the actual files and their location will be listed and viewable. Knowledge of specific files used in a build also helps the developer detect the location of problem features missing or undesired features added. Second, the developer also gets immediate feedback of unresolved references prior to building the system. This saves development time, because unresolved external references are normally reported only at the end of the build process when the link is done.
Program development system 100 also provides flexibility to source code that includes a file of a specific feature class by obviating the need to specify where the include file is located. In the source code files used in program development system 100, there can be a macro class and a file name of an include file. The include file lists its class information within a macro. Prior to compilation, the source code file is scanned, and the location of the appropriate include file is determined by a system utility.
The system utility source code file includes a local include file of a static system-determined name. This included file is created dynamically by the system before compilation of the source code. The source code file lists a local fixed name include file before this macro is listed.
Using the system scan utility, the source code tree of the software system will be scanned for the above defined macros before compilation. System configuration utilities use the information retrieved from scanning the system and reconcile the class information of the file with the include files found. The system utilities generate an include file local to the source code file. The generated local include file provides the macro expansion to specify the physical location of the included file. The system utilities also dynamically create the makefile with the proper location of the include dependency.
In order to maintain control of changes to the include files located in differing locations, a versioning scheme can be used, where both the source code file and the include file list the version of the included file as parameters of their macros. The system utilities validate that they are compatible.
Using this system, the source code does not need to know which include file will be used, and a deployment of the system does not need to manually specify it. This is advantageous in polymorphic features with include files, or multiple versions of features (upgrades . . . ) in different locations. The system utilities automatically resolve the include file to the appropriate file. The class information prevents multiple instances of an include file of the same name being a problem.
The following description provides a more detailed description of program development system 100. FIG. 11 presents an overview of the program development system 100 which emphasizes the flow of information (right side of the figure) to, from, and between the routines (center of the figure) and the designer managing the graphical user interface 200, into the finished product 1106 (lower left corner of the figure). Data flows are indicated by double-line arrows, while routine command paths are indicated by single-line arrows. The description presented below of FIG. 11 places main emphasis upon data, data structures, and the data flow aspects of the present invention.
Initially, the component source code library 1200 is set up within a directory on a media such as a fixed disk drive. Within the library directory, subdirectories are assigned to each component of the software product. Under the subdirectory of each component, sub-subdirectories are set up for features each of which contains one or more source code files corrsponding to that feature, and further sub directories under the first layer of feature subdirectories may define subfeatures, and so on. Each component subdirectory also contains a "component.inf" file 1400 which defines how a particular component is to be compiled and linked, what type of platforms it may, must, or must not be used with, etc. Each feature subdirectory also contains a "feature.inf" file 1600 that defines, among other things, how a particular component is to be compiled and linked, what type of platforms it may, must, or must not be used with, and so on. The options supported by these files are described in more detail in connection with the descriptions presented below of FIGS. 14 through 17.
The database update routine 400 scans all of these files and builds the database 1800, which then contains information extracted from the arguments passed to all of the special macros calls to which macros are inserted into the source code files, plus all the information gathered from the "feature.inf" and "compnent.inf" files. This data can then be accessed by the configurator procedure 700. In particular, the database system is designed and structured so that it can answer the following questions: What are the components? What are the features? With respect to an object (component or feature), what are its dependencies, including functional dependencies (jumps, calls, etc.), options, and include file dependencies? What are its interfaces, including procedures, labels, and lists? What are its options? What are its files? What are its details? It can present a list of the components and/or features whose inclusion in the final product is triggered by a special trigger type, such as: an external trigger (X must be in if Y is in); recommended triggers (use recommended for servers; and "on demand" triggers (it must go in because component Z requires its presence). It can make sure a file (identified by name, path, data and time stamp) exists. It can also present information on a specific option identified by name. And finally, it can present a list of the "Enums" (or enumerated data names and values) for a specified option.
The configurator procedure 700 creates the configuration state data, defining the configuration of the finished product, using information drawn from the database 1800 and information drawn from the product configuration file "platform.cfg" 2100. The configurator 700, which in the preferred embodiment is written in C++, maintains this information in a C++ RAM data structure of classes (in the C programming sense of the word class) as is shown in FIG. 32. As shown, any number of product configurations 3202 may be stored in this RAM data structure. Each such product configuration may be linked to any number of classes 3204 (in the sense of the present invention), components 3206, and features 3208. The classes 3204 may also be linked to any number of components 3206 and features 3208 (note that components do not need to be assigned a class if they are not associated with source code files, which generally they are not). Each feature 3208 may be linked to any number of sub-features 3208. The components 3206 and features 3208 may be associated with files 3214 (source code files and include files) and also with options 3210 (such as equates or manifest constants of the type formally represented as, for example, "START_DELAY EQU 12" in conventional "include" files). In the case of source code files 3214, each may be linked to any number of dependencies 3216 ("include"s, "option"s, macros, and functions, where functions include lists, labels, function calls, and strings) as well as any number of interfaces 3218 (anything that can be publicly (between components) or privately (access limited to parents and siblings) referenced, such as procedures). The "visibility" of a name in a source code file is thus first limited by class, and then by component/function (parent/sibling) relationships if a name is not declared to be public. In the case of options, any option may optionally be assigned a set of enumerations 3212, as in Pascal computer programs, with each enumeration assigned a numeric value, such as "Fast=3; Slow=2; Off=1", to present a simple example. Menus of enumerations may then be presented to the designer through the user interface (when the "Modify" selection is made of the menu 3338 shown in FIG. 33E).
The graphical user interface 200 in FIG. 11 is described in more detail elsewhere. Briefly summarized, the designer at 206 may double click on icons representing source code files, "feature.inf" and "compnent.inf" files and may thereby edit any files, with automatic calls being thereafter placed to the database update routine 400, the configurator procedure 700, and to the graphical configuration display 212 to update the database 1800, the configuration state data 1900, and the user display (FIG. 33A). At 208, the designer may use tools provided to reference and search for various named system components, referencing them and navigating though the library looking for where they may be defined, after which their definitions may be viewed and revised as just described. At 210, the designer may call upon the configurator procedure 700 to modify the finished product configuration, with changes dutifully recorded both in the configuration state data 1900 (as in the "X"s shown in FIG. 19) and in the disk-resident product configuration data file 2100 "platform.cfg." All such changes, once again, are displayed upon the graphical configuration display 212.
The final user command are the user build request commands 214 in FIG. 11. As previously explained in connection with FIG. 7, this command causes user-selected and system-selected configuration state data (as illustrated in FIG. 20 (compare to FIG. 19)) to be supplied to the product make routine 800 (described in overview in FIG. 8 and in more detail in FIG. 34) to first construct the component make files 2400 and the product make files 2500, which together control all aspects of compilation and linking, and also cause the feature include files 2300 "feature.inc" corresponding to each feature and the switching on and off of feature dependencies (including or excluding "calls" and the like) to be constructed or updated.
When it has finished its work, the product make routine 900 in FIG. 11 simply calls upon a standard Unix make utility to execute the product make file 2500 and thereby places into execution the product build routine 1000 described in overview in FIG. 10, which calls upon the compiler, assembler, and linker to create built product component files 1104 for each and every component under the control of the individual component make files, with the source code modified as is required by the feature include files 2300 for each individual feature.
Finally, the product component linker 3600 in FIG. 11 is called upon to accept the built product component files 1104, strip from them data contained in special macro-generated segments that are intended to control the product component linker as it performs the final "fix-up" of the object code images, sewing them together into a fully-linked, unitary ROM image, with calls by name and class replaced with the proper calls to absolute addresses in the ROM image, with list components retrieved from their special segments, organized into independent lists, sorted as commanded, and inserted where indicated into the proper code segments, with options fully resolved, and with all other final steps of linking fully completed. In this manner, the product component linker generates the finished product 1106 ready for installation into an EEPROM or flash ROM or the like.
FIG. 12 illustrates the general structure of the component source code library 1200. This library is constructed on the hard disk drive of a computer or server in any convenient root directory. In the preferred embodiment, all system elements must reside within the confines of this root directory, which is the only part of the disk drive that is scanned by the database update routine 400.
There can be any number of system components. Each component resides within its own subdirectory within the root directory assigned to the library. In FIG. 12, the outline structure of the lines of text represent symbolically the levels of directories and subdirectories within which things are stored, and rectangles surround single subdirectories and their contents.
Accordingly, the root directory in FIG. 12 is the source library A 1202. Everything within this source library is scanned by the database update routine 400. Within this root directory are shown two subdirecoties, one allotted to component A 1202 and one allotted to component B 1206. Each componend subdirectory contains a component information file. The subdirectory for component A contains a component A information file 1400 (the details of which are shown in FIG. 14), and the subdirectory for component B likewise contains a component B information file 1210. Each component subdirectory also contains one or more feature sub-subdirectories. In FIG. 12, the component A subdirectory contains two feature subdiectories 1212 and 1214. Each feature sub-subdirectory contains feature source code files 1300, 1220, 1224, and 1226 and a feature information file 1600 and 1222, as shown. With reference to the feature 1 sub-subdirectory, it contains the feature 1 information file 1600 the details of which are shown in FIG. 16 and the feature 1 source code file A the details of which are shown in FIG. 13.
FIG. 13 presents the source code file "BEEP.ASM", an assembly language source file with macro calls of the present invention emphasized. This file is used to illustrate the Configuration Display (FIG. 33A) and its position in the component source code library 1200 is show in Appendix A.
All source files used with the present invention should include "SYSTEM.INC" 1306, which includes other include files used by the present invention. Among other things, these include files contain the special macros that may be used to implement many aspects of the invention. All source files used with the present invention should also include "FEATURE.INC" 1308, the feature include file that is generated by Product Build Prepare (FIG. 9), which builds a feature include file for each feature (FIG. 35 Build A Feature Include File). The feature include file that was built by the present invention for feature BEEP, and would be included by BEEP.ASM, is shown in FIG. 23. As will be explained, the "FEATURE.INC" include file contains macro variables that control the code generated by the macros PUBEXT 1312 and EXTCALL 1318, which permits direct designer control over the linkup of procedures without changes to the source code.
The PUBEXT macro 1312 declares an external procedure DELAY in class TIMER with interface version 1.0. The macro name itself declares the procedure to be one that is defined by a PUBLIC_PROC macro that is contained within a separately linked component. These references are to be fixed up by the Product Component Linker (FIG. 36). The PUBEXT macro is described in Section 2.1 of the Line-by-line Description of Macros presented below.
The PUBLIC_PROC macro 1316 defines an external procedure ERRORBEEP in the class BEEP with an interface version 1.0. The macro name itself defines the procedure as able to be referenced in separately linked components that declare it with a PUBEXT macro. The PUBLIC_PROC macro is described in Section 3.1 of the Line-by-line Description of Macros. As will be explained, the class designation is replaced with an absolute library address by the macro prior to compilation or assembly.
The EXTCALL macro 1318 calls the external procedure DELAY assigned to the class TIMER using its declaration in the PUBEXT macro 1312. Since this procedure is defined in a seperately linked component, the reference to it will be fixed up by the Product Component Linker (FIG. 36). The EXTCALL macro is described in Section 1.1 of the Line-by-line Description of Macros.
The END_PROC macro 1320 ends the procedure opened by the PUBLIC_PROC macro 1316. It is described in Section 3.3 of the Line-by-line Description of Macros.
Each object, i.e. a component or feature, has a corresponding information file, which can be represented as a .INF file. The purpose of these information files is to include information required by the BIOS tools, or whatever tools for which the software product being developed is used, that cannot be derived from the tree structure or assembly file scan. A database update process scans these .INF files and the assembly files to gather information and place it into a centralized database.
A component information file (COMPNENT.INF) is included at every component tip. A feature information file (FEATURE.INF) is contained within each subdirectory of a component or feature directory. Since the COMPNENT.INF and FEATURE.INF files are virtually the same, the following description simply refers to them as INF files and only distinguishes between the two types where differences exist. In general, the information in the INF files includes the name of the object and associated libraries or binaries, free flowing descriptive information about the object, the class or subclass to which the object belongs, and option declarations.
Each of the INF files may include one or more commands. These commands preferably are not case sensitive and do not exceed a single line. In addition, it is preferable that only one command exists per line. Comments may be placed on any line by itself, or at the end of any command line by preceding it with an identifier, such as `//`.
The commands that may be used within the body of the INF files may be optional, required, or conditionally required. In addition, some commands may be for only a component information file or a feature information file. Among the optional commands is the BringUp command. This command is used to identify that the object should be included in a platform BIOS identified in the PLATFORM.CFG file as `BringUp.` It is used to assist in quickly configuring a BIOS with the minimal objects needed to boot a motherboard. When this command is added to the PLATFORM.CFG file, only the objects required for booting a system to DOS will be installed in the BIOS.
The Class command is a conditionally required command. It provides the name of the class to which the object belongs. Only one class or subclass per INF file is allowed. An object's public procedures are referenced by their function name prefixed with their class.subclass[.subclass . . . ] path. A component is not required to declare a class. A feature, however, is required to declare a class or subclass if it's parent object declares a class or subclass. In other words, a Class command in a feature information file is conditionally required depending upon if it's parent object declares a class or subclass.
The Classification command applies to component information files only, but is required of all component information files. This command is used for specifying information that allows for sorting and classifying components using, for example, BIOS tools. The Classification command may include one or more field names, such as ComponentType, DeviceVendor, DeviceAlias, PartNumber, and Category.
The value of the ComponentType field name is either hardware or software and is always required in the Classification Command. The DeviceVendor field name defines the vendor and is only required and applicable to hardware component types. The DeviceAlias field name defines a commonly known nickname for the component type and is only optional and applicable to hardware component types. The PartNumber field name defines the component part number and is only required and applicable to hardware component types. The Category field name is used to define the category the device or software component fits into and is optional for both software and hardware component types.
A CompileUsing command is an optional command that identifies a custom compile command to be used in the component's MAKEFILE for the specified extension instead of the default command generated by COMPMAKE. This command includes three fields: Command, SourceExtension, and DestinationExtension. The Command field is, for example, a custom DOS command having parameters identifying where specific file information should be located and parameters for other control information. The SourceExtension field provides a file extension of the source code files that should be effected by the custom command. The DestinationExtension provides a file extension of the destination file being created by the custom command.
A CoreVersion command is a required command that identifies the core versions with which the object is compatible. This command may include one or more values, each representing a compatible core version.
A Description command is a required command and provides a text comment that may be used by high level interfaces to provide details regarding the component, feature or option being described. The description may be up to, for example, 512 characters in length.
A LinkUsing command is an optional command that identifies a custom Link command to be used in the component's MAKEFILE instead of the default command generated by COMPMAKE. Like the CompileUsing command, the LinkUsing command includes a Command field, a SourceExtension field and a DestinationExtension field, which provide the same function as described above.
A Name command is a required command and provides the name of the object. An identifier in the Name command, which specifies the name of the object, may be an alphanumeric string of, for example, 40 characters in length, and preferably does not begin with a number or include spaces.
An Option command is an optional command that declares a configurable option and gives it a default value. The designer can change the setting of the option using the PLATFORM.CFG file. This command supports a `body` section for providing descriptive names of the option's supported values. These names may be used instead of numeric values for declaring the default value or changing the value in the PLATFORM.CFG file. The value name should be defined on a separate line. Exclusion of the body section indicates that only numeric values may be used for setting the value.
In addition to a name field defining the option name, there are several other fields in the Option command. A DefaultValueName field provides a valid `value name` as defined in the body section and is required when value names have been defined in the body section of the command. A Default_numeric_value field provides a valid numeric value that preferably does not exceed the length specified. Numeric values may not be used as a default when enumerated names exist. A Size field specifies the size of the option space. A RomEditDescription field is an option description string that is save in ROM if `Romedit` is chosen by the designer in the PLATFORM.CFG file. A ValueName field is a descriptive name that may be used in place of a numeric value when setting the option's value. A Value field represents the specific numeric value to associate with the ValueName. A ValueDescription field provides a textual description of the value's meaning.
An Owner command is a required command that provides a company name of the object owner. This command is used for filtering a customer's components when releasing or replicating core trees to customer sites.
A PlatformType command is an optional command that describes when an object should be included in a build by default based on the PLATFORM.CFG file's identification of platform type. This command includes a one or more PlatformType fields, each having a corresponding Usage field. The PlatformType field can be, for example, BasicPC, Desktop, Server, Notebook, PICO or AllOthers.
The Usage field is used to describe the conditions for including an object in a build. If it is `Recommended`, an object is brought in by default, but the designer may manually remove the recommended object from the build. If it is `Test`, an object will be included in the build by default for testing purposes, but will be excluded from a product release. `OnDemand` an object is automatically brought in when needed to resolve hard external references. For `Explicit`, an object is prevented from being included in a build for the associated PlatformType unless it is explicitly added in the PLATFORM.CFG file. `External Trigger` identifies the name of a Class.SubClass that will trigger an object to be included in a build
A class may combine `External Trigger` with `OnDemand` or `Recommended` for a single platform type. Any other combination of Usage fields for a single platform type, however, is not allowed and will cause a validation failure. Furthermore, only one object for a single class may declare itself OnDemand, Recommended or Externally Triggered within the core files. Otherwise, having more than one default resolution to a dependency will result in a validation failure. Within a single component, only one feature of a specific subclass may declare itself OnDemand, Recommended or Externally Triggered. Having more than one may result in multiple resolutions to a dependency causing a validation failure.
A ShieldPrivates command is an optional command that protects an object's private procedures from being accessed by its sibling objects. This command is useful for objects that are used as repositories of miscellaneous objects that are not functionally related.
A SubClass command is a conditionally required command that provides the name of a subclass to which a feature belongs. Each INF file is allowed only one class or subclass. An object's public procedures are referenced by their function name prefixed with their class.subclass path. As described above with respect to the Class command, a component is not required to declare a class, but a feature is required to declare a class or subclass if it's parent object declares a class or subclass
A Target command is an optional command applicable to component information files only. This command provides the name of a library or binary that should result from building the particular component. The Target command includes a TargetName field and a TypeKey field. the TargetName field defines a character file name. The TypeKey field is a four character code used to identify files of non-standard types. This code is used by the BIOSMAKE utilities for fixup of dispatch tables referencing these files.
A Uses command is an optional command that is used to identify the location of shared code used by an object being described. The build tools may use this command to identify the file as a dependency in the MAKEFILE created for the object. Use of shared files is restricted. In particular, objects may only use files that identify themselves as shared using, for example, a PRIVATE_PROC or PRIVATE_INCLUDE command with the `Shared` attribute. In addition, an object may only use shared source files that are in sibling directories, or immediate children of upstream directory nodes. The Uses command includes a FilePath field that provides the relative path and filename of the shared file to be used by the object.
FIG. 14 presents the component information file for class CORE 1406 shown at path C:.backslash.BIOS.backslash.CORE.backslash.COMPNENT.INF in Appendix A. This is the component that contains feature BEEP (FIG. 16), which contains the source code file BEEP.ASM (FIG. 13). This part of the present invention contains commands describing the component and commands used in the configuration of the component (FIG. 15).
The BRINGUP command 1412 indicates that this component should be included as part of the configuration when a customer using the present invention begins to build a new BIOS with minimal functionality to get started quickly.
The PLATFORMTYPE command 1424 indicates that this component may be used when building a product that will run on an IA32 architecture. The ALLOTHERS command 1428 indicates that this component is RECOMMENDED for all platform types that were not explicitly specified in the PLATFORMTYPE command 1424. This CORE 1406 component will be included in all configurations produced by the present invention that run on an IA32 architecture unless it is explicitly forced out.
FIG. 15 shows those commands in a component information file of the present invention that are used in the configuration of the component. Names in bold are keywords, and names not in bold are specified by the designer. The characters "//" indicate that the rest of the line is a comment. All commands residing between the braces { } of a command are considered within the scope of the command.
The PLATFORMTYPE command 1506 specifies the rules under which the component will be included in the configuration. The rules apply to a configuration for a specific PlatformType such as "DeskTop" or "NoteBook" or to any PlatformType not explicitly mentioned (ALLOTHERS). The rules 1516 include RECOMMENDED: include component unless explicitly forced out of the configuration, ONDEMAND: include component if a procedure in the component is referenced by another component already in the configuration, EXPLICIT: include component only if explicitly forced into the configuration, and EXTERNALTRIGGER: include this component if the component or feature specified by the ClassPath is in the configuration.
The OPTION command 1522 defines the name and default value of an option that may be used in the source code files comprising a component. It may also define the names of acceptable values for the option that may be specified in the product configuration (FIG. 22)
FIG. 16 presents the feature information file for class BEEP 1602 shown at path C:.backslash.BIOS.backslash.CORE.backslash.BEEP.backslash.FEATURE.INF in Appendix A. This is the feature which contains the source code file BEEP.ASM (FIG. 13). This part of the present invention contains commands describing the feature and commands used in the configuration of the feature (FIG. 17).
The BRINGUP command 1612 indicates that this feature should be included as part of the configuration when a customer using the present invention begins to build a new BIOS with minimal functionality to get started quickly.
The PLATFORMTYPE command 1616 indicates that this feature may be used when building a product that will run on an IA32 architecture. The ALLOTHERS command 1620 indicates that this feature is RECOMMENDED for all platform types that were not explicitly specified in the PLATFORMTYPE command 1616. This BEEP 1602 feature will be included in all configurations produced by the present invention that run on an IA32 architecture and include the CORE component unless it is explicitly forced out.
FIG. 17 shows those commands in a feature information file of the present invention that are used in the configuration of the feature. Names in bold are keywords, and names not in bold are specified by the designer. The characters "//" indicate that the rest of the line is a comment. All commands residing between the braces { } of a command are considered within the scope of the command.
The PLATFORMTYPE command 1706 specifies the rules under which the feature will be included in the configuration. The rules apply to a configuration for a specific PlatformType such as DeskTop or NoteBook or to any PlatformType not explicitly mentioned (ALLOTHERS). The rules include RECOMMENDED: include feature unless explicitly forced out of the configuration, ONDEMAND: include feature if a procedure in the feature is referenced by another component already in the configuration, EXPLICIT: include feature only if explicitly forced into the configuration, and EXTERNALTRIGGER: include this feature if the component or feature specified by the ClassPath is in the configuration.
The OPTION command 1721 defines the name and default value of a manifest constant that may be used in the source code files of the feature. It may also define the names of acceptable values for the option that may be specified in the product configuration (FIG. 22)
The PLATFORM.CFG file is a text file that specifies the customizations to a build and contains statements which direct the build. It is in the PLATFORM.CFG file that OEMs may include information to identify OEM features, OEM hooks, and OEM file overrides. Also, although the PLATFORM.CFG file is maintained by the user interface 200, it is an editable file that allows the designer to explicitly state configuration parameters.
The PLATFORM.CFG file includes a minimal description of the BIOS. Based on this information, the configurator 700 can derive a more comprehensive description of the BIOS configuration. For example, if a designer explicitly declares that a component should be included in the build, the configurator 700 can determine that another component or feature should also be included in the BIOS, even if it has not been explicitly declared within the PLATFORM.CFG file.
There are several commands associated with the PLATFORM.CFG file. A BuildOption command specifies information that is specific to the build of a particular software product. The commands within the body of the BuildOption command specify the details of the information to be stored. These commands include Type, which specifies the type of build option, Name, which specifies the name of the item to which the build option is being applied, and Value, which specifies a value to which the item is being set.
A BringUpBios command is used to indicate a special configuration override. This special override instructs the configurator 700 to build a minimal BIOS containing only the minimal set of elements needed to bring up the minimal BIOS. The BringUpBios command may only appear once in the PLATFORM.CFG file.
A Classification command specifies platform specific information. This information can define a name or value to a series of platform specific data, including a vendor name, an alias, a platform number, a revision or version number, and a category.
A Component command specifies the addition, configuration or removal of any component from the build, regardless of the intended platform type. A component's configuration is defined by Features, Options, SystemOptions, Files and OverrideFiles that are specified within the Component command. When brought in by default based on the designated platform type, the component is not listed in the PLATFORM.CFG file.
The Component command preferably includes a ForceFlag. This flag specifies whether or not a component is forced into a build, forced out of a build, or set to use the default build inclusion dependencies and triggers. When the flag is set to Forceln, it will be merged with any exiting default definitions for the component. When a component is set to NoForce, it will revert to its default state, meaning it will depend on other dependency and trigger selections. When a component is set to ForceOut, it is expressly not included in the build.
Each Component command also includes a name of a component to be brought into the system. The name used in the command is derived from the named component's .INF file. Since each component preferably has a unique name, there should be no ambiguity in the component named in the Component command.
All commands residing within a Component command's braces, which delineate what is included in the Component command, are considered within the scope of the named component. Examples of these commands include the Feature, Option, and SystemOption commands. The components themselves may not be placed inside other components. In addition, the Component command can only appear once for each unique component. In other words, there cannot be two or more Component commands describing the same component.
A Feature command allows the addition, configuration and removal of a feature within a given component. The feature named in the command must be valid for the component within which it resides. Like a component, a feature's configuration is defined by Features, Options, SystemOptions, Files and OverrideFiles that are specified within the Feature command. Furthermore, like the Component command, the Feature command includes a ForceFlag that specifies whether a feature is forced into a build, forced out of a build, or set to use the default build inclusion dependencies and triggers.
Although all features must reside within a component definition, features may be defined within the definition of another feature. When a feature is specified inside another feature, the internal feature becomes the child feature and the external one becomes the parent feature. All commands within a feature are considered within the scope of that feature and also within the scope of the component under which the feature is defined. Examples of commands or statements that can be placed inside a feature's braces, which delineate what is included in the Feature command, include Feature, Option, SystemOption, File and OverrideFile.
A File command allows an additional file to be included within a build. This command may only be used within the scope of a component or feature. Parameters included in the File command include a FileName and a FilePath. The FileName defines the name of the file to be brought into a build. The FilePath provides for the relative physical location of a file to be brought into a build.
An Option command specifies the setting of an option that will be used to generate component and feature include files. The Option command may only be used within the scope of a component or feature. Parameters included in the Option command include a Name, a Value, a RomEditFlag, and a Description. The Name parameter defines the name of an option to change. The Value parameter sets forth any valid value as defined by the option in the .INF file. The RomEditFlag parameter is a Boolean value, which sets forth whether or not a RomEdit is enabled for the option. The Description parameter is an option parameter that provides a description of the option that may be displayed in the RomEdit utility.
An OverrideFile command overrides a component file. A file version allows a warning to be displayed to a designer if the override is stale. This command may only be used within the scope of a component or feature. The name of the new overriding file must be identical to the file being overridden. The parameters in the OverrideFile command include a FileName, which provides the name of the override file, a NewPath, which provides the relative physical path of the override file, and an OriginalVersion, which provides a version of the original file.
A PlatformType command specifies a type of platform for the build. This command is used to bring in default components and features based on the specified platform type. Only one PlatformType command may be used in the PLATFORM.CFG file. Parameters in the PlatformType command include a Name, which defines the name of the platform, and an Architecture, which is determined by the CPU and instruction set and specifies a group of systems that will execute the same code. The Architecture parameter may be, for example, IA32 for the IA-32 instruction set architecture or IA64 for the IA-64 instruction set architecture.
A SystemOption command is used to establish an option that is visible across the entire scope of the build description. Predefined options may be set and reset at different levels of processing, such as a global level, a component level, or feature level. Parameters in the SystemOption command include a Name and a Value. The Name parameter gives the name of the SystemOption to be associated with the build description. The name must be one of a set of pre-defined Options. The Value parameter sets forth a value to associate with the named SystemOption.
FIG. 18 presents symbolically a representation of the component database 1800 for a source library A. The data for each component is shown contained within a rectangle. Two components, component A 1802 and component B 1804, are shown, with others assumedly also present but mmitted for clarity and simplicity. Only the details of the data for the component A 1802 is shown.
Each component has a name and a description (line 1806). Each component has a data options table, which is a table that lists all the user-settable options 1808 that affect source code filess within this component. These options are adjusted through use of the user interface (see FIG. 33E, for example), and the option values are actually loaded into the binary image by the product component linker 3600 (FIG. 36) as part of the "fix-up" process when the linker 3600 builds te finished product 1106. Any compilation, assembly, and link options 1810 that are specified for a component are present.
A component may be assigned to a class by its "component.inf" file if its directory contains source code files, but the present practice with the preferred embodiment is to place source code files into feature subdirectories and to have each feature assigned to a class by its "feature.inf" file. Accordingly, every feature is definitely assigned to a class. The several features may therefore be organized by class within the database, as shown. Two classes, class A 1812 and class B 1814, are shown. Within the class A 1812 are two features, feature 11816 and feature 21818 (no details are shown for feature 2). Presumably, any normal system could have many features, as well as sub-features, etc. The featre 11816 has a name and description 1820, a data options table 1822 (essentially the same as that for the component but applicable to the feature source code files), compiler and link opt |