| \input texinfo @c -*-texinfo-*- |
| @c %**start of header |
| |
| @c oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo |
| @c o |
| @c GNAT DOCUMENTATION o |
| @c o |
| @c G N A T _ U G N o |
| @c o |
| @c Copyright (C) 1992-2006, AdaCore o |
| @c o |
| @c GNAT is free software; you can redistribute it and/or modify it under o |
| @c terms of the GNU General Public License as published by the Free Soft- o |
| @c ware Foundation; either version 2, or (at your option) any later ver- o |
| @c sion. GNAT is distributed in the hope that it will be useful, but WITH- o |
| @c OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY o |
| @c or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License o |
| @c for more details. You should have received a copy of the GNU General o |
| @c Public License distributed with GNAT; see file COPYING. If not, write o |
| @c to the Free Software Foundation, 51 Franklin Street, Fifth Floor, o |
| @c Boston, MA 02110-1301, USA. o |
| @c o |
| @c oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo |
| |
| @c oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo |
| @c |
| @c GNAT_UGN Style Guide |
| @c |
| @c 1. Always put a @noindent on the line before the first paragraph |
| @c after any of these commands: |
| @c |
| @c @chapter |
| @c @section |
| @c @subsection |
| @c @subsubsection |
| @c @subsubsubsection |
| @c |
| @c @end smallexample |
| @c @end itemize |
| @c @end enumerate |
| @c |
| @c 2. DO NOT use @example. Use @smallexample instead. |
| @c a) DO NOT use highlighting commands (@b{}, @i{}) inside an @smallexample |
| @c context. These can interfere with the readability of the texi |
| @c source file. Instead, use one of the following annotated |
| @c @smallexample commands, and preprocess the texi file with the |
| @c ada2texi tool (which generates appropriate highlighting): |
| @c @smallexample @c ada |
| @c @smallexample @c adanocomment |
| @c @smallexample @c projectfile |
| @c b) The "@c ada" markup will result in boldface for reserved words |
| @c and italics for comments |
| @c c) The "@c adanocomment" markup will result only in boldface for |
| @c reserved words (comments are left alone) |
| @c d) The "@c projectfile" markup is like "@c ada" except that the set |
| @c of reserved words include the new reserved words for project files |
| @c |
| @c 3. Each @chapter, @section, @subsection, @subsubsection, etc. |
| @c command must be preceded by two empty lines |
| @c |
| @c 4. The @item command should be on a line of its own if it is in an |
| @c @itemize or @enumerate command. |
| @c |
| @c 5. When talking about ALI files use "ALI" (all uppercase), not "Ali" |
| @c or "ali". |
| @c |
| @c 6. DO NOT put trailing spaces at the end of a line. Such spaces will |
| @c cause the document build to fail. |
| @c |
| @c 7. DO NOT use @cartouche for examples that are longer than around 10 lines. |
| @c This command inhibits page breaks, so long examples in a @cartouche can |
| @c lead to large, ugly patches of empty space on a page. |
| @c |
| @c NOTE: This file should be submitted to xgnatugn with either the vms flag |
| @c or the unw flag set. The unw flag covers topics for both Unix and |
| @c Windows. |
| @c |
| @c oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo |
| |
| @ifset vms |
| @setfilename gnat_ugn_vms.info |
| @end ifset |
| |
| @ifset unw |
| @setfilename gnat_ugn_unw.info |
| @end ifset |
| |
| @set FSFEDITION |
| @set EDITION GNAT |
| |
| @ifset unw |
| @set PLATFORM |
| @set FILE gnat_ugn_unw |
| @end ifset |
| |
| @ifset vms |
| @set PLATFORM OpenVMS |
| @set FILE gnat_ugn_vms |
| @end ifset |
| |
| @settitle @value{EDITION} User's Guide @value{PLATFORM} |
| @dircategory GNU Ada tools |
| @direntry |
| * @value{EDITION} User's Guide (@value{FILE}) @value{PLATFORM} |
| @end direntry |
| |
| @include gcc-common.texi |
| |
| @setchapternewpage odd |
| @syncodeindex fn cp |
| @c %**end of header |
| |
| @copying |
| Copyright @copyright{} 1995-2005, Free Software Foundation |
| |
| Permission is granted to copy, distribute and/or modify this document |
| under the terms of the GNU Free Documentation License, Version 1.2 |
| or any later version published by the Free Software Foundation; |
| with the Invariant Sections being ``GNU Free Documentation License'', with the |
| Front-Cover Texts being |
| ``@value{EDITION} User's Guide'', |
| and with no Back-Cover Texts. |
| A copy of the license is included in the section entitled |
| ``GNU Free Documentation License''. |
| @end copying |
| |
| @titlepage |
| @title @value{EDITION} User's Guide |
| @ifset vms |
| @sp 1 |
| @flushright |
| @titlefont{@i{@value{PLATFORM}}} |
| @end flushright |
| @end ifset |
| @subtitle GNAT, The GNU Ada 95 Compiler |
| @versionsubtitle |
| @author Ada Core Technologies, Inc. |
| @page |
| @vskip 0pt plus 1filll |
| |
| @insertcopying |
| |
| @end titlepage |
| |
| @ifnottex |
| @node Top, About This Guide, (dir), (dir) |
| @top @value{EDITION} User's Guide |
| |
| @noindent |
| @value{EDITION} User's Guide @value{PLATFORM} |
| |
| @noindent |
| GNAT, The GNU Ada 95 Compiler@* |
| GCC version @value{version-GCC}@* |
| |
| @noindent |
| AdaCore@* |
| |
| @menu |
| * About This Guide:: |
| * Getting Started with GNAT:: |
| * The GNAT Compilation Model:: |
| * Compiling Using gcc:: |
| * Binding Using gnatbind:: |
| * Linking Using gnatlink:: |
| * The GNAT Make Program gnatmake:: |
| * Improving Performance:: |
| * Renaming Files Using gnatchop:: |
| * Configuration Pragmas:: |
| * Handling Arbitrary File Naming Conventions Using gnatname:: |
| * GNAT Project Manager:: |
| * The Cross-Referencing Tools gnatxref and gnatfind:: |
| * The GNAT Pretty-Printer gnatpp:: |
| * The GNAT Metric Tool gnatmetric:: |
| * File Name Krunching Using gnatkr:: |
| * Preprocessing Using gnatprep:: |
| @ifset vms |
| * The GNAT Run-Time Library Builder gnatlbr:: |
| @end ifset |
| * The GNAT Library Browser gnatls:: |
| * Cleaning Up Using gnatclean:: |
| @ifclear vms |
| * GNAT and Libraries:: |
| * Using the GNU make Utility:: |
| @end ifclear |
| * Memory Management Issues:: |
| * Stack Related Facilities:: |
| * Verifying properties using gnatcheck:: |
| * Creating Sample Bodies Using gnatstub:: |
| * Other Utility Programs:: |
| * Running and Debugging Ada Programs:: |
| @ifset vms |
| * Compatibility with HP Ada:: |
| @end ifset |
| * Platform-Specific Information for the Run-Time Libraries:: |
| * Example of Binder Output File:: |
| * Elaboration Order Handling in GNAT:: |
| * Inline Assembler:: |
| * Compatibility and Porting Guide:: |
| @ifset unw |
| * Microsoft Windows Topics:: |
| @end ifset |
| * GNU Free Documentation License:: |
| * Index:: |
| |
| --- The Detailed Node Listing --- |
| |
| About This Guide |
| |
| * What This Guide Contains:: |
| * What You Should Know before Reading This Guide:: |
| * Related Information:: |
| * Conventions:: |
| |
| Getting Started with GNAT |
| |
| * Running GNAT:: |
| * Running a Simple Ada Program:: |
| * Running a Program with Multiple Units:: |
| * Using the gnatmake Utility:: |
| @ifset vms |
| * Editing with Emacs:: |
| @end ifset |
| @ifclear vms |
| * Introduction to GPS:: |
| * Introduction to Glide and GVD:: |
| @end ifclear |
| |
| The GNAT Compilation Model |
| |
| * Source Representation:: |
| * Foreign Language Representation:: |
| * File Naming Rules:: |
| * Using Other File Names:: |
| * Alternative File Naming Schemes:: |
| * Generating Object Files:: |
| * Source Dependencies:: |
| * The Ada Library Information Files:: |
| * Binding an Ada Program:: |
| * Mixed Language Programming:: |
| @ifclear vms |
| * Building Mixed Ada & C++ Programs:: |
| * Comparison between GNAT and C/C++ Compilation Models:: |
| @end ifclear |
| * Comparison between GNAT and Conventional Ada Library Models:: |
| @ifset vms |
| * Placement of temporary files:: |
| @end ifset |
| |
| Foreign Language Representation |
| |
| * Latin-1:: |
| * Other 8-Bit Codes:: |
| * Wide Character Encodings:: |
| |
| Compiling Ada Programs With gcc |
| |
| * Compiling Programs:: |
| * Switches for gcc:: |
| * Search Paths and the Run-Time Library (RTL):: |
| * Order of Compilation Issues:: |
| * Examples:: |
| |
| Switches for gcc |
| |
| * Output and Error Message Control:: |
| * Warning Message Control:: |
| * Debugging and Assertion Control:: |
| * Validity Checking:: |
| * Style Checking:: |
| * Run-Time Checks:: |
| * Using gcc for Syntax Checking:: |
| * Using gcc for Semantic Checking:: |
| * Compiling Different Versions of Ada:: |
| * Character Set Control:: |
| * File Naming Control:: |
| * Subprogram Inlining Control:: |
| * Auxiliary Output Control:: |
| * Debugging Control:: |
| * Exception Handling Control:: |
| * Units to Sources Mapping Files:: |
| * Integrated Preprocessing:: |
| @ifset vms |
| * Return Codes:: |
| @end ifset |
| |
| Binding Ada Programs With gnatbind |
| |
| * Running gnatbind:: |
| * Switches for gnatbind:: |
| * Command-Line Access:: |
| * Search Paths for gnatbind:: |
| * Examples of gnatbind Usage:: |
| |
| Switches for gnatbind |
| |
| * Consistency-Checking Modes:: |
| * Binder Error Message Control:: |
| * Elaboration Control:: |
| * Output Control:: |
| * Binding with Non-Ada Main Programs:: |
| * Binding Programs with No Main Subprogram:: |
| |
| Linking Using gnatlink |
| |
| * Running gnatlink:: |
| * Switches for gnatlink:: |
| |
| The GNAT Make Program gnatmake |
| |
| * Running gnatmake:: |
| * Switches for gnatmake:: |
| * Mode Switches for gnatmake:: |
| * Notes on the Command Line:: |
| * How gnatmake Works:: |
| * Examples of gnatmake Usage:: |
| |
| Improving Performance |
| * Performance Considerations:: |
| * Reducing the Size of Ada Executables with gnatelim:: |
| * Reducing the Size of Executables with unused subprogram/data elimination:: |
| |
| Performance Considerations |
| * Controlling Run-Time Checks:: |
| * Use of Restrictions:: |
| * Optimization Levels:: |
| * Debugging Optimized Code:: |
| * Inlining of Subprograms:: |
| * Other Optimization Switches:: |
| * Optimization and Strict Aliasing:: |
| @ifset vms |
| * Coverage Analysis:: |
| @end ifset |
| |
| Reducing the Size of Ada Executables with gnatelim |
| * About gnatelim:: |
| * Running gnatelim:: |
| * Correcting the List of Eliminate Pragmas:: |
| * Making Your Executables Smaller:: |
| * Summary of the gnatelim Usage Cycle:: |
| |
| Reducing the Size of Executables with unused subprogram/data elimination |
| * About unused subprogram/data elimination:: |
| * Compilation options:: |
| |
| Renaming Files Using gnatchop |
| |
| * Handling Files with Multiple Units:: |
| * Operating gnatchop in Compilation Mode:: |
| * Command Line for gnatchop:: |
| * Switches for gnatchop:: |
| * Examples of gnatchop Usage:: |
| |
| Configuration Pragmas |
| |
| * Handling of Configuration Pragmas:: |
| * The Configuration Pragmas Files:: |
| |
| Handling Arbitrary File Naming Conventions Using gnatname |
| |
| * Arbitrary File Naming Conventions:: |
| * Running gnatname:: |
| * Switches for gnatname:: |
| * Examples of gnatname Usage:: |
| |
| GNAT Project Manager |
| |
| * Introduction:: |
| * Examples of Project Files:: |
| * Project File Syntax:: |
| * Objects and Sources in Project Files:: |
| * Importing Projects:: |
| * Project Extension:: |
| * Project Hierarchy Extension:: |
| * External References in Project Files:: |
| * Packages in Project Files:: |
| * Variables from Imported Projects:: |
| * Naming Schemes:: |
| * Library Projects:: |
| * Stand-alone Library Projects:: |
| * Switches Related to Project Files:: |
| * Tools Supporting Project Files:: |
| * An Extended Example:: |
| * Project File Complete Syntax:: |
| |
| The Cross-Referencing Tools gnatxref and gnatfind |
| |
| * gnatxref Switches:: |
| * gnatfind Switches:: |
| * Project Files for gnatxref and gnatfind:: |
| * Regular Expressions in gnatfind and gnatxref:: |
| * Examples of gnatxref Usage:: |
| * Examples of gnatfind Usage:: |
| |
| The GNAT Pretty-Printer gnatpp |
| |
| * Switches for gnatpp:: |
| * Formatting Rules:: |
| |
| The GNAT Metrics Tool gnatmetric |
| |
| * Switches for gnatmetric:: |
| |
| File Name Krunching Using gnatkr |
| |
| * About gnatkr:: |
| * Using gnatkr:: |
| * Krunching Method:: |
| * Examples of gnatkr Usage:: |
| |
| Preprocessing Using gnatprep |
| |
| * Using gnatprep:: |
| * Switches for gnatprep:: |
| * Form of Definitions File:: |
| * Form of Input Text for gnatprep:: |
| |
| @ifset vms |
| The GNAT Run-Time Library Builder gnatlbr |
| |
| * Running gnatlbr:: |
| * Switches for gnatlbr:: |
| * Examples of gnatlbr Usage:: |
| @end ifset |
| |
| The GNAT Library Browser gnatls |
| |
| * Running gnatls:: |
| * Switches for gnatls:: |
| * Examples of gnatls Usage:: |
| |
| Cleaning Up Using gnatclean |
| |
| * Running gnatclean:: |
| * Switches for gnatclean:: |
| @c * Examples of gnatclean Usage:: |
| |
| @ifclear vms |
| |
| GNAT and Libraries |
| |
| * Introduction to Libraries in GNAT:: |
| * General Ada Libraries:: |
| * Stand-alone Ada Libraries:: |
| * Rebuilding the GNAT Run-Time Library:: |
| |
| Using the GNU make Utility |
| |
| * Using gnatmake in a Makefile:: |
| * Automatically Creating a List of Directories:: |
| * Generating the Command Line Switches:: |
| * Overcoming Command Line Length Limits:: |
| @end ifclear |
| |
| Memory Management Issues |
| |
| * Some Useful Memory Pools:: |
| * The GNAT Debug Pool Facility:: |
| @ifclear vms |
| * The gnatmem Tool:: |
| @end ifclear |
| |
| Stack Related Facilities |
| |
| * Stack Overflow Checking:: |
| * Static Stack Usage Analysis:: |
| * Dynamic Stack Usage Analysis:: |
| |
| Some Useful Memory Pools |
| |
| The GNAT Debug Pool Facility |
| |
| @ifclear vms |
| The gnatmem Tool |
| |
| * Running gnatmem:: |
| * Switches for gnatmem:: |
| * Example of gnatmem Usage:: |
| @end ifclear |
| |
| Verifying properties using gnatcheck |
| |
| * Format of the Report File:: |
| * General gnatcheck Switches:: |
| * gnatcheck Rule Options:: |
| * Add the Results of Compiler Checks to gnatcheck Output:: |
| |
| Sample Bodies Using gnatstub |
| |
| * Running gnatstub:: |
| * Switches for gnatstub:: |
| |
| Other Utility Programs |
| |
| * Using Other Utility Programs with GNAT:: |
| * The External Symbol Naming Scheme of GNAT:: |
| @ifclear vms |
| * Ada Mode for Glide:: |
| @end ifclear |
| * Converting Ada Files to html with gnathtml:: |
| |
| Running and Debugging Ada Programs |
| |
| * The GNAT Debugger GDB:: |
| * Running GDB:: |
| * Introduction to GDB Commands:: |
| * Using Ada Expressions:: |
| * Calling User-Defined Subprograms:: |
| * Using the Next Command in a Function:: |
| * Ada Exceptions:: |
| * Ada Tasks:: |
| * Debugging Generic Units:: |
| * GNAT Abnormal Termination or Failure to Terminate:: |
| * Naming Conventions for GNAT Source Files:: |
| * Getting Internal Debugging Information:: |
| * Stack Traceback:: |
| |
| @ifset vms |
| * LSE:: |
| @end ifset |
| |
| @ifset vms |
| Compatibility with HP Ada |
| |
| * Ada 95 Compatibility:: |
| * Differences in the Definition of Package System:: |
| * Language-Related Features:: |
| * The Package STANDARD:: |
| * The Package SYSTEM:: |
| * Tasking and Task-Related Features:: |
| * Pragmas and Pragma-Related Features:: |
| * Library of Predefined Units:: |
| * Bindings:: |
| * Main Program Definition:: |
| * Implementation-Defined Attributes:: |
| * Compiler and Run-Time Interfacing:: |
| * Program Compilation and Library Management:: |
| * Input-Output:: |
| * Implementation Limits:: |
| * Tools and Utilities:: |
| |
| Language-Related Features |
| |
| * Integer Types and Representations:: |
| * Floating-Point Types and Representations:: |
| * Pragmas Float_Representation and Long_Float:: |
| * Fixed-Point Types and Representations:: |
| * Record and Array Component Alignment:: |
| * Address Clauses:: |
| * Other Representation Clauses:: |
| |
| Tasking and Task-Related Features |
| |
| * Implementation of Tasks in HP Ada for OpenVMS Alpha Systems:: |
| * Assigning Task IDs:: |
| * Task IDs and Delays:: |
| * Task-Related Pragmas:: |
| * Scheduling and Task Priority:: |
| * The Task Stack:: |
| * External Interrupts:: |
| |
| Pragmas and Pragma-Related Features |
| |
| * Restrictions on the Pragma INLINE:: |
| * Restrictions on the Pragma INTERFACE:: |
| * Restrictions on the Pragma SYSTEM_NAME:: |
| |
| Library of Predefined Units |
| |
| * Changes to DECLIB:: |
| |
| Bindings |
| |
| * Shared Libraries and Options Files:: |
| * Interfaces to C:: |
| @end ifset |
| |
| Platform-Specific Information for the Run-Time Libraries |
| |
| * Summary of Run-Time Configurations:: |
| * Specifying a Run-Time Library:: |
| * Choosing the Scheduling Policy:: |
| * Solaris-Specific Considerations:: |
| * Linux-Specific Considerations:: |
| * AIX-Specific Considerations:: |
| |
| Example of Binder Output File |
| |
| Elaboration Order Handling in GNAT |
| |
| * Elaboration Code in Ada 95:: |
| * Checking the Elaboration Order in Ada 95:: |
| * Controlling the Elaboration Order in Ada 95:: |
| * Controlling Elaboration in GNAT - Internal Calls:: |
| * Controlling Elaboration in GNAT - External Calls:: |
| * Default Behavior in GNAT - Ensuring Safety:: |
| * Treatment of Pragma Elaborate:: |
| * Elaboration Issues for Library Tasks:: |
| * Mixing Elaboration Models:: |
| * What to Do If the Default Elaboration Behavior Fails:: |
| * Elaboration for Access-to-Subprogram Values:: |
| * Summary of Procedures for Elaboration Control:: |
| * Other Elaboration Order Considerations:: |
| |
| Inline Assembler |
| |
| * Basic Assembler Syntax:: |
| * A Simple Example of Inline Assembler:: |
| * Output Variables in Inline Assembler:: |
| * Input Variables in Inline Assembler:: |
| * Inlining Inline Assembler Code:: |
| * Other Asm Functionality:: |
| |
| Compatibility and Porting Guide |
| |
| * Compatibility with Ada 83:: |
| * Implementation-dependent characteristics:: |
| @ifclear vms |
| @c This brief section is only in the non-VMS version |
| @c The complete chapter on HP Ada issues is in the VMS version |
| * Compatibility with HP Ada 83:: |
| @end ifclear |
| * Compatibility with Other Ada 95 Systems:: |
| * Representation Clauses:: |
| @ifset vms |
| * Transitioning from Alpha to I64 OpenVMS:: |
| @end ifset |
| |
| @ifset unw |
| Microsoft Windows Topics |
| |
| * Using GNAT on Windows:: |
| * CONSOLE and WINDOWS subsystems:: |
| * Temporary Files:: |
| * Mixed-Language Programming on Windows:: |
| * Windows Calling Conventions:: |
| * Introduction to Dynamic Link Libraries (DLLs):: |
| * Using DLLs with GNAT:: |
| * Building DLLs with GNAT:: |
| * GNAT and Windows Resources:: |
| * Debugging a DLL:: |
| * Setting Stack Size from gnatlink:: |
| * Setting Heap Size from gnatlink:: |
| @end ifset |
| |
| * Index:: |
| @end menu |
| @end ifnottex |
| |
| @node About This Guide |
| @unnumbered About This Guide |
| |
| @noindent |
| @ifset vms |
| This guide describes the use of @value{EDITION}, |
| a full language compiler for the Ada |
| 95 programming language, implemented on OpenVMS for HP's Alpha and |
| Integrity server (I64) platforms. |
| @end ifset |
| @ifclear vms |
| This guide describes the use of @value{EDITION}, |
| a compiler and software development |
| toolset for the full Ada 95 programming language. |
| @end ifclear |
| It describes the features of the compiler and tools, and details |
| how to use them to build Ada 95 applications. |
| |
| @ifset PROEDITION |
| For ease of exposition, ``GNAT Pro'' will be referred to simply as |
| ``GNAT'' in the remainder of this document. |
| @end ifset |
| |
| @menu |
| * What This Guide Contains:: |
| * What You Should Know before Reading This Guide:: |
| * Related Information:: |
| * Conventions:: |
| @end menu |
| |
| @node What This Guide Contains |
| @unnumberedsec What This Guide Contains |
| |
| @noindent |
| This guide contains the following chapters: |
| @itemize @bullet |
| |
| @item |
| @ref{Getting Started with GNAT}, describes how to get started compiling |
| and running Ada programs with the GNAT Ada programming environment. |
| @item |
| @ref{The GNAT Compilation Model}, describes the compilation model used |
| by GNAT. |
| |
| @item |
| @ref{Compiling Using gcc}, describes how to compile |
| Ada programs with @command{gcc}, the Ada compiler. |
| |
| @item |
| @ref{Binding Using gnatbind}, describes how to |
| perform binding of Ada programs with @code{gnatbind}, the GNAT binding |
| utility. |
| |
| @item |
| @ref{Linking Using gnatlink}, |
| describes @command{gnatlink}, a |
| program that provides for linking using the GNAT run-time library to |
| construct a program. @command{gnatlink} can also incorporate foreign language |
| object units into the executable. |
| |
| @item |
| @ref{The GNAT Make Program gnatmake}, describes @command{gnatmake}, a |
| utility that automatically determines the set of sources |
| needed by an Ada compilation unit, and executes the necessary compilations |
| binding and link. |
| |
| @item |
| @ref{Improving Performance}, shows various techniques for making your |
| Ada program run faster or take less space. |
| It discusses the effect of the compiler's optimization switch and |
| also describes the @command{gnatelim} tool and unused subprogram/data |
| elimination. |
| |
| @item |
| @ref{Renaming Files Using gnatchop}, describes |
| @code{gnatchop}, a utility that allows you to preprocess a file that |
| contains Ada source code, and split it into one or more new files, one |
| for each compilation unit. |
| |
| @item |
| @ref{Configuration Pragmas}, describes the configuration pragmas |
| handled by GNAT. |
| |
| @item |
| @ref{Handling Arbitrary File Naming Conventions Using gnatname}, |
| shows how to override the default GNAT file naming conventions, |
| either for an individual unit or globally. |
| |
| @item |
| @ref{GNAT Project Manager}, describes how to use project files |
| to organize large projects. |
| |
| @item |
| @ref{The Cross-Referencing Tools gnatxref and gnatfind}, discusses |
| @code{gnatxref} and @code{gnatfind}, two tools that provide an easy |
| way to navigate through sources. |
| |
| @item |
| @ref{The GNAT Pretty-Printer gnatpp}, shows how to produce a reformatted |
| version of an Ada source file with control over casing, indentation, |
| comment placement, and other elements of program presentation style. |
| |
| @item |
| @ref{The GNAT Metric Tool gnatmetric}, shows how to compute various |
| metrics for an Ada source file, such as the number of types and subprograms, |
| and assorted complexity measures. |
| |
| @item |
| @ref{File Name Krunching Using gnatkr}, describes the @code{gnatkr} |
| file name krunching utility, used to handle shortened |
| file names on operating systems with a limit on the length of names. |
| |
| @item |
| @ref{Preprocessing Using gnatprep}, describes @code{gnatprep}, a |
| preprocessor utility that allows a single source file to be used to |
| generate multiple or parameterized source files, by means of macro |
| substitution. |
| |
| @ifset vms |
| @item |
| @ref{The GNAT Run-Time Library Builder gnatlbr}, describes @command{gnatlbr}, |
| a tool for rebuilding the GNAT run time with user-supplied |
| configuration pragmas. |
| @end ifset |
| |
| @item |
| @ref{The GNAT Library Browser gnatls}, describes @code{gnatls}, a |
| utility that displays information about compiled units, including dependences |
| on the corresponding sources files, and consistency of compilations. |
| |
| @item |
| @ref{Cleaning Up Using gnatclean}, describes @code{gnatclean}, a utility |
| to delete files that are produced by the compiler, binder and linker. |
| |
| @ifclear vms |
| @item |
| @ref{GNAT and Libraries}, describes the process of creating and using |
| Libraries with GNAT. It also describes how to recompile the GNAT run-time |
| library. |
| |
| @item |
| @ref{Using the GNU make Utility}, describes some techniques for using |
| the GNAT toolset in Makefiles. |
| @end ifclear |
| |
| @item |
| @ref{Memory Management Issues}, describes some useful predefined storage pools |
| and in particular the GNAT Debug Pool facility, which helps detect incorrect |
| memory references. |
| @ifclear vms |
| It also describes @command{gnatmem}, a utility that monitors dynamic |
| allocation and deallocation and helps detect ``memory leaks''. |
| @end ifclear |
| |
| @item |
| @ref{Stack Related Facilities}, describes some useful tools associated with |
| stack checking and analysis. |
| |
| @item |
| @ref{Verifying properties using gnatcheck}, discusses @code{gnatcheck}, |
| a utility that checks Ada code against a set of rules. |
| |
| @item |
| @ref{Creating Sample Bodies Using gnatstub}, discusses @code{gnatstub}, |
| a utility that generates empty but compilable bodies for library units. |
| |
| @item |
| @ref{Other Utility Programs}, discusses several other GNAT utilities, |
| including @code{gnathtml}. |
| |
| @item |
| @ref{Running and Debugging Ada Programs}, describes how to run and debug |
| Ada programs. |
| |
| @ifset vms |
| @item |
| @ref{Compatibility with HP Ada}, details the compatibility of GNAT with |
| HP Ada 83 @footnote{``HP Ada'' refers to the legacy product originally |
| developed by Digital Equipment Corporation and currently supported by HP.} |
| for OpenVMS Alpha. This product was formerly known as DEC Ada, |
| @cindex DEC Ada |
| and for |
| historical compatibility reasons, the relevant libraries still use the |
| DEC prefix. |
| @end ifset |
| |
| @item |
| @ref{Platform-Specific Information for the Run-Time Libraries}, |
| describes the various run-time |
| libraries supported by GNAT on various platforms and explains how to |
| choose a particular library. |
| |
| @item |
| @ref{Example of Binder Output File}, shows the source code for the binder |
| output file for a sample program. |
| |
| @item |
| @ref{Elaboration Order Handling in GNAT}, describes how GNAT helps |
| you deal with elaboration order issues. |
| |
| @item |
| @ref{Inline Assembler}, shows how to use the inline assembly facility |
| in an Ada program. |
| |
| @item |
| @ref{Compatibility and Porting Guide}, includes sections on compatibility |
| of GNAT with other Ada 83 and Ada 95 compilation systems, to assist |
| in porting code from other environments. |
| |
| @ifset unw |
| @item |
| @ref{Microsoft Windows Topics}, presents information relevant to the |
| Microsoft Windows platform. |
| @end ifset |
| @end itemize |
| |
| @c ************************************************* |
| @node What You Should Know before Reading This Guide |
| @c ************************************************* |
| @unnumberedsec What You Should Know before Reading This Guide |
| |
| @cindex Ada 95 Language Reference Manual |
| @noindent |
| This user's guide assumes that you are familiar with Ada 95 language, as |
| described in the International Standard ANSI/ISO/IEC-8652:1995, January |
| 1995. |
| |
| @node Related Information |
| @unnumberedsec Related Information |
| |
| @noindent |
| For further information about related tools, refer to the following |
| documents: |
| |
| @itemize @bullet |
| @item |
| @cite{GNAT Reference Manual}, which contains all reference |
| material for the GNAT implementation of Ada 95. |
| |
| @ifset unw |
| @item |
| @cite{Using the GNAT Programming System}, which describes the GPS |
| integrated development environment. |
| |
| @item |
| @cite{GNAT Programming System Tutorial}, which introduces the |
| main GPS features through examples. |
| @end ifset |
| |
| @item |
| @cite{Ada 95 Language Reference Manual}, which contains all reference |
| material for the Ada 95 programming language. |
| |
| @item |
| @cite{Debugging with GDB} |
| @ifset vms |
| , located in the GNU:[DOCS] directory, |
| @end ifset |
| contains all details on the use of the GNU source-level debugger. |
| |
| @item |
| @cite{GNU Emacs Manual} |
| @ifset vms |
| , located in the GNU:[DOCS] directory if the EMACS kit is installed, |
| @end ifset |
| contains full information on the extensible editor and programming |
| environment Emacs. |
| |
| @end itemize |
| |
| @c ************** |
| @node Conventions |
| @unnumberedsec Conventions |
| @cindex Conventions |
| @cindex Typographical conventions |
| |
| @noindent |
| Following are examples of the typographical and graphic conventions used |
| in this guide: |
| |
| @itemize @bullet |
| @item |
| @code{Functions}, @code{utility program names}, @code{standard names}, |
| and @code{classes}. |
| |
| @item |
| @samp{Option flags} |
| |
| @item |
| @file{File Names}, @file{button names}, and @file{field names}. |
| |
| @item |
| @var{Variables}. |
| |
| @item |
| @emph{Emphasis}. |
| |
| @item |
| [optional information or parameters] |
| |
| @item |
| Examples are described by text |
| @smallexample |
| and then shown this way. |
| @end smallexample |
| @end itemize |
| |
| @noindent |
| Commands that are entered by the user are preceded in this manual by the |
| characters @w{``@code{$ }''} (dollar sign followed by space). If your system |
| uses this sequence as a prompt, then the commands will appear exactly as |
| you see them in the manual. If your system uses some other prompt, then |
| the command will appear with the @code{$} replaced by whatever prompt |
| character you are using. |
| |
| @ifset unw |
| Full file names are shown with the ``@code{/}'' character |
| as the directory separator; e.g., @file{parent-dir/subdir/myfile.adb}. |
| If you are using GNAT on a Windows platform, please note that |
| the ``@code{\}'' character should be used instead. |
| @end ifset |
| |
| @c **************************** |
| @node Getting Started with GNAT |
| @chapter Getting Started with GNAT |
| |
| @noindent |
| This chapter describes some simple ways of using GNAT to build |
| executable Ada programs. |
| @ifset unw |
| @ref{Running GNAT}, through @ref{Using the gnatmake Utility}, |
| show how to use the command line environment. |
| @ref{Introduction to Glide and GVD}, provides a brief |
| introduction to the visually-oriented IDE for GNAT. |
| Supplementing Glide on some platforms is GPS, the |
| GNAT Programming System, which offers a richer graphical |
| ``look and feel'', enhanced configurability, support for |
| development in other programming language, comprehensive |
| browsing features, and many other capabilities. |
| For information on GPS please refer to |
| @cite{Using the GNAT Programming System}. |
| @end ifset |
| |
| @menu |
| * Running GNAT:: |
| * Running a Simple Ada Program:: |
| * Running a Program with Multiple Units:: |
| * Using the gnatmake Utility:: |
| @ifset vms |
| * Editing with Emacs:: |
| @end ifset |
| @ifclear vms |
| * Introduction to GPS:: |
| * Introduction to Glide and GVD:: |
| @end ifclear |
| @end menu |
| |
| @node Running GNAT |
| @section Running GNAT |
| |
| @noindent |
| Three steps are needed to create an executable file from an Ada source |
| file: |
| |
| @enumerate |
| @item |
| The source file(s) must be compiled. |
| @item |
| The file(s) must be bound using the GNAT binder. |
| @item |
| All appropriate object files must be linked to produce an executable. |
| @end enumerate |
| |
| @noindent |
| All three steps are most commonly handled by using the @command{gnatmake} |
| utility program that, given the name of the main program, automatically |
| performs the necessary compilation, binding and linking steps. |
| |
| @node Running a Simple Ada Program |
| @section Running a Simple Ada Program |
| |
| @noindent |
| Any text editor may be used to prepare an Ada program. |
| @ifclear vms |
| If @code{Glide} is |
| used, the optional Ada mode may be helpful in laying out the program. |
| @end ifclear |
| The |
| program text is a normal text file. We will suppose in our initial |
| example that you have used your editor to prepare the following |
| standard format text file: |
| |
| @smallexample @c ada |
| @cartouche |
| with Ada.Text_IO; use Ada.Text_IO; |
| procedure Hello is |
| begin |
| Put_Line ("Hello WORLD!"); |
| end Hello; |
| @end cartouche |
| @end smallexample |
| |
| @noindent |
| This file should be named @file{hello.adb}. |
| With the normal default file naming conventions, GNAT requires |
| that each file |
| contain a single compilation unit whose file name is the |
| unit name, |
| with periods replaced by hyphens; the |
| extension is @file{ads} for a |
| spec and @file{adb} for a body. |
| You can override this default file naming convention by use of the |
| special pragma @code{Source_File_Name} (@pxref{Using Other File Names}). |
| Alternatively, if you want to rename your files according to this default |
| convention, which is probably more convenient if you will be using GNAT |
| for all your compilations, then the @code{gnatchop} utility |
| can be used to generate correctly-named source files |
| (@pxref{Renaming Files Using gnatchop}). |
| |
| You can compile the program using the following command (@code{$} is used |
| as the command prompt in the examples in this document): |
| |
| @smallexample |
| $ gcc -c hello.adb |
| @end smallexample |
| |
| @noindent |
| @command{gcc} is the command used to run the compiler. This compiler is |
| capable of compiling programs in several languages, including Ada 95 and |
| C. It assumes that you have given it an Ada program if the file extension is |
| either @file{.ads} or @file{.adb}, and it will then call |
| the GNAT compiler to compile the specified file. |
| |
| @ifclear vms |
| The @option{-c} switch is required. It tells @command{gcc} to only do a |
| compilation. (For C programs, @command{gcc} can also do linking, but this |
| capability is not used directly for Ada programs, so the @option{-c} |
| switch must always be present.) |
| @end ifclear |
| |
| This compile command generates a file |
| @file{hello.o}, which is the object |
| file corresponding to your Ada program. It also generates |
| an ``Ada Library Information'' file @file{hello.ali}, |
| which contains additional information used to check |
| that an Ada program is consistent. |
| To build an executable file, |
| use @code{gnatbind} to bind the program |
| and @command{gnatlink} to link it. The |
| argument to both @code{gnatbind} and @command{gnatlink} is the name of the |
| @file{ALI} file, but the default extension of @file{.ali} can |
| be omitted. This means that in the most common case, the argument |
| is simply the name of the main program: |
| |
| @smallexample |
| $ gnatbind hello |
| $ gnatlink hello |
| @end smallexample |
| |
| @noindent |
| A simpler method of carrying out these steps is to use |
| @command{gnatmake}, |
| a master program that invokes all the required |
| compilation, binding and linking tools in the correct order. In particular, |
| @command{gnatmake} automatically recompiles any sources that have been |
| modified since they were last compiled, or sources that depend |
| on such modified sources, so that ``version skew'' is avoided. |
| @cindex Version skew (avoided by @command{gnatmake}) |
| |
| @smallexample |
| $ gnatmake hello.adb |
| @end smallexample |
| |
| @noindent |
| The result is an executable program called @file{hello}, which can be |
| run by entering: |
| |
| @smallexample |
| $ ^hello^RUN HELLO^ |
| @end smallexample |
| |
| @noindent |
| assuming that the current directory is on the search path |
| for executable programs. |
| |
| @noindent |
| and, if all has gone well, you will see |
| |
| @smallexample |
| Hello WORLD! |
| @end smallexample |
| |
| @noindent |
| appear in response to this command. |
| |
| @c **************************************** |
| @node Running a Program with Multiple Units |
| @section Running a Program with Multiple Units |
| |
| @noindent |
| Consider a slightly more complicated example that has three files: a |
| main program, and the spec and body of a package: |
| |
| @smallexample @c ada |
| @cartouche |
| @group |
| package Greetings is |
| procedure Hello; |
| procedure Goodbye; |
| end Greetings; |
| |
| with Ada.Text_IO; use Ada.Text_IO; |
| package body Greetings is |
| procedure Hello is |
| begin |
| Put_Line ("Hello WORLD!"); |
| end Hello; |
| |
| procedure Goodbye is |
| begin |
| Put_Line ("Goodbye WORLD!"); |
| end Goodbye; |
| end Greetings; |
| @end group |
| |
| @group |
| with Greetings; |
| procedure Gmain is |
| begin |
| Greetings.Hello; |
| Greetings.Goodbye; |
| end Gmain; |
| @end group |
| @end cartouche |
| @end smallexample |
| |
| @noindent |
| Following the one-unit-per-file rule, place this program in the |
| following three separate files: |
| |
| @table @file |
| @item greetings.ads |
| spec of package @code{Greetings} |
| |
| @item greetings.adb |
| body of package @code{Greetings} |
| |
| @item gmain.adb |
| body of main program |
| @end table |
| |
| @noindent |
| To build an executable version of |
| this program, we could use four separate steps to compile, bind, and link |
| the program, as follows: |
| |
| @smallexample |
| $ gcc -c gmain.adb |
| $ gcc -c greetings.adb |
| $ gnatbind gmain |
| $ gnatlink gmain |
| @end smallexample |
| |
| @noindent |
| Note that there is no required order of compilation when using GNAT. |
| In particular it is perfectly fine to compile the main program first. |
| Also, it is not necessary to compile package specs in the case where |
| there is an accompanying body; you only need to compile the body. If you want |
| to submit these files to the compiler for semantic checking and not code |
| generation, then use the |
| @option{-gnatc} switch: |
| |
| @smallexample |
| $ gcc -c greetings.ads -gnatc |
| @end smallexample |
| |
| @noindent |
| Although the compilation can be done in separate steps as in the |
| above example, in practice it is almost always more convenient |
| to use the @command{gnatmake} tool. All you need to know in this case |
| is the name of the main program's source file. The effect of the above four |
| commands can be achieved with a single one: |
| |
| @smallexample |
| $ gnatmake gmain.adb |
| @end smallexample |
| |
| @noindent |
| In the next section we discuss the advantages of using @command{gnatmake} in |
| more detail. |
| |
| @c ***************************** |
| @node Using the gnatmake Utility |
| @section Using the @command{gnatmake} Utility |
| |
| @noindent |
| If you work on a program by compiling single components at a time using |
| @command{gcc}, you typically keep track of the units you modify. In order to |
| build a consistent system, you compile not only these units, but also any |
| units that depend on the units you have modified. |
| For example, in the preceding case, |
| if you edit @file{gmain.adb}, you only need to recompile that file. But if |
| you edit @file{greetings.ads}, you must recompile both |
| @file{greetings.adb} and @file{gmain.adb}, because both files contain |
| units that depend on @file{greetings.ads}. |
| |
| @code{gnatbind} will warn you if you forget one of these compilation |
| steps, so that it is impossible to generate an inconsistent program as a |
| result of forgetting to do a compilation. Nevertheless it is tedious and |
| error-prone to keep track of dependencies among units. |
| One approach to handle the dependency-bookkeeping is to use a |
| makefile. However, makefiles present maintenance problems of their own: |
| if the dependencies change as you change the program, you must make |
| sure that the makefile is kept up-to-date manually, which is also an |
| error-prone process. |
| |
| The @command{gnatmake} utility takes care of these details automatically. |
| Invoke it using either one of the following forms: |
| |
| @smallexample |
| $ gnatmake gmain.adb |
| $ gnatmake ^gmain^GMAIN^ |
| @end smallexample |
| |
| @noindent |
| The argument is the name of the file containing the main program; |
| you may omit the extension. @command{gnatmake} |
| examines the environment, automatically recompiles any files that need |
| recompiling, and binds and links the resulting set of object files, |
| generating the executable file, @file{^gmain^GMAIN.EXE^}. |
| In a large program, it |
| can be extremely helpful to use @command{gnatmake}, because working out by hand |
| what needs to be recompiled can be difficult. |
| |
| Note that @command{gnatmake} |
| takes into account all the Ada 95 rules that |
| establish dependencies among units. These include dependencies that result |
| from inlining subprogram bodies, and from |
| generic instantiation. Unlike some other |
| Ada make tools, @command{gnatmake} does not rely on the dependencies that were |
| found by the compiler on a previous compilation, which may possibly |
| be wrong when sources change. @command{gnatmake} determines the exact set of |
| dependencies from scratch each time it is run. |
| |
| @ifset vms |
| @node Editing with Emacs |
| @section Editing with Emacs |
| @cindex Emacs |
| |
| @noindent |
| Emacs is an extensible self-documenting text editor that is available in a |
| separate VMSINSTAL kit. |
| |
| Invoke Emacs by typing @kbd{Emacs} at the command prompt. To get started, |
| click on the Emacs Help menu and run the Emacs Tutorial. |
| In a character cell terminal, Emacs help is invoked with @kbd{Ctrl-h} (also |
| written as @kbd{C-h}), and the tutorial by @kbd{C-h t}. |
| |
| Documentation on Emacs and other tools is available in Emacs under the |
| pull-down menu button: @code{Help - Info}. After selecting @code{Info}, |
| use the middle mouse button to select a topic (e.g. Emacs). |
| |
| In a character cell terminal, do @kbd{C-h i} to invoke info, and then @kbd{m} |
| (stands for menu) followed by the menu item desired, as in @kbd{m Emacs}, to |
| get to the Emacs manual. |
| Help on Emacs is also available by typing @kbd{HELP EMACS} at the DCL command |
| prompt. |
| |
| The tutorial is highly recommended in order to learn the intricacies of Emacs, |
| which is sufficiently extensible to provide for a complete programming |
| environment and shell for the sophisticated user. |
| @end ifset |
| |
| @ifclear vms |
| @node Introduction to GPS |
| @section Introduction to GPS |
| @cindex GPS (GNAT Programming System) |
| @cindex GNAT Programming System (GPS) |
| @noindent |
| Although the command line interface (@command{gnatmake}, etc.) alone |
| is sufficient, a graphical Interactive Development |
| Environment can make it easier for you to compose, navigate, and debug |
| programs. This section describes the main features of GPS |
| (``GNAT Programming System''), the GNAT graphical IDE. |
| You will see how to use GPS to build and debug an executable, and |
| you will also learn some of the basics of the GNAT ``project'' facility. |
| |
| GPS enables you to do much more than is presented here; |
| e.g., you can produce a call graph, interface to a third-party |
| Version Control System, and inspect the generated assembly language |
| for a program. |
| Indeed, GPS also supports languages other than Ada. |
| Such additional information, and an explanation of all of the GPS menu |
| items. may be found in the on-line help, which includes |
| a user's guide and a tutorial (these are also accessible from the GNAT |
| startup menu). |
| |
| @menu |
| * Building a New Program with GPS:: |
| * Simple Debugging with GPS:: |
| @end menu |
| |
| @node Building a New Program with GPS |
| @subsection Building a New Program with GPS |
| @noindent |
| GPS invokes the GNAT compilation tools using information |
| contained in a @emph{project} (also known as a @emph{project file}): |
| a collection of properties such |
| as source directories, identities of main subprograms, tool switches, etc., |
| and their associated values. |
| See @ref{GNAT Project Manager} for details. |
| In order to run GPS, you will need to either create a new project |
| or else open an existing one. |
| |
| This section will explain how you can use GPS to create a project, |
| to associate Ada source files with a project, and to build and run |
| programs. |
| |
| @enumerate |
| @item @emph{Creating a project} |
| |
| Invoke GPS, either from the command line or the platform's IDE. |
| After it starts, GPS will display a ``Welcome'' screen with three |
| radio buttons: |
| |
| @itemize @bullet |
| @item |
| @code{Start with default project in directory} |
| |
| @item |
| @code{Create new project with wizard} |
| |
| @item |
| @code{Open existing project} |
| @end itemize |
| |
| @noindent |
| Select @code{Create new project with wizard} and press @code{OK}. |
| A new window will appear. In the text box labeled with |
| @code{Enter the name of the project to create}, type @file{sample} |
| as the project name. |
| In the next box, browse to choose the directory in which you |
| would like to create the project file. |
| After selecting an appropriate directory, press @code{Forward}. |
| |
| A window will appear with the title |
| @code{Version Control System Configuration}. |
| Simply press @code{Forward}. |
| |
| A window will appear with the title |
| @code{Please select the source directories for this project}. |
| The directory that you specified for the project file will be selected |
| by default as the one to use for sources; simply press @code{Forward}. |
| |
| A window will appear with the title |
| @code{Please select the build directory for this project}. |
| The directory that you specified for the project file will be selected |
| by default for object files and executables; |
| simply press @code{Forward}. |
| |
| A window will appear with the title |
| @code{Please select the main units for this project}. |
| You will supply this information later, after creating the source file. |
| Simply press @code{Forward} for now. |
| |
| A window will appear with the title |
| @code{Please select the switches to build the project}. |
| Press @code{Apply}. This will create a project file named |
| @file{sample.prj} in the directory that you had specified. |
| |
| @item @emph{Creating and saving the source file} |
| |
| After you create the new project, a GPS window will appear, which is |
| partitioned into two main sections: |
| |
| @itemize @bullet |
| @item |
| A @emph{Workspace area}, initially greyed out, which you will use for |
| creating and editing source files |
| |
| @item |
| Directly below, a @emph{Messages area}, which initially displays a |
| ``Welcome'' message. |
| (If the Messages area is not visible, drag its border upward to expand it.) |
| @end itemize |
| |
| @noindent |
| Select @code{File} on the menu bar, and then the @code{New} command. |
| The Workspace area will become white, and you can now |
| enter the source program explicitly. |
| Type the following text |
| |
| @smallexample @c ada |
| @group |
| with Ada.Text_IO; use Ada.Text_IO; |
| procedure Hello is |
| begin |
| Put_Line("Hello from GPS!"); |
| end Hello; |
| @end group |
| @end smallexample |
| |
| @noindent |
| Select @code{File}, then @code{Save As}, and enter the source file name |
| @file{hello.adb}. |
| The file will be saved in the same directory you specified as the |
| location of the default project file. |
| |
| @item @emph{Updating the project file} |
| |
| You need to add the new source file to the project. |
| To do this, select |
| the @code{Project} menu and then @code{Edit project properties}. |
| Click the @code{Main files} tab on the left, and then the |
| @code{Add} button. |
| Choose @file{hello.adb} from the list, and press @code{Open}. |
| The project settings window will reflect this action. |
| Click @code{OK}. |
| |
| @item @emph{Building and running the program} |
| |
| In the main GPS window, now choose the @code{Build} menu, then @code{Make}, |
| and select @file{hello.adb}. |
| The Messages window will display the resulting invocations of @command{gcc}, |
| @command{gnatbind}, and @command{gnatlink} |
| (reflecting the default switch settings from the |
| project file that you created) and then a ``successful compilation/build'' |
| message. |
| |
| To run the program, choose the @code{Build} menu, then @code{Run}, and |
| select @command{hello}. |
| An @emph{Arguments Selection} window will appear. |
| There are no command line arguments, so just click @code{OK}. |
| |
| The Messages window will now display the program's output (the string |
| @code{Hello from GPS}), and at the bottom of the GPS window a status |
| update is displayed (@code{Run: hello}). |
| Close the GPS window (or select @code{File}, then @code{Exit}) to |
| terminate this GPS session. |
| @end enumerate |
| |
| @node Simple Debugging with GPS |
| @subsection Simple Debugging with GPS |
| @noindent |
| This section illustrates basic debugging techniques (setting breakpoints, |
| examining/modifying variables, single stepping). |
| |
| @enumerate |
| @item @emph{Opening a project} |
| |
| Start GPS and select @code{Open existing project}; browse to |
| specify the project file @file{sample.prj} that you had created in the |
| earlier example. |
| |
| @item @emph{Creating a source file} |
| |
| Select @code{File}, then @code{New}, and type in the following program: |
| |
| @smallexample @c ada |
| @group |
| with Ada.Text_IO; use Ada.Text_IO; |
| procedure Example is |
| Line : String (1..80); |
| N : Natural; |
| begin |
| Put_Line("Type a line of text at each prompt; an empty line to exit"); |
| loop |
| Put(": "); |
| Get_Line (Line, N); |
| Put_Line (Line (1..N) ); |
| exit when N=0; |
| end loop; |
| end Example; |
| @end group |
| @end smallexample |
| |
| @noindent |
| Select @code{File}, then @code{Save as}, and enter the file name |
| @file{example.adb}. |
| |
| @item @emph{Updating the project file} |
| |
| Add @code{Example} as a new main unit for the project: |
| @enumerate a |
| @item |
| Select @code{Project}, then @code{Edit Project Properties}. |
| |
| @item |
| Select the @code{Main files} tab, click @code{Add}, then |
| select the file @file{example.adb} from the list, and |
| click @code{Open}. |
| You will see the file name appear in the list of main units |
| |
| @item |
| Click @code{OK} |
| @end enumerate |
| |
| @item @emph{Building/running the executable} |
| |
| To build the executable |
| select @code{Build}, then @code{Make}, and then choose @file{example.adb}. |
| |
| Run the program to see its effect (in the Messages area). |
| Each line that you enter is displayed; an empty line will |
| cause the loop to exit and the program to terminate. |
| |
| @item @emph{Debugging the program} |
| |
| Note that the @option{-g} switches to @command{gcc} and @command{gnatlink}, |
| which are required for debugging, are on by default when you create |
| a new project. |
| Thus unless you intentionally remove these settings, you will be able |
| to debug any program that you develop using GPS. |
| |
| @enumerate a |
| @item @emph{Initializing} |
| |
| Select @code{Debug}, then @code{Initialize}, then @file{example} |
| |
| @item @emph{Setting a breakpoint} |
| |
| After performing the initialization step, you will observe a small |
| icon to the right of each line number. |
| This serves as a toggle for breakpoints; clicking the icon will |
| set a breakpoint at the corresponding line (the icon will change to |
| a red circle with an ``x''), and clicking it again |
| will remove the breakpoint / reset the icon. |
| |
| For purposes of this example, set a breakpoint at line 10 (the |
| statement @code{Put_Line@ (Line@ (1..N));} |
| |
| @item @emph{Starting program execution} |
| |
| Select @code{Debug}, then @code{Run}. When the |
| @code{Program Arguments} window appears, click @code{OK}. |
| A console window will appear; enter some line of text, |
| e.g. @code{abcde}, at the prompt. |
| The program will pause execution when it gets to the |
| breakpoint, and the corresponding line is highlighted. |
| |
| @item @emph{Examining a variable} |
| |
| Move the mouse over one of the occurrences of the variable @code{N}. |
| You will see the value (5) displayed, in ``tool tip'' fashion. |
| Right click on @code{N}, select @code{Debug}, then select @code{Display N}. |
| You will see information about @code{N} appear in the @code{Debugger Data} |
| pane, showing the value as 5. |
| |
| @item @emph{Assigning a new value to a variable} |
| |
| Right click on the @code{N} in the @code{Debugger Data} pane, and |
| select @code{Set value of N}. |
| When the input window appears, enter the value @code{4} and click |
| @code{OK}. |
| This value does not automatically appear in the @code{Debugger Data} |
| pane; to see it, right click again on the @code{N} in the |
| @code{Debugger Data} pane and select @code{Update value}. |
| The new value, 4, will appear in red. |
| |
| @item @emph{Single stepping} |
| |
| Select @code{Debug}, then @code{Next}. |
| This will cause the next statement to be executed, in this case the |
| call of @code{Put_Line} with the string slice. |
| Notice in the console window that the displayed string is simply |
| @code{abcd} and not @code{abcde} which you had entered. |
| This is because the upper bound of the slice is now 4 rather than 5. |
| |
| @item @emph{Removing a breakpoint} |
| |
| Toggle the breakpoint icon at line 10. |
| |
| @item @emph{Resuming execution from a breakpoint} |
| |
| Select @code{Debug}, then @code{Continue}. |
| The program will reach the next iteration of the loop, and |
| wait for input after displaying the prompt. |
| This time, just hit the @kbd{Enter} key. |
| The value of @code{N} will be 0, and the program will terminate. |
| The console window will disappear. |
| @end enumerate |
| @end enumerate |
| |
| @node Introduction to Glide and GVD |
| @section Introduction to Glide and GVD |
| @cindex Glide |
| @cindex GVD |
| @noindent |
| This section describes the main features of Glide, |
| a GNAT graphical IDE, and also shows how to use the basic commands in GVD, |
| the GNU Visual Debugger. |
| These tools may be present in addition to, or in place of, GPS on some |
| platforms. |
| Additional information on Glide and GVD may be found |
| in the on-line help for these tools. |
| |
| @menu |
| * Building a New Program with Glide:: |
| * Simple Debugging with GVD:: |
| * Other Glide Features:: |
| @end menu |
| |
| @node Building a New Program with Glide |
| @subsection Building a New Program with Glide |
| @noindent |
| The simplest way to invoke Glide is to enter @command{glide} |
| at the command prompt. It will generally be useful to issue this |
| as a background command, thus allowing you to continue using |
| your command window for other purposes while Glide is running: |
| |
| @smallexample |
| $ glide& |
| @end smallexample |
| |
| @noindent |
| Glide will start up with an initial screen displaying the top-level menu items |
| as well as some other information. The menu selections are as follows |
| @itemize @bullet |
| @item @code{Buffers} |
| @item @code{Files} |
| @item @code{Tools} |
| @item @code{Edit} |
| @item @code{Search} |
| @item @code{Mule} |
| @item @code{Glide} |
| @item @code{Help} |
| @end itemize |
| |
| @noindent |
| For this introductory example, you will need to create a new Ada source file. |
| First, select the @code{Files} menu. This will pop open a menu with around |
| a dozen or so items. To create a file, select the @code{Open file...} choice. |
| Depending on the platform, you may see a pop-up window where you can browse |
| to an appropriate directory and then enter the file name, or else simply |
| see a line at the bottom of the Glide window where you can likewise enter |
| the file name. Note that in Glide, when you attempt to open a non-existent |
| file, the effect is to create a file with that name. For this example enter |
| @file{hello.adb} as the name of the file. |
| |
| A new buffer will now appear, occupying the entire Glide window, |
| with the file name at the top. The menu selections are slightly different |
| from the ones you saw on the opening screen; there is an @code{Entities} item, |
| and in place of @code{Glide} there is now an @code{Ada} item. Glide uses |
| the file extension to identify the source language, so @file{adb} indicates |
| an Ada source file. |
| |
| You will enter some of the source program lines explicitly, |
| and use the syntax-oriented template mechanism to enter other lines. |
| First, type the following text: |
| @smallexample |
| with Ada.Text_IO; use Ada.Text_IO; |
| procedure Hello is |
| begin |
| @end smallexample |
| |
| @noindent |
| Observe that Glide uses different colors to distinguish reserved words from |
| identifiers. Also, after the @code{procedure Hello is} line, the cursor is |
| automatically indented in anticipation of declarations. When you enter |
| @code{begin}, Glide recognizes that there are no declarations and thus places |
| @code{begin} flush left. But after the @code{begin} line the cursor is again |
| indented, where the statement(s) will be placed. |
| |
| The main part of the program will be a @code{for} loop. Instead of entering |
| the text explicitly, however, use a statement template. Select the @code{Ada} |
| item on the top menu bar, move the mouse to the @code{Statements} item, |
| and you will see a large selection of alternatives. Choose @code{for loop}. |
| You will be prompted (at the bottom of the buffer) for a loop name; |
| simply press the @key{Enter} key since a loop name is not needed. |
| You should see the beginning of a @code{for} loop appear in the source |
| program window. You will now be prompted for the name of the loop variable; |
| enter a line with the identifier @code{ind} (lower case). Note that, |
| by default, Glide capitalizes the name (you can override such behavior |
| if you wish, although this is outside the scope of this introduction). |
| Next, Glide prompts you for the loop range; enter a line containing |
| @code{1..5} and you will see this also appear in the source program, |
| together with the remaining elements of the @code{for} loop syntax. |
| |
| Next enter the statement (with an intentional error, a missing semicolon) |
| that will form the body of the loop: |
| @smallexample |
| Put_Line("Hello, World" & Integer'Image(I)) |
| @end smallexample |
| |
| @noindent |
| Finally, type @code{end Hello;} as the last line in the program. |
| Now save the file: choose the @code{File} menu item, and then the |
| @code{Save buffer} selection. You will see a message at the bottom |
| of the buffer confirming that the file has been saved. |
| |
| You are now ready to attempt to build the program. Select the @code{Ada} |
| item from the top menu bar. Although we could choose simply to compile |
| the file, we will instead attempt to do a build (which invokes |
| @command{gnatmake}) since, if the compile is successful, we want to build |
| an executable. Thus select @code{Ada build}. This will fail because of the |
| compilation error, and you will notice that the Glide window has been split: |
| the top window contains the source file, and the bottom window contains the |
| output from the GNAT tools. Glide allows you to navigate from a compilation |
| error to the source file position corresponding to the error: click the |
| middle mouse button (or simultaneously press the left and right buttons, |
| on a two-button mouse) on the diagnostic line in the tool window. The |
| focus will shift to the source window, and the cursor will be positioned |
| on the character at which the error was detected. |
| |
| Correct the error: type in a semicolon to terminate the statement. |
| Although you can again save the file explicitly, you can also simply invoke |
| @code{Ada} @result{} @code{Build} and you will be prompted to save the file. |
| This time the build will succeed; the tool output window shows you the |
| options that are supplied by default. The GNAT tools' output (e.g. |
| object and ALI files, executable) will go in the directory from which |
| Glide was launched. |
| |
| To execute the program, choose @code{Ada} and then @code{Run}. |
| You should see the program's output displayed in the bottom window: |
| |
| @smallexample |
| Hello, world 1 |
| Hello, world 2 |
| Hello, world 3 |
| Hello, world 4 |
| Hello, world 5 |
| @end smallexample |
| |
| @node Simple Debugging with GVD |
| @subsection Simple Debugging with GVD |
| |
| @noindent |
| This section describes how to set breakpoints, examine/modify variables, |
| and step through execution. |
| |
| In order to enable debugging, you need to pass the @option{-g} switch |
| to both the compiler and to @command{gnatlink}. If you are using |
| the command line, passing @option{-g} to @command{gnatmake} will have |
| this effect. You can then launch GVD, e.g. on the @code{hello} program, |
| by issuing the command: |
| |
| @smallexample |
| $ gvd hello |
| @end smallexample |
| |
| @noindent |
| If you are using Glide, then @option{-g} is passed to the relevant tools |
| by default when you do a build. Start the debugger by selecting the |
| @code{Ada} menu item, and then @code{Debug}. |
| |
| GVD comes up in a multi-part window. One pane shows the names of files |
| comprising your executable; another pane shows the source code of the current |
| unit (initially your main subprogram), another pane shows the debugger output |
| and user interactions, and the fourth pane (the data canvas at the top |
| of the window) displays data objects that you have selected. |
| |
| To the left of the source file pane, you will notice green dots adjacent |
| to some lines. These are lines for which object code exists and where |
| breakpoints can thus be set. You set/reset a breakpoint by clicking |
| the green dot. When a breakpoint is set, the dot is replaced by an @code{X} |
| in a red circle. Clicking the circle toggles the breakpoint off, |
| and the red circle is replaced by the green dot. |
| |
| For this example, set a breakpoint at the statement where @code{Put_Line} |
| is invoked. |
| |
| Start program execution by selecting the @code{Run} button on the top menu bar. |
| (The @code{Start} button will also start your program, but it will |
| cause program execution to break at the entry to your main subprogram.) |
| Evidence of reaching the breakpoint will appear: the source file line will be |
| highlighted, and the debugger interactions pane will display |
| a relevant message. |
| |
| You can examine the values of variables in several ways. Move the mouse |
| over an occurrence of @code{Ind} in the @code{for} loop, and you will see |
| the value (now @code{1}) displayed. Alternatively, right-click on @code{Ind} |
| and select @code{Display Ind}; a box showing the variable's name and value |
| will appear in the data canvas. |
| |
| Although a loop index is a constant with respect to Ada semantics, |
| you can change its value in the debugger. Right-click in the box |
| for @code{Ind}, and select the @code{Set Value of Ind} item. |
| Enter @code{2} as the new value, and press @command{OK}. |
| The box for @code{Ind} shows the update. |
| |
| Press the @code{Step} button on the top menu bar; this will step through |
| one line of program text (the invocation of @code{Put_Line}), and you can |
| observe the effect of having modified @code{Ind} since the value displayed |
| is @code{2}. |
| |
| Remove the breakpoint, and resume execution by selecting the @code{Cont} |
| button. You will see the remaining output lines displayed in the debugger |
| interaction window, along with a message confirming normal program |
| termination. |
| |
| @node Other Glide Features |
| @subsection Other Glide Features |
| |
| @noindent |
| You may have observed that some of the menu selections contain abbreviations; |
| e.g., @code{(C-x C-f)} for @code{Open file...} in the @code{Files} menu. |
| These are @emph{shortcut keys} that you can use instead of selecting |
| menu items. The @key{C} stands for @key{Ctrl}; thus @code{(C-x C-f)} means |
| @key{Ctrl-x} followed by @key{Ctrl-f}, and this sequence can be used instead |
| of selecting @code{Files} and then @code{Open file...}. |
| |
| To abort a Glide command, type @key{Ctrl-g}. |
| |
| If you want Glide to start with an existing source file, you can either |
| launch Glide as above and then open the file via @code{Files} @result{} |
| @code{Open file...}, or else simply pass the name of the source file |
| on the command line: |
| |
| @smallexample |
| $ glide hello.adb& |
| @end smallexample |
| |
| @noindent |
| While you are using Glide, a number of @emph{buffers} exist. |
| You create some explicitly; e.g., when you open/create a file. |
| Others arise as an effect of the commands that you issue; e.g., the buffer |
| containing the output of the tools invoked during a build. If a buffer |
| is hidden, you can bring it into a visible window by first opening |
| the @code{Buffers} menu and then selecting the desired entry. |
| |
| If a buffer occupies only part of the Glide screen and you want to expand it |
| to fill the entire screen, then click in the buffer and then select |
| @code{Files} @result{} @code{One Window}. |
| |
| If a window is occupied by one buffer and you want to split the window |
| to bring up a second buffer, perform the following steps: |
| @itemize @bullet |
| @item Select @code{Files} @result{} @code{Split Window}; |
| this will produce two windows each of which holds the original buffer |
| (these are not copies, but rather different views of the same buffer contents) |
| |
| @item With the focus in one of the windows, |
| select the desired buffer from the @code{Buffers} menu |
| @end itemize |
| |
| @noindent |
| To exit from Glide, choose @code{Files} @result{} @code{Exit}. |
| @end ifclear |
| |
| @node The GNAT Compilation Model |
| @chapter The GNAT Compilation Model |
| @cindex GNAT compilation model |
| @cindex Compilation model |
| |
| @menu |
| * Source Representation:: |
| * Foreign Language Representation:: |
| * File Naming Rules:: |
| * Using Other File Names:: |
| * Alternative File Naming Schemes:: |
| * Generating Object Files:: |
| * Source Dependencies:: |
| * The Ada Library Information Files:: |
| * Binding an Ada Program:: |
| * Mixed Language Programming:: |
| @ifclear vms |
| * Building Mixed Ada & C++ Programs:: |
| * Comparison between GNAT and C/C++ Compilation Models:: |
| @end ifclear |
| * Comparison between GNAT and Conventional Ada Library Models:: |
| @ifset vms |
| * Placement of temporary files:: |
| @end ifset |
| @end menu |
| |
| @noindent |
| This chapter describes the compilation model used by GNAT. Although |
| similar to that used by other languages, such as C and C++, this model |
| is substantially different from the traditional Ada compilation models, |
| which are based on a library. The model is initially described without |
| reference to the library-based model. If you have not previously used an |
| Ada compiler, you need only read the first part of this chapter. The |
| last section describes and discusses the differences between the GNAT |
| model and the traditional Ada compiler models. If you have used other |
| Ada compilers, this section will help you to understand those |
| differences, and the advantages of the GNAT model. |
| |
| @node Source Representation |
| @section Source Representation |
| @cindex Latin-1 |
| |
| @noindent |
| Ada source programs are represented in standard text files, using |
| Latin-1 coding. Latin-1 is an 8-bit code that includes the familiar |
| 7-bit ASCII set, plus additional characters used for |
| representing foreign languages (@pxref{Foreign Language Representation} |
| for support of non-USA character sets). The format effector characters |
| are represented using their standard ASCII encodings, as follows: |
| |
| @table @code |
| @item VT |
| @findex VT |
| Vertical tab, @code{16#0B#} |
| |
| @item HT |
| @findex HT |
| Horizontal tab, @code{16#09#} |
| |
| @item CR |
| @findex CR |
| Carriage return, @code{16#0D#} |
| |
| @item LF |
| @findex LF |
| Line feed, @code{16#0A#} |
| |
| @item FF |
| @findex FF |
| Form feed, @code{16#0C#} |
| @end table |
| |
| @noindent |
| Source files are in standard text file format. In addition, GNAT will |
| recognize a wide variety of stream formats, in which the end of |
| physical lines is marked by any of the following sequences: |
| @code{LF}, @code{CR}, @code{CR-LF}, or @code{LF-CR}. This is useful |
| in accommodating files that are imported from other operating systems. |
| |
| @cindex End of source file |
| @cindex Source file, end |
| @findex SUB |
| The end of a source file is normally represented by the physical end of |
| file. However, the control character @code{16#1A#} (@code{SUB}) is also |
| recognized as signalling the end of the source file. Again, this is |
| provided for compatibility with other operating systems where this |
| code is used to represent the end of file. |
| |
| Each file contains a single Ada compilation unit, including any pragmas |
| associated with the unit. For example, this means you must place a |
| package declaration (a package @dfn{spec}) and the corresponding body in |
| separate files. An Ada @dfn{compilation} (which is a sequence of |
| compilation units) is represented using a sequence of files. Similarly, |
| you will place each subunit or child unit in a separate file. |
| |
| @node Foreign Language Representation |
| @section Foreign Language Representation |
| |
| @noindent |
| GNAT supports the standard character sets defined in Ada 95 as well as |
| several other non-standard character sets for use in localized versions |
| of the compiler (@pxref{Character Set Control}). |
| @menu |
| * Latin-1:: |
| * Other 8-Bit Codes:: |
| * Wide Character Encodings:: |
| @end menu |
| |
| @node Latin-1 |
| @subsection Latin-1 |
| @cindex Latin-1 |
| |
| @noindent |
| The basic character set is Latin-1. This character set is defined by ISO |
| standard 8859, part 1. The lower half (character codes @code{16#00#} |
| ... @code{16#7F#)} is identical to standard ASCII coding, but the upper half |
| is used to represent additional characters. These include extended letters |
| used by European languages, such as French accents, the vowels with umlauts |
| used in German, and the extra letter A-ring used in Swedish. |
| |
| @findex Ada.Characters.Latin_1 |
| For a complete list of Latin-1 codes and their encodings, see the source |
| file of library unit @code{Ada.Characters.Latin_1} in file |
| @file{a-chlat1.ads}. |
| You may use any of these extended characters freely in character or |
| string literals. In addition, the extended characters that represent |
| letters can be used in identifiers. |
| |
| @node Other 8-Bit Codes |
| @subsection Other 8-Bit Codes |
| |
| @noindent |
| GNAT also supports several other 8-bit coding schemes: |
| |
| @table @asis |
| @item ISO 8859-2 (Latin-2) |
| @cindex Latin-2 |
| @cindex ISO 8859-2 |
| Latin-2 letters allowed in identifiers, with uppercase and lowercase |
| equivalence. |
| |
| @item ISO 8859-3 (Latin-3) |
| @cindex Latin-3 |
| @cindex ISO 8859-3 |
| Latin-3 letters allowed in identifiers, with uppercase and lowercase |
| equivalence. |
| |
| @item ISO 8859-4 (Latin-4) |
| @cindex Latin-4 |
| @cindex ISO 8859-4 |
| Latin-4 letters allowed in identifiers, with uppercase and lowercase |
| equivalence. |
| |
| @item ISO 8859-5 (Cyrillic) |
| @cindex ISO 8859-5 |
| @cindex Cyrillic |
| ISO 8859-5 letters (Cyrillic) allowed in identifiers, with uppercase and |
| lowercase equivalence. |
| |
| @item ISO 8859-15 (Latin-9) |
| @cindex ISO 8859-15 |
| @cindex Latin-9 |
| ISO 8859-15 (Latin-9) letters allowed in identifiers, with uppercase and |
| lowercase equivalence |
| |
| @item IBM PC (code page 437) |
| @cindex code page 437 |
| This code page is the normal default for PCs in the U.S. It corresponds |
| to the original IBM PC character set. This set has some, but not all, of |
| the extended Latin-1 letters, but these letters do not have the same |
| encoding as Latin-1. In this mode, these letters are allowed in |
| identifiers with uppercase and lowercase equivalence. |
| |
| @item IBM PC (code page 850) |
| @cindex code page 850 |
| This code page is a modification of 437 extended to include all the |
| Latin-1 letters, but still not with the usual Latin-1 encoding. In this |
| mode, all these letters are allowed in identifiers with uppercase and |
| lowercase equivalence. |
| |
| @item Full Upper 8-bit |
| Any character in the range 80-FF allowed in identifiers, and all are |
| considered distinct. In other words, there are no uppercase and lowercase |
| equivalences in this range. This is useful in conjunction with |
| certain encoding schemes used for some foreign character sets (e.g. |
| the typical method of representing Chinese characters on the PC). |
| |
| @item No Upper-Half |
| No upper-half characters in the range 80-FF are allowed in identifiers. |
| This gives Ada 83 compatibility for identifier names. |
| @end table |
| |
| @noindent |
| For precise data on the encodings permitted, and the uppercase and lowercase |
| equivalences that are recognized, see the file @file{csets.adb} in |
| the GNAT compiler sources. You will need to obtain a full source release |
| of GNAT to obtain this file. |
| |
| @node Wide Character Encodings |
| @subsection Wide Character Encodings |
| |
| @noindent |
| GNAT allows wide character codes to appear in character and string |
| literals, and also optionally in identifiers, by means of the following |
| possible encoding schemes: |
| |
| @table @asis |
| |
| @item Hex Coding |
| In this encoding, a wide character is represented by the following five |
| character sequence: |
| |
| @smallexample |
| ESC a b c d |
| @end smallexample |
| |
| @noindent |
| Where @code{a}, @code{b}, @code{c}, @code{d} are the four hexadecimal |
| characters (using uppercase letters) of the wide character code. For |
| example, ESC A345 is used to represent the wide character with code |
| @code{16#A345#}. |
| This scheme is compatible with use of the full Wide_Character set. |
| |
| @item Upper-Half Coding |
| @cindex Upper-Half Coding |
| The wide character with encoding @code{16#abcd#} where the upper bit is on |
| (in other words, ``a'' is in the range 8-F) is represented as two bytes, |
| @code{16#ab#} and @code{16#cd#}. The second byte cannot be a format control |
| character, but is not required to be in the upper half. This method can |
| be also used for shift-JIS or EUC, where the internal coding matches the |
| external coding. |
| |
| @item Shift JIS Coding |
| @cindex Shift JIS Coding |
| A wide character is represented by a two-character sequence, |
| @code{16#ab#} and |
| @code{16#cd#}, with the restrictions described for upper-half encoding as |
| described above. The internal character code is the corresponding JIS |
| character according to the standard algorithm for Shift-JIS |
| conversion. Only characters defined in the JIS code set table can be |
| used with this encoding method. |
| |
| @item EUC Coding |
| @cindex EUC Coding |
| A wide character is represented by a two-character sequence |
| @code{16#ab#} and |
| @code{16#cd#}, with both characters being in the upper half. The internal |
| character code is the corresponding JIS character according to the EUC |
| encoding algorithm. Only characters defined in the JIS code set table |
| can be used with this encoding method. |
| |
| @item UTF-8 Coding |
| A wide character is represented using |
| UCS Transformation Format 8 (UTF-8) as defined in Annex R of ISO |
| 10646-1/Am.2. Depending on the character value, the representation |
| is a one, two, or three byte sequence: |
| @smallexample |
| @iftex |
| @leftskip=.7cm |
| @end iftex |
| 16#0000#-16#007f#: 2#0xxxxxxx# |
| 16#0080#-16#07ff#: 2#110xxxxx# 2#10xxxxxx# |
| 16#0800#-16#ffff#: 2#1110xxxx# 2#10xxxxxx# 2#10xxxxxx# |
| |
| @end smallexample |
| |
| @noindent |
| where the xxx bits correspond to the left-padded bits of the |
| 16-bit character value. Note that all lower half ASCII characters |
| are represented as ASCII bytes and all upper half characters and |
| other wide characters are represented as sequences of upper-half |
| (The full UTF-8 scheme allows for encoding 31-bit characters as |
| 6-byte sequences, but in this implementation, all UTF-8 sequences |
| of four or more bytes length will be treated as illegal). |
| @item Brackets Coding |
| In this encoding, a wide character is represented by the following eight |
| character sequence: |
| |
| @smallexample |
| [ " a b c d " ] |
| @end smallexample |
| |
| @noindent |
| Where @code{a}, @code{b}, @code{c}, @code{d} are the four hexadecimal |
| characters (using uppercase letters) of the wide character code. For |
| example, [``A345''] is used to represent the wide character with code |
| @code{16#A345#}. It is also possible (though not required) to use the |
| Brackets coding for upper half characters. For example, the code |
| @code{16#A3#} can be represented as @code{[``A3'']}. |
| |
| This scheme is compatible with use of the full Wide_Character set, |
| and is also the method used for wide character encoding in the standard |
| ACVC (Ada Compiler Validation Capability) test suite distributions. |
| |
| @end table |
| |
| @noindent |
| Note: Some of these coding schemes do not permit the full use of the |
| Ada 95 character set. For example, neither Shift JIS, nor EUC allow the |
| use of the upper half of the Latin-1 set. |
| |
| @node File Naming Rules |
| @section File Naming Rules |
| |
| @noindent |
| The default file name is determined by the name of the unit that the |
| file contains. The name is formed by taking the full expanded name of |
| the unit and replacing the separating dots with hyphens and using |
| ^lowercase^uppercase^ for all letters. |
| |
| An exception arises if the file name generated by the above rules starts |
| with one of the characters |
| @ifset vms |
| A,G,I, or S, |
| @end ifset |
| @ifclear vms |
| a,g,i, or s, |
| @end ifclear |
| and the second character is a |
| minus. In this case, the character ^tilde^dollar sign^ is used in place |
| of the minus. The reason for this special rule is to avoid clashes with |
| the standard names for child units of the packages System, Ada, |
| Interfaces, and GNAT, which use the prefixes |
| @ifset vms |
| S- A- I- and G- |
| @end ifset |
| @ifclear vms |
| s- a- i- and g- |
| @end ifclear |
| respectively. |
| |
| The file extension is @file{.ads} for a spec and |
| @file{.adb} for a body. The following list shows some |
| examples of these rules. |
| |
| @table @file |
| @item main.ads |
| Main (spec) |
| @item main.adb |
| Main (body) |
| @item arith_functions.ads |
| Arith_Functions (package spec) |
| @item arith_functions.adb |
| Arith_Functions (package body) |
| @item func-spec.ads |
| Func.Spec (child package spec) |
| @item func-spec.adb |
| Func.Spec (child package body) |
| @item main-sub.adb |
| Sub (subunit of Main) |
| @item ^a~bad.adb^A$BAD.ADB^ |
| A.Bad (child package body) |
| @end table |
| |
| @noindent |
| Following these rules can result in excessively long |
| file names if corresponding |
| unit names are long (for example, if child units or subunits are |
| heavily nested). An option is available to shorten such long file names |
| (called file name ``krunching''). This may be particularly useful when |
| programs being developed with GNAT are to be used on operating systems |
| with limited file name lengths. @xref{Using gnatkr}. |
| |
| Of course, no file shortening algorithm can guarantee uniqueness over |
| all possible unit names; if file name krunching is used, it is your |
| responsibility to ensure no name clashes occur. Alternatively you |
| can specify the exact file names that you want used, as described |
| in the next section. Finally, if your Ada programs are migrating from a |
| compiler with a different naming convention, you can use the gnatchop |
| utility to produce source files that follow the GNAT naming conventions. |
| (For details @pxref{Renaming Files Using gnatchop}.) |
| |
| Note: in the case of @code{Windows NT/XP} or @code{OpenVMS} operating |
| systems, case is not significant. So for example on @code{Windows XP} |
| if the canonical name is @code{main-sub.adb}, you can use the file name |
| @code{Main-Sub.adb} instead. However, case is significant for other |
| operating systems, so for example, if you want to use other than |
| canonically cased file names on a Unix system, you need to follow |
| the procedures described in the next section. |
| |
| @node Using Other File Names |
| @section Using Other File Names |
| @cindex File names |
| |
| @noindent |
| In the previous section, we have described the default rules used by |
| GNAT to determine the file name in which a given unit resides. It is |
| often convenient to follow these default rules, and if you follow them, |
| the compiler knows without being explicitly told where to find all |
| the files it needs. |
| |
| However, in some cases, particularly when a program is imported from |
| another Ada compiler environment, it may be more convenient for the |
| programmer to specify which file names contain which units. GNAT allows |
| arbitrary file names to be used by means of the Source_File_Name pragma. |
| The form of this pragma is as shown in the following examples: |
| @cindex Source_File_Name pragma |
| |
| @smallexample @c ada |
| @cartouche |
| pragma Source_File_Name (My_Utilities.Stacks, |
| Spec_File_Name => "myutilst_a.ada"); |
| pragma Source_File_name (My_Utilities.Stacks, |
| Body_File_Name => "myutilst.ada"); |
| @end cartouche |
| @end smallexample |
| |
| @noindent |
| As shown in this example, the first argument for the pragma is the unit |
| name (in this example a child unit). The second argument has the form |
| of a named association. The identifier |
| indicates whether the file name is for a spec or a body; |
| the file name itself is given by a string literal. |
| |
| The source file name pragma is a configuration pragma, which means that |
| normally it will be placed in the @file{gnat.adc} |
| file used to hold configuration |
| pragmas that apply to a complete compilation environment. |
| For more details on how the @file{gnat.adc} file is created and used |
| see @ref{Handling of Configuration Pragmas}. |
| @cindex @file{gnat.adc} |
| |
| @ifclear vms |
| GNAT allows completely arbitrary file names to be specified using the |
| source file name pragma. However, if the file name specified has an |
| extension other than @file{.ads} or @file{.adb} it is necessary to use |
| a special syntax when compiling the file. The name in this case must be |
| preceded by the special sequence @code{-x} followed by a space and the name |
| of the language, here @code{ada}, as in: |
| |
| @smallexample |
| $ gcc -c -x ada peculiar_file_name.sim |
| @end smallexample |
| @end ifclear |
| |
| @noindent |
| @command{gnatmake} handles non-standard file names in the usual manner (the |
| non-standard file name for the main program is simply used as the |
| argument to gnatmake). Note that if the extension is also non-standard, |
| then it must be included in the gnatmake command, it may not be omitted. |
| |
| @node Alternative File Naming Schemes |
| @section Alternative File Naming Schemes |
| @cindex File naming schemes, alternative |
| @cindex File names |
| |
| In the previous section, we described the use of the @code{Source_File_Name} |
| pragma to allow arbitrary names to be assigned to individual source files. |
| However, this approach requires one pragma for each file, and especially in |
| large systems can result in very long @file{gnat.adc} files, and also create |
| a maintenance problem. |
| |
| GNAT also provides a facility for specifying systematic file naming schemes |
| other than the standard default naming scheme previously described. An |
| alternative scheme for naming is specified by the use of |
| @code{Source_File_Name} pragmas having the following format: |
| @cindex Source_File_Name pragma |
| |
| @smallexample @c ada |
| pragma Source_File_Name ( |
| Spec_File_Name => FILE_NAME_PATTERN |
| [,Casing => CASING_SPEC] |
| [,Dot_Replacement => STRING_LITERAL]); |
| |
| pragma Source_File_Name ( |
| Body_File_Name => FILE_NAME_PATTERN |
| [,Casing => CASING_SPEC] |
| [,Dot_Replacement => STRING_LITERAL]); |
| |
| pragma Source_File_Name ( |
| Subunit_File_Name => FILE_NAME_PATTERN |
| [,Casing => CASING_SPEC] |
| [,Dot_Replacement => STRING_LITERAL]); |
| |
| FILE_NAME_PATTERN ::= STRING_LITERAL |
| CASING_SPEC ::= Lowercase | Uppercase | Mixedcase |
| @end smallexample |
| |
| @noindent |
| The @code{FILE_NAME_PATTERN} string shows how the file name is constructed. |
| It contains a single asterisk character, and the unit name is substituted |
| systematically for this asterisk. The optional parameter |
| @code{Casing} indicates |
| whether the unit name is to be all upper-case letters, all lower-case letters, |
| or mixed-case. If no |
| @code{Casing} parameter is used, then the default is all |
| ^lower-case^upper-case^. |
| |
| The optional @code{Dot_Replacement} string is used to replace any periods |
| that occur in subunit or child unit names. If no @code{Dot_Replacement} |
| argument is used then separating dots appear unchanged in the resulting |
| file name. |
| Although the above syntax indicates that the |
| @code{Casing} argument must appear |
| before the @code{Dot_Replacement} argument, but it |
| is also permissible to write these arguments in the opposite order. |
| |
| As indicated, it is possible to specify different naming schemes for |
| bodies, specs, and subunits. Quite often the rule for subunits is the |
| same as the rule for bodies, in which case, there is no need to give |
| a separate @code{Subunit_File_Name} rule, and in this case the |
| @code{Body_File_name} rule is used for subunits as well. |
| |
| The separate rule for subunits can also be used to implement the rather |
| unusual case of a compilation environment (e.g. a single directory) which |
| contains a subunit and a child unit with the same unit name. Although |
| both units cannot appear in the same partition, the Ada Reference Manual |
| allows (but does not require) the possibility of the two units coexisting |
| in the same environment. |
| |
| The file name translation works in the following steps: |
| |
| @itemize @bullet |
| |
| @item |
| If there is a specific @code{Source_File_Name} pragma for the given unit, |
| then this is always used, and any general pattern rules are ignored. |
| |
| @item |
| If there is a pattern type @code{Source_File_Name} pragma that applies to |
| the unit, then the resulting file name will be used if the file exists. If |
| more than one pattern matches, the latest one will be tried first, and the |
| first attempt resulting in a reference to a file that exists will be used. |
| |
| @item |
| If no pattern type @code{Source_File_Name} pragma that applies to the unit |
| for which the corresponding file exists, then the standard GNAT default |
| naming rules are used. |
| |
| @end itemize |
| |
| @noindent |
| As an example of the use of this mechanism, consider a commonly used scheme |
| in which file names are all lower case, with separating periods copied |
| unchanged to the resulting file name, and specs end with @file{.1.ada}, and |
| bodies end with @file{.2.ada}. GNAT will follow this scheme if the following |
| two pragmas appear: |
| |
| @smallexample @c ada |
| pragma Source_File_Name |
| (Spec_File_Name => "*.1.ada"); |
| pragma Source_File_Name |
| (Body_File_Name => "*.2.ada"); |
| @end smallexample |
| |
| @noindent |
| The default GNAT scheme is actually implemented by providing the following |
| default pragmas internally: |
| |
| @smallexample @c ada |
| pragma Source_File_Name |
| (Spec_File_Name => "*.ads", Dot_Replacement => "-"); |
| pragma Source_File_Name |
| (Body_File_Name => "*.adb", Dot_Replacement => "-"); |
| @end smallexample |
| |
| @noindent |
| Our final example implements a scheme typically used with one of the |
| Ada 83 compilers, where the separator character for subunits was ``__'' |
| (two underscores), specs were identified by adding @file{_.ADA}, bodies |
| by adding @file{.ADA}, and subunits by |
| adding @file{.SEP}. All file names were |
| upper case. Child units were not present of course since this was an |
| Ada 83 compiler, but it seems reasonable to extend this scheme to use |
| the same double underscore separator for child units. |
| |
| @smallexample @c ada |
| pragma Source_File_Name |
| (Spec_File_Name => "*_.ADA", |
| Dot_Replacement => "__", |
| Casing = Uppercase); |
| pragma Source_File_Name |
| (Body_File_Name => "*.ADA", |
| Dot_Replacement => "__", |
| Casing = Uppercase); |
| pragma Source_File_Name |
| (Subunit_File_Name => "*.SEP", |
| Dot_Replacement => "__", |
| Casing = Uppercase); |
| @end smallexample |
| |
| @node Generating Object Files |
| @section Generating Object Files |
| |
| @noindent |
| An Ada program consists of a set of source files, and the first step in |
| compiling the program is to generate the corresponding object files. |
| These are generated by compiling a subset of these source files. |
| The files you need to compile are the following: |
| |
| @itemize @bullet |
| @item |
| If a package spec has no body, compile the package spec to produce the |
| object file for the package. |
| |
| @item |
| If a package has both a spec and a body, compile the body to produce the |
| object file for the package. The source file for the package spec need |
| not be compiled in this case because there is only one object file, which |
| contains the code for both the spec and body of the package. |
| |
| @item |
| For a subprogram, compile the subprogram body to produce the object file |
| for the subprogram. The spec, if one is present, is as usual in a |
| separate file, and need not be compiled. |
| |
| @item |
| @cindex Subunits |
| In the case of subunits, only compile the parent unit. A single object |
| file is generated for the entire subunit tree, which includes all the |
| subunits. |
| |
| @item |
| Compile child units independently of their parent units |
| (though, of course, the spec of all the ancestor unit must be present in order |
| to compile a child unit). |
| |
| @item |
| @cindex Generics |
| Compile generic units in the same manner as any other units. The object |
| files in this case are small dummy files that contain at most the |
| flag used for elaboration checking. This is because GNAT always handles generic |
| instantiation by means of macro expansion. However, it is still necessary to |
| compile generic units, for dependency checking and elaboration purposes. |
| @end itemize |
| |
| @noindent |
| The preceding rules describe the set of files that must be compiled to |
| generate the object files for a program. Each object file has the same |
| name as the corresponding source file, except that the extension is |
| @file{.o} as usual. |
| |
| You may wish to compile other files for the purpose of checking their |
| syntactic and semantic correctness. For example, in the case where a |
| package has a separate spec and body, you would not normally compile the |
| spec. However, it is convenient in practice to compile the spec to make |
| sure it is error-free before compiling clients of this spec, because such |
| compilations will fail if there is an error in the spec. |
| |
| GNAT provides an option for compiling such files purely for the |
| purposes of checking correctness; such compilations are not required as |
| part of the process of building a program. To compile a file in this |
| checking mode, use the @option{-gnatc} switch. |
| |
| @node Source Dependencies |
| @section Source Dependencies |
| |
| @noindent |
| A given object file clearly depends on the source file which is compiled |
| to produce it. Here we are using @dfn{depends} in the sense of a typical |
| @code{make} utility; in other words, an object file depends on a source |
| file if changes to the source file require the object file to be |
| recompiled. |
| In addition to this basic dependency, a given object may depend on |
| additional source files as follows: |
| |
| @itemize @bullet |
| @item |
| If a file being compiled @code{with}'s a unit @var{X}, the object file |
| depends on the file containing the spec of unit @var{X}. This includes |
| files that are @code{with}'ed implicitly either because they are parents |
| of @code{with}'ed child units or they are run-time units required by the |
| language constructs used in a particular unit. |
| |
| @item |
| If a file being compiled instantiates a library level generic unit, the |
| object file depends on both the spec and body files for this generic |
| unit. |
| |
| @item |
| If a file being compiled instantiates a generic unit defined within a |
| package, the object file depends on the body file for the package as |
| well as the spec file. |
| |
| @item |
| @findex Inline |
| @cindex @option{-gnatn} switch |
| If a file being compiled contains a call to a subprogram for which |
| pragma @code{Inline} applies and inlining is activated with the |
| @option{-gnatn} switch, the object file depends on the file containing the |
| body of this subprogram as well as on the file containing the spec. Note |
| that for inlining to actually occur as a result of the use of this switch, |
| it is necessary to compile in optimizing mode. |
| |
| @cindex @option{-gnatN} switch |
| The use of @option{-gnatN} activates a more extensive inlining optimization |
| that is performed by the front end of the compiler. This inlining does |
| not require that the code generation be optimized. Like @option{-gnatn}, |
| the use of this switch generates additional dependencies. |
| Note that |
| @option{-gnatN} automatically implies @option{-gnatn} so it is not necessary |
| to specify both options. |
| |
| @item |
| If an object file O depends on the proper body of a subunit through inlining |
| or instantiation, it depends on the parent unit of the subunit. This means that |
| any modification of the parent unit or one of its subunits affects the |
| compilation of O. |
| |
| @item |
| The object file for a parent unit depends on all its subunit body files. |
| |
| @item |
| The previous two rules meant that for purposes of computing dependencies and |
| recompilation, a body and all its subunits are treated as an indivisible whole. |
| |
| @noindent |
| These rules are applied transitively: if unit @code{A} @code{with}'s |
| unit @code{B}, whose elaboration calls an inlined procedure in package |
| @code{C}, the object file for unit @code{A} will depend on the body of |
| @code{C}, in file @file{c.adb}. |
| |
| The set of dependent files described by these rules includes all the |
| files on which the unit is semantically dependent, as described in the |
| Ada 95 Language Reference Manual. However, it is a superset of what the |
| ARM describes, because it includes generic, inline, and subunit dependencies. |
| |
| An object file must be recreated by recompiling the corresponding source |
| file if any of the source files on which it depends are modified. For |
| example, if the @code{make} utility is used to control compilation, |
| the rule for an Ada object file must mention all the source files on |
| which the object file depends, according to the above definition. |
| The determination of the necessary |
| recompilations is done automatically when one uses @command{gnatmake}. |
| @end itemize |
| |
| @node The Ada Library Information Files |
| @section The Ada Library Information Files |
| @cindex Ada Library Information files |
| @cindex @file{ALI} files |
| |
| @noindent |
| Each compilation actually generates two output files. The first of these |
| is the normal object file that has a @file{.o} extension. The second is a |
| text file containing full dependency information. It has the same |
| name as the source file, but an @file{.ali} extension. |
| This file is known as the Ada Library Information (@file{ALI}) file. |
| The following information is contained in the @file{ALI} file. |
| |
| @itemize @bullet |
| @item |
| Version information (indicates which version of GNAT was used to compile |
| the unit(s) in question) |
| |
| @item |
| Main program information (including priority and time slice settings, |
| as well as the wide character encoding used during compilation). |
| |
| @item |
| List of arguments used in the @command{gcc} command for the compilation |
| |
| @item |
| Attributes of the unit, including configuration pragmas used, an indication |
| of whether the compilation was successful, exception model used etc. |
| |
| @item |
| A list of relevant restrictions applying to the unit (used for consistency) |
| checking. |
| |
| @item |
| Categorization information (e.g. use of pragma @code{Pure}). |
| |
| @item |
| Information on all @code{with}'ed units, including presence of |
| @code{Elaborate} or @code{Elaborate_All} pragmas. |
| |
| @item |
| Information from any @code{Linker_Options} pragmas used in the unit |
| |
| @item |
| Information on the use of @code{Body_Version} or @code{Version} |
| attributes in the unit. |
| |
| @item |
| Dependency information. This is a list of files, together with |
| time stamp and checksum information. These are files on which |
| the unit depends in the sense that recompilation is required |
| if any of these units are modified. |
| |
| @item |
| Cross-reference data. Contains information on all entities referenced |
| in the unit. Used by tools like @code{gnatxref} and @code{gnatfind} to |
| provide cross-reference information. |
| |
| @end itemize |
| |
| @noindent |
| For a full detailed description of the format of the @file{ALI} file, |
| see the source of the body of unit @code{Lib.Writ}, contained in file |
| @file{lib-writ.adb} in the GNAT compiler sources. |
| |
| @node Binding an Ada Program |
| @section Binding an Ada Program |
| |
| @noindent |
| When using languages such as C and C++, once the source files have been |
| compiled the only remaining step in building an executable program |
| is linking the object modules together. This means that it is possible to |
| link an inconsistent version of a program, in which two units have |
| included different versions of the same header. |
| |
| The rules of Ada do not permit such an inconsistent program to be built. |
| For example, if two clients have different versions of the same package, |
| it is illegal to build a program containing these two clients. |
| These rules are enforced by the GNAT binder, which also determines an |
| elaboration order consistent with the Ada rules. |
| |
| The GNAT binder is run after all the object files for a program have |
| been created. It is given the name of the main program unit, and from |
| this it determines the set of units required by the program, by reading the |
| corresponding ALI files. It generates error messages if the program is |
| inconsistent or if no valid order of elaboration exists. |
| |
| If no errors are detected, the binder produces a main program, in Ada by |
| default, that contains calls to the elaboration procedures of those |
| compilation unit that require them, followed by |
| a call to the main program. This Ada program is compiled to generate the |
| object file for the main program. The name of |
| the Ada file is @file{b~@var{xxx}.adb} (with the corresponding spec |
| @file{b~@var{xxx}.ads}) where @var{xxx} is the name of the |
| main program unit. |
| |
| Finally, the linker is used to build the resulting executable program, |
| using the object from the main program from the bind step as well as the |
| object files for the Ada units of the program. |
| |
| @node Mixed Language Programming |
| @section Mixed Language Programming |
| @cindex Mixed Language Programming |
| |
| @noindent |
| This section describes how to develop a mixed-language program, |
| specifically one that comprises units in both Ada and C. |
| |
| @menu |
| * Interfacing to C:: |
| * Calling Conventions:: |
| @end menu |
| |
| @node Interfacing to C |
| @subsection Interfacing to C |
| @noindent |
| Interfacing Ada with a foreign language such as C involves using |
| compiler directives to import and/or export entity definitions in each |
| language---using @code{extern} statements in C, for instance, and the |
| @code{Import}, @code{Export}, and @code{Convention} pragmas in Ada. For |
| a full treatment of these topics, read Appendix B, section 1 of the Ada |
| 95 Language Reference Manual. |
| |
| There are two ways to build a program using GNAT that contains some Ada |
| sources and some foreign language sources, depending on whether or not |
| the main subprogram is written in Ada. Here is a source example with |
| the main subprogram in Ada: |
| |
| @smallexample |
| /* file1.c */ |
| #include <stdio.h> |
| |
| void print_num (int num) |
| @{ |
| printf ("num is %d.\n", num); |
| return; |
| @} |
| |
| /* file2.c */ |
| |
| /* num_from_Ada is declared in my_main.adb */ |
| extern int num_from_Ada; |
| |
| int get_num (void) |
| @{ |
| return num_from_Ada; |
| @} |
| @end smallexample |
| |
| @smallexample @c ada |
| -- my_main.adb |
| procedure My_Main is |
| |
| -- Declare then export an Integer entity called num_from_Ada |
| My_Num : Integer := 10; |
| pragma Export (C, My_Num, "num_from_Ada"); |
| |
| -- Declare an Ada function spec for Get_Num, then use |
| -- C function get_num for the implementation. |
| function Get_Num return Integer; |
| pragma Import (C, Get_Num, "get_num"); |
| |
| -- Declare an Ada procedure spec for Print_Num, then use |
| -- C function print_num for the implementation. |
| procedure Print_Num (Num : Integer); |
| pragma Import (C, Print_Num, "print_num"); |
| |
| begin |
| Print_Num (Get_Num); |
| end My_Main; |
| @end smallexample |
| |
| @enumerate |
| @item |
| To build this example, first compile the foreign language files to |
| generate object files: |
| @smallexample |
| ^gcc -c file1.c^gcc -c FILE1.C^ |
| ^gcc -c file2.c^gcc -c FILE2.C^ |
| @end smallexample |
| |
| @item |
| Then, compile the Ada units to produce a set of object files and ALI |
| files: |
| @smallexample |
| gnatmake ^-c^/ACTIONS=COMPILE^ my_main.adb |
| @end smallexample |
| |
| @item |
| Run the Ada binder on the Ada main program: |
| @smallexample |
| gnatbind my_main.ali |
| @end smallexample |
| |
| @item |
| Link the Ada main program, the Ada objects and the other language |
| objects: |
| @smallexample |
| gnatlink my_main.ali file1.o file2.o |
| @end smallexample |
| @end enumerate |
| |
| The last three steps can be grouped in a single command: |
| @smallexample |
| gnatmake my_main.adb -largs file1.o file2.o |
| @end smallexample |
| |
| @cindex Binder output file |
| @noindent |
| If the main program is in a language other than Ada, then you may have |
| more than one entry point into the Ada subsystem. You must use a special |
| binder option to generate callable routines that initialize and |
| finalize the Ada units (@pxref{Binding with Non-Ada Main Programs}). |
| Calls to the initialization and finalization routines must be inserted |
| in the main program, or some other appropriate point in the code. The |
| call to initialize the Ada units must occur before the first Ada |
| subprogram is called, and the call to finalize the Ada units must occur |
| after the last Ada subprogram returns. The binder will place the |
| initialization and finalization subprograms into the |
| @file{b~@var{xxx}.adb} file where they can be accessed by your C |
| sources. To illustrate, we have the following example: |
| |
| @smallexample |
| /* main.c */ |
| extern void adainit (void); |
| extern void adafinal (void); |
| extern int add (int, int); |
| extern int sub (int, int); |
| |
| int main (int argc, char *argv[]) |
| @{ |
| int a = 21, b = 7; |
| |
| adainit(); |
| |
| /* Should print "21 + 7 = 28" */ |
| printf ("%d + %d = %d\n", a, b, add (a, b)); |
| /* Should print "21 - 7 = 14" */ |
| printf ("%d - %d = %d\n", a, b, sub (a, b)); |
| |
| adafinal(); |
| @} |
| @end smallexample |
| |
| @smallexample @c ada |
| -- unit1.ads |
| package Unit1 is |
| function Add (A, B : Integer) return Integer; |
| pragma Export (C, Add, "add"); |
| end Unit1; |
| |
| -- unit1.adb |
| package body Unit1 is |
| function Add (A, B : Integer) return Integer is |
| begin |
| return A + B; |
| end Add; |
| end Unit1; |
| |
| -- unit2.ads |
| package Unit2 is |
| function Sub (A, B : Integer) return Integer; |
| pragma Export (C, Sub, "sub"); |
| end Unit2; |
| |
| -- unit2.adb |
| package body Unit2 is |
| function Sub (A, B : Integer) return Integer is |
| begin |
| return A - B; |
| end Sub; |
| end Unit2; |
| @end smallexample |
| |
| @enumerate |
| @item |
| The build procedure for this application is similar to the last |
| example's. First, compile the foreign language files to generate object |
| files: |
| @smallexample |
| ^gcc -c main.c^gcc -c main.c^ |
| @end smallexample |
| |
| @item |
| Next, compile the Ada units to produce a set of object files and ALI |
| files: |
| @smallexample |
| gnatmake ^-c^/ACTIONS=COMPILE^ unit1.adb |
| gnatmake ^-c^/ACTIONS=COMPILE^ unit2.adb |
| @end smallexample |
| |
| @item |
| Run the Ada binder on every generated ALI file. Make sure to use the |
| @option{-n} option to specify a foreign main program: |
| @smallexample |
| gnatbind ^-n^/NOMAIN^ unit1.ali unit2.ali |
| @end smallexample |
| |
| @item |
| Link the Ada main program, the Ada objects and the foreign language |
| objects. You need only list the last ALI file here: |
| @smallexample |
| gnatlink unit2.ali main.o -o exec_file |
| @end smallexample |
| |
| This procedure yields a binary executable called @file{exec_file}. |
| @end enumerate |
| |
| @node Calling Conventions |
| @subsection Calling Conventions |
| @cindex Foreign Languages |
| @cindex Calling Conventions |
| GNAT follows standard calling sequence conventions and will thus interface |
| to any other language that also follows these conventions. The following |
| Convention identifiers are recognized by GNAT: |
| |
| @table @code |
| @cindex Interfacing to Ada |
| @cindex Other Ada compilers |
| @cindex Convention Ada |
| @item Ada |
| This indicates that the standard Ada calling sequence will be |
| used and all Ada data items may be passed without any limitations in the |
| case where GNAT is used to generate both the caller and callee. It is also |
| possible to mix GNAT generated code and code generated by another Ada |
| compiler. In this case, the data types should be restricted to simple |
| cases, including primitive types. Whether complex data types can be passed |
| depends on the situation. Probably it is safe to pass simple arrays, such |
| as arrays of integers or floats. Records may or may not work, depending |
| on whether both compilers lay them out identically. Complex structures |
| involving variant records, access parameters, tasks, or protected types, |
| are unlikely to be able to be passed. |
| |
| Note that in the case of GNAT running |
| on a platform that supports HP Ada 83, a higher degree of compatibility |
| can be guaranteed, and in particular records are layed out in an identical |
| manner in the two compilers. Note also that if output from two different |
| compilers is mixed, the program is responsible for dealing with elaboration |
| issues. Probably the safest approach is to write the main program in the |
| version of Ada other than GNAT, so that it takes care of its own elaboration |
| requirements, and then call the GNAT-generated adainit procedure to ensure |
| elaboration of the GNAT components. Consult the documentation of the other |
| Ada compiler for further details on elaboration. |
| |
| However, it is not possible to mix the tasking run time of GNAT and |
| HP Ada 83, All the tasking operations must either be entirely within |
| GNAT compiled sections of the program, or entirely within HP Ada 83 |
| compiled sections of the program. |
| |
| @cindex Interfacing to Assembly |
| @cindex Convention Assembler |
| @item Assembler |
| Specifies assembler as the convention. In practice this has the |
| same effect as convention Ada (but is not equivalent in the sense of being |
| considered the same convention). |
| |
| @cindex Convention Asm |
| @findex Asm |
| @item Asm |
| Equivalent to Assembler. |
| |
| @cindex Interfacing to COBOL |
| @cindex Convention COBOL |
| @findex COBOL |
| @item COBOL |
| Data will be passed according to the conventions described |
| in section B.4 of the Ada 95 Reference Manual. |
| |
| @findex C |
| @cindex Interfacing to C |
| @cindex Convention C |
| @item C |
| Data will be passed according to the conventions described |
| in section B.3 of the Ada 95 Reference Manual. |
| |
| A note on interfacing to a C ``varargs'' function: |
| @findex C varargs function |
| @cindex Interfacing to C varargs function |
| @cindex varargs function interfaces |
| |
| @itemize @bullet |
| @item |
| In C, @code{varargs} allows a function to take a variable number of |
| arguments. There is no direct equivalent in this to Ada. One |
| approach that can be used is to create a C wrapper for each |
| different profile and then interface to this C wrapper. For |
| example, to print an @code{int} value using @code{printf}, |
| create a C function @code{printfi} that takes two arguments, a |
| pointer to a string and an int, and calls @code{printf}. |
| Then in the Ada program, use pragma @code{Import} to |
| interface to @code{printfi}. |
| |
| @item |
| It may work on some platforms to directly interface to |
| a @code{varargs} function by providing a specific Ada profile |
| for a particular call. However, this does not work on |
| all platforms, since there is no guarantee that the |
| calling sequence for a two argument normal C function |
| is the same as for calling a @code{varargs} C function with |
| the same two arguments. |
| @end itemize |
| |
| @cindex Convention Default |
| @findex Default |
| @item Default |
| Equivalent to C. |
| |
| @cindex Convention External |
| @findex External |
| @item External |
| Equivalent to C. |
| |
| @ifclear vms |
| @findex C++ |
| @cindex Interfacing to C++ |
| @cindex Convention C++ |
| @item CPP |
| This stands for C++. For most purposes this is identical to C. |
| See the separate description of the specialized GNAT pragmas relating to |
| C++ interfacing for further details. |
| @end ifclear |
| |
| @findex Fortran |
| @cindex Interfacing to Fortran |
| @cindex Convention Fortran |
| @item Fortran |
| Data will be passed according to the conventions described |
| in section B.5 of the Ada 95 Reference Manual. |
| |
| @item Intrinsic |
| This applies to an intrinsic operation, as defined in the Ada 95 |
| Reference Manual. If a pragma Import (Intrinsic) applies to a subprogram, |
| this means that the body of the subprogram is provided by the compiler itself, |
| usually by means of an efficient code sequence, and that the user does not |
| supply an explicit body for it. In an application program, the pragma can |
| only be applied to the following two sets of names, which the GNAT compiler |
| recognizes. |
| |
| @itemize @bullet |
| @item |
| Rotate_Left, Rotate_Right, Shift_Left, Shift_Right, |
| Shift_Right_Arithmetic. The corresponding subprogram declaration must have |
| two formal parameters. The |
| first one must be a signed integer type or a modular type with a binary |
| modulus, and the second parameter must be of type Natural. |
| The return type must be the same as the type of the first argument. The size |
| of this type can only be 8, 16, 32, or 64. |
| @item binary arithmetic operators: ``+'', ``-'', ``*'', ``/'' |
| The corresponding operator declaration must have parameters and result type |
| that have the same root numeric type (for example, all three are long_float |
| types). This simplifies the definition of operations that use type checking |
| to perform dimensional checks: |
| |
| @smallexample @c ada |
| type Distance is new Long_Float; |
| type Time is new Long_Float; |
| type Velocity is new Long_Float; |
| function "/" (D : Distance; T : Time) |
| return Velocity; |
| pragma Import (Intrinsic, "/"); |
| @end smallexample |
| |
| @noindent |
| This common idiom is often programmed with a generic definition and an |
| explicit body. The pragma makes it simpler to introduce such declarations. |
| It incurs no overhead in compilation time or code size, because it is |
| implemented as a single machine instruction. |
| @end itemize |
| @noindent |
| |
| @ifset unw |
| @findex Stdcall |
| @cindex Convention Stdcall |
| @item Stdcall |
| This is relevant only to Windows XP/2000/NT/95 implementations of GNAT, |
| and specifies that the @code{Stdcall} calling sequence will be used, |
| as defined by the NT API. Nevertheless, to ease building |
| cross-platform bindings this convention will be handled as a @code{C} calling |
| convention on non Windows platforms. |
| |
| @findex DLL |
| @cindex Convention DLL |
| @item DLL |
| This is equivalent to @code{Stdcall}. |
| |
| @findex Win32 |
| @cindex Convention Win32 |
| @item Win32 |
| This is equivalent to @code{Stdcall}. |
| @end ifset |
| |
| @findex Stubbed |
| @cindex Convention Stubbed |
| @item Stubbed |
| This is a special convention that indicates that the compiler |
| should provide a stub body that raises @code{Program_Error}. |
| @end table |
| |
| @noindent |
| GNAT additionally provides a useful pragma @code{Convention_Identifier} |
| that can be used to parametrize conventions and allow additional synonyms |
| to be specified. For example if you have legacy code in which the convention |
| identifier Fortran77 was used for Fortran, you can use the configuration |
| pragma: |
| |
| @smallexample @c ada |
| pragma Convention_Identifier (Fortran77, Fortran); |
| @end smallexample |
| |
| @noindent |
| And from now on the identifier Fortran77 may be used as a convention |
| identifier (for example in an @code{Import} pragma) with the same |
| meaning as Fortran. |
| |
| @ifclear vms |
| @node Building Mixed Ada & C++ Programs |
| @section Building Mixed Ada and C++ Programs |
| |
| @noindent |
| A programmer inexperienced with mixed-language development may find that |
| building an application containing both Ada and C++ code can be a |
| challenge. As a matter of fact, interfacing with C++ has not been |
| standardized in the Ada 95 Reference Manual due to the immaturity of -- |
| and lack of standards for -- C++ at the time. This section gives a few |
| hints that should make this task easier. The first section addresses |
| the differences regarding interfacing with C. The second section |
| looks into the delicate problem of linking the complete application from |
| its Ada and C++ parts. The last section gives some hints on how the GNAT |
| run time can be adapted in order to allow inter-language dispatching |
| with a new C++ compiler. |
| |
| @menu |
| * Interfacing to C++:: |
| * Linking a Mixed C++ & Ada Program:: |
| * A Simple Example:: |
| * Adapting the Run Time to a New C++ Compiler:: |
| @end menu |
| |
| @node Interfacing to C++ |
| @subsection Interfacing to C++ |
| |
| @noindent |
| GNAT supports interfacing with C++ compilers generating code that is |
| compatible with the standard Application Binary Interface of the given |
| platform. |
| |
| @noindent |
| Interfacing can be done at 3 levels: simple data, subprograms, and |
| classes. In the first two cases, GNAT offers a specific @var{Convention |
| CPP} that behaves exactly like @var{Convention C}. Usually, C++ mangles |
| the names of subprograms, and currently, GNAT does not provide any help |
| to solve the demangling problem. This problem can be addressed in two |
| ways: |
| @itemize @bullet |
| @item |
| by modifying the C++ code in order to force a C convention using |
| the @code{extern "C"} syntax. |
| |
| @item |
| by figuring out the mangled name and use it as the Link_Name argument of |
| the pragma import. |
| @end itemize |
| |
| @noindent |
| Interfacing at the class level can be achieved by using the GNAT specific |
| pragmas such as @code{CPP_Class} and @code{CPP_Virtual}. See the GNAT |
| Reference Manual for additional information. |
| |
| @node Linking a Mixed C++ & Ada Program |
| @subsection Linking a Mixed C++ & Ada Program |
| |
| @noindent |
| Usually the linker of the C++ development system must be used to link |
| mixed applications because most C++ systems will resolve elaboration |
| issues (such as calling constructors on global class instances) |
| transparently during the link phase. GNAT has been adapted to ease the |
| use of a foreign linker for the last phase. Three cases can be |
| considered: |
| @enumerate |
| |
| @item |
| Using GNAT and G++ (GNU C++ compiler) from the same GCC installation: |
| The C++ linker can simply be called by using the C++ specific driver |
| called @code{c++}. Note that this setup is not very common because it |
| may involve recompiling the whole GCC tree from sources, which makes it |
| harder to upgrade the compilation system for one language without |
| destabilizing the other. |
| |
| @smallexample |
| $ c++ -c file1.C |
| $ c++ -c file2.C |
| $ gnatmake ada_unit -largs file1.o file2.o --LINK=c++ |
| @end smallexample |
| |
| @item |
| Using GNAT and G++ from two different GCC installations: If both |
| compilers are on the PATH, the previous method may be used. It is |
| important to note that environment variables such as C_INCLUDE_PATH, |
| GCC_EXEC_PREFIX, BINUTILS_ROOT, and GCC_ROOT will affect both compilers |
| at the same time and may make one of the two compilers operate |
| improperly if set during invocation of the wrong compiler. It is also |
| very important that the linker uses the proper @file{libgcc.a} GCC |
| library -- that is, the one from the C++ compiler installation. The |
| implicit link command as suggested in the gnatmake command from the |
| former example can be replaced by an explicit link command with the |
| full-verbosity option in order to verify which library is used: |
| @smallexample |
| $ gnatbind ada_unit |
| $ gnatlink -v -v ada_unit file1.o file2.o --LINK=c++ |
| @end smallexample |
| If there is a problem due to interfering environment variables, it can |
| be worked around by using an intermediate script. The following example |
| shows the proper script to use when GNAT has not been installed at its |
| default location and g++ has been installed at its default location: |
| |
| @smallexample |
| $ cat ./my_script |
| #!/bin/sh |
| unset BINUTILS_ROOT |
| unset GCC_ROOT |
| c++ $* |
| $ gnatlink -v -v ada_unit file1.o file2.o --LINK=./my_script |
| @end smallexample |
| |
| @item |
| Using a non-GNU C++ compiler: The commands previously described can be |
| used to insure that the C++ linker is used. Nonetheless, you need to add |
| a few more parameters to the link command line, depending on the exception |
| mechanism used. |
| |
| If the @code{setjmp/longjmp} exception mechanism is used, only the paths |
| to the libgcc libraries are required: |
| |
| @smallexample |
| $ cat ./my_script |
| #!/bin/sh |
| CC $* `gcc -print-file-name=libgcc.a` `gcc -print-file-name=libgcc_eh.a` |
| $ gnatlink ada_unit file1.o file2.o --LINK=./my_script |
| @end smallexample |
| |
| Where CC is the name of the non-GNU C++ compiler. |
| |
| If the @code{zero cost} exception mechanism is used, and the platform |
| supports automatic registration of exception tables (e.g. Solaris or IRIX), |
| paths to more objects are required: |
| |
| @smallexample |
| $ cat ./my_script |
| #!/bin/sh |
| CC `gcc -print-file-name=crtbegin.o` $* \ |
| `gcc -print-file-name=libgcc.a` `gcc -print-file-name=libgcc_eh.a` \ |
| `gcc -print-file-name=crtend.o` |
| $ gnatlink ada_unit file1.o file2.o --LINK=./my_script |
| @end smallexample |
| |
| If the @code{zero cost} exception mechanism is used, and the platform |
| doesn't support automatic registration of exception tables (e.g. HP-UX, |
| Tru64 or AIX), the simple approach described above will not work and |
| a pre-linking phase using GNAT will be necessary. |
| |
| @end enumerate |
| |
| @node A Simple Example |
| @subsection A Simple Example |
| @noindent |
| The following example, provided as part of the GNAT examples, shows how |
| to achieve procedural interfacing between Ada and C++ in both |
| directions. The C++ class A has two methods. The first method is exported |
| to Ada by the means of an extern C wrapper function. The second method |
| calls an Ada subprogram. On the Ada side, The C++ calls are modelled by |
| a limited record with a layout comparable to the C++ class. The Ada |
| subprogram, in turn, calls the C++ method. So, starting from the C++ |
| main program, the process passes back and forth between the two |
| languages. |
| |
| @noindent |
| Here are the compilation commands: |
| @smallexample |
| $ gnatmake -c simple_cpp_interface |
| $ c++ -c cpp_main.C |
| $ c++ -c ex7.C |
| $ gnatbind -n simple_cpp_interface |
| $ gnatlink simple_cpp_interface -o cpp_main --LINK=$(CPLUSPLUS) |
| -lstdc++ ex7.o cpp_main.o |
| @end smallexample |
| |
| @noindent |
| Here are the corresponding sources: |
| @smallexample |
| |
| //cpp_main.C |
| |
| #include "ex7.h" |
| |
| extern "C" @{ |
| void adainit (void); |
| void adafinal (void); |
| void method1 (A *t); |
| @} |
| |
| void method1 (A *t) |
| @{ |
| t->method1 (); |
| @} |
| |
| int main () |
| @{ |
| A obj; |
| adainit (); |
| obj.method2 (3030); |
| adafinal (); |
| @} |
| |
| //ex7.h |
| |
| class Origin @{ |
| public: |
| int o_value; |
| @}; |
| class A : public Origin @{ |
| public: |
| void method1 (void); |
| void method2 (int v); |
| A(); |
| int a_value; |
| @}; |
| |
| //ex7.C |
| |
| #include "ex7.h" |
| #include <stdio.h> |
| |
| extern "C" @{ void ada_method2 (A *t, int v);@} |
| |
| void A::method1 (void) |
| @{ |
| a_value = 2020; |
| printf ("in A::method1, a_value = %d \n",a_value); |
| |
| @} |
| |
| void A::method2 (int v) |
| @{ |
| ada_method2 (this, v); |
| printf ("in A::method2, a_value = %d \n",a_value); |
| |
| @} |
| |
| A::A(void) |
| @{ |
| a_value = 1010; |
| printf ("in A::A, a_value = %d \n",a_value); |
| @} |
| |
| -- Ada sources |
| @b{package} @b{body} Simple_Cpp_Interface @b{is} |
| |
| @b{procedure} Ada_Method2 (This : @b{in} @b{out} A; V : Integer) @b{is} |
| @b{begin} |
| Method1 (This); |
| This.A_Value := V; |
| @b{end} Ada_Method2; |
| |
| @b{end} Simple_Cpp_Interface; |
| |
| @b{package} Simple_Cpp_Interface @b{is} |
| @b{type} A @b{is} @b{limited} |
| @b{record} |
| O_Value : Integer; |
| A_Value : Integer; |
| @b{end} @b{record}; |
| @b{pragma} Convention (C, A); |
| |
| @b{procedure} Method1 (This : @b{in} @b{out} A); |
| @b{pragma} Import (C, Method1); |
| |
| @b{procedure} Ada_Method2 (This : @b{in} @b{out} A; V : Integer); |
| @b{pragma} Export (C, Ada_Method2); |
| |
| @b{end} Simple_Cpp_Interface; |
| @end smallexample |
| |
| @node Adapting the Run Time to a New C++ Compiler |
| @subsection Adapting the Run Time to a New C++ Compiler |
| @noindent |
| GNAT offers the capability to derive Ada 95 tagged types directly from |
| preexisting C++ classes and . See ``Interfacing with C++'' in the |
| @cite{GNAT Reference Manual}. The mechanism used by GNAT for achieving |
| such a goal |
| has been made user configurable through a GNAT library unit |
| @code{Interfaces.CPP}. The default version of this file is adapted to |
| the GNU C++ compiler. Internal knowledge of the virtual |
| table layout used by the new C++ compiler is needed to configure |
| properly this unit. The Interface of this unit is known by the compiler |
| and cannot be changed except for the value of the constants defining the |
| characteristics of the virtual table: CPP_DT_Prologue_Size, CPP_DT_Entry_Size, |
| CPP_TSD_Prologue_Size, CPP_TSD_Entry_Size. Read comments in the source |
| of this unit for more details. |
| |
| @node Comparison between GNAT and C/C++ Compilation Models |
| @section Comparison between GNAT and C/C++ Compilation Models |
| |
| @noindent |
| The GNAT model of compilation is close to the C and C++ models. You can |
| think of Ada specs as corresponding to header files in C. As in C, you |
| don't need to compile specs; they are compiled when they are used. The |
| Ada @code{with} is similar in effect to the @code{#include} of a C |
| header. |
| |
| One notable difference is that, in Ada, you may compile specs separately |
| to check them for semantic and syntactic accuracy. This is not always |
| possible with C headers because they are fragments of programs that have |
| less specific syntactic or semantic rules. |
| |
| The other major difference is the requirement for running the binder, |
| which performs two important functions. First, it checks for |
| consistency. In C or C++, the only defense against assembling |
| inconsistent programs lies outside the compiler, in a makefile, for |
| example. The binder satisfies the Ada requirement that it be impossible |
| to construct an inconsistent program when the compiler is used in normal |
| mode. |
| |
| @cindex Elaboration order control |
| The other important function of the binder is to deal with elaboration |
| issues. There are also elaboration issues in C++ that are handled |
| automatically. This automatic handling has the advantage of being |
| simpler to use, but the C++ programmer has no control over elaboration. |
| Where @code{gnatbind} might complain there was no valid order of |
| elaboration, a C++ compiler would simply construct a program that |
| malfunctioned at run time. |
| @end ifclear |
| |
| @node Comparison between GNAT and Conventional Ada Library Models |
| @section Comparison between GNAT and Conventional Ada Library Models |
| |
| @noindent |
| This section is intended for Ada programmers who have |
| used an Ada compiler implementing the traditional Ada library |
| model, as described in the Ada 95 Language Reference Manual. |
| |
| @cindex GNAT library |
| In GNAT, there is no ``library'' in the normal sense. Instead, the set of |
| source files themselves acts as the library. Compiling Ada programs does |
| not generate any centralized information, but rather an object file and |
| a ALI file, which are of interest only to the binder and linker. |
| In a traditional system, the compiler reads information not only from |
| the source file being compiled, but also from the centralized library. |
| This means that the effect of a compilation depends on what has been |
| previously compiled. In particular: |
| |
| @itemize @bullet |
| @item |
| When a unit is @code{with}'ed, the unit seen by the compiler corresponds |
| to the version of the unit most recently compiled into the library. |
| |
| @item |
| Inlining is effective only if the necessary body has already been |
| compiled into the library. |
| |
| @item |
| Compiling a unit may obsolete other units in the library. |
| @end itemize |
| |
| @noindent |
| In GNAT, compiling one unit never affects the compilation of any other |
| units because the compiler reads only source files. Only changes to source |
| files can affect the results of a compilation. In particular: |
| |
| @itemize @bullet |
| @item |
| When a unit is @code{with}'ed, the unit seen by the compiler corresponds |
| to the source version of the unit that is currently accessible to the |
| compiler. |
| |
| @item |
| @cindex Inlining |
| Inlining requires the appropriate source files for the package or |
| subprogram bodies to be available to the compiler. Inlining is always |
| effective, independent of the order in which units are complied. |
| |
| @item |
| Compiling a unit never affects any other compilations. The editing of |
| sources may cause previous compilations to be out of date if they |
| depended on the source file being modified. |
| @end itemize |
| |
| @noindent |
| The most important result of these differences is that order of compilation |
| is never significant in GNAT. There is no situation in which one is |
| required to do one compilation before another. What shows up as order of |
| compilation requirements in the traditional Ada library becomes, in |
| GNAT, simple source dependencies; in other words, there is only a set |
| of rules saying what source files must be present when a file is |
| compiled. |
| |
| @ifset vms |
| @node Placement of temporary files |
| @section Placement of temporary files |
| @cindex Temporary files (user control over placement) |
| |
| @noindent |
| GNAT creates temporary files in the directory designated by the environment |
| variable @env{TMPDIR}. |
| (See the HP @emph{C RTL Reference Manual} on the function @code{getenv()} |
| for detailed information on how environment variables are resolved. |
| For most users the easiest way to make use of this feature is to simply |
| define @env{TMPDIR} as a job level logical name). |
| For example, if you wish to use a Ramdisk (assuming DECRAM is installed) |
| for compiler temporary files, then you can include something like the |
| following command in your @file{LOGIN.COM} file: |
| |
| @smallexample |
| $ define/job TMPDIR "/disk$scratchram/000000/temp/" |
| @end smallexample |
| |
| @noindent |
| If @env{TMPDIR} is not defined, then GNAT uses the directory designated by |
| @env{TMP}; if @env{TMP} is not defined, then GNAT uses the directory |
| designated by @env{TEMP}. |
| If none of these environment variables are defined then GNAT uses the |
| directory designated by the logical name @code{SYS$SCRATCH:} |
| (by default the user's home directory). If all else fails |
| GNAT uses the current directory for temporary files. |
| @end ifset |
| |
| @c ************************* |
| @node Compiling Using gcc |
| @chapter Compiling Using @command{gcc} |
| |
| @noindent |
| This chapter discusses how to compile Ada programs using the @command{gcc} |
| command. It also describes the set of switches |
| that can be used to control the behavior of the compiler. |
| @menu |
| * Compiling Programs:: |
| * Switches for gcc:: |
| * Search Paths and the Run-Time Library (RTL):: |
| * Order of Compilation Issues:: |
| * Examples:: |
| @end menu |
| |
| @node Compiling Programs |
| @section Compiling Programs |
| |
| @noindent |
| The first step in creating an executable program is to compile the units |
| of the program using the @command{gcc} command. You must compile the |
| following files: |
| |
| @itemize @bullet |
| @item |
| the body file (@file{.adb}) for a library level subprogram or generic |
| subprogram |
| |
| @item |
| the spec file (@file{.ads}) for a library level package or generic |
| package that has no body |
| |
| @item |
| the body file (@file{.adb}) for a library level package |
| or generic package that has a body |
| |
| @end itemize |
| |
| @noindent |
| You need @emph{not} compile the following files |
| |
| @itemize @bullet |
| |
| @item |
| the spec of a library unit which has a body |
| |
| @item |
| subunits |
| @end itemize |
| |
| @noindent |
| because they are compiled as part of compiling related units. GNAT |
| package specs |
| when the corresponding body is compiled, and subunits when the parent is |
| compiled. |
| |
| @cindex cannot generate code |
| If you attempt to compile any of these files, you will get one of the |
| following error messages (where fff is the name of the file you compiled): |
| |
| @smallexample |
| cannot generate code for file @var{fff} (package spec) |
| to check package spec, use -gnatc |
| |
| cannot generate code for file @var{fff} (missing subunits) |
| to check parent unit, use -gnatc |
| |
| cannot generate code for file @var{fff} (subprogram spec) |
| to check subprogram spec, use -gnatc |
| |
| cannot generate code for file @var{fff} (subunit) |
| to check subunit, use -gnatc |
| @end smallexample |
| |
| @noindent |
| As indicated by the above error messages, if you want to submit |
| one of these files to the compiler to check for correct semantics |
| without generating code, then use the @option{-gnatc} switch. |
| |
| The basic command for compiling a file containing an Ada unit is |
| |
| @smallexample |
| $ gcc -c [@var{switches}] @file{file name} |
| @end smallexample |
| |
| @noindent |
| where @var{file name} is the name of the Ada file (usually |
| having an extension |
| @file{.ads} for a spec or @file{.adb} for a body). |
| @ifclear vms |
| You specify the |
| @option{-c} switch to tell @command{gcc} to compile, but not link, the file. |
| @end ifclear |
| The result of a successful compilation is an object file, which has the |
| same name as the source file but an extension of @file{.o} and an Ada |
| Library Information (ALI) file, which also has the same name as the |
| source file, but with @file{.ali} as the extension. GNAT creates these |
| two output files in the current directory, but you may specify a source |
| file in any directory using an absolute or relative path specification |
| containing the directory information. |
| |
| @findex gnat1 |
| @command{gcc} is actually a driver program that looks at the extensions of |
| the file arguments and loads the appropriate compiler. For example, the |
| GNU C compiler is @file{cc1}, and the Ada compiler is @file{gnat1}. |
| These programs are in directories known to the driver program (in some |
| configurations via environment variables you set), but need not be in |
| your path. The @command{gcc} driver also calls the assembler and any other |
| utilities needed to complete the generation of the required object |
| files. |
| |
| It is possible to supply several file names on the same @command{gcc} |
| command. This causes @command{gcc} to call the appropriate compiler for |
| each file. For example, the following command lists three separate |
| files to be compiled: |
| |
| @smallexample |
| $ gcc -c x.adb y.adb z.c |
| @end smallexample |
| |
| @noindent |
| calls @code{gnat1} (the Ada compiler) twice to compile @file{x.adb} and |
| @file{y.adb}, and @code{cc1} (the C compiler) once to compile @file{z.c}. |
| The compiler generates three object files @file{x.o}, @file{y.o} and |
| @file{z.o} and the two ALI files @file{x.ali} and @file{y.ali} from the |
| Ada compilations. Any switches apply to all the files ^listed,^listed.^ |
| @ifclear vms |
| except for |
| @option{-gnat@var{x}} switches, which apply only to Ada compilations. |
| @end ifclear |
| |
| @node Switches for gcc |
| @section Switches for @command{gcc} |
| |
| @noindent |
| The @command{gcc} command accepts switches that control the |
| compilation process. These switches are fully described in this section. |
| First we briefly list all the switches, in alphabetical order, then we |
| describe the switches in more detail in functionally grouped sections. |
| |
| More switches exist for GCC than those documented here, especially |
| for specific targets. However, their use is not recommended as |
| they may change code generation in ways that are incompatible with |
| the Ada run-time library, or can cause inconsistencies between |
| compilation units. |
| |
| @menu |
| * Output and Error Message Control:: |
| * Warning Message Control:: |
| * Debugging and Assertion Control:: |
| * Validity Checking:: |
| * Style Checking:: |
| * Run-Time Checks:: |
| * Using gcc for Syntax Checking:: |
| * Using gcc for Semantic Checking:: |
| * Compiling Different Versions of Ada:: |
| * Character Set Control:: |
| * File Naming Control:: |
| * Subprogram Inlining Control:: |
| * Auxiliary Output Control:: |
| * Debugging Control:: |
| * Exception Handling Control:: |
| * Units to Sources Mapping Files:: |
| * Integrated Preprocessing:: |
| * Code Generation Control:: |
| @ifset vms |
| * Return Codes:: |
| @end ifset |
| @end menu |
| |
| @table @option |
| @c !sort! |
| @ifclear vms |
| @cindex @option{-b} (@command{gcc}) |
| @item -b @var{target} |
| Compile your program to run on @var{target}, which is the name of a |
| system configuration. You must have a GNAT cross-compiler built if |
| @var{target} is not the same as your host system. |
| |
| @item -B@var{dir} |
| @cindex @option{-B} (@command{gcc}) |
| Load compiler executables (for example, @code{gnat1}, the Ada compiler) |
| from @var{dir} instead of the default location. Only use this switch |
| when multiple versions of the GNAT compiler are available. See the |
| @command{gcc} manual page for further details. You would normally use the |
| @option{-b} or @option{-V} switch instead. |
| |
| @item -c |
| @cindex @option{-c} (@command{gcc}) |
| Compile. Always use this switch when compiling Ada programs. |
| |
| Note: for some other languages when using @command{gcc}, notably in |
| the case of C and C++, it is possible to use |
| use @command{gcc} without a @option{-c} switch to |
| compile and link in one step. In the case of GNAT, you |
| cannot use this approach, because the binder must be run |
| and @command{gcc} cannot be used to run the GNAT binder. |
| @end ifclear |
| |
| @item -fno-inline |
| @cindex @option{-fno-inline} (@command{gcc}) |
| Suppresses all back-end inlining, even if other optimization or inlining |
| switches are set. |
| This includes suppression of inlining that results |
| from the use of the pragma @code{Inline_Always}. |
| See also @option{-gnatn} and @option{-gnatN}. |
| |
| @item -fno-strict-aliasing |
| @cindex @option{-fno-strict-aliasing} (@command{gcc}) |
| Causes the compiler to avoid assumptions regarding non-aliasing |
| of objects of different types. See |
| @ref{Optimization and Strict Aliasing} for details. |
| |
| @item -fstack-check |
| @cindex @option{-fstack-check} (@command{gcc}) |
| Activates stack checking. |
| See @ref{Stack Overflow Checking} for details. |
| |
| @item -fstack-usage |
| @cindex @option{-fstack-usage} (@command{gcc}) |
| Makes the compiler output stack usage information for the program, on a |
| per-function basis. See @ref{Static Stack Usage Analysis} for details. |
| |
| @item -fcallgraph-info[=su] |
| @cindex @option{-fcallgraph-info} (@command{gcc}) |
| Makes the compiler output callgraph information for the program, on a |
| per-file basis. The information is generated in the VCG format. It can |
| be decorated with stack-usage per-node information. |
| |
| @item ^-g^/DEBUG^ |
| @cindex @option{^-g^/DEBUG^} (@command{gcc}) |
| Generate debugging information. This information is stored in the object |
| file and copied from there to the final executable file by the linker, |
| where it can be read by the debugger. You must use the |
| @option{^-g^/DEBUG^} switch if you plan on using the debugger. |
| |
| @item -gnat83 |
| @cindex @option{-gnat83} (@command{gcc}) |
| Enforce Ada 83 restrictions. |
| |
| @item -gnat95 |
| @cindex @option{-gnat95} (@command{gcc}) |
| Enforce Ada 95 restrictions. |
| |
| @item -gnat05 |
| @cindex @option{-gnat05} (@command{gcc}) |
| Allow full Ada 2005 features. |
| |
| @item -gnata |
| @cindex @option{-gnata} (@command{gcc}) |
| Assertions enabled. @code{Pragma Assert} and @code{pragma Debug} to be |
| activated. Note that these pragmas can also be controlled using the |
| configuration pragmas @code{Assertion_Policy} and @code{Debug_Policy}. |
| |
| @item -gnatA |
| @cindex @option{-gnatA} (@command{gcc}) |
| Avoid processing @file{gnat.adc}. If a gnat.adc file is present, |
| it will be ignored. |
| |
| @item -gnatb |
| @cindex @option{-gnatb} (@command{gcc}) |
| Generate brief messages to @file{stderr} even if verbose mode set. |
| |
| @item -gnatc |
| @cindex @option{-gnatc} (@command{gcc}) |
| Check syntax and semantics only (no code generation attempted). |
| |
| @item -gnatd |
| @cindex @option{-gnatd} (@command{gcc}) |
| Specify debug options for the compiler. The string of characters after |
| the @option{-gnatd} specify the specific debug options. The possible |
| characters are 0-9, a-z, A-Z, optionally preceded by a dot. See |
| compiler source file @file{debug.adb} for details of the implemented |
| debug options. Certain debug options are relevant to applications |
| programmers, and these are documented at appropriate points in this |
| users guide. |
| |
| @item -gnatD |
| @cindex @option{-gnatD} (@command{gcc}) |
| Create expanded source files for source level debugging. This switch |
| also suppress generation of cross-reference information |
| (see @option{-gnatx}). |
| |
| @item -gnatec=@var{path} |
| @cindex @option{-gnatec} (@command{gcc}) |
| Specify a configuration pragma file |
| @ifclear vms |
| (the equal sign is optional) |
| @end ifclear |
| (@pxref{The Configuration Pragmas Files}). |
| |
| @item ^-gnateD^/DATA_PREPROCESSING=^symbol[=value] |
| @cindex @option{-gnateD} (@command{gcc}) |
| Defines a symbol, associated with value, for preprocessing. |
| (@pxref{Integrated Preprocessing}). |
| |
| @item -gnatef |
| @cindex @option{-gnatef} (@command{gcc}) |
| Display full source path name in brief error messages. |
| |
| @item -gnatem=@var{path} |
| @cindex @option{-gnatem} (@command{gcc}) |
| Specify a mapping file |
| @ifclear vms |
| (the equal sign is optional) |
| @end ifclear |
| (@pxref{Units to Sources Mapping Files}). |
| |
| @item -gnatep=@var{file} |
| @cindex @option{-gnatep} (@command{gcc}) |
| Specify a preprocessing data file |
| @ifclear vms |
| (the equal sign is optional) |
| @end ifclear |
| (@pxref{Integrated Preprocessing}). |
| |
| @item -gnatE |
| @cindex @option{-gnatE} (@command{gcc}) |
| Full dynamic elaboration checks. |
| |
| @item -gnatf |
| @cindex @option{-gnatf} (@command{gcc}) |
| Full errors. Multiple errors per line, all undefined references, do not |
| attempt to suppress cascaded errors. |
| |
| @item -gnatF |
| @cindex @option{-gnatF} (@command{gcc}) |
| Externals names are folded to all uppercase. |
| |
| @item -gnatg |
| @cindex @option{-gnatg} (@command{gcc}) |
| Internal GNAT implementation mode. This should not be used for |
| applications programs, it is intended only for use by the compiler |
| and its run-time library. For documentation, see the GNAT sources. |
| Note that @option{-gnatg} implies @option{-gnatwu} so that warnings |
| are generated on unreferenced entities, and all warnings are treated |
| as errors. |
| |
| @item -gnatG |
| @cindex @option{-gnatG} (@command{gcc}) |
| List generated expanded code in source form. |
| |
| @item ^-gnath^/HELP^ |
| @cindex @option{^-gnath^/HELP^} (@command{gcc}) |
| Output usage information. The output is written to @file{stdout}. |
| |
| @item ^-gnati^/IDENTIFIER_CHARACTER_SET=^@var{c} |
| @cindex @option{^-gnati^/IDENTIFIER_CHARACTER_SET^} (@command{gcc}) |
| Identifier character set |
| @ifclear vms |
| (@var{c}=1/2/3/4/8/9/p/f/n/w). |
| @end ifclear |
| @ifset vms |
| For details of the possible selections for @var{c}, |
| see @ref{Character Set Control}. |
| @end ifset |
| |
| @item -gnatk=@var{n} |
| @cindex @option{-gnatk} (@command{gcc}) |
| Limit file names to @var{n} (1-999) characters ^(@code{k} = krunch)^^. |
| |
| @item -gnatl |
| @cindex @option{-gnatl} (@command{gcc}) |
| Output full source listing with embedded error messages. |
| |
| @item -gnatm=@var{n} |
| @cindex @option{-gnatm} (@command{gcc}) |
| Limit number of detected error or warning messages to @var{n} |
| where @var{n} is in the range 1..999_999. The default setting if |
| no switch is given is 9999. Compilation is terminated if this |
| limit is exceeded. The equal sign here is optional. |
| |
| @item -gnatn |
| @cindex @option{-gnatn} (@command{gcc}) |
| Activate inlining for subprograms for which |
| pragma @code{inline} is specified. This inlining is performed |
| by the GCC back-end. |
| |
| @item -gnatN |
| @cindex @option{-gnatN} (@command{gcc}) |
| Activate front end inlining for subprograms for which |
| pragma @code{Inline} is specified. This inlining is performed |
| by the front end and will be visible in the |
| @option{-gnatG} output. |
| In some cases, this has proved more effective than the back end |
| inlining resulting from the use of |
| @option{-gnatn}. |
| Note that |
| @option{-gnatN} automatically implies |
| @option{-gnatn} so it is not necessary |
| to specify both options. There are a few cases that the back-end inlining |
| catches that cannot be dealt with in the front-end. |
| |
| @item -gnato |
| @cindex @option{-gnato} (@command{gcc}) |
| Enable numeric overflow checking (which is not normally enabled by |
| default). Not that division by zero is a separate check that is not |
| controlled by this switch (division by zero checking is on by default). |
| |
| @item -gnatp |
| @cindex @option{-gnatp} (@command{gcc}) |
| Suppress all checks. |
| |
| @item -gnatP |
| @cindex @option{-gnatP} (@command{gcc}) |
| Enable polling. This is required on some systems (notably Windows NT) to |
| obtain asynchronous abort and asynchronous transfer of control capability. |
| See the description of pragma Polling in the GNAT Reference Manual for |
| full details. |
| |
| @item -gnatq |
| @cindex @option{-gnatq} (@command{gcc}) |
| Don't quit; try semantics, even if parse errors. |
| |
| @item -gnatQ |
| @cindex @option{-gnatQ} (@command{gcc}) |
| Don't quit; generate @file{ALI} and tree files even if illegalities. |
| |
| @item ^-gnatR[0/1/2/3[s]]^/REPRESENTATION_INFO^ |
| @cindex @option{-gnatR} (@command{gcc}) |
| Output representation information for declared types and objects. |
| |
| @item -gnats |
| @cindex @option{-gnats} (@command{gcc}) |
| Syntax check only. |
| |
| @item -gnatS |
| @cindex @option{-gnatS} (@command{gcc}) |
| Print package Standard. |
| |
| @item -gnatt |
| @cindex @option{-gnatt} (@command{gcc}) |
| Generate tree output file. |
| |
| @item ^-gnatT^/TABLE_MULTIPLIER=^@var{nnn} |
| @cindex @option{^-gnatT^/TABLE_MULTIPLIER^} (@command{gcc}) |
| All compiler tables start at @var{nnn} times usual starting size. |
| |
| @item -gnatu |
| @cindex @option{-gnatu} (@command{gcc}) |
| List units for this compilation. |
| |
| @item -gnatU |
| @cindex @option{-gnatU} (@command{gcc}) |
| Tag all error messages with the unique string ``error:'' |
| |
| @item -gnatv |
| @cindex @option{-gnatv} (@command{gcc}) |
| Verbose mode. Full error output with source lines to @file{stdout}. |
| |
| @item -gnatV |
| @cindex @option{-gnatV} (@command{gcc}) |
| Control level of validity checking. See separate section describing |
| this feature. |
| |
| @item ^-gnatw@var{xxx}^/WARNINGS=(@var{option}[,...])^ |
| @cindex @option{^-gnatw^/WARNINGS^} (@command{gcc}) |
| Warning mode where |
| ^@var{xxx} is a string of option letters that^the list of options^ denotes |
| the exact warnings that |
| are enabled or disabled (@pxref{Warning Message Control}). |
| |
| @item ^-gnatW^/WIDE_CHARACTER_ENCODING=^@var{e} |
| @cindex @option{^-gnatW^/WIDE_CHARACTER_ENCODING^} (@command{gcc}) |
| Wide character encoding method |
| @ifclear vms |
| (@var{e}=n/h/u/s/e/8). |
| @end ifclear |
| @ifset vms |
| (@var{e}=@code{BRACKETS, NONE, HEX, UPPER, SHIFT_JIS, EUC, UTF8}) |
| @end ifset |
| |
| @item -gnatx |
| @cindex @option{-gnatx} (@command{gcc}) |
| Suppress generation of cross-reference information. |
| |
| @item ^-gnaty^/STYLE_CHECKS=(option,option..)^ |
| @cindex @option{^-gnaty^/STYLE_CHECKS^} (@command{gcc}) |
| Enable built-in style checks (@pxref{Style Checking}). |
| |
| @item ^-gnatz^/DISTRIBUTION_STUBS=^@var{m} |
| @cindex @option{^-gnatz^/DISTRIBUTION_STUBS^} (@command{gcc}) |
| Distribution stub generation and compilation |
| @ifclear vms |
| (@var{m}=r/c for receiver/caller stubs). |
| @end ifclear |
| @ifset vms |
| (@var{m}=@code{RECEIVER} or @code{CALLER} to specify the type of stubs |
| to be generated and compiled). |
| @end ifset |
| |
| @item ^-I^/SEARCH=^@var{dir} |
| @cindex @option{^-I^/SEARCH^} (@command{gcc}) |
| @cindex RTL |
| Direct GNAT to search the @var{dir} directory for source files needed by |
| the current compilation |
| (@pxref{Search Paths and the Run-Time Library (RTL)}). |
| |
| @item ^-I-^/NOCURRENT_DIRECTORY^ |
| @cindex @option{^-I-^/NOCURRENT_DIRECTORY^} (@command{gcc}) |
| @cindex RTL |
| Except for the source file named in the command line, do not look for source |
| files in the directory containing the source file named in the command line |
| (@pxref{Search Paths and the Run-Time Library (RTL)}). |
| |
| @ifclear vms |
| @item -mbig-switch |
| @cindex @option{-mbig-switch} (@command{gcc}) |
| @cindex @code{case} statement (effect of @option{-mbig-switch} option) |
| This standard gcc switch causes the compiler to use larger offsets in its |
| jump table representation for @code{case} statements. |
| This may result in less efficient code, but is sometimes necessary |
| (for example on HP-UX targets) |
| @cindex HP-UX and @option{-mbig-switch} option |
| in order to compile large and/or nested @code{case} statements. |
| |
| @item -o @var{file} |
| @cindex @option{-o} (@command{gcc}) |
| This switch is used in @command{gcc} to redirect the generated object file |
| and its associated ALI file. Beware of this switch with GNAT, because it may |
| cause the object file and ALI file to have different names which in turn |
| may confuse the binder and the linker. |
| @end ifclear |
| |
| @item -nostdinc |
| @cindex @option{-nostdinc} (@command{gcc}) |
| Inhibit the search of the default location for the GNAT Run Time |
| Library (RTL) source files. |
| |
| @item -nostdlib |
| @cindex @option{-nostdlib} (@command{gcc}) |
| Inhibit the search of the default location for the GNAT Run Time |
| Library (RTL) ALI files. |
| |
| @ifclear vms |
| @item -O[@var{n}] |
| @cindex @option{-O} (@command{gcc}) |
| @var{n} controls the optimization level. |
| |
| @table @asis |
| @item n = 0 |
| No optimization, the default setting if no @option{-O} appears |
| |
| @item n = 1 |
| Normal optimization, the default if you specify @option{-O} without |
| an operand. A good compromise between code quality and compilation |
| time. |
| |
| @item n = 2 |
| Extensive optimization, may improve execution time, possibly at the cost of |
| substantially increased compilation time. |
| |
| @end table |
| @end ifclear |
| |
| @ifset vms |
| @item /NOOPTIMIZE |
| @cindex @option{/NOOPTIMIZE} (@code{GNAT COMPILE}) |
| Equivalent to @option{/OPTIMIZE=NONE}. |
| This is the default behavior in the absence of an @option{/OPTMIZE} |
| qualifier. |
| |
| @item /OPTIMIZE[=(keyword[,...])] |
| @cindex @option{/OPTIMIZE} (@code{GNAT COMPILE}) |
| Selects the level of optimization for your program. The supported |
| keywords are as follows: |
| @table @code |
| @item ALL |
| Perform most optimizations, including those that |
| are expensive. |
| This is the default if the @option{/OPTMIZE} qualifier is supplied |
| without keyword options. |
| |
| @item NONE |
| Do not do any optimizations. Same as @code{/NOOPTIMIZE}. |
| |
| @item SOME |
| Perform some optimizations, but omit ones that are costly. |
| |
| @item DEVELOPMENT |
| Same as @code{SOME}. |
| |
| @item UNROLL_LOOPS |
| Try to unroll loops. This keyword may be specified together with |
| any keyword above other than @code{NONE}. Loop unrolling |
| usually, but not always, improves the performance of programs. |
| @end table |
| @end ifset |
| |
| @ifclear vms |
| @item -pass-exit-codes |
| @cindex @option{-pass-exit-codes} (@command{gcc}) |
| Catch exit codes from the compiler and use the most meaningful as |
| exit status. |
| @end ifclear |
| |
| @item --RTS=@var{rts-path} |
| @cindex @option{--RTS} (@command{gcc}) |
| Specifies the default location of the runtime library. Same meaning as the |
| equivalent @command{gnatmake} flag (@pxref{Switches for gnatmake}). |
| |
| @item ^-S^/ASM^ |
| @cindex @option{^-S^/ASM^} (@command{gcc}) |
| ^Used in place of @option{-c} to^Used to^ |
| cause the assembler source file to be |
| generated, using @file{^.s^.S^} as the extension, |
| instead of the object file. |
| This may be useful if you need to examine the generated assembly code. |
| |
| @item ^-fverbose-asm^/VERBOSE_ASM^ |
| @cindex @option{^-fverbose-asm^/VERBOSE_ASM^} (@command{gcc}) |
| ^Used in conjunction with @option{-S}^Used in place of @option{/ASM}^ |
| to cause the generated assembly code file to be annotated with variable |
| names, making it significantly easier to follow. |
| |
| @item ^-v^/VERBOSE^ |
| @cindex @option{^-v^/VERBOSE^} (@command{gcc}) |
| Show commands generated by the @command{gcc} driver. Normally used only for |
| debugging purposes or if you need to be sure what version of the |
| compiler you are executing. |
| |
| @ifclear vms |
| @item -V @var{ver} |
| @cindex @option{-V} (@command{gcc}) |
| Execute @var{ver} version of the compiler. This is the @command{gcc} |
| version, not the GNAT version. |
| @end ifclear |
| |
| @item ^-w^NO_BACK_END_WARNINGS^ |
| @cindex @option{-w} (@command{gcc}) |
| Turn off warnings generated by the back end of the compiler. Use of |
| this switch also causes the default for front end warnings to be set |
| to suppress (as though @option{-gnatws} had appeared at the start of |
| the options. |
| |
| @end table |
| |
| @ifclear vms |
| @c Combining qualifiers does not work on VMS |
| You may combine a sequence of GNAT switches into a single switch. For |
| example, the combined switch |
| |
| @cindex Combining GNAT switches |
| @smallexample |
| -gnatofi3 |
| @end smallexample |
| |
| @noindent |
| is equivalent to specifying the following sequence of switches: |
| |
| @smallexample |
| -gnato -gnatf -gnati3 |
| @end smallexample |
| @end ifclear |
| |
| @noindent |
| The following restrictions apply to the combination of switches |
| in this manner: |
| |
| @itemize @bullet |
| @item |
| The switch @option{-gnatc} if combined with other switches must come |
| first in the string. |
| |
| @item |
| The switch @option{-gnats} if combined with other switches must come |
| first in the string. |
| |
| @item |
| The switches |
| @option{^-gnatz^/DISTRIBUTION_STUBS^}, @option{-gnatzc}, and @option{-gnatzr} |
| may not be combined with any other switches. |
| |
| @ifclear vms |
| @item |
| Once a ``y'' appears in the string (that is a use of the @option{-gnaty} |
| switch), then all further characters in the switch are interpreted |
| as style modifiers (see description of @option{-gnaty}). |
| |
| @item |
| Once a ``d'' appears in the string (that is a use of the @option{-gnatd} |
| switch), then all further characters in the switch are interpreted |
| as debug flags (see description of @option{-gnatd}). |
| |
| @item |
| Once a ``w'' appears in the string (that is a use of the @option{-gnatw} |
| switch), then all further characters in the switch are interpreted |
| as warning mode modifiers (see description of @option{-gnatw}). |
| |
| @item |
| Once a ``V'' appears in the string (that is a use of the @option{-gnatV} |
| switch), then all further characters in the switch are interpreted |
| as validity checking options (see description of @option{-gnatV}). |
| @end ifclear |
| @end itemize |
| |
| @node Output and Error Message Control |
| @subsection Output and Error Message Control |
| @findex stderr |
| |
| @noindent |
| The standard default format for error messages is called ``brief format''. |
| Brief format messages are written to @file{stderr} (the standard error |
| file) and have the following form: |
| |
| @smallexample |
| e.adb:3:04: Incorrect spelling of keyword "function" |
| e.adb:4:20: ";" should be "is" |
| @end smallexample |
| |
| @noindent |
| The first integer after the file name is the line number in the file, |
| and the second integer is the column number within the line. |
| @code{glide} can parse the error messages |
| and point to the referenced character. |
| The following switches provide control over the error message |
| format: |
| |
| @table @option |
| @c !sort! |
| @item -gnatv |
| @cindex @option{-gnatv} (@command{gcc}) |
| @findex stdout |
| @ifclear vms |
| The v stands for verbose. |
| @end ifclear |
| The effect of this setting is to write long-format error |
| messages to @file{stdout} (the standard output file. |
| The same program compiled with the |
| @option{-gnatv} switch would generate: |
| |
| @smallexample |
| @cartouche |
| 3. funcion X (Q : Integer) |
| | |
| >>> Incorrect spelling of keyword "function" |
| 4. return Integer; |
| | |
| >>> ";" should be "is" |
| @end cartouche |
| @end smallexample |
| |
| @noindent |
| The vertical bar indicates the location of the error, and the @samp{>>>} |
| prefix can be used to search for error messages. When this switch is |
| used the only source lines output are those with errors. |
| |
| @item -gnatl |
| @cindex @option{-gnatl} (@command{gcc}) |
| @ifclear vms |
| The @code{l} stands for list. |
| @end ifclear |
| This switch causes a full listing of |
| the file to be generated. The output might look as follows: |
| |
| @smallexample |
| @cartouche |
| 1. procedure E is |
| 2. V : Integer; |
| 3. funcion X (Q : Integer) |
| | |
| >>> Incorrect spelling of keyword "function" |
| 4. return Integer; |
| | |
| >>> ";" should be "is" |
| 5. begin |
| 6. return Q + Q; |
| 7. end; |
| 8. begin |
| 9. V := X + X; |
| 10.end E; |
| @end cartouche |
| @end smallexample |
| |
| @noindent |
| @findex stderr |
| When you specify the @option{-gnatv} or @option{-gnatl} switches and |
| standard output is redirected, a brief summary is written to |
| @file{stderr} (standard error) giving the number of error messages and |
| warning messages generated. |
| |
| @item -gnatU |
| @cindex @option{-gnatU} (@command{gcc}) |
| This switch forces all error messages to be preceded by the unique |
| string ``error:''. This means that error messages take a few more |
| characters in space, but allows easy searching for and identification |
| of error messages. |
| |
| @item -gnatb |
| @cindex @option{-gnatb} (@command{gcc}) |
| @ifclear vms |
| The @code{b} stands for brief. |
| @end ifclear |
| This switch causes GNAT to generate the |
| brief format error messages to @file{stderr} (the standard error |
| file) as well as the verbose |
| format message or full listing (which as usual is written to |
| @file{stdout} (the standard output file). |
| |
| @item -gnatm=@var{n} |
| @cindex @option{-gnatm} (@command{gcc}) |
| @ifclear vms |
| The @code{m} stands for maximum. |
| @end ifclear |
| @var{n} is a decimal integer in the |
| range of 1 to 999 and limits the number of error messages to be |
| generated. For example, using @option{-gnatm2} might yield |
| |
| @smallexample |
| e.adb:3:04: Incorrect spelling of keyword "function" |
| e.adb:5:35: missing ".." |
| fatal error: maximum errors reached |
| compilation abandoned |
| @end smallexample |
| |
| @noindent |
| Note that the equal sign is optional, so the switches |
| @option{-gnatm2} and @option{-gnatm=2} are equivalent. |
| |
| @item -gnatf |
| @cindex @option{-gnatf} (@command{gcc}) |
| @cindex Error messages, suppressing |
| @ifclear vms |
| The @code{f} stands for full. |
| @end ifclear |
| Normally, the compiler suppresses error messages that are likely to be |
| redundant. This switch causes all error |
| messages to be generated. In particular, in the case of |
| references to undefined variables. If a given variable is referenced |
| several times, the normal format of messages is |
| @smallexample |
| e.adb:7:07: "V" is undefined (more references follow) |
| @end smallexample |
| |
| @noindent |
| where the parenthetical comment warns that there are additional |
| references to the variable @code{V}. Compiling the same program with the |
| @option{-gnatf} switch yields |
| |
| @smallexample |
| e.adb:7:07: "V" is undefined |
| e.adb:8:07: "V" is undefined |
| e.adb:8:12: "V" is undefined |
| e.adb:8:16: "V" is undefined |
| e.adb:9:07: "V" is undefined |
| e.adb:9:12: "V" is undefined |
| @end smallexample |
| |
| @noindent |
| The @option{-gnatf} switch also generates additional information for |
| some error messages. Some examples are: |
| |
| @itemize @bullet |
| @item |
| Full details on entities not available in high integrity mode |
| @item |
| Details on possibly non-portable unchecked conversion |
| @item |
| List possible interpretations for ambiguous calls |
| @item |
| Additional details on incorrect parameters |
| @end itemize |
| |
| @item -gnatq |
| @cindex @option{-gnatq} (@command{gcc}) |
| @ifclear vms |
| The @code{q} stands for quit (really ``don't quit''). |
| @end ifclear |
| In normal operation mode, the compiler first parses the program and |
| determines if there are any syntax errors. If there are, appropriate |
| error messages are generated and compilation is immediately terminated. |
| This switch tells |
| GNAT to continue with semantic analysis even if syntax errors have been |
| found. This may enable the detection of more errors in a single run. On |
| the other hand, the semantic analyzer is more likely to encounter some |
| internal fatal error when given a syntactically invalid tree. |
| |
| @item -gnatQ |
| @cindex @option{-gnatQ} (@command{gcc}) |
| In normal operation mode, the @file{ALI} file is not generated if any |
| illegalities are detected in the program. The use of @option{-gnatQ} forces |
| generation of the @file{ALI} file. This file is marked as being in |
| error, so it cannot be used for binding purposes, but it does contain |
| reasonably complete cross-reference information, and thus may be useful |
| for use by tools (e.g. semantic browsing tools or integrated development |
| environments) that are driven from the @file{ALI} file. This switch |
| implies @option{-gnatq}, since the semantic phase must be run to get a |
| meaningful ALI file. |
| |
| In addition, if @option{-gnatt} is also specified, then the tree file is |
| generated even if there are illegalities. It may be useful in this case |
| to also specify @option{-gnatq} to ensure that full semantic processing |
| occurs. The resulting tree file can be processed by ASIS, for the purpose |
| of providing partial information about illegal units, but if the error |
| causes the tree to be badly malformed, then ASIS may crash during the |
| analysis. |
| |
| When @option{-gnatQ} is used and the generated @file{ALI} file is marked as |
| being in error, @command{gnatmake} will attempt to recompile the source when it |
| finds such an @file{ALI} file, including with switch @option{-gnatc}. |
| |
| Note that @option{-gnatQ} has no effect if @option{-gnats} is specified, |
| since ALI files are never generated if @option{-gnats} is set. |
| |
| @end table |
| |
| @node Warning Message Control |
| @subsection Warning Message Control |
| @cindex Warning messages |
| @noindent |
| In addition to error messages, which correspond to illegalities as defined |
| in the Ada 95 Reference Manual, the compiler detects two kinds of warning |
| situations. |
| |
| First, the compiler considers some constructs suspicious and generates a |
| warning message to alert you to a possible error. Second, if the |
| compiler detects a situation that is sure to raise an exception at |
| run time, it generates a warning message. The following shows an example |
| of warning messages: |
| @smallexample |
| e.adb:4:24: warning: creation of object may raise Storage_Error |
| e.adb:10:17: warning: static value out of range |
| e.adb:10:17: warning: "Constraint_Error" will be raised at run time |
| @end smallexample |
| |
| @noindent |
| GNAT considers a large number of situations as appropriate |
| for the generation of warning messages. As always, warnings are not |
| definite indications of errors. For example, if you do an out-of-range |
| assignment with the deliberate intention of raising a |
| @code{Constraint_Error} exception, then the warning that may be |
| issued does not indicate an error. Some of the situations for which GNAT |
| issues warnings (at least some of the time) are given in the following |
| list. This list is not complete, and new warnings are often added to |
| subsequent versions of GNAT. The list is intended to give a general idea |
| of the kinds of warnings that are generated. |
| |
| @itemize @bullet |
| @item |
| Possible infinitely recursive calls |
| |
| @item |
| Out-of-range values being assigned |
| |
| @item |
| Possible order of elaboration problems |
| |
| @item |
| Unreachable code |
| |
| @item |
| Fixed-point type declarations with a null range |
| |
| @item |
| Direct_IO or Sequential_IO instantiated with a type that has access values |
| |
| @item |
| Variables that are never assigned a value |
| |
| @item |
| Variables that are referenced before being initialized |
| |
| @item |
| Task entries with no corresponding @code{accept} statement |
| |
| @item |
| Duplicate accepts for the same task entry in a @code{select} |
| |
| @item |
| Objects that take too much storage |
| |
| @item |
| Unchecked conversion between types of differing sizes |
| |
| @item |
| Missing @code{return} statement along some execution path in a function |
| |
| @item |
| Incorrect (unrecognized) pragmas |
| |
| @item |
| Incorrect external names |
| |
| @item |
| Allocation from empty storage pool |
| |
| @item |
| Potentially blocking operation in protected type |
| |
| @item |
| Suspicious parenthesization of expressions |
| |
| @item |
| Mismatching bounds in an aggregate |
| |
| @item |
| Attempt to return local value by reference |
| |
| @item |
| Premature instantiation of a generic body |
| |
| @item |
| Attempt to pack aliased components |
| |
| @item |
| Out of bounds array subscripts |
| |
| @item |
| Wrong length on string assignment |
| |
| @item |
| Violations of style rules if style checking is enabled |
| |
| @item |
| Unused @code{with} clauses |
| |
| @item |
| @code{Bit_Order} usage that does not have any effect |
| |
| @item |
| @code{Standard.Duration} used to resolve universal fixed expression |
| |
| @item |
| Dereference of possibly null value |
| |
| @item |
| Declaration that is likely to cause storage error |
| |
| @item |
| Internal GNAT unit @code{with}'ed by application unit |
| |
| @item |
| Values known to be out of range at compile time |
| |
| @item |
| Unreferenced labels and variables |
| |
| @item |
| Address overlays that could clobber memory |
| |
| @item |
| Unexpected initialization when address clause present |
| |
| @item |
| Bad alignment for address clause |
| |
| @item |
| Useless type conversions |
| |
| @item |
| Redundant assignment statements and other redundant constructs |
| |
| @item |
| Useless exception handlers |
| |
| @item |
| Accidental hiding of name by child unit |
| |
| @item |
| Access before elaboration detected at compile time |
| |
| @item |
| A range in a @code{for} loop that is known to be null or might be null |
| |
| @end itemize |
| |
| @noindent |
| The following switches are available to control the handling of |
| warning messages: |
| |
| @table @option |
| @c !sort! |
| @item -gnatwa |
| @emph{Activate all optional errors.} |
| @cindex @option{-gnatwa} (@command{gcc}) |
| This switch activates most optional warning messages, see remaining list |
| in this section for details on optional warning messages that can be |
| individually controlled. The warnings that are not turned on by this |
| switch are |
| @option{-gnatwd} (implicit dereferencing), |
| @option{-gnatwh} (hiding), |
| and @option{-gnatwl} (elaboration warnings). |
| All other optional warnings are turned on. |
| |
| @item -gnatwA |
| @emph{Suppress all optional errors.} |
| @cindex @option{-gnatwA} (@command{gcc}) |
| This switch suppresses all optional warning messages, see remaining list |
| in this section for details on optional warning messages that can be |
| individually controlled. |
| |
| @item -gnatwb |
| @emph{Activate warnings on bad fixed values.} |
| @cindex @option{-gnatwb} (@command{gcc}) |
| @cindex Bad fixed values |
| @cindex Fixed-point Small value |
| @cindex Small value |
| This switch activates warnings for static fixed-point expressions whose |
| value is not an exact multiple of Small. Such values are implementation |
| dependent, since an implementation is free to choose either of the multiples |
| that surround the value. GNAT always chooses the closer one, but this is not |
| required behavior, and it is better to specify a value that is an exact |
| multiple, ensuring predictable execution. The default is that such warnings |
| are not generated. |
| |
| @item -gnatwB |
| @emph{Suppress warnings on bad fixed values.} |
| @cindex @option{-gnatwB} (@command{gcc}) |
| This switch suppresses warnings for static fixed-point expressions whose |
| value is not an exact multiple of Small. |
| |
| @item -gnatwc |
| @emph{Activate warnings on conditionals.} |
| @cindex @option{-gnatwc} (@command{gcc}) |
| @cindex Conditionals, constant |
| This switch activates warnings for conditional expressions used in |
| tests that are known to be True or False at compile time. The default |
| is that such warnings are not generated. |
| Note that this warning does |
| not get issued for the use of boolean variables or constants whose |
| values are known at compile time, since this is a standard technique |
| for conditional compilation in Ada, and this would generate too many |
| ``false positive'' warnings. |
| |
| This warning option also activates a special test for comparisons using |
| the operators ``>='' and`` <=''. |
| If the compiler can tell that only the equality condition is possible, |
| then it will warn that the ``>'' or ``<'' part of the test |
| is useless and that the operator could be replaced by ``=''. |
| An example would be comparing a @code{Natural} variable <= 0. |
| |
| This warning can also be turned on using @option{-gnatwa}. |
| |
| @item -gnatwC |
| @emph{Suppress warnings on conditionals.} |
| @cindex @option{-gnatwC} (@command{gcc}) |
| This switch suppresses warnings for conditional expressions used in |
| tests that are known to be True or False at compile time. |
| |
| @item -gnatwd |
| @emph{Activate warnings on implicit dereferencing.} |
| @cindex @option{-gnatwd} (@command{gcc}) |
| If this switch is set, then the use of a prefix of an access type |
| in an indexed component, slice, or selected component without an |
| explicit @code{.all} will generate a warning. With this warning |
| enabled, access checks occur only at points where an explicit |
| @code{.all} appears in the source code (assuming no warnings are |
| generated as a result of this switch). The default is that such |
| warnings are not generated. |
| Note that @option{-gnatwa} does not affect the setting of |
| this warning option. |
| |
| @item -gnatwD |
| @emph{Suppress warnings on implicit dereferencing.} |
| @cindex @option{-gnatwD} (@command{gcc}) |
| @cindex Implicit dereferencing |
| @cindex Dereferencing, implicit |
| This switch suppresses warnings for implicit dereferences in |
| indexed components, slices, and selected components. |
| |
| @item -gnatwe |
| @emph{Treat warnings as errors.} |
| @cindex @option{-gnatwe} (@command{gcc}) |
| @cindex Warnings, treat as error |
| This switch causes warning messages to be treated as errors. |
| The warning string still appears, but the warning messages are counted |
| as errors, and prevent the generation of an object file. |
| |
| @item -gnatwf |
| @emph{Activate warnings on unreferenced formals.} |
| @cindex @option{-gnatwf} (@command{gcc}) |
| @cindex Formals, unreferenced |
| This switch causes a warning to be generated if a formal parameter |
| is not referenced in the body of the subprogram. This warning can |
| also be turned on using @option{-gnatwa} or @option{-gnatwu}. |
| |
| @item -gnatwF |
| @emph{Suppress warnings on unreferenced formals.} |
| @cindex @option{-gnatwF} (@command{gcc}) |
| This switch suppresses warnings for unreferenced formal |
| parameters. Note that the |
| combination @option{-gnatwu} followed by @option{-gnatwF} has the |
| effect of warning on unreferenced entities other than subprogram |
| formals. |
| |
| @item -gnatwg |
| @emph{Activate warnings on unrecognized pragmas.} |
| @cindex @option{-gnatwg} (@command{gcc}) |
| @cindex Pragmas, unrecognized |
| This switch causes a warning to be generated if an unrecognized |
| pragma is encountered. Apart from issuing this warning, the |
| pragma is ignored and has no effect. This warning can |
| also be turned on using @option{-gnatwa}. The default |
| is that such warnings are issued (satisfying the Ada Reference |
| Manual requirement that such warnings appear). |
| |
| @item -gnatwG |
| @emph{Suppress warnings on unrecognized pragmas.} |
| @cindex @option{-gnatwG} (@command{gcc}) |
| This switch suppresses warnings for unrecognized pragmas. |
| |
| @item -gnatwh |
| @emph{Activate warnings on hiding.} |
| @cindex @option{-gnatwh} (@command{gcc}) |
| @cindex Hiding of Declarations |
| This switch activates warnings on hiding declarations. |
| A declaration is considered hiding |
| if it is for a non-overloadable entity, and it declares an entity with the |
| same name as some other entity that is directly or use-visible. The default |
| is that such warnings are not generated. |
| Note that @option{-gnatwa} does not affect the setting of this warning option. |
| |
| @item -gnatwH |
| @emph{Suppress warnings on hiding.} |
| @cindex @option{-gnatwH} (@command{gcc}) |
| This switch suppresses warnings on hiding declarations. |
| |
| @item -gnatwi |
| @emph{Activate warnings on implementation units.} |
| @cindex @option{-gnatwi} (@command{gcc}) |
| This switch activates warnings for a @code{with} of an internal GNAT |
| implementation unit, defined as any unit from the @code{Ada}, |
| @code{Interfaces}, @code{GNAT}, |
| ^^@code{DEC},^ or @code{System} |
| hierarchies that is not |
| documented in either the Ada Reference Manual or the GNAT |
| Programmer's Reference Manual. Such units are intended only |
| for internal implementation purposes and should not be @code{with}'ed |
| by user programs. The default is that such warnings are generated |
| This warning can also be turned on using @option{-gnatwa}. |
| |
| @item -gnatwI |
| @emph{Disable warnings on implementation units.} |
| @cindex @option{-gnatwI} (@command{gcc}) |
| This switch disables warnings for a @code{with} of an internal GNAT |
| implementation unit. |
| |
| @item -gnatwj |
| @emph{Activate warnings on obsolescent features (Annex J).} |
| @cindex @option{-gnatwj} (@command{gcc}) |
| @cindex Features, obsolescent |
| @cindex Obsolescent features |
| If this warning option is activated, then warnings are generated for |
| calls to subprograms marked with @code{pragma Obsolescent} and |
| for use of features in Annex J of the Ada Reference Manual. In the |
| case of Annex J, not all features are flagged. In particular use |
| of the renamed packages (like @code{Text_IO}) and use of package |
| @code{ASCII} are not flagged, since these are very common and |
| would generate many annoying positive warnings. The default is that |
| such warnings are not generated. |
| |
| In addition to the above cases, warnings are also generated for |
| GNAT features that have been provided in past versions but which |
| have been superseded (typically by features in the new Ada standard). |
| For example, @code{pragma Ravenscar} will be flagged since its |
| function is replaced by @code{pragma Profile(Ravenscar)}. |
| |
| Note that this warning option functions differently from the |
| restriction @code{No_Obsolescent_Features} in two respects. |
| First, the restriction applies only to annex J features. |
| Second, the restriction does flag uses of package @code{ASCII}. |
| |
| @item -gnatwJ |
| @emph{Suppress warnings on obsolescent features (Annex J).} |
| @cindex @option{-gnatwJ} (@command{gcc}) |
| This switch disables warnings on use of obsolescent features. |
| |
| @item -gnatwk |
| @emph{Activate warnings on variables that could be constants.} |
| @cindex @option{-gnatwk} (@command{gcc}) |
| This switch activates warnings for variables that are initialized but |
| never modified, and then could be declared constants. |
| |
| @item -gnatwK |
| @emph{Suppress warnings on variables that could be constants.} |
| @cindex @option{-gnatwK} (@command{gcc}) |
| This switch disables warnings on variables that could be declared constants. |
| |
| @item -gnatwl |
| @emph{Activate warnings for missing elaboration pragmas.} |
| @cindex @option{-gnatwl} (@command{gcc}) |
| @cindex Elaboration, warnings |
| This switch activates warnings on missing |
| @code{Elaborate_All} and @code{Elaborate} pragmas. |
| See the section in this guide on elaboration checking for details on |
| when such pragmas should be used. Warnings are also generated if you |
| are using the static mode of elaboration, and a @code{pragma Elaborate} |
| is encountered. The default is that such warnings |
| are not generated. |
| This warning is not automatically turned on by the use of @option{-gnatwa}. |
| |
| @item -gnatwL |
| @emph{Suppress warnings for missing elaboration pragmas.} |
| @cindex @option{-gnatwL} (@command{gcc}) |
| This switch suppresses warnings on missing Elaborate and Elaborate_All pragmas. |
| See the section in this guide on elaboration checking for details on |
| when such pragmas should be used. |
| |
| @item -gnatwm |
| @emph{Activate warnings on modified but unreferenced variables.} |
| @cindex @option{-gnatwm} (@command{gcc}) |
| This switch activates warnings for variables that are assigned (using |
| an initialization value or with one or more assignment statements) but |
| whose value is never read. The warning is suppressed for volatile |
| variables and also for variables that are renamings of other variables |
| or for which an address clause is given. |
| This warning can also be turned on using @option{-gnatwa}. |
| |
| @item -gnatwM |
| @emph{Disable warnings on modified but unreferenced variables.} |
| @cindex @option{-gnatwM} (@command{gcc}) |
| This switch disables warnings for variables that are assigned or |
| initialized, but never read. |
| |
| @item -gnatwn |
| @emph{Set normal warnings mode.} |
| @cindex @option{-gnatwn} (@command{gcc}) |
| This switch sets normal warning mode, in which enabled warnings are |
| issued and treated as warnings rather than errors. This is the default |
| mode. the switch @option{-gnatwn} can be used to cancel the effect of |
| an explicit @option{-gnatws} or |
| @option{-gnatwe}. It also cancels the effect of the |
| implicit @option{-gnatwe} that is activated by the |
| use of @option{-gnatg}. |
| |
| @item -gnatwo |
| @emph{Activate warnings on address clause overlays.} |
| @cindex @option{-gnatwo} (@command{gcc}) |
| @cindex Address Clauses, warnings |
| This switch activates warnings for possibly unintended initialization |
| effects of defining address clauses that cause one variable to overlap |
| another. The default is that such warnings are generated. |
| This warning can also be turned on using @option{-gnatwa}. |
| |
| @item -gnatwO |
| @emph{Suppress warnings on address clause overlays.} |
| @cindex @option{-gnatwO} (@command{gcc}) |
| This switch suppresses warnings on possibly unintended initialization |
| effects of defining address clauses that cause one variable to overlap |
| another. |
| |
| @item -gnatwp |
| @emph{Activate warnings on ineffective pragma Inlines.} |
| @cindex @option{-gnatwp} (@command{gcc}) |
| @cindex Inlining, warnings |
| This switch activates warnings for failure of front end inlining |
| (activated by @option{-gnatN}) to inline a particular call. There are |
| many reasons for not being able to inline a call, including most |
| commonly that the call is too complex to inline. |
| This warning can also be turned on using @option{-gnatwa}. |
| |
| @item -gnatwP |
| @emph{Suppress warnings on ineffective pragma Inlines.} |
| @cindex @option{-gnatwP} (@command{gcc}) |
| This switch suppresses warnings on ineffective pragma Inlines. If the |
| inlining mechanism cannot inline a call, it will simply ignore the |
| request silently. |
| |
| @item -gnatwr |
| @emph{Activate warnings on redundant constructs.} |
| @cindex @option{-gnatwr} (@command{gcc}) |
| This switch activates warnings for redundant constructs. The following |
| is the current list of constructs regarded as redundant: |
| This warning can also be turned on using @option{-gnatwa}. |
| |
| @itemize @bullet |
| @item |
| Assignment of an item to itself. |
| @item |
| Type conversion that converts an expression to its own type. |
| @item |
| Use of the attribute @code{Base} where @code{typ'Base} is the same |
| as @code{typ}. |
| @item |
| Use of pragma @code{Pack} when all components are placed by a record |
| representation clause. |
| @item |
| Exception handler containing only a reraise statement (raise with no |
| operand) which has no effect. |
| @item |
| Use of the operator abs on an operand that is known at compile time |
| to be non-negative |
| @item |
| Comparison of boolean expressions to an explicit True value. |
| @end itemize |
| |
| @item -gnatwR |
| @emph{Suppress warnings on redundant constructs.} |
| @cindex @option{-gnatwR} (@command{gcc}) |
| This switch suppresses warnings for redundant constructs. |
| |
| @item -gnatws |
| @emph{Suppress all warnings.} |
| @cindex @option{-gnatws} (@command{gcc}) |
| This switch completely suppresses the |
| output of all warning messages from the GNAT front end. |
| Note that it does not suppress warnings from the @command{gcc} back end. |
| To suppress these back end warnings as well, use the switch @option{-w} |
| in addition to @option{-gnatws}. |
| |
| @item -gnatwu |
| @emph{Activate warnings on unused entities.} |
| @cindex @option{-gnatwu} (@command{gcc}) |
| This switch activates warnings to be generated for entities that |
| are declared but not referenced, and for units that are @code{with}'ed |
| and not |
| referenced. In the case of packages, a warning is also generated if |
| no entities in the package are referenced. This means that if the package |
| is referenced but the only references are in @code{use} |
| clauses or @code{renames} |
| declarations, a warning is still generated. A warning is also generated |
| for a generic package that is @code{with}'ed but never instantiated. |
| In the case where a package or subprogram body is compiled, and there |
| is a @code{with} on the corresponding spec |
| that is only referenced in the body, |
| a warning is also generated, noting that the |
| @code{with} can be moved to the body. The default is that |
| such warnings are not generated. |
| This switch also activates warnings on unreferenced formals |
| (it includes the effect of @option{-gnatwf}). |
| This warning can also be turned on using @option{-gnatwa}. |
| |
| @item -gnatwU |
| @emph{Suppress warnings on unused entities.} |
| @cindex @option{-gnatwU} (@command{gcc}) |
| This switch suppresses warnings for unused entities and packages. |
| It also turns off warnings on unreferenced formals (and thus includes |
| the effect of @option{-gnatwF}). |
| |
| @item -gnatwv |
| @emph{Activate warnings on unassigned variables.} |
| @cindex @option{-gnatwv} (@command{gcc}) |
| @cindex Unassigned variable warnings |
| This switch activates warnings for access to variables which |
| may not be properly initialized. The default is that |
| such warnings are generated. |
| |
| @item -gnatwV |
| @emph{Suppress warnings on unassigned variables.} |
| @cindex @option{-gnatwV} (@command{gcc}) |
| This switch suppresses warnings for access to variables which |
| may not be properly initialized. |
| |
| @item -gnatwy |
| @emph{Activate warnings for Ada 2005 compatibility issues.} |
| @cindex @option{-gnatwy} (@command{gcc}) |
| @cindex Ada 2005 compatibility issues warnings |
| For the most part Ada 2005 is upwards compatible with Ada 95, |
| but there are some exceptions (for example the fact that |
| @code{interface} is now a reserved word in Ada 2005). This |
| switch activates several warnings to help in identifying |
| and correcting such incompatibilities. The default is that |
| these warnings are generated. Note that at one point Ada 2005 |
| was called Ada 0Y, hence the choice of character. |
| |
| @item -gnatwY |
| @emph{Disable warnings for Ada 2005 compatibility issues.} |
| @cindex @option{-gnatwY} (@command{gcc}) |
| @cindex Ada 2005 compatibility issues warnings |
| This switch suppresses several warnings intended to help in identifying |
| incompatibilities between Ada 95 and Ada 2005. |
| |
| @item -gnatwx |
| @emph{Activate warnings on Export/Import pragmas.} |
| @cindex @option{-gnatwx} (@command{gcc}) |
| @cindex Export/Import pragma warnings |
| This switch activates warnings on Export/Import pragmas when |
| the compiler detects a possible conflict between the Ada and |
| foreign language calling sequences. For example, the use of |
| default parameters in a convention C procedure is dubious |
| because the C compiler cannot supply the proper default, so |
| a warning is issued. The default is that such warnings are |
| generated. |
| |
| @item -gnatwX |
| @emph{Suppress warnings on Export/Import pragmas.} |
| @cindex @option{-gnatwX} (@command{gcc}) |
| This switch suppresses warnings on Export/Import pragmas. |
| The sense of this is that you are telling the compiler that |
| you know what you are doing in writing the pragma, and it |
| should not complain at you. |
| |
| @item -gnatwz |
| @emph{Activate warnings on unchecked conversions.} |
| @cindex @option{-gnatwz} (@command{gcc}) |
| @cindex Unchecked_Conversion warnings |
| This switch activates warnings for unchecked conversions |
| where the types are known at compile time to have different |
| sizes. The default |
| is that such warnings are generated. |
| |
| @item -gnatwZ |
| @emph{Suppress warnings on unchecked conversions.} |
| @cindex @option{-gnatwZ} (@command{gcc}) |
| This switch suppresses warnings for unchecked conversions |
| where the types are known at compile time to have different |
| sizes. |
| |
| @item ^-Wuninitialized^WARNINGS=UNINITIALIZED^ |
| @cindex @option{-Wuninitialized} |
| The warnings controlled by the @option{-gnatw} switch are generated by the |
| front end of the compiler. In some cases, the @option{^gcc^GCC^} back end |
| can provide additional warnings. One such useful warning is provided by |
| @option{^-Wuninitialized^WARNINGS=UNINITIALIZED^}. This must be used in |
| conjunction with turning on optimization mode. This causes the flow |
| analysis circuits of the back end optimizer to output additional |
| warnings about uninitialized variables. |
| |
| @item ^-w^/NO_BACK_END_WARNINGS^ |
| @cindex @option{-w} |
| This switch suppresses warnings from the @option{^gcc^GCC^} back end. The |
| code generator detects a number of warning situations that are missed |
| by the @option{GNAT} front end, and this switch can be used to suppress them. |
| The use of this switch also sets the default front end warning mode to |
| @option{-gnatws}, that is, front end warnings suppressed as well. |
| |
| @end table |
| |
| @noindent |
| @ifclear vms |
| A string of warning parameters can be used in the same parameter. For example: |
| |
| @smallexample |
| -gnatwaLe |
| @end smallexample |
| |
| @noindent |
| will turn on all optional warnings except for elaboration pragma warnings, |
| and also specify that warnings should be treated as errors. |
| @end ifclear |
| When no switch @option{^-gnatw^/WARNINGS^} is used, this is equivalent to: |
| |
| @table @option |
| @c !sort! |
| @item -gnatwC |
| @item -gnatwD |
| @item -gnatwF |
| @item -gnatwg |
| @item -gnatwH |
| @item -gnatwi |
| @item -gnatwJ |
| @item -gnatwK |
| @item -gnatwL |
| @item -gnatwM |
| @item -gnatwn |
| @item -gnatwo |
| @item -gnatwP |
| @item -gnatwR |
| @item -gnatwU |
| @item -gnatwv |
| @item -gnatwz |
| @item -gnatwx |
| |
| @end table |
| |
| @node Debugging and Assertion Control |
| @subsection Debugging and Assertion Control |
| |
| @table @option |
| @item -gnata |
| @cindex @option{-gnata} (@command{gcc}) |
| @findex Assert |
| @findex Debug |
| @cindex Assertions |
| |
| @noindent |
| The pragmas @code{Assert} and @code{Debug} normally have no effect and |
| are ignored. This switch, where @samp{a} stands for assert, causes |
| @code{Assert} and @code{Debug} pragmas to be activated. |
| |
| The pragmas have the form: |
| |
| @smallexample |
| @cartouche |
| @b{pragma} Assert (@var{Boolean-expression} [, |
| @var{static-string-expression}]) |
| @b{pragma} Debug (@var{procedure call}) |
| @end cartouche |
| @end smallexample |
| |
| @noindent |
| The @code{Assert} pragma causes @var{Boolean-expression} to be tested. |
| If the result is @code{True}, the pragma has no effect (other than |
| possible side effects from evaluating the expression). If the result is |
| @code{False}, the exception @code{Assert_Failure} declared in the package |
| @code{System.Assertions} is |
| raised (passing @var{static-string-expression}, if present, as the |
| message associated with the exception). If no string expression is |
| given the default is a string giving the file name and line number |
| of the pragma. |
| |
| The @code{Debug} pragma causes @var{procedure} to be called. Note that |
| @code{pragma Debug} may appear within a declaration sequence, allowing |
| debugging procedures to be called between declarations. |
| |
| @ifset vms |
| @item /DEBUG[=debug-level] |
| @itemx /NODEBUG |
| Specifies how much debugging information is to be included in |
| the resulting object file where 'debug-level' is one of the following: |
| @table @code |
| @item TRACEBACK |
| Include both debugger symbol records and traceback |
| the object file. |
| This is the default setting. |
| @item ALL |
| Include both debugger symbol records and traceback in |
| object file. |
| @item NONE |
| Excludes both debugger symbol records and traceback |
| the object file. Same as /NODEBUG. |
| @item SYMBOLS |
| Includes only debugger symbol records in the object |
| file. Note that this doesn't include traceback information. |
| @end table |
| @end ifset |
| @end table |
| |
| @node Validity Checking |
| @subsection Validity Checking |
| @findex Validity Checking |
| |
| @noindent |
| The Ada 95 Reference Manual has specific requirements for checking |
| for invalid values. In particular, RM 13.9.1 requires that the |
| evaluation of invalid values (for example from unchecked conversions), |
| not result in erroneous execution. In GNAT, the result of such an |
| evaluation in normal default mode is to either use the value |
| unmodified, or to raise Constraint_Error in those cases where use |
| of the unmodified value would cause erroneous execution. The cases |
| where unmodified values might lead to erroneous execution are case |
| statements (where a wild jump might result from an invalid value), |
| and subscripts on the left hand side (where memory corruption could |
| occur as a result of an invalid value). |
| |
| The @option{-gnatV^@var{x}^^} switch allows more control over the validity |
| checking mode. |
| @ifclear vms |
| The @code{x} argument is a string of letters that |
| indicate validity checks that are performed or not performed in addition |
| to the default checks described above. |
| @end ifclear |
| @ifset vms |
| The options allowed for this qualifier |
| indicate validity checks that are performed or not performed in addition |
| to the default checks described above. |
| @end ifset |
| |
| @table @option |
| @c !sort! |
| @item -gnatVa |
| @emph{All validity checks.} |
| @cindex @option{-gnatVa} (@command{gcc}) |
| All validity checks are turned on. |
| @ifclear vms |
| That is, @option{-gnatVa} is |
| equivalent to @option{gnatVcdfimorst}. |
| @end ifclear |
| |
| @item -gnatVc |
| @emph{Validity checks for copies.} |
| @cindex @option{-gnatVc} (@command{gcc}) |
| The right hand side of assignments, and the initializing values of |
| object declarations are validity checked. |
| |
| @item -gnatVd |
| @emph{Default (RM) validity checks.} |
| @cindex @option{-gnatVd} (@command{gcc}) |
| Some validity checks are done by default following normal Ada semantics |
| (RM 13.9.1 (9-11)). |
| A check is done in case statements that the expression is within the range |
| of the subtype. If it is not, Constraint_Error is raised. |
| For assignments to array components, a check is done that the expression used |
| as index is within the range. If it is not, Constraint_Error is raised. |
| Both these validity checks may be turned off using switch @option{-gnatVD}. |
| They are turned on by default. If @option{-gnatVD} is specified, a subsequent |
| switch @option{-gnatVd} will leave the checks turned on. |
| Switch @option{-gnatVD} should be used only if you are sure that all such |
| expressions have valid values. If you use this switch and invalid values |
| are present, then the program is erroneous, and wild jumps or memory |
| overwriting may occur. |
| |
| @item -gnatVf |
| @emph{Validity checks for floating-point values.} |
| @cindex @option{-gnatVf} (@command{gcc}) |
| In the absence of this switch, validity checking occurs only for discrete |
| values. If @option{-gnatVf} is specified, then validity checking also applies |
| for floating-point values, and NaN's and infinities are considered invalid, |
| as well as out of range values for constrained types. Note that this means |
| that standard @code{IEEE} infinity mode is not allowed. The exact contexts |
| in which floating-point values are checked depends on the setting of other |
| options. For example, |
| @option{^-gnatVif^VALIDITY_CHECKING=(IN_PARAMS,FLOATS)^} or |
| @option{^-gnatVfi^VALIDITY_CHECKING=(FLOATS,IN_PARAMS)^} |
| (the order does not matter) specifies that floating-point parameters of mode |
| @code{in} should be validity checked. |
| |
| @item -gnatVi |
| @emph{Validity checks for @code{in} mode parameters} |
| @cindex @option{-gnatVi} (@command{gcc}) |
| Arguments for parameters of mode @code{in} are validity checked in function |
| and procedure calls at the point of call. |
| |
| @item -gnatVm |
| @emph{Validity checks for @code{in out} mode parameters.} |
| @cindex @option{-gnatVm} (@command{gcc}) |
| Arguments for parameters of mode @code{in out} are validity checked in |
| procedure calls at the point of call. The @code{'m'} here stands for |
| modify, since this concerns parameters that can be modified by the call. |
| Note that there is no specific option to test @code{out} parameters, |
| but any reference within the subprogram will be tested in the usual |
| manner, and if an invalid value is copied back, any reference to it |
| will be subject to validity checking. |
| |
| @item -gnatVn |
| @emph{No validity checks.} |
| @cindex @option{-gnatVn} (@command{gcc}) |
| This switch turns off all validity checking, including the default checking |
| for case statements and left hand side subscripts. Note that the use of |
| the switch @option{-gnatp} suppresses all run-time checks, including |
| validity checks, and thus implies @option{-gnatVn}. When this switch |
| is used, it cancels any other @option{-gnatV} previously issued. |
| |
| @item -gnatVo |
| @emph{Validity checks for operator and attribute operands.} |
| @cindex @option{-gnatVo} (@command{gcc}) |
| Arguments for predefined operators and attributes are validity checked. |
| This includes all operators in package @code{Standard}, |
| the shift operators defined as intrinsic in package @code{Interfaces} |
| and operands for attributes such as @code{Pos}. Checks are also made |
| on individual component values for composite comparisons, and on the |
| expressions in type conversions and qualified expressions. |
| |
| @item -gnatVp |
| @emph{Validity checks for parameters.} |
| @cindex @option{-gnatVp} (@command{gcc}) |
| This controls the treatment of parameters within a subprogram (as opposed |
| to @option{-gnatVi} and @option{-gnatVm} which control validity testing |
| of parameters on a call. If either of these call options is used, then |
| normally an assumption is made within a subprogram that the input arguments |
| have been validity checking at the point of call, and do not need checking |
| again within a subprogram). If @option{-gnatVp} is set, then this assumption |
| is not made, and parameters are not assumed to be valid, so their validity |
| will be checked (or rechecked) within the subprogram. |
| |
| @item -gnatVr |
| @emph{Validity checks for function returns.} |
| @cindex @option{-gnatVr} (@command{gcc}) |
| The expression in @code{return} statements in functions is validity |
| checked. |
| |
| @item -gnatVs |
| @emph{Validity checks for subscripts.} |
| @cindex @option{-gnatVs} (@command{gcc}) |
| All subscripts expressions are checked for validity, whether they appear |
| on the right side or left side (in default mode only left side subscripts |
| are validity checked). |
| |
| @item -gnatVt |
| @emph{Validity checks for tests.} |
| @cindex @option{-gnatVt} (@command{gcc}) |
| Expressions used as conditions in @code{if}, @code{while} or @code{exit} |
| statements are checked, as well as guard expressions in entry calls. |
| |
| @end table |
| |
| @noindent |
| The @option{-gnatV} switch may be followed by |
| ^a string of letters^a list of options^ |
| to turn on a series of validity checking options. |
| For example, |
| @option{^-gnatVcr^/VALIDITY_CHECKING=(COPIES, RETURNS)^} |
| specifies that in addition to the default validity checking, copies and |
| function return expressions are to be validity checked. |
| In order to make it easier |
| to specify the desired combination of effects, |
| @ifclear vms |
| the upper case letters @code{CDFIMORST} may |
| be used to turn off the corresponding lower case option. |
| @end ifclear |
| @ifset vms |
| the prefix @code{NO} on an option turns off the corresponding validity |
| checking: |
| @itemize @bullet |
| @item @code{NOCOPIES} |
| @item @code{NODEFAULT} |
| @item @code{NOFLOATS} |
| @item @code{NOIN_PARAMS} |
| @item @code{NOMOD_PARAMS} |
| @item @code{NOOPERANDS} |
| @item @code{NORETURNS} |
| @item @code{NOSUBSCRIPTS} |
| @item @code{NOTESTS} |
| @end itemize |
| @end ifset |
| Thus |
| @option{^-gnatVaM^/VALIDITY_CHECKING=(ALL, NOMOD_PARAMS)^} |
| turns on all validity checking options except for |
| checking of @code{@b{in out}} procedure arguments. |
| |
| The specification of additional validity checking generates extra code (and |
| in the case of @option{-gnatVa} the code expansion can be substantial. |
| However, these additional checks can be very useful in detecting |
| uninitialized variables, incorrect use of unchecked conversion, and other |
| errors leading to invalid values. The use of pragma @code{Initialize_Scalars} |
| is useful in conjunction with the extra validity checking, since this |
| ensures that wherever possible uninitialized variables have invalid values. |
| |
| See also the pragma @code{Validity_Checks} which allows modification of |
| the validity checking mode at the program source level, and also allows for |
| temporary disabling of validity checks. |
| |
| @node Style Checking |
| @subsection Style Checking |
| @findex Style checking |
| |
| @noindent |
| The @option{-gnaty^x^(option,option,...)^} switch |
| @cindex @option{-gnaty} (@command{gcc}) |
| causes the compiler to |
| enforce specified style rules. A limited set of style rules has been used |
| in writing the GNAT sources themselves. This switch allows user programs |
| to activate all or some of these checks. If the source program fails a |
| specified style check, an appropriate warning message is given, preceded by |
| the character sequence ``(style)''. |
| @ifset vms |
| @code{(option,option,...)} is a sequence of keywords |
| @end ifset |
| @ifclear vms |
| The string @var{x} is a sequence of letters or digits |
| @end ifclear |
| indicating the particular style |
| checks to be performed. The following checks are defined: |
| |
| @table @option |
| @c !sort! |
| @item 1-9 |
| @emph{Specify indentation level.} |
| If a digit from 1-9 appears |
| ^in the string after @option{-gnaty}^as an option for /STYLE_CHECKS^ |
| then proper indentation is checked, with the digit indicating the |
| indentation level required. |
| The general style of required indentation is as specified by |
| the examples in the Ada Reference Manual. Full line comments must be |
| aligned with the @code{--} starting on a column that is a multiple of |
| the alignment level. |
| |
| @item ^a^ATTRIBUTE^ |
| @emph{Check attribute casing.} |
| If the ^letter a^word ATTRIBUTE^ appears in the string after @option{-gnaty} |
| then attribute names, including the case of keywords such as @code{digits} |
| used as attributes names, must be written in mixed case, that is, the |
| initial letter and any letter following an underscore must be uppercase. |
| All other letters must be lowercase. |
| |
| @item ^b^BLANKS^ |
| @emph{Blanks not allowed at statement end.} |
| If the ^letter b^word BLANKS^ appears in the string after @option{-gnaty} then |
| trailing blanks are not allowed at the end of statements. The purpose of this |
| rule, together with h (no horizontal tabs), is to enforce a canonical format |
| for the use of blanks to separate source tokens. |
| |
| @item ^c^COMMENTS^ |
| @emph{Check comments.} |
| If the ^letter c^word COMMENTS^ appears in the string after @option{-gnaty} |
| then comments must meet the following set of rules: |
| |
| @itemize @bullet |
| |
| @item |
| The ``@code{--}'' that starts the column must either start in column one, |
| or else at least one blank must precede this sequence. |
| |
| @item |
| Comments that follow other tokens on a line must have at least one blank |
| following the ``@code{--}'' at the start of the comment. |
| |
| @item |
| Full line comments must have two blanks following the ``@code{--}'' that |
| starts the comment, with the following exceptions. |
| |
| @item |
| A line consisting only of the ``@code{--}'' characters, possibly preceded |
| by blanks is permitted. |
| |
| @item |
| A comment starting with ``@code{--x}'' where @code{x} is a special character |
| is permitted. |
| This allows proper processing of the output generated by specialized tools |
| including @command{gnatprep} (where ``@code{--!}'' is used) and the SPARK |
| annotation |
| language (where ``@code{--#}'' is used). For the purposes of this rule, a |
| special character is defined as being in one of the ASCII ranges |
| @code{16#21#..16#2F#} or @code{16#3A#..16#3F#}. |
| Note that this usage is not permitted |
| in GNAT implementation units (i.e. when @option{-gnatg} is used). |
| |
| @item |
| A line consisting entirely of minus signs, possibly preceded by blanks, is |
| permitted. This allows the construction of box comments where lines of minus |
| signs are used to form the top and bottom of the box. |
| |
| @item |
| A comment that starts and ends with ``@code{--}'' is permitted as long as at |
| least one blank follows the initial ``@code{--}''. Together with the preceding |
| rule, this allows the construction of box comments, as shown in the following |
| example: |
| @smallexample |
| --------------------------- |
| -- This is a box comment -- |
| -- with two text lines. -- |
| --------------------------- |
| @end smallexample |
| @end itemize |
| |
| @item ^d^DOS_LINE_ENDINGS^ |
| @emph{Check no DOS line terminators present.} |
| If the ^letter d^word DOS_LINE_ENDINGS^ appears in the string after |
| @option{-gnaty} then all lines must be terminated by a single ASCII.LF |
| character (in particular the DOS line terminator sequence CR/LF is not |
| allowed). |
| |
| @item ^e^END^ |
| @emph{Check end/exit labels.} |
| If the ^letter e^word END^ appears in the string after @option{-gnaty} then |
| optional labels on @code{end} statements ending subprograms and on |
| @code{exit} statements exiting named loops, are required to be present. |
| |
| @item ^f^VTABS^ |
| @emph{No form feeds or vertical tabs.} |
| If the ^letter f^word VTABS^ appears in the string after @option{-gnaty} then |
| neither form feeds nor vertical tab characters are permitted |
| in the source text. |
| |
| @item ^h^HTABS^ |
| @emph{No horizontal tabs.} |
| If the ^letter h^word HTABS^ appears in the string after @option{-gnaty} then |
| horizontal tab characters are not permitted in the source text. |
| Together with the b (no blanks at end of line) check, this |
| enforces a canonical form for the use of blanks to separate |
| source tokens. |
| |
| @item ^i^IF_THEN^ |
| @emph{Check if-then layout.} |
| If the ^letter i^word IF_THEN^ appears in the string after @option{-gnaty}, |
| then the keyword @code{then} must appear either on the same |
| line as corresponding @code{if}, or on a line on its own, lined |
| up under the @code{if} with at least one non-blank line in between |
| containing all or part of the condition to be tested. |
| |
| @item ^I^IN_MODE^ |
| @emph{check mode IN keywords} |
| If the ^letter I (upper case)^word IN_MODE^ appears in the string |
| after @option{-gnaty} then mode @code{in} (the default mode) is not |
| allowed to be given explicitly. @code{in out} is fine, |
| but not @code{in} on its own. |
| |
| @item ^k^KEYWORD^ |
| @emph{Check keyword casing.} |
| If the ^letter k^word KEYWORD^ appears in the string after @option{-gnaty} then |
| all keywords must be in lower case (with the exception of keywords |
| such as @code{digits} used as attribute names to which this check |
| does not apply). |
| |
| @item ^l^LAYOUT^ |
| @emph{Check layout.} |
| If the ^letter l^word LAYOUT^ appears in the string after @option{-gnaty} then |
| layout of statement and declaration constructs must follow the |
| recommendations in the Ada Reference Manual, as indicated by the |
| form of the syntax rules. For example an @code{else} keyword must |
| be lined up with the corresponding @code{if} keyword. |
| |
| There are two respects in which the style rule enforced by this check |
| option are more liberal than those in the Ada Reference Manual. First |
| in the case of record declarations, it is permissible to put the |
| @code{record} keyword on the same line as the @code{type} keyword, and |
| then the @code{end} in @code{end record} must line up under @code{type}. |
| For example, either of the following two layouts is acceptable: |
| |
| @smallexample @c ada |
| @cartouche |
| type q is record |
| a : integer; |
| b : integer; |
| end record; |
| |
| type q is |
| record |
| a : integer; |
| b : integer; |
| end record; |
| @end cartouche |
| @end smallexample |
| |
| @noindent |
| Second, in the case of a block statement, a permitted alternative |
| is to put the block label on the same line as the @code{declare} or |
| @code{begin} keyword, and then line the @code{end} keyword up under |
| the block label. For example both the following are permitted: |
| |
| @smallexample @c ada |
| @cartouche |
| Block : declare |
| A : Integer := 3; |
| begin |
| Proc (A, A); |
| end Block; |
| |
| Block : |
| declare |
| A : Integer := 3; |
| begin |
| Proc (A, A); |
| end Block; |
| @end cartouche |
| @end smallexample |
| |
| @noindent |
| The same alternative format is allowed for loops. For example, both of |
| the following are permitted: |
| |
| @smallexample @c ada |
| @cartouche |
| Clear : while J < 10 loop |
| A (J) := 0; |
| end loop Clear; |
| |
| Clear : |
| while J < 10 loop |
| A (J) := 0; |
| end loop Clear; |
| @end cartouche |
| @end smallexample |
| |
| @item ^Lnnn^MAX_NESTING=nnn^ |
| @emph{Set maximum nesting level} |
| If the sequence ^Lnnn^MAX_NESTING=nnn^, where nnn is a decimal number in |
| the range 0-999, appears in the string after @option{-gnaty} then the |
| maximum level of nesting of constructs (including subprograms, loops, |
| blocks, packages, and conditionals) may not exceed the given value. A |
| value of zero disconnects this style check. |
| |
| @item ^m^LINE_LENGTH^ |
| @emph{Check maximum line length.} |
| If the ^letter m^word LINE_LENGTH^ appears in the string after @option{-gnaty} |
| then the length of source lines must not exceed 79 characters, including |
| any trailing blanks. The value of 79 allows convenient display on an |
| 80 character wide device or window, allowing for possible special |
| treatment of 80 character lines. Note that this count is of |
| characters in the source text. This means that a tab character counts |
| as one character in this count but a wide character sequence counts as |
| a single character (however many bytes are needed in the encoding). |
| |
| @item ^Mnnn^MAX_LENGTH=nnn^ |
| @emph{Set maximum line length.} |
| If the sequence ^M^MAX_LENGTH=^nnn, where nnn is a decimal number, appears in |
| the string after @option{-gnaty} then the length of lines must not exceed the |
| given value. The maximum value that can be specified is 32767. |
| |
| @item ^n^STANDARD_CASING^ |
| @emph{Check casing of entities in Standard.} |
| If the ^letter n^word STANDARD_CASING^ appears in the string |
| after @option{-gnaty} then any identifier from Standard must be cased |
| to match the presentation in the Ada Reference Manual (for example, |
| @code{Integer} and @code{ASCII.NUL}). |
| |
| @item ^o^ORDERED_SUBPROGRAMS^ |
| @emph{Check order of subprogram bodies.} |
| If the ^letter o^word ORDERED_SUBPROGRAMS^ appears in the string |
| after @option{-gnaty} then all subprogram bodies in a given scope |
| (e.g. a package body) must be in alphabetical order. The ordering |
| rule uses normal Ada rules for comparing strings, ignoring casing |
| of letters, except that if there is a trailing numeric suffix, then |
| the value of this suffix is used in the ordering (e.g. Junk2 comes |
| before Junk10). |
| |
| @item ^p^PRAGMA^ |
| @emph{Check pragma casing.} |
| If the ^letter p^word PRAGMA^ appears in the string after @option{-gnaty} then |
| pragma names must be written in mixed case, that is, the |
| initial letter and any letter following an underscore must be uppercase. |
| All other letters must be lowercase. |
| |
| @item ^r^REFERENCES^ |
| @emph{Check references.} |
| If the ^letter r^word REFERENCES^ appears in the string after @option{-gnaty} |
| then all identifier references must be cased in the same way as the |
| corresponding declaration. No specific casing style is imposed on |
| identifiers. The only requirement is for consistency of references |
| with declarations. |
| |
| @item ^s^SPECS^ |
| @emph{Check separate specs.} |
| If the ^letter s^word SPECS^ appears in the string after @option{-gnaty} then |
| separate declarations (``specs'') are required for subprograms (a |
| body is not allowed to serve as its own declaration). The only |
| exception is that parameterless library level procedures are |
| not required to have a separate declaration. This exception covers |
| the most frequent form of main program procedures. |
| |
| @item ^t^TOKEN^ |
| @emph{Check token spacing.} |
| If the ^letter t^word TOKEN^ appears in the string after @option{-gnaty} then |
| the following token spacing rules are enforced: |
| |
| @itemize @bullet |
| |
| @item |
| The keywords @code{@b{abs}} and @code{@b{not}} must be followed by a space. |
| |
| @item |
| The token @code{=>} must be surrounded by spaces. |
| |
| @item |
| The token @code{<>} must be preceded by a space or a left parenthesis. |
| |
| @item |
| Binary operators other than @code{**} must be surrounded by spaces. |
| There is no restriction on the layout of the @code{**} binary operator. |
| |
| @item |
| Colon must be surrounded by spaces. |
| |
| @item |
| Colon-equal (assignment, initialization) must be surrounded by spaces. |
| |
| @item |
| Comma must be the first non-blank character on the line, or be |
| immediately preceded by a non-blank character, and must be followed |
| by a space. |
| |
| @item |
| If the token preceding a left parenthesis ends with a letter or digit, then |
| a space must separate the two tokens. |
| |
| @item |
| A right parenthesis must either be the first non-blank character on |
| a line, or it must be preceded by a non-blank character. |
| |
| @item |
| A semicolon must not be preceded by a space, and must not be followed by |
| a non-blank character. |
| |
| @item |
| A unary plus or minus may not be followed by a space. |
| |
| @item |
| A vertical bar must be surrounded by spaces. |
| @end itemize |
| |
| @item ^u^UNNECESSARY_BLANK_LINES^ |
| @emph{Check unnecessary blank lines.} |
| Check for unnecessary blank lines. A blank line is considered |
| unnecessary if it appears at the end of the file, or if more than |
| one blank line occurs in sequence. |
| |
| @item ^x^XTRA_PARENS^ |
| @emph{Check extra parentheses.} |
| Check for the use of an unnecessary extra level of parentheses (C-style) |
| around conditions in @code{if} statements, @code{while} statements and |
| @code{exit} statements. |
| |
| @end table |
| |
| @noindent |
| In the above rules, appearing in column one is always permitted, that is, |
| counts as meeting either a requirement for a required preceding space, |
| or as meeting a requirement for no preceding space. |
| |
| Appearing at the end of a line is also always permitted, that is, counts |
| as meeting either a requirement for a following space, or as meeting |
| a requirement for no following space. |
| |
| @noindent |
| If any of these style rules is violated, a message is generated giving |
| details on the violation. The initial characters of such messages are |
| always ``@code{(style)}''. Note that these messages are treated as warning |
| messages, so they normally do not prevent the generation of an object |
| file. The @option{-gnatwe} switch can be used to treat warning messages, |
| including style messages, as fatal errors. |
| |
| The switch |
| @ifclear vms |
| @option{-gnaty} on its own (that is not |
| followed by any letters or digits), |
| is equivalent to @code{gnaty3abcefhiklmnprst}, that is all checking |
| options enabled with the exception of @option{-gnatyo}, |
| @option{-gnatyd}, @option{-gnatyu}, and @option{-gnatyx}. |
| @end ifclear |
| @ifset vms |
| /STYLE_CHECKS=ALL_BUILTIN enables all checking options with |
| the exception of ORDERED_SUBPROGRAMS, UNNECESSARY_BLANK_LINES, |
| XTRA_PARENS, and DOS_LINE_ENDINGS. In addition |
| @end ifset |
| an indentation level of 3 is set. This is similar to the standard |
| checking option that is used for the GNAT sources. |
| |
| The switch |
| @ifclear vms |
| @option{-gnatyN} |
| @end ifclear |
| @ifset vms |
| /STYLE_CHECKS=NONE |
| @end ifset |
| clears any previously set style checks. |
| |
| @node Run-Time Checks |
| @subsection Run-Time Checks |
| @cindex Division by zero |
| @cindex Access before elaboration |
| @cindex Checks, division by zero |
| @cindex Checks, access before elaboration |
| @cindex Checks, stack overflow checking |
| |
| @noindent |
| If you compile with the default options, GNAT will insert many run-time |
| checks into the compiled code, including code that performs range |
| checking against constraints, but not arithmetic overflow checking for |
| integer operations (including division by zero), checks for access |
| before elaboration on subprogram calls, or stack overflow checking. All |
| other run-time checks, as required by the Ada 95 Reference Manual, are |
| generated by default. The following @command{gcc} switches refine this |
| default behavior: |
| |
| @table @option |
| @c !sort! |
| @item -gnatp |
| @cindex @option{-gnatp} (@command{gcc}) |
| @cindex Suppressing checks |
| @cindex Checks, suppressing |
| @findex Suppress |
| Suppress all run-time checks as though @code{pragma Suppress (all_checks}) |
| had been present in the source. Validity checks are also suppressed (in |
| other words @option{-gnatp} also implies @option{-gnatVn}. |
| Use this switch to improve the performance |
| of the code at the expense of safety in the presence of invalid data or |
| program bugs. |
| |
| @item -gnato |
| @cindex @option{-gnato} (@command{gcc}) |
| @cindex Overflow checks |
| @cindex Check, overflow |
| Enables overflow checking for integer operations. |
| This causes GNAT to generate slower and larger executable |
| programs by adding code to check for overflow (resulting in raising |
| @code{Constraint_Error} as required by standard Ada |
| semantics). These overflow checks correspond to situations in which |
| the true value of the result of an operation may be outside the base |
| range of the result type. The following example shows the distinction: |
| |
| @smallexample @c ada |
| X1 : Integer := Integer'Last; |
| X2 : Integer range 1 .. 5 := 5; |
| X3 : Integer := Integer'Last; |
| X4 : Integer range 1 .. 5 := 5; |
| F : Float := 2.0E+20; |
| ... |
| X1 := X1 + 1; |
| X2 := X2 + 1; |
| X3 := Integer (F); |
| X4 := Integer (F); |
| @end smallexample |
| |
| @noindent |
| Here the first addition results in a value that is outside the base range |
| of Integer, and hence requires an overflow check for detection of the |
| constraint error. Thus the first assignment to @code{X1} raises a |
| @code{Constraint_Error} exception only if @option{-gnato} is set. |
| |
| The second increment operation results in a violation |
| of the explicit range constraint, and such range checks are always |
| performed (unless specifically suppressed with a pragma @code{suppress} |
| or the use of @option{-gnatp}). |
| |
| The two conversions of @code{F} both result in values that are outside |
| the base range of type @code{Integer} and thus will raise |
| @code{Constraint_Error} exceptions only if @option{-gnato} is used. |
| The fact that the result of the second conversion is assigned to |
| variable @code{X4} with a restricted range is irrelevant, since the problem |
| is in the conversion, not the assignment. |
| |
| Basically the rule is that in the default mode (@option{-gnato} not |
| used), the generated code assures that all integer variables stay |
| within their declared ranges, or within the base range if there is |
| no declared range. This prevents any serious problems like indexes |
| out of range for array operations. |
| |
| What is not checked in default mode is an overflow that results in |
| an in-range, but incorrect value. In the above example, the assignments |
| to @code{X1}, @code{X2}, @code{X3} all give results that are within the |
| range of the target variable, but the result is wrong in the sense that |
| it is too large to be represented correctly. Typically the assignment |
| to @code{X1} will result in wrap around to the largest negative number. |
| The conversions of @code{F} will result in some @code{Integer} value |
| and if that integer value is out of the @code{X4} range then the |
| subsequent assignment would generate an exception. |
| |
| @findex Machine_Overflows |
| Note that the @option{-gnato} switch does not affect the code generated |
| for any floating-point operations; it applies only to integer |
| semantics). |
| For floating-point, GNAT has the @code{Machine_Overflows} |
| attribute set to @code{False} and the normal mode of operation is to |
| generate IEEE NaN and infinite values on overflow or invalid operations |
| (such as dividing 0.0 by 0.0). |
| |
| The reason that we distinguish overflow checking from other kinds of |
| range constraint checking is that a failure of an overflow check can |
| generate an incorrect value, but cannot cause erroneous behavior. This |
| is unlike the situation with a constraint check on an array subscript, |
| where failure to perform the check can result in random memory description, |
| or the range check on a case statement, where failure to perform the check |
| can cause a wild jump. |
| |
| Note again that @option{-gnato} is off by default, so overflow checking is |
| not performed in default mode. This means that out of the box, with the |
| default settings, GNAT does not do all the checks expected from the |
| language description in the Ada Reference Manual. If you want all constraint |
| checks to be performed, as described in this Manual, then you must |
| explicitly use the -gnato switch either on the @command{gnatmake} or |
| @command{gcc} command. |
| |
| @item -gnatE |
| @cindex @option{-gnatE} (@command{gcc}) |
| @cindex Elaboration checks |
| @cindex Check, elaboration |
| Enables dynamic checks for access-before-elaboration |
| on subprogram calls and generic instantiations. |
| For full details of the effect and use of this switch, |
| @xref{Compiling Using gcc}. |
| |
| @item -fstack-check |
| @cindex @option{-fstack-check} (@command{gcc}) |
| @cindex Stack Overflow Checking |
| @cindex Checks, stack overflow checking |
| Activates stack overflow checking. For full details of the effect and use of |
| this switch see @ref{Stack Overflow Checking}. |
| @end table |
| |
| @findex Unsuppress |
| @noindent |
| The setting of these switches only controls the default setting of the |
| checks. You may modify them using either @code{Suppress} (to remove |
| checks) or @code{Unsuppress} (to add back suppressed checks) pragmas in |
| the program source. |
| |
| @node Using gcc for Syntax Checking |
| @subsection Using @command{gcc} for Syntax Checking |
| @table @option |
| @item -gnats |
| @cindex @option{-gnats} (@command{gcc}) |
| @ifclear vms |
| |
| @noindent |
| The @code{s} stands for ``syntax''. |
| @end ifclear |
| |
| Run GNAT in syntax checking only mode. For |
| example, the command |
| |
| @smallexample |
| $ gcc -c -gnats x.adb |
| @end smallexample |
| |
| @noindent |
| compiles file @file{x.adb} in syntax-check-only mode. You can check a |
| series of files in a single command |
| @ifclear vms |
| , and can use wild cards to specify such a group of files. |
| Note that you must specify the @option{-c} (compile |
| only) flag in addition to the @option{-gnats} flag. |
| @end ifclear |
| . |
| You may use other switches in conjunction with @option{-gnats}. In |
| particular, @option{-gnatl} and @option{-gnatv} are useful to control the |
| format of any generated error messages. |
| |
| When the source file is empty or contains only empty lines and/or comments, |
| the output is a warning: |
| |
| @smallexample |
| $ gcc -c -gnats -x ada toto.txt |
| toto.txt:1:01: warning: empty file, contains no compilation units |
| $ |
| @end smallexample |
| |
| Otherwise, the output is simply the error messages, if any. No object file or |
| ALI file is generated by a syntax-only compilation. Also, no units other |
| than the one specified are accessed. For example, if a unit @code{X} |
| @code{with}'s a unit @code{Y}, compiling unit @code{X} in syntax |
| check only mode does not access the source file containing unit |
| @code{Y}. |
| |
| @cindex Multiple units, syntax checking |
| Normally, GNAT allows only a single unit in a source file. However, this |
| restriction does not apply in syntax-check-only mode, and it is possible |
| to check a file containing multiple compilation units concatenated |
| together. This is primarily used by the @code{gnatchop} utility |
| (@pxref{Renaming Files Using gnatchop}). |
| @end table |
| |
| @node Using gcc for Semantic Checking |
| @subsection Using @command{gcc} for Semantic Checking |
| @table @option |
| @item -gnatc |
| @cindex @option{-gnatc} (@command{gcc}) |
| |
| @ifclear vms |
| @noindent |
| The @code{c} stands for ``check''. |
| @end ifclear |
| Causes the compiler to operate in semantic check mode, |
| with full checking for all illegalities specified in the |
| Ada 95 Reference Manual, but without generation of any object code |
| (no object file is generated). |
| |
| Because dependent files must be accessed, you must follow the GNAT |
| semantic restrictions on file structuring to operate in this mode: |
| |
| @itemize @bullet |
| @item |
| The needed source files must be accessible |
| (@pxref{Search Paths and the Run-Time Library (RTL)}). |
| |
| @item |
| Each file must contain only one compilation unit. |
| |
| @item |
| The file name and unit name must match (@pxref{File Naming Rules}). |
| @end itemize |
| |
| The output consists of error messages as appropriate. No object file is |
| generated. An @file{ALI} file is generated for use in the context of |
| cross-reference tools, but this file is marked as not being suitable |
| for binding (since no object file is generated). |
| The checking corresponds exactly to the notion of |
| legality in the Ada 95 Reference Manual. |
| |
| Any unit can be compiled in semantics-checking-only mode, including |
| units that would not normally be compiled (subunits, |
| and specifications where a separate body is present). |
| @end table |
| |
| @node Compiling Different Versions of Ada |
| @subsection Compiling Different Versions of Ada |
| @table @option |
| @cindex Compatibility with Ada 83 |
| @cindex Ada 83 mode |
| @cindex Ada 95 mode |
| @cindex Ada 2005 mode |
| |
| GNAT is primarily an Ada 95 compiler, but the switches described in |
| this section allow operation in Ada 83 compatibility mode, and also |
| allow the use of a preliminary implementation of many of the expected |
| new features in Ada 2005, the forthcoming new version of the standard. |
| |
| @item -gnat83 (Ada 83 Compatibility Mode) |
| @cindex @option{-gnat83} (@command{gcc}) |
| @cindex ACVC, Ada 83 tests |
| |
| @noindent |
| Although GNAT is primarily an Ada 95 compiler, it accepts this switch to |
| specify that an Ada 83 program is to be compiled in Ada 83 mode. If you specify |
| this switch, GNAT rejects most Ada 95 extensions and applies Ada 83 semantics |
| where this can be done easily. |
| It is not possible to guarantee this switch does a perfect |
| job; for example, some subtle tests, such as are |
| found in earlier ACVC tests (and that have been removed from the ACATS suite |
| for Ada 95), might not compile correctly. |
| Nevertheless, this switch may be useful in some circumstances, for example |
| where, due to contractual reasons, legacy code needs to be maintained |
| using only Ada 83 features. |
| |
| With few exceptions (most notably the need to use @code{<>} on |
| @cindex Generic formal parameters |
| unconstrained generic formal parameters, the use of the new Ada 95 |
| reserved words, and the use of packages |
| with optional bodies), it is not necessary to use the |
| @option{-gnat83} switch when compiling Ada 83 programs, because, with rare |
| exceptions, Ada 95 is upwardly compatible with Ada 83. This |
| means that a correct Ada 83 program is usually also a correct Ada 95 |
| program. |
| For further information, please refer to @ref{Compatibility and Porting Guide}. |
| |
| @item -gnat95 (Ada 95 mode) |
| @cindex @option{-gnat95} (@command{gcc}) |
| |
| @noindent |
| GNAT is primarily an Ada 95 compiler, and all current releases of GNAT Pro |
| compile in Ada 95 mode by default. Typically, Ada 95 is sufficiently upwards |
| compatible with Ada 83, that legacy Ada 83 programs may be compiled using |
| this default Ada95 mode without problems (see section above describing the |
| use of @option{-gnat83} to run in Ada 83 mode). |
| |
| In Ada 95 mode, the use of Ada 2005 features will in general cause error |
| messages or warnings. Some specialized releases of GNAT (notably the GAP |
| academic version) operate in Ada 2005 mode by default (see section below |
| describing the use of @option{-gnat05} to run in Ada 2005 mode). For such |
| versions the @option{-gnat95} switch may be used to enforce Ada 95 mode. |
| This option also can be used to cancel the effect of a previous |
| @option{-gnat83} or @option{-gnat05} switch earlier in the command line. |
| |
| |
| @item -gnat05 (Ada 2005 mode) |
| @cindex @option{-gnat05} (@command{gcc}) |
| |
| @noindent |
| Although GNAT is primarily an Ada 95 compiler, it can be set to operate |
| in Ada 2005 mode using this option. Although the new standard has not |
| yet been issued (as of early 2005), many features have been discussed and |
| approved in ``Ada Issues'' (AI's). For the text of these AI's, see |
| @url{www.ada-auth.org/cgi-bin/cvsweb.cgi/AIs}. Included with GNAT |
| releases is a file @file{features-ada0y} that describes the current set |
| of implemented Ada 2005 features. |
| |
| If these features are used in Ada 95 mode (which is the normal default), |
| then error messages or warnings may be |
| generated, reflecting the fact that these new features are otherwise |
| unauthorized extensions to Ada 95. The use of the @option{-gnat05} |
| switch (or an equivalent pragma) causes these messages to be suppressed. |
| |
| Note that some specialized releases of GNAT (notably the GAP academic |
| version) have Ada 2005 mode on by default, and in such environments, |
| the Ada 2005 features can be used freely without the use of switches. |
| |
| @end table |
| |
| @node Character Set Control |
| @subsection Character Set Control |
| @table @option |
| @item ^-gnati^/IDENTIFIER_CHARACTER_SET=^@var{c} |
| @cindex @option{^-gnati^/IDENTIFIER_CHARACTER_SET^} (@command{gcc}) |
| |
| @noindent |
| Normally GNAT recognizes the Latin-1 character set in source program |
| identifiers, as described in the Ada 95 Reference Manual. |
| This switch causes |
| GNAT to recognize alternate character sets in identifiers. @var{c} is a |
| single character ^^or word^ indicating the character set, as follows: |
| |
| @table @code |
| @item 1 |
| ISO 8859-1 (Latin-1) identifiers |
| |
| @item 2 |
| ISO 8859-2 (Latin-2) letters allowed in identifiers |
| |
| @item 3 |
| ISO 8859-3 (Latin-3) letters allowed in identifiers |
| |
| @item 4 |
| ISO 8859-4 (Latin-4) letters allowed in identifiers |
| |
| @item 5 |
| ISO 8859-5 (Cyrillic) letters allowed in identifiers |
| |
| @item 9 |
| ISO 8859-15 (Latin-9) letters allowed in identifiers |
| |
| @item ^p^PC^ |
| IBM PC letters (code page 437) allowed in identifiers |
| |
| @item ^8^PC850^ |
| IBM PC letters (code page 850) allowed in identifiers |
| |
| @item ^f^FULL_UPPER^ |
| Full upper-half codes allowed in identifiers |
| |
| @item ^n^NO_UPPER^ |
| No upper-half codes allowed in identifiers |
| |
| @item ^w^WIDE^ |
| Wide-character codes (that is, codes greater than 255) |
| allowed in identifiers |
| @end table |
| |
| @xref{Foreign Language Representation}, for full details on the |
| implementation of these character sets. |
| |
| @item ^-gnatW^/WIDE_CHARACTER_ENCODING=^@var{e} |
| @cindex @option{^-gnatW^/WIDE_CHARACTER_ENCODING^} (@command{gcc}) |
| Specify the method of encoding for wide characters. |
| @var{e} is one of the following: |
| |
| @table @code |
| |
| @item ^h^HEX^ |
| Hex encoding (brackets coding also recognized) |
| |
| @item ^u^UPPER^ |
| Upper half encoding (brackets encoding also recognized) |
| |
| @item ^s^SHIFT_JIS^ |
| Shift/JIS encoding (brackets encoding also recognized) |
| |
| @item ^e^EUC^ |
| EUC encoding (brackets encoding also recognized) |
| |
| @item ^8^UTF8^ |
| UTF-8 encoding (brackets encoding also recognized) |
| |
| @item ^b^BRACKETS^ |
| Brackets encoding only (default value) |
| @end table |
| For full details on these encoding |
| methods see @ref{Wide Character Encodings}. |
| Note that brackets coding is always accepted, even if one of the other |
| options is specified, so for example @option{-gnatW8} specifies that both |
| brackets and @code{UTF-8} encodings will be recognized. The units that are |
| with'ed directly or indirectly will be scanned using the specified |
| representation scheme, and so if one of the non-brackets scheme is |
| used, it must be used consistently throughout the program. However, |
| since brackets encoding is always recognized, it may be conveniently |
| used in standard libraries, allowing these libraries to be used with |
| any of the available coding schemes. |
| scheme. If no @option{-gnatW?} parameter is present, then the default |
| representation is Brackets encoding only. |
| |
| Note that the wide character representation that is specified (explicitly |
| or by default) for the main program also acts as the default encoding used |
| for Wide_Text_IO files if not specifically overridden by a WCEM form |
| parameter. |
| |
| @end table |
| @node File Naming Control |
| @subsection File Naming Control |
| |
| @table @option |
| @item ^-gnatk^/FILE_NAME_MAX_LENGTH=^@var{n} |
| @cindex @option{-gnatk} (@command{gcc}) |
| Activates file name ``krunching''. @var{n}, a decimal integer in the range |
| 1-999, indicates the maximum allowable length of a file name (not |
| including the @file{.ads} or @file{.adb} extension). The default is not |
| to enable file name krunching. |
| |
| For the source file naming rules, @xref{File Naming Rules}. |
| @end table |
| |
| @node Subprogram Inlining Control |
| @subsection Subprogram Inlining Control |
| |
| @table @option |
| @c !sort! |
| @item -gnatn |
| @cindex @option{-gnatn} (@command{gcc}) |
| @ifclear vms |
| The @code{n} here is intended to suggest the first syllable of the |
| word ``inline''. |
| @end ifclear |
| GNAT recognizes and processes @code{Inline} pragmas. However, for the |
| inlining to actually occur, optimization must be enabled. To enable |
| inlining of subprograms specified by pragma @code{Inline}, |
| you must also specify this switch. |
| In the absence of this switch, GNAT does not attempt |
| inlining and does not need to access the bodies of |
| subprograms for which @code{pragma Inline} is specified if they are not |
| in the current unit. |
| |
| If you specify this switch the compiler will access these bodies, |
| creating an extra source dependency for the resulting object file, and |
| where possible, the call will be inlined. |
| For further details on when inlining is possible |
| see @ref{Inlining of Subprograms}. |
| |
| @item -gnatN |
| @cindex @option{-gnatN} (@command{gcc}) |
| The front end inlining activated by this switch is generally more extensive, |
| and quite often more effective than the standard @option{-gnatn} inlining mode. |
| It will also generate additional dependencies. |
| Note that |
| @option{-gnatN} automatically implies @option{-gnatn} so it is not necessary |
| to specify both options. |
| @end table |
| |
| @node Auxiliary Output Control |
| @subsection Auxiliary Output Control |
| |
| @table @option |
| @item -gnatt |
| @cindex @option{-gnatt} (@command{gcc}) |
| @cindex Writing internal trees |
| @cindex Internal trees, writing to file |
| Causes GNAT to write the internal tree for a unit to a file (with the |
| extension @file{.adt}. |
| This not normally required, but is used by separate analysis tools. |
| Typically |
| these tools do the necessary compilations automatically, so you should |
| not have to specify this switch in normal operation. |
| |
| @item -gnatu |
| @cindex @option{-gnatu} (@command{gcc}) |
| Print a list of units required by this compilation on @file{stdout}. |
| The listing includes all units on which the unit being compiled depends |
| either directly or indirectly. |
| |
| @ifclear vms |
| @item -pass-exit-codes |
| @cindex @option{-pass-exit-codes} (@command{gcc}) |
| If this switch is not used, the exit code returned by @command{gcc} when |
| compiling multiple files indicates whether all source files have |
| been successfully used to generate object files or not. |
| |
| When @option{-pass-exit-codes} is used, @command{gcc} exits with an extended |
| exit status and allows an integrated development environment to better |
| react to a compilation failure. Those exit status are: |
| |
| @table @asis |
| @item 5 |
| There was an error in at least one source file. |
| @item 3 |
| At least one source file did not generate an object file. |
| @item 2 |
| The compiler died unexpectedly (internal error for example). |
| @item 0 |
| An object file has been generated for every source file. |
| @end table |
| @end ifclear |
| @end table |
| |
| @node Debugging Control |
| @subsection Debugging Control |
| |
| @table @option |
| @c !sort! |
| @cindex Debugging options |
| @ifclear vms |
| @item -gnatd@var{x} |
| @cindex @option{-gnatd} (@command{gcc}) |
| Activate internal debugging switches. @var{x} is a letter or digit, or |
| string of letters or digits, which specifies the type of debugging |
| outputs desired. Normally these are used only for internal development |
| or system debugging purposes. You can find full documentation for these |
| switches in the body of the @code{Debug} unit in the compiler source |
| file @file{debug.adb}. |
| @end ifclear |
| |
| @item -gnatG |
| @cindex @option{-gnatG} (@command{gcc}) |
| This switch causes the compiler to generate auxiliary output containing |
| a pseudo-source listing of the generated expanded code. Like most Ada |
| compilers, GNAT works by first transforming the high level Ada code into |
| lower level constructs. For example, tasking operations are transformed |
| into calls to the tasking run-time routines. A unique capability of GNAT |
| is to list this expanded code in a form very close to normal Ada source. |
| This is very useful in understanding the implications of various Ada |
| usage on the efficiency of the generated code. There are many cases in |
| Ada (e.g. the use of controlled types), where simple Ada statements can |
| generate a lot of run-time code. By using @option{-gnatG} you can identify |
| these cases, and consider whether it may be desirable to modify the coding |
| approach to improve efficiency. |
| |
| The format of the output is very similar to standard Ada source, and is |
| easily understood by an Ada programmer. The following special syntactic |
| additions correspond to low level features used in the generated code that |
| do not have any exact analogies in pure Ada source form. The following |
| is a partial list of these special constructions. See the specification |
| of package @code{Sprint} in file @file{sprint.ads} for a full list. |
| |
| @table @code |
| @item new @var{xxx} [storage_pool = @var{yyy}] |
| Shows the storage pool being used for an allocator. |
| |
| @item at end @var{procedure-name}; |
| Shows the finalization (cleanup) procedure for a scope. |
| |
| @item (if @var{expr} then @var{expr} else @var{expr}) |
| Conditional expression equivalent to the @code{x?y:z} construction in C. |
| |
| @item @var{target}^^^(@var{source}) |
| A conversion with floating-point truncation instead of rounding. |
| |
| @item @var{target}?(@var{source}) |
| A conversion that bypasses normal Ada semantic checking. In particular |
| enumeration types and fixed-point types are treated simply as integers. |
| |
| @item @var{target}?^^^(@var{source}) |
| Combines the above two cases. |
| |
| @item @var{x} #/ @var{y} |
| @itemx @var{x} #mod @var{y} |
| @itemx @var{x} #* @var{y} |
| @itemx @var{x} #rem @var{y} |
| A division or multiplication of fixed-point values which are treated as |
| integers without any kind of scaling. |
| |
| @item free @var{expr} [storage_pool = @var{xxx}] |
| Shows the storage pool associated with a @code{free} statement. |
| |
| @item [subtype or type declaration] |
| Used to list an equivalent declaration for an internally generated |
| type that is referenced elsewhere in the listing. |
| |
| @item freeze @var{type-name} [@var{actions}] |
| Shows the point at which @var{type-name} is frozen, with possible |
| associated actions to be performed at the freeze point. |
| |
| @item reference @var{itype} |
| Reference (and hence definition) to internal type @var{itype}. |
| |
| @item @var{function-name}! (@var{arg}, @var{arg}, @var{arg}) |
| Intrinsic function call. |
| |
| @item @var{label-name} : label |
| Declaration of label @var{labelname}. |
| |
| @item #$ @var{subprogram-name} |
| An implicit call to a run-time support routine |
| (to meet the requirement of H.3.1(9) in a |
| convenient manner). |
| |
| @item @var{expr} && @var{expr} && @var{expr} ... && @var{expr} |
| A multiple concatenation (same effect as @var{expr} & @var{expr} & |
| @var{expr}, but handled more efficiently). |
| |
| @item [constraint_error] |
| Raise the @code{Constraint_Error} exception. |
| |
| @item @var{expression}'reference |
| A pointer to the result of evaluating @var{expression}. |
| |
| @item @var{target-type}!(@var{source-expression}) |
| An unchecked conversion of @var{source-expression} to @var{target-type}. |
| |
| @item [@var{numerator}/@var{denominator}] |
| Used to represent internal real literals (that) have no exact |
| representation in base 2-16 (for example, the result of compile time |
| evaluation of the expression 1.0/27.0). |
| @end table |
| |
| @item -gnatD |
| @cindex @option{-gnatD} (@command{gcc}) |
| When used in conjunction with @option{-gnatG}, this switch causes |
| the expanded source, as described above for |
| @option{-gnatG} to be written to files with names |
| @file{^xxx.dg^XXX_DG^}, where @file{xxx} is the normal file name, |
| instead of to the standard output file. For |
| example, if the source file name is @file{hello.adb}, then a file |
| @file{^hello.adb.dg^HELLO.ADB_DG^} will be written. The debugging |
| information generated by the @command{gcc} @option{^-g^/DEBUG^} switch |
| will refer to the generated @file{^xxx.dg^XXX_DG^} file. This allows |
| you to do source level debugging using the generated code which is |
| sometimes useful for complex code, for example to find out exactly |
| which part of a complex construction raised an exception. This switch |
| also suppress generation of cross-reference information (see |
| @option{-gnatx}) since otherwise the cross-reference information |
| would refer to the @file{^.dg^.DG^} file, which would cause |
| confusion since this is not the original source file. |
| |
| Note that @option{-gnatD} actually implies @option{-gnatG} |
| automatically, so it is not necessary to give both options. |
| In other words @option{-gnatD} is equivalent to @option{-gnatDG}). |
| |
| @ifclear vms |
| @item -gnatR[0|1|2|3[s]] |
| @cindex @option{-gnatR} (@command{gcc}) |
| This switch controls output from the compiler of a listing showing |
| representation information for declared types and objects. For |
| @option{-gnatR0}, no information is output (equivalent to omitting |
| the @option{-gnatR} switch). For @option{-gnatR1} (which is the default, |
| so @option{-gnatR} with no parameter has the same effect), size and alignment |
| information is listed for declared array and record types. For |
| @option{-gnatR2}, size and alignment information is listed for all |
| expression information for values that are computed at run time for |
| variant records. These symbolic expressions have a mostly obvious |
| format with #n being used to represent the value of the n'th |
| discriminant. See source files @file{repinfo.ads/adb} in the |
| @code{GNAT} sources for full details on the format of @option{-gnatR3} |
| output. If the switch is followed by an s (e.g. @option{-gnatR2s}), then |
| the output is to a file with the name @file{^file.rep^file_REP^} where |
| file is the name of the corresponding source file. |
| @end ifclear |
| @ifset vms |
| @item /REPRESENTATION_INFO |
| @cindex @option{/REPRESENTATION_INFO} (@command{gcc}) |
| This qualifier controls output from the compiler of a listing showing |
| representation information for declared types and objects. For |
| @option{/REPRESENTATION_INFO=NONE}, no information is output |
| (equivalent to omitting the @option{/REPRESENTATION_INFO} qualifier). |
| @option{/REPRESENTATION_INFO} without option is equivalent to |
| @option{/REPRESENTATION_INFO=ARRAYS}. |
| For @option{/REPRESENTATION_INFO=ARRAYS}, size and alignment |
| information is listed for declared array and record types. For |
| @option{/REPRESENTATION_INFO=OBJECTS}, size and alignment information |
| is listed for all expression information for values that are computed |
| at run time for variant records. These symbolic expressions have a mostly |
| obvious format with #n being used to represent the value of the n'th |
| discriminant. See source files @file{REPINFO.ADS/ADB} in the |
| @code{GNAT} sources for full details on the format of |
| @option{/REPRESENTATION_INFO=SYMBOLIC} output. |
| If _FILE is added at the end of an option |
| (e.g. @option{/REPRESENTATION_INFO=ARRAYS_FILE}), |
| then the output is to a file with the name @file{file_REP} where |
| file is the name of the corresponding source file. |
| @end ifset |
| Note that it is possible for record components to have zero size. In |
| this case, the component clause uses an obvious extension of permitted |
| Ada syntax, for example @code{at 0 range 0 .. -1}. |
| |
| @item -gnatS |
| @cindex @option{-gnatS} (@command{gcc}) |
| The use of the switch @option{-gnatS} for an |
| Ada compilation will cause the compiler to output a |
| representation of package Standard in a form very |
| close to standard Ada. It is not quite possible to |
| do this entirely in standard Ada (since new |
| numeric base types cannot be created in standard |
| Ada), but the output is easily |
| readable to any Ada programmer, and is useful to |
| determine the characteristics of target dependent |
| types in package Standard. |
| |
| @item -gnatx |
| @cindex @option{-gnatx} (@command{gcc}) |
| Normally the compiler generates full cross-referencing information in |
| the @file{ALI} file. This information is used by a number of tools, |
| including @code{gnatfind} and @code{gnatxref}. The @option{-gnatx} switch |
| suppresses this information. This saves some space and may slightly |
| speed up compilation, but means that these tools cannot be used. |
| @end table |
| |
| @node Exception Handling Control |
| @subsection Exception Handling Control |
| |
| @noindent |
| GNAT uses two methods for handling exceptions at run-time. The |
| @code{setjmp/longjmp} method saves the context when entering |
| a frame with an exception handler. Then when an exception is |
| raised, the context can be restored immediately, without the |
| need for tracing stack frames. This method provides very fast |
| exception propagation, but introduces significant overhead for |
| the use of exception handlers, even if no exception is raised. |
| |
| The other approach is called ``zero cost'' exception handling. |
| With this method, the compiler builds static tables to describe |
| the exception ranges. No dynamic code is required when entering |
| a frame containing an exception handler. When an exception is |
| raised, the tables are used to control a back trace of the |
| subprogram invocation stack to locate the required exception |
| handler. This method has considerably poorer performance for |
| the propagation of exceptions, but there is no overhead for |
| exception handlers if no exception is raised. Note that in this |
| mode and in the context of mixed Ada and C/C++ programming, |
| to propagate an exception through a C/C++ code, the C/C++ code |
| must be compiled with the @option{-funwind-tables} GCC's |
| option. |
| |
| The following switches can be used to control which of the |
| two exception handling methods is used. |
| |
| @table @option |
| @c !sort! |
| |
| @item --RTS=sjlj |
| @cindex @option{--RTS=sjlj} (@command{gnatmake}) |
| This switch causes the setjmp/longjmp run-time to be used |
| for exception handling. If this is the default mechanism for the |
| target (see below), then this has no effect. If the default |
| mechanism for the target is zero cost exceptions, then |
| this switch can be used to modify this default, and must be |
| used for all units in the partition. |
| This option is rarely used. One case in which it may be |
| advantageous is if you have an application where exception |
| raising is common and the overall performance of the |
| application is improved by favoring exception propagation. |
| |
| @item --RTS=zcx |
| @cindex @option{--RTS=zcx} (@command{gnatmake}) |
| @cindex Zero Cost Exceptions |
| This switch causes the zero cost approach to be used |
| for exception handling. If this is the default mechanism for the |
| target (see below), then this has no effect. If the default |
| mechanism for the target is setjmp/longjmp exceptions, then |
| this switch can be used to modify this default, and must be |
| used for all units in the partition. |
| This option can only be used if the zero cost approach |
| is available for the target in use (see below). |
| @end table |
| |
| @noindent |
| The @code{setjmp/longjmp} approach is available on all targets, while |
| the @code{zero cost} approach is available on selected targets. |
| To determine whether zero cost exceptions can be used for a |
| particular target, look at the private part of the file system.ads. |
| Either @code{GCC_ZCX_Support} or @code{Front_End_ZCX_Support} must |
| be True to use the zero cost approach. If both of these switches |
| are set to False, this means that zero cost exception handling |
| is not yet available for that target. The switch |
| @code{ZCX_By_Default} indicates the default approach. If this |
| switch is set to True, then the @code{zero cost} approach is |
| used by default. |
| |
| @node Units to Sources Mapping Files |
| @subsection Units to Sources Mapping Files |
| |
| @table @option |
| |
| @item -gnatem^^=^@var{path} |
| @cindex @option{-gnatem} (@command{gcc}) |
| A mapping file is a way to communicate to the compiler two mappings: |
| from unit names to file names (without any directory information) and from |
| file names to path names (with full directory information). These mappings |
| are used by the compiler to short-circuit the path search. |
| |
| The use of mapping files is not required for correct operation of the |
| compiler, but mapping files can improve efficiency, particularly when |
| sources are read over a slow network connection. In normal operation, |
| you need not be concerned with the format or use of mapping files, |
| and the @option{-gnatem} switch is not a switch that you would use |
| explicitly. it is intended only for use by automatic tools such as |
| @command{gnatmake} running under the project file facility. The |
| description here of the format of mapping files is provided |
| for completeness and for possible use by other tools. |
| |
| A mapping file is a sequence of sets of three lines. In each set, |
| the first line is the unit name, in lower case, with ``@code{%s}'' |
| appended for |
| specifications and ``@code{%b}'' appended for bodies; the second line is the |
| file name; and the third line is the path name. |
| |
| Example: |
| @smallexample |
| main%b |
| main.2.ada |
| /gnat/project1/sources/main.2.ada |
| @end smallexample |
| |
| When the switch @option{-gnatem} is specified, the compiler will create |
| in memory the two mappings from the specified file. If there is any problem |
| (non existent file, truncated file or duplicate entries), no mapping |
| will be created. |
| |
| Several @option{-gnatem} switches may be specified; however, only the last |
| one on the command line will be taken into account. |
| |
| When using a project file, @command{gnatmake} create a temporary mapping file |
| and communicates it to the compiler using this switch. |
| |
| @end table |
| |
| @node Integrated Preprocessing |
| @subsection Integrated Preprocessing |
| |
| @noindent |
| GNAT sources may be preprocessed immediately before compilation; the actual |
| text of the source is not the text of the source file, but is derived from it |
| through a process called preprocessing. Integrated preprocessing is specified |
| through switches @option{-gnatep} and/or @option{-gnateD}. @option{-gnatep} |
| indicates, through a text file, the preprocessing data to be used. |
| @option{-gnateD} specifies or modifies the values of preprocessing symbol. |
| |
| @noindent |
| It is recommended that @command{gnatmake} switch ^-s^/SWITCH_CHECK^ should be |
| used when Integrated Preprocessing is used. The reason is that preprocessing |
| with another Preprocessing Data file without changing the sources will |
| not trigger recompilation without this switch. |
| |
| @noindent |
| Note that @command{gnatmake} switch ^-m^/MINIMAL_RECOMPILATION^ will almost |
| always trigger recompilation for sources that are preprocessed, |
| because @command{gnatmake} cannot compute the checksum of the source after |
| preprocessing. |
| |
| @noindent |
| The actual preprocessing function is described in details in section |
| @ref{Preprocessing Using gnatprep}. This section only describes how integrated |
| preprocessing is triggered and parameterized. |
| |
| @table @code |
| |
| @item -gnatep=@var{file} |
| @cindex @option{-gnatep} (@command{gcc}) |
| This switch indicates to the compiler the file name (without directory |
| information) of the preprocessor data file to use. The preprocessor data file |
| should be found in the source directories. |
| |
| @noindent |
| A preprocessing data file is a text file with significant lines indicating |
| how should be preprocessed either a specific source or all sources not |
| mentioned in other lines. A significant line is a non empty, non comment line. |
| Comments are similar to Ada comments. |
| |
| @noindent |
| Each significant line starts with either a literal string or the character '*'. |
| A literal string is the file name (without directory information) of the source |
| to preprocess. A character '*' indicates the preprocessing for all the sources |
| that are not specified explicitly on other lines (order of the lines is not |
| significant). It is an error to have two lines with the same file name or two |
| lines starting with the character '*'. |
| |
| @noindent |
| After the file name or the character '*', another optional literal string |
| indicating the file name of the definition file to be used for preprocessing |
| (@pxref{Form of Definitions File}). The definition files are found by the |
| compiler in one of the source directories. In some cases, when compiling |
| a source in a directory other than the current directory, if the definition |
| file is in the current directory, it may be necessary to add the current |
| directory as a source directory through switch ^-I.^/SEARCH=[]^, otherwise |
| the compiler would not find the definition file. |
| |
| @noindent |
| Then, optionally, ^switches^switches^ similar to those of @code{gnatprep} may |
| be found. Those ^switches^switches^ are: |
| |
| @table @code |
| |
| @item -b |
| Causes both preprocessor lines and the lines deleted by |
| preprocessing to be replaced by blank lines, preserving the line number. |
| This ^switch^switch^ is always implied; however, if specified after @option{-c} |
| it cancels the effect of @option{-c}. |
| |
| @item -c |
| Causes both preprocessor lines and the lines deleted |
| by preprocessing to be retained as comments marked |
| with the special string ``@code{--! }''. |
| |
| @item -Dsymbol=value |
| Define or redefine a symbol, associated with value. A symbol is an Ada |
| identifier, or an Ada reserved word, with the exception of @code{if}, |
| @code{else}, @code{elsif}, @code{end}, @code{and}, @code{or} and @code{then}. |
| @code{value} is either a literal string, an Ada identifier or any Ada reserved |
| word. A symbol declared with this ^switch^switch^ replaces a symbol with the |
| same name defined in a definition file. |
| |
| @item -s |
| Causes a sorted list of symbol names and values to be |
| listed on the standard output file. |
| |
| @item -u |
| Causes undefined symbols to be treated as having the value @code{FALSE} |
| in the context |
| of a preprocessor test. In the absence of this option, an undefined symbol in |
| a @code{#if} or @code{#elsif} test will be treated as an error. |
| |
| @end table |
| |
| @noindent |
| Examples of valid lines in a preprocessor data file: |
| |
| @smallexample |
| "toto.adb" "prep.def" -u |
| -- preprocess "toto.adb", using definition file "prep.def", |
| -- undefined symbol are False. |
| |
| * -c -DVERSION=V101 |
| -- preprocess all other sources without a definition file; |
| -- suppressed lined are commented; symbol VERSION has the value V101. |
| |
| "titi.adb" "prep2.def" -s |
| -- preprocess "titi.adb", using definition file "prep2.def"; |
| -- list all symbols with their values. |
| @end smallexample |
| |
| @item ^-gnateD^/DATA_PREPROCESSING=^symbol[=value] |
| @cindex @option{-gnateD} (@command{gcc}) |
| Define or redefine a preprocessing symbol, associated with value. If no value |
| is given on the command line, then the value of the symbol is @code{True}. |
| A symbol is an identifier, following normal Ada (case-insensitive) |
| rules for its syntax, and value is any sequence (including an empty sequence) |
| of characters from the set (letters, digits, period, underline). |
| Ada reserved words may be used as symbols, with the exceptions of @code{if}, |
| @code{else}, @code{elsif}, @code{end}, @code{and}, @code{or} and @code{then}. |
| |
| @noindent |
| A symbol declared with this ^switch^switch^ on the command line replaces a |
| symbol with the same name either in a definition file or specified with a |
| ^switch^switch^ -D in the preprocessor data file. |
| |
| @noindent |
| This switch is similar to switch @option{^-D^/ASSOCIATE^} of @code{gnatprep}. |
| |
| @end table |
| |
| @node Code Generation Control |
| @subsection Code Generation Control |
| |
| @noindent |
| |
| The GCC technology provides a wide range of target dependent |
| @option{-m} switches for controlling |
| details of code generation with respect to different versions of |
| architectures. This includes variations in instruction sets (e.g. |
| different members of the power pc family), and different requirements |
| for optimal arrangement of instructions (e.g. different members of |
| the x86 family). The list of available @option{-m} switches may be |
| found in the GCC documentation. |
| |
| Use of these @option{-m} switches may in some cases result in improved |
| code performance. |
| |
| The GNAT Pro technology is tested and qualified without any |
| @option{-m} switches, |
| so generally the most reliable approach is to avoid the use of these |
| switches. However, we generally expect most of these switches to work |
| successfully with GNAT Pro, and many customers have reported successful |
| use of these options. |
| |
| Our general advice is to avoid the use of @option{-m} switches unless |
| special needs lead to requirements in this area. In particular, |
| there is no point in using @option{-m} switches to improve performance |
| unless you actually see a performance improvement. |
| |
| @ifset vms |
| @node Return Codes |
| @subsection Return Codes |
| @cindex Return Codes |
| @cindex @option{/RETURN_CODES=VMS} |
| |
| @noindent |
| On VMS, GNAT compiled programs return POSIX-style codes by default, |
| e.g. @option{/RETURN_CODES=POSIX}. |
| |
| To enable VMS style return codes, use GNAT BIND and LINK with the option |
| @option{/RETURN_CODES=VMS}. For example: |
| |
| @smallexample |
| GNAT BIND MYMAIN.ALI /RETURN_CODES=VMS |
| GNAT LINK MYMAIN.ALI /RETURN_CODES=VMS |
| @end smallexample |
| |
| @noindent |
| Programs built with /RETURN_CODES=VMS are suitable to be called in |
| VMS DCL scripts. Programs compiled with the default /RETURN_CODES=POSIX |
| are suitable for spawning with appropriate GNAT RTL routines. |
| |
| @end ifset |
| |
| @node Search Paths and the Run-Time Library (RTL) |
| @section Search Paths and the Run-Time Library (RTL) |
| |
| @noindent |
| With the GNAT source-based library system, the compiler must be able to |
| find source files for units that are needed by the unit being compiled. |
| Search paths are used to guide this process. |
| |
| The compiler compiles one source file whose name must be given |
| explicitly on the command line. In other words, no searching is done |
| for this file. To find all other source files that are needed (the most |
| common being the specs of units), the compiler examines the following |
| directories, in the following order: |
| |
| @enumerate |
| @item |
| The directory containing the source file of the main unit being compiled |
| (the file name on the command line). |
| |
| @item |
| Each directory named by an @option{^-I^/SOURCE_SEARCH^} switch given on the |
| @command{gcc} command line, in the order given. |
| |
| @item |
| @findex ADA_PRJ_INCLUDE_FILE |
| Each of the directories listed in the text file whose name is given |
| by the @code{ADA_PRJ_INCLUDE_FILE} ^environment variable^logical name^. |
| |
| @noindent |
| @code{ADA_PRJ_INCLUDE_FILE} is normally set by gnatmake or by the ^gnat^GNAT^ |
| driver when project files are used. It should not normally be set |
| by other means. |
| |
| @item |
| @findex ADA_INCLUDE_PATH |
| Each of the directories listed in the value of the |
| @code{ADA_INCLUDE_PATH} ^environment variable^logical name^. |
| @ifclear vms |
| Construct this value |
| exactly as the @code{PATH} environment variable: a list of directory |
| names separated by colons (semicolons when working with the NT version). |
| @end ifclear |
| @ifset vms |
| Normally, define this value as a logical name containing a comma separated |
| list of directory names. |
| |
| This variable can also be defined by means of an environment string |
| (an argument to the HP C exec* set of functions). |
| |
| Logical Name: |
| @smallexample |
| DEFINE ANOTHER_PATH FOO:[BAG] |
| DEFINE ADA_INCLUDE_PATH ANOTHER_PATH,FOO:[BAM],FOO:[BAR] |
| @end smallexample |
| |
| By default, the path includes GNU:[LIB.OPENVMS7_x.2_8_x.DECLIB] |
| first, followed by the standard Ada 95 |
| libraries in GNU:[LIB.OPENVMS7_x.2_8_x.ADAINCLUDE]. |
| If this is not redefined, the user will obtain the HP Ada 83 IO packages |
| (Text_IO, Sequential_IO, etc) |
| instead of the Ada95 packages. Thus, in order to get the Ada 95 |
| packages by default, ADA_INCLUDE_PATH must be redefined. |
| @end ifset |
| |
| @item |
| The content of the @file{ada_source_path} file which is part of the GNAT |
| installation tree and is used to store standard libraries such as the |
| GNAT Run Time Library (RTL) source files. |
| @ifclear vms |
| @ref{Installing a library} |
| @end ifclear |
| @end enumerate |
| |
| @noindent |
| Specifying the switch @option{^-I-^/NOCURRENT_DIRECTORY^} |
| inhibits the use of the directory |
| containing the source file named in the command line. You can still |
| have this directory on your search path, but in this case it must be |
| explicitly requested with a @option{^-I^/SOURCE_SEARCH^} switch. |
| |
| Specifying the switch @option{-nostdinc} |
| inhibits the search of the default location for the GNAT Run Time |
| Library (RTL) source files. |
| |
| The compiler outputs its object files and ALI files in the current |
| working directory. |
| @ifclear vms |
| Caution: The object file can be redirected with the @option{-o} switch; |
| however, @command{gcc} and @code{gnat1} have not been coordinated on this |
| so the @file{ALI} file will not go to the right place. Therefore, you should |
| avoid using the @option{-o} switch. |
| @end ifclear |
| |
| @findex System.IO |
| The packages @code{Ada}, @code{System}, and @code{Interfaces} and their |
| children make up the GNAT RTL, together with the simple @code{System.IO} |
| package used in the @code{"Hello World"} example. The sources for these units |
| are needed by the compiler and are kept together in one directory. Not |
| all of the bodies are needed, but all of the sources are kept together |
| anyway. In a normal installation, you need not specify these directory |
| names when compiling or binding. Either the environment variables or |
| the built-in defaults cause these files to be found. |
| |
| In addition to the language-defined hierarchies (@code{System}, @code{Ada} and |
| @code{Interfaces}), the GNAT distribution provides a fourth hierarchy, |
| consisting of child units of @code{GNAT}. This is a collection of generally |
| useful types, subprograms, etc. See the @cite{GNAT Reference Manual} for |
| further details. |
| |
| Besides simplifying access to the RTL, a major use of search paths is |
| in compiling sources from multiple directories. This can make |
| development environments much more flexible. |
| |
| @node Order of Compilation Issues |
| @section Order of Compilation Issues |
| |
| @noindent |
| If, in our earlier example, there was a spec for the @code{hello} |
| procedure, it would be contained in the file @file{hello.ads}; yet this |
| file would not have to be explicitly compiled. This is the result of the |
| model we chose to implement library management. Some of the consequences |
| of this model are as follows: |
| |
| @itemize @bullet |
| @item |
| There is no point in compiling specs (except for package |
| specs with no bodies) because these are compiled as needed by clients. If |
| you attempt a useless compilation, you will receive an error message. |
| It is also useless to compile subunits because they are compiled as needed |
| by the parent. |
| |
| @item |
| There are no order of compilation requirements: performing a |
| compilation never obsoletes anything. The only way you can obsolete |
| something and require recompilations is to modify one of the |
| source files on which it depends. |
| |
| @item |
| There is no library as such, apart from the ALI files |
| (@pxref{The Ada Library Information Files}, for information on the format |
| of these files). For now we find it convenient to create separate ALI files, |
| but eventually the information therein may be incorporated into the object |
| file directly. |
| |
| @item |
| When you compile a unit, the source files for the specs of all units |
| that it @code{with}'s, all its subunits, and the bodies of any generics it |
| instantiates must be available (reachable by the search-paths mechanism |
| described above), or you will receive a fatal error message. |
| @end itemize |
| |
| @node Examples |
| @section Examples |
| |
| @noindent |
| The following are some typical Ada compilation command line examples: |
| |
| @table @code |
| @item $ gcc -c xyz.adb |
| Compile body in file @file{xyz.adb} with all default options. |
| |
| @ifclear vms |
| @item $ gcc -c -O2 -gnata xyz-def.adb |
| @end ifclear |
| @ifset vms |
| @item $ GNAT COMPILE /OPTIMIZE=ALL -gnata xyz-def.adb |
| @end ifset |
| |
| Compile the child unit package in file @file{xyz-def.adb} with extensive |
| optimizations, and pragma @code{Assert}/@code{Debug} statements |
| enabled. |
| |
| @item $ gcc -c -gnatc abc-def.adb |
| Compile the subunit in file @file{abc-def.adb} in semantic-checking-only |
| mode. |
| @end table |
| |
| @node Binding Using gnatbind |
| @chapter Binding Using @code{gnatbind} |
| @findex gnatbind |
| |
| @menu |
| * Running gnatbind:: |
| * Switches for gnatbind:: |
| * Command-Line Access:: |
| * Search Paths for gnatbind:: |
| * Examples of gnatbind Usage:: |
| @end menu |
| |
| @noindent |
| This chapter describes the GNAT binder, @code{gnatbind}, which is used |
| to bind compiled GNAT objects. The @code{gnatbind} program performs |
| four separate functions: |
| |
| @enumerate |
| @item |
| Checks that a program is consistent, in accordance with the rules in |
| Chapter 10 of the Ada 95 Reference Manual. In particular, error |
| messages are generated if a program uses inconsistent versions of a |
| given unit. |
| |
| @item |
| Checks that an acceptable order of elaboration exists for the program |
| and issues an error message if it cannot find an order of elaboration |
| that satisfies the rules in Chapter 10 of the Ada 95 Language Manual. |
| |
| @item |
| Generates a main program incorporating the given elaboration order. |
| This program is a small Ada package (body and spec) that |
| must be subsequently compiled |
| using the GNAT compiler. The necessary compilation step is usually |
| performed automatically by @command{gnatlink}. The two most important |
| functions of this program |
| are to call the elaboration routines of units in an appropriate order |
| and to call the main program. |
| |
| @item |
| Determines the set of object files required by the given main program. |
| This information is output in the forms of comments in the generated program, |
| to be read by the @command{gnatlink} utility used to link the Ada application. |
| @end enumerate |
| |
| @node Running gnatbind |
| @section Running @code{gnatbind} |
| |
| @noindent |
| The form of the @code{gnatbind} command is |
| |
| @smallexample |
| $ gnatbind [@i{switches}] @i{mainprog}[.ali] [@i{switches}] |
| @end smallexample |
| |
| @noindent |
| where @file{@i{mainprog}.adb} is the Ada file containing the main program |
| unit body. If no switches are specified, @code{gnatbind} constructs an Ada |
| package in two files whose names are |
| @file{b~@i{mainprog}.ads}, and @file{b~@i{mainprog}.adb}. |
| For example, if given the |
| parameter @file{hello.ali}, for a main program contained in file |
| @file{hello.adb}, the binder output files would be @file{b~hello.ads} |
| and @file{b~hello.adb}. |
| |
| When doing consistency checking, the binder takes into consideration |
| any source files it can locate. For example, if the binder determines |
| that the given main program requires the package @code{Pack}, whose |
| @file{.ALI} |
| file is @file{pack.ali} and whose corresponding source spec file is |
| @file{pack.ads}, it attempts to locate the source file @file{pack.ads} |
| (using the same search path conventions as previously described for the |
| @command{gcc} command). If it can locate this source file, it checks that |
| the time stamps |
| or source checksums of the source and its references to in @file{ALI} files |
| match. In other words, any @file{ALI} files that mentions this spec must have |
| resulted from compiling this version of the source file (or in the case |
| where the source checksums match, a version close enough that the |
| difference does not matter). |
| |
| @cindex Source files, use by binder |
| The effect of this consistency checking, which includes source files, is |
| that the binder ensures that the program is consistent with the latest |
| version of the source files that can be located at bind time. Editing a |
| source file without compiling files that depend on the source file cause |
| error messages to be generated by the binder. |
| |
| For example, suppose you have a main program @file{hello.adb} and a |
| package @code{P}, from file @file{p.ads} and you perform the following |
| steps: |
| |
| @enumerate |
| @item |
| Enter @code{gcc -c hello.adb} to compile the main program. |
| |
| @item |
| Enter @code{gcc -c p.ads} to compile package @code{P}. |
| |
| @item |
| Edit file @file{p.ads}. |
| |
| @item |
| Enter @code{gnatbind hello}. |
| @end enumerate |
| |
| @noindent |
| At this point, the file @file{p.ali} contains an out-of-date time stamp |
| because the file @file{p.ads} has been edited. The attempt at binding |
| fails, and the binder generates the following error messages: |
| |
| @smallexample |
| error: "hello.adb" must be recompiled ("p.ads" has been modified) |
| error: "p.ads" has been modified and must be recompiled |
| @end smallexample |
| |
| @noindent |
| Now both files must be recompiled as indicated, and then the bind can |
| succeed, generating a main program. You need not normally be concerned |
| with the contents of this file, but for reference purposes a sample |
| binder output file is given in @ref{Example of Binder Output File}. |
| |
| In most normal usage, the default mode of @command{gnatbind} which is to |
| generate the main package in Ada, as described in the previous section. |
| In particular, this means that any Ada programmer can read and understand |
| the generated main program. It can also be debugged just like any other |
| Ada code provided the @option{^-g^/DEBUG^} switch is used for |
| @command{gnatbind} and @command{gnatlink}. |
| |
| However for some purposes it may be convenient to generate the main |
| program in C rather than Ada. This may for example be helpful when you |
| are generating a mixed language program with the main program in C. The |
| GNAT compiler itself is an example. |
| The use of the @option{^-C^/BIND_FILE=C^} switch |
| for both @code{gnatbind} and @command{gnatlink} will cause the program to |
| be generated in C (and compiled using the gnu C compiler). |
| |
| @node Switches for gnatbind |
| @section Switches for @command{gnatbind} |
| |
| @noindent |
| The following switches are available with @code{gnatbind}; details will |
| be presented in subsequent sections. |
| |
| @menu |
| * Consistency-Checking Modes:: |
| * Binder Error Message Control:: |
| * Elaboration Control:: |
| * Output Control:: |
| * Binding with Non-Ada Main Programs:: |
| * Binding Programs with No Main Subprogram:: |
| @end menu |
| |
| @table @option |
| @c !sort! |
| @item ^-aO^/OBJECT_SEARCH^ |
| @cindex @option{^-aO^/OBJECT_SEARCH^} (@command{gnatbind}) |
| Specify directory to be searched for ALI files. |
| |
| @item ^-aI^/SOURCE_SEARCH^ |
| @cindex @option{^-aI^/SOURCE_SEARCH^} (@command{gnatbind}) |
| Specify directory to be searched for source file. |
| |
| @item ^-A^/BIND_FILE=ADA^ |
| @cindex @option{^-A^/BIND_FILE=ADA^} (@command{gnatbind}) |
| Generate binder program in Ada (default) |
| |
| @item ^-b^/REPORT_ERRORS=BRIEF^ |
| @cindex @option{^-b^/REPORT_ERRORS=BRIEF^} (@command{gnatbind}) |
| Generate brief messages to @file{stderr} even if verbose mode set. |
| |
| @item ^-c^/NOOUTPUT^ |
| @cindex @option{^-c^/NOOUTPUT^} (@command{gnatbind}) |
| Check only, no generation of binder output file. |
| |
| @item ^-C^/BIND_FILE=C^ |
| @cindex @option{^-C^/BIND_FILE=C^} (@command{gnatbind}) |
| Generate binder program in C |
| |
| @item ^-d^/DEFAULT_STACK_SIZE=^@var{nn}[k|m] |
| @cindex @option{^-d^/DEFAULT_STACK_SIZE=^@var{nn}[k|m]} (@command{gnatbind}) |
| This switch can be used to change the default task stack size value |
| to a specified size @var{nn}, which is expressed in bytes by default, or |
| in kilobytes when suffixed with @var{k} or in megabytes when suffixed |
| with @var{m}. |
| In the absence of a [k|m] suffix, this switch is equivalent, in effect, |
| to completing all task specs with |
| @smallexample @c ada |
| pragma Storage_Size (nn); |
| @end smallexample |
| When they do not already have such a pragma. |
| |
| @item ^-D^/DEFAULT_SECONDARY_STACK_SIZE=^@var{nn}[k|m] |
| @cindex @option{^-D^/DEFAULT_SECONDARY_STACK_SIZE=nnnnn^} (@command{gnatbind}) |
| This switch can be used to change the default secondary stack size value |
| to a specified size @var{nn}, which is expressed in bytes by default, or |
| in kilobytes when suffixed with @var{k} or in megabytes when suffixed |
| with @var{m}. |
| |
| The secondary stack is used to deal with functions that return a variable |
| sized result, for example a function returning an unconstrained |
| String. There are two ways in which this secondary stack is allocated. |
| |
| For most targets, the secondary stack is growing on demand and is allocated |
| as a chain of blocks in the heap. The -D option is not very |
| relevant. It only give some control over the size of the allocated |
| blocks (whose size is the minimum of the default secondary stack size value, |
| and the actual size needed for the current allocation request). |
| |
| For certain targets, notably VxWorks 653, |
| the secondary stack is allocated by carving off a fixed ratio chunk of the |
| primary task stack. The -D option is used to defined the |
| size of the environment task's secondary stack. |
| |
| @item ^-e^/ELABORATION_DEPENDENCIES^ |
| @cindex @option{^-e^/ELABORATION_DEPENDENCIES^} (@command{gnatbind}) |
| Output complete list of elaboration-order dependencies. |
| |
| @item ^-E^/STORE_TRACEBACKS^ |
| @cindex @option{^-E^/STORE_TRACEBACKS^} (@command{gnatbind}) |
| Store tracebacks in exception occurrences when the target supports it. |
| This is the default with the zero cost exception mechanism. |
| @ignore |
| @c The following may get moved to an appendix |
| This option is currently supported on the following targets: |
| all x86 ports, Solaris, Windows, HP-UX, AIX, PowerPC VxWorks and Alpha VxWorks. |
| @end ignore |
| See also the packages @code{GNAT.Traceback} and |
| @code{GNAT.Traceback.Symbolic} for more information. |
| @ifclear vms |
| Note that on x86 ports, you must not use @option{-fomit-frame-pointer} |
| @command{gcc} option. |
| @end ifclear |
| |
| @item ^-F^/FORCE_ELABS_FLAGS^ |
| @cindex @option{^-F^/FORCE_ELABS_FLAGS^} (@command{gnatbind}) |
| Force the checks of elaboration flags. @command{gnatbind} does not normally |
| generate checks of elaboration flags for the main executable, except when |
| a Stand-Alone Library is used. However, there are cases when this cannot be |
| detected by gnatbind. An example is importing an interface of a Stand-Alone |
| Library through a pragma Import and only specifying through a linker switch |
| this Stand-Alone Library. This switch is used to guarantee that elaboration |
| flag checks are generated. |
| |
| @item ^-h^/HELP^ |
| @cindex @option{^-h^/HELP^} (@command{gnatbind}) |
| Output usage (help) information |
| |
| @item ^-I^/SEARCH^ |
| @cindex @option{^-I^/SEARCH^} (@command{gnatbind}) |
| Specify directory to be searched for source and ALI files. |
| |
| @item ^-I-^/NOCURRENT_DIRECTORY^ |
| @cindex @option{^-I-^/NOCURRENT_DIRECTORY^} (@command{gnatbind}) |
| Do not look for sources in the current directory where @code{gnatbind} was |
| invoked, and do not look for ALI files in the directory containing the |
| ALI file named in the @code{gnatbind} command line. |
| |
| @item ^-l^/ORDER_OF_ELABORATION^ |
| @cindex @option{^-l^/ORDER_OF_ELABORATION^} (@command{gnatbind}) |
| Output chosen elaboration order. |
| |
| @item ^-Lxxx^/BUILD_LIBRARY=xxx^ |
| @cindex @option{^-L^/BUILD_LIBRARY^} (@command{gnatbind}) |
| Bind the units for library building. In this case the adainit and |
| adafinal procedures (@pxref{Binding with Non-Ada Main Programs}) |
| are renamed to ^xxxinit^XXXINIT^ and |
| ^xxxfinal^XXXFINAL^. |
| Implies ^-n^/NOCOMPILE^. |
| @ifclear vms |
| (@xref{GNAT and Libraries}, for more details.) |
| @end ifclear |
| @ifset vms |
| On OpenVMS, these init and final procedures are exported in uppercase |
| letters. For example if /BUILD_LIBRARY=toto is used, the exported name of |
| the init procedure will be "TOTOINIT" and the exported name of the final |
| procedure will be "TOTOFINAL". |
| @end ifset |
| |
| @item ^-Mxyz^/RENAME_MAIN=xyz^ |
| @cindex @option{^-M^/RENAME_MAIN^} (@command{gnatbind}) |
| Rename generated main program from main to xyz. This option is |
| supported on cross environments only. |
| |
| @item ^-m^/ERROR_LIMIT=^@var{n} |
| @cindex @option{^-m^/ERROR_LIMIT^} (@command{gnatbind}) |
| Limit number of detected errors to @var{n}, where @var{n} is |
| in the range 1..999_999. The default value if no switch is |
| given is 9999. Binding is terminated if the limit is exceeded. |
| @ifset unw |
| Furthermore, under Windows, the sources pointed to by the libraries path |
| set in the registry are not searched for. |
| @end ifset |
| |
| @item ^-n^/NOMAIN^ |
| @cindex @option{^-n^/NOMAIN^} (@command{gnatbind}) |
| No main program. |
| |
| @item -nostdinc |
| @cindex @option{-nostdinc} (@command{gnatbind}) |
| Do not look for sources in the system default directory. |
| |
| @item -nostdlib |
| @cindex @option{-nostdlib} (@command{gnatbind}) |
| Do not look for library files in the system default directory. |
| |
| @item --RTS=@var{rts-path} |
| @cindex @option{--RTS} (@code{gnatbind}) |
| Specifies the default location of the runtime library. Same meaning as the |
| equivalent @command{gnatmake} flag (@pxref{Switches for gnatmake}). |
| |
| @item ^-o ^/OUTPUT=^@var{file} |
| @cindex @option{^-o ^/OUTPUT^} (@command{gnatbind}) |
| Name the output file @var{file} (default is @file{b~@var{xxx}.adb}). |
| Note that if this option is used, then linking must be done manually, |
| gnatlink cannot be used. |
| |
| @item ^-O^/OBJECT_LIST^ |
| @cindex @option{^-O^/OBJECT_LIST^} (@command{gnatbind}) |
| Output object list. |
| |
| @item ^-p^/PESSIMISTIC_ELABORATION^ |
| @cindex @option{^-p^/PESSIMISTIC_ELABORATION^} (@command{gnatbind}) |
| Pessimistic (worst-case) elaboration order |
| |
| @item ^-s^/READ_SOURCES=ALL^ |
| @cindex @option{^-s^/READ_SOURCES=ALL^} (@command{gnatbind}) |
| Require all source files to be present. |
| |
| @item ^-S@var{xxx}^/INITIALIZE_SCALARS=@var{xxx}^ |
| @cindex @option{^-S^/INITIALIZE_SCALARS^} (@command{gnatbind}) |
| Specifies the value to be used when detecting uninitialized scalar |
| objects with pragma Initialize_Scalars. |
| The @var{xxx} ^string specified with the switch^option^ may be either |
| @itemize @bullet |
| @item ``@option{^in^INVALID^}'' requesting an invalid value where possible |
| @item ``@option{^lo^LOW^}'' for the lowest possible value |
| @item ``@option{^hi^HIGH^}'' for the highest possible value |
| @item ``@option{xx}'' for a value consisting of repeated bytes with the |
| value 16#xx# (i.e. xx is a string of two hexadecimal digits). |
| @end itemize |
| |
| In addition, you can specify @option{-Sev} to indicate that the value is |
| to be set at run time. In this case, the program will look for an environment |
| @cindex GNAT_INIT_SCALARS |
| variable of the form @code{GNAT_INIT_SCALARS=xx}, where xx is one |
| of @option{in/lo/hi/xx} with the same meanings as above. |
| If no environment variable is found, or if it does not have a valid value, |
| then the default is @option{in} (invalid values). |
| |
| @ifclear vms |
| @item -static |
| @cindex @option{-static} (@code{gnatbind}) |
| Link against a static GNAT run time. |
| |
| @item -shared |
| @cindex @option{-shared} (@code{gnatbind}) |
| Link against a shared GNAT run time when available. |
| @end ifclear |
| |
| @item ^-t^/NOTIME_STAMP_CHECK^ |
| @cindex @option{^-t^/NOTIME_STAMP_CHECK^} (@code{gnatbind}) |
| Tolerate time stamp and other consistency errors |
| |
| @item ^-T@var{n}^/TIME_SLICE=@var{n}^ |
| @cindex @option{^-T^/TIME_SLICE^} (@code{gnatbind}) |
| Set the time slice value to @var{n} milliseconds. If the system supports |
| the specification of a specific time slice value, then the indicated value |
| is used. If the system does not support specific time slice values, but |
| does support some general notion of round-robin scheduling, then any |
| nonzero value will activate round-robin scheduling. |
| |
| A value of zero is treated specially. It turns off time |
| slicing, and in addition, indicates to the tasking run time that the |
| semantics should match as closely as possible the Annex D |
| requirements of the Ada RM, and in particular sets the default |
| scheduling policy to @code{FIFO_Within_Priorities}. |
| |
| |
| @item ^-u@var{n}^/DYNAMIC_STACK_USAGE=@var{n}^ |
| @cindex @option{^-u^/DYNAMIC_STACK_USAGE^} (@code{gnatbind}) |
| Enable dynamic stack usage, with n result stored and displayed at program |
| termination. Results that can't be stored are displayed on the fly, at task |
| termination. This option is currently not supported on OpenVMS I64 platforms. |
| |
| @item ^-v^/REPORT_ERRORS=VERBOSE^ |
| @cindex @option{^-v^/REPORT_ERRORS=VERBOSE^} (@code{gnatbind}) |
| Verbose mode. Write error messages, header, summary output to |
| @file{stdout}. |
| |
| @ifclear vms |
| @item -w@var{x} |
| @cindex @option{-w} (@code{gnatbind}) |
| Warning mode (@var{x}=s/e for suppress/treat as error) |
| @end ifclear |
| |
| @ifset vms |
| @item /WARNINGS=NORMAL |
| @cindex @option{/WARNINGS} (@code{gnatbind}) |
| Normal warnings mode. Warnings are issued but ignored |
| |
| @item /WARNINGS=SUPPRESS |
| @cindex @option{/WARNINGS} (@code{gnatbind}) |
| All warning messages are suppressed |
| |
| @item /WARNINGS=ERROR |
| @cindex @option{/WARNINGS} (@code{gnatbind}) |
| Warning messages are treated as fatal errors |
| @end ifset |
| |
| @item ^-x^/READ_SOURCES=NONE^ |
| @cindex @option{^-x^/READ_SOURCES^} (@code{gnatbind}) |
| Exclude source files (check object consistency only). |
| |
| @ifset vms |
| @item /READ_SOURCES=AVAILABLE |
| @cindex @option{/READ_SOURCES} (@code{gnatbind}) |
| Default mode, in which sources are checked for consistency only if |
| they are available. |
| @end ifset |
| |
| @item ^-z^/ZERO_MAIN^ |
| @cindex @option{^-z^/ZERO_MAIN^} (@code{gnatbind}) |
| No main subprogram. |
| @end table |
| |
| @ifclear vms |
| @noindent |
| You may obtain this listing of switches by running @code{gnatbind} with |
| no arguments. |
| @end ifclear |
| |
| @node Consistency-Checking Modes |
| @subsection Consistency-Checking Modes |
| |
| @noindent |
| As described earlier, by default @code{gnatbind} checks |
| that object files are consistent with one another and are consistent |
| with any source files it can locate. The following switches control binder |
| access to sources. |
| |
| @table @option |
| @c !sort! |
| @item ^-s^/READ_SOURCES=ALL^ |
| @cindex @option{^-s^/READ_SOURCES=ALL^} (@code{gnatbind}) |
| Require source files to be present. In this mode, the binder must be |
| able to locate all source files that are referenced, in order to check |
| their consistency. In normal mode, if a source file cannot be located it |
| is simply ignored. If you specify this switch, a missing source |
| file is an error. |
| |
| @item ^-x^/READ_SOURCES=NONE^ |
| @cindex @option{^-x^/READ_SOURCES=NONE^} (@code{gnatbind}) |
| Exclude source files. In this mode, the binder only checks that ALI |
| files are consistent with one another. Source files are not accessed. |
| The binder runs faster in this mode, and there is still a guarantee that |
| the resulting program is self-consistent. |
| If a source file has been edited since it was last compiled, and you |
| specify this switch, the binder will not detect that the object |
| file is out of date with respect to the source file. Note that this is the |
| mode that is automatically used by @command{gnatmake} because in this |
| case the checking against sources has already been performed by |
| @command{gnatmake} in the course of compilation (i.e. before binding). |
| |
| @ifset vms |
| @item /READ_SOURCES=AVAILABLE |
| @cindex @code{/READ_SOURCES=AVAILABLE} (@code{gnatbind}) |
| This is the default mode in which source files are checked if they are |
| available, and ignored if they are not available. |
| @end ifset |
| @end table |
| |
| @node Binder Error Message Control |
| @subsection Binder Error Message Control |
| |
| @noindent |
| The following switches provide control over the generation of error |
| messages from the binder: |
| |
| @table @option |
| @c !sort! |
| @item ^-v^/REPORT_ERRORS=VERBOSE^ |
| @cindex @option{^-v^/REPORT_ERRORS=VERBOSE^} (@code{gnatbind}) |
| Verbose mode. In the normal mode, brief error messages are generated to |
| @file{stderr}. If this switch is present, a header is written |
| to @file{stdout} and any error messages are directed to @file{stdout}. |
| All that is written to @file{stderr} is a brief summary message. |
| |
| @item ^-b^/REPORT_ERRORS=BRIEF^ |
| @cindex @option{^-b^/REPORT_ERRORS=BRIEF^} (@code{gnatbind}) |
| Generate brief error messages to @file{stderr} even if verbose mode is |
| specified. This is relevant only when used with the |
| @option{^-v^/REPORT_ERRORS=VERBOSE^} switch. |
| |
| @ifclear vms |
| @item -m@var{n} |
| @cindex @option{-m} (@code{gnatbind}) |
| Limits the number of error messages to @var{n}, a decimal integer in the |
| range 1-999. The binder terminates immediately if this limit is reached. |
| |
| @item -M@var{xxx} |
| @cindex @option{-M} (@code{gnatbind}) |
| Renames the generated main program from @code{main} to @code{xxx}. |
| This is useful in the case of some cross-building environments, where |
| the actual main program is separate from the one generated |
| by @code{gnatbind}. |
| @end ifclear |
| |
| @item ^-ws^/WARNINGS=SUPPRESS^ |
| @cindex @option{^-ws^/WARNINGS=SUPPRESS^} (@code{gnatbind}) |
| @cindex Warnings |
| Suppress all warning messages. |
| |
| @item ^-we^/WARNINGS=ERROR^ |
| @cindex @option{^-we^/WARNINGS=ERROR^} (@code{gnatbind}) |
| Treat any warning messages as fatal errors. |
| |
| @ifset vms |
| @item /WARNINGS=NORMAL |
| Standard mode with warnings generated, but warnings do not get treated |
| as errors. |
| @end ifset |
| |
| @item ^-t^/NOTIME_STAMP_CHECK^ |
| @cindex @option{^-t^/NOTIME_STAMP_CHECK^} (@code{gnatbind}) |
| @cindex Time stamp checks, in binder |
| @cindex Binder consistency checks |
| @cindex Consistency checks, in binder |
| The binder performs a number of consistency checks including: |
| |
| @itemize @bullet |
| @item |
| Check that time stamps of a given source unit are consistent |
| @item |
| Check that checksums of a given source unit are consistent |
| @item |
| Check that consistent versions of @code{GNAT} were used for compilation |
| @item |
| Check consistency of configuration pragmas as required |
| @end itemize |
| |
| @noindent |
| Normally failure of such checks, in accordance with the consistency |
| requirements of the Ada Reference Manual, causes error messages to be |
| generated which abort the binder and prevent the output of a binder |
| file and subsequent link to obtain an executable. |
| |
| The @option{^-t^/NOTIME_STAMP_CHECK^} switch converts these error messages |
| into warnings, so that |
| binding and linking can continue to completion even in the presence of such |
| errors. The result may be a failed link (due to missing symbols), or a |
| non-functional executable which has undefined semantics. |
| @emph{This means that |
| @option{^-t^/NOTIME_STAMP_CHECK^} should be used only in unusual situations, |
| with extreme care.} |
| @end table |
| |
| @node Elaboration Control |
| @subsection Elaboration Control |
| |
| @noindent |
| The following switches provide additional control over the elaboration |
| order. For full details see @ref{Elaboration Order Handling in GNAT}. |
| |
| @table @option |
| @item ^-p^/PESSIMISTIC_ELABORATION^ |
| @cindex @option{^-p^/PESSIMISTIC_ELABORATION^} (@code{gnatbind}) |
| Normally the binder attempts to choose an elaboration order that is |
| likely to minimize the likelihood of an elaboration order error resulting |
| in raising a @code{Program_Error} exception. This switch reverses the |
| action of the binder, and requests that it deliberately choose an order |
| that is likely to maximize the likelihood of an elaboration error. |
| This is useful in ensuring portability and avoiding dependence on |
| accidental fortuitous elaboration ordering. |
| |
| Normally it only makes sense to use the @option{^-p^/PESSIMISTIC_ELABORATION^} |
| switch if dynamic |
| elaboration checking is used (@option{-gnatE} switch used for compilation). |
| This is because in the default static elaboration mode, all necessary |
| @code{Elaborate} and @code{Elaborate_All} pragmas are implicitly inserted. |
| These implicit pragmas are still respected by the binder in |
| @option{^-p^/PESSIMISTIC_ELABORATION^} mode, so a |
| safe elaboration order is assured. |
| @end table |
| |
| @node Output Control |
| @subsection Output Control |
| |
| @noindent |
| The following switches allow additional control over the output |
| generated by the binder. |
| |
| @table @option |
| @c !sort! |
| |
| @item ^-A^/BIND_FILE=ADA^ |
| @cindex @option{^-A^/BIND_FILE=ADA^} (@code{gnatbind}) |
| Generate binder program in Ada (default). The binder program is named |
| @file{b~@var{mainprog}.adb} by default. This can be changed with |
| @option{^-o^/OUTPUT^} @code{gnatbind} option. |
| |
| @item ^-c^/NOOUTPUT^ |
| @cindex @option{^-c^/NOOUTPUT^} (@code{gnatbind}) |
| Check only. Do not generate the binder output file. In this mode the |
| binder performs all error checks but does not generate an output file. |
| |
| @item ^-C^/BIND_FILE=C^ |
| @cindex @option{^-C^/BIND_FILE=C^} (@code{gnatbind}) |
| Generate binder program in C. The binder program is named |
| @file{b_@var{mainprog}.c}. |
| This can be changed with @option{^-o^/OUTPUT^} @code{gnatbind} |
| option. |
| |
| @item ^-e^/ELABORATION_DEPENDENCIES^ |
| @cindex @option{^-e^/ELABORATION_DEPENDENCIES^} (@code{gnatbind}) |
| Output complete list of elaboration-order dependencies, showing the |
| reason for each dependency. This output can be rather extensive but may |
| be useful in diagnosing problems with elaboration order. The output is |
| written to @file{stdout}. |
| |
| @item ^-h^/HELP^ |
| @cindex @option{^-h^/HELP^} (@code{gnatbind}) |
| Output usage information. The output is written to @file{stdout}. |
| |
| @item ^-K^/LINKER_OPTION_LIST^ |
| @cindex @option{^-K^/LINKER_OPTION_LIST^} (@code{gnatbind}) |
| Output linker options to @file{stdout}. Includes library search paths, |
| contents of pragmas Ident and Linker_Options, and libraries added |
| by @code{gnatbind}. |
| |
| @item ^-l^/ORDER_OF_ELABORATION^ |
| @cindex @option{^-l^/ORDER_OF_ELABORATION^} (@code{gnatbind}) |
| Output chosen elaboration order. The output is written to @file{stdout}. |
| |
| @item ^-O^/OBJECT_LIST^ |
| @cindex @option{^-O^/OBJECT_LIST^} (@code{gnatbind}) |
| Output full names of all the object files that must be linked to provide |
| the Ada component of the program. The output is written to @file{stdout}. |
| This list includes the files explicitly supplied and referenced by the user |
| as well as implicitly referenced run-time unit files. The latter are |
| omitted if the corresponding units reside in shared libraries. The |
| directory names for the run-time units depend on the system configuration. |
| |
| @item ^-o ^/OUTPUT=^@var{file} |
| @cindex @option{^-o^/OUTPUT^} (@code{gnatbind}) |
| Set name of output file to @var{file} instead of the normal |
| @file{b~@var{mainprog}.adb} default. Note that @var{file} denote the Ada |
| binder generated body filename. In C mode you would normally give |
| @var{file} an extension of @file{.c} because it will be a C source program. |
| Note that if this option is used, then linking must be done manually. |
| It is not possible to use gnatlink in this case, since it cannot locate |
| the binder file. |
| |
| @item ^-r^/RESTRICTION_LIST^ |
| @cindex @option{^-r^/RESTRICTION_LIST^} (@code{gnatbind}) |
| Generate list of @code{pragma Restrictions} that could be applied to |
| the current unit. This is useful for code audit purposes, and also may |
| be used to improve code generation in some cases. |
| |
| @end table |
| |
| @node Binding with Non-Ada Main Programs |
| @subsection Binding with Non-Ada Main Programs |
| |
| @noindent |
| In our description so far we have assumed that the main |
| program is in Ada, and that the task of the binder is to generate a |
| corresponding function @code{main} that invokes this Ada main |
| program. GNAT also supports the building of executable programs where |
| the main program is not in Ada, but some of the called routines are |
| written in Ada and compiled using GNAT (@pxref{Mixed Language Programming}). |
| The following switch is used in this situation: |
| |
| @table @option |
| @item ^-n^/NOMAIN^ |
| @cindex @option{^-n^/NOMAIN^} (@code{gnatbind}) |
| No main program. The main program is not in Ada. |
| @end table |
| |
| @noindent |
| In this case, most of the functions of the binder are still required, |
| but instead of generating a main program, the binder generates a file |
| containing the following callable routines: |
| |
| @table @code |
| @item adainit |
| @findex adainit |
| You must call this routine to initialize the Ada part of the program by |
| calling the necessary elaboration routines. A call to @code{adainit} is |
| required before the first call to an Ada subprogram. |
| |
| Note that it is assumed that the basic execution environment must be setup |
| to be appropriate for Ada execution at the point where the first Ada |
| subprogram is called. In particular, if the Ada code will do any |
| floating-point operations, then the FPU must be setup in an appropriate |
| manner. For the case of the x86, for example, full precision mode is |
| required. The procedure GNAT.Float_Control.Reset may be used to ensure |
| that the FPU is in the right state. |
| |
| @item adafinal |
| @findex adafinal |
| You must call this routine to perform any library-level finalization |
| required by the Ada subprograms. A call to @code{adafinal} is required |
| after the last call to an Ada subprogram, and before the program |
| terminates. |
| @end table |
| |
| @noindent |
| If the @option{^-n^/NOMAIN^} switch |
| @cindex @option{^-n^/NOMAIN^} (@command{gnatbind}) |
| @cindex Binder, multiple input files |
| is given, more than one ALI file may appear on |
| the command line for @code{gnatbind}. The normal @dfn{closure} |
| calculation is performed for each of the specified units. Calculating |
| the closure means finding out the set of units involved by tracing |
| @code{with} references. The reason it is necessary to be able to |
| specify more than one ALI file is that a given program may invoke two or |
| more quite separate groups of Ada units. |
| |
| The binder takes the name of its output file from the last specified ALI |
| file, unless overridden by the use of the @option{^-o file^/OUTPUT=file^}. |
| @cindex @option{^-o^/OUTPUT^} (@command{gnatbind}) |
| The output is an Ada unit in source form that can |
| be compiled with GNAT unless the -C switch is used in which case the |
| output is a C source file, which must be compiled using the C compiler. |
| This compilation occurs automatically as part of the @command{gnatlink} |
| processing. |
| |
| Currently the GNAT run time requires a FPU using 80 bits mode |
| precision. Under targets where this is not the default it is required to |
| call GNAT.Float_Control.Reset before using floating point numbers (this |
| include float computation, float input and output) in the Ada code. A |
| side effect is that this could be the wrong mode for the foreign code |
| where floating point computation could be broken after this call. |
| |
| @node Binding Programs with No Main Subprogram |
| @subsection Binding Programs with No Main Subprogram |
| |
| @noindent |
| It is possible to have an Ada program which does not have a main |
| subprogram. This program will call the elaboration routines of all the |
| packages, then the finalization routines. |
| |
| The following switch is used to bind programs organized in this manner: |
| |
| @table @option |
| @item ^-z^/ZERO_MAIN^ |
| @cindex @option{^-z^/ZERO_MAIN^} (@code{gnatbind}) |
| Normally the binder checks that the unit name given on the command line |
| corresponds to a suitable main subprogram. When this switch is used, |
| a list of ALI files can be given, and the execution of the program |
| consists of elaboration of these units in an appropriate order. |
| @end table |
| |
| @node Command-Line Access |
| @section Command-Line Access |
| |
| @noindent |
| The package @code{Ada.Command_Line} provides access to the command-line |
| arguments and program name. In order for this interface to operate |
| correctly, the two variables |
| |
| @smallexample |
| @group |
| int gnat_argc; |
| char **gnat_argv; |
| @end group |
| @end smallexample |
| |
| @noindent |
| @findex gnat_argv |
| @findex gnat_argc |
| are declared in one of the GNAT library routines. These variables must |
| be set from the actual @code{argc} and @code{argv} values passed to the |
| main program. With no @option{^n^/NOMAIN^} present, @code{gnatbind} |
| generates the C main program to automatically set these variables. |
| If the @option{^n^/NOMAIN^} switch is used, there is no automatic way to |
| set these variables. If they are not set, the procedures in |
| @code{Ada.Command_Line} will not be available, and any attempt to use |
| them will raise @code{Constraint_Error}. If command line access is |
| required, your main program must set @code{gnat_argc} and |
| @code{gnat_argv} from the @code{argc} and @code{argv} values passed to |
| it. |
| |
| @node Search Paths for gnatbind |
| @section Search Paths for @code{gnatbind} |
| |
| @noindent |
| The binder takes the name of an ALI file as its argument and needs to |
| locate source files as well as other ALI files to verify object consistency. |
| |
| For source files, it follows exactly the same search rules as @command{gcc} |
| (@pxref{Search Paths and the Run-Time Library (RTL)}). For ALI files the |
| directories searched are: |
| |
| @enumerate |
| @item |
| The directory containing the ALI file named in the command line, unless |
| the switch @option{^-I-^/NOCURRENT_DIRECTORY^} is specified. |
| |
| @item |
| All directories specified by @option{^-I^/SEARCH^} |
| switches on the @code{gnatbind} |
| command line, in the order given. |
| |
| @item |
| @findex ADA_PRJ_OBJECTS_FILE |
| Each of the directories listed in the text file whose name is given |
| by the @code{ADA_PRJ_OBJECTS_FILE} ^environment variable^logical name^. |
| |
| @noindent |
| @code{ADA_PRJ_OBJECTS_FILE} is normally set by gnatmake or by the ^gnat^GNAT^ |
| driver when project files are used. It should not normally be set |
| by other means. |
| |
| @item |
| @findex ADA_OBJECTS_PATH |
| Each of the directories listed in the value of the |
| @code{ADA_OBJECTS_PATH} ^environment variable^logical name^. |
| @ifset unw |
| Construct this value |
| exactly as the @code{PATH} environment variable: a list of directory |
| names separated by colons (semicolons when working with the NT version |
| of GNAT). |
| @end ifset |
| @ifset vms |
| Normally, define this value as a logical name containing a comma separated |
| list of directory names. |
| |
| This variable can also be defined by means of an environment string |
| (an argument to the HP C exec* set of functions). |
| |
| Logical Name: |
| @smallexample |
| DEFINE ANOTHER_PATH FOO:[BAG] |
| DEFINE ADA_OBJECTS_PATH ANOTHER_PATH,FOO:[BAM],FOO:[BAR] |
| @end smallexample |
| |
| By default, the path includes GNU:[LIB.OPENVMS7_x.2_8_x.DECLIB] |
| first, followed by the standard Ada 95 |
| libraries in GNU:[LIB.OPENVMS7_x.2_8_x.ADALIB]. |
| If this is not redefined, the user will obtain the HP Ada 83 IO packages |
| (Text_IO, Sequential_IO, etc) |
| instead of the Ada95 packages. Thus, in order to get the Ada 95 |
| packages by default, ADA_OBJECTS_PATH must be redefined. |
| @end ifset |
| |
| @item |
| The content of the @file{ada_object_path} file which is part of the GNAT |
| installation tree and is used to store standard libraries such as the |
| GNAT Run Time Library (RTL) unless the switch @option{-nostdlib} is |
| specified. |
| @ifclear vms |
| @ref{Installing a library} |
| @end ifclear |
| @end enumerate |
| |
| @noindent |
| In the binder the switch @option{^-I^/SEARCH^} |
| @cindex @option{^-I^/SEARCH^} (@command{gnatbind}) |
| is used to specify both source and |
| library file paths. Use @option{^-aI^/SOURCE_SEARCH^} |
| @cindex @option{^-aI^/SOURCE_SEARCH^} (@command{gnatbind}) |
| instead if you want to specify |
| source paths only, and @option{^-aO^/LIBRARY_SEARCH^} |
| @cindex @option{^-aO^/LIBRARY_SEARCH^} (@command{gnatbind}) |
| if you want to specify library paths |
| only. This means that for the binder |
| @option{^-I^/SEARCH=^}@var{dir} is equivalent to |
| @option{^-aI^/SOURCE_SEARCH=^}@var{dir} |
| @option{^-aO^/OBJECT_SEARCH=^}@var{dir}. |
| The binder generates the bind file (a C language source file) in the |
| current working directory. |
| |
| @findex Ada |
| @findex System |
| @findex Interfaces |
| @findex GNAT |
| The packages @code{Ada}, @code{System}, and @code{Interfaces} and their |
| children make up the GNAT Run-Time Library, together with the package |
| GNAT and its children, which contain a set of useful additional |
| library functions provided by GNAT. The sources for these units are |
| needed by the compiler and are kept together in one directory. The ALI |
| files and object files generated by compiling the RTL are needed by the |
| binder and the linker and are kept together in one directory, typically |
| different from the directory containing the sources. In a normal |
| installation, you need not specify these directory names when compiling |
| or binding. Either the environment variables or the built-in defaults |
| cause these files to be found. |
| |
| Besides simplifying access to the RTL, a major use of search paths is |
| in compiling sources from multiple directories. This can make |
| development environments much more flexible. |
| |
| @node Examples of gnatbind Usage |
| @section Examples of @code{gnatbind} Usage |
| |
| @noindent |
| This section contains a number of examples of using the GNAT binding |
| utility @code{gnatbind}. |
| |
| @table @code |
| @item gnatbind hello |
| The main program @code{Hello} (source program in @file{hello.adb}) is |
| bound using the standard switch settings. The generated main program is |
| @file{b~hello.adb}. This is the normal, default use of the binder. |
| |
| @ifclear vms |
| @item gnatbind hello -o mainprog.adb |
| @end ifclear |
| @ifset vms |
| @item gnatbind HELLO.ALI /OUTPUT=Mainprog.ADB |
| @end ifset |
| The main program @code{Hello} (source program in @file{hello.adb}) is |
| bound using the standard switch settings. The generated main program is |
| @file{mainprog.adb} with the associated spec in |
| @file{mainprog.ads}. Note that you must specify the body here not the |
| spec, in the case where the output is in Ada. Note that if this option |
| is used, then linking must be done manually, since gnatlink will not |
| be able to find the generated file. |
| |
| @ifclear vms |
| @item gnatbind main -C -o mainprog.c -x |
| @end ifclear |
| @ifset vms |
| @item gnatbind MAIN.ALI /BIND_FILE=C /OUTPUT=Mainprog.C /READ_SOURCES=NONE |
| @end ifset |
| The main program @code{Main} (source program in |
| @file{main.adb}) is bound, excluding source files from the |
| consistency checking, generating |
| the file @file{mainprog.c}. |
| |
| @ifclear vms |
| @item gnatbind -x main_program -C -o mainprog.c |
| This command is exactly the same as the previous example. Switches may |
| appear anywhere in the command line, and single letter switches may be |
| combined into a single switch. |
| @end ifclear |
| |
| @ifclear vms |
| @item gnatbind -n math dbase -C -o ada-control.c |
| @end ifclear |
| @ifset vms |
| @item gnatbind /NOMAIN math dbase /BIND_FILE=C /OUTPUT=ada-control.c |
| @end ifset |
| The main program is in a language other than Ada, but calls to |
| subprograms in packages @code{Math} and @code{Dbase} appear. This call |
| to @code{gnatbind} generates the file @file{ada-control.c} containing |
| the @code{adainit} and @code{adafinal} routines to be called before and |
| after accessing the Ada units. |
| @end table |
| |
| @c ------------------------------------ |
| @node Linking Using gnatlink |
| @chapter Linking Using @command{gnatlink} |
| @c ------------------------------------ |
| @findex gnatlink |
| |
| @noindent |
| This chapter discusses @command{gnatlink}, a tool that links |
| an Ada program and builds an executable file. This utility |
| invokes the system linker ^(via the @command{gcc} command)^^ |
| with a correct list of object files and library references. |
| @command{gnatlink} automatically determines the list of files and |
| references for the Ada part of a program. It uses the binder file |
| generated by the @command{gnatbind} to determine this list. |
| |
| @menu |
| * Running gnatlink:: |
| * Switches for gnatlink:: |
| @end menu |
| |
| @node Running gnatlink |
| @section Running @command{gnatlink} |
| |
| @noindent |
| The form of the @command{gnatlink} command is |
| |
| @smallexample |
| $ gnatlink [@var{switches}] @var{mainprog}[.ali] |
| [@var{non-Ada objects}] [@var{linker options}] |
| @end smallexample |
| |
| @noindent |
| The arguments of @command{gnatlink} (switches, main @file{ALI} file, |
| non-Ada objects |
| or linker options) may be in any order, provided that no non-Ada object may |
| be mistaken for a main @file{ALI} file. |
| Any file name @file{F} without the @file{.ali} |
| extension will be taken as the main @file{ALI} file if a file exists |
| whose name is the concatenation of @file{F} and @file{.ali}. |
| |
| @noindent |
| @file{@var{mainprog}.ali} references the ALI file of the main program. |
| The @file{.ali} extension of this file can be omitted. From this |
| reference, @command{gnatlink} locates the corresponding binder file |
| @file{b~@var{mainprog}.adb} and, using the information in this file along |
| with the list of non-Ada objects and linker options, constructs a |
| linker command file to create the executable. |
| |
| The arguments other than the @command{gnatlink} switches and the main |
| @file{ALI} file are passed to the linker uninterpreted. |
| They typically include the names of |
| object files for units written in other languages than Ada and any library |
| references required to resolve references in any of these foreign language |
| units, or in @code{Import} pragmas in any Ada units. |
| |
| @var{linker options} is an optional list of linker specific |
| switches. |
| The default linker called by gnatlink is @var{gcc} which in |
| turn calls the appropriate system linker. |
| Standard options for the linker such as @option{-lmy_lib} or |
| @option{-Ldir} can be added as is. |
| For options that are not recognized by |
| @var{gcc} as linker options, use the @var{gcc} switches @option{-Xlinker} or |
| @option{-Wl,}. |
| Refer to the GCC documentation for |
| details. Here is an example showing how to generate a linker map: |
| |
| @smallexample |
| $ ^gnatlink my_prog -Wl,-Map,MAPFILE^GNAT LINK my_prog.ali /MAP^ |
| @end smallexample |
| |
| Using @var{linker options} it is possible to set the program stack and |
| heap size. |
| @ifclear vms |
| See @ref{Setting Stack Size from gnatlink} and |
| @ref{Setting Heap Size from gnatlink}. |
| @end ifclear |
| |
| @command{gnatlink} determines the list of objects required by the Ada |
| program and prepends them to the list of objects passed to the linker. |
| @command{gnatlink} also gathers any arguments set by the use of |
| @code{pragma Linker_Options} and adds them to the list of arguments |
| presented to the linker. |
| |
| @ifset vms |
| @command{gnatlink} accepts the following types of extra files on the command |
| line: objects (.OBJ), libraries (.OLB), sharable images (.EXE), and |
| options files (.OPT). These are recognized and handled according to their |
| extension. |
| @end ifset |
| |
| @node Switches for gnatlink |
| @section Switches for @command{gnatlink} |
| |
| @noindent |
| The following switches are available with the @command{gnatlink} utility: |
| |
| @table @option |
| @c !sort! |
| |
| @item ^-A^/BIND_FILE=ADA^ |
| @cindex @option{^-A^/BIND_FILE=ADA^} (@command{gnatlink}) |
| The binder has generated code in Ada. This is the default. |
| |
| @item ^-C^/BIND_FILE=C^ |
| @cindex @option{^-C^/BIND_FILE=C^} (@command{gnatlink}) |
| If instead of generating a file in Ada, the binder has generated one in |
| C, then the linker needs to know about it. Use this switch to signal |
| to @command{gnatlink} that the binder has generated C code rather than |
| Ada code. |
| |
| @item ^-f^/FORCE_OBJECT_FILE_LIST^ |
| @cindex Command line length |
| @cindex @option{^-f^/FORCE_OBJECT_FILE_LIST^} (@command{gnatlink}) |
| On some targets, the command line length is limited, and @command{gnatlink} |
| will generate a separate file for the linker if the list of object files |
| is too long. |
| The @option{^-f^/FORCE_OBJECT_FILE_LIST^} switch forces this file |
| to be generated even if |
| the limit is not exceeded. This is useful in some cases to deal with |
| special situations where the command line length is exceeded. |
| |
| @item ^-g^/DEBUG^ |
| @cindex Debugging information, including |
| @cindex @option{^-g^/DEBUG^} (@command{gnatlink}) |
| The option to include debugging information causes the Ada bind file (in |
| other words, @file{b~@var{mainprog}.adb}) to be compiled with |
| @option{^-g^/DEBUG^}. |
| In addition, the binder does not delete the @file{b~@var{mainprog}.adb}, |
| @file{b~@var{mainprog}.o} and @file{b~@var{mainprog}.ali} files. |
| Without @option{^-g^/DEBUG^}, the binder removes these files by |
| default. The same procedure apply if a C bind file was generated using |
| @option{^-C^/BIND_FILE=C^} @code{gnatbind} option, in this case the filenames |
| are @file{b_@var{mainprog}.c} and @file{b_@var{mainprog}.o}. |
| |
| @item ^-n^/NOCOMPILE^ |
| @cindex @option{^-n^/NOCOMPILE^} (@command{gnatlink}) |
| Do not compile the file generated by the binder. This may be used when |
| a link is rerun with different options, but there is no need to recompile |
| the binder file. |
| |
| @item ^-v^/VERBOSE^ |
| @cindex @option{^-v^/VERBOSE^} (@command{gnatlink}) |
| Causes additional information to be output, including a full list of the |
| included object files. This switch option is most useful when you want |
| to see what set of object files are being used in the link step. |
| |
| @item ^-v -v^/VERBOSE/VERBOSE^ |
| @cindex @option{^-v -v^/VERBOSE/VERBOSE^} (@command{gnatlink}) |
| Very verbose mode. Requests that the compiler operate in verbose mode when |
| it compiles the binder file, and that the system linker run in verbose mode. |
| |
| @item ^-o ^/EXECUTABLE=^@var{exec-name} |
| @cindex @option{^-o^/EXECUTABLE^} (@command{gnatlink}) |
| @var{exec-name} specifies an alternate name for the generated |
| executable program. If this switch is omitted, the executable has the same |
| name as the main unit. For example, @code{gnatlink try.ali} creates |
| an executable called @file{^try^TRY.EXE^}. |
| |
| @ifclear vms |
| @item -b @var{target} |
| @cindex @option{-b} (@command{gnatlink}) |
| Compile your program to run on @var{target}, which is the name of a |
| system configuration. You must have a GNAT cross-compiler built if |
| @var{target} is not the same as your host system. |
| |
| @item -B@var{dir} |
| @cindex @option{-B} (@command{gnatlink}) |
| Load compiler executables (for example, @code{gnat1}, the Ada compiler) |
| from @var{dir} instead of the default location. Only use this switch |
| when multiple versions of the GNAT compiler are available. See the |
| @command{gcc} manual page for further details. You would normally use the |
| @option{-b} or @option{-V} switch instead. |
| |
| @item --GCC=@var{compiler_name} |
| @cindex @option{--GCC=compiler_name} (@command{gnatlink}) |
| Program used for compiling the binder file. The default is |
| @command{gcc}. You need to use quotes around @var{compiler_name} if |
| @code{compiler_name} contains spaces or other separator characters. |
| As an example @option{--GCC="foo -x -y"} will instruct @command{gnatlink} to |
| use @code{foo -x -y} as your compiler. Note that switch @option{-c} is always |
| inserted after your command name. Thus in the above example the compiler |
| command that will be used by @command{gnatlink} will be @code{foo -c -x -y}. |
| A limitation of this syntax is that the name and path name of the executable |
| itself must not include any embedded spaces. If several |
| @option{--GCC=compiler_name} are used, only the last @var{compiler_name} |
| is taken into account. However, all the additional switches are also taken |
| into account. Thus, |
| @option{--GCC="foo -x -y" --GCC="bar -z -t"} is equivalent to |
| @option{--GCC="bar -x -y -z -t"}. |
| |
| @item --LINK=@var{name} |
| @cindex @option{--LINK=} (@command{gnatlink}) |
| @var{name} is the name of the linker to be invoked. This is especially |
| useful in mixed language programs since languages such as C++ require |
| their own linker to be used. When this switch is omitted, the default |
| name for the linker is @command{gcc}. When this switch is used, the |
| specified linker is called instead of @command{gcc} with exactly the same |
| parameters that would have been passed to @command{gcc} so if the desired |
| linker requires different parameters it is necessary to use a wrapper |
| script that massages the parameters before invoking the real linker. It |
| may be useful to control the exact invocation by using the verbose |
| switch. |
| |
| @end ifclear |
| |
| @ifset vms |
| @item /DEBUG=TRACEBACK |
| @cindex @code{/DEBUG=TRACEBACK} (@command{gnatlink}) |
| This qualifier causes sufficient information to be included in the |
| executable file to allow a traceback, but does not include the full |
| symbol information needed by the debugger. |
| |
| @item /IDENTIFICATION="<string>" |
| @code{"<string>"} specifies the string to be stored in the image file |
| identification field in the image header. |
| It overrides any pragma @code{Ident} specified string. |
| |
| @item /NOINHIBIT-EXEC |
| Generate the executable file even if there are linker warnings. |
| |
| @item /NOSTART_FILES |
| Don't link in the object file containing the ``main'' transfer address. |
| Used when linking with a foreign language main program compiled with an |
| HP compiler. |
| |
| @item /STATIC |
| Prefer linking with object libraries over sharable images, even without |
| /DEBUG. |
| @end ifset |
| |
| @end table |
| |
| |
| @node The GNAT Make Program gnatmake |
| @chapter The GNAT Make Program @command{gnatmake} |
| @findex gnatmake |
| |
| @menu |
| * Running gnatmake:: |
| * Switches for gnatmake:: |
| * Mode Switches for gnatmake:: |
| * Notes on the Command Line:: |
| * How gnatmake Works:: |
| * Examples of gnatmake Usage:: |
| @end menu |
| @noindent |
| A typical development cycle when working on an Ada program consists of |
| the following steps: |
| |
| @enumerate |
| @item |
| Edit some sources to fix bugs. |
| |
| @item |
| Add enhancements. |
| |
| @item |
| Compile all sources affected. |
| |
| @item |
| Rebind and relink. |
| |
| @item |
| Test. |
| @end enumerate |
| |
| @noindent |
| The third step can be tricky, because not only do the modified files |
| @cindex Dependency rules |
| have to be compiled, but any files depending on these files must also be |
| recompiled. The dependency rules in Ada can be quite complex, especially |
| in the presence of overloading, @code{use} clauses, generics and inlined |
| subprograms. |
| |
| @command{gnatmake} automatically takes care of the third and fourth steps |
| of this process. It determines which sources need to be compiled, |
| compiles them, and binds and links the resulting object files. |
| |
| Unlike some other Ada make programs, the dependencies are always |
| accurately recomputed from the new sources. The source based approach of |
| the GNAT compilation model makes this possible. This means that if |
| changes to the source program cause corresponding changes in |
| dependencies, they will always be tracked exactly correctly by |
| @command{gnatmake}. |
| |
| @node Running gnatmake |
| @section Running @command{gnatmake} |
| |
| @noindent |
| The usual form of the @command{gnatmake} command is |
| |
| @smallexample |
| $ gnatmake [@var{switches}] @var{file_name} |
| [@var{file_names}] [@var{mode_switches}] |
| @end smallexample |
| |
| @noindent |
| The only required argument is one @var{file_name}, which specifies |
| a compilation unit that is a main program. Several @var{file_names} can be |
| specified: this will result in several executables being built. |
| If @code{switches} are present, they can be placed before the first |
| @var{file_name}, between @var{file_names} or after the last @var{file_name}. |
| If @var{mode_switches} are present, they must always be placed after |
| the last @var{file_name} and all @code{switches}. |
| |
| If you are using standard file extensions (.adb and .ads), then the |
| extension may be omitted from the @var{file_name} arguments. However, if |
| you are using non-standard extensions, then it is required that the |
| extension be given. A relative or absolute directory path can be |
| specified in a @var{file_name}, in which case, the input source file will |
| be searched for in the specified directory only. Otherwise, the input |
| source file will first be searched in the directory where |
| @command{gnatmake} was invoked and if it is not found, it will be search on |
| the source path of the compiler as described in |
| @ref{Search Paths and the Run-Time Library (RTL)}. |
| |
| All @command{gnatmake} output (except when you specify |
| @option{^-M^/DEPENDENCIES_LIST^}) is to |
| @file{stderr}. The output produced by the |
| @option{^-M^/DEPENDENCIES_LIST^} switch is send to |
| @file{stdout}. |
| |
| @node Switches for gnatmake |
| @section Switches for @command{gnatmake} |
| |
| @noindent |
| You may specify any of the following switches to @command{gnatmake}: |
| |
| @table @option |
| @c !sort! |
| @ifclear vms |
| @item --GCC=@var{compiler_name} |
| @cindex @option{--GCC=compiler_name} (@command{gnatmake}) |
| Program used for compiling. The default is `@command{gcc}'. You need to use |
| quotes around @var{compiler_name} if @code{compiler_name} contains |
| spaces or other separator characters. As an example @option{--GCC="foo -x |
| -y"} will instruct @command{gnatmake} to use @code{foo -x -y} as your |
| compiler. A limitation of this syntax is that the name and path name of |
| the executable itself must not include any embedded spaces. Note that |
| switch @option{-c} is always inserted after your command name. Thus in the |
| above example the compiler command that will be used by @command{gnatmake} |
| will be @code{foo -c -x -y}. If several @option{--GCC=compiler_name} are |
| used, only the last @var{compiler_name} is taken into account. However, |
| all the additional switches are also taken into account. Thus, |
| @option{--GCC="foo -x -y" --GCC="bar -z -t"} is equivalent to |
| @option{--GCC="bar -x -y -z -t"}. |
| |
| @item --GNATBIND=@var{binder_name} |
| @cindex @option{--GNATBIND=binder_name} (@command{gnatmake}) |
| Program used for binding. The default is `@code{gnatbind}'. You need to |
| use quotes around @var{binder_name} if @var{binder_name} contains spaces |
| or other separator characters. As an example @option{--GNATBIND="bar -x |
| -y"} will instruct @command{gnatmake} to use @code{bar -x -y} as your |
| binder. Binder switches that are normally appended by @command{gnatmake} |
| to `@code{gnatbind}' are now appended to the end of @code{bar -x -y}. |
| A limitation of this syntax is that the name and path name of the executable |
| itself must not include any embedded spaces. |
| |
| @item --GNATLINK=@var{linker_name} |
| @cindex @option{--GNATLINK=linker_name} (@command{gnatmake}) |
| Program used for linking. The default is `@command{gnatlink}'. You need to |
| use quotes around @var{linker_name} if @var{linker_name} contains spaces |
| or other separator characters. As an example @option{--GNATLINK="lan -x |
| -y"} will instruct @command{gnatmake} to use @code{lan -x -y} as your |
| linker. Linker switches that are normally appended by @command{gnatmake} to |
| `@command{gnatlink}' are now appended to the end of @code{lan -x -y}. |
| A limitation of this syntax is that the name and path name of the executable |
| itself must not include any embedded spaces. |
| |
| @end ifclear |
| |
| @item ^-a^/ALL_FILES^ |
| @cindex @option{^-a^/ALL_FILES^} (@command{gnatmake}) |
| Consider all files in the make process, even the GNAT internal system |
| files (for example, the predefined Ada library files), as well as any |
| locked files. Locked files are files whose ALI file is write-protected. |
| By default, |
| @command{gnatmake} does not check these files, |
| because the assumption is that the GNAT internal files are properly up |
| to date, and also that any write protected ALI files have been properly |
| installed. Note that if there is an installation problem, such that one |
| of these files is not up to date, it will be properly caught by the |
| binder. |
| You may have to specify this switch if you are working on GNAT |
| itself. The switch @option{^-a^/ALL_FILES^} is also useful |
| in conjunction with @option{^-f^/FORCE_COMPILE^} |
| if you need to recompile an entire application, |
| including run-time files, using special configuration pragmas, |
| such as a @code{Normalize_Scalars} pragma. |
| |
| By default |
| @code{gnatmake ^-a^/ALL_FILES^} compiles all GNAT |
| internal files with |
| @ifclear vms |
| @code{gcc -c -gnatpg} rather than @code{gcc -c}. |
| @end ifclear |
| @ifset vms |
| the @code{/CHECKS=SUPPRESS_ALL /STYLE_CHECKS=GNAT} switch. |
| @end ifset |
| |
| @item ^-b^/ACTIONS=BIND^ |
| @cindex @option{^-b^/ACTIONS=BIND^} (@command{gnatmake}) |
| Bind only. Can be combined with @option{^-c^/ACTIONS=COMPILE^} to do |
| compilation and binding, but no link. |
| Can be combined with @option{^-l^/ACTIONS=LINK^} |
| to do binding and linking. When not combined with |
| @option{^-c^/ACTIONS=COMPILE^} |
| all the units in the closure of the main program must have been previously |
| compiled and must be up to date. The root unit specified by @var{file_name} |
| may be given without extension, with the source extension or, if no GNAT |
| Project File is specified, with the ALI file extension. |
| |
| @item ^-c^/ACTIONS=COMPILE^ |
| @cindex @option{^-c^/ACTIONS=COMPILE^} (@command{gnatmake}) |
| Compile only. Do not perform binding, except when @option{^-b^/ACTIONS=BIND^} |
| is also specified. Do not perform linking, except if both |
| @option{^-b^/ACTIONS=BIND^} and |
| @option{^-l^/ACTIONS=LINK^} are also specified. |
| If the root unit specified by @var{file_name} is not a main unit, this is the |
| default. Otherwise @command{gnatmake} will attempt binding and linking |
| unless all objects are up to date and the executable is more recent than |
| the objects. |
| |
| @item ^-C^/MAPPING^ |
| @cindex @option{^-C^/MAPPING^} (@command{gnatmake}) |
| Use a temporary mapping file. A mapping file is a way to communicate to the |
| compiler two mappings: from unit names to file names (without any directory |
| information) and from file names to path names (with full directory |
| information). These mappings are used by the compiler to short-circuit the path |
| search. When @command{gnatmake} is invoked with this switch, it will create |
| a temporary mapping file, initially populated by the project manager, |
| if @option{^-P^/PROJECT_FILE^} is used, otherwise initially empty. |
| Each invocation of the compiler will add the newly accessed sources to the |
| mapping file. This will improve the source search during the next invocation |
| of the compiler. |
| |
| @item ^-C=^/USE_MAPPING_FILE=^@var{file} |
| @cindex @option{^-C=^/USE_MAPPING^} (@command{gnatmake}) |
| Use a specific mapping file. The file, specified as a path name (absolute or |
| relative) by this switch, should already exist, otherwise the switch is |
| ineffective. The specified mapping file will be communicated to the compiler. |
| This switch is not compatible with a project file |
| (^-P^/PROJECT_FILE=^@var{file}) or with multiple compiling processes |
| (^-j^/PROCESSES=^nnn, when nnn is greater than 1). |
| |
| @item ^-D ^/DIRECTORY_OBJECTS=^@var{dir} |
| @cindex @option{^-D^/DIRECTORY_OBJECTS^} (@command{gnatmake}) |
| Put all object files and ALI file in directory @var{dir}. |
| If the @option{^-D^/DIRECTORY_OBJECTS^} switch is not used, all object files |
| and ALI files go in the current working directory. |
| |
| This switch cannot be used when using a project file. |
| |
| @ifclear vms |
| @item -eL |
| @cindex @option{-eL} (@command{gnatmake}) |
| Follow all symbolic links when processing project files. |
| @end ifclear |
| |
| @item ^-f^/FORCE_COMPILE^ |
| @cindex @option{^-f^/FORCE_COMPILE^} (@command{gnatmake}) |
| Force recompilations. Recompile all sources, even though some object |
| files may be up to date, but don't recompile predefined or GNAT internal |
| files or locked files (files with a write-protected ALI file), |
| unless the @option{^-a^/ALL_FILES^} switch is also specified. |
| |
| @item ^-F^/FULL_PATH_IN_BRIEF_MESSAGES^ |
| @cindex @option{^-F^/FULL_PATH_IN_BRIEF_MESSAGES^} (@command{gnatmake}) |
| When using project files, if some errors or warnings are detected during |
| parsing and verbose mode is not in effect (no use of switch |
| ^-v^/VERBOSE^), then error lines start with the full path name of the project |
| file, rather than its simple file name. |
| |
| @item ^-i^/IN_PLACE^ |
| @cindex @option{^-i^/IN_PLACE^} (@command{gnatmake}) |
| In normal mode, @command{gnatmake} compiles all object files and ALI files |
| into the current directory. If the @option{^-i^/IN_PLACE^} switch is used, |
| then instead object files and ALI files that already exist are overwritten |
| in place. This means that once a large project is organized into separate |
| directories in the desired manner, then @command{gnatmake} will automatically |
| maintain and update this organization. If no ALI files are found on the |
| Ada object path (@ref{Search Paths and the Run-Time Library (RTL)}), |
| the new object and ALI files are created in the |
| directory containing the source being compiled. If another organization |
| is desired, where objects and sources are kept in different directories, |
| a useful technique is to create dummy ALI files in the desired directories. |
| When detecting such a dummy file, @command{gnatmake} will be forced to |
| recompile the corresponding source file, and it will be put the resulting |
| object and ALI files in the directory where it found the dummy file. |
| |
| @item ^-j^/PROCESSES=^@var{n} |
| @cindex @option{^-j^/PROCESSES^} (@command{gnatmake}) |
| @cindex Parallel make |
| Use @var{n} processes to carry out the (re)compilations. On a |
| multiprocessor machine compilations will occur in parallel. In the |
| event of compilation errors, messages from various compilations might |
| get interspersed (but @command{gnatmake} will give you the full ordered |
| list of failing compiles at the end). If this is problematic, rerun |
| the make process with n set to 1 to get a clean list of messages. |
| |
| @item ^-k^/CONTINUE_ON_ERROR^ |
| @cindex @option{^-k^/CONTINUE_ON_ERROR^} (@command{gnatmake}) |
| Keep going. Continue as much as possible after a compilation error. To |
| ease the programmer's task in case of compilation errors, the list of |
| sources for which the compile fails is given when @command{gnatmake} |
| terminates. |
| |
| If @command{gnatmake} is invoked with several @file{file_names} and with this |
| switch, if there are compilation errors when building an executable, |
| @command{gnatmake} will not attempt to build the following executables. |
| |
| @item ^-l^/ACTIONS=LINK^ |
| @cindex @option{^-l^/ACTIONS=LINK^} (@command{gnatmake}) |
| Link only. Can be combined with @option{^-b^/ACTIONS=BIND^} to binding |
| and linking. Linking will not be performed if combined with |
| @option{^-c^/ACTIONS=COMPILE^} |
| but not with @option{^-b^/ACTIONS=BIND^}. |
| When not combined with @option{^-b^/ACTIONS=BIND^} |
| all the units in the closure of the main program must have been previously |
| compiled and must be up to date, and the main program needs to have been bound. |
| The root unit specified by @var{file_name} |
| may be given without extension, with the source extension or, if no GNAT |
| Project File is specified, with the ALI file extension. |
| |
| @item ^-m^/MINIMAL_RECOMPILATION^ |
| @cindex @option{^-m^/MINIMAL_RECOMPILATION^} (@command{gnatmake}) |
| Specify that the minimum necessary amount of recompilations |
| be performed. In this mode @command{gnatmake} ignores time |
| stamp differences when the only |
| modifications to a source file consist in adding/removing comments, |
| empty lines, spaces or tabs. This means that if you have changed the |
| comments in a source file or have simply reformatted it, using this |
| switch will tell gnatmake not to recompile files that depend on it |
| (provided other sources on which these files depend have undergone no |
| semantic modifications). Note that the debugging information may be |
| out of date with respect to the sources if the @option{-m} switch causes |
| a compilation to be switched, so the use of this switch represents a |
| trade-off between compilation time and accurate debugging information. |
| |
| @item ^-M^/DEPENDENCIES_LIST^ |
| @cindex Dependencies, producing list |
| @cindex @option{^-M^/DEPENDENCIES_LIST^} (@command{gnatmake}) |
| Check if all objects are up to date. If they are, output the object |
| dependences to @file{stdout} in a form that can be directly exploited in |
| a @file{Makefile}. By default, each source file is prefixed with its |
| (relative or absolute) directory name. This name is whatever you |
| specified in the various @option{^-aI^/SOURCE_SEARCH^} |
| and @option{^-I^/SEARCH^} switches. If you use |
| @code{gnatmake ^-M^/DEPENDENCIES_LIST^} |
| @option{^-q^/QUIET^} |
| (see below), only the source file names, |
| without relative paths, are output. If you just specify the |
| @option{^-M^/DEPENDENCIES_LIST^} |
| switch, dependencies of the GNAT internal system files are omitted. This |
| is typically what you want. If you also specify |
| the @option{^-a^/ALL_FILES^} switch, |
| dependencies of the GNAT internal files are also listed. Note that |
| dependencies of the objects in external Ada libraries (see switch |
| @option{^-aL^/SKIP_MISSING=^}@var{dir} in the following list) |
| are never reported. |
| |
| @item ^-n^/DO_OBJECT_CHECK^ |
| @cindex @option{^-n^/DO_OBJECT_CHECK^} (@command{gnatmake}) |
| Don't compile, bind, or link. Checks if all objects are up to date. |
| If they are not, the full name of the first file that needs to be |
| recompiled is printed. |
| Repeated use of this option, followed by compiling the indicated source |
| file, will eventually result in recompiling all required units. |
| |
| @item ^-o ^/EXECUTABLE=^@var{exec_name} |
| @cindex @option{^-o^/EXECUTABLE^} (@command{gnatmake}) |
| Output executable name. The name of the final executable program will be |
| @var{exec_name}. If the @option{^-o^/EXECUTABLE^} switch is omitted the default |
| name for the executable will be the name of the input file in appropriate form |
| for an executable file on the host system. |
| |
| This switch cannot be used when invoking @command{gnatmake} with several |
| @file{file_names}. |
| |
| @item ^-P^/PROJECT_FILE=^@var{project} |
| @cindex @option{^-P^/PROJECT_FILE^} (@command{gnatmake}) |
| Use project file @var{project}. Only one such switch can be used. |
| @xref{gnatmake and Project Files}. |
| |
| @item ^-q^/QUIET^ |
| @cindex @option{^-q^/QUIET^} (@command{gnatmake}) |
| Quiet. When this flag is not set, the commands carried out by |
| @command{gnatmake} are displayed. |
| |
| @item ^-s^/SWITCH_CHECK/^ |
| @cindex @option{^-s^/SWITCH_CHECK^} (@command{gnatmake}) |
| Recompile if compiler switches have changed since last compilation. |
| All compiler switches but -I and -o are taken into account in the |
| following way: |
| orders between different ``first letter'' switches are ignored, but |
| orders between same switches are taken into account. For example, |
| @option{-O -O2} is different than @option{-O2 -O}, but @option{-g -O} |
| is equivalent to @option{-O -g}. |
| |
| This switch is recommended when Integrated Preprocessing is used. |
| |
| @item ^-u^/UNIQUE^ |
| @cindex @option{^-u^/UNIQUE^} (@command{gnatmake}) |
| Unique. Recompile at most the main files. It implies -c. Combined with |
| -f, it is equivalent to calling the compiler directly. Note that using |
| ^-u^/UNIQUE^ with a project file and no main has a special meaning |
| (@pxref{Project Files and Main Subprograms}). |
| |
| @item ^-U^/ALL_PROJECTS^ |
| @cindex @option{^-U^/ALL_PROJECTS^} (@command{gnatmake}) |
| When used without a project file or with one or several mains on the command |
| line, is equivalent to ^-u^/UNIQUE^. When used with a project file and no main |
| on the command line, all sources of all project files are checked and compiled |
| if not up to date, and libraries are rebuilt, if necessary. |
| |
| @item ^-v^/REASONS^ |
| @cindex @option{^-v^/REASONS^} (@command{gnatmake}) |
| Verbose. Display the reason for all recompilations @command{gnatmake} |
| decides are necessary, with the highest verbosity level. |
| |
| @item ^-vl^/LOW_VERBOSITY^ |
| @cindex @option{^-vl^/LOW_VERBOSITY^} (@command{gnatmake}) |
| Verbosity level Low. Display fewer lines than in verbosity Medium. |
| |
| @item ^-vm^/MEDIUM_VERBOSITY^ |
| @cindex @option{^-vm^/MEDIUM_VERBOSITY^} (@command{gnatmake}) |
| Verbosity level Medium. Potentially display fewer lines than in verbosity High. |
| |
| @item ^-vh^/HIGH_VERBOSITY^ |
| @cindex @option{^-vm^/HIGH_VERBOSITY^} (@command{gnatmake}) |
| Verbosity level High. Equivalent to ^-v^/REASONS^. |
| |
| @item ^-vP^/MESSAGES_PROJECT_FILE=^@emph{x} |
| Indicate the verbosity of the parsing of GNAT project files. |
| @xref{Switches Related to Project Files}. |
| |
| @item ^-x^/NON_PROJECT_UNIT_COMPILATION^ |
| @cindex @option{^-x^/NON_PROJECT_UNIT_COMPILATION^} (@command{gnatmake}) |
| Indicate that sources that are not part of any Project File may be compiled. |
| Normally, when using Project Files, only sources that are part of a Project |
| File may be compile. When this switch is used, a source outside of all Project |
| Files may be compiled. The ALI file and the object file will be put in the |
| object directory of the main Project. The compilation switches used will only |
| be those specified on the command line. |
| |
| @item ^-X^/EXTERNAL_REFERENCE=^@var{name=value} |
| Indicate that external variable @var{name} has the value @var{value}. |
| The Project Manager will use this value for occurrences of |
| @code{external(name)} when parsing the project file. |
| @xref{Switches Related to Project Files}. |
| |
| @item ^-z^/NOMAIN^ |
| @cindex @option{^-z^/NOMAIN^} (@command{gnatmake}) |
| No main subprogram. Bind and link the program even if the unit name |
| given on the command line is a package name. The resulting executable |
| will execute the elaboration routines of the package and its closure, |
| then the finalization routines. |
| |
| @item ^-g^/DEBUG^ |
| @cindex @option{^-g^/DEBUG^} (@command{gnatmake}) |
| Enable debugging. This switch is simply passed to the compiler and to the |
| linker. |
| |
| @end table |
| |
| @table @asis |
| @item @command{gcc} @asis{switches} |
| @ifclear vms |
| Any uppercase or multi-character switch that is not a @command{gnatmake} switch |
| is passed to @command{gcc} (e.g. @option{-O}, @option{-gnato,} etc.) |
| @end ifclear |
| @ifset vms |
| Any qualifier that cannot be recognized as a qualifier for @code{GNAT MAKE} |
| but is recognizable as a valid qualifier for @code{GNAT COMPILE} is |
| automatically treated as a compiler switch, and passed on to all |
| compilations that are carried out. |
| @end ifset |
| @end table |
| |
| @noindent |
| Source and library search path switches: |
| |
| @table @option |
| @c !sort! |
| @item ^-aI^/SOURCE_SEARCH=^@var{dir} |
| @cindex @option{^-aI^/SOURCE_SEARCH^} (@command{gnatmake}) |
| When looking for source files also look in directory @var{dir}. |
| The order in which source files search is undertaken is |
| described in @ref{Search Paths and the Run-Time Library (RTL)}. |
| |
| @item ^-aL^/SKIP_MISSING=^@var{dir} |
| @cindex @option{^-aL^/SKIP_MISSING^} (@command{gnatmake}) |
| Consider @var{dir} as being an externally provided Ada library. |
| Instructs @command{gnatmake} to skip compilation units whose @file{.ALI} |
| files have been located in directory @var{dir}. This allows you to have |
| missing bodies for the units in @var{dir} and to ignore out of date bodies |
| for the same units. You still need to specify |
| the location of the specs for these units by using the switches |
| @option{^-aI^/SOURCE_SEARCH=^@var{dir}} |
| or @option{^-I^/SEARCH=^@var{dir}}. |
| Note: this switch is provided for compatibility with previous versions |
| of @command{gnatmake}. The easier method of causing standard libraries |
| to be excluded from consideration is to write-protect the corresponding |
| ALI files. |
| |
| @item ^-aO^/OBJECT_SEARCH=^@var{dir} |
| @cindex @option{^-aO^/OBJECT_SEARCH^} (@command{gnatmake}) |
| When searching for library and object files, look in directory |
| @var{dir}. The order in which library files are searched is described in |
| @ref{Search Paths for gnatbind}. |
| |
| @item ^-A^/CONDITIONAL_SOURCE_SEARCH=^@var{dir} |
| @cindex Search paths, for @command{gnatmake} |
| @cindex @option{^-A^/CONDITIONAL_SOURCE_SEARCH^} (@command{gnatmake}) |
| Equivalent to @option{^-aL^/SKIP_MISSING=^@var{dir} |
| ^-aI^/SOURCE_SEARCH=^@var{dir}}. |
| |
| @item ^-I^/SEARCH=^@var{dir} |
| @cindex @option{^-I^/SEARCH^} (@command{gnatmake}) |
| Equivalent to @option{^-aO^/OBJECT_SEARCH=^@var{dir} |
| ^-aI^/SOURCE_SEARCH=^@var{dir}}. |
| |
| @item ^-I-^/NOCURRENT_DIRECTORY^ |
| @cindex @option{^-I-^/NOCURRENT_DIRECTORY^} (@command{gnatmake}) |
| @cindex Source files, suppressing search |
| Do not look for source files in the directory containing the source |
| file named in the command line. |
| Do not look for ALI or object files in the directory |
| where @command{gnatmake} was invoked. |
| |
| @item ^-L^/LIBRARY_SEARCH=^@var{dir} |
| @cindex @option{^-L^/LIBRARY_SEARCH^} (@command{gnatmake}) |
| @cindex Linker libraries |
| Add directory @var{dir} to the list of directories in which the linker |
| will search for libraries. This is equivalent to |
| @option{-largs ^-L^/LIBRARY_SEARCH=^}@var{dir}. |
| @ifclear vms |
| Furthermore, under Windows, the sources pointed to by the libraries path |
| set in the registry are not searched for. |
| @end ifclear |
| |
| @item -nostdinc |
| @cindex @option{-nostdinc} (@command{gnatmake}) |
| Do not look for source files in the system default directory. |
| |
| @item -nostdlib |
| @cindex @option{-nostdlib} (@command{gnatmake}) |
| Do not look for library files in the system default directory. |
| |
| @item --RTS=@var{rts-path} |
| @cindex @option{--RTS} (@command{gnatmake}) |
| Specifies the default location of the runtime library. GNAT looks for the |
| runtime |
| in the following directories, and stops as soon as a valid runtime is found |
| (@file{adainclude} or @file{ada_source_path}, and @file{adalib} or |
| @file{ada_object_path} present): |
| |
| @itemize @bullet |
| @item <current directory>/$rts_path |
| |
| @item <default-search-dir>/$rts_path |
| |
| @item <default-search-dir>/rts-$rts_path |
| @end itemize |
| |
| @noindent |
| The selected path is handled like a normal RTS path. |
| |
| @end table |
| |
| @node Mode Switches for gnatmake |
| @section Mode Switches for @command{gnatmake} |
| |
| @noindent |
| The mode switches (referred to as @code{mode_switches}) allow the |
| inclusion of switches that are to be passed to the compiler itself, the |
| binder or the linker. The effect of a mode switch is to cause all |
| subsequent switches up to the end of the switch list, or up to the next |
| mode switch, to be interpreted as switches to be passed on to the |
| designated component of GNAT. |
| |
| @table @option |
| @c !sort! |
| @item -cargs @var{switches} |
| @cindex @option{-cargs} (@command{gnatmake}) |
| Compiler switches. Here @var{switches} is a list of switches |
| that are valid switches for @command{gcc}. They will be passed on to |
| all compile steps performed by @command{gnatmake}. |
| |
| @item -bargs @var{switches} |
| @cindex @option{-bargs} (@command{gnatmake}) |
| Binder switches. Here @var{switches} is a list of switches |
| that are valid switches for @code{gnatbind}. They will be passed on to |
| all bind steps performed by @command{gnatmake}. |
| |
| @item -largs @var{switches} |
| @cindex @option{-largs} (@command{gnatmake}) |
| Linker switches. Here @var{switches} is a list of switches |
| that are valid switches for @command{gnatlink}. They will be passed on to |
| all link steps performed by @command{gnatmake}. |
| |
| @item -margs @var{switches} |
| @cindex @option{-margs} (@command{gnatmake}) |
| Make switches. The switches are directly interpreted by @command{gnatmake}, |
| regardless of any previous occurrence of @option{-cargs}, @option{-bargs} |
| or @option{-largs}. |
| @end table |
| |
| @node Notes on the Command Line |
| @section Notes on the Command Line |
| |
| @noindent |
| This section contains some additional useful notes on the operation |
| of the @command{gnatmake} command. |
| |
| @itemize @bullet |
| @item |
| @cindex Recompilation, by @command{gnatmake} |
| If @command{gnatmake} finds no ALI files, it recompiles the main program |
| and all other units required by the main program. |
| This means that @command{gnatmake} |
| can be used for the initial compile, as well as during subsequent steps of |
| the development cycle. |
| |
| @item |
| If you enter @code{gnatmake @var{file}.adb}, where @file{@var{file}.adb} |
| is a subunit or body of a generic unit, @command{gnatmake} recompiles |
| @file{@var{file}.adb} (because it finds no ALI) and stops, issuing a |
| warning. |
| |
| @item |
| In @command{gnatmake} the switch @option{^-I^/SEARCH^} |
| is used to specify both source and |
| library file paths. Use @option{^-aI^/SOURCE_SEARCH^} |
| instead if you just want to specify |
| source paths only and @option{^-aO^/OBJECT_SEARCH^} |
| if you want to specify library paths |
| only. |
| |
| @item |
| @command{gnatmake} will ignore any files whose ALI file is write-protected. |
| This may conveniently be used to exclude standard libraries from |
| consideration and in particular it means that the use of the |
| @option{^-f^/FORCE_COMPILE^} switch will not recompile these files |
| unless @option{^-a^/ALL_FILES^} is also specified. |
| |
| @item |
| @command{gnatmake} has been designed to make the use of Ada libraries |
| particularly convenient. Assume you have an Ada library organized |
| as follows: @i{^obj-dir^[OBJ_DIR]^} contains the objects and ALI files for |
| of your Ada compilation units, |
| whereas @i{^include-dir^[INCLUDE_DIR]^} contains the |
| specs of these units, but no bodies. Then to compile a unit |
| stored in @code{main.adb}, which uses this Ada library you would just type |
| |
| @smallexample |
| @ifclear vms |
| $ gnatmake -aI@var{include-dir} -aL@var{obj-dir} main |
| @end ifclear |
| @ifset vms |
| $ gnatmake /SOURCE_SEARCH=@i{[INCLUDE_DIR]} |
| /SKIP_MISSING=@i{[OBJ_DIR]} main |
| @end ifset |
| @end smallexample |
| |
| @item |
| Using @command{gnatmake} along with the |
| @option{^-m (minimal recompilation)^/MINIMAL_RECOMPILATION^} |
| switch provides a mechanism for avoiding unnecessary rcompilations. Using |
| this switch, |
| you can update the comments/format of your |
| source files without having to recompile everything. Note, however, that |
| adding or deleting lines in a source files may render its debugging |
| info obsolete. If the file in question is a spec, the impact is rather |
| limited, as that debugging info will only be useful during the |
| elaboration phase of your program. For bodies the impact can be more |
| significant. In all events, your debugger will warn you if a source file |
| is more recent than the corresponding object, and alert you to the fact |
| that the debugging information may be out of date. |
| @end itemize |
| |
| @node How gnatmake Works |
| @section How @command{gnatmake} Works |
| |
| @noindent |
| Generally @command{gnatmake} automatically performs all necessary |
| recompilations and you don't need to worry about how it works. However, |
| it may be useful to have some basic understanding of the @command{gnatmake} |
| approach and in particular to understand how it uses the results of |
| previous compilations without incorrectly depending on them. |
| |
| First a definition: an object file is considered @dfn{up to date} if the |
| corresponding ALI file exists and if all the source files listed in the |
| dependency section of this ALI file have time stamps matching those in |
| the ALI file. This means that neither the source file itself nor any |
| files that it depends on have been modified, and hence there is no need |
| to recompile this file. |
| |
| @command{gnatmake} works by first checking if the specified main unit is up |
| to date. If so, no compilations are required for the main unit. If not, |
| @command{gnatmake} compiles the main program to build a new ALI file that |
| reflects the latest sources. Then the ALI file of the main unit is |
| examined to find all the source files on which the main program depends, |
| and @command{gnatmake} recursively applies the above procedure on all these |
| files. |
| |
| This process ensures that @command{gnatmake} only trusts the dependencies |
| in an existing ALI file if they are known to be correct. Otherwise it |
| always recompiles to determine a new, guaranteed accurate set of |
| dependencies. As a result the program is compiled ``upside down'' from what may |
| be more familiar as the required order of compilation in some other Ada |
| systems. In particular, clients are compiled before the units on which |
| they depend. The ability of GNAT to compile in any order is critical in |
| allowing an order of compilation to be chosen that guarantees that |
| @command{gnatmake} will recompute a correct set of new dependencies if |
| necessary. |
| |
| When invoking @command{gnatmake} with several @var{file_names}, if a unit is |
| imported by several of the executables, it will be recompiled at most once. |
| |
| Note: when using non-standard naming conventions |
| (@pxref{Using Other File Names}), changing through a configuration pragmas |
| file the version of a source and invoking @command{gnatmake} to recompile may |
| have no effect, if the previous version of the source is still accessible |
| by @command{gnatmake}. It may be necessary to use the switch |
| ^-f^/FORCE_COMPILE^. |
| |
| @node Examples of gnatmake Usage |
| @section Examples of @command{gnatmake} Usage |
| |
| @table @code |
| @item gnatmake hello.adb |
| Compile all files necessary to bind and link the main program |
| @file{hello.adb} (containing unit @code{Hello}) and bind and link the |
| resulting object files to generate an executable file @file{^hello^HELLO.EXE^}. |
| |
| @item gnatmake main1 main2 main3 |
| Compile all files necessary to bind and link the main programs |
| @file{main1.adb} (containing unit @code{Main1}), @file{main2.adb} |
| (containing unit @code{Main2}) and @file{main3.adb} |
| (containing unit @code{Main3}) and bind and link the resulting object files |
| to generate three executable files @file{^main1^MAIN1.EXE^}, |
| @file{^main2^MAIN2.EXE^} |
| and @file{^main3^MAIN3.EXE^}. |
| |
| @ifclear vms |
| @item gnatmake -q Main_Unit -cargs -O2 -bargs -l |
| @end ifclear |
| |
| @ifset vms |
| @item gnatmake Main_Unit /QUIET |
| /COMPILER_QUALIFIERS /OPTIMIZE=ALL |
| /BINDER_QUALIFIERS /ORDER_OF_ELABORATION |
| @end ifset |
| Compile all files necessary to bind and link the main program unit |
| @code{Main_Unit} (from file @file{main_unit.adb}). All compilations will |
| be done with optimization level 2 and the order of elaboration will be |
| listed by the binder. @command{gnatmake} will operate in quiet mode, not |
| displaying commands it is executing. |
| @end table |
| |
| @c ************************* |
| @node Improving Performance |
| @chapter Improving Performance |
| @cindex Improving performance |
| |
| @noindent |
| This chapter presents several topics related to program performance. |
| It first describes some of the tradeoffs that need to be considered |
| and some of the techniques for making your program run faster. |
| It then documents the @command{gnatelim} tool and unused subprogram/data |
| elimination feature, which can reduce the size of program executables. |
| |
| @ifnottex |
| @menu |
| * Performance Considerations:: |
| * Reducing the Size of Ada Executables with gnatelim:: |
| * Reducing the Size of Executables with unused subprogram/data elimination:: |
| @end menu |
| @end ifnottex |
| |
| @c ***************************** |
| @node Performance Considerations |
| @section Performance Considerations |
| |
| @noindent |
| The GNAT system provides a number of options that allow a trade-off |
| between |
| |
| @itemize @bullet |
| @item |
| performance of the generated code |
| |
| @item |
| speed of compilation |
| |
| @item |
| minimization of dependences and recompilation |
| |
| @item |
| the degree of run-time checking. |
| @end itemize |
| |
| @noindent |
| The defaults (if no options are selected) aim at improving the speed |
| of compilation and minimizing dependences, at the expense of performance |
| of the generated code: |
| |
| @itemize @bullet |
| @item |
| no optimization |
| |
| @item |
| no inlining of subprogram calls |
| |
| @item |
| all run-time checks enabled except overflow and elaboration checks |
| @end itemize |
| |
| @noindent |
| These options are suitable for most program development purposes. This |
| chapter describes how you can modify these choices, and also provides |
| some guidelines on debugging optimized code. |
| |
| @menu |
| * Controlling Run-Time Checks:: |
| * Use of Restrictions:: |
| * Optimization Levels:: |
| * Debugging Optimized Code:: |
| * Inlining of Subprograms:: |
| * Other Optimization Switches:: |
| * Optimization and Strict Aliasing:: |
| |
| @ifset vms |
| * Coverage Analysis:: |
| @end ifset |
| @end menu |
| |
| @node Controlling Run-Time Checks |
| @subsection Controlling Run-Time Checks |
| |
| @noindent |
| By default, GNAT generates all run-time checks, except arithmetic overflow |
| checking for integer operations and checks for access before elaboration on |
| subprogram calls. The latter are not required in default mode, because all |
| necessary checking is done at compile time. |
| @cindex @option{-gnatp} (@command{gcc}) |
| @cindex @option{-gnato} (@command{gcc}) |
| Two gnat switches, @option{-gnatp} and @option{-gnato} allow this default to |
| be modified. @xref{Run-Time Checks}. |
| |
| Our experience is that the default is suitable for most development |
| purposes. |
| |
| We treat integer overflow specially because these |
| are quite expensive and in our experience are not as important as other |
| run-time checks in the development process. Note that division by zero |
| is not considered an overflow check, and divide by zero checks are |
| generated where required by default. |
| |
| Elaboration checks are off by default, and also not needed by default, since |
| GNAT uses a static elaboration analysis approach that avoids the need for |
| run-time checking. This manual contains a full chapter discussing the issue |
| of elaboration checks, and if the default is not satisfactory for your use, |
| you should read this chapter. |
| |
| For validity checks, the minimal checks required by the Ada Reference |
| Manual (for case statements and assignments to array elements) are on |
| by default. These can be suppressed by use of the @option{-gnatVn} switch. |
| Note that in Ada 83, there were no validity checks, so if the Ada 83 mode |
| is acceptable (or when comparing GNAT performance with an Ada 83 compiler), |
| it may be reasonable to routinely use @option{-gnatVn}. Validity checks |
| are also suppressed entirely if @option{-gnatp} is used. |
| |
| @cindex Overflow checks |
| @cindex Checks, overflow |
| @findex Suppress |
| @findex Unsuppress |
| @cindex pragma Suppress |
| @cindex pragma Unsuppress |
| Note that the setting of the switches controls the default setting of |
| the checks. They may be modified using either @code{pragma Suppress} (to |
| remove checks) or @code{pragma Unsuppress} (to add back suppressed |
| checks) in the program source. |
| |
| @node Use of Restrictions |
| @subsection Use of Restrictions |
| |
| @noindent |
| The use of pragma Restrictions allows you to control which features are |
| permitted in your program. Apart from the obvious point that if you avoid |
| relatively expensive features like finalization (enforceable by the use |
| of pragma Restrictions (No_Finalization), the use of this pragma does not |
| affect the generated code in most cases. |
| |
| One notable exception to this rule is that the possibility of task abort |
| results in some distributed overhead, particularly if finalization or |
| exception handlers are used. The reason is that certain sections of code |
| have to be marked as non-abortable. |
| |
| If you use neither the @code{abort} statement, nor asynchronous transfer |
| of control (@code{select .. then abort}), then this distributed overhead |
| is removed, which may have a general positive effect in improving |
| overall performance. Especially code involving frequent use of tasking |
| constructs and controlled types will show much improved performance. |
| The relevant restrictions pragmas are |
| |
| @smallexample @c ada |
| pragma Restrictions (No_Abort_Statements); |
| pragma Restrictions (Max_Asynchronous_Select_Nesting => 0); |
| @end smallexample |
| |
| @noindent |
| It is recommended that these restriction pragmas be used if possible. Note |
| that this also means that you can write code without worrying about the |
| possibility of an immediate abort at any point. |
| |
| @node Optimization Levels |
| @subsection Optimization Levels |
| @cindex @option{^-O^/OPTIMIZE^} (@command{gcc}) |
| |
| @noindent |
| The default is optimization off. This results in the fastest compile |
| times, but GNAT makes absolutely no attempt to optimize, and the |
| generated programs are considerably larger and slower than when |
| optimization is enabled. You can use the |
| @ifclear vms |
| @option{-O@var{n}} switch, where @var{n} is an integer from 0 to 3, |
| @end ifclear |
| @ifset vms |
| @code{OPTIMIZE} qualifier |
| @end ifset |
| to @command{gcc} to control the optimization level: |
| |
| @table @option |
| @item ^-O0^/OPTIMIZE=NONE^ |
| No optimization (the default); |
| generates unoptimized code but has |
| the fastest compilation time. |
| |
| Note that many other compilers do fairly extensive optimization |
| even if "no optimization" is specified. When using gcc, it is |
| very unusual to use ^-O0^/OPTIMIZE=NONE^ for production if |
| execution time is of any concern, since ^-O0^/OPTIMIZE=NONE^ |
| really does mean no optimization at all. This difference between |
| gcc and other compilers should be kept in mind when doing |
| performance comparisons. |
| |
| @item ^-O1^/OPTIMIZE=SOME^ |
| Moderate optimization; |
| optimizes reasonably well but does not |
| degrade compilation time significantly. |
| |
| @item ^-O2^/OPTIMIZE=ALL^ |
| @ifset vms |
| @itemx /OPTIMIZE=DEVELOPMENT |
| @end ifset |
| Full optimization; |
| generates highly optimized code and has |
| the slowest compilation time. |
| |
| @item ^-O3^/OPTIMIZE=INLINING^ |
| Full optimization as in @option{-O2}, |
| and also attempts automatic inlining of small |
| subprograms within a unit (@pxref{Inlining of Subprograms}). |
| @end table |
| |
| @noindent |
| Higher optimization levels perform more global transformations on the |
| program and apply more expensive analysis algorithms in order to generate |
| faster and more compact code. The price in compilation time, and the |
| resulting improvement in execution time, |
| both depend on the particular application and the hardware environment. |
| You should experiment to find the best level for your application. |
| |
| Since the precise set of optimizations done at each level will vary from |
| release to release (and sometime from target to target), it is best to think |
| of the optimization settings in general terms. |
| The @cite{Using GNU GCC} manual contains details about |
| ^the @option{-O} settings and a number of @option{-f} options that^how to^ |
| individually enable or disable specific optimizations. |
| |
| Unlike some other compilation systems, ^@command{gcc}^GNAT^ has |
| been tested extensively at all optimization levels. There are some bugs |
| which appear only with optimization turned on, but there have also been |
| bugs which show up only in @emph{unoptimized} code. Selecting a lower |
| level of optimization does not improve the reliability of the code |
| generator, which in practice is highly reliable at all optimization |
| levels. |
| |
| Note regarding the use of @option{-O3}: The use of this optimization level |
| is generally discouraged with GNAT, since it often results in larger |
| executables which run more slowly. See further discussion of this point |
| in @ref{Inlining of Subprograms}. |
| |
| @node Debugging Optimized Code |
| @subsection Debugging Optimized Code |
| @cindex Debugging optimized code |
| @cindex Optimization and debugging |
| |
| @noindent |
| Although it is possible to do a reasonable amount of debugging at |
| @ifclear vms |
| nonzero optimization levels, |
| the higher the level the more likely that |
| @end ifclear |
| @ifset vms |
| @option{/OPTIMIZE} settings other than @code{NONE}, |
| such settings will make it more likely that |
| @end ifset |
| source-level constructs will have been eliminated by optimization. |
| For example, if a loop is strength-reduced, the loop |
| control variable may be completely eliminated and thus cannot be |
| displayed in the debugger. |
| This can only happen at @option{-O2} or @option{-O3}. |
| Explicit temporary variables that you code might be eliminated at |
| ^level^setting^ @option{-O1} or higher. |
| |
| The use of the @option{^-g^/DEBUG^} switch, |
| @cindex @option{^-g^/DEBUG^} (@command{gcc}) |
| which is needed for source-level debugging, |
| affects the size of the program executable on disk, |
| and indeed the debugging information can be quite large. |
| However, it has no effect on the generated code (and thus does not |
| degrade performance) |
| |
| Since the compiler generates debugging tables for a compilation unit before |
| it performs optimizations, the optimizing transformations may invalidate some |
| of the debugging data. You therefore need to anticipate certain |
| anomalous situations that may arise while debugging optimized code. |
| These are the most common cases: |
| |
| @enumerate |
| @item |
| @i{The ``hopping Program Counter'':} Repeated @code{step} or @code{next} |
| commands show |
| the PC bouncing back and forth in the code. This may result from any of |
| the following optimizations: |
| |
| @itemize @bullet |
| @item |
| @i{Common subexpression elimination:} using a single instance of code for a |
| quantity that the source computes several times. As a result you |
| may not be able to stop on what looks like a statement. |
| |
| @item |
| @i{Invariant code motion:} moving an expression that does not change within a |
| loop, to the beginning of the loop. |
| |
| @item |
| @i{Instruction scheduling:} moving instructions so as to |
| overlap loads and stores (typically) with other code, or in |
| general to move computations of values closer to their uses. Often |
| this causes you to pass an assignment statement without the assignment |
| happening and then later bounce back to the statement when the |
| value is actually needed. Placing a breakpoint on a line of code |
| and then stepping over it may, therefore, not always cause all the |
| expected side-effects. |
| @end itemize |
| |
| @item |
| @i{The ``big leap'':} More commonly known as @emph{cross-jumping}, in which |
| two identical pieces of code are merged and the program counter suddenly |
| jumps to a statement that is not supposed to be executed, simply because |
| it (and the code following) translates to the same thing as the code |
| that @emph{was} supposed to be executed. This effect is typically seen in |
| sequences that end in a jump, such as a @code{goto}, a @code{return}, or |
| a @code{break} in a C @code{^switch^switch^} statement. |
| |
| @item |
| @i{The ``roving variable'':} The symptom is an unexpected value in a variable. |
| There are various reasons for this effect: |
| |
| @itemize @bullet |
| @item |
| In a subprogram prologue, a parameter may not yet have been moved to its |
| ``home''. |
| |
| @item |
| A variable may be dead, and its register re-used. This is |
| probably the most common cause. |
| |
| @item |
| As mentioned above, the assignment of a value to a variable may |
| have been moved. |
| |
| @item |
| A variable may be eliminated entirely by value propagation or |
| other means. In this case, GCC may incorrectly generate debugging |
| information for the variable |
| @end itemize |
| |
| @noindent |
| In general, when an unexpected value appears for a local variable or parameter |
| you should first ascertain if that value was actually computed by |
| your program, as opposed to being incorrectly reported by the debugger. |
| Record fields or |
| array elements in an object designated by an access value |
| are generally less of a problem, once you have ascertained that the access |
| value is sensible. |
| Typically, this means checking variables in the preceding code and in the |
| calling subprogram to verify that the value observed is explainable from other |
| values (one must apply the procedure recursively to those |
| other values); or re-running the code and stopping a little earlier |
| (perhaps before the call) and stepping to better see how the variable obtained |
| the value in question; or continuing to step @emph{from} the point of the |
| strange value to see if code motion had simply moved the variable's |
| assignments later. |
| @end enumerate |
| |
| @noindent |
| In light of such anomalies, a recommended technique is to use @option{-O0} |
| early in the software development cycle, when extensive debugging capabilities |
| are most needed, and then move to @option{-O1} and later @option{-O2} as |
| the debugger becomes less critical. |
| Whether to use the @option{^-g^/DEBUG^} switch in the release version is |
| a release management issue. |
| @ifclear vms |
| Note that if you use @option{-g} you can then use the @command{strip} program |
| on the resulting executable, |
| which removes both debugging information and global symbols. |
| @end ifclear |
| |
| @node Inlining of Subprograms |
| @subsection Inlining of Subprograms |
| |
| @noindent |
| A call to a subprogram in the current unit is inlined if all the |
| following conditions are met: |
| |
| @itemize @bullet |
| @item |
| The optimization level is at least @option{-O1}. |
| |
| @item |
| The called subprogram is suitable for inlining: It must be small enough |
| and not contain nested subprograms or anything else that @command{gcc} |
| cannot support in inlined subprograms. |
| |
| @item |
| The call occurs after the definition of the body of the subprogram. |
| |
| @item |
| @cindex pragma Inline |
| @findex Inline |
| Either @code{pragma Inline} applies to the subprogram or it is |
| small and automatic inlining (optimization level @option{-O3}) is |
| specified. |
| @end itemize |
| |
| @noindent |
| Calls to subprograms in @code{with}'ed units are normally not inlined. |
| To achieve this level of inlining, the following conditions must all be |
| true: |
| |
| @itemize @bullet |
| @item |
| The optimization level is at least @option{-O1}. |
| |
| @item |
| The called subprogram is suitable for inlining: It must be small enough |
| and not contain nested subprograms or anything else @command{gcc} cannot |
| support in inlined subprograms. |
| |
| @item |
| The call appears in a body (not in a package spec). |
| |
| @item |
| There is a @code{pragma Inline} for the subprogram. |
| |
| @item |
| @cindex @option{-gnatn} (@command{gcc}) |
| The @option{^-gnatn^/INLINE^} switch |
| is used in the @command{gcc} command line |
| @end itemize |
| |
| Note that specifying the @option{-gnatn} switch causes additional |
| compilation dependencies. Consider the following: |
| |
| @smallexample @c ada |
| @cartouche |
| package R is |
| procedure Q; |
| pragma Inline (Q); |
| end R; |
| package body R is |
| ... |
| end R; |
| |
| with R; |
| procedure Main is |
| begin |
| ... |
| R.Q; |
| end Main; |
| @end cartouche |
| @end smallexample |
| |
| @noindent |
| With the default behavior (no @option{-gnatn} switch specified), the |
| compilation of the @code{Main} procedure depends only on its own source, |
| @file{main.adb}, and the spec of the package in file @file{r.ads}. This |
| means that editing the body of @code{R} does not require recompiling |
| @code{Main}. |
| |
| On the other hand, the call @code{R.Q} is not inlined under these |
| circumstances. If the @option{-gnatn} switch is present when @code{Main} |
| is compiled, the call will be inlined if the body of @code{Q} is small |
| enough, but now @code{Main} depends on the body of @code{R} in |
| @file{r.adb} as well as on the spec. This means that if this body is edited, |
| the main program must be recompiled. Note that this extra dependency |
| occurs whether or not the call is in fact inlined by @command{gcc}. |
| |
| The use of front end inlining with @option{-gnatN} generates similar |
| additional dependencies. |
| |
| @cindex @option{^-fno-inline^/INLINE=SUPPRESS^} (@command{gcc}) |
| Note: The @option{^-fno-inline^/INLINE=SUPPRESS^} switch |
| can be used to prevent |
| all inlining. This switch overrides all other conditions and ensures |
| that no inlining occurs. The extra dependences resulting from |
| @option{-gnatn} will still be active, even if |
| this switch is used to suppress the resulting inlining actions. |
| |
| Note regarding the use of @option{-O3}: There is no difference in inlining |
| behavior between @option{-O2} and @option{-O3} for subprograms with an explicit |
| pragma @code{Inline} assuming the use of @option{-gnatn} |
| or @option{-gnatN} (the switches that activate inlining). If you have used |
| pragma @code{Inline} in appropriate cases, then it is usually much better |
| to use @option{-O2} and @option{-gnatn} and avoid the use of @option{-O3} which |
| in this case only has the effect of inlining subprograms you did not |
| think should be inlined. We often find that the use of @option{-O3} slows |
| down code by performing excessive inlining, leading to increased instruction |
| cache pressure from the increased code size. So the bottom line here is |
| that you should not automatically assume that @option{-O3} is better than |
| @option{-O2}, and indeed you should use @option{-O3} only if tests show that |
| it actually improves performance. |
| |
| @node Other Optimization Switches |
| @subsection Other Optimization Switches |
| @cindex Optimization Switches |
| |
| Since @code{GNAT} uses the @code{gcc} back end, all the specialized |
| @code{gcc} optimization switches are potentially usable. These switches |
| have not been extensively tested with GNAT but can generally be expected |
| to work. Examples of switches in this category are |
| @option{-funroll-loops} and |
| the various target-specific @option{-m} options (in particular, it has been |
| observed that @option{-march=pentium4} can significantly improve performance |
| on appropriate machines). For full details of these switches, see the |
| @code{gcc} manual. |
| |
| @node Optimization and Strict Aliasing |
| @subsection Optimization and Strict Aliasing |
| @cindex Aliasing |
| @cindex Strict Aliasing |
| @cindex No_Strict_Aliasing |
| |
| @noindent |
| The strong typing capabilities of Ada allow an optimizer to generate |
| efficient code in situations where other languages would be forced to |
| make worst case assumptions preventing such optimizations. Consider |
| the following example: |
| |
| @smallexample @c ada |
| @cartouche |
| procedure R is |
| type Int1 is new Integer; |
| type Int2 is new Integer; |
| type Int1A is access Int1; |
| type Int2A is access Int2; |
| Int1V : Int1A; |
| Int2V : Int2A; |
| ... |
| |
| begin |
| ... |
| for J in Data'Range loop |
| if Data (J) = Int1V.all then |
| Int2V.all := Int2V.all + 1; |
| end if; |
| end loop; |
| ... |
| end R; |
| @end cartouche |
| @end smallexample |
| |
| @noindent |
| In this example, since the variable @code{Int1V} can only access objects |
| of type @code{Int1}, and @code{Int2V} can only access objects of type |
| @code{Int2}, there is no possibility that the assignment to |
| @code{Int2V.all} affects the value of @code{Int1V.all}. This means that |
| the compiler optimizer can "know" that the value @code{Int1V.all} is constant |
| for all iterations of the loop and avoid the extra memory reference |
| required to dereference it each time through the loop. |
| |
| This kind of optimization, called strict aliasing analysis, is |
| triggered by specifying an optimization level of @option{-O2} or |
| higher and allows @code{GNAT} to generate more efficient code |
| when access values are involved. |
| |
| However, although this optimization is always correct in terms of |
| the formal semantics of the Ada Reference Manual, difficulties can |
| arise if features like @code{Unchecked_Conversion} are used to break |
| the typing system. Consider the following complete program example: |
| |
| @smallexample @c ada |
| @cartouche |
| package p1 is |
| type int1 is new integer; |
| type int2 is new integer; |
| type a1 is access int1; |
| type a2 is access int2; |
| end p1; |
| |
| with p1; use p1; |
| package p2 is |
| function to_a2 (Input : a1) return a2; |
| end p2; |
| |
| with Unchecked_Conversion; |
| package body p2 is |
| function to_a2 (Input : a1) return a2 is |
| function to_a2u is |
| new Unchecked_Conversion (a1, a2); |
| begin |
| return to_a2u (Input); |
| end to_a2; |
| end p2; |
| |
| with p2; use p2; |
| with p1; use p1; |
| with Text_IO; use Text_IO; |
| procedure m is |
| v1 : a1 := new int1; |
| v2 : a2 := to_a2 (v1); |
| begin |
| v1.all := 1; |
| v2.all := 0; |
| put_line (int1'image (v1.all)); |
| end; |
| @end cartouche |
| @end smallexample |
| |
| @noindent |
| This program prints out 0 in @code{-O0} or @code{-O1} |
| mode, but it prints out 1 in @code{-O2} mode. That's |
| because in strict aliasing mode, the compiler can and |
| does assume that the assignment to @code{v2.all} could not |
| affect the value of @code{v1.all}, since different types |
| are involved. |
| |
| This behavior is not a case of non-conformance with the standard, since |
| the Ada RM specifies that an unchecked conversion where the resulting |
| bit pattern is not a correct value of the target type can result in an |
| abnormal value and attempting to reference an abnormal value makes the |
| execution of a program erroneous. That's the case here since the result |
| does not point to an object of type @code{int2}. This means that the |
| effect is entirely unpredictable. |
| |
| However, although that explanation may satisfy a language |
| lawyer, in practice an applications programmer expects an |
| unchecked conversion involving pointers to create true |
| aliases and the behavior of printing 1 seems plain wrong. |
| In this case, the strict aliasing optimization is unwelcome. |
| |
| Indeed the compiler recognizes this possibility, and the |
| unchecked conversion generates a warning: |
| |
| @smallexample |
| p2.adb:5:07: warning: possible aliasing problem with type "a2" |
| p2.adb:5:07: warning: use -fno-strict-aliasing switch for references |
| p2.adb:5:07: warning: or use "pragma No_Strict_Aliasing (a2);" |
| @end smallexample |
| |
| @noindent |
| Unfortunately the problem is recognized when compiling the body of |
| package @code{p2}, but the actual "bad" code is generated while |
| compiling the body of @code{m} and this latter compilation does not see |
| the suspicious @code{Unchecked_Conversion}. |
| |
| As implied by the warning message, there are approaches you can use to |
| avoid the unwanted strict aliasing optimization in a case like this. |
| |
| One possibility is to simply avoid the use of @code{-O2}, but |
| that is a bit drastic, since it throws away a number of useful |
| optimizations that do not involve strict aliasing assumptions. |
| |
| A less drastic approach is to compile the program using the |
| option @code{-fno-strict-aliasing}. Actually it is only the |
| unit containing the dereferencing of the suspicious pointer |
| that needs to be compiled. So in this case, if we compile |
| unit @code{m} with this switch, then we get the expected |
| value of zero printed. Analyzing which units might need |
| the switch can be painful, so a more reasonable approach |
| is to compile the entire program with options @code{-O2} |
| and @code{-fno-strict-aliasing}. If the performance is |
| satisfactory with this combination of options, then the |
| advantage is that the entire issue of possible "wrong" |
| optimization due to strict aliasing is avoided. |
| |
| To avoid the use of compiler switches, the configuration |
| pragma @code{No_Strict_Aliasing} with no parameters may be |
| used to specify that for all access types, the strict |
| aliasing optimization should be suppressed. |
| |
| However, these approaches are still overkill, in that they causes |
| all manipulations of all access values to be deoptimized. A more |
| refined approach is to concentrate attention on the specific |
| access type identified as problematic. |
| |
| First, if a careful analysis of uses of the pointer shows |
| that there are no possible problematic references, then |
| the warning can be suppressed by bracketing the |
| instantiation of @code{Unchecked_Conversion} to turn |
| the warning off: |
| |
| @smallexample @c ada |
| pragma Warnings (Off); |
| function to_a2u is |
| new Unchecked_Conversion (a1, a2); |
| pragma Warnings (On); |
| @end smallexample |
| |
| @noindent |
| Of course that approach is not appropriate for this particular |
| example, since indeed there is a problematic reference. In this |
| case we can take one of two other approaches. |
| |
| The first possibility is to move the instantiation of unchecked |
| conversion to the unit in which the type is declared. In |
| this example, we would move the instantiation of |
| @code{Unchecked_Conversion} from the body of package |
| @code{p2} to the spec of package @code{p1}. Now the |
| warning disappears. That's because any use of the |
| access type knows there is a suspicious unchecked |
| conversion, and the strict aliasing optimization |
| is automatically suppressed for the type. |
| |
| If it is not practical to move the unchecked conversion to the same unit |
| in which the destination access type is declared (perhaps because the |
| source type is not visible in that unit), you may use pragma |
| @code{No_Strict_Aliasing} for the type. This pragma must occur in the |
| same declarative sequence as the declaration of the access type: |
| |
| @smallexample @c ada |
| type a2 is access int2; |
| pragma No_Strict_Aliasing (a2); |
| @end smallexample |
| |
| @noindent |
| Here again, the compiler now knows that the strict aliasing optimization |
| should be suppressed for any reference to type @code{a2} and the |
| expected behavior is obtained. |
| |
| Finally, note that although the compiler can generate warnings for |
| simple cases of unchecked conversions, there are tricker and more |
| indirect ways of creating type incorrect aliases which the compiler |
| cannot detect. Examples are the use of address overlays and unchecked |
| conversions involving composite types containing access types as |
| components. In such cases, no warnings are generated, but there can |
| still be aliasing problems. One safe coding practice is to forbid the |
| use of address clauses for type overlaying, and to allow unchecked |
| conversion only for primitive types. This is not really a significant |
| restriction since any possible desired effect can be achieved by |
| unchecked conversion of access values. |
| |
| @ifset vms |
| @node Coverage Analysis |
| @subsection Coverage Analysis |
| |
| @noindent |
| GNAT supports the HP Performance Coverage Analyzer (PCA), which allows |
| the user to determine the distribution of execution time across a program, |
| @pxref{Profiling} for details of usage. |
| @end ifset |
| |
| @node Reducing the Size of Ada Executables with gnatelim |
| @section Reducing the Size of Ada Executables with @code{gnatelim} |
| @findex gnatelim |
| |
| @noindent |
| This section describes @command{gnatelim}, a tool which detects unused |
| subprograms and helps the compiler to create a smaller executable for your |
| program. |
| |
| @menu |
| * About gnatelim:: |
| * Running gnatelim:: |
| * Correcting the List of Eliminate Pragmas:: |
| * Making Your Executables Smaller:: |
| * Summary of the gnatelim Usage Cycle:: |
| @end menu |
| |
| @node About gnatelim |
| @subsection About @code{gnatelim} |
| |
| @noindent |
| When a program shares a set of Ada |
| packages with other programs, it may happen that this program uses |
| only a fraction of the subprograms defined in these packages. The code |
| created for these unused subprograms increases the size of the executable. |
| |
| @code{gnatelim} tracks unused subprograms in an Ada program and |
| outputs a list of GNAT-specific pragmas @code{Eliminate} marking all the |
| subprograms that are declared but never called. By placing the list of |
| @code{Eliminate} pragmas in the GNAT configuration file @file{gnat.adc} and |
| recompiling your program, you may decrease the size of its executable, |
| because the compiler will not generate the code for 'eliminated' subprograms. |
| See GNAT Reference Manual for more information about this pragma. |
| |
| @code{gnatelim} needs as its input data the name of the main subprogram |
| and a bind file for a main subprogram. |
| |
| To create a bind file for @code{gnatelim}, run @code{gnatbind} for |
| the main subprogram. @code{gnatelim} can work with both Ada and C |
| bind files; when both are present, it uses the Ada bind file. |
| The following commands will build the program and create the bind file: |
| |
| @smallexample |
| $ gnatmake ^-c Main_Prog^/ACTIONS=COMPILE MAIN_PROG^ |
| $ gnatbind main_prog |
| @end smallexample |
| |
| Note that @code{gnatelim} needs neither object nor ALI files. |
| |
| @node Running gnatelim |
| @subsection Running @code{gnatelim} |
| |
| @noindent |
| @code{gnatelim} has the following command-line interface: |
| |
| @smallexample |
| $ gnatelim [options] name |
| @end smallexample |
| |
| @noindent |
| @code{name} should be a name of a source file that contains the main subprogram |
| of a program (partition). |
| |
| @code{gnatelim} has the following switches: |
| |
| @table @option |
| @c !sort! |
| @item ^-q^/QUIET^ |
| @cindex @option{^-q^/QUIET^} (@command{gnatelim}) |
| Quiet mode: by default @code{gnatelim} outputs to the standard error |
| stream the number of program units left to be processed. This option turns |
| this trace off. |
| |
| @item ^-v^/VERBOSE^ |
| @cindex @option{^-v^/VERBOSE^} (@command{gnatelim}) |
| Verbose mode: @code{gnatelim} version information is printed as Ada |
| comments to the standard output stream. Also, in addition to the number of |
| program units left @code{gnatelim} will output the name of the current unit |
| being processed. |
| |
| @item ^-a^/ALL^ |
| @cindex @option{^-a^/ALL^} (@command{gnatelim}) |
| Also look for subprograms from the GNAT run time that can be eliminated. Note |
| that when @file{gnat.adc} is produced using this switch, the entire program |
| must be recompiled with switch @option{^-a^/ALL_FILES^} to @command{gnatmake}. |
| |
| @item ^-I^/INCLUDE_DIRS=^@var{dir} |
| @cindex @option{^-I^/INCLUDE_DIRS^} (@command{gnatelim}) |
| When looking for source files also look in directory @var{dir}. Specifying |
| @option{^-I-^/INCLUDE_DIRS=-^} instructs @code{gnatelim} not to look for |
| sources in the current directory. |
| |
| @item ^-b^/BIND_FILE=^@var{bind_file} |
| @cindex @option{^-b^/BIND_FILE^} (@command{gnatelim}) |
| Specifies @var{bind_file} as the bind file to process. If not set, the name |
| of the bind file is computed from the full expanded Ada name |
| of a main subprogram. |
| |
| @item ^-C^/CONFIG_FILE=^@var{config_file} |
| @cindex @option{^-C^/CONFIG_FILE^} (@command{gnatelim}) |
| Specifies a file @var{config_file} that contains configuration pragmas. The |
| file must be specified with full path. |
| |
| @item ^--GCC^/COMPILER^=@var{compiler_name} |
| @cindex @option{^-GCC^/COMPILER^} (@command{gnatelim}) |
| Instructs @code{gnatelim} to use specific @command{gcc} compiler instead of one |
| available on the path. |
| |
| @item ^--GNATMAKE^/GNATMAKE^=@var{gnatmake_name} |
| @cindex @option{^--GNATMAKE^/GNATMAKE^} (@command{gnatelim}) |
| Instructs @code{gnatelim} to use specific @command{gnatmake} instead of one |
| available on the path. |
| @end table |
| |
| @noindent |
| @code{gnatelim} sends its output to the standard output stream, and all the |
| tracing and debug information is sent to the standard error stream. |
| In order to produce a proper GNAT configuration file |
| @file{gnat.adc}, redirection must be used: |
| |
| @smallexample |
| @ifset vms |
| $ PIPE GNAT ELIM MAIN_PROG.ADB > GNAT.ADC |
| @end ifset |
| @ifclear vms |
| $ gnatelim main_prog.adb > gnat.adc |
| @end ifclear |
| @end smallexample |
| |
| @ifclear vms |
| @noindent |
| or |
| |
| @smallexample |
| $ gnatelim main_prog.adb >> gnat.adc |
| @end smallexample |
| |
| @noindent |
| in order to append the @code{gnatelim} output to the existing contents of |
| @file{gnat.adc}. |
| @end ifclear |
| |
| @node Correcting the List of Eliminate Pragmas |
| @subsection Correcting the List of Eliminate Pragmas |
| |
| @noindent |
| In some rare cases @code{gnatelim} may try to eliminate |
| subprograms that are actually called in the program. In this case, the |
| compiler will generate an error message of the form: |
| |
| @smallexample |
| file.adb:106:07: cannot call eliminated subprogram "My_Prog" |
| @end smallexample |
| |
| @noindent |
| You will need to manually remove the wrong @code{Eliminate} pragmas from |
| the @file{gnat.adc} file. You should recompile your program |
| from scratch after that, because you need a consistent @file{gnat.adc} file |
| during the entire compilation. |
| |
| @node Making Your Executables Smaller |
| @subsection Making Your Executables Smaller |
| |
| @noindent |
| In order to get a smaller executable for your program you now have to |
| recompile the program completely with the new @file{gnat.adc} file |
| created by @code{gnatelim} in your current directory: |
| |
| @smallexample |
| $ gnatmake ^-f main_prog^/FORCE_COMPILE MAIN_PROG^ |
| @end smallexample |
| |
| @noindent |
| (Use the @option{^-f^/FORCE_COMPILE^} option for @command{gnatmake} to |
| recompile everything |
| with the set of pragmas @code{Eliminate} that you have obtained with |
| @command{gnatelim}). |
| |
| Be aware that the set of @code{Eliminate} pragmas is specific to each |
| program. It is not recommended to merge sets of @code{Eliminate} |
| pragmas created for different programs in one @file{gnat.adc} file. |
| |
| @node Summary of the gnatelim Usage Cycle |
| @subsection Summary of the gnatelim Usage Cycle |
| |
| @noindent |
| Here is a quick summary of the steps to be taken in order to reduce |
| the size of your executables with @code{gnatelim}. You may use |
| other GNAT options to control the optimization level, |
| to produce the debugging information, to set search path, etc. |
| |
| @enumerate |
| @item |
| Produce a bind file |
| |
| @smallexample |
| $ gnatmake ^-c main_prog^/ACTIONS=COMPILE MAIN_PROG^ |
| $ gnatbind main_prog |
| @end smallexample |
| |
| @item |
| Generate a list of @code{Eliminate} pragmas |
| @smallexample |
| @ifset vms |
| $ PIPE GNAT ELIM MAIN_PROG > GNAT.ADC |
| @end ifset |
| @ifclear vms |
| $ gnatelim main_prog >[>] gnat.adc |
| @end ifclear |
| @end smallexample |
| |
| @item |
| Recompile the application |
| |
| @smallexample |
| $ gnatmake ^-f main_prog^/FORCE_COMPILE MAIN_PROG^ |
| @end smallexample |
| |
| @end enumerate |
| |
| @node Reducing the Size of Executables with unused subprogram/data elimination |
| @section Reducing the Size of Executables with Unused Subprogram/Data Elimination |
| @findex unused subprogram/data elimination |
| |
| @noindent |
| This section describes how you can eliminate unused subprograms and data from |
| your executable just by setting options at compilation time. |
| |
| @menu |
| * About unused subprogram/data elimination:: |
| * Compilation options:: |
| @end menu |
| |
| @node About unused subprogram/data elimination |
| @subsection About unused subprogram/data elimination |
| |
| @noindent |
| By default, an executable contains all code and data of its composing objects |
| (directly linked or coming from statically linked libraries), even data or code |
| never used by this executable. |
| |
| This feature will allow you to eliminate such unused code from your |
| executable, making it smaller (in disk and in memory). |
| |
| This functionality is only available on native x86 GNU/Linux platform for the |
| moment. |
| |
| @node Compilation options |
| @subsection Compilation options |
| |
| @noindent |
| The operation of eliminating the unused code and data from the final executable |
| is directly performed by the linker. |
| |
| In order to do this, it has to work with objects compiled with the |
| following options: |
| @option{-ffunction-sections} @option{-fdata-sections}. |
| @cindex @option{-ffunction-sections} (@command{gcc}) |
| @cindex @option{-fdata-sections} (@command{gcc}) |
| These options are usable with C and Ada files. |
| They will place respectively each |
| function or data in a separate section in the resulting object file. |
| |
| Once the objects and static libraries are created with these options, the |
| linker can perform the dead code elimination. You can do this by setting |
| the @option{-Wl,--gc-sections} option to gcc command or in the |
| @option{-largs} section of gnatmake. This will create the final executable, |
| without including the code and data determined as never accessed. |
| |
| Note that objects compiled without the @option{-ffunction-sections} and |
| @option{-fdata-sections} options can still be linked with the executable. |
| However, no dead code elimination will be performed on those objects (they will |
| be linked as is). |
| |
| The GNAT static library is now compiled with -ffunction-sections and |
| -fdata-sections. This allows you to eliminate the unused code of the GNAT |
| library from your executable. |
| |
| @c ******************************** |
| @node Renaming Files Using gnatchop |
| @chapter Renaming Files Using @code{gnatchop} |
| @findex gnatchop |
| |
| @noindent |
| This chapter discusses how to handle files with multiple units by using |
| the @code{gnatchop} utility. This utility is also useful in renaming |
| files to meet the standard GNAT default file naming conventions. |
| |
| @menu |
| * Handling Files with Multiple Units:: |
| * Operating gnatchop in Compilation Mode:: |
| * Command Line for gnatchop:: |
| * Switches for gnatchop:: |
| * Examples of gnatchop Usage:: |
| @end menu |
| |
| @node Handling Files with Multiple Units |
| @section Handling Files with Multiple Units |
| |
| @noindent |
| The basic compilation model of GNAT requires that a file submitted to the |
| compiler have only one unit and there be a strict correspondence |
| between the file name and the unit name. |
| |
| The @code{gnatchop} utility allows both of these rules to be relaxed, |
| allowing GNAT to process files which contain multiple compilation units |
| and files with arbitrary file names. @code{gnatchop} |
| reads the specified file and generates one or more output files, |
| containing one unit per file. The unit and the file name correspond, |
| as required by GNAT. |
| |
| If you want to permanently restructure a set of ``foreign'' files so that |
| they match the GNAT rules, and do the remaining development using the |
| GNAT structure, you can simply use @command{gnatchop} once, generate the |
| new set of files and work with them from that point on. |
| |
| Alternatively, if you want to keep your files in the ``foreign'' format, |
| perhaps to maintain compatibility with some other Ada compilation |
| system, you can set up a procedure where you use @command{gnatchop} each |
| time you compile, regarding the source files that it writes as temporary |
| files that you throw away. |
| |
| @node Operating gnatchop in Compilation Mode |
| @section Operating gnatchop in Compilation Mode |
| |
| @noindent |
| The basic function of @code{gnatchop} is to take a file with multiple units |
| and split it into separate files. The boundary between files is reasonably |
| clear, except for the issue of comments and pragmas. In default mode, the |
| rule is that any pragmas between units belong to the previous unit, except |
| that configuration pragmas always belong to the following unit. Any comments |
| belong to the following unit. These rules |
| almost always result in the right choice of |
| the split point without needing to mark it explicitly and most users will |
| find this default to be what they want. In this default mode it is incorrect to |
| submit a file containing only configuration pragmas, or one that ends in |
| configuration pragmas, to @code{gnatchop}. |
| |
| However, using a special option to activate ``compilation mode'', |
| @code{gnatchop} |
| can perform another function, which is to provide exactly the semantics |
| required by the RM for handling of configuration pragmas in a compilation. |
| In the absence of configuration pragmas (at the main file level), this |
| option has no effect, but it causes such configuration pragmas to be handled |
| in a quite different manner. |
| |
| First, in compilation mode, if @code{gnatchop} is given a file that consists of |
| only configuration pragmas, then this file is appended to the |
| @file{gnat.adc} file in the current directory. This behavior provides |
| the required behavior described in the RM for the actions to be taken |
| on submitting such a file to the compiler, namely that these pragmas |
| should apply to all subsequent compilations in the same compilation |
| environment. Using GNAT, the current directory, possibly containing a |
| @file{gnat.adc} file is the representation |
| of a compilation environment. For more information on the |
| @file{gnat.adc} file, see @ref{Handling of Configuration Pragmas}. |
| |
| Second, in compilation mode, if @code{gnatchop} |
| is given a file that starts with |
| configuration pragmas, and contains one or more units, then these |
| configuration pragmas are prepended to each of the chopped files. This |
| behavior provides the required behavior described in the RM for the |
| actions to be taken on compiling such a file, namely that the pragmas |
| apply to all units in the compilation, but not to subsequently compiled |
| units. |
| |
| Finally, if configuration pragmas appear between units, they are appended |
| to the previous unit. This results in the previous unit being illegal, |
| since the compiler does not accept configuration pragmas that follow |
| a unit. This provides the required RM behavior that forbids configuration |
| pragmas other than those preceding the first compilation unit of a |
| compilation. |
| |
| For most purposes, @code{gnatchop} will be used in default mode. The |
| compilation mode described above is used only if you need exactly |
| accurate behavior with respect to compilations, and you have files |
| that contain multiple units and configuration pragmas. In this |
| circumstance the use of @code{gnatchop} with the compilation mode |
| switch provides the required behavior, and is for example the mode |
| in which GNAT processes the ACVC tests. |
| |
| @node Command Line for gnatchop |
| @section Command Line for @code{gnatchop} |
| |
| @noindent |
| The @code{gnatchop} command has the form: |
| |
| @smallexample |
| $ gnatchop switches @var{file name} [@var{file name} @var{file name} ...] |
| [@var{directory}] |
| @end smallexample |
| |
| @noindent |
| The only required argument is the file name of the file to be chopped. |
| There are no restrictions on the form of this file name. The file itself |
| contains one or more Ada units, in normal GNAT format, concatenated |
| together. As shown, more than one file may be presented to be chopped. |
| |
| When run in default mode, @code{gnatchop} generates one output file in |
| the current directory for each unit in each of the files. |
| |
| @var{directory}, if specified, gives the name of the directory to which |
| the output files will be written. If it is not specified, all files are |
| written to the current directory. |
| |
| For example, given a |
| file called @file{hellofiles} containing |
| |
| @smallexample @c ada |
| @group |
| @cartouche |
| procedure hello; |
| |
| with Text_IO; use Text_IO; |
| procedure hello is |
| begin |
| Put_Line ("Hello"); |
| end hello; |
| @end cartouche |
| @end group |
| @end smallexample |
| |
| @noindent |
| the command |
| |
| @smallexample |
| $ gnatchop ^hellofiles^HELLOFILES.^ |
| @end smallexample |
| |
| @noindent |
| generates two files in the current directory, one called |
| @file{hello.ads} containing the single line that is the procedure spec, |
| and the other called @file{hello.adb} containing the remaining text. The |
| original file is not affected. The generated files can be compiled in |
| the normal manner. |
| |
| @noindent |
| When gnatchop is invoked on a file that is empty or that contains only empty |
| lines and/or comments, gnatchop will not fail, but will not produce any |
| new sources. |
| |
| For example, given a |
| file called @file{toto.txt} containing |
| |
| @smallexample @c ada |
| @group |
| @cartouche |
| -- Just a comment |
| @end cartouche |
| @end group |
| @end smallexample |
| |
| @noindent |
| the command |
| |
| @smallexample |
| $ gnatchop ^toto.txt^TOT.TXT^ |
| @end smallexample |
| |
| @noindent |
| will not produce any new file and will result in the following warnings: |
| |
| @smallexample |
| toto.txt:1:01: warning: empty file, contains no compilation units |
| no compilation units found |
| no source files written |
| @end smallexample |
| |
| @node Switches for gnatchop |
| @section Switches for @code{gnatchop} |
| |
| @noindent |
| @command{gnatchop} recognizes the following switches: |
| |
| @table @option |
| @c !sort! |
| |
| @item ^-c^/COMPILATION^ |
| @cindex @option{^-c^/COMPILATION^} (@code{gnatchop}) |
| Causes @code{gnatchop} to operate in compilation mode, in which |
| configuration pragmas are handled according to strict RM rules. See |
| previous section for a full description of this mode. |
| |
| @ifclear vms |
| @item -gnatxxx |
| This passes the given @option{-gnatxxx} switch to @code{gnat} which is |
| used to parse the given file. Not all @code{xxx} options make sense, |
| but for example, the use of @option{-gnati2} allows @code{gnatchop} to |
| process a source file that uses Latin-2 coding for identifiers. |
| @end ifclear |
| |
| @item ^-h^/HELP^ |
| Causes @code{gnatchop} to generate a brief help summary to the standard |
| output file showing usage information. |
| |
| @item ^-k@var{mm}^/FILE_NAME_MAX_LENGTH=@var{mm}^ |
| @cindex @option{^-k^/FILE_NAME_MAX_LENGTH^} (@code{gnatchop}) |
| Limit generated file names to the specified number @code{mm} |
| of characters. |
| This is useful if the |
| resulting set of files is required to be interoperable with systems |
| which limit the length of file names. |
| @ifset vms |
| If no value is given, or |
| if no @code{/FILE_NAME_MAX_LENGTH} qualifier is given, |
| a default of 39, suitable for OpenVMS Alpha |
| Systems, is assumed |
| @end ifset |
| @ifclear vms |
| No space is allowed between the @option{-k} and the numeric value. The numeric |
| value may be omitted in which case a default of @option{-k8}, |
| suitable for use |
| with DOS-like file systems, is used. If no @option{-k} switch |
| is present then |
| there is no limit on the length of file names. |
| @end ifclear |
| |
| @item ^-p^/PRESERVE^ |
| @cindex @option{^-p^/PRESERVE^} (@code{gnatchop}) |
| Causes the file ^modification^creation^ time stamp of the input file to be |
| preserved and used for the time stamp of the output file(s). This may be |
| useful for preserving coherency of time stamps in an environment where |
| @code{gnatchop} is used as part of a standard build process. |
| |
| @item ^-q^/QUIET^ |
| @cindex @option{^-q^/QUIET^} (@code{gnatchop}) |
| Causes output of informational messages indicating the set of generated |
| files to be suppressed. Warnings and error messages are unaffected. |
| |
| @item ^-r^/REFERENCE^ |
| @cindex @option{^-r^/REFERENCE^} (@code{gnatchop}) |
| @findex Source_Reference |
| Generate @code{Source_Reference} pragmas. Use this switch if the output |
| files are regarded as temporary and development is to be done in terms |
| of the original unchopped file. This switch causes |
| @code{Source_Reference} pragmas to be inserted into each of the |
| generated files to refers back to the original file name and line number. |
| The result is that all error messages refer back to the original |
| unchopped file. |
| In addition, the debugging information placed into the object file (when |
| the @option{^-g^/DEBUG^} switch of @command{gcc} or @command{gnatmake} is |
| specified) |
| also refers back to this original file so that tools like profilers and |
| debuggers will give information in terms of the original unchopped file. |
| |
| If the original file to be chopped itself contains |
| a @code{Source_Reference} |
| pragma referencing a third file, then gnatchop respects |
| this pragma, and the generated @code{Source_Reference} pragmas |
| in the chopped file refer to the original file, with appropriate |
| line numbers. This is particularly useful when @code{gnatchop} |
| is used in conjunction with @code{gnatprep} to compile files that |
| contain preprocessing statements and multiple units. |
| |
| @item ^-v^/VERBOSE^ |
| @cindex @option{^-v^/VERBOSE^} (@code{gnatchop}) |
| Causes @code{gnatchop} to operate in verbose mode. The version |
| number and copyright notice are output, as well as exact copies of |
| the gnat1 commands spawned to obtain the chop control information. |
| |
| @item ^-w^/OVERWRITE^ |
| @cindex @option{^-w^/OVERWRITE^} (@code{gnatchop}) |
| Overwrite existing file names. Normally @code{gnatchop} regards it as a |
| fatal error if there is already a file with the same name as a |
| file it would otherwise output, in other words if the files to be |
| chopped contain duplicated units. This switch bypasses this |
| check, and causes all but the last instance of such duplicated |
| units to be skipped. |
| |
| @ifclear vms |
| @item --GCC=xxxx |
| @cindex @option{--GCC=} (@code{gnatchop}) |
| Specify the path of the GNAT parser to be used. When this switch is used, |
| no attempt is made to add the prefix to the GNAT parser executable. |
| @end ifclear |
| @end table |
| |
| @node Examples of gnatchop Usage |
| @section Examples of @code{gnatchop} Usage |
| |
| @table @code |
| @ifset vms |
| @item gnatchop /OVERWRITE HELLO_S.ADA [PRERELEASE.FILES] |
| @end ifset |
| @ifclear vms |
| @item gnatchop -w hello_s.ada prerelease/files |
| @end ifclear |
| |
| Chops the source file @file{hello_s.ada}. The output files will be |
| placed in the directory @file{^prerelease/files^[PRERELEASE.FILES]^}, |
| overwriting any |
| files with matching names in that directory (no files in the current |
| directory are modified). |
| |
| @item gnatchop ^archive^ARCHIVE.^ |
| Chops the source file @file{^archive^ARCHIVE.^} |
| into the current directory. One |
| useful application of @code{gnatchop} is in sending sets of sources |
| around, for example in email messages. The required sources are simply |
| concatenated (for example, using a ^Unix @code{cat}^VMS @code{APPEND/NEW}^ |
| command), and then |
| @code{gnatchop} is used at the other end to reconstitute the original |
| file names. |
| |
| @item gnatchop file1 file2 file3 direc |
| Chops all units in files @file{file1}, @file{file2}, @file{file3}, placing |
| the resulting files in the directory @file{direc}. Note that if any units |
| occur more than once anywhere within this set of files, an error message |
| is generated, and no files are written. To override this check, use the |
| @option{^-w^/OVERWRITE^} switch, |
| in which case the last occurrence in the last file will |
| be the one that is output, and earlier duplicate occurrences for a given |
| unit will be skipped. |
| @end table |
| |
| @node Configuration Pragmas |
| @chapter Configuration Pragmas |
| @cindex Configuration pragmas |
| @cindex Pragmas, configuration |
| |
| @noindent |
| In Ada 95, configuration pragmas include those pragmas described as |
| such in the Ada 95 Reference Manual, as well as |
| implementation-dependent pragmas that are configuration pragmas. See the |
| individual descriptions of pragmas in the GNAT Reference Manual for |
| details on these additional GNAT-specific configuration pragmas. Most |
| notably, the pragma @code{Source_File_Name}, which allows |
| specifying non-default names for source files, is a configuration |
| pragma. The following is a complete list of configuration pragmas |
| recognized by @code{GNAT}: |
| |
| @smallexample |
| Ada_83 |
| Ada_95 |
| Ada_05 |
| C_Pass_By_Copy |
| Component_Alignment |
| Detect_Blocking |
| Discard_Names |
| Elaboration_Checks |
| Eliminate |
| Extend_System |
| External_Name_Casing |
| Float_Representation |
| Initialize_Scalars |
| Interrupt_State |
| License |
| Locking_Policy |
| Long_Float |
| Normalize_Scalars |
| Persistent_BSS |
| Polling |
| Profile |
| Profile_Warnings |
| Propagate_Exceptions |
| Queuing_Policy |
| Ravenscar |
| Restricted_Run_Time |
| Restrictions |
| Restrictions_Warnings |
| Reviewable |
| Source_File_Name |
| Style_Checks |
| Suppress |
| Task_Dispatching_Policy |
| Universal_Data |
| Unsuppress |
| Use_VADS_Size |
| Warnings |
| Validity_Checks |
| @end smallexample |
| |
| @menu |
| * Handling of Configuration Pragmas:: |
| * The Configuration Pragmas Files:: |
| @end menu |
| |
| @node Handling of Configuration Pragmas |
| @section Handling of Configuration Pragmas |
| |
| Configuration pragmas may either appear at the start of a compilation |
| unit, in which case they apply only to that unit, or they may apply to |
| all compilations performed in a given compilation environment. |
| |
| GNAT also provides the @code{gnatchop} utility to provide an automatic |
| way to handle configuration pragmas following the semantics for |
| compilations (that is, files with multiple units), described in the RM. |
| See @ref{Operating gnatchop in Compilation Mode} for details. |
| However, for most purposes, it will be more convenient to edit the |
| @file{gnat.adc} file that contains configuration pragmas directly, |
| as described in the following section. |
| |
| @node The Configuration Pragmas Files |
| @section The Configuration Pragmas Files |
| @cindex @file{gnat.adc} |
| |
| @noindent |
| In GNAT a compilation environment is defined by the current |
| directory at the time that a compile command is given. This current |
| directory is searched for a file whose name is @file{gnat.adc}. If |
| this file is present, it is expected to contain one or more |
| configuration pragmas that will be applied to the current compilation. |
| However, if the switch @option{-gnatA} is used, @file{gnat.adc} is not |
| considered. |
| |
| Configuration pragmas may be entered into the @file{gnat.adc} file |
| either by running @code{gnatchop} on a source file that consists only of |
| configuration pragmas, or more conveniently by |
| direct editing of the @file{gnat.adc} file, which is a standard format |
| source file. |
| |
| In addition to @file{gnat.adc}, one additional file containing configuration |
| pragmas may be applied to the current compilation using the switch |
| @option{-gnatec}@var{path}. @var{path} must designate an existing file that |
| contains only configuration pragmas. These configuration pragmas are |
| in addition to those found in @file{gnat.adc} (provided @file{gnat.adc} |
| is present and switch @option{-gnatA} is not used). |
| |
| It is allowed to specify several switches @option{-gnatec}, however only |
| the last one on the command line will be taken into account. |
| |
| If you are using project file, a separate mechanism is provided using |
| project attributes, see @ref{Specifying Configuration Pragmas} for more |
| details. |
| |
| @ifset vms |
| Of special interest to GNAT OpenVMS Alpha is the following |
| configuration pragma: |
| |
| @smallexample @c ada |
| @cartouche |
| pragma Extend_System (Aux_DEC); |
| @end cartouche |
| @end smallexample |
| |
| @noindent |
| In the presence of this pragma, GNAT adds to the definition of the |
| predefined package SYSTEM all the additional types and subprograms that are |
| defined in HP Ada. See @ref{Compatibility with HP Ada} for details. |
| @end ifset |
| |
| @node Handling Arbitrary File Naming Conventions Using gnatname |
| @chapter Handling Arbitrary File Naming Conventions Using @code{gnatname} |
| @cindex Arbitrary File Naming Conventions |
| |
| @menu |
| * Arbitrary File Naming Conventions:: |
| * Running gnatname:: |
| * Switches for gnatname:: |
| * Examples of gnatname Usage:: |
| @end menu |
| |
| @node Arbitrary File Naming Conventions |
| @section Arbitrary File Naming Conventions |
| |
| @noindent |
| The GNAT compiler must be able to know the source file name of a compilation |
| unit. When using the standard GNAT default file naming conventions |
| (@code{.ads} for specs, @code{.adb} for bodies), the GNAT compiler |
| does not need additional information. |
| |
| @noindent |
| When the source file names do not follow the standard GNAT default file naming |
| conventions, the GNAT compiler must be given additional information through |
| a configuration pragmas file (@pxref{Configuration Pragmas}) |
| or a project file. |
| When the non standard file naming conventions are well-defined, |
| a small number of pragmas @code{Source_File_Name} specifying a naming pattern |
| (@pxref{Alternative File Naming Schemes}) may be sufficient. However, |
| if the file naming conventions are irregular or arbitrary, a number |
| of pragma @code{Source_File_Name} for individual compilation units |
| must be defined. |
| To help maintain the correspondence between compilation unit names and |
| source file names within the compiler, |
| GNAT provides a tool @code{gnatname} to generate the required pragmas for a |
| set of files. |
| |
| @node Running gnatname |
| @section Running @code{gnatname} |
| |
| @noindent |
| The usual form of the @code{gnatname} command is |
| |
| @smallexample |
| $ gnatname [@var{switches}] @var{naming_pattern} [@var{naming_patterns}] |
| @end smallexample |
| |
| @noindent |
| All of the arguments are optional. If invoked without any argument, |
| @code{gnatname} will display its usage. |
| |
| @noindent |
| When used with at least one naming pattern, @code{gnatname} will attempt to |
| find all the compilation units in files that follow at least one of the |
| naming patterns. To find these compilation units, |
| @code{gnatname} will use the GNAT compiler in syntax-check-only mode on all |
| regular files. |
| |
| @noindent |
| One or several Naming Patterns may be given as arguments to @code{gnatname}. |
| Each Naming Pattern is enclosed between double quotes. |
| A Naming Pattern is a regular expression similar to the wildcard patterns |
| used in file names by the Unix shells or the DOS prompt. |
| |
| @noindent |
| Examples of Naming Patterns are |
| |
| @smallexample |
| "*.[12].ada" |
| "*.ad[sb]*" |
| "body_*" "spec_*" |
| @end smallexample |
| |
| @noindent |
| For a more complete description of the syntax of Naming Patterns, |
| see the second kind of regular expressions described in @file{g-regexp.ads} |
| (the ``Glob'' regular expressions). |
| |
| @noindent |
| When invoked with no switches, @code{gnatname} will create a configuration |
| pragmas file @file{gnat.adc} in the current working directory, with pragmas |
| @code{Source_File_Name} for each file that contains a valid Ada unit. |
| |
| @node Switches for gnatname |
| @section Switches for @code{gnatname} |
| |
| @noindent |
| Switches for @code{gnatname} must precede any specified Naming Pattern. |
| |
| @noindent |
| You may specify any of the following switches to @code{gnatname}: |
| |
| @table @option |
| @c !sort! |
| |
| @item ^-c^/CONFIG_FILE=^@file{file} |
| @cindex @option{^-c^/CONFIG_FILE^} (@code{gnatname}) |
| Create a configuration pragmas file @file{file} (instead of the default |
| @file{gnat.adc}). |
| @ifclear vms |
| There may be zero, one or more space between @option{-c} and |
| @file{file}. |
| @end ifclear |
| @file{file} may include directory information. @file{file} must be |
| writable. There may be only one switch @option{^-c^/CONFIG_FILE^}. |
| When a switch @option{^-c^/CONFIG_FILE^} is |
| specified, no switch @option{^-P^/PROJECT_FILE^} may be specified (see below). |
| |
| @item ^-d^/SOURCE_DIRS=^@file{dir} |
| @cindex @option{^-d^/SOURCE_DIRS^} (@code{gnatname}) |
| Look for source files in directory @file{dir}. There may be zero, one or more |
| spaces between @option{^-d^/SOURCE_DIRS=^} and @file{dir}. |
| When a switch @option{^-d^/SOURCE_DIRS^} |
| is specified, the current working directory will not be searched for source |
| files, unless it is explicitly specified with a @option{^-d^/SOURCE_DIRS^} |
| or @option{^-D^/DIR_FILES^} switch. |
| Several switches @option{^-d^/SOURCE_DIRS^} may be specified. |
| If @file{dir} is a relative path, it is relative to the directory of |
| the configuration pragmas file specified with switch |
| @option{^-c^/CONFIG_FILE^}, |
| or to the directory of the project file specified with switch |
| @option{^-P^/PROJECT_FILE^} or, |
| if neither switch @option{^-c^/CONFIG_FILE^} |
| nor switch @option{^-P^/PROJECT_FILE^} are specified, it is relative to the |
| current working directory. The directory |
| specified with switch @option{^-d^/SOURCE_DIRS^} must exist and be readable. |
| |
| @item ^-D^/DIRS_FILE=^@file{file} |
| @cindex @option{^-D^/DIRS_FILE^} (@code{gnatname}) |
| Look for source files in all directories listed in text file @file{file}. |
| There may be zero, one or more spaces between @option{^-D^/DIRS_FILE=^} |
| and @file{file}. |
| @file{file} must be an existing, readable text file. |
| Each non empty line in @file{file} must be a directory. |
| Specifying switch @option{^-D^/DIRS_FILE^} is equivalent to specifying as many |
| switches @option{^-d^/SOURCE_DIRS^} as there are non empty lines in |
| @file{file}. |
| |
| @item ^-f^/FOREIGN_PATTERN=^@file{pattern} |
| @cindex @option{^-f^/FOREIGN_PATTERN^} (@code{gnatname}) |
| Foreign patterns. Using this switch, it is possible to add sources of languages |
| other than Ada to the list of sources of a project file. |
| It is only useful if a ^-P^/PROJECT_FILE^ switch is used. |
| For example, |
| @smallexample |
| gnatname ^-Pprj -f"*.c"^/PROJECT_FILE=PRJ /FOREIGN_PATTERN=*.C^ "*.ada" |
| @end smallexample |
| @noindent |
| will look for Ada units in all files with the @file{.ada} extension, |
| and will add to the list of file for project @file{prj.gpr} the C files |
| with extension ".^c^C^". |
| |
| @item ^-h^/HELP^ |
| @cindex @option{^-h^/HELP^} (@code{gnatname}) |
| Output usage (help) information. The output is written to @file{stdout}. |
| |
| @item ^-P^/PROJECT_FILE=^@file{proj} |
| @cindex @option{^-P^/PROJECT_FILE^} (@code{gnatname}) |
| Create or update project file @file{proj}. There may be zero, one or more space |
| between @option{-P} and @file{proj}. @file{proj} may include directory |
| information. @file{proj} must be writable. |
| There may be only one switch @option{^-P^/PROJECT_FILE^}. |
| When a switch @option{^-P^/PROJECT_FILE^} is specified, |
| no switch @option{^-c^/CONFIG_FILE^} may be specified. |
| |
| @item ^-v^/VERBOSE^ |
| @cindex @option{^-v^/VERBOSE^} (@code{gnatname}) |
| Verbose mode. Output detailed explanation of behavior to @file{stdout}. |
| This includes name of the file written, the name of the directories to search |
| and, for each file in those directories whose name matches at least one of |
| the Naming Patterns, an indication of whether the file contains a unit, |
| and if so the name of the unit. |
| |
| @item ^-v -v^/VERBOSE /VERBOSE^ |
| @cindex @option{^-v -v^/VERBOSE /VERBOSE^} (@code{gnatname}) |
| Very Verbose mode. In addition to the output produced in verbose mode, |
| for each file in the searched directories whose name matches none of |
| the Naming Patterns, an indication is given that there is no match. |
| |
| @item ^-x^/EXCLUDED_PATTERN=^@file{pattern} |
| @cindex @option{^-x^/EXCLUDED_PATTERN^} (@code{gnatname}) |
| Excluded patterns. Using this switch, it is possible to exclude some files |
| that would match the name patterns. For example, |
| @smallexample |
| gnatname ^-x "*_nt.ada"^/EXCLUDED_PATTERN=*_nt.ada^ "*.ada" |
| @end smallexample |
| @noindent |
| will look for Ada units in all files with the @file{.ada} extension, |
| except those whose names end with @file{_nt.ada}. |
| |
| @end table |
| |
| @node Examples of gnatname Usage |
| @section Examples of @code{gnatname} Usage |
| |
| @ifset vms |
| @smallexample |
| $ gnatname /CONFIG_FILE=[HOME.ME]NAMES.ADC /SOURCE_DIRS=SOURCES "[a-z]*.ada*" |
| @end smallexample |
| @end ifset |
| |
| @ifclear vms |
| @smallexample |
| $ gnatname -c /home/me/names.adc -d sources "[a-z]*.ada*" |
| @end smallexample |
| @end ifclear |
| |
| @noindent |
| In this example, the directory @file{^/home/me^[HOME.ME]^} must already exist |
| and be writable. In addition, the directory |
| @file{^/home/me/sources^[HOME.ME.SOURCES]^} (specified by |
| @option{^-d sources^/SOURCE_DIRS=SOURCES^}) must exist and be readable. |
| |
| @ifclear vms |
| Note the optional spaces after @option{-c} and @option{-d}. |
| @end ifclear |
| |
| @smallexample |
| @ifclear vms |
| $ gnatname -P/home/me/proj -x "*_nt_body.ada" |
| -dsources -dsources/plus -Dcommon_dirs.txt "body_*" "spec_*" |
| @end ifclear |
| @ifset vms |
| $ gnatname /PROJECT_FILE=[HOME.ME]PROJ |
| /EXCLUDED_PATTERN=*_nt_body.ada |
| /SOURCE_DIRS=(SOURCES,[SOURCES.PLUS]) |
| /DIRS_FILE=COMMON_DIRS.TXT "body_*" "spec_*" |
| @end ifset |
| @end smallexample |
| |
| Note that several switches @option{^-d^/SOURCE_DIRS^} may be used, |
| even in conjunction with one or several switches |
| @option{^-D^/DIRS_FILE^}. Several Naming Patterns and one excluded pattern |
| are used in this example. |
| |
| @c ***************************************** |
| @c * G N A T P r o j e c t M a n a g e r * |
| @c ***************************************** |
| @node GNAT Project Manager |
| @chapter GNAT Project Manager |
| |
| @menu |
| * Introduction:: |
| * Examples of Project Files:: |
| * Project File Syntax:: |
| * Objects and Sources in Project Files:: |
| * Importing Projects:: |
| * Project Extension:: |
| * Project Hierarchy Extension:: |
| * External References in Project Files:: |
| * Packages in Project Files:: |
| * Variables from Imported Projects:: |
| * Naming Schemes:: |
| * Library Projects:: |
| * Stand-alone Library Projects:: |
| * Switches Related to Project Files:: |
| * Tools Supporting Project Files:: |
| * An Extended Example:: |
| * Project File Complete Syntax:: |
| @end menu |
| |
| @c **************** |
| @c * Introduction * |
| @c **************** |
| |
| @node Introduction |
| @section Introduction |
| |
| @noindent |
| This chapter describes GNAT's @emph{Project Manager}, a facility that allows |
| you to manage complex builds involving a number of source files, directories, |
| and compilation options for different system configurations. In particular, |
| project files allow you to specify: |
| @itemize @bullet |
| @item |
| The directory or set of directories containing the source files, and/or the |
| names of the specific source files themselves |
| @item |
| The directory in which the compiler's output |
| (@file{ALI} files, object files, tree files) is to be placed |
| @item |
| The directory in which the executable programs is to be placed |
| @item |
| ^Switch^Switch^ settings for any of the project-enabled tools |
| (@command{gnatmake}, compiler, binder, linker, @code{gnatls}, @code{gnatxref}, |
| @code{gnatfind}); you can apply these settings either globally or to individual |
| compilation units. |
| @item |
| The source files containing the main subprogram(s) to be built |
| @item |
| The source programming language(s) (currently Ada and/or C) |
| @item |
| Source file naming conventions; you can specify these either globally or for |
| individual compilation units |
| @end itemize |
| |
| @menu |
| * Project Files:: |
| @end menu |
| |
| @node Project Files |
| @subsection Project Files |
| |
| @noindent |
| Project files are written in a syntax close to that of Ada, using familiar |
| notions such as packages, context clauses, declarations, default values, |
| assignments, and inheritance. Finally, project files can be built |
| hierarchically from other project files, simplifying complex system |
| integration and project reuse. |
| |
| A @dfn{project} is a specific set of values for various compilation properties. |
| The settings for a given project are described by means of |
| a @dfn{project file}, which is a text file written in an Ada-like syntax. |
| Property values in project files are either strings or lists of strings. |
| Properties that are not explicitly set receive default values. A project |
| file may interrogate the values of @dfn{external variables} (user-defined |
| command-line switches or environment variables), and it may specify property |
| settings conditionally, based on the value of such variables. |
| |
| In simple cases, a project's source files depend only on other source files |
| in the same project, or on the predefined libraries. (@emph{Dependence} is |
| used in |
| the Ada technical sense; as in one Ada unit @code{with}ing another.) However, |
| the Project Manager also allows more sophisticated arrangements, |
| where the source files in one project depend on source files in other |
| projects: |
| @itemize @bullet |
| @item |
| One project can @emph{import} other projects containing needed source files. |
| @item |
| You can organize GNAT projects in a hierarchy: a @emph{child} project |
| can extend a @emph{parent} project, inheriting the parent's source files and |
| optionally overriding any of them with alternative versions |
| @end itemize |
| |
| @noindent |
| More generally, the Project Manager lets you structure large development |
| efforts into hierarchical subsystems, where build decisions are delegated |
| to the subsystem level, and thus different compilation environments |
| (^switch^switch^ settings) used for different subsystems. |
| |
| The Project Manager is invoked through the |
| @option{^-P^/PROJECT_FILE=^@emph{projectfile}} |
| switch to @command{gnatmake} or to the @command{^gnat^GNAT^} front driver. |
| @ifclear vms |
| There may be zero, one or more spaces between @option{-P} and |
| @option{@emph{projectfile}}. |
| @end ifclear |
| If you want to define (on the command line) an external variable that is |
| queried by the project file, you must use the |
| @option{^-X^/EXTERNAL_REFERENCE=^@emph{vbl}=@emph{value}} switch. |
| The Project Manager parses and interprets the project file, and drives the |
| invoked tool based on the project settings. |
| |
| The Project Manager supports a wide range of development strategies, |
| for systems of all sizes. Here are some typical practices that are |
| easily handled: |
| @itemize @bullet |
| @item |
| Using a common set of source files, but generating object files in different |
| directories via different ^switch^switch^ settings |
| @item |
| Using a mostly-shared set of source files, but with different versions of |
| some unit or units |
| @end itemize |
| |
| @noindent |
| The destination of an executable can be controlled inside a project file |
| using the @option{^-o^-o^} |
| ^switch^switch^. |
| In the absence of such a ^switch^switch^ either inside |
| the project file or on the command line, any executable files generated by |
| @command{gnatmake} are placed in the directory @code{Exec_Dir} specified |
| in the project file. If no @code{Exec_Dir} is specified, they will be placed |
| in the object directory of the project. |
| |
| You can use project files to achieve some of the effects of a source |
| versioning system (for example, defining separate projects for |
| the different sets of sources that comprise different releases) but the |
| Project Manager is independent of any source configuration management tools |
| that might be used by the developers. |
| |
| The next section introduces the main features of GNAT's project facility |
| through a sequence of examples; subsequent sections will present the syntax |
| and semantics in more detail. A more formal description of the project |
| facility appears in the GNAT Reference Manual. |
| |
| @c ***************************** |
| @c * Examples of Project Files * |
| @c ***************************** |
| |
| @node Examples of Project Files |
| @section Examples of Project Files |
| @noindent |
| This section illustrates some of the typical uses of project files and |
| explains their basic structure and behavior. |
| |
| @menu |
| * Common Sources with Different ^Switches^Switches^ and Directories:: |
| * Using External Variables:: |
| * Importing Other Projects:: |
| * Extending a Project:: |
| @end menu |
| |
| @node Common Sources with Different ^Switches^Switches^ and Directories |
| @subsection Common Sources with Different ^Switches^Switches^ and Directories |
| |
| @menu |
| * Source Files:: |
| * Specifying the Object Directory:: |
| * Specifying the Exec Directory:: |
| * Project File Packages:: |
| * Specifying ^Switch^Switch^ Settings:: |
| * Main Subprograms:: |
| * Executable File Names:: |
| * Source File Naming Conventions:: |
| * Source Language(s):: |
| @end menu |
| |
| @noindent |
| Suppose that the Ada source files @file{pack.ads}, @file{pack.adb}, and |
| @file{proc.adb} are in the @file{/common} directory. The file |
| @file{proc.adb} contains an Ada main subprogram @code{Proc} that @code{with}s |
| package @code{Pack}. We want to compile these source files under two sets |
| of ^switches^switches^: |
| @itemize @bullet |
| @item |
| When debugging, we want to pass the @option{-g} switch to @command{gnatmake}, |
| and the @option{^-gnata^-gnata^}, |
| @option{^-gnato^-gnato^}, |
| and @option{^-gnatE^-gnatE^} switches to the |
| compiler; the compiler's output is to appear in @file{/common/debug} |
| @item |
| When preparing a release version, we want to pass the @option{^-O2^O2^} switch |
| to the compiler; the compiler's output is to appear in @file{/common/release} |
| @end itemize |
| |
| @noindent |
| The GNAT project files shown below, respectively @file{debug.gpr} and |
| @file{release.gpr} in the @file{/common} directory, achieve these effects. |
| |
| Schematically: |
| @smallexample |
| @group |
| ^/common^[COMMON]^ |
| debug.gpr |
| release.gpr |
| pack.ads |
| pack.adb |
| proc.adb |
| @end group |
| @group |
| ^/common/debug^[COMMON.DEBUG]^ |
| proc.ali, proc.o |
| pack.ali, pack.o |
| @end group |
| @group |
| ^/common/release^[COMMON.RELEASE]^ |
| proc.ali, proc.o |
| pack.ali, pack.o |
| @end group |
| @end smallexample |
| Here are the corresponding project files: |
| |
| @smallexample @c projectfile |
| @group |
| project Debug is |
| for Object_Dir use "debug"; |
| for Main use ("proc"); |
| |
| package Builder is |
| for ^Default_Switches^Default_Switches^ ("Ada") |
| use ("^-g^-g^"); |
| for Executable ("proc.adb") use "proc1"; |
| end Builder; |
| @end group |
| |
| @group |
| package Compiler is |
| for ^Default_Switches^Default_Switches^ ("Ada") |
| use ("-fstack-check", |
| "^-gnata^-gnata^", |
| "^-gnato^-gnato^", |
| "^-gnatE^-gnatE^"); |
| end Compiler; |
| end Debug; |
| @end group |
| @end smallexample |
| |
| @smallexample @c projectfile |
| @group |
| project Release is |
| for Object_Dir use "release"; |
| for Exec_Dir use "."; |
| for Main use ("proc"); |
| |
| package Compiler is |
| for ^Default_Switches^Default_Switches^ ("Ada") |
| use ("^-O2^-O2^"); |
| end Compiler; |
| end Release; |
| @end group |
| @end smallexample |
| |
| @noindent |
| The name of the project defined by @file{debug.gpr} is @code{"Debug"} (case |
| insensitive), and analogously the project defined by @file{release.gpr} is |
| @code{"Release"}. For consistency the file should have the same name as the |
| project, and the project file's extension should be @code{"gpr"}. These |
| conventions are not required, but a warning is issued if they are not followed. |
| |
| If the current directory is @file{^/temp^[TEMP]^}, then the command |
| @smallexample |
| gnatmake ^-P/common/debug.gpr^/PROJECT_FILE=[COMMON]DEBUG^ |
| @end smallexample |
| |
| @noindent |
| generates object and ALI files in @file{^/common/debug^[COMMON.DEBUG]^}, |
| as well as the @code{^proc1^PROC1.EXE^} executable, |
| using the ^switch^switch^ settings defined in the project file. |
| |
| Likewise, the command |
| @smallexample |
| gnatmake ^-P/common/release.gpr^/PROJECT_FILE=[COMMON]RELEASE^ |
| @end smallexample |
| |
| @noindent |
| generates object and ALI files in @file{^/common/release^[COMMON.RELEASE]^}, |
| and the @code{^proc^PROC.EXE^} |
| executable in @file{^/common^[COMMON]^}, |
| using the ^switch^switch^ settings from the project file. |
| |
| @node Source Files |
| @unnumberedsubsubsec Source Files |
| |
| @noindent |
| If a project file does not explicitly specify a set of source directories or |
| a set of source files, then by default the project's source files are the |
| Ada source files in the project file directory. Thus @file{pack.ads}, |
| @file{pack.adb}, and @file{proc.adb} are the source files for both projects. |
| |
| @node Specifying the Object Directory |
| @unnumberedsubsubsec Specifying the Object Directory |
| |
| @noindent |
| Several project properties are modeled by Ada-style @emph{attributes}; |
| a property is defined by supplying the equivalent of an Ada attribute |
| definition clause in the project file. |
| A project's object directory is another such a property; the corresponding |
| attribute is @code{Object_Dir}, and its value is also a string expression, |
| specified either as absolute or relative. In the later case, |
| it is relative to the project file directory. Thus the compiler's |
| output is directed to @file{^/common/debug^[COMMON.DEBUG]^} |
| (for the @code{Debug} project) |
| and to @file{^/common/release^[COMMON.RELEASE]^} |
| (for the @code{Release} project). |
| If @code{Object_Dir} is not specified, then the default is the project file |
| directory itself. |
| |
| @node Specifying the Exec Directory |
| @unnumberedsubsubsec Specifying the Exec Directory |
| |
| @noindent |
| A project's exec directory is another property; the corresponding |
| attribute is @code{Exec_Dir}, and its value is also a string expression, |
| either specified as relative or absolute. If @code{Exec_Dir} is not specified, |
| then the default is the object directory (which may also be the project file |
| directory if attribute @code{Object_Dir} is not specified). Thus the executable |
| is placed in @file{^/common/debug^[COMMON.DEBUG]^} |
| for the @code{Debug} project (attribute @code{Exec_Dir} not specified) |
| and in @file{^/common^[COMMON]^} for the @code{Release} project. |
| |
| @node Project File Packages |
| @unnumberedsubsubsec Project File Packages |
| |
| @noindent |
| A GNAT tool that is integrated with the Project Manager is modeled by a |
| corresponding package in the project file. In the example above, |
| The @code{Debug} project defines the packages @code{Builder} |
| (for @command{gnatmake}) and @code{Compiler}; |
| the @code{Release} project defines only the @code{Compiler} package. |
| |
| The Ada-like package syntax is not to be taken literally. Although packages in |
| project files bear a surface resemblance to packages in Ada source code, the |
| notation is simply a way to convey a grouping of properties for a named |
| entity. Indeed, the package names permitted in project files are restricted |
| to a predefined set, corresponding to the project-aware tools, and the contents |
| of packages are limited to a small set of constructs. |
| The packages in the example above contain attribute definitions. |
| |
| @node Specifying ^Switch^Switch^ Settings |
| @unnumberedsubsubsec Specifying ^Switch^Switch^ Settings |
| |
| @noindent |
| ^Switch^Switch^ settings for a project-aware tool can be specified through |
| attributes in the package that corresponds to the tool. |
| The example above illustrates one of the relevant attributes, |
| @code{^Default_Switches^Default_Switches^}, which is defined in packages |
| in both project files. |
| Unlike simple attributes like @code{Source_Dirs}, |
| @code{^Default_Switches^Default_Switches^} is |
| known as an @emph{associative array}. When you define this attribute, you must |
| supply an ``index'' (a literal string), and the effect of the attribute |
| definition is to set the value of the array at the specified index. |
| For the @code{^Default_Switches^Default_Switches^} attribute, |
| the index is a programming language (in our case, Ada), |
| and the value specified (after @code{use}) must be a list |
| of string expressions. |
| |
| The attributes permitted in project files are restricted to a predefined set. |
| Some may appear at project level, others in packages. |
| For any attribute that is an associative array, the index must always be a |
| literal string, but the restrictions on this string (e.g., a file name or a |
| language name) depend on the individual attribute. |
| Also depending on the attribute, its specified value will need to be either a |
| string or a string list. |
| |
| In the @code{Debug} project, we set the switches for two tools, |
| @command{gnatmake} and the compiler, and thus we include the two corresponding |
| packages; each package defines the @code{^Default_Switches^Default_Switches^} |
| attribute with index @code{"Ada"}. |
| Note that the package corresponding to |
| @command{gnatmake} is named @code{Builder}. The @code{Release} project is |
| similar, but only includes the @code{Compiler} package. |
| |
| In project @code{Debug} above, the ^switches^switches^ starting with |
| @option{-gnat} that are specified in package @code{Compiler} |
| could have been placed in package @code{Builder}, since @command{gnatmake} |
| transmits all such ^switches^switches^ to the compiler. |
| |
| @node Main Subprograms |
| @unnumberedsubsubsec Main Subprograms |
| |
| @noindent |
| One of the specifiable properties of a project is a list of files that contain |
| main subprograms. This property is captured in the @code{Main} attribute, |
| whose value is a list of strings. If a project defines the @code{Main} |
| attribute, it is not necessary to identify the main subprogram(s) when |
| invoking @command{gnatmake} (@pxref{gnatmake and Project Files}). |
| |
| @node Executable File Names |
| @unnumberedsubsubsec Executable File Names |
| |
| @noindent |
| By default, the executable file name corresponding to a main source is |
| deduced from the main source file name. Through the attributes |
| @code{Executable} and @code{Executable_Suffix} of package @code{Builder}, |
| it is possible to change this default. |
| In project @code{Debug} above, the executable file name |
| for main source @file{^proc.adb^PROC.ADB^} is |
| @file{^proc1^PROC1.EXE^}. |
| Attribute @code{Executable_Suffix}, when specified, may change the suffix |
| of the executable files, when no attribute @code{Executable} applies: |
| its value replace the platform-specific executable suffix. |
| Attributes @code{Executable} and @code{Executable_Suffix} are the only ways to |
| specify a non default executable file name when several mains are built at once |
| in a single @command{gnatmake} command. |
| |
| @node Source File Naming Conventions |
| @unnumberedsubsubsec Source File Naming Conventions |
| |
| @noindent |
| Since the project files above do not specify any source file naming |
| conventions, the GNAT defaults are used. The mechanism for defining source |
| file naming conventions -- a package named @code{Naming} -- |
| is described below (@pxref{Naming Schemes}). |
| |
| @node Source Language(s) |
| @unnumberedsubsubsec Source Language(s) |
| |
| @noindent |
| Since the project files do not specify a @code{Languages} attribute, by |
| default the GNAT tools assume that the language of the project file is Ada. |
| More generally, a project can comprise source files |
| in Ada, C, and/or other languages. |
| |
| @node Using External Variables |
| @subsection Using External Variables |
| |
| @noindent |
| Instead of supplying different project files for debug and release, we can |
| define a single project file that queries an external variable (set either |
| on the command line or via an ^environment variable^logical name^) in order to |
| conditionally define the appropriate settings. Again, assume that the |
| source files @file{pack.ads}, @file{pack.adb}, and @file{proc.adb} are |
| located in directory @file{^/common^[COMMON]^}. The following project file, |
| @file{build.gpr}, queries the external variable named @code{STYLE} and |
| defines an object directory and ^switch^switch^ settings based on whether |
| the value is @code{"deb"} (debug) or @code{"rel"} (release), and where |
| the default is @code{"deb"}. |
| |
| @smallexample @c projectfile |
| @group |
| project Build is |
| for Main use ("proc"); |
| |
| type Style_Type is ("deb", "rel"); |
| Style : Style_Type := external ("STYLE", "deb"); |
| |
| case Style is |
| when "deb" => |
| for Object_Dir use "debug"; |
| |
| when "rel" => |
| for Object_Dir use "release"; |
| for Exec_Dir use "."; |
| end case; |
| @end group |
| |
| @group |
| package Builder is |
| |
| case Style is |
| when "deb" => |
| for ^Default_Switches^Default_Switches^ ("Ada") |
| use ("^-g^-g^"); |
| for Executable ("proc") use "proc1"; |
| when others => |
| null; |
| end case; |
| |
| end Builder; |
| @end group |
| |
| @group |
| package Compiler is |
| |
| case Style is |
| when "deb" => |
| for ^Default_Switches^Default_Switches^ ("Ada") |
| use ("^-gnata^-gnata^", |
| "^-gnato^-gnato^", |
| "^-gnatE^-gnatE^"); |
| |
| when "rel" => |
| for ^Default_Switches^Default_Switches^ ("Ada") |
| use ("^-O2^-O2^"); |
| end case; |
| |
| end Compiler; |
| |
| end Build; |
| @end group |
| @end smallexample |
| |
| @noindent |
| @code{Style_Type} is an example of a @emph{string type}, which is the project |
| file analog of an Ada enumeration type but whose components are string literals |
| rather than identifiers. @code{Style} is declared as a variable of this type. |
| |
| The form @code{external("STYLE", "deb")} is known as an |
| @emph{external reference}; its first argument is the name of an |
| @emph{external variable}, and the second argument is a default value to be |
| used if the external variable doesn't exist. You can define an external |
| variable on the command line via the @option{^-X^/EXTERNAL_REFERENCE^} switch, |
| or you can use ^an environment variable^a logical name^ |
| as an external variable. |
| |
| Each @code{case} construct is expanded by the Project Manager based on the |
| value of @code{Style}. Thus the command |
| @ifclear vms |
| @smallexample |
| gnatmake -P/common/build.gpr -XSTYLE=deb |
| @end smallexample |
| @end ifclear |
| |
| @ifset vms |
| @smallexample |
| gnatmake /PROJECT_FILE=[COMMON]BUILD.GPR /EXTERNAL_REFERENCE=STYLE=deb |
| @end smallexample |
| @end ifset |
| |
| @noindent |
| is equivalent to the @command{gnatmake} invocation using the project file |
| @file{debug.gpr} in the earlier example. So is the command |
| @smallexample |
| gnatmake ^-P/common/build.gpr^/PROJECT_FILE=[COMMON]BUILD.GPR^ |
| @end smallexample |
| |
| @noindent |
| since @code{"deb"} is the default for @code{STYLE}. |
| |
| Analogously, |
| |
| @ifclear vms |
| @smallexample |
| gnatmake -P/common/build.gpr -XSTYLE=rel |
| @end smallexample |
| @end ifclear |
| |
| @ifset vms |
| @smallexample |
| GNAT MAKE /PROJECT_FILE=[COMMON]BUILD.GPR /EXTERNAL_REFERENCE=STYLE=rel |
| @end smallexample |
| @end ifset |
| |
| @noindent |
| is equivalent to the @command{gnatmake} invocation using the project file |
| @file{release.gpr} in the earlier example. |
| |
| @node Importing Other Projects |
| @subsection Importing Other Projects |
| @cindex @code{ADA_PROJECT_PATH} |
| |
| @noindent |
| A compilation unit in a source file in one project may depend on compilation |
| units in source files in other projects. To compile this unit under |
| control of a project file, the |
| dependent project must @emph{import} the projects containing the needed source |
| files. |
| This effect is obtained using syntax similar to an Ada @code{with} clause, |
| but where @code{with}ed entities are strings that denote project files. |
| |
| As an example, suppose that the two projects @code{GUI_Proj} and |
| @code{Comm_Proj} are defined in the project files @file{gui_proj.gpr} and |
| @file{comm_proj.gpr} in directories @file{^/gui^[GUI]^} |
| and @file{^/comm^[COMM]^}, respectively. |
| Suppose that the source files for @code{GUI_Proj} are |
| @file{gui.ads} and @file{gui.adb}, and that the source files for |
| @code{Comm_Proj} are @file{comm.ads} and @file{comm.adb}, where each set of |
| files is located in its respective project file directory. Schematically: |
| |
| @smallexample |
| @group |
| ^/gui^[GUI]^ |
| gui_proj.gpr |
| gui.ads |
| gui.adb |
| @end group |
| |
| @group |
| ^/comm^[COMM]^ |
| comm_proj.gpr |
| comm.ads |
| comm.adb |
| @end group |
| @end smallexample |
| |
| @noindent |
| We want to develop an application in directory @file{^/app^[APP]^} that |
| @code{with} the packages @code{GUI} and @code{Comm}, using the properties of |
| the corresponding project files (e.g. the ^switch^switch^ settings |
| and object directory). |
| Skeletal code for a main procedure might be something like the following: |
| |
| @smallexample @c ada |
| @group |
| with GUI, Comm; |
| procedure App_Main is |
| ... |
| begin |
| ... |
| end App_Main; |
| @end group |
| @end smallexample |
| |
| @noindent |
| Here is a project file, @file{app_proj.gpr}, that achieves the desired |
| effect: |
| |
| @smallexample @c projectfile |
| @group |
| with "/gui/gui_proj", "/comm/comm_proj"; |
| project App_Proj is |
| for Main use ("app_main"); |
| end App_Proj; |
| @end group |
| @end smallexample |
| |
| @noindent |
| Building an executable is achieved through the command: |
| @smallexample |
| gnatmake ^-P/app/app_proj^/PROJECT_FILE=[APP]APP_PROJ^ |
| @end smallexample |
| @noindent |
| which will generate the @code{^app_main^APP_MAIN.EXE^} executable |
| in the directory where @file{app_proj.gpr} resides. |
| |
| If an imported project file uses the standard extension (@code{^gpr^GPR^}) then |
| (as illustrated above) the @code{with} clause can omit the extension. |
| |
| Our example specified an absolute path for each imported project file. |
| Alternatively, the directory name of an imported object can be omitted |
| if either |
| @itemize @bullet |
| @item |
| The imported project file is in the same directory as the importing project |
| file, or |
| @item |
| You have defined ^an environment variable^a logical name^ |
| that includes the directory containing |
| the needed project file. The syntax of @code{ADA_PROJECT_PATH} is the same as |
| the syntax of @code{ADA_INCLUDE_PATH} and @code{ADA_OBJECTS_PATH}: a list of |
| directory names separated by colons (semicolons on Windows). |
| @end itemize |
| |
| @noindent |
| Thus, if we define @code{ADA_PROJECT_PATH} to include @file{^/gui^[GUI]^} and |
| @file{^/comm^[COMM]^}, then our project file @file{app_proj.gpr} can be written |
| as follows: |
| |
| @smallexample @c projectfile |
| @group |
| with "gui_proj", "comm_proj"; |
| project App_Proj is |
| for Main use ("app_main"); |
| end App_Proj; |
| @end group |
| @end smallexample |
| |
| @noindent |
| Importing other projects can create ambiguities. |
| For example, the same unit might be present in different imported projects, or |
| it might be present in both the importing project and in an imported project. |
| Both of these conditions are errors. Note that in the current version of |
| the Project Manager, it is illegal to have an ambiguous unit even if the |
| unit is never referenced by the importing project. This restriction may be |
| relaxed in a future release. |
| |
| @node Extending a Project |
| @subsection Extending a Project |
| |
| @noindent |
| In large software systems it is common to have multiple |
| implementations of a common interface; in Ada terms, multiple versions of a |
| package body for the same specification. For example, one implementation |
| might be safe for use in tasking programs, while another might only be used |
| in sequential applications. This can be modeled in GNAT using the concept |
| of @emph{project extension}. If one project (the ``child'') @emph{extends} |
| another project (the ``parent'') then by default all source files of the |
| parent project are inherited by the child, but the child project can |
| override any of the parent's source files with new versions, and can also |
| add new files. This facility is the project analog of a type extension in |
| Object-Oriented Programming. Project hierarchies are permitted (a child |
| project may be the parent of yet another project), and a project that |
| inherits one project can also import other projects. |
| |
| As an example, suppose that directory @file{^/seq^[SEQ]^} contains the project |
| file @file{seq_proj.gpr} as well as the source files @file{pack.ads}, |
| @file{pack.adb}, and @file{proc.adb}: |
| |
| @smallexample |
| @group |
| ^/seq^[SEQ]^ |
| pack.ads |
| pack.adb |
| proc.adb |
| seq_proj.gpr |
| @end group |
| @end smallexample |
| |
| @noindent |
| Note that the project file can simply be empty (that is, no attribute or |
| package is defined): |
| |
| @smallexample @c projectfile |
| @group |
| project Seq_Proj is |
| end Seq_Proj; |
| @end group |
| @end smallexample |
| |
| @noindent |
| implying that its source files are all the Ada source files in the project |
| directory. |
| |
| Suppose we want to supply an alternate version of @file{pack.adb}, in |
| directory @file{^/tasking^[TASKING]^}, but use the existing versions of |
| @file{pack.ads} and @file{proc.adb}. We can define a project |
| @code{Tasking_Proj} that inherits @code{Seq_Proj}: |
| |
| @smallexample |
| @group |
| ^/tasking^[TASKING]^ |
| pack.adb |
| tasking_proj.gpr |
| @end group |
| |
| @group |
| project Tasking_Proj extends "/seq/seq_proj" is |
| end Tasking_Proj; |
| @end group |
| @end smallexample |
| |
| @noindent |
| The version of @file{pack.adb} used in a build depends on which project file |
| is specified. |
| |
| Note that we could have obtained the desired behavior using project import |
| rather than project inheritance; a @code{base} project would contain the |
| sources for @file{pack.ads} and @file{proc.adb}, a sequential project would |
| import @code{base} and add @file{pack.adb}, and likewise a tasking project |
| would import @code{base} and add a different version of @file{pack.adb}. The |
| choice depends on whether other sources in the original project need to be |
| overridden. If they do, then project extension is necessary, otherwise, |
| importing is sufficient. |
| |
| @noindent |
| In a project file that extends another project file, it is possible to |
| indicate that an inherited source is not part of the sources of the extending |
| project. This is necessary sometimes when a package spec has been overloaded |
| and no longer requires a body: in this case, it is necessary to indicate that |
| the inherited body is not part of the sources of the project, otherwise there |
| will be a compilation error when compiling the spec. |
| |
| For that purpose, the attribute @code{Locally_Removed_Files} is used. |
| Its value is a string list: a list of file names. |
| |
| @smallexample @c @projectfile |
| project B extends "a" is |
| for Source_Files use ("pkg.ads"); |
| -- New spec of Pkg does not need a completion |
| for Locally_Removed_Files use ("pkg.adb"); |
| end B; |
| @end smallexample |
| |
| Attribute @code{Locally_Removed_Files} may also be used to check if a source |
| is still needed: if it is possible to build using @command{gnatmake} when such |
| a source is put in attribute @code{Locally_Removed_Files} of a project P, then |
| it is possible to remove the source completely from a system that includes |
| project P. |
| |
| @c *********************** |
| @c * Project File Syntax * |
| @c *********************** |
| |
| @node Project File Syntax |
| @section Project File Syntax |
| |
| @menu |
| * Basic Syntax:: |
| * Packages:: |
| * Expressions:: |
| * String Types:: |
| * Variables:: |
| * Attributes:: |
| * Associative Array Attributes:: |
| * case Constructions:: |
| @end menu |
| |
| @noindent |
| This section describes the structure of project files. |
| |
| A project may be an @emph{independent project}, entirely defined by a single |
| project file. Any Ada source file in an independent project depends only |
| on the predefined library and other Ada source files in the same project. |
| |
| @noindent |
| A project may also @dfn{depend on} other projects, in either or both of |
| the following ways: |
| @itemize @bullet |
| @item It may import any number of projects |
| @item It may extend at most one other project |
| @end itemize |
| |
| @noindent |
| The dependence relation is a directed acyclic graph (the subgraph reflecting |
| the ``extends'' relation is a tree). |
| |
| A project's @dfn{immediate sources} are the source files directly defined by |
| that project, either implicitly by residing in the project file's directory, |
| or explicitly through any of the source-related attributes described below. |
| More generally, a project @var{proj}'s @dfn{sources} are the immediate sources |
| of @var{proj} together with the immediate sources (unless overridden) of any |
| project on which @var{proj} depends (either directly or indirectly). |
| |
| @node Basic Syntax |
| @subsection Basic Syntax |
| |
| @noindent |
| As seen in the earlier examples, project files have an Ada-like syntax. |
| The minimal project file is: |
| @smallexample @c projectfile |
| @group |
| project Empty is |
| |
| end Empty; |
| @end group |
| @end smallexample |
| |
| @noindent |
| The identifier @code{Empty} is the name of the project. |
| This project name must be present after the reserved |
| word @code{end} at the end of the project file, followed by a semi-colon. |
| |
| Any name in a project file, such as the project name or a variable name, |
| has the same syntax as an Ada identifier. |
| |
| The reserved words of project files are the Ada reserved words plus |
| @code{extends}, @code{external}, and @code{project}. Note that the only Ada |
| reserved words currently used in project file syntax are: |
| |
| @itemize @bullet |
| @item |
| @code{case} |
| @item |
| @code{end} |
| @item |
| @code{for} |
| @item |
| @code{is} |
| @item |
| @code{others} |
| @item |
| @code{package} |
| @item |
| @code{renames} |
| @item |
| @code{type} |
| @item |
| @code{use} |
| @item |
| @code{when} |
| @item |
| @code{with} |
| @end itemize |
| |
| @noindent |
| Comments in project files have the same syntax as in Ada, two consecutives |
| hyphens through the end of the line. |
| |
| @node Packages |
| @subsection Packages |
| |
| @noindent |
| A project file may contain @emph{packages}. The name of a package must be one |
| of the identifiers from the following list. A package |
| with a given name may only appear once in a project file. Package names are |
| case insensitive. The following package names are legal: |
| |
| @itemize @bullet |
| @item |
| @code{Naming} |
| @item |
| @code{Builder} |
| @item |
| @code{Compiler} |
| @item |
| @code{Binder} |
| @item |
| @code{Linker} |
| @item |
| @code{Finder} |
| @item |
| @code{Cross_Reference} |
| @item |
| @code{Eliminate} |
| @item |
| @code{Pretty_Printer} |
| @item |
| @code{Metrics} |
| @item |
| @code{gnatls} |
| @item |
| @code{gnatstub} |
| @item |
| @code{IDE} |
| @item |
| @code{Language_Processing} |
| @end itemize |
| |
| @noindent |
| In its simplest form, a package may be empty: |
| |
| @smallexample @c projectfile |
| @group |
| project Simple is |
| package Builder is |
| end Builder; |
| end Simple; |
| @end group |
| @end smallexample |
| |
| @noindent |
| A package may contain @emph{attribute declarations}, |
| @emph{variable declarations} and @emph{case constructions}, as will be |
| described below. |
| |
| When there is ambiguity between a project name and a package name, |
| the name always designates the project. To avoid possible confusion, it is |
| always a good idea to avoid naming a project with one of the |
| names allowed for packages or any name that starts with @code{gnat}. |
| |
| @node Expressions |
| @subsection Expressions |
| |
| @noindent |
| An @emph{expression} is either a @emph{string expression} or a |
| @emph{string list expression}. |
| |
| A @emph{string expression} is either a @emph{simple string expression} or a |
| @emph{compound string expression}. |
| |
| A @emph{simple string expression} is one of the following: |
| @itemize @bullet |
| @item A literal string; e.g.@code{"comm/my_proj.gpr"} |
| @item A string-valued variable reference (@pxref{Variables}) |
| @item A string-valued attribute reference (@pxref{Attributes}) |
| @item An external reference (@pxref{External References in Project Files}) |
| @end itemize |
| |
| @noindent |
| A @emph{compound string expression} is a concatenation of string expressions, |
| using the operator @code{"&"} |
| @smallexample |
| Path & "/" & File_Name & ".ads" |
| @end smallexample |
| |
| @noindent |
| A @emph{string list expression} is either a |
| @emph{simple string list expression} or a |
| @emph{compound string list expression}. |
| |
| A @emph{simple string list expression} is one of the following: |
| @itemize @bullet |
| @item A parenthesized list of zero or more string expressions, |
| separated by commas |
| @smallexample |
| File_Names := (File_Name, "gnat.adc", File_Name & ".orig"); |
| Empty_List := (); |
| @end smallexample |
| @item A string list-valued variable reference |
| @item A string list-valued attribute reference |
| @end itemize |
| |
| @noindent |
| A @emph{compound string list expression} is the concatenation (using |
| @code{"&"}) of a simple string list expression and an expression. Note that |
| each term in a compound string list expression, except the first, may be |
| either a string expression or a string list expression. |
| |
| @smallexample @c projectfile |
| @group |
| File_Name_List := () & File_Name; -- One string in this list |
| Extended_File_Name_List := File_Name_List & (File_Name & ".orig"); |
| -- Two strings |
| Big_List := File_Name_List & Extended_File_Name_List; |
| -- Concatenation of two string lists: three strings |
| Illegal_List := "gnat.adc" & Extended_File_Name_List; |
| -- Illegal: must start with a string list |
| @end group |
| @end smallexample |
| |
| @node String Types |
| @subsection String Types |
| |
| @noindent |
| A @emph{string type declaration} introduces a discrete set of string literals. |
| If a string variable is declared to have this type, its value |
| is restricted to the given set of literals. |
| |
| Here is an example of a string type declaration: |
| |
| @smallexample @c projectfile |
| type OS is ("NT", "nt", "Unix", "GNU/Linux", "other OS"); |
| @end smallexample |
| |
| @noindent |
| Variables of a string type are called @emph{typed variables}; all other |
| variables are called @emph{untyped variables}. Typed variables are |
| particularly useful in @code{case} constructions, to support conditional |
| attribute declarations. |
| (@pxref{case Constructions}). |
| |
| The string literals in the list are case sensitive and must all be different. |
| They may include any graphic characters allowed in Ada, including spaces. |
| |
| A string type may only be declared at the project level, not inside a package. |
| |
| A string type may be referenced by its name if it has been declared in the same |
| project file, or by an expanded name whose prefix is the name of the project |
| in which it is declared. |
| |
| @node Variables |
| @subsection Variables |
| |
| @noindent |
| A variable may be declared at the project file level, or within a package. |
| Here are some examples of variable declarations: |
| |
| @smallexample @c projectfile |
| @group |
| This_OS : OS := external ("OS"); -- a typed variable declaration |
| That_OS := "GNU/Linux"; -- an untyped variable declaration |
| @end group |
| @end smallexample |
| |
| @noindent |
| The syntax of a @emph{typed variable declaration} is identical to the Ada |
| syntax for an object declaration. By contrast, the syntax of an untyped |
| variable declaration is identical to an Ada assignment statement. In fact, |
| variable declarations in project files have some of the characteristics of |
| an assignment, in that successive declarations for the same variable are |
| allowed. Untyped variable declarations do establish the expected kind of the |
| variable (string or string list), and successive declarations for it must |
| respect the initial kind. |
| |
| @noindent |
| A string variable declaration (typed or untyped) declares a variable |
| whose value is a string. This variable may be used as a string expression. |
| @smallexample @c projectfile |
| File_Name := "readme.txt"; |
| Saved_File_Name := File_Name & ".saved"; |
| @end smallexample |
| |
| @noindent |
| A string list variable declaration declares a variable whose value is a list |
| of strings. The list may contain any number (zero or more) of strings. |
| |
| @smallexample @c projectfile |
| Empty_List := (); |
| List_With_One_Element := ("^-gnaty^-gnaty^"); |
| List_With_Two_Elements := List_With_One_Element & "^-gnatg^-gnatg^"; |
| Long_List := ("main.ada", "pack1_.ada", "pack1.ada", "pack2_.ada" |
| "pack2.ada", "util_.ada", "util.ada"); |
| @end smallexample |
| |
| @noindent |
| The same typed variable may not be declared more than once at project level, |
| and it may not be declared more than once in any package; it is in effect |
| a constant. |
| |
| The same untyped variable may be declared several times. Declarations are |
| elaborated in the order in which they appear, so the new value replaces |
| the old one, and any subsequent reference to the variable uses the new value. |
| However, as noted above, if a variable has been declared as a string, all |
| subsequent |
| declarations must give it a string value. Similarly, if a variable has |
| been declared as a string list, all subsequent declarations |
| must give it a string list value. |
| |
| A @emph{variable reference} may take several forms: |
| |
| @itemize @bullet |
| @item The simple variable name, for a variable in the current package (if any) |
| or in the current project |
| @item An expanded name, whose prefix is a context name. |
| @end itemize |
| |
| @noindent |
| A @emph{context} may be one of the following: |
| |
| @itemize @bullet |
| @item The name of an existing package in the current project |
| @item The name of an imported project of the current project |
| @item The name of an ancestor project (i.e., a project extended by the current |
| project, either directly or indirectly) |
| @item An expanded name whose prefix is an imported/parent project name, and |
| whose selector is a package name in that project. |
| @end itemize |
| |
| @noindent |
| A variable reference may be used in an expression. |
| |
| @node Attributes |
| @subsection Attributes |
| |
| @noindent |
| A project (and its packages) may have @emph{attributes} that define |
| the project's properties. Some attributes have values that are strings; |
| others have values that are string lists. |
| |
| There are two categories of attributes: @emph{simple attributes} |
| and @emph{associative arrays} (@pxref{Associative Array Attributes}). |
| |
| Legal project attribute names, and attribute names for each legal package are |
| listed below. Attributes names are case-insensitive. |
| |
| The following attributes are defined on projects (all are simple attributes): |
| |
| @multitable @columnfractions .4 .3 |
| @item @emph{Attribute Name} |
| @tab @emph{Value} |
| @item @code{Source_Files} |
| @tab string list |
| @item @code{Source_Dirs} |
| @tab string list |
| @item @code{Source_List_File} |
| @tab string |
| @item @code{Object_Dir} |
| @tab string |
| @item @code{Exec_Dir} |
| @tab string |
| @item @code{Locally_Removed_Files} |
| @tab string list |
| @item @code{Languages} |
| @tab string list |
| @item @code{Main} |
| @tab string list |
| @item @code{Library_Dir} |
| @tab string |
| @item @code{Library_Name} |
| @tab string |
| @item @code{Library_Kind} |
| @tab string |
| @item @code{Library_Version} |
| @tab string |
| @item @code{Library_Interface} |
| @tab string |
| @item @code{Library_Auto_Init} |
| @tab string |
| @item @code{Library_Options} |
| @tab string list |
| @item @code{Library_Src_Dir} |
| @tab string |
| @item @code{Library_ALI_Dir} |
| @tab string |
| @item @code{Library_GCC} |
| @tab string |
| @item @code{Library_Symbol_File} |
| @tab string |
| @item @code{Library_Symbol_Policy} |
| @tab string |
| @item @code{Library_Reference_Symbol_File} |
| @tab string |
| @item @code{Externally_Built} |
| @tab string |
| @end multitable |
| |
| @noindent |
| The following attributes are defined for package @code{Naming} |
| (@pxref{Naming Schemes}): |
| |
| @multitable @columnfractions .4 .2 .2 .2 |
| @item Attribute Name @tab Category @tab Index @tab Value |
| @item @code{Spec_Suffix} |
| @tab associative array |
| @tab language name |
| @tab string |
| @item @code{Body_Suffix} |
| @tab associative array |
| @tab language name |
| @tab string |
| @item @code{Separate_Suffix} |
| @tab simple attribute |
| @tab n/a |
| @tab string |
| @item @code{Casing} |
| @tab simple attribute |
| @tab n/a |
| @tab string |
| @item @code{Dot_Replacement} |
| @tab simple attribute |
| @tab n/a |
| @tab string |
| @item @code{Spec} |
| @tab associative array |
| @tab Ada unit name |
| @tab string |
| @item @code{Body} |
| @tab associative array |
| @tab Ada unit name |
| @tab string |
| @item @code{Specification_Exceptions} |
| @tab associative array |
| @tab language name |
| @tab string list |
| @item @code{Implementation_Exceptions} |
| @tab associative array |
| @tab language name |
| @tab string list |
| @end multitable |
| |
| @noindent |
| The following attributes are defined for packages @code{Builder}, |
| @code{Compiler}, @code{Binder}, |
| @code{Linker}, @code{Cross_Reference}, and @code{Finder} |
| (@pxref{^Switches^Switches^ and Project Files}). |
| |
| @multitable @columnfractions .4 .2 .2 .2 |
| @item Attribute Name @tab Category @tab Index @tab Value |
| @item @code{^Default_Switches^Default_Switches^} |
| @tab associative array |
| @tab language name |
| @tab string list |
| @item @code{^Switches^Switches^} |
| @tab associative array |
| @tab file name |
| @tab string list |
| @end multitable |
| |
| @noindent |
| In addition, package @code{Compiler} has a single string attribute |
| @code{Local_Configuration_Pragmas} and package @code{Builder} has a single |
| string attribute @code{Global_Configuration_Pragmas}. |
| |
| @noindent |
| Each simple attribute has a default value: the empty string (for string-valued |
| attributes) and the empty list (for string list-valued attributes). |
| |
| An attribute declaration defines a new value for an attribute. |
| |
| Examples of simple attribute declarations: |
| |
| @smallexample @c projectfile |
| for Object_Dir use "objects"; |
| for Source_Dirs use ("units", "test/drivers"); |
| @end smallexample |
| |
| @noindent |
| The syntax of a @dfn{simple attribute declaration} is similar to that of an |
| attribute definition clause in Ada. |
| |
| Attributes references may be appear in expressions. |
| The general form for such a reference is @code{<entity>'<attribute>}: |
| Associative array attributes are functions. Associative |
| array attribute references must have an argument that is a string literal. |
| |
| Examples are: |
| |
| @smallexample @c projectfile |
| project'Object_Dir |
| Naming'Dot_Replacement |
| Imported_Project'Source_Dirs |
| Imported_Project.Naming'Casing |
| Builder'^Default_Switches^Default_Switches^("Ada") |
| @end smallexample |
| |
| @noindent |
| The prefix of an attribute may be: |
| @itemize @bullet |
| @item @code{project} for an attribute of the current project |
| @item The name of an existing package of the current project |
| @item The name of an imported project |
| @item The name of a parent project that is extended by the current project |
| @item An expanded name whose prefix is imported/parent project name, |
| and whose selector is a package name |
| @end itemize |
| |
| @noindent |
| Example: |
| @smallexample @c projectfile |
| @group |
| project Prj is |
| for Source_Dirs use project'Source_Dirs & "units"; |
| for Source_Dirs use project'Source_Dirs & "test/drivers" |
| end Prj; |
| @end group |
| @end smallexample |
| |
| @noindent |
| In the first attribute declaration, initially the attribute @code{Source_Dirs} |
| has the default value: an empty string list. After this declaration, |
| @code{Source_Dirs} is a string list of one element: @code{"units"}. |
| After the second attribute declaration @code{Source_Dirs} is a string list of |
| two elements: @code{"units"} and @code{"test/drivers"}. |
| |
| Note: this example is for illustration only. In practice, |
| the project file would contain only one attribute declaration: |
| |
| @smallexample @c projectfile |
| for Source_Dirs use ("units", "test/drivers"); |
| @end smallexample |
| |
| @node Associative Array Attributes |
| @subsection Associative Array Attributes |
| |
| @noindent |
| Some attributes are defined as @emph{associative arrays}. An associative |
| array may be regarded as a function that takes a string as a parameter |
| and delivers a string or string list value as its result. |
| |
| Here are some examples of single associative array attribute associations: |
| |
| @smallexample @c projectfile |
| for Body ("main") use "Main.ada"; |
| for ^Switches^Switches^ ("main.ada") |
| use ("^-v^-v^", |
| "^-gnatv^-gnatv^"); |
| for ^Switches^Switches^ ("main.ada") |
| use Builder'^Switches^Switches^ ("main.ada") |
| & "^-g^-g^"; |
| @end smallexample |
| |
| @noindent |
| Like untyped variables and simple attributes, associative array attributes |
| may be declared several times. Each declaration supplies a new value for the |
| attribute, and replaces the previous setting. |
| |
| @noindent |
| An associative array attribute may be declared as a full associative array |
| declaration, with the value of the same attribute in an imported or extended |
| project. |
| |
| @smallexample @c projectfile |
| package Builder is |
| for Default_Switches use Default.Builder'Default_Switches; |
| end Builder; |
| @end smallexample |
| |
| @noindent |
| In this example, @code{Default} must be either a project imported by the |
| current project, or the project that the current project extends. If the |
| attribute is in a package (in this case, in package @code{Builder}), the same |
| package needs to be specified. |
| |
| @noindent |
| A full associative array declaration replaces any other declaration for the |
| attribute, including other full associative array declaration. Single |
| associative array associations may be declare after a full associative |
| declaration, modifying the value for a single association of the attribute. |
| |
| @node case Constructions |
| @subsection @code{case} Constructions |
| |
| @noindent |
| A @code{case} construction is used in a project file to effect conditional |
| behavior. |
| Here is a typical example: |
| |
| @smallexample @c projectfile |
| @group |
| project MyProj is |
| type OS_Type is ("GNU/Linux", "Unix", "NT", "VMS"); |
| |
| OS : OS_Type := external ("OS", "GNU/Linux"); |
| @end group |
| |
| @group |
| package Compiler is |
| case OS is |
| when "GNU/Linux" | "Unix" => |
| for ^Default_Switches^Default_Switches^ ("Ada") |
| use ("^-gnath^-gnath^"); |
| when "NT" => |
| for ^Default_Switches^Default_Switches^ ("Ada") |
| use ("^-gnatP^-gnatP^"); |
| when others => |
| end case; |
| end Compiler; |
| end MyProj; |
| @end group |
| @end smallexample |
| |
| @noindent |
| The syntax of a @code{case} construction is based on the Ada case statement |
| (although there is no @code{null} construction for empty alternatives). |
| |
| The case expression must be a typed string variable. |
| Each alternative comprises the reserved word @code{when}, either a list of |
| literal strings separated by the @code{"|"} character or the reserved word |
| @code{others}, and the @code{"=>"} token. |
| Each literal string must belong to the string type that is the type of the |
| case variable. |
| An @code{others} alternative, if present, must occur last. |
| |
| After each @code{=>}, there are zero or more constructions. The only |
| constructions allowed in a case construction are other case constructions and |
| attribute declarations. String type declarations, variable declarations and |
| package declarations are not allowed. |
| |
| The value of the case variable is often given by an external reference |
| (@pxref{External References in Project Files}). |
| |
| @c **************************************** |
| @c * Objects and Sources in Project Files * |
| @c **************************************** |
| |
| @node Objects and Sources in Project Files |
| @section Objects and Sources in Project Files |
| |
| @menu |
| * Object Directory:: |
| * Exec Directory:: |
| * Source Directories:: |
| * Source File Names:: |
| @end menu |
| |
| @noindent |
| Each project has exactly one object directory and one or more source |
| directories. The source directories must contain at least one source file, |
| unless the project file explicitly specifies that no source files are present |
| (@pxref{Source File Names}). |
| |
| @node Object Directory |
| @subsection Object Directory |
| |
| @noindent |
| The object directory for a project is the directory containing the compiler's |
| output (such as @file{ALI} files and object files) for the project's immediate |
| sources. |
| |
| The object directory is given by the value of the attribute @code{Object_Dir} |
| in the project file. |
| |
| @smallexample @c projectfile |
| for Object_Dir use "objects"; |
| @end smallexample |
| |
| @noindent |
| The attribute @var{Object_Dir} has a string value, the path name of the object |
| directory. The path name may be absolute or relative to the directory of the |
| project file. This directory must already exist, and be readable and writable. |
| |
| By default, when the attribute @code{Object_Dir} is not given an explicit value |
| or when its value is the empty string, the object directory is the same as the |
| directory containing the project file. |
| |
| @node Exec Directory |
| @subsection Exec Directory |
| |
| @noindent |
| The exec directory for a project is the directory containing the executables |
| for the project's main subprograms. |
| |
| The exec directory is given by the value of the attribute @code{Exec_Dir} |
| in the project file. |
| |
| @smallexample @c projectfile |
| for Exec_Dir use "executables"; |
| @end smallexample |
| |
| @noindent |
| The attribute @var{Exec_Dir} has a string value, the path name of the exec |
| directory. The path name may be absolute or relative to the directory of the |
| project file. This directory must already exist, and be writable. |
| |
| By default, when the attribute @code{Exec_Dir} is not given an explicit value |
| or when its value is the empty string, the exec directory is the same as the |
| object directory of the project file. |
| |
| @node Source Directories |
| @subsection Source Directories |
| |
| @noindent |
| The source directories of a project are specified by the project file |
| attribute @code{Source_Dirs}. |
| |
| This attribute's value is a string list. If the attribute is not given an |
| explicit value, then there is only one source directory, the one where the |
| project file resides. |
| |
| A @code{Source_Dirs} attribute that is explicitly defined to be the empty list, |
| as in |
| |
| @smallexample @c projectfile |
| for Source_Dirs use (); |
| @end smallexample |
| |
| @noindent |
| indicates that the project contains no source files. |
| |
| Otherwise, each string in the string list designates one or more |
| source directories. |
| |
| @smallexample @c projectfile |
| for Source_Dirs use ("sources", "test/drivers"); |
| @end smallexample |
| |
| @noindent |
| If a string in the list ends with @code{"/**"}, then the directory whose path |
| name precedes the two asterisks, as well as all its subdirectories |
| (recursively), are source directories. |
| |
| @smallexample @c projectfile |
| for Source_Dirs use ("/system/sources/**"); |
| @end smallexample |
| |
| @noindent |
| Here the directory @code{/system/sources} and all of its subdirectories |
| (recursively) are source directories. |
| |
| To specify that the source directories are the directory of the project file |
| and all of its subdirectories, you can declare @code{Source_Dirs} as follows: |
| @smallexample @c projectfile |
| for Source_Dirs use ("./**"); |
| @end smallexample |
| |
| @noindent |
| Each of the source directories must exist and be readable. |
| |
| @node Source File Names |
| @subsection Source File Names |
| |
| @noindent |
| In a project that contains source files, their names may be specified by the |
| attributes @code{Source_Files} (a string list) or @code{Source_List_File} |
| (a string). Source file names never include any directory information. |
| |
| If the attribute @code{Source_Files} is given an explicit value, then each |
| element of the list is a source file name. |
| |
| @smallexample @c projectfile |
| for Source_Files use ("main.adb"); |
| for Source_Files use ("main.adb", "pack1.ads", "pack2.adb"); |
| @end smallexample |
| |
| @noindent |
| If the attribute @code{Source_Files} is not given an explicit value, |
| but the attribute @code{Source_List_File} is given a string value, |
| then the source file names are contained in the text file whose path name |
| (absolute or relative to the directory of the project file) is the |
| value of the attribute @code{Source_List_File}. |
| |
| Each line in the file that is not empty or is not a comment |
| contains a source file name. |
| |
| @smallexample @c projectfile |
| for Source_List_File use "source_list.txt"; |
| @end smallexample |
| |
| @noindent |
| By default, if neither the attribute @code{Source_Files} nor the attribute |
| @code{Source_List_File} is given an explicit value, then each file in the |
| source directories that conforms to the project's naming scheme |
| (@pxref{Naming Schemes}) is an immediate source of the project. |
| |
| A warning is issued if both attributes @code{Source_Files} and |
| @code{Source_List_File} are given explicit values. In this case, the attribute |
| @code{Source_Files} prevails. |
| |
| Each source file name must be the name of one existing source file |
| in one of the source directories. |
| |
| A @code{Source_Files} attribute whose value is an empty list |
| indicates that there are no source files in the project. |
| |
| If the order of the source directories is known statically, that is if |
| @code{"/**"} is not used in the string list @code{Source_Dirs}, then there may |
| be several files with the same source file name. In this case, only the file |
| in the first directory is considered as an immediate source of the project |
| file. If the order of the source directories is not known statically, it is |
| an error to have several files with the same source file name. |
| |
| Projects can be specified to have no Ada source |
| files: the value of (@code{Source_Dirs} or @code{Source_Files} may be an empty |
| list, or the @code{"Ada"} may be absent from @code{Languages}: |
| |
| @smallexample @c projectfile |
| for Source_Dirs use (); |
| for Source_Files use (); |
| for Languages use ("C", "C++"); |
| @end smallexample |
| |
| @noindent |
| Otherwise, a project must contain at least one immediate source. |
| |
| Projects with no source files are useful as template packages |
| (@pxref{Packages in Project Files}) for other projects; in particular to |
| define a package @code{Naming} (@pxref{Naming Schemes}). |
| |
| @c **************************** |
| @c * Importing Projects * |
| @c **************************** |
| |
| @node Importing Projects |
| @section Importing Projects |
| @cindex @code{ADA_PROJECT_PATH} |
| |
| @noindent |
| An immediate source of a project P may depend on source files that |
| are neither immediate sources of P nor in the predefined library. |
| To get this effect, P must @emph{import} the projects that contain the needed |
| source files. |
| |
| @smallexample @c projectfile |
| @group |
| with "project1", "utilities.gpr"; |
| with "/namings/apex.gpr"; |
| project Main is |
| ... |
| @end group |
| @end smallexample |
| |
| @noindent |
| As can be seen in this example, the syntax for importing projects is similar |
| to the syntax for importing compilation units in Ada. However, project files |
| use literal strings instead of names, and the @code{with} clause identifies |
| project files rather than packages. |
| |
| Each literal string is the file name or path name (absolute or relative) of a |
| project file. If a string corresponds to a file name, with no path or a |
| relative path, then its location is determined by the @emph{project path}. The |
| latter can be queried using @code{gnatls -v}. It contains: |
| |
| @itemize @bullet |
| @item |
| In first position, the directory containing the current project file. |
| @item |
| In last position, the default project directory. This default project directory |
| is part of the GNAT installation and is the standard place to install project |
| files giving access to standard support libraries. |
| @ifclear vms |
| @ref{Installing a library} |
| @end ifclear |
| |
| @item |
| In between, all the directories referenced in the |
| ^environment variable^logical name^ @env{ADA_PROJECT_PATH} if it exists. |
| @end itemize |
| |
| @noindent |
| If a relative pathname is used, as in |
| |
| @smallexample @c projectfile |
| with "tests/proj"; |
| @end smallexample |
| |
| @noindent |
| then the full path for the project is constructed by concatenating this |
| relative path to those in the project path, in order, until a matching file is |
| found. Any symbolic link will be fully resolved in the directory of the |
| importing project file before the imported project file is examined. |
| |
| If the @code{with}'ed project file name does not have an extension, |
| the default is @file{^.gpr^.GPR^}. If a file with this extension is not found, |
| then the file name as specified in the @code{with} clause (no extension) will |
| be used. In the above example, if a file @code{project1.gpr} is found, then it |
| will be used; otherwise, if a file @code{^project1^PROJECT1^} exists |
| then it will be used; if neither file exists, this is an error. |
| |
| A warning is issued if the name of the project file does not match the |
| name of the project; this check is case insensitive. |
| |
| Any source file that is an immediate source of the imported project can be |
| used by the immediate sources of the importing project, transitively. Thus |
| if @code{A} imports @code{B}, and @code{B} imports @code{C}, the immediate |
| sources of @code{A} may depend on the immediate sources of @code{C}, even if |
| @code{A} does not import @code{C} explicitly. However, this is not recommended, |
| because if and when @code{B} ceases to import @code{C}, some sources in |
| @code{A} will no longer compile. |
| |
| A side effect of this capability is that normally cyclic dependencies are not |
| permitted: if @code{A} imports @code{B} (directly or indirectly) then @code{B} |
| is not allowed to import @code{A}. However, there are cases when cyclic |
| dependencies would be beneficial. For these cases, another form of import |
| between projects exists, the @code{limited with}: a project @code{A} that |
| imports a project @code{B} with a straight @code{with} may also be imported, |
| directly or indirectly, by @code{B} on the condition that imports from @code{B} |
| to @code{A} include at least one @code{limited with}. |
| |
| @smallexample @c 0projectfile |
| with "../b/b.gpr"; |
| with "../c/c.gpr"; |
| project A is |
| end A; |
| |
| limited with "../a/a.gpr"; |
| project B is |
| end B; |
| |
| with "../d/d.gpr"; |
| project C is |
| end C; |
| |
| limited with "../a/a.gpr"; |
| project D is |
| end D; |
| @end smallexample |
| |
| @noindent |
| In the above legal example, there are two project cycles: |
| @itemize @bullet |
| @item A-> B-> A |
| @item A -> C -> D -> A |
| @end itemize |
| |
| @noindent |
| In each of these cycle there is one @code{limited with}: import of @code{A} |
| from @code{B} and import of @code{A} from @code{D}. |
| |
| The difference between straight @code{with} and @code{limited with} is that |
| the name of a project imported with a @code{limited with} cannot be used in the |
| project that imports it. In particular, its packages cannot be renamed and |
| its variables cannot be referred to. |
| |
| An exception to the above rules for @code{limited with} is that for the main |
| project specified to @command{gnatmake} or to the @command{GNAT} driver a |
| @code{limited with} is equivalent to a straight @code{with}. For example, |
| in the example above, projects @code{B} and @code{D} could not be main |
| projects for @command{gnatmake} or to the @command{GNAT} driver, because they |
| each have a @code{limited with} that is the only one in a cycle of importing |
| projects. |
| |
| @c ********************* |
| @c * Project Extension * |
| @c ********************* |
| |
| @node Project Extension |
| @section Project Extension |
| |
| @noindent |
| During development of a large system, it is sometimes necessary to use |
| modified versions of some of the source files, without changing the original |
| sources. This can be achieved through the @emph{project extension} facility. |
| |
| @smallexample @c projectfile |
| project Modified_Utilities extends "/baseline/utilities.gpr" is ... |
| @end smallexample |
| |
| @noindent |
| A project extension declaration introduces an extending project |
| (the @emph{child}) and a project being extended (the @emph{parent}). |
| |
| By default, a child project inherits all the sources of its parent. |
| However, inherited sources can be overridden: a unit in a parent is hidden |
| by a unit of the same name in the child. |
| |
| Inherited sources are considered to be sources (but not immediate sources) |
| of the child project; see @ref{Project File Syntax}. |
| |
| An inherited source file retains any switches specified in the parent project. |
| |
| For example if the project @code{Utilities} contains the specification and the |
| body of an Ada package @code{Util_IO}, then the project |
| @code{Modified_Utilities} can contain a new body for package @code{Util_IO}. |
| The original body of @code{Util_IO} will not be considered in program builds. |
| However, the package specification will still be found in the project |
| @code{Utilities}. |
| |
| A child project can have only one parent but it may import any number of other |
| projects. |
| |
| A project is not allowed to import directly or indirectly at the same time a |
| child project and any of its ancestors. |
| |
| @c ******************************* |
| @c * Project Hierarchy Extension * |
| @c ******************************* |
| |
| @node Project Hierarchy Extension |
| @section Project Hierarchy Extension |
| |
| @noindent |
| When extending a large system spanning multiple projects, it is often |
| inconvenient to extend every project in the hierarchy that is impacted by a |
| small change introduced. In such cases, it is possible to create a virtual |
| extension of entire hierarchy using @code{extends all} relationship. |
| |
| When the project is extended using @code{extends all} inheritance, all projects |
| that are imported by it, both directly and indirectly, are considered virtually |
| extended. That is, the Project Manager creates "virtual projects" |
| that extend every project in the hierarchy; all these virtual projects have |
| no sources of their own and have as object directory the object directory of |
| the root of "extending all" project. |
| |
| It is possible to explicitly extend one or more projects in the hierarchy |
| in order to modify the sources. These extending projects must be imported by |
| the "extending all" project, which will replace the corresponding virtual |
| projects with the explicit ones. |
| |
| When building such a project hierarchy extension, the Project Manager will |
| ensure that both modified sources and sources in virtual extending projects |
| that depend on them, are recompiled. |
| |
| By means of example, consider the following hierarchy of projects. |
| |
| @enumerate |
| @item |
| project A, containing package P1 |
| @item |
| project B importing A and containing package P2 which depends on P1 |
| @item |
| project C importing B and containing package P3 which depends on P2 |
| @end enumerate |
| |
| @noindent |
| We want to modify packages P1 and P3. |
| |
| This project hierarchy will need to be extended as follows: |
| |
| @enumerate |
| @item |
| Create project A1 that extends A, placing modified P1 there: |
| |
| @smallexample @c 0projectfile |
| project A1 extends "(...)/A" is |
| end A1; |
| @end smallexample |
| |
| @item |
| Create project C1 that "extends all" C and imports A1, placing modified |
| P3 there: |
| |
| @smallexample @c 0projectfile |
| with "(...)/A1"; |
| project C1 extends all "(...)/C" is |
| end C1; |
| @end smallexample |
| @end enumerate |
| |
| When you build project C1, your entire modified project space will be |
| recompiled, including the virtual project B1 that has been impacted by the |
| "extending all" inheritance of project C. |
| |
| Note that if a Library Project in the hierarchy is virtually extended, |
| the virtual project that extends the Library Project is not a Library Project. |
| |
| @c **************************************** |
| @c * External References in Project Files * |
| @c **************************************** |
| |
| @node External References in Project Files |
| @section External References in Project Files |
| |
| @noindent |
| A project file may contain references to external variables; such references |
| are called @emph{external references}. |
| |
| An external variable is either defined as part of the environment (an |
| environment variable in Unix, for example) or else specified on the command |
| line via the @option{^-X^/EXTERNAL_REFERENCE=^@emph{vbl}=@emph{value}} switch. |
| If both, then the command line value is used. |
| |
| The value of an external reference is obtained by means of the built-in |
| function @code{external}, which returns a string value. |
| This function has two forms: |
| @itemize @bullet |
| @item @code{external (external_variable_name)} |
| @item @code{external (external_variable_name, default_value)} |
| @end itemize |
| |
| @noindent |
| Each parameter must be a string literal. For example: |
| |
| @smallexample @c projectfile |
| external ("USER") |
| external ("OS", "GNU/Linux") |
| @end smallexample |
| |
| @noindent |
| In the form with one parameter, the function returns the value of |
| the external variable given as parameter. If this name is not present in the |
| environment, the function returns an empty string. |
| |
| In the form with two string parameters, the second argument is |
| the value returned when the variable given as the first argument is not |
| present in the environment. In the example above, if @code{"OS"} is not |
| the name of ^an environment variable^a logical name^ and is not passed on |
| the command line, then the returned value is @code{"GNU/Linux"}. |
| |
| An external reference may be part of a string expression or of a string |
| list expression, and can therefore appear in a variable declaration or |
| an attribute declaration. |
| |
| @smallexample @c projectfile |
| @group |
| type Mode_Type is ("Debug", "Release"); |
| Mode : Mode_Type := external ("MODE"); |
| case Mode is |
| when "Debug" => |
| ... |
| @end group |
| @end smallexample |
| |
| @c ***************************** |
| @c * Packages in Project Files * |
| @c ***************************** |
| |
| @node Packages in Project Files |
| @section Packages in Project Files |
| |
| @noindent |
| A @emph{package} defines the settings for project-aware tools within a |
| project. |
| For each such tool one can declare a package; the names for these |
| packages are preset (@pxref{Packages}). |
| A package may contain variable declarations, attribute declarations, and case |
| constructions. |
| |
| @smallexample @c projectfile |
| @group |
| project Proj is |
| package Builder is -- used by gnatmake |
| for ^Default_Switches^Default_Switches^ ("Ada") |
| use ("^-v^-v^", |
| "^-g^-g^"); |
| end Builder; |
| end Proj; |
| @end group |
| @end smallexample |
| |
| @noindent |
| The syntax of package declarations mimics that of package in Ada. |
| |
| Most of the packages have an attribute |
| @code{^Default_Switches^Default_Switches^}. |
| This attribute is an associative array, and its value is a string list. |
| The index of the associative array is the name of a programming language (case |
| insensitive). This attribute indicates the ^switch^switch^ |
| or ^switches^switches^ to be used |
| with the corresponding tool. |
| |
| Some packages also have another attribute, @code{^Switches^Switches^}, |
| an associative array whose value is a string list. |
| The index is the name of a source file. |
| This attribute indicates the ^switch^switch^ |
| or ^switches^switches^ to be used by the corresponding |
| tool when dealing with this specific file. |
| |
| Further information on these ^switch^switch^-related attributes is found in |
| @ref{^Switches^Switches^ and Project Files}. |
| |
| A package may be declared as a @emph{renaming} of another package; e.g., from |
| the project file for an imported project. |
| |
| @smallexample @c projectfile |
| @group |
| with "/global/apex.gpr"; |
| project Example is |
| package Naming renames Apex.Naming; |
| ... |
| end Example; |
| @end group |
| @end smallexample |
| |
| @noindent |
| Packages that are renamed in other project files often come from project files |
| that have no sources: they are just used as templates. Any modification in the |
| template will be reflected automatically in all the project files that rename |
| a package from the template. |
| |
| In addition to the tool-oriented packages, you can also declare a package |
| named @code{Naming} to establish specialized source file naming conventions |
| (@pxref{Naming Schemes}). |
| |
| @c ************************************ |
| @c * Variables from Imported Projects * |
| @c ************************************ |
| |
| @node Variables from Imported Projects |
| @section Variables from Imported Projects |
| |
| @noindent |
| An attribute or variable defined in an imported or parent project can |
| be used in expressions in the importing / extending project. |
| Such an attribute or variable is denoted by an expanded name whose prefix |
| is either the name of the project or the expanded name of a package within |
| a project. |
| |
| @smallexample @c projectfile |
| @group |
| with "imported"; |
| project Main extends "base" is |
| Var1 := Imported.Var; |
| Var2 := Base.Var & ".new"; |
| @end group |
| |
| @group |
| package Builder is |
| for ^Default_Switches^Default_Switches^ ("Ada") |
| use Imported.Builder.Ada_^Switches^Switches^ & |
| "^-gnatg^-gnatg^" & |
| "^-v^-v^"; |
| end Builder; |
| @end group |
| |
| @group |
| package Compiler is |
| for ^Default_Switches^Default_Switches^ ("Ada") |
| use Base.Compiler.Ada_^Switches^Switches^; |
| end Compiler; |
| end Main; |
| @end group |
| @end smallexample |
| |
| @noindent |
| In this example: |
| |
| @itemize @bullet |
| @item |
| The value of @code{Var1} is a copy of the variable @code{Var} defined |
| in the project file @file{"imported.gpr"} |
| @item |
| the value of @code{Var2} is a copy of the value of variable @code{Var} |
| defined in the project file @file{base.gpr}, concatenated with @code{".new"} |
| @item |
| attribute @code{^Default_Switches^Default_Switches^ ("Ada")} in package |
| @code{Builder} is a string list that includes in its value a copy of the value |
| of @code{Ada_^Switches^Switches^} defined in the @code{Builder} package |
| in project file @file{imported.gpr} plus two new elements: |
| @option{"^-gnatg^-gnatg^"} |
| and @option{"^-v^-v^"}; |
| @item |
| attribute @code{^Default_Switches^Default_Switches^ ("Ada")} in package |
| @code{Compiler} is a copy of the variable @code{Ada_^Switches^Switches^} |
| defined in the @code{Compiler} package in project file @file{base.gpr}, |
| the project being extended. |
| @end itemize |
| |
| @c ****************** |
| @c * Naming Schemes * |
| @c ****************** |
| |
| @node Naming Schemes |
| @section Naming Schemes |
| |
| @noindent |
| Sometimes an Ada software system is ported from a foreign compilation |
| environment to GNAT, and the file names do not use the default GNAT |
| conventions. Instead of changing all the file names (which for a variety |
| of reasons might not be possible), you can define the relevant file |
| naming scheme in the @code{Naming} package in your project file. |
| |
| @noindent |
| Note that the use of pragmas described in |
| @ref{Alternative File Naming Schemes} by mean of a configuration |
| pragmas file is not supported when using project files. You must use |
| the features described in this paragraph. You can however use specify |
| other configuration pragmas (@pxref{Specifying Configuration Pragmas}). |
| |
| @ifclear vms |
| For example, the following |
| package models the Apex file naming rules: |
| |
| @smallexample @c projectfile |
| @group |
| package Naming is |
| for Casing use "lowercase"; |
| for Dot_Replacement use "."; |
| for Spec_Suffix ("Ada") use ".1.ada"; |
| for Body_Suffix ("Ada") use ".2.ada"; |
| end Naming; |
| @end group |
| @end smallexample |
| @end ifclear |
| |
| @ifset vms |
| For example, the following package models the HP Ada file naming rules: |
| |
| @smallexample @c projectfile |
| @group |
| package Naming is |
| for Casing use "lowercase"; |
| for Dot_Replacement use "__"; |
| for Spec_Suffix ("Ada") use "_.^ada^ada^"; |
| for Body_Suffix ("Ada") use ".^ada^ada^"; |
| end Naming; |
| @end group |
| @end smallexample |
| |
| @noindent |
| (Note that @code{Casing} is @code{"lowercase"} because GNAT gets the file |
| names in lower case) |
| @end ifset |
| |
| @noindent |
| You can define the following attributes in package @code{Naming}: |
| |
| @table @code |
| |
| @item @var{Casing} |
| This must be a string with one of the three values @code{"lowercase"}, |
| @code{"uppercase"} or @code{"mixedcase"}; these strings are case insensitive. |
| |
| @noindent |
| If @var{Casing} is not specified, then the default is @code{"lowercase"}. |
| |
| @item @var{Dot_Replacement} |
| This must be a string whose value satisfies the following conditions: |
| |
| @itemize @bullet |
| @item It must not be empty |
| @item It cannot start or end with an alphanumeric character |
| @item It cannot be a single underscore |
| @item It cannot start with an underscore followed by an alphanumeric |
| @item It cannot contain a dot @code{'.'} except if the entire string |
| is @code{"."} |
| @end itemize |
| |
| @noindent |
| If @code{Dot_Replacement} is not specified, then the default is @code{"-"}. |
| |
| @item @var{Spec_Suffix} |
| This is an associative array (indexed by the programming language name, case |
| insensitive) whose value is a string that must satisfy the following |
| conditions: |
| |
| @itemize @bullet |
| @item It must not be empty |
| @item It must include at least one dot |
| @end itemize |
| @noindent |
| If @code{Spec_Suffix ("Ada")} is not specified, then the default is |
| @code{"^.ads^.ADS^"}. |
| |
| @item @var{Body_Suffix} |
| This is an associative array (indexed by the programming language name, case |
| insensitive) whose value is a string that must satisfy the following |
| conditions: |
| |
| @itemize @bullet |
| @item It must not be empty |
| @item It must include at least one dot |
| @item It cannot end with the same string as @code{Spec_Suffix ("Ada")} |
| @end itemize |
| @noindent |
| If @code{Body_Suffix ("Ada")} is not specified, then the default is |
| @code{"^.adb^.ADB^"}. |
| |
| @item @var{Separate_Suffix} |
| This must be a string whose value satisfies the same conditions as |
| @code{Body_Suffix}. |
| |
| @noindent |
| If @code{Separate_Suffix ("Ada")} is not specified, then it defaults to same |
| value as @code{Body_Suffix ("Ada")}. |
| |
| @item @var{Spec} |
| @noindent |
| You can use the associative array attribute @code{Spec} to define |
| the source file name for an individual Ada compilation unit's spec. The array |
| index must be a string literal that identifies the Ada unit (case insensitive). |
| The value of this attribute must be a string that identifies the file that |
| contains this unit's spec (case sensitive or insensitive depending on the |
| operating system). |
| |
| @smallexample @c projectfile |
| for Spec ("MyPack.MyChild") use "mypack.mychild.spec"; |
| @end smallexample |
| |
| @item @var{Body} |
| |
| You can use the associative array attribute @code{Body} to |
| define the source file name for an individual Ada compilation unit's body |
| (possibly a subunit). The array index must be a string literal that identifies |
| the Ada unit (case insensitive). The value of this attribute must be a string |
| that identifies the file that contains this unit's body or subunit (case |
| sensitive or insensitive depending on the operating system). |
| |
| @smallexample @c projectfile |
| for Body ("MyPack.MyChild") use "mypack.mychild.body"; |
| @end smallexample |
| @end table |
| |
| @c ******************** |
| @c * Library Projects * |
| @c ******************** |
| |
| @node Library Projects |
| @section Library Projects |
| |
| @noindent |
| @emph{Library projects} are projects whose object code is placed in a library. |
| (Note that this facility is not yet supported on all platforms) |
| |
| To create a library project, you need to define in its project file |
| two project-level attributes: @code{Library_Name} and @code{Library_Dir}. |
| Additionally, you may define other library-related attributes such as |
| @code{Library_Kind}, @code{Library_Version}, @code{Library_Interface}, |
| @code{Library_Auto_Init}, @code{Library_Options} and @code{Library_GCC}. |
| |
| The @code{Library_Name} attribute has a string value. There is no restriction |
| on the name of a library. It is the responsibility of the developer to |
| choose a name that will be accepted by the platform. It is recommended to |
| choose names that could be Ada identifiers; such names are almost guaranteed |
| to be acceptable on all platforms. |
| |
| The @code{Library_Dir} attribute has a string value that designates the path |
| (absolute or relative) of the directory where the library will reside. |
| It must designate an existing directory, and this directory must be writable, |
| different from the project's object directory and from any source directory |
| in the project tree. |
| |
| If both @code{Library_Name} and @code{Library_Dir} are specified and |
| are legal, then the project file defines a library project. The optional |
| library-related attributes are checked only for such project files. |
| |
| The @code{Library_Kind} attribute has a string value that must be one of the |
| following (case insensitive): @code{"static"}, @code{"dynamic"} or |
| @code{"relocatable"} (which is a synonym for @code{"dynamic"}). If this |
| attribute is not specified, the library is a static library, that is |
| an archive of object files that can be potentially linked into a |
| static executable. Otherwise, the library may be dynamic or |
| relocatable, that is a library that is loaded only at the start of execution. |
| |
| If you need to build both a static and a dynamic library, you should use two |
| different object directories, since in some cases some extra code needs to |
| be generated for the latter. For such cases, it is recommended to either use |
| two different project files, or a single one which uses external variables |
| to indicate what kind of library should be build. |
| |
| The @code{Library_ALI_Dir} attribute may be specified to indicate the |
| directory where the ALI files of the library will be copied. When it is |
| not specified, the ALI files are copied ti the directory specified in |
| attribute @code{Library_Dir}. The directory specified by @code{Library_ALI_Dir} |
| must be writable and different from the project's object directory and from |
| any source directory in the project tree. |
| |
| The @code{Library_Version} attribute has a string value whose interpretation |
| is platform dependent. It has no effect on VMS and Windows. On Unix, it is |
| used only for dynamic/relocatable libraries as the internal name of the |
| library (the @code{"soname"}). If the library file name (built from the |
| @code{Library_Name}) is different from the @code{Library_Version}, then the |
| library file will be a symbolic link to the actual file whose name will be |
| @code{Library_Version}. |
| |
| Example (on Unix): |
| |
| @smallexample @c projectfile |
| @group |
| project Plib is |
| |
| Version := "1"; |
| |
| for Library_Dir use "lib_dir"; |
| for Library_Name use "dummy"; |
| for Library_Kind use "relocatable"; |
| for Library_Version use "libdummy.so." & Version; |
| |
| end Plib; |
| @end group |
| @end smallexample |
| |
| @noindent |
| Directory @file{lib_dir} will contain the internal library file whose name |
| will be @file{libdummy.so.1}, and @file{libdummy.so} will be a symbolic link to |
| @file{libdummy.so.1}. |
| |
| When @command{gnatmake} detects that a project file |
| is a library project file, it will check all immediate sources of the project |
| and rebuild the library if any of the sources have been recompiled. |
| |
| Standard project files can import library project files. In such cases, |
| the libraries will only be rebuilt if some of its sources are recompiled |
| because they are in the closure of some other source in an importing project. |
| Sources of the library project files that are not in such a closure will |
| not be checked, unless the full library is checked, because one of its sources |
| needs to be recompiled. |
| |
| For instance, assume the project file @code{A} imports the library project file |
| @code{L}. The immediate sources of A are @file{a1.adb}, @file{a2.ads} and |
| @file{a2.adb}. The immediate sources of L are @file{l1.ads}, @file{l1.adb}, |
| @file{l2.ads}, @file{l2.adb}. |
| |
| If @file{l1.adb} has been modified, then the library associated with @code{L} |
| will be rebuilt when compiling all the immediate sources of @code{A} only |
| if @file{a1.ads}, @file{a2.ads} or @file{a2.adb} includes a statement |
| @code{"with L1;"}. |
| |
| To be sure that all the sources in the library associated with @code{L} are |
| up to date, and that all the sources of project @code{A} are also up to date, |
| the following two commands needs to be used: |
| |
| @smallexample |
| gnatmake -Pl.gpr |
| gnatmake -Pa.gpr |
| @end smallexample |
| |
| When a library is built or rebuilt, an attempt is made first to delete all |
| files in the library directory. |
| All @file{ALI} files will also be copied from the object directory to the |
| library directory. To build executables, @command{gnatmake} will use the |
| library rather than the individual object files. |
| |
| @ifclear vms |
| It is also possible to create library project files for third-party libraries |
| that are precompiled and cannot be compiled locally thanks to the |
| @code{externally_built} attribute. (See @ref{Installing a library}). |
| @end ifclear |
| |
| @c ******************************* |
| @c * Stand-alone Library Projects * |
| @c ******************************* |
| |
| @node Stand-alone Library Projects |
| @section Stand-alone Library Projects |
| |
| @noindent |
| A Stand-alone Library is a library that contains the necessary code to |
| elaborate the Ada units that are included in the library. A Stand-alone |
| Library is suitable to be used in an executable when the main is not |
| in Ada. However, Stand-alone Libraries may also be used with an Ada main |
| subprogram. |
| |
| A Stand-alone Library Project is a Library Project where the library is |
| a Stand-alone Library. |
| |
| To be a Stand-alone Library Project, in addition to the two attributes |
| that make a project a Library Project (@code{Library_Name} and |
| @code{Library_Dir}, see @ref{Library Projects}), the attribute |
| @code{Library_Interface} must be defined. |
| |
| @smallexample @c projectfile |
| @group |
| for Library_Dir use "lib_dir"; |
| for Library_Name use "dummy"; |
| for Library_Interface use ("int1", "int1.child"); |
| @end group |
| @end smallexample |
| |
| Attribute @code{Library_Interface} has a non empty string list value, |
| each string in the list designating a unit contained in an immediate source |
| of the project file. |
| |
| When a Stand-alone Library is built, first the binder is invoked to build |
| a package whose name depends on the library name |
| (^b~dummy.ads/b^B$DUMMY.ADS/B^ in the example above). |
| This binder-generated package includes initialization and |
| finalization procedures whose |
| names depend on the library name (dummyinit and dummyfinal in the example |
| above). The object corresponding to this package is included in the library. |
| |
| A dynamic or relocatable Stand-alone Library is automatically initialized |
| if automatic initialization of Stand-alone Libraries is supported on the |
| platform and if attribute @code{Library_Auto_Init} is not specified or |
| is specified with the value "true". A static Stand-alone Library is never |
| automatically initialized. |
| |
| Single string attribute @code{Library_Auto_Init} may be specified with only |
| two possible values: "false" or "true" (case-insensitive). Specifying |
| "false" for attribute @code{Library_Auto_Init} will prevent automatic |
| initialization of dynamic or relocatable libraries. |
| |
| When a non automatically initialized Stand-alone Library is used |
| in an executable, its initialization procedure must be called before |
| any service of the library is used. |
| When the main subprogram is in Ada, it may mean that the initialization |
| procedure has to be called during elaboration of another package. |
| |
| For a Stand-Alone Library, only the @file{ALI} files of the Interface Units |
| (those that are listed in attribute @code{Library_Interface}) are copied to |
| the Library Directory. As a consequence, only the Interface Units may be |
| imported from Ada units outside of the library. If other units are imported, |
| the binding phase will fail. |
| |
| When a Stand-Alone Library is bound, the switches that are specified in |
| the attribute @code{Default_Switches ("Ada")} in package @code{Binder} are |
| used in the call to @command{gnatbind}. |
| |
| The string list attribute @code{Library_Options} may be used to specified |
| additional switches to the call to @command{gcc} to link the library. |
| |
| The attribute @code{Library_Src_Dir}, may be specified for a |
| Stand-Alone Library. @code{Library_Src_Dir} is a simple attribute that has a |
| single string value. Its value must be the path (absolute or relative to the |
| project directory) of an existing directory. This directory cannot be the |
| object directory or one of the source directories, but it can be the same as |
| the library directory. The sources of the Interface |
| Units of the library, necessary to an Ada client of the library, will be |
| copied to the designated directory, called Interface Copy directory. |
| These sources includes the specs of the Interface Units, but they may also |
| include bodies and subunits, when pragmas @code{Inline} or @code{Inline_Always} |
| are used, or when there is a generic units in the spec. Before the sources |
| are copied to the Interface Copy directory, an attempt is made to delete all |
| files in the Interface Copy directory. |
| |
| @c ************************************* |
| @c * Switches Related to Project Files * |
| @c ************************************* |
| @node Switches Related to Project Files |
| @section Switches Related to Project Files |
| |
| @noindent |
| The following switches are used by GNAT tools that support project files: |
| |
| @table @option |
| |
| @item ^-P^/PROJECT_FILE=^@var{project} |
| @cindex @option{^-P^/PROJECT_FILE^} (any tool supporting project files) |
| Indicates the name of a project file. This project file will be parsed with |
| the verbosity indicated by @option{^-vP^MESSAGE_PROJECT_FILES=^@emph{x}}, |
| if any, and using the external references indicated |
| by @option{^-X^/EXTERNAL_REFERENCE^} switches, if any. |
| @ifclear vms |
| There may zero, one or more spaces between @option{-P} and @var{project}. |
| @end ifclear |
| |
| @noindent |
| There must be only one @option{^-P^/PROJECT_FILE^} switch on the command line. |
| |
| @noindent |
| Since the Project Manager parses the project file only after all the switches |
| on the command line are checked, the order of the switches |
| @option{^-P^/PROJECT_FILE^}, |
| @option{^-vP^/MESSAGES_PROJECT_FILE=^@emph{x}} |
| or @option{^-X^/EXTERNAL_REFERENCE^} is not significant. |
| |
| @item ^-X^/EXTERNAL_REFERENCE=^@var{name=value} |
| @cindex @option{^-X^/EXTERNAL_REFERENCE^} (any tool supporting project files) |
| Indicates that external variable @var{name} has the value @var{value}. |
| The Project Manager will use this value for occurrences of |
| @code{external(name)} when parsing the project file. |
| |
| @ifclear vms |
| @noindent |
| If @var{name} or @var{value} includes a space, then @var{name=value} should be |
| put between quotes. |
| @smallexample |
| -XOS=NT |
| -X"user=John Doe" |
| @end smallexample |
| @end ifclear |
| |
| @noindent |
| Several @option{^-X^/EXTERNAL_REFERENCE^} switches can be used simultaneously. |
| If several @option{^-X^/EXTERNAL_REFERENCE^} switches specify the same |
| @var{name}, only the last one is used. |
| |
| @noindent |
| An external variable specified with a @option{^-X^/EXTERNAL_REFERENCE^} switch |
| takes precedence over the value of the same name in the environment. |
| |
| @item ^-vP^/MESSAGES_PROJECT_FILE=^@emph{x} |
| @cindex @code{^-vP^/MESSAGES_PROJECT_FILE^} (any tool supporting project files) |
| @c Previous line uses code vs option command, to stay less than 80 chars |
| Indicates the verbosity of the parsing of GNAT project files. |
| |
| @ifclear vms |
| @option{-vP0} means Default; |
| @option{-vP1} means Medium; |
| @option{-vP2} means High. |
| @end ifclear |
| |
| @ifset vms |
| There are three possible options for this qualifier: DEFAULT, MEDIUM and |
| HIGH. |
| @end ifset |
| |
| @noindent |
| The default is ^Default^DEFAULT^: no output for syntactically correct |
| project files. |
| @noindent |
| If several @option{^-vP^/MESSAGES_PROJECT_FILE=^@emph{x}} switches are present, |
| only the last one is used. |
| |
| @end table |
| |
| @c ********************************** |
| @c * Tools Supporting Project Files * |
| @c ********************************** |
| |
| @node Tools Supporting Project Files |
| @section Tools Supporting Project Files |
| |
| @menu |
| * gnatmake and Project Files:: |
| * The GNAT Driver and Project Files:: |
| @ifclear vms |
| * Glide and Project Files:: |
| @end ifclear |
| @end menu |
| |
| @node gnatmake and Project Files |
| @subsection gnatmake and Project Files |
| |
| @noindent |
| This section covers several topics related to @command{gnatmake} and |
| project files: defining ^switches^switches^ for @command{gnatmake} |
| and for the tools that it invokes; specifying configuration pragmas; |
| the use of the @code{Main} attribute; building and rebuilding library project |
| files. |
| |
| @menu |
| * ^Switches^Switches^ and Project Files:: |
| * Specifying Configuration Pragmas:: |
| * Project Files and Main Subprograms:: |
| * Library Project Files:: |
| @end menu |
| |
| @node ^Switches^Switches^ and Project Files |
| @subsubsection ^Switches^Switches^ and Project Files |
| |
| @ifset vms |
| It is not currently possible to specify VMS style qualifiers in the project |
| files; only Unix style ^switches^switches^ may be specified. |
| @end ifset |
| |
| @noindent |
| For each of the packages @code{Builder}, @code{Compiler}, @code{Binder}, and |
| @code{Linker}, you can specify a @code{^Default_Switches^Default_Switches^} |
| attribute, a @code{^Switches^Switches^} attribute, or both; |
| as their names imply, these ^switch^switch^-related |
| attributes affect the ^switches^switches^ that are used for each of these GNAT |
| components when |
| @command{gnatmake} is invoked. As will be explained below, these |
| component-specific ^switches^switches^ precede |
| the ^switches^switches^ provided on the @command{gnatmake} command line. |
| |
| The @code{^Default_Switches^Default_Switches^} attribute is an associative |
| array indexed by language name (case insensitive) whose value is a string list. |
| For example: |
| |
| @smallexample @c projectfile |
| @group |
| package Compiler is |
| for ^Default_Switches^Default_Switches^ ("Ada") |
| use ("^-gnaty^-gnaty^", |
| "^-v^-v^"); |
| end Compiler; |
| @end group |
| @end smallexample |
| |
| @noindent |
| The @code{^Switches^Switches^} attribute is also an associative array, |
| indexed by a file name (which may or may not be case sensitive, depending |
| on the operating system) whose value is a string list. For example: |
| |
| @smallexample @c projectfile |
| @group |
| package Builder is |
| for ^Switches^Switches^ ("main1.adb") |
| use ("^-O2^-O2^"); |
| for ^Switches^Switches^ ("main2.adb") |
| use ("^-g^-g^"); |
| end Builder; |
| @end group |
| @end smallexample |
| |
| @noindent |
| For the @code{Builder} package, the file names must designate source files |
| for main subprograms. For the @code{Binder} and @code{Linker} packages, the |
| file names must designate @file{ALI} or source files for main subprograms. |
| In each case just the file name without an explicit extension is acceptable. |
| |
| For each tool used in a program build (@command{gnatmake}, the compiler, the |
| binder, and the linker), the corresponding package @dfn{contributes} a set of |
| ^switches^switches^ for each file on which the tool is invoked, based on the |
| ^switch^switch^-related attributes defined in the package. |
| In particular, the ^switches^switches^ |
| that each of these packages contributes for a given file @var{f} comprise: |
| |
| @itemize @bullet |
| @item |
| the value of attribute @code{^Switches^Switches^ (@var{f})}, |
| if it is specified in the package for the given file, |
| @item |
| otherwise, the value of @code{^Default_Switches^Default_Switches^ ("Ada")}, |
| if it is specified in the package. |
| @end itemize |
| |
| @noindent |
| If neither of these attributes is defined in the package, then the package does |
| not contribute any ^switches^switches^ for the given file. |
| |
| When @command{gnatmake} is invoked on a file, the ^switches^switches^ comprise |
| two sets, in the following order: those contributed for the file |
| by the @code{Builder} package; |
| and the switches passed on the command line. |
| |
| When @command{gnatmake} invokes a tool (compiler, binder, linker) on a file, |
| the ^switches^switches^ passed to the tool comprise three sets, |
| in the following order: |
| |
| @enumerate |
| @item |
| the applicable ^switches^switches^ contributed for the file |
| by the @code{Builder} package in the project file supplied on the command line; |
| |
| @item |
| those contributed for the file by the package (in the relevant project file -- |
| see below) corresponding to the tool; and |
| |
| @item |
| the applicable switches passed on the command line. |
| @end enumerate |
| |
| @noindent |
| The term @emph{applicable ^switches^switches^} reflects the fact that |
| @command{gnatmake} ^switches^switches^ may or may not be passed to individual |
| tools, depending on the individual ^switch^switch^. |
| |
| @command{gnatmake} may invoke the compiler on source files from different |
| projects. The Project Manager will use the appropriate project file to |
| determine the @code{Compiler} package for each source file being compiled. |
| Likewise for the @code{Binder} and @code{Linker} packages. |
| |
| As an example, consider the following package in a project file: |
| |
| @smallexample @c projectfile |
| @group |
| project Proj1 is |
| package Compiler is |
| for ^Default_Switches^Default_Switches^ ("Ada") |
| use ("^-g^-g^"); |
| for ^Switches^Switches^ ("a.adb") |
| use ("^-O1^-O1^"); |
| for ^Switches^Switches^ ("b.adb") |
| use ("^-O2^-O2^", |
| "^-gnaty^-gnaty^"); |
| end Compiler; |
| end Proj1; |
| @end group |
| @end smallexample |
| |
| @noindent |
| If @command{gnatmake} is invoked with this project file, and it needs to |
| compile, say, the files @file{a.adb}, @file{b.adb}, and @file{c.adb}, then |
| @file{a.adb} will be compiled with the ^switch^switch^ |
| @option{^-O1^-O1^}, |
| @file{b.adb} with ^switches^switches^ |
| @option{^-O2^-O2^} |
| and @option{^-gnaty^-gnaty^}, |
| and @file{c.adb} with @option{^-g^-g^}. |
| |
| The following example illustrates the ordering of the ^switches^switches^ |
| contributed by different packages: |
| |
| @smallexample @c projectfile |
| @group |
| project Proj2 is |
| package Builder is |
| for ^Switches^Switches^ ("main.adb") |
| use ("^-g^-g^", |
| "^-O1^-)1^", |
| "^-f^-f^"); |
| end Builder; |
| @end group |
| |
| @group |
| package Compiler is |
| for ^Switches^Switches^ ("main.adb") |
| use ("^-O2^-O2^"); |
| end Compiler; |
| end Proj2; |
| @end group |
| @end smallexample |
| |
| @noindent |
| If you issue the command: |
| |
| @smallexample |
| gnatmake ^-Pproj2^/PROJECT_FILE=PROJ2^ -O0 main |
| @end smallexample |
| |
| @noindent |
| then the compiler will be invoked on @file{main.adb} with the following |
| sequence of ^switches^switches^ |
| |
| @smallexample |
| ^-g -O1 -O2 -O0^-g -O1 -O2 -O0^ |
| @end smallexample |
| |
| with the last @option{^-O^-O^} |
| ^switch^switch^ having precedence over the earlier ones; |
| several other ^switches^switches^ |
| (such as @option{^-c^-c^}) are added implicitly. |
| |
| The ^switches^switches^ |
| @option{^-g^-g^} |
| and @option{^-O1^-O1^} are contributed by package |
| @code{Builder}, @option{^-O2^-O2^} is contributed |
| by the package @code{Compiler} |
| and @option{^-O0^-O0^} comes from the command line. |
| |
| The @option{^-g^-g^} |
| ^switch^switch^ will also be passed in the invocation of |
| @command{Gnatlink.} |
| |
| A final example illustrates switch contributions from packages in different |
| project files: |
| |
| @smallexample @c projectfile |
| @group |
| project Proj3 is |
| for Source_Files use ("pack.ads", "pack.adb"); |
| package Compiler is |
| for ^Default_Switches^Default_Switches^ ("Ada") |
| use ("^-gnata^-gnata^"); |
| end Compiler; |
| end Proj3; |
| @end group |
| |
| @group |
| with "Proj3"; |
| project Proj4 is |
| for Source_Files use ("foo_main.adb", "bar_main.adb"); |
| package Builder is |
| for ^Switches^Switches^ ("foo_main.adb") |
| use ("^-s^-s^", |
| "^-g^-g^"); |
| end Builder; |
| end Proj4; |
| @end group |
| |
| @group |
| -- Ada source file: |
| with Pack; |
| procedure Foo_Main is |
| ... |
| end Foo_Main; |
| @end group |
| @end smallexample |
| |
| If the command is |
| @smallexample |
| gnatmake ^-PProj4^/PROJECT_FILE=PROJ4^ foo_main.adb -cargs -gnato |
| @end smallexample |
| |
| @noindent |
| then the ^switches^switches^ passed to the compiler for @file{foo_main.adb} are |
| @option{^-g^-g^} (contributed by the package @code{Proj4.Builder}) and |
| @option{^-gnato^-gnato^} (passed on the command line). |
| When the imported package @code{Pack} is compiled, the ^switches^switches^ used |
| are @option{^-g^-g^} from @code{Proj4.Builder}, |
| @option{^-gnata^-gnata^} (contributed from package @code{Proj3.Compiler}, |
| and @option{^-gnato^-gnato^} from the command line. |
| |
| @noindent |
| When using @command{gnatmake} with project files, some ^switches^switches^ or |
| arguments may be expressed as relative paths. As the working directory where |
| compilation occurs may change, these relative paths are converted to absolute |
| paths. For the ^switches^switches^ found in a project file, the relative paths |
| are relative to the project file directory, for the switches on the command |
| line, they are relative to the directory where @command{gnatmake} is invoked. |
| The ^switches^switches^ for which this occurs are: |
| ^-I^-I^, |
| ^-A^-A^, |
| ^-L^-L^, |
| ^-aO^-aO^, |
| ^-aL^-aL^, |
| ^-aI^-aI^, as well as all arguments that are not switches (arguments to |
| ^switch^switch^ |
| ^-o^-o^, object files specified in package @code{Linker} or after |
| -largs on the command line). The exception to this rule is the ^switch^switch^ |
| ^--RTS=^--RTS=^ for which a relative path argument is never converted. |
| |
| @node Specifying Configuration Pragmas |
| @subsubsection Specifying Configuration Pragmas |
| |
| When using @command{gnatmake} with project files, if there exists a file |
| @file{gnat.adc} that contains configuration pragmas, this file will be |
| ignored. |
| |
| Configuration pragmas can be defined by means of the following attributes in |
| project files: @code{Global_Configuration_Pragmas} in package @code{Builder} |
| and @code{Local_Configuration_Pragmas} in package @code{Compiler}. |
| |
| Both these attributes are single string attributes. Their values is the path |
| name of a file containing configuration pragmas. If a path name is relative, |
| then it is relative to the project directory of the project file where the |
| attribute is defined. |
| |
| When compiling a source, the configuration pragmas used are, in order, |
| those listed in the file designated by attribute |
| @code{Global_Configuration_Pragmas} in package @code{Builder} of the main |
| project file, if it is specified, and those listed in the file designated by |
| attribute @code{Local_Configuration_Pragmas} in package @code{Compiler} of |
| the project file of the source, if it exists. |
| |
| @node Project Files and Main Subprograms |
| @subsubsection Project Files and Main Subprograms |
| |
| @noindent |
| When using a project file, you can invoke @command{gnatmake} |
| with one or several main subprograms, by specifying their source files on the |
| command line. |
| |
| @smallexample |
| gnatmake ^-P^/PROJECT_FILE=^prj main1 main2 main3 |
| @end smallexample |
| |
| @noindent |
| Each of these needs to be a source file of the same project, except |
| when the switch ^-u^/UNIQUE^ is used. |
| |
| @noindent |
| When ^-u^/UNIQUE^ is not used, all the mains need to be sources of the |
| same project, one of the project in the tree rooted at the project specified |
| on the command line. The package @code{Builder} of this common project, the |
| "main project" is the one that is considered by @command{gnatmake}. |
| |
| @noindent |
| When ^-u^/UNIQUE^ is used, the specified source files may be in projects |
| imported directly or indirectly by the project specified on the command line. |
| Note that if such a source file is not part of the project specified on the |
| command line, the ^switches^switches^ found in package @code{Builder} of the |
| project specified on the command line, if any, that are transmitted |
| to the compiler will still be used, not those found in the project file of |
| the source file. |
| |
| @noindent |
| When using a project file, you can also invoke @command{gnatmake} without |
| explicitly specifying any main, and the effect depends on whether you have |
| defined the @code{Main} attribute. This attribute has a string list value, |
| where each element in the list is the name of a source file (the file |
| extension is optional) that contains a unit that can be a main subprogram. |
| |
| If the @code{Main} attribute is defined in a project file as a non-empty |
| string list and the switch @option{^-u^/UNIQUE^} is not used on the command |
| line, then invoking @command{gnatmake} with this project file but without any |
| main on the command line is equivalent to invoking @command{gnatmake} with all |
| the file names in the @code{Main} attribute on the command line. |
| |
| Example: |
| @smallexample @c projectfile |
| @group |
| project Prj is |
| for Main use ("main1", "main2", "main3"); |
| end Prj; |
| @end group |
| @end smallexample |
| |
| @noindent |
| With this project file, @code{"gnatmake ^-Pprj^/PROJECT_FILE=PRJ^"} |
| is equivalent to |
| @code{"gnatmake ^-Pprj^/PROJECT_FILE=PRJ^ main1 main2 main3"}. |
| |
| When the project attribute @code{Main} is not specified, or is specified |
| as an empty string list, or when the switch @option{-u} is used on the command |
| line, then invoking @command{gnatmake} with no main on the command line will |
| result in all immediate sources of the project file being checked, and |
| potentially recompiled. Depending on the presence of the switch @option{-u}, |
| sources from other project files on which the immediate sources of the main |
| project file depend are also checked and potentially recompiled. In other |
| words, the @option{-u} switch is applied to all of the immediate sources of the |
| main project file. |
| |
| When no main is specified on the command line and attribute @code{Main} exists |
| and includes several mains, or when several mains are specified on the |
| command line, the default ^switches^switches^ in package @code{Builder} will |
| be used for all mains, even if there are specific ^switches^switches^ |
| specified for one or several mains. |
| |
| But the ^switches^switches^ from package @code{Binder} or @code{Linker} will be |
| the specific ^switches^switches^ for each main, if they are specified. |
| |
| @node Library Project Files |
| @subsubsection Library Project Files |
| |
| @noindent |
| When @command{gnatmake} is invoked with a main project file that is a library |
| project file, it is not allowed to specify one or more mains on the command |
| line. |
| |
| @noindent |
| When a library project file is specified, switches ^-b^/ACTION=BIND^ and |
| ^-l^/ACTION=LINK^ have special meanings. |
| |
| @itemize @bullet |
| @item ^-b^/ACTION=BIND^ is only allowed for stand-alone libraries. It indicates |
| to @command{gnatmake} that @command{gnatbind} should be invoked for the |
| library. |
| |
| @item ^-l^/ACTION=LINK^ may be used for all library projects. It indicates |
| to @command{gnatmake} that the binder generated file should be compiled |
| (in the case of a stand-alone library) and that the library should be built. |
| |
| @end itemize |
| |
| @node The GNAT Driver and Project Files |
| @subsection The GNAT Driver and Project Files |
| |
| @noindent |
| A number of GNAT tools, other than @command{^gnatmake^gnatmake^} |
| are project-aware: |
| @command{^gnatbind^gnatbind^}, |
| @command{^gnatfind^gnatfind^}, |
| @command{^gnatlink^gnatlink^}, |
| @command{^gnatls^gnatls^}, |
| @command{^gnatelim^gnatelim^}, |
| @command{^gnatpp^gnatpp^}, |
| @command{^gnatmetric^gnatmetric^}, |
| @command{^gnatstub^gnatstub^}, |
| and @command{^gnatxref^gnatxref^}. However, none of these tools can be invoked |
| directly with a project file switch (@option{^-P^/PROJECT_FILE=^}). |
| They must be invoked through the @command{gnat} driver. |
| |
| The @command{gnat} driver is a front-end that accepts a number of commands and |
| call the corresponding tool. It has been designed initially for VMS to convert |
| VMS style qualifiers to Unix style switches, but it is now available to all |
| the GNAT supported platforms. |
| |
| On non VMS platforms, the @command{gnat} driver accepts the following commands |
| (case insensitive): |
| |
| @itemize @bullet |
| @item |
| BIND to invoke @command{^gnatbind^gnatbind^} |
| @item |
| CHOP to invoke @command{^gnatchop^gnatchop^} |
| @item |
| CLEAN to invoke @command{^gnatclean^gnatclean^} |
| @item |
| COMP or COMPILE to invoke the compiler |
| @item |
| ELIM to invoke @command{^gnatelim^gnatelim^} |
| @item |
| FIND to invoke @command{^gnatfind^gnatfind^} |
| @item |
| KR or KRUNCH to invoke @command{^gnatkr^gnatkr^} |
| @item |
| LINK to invoke @command{^gnatlink^gnatlink^} |
| @item |
| LS or LIST to invoke @command{^gnatls^gnatls^} |
| @item |
| MAKE to invoke @command{^gnatmake^gnatmake^} |
| @item |
| NAME to invoke @command{^gnatname^gnatname^} |
| @item |
| PREP or PREPROCESS to invoke @command{^gnatprep^gnatprep^} |
| @item |
| PP or PRETTY to invoke @command{^gnatpp^gnatpp^} |
| @item |
| METRIC to invoke @command{^gnatmetric^gnatmetric^} |
| @item |
| STUB to invoke @command{^gnatstub^gnatstub^} |
| @item |
| XREF to invoke @command{^gnatxref^gnatxref^} |
| @end itemize |
| |
| @noindent |
| (note that the compiler is invoked using the command |
| @command{^gnatmake -f -u -c^gnatmake -f -u -c^}). |
| |
| @noindent |
| On non VMS platforms, between @command{gnat} and the command, two |
| special switches may be used: |
| |
| @itemize @bullet |
| @item |
| @command{-v} to display the invocation of the tool. |
| @item |
| @command{-dn} to prevent the @command{gnat} driver from removing |
| the temporary files it has created. These temporary files are |
| configuration files and temporary file list files. |
| @end itemize |
| |
| @noindent |
| The command may be followed by switches and arguments for the invoked |
| tool. |
| |
| @smallexample |
| gnat bind -C main.ali |
| gnat ls -a main |
| gnat chop foo.txt |
| @end smallexample |
| |
| @noindent |
| Switches may also be put in text files, one switch per line, and the text |
| files may be specified with their path name preceded by '@@'. |
| |
| @smallexample |
| gnat bind @@args.txt main.ali |
| @end smallexample |
| |
| @noindent |
| In addition, for commands BIND, COMP or COMPILE, FIND, ELIM, LS or LIST, LINK, |
| METRIC, PP or PRETTY, STUB and XREF, the project file related switches |
| (@option{^-P^/PROJECT_FILE^}, |
| @option{^-X^/EXTERNAL_REFERENCE^} and |
| @option{^-vP^/MESSAGES_PROJECT_FILE=^x}) may be used in addition to |
| the switches of the invoking tool. |
| |
| @noindent |
| When GNAT PP or GNAT PRETTY is used with a project file, but with no source |
| specified on the command line, it invokes @command{^gnatpp^gnatpp^} with all |
| the immediate sources of the specified project file. |
| |
| @noindent |
| When GNAT METRIC is used with a project file, but with no source |
| specified on the command line, it invokes @command{^gnatmetric^gnatmetric^} |
| with all the immediate sources of the specified project file and with |
| @option{^-d^/DIRECTORY^} with the parameter pointing to the object directory |
| of the project. |
| |
| @noindent |
| In addition, when GNAT PP, GNAT PRETTY or GNAT METRIC is used with |
| a project file, no source is specified on the command line and |
| switch ^-U^/ALL_PROJECTS^ is specified on the command line, then |
| the underlying tool (^gnatpp^gnatpp^ or |
| ^gnatmetric^gnatmetric^) is invoked for all sources of all projects, |
| not only for the immediate sources of the main project. |
| @ifclear vms |
| (-U stands for Universal or Union of the project files of the project tree) |
| @end ifclear |
| |
| @noindent |
| For each of the following commands, there is optionally a corresponding |
| package in the main project. |
| |
| @itemize @bullet |
| @item |
| package @code{Binder} for command BIND (invoking @code{^gnatbind^gnatbind^}) |
| |
| @item |
| package @code{Compiler} for command COMP or COMPILE (invoking the compiler) |
| |
| @item |
| package @code{Finder} for command FIND (invoking @code{^gnatfind^gnatfind^}) |
| |
| @item |
| package @code{Eliminate} for command ELIM (invoking |
| @code{^gnatelim^gnatelim^}) |
| |
| @item |
| package @code{Gnatls} for command LS or LIST (invoking @code{^gnatls^gnatls^}) |
| |
| @item |
| package @code{Linker} for command LINK (invoking @code{^gnatlink^gnatlink^}) |
| |
| @item |
| package @code{Metrics} for command METRIC |
| (invoking @code{^gnatmetric^gnatmetric^}) |
| |
| @item |
| package @code{Pretty_Printer} for command PP or PRETTY |
| (invoking @code{^gnatpp^gnatpp^}) |
| |
| @item |
| package @code{Gnatstub} for command STUB |
| (invoking @code{^gnatstub^gnatstub^}) |
| |
| @item |
| package @code{Cross_Reference} for command XREF (invoking |
| @code{^gnatxref^gnatxref^}) |
| |
| @end itemize |
| |
| @noindent |
| Package @code{Gnatls} has a unique attribute @code{^Switches^Switches^}, |
| a simple variable with a string list value. It contains ^switches^switches^ |
| for the invocation of @code{^gnatls^gnatls^}. |
| |
| @smallexample @c projectfile |
| @group |
| project Proj1 is |
| package gnatls is |
| for ^Switches^Switches^ |
| use ("^-a^-a^", |
| "^-v^-v^"); |
| end gnatls; |
| end Proj1; |
| @end group |
| @end smallexample |
| |
| @noindent |
| All other packages have two attribute @code{^Switches^Switches^} and |
| @code{^Default_Switches^Default_Switches^}. |
| |
| @noindent |
| @code{^Switches^Switches^} is an associated array attribute, indexed by the |
| source file name, that has a string list value: the ^switches^switches^ to be |
| used when the tool corresponding to the package is invoked for the specific |
| source file. |
| |
| @noindent |
| @code{^Default_Switches^Default_Switches^} is an associative array attribute, |
| indexed by the programming language that has a string list value. |
| @code{^Default_Switches^Default_Switches^ ("Ada")} contains the |
| ^switches^switches^ for the invocation of the tool corresponding |
| to the package, except if a specific @code{^Switches^Switches^} attribute |
| is specified for the source file. |
| |
| @smallexample @c projectfile |
| @group |
| project Proj is |
| |
| for Source_Dirs use ("./**"); |
| |
| package gnatls is |
| for ^Switches^Switches^ use |
| ("^-a^-a^", |
| "^-v^-v^"); |
| end gnatls; |
| @end group |
| @group |
| |
| package Compiler is |
| for ^Default_Switches^Default_Switches^ ("Ada") |
| use ("^-gnatv^-gnatv^", |
| "^-gnatwa^-gnatwa^"); |
| end Binder; |
| @end group |
| @group |
| |
| package Binder is |
| for ^Default_Switches^Default_Switches^ ("Ada") |
| use ("^-C^-C^", |
| "^-e^-e^"); |
| end Binder; |
| @end group |
| @group |
| |
| package Linker is |
| for ^Default_Switches^Default_Switches^ ("Ada") |
| use ("^-C^-C^"); |
| for ^Switches^Switches^ ("main.adb") |
| use ("^-C^-C^", |
| "^-v^-v^", |
| "^-v^-v^"); |
| end Linker; |
| @end group |
| @group |
| |
| package Finder is |
| for ^Default_Switches^Default_Switches^ ("Ada") |
| use ("^-a^-a^", |
| "^-f^-f^"); |
| end Finder; |
| @end group |
| @group |
| |
| package Cross_Reference is |
| for ^Default_Switches^Default_Switches^ ("Ada") |
| use ("^-a^-a^", |
| "^-f^-f^", |
| "^-d^-d^", |
| "^-u^-u^"); |
| end Cross_Reference; |
| end Proj; |
| @end group |
| @end smallexample |
| |
| @noindent |
| With the above project file, commands such as |
| |
| @smallexample |
| ^gnat comp -Pproj main^GNAT COMP /PROJECT_FILE=PROJ MAIN^ |
| ^gnat ls -Pproj main^GNAT LIST /PROJECT_FILE=PROJ MAIN^ |
| ^gnat xref -Pproj main^GNAT XREF /PROJECT_FILE=PROJ MAIN^ |
| ^gnat bind -Pproj main.ali^GNAT BIND /PROJECT_FILE=PROJ MAIN.ALI^ |
| ^gnat link -Pproj main.ali^GNAT LINK /PROJECT_FILE=PROJ MAIN.ALI^ |
| @end smallexample |
| |
| @noindent |
| will set up the environment properly and invoke the tool with the switches |
| found in the package corresponding to the tool: |
| @code{^Default_Switches^Default_Switches^ ("Ada")} for all tools, |
| except @code{^Switches^Switches^ ("main.adb")} |
| for @code{^gnatlink^gnatlink^}. |
| |
| @ifclear vms |
| @node Glide and Project Files |
| @subsection Glide and Project Files |
| |
| @noindent |
| Glide will automatically recognize the @file{.gpr} extension for |
| project files, and will |
| convert them to its own internal format automatically. However, it |
| doesn't provide a syntax-oriented editor for modifying these |
| files. |
| The project file will be loaded as text when you select the menu item |
| @code{Ada} @result{} @code{Project} @result{} @code{Edit}. |
| You can edit this text and save the @file{gpr} file; |
| when you next select this project file in Glide it |
| will be automatically reloaded. |
| @end ifclear |
| |
| @c ********************** |
| @node An Extended Example |
| @section An Extended Example |
| |
| @noindent |
| Suppose that we have two programs, @var{prog1} and @var{prog2}, |
| whose sources are in corresponding directories. We would like |
| to build them with a single @command{gnatmake} command, and we want to place |
| their object files into @file{build} subdirectories of the source directories. |
| Furthermore, we want to have to have two separate subdirectories |
| in @file{build} -- @file{release} and @file{debug} -- which will contain |
| the object files compiled with different set of compilation flags. |
| |
| In other words, we have the following structure: |
| |
| @smallexample |
| @group |
| main |
| |- prog1 |
| | |- build |
| | | debug |
| | | release |
| |- prog2 |
| |- build |
| | debug |
| | release |
| @end group |
| @end smallexample |
| |
| @noindent |
| Here are the project files that we must place in a directory @file{main} |
| to maintain this structure: |
| |
| @enumerate |
| |
| @item We create a @code{Common} project with a package @code{Compiler} that |
| specifies the compilation ^switches^switches^: |
| |
| @smallexample |
| File "common.gpr": |
| @group |
| @b{project} Common @b{is} |
| |
| @b{for} Source_Dirs @b{use} (); -- No source files |
| @end group |
| |
| @group |
| @b{type} Build_Type @b{is} ("release", "debug"); |
| Build : Build_Type := External ("BUILD", "debug"); |
| @end group |
| @group |
| @b{package} Compiler @b{is} |
| @b{case} Build @b{is} |
| @b{when} "release" => |
| @b{for} ^Default_Switches^Default_Switches^ ("Ada") |
| @b{use} ("^-O2^-O2^"); |
| @b{when} "debug" => |
| @b{for} ^Default_Switches^Default_Switches^ ("Ada") |
| @b{use} ("^-g^-g^"); |
| @b{end case}; |
| @b{end} Compiler; |
| |
| @b{end} Common; |
| @end group |
| @end smallexample |
| |
| @item We create separate projects for the two programs: |
| |
| @smallexample |
| @group |
| File "prog1.gpr": |
| |
| @b{with} "common"; |
| @b{project} Prog1 @b{is} |
| |
| @b{for} Source_Dirs @b{use} ("prog1"); |
| @b{for} Object_Dir @b{use} "prog1/build/" & Common.Build; |
| |
| @b{package} Compiler @b{renames} Common.Compiler; |
| |
| @b{end} Prog1; |
| @end group |
| @end smallexample |
| |
| @smallexample |
| @group |
| File "prog2.gpr": |
| |
| @b{with} "common"; |
| @b{project} Prog2 @b{is} |
| |
| @b{for} Source_Dirs @b{use} ("prog2"); |
| @b{for} Object_Dir @b{use} "prog2/build/" & Common.Build; |
| |
| @b{package} Compiler @b{renames} Common.Compiler; |
| |
| @end group |
| @b{end} Prog2; |
| @end smallexample |
| |
| @item We create a wrapping project @code{Main}: |
| |
| @smallexample |
| @group |
| File "main.gpr": |
| |
| @b{with} "common"; |
| @b{with} "prog1"; |
| @b{with} "prog2"; |
| @b{project} Main @b{is} |
| |
| @b{package} Compiler @b{renames} Common.Compiler; |
| |
| @b{end} Main; |
| @end group |
| @end smallexample |
| |
| @item Finally we need to create a dummy procedure that @code{with}s (either |
| explicitly or implicitly) all the sources of our two programs. |
| |
| @end enumerate |
| |
| @noindent |
| Now we can build the programs using the command |
| |
| @smallexample |
| gnatmake ^-P^/PROJECT_FILE=^main dummy |
| @end smallexample |
| |
| @noindent |
| for the Debug mode, or |
| |
| @ifclear vms |
| @smallexample |
| gnatmake -Pmain -XBUILD=release |
| @end smallexample |
| @end ifclear |
| |
| @ifset vms |
| @smallexample |
| GNAT MAKE /PROJECT_FILE=main /EXTERNAL_REFERENCE=BUILD=release |
| @end smallexample |
| @end ifset |
| |
| @noindent |
| for the Release mode. |
| |
| @c ******************************** |
| @c * Project File Complete Syntax * |
| @c ******************************** |
| |
| @node Project File Complete Syntax |
| @section Project File Complete Syntax |
| |
| @smallexample |
| project ::= |
| context_clause project_declaration |
| |
| context_clause ::= |
| @{with_clause@} |
| |
| with_clause ::= |
| @b{with} path_name @{ , path_name @} ; |
| |
| path_name ::= |
| string_literal |
| |
| project_declaration ::= |
| simple_project_declaration | project_extension |
| |
| simple_project_declaration ::= |
| @b{project} <project_>simple_name @b{is} |
| @{declarative_item@} |
| @b{end} <project_>simple_name; |
| |
| project_extension ::= |
| @b{project} <project_>simple_name @b{extends} path_name @b{is} |
| @{declarative_item@} |
| @b{end} <project_>simple_name; |
| |
| declarative_item ::= |
| package_declaration | |
| typed_string_declaration | |
| other_declarative_item |
| |
| package_declaration ::= |
| package_specification | package_renaming |
| |
| package_specification ::= |
| @b{package} package_identifier @b{is} |
| @{simple_declarative_item@} |
| @b{end} package_identifier ; |
| |
| package_identifier ::= |
| @code{Naming} | @code{Builder} | @code{Compiler} | @code{Binder} | |
| @code{Linker} | @code{Finder} | @code{Cross_Reference} | |
| @code{^gnatls^gnatls^} | @code{IDE} | @code{Pretty_Printer} |
| |
| package_renaming ::== |
| @b{package} package_identifier @b{renames} |
| <project_>simple_name.package_identifier ; |
| |
| typed_string_declaration ::= |
| @b{type} <typed_string_>_simple_name @b{is} |
| ( string_literal @{, string_literal@} ); |
| |
| other_declarative_item ::= |
| attribute_declaration | |
| typed_variable_declaration | |
| variable_declaration | |
| case_construction |
| |
| attribute_declaration ::= |
| full_associative_array_declaration | |
| @b{for} attribute_designator @b{use} expression ; |
| |
| full_associative_array_declaration ::= |
| @b{for} <associative_array_attribute_>simple_name @b{use} |
| <project_>simple_name [ . <package_>simple_Name ] ' <attribute_>simple_name ; |
| |
| attribute_designator ::= |
| <simple_attribute_>simple_name | |
| <associative_array_attribute_>simple_name ( string_literal ) |
| |
| typed_variable_declaration ::= |
| <typed_variable_>simple_name : <typed_string_>name := string_expression ; |
| |
| variable_declaration ::= |
| <variable_>simple_name := expression; |
| |
| expression ::= |
| term @{& term@} |
| |
| term ::= |
| literal_string | |
| string_list | |
| <variable_>name | |
| external_value | |
| attribute_reference |
| |
| string_literal ::= |
| (same as Ada) |
| |
| string_list ::= |
| ( <string_>expression @{ , <string_>expression @} ) |
| |
| external_value ::= |
| @b{external} ( string_literal [, string_literal] ) |
| |
| attribute_reference ::= |
| attribute_prefix ' <simple_attribute_>simple_name [ ( literal_string ) ] |
| |
| attribute_prefix ::= |
| @b{project} | |
| <project_>simple_name | package_identifier | |
| <project_>simple_name . package_identifier |
| |
| case_construction ::= |
| @b{case} <typed_variable_>name @b{is} |
| @{case_item@} |
| @b{end case} ; |
| |
| case_item ::= |
| @b{when} discrete_choice_list => |
| @{case_construction | attribute_declaration@} |
| |
| discrete_choice_list ::= |
| string_literal @{| string_literal@} | |
| @b{others} |
| |
| name ::= |
| simple_name @{. simple_name@} |
| |
| simple_name ::= |
| identifier (same as Ada) |
| |
| @end smallexample |
| |
| @node The Cross-Referencing Tools gnatxref and gnatfind |
| @chapter The Cross-Referencing Tools @code{gnatxref} and @code{gnatfind} |
| @findex gnatxref |
| @findex gnatfind |
| |
| @noindent |
| The compiler generates cross-referencing information (unless |
| you set the @samp{-gnatx} switch), which are saved in the @file{.ali} files. |
| This information indicates where in the source each entity is declared and |
| referenced. Note that entities in package Standard are not included, but |
| entities in all other predefined units are included in the output. |
| |
| Before using any of these two tools, you need to compile successfully your |
| application, so that GNAT gets a chance to generate the cross-referencing |
| information. |
| |
| The two tools @code{gnatxref} and @code{gnatfind} take advantage of this |
| information to provide the user with the capability to easily locate the |
| declaration and references to an entity. These tools are quite similar, |
| the difference being that @code{gnatfind} is intended for locating |
| definitions and/or references to a specified entity or entities, whereas |
| @code{gnatxref} is oriented to generating a full report of all |
| cross-references. |
| |
| To use these tools, you must not compile your application using the |
| @option{-gnatx} switch on the @command{gnatmake} command line |
| (@pxref{The GNAT Make Program gnatmake}). Otherwise, cross-referencing |
| information will not be generated. |
| |
| @menu |
| * gnatxref Switches:: |
| * gnatfind Switches:: |
| * Project Files for gnatxref and gnatfind:: |
| * Regular Expressions in gnatfind and gnatxref:: |
| * Examples of gnatxref Usage:: |
| * Examples of gnatfind Usage:: |
| @end menu |
| |
| @node gnatxref Switches |
| @section @code{gnatxref} Switches |
| |
| @noindent |
| The command invocation for @code{gnatxref} is: |
| @smallexample |
| $ gnatxref [switches] sourcefile1 [sourcefile2 ...] |
| @end smallexample |
| |
| @noindent |
| where |
| |
| @table @code |
| @item sourcefile1, sourcefile2 |
| identifies the source files for which a report is to be generated. The |
| ``with''ed units will be processed too. You must provide at least one file. |
| |
| These file names are considered to be regular expressions, so for instance |
| specifying @file{source*.adb} is the same as giving every file in the current |
| directory whose name starts with @file{source} and whose extension is |
| @file{adb}. |
| |
| You shouldn't specify any directory name, just base names. @command{gnatxref} |
| and @command{gnatfind} will be able to locate these files by themselves using |
| the source path. If you specify directories, no result is produced. |
| |
| @end table |
| |
| @noindent |
| The switches can be : |
| @table @option |
| @c !sort! |
| @item ^-a^/ALL_FILES^ |
| @cindex @option{^-a^/ALL_FILES^} (@command{gnatxref}) |
| If this switch is present, @code{gnatfind} and @code{gnatxref} will parse |
| the read-only files found in the library search path. Otherwise, these files |
| will be ignored. This option can be used to protect Gnat sources or your own |
| libraries from being parsed, thus making @code{gnatfind} and @code{gnatxref} |
| much faster, and their output much smaller. Read-only here refers to access |
| or permissions status in the file system for the current user. |
| |
| @item -aIDIR |
| @cindex @option{-aIDIR} (@command{gnatxref}) |
| When looking for source files also look in directory DIR. The order in which |
| source file search is undertaken is the same as for @command{gnatmake}. |
| |
| @item -aODIR |
| @cindex @option{-aODIR} (@command{gnatxref}) |
| When searching for library and object files, look in directory |
| DIR. The order in which library files are searched is the same as for |
| @command{gnatmake}. |
| |
| @item -nostdinc |
| @cindex @option{-nostdinc} (@command{gnatxref}) |
| Do not look for sources in the system default directory. |
| |
| @item -nostdlib |
| @cindex @option{-nostdlib} (@command{gnatxref}) |
| Do not look for library files in the system default directory. |
| |
| @item --RTS=@var{rts-path} |
| @cindex @option{--RTS} (@command{gnatxref}) |
| Specifies the default location of the runtime library. Same meaning as the |
| equivalent @command{gnatmake} flag (@pxref{Switches for gnatmake}). |
| |
| @item ^-d^/DERIVED_TYPES^ |
| @cindex @option{^-d^/DERIVED_TYPES^} (@command{gnatxref}) |
| If this switch is set @code{gnatxref} will output the parent type |
| reference for each matching derived types. |
| |
| @item ^-f^/FULL_PATHNAME^ |
| @cindex @option{^-f^/FULL_PATHNAME^} (@command{gnatxref}) |
| If this switch is set, the output file names will be preceded by their |
| directory (if the file was found in the search path). If this switch is |
| not set, the directory will not be printed. |
| |
| @item ^-g^/IGNORE_LOCALS^ |
| @cindex @option{^-g^/IGNORE_LOCALS^} (@command{gnatxref}) |
| If this switch is set, information is output only for library-level |
| entities, ignoring local entities. The use of this switch may accelerate |
| @code{gnatfind} and @code{gnatxref}. |
| |
| @item -IDIR |
| @cindex @option{-IDIR} (@command{gnatxref}) |
| Equivalent to @samp{-aODIR -aIDIR}. |
| |
| @item -pFILE |
| @cindex @option{-pFILE} (@command{gnatxref}) |
| Specify a project file to use @xref{Project Files}. These project files are |
| the @file{.adp} files used by Glide. If you need to use the @file{.gpr} |
| project files, you should use gnatxref through the GNAT driver |
| (@command{gnat xref -Pproject}). |
| |
| By default, @code{gnatxref} and @code{gnatfind} will try to locate a |
| project file in the current directory. |
| |
| If a project file is either specified or found by the tools, then the content |
| of the source directory and object directory lines are added as if they |
| had been specified respectively by @samp{^-aI^/SOURCE_SEARCH^} |
| and @samp{^-aO^OBJECT_SEARCH^}. |
| @item ^-u^/UNUSED^ |
| Output only unused symbols. This may be really useful if you give your |
| main compilation unit on the command line, as @code{gnatxref} will then |
| display every unused entity and 'with'ed package. |
| |
| @ifclear vms |
| @item -v |
| Instead of producing the default output, @code{gnatxref} will generate a |
| @file{tags} file that can be used by vi. For examples how to use this |
| feature, see @ref{Examples of gnatxref Usage}. The tags file is output |
| to the standard output, thus you will have to redirect it to a file. |
| @end ifclear |
| |
| @end table |
| |
| @noindent |
| All these switches may be in any order on the command line, and may even |
| appear after the file names. They need not be separated by spaces, thus |
| you can say @samp{gnatxref ^-ag^/ALL_FILES/IGNORE_LOCALS^} instead of |
| @samp{gnatxref ^-a -g^/ALL_FILES /IGNORE_LOCALS^}. |
| |
| @node gnatfind Switches |
| @section @code{gnatfind} Switches |
| |
| @noindent |
| The command line for @code{gnatfind} is: |
| |
| @smallexample |
| $ gnatfind [switches] pattern[:sourcefile[:line[:column]]] |
| [file1 file2 ...] |
| @end smallexample |
| |
| @noindent |
| where |
| |
| @table @code |
| @item pattern |
| An entity will be output only if it matches the regular expression found |
| in @samp{pattern}, see @ref{Regular Expressions in gnatfind and gnatxref}. |
| |
| Omitting the pattern is equivalent to specifying @samp{*}, which |
| will match any entity. Note that if you do not provide a pattern, you |
| have to provide both a sourcefile and a line. |
| |
| Entity names are given in Latin-1, with uppercase/lowercase equivalence |
| for matching purposes. At the current time there is no support for |
| 8-bit codes other than Latin-1, or for wide characters in identifiers. |
| |
| @item sourcefile |
| @code{gnatfind} will look for references, bodies or declarations |
| of symbols referenced in @file{sourcefile}, at line @samp{line} |
| and column @samp{column}. See @ref{Examples of gnatfind Usage} |
| for syntax examples. |
| |
| @item line |
| is a decimal integer identifying the line number containing |
| the reference to the entity (or entities) to be located. |
| |
| @item column |
| is a decimal integer identifying the exact location on the |
| line of the first character of the identifier for the |
| entity reference. Columns are numbered from 1. |
| |
| @item file1 file2 ... |
| The search will be restricted to these source files. If none are given, then |
| the search will be done for every library file in the search path. |
| These file must appear only after the pattern or sourcefile. |
| |
| These file names are considered to be regular expressions, so for instance |
| specifying 'source*.adb' is the same as giving every file in the current |
| directory whose name starts with 'source' and whose extension is 'adb'. |
| |
| The location of the spec of the entity will always be displayed, even if it |
| isn't in one of file1, file2,... The occurrences of the entity in the |
| separate units of the ones given on the command line will also be displayed. |
| |
| Note that if you specify at least one file in this part, @code{gnatfind} may |
| sometimes not be able to find the body of the subprograms... |
| |
| @end table |
| |
| @noindent |
| At least one of 'sourcefile' or 'pattern' has to be present on |
| the command line. |
| |
| The following switches are available: |
| @table @option |
| @c !sort! |
| |
| @item ^-a^/ALL_FILES^ |
| @cindex @option{^-a^/ALL_FILES^} (@command{gnatfind}) |
| If this switch is present, @code{gnatfind} and @code{gnatxref} will parse |
| the read-only files found in the library search path. Otherwise, these files |
| will be ignored. This option can be used to protect Gnat sources or your own |
| libraries from being parsed, thus making @code{gnatfind} and @code{gnatxref} |
| much faster, and their output much smaller. Read-only here refers to access |
| or permission status in the file system for the current user. |
| |
| @item -aIDIR |
| @cindex @option{-aIDIR} (@command{gnatfind}) |
| When looking for source files also look in directory DIR. The order in which |
| source file search is undertaken is the same as for @command{gnatmake}. |
| |
| @item -aODIR |
| @cindex @option{-aODIR} (@command{gnatfind}) |
| When searching for library and object files, look in directory |
| DIR. The order in which library files are searched is the same as for |
| @command{gnatmake}. |
| |
| @item -nostdinc |
| @cindex @option{-nostdinc} (@command{gnatfind}) |
| Do not look for sources in the system default directory. |
| |
| @item -nostdlib |
| @cindex @option{-nostdlib} (@command{gnatfind}) |
| Do not look for library files in the system default directory. |
| |
| @item --RTS=@var{rts-path} |
| @cindex @option{--RTS} (@command{gnatfind}) |
| Specifies the default location of the runtime library. Same meaning as the |
| equivalent @command{gnatmake} flag (@pxref{Switches for gnatmake}). |
| |
| @item ^-d^/DERIVED_TYPE_INFORMATION^ |
| @cindex @option{^-d^/DERIVED_TYPE_INFORMATION^} (@code{gnatfind}) |
| If this switch is set, then @code{gnatfind} will output the parent type |
| reference for each matching derived types. |
| |
| @item ^-e^/EXPRESSIONS^ |
| @cindex @option{^-e^/EXPRESSIONS^} (@command{gnatfind}) |
| By default, @code{gnatfind} accept the simple regular expression set for |
| @samp{pattern}. If this switch is set, then the pattern will be |
| considered as full Unix-style regular expression. |
| |
| @item ^-f^/FULL_PATHNAME^ |
| @cindex @option{^-f^/FULL_PATHNAME^} (@command{gnatfind}) |
| If this switch is set, the output file names will be preceded by their |
| directory (if the file was found in the search path). If this switch is |
| not set, the directory will not be printed. |
| |
| @item ^-g^/IGNORE_LOCALS^ |
| @cindex @option{^-g^/IGNORE_LOCALS^} (@command{gnatfind}) |
| If this switch is set, information is output only for library-level |
| entities, ignoring local entities. The use of this switch may accelerate |
| @code{gnatfind} and @code{gnatxref}. |
| |
| @item -IDIR |
| @cindex @option{-IDIR} (@command{gnatfind}) |
| Equivalent to @samp{-aODIR -aIDIR}. |
| |
| @item -pFILE |
| @cindex @option{-pFILE} (@command{gnatfind}) |
| Specify a project file (@pxref{Project Files}) to use. |
| By default, @code{gnatxref} and @code{gnatfind} will try to locate a |
| project file in the current directory. |
| |
| If a project file is either specified or found by the tools, then the content |
| of the source directory and object directory lines are added as if they |
| had been specified respectively by @samp{^-aI^/SOURCE_SEARCH^} and |
| @samp{^-aO^/OBJECT_SEARCH^}. |
| |
| @item ^-r^/REFERENCES^ |
| @cindex @option{^-r^/REFERENCES^} (@command{gnatfind}) |
| By default, @code{gnatfind} will output only the information about the |
| declaration, body or type completion of the entities. If this switch is |
| set, the @code{gnatfind} will locate every reference to the entities in |
| the files specified on the command line (or in every file in the search |
| path if no file is given on the command line). |
| |
| @item ^-s^/PRINT_LINES^ |
| @cindex @option{^-s^/PRINT_LINES^} (@command{gnatfind}) |
| If this switch is set, then @code{gnatfind} will output the content |
| of the Ada source file lines were the entity was found. |
| |
| @item ^-t^/TYPE_HIERARCHY^ |
| @cindex @option{^-t^/TYPE_HIERARCHY^} (@command{gnatfind}) |
| If this switch is set, then @code{gnatfind} will output the type hierarchy for |
| the specified type. It act like -d option but recursively from parent |
| type to parent type. When this switch is set it is not possible to |
| specify more than one file. |
| |
| @end table |
| |
| @noindent |
| All these switches may be in any order on the command line, and may even |
| appear after the file names. They need not be separated by spaces, thus |
| you can say @samp{gnatxref ^-ag^/ALL_FILES/IGNORE_LOCALS^} instead of |
| @samp{gnatxref ^-a -g^/ALL_FILES /IGNORE_LOCALS^}. |
| |
| As stated previously, gnatfind will search in every directory in the |
| search path. You can force it to look only in the current directory if |
| you specify @code{*} at the end of the command line. |
| |
| @node Project Files for gnatxref and gnatfind |
| @section Project Files for @command{gnatxref} and @command{gnatfind} |
| |
| @noindent |
| Project files allow a programmer to specify how to compile its |
| application, where to find sources, etc. These files are used |
| @ifclear vms |
| primarily by the Glide Ada mode, but they can also be used |
| @end ifclear |
| by the two tools |
| @code{gnatxref} and @code{gnatfind}. |
| |
| A project file name must end with @file{.gpr}. If a single one is |
| present in the current directory, then @code{gnatxref} and @code{gnatfind} will |
| extract the information from it. If multiple project files are found, none of |
| them is read, and you have to use the @samp{-p} switch to specify the one |
| you want to use. |
| |
| The following lines can be included, even though most of them have default |
| values which can be used in most cases. |
| The lines can be entered in any order in the file. |
| Except for @file{src_dir} and @file{obj_dir}, you can only have one instance of |
| each line. If you have multiple instances, only the last one is taken into |
| account. |
| |
| @table @code |
| @item src_dir=DIR |
| [default: @code{"^./^[]^"}] |
| specifies a directory where to look for source files. Multiple @code{src_dir} |
| lines can be specified and they will be searched in the order they |
| are specified. |
| |
| @item obj_dir=DIR |
| [default: @code{"^./^[]^"}] |
| specifies a directory where to look for object and library files. Multiple |
| @code{obj_dir} lines can be specified, and they will be searched in the order |
| they are specified |
| |
| @item comp_opt=SWITCHES |
| [default: @code{""}] |
| creates a variable which can be referred to subsequently by using |
| the @code{$@{comp_opt@}} notation. This is intended to store the default |
| switches given to @command{gnatmake} and @command{gcc}. |
| |
| @item bind_opt=SWITCHES |
| [default: @code{""}] |
| creates a variable which can be referred to subsequently by using |
| the @samp{$@{bind_opt@}} notation. This is intended to store the default |
| switches given to @command{gnatbind}. |
| |
| @item link_opt=SWITCHES |
| [default: @code{""}] |
| creates a variable which can be referred to subsequently by using |
| the @samp{$@{link_opt@}} notation. This is intended to store the default |
| switches given to @command{gnatlink}. |
| |
| @item main=EXECUTABLE |
| [default: @code{""}] |
| specifies the name of the executable for the application. This variable can |
| be referred to in the following lines by using the @samp{$@{main@}} notation. |
| |
| @ifset vms |
| @item comp_cmd=COMMAND |
| [default: @code{"GNAT COMPILE /SEARCH=$@{src_dir@} /DEBUG /TRY_SEMANTICS"}] |
| @end ifset |
| @ifclear vms |
| @item comp_cmd=COMMAND |
| [default: @code{"gcc -c -I$@{src_dir@} -g -gnatq"}] |
| @end ifclear |
| specifies the command used to compile a single file in the application. |
| |
| @ifset vms |
| @item make_cmd=COMMAND |
| [default: @code{"GNAT MAKE $@{main@} |
| /SOURCE_SEARCH=$@{src_dir@} /OBJECT_SEARCH=$@{obj_dir@} |
| /DEBUG /TRY_SEMANTICS /COMPILER_QUALIFIERS $@{comp_opt@} |
| /BINDER_QUALIFIERS $@{bind_opt@} /LINKER_QUALIFIERS $@{link_opt@}"}] |
| @end ifset |
| @ifclear vms |
| @item make_cmd=COMMAND |
| [default: @code{"gnatmake $@{main@} -aI$@{src_dir@} |
| -aO$@{obj_dir@} -g -gnatq -cargs $@{comp_opt@} |
| -bargs $@{bind_opt@} -largs $@{link_opt@}"}] |
| @end ifclear |
| specifies the command used to recompile the whole application. |
| |
| @item run_cmd=COMMAND |
| [default: @code{"$@{main@}"}] |
| specifies the command used to run the application. |
| |
| @item debug_cmd=COMMAND |
| [default: @code{"gdb $@{main@}"}] |
| specifies the command used to debug the application |
| |
| @end table |
| |
| @noindent |
| @command{gnatxref} and @command{gnatfind} only take into account the |
| @code{src_dir} and @code{obj_dir} lines, and ignore the others. |
| |
| @node Regular Expressions in gnatfind and gnatxref |
| @section Regular Expressions in @code{gnatfind} and @code{gnatxref} |
| |
| @noindent |
| As specified in the section about @command{gnatfind}, the pattern can be a |
| regular expression. Actually, there are to set of regular expressions |
| which are recognized by the program : |
| |
| @table @code |
| @item globbing patterns |
| These are the most usual regular expression. They are the same that you |
| generally used in a Unix shell command line, or in a DOS session. |
| |
| Here is a more formal grammar : |
| @smallexample |
| @group |
| @iftex |
| @leftskip=.5cm |
| @end iftex |
| regexp ::= term |
| term ::= elmt -- matches elmt |
| term ::= elmt elmt -- concatenation (elmt then elmt) |
| term ::= * -- any string of 0 or more characters |
| term ::= ? -- matches any character |
| term ::= [char @{char@}] -- matches any character listed |
| term ::= [char - char] -- matches any character in range |
| @end group |
| @end smallexample |
| |
| @item full regular expression |
| The second set of regular expressions is much more powerful. This is the |
| type of regular expressions recognized by utilities such a @file{grep}. |
| |
| The following is the form of a regular expression, expressed in Ada |
| reference manual style BNF is as follows |
| |
| @smallexample |
| @iftex |
| @leftskip=.5cm |
| @end iftex |
| @group |
| regexp ::= term @{| term@} -- alternation (term or term ...) |
| |
| term ::= item @{item@} -- concatenation (item then item) |
| |
| item ::= elmt -- match elmt |
| item ::= elmt * -- zero or more elmt's |
| item ::= elmt + -- one or more elmt's |
| item ::= elmt ? -- matches elmt or nothing |
| @end group |
| @group |
| elmt ::= nschar -- matches given character |
| elmt ::= [nschar @{nschar@}] -- matches any character listed |
| elmt ::= [^^^ nschar @{nschar@}] -- matches any character not listed |
| elmt ::= [char - char] -- matches chars in given range |
| elmt ::= \ char -- matches given character |
| elmt ::= . -- matches any single character |
| elmt ::= ( regexp ) -- parens used for grouping |
| |
| char ::= any character, including special characters |
| nschar ::= any character except ()[].*+?^^^ |
| @end group |
| @end smallexample |
| |
| Following are a few examples : |
| |
| @table @samp |
| @item abcde|fghi |
| will match any of the two strings 'abcde' and 'fghi'. |
| |
| @item abc*d |
| will match any string like 'abd', 'abcd', 'abccd', 'abcccd', and so on |
| |
| @item [a-z]+ |
| will match any string which has only lowercase characters in it (and at |
| least one character |
| |
| @end table |
| @end table |
| |
| @node Examples of gnatxref Usage |
| @section Examples of @code{gnatxref} Usage |
| |
| @subsection General Usage |
| |
| @noindent |
| For the following examples, we will consider the following units : |
| |
| @smallexample @c ada |
| @group |
| @cartouche |
| main.ads: |
| 1: with Bar; |
| 2: package Main is |
| 3: procedure Foo (B : in Integer); |
| 4: C : Integer; |
| 5: private |
| 6: D : Integer; |
| 7: end Main; |
| |
| main.adb: |
| 1: package body Main is |
| 2: procedure Foo (B : in Integer) is |
| 3: begin |
| 4: C := B; |
| 5: D := B; |
| 6: Bar.Print (B); |
| 7: Bar.Print (C); |
| 8: end Foo; |
| 9: end Main; |
| |
| bar.ads: |
| 1: package Bar is |
| 2: procedure Print (B : Integer); |
| 3: end bar; |
| @end cartouche |
| @end group |
| @end smallexample |
| |
| @table @code |
| |
| @noindent |
| The first thing to do is to recompile your application (for instance, in |
| that case just by doing a @samp{gnatmake main}, so that GNAT generates |
| the cross-referencing information. |
| You can then issue any of the following commands: |
| |
| @item gnatxref main.adb |
| @code{gnatxref} generates cross-reference information for main.adb |
| and every unit 'with'ed by main.adb. |
| |
| The output would be: |
| @smallexample |
| @iftex |
| @leftskip=0cm |
| @end iftex |
| B Type: Integer |
| Decl: bar.ads 2:22 |
| B Type: Integer |
| Decl: main.ads 3:20 |
| Body: main.adb 2:20 |
| Ref: main.adb 4:13 5:13 6:19 |
| Bar Type: Unit |
| Decl: bar.ads 1:9 |
| Ref: main.adb 6:8 7:8 |
| main.ads 1:6 |
| C Type: Integer |
| Decl: main.ads 4:5 |
| Modi: main.adb 4:8 |
| Ref: main.adb 7:19 |
| D Type: Integer |
| Decl: main.ads 6:5 |
| Modi: main.adb 5:8 |
| Foo Type: Unit |
| Decl: main.ads 3:15 |
| Body: main.adb 2:15 |
| Main Type: Unit |
| Decl: main.ads 2:9 |
| Body: main.adb 1:14 |
| Print Type: Unit |
| Decl: bar.ads 2:15 |
| Ref: main.adb 6:12 7:12 |
| @end smallexample |
| |
| @noindent |
| that is the entity @code{Main} is declared in main.ads, line 2, column 9, |
| its body is in main.adb, line 1, column 14 and is not referenced any where. |
| |
| The entity @code{Print} is declared in bar.ads, line 2, column 15 and it |
| it referenced in main.adb, line 6 column 12 and line 7 column 12. |
| |
| @item gnatxref package1.adb package2.ads |
| @code{gnatxref} will generates cross-reference information for |
| package1.adb, package2.ads and any other package 'with'ed by any |
| of these. |
| |
| @end table |
| |
| @ifclear vms |
| @subsection Using gnatxref with vi |
| |
| @code{gnatxref} can generate a tags file output, which can be used |
| directly from @file{vi}. Note that the standard version of @file{vi} |
| will not work properly with overloaded symbols. Consider using another |
| free implementation of @file{vi}, such as @file{vim}. |
| |
| @smallexample |
| $ gnatxref -v gnatfind.adb > tags |
| @end smallexample |
| |
| @noindent |
| will generate the tags file for @code{gnatfind} itself (if the sources |
| are in the search path!). |
| |
| From @file{vi}, you can then use the command @samp{:tag @i{entity}} |
| (replacing @i{entity} by whatever you are looking for), and vi will |
| display a new file with the corresponding declaration of entity. |
| @end ifclear |
| |
| @node Examples of gnatfind Usage |
| @section Examples of @code{gnatfind} Usage |
| |
| @table @code |
| |
| @item gnatfind ^-f^/FULL_PATHNAME^ xyz:main.adb |
| Find declarations for all entities xyz referenced at least once in |
| main.adb. The references are search in every library file in the search |
| path. |
| |
| The directories will be printed as well (as the @samp{^-f^/FULL_PATHNAME^} |
| switch is set) |
| |
| The output will look like: |
| @smallexample |
| ^directory/^[directory]^main.ads:106:14: xyz <= declaration |
| ^directory/^[directory]^main.adb:24:10: xyz <= body |
| ^directory/^[directory]^foo.ads:45:23: xyz <= declaration |
| @end smallexample |
| |
| @noindent |
| that is to say, one of the entities xyz found in main.adb is declared at |
| line 12 of main.ads (and its body is in main.adb), and another one is |
| declared at line 45 of foo.ads |
| |
| @item gnatfind ^-fs^/FULL_PATHNAME/SOURCE_LINE^ xyz:main.adb |
| This is the same command as the previous one, instead @code{gnatfind} will |
| display the content of the Ada source file lines. |
| |
| The output will look like: |
| |
| @smallexample |
| ^directory/^[directory]^main.ads:106:14: xyz <= declaration |
| procedure xyz; |
| ^directory/^[directory]^main.adb:24:10: xyz <= body |
| procedure xyz is |
| ^directory/^[directory]^foo.ads:45:23: xyz <= declaration |
| xyz : Integer; |
| @end smallexample |
| |
| @noindent |
| This can make it easier to find exactly the location your are looking |
| for. |
| |
| @item gnatfind ^-r^/REFERENCES^ "*x*":main.ads:123 foo.adb |
| Find references to all entities containing an x that are |
| referenced on line 123 of main.ads. |
| The references will be searched only in main.ads and foo.adb. |
| |
| @item gnatfind main.ads:123 |
| Find declarations and bodies for all entities that are referenced on |
| line 123 of main.ads. |
| |
| This is the same as @code{gnatfind "*":main.adb:123}. |
| |
| @item gnatfind ^mydir/^[mydir]^main.adb:123:45 |
| Find the declaration for the entity referenced at column 45 in |
| line 123 of file main.adb in directory mydir. Note that it |
| is usual to omit the identifier name when the column is given, |
| since the column position identifies a unique reference. |
| |
| The column has to be the beginning of the identifier, and should not |
| point to any character in the middle of the identifier. |
| |
| @end table |
| |
| @c ********************************* |
| @node The GNAT Pretty-Printer gnatpp |
| @chapter The GNAT Pretty-Printer @command{gnatpp} |
| @findex gnatpp |
| @cindex Pretty-Printer |
| |
| @noindent |
| ^The @command{gnatpp} tool^GNAT PRETTY^ is an ASIS-based utility |
| for source reformatting / pretty-printing. |
| It takes an Ada source file as input and generates a reformatted |
| version as output. |
| You can specify various style directives via switches; e.g., |
| identifier case conventions, rules of indentation, and comment layout. |
| |
| To produce a reformatted file, @command{gnatpp} generates and uses the ASIS |
| tree for the input source and thus requires the input to be syntactically and |
| semantically legal. |
| If this condition is not met, @command{gnatpp} will terminate with an |
| error message; no output file will be generated. |
| |
| If the compilation unit |
| contained in the input source depends semantically upon units located |
| outside the current directory, you have to provide the source search path |
| when invoking @command{gnatpp}, if these units are contained in files with |
| names that do not follow the GNAT file naming rules, you have to provide |
| the configuration file describing the corresponding naming scheme; |
| see the description of the @command{gnatpp} |
| switches below. Another possibility is to use a project file and to |
| call @command{gnatpp} through the @command{gnat} driver |
| |
| The @command{gnatpp} command has the form |
| |
| @smallexample |
| $ gnatpp [@var{switches}] @var{filename} |
| @end smallexample |
| |
| @noindent |
| where |
| @itemize @bullet |
| @item |
| @var{switches} is an optional sequence of switches defining such properties as |
| the formatting rules, the source search path, and the destination for the |
| output source file |
| |
| @item |
| @var{filename} is the name (including the extension) of the source file to |
| reformat; ``wildcards'' or several file names on the same gnatpp command are |
| allowed. The file name may contain path information; it does not have to |
| follow the GNAT file naming rules |
| @end itemize |
| |
| @menu |
| * Switches for gnatpp:: |
| * Formatting Rules:: |
| @end menu |
| |
| @node Switches for gnatpp |
| @section Switches for @command{gnatpp} |
| |
| @noindent |
| The following subsections describe the various switches accepted by |
| @command{gnatpp}, organized by category. |
| |
| @ifclear vms |
| You specify a switch by supplying a name and generally also a value. |
| In many cases the values for a switch with a given name are incompatible with |
| each other |
| (for example the switch that controls the casing of a reserved word may have |
| exactly one value: upper case, lower case, or |
| mixed case) and thus exactly one such switch can be in effect for an |
| invocation of @command{gnatpp}. |
| If more than one is supplied, the last one is used. |
| However, some values for the same switch are mutually compatible. |
| You may supply several such switches to @command{gnatpp}, but then |
| each must be specified in full, with both the name and the value. |
| Abbreviated forms (the name appearing once, followed by each value) are |
| not permitted. |
| For example, to set |
| the alignment of the assignment delimiter both in declarations and in |
| assignment statements, you must write @option{-A2A3} |
| (or @option{-A2 -A3}), but not @option{-A23}. |
| @end ifclear |
| |
| @ifset vms |
| In many cases the set of options for a given qualifier are incompatible with |
| each other (for example the qualifier that controls the casing of a reserved |
| word may have exactly one option, which specifies either upper case, lower |
| case, or mixed case), and thus exactly one such option can be in effect for |
| an invocation of @command{gnatpp}. |
| If more than one is supplied, the last one is used. |
| However, some qualifiers have options that are mutually compatible, |
| and then you may then supply several such options when invoking |
| @command{gnatpp}. |
| @end ifset |
| |
| In most cases, it is obvious whether or not the |
| ^values for a switch with a given name^options for a given qualifier^ |
| are compatible with each other. |
| When the semantics might not be evident, the summaries below explicitly |
| indicate the effect. |
| |
| @menu |
| * Alignment Control:: |
| * Casing Control:: |
| * Construct Layout Control:: |
| * General Text Layout Control:: |
| * Other Formatting Options:: |
| * Setting the Source Search Path:: |
| * Output File Control:: |
| * Other gnatpp Switches:: |
| @end menu |
| |
| @node Alignment Control |
| @subsection Alignment Control |
| @cindex Alignment control in @command{gnatpp} |
| |
| @noindent |
| Programs can be easier to read if certain constructs are vertically aligned. |
| By default all alignments are set ON. |
| Through the @option{^-A0^/ALIGN=OFF^} switch you may reset the default to |
| OFF, and then use one or more of the other |
| ^@option{-A@var{n}} switches^@option{/ALIGN} options^ |
| to activate alignment for specific constructs. |
| |
| @table @option |
| @cindex @option{^-A@var{n}^/ALIGN^} (@command{gnatpp}) |
| |
| @ifset vms |
| @item /ALIGN=ON |
| Set all alignments to ON |
| @end ifset |
| |
| @item ^-A0^/ALIGN=OFF^ |
| Set all alignments to OFF |
| |
| @item ^-A1^/ALIGN=COLONS^ |
| Align @code{:} in declarations |
| |
| @item ^-A2^/ALIGN=DECLARATIONS^ |
| Align @code{:=} in initializations in declarations |
| |
| @item ^-A3^/ALIGN=STATEMENTS^ |
| Align @code{:=} in assignment statements |
| |
| @item ^-A4^/ALIGN=ARROWS^ |
| Align @code{=>} in associations |
| |
| @item ^-A5^/ALIGN=COMPONENT_CLAUSES^ |
| Align @code{at} keywords in the component clauses in record |
| representation clauses |
| @end table |
| |
| @noindent |
| The @option{^-A^/ALIGN^} switches are mutually compatible; any combination |
| is allowed. |
| |
| @node Casing Control |
| @subsection Casing Control |
| @cindex Casing control in @command{gnatpp} |
| |
| @noindent |
| @command{gnatpp} allows you to specify the casing for reserved words, |
| pragma names, attribute designators and identifiers. |
| For identifiers you may define a |
| general rule for name casing but also override this rule |
| via a set of dictionary files. |
| |
| Three types of casing are supported: lower case, upper case, and mixed case. |
| Lower and upper case are self-explanatory (but since some letters in |
| Latin1 and other GNAT-supported character sets |
| exist only in lower-case form, an upper case conversion will have no |
| effect on them.) |
| ``Mixed case'' means that the first letter, and also each letter immediately |
| following an underscore, are converted to their uppercase forms; |
| all the other letters are converted to their lowercase forms. |
| |
| @table @option |
| @cindex @option{^-a@var{x}^/ATTRIBUTE^} (@command{gnatpp}) |
| @item ^-aL^/ATTRIBUTE_CASING=LOWER_CASE^ |
| Attribute designators are lower case |
| |
| @item ^-aU^/ATTRIBUTE_CASING=UPPER_CASE^ |
| Attribute designators are upper case |
| |
| @item ^-aM^/ATTRIBUTE_CASING=MIXED_CASE^ |
| Attribute designators are mixed case (this is the default) |
| |
| @cindex @option{^-k@var{x}^/KEYWORD_CASING^} (@command{gnatpp}) |
| @item ^-kL^/KEYWORD_CASING=LOWER_CASE^ |
| Keywords (technically, these are known in Ada as @emph{reserved words}) are |
| lower case (this is the default) |
| |
| @item ^-kU^/KEYWORD_CASING=UPPER_CASE^ |
| Keywords are upper case |
| |
| @cindex @option{^-n@var{x}^/NAME_CASING^} (@command{gnatpp}) |
| @item ^-nD^/NAME_CASING=AS_DECLARED^ |
| Name casing for defining occurrences are as they appear in the source file |
| (this is the default) |
| |
| @item ^-nU^/NAME_CASING=UPPER_CASE^ |
| Names are in upper case |
| |
| @item ^-nL^/NAME_CASING=LOWER_CASE^ |
| Names are in lower case |
| |
| @item ^-nM^/NAME_CASING=MIXED_CASE^ |
| Names are in mixed case |
| |
| @cindex @option{^-p@var{x}^/PRAGMA_CASING^} (@command{gnatpp}) |
| @item ^-pL^/PRAGMA_CASING=LOWER_CASE^ |
| Pragma names are lower case |
| |
| @item ^-pU^/PRAGMA_CASING=UPPER_CASE^ |
| Pragma names are upper case |
| |
| @item ^-pM^/PRAGMA_CASING=MIXED_CASE^ |
| Pragma names are mixed case (this is the default) |
| |
| @item ^-D@var{file}^/DICTIONARY=@var{file}^ |
| @cindex @option{^-D^/DICTIONARY^} (@command{gnatpp}) |
| Use @var{file} as a @emph{dictionary file} that defines |
| the casing for a set of specified names, |
| thereby overriding the effect on these names by |
| any explicit or implicit |
| ^-n^/NAME_CASING^ switch. |
| To supply more than one dictionary file, |
| use ^several @option{-D} switches^a list of files as options^. |
| |
| @noindent |
| @option{gnatpp} implicitly uses a @emph{default dictionary file} |
| to define the casing for the Ada predefined names and |
| the names declared in the GNAT libraries. |
| |
| @item ^-D-^/SPECIFIC_CASING^ |
| @cindex @option{^-D-^/SPECIFIC_CASING^} (@command{gnatpp}) |
| Do not use the default dictionary file; |
| instead, use the casing |
| defined by a @option{^-n^/NAME_CASING^} switch and any explicit |
| dictionary file(s) |
| @end table |
| |
| @noindent |
| The structure of a dictionary file, and details on the conventions |
| used in the default dictionary file, are defined in @ref{Name Casing}. |
| |
| The @option{^-D-^/SPECIFIC_CASING^} and |
| @option{^-D@var{file}^/DICTIONARY=@var{file}^} switches are mutually |
| compatible. |
| |
| @node Construct Layout Control |
| @subsection Construct Layout Control |
| @cindex Layout control in @command{gnatpp} |
| |
| @noindent |
| This group of @command{gnatpp} switches controls the layout of comments and |
| complex syntactic constructs. See @ref{Formatting Comments} for details |
| on their effect. |
| |
| @table @option |
| @cindex @option{^-c@var{n}^/COMMENTS_LAYOUT^} (@command{gnatpp}) |
| @item ^-c0^/COMMENTS_LAYOUT=UNTOUCHED^ |
| All the comments remain unchanged |
| |
| @item ^-c1^/COMMENTS_LAYOUT=DEFAULT^ |
| GNAT-style comment line indentation (this is the default). |
| |
| @item ^-c2^/COMMENTS_LAYOUT=STANDARD_INDENT^ |
| Reference-manual comment line indentation. |
| |
| @item ^-c3^/COMMENTS_LAYOUT=GNAT_BEGINNING^ |
| GNAT-style comment beginning |
| |
| @item ^-c4^/COMMENTS_LAYOUT=REFORMAT^ |
| Reformat comment blocks |
| |
| @cindex @option{^-l@var{n}^/CONSTRUCT_LAYOUT^} (@command{gnatpp}) |
| @item ^-l1^/CONSTRUCT_LAYOUT=GNAT^ |
| GNAT-style layout (this is the default) |
| |
| @item ^-l2^/CONSTRUCT_LAYOUT=COMPACT^ |
| Compact layout |
| |
| @item ^-l3^/CONSTRUCT_LAYOUT=UNCOMPACT^ |
| Uncompact layout |
| |
| @cindex @option{^-N^/NOTABS^} (@command{gnatpp}) |
| @item ^-N^/NOTABS^ |
| All the VT characters are removed from the comment text. All the HT characters |
| are expanded with the sequences of space characters to get to the next tab |
| stops. |
| |
| @cindex @option{^--no-separate-is^/NO_SEPARATE_IS^} (@command{gnatpp}) |
| @item ^--no-separate-is^/NO_SEPARATE_IS^ |
| Do not place the keyword @code{is} on a separate line in a subprogram body in |
| case if the specification occupies more then one line. |
| |
| @end table |
| |
| @ifclear vms |
| @noindent |
| The @option{-c1} and @option{-c2} switches are incompatible. |
| The @option{-c3} and @option{-c4} switches are compatible with each other and |
| also with @option{-c1} and @option{-c2}. The @option{-c0} switch disables all |
| the other comment formatting switches. |
| |
| The @option{-l1}, @option{-l2}, and @option{-l3} switches are incompatible. |
| @end ifclear |
| |
| @ifset vms |
| @noindent |
| For the @option{/COMMENTS_LAYOUT} qualifier: |
| @itemize @bullet |
| @item |
| The @option{DEFAULT} and @option{STANDARD_INDENT} options are incompatible. |
| @item |
| The @option{GNAT_BEGINNING} and @option{REFORMAT} options are compatible with |
| each other and also with @option{DEFAULT} and @option{STANDARD_INDENT}. |
| @end itemize |
| |
| @noindent |
| The @option{GNAT}, @option{COMPACT}, and @option{UNCOMPACT} options for the |
| @option{/CONSTRUCT_LAYOUT} qualifier are incompatible. |
| @end ifset |
| |
| @node General Text Layout Control |
| @subsection General Text Layout Control |
| |
| @noindent |
| These switches allow control over line length and indentation. |
| |
| @table @option |
| @item ^-M@i{nnn}^/LINE_LENGTH_MAX=@i{nnn}^ |
| @cindex @option{^-M^/LINE_LENGTH^} (@command{gnatpp}) |
| Maximum line length, @i{nnn} from 32 ..256, the default value is 79 |
| |
| @item ^-i@i{nnn}^/INDENTATION_LEVEL=@i{nnn}^ |
| @cindex @option{^-i^/INDENTATION_LEVEL^} (@command{gnatpp}) |
| Indentation level, @i{nnn} from 1 .. 9, the default value is 3 |
| |
| @item ^-cl@i{nnn}^/CONTINUATION_INDENT=@i{nnn}^ |
| @cindex @option{^-cl^/CONTINUATION_INDENT^} (@command{gnatpp}) |
| Indentation level for continuation lines (relative to the line being |
| continued), @i{nnn} from 1 .. 9. |
| The default |
| value is one less then the (normal) indentation level, unless the |
| indentation is set to 1 (in which case the default value for continuation |
| line indentation is also 1) |
| @end table |
| |
| @node Other Formatting Options |
| @subsection Other Formatting Options |
| |
| @noindent |
| These switches control the inclusion of missing end/exit labels, and |
| the indentation level in @b{case} statements. |
| |
| @table @option |
| @item ^-e^/NO_MISSED_LABELS^ |
| @cindex @option{^-e^/NO_MISSED_LABELS^} (@command{gnatpp}) |
| Do not insert missing end/exit labels. An end label is the name of |
| a construct that may optionally be repeated at the end of the |
| construct's declaration; |
| e.g., the names of packages, subprograms, and tasks. |
| An exit label is the name of a loop that may appear as target |
| of an exit statement within the loop. |
| By default, @command{gnatpp} inserts these end/exit labels when |
| they are absent from the original source. This option suppresses such |
| insertion, so that the formatted source reflects the original. |
| |
| @item ^-ff^/FORM_FEED_AFTER_PRAGMA_PAGE^ |
| @cindex @option{^-ff^/FORM_FEED_AFTER_PRAGMA_PAGE^} (@command{gnatpp}) |
| Insert a Form Feed character after a pragma Page. |
| |
| @item ^-T@i{nnn}^/MAX_INDENT=@i{nnn}^ |
| @cindex @option{^-T^/MAX_INDENT^} (@command{gnatpp}) |
| Do not use an additional indentation level for @b{case} alternatives |
| and variants if there are @i{nnn} or more (the default |
| value is 10). |
| If @i{nnn} is 0, an additional indentation level is |
| used for @b{case} alternatives and variants regardless of their number. |
| @end table |
| |
| @node Setting the Source Search Path |
| @subsection Setting the Source Search Path |
| |
| @noindent |
| To define the search path for the input source file, @command{gnatpp} |
| uses the same switches as the GNAT compiler, with the same effects. |
| |
| @table @option |
| @item ^-I^/SEARCH=^@var{dir} |
| @cindex @option{^-I^/SEARCH^} (@code{gnatpp}) |
| The same as the corresponding gcc switch |
| |
| @item ^-I-^/NOCURRENT_DIRECTORY^ |
| @cindex @option{^-I-^/NOCURRENT_DIRECTORY^} (@code{gnatpp}) |
| The same as the corresponding gcc switch |
| |
| @item ^-gnatec^/CONFIGURATION_PRAGMAS_FILE^=@var{path} |
| @cindex @option{^-gnatec^/CONFIGURATION_PRAGMAS_FILE^} (@code{gnatpp}) |
| The same as the corresponding gcc switch |
| |
| @item ^--RTS^/RUNTIME_SYSTEM^=@var{path} |
| @cindex @option{^--RTS^/RUNTIME_SYSTEM^} (@code{gnatpp}) |
| The same as the corresponding gcc switch |
| |
| @end table |
| |
| @node Output File Control |
| @subsection Output File Control |
| |
| @noindent |
| By default the output is sent to the file whose name is obtained by appending |
| the ^@file{.pp}^@file{$PP}^ suffix to the name of the input file |
| (if the file with this name already exists, it is unconditionally overwritten). |
| Thus if the input file is @file{^my_ada_proc.adb^MY_ADA_PROC.ADB^} then |
| @command{gnatpp} will produce @file{^my_ada_proc.adb.pp^MY_ADA_PROC.ADB$PP^} |
| as output file. |
| The output may be redirected by the following switches: |
| |
| @table @option |
| @item ^-pipe^/STANDARD_OUTPUT^ |
| @cindex @option{^-pipe^/STANDARD_OUTPUT^} (@code{gnatpp}) |
| Send the output to @code{Standard_Output} |
| |
| @item ^-o @var{output_file}^/OUTPUT=@var{output_file}^ |
| @cindex @option{^-o^/OUTPUT^} (@code{gnatpp}) |
| Write the output into @var{output_file}. |
| If @var{output_file} already exists, @command{gnatpp} terminates without |
| reading or processing the input file. |
| |
| @item ^-of ^/FORCED_OUTPUT=^@var{output_file} |
| @cindex @option{^-of^/FORCED_OUTPUT^} (@code{gnatpp}) |
| Write the output into @var{output_file}, overwriting the existing file |
| (if one is present). |
| |
| @item ^-r^/REPLACE^ |
| @cindex @option{^-r^/REPLACE^} (@code{gnatpp}) |
| Replace the input source file with the reformatted output, and copy the |
| original input source into the file whose name is obtained by appending the |
| ^@file{.npp}^@file{$NPP}^ suffix to the name of the input file. |
| If a file with this name already exists, @command{gnatpp} terminates without |
| reading or processing the input file. |
| |
| @item ^-rf^/OVERRIDING_REPLACE^ |
| @cindex @option{^-rf^/OVERRIDING_REPLACE^} (@code{gnatpp}) |
| Like @option{^-r^/REPLACE^} except that if the file with the specified name |
| already exists, it is overwritten. |
| |
| @item ^-rnb^/NO_BACKUP^ |
| @cindex @option{^-rnb^/NO_BACKUP^} (@code{gnatpp}) |
| Replace the input source file with the reformatted output without |
| creating any backup copy of the input source. |
| |
| @item ^--eol=@var{xxx}^/END_OF_LINE=@var{xxx}^ |
| @cindex @option{^--eol^/END_OF_LINE^} (@code{gnatpp}) |
| Specifies the format of the reformatted output file. The @var{xxx} |
| ^string specified with the switch^option^ may be either |
| @itemize @bullet |
| @item ``@option{^dos^DOS^}'' MS DOS style, lines end with CR LF characters |
| @item ``@option{^crlf^CRLF^}'' |
| the same as @option{^crlf^CRLF^} |
| @item ``@option{^unix^UNIX^}'' UNIX style, lines end with LF character |
| @item ``@option{^lf^LF^}'' |
| the same as @option{^unix^UNIX^} |
| @end itemize |
| |
| @end table |
| |
| @noindent |
| Options @option{^-pipe^/STANDARD_OUTPUT^}, |
| @option{^-o^/OUTPUT^} and |
| @option{^-of^/FORCED_OUTPUT^} are allowed only if the call to gnatpp |
| contains only one file to reformat. |
| Option |
| @option{^--eol^/END_OF_LINE^} |
| cannot be used together |
| with @option{^-pipe^/STANDARD_OUTPUT^} option. |
| |
| @node Other gnatpp Switches |
| @subsection Other @code{gnatpp} Switches |
| |
| @noindent |
| The additional @command{gnatpp} switches are defined in this subsection. |
| |
| @table @option |
| @item ^-files @var{filename}^/FILES=@var{output_file}^ |
| @cindex @option{^-files^/FILES^} (@code{gnatpp}) |
| Take the argument source files from the specified file. This file should be an |
| ordinary textual file containing file names separated by spaces or |
| line breaks. You can use this switch more then once in the same call to |
| @command{gnatpp}. You also can combine this switch with explicit list of |
| files. |
| |
| @item ^-v^/VERBOSE^ |
| @cindex @option{^-v^/VERBOSE^} (@code{gnatpp}) |
| Verbose mode; |
| @command{gnatpp} generates version information and then |
| a trace of the actions it takes to produce or obtain the ASIS tree. |
| |
| @item ^-w^/WARNINGS^ |
| @cindex @option{^-w^/WARNINGS^} (@code{gnatpp}) |
| Warning mode; |
| @command{gnatpp} generates a warning whenever it cannot provide |
| a required layout in the result source. |
| @end table |
| |
| @node Formatting Rules |
| @section Formatting Rules |
| |
| @noindent |
| The following subsections show how @command{gnatpp} treats ``white space'', |
| comments, program layout, and name casing. |
| They provide the detailed descriptions of the switches shown above. |
| |
| @menu |
| * White Space and Empty Lines:: |
| * Formatting Comments:: |
| * Construct Layout:: |
| * Name Casing:: |
| @end menu |
| |
| @node White Space and Empty Lines |
| @subsection White Space and Empty Lines |
| |
| @noindent |
| @command{gnatpp} does not have an option to control space characters. |
| It will add or remove spaces according to the style illustrated by the |
| examples in the @cite{Ada Reference Manual}. |
| |
| The only format effectors |
| (see @cite{Ada Reference Manual}, paragraph 2.1(13)) |
| that will appear in the output file are platform-specific line breaks, |
| and also format effectors within (but not at the end of) comments. |
| In particular, each horizontal tab character that is not inside |
| a comment will be treated as a space and thus will appear in the |
| output file as zero or more spaces depending on |
| the reformatting of the line in which it appears. |
| The only exception is a Form Feed character, which is inserted after a |
| pragma @code{Page} when @option{-ff} is set. |
| |
| The output file will contain no lines with trailing ``white space'' (spaces, |
| format effectors). |
| |
| Empty lines in the original source are preserved |
| only if they separate declarations or statements. |
| In such contexts, a |
| sequence of two or more empty lines is replaced by exactly one empty line. |
| Note that a blank line will be removed if it separates two ``comment blocks'' |
| (a comment block is a sequence of whole-line comments). |
| In order to preserve a visual separation between comment blocks, use an |
| ``empty comment'' (a line comprising only hyphens) rather than an empty line. |
| Likewise, if for some reason you wish to have a sequence of empty lines, |
| use a sequence of empty comments instead. |
| |
| @node Formatting Comments |
| @subsection Formatting Comments |
| |
| @noindent |
| Comments in Ada code are of two kinds: |
| @itemize @bullet |
| @item |
| a @emph{whole-line comment}, which appears by itself (possibly preceded by |
| ``white space'') on a line |
| |
| @item |
| an @emph{end-of-line comment}, which follows some other Ada lexical element |
| on the same line. |
| @end itemize |
| |
| @noindent |
| The indentation of a whole-line comment is that of either |
| the preceding or following line in |
| the formatted source, depending on switch settings as will be described below. |
| |
| For an end-of-line comment, @command{gnatpp} leaves the same number of spaces |
| between the end of the preceding Ada lexical element and the beginning |
| of the comment as appear in the original source, |
| unless either the comment has to be split to |
| satisfy the line length limitation, or else the next line contains a |
| whole line comment that is considered a continuation of this end-of-line |
| comment (because it starts at the same position). |
| In the latter two |
| cases, the start of the end-of-line comment is moved right to the nearest |
| multiple of the indentation level. |
| This may result in a ``line overflow'' (the right-shifted comment extending |
| beyond the maximum line length), in which case the comment is split as |
| described below. |
| |
| There is a difference between @option{^-c1^/COMMENTS_LAYOUT=DEFAULT^} |
| (GNAT-style comment line indentation) |
| and @option{^-c2^/COMMENTS_LAYOUT=STANDARD_INDENT^} |
| (reference-manual comment line indentation). |
| With reference-manual style, a whole-line comment is indented as if it |
| were a declaration or statement at the same place |
| (i.e., according to the indentation of the preceding line(s)). |
| With GNAT style, a whole-line comment that is immediately followed by an |
| @b{if} or @b{case} statement alternative, a record variant, or the reserved |
| word @b{begin}, is indented based on the construct that follows it. |
| |
| For example: |
| @smallexample @c ada |
| @cartouche |
| if A then |
| null; |
| -- some comment |
| else |
| null; |
| end if; |
| @end cartouche |
| @end smallexample |
| |
| @noindent |
| Reference-manual indentation produces: |
| |
| @smallexample @c ada |
| @cartouche |
| if A then |
| null; |
| -- some comment |
| else |
| null; |
| end if; |
| @end cartouche |
| @end smallexample |
| |
| @noindent |
| while GNAT-style indentation produces: |
| |
| @smallexample @c ada |
| @cartouche |
| if A then |
| null; |
| -- some comment |
| else |
| null; |
| end if; |
| @end cartouche |
| @end smallexample |
| |
| @noindent |
| The @option{^-c3^/COMMENTS_LAYOUT=GNAT_BEGINNING^} switch |
| (GNAT style comment beginning) has the following |
| effect: |
| |
| @itemize @bullet |
| @item |
| For each whole-line comment that does not end with two hyphens, |
| @command{gnatpp} inserts spaces if necessary after the starting two hyphens |
| to ensure that there are at least two spaces between these hyphens and the |
| first non-blank character of the comment. |
| @end itemize |
| |
| @noindent |
| For an end-of-line comment, if in the original source the next line is a |
| whole-line comment that starts at the same position |
| as the end-of-line comment, |
| then the whole-line comment (and all whole-line comments |
| that follow it and that start at the same position) |
| will start at this position in the output file. |
| |
| @noindent |
| That is, if in the original source we have: |
| |
| @smallexample @c ada |
| @cartouche |
| begin |
| A := B + C; -- B must be in the range Low1..High1 |
| -- C must be in the range Low2..High2 |
| --B+C will be in the range Low1+Low2..High1+High2 |
| X := X + 1; |
| @end cartouche |
| @end smallexample |
| |
| @noindent |
| Then in the formatted source we get |
| |
| @smallexample @c ada |
| @cartouche |
| begin |
| A := B + C; -- B must be in the range Low1..High1 |
| -- C must be in the range Low2..High2 |
| -- B+C will be in the range Low1+Low2..High1+High2 |
| X := X + 1; |
| @end cartouche |
| @end smallexample |
| |
| @noindent |
| A comment that exceeds the line length limit will be split. |
| Unless switch |
| @option{^-c4^/COMMENTS_LAYOUT=REFORMAT^} (reformat comment blocks) is set and |
| the line belongs to a reformattable block, splitting the line generates a |
| @command{gnatpp} warning. |
| The @option{^-c4^/COMMENTS_LAYOUT=REFORMAT^} switch specifies that whole-line |
| comments may be reformatted in typical |
| word processor style (that is, moving words between lines and putting as |
| many words in a line as possible). |
| |
| @node Construct Layout |
| @subsection Construct Layout |
| |
| @noindent |
| In several cases the suggested layout in the Ada Reference Manual includes |
| an extra level of indentation that many programmers prefer to avoid. The |
| affected cases include: |
| |
| @itemize @bullet |
| |
| @item Record type declaration (RM 3.8) |
| |
| @item Record representation clause (RM 13.5.1) |
| |
| @item Loop statement in case if a loop has a statement identifier (RM 5.6) |
| |
| @item Block statement in case if a block has a statement identifier (RM 5.6) |
| @end itemize |
| |
| @noindent |
| In compact mode (when GNAT style layout or compact layout is set), |
| the pretty printer uses one level of indentation instead |
| of two. This is achieved in the record definition and record representation |
| clause cases by putting the @code{record} keyword on the same line as the |
| start of the declaration or representation clause, and in the block and loop |
| case by putting the block or loop header on the same line as the statement |
| identifier. |
| |
| @noindent |
| The difference between GNAT style @option{^-l1^/CONSTRUCT_LAYOUT=GNAT^} |
| and compact @option{^-l2^/CONSTRUCT_LAYOUT=COMPACT^} |
| layout on the one hand, and uncompact layout |
| @option{^-l3^/CONSTRUCT_LAYOUT=UNCOMPACT^} on the other hand, |
| can be illustrated by the following examples: |
| |
| @iftex |
| @cartouche |
| @multitable @columnfractions .5 .5 |
| @item @i{GNAT style, compact layout} @tab @i{Uncompact layout} |
| |
| @item |
| @smallexample @c ada |
| type q is record |
| a : integer; |
| b : integer; |
| end record; |
| @end smallexample |
| @tab |
| @smallexample @c ada |
| type q is |
| record |
| a : integer; |
| b : integer; |
| end record; |
| @end smallexample |
| |
| @item |
| @smallexample @c ada |
| for q use record |
| a at 0 range 0 .. 31; |
| b at 4 range 0 .. 31; |
| end record; |
| @end smallexample |
| @tab |
| @smallexample @c ada |
| for q use |
| record |
| a at 0 range 0 .. 31; |
| b at 4 range 0 .. 31; |
| end record; |
| @end smallexample |
| |
| @item |
| @smallexample @c ada |
| Block : declare |
| A : Integer := 3; |
| begin |
| Proc (A, A); |
| end Block; |
| @end smallexample |
| @tab |
| @smallexample @c ada |
| Block : |
| declare |
| A : Integer := 3; |
| begin |
| Proc (A, A); |
| end Block; |
| @end smallexample |
| |
| @item |
| @smallexample @c ada |
| Clear : for J in 1 .. 10 loop |
| A (J) := 0; |
| end loop Clear; |
| @end smallexample |
| @tab |
| @smallexample @c ada |
| Clear : |
| for J in 1 .. 10 loop |
| A (J) := 0; |
| end loop Clear; |
| @end smallexample |
| @end multitable |
| @end cartouche |
| @end iftex |
| |
| @ifnottex |
| @smallexample |
| @cartouche |
| GNAT style, compact layout Uncompact layout |
| |
| type q is record type q is |
| a : integer; record |
| b : integer; a : integer; |
| end record; b : integer; |
| end record; |
| |
| for q use record for q use |
| a at 0 range 0 .. 31; record |
| b at 4 range 0 .. 31; a at 0 range 0 .. 31; |
| end record; b at 4 range 0 .. 31; |
| end record; |
| |
| Block : declare Block : |
| A : Integer := 3; declare |
| begin A : Integer := 3; |
| Proc (A, A); begin |
| end Block; Proc (A, A); |
| end Block; |
| |
| Clear : for J in 1 .. 10 loop Clear : |
| A (J) := 0; for J in 1 .. 10 loop |
| end loop Clear; A (J) := 0; |
| end loop Clear; |
| @end cartouche |
| @end smallexample |
| @end ifnottex |
| |
| @noindent |
| A further difference between GNAT style layout and compact layout is that |
| GNAT style layout inserts empty lines as separation for |
| compound statements, return statements and bodies. |
| |
| @node Name Casing |
| @subsection Name Casing |
| |
| @noindent |
| @command{gnatpp} always converts the usage occurrence of a (simple) name to |
| the same casing as the corresponding defining identifier. |
| |
| You control the casing for defining occurrences via the |
| @option{^-n^/NAME_CASING^} switch. |
| @ifclear vms |
| With @option{-nD} (``as declared'', which is the default), |
| @end ifclear |
| @ifset vms |
| With @option{/NAME_CASING=AS_DECLARED}, which is the default, |
| @end ifset |
| defining occurrences appear exactly as in the source file |
| where they are declared. |
| The other ^values for this switch^options for this qualifier^ --- |
| @option{^-nU^UPPER_CASE^}, |
| @option{^-nL^LOWER_CASE^}, |
| @option{^-nM^MIXED_CASE^} --- |
| result in |
| ^upper, lower, or mixed case, respectively^the corresponding casing^. |
| If @command{gnatpp} changes the casing of a defining |
| occurrence, it analogously changes the casing of all the |
| usage occurrences of this name. |
| |
| If the defining occurrence of a name is not in the source compilation unit |
| currently being processed by @command{gnatpp}, the casing of each reference to |
| this name is changed according to the value of the @option{^-n^/NAME_CASING^} |
| switch (subject to the dictionary file mechanism described below). |
| Thus @command{gnatpp} acts as though the @option{^-n^/NAME_CASING^} switch |
| had affected the |
| casing for the defining occurrence of the name. |
| |
| Some names may need to be spelled with casing conventions that are not |
| covered by the upper-, lower-, and mixed-case transformations. |
| You can arrange correct casing by placing such names in a |
| @emph{dictionary file}, |
| and then supplying a @option{^-D^/DICTIONARY^} switch. |
| The casing of names from dictionary files overrides |
| any @option{^-n^/NAME_CASING^} switch. |
| |
| To handle the casing of Ada predefined names and the names from GNAT libraries, |
| @command{gnatpp} assumes a default dictionary file. |
| The name of each predefined entity is spelled with the same casing as is used |
| for the entity in the @cite{Ada Reference Manual}. |
| The name of each entity in the GNAT libraries is spelled with the same casing |
| as is used in the declaration of that entity. |
| |
| The @w{@option{^-D-^/SPECIFIC_CASING^}} switch suppresses the use of the |
| default dictionary file. |
| Instead, the casing for predefined and GNAT-defined names will be established |
| by the @option{^-n^/NAME_CASING^} switch or explicit dictionary files. |
| For example, by default the names @code{Ada.Text_IO} and @code{GNAT.OS_Lib} |
| will appear as just shown, |
| even in the presence of a @option{^-nU^/NAME_CASING=UPPER_CASE^} switch. |
| To ensure that even such names are rendered in uppercase, |
| additionally supply the @w{@option{^-D-^/SPECIFIC_CASING^}} switch |
| (or else, less conveniently, place these names in upper case in a dictionary |
| file). |
| |
| A dictionary file is |
| a plain text file; each line in this file can be either a blank line |
| (containing only space characters and ASCII.HT characters), an Ada comment |
| line, or the specification of exactly one @emph{casing schema}. |
| |
| A casing schema is a string that has the following syntax: |
| |
| @smallexample |
| @cartouche |
| @var{casing_schema} ::= @var{identifier} | *@var{simple_identifier}* |
| |
| @var{simple_identifier} ::= @var{letter}@{@var{letter_or_digit}@} |
| @end cartouche |
| @end smallexample |
| |
| @noindent |
| (See @cite{Ada Reference Manual}, Section 2.3) for the definition of the |
| @var{identifier} lexical element and the @var{letter_or_digit} category.) |
| |
| The casing schema string can be followed by white space and/or an Ada-style |
| comment; any amount of white space is allowed before the string. |
| |
| If a dictionary file is passed as |
| @ifclear vms |
| the value of a @option{-D@var{file}} switch |
| @end ifclear |
| @ifset vms |
| an option to the @option{/DICTIONARY} qualifier |
| @end ifset |
| then for every |
| simple name and every identifier, @command{gnatpp} checks if the dictionary |
| defines the casing for the name or for some of its parts (the term ``subword'' |
| is used below to denote the part of a name which is delimited by ``_'' or by |
| the beginning or end of the word and which does not contain any ``_'' inside): |
| |
| @itemize @bullet |
| @item |
| if the whole name is in the dictionary, @command{gnatpp} uses for this name |
| the casing defined by the dictionary; no subwords are checked for this word |
| |
| @item |
| for every subword @command{gnatpp} checks if the dictionary contains the |
| corresponding string of the form @code{*@var{simple_identifier}*}, |
| and if it does, the casing of this @var{simple_identifier} is used |
| for this subword |
| |
| @item |
| if the whole name does not contain any ``_'' inside, and if for this name |
| the dictionary contains two entries - one of the form @var{identifier}, |
| and another - of the form *@var{simple_identifier}*, then the first one |
| is applied to define the casing of this name |
| |
| @item |
| if more than one dictionary file is passed as @command{gnatpp} switches, each |
| dictionary adds new casing exceptions and overrides all the existing casing |
| exceptions set by the previous dictionaries |
| |
| @item |
| when @command{gnatpp} checks if the word or subword is in the dictionary, |
| this check is not case sensitive |
| @end itemize |
| |
| @noindent |
| For example, suppose we have the following source to reformat: |
| |
| @smallexample @c ada |
| @cartouche |
| procedure test is |
| name1 : integer := 1; |
| name4_name3_name2 : integer := 2; |
| name2_name3_name4 : Boolean; |
| name1_var : Float; |
| begin |
| name2_name3_name4 := name4_name3_name2 > name1; |
| end; |
| @end cartouche |
| @end smallexample |
| |
| @noindent |
| And suppose we have two dictionaries: |
| |
| @smallexample |
| @cartouche |
| @i{dict1:} |
| NAME1 |
| *NaMe3* |
| *Name1* |
| @end cartouche |
| |
| @cartouche |
| @i{dict2:} |
| *NAME3* |
| @end cartouche |
| @end smallexample |
| |
| @noindent |
| If @command{gnatpp} is called with the following switches: |
| |
| @smallexample |
| @ifclear vms |
| @command{gnatpp -nM -D dict1 -D dict2 test.adb} |
| @end ifclear |
| @ifset vms |
| @command{gnatpp test.adb /NAME_CASING=MIXED_CASE /DICTIONARY=(dict1, dict2)} |
| @end ifset |
| @end smallexample |
| |
| @noindent |
| then we will get the following name casing in the @command{gnatpp} output: |
| |
| @smallexample @c ada |
| @cartouche |
| procedure Test is |
| NAME1 : Integer := 1; |
| Name4_NAME3_Name2 : Integer := 2; |
| Name2_NAME3_Name4 : Boolean; |
| Name1_Var : Float; |
| begin |
| Name2_NAME3_Name4 := Name4_NAME3_Name2 > NAME1; |
| end Test; |
| @end cartouche |
| @end smallexample |
| |
| @c ********************************* |
| @node The GNAT Metric Tool gnatmetric |
| @chapter The GNAT Metric Tool @command{gnatmetric} |
| @findex gnatmetric |
| @cindex Metric tool |
| |
| @noindent |
| ^The @command{gnatmetric} tool^@command{GNAT METRIC}^ is an ASIS-based utility |
| for computing various program metrics. |
| It takes an Ada source file as input and generates a file containing the |
| metrics data as output. Various switches control which |
| metrics are computed and output. |
| |
| @command{gnatmetric} generates and uses the ASIS |
| tree for the input source and thus requires the input to be syntactically and |
| semantically legal. |
| If this condition is not met, @command{gnatmetric} will generate |
| an error message; no metric information for this file will be |
| computed and reported. |
| |
| If the compilation unit contained in the input source depends semantically |
| upon units in files located outside the current directory, you have to provide |
| the source search path when invoking @command{gnatmetric}. |
| If it depends semantically upon units that are contained |
| in files with names that do not follow the GNAT file naming rules, you have to |
| provide the configuration file describing the corresponding naming scheme (see |
| the description of the @command{gnatmetric} switches below.) |
| Alternatively, you may use a project file and invoke @command{gnatmetric} |
| through the @command{gnat} driver. |
| |
| |
| The @command{gnatmetric} command has the form |
| |
| @smallexample |
| $ gnatmetric [@i{switches}] @{@i{filename}@} [@i{-cargs gcc_switches}] |
| @end smallexample |
| |
| @noindent |
| where |
| @itemize @bullet |
| @item |
| @i{switches} specify the metrics to compute and define the destination for |
| the output |
| |
| @item |
| Each @i{filename} is the name (including the extension) of a source |
| file to process. ``Wildcards'' are allowed, and |
| the file name may contain path information. |
| If no @i{filename} is supplied, then the @i{switches} list must contain |
| at least one |
| @option{-files} switch (@pxref{Other gnatmetric Switches}). |
| Including both a @option{-files} switch and one or more |
| @i{filename} arguments is permitted. |
| |
| @item |
| @i{-cargs gcc_switches} is a list of switches for |
| @command{gcc}. They will be passed on to all compiler invocations made by |
| @command{gnatmetric} to generate the ASIS trees. Here you can provide |
| @option{^-I^/INCLUDE_DIRS=^} switches to form the source search path, |
| and use the @option{-gnatec} switch to set the configuration file. |
| @end itemize |
| |
| @menu |
| * Switches for gnatmetric:: |
| @end menu |
| |
| @node Switches for gnatmetric |
| @section Switches for @command{gnatmetric} |
| |
| @noindent |
| The following subsections describe the various switches accepted by |
| @command{gnatmetric}, organized by category. |
| |
| @menu |
| * Output Files Control:: |
| * Disable Metrics For Local Units:: |
| * Line Metrics Control:: |
| * Syntax Metrics Control:: |
| * Complexity Metrics Control:: |
| * Other gnatmetric Switches:: |
| @end menu |
| |
| @node Output Files Control |
| @subsection Output File Control |
| @cindex Output file control in @command{gnatmetric} |
| |
| @noindent |
| @command{gnatmetric} has two output formats. It can generate a |
| textual (human-readable) form, and also XML. By default only textual |
| output is generated. |
| |
| When generating the output in textual form, @command{gnatmetric} creates |
| for each Ada source file a corresponding text file |
| containing the computed metrics. By default, this file |
| is placed in the same directory as where the source file is located, and |
| its name is obtained |
| by appending the ^@file{.metrix}^@file{$METRIX}^ suffix to the name of the |
| input file. |
| |
| All the output information generated in XML format is placed in a single |
| file. By default this file is placed in the current directory and has the |
| name ^@file{metrix.xml}^@file{METRIX$XML}^. |
| |
| Some of the computed metrics are summed over the units passed to |
| @command{gnatmetric}; for example, the total number of lines of code. |
| By default this information is sent to @file{stdout}, but a file |
| can be specified with the @option{-og} switch. |
| |
| The following switches control the @command{gnatmetric} output: |
| |
| @table @option |
| @cindex @option{^-x^/XML^} (@command{gnatmetric}) |
| @item ^-x^/XML^ |
| Generate the XML output |
| |
| @cindex @option{^-nt^/NO_TEXT^} (@command{gnatmetric}) |
| @item ^-nt^/NO_TEXT^ |
| Do not generate the output in text form (implies @option{^-x^/XML^}) |
| |
| @cindex @option{^-d^/DIRECTORY^} (@command{gnatmetric}) |
| @item ^-d @var{output_dir}^/DIRECTORY=@var{output_dir}^ |
| Put textual files with detailed metrics into @var{output_dir} |
| |
| @cindex @option{^-o^/SUFFIX_DETAILS^} (@command{gnatmetric}) |
| @item ^-o @var{file_suffix}^/SUFFIX_DETAILS=@var{file_suffix}^ |
| Use @var{file_suffix}, instead of ^@file{.metrix}^@file{$METRIX}^ |
| in the name of the output file. |
| |
| @cindex @option{^-og^/GLOBAL_OUTPUT^} (@command{gnatmetric}) |
| @item ^-og @var{file_name}^/GLOBAL_OUTPUT=@var{file_name}^ |
| Put global metrics into @var{file_name} |
| |
| @cindex @option{^-ox^/XML_OUTPUT^} (@command{gnatmetric}) |
| @item ^-ox @var{file_name}^/XML_OUTPUT=@var{file_name}^ |
| Put the XML output into @var{file_name} (also implies @option{^-x^/XML^}) |
| |
| @cindex @option{^-sfn^/SHORT_SOURCE_FILE_NAME^} (@command{gnatmetric}) |
| @item ^-sfn^/SHORT_SOURCE_FILE_NAME^ |
| Use ``short'' source file names in the output. (The @command{gnatmetric} |
| output includes the name(s) of the Ada source file(s) from which the metrics |
| are computed. By default each name includes the absolute path. The |
| @option{^-sfn^/SHORT_SOURCE_FILE_NAME^} switch causes @command{gnatmetric} |
| to exclude all directory information from the file names that are output.) |
| |
| @end table |
| |
| @node Disable Metrics For Local Units |
| @subsection Disable Metrics For Local Units |
| @cindex Disable Metrics For Local Units in @command{gnatmetric} |
| |
| @noindent |
| @command{gnatmetric} relies on the GNAT compilation model @minus{} |
| one compilation |
| unit per one source file. It computes line metrics for the whole source |
| file, and it also computes syntax |
| and complexity metrics for the file's outermost unit. |
| |
| By default, @command{gnatmetric} will also compute all metrics for certain |
| kinds of locally declared program units: |
| |
| @itemize @bullet |
| @item |
| subprogram (and generic subprogram) bodies; |
| |
| @item |
| package (and generic package) specifications and bodies; |
| |
| @item |
| task object and type specifications and bodies; |
| |
| @item |
| protected object and type specifications and bodies. |
| @end itemize |
| |
| @noindent |
| These kinds of entities will be referred to as |
| @emph{eligible local program units}, or simply @emph{eligible local units}, |
| @cindex Eligible local unit (for @command{gnatmetric}) |
| in the discussion below. |
| |
| Note that a subprogram declaration, generic instantiation, |
| or renaming declaration only receives metrics |
| computation when it appear as the outermost entity |
| in a source file. |
| |
| Suppression of metrics computation for eligible local units can be |
| obtained via the following switch: |
| |
| @table @option |
| @cindex @option{^-n@var{x}^/SUPPRESS^} (@command{gnatmetric}) |
| @item ^-nolocal^/SUPPRESS=LOCAL_DETAILS^ |
| Do not compute detailed metrics for eligible local program units |
| |
| @end table |
| |
| @node Line Metrics Control |
| @subsection Line Metrics Control |
| @cindex Line metrics control in @command{gnatmetric} |
| |
| @noindent |
| For any (legal) source file, and for each of its |
| eligible local program units, @command{gnatmetric} computes the following |
| metrics: |
| |
| @itemize @bullet |
| @item |
| the total number of lines; |
| |
| @item |
| the total number of code lines (i.e., non-blank lines that are not comments) |
| |
| @item |
| the number of comment lines |
| |
| @item |
| the number of code lines containing end-of-line comments; |
| |
| @item |
| the number of empty lines and lines containing only space characters and/or |
| format effectors (blank lines) |
| |
| @end itemize |
| |
| If @command{gnatmetric} is invoked on more than one source file, it sums the |
| values of the line metrics for all the files being processed and then |
| generates the cumulative results. |
| |
| By default, all the line metrics are computed and reported. You can use the |
| following switches to select the specific line metrics to be computed and |
| reported (if any of these parameters is set, only explicitly specified line |
| metrics are computed). |
| |
| @table @option |
| @cindex @option{^-la^/LINES_ALL^} (@command{gnatmetric}) |
| @item ^-la^/LINES_ALL^ |
| The number of all lines |
| |
| @cindex @option{^-lcode^/CODE_LINES^} (@command{gnatmetric}) |
| @item ^-lcode^/CODE_LINES^ |
| The number of code lines |
| |
| @cindex @option{^-lcomm^/COMMENT_LINES^} (@command{gnatmetric}) |
| @item ^-lcomm^/COMENT_LINES^ |
| The number of comment lines |
| |
| @cindex @option{^-leol^/MIXED_CODE_COMMENTS^} (@command{gnatmetric}) |
| @item ^-leol^/MIXED_CODE_COMMENTS^ |
| The number of code lines containing |
| end-of-line comments |
| |
| @cindex @option{^-lb^/BLANK_LINES^} (@command{gnatmetric}) |
| @item ^-lb^/BLANK_LINES^ |
| The number of blank lines |
| |
| @end table |
| |
| |
| @node Syntax Metrics Control |
| @subsection Syntax Metrics Control |
| @cindex Syntax metrics control in @command{gnatmetric} |
| |
| @noindent |
| @command{gnatmetric} computes various syntactic metrics for the |
| outermost unit and for each eligible local unit: |
| |
| @table @emph |
| @item LSLOC (``Logical Source Lines Of Code'') |
| The total number of declarations and the total number of statements |
| |
| @item Maximal static nesting level of inner program units |
| According to |
| @cite{Ada 95 Language Reference Manual}, 10.1(1), ``A program unit is either a |
| package, a task unit, a protected unit, a |
| protected entry, a generic unit, or an explicitly declared subprogram other |
| than an enumeration literal.'' |
| |
| @item Maximal nesting level of composite syntactic constructs |
| This corresponds to the notion of the |
| maximum nesting level in the GNAT built-in style checks |
| (@pxref{Style Checking}) |
| @end table |
| |
| @noindent |
| For the outermost unit in the file, @command{gnatmetric} additionally computes |
| the following metrics: |
| |
| @table @emph |
| @item Public subprograms |
| This metric is computed for package specifications. It is the |
| number of subprograms and generic subprograms declared in the visible |
| part (including in nested packages, protected objects, and |
| protected types). |
| |
| @item All subprograms |
| This metric is computed for bodies and subunits. The |
| metric is equal to a total number of subprogram bodies in the compilation |
| unit. |
| Neither generic instantiations nor renamings-as-a-body nor body stubs |
| are counted. Any subprogram body is counted, independently of its nesting |
| level and enclosing constructs. Generic bodies and bodies of protected |
| subprograms are counted in the same way as ``usual'' subprogram bodies. |
| |
| @item Public types |
| This metric is computed for package specifications and |
| generic package declarations. It is the total number of types |
| that can be referenced from outside this compilation unit, plus the |
| number of types from all the visible parts of all the visible generic packages. |
| Generic formal types are not counted. Only types, not subtypes, |
| are included. |
| |
| @noindent |
| Along with the total number of public types, the following |
| types are counted and reported separately: |
| |
| @itemize @bullet |
| @item |
| Abstract types |
| |
| @item |
| Root tagged types (abstract, non-abstract, private, non-private). Type |
| extensions are @emph{not} counted |
| |
| @item |
| Private types (including private extensions) |
| |
| @item |
| Task types |
| |
| @item |
| Protected types |
| |
| @end itemize |
| |
| @item All types |
| This metric is computed for any compilation unit. It is equal to the total |
| number of the declarations of different types given in the compilation unit. |
| The private and the corresponding full type declaration are counted as one |
| type declaration. Incomplete type declarations and generic formal types |
| are not counted. |
| No distinction is made among different kinds of types (abstract, |
| private etc.); the total number of types is computed and reported. |
| |
| @end table |
| |
| @noindent |
| By default, all the syntax metrics are computed and reported. You can use the |
| following switches to select specific syntax metrics; |
| if any of these is set, only the explicitly specified metrics are computed. |
| |
| @table @option |
| @cindex @option{^-ed^/DECLARATION_TOTAL^} (@command{gnatmetric}) |
| @item ^-ed^/DECLARATION_TOTAL^ |
| The total number of declarations |
| |
| @cindex @option{^-es^/STATEMENT_TOTAL^} (@command{gnatmetric}) |
| @item ^-es^/STATEMENT_TOTAL^ |
| The total number of statements |
| |
| @cindex @option{^-eps^/^} (@command{gnatmetric}) |
| @item ^-eps^/INT_SUBPROGRAMS^ |
| The number of public subprograms in a compilation unit |
| |
| @cindex @option{^-eas^/SUBPROGRAMS_ALL^} (@command{gnatmetric}) |
| @item ^-eas^/SUBPROGRAMS_ALL^ |
| The number of all the subprograms in a compilation unit |
| |
| @cindex @option{^-ept^/INT_TYPES^} (@command{gnatmetric}) |
| @item ^-ept^/INT_TYPES^ |
| The number of public types in a compilation unit |
| |
| @cindex @option{^-eat^/TYPES_ALL^} (@command{gnatmetric}) |
| @item ^-eat^/TYPES_ALL^ |
| The number of all the types in a compilation unit |
| |
| @cindex @option{^-enu^/PROGRAM_NESTING_MAX^} (@command{gnatmetric}) |
| @item ^-enu^/PROGRAM_NESTING_MAX^ |
| The maximal program unit nesting level |
| |
| @cindex @option{^-ec^/CONSTRUCT_NESTING_MAX^} (@command{gnatmetric}) |
| @item ^-ec^/CONSTRUCT_NESTING_MAX^ |
| The maximal construct nesting level |
| |
| @end table |
| |
| @node Complexity Metrics Control |
| @subsection Complexity Metrics Control |
| @cindex Complexity metrics control in @command{gnatmetric} |
| |
| @noindent |
| For a program unit that is an executable body (a subprogram body (including |
| generic bodies), task body, entry body or a package body containing |
| its own statement sequence ) @command{gnatmetric} computes the following |
| complexity metrics: |
| |
| @itemize @bullet |
| @item |
| McCabe cyclomatic complexity; |
| |
| @item |
| McCabe essential complexity; |
| |
| @item |
| maximal loop nesting level |
| |
| @end itemize |
| |
| @noindent |
| The McCabe complexity metrics are defined |
| in @url{www.mccabe.com/pdf/nist235r.pdf} |
| |
| According to McCabe, both control statements and short-circuit control forms |
| should be taken into account when computing cyclomatic complexity. For each |
| body, we compute three metric values: |
| |
| @itemize @bullet |
| @item |
| the complexity introduced by control |
| statements only, without taking into account short-circuit forms, |
| |
| @item |
| the complexity introduced by short-circuit control forms only, and |
| |
| @item |
| the total |
| cyclomatic complexity, which is the sum of these two values. |
| @end itemize |
| |
| @noindent |
| When computing cyclomatic and essential complexity, @command{gnatmetric} skips |
| the code in the exception handlers and in all the nested program units. |
| |
| By default, all the complexity metrics are computed and reported. |
| For more finely-grained control you can use |
| the following switches: |
| |
| @table @option |
| @cindex @option{^-n@var{x}^/SUPPRESS^} (@command{gnatmetric}) |
| |
| @item ^-nocc^/SUPPRESS=CYCLOMATIC_COMPLEXITY^ |
| Do not compute the McCabe Cyclomatic Complexity |
| |
| @item ^-noec^/SUPPRESS=ESSENTIAL_COMPLEXITY^ |
| Do not compute the Essential Complexity |
| |
| @item ^-nonl^/SUPPRESS=MAXIMAL_LOOP_NESTING^ |
| Do not compute maximal loop nesting level |
| |
| @item ^-ne^/SUPPRESS=EXITS_AS_GOTOS^ |
| Do not consider @code{exit} statements as @code{goto}s when |
| computing Essential Complexity |
| |
| @end table |
| |
| @node Other gnatmetric Switches |
| @subsection Other @code{gnatmetric} Switches |
| |
| @noindent |
| Additional @command{gnatmetric} switches are as follows: |
| |
| @table @option |
| @item ^-files @var{filename}^/FILES=@var{filename}^ |
| @cindex @option{^-files^/FILES^} (@code{gnatmetric}) |
| Take the argument source files from the specified file. This file should be an |
| ordinary textual file containing file names separated by spaces or |
| line breaks. You can use this switch more then once in the same call to |
| @command{gnatmetric}. You also can combine this switch with |
| an explicit list of files. |
| |
| @item ^-v^/VERBOSE^ |
| @cindex @option{^-v^/VERBOSE^} (@code{gnatmetric}) |
| Verbose mode; |
| @command{gnatmetric} generates version information and then |
| a trace of sources being processed. |
| |
| @item ^-dv^/DEBUG_OUTPUT^ |
| @cindex @option{^-dv^/DEBUG_OUTPUT^} (@code{gnatmetric}) |
| Debug mode; |
| @command{gnatmetric} generates various messages useful to understand what |
| happens during the metrics computation |
| |
| @item ^-q^/QUIET^ |
| @cindex @option{^-q^/QUIET^} (@code{gnatmetric}) |
| Quiet mode. |
| @end table |
| |
| @c *********************************** |
| @node File Name Krunching Using gnatkr |
| @chapter File Name Krunching Using @code{gnatkr} |
| @findex gnatkr |
| |
| @noindent |
| This chapter discusses the method used by the compiler to shorten |
| the default file names chosen for Ada units so that they do not |
| exceed the maximum length permitted. It also describes the |
| @code{gnatkr} utility that can be used to determine the result of |
| applying this shortening. |
| @menu |
| * About gnatkr:: |
| * Using gnatkr:: |
| * Krunching Method:: |
| * Examples of gnatkr Usage:: |
| @end menu |
| |
| @node About gnatkr |
| @section About @code{gnatkr} |
| |
| @noindent |
| The default file naming rule in GNAT |
| is that the file name must be derived from |
| the unit name. The exact default rule is as follows: |
| @itemize @bullet |
| @item |
| Take the unit name and replace all dots by hyphens. |
| @item |
| If such a replacement occurs in the |
| second character position of a name, and the first character is |
| ^a, g, s, or i^A, G, S, or I^ then replace the dot by the character |
| ^~ (tilde)^$ (dollar sign)^ |
| instead of a minus. |
| @end itemize |
| The reason for this exception is to avoid clashes |
| with the standard names for children of System, Ada, Interfaces, |
| and GNAT, which use the prefixes ^s- a- i- and g-^S- A- I- and G-^ |
| respectively. |
| |
| The @option{^-gnatk^/FILE_NAME_MAX_LENGTH=^@var{nn}} |
| switch of the compiler activates a ``krunching'' |
| circuit that limits file names to nn characters (where nn is a decimal |
| integer). For example, using OpenVMS, |
| where the maximum file name length is |
| 39, the value of nn is usually set to 39, but if you want to generate |
| a set of files that would be usable if ported to a system with some |
| different maximum file length, then a different value can be specified. |
| The default value of 39 for OpenVMS need not be specified. |
| |
| The @code{gnatkr} utility can be used to determine the krunched name for |
| a given file, when krunched to a specified maximum length. |
| |
| @node Using gnatkr |
| @section Using @code{gnatkr} |
| |
| @noindent |
| The @code{gnatkr} command has the form |
| |
| @ifclear vms |
| @smallexample |
| $ gnatkr @var{name} [@var{length}] |
| @end smallexample |
| @end ifclear |
| |
| @ifset vms |
| @smallexample |
| $ gnatkr @var{name} /COUNT=nn |
| @end smallexample |
| @end ifset |
| |
| @noindent |
| @var{name} is the uncrunched file name, derived from the name of the unit |
| in the standard manner described in the previous section (i.e. in particular |
| all dots are replaced by hyphens). The file name may or may not have an |
| extension (defined as a suffix of the form period followed by arbitrary |
| characters other than period). If an extension is present then it will |
| be preserved in the output. For example, when krunching @file{hellofile.ads} |
| to eight characters, the result will be hellofil.ads. |
| |
| Note: for compatibility with previous versions of @code{gnatkr} dots may |
| appear in the name instead of hyphens, but the last dot will always be |
| taken as the start of an extension. So if @code{gnatkr} is given an argument |
| such as @file{Hello.World.adb} it will be treated exactly as if the first |
| period had been a hyphen, and for example krunching to eight characters |
| gives the result @file{hellworl.adb}. |
| |
| Note that the result is always all lower case (except on OpenVMS where it is |
| all upper case). Characters of the other case are folded as required. |
| |
| @var{length} represents the length of the krunched name. The default |
| when no argument is given is ^8^39^ characters. A length of zero stands for |
| unlimited, in other words do not chop except for system files where the |
| implied crunching length is always eight characters. |
| |
| @noindent |
| The output is the krunched name. The output has an extension only if the |
| original argument was a file name with an extension. |
| |
| @node Krunching Method |
| @section Krunching Method |
| |
| @noindent |
| The initial file name is determined by the name of the unit that the file |
| contains. The name is formed by taking the full expanded name of the |
| unit and replacing the separating dots with hyphens and |
| using ^lowercase^uppercase^ |
| for all letters, except that a hyphen in the second character position is |
| replaced by a ^tilde^dollar sign^ if the first character is |
| ^a, i, g, or s^A, I, G, or S^. |
| The extension is @code{.ads} for a |
| specification and @code{.adb} for a body. |
| Krunching does not affect the extension, but the file name is shortened to |
| the specified length by following these rules: |
| |
| @itemize @bullet |
| @item |
| The name is divided into segments separated by hyphens, tildes or |
| underscores and all hyphens, tildes, and underscores are |
| eliminated. If this leaves the name short enough, we are done. |
| |
| @item |
| If the name is too long, the longest segment is located (left-most |
| if there are two of equal length), and shortened by dropping |
| its last character. This is repeated until the name is short enough. |
| |
| As an example, consider the krunching of @*@file{our-strings-wide_fixed.adb} |
| to fit the name into 8 characters as required by some operating systems. |
| |
| @smallexample |
| our-strings-wide_fixed 22 |
| our strings wide fixed 19 |
| our string wide fixed 18 |
| our strin wide fixed 17 |
| our stri wide fixed 16 |
| our stri wide fixe 15 |
| our str wide fixe 14 |
| our str wid fixe 13 |
| our str wid fix 12 |
| ou str wid fix 11 |
| ou st wid fix 10 |
| ou st wi fix 9 |
| ou st wi fi 8 |
| Final file name: oustwifi.adb |
| @end smallexample |
| |
| @item |
| The file names for all predefined units are always krunched to eight |
| characters. The krunching of these predefined units uses the following |
| special prefix replacements: |
| |
| @table @file |
| @item ada- |
| replaced by @file{^a^A^-} |
| |
| @item gnat- |
| replaced by @file{^g^G^-} |
| |
| @item interfaces- |
| replaced by @file{^i^I^-} |
| |
| @item system- |
| replaced by @file{^s^S^-} |
| @end table |
| |
| These system files have a hyphen in the second character position. That |
| is why normal user files replace such a character with a |
| ^tilde^dollar sign^, to |
| avoid confusion with system file names. |
| |
| As an example of this special rule, consider |
| @*@file{ada-strings-wide_fixed.adb}, which gets krunched as follows: |
| |
| @smallexample |
| ada-strings-wide_fixed 22 |
| a- strings wide fixed 18 |
| a- string wide fixed 17 |
| a- strin wide fixed 16 |
| a- stri wide fixed 15 |
| a- stri wide fixe 14 |
| a- str wide fixe 13 |
| a- str wid fixe 12 |
| a- str wid fix 11 |
| a- st wid fix 10 |
| a- st wi fix 9 |
| a- st wi fi 8 |
| Final file name: a-stwifi.adb |
| @end smallexample |
| @end itemize |
| |
| Of course no file shortening algorithm can guarantee uniqueness over all |
| possible unit names, and if file name krunching is used then it is your |
| responsibility to ensure that no name clashes occur. The utility |
| program @code{gnatkr} is supplied for conveniently determining the |
| krunched name of a file. |
| |
| @node Examples of gnatkr Usage |
| @section Examples of @code{gnatkr} Usage |
| |
| @smallexample |
| @iftex |
| @leftskip=0cm |
| @end iftex |
| @ifclear vms |
| $ gnatkr very_long_unit_name.ads --> velounna.ads |
| $ gnatkr grandparent-parent-child.ads --> grparchi.ads |
| $ gnatkr Grandparent.Parent.Child.ads --> grparchi.ads |
| $ gnatkr grandparent-parent-child --> grparchi |
| @end ifclear |
| $ gnatkr very_long_unit_name.ads/count=6 --> vlunna.ads |
| $ gnatkr very_long_unit_name.ads/count=0 --> very_long_unit_name.ads |
| @end smallexample |
| |
| @node Preprocessing Using gnatprep |
| @chapter Preprocessing Using @code{gnatprep} |
| @findex gnatprep |
| |
| @noindent |
| The @code{gnatprep} utility provides |
| a simple preprocessing capability for Ada programs. |
| It is designed for use with GNAT, but is not dependent on any special |
| features of GNAT. |
| |
| @menu |
| * Using gnatprep:: |
| * Switches for gnatprep:: |
| * Form of Definitions File:: |
| * Form of Input Text for gnatprep:: |
| @end menu |
| |
| @node Using gnatprep |
| @section Using @code{gnatprep} |
| |
| @noindent |
| To call @code{gnatprep} use |
| |
| @smallexample |
| $ gnatprep [switches] infile outfile [deffile] |
| @end smallexample |
| |
| @noindent |
| where |
| @table @code |
| @item switches |
| is an optional sequence of switches as described in the next section. |
| |
| @item infile |
| is the full name of the input file, which is an Ada source |
| file containing preprocessor directives. |
| |
| @item outfile |
| is the full name of the output file, which is an Ada source |
| in standard Ada form. When used with GNAT, this file name will |
| normally have an ads or adb suffix. |
| |
| @item deffile |
| is the full name of a text file containing definitions of |
| symbols to be referenced by the preprocessor. This argument is |
| optional, and can be replaced by the use of the @option{-D} switch. |
| |
| @end table |
| |
| @node Switches for gnatprep |
| @section Switches for @code{gnatprep} |
| |
| @table @option |
| @c !sort! |
| |
| @item ^-b^/BLANK_LINES^ |
| @cindex @option{^-b^/BLANK_LINES^} (@command{gnatprep}) |
| Causes both preprocessor lines and the lines deleted by |
| preprocessing to be replaced by blank lines in the output source file, |
| preserving line numbers in the output file. |
| |
| @item ^-c^/COMMENTS^ |
| @cindex @option{^-c^/COMMENTS^} (@command{gnatprep}) |
| Causes both preprocessor lines and the lines deleted |
| by preprocessing to be retained in the output source as comments marked |
| with the special string @code{"--! "}. This option will result in line numbers |
| being preserved in the output file. |
| |
| @item ^-C^/REPLACE_IN_COMMENTS^ |
| @cindex @option{^-C^/REPLACE_IN_COMMENTS^} (@command{gnatprep}) |
| Causes comments to be scanned. Normally comments are ignored by gnatprep. |
| If this option is specified, then comments are scanned and any $symbol |
| substitutions performed as in program text. This is particularly useful |
| when structured comments are used (e.g. when writing programs in the |
| SPARK dialect of Ada). Note that this switch is not available when |
| doing integrated preprocessing (it would be useless in this context |
| since comments are ignored by the compiler in any case). |
| |
| @item ^-Dsymbol=value^/ASSOCIATE="symbol=value"^ |
| @cindex @option{^-D^/ASSOCIATE^} (@command{gnatprep}) |
| Defines a new symbol, associated with value. If no value is given on the |
| command line, then symbol is considered to be @code{True}. This switch |
| can be used in place of a definition file. |
| |
| @ifset vms |
| @item /REMOVE |
| @cindex @option{/REMOVE} (@command{gnatprep}) |
| This is the default setting which causes lines deleted by preprocessing |
| to be entirely removed from the output file. |
| @end ifset |
| |
| @item ^-r^/REFERENCE^ |
| @cindex @option{^-r^/REFERENCE^} (@command{gnatprep}) |
| Causes a @code{Source_Reference} pragma to be generated that |
| references the original input file, so that error messages will use |
| the file name of this original file. The use of this switch implies |
| that preprocessor lines are not to be removed from the file, so its |
| use will force @option{^-b^/BLANK_LINES^} mode if |
| @option{^-c^/COMMENTS^} |
| has not been specified explicitly. |
| |
| Note that if the file to be preprocessed contains multiple units, then |
| it will be necessary to @code{gnatchop} the output file from |
| @code{gnatprep}. If a @code{Source_Reference} pragma is present |
| in the preprocessed file, it will be respected by |
| @code{gnatchop ^-r^/REFERENCE^} |
| so that the final chopped files will correctly refer to the original |
| input source file for @code{gnatprep}. |
| |
| @item ^-s^/SYMBOLS^ |
| @cindex @option{^-s^/SYMBOLS^} (@command{gnatprep}) |
| Causes a sorted list of symbol names and values to be |
| listed on the standard output file. |
| |
| @item ^-u^/UNDEFINED^ |
| @cindex @option{^-u^/UNDEFINED^} (@command{gnatprep}) |
| Causes undefined symbols to be treated as having the value FALSE in the context |
| of a preprocessor test. In the absence of this option, an undefined symbol in |
| a @code{#if} or @code{#elsif} test will be treated as an error. |
| |
| @end table |
| |
| @ifclear vms |
| @noindent |
| Note: if neither @option{-b} nor @option{-c} is present, |
| then preprocessor lines and |
| deleted lines are completely removed from the output, unless -r is |
| specified, in which case -b is assumed. |
| @end ifclear |
| |
| @node Form of Definitions File |
| @section Form of Definitions File |
| |
| @noindent |
| The definitions file contains lines of the form |
| |
| @smallexample |
| symbol := value |
| @end smallexample |
| |
| @noindent |
| where symbol is an identifier, following normal Ada (case-insensitive) |
| rules for its syntax, and value is one of the following: |
| |
| @itemize @bullet |
| @item |
| Empty, corresponding to a null substitution |
| @item |
| A string literal using normal Ada syntax |
| @item |
| Any sequence of characters from the set |
| (letters, digits, period, underline). |
| @end itemize |
| |
| @noindent |
| Comment lines may also appear in the definitions file, starting with |
| the usual @code{--}, |
| and comments may be added to the definitions lines. |
| |
| @node Form of Input Text for gnatprep |
| @section Form of Input Text for @code{gnatprep} |
| |
| @noindent |
| The input text may contain preprocessor conditional inclusion lines, |
| as well as general symbol substitution sequences. |
| |
| The preprocessor conditional inclusion commands have the form |
| |
| @smallexample |
| @group |
| @cartouche |
| #if @i{expression} [then] |
| lines |
| #elsif @i{expression} [then] |
| lines |
| #elsif @i{expression} [then] |
| lines |
| ... |
| #else |
| lines |
| #end if; |
| @end cartouche |
| @end group |
| @end smallexample |
| |
| @noindent |
| In this example, @i{expression} is defined by the following grammar: |
| @smallexample |
| @i{expression} ::= <symbol> |
| @i{expression} ::= <symbol> = "<value>" |
| @i{expression} ::= <symbol> = <symbol> |
| @i{expression} ::= <symbol> 'Defined |
| @i{expression} ::= not @i{expression} |
| @i{expression} ::= @i{expression} and @i{expression} |
| @i{expression} ::= @i{expression} or @i{expression} |
| @i{expression} ::= @i{expression} and then @i{expression} |
| @i{expression} ::= @i{expression} or else @i{expression} |
| @i{expression} ::= ( @i{expression} ) |
| @end smallexample |
| |
| @noindent |
| For the first test (@i{expression} ::= <symbol>) the symbol must have |
| either the value true or false, that is to say the right-hand of the |
| symbol definition must be one of the (case-insensitive) literals |
| @code{True} or @code{False}. If the value is true, then the |
| corresponding lines are included, and if the value is false, they are |
| excluded. |
| |
| The test (@i{expression} ::= <symbol> @code{'Defined}) is true only if |
| the symbol has been defined in the definition file or by a @option{-D} |
| switch on the command line. Otherwise, the test is false. |
| |
| The equality tests are case insensitive, as are all the preprocessor lines. |
| |
| If the symbol referenced is not defined in the symbol definitions file, |
| then the effect depends on whether or not switch @option{-u} |
| is specified. If so, then the symbol is treated as if it had the value |
| false and the test fails. If this switch is not specified, then |
| it is an error to reference an undefined symbol. It is also an error to |
| reference a symbol that is defined with a value other than @code{True} |
| or @code{False}. |
| |
| The use of the @code{not} operator inverts the sense of this logical test, so |
| that the lines are included only if the symbol is not defined. |
| The @code{then} keyword is optional as shown |
| |
| The @code{#} must be the first non-blank character on a line, but |
| otherwise the format is free form. Spaces or tabs may appear between |
| the @code{#} and the keyword. The keywords and the symbols are case |
| insensitive as in normal Ada code. Comments may be used on a |
| preprocessor line, but other than that, no other tokens may appear on a |
| preprocessor line. Any number of @code{elsif} clauses can be present, |
| including none at all. The @code{else} is optional, as in Ada. |
| |
| The @code{#} marking the start of a preprocessor line must be the first |
| non-blank character on the line, i.e. it must be preceded only by |
| spaces or horizontal tabs. |
| |
| Symbol substitution outside of preprocessor lines is obtained by using |
| the sequence |
| |
| @smallexample |
| $symbol |
| @end smallexample |
| |
| @noindent |
| anywhere within a source line, except in a comment or within a |
| string literal. The identifier |
| following the @code{$} must match one of the symbols defined in the symbol |
| definition file, and the result is to substitute the value of the |
| symbol in place of @code{$symbol} in the output file. |
| |
| Note that although the substitution of strings within a string literal |
| is not possible, it is possible to have a symbol whose defined value is |
| a string literal. So instead of setting XYZ to @code{hello} and writing: |
| |
| @smallexample |
| Header : String := "$XYZ"; |
| @end smallexample |
| |
| @noindent |
| you should set XYZ to @code{"hello"} and write: |
| |
| @smallexample |
| Header : String := $XYZ; |
| @end smallexample |
| |
| @noindent |
| and then the substitution will occur as desired. |
| |
| @ifset vms |
| @node The GNAT Run-Time Library Builder gnatlbr |
| @chapter The GNAT Run-Time Library Builder @code{gnatlbr} |
| @findex gnatlbr |
| @cindex Library builder |
| |
| @noindent |
| @code{gnatlbr} is a tool for rebuilding the GNAT run time with user |
| supplied configuration pragmas. |
| |
| @menu |
| * Running gnatlbr:: |
| * Switches for gnatlbr:: |
| * Examples of gnatlbr Usage:: |
| @end menu |
| |
| @node Running gnatlbr |
| @section Running @code{gnatlbr} |
| |
| @noindent |
| The @code{gnatlbr} command has the form |
| |
| @smallexample |
| $ GNAT LIBRARY /[CREATE | SET | DELETE]=directory [/CONFIG=file] |
| @end smallexample |
| |
| @node Switches for gnatlbr |
| @section Switches for @code{gnatlbr} |
| |
| @noindent |
| @code{gnatlbr} recognizes the following switches: |
| |
| @table @option |
| @c !sort! |
| @item /CREATE=directory |
| @cindex @code{/CREATE} (@code{gnatlbr}) |
| Create the new run-time library in the specified directory. |
| |
| @item /SET=directory |
| @cindex @code{/SET} (@code{gnatlbr}) |
| Make the library in the specified directory the current run-time |
| library. |
| |
| @item /DELETE=directory |
| @cindex @code{/DELETE} (@code{gnatlbr}) |
| Delete the run-time library in the specified directory. |
| |
| @item /CONFIG=file |
| @cindex @code{/CONFIG} (@code{gnatlbr}) |
| With /CREATE: |
| Use the configuration pragmas in the specified file when building |
| the library. |
| |
| With /SET: |
| Use the configuration pragmas in the specified file when compiling. |
| |
| @end table |
| |
| @node Examples of gnatlbr Usage |
| @section Example of @code{gnatlbr} Usage |
| |
| @smallexample |
| Contents of VAXFLOAT.ADC: |
| pragma Float_Representation (VAX_Float); |
| |
| $ GNAT LIBRARY /CREATE=[.VAXFLOAT] /CONFIG=VAXFLOAT.ADC |
| |
| GNAT LIBRARY rebuilds the run-time library in directory [.VAXFLOAT] |
| |
| @end smallexample |
| @end ifset |
| |
| @node The GNAT Library Browser gnatls |
| @chapter The GNAT Library Browser @code{gnatls} |
| @findex gnatls |
| @cindex Library browser |
| |
| @noindent |
| @code{gnatls} is a tool that outputs information about compiled |
| units. It gives the relationship between objects, unit names and source |
| files. It can also be used to check the source dependencies of a unit |
| as well as various characteristics. |
| |
| @menu |
| * Running gnatls:: |
| * Switches for gnatls:: |
| * Examples of gnatls Usage:: |
| @end menu |
| |
| @node Running gnatls |
| @section Running @code{gnatls} |
| |
| @noindent |
| The @code{gnatls} command has the form |
| |
| @smallexample |
| $ gnatls switches @var{object_or_ali_file} |
| @end smallexample |
| |
| @noindent |
| The main argument is the list of object or @file{ali} files |
| (@pxref{The Ada Library Information Files}) |
| for which information is requested. |
| |
| In normal mode, without additional option, @code{gnatls} produces a |
| four-column listing. Each line represents information for a specific |
| object. The first column gives the full path of the object, the second |
| column gives the name of the principal unit in this object, the third |
| column gives the status of the source and the fourth column gives the |
| full path of the source representing this unit. |
| Here is a simple example of use: |
| |
| @smallexample |
| $ gnatls *.o |
| ^./^[]^demo1.o demo1 DIF demo1.adb |
| ^./^[]^demo2.o demo2 OK demo2.adb |
| ^./^[]^hello.o h1 OK hello.adb |
| ^./^[]^instr-child.o instr.child MOK instr-child.adb |
| ^./^[]^instr.o instr OK instr.adb |
| ^./^[]^tef.o tef DIF tef.adb |
| ^./^[]^text_io_example.o text_io_example OK text_io_example.adb |
| ^./^[]^tgef.o tgef DIF tgef.adb |
| @end smallexample |
| |
| @noindent |
| The first line can be interpreted as follows: the main unit which is |
| contained in |
| object file @file{demo1.o} is demo1, whose main source is in |
| @file{demo1.adb}. Furthermore, the version of the source used for the |
| compilation of demo1 has been modified (DIF). Each source file has a status |
| qualifier which can be: |
| |
| @table @code |
| @item OK (unchanged) |
| The version of the source file used for the compilation of the |
| specified unit corresponds exactly to the actual source file. |
| |
| @item MOK (slightly modified) |
| The version of the source file used for the compilation of the |
| specified unit differs from the actual source file but not enough to |
| require recompilation. If you use gnatmake with the qualifier |
| @option{^-m (minimal recompilation)^/MINIMAL_RECOMPILATION^}, a file marked |
| MOK will not be recompiled. |
| |
| @item DIF (modified) |
| No version of the source found on the path corresponds to the source |
| used to build this object. |
| |
| @item ??? (file not found) |
| No source file was found for this unit. |
| |
| @item HID (hidden, unchanged version not first on PATH) |
| The version of the source that corresponds exactly to the source used |
| for compilation has been found on the path but it is hidden by another |
| version of the same source that has been modified. |
| |
| @end table |
| |
| @node Switches for gnatls |
| @section Switches for @code{gnatls} |
| |
| @noindent |
| @code{gnatls} recognizes the following switches: |
| |
| @table @option |
| @c !sort! |
| @item ^-a^/ALL_UNITS^ |
| @cindex @option{^-a^/ALL_UNITS^} (@code{gnatls}) |
| Consider all units, including those of the predefined Ada library. |
| Especially useful with @option{^-d^/DEPENDENCIES^}. |
| |
| @item ^-d^/DEPENDENCIES^ |
| @cindex @option{^-d^/DEPENDENCIES^} (@code{gnatls}) |
| List sources from which specified units depend on. |
| |
| @item ^-h^/OUTPUT=OPTIONS^ |
| @cindex @option{^-h^/OUTPUT=OPTIONS^} (@code{gnatls}) |
| Output the list of options. |
| |
| @item ^-o^/OUTPUT=OBJECTS^ |
| @cindex @option{^-o^/OUTPUT=OBJECTS^} (@code{gnatls}) |
| Only output information about object files. |
| |
| @item ^-s^/OUTPUT=SOURCES^ |
| @cindex @option{^-s^/OUTPUT=SOURCES^} (@code{gnatls}) |
| Only output information about source files. |
| |
| @item ^-u^/OUTPUT=UNITS^ |
| @cindex @option{^-u^/OUTPUT=UNITS^} (@code{gnatls}) |
| Only output information about compilation units. |
| |
| @item ^-files^/FILES^=@var{file} |
| @cindex @option{^-files^/FILES^} (@code{gnatls}) |
| Take as arguments the files listed in text file @var{file}. |
| Text file @var{file} may contain empty lines that are ignored. |
| Each non empty line should contain the name of an existing file. |
| Several such switches may be specified simultaneously. |
| |
| @item ^-aO^/OBJECT_SEARCH=^@var{dir} |
| @itemx ^-aI^/SOURCE_SEARCH=^@var{dir} |
| @itemx ^-I^/SEARCH=^@var{dir} |
| @itemx ^-I-^/NOCURRENT_DIRECTORY^ |
| @itemx -nostdinc |
| @cindex @option{^-aO^/OBJECT_SEARCH^} (@code{gnatls}) |
| @cindex @option{^-aI^/SOURCE_SEARCH^} (@code{gnatls}) |
| @cindex @option{^-I^/SEARCH^} (@code{gnatls}) |
| @cindex @option{^-I-^/NOCURRENT_DIRECTORY^} (@code{gnatls}) |
| Source path manipulation. Same meaning as the equivalent @command{gnatmake} |
| flags (@pxref{Switches for gnatmake}). |
| |
| @item --RTS=@var{rts-path} |
| @cindex @option{--RTS} (@code{gnatls}) |
| Specifies the default location of the runtime library. Same meaning as the |
| equivalent @command{gnatmake} flag (@pxref{Switches for gnatmake}). |
| |
| @item ^-v^/OUTPUT=VERBOSE^ |
| @cindex @option{^-v^/OUTPUT=VERBOSE^} (@code{gnatls}) |
| Verbose mode. Output the complete source, object and project paths. Do not use |
| the default column layout but instead use long format giving as much as |
| information possible on each requested units, including special |
| characteristics such as: |
| |
| @table @code |
| @item Preelaborable |
| The unit is preelaborable in the Ada 95 sense. |
| |
| @item No_Elab_Code |
| No elaboration code has been produced by the compiler for this unit. |
| |
| @item Pure |
| The unit is pure in the Ada 95 sense. |
| |
| @item Elaborate_Body |
| The unit contains a pragma Elaborate_Body. |
| |
| @item Remote_Types |
| The unit contains a pragma Remote_Types. |
| |
| @item Shared_Passive |
| The unit contains a pragma Shared_Passive. |
| |
| @item Predefined |
| This unit is part of the predefined environment and cannot be modified |
| by the user. |
| |
| @item Remote_Call_Interface |
| The unit contains a pragma Remote_Call_Interface. |
| |
| @end table |
| |
| @end table |
| |
| @node Examples of gnatls Usage |
| @section Example of @code{gnatls} Usage |
| @ifclear vms |
| |
| @noindent |
| Example of using the verbose switch. Note how the source and |
| object paths are affected by the -I switch. |
| |
| @smallexample |
| $ gnatls -v -I.. demo1.o |
| |
| GNATLS 5.03w (20041123-34) |
| Copyright 1997-2004 Free Software Foundation, Inc. |
| |
| Source Search Path: |
| <Current_Directory> |
| ../ |
| /home/comar/local/adainclude/ |
| |
| Object Search Path: |
| <Current_Directory> |
| ../ |
| /home/comar/local/lib/gcc-lib/x86-linux/3.4.3/adalib/ |
| |
| Project Search Path: |
| <Current_Directory> |
| /home/comar/local/lib/gnat/ |
| |
| ./demo1.o |
| Unit => |
| Name => demo1 |
| Kind => subprogram body |
| Flags => No_Elab_Code |
| Source => demo1.adb modified |
| @end smallexample |
| |
| @noindent |
| The following is an example of use of the dependency list. |
| Note the use of the -s switch |
| which gives a straight list of source files. This can be useful for |
| building specialized scripts. |
| |
| @smallexample |
| $ gnatls -d demo2.o |
| ./demo2.o demo2 OK demo2.adb |
| OK gen_list.ads |
| OK gen_list.adb |
| OK instr.ads |
| OK instr-child.ads |
| |
| $ gnatls -d -s -a demo1.o |
| demo1.adb |
| /home/comar/local/adainclude/ada.ads |
| /home/comar/local/adainclude/a-finali.ads |
| /home/comar/local/adainclude/a-filico.ads |
| /home/comar/local/adainclude/a-stream.ads |
| /home/comar/local/adainclude/a-tags.ads |
| gen_list.ads |
| gen_list.adb |
| /home/comar/local/adainclude/gnat.ads |
| /home/comar/local/adainclude/g-io.ads |
| instr.ads |
| /home/comar/local/adainclude/system.ads |
| /home/comar/local/adainclude/s-exctab.ads |
| /home/comar/local/adainclude/s-finimp.ads |
| /home/comar/local/adainclude/s-finroo.ads |
| /home/comar/local/adainclude/s-secsta.ads |
| /home/comar/local/adainclude/s-stalib.ads |
| /home/comar/local/adainclude/s-stoele.ads |
| /home/comar/local/adainclude/s-stratt.ads |
| /home/comar/local/adainclude/s-tasoli.ads |
| /home/comar/local/adainclude/s-unstyp.ads |
| /home/comar/local/adainclude/unchconv.ads |
| @end smallexample |
| @end ifclear |
| |
| @ifset vms |
| @smallexample |
| GNAT LIST /DEPENDENCIES /OUTPUT=SOURCES /ALL_UNITS DEMO1.ADB |
| |
| GNU:[LIB.OPENVMS7_1.2_8_1.ADALIB]ada.ads |
| GNU:[LIB.OPENVMS7_1.2_8_1.ADALIB]a-finali.ads |
| GNU:[LIB.OPENVMS7_1.2_8_1.ADALIB]a-filico.ads |
| GNU:[LIB.OPENVMS7_1.2_8_1.ADALIB]a-stream.ads |
| GNU:[LIB.OPENVMS7_1.2_8_1.ADALIB]a-tags.ads |
| demo1.adb |
| gen_list.ads |
| gen_list.adb |
| GNU:[LIB.OPENVMS7_1.2_8_1.ADALIB]gnat.ads |
| GNU:[LIB.OPENVMS7_1.2_8_1.ADALIB]g-io.ads |
| instr.ads |
| GNU:[LIB.OPENVMS7_1.2_8_1.ADALIB]system.ads |
| GNU:[LIB.OPENVMS7_1.2_8_1.ADALIB]s-exctab.ads |
| GNU:[LIB.OPENVMS7_1.2_8_1.ADALIB]s-finimp.ads |
| GNU:[LIB.OPENVMS7_1.2_8_1.ADALIB]s-finroo.ads |
| GNU:[LIB.OPENVMS7_1.2_8_1.ADALIB]s-secsta.ads |
| GNU:[LIB.OPENVMS7_1.2_8_1.ADALIB]s-stalib.ads |
| GNU:[LIB.OPENVMS7_1.2_8_1.ADALIB]s-stoele.ads |
| GNU:[LIB.OPENVMS7_1.2_8_1.ADALIB]s-stratt.ads |
| GNU:[LIB.OPENVMS7_1.2_8_1.ADALIB]s-tasoli.ads |
| GNU:[LIB.OPENVMS7_1.2_8_1.ADALIB]s-unstyp.ads |
| GNU:[LIB.OPENVMS7_1.2_8_1.ADALIB]unchconv.ads |
| @end smallexample |
| @end ifset |
| |
| @node Cleaning Up Using gnatclean |
| @chapter Cleaning Up Using @code{gnatclean} |
| @findex gnatclean |
| @cindex Cleaning tool |
| |
| @noindent |
| @code{gnatclean} is a tool that allows the deletion of files produced by the |
| compiler, binder and linker, including ALI files, object files, tree files, |
| expanded source files, library files, interface copy source files, binder |
| generated files and executable files. |
| |
| @menu |
| * Running gnatclean:: |
| * Switches for gnatclean:: |
| @c * Examples of gnatclean Usage:: |
| @end menu |
| |
| @node Running gnatclean |
| @section Running @code{gnatclean} |
| |
| @noindent |
| The @code{gnatclean} command has the form: |
| |
| @smallexample |
| $ gnatclean switches @var{names} |
| @end smallexample |
| |
| @noindent |
| @var{names} is a list of source file names. Suffixes @code{.^ads^ADS^} and |
| @code{^adb^ADB^} may be omitted. If a project file is specified using switch |
| @code{^-P^/PROJECT_FILE=^}, then @var{names} may be completely omitted. |
| |
| @noindent |
| In normal mode, @code{gnatclean} delete the files produced by the compiler and, |
| if switch @code{^-c^/COMPILER_FILES_ONLY^} is not specified, by the binder and |
| the linker. In informative-only mode, specified by switch |
| @code{^-n^/NODELETE^}, the list of files that would have been deleted in |
| normal mode is listed, but no file is actually deleted. |
| |
| @node Switches for gnatclean |
| @section Switches for @code{gnatclean} |
| |
| @noindent |
| @code{gnatclean} recognizes the following switches: |
| |
| @table @option |
| @c !sort! |
| @item ^-c^/COMPILER_FILES_ONLY^ |
| @cindex @option{^-c^/COMPILER_FILES_ONLY^} (@code{gnatclean}) |
| Only attempt to delete the files produced by the compiler, not those produced |
| by the binder or the linker. The files that are not to be deleted are library |
| files, interface copy files, binder generated files and executable files. |
| |
| @item ^-D ^/DIRECTORY_OBJECTS=^@var{dir} |
| @cindex @option{^-D^/DIRECTORY_OBJECTS^} (@code{gnatclean}) |
| Indicate that ALI and object files should normally be found in directory |
| @var{dir}. |
| |
| @item ^-F^/FULL_PATH_IN_BRIEF_MESSAGES^ |
| @cindex @option{^-F^/FULL_PATH_IN_BRIEF_MESSAGES^} (@code{gnatclean}) |
| When using project files, if some errors or warnings are detected during |
| parsing and verbose mode is not in effect (no use of switch |
| ^-v^/VERBOSE^), then error lines start with the full path name of the project |
| file, rather than its simple file name. |
| |
| @item ^-h^/HELP^ |
| @cindex @option{^-h^/HELP^} (@code{gnatclean}) |
| Output a message explaining the usage of @code{^gnatclean^gnatclean^}. |
| |
| @item ^-n^/NODELETE^ |
| @cindex @option{^-n^/NODELETE^} (@code{gnatclean}) |
| Informative-only mode. Do not delete any files. Output the list of the files |
| that would have been deleted if this switch was not specified. |
| |
| @item ^-P^/PROJECT_FILE=^@var{project} |
| @cindex @option{^-P^/PROJECT_FILE^} (@code{gnatclean}) |
| Use project file @var{project}. Only one such switch can be used. |
| When cleaning a project file, the files produced by the compilation of the |
| immediate sources or inherited sources of the project files are to be |
| deleted. This is not depending on the presence or not of executable names |
| on the command line. |
| |
| @item ^-q^/QUIET^ |
| @cindex @option{^-q^/QUIET^} (@code{gnatclean}) |
| Quiet output. If there are no errors, do not output anything, except in |
| verbose mode (switch ^-v^/VERBOSE^) or in informative-only mode |
| (switch ^-n^/NODELETE^). |
| |
| @item ^-r^/RECURSIVE^ |
| @cindex @option{^-r^/RECURSIVE^} (@code{gnatclean}) |
| When a project file is specified (using switch ^-P^/PROJECT_FILE=^), |
| clean all imported and extended project files, recursively. If this switch |
| is not specified, only the files related to the main project file are to be |
| deleted. This switch has no effect if no project file is specified. |
| |
| @item ^-v^/VERBOSE^ |
| @cindex @option{^-v^/VERBOSE^} (@code{gnatclean}) |
| Verbose mode. |
| |
| @item ^-vP^/MESSAGES_PROJECT_FILE=^@emph{x} |
| @cindex @option{^-vP^/MESSAGES_PROJECT_FILE^} (@code{gnatclean}) |
| Indicates the verbosity of the parsing of GNAT project files. |
| @xref{Switches Related to Project Files}. |
| |
| @item ^-X^/EXTERNAL_REFERENCE=^@var{name=value} |
| @cindex @option{^-X^/EXTERNAL_REFERENCE^} (@code{gnatclean}) |
| Indicates that external variable @var{name} has the value @var{value}. |
| The Project Manager will use this value for occurrences of |
| @code{external(name)} when parsing the project file. |
| @xref{Switches Related to Project Files}. |
| |
| @item ^-aO^/OBJECT_SEARCH=^@var{dir} |
| @cindex @option{^-aO^/OBJECT_SEARCH^} (@code{gnatclean}) |
| When searching for ALI and object files, look in directory |
| @var{dir}. |
| |
| @item ^-I^/SEARCH=^@var{dir} |
| @cindex @option{^-I^/SEARCH^} (@code{gnatclean}) |
| Equivalent to @option{^-aO^/OBJECT_SEARCH=^@var{dir}}. |
| |
| @item ^-I-^/NOCURRENT_DIRECTORY^ |
| @cindex @option{^-I-^/NOCURRENT_DIRECTORY^} (@code{gnatclean}) |
| @cindex Source files, suppressing search |
| Do not look for ALI or object files in the directory |
| where @code{gnatclean} was invoked. |
| |
| @end table |
| |
| @c @node Examples of gnatclean Usage |
| @c @section Examples of @code{gnatclean} Usage |
| |
| @ifclear vms |
| @node GNAT and Libraries |
| @chapter GNAT and Libraries |
| @cindex Library, building, installing, using |
| |
| @noindent |
| This chapter describes how to build and use libraries with GNAT, and also shows |
| how to recompile the GNAT run-time library. You should be familiar with the |
| Project Manager facility (@pxref{GNAT Project Manager}) before reading this |
| chapter. |
| |
| @menu |
| * Introduction to Libraries in GNAT:: |
| * General Ada Libraries:: |
| * Stand-alone Ada Libraries:: |
| * Rebuilding the GNAT Run-Time Library:: |
| @end menu |
| |
| @node Introduction to Libraries in GNAT |
| @section Introduction to Libraries in GNAT |
| |
| @noindent |
| A library is, conceptually, a collection of objects which does not have its |
| own main thread of execution, but rather provides certain services to the |
| applications that use it. A library can be either statically linked with the |
| application, in which case its code is directly included in the application, |
| or, on platforms that support it, be dynamically linked, in which case |
| its code is shared by all applications making use of this library. |
| |
| GNAT supports both types of libraries. |
| In the static case, the compiled code can be provided in different ways. The |
| simplest approach is to provide directly the set of objects resulting from |
| compilation of the library source files. Alternatively, you can group the |
| objects into an archive using whatever commands are provided by the operating |
| system. For the latter case, the objects are grouped into a shared library. |
| |
| In the GNAT environment, a library has three types of components: |
| @itemize @bullet |
| @item |
| Source files. |
| @item |
| @file{ALI} files. |
| @xref{The Ada Library Information Files}. |
| @item |
| Object files, an archive or a shared library. |
| @end itemize |
| |
| @noindent |
| A GNAT library may expose all its source files, which is useful for |
| documentation purposes. Alternatively, it may expose only the units needed by |
| an external user to make use of the library. That is to say, the specs |
| reflecting the library services along with all the units needed to compile |
| those specs, which can include generic bodies or any body implementing an |
| inlined routine. In the case of @emph{stand-alone libraries} those exposed |
| units are called @emph{interface units} (@pxref{Stand-alone Ada Libraries}). |
| |
| All compilation units comprising an application, including those in a library, |
| need to be elaborated in an order partially defined by Ada's semantics. GNAT |
| computes the elaboration order from the @file{ALI} files and this is why they |
| constitute a mandatory part of GNAT libraries. Except in the case of |
| @emph{stand-alone libraries}, where a specific library elaboration routine is |
| produced independently of the application(s) using the library. |
| |
| @node General Ada Libraries |
| @section General Ada Libraries |
| |
| @menu |
| * Building a library:: |
| * Installing a library:: |
| * Using a library:: |
| @end menu |
| |
| @node Building a library |
| @subsection Building a library |
| |
| @noindent |
| The easiest way to build a library is to use the Project Manager, |
| which supports a special type of project called a @emph{Library Project} |
| (@pxref{Library Projects}). |
| |
| A project is considered a library project, when two project-level attributes |
| are defined in it: @code{Library_Name} and @code{Library_Dir}. In order to |
| control different aspects of library configuration, additional optional |
| project-level attributes can be specified: |
| @table @code |
| @item Library_Kind |
| This attribute controls whether the library is to be static or dynamic |
| |
| @item Library_Version |
| This attribute specifies the library version; this value is used |
| during dynamic linking of shared libraries to determine if the currently |
| installed versions of the binaries are compatible. |
| |
| @item Library_Options |
| @item Library_GCC |
| These attributes specify additional low-level options to be used during |
| library generation, and redefine the actual application used to generate |
| library. |
| @end table |
| |
| @noindent |
| The GNAT Project Manager takes full care of the library maintenance task, |
| including recompilation of the source files for which objects do not exist |
| or are not up to date, assembly of the library archive, and installation of |
| the library (i.e., copying associated source, object and @file{ALI} files |
| to the specified location). |
| |
| Here is a simple library project file: |
| @smallexample @c ada |
| project My_Lib is |
| for Source_Dirs use ("src1", "src2"); |
| for Object_Dir use "obj"; |
| for Library_Name use "mylib"; |
| for Library_Dir use "lib"; |
| for Library_Kind use "dynamic"; |
| end My_lib; |
| @end smallexample |
| |
| @noindent |
| and the compilation command to build and install the library: |
| |
| @smallexample @c ada |
| $ gnatmake -Pmy_lib |
| @end smallexample |
| |
| @noindent |
| It is not entirely trivial to perform manually all the steps required to |
| produce a library. We recommend that you use the GNAT Project Manager |
| for this task. In special cases where this is not desired, the necessary |
| steps are discussed below. |
| |
| There are various possibilities for compiling the units that make up the |
| library: for example with a Makefile (@pxref{Using the GNU make Utility}) or |
| with a conventional script. For simple libraries, it is also possible to create |
| a dummy main program which depends upon all the packages that comprise the |
| interface of the library. This dummy main program can then be given to |
| @command{gnatmake}, which will ensure that all necessary objects are built. |
| |
| After this task is accomplished, you should follow the standard procedure |
| of the underlying operating system to produce the static or shared library. |
| |
| Here is an example of such a dummy program: |
| @smallexample @c ada |
| @group |
| with My_Lib.Service1; |
| with My_Lib.Service2; |
| with My_Lib.Service3; |
| procedure My_Lib_Dummy is |
| begin |
| null; |
| end; |
| @end group |
| @end smallexample |
| |
| @noindent |
| Here are the generic commands that will build an archive or a shared library. |
| |
| @smallexample |
| # compiling the library |
| $ gnatmake -c my_lib_dummy.adb |
| |
| # we don't need the dummy object itself |
| $ rm my_lib_dummy.o my_lib_dummy.ali |
| |
| # create an archive with the remaining objects |
| $ ar rc libmy_lib.a *.o |
| # some systems may require "ranlib" to be run as well |
| |
| # or create a shared library |
| $ gcc -shared -o libmy_lib.so *.o |
| # some systems may require the code to have been compiled with -fPIC |
| |
| # remove the object files that are now in the library |
| $ rm *.o |
| |
| # Make the ALI files read-only so that gnatmake will not try to |
| # regenerate the objects that are in the library |
| $ chmod -w *.ali |
| @end smallexample |
| |
| @noindent |
| Please note that the library must have a name of the form @file{libxxx.a} or |
| @file{libxxx.so} (or @file{libxxx.dll} on Windows) in order to be accessed by |
| the directive @option{-lxxx} at link time. |
| |
| @node Installing a library |
| @subsection Installing a library |
| @cindex @code{ADA_PROJECT_PATH} |
| |
| @noindent |
| If you use project files, library installation is part of the library build |
| process. Thus no further action is needed in order to make use of the |
| libraries that are built as part of the general application build. A usable |
| version of the library is installed in the directory specified by the |
| @code{Library_Dir} attribute of the library project file. |
| |
| You may want to install a library in a context different from where the library |
| is built. This situation arises with third party suppliers, who may want |
| to distribute a library in binary form where the user is not expected to be |
| able to recompile the library. The simplest option in this case is to provide |
| a project file slightly different from the one used to build the library, by |
| using the @code{externally_built} attribute. For instance, the project |
| file used to build the library in the previous section can be changed into the |
| following one when the library is installed: |
| |
| @smallexample @c projectfile |
| project My_Lib is |
| for Source_Dirs use ("src1", "src2"); |
| for Library_Name use "mylib"; |
| for Library_Dir use "lib"; |
| for Library_Kind use "dynamic"; |
| for Externally_Built use "true"; |
| end My_lib; |
| @end smallexample |
| |
| @noindent |
| This project file assumes that the directories @file{src1}, |
| @file{src2}, and @file{lib} exist in |
| the directory containing the project file. The @code{externally_built} |
| attribute makes it clear to the GNAT builder that it should not attempt to |
| recompile any of the units from this library. It allows the library provider to |
| restrict the source set to the minimum necessary for clients to make use of the |
| library as described in the first section of this chapter. It is the |
| responsibility of the library provider to install the necessary sources, ALI |
| files and libraries in the directories mentioned in the project file. For |
| convenience, the user's library project file should be installed in a location |
| that will be searched automatically by the GNAT |
| builder. These are the directories referenced in the @code{ADA_PROJECT_PATH} |
| environment variable (@pxref{Importing Projects}), and also the default GNAT |
| library location that can be queried with @command{gnatls -v} and is usually of |
| the form $gnat_install_root/lib/gnat. |
| |
| When project files are not an option, it is also possible, but not recommended, |
| to install the library so that the sources needed to use the library are on the |
| Ada source path and the ALI files & libraries be on the Ada Object path (see |
| @ref{Search Paths and the Run-Time Library (RTL)}. Alternatively, the system |
| administrator can place general-purpose libraries in the default compiler |
| paths, by specifying the libraries' location in the configuration files |
| @file{ada_source_path} and @file{ada_object_path}. These configuration files |
| must be located in the GNAT installation tree at the same place as the gcc spec |
| file. The location of the gcc spec file can be determined as follows: |
| @smallexample |
| $ gcc -v |
| @end smallexample |
| |
| @noindent |
| The configuration files mentioned above have a simple format: each line |
| must contain one unique directory name. |
| Those names are added to the corresponding path |
| in their order of appearance in the file. The names can be either absolute |
| or relative; in the latter case, they are relative to where theses files |
| are located. |
| |
| The files @file{ada_source_path} and @file{ada_object_path} might not be |
| present in a |
| GNAT installation, in which case, GNAT will look for its run-time library in |
| the directories @file{adainclude} (for the sources) and @file{adalib} (for the |
| objects and @file{ALI} files). When the files exist, the compiler does not |
| look in @file{adainclude} and @file{adalib}, and thus the |
| @file{ada_source_path} file |
| must contain the location for the GNAT run-time sources (which can simply |
| be @file{adainclude}). In the same way, the @file{ada_object_path} file must |
| contain the location for the GNAT run-time objects (which can simply |
| be @file{adalib}). |
| |
| You can also specify a new default path to the run-time library at compilation |
| time with the switch @option{--RTS=rts-path}. You can thus choose / change |
| the run-time library you want your program to be compiled with. This switch is |
| recognized by @command{gcc}, @command{gnatmake}, @command{gnatbind}, |
| @command{gnatls}, @command{gnatfind} and @command{gnatxref}. |
| |
| It is possible to install a library before or after the standard GNAT |
| library, by reordering the lines in the configuration files. In general, a |
| library must be installed before the GNAT library if it redefines |
| any part of it. |
| |
| @node Using a library |
| @subsection Using a library |
| |
| @noindent Once again, the project facility greatly simplifies the use of |
| libraries. In this context, using a library is just a matter of adding a |
| @code{with} clause in the user project. For instance, to make use of the |
| library @code{My_Lib} shown in examples in earlier sections, you can |
| write: |
| |
| @smallexample @c projectfile |
| with "my_lib"; |
| project My_Proj is |
| ... |
| end My_Proj; |
| @end smallexample |
| |
| Even if you have a third-party, non-Ada library, you can still use GNAT's |
| Project Manager facility to provide a wrapper for it. For example, the |
| following project, when @code{with}ed by your main project, will link with the |
| third-party library @file{liba.a}: |
| |
| @smallexample @c projectfile |
| @group |
| project Liba is |
| for Externally_Built use "true"; |
| for Library_Dir use "lib"; |
| for Library_Name use "a"; |
| for Library_Kind use "static"; |
| end Liba; |
| @end group |
| @end smallexample |
| This is an alternative to the use of @code{pragma Linker_Options}. It is |
| especially interesting in the context of systems with several interdependent |
| static libraries where finding a proper linker order is not easy and best be |
| left to the tools having visibility over project dependence information. |
| |
| @noindent |
| In order to use an Ada library manually, you need to make sure that this |
| library is on both your source and object path |
| (see @ref{Search Paths and the Run-Time Library (RTL)} |
| and @ref{Search Paths for gnatbind}). Furthermore, when the objects are grouped |
| in an archive or a shared library, you need to specify the desired |
| library at link time. |
| |
| For example, you can use the library @file{mylib} installed in |
| @file{/dir/my_lib_src} and @file{/dir/my_lib_obj} with the following commands: |
| |
| @smallexample |
| $ gnatmake -aI/dir/my_lib_src -aO/dir/my_lib_obj my_appl \ |
| -largs -lmy_lib |
| @end smallexample |
| |
| @noindent |
| This can be expressed more simply: |
| @smallexample |
| $ gnatmake my_appl |
| @end smallexample |
| @noindent |
| when the following conditions are met: |
| @itemize @bullet |
| @item |
| @file{/dir/my_lib_src} has been added by the user to the environment |
| variable @code{ADA_INCLUDE_PATH}, or by the administrator to the file |
| @file{ada_source_path} |
| @item |
| @file{/dir/my_lib_obj} has been added by the user to the environment |
| variable @code{ADA_OBJECTS_PATH}, or by the administrator to the file |
| @file{ada_object_path} |
| @item |
| a pragma @code{Linker_Options} has been added to one of the sources. |
| For example: |
| |
| @smallexample @c ada |
| pragma Linker_Options ("-lmy_lib"); |
| @end smallexample |
| @end itemize |
| |
| @node Stand-alone Ada Libraries |
| @section Stand-alone Ada Libraries |
| @cindex Stand-alone library, building, using |
| |
| @menu |
| * Introduction to Stand-alone Libraries:: |
| * Building a Stand-alone Library:: |
| * Creating a Stand-alone Library to be used in a non-Ada context:: |
| * Restrictions in Stand-alone Libraries:: |
| @end menu |
| |
| @node Introduction to Stand-alone Libraries |
| @subsection Introduction to Stand-alone Libraries |
| |
| @noindent |
| A Stand-alone Library (abbreviated ``SAL'') is a library that contains the |
| necessary code to |
| elaborate the Ada units that are included in the library. In contrast with |
| an ordinary library, which consists of all sources, objects and @file{ALI} |
| files of the |
| library, a SAL may specify a restricted subset of compilation units |
| to serve as a library interface. In this case, the fully |
| self-sufficient set of files will normally consist of an objects |
| archive, the sources of interface units' specs, and the @file{ALI} |
| files of interface units. |
| If an interface spec contains a generic unit or an inlined subprogram, |
| the body's |
| source must also be provided; if the units that must be provided in the source |
| form depend on other units, the source and @file{ALI} files of those must |
| also be provided. |
| |
| The main purpose of a SAL is to minimize the recompilation overhead of client |
| applications when a new version of the library is installed. Specifically, |
| if the interface sources have not changed, client applications do not need to |
| be recompiled. If, furthermore, a SAL is provided in the shared form and its |
| version, controlled by @code{Library_Version} attribute, is not changed, |
| then the clients do not need to be relinked. |
| |
| SALs also allow the library providers to minimize the amount of library source |
| text exposed to the clients. Such ``information hiding'' might be useful or |
| necessary for various reasons. |
| |
| Stand-alone libraries are also well suited to be used in an executable whose |
| main routine is not written in Ada. |
| |
| @node Building a Stand-alone Library |
| @subsection Building a Stand-alone Library |
| |
| @noindent |
| GNAT's Project facility provides a simple way of building and installing |
| stand-alone libraries; see @ref{Stand-alone Library Projects}. |
| To be a Stand-alone Library Project, in addition to the two attributes |
| that make a project a Library Project (@code{Library_Name} and |
| @code{Library_Dir}; see @ref{Library Projects}), the attribute |
| @code{Library_Interface} must be defined. For example: |
| |
| @smallexample @c projectfile |
| @group |
| for Library_Dir use "lib_dir"; |
| for Library_Name use "dummy"; |
| for Library_Interface use ("int1", "int1.child"); |
| @end group |
| @end smallexample |
| |
| @noindent |
| Attribute @code{Library_Interface} has a non-empty string list value, |
| each string in the list designating a unit contained in an immediate source |
| of the project file. |
| |
| When a Stand-alone Library is built, first the binder is invoked to build |
| a package whose name depends on the library name |
| (@file{^b~dummy.ads/b^B$DUMMY.ADS/B^} in the example above). |
| This binder-generated package includes initialization and |
| finalization procedures whose |
| names depend on the library name (@code{dummyinit} and @code{dummyfinal} |
| in the example |
| above). The object corresponding to this package is included in the library. |
| |
| You must ensure timely (e.g., prior to any use of interfaces in the SAL) |
| calling of these procedures if a static SAL is built, or if a shared SAL |
| is built |
| with the project-level attribute @code{Library_Auto_Init} set to |
| @code{"false"}. |
| |
| For a Stand-Alone Library, only the @file{ALI} files of the Interface Units |
| (those that are listed in attribute @code{Library_Interface}) are copied to |
| the Library Directory. As a consequence, only the Interface Units may be |
| imported from Ada units outside of the library. If other units are imported, |
| the binding phase will fail. |
| |
| The attribute @code{Library_Src_Dir} may be specified for a |
| Stand-Alone Library. @code{Library_Src_Dir} is a simple attribute that has a |
| single string value. Its value must be the path (absolute or relative to the |
| project directory) of an existing directory. This directory cannot be the |
| object directory or one of the source directories, but it can be the same as |
| the library directory. The sources of the Interface |
| Units of the library that are needed by an Ada client of the library will be |
| copied to the designated directory, called the Interface Copy directory. |
| These sources include the specs of the Interface Units, but they may also |
| include bodies and subunits, when pragmas @code{Inline} or @code{Inline_Always} |
| are used, or when there is a generic unit in the spec. Before the sources |
| are copied to the Interface Copy directory, an attempt is made to delete all |
| files in the Interface Copy directory. |
| |
| Building stand-alone libraries by hand is somewhat tedious, but for those |
| occasions when it is necessary here are the steps that you need to perform: |
| @itemize @bullet |
| @item |
| Compile all library sources. |
| |
| @item |
| Invoke the binder with the switch @option{-n} (No Ada main program), |
| with all the @file{ALI} files of the interfaces, and |
| with the switch @option{-L} to give specific names to the @code{init} |
| and @code{final} procedures. For example: |
| @smallexample |
| gnatbind -n int1.ali int2.ali -Lsal1 |
| @end smallexample |
| |
| @item |
| Compile the binder generated file: |
| @smallexample |
| gcc -c b~int2.adb |
| @end smallexample |
| |
| @item |
| Link the dynamic library with all the necessary object files, |
| indicating to the linker the names of the @code{init} (and possibly |
| @code{final}) procedures for automatic initialization (and finalization). |
| The built library should be placed in a directory different from |
| the object directory. |
| |
| @item |
| Copy the @code{ALI} files of the interface to the library directory, |
| add in this copy an indication that it is an interface to a SAL |
| (i.e. add a word @option{SL} on the line in the @file{ALI} file that starts |
| with letter ``P'') and make the modified copy of the @file{ALI} file |
| read-only. |
| @end itemize |
| |
| @noindent |
| Using SALs is not different from using other libraries |
| (see @ref{Using a library}). |
| |
| @node Creating a Stand-alone Library to be used in a non-Ada context |
| @subsection Creating a Stand-alone Library to be used in a non-Ada context |
| |
| @noindent |
| It is easy to adapt the SAL build procedure discussed above for use of a SAL in |
| a non-Ada context. |
| |
| The only extra step required is to ensure that library interface subprograms |
| are compatible with the main program, by means of @code{pragma Export} |
| or @code{pragma Convention}. |
| |
| Here is an example of simple library interface for use with C main program: |
| |
| @smallexample @c ada |
| package Interface is |
| |
| procedure Do_Something; |
| pragma Export (C, Do_Something, "do_something"); |
| |
| procedure Do_Something_Else; |
| pragma Export (C, Do_Something_Else, "do_something_else"); |
| |
| end Interface; |
| @end smallexample |
| |
| @noindent |
| On the foreign language side, you must provide a ``foreign'' view of the |
| library interface; remember that it should contain elaboration routines in |
| addition to interface subprograms. |
| |
| The example below shows the content of @code{mylib_interface.h} (note |
| that there is no rule for the naming of this file, any name can be used) |
| @smallexample |
| /* the library elaboration procedure */ |
| extern void mylibinit (void); |
| |
| /* the library finalization procedure */ |
| extern void mylibfinal (void); |
| |
| /* the interface exported by the library */ |
| extern void do_something (void); |
| extern void do_something_else (void); |
| @end smallexample |
| |
| @noindent |
| Libraries built as explained above can be used from any program, provided |
| that the elaboration procedures (named @code{mylibinit} in the previous |
| example) are called before the library services are used. Any number of |
| libraries can be used simultaneously, as long as the elaboration |
| procedure of each library is called. |
| |
| Below is an example of a C program that uses the @code{mylib} library. |
| |
| @smallexample |
| #include "mylib_interface.h" |
| |
| int |
| main (void) |
| @{ |
| /* First, elaborate the library before using it */ |
| mylibinit (); |
| |
| /* Main program, using the library exported entities */ |
| do_something (); |
| do_something_else (); |
| |
| /* Library finalization at the end of the program */ |
| mylibfinal (); |
| return 0; |
| @} |
| @end smallexample |
| |
| @noindent |
| Note that invoking any library finalization procedure generated by |
| @code{gnatbind} shuts down the Ada run-time environment. |
| Consequently, the |
| finalization of all Ada libraries must be performed at the end of the program. |
| No call to these libraries or to the Ada run-time library should be made |
| after the finalization phase. |
| |
| @node Restrictions in Stand-alone Libraries |
| @subsection Restrictions in Stand-alone Libraries |
| |
| @noindent |
| The pragmas listed below should be used with caution inside libraries, |
| as they can create incompatibilities with other Ada libraries: |
| @itemize @bullet |
| @item pragma @code{Locking_Policy} |
| @item pragma @code{Queuing_Policy} |
| @item pragma @code{Task_Dispatching_Policy} |
| @item pragma @code{Unreserve_All_Interrupts} |
| @end itemize |
| |
| @noindent |
| When using a library that contains such pragmas, the user must make sure |
| that all libraries use the same pragmas with the same values. Otherwise, |
| @code{Program_Error} will |
| be raised during the elaboration of the conflicting |
| libraries. The usage of these pragmas and its consequences for the user |
| should therefore be well documented. |
| |
| Similarly, the traceback in the exception occurrence mechanism should be |
| enabled or disabled in a consistent manner across all libraries. |
| Otherwise, Program_Error will be raised during the elaboration of the |
| conflicting libraries. |
| |
| If the @code{Version} or @code{Body_Version} |
| attributes are used inside a library, then you need to |
| perform a @code{gnatbind} step that specifies all @file{ALI} files in all |
| libraries, so that version identifiers can be properly computed. |
| In practice these attributes are rarely used, so this is unlikely |
| to be a consideration. |
| |
| @node Rebuilding the GNAT Run-Time Library |
| @section Rebuilding the GNAT Run-Time Library |
| @cindex GNAT Run-Time Library, rebuilding |
| @cindex Building the GNAT Run-Time Library |
| @cindex Rebuilding the GNAT Run-Time Library |
| @cindex Run-Time Library, rebuilding |
| |
| @noindent |
| It may be useful to recompile the GNAT library in various contexts, the |
| most important one being the use of partition-wide configuration pragmas |
| such as @code{Normalize_Scalars}. A special Makefile called |
| @code{Makefile.adalib} is provided to that effect and can be found in |
| the directory containing the GNAT library. The location of this |
| directory depends on the way the GNAT environment has been installed and can |
| be determined by means of the command: |
| |
| @smallexample |
| $ gnatls -v |
| @end smallexample |
| |
| @noindent |
| The last entry in the object search path usually contains the |
| gnat library. This Makefile contains its own documentation and in |
| particular the set of instructions needed to rebuild a new library and |
| to use it. |
| |
| @node Using the GNU make Utility |
| @chapter Using the GNU @code{make} Utility |
| @findex make |
| |
| @noindent |
| This chapter offers some examples of makefiles that solve specific |
| problems. It does not explain how to write a makefile (see the GNU make |
| documentation), nor does it try to replace the @command{gnatmake} utility |
| (@pxref{The GNAT Make Program gnatmake}). |
| |
| All the examples in this section are specific to the GNU version of |
| make. Although @code{make} is a standard utility, and the basic language |
| is the same, these examples use some advanced features found only in |
| @code{GNU make}. |
| |
| @menu |
| * Using gnatmake in a Makefile:: |
| * Automatically Creating a List of Directories:: |
| * Generating the Command Line Switches:: |
| * Overcoming Command Line Length Limits:: |
| @end menu |
| |
| @node Using gnatmake in a Makefile |
| @section Using gnatmake in a Makefile |
| @findex makefile |
| @cindex GNU make |
| |
| @noindent |
| Complex project organizations can be handled in a very powerful way by |
| using GNU make combined with gnatmake. For instance, here is a Makefile |
| which allows you to build each subsystem of a big project into a separate |
| shared library. Such a makefile allows you to significantly reduce the link |
| time of very big applications while maintaining full coherence at |
| each step of the build process. |
| |
| The list of dependencies are handled automatically by |
| @command{gnatmake}. The Makefile is simply used to call gnatmake in each of |
| the appropriate directories. |
| |
| Note that you should also read the example on how to automatically |
| create the list of directories |
| (@pxref{Automatically Creating a List of Directories}) |
| which might help you in case your project has a lot of subdirectories. |
| |
| @smallexample |
| @iftex |
| @leftskip=0cm |
| @font@heightrm=cmr8 |
| @heightrm |
| @end iftex |
| ## This Makefile is intended to be used with the following directory |
| ## configuration: |
| ## - The sources are split into a series of csc (computer software components) |
| ## Each of these csc is put in its own directory. |
| ## Their name are referenced by the directory names. |
| ## They will be compiled into shared library (although this would also work |
| ## with static libraries |
| ## - The main program (and possibly other packages that do not belong to any |
| ## csc is put in the top level directory (where the Makefile is). |
| ## toplevel_dir __ first_csc (sources) __ lib (will contain the library) |
| ## \_ second_csc (sources) __ lib (will contain the library) |
| ## \_ ... |
| ## Although this Makefile is build for shared library, it is easy to modify |
| ## to build partial link objects instead (modify the lines with -shared and |
| ## gnatlink below) |
| ## |
| ## With this makefile, you can change any file in the system or add any new |
| ## file, and everything will be recompiled correctly (only the relevant shared |
| ## objects will be recompiled, and the main program will be re-linked). |
| |
| # The list of computer software component for your project. This might be |
| # generated automatically. |
| CSC_LIST=aa bb cc |
| |
| # Name of the main program (no extension) |
| MAIN=main |
| |
| # If we need to build objects with -fPIC, uncomment the following line |
| #NEED_FPIC=-fPIC |
| |
| # The following variable should give the directory containing libgnat.so |
| # You can get this directory through 'gnatls -v'. This is usually the last |
| # directory in the Object_Path. |
| GLIB=... |
| |
| # The directories for the libraries |
| # (This macro expands the list of CSC to the list of shared libraries, you |
| # could simply use the expanded form : |
| # LIB_DIR=aa/lib/libaa.so bb/lib/libbb.so cc/lib/libcc.so |
| LIB_DIR=$@{foreach dir,$@{CSC_LIST@},$@{dir@}/lib/lib$@{dir@}.so@} |
| |
| $@{MAIN@}: objects $@{LIB_DIR@} |
| gnatbind $@{MAIN@} $@{CSC_LIST:%=-aO%/lib@} -shared |
| gnatlink $@{MAIN@} $@{CSC_LIST:%=-l%@} |
| |
| objects:: |
| # recompile the sources |
| gnatmake -c -i $@{MAIN@}.adb $@{NEED_FPIC@} $@{CSC_LIST:%=-I%@} |
| |
| # Note: In a future version of GNAT, the following commands will be simplified |
| # by a new tool, gnatmlib |
| $@{LIB_DIR@}: |
| mkdir -p $@{dir $@@ @} |
| cd $@{dir $@@ @}; gcc -shared -o $@{notdir $@@ @} ../*.o -L$@{GLIB@} -lgnat |
| cd $@{dir $@@ @}; cp -f ../*.ali . |
| |
| # The dependencies for the modules |
| # Note that we have to force the expansion of *.o, since in some cases |
| # make won't be able to do it itself. |
| aa/lib/libaa.so: $@{wildcard aa/*.o@} |
| bb/lib/libbb.so: $@{wildcard bb/*.o@} |
| cc/lib/libcc.so: $@{wildcard cc/*.o@} |
| |
| # Make sure all of the shared libraries are in the path before starting the |
| # program |
| run:: |
| LD_LIBRARY_PATH=`pwd`/aa/lib:`pwd`/bb/lib:`pwd`/cc/lib ./$@{MAIN@} |
| |
| clean:: |
| $@{RM@} -rf $@{CSC_LIST:%=%/lib@} |
| $@{RM@} $@{CSC_LIST:%=%/*.ali@} |
| $@{RM@} $@{CSC_LIST:%=%/*.o@} |
| $@{RM@} *.o *.ali $@{MAIN@} |
| @end smallexample |
| |
| @node Automatically Creating a List of Directories |
| @section Automatically Creating a List of Directories |
| |
| @noindent |
| In most makefiles, you will have to specify a list of directories, and |
| store it in a variable. For small projects, it is often easier to |
| specify each of them by hand, since you then have full control over what |
| is the proper order for these directories, which ones should be |
| included... |
| |
| However, in larger projects, which might involve hundreds of |
| subdirectories, it might be more convenient to generate this list |
| automatically. |
| |
| The example below presents two methods. The first one, although less |
| general, gives you more control over the list. It involves wildcard |
| characters, that are automatically expanded by @code{make}. Its |
| shortcoming is that you need to explicitly specify some of the |
| organization of your project, such as for instance the directory tree |
| depth, whether some directories are found in a separate tree,... |
| |
| The second method is the most general one. It requires an external |
| program, called @code{find}, which is standard on all Unix systems. All |
| the directories found under a given root directory will be added to the |
| list. |
| |
| @smallexample |
| @iftex |
| @leftskip=0cm |
| @font@heightrm=cmr8 |
| @heightrm |
| @end iftex |
| # The examples below are based on the following directory hierarchy: |
| # All the directories can contain any number of files |
| # ROOT_DIRECTORY -> a -> aa -> aaa |
| # -> ab |
| # -> ac |
| # -> b -> ba -> baa |
| # -> bb |
| # -> bc |
| # This Makefile creates a variable called DIRS, that can be reused any time |
| # you need this list (see the other examples in this section) |
| |
| # The root of your project's directory hierarchy |
| ROOT_DIRECTORY=. |
| |
| #### |
| # First method: specify explicitly the list of directories |
| # This allows you to specify any subset of all the directories you need. |
| #### |
| |
| DIRS := a/aa/ a/ab/ b/ba/ |
| |
| #### |
| # Second method: use wildcards |
| # Note that the argument(s) to wildcard below should end with a '/'. |
| # Since wildcards also return file names, we have to filter them out |
| # to avoid duplicate directory names. |
| # We thus use make's @code{dir} and @code{sort} functions. |
| # It sets DIRs to the following value (note that the directories aaa and baa |
| # are not given, unless you change the arguments to wildcard). |
| # DIRS= ./a/a/ ./b/ ./a/aa/ ./a/ab/ ./a/ac/ ./b/ba/ ./b/bb/ ./b/bc/ |
| #### |
| |
| DIRS := $@{sort $@{dir $@{wildcard $@{ROOT_DIRECTORY@}/*/ |
| $@{ROOT_DIRECTORY@}/*/*/@}@}@} |
| |
| #### |
| # Third method: use an external program |
| # This command is much faster if run on local disks, avoiding NFS slowdowns. |
| # This is the most complete command: it sets DIRs to the following value: |
| # DIRS= ./a ./a/aa ./a/aa/aaa ./a/ab ./a/ac ./b ./b/ba ./b/ba/baa ./b/bb ./b/bc |
| #### |
| |
| DIRS := $@{shell find $@{ROOT_DIRECTORY@} -type d -print@} |
| |
| @end smallexample |
| |
| @node Generating the Command Line Switches |
| @section Generating the Command Line Switches |
| |
| @noindent |
| Once you have created the list of directories as explained in the |
| previous section (@pxref{Automatically Creating a List of Directories}), |
| you can easily generate the command line arguments to pass to gnatmake. |
| |
| For the sake of completeness, this example assumes that the source path |
| is not the same as the object path, and that you have two separate lists |
| of directories. |
| |
| @smallexample |
| # see "Automatically creating a list of directories" to create |
| # these variables |
| SOURCE_DIRS= |
| OBJECT_DIRS= |
| |
| GNATMAKE_SWITCHES := $@{patsubst %,-aI%,$@{SOURCE_DIRS@}@} |
| GNATMAKE_SWITCHES += $@{patsubst %,-aO%,$@{OBJECT_DIRS@}@} |
| |
| all: |
| gnatmake $@{GNATMAKE_SWITCHES@} main_unit |
| @end smallexample |
| |
| @node Overcoming Command Line Length Limits |
| @section Overcoming Command Line Length Limits |
| |
| @noindent |
| One problem that might be encountered on big projects is that many |
| operating systems limit the length of the command line. It is thus hard to give |
| gnatmake the list of source and object directories. |
| |
| This example shows how you can set up environment variables, which will |
| make @command{gnatmake} behave exactly as if the directories had been |
| specified on the command line, but have a much higher length limit (or |
| even none on most systems). |
| |
| It assumes that you have created a list of directories in your Makefile, |
| using one of the methods presented in |
| @ref{Automatically Creating a List of Directories}. |
| For the sake of completeness, we assume that the object |
| path (where the ALI files are found) is different from the sources patch. |
| |
| Note a small trick in the Makefile below: for efficiency reasons, we |
| create two temporary variables (SOURCE_LIST and OBJECT_LIST), that are |
| expanded immediately by @code{make}. This way we overcome the standard |
| make behavior which is to expand the variables only when they are |
| actually used. |
| |
| On Windows, if you are using the standard Windows command shell, you must |
| replace colons with semicolons in the assignments to these variables. |
| |
| @smallexample |
| @iftex |
| @leftskip=0cm |
| @font@heightrm=cmr8 |
| @heightrm |
| @end iftex |
| # In this example, we create both ADA_INCLUDE_PATH and ADA_OBJECT_PATH. |
| # This is the same thing as putting the -I arguments on the command line. |
| # (the equivalent of using -aI on the command line would be to define |
| # only ADA_INCLUDE_PATH, the equivalent of -aO is ADA_OBJECT_PATH). |
| # You can of course have different values for these variables. |
| # |
| # Note also that we need to keep the previous values of these variables, since |
| # they might have been set before running 'make' to specify where the GNAT |
| # library is installed. |
| |
| # see "Automatically creating a list of directories" to create these |
| # variables |
| SOURCE_DIRS= |
| OBJECT_DIRS= |
| |
| empty:= |
| space:=$@{empty@} $@{empty@} |
| SOURCE_LIST := $@{subst $@{space@},:,$@{SOURCE_DIRS@}@} |
| OBJECT_LIST := $@{subst $@{space@},:,$@{OBJECT_DIRS@}@} |
| ADA_INCLUDE_PATH += $@{SOURCE_LIST@} |
| ADA_OBJECT_PATH += $@{OBJECT_LIST@} |
| export ADA_INCLUDE_PATH |
| export ADA_OBJECT_PATH |
| |
| all: |
| gnatmake main_unit |
| @end smallexample |
| @end ifclear |
| |
| @node Memory Management Issues |
| @chapter Memory Management Issues |
| |
| @noindent |
| This chapter describes some useful memory pools provided in the GNAT library |
| and in particular the GNAT Debug Pool facility, which can be used to detect |
| incorrect uses of access values (including ``dangling references''). |
| @ifclear vms |
| It also describes the @command{gnatmem} tool, which can be used to track down |
| ``memory leaks''. |
| @end ifclear |
| |
| @menu |
| * Some Useful Memory Pools:: |
| * The GNAT Debug Pool Facility:: |
| @ifclear vms |
| * The gnatmem Tool:: |
| @end ifclear |
| @end menu |
| |
| @node Some Useful Memory Pools |
| @section Some Useful Memory Pools |
| @findex Memory Pool |
| @cindex storage, pool |
| |
| @noindent |
| The @code{System.Pool_Global} package offers the Unbounded_No_Reclaim_Pool |
| storage pool. Allocations use the standard system call @code{malloc} while |
| deallocations use the standard system call @code{free}. No reclamation is |
| performed when the pool goes out of scope. For performance reasons, the |
| standard default Ada allocators/deallocators do not use any explicit storage |
| pools but if they did, they could use this storage pool without any change in |
| behavior. That is why this storage pool is used when the user |
| manages to make the default implicit allocator explicit as in this example: |
| @smallexample @c ada |
| type T1 is access Something; |
| -- no Storage pool is defined for T2 |
| type T2 is access Something_Else; |
| for T2'Storage_Pool use T1'Storage_Pool; |
| -- the above is equivalent to |
| for T2'Storage_Pool use System.Pool_Global.Global_Pool_Object; |
| @end smallexample |
| |
| @noindent |
| The @code{System.Pool_Local} package offers the Unbounded_Reclaim_Pool storage |
| pool. The allocation strategy is similar to @code{Pool_Local}'s |
| except that the all |
| storage allocated with this pool is reclaimed when the pool object goes out of |
| scope. This pool provides a explicit mechanism similar to the implicit one |
| provided by several Ada 83 compilers for allocations performed through a local |
| access type and whose purpose was to reclaim memory when exiting the |
| scope of a given local access. As an example, the following program does not |
| leak memory even though it does not perform explicit deallocation: |
| |
| @smallexample @c ada |
| with System.Pool_Local; |
| procedure Pooloc1 is |
| procedure Internal is |
| type A is access Integer; |
| X : System.Pool_Local.Unbounded_Reclaim_Pool; |
| for A'Storage_Pool use X; |
| v : A; |
| begin |
| for I in 1 .. 50 loop |
| v := new Integer; |
| end loop; |
| end Internal; |
| begin |
| for I in 1 .. 100 loop |
| Internal; |
| end loop; |
| end Pooloc1; |
| @end smallexample |
| |
| @noindent |
| The @code{System.Pool_Size} package implements the Stack_Bounded_Pool used when |
| @code{Storage_Size} is specified for an access type. |
| The whole storage for the pool is |
| allocated at once, usually on the stack at the point where the access type is |
| elaborated. It is automatically reclaimed when exiting the scope where the |
| access type is defined. This package is not intended to be used directly by the |
| user and it is implicitly used for each such declaration: |
| |
| @smallexample @c ada |
| type T1 is access Something; |
| for T1'Storage_Size use 10_000; |
| @end smallexample |
| |
| |
| @node The GNAT Debug Pool Facility |
| @section The GNAT Debug Pool Facility |
| @findex Debug Pool |
| @cindex storage, pool, memory corruption |
| |
| @noindent |
| The use of unchecked deallocation and unchecked conversion can easily |
| lead to incorrect memory references. The problems generated by such |
| references are usually difficult to tackle because the symptoms can be |
| very remote from the origin of the problem. In such cases, it is |
| very helpful to detect the problem as early as possible. This is the |
| purpose of the Storage Pool provided by @code{GNAT.Debug_Pools}. |
| |
| In order to use the GNAT specific debugging pool, the user must |
| associate a debug pool object with each of the access types that may be |
| related to suspected memory problems. See Ada Reference Manual 13.11. |
| @smallexample @c ada |
| type Ptr is access Some_Type; |
| Pool : GNAT.Debug_Pools.Debug_Pool; |
| for Ptr'Storage_Pool use Pool; |
| @end smallexample |
| |
| @noindent |
| @code{GNAT.Debug_Pools} is derived from a GNAT-specific kind of |
| pool: the @code{Checked_Pool}. Such pools, like standard Ada storage pools, |
| allow the user to redefine allocation and deallocation strategies. They |
| also provide a checkpoint for each dereference, through the use of |
| the primitive operation @code{Dereference} which is implicitly called at |
| each dereference of an access value. |
| |
| Once an access type has been associated with a debug pool, operations on |
| values of the type may raise four distinct exceptions, |
| which correspond to four potential kinds of memory corruption: |
| @itemize @bullet |
| @item |
| @code{GNAT.Debug_Pools.Accessing_Not_Allocated_Storage} |
| @item |
| @code{GNAT.Debug_Pools.Accessing_Deallocated_Storage} |
| @item |
| @code{GNAT.Debug_Pools.Freeing_Not_Allocated_Storage} |
| @item |
| @code{GNAT.Debug_Pools.Freeing_Deallocated_Storage } |
| @end itemize |
| |
| @noindent |
| For types associated with a Debug_Pool, dynamic allocation is performed using |
| the standard GNAT allocation routine. References to all allocated chunks of |
| memory are kept in an internal dictionary. Several deallocation strategies are |
| provided, whereupon the user can choose to release the memory to the system, |
| keep it allocated for further invalid access checks, or fill it with an easily |
| recognizable pattern for debug sessions. The memory pattern is the old IBM |
| hexadecimal convention: @code{16#DEADBEEF#}. |
| |
| See the documentation in the file g-debpoo.ads for more information on the |
| various strategies. |
| |
| Upon each dereference, a check is made that the access value denotes a |
| properly allocated memory location. Here is a complete example of use of |
| @code{Debug_Pools}, that includes typical instances of memory corruption: |
| @smallexample @c ada |
| @iftex |
| @leftskip=0cm |
| @end iftex |
| with Gnat.Io; use Gnat.Io; |
| with Unchecked_Deallocation; |
| with Unchecked_Conversion; |
| with GNAT.Debug_Pools; |
| with System.Storage_Elements; |
| with Ada.Exceptions; use Ada.Exceptions; |
| procedure Debug_Pool_Test is |
| |
| type T is access Integer; |
| type U is access all T; |
| |
| P : GNAT.Debug_Pools.Debug_Pool; |
| for T'Storage_Pool use P; |
| |
| procedure Free is new Unchecked_Deallocation (Integer, T); |
| function UC is new Unchecked_Conversion (U, T); |
| A, B : aliased T; |
| |
| procedure Info is new GNAT.Debug_Pools.Print_Info(Put_Line); |
| |
| begin |
| Info (P); |
| A := new Integer; |
| B := new Integer; |
| B := A; |
| Info (P); |
| Free (A); |
| begin |
| Put_Line (Integer'Image(B.all)); |
| exception |
| when E : others => Put_Line ("raised: " & Exception_Name (E)); |
| end; |
| begin |
| Free (B); |
| exception |
| when E : others => Put_Line ("raised: " & Exception_Name (E)); |
| end; |
| B := UC(A'Access); |
| begin |
| Put_Line (Integer'Image(B.all)); |
| exception |
| when E : others => Put_Line ("raised: " & Exception_Name (E)); |
| end; |
| begin |
| Free (B); |
| exception |
| when E : others => Put_Line ("raised: " & Exception_Name (E)); |
| end; |
| Info (P); |
| end Debug_Pool_Test; |
| @end smallexample |
| |
| @noindent |
| The debug pool mechanism provides the following precise diagnostics on the |
| execution of this erroneous program: |
| @smallexample |
| Debug Pool info: |
| Total allocated bytes : 0 |
| Total deallocated bytes : 0 |
| Current Water Mark: 0 |
| High Water Mark: 0 |
| |
| Debug Pool info: |
| Total allocated bytes : 8 |
| Total deallocated bytes : 0 |
| Current Water Mark: 8 |
| High Water Mark: 8 |
| |
| raised: GNAT.DEBUG_POOLS.ACCESSING_DEALLOCATED_STORAGE |
| raised: GNAT.DEBUG_POOLS.FREEING_DEALLOCATED_STORAGE |
| raised: GNAT.DEBUG_POOLS.ACCESSING_NOT_ALLOCATED_STORAGE |
| raised: GNAT.DEBUG_POOLS.FREEING_NOT_ALLOCATED_STORAGE |
| Debug Pool info: |
| Total allocated bytes : 8 |
| Total deallocated bytes : 4 |
| Current Water Mark: 4 |
| High Water Mark: 8 |
| @end smallexample |
| |
| @ifclear vms |
| @node The gnatmem Tool |
| @section The @command{gnatmem} Tool |
| @findex gnatmem |
| |
| @noindent |
| The @code{gnatmem} utility monitors dynamic allocation and |
| deallocation activity in a program, and displays information about |
| incorrect deallocations and possible sources of memory leaks. |
| It provides three type of information: |
| @itemize @bullet |
| @item |
| General information concerning memory management, such as the total |
| number of allocations and deallocations, the amount of allocated |
| memory and the high water mark, i.e. the largest amount of allocated |
| memory in the course of program execution. |
| |
| @item |
| Backtraces for all incorrect deallocations, that is to say deallocations |
| which do not correspond to a valid allocation. |
| |
| @item |
| Information on each allocation that is potentially the origin of a memory |
| leak. |
| @end itemize |
| |
| @menu |
| * Running gnatmem:: |
| * Switches for gnatmem:: |
| * Example of gnatmem Usage:: |
| @end menu |
| |
| @node Running gnatmem |
| @subsection Running @code{gnatmem} |
| |
| @noindent |
| @code{gnatmem} makes use of the output created by the special version of |
| allocation and deallocation routines that record call information. This |
| allows to obtain accurate dynamic memory usage history at a minimal cost to |
| the execution speed. Note however, that @code{gnatmem} is not supported on |
| all platforms (currently, it is supported on AIX, HP-UX, GNU/Linux x86, |
| 32-bit Solaris (sparc and x86) and Windows NT/2000/XP (x86). |
| |
| @noindent |
| The @code{gnatmem} command has the form |
| |
| @smallexample |
| $ gnatmem [switches] user_program |
| @end smallexample |
| |
| @noindent |
| The program must have been linked with the instrumented version of the |
| allocation and deallocation routines. This is done by linking with the |
| @file{libgmem.a} library. For correct symbolic backtrace information, |
| the user program should be compiled with debugging options |
| (see @ref{Switches for gcc}). For example to build @file{my_program}: |
| |
| @smallexample |
| $ gnatmake -g my_program -largs -lgmem |
| @end smallexample |
| |
| @noindent |
| When @file{my_program} is executed, the file @file{gmem.out} is produced. |
| This file contains information about all allocations and deallocations |
| performed by the program. It is produced by the instrumented allocations and |
| deallocations routines and will be used by @code{gnatmem}. |
| |
| In order to produce symbolic backtrace information for allocations and |
| deallocations performed by the GNAT run-time library, you need to use a |
| version of that library that has been compiled with the @option{-g} switch |
| (see @ref{Rebuilding the GNAT Run-Time Library}). |
| |
| Gnatmem must be supplied with the @file{gmem.out} file and the executable to |
| examine. If the location of @file{gmem.out} file was not explicitly supplied by |
| @code{-i} switch, gnatmem will assume that this file can be found in the |
| current directory. For example, after you have executed @file{my_program}, |
| @file{gmem.out} can be analyzed by @code{gnatmem} using the command: |
| |
| @smallexample |
| $ gnatmem my_program |
| @end smallexample |
| |
| @noindent |
| This will produce the output with the following format: |
| |
| *************** debut cc |
| @smallexample |
| $ gnatmem my_program |
| |
| Global information |
| ------------------ |
| Total number of allocations : 45 |
| Total number of deallocations : 6 |
| Final Water Mark (non freed mem) : 11.29 Kilobytes |
| High Water Mark : 11.40 Kilobytes |
| |
| . |
| . |
| . |
| Allocation Root # 2 |
| ------------------- |
| Number of non freed allocations : 11 |
| Final Water Mark (non freed mem) : 1.16 Kilobytes |
| High Water Mark : 1.27 Kilobytes |
| Backtrace : |
| my_program.adb:23 my_program.alloc |
| . |
| . |
| . |
| @end smallexample |
| |
| The first block of output gives general information. In this case, the |
| Ada construct ``@code{@b{new}}'' was executed 45 times, and only 6 calls to an |
| Unchecked_Deallocation routine occurred. |
| |
| @noindent |
| Subsequent paragraphs display information on all allocation roots. |
| An allocation root is a specific point in the execution of the program |
| that generates some dynamic allocation, such as a ``@code{@b{new}}'' |
| construct. This root is represented by an execution backtrace (or subprogram |
| call stack). By default the backtrace depth for allocations roots is 1, so |
| that a root corresponds exactly to a source location. The backtrace can |
| be made deeper, to make the root more specific. |
| |
| @node Switches for gnatmem |
| @subsection Switches for @code{gnatmem} |
| |
| @noindent |
| @code{gnatmem} recognizes the following switches: |
| |
| @table @option |
| |
| @item -q |
| @cindex @option{-q} (@code{gnatmem}) |
| Quiet. Gives the minimum output needed to identify the origin of the |
| memory leaks. Omits statistical information. |
| |
| @item @var{N} |
| @cindex @var{N} (@code{gnatmem}) |
| N is an integer literal (usually between 1 and 10) which controls the |
| depth of the backtraces defining allocation root. The default value for |
| N is 1. The deeper the backtrace, the more precise the localization of |
| the root. Note that the total number of roots can depend on this |
| parameter. This parameter must be specified @emph{before} the name of the |
| executable to be analyzed, to avoid ambiguity. |
| |
| @item -b n |
| @cindex @option{-b} (@code{gnatmem}) |
| This switch has the same effect as just depth parameter. |
| |
| @item -i @var{file} |
| @cindex @option{-i} (@code{gnatmem}) |
| Do the @code{gnatmem} processing starting from @file{file}, rather than |
| @file{gmem.out} in the current directory. |
| |
| @item -m n |
| @cindex @option{-m} (@code{gnatmem}) |
| This switch causes @code{gnatmem} to mask the allocation roots that have less |
| than n leaks. The default value is 1. Specifying the value of 0 will allow to |
| examine even the roots that didn't result in leaks. |
| |
| @item -s order |
| @cindex @option{-s} (@code{gnatmem}) |
| This switch causes @code{gnatmem} to sort the allocation roots according to the |
| specified order of sort criteria, each identified by a single letter. The |
| currently supported criteria are @code{n, h, w} standing respectively for |
| number of unfreed allocations, high watermark, and final watermark |
| corresponding to a specific root. The default order is @code{nwh}. |
| |
| @end table |
| |
| @node Example of gnatmem Usage |
| @subsection Example of @code{gnatmem} Usage |
| |
| @noindent |
| The following example shows the use of @code{gnatmem} |
| on a simple memory-leaking program. |
| Suppose that we have the following Ada program: |
| |
| @smallexample @c ada |
| @group |
| @cartouche |
| with Unchecked_Deallocation; |
| procedure Test_Gm is |
| |
| type T is array (1..1000) of Integer; |
| type Ptr is access T; |
| procedure Free is new Unchecked_Deallocation (T, Ptr); |
| A : Ptr; |
| |
| procedure My_Alloc is |
| begin |
| A := new T; |
| end My_Alloc; |
| |
| procedure My_DeAlloc is |
| B : Ptr := A; |
| begin |
| Free (B); |
| end My_DeAlloc; |
| |
| begin |
| My_Alloc; |
| for I in 1 .. 5 loop |
| for J in I .. 5 loop |
| My_Alloc; |
| end loop; |
| My_Dealloc; |
| end loop; |
| end; |
| @end cartouche |
| @end group |
| @end smallexample |
| |
| @noindent |
| The program needs to be compiled with debugging option and linked with |
| @code{gmem} library: |
| |
| @smallexample |
| $ gnatmake -g test_gm -largs -lgmem |
| @end smallexample |
| |
| @noindent |
| Then we execute the program as usual: |
| |
| @smallexample |
| $ test_gm |
| @end smallexample |
| |
| @noindent |
| Then @code{gnatmem} is invoked simply with |
| @smallexample |
| $ gnatmem test_gm |
| @end smallexample |
| |
| @noindent |
| which produces the following output (result may vary on different platforms): |
| |
| @smallexample |
| Global information |
| ------------------ |
| Total number of allocations : 18 |
| Total number of deallocations : 5 |
| Final Water Mark (non freed mem) : 53.00 Kilobytes |
| High Water Mark : 56.90 Kilobytes |
| |
| Allocation Root # 1 |
| ------------------- |
| Number of non freed allocations : 11 |
| Final Water Mark (non freed mem) : 42.97 Kilobytes |
| High Water Mark : 46.88 Kilobytes |
| Backtrace : |
| test_gm.adb:11 test_gm.my_alloc |
| |
| Allocation Root # 2 |
| ------------------- |
| Number of non freed allocations : 1 |
| Final Water Mark (non freed mem) : 10.02 Kilobytes |
| High Water Mark : 10.02 Kilobytes |
| Backtrace : |
| s-secsta.adb:81 system.secondary_stack.ss_init |
| |
| Allocation Root # 3 |
| ------------------- |
| Number of non freed allocations : 1 |
| Final Water Mark (non freed mem) : 12 Bytes |
| High Water Mark : 12 Bytes |
| Backtrace : |
| s-secsta.adb:181 system.secondary_stack.ss_init |
| @end smallexample |
| |
| @noindent |
| Note that the GNAT run time contains itself a certain number of |
| allocations that have no corresponding deallocation, |
| as shown here for root #2 and root |
| #3. This is a normal behavior when the number of non freed allocations |
| is one, it allocates dynamic data structures that the run time needs for |
| the complete lifetime of the program. Note also that there is only one |
| allocation root in the user program with a single line back trace: |
| test_gm.adb:11 test_gm.my_alloc, whereas a careful analysis of the |
| program shows that 'My_Alloc' is called at 2 different points in the |
| source (line 21 and line 24). If those two allocation roots need to be |
| distinguished, the backtrace depth parameter can be used: |
| |
| @smallexample |
| $ gnatmem 3 test_gm |
| @end smallexample |
| |
| @noindent |
| which will give the following output: |
| |
| @smallexample |
| Global information |
| ------------------ |
| Total number of allocations : 18 |
| Total number of deallocations : 5 |
| Final Water Mark (non freed mem) : 53.00 Kilobytes |
| High Water Mark : 56.90 Kilobytes |
| |
| Allocation Root # 1 |
| ------------------- |
| Number of non freed allocations : 10 |
| Final Water Mark (non freed mem) : 39.06 Kilobytes |
| High Water Mark : 42.97 Kilobytes |
| Backtrace : |
| test_gm.adb:11 test_gm.my_alloc |
| test_gm.adb:24 test_gm |
| b_test_gm.c:52 main |
| |
| Allocation Root # 2 |
| ------------------- |
| Number of non freed allocations : 1 |
| Final Water Mark (non freed mem) : 10.02 Kilobytes |
| High Water Mark : 10.02 Kilobytes |
| Backtrace : |
| s-secsta.adb:81 system.secondary_stack.ss_init |
| s-secsta.adb:283 <system__secondary_stack___elabb> |
| b_test_gm.c:33 adainit |
| |
| Allocation Root # 3 |
| ------------------- |
| Number of non freed allocations : 1 |
| Final Water Mark (non freed mem) : 3.91 Kilobytes |
| High Water Mark : 3.91 Kilobytes |
| Backtrace : |
| test_gm.adb:11 test_gm.my_alloc |
| test_gm.adb:21 test_gm |
| b_test_gm.c:52 main |
| |
| Allocation Root # 4 |
| ------------------- |
| Number of non freed allocations : 1 |
| Final Water Mark (non freed mem) : 12 Bytes |
| High Water Mark : 12 Bytes |
| Backtrace : |
| s-secsta.adb:181 system.secondary_stack.ss_init |
| s-secsta.adb:283 <system__secondary_stack___elabb> |
| b_test_gm.c:33 adainit |
| @end smallexample |
| |
| @noindent |
| The allocation root #1 of the first example has been split in 2 roots #1 |
| and #3 thanks to the more precise associated backtrace. |
| |
| @end ifclear |
| |
| @node Stack Related Facilities |
| @chapter Stack Related Facilities |
| |
| @noindent |
| This chapter describes some useful tools associated with stack |
| checking and analysis. In |
| particular, it deals with dynamic and static stack usage measurements. |
| |
| @menu |
| * Stack Overflow Checking:: |
| * Static Stack Usage Analysis:: |
| * Dynamic Stack Usage Analysis:: |
| @end menu |
| |
| @node Stack Overflow Checking |
| @section Stack Overflow Checking |
| @cindex Stack Overflow Checking |
| @cindex -fstack-check |
| |
| @noindent |
| For most operating systems, @command{gcc} does not perform stack overflow |
| checking by default. This means that if the main environment task or |
| some other task exceeds the available stack space, then unpredictable |
| behavior will occur. Most native systems offer some level of protection by |
| adding a guard page at the end of each task stack. This mechanism is usually |
| not enough for dealing properly with stack overflow situations because |
| a large local variable could ``jump'' above the guard page. |
| Furthermore, when the |
| guard page is hit, there may not be any space left on the stack for executing |
| the exception propagation code. Enabling stack checking avoids |
| such situations. |
| |
| To activate stack checking, compile all units with the gcc option |
| @option{-fstack-check}. For example: |
| |
| @smallexample |
| gcc -c -fstack-check package1.adb |
| @end smallexample |
| |
| @noindent |
| Units compiled with this option will generate extra instructions to check |
| that any use of the stack (for procedure calls or for declaring local |
| variables in declare blocks) does not exceed the available stack space. |
| If the space is exceeded, then a @code{Storage_Error} exception is raised. |
| |
| For declared tasks, the stack size is controlled by the size |
| given in an applicable @code{Storage_Size} pragma or by the value specified |
| at bind time with @option{-d} (@pxref{Switches for gnatbind}) or is set to |
| the default size as defined in the GNAT runtime otherwise. |
| |
| For the environment task, the stack size depends on |
| system defaults and is unknown to the compiler. Stack checking |
| may still work correctly if a fixed |
| size stack is allocated, but this cannot be guaranteed. |
| To ensure that a clean exception is signalled for stack |
| overflow, set the environment variable |
| @code{GNAT_STACK_LIMIT} to indicate the maximum |
| stack area that can be used, as in: |
| @cindex GNAT_STACK_LIMIT |
| |
| @smallexample |
| SET GNAT_STACK_LIMIT 1600 |
| @end smallexample |
| |
| @noindent |
| The limit is given in kilobytes, so the above declaration would |
| set the stack limit of the environment task to 1.6 megabytes. |
| Note that the only purpose of this usage is to limit the amount |
| of stack used by the environment task. If it is necessary to |
| increase the amount of stack for the environment task, then this |
| is an operating systems issue, and must be addressed with the |
| appropriate operating systems commands. |
| |
| @node Static Stack Usage Analysis |
| @section Static Stack Usage Analysis |
| @cindex Static Stack Usage Analysis |
| @cindex -fstack-usage |
| |
| @noindent |
| A unit compiled with @option{-fstack-usage} will generate an extra file |
| that specifies |
| the maximum amount of stack used, on a per-function basis. |
| The file has the same |
| basename as the target object file with a @file{.su} extension. |
| Each line of this file is made up of three fields: |
| |
| @itemize |
| @item |
| The name of the function. |
| @item |
| A number of bytes. |
| @item |
| One or more qualifiers: @code{static}, @code{dynamic}, @code{bounded}. |
| @end itemize |
| |
| The second field corresponds to the size of the known part of the function |
| frame. |
| |
| The qualifier @code{static} means that the function frame size |
| is purely static. |
| It usually means that all local variables have a static size. |
| In this case, the second field is a reliable measure of the function stack |
| utilization. |
| |
| The qualifier @code{dynamic} means that the function frame size is not static. |
| It happens mainly when some local variables have a dynamic size. When this |
| qualifier appears alone, the second field is not a reliable measure |
| of the function stack analysis. When it is qualified with @code{bounded}, it |
| means that the second field is a reliable maximum of the function stack |
| utilization. |
| |
| @node Dynamic Stack Usage Analysis |
| @section Dynamic Stack Usage Analysis |
| |
| @noindent |
| It is possible to measure the maximum amount of stack used by a task, by |
| adding a switch to @command{gnatbind}, as: |
| |
| @smallexample |
| $ gnatbind -u0 file |
| @end smallexample |
| |
| @noindent |
| With this option, at each task termination, its stack usage is output on |
| @file{stderr}. |
| It is not always convenient to output the stack usage when the program |
| is still running. Hence, it is possible to delay this output until program |
| termination. for a given number of tasks specified as the argument of the |
| @code{-u} option. For instance: |
| |
| @smallexample |
| $ gnatbind -u100 file |
| @end smallexample |
| |
| @noindent |
| will buffer the stack usage information of the first 100 tasks to terminate and |
| output this info at program termination. Results are displayed in four |
| columns: |
| |
| @noindent |
| Index | Task Name | Stack Size | Actual Use |
| |
| @noindent |
| where: |
| |
| @table @emph |
| @item Index |
| is a number associated with each task. |
| |
| @item Task Name |
| is the name of the task analyzed. |
| |
| @item Stack Size |
| is the maximum size for the stack. In order to prevent overflow, |
| the real stack limit is slightly larger than the Stack Size in order to allow |
| proper recovery. |
| |
| @item Actual Use |
| is the measure done by the stack analyzer. |
| |
| @end table |
| |
| @noindent |
| The environment task stack, e.g. the stack that contains the main unit, is |
| only processed when the environment variable GNAT_STACK_LIMIT is set. |
| |
| @c ********************************* |
| @node Verifying properties using gnatcheck |
| @chapter Verifying properties using @command{gnatcheck} |
| @findex gnatcheck |
| |
| @noindent |
| The @command{gnatcheck} tool is an ASIS-based utility that checks properties |
| of Ada source files according to a given set of semantic rules. |
| |
| In order to check compliance with a given rule, @command{gnatcheck} has to |
| semantically analyze the Ada sources. |
| Therefore, checks can only be performed on |
| legal Ada units. Moreover, when a unit depends semantically upon units located |
| outside the current directory, the source search path has to be provided when |
| calling @command{gnatcheck}, either through a specified project file or |
| through @command{gnatcheck} switches as described below. |
| |
| The project support for @command{gnatcheck} is provided by the @command{gnat} |
| driver. |
| |
| Several rules are already implemented in @command{gnatcheck}. The list of such |
| rules can be obtained with option @option{^-h^/HELP^} as described in the next |
| section. A user can add new rules by modifying the @command{gnatcheck} code and |
| rebuilding the tool. For adding a simple rule making some local checks, a small |
| amount of straightforward ASIS-based programming is usually needed. |
| |
| @noindent |
| @command{gnatcheck} has the command-line interface of the form |
| |
| @smallexample |
| $ gnatcheck [@i{switches}] @{@i{filename}@} [@i{^-files^/FILES^=@{arg_list_filename@}}] |
| [@i{-cargs gcc_switches}] [@i{-rules rule_options}] |
| @end smallexample |
| |
| |
| @noindent |
| where |
| @itemize @bullet |
| @item |
| @i{switches} specify the general tool options |
| |
| @item |
| Each @i{filename} is the name (including the extension) of a source |
| file to process. ``Wildcards'' are allowed, and |
| the file name may contain path information. |
| |
| @item |
| Each @i{arg_list_filename} is the name (including the extension) of a text |
| file containing the names of the source files to process, separated by spaces |
| or line breaks. |
| |
| @item |
| @i{-cargs gcc_switches} is a list of switches for |
| @command{gcc}. They will be passed on to all compiler invocations made by |
| @command{gnatcheck} to generate the ASIS trees. Here you can provide |
| @option{^-I^/INCLUDE_DIRS=^} switches to form the source search path, |
| and use the @option{-gnatec} switch to set the configuration file. |
| |
| @item |
| @i{-rules rule_options} is a list of options for controlling a set of |
| rules to be checked by @command{gnatcheck} (@pxref{gnatcheck Rule Options}) |
| @end itemize |
| |
| @noindent |
| Either a @i{filename} or an @i{arg_list_filename} needs to be supplied. |
| |
| @menu |
| * Format of the Report File:: |
| * General gnatcheck Switches:: |
| * gnatcheck Rule Options:: |
| * Add the Results of Compiler Checks to gnatcheck Output:: |
| @end menu |
| |
| @node Format of the Report File |
| @section Format of the Report File |
| |
| @noindent |
| The @command{gnatcheck} tool outputs on @file{stdout} all messages concerning |
| rule violations. |
| It also creates, in the current |
| directory, a text file named @file{^gnatcheck.out^GNATCHECK.OUT^} that |
| contains the complete report of the last gnatcheck run. This report contains: |
| @itemize @bullet |
| @item a list of the Ada source files being checked, |
| @item a list of enabled and disabled rules, |
| @item a list of the diagnostic messages, ordered in three different ways |
| and collected in three separate |
| sections. Section 1 contains the raw list of diagnostic messages. It |
| corresponds to the output going to @file{stdout}. Section 2 contains |
| messages ordered by rules. |
| Section 3 contains messages ordered by source files. |
| @end itemize |
| |
| |
| @node General gnatcheck Switches |
| @section General @command{gnatcheck} Switches |
| |
| @noindent |
| The following switches control the general @command{gnatcheck} behavior |
| |
| @table @option |
| @cindex @option{^-a^/ALL^} (@command{gnatcheck}) |
| @item ^-a^/ALL^ |
| Process all units including those with read-only ALI files such as |
| those from GNAT Run-Time library. |
| |
| @cindex @option{^-h^/HELP^} (@command{gnatcheck}) |
| @item ^-h^/HELP^ |
| Print out the list of the currently implemented rules. For more details see |
| the README file in the @command{gnatcheck} sources. |
| |
| @cindex @option{^-l^/LOCS^} (@command{gnatcheck}) |
| @item ^-l^/LOCS^ |
| Use full source locations references in the report file. For a construct from |
| a generic instantiation a full source location is a chain from the location |
| of this construct in the generic unit to the place where this unit is |
| instantiated. |
| |
| @cindex @option{^-q^/QUIET^} (@command{gnatcheck}) |
| @item ^-q^/QUIET^ |
| Quiet mode. All the diagnoses about rule violations are placed in the |
| @command{gnatcheck} report file only, without duplicating in @file{stdout}. |
| |
| @cindex @option{^-s^/SHORT^} (@command{gnatcheck}) |
| @item ^-s^/SHORT^ |
| Short format of the report file (no version information, no list of applied |
| rules, no list of checked sources is included) |
| |
| @cindex @option{^-s1^/COMPILER_STYLE^} (@command{gnatcheck}) |
| @item ^-s1^/COMPILER_STYLE^ |
| Include the compiler-style section in the report file |
| |
| @cindex @option{^-s2^/BY_RULES^} (@command{gnatcheck}) |
| @item ^-s2^/BY_RULES^ |
| Include the section containing diagnoses ordered by rules in the report file |
| |
| @cindex @option{^-s3^/BY_FILES_BY_RULES^} (@command{gnatcheck}) |
| @item ^-s3^/BY_FILES_BY_RULES^ |
| Include the section containing diagnoses ordered by files and then by rules |
| in the report file |
| |
| @cindex @option{^-v^/VERBOSE^} (@command{gnatcheck}) |
| @item ^-v^/VERBOSE^ |
| Verbose mode; @command{gnatcheck} generates version information and then |
| a trace of sources being processed. |
| |
| @end table |
| |
| @noindent |
| Note, that if either of the options @option{^-s1^/COMPILER_STYLE^}, |
| @option{^-s2^/BY_RULES^} or |
| @option{^-s3^/BY_FILES_BY_RULES^} is specified, |
| then the @command{gnatcheck} report file will contain only sections |
| explicitly stated by these options. |
| |
| @node gnatcheck Rule Options |
| @section @command{gnatcheck} Rule Options |
| |
| @noindent |
| The following options control the processing performed by |
| @command{gnatcheck}. |
| |
| @table @option |
| @cindex @option{+ALL} (@command{gnatcheck}) |
| @item +ALL |
| Turn all the rule checks ON |
| |
| @cindex @option{-ALL} (@command{gnatcheck}) |
| @item -ALL |
| Turn all the rule checks OFF |
| |
| @cindex @option{+R} (@command{gnatcheck}) |
| @item +R@i{rule_id[:param]} |
| Turn on the check for a specified rule with the specified parameter, if any. |
| @i{rule_id} should be the identifier of one of the currently implemented rules |
| (use @option{^-h^/HELP^} for the list of implemented rules). Rule identifiers |
| are not case-sensitive. The @i{:param} item should |
| be a string representing a valid parameter(s) for the specified rule. |
| If it contains any space characters then this string must be enclosed in |
| quotation marks. |
| |
| @cindex @option{-R} (@command{gnatcheck}) |
| @item -R@i{rule_id} |
| Turn off the check for a specified rule |
| |
| @end table |
| |
| @node Add the Results of Compiler Checks to gnatcheck Output |
| @section Add the Results of Compiler Checks to @command{gnatcheck} Output |
| |
| @noindent |
| The @command{gnatcheck} tool can include in the generated diagnostic messages |
| and in |
| the report file the results of the checks performed by the compiler. Though |
| disabled by default, this effect may be obtained by using @option{+R} with |
| the following rule identifiers and parameters: |
| |
| @table @option |
| @item Restrictions |
| To record restrictions violations (that are performed by the compiler if the |
| pragma @code{Restrictions} or @code{Restriction_Warnings} are given), |
| use the rule named |
| @i{Restrictions} with the same parameters as pragma |
| @code{Restrictions} or @code{Restriction_Warnings} |
| |
| @item Style_Checks |
| To record compiler style checks, use the rule named |
| @i{Style_Checks}. A parameter of this rule can be either @i{All_Checks}, that |
| turns ON all the style checks, or a string that has exactly the same structure |
| and semantics as @code{string_LITERAL} parameter of GNAT pragma |
| @code{Style_Checks}. |
| |
| @item Warnings |
| To record compiler warnings (@pxref{Warning Message Control}), use the rule |
| named @i{Warnings} with a parameter that is a valid |
| @code{static_string_expression} argument of GNAT pragma @code{Warnings}. |
| |
| @end table |
| |
| @c ********************************* |
| @node Creating Sample Bodies Using gnatstub |
| @chapter Creating Sample Bodies Using @command{gnatstub} |
| @findex gnatstub |
| |
| @noindent |
| @command{gnatstub} creates body stubs, that is, empty but compilable bodies |
| for library unit declarations. |
| |
| To create a body stub, @command{gnatstub} has to compile the library |
| unit declaration. Therefore, bodies can be created only for legal |
| library units. Moreover, if a library unit depends semantically upon |
| units located outside the current directory, you have to provide |
| the source search path when calling @command{gnatstub}, see the description |
| of @command{gnatstub} switches below. |
| |
| @menu |
| * Running gnatstub:: |
| * Switches for gnatstub:: |
| @end menu |
| |
| @node Running gnatstub |
| @section Running @command{gnatstub} |
| |
| @noindent |
| @command{gnatstub} has the command-line interface of the form |
| |
| @smallexample |
| $ gnatstub [switches] filename [directory] |
| @end smallexample |
| |
| @noindent |
| where |
| @table @emph |
| @item filename |
| is the name of the source file that contains a library unit declaration |
| for which a body must be created. The file name may contain the path |
| information. |
| The file name does not have to follow the GNAT file name conventions. If the |
| name |
| does not follow GNAT file naming conventions, the name of the body file must |
| be provided |
| explicitly as the value of the @option{^-o^/BODY=^@var{body-name}} option. |
| If the file name follows the GNAT file naming |
| conventions and the name of the body file is not provided, |
| @command{gnatstub} |
| creates the name |
| of the body file from the argument file name by replacing the @file{.ads} |
| suffix |
| with the @file{.adb} suffix. |
| |
| @item directory |
| indicates the directory in which the body stub is to be placed (the default |
| is the |
| current directory) |
| |
| @item switches |
| is an optional sequence of switches as described in the next section |
| @end table |
| |
| @node Switches for gnatstub |
| @section Switches for @command{gnatstub} |
| |
| @table @option |
| @c !sort! |
| |
| @item ^-f^/FULL^ |
| @cindex @option{^-f^/FULL^} (@command{gnatstub}) |
| If the destination directory already contains a file with the name of the |
| body file |
| for the argument spec file, replace it with the generated body stub. |
| |
| @item ^-hs^/HEADER=SPEC^ |
| @cindex @option{^-hs^/HEADER=SPEC^} (@command{gnatstub}) |
| Put the comment header (i.e., all the comments preceding the |
| compilation unit) from the source of the library unit declaration |
| into the body stub. |
| |
| @item ^-hg^/HEADER=GENERAL^ |
| @cindex @option{^-hg^/HEADER=GENERAL^} (@command{gnatstub}) |
| Put a sample comment header into the body stub. |
| |
| @ifclear vms |
| @item -IDIR |
| @cindex @option{-IDIR} (@command{gnatstub}) |
| @itemx -I- |
| @cindex @option{-I-} (@command{gnatstub}) |
| @end ifclear |
| @ifset vms |
| @item /NOCURRENT_DIRECTORY |
| @cindex @option{/NOCURRENT_DIRECTORY} (@command{gnatstub}) |
| @end ifset |
| ^These switches have ^This switch has^ the same meaning as in calls to |
| @command{gcc}. |
| ^They define ^It defines ^ the source search path in the call to |
| @command{gcc} issued |
| by @command{gnatstub} to compile an argument source file. |
| |
| @item ^-gnatec^/CONFIGURATION_PRAGMAS_FILE=^@var{PATH} |
| @cindex @option{^-gnatec^/CONFIGURATION_PRAGMAS_FILE^} (@command{gnatstub}) |
| This switch has the same meaning as in calls to @command{gcc}. |
| It defines the additional configuration file to be passed to the call to |
| @command{gcc} issued |
| by @command{gnatstub} to compile an argument source file. |
| |
| @item ^-gnatyM^/MAX_LINE_LENGTH=^@var{n} |
| @cindex @option{^-gnatyM^/MAX_LINE_LENGTH^} (@command{gnatstub}) |
| (@var{n} is a non-negative integer). Set the maximum line length in the |
| body stub to @var{n}; the default is 79. The maximum value that can be |
| specified is 32767. Note that in the special case of configuration |
| pragma files, the maximum is always 32767 regardless of whether or |
| not this switch appears. |
| |
| @item ^-gnaty^/STYLE_CHECKS=^@var{n} |
| @cindex @option{^-gnaty^/STYLE_CHECKS=^} (@command{gnatstub}) |
| (@var{n} is a non-negative integer from 1 to 9). Set the indentation level in |
| the generated body sample to @var{n}. |
| The default indentation is 3. |
| |
| @item ^-gnatyo^/ORDERED_SUBPROGRAMS^ |
| @cindex @option{^-gnato^/ORDERED_SUBPROGRAMS^} (@command{gnatstub}) |
| Order local bodies alphabetically. (By default local bodies are ordered |
| in the same way as the corresponding local specs in the argument spec file.) |
| |
| @item ^-i^/INDENTATION=^@var{n} |
| @cindex @option{^-i^/INDENTATION^} (@command{gnatstub}) |
| Same as @option{^-gnaty^/STYLE_CHECKS=^@var{n}} |
| |
| @item ^-k^/TREE_FILE=SAVE^ |
| @cindex @option{^-k^/TREE_FILE=SAVE^} (@command{gnatstub}) |
| Do not remove the tree file (i.e., the snapshot of the compiler internal |
| structures used by @command{gnatstub}) after creating the body stub. |
| |
| @item ^-l^/LINE_LENGTH=^@var{n} |
| @cindex @option{^-l^/LINE_LENGTH^} (@command{gnatstub}) |
| Same as @option{^-gnatyM^/MAX_LINE_LENGTH=^@var{n}} |
| |
| @item ^-o^/BODY=^@var{body-name} |
| @cindex @option{^-o^/BODY^} (@command{gnatstub}) |
| Body file name. This should be set if the argument file name does not |
| follow |
| the GNAT file naming |
| conventions. If this switch is omitted the default name for the body will be |
| obtained |
| from the argument file name according to the GNAT file naming conventions. |
| |
| @item ^-q^/QUIET^ |
| @cindex @option{^-q^/QUIET^} (@command{gnatstub}) |
| Quiet mode: do not generate a confirmation when a body is |
| successfully created, and do not generate a message when a body is not |
| required for an |
| argument unit. |
| |
| @item ^-r^/TREE_FILE=REUSE^ |
| @cindex @option{^-r^/TREE_FILE=REUSE^} (@command{gnatstub}) |
| Reuse the tree file (if it exists) instead of creating it. Instead of |
| creating the tree file for the library unit declaration, @command{gnatstub} |
| tries to find it in the current directory and use it for creating |
| a body. If the tree file is not found, no body is created. This option |
| also implies @option{^-k^/SAVE^}, whether or not |
| the latter is set explicitly. |
| |
| @item ^-t^/TREE_FILE=OVERWRITE^ |
| @cindex @option{^-t^/TREE_FILE=OVERWRITE^} (@command{gnatstub}) |
| Overwrite the existing tree file. If the current directory already |
| contains the file which, according to the GNAT file naming rules should |
| be considered as a tree file for the argument source file, |
| @command{gnatstub} |
| will refuse to create the tree file needed to create a sample body |
| unless this option is set. |
| |
| @item ^-v^/VERBOSE^ |
| @cindex @option{^-v^/VERBOSE^} (@command{gnatstub}) |
| Verbose mode: generate version information. |
| |
| @end table |
| |
| @node Other Utility Programs |
| @chapter Other Utility Programs |
| |
| @noindent |
| This chapter discusses some other utility programs available in the Ada |
| environment. |
| |
| @menu |
| * Using Other Utility Programs with GNAT:: |
| * The External Symbol Naming Scheme of GNAT:: |
| @ifclear vms |
| * Ada Mode for Glide:: |
| @end ifclear |
| * Converting Ada Files to html with gnathtml:: |
| * Installing gnathtml:: |
| @ifset vms |
| * LSE:: |
| * Profiling:: |
| @end ifset |
| @end menu |
| |
| @node Using Other Utility Programs with GNAT |
| @section Using Other Utility Programs with GNAT |
| |
| @noindent |
| The object files generated by GNAT are in standard system format and in |
| particular the debugging information uses this format. This means |
| programs generated by GNAT can be used with existing utilities that |
| depend on these formats. |
| |
| @ifclear vms |
| In general, any utility program that works with C will also often work with |
| Ada programs generated by GNAT. This includes software utilities such as |
| gprof (a profiling program), @code{gdb} (the FSF debugger), and utilities such |
| as Purify. |
| @end ifclear |
| |
| @node The External Symbol Naming Scheme of GNAT |
| @section The External Symbol Naming Scheme of GNAT |
| |
| @noindent |
| In order to interpret the output from GNAT, when using tools that are |
| originally intended for use with other languages, it is useful to |
| understand the conventions used to generate link names from the Ada |
| entity names. |
| |
| All link names are in all lowercase letters. With the exception of library |
| procedure names, the mechanism used is simply to use the full expanded |
| Ada name with dots replaced by double underscores. For example, suppose |
| we have the following package spec: |
| |
| @smallexample @c ada |
| @group |
| @cartouche |
| package QRS is |
| MN : Integer; |
| end QRS; |
| @end cartouche |
| @end group |
| @end smallexample |
| |
| @noindent |
| The variable @code{MN} has a full expanded Ada name of @code{QRS.MN}, so |
| the corresponding link name is @code{qrs__mn}. |
| @findex Export |
| Of course if a @code{pragma Export} is used this may be overridden: |
| |
| @smallexample @c ada |
| @group |
| @cartouche |
| package Exports is |
| Var1 : Integer; |
| pragma Export (Var1, C, External_Name => "var1_name"); |
| Var2 : Integer; |
| pragma Export (Var2, C, Link_Name => "var2_link_name"); |
| end Exports; |
| @end cartouche |
| @end group |
| @end smallexample |
| |
| @noindent |
| In this case, the link name for @var{Var1} is whatever link name the |
| C compiler would assign for the C function @var{var1_name}. This typically |
| would be either @var{var1_name} or @var{_var1_name}, depending on operating |
| system conventions, but other possibilities exist. The link name for |
| @var{Var2} is @var{var2_link_name}, and this is not operating system |
| dependent. |
| |
| @findex _main |
| One exception occurs for library level procedures. A potential ambiguity |
| arises between the required name @code{_main} for the C main program, |
| and the name we would otherwise assign to an Ada library level procedure |
| called @code{Main} (which might well not be the main program). |
| |
| To avoid this ambiguity, we attach the prefix @code{_ada_} to such |
| names. So if we have a library level procedure such as |
| |
| @smallexample @c ada |
| @group |
| @cartouche |
| procedure Hello (S : String); |
| @end cartouche |
| @end group |
| @end smallexample |
| |
| @noindent |
| the external name of this procedure will be @var{_ada_hello}. |
| |
| @ifclear vms |
| @node Ada Mode for Glide |
| @section Ada Mode for @code{Glide} |
| @cindex Ada mode (for Glide) |
| |
| @noindent |
| The Glide mode for programming in Ada (both Ada83 and Ada95) helps the |
| user to understand and navigate existing code, and facilitates writing |
| new code. It furthermore provides some utility functions for easier |
| integration of standard Emacs features when programming in Ada. |
| |
| Its general features include: |
| |
| @itemize @bullet |
| @item |
| An Integrated Development Environment with functionality such as the |
| following |
| |
| @itemize @bullet |
| @item |
| ``Project files'' for configuration-specific aspects |
| (e.g. directories and compilation options) |
| |
| @item |
| Compiling and stepping through error messages. |
| |
| @item |
| Running and debugging an applications within Glide. |
| @end itemize |
| |
| @item |
| Pull-down menus |
| |
| @item |
| User configurability |
| @end itemize |
| |
| Some of the specific Ada mode features are: |
| |
| @itemize @bullet |
| @item |
| Functions for easy and quick stepping through Ada code |
| |
| @item |
| Getting cross reference information for identifiers (e.g., finding a |
| defining occurrence) |
| |
| @item |
| Displaying an index menu of types and subprograms, allowing |
| direct selection for browsing |
| |
| @item |
| Automatic color highlighting of the various Ada entities |
| @end itemize |
| |
| Glide directly supports writing Ada code, via several facilities: |
| |
| @itemize @bullet |
| @item |
| Switching between spec and body files with possible |
| autogeneration of body files |
| |
| @item |
| Automatic formating of subprogram parameter lists |
| |
| @item |
| Automatic indentation according to Ada syntax |
| |
| @item |
| Automatic completion of identifiers |
| |
| @item |
| Automatic (and configurable) casing of identifiers, keywords, and attributes |
| |
| @item |
| Insertion of syntactic templates |
| |
| @item |
| Block commenting / uncommenting |
| @end itemize |
| |
| @noindent |
| For more information, please refer to the online documentation |
| available in the @code{Glide} @result{} @code{Help} menu. |
| @end ifclear |
| |
| @node Converting Ada Files to html with gnathtml |
| @section Converting Ada Files to HTML with @code{gnathtml} |
| |
| @noindent |
| This @code{Perl} script allows Ada source files to be browsed using |
| standard Web browsers. For installation procedure, see the section |
| @xref{Installing gnathtml}. |
| |
| Ada reserved keywords are highlighted in a bold font and Ada comments in |
| a blue font. Unless your program was compiled with the gcc @option{-gnatx} |
| switch to suppress the generation of cross-referencing information, user |
| defined variables and types will appear in a different color; you will |
| be able to click on any identifier and go to its declaration. |
| |
| The command line is as follow: |
| @smallexample |
| $ perl gnathtml.pl [^switches^options^] ada-files |
| @end smallexample |
| |
| @noindent |
| You can pass it as many Ada files as you want. @code{gnathtml} will generate |
| an html file for every ada file, and a global file called @file{index.htm}. |
| This file is an index of every identifier defined in the files. |
| |
| The available ^switches^options^ are the following ones : |
| |
| @table @option |
| @item -83 |
| @cindex @option{-83} (@code{gnathtml}) |
| Only the subset on the Ada 83 keywords will be highlighted, not the full |
| Ada 95 keywords set. |
| |
| @item -cc @var{color} |
| @cindex @option{-cc} (@code{gnathtml}) |
| This option allows you to change the color used for comments. The default |
| value is green. The color argument can be any name accepted by html. |
| |
| @item -d |
| @cindex @option{-d} (@code{gnathtml}) |
| If the Ada files depend on some other files (for instance through |
| @code{with} clauses, the latter files will also be converted to html. |
| Only the files in the user project will be converted to html, not the files |
| in the run-time library itself. |
| |
| @item -D |
| @cindex @option{-D} (@code{gnathtml}) |
| This command is the same as @option{-d} above, but @command{gnathtml} will |
| also look for files in the run-time library, and generate html files for them. |
| |
| @item -ext @var{extension} |
| @cindex @option{-ext} (@code{gnathtml}) |
| This option allows you to change the extension of the generated HTML files. |
| If you do not specify an extension, it will default to @file{htm}. |
| |
| @item -f |
| @cindex @option{-f} (@code{gnathtml}) |
| By default, gnathtml will generate html links only for global entities |
| ('with'ed units, global variables and types,...). If you specify |
| @option{-f} on the command line, then links will be generated for local |
| entities too. |
| |
| @item -l @var{number} |
| @cindex @option{-l} (@code{gnathtml}) |
| If this ^switch^option^ is provided and @var{number} is not 0, then |
| @code{gnathtml} will number the html files every @var{number} line. |
| |
| @item -I @var{dir} |
| @cindex @option{-I} (@code{gnathtml}) |
| Specify a directory to search for library files (@file{.ALI} files) and |
| source files. You can provide several -I switches on the command line, |
| and the directories will be parsed in the order of the command line. |
| |
| @item -o @var{dir} |
| @cindex @option{-o} (@code{gnathtml}) |
| Specify the output directory for html files. By default, gnathtml will |
| saved the generated html files in a subdirectory named @file{html/}. |
| |
| @item -p @var{file} |
| @cindex @option{-p} (@code{gnathtml}) |
| If you are using Emacs and the most recent Emacs Ada mode, which provides |
| a full Integrated Development Environment for compiling, checking, |
| running and debugging applications, you may use @file{.gpr} files |
| to give the directories where Emacs can find sources and object files. |
| |
| Using this ^switch^option^, you can tell gnathtml to use these files. |
| This allows you to get an html version of your application, even if it |
| is spread over multiple directories. |
| |
| @item -sc @var{color} |
| @cindex @option{-sc} (@code{gnathtml}) |
| This ^switch^option^ allows you to change the color used for symbol |
| definitions. |
| The default value is red. The color argument can be any name accepted by html. |
| |
| @item -t @var{file} |
| @cindex @option{-t} (@code{gnathtml}) |
| This ^switch^option^ provides the name of a file. This file contains a list of |
| file names to be converted, and the effect is exactly as though they had |
| appeared explicitly on the command line. This |
| is the recommended way to work around the command line length limit on some |
| systems. |
| |
| @end table |
| |
| @node Installing gnathtml |
| @section Installing @code{gnathtml} |
| |
| @noindent |
| @code{Perl} needs to be installed on your machine to run this script. |
| @code{Perl} is freely available for almost every architecture and |
| Operating System via the Internet. |
| |
| On Unix systems, you may want to modify the first line of the script |
| @code{gnathtml}, to explicitly tell the Operating system where Perl |
| is. The syntax of this line is : |
| @smallexample |
| #!full_path_name_to_perl |
| @end smallexample |
| |
| @noindent |
| Alternatively, you may run the script using the following command line: |
| |
| @smallexample |
| $ perl gnathtml.pl [switches] files |
| @end smallexample |
| |
| @ifset vms |
| @node LSE |
| @section LSE |
| @findex LSE |
| |
| @noindent |
| The GNAT distribution provides an Ada 95 template for the HP Language |
| Sensitive Editor (LSE), a component of DECset. In order to |
| access it, invoke LSE with the qualifier /ENVIRONMENT=GNU:[LIB]ADA95.ENV. |
| |
| @node Profiling |
| @section Profiling |
| @findex PCA |
| |
| @noindent |
| GNAT supports The HP Performance Coverage Analyzer (PCA), a component |
| of DECset. To use it proceed as outlined under ``HELP PCA'', except for running |
| the collection phase with the /DEBUG qualifier. |
| |
| @smallexample |
| $ GNAT MAKE /DEBUG <PROGRAM_NAME> |
| $ DEFINE LIB$DEBUG PCA$COLLECTOR |
| $ RUN/DEBUG <PROGRAM_NAME> |
| @end smallexample |
| @noindent |
| @end ifset |
| |
| @node Running and Debugging Ada Programs |
| @chapter Running and Debugging Ada Programs |
| @cindex Debugging |
| |
| @noindent |
| This chapter discusses how to debug Ada programs. |
| @ifset vms |
| It applies to the Alpha OpenVMS platform; |
| the debugger for I64 OpenVMS is scheduled for a subsequent release. |
| @end ifset |
| |
| An incorrect Ada program may be handled in three ways by the GNAT compiler: |
| |
| @enumerate |
| @item |
| The illegality may be a violation of the static semantics of Ada. In |
| that case GNAT diagnoses the constructs in the program that are illegal. |
| It is then a straightforward matter for the user to modify those parts of |
| the program. |
| |
| @item |
| The illegality may be a violation of the dynamic semantics of Ada. In |
| that case the program compiles and executes, but may generate incorrect |
| results, or may terminate abnormally with some exception. |
| |
| @item |
| When presented with a program that contains convoluted errors, GNAT |
| itself may terminate abnormally without providing full diagnostics on |
| the incorrect user program. |
| @end enumerate |
| |
| @menu |
| * The GNAT Debugger GDB:: |
| * Running GDB:: |
| * Introduction to GDB Commands:: |
| * Using Ada Expressions:: |
| * Calling User-Defined Subprograms:: |
| * Using the Next Command in a Function:: |
| * Ada Exceptions:: |
| * Ada Tasks:: |
| * Debugging Generic Units:: |
| * GNAT Abnormal Termination or Failure to Terminate:: |
| * Naming Conventions for GNAT Source Files:: |
| * Getting Internal Debugging Information:: |
| * Stack Traceback:: |
| @end menu |
| |
| @cindex Debugger |
| @findex gdb |
| |
| @node The GNAT Debugger GDB |
| @section The GNAT Debugger GDB |
| |
| @noindent |
| @code{GDB} is a general purpose, platform-independent debugger that |
| can be used to debug mixed-language programs compiled with @command{gcc}, |
| and in particular is capable of debugging Ada programs compiled with |
| GNAT. The latest versions of @code{GDB} are Ada-aware and can handle |
| complex Ada data structures. |
| |
| The manual @cite{Debugging with GDB} |
| @ifset vms |
| , located in the GNU:[DOCS] directory, |
| @end ifset |
| contains full details on the usage of @code{GDB}, including a section on |
| its usage on programs. This manual should be consulted for full |
| details. The section that follows is a brief introduction to the |
| philosophy and use of @code{GDB}. |
| |
| When GNAT programs are compiled, the compiler optionally writes debugging |
| information into the generated object file, including information on |
| line numbers, and on declared types and variables. This information is |
| separate from the generated code. It makes the object files considerably |
| larger, but it does not add to the size of the actual executable that |
| will be loaded into memory, and has no impact on run-time performance. The |
| generation of debug information is triggered by the use of the |
| ^-g^/DEBUG^ switch in the gcc or gnatmake command used to carry out |
| the compilations. It is important to emphasize that the use of these |
| options does not change the generated code. |
| |
| The debugging information is written in standard system formats that |
| are used by many tools, including debuggers and profilers. The format |
| of the information is typically designed to describe C types and |
| semantics, but GNAT implements a translation scheme which allows full |
| details about Ada types and variables to be encoded into these |
| standard C formats. Details of this encoding scheme may be found in |
| the file exp_dbug.ads in the GNAT source distribution. However, the |
| details of this encoding are, in general, of no interest to a user, |
| since @code{GDB} automatically performs the necessary decoding. |
| |
| When a program is bound and linked, the debugging information is |
| collected from the object files, and stored in the executable image of |
| the program. Again, this process significantly increases the size of |
| the generated executable file, but it does not increase the size of |
| the executable program itself. Furthermore, if this program is run in |
| the normal manner, it runs exactly as if the debug information were |
| not present, and takes no more actual memory. |
| |
| However, if the program is run under control of @code{GDB}, the |
| debugger is activated. The image of the program is loaded, at which |
| point it is ready to run. If a run command is given, then the program |
| will run exactly as it would have if @code{GDB} were not present. This |
| is a crucial part of the @code{GDB} design philosophy. @code{GDB} is |
| entirely non-intrusive until a breakpoint is encountered. If no |
| breakpoint is ever hit, the program will run exactly as it would if no |
| debugger were present. When a breakpoint is hit, @code{GDB} accesses |
| the debugging information and can respond to user commands to inspect |
| variables, and more generally to report on the state of execution. |
| |
| @c ************** |
| @node Running GDB |
| @section Running GDB |
| |
| @noindent |
| The debugger can be launched directly and simply from @code{glide} or |
| through its graphical interface: @code{gvd}. It can also be used |
| directly in text mode. Here is described the basic use of @code{GDB} |
| in text mode. All the commands described below can be used in the |
| @code{gvd} console window even though there is usually other more |
| graphical ways to achieve the same goals. |
| |
| @ifclear vms |
| @noindent |
| The command to run the graphical interface of the debugger is |
| @smallexample |
| $ gvd program |
| @end smallexample |
| @end ifclear |
| |
| @noindent |
| The command to run @code{GDB} in text mode is |
| |
| @smallexample |
| $ ^gdb program^$ GDB PROGRAM^ |
| @end smallexample |
| |
| @noindent |
| where @code{^program^PROGRAM^} is the name of the executable file. This |
| activates the debugger and results in a prompt for debugger commands. |
| The simplest command is simply @code{run}, which causes the program to run |
| exactly as if the debugger were not present. The following section |
| describes some of the additional commands that can be given to @code{GDB}. |
| |
| @c ******************************* |
| @node Introduction to GDB Commands |
| @section Introduction to GDB Commands |
| |
| @noindent |
| @code{GDB} contains a large repertoire of commands. The manual |
| @cite{Debugging with GDB} |
| @ifset vms |
| , located in the GNU:[DOCS] directory, |
| @end ifset |
| includes extensive documentation on the use |
| of these commands, together with examples of their use. Furthermore, |
| the command @var{help} invoked from within @code{GDB} activates a simple help |
| facility which summarizes the available commands and their options. |
| In this section we summarize a few of the most commonly |
| used commands to give an idea of what @code{GDB} is about. You should create |
| a simple program with debugging information and experiment with the use of |
| these @code{GDB} commands on the program as you read through the |
| following section. |
| |
| @table @code |
| @item set args @var{arguments} |
| The @var{arguments} list above is a list of arguments to be passed to |
| the program on a subsequent run command, just as though the arguments |
| had been entered on a normal invocation of the program. The @code{set args} |
| command is not needed if the program does not require arguments. |
| |
| @item run |
| The @code{run} command causes execution of the program to start from |
| the beginning. If the program is already running, that is to say if |
| you are currently positioned at a breakpoint, then a prompt will ask |
| for confirmation that you want to abandon the current execution and |
| restart. |
| |
| @item breakpoint @var{location} |
| The breakpoint command sets a breakpoint, that is to say a point at which |
| execution will halt and @code{GDB} will await further |
| commands. @var{location} is |
| either a line number within a file, given in the format @code{file:linenumber}, |
| or it is the name of a subprogram. If you request that a breakpoint be set on |
| a subprogram that is overloaded, a prompt will ask you to specify on which of |
| those subprograms you want to breakpoint. You can also |
| specify that all of them should be breakpointed. If the program is run |
| and execution encounters the breakpoint, then the program |
| stops and @code{GDB} signals that the breakpoint was encountered by |
| printing the line of code before which the program is halted. |
| |
| @item breakpoint exception @var{name} |
| A special form of the breakpoint command which breakpoints whenever |
| exception @var{name} is raised. |
| If @var{name} is omitted, |
| then a breakpoint will occur when any exception is raised. |
| |
| @item print @var{expression} |
| This will print the value of the given expression. Most simple |
| Ada expression formats are properly handled by @code{GDB}, so the expression |
| can contain function calls, variables, operators, and attribute references. |
| |
| @item continue |
| Continues execution following a breakpoint, until the next breakpoint or the |
| termination of the program. |
| |
| @item step |
| Executes a single line after a breakpoint. If the next statement |
| is a subprogram call, execution continues into (the first statement of) |
| the called subprogram. |
| |
| @item next |
| Executes a single line. If this line is a subprogram call, executes and |
| returns from the call. |
| |
| @item list |
| Lists a few lines around the current source location. In practice, it |
| is usually more convenient to have a separate edit window open with the |
| relevant source file displayed. Successive applications of this command |
| print subsequent lines. The command can be given an argument which is a |
| line number, in which case it displays a few lines around the specified one. |
| |
| @item backtrace |
| Displays a backtrace of the call chain. This command is typically |
| used after a breakpoint has occurred, to examine the sequence of calls that |
| leads to the current breakpoint. The display includes one line for each |
| activation record (frame) corresponding to an active subprogram. |
| |
| @item up |
| At a breakpoint, @code{GDB} can display the values of variables local |
| to the current frame. The command @code{up} can be used to |
| examine the contents of other active frames, by moving the focus up |
| the stack, that is to say from callee to caller, one frame at a time. |
| |
| @item down |
| Moves the focus of @code{GDB} down from the frame currently being |
| examined to the frame of its callee (the reverse of the previous command), |
| |
| @item frame @var{n} |
| Inspect the frame with the given number. The value 0 denotes the frame |
| of the current breakpoint, that is to say the top of the call stack. |
| |
| @end table |
| |
| The above list is a very short introduction to the commands that |
| @code{GDB} provides. Important additional capabilities, including conditional |
| breakpoints, the ability to execute command sequences on a breakpoint, |
| the ability to debug at the machine instruction level and many other |
| features are described in detail in @cite{Debugging with GDB}. |
| Note that most commands can be abbreviated |
| (for example, c for continue, bt for backtrace). |
| |
| @node Using Ada Expressions |
| @section Using Ada Expressions |
| @cindex Ada expressions |
| |
| @noindent |
| @code{GDB} supports a fairly large subset of Ada expression syntax, with some |
| extensions. The philosophy behind the design of this subset is |
| |
| @itemize @bullet |
| @item |
| That @code{GDB} should provide basic literals and access to operations for |
| arithmetic, dereferencing, field selection, indexing, and subprogram calls, |
| leaving more sophisticated computations to subprograms written into the |
| program (which therefore may be called from @code{GDB}). |
| |
| @item |
| That type safety and strict adherence to Ada language restrictions |
| are not particularly important to the @code{GDB} user. |
| |
| @item |
| That brevity is important to the @code{GDB} user. |
| @end itemize |
| |
| Thus, for brevity, the debugger acts as if there were |
| implicit @code{with} and @code{use} clauses in effect for all user-written |
| packages, thus making it unnecessary to fully qualify most names with |
| their packages, regardless of context. Where this causes ambiguity, |
| @code{GDB} asks the user's intent. |
| |
| For details on the supported Ada syntax, see @cite{Debugging with GDB}. |
| |
| @node Calling User-Defined Subprograms |
| @section Calling User-Defined Subprograms |
| |
| @noindent |
| An important capability of @code{GDB} is the ability to call user-defined |
| subprograms while debugging. This is achieved simply by entering |
| a subprogram call statement in the form: |
| |
| @smallexample |
| call subprogram-name (parameters) |
| @end smallexample |
| |
| @noindent |
| The keyword @code{call} can be omitted in the normal case where the |
| @code{subprogram-name} does not coincide with any of the predefined |
| @code{GDB} commands. |
| |
| The effect is to invoke the given subprogram, passing it the |
| list of parameters that is supplied. The parameters can be expressions and |
| can include variables from the program being debugged. The |
| subprogram must be defined |
| at the library level within your program, and @code{GDB} will call the |
| subprogram within the environment of your program execution (which |
| means that the subprogram is free to access or even modify variables |
| within your program). |
| |
| The most important use of this facility is in allowing the inclusion of |
| debugging routines that are tailored to particular data structures |
| in your program. Such debugging routines can be written to provide a suitably |
| high-level description of an abstract type, rather than a low-level dump |
| of its physical layout. After all, the standard |
| @code{GDB print} command only knows the physical layout of your |
| types, not their abstract meaning. Debugging routines can provide information |
| at the desired semantic level and are thus enormously useful. |
| |
| For example, when debugging GNAT itself, it is crucial to have access to |
| the contents of the tree nodes used to represent the program internally. |
| But tree nodes are represented simply by an integer value (which in turn |
| is an index into a table of nodes). |
| Using the @code{print} command on a tree node would simply print this integer |
| value, which is not very useful. But the PN routine (defined in file |
| treepr.adb in the GNAT sources) takes a tree node as input, and displays |
| a useful high level representation of the tree node, which includes the |
| syntactic category of the node, its position in the source, the integers |
| that denote descendant nodes and parent node, as well as varied |
| semantic information. To study this example in more detail, you might want to |
| look at the body of the PN procedure in the stated file. |
| |
| @node Using the Next Command in a Function |
| @section Using the Next Command in a Function |
| |
| @noindent |
| When you use the @code{next} command in a function, the current source |
| location will advance to the next statement as usual. A special case |
| arises in the case of a @code{return} statement. |
| |
| Part of the code for a return statement is the ``epilog'' of the function. |
| This is the code that returns to the caller. There is only one copy of |
| this epilog code, and it is typically associated with the last return |
| statement in the function if there is more than one return. In some |
| implementations, this epilog is associated with the first statement |
| of the function. |
| |
| The result is that if you use the @code{next} command from a return |
| statement that is not the last return statement of the function you |
| may see a strange apparent jump to the last return statement or to |
| the start of the function. You should simply ignore this odd jump. |
| The value returned is always that from the first return statement |
| that was stepped through. |
| |
| @node Ada Exceptions |
| @section Breaking on Ada Exceptions |
| @cindex Exceptions |
| |
| @noindent |
| You can set breakpoints that trip when your program raises |
| selected exceptions. |
| |
| @table @code |
| @item break exception |
| Set a breakpoint that trips whenever (any task in the) program raises |
| any exception. |
| |
| @item break exception @var{name} |
| Set a breakpoint that trips whenever (any task in the) program raises |
| the exception @var{name}. |
| |
| @item break exception unhandled |
| Set a breakpoint that trips whenever (any task in the) program raises an |
| exception for which there is no handler. |
| |
| @item info exceptions |
| @itemx info exceptions @var{regexp} |
| The @code{info exceptions} command permits the user to examine all defined |
| exceptions within Ada programs. With a regular expression, @var{regexp}, as |
| argument, prints out only those exceptions whose name matches @var{regexp}. |
| @end table |
| |
| @node Ada Tasks |
| @section Ada Tasks |
| @cindex Tasks |
| |
| @noindent |
| @code{GDB} allows the following task-related commands: |
| |
| @table @code |
| @item info tasks |
| This command shows a list of current Ada tasks, as in the following example: |
| |
| @smallexample |
| @iftex |
| @leftskip=0cm |
| @end iftex |
| (gdb) info tasks |
| ID TID P-ID Thread Pri State Name |
| 1 8088000 0 807e000 15 Child Activation Wait main_task |
| 2 80a4000 1 80ae000 15 Accept/Select Wait b |
| 3 809a800 1 80a4800 15 Child Activation Wait a |
| * 4 80ae800 3 80b8000 15 Running c |
| @end smallexample |
| |
| @noindent |
| In this listing, the asterisk before the first task indicates it to be the |
| currently running task. The first column lists the task ID that is used |
| to refer to tasks in the following commands. |
| |
| @item break @var{linespec} task @var{taskid} |
| @itemx break @var{linespec} task @var{taskid} if @dots{} |
| @cindex Breakpoints and tasks |
| These commands are like the @code{break @dots{} thread @dots{}}. |
| @var{linespec} specifies source lines. |
| |
| Use the qualifier @samp{task @var{taskid}} with a breakpoint command |
| to specify that you only want @code{GDB} to stop the program when a |
| particular Ada task reaches this breakpoint. @var{taskid} is one of the |
| numeric task identifiers assigned by @code{GDB}, shown in the first |
| column of the @samp{info tasks} display. |
| |
| If you do not specify @samp{task @var{taskid}} when you set a |
| breakpoint, the breakpoint applies to @emph{all} tasks of your |
| program. |
| |
| You can use the @code{task} qualifier on conditional breakpoints as |
| well; in this case, place @samp{task @var{taskid}} before the |
| breakpoint condition (before the @code{if}). |
| |
| @item task @var{taskno} |
| @cindex Task switching |
| |
| This command allows to switch to the task referred by @var{taskno}. In |
| particular, This allows to browse the backtrace of the specified |
| task. It is advised to switch back to the original task before |
| continuing execution otherwise the scheduling of the program may be |
| perturbed. |
| @end table |
| |
| @noindent |
| For more detailed information on the tasking support, |
| see @cite{Debugging with GDB}. |
| |
| @node Debugging Generic Units |
| @section Debugging Generic Units |
| @cindex Debugging Generic Units |
| @cindex Generics |
| |
| @noindent |
| GNAT always uses code expansion for generic instantiation. This means that |
| each time an instantiation occurs, a complete copy of the original code is |
| made, with appropriate substitutions of formals by actuals. |
| |
| It is not possible to refer to the original generic entities in |
| @code{GDB}, but it is always possible to debug a particular instance of |
| a generic, by using the appropriate expanded names. For example, if we have |
| |
| @smallexample @c ada |
| @group |
| @cartouche |
| procedure g is |
| |
| generic package k is |
| procedure kp (v1 : in out integer); |
| end k; |
| |
| package body k is |
| procedure kp (v1 : in out integer) is |
| begin |
| v1 := v1 + 1; |
| end kp; |
| end k; |
| |
| package k1 is new k; |
| package k2 is new k; |
| |
| var : integer := 1; |
| |
| begin |
| k1.kp (var); |
| k2.kp (var); |
| k1.kp (var); |
| k2.kp (var); |
| end; |
| @end cartouche |
| @end group |
| @end smallexample |
| |
| @noindent |
| Then to break on a call to procedure kp in the k2 instance, simply |
| use the command: |
| |
| @smallexample |
| (gdb) break g.k2.kp |
| @end smallexample |
| |
| @noindent |
| When the breakpoint occurs, you can step through the code of the |
| instance in the normal manner and examine the values of local variables, as for |
| other units. |
| |
| @node GNAT Abnormal Termination or Failure to Terminate |
| @section GNAT Abnormal Termination or Failure to Terminate |
| @cindex GNAT Abnormal Termination or Failure to Terminate |
| |
| @noindent |
| When presented with programs that contain serious errors in syntax |
| or semantics, |
| GNAT may on rare occasions experience problems in operation, such |
| as aborting with a |
| segmentation fault or illegal memory access, raising an internal |
| exception, terminating abnormally, or failing to terminate at all. |
| In such cases, you can activate |
| various features of GNAT that can help you pinpoint the construct in your |
| program that is the likely source of the problem. |
| |
| The following strategies are presented in increasing order of |
| difficulty, corresponding to your experience in using GNAT and your |
| familiarity with compiler internals. |
| |
| @enumerate |
| @item |
| Run @command{gcc} with the @option{-gnatf}. This first |
| switch causes all errors on a given line to be reported. In its absence, |
| only the first error on a line is displayed. |
| |
| The @option{-gnatdO} switch causes errors to be displayed as soon as they |
| are encountered, rather than after compilation is terminated. If GNAT |
| terminates prematurely or goes into an infinite loop, the last error |
| message displayed may help to pinpoint the culprit. |
| |
| @item |
| Run @command{gcc} with the @option{^-v (verbose)^/VERBOSE^} switch. In this |
| mode, @command{gcc} produces ongoing information about the progress of the |
| compilation and provides the name of each procedure as code is |
| generated. This switch allows you to find which Ada procedure was being |
| compiled when it encountered a code generation problem. |
| |
| @item |
| @cindex @option{-gnatdc} switch |
| Run @command{gcc} with the @option{-gnatdc} switch. This is a GNAT specific |
| switch that does for the front-end what @option{^-v^VERBOSE^} does |
| for the back end. The system prints the name of each unit, |
| either a compilation unit or nested unit, as it is being analyzed. |
| @item |
| Finally, you can start |
| @code{gdb} directly on the @code{gnat1} executable. @code{gnat1} is the |
| front-end of GNAT, and can be run independently (normally it is just |
| called from @command{gcc}). You can use @code{gdb} on @code{gnat1} as you |
| would on a C program (but @pxref{The GNAT Debugger GDB} for caveats). The |
| @code{where} command is the first line of attack; the variable |
| @code{lineno} (seen by @code{print lineno}), used by the second phase of |
| @code{gnat1} and by the @command{gcc} backend, indicates the source line at |
| which the execution stopped, and @code{input_file name} indicates the name of |
| the source file. |
| @end enumerate |
| |
| @node Naming Conventions for GNAT Source Files |
| @section Naming Conventions for GNAT Source Files |
| |
| @noindent |
| In order to examine the workings of the GNAT system, the following |
| brief description of its organization may be helpful: |
| |
| @itemize @bullet |
| @item |
| Files with prefix @file{^sc^SC^} contain the lexical scanner. |
| |
| @item |
| All files prefixed with @file{^par^PAR^} are components of the parser. The |
| numbers correspond to chapters of the Ada 95 Reference Manual. For example, |
| parsing of select statements can be found in @file{par-ch9.adb}. |
| |
| @item |
| All files prefixed with @file{^sem^SEM^} perform semantic analysis. The |
| numbers correspond to chapters of the Ada standard. For example, all |
| issues involving context clauses can be found in @file{sem_ch10.adb}. In |
| addition, some features of the language require sufficient special processing |
| to justify their own semantic files: sem_aggr for aggregates, sem_disp for |
| dynamic dispatching, etc. |
| |
| @item |
| All files prefixed with @file{^exp^EXP^} perform normalization and |
| expansion of the intermediate representation (abstract syntax tree, or AST). |
| these files use the same numbering scheme as the parser and semantics files. |
| For example, the construction of record initialization procedures is done in |
| @file{exp_ch3.adb}. |
| |
| @item |
| The files prefixed with @file{^bind^BIND^} implement the binder, which |
| verifies the consistency of the compilation, determines an order of |
| elaboration, and generates the bind file. |
| |
| @item |
| The files @file{atree.ads} and @file{atree.adb} detail the low-level |
| data structures used by the front-end. |
| |
| @item |
| The files @file{sinfo.ads} and @file{sinfo.adb} detail the structure of |
| the abstract syntax tree as produced by the parser. |
| |
| @item |
| The files @file{einfo.ads} and @file{einfo.adb} detail the attributes of |
| all entities, computed during semantic analysis. |
| |
| @item |
| Library management issues are dealt with in files with prefix |
| @file{^lib^LIB^}. |
| |
| @item |
| @findex Ada |
| @cindex Annex A |
| Ada files with the prefix @file{^a-^A-^} are children of @code{Ada}, as |
| defined in Annex A. |
| |
| @item |
| @findex Interfaces |
| @cindex Annex B |
| Files with prefix @file{^i-^I-^} are children of @code{Interfaces}, as |
| defined in Annex B. |
| |
| @item |
| @findex System |
| Files with prefix @file{^s-^S-^} are children of @code{System}. This includes |
| both language-defined children and GNAT run-time routines. |
| |
| @item |
| @findex GNAT |
| Files with prefix @file{^g-^G-^} are children of @code{GNAT}. These are useful |
| general-purpose packages, fully documented in their specifications. All |
| the other @file{.c} files are modifications of common @command{gcc} files. |
| @end itemize |
| |
| @node Getting Internal Debugging Information |
| @section Getting Internal Debugging Information |
| |
| @noindent |
| Most compilers have internal debugging switches and modes. GNAT |
| does also, except GNAT internal debugging switches and modes are not |
| secret. A summary and full description of all the compiler and binder |
| debug flags are in the file @file{debug.adb}. You must obtain the |
| sources of the compiler to see the full detailed effects of these flags. |
| |
| The switches that print the source of the program (reconstructed from |
| the internal tree) are of general interest for user programs, as are the |
| options to print |
| the full internal tree, and the entity table (the symbol table |
| information). The reconstructed source provides a readable version of the |
| program after the front-end has completed analysis and expansion, |
| and is useful when studying the performance of specific constructs. |
| For example, constraint checks are indicated, complex aggregates |
| are replaced with loops and assignments, and tasking primitives |
| are replaced with run-time calls. |
| |
| @node Stack Traceback |
| @section Stack Traceback |
| @cindex traceback |
| @cindex stack traceback |
| @cindex stack unwinding |
| |
| @noindent |
| Traceback is a mechanism to display the sequence of subprogram calls that |
| leads to a specified execution point in a program. Often (but not always) |
| the execution point is an instruction at which an exception has been raised. |
| This mechanism is also known as @i{stack unwinding} because it obtains |
| its information by scanning the run-time stack and recovering the activation |
| records of all active subprograms. Stack unwinding is one of the most |
| important tools for program debugging. |
| |
| The first entry stored in traceback corresponds to the deepest calling level, |
| that is to say the subprogram currently executing the instruction |
| from which we want to obtain the traceback. |
| |
| Note that there is no runtime performance penalty when stack traceback |
| is enabled, and no exception is raised during program execution. |
| |
| @menu |
| * Non-Symbolic Traceback:: |
| * Symbolic Traceback:: |
| @end menu |
| |
| @node Non-Symbolic Traceback |
| @subsection Non-Symbolic Traceback |
| @cindex traceback, non-symbolic |
| |
| @noindent |
| Note: this feature is not supported on all platforms. See |
| @file{GNAT.Traceback spec in g-traceb.ads} for a complete list of supported |
| platforms. |
| |
| @menu |
| * Tracebacks From an Unhandled Exception:: |
| * Tracebacks From Exception Occurrences (non-symbolic):: |
| * Tracebacks From Anywhere in a Program (non-symbolic):: |
| @end menu |
| |
| @node Tracebacks From an Unhandled Exception |
| @subsubsection Tracebacks From an Unhandled Exception |
| |
| @noindent |
| A runtime non-symbolic traceback is a list of addresses of call instructions. |
| To enable this feature you must use the @option{-E} |
| @code{gnatbind}'s option. With this option a stack traceback is stored as part |
| of exception information. You can retrieve this information using the |
| @code{addr2line} tool. |
| |
| Here is a simple example: |
| |
| @smallexample @c ada |
| @cartouche |
| procedure STB is |
| |
| procedure P1 is |
| begin |
| raise Constraint_Error; |
| end P1; |
| |
| procedure P2 is |
| begin |
| P1; |
| end P2; |
| |
| begin |
| P2; |
| end STB; |
| @end cartouche |
| @end smallexample |
| |
| @smallexample |
| $ gnatmake stb -bargs -E |
| $ stb |
| |
| Execution terminated by unhandled exception |
| Exception name: CONSTRAINT_ERROR |
| Message: stb.adb:5 |
| Call stack traceback locations: |
| 0x401373 0x40138b 0x40139c 0x401335 0x4011c4 0x4011f1 0x77e892a4 |
| @end smallexample |
| |
| @noindent |
| As we see the traceback lists a sequence of addresses for the unhandled |
| exception @code{CONSTRAINT_ERROR} raised in procedure P1. It is easy to |
| guess that this exception come from procedure P1. To translate these |
| addresses into the source lines where the calls appear, the |
| @code{addr2line} tool, described below, is invaluable. The use of this tool |
| requires the program to be compiled with debug information. |
| |
| @smallexample |
| $ gnatmake -g stb -bargs -E |
| $ stb |
| |
| Execution terminated by unhandled exception |
| Exception name: CONSTRAINT_ERROR |
| Message: stb.adb:5 |
| Call stack traceback locations: |
| 0x401373 0x40138b 0x40139c 0x401335 0x4011c4 0x4011f1 0x77e892a4 |
| |
| $ addr2line --exe=stb 0x401373 0x40138b 0x40139c 0x401335 0x4011c4 |
| 0x4011f1 0x77e892a4 |
| |
| 00401373 at d:/stb/stb.adb:5 |
| 0040138B at d:/stb/stb.adb:10 |
| 0040139C at d:/stb/stb.adb:14 |
| 00401335 at d:/stb/b~stb.adb:104 |
| 004011C4 at /build/.../crt1.c:200 |
| 004011F1 at /build/.../crt1.c:222 |
| 77E892A4 in ?? at ??:0 |
| @end smallexample |
| |
| @noindent |
| The @code{addr2line} tool has several other useful options: |
| |
| @table @code |
| @item --functions |
| to get the function name corresponding to any location |
| |
| @item --demangle=gnat |
| to use the gnat decoding mode for the function names. Note that |
| for binutils version 2.9.x the option is simply @option{--demangle}. |
| @end table |
| |
| @smallexample |
| $ addr2line --exe=stb --functions --demangle=gnat 0x401373 0x40138b |
| 0x40139c 0x401335 0x4011c4 0x4011f1 |
| |
| 00401373 in stb.p1 at d:/stb/stb.adb:5 |
| 0040138B in stb.p2 at d:/stb/stb.adb:10 |
| 0040139C in stb at d:/stb/stb.adb:14 |
| 00401335 in main at d:/stb/b~stb.adb:104 |
| 004011C4 in <__mingw_CRTStartup> at /build/.../crt1.c:200 |
| 004011F1 in <mainCRTStartup> at /build/.../crt1.c:222 |
| @end smallexample |
| |
| @noindent |
| From this traceback we can see that the exception was raised in |
| @file{stb.adb} at line 5, which was reached from a procedure call in |
| @file{stb.adb} at line 10, and so on. The @file{b~std.adb} is the binder file, |
| which contains the call to the main program. |
| @xref{Running gnatbind}. The remaining entries are assorted runtime routines, |
| and the output will vary from platform to platform. |
| |
| It is also possible to use @code{GDB} with these traceback addresses to debug |
| the program. For example, we can break at a given code location, as reported |
| in the stack traceback: |
| |
| @smallexample |
| $ gdb -nw stb |
| @ifclear vms |
| @noindent |
| Furthermore, this feature is not implemented inside Windows DLL. Only |
| the non-symbolic traceback is reported in this case. |
| @end ifclear |
| |
| (gdb) break *0x401373 |
| Breakpoint 1 at 0x401373: file stb.adb, line 5. |
| @end smallexample |
| |
| @noindent |
| It is important to note that the stack traceback addresses |
| do not change when debug information is included. This is particularly useful |
| because it makes it possible to release software without debug information (to |
| minimize object size), get a field report that includes a stack traceback |
| whenever an internal bug occurs, and then be able to retrieve the sequence |
| of calls with the same program compiled with debug information. |
| |
| @node Tracebacks From Exception Occurrences (non-symbolic) |
| @subsubsection Tracebacks From Exception Occurrences |
| |
| @noindent |
| Non-symbolic tracebacks are obtained by using the @option{-E} binder argument. |
| The stack traceback is attached to the exception information string, and can |
| be retrieved in an exception handler within the Ada program, by means of the |
| Ada95 facilities defined in @code{Ada.Exceptions}. Here is a simple example: |
| |
| @smallexample @c ada |
| with Ada.Text_IO; |
| with Ada.Exceptions; |
| |
| procedure STB is |
| |
| use Ada; |
| use Ada.Exceptions; |
| |
| procedure P1 is |
| K : Positive := 1; |
| begin |
| K := K - 1; |
| exception |
| when E : others => |
| Text_IO.Put_Line (Exception_Information (E)); |
| end P1; |
| |
| procedure P2 is |
| begin |
| P1; |
| end P2; |
| |
| begin |
| P2; |
| end STB; |
| @end smallexample |
| |
| @noindent |
| This program will output: |
| |
| @smallexample |
| $ stb |
| |
| Exception name: CONSTRAINT_ERROR |
| Message: stb.adb:12 |
| Call stack traceback locations: |
| 0x4015e4 0x401633 0x401644 0x401461 0x4011c4 0x4011f1 0x77e892a4 |
| @end smallexample |
| |
| @node Tracebacks From Anywhere in a Program (non-symbolic) |
| @subsubsection Tracebacks From Anywhere in a Program |
| |
| @noindent |
| It is also possible to retrieve a stack traceback from anywhere in a |
| program. For this you need to |
| use the @code{GNAT.Traceback} API. This package includes a procedure called |
| @code{Call_Chain} that computes a complete stack traceback, as well as useful |
| display procedures described below. It is not necessary to use the |
| @option{-E gnatbind} option in this case, because the stack traceback mechanism |
| is invoked explicitly. |
| |
| @noindent |
| In the following example we compute a traceback at a specific location in |
| the program, and we display it using @code{GNAT.Debug_Utilities.Image} to |
| convert addresses to strings: |
| |
| @smallexample @c ada |
| with Ada.Text_IO; |
| with GNAT.Traceback; |
| with GNAT.Debug_Utilities; |
| |
| procedure STB is |
| |
| use Ada; |
| use GNAT; |
| use GNAT.Traceback; |
| |
| procedure P1 is |
| TB : Tracebacks_Array (1 .. 10); |
| -- We are asking for a maximum of 10 stack frames. |
| Len : Natural; |
| -- Len will receive the actual number of stack frames returned. |
| begin |
| Call_Chain (TB, Len); |
| |
| Text_IO.Put ("In STB.P1 : "); |
| |
| for K in 1 .. Len loop |
| Text_IO.Put (Debug_Utilities.Image (TB (K))); |
| Text_IO.Put (' '); |
| end loop; |
| |
| Text_IO.New_Line; |
| end P1; |
| |
| procedure P2 is |
| begin |
| P1; |
| end P2; |
| |
| begin |
| P2; |
| end STB; |
| @end smallexample |
| |
| @smallexample |
| $ gnatmake -g stb |
| $ stb |
| |
| In STB.P1 : 16#0040_F1E4# 16#0040_14F2# 16#0040_170B# 16#0040_171C# |
| 16#0040_1461# 16#0040_11C4# 16#0040_11F1# 16#77E8_92A4# |
| @end smallexample |
| |
| @noindent |
| You can then get further information by invoking the @code{addr2line} |
| tool as described earlier (note that the hexadecimal addresses |
| need to be specified in C format, with a leading ``0x''). |
| |
| @node Symbolic Traceback |
| @subsection Symbolic Traceback |
| @cindex traceback, symbolic |
| |
| @noindent |
| A symbolic traceback is a stack traceback in which procedure names are |
| associated with each code location. |
| |
| @noindent |
| Note that this feature is not supported on all platforms. See |
| @file{GNAT.Traceback.Symbolic spec in g-trasym.ads} for a complete |
| list of currently supported platforms. |
| |
| @noindent |
| Note that the symbolic traceback requires that the program be compiled |
| with debug information. If it is not compiled with debug information |
| only the non-symbolic information will be valid. |
| |
| @menu |
| * Tracebacks From Exception Occurrences (symbolic):: |
| * Tracebacks From Anywhere in a Program (symbolic):: |
| @end menu |
| |
| @node Tracebacks From Exception Occurrences (symbolic) |
| @subsubsection Tracebacks From Exception Occurrences |
| |
| @smallexample @c ada |
| with Ada.Text_IO; |
| with GNAT.Traceback.Symbolic; |
| |
| procedure STB is |
| |
| procedure P1 is |
| begin |
| raise Constraint_Error; |
| end P1; |
| |
| procedure P2 is |
| begin |
| P1; |
| end P2; |
| |
| procedure P3 is |
| begin |
| P2; |
| end P3; |
| |
| begin |
| P3; |
| exception |
| when E : others => |
| Ada.Text_IO.Put_Line (GNAT.Traceback.Symbolic.Symbolic_Traceback (E)); |
| end STB; |
| @end smallexample |
| |
| @smallexample |
| $ gnatmake -g .\stb -bargs -E -largs -lgnat -laddr2line -lintl |
| $ stb |
| |
| 0040149F in stb.p1 at stb.adb:8 |
| 004014B7 in stb.p2 at stb.adb:13 |
| 004014CF in stb.p3 at stb.adb:18 |
| 004015DD in ada.stb at stb.adb:22 |
| 00401461 in main at b~stb.adb:168 |
| 004011C4 in __mingw_CRTStartup at crt1.c:200 |
| 004011F1 in mainCRTStartup at crt1.c:222 |
| 77E892A4 in ?? at ??:0 |
| @end smallexample |
| |
| @noindent |
| In the above example the ``.\'' syntax in the @command{gnatmake} command |
| is currently required by @command{addr2line} for files that are in |
| the current working directory. |
| Moreover, the exact sequence of linker options may vary from platform |
| to platform. |
| The above @option{-largs} section is for Windows platforms. By contrast, |
| under Unix there is no need for the @option{-largs} section. |
| Differences across platforms are due to details of linker implementation. |
| |
| @node Tracebacks From Anywhere in a Program (symbolic) |
| @subsubsection Tracebacks From Anywhere in a Program |
| |
| @noindent |
| It is possible to get a symbolic stack traceback |
| from anywhere in a program, just as for non-symbolic tracebacks. |
| The first step is to obtain a non-symbolic |
| traceback, and then call @code{Symbolic_Traceback} to compute the symbolic |
| information. Here is an example: |
| |
| @smallexample @c ada |
| with Ada.Text_IO; |
| with GNAT.Traceback; |
| with GNAT.Traceback.Symbolic; |
| |
| procedure STB is |
| |
| use Ada; |
| use GNAT.Traceback; |
| use GNAT.Traceback.Symbolic; |
| |
| procedure P1 is |
| TB : Tracebacks_Array (1 .. 10); |
| -- We are asking for a maximum of 10 stack frames. |
| Len : Natural; |
| -- Len will receive the actual number of stack frames returned. |
| begin |
| Call_Chain (TB, Len); |
| Text_IO.Put_Line (Symbolic_Traceback (TB (1 .. Len))); |
| end P1; |
| |
| procedure P2 is |
| begin |
| P1; |
| end P2; |
| |
| begin |
| P2; |
| end STB; |
| @end smallexample |
| |
| |
| @c ****************************** |
| @ifset vms |
| @node Compatibility with HP Ada |
| @chapter Compatibility with HP Ada |
| @cindex Compatibility |
| |
| @noindent |
| @cindex DEC Ada |
| @cindex HP Ada |
| @cindex Compatibility between GNAT and HP Ada |
| This chapter compares HP Ada (formerly known as ``DEC Ada'') |
| for OpenVMS Alpha and GNAT for OpenVMS for Alpha and for I64. |
| GNAT is highly compatible |
| with HP Ada, and it should generally be straightforward to port code |
| from the HP Ada environment to GNAT. However, there are a few language |
| and implementation differences of which the user must be aware. These |
| differences are discussed in this chapter. In |
| addition, the operating environment and command structure for the |
| compiler are different, and these differences are also discussed. |
| |
| For further details on these and other compatibility issues, |
| see Appendix E of the HP publication |
| @cite{HP Ada, Technical Overview and Comparison on HP Platforms}. |
| |
| Except where otherwise indicated, the description of GNAT for OpenVMS |
| applies to both the Alpha and I64 platforms. |
| |
| For information on porting Ada code from GNAT on Alpha OpenVMS to GNAT on |
| I64 OpenVMS, see @ref{Transitioning from Alpha to I64 OpenVMS}. |
| |
| The discussion in this chapter addresses specifically the implementation |
| of Ada 83 for HP OpenVMS Alpha Systems. In cases where the implementation |
| of HP Ada differs between OpenVMS Alpha Systems and OpenVMS VAX Systems, |
| GNAT always follows the Alpha implementation. |
| |
| For GNAT running on other than VMS systems, all the HP Ada 83 pragmas and |
| attributes are recognized, although only a subset of them can sensibly |
| be implemented. The description of pragmas in the |
| @cite{GNAT Reference Manual} indicates whether or not they are applicable |
| to non-VMS systems. |
| |
| |
| @menu |
| * Ada 95 Compatibility:: |
| * Differences in the Definition of Package System:: |
| * Language-Related Features:: |
| * The Package STANDARD:: |
| * The Package SYSTEM:: |
| * Tasking and Task-Related Features:: |
| * Pragmas and Pragma-Related Features:: |
| * Library of Predefined Units:: |
| * Bindings:: |
| * Main Program Definition:: |
| * Implementation-Defined Attributes:: |
| * Compiler and Run-Time Interfacing:: |
| * Program Compilation and Library Management:: |
| * Input-Output:: |
| * Implementation Limits:: |
| * Tools and Utilities:: |
| @end menu |
| |
| @node Ada 95 Compatibility |
| @section Ada 95 Compatibility |
| |
| @noindent |
| GNAT is an Ada 95 compiler, and HP Ada is an Ada 83 |
| compiler. Ada 95 is almost completely upwards compatible |
| with Ada 83, and therefore Ada 83 programs will compile |
| and run under GNAT with |
| no changes or only minor changes. The Ada 95 Reference |
| Manual provides details on specific incompatibilities. |
| |
| GNAT provides the switch @option{/83} on the @command{GNAT COMPILE} command, |
| as well as the pragma @code{ADA_83}, to force the compiler to |
| operate in Ada 83 mode. This mode does not guarantee complete |
| conformance to Ada 83, but in practice is sufficient to |
| eliminate most sources of incompatibilities. |
| In particular, it eliminates the recognition of the |
| additional Ada 95 keywords, so that their use as identifiers |
| in Ada 83 programs is legal, and handles the cases of packages |
| with optional bodies, and generics that instantiate unconstrained |
| types without the use of @code{(<>)}. |
| |
| @node Differences in the Definition of Package System |
| @section Differences in the Definition of Package @code{System} |
| |
| @noindent |
| Both Ada 95 and Ada 83 permit a compiler to add |
| implementation-dependent declarations to package @code{System}. |
| In normal mode, |
| GNAT does not take advantage of this permission, and the version of |
| @code{System} provided by GNAT exactly matches that in Ada 95. |
| |
| However, HP Ada adds an extensive set of declarations to package |
| @code{System}, |
| as fully documented in the HP Ada manuals. To minimize changes required |
| for programs that make use of these extensions, GNAT provides the pragma |
| @code{Extend_System} for extending the definition of package System. By using: |
| @cindex pragma @code{Extend_System} |
| @cindex @code{Extend_System} pragma |
| |
| @smallexample @c ada |
| @group |
| @cartouche |
| pragma Extend_System (Aux_DEC); |
| @end cartouche |
| @end group |
| @end smallexample |
| |
| @noindent |
| the set of definitions in @code{System} is extended to include those in |
| package @code{System.Aux_DEC}. |
| @cindex @code{System.Aux_DEC} package |
| @cindex @code{Aux_DEC} package (child of @code{System}) |
| These definitions are incorporated directly into package @code{System}, |
| as though they had been declared there. For a |
| list of the declarations added, see the specification of this package, |
| which can be found in the file @file{s-auxdec.ads} in the GNAT library. |
| @cindex @file{s-auxdec.ads} file |
| The pragma @code{Extend_System} is a configuration pragma, which means that |
| it can be placed in the file @file{gnat.adc}, so that it will automatically |
| apply to all subsequent compilations. See @ref{Configuration Pragmas}, |
| for further details. |
| |
| An alternative approach that avoids the use of the non-standard |
| @code{Extend_System} pragma is to add a context clause to the unit that |
| references these facilities: |
| |
| @smallexample @c ada |
| @cartouche |
| with System.Aux_DEC; |
| use System.Aux_DEC; |
| @end cartouche |
| @end smallexample |
| |
| @noindent |
| The effect is not quite semantically identical to incorporating |
| the declarations directly into package @code{System}, |
| but most programs will not notice a difference |
| unless they use prefix notation (e.g. @code{System.Integer_8}) |
| to reference the entities directly in package @code{System}. |
| For units containing such references, |
| the prefixes must either be removed, or the pragma @code{Extend_System} |
| must be used. |
| |
| @node Language-Related Features |
| @section Language-Related Features |
| |
| @noindent |
| The following sections highlight differences in types, |
| representations of types, operations, alignment, and |
| related topics. |
| |
| @menu |
| * Integer Types and Representations:: |
| * Floating-Point Types and Representations:: |
| * Pragmas Float_Representation and Long_Float:: |
| * Fixed-Point Types and Representations:: |
| * Record and Array Component Alignment:: |
| * Address Clauses:: |
| * Other Representation Clauses:: |
| @end menu |
| |
| @node Integer Types and Representations |
| @subsection Integer Types and Representations |
| |
| @noindent |
| The set of predefined integer types is identical in HP Ada and GNAT. |
| Furthermore the representation of these integer types is also identical, |
| including the capability of size clauses forcing biased representation. |
| |
| In addition, |
| HP Ada for OpenVMS Alpha systems has defined the |
| following additional integer types in package @code{System}: |
| |
| @itemize @bullet |
| |
| @item |
| @code{INTEGER_8} |
| |
| @item |
| @code{INTEGER_16} |
| |
| @item |
| @code{INTEGER_32} |
| |
| @item |
| @code{INTEGER_64} |
| |
| @item |
| @code{LARGEST_INTEGER} |
| @end itemize |
| |
| @noindent |
| In GNAT, the first four of these types may be obtained from the |
| standard Ada 95 package @code{Interfaces}. |
| Alternatively, by use of the pragma @code{Extend_System}, identical |
| declarations can be referenced directly in package @code{System}. |
| On both GNAT and HP Ada, the maximum integer size is 64 bits. |
| |
| @node Floating-Point Types and Representations |
| @subsection Floating-Point Types and Representations |
| @cindex Floating-Point types |
| |
| @noindent |
| The set of predefined floating-point types is identical in HP Ada and GNAT. |
| Furthermore the representation of these floating-point |
| types is also identical. One important difference is that the default |
| representation for HP Ada is @code{VAX_Float}, but the default representation |
| for GNAT is IEEE. |
| |
| Specific types may be declared to be @code{VAX_Float} or IEEE, using the |
| pragma @code{Float_Representation} as described in the HP Ada |
| documentation. |
| For example, the declarations: |
| |
| @smallexample @c ada |
| @cartouche |
| type F_Float is digits 6; |
| pragma Float_Representation (VAX_Float, F_Float); |
| @end cartouche |
| @end smallexample |
| |
| @noindent |
| declares a type @code{F_Float} that will be represented in @code{VAX_Float} |
| format. |
| This set of declarations actually appears in @code{System.Aux_DEC}, |
| which contains |
| the full set of additional floating-point declarations provided in |
| the HP Ada version of package @code{System}. |
| This and similar declarations may be accessed in a user program |
| by using pragma @code{Extend_System}. The use of this |
| pragma, and the related pragma @code{Long_Float} is described in further |
| detail in the following section. |
| |
| @node Pragmas Float_Representation and Long_Float |
| @subsection Pragmas @code{Float_Representation} and @code{Long_Float} |
| |
| @noindent |
| HP Ada provides the pragma @code{Float_Representation}, which |
| acts as a program library switch to allow control over |
| the internal representation chosen for the predefined |
| floating-point types declared in the package @code{Standard}. |
| The format of this pragma is as follows: |
| |
| @smallexample @c ada |
| @cartouche |
| pragma Float_Representation(VAX_Float | IEEE_Float); |
| @end cartouche |
| @end smallexample |
| |
| @noindent |
| This pragma controls the representation of floating-point |
| types as follows: |
| |
| @itemize @bullet |
| @item |
| @code{VAX_Float} specifies that floating-point |
| types are represented by default with the VAX system hardware types |
| @code{F-floating}, @code{D-floating}, @code{G-floating}. |
| Note that the @code{H-floating} |
| type was available only on VAX systems, and is not available |
| in either HP Ada or GNAT. |
| |
| @item |
| @code{IEEE_Float} specifies that floating-point |
| types are represented by default with the IEEE single and |
| double floating-point types. |
| @end itemize |
| |
| @noindent |
| GNAT provides an identical implementation of the pragma |
| @code{Float_Representation}, except that it functions as a |
| configuration pragma. Note that the |
| notion of configuration pragma corresponds closely to the |
| HP Ada notion of a program library switch. |
| |
| When no pragma is used in GNAT, the default is @code{IEEE_Float}, |
| which is different |
| from HP Ada 83, where the default is @code{VAX_Float}. In addition, the |
| predefined libraries in GNAT are built using @code{IEEE_Float}, so it is not |
| advisable to change the format of numbers passed to standard library |
| routines, and if necessary explicit type conversions may be needed. |
| |
| The use of @code{IEEE_Float} is recommended in GNAT since it is more |
| efficient, and (given that it conforms to an international standard) |
| potentially more portable. |
| The situation in which @code{VAX_Float} may be useful is in interfacing |
| to existing code and data that expect the use of @code{VAX_Float}. |
| In such a situation use the predefined @code{VAX_Float} |
| types in package @code{System}, as extended by |
| @code{Extend_System}. For example, use @code{System.F_Float} |
| to specify the 32-bit @code{F-Float} format. |
| |
| @noindent |
| On OpenVMS systems, HP Ada provides the pragma @code{Long_Float} |
| to allow control over the internal representation chosen |
| for the predefined type @code{Long_Float} and for floating-point |
| type declarations with digits specified in the range 7 .. 15. |
| The format of this pragma is as follows: |
| |
| @smallexample @c ada |
| @cartouche |
| pragma Long_Float (D_FLOAT | G_FLOAT); |
| @end cartouche |
| @end smallexample |
| |
| @node Fixed-Point Types and Representations |
| @subsection Fixed-Point Types and Representations |
| |
| @noindent |
| On HP Ada for OpenVMS Alpha systems, rounding is |
| away from zero for both positive and negative numbers. |
| Therefore, @code{+0.5} rounds to @code{1}, |
| and @code{-0.5} rounds to @code{-1}. |
| |
| On GNAT the results of operations |
| on fixed-point types are in accordance with the Ada 95 |
| rules. In particular, results of operations on decimal |
| fixed-point types are truncated. |
| |
| @node Record and Array Component Alignment |
| @subsection Record and Array Component Alignment |
| |
| @noindent |
| On HP Ada for OpenVMS Alpha, all non composite components |
| are aligned on natural boundaries. For example, 1-byte |
| components are aligned on byte boundaries, 2-byte |
| components on 2-byte boundaries, 4-byte components on 4-byte |
| byte boundaries, and so on. The OpenVMS Alpha hardware |
| runs more efficiently with naturally aligned data. |
| |
| On GNAT, alignment rules are compatible |
| with HP Ada for OpenVMS Alpha. |
| |
| @node Address Clauses |
| @subsection Address Clauses |
| |
| @noindent |
| In HP Ada and GNAT, address clauses are supported for |
| objects and imported subprograms. |
| The predefined type @code{System.Address} is a private type |
| in both compilers on Alpha OpenVMS, with the same representation |
| (it is simply a machine pointer). Addition, subtraction, and comparison |
| operations are available in the standard Ada 95 package |
| @code{System.Storage_Elements}, or in package @code{System} |
| if it is extended to include @code{System.Aux_DEC} using a |
| pragma @code{Extend_System} as previously described. |
| |
| Note that code that @code{with}'s both this extended package @code{System} |
| and the package @code{System.Storage_Elements} should not @code{use} |
| both packages, or ambiguities will result. In general it is better |
| not to mix these two sets of facilities. The Ada 95 package was |
| designed specifically to provide the kind of features that HP Ada |
| adds directly to package @code{System}. |
| |
| The type @code{System.Address} is a 64-bit integer type in GNAT for |
| I64 OpenVMS. For more information, |
| see @ref{Transitioning from Alpha to I64 OpenVMS}. |
| |
| GNAT is compatible with HP Ada in its handling of address |
| clauses, except for some limitations in |
| the form of address clauses for composite objects with |
| initialization. Such address clauses are easily replaced |
| by the use of an explicitly-defined constant as described |
| in the Ada 95 Reference Manual (13.1(22)). For example, the sequence |
| of declarations: |
| |
| @smallexample @c ada |
| @cartouche |
| X, Y : Integer := Init_Func; |
| Q : String (X .. Y) := "abc"; |
| ... |
| for Q'Address use Compute_Address; |
| @end cartouche |
| @end smallexample |
| |
| @noindent |
| will be rejected by GNAT, since the address cannot be computed at the time |
| that @code{Q} is declared. To achieve the intended effect, write instead: |
| |
| @smallexample @c ada |
| @group |
| @cartouche |
| X, Y : Integer := Init_Func; |
| Q_Address : constant Address := Compute_Address; |
| Q : String (X .. Y) := "abc"; |
| ... |
| for Q'Address use Q_Address; |
| @end cartouche |
| @end group |
| @end smallexample |
| |
| @noindent |
| which will be accepted by GNAT (and other Ada 95 compilers), and is also |
| compatible with Ada 83. A fuller description of the restrictions |
| on address specifications is found in the @cite{GNAT Reference Manual}. |
| |
| @node Other Representation Clauses |
| @subsection Other Representation Clauses |
| |
| @noindent |
| GNAT implements in a compatible manner all the representation |
| clauses supported by HP Ada. In addition, GNAT |
| implements the representation clause forms that were introduced in Ada 95, |
| including @code{COMPONENT_SIZE} and @code{SIZE} clauses for objects. |
| |
| @node The Package STANDARD |
| @section The Package @code{STANDARD} |
| |
| @noindent |
| The package @code{STANDARD}, as implemented by HP Ada, is fully |
| described in the Ada 95 Reference Manual and in the HP Ada |
| Language Reference Manual. As implemented by GNAT, the |
| package @code{STANDARD} is described in the Ada 95 Reference |
| Manual. |
| |
| In addition, HP Ada supports the Latin-1 character set in |
| the type @code{CHARACTER}. GNAT supports the Latin-1 character set |
| in the type @code{CHARACTER} and also Unicode (ISO 10646 BMP) in |
| the type @code{WIDE_CHARACTER}. |
| |
| The floating-point types supported by GNAT are those |
| supported by HP Ada, but the defaults are different, and are controlled by |
| pragmas. See @ref{Floating-Point Types and Representations}, for details. |
| |
| @node The Package SYSTEM |
| @section The Package @code{SYSTEM} |
| |
| @noindent |
| HP Ada provides a specific version of the package |
| @code{SYSTEM} for each platform on which the language is implemented. |
| For the complete specification of the package @code{SYSTEM}, see |
| Appendix F of the @cite{HP Ada Language Reference Manual}. |
| |
| On HP Ada, the package @code{SYSTEM} includes the following conversion |
| functions: |
| @itemize @bullet |
| @item @code{TO_ADDRESS(INTEGER)} |
| |
| @item @code{TO_ADDRESS(UNSIGNED_LONGWORD)} |
| |
| @item @code{TO_ADDRESS(}@i{universal_integer}@code{)} |
| |
| @item @code{TO_INTEGER(ADDRESS)} |
| |
| @item @code{TO_UNSIGNED_LONGWORD(ADDRESS)} |
| |
| @item Function @code{IMPORT_VALUE return UNSIGNED_LONGWORD} and the |
| functions @code{IMPORT_ADDRESS} and @code{IMPORT_LARGEST_VALUE} |
| @end itemize |
| |
| @noindent |
| By default, GNAT supplies a version of @code{SYSTEM} that matches |
| the definition given in the Ada 95 Reference Manual. |
| This |
| is a subset of the HP system definitions, which is as |
| close as possible to the original definitions. The only difference |
| is that the definition of @code{SYSTEM_NAME} is different: |
| |
| @smallexample @c ada |
| @cartouche |
| type Name is (SYSTEM_NAME_GNAT); |
| System_Name : constant Name := SYSTEM_NAME_GNAT; |
| @end cartouche |
| @end smallexample |
| |
| @noindent |
| Also, GNAT adds the new Ada 95 declarations for |
| @code{BIT_ORDER} and @code{DEFAULT_BIT_ORDER}. |
| |
| However, the use of the following pragma causes GNAT |
| to extend the definition of package @code{SYSTEM} so that it |
| encompasses the full set of HP-specific extensions, |
| including the functions listed above: |
| |
| @smallexample @c ada |
| @cartouche |
| pragma Extend_System (Aux_DEC); |
| @end cartouche |
| @end smallexample |
| |
| @noindent |
| The pragma @code{Extend_System} is a configuration pragma that |
| is most conveniently placed in the @file{gnat.adc} file. See the |
| @cite{GNAT Reference Manual} for further details. |
| |
| HP Ada does not allow the recompilation of the package |
| @code{SYSTEM}. Instead HP Ada provides several pragmas |
| (@code{SYSTEM_NAME}, @code{STORAGE_UNIT}, and @code{MEMORY_SIZE}) |
| to modify values in the package @code{SYSTEM}. |
| On OpenVMS Alpha systems, the pragma |
| @code{SYSTEM_NAME} takes the enumeration literal @code{OPENVMS_AXP} as |
| its single argument. |
| |
| GNAT does permit the recompilation of package @code{SYSTEM} using |
| the special switch @option{-gnatg}, and this switch can be used if |
| it is necessary to modify the definitions in @code{SYSTEM}. GNAT does |
| not permit the specification of @code{SYSTEM_NAME}, @code{STORAGE_UNIT} |
| or @code{MEMORY_SIZE} by any other means. |
| |
| On GNAT systems, the pragma @code{SYSTEM_NAME} takes the |
| enumeration literal @code{SYSTEM_NAME_GNAT}. |
| |
| The definitions provided by the use of |
| |
| @smallexample @c ada |
| pragma Extend_System (AUX_Dec); |
| @end smallexample |
| |
| @noindent |
| are virtually identical to those provided by the HP Ada 83 package |
| @code{SYSTEM}. One important difference is that the name of the |
| @code{TO_ADDRESS} |
| function for type @code{UNSIGNED_LONGWORD} is changed to |
| @code{TO_ADDRESS_LONG}. |
| See the @cite{GNAT Reference Manual} for a discussion of why this change was |
| necessary. |
| |
| @noindent |
| The version of @code{TO_ADDRESS} taking a @i{universal_integer} argument |
| is in fact |
| an extension to Ada 83 not strictly compatible with the reference manual. |
| GNAT, in order to be exactly compatible with the standard, |
| does not provide this capability. In HP Ada 83, the |
| point of this definition is to deal with a call like: |
| |
| @smallexample @c ada |
| TO_ADDRESS (16#12777#); |
| @end smallexample |
| |
| @noindent |
| Normally, according to Ada 83 semantics, one would expect this to be |
| ambiguous, since it matches both the @code{INTEGER} and |
| @code{UNSIGNED_LONGWORD} forms of @code{TO_ADDRESS}. |
| However, in HP Ada 83, there is no ambiguity, since the |
| definition using @i{universal_integer} takes precedence. |
| |
| In GNAT, since the version with @i{universal_integer} cannot be supplied, |
| it is |
| not possible to be 100% compatible. Since there are many programs using |
| numeric constants for the argument to @code{TO_ADDRESS}, the decision in |
| GNAT was |
| to change the name of the function in the @code{UNSIGNED_LONGWORD} case, |
| so the declarations provided in the GNAT version of @code{AUX_Dec} are: |
| |
| @smallexample @c ada |
| function To_Address (X : Integer) return Address; |
| pragma Pure_Function (To_Address); |
| |
| function To_Address_Long (X : Unsigned_Longword) return Address; |
| pragma Pure_Function (To_Address_Long); |
| @end smallexample |
| |
| @noindent |
| This means that programs using @code{TO_ADDRESS} for |
| @code{UNSIGNED_LONGWORD} must change the name to @code{TO_ADDRESS_LONG}. |
| |
| @node Tasking and Task-Related Features |
| @section Tasking and Task-Related Features |
| |
| @noindent |
| This section compares the treatment of tasking in GNAT |
| and in HP Ada for OpenVMS Alpha. |
| The GNAT description applies to both Alpha and I64 OpenVMS. |
| For detailed information on tasking in |
| HP Ada, see the @cite{HP Ada Language Reference Manual} and the |
| relevant run-time reference manual. |
| |
| @menu |
| * Implementation of Tasks in HP Ada for OpenVMS Alpha Systems:: |
| * Assigning Task IDs:: |
| * Task IDs and Delays:: |
| * Task-Related Pragmas:: |
| * Scheduling and Task Priority:: |
| * The Task Stack:: |
| * External Interrupts:: |
| @end menu |
| |
| @node Implementation of Tasks in HP Ada for OpenVMS Alpha Systems |
| @subsection Implementation of Tasks in HP Ada for OpenVMS Alpha Systems |
| |
| @noindent |
| On OpenVMS Alpha systems, each Ada task (except a passive |
| task) is implemented as a single stream of execution |
| that is created and managed by the kernel. On these |
| systems, HP Ada tasking support is based on DECthreads, |
| an implementation of the POSIX standard for threads. |
| |
| Also, on OpenVMS Alpha systems, HP Ada tasks and foreign |
| code that calls DECthreads routines can be used together. |
| The interaction between Ada tasks and DECthreads routines |
| can have some benefits. For example when on OpenVMS Alpha, |
| HP Ada can call C code that is already threaded. |
| |
| GNAT uses the facilities of DECthreads, |
| and Ada tasks are mapped to threads. |
| |
| |
| @node Assigning Task IDs |
| @subsection Assigning Task IDs |
| |
| @noindent |
| The HP Ada Run-Time Library always assigns @code{%TASK 1} to |
| the environment task that executes the main program. On |
| OpenVMS Alpha systems, @code{%TASK 0} is often used for tasks |
| that have been created but are not yet activated. |
| |
| On OpenVMS Alpha systems, task IDs are assigned at |
| activation. On GNAT systems, task IDs are also assigned at |
| task creation but do not have the same form or values as |
| task ID values in HP Ada. There is no null task, and the |
| environment task does not have a specific task ID value. |
| |
| @node Task IDs and Delays |
| @subsection Task IDs and Delays |
| |
| @noindent |
| On OpenVMS Alpha systems, tasking delays are implemented |
| using Timer System Services. The Task ID is used for the |
| identification of the timer request (the @code{REQIDT} parameter). |
| If Timers are used in the application take care not to use |
| @code{0} for the identification, because cancelling such a timer |
| will cancel all timers and may lead to unpredictable results. |
| |
| @node Task-Related Pragmas |
| @subsection Task-Related Pragmas |
| |
| @noindent |
| Ada supplies the pragma @code{TASK_STORAGE}, which allows |
| specification of the size of the guard area for a task |
| stack. (The guard area forms an area of memory that has no |
| read or write access and thus helps in the detection of |
| stack overflow.) On OpenVMS Alpha systems, if the pragma |
| @code{TASK_STORAGE} specifies a value of zero, a minimal guard |
| area is created. In the absence of a pragma @code{TASK_STORAGE}, |
| a default guard area is created. |
| |
| GNAT supplies the following task-related pragmas: |
| |
| @itemize @bullet |
| @item @code{TASK_INFO} |
| |
| This pragma appears within a task definition and |
| applies to the task in which it appears. The argument |
| must be of type @code{SYSTEM.TASK_INFO.TASK_INFO_TYPE}. |
| |
| @item @code{TASK_STORAGE} |
| |
| GNAT implements pragma @code{TASK_STORAGE} in the same way as |
| HP Ada. |
| Both HP Ada and GNAT supply the pragmas @code{PASSIVE}, |
| @code{SUPPRESS}, and @code{VOLATILE}. |
| @end itemize |
| @node Scheduling and Task Priority |
| @subsection Scheduling and Task Priority |
| |
| @noindent |
| HP Ada implements the Ada language requirement that |
| when two tasks are eligible for execution and they have |
| different priorities, the lower priority task does not |
| execute while the higher priority task is waiting. The HP |
| Ada Run-Time Library keeps a task running until either the |
| task is suspended or a higher priority task becomes ready. |
| |
| On OpenVMS Alpha systems, the default strategy is round- |
| robin with preemption. Tasks of equal priority take turns |
| at the processor. A task is run for a certain period of |
| time and then placed at the tail of the ready queue for |
| its priority level. |
| |
| HP Ada provides the implementation-defined pragma @code{TIME_SLICE}, |
| which can be used to enable or disable round-robin |
| scheduling of tasks with the same priority. |
| See the relevant HP Ada run-time reference manual for |
| information on using the pragmas to control HP Ada task |
| scheduling. |
| |
| GNAT follows the scheduling rules of Annex D (Real-Time |
| Annex) of the Ada 95 Reference Manual. In general, this |
| scheduling strategy is fully compatible with HP Ada |
| although it provides some additional constraints (as |
| fully documented in Annex D). |
| GNAT implements time slicing control in a manner compatible with |
| HP Ada 83, by means of the pragma @code{Time_Slice}, whose semantics |
| are identical to the HP Ada 83 pragma of the same name. |
| Note that it is not possible to mix GNAT tasking and |
| HP Ada 83 tasking in the same program, since the two run-time |
| libraries are not compatible. |
| |
| @node The Task Stack |
| @subsection The Task Stack |
| |
| @noindent |
| In HP Ada, a task stack is allocated each time a |
| non-passive task is activated. As soon as the task is |
| terminated, the storage for the task stack is deallocated. |
| If you specify a size of zero (bytes) with @code{T'STORAGE_SIZE}, |
| a default stack size is used. Also, regardless of the size |
| specified, some additional space is allocated for task |
| management purposes. On OpenVMS Alpha systems, at least |
| one page is allocated. |
| |
| GNAT handles task stacks in a similar manner. In accordance with |
| the Ada 95 rules, it provides the pragma @code{STORAGE_SIZE} as |
| an alternative method for controlling the task stack size. |
| The specification of the attribute @code{T'STORAGE_SIZE} is also |
| supported in a manner compatible with HP Ada. |
| |
| @node External Interrupts |
| @subsection External Interrupts |
| |
| @noindent |
| On HP Ada, external interrupts can be associated with task entries. |
| GNAT is compatible with HP Ada in its handling of external interrupts. |
| |
| @node Pragmas and Pragma-Related Features |
| @section Pragmas and Pragma-Related Features |
| |
| @noindent |
| Both HP Ada and GNAT supply all language-defined pragmas |
| as specified by the Ada 83 standard. GNAT also supplies all |
| language-defined pragmas specified in the Ada 95 Reference Manual. |
| In addition, GNAT implements the implementation-defined pragmas |
| from HP Ada 83. |
| |
| @itemize @bullet |
| @item @code{AST_ENTRY} |
| |
| @item @code{COMMON_OBJECT} |
| |
| @item @code{COMPONENT_ALIGNMENT} |
| |
| @item @code{EXPORT_EXCEPTION} |
| |
| @item @code{EXPORT_FUNCTION} |
| |
| @item @code{EXPORT_OBJECT} |
| |
| @item @code{EXPORT_PROCEDURE} |
| |
| @item @code{EXPORT_VALUED_PROCEDURE} |
| |
| @item @code{FLOAT_REPRESENTATION} |
| |
| @item @code{IDENT} |
| |
| @item @code{IMPORT_EXCEPTION} |
| |
| @item @code{IMPORT_FUNCTION} |
| |
| @item @code{IMPORT_OBJECT} |
| |
| @item @code{IMPORT_PROCEDURE} |
| |
| @item @code{IMPORT_VALUED_PROCEDURE} |
| |
| @item @code{INLINE_GENERIC} |
| |
| @item @code{INTERFACE_NAME} |
| |
| @item @code{LONG_FLOAT} |
| |
| @item @code{MAIN_STORAGE} |
| |
| @item @code{PASSIVE} |
| |
| @item @code{PSET_OBJECT} |
| |
| @item @code{SHARE_GENERIC} |
| |
| @item @code{SUPPRESS_ALL} |
| |
| @item @code{TASK_STORAGE} |
| |
| @item @code{TIME_SLICE} |
| |
| @item @code{TITLE} |
| @end itemize |
| |
| @noindent |
| These pragmas are all fully implemented, with the exception of @code{TITLE}, |
| @code{PASSIVE}, and @code{SHARE_GENERIC}, which are |
| recognized, but which have no |
| effect in GNAT. The effect of @code{PASSIVE} may be obtained by the |
| use of protected objects in Ada 95. In GNAT, all generics are inlined. |
| |
| Unlike HP Ada, the GNAT ``@code{EXPORT_}@i{subprogram}'' pragmas require |
| a separate subprogram specification which must appear before the |
| subprogram body. |
| |
| GNAT also supplies a number of implementation-defined pragmas as follows: |
| @itemize @bullet |
| @item @code{ABORT_DEFER} |
| |
| @item @code{ADA_83} |
| |
| @item @code{ADA_95} |
| |
| @item @code{ADA_05} |
| |
| @item @code{ANNOTATE} |
| |
| @item @code{ASSERT} |
| |
| @item @code{C_PASS_BY_COPY} |
| |
| @item @code{CPP_CLASS} |
| |
| @item @code{CPP_CONSTRUCTOR} |
| |
| @item @code{CPP_DESTRUCTOR} |
| |
| @item @code{CPP_VIRTUAL} |
| |
| @item @code{CPP_VTABLE} |
| |
| @item @code{DEBUG} |
| |
| @item @code{EXTEND_SYSTEM} |
| |
| @item @code{LINKER_ALIAS} |
| |
| @item @code{LINKER_SECTION} |
| |
| @item @code{MACHINE_ATTRIBUTE} |
| |
| @item @code{NO_RETURN} |
| |
| @item @code{PURE_FUNCTION} |
| |
| @item @code{SOURCE_FILE_NAME} |
| |
| @item @code{SOURCE_REFERENCE} |
| |
| @item @code{TASK_INFO} |
| |
| @item @code{UNCHECKED_UNION} |
| |
| @item @code{UNIMPLEMENTED_UNIT} |
| |
| @item @code{UNIVERSAL_DATA} |
| |
| @item @code{UNSUPPRESS} |
| |
| @item @code{WARNINGS} |
| |
| @item @code{WEAK_EXTERNAL} |
| @end itemize |
| |
| @noindent |
| For full details on these GNAT implementation-defined pragmas, see |
| the GNAT Reference Manual. |
| |
| @menu |
| * Restrictions on the Pragma INLINE:: |
| * Restrictions on the Pragma INTERFACE:: |
| * Restrictions on the Pragma SYSTEM_NAME:: |
| @end menu |
| |
| @node Restrictions on the Pragma INLINE |
| @subsection Restrictions on Pragma @code{INLINE} |
| |
| @noindent |
| HP Ada enforces the following restrictions on the pragma @code{INLINE}: |
| @itemize @bullet |
| @item Parameters cannot have a task type. |
| |
| @item Function results cannot be task types, unconstrained |
| array types, or unconstrained types with discriminants. |
| |
| @item Bodies cannot declare the following: |
| @itemize @bullet |
| @item Subprogram body or stub (imported subprogram is allowed) |
| |
| @item Tasks |
| |
| @item Generic declarations |
| |
| @item Instantiations |
| |
| @item Exceptions |
| |
| @item Access types (types derived from access types allowed) |
| |
| @item Array or record types |
| |
| @item Dependent tasks |
| |
| @item Direct recursive calls of subprogram or containing |
| subprogram, directly or via a renaming |
| |
| @end itemize |
| @end itemize |
| |
| @noindent |
| In GNAT, the only restriction on pragma @code{INLINE} is that the |
| body must occur before the call if both are in the same |
| unit, and the size must be appropriately small. There are |
| no other specific restrictions which cause subprograms to |
| be incapable of being inlined. |
| |
| @node Restrictions on the Pragma INTERFACE |
| @subsection Restrictions on Pragma @code{INTERFACE} |
| |
| @noindent |
| The following restrictions on pragma @code{INTERFACE} |
| are enforced by both HP Ada and GNAT: |
| @itemize @bullet |
| @item Languages accepted: Ada, Bliss, C, Fortran, Default. |
| Default is the default on OpenVMS Alpha systems. |
| |
| @item Parameter passing: Language specifies default |
| mechanisms but can be overridden with an @code{EXPORT} pragma. |
| |
| @itemize @bullet |
| @item Ada: Use internal Ada rules. |
| |
| @item Bliss, C: Parameters must be mode @code{in}; cannot be |
| record or task type. Result cannot be a string, an |
| array, or a record. |
| |
| @item Fortran: Parameters cannot have a task type. Result cannot |
| be a string, an array, or a record. |
| @end itemize |
| @end itemize |
| |
| @noindent |
| GNAT is entirely upwards compatible with HP Ada, and in addition allows |
| record parameters for all languages. |
| |
| @node Restrictions on the Pragma SYSTEM_NAME |
| @subsection Restrictions on Pragma @code{SYSTEM_NAME} |
| |
| @noindent |
| For HP Ada for OpenVMS Alpha, the enumeration literal |
| for the type @code{NAME} is @code{OPENVMS_AXP}. |
| In GNAT, the enumeration |
| literal for the type @code{NAME} is @code{SYSTEM_NAME_GNAT}. |
| |
| @node Library of Predefined Units |
| @section Library of Predefined Units |
| |
| @noindent |
| A library of predefined units is provided as part of the |
| HP Ada and GNAT implementations. HP Ada does not provide |
| the package @code{MACHINE_CODE} but instead recommends importing |
| assembler code. |
| |
| The GNAT versions of the HP Ada Run-Time Library (@code{ADA$PREDEFINED:}) |
| units are taken from the OpenVMS Alpha version, not the OpenVMS VAX |
| version. |
| The HP Ada Predefined Library units are modified to remove Ada 95 |
| incompatibilities and to make them interoperable with GNAT |
| (@pxref{Changes to DECLIB}, for details). |
| The units are located in the @file{DECLIB} directory. |
| |
| |
| The GNAT RTL is contained in |
| the @file{ADALIB} directory, and |
| the default search path is set up to find @code{DECLIB} units in preference |
| to @code{ADALIB} units with the same name (@code{TEXT_IO}, |
| @code{SEQUENTIAL_IO}, and @code{DIRECT_IO}, for example). |
| |
| |
| @menu |
| * Changes to DECLIB:: |
| @end menu |
| |
| @node Changes to DECLIB |
| @subsection Changes to @code{DECLIB} |
| |
| @noindent |
| The changes made to the HP Ada predefined library for GNAT and Ada 95 |
| compatibility are minor and include the following: |
| |
| @itemize @bullet |
| @item Adjusting the location of pragmas and record representation |
| clauses to obey Ada 95 rules |
| |
| @item Adding the proper notation to generic formal parameters |
| that take unconstrained types in instantiation |
| |
| @item Adding pragma @code{ELABORATE_BODY} to package specifications |
| that have package bodies not otherwise allowed |
| |
| @item Replacing occurrences of the identifier ``@code{PROTECTED}'' by |
| ``@code{PROTECTD}''. |
| Currently these are found only in the @code{STARLET} package spec. |
| |
| @item Changing @code{SYSTEM.ADDRESS} to @code{SYSTEM.SHORT_ADDRESS} |
| where the address size is constrained to 32 bits. |
| @end itemize |
| |
| @noindent |
| None of the above changes is visible to users. |
| |
| @node Bindings |
| @section Bindings |
| |
| @noindent |
| On OpenVMS Alpha, HP Ada provides the following strongly-typed bindings: |
| @itemize @bullet |
| |
| @item Command Language Interpreter (CLI interface) |
| |
| @item DECtalk Run-Time Library (DTK interface) |
| |
| @item Librarian utility routines (LBR interface) |
| |
| @item General Purpose Run-Time Library (LIB interface) |
| |
| @item Math Run-Time Library (MTH interface) |
| |
| @item National Character Set Run-Time Library (NCS interface) |
| |
| @item Compiled Code Support Run-Time Library (OTS interface) |
| |
| @item Parallel Processing Run-Time Library (PPL interface) |
| |
| @item Screen Management Run-Time Library (SMG interface) |
| |
| @item Sort Run-Time Library (SOR interface) |
| |
| @item String Run-Time Library (STR interface) |
| |
| @item STARLET System Library |
| @findex Starlet |
| |
| @item X Window System Version 11R4 and 11R5 (X, XLIB interface) |
| |
| @item X Windows Toolkit (XT interface) |
| |
| @item X/Motif Version 1.1.3 and 1.2 (XM interface) |
| @end itemize |
| |
| @noindent |
| GNAT provides implementations of these HP bindings in the @code{DECLIB} |
| directory. |
| |
| The X/Motif bindings used to build @code{DECLIB} are whatever versions are |
| in the |
| HP Ada @file{ADA$PREDEFINED} directory with extension @file{.ADC}. |
| A pragma @code{Linker_Options} has been added to packages @code{Xm}, |
| @code{Xt}, and @code{X_Lib} |
| causing the default X/Motif sharable image libraries to be linked in. This |
| is done via options files named @file{xm.opt}, @file{xt.opt}, and |
| @file{x_lib.opt} (also located in the @file{DECLIB} directory). |
| |
| It may be necessary to edit these options files to update or correct the |
| library names if, for example, the newer X/Motif bindings from |
| @file{ADA$EXAMPLES} |
| had been (previous to installing GNAT) copied and renamed to supersede the |
| default @file{ADA$PREDEFINED} versions. |
| |
| @menu |
| * Shared Libraries and Options Files:: |
| * Interfaces to C:: |
| @end menu |
| |
| @node Shared Libraries and Options Files |
| @subsection Shared Libraries and Options Files |
| |
| @noindent |
| When using the HP Ada |
| predefined X and Motif bindings, the linking with their sharable images is |
| done automatically by @command{GNAT LINK}. |
| When using other X and Motif bindings, you need |
| to add the corresponding sharable images to the command line for |
| @code{GNAT LINK}. When linking with shared libraries, or with |
| @file{.OPT} files, you must |
| also add them to the command line for @command{GNAT LINK}. |
| |
| A shared library to be used with GNAT is built in the same way as other |
| libraries under VMS. The VMS Link command can be used in standard fashion. |
| |
| @node Interfaces to C |
| @subsection Interfaces to C |
| |
| @noindent |
| HP Ada |
| provides the following Ada types and operations: |
| |
| @itemize @bullet |
| @item C types package (@code{C_TYPES}) |
| |
| @item C strings (@code{C_TYPES.NULL_TERMINATED}) |
| |
| @item Other_types (@code{SHORT_INT}) |
| @end itemize |
| |
| @noindent |
| Interfacing to C with GNAT, you can use the above approach |
| described for HP Ada or the facilities of Annex B of |
| the Ada 95 Reference Manual (packages @code{INTERFACES.C}, |
| @code{INTERFACES.C.STRINGS} and @code{INTERFACES.C.POINTERS}). For more |
| information, see the section ``Interfacing to C'' in the |
| @cite{GNAT Reference Manual}. |
| |
| The @option{-gnatF} qualifier forces default and explicit |
| @code{External_Name} parameters in pragmas @code{Import} and @code{Export} |
| to be uppercased for compatibility with the default behavior |
| of HP C. The qualifier has no effect on @code{Link_Name} parameters. |
| |
| @node Main Program Definition |
| @section Main Program Definition |
| |
| @noindent |
| The following section discusses differences in the |
| definition of main programs on HP Ada and GNAT. |
| On HP Ada, main programs are defined to meet the |
| following conditions: |
| @itemize @bullet |
| @item Procedure with no formal parameters (returns @code{0} upon |
| normal completion) |
| |
| @item Procedure with no formal parameters (returns @code{42} when |
| an unhandled exception is raised) |
| |
| @item Function with no formal parameters whose returned value |
| is of a discrete type |
| |
| @item Procedure with one @code{out} formal of a discrete type for |
| which a specification of pragma @code{EXPORT_VALUED_PROCEDURE} |
| is given. |
| |
| @end itemize |
| |
| @noindent |
| When declared with the pragma @code{EXPORT_VALUED_PROCEDURE}, |
| a main function or main procedure returns a discrete |
| value whose size is less than 64 bits (32 on VAX systems), |
| the value is zero- or sign-extended as appropriate. |
| On GNAT, main programs are defined as follows: |
| @itemize @bullet |
| @item Must be a non-generic, parameterless subprogram that |
| is either a procedure or function returning an Ada |
| @code{STANDARD.INTEGER} (the predefined type) |
| |
| @item Cannot be a generic subprogram or an instantiation of a |
| generic subprogram |
| @end itemize |
| |
| @node Implementation-Defined Attributes |
| @section Implementation-Defined Attributes |
| |
| @noindent |
| GNAT provides all HP Ada implementation-defined |
| attributes. |
| |
| @node Compiler and Run-Time Interfacing |
| @section Compiler and Run-Time Interfacing |
| |
| @noindent |
| HP Ada provides the following qualifiers to pass options to the linker |
| (ACS LINK): |
| @itemize @bullet |
| @item @option{/WAIT} and @option{/SUBMIT} |
| |
| @item @option{/COMMAND} |
| |
| @item @option{/[NO]MAP} |
| |
| @item @option{/OUTPUT=@i{file-spec}} |
| |
| @item @option{/[NO]DEBUG} and @option{/[NO]TRACEBACK} |
| @end itemize |
| |
| @noindent |
| To pass options to the linker, GNAT provides the following |
| switches: |
| |
| @itemize @bullet |
| @item @option{/EXECUTABLE=@i{exec-name}} |
| |
| @item @option{/VERBOSE} |
| |
| @item @option{/[NO]DEBUG} and @option{/[NO]TRACEBACK} |
| @end itemize |
| |
| @noindent |
| For more information on these switches, see |
| @ref{Switches for gnatlink}. |
| In HP Ada, the command-line switch @option{/OPTIMIZE} is available |
| to control optimization. HP Ada also supplies the |
| following pragmas: |
| @itemize @bullet |
| @item @code{OPTIMIZE} |
| |
| @item @code{INLINE} |
| |
| @item @code{INLINE_GENERIC} |
| |
| @item @code{SUPPRESS_ALL} |
| |
| @item @code{PASSIVE} |
| @end itemize |
| |
| @noindent |
| In GNAT, optimization is controlled strictly by command |
| line parameters, as described in the corresponding section of this guide. |
| The HP pragmas for control of optimization are |
| recognized but ignored. |
| |
| Note that in GNAT, the default is optimization off, whereas in HP Ada |
| the default is that optimization is turned on. |
| |
| @node Program Compilation and Library Management |
| @section Program Compilation and Library Management |
| |
| @noindent |
| HP Ada and GNAT provide a comparable set of commands to |
| build programs. HP Ada also provides a program library, |
| which is a concept that does not exist on GNAT. Instead, |
| GNAT provides directories of sources that are compiled as |
| needed. |
| |
| The following table summarizes |
| the HP Ada commands and provides |
| equivalent GNAT commands. In this table, some GNAT |
| equivalents reflect the fact that GNAT does not use the |
| concept of a program library. Instead, it uses a model |
| in which collections of source and object files are used |
| in a manner consistent with other languages like C and |
| Fortran. Therefore, standard system file commands are used |
| to manipulate these elements. Those GNAT commands are marked with |
| an asterisk. |
| Note that, unlike HP Ada, none of the GNAT commands accepts wild cards. |
| |
| @need 1500 |
| @multitable @columnfractions .35 .65 |
| |
| @item @emph{HP Ada Command} |
| @tab @emph{GNAT Equivalent / Description} |
| |
| @item @command{ADA} |
| @tab @command{GNAT COMPILE}@* |
| Invokes the compiler to compile one or more Ada source files. |
| |
| @item @command{ACS ATTACH}@* |
| @tab [No equivalent]@* |
| Switches control of terminal from current process running the program |
| library manager. |
| |
| @item @command{ACS CHECK} |
| @tab @command{GNAT MAKE /DEPENDENCY_LIST}@* |
| Forms the execution closure of one |
| or more compiled units and checks completeness and currency. |
| |
| @item @command{ACS COMPILE} |
| @tab @command{GNAT MAKE /ACTIONS=COMPILE}@* |
| Forms the execution closure of one or |
| more specified units, checks completeness and currency, |
| identifies units that have revised source files, compiles same, |
| and recompiles units that are or will become obsolete. |
| Also completes incomplete generic instantiations. |
| |
| @item @command{ACS COPY FOREIGN} |
| @tab Copy (*)@* |
| Copies a foreign object file into the program library as a |
| library unit body. |
| |
| @item @command{ACS COPY UNIT} |
| @tab Copy (*)@* |
| Copies a compiled unit from one program library to another. |
| |
| @item @command{ACS CREATE LIBRARY} |
| @tab Create /directory (*)@* |
| Creates a program library. |
| |
| @item @command{ACS CREATE SUBLIBRARY} |
| @tab Create /directory (*)@* |
| Creates a program sublibrary. |
| |
| @item @command{ACS DELETE LIBRARY} |
| @tab @* |
| Deletes a program library and its contents. |
| |
| @item @command{ACS DELETE SUBLIBRARY} |
| @tab @* |
| Deletes a program sublibrary and its contents. |
| |
| @item @command{ACS DELETE UNIT} |
| @tab Delete file (*)@* |
| On OpenVMS systems, deletes one or more compiled units from |
| the current program library. |
| |
| @item @command{ACS DIRECTORY} |
| @tab Directory (*)@* |
| On OpenVMS systems, lists units contained in the current |
| program library. |
| |
| @item @command{ACS ENTER FOREIGN} |
| @tab Copy (*)@* |
| Allows the import of a foreign body as an Ada library |
| specification and enters a reference to a pointer. |
| |
| @item @command{ACS ENTER UNIT} |
| @tab Copy (*)@* |
| Enters a reference (pointer) from the current program library to |
| a unit compiled into another program library. |
| |
| @item @command{ACS EXIT} |
| @tab [No equivalent]@* |
| Exits from the program library manager. |
| |
| @item @command{ACS EXPORT} |
| @tab Copy (*)@* |
| Creates an object file that contains system-specific object code |
| for one or more units. With GNAT, object files can simply be copied |
| into the desired directory. |
| |
| @item @command{ACS EXTRACT SOURCE} |
| @tab Copy (*)@* |
| Allows access to the copied source file for each Ada compilation unit |
| |
| @item @command{ACS HELP} |
| @tab @command{HELP GNAT}@* |
| Provides online help. |
| |
| @item @command{ACS LINK} |
| @tab @command{GNAT LINK}@* |
| Links an object file containing Ada units into an executable file. |
| |
| @item @command{ACS LOAD} |
| @tab Copy (*)@* |
| Loads (partially compiles) Ada units into the program library. |
| Allows loading a program from a collection of files into a library |
| without knowing the relationship among units. |
| |
| @item @command{ACS MERGE} |
| @tab Copy (*)@* |
| Merges into the current program library, one or more units from |
| another library where they were modified. |
| |
| @item @command{ACS RECOMPILE} |
| @tab @command{GNAT MAKE /ACTIONS=COMPILE}@* |
| Recompiles from external or copied source files any obsolete |
| unit in the closure. Also, completes any incomplete generic |
| instantiations. |
| |
| @item @command{ACS REENTER} |
| @tab @command{GNAT MAKE}@* |
| Reenters current references to units compiled after last entered |
| with the @command{ACS ENTER UNIT} command. |
| |
| @item @command{ACS SET LIBRARY} |
| @tab Set default (*)@* |
| Defines a program library to be the compilation context as well |
| as the target library for compiler output and commands in general. |
| |
| @item @command{ACS SET PRAGMA} |
| @tab Edit @file{gnat.adc} (*)@* |
| Redefines specified values of the library characteristics |
| @code{LONG_ FLOAT}, @code{MEMORY_SIZE}, @code{SYSTEM_NAME}, |
| and @code{Float_Representation}. |
| |
| @item @command{ACS SET SOURCE} |
| @tab Define @code{ADA_INCLUDE_PATH} path (*)@* |
| Defines the source file search list for the @command{ACS COMPILE} command. |
| |
| @item @command{ACS SHOW LIBRARY} |
| @tab Directory (*)@* |
| Lists information about one or more program libraries. |
| |
| @item @command{ACS SHOW PROGRAM} |
| @tab [No equivalent]@* |
| Lists information about the execution closure of one or |
| more units in the program library. |
| |
| @item @command{ACS SHOW SOURCE} |
| @tab Show logical @code{ADA_INCLUDE_PATH}@* |
| Shows the source file search used when compiling units. |
| |
| @item @command{ACS SHOW VERSION} |
| @tab Compile with @option{VERBOSE} option |
| Displays the version number of the compiler and program library |
| manager used. |
| |
| @item @command{ACS SPAWN} |
| @tab [No equivalent]@* |
| Creates a subprocess of the current process (same as @command{DCL SPAWN} |
| command). |
| |
| @item @command{ACS VERIFY} |
| @tab [No equivalent]@* |
| Performs a series of consistency checks on a program library to |
| determine whether the library structure and library files are in |
| valid form. |
| @end multitable |
| |
| @noindent |
| |
| @node Input-Output |
| @section Input-Output |
| |
| @noindent |
| On OpenVMS Alpha systems, HP Ada uses OpenVMS Record |
| Management Services (RMS) to perform operations on |
| external files. |
| |
| @noindent |
| HP Ada and GNAT predefine an identical set of input- |
| output packages. To make the use of the |
| generic @code{TEXT_IO} operations more convenient, HP Ada |
| provides predefined library packages that instantiate the |
| integer and floating-point operations for the predefined |
| integer and floating-point types as shown in the following table. |
| |
| @multitable @columnfractions .45 .55 |
| @item @emph{Package Name} @tab Instantiation |
| |
| @item @code{INTEGER_TEXT_IO} |
| @tab @code{INTEGER_IO(INTEGER)} |
| |
| @item @code{SHORT_INTEGER_TEXT_IO} |
| @tab @code{INTEGER_IO(SHORT_INTEGER)} |
| |
| @item @code{SHORT_SHORT_INTEGER_TEXT_IO} |
| @tab @code{INTEGER_IO(SHORT_SHORT_INTEGER)} |
| |
| @item @code{FLOAT_TEXT_IO} |
| @tab @code{FLOAT_IO(FLOAT)} |
| |
| @item @code{LONG_FLOAT_TEXT_IO} |
| @tab @code{FLOAT_IO(LONG_FLOAT)} |
| @end multitable |
| |
| @noindent |
| The HP Ada predefined packages and their operations |
| are implemented using OpenVMS Alpha files and input-output |
| facilities. HP Ada supports asynchronous input-output on OpenVMS Alpha. |
| Familiarity with the following is recommended: |
| @itemize @bullet |
| @item RMS file organizations and access methods |
| |
| @item OpenVMS file specifications and directories |
| |
| @item OpenVMS File Definition Language (FDL) |
| @end itemize |
| |
| @noindent |
| GNAT provides I/O facilities that are completely |
| compatible with HP Ada. The distribution includes the |
| standard HP Ada versions of all I/O packages, operating |
| in a manner compatible with HP Ada. In particular, the |
| following packages are by default the HP Ada (Ada 83) |
| versions of these packages rather than the renamings |
| suggested in Annex J of the Ada 95 Reference Manual: |
| @itemize @bullet |
| @item @code{TEXT_IO} |
| |
| @item @code{SEQUENTIAL_IO} |
| |
| @item @code{DIRECT_IO} |
| @end itemize |
| |
| @noindent |
| The use of the standard Ada 95 syntax for child packages (for |
| example, @code{ADA.TEXT_IO}) retrieves the Ada 95 versions of these |
| packages, as defined in the Ada 95 Reference Manual. |
| GNAT provides HP-compatible predefined instantiations |
| of the @code{TEXT_IO} packages, and also |
| provides the standard predefined instantiations required |
| by the Ada 95 Reference Manual. |
| |
| For further information on how GNAT interfaces to the file |
| system or how I/O is implemented in programs written in |
| mixed languages, see the chapter ``Implementation of the |
| Standard I/O'' in the @cite{GNAT Reference Manual}. |
| This chapter covers the following: |
| @itemize @bullet |
| @item Standard I/O packages |
| |
| @item @code{FORM} strings |
| |
| @item @code{ADA.DIRECT_IO} |
| |
| @item @code{ADA.SEQUENTIAL_IO} |
| |
| @item @code{ADA.TEXT_IO} |
| |
| @item Stream pointer positioning |
| |
| @item Reading and writing non-regular files |
| |
| @item @code{GET_IMMEDIATE} |
| |
| @item Treating @code{TEXT_IO} files as streams |
| |
| @item Shared files |
| |
| @item Open modes |
| @end itemize |
| |
| @node Implementation Limits |
| @section Implementation Limits |
| |
| @noindent |
| The following table lists implementation limits for HP Ada |
| and GNAT systems. |
| @multitable @columnfractions .60 .20 .20 |
| @sp 1 |
| @item @emph{Compilation Parameter} |
| @tab @emph{HP Ada} |
| @tab @emph{GNAT} |
| @sp 1 |
| |
| @item In a subprogram or entry declaration, maximum number of |
| formal parameters that are of an unconstrained record type |
| @tab 32 |
| @tab No set limit |
| @sp 1 |
| |
| @item Maximum identifier length (number of characters) |
| @tab 255 |
| @tab 255 |
| @sp 1 |
| |
| @item Maximum number of characters in a source line |
| @tab 255 |
| @tab 255 |
| @sp 1 |
| |
| @item Maximum collection size (number of bytes) |
| @tab 2**31-1 |
| @tab 2**31-1 |
| @sp 1 |
| |
| @item Maximum number of discriminants for a record type |
| @tab 245 |
| @tab No set limit |
| @sp 1 |
| |
| @item Maximum number of formal parameters in an entry or |
| subprogram declaration |
| @tab 246 |
| @tab No set limit |
| @sp 1 |
| |
| @item Maximum number of dimensions in an array type |
| @tab 255 |
| @tab No set limit |
| @sp 1 |
| |
| @item Maximum number of library units and subunits in a compilation. |
| @tab 4095 |
| @tab No set limit |
| @sp 1 |
| |
| @item Maximum number of library units and subunits in an execution. |
| @tab 16383 |
| @tab No set limit |
| @sp 1 |
| |
| @item Maximum number of objects declared with the pragma @code{COMMON_OBJECT} |
| or @code{PSECT_OBJECT} |
| @tab 32757 |
| @tab No set limit |
| @sp 1 |
| |
| @item Maximum number of enumeration literals in an enumeration type |
| definition |
| @tab 65535 |
| @tab No set limit |
| @sp 1 |
| |
| @item Maximum number of lines in a source file |
| @tab 65534 |
| @tab No set limit |
| @sp 1 |
| |
| @item Maximum number of bits in any object |
| @tab 2**31-1 |
| @tab 2**31-1 |
| @sp 1 |
| |
| @item Maximum size of the static portion of a stack frame (approximate) |
| @tab 2**31-1 |
| @tab 2**31-1 |
| @end multitable |
| |
| @node Tools and Utilities |
| @section Tools and Utilities |
| |
| @noindent |
| The following table lists some of the OpenVMS development tools |
| available for HP Ada, and the corresponding tools for |
| use with @value{EDITION} on Alpha and I64 platforms. |
| Aside from the debugger, all the OpenVMS tools identified are part |
| of the DECset package. |
| |
| |
| @iftex |
| @c Specify table in TeX since Texinfo does a poor job |
| @tex |
| \smallskip |
| \smallskip |
| \settabs\+Language-Sensitive Editor\quad |
| &Product with HP Ada\quad |
| &\cr |
| \+\it Tool |
| &\it Product with HP Ada |
| & \it Product with GNAT Pro\cr |
| \smallskip |
| \+Code Management System |
| &HP CMS |
| & HP CMS\cr |
| \smallskip |
| \+Language-Sensitive Editor |
| &HP LSE |
| & emacs or HP LSE (Alpha)\cr |
| \+ |
| & |
| & HP LSE (I64)\cr |
| \smallskip |
| \+Debugger |
| &OpenVMS Debug |
| & gdb (Alpha),\cr |
| \+ |
| & |
| & OpenVMS Debug (I64)\cr |
| \smallskip |
| \+Source Code Analyzer / |
| &HP SCA |
| & GNAT XREF\cr |
| \+Cross Referencer |
| & |
| &\cr |
| \smallskip |
| \+Test Manager |
| &HP Digital Test |
| & HP DTM\cr |
| \+ |
| &Manager (DTM) |
| &\cr |
| \smallskip |
| \+Performance and |
| & HP PCA |
| & HP PCA\cr |
| \+Coverage Analyzer |
| & |
| &\cr |
| \smallskip |
| \+Module Management |
| & HP MMS |
| & Not applicable\cr |
| \+ System |
| & |
| &\cr |
| \smallskip |
| \smallskip |
| @end tex |
| @end iftex |
| |
| @ifnottex |
| @c This is the Texinfo version of the table. It renders poorly in pdf, hence |
| @c the TeX version above for the printed version |
| @flushleft |
| @c @multitable @columnfractions .3 .4 .4 |
| @multitable {Source Code Analyzer /}{Product with HP Ada}{Product with GNAT Pro} |
| @item @i{Tool} |
| @tab @i{Product with HP Ada} |
| @tab @i{Product with @value{EDITION}} |
| @item Code Management@*System |
| @tab HP CMS |
| @tab HP CMS |
| @item Language-Sensitive@*Editor |
| @tab HP LSE |
| @tab emacs or HP LSE (Alpha) |
| @item |
| @tab |
| @tab HP LSE (I64) |
| @item Debugger |
| @tab OpenVMS Debug |
| @tab gdb (Alpha), |
| @item |
| @tab |
| @tab OpenVMS Debug (I64) |
| @item Source Code Analyzer /@*Cross Referencer |
| @tab HP SCA |
| @tab GNAT XREF |
| @item Test Manager |
| @tab HP Digital Test@*Manager (DTM) |
| @tab HP DTM |
| @item Performance and@*Coverage Analyzer |
| @tab HP PCA |
| @tab HP PCA |
| @item Module Management@*System |
| @tab HP MMS |
| @tab Not applicable |
| @end multitable |
| @end flushleft |
| @end ifnottex |
| |
| @end ifset |
| |
| |
| @c ************************************** |
| @node Platform-Specific Information for the Run-Time Libraries |
| @appendix Platform-Specific Information for the Run-Time Libraries |
| @cindex Tasking and threads libraries |
| @cindex Threads libraries and tasking |
| @cindex Run-time libraries (platform-specific information) |
| |
| @noindent |
| The GNAT run-time implementation may vary with respect to both the |
| underlying threads library and the exception handling scheme. |
| For threads support, one or more of the following are supplied: |
| @itemize @bullet |
| @item @b{native threads library}, a binding to the thread package from |
| the underlying operating system |
| |
| @item @b{pthreads library} (Sparc Solaris only), a binding to the Solaris |
| POSIX thread package |
| @end itemize |
| |
| @noindent |
| For exception handling, either or both of two models are supplied: |
| @itemize @bullet |
| @item @b{Zero-Cost Exceptions} (``ZCX''),@footnote{ |
| Most programs should experience a substantial speed improvement by |
| being compiled with a ZCX run-time. |
| This is especially true for |
| tasking applications or applications with many exception handlers.} |
| @cindex Zero-Cost Exceptions |
| @cindex ZCX (Zero-Cost Exceptions) |
| which uses binder-generated tables that |
| are interrogated at run time to locate a handler |
| |
| @item @b{setjmp / longjmp} (``SJLJ''), |
| @cindex setjmp/longjmp Exception Model |
| @cindex SJLJ (setjmp/longjmp Exception Model) |
| which uses dynamically-set data to establish |
| the set of handlers |
| @end itemize |
| |
| @noindent |
| This appendix summarizes which combinations of threads and exception support |
| are supplied on various GNAT platforms. |
| It then shows how to select a particular library either |
| permanently or temporarily, |
| explains the properties of (and tradeoffs among) the various threads |
| libraries, and provides some additional |
| information about several specific platforms. |
| |
| @menu |
| * Summary of Run-Time Configurations:: |
| * Specifying a Run-Time Library:: |
| * Choosing the Scheduling Policy:: |
| * Solaris-Specific Considerations:: |
| * Linux-Specific Considerations:: |
| * AIX-Specific Considerations:: |
| @end menu |
| |
| @node Summary of Run-Time Configurations |
| @section Summary of Run-Time Configurations |
| |
| @multitable @columnfractions .30 .70 |
| @item @b{alpha-openvms} |
| @item @code{@ @ }@i{rts-native (default)} |
| @item @code{@ @ @ @ }Tasking @tab native VMS threads |
| @item @code{@ @ @ @ }Exceptions @tab ZCX |
| @* |
| @item @b{alpha-tru64} |
| @item @code{@ @ }@i{rts-native (default)} |
| @item @code{@ @ @ @ }Tasking @tab native TRU64 threads |
| @item @code{@ @ @ @ }Exceptions @tab ZCX |
| @* |
| @item @code{@ @ }@i{rts-sjlj} |
| @item @code{@ @ @ @ }Tasking @tab native TRU64 threads |
| @item @code{@ @ @ @ }Exceptions @tab SJLJ |
| @* |
| @item @b{ia64-hp_linux} |
| @item @code{@ @ }@i{rts-native (default)} |
| @item @code{@ @ @ @ }Tasking @tab pthread library |
| @item @code{@ @ @ @ }Exceptions @tab ZCX |
| @* |
| @item @b{ia64-hpux} |
| @item @code{@ @ }@i{rts-native (default)} |
| @item @code{@ @ @ @ }Tasking @tab native HP-UX threads |
| @item @code{@ @ @ @ }Exceptions @tab SJLJ |
| @* |
| @item @b{ia64-openvms} |
| @item @code{@ @ }@i{rts-native (default)} |
| @item @code{@ @ @ @ }Tasking @tab native VMS threads |
| @item @code{@ @ @ @ }Exceptions @tab ZCX |
| @* |
| @item @b{ia64-sgi_linux} |
| @item @code{@ @ }@i{rts-native (default)} |
| @item @code{@ @ @ @ }Tasking @tab pthread library |
| @item @code{@ @ @ @ }Exceptions @tab ZCX |
| @* |
| @item @b{mips-irix} |
| @item @code{@ @ }@i{rts-native (default)} |
| @item @code{@ @ @ @ }Tasking @tab native IRIX threads |
| @item @code{@ @ @ @ }Exceptions @tab ZCX |
| @* |
| @item @b{pa-hpux} |
| @item @code{@ @ }@i{rts-native (default)} |
| @item @code{@ @ @ @ }Tasking @tab native HP-UX threads |
| @item @code{@ @ @ @ }Exceptions @tab ZCX |
| @* |
| @item @code{@ @ }@i{rts-sjlj} |
| @item @code{@ @ @ @ }Tasking @tab native HP-UX threads |
| @item @code{@ @ @ @ }Exceptions @tab SJLJ |
| @* |
| @item @b{ppc-aix} |
| @item @code{@ @ }@i{rts-native (default)} |
| @item @code{@ @ @ @ }Tasking @tab native AIX threads |
| @item @code{@ @ @ @ }Exceptions @tab SJLJ |
| @* |
| @item @b{ppc-darwin} |
| @item @code{@ @ }@i{rts-native (default)} |
| @item @code{@ @ @ @ }Tasking @tab native MacOS threads |
| @item @code{@ @ @ @ }Exceptions @tab ZCX |
| @* |
| @item @b{sparc-solaris} @tab |
| @item @code{@ @ }@i{rts-native (default)} |
| @item @code{@ @ @ @ }Tasking @tab native Solaris threads library |
| @item @code{@ @ @ @ }Exceptions @tab ZCX |
| @* |
| @item @code{@ @ }@i{rts-m64} |
| @item @code{@ @ @ @ }Tasking @tab native Solaris threads library |
| @item @code{@ @ @ @ }Exceptions @tab ZCX |
| @item @code{@ @ @ @ }Constraints @tab Use only when compiling in 64-bit mode; |
| @item @tab Use only on Solaris 8 or later. |
| @item @tab @xref{Building and Debugging 64-bit Applications}, for details. |
| @* |
| @item @code{@ @ }@i{rts-pthread} |
| @item @code{@ @ @ @ }Tasking @tab pthread library |
| @item @code{@ @ @ @ }Exceptions @tab ZCX |
| @* |
| @item @code{@ @ }@i{rts-sjlj} |
| @item @code{@ @ @ @ }Tasking @tab native Solaris threads library |
| @item @code{@ @ @ @ }Exceptions @tab SJLJ |
| @* |
| @item @b{x86-linux} |
| @item @code{@ @ }@i{rts-native (default)} |
| @item @code{@ @ @ @ }Tasking @tab pthread library |
| @item @code{@ @ @ @ }Exceptions @tab ZCX |
| @* |
| @item @code{@ @ }@i{rts-sjlj} |
| @item @code{@ @ @ @ }Tasking @tab pthread library |
| @item @code{@ @ @ @ }Exceptions @tab SJLJ |
| @* |
| @item @b{x86-lynx} |
| @item @code{@ @ }@i{rts-native (default)} |
| @item @code{@ @ @ @ }Tasking @tab native LynxOS threads |
| @item @code{@ @ @ @ }Exceptions @tab SJLJ |
| @* |
| @item @b{x86-windows} |
| @item @code{@ @ }@i{rts-native (default)} |
| @item @code{@ @ @ @ }Tasking @tab native Win32 threads |
| @item @code{@ @ @ @ }Exceptions @tab ZCX |
| @* |
| @item @code{@ @ }@i{rts-sjlj (default)} |
| @item @code{@ @ @ @ }Tasking @tab native Win32 threads |
| @item @code{@ @ @ @ }Exceptions @tab SJLJ |
| @* |
| @item @b{x86_64-linux} |
| @item @code{@ @ }@i{rts-native (default)} |
| @item @code{@ @ @ @ }Tasking @tab pthread library |
| @item @code{@ @ @ @ }Exceptions @tab ZCX |
| @* |
| @item @code{@ @ }@i{rts-sjlj} |
| @item @code{@ @ @ @ }Tasking @tab pthread library |
| @item @code{@ @ @ @ }Exceptions @tab SJLJ |
| @* |
| @end multitable |
| |
| @node Specifying a Run-Time Library |
| @section Specifying a Run-Time Library |
| |
| @noindent |
| The @file{adainclude} subdirectory containing the sources of the GNAT |
| run-time library, and the @file{adalib} subdirectory containing the |
| @file{ALI} files and the static and/or shared GNAT library, are located |
| in the gcc target-dependent area: |
| |
| @smallexample |
| target=$prefix/lib/gcc-lib/gcc-@i{dumpmachine}/gcc-@i{dumpversion}/ |
| @end smallexample |
| |
| @noindent |
| As indicated above, on some platforms several run-time libraries are supplied. |
| These libraries are installed in the target dependent area and |
| contain a complete source and binary subdirectory. The detailed description |
| below explains the differences between the different libraries in terms of |
| their thread support. |
| |
| The default run-time library (when GNAT is installed) is @emph{rts-native}. |
| This default run time is selected by the means of soft links. |
| For example on x86-linux: |
| |
| @smallexample |
| @group |
| $(target-dir) |
| | |
| +--- adainclude----------+ |
| | | |
| +--- adalib-----------+ | |
| | | | |
| +--- rts-native | | |
| | | | | |
| | +--- adainclude <---+ |
| | | | |
| | +--- adalib <----+ |
| | |
| +--- rts-sjlj |
| | |
| +--- adainclude |
| | |
| +--- adalib |
| @end group |
| @end smallexample |
| |
| @noindent |
| If the @i{rts-sjlj} library is to be selected on a permanent basis, |
| these soft links can be modified with the following commands: |
| |
| @smallexample |
| $ cd $target |
| $ rm -f adainclude adalib |
| $ ln -s rts-sjlj/adainclude adainclude |
| $ ln -s rts-sjlj/adalib adalib |
| @end smallexample |
| |
| @noindent |
| Alternatively, you can specify @file{rts-sjlj/adainclude} in the file |
| @file{$target/ada_source_path} and @file{rts-sjlj/adalib} in |
| @file{$target/ada_object_path}. |
| |
| Selecting another run-time library temporarily can be |
| achieved by the regular mechanism for GNAT object or source path selection: |
| |
| @itemize @bullet |
| @item |
| Set the environment variables: |
| |
| @smallexample |
| $ ADA_INCLUDE_PATH=$target/rts-sjlj/adainclude:$ADA_INCLUDE_PATH |
| $ ADA_OBJECTS_PATH=$target/rts-sjlj/adalib:$ADA_OBJECTS_PATH |
| $ export ADA_INCLUDE_PATH ADA_OBJECTS_PATH |
| @end smallexample |
| |
| @item |
| Use @option{-aI$target/rts-sjlj/adainclude} |
| and @option{-aO$target/rts-sjlj/adalib} |
| on the @command{gnatmake} command line |
| |
| @item |
| Use the switch @option{--RTS}; e.g., @option{--RTS=sjlj} |
| @cindex @option{--RTS} option |
| @end itemize |
| |
| @node Choosing the Scheduling Policy |
| @section Choosing the Scheduling Policy |
| |
| @noindent |
| When using a POSIX threads implementation, you have a choice of several |
| scheduling policies: @code{SCHED_FIFO}, |
| @cindex @code{SCHED_FIFO} scheduling policy |
| @code{SCHED_RR} |
| @cindex @code{SCHED_RR} scheduling policy |
| and @code{SCHED_OTHER}. |
| @cindex @code{SCHED_OTHER} scheduling policy |
| Typically, the default is @code{SCHED_OTHER}, while using @code{SCHED_FIFO} |
| or @code{SCHED_RR} requires special (e.g., root) privileges. |
| |
| By default, GNAT uses the @code{SCHED_OTHER} policy. To specify |
| @code{SCHED_FIFO}, |
| @cindex @code{SCHED_FIFO} scheduling policy |
| you can use one of the following: |
| |
| @itemize @bullet |
| @item |
| @code{pragma Time_Slice (0.0)} |
| @cindex pragma Time_Slice |
| @item |
| the corresponding binder option @option{-T0} |
| @cindex @option{-T0} option |
| @item |
| @code{pragma Task_Dispatching_Policy (FIFO_Within_Priorities)} |
| @cindex pragma Task_Dispatching_Policy |
| @end itemize |
| |
| @noindent |
| To specify @code{SCHED_RR}, |
| @cindex @code{SCHED_RR} scheduling policy |
| you should use @code{pragma Time_Slice} with a |
| value greater than @code{0.0}, or else use the corresponding @option{-T} |
| binder option. |
| |
| @node Solaris-Specific Considerations |
| @section Solaris-Specific Considerations |
| @cindex Solaris Sparc threads libraries |
| |
| @noindent |
| This section addresses some topics related to the various threads libraries |
| on Sparc Solaris and then provides some information on building and |
| debugging 64-bit applications. |
| |
| @menu |
| * Solaris Threads Issues:: |
| * Building and Debugging 64-bit Applications:: |
| @end menu |
| |
| @node Solaris Threads Issues |
| @subsection Solaris Threads Issues |
| |
| @noindent |
| GNAT under Solaris comes with an alternate tasking run-time library |
| based on POSIX threads --- @emph{rts-pthread}. |
| @cindex rts-pthread threads library |
| This run-time library has the advantage of being mostly shared across all |
| POSIX-compliant thread implementations, and it also provides under |
| @w{Solaris 8} the @code{PTHREAD_PRIO_INHERIT} |
| @cindex @code{PTHREAD_PRIO_INHERIT} policy (under rts-pthread) |
| and @code{PTHREAD_PRIO_PROTECT} |
| @cindex @code{PTHREAD_PRIO_PROTECT} policy (under rts-pthread) |
| semantics that can be selected using the predefined pragma |
| @code{Locking_Policy} |
| @cindex pragma Locking_Policy (under rts-pthread) |
| with respectively |
| @code{Inheritance_Locking} and @code{Ceiling_Locking} as the policy. |
| @cindex @code{Inheritance_Locking} (under rts-pthread) |
| @cindex @code{Ceiling_Locking} (under rts-pthread) |
| |
| As explained above, the native run-time library is based on the Solaris thread |
| library (@code{libthread}) and is the default library. |
| |
| When the Solaris threads library is used (this is the default), programs |
| compiled with GNAT can automatically take advantage of |
| and can thus execute on multiple processors. |
| The user can alternatively specify a processor on which the program should run |
| to emulate a single-processor system. The multiprocessor / uniprocessor choice |
| is made by |
| setting the environment variable @code{GNAT_PROCESSOR} |
| @cindex @code{GNAT_PROCESSOR} environment variable (on Sparc Solaris) |
| to one of the following: |
| |
| @table @code |
| @item -2 |
| Use the default configuration (run the program on all |
| available processors) - this is the same as having |
| @code{GNAT_PROCESSOR} unset |
| |
| @item -1 |
| Let the run-time implementation choose one processor and run the program on |
| that processor |
| |
| @item 0 .. Last_Proc |
| Run the program on the specified processor. |
| @code{Last_Proc} is equal to @code{_SC_NPROCESSORS_CONF - 1} |
| (where @code{_SC_NPROCESSORS_CONF} is a system variable). |
| @end table |
| |
| @node Building and Debugging 64-bit Applications |
| @subsection Building and Debugging 64-bit Applications |
| |
| @noindent |
| In a 64-bit application, all the sources involved must be compiled with the |
| @option{-m64} command-line option, and a specific GNAT library (compiled with |
| this option) is required. |
| The easiest way to build a 64bit application is to add |
| @option{-m64 --RTS=m64} to the @command{gnatmake} flags. |
| |
| To debug these applications, a special version of gdb called @command{gdb64} |
| needs to be used. |
| |
| To summarize, building and debugging a ``Hello World'' program in 64-bit mode |
| amounts to: |
| |
| @smallexample |
| $ gnatmake -m64 -g --RTS=m64 hello.adb |
| $ gdb64 hello |
| @end smallexample |
| |
| @node Linux-Specific Considerations |
| @section Linux-Specific Considerations |
| @cindex Linux threads libraries |
| |
| @noindent |
| On GNU/Linux without NPTL support (usually system with GNU C Library |
| older than 2.3), the signal model is not POSIX compliant, which means |
| that to send a signal to the process, you need to send the signal to all |
| threads, e.g. by using @code{killpg()}. |
| |
| @node AIX-Specific Considerations |
| @section AIX-Specific Considerations |
| @cindex AIX resolver library |
| |
| @noindent |
| On AIX, the resolver library initializes some internal structure on |
| the first call to @code{get*by*} functions, which are used to implement |
| @code{GNAT.Sockets.Get_Host_By_Name} and |
| @code{GNAT.Sockets.Get_Host_By_Addrss}. |
| If such initialization occurs within an Ada task, and the stack size for |
| the task is the default size, a stack overflow may occur. |
| |
| To avoid this overflow, the user should either ensure that the first call |
| to @code{GNAT.Sockets.Get_Host_By_Name} or |
| @code{GNAT.Sockets.Get_Host_By_Addrss} |
| occurs in the environment task, or use @code{pragma Storage_Size} to |
| specify a sufficiently large size for the stack of the task that contains |
| this call. |
| |
| @c ******************************* |
| @node Example of Binder Output File |
| @appendix Example of Binder Output File |
| |
| @noindent |
| This Appendix displays the source code for @command{gnatbind}'s output |
| file generated for a simple ``Hello World'' program. |
| Comments have been added for clarification purposes. |
| |
| @smallexample @c adanocomment |
| @iftex |
| @leftskip=0cm |
| @end iftex |
| -- The package is called Ada_Main unless this name is actually used |
| -- as a unit name in the partition, in which case some other unique |
| -- name is used. |
| |
| with System; |
| package ada_main is |
| |
| Elab_Final_Code : Integer; |
| pragma Import (C, Elab_Final_Code, "__gnat_inside_elab_final_code"); |
| |
| -- The main program saves the parameters (argument count, |
| -- argument values, environment pointer) in global variables |
| -- for later access by other units including |
| -- Ada.Command_Line. |
| |
| gnat_argc : Integer; |
| gnat_argv : System.Address; |
| gnat_envp : System.Address; |
| |
| -- The actual variables are stored in a library routine. This |
| -- is useful for some shared library situations, where there |
| -- are problems if variables are not in the library. |
| |
| pragma Import (C, gnat_argc); |
| pragma Import (C, gnat_argv); |
| pragma Import (C, gnat_envp); |
| |
| -- The exit status is similarly an external location |
| |
| gnat_exit_status : Integer; |
| pragma Import (C, gnat_exit_status); |
| |
| GNAT_Version : constant String := |
| "GNAT Version: 3.15w (20010315)"; |
| pragma Export (C, GNAT_Version, "__gnat_version"); |
| |
| -- This is the generated adafinal routine that performs |
| -- finalization at the end of execution. In the case where |
| -- Ada is the main program, this main program makes a call |
| -- to adafinal at program termination. |
| |
| procedure adafinal; |
| pragma Export (C, adafinal, "adafinal"); |
| |
| -- This is the generated adainit routine that performs |
| -- initialization at the start of execution. In the case |
| -- where Ada is the main program, this main program makes |
| -- a call to adainit at program startup. |
| |
| procedure adainit; |
| pragma Export (C, adainit, "adainit"); |
| |
| -- This routine is called at the start of execution. It is |
| -- a dummy routine that is used by the debugger to breakpoint |
| -- at the start of execution. |
| |
| procedure Break_Start; |
| pragma Import (C, Break_Start, "__gnat_break_start"); |
| |
| -- This is the actual generated main program (it would be |
| -- suppressed if the no main program switch were used). As |
| -- required by standard system conventions, this program has |
| -- the external name main. |
| |
| function main |
| (argc : Integer; |
| argv : System.Address; |
| envp : System.Address) |
| return Integer; |
| pragma Export (C, main, "main"); |
| |
| -- The following set of constants give the version |
| -- identification values for every unit in the bound |
| -- partition. This identification is computed from all |
| -- dependent semantic units, and corresponds to the |
| -- string that would be returned by use of the |
| -- Body_Version or Version attributes. |
| |
| type Version_32 is mod 2 ** 32; |
| u00001 : constant Version_32 := 16#7880BEB3#; |
| u00002 : constant Version_32 := 16#0D24CBD0#; |
| u00003 : constant Version_32 := 16#3283DBEB#; |
| u00004 : constant Version_32 := 16#2359F9ED#; |
| u00005 : constant Version_32 := 16#664FB847#; |
| u00006 : constant Version_32 := 16#68E803DF#; |
| u00007 : constant Version_32 := 16#5572E604#; |
| u00008 : constant Version_32 := 16#46B173D8#; |
| u00009 : constant Version_32 := 16#156A40CF#; |
| u00010 : constant Version_32 := 16#033DABE0#; |
| u00011 : constant Version_32 := 16#6AB38FEA#; |
| u00012 : constant Version_32 := 16#22B6217D#; |
| u00013 : constant Version_32 := 16#68A22947#; |
| u00014 : constant Version_32 := 16#18CC4A56#; |
| u00015 : constant Version_32 := 16#08258E1B#; |
| u00016 : constant Version_32 := 16#367D5222#; |
| u00017 : constant Version_32 := 16#20C9ECA4#; |
| u00018 : constant Version_32 := 16#50D32CB6#; |
| u00019 : constant Version_32 := 16#39A8BB77#; |
| u00020 : constant Version_32 := 16#5CF8FA2B#; |
| u00021 : constant Version_32 := 16#2F1EB794#; |
| u00022 : constant Version_32 := 16#31AB6444#; |
| u00023 : constant Version_32 := 16#1574B6E9#; |
| u00024 : constant Version_32 := 16#5109C189#; |
| u00025 : constant Version_32 := 16#56D770CD#; |
| u00026 : constant Version_32 := 16#02F9DE3D#; |
| u00027 : constant Version_32 := 16#08AB6B2C#; |
| u00028 : constant Version_32 := 16#3FA37670#; |
| u00029 : constant Version_32 := 16#476457A0#; |
| u00030 : constant Version_32 := 16#731E1B6E#; |
| u00031 : constant Version_32 := 16#23C2E789#; |
| u00032 : constant Version_32 := 16#0F1BD6A1#; |
| u00033 : constant Version_32 := 16#7C25DE96#; |
| u00034 : constant Version_32 := 16#39ADFFA2#; |
| u00035 : constant Version_32 := 16#571DE3E7#; |
| u00036 : constant Version_32 := 16#5EB646AB#; |
| u00037 : constant Version_32 := 16#4249379B#; |
| u00038 : constant Version_32 := 16#0357E00A#; |
| u00039 : constant Version_32 := 16#3784FB72#; |
| u00040 : constant Version_32 := 16#2E723019#; |
| u00041 : constant Version_32 := 16#623358EA#; |
| u00042 : constant Version_32 := 16#107F9465#; |
| u00043 : constant Version_32 := 16#6843F68A#; |
| u00044 : constant Version_32 := 16#63305874#; |
| u00045 : constant Version_32 := 16#31E56CE1#; |
| u00046 : constant Version_32 := 16#02917970#; |
| u00047 : constant Version_32 := 16#6CCBA70E#; |
| u00048 : constant Version_32 := 16#41CD4204#; |
| u00049 : constant Version_32 := 16#572E3F58#; |
| u00050 : constant Version_32 := 16#20729FF5#; |
| u00051 : constant Version_32 := 16#1D4F93E8#; |
| u00052 : constant Version_32 := 16#30B2EC3D#; |
| u00053 : constant Version_32 := 16#34054F96#; |
| u00054 : constant Version_32 := 16#5A199860#; |
| u00055 : constant Version_32 := 16#0E7F912B#; |
| u00056 : constant Version_32 := 16#5760634A#; |
| u00057 : constant Version_32 := 16#5D851835#; |
| |
| -- The following Export pragmas export the version numbers |
| -- with symbolic names ending in B (for body) or S |
| -- (for spec) so that they can be located in a link. The |
| -- information provided here is sufficient to track down |
| -- the exact versions of units used in a given build. |
| |
| pragma Export (C, u00001, "helloB"); |
| pragma Export (C, u00002, "system__standard_libraryB"); |
| pragma Export (C, u00003, "system__standard_libraryS"); |
| pragma Export (C, u00004, "adaS"); |
| pragma Export (C, u00005, "ada__text_ioB"); |
| pragma Export (C, u00006, "ada__text_ioS"); |
| pragma Export (C, u00007, "ada__exceptionsB"); |
| pragma Export (C, u00008, "ada__exceptionsS"); |
| pragma Export (C, u00009, "gnatS"); |
| pragma Export (C, u00010, "gnat__heap_sort_aB"); |
| pragma Export (C, u00011, "gnat__heap_sort_aS"); |
| pragma Export (C, u00012, "systemS"); |
| pragma Export (C, u00013, "system__exception_tableB"); |
| pragma Export (C, u00014, "system__exception_tableS"); |
| pragma Export (C, u00015, "gnat__htableB"); |
| pragma Export (C, u00016, "gnat__htableS"); |
| pragma Export (C, u00017, "system__exceptionsS"); |
| pragma Export (C, u00018, "system__machine_state_operationsB"); |
| pragma Export (C, u00019, "system__machine_state_operationsS"); |
| pragma Export (C, u00020, "system__machine_codeS"); |
| pragma Export (C, u00021, "system__storage_elementsB"); |
| pragma Export (C, u00022, "system__storage_elementsS"); |
| pragma Export (C, u00023, "system__secondary_stackB"); |
| pragma Export (C, u00024, "system__secondary_stackS"); |
| pragma Export (C, u00025, "system__parametersB"); |
| pragma Export (C, u00026, "system__parametersS"); |
| pragma Export (C, u00027, "system__soft_linksB"); |
| pragma Export (C, u00028, "system__soft_linksS"); |
| pragma Export (C, u00029, "system__stack_checkingB"); |
| pragma Export (C, u00030, "system__stack_checkingS"); |
| pragma Export (C, u00031, "system__tracebackB"); |
| pragma Export (C, u00032, "system__tracebackS"); |
| pragma Export (C, u00033, "ada__streamsS"); |
| pragma Export (C, u00034, "ada__tagsB"); |
| pragma Export (C, u00035, "ada__tagsS"); |
| pragma Export (C, u00036, "system__string_opsB"); |
| pragma Export (C, u00037, "system__string_opsS"); |
| pragma Export (C, u00038, "interfacesS"); |
| pragma Export (C, u00039, "interfaces__c_streamsB"); |
| pragma Export (C, u00040, "interfaces__c_streamsS"); |
| pragma Export (C, u00041, "system__file_ioB"); |
| pragma Export (C, u00042, "system__file_ioS"); |
| pragma Export (C, u00043, "ada__finalizationB"); |
| pragma Export (C, u00044, "ada__finalizationS"); |
| pragma Export (C, u00045, "system__finalization_rootB"); |
| pragma Export (C, u00046, "system__finalization_rootS"); |
| pragma Export (C, u00047, "system__finalization_implementationB"); |
| pragma Export (C, u00048, "system__finalization_implementationS"); |
| pragma Export (C, u00049, "system__string_ops_concat_3B"); |
| pragma Export (C, u00050, "system__string_ops_concat_3S"); |
| pragma Export (C, u00051, "system__stream_attributesB"); |
| pragma Export (C, u00052, "system__stream_attributesS"); |
| pragma Export (C, u00053, "ada__io_exceptionsS"); |
| pragma Export (C, u00054, "system__unsigned_typesS"); |
| pragma Export (C, u00055, "system__file_control_blockS"); |
| pragma Export (C, u00056, "ada__finalization__list_controllerB"); |
| pragma Export (C, u00057, "ada__finalization__list_controllerS"); |
| |
| -- BEGIN ELABORATION ORDER |
| -- ada (spec) |
| -- gnat (spec) |
| -- gnat.heap_sort_a (spec) |
| -- gnat.heap_sort_a (body) |
| -- gnat.htable (spec) |
| -- gnat.htable (body) |
| -- interfaces (spec) |
| -- system (spec) |
| -- system.machine_code (spec) |
| -- system.parameters (spec) |
| -- system.parameters (body) |
| -- interfaces.c_streams (spec) |
| -- interfaces.c_streams (body) |
| -- system.standard_library (spec) |
| -- ada.exceptions (spec) |
| -- system.exception_table (spec) |
| -- system.exception_table (body) |
| -- ada.io_exceptions (spec) |
| -- system.exceptions (spec) |
| -- system.storage_elements (spec) |
| -- system.storage_elements (body) |
| -- system.machine_state_operations (spec) |
| -- system.machine_state_operations (body) |
| -- system.secondary_stack (spec) |
| -- system.stack_checking (spec) |
| -- system.soft_links (spec) |
| -- system.soft_links (body) |
| -- system.stack_checking (body) |
| -- system.secondary_stack (body) |
| -- system.standard_library (body) |
| -- system.string_ops (spec) |
| -- system.string_ops (body) |
| -- ada.tags (spec) |
| -- ada.tags (body) |
| -- ada.streams (spec) |
| -- system.finalization_root (spec) |
| -- system.finalization_root (body) |
| -- system.string_ops_concat_3 (spec) |
| -- system.string_ops_concat_3 (body) |
| -- system.traceback (spec) |
| -- system.traceback (body) |
| -- ada.exceptions (body) |
| -- system.unsigned_types (spec) |
| -- system.stream_attributes (spec) |
| -- system.stream_attributes (body) |
| -- system.finalization_implementation (spec) |
| -- system.finalization_implementation (body) |
| -- ada.finalization (spec) |
| -- ada.finalization (body) |
| -- ada.finalization.list_controller (spec) |
| -- ada.finalization.list_controller (body) |
| -- system.file_control_block (spec) |
| -- system.file_io (spec) |
| -- system.file_io (body) |
| -- ada.text_io (spec) |
| -- ada.text_io (body) |
| -- hello (body) |
| -- END ELABORATION ORDER |
| |
| end ada_main; |
| |
| -- The following source file name pragmas allow the generated file |
| -- names to be unique for different main programs. They are needed |
| -- since the package name will always be Ada_Main. |
| |
| pragma Source_File_Name (ada_main, Spec_File_Name => "b~hello.ads"); |
| pragma Source_File_Name (ada_main, Body_File_Name => "b~hello.adb"); |
| |
| -- Generated package body for Ada_Main starts here |
| |
| package body ada_main is |
| |
| -- The actual finalization is performed by calling the |
| -- library routine in System.Standard_Library.Adafinal |
| |
| procedure Do_Finalize; |
| pragma Import (C, Do_Finalize, "system__standard_library__adafinal"); |
| |
| ------------- |
| -- adainit -- |
| ------------- |
| |
| @findex adainit |
| procedure adainit is |
| |
| -- These booleans are set to True once the associated unit has |
| -- been elaborated. It is also used to avoid elaborating the |
| -- same unit twice. |
| |
| E040 : Boolean; |
| pragma Import (Ada, E040, "interfaces__c_streams_E"); |
| |
| E008 : Boolean; |
| pragma Import (Ada, E008, "ada__exceptions_E"); |
| |
| E014 : Boolean; |
| pragma Import (Ada, E014, "system__exception_table_E"); |
| |
| E053 : Boolean; |
| pragma Import (Ada, E053, "ada__io_exceptions_E"); |
| |
| E017 : Boolean; |
| pragma Import (Ada, E017, "system__exceptions_E"); |
| |
| E024 : Boolean; |
| pragma Import (Ada, E024, "system__secondary_stack_E"); |
| |
| E030 : Boolean; |
| pragma Import (Ada, E030, "system__stack_checking_E"); |
| |
| E028 : Boolean; |
| pragma Import (Ada, E028, "system__soft_links_E"); |
| |
| E035 : Boolean; |
| pragma Import (Ada, E035, "ada__tags_E"); |
| |
| E033 : Boolean; |
| pragma Import (Ada, E033, "ada__streams_E"); |
| |
| E046 : Boolean; |
| pragma Import (Ada, E046, "system__finalization_root_E"); |
| |
| E048 : Boolean; |
| pragma Import (Ada, E048, "system__finalization_implementation_E"); |
| |
| E044 : Boolean; |
| pragma Import (Ada, E044, "ada__finalization_E"); |
| |
| E057 : Boolean; |
| pragma Import (Ada, E057, "ada__finalization__list_controller_E"); |
| |
| E055 : Boolean; |
| pragma Import (Ada, E055, "system__file_control_block_E"); |
| |
| E042 : Boolean; |
| pragma Import (Ada, E042, "system__file_io_E"); |
| |
| E006 : Boolean; |
| pragma Import (Ada, E006, "ada__text_io_E"); |
| |
| -- Set_Globals is a library routine that stores away the |
| -- value of the indicated set of global values in global |
| -- variables within the library. |
| |
| procedure Set_Globals |
| (Main_Priority : Integer; |
| Time_Slice_Value : Integer; |
| WC_Encoding : Character; |
| Locking_Policy : Character; |
| Queuing_Policy : Character; |
| Task_Dispatching_Policy : Character; |
| Adafinal : System.Address; |
| Unreserve_All_Interrupts : Integer; |
| Exception_Tracebacks : Integer); |
| @findex __gnat_set_globals |
| pragma Import (C, Set_Globals, "__gnat_set_globals"); |
| |
| -- SDP_Table_Build is a library routine used to build the |
| -- exception tables. See unit Ada.Exceptions in files |
| -- a-except.ads/adb for full details of how zero cost |
| -- exception handling works. This procedure, the call to |
| -- it, and the two following tables are all omitted if the |
| -- build is in longjmp/setjump exception mode. |
| |
| @findex SDP_Table_Build |
| @findex Zero Cost Exceptions |
| procedure SDP_Table_Build |
| (SDP_Addresses : System.Address; |
| SDP_Count : Natural; |
| Elab_Addresses : System.Address; |
| Elab_Addr_Count : Natural); |
| pragma Import (C, SDP_Table_Build, "__gnat_SDP_Table_Build"); |
| |
| -- Table of Unit_Exception_Table addresses. Used for zero |
| -- cost exception handling to build the top level table. |
| |
| ST : aliased constant array (1 .. 23) of System.Address := ( |
| Hello'UET_Address, |
| Ada.Text_Io'UET_Address, |
| Ada.Exceptions'UET_Address, |
| Gnat.Heap_Sort_A'UET_Address, |
| System.Exception_Table'UET_Address, |
| System.Machine_State_Operations'UET_Address, |
| System.Secondary_Stack'UET_Address, |
| System.Parameters'UET_Address, |
| System.Soft_Links'UET_Address, |
| System.Stack_Checking'UET_Address, |
| System.Traceback'UET_Address, |
| Ada.Streams'UET_Address, |
| Ada.Tags'UET_Address, |
| System.String_Ops'UET_Address, |
| Interfaces.C_Streams'UET_Address, |
| System.File_Io'UET_Address, |
| Ada.Finalization'UET_Address, |
| System.Finalization_Root'UET_Address, |
| System.Finalization_Implementation'UET_Address, |
| System.String_Ops_Concat_3'UET_Address, |
| System.Stream_Attributes'UET_Address, |
| System.File_Control_Block'UET_Address, |
| Ada.Finalization.List_Controller'UET_Address); |
| |
| -- Table of addresses of elaboration routines. Used for |
| -- zero cost exception handling to make sure these |
| -- addresses are included in the top level procedure |
| -- address table. |
| |
| EA : aliased constant array (1 .. 23) of System.Address := ( |
| adainit'Code_Address, |
| Do_Finalize'Code_Address, |
| Ada.Exceptions'Elab_Spec'Address, |
| System.Exceptions'Elab_Spec'Address, |
| Interfaces.C_Streams'Elab_Spec'Address, |
| System.Exception_Table'Elab_Body'Address, |
| Ada.Io_Exceptions'Elab_Spec'Address, |
| System.Stack_Checking'Elab_Spec'Address, |
| System.Soft_Links'Elab_Body'Address, |
| System.Secondary_Stack'Elab_Body'Address, |
| Ada.Tags'Elab_Spec'Address, |
| Ada.Tags'Elab_Body'Address, |
| Ada.Streams'Elab_Spec'Address, |
| System.Finalization_Root'Elab_Spec'Address, |
| Ada.Exceptions'Elab_Body'Address, |
| System.Finalization_Implementation'Elab_Spec'Address, |
| System.Finalization_Implementation'Elab_Body'Address, |
| Ada.Finalization'Elab_Spec'Address, |
| Ada.Finalization.List_Controller'Elab_Spec'Address, |
| System.File_Control_Block'Elab_Spec'Address, |
| System.File_Io'Elab_Body'Address, |
| Ada.Text_Io'Elab_Spec'Address, |
| Ada.Text_Io'Elab_Body'Address); |
| |
| -- Start of processing for adainit |
| |
| begin |
| |
| -- Call SDP_Table_Build to build the top level procedure |
| -- table for zero cost exception handling (omitted in |
| -- longjmp/setjump mode). |
| |
| SDP_Table_Build (ST'Address, 23, EA'Address, 23); |
| |
| -- Call Set_Globals to record various information for |
| -- this partition. The values are derived by the binder |
| -- from information stored in the ali files by the compiler. |
| |
| @findex __gnat_set_globals |
| Set_Globals |
| (Main_Priority => -1, |
| -- Priority of main program, -1 if no pragma Priority used |
| |
| Time_Slice_Value => -1, |
| -- Time slice from Time_Slice pragma, -1 if none used |
| |
| WC_Encoding => 'b', |
| -- Wide_Character encoding used, default is brackets |
| |
| Locking_Policy => ' ', |
| -- Locking_Policy used, default of space means not |
| -- specified, otherwise it is the first character of |
| -- the policy name. |
| |
| Queuing_Policy => ' ', |
| -- Queuing_Policy used, default of space means not |
| -- specified, otherwise it is the first character of |
| -- the policy name. |
| |
| Task_Dispatching_Policy => ' ', |
| -- Task_Dispatching_Policy used, default of space means |
| -- not specified, otherwise first character of the |
| -- policy name. |
| |
| Adafinal => System.Null_Address, |
| -- Address of Adafinal routine, not used anymore |
| |
| Unreserve_All_Interrupts => 0, |
| -- Set true if pragma Unreserve_All_Interrupts was used |
| |
| Exception_Tracebacks => 0); |
| -- Indicates if exception tracebacks are enabled |
| |
| Elab_Final_Code := 1; |
| |
| -- Now we have the elaboration calls for all units in the partition. |
| -- The Elab_Spec and Elab_Body attributes generate references to the |
| -- implicit elaboration procedures generated by the compiler for |
| -- each unit that requires elaboration. |
| |
| if not E040 then |
| Interfaces.C_Streams'Elab_Spec; |
| end if; |
| E040 := True; |
| if not E008 then |
| Ada.Exceptions'Elab_Spec; |
| end if; |
| if not E014 then |
| System.Exception_Table'Elab_Body; |
| E014 := True; |
| end if; |
| if not E053 then |
| Ada.Io_Exceptions'Elab_Spec; |
| E053 := True; |
| end if; |
| if not E017 then |
| System.Exceptions'Elab_Spec; |
| E017 := True; |
| end if; |
| if not E030 then |
| System.Stack_Checking'Elab_Spec; |
| end if; |
| if not E028 then |
| System.Soft_Links'Elab_Body; |
| E028 := True; |
| end if; |
| E030 := True; |
| if not E024 then |
| System.Secondary_Stack'Elab_Body; |
| E024 := True; |
| end if; |
| if not E035 then |
| Ada.Tags'Elab_Spec; |
| end if; |
| if not E035 then |
| Ada.Tags'Elab_Body; |
| E035 := True; |
| end if; |
| if not E033 then |
| Ada.Streams'Elab_Spec; |
| E033 := True; |
| end if; |
| if not E046 then |
| System.Finalization_Root'Elab_Spec; |
| end if; |
| E046 := True; |
| if not E008 then |
| Ada.Exceptions'Elab_Body; |
| E008 := True; |
| end if; |
| if not E048 then |
| System.Finalization_Implementation'Elab_Spec; |
| end if; |
| if not E048 then |
| System.Finalization_Implementation'Elab_Body; |
| E048 := True; |
| end if; |
| if not E044 then |
| Ada.Finalization'Elab_Spec; |
| end if; |
| E044 := True; |
| if not E057 then |
| Ada.Finalization.List_Controller'Elab_Spec; |
| end if; |
| E057 := True; |
| if not E055 then |
| System.File_Control_Block'Elab_Spec; |
| E055 := True; |
| end if; |
| if not E042 then |
| System.File_Io'Elab_Body; |
| E042 := True; |
| end if; |
| if not E006 then |
| Ada.Text_Io'Elab_Spec; |
| end if; |
| if not E006 then |
| Ada.Text_Io'Elab_Body; |
| E006 := True; |
| end if; |
| |
| Elab_Final_Code := 0; |
| end adainit; |
| |
| -------------- |
| -- adafinal -- |
| -------------- |
| |
| @findex adafinal |
| procedure adafinal is |
| begin |
| Do_Finalize; |
| end adafinal; |
| |
| ---------- |
| -- main -- |
| ---------- |
| |
| -- main is actually a function, as in the ANSI C standard, |
| -- defined to return the exit status. The three parameters |
| -- are the argument count, argument values and environment |
| -- pointer. |
| |
| @findex Main Program |
| function main |
| (argc : Integer; |
| argv : System.Address; |
| envp : System.Address) |
| return Integer |
| is |
| -- The initialize routine performs low level system |
| -- initialization using a standard library routine which |
| -- sets up signal handling and performs any other |
| -- required setup. The routine can be found in file |
| -- a-init.c. |
| |
| @findex __gnat_initialize |
| procedure initialize; |
| pragma Import (C, initialize, "__gnat_initialize"); |
| |
| -- The finalize routine performs low level system |
| -- finalization using a standard library routine. The |
| -- routine is found in file a-final.c and in the standard |
| -- distribution is a dummy routine that does nothing, so |
| -- really this is a hook for special user finalization. |
| |
| @findex __gnat_finalize |
| procedure finalize; |
| pragma Import (C, finalize, "__gnat_finalize"); |
| |
| -- We get to the main program of the partition by using |
| -- pragma Import because if we try to with the unit and |
| -- call it Ada style, then not only do we waste time |
| -- recompiling it, but also, we don't really know the right |
| -- switches (e.g. identifier character set) to be used |
| -- to compile it. |
| |
| procedure Ada_Main_Program; |
| pragma Import (Ada, Ada_Main_Program, "_ada_hello"); |
| |
| -- Start of processing for main |
| |
| begin |
| -- Save global variables |
| |
| gnat_argc := argc; |
| gnat_argv := argv; |
| gnat_envp := envp; |
| |
| -- Call low level system initialization |
| |
| Initialize; |
| |
| -- Call our generated Ada initialization routine |
| |
| adainit; |
| |
| -- This is the point at which we want the debugger to get |
| -- control |
| |
| Break_Start; |
| |
| -- Now we call the main program of the partition |
| |
| Ada_Main_Program; |
| |
| -- Perform Ada finalization |
| |
| adafinal; |
| |
| -- Perform low level system finalization |
| |
| Finalize; |
| |
| -- Return the proper exit status |
| return (gnat_exit_status); |
| end; |
| |
| -- This section is entirely comments, so it has no effect on the |
| -- compilation of the Ada_Main package. It provides the list of |
| -- object files and linker options, as well as some standard |
| -- libraries needed for the link. The gnatlink utility parses |
| -- this b~hello.adb file to read these comment lines to generate |
| -- the appropriate command line arguments for the call to the |
| -- system linker. The BEGIN/END lines are used for sentinels for |
| -- this parsing operation. |
| |
| -- The exact file names will of course depend on the environment, |
| -- host/target and location of files on the host system. |
| |
| @findex Object file list |
| -- BEGIN Object file/option list |
| -- ./hello.o |
| -- -L./ |
| -- -L/usr/local/gnat/lib/gcc-lib/i686-pc-linux-gnu/2.8.1/adalib/ |
| -- /usr/local/gnat/lib/gcc-lib/i686-pc-linux-gnu/2.8.1/adalib/libgnat.a |
| -- END Object file/option list |
| |
| end ada_main; |
| @end smallexample |
| |
| @noindent |
| The Ada code in the above example is exactly what is generated by the |
| binder. We have added comments to more clearly indicate the function |
| of each part of the generated @code{Ada_Main} package. |
| |
| The code is standard Ada in all respects, and can be processed by any |
| tools that handle Ada. In particular, it is possible to use the debugger |
| in Ada mode to debug the generated @code{Ada_Main} package. For example, |
| suppose that for reasons that you do not understand, your program is crashing |
| during elaboration of the body of @code{Ada.Text_IO}. To locate this bug, |
| you can place a breakpoint on the call: |
| |
| @smallexample @c ada |
| Ada.Text_Io'Elab_Body; |
| @end smallexample |
| |
| @noindent |
| and trace the elaboration routine for this package to find out where |
| the problem might be (more usually of course you would be debugging |
| elaboration code in your own application). |
| |
| @node Elaboration Order Handling in GNAT |
| @appendix Elaboration Order Handling in GNAT |
| @cindex Order of elaboration |
| @cindex Elaboration control |
| |
| @menu |
| * Elaboration Code in Ada 95:: |
| * Checking the Elaboration Order in Ada 95:: |
| * Controlling the Elaboration Order in Ada 95:: |
| * Controlling Elaboration in GNAT - Internal Calls:: |
| * Controlling Elaboration in GNAT - External Calls:: |
| * Default Behavior in GNAT - Ensuring Safety:: |
| * Treatment of Pragma Elaborate:: |
| * Elaboration Issues for Library Tasks:: |
| * Mixing Elaboration Models:: |
| * What to Do If the Default Elaboration Behavior Fails:: |
| * Elaboration for Access-to-Subprogram Values:: |
| * Summary of Procedures for Elaboration Control:: |
| * Other Elaboration Order Considerations:: |
| @end menu |
| |
| @noindent |
| This chapter describes the handling of elaboration code in Ada 95 and |
| in GNAT, and discusses how the order of elaboration of program units can |
| be controlled in GNAT, either automatically or with explicit programming |
| features. |
| |
| @node Elaboration Code in Ada 95 |
| @section Elaboration Code in Ada 95 |
| |
| @noindent |
| Ada 95 provides rather general mechanisms for executing code at elaboration |
| time, that is to say before the main program starts executing. Such code arises |
| in three contexts: |
| |
| @table @asis |
| @item Initializers for variables. |
| Variables declared at the library level, in package specs or bodies, can |
| require initialization that is performed at elaboration time, as in: |
| @smallexample @c ada |
| @cartouche |
| Sqrt_Half : Float := Sqrt (0.5); |
| @end cartouche |
| @end smallexample |
| |
| @item Package initialization code |
| Code in a @code{BEGIN-END} section at the outer level of a package body is |
| executed as part of the package body elaboration code. |
| |
| @item Library level task allocators |
| Tasks that are declared using task allocators at the library level |
| start executing immediately and hence can execute at elaboration time. |
| @end table |
| |
| @noindent |
| Subprogram calls are possible in any of these contexts, which means that |
| any arbitrary part of the program may be executed as part of the elaboration |
| code. It is even possible to write a program which does all its work at |
| elaboration time, with a null main program, although stylistically this |
| would usually be considered an inappropriate way to structure |
| a program. |
| |
| An important concern arises in the context of elaboration code: |
| we have to be sure that it is executed in an appropriate order. What we |
| have is a series of elaboration code sections, potentially one section |
| for each unit in the program. It is important that these execute |
| in the correct order. Correctness here means that, taking the above |
| example of the declaration of @code{Sqrt_Half}, |
| if some other piece of |
| elaboration code references @code{Sqrt_Half}, |
| then it must run after the |
| section of elaboration code that contains the declaration of |
| @code{Sqrt_Half}. |
| |
| There would never be any order of elaboration problem if we made a rule |
| that whenever you @code{with} a unit, you must elaborate both the spec and body |
| of that unit before elaborating the unit doing the @code{with}'ing: |
| |
| @smallexample @c ada |
| @group |
| @cartouche |
| with Unit_1; |
| package Unit_2 is ... |
| @end cartouche |
| @end group |
| @end smallexample |
| |
| @noindent |
| would require that both the body and spec of @code{Unit_1} be elaborated |
| before the spec of @code{Unit_2}. However, a rule like that would be far too |
| restrictive. In particular, it would make it impossible to have routines |
| in separate packages that were mutually recursive. |
| |
| You might think that a clever enough compiler could look at the actual |
| elaboration code and determine an appropriate correct order of elaboration, |
| but in the general case, this is not possible. Consider the following |
| example. |
| |
| In the body of @code{Unit_1}, we have a procedure @code{Func_1} |
| that references |
| the variable @code{Sqrt_1}, which is declared in the elaboration code |
| of the body of @code{Unit_1}: |
| |
| @smallexample @c ada |
| @cartouche |
| Sqrt_1 : Float := Sqrt (0.1); |
| @end cartouche |
| @end smallexample |
| |
| @noindent |
| The elaboration code of the body of @code{Unit_1} also contains: |
| |
| @smallexample @c ada |
| @group |
| @cartouche |
| if expression_1 = 1 then |
| Q := Unit_2.Func_2; |
| end if; |
| @end cartouche |
| @end group |
| @end smallexample |
| |
| @noindent |
| @code{Unit_2} is exactly parallel, |
| it has a procedure @code{Func_2} that references |
| the variable @code{Sqrt_2}, which is declared in the elaboration code of |
| the body @code{Unit_2}: |
| |
| @smallexample @c ada |
| @cartouche |
| Sqrt_2 : Float := Sqrt (0.1); |
| @end cartouche |
| @end smallexample |
| |
| @noindent |
| The elaboration code of the body of @code{Unit_2} also contains: |
| |
| @smallexample @c ada |
| @group |
| @cartouche |
| if expression_2 = 2 then |
| Q := Unit_1.Func_1; |
| end if; |
| @end cartouche |
| @end group |
| @end smallexample |
| |
| @noindent |
| Now the question is, which of the following orders of elaboration is |
| acceptable: |
| |
| @smallexample |
| @group |
| Spec of Unit_1 |
| Spec of Unit_2 |
| Body of Unit_1 |
| Body of Unit_2 |
| @end group |
| @end smallexample |
| |
| @noindent |
| or |
| |
| @smallexample |
| @group |
| Spec of Unit_2 |
| Spec of Unit_1 |
| Body of Unit_2 |
| Body of Unit_1 |
| @end group |
| @end smallexample |
| |
| @noindent |
| If you carefully analyze the flow here, you will see that you cannot tell |
| at compile time the answer to this question. |
| If @code{expression_1} is not equal to 1, |
| and @code{expression_2} is not equal to 2, |
| then either order is acceptable, because neither of the function calls is |
| executed. If both tests evaluate to true, then neither order is acceptable |
| and in fact there is no correct order. |
| |
| If one of the two expressions is true, and the other is false, then one |
| of the above orders is correct, and the other is incorrect. For example, |
| if @code{expression_1} = 1 and @code{expression_2} /= 2, |
| then the call to @code{Func_2} |
| will occur, but not the call to @code{Func_1.} |
| This means that it is essential |
| to elaborate the body of @code{Unit_1} before |
| the body of @code{Unit_2}, so the first |
| order of elaboration is correct and the second is wrong. |
| |
| By making @code{expression_1} and @code{expression_2} |
| depend on input data, or perhaps |
| the time of day, we can make it impossible for the compiler or binder |
| to figure out which of these expressions will be true, and hence it |
| is impossible to guarantee a safe order of elaboration at run time. |
| |
| @node Checking the Elaboration Order in Ada 95 |
| @section Checking the Elaboration Order in Ada 95 |
| |
| @noindent |
| In some languages that involve the same kind of elaboration problems, |
| e.g. Java and C++, the programmer is expected to worry about these |
| ordering problems himself, and it is common to |
| write a program in which an incorrect elaboration order gives |
| surprising results, because it references variables before they |
| are initialized. |
| Ada 95 is designed to be a safe language, and a programmer-beware approach is |
| clearly not sufficient. Consequently, the language provides three lines |
| of defense: |
| |
| @table @asis |
| @item Standard rules |
| Some standard rules restrict the possible choice of elaboration |
| order. In particular, if you @code{with} a unit, then its spec is always |
| elaborated before the unit doing the @code{with}. Similarly, a parent |
| spec is always elaborated before the child spec, and finally |
| a spec is always elaborated before its corresponding body. |
| |
| @item Dynamic elaboration checks |
| @cindex Elaboration checks |
| @cindex Checks, elaboration |
| Dynamic checks are made at run time, so that if some entity is accessed |
| before it is elaborated (typically by means of a subprogram call) |
| then the exception (@code{Program_Error}) is raised. |
| |
| @item Elaboration control |
| Facilities are provided for the programmer to specify the desired order |
| of elaboration. |
| @end table |
| |
| Let's look at these facilities in more detail. First, the rules for |
| dynamic checking. One possible rule would be simply to say that the |
| exception is raised if you access a variable which has not yet been |
| elaborated. The trouble with this approach is that it could require |
| expensive checks on every variable reference. Instead Ada 95 has two |
| rules which are a little more restrictive, but easier to check, and |
| easier to state: |
| |
| @table @asis |
| @item Restrictions on calls |
| A subprogram can only be called at elaboration time if its body |
| has been elaborated. The rules for elaboration given above guarantee |
| that the spec of the subprogram has been elaborated before the |
| call, but not the body. If this rule is violated, then the |
| exception @code{Program_Error} is raised. |
| |
| @item Restrictions on instantiations |
| A generic unit can only be instantiated if the body of the generic |
| unit has been elaborated. Again, the rules for elaboration given above |
| guarantee that the spec of the generic unit has been elaborated |
| before the instantiation, but not the body. If this rule is |
| violated, then the exception @code{Program_Error} is raised. |
| @end table |
| |
| @noindent |
| The idea is that if the body has been elaborated, then any variables |
| it references must have been elaborated; by checking for the body being |
| elaborated we guarantee that none of its references causes any |
| trouble. As we noted above, this is a little too restrictive, because a |
| subprogram that has no non-local references in its body may in fact be safe |
| to call. However, it really would be unsafe to rely on this, because |
| it would mean that the caller was aware of details of the implementation |
| in the body. This goes against the basic tenets of Ada. |
| |
| A plausible implementation can be described as follows. |
| A Boolean variable is associated with each subprogram |
| and each generic unit. This variable is initialized to False, and is set to |
| True at the point body is elaborated. Every call or instantiation checks the |
| variable, and raises @code{Program_Error} if the variable is False. |
| |
| Note that one might think that it would be good enough to have one Boolean |
| variable for each package, but that would not deal with cases of trying |
| to call a body in the same package as the call |
| that has not been elaborated yet. |
| Of course a compiler may be able to do enough analysis to optimize away |
| some of the Boolean variables as unnecessary, and @code{GNAT} indeed |
| does such optimizations, but still the easiest conceptual model is to |
| think of there being one variable per subprogram. |
| |
| @node Controlling the Elaboration Order in Ada 95 |
| @section Controlling the Elaboration Order in Ada 95 |
| |
| @noindent |
| In the previous section we discussed the rules in Ada 95 which ensure |
| that @code{Program_Error} is raised if an incorrect elaboration order is |
| chosen. This prevents erroneous executions, but we need mechanisms to |
| specify a correct execution and avoid the exception altogether. |
| To achieve this, Ada 95 provides a number of features for controlling |
| the order of elaboration. We discuss these features in this section. |
| |
| First, there are several ways of indicating to the compiler that a given |
| unit has no elaboration problems: |
| |
| @table @asis |
| @item packages that do not require a body |
| In Ada 95, a library package that does not require a body does not permit |
| a body. This means that if we have a such a package, as in: |
| |
| @smallexample @c ada |
| @group |
| @cartouche |
| package Definitions is |
| generic |
| type m is new integer; |
| package Subp is |
| type a is array (1 .. 10) of m; |
| type b is array (1 .. 20) of m; |
| end Subp; |
| end Definitions; |
| @end cartouche |
| @end group |
| @end smallexample |
| |
| @noindent |
| A package that @code{with}'s @code{Definitions} may safely instantiate |
| @code{Definitions.Subp} because the compiler can determine that there |
| definitely is no package body to worry about in this case |
| |
| @item pragma Pure |
| @cindex pragma Pure |
| @findex Pure |
| Places sufficient restrictions on a unit to guarantee that |
| no call to any subprogram in the unit can result in an |
| elaboration problem. This means that the compiler does not need |
| to worry about the point of elaboration of such units, and in |
| particular, does not need to check any calls to any subprograms |
| in this unit. |
| |
| @item pragma Preelaborate |
| @findex Preelaborate |
| @cindex pragma Preelaborate |
| This pragma places slightly less stringent restrictions on a unit than |
| does pragma Pure, |
| but these restrictions are still sufficient to ensure that there |
| are no elaboration problems with any calls to the unit. |
| |
| @item pragma Elaborate_Body |
| @findex Elaborate_Body |
| @cindex pragma Elaborate_Body |
| This pragma requires that the body of a unit be elaborated immediately |
| after its spec. Suppose a unit @code{A} has such a pragma, |
| and unit @code{B} does |
| a @code{with} of unit @code{A}. Recall that the standard rules require |
| the spec of unit @code{A} |
| to be elaborated before the @code{with}'ing unit; given the pragma in |
| @code{A}, we also know that the body of @code{A} |
| will be elaborated before @code{B}, so |
| that calls to @code{A} are safe and do not need a check. |
| @end table |
| |
| @noindent |
| Note that, |
| unlike pragma @code{Pure} and pragma @code{Preelaborate}, |
| the use of |
| @code{Elaborate_Body} does not guarantee that the program is |
| free of elaboration problems, because it may not be possible |
| to satisfy the requested elaboration order. |
| Let's go back to the example with @code{Unit_1} and @code{Unit_2}. |
| If a programmer |
| marks @code{Unit_1} as @code{Elaborate_Body}, |
| and not @code{Unit_2,} then the order of |
| elaboration will be: |
| |
| @smallexample |
| @group |
| Spec of Unit_2 |
| Spec of Unit_1 |
| Body of Unit_1 |
| Body of Unit_2 |
| @end group |
| @end smallexample |
| |
| @noindent |
| Now that means that the call to @code{Func_1} in @code{Unit_2} |
| need not be checked, |
| it must be safe. But the call to @code{Func_2} in |
| @code{Unit_1} may still fail if |
| @code{Expression_1} is equal to 1, |
| and the programmer must still take |
| responsibility for this not being the case. |
| |
| If all units carry a pragma @code{Elaborate_Body}, then all problems are |
| eliminated, except for calls entirely within a body, which are |
| in any case fully under programmer control. However, using the pragma |
| everywhere is not always possible. |
| In particular, for our @code{Unit_1}/@code{Unit_2} example, if |
| we marked both of them as having pragma @code{Elaborate_Body}, then |
| clearly there would be no possible elaboration order. |
| |
| The above pragmas allow a server to guarantee safe use by clients, and |
| clearly this is the preferable approach. Consequently a good rule in |
| Ada 95 is to mark units as @code{Pure} or @code{Preelaborate} if possible, |
| and if this is not possible, |
| mark them as @code{Elaborate_Body} if possible. |
| As we have seen, there are situations where neither of these |
| three pragmas can be used. |
| So we also provide methods for clients to control the |
| order of elaboration of the servers on which they depend: |
| |
| @table @asis |
| @item pragma Elaborate (unit) |
| @findex Elaborate |
| @cindex pragma Elaborate |
| This pragma is placed in the context clause, after a @code{with} clause, |
| and it requires that the body of the named unit be elaborated before |
| the unit in which the pragma occurs. The idea is to use this pragma |
| if the current unit calls at elaboration time, directly or indirectly, |
| some subprogram in the named unit. |
| |
| @item pragma Elaborate_All (unit) |
| @findex Elaborate_All |
| @cindex pragma Elaborate_All |
| This is a stronger version of the Elaborate pragma. Consider the |
| following example: |
| |
| @smallexample |
| Unit A @code{with}'s unit B and calls B.Func in elab code |
| Unit B @code{with}'s unit C, and B.Func calls C.Func |
| @end smallexample |
| |
| @noindent |
| Now if we put a pragma @code{Elaborate (B)} |
| in unit @code{A}, this ensures that the |
| body of @code{B} is elaborated before the call, but not the |
| body of @code{C}, so |
| the call to @code{C.Func} could still cause @code{Program_Error} to |
| be raised. |
| |
| The effect of a pragma @code{Elaborate_All} is stronger, it requires |
| not only that the body of the named unit be elaborated before the |
| unit doing the @code{with}, but also the bodies of all units that the |
| named unit uses, following @code{with} links transitively. For example, |
| if we put a pragma @code{Elaborate_All (B)} in unit @code{A}, |
| then it requires |
| not only that the body of @code{B} be elaborated before @code{A}, |
| but also the |
| body of @code{C}, because @code{B} @code{with}'s @code{C}. |
| @end table |
| |
| @noindent |
| We are now in a position to give a usage rule in Ada 95 for avoiding |
| elaboration problems, at least if dynamic dispatching and access to |
| subprogram values are not used. We will handle these cases separately |
| later. |
| |
| The rule is simple. If a unit has elaboration code that can directly or |
| indirectly make a call to a subprogram in a @code{with}'ed unit, or instantiate |
| a generic package in a @code{with}'ed unit, |
| then if the @code{with}'ed unit does not have |
| pragma @code{Pure} or @code{Preelaborate}, then the client should have |
| a pragma @code{Elaborate_All} |
| for the @code{with}'ed unit. By following this rule a client is |
| assured that calls can be made without risk of an exception. |
| |
| For generic subprogram instantiations, the rule can be relaxed to |
| require only a pragma @code{Elaborate} since elaborating the body |
| of a subprogram cannot cause any transitive elaboration (we are |
| not calling the subprogram in this case, just elaborating its |
| declaration). |
| |
| If this rule is not followed, then a program may be in one of four |
| states: |
| |
| @table @asis |
| @item No order exists |
| No order of elaboration exists which follows the rules, taking into |
| account any @code{Elaborate}, @code{Elaborate_All}, |
| or @code{Elaborate_Body} pragmas. In |
| this case, an Ada 95 compiler must diagnose the situation at bind |
| time, and refuse to build an executable program. |
| |
| @item One or more orders exist, all incorrect |
| One or more acceptable elaboration orders exists, and all of them |
| generate an elaboration order problem. In this case, the binder |
| can build an executable program, but @code{Program_Error} will be raised |
| when the program is run. |
| |
| @item Several orders exist, some right, some incorrect |
| One or more acceptable elaboration orders exists, and some of them |
| work, and some do not. The programmer has not controlled |
| the order of elaboration, so the binder may or may not pick one of |
| the correct orders, and the program may or may not raise an |
| exception when it is run. This is the worst case, because it means |
| that the program may fail when moved to another compiler, or even |
| another version of the same compiler. |
| |
| @item One or more orders exists, all correct |
| One ore more acceptable elaboration orders exist, and all of them |
| work. In this case the program runs successfully. This state of |
| affairs can be guaranteed by following the rule we gave above, but |
| may be true even if the rule is not followed. |
| @end table |
| |
| @noindent |
| Note that one additional advantage of following our rules on the use |
| of @code{Elaborate} and @code{Elaborate_All} |
| is that the program continues to stay in the ideal (all orders OK) state |
| even if maintenance |
| changes some bodies of some units. Conversely, if a program that does |
| not follow this rule happens to be safe at some point, this state of affairs |
| may deteriorate silently as a result of maintenance changes. |
| |
| You may have noticed that the above discussion did not mention |
| the use of @code{Elaborate_Body}. This was a deliberate omission. If you |
| @code{with} an @code{Elaborate_Body} unit, it still may be the case that |
| code in the body makes calls to some other unit, so it is still necessary |
| to use @code{Elaborate_All} on such units. |
| |
| @node Controlling Elaboration in GNAT - Internal Calls |
| @section Controlling Elaboration in GNAT - Internal Calls |
| |
| @noindent |
| In the case of internal calls, i.e. calls within a single package, the |
| programmer has full control over the order of elaboration, and it is up |
| to the programmer to elaborate declarations in an appropriate order. For |
| example writing: |
| |
| @smallexample @c ada |
| @group |
| @cartouche |
| function One return Float; |
| |
| Q : Float := One; |
| |
| function One return Float is |
| begin |
| return 1.0; |
| end One; |
| @end cartouche |
| @end group |
| @end smallexample |
| |
| @noindent |
| will obviously raise @code{Program_Error} at run time, because function |
| One will be called before its body is elaborated. In this case GNAT will |
| generate a warning that the call will raise @code{Program_Error}: |
| |
| @smallexample |
| @group |
| @cartouche |
| 1. procedure y is |
| 2. function One return Float; |
| 3. |
| 4. Q : Float := One; |
| | |
| >>> warning: cannot call "One" before body is elaborated |
| >>> warning: Program_Error will be raised at run time |
| |
| 5. |
| 6. function One return Float is |
| 7. begin |
| 8. return 1.0; |
| 9. end One; |
| 10. |
| 11. begin |
| 12. null; |
| 13. end; |
| @end cartouche |
| @end group |
| @end smallexample |
| |
| @noindent |
| Note that in this particular case, it is likely that the call is safe, because |
| the function @code{One} does not access any global variables. |
| Nevertheless in Ada 95, we do not want the validity of the check to depend on |
| the contents of the body (think about the separate compilation case), so this |
| is still wrong, as we discussed in the previous sections. |
| |
| The error is easily corrected by rearranging the declarations so that the |
| body of One appears before the declaration containing the call |
| (note that in Ada 95, |
| declarations can appear in any order, so there is no restriction that |
| would prevent this reordering, and if we write: |
| |
| @smallexample @c ada |
| @group |
| @cartouche |
| function One return Float; |
| |
| function One return Float is |
| begin |
| return 1.0; |
| end One; |
| |
| Q : Float := One; |
| @end cartouche |
| @end group |
| @end smallexample |
| |
| @noindent |
| then all is well, no warning is generated, and no |
| @code{Program_Error} exception |
| will be raised. |
| Things are more complicated when a chain of subprograms is executed: |
| |
| @smallexample @c ada |
| @group |
| @cartouche |
| function A return Integer; |
| function B return Integer; |
| function C return Integer; |
| |
| function B return Integer is begin return A; end; |
| function C return Integer is begin return B; end; |
| |
| X : Integer := C; |
| |
| function A return Integer is begin return 1; end; |
| @end cartouche |
| @end group |
| @end smallexample |
| |
| @noindent |
| Now the call to @code{C} |
| at elaboration time in the declaration of @code{X} is correct, because |
| the body of @code{C} is already elaborated, |
| and the call to @code{B} within the body of |
| @code{C} is correct, but the call |
| to @code{A} within the body of @code{B} is incorrect, because the body |
| of @code{A} has not been elaborated, so @code{Program_Error} |
| will be raised on the call to @code{A}. |
| In this case GNAT will generate a |
| warning that @code{Program_Error} may be |
| raised at the point of the call. Let's look at the warning: |
| |
| @smallexample |
| @group |
| @cartouche |
| 1. procedure x is |
| 2. function A return Integer; |
| 3. function B return Integer; |
| 4. function C return Integer; |
| 5. |
| 6. function B return Integer is begin return A; end; |
| | |
| >>> warning: call to "A" before body is elaborated may |
| raise Program_Error |
| >>> warning: "B" called at line 7 |
| >>> warning: "C" called at line 9 |
| |
| 7. function C return Integer is begin return B; end; |
| 8. |
| 9. X : Integer := C; |
| 10. |
| 11. function A return Integer is begin return 1; end; |
| 12. |
| 13. begin |
| 14. null; |
| 15. end; |
| @end cartouche |
| @end group |
| @end smallexample |
| |
| @noindent |
| Note that the message here says ``may raise'', instead of the direct case, |
| where the message says ``will be raised''. That's because whether |
| @code{A} is |
| actually called depends in general on run-time flow of control. |
| For example, if the body of @code{B} said |
| |
| @smallexample @c ada |
| @group |
| @cartouche |
| function B return Integer is |
| begin |
| if some-condition-depending-on-input-data then |
| return A; |
| else |
| return 1; |
| end if; |
| end B; |
| @end cartouche |
| @end group |
| @end smallexample |
| |
| @noindent |
| then we could not know until run time whether the incorrect call to A would |
| actually occur, so @code{Program_Error} might |
| or might not be raised. It is possible for a compiler to |
| do a better job of analyzing bodies, to |
| determine whether or not @code{Program_Error} |
| might be raised, but it certainly |
| couldn't do a perfect job (that would require solving the halting problem |
| and is provably impossible), and because this is a warning anyway, it does |
| not seem worth the effort to do the analysis. Cases in which it |
| would be relevant are rare. |
| |
| In practice, warnings of either of the forms given |
| above will usually correspond to |
| real errors, and should be examined carefully and eliminated. |
| In the rare case where a warning is bogus, it can be suppressed by any of |
| the following methods: |
| |
| @itemize @bullet |
| @item |
| Compile with the @option{-gnatws} switch set |
| |
| @item |
| Suppress @code{Elaboration_Check} for the called subprogram |
| |
| @item |
| Use pragma @code{Warnings_Off} to turn warnings off for the call |
| @end itemize |
| |
| @noindent |
| For the internal elaboration check case, |
| GNAT by default generates the |
| necessary run-time checks to ensure |
| that @code{Program_Error} is raised if any |
| call fails an elaboration check. Of course this can only happen if a |
| warning has been issued as described above. The use of pragma |
| @code{Suppress (Elaboration_Check)} may (but is not guaranteed to) suppress |
| some of these checks, meaning that it may be possible (but is not |
| guaranteed) for a program to be able to call a subprogram whose body |
| is not yet elaborated, without raising a @code{Program_Error} exception. |
| |
| @node Controlling Elaboration in GNAT - External Calls |
| @section Controlling Elaboration in GNAT - External Calls |
| |
| @noindent |
| The previous section discussed the case in which the execution of a |
| particular thread of elaboration code occurred entirely within a |
| single unit. This is the easy case to handle, because a programmer |
| has direct and total control over the order of elaboration, and |
| furthermore, checks need only be generated in cases which are rare |
| and which the compiler can easily detect. |
| The situation is more complex when separate compilation is taken into account. |
| Consider the following: |
| |
| @smallexample @c ada |
| @cartouche |
| @group |
| package Math is |
| function Sqrt (Arg : Float) return Float; |
| end Math; |
| |
| package body Math is |
| function Sqrt (Arg : Float) return Float is |
| begin |
| ... |
| end Sqrt; |
| end Math; |
| @end group |
| @group |
| with Math; |
| package Stuff is |
| X : Float := Math.Sqrt (0.5); |
| end Stuff; |
| |
| with Stuff; |
| procedure Main is |
| begin |
| ... |
| end Main; |
| @end group |
| @end cartouche |
| @end smallexample |
| |
| @noindent |
| where @code{Main} is the main program. When this program is executed, the |
| elaboration code must first be executed, and one of the jobs of the |
| binder is to determine the order in which the units of a program are |
| to be elaborated. In this case we have four units: the spec and body |
| of @code{Math}, |
| the spec of @code{Stuff} and the body of @code{Main}). |
| In what order should the four separate sections of elaboration code |
| be executed? |
| |
| There are some restrictions in the order of elaboration that the binder |
| can choose. In particular, if unit U has a @code{with} |
| for a package @code{X}, then you |
| are assured that the spec of @code{X} |
| is elaborated before U , but you are |
| not assured that the body of @code{X} |
| is elaborated before U. |
| This means that in the above case, the binder is allowed to choose the |
| order: |
| |
| @smallexample |
| spec of Math |
| spec of Stuff |
| body of Math |
| body of Main |
| @end smallexample |
| |
| @noindent |
| but that's not good, because now the call to @code{Math.Sqrt} |
| that happens during |
| the elaboration of the @code{Stuff} |
| spec happens before the body of @code{Math.Sqrt} is |
| elaborated, and hence causes @code{Program_Error} exception to be raised. |
| At first glance, one might say that the binder is misbehaving, because |
| obviously you want to elaborate the body of something you @code{with} |
| first, but |
| that is not a general rule that can be followed in all cases. Consider |
| |
| @smallexample @c ada |
| @group |
| @cartouche |
| package X is ... |
| |
| package Y is ... |
| |
| with X; |
| package body Y is ... |
| |
| with Y; |
| package body X is ... |
| @end cartouche |
| @end group |
| @end smallexample |
| |
| @noindent |
| This is a common arrangement, and, apart from the order of elaboration |
| problems that might arise in connection with elaboration code, this works fine. |
| A rule that says that you must first elaborate the body of anything you |
| @code{with} cannot work in this case: |
| the body of @code{X} @code{with}'s @code{Y}, |
| which means you would have to |
| elaborate the body of @code{Y} first, but that @code{with}'s @code{X}, |
| which means |
| you have to elaborate the body of @code{X} first, but ... and we have a |
| loop that cannot be broken. |
| |
| It is true that the binder can in many cases guess an order of elaboration |
| that is unlikely to cause a @code{Program_Error} |
| exception to be raised, and it tries to do so (in the |
| above example of @code{Math/Stuff/Spec}, the GNAT binder will |
| by default |
| elaborate the body of @code{Math} right after its spec, so all will be well). |
| |
| However, a program that blindly relies on the binder to be helpful can |
| get into trouble, as we discussed in the previous sections, so |
| GNAT |
| provides a number of facilities for assisting the programmer in |
| developing programs that are robust with respect to elaboration order. |
| |
| @node Default Behavior in GNAT - Ensuring Safety |
| @section Default Behavior in GNAT - Ensuring Safety |
| |
| @noindent |
| The default behavior in GNAT ensures elaboration safety. In its |
| default mode GNAT implements the |
| rule we previously described as the right approach. Let's restate it: |
| |
| @itemize |
| @item |
| @emph{If a unit has elaboration code that can directly or indirectly make a |
| call to a subprogram in a @code{with}'ed unit, or instantiate a generic |
| package in a @code{with}'ed unit, then if the @code{with}'ed unit |
| does not have pragma @code{Pure} or |
| @code{Preelaborate}, then the client should have an |
| @code{Elaborate_All} pragma for the @code{with}'ed unit.} |
| |
| @emph{In the case of instantiating a generic subprogram, it is always |
| sufficient to have only an @code{Elaborate} pragma for the |
| @code{with}'ed unit.} |
| @end itemize |
| |
| @noindent |
| By following this rule a client is assured that calls and instantiations |
| can be made without risk of an exception. |
| |
| In this mode GNAT traces all calls that are potentially made from |
| elaboration code, and puts in any missing implicit @code{Elaborate} |
| and @code{Elaborate_All} pragmas. |
| The advantage of this approach is that no elaboration problems |
| are possible if the binder can find an elaboration order that is |
| consistent with these implicit @code{Elaborate} and |
| @code{Elaborate_All} pragmas. The |
| disadvantage of this approach is that no such order may exist. |
| |
| If the binder does not generate any diagnostics, then it means that it has |
| found an elaboration order that is guaranteed to be safe. However, the binder |
| may still be relying on implicitly generated @code{Elaborate} and |
| @code{Elaborate_All} pragmas so portability to other compilers than GNAT is not |
| guaranteed. |
| |
| If it is important to guarantee portability, then the compilations should |
| use the |
| @option{-gnatwl} |
| (warn on elaboration problems) switch. This will cause warning messages |
| to be generated indicating the missing @code{Elaborate} and |
| @code{Elaborate_All} pragmas. |
| Consider the following source program: |
| |
| @smallexample @c ada |
| @group |
| @cartouche |
| with k; |
| package j is |
| m : integer := k.r; |
| end; |
| @end cartouche |
| @end group |
| @end smallexample |
| |
| @noindent |
| where it is clear that there |
| should be a pragma @code{Elaborate_All} |
| for unit @code{k}. An implicit pragma will be generated, and it is |
| likely that the binder will be able to honor it. However, if you want |
| to port this program to some other Ada compiler than GNAT. |
| it is safer to include the pragma explicitly in the source. If this |
| unit is compiled with the |
| @option{-gnatwl} |
| switch, then the compiler outputs a warning: |
| |
| @smallexample |
| @group |
| @cartouche |
| 1. with k; |
| 2. package j is |
| 3. m : integer := k.r; |
| | |
| >>> warning: call to "r" may raise Program_Error |
| >>> warning: missing pragma Elaborate_All for "k" |
| |
| 4. end; |
| @end cartouche |
| @end group |
| @end smallexample |
| |
| @noindent |
| and these warnings can be used as a guide for supplying manually |
| the missing pragmas. It is usually a bad idea to use this warning |
| option during development. That's because it will warn you when |
| you need to put in a pragma, but cannot warn you when it is time |
| to take it out. So the use of pragma @code{Elaborate_All} may lead to |
| unnecessary dependencies and even false circularities. |
| |
| This default mode is more restrictive than the Ada Reference |
| Manual, and it is possible to construct programs which will compile |
| using the dynamic model described there, but will run into a |
| circularity using the safer static model we have described. |
| |
| Of course any Ada compiler must be able to operate in a mode |
| consistent with the requirements of the Ada Reference Manual, |
| and in particular must have the capability of implementing the |
| standard dynamic model of elaboration with run-time checks. |
| |
| In GNAT, this standard mode can be achieved either by the use of |
| the @option{-gnatE} switch on the compiler (@command{gcc} or |
| @command{gnatmake}) command, or by the use of the configuration pragma: |
| |
| @smallexample @c ada |
| pragma Elaboration_Checks (RM); |
| @end smallexample |
| |
| @noindent |
| Either approach will cause the unit affected to be compiled using the |
| standard dynamic run-time elaboration checks described in the Ada |
| Reference Manual. The static model is generally preferable, since it |
| is clearly safer to rely on compile and link time checks rather than |
| run-time checks. However, in the case of legacy code, it may be |
| difficult to meet the requirements of the static model. This |
| issue is further discussed in |
| @ref{What to Do If the Default Elaboration Behavior Fails}. |
| |
| Note that the static model provides a strict subset of the allowed |
| behavior and programs of the Ada Reference Manual, so if you do |
| adhere to the static model and no circularities exist, |
| then you are assured that your program will |
| work using the dynamic model, providing that you remove any |
| pragma Elaborate statements from the source. |
| |
| @node Treatment of Pragma Elaborate |
| @section Treatment of Pragma Elaborate |
| @cindex Pragma Elaborate |
| |
| @noindent |
| The use of @code{pragma Elaborate} |
| should generally be avoided in Ada 95 programs. |
| The reason for this is that there is no guarantee that transitive calls |
| will be properly handled. Indeed at one point, this pragma was placed |
| in Annex J (Obsolescent Features), on the grounds that it is never useful. |
| |
| Now that's a bit restrictive. In practice, the case in which |
| @code{pragma Elaborate} is useful is when the caller knows that there |
| are no transitive calls, or that the called unit contains all necessary |
| transitive @code{pragma Elaborate} statements, and legacy code often |
| contains such uses. |
| |
| Strictly speaking the static mode in GNAT should ignore such pragmas, |
| since there is no assurance at compile time that the necessary safety |
| conditions are met. In practice, this would cause GNAT to be incompatible |
| with correctly written Ada 83 code that had all necessary |
| @code{pragma Elaborate} statements in place. Consequently, we made the |
| decision that GNAT in its default mode will believe that if it encounters |
| a @code{pragma Elaborate} then the programmer knows what they are doing, |
| and it will trust that no elaboration errors can occur. |
| |
| The result of this decision is two-fold. First to be safe using the |
| static mode, you should remove all @code{pragma Elaborate} statements. |
| Second, when fixing circularities in existing code, you can selectively |
| use @code{pragma Elaborate} statements to convince the static mode of |
| GNAT that it need not generate an implicit @code{pragma Elaborate_All} |
| statement. |
| |
| When using the static mode with @option{-gnatwl}, any use of |
| @code{pragma Elaborate} will generate a warning about possible |
| problems. |
| |
| @node Elaboration Issues for Library Tasks |
| @section Elaboration Issues for Library Tasks |
| @cindex Library tasks, elaboration issues |
| @cindex Elaboration of library tasks |
| |
| @noindent |
| In this section we examine special elaboration issues that arise for |
| programs that declare library level tasks. |
| |
| Generally the model of execution of an Ada program is that all units are |
| elaborated, and then execution of the program starts. However, the |
| declaration of library tasks definitely does not fit this model. The |
| reason for this is that library tasks start as soon as they are declared |
| (more precisely, as soon as the statement part of the enclosing package |
| body is reached), that is to say before elaboration |
| of the program is complete. This means that if such a task calls a |
| subprogram, or an entry in another task, the callee may or may not be |
| elaborated yet, and in the standard |
| Reference Manual model of dynamic elaboration checks, you can even |
| get timing dependent Program_Error exceptions, since there can be |
| a race between the elaboration code and the task code. |
| |
| The static model of elaboration in GNAT seeks to avoid all such |
| dynamic behavior, by being conservative, and the conservative |
| approach in this particular case is to assume that all the code |
| in a task body is potentially executed at elaboration time if |
| a task is declared at the library level. |
| |
| This can definitely result in unexpected circularities. Consider |
| the following example |
| |
| @smallexample @c ada |
| package Decls is |
| task Lib_Task is |
| entry Start; |
| end Lib_Task; |
| |
| type My_Int is new Integer; |
| |
| function Ident (M : My_Int) return My_Int; |
| end Decls; |
| |
| with Utils; |
| package body Decls is |
| task body Lib_Task is |
| begin |
| accept Start; |
| Utils.Put_Val (2); |
| end Lib_Task; |
| |
| function Ident (M : My_Int) return My_Int is |
| begin |
| return M; |
| end Ident; |
| end Decls; |
| |
| with Decls; |
| package Utils is |
| procedure Put_Val (Arg : Decls.My_Int); |
| end Utils; |
| |
| with Text_IO; |
| package body Utils is |
| procedure Put_Val (Arg : Decls.My_Int) is |
| begin |
| Text_IO.Put_Line (Decls.My_Int'Image (Decls.Ident (Arg))); |
| end Put_Val; |
| end Utils; |
| |
| with Decls; |
| procedure Main is |
| begin |
| Decls.Lib_Task.Start; |
| end; |
| @end smallexample |
| |
| @noindent |
| If the above example is compiled in the default static elaboration |
| mode, then a circularity occurs. The circularity comes from the call |
| @code{Utils.Put_Val} in the task body of @code{Decls.Lib_Task}. Since |
| this call occurs in elaboration code, we need an implicit pragma |
| @code{Elaborate_All} for @code{Utils}. This means that not only must |
| the spec and body of @code{Utils} be elaborated before the body |
| of @code{Decls}, but also the spec and body of any unit that is |
| @code{with'ed} by the body of @code{Utils} must also be elaborated before |
| the body of @code{Decls}. This is the transitive implication of |
| pragma @code{Elaborate_All} and it makes sense, because in general |
| the body of @code{Put_Val} might have a call to something in a |
| @code{with'ed} unit. |
| |
| In this case, the body of Utils (actually its spec) @code{with's} |
| @code{Decls}. Unfortunately this means that the body of @code{Decls} |
| must be elaborated before itself, in case there is a call from the |
| body of @code{Utils}. |
| |
| Here is the exact chain of events we are worrying about: |
| |
| @enumerate |
| @item |
| In the body of @code{Decls} a call is made from within the body of a library |
| task to a subprogram in the package @code{Utils}. Since this call may |
| occur at elaboration time (given that the task is activated at elaboration |
| time), we have to assume the worst, i.e. that the |
| call does happen at elaboration time. |
| |
| @item |
| This means that the body and spec of @code{Util} must be elaborated before |
| the body of @code{Decls} so that this call does not cause an access before |
| elaboration. |
| |
| @item |
| Within the body of @code{Util}, specifically within the body of |
| @code{Util.Put_Val} there may be calls to any unit @code{with}'ed |
| by this package. |
| |
| @item |
| One such @code{with}'ed package is package @code{Decls}, so there |
| might be a call to a subprogram in @code{Decls} in @code{Put_Val}. |
| In fact there is such a call in this example, but we would have to |
| assume that there was such a call even if it were not there, since |
| we are not supposed to write the body of @code{Decls} knowing what |
| is in the body of @code{Utils}; certainly in the case of the |
| static elaboration model, the compiler does not know what is in |
| other bodies and must assume the worst. |
| |
| @item |
| This means that the spec and body of @code{Decls} must also be |
| elaborated before we elaborate the unit containing the call, but |
| that unit is @code{Decls}! This means that the body of @code{Decls} |
| must be elaborated before itself, and that's a circularity. |
| @end enumerate |
| |
| @noindent |
| Indeed, if you add an explicit pragma @code{Elaborate_All} for @code{Utils} in |
| the body of @code{Decls} you will get a true Ada Reference Manual |
| circularity that makes the program illegal. |
| |
| In practice, we have found that problems with the static model of |
| elaboration in existing code often arise from library tasks, so |
| we must address this particular situation. |
| |
| Note that if we compile and run the program above, using the dynamic model of |
| elaboration (that is to say use the @option{-gnatE} switch), |
| then it compiles, binds, |
| links, and runs, printing the expected result of 2. Therefore in some sense |
| the circularity here is only apparent, and we need to capture |
| the properties of this program that distinguish it from other library-level |
| tasks that have real elaboration problems. |
| |
| We have four possible answers to this question: |
| |
| @itemize @bullet |
| |
| @item |
| Use the dynamic model of elaboration. |
| |
| If we use the @option{-gnatE} switch, then as noted above, the program works. |
| Why is this? If we examine the task body, it is apparent that the task cannot |
| proceed past the |
| @code{accept} statement until after elaboration has been completed, because |
| the corresponding entry call comes from the main program, not earlier. |
| This is why the dynamic model works here. But that's really giving |
| up on a precise analysis, and we prefer to take this approach only if we cannot |
| solve the |
| problem in any other manner. So let us examine two ways to reorganize |
| the program to avoid the potential elaboration problem. |
| |
| @item |
| Split library tasks into separate packages. |
| |
| Write separate packages, so that library tasks are isolated from |
| other declarations as much as possible. Let us look at a variation on |
| the above program. |
| |
| @smallexample @c ada |
| package Decls1 is |
| task Lib_Task is |
| entry Start; |
| end Lib_Task; |
| end Decls1; |
| |
| with Utils; |
| package body Decls1 is |
| task body Lib_Task is |
| begin |
| accept Start; |
| Utils.Put_Val (2); |
| end Lib_Task; |
| end Decls1; |
| |
| package Decls2 is |
| type My_Int is new Integer; |
| function Ident (M : My_Int) return My_Int; |
| end Decls2; |
| |
| with Utils; |
| package body Decls2 is |
| function Ident (M : My_Int) return My_Int is |
| begin |
| return M; |
| end Ident; |
| end Decls2; |
| |
| with Decls2; |
| package Utils is |
| procedure Put_Val (Arg : Decls2.My_Int); |
| end Utils; |
| |
| with Text_IO; |
| package body Utils is |
| procedure Put_Val (Arg : Decls2.My_Int) is |
| begin |
| Text_IO.Put_Line (Decls2.My_Int'Image (Decls2.Ident (Arg))); |
| end Put_Val; |
| end Utils; |
| |
| with Decls1; |
| procedure Main is |
| begin |
| Decls1.Lib_Task.Start; |
| end; |
| @end smallexample |
| |
| @noindent |
| All we have done is to split @code{Decls} into two packages, one |
| containing the library task, and one containing everything else. Now |
| there is no cycle, and the program compiles, binds, links and executes |
| using the default static model of elaboration. |
| |
| @item |
| Declare separate task types. |
| |
| A significant part of the problem arises because of the use of the |
| single task declaration form. This means that the elaboration of |
| the task type, and the elaboration of the task itself (i.e. the |
| creation of the task) happen at the same time. A good rule |
| of style in Ada 95 is to always create explicit task types. By |
| following the additional step of placing task objects in separate |
| packages from the task type declaration, many elaboration problems |
| are avoided. Here is another modified example of the example program: |
| |
| @smallexample @c ada |
| package Decls is |
| task type Lib_Task_Type is |
| entry Start; |
| end Lib_Task_Type; |
| |
| type My_Int is new Integer; |
| |
| function Ident (M : My_Int) return My_Int; |
| end Decls; |
| |
| with Utils; |
| package body Decls is |
| task body Lib_Task_Type is |
| begin |
| accept Start; |
| Utils.Put_Val (2); |
| end Lib_Task_Type; |
| |
| function Ident (M : My_Int) return My_Int is |
| begin |
| return M; |
| end Ident; |
| end Decls; |
| |
| with Decls; |
| package Utils is |
| procedure Put_Val (Arg : Decls.My_Int); |
| end Utils; |
| |
| with Text_IO; |
| package body Utils is |
| procedure Put_Val (Arg : Decls.My_Int) is |
| begin |
| Text_IO.Put_Line (Decls.My_Int'Image (Decls.Ident (Arg))); |
| end Put_Val; |
| end Utils; |
| |
| with Decls; |
| package Declst is |
| Lib_Task : Decls.Lib_Task_Type; |
| end Declst; |
| |
| with Declst; |
| procedure Main is |
| begin |
| Declst.Lib_Task.Start; |
| end; |
| @end smallexample |
| |
| @noindent |
| What we have done here is to replace the @code{task} declaration in |
| package @code{Decls} with a @code{task type} declaration. Then we |
| introduce a separate package @code{Declst} to contain the actual |
| task object. This separates the elaboration issues for |
| the @code{task type} |
| declaration, which causes no trouble, from the elaboration issues |
| of the task object, which is also unproblematic, since it is now independent |
| of the elaboration of @code{Utils}. |
| This separation of concerns also corresponds to |
| a generally sound engineering principle of separating declarations |
| from instances. This version of the program also compiles, binds, links, |
| and executes, generating the expected output. |
| |
| @item |
| Use No_Entry_Calls_In_Elaboration_Code restriction. |
| @cindex No_Entry_Calls_In_Elaboration_Code |
| |
| The previous two approaches described how a program can be restructured |
| to avoid the special problems caused by library task bodies. in practice, |
| however, such restructuring may be difficult to apply to existing legacy code, |
| so we must consider solutions that do not require massive rewriting. |
| |
| Let us consider more carefully why our original sample program works |
| under the dynamic model of elaboration. The reason is that the code |
| in the task body blocks immediately on the @code{accept} |
| statement. Now of course there is nothing to prohibit elaboration |
| code from making entry calls (for example from another library level task), |
| so we cannot tell in isolation that |
| the task will not execute the accept statement during elaboration. |
| |
| However, in practice it is very unusual to see elaboration code |
| make any entry calls, and the pattern of tasks starting |
| at elaboration time and then immediately blocking on @code{accept} or |
| @code{select} statements is very common. What this means is that |
| the compiler is being too pessimistic when it analyzes the |
| whole package body as though it might be executed at elaboration |
| time. |
| |
| If we know that the elaboration code contains no entry calls, (a very safe |
| assumption most of the time, that could almost be made the default |
| behavior), then we can compile all units of the program under control |
| of the following configuration pragma: |
| |
| @smallexample |
| pragma Restrictions (No_Entry_Calls_In_Elaboration_Code); |
| @end smallexample |
| |
| @noindent |
| This pragma can be placed in the @file{gnat.adc} file in the usual |
| manner. If we take our original unmodified program and compile it |
| in the presence of a @file{gnat.adc} containing the above pragma, |
| then once again, we can compile, bind, link, and execute, obtaining |
| the expected result. In the presence of this pragma, the compiler does |
| not trace calls in a task body, that appear after the first @code{accept} |
| or @code{select} statement, and therefore does not report a potential |
| circularity in the original program. |
| |
| The compiler will check to the extent it can that the above |
| restriction is not violated, but it is not always possible to do a |
| complete check at compile time, so it is important to use this |
| pragma only if the stated restriction is in fact met, that is to say |
| no task receives an entry call before elaboration of all units is completed. |
| |
| @end itemize |
| |
| @node Mixing Elaboration Models |
| @section Mixing Elaboration Models |
| @noindent |
| So far, we have assumed that the entire program is either compiled |
| using the dynamic model or static model, ensuring consistency. It |
| is possible to mix the two models, but rules have to be followed |
| if this mixing is done to ensure that elaboration checks are not |
| omitted. |
| |
| The basic rule is that @emph{a unit compiled with the static model cannot |
| be @code{with'ed} by a unit compiled with the dynamic model}. The |
| reason for this is that in the static model, a unit assumes that |
| its clients guarantee to use (the equivalent of) pragma |
| @code{Elaborate_All} so that no elaboration checks are required |
| in inner subprograms, and this assumption is violated if the |
| client is compiled with dynamic checks. |
| |
| The precise rule is as follows. A unit that is compiled with dynamic |
| checks can only @code{with} a unit that meets at least one of the |
| following criteria: |
| |
| @itemize @bullet |
| |
| @item |
| The @code{with'ed} unit is itself compiled with dynamic elaboration |
| checks (that is with the @option{-gnatE} switch. |
| |
| @item |
| The @code{with'ed} unit is an internal GNAT implementation unit from |
| the System, Interfaces, Ada, or GNAT hierarchies. |
| |
| @item |
| The @code{with'ed} unit has pragma Preelaborate or pragma Pure. |
| |
| @item |
| The @code{with'ing} unit (that is the client) has an explicit pragma |
| @code{Elaborate_All} for the @code{with'ed} unit. |
| |
| @end itemize |
| |
| @noindent |
| If this rule is violated, that is if a unit with dynamic elaboration |
| checks @code{with's} a unit that does not meet one of the above four |
| criteria, then the binder (@code{gnatbind}) will issue a warning |
| similar to that in the following example: |
| |
| @smallexample |
| warning: "x.ads" has dynamic elaboration checks and with's |
| warning: "y.ads" which has static elaboration checks |
| @end smallexample |
| |
| @noindent |
| These warnings indicate that the rule has been violated, and that as a result |
| elaboration checks may be missed in the resulting executable file. |
| This warning may be suppressed using the @option{-ws} binder switch |
| in the usual manner. |
| |
| One useful application of this mixing rule is in the case of a subsystem |
| which does not itself @code{with} units from the remainder of the |
| application. In this case, the entire subsystem can be compiled with |
| dynamic checks to resolve a circularity in the subsystem, while |
| allowing the main application that uses this subsystem to be compiled |
| using the more reliable default static model. |
| |
| @node What to Do If the Default Elaboration Behavior Fails |
| @section What to Do If the Default Elaboration Behavior Fails |
| |
| @noindent |
| If the binder cannot find an acceptable order, it outputs detailed |
| diagnostics. For example: |
| @smallexample |
| @group |
| @iftex |
| @leftskip=0cm |
| @end iftex |
| error: elaboration circularity detected |
| info: "proc (body)" must be elaborated before "pack (body)" |
| info: reason: Elaborate_All probably needed in unit "pack (body)" |
| info: recompile "pack (body)" with -gnatwl |
| info: for full details |
| info: "proc (body)" |
| info: is needed by its spec: |
| info: "proc (spec)" |
| info: which is withed by: |
| info: "pack (body)" |
| info: "pack (body)" must be elaborated before "proc (body)" |
| info: reason: pragma Elaborate in unit "proc (body)" |
| @end group |
| |
| @end smallexample |
| |
| @noindent |
| In this case we have a cycle that the binder cannot break. On the one |
| hand, there is an explicit pragma Elaborate in @code{proc} for |
| @code{pack}. This means that the body of @code{pack} must be elaborated |
| before the body of @code{proc}. On the other hand, there is elaboration |
| code in @code{pack} that calls a subprogram in @code{proc}. This means |
| that for maximum safety, there should really be a pragma |
| Elaborate_All in @code{pack} for @code{proc} which would require that |
| the body of @code{proc} be elaborated before the body of |
| @code{pack}. Clearly both requirements cannot be satisfied. |
| Faced with a circularity of this kind, you have three different options. |
| |
| @table @asis |
| @item Fix the program |
| The most desirable option from the point of view of long-term maintenance |
| is to rearrange the program so that the elaboration problems are avoided. |
| One useful technique is to place the elaboration code into separate |
| child packages. Another is to move some of the initialization code to |
| explicitly called subprograms, where the program controls the order |
| of initialization explicitly. Although this is the most desirable option, |
| it may be impractical and involve too much modification, especially in |
| the case of complex legacy code. |
| |
| @item Perform dynamic checks |
| If the compilations are done using the |
| @option{-gnatE} |
| (dynamic elaboration check) switch, then GNAT behaves in a quite different |
| manner. Dynamic checks are generated for all calls that could possibly result |
| in raising an exception. With this switch, the compiler does not generate |
| implicit @code{Elaborate} or @code{Elaborate_All} pragmas. The behavior then is |
| exactly as specified in the Ada 95 Reference Manual. The binder will generate |
| an executable program that may or may not raise @code{Program_Error}, and then |
| it is the programmer's job to ensure that it does not raise an exception. Note |
| that it is important to compile all units with the switch, it cannot be used |
| selectively. |
| |
| @item Suppress checks |
| The drawback of dynamic checks is that they generate a |
| significant overhead at run time, both in space and time. If you |
| are absolutely sure that your program cannot raise any elaboration |
| exceptions, and you still want to use the dynamic elaboration model, |
| then you can use the configuration pragma |
| @code{Suppress (Elaboration_Check)} to suppress all such checks. For |
| example this pragma could be placed in the @file{gnat.adc} file. |
| |
| @item Suppress checks selectively |
| When you know that certain calls or instantiations in elaboration code cannot |
| possibly lead to an elaboration error, and the binder nevertheless complains |
| about implicit @code{Elaborate} and @code{Elaborate_All} pragmas that lead to |
| elaboration circularities, it is possible to remove those warnings locally and |
| obtain a program that will bind. Clearly this can be unsafe, and it is the |
| responsibility of the programmer to make sure that the resulting program has no |
| elaboration anomalies. The pragma @code{Suppress (Elaboration_Check)} can be |
| used with different granularity to suppress warnings and break elaboration |
| circularities: |
| |
| @itemize @bullet |
| @item |
| Place the pragma that names the called subprogram in the declarative part |
| that contains the call. |
| |
| @item |
| Place the pragma in the declarative part, without naming an entity. This |
| disables warnings on all calls in the corresponding declarative region. |
| |
| @item |
| Place the pragma in the package spec that declares the called subprogram, |
| and name the subprogram. This disables warnings on all elaboration calls to |
| that subprogram. |
| |
| @item |
| Place the pragma in the package spec that declares the called subprogram, |
| without naming any entity. This disables warnings on all elaboration calls to |
| all subprograms declared in this spec. |
| |
| @item Use Pragma Elaborate |
| As previously described in section @xref{Treatment of Pragma Elaborate}, |
| GNAT in static mode assumes that a @code{pragma} Elaborate indicates correctly |
| that no elaboration checks are required on calls to the designated unit. |
| There may be cases in which the caller knows that no transitive calls |
| can occur, so that a @code{pragma Elaborate} will be sufficient in a |
| case where @code{pragma Elaborate_All} would cause a circularity. |
| @end itemize |
| |
| @noindent |
| These five cases are listed in order of decreasing safety, and therefore |
| require increasing programmer care in their application. Consider the |
| following program: |
| |
| @smallexample @c adanocomment |
| package Pack1 is |
| function F1 return Integer; |
| X1 : Integer; |
| end Pack1; |
| |
| package Pack2 is |
| function F2 return Integer; |
| function Pure (x : integer) return integer; |
| -- pragma Suppress (Elaboration_Check, On => Pure); -- (3) |
| -- pragma Suppress (Elaboration_Check); -- (4) |
| end Pack2; |
| |
| with Pack2; |
| package body Pack1 is |
| function F1 return Integer is |
| begin |
| return 100; |
| end F1; |
| Val : integer := Pack2.Pure (11); -- Elab. call (1) |
| begin |
| declare |
| -- pragma Suppress(Elaboration_Check, Pack2.F2); -- (1) |
| -- pragma Suppress(Elaboration_Check); -- (2) |
| begin |
| X1 := Pack2.F2 + 1; -- Elab. call (2) |
| end; |
| end Pack1; |
| |
| with Pack1; |
| package body Pack2 is |
| function F2 return Integer is |
| begin |
| return Pack1.F1; |
| end F2; |
| function Pure (x : integer) return integer is |
| begin |
| return x ** 3 - 3 * x; |
| end; |
| end Pack2; |
| |
| with Pack1, Ada.Text_IO; |
| procedure Proc3 is |
| begin |
| Ada.Text_IO.Put_Line(Pack1.X1'Img); -- 101 |
| end Proc3; |
| @end smallexample |
| In the absence of any pragmas, an attempt to bind this program produces |
| the following diagnostics: |
| @smallexample |
| @group |
| @iftex |
| @leftskip=.5cm |
| @end iftex |
| error: elaboration circularity detected |
| info: "pack1 (body)" must be elaborated before "pack1 (body)" |
| info: reason: Elaborate_All probably needed in unit "pack1 (body)" |
| info: recompile "pack1 (body)" with -gnatwl for full details |
| info: "pack1 (body)" |
| info: must be elaborated along with its spec: |
| info: "pack1 (spec)" |
| info: which is withed by: |
| info: "pack2 (body)" |
| info: which must be elaborated along with its spec: |
| info: "pack2 (spec)" |
| info: which is withed by: |
| info: "pack1 (body)" |
| @end group |
| @end smallexample |
| The sources of the circularity are the two calls to @code{Pack2.Pure} and |
| @code{Pack2.F2} in the body of @code{Pack1}. We can see that the call to |
| F2 is safe, even though F2 calls F1, because the call appears after the |
| elaboration of the body of F1. Therefore the pragma (1) is safe, and will |
| remove the warning on the call. It is also possible to use pragma (2) |
| because there are no other potentially unsafe calls in the block. |
| |
| @noindent |
| The call to @code{Pure} is safe because this function does not depend on the |
| state of @code{Pack2}. Therefore any call to this function is safe, and it |
| is correct to place pragma (3) in the corresponding package spec. |
| |
| @noindent |
| Finally, we could place pragma (4) in the spec of @code{Pack2} to disable |
| warnings on all calls to functions declared therein. Note that this is not |
| necessarily safe, and requires more detailed examination of the subprogram |
| bodies involved. In particular, a call to @code{F2} requires that @code{F1} |
| be already elaborated. |
| @end table |
| |
| @noindent |
| It is hard to generalize on which of these four approaches should be |
| taken. Obviously if it is possible to fix the program so that the default |
| treatment works, this is preferable, but this may not always be practical. |
| It is certainly simple enough to use |
| @option{-gnatE} |
| but the danger in this case is that, even if the GNAT binder |
| finds a correct elaboration order, it may not always do so, |
| and certainly a binder from another Ada compiler might not. A |
| combination of testing and analysis (for which the warnings generated |
| with the |
| @option{-gnatwl} |
| switch can be useful) must be used to ensure that the program is free |
| of errors. One switch that is useful in this testing is the |
| @option{^-p (pessimistic elaboration order)^/PESSIMISTIC_ELABORATION_ORDER^} |
| switch for |
| @code{gnatbind}. |
| Normally the binder tries to find an order that has the best chance of |
| of avoiding elaboration problems. With this switch, the binder |
| plays a devil's advocate role, and tries to choose the order that |
| has the best chance of failing. If your program works even with this |
| switch, then it has a better chance of being error free, but this is still |
| not a guarantee. |
| |
| For an example of this approach in action, consider the C-tests (executable |
| tests) from the ACVC suite. If these are compiled and run with the default |
| treatment, then all but one of them succeed without generating any error |
| diagnostics from the binder. However, there is one test that fails, and |
| this is not surprising, because the whole point of this test is to ensure |
| that the compiler can handle cases where it is impossible to determine |
| a correct order statically, and it checks that an exception is indeed |
| raised at run time. |
| |
| This one test must be compiled and run using the |
| @option{-gnatE} |
| switch, and then it passes. Alternatively, the entire suite can |
| be run using this switch. It is never wrong to run with the dynamic |
| elaboration switch if your code is correct, and we assume that the |
| C-tests are indeed correct (it is less efficient, but efficiency is |
| not a factor in running the ACVC tests.) |
| |
| @node Elaboration for Access-to-Subprogram Values |
| @section Elaboration for Access-to-Subprogram Values |
| @cindex Access-to-subprogram |
| |
| @noindent |
| The introduction of access-to-subprogram types in Ada 95 complicates |
| the handling of elaboration. The trouble is that it becomes |
| impossible to tell at compile time which procedure |
| is being called. This means that it is not possible for the binder |
| to analyze the elaboration requirements in this case. |
| |
| If at the point at which the access value is created |
| (i.e., the evaluation of @code{P'Access} for a subprogram @code{P}), |
| the body of the subprogram is |
| known to have been elaborated, then the access value is safe, and its use |
| does not require a check. This may be achieved by appropriate arrangement |
| of the order of declarations if the subprogram is in the current unit, |
| or, if the subprogram is in another unit, by using pragma |
| @code{Pure}, @code{Preelaborate}, or @code{Elaborate_Body} |
| on the referenced unit. |
| |
| If the referenced body is not known to have been elaborated at the point |
| the access value is created, then any use of the access value must do a |
| dynamic check, and this dynamic check will fail and raise a |
| @code{Program_Error} exception if the body has not been elaborated yet. |
| GNAT will generate the necessary checks, and in addition, if the |
| @option{-gnatwl} |
| switch is set, will generate warnings that such checks are required. |
| |
| The use of dynamic dispatching for tagged types similarly generates |
| a requirement for dynamic checks, and premature calls to any primitive |
| operation of a tagged type before the body of the operation has been |
| elaborated, will result in the raising of @code{Program_Error}. |
| |
| @node Summary of Procedures for Elaboration Control |
| @section Summary of Procedures for Elaboration Control |
| @cindex Elaboration control |
| |
| @noindent |
| First, compile your program with the default options, using none of |
| the special elaboration control switches. If the binder successfully |
| binds your program, then you can be confident that, apart from issues |
| raised by the use of access-to-subprogram types and dynamic dispatching, |
| the program is free of elaboration errors. If it is important that the |
| program be portable, then use the |
| @option{-gnatwl} |
| switch to generate warnings about missing @code{Elaborate} or |
| @code{Elaborate_All} pragmas, and supply the missing pragmas. |
| |
| If the program fails to bind using the default static elaboration |
| handling, then you can fix the program to eliminate the binder |
| message, or recompile the entire program with the |
| @option{-gnatE} switch to generate dynamic elaboration checks, |
| and, if you are sure there really are no elaboration problems, |
| use a global pragma @code{Suppress (Elaboration_Check)}. |
| |
| @node Other Elaboration Order Considerations |
| @section Other Elaboration Order Considerations |
| @noindent |
| This section has been entirely concerned with the issue of finding a valid |
| elaboration order, as defined by the Ada Reference Manual. In a case |
| where several elaboration orders are valid, the task is to find one |
| of the possible valid elaboration orders (and the static model in GNAT |
| will ensure that this is achieved). |
| |
| The purpose of the elaboration rules in the Ada Reference Manual is to |
| make sure that no entity is accessed before it has been elaborated. For |
| a subprogram, this means that the spec and body must have been elaborated |
| before the subprogram is called. For an object, this means that the object |
| must have been elaborated before its value is read or written. A violation |
| of either of these two requirements is an access before elaboration order, |
| and this section has been all about avoiding such errors. |
| |
| In the case where more than one order of elaboration is possible, in the |
| sense that access before elaboration errors are avoided, then any one of |
| the orders is ``correct'' in the sense that it meets the requirements of |
| the Ada Reference Manual, and no such error occurs. |
| |
| However, it may be the case for a given program, that there are |
| constraints on the order of elaboration that come not from consideration |
| of avoiding elaboration errors, but rather from extra-lingual logic |
| requirements. Consider this example: |
| |
| @smallexample @c ada |
| with Init_Constants; |
| package Constants is |
| X : Integer := 0; |
| Y : Integer := 0; |
| end Constants; |
| |
| package Init_Constants is |
| procedure P; -- require a body |
| end Init_Constants; |
| |
| with Constants; |
| package body Init_Constants is |
| procedure P is begin null; end; |
| begin |
| Constants.X := 3; |
| Constants.Y := 4; |
| end Init_Constants; |
| |
| with Constants; |
| package Calc is |
| Z : Integer := Constants.X + Constants.Y; |
| end Calc; |
| |
| with Calc; |
| with Text_IO; use Text_IO; |
| procedure Main is |
| begin |
| Put_Line (Calc.Z'Img); |
| end Main; |
| @end smallexample |
| |
| @noindent |
| In this example, there is more than one valid order of elaboration. For |
| example both the following are correct orders: |
| |
| @smallexample |
| Init_Constants spec |
| Constants spec |
| Calc spec |
| Init_Constants body |
| Main body |
| |
| and |
| |
| Init_Constants spec |
| Init_Constants body |
| Constants spec |
| Calc spec |
| Main body |
| @end smallexample |
| |
| @noindent |
| There is no language rule to prefer one or the other, both are correct |
| from an order of elaboration point of view. But the programmatic effects |
| of the two orders are very different. In the first, the elaboration routine |
| of @code{Calc} initializes @code{Z} to zero, and then the main program |
| runs with this value of zero. But in the second order, the elaboration |
| routine of @code{Calc} runs after the body of Init_Constants has set |
| @code{X} and @code{Y} and thus @code{Z} is set to 7 before @code{Main} |
| runs. |
| |
| One could perhaps by applying pretty clever non-artificial intelligence |
| to the situation guess that it is more likely that the second order of |
| elaboration is the one desired, but there is no formal linguistic reason |
| to prefer one over the other. In fact in this particular case, GNAT will |
| prefer the second order, because of the rule that bodies are elaborated |
| as soon as possible, but it's just luck that this is what was wanted |
| (if indeed the second order was preferred). |
| |
| If the program cares about the order of elaboration routines in a case like |
| this, it is important to specify the order required. In this particular |
| case, that could have been achieved by adding to the spec of Calc: |
| |
| @smallexample @c ada |
| pragma Elaborate_All (Constants); |
| @end smallexample |
| |
| @noindent |
| which requires that the body (if any) and spec of @code{Constants}, |
| as well as the body and spec of any unit @code{with}'ed by |
| @code{Constants} be elaborated before @code{Calc} is elaborated. |
| |
| Clearly no automatic method can always guess which alternative you require, |
| and if you are working with legacy code that had constraints of this kind |
| which were not properly specified by adding @code{Elaborate} or |
| @code{Elaborate_All} pragmas, then indeed it is possible that two different |
| compilers can choose different orders. |
| |
| The @code{gnatbind} |
| @option{^-p^/PESSIMISTIC_ELABORATION^} switch may be useful in smoking |
| out problems. This switch causes bodies to be elaborated as late as possible |
| instead of as early as possible. In the example above, it would have forced |
| the choice of the first elaboration order. If you get different results |
| when using this switch, and particularly if one set of results is right, |
| and one is wrong as far as you are concerned, it shows that you have some |
| missing @code{Elaborate} pragmas. For the example above, we have the |
| following output: |
| |
| @smallexample |
| gnatmake -f -q main |
| main |
| 7 |
| gnatmake -f -q main -bargs -p |
| main |
| 0 |
| @end smallexample |
| |
| @noindent |
| It is of course quite unlikely that both these results are correct, so |
| it is up to you in a case like this to investigate the source of the |
| difference, by looking at the two elaboration orders that are chosen, |
| and figuring out which is correct, and then adding the necessary |
| @code{Elaborate} or @code{Elaborate_All} pragmas to ensure the desired order. |
| |
| @node Inline Assembler |
| @appendix Inline Assembler |
| |
| @noindent |
| If you need to write low-level software that interacts directly |
| with the hardware, Ada provides two ways to incorporate assembly |
| language code into your program. First, you can import and invoke |
| external routines written in assembly language, an Ada feature fully |
| supported by GNAT. However, for small sections of code it may be simpler |
| or more efficient to include assembly language statements directly |
| in your Ada source program, using the facilities of the implementation-defined |
| package @code{System.Machine_Code}, which incorporates the gcc |
| Inline Assembler. The Inline Assembler approach offers a number of advantages, |
| including the following: |
| |
| @itemize @bullet |
| @item No need to use non-Ada tools |
| @item Consistent interface over different targets |
| @item Automatic usage of the proper calling conventions |
| @item Access to Ada constants and variables |
| @item Definition of intrinsic routines |
| @item Possibility of inlining a subprogram comprising assembler code |
| @item Code optimizer can take Inline Assembler code into account |
| @end itemize |
| |
| This chapter presents a series of examples to show you how to use |
| the Inline Assembler. Although it focuses on the Intel x86, |
| the general approach applies also to other processors. |
| It is assumed that you are familiar with Ada |
| and with assembly language programming. |
| |
| @menu |
| * Basic Assembler Syntax:: |
| * A Simple Example of Inline Assembler:: |
| * Output Variables in Inline Assembler:: |
| * Input Variables in Inline Assembler:: |
| * Inlining Inline Assembler Code:: |
| * Other Asm Functionality:: |
| @end menu |
| |
| @c --------------------------------------------------------------------------- |
| @node Basic Assembler Syntax |
| @section Basic Assembler Syntax |
| |
| @noindent |
| The assembler used by GNAT and gcc is based not on the Intel assembly |
| language, but rather on a language that descends from the AT&T Unix |
| assembler @emph{as} (and which is often referred to as ``AT&T syntax''). |
| The following table summarizes the main features of @emph{as} syntax |
| and points out the differences from the Intel conventions. |
| See the gcc @emph{as} and @emph{gas} (an @emph{as} macro |
| pre-processor) documentation for further information. |
| |
| @table @asis |
| @item Register names |
| gcc / @emph{as}: Prefix with ``%''; for example @code{%eax} |
| @* |
| Intel: No extra punctuation; for example @code{eax} |
| |
| @item Immediate operand |
| gcc / @emph{as}: Prefix with ``$''; for example @code{$4} |
| @* |
| Intel: No extra punctuation; for example @code{4} |
| |
| @item Address |
| gcc / @emph{as}: Prefix with ``$''; for example @code{$loc} |
| @* |
| Intel: No extra punctuation; for example @code{loc} |
| |
| @item Memory contents |
| gcc / @emph{as}: No extra punctuation; for example @code{loc} |
| @* |
| Intel: Square brackets; for example @code{[loc]} |
| |
| @item Register contents |
| gcc / @emph{as}: Parentheses; for example @code{(%eax)} |
| @* |
| Intel: Square brackets; for example @code{[eax]} |
| |
| @item Hexadecimal numbers |
| gcc / @emph{as}: Leading ``0x'' (C language syntax); for example @code{0xA0} |
| @* |
| Intel: Trailing ``h''; for example @code{A0h} |
| |
| @item Operand size |
| gcc / @emph{as}: Explicit in op code; for example @code{movw} to move |
| a 16-bit word |
| @* |
| Intel: Implicit, deduced by assembler; for example @code{mov} |
| |
| @item Instruction repetition |
| gcc / @emph{as}: Split into two lines; for example |
| @* |
| @code{rep} |
| @* |
| @code{stosl} |
| @* |
| Intel: Keep on one line; for example @code{rep stosl} |
| |
| @item Order of operands |
| gcc / @emph{as}: Source first; for example @code{movw $4, %eax} |
| @* |
| Intel: Destination first; for example @code{mov eax, 4} |
| @end table |
| |
| @c --------------------------------------------------------------------------- |
| @node A Simple Example of Inline Assembler |
| @section A Simple Example of Inline Assembler |
| |
| @noindent |
| The following example will generate a single assembly language statement, |
| @code{nop}, which does nothing. Despite its lack of run-time effect, |
| the example will be useful in illustrating the basics of |
| the Inline Assembler facility. |
| |
| @smallexample @c ada |
| @group |
| with System.Machine_Code; use System.Machine_Code; |
| procedure Nothing is |
| begin |
| Asm ("nop"); |
| end Nothing; |
| @end group |
| @end smallexample |
| |
| @code{Asm} is a procedure declared in package @code{System.Machine_Code}; |
| here it takes one parameter, a @emph{template string} that must be a static |
| expression and that will form the generated instruction. |
| @code{Asm} may be regarded as a compile-time procedure that parses |
| the template string and additional parameters (none here), |
| from which it generates a sequence of assembly language instructions. |
| |
| The examples in this chapter will illustrate several of the forms |
| for invoking @code{Asm}; a complete specification of the syntax |
| is found in the @cite{GNAT Reference Manual}. |
| |
| Under the standard GNAT conventions, the @code{Nothing} procedure |
| should be in a file named @file{nothing.adb}. |
| You can build the executable in the usual way: |
| @smallexample |
| gnatmake nothing |
| @end smallexample |
| However, the interesting aspect of this example is not its run-time behavior |
| but rather the generated assembly code. |
| To see this output, invoke the compiler as follows: |
| @smallexample |
| gcc -c -S -fomit-frame-pointer -gnatp @file{nothing.adb} |
| @end smallexample |
| where the options are: |
| |
| @table @code |
| @item -c |
| compile only (no bind or link) |
| @item -S |
| generate assembler listing |
| @item -fomit-frame-pointer |
| do not set up separate stack frames |
| @item -gnatp |
| do not add runtime checks |
| @end table |
| |
| This gives a human-readable assembler version of the code. The resulting |
| file will have the same name as the Ada source file, but with a @code{.s} |
| extension. In our example, the file @file{nothing.s} has the following |
| contents: |
| |
| @smallexample |
| @group |
| .file "nothing.adb" |
| gcc2_compiled.: |
| ___gnu_compiled_ada: |
| .text |
| .align 4 |
| .globl __ada_nothing |
| __ada_nothing: |
| #APP |
| nop |
| #NO_APP |
| jmp L1 |
| .align 2,0x90 |
| L1: |
| ret |
| @end group |
| @end smallexample |
| |
| The assembly code you included is clearly indicated by |
| the compiler, between the @code{#APP} and @code{#NO_APP} |
| delimiters. The character before the 'APP' and 'NOAPP' |
| can differ on different targets. For example, GNU/Linux uses '#APP' while |
| on NT you will see '/APP'. |
| |
| If you make a mistake in your assembler code (such as using the |
| wrong size modifier, or using a wrong operand for the instruction) GNAT |
| will report this error in a temporary file, which will be deleted when |
| the compilation is finished. Generating an assembler file will help |
| in such cases, since you can assemble this file separately using the |
| @emph{as} assembler that comes with gcc. |
| |
| Assembling the file using the command |
| |
| @smallexample |
| as @file{nothing.s} |
| @end smallexample |
| @noindent |
| will give you error messages whose lines correspond to the assembler |
| input file, so you can easily find and correct any mistakes you made. |
| If there are no errors, @emph{as} will generate an object file |
| @file{nothing.out}. |
| |
| @c --------------------------------------------------------------------------- |
| @node Output Variables in Inline Assembler |
| @section Output Variables in Inline Assembler |
| |
| @noindent |
| The examples in this section, showing how to access the processor flags, |
| illustrate how to specify the destination operands for assembly language |
| statements. |
| |
| @smallexample @c ada |
| @group |
| with Interfaces; use Interfaces; |
| with Ada.Text_IO; use Ada.Text_IO; |
| with System.Machine_Code; use System.Machine_Code; |
| procedure Get_Flags is |
| Flags : Unsigned_32; |
| use ASCII; |
| begin |
| Asm ("pushfl" & LF & HT & -- push flags on stack |
| "popl %%eax" & LF & HT & -- load eax with flags |
| "movl %%eax, %0", -- store flags in variable |
| Outputs => Unsigned_32'Asm_Output ("=g", Flags)); |
| Put_Line ("Flags register:" & Flags'Img); |
| end Get_Flags; |
| @end group |
| @end smallexample |
| |
| In order to have a nicely aligned assembly listing, we have separated |
| multiple assembler statements in the Asm template string with linefeed |
| (ASCII.LF) and horizontal tab (ASCII.HT) characters. |
| The resulting section of the assembly output file is: |
| |
| @smallexample |
| @group |
| #APP |
| pushfl |
| popl %eax |
| movl %eax, -40(%ebp) |
| #NO_APP |
| @end group |
| @end smallexample |
| |
| It would have been legal to write the Asm invocation as: |
| |
| @smallexample |
| Asm ("pushfl popl %%eax movl %%eax, %0") |
| @end smallexample |
| |
| but in the generated assembler file, this would come out as: |
| |
| @smallexample |
| #APP |
| pushfl popl %eax movl %eax, -40(%ebp) |
| #NO_APP |
| @end smallexample |
| |
| which is not so convenient for the human reader. |
| |
| We use Ada comments |
| at the end of each line to explain what the assembler instructions |
| actually do. This is a useful convention. |
| |
| When writing Inline Assembler instructions, you need to precede each register |
| and variable name with a percent sign. Since the assembler already requires |
| a percent sign at the beginning of a register name, you need two consecutive |
| percent signs for such names in the Asm template string, thus @code{%%eax}. |
| In the generated assembly code, one of the percent signs will be stripped off. |
| |
| Names such as @code{%0}, @code{%1}, @code{%2}, etc., denote input or output |
| variables: operands you later define using @code{Input} or @code{Output} |
| parameters to @code{Asm}. |
| An output variable is illustrated in |
| the third statement in the Asm template string: |
| @smallexample |
| movl %%eax, %0 |
| @end smallexample |
| The intent is to store the contents of the eax register in a variable that can |
| be accessed in Ada. Simply writing @code{movl %%eax, Flags} would not |
| necessarily work, since the compiler might optimize by using a register |
| to hold Flags, and the expansion of the @code{movl} instruction would not be |
| aware of this optimization. The solution is not to store the result directly |
| but rather to advise the compiler to choose the correct operand form; |
| that is the purpose of the @code{%0} output variable. |
| |
| Information about the output variable is supplied in the @code{Outputs} |
| parameter to @code{Asm}: |
| @smallexample |
| Outputs => Unsigned_32'Asm_Output ("=g", Flags)); |
| @end smallexample |
| |
| The output is defined by the @code{Asm_Output} attribute of the target type; |
| the general format is |
| @smallexample |
| Type'Asm_Output (constraint_string, variable_name) |
| @end smallexample |
| |
| The constraint string directs the compiler how |
| to store/access the associated variable. In the example |
| @smallexample |
| Unsigned_32'Asm_Output ("=m", Flags); |
| @end smallexample |
| the @code{"m"} (memory) constraint tells the compiler that the variable |
| @code{Flags} should be stored in a memory variable, thus preventing |
| the optimizer from keeping it in a register. In contrast, |
| @smallexample |
| Unsigned_32'Asm_Output ("=r", Flags); |
| @end smallexample |
| uses the @code{"r"} (register) constraint, telling the compiler to |
| store the variable in a register. |
| |
| If the constraint is preceded by the equal character (@strong{=}), it tells |
| the compiler that the variable will be used to store data into it. |
| |
| In the @code{Get_Flags} example, we used the @code{"g"} (global) constraint, |
| allowing the optimizer to choose whatever it deems best. |
| |
| There are a fairly large number of constraints, but the ones that are |
| most useful (for the Intel x86 processor) are the following: |
| |
| @table @code |
| @item = |
| output constraint |
| @item g |
| global (i.e. can be stored anywhere) |
| @item m |
| in memory |
| @item I |
| a constant |
| @item a |
| use eax |
| @item b |
| use ebx |
| @item c |
| use ecx |
| @item d |
| use edx |
| @item S |
| use esi |
| @item D |
| use edi |
| @item r |
| use one of eax, ebx, ecx or edx |
| @item q |
| use one of eax, ebx, ecx, edx, esi or edi |
| @end table |
| |
| The full set of constraints is described in the gcc and @emph{as} |
| documentation; note that it is possible to combine certain constraints |
| in one constraint string. |
| |
| You specify the association of an output variable with an assembler operand |
| through the @code{%}@emph{n} notation, where @emph{n} is a non-negative |
| integer. Thus in |
| @smallexample @c ada |
| @group |
| Asm ("pushfl" & LF & HT & -- push flags on stack |
| "popl %%eax" & LF & HT & -- load eax with flags |
| "movl %%eax, %0", -- store flags in variable |
| Outputs => Unsigned_32'Asm_Output ("=g", Flags)); |
| @end group |
| @end smallexample |
| @noindent |
| @code{%0} will be replaced in the expanded code by the appropriate operand, |
| whatever |
| the compiler decided for the @code{Flags} variable. |
| |
| In general, you may have any number of output variables: |
| @itemize @bullet |
| @item |
| Count the operands starting at 0; thus @code{%0}, @code{%1}, etc. |
| @item |
| Specify the @code{Outputs} parameter as a parenthesized comma-separated list |
| of @code{Asm_Output} attributes |
| @end itemize |
| |
| For example: |
| @smallexample @c ada |
| @group |
| Asm ("movl %%eax, %0" & LF & HT & |
| "movl %%ebx, %1" & LF & HT & |
| "movl %%ecx, %2", |
| Outputs => (Unsigned_32'Asm_Output ("=g", Var_A), -- %0 = Var_A |
| Unsigned_32'Asm_Output ("=g", Var_B), -- %1 = Var_B |
| Unsigned_32'Asm_Output ("=g", Var_C))); -- %2 = Var_C |
| @end group |
| @end smallexample |
| @noindent |
| where @code{Var_A}, @code{Var_B}, and @code{Var_C} are variables |
| in the Ada program. |
| |
| As a variation on the @code{Get_Flags} example, we can use the constraints |
| string to direct the compiler to store the eax register into the @code{Flags} |
| variable, instead of including the store instruction explicitly in the |
| @code{Asm} template string: |
| |
| @smallexample @c ada |
| @group |
| with Interfaces; use Interfaces; |
| with Ada.Text_IO; use Ada.Text_IO; |
| with System.Machine_Code; use System.Machine_Code; |
| procedure Get_Flags_2 is |
| Flags : Unsigned_32; |
| use ASCII; |
| begin |
| Asm ("pushfl" & LF & HT & -- push flags on stack |
| "popl %%eax", -- save flags in eax |
| Outputs => Unsigned_32'Asm_Output ("=a", Flags)); |
| Put_Line ("Flags register:" & Flags'Img); |
| end Get_Flags_2; |
| @end group |
| @end smallexample |
| |
| @noindent |
| The @code{"a"} constraint tells the compiler that the @code{Flags} |
| variable will come from the eax register. Here is the resulting code: |
| |
| @smallexample |
| @group |
| #APP |
| pushfl |
| popl %eax |
| #NO_APP |
| movl %eax,-40(%ebp) |
| @end group |
| @end smallexample |
| |
| @noindent |
| The compiler generated the store of eax into Flags after |
| expanding the assembler code. |
| |
| Actually, there was no need to pop the flags into the eax register; |
| more simply, we could just pop the flags directly into the program variable: |
| |
| @smallexample @c ada |
| @group |
| with Interfaces; use Interfaces; |
| with Ada.Text_IO; use Ada.Text_IO; |
| with System.Machine_Code; use System.Machine_Code; |
| procedure Get_Flags_3 is |
| Flags : Unsigned_32; |
| use ASCII; |
| begin |
| Asm ("pushfl" & LF & HT & -- push flags on stack |
| "pop %0", -- save flags in Flags |
| Outputs => Unsigned_32'Asm_Output ("=g", Flags)); |
| Put_Line ("Flags register:" & Flags'Img); |
| end Get_Flags_3; |
| @end group |
| @end smallexample |
| |
| @c --------------------------------------------------------------------------- |
| @node Input Variables in Inline Assembler |
| @section Input Variables in Inline Assembler |
| |
| @noindent |
| The example in this section illustrates how to specify the source operands |
| for assembly language statements. |
| The program simply increments its input value by 1: |
| |
| @smallexample @c ada |
| @group |
| with Interfaces; use Interfaces; |
| with Ada.Text_IO; use Ada.Text_IO; |
| with System.Machine_Code; use System.Machine_Code; |
| procedure Increment is |
| |
| function Incr (Value : Unsigned_32) return Unsigned_32 is |
| Result : Unsigned_32; |
| begin |
| Asm ("incl %0", |
| Inputs => Unsigned_32'Asm_Input ("a", Value), |
| Outputs => Unsigned_32'Asm_Output ("=a", Result)); |
| return Result; |
| end Incr; |
| |
| Value : Unsigned_32; |
| |
| begin |
| Value := 5; |
| Put_Line ("Value before is" & Value'Img); |
| Value := Incr (Value); |
| Put_Line ("Value after is" & Value'Img); |
| end Increment; |
| @end group |
| @end smallexample |
| |
| The @code{Outputs} parameter to @code{Asm} specifies |
| that the result will be in the eax register and that it is to be stored |
| in the @code{Result} variable. |
| |
| The @code{Inputs} parameter looks much like the @code{Outputs} parameter, |
| but with an @code{Asm_Input} attribute. |
| The @code{"="} constraint, indicating an output value, is not present. |
| |
| You can have multiple input variables, in the same way that you can have more |
| than one output variable. |
| |
| The parameter count (%0, %1) etc, now starts at the first input |
| statement, and continues with the output statements. |
| When both parameters use the same variable, the |
| compiler will treat them as the same %n operand, which is the case here. |
| |
| Just as the @code{Outputs} parameter causes the register to be stored into the |
| target variable after execution of the assembler statements, so does the |
| @code{Inputs} parameter cause its variable to be loaded into the register |
| before execution of the assembler statements. |
| |
| Thus the effect of the @code{Asm} invocation is: |
| @enumerate |
| @item load the 32-bit value of @code{Value} into eax |
| @item execute the @code{incl %eax} instruction |
| @item store the contents of eax into the @code{Result} variable |
| @end enumerate |
| |
| The resulting assembler file (with @option{-O2} optimization) contains: |
| @smallexample |
| @group |
| _increment__incr.1: |
| subl $4,%esp |
| movl 8(%esp),%eax |
| #APP |
| incl %eax |
| #NO_APP |
| movl %eax,%edx |
| movl %ecx,(%esp) |
| addl $4,%esp |
| ret |
| @end group |
| @end smallexample |
| |
| @c --------------------------------------------------------------------------- |
| @node Inlining Inline Assembler Code |
| @section Inlining Inline Assembler Code |
| |
| @noindent |
| For a short subprogram such as the @code{Incr} function in the previous |
| section, the overhead of the call and return (creating / deleting the stack |
| frame) can be significant, compared to the amount of code in the subprogram |
| body. A solution is to apply Ada's @code{Inline} pragma to the subprogram, |
| which directs the compiler to expand invocations of the subprogram at the |
| point(s) of call, instead of setting up a stack frame for out-of-line calls. |
| Here is the resulting program: |
| |
| @smallexample @c ada |
| @group |
| with Interfaces; use Interfaces; |
| with Ada.Text_IO; use Ada.Text_IO; |
| with System.Machine_Code; use System.Machine_Code; |
| procedure Increment_2 is |
| |
| function Incr (Value : Unsigned_32) return Unsigned_32 is |
| Result : Unsigned_32; |
| begin |
| Asm ("incl %0", |
| Inputs => Unsigned_32'Asm_Input ("a", Value), |
| Outputs => Unsigned_32'Asm_Output ("=a", Result)); |
| return Result; |
| end Incr; |
| pragma Inline (Increment); |
| |
| Value : Unsigned_32; |
| |
| begin |
| Value := 5; |
| Put_Line ("Value before is" & Value'Img); |
| Value := Increment (Value); |
| Put_Line ("Value after is" & Value'Img); |
| end Increment_2; |
| @end group |
| @end smallexample |
| |
| Compile the program with both optimization (@option{-O2}) and inlining |
| enabled (@option{-gnatpn} instead of @option{-gnatp}). |
| |
| The @code{Incr} function is still compiled as usual, but at the |
| point in @code{Increment} where our function used to be called: |
| |
| @smallexample |
| @group |
| pushl %edi |
| call _increment__incr.1 |
| @end group |
| @end smallexample |
| |
| @noindent |
| the code for the function body directly appears: |
| |
| @smallexample |
| @group |
| movl %esi,%eax |
| #APP |
| incl %eax |
| #NO_APP |
| movl %eax,%edx |
| @end group |
| @end smallexample |
| |
| @noindent |
| thus saving the overhead of stack frame setup and an out-of-line call. |
| |
| @c --------------------------------------------------------------------------- |
| @node Other Asm Functionality |
| @section Other @code{Asm} Functionality |
| |
| @noindent |
| This section describes two important parameters to the @code{Asm} |
| procedure: @code{Clobber}, which identifies register usage; |
| and @code{Volatile}, which inhibits unwanted optimizations. |
| |
| @menu |
| * The Clobber Parameter:: |
| * The Volatile Parameter:: |
| @end menu |
| |
| @c --------------------------------------------------------------------------- |
| @node The Clobber Parameter |
| @subsection The @code{Clobber} Parameter |
| |
| @noindent |
| One of the dangers of intermixing assembly language and a compiled language |
| such as Ada is that the compiler needs to be aware of which registers are |
| being used by the assembly code. In some cases, such as the earlier examples, |
| the constraint string is sufficient to indicate register usage (e.g., |
| @code{"a"} for |
| the eax register). But more generally, the compiler needs an explicit |
| identification of the registers that are used by the Inline Assembly |
| statements. |
| |
| Using a register that the compiler doesn't know about |
| could be a side effect of an instruction (like @code{mull} |
| storing its result in both eax and edx). |
| It can also arise from explicit register usage in your |
| assembly code; for example: |
| @smallexample |
| @group |
| Asm ("movl %0, %%ebx" & LF & HT & |
| "movl %%ebx, %1", |
| Inputs => Unsigned_32'Asm_Input ("g", Var_In), |
| Outputs => Unsigned_32'Asm_Output ("=g", Var_Out)); |
| @end group |
| @end smallexample |
| @noindent |
| where the compiler (since it does not analyze the @code{Asm} template string) |
| does not know you are using the ebx register. |
| |
| In such cases you need to supply the @code{Clobber} parameter to @code{Asm}, |
| to identify the registers that will be used by your assembly code: |
| |
| @smallexample |
| @group |
| Asm ("movl %0, %%ebx" & LF & HT & |
| "movl %%ebx, %1", |
| Inputs => Unsigned_32'Asm_Input ("g", Var_In), |
| Outputs => Unsigned_32'Asm_Output ("=g", Var_Out), |
| Clobber => "ebx"); |
| @end group |
| @end smallexample |
| |
| The Clobber parameter is a static string expression specifying the |
| register(s) you are using. Note that register names are @emph{not} prefixed |
| by a percent sign. Also, if more than one register is used then their names |
| are separated by commas; e.g., @code{"eax, ebx"} |
| |
| The @code{Clobber} parameter has several additional uses: |
| @enumerate |
| @item Use ``register'' name @code{cc} to indicate that flags might have changed |
| @item Use ``register'' name @code{memory} if you changed a memory location |
| @end enumerate |
| |
| @c --------------------------------------------------------------------------- |
| @node The Volatile Parameter |
| @subsection The @code{Volatile} Parameter |
| @cindex Volatile parameter |
| |
| @noindent |
| Compiler optimizations in the presence of Inline Assembler may sometimes have |
| unwanted effects. For example, when an @code{Asm} invocation with an input |
| variable is inside a loop, the compiler might move the loading of the input |
| variable outside the loop, regarding it as a one-time initialization. |
| |
| If this effect is not desired, you can disable such optimizations by setting |
| the @code{Volatile} parameter to @code{True}; for example: |
| |
| @smallexample @c ada |
| @group |
| Asm ("movl %0, %%ebx" & LF & HT & |
| "movl %%ebx, %1", |
| Inputs => Unsigned_32'Asm_Input ("g", Var_In), |
| Outputs => Unsigned_32'Asm_Output ("=g", Var_Out), |
| Clobber => "ebx", |
| Volatile => True); |
| @end group |
| @end smallexample |
| |
| By default, @code{Volatile} is set to @code{False} unless there is no |
| @code{Outputs} parameter. |
| |
| Although setting @code{Volatile} to @code{True} prevents unwanted |
| optimizations, it will also disable other optimizations that might be |
| important for efficiency. In general, you should set @code{Volatile} |
| to @code{True} only if the compiler's optimizations have created |
| problems. |
| @c END OF INLINE ASSEMBLER CHAPTER |
| @c =============================== |
| |
| @c *********************************** |
| @c * Compatibility and Porting Guide * |
| @c *********************************** |
| @node Compatibility and Porting Guide |
| @appendix Compatibility and Porting Guide |
| |
| @noindent |
| This chapter describes the compatibility issues that may arise between |
| GNAT and other Ada 83 and Ada 95 compilation systems, and shows how GNAT |
| can expedite porting |
| applications developed in other Ada environments. |
| |
| @menu |
| * Compatibility with Ada 83:: |
| * Implementation-dependent characteristics:: |
| * Compatibility with Other Ada 95 Systems:: |
| * Representation Clauses:: |
| @ifclear vms |
| @c Brief section is only in non-VMS version |
| @c Full chapter is in VMS version |
| * Compatibility with HP Ada 83:: |
| @end ifclear |
| @ifset vms |
| * Transitioning from Alpha to I64 OpenVMS:: |
| @end ifset |
| @end menu |
| |
| @node Compatibility with Ada 83 |
| @section Compatibility with Ada 83 |
| @cindex Compatibility (between Ada 83 and Ada 95) |
| |
| @noindent |
| Ada 95 is designed to be highly upwards compatible with Ada 83. In |
| particular, the design intention is that the difficulties associated |
| with moving from Ada 83 to Ada 95 should be no greater than those |
| that occur when moving from one Ada 83 system to another. |
| |
| However, there are a number of points at which there are minor |
| incompatibilities. The @cite{Ada 95 Annotated Reference Manual} contains |
| full details of these issues, |
| and should be consulted for a complete treatment. |
| In practice the |
| following subsections treat the most likely issues to be encountered. |
| |
| @menu |
| * Legal Ada 83 programs that are illegal in Ada 95:: |
| * More deterministic semantics:: |
| * Changed semantics:: |
| * Other language compatibility issues:: |
| @end menu |
| |
| @node Legal Ada 83 programs that are illegal in Ada 95 |
| @subsection Legal Ada 83 programs that are illegal in Ada 95 |
| |
| @table @asis |
| @item Character literals |
| Some uses of character literals are ambiguous. Since Ada 95 has introduced |
| @code{Wide_Character} as a new predefined character type, some uses of |
| character literals that were legal in Ada 83 are illegal in Ada 95. |
| For example: |
| @smallexample @c ada |
| for Char in 'A' .. 'Z' loop ... end loop; |
| @end smallexample |
| @noindent |
| The problem is that @code{'A'} and @code{'Z'} could be from either |
| @code{Character} or @code{Wide_Character}. The simplest correction |
| is to make the type explicit; e.g.: |
| @smallexample @c ada |
| for Char in Character range 'A' .. 'Z' loop ... end loop; |
| @end smallexample |
| |
| @item New reserved words |
| The identifiers @code{abstract}, @code{aliased}, @code{protected}, |
| @code{requeue}, @code{tagged}, and @code{until} are reserved in Ada 95. |
| Existing Ada 83 code using any of these identifiers must be edited to |
| use some alternative name. |
| |
| @item Freezing rules |
| The rules in Ada 95 are slightly different with regard to the point at |
| which entities are frozen, and representation pragmas and clauses are |
| not permitted past the freeze point. This shows up most typically in |
| the form of an error message complaining that a representation item |
| appears too late, and the appropriate corrective action is to move |
| the item nearer to the declaration of the entity to which it refers. |
| |
| A particular case is that representation pragmas |
| @ifset vms |
| (including the |
| extended HP Ada 83 compatibility pragmas such as @code{Export_Procedure}) |
| @end ifset |
| cannot be applied to a subprogram body. If necessary, a separate subprogram |
| declaration must be introduced to which the pragma can be applied. |
| |
| @item Optional bodies for library packages |
| In Ada 83, a package that did not require a package body was nevertheless |
| allowed to have one. This lead to certain surprises in compiling large |
| systems (situations in which the body could be unexpectedly ignored by the |
| binder). In Ada 95, if a package does not require a body then it is not |
| permitted to have a body. To fix this problem, simply remove a redundant |
| body if it is empty, or, if it is non-empty, introduce a dummy declaration |
| into the spec that makes the body required. One approach is to add a private |
| part to the package declaration (if necessary), and define a parameterless |
| procedure called @code{Requires_Body}, which must then be given a dummy |
| procedure body in the package body, which then becomes required. |
| Another approach (assuming that this does not introduce elaboration |
| circularities) is to add an @code{Elaborate_Body} pragma to the package spec, |
| since one effect of this pragma is to require the presence of a package body. |
| |
| @item @code{Numeric_Error} is now the same as @code{Constraint_Error} |
| In Ada 95, the exception @code{Numeric_Error} is a renaming of |
| @code{Constraint_Error}. |
| This means that it is illegal to have separate exception handlers for |
| the two exceptions. The fix is simply to remove the handler for the |
| @code{Numeric_Error} case (since even in Ada 83, a compiler was free to raise |
| @code{Constraint_Error} in place of @code{Numeric_Error} in all cases). |
| |
| @item Indefinite subtypes in generics |
| In Ada 83, it was permissible to pass an indefinite type (e.g.@: @code{String}) |
| as the actual for a generic formal private type, but then the instantiation |
| would be illegal if there were any instances of declarations of variables |
| of this type in the generic body. In Ada 95, to avoid this clear violation |
| of the methodological principle known as the ``contract model'', |
| the generic declaration explicitly indicates whether |
| or not such instantiations are permitted. If a generic formal parameter |
| has explicit unknown discriminants, indicated by using @code{(<>)} after the |
| type name, then it can be instantiated with indefinite types, but no |
| stand-alone variables can be declared of this type. Any attempt to declare |
| such a variable will result in an illegality at the time the generic is |
| declared. If the @code{(<>)} notation is not used, then it is illegal |
| to instantiate the generic with an indefinite type. |
| This is the potential incompatibility issue when porting Ada 83 code to Ada 95. |
| It will show up as a compile time error, and |
| the fix is usually simply to add the @code{(<>)} to the generic declaration. |
| @end table |
| |
| @node More deterministic semantics |
| @subsection More deterministic semantics |
| |
| @table @asis |
| @item Conversions |
| Conversions from real types to integer types round away from 0. In Ada 83 |
| the conversion Integer(2.5) could deliver either 2 or 3 as its value. This |
| implementation freedom was intended to support unbiased rounding in |
| statistical applications, but in practice it interfered with portability. |
| In Ada 95 the conversion semantics are unambiguous, and rounding away from 0 |
| is required. Numeric code may be affected by this change in semantics. |
| Note, though, that this issue is no worse than already existed in Ada 83 |
| when porting code from one vendor to another. |
| |
| @item Tasking |
| The Real-Time Annex introduces a set of policies that define the behavior of |
| features that were implementation dependent in Ada 83, such as the order in |
| which open select branches are executed. |
| @end table |
| |
| @node Changed semantics |
| @subsection Changed semantics |
| |
| @noindent |
| The worst kind of incompatibility is one where a program that is legal in |
| Ada 83 is also legal in Ada 95 but can have an effect in Ada 95 that was not |
| possible in Ada 83. Fortunately this is extremely rare, but the one |
| situation that you should be alert to is the change in the predefined type |
| @code{Character} from 7-bit ASCII to 8-bit Latin-1. |
| |
| @table @asis |
| @item range of @code{Character} |
| The range of @code{Standard.Character} is now the full 256 characters |
| of Latin-1, whereas in most Ada 83 implementations it was restricted |
| to 128 characters. Although some of the effects of |
| this change will be manifest in compile-time rejection of legal |
| Ada 83 programs it is possible for a working Ada 83 program to have |
| a different effect in Ada 95, one that was not permitted in Ada 83. |
| As an example, the expression |
| @code{Character'Pos(Character'Last)} returned @code{127} in Ada 83 and now |
| delivers @code{255} as its value. |
| In general, you should look at the logic of any |
| character-processing Ada 83 program and see whether it needs to be adapted |
| to work correctly with Latin-1. Note that the predefined Ada 95 API has a |
| character handling package that may be relevant if code needs to be adapted |
| to account for the additional Latin-1 elements. |
| The desirable fix is to |
| modify the program to accommodate the full character set, but in some cases |
| it may be convenient to define a subtype or derived type of Character that |
| covers only the restricted range. |
| @cindex Latin-1 |
| @end table |
| |
| @node Other language compatibility issues |
| @subsection Other language compatibility issues |
| @table @asis |
| @item @option{-gnat83 switch} |
| All implementations of GNAT provide a switch that causes GNAT to operate |
| in Ada 83 mode. In this mode, some but not all compatibility problems |
| of the type described above are handled automatically. For example, the |
| new Ada 95 reserved words are treated simply as identifiers as in Ada 83. |
| However, |
| in practice, it is usually advisable to make the necessary modifications |
| to the program to remove the need for using this switch. |
| See @ref{Compiling Different Versions of Ada}. |
| |
| @item Support for removed Ada 83 pragmas and attributes |
| A number of pragmas and attributes from Ada 83 have been removed from Ada 95, |
| generally because they have been replaced by other mechanisms. Ada 95 |
| compilers are allowed, but not required, to implement these missing |
| elements. In contrast with some other Ada 95 compilers, GNAT implements all |
| such pragmas and attributes, eliminating this compatibility concern. These |
| include @code{pragma Interface} and the floating point type attributes |
| (@code{Emax}, @code{Mantissa}, etc.), among other items. |
| @end table |
| |
| @node Implementation-dependent characteristics |
| @section Implementation-dependent characteristics |
| @noindent |
| Although the Ada language defines the semantics of each construct as |
| precisely as practical, in some situations (for example for reasons of |
| efficiency, or where the effect is heavily dependent on the host or target |
| platform) the implementation is allowed some freedom. In porting Ada 83 |
| code to GNAT, you need to be aware of whether / how the existing code |
| exercised such implementation dependencies. Such characteristics fall into |
| several categories, and GNAT offers specific support in assisting the |
| transition from certain Ada 83 compilers. |
| |
| @menu |
| * Implementation-defined pragmas:: |
| * Implementation-defined attributes:: |
| * Libraries:: |
| * Elaboration order:: |
| * Target-specific aspects:: |
| @end menu |
| |
| @node Implementation-defined pragmas |
| @subsection Implementation-defined pragmas |
| |
| @noindent |
| Ada compilers are allowed to supplement the language-defined pragmas, and |
| these are a potential source of non-portability. All GNAT-defined pragmas |
| are described in the GNAT Reference Manual, and these include several that |
| are specifically intended to correspond to other vendors' Ada 83 pragmas. |
| For migrating from VADS, the pragma @code{Use_VADS_Size} may be useful. |
| For |
| compatibility with HP Ada 83, GNAT supplies the pragmas |
| @code{Extend_System}, @code{Ident}, @code{Inline_Generic}, |
| @code{Interface_Name}, @code{Passive}, @code{Suppress_All}, |
| and @code{Volatile}. |
| Other relevant pragmas include @code{External} and @code{Link_With}. |
| Some vendor-specific |
| Ada 83 pragmas (@code{Share_Generic}, @code{Subtitle}, and @code{Title}) are |
| recognized, thus |
| avoiding compiler rejection of units that contain such pragmas; they are not |
| relevant in a GNAT context and hence are not otherwise implemented. |
| |
| @node Implementation-defined attributes |
| @subsection Implementation-defined attributes |
| |
| Analogous to pragmas, the set of attributes may be extended by an |
| implementation. All GNAT-defined attributes are described in the |
| @cite{GNAT Reference Manual}, and these include several that are specifically |
| intended |
| to correspond to other vendors' Ada 83 attributes. For migrating from VADS, |
| the attribute @code{VADS_Size} may be useful. For compatibility with HP |
| Ada 83, GNAT supplies the attributes @code{Bit}, @code{Machine_Size} and |
| @code{Type_Class}. |
| |
| @node Libraries |
| @subsection Libraries |
| @noindent |
| Vendors may supply libraries to supplement the standard Ada API. If Ada 83 |
| code uses vendor-specific libraries then there are several ways to manage |
| this in Ada 95: |
| @enumerate |
| @item |
| If the source code for the libraries (specifications and bodies) are |
| available, then the libraries can be migrated in the same way as the |
| application. |
| @item |
| If the source code for the specifications but not the bodies are |
| available, then you can reimplement the bodies. |
| @item |
| Some new Ada 95 features obviate the need for library support. For |
| example most Ada 83 vendors supplied a package for unsigned integers. The |
| Ada 95 modular type feature is the preferred way to handle this need, so |
| instead of migrating or reimplementing the unsigned integer package it may |
| be preferable to retrofit the application using modular types. |
| @end enumerate |
| |
| @node Elaboration order |
| @subsection Elaboration order |
| @noindent |
| The implementation can choose any elaboration order consistent with the unit |
| dependency relationship. This freedom means that some orders can result in |
| Program_Error being raised due to an ``Access Before Elaboration'': an attempt |
| to invoke a subprogram its body has been elaborated, or to instantiate a |
| generic before the generic body has been elaborated. By default GNAT |
| attempts to choose a safe order (one that will not encounter access before |
| elaboration problems) by implicitly inserting @code{Elaborate} or |
| @code{Elaborate_All} pragmas where |
| needed. However, this can lead to the creation of elaboration circularities |
| and a resulting rejection of the program by gnatbind. This issue is |
| thoroughly described in @ref{Elaboration Order Handling in GNAT}. |
| In brief, there are several |
| ways to deal with this situation: |
| |
| @itemize @bullet |
| @item |
| Modify the program to eliminate the circularities, e.g. by moving |
| elaboration-time code into explicitly-invoked procedures |
| @item |
| Constrain the elaboration order by including explicit @code{Elaborate_Body} or |
| @code{Elaborate} pragmas, and then inhibit the generation of implicit |
| @code{Elaborate_All} |
| pragmas either globally (as an effect of the @option{-gnatE} switch) or locally |
| (by selectively suppressing elaboration checks via pragma |
| @code{Suppress(Elaboration_Check)} when it is safe to do so). |
| @end itemize |
| |
| @node Target-specific aspects |
| @subsection Target-specific aspects |
| @noindent |
| Low-level applications need to deal with machine addresses, data |
| representations, interfacing with assembler code, and similar issues. If |
| such an Ada 83 application is being ported to different target hardware (for |
| example where the byte endianness has changed) then you will need to |
| carefully examine the program logic; the porting effort will heavily depend |
| on the robustness of the original design. Moreover, Ada 95 is sometimes |
| incompatible with typical Ada 83 compiler practices regarding implicit |
| packing, the meaning of the Size attribute, and the size of access values. |
| GNAT's approach to these issues is described in @ref{Representation Clauses}. |
| |
| @node Compatibility with Other Ada 95 Systems |
| @section Compatibility with Other Ada 95 Systems |
| |
| @noindent |
| Providing that programs avoid the use of implementation dependent and |
| implementation defined features of Ada 95, as documented in the Ada 95 |
| reference manual, there should be a high degree of portability between |
| GNAT and other Ada 95 systems. The following are specific items which |
| have proved troublesome in moving GNAT programs to other Ada 95 |
| compilers, but do not affect porting code to GNAT@. |
| |
| @table @asis |
| @item Ada 83 Pragmas and Attributes |
| Ada 95 compilers are allowed, but not required, to implement the missing |
| Ada 83 pragmas and attributes that are no longer defined in Ada 95. |
| GNAT implements all such pragmas and attributes, eliminating this as |
| a compatibility concern, but some other Ada 95 compilers reject these |
| pragmas and attributes. |
| |
| @item Special-needs Annexes |
| GNAT implements the full set of special needs annexes. At the |
| current time, it is the only Ada 95 compiler to do so. This means that |
| programs making use of these features may not be portable to other Ada |
| 95 compilation systems. |
| |
| @item Representation Clauses |
| Some other Ada 95 compilers implement only the minimal set of |
| representation clauses required by the Ada 95 reference manual. GNAT goes |
| far beyond this minimal set, as described in the next section. |
| @end table |
| |
| @node Representation Clauses |
| @section Representation Clauses |
| |
| @noindent |
| The Ada 83 reference manual was quite vague in describing both the minimal |
| required implementation of representation clauses, and also their precise |
| effects. The Ada 95 reference manual is much more explicit, but the minimal |
| set of capabilities required in Ada 95 is quite limited. |
| |
| GNAT implements the full required set of capabilities described in the |
| Ada 95 reference manual, but also goes much beyond this, and in particular |
| an effort has been made to be compatible with existing Ada 83 usage to the |
| greatest extent possible. |
| |
| A few cases exist in which Ada 83 compiler behavior is incompatible with |
| requirements in the Ada 95 reference manual. These are instances of |
| intentional or accidental dependence on specific implementation dependent |
| characteristics of these Ada 83 compilers. The following is a list of |
| the cases most likely to arise in existing legacy Ada 83 code. |
| |
| @table @asis |
| @item Implicit Packing |
| Some Ada 83 compilers allowed a Size specification to cause implicit |
| packing of an array or record. This could cause expensive implicit |
| conversions for change of representation in the presence of derived |
| types, and the Ada design intends to avoid this possibility. |
| Subsequent AI's were issued to make it clear that such implicit |
| change of representation in response to a Size clause is inadvisable, |
| and this recommendation is represented explicitly in the Ada 95 RM |
| as implementation advice that is followed by GNAT@. |
| The problem will show up as an error |
| message rejecting the size clause. The fix is simply to provide |
| the explicit pragma @code{Pack}, or for more fine tuned control, provide |
| a Component_Size clause. |
| |
| @item Meaning of Size Attribute |
| The Size attribute in Ada 95 for discrete types is defined as being the |
| minimal number of bits required to hold values of the type. For example, |
| on a 32-bit machine, the size of Natural will typically be 31 and not |
| 32 (since no sign bit is required). Some Ada 83 compilers gave 31, and |
| some 32 in this situation. This problem will usually show up as a compile |
| time error, but not always. It is a good idea to check all uses of the |
| 'Size attribute when porting Ada 83 code. The GNAT specific attribute |
| Object_Size can provide a useful way of duplicating the behavior of |
| some Ada 83 compiler systems. |
| |
| @item Size of Access Types |
| A common assumption in Ada 83 code is that an access type is in fact a pointer, |
| and that therefore it will be the same size as a System.Address value. This |
| assumption is true for GNAT in most cases with one exception. For the case of |
| a pointer to an unconstrained array type (where the bounds may vary from one |
| value of the access type to another), the default is to use a ``fat pointer'', |
| which is represented as two separate pointers, one to the bounds, and one to |
| the array. This representation has a number of advantages, including improved |
| efficiency. However, it may cause some difficulties in porting existing Ada 83 |
| code which makes the assumption that, for example, pointers fit in 32 bits on |
| a machine with 32-bit addressing. |
| |
| To get around this problem, GNAT also permits the use of ``thin pointers'' for |
| access types in this case (where the designated type is an unconstrained array |
| type). These thin pointers are indeed the same size as a System.Address value. |
| To specify a thin pointer, use a size clause for the type, for example: |
| |
| @smallexample @c ada |
| type X is access all String; |
| for X'Size use Standard'Address_Size; |
| @end smallexample |
| |
| @noindent |
| which will cause the type X to be represented using a single pointer. |
| When using this representation, the bounds are right behind the array. |
| This representation is slightly less efficient, and does not allow quite |
| such flexibility in the use of foreign pointers or in using the |
| Unrestricted_Access attribute to create pointers to non-aliased objects. |
| But for any standard portable use of the access type it will work in |
| a functionally correct manner and allow porting of existing code. |
| Note that another way of forcing a thin pointer representation |
| is to use a component size clause for the element size in an array, |
| or a record representation clause for an access field in a record. |
| @end table |
| |
| @ifclear vms |
| @c This brief section is only in the non-VMS version |
| @c The complete chapter on HP Ada is in the VMS version |
| @node Compatibility with HP Ada 83 |
| @section Compatibility with HP Ada 83 |
| |
| @noindent |
| The VMS version of GNAT fully implements all the pragmas and attributes |
| provided by HP Ada 83, as well as providing the standard HP Ada 83 |
| libraries, including Starlet. In addition, data layouts and parameter |
| passing conventions are highly compatible. This means that porting |
| existing HP Ada 83 code to GNAT in VMS systems should be easier than |
| most other porting efforts. The following are some of the most |
| significant differences between GNAT and HP Ada 83. |
| |
| @table @asis |
| @item Default floating-point representation |
| In GNAT, the default floating-point format is IEEE, whereas in HP Ada 83, |
| it is VMS format. GNAT does implement the necessary pragmas |
| (Long_Float, Float_Representation) for changing this default. |
| |
| @item System |
| The package System in GNAT exactly corresponds to the definition in the |
| Ada 95 reference manual, which means that it excludes many of the |
| HP Ada 83 extensions. However, a separate package Aux_DEC is provided |
| that contains the additional definitions, and a special pragma, |
| Extend_System allows this package to be treated transparently as an |
| extension of package System. |
| |
| @item To_Address |
| The definitions provided by Aux_DEC are exactly compatible with those |
| in the HP Ada 83 version of System, with one exception. |
| HP Ada provides the following declarations: |
| |
| @smallexample @c ada |
| TO_ADDRESS (INTEGER) |
| TO_ADDRESS (UNSIGNED_LONGWORD) |
| TO_ADDRESS (universal_integer) |
| @end smallexample |
| |
| @noindent |
| The version of TO_ADDRESS taking a universal integer argument is in fact |
| an extension to Ada 83 not strictly compatible with the reference manual. |
| In GNAT, we are constrained to be exactly compatible with the standard, |
| and this means we cannot provide this capability. In HP Ada 83, the |
| point of this definition is to deal with a call like: |
| |
| @smallexample @c ada |
| TO_ADDRESS (16#12777#); |
| @end smallexample |
| |
| @noindent |
| Normally, according to the Ada 83 standard, one would expect this to be |
| ambiguous, since it matches both the INTEGER and UNSIGNED_LONGWORD forms |
| of TO_ADDRESS@. However, in HP Ada 83, there is no ambiguity, since the |
| definition using universal_integer takes precedence. |
| |
| In GNAT, since the version with universal_integer cannot be supplied, it is |
| not possible to be 100% compatible. Since there are many programs using |
| numeric constants for the argument to TO_ADDRESS, the decision in GNAT was |
| to change the name of the function in the UNSIGNED_LONGWORD case, so the |
| declarations provided in the GNAT version of AUX_Dec are: |
| |
| @smallexample @c ada |
| function To_Address (X : Integer) return Address; |
| pragma Pure_Function (To_Address); |
| |
| function To_Address_Long (X : Unsigned_Longword) |
| return Address; |
| pragma Pure_Function (To_Address_Long); |
| @end smallexample |
| |
| @noindent |
| This means that programs using TO_ADDRESS for UNSIGNED_LONGWORD must |
| change the name to TO_ADDRESS_LONG@. |
| |
| @item Task_Id values |
| The Task_Id values assigned will be different in the two systems, and GNAT |
| does not provide a specified value for the Task_Id of the environment task, |
| which in GNAT is treated like any other declared task. |
| @end table |
| |
| For full details on these and other less significant compatibility issues, |
| see appendix E of the HP publication entitled @cite{HP Ada, Technical |
| Overview and Comparison on HP Platforms}. |
| |
| For GNAT running on other than VMS systems, all the HP Ada 83 pragmas and |
| attributes are recognized, although only a subset of them can sensibly |
| be implemented. The description of pragmas in the |
| @cite{GNAT Reference Manual} |
| indicates whether or not they are applicable to non-VMS systems. |
| @end ifclear |
| |
| @ifset vms |
| @node Transitioning from Alpha to I64 OpenVMS |
| @section Transitioning from Alpha to I64 OpenVMS |
| |
| @menu |
| * Introduction to transitioning:: |
| * Migration of 32 bit code:: |
| * Taking advantage of 64 bit addressing:: |
| * Technical details:: |
| @end menu |
| |
| @node Introduction to transitioning |
| @subsection Introduction to transitioning |
| |
| @noindent |
| This section is meant to assist users of @value{EDITION} |
| for Alpha OpenVMS who are planning to transition to the I64 architecture. |
| @value{EDITION} for Open VMS I64 has been designed to meet |
| three main goals: |
| |
| @enumerate |
| @item |
| Providing a full conforming implementation of the Ada 95 language |
| |
| @item |
| Allowing maximum backward compatibility, thus easing migration of existing |
| Ada source code |
| |
| @item |
| Supplying a path for exploiting the full I64 address range |
| @end enumerate |
| |
| @noindent |
| Ada's strong typing semantics has made it |
| impractical to have different 32-bit and 64-bit modes. As soon as |
| one object could possibly be outside the 32-bit address space, this |
| would make it necessary for the @code{System.Address} type to be 64 bits. |
| In particular, this would cause inconsistencies if 32-bit code is |
| called from 64-bit code that raises an exception. |
| |
| This issue has been resolved by always using 64-bit addressing |
| at the system level, but allowing for automatic conversions between |
| 32-bit and 64-bit addresses where required. Thus users who |
| do not currently require 64-bit addressing capabilities, can |
| recompile their code with only minimal changes (and indeed |
| if the code is written in portable Ada, with no assumptions about |
| the size of the @code{Address} type, then no changes at all are necessary). |
| At the same time, |
| this approach provides a simple, gradual upgrade path to future |
| use of larger memories than available for 32-bit systems. |
| Also, newly written applications or libraries will by default |
| be fully compatible with future systems exploiting 64-bit |
| addressing capabilities present in I64. |
| |
| @ref{Migration of 32 bit code}, will focus on porting applications |
| that do not require more than 2 GB of |
| addressable memory. This code will be referred to as |
| @emph{32-bit code}. |
| For applications intending to exploit the full I64 address space, |
| @ref{Taking advantage of 64 bit addressing}, |
| will consider further changes that may be required. |
| Such code is called @emph{64-bit code} in the |
| remainder of this guide. |
| |
| |
| @node Migration of 32 bit code |
| @subsection Migration of 32-bit code |
| |
| @menu |
| * Address types:: |
| * Access types:: |
| * Unchecked conversions:: |
| * Predefined constants:: |
| * Single source compatibility:: |
| * Experience with source compatibility:: |
| @end menu |
| |
| @node Address types |
| @subsubsection Address types |
| |
| @noindent |
| To solve the problem of mixing 64-bit and 32-bit addressing, |
| while maintaining maximum backward compatibility, the following |
| approach has been taken: |
| |
| @itemize @bullet |
| @item |
| @code{System.Address} always has a size of 64 bits |
| |
| @item |
| @code{System.Short_Address} is a 32-bit subtype of @code{System.Address} |
| @end itemize |
| |
| |
| @noindent |
| Since @code{System.Short_Address} is a subtype of @code{System.Address}, |
| a @code{Short_Address} |
| may be used where an @code{Address} is required, and vice versa, without |
| needing explicit type conversions. |
| By virtue of the Open VMS I64 parameter passing conventions, |
| even imported |
| and exported subprograms that have 32-bit address parameters are |
| compatible with those that have 64-bit address parameters. |
| (See @ref{Making code 64 bit clean} for details.) |
| |
| The areas that may need attention are those where record types have |
| been defined that contain components of the type @code{System.Address}, and |
| where objects of this type are passed to code expecting a record layout with |
| 32-bit addresses. |
| |
| Different compilers on different platforms cannot be |
| expected to represent the same type in the same way, |
| since alignment constraints |
| and other system-dependent properties affect the compiler's decision. |
| For that reason, Ada code |
| generally uses representation clauses to specify the expected |
| layout where required. |
| |
| If such a representation clause uses 32 bits for a component having |
| the type @code{System.Address}, GNAT Pro for OpenVMS I64 will detect |
| that error and produce a specific diagnostic message. |
| The developer should then determine whether the representation |
| should be 64 bits or not and make either of two changes: |
| change the size to 64 bits and leave the type as @code{System.Address}, or |
| leave the size as 32 bits and change the type to @code{System.Short_Address}. |
| Since @code{Short_Address} is a subtype of @code{Address}, no changes are |
| required in any code setting or accessing the field; the compiler will |
| automatically perform any needed conversions between address |
| formats. |
| |
| @node Access types |
| @subsubsection Access types |
| |
| @noindent |
| By default, objects designated by access values are always |
| allocated in the 32-bit |
| address space. Thus legacy code will never contain |
| any objects that are not addressable with 32-bit addresses, and |
| the compiler will never raise exceptions as result of mixing |
| 32-bit and 64-bit addresses. |
| |
| However, the access values themselves are represented in 64 bits, for optimum |
| performance and future compatibility with 64-bit code. As was |
| the case with @code{System.Address}, the compiler will give an error message |
| if an object or record component has a representation clause that |
| requires the access value to fit in 32 bits. In such a situation, |
| an explicit size clause for the access type, specifying 32 bits, |
| will have the desired effect. |
| |
| General access types (declared with @code{access all}) can never be |
| 32 bits, as values of such types must be able to refer to any object |
| of the designated type, |
| including objects residing outside the 32-bit address range. |
| Existing Ada 83 code will not contain such type definitions, |
| however, since general access types were introduced in Ada 95. |
| |
| @node Unchecked conversions |
| @subsubsection Unchecked conversions |
| |
| @noindent |
| In the case of an @code{Unchecked_Conversion} where the source type is a |
| 64-bit access type or the type @code{System.Address}, and the target |
| type is a 32-bit type, the compiler will generate a warning. |
| Even though the generated code will still perform the required |
| conversions, it is highly recommended in these cases to use |
| respectively a 32-bit access type or @code{System.Short_Address} |
| as the source type. |
| |
| @node Predefined constants |
| @subsubsection Predefined constants |
| |
| @noindent |
| The following predefined constants have changed: |
| |
| @multitable {@code{System.Address_Size}} {2**32} {2**64} |
| @item @b{Constant} @tab @b{Old} @tab @b{New} |
| @item @code{System.Word_Size} @tab 32 @tab 64 |
| @item @code{System.Memory_Size} @tab 2**32 @tab 2**64 |
| @item @code{System.Address_Size} @tab 32 @tab 64 |
| @end multitable |
| |
| @noindent |
| If you need to refer to the specific |
| memory size of a 32-bit implementation, instead of the |
| actual memory size, use @code{System.Short_Memory_Size} |
| rather than @code{System.Memory_Size}. |
| Similarly, references to @code{System.Address_Size} may need |
| to be replaced by @code{System.Short_Address'Size}. |
| The program @command{gnatfind} may be useful for locating |
| references to the above constants, so that you can verify that they |
| are still correct. |
| |
| @node Single source compatibility |
| @subsubsection Single source compatibility |
| |
| @noindent |
| In order to allow the same source code to be compiled on |
| both Alpha and I64 platforms, GNAT Pro for Alpha OpenVMS |
| defines @code{System.Short_Address} and System.Short_Memory_Size |
| as aliases of respectively @code{System.Address} and |
| @code{System.Memory_Size}. |
| (These aliases also leave the door open for a possible |
| future ``upgrade'' of OpenVMS Alpha to a 64-bit address space.) |
| |
| @node Experience with source compatibility |
| @subsubsection Experience with source compatibility |
| |
| @noindent |
| The Security Server and STARLET provide an interesting ``test case'' |
| for source compatibility issues, since it is in such system code |
| where assumptions about @code{Address} size might be expected to occur. |
| Indeed, there were a small number of occasions in the Security Server |
| file @file{jibdef.ads} |
| where a representation clause for a record type specified |
| 32 bits for a component of type @code{Address}. |
| All of these errors were detected by the compiler. |
| The repair was obvious and immediate; to simply replace @code{Address} by |
| @code{Short_Address}. |
| |
| In the case of STARLET, there were several record types that should |
| have had representation clauses but did not. In these record types |
| there was an implicit assumption that an @code{Address} value occupied |
| 32 bits. |
| These compiled without error, but their usage resulted in run-time error |
| returns from STARLET system calls. |
| To assist in the compile-time detection of such situations, we |
| plan to include a switch to generate a warning message when a |
| record component is of type @code{Address}. |
| |
| |
| @c **************************************** |
| @node Taking advantage of 64 bit addressing |
| @subsection Taking advantage of 64-bit addressing |
| |
| @menu |
| * Making code 64 bit clean:: |
| * Allocating memory from the 64 bit storage pool:: |
| * Restrictions on use of 64 bit objects:: |
| * Using 64 bit storage pools by default:: |
| * General access types:: |
| * STARLET and other predefined libraries:: |
| @end menu |
| |
| @node Making code 64 bit clean |
| @subsubsection Making code 64-bit clean |
| |
| @noindent |
| In order to prevent problems that may occur when (parts of) a |
| system start using memory outside the 32-bit address range, |
| we recommend some additional guidelines: |
| |
| @itemize @bullet |
| @item |
| For imported subprograms that take parameters of the |
| type @code{System.Address}, ensure that these subprograms can |
| indeed handle 64-bit addresses. If not, or when in doubt, |
| change the subprogram declaration to specify |
| @code{System.Short_Address} instead. |
| |
| @item |
| Resolve all warnings related to size mismatches in |
| unchecked conversions. Failing to do so causes |
| erroneous execution if the source object is outside |
| the 32-bit address space. |
| |
| @item |
| (optional) Explicitly use the 32-bit storage pool |
| for access types used in a 32-bit context, or use |
| generic access types where possible |
| (@pxref{Restrictions on use of 64 bit objects}). |
| @end itemize |
| |
| @noindent |
| If these rules are followed, the compiler will automatically insert |
| any necessary checks to ensure that no addresses or access values |
| passed to 32-bit code ever refer to objects outside the 32-bit |
| address range. |
| Any attempt to do this will raise @code{Constraint_Error}. |
| |
| @node Allocating memory from the 64 bit storage pool |
| @subsubsection Allocating memory from the 64-bit storage pool |
| |
| @noindent |
| For any access type @code{T} that potentially requires memory allocations |
| beyond the 32-bit address space, |
| use the following representation clause: |
| |
| @smallexample @c ada |
| for T'Storage_Pool use System.Pool_64; |
| @end smallexample |
| |
| |
| @node Restrictions on use of 64 bit objects |
| @subsubsection Restrictions on use of 64-bit objects |
| |
| @noindent |
| Taking the address of an object allocated from a 64-bit storage pool, |
| and then passing this address to a subprogram expecting |
| @code{System.Short_Address}, |
| or assigning it to a variable of type @code{Short_Address}, will cause |
| @code{Constraint_Error} to be raised. In case the code is not 64-bit clean |
| (@pxref{Making code 64 bit clean}), or checks are suppressed, |
| no exception is raised and execution |
| will become erroneous. |
| |
| @node Using 64 bit storage pools by default |
| @subsubsection Using 64-bit storage pools by default |
| |
| @noindent |
| In some cases it may be desirable to have the compiler allocate |
| from 64-bit storage pools by default. This may be the case for |
| libraries that are 64-bit clean, but may be used in both 32-bit |
| and 64-bit contexts. For these cases the following configuration |
| pragma may be specified: |
| |
| @smallexample @c ada |
| pragma Pool_64_Default; |
| @end smallexample |
| |
| @noindent |
| Any code compiled in the context of this pragma will by default |
| use the @code{System.Pool_64} storage pool. This default may be overridden |
| for a specific access type @code{T} by the representation clause: |
| |
| @smallexample @c ada |
| for T'Storage_Pool use System.Pool_32; |
| @end smallexample |
| |
| @noindent |
| Any object whose address may be passed to a subprogram with a |
| @code{Short_Address} argument, or assigned to a variable of type |
| @code{Short_Address}, needs to be allocated from this pool. |
| |
| @node General access types |
| @subsubsection General access types |
| |
| @noindent |
| Objects designated by access values from a |
| general access type (declared with @code{access all}) are never allocated |
| from a 64-bit storage pool. Code that uses general access types will |
| accept objects allocated in either 32-bit or 64-bit address spaces, |
| but never allocate objects outside the 32-bit address space. |
| Using general access types ensures maximum compatibility with both |
| 32-bit and 64-bit code. |
| |
| |
| @node STARLET and other predefined libraries |
| @subsubsection STARLET and other predefined libraries |
| |
| @noindent |
| All code that comes as part of GNAT is 64-bit clean, but the |
| restrictions given in @ref{Restrictions on use of 64 bit objects}, |
| still apply. Look at the package |
| specifications to see in which contexts objects allocated |
| in 64-bit address space are acceptable. |
| |
| @node Technical details |
| @subsection Technical details |
| |
| @noindent |
| GNAT Pro for Open VMS I64 takes advantage of the freedom given in the Ada |
| standard with respect to the type of @code{System.Address}. Previous versions |
| of GNAT Pro have defined this type as private and implemented it as |
| a modular type. |
| |
| In order to allow defining @code{System.Short_Address} as a proper subtype, |
| and to match the implicit sign extension in parameter passing, |
| in GNAT Pro for Open VMS I64, @code{System.Address} is defined as a |
| visible (i.e., non-private) integer type. |
| Standard operations on the type, such as the binary operators ``+'', ``-'', |
| etc., that take @code{Address} operands and return an @code{Address} result, |
| have been hidden by declaring these |
| @code{abstract}, an Ada 95 feature that helps avoid the potential ambiguities |
| that would otherwise result from overloading. |
| (Note that, although @code{Address} is a visible integer type, |
| good programming practice dictates against exploiting the type's |
| integer properties such as literals, since this will compromise |
| code portability.) |
| |
| Defining @code{Address} as a visible integer type helps achieve |
| maximum compatibility for existing Ada code, |
| without sacrificing the capabilities of the I64 architecture. |
| @end ifset |
| |
| |
| @c ************************************************ |
| @ifset unw |
| @node Microsoft Windows Topics |
| @appendix Microsoft Windows Topics |
| @cindex Windows NT |
| @cindex Windows 95 |
| @cindex Windows 98 |
| |
| @noindent |
| This chapter describes topics that are specific to the Microsoft Windows |
| platforms (NT, 2000, and XP Professional). |
| |
| @menu |
| * Using GNAT on Windows:: |
| * Using a network installation of GNAT:: |
| * CONSOLE and WINDOWS subsystems:: |
| * Temporary Files:: |
| * Mixed-Language Programming on Windows:: |
| * Windows Calling Conventions:: |
| * Introduction to Dynamic Link Libraries (DLLs):: |
| * Using DLLs with GNAT:: |
| * Building DLLs with GNAT:: |
| * Building DLLs with GNAT Project files:: |
| * Building DLLs with gnatdll:: |
| * GNAT and Windows Resources:: |
| * Debugging a DLL:: |
| * Setting Stack Size from gnatlink:: |
| * Setting Heap Size from gnatlink:: |
| @end menu |
| |
| @node Using GNAT on Windows |
| @section Using GNAT on Windows |
| |
| @noindent |
| One of the strengths of the GNAT technology is that its tool set |
| (@command{gcc}, @command{gnatbind}, @command{gnatlink}, @command{gnatmake}, the |
| @code{gdb} debugger, etc.) is used in the same way regardless of the |
| platform. |
| |
| On Windows this tool set is complemented by a number of Microsoft-specific |
| tools that have been provided to facilitate interoperability with Windows |
| when this is required. With these tools: |
| |
| @itemize @bullet |
| |
| @item |
| You can build applications using the @code{CONSOLE} or @code{WINDOWS} |
| subsystems. |
| |
| @item |
| You can use any Dynamically Linked Library (DLL) in your Ada code (both |
| relocatable and non-relocatable DLLs are supported). |
| |
| @item |
| You can build Ada DLLs for use in other applications. These applications |
| can be written in a language other than Ada (e.g., C, C++, etc). Again both |
| relocatable and non-relocatable Ada DLLs are supported. |
| |
| @item |
| You can include Windows resources in your Ada application. |
| |
| @item |
| You can use or create COM/DCOM objects. |
| @end itemize |
| |
| @noindent |
| Immediately below are listed all known general GNAT-for-Windows restrictions. |
| Other restrictions about specific features like Windows Resources and DLLs |
| are listed in separate sections below. |
| |
| @itemize @bullet |
| |
| @item |
| It is not possible to use @code{GetLastError} and @code{SetLastError} |
| when tasking, protected records, or exceptions are used. In these |
| cases, in order to implement Ada semantics, the GNAT run-time system |
| calls certain Win32 routines that set the last error variable to 0 upon |
| success. It should be possible to use @code{GetLastError} and |
| @code{SetLastError} when tasking, protected record, and exception |
| features are not used, but it is not guaranteed to work. |
| |
| @item |
| It is not possible to link against Microsoft libraries except for |
| import libraries. The library must be built to be compatible with |
| @file{MSVCRT.LIB} (/MD Microsoft compiler option), @file{LIBC.LIB} and |
| @file{LIBCMT.LIB} (/ML or /MT Microsoft compiler options) are known to |
| not be compatible with the GNAT runtime. Even if the library is |
| compatible with @file{MSVCRT.LIB} it is not guaranteed to work. |
| |
| @item |
| When the compilation environment is located on FAT32 drives, users may |
| experience recompilations of the source files that have not changed if |
| Daylight Saving Time (DST) state has changed since the last time files |
| were compiled. NTFS drives do not have this problem. |
| |
| @item |
| No components of the GNAT toolset use any entries in the Windows |
| registry. The only entries that can be created are file associations and |
| PATH settings, provided the user has chosen to create them at installation |
| time, as well as some minimal book-keeping information needed to correctly |
| uninstall or integrate different GNAT products. |
| @end itemize |
| |
| @node Using a network installation of GNAT |
| @section Using a network installation of GNAT |
| |
| @noindent |
| Make sure the system on which GNAT is installed is accessible from the |
| current machine, i.e. the install location is shared over the network. |
| Shared resources are accessed on Windows by means of UNC paths, which |
| have the format @code{\\server\sharename\path} |
| |
| In order to use such a network installation, simply add the UNC path of the |
| @file{bin} directory of your GNAT installation in front of your PATH. For |
| example, if GNAT is installed in @file{\GNAT} directory of a share location |
| called @file{c-drive} on a machine @file{LOKI}, the following command will |
| make it available: |
| |
| @code{@ @ @ path \\loki\c-drive\gnat\bin;%path%} |
| |
| Be aware that every compilation using the network installation results in the |
| transfer of large amounts of data across the network and will likely cause |
| serious performance penalty. |
| |
| @node CONSOLE and WINDOWS subsystems |
| @section CONSOLE and WINDOWS subsystems |
| @cindex CONSOLE Subsystem |
| @cindex WINDOWS Subsystem |
| @cindex -mwindows |
| |
| @noindent |
| There are two main subsystems under Windows. The @code{CONSOLE} subsystem |
| (which is the default subsystem) will always create a console when |
| launching the application. This is not something desirable when the |
| application has a Windows GUI. To get rid of this console the |
| application must be using the @code{WINDOWS} subsystem. To do so |
| the @option{-mwindows} linker option must be specified. |
| |
| @smallexample |
| $ gnatmake winprog -largs -mwindows |
| @end smallexample |
| |
| @node Temporary Files |
| @section Temporary Files |
| @cindex Temporary files |
| |
| @noindent |
| It is possible to control where temporary files gets created by setting |
| the TMP environment variable. The file will be created: |
| |
| @itemize |
| @item Under the directory pointed to by the TMP environment variable if |
| this directory exists. |
| |
| @item Under c:\temp, if the TMP environment variable is not set (or not |
| pointing to a directory) and if this directory exists. |
| |
| @item Under the current working directory otherwise. |
| @end itemize |
| |
| @noindent |
| This allows you to determine exactly where the temporary |
| file will be created. This is particularly useful in networked |
| environments where you may not have write access to some |
| directories. |
| |
| @node Mixed-Language Programming on Windows |
| @section Mixed-Language Programming on Windows |
| |
| @noindent |
| Developing pure Ada applications on Windows is no different than on |
| other GNAT-supported platforms. However, when developing or porting an |
| application that contains a mix of Ada and C/C++, the choice of your |
| Windows C/C++ development environment conditions your overall |
| interoperability strategy. |
| |
| If you use @command{gcc} to compile the non-Ada part of your application, |
| there are no Windows-specific restrictions that affect the overall |
| interoperability with your Ada code. If you plan to use |
| Microsoft tools (e.g. Microsoft Visual C/C++), you should be aware of |
| the following limitations: |
| |
| @itemize @bullet |
| @item |
| You cannot link your Ada code with an object or library generated with |
| Microsoft tools if these use the @code{.tls} section (Thread Local |
| Storage section) since the GNAT linker does not yet support this section. |
| |
| @item |
| You cannot link your Ada code with an object or library generated with |
| Microsoft tools if these use I/O routines other than those provided in |
| the Microsoft DLL: @code{msvcrt.dll}. This is because the GNAT run time |
| uses the services of @code{msvcrt.dll} for its I/Os. Use of other I/O |
| libraries can cause a conflict with @code{msvcrt.dll} services. For |
| instance Visual C++ I/O stream routines conflict with those in |
| @code{msvcrt.dll}. |
| @end itemize |
| |
| @noindent |
| If you do want to use the Microsoft tools for your non-Ada code and hit one |
| of the above limitations, you have two choices: |
| |
| @enumerate |
| @item |
| Encapsulate your non Ada code in a DLL to be linked with your Ada |
| application. In this case, use the Microsoft or whatever environment to |
| build the DLL and use GNAT to build your executable |
| (@pxref{Using DLLs with GNAT}). |
| |
| @item |
| Or you can encapsulate your Ada code in a DLL to be linked with the |
| other part of your application. In this case, use GNAT to build the DLL |
| (@pxref{Building DLLs with GNAT}) and use the Microsoft or whatever |
| environment to build your executable. |
| @end enumerate |
| |
| @node Windows Calling Conventions |
| @section Windows Calling Conventions |
| @findex Stdcall |
| @findex APIENTRY |
| |
| @menu |
| * C Calling Convention:: |
| * Stdcall Calling Convention:: |
| * Win32 Calling Convention:: |
| * DLL Calling Convention:: |
| @end menu |
| |
| @noindent |
| When a subprogram @code{F} (caller) calls a subprogram @code{G} |
| (callee), there are several ways to push @code{G}'s parameters on the |
| stack and there are several possible scenarios to clean up the stack |
| upon @code{G}'s return. A calling convention is an agreed upon software |
| protocol whereby the responsibilities between the caller (@code{F}) and |
| the callee (@code{G}) are clearly defined. Several calling conventions |
| are available for Windows: |
| |
| @itemize @bullet |
| @item |
| @code{C} (Microsoft defined) |
| |
| @item |
| @code{Stdcall} (Microsoft defined) |
| |
| @item |
| @code{Win32} (GNAT specific) |
| |
| @item |
| @code{DLL} (GNAT specific) |
| @end itemize |
| |
| @node C Calling Convention |
| @subsection @code{C} Calling Convention |
| |
| @noindent |
| This is the default calling convention used when interfacing to C/C++ |
| routines compiled with either @command{gcc} or Microsoft Visual C++. |
| |
| In the @code{C} calling convention subprogram parameters are pushed on the |
| stack by the caller from right to left. The caller itself is in charge of |
| cleaning up the stack after the call. In addition, the name of a routine |
| with @code{C} calling convention is mangled by adding a leading underscore. |
| |
| The name to use on the Ada side when importing (or exporting) a routine |
| with @code{C} calling convention is the name of the routine. For |
| instance the C function: |
| |
| @smallexample |
| int get_val (long); |
| @end smallexample |
| |
| @noindent |
| should be imported from Ada as follows: |
| |
| @smallexample @c ada |
| @group |
| function Get_Val (V : Interfaces.C.long) return Interfaces.C.int; |
| pragma Import (C, Get_Val, External_Name => "get_val"); |
| @end group |
| @end smallexample |
| |
| @noindent |
| Note that in this particular case the @code{External_Name} parameter could |
| have been omitted since, when missing, this parameter is taken to be the |
| name of the Ada entity in lower case. When the @code{Link_Name} parameter |
| is missing, as in the above example, this parameter is set to be the |
| @code{External_Name} with a leading underscore. |
| |
| When importing a variable defined in C, you should always use the @code{C} |
| calling convention unless the object containing the variable is part of a |
| DLL (in which case you should use the @code{Stdcall} calling |
| convention, @pxref{Stdcall Calling Convention}). |
| |
| @node Stdcall Calling Convention |
| @subsection @code{Stdcall} Calling Convention |
| |
| @noindent |
| This convention, which was the calling convention used for Pascal |
| programs, is used by Microsoft for all the routines in the Win32 API for |
| efficiency reasons. It must be used to import any routine for which this |
| convention was specified. |
| |
| In the @code{Stdcall} calling convention subprogram parameters are pushed |
| on the stack by the caller from right to left. The callee (and not the |
| caller) is in charge of cleaning the stack on routine exit. In addition, |
| the name of a routine with @code{Stdcall} calling convention is mangled by |
| adding a leading underscore (as for the @code{C} calling convention) and a |
| trailing @code{@@}@code{@i{nn}}, where @i{nn} is the overall size (in |
| bytes) of the parameters passed to the routine. |
| |
| The name to use on the Ada side when importing a C routine with a |
| @code{Stdcall} calling convention is the name of the C routine. The leading |
| underscore and trailing @code{@@}@code{@i{nn}} are added automatically by |
| the compiler. For instance the Win32 function: |
| |
| @smallexample |
| @b{APIENTRY} int get_val (long); |
| @end smallexample |
| |
| @noindent |
| should be imported from Ada as follows: |
| |
| @smallexample @c ada |
| @group |
| function Get_Val (V : Interfaces.C.long) return Interfaces.C.int; |
| pragma Import (Stdcall, Get_Val); |
| -- On the x86 a long is 4 bytes, so the Link_Name is "_get_val@@4" |
| @end group |
| @end smallexample |
| |
| @noindent |
| As for the @code{C} calling convention, when the @code{External_Name} |
| parameter is missing, it is taken to be the name of the Ada entity in lower |
| case. If instead of writing the above import pragma you write: |
| |
| @smallexample @c ada |
| @group |
| function Get_Val (V : Interfaces.C.long) return Interfaces.C.int; |
| pragma Import (Stdcall, Get_Val, External_Name => "retrieve_val"); |
| @end group |
| @end smallexample |
| |
| @noindent |
| then the imported routine is @code{_retrieve_val@@4}. However, if instead |
| of specifying the @code{External_Name} parameter you specify the |
| @code{Link_Name} as in the following example: |
| |
| @smallexample @c ada |
| @group |
| function Get_Val (V : Interfaces.C.long) return Interfaces.C.int; |
| pragma Import (Stdcall, Get_Val, Link_Name => "retrieve_val"); |
| @end group |
| @end smallexample |
| |
| @noindent |
| then the imported routine is @code{retrieve_val@@4}, that is, there is no |
| trailing underscore but the appropriate @code{@@}@code{@i{nn}} is always |
| added at the end of the @code{Link_Name} by the compiler. |
| |
| @noindent |
| Note, that in some special cases a DLL's entry point name lacks a trailing |
| @code{@@}@code{@i{nn}} while the exported name generated for a call has it. |
| The @code{gnatdll} tool, which creates the import library for the DLL, is able |
| to handle those cases (@pxref{Using gnatdll} for the description of |
| the switches). |
| |
| @noindent |
| It is also possible to import variables defined in a DLL by using an |
| import pragma for a variable. As an example, if a DLL contains a |
| variable defined as: |
| |
| @smallexample |
| int my_var; |
| @end smallexample |
| |
| @noindent |
| then, to access this variable from Ada you should write: |
| |
| @smallexample @c ada |
| @group |
| My_Var : Interfaces.C.int; |
| pragma Import (Stdcall, My_Var); |
| @end group |
| @end smallexample |
| |
| @noindent |
| Note that to ease building cross-platform bindings this convention |
| will be handled as a @code{C} calling convention on non Windows platforms. |
| |
| @node Win32 Calling Convention |
| @subsection @code{Win32} Calling Convention |
| |
| @noindent |
| This convention, which is GNAT-specific is fully equivalent to the |
| @code{Stdcall} calling convention described above. |
| |
| @node DLL Calling Convention |
| @subsection @code{DLL} Calling Convention |
| |
| @noindent |
| This convention, which is GNAT-specific is fully equivalent to the |
| @code{Stdcall} calling convention described above. |
| |
| @node Introduction to Dynamic Link Libraries (DLLs) |
| @section Introduction to Dynamic Link Libraries (DLLs) |
| @findex DLL |
| |
| @noindent |
| A Dynamically Linked Library (DLL) is a library that can be shared by |
| several applications running under Windows. A DLL can contain any number of |
| routines and variables. |
| |
| One advantage of DLLs is that you can change and enhance them without |
| forcing all the applications that depend on them to be relinked or |
| recompiled. However, you should be aware than all calls to DLL routines are |
| slower since, as you will understand below, such calls are indirect. |
| |
| To illustrate the remainder of this section, suppose that an application |
| wants to use the services of a DLL @file{API.dll}. To use the services |
| provided by @file{API.dll} you must statically link against the DLL or |
| an import library which contains a jump table with an entry for each |
| routine and variable exported by the DLL. In the Microsoft world this |
| import library is called @file{API.lib}. When using GNAT this import |
| library is called either @file{libAPI.a} or @file{libapi.a} (names are |
| case insensitive). |
| |
| After you have linked your application with the DLL or the import library |
| and you run your application, here is what happens: |
| |
| @enumerate |
| @item |
| Your application is loaded into memory. |
| |
| @item |
| The DLL @file{API.dll} is mapped into the address space of your |
| application. This means that: |
| |
| @itemize @bullet |
| @item |
| The DLL will use the stack of the calling thread. |
| |
| @item |
| The DLL will use the virtual address space of the calling process. |
| |
| @item |
| The DLL will allocate memory from the virtual address space of the calling |
| process. |
| |
| @item |
| Handles (pointers) can be safely exchanged between routines in the DLL |
| routines and routines in the application using the DLL. |
| @end itemize |
| |
| @item |
| The entries in the jump table (from the import library @file{libAPI.a} |
| or @file{API.lib} or automatically created when linking against a DLL) |
| which is part of your application are initialized with the addresses |
| of the routines and variables in @file{API.dll}. |
| |
| @item |
| If present in @file{API.dll}, routines @code{DllMain} or |
| @code{DllMainCRTStartup} are invoked. These routines typically contain |
| the initialization code needed for the well-being of the routines and |
| variables exported by the DLL. |
| @end enumerate |
| |
| @noindent |
| There is an additional point which is worth mentioning. In the Windows |
| world there are two kind of DLLs: relocatable and non-relocatable |
| DLLs. Non-relocatable DLLs can only be loaded at a very specific address |
| in the target application address space. If the addresses of two |
| non-relocatable DLLs overlap and these happen to be used by the same |
| application, a conflict will occur and the application will run |
| incorrectly. Hence, when possible, it is always preferable to use and |
| build relocatable DLLs. Both relocatable and non-relocatable DLLs are |
| supported by GNAT. Note that the @option{-s} linker option (see GNU Linker |
| User's Guide) removes the debugging symbols from the DLL but the DLL can |
| still be relocated. |
| |
| As a side note, an interesting difference between Microsoft DLLs and |
| Unix shared libraries, is the fact that on most Unix systems all public |
| routines are exported by default in a Unix shared library, while under |
| Windows it is possible (but not required) to list exported routines in |
| a definition file (@pxref{The Definition File}). |
| |
| @node Using DLLs with GNAT |
| @section Using DLLs with GNAT |
| |
| @menu |
| * Creating an Ada Spec for the DLL Services:: |
| * Creating an Import Library:: |
| @end menu |
| |
| @noindent |
| To use the services of a DLL, say @file{API.dll}, in your Ada application |
| you must have: |
| |
| @enumerate |
| @item |
| The Ada spec for the routines and/or variables you want to access in |
| @file{API.dll}. If not available this Ada spec must be built from the C/C++ |
| header files provided with the DLL. |
| |
| @item |
| The import library (@file{libAPI.a} or @file{API.lib}). As previously |
| mentioned an import library is a statically linked library containing the |
| import table which will be filled at load time to point to the actual |
| @file{API.dll} routines. Sometimes you don't have an import library for the |
| DLL you want to use. The following sections will explain how to build |
| one. Note that this is optional. |
| |
| @item |
| The actual DLL, @file{API.dll}. |
| @end enumerate |
| |
| @noindent |
| Once you have all the above, to compile an Ada application that uses the |
| services of @file{API.dll} and whose main subprogram is @code{My_Ada_App}, |
| you simply issue the command |
| |
| @smallexample |
| $ gnatmake my_ada_app -largs -lAPI |
| @end smallexample |
| |
| @noindent |
| The argument @option{-largs -lAPI} at the end of the @command{gnatmake} command |
| tells the GNAT linker to look first for a library named @file{API.lib} |
| (Microsoft-style name) and if not found for a library named @file{libAPI.a} |
| (GNAT-style name). Note that if the Ada package spec for @file{API.dll} |
| contains the following pragma |
| |
| @smallexample @c ada |
| pragma Linker_Options ("-lAPI"); |
| @end smallexample |
| |
| @noindent |
| you do not have to add @option{-largs -lAPI} at the end of the |
| @command{gnatmake} command. |
| |
| If any one of the items above is missing you will have to create it |
| yourself. The following sections explain how to do so using as an |
| example a fictitious DLL called @file{API.dll}. |
| |
| @node Creating an Ada Spec for the DLL Services |
| @subsection Creating an Ada Spec for the DLL Services |
| |
| @noindent |
| A DLL typically comes with a C/C++ header file which provides the |
| definitions of the routines and variables exported by the DLL. The Ada |
| equivalent of this header file is a package spec that contains definitions |
| for the imported entities. If the DLL you intend to use does not come with |
| an Ada spec you have to generate one such spec yourself. For example if |
| the header file of @file{API.dll} is a file @file{api.h} containing the |
| following two definitions: |
| |
| @smallexample |
| @group |
| @cartouche |
| int some_var; |
| int get (char *); |
| @end cartouche |
| @end group |
| @end smallexample |
| |
| @noindent |
| then the equivalent Ada spec could be: |
| |
| @smallexample @c ada |
| @group |
| @cartouche |
| with Interfaces.C.Strings; |
| package API is |
| use Interfaces; |
| |
| Some_Var : C.int; |
| function Get (Str : C.Strings.Chars_Ptr) return C.int; |
| |
| private |
| pragma Import (C, Get); |
| pragma Import (DLL, Some_Var); |
| end API; |
| @end cartouche |
| @end group |
| @end smallexample |
| |
| @noindent |
| Note that a variable is |
| @strong{always imported with a Stdcall convention}. A function |
| can have @code{C} or @code{Stdcall} convention. |
| (@pxref{Windows Calling Conventions}). |
| |
| @node Creating an Import Library |
| @subsection Creating an Import Library |
| @cindex Import library |
| |
| @menu |
| * The Definition File:: |
| * GNAT-Style Import Library:: |
| * Microsoft-Style Import Library:: |
| @end menu |
| |
| @noindent |
| If a Microsoft-style import library @file{API.lib} or a GNAT-style |
| import library @file{libAPI.a} is available with @file{API.dll} you |
| can skip this section. You can also skip this section if |
| @file{API.dll} is built with GNU tools as in this case it is possible |
| to link directly against the DLL. Otherwise read on. |
| |
| @node The Definition File |
| @subsubsection The Definition File |
| @cindex Definition file |
| @findex .def |
| |
| @noindent |
| As previously mentioned, and unlike Unix systems, the list of symbols |
| that are exported from a DLL must be provided explicitly in Windows. |
| The main goal of a definition file is precisely that: list the symbols |
| exported by a DLL. A definition file (usually a file with a @code{.def} |
| suffix) has the following structure: |
| |
| @smallexample |
| @group |
| @cartouche |
| [LIBRARY @i{name}] |
| [DESCRIPTION @i{string}] |
| EXPORTS |
| @i{symbol1} |
| @i{symbol2} |
| ... |
| @end cartouche |
| @end group |
| @end smallexample |
| |
| @table @code |
| @item LIBRARY @i{name} |
| This section, which is optional, gives the name of the DLL. |
| |
| @item DESCRIPTION @i{string} |
| This section, which is optional, gives a description string that will be |
| embedded in the import library. |
| |
| @item EXPORTS |
| This section gives the list of exported symbols (procedures, functions or |
| variables). For instance in the case of @file{API.dll} the @code{EXPORTS} |
| section of @file{API.def} looks like: |
| |
| @smallexample |
| @group |
| @cartouche |
| EXPORTS |
| some_var |
| get |
| @end cartouche |
| @end group |
| @end smallexample |
| @end table |
| |
| @noindent |
| Note that you must specify the correct suffix (@code{@@}@code{@i{nn}}) |
| (@pxref{Windows Calling Conventions}) for a Stdcall |
| calling convention function in the exported symbols list. |
| |
| @noindent |
| There can actually be other sections in a definition file, but these |
| sections are not relevant to the discussion at hand. |
| |
| @node GNAT-Style Import Library |
| @subsubsection GNAT-Style Import Library |
| |
| @noindent |
| To create a static import library from @file{API.dll} with the GNAT tools |
| you should proceed as follows: |
| |
| @enumerate |
| @item |
| Create the definition file @file{API.def} (@pxref{The Definition File}). |
| For that use the @code{dll2def} tool as follows: |
| |
| @smallexample |
| $ dll2def API.dll > API.def |
| @end smallexample |
| |
| @noindent |
| @code{dll2def} is a very simple tool: it takes as input a DLL and prints |
| to standard output the list of entry points in the DLL. Note that if |
| some routines in the DLL have the @code{Stdcall} convention |
| (@pxref{Windows Calling Conventions}) with stripped @code{@@}@i{nn} |
| suffix then you'll have to edit @file{api.def} to add it, and specify |
| @code{-k} to @code{gnatdll} when creating the import library. |
| |
| @noindent |
| Here are some hints to find the right @code{@@}@i{nn} suffix. |
| |
| @enumerate |
| @item |
| If you have the Microsoft import library (.lib), it is possible to get |
| the right symbols by using Microsoft @code{dumpbin} tool (see the |
| corresponding Microsoft documentation for further details). |
| |
| @smallexample |
| $ dumpbin /exports api.lib |
| @end smallexample |
| |
| @item |
| If you have a message about a missing symbol at link time the compiler |
| tells you what symbol is expected. You just have to go back to the |
| definition file and add the right suffix. |
| @end enumerate |
| |
| @item |
| Build the import library @code{libAPI.a}, using @code{gnatdll} |
| (@pxref{Using gnatdll}) as follows: |
| |
| @smallexample |
| $ gnatdll -e API.def -d API.dll |
| @end smallexample |
| |
| @noindent |
| @code{gnatdll} takes as input a definition file @file{API.def} and the |
| name of the DLL containing the services listed in the definition file |
| @file{API.dll}. The name of the static import library generated is |
| computed from the name of the definition file as follows: if the |
| definition file name is @i{xyz}@code{.def}, the import library name will |
| be @code{lib}@i{xyz}@code{.a}. Note that in the previous example option |
| @option{-e} could have been removed because the name of the definition |
| file (before the ``@code{.def}'' suffix) is the same as the name of the |
| DLL (@pxref{Using gnatdll} for more information about @code{gnatdll}). |
| @end enumerate |
| |
| @node Microsoft-Style Import Library |
| @subsubsection Microsoft-Style Import Library |
| |
| @noindent |
| With GNAT you can either use a GNAT-style or Microsoft-style import |
| library. A Microsoft import library is needed only if you plan to make an |
| Ada DLL available to applications developed with Microsoft |
| tools (@pxref{Mixed-Language Programming on Windows}). |
| |
| To create a Microsoft-style import library for @file{API.dll} you |
| should proceed as follows: |
| |
| @enumerate |
| @item |
| Create the definition file @file{API.def} from the DLL. For this use either |
| the @code{dll2def} tool as described above or the Microsoft @code{dumpbin} |
| tool (see the corresponding Microsoft documentation for further details). |
| |
| @item |
| Build the actual import library using Microsoft's @code{lib} utility: |
| |
| @smallexample |
| $ lib -machine:IX86 -def:API.def -out:API.lib |
| @end smallexample |
| |
| @noindent |
| If you use the above command the definition file @file{API.def} must |
| contain a line giving the name of the DLL: |
| |
| @smallexample |
| LIBRARY "API" |
| @end smallexample |
| |
| @noindent |
| See the Microsoft documentation for further details about the usage of |
| @code{lib}. |
| @end enumerate |
| |
| @node Building DLLs with GNAT |
| @section Building DLLs with GNAT |
| @cindex DLLs, building |
| |
| @noindent |
| This section explain how to build DLLs using the GNAT built-in DLL |
| support. With the following procedure it is straight forward to build |
| and use DLLs with GNAT. |
| |
| @enumerate |
| |
| @item building object files |
| |
| The first step is to build all objects files that are to be included |
| into the DLL. This is done by using the standard @command{gnatmake} tool. |
| |
| @item building the DLL |
| |
| To build the DLL you must use @command{gcc}'s @code{-shared} |
| option. It is quite simple to use this method: |
| |
| @smallexample |
| $ gcc -shared -o api.dll obj1.o obj2.o ... |
| @end smallexample |
| |
| It is important to note that in this case all symbols found in the |
| object files are automatically exported. It is possible to restrict |
| the set of symbols to export by passing to @command{gcc} a definition |
| file, @pxref{The Definition File}. For example: |
| |
| @smallexample |
| $ gcc -shared -o api.dll api.def obj1.o obj2.o ... |
| @end smallexample |
| |
| If you use a definition file you must export the elaboration procedures |
| for every package that required one. Elaboration procedures are named |
| using the package name followed by "_E". |
| |
| @item preparing DLL to be used |
| |
| For the DLL to be used by client programs the bodies must be hidden |
| from it and the .ali set with read-only attribute. This is very important |
| otherwise GNAT will recompile all packages and will not actually use |
| the code in the DLL. For example: |
| |
| @smallexample |
| $ mkdir apilib |
| $ copy *.ads *.ali api.dll apilib |
| $ attrib +R apilib\*.ali |
| @end smallexample |
| |
| @end enumerate |
| |
| At this point it is possible to use the DLL by directly linking |
| against it. Note that you must use the GNAT shared runtime when using |
| GNAT shared libraries. This is achieved by using @code{-shared} binder's |
| option. |
| |
| @smallexample |
| $ gnatmake main -Iapilib -bargs -shared -largs -Lapilib -lAPI |
| @end smallexample |
| |
| @node Building DLLs with GNAT Project files |
| @section Building DLLs with GNAT Project files |
| @cindex DLLs, building |
| |
| @noindent |
| There is nothing specific to Windows in this area. @pxref{Library Projects}. |
| |
| @node Building DLLs with gnatdll |
| @section Building DLLs with gnatdll |
| @cindex DLLs, building |
| |
| @menu |
| * Limitations When Using Ada DLLs from Ada:: |
| * Exporting Ada Entities:: |
| * Ada DLLs and Elaboration:: |
| * Ada DLLs and Finalization:: |
| * Creating a Spec for Ada DLLs:: |
| * Creating the Definition File:: |
| * Using gnatdll:: |
| @end menu |
| |
| @noindent |
| Note that it is preferred to use the built-in GNAT DLL support |
| (@pxref{Building DLLs with GNAT}) or GNAT Project files |
| (@pxref{Building DLLs with GNAT Project files}) to build DLLs. |
| |
| This section explains how to build DLLs containing Ada code using |
| @code{gnatdll}. These DLLs will be referred to as Ada DLLs in the |
| remainder of this section. |
| |
| The steps required to build an Ada DLL that is to be used by Ada as well as |
| non-Ada applications are as follows: |
| |
| @enumerate |
| @item |
| You need to mark each Ada @i{entity} exported by the DLL with a @code{C} or |
| @code{Stdcall} calling convention to avoid any Ada name mangling for the |
| entities exported by the DLL (@pxref{Exporting Ada Entities}). You can |
| skip this step if you plan to use the Ada DLL only from Ada applications. |
| |
| @item |
| Your Ada code must export an initialization routine which calls the routine |
| @code{adainit} generated by @command{gnatbind} to perform the elaboration of |
| the Ada code in the DLL (@pxref{Ada DLLs and Elaboration}). The initialization |
| routine exported by the Ada DLL must be invoked by the clients of the DLL |
| to initialize the DLL. |
| |
| @item |
| When useful, the DLL should also export a finalization routine which calls |
| routine @code{adafinal} generated by @command{gnatbind} to perform the |
| finalization of the Ada code in the DLL (@pxref{Ada DLLs and Finalization}). |
| The finalization routine exported by the Ada DLL must be invoked by the |
| clients of the DLL when the DLL services are no further needed. |
| |
| @item |
| You must provide a spec for the services exported by the Ada DLL in each |
| of the programming languages to which you plan to make the DLL available. |
| |
| @item |
| You must provide a definition file listing the exported entities |
| (@pxref{The Definition File}). |
| |
| @item |
| Finally you must use @code{gnatdll} to produce the DLL and the import |
| library (@pxref{Using gnatdll}). |
| @end enumerate |
| |
| @noindent |
| Note that a relocatable DLL stripped using the @code{strip} |
| binutils tool will not be relocatable anymore. To build a DLL without |
| debug information pass @code{-largs -s} to @code{gnatdll}. This |
| restriction does not apply to a DLL built using a Library Project. |
| @pxref{Library Projects}. |
| |
| @node Limitations When Using Ada DLLs from Ada |
| @subsection Limitations When Using Ada DLLs from Ada |
| |
| @noindent |
| When using Ada DLLs from Ada applications there is a limitation users |
| should be aware of. Because on Windows the GNAT run time is not in a DLL of |
| its own, each Ada DLL includes a part of the GNAT run time. Specifically, |
| each Ada DLL includes the services of the GNAT run time that are necessary |
| to the Ada code inside the DLL. As a result, when an Ada program uses an |
| Ada DLL there are two independent GNAT run times: one in the Ada DLL and |
| one in the main program. |
| |
| It is therefore not possible to exchange GNAT run-time objects between the |
| Ada DLL and the main Ada program. Example of GNAT run-time objects are file |
| handles (e.g. @code{Text_IO.File_Type}), tasks types, protected objects |
| types, etc. |
| |
| It is completely safe to exchange plain elementary, array or record types, |
| Windows object handles, etc. |
| |
| @node Exporting Ada Entities |
| @subsection Exporting Ada Entities |
| @cindex Export table |
| |
| @noindent |
| Building a DLL is a way to encapsulate a set of services usable from any |
| application. As a result, the Ada entities exported by a DLL should be |
| exported with the @code{C} or @code{Stdcall} calling conventions to avoid |
| any Ada name mangling. As an example here is an Ada package |
| @code{API}, spec and body, exporting two procedures, a function, and a |
| variable: |
| |
| @smallexample @c ada |
| @group |
| @cartouche |
| with Interfaces.C; use Interfaces; |
| package API is |
| Count : C.int := 0; |
| function Factorial (Val : C.int) return C.int; |
| |
| procedure Initialize_API; |
| procedure Finalize_API; |
| -- Initialization & Finalization routines. More in the next section. |
| private |
| pragma Export (C, Initialize_API); |
| pragma Export (C, Finalize_API); |
| pragma Export (C, Count); |
| pragma Export (C, Factorial); |
| end API; |
| @end cartouche |
| @end group |
| @end smallexample |
| |
| @smallexample @c ada |
| @group |
| @cartouche |
| package body API is |
| function Factorial (Val : C.int) return C.int is |
| Fact : C.int := 1; |
| begin |
| Count := Count + 1; |
| for K in 1 .. Val loop |
| Fact := Fact * K; |
| end loop; |
| return Fact; |
| end Factorial; |
| |
| procedure Initialize_API is |
| procedure Adainit; |
| pragma Import (C, Adainit); |
| begin |
| Adainit; |
| end Initialize_API; |
| |
| procedure Finalize_API is |
| procedure Adafinal; |
| pragma Import (C, Adafinal); |
| begin |
| Adafinal; |
| end Finalize_API; |
| end API; |
| @end cartouche |
| @end group |
| @end smallexample |
| |
| @noindent |
| If the Ada DLL you are building will only be used by Ada applications |
| you do not have to export Ada entities with a @code{C} or @code{Stdcall} |
| convention. As an example, the previous package could be written as |
| follows: |
| |
| @smallexample @c ada |
| @group |
| @cartouche |
| package API is |
| Count : Integer := 0; |
| function Factorial (Val : Integer) return Integer; |
| |
| procedure Initialize_API; |
| procedure Finalize_API; |
| -- Initialization and Finalization routines. |
| end API; |
| @end cartouche |
| @end group |
| @end smallexample |
| |
| @smallexample @c ada |
| @group |
| @cartouche |
| package body API is |
| function Factorial (Val : Integer) return Integer is |
| Fact : Integer := 1; |
| begin |
| Count := Count + 1; |
| for K in 1 .. Val loop |
| Fact := Fact * K; |
| end loop; |
| return Fact; |
| end Factorial; |
| |
| ... |
| -- The remainder of this package body is unchanged. |
| end API; |
| @end cartouche |
| @end group |
| @end smallexample |
| |
| @noindent |
| Note that if you do not export the Ada entities with a @code{C} or |
| @code{Stdcall} convention you will have to provide the mangled Ada names |
| in the definition file of the Ada DLL |
| (@pxref{Creating the Definition File}). |
| |
| @node Ada DLLs and Elaboration |
| @subsection Ada DLLs and Elaboration |
| @cindex DLLs and elaboration |
| |
| @noindent |
| The DLL that you are building contains your Ada code as well as all the |
| routines in the Ada library that are needed by it. The first thing a |
| user of your DLL must do is elaborate the Ada code |
| (@pxref{Elaboration Order Handling in GNAT}). |
| |
| To achieve this you must export an initialization routine |
| (@code{Initialize_API} in the previous example), which must be invoked |
| before using any of the DLL services. This elaboration routine must call |
| the Ada elaboration routine @code{adainit} generated by the GNAT binder |
| (@pxref{Binding with Non-Ada Main Programs}). See the body of |
| @code{Initialize_Api} for an example. Note that the GNAT binder is |
| automatically invoked during the DLL build process by the @code{gnatdll} |
| tool (@pxref{Using gnatdll}). |
| |
| When a DLL is loaded, Windows systematically invokes a routine called |
| @code{DllMain}. It would therefore be possible to call @code{adainit} |
| directly from @code{DllMain} without having to provide an explicit |
| initialization routine. Unfortunately, it is not possible to call |
| @code{adainit} from the @code{DllMain} if your program has library level |
| tasks because access to the @code{DllMain} entry point is serialized by |
| the system (that is, only a single thread can execute ``through'' it at a |
| time), which means that the GNAT run time will deadlock waiting for the |
| newly created task to complete its initialization. |
| |
| @node Ada DLLs and Finalization |
| @subsection Ada DLLs and Finalization |
| @cindex DLLs and finalization |
| |
| @noindent |
| When the services of an Ada DLL are no longer needed, the client code should |
| invoke the DLL finalization routine, if available. The DLL finalization |
| routine is in charge of releasing all resources acquired by the DLL. In the |
| case of the Ada code contained in the DLL, this is achieved by calling |
| routine @code{adafinal} generated by the GNAT binder |
| (@pxref{Binding with Non-Ada Main Programs}). |
| See the body of @code{Finalize_Api} for an |
| example. As already pointed out the GNAT binder is automatically invoked |
| during the DLL build process by the @code{gnatdll} tool |
| (@pxref{Using gnatdll}). |
| |
| @node Creating a Spec for Ada DLLs |
| @subsection Creating a Spec for Ada DLLs |
| |
| @noindent |
| To use the services exported by the Ada DLL from another programming |
| language (e.g. C), you have to translate the specs of the exported Ada |
| entities in that language. For instance in the case of @code{API.dll}, |
| the corresponding C header file could look like: |
| |
| @smallexample |
| @group |
| @cartouche |
| extern int *_imp__count; |
| #define count (*_imp__count) |
| int factorial (int); |
| @end cartouche |
| @end group |
| @end smallexample |
| |
| @noindent |
| It is important to understand that when building an Ada DLL to be used by |
| other Ada applications, you need two different specs for the packages |
| contained in the DLL: one for building the DLL and the other for using |
| the DLL. This is because the @code{DLL} calling convention is needed to |
| use a variable defined in a DLL, but when building the DLL, the variable |
| must have either the @code{Ada} or @code{C} calling convention. As an |
| example consider a DLL comprising the following package @code{API}: |
| |
| @smallexample @c ada |
| @group |
| @cartouche |
| package API is |
| Count : Integer := 0; |
| ... |
| -- Remainder of the package omitted. |
| end API; |
| @end cartouche |
| @end group |
| @end smallexample |
| |
| @noindent |
| After producing a DLL containing package @code{API}, the spec that |
| must be used to import @code{API.Count} from Ada code outside of the |
| DLL is: |
| |
| @smallexample @c ada |
| @group |
| @cartouche |
| package API is |
| Count : Integer; |
| pragma Import (DLL, Count); |
| end API; |
| @end cartouche |
| @end group |
| @end smallexample |
| |
| @node Creating the Definition File |
| @subsection Creating the Definition File |
| |
| @noindent |
| The definition file is the last file needed to build the DLL. It lists |
| the exported symbols. As an example, the definition file for a DLL |
| containing only package @code{API} (where all the entities are exported |
| with a @code{C} calling convention) is: |
| |
| @smallexample |
| @group |
| @cartouche |
| EXPORTS |
| count |
| factorial |
| finalize_api |
| initialize_api |
| @end cartouche |
| @end group |
| @end smallexample |
| |
| @noindent |
| If the @code{C} calling convention is missing from package @code{API}, |
| then the definition file contains the mangled Ada names of the above |
| entities, which in this case are: |
| |
| @smallexample |
| @group |
| @cartouche |
| EXPORTS |
| api__count |
| api__factorial |
| api__finalize_api |
| api__initialize_api |
| @end cartouche |
| @end group |
| @end smallexample |
| |
| @node Using gnatdll |
| @subsection Using @code{gnatdll} |
| @findex gnatdll |
| |
| @menu |
| * gnatdll Example:: |
| * gnatdll behind the Scenes:: |
| * Using dlltool:: |
| @end menu |
| |
| @noindent |
| @code{gnatdll} is a tool to automate the DLL build process once all the Ada |
| and non-Ada sources that make up your DLL have been compiled. |
| @code{gnatdll} is actually in charge of two distinct tasks: build the |
| static import library for the DLL and the actual DLL. The form of the |
| @code{gnatdll} command is |
| |
| @smallexample |
| @cartouche |
| $ gnatdll [@var{switches}] @var{list-of-files} [-largs @var{opts}] |
| @end cartouche |
| @end smallexample |
| |
| @noindent |
| where @i{list-of-files} is a list of ALI and object files. The object |
| file list must be the exact list of objects corresponding to the non-Ada |
| sources whose services are to be included in the DLL. The ALI file list |
| must be the exact list of ALI files for the corresponding Ada sources |
| whose services are to be included in the DLL. If @i{list-of-files} is |
| missing, only the static import library is generated. |
| |
| @noindent |
| You may specify any of the following switches to @code{gnatdll}: |
| |
| @table @code |
| @item -a[@var{address}] |
| @cindex @option{-a} (@code{gnatdll}) |
| Build a non-relocatable DLL at @var{address}. If @var{address} is not |
| specified the default address @var{0x11000000} will be used. By default, |
| when this switch is missing, @code{gnatdll} builds relocatable DLL. We |
| advise the reader to build relocatable DLL. |
| |
| @item -b @var{address} |
| @cindex @option{-b} (@code{gnatdll}) |
| Set the relocatable DLL base address. By default the address is |
| @var{0x11000000}. |
| |
| @item -bargs @var{opts} |
| @cindex @option{-bargs} (@code{gnatdll}) |
| Binder options. Pass @var{opts} to the binder. |
| |
| @item -d @var{dllfile} |
| @cindex @option{-d} (@code{gnatdll}) |
| @var{dllfile} is the name of the DLL. This switch must be present for |
| @code{gnatdll} to do anything. The name of the generated import library is |
| obtained algorithmically from @var{dllfile} as shown in the following |
| example: if @var{dllfile} is @code{xyz.dll}, the import library name is |
| @code{libxyz.a}. The name of the definition file to use (if not specified |
| by option @option{-e}) is obtained algorithmically from @var{dllfile} |
| as shown in the following example: |
| if @var{dllfile} is @code{xyz.dll}, the definition |
| file used is @code{xyz.def}. |
| |
| @item -e @var{deffile} |
| @cindex @option{-e} (@code{gnatdll}) |
| @var{deffile} is the name of the definition file. |
| |
| @item -g |
| @cindex @option{-g} (@code{gnatdll}) |
| Generate debugging information. This information is stored in the object |
| file and copied from there to the final DLL file by the linker, |
| where it can be read by the debugger. You must use the |
| @option{-g} switch if you plan on using the debugger or the symbolic |
| stack traceback. |
| |
| @item -h |
| @cindex @option{-h} (@code{gnatdll}) |
| Help mode. Displays @code{gnatdll} switch usage information. |
| |
| @item -Idir |
| @cindex @option{-I} (@code{gnatdll}) |
| Direct @code{gnatdll} to search the @var{dir} directory for source and |
| object files needed to build the DLL. |
| (@pxref{Search Paths and the Run-Time Library (RTL)}). |
| |
| @item -k |
| @cindex @option{-k} (@code{gnatdll}) |
| Removes the @code{@@}@i{nn} suffix from the import library's exported |
| names, but keeps them for the link names. You must specify this |
| option if you want to use a @code{Stdcall} function in a DLL for which |
| the @code{@@}@i{nn} suffix has been removed. This is the case for most |
| of the Windows NT DLL for example. This option has no effect when |
| @option{-n} option is specified. |
| |
| @item -l @var{file} |
| @cindex @option{-l} (@code{gnatdll}) |
| The list of ALI and object files used to build the DLL are listed in |
| @var{file}, instead of being given in the command line. Each line in |
| @var{file} contains the name of an ALI or object file. |
| |
| @item -n |
| @cindex @option{-n} (@code{gnatdll}) |
| No Import. Do not create the import library. |
| |
| @item -q |
| @cindex @option{-q} (@code{gnatdll}) |
| Quiet mode. Do not display unnecessary messages. |
| |
| @item -v |
| @cindex @option{-v} (@code{gnatdll}) |
| Verbose mode. Display extra information. |
| |
| @item -largs @var{opts} |
| @cindex @option{-largs} (@code{gnatdll}) |
| Linker options. Pass @var{opts} to the linker. |
| @end table |
| |
| @node gnatdll Example |
| @subsubsection @code{gnatdll} Example |
| |
| @noindent |
| As an example the command to build a relocatable DLL from @file{api.adb} |
| once @file{api.adb} has been compiled and @file{api.def} created is |
| |
| @smallexample |
| $ gnatdll -d api.dll api.ali |
| @end smallexample |
| |
| @noindent |
| The above command creates two files: @file{libapi.a} (the import |
| library) and @file{api.dll} (the actual DLL). If you want to create |
| only the DLL, just type: |
| |
| @smallexample |
| $ gnatdll -d api.dll -n api.ali |
| @end smallexample |
| |
| @noindent |
| Alternatively if you want to create just the import library, type: |
| |
| @smallexample |
| $ gnatdll -d api.dll |
| @end smallexample |
| |
| @node gnatdll behind the Scenes |
| @subsubsection @code{gnatdll} behind the Scenes |
| |
| @noindent |
| This section details the steps involved in creating a DLL. @code{gnatdll} |
| does these steps for you. Unless you are interested in understanding what |
| goes on behind the scenes, you should skip this section. |
| |
| We use the previous example of a DLL containing the Ada package @code{API}, |
| to illustrate the steps necessary to build a DLL. The starting point is a |
| set of objects that will make up the DLL and the corresponding ALI |
| files. In the case of this example this means that @file{api.o} and |
| @file{api.ali} are available. To build a relocatable DLL, @code{gnatdll} does |
| the following: |
| |
| @enumerate |
| @item |
| @code{gnatdll} builds the base file (@file{api.base}). A base file gives |
| the information necessary to generate relocation information for the |
| DLL. |
| |
| @smallexample |
| @group |
| $ gnatbind -n api |
| $ gnatlink api -o api.jnk -mdll -Wl,--base-file,api.base |
| @end group |
| @end smallexample |
| |
| @noindent |
| In addition to the base file, the @command{gnatlink} command generates an |
| output file @file{api.jnk} which can be discarded. The @option{-mdll} switch |
| asks @command{gnatlink} to generate the routines @code{DllMain} and |
| @code{DllMainCRTStartup} that are called by the Windows loader when the DLL |
| is loaded into memory. |
| |
| @item |
| @code{gnatdll} uses @code{dlltool} (@pxref{Using dlltool}) to build the |
| export table (@file{api.exp}). The export table contains the relocation |
| information in a form which can be used during the final link to ensure |
| that the Windows loader is able to place the DLL anywhere in memory. |
| |
| @smallexample |
| @group |
| $ dlltool --dllname api.dll --def api.def --base-file api.base \ |
| --output-exp api.exp |
| @end group |
| @end smallexample |
| |
| @item |
| @code{gnatdll} builds the base file using the new export table. Note that |
| @command{gnatbind} must be called once again since the binder generated file |
| has been deleted during the previous call to @command{gnatlink}. |
| |
| @smallexample |
| @group |
| $ gnatbind -n api |
| $ gnatlink api -o api.jnk api.exp -mdll |
| -Wl,--base-file,api.base |
| @end group |
| @end smallexample |
| |
| @item |
| @code{gnatdll} builds the new export table using the new base file and |
| generates the DLL import library @file{libAPI.a}. |
| |
| @smallexample |
| @group |
| $ dlltool --dllname api.dll --def api.def --base-file api.base \ |
| --output-exp api.exp --output-lib libAPI.a |
| @end group |
| @end smallexample |
| |
| @item |
| Finally @code{gnatdll} builds the relocatable DLL using the final export |
| table. |
| |
| @smallexample |
| @group |
| $ gnatbind -n api |
| $ gnatlink api api.exp -o api.dll -mdll |
| @end group |
| @end smallexample |
| @end enumerate |
| |
| @node Using dlltool |
| @subsubsection Using @code{dlltool} |
| |
| @noindent |
| @code{dlltool} is the low-level tool used by @code{gnatdll} to build |
| DLLs and static import libraries. This section summarizes the most |
| common @code{dlltool} switches. The form of the @code{dlltool} command |
| is |
| |
| @smallexample |
| $ dlltool [@var{switches}] |
| @end smallexample |
| |
| @noindent |
| @code{dlltool} switches include: |
| |
| @table @option |
| @item --base-file @var{basefile} |
| @cindex @option{--base-file} (@command{dlltool}) |
| Read the base file @var{basefile} generated by the linker. This switch |
| is used to create a relocatable DLL. |
| |
| @item --def @var{deffile} |
| @cindex @option{--def} (@command{dlltool}) |
| Read the definition file. |
| |
| @item --dllname @var{name} |
| @cindex @option{--dllname} (@command{dlltool}) |
| Gives the name of the DLL. This switch is used to embed the name of the |
| DLL in the static import library generated by @code{dlltool} with switch |
| @option{--output-lib}. |
| |
| @item -k |
| @cindex @option{-k} (@command{dlltool}) |
| Kill @code{@@}@i{nn} from exported names |
| (@pxref{Windows Calling Conventions} |
| for a discussion about @code{Stdcall}-style symbols. |
| |
| @item --help |
| @cindex @option{--help} (@command{dlltool}) |
| Prints the @code{dlltool} switches with a concise description. |
| |
| @item --output-exp @var{exportfile} |
| @cindex @option{--output-exp} (@command{dlltool}) |
| Generate an export file @var{exportfile}. The export file contains the |
| export table (list of symbols in the DLL) and is used to create the DLL. |
| |
| @item --output-lib @i{libfile} |
| @cindex @option{--output-lib} (@command{dlltool}) |
| Generate a static import library @var{libfile}. |
| |
| @item -v |
| @cindex @option{-v} (@command{dlltool}) |
| Verbose mode. |
| |
| @item --as @i{assembler-name} |
| @cindex @option{--as} (@command{dlltool}) |
| Use @i{assembler-name} as the assembler. The default is @code{as}. |
| @end table |
| |
| @node GNAT and Windows Resources |
| @section GNAT and Windows Resources |
| @cindex Resources, windows |
| |
| @menu |
| * Building Resources:: |
| * Compiling Resources:: |
| * Using Resources:: |
| @end menu |
| |
| @noindent |
| Resources are an easy way to add Windows specific objects to your |
| application. The objects that can be added as resources include: |
| |
| @itemize @bullet |
| @item |
| menus |
| |
| @item |
| accelerators |
| |
| @item |
| dialog boxes |
| |
| @item |
| string tables |
| |
| @item |
| bitmaps |
| |
| @item |
| cursors |
| |
| @item |
| icons |
| |
| @item |
| fonts |
| @end itemize |
| |
| @noindent |
| This section explains how to build, compile and use resources. |
| |
| @node Building Resources |
| @subsection Building Resources |
| @cindex Resources, building |
| |
| @noindent |
| A resource file is an ASCII file. By convention resource files have an |
| @file{.rc} extension. |
| The easiest way to build a resource file is to use Microsoft tools |
| such as @code{imagedit.exe} to build bitmaps, icons and cursors and |
| @code{dlgedit.exe} to build dialogs. |
| It is always possible to build an @file{.rc} file yourself by writing a |
| resource script. |
| |
| It is not our objective to explain how to write a resource file. A |
| complete description of the resource script language can be found in the |
| Microsoft documentation. |
| |
| @node Compiling Resources |
| @subsection Compiling Resources |
| @findex rc |
| @findex windres |
| @cindex Resources, compiling |
| |
| @noindent |
| This section describes how to build a GNAT-compatible (COFF) object file |
| containing the resources. This is done using the Resource Compiler |
| @code{windres} as follows: |
| |
| @smallexample |
| $ windres -i myres.rc -o myres.o |
| @end smallexample |
| |
| @noindent |
| By default @code{windres} will run @command{gcc} to preprocess the @file{.rc} |
| file. You can specify an alternate preprocessor (usually named |
| @file{cpp.exe}) using the @code{windres} @option{--preprocessor} |
| parameter. A list of all possible options may be obtained by entering |
| the command @code{windres} @option{--help}. |
| |
| It is also possible to use the Microsoft resource compiler @code{rc.exe} |
| to produce a @file{.res} file (binary resource file). See the |
| corresponding Microsoft documentation for further details. In this case |
| you need to use @code{windres} to translate the @file{.res} file to a |
| GNAT-compatible object file as follows: |
| |
| @smallexample |
| $ windres -i myres.res -o myres.o |
| @end smallexample |
| |
| @node Using Resources |
| @subsection Using Resources |
| @cindex Resources, using |
| |
| @noindent |
| To include the resource file in your program just add the |
| GNAT-compatible object file for the resource(s) to the linker |
| arguments. With @command{gnatmake} this is done by using the @option{-largs} |
| option: |
| |
| @smallexample |
| $ gnatmake myprog -largs myres.o |
| @end smallexample |
| |
| @node Debugging a DLL |
| @section Debugging a DLL |
| @cindex DLL debugging |
| |
| @menu |
| * Program and DLL Both Built with GCC/GNAT:: |
| * Program Built with Foreign Tools and DLL Built with GCC/GNAT:: |
| @end menu |
| |
| @noindent |
| Debugging a DLL is similar to debugging a standard program. But |
| we have to deal with two different executable parts: the DLL and the |
| program that uses it. We have the following four possibilities: |
| |
| @enumerate 1 |
| @item |
| The program and the DLL are built with @code{GCC/GNAT}. |
| @item |
| The program is built with foreign tools and the DLL is built with |
| @code{GCC/GNAT}. |
| @item |
| The program is built with @code{GCC/GNAT} and the DLL is built with |
| foreign tools. |
| @item |
| @end enumerate |
| |
| @noindent |
| In this section we address only cases one and two above. |
| There is no point in trying to debug |
| a DLL with @code{GNU/GDB}, if there is no GDB-compatible debugging |
| information in it. To do so you must use a debugger compatible with the |
| tools suite used to build the DLL. |
| |
| @node Program and DLL Both Built with GCC/GNAT |
| @subsection Program and DLL Both Built with GCC/GNAT |
| |
| @noindent |
| This is the simplest case. Both the DLL and the program have @code{GDB} |
| compatible debugging information. It is then possible to break anywhere in |
| the process. Let's suppose here that the main procedure is named |
| @code{ada_main} and that in the DLL there is an entry point named |
| @code{ada_dll}. |
| |
| @noindent |
| The DLL (@pxref{Introduction to Dynamic Link Libraries (DLLs)}) and |
| program must have been built with the debugging information (see GNAT -g |
| switch). Here are the step-by-step instructions for debugging it: |
| |
| @enumerate 1 |
| @item Launch @code{GDB} on the main program. |
| |
| @smallexample |
| $ gdb -nw ada_main |
| @end smallexample |
| |
| @item Start the program and stop at the beginning of the main procedure |
| |
| @smallexample |
| (gdb) start |
| @end smallexample |
| |
| @noindent |
| This step is required to be able to set a breakpoint inside the DLL. As long |
| as the program is not run, the DLL is not loaded. This has the |
| consequence that the DLL debugging information is also not loaded, so it is not |
| possible to set a breakpoint in the DLL. |
| |
| @item Set a breakpoint inside the DLL |
| |
| @smallexample |
| (gdb) break ada_dll |
| (gdb) cont |
| @end smallexample |
| |
| @end enumerate |
| |
| @noindent |
| At this stage a breakpoint is set inside the DLL. From there on |
| you can use the standard approach to debug the whole program |
| (@pxref{Running and Debugging Ada Programs}). |
| |
| @ignore |
| @c This used to work, probably because the DLLs were non-relocatable |
| @c keep this section around until the problem is sorted out. |
| |
| To break on the @code{DllMain} routine it is not possible to follow |
| the procedure above. At the time the program stop on @code{ada_main} |
| the @code{DllMain} routine as already been called. Either you can use |
| the procedure below @pxref{Debugging the DLL Directly} or this procedure: |
| |
| @enumerate 1 |
| @item Launch @code{GDB} on the main program. |
| |
| @smallexample |
| $ gdb ada_main |
| @end smallexample |
| |
| @item Load DLL symbols |
| |
| @smallexample |
| (gdb) add-sym api.dll |
| @end smallexample |
| |
| @item Set a breakpoint inside the DLL |
| |
| @smallexample |
| (gdb) break ada_dll.adb:45 |
| @end smallexample |
| |
| Note that at this point it is not possible to break using the routine symbol |
| directly as the program is not yet running. The solution is to break |
| on the proper line (break in @file{ada_dll.adb} line 45). |
| |
| @item Start the program |
| |
| @smallexample |
| (gdb) run |
| @end smallexample |
| |
| @end enumerate |
| @end ignore |
| |
| @node Program Built with Foreign Tools and DLL Built with GCC/GNAT |
| @subsection Program Built with Foreign Tools and DLL Built with GCC/GNAT |
| |
| @menu |
| * Debugging the DLL Directly:: |
| * Attaching to a Running Process:: |
| @end menu |
| |
| @noindent |
| In this case things are slightly more complex because it is not possible to |
| start the main program and then break at the beginning to load the DLL and the |
| associated DLL debugging information. It is not possible to break at the |
| beginning of the program because there is no @code{GDB} debugging information, |
| and therefore there is no direct way of getting initial control. This |
| section addresses this issue by describing some methods that can be used |
| to break somewhere in the DLL to debug it. |
| |
| @noindent |
| First suppose that the main procedure is named @code{main} (this is for |
| example some C code built with Microsoft Visual C) and that there is a |
| DLL named @code{test.dll} containing an Ada entry point named |
| @code{ada_dll}. |
| |
| @noindent |
| The DLL (@pxref{Introduction to Dynamic Link Libraries (DLLs)}) must have |
| been built with debugging information (see GNAT -g option). |
| |
| @node Debugging the DLL Directly |
| @subsubsection Debugging the DLL Directly |
| |
| @enumerate 1 |
| @item |
| Find out the executable starting address |
| |
| @smallexample |
| $ objdump --file-header main.exe |
| @end smallexample |
| |
| The starting address is reported on the last line. For example: |
| |
| @smallexample |
| main.exe: file format pei-i386 |
| architecture: i386, flags 0x0000010a: |
| EXEC_P, HAS_DEBUG, D_PAGED |
| start address 0x00401010 |
| @end smallexample |
| |
| @item |
| Launch the debugger on the executable. |
| |
| @smallexample |
| $ gdb main.exe |
| @end smallexample |
| |
| @item |
| Set a breakpoint at the starting address, and launch the program. |
| |
| @smallexample |
| $ (gdb) break *0x00401010 |
| $ (gdb) run |
| @end smallexample |
| |
| The program will stop at the given address. |
| |
| @item |
| Set a breakpoint on a DLL subroutine. |
| |
| @smallexample |
| (gdb) break ada_dll.adb:45 |
| @end smallexample |
| |
| Or if you want to break using a symbol on the DLL, you need first to |
| select the Ada language (language used by the DLL). |
| |
| @smallexample |
| (gdb) set language ada |
| (gdb) break ada_dll |
| @end smallexample |
| |
| @item |
| Continue the program. |
| |
| @smallexample |
| (gdb) cont |
| @end smallexample |
| |
| @noindent |
| This will run the program until it reaches the breakpoint that has been |
| set. From that point you can use the standard way to debug a program |
| as described in (@pxref{Running and Debugging Ada Programs}). |
| |
| @end enumerate |
| |
| @noindent |
| It is also possible to debug the DLL by attaching to a running process. |
| |
| @node Attaching to a Running Process |
| @subsubsection Attaching to a Running Process |
| @cindex DLL debugging, attach to process |
| |
| @noindent |
| With @code{GDB} it is always possible to debug a running process by |
| attaching to it. It is possible to debug a DLL this way. The limitation |
| of this approach is that the DLL must run long enough to perform the |
| attach operation. It may be useful for instance to insert a time wasting |
| loop in the code of the DLL to meet this criterion. |
| |
| @enumerate 1 |
| |
| @item Launch the main program @file{main.exe}. |
| |
| @smallexample |
| $ main |
| @end smallexample |
| |
| @item Use the Windows @i{Task Manager} to find the process ID. Let's say |
| that the process PID for @file{main.exe} is 208. |
| |
| @item Launch gdb. |
| |
| @smallexample |
| $ gdb |
| @end smallexample |
| |
| @item Attach to the running process to be debugged. |
| |
| @smallexample |
| (gdb) attach 208 |
| @end smallexample |
| |
| @item Load the process debugging information. |
| |
| @smallexample |
| (gdb) symbol-file main.exe |
| @end smallexample |
| |
| @item Break somewhere in the DLL. |
| |
| @smallexample |
| (gdb) break ada_dll |
| @end smallexample |
| |
| @item Continue process execution. |
| |
| @smallexample |
| (gdb) cont |
| @end smallexample |
| |
| @end enumerate |
| |
| @noindent |
| This last step will resume the process execution, and stop at |
| the breakpoint we have set. From there you can use the standard |
| approach to debug a program as described in |
| (@pxref{Running and Debugging Ada Programs}). |
| |
| @node Setting Stack Size from gnatlink |
| @section Setting Stack Size from @command{gnatlink} |
| |
| @noindent |
| It is possible to specify the program stack size at link time. On modern |
| versions of Windows, starting with XP, this is mostly useful to set the size of |
| the main stack (environment task). The other task stacks are set with pragma |
| Linker_Options or with gnatbind -d. On older versions of Windows (2000, NT4, |
| etc.), it is not possible to set the reserve size of individual tasks and thus |
| the link-time stack size applies to all tasks. |
| |
| This setting can be done with |
| @command{gnatlink} using either: |
| |
| @itemize @bullet |
| |
| @item using @option{-Xlinker} linker option |
| |
| @smallexample |
| $ gnatlink hello -Xlinker --stack=0x10000,0x1000 |
| @end smallexample |
| |
| This sets the stack reserve size to 0x10000 bytes and the stack commit |
| size to 0x1000 bytes. |
| |
| @item using @option{-Wl} linker option |
| |
| @smallexample |
| $ gnatlink hello -Wl,--stack=0x1000000 |
| @end smallexample |
| |
| This sets the stack reserve size to 0x1000000 bytes. Note that with |
| @option{-Wl} option it is not possible to set the stack commit size |
| because the coma is a separator for this option. |
| |
| @end itemize |
| |
| @node Setting Heap Size from gnatlink |
| @section Setting Heap Size from @command{gnatlink} |
| |
| @noindent |
| Under Windows systems, it is possible to specify the program heap size from |
| @command{gnatlink} using either: |
| |
| @itemize @bullet |
| |
| @item using @option{-Xlinker} linker option |
| |
| @smallexample |
| $ gnatlink hello -Xlinker --heap=0x10000,0x1000 |
| @end smallexample |
| |
| This sets the heap reserve size to 0x10000 bytes and the heap commit |
| size to 0x1000 bytes. |
| |
| @item using @option{-Wl} linker option |
| |
| @smallexample |
| $ gnatlink hello -Wl,--heap=0x1000000 |
| @end smallexample |
| |
| This sets the heap reserve size to 0x1000000 bytes. Note that with |
| @option{-Wl} option it is not possible to set the heap commit size |
| because the coma is a separator for this option. |
| |
| @end itemize |
| |
| |
| @end ifset |
| |
| @c ********************************** |
| @c * GNU Free Documentation License * |
| @c ********************************** |
| @include fdl.texi |
| @c GNU Free Documentation License |
| |
| @node Index,,GNU Free Documentation License, Top |
| @unnumbered Index |
| |
| @printindex cp |
| |
| @contents |
| @c Put table of contents at end, otherwise it precedes the "title page" in |
| @c the .txt version |
| @c Edit the pdf file to move the contents to the beginning, after the title |
| @c page |
| |
| @bye |