| \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-2013, Free Software Foundation, Inc. o |
| @c o |
| @c oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo |
| |
| @setfilename gnat_ugn.info |
| |
| @copying |
| Copyright @copyright{} 1995-2009 Free Software Foundation, |
| Inc. |
| |
| Permission is granted to copy, distribute and/or modify this document |
| under the terms of the GNU Free Documentation License, Version 1.3 or |
| any later version published by the Free Software Foundation; with no |
| Invariant Sections, with no Front-Cover Texts and with no Back-Cover |
| Texts. A copy of the license is included in the section entitled |
| ``GNU Free Documentation License''. |
| @end copying |
| |
| @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 |
| |
| @set NOW January 2007 |
| @c This flag is used where the text refers to conditions that exist when the |
| @c text was entered into the document but which may change over time. |
| @c Update the setting for the flag, and (if necessary) the text surrounding, |
| @c the references to the flag, on future doc revisions: |
| @c search for @value{NOW}. |
| |
| @set FSFEDITION |
| @set EDITION GNAT |
| @set DEFAULTLANGUAGEVERSION Ada 2005 |
| @set NONDEFAULTLANGUAGEVERSION Ada 95 |
| |
| @ifset unw |
| @set PLATFORM |
| @set TITLESUFFIX |
| @end ifset |
| |
| @ifset vms |
| @set PLATFORM OpenVMS |
| @set TITLESUFFIX for OpenVMS |
| @end ifset |
| |
| @c @ovar(ARG) |
| @c ---------- |
| @c The ARG is an optional argument. To be used for macro arguments in |
| @c their documentation (@defmac). |
| @macro ovar{varname} |
| @r{[}@var{\varname\}@r{]}@c |
| @end macro |
| @c Status as of November 2009: |
| @c Unfortunately texi2pdf and texi2html treat the trailing "@c" |
| @c differently, and faulty output is produced by one or the other |
| @c depending on whether the "@c" is present or absent. |
| @c As a result, the @ovar macro is not used, and all invocations |
| @c of the @ovar macro have been expanded inline. |
| |
| |
| @settitle @value{EDITION} User's Guide @value{TITLESUFFIX} |
| @dircategory GNU Ada tools |
| @direntry |
| * @value{EDITION} User's Guide: (gnat_ugn). @value{PLATFORM} |
| @end direntry |
| |
| @include gcc-common.texi |
| |
| @setchapternewpage odd |
| @syncodeindex fn cp |
| @c %**end of header |
| |
| @titlepage |
| @title @value{EDITION} User's Guide |
| @ifset vms |
| @sp 1 |
| @flushright |
| @titlefont{@i{@value{PLATFORM}}} |
| @end flushright |
| @end ifset |
| |
| @sp 2 |
| |
| @subtitle GNAT, The GNU Ada Compiler |
| @versionsubtitle |
| @author AdaCore |
| |
| @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 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:: |
| * Tools Supporting Project Files:: |
| * 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:: |
| * 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:: |
| * Creating Unit Tests Using gnattest:: |
| * Performing Dimensionality Analysis in GNAT:: |
| * Generating Ada Bindings for C and C++ headers:: |
| * Other Utility Programs:: |
| * Running and Debugging Ada Programs:: |
| @ifclear vms |
| * Code Coverage and Profiling:: |
| @end ifclear |
| @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:: |
| * Overflow Check Handling in GNAT:: |
| * Conditional Compilation:: |
| * Inline Assembler:: |
| * Compatibility and Porting Guide:: |
| @ifset unw |
| * Microsoft Windows Topics:: |
| * Mac OS 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:: |
| @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:: |
| * Text_IO Suggestions:: |
| * Reducing Size of Ada Executables with gnatelim:: |
| * Reducing 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:: |
| * Vectorization of loops:: |
| * Other Optimization Switches:: |
| * Optimization and Strict Aliasing:: |
| @ifset vms |
| * Coverage Analysis:: |
| @end ifset |
| |
| Reducing Size of Ada Executables with gnatelim |
| * About gnatelim:: |
| * Running gnatelim:: |
| * Processing Precompiled Libraries:: |
| * Correcting the List of Eliminate Pragmas:: |
| * Making Your Executables Smaller:: |
| * Summary of the gnatelim Usage Cycle:: |
| |
| Reducing 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:: |
| |
| The Cross-Referencing Tools gnatxref and gnatfind |
| |
| * Switches for gnatxref:: |
| * Switches for gnatfind:: |
| * 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 |
| * Preprocessing Symbols:: |
| * Using gnatprep:: |
| * Switches for gnatprep:: |
| * Form of Definitions File:: |
| * Form of Input Text for gnatprep:: |
| |
| 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 |
| |
| Sample Bodies Using gnatstub |
| |
| * Running gnatstub:: |
| * Switches for gnatstub:: |
| |
| Creating Unit Tests Using gnattest |
| |
| * Running gnattest:: |
| * Switches for gnattest:: |
| * Project Attributes for gnattest:: |
| * Simple Example:: |
| * Setting Up and Tearing Down the Testing Environment:: |
| * Regenerating Tests:: |
| * Default Test Behavior:: |
| * Testing Primitive Operations of Tagged Types:: |
| * Testing Inheritance:: |
| * Tagged Types Substitutability Testing:: |
| * Testing with Contracts:: |
| * Additional Tests:: |
| @ifclear vms |
| * Support for other platforms/run-times:: |
| @end ifclear |
| * Current Limitations:: |
| |
| Other Utility Programs |
| |
| * Using Other Utility Programs with GNAT:: |
| * The External Symbol Naming Scheme of GNAT:: |
| * Converting Ada Files to html with gnathtml:: |
| |
| @ifclear vms |
| Code Coverage and Profiling |
| |
| * Code Coverage of Ada Programs using gcov:: |
| * Profiling an Ada Program using gprof:: |
| @end ifclear |
| |
| 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:: |
| * Remote Debugging using gdbserver:: |
| * 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 Language 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:: |
| * RTX-Specific Considerations:: |
| * HP-UX-Specific Considerations:: |
| |
| Example of Binder Output File |
| |
| Elaboration Order Handling in GNAT |
| |
| * Elaboration Code:: |
| * Checking the Elaboration Order:: |
| * Controlling the Elaboration Order:: |
| * 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 Dispatching Calls:: |
| * Summary of Procedures for Elaboration Control:: |
| * Other Elaboration Order Considerations:: |
| |
| Overflow Check Handling in GNAT |
| * Background:: |
| * Overflow Checking Modes in GNAT:: |
| * Specifying the Desired Mode:: |
| * Default Settings:: |
| * Implementation Notes:: |
| |
| Conditional Compilation |
| * Use of Boolean Constants:: |
| * Debugging - A Special Case:: |
| * Conditionalizing Declarations:: |
| * Use of Alternative Implementations:: |
| * Preprocessing:: |
| |
| 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:: |
| * Compatibility between Ada 95 and Ada 2005:: |
| * 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 Systems:: |
| * Representation Clauses:: |
| @ifset vms |
| * Transitioning to 64-Bit GNAT for 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:: |
| |
| Mac OS Topics |
| |
| * Codesigning the Debugger:: |
| @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 compiler and software development toolset for the full Ada |
| 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 programming language. |
| @end ifclear |
| It documents the features of the compiler and tools, and explains |
| how to use them to build Ada applications. |
| |
| @value{EDITION} implements Ada 95 and Ada 2005, and it may also be invoked in |
| Ada 83 compatibility mode. |
| By default, @value{EDITION} assumes @value{DEFAULTLANGUAGEVERSION}, |
| but you can override with a compiler switch |
| (@pxref{Compiling Different Versions of Ada}) |
| to explicitly specify the language version. |
| Throughout this manual, references to ``Ada'' without a year suffix |
| apply to both the Ada 95 and Ada 2005 versions of the language. |
| |
| |
| @ifclear FSFEDITION |
| For ease of exposition, ``@value{EDITION}'' will be referred to simply as |
| ``GNAT'' in the remainder of this document. |
| @end ifclear |
| |
| |
| |
| |
| @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. |
| |
| @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{Creating Unit Tests Using gnattest}, discusses @code{gnattest}, |
| a utility that generates unit testing templates for library units. |
| |
| @item |
| @ref{Performing Dimensionality Analysis in GNAT}, describes the Ada 2012 |
| facilities used in GNAT to declare dimensioned objects, and to verify that |
| uses of these objects are consistent with their given physical dimensions |
| (so that meters cannot be assigned to kilograms, and so on). |
| |
| @item |
| @ref{Generating Ada Bindings for C and C++ headers}, describes how to |
| generate automatically Ada bindings from C and C++ headers. |
| |
| @item |
| @ref{Other Utility Programs}, discusses several other GNAT utilities, |
| including @code{gnathtml}. |
| |
| @ifclear vms |
| @item |
| @ref{Code Coverage and Profiling}, describes how to perform a structural |
| coverage and profile the execution of Ada programs. |
| @end ifclear |
| |
| @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{Overflow Check Handling in GNAT}, describes how GNAT helps |
| you deal with arithmetic overflow issues. |
| |
| @item |
| @ref{Conditional Compilation}, describes how to model conditional compilation, |
| both with Ada in general and with GNAT facilities in particular. |
| |
| @item |
| @ref{Inline Assembler}, shows how to use the inline assembly facility |
| in an Ada program. |
| |
| @item |
| @ref{Compatibility and Porting Guide}, contains sections on compatibility |
| of GNAT with other Ada development environments (including Ada 83 systems), |
| to assist in porting code from those environments. |
| |
| @ifset unw |
| @item |
| @ref{Microsoft Windows Topics}, presents information relevant to the |
| Microsoft Windows platform. |
| |
| @item |
| @ref{Mac OS Topics}, presents information relevant to Apple's OS X |
| 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 |
| @cindex Ada 2005 Language Reference Manual |
| @noindent |
| This guide assumes a basic familiarity with the Ada 95 language, as |
| described in the International Standard ANSI/ISO/IEC-8652:1995, January |
| 1995. |
| It does not require knowledge of the new features introduced by Ada 2005, |
| (officially known as ISO/IEC 8652:1995 with Technical Corrigendum 1 |
| and Amendment 1). |
| Both reference manuals are included in the GNAT documentation |
| package. |
| |
| @node Related Information |
| @unnumberedsec Related Information |
| |
| @noindent |
| For further information about related tools, refer to the following |
| documents: |
| |
| @itemize @bullet |
| @item |
| @xref{Top, GNAT Reference Manual, About This Guide, gnat_rm, GNAT |
| Reference Manual}, which contains all reference material for the GNAT |
| implementation of Ada. |
| |
| @ifset unw |
| @item |
| @cite{Using the GNAT Programming Studio}, which describes the GPS |
| Integrated Development Environment. |
| |
| @item |
| @cite{GNAT Programming Studio Tutorial}, which introduces the |
| main GPS features through examples. |
| @end ifset |
| |
| @item |
| @cite{Ada 95 Reference Manual}, which contains reference |
| material for the Ada 95 programming language. |
| |
| @item |
| @cite{Ada 2005 Reference Manual}, which contains reference |
| material for the Ada 2005 programming language. |
| |
| @item |
| @xref{Top,, Debugging with GDB, gdb, Debugging with GDB}, |
| @ifset vms |
| in the GNU:[DOCS] directory, |
| @end ifset |
| for all details on the use of the GNU source-level debugger. |
| |
| @item |
| @xref{Top,, The extensible self-documenting text editor, emacs, |
| GNU Emacs Manual}, |
| @ifset vms |
| located in the GNU:[DOCS] directory if the EMACS kit is installed, |
| @end ifset |
| for 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}, @command{utility program names}, @code{standard names}, |
| and @code{classes}. |
| |
| @item |
| @option{Option flags} |
| |
| @item |
| @file{File names}, @samp{button names}, and @samp{field names}. |
| |
| @item |
| @code{Variables}, @env{environment variables}, and @var{metasyntactic |
| variables}. |
| |
| @item |
| @emph{Emphasis}. |
| |
| @item |
| @r{[}optional information or parameters@r{]} |
| |
| @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 GPS}, provides a brief |
| introduction to the GNAT Programming Studio, a visually-oriented |
| Integrated Development Environment for GNAT. |
| GPS offers a graphical ``look and feel'', support for development in |
| other programming languages, comprehensive browsing features, and |
| many other capabilities. |
| For information on GPS please refer to |
| @cite{Using the GNAT Programming Studio}. |
| @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:: |
| @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. |
| (If @code{Emacs} is |
| used, the optional Ada mode may be helpful in laying out the program.) |
| The |
| program text is a normal text file. We will assume 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 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 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 Studio) |
| @cindex GNAT Programming Studio (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 Studio''), 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 |
| @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 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#} |
| @dots{} @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#0@var{xxxxxxx}# |
| 16#0080#-16#07ff#: 2#110@var{xxxxx}# 2#10@var{xxxxxx}# |
| 16#0800#-16#ffff#: 2#1110@var{xxxx}# 2#10@var{xxxxxx}# 2#10@var{xxxxxx}# |
| |
| @end smallexample |
| |
| @noindent |
| where the @var{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 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 |
| @samp{A}, @samp{G}, @samp{I}, or @samp{S}, |
| @end ifset |
| @ifclear vms |
| @samp{a}, @samp{g}, @samp{i}, or @samp{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 |
| @samp{S-}, @samp{A-}, @samp{I-}, and @samp{G-}, |
| @end ifset |
| @ifclear vms |
| @samp{s-}, @samp{a-}, @samp{i-}, and @samp{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 @option{-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 @command{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 |
| @r{[},Casing => CASING_SPEC@r{]} |
| @r{[},Dot_Replacement => STRING_LITERAL@r{]}); |
| |
| pragma Source_File_Name ( |
| Body_File_Name => FILE_NAME_PATTERN |
| @r{[},Casing => CASING_SPEC@r{]} |
| @r{[},Dot_Replacement => STRING_LITERAL@r{]}); |
| |
| pragma Source_File_Name ( |
| Subunit_File_Name => FILE_NAME_PATTERN |
| @r{[},Casing => CASING_SPEC@r{]} |
| @r{[},Dot_Replacement => STRING_LITERAL@r{]}); |
| |
| 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 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. |
| |
| When using a gcc-based back end (in practice this means using any version |
| of GNAT other than the JGNAT, .NET or GNAAMP versions), then the use of |
| @option{-gnatN} is deprecated, and the use of @option{-gnatn} is preferred. |
| Historically front end inlining was more extensive than the gcc back end |
| inlining, but that is no longer the case. |
| |
| @item |
| If an object file @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 @file{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 dictated by the |
| Ada language standard. However, it is a superset of what the |
| standard 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. |
| A full treatment of these topics is provided in Appendix B, section 1 |
| of the Ada 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 |
| |
| @noindent |
| Depending on the circumstances (for example when your non-Ada main object |
| does not provide symbol @code{main}), you may also need to instruct the |
| GNAT linker not to include the standard startup objects by passing the |
| @option{^-nostartfiles^/NOSTART_FILES^} switch to @command{gnatlink}. |
| |
| @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 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 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 C_Plus_Plus (or 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 Reference Manual. |
| |
| @item Intrinsic |
| This applies to an intrinsic operation, as defined in the Ada |
| 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 may |
| be applied to the following sets of names: |
| |
| @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. |
| |
| @item |
| General subprogram entities, to bind an Ada subprogram declaration to |
| a compiler builtin by name with back-ends where such interfaces are |
| available. A typical example is the set of ``__builtin'' functions |
| exposed by the GCC back-end, as in the following example: |
| |
| @smallexample @c ada |
| function builtin_sqrt (F : Float) return Float; |
| pragma Import (Intrinsic, builtin_sqrt, "__builtin_sqrtf"); |
| @end smallexample |
| |
| Most of the GCC builtins are accessible this way, and as for other |
| import conventions (e.g. C), it is the user's responsibility to ensure |
| that the Ada subprogram profile matches the underlying builtin |
| expectations. |
| @end itemize |
| |
| @noindent |
| |
| @ifset unw |
| @findex Stdcall |
| @cindex Convention Stdcall |
| @item Stdcall |
| This is relevant only to Windows XP/2000/NT 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 parameterize 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. This section gives a few |
| hints that should make this task easier. The first section addresses |
| the differences between interfacing with C and 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 library 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:: |
| * Interfacing with C++ constructors:: |
| * Interfacing with C++ at the Class Level:: |
| @end menu |
| |
| @node Interfacing to C++ |
| @subsection Interfacing to C++ |
| |
| @noindent |
| GNAT supports interfacing with the G++ compiler (or any C++ compiler |
| generating code that is compatible with the G++ Application Binary |
| Interface ---see http://www.codesourcery.com/archives/cxx-abi). |
| |
| @noindent |
| Interfacing can be done at 3 levels: simple data, subprograms, and |
| classes. In the first two cases, GNAT offers a specific @code{Convention |
| C_Plus_Plus} (or @code{CPP}) that behaves exactly like @code{Convention C}. |
| Usually, C++ mangles the names of subprograms. To generate proper mangled |
| names automatically, see @ref{Generating Ada Bindings for C and C++ headers}). |
| This problem can also be addressed manually 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 (using e.g. @command{nm}) and using 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_Constructor}. @xref{Interfacing to C++,,, |
| gnat_rm, 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{g++}. |
| |
| Note that if the C++ code uses inline functions, you will need to |
| compile your C++ code with the @code{-fkeep-inline-functions} switch in |
| order to provide an existing function implementation that the Ada code can |
| link with. |
| |
| @smallexample |
| $ g++ -c -fkeep-inline-functions file1.C |
| $ g++ -c -fkeep-inline-functions file2.C |
| $ gnatmake ada_unit -largs file1.o file2.o --LINK=g++ |
| @end smallexample |
| |
| @item |
| Using GNAT and G++ from two different GCC installations: If both |
| compilers are on the @env{PATH}, the previous method may be used. It is |
| important to note that environment variables such as |
| @env{C_INCLUDE_PATH}, @env{GCC_EXEC_PREFIX}, @env{BINUTILS_ROOT}, and |
| @env{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 @command{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), |
| 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 |
| or AIX), the simple approach described above will not work and |
| a pre-linking phase using GNAT will be necessary. |
| |
| @end enumerate |
| |
| Another alternative is to use the @command{gprbuild} multi-language builder |
| which has a large knowledge base and knows how to link Ada and C++ code |
| together automatically in most cases. |
| |
| @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 |
| $ g++ -c cpp_main.C |
| $ g++ -c ex7.C |
| $ gnatbind -n simple_cpp_interface |
| $ gnatlink simple_cpp_interface -o cpp_main --LINK=g++ |
| -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); |
| @} |
| @end smallexample |
| |
| @smallexample @c ada |
| -- Ada sources |
| package body Simple_Cpp_Interface is |
| |
| procedure Ada_Method2 (This : in out A; V : Integer) is |
| begin |
| Method1 (This); |
| This.A_Value := V; |
| end Ada_Method2; |
| |
| end Simple_Cpp_Interface; |
| |
| with System; |
| package Simple_Cpp_Interface is |
| type A is limited |
| record |
| Vptr : System.Address; |
| O_Value : Integer; |
| A_Value : Integer; |
| end record; |
| pragma Convention (C, A); |
| |
| procedure Method1 (This : in out A); |
| pragma Import (C, Method1); |
| |
| procedure Ada_Method2 (This : in out A; V : Integer); |
| pragma Export (C, Ada_Method2); |
| |
| end Simple_Cpp_Interface; |
| @end smallexample |
| |
| @node Interfacing with C++ constructors |
| @subsection Interfacing with C++ constructors |
| @noindent |
| |
| In order to interface with C++ constructors GNAT provides the |
| @code{pragma CPP_Constructor} (@xref{Interfacing to C++,,, |
| gnat_rm, GNAT Reference Manual}, for additional information). |
| In this section we present some common uses of C++ constructors |
| in mixed-languages programs in GNAT. |
| |
| Let us assume that we need to interface with the following |
| C++ class: |
| |
| @smallexample |
| @b{class} Root @{ |
| @b{public}: |
| int a_value; |
| int b_value; |
| @b{virtual} int Get_Value (); |
| Root(); // Default constructor |
| Root(int v); // 1st non-default constructor |
| Root(int v, int w); // 2nd non-default constructor |
| @}; |
| @end smallexample |
| |
| For this purpose we can write the following package spec (further |
| information on how to build this spec is available in |
| @ref{Interfacing with C++ at the Class Level} and |
| @ref{Generating Ada Bindings for C and C++ headers}). |
| |
| @smallexample @c ada |
| with Interfaces.C; use Interfaces.C; |
| package Pkg_Root is |
| type Root is tagged limited record |
| A_Value : int; |
| B_Value : int; |
| end record; |
| pragma Import (CPP, Root); |
| |
| function Get_Value (Obj : Root) return int; |
| pragma Import (CPP, Get_Value); |
| |
| function Constructor return Root; |
| pragma Cpp_Constructor (Constructor, "_ZN4RootC1Ev"); |
| |
| function Constructor (v : Integer) return Root; |
| pragma Cpp_Constructor (Constructor, "_ZN4RootC1Ei"); |
| |
| function Constructor (v, w : Integer) return Root; |
| pragma Cpp_Constructor (Constructor, "_ZN4RootC1Eii"); |
| end Pkg_Root; |
| @end smallexample |
| |
| On the Ada side the constructor is represented by a function (whose |
| name is arbitrary) that returns the classwide type corresponding to |
| the imported C++ class. Although the constructor is described as a |
| function, it is typically a procedure with an extra implicit argument |
| (the object being initialized) at the implementation level. GNAT |
| issues the appropriate call, whatever it is, to get the object |
| properly initialized. |
| |
| Constructors can only appear in the following contexts: |
| |
| @itemize @bullet |
| @item |
| On the right side of an initialization of an object of type @var{T}. |
| @item |
| On the right side of an initialization of a record component of type @var{T}. |
| @item |
| In an Ada 2005 limited aggregate. |
| @item |
| In an Ada 2005 nested limited aggregate. |
| @item |
| In an Ada 2005 limited aggregate that initializes an object built in |
| place by an extended return statement. |
| @end itemize |
| |
| @noindent |
| In a declaration of an object whose type is a class imported from C++, |
| either the default C++ constructor is implicitly called by GNAT, or |
| else the required C++ constructor must be explicitly called in the |
| expression that initializes the object. For example: |
| |
| @smallexample @c ada |
| Obj1 : Root; |
| Obj2 : Root := Constructor; |
| Obj3 : Root := Constructor (v => 10); |
| Obj4 : Root := Constructor (30, 40); |
| @end smallexample |
| |
| The first two declarations are equivalent: in both cases the default C++ |
| constructor is invoked (in the former case the call to the constructor is |
| implicit, and in the latter case the call is explicit in the object |
| declaration). @code{Obj3} is initialized by the C++ non-default constructor |
| that takes an integer argument, and @code{Obj4} is initialized by the |
| non-default C++ constructor that takes two integers. |
| |
| Let us derive the imported C++ class in the Ada side. For example: |
| |
| @smallexample @c ada |
| type DT is new Root with record |
| C_Value : Natural := 2009; |
| end record; |
| @end smallexample |
| |
| In this case the components DT inherited from the C++ side must be |
| initialized by a C++ constructor, and the additional Ada components |
| of type DT are initialized by GNAT. The initialization of such an |
| object is done either by default, or by means of a function returning |
| an aggregate of type DT, or by means of an extension aggregate. |
| |
| @smallexample @c ada |
| Obj5 : DT; |
| Obj6 : DT := Function_Returning_DT (50); |
| Obj7 : DT := (Constructor (30,40) with C_Value => 50); |
| @end smallexample |
| |
| The declaration of @code{Obj5} invokes the default constructors: the |
| C++ default constructor of the parent type takes care of the initialization |
| of the components inherited from Root, and GNAT takes care of the default |
| initialization of the additional Ada components of type DT (that is, |
| @code{C_Value} is initialized to value 2009). The order of invocation of |
| the constructors is consistent with the order of elaboration required by |
| Ada and C++. That is, the constructor of the parent type is always called |
| before the constructor of the derived type. |
| |
| Let us now consider a record that has components whose type is imported |
| from C++. For example: |
| |
| @smallexample @c ada |
| type Rec1 is limited record |
| Data1 : Root := Constructor (10); |
| Value : Natural := 1000; |
| end record; |
| |
| type Rec2 (D : Integer := 20) is limited record |
| Rec : Rec1; |
| Data2 : Root := Constructor (D, 30); |
| end record; |
| @end smallexample |
| |
| The initialization of an object of type @code{Rec2} will call the |
| non-default C++ constructors specified for the imported components. |
| For example: |
| |
| @smallexample @c ada |
| Obj8 : Rec2 (40); |
| @end smallexample |
| |
| Using Ada 2005 we can use limited aggregates to initialize an object |
| invoking C++ constructors that differ from those specified in the type |
| declarations. For example: |
| |
| @smallexample @c ada |
| Obj9 : Rec2 := (Rec => (Data1 => Constructor (15, 16), |
| others => <>), |
| others => <>); |
| @end smallexample |
| |
| The above declaration uses an Ada 2005 limited aggregate to |
| initialize @code{Obj9}, and the C++ constructor that has two integer |
| arguments is invoked to initialize the @code{Data1} component instead |
| of the constructor specified in the declaration of type @code{Rec1}. In |
| Ada 2005 the box in the aggregate indicates that unspecified components |
| are initialized using the expression (if any) available in the component |
| declaration. That is, in this case discriminant @code{D} is initialized |
| to value @code{20}, @code{Value} is initialized to value 1000, and the |
| non-default C++ constructor that handles two integers takes care of |
| initializing component @code{Data2} with values @code{20,30}. |
| |
| In Ada 2005 we can use the extended return statement to build the Ada |
| equivalent to C++ non-default constructors. For example: |
| |
| @smallexample @c ada |
| function Constructor (V : Integer) return Rec2 is |
| begin |
| return Obj : Rec2 := (Rec => (Data1 => Constructor (V, 20), |
| others => <>), |
| others => <>) do |
| -- Further actions required for construction of |
| -- objects of type Rec2 |
| ... |
| end record; |
| end Constructor; |
| @end smallexample |
| |
| In this example the extended return statement construct is used to |
| build in place the returned object whose components are initialized |
| by means of a limited aggregate. Any further action associated with |
| the constructor can be placed inside the construct. |
| |
| @node Interfacing with C++ at the Class Level |
| @subsection Interfacing with C++ at the Class Level |
| @noindent |
| In this section we demonstrate the GNAT features for interfacing with |
| C++ by means of an example making use of Ada 2005 abstract interface |
| types. This example consists of a classification of animals; classes |
| have been used to model our main classification of animals, and |
| interfaces provide support for the management of secondary |
| classifications. We first demonstrate a case in which the types and |
| constructors are defined on the C++ side and imported from the Ada |
| side, and latter the reverse case. |
| |
| The root of our derivation will be the @code{Animal} class, with a |
| single private attribute (the @code{Age} of the animal) and two public |
| primitives to set and get the value of this attribute. |
| |
| @smallexample |
| @b{class} Animal @{ |
| @b{public}: |
| @b{virtual} void Set_Age (int New_Age); |
| @b{virtual} int Age (); |
| @b{private}: |
| int Age_Count; |
| @}; |
| @end smallexample |
| |
| Abstract interface types are defined in C++ by means of classes with pure |
| virtual functions and no data members. In our example we will use two |
| interfaces that provide support for the common management of @code{Carnivore} |
| and @code{Domestic} animals: |
| |
| @smallexample |
| @b{class} Carnivore @{ |
| @b{public}: |
| @b{virtual} int Number_Of_Teeth () = 0; |
| @}; |
| |
| @b{class} Domestic @{ |
| @b{public}: |
| @b{virtual void} Set_Owner (char* Name) = 0; |
| @}; |
| @end smallexample |
| |
| Using these declarations, we can now say that a @code{Dog} is an animal that is |
| both Carnivore and Domestic, that is: |
| |
| @smallexample |
| @b{class} Dog : Animal, Carnivore, Domestic @{ |
| @b{public}: |
| @b{virtual} int Number_Of_Teeth (); |
| @b{virtual} void Set_Owner (char* Name); |
| |
| Dog(); // Constructor |
| @b{private}: |
| int Tooth_Count; |
| char *Owner; |
| @}; |
| @end smallexample |
| |
| In the following examples we will assume that the previous declarations are |
| located in a file named @code{animals.h}. The following package demonstrates |
| how to import these C++ declarations from the Ada side: |
| |
| @smallexample @c ada |
| with Interfaces.C.Strings; use Interfaces.C.Strings; |
| package Animals is |
| type Carnivore is interface; |
| pragma Convention (C_Plus_Plus, Carnivore); |
| function Number_Of_Teeth (X : Carnivore) |
| return Natural is abstract; |
| |
| type Domestic is interface; |
| pragma Convention (C_Plus_Plus, Set_Owner); |
| procedure Set_Owner |
| (X : in out Domestic; |
| Name : Chars_Ptr) is abstract; |
| |
| type Animal is tagged record |
| Age : Natural := 0; |
| end record; |
| pragma Import (C_Plus_Plus, Animal); |
| |
| procedure Set_Age (X : in out Animal; Age : Integer); |
| pragma Import (C_Plus_Plus, Set_Age); |
| |
| function Age (X : Animal) return Integer; |
| pragma Import (C_Plus_Plus, Age); |
| |
| type Dog is new Animal and Carnivore and Domestic with record |
| Tooth_Count : Natural; |
| Owner : String (1 .. 30); |
| end record; |
| pragma Import (C_Plus_Plus, Dog); |
| |
| function Number_Of_Teeth (A : Dog) return Integer; |
| pragma Import (C_Plus_Plus, Number_Of_Teeth); |
| |
| procedure Set_Owner (A : in out Dog; Name : Chars_Ptr); |
| pragma Import (C_Plus_Plus, Set_Owner); |
| |
| function New_Dog return Dog; |
| pragma CPP_Constructor (New_Dog); |
| pragma Import (CPP, New_Dog, "_ZN3DogC2Ev"); |
| end Animals; |
| @end smallexample |
| |
| Thanks to the compatibility between GNAT run-time structures and the C++ ABI, |
| interfacing with these C++ classes is easy. The only requirement is that all |
| the primitives and components must be declared exactly in the same order in |
| the two languages. |
| |
| Regarding the abstract interfaces, we must indicate to the GNAT compiler by |
| means of a @code{pragma Convention (C_Plus_Plus)}, the convention used to pass |
| the arguments to the called primitives will be the same as for C++. For the |
| imported classes we use @code{pragma Import} with convention @code{C_Plus_Plus} |
| to indicate that they have been defined on the C++ side; this is required |
| because the dispatch table associated with these tagged types will be built |
| in the C++ side and therefore will not contain the predefined Ada primitives |
| which Ada would otherwise expect. |
| |
| As the reader can see there is no need to indicate the C++ mangled names |
| associated with each subprogram because it is assumed that all the calls to |
| these primitives will be dispatching calls. The only exception is the |
| constructor, which must be registered with the compiler by means of |
| @code{pragma CPP_Constructor} and needs to provide its associated C++ |
| mangled name because the Ada compiler generates direct calls to it. |
| |
| With the above packages we can now declare objects of type Dog on the Ada side |
| and dispatch calls to the corresponding subprograms on the C++ side. We can |
| also extend the tagged type Dog with further fields and primitives, and |
| override some of its C++ primitives on the Ada side. For example, here we have |
| a type derivation defined on the Ada side that inherits all the dispatching |
| primitives of the ancestor from the C++ side. |
| |
| @smallexample |
| @b{with} Animals; @b{use} Animals; |
| @b{package} Vaccinated_Animals @b{is} |
| @b{type} Vaccinated_Dog @b{is new} Dog @b{with null record}; |
| @b{function} Vaccination_Expired (A : Vaccinated_Dog) @b{return} Boolean; |
| @b{end} Vaccinated_Animals; |
| @end smallexample |
| |
| It is important to note that, because of the ABI compatibility, the programmer |
| does not need to add any further information to indicate either the object |
| layout or the dispatch table entry associated with each dispatching operation. |
| |
| Now let us define all the types and constructors on the Ada side and export |
| them to C++, using the same hierarchy of our previous example: |
| |
| @smallexample @c ada |
| with Interfaces.C.Strings; |
| use Interfaces.C.Strings; |
| package Animals is |
| type Carnivore is interface; |
| pragma Convention (C_Plus_Plus, Carnivore); |
| function Number_Of_Teeth (X : Carnivore) |
| return Natural is abstract; |
| |
| type Domestic is interface; |
| pragma Convention (C_Plus_Plus, Set_Owner); |
| procedure Set_Owner |
| (X : in out Domestic; |
| Name : Chars_Ptr) is abstract; |
| |
| type Animal is tagged record |
| Age : Natural := 0; |
| end record; |
| pragma Convention (C_Plus_Plus, Animal); |
| |
| procedure Set_Age (X : in out Animal; Age : Integer); |
| pragma Export (C_Plus_Plus, Set_Age); |
| |
| function Age (X : Animal) return Integer; |
| pragma Export (C_Plus_Plus, Age); |
| |
| type Dog is new Animal and Carnivore and Domestic with record |
| Tooth_Count : Natural; |
| Owner : String (1 .. 30); |
| end record; |
| pragma Convention (C_Plus_Plus, Dog); |
| |
| function Number_Of_Teeth (A : Dog) return Integer; |
| pragma Export (C_Plus_Plus, Number_Of_Teeth); |
| |
| procedure Set_Owner (A : in out Dog; Name : Chars_Ptr); |
| pragma Export (C_Plus_Plus, Set_Owner); |
| |
| function New_Dog return Dog'Class; |
| pragma Export (C_Plus_Plus, New_Dog); |
| end Animals; |
| @end smallexample |
| |
| Compared with our previous example the only difference is the use of |
| @code{pragma Export} to indicate to the GNAT compiler that the primitives will |
| be available to C++. Thanks to the ABI compatibility, on the C++ side there is |
| nothing else to be done; as explained above, the only requirement is that all |
| the primitives and components are declared in exactly the same order. |
| |
| For completeness, let us see a brief C++ main program that uses the |
| declarations available in @code{animals.h} (presented in our first example) to |
| import and use the declarations from the Ada side, properly initializing and |
| finalizing the Ada run-time system along the way: |
| |
| @smallexample |
| @b{#include} "animals.h" |
| @b{#include} <iostream> |
| @b{using namespace} std; |
| |
| void Check_Carnivore (Carnivore *obj) @{@dots{}@} |
| void Check_Domestic (Domestic *obj) @{@dots{}@} |
| void Check_Animal (Animal *obj) @{@dots{}@} |
| void Check_Dog (Dog *obj) @{@dots{}@} |
| |
| @b{extern} "C" @{ |
| void adainit (void); |
| void adafinal (void); |
| Dog* new_dog (); |
| @} |
| |
| void test () |
| @{ |
| Dog *obj = new_dog(); // Ada constructor |
| Check_Carnivore (obj); // Check secondary DT |
| Check_Domestic (obj); // Check secondary DT |
| Check_Animal (obj); // Check primary DT |
| Check_Dog (obj); // Check primary DT |
| @} |
| |
| int main () |
| @{ |
| adainit (); test(); adafinal (); |
| return 0; |
| @} |
| @end smallexample |
| |
| @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 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 @var{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 |
| @c $ gcc -c @ovar{switches} @file{file name} |
| @c Expanding @ovar macro inline (explanation in macro def comments) |
| $ gcc -c @r{[}@var{switches}@r{]} @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. |
| @xref{Directory Options,, Options for Directory Search, gcc, Using the |
| GNU Compiler Collection (GCC)}, 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 -fcallgraph-info@r{[}=su,da@r{]} |
| @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 additional, per-node and/or per-edge information, if a |
| list of comma-separated markers is additionally specified. When the |
| @var{su} marker is specified, the callgraph is decorated with stack usage information; it is equivalent to @option{-fstack-usage}. When the @var{da} |
| marker is specified, the callgraph is decorated with information about |
| dynamically allocated objects. |
| |
| @item -fdump-scos |
| @cindex @option{-fdump-scos} (@command{gcc}) |
| Generates SCO (Source Coverage Obligation) information in the ALI file. |
| This information is used by advanced coverage tools. See unit @file{SCOs} |
| in the compiler sources for details in files @file{scos.ads} and |
| @file{scos.adb}. |
| |
| @item -flto@r{[}=n@r{]} |
| @cindex @option{-flto} (@command{gcc}) |
| Enables Link Time Optimization. This switch must be used in conjunction |
| with the traditional @option{-Ox} switches and instructs the compiler to |
| defer most optimizations until the link stage. The advantage of this |
| approach is that the compiler can do a whole-program analysis and choose |
| the best interprocedural optimization strategy based on a complete view |
| of the program, instead of a fragmentary view with the usual approach. |
| This can also speed up the compilation of huge programs and reduce the |
| size of the final executable, compared with a per-unit compilation with |
| full inlining across modules enabled with the @option{-gnatn2} switch. |
| The drawback of this approach is that it may require much more memory. |
| The switch, as well as the accompanying @option{-Ox} switches, must be |
| specified both for the compilation and the link phases. |
| If the @var{n} parameter is specified, the optimization and final code |
| generation at link time are executed using @var{n} parallel jobs by |
| means of an installed @command{make} program. |
| |
| @item -fno-inline |
| @cindex @option{-fno-inline} (@command{gcc}) |
| Suppresses all 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}. |
| Any occurrences of pragma @code{Inline} or @code{Inline_Always} |
| are ignored, and @option{-gnatn} and @option{-gnatN} have no |
| effects if this switch is present. Note that inlining can also |
| be suppressed on a finer-grained basis with pragma @code{No_Inline}. |
| |
| @item -fno-inline-functions |
| @cindex @option{-fno-inline-functions} (@command{gcc}) |
| Suppresses automatic inlining of subprograms, which is enabled |
| if @option{-O3} is used. |
| |
| @item -fno-inline-small-functions |
| @cindex @option{-fno-inline-small-functions} (@command{gcc}) |
| Suppresses automatic inlining of small subprograms, which is enabled |
| if @option{-O2} is used. |
| |
| @item -fno-inline-functions-called-once |
| @cindex @option{-fno-inline-functions-called-once} (@command{gcc}) |
| Suppresses inlining of subprograms local to the unit and called once |
| from within it, which is enabled if @option{-O1} is used. |
| |
| @item -fno-ivopts |
| @cindex @option{-fno-ivopts} (@command{gcc}) |
| Suppresses high-level loop induction variable optimizations, which are |
| enabled if @option{-O1} is used. These optimizations are generally |
| profitable but, for some specific cases of loops with numerous uses |
| of the iteration variable that follow a common pattern, they may end |
| up destroying the regularity that could be exploited at a lower level |
| and thus producing inferior code. |
| |
| @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-subprogram basis. See @ref{Static Stack Usage Analysis} for details. |
| |
| @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 -gnat2005 |
| @cindex @option{-gnat2005} (@command{gcc}) |
| Allow full Ada 2005 features (same as @option{-gnat05}) |
| |
| @item -gnat12 |
| @cindex @option{-gnat12} (@command{gcc}) |
| |
| @item -gnat2012 |
| @cindex @option{-gnat2012} (@command{gcc}) |
| Allow full Ada 2012 features (same as @option{-gnat12}) |
| |
| @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}. |
| It also activates pragmas @code{Check}, @code{Precondition}, and |
| @code{Postcondition}. Note that these pragmas can also be controlled |
| using the configuration pragma @code{Check_Policy}. In Ada 2012, it |
| also activates all assertions defined in the RM as aspects: preconditions, |
| postconditions, type invariants and (sub)type predicates. In all Ada modes, |
| corresponding pragmas for type invariants and (sub)type predicates are |
| also activated. |
| |
| @item -gnatA |
| @cindex @option{-gnatA} (@command{gcc}) |
| Avoid processing @file{gnat.adc}. If a @file{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 -gnatB |
| @cindex @option{-gnatB} (@command{gcc}) |
| Assume no invalid (bad) values except for 'Valid attribute use |
| (@pxref{Validity Checking}). |
| |
| @item -gnatc |
| @cindex @option{-gnatc} (@command{gcc}) |
| Check syntax and semantics only (no code generation attempted). |
| |
| @item -gnatC |
| @cindex @option{-gnatC} (@command{gcc}) |
| Generate CodePeer information (no code generation attempted). |
| This switch will generate an intermediate representation suitable for |
| use by CodePeer (@file{.scil} files). This switch is not compatible with |
| code generation (it will, among other things, disable some switches such |
| as -gnatn, and enable others such as -gnata). |
| |
| @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. |
| |
| @ifclear vms |
| @item -gnatD |
| @cindex @option{-gnatD[nn]} (@command{gcc}) |
| @end ifclear |
| @ifset vms |
| @item /XDEBUG /LXDEBUG=nnn |
| @end ifset |
| Create expanded source files for source level debugging. This switch |
| also suppress generation of cross-reference information |
| (see @option{-gnatx}). |
| |
| @item ^-gnateA^/ALIASING_CHECK^ |
| @cindex @option{-gnateA} (@command{gcc}) |
| Check that there is no aliasing between two parameters of the same subprogram. |
| |
| @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^/DISABLE_ATOMIC_SYNCHRONIZATION^ |
| @cindex @option{-gnated} (@command{gcc}) |
| Disable atomic synchronization |
| |
| @item ^-gnateD^/DATA_PREPROCESSING=^symbol@r{[}=@var{value}@r{]} |
| @cindex @option{-gnateD} (@command{gcc}) |
| Defines a symbol, associated with @var{value}, for preprocessing. |
| (@pxref{Integrated Preprocessing}). |
| |
| @item -gnateE |
| @cindex @option{-gnateE} (@command{gcc}) |
| Generate extra information in exception messages. In particular, display |
| extra column information and the value and range associated with index and |
| range check failures, and extra column information for access checks. |
| In cases where the compiler is able to determine at compile time that |
| a check will fail, it gives a warning, and the extra information is not |
| produced at run time. |
| |
| @item -gnatef |
| @cindex @option{-gnatef} (@command{gcc}) |
| Display full source path name in brief error messages. |
| |
| @item -gnateF |
| @cindex @option{-gnateF} (@command{gcc}) |
| Check for overflow on all floating-point operations, including those |
| for unconstrained predefined types. See description of pragma |
| @code{Check_Float_Overflow} in GNAT RM. |
| |
| @item -gnateG |
| @cindex @option{-gnateG} (@command{gcc}) |
| Save result of preprocessing in a text file. |
| |
| @item -gnatei@var{nnn} |
| @cindex @option{-gnatei} (@command{gcc}) |
| Set maximum number of instantiations during compilation of a single unit to |
| @var{nnn}. This may be useful in increasing the default maximum of 8000 for |
| the rare case when a single unit legitimately exceeds this limit. |
| |
| @item -gnateI@var{nnn} |
| @cindex @option{-gnateI} (@command{gcc}) |
| Indicates that the source is a multi-unit source and that the index of the |
| unit to compile is @var{nnn}. @var{nnn} needs to be a positive number and need |
| to be a valid index in the multi-unit source. |
| |
| @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 -gnateP |
| @cindex @option{-gnateP} (@command{gcc}) |
| Turn categorization dependency errors into warnings. |
| Ada requires that units that WITH one another have compatible categories, for |
| example a Pure unit cannot WITH a Preelaborate unit. If this switch is used, |
| these errors become warnings (which can be ignored, or suppressed in the usual |
| manner). This can be useful in some specialized circumstances such as the |
| temporary use of special test software. |
| |
| @item -gnateS |
| @cindex @option{-gnateS} (@command{gcc}) |
| Synonym of @option{-fdump-scos}, kept for backards compatibility. |
| |
| @item ^-gnatet^/TARGET_DEPENDENT_INFO^ |
| @cindex @option{-gnatet} (@command{gcc}) |
| Generate target dependent information. |
| |
| @item ^-gnateV^/PARAMETER_VALIDITY_CHECK^ |
| @cindex @option{-gnateV} (@command{gcc}) |
| Check validity of subprogram parameters. |
| |
| @item ^-gnateY^/IGNORE_SUPPRESS_SYLE_CHECK_PRAGMAS^ |
| @cindex @option{-gnateY} (@command{gcc}) |
| Ignore all STYLE_CHECKS pragmas. Full legality checks |
| are still carried out, but the pragmas have no effect |
| on what style checks are active. This allows all style |
| checking options to be controlled from the command line. |
| |
| @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^/GNAT_INTERNAL^ |
| @cindex @option{^-gnatg^/GNAT_INTERNAL^} (@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^/GNAT_INTERNAL^} implies |
| @option{^-gnatwae^/WARNINGS=ALL,ERRORS^} and |
| @option{^-gnatyg^/STYLE_CHECKS=GNAT^} |
| so that all standard warnings and all standard style options are turned on. |
| All warnings and style messages are treated as errors. |
| |
| @ifclear vms |
| @item -gnatG=nn |
| @cindex @option{-gnatG[nn]} (@command{gcc}) |
| @end ifclear |
| @ifset vms |
| @item /EXPAND_SOURCE, /LEXPAND_SOURCE=nnn |
| @end ifset |
| 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 |
| For details of the possible selections for @var{c}, |
| see @ref{Character Set Control}. |
| |
| @item ^-gnatI^/IGNORE_REP_CLAUSES^ |
| @cindex @option{^-gnatI^IGNORE_REP_CLAUSES^} (@command{gcc}) |
| Ignore representation clauses. When this switch is used, |
| representation clauses are treated as comments. This is useful |
| when initially porting code where you want to ignore rep clause |
| problems, and also for compiling foreign code (particularly |
| for use with ASIS). The representation clauses that are ignored |
| are: enumeration_representation_clause, record_representation_clause, |
| and attribute_definition_clause for the following attributes: |
| Address, Alignment, Bit_Order, Component_Size, Machine_Radix, |
| Object_Size, Size, Small, Stream_Size, and Value_Size. |
| Note that this option should be used only for compiling -- the |
| code is likely to malfunction at run time. |
| |
| @item -gnatjnn |
| @cindex @option{-gnatjnn} (@command{gcc}) |
| Reformat error messages to fit on nn character lines |
| |
| @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 -gnatL |
| @cindex @option{-gnatL} (@command{gcc}) |
| Used in conjunction with -gnatG or -gnatD to intersperse original |
| source lines (as comment lines with line numbers) in the expanded |
| source output. |
| |
| @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..999999. The default setting if |
| no switch is given is 9999. If the number of warnings reaches this |
| limit, then a message is output and further warnings are suppressed, |
| but the compilation is continued. If the number of error messages |
| reaches this limit, then a message is output and the compilation |
| is abandoned. The equal sign here is optional. A value of zero |
| means that no limit applies. |
| |
| @item -gnatn[12] |
| @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. An optional |
| digit sets the inlining level: 1 for moderate inlining across modules |
| or 2 for full inlining across modules. If no inlining level is specified, |
| the compiler will pick it based on the optimization level. |
| |
| @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. |
| |
| When using a gcc-based back end (in practice this means using any version |
| of GNAT other than the JGNAT, .NET or GNAAMP versions), then the use of |
| @option{-gnatN} is deprecated, and the use of @option{-gnatn} is preferred. |
| Historically front end inlining was more extensive than the gcc back end |
| inlining, but that is no longer the case. |
| |
| @item -gnato?? |
| @cindex @option{-gnato??} (@command{gcc}) |
| Set default mode for handling generation of code to avoid intermediate |
| arithmetic overflow. Here `@code{??}' is two digits, a |
| single digit, or nothing. Each digit is one of the digits `@code{1}' |
| through `@code{3}': |
| |
| @itemize @bullet |
| @item @code{1}: |
| all intermediate overflows checked against base type (@code{STRICT}) |
| @item @code{2}: |
| minimize intermediate overflows (@code{MINIMIZED}) |
| @item @code{3}: |
| eliminate intermediate overflows (@code{ELIMINATED}) |
| @end itemize |
| |
| If only one digit appears then it applies to all |
| cases; if two digits are given, then the first applies outside |
| assertions, and the second within assertions. |
| |
| If no digits follow the @option{-gnato}, then it is equivalent to |
| @option{-gnato11}, |
| causing all intermediate overflows to be handled in strict mode. |
| |
| This switch also causes arithmetic overflow checking to be performed |
| (as though pragma @code{Unsuppress (Overflow_Mode)} has been specified. |
| |
| The default if no option @option{-gnato} is given is that overflow handling |
| is in @code{STRICT} mode (computations done using the base type), and that |
| overflow checking is suppressed. |
| |
| Note that division by zero is a separate check that is not |
| controlled by this switch (division by zero checking is on by default). |
| |
| See also @ref{Specifying the Desired Mode}. |
| |
| @item -gnatp |
| @cindex @option{-gnatp} (@command{gcc}) |
| Suppress all checks. See @ref{Run-Time Checks} for details. This switch |
| has no effect if cancelled by a subsequent @option{-gnat-p} switch. |
| |
| @item -gnat-p |
| @cindex @option{-gnat-p} (@command{gcc}) |
| Cancel effect of previous @option{-gnatp} switch. |
| |
| @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. |
| @xref{Pragma Polling,,, gnat_rm, 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 |
| @cindex @option{-gnatr} (@command{gcc}) |
| Treat pragma Restrictions as Restriction_Warnings. |
| |
| @item ^-gnatR@r{[}0@r{/}1@r{/}2@r{/}3@r{[}s@r{]]}^/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 (@pxref{Validity Checking}). |
| |
| @item ^-gnatw@var{xxx}^/WARNINGS=(@var{option}@r{[},@dots{}@r{]})^ |
| @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 -gnatX |
| @cindex @option{-gnatX} (@command{gcc}) |
| Enable GNAT implementation extensions and latest Ada version. |
| |
| @item ^-gnaty^/STYLE_CHECKS=(option,option@dots{})^ |
| @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 |
| @c @item -O@ovar{n} |
| @c Expanding @ovar macro inline (explanation in macro def comments) |
| @item -O@r{[}@var{n}@r{]} |
| @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. |
| |
| @item n = 3 |
| Same as @option{-O2}, and also includes inline expansion for small subprograms |
| in the same unit. |
| |
| @item n = s |
| Optimize space usage |
| @end table |
| |
| @noindent |
| See also @ref{Optimization Levels}. |
| @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{/OPTIMIZE} |
| qualifier. |
| |
| @item /OPTIMIZE@r{[}=(keyword@r{[},@dots{}@r{]})@r{]} |
| @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{/OPTIMIZE} 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 INLINING |
| Full optimization as in @option{/OPTIMIZE=ALL}, and also attempts |
| automatic inlining of small subprograms within a unit |
| |
| @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. |
| |
| @item SPACE |
| Optimize space usage |
| @end table |
| |
| @noindent |
| See also @ref{Optimization Levels}. |
| @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{/DISTRIBUTION_STUBS=},^ |
| @option{-gnatzc} and @option{-gnatzr} may not be combined with any other |
| switches, and only one of them may appear in the command line. |
| |
| @item |
| The switch @option{-gnat-p} may not be combined with any other switch. |
| |
| @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 (@pxref{Validity Checking}). |
| |
| @item |
| Option ``em'', ``ec'', ``ep'', ``l='' and ``R'' must be the last options in |
| a combined list of options. |
| @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. |
| @ifclear vms |
| @code{GPS} can parse the error messages |
| and point to the referenced character. |
| @end ifclear |
| 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. In the case where a body is |
| compiled, the corresponding spec is also listed, along |
| with any subunits. Typical output from compiling a package |
| body @file{p.adb} might look like: |
| |
| @smallexample @c ada |
| @cartouche |
| Compiling: p.adb |
| |
| 1. package body p is |
| 2. procedure a; |
| 3. procedure a is separate; |
| 4. begin |
| 5. null |
| | |
| >>> missing ";" |
| |
| 6. end; |
| |
| Compiling: p.ads |
| |
| 1. package p is |
| 2. pragma Elaborate_Body |
| | |
| >>> missing ";" |
| |
| 3. end p; |
| |
| Compiling: p-a.adb |
| |
| 1. separate p |
| | |
| >>> missing "(" |
| |
| 2. procedure a is |
| 3. begin |
| 4. null |
| | |
| >>> missing ";" |
| |
| 5. end; |
| @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 ^-gnatl^/OUTPUT_FILE^=file |
| @cindex @option{^-gnatl^/OUTPUT_FILE^=fname} (@command{gcc}) |
| This has the same effect as @option{-gnatl} except that the output is |
| written to a file instead of to standard output. If the given name |
| @file{fname} does not start with a period, then it is the full name |
| of the file to be written. If @file{fname} is an extension, it is |
| appended to the name of the file being compiled. For example, if |
| file @file{xyz.adb} is compiled with @option{^-gnatl^/OUTPUT_FILE^=.lst}, |
| then the output is written to file ^xyz.adb.lst^xyz.adb_lst^. |
| |
| @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 999999 and limits the number of error or warning |
| 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 number of errors detected |
| compilation abandoned |
| @end smallexample |
| |
| @noindent |
| The default setting if |
| no switch is given is 9999. If the number of warnings reaches this |
| limit, then a message is output and further warnings are suppressed, |
| but the compilation is continued. If the number of error messages |
| reaches this limit, then a message is output and the compilation |
| is abandoned. A value of zero means that no limit applies. |
| |
| @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 |
| Details on possibly non-portable unchecked conversion |
| @item |
| List possible interpretations for ambiguous calls |
| @item |
| Additional details on incorrect parameters |
| @end itemize |
| |
| @item -gnatjnn |
| @cindex @option{-gnatjnn} (@command{gcc}) |
| In normal operation mode (or if @option{-gnatj0} is used, then error messages |
| with continuation lines are treated as though the continuation lines were |
| separate messages (and so a warning with two continuation lines counts as |
| three warnings, and is listed as three separate messages). |
| |
| If the @option{-gnatjnn} switch is used with a positive value for nn, then |
| messages are output in a different manner. A message and all its continuation |
| lines are treated as a unit, and count as only one warning or message in the |
| statistics totals. Furthermore, the message is reformatted so that no line |
| is longer than nn characters. |
| |
| @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 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 |
| Assertions (pragma Assert) that are sure to fail |
| |
| @item |
| Unreachable code |
| |
| @item |
| Address clauses with possibly unaligned values, or where an attempt is |
| made to overlay a smaller variable with a larger one. |
| |
| @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 section lists compiler switches that are available |
| to control the handling of warning messages. It is also possible |
| to exercise much finer control over what warnings are issued and |
| suppressed using the GNAT pragma Warnings, @xref{Pragma Warnings,,, |
| gnat_rm, GNAT Reference manual}. |
| |
| @table @option |
| @c !sort! |
| @item -gnatwa |
| @emph{Activate most optional warnings.} |
| @cindex @option{-gnatwa} (@command{gcc}) |
| This switch activates most optional warning messages. See the 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), |
| @ifclear vms |
| @option{-gnatw.d} (tag warnings with -gnatw switch) |
| @end ifclear |
| @option{-gnatw.h} (holes (gaps) in record layouts) |
| @option{-gnatw.i} (overlapping actuals), |
| @option{-gnatw.k} (redefinition of names in standard), |
| @option{-gnatwl} (elaboration warnings), |
| @option{-gnatw.l} (inherited aspects), |
| @option{-gnatw.o} (warn on values set by out parameters ignored), |
| @option{-gnatwt} (tracking of deleted conditional code) |
| and @option{-gnatw.u} (unordered enumeration), |
| 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. Note that unlike switch @option{-gnatws}, the |
| use of switch @option{-gnatwA} does not suppress warnings that are |
| normally given unconditionally and cannot be individually controlled |
| (for example, the warning about a missing exit path in a function). |
| Also, again unlike switch @option{-gnatws}, warnings suppressed by |
| the use of switch @option{-gnatwA} can be individually turned back |
| on. For example the use of switch @option{-gnatwA} followed by |
| switch @option{-gnatwd} will suppress all optional warnings except |
| the warnings for implicit dereferencing. |
| |
| @item -gnatw.a |
| @emph{Activate warnings on failing assertions.} |
| @cindex @option{-gnatw.a} (@command{gcc}) |
| @cindex Assert failures |
| This switch activates warnings for assertions where the compiler can tell at |
| compile time that the assertion will fail. Note that this warning is given |
| even if assertions are disabled. The default is that such warnings are |
| generated. |
| |
| @item -gnatw.A |
| @emph{Suppress warnings on failing assertions.} |
| @cindex @option{-gnatw.A} (@command{gcc}) |
| @cindex Assert failures |
| This switch suppresses warnings for assertions where the compiler can tell at |
| compile time that the assertion will fail. |
| |
| @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 -gnatw.b |
| @emph{Activate warnings on biased representation.} |
| @cindex @option{-gnatw.b} (@command{gcc}) |
| @cindex Biased representation |
| This switch activates warnings when a size clause, value size clause, component |
| clause, or component size clause forces the use of biased representation for an |
| integer type (e.g. representing a range of 10..11 in a single bit by using 0/1 |
| to represent 10/11). The default is that such warnings are generated. |
| |
| @item -gnatw.B |
| @emph{Suppress warnings on biased representation.} |
| @cindex @option{-gnatwB} (@command{gcc}) |
| This switch suppresses warnings for representation clauses that force the use |
| of biased representation. |
| |
| @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 option also generates warnings if |
| one or both tests is optimized away in a membership test for integer |
| values if the result can be determined at compile time. Range tests on |
| enumeration types are not included, since it is common for such tests |
| to include an end point. |
| |
| 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 -gnatw.c |
| @emph{Activate warnings on missing component clauses.} |
| @cindex @option{-gnatw.c} (@command{gcc}) |
| @cindex Component clause, missing |
| This switch activates warnings for record components where a record |
| representation clause is present and has component clauses for the |
| majority, but not all, of the components. A warning is given for each |
| component for which no component clause is present. |
| |
| This warning can also be turned on using @option{-gnatwa}. |
| |
| @item -gnatw.C |
| @emph{Suppress warnings on missing component clauses.} |
| @cindex @option{-gnatwC} (@command{gcc}) |
| This switch suppresses warnings for record components that are |
| missing a component clause in the situation described above. |
| |
| @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. |
| |
| @ifclear vms |
| @item -gnatw.d |
| @emph{Activate tagging of warning messages.} |
| @cindex @option{-gnatw.d} (@command{gcc}) |
| If this switch is set, then warning messages are tagged, either with |
| the string ``@option{-gnatw?}'' showing which switch controls the warning, |
| or with ``[enabled by default]'' if the warning is not under control of a |
| specific @option{-gnatw?} switch. This mode is off by default, and is not |
| affected by the use of @code{-gnatwa}. |
| |
| @item -gnatw.D |
| @emph{Deactivate tagging of warning messages.} |
| @cindex @option{-gnatw.d} (@command{gcc}) |
| If this switch is set, then warning messages return to the default |
| mode in which warnings are not tagged as described above for |
| @code{-gnatw.d}. |
| @end ifclear |
| |
| @item -gnatwe |
| @emph{Treat warnings and style checks as errors.} |
| @cindex @option{-gnatwe} (@command{gcc}) |
| @cindex Warnings, treat as error |
| This switch causes warning messages and style check 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. Note that this |
| is the only -gnatw switch that affects the handling of style check messages. |
| |
| @item -gnatw.e |
| @emph{Activate every optional warning} |
| @cindex @option{-gnatw.e} (@command{gcc}) |
| @cindex Warnings, activate every optional warning |
| This switch activates all optional warnings, including those which |
| are not activated by @code{-gnatwa}. The use of this switch is not |
| recommended for normal use. If you turn this switch on, it is almost |
| certain that you will get large numbers of useless warnings. The |
| warnings that are excluded from @code{-gnatwa} are typically highly |
| specialized warnings that are suitable for use only in code that has |
| been specifically designed according to specialized coding rules. |
| |
| @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}. The |
| default is that these warnings are not generated. |
| |
| @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 -gnatw.h |
| @emph{Activate warnings on holes/gaps in records.} |
| @cindex @option{-gnatw.h} (@command{gcc}) |
| @cindex Record Representation (gaps) |
| This switch activates warnings on component clauses in record |
| representation clauses that leave holes (gaps) in the record layout. |
| If this warning option is active, then record representation clauses |
| should specify a contiguous layout, adding unused fill fields if needed. |
| Note that @option{-gnatwa} does not affect the setting of this warning option. |
| |
| @item -gnatw.H |
| @emph{Suppress warnings on holes/gaps in records.} |
| @cindex @option{-gnatw.H} (@command{gcc}) |
| This switch suppresses warnings on component clauses in record |
| representation clauses that leave holes (haps) in the record layout. |
| |
| @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 -gnatw.i |
| @emph{Activate warnings on overlapping actuals.} |
| @cindex @option{-gnatw.i} (@command{gcc}) |
| This switch enables a warning on statically detectable overlapping actuals in |
| a subprogram call, when one of the actuals is an in-out parameter, and the |
| types of the actuals are not by-copy types. The warning is off by default, |
| and is not included under -gnatwa. |
| |
| @item -gnatw.I |
| @emph{Disable warnings on overlapping actuals.} |
| @cindex @option{-gnatw.I} (@command{gcc}) |
| This switch disables warnings on overlapping actuals in a call.. |
| |
| @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. This warning is also turned on by |
| the use of @option{-gnatwa}. |
| |
| 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)}, and |
| @code{pragma Interface_Name} will be flagged since its function |
| is replaced by @code{pragma Import}. |
| |
| 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. The default is that |
| such warnings are not given. |
| This warning can also be turned on using @option{-gnatwa}. |
| |
| @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 -gnatw.k |
| @emph{Activate warnings on redefinition of names in standard.} |
| @cindex @option{-gnatw.k} (@command{gcc}) |
| This switch activates warnings for declarations that declare a name that |
| is defined in package Standard. Such declarations can be confusing, |
| especially since the names in package Standard continue to be directly |
| visible, meaning that use visibiliy on such redeclared names does not |
| work as expected. Names of discriminants and components in records are |
| not included in this check. |
| This warning is not part of the warnings activated by @option{-gnatwa}. |
| It must be explicitly activated. |
| |
| @item -gnatw.K |
| @emph{Suppress warnings on variables that could be constants.} |
| @cindex @option{-gnatwK} (@command{gcc}) |
| This switch activates warnings for declarations that declare a name that |
| is defined in package Standard. |
| |
| @item -gnatwl |
| @emph{Activate warnings for 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. In dynamic elaboration mode, this switch |
| generations warnings about the need to add elaboration pragmas. Note however, |
| that if you blindly follow these warnings, and add @code{Elaborate_All} |
| warnings wherever they are recommended, you basically end up with the |
| equivalent of the static elaboration model, which may not be what you want for |
| legacy code for which the static model does not work. |
| |
| For the static model, the messages generated are labeled "info:" (for |
| information messages). They are not warnings to add elaboration pragmas, |
| merely informational messages showing what implicit elaboration pragmas |
| have been added, for use in analyzing elaboration circularity problems. |
| |
| 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 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 -gnatw.l |
| @emph{List inherited aspects.} |
| @cindex @option{-gnatw.l} (@command{gcc}) |
| This switch causes the compiler to list inherited invariants, |
| preconditions, and postconditions from Type_Invariant'Class, Invariant'Class, |
| Pre'Class, and Post'Class aspects. Also list inherited subtype predicates. |
| These messages are not automatically turned on by the use of @option{-gnatwa}. |
| |
| @item -gnatw.L |
| @emph{Suppress listing of inherited aspects.} |
| @cindex @option{-gnatw.L} (@command{gcc}) |
| This switch suppresses listing of inherited aspects. |
| |
| @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}. |
| The default is that these warnings are not given. |
| |
| @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 -gnatw.m |
| @emph{Activate warnings on suspicious modulus values.} |
| @cindex @option{-gnatw.m} (@command{gcc}) |
| This switch activates warnings for modulus values that seem suspicious. |
| The cases caught are where the size is the same as the modulus (e.g. |
| a modulus of 7 with a size of 7 bits), and modulus values of 32 or 64 |
| with no size clause. The guess in both cases is that 2**x was intended |
| rather than x. In addition expressions of the form 2*x for small x |
| generate a warning (the almost certainly accurate guess being that |
| 2**x was intended). The default is that these warnings are given. |
| |
| @item -gnatw.M |
| @emph{Disable warnings on suspicious modulus values.} |
| @cindex @option{-gnatw.M} (@command{gcc}) |
| This switch disables warnings for suspicious modulus values. |
| |
| @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 -gnatw.o |
| @emph{Activate warnings on modified but unreferenced out parameters.} |
| @cindex @option{-gnatw.o} (@command{gcc}) |
| This switch activates warnings for variables that are modified by using |
| them as actuals for a call to a procedure with an out mode formal, where |
| the resulting assigned value is never read. It is applicable in the case |
| where there is more than one out mode formal. If there is only one out |
| mode formal, the warning is issued by default (controlled by -gnatwu). |
| 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. |
| The default is that these warnings are not given. Note that this warning |
| is not included in -gnatwa, it must be activated explicitly. |
| |
| @item -gnatw.O |
| @emph{Disable warnings on modified but unreferenced out parameters.} |
| @cindex @option{-gnatw.O} (@command{gcc}) |
| This switch suppresses warnings for variables that are modified by using |
| them as actuals for a call to a procedure with an out mode formal, where |
| the resulting assigned value is never read. |
| |
| @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. The default is |
| that such warnings are not given. |
| This warning can also be turned on using @option{-gnatwa}. |
| Warnings on ineffective inlining by the gcc back-end can be activated |
| separately, using the gcc switch -Winline. |
| |
| @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 -gnatw.p |
| @emph{Activate warnings on parameter ordering.} |
| @cindex @option{-gnatw.p} (@command{gcc}) |
| @cindex Parameter order, warnings |
| This switch activates warnings for cases of suspicious parameter |
| ordering when the list of arguments are all simple identifiers that |
| match the names of the formals, but are in a different order. The |
| warning is suppressed if any use of named parameter notation is used, |
| so this is the appropriate way to suppress a false positive (and |
| serves to emphasize that the "misordering" is deliberate). The |
| default is |
| that such warnings are not given. |
| This warning can also be turned on using @option{-gnatwa}. |
| |
| @item -gnatw.P |
| @emph{Suppress warnings on parameter ordering.} |
| @cindex @option{-gnatw.P} (@command{gcc}) |
| This switch suppresses warnings on cases of suspicious parameter |
| ordering. |
| |
| @item -gnatwq |
| @emph{Activate warnings on questionable missing parentheses.} |
| @cindex @option{-gnatwq} (@command{gcc}) |
| @cindex Parentheses, warnings |
| This switch activates warnings for cases where parentheses are not used and |
| the result is potential ambiguity from a readers point of view. For example |
| (not a > b) when a and b are modular means ((not a) > b) and very likely the |
| programmer intended (not (a > b)). Similarly (-x mod 5) means (-(x mod 5)) and |
| quite likely ((-x) mod 5) was intended. In such situations it seems best to |
| follow the rule of always parenthesizing to make the association clear, and |
| this warning switch warns if such parentheses are not present. The default |
| is that these warnings are given. |
| This warning can also be turned on using @option{-gnatwa}. |
| |
| @item -gnatwQ |
| @emph{Suppress warnings on questionable missing parentheses.} |
| @cindex @option{-gnatwQ} (@command{gcc}) |
| This switch suppresses warnings for cases where the association is not |
| clear and the use of parentheses is preferred. |
| |
| @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: |
| |
| @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 |
| |
| This warning can also be turned on using @option{-gnatwa}. |
| The default is that warnings for redundant constructs are not given. |
| |
| @item -gnatwR |
| @emph{Suppress warnings on redundant constructs.} |
| @cindex @option{-gnatwR} (@command{gcc}) |
| This switch suppresses warnings for redundant constructs. |
| |
| @item -gnatw.r |
| @emph{Activate warnings for object renaming function.} |
| @cindex @option{-gnatw.r} (@command{gcc}) |
| This switch activates warnings for an object renaming that renames a |
| function call, which is equivalent to a constant declaration (as |
| opposed to renaming the function itself). The default is that these |
| warnings are given. This warning can also be turned on using |
| @option{-gnatwa}. |
| |
| @item -gnatw.R |
| @emph{Suppress warnings for object renaming function.} |
| @cindex @option{-gnatwT} (@command{gcc}) |
| This switch suppresses warnings for object renaming function. |
| |
| @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, including |
| both warnings that can be controlled by switches described in this |
| section, and those that are normally given unconditionally. The |
| effect of this suppress action can only be cancelled by a subsequent |
| use of the switch @option{-gnatwn}. |
| |
| Note that switch @option{-gnatws} 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}. Also this switch has no effect on the |
| handling of style check messages. |
| |
| @item -gnatw.s |
| @emph{Activate warnings on overridden size clauses.} |
| @cindex @option{-gnatw.s} (@command{gcc}) |
| @cindex Record Representation (component sizes) |
| This switch activates warnings on component clauses in record |
| representation clauses where the length given overrides that |
| specified by an explicit size clause for the component type. A |
| warning is similarly given in the array case if a specified |
| component size overrides an explicit size clause for the array |
| component type. |
| Note that @option{-gnatwa} does not affect the setting of this warning option. |
| |
| @item -gnatw.S |
| @emph{Suppress warnings on overridden size clauses.} |
| @cindex @option{-gnatw.S} (@command{gcc}) |
| This switch suppresses warnings on component clauses in record |
| representation clauses that override size clauses, and similar |
| warnings when an array component size overrides a size clause. |
| |
| @item -gnatwt |
| @emph{Activate warnings for tracking of deleted conditional code.} |
| @cindex @option{-gnatwt} (@command{gcc}) |
| @cindex Deactivated code, warnings |
| @cindex Deleted code, warnings |
| This switch activates warnings for tracking of code in conditionals (IF and |
| CASE statements) that is detected to be dead code which cannot be executed, and |
| which is removed by the front end. This warning is off by default, and is not |
| turned on by @option{-gnatwa}, it has to be turned on explicitly. This may be |
| useful for detecting deactivated code in certified applications. |
| |
| @item -gnatwT |
| @emph{Suppress warnings for tracking of deleted conditional code.} |
| @cindex @option{-gnatwT} (@command{gcc}) |
| This switch suppresses warnings for tracking of deleted conditional code. |
| |
| @item -gnatw.t |
| @emph{Activate warnings on suspicious contracts.} |
| @cindex @option{-gnatw.t} (@command{gcc}) |
| This switch activates warnings on suspicious postconditions (whether a |
| pragma @code{Postcondition} or a @code{Post} aspect in Ada 2012) |
| and suspicious contract cases (pragma @code{Contract_Case}). A |
| function postcondition or contract case is suspicious when no postcondition |
| or contract case for this function mentions the result of the function. |
| A procedure postcondition or contract case is suspicious when it only |
| refers to the pre-state of the procedure, because in that case it should |
| rather be expressed as a precondition. The default is that such warnings |
| are not generated. This warning can also be turned on using @option{-gnatwa}. |
| |
| @item -gnatw.T |
| @emph{Suppress warnings on suspicious contracts.} |
| @cindex @option{-gnatw.T} (@command{gcc}) |
| This switch suppresses warnings on suspicious postconditions. |
| |
| @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 a with'ed |
| 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 -gnatw.u |
| @emph{Activate warnings on unordered enumeration types.} |
| @cindex @option{-gnatw.u} (@command{gcc}) |
| This switch causes enumeration types to be considered as conceptually |
| unordered, unless an explicit pragma @code{Ordered} is given for the type. |
| The effect is to generate warnings in clients that use explicit comparisons |
| or subranges, since these constructs both treat objects of the type as |
| ordered. (A @emph{client} is defined as a unit that is other than the unit in |
| which the type is declared, or its body or subunits.) Please refer to |
| the description of pragma @code{Ordered} in the |
| @cite{@value{EDITION} Reference Manual} for further details. |
| The default is that such warnings are not generated. |
| This warning is not automatically turned on by the use of @option{-gnatwa}. |
| |
| @item -gnatw.U |
| @emph{Deactivate warnings on unordered enumeration types.} |
| @cindex @option{-gnatw.U} (@command{gcc}) |
| This switch causes all enumeration types to be considered as ordered, so |
| that no warnings are given for comparisons or subranges for any type. |
| |
| @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. |
| This warning can also be turned on using @option{-gnatwa}. |
| |
| @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. |
| For variables of a composite type, the warning can also be suppressed in |
| Ada 2005 by using a default initialization with a box. For example, if |
| Table is an array of records whose components are only partially uninitialized, |
| then the following code: |
| |
| @smallexample @c ada |
| Tab : Table := (others => <>); |
| @end smallexample |
| |
| will suppress warnings on subsequent statements that access components |
| of variable Tab. |
| |
| @item -gnatw.v |
| @emph{Activate info messages for non-default bit order.} |
| @cindex @option{-gnatw.v} (@command{gcc}) |
| @cindex bit order warnings |
| This switch activates messages (labeled "info", they are not warnings, |
| just informational messages) about the effects of non-default bit-order |
| on records to which a component clause is applied. The effect of specifying |
| non-default bit ordering is a bit subtle (and changed with Ada 2005), so |
| these messages, which are given by default, are useful in understanding the |
| exact consequences of using this feature. These messages |
| can also be turned on using @option{-gnatwa} |
| |
| @item -gnatw.V |
| @emph{Suppress info messages for non-default bit order.} |
| @cindex @option{-gnatw.V} (@command{gcc}) |
| This switch suppresses information messages for the effects of specifying |
| non-default bit order on record components with component clauses. |
| |
| @item -gnatww |
| @emph{Activate warnings on wrong low bound assumption.} |
| @cindex @option{-gnatww} (@command{gcc}) |
| @cindex String indexing warnings |
| This switch activates warnings for indexing an unconstrained string parameter |
| with a literal or S'Length. This is a case where the code is assuming that the |
| low bound is one, which is in general not true (for example when a slice is |
| passed). The default is that such warnings are generated. |
| This warning can also be turned on using @option{-gnatwa}. |
| |
| @item -gnatwW |
| @emph{Suppress warnings on wrong low bound assumption.} |
| @cindex @option{-gnatwW} (@command{gcc}) |
| This switch suppresses warnings for indexing an unconstrained string parameter |
| with a literal or S'Length. Note that this warning can also be suppressed |
| in a particular case by adding an |
| assertion that the lower bound is 1, |
| as shown in the following example. |
| |
| @smallexample @c ada |
| procedure K (S : String) is |
| pragma Assert (S'First = 1); |
| @dots{} |
| @end smallexample |
| |
| @item -gnatw.w |
| @emph{Activate warnings on unnecessary Warnings Off pragmas} |
| @cindex @option{-gnatw.w} (@command{gcc}) |
| @cindex Warnings Off control |
| This switch activates warnings for use of @code{pragma Warnings (Off, entity)} |
| where either the pragma is entirely useless (because it suppresses no |
| warnings), or it could be replaced by @code{pragma Unreferenced} or |
| @code{pragma Unmodified}. The default is that these warnings are not given. |
| Note that this warning is not included in -gnatwa, it must be |
| activated explicitly. |
| |
| @item -gnatw.W |
| @emph{Suppress warnings on unnecessary Warnings Off pragmas} |
| @cindex @option{-gnatw.W} (@command{gcc}) |
| This switch suppresses warnings for use of @code{pragma Warnings (Off, entity)}. |
| |
| @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. |
| This warning can also be turned on using @option{-gnatwa}. |
| |
| @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 -gnatw.x |
| @emph{Activate warnings for No_Exception_Propagation mode.} |
| @cindex @option{-gnatwm} (@command{gcc}) |
| This switch activates warnings for exception usage when pragma Restrictions |
| (No_Exception_Propagation) is in effect. Warnings are given for implicit or |
| explicit exception raises which are not covered by a local handler, and for |
| exception handlers which do not cover a local raise. The default is that these |
| warnings are not given. |
| |
| @item -gnatw.X |
| @emph{Disable warnings for No_Exception_Propagation mode.} |
| This switch disables warnings for exception usage when pragma Restrictions |
| (No_Exception_Propagation) is in effect. |
| |
| @item -gnatwy |
| @emph{Activate warnings for Ada compatibility issues.} |
| @cindex @option{-gnatwy} (@command{gcc}) |
| @cindex Ada compatibility issues warnings |
| For the most part, newer versions of Ada are upwards compatible |
| with older versions. For example, Ada 2005 programs will almost |
| always work when compiled as Ada 2012. |
| However there are some exceptions (for example the fact that |
| @code{some} is now a reserved word in Ada 2012). 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. |
| This warning can also be turned on using @option{-gnatwa}. |
| |
| @item -gnatwY |
| @emph{Disable warnings for Ada compatibility issues.} |
| @cindex @option{-gnatwY} (@command{gcc}) |
| @cindex Ada compatibility issues warnings |
| This switch suppresses the warnings intended to help in identifying |
| incompatibilities between Ada language versions. |
| |
| @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. Warnings are also |
| generated for subprogram pointers with different conventions, |
| and, on VMS only, for data pointers with different conventions. |
| This warning can also be turned on using @option{-gnatwa}. |
| |
| @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 or conventions. |
| |
| @item ^-Wunused^WARNINGS=UNUSED^ |
| @cindex @option{-Wunused} |
| The warnings controlled by the @option{-gnatw} switch are generated by |
| the front end of the compiler. The @option{GCC} back end can provide |
| additional warnings and they are controlled by the @option{-W} switch. |
| For example, @option{^-Wunused^WARNINGS=UNUSED^} activates back end |
| warnings for entities that are declared but not referenced. |
| |
| @item ^-Wuninitialized^WARNINGS=UNINITIALIZED^ |
| @cindex @option{-Wuninitialized} |
| Similarly, @option{^-Wuninitialized^WARNINGS=UNINITIALIZED^} activates |
| the back end warning for uninitialized variables. This switch must be |
| used in conjunction with an optimization level greater than zero. |
| |
| @item -Wstack-usage=@var{len} |
| @cindex @option{-Wstack-usage} |
| Warn if the stack usage of a subprogram might be larger than @var{len} bytes. |
| See @ref{Static Stack Usage Analysis} for details. |
| |
| @item ^-Wall^/ALL_BACK_END_WARNINGS^ |
| @cindex @option{-Wall} |
| This switch enables most warnings from the @option{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 activate them. |
| The use of this switch also sets the default front end warning mode to |
| @option{-gnatwa}, that is, most front end warnings activated as well. |
| |
| @item ^-w^/NO_BACK_END_WARNINGS^ |
| @cindex @option{-w} |
| Conversely, this switch suppresses warnings from the @option{GCC} back end. |
| 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 |
| -gnatwaGe |
| @end smallexample |
| |
| @noindent |
| will turn on all optional warnings except for unrecognized 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 -gnatw.a |
| @item -gnatwB |
| @item -gnatw.b |
| @item -gnatwC |
| @item -gnatw.C |
| @item -gnatwD |
| @item -gnatwF |
| @item -gnatwg |
| @item -gnatwH |
| @item -gnatwi |
| @item -gnatw.I |
| @item -gnatwJ |
| @item -gnatwK |
| @item -gnatwL |
| @item -gnatw.L |
| @item -gnatwM |
| @item -gnatw.m |
| @item -gnatwn |
| @item -gnatwo |
| @item -gnatw.O |
| @item -gnatwP |
| @item -gnatw.P |
| @item -gnatwq |
| @item -gnatwR |
| @item -gnatw.R |
| @item -gnatw.S |
| @item -gnatwT |
| @item -gnatw.T |
| @item -gnatwU |
| @item -gnatwv |
| @item -gnatww |
| @item -gnatw.W |
| @item -gnatwx |
| @item -gnatw.X |
| @item -gnatwy |
| @item -gnatwz |
| |
| @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} @r{[}, |
| @var{static-string-expression}@r{]}) |
| @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@r{[}=debug-level@r{]} |
| @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 Reference Manual defines the concept of invalid values (see |
| RM 13.9.1). The primary source of invalid values is uninitialized |
| variables. A scalar variable that is left uninitialized may contain |
| an invalid value; the concept of invalid does not apply to access or |
| composite types. |
| |
| It is an error to read an invalid value, but the RM does not require |
| run-time checks to detect such errors, except for some minimal |
| checking to prevent erroneous execution (i.e. unpredictable |
| behavior). This corresponds to the @option{-gnatVd} switch below, |
| which is the default. For example, by default, if the expression of a |
| case statement is invalid, it will raise Constraint_Error rather than |
| causing a wild jump, and if an array index on the left-hand side of an |
| assignment is invalid, it will raise Constraint_Error rather than |
| overwriting an arbitrary memory location. |
| |
| The @option{-gnatVa} may be used to enable additional validity checks, |
| which are not required by the RM. These checks are often very |
| expensive (which is why the RM does not require them). These checks |
| are useful in tracking down uninitialized variables, but they are |
| not usually recommended for production builds. |
| |
| The other @option{-gnatV^@var{x}^^} switches below allow finer-grained |
| control; you can enable whichever validity checks you desire. However, |
| for most debugging purposes, @option{-gnatVa} is sufficient, and the |
| default @option{-gnatVd} (i.e. standard Ada behavior) is usually |
| sufficient for non-debugging use. |
| |
| The @option{-gnatB} switch tells the compiler to assume that all |
| values are valid (that is, within their declared subtype range) |
| except in the context of a use of the Valid attribute. This means |
| the compiler can generate more efficient code, since the range |
| of values is better known at compile time. However, an uninitialized |
| variable can cause wild jumps and memory corruption in this mode. |
| |
| The @option{-gnatV^@var{x}^^} switch allows control over the validity |
| checking mode as described below. |
| @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 required by Ada as 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 required by Ada as 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 -gnatVe |
| @emph{Validity checks for elementary components.} |
| @cindex @option{-gnatVe} (@command{gcc}) |
| In the absence of this switch, assignments to record or array components are |
| not validity checked, even if validity checks for assignments generally |
| (@option{-gnatVc}) are turned on. In Ada, assignment of composite values do not |
| require valid data, but assignment of individual components does. So for |
| example, there is a difference between copying the elements of an array with a |
| slice assignment, compared to assigning element by element in a loop. This |
| switch allows you to turn off validity checking for components, even when they |
| are assigned component by component. |
| |
| @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 NaNs and infinities are considered invalid, |
| as well as out of range values for constrained types. Note that this means |
| that standard 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. Checks are |
| also made on explicit ranges using @samp{..} (e.g.@: slices, loops etc). |
| |
| @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,@dots{})^} 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 message is given, preceded by |
| the character sequence ``(style)''. This message does not prevent |
| successful compilation (unless the @option{-gnatwe} switch is used). |
| |
| Note that this is by no means intended to be a general facility for |
| checking arbitrary coding standards. It is simply an embedding of the |
| style rules we have chosen for the GNAT sources. If you are starting |
| a project which does not have established style standards, you may |
| find it useful to adopt the entire set of GNAT coding standards, or |
| some subset of them. If you already have an established set of coding |
| standards, then it may be that selected style checking options do |
| indeed correspond to choices you have made, but for general checking |
| of an existing set of coding rules, you should look to the gnatcheck |
| tool, which is designed for that purpose. |
| |
| @ifset vms |
| @code{(option,option,@dots{})} 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 0-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. A value of zero turns off this style check. |
| 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, or they may be aligned the same way as the following |
| non-blank line (this is useful when full line comments appear in the middle |
| of a statement. |
| |
| @item ^a^ATTRIBUTE^ |
| @emph{Check attribute casing.} |
| 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 ^A^ARRAY_INDEXES^ |
| @emph{Use of array index numbers in array attributes.} |
| When using the array attributes First, Last, Range, |
| or Length, the index number must be omitted for one-dimensional arrays |
| and is required for multi-dimensional arrays. |
| |
| @item ^b^BLANKS^ |
| @emph{Blanks not allowed at statement end.} |
| 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 ^B^BOOLEAN_OPERATORS^ |
| @emph{Check Boolean operators.} |
| The use of AND/OR operators is not permitted except in the cases of modular |
| operands, array operands, and simple stand-alone boolean variables or |
| boolean constants. In all other cases @code{and then}/@code{or else} are |
| required. |
| |
| @item ^c^COMMENTS^ |
| @emph{Check comments, double space.} |
| 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 at least 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#@dots{}16#2F#} or @code{16#3A#@dots{}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 ^C^COMMENTS1^ |
| @emph{Check comments, single space.} |
| This is identical to @code{^c^COMMENTS^} except that only one space |
| is required following the @code{--} of a comment instead of two. |
| |
| @item ^d^DOS_LINE_ENDINGS^ |
| @emph{Check no DOS line terminators present.} |
| 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.} |
| 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.} |
| Neither form feeds nor vertical tab characters are permitted |
| in the source text. |
| |
| @item ^g^GNAT^ |
| @emph{GNAT style mode.} |
| The set of style check switches is set to match that used by the GNAT sources. |
| This may be useful when developing code that is eventually intended to be |
| incorporated into GNAT. For further details, see GNAT sources. |
| |
| @item ^h^HTABS^ |
| @emph{No horizontal tabs.} |
| 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.} |
| 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.} |
| 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.} |
| 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.} |
| 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}. |
| This is also permitted when the type declaration is split on two lines. |
| For example, any of the following three 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; |
| |
| 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.} |
| The maximum level of nesting of constructs (including subprograms, loops, |
| blocks, packages, and conditionals) may not exceed the given value |
| @option{nnn}. A value of zero disconnects this style check. |
| |
| @item ^m^LINE_LENGTH^ |
| @emph{Check maximum line length.} |
| 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 and 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.} |
| The length of lines must not exceed the |
| given value @option{nnn}. The maximum value that can be specified is 32767. |
| If neither style option for setting the line length is used, then the |
| default is 255. This also controls the maximum length of lexical elements, |
| where the only restriction is that they must fit on a single line. |
| |
| @item ^n^STANDARD_CASING^ |
| @emph{Check casing of entities in Standard.} |
| 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 ^N^NONE^ |
| @emph{Turn off all style checks.} |
| All style check options are turned off. |
| |
| @item ^o^ORDERED_SUBPROGRAMS^ |
| @emph{Check order of subprogram bodies.} |
| 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 ^O^OVERRIDING_INDICATORS^ |
| @emph{Check that overriding subprograms are explicitly marked as such.} |
| The declaration of a primitive operation of a type extension that overrides |
| an inherited operation must carry an overriding indicator. |
| |
| @item ^p^PRAGMA^ |
| @emph{Check pragma casing.} |
| 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.} |
| 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.} |
| 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 ^S^STATEMENTS_AFTER_THEN_ELSE^ |
| @emph{Check no statements after @code{then}/@code{else}.} |
| No statements are allowed |
| on the same line as a @code{then} or @code{else} keyword following the |
| keyword in an @code{if} statement. @code{or else} and @code{and then} are not |
| affected, and a special exception allows a pragma to appear after @code{else}. |
| |
| @item ^t^TOKEN^ |
| @emph{Check token spacing.} |
| The following token spacing rules are enforced: |
| |
| @itemize @bullet |
| |
| @item |
| The keywords @code{abs} and @code{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 |
| if the token following a right parenthesis starts 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 |
| Exactly one blank (and no other white space) must appear between |
| a @code{not} token and a following @code{in} token. |
| |
| @item ^u^UNNECESSARY_BLANK_LINES^ |
| @emph{Check unnecessary blank lines.} |
| Unnecessary blank lines are not allowed. 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.} |
| Unnecessary extra level of parentheses (C-style) are not allowed |
| around conditions in @code{if} statements, @code{while} statements and |
| @code{exit} statements. |
| |
| @item ^y^ALL_BUILTIN^ |
| @emph{Set all standard style check options} |
| This is equivalent to @code{gnaty3aAbcefhiklmnprst}, that is all checking |
| options enabled with the exception of @option{-gnatyB}, @option{-gnatyd}, |
| @option{-gnatyI}, @option{-gnatyLnnn}, @option{-gnatyo}, @option{-gnatyO}, |
| @option{-gnatyS}, @option{-gnatyu}, and @option{-gnatyx}. |
| |
| @ifclear vms |
| @item - |
| @emph{Remove style check options} |
| This causes any subsequent options in the string to act as canceling the |
| corresponding style check option. To cancel maximum nesting level control, |
| use @option{L} parameter witout any integer value after that, because any |
| digit following @option{-} in the parameter string of the @option{-gnaty} |
| option will be threated as canceling indentation check. The same is true |
| for @option{M} parameter. @option{y} and @option{N} parameters are not |
| allowed after @option{-}. |
| |
| @item + |
| This causes any subsequent options in the string to enable the corresponding |
| style check option. That is, it cancels the effect of a previous ^-^REMOVE^, |
| if any. |
| @end ifclear |
| |
| @ifset vms |
| @item NOxxx |
| @emph{Removing style check options} |
| If the name of a style check is preceded by @option{NO} then the corresponding |
| style check is turned off. For example @option{NOCOMMENTS} turns off style |
| checking for comments. |
| @end ifset |
| @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 the use of @option{-gnatyy} as described above, that is all |
| built-in standard style check options are enabled. |
| |
| @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 |
| |
| 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 |
| By default, the following checks are suppressed: integer overflow |
| checks, stack overflow checks, and checks for access before |
| elaboration on subprogram calls. All other checks, including range |
| checks and array bounds checks, are turned on 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 |
| This switch causes the unit to be compiled |
| as though @code{pragma Suppress (All_checks)} |
| had been present in the source. Validity checks are also eliminated (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. |
| |
| Note that when checks are suppressed, the compiler is allowed, but not |
| required, to omit the checking code. If the run-time cost of the |
| checking code is zero or near-zero, the compiler will generate it even |
| if checks are suppressed. In particular, if the compiler can prove |
| that a certain check will necessarily fail, it will generate code to |
| do an unconditional ``raise'', even if checks are suppressed. The |
| compiler warns in this case. Another case in which checks may not be |
| eliminated is when they are embedded in certain run time routines such |
| as math library routines. |
| |
| Of course, run-time checks are omitted whenever the compiler can prove |
| that they will not fail, whether or not checks are suppressed. |
| |
| Note that if you suppress a check that would have failed, program |
| execution is erroneous, which means the behavior is totally |
| unpredictable. The program might crash, or print wrong answers, or |
| do anything else. It might even do exactly what you wanted it to do |
| (and then it might start failing mysteriously next week or next |
| year). The compiler will generate code based on the assumption that |
| the condition being checked is true, which can result in disaster if |
| that assumption is wrong. |
| |
| The @option{-gnatp} switch has no effect if a subsequent |
| @option{-gnat-p} switch appears. |
| |
| @item -gnat-p |
| @cindex @option{-gnat-p} (@command{gcc}) |
| @cindex Suppressing checks |
| @cindex Checks, suppressing |
| @findex Suppress |
| This switch cancels the effect of a previous @option{gnatp} switch. |
| |
| @item -gnato?? |
| @cindex @option{-gnato??} (@command{gcc}) |
| @cindex Overflow checks |
| @cindex Overflow mode |
| @cindex Check, overflow |
| This switch controls the mode used for computing intermediate |
| arithmetic integer operations, and also enables overflow checking. |
| For a full description of overflow mode and checking control, see |
| the ``Overflow Check Handling in GNAT'' appendix in this |
| User's Guide. |
| |
| Overflow checks are always enabled by this switch. The argument |
| controls the mode, using the codes |
| |
| @itemize |
| @item 1 = STRICT |
| In STRICT mode, intermediate operations are always done using the |
| base type, and overflow checking ensures that the result is within |
| the base type range. |
| |
| @item 2 = MINIMIZED |
| In MINIMIZED mode, overflows in intermediate operations are avoided |
| where possible by using a larger integer type for the computation |
| (typically @code{Long_Long_Integer}). Overflow checking ensures that |
| the result fits in this larger integer type. |
| |
| @item 3 = ELIMINATED |
| In ELIMINATED mode, overflows in intermediate operations are avoided |
| by using multi-precision arithmetic. In this case, overflow checking |
| has no effect on intermediate operations (since overflow is impossible). |
| @end itemize |
| |
| If two digits are present after @option{-gnato} then the first digit |
| sets the mode for expressions outside assertions, and the second digit |
| sets the mode for expressions within assertions. Here assertions is used |
| in the technical sense (which includes for example precondition and |
| postcondition expressions). |
| |
| If one digit is present, the corresponding mode is applicable to both |
| expressions within and outside assertion expressions. |
| |
| If no digits are present, the default is to enable overflow checks |
| and set STRICT mode for both kinds of expressions. This is compatible |
| with the use of @option{-gnato} in previous versions of GNAT. |
| |
| @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, @value{EDITION} 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, unlike |
| for example the failure of a range check, can result in an incorrect |
| value, but cannot cause random memory destruction (like an out of range |
| subscript), or a wild jump (from an out of range case value). Overflow |
| checking is also quite expensive in time and space, since in general it |
| requires the use of double length arithmetic. |
| |
| Note again that the default is @option{-gnato00}, so overflow checking is |
| not performed in default mode. This means that out of the box, with the |
| default settings, @value{EDITION} 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 @option{-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. |
| Note that @option{-gnatE} is not necessary for safety, because in the |
| default mode, GNAT ensures statically that the checks would not fail. |
| 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 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 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 |
| |
| @noindent |
| The switches described in this section allow you to explicitly specify |
| the version of the Ada language that your programs are written in. |
| By default @value{EDITION} assumes @value{DEFAULTLANGUAGEVERSION}, |
| but you can also specify @value{NONDEFAULTLANGUAGEVERSION} or |
| indicate Ada 83 compatibility mode. |
| |
| @table @option |
| @cindex Compatibility with Ada 83 |
| |
| @item -gnat83 (Ada 83 Compatibility Mode) |
| @cindex @option{-gnat83} (@command{gcc}) |
| @cindex ACVC, Ada 83 tests |
| @cindex Ada 83 mode |
| |
| @noindent |
| Although GNAT is primarily an Ada 95 / Ada 2005 compiler, this switch |
| specifies that the program is to be compiled in Ada 83 mode. With |
| @option{-gnat83}, GNAT rejects most post-Ada 83 extensions and applies Ada 83 |
| semantics where this can be done easily. |
| It is not possible to guarantee this switch does a perfect |
| job; 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, existing 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 / Ada 2005 |
| reserved words, and the use of packages |
| with optional bodies), it is not necessary to specify the |
| @option{-gnat83} switch when compiling Ada 83 programs, because, with rare |
| exceptions, Ada 95 and Ada 2005 are upwardly compatible with Ada 83. Thus |
| a correct Ada 83 program is usually also a correct program |
| in these later versions of the language standard. |
| For further information, please refer to @ref{Compatibility and Porting Guide}. |
| |
| @item -gnat95 (Ada 95 mode) |
| @cindex @option{-gnat95} (@command{gcc}) |
| @cindex Ada 95 mode |
| |
| @noindent |
| This switch directs the compiler to implement the Ada 95 version of the |
| language. |
| Since Ada 95 is almost completely upwards |
| compatible with Ada 83, Ada 83 programs may generally be compiled using |
| this switch (see the description of the @option{-gnat83} switch for further |
| information about Ada 83 mode). |
| If an Ada 2005 program is compiled in Ada 95 mode, |
| uses of the new Ada 2005 features will cause error |
| messages or warnings. |
| |
| This switch also can be used to cancel the effect of a previous |
| @option{-gnat83}, @option{-gnat05/2005}, or @option{-gnat12/2012} |
| switch earlier in the command line. |
| |
| @item -gnat05 or -gnat2005 (Ada 2005 mode) |
| @cindex @option{-gnat05} (@command{gcc}) |
| @cindex @option{-gnat2005} (@command{gcc}) |
| @cindex Ada 2005 mode |
| |
| @noindent |
| This switch directs the compiler to implement the Ada 2005 version of the |
| language, as documented in the official Ada standards document. |
| Since Ada 2005 is almost completely upwards |
| compatible with Ada 95 (and thus also with Ada 83), Ada 83 and Ada 95 programs |
| may generally be compiled using this switch (see the description of the |
| @option{-gnat83} and @option{-gnat95} switches for further |
| information). |
| |
| @ifset PROEDITION |
| Note that even though Ada 2005 is the current official version of the |
| language, GNAT still compiles in Ada 95 mode by default, so if you are |
| using Ada 2005 features in your program, you must use this switch (or |
| the equivalent Ada_05 or Ada_2005 configuration pragmas). |
| @end ifset |
| |
| @item -gnat12 or -gnat2012 (Ada 2012 mode) |
| @cindex @option{-gnat12} (@command{gcc}) |
| @cindex @option{-gnat2012} (@command{gcc}) |
| @cindex Ada 2012 mode |
| |
| @noindent |
| This switch directs the compiler to implement the Ada 2012 version of the |
| language. |
| Since Ada 2012 is almost completely upwards |
| compatible with Ada 2005 (and thus also with Ada 83, and Ada 95), |
| Ada 83 and Ada 95 programs |
| may generally be compiled using this switch (see the description of the |
| @option{-gnat83}, @option{-gnat95}, and @option{-gnat05/2005} switches |
| for further information). |
| |
| For information about the approved ``Ada Issues'' that have been incorporated |
| into Ada 2012, see @url{http://www.ada-auth.org/ais.html}. |
| Included with GNAT releases is a file @file{features-ada12} that describes |
| the set of implemented Ada 2012 features. |
| |
| @item -gnatX (Enable GNAT Extensions) |
| @cindex @option{-gnatX} (@command{gcc}) |
| @cindex Ada language extensions |
| @cindex GNAT extensions |
| |
| @noindent |
| This switch directs the compiler to implement the latest version of the |
| language (currently Ada 2012) and also to enable certain GNAT implementation |
| extensions that are not part of any Ada standard. For a full list of these |
| extensions, see the GNAT reference manual. |
| |
| @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 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 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. |
| |
| Note that brackets encoding only applies to program text. Within comments, |
| brackets are considered to be normal graphic characters, and bracket sequences |
| are never recognized as wide characters. |
| |
| If no @option{-gnatW?} parameter is present, then the default |
| representation is normally Brackets encoding only. However, if the |
| first three characters of the file are 16#EF# 16#BB# 16#BF# (the standard |
| byte order mark or BOM for UTF-8), then these three characters are |
| skipped and the default representation for the file is set to UTF-8. |
| |
| 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 |
| |
| When no @option{-gnatW?} is specified, then characters (other than wide |
| characters represented using brackets notation) are treated as 8-bit |
| Latin-1 codes. The codes recognized are the Latin-1 graphic characters, |
| and ASCII format effectors (CR, LF, HT, VT). Other lower half control |
| characters in the range 16#00#..16#1F# are not accepted in program text |
| or in comments. Upper half control characters (16#80#..16#9F#) are rejected |
| in program text, but allowed and ignored in comments. Note in particular |
| that the Next Line (NEL) character whose encoding is 16#85# is not recognized |
| as an end of line in this default mode. If your source program contains |
| instances of the NEL character used as a line terminator, |
| you must use UTF-8 encoding for the whole |
| source program. In default mode, all lines must be ended by a standard |
| end of line sequence (CR, CR/LF, or LF). |
| |
| Note that the convention of simply accepting all upper half characters in |
| comments means that programs that use standard ASCII for program text, but |
| UTF-8 encoding for comments are accepted in default mode, providing that the |
| comments are ended by an appropriate (CR, or CR/LF, or LF) line terminator. |
| This is a common mode for many programs with foreign language comments. |
| |
| @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[12] |
| @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 and, in order |
| 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. |
| |
| You can optionally specify the inlining level: 1 for moderate inlining across |
| modules, which is a good compromise between compilation times and performances |
| at run time, or 2 for full inlining across modules, which may bring about |
| longer compilation times. If no inlining level is specified, the compiler will |
| pick it based on the optimization level: 1 for @option{-O1}, @option{-O2} or |
| @option{-Os} and 2 for @option{-O3}. |
| |
| 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}) |
| This switch activates front-end inlining which also |
| generates additional dependencies. |
| |
| When using a gcc-based back end (in practice this means using any version |
| of GNAT other than the JGNAT, .NET or GNAAMP versions), then the use of |
| @option{-gnatN} is deprecated, and the use of @option{-gnatn} is preferred. |
| Historically front end inlining was more extensive than the gcc back end |
| inlining, but that is no longer the case. |
| @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. |
| Note that the combination of switches @option{-gnatct} |
| generates a tree in the form required by ASIS applications. |
| |
| @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[=nn] |
| @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 optional parameter @code{nn} if present after -gnatG specifies an |
| alternative maximum line length that overrides the normal default of 72. |
| This value is in the range 40-999999, values less than 40 being silently |
| reset to 40. The equal sign is optional. |
| |
| 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 spec |
| of package @code{Sprint} in file @file{sprint.ads} for a full list. |
| |
| If the switch @option{-gnatL} is used in conjunction with |
| @cindex @option{-gnatL} (@command{gcc}) |
| @option{-gnatG}, then the original source lines are interspersed |
| in the expanded source (as comment lines with the original line number). |
| |
| @table @code |
| @item new @var{xxx} @r{[}storage_pool = @var{yyy}@r{]} |
| 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} @r{[}storage_pool = @var{xxx}@r{]} |
| 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. |
| |
| @c @item freeze @var{type-name} @ovar{actions} |
| @c Expanding @ovar macro inline (explanation in macro def comments) |
| @item freeze @var{type-name} @r{[}@var{actions}@r{]} |
| 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} @dots{} && @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[=nn] |
| @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}). |
| |
| If the switch @option{-gnatL} is used in conjunction with |
| @cindex @option{-gnatL} (@command{gcc}) |
| @option{-gnatDG}, then the original source lines are interspersed |
| in the expanded source (as comment lines with the original line number). |
| |
| The optional parameter @code{nn} if present after -gnatD specifies an |
| alternative maximum line length that overrides the normal default of 72. |
| This value is in the range 40-999999, values less than 40 being silently |
| reset to 40. The equal sign is optional. |
| |
| @item -gnatr |
| @cindex @option{-gnatr} (@command{gcc}) |
| @cindex pragma Restrictions |
| This switch causes pragma Restrictions to be treated as Restriction_Warnings |
| so that violation of restrictions causes warnings rather than illegalities. |
| This is useful during the development process when new restrictions are added |
| or investigated. The switch also causes pragma Profile to be treated as |
| Profile_Warnings, and pragma Restricted_Run_Time and pragma Ravenscar set |
| restriction warnings rather than restrictions. |
| |
| @ifclear vms |
| @item -gnatR@r{[}0@r{|}1@r{|}2@r{|}3@r{[}s@r{]]} |
| @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 |
| declared types and objects. Finally @option{-gnatR3} includes symbolic |
| expressions 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}. |
| |
| Representation information requires that code be generated (since it is the |
| code generator that lays out complex data structures). If an attempt is made |
| to output representation information when no code is generated, for example |
| when a subunit is compiled on its own, then no information can be generated |
| and the compiler outputs a message to this effect. |
| |
| @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 may 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 (when available) to be used |
| for exception handling. 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 switch is unneeded. 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, otherwise it will generate an error. |
| @end table |
| |
| @noindent |
| The same option @option{--RTS} must be used both for @command{gcc} |
| and @command{gnatbind}. Passing this option to @command{gnatmake} |
| (@pxref{Switches for gnatmake}) will ensure the required consistency |
| through the compilation and binding steps. |
| |
| @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 primarily 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 specs 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 (nonexistent 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} creates 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. |
| In this case, 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 |
| Note that when integrated preprocessing is used, the output from the |
| preprocessor is not written to any external file. Instead it is passed |
| internally to the compiler. If you need to preserve the result of |
| preprocessing in a file, then you should use @command{gnatprep} |
| to perform the desired preprocessing in stand-alone mode. |
| |
| @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. Note that when the compiler is |
| called by a builder (@command{gnatmake} or @command{gprbuild}) with a project |
| file, if the object directory is not also a source directory, the builder needs |
| to be called with @option{-x}. |
| |
| @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 nonempty, 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@r{[}=value@r{]} |
| @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}. |
| |
| @item -gnateG |
| When integrated preprocessing is performed and the preprocessor modifies |
| the source text, write the result of this preprocessing into a file |
| <source>^.prep^_prep^. |
| |
| @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 @value{EDITION} 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 @value{EDITION}, 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 @env{ADA_PRJ_INCLUDE_FILE} ^environment variable^logical name^. |
| |
| @noindent |
| @env{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 |
| @env{ADA_INCLUDE_PATH} ^environment variable^logical name^. |
| @ifclear vms |
| Construct this value |
| exactly as the @env{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 |
| 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 standard Ada packages. Thus, in order to get the standard Ada |
| 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. @xref{Top, GNAT Reference Manual, About |
| This Guid, gnat_rm, 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. |
| |
| Note: to invoke @code{gnatbind} with a project file, use the @code{gnat} |
| driver (see @ref{The GNAT Driver and Project Files}). |
| |
| 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 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 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 |
| @c $ gnatbind @ovar{switches} @var{mainprog}@r{[}.ali@r{]} @ovar{switches} |
| @c Expanding @ovar macro inline (explanation in macro def comments) |
| $ gnatbind @r{[}@var{switches}@r{]} @var{mainprog}@r{[}.ali@r{]} @r{[}@var{switches}@r{]} |
| @end smallexample |
| |
| @noindent |
| where @file{@var{mainprog}.adb} is the Ada file containing the main program |
| unit body. @code{gnatbind} constructs an Ada |
| package in two files whose names are |
| @file{b~@var{mainprog}.ads}, and @file{b~@var{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}. |
| |
| @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:: |
| * Dynamic Allocation Control:: |
| * Binding with Non-Ada Main Programs:: |
| * Binding Programs with No Main Subprogram:: |
| @end menu |
| |
| @table @option |
| @c !sort! |
| |
| @item --version |
| @cindex @option{--version} @command{gnatbind} |
| Display Copyright and version, then exit disregarding all other options. |
| |
| @item --help |
| @cindex @option{--help} @command{gnatbind} |
| If @option{--version} was not used, display usage, then exit disregarding |
| all other options. |
| |
| @item -a |
| @cindex @option{-a} @command{gnatbind} |
| Indicates that, if supported by the platform, the adainit procedure should |
| be treated as an initialisation routine by the linker (a constructor). This |
| is intended to be used by the Project Manager to automatically initialize |
| shared Stand-Alone Libraries. |
| |
| @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^/ALI_LIST^@r{[=}@var{filename}@r{]} |
| @cindex @option{^-A^/ALI_LIST^} (@command{gnatbind}) |
| Output ALI list (to standard output or to the named file). |
| |
| @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 ^-d^/DEFAULT_STACK_SIZE=^@var{nn}@r{[}k@r{|}m@r{]} |
| @cindex @option{^-d^/DEFAULT_STACK_SIZE=^@var{nn}@r{[}k@r{|}m@r{]}} (@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 @samp{@r{[}k@r{|}m@r{]}} 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}@r{[}k@r{|}m@r{]} |
| @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 define 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. |
| @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 ^-H32^/32_MALLOC^ |
| @cindex @option{^-H32^/32_MALLOC^} (@command{gnatbind}) |
| Use 32-bit allocations for @code{__gnat_malloc} (and thus for access types). |
| For further details see @ref{Dynamic Allocation Control}. |
| |
| @item ^-H64^/64_MALLOC^ |
| @cindex @option{^-H64^/64_MALLOC^} (@command{gnatbind}) |
| Use 64-bit allocations for @code{__gnat_malloc} (and thus for access types). |
| @cindex @code{__gnat_malloc} |
| For further details see @ref{Dynamic Allocation Control}. |
| |
| @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 ^-L@var{xxx}^/BUILD_LIBRARY=@var{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 ^@var{xxx}init^@var{XXX}INIT^ and |
| ^@var{xxx}final^@var{XXX}FINAL^. |
| 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 or warnings to @var{n}, where @var{n} is |
| in the range 1..999999. The default value if no switch is |
| given is 9999. If the number of warnings reaches this limit, then a |
| message is output and further warnings are suppressed, the bind |
| continues in this case. If the number of errors reaches this |
| limit, then a message is output and the bind is abandoned. |
| A value of zero means that no limit is enforced. The equal |
| sign is optional. |
| |
| @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^@r{[=}@var{filename}@r{]} |
| @cindex @option{^-O^/OBJECT_LIST^} (@command{gnatbind}) |
| Output object list (to standard output or to the named file). |
| |
| @item ^-p^/PESSIMISTIC_ELABORATION^ |
| @cindex @option{^-p^/PESSIMISTIC_ELABORATION^} (@command{gnatbind}) |
| Pessimistic (worst-case) elaboration order |
| |
| @item ^-P^-P^ |
| @cindex @option{^-P^/CODEPEER^} (@command{gnatbind}) |
| Generate binder file suitable for CodePeer. |
| |
| @item ^-R^-R^ |
| @cindex @option{^-R^-R^} (@command{gnatbind}) |
| Output closure source list. |
| |
| @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{@var{xx}}'' for a value consisting of repeated bytes with the |
| value @code{16#@var{xx}#} (i.e., @var{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 @env{GNAT_INIT_SCALARS=@var{xx}}, where @var{xx} is one |
| of @option{in/lo/hi/@var{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 @var{n} results stored and displayed |
| at program termination. A result is generated when a task |
| terminates. Results that can't be stored are displayed on the fly, at |
| task termination. This option is currently not supported on Itanium |
| platforms. (See @ref{Dynamic Stack Usage Analysis} for details.) |
| |
| @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 ^-Wx^/WIDE_CHARACTER_ENCODING=^@var{e} |
| @cindex @option{^-Wx^/WIDE_CHARACTER_ENCODING^} (@code{gnatbind}) |
| Override default wide character encoding for standard Text_IO files. |
| |
| @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 ^-y^/ENABLE_LEAP_SECONDS^ |
| @cindex @option{^-y^/ENABLE_LEAP_SECONDS^} (@code{gnatbind}) |
| Enable leap seconds support in @code{Ada.Calendar} and its children. |
| |
| @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 ^-Wx^/WIDE_CHARACTER_ENCODING=^@var{e} |
| @cindex @option{^-Wx^/WIDE_CHARACTER_ENCODING^} (@code{gnatbind}) |
| Override default wide character encoding for standard Text_IO files. |
| Normally the default wide character encoding method used for standard |
| [Wide_[Wide_]]Text_IO files is taken from the encoding specified for |
| the main source input (see description of switch |
| @option{^-gnatWx^/WIDE_CHARACTER_ENCODING^} for the compiler). The |
| use of this switch for the binder (which has the same set of |
| possible arguments) overrides this default as specified. |
| |
| @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. |
| |
| Note that @option{^-p^/PESSIMISTIC_ELABORATION^} is not intended for |
| production use; it is more for debugging/experimental use. |
| @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 ^-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 ^-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. |
| 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 Dynamic Allocation Control |
| @subsection Dynamic Allocation Control |
| |
| @noindent |
| The heap control switches -- @option{-H32} and @option{-H64} -- |
| determine whether dynamic allocation uses 32-bit or 64-bit memory. |
| They only affect compiler-generated allocations via @code{__gnat_malloc}; |
| explicit calls to @code{malloc} and related functions from the C |
| run-time library are unaffected. |
| |
| @table @option |
| @item -H32 |
| Allocate memory on 32-bit heap |
| |
| @item -H64 |
| Allocate memory on 64-bit heap. This is the default |
| unless explicitly overridden by a @code{'Size} clause on the access type. |
| @end table |
| |
| @ifset vms |
| @noindent |
| See also @ref{Access types and 32/64-bit allocation}. |
| @end ifset |
| @ifclear vms |
| @noindent |
| These switches are only effective on VMS platforms. |
| @end ifclear |
| |
| |
| @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. |
| 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. Note |
| that the default wide character encoding method for standard Text_IO |
| files is always set to Brackets if this switch is set (you can use |
| the binder switch |
| @option{^-Wx^WIDE_CHARACTER_ENCODING^} to override this default). |
| @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 @env{ADA_PRJ_OBJECTS_FILE} ^environment variable^logical name^. |
| |
| @noindent |
| @env{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 |
| @env{ADA_OBJECTS_PATH} ^environment variable^logical name^. |
| @ifset unw |
| Construct this value |
| exactly as the @env{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 |
| 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 standard Ada packages. Thus, in order to get the standard Ada |
| 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. Note that if this option is used, then linking must be done manually, |
| since gnatlink will not be able to find the generated file. |
| @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. |
| |
| Note: to invoke @code{gnatlink} with a project file, use the @code{gnat} |
| driver (see @ref{The GNAT Driver and Project Files}). |
| |
| @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 |
| @c $ gnatlink @ovar{switches} @var{mainprog}@r{[}.ali@r{]} |
| @c @ovar{non-Ada objects} @ovar{linker options} |
| @c Expanding @ovar macro inline (explanation in macro def comments) |
| $ gnatlink @r{[}@var{switches}@r{]} @var{mainprog}@r{[}.ali@r{]} |
| @r{[}@var{non-Ada objects}@r{]} @r{[}@var{linker options}@r{]} |
| |
| @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 @command{gcc} which in |
| turn calls the appropriate system linker. |
| |
| One useful option for the linker is @option{-s}: it reduces the size of the |
| executable by removing all symbol table and relocation information from the |
| executable. |
| |
| 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 |
| @command{gcc} as linker options, use the @command{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. |
| @ifset unw |
| See @ref{Setting Stack Size from gnatlink} and |
| @ref{Setting Heap Size from gnatlink}. |
| @end ifset |
| |
| @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 (@file{.OBJ}), libraries (@file{.OLB}), sharable images |
| (@file{.EXE}), and options files (@file{.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 --version |
| @cindex @option{--version} @command{gnatlink} |
| Display Copyright and version, then exit disregarding all other options. |
| |
| @item --help |
| @cindex @option{--help} @command{gnatlink} |
| If @option{--version} was not used, display usage, then exit disregarding |
| all other options. |
| |
| @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. |
| @xref{Directory Options,,, gcc, The GNU Compiler Collection}, |
| for further details. You would normally use the @option{-b} or |
| @option{-V} switch instead. |
| |
| @item -M |
| When linking an executable, create a map file. The name of the map file |
| has the same name as the executable with extension ".map". |
| |
| @item -M=mapfile |
| When linking an executable, create a map file. The name of the map file is |
| "mapfile". |
| |
| @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 the compiler executable is |
| different from the default one (gcc or <prefix>-gcc), then the back-end |
| switches in the ALI file are not used to compile the binder generated source. |
| For example, this is the case with @option{--GCC="foo -x -y"}. But the back end |
| switches will be used for @option{--GCC="gcc -gnatv"}. 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 |
| @c $ gnatmake @ovar{switches} @var{file_name} |
| @c @ovar{file_names} @ovar{mode_switches} |
| @c Expanding @ovar macro inline (explanation in macro def comments) |
| $ gnatmake @r{[}@var{switches}@r{]} @var{file_name} |
| @r{[}@var{file_names}@r{]} @r{[}@var{mode_switches}@r{]} |
| @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 (@file{.adb} and @file{.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! |
| |
| @item --version |
| @cindex @option{--version} @command{gnatmake} |
| Display Copyright and version, then exit disregarding all other options. |
| |
| @item --help |
| @cindex @option{--help} @command{gnatmake} |
| If @option{--version} was not used, display usage, then exit disregarding |
| all other options. |
| |
| @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 ^--subdirs^/SUBDIRS^=subdir |
| Actual object directory of each project file is the subdirectory subdir of the |
| object directory specified or defaulted in the project file. |
| |
| @item ^--single-compile-per-obj-dir^/SINGLE_COMPILE_PER_OBJ_DIR^ |
| Disallow simultaneous compilations in the same object directory when |
| project files are used. |
| |
| @item ^--unchecked-shared-lib-imports^/UNCHECKED_SHARED_LIB_IMPORTS^ |
| By default, shared library projects are not allowed to import static library |
| projects. When this switch is used on the command line, this restriction is |
| relaxed. |
| |
| @item ^--source-info=<source info file>^/SRC_INFO=source-info-file^ |
| Specify a source info file. This switch is active only when project files |
| are used. If the source info file is specified as a relative path, then it is |
| relative to the object directory of the main project. If the source info file |
| does not exist, then after the Project Manager has successfully parsed and |
| processed the project files and found the sources, it creates the source info |
| file. If the source info file already exists and can be read successfully, |
| then the Project Manager will get all the needed information about the sources |
| from the source info file and will not look for them. This reduces the time |
| to process the project files, especially when looking for sources that take a |
| long time. If the source info file exists but cannot be parsed successfully, |
| the Project Manager will attempt to recreate it. If the Project Manager fails |
| to create the source info file, a message is issued, but gnatmake does not |
| fail. @command{gnatmake} "trusts" the source info file. This means that |
| if the source files have changed (addition, deletion, moving to a different |
| source directory), then the source info file need to be deleted and recreated. |
| |
| @ifclear vms |
| @item --create-map-file |
| When linking an executable, create a map file. The name of the map file |
| has the same name as the executable with extension ".map". |
| |
| @item --create-map-file=mapfile |
| When linking an executable, create a map file. The name of the map file is |
| "mapfile". |
| |
| @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). A mapping file can make the compiler's |
| file searches faster, especially if there are many source directories, |
| or the sources are read over a slow network connection. If |
| @option{^-P^/PROJECT_FILE^} is used, a mapping file is always used, so |
| @option{^-C^/MAPPING^} is unnecessary; in this case the mapping file |
| is initially populated based on the project file. If |
| @option{^-C^/MAPPING^} is used without |
| @option{^-P^/PROJECT_FILE^}, |
| the mapping file is initially empty. Each invocation of the compiler |
| will add any newly accessed sources to the mapping file. |
| |
| @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^/DISPLAY_PROGRESS^ |
| @cindex @option{^-d^/DISPLAY_PROGRESS^} (@command{gnatmake}) |
| Display progress for each source, up to date or not, as a single line |
| |
| @smallexample |
| completed x out of y (zz%) |
| @end smallexample |
| |
| If the file needs to be compiled this is displayed after the invocation of |
| the compiler. These lines are displayed even in quiet output mode. |
| |
| @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. |
| |
| @item -eInnn |
| @cindex @option{-eI} (@command{gnatmake}) |
| Indicates that the main source is a multi-unit source and the rank of the unit |
| in the source file is nnn. nnn needs to be a positive number and a valid |
| index in the source. This switch cannot be used when @command{gnatmake} is |
| invoked for several mains. |
| |
| @ifclear vms |
| @item -eL |
| @cindex @option{-eL} (@command{gnatmake}) |
| @cindex symbolic links |
| Follow all symbolic links when processing project files. |
| This should be used if your project uses symbolic links for files or |
| directories, but is not needed in other cases. |
| |
| @cindex naming scheme |
| This also assumes that no directory matches the naming scheme for files (for |
| instance that you do not have a directory called "sources.ads" when using the |
| default GNAT naming scheme). |
| |
| When you do not have to use this switch (i.e.@: by default), gnatmake is able to |
| save a lot of system calls (several per source file and object file), which |
| can result in a significant speed up to load and manipulate a project file, |
| especially when using source files from a remote system. |
| |
| @end ifclear |
| |
| @item ^-eS^/STANDARD_OUTPUT_FOR_COMMANDS^ |
| @cindex @option{^-eS^/STANDARD_OUTPUT_FOR_COMMANDS^} (@command{gnatmake}) |
| Output the commands for the compiler, the binder and the linker |
| on ^standard output^SYS$OUTPUT^, |
| instead of ^standard error^SYS$ERROR^. |
| |
| @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 ^-g^/DEBUG^ |
| @cindex @option{^-g^/DEBUG^} (@command{gnatmake}) |
| Enable debugging. This switch is simply passed to the compiler and to the |
| linker. |
| |
| @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 @command{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 or --create-missing-dirs^/CREATE_MISSING_DIRS^ |
| @cindex @option{^-p^/CREATE_MISSING_DIRS^} (@command{gnatmake}) |
| When using project files (^-P^/PROJECT_FILE=^@var{project}), create |
| automatically missing object directories, library directories and exec |
| directories. |
| |
| @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. Even when |
| @option{^-x^/NON_PROJECT_UNIT_COMPILATION^} is used, mains specified on the |
| command line need to be sources of a project file. |
| |
| @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. |
| |
| @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 recompilations. 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:: |
| * Text_IO Suggestions:: |
| * Reducing Size of Ada Executables with gnatelim:: |
| * Reducing 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:: |
| * Vectorization of loops:: |
| * 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 integer overflow |
| checks, stack overflow checks, 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 @dots{} 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 |
| Without any optimization ^option,^qualifier,^ |
| the compiler's goal is to reduce the cost of |
| compilation and to make debugging produce the expected results. |
| Statements are independent: if you stop the program with a breakpoint between |
| statements, you can then assign a new value to any variable or change |
| the program counter to any other statement in the subprogram and get exactly |
| the results you would expect from the source code. |
| |
| Turning on optimization makes the compiler attempt to improve the |
| performance and/or code size at the expense of compilation time and |
| possibly the ability to debug the program. |
| |
| If you use multiple |
| ^-O options, with or without level numbers,^/OPTIMIZE qualifiers,^ |
| the last such option is the one that is effective. |
| |
| @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} switch (the permitted forms are @option{-O0}, @option{-O1} |
| @option{-O2}, @option{-O3}, and @option{-Os}) |
| @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. With 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}; |
| also uses more aggressive automatic inlining of subprograms within a unit |
| (@pxref{Inlining of Subprograms}) and attempts to vectorize loops. |
| |
| @item ^-Os^/OPTIMIZE=SPACE^ |
| Optimize space usage (code and data) of resulting program. |
| @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. |
| @xref{Optimize Options,, Options That Control Optimization, gcc, Using |
| the GNU Compiler Collection (GCC)}, for 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 may 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 something that @command{gcc} cannot support in inlined |
| subprograms. |
| |
| @item |
| @cindex pragma Inline |
| @findex Inline |
| Any one of the following applies: @code{pragma Inline} is applied to the |
| subprogram and the @option{^-gnatn^/INLINE^} switch is specified; the |
| subprogram is local to the unit and called once from within it; the |
| subprogram is small and optimization level @option{-O2} is specified; |
| optimization level @option{-O3} is specified. |
| @end itemize |
| |
| @noindent |
| Calls to subprograms in @code{with}'ed units are normally not inlined. |
| To achieve actual inlining (that is, replacement of the call by the code |
| in the body of the subprogram), 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 something that @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 |
| The @option{^-gnatn^/INLINE^} switch is used on the command line. |
| @end itemize |
| |
| Even if all these conditions are met, it may not be possible for |
| the compiler to inline the call, due to the length of the body, |
| or features in the body that make it impossible for the compiler |
| to do the inlining. |
| |
| 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 |
| @dots{} |
| end R; |
| |
| with R; |
| procedure Main is |
| begin |
| @dots{} |
| 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. |
| |
| @cindex @option{-fno-inline-functions} (@command{gcc}) |
| Note: The @option{-fno-inline-functions} switch can be used to prevent |
| automatic inlining of subprograms if @option{-O3} is used. |
| |
| @cindex @option{-fno-inline-small-functions} (@command{gcc}) |
| Note: The @option{-fno-inline-small-functions} switch can be used to prevent |
| automatic inlining of small subprograms if @option{-O2} is used. |
| |
| @cindex @option{-fno-inline-functions-called-once} (@command{gcc}) |
| Note: The @option{-fno-inline-functions-called-once} switch |
| can be used to prevent inlining of subprograms local to the unit |
| and called once from within it if @option{-O1} is used. |
| |
| Note regarding the use of @option{-O3}: @option{-gnatn} is made up of two |
| sub-switches @option{-gnatn1} and @option{-gnatn2} that can be directly |
| specified in lieu of it, @option{-gnatn} being translated into one of them |
| based on the optimization level. With @option{-O2} or below, @option{-gnatn} |
| is equivalent to @option{-gnatn1} which activates pragma @code{Inline} with |
| moderate inlining across modules. With @option{-O3}, @option{-gnatn} is |
| equivalent to @option{-gnatn2} which activates pragma @code{Inline} with |
| full inlining across modules. 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 has the additional |
| effect of inlining subprograms you did not think should be inlined. We have |
| found that the use of @option{-O3} may slow down the compilation and increase |
| the code size by performing excessive inlining, leading to increased |
| instruction cache pressure from the increased code size and thus minor |
| performance improvements. 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 for your program. |
| |
| @node Vectorization of loops |
| @subsection Vectorization of loops |
| @cindex Optimization Switches |
| |
| You can take advantage of the auto-vectorizer present in the @command{gcc} |
| back end to vectorize loops with GNAT. The corresponding command line switch |
| is @option{-ftree-vectorize} but, as it is enabled by default at @option{-O3} |
| and other aggressive optimizations helpful for vectorization also are enabled |
| by default at this level, using @option{-O3} directly is recommended. |
| |
| You also need to make sure that the target architecture features a supported |
| SIMD instruction set. For example, for the x86 architecture, you should at |
| least specify @option{-msse2} to get significant vectorization (but you don't |
| need to specify it for x86-64 as it is part of the base 64-bit architecture). |
| Similarly, for the PowerPC architecture, you should specify @option{-maltivec}. |
| |
| The preferred loop form for vectorization is the @code{for} iteration scheme. |
| Loops with a @code{while} iteration scheme can also be vectorized if they are |
| very simple, but the vectorizer will quickly give up otherwise. With either |
| iteration scheme, the flow of control must be straight, in particular no |
| @code{exit} statement may appear in the loop body. The loop may however |
| contain a single nested loop, if it can be vectorized when considered alone: |
| |
| @smallexample @c ada |
| @cartouche |
| A : array (1..4, 1..4) of Long_Float; |
| S : array (1..4) of Long_Float; |
| |
| procedure Sum is |
| begin |
| for I in A'Range(1) loop |
| for J in A'Range(2) loop |
| S (I) := S (I) + A (I, J); |
| end loop; |
| end loop; |
| end Sum; |
| @end cartouche |
| @end smallexample |
| |
| The vectorizable operations depend on the targeted SIMD instruction set, but |
| the adding and some of the multiplying operators are generally supported, as |
| well as the logical operators for modular types. Note that, in the former |
| case, enabling overflow checks, for example with @option{-gnato}, totally |
| disables vectorization. The other checks are not supposed to have the same |
| definitive effect, although compiling with @option{-gnatp} might well reveal |
| cases where some checks do thwart vectorization. |
| |
| Type conversions may also prevent vectorization if they involve semantics that |
| are not directly supported by the code generator or the SIMD instruction set. |
| A typical example is direct conversion from floating-point to integer types. |
| The solution in this case is to use the following idiom: |
| |
| @smallexample @c ada |
| Integer (S'Truncation (F)) |
| @end smallexample |
| |
| @noindent |
| if @code{S} is the subtype of floating-point object @code{F}. |
| |
| In most cases, the vectorizable loops are loops that iterate over arrays. |
| All kinds of array types are supported, i.e. constrained array types with |
| static bounds: |
| |
| @smallexample @c ada |
| type Array_Type is array (1 .. 4) of Long_Float; |
| @end smallexample |
| |
| @noindent |
| constrained array types with dynamic bounds: |
| |
| @smallexample @c ada |
| type Array_Type is array (1 .. Q.N) of Long_Float; |
| |
| type Array_Type is array (Q.K .. 4) of Long_Float; |
| |
| type Array_Type is array (Q.K .. Q.N) of Long_Float; |
| @end smallexample |
| |
| @noindent |
| or unconstrained array types: |
| |
| @smallexample @c ada |
| type Array_Type is array (Positive range <>) of Long_Float; |
| @end smallexample |
| |
| @noindent |
| The quality of the generated code decreases when the dynamic aspect of the |
| array type increases, the worst code being generated for unconstrained array |
| types. This is so because, the less information the compiler has about the |
| bounds of the array, the more fallback code it needs to generate in order to |
| fix things up at run time. |
| |
| It is possible to specify that a given loop should be subject to vectorization |
| preferably to other optimizations by means of pragma @code{Loop_Optimize}: |
| |
| @smallexample @c ada |
| pragma Loop_Optimize (Vector); |
| @end smallexample |
| |
| @noindent |
| placed immediately within the loop will convey the appropriate hint to the |
| compiler for this loop. |
| |
| You can obtain information about the vectorization performed by the compiler |
| by specifying @option{-ftree-vectorizer-verbose=N}. For more details of |
| this switch, see @ref{Debugging Options,,Options for Debugging Your Program |
| or GCC, gcc, Using the GNU Compiler Collection (GCC)}. |
| |
| @node Other Optimization Switches |
| @subsection Other Optimization Switches |
| @cindex Optimization Switches |
| |
| Since @code{GNAT} uses the @command{gcc} back end, all the specialized |
| @command{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=xxx} can significantly improve performance |
| on appropriate machines). For full details of these switches, see |
| @ref{Submodel Options,, Hardware Models and Configurations, gcc, Using |
| the GNU Compiler Collection (GCC)}. |
| |
| @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; |
| @dots{} |
| |
| begin |
| @dots{} |
| for J in Data'Range loop |
| if Data (J) = Int1V.all then |
| Int2V.all := Int2V.all + 1; |
| end if; |
| end loop; |
| @dots{} |
| 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 or @option{-Os} 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 @option{-O0} or @option{-O1} |
| mode, but it prints out 1 in @option{-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 @option{-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 @option{-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 @option{-O2} |
| and @option{-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. |
| |
| The aliasing analysis done in strict aliasing mode can certainly |
| have significant benefits. We have seen cases of large scale |
| application code where the time is increased by up to 5% by turning |
| this optimization off. If you have code that includes significant |
| usage of unchecked conversion, you might want to just stick with |
| @option{-O1} and avoid the entire issue. If you get adequate |
| performance at this level of optimization level, that's probably |
| the safest approach. If tests show that you really need higher |
| levels of optimization, then you can experiment with @option{-O2} |
| and @option{-O2 -fno-strict-aliasing} to see how much effect this |
| has on size and speed of the code. If you really need to use |
| @option{-O2} with strict aliasing in effect, then you should |
| review any uses of unchecked conversion of access types, |
| particularly if you are getting the warnings described above. |
| |
| @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 Text_IO Suggestions |
| @section @code{Text_IO} Suggestions |
| @cindex @code{Text_IO} and performance |
| |
| @noindent |
| The @code{Ada.Text_IO} package has fairly high overheads due in part to |
| the requirement of maintaining page and line counts. If performance |
| is critical, a recommendation is to use @code{Stream_IO} instead of |
| @code{Text_IO} for volume output, since this package has less overhead. |
| |
| If @code{Text_IO} must be used, note that by default output to the standard |
| output and standard error files is unbuffered (this provides better |
| behavior when output statements are used for debugging, or if the |
| progress of a program is observed by tracking the output, e.g. by |
| using the Unix @command{tail -f} command to watch redirected output. |
| |
| If you are generating large volumes of output with @code{Text_IO} and |
| performance is an important factor, use a designated file instead |
| of the standard output file, or change the standard output file to |
| be buffered using @code{Interfaces.C_Streams.setvbuf}. |
| |
| |
| |
| @node Reducing Size of Ada Executables with gnatelim |
| @section Reducing 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:: |
| * Processing Precompiled Libraries:: |
| * 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. |
| @xref{Pragma Eliminate,,, gnat_rm, GNAT Reference Manual}, for more |
| information about this pragma. |
| |
| @code{gnatelim} needs as its input data the name of the main subprogram. |
| |
| If a set of source files is specified as @code{gnatelim} arguments, it |
| treats these files as a complete set of sources making up a program to |
| analyse, and analyses only these sources. |
| |
| After a full successful build of the main subprogram @code{gnatelim} can be |
| called without specifying sources to analyse, in this case it computes |
| the source closure of the main unit from the @file{ALI} files. |
| |
| The following command will create the set of @file{ALI} files needed for |
| @code{gnatelim}: |
| |
| @smallexample |
| $ gnatmake ^-c Main_Prog^/ACTIONS=COMPILE MAIN_PROG^ |
| @end smallexample |
| |
| Note that @code{gnatelim} does not need object files. |
| |
| @node Running gnatelim |
| @subsection Running @code{gnatelim} |
| |
| @noindent |
| @code{gnatelim} has the following command-line interface: |
| |
| @smallexample |
| $ gnatelim [@var{switches}] ^-main^?MAIN^=@var{main_unit_name} @{@var{filename}@} @r{[}-cargs @var{gcc_switches}@r{]} |
| @end smallexample |
| |
| @noindent |
| @var{main_unit_name} should be a name of a source file that contains the main |
| subprogram of a program (partition). |
| |
| Each @var{filename} is the name (including the extension) of a source |
| file to process. ``Wildcards'' are allowed, and |
| the file name may contain path information. |
| |
| @samp{@var{gcc_switches}} is a list of switches for |
| @command{gcc}. They will be passed on to all compiler invocations made by |
| @command{gnatelim} to generate the ASIS trees. Here you can provide |
| @option{^-I^/INCLUDE_DIRS=^} switches to form the source search path, |
| use the @option{-gnatec} switch to set the configuration file, |
| use the @option{-gnat05} switch if sources should be compiled in |
| Ada 2005 mode etc. |
| |
| @code{gnatelim} has the following switches: |
| |
| @table @option |
| @c !sort! |
| @item ^-files^/FILES^=@var{filename} |
| @cindex @option{^-files^/FILES^} (@code{gnatelim}) |
| Take the argument source files from the specified file. This file should be an |
| ordinary text file containing file names separated by spaces or |
| line breaks. You can use this switch more than once in the same call to |
| @command{gnatelim}. You also can combine this switch with |
| an explicit list of files. |
| |
| @item ^-log^/LOG^ |
| @cindex @option{^-log^/LOG^} (@command{gnatelim}) |
| Duplicate all the output sent to @file{stderr} into a log file. The log file |
| is named @file{gnatelim.log} and is located in the current directory. |
| |
| @item ^-log^/LOGFILE^=@var{filename} |
| @cindex @option{^-log^/LOGFILE^} (@command{gnatelim}) |
| Duplicate all the output sent to @file{stderr} into a specified log file. |
| |
| @cindex @option{^--no-elim-dispatch^/NO_DISPATCH^} (@command{gnatelim}) |
| @item ^--no-elim-dispatch^/NO_DISPATCH^ |
| Do not generate pragmas for dispatching operations. |
| |
| @item ^--ignore^/IGNORE^=@var{filename} |
| @cindex @option{^--ignore^/IGNORE^} (@command{gnatelim}) |
| Do not generate pragmas for subprograms declared in the sources |
| listed in a specified file |
| |
| @cindex @option{^-o^/OUTPUT^} (@command{gnatelim}) |
| @item ^-o^/OUTPUT^=@var{report_file} |
| Put @command{gnatelim} output into a specified file. If this file already exists, |
| it is overridden. If this switch is not used, @command{gnatelim} outputs its results |
| into @file{stderr} |
| |
| @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. |
| |
| @cindex @option{^-t^/TIME^} (@command{gnatelim}) |
| @item ^-t^/TIME^ |
| Print out execution time. |
| |
| @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 ^-wq^/WARNINGS=QUIET^ |
| @cindex @option{^-wq^/WARNINGS=QUIET^} (@command{gnatelim}) |
| Quiet warning mode - some warnings are suppressed. In particular warnings that |
| indicate that the analysed set of sources is incomplete to make up a |
| partition and that some subprogram bodies are missing are not generated. |
| @end table |
| |
| @noindent |
| Note: to invoke @command{gnatelim} with a project file, use the @code{gnat} |
| driver (see @ref{The GNAT Driver and Project Files}). |
| |
| @node Processing Precompiled Libraries |
| @subsection Processing Precompiled Libraries |
| |
| @noindent |
| If some program uses a precompiled Ada library, it can be processed by |
| @code{gnatelim} in a usual way. @code{gnatelim} will newer generate an |
| Eliminate pragma for a subprogram if the body of this subprogram has not |
| been analysed, this is a typical case for subprograms from precompiled |
| libraries. Switch @option{^-wq^/WARNINGS=QUIET^} may be used to suppress |
| warnings about missing source files and non-analyzed subprogram bodies |
| that can be generated when processing precompiled Ada libraries. |
| |
| @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 |
| main.adb:4:08: cannot reference subprogram "P" eliminated at elim.out:5 |
| @end smallexample |
| |
| @noindent |
| You will need to manually remove the wrong @code{Eliminate} pragmas from |
| the configuration file indicated in the error message. You should recompile |
| your program from scratch after that, because you need a consistent |
| configuration file(s) 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 configuration file containing |
| pragmas Eliminate generated by gnatelim. If these pragmas are placed in |
| @file{gnat.adc} file located in your current directory, just do: |
| |
| @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 configuration file. |
| |
| @node Summary of the gnatelim Usage Cycle |
| @subsection Summary of the @code{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 |
| Create a complete set of @file{ALI} files (if the program has not been |
| built already) |
| |
| @smallexample |
| $ gnatmake ^-c main_prog^/ACTIONS=COMPILE MAIN_PROG^ |
| @end smallexample |
| |
| @item |
| Generate a list of @code{Eliminate} pragmas in default configuration file |
| @file{gnat.adc} in the current directory |
| @smallexample |
| @ifset vms |
| $ PIPE GNAT ELIM MAIN_PROG > GNAT.ADC |
| @end ifset |
| @ifclear vms |
| $ gnatelim main_prog >@r{[}>@r{]} 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 Size of Executables with unused subprogram/data elimination |
| @section Reducing 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:: |
| * Example of unused subprogram/data elimination:: |
| @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 available on all Linux platforms except for the IA-64 |
| architecture and on all cross platforms using the ELF binary file format. |
| In both cases GNU binutils version 2.16 or later are required to enable it. |
| |
| @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 @command{gnatmake}. This will perform a |
| garbage collection of code and data never referenced. |
| |
| If the linker performs a partial link (@option{-r} ld linker option), then you |
| will need to provide one or several entry point using the |
| @option{-e} / @option{--entry} ld option. |
| |
| 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 on some platforms. This allows you to eliminate the unused code |
| and data of the GNAT library from your executable. |
| |
| @node Example of unused subprogram/data elimination |
| @subsection Example of unused subprogram/data elimination |
| |
| @noindent |
| Here is a simple example: |
| |
| @smallexample @c ada |
| with Aux; |
| |
| procedure Test is |
| begin |
| Aux.Used (10); |
| end Test; |
| |
| package Aux is |
| Used_Data : Integer; |
| Unused_Data : Integer; |
| |
| procedure Used (Data : Integer); |
| procedure Unused (Data : Integer); |
| end Aux; |
| |
| package body Aux is |
| procedure Used (Data : Integer) is |
| begin |
| Used_Data := Data; |
| end Used; |
| |
| procedure Unused (Data : Integer) is |
| begin |
| Unused_Data := Data; |
| end Unused; |
| end Aux; |
| @end smallexample |
| |
| @noindent |
| @code{Unused} and @code{Unused_Data} are never referenced in this code |
| excerpt, and hence they may be safely removed from the final executable. |
| |
| @smallexample |
| $ gnatmake test |
| |
| $ nm test | grep used |
| 020015f0 T aux__unused |
| 02005d88 B aux__unused_data |
| 020015cc T aux__used |
| 02005d84 B aux__used_data |
| |
| $ gnatmake test -cargs -fdata-sections -ffunction-sections \ |
| -largs -Wl,--gc-sections |
| |
| $ nm test | grep used |
| 02005350 T aux__used |
| 0201ffe0 B aux__used_data |
| @end smallexample |
| |
| @noindent |
| It can be observed that the procedure @code{Unused} and the object |
| @code{Unused_Data} are removed by the linker when using the |
| appropriate options. |
| |
| @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. |
| |
| Note that if your file containing multiple units starts with a byte order |
| mark (BOM) specifying UTF-8 encoding, then the files generated by gnatchop |
| will each start with a copy of this BOM, meaning that they can be compiled |
| automatically in UTF-8 mode without needing to specify an explicit encoding. |
| |
| @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 |
| @c $ gnatchop switches @var{file name} @r{[}@var{file name} @dots{}@r{]} |
| @c @ovar{directory} |
| @c Expanding @ovar macro inline (explanation in macro def comments) |
| $ gnatchop switches @var{file name} @r{[}@var{file name} @dots{}@r{]} |
| @r{[}@var{directory}@r{]} |
| @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 --version |
| @cindex @option{--version} @command{gnatchop} |
| Display Copyright and version, then exit disregarding all other options. |
| |
| @item --help |
| @cindex @option{--help} @command{gnatchop} |
| If @option{--version} was not used, display usage, then exit disregarding |
| all other options. |
| |
| @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 -gnat@var{xxx} |
| This passes the given @option{-gnat@var{xxx}} switch to @code{gnat} which is |
| used to parse the given file. Not all @var{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=@var{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 |
| @command{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 |
| Configuration pragmas include those pragmas described as |
| such in the Ada Reference Manual, as well as |
| implementation-dependent pragmas that are configuration pragmas. |
| @xref{Implementation Defined Pragmas,,, gnat_rm, 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 GNAT: |
| |
| @smallexample |
| Ada_83 |
| Ada_95 |
| Ada_05 |
| Ada_2005 |
| Ada_12 |
| Ada_2012 |
| Annotate |
| Assertion_Policy |
| Assume_No_Invalid_Values |
| C_Pass_By_Copy |
| Check_Name |
| Check_Policy |
| Compile_Time_Error |
| Compile_Time_Warning |
| Compiler_Unit |
| Component_Alignment |
| Convention_Identifier |
| Debug_Policy |
| Detect_Blocking |
| Default_Storage_Pool |
| Discard_Names |
| Elaboration_Checks |
| Eliminate |
| Extend_System |
| Extensions_Allowed |
| External_Name_Casing |
| Fast_Math |
| Favor_Top_Level |
| Float_Representation |
| Implicit_Packing |
| Initialize_Scalars |
| Interrupt_State |
| License |
| Locking_Policy |
| Long_Float |
| No_Run_Time |
| No_Strict_Aliasing |
| Normalize_Scalars |
| Optimize_Alignment |
| Persistent_BSS |
| Polling |
| Priority_Specific_Dispatching |
| Profile |
| Profile_Warnings |
| Propagate_Exceptions |
| Queuing_Policy |
| Ravenscar |
| Restricted_Run_Time |
| Restrictions |
| Restrictions_Warnings |
| Reviewable |
| Short_Circuit_And_Or |
| Source_File_Name |
| Source_File_Name_Project |
| Style_Checks |
| Suppress |
| Suppress_Exception_Locations |
| Task_Dispatching_Policy |
| Universal_Data |
| Unsuppress |
| Use_VADS_Size |
| Validity_Checks |
| Warnings |
| Wide_Character_Encoding |
| |
| @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, or they can appear in a configuration pragma file to 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. |
| |
| In the case of @code{Restrictions} pragmas appearing as configuration |
| pragmas in individual compilation units, the exact handling depends on |
| the type of restriction. |
| |
| Restrictions that require partition-wide consistency (like |
| @code{No_Tasking}) are |
| recognized wherever they appear |
| and can be freely inherited, e.g. from a with'ed unit to the with'ing |
| unit. This makes sense since the binder will in any case insist on seeing |
| consistent use, so any unit not conforming to any restrictions that are |
| anywhere in the partition will be rejected, and you might as well find |
| that out at compile time rather than at bind time. |
| |
| For restrictions that do not require partition-wide consistency, e.g. |
| SPARK or No_Implementation_Attributes, in general the restriction applies |
| only to the unit in which the pragma appears, and not to any other units. |
| |
| The exception is No_Elaboration_Code which always applies to the entire |
| object file from a compilation, i.e. to the body, spec, and all subunits. |
| This restriction can be specified in a configuration pragma file, or it |
| can be on the body and/or the spec (in eithe case it applies to all the |
| relevant units). It can appear on a subunit only if it has previously |
| appeared in the body of spec. |
| |
| @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}, additional files 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}, all of which |
| 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 |
| @c $ gnatname @ovar{switches} @var{naming_pattern} @ovar{naming_patterns} |
| @c @r{[}--and @ovar{switches} @var{naming_pattern} @ovar{naming_patterns}@r{]} |
| @c Expanding @ovar macro inline (explanation in macro def comments) |
| $ gnatname @r{[}@var{switches}@r{]} @var{naming_pattern} @r{[}@var{naming_patterns}@r{]} |
| @r{[}--and @r{[}@var{switches}@r{]} @var{naming_pattern} @r{[}@var{naming_patterns}@r{]}@r{]} |
| @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 (or single |
| quotes on Windows). |
| 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 |
| @code{gnatname} may be called with several sections of directories/patterns. |
| Sections are separated by switch @code{--and}. In each section, there must be |
| at least one pattern. If no directory is specified in a section, the current |
| directory (or the project directory is @code{-P} is used) is implied. |
| The options other that the directory switches and the patterns apply globally |
| even if they are in different sections. |
| |
| @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 switch @code{-P}, @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 --version |
| @cindex @option{--version} @command{gnatname} |
| Display Copyright and version, then exit disregarding all other options. |
| |
| @item --help |
| @cindex @option{--help} @command{gnatname} |
| If @option{--version} was not used, display usage, then exit disregarding |
| all other options. |
| |
| @item --and |
| Start another section of directories/patterns. |
| |
| @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 nonempty 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 nonempty 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 @file{.^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 ***************************************** |
| |
| @c ------ macros for projects.texi |
| @c These macros are needed when building the gprbuild documentation, but |
| @c should have no effect in the gnat user's guide |
| |
| @macro CODESAMPLE{TXT} |
| @smallexample |
| @group |
| \TXT\ |
| @end group |
| @end smallexample |
| @end macro |
| |
| @macro PROJECTFILE{TXT} |
| @CODESAMPLE{\TXT\} |
| @end macro |
| |
| @c simulates a newline when in a @CODESAMPLE |
| @macro NL{} |
| @end macro |
| |
| @macro TIP{TXT} |
| @quotation |
| @noindent |
| \TXT\ |
| @end quotation |
| @end macro |
| |
| @macro TIPHTML{TXT} |
| \TXT\ |
| @end macro |
| |
| @macro IMPORTANT{TXT} |
| @quotation |
| @noindent |
| \TXT\ |
| @end quotation |
| |
| @end macro |
| |
| @macro NOTE{TXT} |
| @quotation |
| @noindent |
| \TXT\ |
| @end quotation |
| @end macro |
| |
| @include projects.texi |
| |
| @c ***************************************** |
| @c * Cross-referencing tools |
| @c ***************************************** |
| |
| @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. |
| |
| Note: to invoke @code{gnatxref} or @code{gnatfind} with a project file, |
| use the @code{gnat} driver (see @ref{The GNAT Driver and Project Files}). |
| |
| @menu |
| * Switches for gnatxref:: |
| * Switches for gnatfind:: |
| * Project Files for gnatxref and gnatfind:: |
| * Regular Expressions in gnatfind and gnatxref:: |
| * Examples of gnatxref Usage:: |
| * Examples of gnatfind Usage:: |
| @end menu |
| |
| @node Switches for gnatxref |
| @section @code{gnatxref} Switches |
| |
| @noindent |
| The command invocation for @code{gnatxref} is: |
| @smallexample |
| @c $ gnatxref @ovar{switches} @var{sourcefile1} @r{[}@var{sourcefile2} @dots{}@r{]} |
| @c Expanding @ovar macro inline (explanation in macro def comments) |
| $ gnatxref @r{[}@var{switches}@r{]} @var{sourcefile1} @r{[}@var{sourcefile2} @dots{}@r{]} |
| @end smallexample |
| |
| @noindent |
| where |
| |
| @table @var |
| @item sourcefile1 |
| @itemx 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 --version |
| @cindex @option{--version} @command{gnatxref} |
| Display Copyright and version, then exit disregarding all other options. |
| |
| @item --help |
| @cindex @option{--help} @command{gnatxref} |
| If @option{--version} was not used, display usage, then exit disregarding |
| all other options. |
| |
| @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 --ext=@var{extension} |
| @cindex @option{--ext} (@command{gnatxref}) |
| Specify an alternate ali file extension. The default is @code{ali} and other |
| extensions (e.g. @code{sli} for SPARK library files) may be specified via this |
| switch. Note that if this switch overrides the default, which means that only |
| the new extension will be considered. |
| |
| @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{GNAT Project Manager}. |
| 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 Switches for gnatfind |
| @section @code{gnatfind} Switches |
| |
| @noindent |
| The command line for @code{gnatfind} is: |
| |
| @smallexample |
| @c $ gnatfind @ovar{switches} @var{pattern}@r{[}:@var{sourcefile}@r{[}:@var{line}@r{[}:@var{column}@r{]]]} |
| @c @r{[}@var{file1} @var{file2} @dots{}] |
| @c Expanding @ovar macro inline (explanation in macro def comments) |
| $ gnatfind @r{[}@var{switches}@r{]} @var{pattern}@r{[}:@var{sourcefile}@r{[}:@var{line}@r{[}:@var{column}@r{]]]} |
| @r{[}@var{file1} @var{file2} @dots{}@r{]} |
| @end smallexample |
| |
| @noindent |
| where |
| |
| @table @var |
| @item pattern |
| An entity will be output only if it matches the regular expression found |
| in @var{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{@var{sourcefile}}, at line @var{line} |
| and column @var{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 @dots{} |
| 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 @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}. |
| |
| The location of the spec of the entity will always be displayed, even if it |
| isn't in one of @file{@var{file1}}, @file{@var{file2}},@enddots{} 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! |
| |
| @cindex @option{--version} @command{gnatfind} |
| Display Copyright and version, then exit disregarding all other options. |
| |
| @item --help |
| @cindex @option{--help} @command{gnatfind} |
| If @option{--version} was not used, display usage, then exit disregarding |
| all other options. |
| |
| @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 --ext=@var{extension} |
| @cindex @option{--ext} (@command{gnatfind}) |
| Specify an alternate ali file extension. The default is @code{ali} and other |
| extensions (e.g. @code{sli} for SPARK library files) may be specified via this |
| switch. Note that if this switch overrides the default, which means that only |
| the new extension will be considered. |
| |
| @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{GNAT Project Manager}) 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 GPS, 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 @dots{}) |
| |
| 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 @samp{abcde} and @samp{fghi}, |
| |
| @item abc*d |
| will match any string like @samp{abd}, @samp{abcd}, @samp{abccd}, |
| @samp{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 |
| is 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 @command{vi}. Note that the standard version of @command{vi} |
| will not work properly with overloaded symbols. Consider using another |
| free implementation of @command{vi}, such as @command{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 @command{vi}, you can then use the command @samp{:tag @var{entity}} |
| (replacing @var{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. |
| |
| @command{gnatpp} cannot process sources that contain |
| preprocessing directives. |
| |
| 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 |
| (see @ref{The GNAT Driver and Project Files}). |
| |
| The @command{gnatpp} command has the form |
| |
| @smallexample |
| @c $ gnatpp @ovar{switches} @var{filename} |
| @c Expanding @ovar macro inline (explanation in macro def comments) |
| $ gnatpp @r{[}@var{switches}@r{]} @var{filename} @r{[}-cargs @var{gcc_switches}@r{]} |
| @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 |
| |
| @item |
| @samp{@var{gcc_switches}} is a list of switches for |
| @command{gcc}. They will be passed on to all compiler invocations made by |
| @command{gnatelim} to generate the ASIS trees. Here you can provide |
| @option{^-I^/INCLUDE_DIRS=^} switches to form the source search path, |
| use the @option{-gnatec} switch to set the configuration file, |
| use the @option{-gnat05} switch if sources should be compiled in |
| Ada 2005 mode etc. |
| @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{^-ne@var{x}^/ENUM_CASING^} (@command{gnatpp}) |
| @item ^-neD^/ENUM_CASING=AS_DECLARED^ |
| Enumeration literal casing for defining occurrences are as they appear in the |
| source file. Overrides ^-n^/NAME_CASING^ casing setting. |
| |
| @item ^-neU^/ENUM_CASING=UPPER_CASE^ |
| Enumeration literals are in upper case. Overrides ^-n^/NAME_CASING^ casing |
| setting. |
| |
| @item ^-neL^/ENUM_CASING=LOWER_CASE^ |
| Enumeration literals are in lower case. Overrides ^-n^/NAME_CASING^ casing |
| setting. |
| |
| @item ^-neM^/ENUM_CASING=MIXED_CASE^ |
| Enumeration literals are in mixed case. Overrides ^-n^/NAME_CASING^ casing |
| setting. |
| |
| @cindex @option{^-nt@var{x}^/TYPE_CASING^} (@command{gnatpp}) |
| @item ^-neD^/TYPE_CASING=AS_DECLARED^ |
| Names introduced by type and subtype declarations are always |
| cased as they appear in the declaration in the source file. |
| Overrides ^-n^/NAME_CASING^ casing setting. |
| |
| @item ^-ntU^/TYPE_CASING=UPPER_CASE^ |
| Names introduced by type and subtype declarations are always in |
| upper case. Overrides ^-n^/NAME_CASING^ casing setting. |
| |
| @item ^-ntL^/TYPE_CASING=LOWER_CASE^ |
| Names introduced by type and subtype declarations are always in |
| lower case. Overrides ^-n^/NAME_CASING^ casing setting. |
| |
| @item ^-ntM^/TYPE_CASING=MIXED_CASE^ |
| Names introduced by type and subtype declarations are always in |
| mixed case. Overrides ^-n^/NAME_CASING^ casing setting. |
| |
| @item ^-nnU^/NUMBER_CASING=UPPER_CASE^ |
| Names introduced by number declarations are always in |
| upper case. Overrides ^-n^/NAME_CASING^ casing setting. |
| |
| @item ^-nnL^/NUMBER_CASING=LOWER_CASE^ |
| Names introduced by number declarations are always in |
| lower case. Overrides ^-n^/NAME_CASING^ casing setting. |
| |
| @item ^-nnM^/NUMBER_CASING=MIXED_CASE^ |
| Names introduced by number declarations are always in |
| mixed case. Overrides ^-n^/NAME_CASING^ casing setting. |
| |
| @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 |
| |
| @item ^-c5^/COMMENTS_LAYOUT=KEEP_SPECIAL^ |
| Keep unchanged special form comments |
| |
| @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 spec occupies more than one line. |
| |
| @cindex @option{^--separate-label^/SEPARATE_LABEL^} (@command{gnatpp}) |
| @item ^--separate-label^/SEPARATE_LABEL^ |
| Place statement label(s) on a separate line, with the following statement |
| on the next line. |
| |
| @cindex @option{^--separate-loop-then^/SEPARATE_LOOP_THEN^} (@command{gnatpp}) |
| @item ^--separate-loop-then^/SEPARATE_LOOP_THEN^ |
| Place the keyword @code{loop} in FOR and WHILE loop statements and the |
| keyword @code{then} in IF statements on a separate line. |
| |
| @cindex @option{^--no-separate-loop-then^/NO_SEPARATE_LOOP_THEN^} (@command{gnatpp}) |
| @item ^--no-separate-loop-then^/NO_SEPARATE_LOOP_THEN^ |
| Do not place the keyword @code{loop} in FOR and WHILE loop statements and the |
| keyword @code{then} in IF statements on a separate line. This option is |
| incompatible with @option{^--separate-loop-then^/SEPARATE_LOOP_THEN^} option. |
| |
| @cindex @option{^--use-on-new-line^/USE_ON_NEW_LINE^} (@command{gnatpp}) |
| @item ^--use-on-new-line^/USE_ON_NEW_LINE^ |
| Start each USE clause in a context clause from a separate line. |
| |
| @cindex @option{^--separate-stmt-name^/STMT_NAME_ON_NEW_LINE^} (@command{gnatpp}) |
| @item ^--separate-stmt-name^/STMT_NAME_ON_NEW_LINE^ |
| Use a separate line for a loop or block statement name, but do not use an extra |
| indentation level for the statement itself. |
| |
| @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@var{nnn}^/LINE_LENGTH_MAX=@var{nnn}^ |
| @cindex @option{^-M^/LINE_LENGTH^} (@command{gnatpp}) |
| Maximum line length, @var{nnn} from 32@dots{}256, the default value is 79 |
| |
| @item ^-i@var{nnn}^/INDENTATION_LEVEL=@var{nnn}^ |
| @cindex @option{^-i^/INDENTATION_LEVEL^} (@command{gnatpp}) |
| Indentation level, @var{nnn} from 1@dots{}9, the default value is 3 |
| |
| @item ^-cl@var{nnn}^/CONTINUATION_INDENT=@var{nnn}^ |
| @cindex @option{^-cl^/CONTINUATION_INDENT^} (@command{gnatpp}) |
| Indentation level for continuation lines (relative to the line being |
| continued), @var{nnn} from 1@dots{}9. |
| The default |
| value is one less than 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@var{nnn}^/MAX_INDENT=@var{nnn}^ |
| @cindex @option{^-T^/MAX_INDENT^} (@command{gnatpp}) |
| Do not use an additional indentation level for @b{case} alternatives |
| and variants if there are @var{nnn} or more (the default |
| value is 10). |
| If @var{nnn} is 0, an additional indentation level is |
| used for @b{case} alternatives and variants regardless of their number. |
| |
| @item ^--call_threshold=@var{nnn}^/MAX_ACT=@var{nnn}^ |
| @cindex @option{^--call_threshold^/MAX_ACT^} (@command{gnatpp}) |
| If the number of parameter associations is greater than @var{nnn} and if at |
| least one association uses named notation, start each association from |
| a new line. If @var{nnn} is 0, no check for the number of associations |
| is made, this is the default. |
| |
| @item ^--par_threshold=@var{nnn}^/MAX_PAR=@var{nnn}^ |
| @cindex @option{^--par_threshold^/MAX_PAR^} (@command{gnatpp}) |
| If the number of parameter specifications is greater than @var{nnn} |
| (or equal to @var{nnn} in case of a function), start each specification from |
| a new line. The default for @var{nnn} is 3. |
| @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^/REPLACE_NO_BACKUP^ |
| @cindex @option{^-rnb^/REPLACE_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 |
| |
| @item ^-W^/RESULT_ENCODING=^@var{e} |
| @cindex @option{^-W^/RESULT_ENCODING=^} (@command{gnatpp}) |
| Specify the wide character encoding method used to write the code in the |
| result file |
| @var{e} is one of the following: |
| |
| @itemize @bullet |
| |
| @item ^h^HEX^ |
| Hex encoding |
| |
| @item ^u^UPPER^ |
| Upper half encoding |
| |
| @item ^s^SHIFT_JIS^ |
| Shift/JIS encoding |
| |
| @item ^e^EUC^ |
| EUC encoding |
| |
| @item ^8^UTF8^ |
| UTF-8 encoding |
| |
| @item ^b^BRACKETS^ |
| Brackets encoding (default value) |
| @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^} |
| and |
| @option{^-W^/RESULT_ENCODING^} |
| 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{filename}^ |
| @cindex @option{^-files^/FILES^} (@code{gnatpp}) |
| Take the argument source files from the specified file. This file should be an |
| ordinary text file containing file names separated by spaces or |
| line breaks. You can use this switch more than once in the same call to |
| @command{gnatpp}. You also can combine this switch with an 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). |
| |
| @noindent |
| The @option{^-c5^/COMMENTS_LAYOUT=KEEP_SPECIAL^} switch specifies, that comments |
| that has a special format (that is, a character that is neither a letter nor digit |
| not white space nor line break immediately following the leading @code{--} of |
| the comment) should be without any change moved from the argument source |
| into reformatted source. This switch allows to preserve comments that are used |
| as a special marks in the code (e.g.@: SPARK annotation). |
| |
| @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. |
| |
| Note that the layout specified by |
| @option{^--separate-stmt-name^/STMT_NAME_ON_NEW_LINE^} |
| for named block and loop statements overrides the layout defined by these |
| constructs by @option{^-l1^/CONSTRUCT_LAYOUT=GNAT^}, |
| @option{^-l2^/CONSTRUCT_LAYOUT=COMPACT^} or |
| @option{^-l3^/CONSTRUCT_LAYOUT=UNCOMPACT^} option. |
| |
| @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 (see @ref{The GNAT Driver and Project Files}). |
| |
| The @command{gnatmetric} command has the form |
| |
| @smallexample |
| @c $ gnatmetric @ovar{switches} @{@var{filename}@} @r{[}-cargs @var{gcc_switches}@r{]} |
| @c Expanding @ovar macro inline (explanation in macro def comments) |
| $ gnatmetric @r{[}@var{switches}@r{]} @{@var{filename}@} @r{[}-cargs @var{gcc_switches}@r{]} |
| @end smallexample |
| |
| @noindent |
| where |
| @itemize @bullet |
| @item |
| @var{switches} specify the metrics to compute and define the destination for |
| the output |
| |
| @item |
| Each @var{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 @var{filename} is supplied, then the @var{switches} list must contain |
| at least one |
| @option{-files} switch (@pxref{Other gnatmetric Switches}). |
| Including both a @option{-files} switch and one or more |
| @var{filename} arguments is permitted. |
| |
| @item |
| @samp{@var{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, |
| use the @option{-gnat05} switch if sources should be compiled in |
| Ada 2005 mode etc. |
| @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:: |
| * Specifying a set of metrics to compute:: |
| * Other gnatmetric Switches:: |
| * Generate project-wide metrics:: |
| @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, except for the case when the set of metrics |
| specified by gnatmetric parameters consists only of metrics that are computed |
| for the whole set of analyzed sources, but not for each Ada source. |
| 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{^-xs^/XSD^} (@command{gnatmetric}) |
| @item ^-xs^/XSD^ |
| Generate the XML output and the XML schema file that describes the structure |
| of the XML metric report, this schema is assigned to the XML file. The schema |
| file has the same name as the XML output file with @file{.xml} suffix replaced |
| with @file{.xsd} |
| |
| @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 text 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) specs 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 Specifying a set of metrics to compute |
| @subsection Specifying a set of metrics to compute |
| |
| @noindent |
| By default all the metrics are computed and reported. The switches |
| described in this subsection allow you to control, on an individual |
| basis, whether metrics are computed and |
| reported. If at least one positive metric |
| switch is specified (that is, a switch that defines that a given |
| metric or set of metrics is to be computed), then only |
| explicitly specified metrics are reported. |
| |
| @menu |
| * Line Metrics Control:: |
| * Syntax Metrics Control:: |
| * Complexity Metrics Control:: |
| * Coupling Metrics Control:: |
| @end menu |
| |
| @node Line Metrics Control |
| @subsubsection 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 comment percentage: the ratio between the number of lines that contain |
| comments and the number of all non-blank lines, expressed as a percentage; |
| |
| @item |
| the number of empty lines and lines containing only space characters and/or |
| format effectors (blank lines) |
| |
| @item |
| the average number of code lines in subprogram bodies, task bodies, entry |
| bodies and statement sequences in package bodies (this metric is only computed |
| across the whole set of the analyzed units) |
| |
| @end itemize |
| |
| @noindent |
| @command{gnatmetric} sums the values of the line metrics for all the |
| files being processed and then generates the cumulative results. The tool |
| also computes for all the files being processed the average number of code |
| lines in bodies. |
| |
| You can use the following switches to select the specific line metrics |
| to be computed and reported. |
| |
| @table @option |
| @cindex @option{^--lines@var{x}^/LINE_COUNT_METRICS^} (@command{gnatmetric}) |
| |
| @ifclear vms |
| @cindex @option{--no-lines@var{x}} |
| @end ifclear |
| |
| @item ^--lines-all^/LINE_COUNT_METRICS=ALL^ |
| Report all the line metrics |
| |
| @item ^--no-lines-all^/LINE_COUNT_METRICS=NONE^ |
| Do not report any of line metrics |
| |
| @item ^--lines^/LINE_COUNT_METRICS=ALL_LINES^ |
| Report the number of all lines |
| |
| @item ^--no-lines^/LINE_COUNT_METRICS=NOALL_LINES^ |
| Do not report the number of all lines |
| |
| @item ^--lines-code^/LINE_COUNT_METRICS=CODE_LINES^ |
| Report the number of code lines |
| |
| @item ^--no-lines-code^/LINE_COUNT_METRICS=NOCODE_LINES^ |
| Do not report the number of code lines |
| |
| @item ^--lines-comment^/LINE_COUNT_METRICS=COMMENT_LINES^ |
| Report the number of comment lines |
| |
| @item ^--no-lines-comment^/LINE_COUNT_METRICS=NOCOMMENT_LINES^ |
| Do not report the number of comment lines |
| |
| @item ^--lines-eol-comment^/LINE_COUNT_METRICS=CODE_COMMENT_LINES^ |
| Report the number of code lines containing |
| end-of-line comments |
| |
| @item ^--no-lines-eol-comment^/LINE_COUNT_METRICS=NOCODE_COMMENT_LINES^ |
| Do not report the number of code lines containing |
| end-of-line comments |
| |
| @item ^--lines-ratio^/LINE_COUNT_METRICS=COMMENT_PERCENTAGE^ |
| Report the comment percentage in the program text |
| |
| @item ^--no-lines-ratio^/LINE_COUNT_METRICS=NOCOMMENT_PERCENTAGE^ |
| Do not report the comment percentage in the program text |
| |
| @item ^--lines-blank^/LINE_COUNT_METRICS=BLANK_LINES^ |
| Report the number of blank lines |
| |
| @item ^--no-lines-blank^/LINE_COUNT_METRICS=NOBLANK_LINES^ |
| Do not report the number of blank lines |
| |
| @item ^--lines-average^/LINE_COUNT_METRICS=AVERAGE_BODY_LINES^ |
| Report the average number of code lines in subprogram bodies, task bodies, |
| entry bodies and statement sequences in package bodies. The metric is computed |
| and reported for the whole set of processed Ada sources only. |
| |
| @item ^--no-lines-average^/LINE_COUNT_METRICS=NOAVERAGE_BODY_LINES^ |
| Do not report the average number of code lines in subprogram bodies, |
| task bodies, entry bodies and statement sequences in package bodies. |
| |
| @end table |
| |
| @node Syntax Metrics Control |
| @subsubsection 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. Note |
| that the definition of declarations is the one given in the reference |
| manual: |
| |
| @noindent |
| ``Each of the following is defined to be a declaration: any basic_declaration; |
| an enumeration_literal_specification; a discriminant_specification; |
| a component_declaration; a loop_parameter_specification; a |
| parameter_specification; a subprogram_body; an entry_declaration; |
| an entry_index_specification; a choice_parameter_specification; |
| a generic_formal_parameter_declaration.'' |
| |
| This means for example that each enumeration literal adds one to the count, |
| as well as each subprogram parameter. |
| |
| Thus the results from this metric will be significantly greater than might |
| be expected from a naive view of counting semicolons. |
| |
| @item Maximal static nesting level of inner program units |
| According to |
| @cite{Ada 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 specs. It is the |
| number of subprograms and generic subprograms declared in the visible |
| part (including the visible part of 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 specs 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. |
| |
| @table @option |
| |
| @cindex @option{^--syntax@var{x}^/SYNTAX_METRICS^} (@command{gnatmetric}) |
| |
| @ifclear vms |
| @cindex @option{--no-syntax@var{x}} (@command{gnatmetric}) |
| @end ifclear |
| |
| @item ^--syntax-all^/SYNTAX_METRICS=ALL^ |
| Report all the syntax metrics |
| |
| @item ^--no-syntax-all^/SYNTAX_METRICS=NONE^ |
| Do not report any of syntax metrics |
| |
| @item ^--declarations^/SYNTAX_METRICS=DECLARATIONS^ |
| Report the total number of declarations |
| |
| @item ^--no-declarations^/SYNTAX_METRICS=NODECLARATIONS^ |
| Do not report the total number of declarations |
| |
| @item ^--statements^/SYNTAX_METRICS=STATEMENTS^ |
| Report the total number of statements |
| |
| @item ^--no-statements^/SYNTAX_METRICS=NOSTATEMENTS^ |
| Do not report the total number of statements |
| |
| @item ^--public-subprograms^/SYNTAX_METRICS=PUBLIC_SUBPROGRAMS^ |
| Report the number of public subprograms in a compilation unit |
| |
| @item ^--no-public-subprograms^/SYNTAX_METRICS=NOPUBLIC_SUBPROGRAMS^ |
| Do not report the number of public subprograms in a compilation unit |
| |
| @item ^--all-subprograms^/SYNTAX_METRICS=ALL_SUBPROGRAMS^ |
| Report the number of all the subprograms in a compilation unit |
| |
| @item ^--no-all-subprograms^/SYNTAX_METRICS=NOALL_SUBPROGRAMS^ |
| Do not report the number of all the subprograms in a compilation unit |
| |
| @item ^--public-types^/SYNTAX_METRICS=PUBLIC_TYPES^ |
| Report the number of public types in a compilation unit |
| |
| @item ^--no-public-types^/SYNTAX_METRICS=NOPUBLIC_TYPES^ |
| Do not report the number of public types in a compilation unit |
| |
| @item ^--all-types^/SYNTAX_METRICS=ALL_TYPES^ |
| Report the number of all the types in a compilation unit |
| |
| @item ^--no-all-types^/SYNTAX_METRICS=NOALL_TYPES^ |
| Do not report the number of all the types in a compilation unit |
| |
| @item ^--unit-nesting^/SYNTAX_METRICS=UNIT_NESTING^ |
| Report the maximal program unit nesting level |
| |
| @item ^--no-unit-nesting^/SYNTAX_METRICS=UNIT_NESTING_OFF^ |
| Do not report the maximal program unit nesting level |
| |
| @item ^--construct-nesting^/SYNTAX_METRICS=CONSTRUCT_NESTING^ |
| Report the maximal construct nesting level |
| |
| @item ^--no-construct-nesting^/SYNTAX_METRICS=NOCONSTRUCT_NESTING^ |
| Do not report the maximal construct nesting level |
| |
| @end table |
| |
| @node Complexity Metrics Control |
| @subsubsection 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; |
| |
| @item |
| extra exit points (for subprograms); |
| @end itemize |
| |
| @noindent |
| The McCabe cyclomatic complexity metric is defined |
| in @url{http://www.mccabe.com/pdf/mccabe-nist235r.pdf} |
| |
| According to McCabe, both control statements and short-circuit control forms |
| should be taken into account when computing cyclomatic complexity. |
| For Ada 2012 we have also take into account conditional expressions |
| and quantified expressions. 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 |
| |
| The cyclomatic complexity is also computed for Ada 2012 expression functions. |
| An expression function cannot have statements as its components, so only one |
| metric value is computed as a cyclomatic complexity of an expression function. |
| |
| The origin of cyclomatic complexity metric is the need to estimate the number |
| of independent paths in the control flow graph that in turn gives the number |
| of tests needed to satisfy paths coverage testing completeness criterion. |
| Considered from the testing point of view, a static Ada @code{loop} (that is, |
| the @code{loop} statement having static subtype in loop parameter |
| specification) does not add to cyclomatic complexity. By providing |
| @option{^--no-static-loop^NO_STATIC_LOOP^} option a user |
| may specify that such loops should not be counted when computing the |
| cyclomatic complexity metric |
| |
| The Ada essential complexity metric is a McCabe cyclomatic complexity metric |
| counted for the code that is reduced by excluding all the pure structural Ada |
| control statements. An compound statement is considered as a non-structural |
| if it contains a @code{raise} or @code{return} statement as it subcomponent, |
| or if it contains a @code{goto} statement that transfers the control outside |
| the operator. A selective accept statement with @code{terminate} alternative |
| is considered as non-structural statement. When computing this metric, |
| @code{exit} statements are treated in the same way as @code{goto} |
| statements unless @option{^-ne^NO_EXITS_AS_GOTOS^} option is specified. |
| |
| The Ada essential complexity metric defined here is intended to quantify |
| the extent to which the software is unstructured. It is adapted from |
| the McCabe essential complexity metric defined in |
| @url{http://www.mccabe.com/pdf/mccabe-nist235r.pdf} but is modified to be more |
| suitable for typical Ada usage. For example, short circuit forms |
| are not penalized as unstructured in the Ada essential complexity metric. |
| |
| When computing cyclomatic and essential complexity, @command{gnatmetric} skips |
| the code in the exception handlers and in all the nested program units. The |
| code of assertions and predicates (that is, subprogram preconditions and |
| postconditions, subtype predicates and type invariants) is also skipped. |
| |
| By default, all the complexity metrics are computed and reported. |
| For more fine-grained control you can use |
| the following switches: |
| |
| @table @option |
| @cindex @option{^-complexity@var{x}^/COMPLEXITY_METRICS^} (@command{gnatmetric}) |
| |
| @ifclear vms |
| @cindex @option{--no-complexity@var{x}} |
| @end ifclear |
| |
| @item ^--complexity-all^/COMPLEXITY_METRICS=ALL^ |
| Report all the complexity metrics |
| |
| @item ^--no-complexity-all^/COMPLEXITY_METRICS=NONE^ |
| Do not report any of complexity metrics |
| |
| @item ^--complexity-cyclomatic^/COMPLEXITY_METRICS=CYCLOMATIC^ |
| Report the McCabe Cyclomatic Complexity |
| |
| @item ^--no-complexity-cyclomatic^/COMPLEXITY_METRICS=NOCYCLOMATIC^ |
| Do not report the McCabe Cyclomatic Complexity |
| |
| @item ^--complexity-essential^/COMPLEXITY_METRICS=ESSENTIAL^ |
| Report the Essential Complexity |
| |
| @item ^--no-complexity-essential^/COMPLEXITY_METRICS=NOESSENTIAL^ |
| Do not report the Essential Complexity |
| |
| @item ^--loop-nesting^/COMPLEXITY_METRICS=LOOP_NESTING_ON^ |
| Report maximal loop nesting level |
| |
| @item ^--no-loop-nesting^/COMPLEXITY_METRICS=NOLOOP_NESTING^ |
| Do not report maximal loop nesting level |
| |
| @item ^--complexity-average^/COMPLEXITY_METRICS=AVERAGE_COMPLEXITY^ |
| Report the average McCabe Cyclomatic Complexity for all the subprogram bodies, |
| task bodies, entry bodies and statement sequences in package bodies. |
| The metric is computed and reported for whole set of processed Ada sources |
| only. |
| |
| @item ^--no-complexity-average^/COMPLEXITY_METRICS=NOAVERAGE_COMPLEXITY^ |
| Do not report the average McCabe Cyclomatic Complexity for all the subprogram |
| bodies, task bodies, entry bodies and statement sequences in package bodies |
| |
| @cindex @option{^-ne^/NO_EXITS_AS_GOTOS^} (@command{gnatmetric}) |
| @item ^-ne^/NO_EXITS_AS_GOTOS^ |
| Do not consider @code{exit} statements as @code{goto}s when |
| computing Essential Complexity |
| |
| @cindex @option{^--no-static-loop^/NO_STATIC_LOOP^} (@command{gnatmetric}) |
| @item ^--no-static-loop^/NO_STATIC_LOOP^ |
| Do not consider static loops when computing cyclomatic complexity |
| |
| @item ^--extra-exit-points^/EXTRA_EXIT_POINTS^ |
| Report the extra exit points for subprogram bodies. As an exit point, this |
| metric counts @code{return} statements and raise statements in case when the |
| raised exception is not handled in the same body. In case of a function this |
| metric subtracts 1 from the number of exit points, because a function body |
| must contain at least one @code{return} statement. |
| |
| @item ^--no-extra-exit-points^/NOEXTRA_EXIT_POINTS^ |
| Do not report the extra exit points for subprogram bodies |
| @end table |
| |
| |
| @node Coupling Metrics Control |
| @subsubsection Coupling Metrics Control |
| @cindex Coupling metrics control in @command{gnatmetric} |
| |
| @noindent |
| @cindex Coupling metrics (in in @command{gnatmetric}) |
| Coupling metrics measure the dependencies between a given entity and other |
| entities the program consists of. The goal of these metrics is to estimate the |
| stability of the whole program considered as the collection of entities |
| (modules, classes etc.). |
| |
| Gnatmetric computes the following coupling metrics: |
| |
| @itemize @bullet |
| |
| @item |
| @emph{object-oriented coupling} - for classes in traditional object-oriented |
| sense; |
| |
| @item |
| @emph{unit coupling} - for all the program units making up a program; |
| |
| @item |
| @emph{control coupling} - this metric counts dependencies between a unit and |
| only those units that define subprograms; |
| @end itemize |
| |
| @noindent |
| Two kinds of coupling metrics are computed: |
| |
| @table @asis |
| @item fan-out coupling (efferent coupling) |
| @cindex fan-out coupling |
| @cindex efferent coupling |
| the number of entities the given entity depends upon. It |
| estimates in what extent the given entity depends on the changes in |
| ``external world'' |
| |
| @item fan-in coupling (afferent coupling) |
| @cindex fan-in coupling |
| @cindex afferent coupling |
| the number of entities that depend on a given entity. |
| It estimates in what extent the ``external world'' depends on the changes in a |
| given entity |
| @end table |
| |
| @noindent |
| |
| Object-oriented coupling metrics are metrics that measure the dependencies |
| between a given class (or a group of classes) and the other classes in the |
| program. In this subsection the term ``class'' is used in its traditional |
| object-oriented programming sense (an instantiable module that contains data |
| and/or method members). A @emph{category} (of classes) is a group of closely |
| related classes that are reused and/or modified together. |
| |
| A class @code{K}'s fan-out coupling is the number of classes |
| that @code{K} depends upon. |
| A category's fan-out coupling is the number of classes outside the |
| category that the classes inside the category depend upon. |
| |
| A class @code{K}'s fan-in coupling is the number of classes |
| that depend upon @code{K}. |
| A category's fan-in coupling is the number of classes outside the |
| category that depend on classes belonging to the category. |
| |
| Ada's implementation of the object-oriented paradigm does not use the |
| traditional class notion, so the definition of the coupling |
| metrics for Ada maps the class and class category notions |
| onto Ada constructs. |
| |
| For the coupling metrics, several kinds of modules -- a library package, |
| a library generic package, and a library generic package instantiation -- |
| that define a tagged type or an interface type are |
| considered to be a class. A category consists of a library package (or |
| a library generic package) that defines a tagged or an interface type, |
| together with all its descendant (generic) packages that define tagged |
| or interface types. That is a |
| category is an Ada hierarchy of library-level program units. So class coupling |
| in case of Ada is called as tagged coupling, and category coupling - as |
| hierarchy coupling. |
| |
| For any package counted as a class, its body and subunits (if any) are |
| considered together with its spec when counting the dependencies, and coupling |
| metrics are reported for spec units only. For dependencies between classes, |
| the Ada semantic dependencies are considered. For object-oriented coupling |
| metrics, only dependencies on units that are considered as classes, are |
| considered. |
| |
| For unit and control coupling also not compilation units but program units are |
| counted. That is, for a package, its spec, its body and its subunits (if any) |
| are considered as making up one unit, and the dependencies that are counted |
| are the dependencies of all these compilation units collected together as |
| the dependencies as a (whole) unit. And metrics are reported for spec |
| compilation units only (or for a subprogram body unit in case if there is no |
| separate spec for the given subprogram). |
| |
| For unit coupling, dependencies between all kinds of program units are |
| considered. For control coupling, for each unit the dependencies of this unit |
| upon units that define subprograms are counted, so control fan-out coupling |
| is reported for all units, but control fan-in coupling - only for the units |
| that define subprograms. |
| |
| The following simple example illustrates the difference between unit coupling |
| and control coupling metrics: |
| |
| @smallexample @c ada |
| package Lib_1 is |
| function F_1 (I : Integer) return Integer; |
| end Lib_1; |
| |
| package Lib_2 is |
| type T_2 is new Integer; |
| end Lib_2; |
| |
| package body Lib_1 is |
| function F_1 (I : Integer) return Integer is |
| begin |
| return I + 1; |
| end F_1; |
| end Lib_1; |
| |
| with Lib_2; use Lib_2; |
| package Pack is |
| Var : T_2; |
| function Fun (I : Integer) return Integer; |
| end Pack; |
| |
| with Lib_1; use Lib_1; |
| package body Pack is |
| function Fun (I : Integer) return Integer is |
| begin |
| return F_1 (I); |
| end Fun; |
| end Pack; |
| @end smallexample |
| |
| @noindent |
| if we apply @command{gnatmetric} with @code{--coupling-all} option to these |
| units, the result will be: |
| |
| @smallexample |
| Coupling metrics: |
| ================= |
| Unit Lib_1 (C:\customers\662\L406-007\lib_1.ads) |
| control fan-out coupling : 0 |
| control fan-in coupling : 1 |
| unit fan-out coupling : 0 |
| unit fan-in coupling : 1 |
| |
| Unit Pack (C:\customers\662\L406-007\pack.ads) |
| control fan-out coupling : 1 |
| control fan-in coupling : 0 |
| unit fan-out coupling : 2 |
| unit fan-in coupling : 0 |
| |
| Unit Lib_2 (C:\customers\662\L406-007\lib_2.ads) |
| control fan-out coupling : 0 |
| unit fan-out coupling : 0 |
| unit fan-in coupling : 1 |
| @end smallexample |
| |
| @noindent |
| The result does not contain values for object-oriented |
| coupling because none of the argument unit contains a tagged type and |
| therefore none of these units can be treated as a class. |
| |
| @code{Pack} (considered as a program unit, that is spec+body) depends on two |
| units - @code{Lib_1} @code{and Lib_2}, therefore it has unit fan-out coupling |
| equals to 2. And nothing depend on it, so its unit fan-in coupling is 0 as |
| well as control fan-in coupling. Only one of the units @code{Pack} depends |
| upon defines a subprogram, so its control fan-out coupling is 1. |
| |
| @code{Lib_2} depends on nothing, so fan-out metrics for it are 0. It does |
| not define a subprogram, so control fan-in metric cannot be applied to it, |
| and there is one unit that depends on it (@code{Pack}), so it has |
| unit fan-in coupling equals to 1. |
| |
| @code{Lib_1} is similar to @code{Lib_2}, but it does define a subprogram. |
| So it has control fan-in coupling equals to 1 (because there is a unit |
| depending on it). |
| |
| When computing coupling metrics, @command{gnatmetric} counts only |
| dependencies between units that are arguments of the @command{gnatmetric} |
| call. Coupling metrics are program-wide (or project-wide) metrics, so to |
| get a valid result, you should call @command{gnatmetric} for |
| the whole set of sources that make up your program. It can be done |
| by calling @command{gnatmetric} from the GNAT driver with @option{-U} |
| option (see @ref{The GNAT Driver and Project Files} for details). |
| |
| By default, all the coupling metrics are disabled. You can use the following |
| switches to specify the coupling metrics to be computed and reported: |
| |
| @table @option |
| |
| @ifclear vms |
| @cindex @option{--tagged-coupling@var{x}} (@command{gnatmetric}) |
| @cindex @option{--hierarchy-coupling@var{x}} (@command{gnatmetric}) |
| @cindex @option{--unit-coupling@var{x}} (@command{gnatmetric}) |
| @cindex @option{--control-coupling@var{x}} (@command{gnatmetric}) |
| @end ifclear |
| |
| @ifset vms |
| @cindex @option{/COUPLING_METRICS} (@command{gnatmetric}) |
| @end ifset |
| |
| @item ^--coupling-all^/COUPLING_METRICS=ALL^ |
| Report all the coupling metrics |
| |
| @item ^--tagged-coupling-out^/COUPLING_METRICS=TAGGED_OUT^ |
| Report tagged (class) fan-out coupling |
| |
| @item ^--tagged-coupling-in^/COUPLING_METRICS=TAGGED_IN^ |
| Report tagged (class) fan-in coupling |
| |
| @item ^--hierarchy-coupling-out^/COUPLING_METRICS=HIERARCHY_OUT^ |
| Report hierarchy (category) fan-out coupling |
| |
| @item ^--hierarchy-coupling-in^/COUPLING_METRICS=HIERARCHY_IN^ |
| Report hierarchy (category) fan-in coupling |
| |
| @item ^--unit-coupling-out^/COUPLING_METRICS=UNIT_OUT^ |
| Report unit fan-out coupling |
| |
| @item ^--unit-coupling-in^/COUPLING_METRICS=UNIT_IN^ |
| Report unit fan-in coupling |
| |
| @item ^--control-coupling-out^/COUPLING_METRICS=CONTROL_OUT^ |
| Report control fan-out coupling |
| |
| @item ^--control-coupling-in^/COUPLING_METRICS=CONTROL_IN^ |
| Report control fan-in coupling |
| @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 text file containing file names separated by spaces or |
| line breaks. You can use this switch more than 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 ^-q^/QUIET^ |
| @cindex @option{^-q^/QUIET^} (@code{gnatmetric}) |
| Quiet mode. |
| @end table |
| |
| @node Generate project-wide metrics |
| @subsection Generate project-wide metrics |
| |
| In order to compute metrics on all units of a given project, you can use |
| the @command{gnat} driver along with the @option{-P} option: |
| @smallexample |
| gnat metric -Pproj |
| @end smallexample |
| |
| @noindent |
| If the project @code{proj} depends upon other projects, you can compute |
| the metrics on the project closure using the @option{-U} option: |
| @smallexample |
| gnat metric -Pproj -U |
| @end smallexample |
| |
| @noindent |
| Finally, if not all the units are relevant to a particular main |
| program in the project closure, you can generate metrics for the set |
| of units needed to create a given main program (unit closure) using |
| the @option{-U} option followed by the name of the main unit: |
| @smallexample |
| gnat metric -Pproj -U main |
| @end smallexample |
| |
| |
| @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 |
| ^@samp{a}, @samp{g}, @samp{s}, or @samp{i}, ^@samp{A}, @samp{G}, @samp{S}, or @samp{I},^ |
| then replace the dot by the character |
| ^@samp{~} (tilde)^@samp{$} (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 |
| ^@samp{s-}, @samp{a-}, @samp{i-}, and @samp{g-},^@samp{S-}, @samp{A-}, @samp{I-}, and @samp{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 |
| @c $ gnatkr @var{name} @ovar{length} |
| @c Expanding @ovar macro inline (explanation in macro def comments) |
| $ gnatkr @var{name} @r{[}@var{length}@r{]} |
| @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 |
| ^@samp{a}, @samp{i}, @samp{g}, or @samp{s}^@samp{A}, @samp{I}, @samp{G}, or @samp{S}^. |
| The extension is @code{.ads} for a |
| spec 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 |
| This chapter discusses how to use GNAT's @code{gnatprep} utility for simple |
| preprocessing. |
| Although designed for use with GNAT, @code{gnatprep} does not depend on any |
| special GNAT features. |
| For further discussion of conditional compilation in general, see |
| @ref{Conditional Compilation}. |
| |
| @menu |
| * Preprocessing Symbols:: |
| * Using gnatprep:: |
| * Switches for gnatprep:: |
| * Form of Definitions File:: |
| * Form of Input Text for gnatprep:: |
| @end menu |
| |
| @node Preprocessing Symbols |
| @section Preprocessing Symbols |
| |
| @noindent |
| Preprocessing symbols are defined in definition files and referred to in |
| sources to be preprocessed. A Preprocessing symbol is an identifier, following |
| normal Ada (case-insensitive) rules for its syntax, with the restriction that |
| all characters need to be in the ASCII set (no accented letters). |
| |
| @node Using gnatprep |
| @section Using @code{gnatprep} |
| |
| @noindent |
| To call @code{gnatprep} use |
| |
| @smallexample |
| @c $ gnatprep @ovar{switches} @var{infile} @var{outfile} @ovar{deffile} |
| @c Expanding @ovar macro inline (explanation in macro def comments) |
| $ gnatprep @r{[}@var{switches}@r{]} @var{infile} @var{outfile} @r{[}@var{deffile}@r{]} |
| @end smallexample |
| |
| @noindent |
| where |
| @table @var |
| @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 |
| preprocessing 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 preprocessing 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 a preprocessing symbol, 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} @r{[}then@r{]} |
| lines |
| #elsif @i{expression} @r{[}then@r{]} |
| lines |
| #elsif @i{expression} @r{[}then@r{]} |
| lines |
| @dots{} |
| #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 |
| |
| The following restriction exists: it is not allowed to have "and" or "or" |
| following "not" in the same expression without parentheses. For example, this |
| is not allowed: |
| |
| @smallexample |
| not X or Y |
| @end smallexample |
| |
| This should be one of the following: |
| |
| @smallexample |
| (not X) or Y |
| not (X or Y) |
| @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. |
| The @code{not} operator cannot be combined with the @code{or} or @code{and} |
| operators, without parentheses. For example, "if not X or Y then" is not |
| allowed, but "if (not X) or Y then" and "if not (X or Y) then" are. |
| |
| 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. |
| |
| @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. |
| |
| Note: to invoke @code{gnatls} with a project file, use the @code{gnat} |
| driver (see @ref{The GNAT Driver and Project Files}). |
| |
| @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! |
| @cindex @option{--version} @command{gnatls} |
| Display Copyright and version, then exit disregarding all other options. |
| |
| @item --help |
| @cindex @option{--help} @command{gnatls} |
| If @option{--version} was not used, display usage, then exit disregarding |
| all other options. |
| |
| @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 nonempty 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 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 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! |
| @cindex @option{--version} @command{gnatclean} |
| Display Copyright and version, then exit disregarding all other options. |
| |
| @item --help |
| @cindex @option{--help} @command{gnatclean} |
| If @option{--version} was not used, display usage, then exit disregarding |
| all other options. |
| |
| @item ^--subdirs^/SUBDIRS^=subdir |
| Actual object directory of each project file is the subdirectory subdir of the |
| object directory specified or defaulted in the project file. |
| |
| @item ^--unchecked-shared-lib-imports^/UNCHECKED_SHARED_LIB_IMPORTS^ |
| By default, shared library projects are not allowed to import static library |
| projects. When this switch is used on the command line, this restriction is |
| relaxed. |
| |
| @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. |
| @emph{Stand-alone libraries} are the exception to this rule because 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{lib@var{xxx}.a} |
| or @file{lib@var{xxx}.so} (or @file{lib@var{xxx}.dll} on Windows) in order to |
| be accessed by the directive @option{-l@var{xxx}} at link time. |
| |
| @node Installing a library |
| @subsection Installing a library |
| @cindex @code{ADA_PROJECT_PATH} |
| @cindex @code{GPR_PROJECT_PATH} |
| |
| @noindent |
| If you use project files, library installation is part of the library build |
| process (@pxref{Installing a library with project files}). |
| |
| 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 |
| @dots{} |
| 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 Source_Files use (); |
| 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 @env{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 @env{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. |
| |
| @noindent |
| It is also possible to build an encapsulated library where not only |
| the code to elaborate and finalize the library is embedded but also |
| ensuring that the library is linked only against static |
| libraries. So an encapsulated library only depends on system |
| libraries, all other code, including the GNAT runtime, is embedded. To |
| build an encapsulated library the attribute |
| @code{Library_Standalone} must be set to @code{encapsulated}: |
| |
| @smallexample @c projectfile |
| @group |
| for Library_Dir use "lib_dir"; |
| for Library_Name use "dummy"; |
| for Library_Interface use ("int1", "int1.child"); |
| for Library_Standalone use "encapsulated"; |
| @end group |
| @end smallexample |
| |
| @noindent |
| The default value for this attribute is @code{standard} in which case |
| a stand-alone library is built. |
| |
| 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 My_Package 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 My_Package; |
| @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 (@pxref{Top,, GNU |
| make, make, GNU @code{make}}), 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 @command{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) |
| ## \_ @dots{} |
| ## 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=@dots{} |
| |
| # 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 @command{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, @enddots{} |
| |
| The second method is the most general one. It requires an external |
| program, called @command{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_OBJECTS_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_OBJECTS_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_OBJECTS_PATH += $@{OBJECT_LIST@} |
| export ADA_INCLUDE_PATH |
| export ADA_OBJECTS_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 is designed to work in association with a static runtime library |
| only and in this context provides three types 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, |
| Solaris and Windows NT/2000/XP (x86). |
| |
| @noindent |
| The @code{gnatmem} command has the form |
| |
| @smallexample |
| @c $ gnatmem @ovar{switches} user_program |
| @c Expanding @ovar macro inline (explanation in macro def comments) |
| $ gnatmem @r{[}@var{switches}@r{]} @var{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 |
| As library @file{libgmem.a} contains an alternate body for package |
| @code{System.Memory}, @file{s-memory.adb} should not be compiled and linked |
| when an executable is linked with library @file{libgmem.a}. It is then not |
| recommended to use @command{gnatmake} with switch @option{^-a^/ALL_FILES^}. |
| |
| @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 |
| @option{-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. |
| @ifclear vms |
| To ensure that a clean exception is signalled for stack |
| overflow, set the environment variable |
| @env{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. |
| @end ifclear |
| @ifset vms |
| To have a fixed size stack in the environment task, the stack must be put |
| in the P0 address space and its size specified. Use these switches to |
| create a p0 image: |
| |
| @smallexample |
| gnatmake my_progs -largs "-Wl,--opt=STACK=4000,/p0image" |
| @end smallexample |
| |
| @noindent |
| The quotes are required to keep case. The number after @samp{STACK=} is the |
| size of the environmental task stack in pagelets (512 bytes). In this example |
| the stack size is about 2 megabytes. |
| |
| @noindent |
| A consequence of the @option{/p0image} qualifier is also to makes RMS buffers |
| be placed in P0 space. Refer to @cite{HP OpenVMS Linker Utility Manual} for |
| more details about the @option{/p0image} qualifier and the @option{stack} |
| option. |
| |
| @noindent |
| On Itanium platforms, you can instead assign the @samp{GNAT_STACK_SIZE} and |
| @samp{GNAT_RBS_SIZE} logicals to the size of the primary and register |
| stack in kilobytes. For example: |
| |
| @smallexample |
| $ define GNAT_RBS_SIZE 1024 ! Limit the RBS size to 1MB. |
| @end smallexample |
| @end ifset |
| |
| @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. |
| |
| A unit compiled with @option{-Wstack-usage} will issue a warning for each |
| subprogram whose stack usage might be larger than the specified amount of |
| bytes. The wording is in keeping with the qualifier documented above. |
| |
| @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 |
| @option{-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 | Stack Usage |
| |
| @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. |
| |
| @item Stack Usage |
| is the measure done by the stack analyzer. In order to prevent overflow, the stack |
| is not entirely analyzed, and it's not possible to know exactly how |
| much has actually been used. |
| |
| @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. |
| |
| @noindent |
| The package @code{GNAT.Task_Stack_Usage} provides facilities to get |
| stack usage reports at run-time. See its body for the details. |
| |
| @c ********************************* |
| @c * GNATCHECK * |
| @c ********************************* |
| @node Verifying Properties Using gnatcheck |
| @chapter Verifying Properties Using @command{gnatcheck} |
| @findex gnatcheck |
| @cindex @command{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. |
| @cindex ASIS |
| |
| 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. |
| |
| For full details, refer to @cite{GNATcheck Reference Manual} document. |
| |
| |
| @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. |
| |
| Note: to invoke @code{gnatstub} with a project file, use the @code{gnat} |
| driver (see @ref{The GNAT Driver and Project Files}). |
| |
| 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. |
| |
| By default, all the program unit body stubs generated by @code{gnatstub} |
| raise the predefined @code{Program_Error} exception, which will catch |
| accidental calls of generated stubs. This behavior can be changed with |
| option @option{^--no-exception^/NO_EXCEPTION^} (see below). |
| |
| @menu |
| * Running gnatstub:: |
| * Switches for gnatstub:: |
| @end menu |
| |
| @node Running gnatstub |
| @section Running @command{gnatstub} |
| |
| @noindent |
| @command{gnatstub} has a command-line interface of the form: |
| |
| @smallexample |
| @c $ gnatstub @ovar{switches} @var{filename} @ovar{directory} |
| @c Expanding @ovar macro inline (explanation in macro def comments) |
| $ gnatstub @r{[}@var{switches}@r{]} @var{filename} @r{[}@var{directory}@r{]} @r{[}-cargs @var{gcc_switches}@r{]} |
| @end smallexample |
| |
| @noindent |
| where |
| @table @var |
| @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 @samp{@var{gcc_switches}} is a list of switches for |
| @command{gcc}. They will be passed on to all compiler invocations made by |
| @command{gnatstub} to generate the ASIS trees. Here you can provide |
| @option{^-I^/INCLUDE_DIRS=^} switches to form the source search path, |
| use the @option{-gnatec} switch to set the configuration file, |
| use the @option{-gnat05} switch if sources should be compiled in |
| Ada 2005 mode etc. |
| |
| @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. |
| |
| @item ^--header-file=@var{filename}^/FROM_HEADER_FILE=@var{filename}^ |
| @cindex @option{^--header-file^/FROM_HEADER_FILE=^} (@command{gnatstub}) |
| Use the content of the file as the comment header for a generated 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 ^--no-exception^/NO_EXCEPTION^ |
| @cindex @option{^--no-exception^/NO_EXCEPTION^} (@command{gnatstub}) |
| Avoid raising PROGRAM_ERROR in the generated bodies of program unit stubs. |
| This is not always possible for function stubs. |
| |
| @item ^--no-local-header^/NO_LOCAL_HEADER^ |
| @cindex @option{^--no-local-header^/NO_LOCAL_HEADER^} (@command{gnatstub}) |
| Do not place local comment header with unit name before body stub for a |
| unit. |
| |
| @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 |
| |
| @c ********************************* |
| @node Creating Unit Tests Using gnattest |
| @chapter Creating Unit Tests Using @command{gnattest} |
| @findex gnattest |
| |
| @noindent |
| @command{gnattest} is an ASIS-based utility that creates unit-test skeletons |
| as well as a test driver infrastructure (harness). @command{gnattest} creates |
| a skeleton for each visible subprogram in the packages under consideration when |
| they do not exist already. |
| |
| In order to process source files from a project, @command{gnattest} has to |
| semantically analyze the sources. Therefore, test skeletons can only be |
| generated for legal Ada units. If a unit is dependent on other units, |
| those units should be among the source files of the project or of other projects |
| imported by this one. |
| |
| Generated skeletons and harnesses are based on the AUnit testing framework. |
| AUnit is an Ada adaptation of the xxxUnit testing frameworks, similar to JUnit |
| for Java or CppUnit for C++. While it is advised that gnattest users read |
| the AUnit manual, deep knowledge of AUnit is not necessary for using gnattest. |
| For correct operation of @command{gnattest}, AUnit should be installed and |
| aunit.gpr must be on the project path. This happens automatically when Aunit |
| is installed at its default location. |
| @menu |
| * Running gnattest:: |
| * Switches for gnattest:: |
| * Project Attributes for gnattest:: |
| * Simple Example:: |
| * Setting Up and Tearing Down the Testing Environment:: |
| * Regenerating Tests:: |
| * Default Test Behavior:: |
| * Testing Primitive Operations of Tagged Types:: |
| * Testing Inheritance:: |
| * Tagged Types Substitutability Testing:: |
| * Testing with Contracts:: |
| * Additional Tests:: |
| @ifclear vms |
| * Support for other platforms/run-times:: |
| @end ifclear |
| * Current Limitations:: |
| @end menu |
| |
| @node Running gnattest |
| @section Running @command{gnattest} |
| |
| @noindent |
| @command{gnattest} has a command-line interface of the form |
| |
| @smallexample |
| @c $ gnattest @var{-Pprojname} @ovar{switches} @ovar{filename} @ovar{directory} |
| @c Expanding @ovar macro inline (explanation in macro def comments) |
| $ gnattest @var{-Pprojname} @r{[}@var{--harness-dir=dirname}@r{]} @r{[}@var{switches}@r{]} @r{[}@var{filename}@r{]} @r{[}-cargs @var{gcc_switches}@r{]} |
| @end smallexample |
| |
| @noindent |
| where |
| @table @var |
| |
| @item -Pprojname |
| specifies the project defining the location of source files. When no |
| file names are provided on the command line, all sources in the project |
| are used as input. This switch is required. |
| |
| @item filename |
| is the name of the source file containing the library unit package declaration |
| for which a test package will be created. The file name may be given with a |
| path. |
| |
| @item @samp{@var{gcc_switches}} |
| is a list of switches for |
| @command{gcc}. These switches will be passed on to all compiler invocations |
| made by @command{gnattest} to generate a set of ASIS trees. Here you can provide |
| @option{^-I^/INCLUDE_DIRS=^} switches to form the source search path, |
| use the @option{-gnatec} switch to set the configuration file, |
| use the @option{-gnat05} switch if sources should be compiled in |
| Ada 2005 mode, etc. |
| |
| @item switches |
| is an optional sequence of switches as described in the next section. |
| |
| @end table |
| |
| @command{gnattest} results can be found in two different places. |
| |
| @itemize @bullet |
| @item automatic harness: |
| the harness code, which is located by default in "gnattest/harness" directory |
| that is created in the object directory of corresponding project file. All of |
| this code is generated completely automatically and can be destroyed and |
| regenerated at will. It is not recommended to modify this code manually, since |
| it could easily be overridden by mistake. The entry point in the harness code is |
| the project file named @command{test_driver.gpr}. Tests can be compiled and run |
| using a command such as: |
| |
| @smallexample |
| gnatmake -P<harness-dir>/test_driver |
| test_runner |
| @end smallexample |
| |
| Note that you might need to specify the necessary values of scenario variables |
| when you are not using the AUnit defaults. |
| |
| @item actual unit test skeletons: |
| a test skeleton for each visible subprogram is created in a separate file, if it |
| doesn't exist already. By default, those separate test files are located in a |
| "gnattest/tests" directory that is created in the object directory of |
| corresponding project file. For example, if a source file my_unit.ads in |
| directory src contains a visible subprogram Proc, then the corresponding unit |
| test will be found in file src/tests/my_unit-test_data-tests-proc_<code>.adb. |
| <code> is a signature encoding used to differentiate test names in case of |
| overloading. |
| |
| Note that if the project already has both my_unit.ads and my_unit-test_data.ads, |
| this will cause a name conflict with the generated test package. |
| @end itemize |
| |
| @node Switches for gnattest |
| @section Switches for @command{gnattest} |
| |
| @table @option |
| @c !sort! |
| |
| @item --harness-only |
| @cindex @option{--harness-only} (@command{gnattest}) |
| When this option is given, @command{gnattest} creates a harness for all |
| sources, treating them as test packages. |
| |
| @item --additional-tests=@var{projname} |
| @cindex @option{--additional-tests} (@command{gnattest}) |
| Sources described in @var{projname} are considered potential additional |
| manual tests to be added to the test suite. |
| |
| @item -r |
| @cindex @option{-r} (@command{gnattest}) |
| Recursively consider all sources from all projects. |
| |
| @item -X@var{name=value} |
| @cindex @option{-X} (@command{gnattest}) |
| Indicate that external variable @var{name} has the value @var{value}. |
| |
| @item -q |
| @cindex @option{-q} (@command{gnattest}) |
| Suppresses noncritical output messages. |
| |
| @item -v |
| @cindex @option{-v} (@command{gnattest}) |
| Verbose mode: generates version information. |
| |
| @item --validate-type-extensions |
| @cindex @option{--validate-type-extensions} (@command{gnattest}) |
| Enables substitution check: run all tests from all parents in order |
| to check substitutability. |
| |
| @item --skeleton-default=@var{val} |
| @cindex @option{--skeleton-default} (@command{gnattest}) |
| Specifies the default behavior of generated skeletons. @var{val} can be either |
| "fail" or "pass", "fail" being the default. |
| |
| @item --tests-root=@var{dirname} |
| @cindex @option{--tests-root} (@command{gnattest}) |
| The directory hierarchy of tested sources is recreated in the @var{dirname} |
| directory, and test packages are placed in corresponding directories. |
| If the @var{dirname} is a relative path, it is considered relative to the object |
| directory of the project file. When all sources from all projects are taken |
| recursively from all projects, directory hierarchies of tested sources are |
| recreated for each project in their object directories and test packages are |
| placed accordingly. |
| |
| @item --subdir=@var{dirname} |
| @cindex @option{--subdir} (@command{gnattest}) |
| Test packages are placed in subdirectories. |
| |
| @item --tests-dir=@var{dirname} |
| @cindex @option{--tests-dir} (@command{gnattest}) |
| All test packages are placed in the @var{dirname} directory. |
| If the @var{dirname} is a relative path, it is considered relative to the object |
| directory of the project file. When all sources from all projects are taken |
| recursively from all projects, @var{dirname} directories are created for each |
| project in their object directories and test packages are placed accordingly. |
| |
| @item --harness-dir=@var{dirname} |
| @cindex @option{--harness-dir} (@command{gnattest}) |
| specifies the directory that will hold the harness packages and project file |
| for the test driver. If the @var{dirname} is a relative path, it is considered |
| relative to the object directory of the project file. |
| |
| @item --separates |
| @cindex @option{--separates} (@command{gnattest}) |
| Bodies of all test routines are generated as separates. Note that this mode is |
| kept for compatibility reasons only and it is not advised to use it due to |
| possible problems with hash in names of test skeletons when using an |
| inconsistent casing. Separate test skeletons can be incorporated to monolith |
| test package with improved hash being used by using @option{--transition} |
| switch. |
| |
| |
| @item --transition |
| @cindex @option{--transition} (@command{gnattest}) |
| This allows transition from separate test routines to monolith test packages. |
| All matching test routines are overwritten with contents of corresponding |
| separates. Note that if separate test routines had any manually added with |
| clauses they will be moved to the test package body as is and have to be moved |
| by hand. |
| |
| @end table |
| |
| @option{--tests_root}, @option{--subdir} and @option{--tests-dir} switches are |
| mutually exclusive. |
| |
| @node Project Attributes for gnattest |
| @section Project Attributes for @command{gnattest} |
| |
| @noindent |
| |
| Most of the command-line options can also be passed to the tool by adding |
| special attributes to the project file. Those attributes should be put in |
| package gnattest. Here is the list of attributes: |
| |
| @itemize @bullet |
| |
| @item Tests_Root |
| is used to select the same output mode as with the --tests-root option. |
| This attribute cannot be used together with Subdir or Tests_Dir. |
| |
| @item Subdir |
| is used to select the same output mode as with the --subdir option. |
| This attribute cannot be used together with Tests_Root or Tests_Dir. |
| |
| @item Tests_Dir |
| is used to select the same output mode as with the --tests-dir option. |
| This attribute cannot be used together with Subdir or Tests_Root. |
| |
| @item Harness_Dir |
| is used to specify the directory in which to place harness packages and project |
| file for the test driver, otherwise specified by --harness-dir. |
| |
| @item Additional_Tests |
| is used to specify the project file, otherwise given by |
| --additional-tests switch. |
| |
| @item Skeletons_Default |
| is used to specify the default behaviour of test skeletons, otherwise |
| specified by --skeleton-default option. The value of this attribute |
| should be either "pass" or "fail". |
| |
| @end itemize |
| |
| Each of those attributes can be overridden from the command line if needed. |
| Other @command{gnattest} switches can also be passed via the project |
| file as an attribute list called GNATtest_Switches. |
| |
| @node Simple Example |
| @section Simple Example |
| |
| @noindent |
| |
| Let's take a very simple example using the first @command{gnattest} example |
| located in: |
| |
| @smallexample |
| <install_prefix>/share/examples/gnattest/simple |
| @end smallexample |
| |
| This project contains a simple package containing one subprogram. By running gnattest: |
| |
| @smallexample |
| $ gnattest --harness-dir=driver -Psimple.gpr |
| @end smallexample |
| |
| a test driver is created in directory "driver". It can be compiled and run: |
| |
| @smallexample |
| $ cd driver |
| $ gprbuild -Ptest_driver |
| $ test_runner |
| @end smallexample |
| |
| One failed test with diagnosis "test not implemented" is reported. |
| Since no special output option was specified, the test package Simple.Tests |
| is located in: |
| |
| @smallexample |
| <install_prefix>/share/examples/gnattest/simple/obj/gnattest/tests |
| @end smallexample |
| |
| For each package containing visible subprograms, a child test package is |
| generated. It contains one test routine per tested subprogram. Each |
| declaration of a test subprogram has a comment specifying which tested |
| subprogram it corresponds to. Bodies of test routines are placed in test package |
| bodies and are surrounded by special comment sections. Those comment sections |
| should not be removed or modified in order for gnattest to be able to regenerate |
| test packages and keep already written tests in place. |
| The test routine Test_Inc_5eaee3 located at simple-test_data-tests.adb contains |
| a single statement: a call to procedure Assert. It has two arguments: |
| the Boolean expression we want to check and the diagnosis message to display if |
| the condition is false. |
| |
| That is where actual testing code should be written after a proper setup. |
| An actual check can be performed by replacing the Assert call with: |
| |
| @smallexample @c ada |
| Assert (Inc (1) = 2, "wrong incrementation"); |
| @end smallexample |
| |
| After recompiling and running the test driver, one successfully passed test |
| is reported. |
| |
| @node Setting Up and Tearing Down the Testing Environment |
| @section Setting Up and Tearing Down the Testing Environment |
| |
| @noindent |
| |
| Besides test routines themselves, each test package has a parent package |
| Test_Data that has two procedures: Set_Up and Tear_Down. This package is never |
| overwritten by the tool. Set_Up is called before each test routine of the |
| package and Tear_Down is called after each test routine. Those two procedures |
| can be used to perform necessary initialization and finalization, |
| memory allocation, etc. Test type declared in Test_Data package is parent type |
| for the test type of test package and can have user-defined components whose |
| values can be set by Set_Up routine and used in test routines afterwards. |
| |
| @node Regenerating Tests |
| @section Regenerating Tests |
| |
| @noindent |
| |
| Bodies of test routines and test_data packages are never overridden after they |
| have been created once. As long as the name of the subprogram, full expanded Ada |
| names, and the order of its parameters is the same, and comment sections are |
| intact the old test routine will fit in its place and no test skeleton will be |
| generated for the subprogram. |
| |
| This can be demonstrated with the previous example. By uncommenting declaration |
| and body of function Dec in simple.ads and simple.adb, running |
| @command{gnattest} on the project, and then running the test driver: |
| |
| @smallexample |
| gnattest --harness-dir=driver -Psimple.gpr |
| cd driver |
| gprbuild -Ptest_driver |
| test_runner |
| @end smallexample |
| |
| the old test is not replaced with a stub, nor is it lost, but a new test |
| skeleton is created for function Dec. |
| |
| The only way of regenerating tests skeletons is to remove the previously created |
| tests together with corresponding comment sections. |
| |
| @node Default Test Behavior |
| @section Default Test Behavior |
| |
| @noindent |
| |
| The generated test driver can treat unimplemented tests in two ways: |
| either count them all as failed (this is useful to see which tests are still |
| left to implement) or as passed (to sort out unimplemented ones from those |
| actually failing). |
| |
| The test driver accepts a switch to specify this behavior: |
| --skeleton-default=val, where val is either "pass" or "fail" (exactly as for |
| @command{gnattest}). |
| |
| The default behavior of the test driver is set with the same switch |
| as passed to gnattest when generating the test driver. |
| |
| Passing it to the driver generated on the first example: |
| |
| @smallexample |
| test_runner --skeleton-default=pass |
| @end smallexample |
| |
| makes both tests pass, even the unimplemented one. |
| |
| @node Testing Primitive Operations of Tagged Types |
| @section Testing Primitive Operations of Tagged Types |
| |
| @noindent |
| |
| Creation of test skeletons for primitive operations of tagged types entails |
| a number of features. Test routines for all primitives of a given tagged type |
| are placed in a separate child package named according to the tagged type. For |
| example, if you have tagged type T in package P, all tests for primitives |
| of T will be in P.T_Test_Data.T_Tests. |
| |
| Consider running gnattest on the second example (note: actual tests for this |
| example already exist, so there's no need to worry if the tool reports that |
| no new stubs were generated): |
| |
| @smallexample |
| cd <install_prefix>/share/examples/gnattest/tagged_rec |
| gnattest --harness-dir=driver -Ptagged_rec.gpr |
| @end smallexample |
| |
| Taking a closer look at the test type declared in the test package |
| Speed1.Controller_Test_Data is necessary. It is declared in: |
| |
| @smallexample |
| <install_prefix>/share/examples/gnattest/tagged_rec/obj/gnattest/tests |
| @end smallexample |
| |
| Test types are direct or indirect descendants of |
| AUnit.Test_Fixtures.Test_Fixture type. In the case of nonprimitive tested |
| subprograms, the user doesn't need to be concerned with them. However, |
| when generating test packages for primitive operations, there are some things |
| the user needs to know. |
| |
| Type Test_Controller has components that allow assignment of various |
| derivations of type Controller. And if you look at the specification of |
| package Speed2.Auto_Controller, you will see that Test_Auto_Controller |
| actually derives from Test_Controller rather than AUnit type Test_Fixture. |
| Thus, test types mirror the hierarchy of tested types. |
| |
| The Set_Up procedure of Test_Data package corresponding to a test package |
| of primitive operations of type T assigns to Fixture a reference to an |
| object of that exact type T. Notice, however, that if the tagged type has |
| discriminants, the Set_Up only has a commented template for setting |
| up the fixture, since filling the discriminant with actual value is up |
| to the user. |
| |
| The knowledge of the structure of test types allows additional testing |
| without additional effort. Those possibilities are described below. |
| |
| @node Testing Inheritance |
| @section Testing Inheritance |
| |
| @noindent |
| |
| Since the test type hierarchy mimics the hierarchy of tested types, the |
| inheritance of tests takes place. An example of such inheritance can be |
| seen by running the test driver generated for the second example. As previously |
| mentioned, actual tests are already written for this example. |
| |
| @smallexample |
| cd driver |
| gprbuild -Ptest_driver |
| test_runner |
| @end smallexample |
| |
| There are 6 passed tests while there are only 5 testable subprograms. The test |
| routine for function Speed has been inherited and run against objects of the |
| derived type. |
| |
| @node Tagged Types Substitutability Testing |
| @section Tagged Types Substitutability Testing |
| |
| @noindent |
| |
| Tagged Types Substitutability Testing is a way of verifying the global type |
| consistency by testing. Global type consistency is a principle stating that if |
| S is a subtype of T (in Ada, S is a derived type of tagged type T), |
| then objects of type T may be replaced with objects of type S (that is, |
| objects of type S may be substituted for objects of type T), without |
| altering any of the desirable properties of the program. When the properties |
| of the program are expressed in the form of subprogram preconditions and |
| postconditions (let's call them pre and post), the principle is formulated as |
| relations between the pre and post of primitive operations and the pre and post |
| of their derived operations. The pre of a derived operation should not be |
| stronger than the original pre, and the post of the derived operation should |
| not be weaker than the original post. Those relations ensure that verifying if |
| a dispatching call is safe can be done just by using the pre and post of the |
| root operation. |
| |
| Verifying global type consistency by testing consists of running all the unit |
| tests associated with the primitives of a given tagged type with objects of its |
| derived types. |
| |
| In the example used in the previous section, there was clearly a violation of |
| type consistency. The overriding primitive Adjust_Speed in package Speed2 |
| removes the functionality of the overridden primitive and thus doesn't respect |
| the consistency principle. |
| Gnattest has a special option to run overridden parent tests against objects |
| of the type which have overriding primitives: |
| |
| @smallexample |
| gnattest --harness-dir=driver --validate-type-extensions -Ptagged_rec.gpr |
| cd driver |
| gprbuild -Ptest_driver |
| test_runner |
| @end smallexample |
| |
| While all the tests pass by themselves, the parent test for Adjust_Speed fails |
| against objects of the derived type. |
| |
| Non-overridden tests are already inherited for derived test types, so the |
| --validate-type-extensions enables the application of overriden tests to objects |
| of derived types. |
| |
| @node Testing with Contracts |
| @section Testing with Contracts |
| |
| @noindent |
| |
| @command{gnattest} supports pragmas Precondition, Postcondition, and Test_Case, |
| as well as corresponding aspects. |
| Test routines are generated, one per each Test_Case associated with a tested |
| subprogram. Those test routines have special wrappers for tested functions |
| that have composition of pre- and postcondition of the subprogram with |
| "requires" and "ensures" of the Test_Case (depending on the mode, pre and post |
| either count for Nominal mode or do not count for Robustness mode). |
| |
| The third example demonstrates how this works: |
| |
| @smallexample |
| cd <install_prefix>/share/examples/gnattest/contracts |
| gnattest --harness-dir=driver -Pcontracts.gpr |
| @end smallexample |
| |
| Putting actual checks within the range of the contract does not cause any |
| error reports. For example, for the test routine which corresponds to |
| test case 1: |
| |
| @smallexample @c ada |
| Assert (Sqrt (9.0) = 3.0, "wrong sqrt"); |
| @end smallexample |
| |
| and for the test routine corresponding to test case 2: |
| |
| @smallexample @c ada |
| Assert (Sqrt (-5.0) = -1.0, "wrong error indication"); |
| @end smallexample |
| |
| are acceptable: |
| |
| @smallexample |
| cd driver |
| gprbuild -Ptest_driver |
| test_runner |
| @end smallexample |
| |
| However, by changing 9.0 to 25.0 and 3.0 to 5.0, for example, you can get |
| a precondition violation for test case one. Also, by using any otherwise |
| correct but positive pair of numbers in the second test routine, you can also |
| get a precondition violation. Postconditions are checked and reported |
| the same way. |
| |
| @node Additional Tests |
| @section Additional Tests |
| |
| @noindent |
| @command{gnattest} can add user-written tests to the main suite of the test |
| driver. @command{gnattest} traverses the given packages and searches for test |
| routines. All procedures with a single in out parameter of a type which is |
| derived from AUnit.Test_Fixtures.Test_Fixture and that are declared in package |
| specifications are added to the suites and are then executed by the test driver. |
| (Set_Up and Tear_Down are filtered out.) |
| |
| An example illustrates two ways of creating test harnesses for user-written |
| tests. Directory additional_tests contains an AUnit-based test driver written |
| by hand. |
| |
| @smallexample |
| <install_prefix>/share/examples/gnattest/additional_tests/ |
| @end smallexample |
| |
| To create a test driver for already-written tests, use the --harness-only |
| option: |
| |
| @smallexample |
| gnattest -Padditional/harness/harness.gpr --harness-dir=harness_only \ |
| --harness-only |
| gnatmake -Pharness_only/test_driver.gpr |
| harness_only/test_runner |
| @end smallexample |
| |
| Additional tests can also be executed together with generated tests: |
| |
| @smallexample |
| gnattest -Psimple.gpr --additional-tests=additional/harness/harness.gpr \ |
| --harness-dir=mixing |
| gnatmake -Pmixing/test_driver.gpr |
| mixing/test_runner |
| @end smallexample |
| |
| @ifclear vms |
| @node Support for other platforms/run-times |
| @section Support for other platforms/run-times |
| |
| @noindent |
| @command{gnattest} can be used to generate the test harness for platforms |
| and run-time libraries others than the default native target with the |
| default full run-time. For example, when using a limited run-time library |
| such as Zero FootPrint (ZFP), a simplified harness is generated. |
| |
| Two variables are used to tell the underlying AUnit framework how to generate |
| the test harness: @code{PLATFORM}, which identifies the target, and |
| @code{RUNTIME}, used to determine the run-time library for which the harness |
| is generated. Corresponding prefix should also be used when calling |
| @command{gnattest} for non-native targets. For example, the following options |
| are used to generate the AUnit test harness for a PowerPC ELF target using |
| the ZFP run-time library: |
| |
| @smallexample |
| powerpc-elf-gnattest -Psimple.gpr -XPLATFORM=powerpc-elf -XRUNTIME=zfp |
| @end smallexample |
| @end ifclear |
| |
| @node Current Limitations |
| @section Current Limitations |
| |
| @noindent |
| |
| The tool currently does not support following features: |
| |
| @itemize @bullet |
| @item generic tests for generic packages and package instantiations |
| @item tests for protected subprograms and entries |
| |
| @end itemize |
| |
| @c ********************************* |
| @node Performing Dimensionality Analysis in GNAT |
| @chapter Performing Dimensionality Analysis in GNAT |
| @noindent |
| The GNAT compiler now supports dimensionality checking. The user can |
| specify physical units for objects, and the compiler will verify that uses |
| of these objects are compatible with their dimensions, in a fashion that is |
| familiar to engineering practice. The dimensions of algebraic expressions |
| (including powers with static exponents) are computed from their consistuents. |
| |
| This feature depends on Ada 2012 aspect specifications, and is available from |
| version 7.0.1 of GNAT onwards. The GNAT-specific aspect Dimension_System allows |
| the user to define a system of units; the aspect Dimension then allows the user |
| to declare dimensioned quantities within a given system. |
| |
| The major advantage of this model is that it does not require the declaration of |
| multiple operators for all possible combinations of types: it is only necessary |
| to use the proper subtypes in object declarations. |
| |
| The simplest way to impose dimensionality checking on a computation is to make |
| use of the package System.Dim.Mks, which is part of the GNAT library. This |
| package defines a floating-point type MKS_Type, for which a sequence of |
| dimension names are specified, together with their conventional abbreviations. |
| The following should be read together with the full specification of the |
| package, in file s-dimmks.ads. |
| |
| @smallexample @c ada |
| type Mks_Type is new Long_Long_Float |
| with |
| Dimension_System => ( |
| (Unit_Name => Meter, Unit_Symbol => 'm', Dim_Symbol => 'L'), |
| (Unit_Name => Kilogram, Unit_Symbol => "kg", Dim_Symbol => 'M'), |
| (Unit_Name => Second, Unit_Symbol => 's', Dim_Symbol => 'T'), |
| (Unit_Name => Ampere, Unit_Symbol => 'A', Dim_Symbol => 'I'), |
| (Unit_Name => Kelvin, Unit_Symbol => 'K', Dim_Symbol => "Theta"), |
| (Unit_Name => Mole, Unit_Symbol => "mol", Dim_Symbol => 'N'), |
| (Unit_Name => Candela, Unit_Symbol => "cd", Dim_Symbol => 'J')); |
| @end smallexample |
| |
| @noindent |
| The package then defines a series of subtypes that correspond to these |
| conventional units. For example: |
| @smallexample @c ada |
| subtype Length is Mks_Type |
| with |
| Dimension => (Symbol => 'm', |
| Meter => 1, |
| others => 0); |
| @end smallexample |
| @noindent |
| and similarly for Mass, Time, Electric_Current, Thermodynamic_Temperature, |
| Amount_Of_Substance, and Luminous_Intensity (the standard set of units of |
| the SI system). |
| |
| The package also defines conventional names for values of each unit, for |
| example: |
| |
| @smallexample @c ada |
| m : constant Length := 1.0; |
| kg : constant Mass := 1.0; |
| s : constant Time := 1.0; |
| A : constant Electric_Current := 1.0; |
| @end smallexample |
| |
| @noindent |
| as well as useful multiples of these units: |
| |
| @smallexample @c ada |
| cm : constant Length := 1.0E-02; |
| g : constant Mass := 1.0E-03; |
| min : constant Time := 60.0; |
| day : constant TIme := 60.0 * 24.0 * min; |
| ... |
| @end smallexample |
| |
| @noindent |
| The user can then define a derived unit by providing the aspect that |
| specifies its dimensions within the MKS system, as well as the string to |
| be used for output of a value of that unit: |
| |
| @smallexample @c ada |
| subtype Acceleration is Mks_Type |
| with Dimension => ("m/sec^^^2", Meter => 1, Second => -2, others => 0); |
| @end smallexample |
| |
| @noindent |
| Here is a complete example of use: |
| |
| @smallexample @c ada |
| with System.Dim.MKS; use System.Dim.Mks; |
| with System.Dim.Mks_IO; use System.Dim.Mks_IO; |
| with Text_IO; use Text_IO; |
| procedure Free_Fall is |
| subtype Acceleration is Mks_Type |
| with Dimension => ("m/sec^^^2", 1, 0, -2, others => 0); |
| G : constant acceleration := 9.81 * m / (s ** 2); |
| T : Time := 10.0*s; |
| Distance : Length; |
| begin |
| Put ("Gravitational constant: "); |
| Put (G, Aft => 2, Exp => 0); Put_Line (""); |
| Distance := 0.5 * G * T ** 2; |
| Put ("distance travelled in 10 seconds of free fall "); |
| Put (Distance, Aft => 2, Exp => 0); |
| Put_Line (""); |
| end Free_Fall; |
| @end smallexample |
| |
| @noindent |
| Execution of this program yields: |
| @smallexample |
| Gravitational constant: 9.81 m/sec^^^2 |
| distance travelled in 10 seconds of free fall 490.50 m |
| @end smallexample |
| |
| @noindent |
| However, incorrect assignments such as: |
| |
| @smallexample @c ada |
| Distance := 5.0; |
| Distance := 5.0 * kg: |
| @end smallexample |
| |
| @noindent |
| are rejected with the following diagnoses: |
| |
| @smallexample |
| Distance := 5.0; |
| >>> dimensions mismatch in assignment |
| >>> left-hand side has dimension [L] |
| >>> right-hand side is dimensionless |
| |
| Distance := 5.0 * kg: |
| >>> dimensions mismatch in assignment |
| >>> left-hand side has dimension [L] |
| >>> right-hand side has dimension [M] |
| @end smallexample |
| |
| @noindent |
| The dimensions of an expression are properly displayed, even if there is |
| no explicit subtype for it. If we add to the program: |
| |
| @smallexample @c ada |
| Put ("Final velocity: "); |
| Put (G * T, Aft =>2, Exp =>0); |
| Put_Line (""); |
| @end smallexample |
| |
| @noindent |
| then the output includes: |
| @smallexample |
| Final velocity: 98.10 m.s**(-1) |
| @end smallexample |
| |
| @c ********************************* |
| @node Generating Ada Bindings for C and C++ headers |
| @chapter Generating Ada Bindings for C and C++ headers |
| @findex binding |
| |
| @noindent |
| GNAT now comes with a binding generator for C and C++ headers which is |
| intended to do 95% of the tedious work of generating Ada specs from C |
| or C++ header files. |
| |
| Note that this capability is not intended to generate 100% correct Ada specs, |
| and will is some cases require manual adjustments, although it can often |
| be used out of the box in practice. |
| |
| Some of the known limitations include: |
| |
| @itemize @bullet |
| @item only very simple character constant macros are translated into Ada |
| constants. Function macros (macros with arguments) are partially translated |
| as comments, to be completed manually if needed. |
| @item some extensions (e.g. vector types) are not supported |
| @item pointers to pointers or complex structures are mapped to System.Address |
| @item identifiers with identical name (except casing) will generate compilation |
| errors (e.g. @code{shm_get} vs @code{SHM_GET}). |
| @end itemize |
| |
| The code generated is using the Ada 2005 syntax, which makes it |
| easier to interface with other languages than previous versions of Ada. |
| |
| @menu |
| * Running the binding generator:: |
| * Generating bindings for C++ headers:: |
| * Switches:: |
| @end menu |
| |
| @node Running the binding generator |
| @section Running the binding generator |
| |
| @noindent |
| The binding generator is part of the @command{gcc} compiler and can be |
| invoked via the @option{-fdump-ada-spec} switch, which will generate Ada |
| spec files for the header files specified on the command line, and all |
| header files needed by these files transitively. For example: |
| |
| @smallexample |
| $ g++ -c -fdump-ada-spec -C /usr/include/time.h |
| $ gcc -c -gnat05 *.ads |
| @end smallexample |
| |
| will generate, under GNU/Linux, the following files: @file{time_h.ads}, |
| @file{bits_time_h.ads}, @file{stddef_h.ads}, @file{bits_types_h.ads} which |
| correspond to the files @file{/usr/include/time.h}, |
| @file{/usr/include/bits/time.h}, etc@dots{}, and will then compile in Ada 2005 |
| mode these Ada specs. |
| |
| The @code{-C} switch tells @command{gcc} to extract comments from headers, |
| and will attempt to generate corresponding Ada comments. |
| |
| If you want to generate a single Ada file and not the transitive closure, you |
| can use instead the @option{-fdump-ada-spec-slim} switch. |
| |
| You can optionally specify a parent unit, of which all generated units will |
| be children, using @code{-fada-spec-parent=}@var{unit}. |
| |
| Note that we recommend when possible to use the @command{g++} driver to |
| generate bindings, even for most C headers, since this will in general |
| generate better Ada specs. For generating bindings for C++ headers, it is |
| mandatory to use the @command{g++} command, or @command{gcc -x c++} which |
| is equivalent in this case. If @command{g++} cannot work on your C headers |
| because of incompatibilities between C and C++, then you can fallback to |
| @command{gcc} instead. |
| |
| For an example of better bindings generated from the C++ front-end, |
| the name of the parameters (when available) are actually ignored by the C |
| front-end. Consider the following C header: |
| |
| @smallexample |
| extern void foo (int variable); |
| @end smallexample |
| |
| with the C front-end, @code{variable} is ignored, and the above is handled as: |
| |
| @smallexample |
| extern void foo (int); |
| @end smallexample |
| |
| generating a generic: |
| |
| @smallexample |
| procedure foo (param1 : int); |
| @end smallexample |
| |
| with the C++ front-end, the name is available, and we generate: |
| |
| @smallexample |
| procedure foo (variable : int); |
| @end smallexample |
| |
| In some cases, the generated bindings will be more complete or more meaningful |
| when defining some macros, which you can do via the @option{-D} switch. This |
| is for example the case with @file{Xlib.h} under GNU/Linux: |
| |
| @smallexample |
| g++ -c -fdump-ada-spec -DXLIB_ILLEGAL_ACCESS -C /usr/include/X11/Xlib.h |
| @end smallexample |
| |
| The above will generate more complete bindings than a straight call without |
| the @option{-DXLIB_ILLEGAL_ACCESS} switch. |
| |
| In other cases, it is not possible to parse a header file in a stand-alone |
| manner, because other include files need to be included first. In this |
| case, the solution is to create a small header file including the needed |
| @code{#include} and possible @code{#define} directives. For example, to |
| generate Ada bindings for @file{readline/readline.h}, you need to first |
| include @file{stdio.h}, so you can create a file with the following two |
| lines in e.g. @file{readline1.h}: |
| |
| @smallexample |
| #include <stdio.h> |
| #include <readline/readline.h> |
| @end smallexample |
| |
| and then generate Ada bindings from this file: |
| |
| @smallexample |
| $ g++ -c -fdump-ada-spec readline1.h |
| @end smallexample |
| |
| @node Generating bindings for C++ headers |
| @section Generating bindings for C++ headers |
| |
| @noindent |
| Generating bindings for C++ headers is done using the same options, always |
| with the @command{g++} compiler. |
| |
| In this mode, C++ classes will be mapped to Ada tagged types, constructors |
| will be mapped using the @code{CPP_Constructor} pragma, and when possible, |
| multiple inheritance of abstract classes will be mapped to Ada interfaces |
| (@xref{Interfacing to C++,,,gnat_rm, GNAT Reference Manual}, for additional |
| information on interfacing to C++). |
| |
| For example, given the following C++ header file: |
| |
| @smallexample |
| @group |
| @cartouche |
| class Carnivore @{ |
| public: |
| virtual int Number_Of_Teeth () = 0; |
| @}; |
| |
| class Domestic @{ |
| public: |
| virtual void Set_Owner (char* Name) = 0; |
| @}; |
| |
| class Animal @{ |
| public: |
| int Age_Count; |
| virtual void Set_Age (int New_Age); |
| @}; |
| |
| class Dog : Animal, Carnivore, Domestic @{ |
| public: |
| int Tooth_Count; |
| char *Owner; |
| |
| virtual int Number_Of_Teeth (); |
| virtual void Set_Owner (char* Name); |
| |
| Dog(); |
| @}; |
| @end cartouche |
| @end group |
| @end smallexample |
| |
| The corresponding Ada code is generated: |
| |
| @smallexample @c ada |
| @group |
| @cartouche |
| package Class_Carnivore is |
| type Carnivore is limited interface; |
| pragma Import (CPP, Carnivore); |
| |
| function Number_Of_Teeth (this : access Carnivore) return int is abstract; |
| end; |
| use Class_Carnivore; |
| |
| package Class_Domestic is |
| type Domestic is limited interface; |
| pragma Import (CPP, Domestic); |
| |
| procedure Set_Owner |
| (this : access Domestic; |
| Name : Interfaces.C.Strings.chars_ptr) is abstract; |
| end; |
| use Class_Domestic; |
| |
| package Class_Animal is |
| type Animal is tagged limited record |
| Age_Count : aliased int; |
| end record; |
| pragma Import (CPP, Animal); |
| |
| procedure Set_Age (this : access Animal; New_Age : int); |
| pragma Import (CPP, Set_Age, "_ZN6Animal7Set_AgeEi"); |
| end; |
| use Class_Animal; |
| |
| package Class_Dog is |
| type Dog is new Animal and Carnivore and Domestic with record |
| Tooth_Count : aliased int; |
| Owner : Interfaces.C.Strings.chars_ptr; |
| end record; |
| pragma Import (CPP, Dog); |
| |
| function Number_Of_Teeth (this : access Dog) return int; |
| pragma Import (CPP, Number_Of_Teeth, "_ZN3Dog15Number_Of_TeethEv"); |
| |
| procedure Set_Owner |
| (this : access Dog; Name : Interfaces.C.Strings.chars_ptr); |
| pragma Import (CPP, Set_Owner, "_ZN3Dog9Set_OwnerEPc"); |
| |
| function New_Dog return Dog; |
| pragma CPP_Constructor (New_Dog); |
| pragma Import (CPP, New_Dog, "_ZN3DogC1Ev"); |
| end; |
| use Class_Dog; |
| @end cartouche |
| @end group |
| @end smallexample |
| |
| @node Switches |
| @section Switches |
| |
| @table @option |
| @item -fdump-ada-spec |
| @cindex @option{-fdump-ada-spec} (@command{gcc}) |
| Generate Ada spec files for the given header files transitively (including |
| all header files that these headers depend upon). |
| |
| @item -fdump-ada-spec-slim |
| @cindex @option{-fdump-ada-spec-slim} (@command{gcc}) |
| Generate Ada spec files for the header files specified on the command line |
| only. |
| |
| @item -fada-spec-parent=@var{unit} |
| @cindex -fada-spec-parent (@command{gcc}) |
| Specifies that all files generated by @option{-fdump-ada-spec*} are |
| to be child units of the specified parent unit. |
| |
| @item -C |
| @cindex @option{-C} (@command{gcc}) |
| Extract comments from headers and generate Ada comments in the Ada spec files. |
| @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:: |
| * 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}. |
| |
| |
| @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 |
| @c $ perl gnathtml.pl @ovar{^switches^options^} @var{ada-files} |
| @c Expanding @ovar macro inline (explanation in macro def comments) |
| $ perl gnathtml.pl @r{[}@var{^switches^options^}@r{]} @var{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 Ada 83 subset of keywords will be highlighted. |
| |
| @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,@dots{}). 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 |
| @c $ perl gnathtml.pl @ovar{switches} @var{files} |
| @c Expanding @ovar macro inline (explanation in macro def comments) |
| $ perl gnathtml.pl @r{[}@var{switches}@r{]} @var{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 |
| |
| @ifclear vms |
| @c ****************************** |
| @node Code Coverage and Profiling |
| @chapter Code Coverage and Profiling |
| @cindex Code Coverage |
| @cindex Profiling |
| |
| @noindent |
| This chapter describes how to use @code{gcov} - coverage testing tool - and |
| @code{gprof} - profiler tool - on your Ada programs. |
| |
| @menu |
| * Code Coverage of Ada Programs using gcov:: |
| * Profiling an Ada Program using gprof:: |
| @end menu |
| |
| @node Code Coverage of Ada Programs using gcov |
| @section Code Coverage of Ada Programs using gcov |
| @cindex gcov |
| @cindex -fprofile-arcs |
| @cindex -ftest-coverage |
| @cindex -coverage |
| @cindex Code Coverage |
| |
| @noindent |
| @code{gcov} is a test coverage program: it analyzes the execution of a given |
| program on selected tests, to help you determine the portions of the program |
| that are still untested. |
| |
| @code{gcov} is part of the GCC suite, and is described in detail in the GCC |
| User's Guide. You can refer to this documentation for a more complete |
| description. |
| |
| This chapter provides a quick startup guide, and |
| details some Gnat-specific features. |
| |
| @menu |
| * Quick startup guide:: |
| * Gnat specifics:: |
| @end menu |
| |
| @node Quick startup guide |
| @subsection Quick startup guide |
| |
| In order to perform coverage analysis of a program using @code{gcov}, 3 |
| steps are needed: |
| |
| @itemize @bullet |
| @item |
| Code instrumentation during the compilation process |
| @item |
| Execution of the instrumented program |
| @item |
| Execution of the @code{gcov} tool to generate the result. |
| @end itemize |
| |
| The code instrumentation needed by gcov is created at the object level: |
| The source code is not modified in any way, because the instrumentation code is |
| inserted by gcc during the compilation process. To compile your code with code |
| coverage activated, you need to recompile your whole project using the |
| switches |
| @code{-fprofile-arcs} and @code{-ftest-coverage}, and link it using |
| @code{-fprofile-arcs}. |
| |
| @smallexample |
| $ gnatmake -P my_project.gpr -f -cargs -fprofile-arcs -ftest-coverage \ |
| -largs -fprofile-arcs |
| @end smallexample |
| |
| This compilation process will create @file{.gcno} files together with |
| the usual object files. |
| |
| Once the program is compiled with coverage instrumentation, you can |
| run it as many times as needed - on portions of a test suite for |
| example. The first execution will produce @file{.gcda} files at the |
| same location as the @file{.gcno} files. The following executions |
| will update those files, so that a cumulative result of the covered |
| portions of the program is generated. |
| |
| Finally, you need to call the @code{gcov} tool. The different options of |
| @code{gcov} are available in the GCC User's Guide, section 'Invoking gcov'. |
| |
| This will create annotated source files with a @file{.gcov} extension: |
| @file{my_main.adb} file will be analysed in @file{my_main.adb.gcov}. |
| |
| @node Gnat specifics |
| @subsection Gnat specifics |
| |
| Because Ada semantics, portions of the source code may be shared among |
| several object files. This is the case for example when generics are |
| involved, when inlining is active or when declarations generate initialisation |
| calls. In order to take |
| into account this shared code, you need to call @code{gcov} on all |
| source files of the tested program at once. |
| |
| The list of source files might exceed the system's maximum command line |
| length. In order to bypass this limitation, a new mechanism has been |
| implemented in @code{gcov}: you can now list all your project's files into a |
| text file, and provide this file to gcov as a parameter, preceded by a @@ |
| (e.g. @samp{gcov @@mysrclist.txt}). |
| |
| Note that on AIX compiling a static library with @code{-fprofile-arcs} is |
| not supported as there can be unresolved symbols during the final link. |
| |
| @node Profiling an Ada Program using gprof |
| @section Profiling an Ada Program using gprof |
| @cindex gprof |
| @cindex -pg |
| @cindex Profiling |
| |
| @noindent |
| This section is not meant to be an exhaustive documentation of @code{gprof}. |
| Full documentation for it can be found in the GNU Profiler User's Guide |
| documentation that is part of this GNAT distribution. |
| |
| Profiling a program helps determine the parts of a program that are executed |
| most often, and are therefore the most time-consuming. |
| |
| @code{gprof} is the standard GNU profiling tool; it has been enhanced to |
| better handle Ada programs and multitasking. |
| It is currently supported on the following platforms |
| @itemize @bullet |
| @item |
| linux x86/x86_64 |
| @item |
| solaris sparc/sparc64/x86 |
| @item |
| windows x86 |
| @end itemize |
| |
| @noindent |
| In order to profile a program using @code{gprof}, 3 steps are needed: |
| |
| @itemize @bullet |
| @item |
| Code instrumentation, requiring a full recompilation of the project with the |
| proper switches. |
| @item |
| Execution of the program under the analysis conditions, i.e. with the desired |
| input. |
| @item |
| Analysis of the results using the @code{gprof} tool. |
| @end itemize |
| |
| @noindent |
| The following sections detail the different steps, and indicate how |
| to interpret the results: |
| @menu |
| * Compilation for profiling:: |
| * Program execution:: |
| * Running gprof:: |
| * Interpretation of profiling results:: |
| @end menu |
| |
| @node Compilation for profiling |
| @subsection Compilation for profiling |
| @cindex -pg |
| @cindex Profiling |
| |
| In order to profile a program the first step is to tell the compiler |
| to generate the necessary profiling information. The compiler switch to be used |
| is @code{-pg}, which must be added to other compilation switches. This |
| switch needs to be specified both during compilation and link stages, and can |
| be specified once when using gnatmake: |
| |
| @smallexample |
| gnatmake -f -pg -P my_project |
| @end smallexample |
| |
| @noindent |
| Note that only the objects that were compiled with the @samp{-pg} switch will |
| be profiled; if you need to profile your whole project, use the @samp{-f} |
| gnatmake switch to force full recompilation. |
| |
| @node Program execution |
| @subsection Program execution |
| |
| @noindent |
| Once the program has been compiled for profiling, you can run it as usual. |
| |
| The only constraint imposed by profiling is that the program must terminate |
| normally. An interrupted program (via a Ctrl-C, kill, etc.) will not be |
| properly analyzed. |
| |
| Once the program completes execution, a data file called @file{gmon.out} is |
| generated in the directory where the program was launched from. If this file |
| already exists, it will be overwritten. |
| |
| @node Running gprof |
| @subsection Running gprof |
| |
| @noindent |
| The @code{gprof} tool is called as follow: |
| |
| @smallexample |
| gprof my_prog gmon.out |
| @end smallexample |
| |
| @noindent |
| or simpler: |
| |
| @smallexample |
| gprof my_prog |
| @end smallexample |
| |
| @noindent |
| The complete form of the gprof command line is the following: |
| |
| @smallexample |
| gprof [^switches^options^] [executable [data-file]] |
| @end smallexample |
| |
| @noindent |
| @code{gprof} supports numerous ^switch^options^. The order of these |
| ^switch^options^ does not matter. The full list of options can be found in |
| the GNU Profiler User's Guide documentation that comes with this documentation. |
| |
| The following is the subset of those switches that is most relevant: |
| |
| @table @option |
| |
| @item --demangle[=@var{style}] |
| @itemx --no-demangle |
| @cindex @option{--demangle} (@code{gprof}) |
| These options control whether symbol names should be demangled when |
| printing output. The default is to demangle C++ symbols. The |
| @code{--no-demangle} option may be used to turn off demangling. Different |
| compilers have different mangling styles. The optional demangling style |
| argument can be used to choose an appropriate demangling style for your |
| compiler, in particular Ada symbols generated by GNAT can be demangled using |
| @code{--demangle=gnat}. |
| |
| @item -e @var{function_name} |
| @cindex @option{-e} (@code{gprof}) |
| The @samp{-e @var{function}} option tells @code{gprof} not to print |
| information about the function @var{function_name} (and its |
| children@dots{}) in the call graph. The function will still be listed |
| as a child of any functions that call it, but its index number will be |
| shown as @samp{[not printed]}. More than one @samp{-e} option may be |
| given; only one @var{function_name} may be indicated with each @samp{-e} |
| option. |
| |
| @item -E @var{function_name} |
| @cindex @option{-E} (@code{gprof}) |
| The @code{-E @var{function}} option works like the @code{-e} option, but |
| execution time spent in the function (and children who were not called from |
| anywhere else), will not be used to compute the percentages-of-time for |
| the call graph. More than one @samp{-E} option may be given; only one |
| @var{function_name} may be indicated with each @samp{-E} option. |
| |
| @item -f @var{function_name} |
| @cindex @option{-f} (@code{gprof}) |
| The @samp{-f @var{function}} option causes @code{gprof} to limit the |
| call graph to the function @var{function_name} and its children (and |
| their children@dots{}). More than one @samp{-f} option may be given; |
| only one @var{function_name} may be indicated with each @samp{-f} |
| option. |
| |
| @item -F @var{function_name} |
| @cindex @option{-F} (@code{gprof}) |
| The @samp{-F @var{function}} option works like the @code{-f} option, but |
| only time spent in the function and its children (and their |
| children@dots{}) will be used to determine total-time and |
| percentages-of-time for the call graph. More than one @samp{-F} option |
| may be given; only one @var{function_name} may be indicated with each |
| @samp{-F} option. The @samp{-F} option overrides the @samp{-E} option. |
| |
| @end table |
| |
| @node Interpretation of profiling results |
| @subsection Interpretation of profiling results |
| |
| @noindent |
| |
| The results of the profiling analysis are represented by two arrays: the |
| 'flat profile' and the 'call graph'. Full documentation of those outputs |
| can be found in the GNU Profiler User's Guide. |
| |
| The flat profile shows the time spent in each function of the program, and how |
| many time it has been called. This allows you to locate easily the most |
| time-consuming functions. |
| |
| The call graph shows, for each subprogram, the subprograms that call it, |
| and the subprograms that it calls. It also provides an estimate of the time |
| spent in each of those callers/called subprograms. |
| @end ifclear |
| |
| @c ****************************** |
| @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 GNAT on the Alpha OpenVMS platform; |
| for I64 OpenVMS please refer to the @cite{OpenVMS Debugger Manual}, |
| since HP has implemented Ada support in the OpenVMS debugger on I64. |
| @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:: |
| * Remote Debugging using gdbserver:: |
| * 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. |
| |
| @xref{Top,, Debugging with GDB, gdb, Debugging with GDB}, |
| @ifset vms |
| located in the GNU:[DOCS] directory, |
| @end ifset |
| for 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 @command{gcc} or @command{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 |
| This section describes how to initiate the debugger. |
| @c The above sentence is really just filler, but it was otherwise |
| @c clumsy to get the first paragraph nonindented given the conditional |
| @c nature of the description |
| |
| @ifclear vms |
| The debugger can be launched from a @code{GPS} menu or |
| directly from the command line. The description below covers the latter use. |
| All the commands shown can be used in the @code{GPS} debug console window, |
| but there are usually more GUI-based ways to achieve the same effect. |
| @end ifclear |
| |
| The command to run @code{GDB} 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. @xref{Top,, |
| Debugging with GDB, gdb, Debugging with GDB}, |
| @ifset vms |
| located in the GNU:[DOCS] directory, |
| @end ifset |
| for extensive documentation on the use |
| of these commands, together with examples of their use. Furthermore, |
| the command @command{help} invoked from within 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 catch exception @var{name} |
| This command causes the program execution to stop whenever exception |
| @var{name} is raised. If @var{name} is omitted, then the execution is |
| suspended 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 |
| |
| @noindent |
| 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 @ref{Top,, Debugging with GDB, gdb, |
| 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 |
| |
| @noindent |
| 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 @ref{Top,, Debugging with |
| GDB, gdb, 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 Stopping when Ada Exceptions are Raised |
| @cindex Exceptions |
| |
| @noindent |
| You can set catchpoints that stop the program execution when your program |
| raises selected exceptions. |
| |
| @table @code |
| @item catch exception |
| Set a catchpoint that stops execution whenever (any task in the) program |
| raises any exception. |
| |
| @item catch exception @var{name} |
| Set a catchpoint that stops execution whenever (any task in the) program |
| raises the exception @var{name}. |
| |
| @item catch exception unhandled |
| Set a catchpoint that stops executing 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 @ref{Top,, Debugging with GDB, gdb, 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 Remote Debugging using gdbserver |
| @section Remote Debugging using gdbserver |
| @cindex Remote Debugging using gdbserver |
| |
| @noindent |
| On platforms where gdbserver is supported, it is possible to use this tool |
| to debug your application remotely. This can be useful in situations |
| where the program needs to be run on a target host that is different |
| from the host used for development, particularly when the target has |
| a limited amount of resources (either CPU and/or memory). |
| |
| To do so, start your program using gdbserver on the target machine. |
| gdbserver then automatically suspends the execution of your program |
| at its entry point, waiting for a debugger to connect to it. The |
| following commands starts an application and tells gdbserver to |
| wait for a connection with the debugger on localhost port 4444. |
| |
| @smallexample |
| $ gdbserver localhost:4444 program |
| Process program created; pid = 5685 |
| Listening on port 4444 |
| @end smallexample |
| |
| Once gdbserver has started listening, we can tell the debugger to establish |
| a connection with this gdbserver, and then start the same debugging session |
| as if the program was being debugged on the same host, directly under |
| the control of GDB. |
| |
| @smallexample |
| $ gdb program |
| (gdb) target remote targethost:4444 |
| Remote debugging using targethost:4444 |
| 0x00007f29936d0af0 in ?? () from /lib64/ld-linux-x86-64.so. |
| (gdb) b foo.adb:3 |
| Breakpoint 1 at 0x401f0c: file foo.adb, line 3. |
| (gdb) continue |
| Continuing. |
| |
| Breakpoint 1, foo () at foo.adb:4 |
| 4 end foo; |
| @end smallexample |
| |
| It is also possible to use gdbserver to attach to an already running |
| program, in which case the execution of that program is simply suspended |
| until the connection between the debugger and gdbserver is established. |
| |
| For more information on how to use gdbserver, @ref{Top, Server, Using |
| the gdbserver Program, gdb, Debugging with GDB}. @value{EDITION} provides support |
| for gdbserver on x86-linux, x86-windows and x86_64-linux. |
| |
| @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 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 specs. 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/@dots{}/crt1.c:200 |
| 004011F1 at /build/@dots{}/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/@dots{}/crt1.c:200 |
| 004011F1 in <mainCRTStartup> at /build/@dots{}/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 |
| Ada 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 to 64-Bit GNAT for 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 |
| @xref{Implementation Defined Pragmas,,, gnat_rm, GNAT Reference Manual}, |
| indicates whether or not they are applicable to non-VMS systems. |
| |
| @menu |
| * Ada Language 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 Language Compatibility |
| @section Ada Language Compatibility |
| |
| @noindent |
| GNAT handles Ada 95 and Ada 2005 as well as Ada 83, whereas HP Ada is only |
| for Ada 83. Ada 95 and Ada 2005 are 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 @cite{Annotated Ada 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 and Ada 2005 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 |
| An Ada compiler is allowed 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 defined in the Ada |
| Reference Manual. |
| |
| 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 spec 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 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 |
| 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 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 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 to 64-Bit GNAT for 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 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"; |
| @dots{} |
| 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"; |
| @dots{} |
| for Q'Address use Q_Address; |
| @end cartouche |
| @end group |
| @end smallexample |
| |
| @noindent |
| which will be accepted by GNAT (and other Ada compilers), and is also |
| compatible with Ada 83. A fuller description of the restrictions |
| on address specifications is found in @ref{Top, GNAT Reference Manual, |
| About This Guide, gnat_rm, 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 @cite{Ada Reference Manual} and in the |
| @cite{HP Ada Language Reference Manual}. As implemented by GNAT, the |
| package @code{STANDARD} is described in the @cite{Ada 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 spec 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 @cite{Ada 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 Ada 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. @xref{Pragma |
| Extend_System,,, gnat_rm, 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}. |
| @xref{Address Clauses,,, gnat_rm, 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 @cite{Ada 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 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 introduced by Ada 95 and Ada 2005. |
| 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{PSECT_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 Ada protected objects. 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 including the |
| following: |
| |
| @itemize @bullet |
| @item @code{ABORT_DEFER} |
| |
| @item @code{ADA_83} |
| |
| @item @code{ADA_95} |
| |
| @item @code{ADA_05} |
| |
| @item @code{Ada_2005} |
| |
| @item @code{Ada_12} |
| |
| @item @code{Ada_2012} |
| |
| @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{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 and other GNAT implementation-defined pragmas, |
| see @ref{Implementation Defined Pragmas,,, gnat_rm, 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 post-Ada 83 |
| 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 post-Ada 83 |
| compatibility are minor and include the following: |
| |
| @itemize @bullet |
| @item Adjusting the location of pragmas and record representation |
| clauses to obey Ada 95 (and thus Ada 2005) rules |
| |
| @item Adding the proper notation to generic formal parameters |
| that take unconstrained types in instantiation |
| |
| @item Adding pragma @code{ELABORATE_BODY} to package specs |
| 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, on both the Alpha and I64 OpenVMS platforms. |
| |
| The X components of DECLIB compatibility package are located in a separate |
| library, called XDECGNAT, which is not linked with by default; this library |
| must be explicitly linked with any application that makes use of any X facilities, |
| with a command similar to |
| |
| @code{GNAT MAKE USE_X /LINK /LIBRARY=XDECGNAT} |
| |
| 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 @cite{Ada Reference Manual} (packages @code{INTERFACES.C}, |
| @code{INTERFACES.C.STRINGS} and @code{INTERFACES.C.POINTERS}). For more |
| information, see @ref{Interfacing to C,,, gnat_rm, 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{/@r{[}NO@r{]}MAP} |
| |
| @item @option{/OUTPUT=@var{file-spec}} |
| |
| @item @option{/@r{[}NO@r{]}DEBUG} and @option{/@r{[}NO@r{]}TRACEBACK} |
| @end itemize |
| |
| @noindent |
| To pass options to the linker, GNAT provides the following |
| switches: |
| |
| @itemize @bullet |
| @item @option{/EXECUTABLE=@var{exec-name}} |
| |
| @item @option{/VERBOSE} |
| |
| @item @option{/@r{[}NO@r{]}DEBUG} and @option{/@r{[}NO@r{]}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 |
| spec 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 Reference Manual: |
| @itemize @bullet |
| @item @code{TEXT_IO} |
| |
| @item @code{SEQUENTIAL_IO} |
| |
| @item @code{DIRECT_IO} |
| @end itemize |
| |
| @noindent |
| The use of the standard child package syntax (for |
| example, @code{ADA.TEXT_IO}) retrieves the post-Ada 83 versions of these |
| packages. |
| GNAT provides HP-compatible predefined instantiations |
| of the @code{TEXT_IO} packages, and also |
| provides the standard predefined instantiations required |
| by the @cite{Ada 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 @ref{Implementation of the Standard I/O,,, |
| gnat_rm, 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 32766 |
| @sp 1 |
| |
| @item Maximum number of characters in a source line |
| @tab 255 |
| @tab 32766 |
| @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 @value{EDITION}\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 /}{Tool with HP Ada}{Tool with @value{EDITION}} |
| @item @i{Tool} |
| @tab @i{Tool with HP Ada} |
| @tab @i{Tool 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:: |
| * RTX-Specific Considerations:: |
| * HP-UX-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 @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{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 ZCX |
| @* |
| @item @code{@ @ }@i{rts-sjlj} |
| @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-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{sparc64-solaris} @tab |
| @item @code{@ @ }@i{rts-native (default)} |
| @item @code{@ @ @ @ }Tasking @tab native Solaris threads library |
| @item @code{@ @ @ @ }Exceptions @tab ZCX |
| @* |
| @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-solaris} |
| @item @code{@ @ }@i{rts-native (default)} |
| @item @code{@ @ @ @ }Tasking @tab native Solaris threads |
| @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-windows} |
| @item @code{@ @ }@i{rts-native (default)} |
| @item @code{@ @ @ @ }Tasking @tab native Win32 threads |
| @item @code{@ @ @ @ }Exceptions @tab ZCX |
| @* |
| @item @code{@ @ }@i{rts-sjlj} |
| @item @code{@ @ @ @ }Tasking @tab native Win32 threads |
| @item @code{@ @ @ @ }Exceptions @tab SJLJ |
| @* |
| @item @b{x86-windows-rtx} |
| @item @code{@ @ }@i{rts-rtx-rtss (default)} |
| @item @code{@ @ @ @ }Tasking @tab RTX real-time subsystem RTSS threads (kernel mode) |
| @item @code{@ @ @ @ }Exceptions @tab SJLJ |
| @* |
| @item @code{@ @ }@i{rts-rtx-w32} |
| @item @code{@ @ @ @ }Tasking @tab RTX Win32 threads (user mode) |
| @item @code{@ @ @ @ }Exceptions @tab ZCX |
| @* |
| @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/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 using the @option{--RTS} switch, e.g., @option{--RTS=sjlj} |
| @cindex @option{--RTS} option |
| |
| @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. |
| |
| @menu |
| * Solaris Threads Issues:: |
| @end menu |
| |
| @node Solaris Threads Issues |
| @subsection Solaris Threads Issues |
| |
| @noindent |
| GNAT under Solaris/Sparc 32 bits 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 @env{GNAT_PROCESSOR} |
| @cindex @env{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 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_Address}. |
| 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. |
| |
| @node RTX-Specific Considerations |
| @section RTX-Specific Considerations |
| @cindex RTX libraries |
| |
| @noindent |
| The Real-time Extension (RTX) to Windows is based on the Windows Win32 |
| API. Applications can be built to work in two different modes: |
| |
| @itemize @bullet |
| @item |
| Windows executables that run in Ring 3 to utilize memory protection |
| (@emph{rts-rtx-w32}). |
| |
| @item |
| Real-time subsystem (RTSS) executables that run in Ring 0, where |
| performance can be optimized with RTSS applications taking precedent |
| over all Windows applications (@emph{rts-rtx-rtss}). This mode requires |
| the Microsoft linker to handle RTSS libraries. |
| |
| @end itemize |
| |
| @node HP-UX-Specific Considerations |
| @section HP-UX-Specific Considerations |
| @cindex HP-UX Scheduling |
| |
| @noindent |
| On HP-UX, appropriate privileges are required to change the scheduling |
| parameters of a task. The calling process must have appropriate |
| privileges or be a member of a group having @code{PRIV_RTSCHED} access to |
| successfully change the scheduling parameters. |
| |
| By default, GNAT uses the @code{SCHED_HPUX} policy. To have access to the |
| priority range 0-31 either the @code{FIFO_Within_Priorities} or the |
| @code{Round_Robin_Within_Priorities} scheduling policies need to be set. |
| |
| To specify the @code{FIFO_Within_Priorities} 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 the @code{Round_Robin_Within_Priorities}, scheduling policy |
| you should use @code{pragma Time_Slice} with a |
| value greater than @code{0.0}, or use the corresponding @option{-T} |
| binder option, or set the @code{pragma Task_Dispatching_Policy |
| (Round_Robin_Within_Priorities)}. |
| |
| @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: 6.0.0w (20061115)"; |
| 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/setjmp 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/setjmp 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:: |
| * Checking the Elaboration Order:: |
| * Controlling the Elaboration Order:: |
| * 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 Dispatching Calls:: |
| * Summary of Procedures for Elaboration Control:: |
| * Other Elaboration Order Considerations:: |
| @end menu |
| |
| @noindent |
| This chapter describes the handling of elaboration code in Ada 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 |
| @section Elaboration Code |
| |
| @noindent |
| Ada 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 @dots{} |
| @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_1} |
| will occur, but not the call to @code{Func_2.} |
| 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 |
| @section Checking the Elaboration Order |
| |
| @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 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 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 |
| @section Controlling the Elaboration Order |
| |
| @noindent |
| In the previous section we discussed the rules in Ada 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 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 |
| A library package that does not require a body does not permit |
| a body (this rule was introduced in Ada 95). |
| Thus 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 |
| 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 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 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 exist, 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, 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 @code{One} appears before the declaration containing the call |
| (note that in Ada 95 and Ada 2005, |
| 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 |
| @dots{} |
| 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 |
| @dots{} |
| 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 @dots{} |
| |
| package Y is @dots{} |
| |
| with X; |
| package body Y is @dots{} |
| |
| with Y; |
| package body X is @dots{} |
| @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 @dots{} 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 (DYNAMIC); |
| @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 and Ada 2005 programs, |
| since 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 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 @cite{Ada 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 avoiding elaboration problems. However, if this switch is used, 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 Dispatching Calls |
| @section Elaboration for Dispatching Calls |
| @cindex Dispatching calls |
| |
| @noindent |
| In rare cases, the static elaboration model fails to prevent |
| dispatching calls to not-yet-elaborated subprograms. In such cases, we |
| fall back to run-time checks; premature calls to any primitive |
| operation of a tagged type before the body of the operation has been |
| elaborated will raise @code{Program_Error}. |
| |
| Access-to-subprogram types, however, are handled conservatively, and |
| do not require run-time checks. This was not true in earlier versions |
| of the compiler; you can use the @option{-gnatd.U} debug switch to |
| revert to the old behavior if the new conservative behavior causes |
| elaboration cycles. |
| |
| @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. |
| |
| However, GNAT does attempt to diagnose the common situation where there |
| are uninitialized variables in the visible part of a package spec, and the |
| corresponding package body has an elaboration block that directly or |
| indirectly initialized one or more of these variables. This is the situation |
| in which a pragma Elaborate_Body is usually desirable, and GNAT will generate |
| a warning that suggests this addition if it detects this situation. |
| |
| 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. |
| |
| |
| @c ********************************** |
| @node Overflow Check Handling in GNAT |
| @appendix Overflow Check Handling in GNAT |
| @cindex Overflow checks |
| @cindex Checks (overflow) |
| @c ********************************** |
| |
| @menu |
| * Background:: |
| * Overflow Checking Modes in GNAT:: |
| * Specifying the Desired Mode:: |
| * Default Settings:: |
| * Implementation Notes:: |
| @end menu |
| |
| |
| @node Background |
| @section Background |
| |
| @noindent |
| Overflow checks are checks that the compiler may make to ensure |
| that intermediate results are not out of range. For example: |
| |
| @smallexample @c ada |
| A : Integer; |
| ... |
| A := A + 1; |
| @end smallexample |
| |
| @noindent |
| if @code{A} has the value @code{Integer'Last}, then the addition may cause |
| overflow since the result is out of range of the type @code{Integer}. |
| In this case @code{Constraint_Error} will be raised if checks are |
| enabled. |
| |
| A trickier situation arises in examples like the following: |
| |
| @smallexample @c ada |
| A, C : Integer; |
| ... |
| A := (A + 1) + C; |
| @end smallexample |
| |
| @noindent |
| where @code{A} is @code{Integer'Last} and @code{C} is @code{-1}. |
| Now the final result of the expression on the right hand side is |
| @code{Integer'Last} which is in range, but the question arises whether the |
| intermediate addition of @code{(A + 1)} raises an overflow error. |
| |
| The (perhaps surprising) answer is that the Ada language |
| definition does not answer this question. Instead it leaves |
| it up to the implementation to do one of two things if overflow |
| checks are enabled. |
| |
| @itemize @bullet |
| @item |
| raise an exception (@code{Constraint_Error}), or |
| |
| @item |
| yield the correct mathematical result which is then used in |
| subsequent operations. |
| @end itemize |
| |
| @noindent |
| If the compiler chooses the first approach, then the assignment of this |
| example will indeed raise @code{Constraint_Error} if overflow checking is |
| enabled, or result in erroneous execution if overflow checks are suppressed. |
| |
| But if the compiler |
| chooses the second approach, then it can perform both additions yielding |
| the correct mathematical result, which is in range, so no exception |
| will be raised, and the right result is obtained, regardless of whether |
| overflow checks are suppressed. |
| |
| Note that in the first example an |
| exception will be raised in either case, since if the compiler |
| gives the correct mathematical result for the addition, it will |
| be out of range of the target type of the assignment, and thus |
| fails the range check. |
| |
| This lack of specified behavior in the handling of overflow for |
| intermediate results is a source of non-portability, and can thus |
| be problematic when programs are ported. Most typically this arises |
| in a situation where the original compiler did not raise an exception, |
| and then the application is moved to a compiler where the check is |
| performed on the intermediate result and an unexpected exception is |
| raised. |
| |
| Furthermore, when using Ada 2012's preconditions and other |
| assertion forms, another issue arises. Consider: |
| |
| @smallexample @c ada |
| procedure P (A, B : Integer) with |
| Pre => A + B <= Integer'Last; |
| @end smallexample |
| |
| @noindent |
| One often wants to regard arithmetic in a context like this from |
| a mathematical point of view. So for example, if the two actual parameters |
| for a call to @code{P} are both @code{Integer'Last}, then |
| the precondition should be regarded as False. If we are executing |
| in a mode with run-time checks enabled for preconditions, then we would |
| like this precondition to fail, rather than raising an exception |
| because of the intermediate overflow. |
| |
| However, the language definition leaves the specification of |
| whether the above condition fails (raising @code{Assert_Error}) or |
| causes an intermediate overflow (raising @code{Constraint_Error}) |
| up to the implementation. |
| |
| The situation is worse in a case such as the following: |
| |
| @smallexample @c ada |
| procedure Q (A, B, C : Integer) with |
| Pre => A + B + C <= Integer'Last; |
| @end smallexample |
| |
| @noindent |
| Consider the call |
| |
| @smallexample @c ada |
| Q (A => Integer'Last, B => 1, C => -1); |
| @end smallexample |
| |
| @noindent |
| From a mathematical point of view the precondition |
| is True, but at run time we may (but are not guaranteed to) get an |
| exception raised because of the intermediate overflow (and we really |
| would prefer this precondition to be considered True at run time). |
| |
| @node Overflow Checking Modes in GNAT |
| @section Overflow Checking Modes in GNAT |
| |
| @noindent |
| To deal with the portability issue, and with the problem of |
| mathematical versus run-time intepretation of the expressions in |
| assertions, GNAT provides comprehensive control over the handling |
| of intermediate overflow. GNAT can operate in three modes, and |
| furthemore, permits separate selection of operating modes for |
| the expressions within assertions (here the term ``assertions'' |
| is used in the technical sense, which includes preconditions and so forth) |
| and for expressions appearing outside assertions. |
| |
| The three modes are: |
| |
| @itemize @bullet |
| @item @i{Use base type for intermediate operations} (@code{STRICT}) |
| |
| In this mode, all intermediate results for predefined arithmetic |
| operators are computed using the base type, and the result must |
| be in range of the base type. If this is not the |
| case then either an exception is raised (if overflow checks are |
| enabled) or the execution is erroneous (if overflow checks are suppressed). |
| This is the normal default mode. |
| |
| @item @i{Most intermediate overflows avoided} (@code{MINIMIZED}) |
| |
| In this mode, the compiler attempts to avoid intermediate overflows by |
| using a larger integer type, typically @code{Long_Long_Integer}, |
| as the type in which arithmetic is |
| performed for predefined arithmetic operators. This may be slightly more |
| expensive at |
| run time (compared to suppressing intermediate overflow checks), though |
| the cost is negligible on modern 64-bit machines. For the examples given |
| earlier, no intermediate overflows would have resulted in exceptions, |
| since the intermediate results are all in the range of |
| @code{Long_Long_Integer} (typically 64-bits on nearly all implementations |
| of GNAT). In addition, if checks are enabled, this reduces the number of |
| checks that must be made, so this choice may actually result in an |
| improvement in space and time behavior. |
| |
| However, there are cases where @code{Long_Long_Integer} is not large |
| enough, consider the following example: |
| |
| @smallexample @c ada |
| procedure R (A, B, C, D : Integer) with |
| Pre => (A**2 * B**2) / (C**2 * D**2) <= 10; |
| @end smallexample |
| |
| where @code{A} = @code{B} = @code{C} = @code{D} = @code{Integer'Last}. |
| Now the intermediate results are |
| out of the range of @code{Long_Long_Integer} even though the final result |
| is in range and the precondition is True (from a mathematical point |
| of view). In such a case, operating in this mode, an overflow occurs |
| for the intermediate computation (which is why this mode |
| says @i{most} intermediate overflows are avoided). In this case, |
| an exception is raised if overflow checks are enabled, and the |
| execution is erroneous if overflow checks are suppressed. |
| |
| @item @i{All intermediate overflows avoided} (@code{ELIMINATED}) |
| |
| In this mode, the compiler avoids all intermediate overflows |
| by using arbitrary precision arithmetic as required. In this |
| mode, the above example with @code{A**2 * B**2} would |
| not cause intermediate overflow, because the intermediate result |
| would be evaluated using sufficient precision, and the result |
| of evaluating the precondition would be True. |
| |
| This mode has the advantage of avoiding any intermediate |
| overflows, but at the expense of significant run-time overhead, |
| including the use of a library (included automatically in this |
| mode) for multiple-precision arithmetic. |
| |
| This mode provides cleaner semantics for assertions, since now |
| the run-time behavior emulates true arithmetic behavior for the |
| predefined arithmetic operators, meaning that there is never a |
| conflict between the mathematical view of the assertion, and its |
| run-time behavior. |
| |
| Note that in this mode, the behavior is unaffected by whether or |
| not overflow checks are suppressed, since overflow does not occur. |
| It is possible for gigantic intermediate expressions to raise |
| @code{Storage_Error} as a result of attempting to compute the |
| results of such expressions (e.g. @code{Integer'Last ** Integer'Last}) |
| but overflow is impossible. |
| |
| |
| @end itemize |
| |
| @noindent |
| Note that these modes apply only to the evaluation of predefined |
| arithmetic, membership, and comparison operators for signed integer |
| aritmetic. |
| |
| For fixed-point arithmetic, checks can be suppressed. But if checks |
| are enabled |
| then fixed-point values are always checked for overflow against the |
| base type for intermediate expressions (that is such checks always |
| operate in the equivalent of @code{STRICT} mode). |
| |
| For floating-point, on nearly all architectures, @code{Machine_Overflows} |
| is False, and IEEE infinities are generated, so overflow exceptions |
| are never raised. If you want to avoid infinities, and check that |
| final results of expressions are in range, then you can declare a |
| constrained floating-point type, and range checks will be carried |
| out in the normal manner (with infinite values always failing all |
| range checks). |
| |
| |
| @c ------------------------- |
| @node Specifying the Desired Mode |
| @section Specifying the Desired Mode |
| |
| @noindent |
| The desired mode of for handling intermediate overflow can be specified using |
| either the @code{Overflow_Mode} pragma or an equivalent compiler switch. |
| The pragma has the form |
| @cindex pragma @code{Overflow_Mode} |
| |
| @smallexample @c ada |
| pragma Overflow_Mode ([General =>] MODE [, [Assertions =>] MODE]); |
| @end smallexample |
| |
| @noindent |
| where @code{MODE} is one of |
| |
| @itemize @bullet |
| @item @code{STRICT}: intermediate overflows checked (using base type) |
| @item @code{MINIMIZED}: minimize intermediate overflows |
| @item @code{ELIMINATED}: eliminate intermediate overflows |
| @end itemize |
| |
| @noindent |
| The case is ignored, so @code{MINIMIZED}, @code{Minimized} and |
| @code{minimized} all have the same effect. |
| |
| If only the @code{General} parameter is present, then the given @code{MODE} |
| applies |
| to expressions both within and outside assertions. If both arguments |
| are present, then @code{General} applies to expressions outside assertions, |
| and @code{Assertions} applies to expressions within assertions. For example: |
| |
| @smallexample @c ada |
| pragma Overflow_Mode |
| (General => Minimized, Assertions => Eliminated); |
| @end smallexample |
| |
| @noindent |
| specifies that general expressions outside assertions be evaluated |
| in ``minimize intermediate overflows'' mode, and expressions within |
| assertions be evaluated in ``eliminate intermediate overflows'' mode. |
| This is often a reasonable choice, avoiding excessive overhead |
| outside assertions, but assuring a high degree of portability |
| when importing code from another compiler, while incurring |
| the extra overhead for assertion expressions to ensure that |
| the behavior at run time matches the expected mathematical |
| behavior. |
| |
| The @code{Overflow_Mode} pragma has the same scoping and placement |
| rules as pragma @code{Suppress}, so it can occur either as a |
| configuration pragma, specifying a default for the whole |
| program, or in a declarative scope, where it applies to the |
| remaining declarations and statements in that scope. |
| |
| Note that pragma @code{Overflow_Mode} does not affect whether |
| overflow checks are enabled or suppressed. It only controls the |
| method used to compute intermediate values. To control whether |
| overflow checking is enabled or suppressed, use pragma @code{Suppress} |
| or @code{Unsuppress} in the usual manner |
| |
| Additionally, a compiler switch @option{-gnato?} or @option{-gnato??} |
| can be used to control the checking mode default (which can be subsequently |
| overridden using pragmas). |
| @cindex @option{-gnato?} (gcc) |
| @cindex @option{-gnato??} (gcc) |
| |
| Here `@code{?}' is one of the digits `@code{1}' through `@code{3}': |
| |
| @itemize @bullet |
| @item @code{1}: |
| use base type for intermediate operations (@code{STRICT}) |
| @item @code{2}: |
| minimize intermediate overflows (@code{MINIMIZED}) |
| @item @code{3}: |
| eliminate intermediate overflows (@code{ELIMINATED}) |
| @end itemize |
| |
| @noindent |
| As with the pragma, if only one digit appears then it applies to all |
| cases; if two digits are given, then the first applies outside |
| assertions, and the second within assertions. Thus the equivalent |
| of the example pragma above would be @option{-gnato23}. |
| |
| If no digits follow the @option{-gnato}, then it is equivalent to |
| @option{-gnato11}, |
| causing all intermediate operations to be computed using the base |
| type (@code{STRICT} mode). |
| |
| In addition to setting the mode used for computation of intermediate |
| results, the @code{-gnato} switch also enables overflow checking (which |
| is suppressed by default). It thus combines the effect of using |
| a pragma @code{Overflow_Mode} and pragma @code{Unsuppress}. |
| |
| |
| @c ------------------------- |
| @node Default Settings |
| @section Default Settings |
| |
| The default mode for overflow checks is |
| |
| @smallexample |
| General => Strict |
| @end smallexample |
| |
| @noindent |
| which causes all computations both inside and outside assertions to use |
| the base type. In addition overflow checks are suppressed. |
| |
| This retains compatibility with previous versions of |
| GNAT which suppressed overflow checks by default and always |
| used the base type for computation of intermediate results. |
| |
| The switch @option{-gnato} (with no digits following) is equivalent to |
| @cindex @option{-gnato} (gcc) |
| |
| @smallexample |
| General => Strict |
| @end smallexample |
| |
| @noindent |
| which causes overflow checking of all intermediate overflows |
| both inside and outside assertions against the base type. |
| This provides compatibility |
| with this switch as implemented in previous versions of GNAT. |
| |
| The pragma @code{Suppress (Overflow_Check)} disables overflow |
| checking, but it has no effect on the method used for computing |
| intermediate results. |
| |
| The pragma @code{Unsuppress (Overflow_Check)} enables overflow |
| checking, but it has no effect on the method used for computing |
| intermediate results. |
| |
| @c ------------------------- |
| @node Implementation Notes |
| @section Implementation Notes |
| |
| In practice on typical 64-bit machines, the @code{MINIMIZED} mode is |
| reasonably efficient, and can be generally used. It also helps |
| to ensure compatibility with code imported from some other |
| compiler to GNAT. |
| |
| Setting all intermediate overflows checking (@code{CHECKED} mode) |
| makes sense if you want to |
| make sure that your code is compatible with any other possible |
| Ada implementation. This may be useful in ensuring portability |
| for code that is to be exported to some other compiler than GNAT. |
| |
| |
| The Ada standard allows the reassociation of expressions at |
| the same precedence level if no parentheses are present. For |
| example, @w{@code{A+B+C}} parses as though it were @w{@code{(A+B)+C}}, but |
| the compiler can reintepret this as @w{@code{A+(B+C)}}, possibly |
| introducing or eliminating an overflow exception. The GNAT |
| compiler never takes advantage of this freedom, and the |
| expression @w{@code{A+B+C}} will be evaluated as @w{@code{(A+B)+C}}. |
| If you need the other order, you can write the parentheses |
| explicitly @w{@code{A+(B+C)}} and GNAT will respect this order. |
| |
| The use of @code{ELIMINATED} mode will cause the compiler to |
| automatically include an appropriate arbitrary precision |
| integer arithmetic package. The compiler will make calls |
| to this package, though only in cases where it cannot be |
| sure that @code{Long_Long_Integer} is sufficient to guard against |
| intermediate overflows. This package does not use dynamic |
| alllocation, but it does use the secondary stack, so an |
| appropriate secondary stack package must be present (this |
| is always true for standard full Ada, but may require |
| specific steps for restricted run times such as ZFP). |
| |
| Although @code{ELIMINATED} mode causes expressions to use arbitrary |
| precision arithmetic, avoiding overflow, the final result |
| must be in an appropriate range. This is true even if the |
| final result is of type @code{[Long_[Long_]]Integer'Base}, which |
| still has the same bounds as its associated constrained |
| type at run-time. |
| |
| Currently, the @code{ELIMINATED} mode is only available on target |
| platforms for which @code{Long_Long_Integer} is 64-bits (nearly all GNAT |
| platforms). |
| |
| @c ******************************* |
| @node Conditional Compilation |
| @appendix Conditional Compilation |
| @c ******************************* |
| @cindex Conditional compilation |
| |
| @noindent |
| It is often necessary to arrange for a single source program |
| to serve multiple purposes, where it is compiled in different |
| ways to achieve these different goals. Some examples of the |
| need for this feature are |
| |
| @itemize @bullet |
| @item Adapting a program to a different hardware environment |
| @item Adapting a program to a different target architecture |
| @item Turning debugging features on and off |
| @item Arranging for a program to compile with different compilers |
| @end itemize |
| |
| @noindent |
| In C, or C++, the typical approach would be to use the preprocessor |
| that is defined as part of the language. The Ada language does not |
| contain such a feature. This is not an oversight, but rather a very |
| deliberate design decision, based on the experience that overuse of |
| the preprocessing features in C and C++ can result in programs that |
| are extremely difficult to maintain. For example, if we have ten |
| switches that can be on or off, this means that there are a thousand |
| separate programs, any one of which might not even be syntactically |
| correct, and even if syntactically correct, the resulting program |
| might not work correctly. Testing all combinations can quickly become |
| impossible. |
| |
| Nevertheless, the need to tailor programs certainly exists, and in |
| this Appendix we will discuss how this can |
| be achieved using Ada in general, and GNAT in particular. |
| |
| @menu |
| * Use of Boolean Constants:: |
| * Debugging - A Special Case:: |
| * Conditionalizing Declarations:: |
| * Use of Alternative Implementations:: |
| * Preprocessing:: |
| @end menu |
| |
| @node Use of Boolean Constants |
| @section Use of Boolean Constants |
| |
| @noindent |
| In the case where the difference is simply which code |
| sequence is executed, the cleanest solution is to use Boolean |
| constants to control which code is executed. |
| |
| @smallexample @c ada |
| @group |
| FP_Initialize_Required : constant Boolean := True; |
| @dots{} |
| if FP_Initialize_Required then |
| @dots{} |
| end if; |
| @end group |
| @end smallexample |
| |
| @noindent |
| Not only will the code inside the @code{if} statement not be executed if |
| the constant Boolean is @code{False}, but it will also be completely |
| deleted from the program. |
| However, the code is only deleted after the @code{if} statement |
| has been checked for syntactic and semantic correctness. |
| (In contrast, with preprocessors the code is deleted before the |
| compiler ever gets to see it, so it is not checked until the switch |
| is turned on.) |
| @cindex Preprocessors (contrasted with conditional compilation) |
| |
| Typically the Boolean constants will be in a separate package, |
| something like: |
| |
| @smallexample @c ada |
| @group |
| package Config is |
| FP_Initialize_Required : constant Boolean := True; |
| Reset_Available : constant Boolean := False; |
| @dots{} |
| end Config; |
| @end group |
| @end smallexample |
| |
| @noindent |
| The @code{Config} package exists in multiple forms for the various targets, |
| with an appropriate script selecting the version of @code{Config} needed. |
| Then any other unit requiring conditional compilation can do a @code{with} |
| of @code{Config} to make the constants visible. |
| |
| |
| @node Debugging - A Special Case |
| @section Debugging - A Special Case |
| |
| @noindent |
| A common use of conditional code is to execute statements (for example |
| dynamic checks, or output of intermediate results) under control of a |
| debug switch, so that the debugging behavior can be turned on and off. |
| This can be done using a Boolean constant to control whether the code |
| is active: |
| |
| @smallexample @c ada |
| @group |
| if Debugging then |
| Put_Line ("got to the first stage!"); |
| end if; |
| @end group |
| @end smallexample |
| |
| @noindent |
| or |
| |
| @smallexample @c ada |
| @group |
| if Debugging and then Temperature > 999.0 then |
| raise Temperature_Crazy; |
| end if; |
| @end group |
| @end smallexample |
| |
| @noindent |
| Since this is a common case, there are special features to deal with |
| this in a convenient manner. For the case of tests, Ada 2005 has added |
| a pragma @code{Assert} that can be used for such tests. This pragma is modeled |
| @cindex pragma @code{Assert} |
| on the @code{Assert} pragma that has always been available in GNAT, so this |
| feature may be used with GNAT even if you are not using Ada 2005 features. |
| The use of pragma @code{Assert} is described in |
| @ref{Pragma Assert,,, gnat_rm, GNAT Reference Manual}, but as an |
| example, the last test could be written: |
| |
| @smallexample @c ada |
| pragma Assert (Temperature <= 999.0, "Temperature Crazy"); |
| @end smallexample |
| |
| @noindent |
| or simply |
| |
| @smallexample @c ada |
| pragma Assert (Temperature <= 999.0); |
| @end smallexample |
| |
| @noindent |
| In both cases, if assertions are active and the temperature is excessive, |
| the exception @code{Assert_Failure} will be raised, with the given string in |
| the first case or a string indicating the location of the pragma in the second |
| case used as the exception message. |
| |
| You can turn assertions on and off by using the @code{Assertion_Policy} |
| pragma. |
| @cindex pragma @code{Assertion_Policy} |
| This is an Ada 2005 pragma which is implemented in all modes by |
| GNAT, but only in the latest versions of GNAT which include Ada 2005 |
| capability. Alternatively, you can use the @option{-gnata} switch |
| @cindex @option{-gnata} switch |
| to enable assertions from the command line (this is recognized by all versions |
| of GNAT). |
| |
| For the example above with the @code{Put_Line}, the GNAT-specific pragma |
| @code{Debug} can be used: |
| @cindex pragma @code{Debug} |
| |
| @smallexample @c ada |
| pragma Debug (Put_Line ("got to the first stage!")); |
| @end smallexample |
| |
| @noindent |
| If debug pragmas are enabled, the argument, which must be of the form of |
| a procedure call, is executed (in this case, @code{Put_Line} will be called). |
| Only one call can be present, but of course a special debugging procedure |
| containing any code you like can be included in the program and then |
| called in a pragma @code{Debug} argument as needed. |
| |
| One advantage of pragma @code{Debug} over the @code{if Debugging then} |
| construct is that pragma @code{Debug} can appear in declarative contexts, |
| such as at the very beginning of a procedure, before local declarations have |
| been elaborated. |
| |
| Debug pragmas are enabled using either the @option{-gnata} switch that also |
| controls assertions, or with a separate Debug_Policy pragma. |
| @cindex pragma @code{Debug_Policy} |
| The latter pragma is new in the Ada 2005 versions of GNAT (but it can be used |
| in Ada 95 and Ada 83 programs as well), and is analogous to |
| pragma @code{Assertion_Policy} to control assertions. |
| |
| @code{Assertion_Policy} and @code{Debug_Policy} are configuration pragmas, |
| and thus they can appear in @file{gnat.adc} if you are not using a |
| project file, or in the file designated to contain configuration pragmas |
| in a project file. |
| They then apply to all subsequent compilations. In practice the use of |
| the @option{-gnata} switch is often the most convenient method of controlling |
| the status of these pragmas. |
| |
| Note that a pragma is not a statement, so in contexts where a statement |
| sequence is required, you can't just write a pragma on its own. You have |
| to add a @code{null} statement. |
| |
| @smallexample @c ada |
| @group |
| if @dots{} then |
| @dots{} -- some statements |
| else |
| pragma Assert (Num_Cases < 10); |
| null; |
| end if; |
| @end group |
| @end smallexample |
| |
| |
| @node Conditionalizing Declarations |
| @section Conditionalizing Declarations |
| |
| @noindent |
| In some cases, it may be necessary to conditionalize declarations to meet |
| different requirements. For example we might want a bit string whose length |
| is set to meet some hardware message requirement. |
| |
| In some cases, it may be possible to do this using declare blocks controlled |
| by conditional constants: |
| |
| @smallexample @c ada |
| @group |
| if Small_Machine then |
| declare |
| X : Bit_String (1 .. 10); |
| begin |
| @dots{} |
| end; |
| else |
| declare |
| X : Large_Bit_String (1 .. 1000); |
| begin |
| @dots{} |
| end; |
| end if; |
| @end group |
| @end smallexample |
| |
| @noindent |
| Note that in this approach, both declarations are analyzed by the |
| compiler so this can only be used where both declarations are legal, |
| even though one of them will not be used. |
| |
| Another approach is to define integer constants, e.g.@: @code{Bits_Per_Word}, |
| or Boolean constants, e.g.@: @code{Little_Endian}, and then write declarations |
| that are parameterized by these constants. For example |
| |
| @smallexample @c ada |
| @group |
| for Rec use |
| Field1 at 0 range Boolean'Pos (Little_Endian) * 10 .. Bits_Per_Word; |
| end record; |
| @end group |
| @end smallexample |
| |
| @noindent |
| If @code{Bits_Per_Word} is set to 32, this generates either |
| |
| @smallexample @c ada |
| @group |
| for Rec use |
| Field1 at 0 range 0 .. 32; |
| end record; |
| @end group |
| @end smallexample |
| |
| @noindent |
| for the big endian case, or |
| |
| @smallexample @c ada |
| @group |
| for Rec use record |
| Field1 at 0 range 10 .. 32; |
| end record; |
| @end group |
| @end smallexample |
| |
| @noindent |
| for the little endian case. Since a powerful subset of Ada expression |
| notation is usable for creating static constants, clever use of this |
| feature can often solve quite difficult problems in conditionalizing |
| compilation (note incidentally that in Ada 95, the little endian |
| constant was introduced as @code{System.Default_Bit_Order}, so you do not |
| need to define this one yourself). |
| |
| |
| @node Use of Alternative Implementations |
| @section Use of Alternative Implementations |
| |
| @noindent |
| In some cases, none of the approaches described above are adequate. This |
| can occur for example if the set of declarations required is radically |
| different for two different configurations. |
| |
| In this situation, the official Ada way of dealing with conditionalizing |
| such code is to write separate units for the different cases. As long as |
| this does not result in excessive duplication of code, this can be done |
| without creating maintenance problems. The approach is to share common |
| code as far as possible, and then isolate the code and declarations |
| that are different. Subunits are often a convenient method for breaking |
| out a piece of a unit that is to be conditionalized, with separate files |
| for different versions of the subunit for different targets, where the |
| build script selects the right one to give to the compiler. |
| @cindex Subunits (and conditional compilation) |
| |
| As an example, consider a situation where a new feature in Ada 2005 |
| allows something to be done in a really nice way. But your code must be able |
| to compile with an Ada 95 compiler. Conceptually you want to say: |
| |
| @smallexample @c ada |
| @group |
| if Ada_2005 then |
| @dots{} neat Ada 2005 code |
| else |
| @dots{} not quite as neat Ada 95 code |
| end if; |
| @end group |
| @end smallexample |
| |
| @noindent |
| where @code{Ada_2005} is a Boolean constant. |
| |
| But this won't work when @code{Ada_2005} is set to @code{False}, |
| since the @code{then} clause will be illegal for an Ada 95 compiler. |
| (Recall that although such unreachable code would eventually be deleted |
| by the compiler, it still needs to be legal. If it uses features |
| introduced in Ada 2005, it will be illegal in Ada 95.) |
| |
| So instead we write |
| |
| @smallexample @c ada |
| procedure Insert is separate; |
| @end smallexample |
| |
| @noindent |
| Then we have two files for the subunit @code{Insert}, with the two sets of |
| code. |
| If the package containing this is called @code{File_Queries}, then we might |
| have two files |
| |
| @itemize @bullet |
| @item @file{file_queries-insert-2005.adb} |
| @item @file{file_queries-insert-95.adb} |
| @end itemize |
| |
| @noindent |
| and the build script renames the appropriate file to |
| |
| @smallexample |
| file_queries-insert.adb |
| @end smallexample |
| |
| @noindent |
| and then carries out the compilation. |
| |
| This can also be done with project files' naming schemes. For example: |
| |
| @smallexample @c project |
| For Body ("File_Queries.Insert") use "file_queries-insert-2005.ada"; |
| @end smallexample |
| |
| @noindent |
| Note also that with project files it is desirable to use a different extension |
| than @file{ads} / @file{adb} for alternative versions. Otherwise a naming |
| conflict may arise through another commonly used feature: to declare as part |
| of the project a set of directories containing all the sources obeying the |
| default naming scheme. |
| |
| The use of alternative units is certainly feasible in all situations, |
| and for example the Ada part of the GNAT run-time is conditionalized |
| based on the target architecture using this approach. As a specific example, |
| consider the implementation of the AST feature in VMS. There is one |
| spec: |
| |
| @smallexample |
| s-asthan.ads |
| @end smallexample |
| |
| @noindent |
| which is the same for all architectures, and three bodies: |
| |
| @table @file |
| @item s-asthan.adb |
| used for all non-VMS operating systems |
| @item s-asthan-vms-alpha.adb |
| used for VMS on the Alpha |
| @item s-asthan-vms-ia64.adb |
| used for VMS on the ia64 |
| @end table |
| |
| @noindent |
| The dummy version @file{s-asthan.adb} simply raises exceptions noting that |
| this operating system feature is not available, and the two remaining |
| versions interface with the corresponding versions of VMS to provide |
| VMS-compatible AST handling. The GNAT build script knows the architecture |
| and operating system, and automatically selects the right version, |
| renaming it if necessary to @file{s-asthan.adb} before the run-time build. |
| |
| Another style for arranging alternative implementations is through Ada's |
| access-to-subprogram facility. |
| In case some functionality is to be conditionally included, |
| you can declare an access-to-procedure variable @code{Ref} that is initialized |
| to designate a ``do nothing'' procedure, and then invoke @code{Ref.all} |
| when appropriate. |
| In some library package, set @code{Ref} to @code{Proc'Access} for some |
| procedure @code{Proc} that performs the relevant processing. |
| The initialization only occurs if the library package is included in the |
| program. |
| The same idea can also be implemented using tagged types and dispatching |
| calls. |
| |
| |
| @node Preprocessing |
| @section Preprocessing |
| @cindex Preprocessing |
| |
| @noindent |
| Although it is quite possible to conditionalize code without the use of |
| C-style preprocessing, as described earlier in this section, it is |
| nevertheless convenient in some cases to use the C approach. Moreover, |
| older Ada compilers have often provided some preprocessing capability, |
| so legacy code may depend on this approach, even though it is not |
| standard. |
| |
| To accommodate such use, GNAT provides a preprocessor (modeled to a large |
| extent on the various preprocessors that have been used |
| with legacy code on other compilers, to enable easier transition). |
| |
| The preprocessor may be used in two separate modes. It can be used quite |
| separately from the compiler, to generate a separate output source file |
| that is then fed to the compiler as a separate step. This is the |
| @code{gnatprep} utility, whose use is fully described in |
| @ref{Preprocessing Using gnatprep}. |
| @cindex @code{gnatprep} |
| |
| The preprocessing language allows such constructs as |
| |
| @smallexample |
| @group |
| #if DEBUG or PRIORITY > 4 then |
| bunch of declarations |
| #else |
| completely different bunch of declarations |
| #end if; |
| @end group |
| @end smallexample |
| |
| @noindent |
| The values of the symbols @code{DEBUG} and @code{PRIORITY} can be |
| defined either on the command line or in a separate file. |
| |
| The other way of running the preprocessor is even closer to the C style and |
| often more convenient. In this approach the preprocessing is integrated into |
| the compilation process. The compiler is fed the preprocessor input which |
| includes @code{#if} lines etc, and then the compiler carries out the |
| preprocessing internally and processes the resulting output. |
| For more details on this approach, see @ref{Integrated Preprocessing}. |
| |
| |
| @c ******************************* |
| @node Inline Assembler |
| @appendix Inline Assembler |
| @c ******************************* |
| |
| @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 @ref{Machine Code Insertions,,, gnat_rm, 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", |
| Outputs => Unsigned_32'Asm_Output ("=a", Result), |
| Inputs => Unsigned_32'Asm_Input ("a", Value)); |
| 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, still starts at the first output statement, |
| and continues with the input statements. |
| |
| 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", |
| Outputs => Unsigned_32'Asm_Output ("=a", Result), |
| Inputs => Unsigned_32'Asm_Input ("a", Value)); |
| 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 |
| (@option{-gnatn}) enabled. |
| |
| 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", |
| Outputs => Unsigned_32'Asm_Output ("=g", Var_Out), |
| Inputs => Unsigned_32'Asm_Input ("g", Var_In)); |
| @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", |
| Outputs => Unsigned_32'Asm_Output ("=g", Var_Out), |
| Inputs => Unsigned_32'Asm_Input ("g", Var_In), |
| 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", |
| Outputs => Unsigned_32'Asm_Output ("=g", Var_Out), |
| Inputs => Unsigned_32'Asm_Input ("g", Var_In), |
| 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 compilation systems (including those for Ada 83), |
| and shows how GNAT can expedite porting |
| applications developed in other Ada environments. |
| |
| @menu |
| * Compatibility with Ada 83:: |
| * Compatibility between Ada 95 and Ada 2005:: |
| * Implementation-dependent characteristics:: |
| * Compatibility with Other Ada 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 to 64-Bit GNAT for OpenVMS:: |
| @end ifset |
| @end menu |
| |
| @node Compatibility with Ada 83 |
| @section Compatibility with Ada 83 |
| @cindex Compatibility (between Ada 83 and Ada 95 / Ada 2005) |
| |
| @noindent |
| Ada 95 and Ada 2005 are highly upwards compatible with Ada 83. In |
| particular, the design intention was that the difficulties associated |
| with moving from Ada 83 to Ada 95 or Ada 2005 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 |
| |
| Some legal Ada 83 programs are illegal (i.e., they will fail to compile) in |
| Ada 95 and thus also in Ada 2005: |
| |
| @table @emph |
| @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 @dots{} 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 @dots{} 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 |
| subtype 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 @emph |
| @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 @emph |
| @item Range of type @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 @emph |
| @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 reserved words introduced in Ada 95 and Ada 2005 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 were removed from Ada 95, |
| generally because they were replaced by other mechanisms. Ada 95 and Ada 2005 |
| compilers are allowed, but not required, to implement these missing |
| elements. In contrast with some other 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 Compatibility between Ada 95 and Ada 2005 |
| @section Compatibility between Ada 95 and Ada 2005 |
| @cindex Compatibility between Ada 95 and Ada 2005 |
| |
| @noindent |
| Although Ada 2005 was designed to be upwards compatible with Ada 95, there are |
| a number of incompatibilities. Several are enumerated below; |
| for a complete description please see the |
| Annotated Ada 2005 Reference Manual, or section 9.1.1 in |
| @cite{Rationale for Ada 2005}. |
| |
| @table @emph |
| @item New reserved words. |
| The words @code{interface}, @code{overriding} and @code{synchronized} are |
| reserved in Ada 2005. |
| A pre-Ada 2005 program that uses any of these as an identifier will be |
| illegal. |
| |
| @item New declarations in predefined packages. |
| A number of packages in the predefined environment contain new declarations: |
| @code{Ada.Exceptions}, @code{Ada.Real_Time}, @code{Ada.Strings}, |
| @code{Ada.Strings.Fixed}, @code{Ada.Strings.Bounded}, |
| @code{Ada.Strings.Unbounded}, @code{Ada.Strings.Wide_Fixed}, |
| @code{Ada.Strings.Wide_Bounded}, @code{Ada.Strings.Wide_Unbounded}, |
| @code{Ada.Tags}, @code{Ada.Text_IO}, and @code{Interfaces.C}. |
| If an Ada 95 program does a @code{with} and @code{use} of any of these |
| packages, the new declarations may cause name clashes. |
| |
| @item Access parameters. |
| A nondispatching subprogram with an access parameter cannot be renamed |
| as a dispatching operation. This was permitted in Ada 95. |
| |
| @item Access types, discriminants, and constraints. |
| Rule changes in this area have led to some incompatibilities; for example, |
| constrained subtypes of some access types are not permitted in Ada 2005. |
| |
| @item Aggregates for limited types. |
| The allowance of aggregates for limited types in Ada 2005 raises the |
| possibility of ambiguities in legal Ada 95 programs, since additional types |
| now need to be considered in expression resolution. |
| |
| @item Fixed-point multiplication and division. |
| Certain expressions involving ``*'' or ``/'' for a fixed-point type, which |
| were legal in Ada 95 and invoked the predefined versions of these operations, |
| are now ambiguous. |
| The ambiguity may be resolved either by applying a type conversion to the |
| expression, or by explicitly invoking the operation from package |
| @code{Standard}. |
| |
| @item Return-by-reference types. |
| The Ada 95 return-by-reference mechanism has been removed. Instead, the user |
| can declare a function returning a value from an anonymous access type. |
| @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 @ref{Implementation Defined Pragmas,,, gnat_rm, 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 |
| @ref{Implementation Defined Attributes,,, gnat_rm, 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 or Ada 2005: |
| @enumerate |
| @item |
| If the source code for the libraries (specs and bodies) are |
| available, then the libraries can be migrated in the same way as the |
| application. |
| @item |
| If the source code for the specs but not the bodies are |
| available, then you can reimplement the bodies. |
| @item |
| Some features introduced by Ada 95 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 (and thus |
| Ada 2005) are 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 Systems |
| @section Compatibility with Other Ada Systems |
| |
| @noindent |
| If programs avoid the use of implementation dependent and |
| implementation defined features, as documented in the @cite{Ada |
| Reference Manual}, there should be a high degree of portability between |
| GNAT and other Ada systems. The following are specific items which |
| have proved troublesome in moving Ada 95 programs from GNAT to other Ada 95 |
| compilers, but do not affect porting code to GNAT@. |
| (As of @value{NOW}, GNAT is the only compiler available for Ada 2005; |
| the following issues may or may not arise for Ada 2005 programs |
| when other compilers appear.) |
| |
| @table @emph |
| @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 Specialized 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. Ada 95 (and thus also Ada 2005) are much more explicit, but the |
| minimal set of capabilities required is still quite limited. |
| |
| GNAT implements the full required set of capabilities in |
| Ada 95 and Ada 2005, but also goes much further, 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 |
| the requirements in Ada 95 (and thus also Ada 2005). 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 Ada 83 code. |
| |
| @table @emph |
| @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 (and Ada 2005) |
| Reference Manuals 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 (and Ada 2005) for discrete types is defined as |
| the minimal number of bits required to hold values of the type. For example, |
| on a 32-bit machine, the size of @code{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 @emph |
| @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 (@i{universal_integer}) |
| @end smallexample |
| |
| @noindent |
| The version of TO_ADDRESS taking a @i{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 @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 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 |
| |
| @noindent |
| 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 @ref{Implementation |
| Defined Pragmas,,, gnat_rm, GNAT Reference Manual} |
| indicates whether or not they are applicable to non-VMS systems. |
| @end ifclear |
| |
| @ifset vms |
| @node Transitioning to 64-Bit GNAT for OpenVMS |
| @section Transitioning to 64-Bit @value{EDITION} for OpenVMS |
| |
| @noindent |
| This section is meant to assist users of pre-2006 @value{EDITION} |
| for Alpha OpenVMS who are transitioning to 64-bit @value{EDITION}, |
| the version of the GNAT technology supplied in 2006 and later for |
| OpenVMS on both Alpha and I64. |
| |
| @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 |
| |
| @noindent |
| 64-bit @value{EDITION} for Open VMS has been designed to meet |
| three main goals: |
| |
| @enumerate |
| @item |
| Providing a full conforming implementation of Ada 95 and Ada 2005 |
| |
| @item |
| Allowing maximum backward compatibility, thus easing migration of existing |
| Ada source code |
| |
| @item |
| Supplying a path for exploiting the full 64-bit 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. |
| |
| @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 64-bit address space, |
| @ref{Taking advantage of 64 bit addressing}, |
| will consider further changes that may be required. |
| Such code will be referred to below as @emph{64-bit code}. |
| |
| @node Migration of 32 bit code |
| @subsection Migration of 32-bit code |
| |
| @menu |
| * Address types:: |
| * Access types and 32/64-bit allocation:: |
| * Unchecked conversions:: |
| * Predefined constants:: |
| * Interfacing with C:: |
| * 32/64-bit descriptors:: |
| * 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 |
| @cindex @code{System.Address} size |
| @cindex @code{Address} size |
| |
| @item |
| @code{System.Short_Address} is a 32-bit subtype of @code{System.Address} |
| @cindex @code{System.Short_Address} size |
| @cindex @code{Short_Address} size |
| @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 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}, 64-bit @value{EDITION} for OpenVMS |
| 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 and 32/64-bit allocation |
| @subsubsection Access types and 32/64-bit allocation |
| @cindex 32-bit allocation |
| @cindex 64-bit allocation |
| |
| @noindent |
| By default, objects designated by access values are always allocated in |
| the 64-bit address space, and access values themselves are represented |
| in 64 bits. If these defaults are not appropriate, and 32-bit allocation |
| is required (for example if the address of an allocated object is assigned |
| to a @code{Short_Address} variable), then several alternatives are available: |
| |
| @itemize @bullet |
| @item |
| A pool-specific access type (ie, an @w{Ada 83} access type, whose |
| definition is @code{access T} versus @code{access all T} or |
| @code{access constant T}), may be declared with a @code{'Size} representation |
| clause that establishes the size as 32 bits. |
| In such circumstances allocations for that type will |
| be from the 32-bit heap. Such a clause is not permitted |
| for a general access type (declared with @code{access all} or |
| @code{access constant}) 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 @w{Ada 83} code will not contain such |
| type definitions, however, since general access types were introduced |
| in @w{Ada 95}. |
| |
| @item |
| Switches for @command{GNAT BIND} control whether the internal GNAT |
| allocation routine @code{__gnat_malloc} uses 64-bit or 32-bit allocations. |
| @cindex @code{__gnat_malloc} |
| The switches are respectively @option{-H64} (the default) and |
| @option{-H32}. |
| @cindex @option{-H32} (@command{gnatbind}) |
| @cindex @option{-H64} (@command{gnatbind}) |
| |
| @item |
| The environment variable (logical name) @code{GNAT$NO_MALLOC_64} |
| @cindex @code{GNAT$NO_MALLOC_64} environment variable |
| may be used to force @code{__gnat_malloc} to use 32-bit allocation. |
| If this variable is left |
| undefined, or defined as @code{"DISABLE"}, @code{"FALSE"}, or @code{"0"}, |
| then the default (64-bit) allocation is used. |
| If defined as @code{"ENABLE"}, @code{"TRUE"}, or @code{"1"}, |
| then 32-bit allocation is used. The gnatbind qualifiers described above |
| override this logical name. |
| |
| @item |
| A ^gcc switch^gcc switch^ for OpenVMS, @option{-mno-malloc64}, operates |
| @cindex @option{-mno-malloc64} (^gcc^gcc^) |
| at a low level to convert explicit calls to @code{malloc} and related |
| functions from the C run-time library so that they perform allocations |
| in the 32-bit heap. |
| Since all internal allocations from GNAT use @code{__gnat_malloc}, |
| this switch is not required unless the program makes explicit calls on |
| @code{malloc} (or related functions) from interfaced C code. |
| @end itemize |
| |
| |
| @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 table shows the correspondence between pre-2006 versions of |
| @value{EDITION} on Alpha OpenVMS (``Old'') and 64-bit @value{EDITION} |
| (``New''): |
| |
| @multitable {@code{System.Short_Memory_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.Short_Memory_Size} @tab 2**32 @tab 2**32 |
| @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 Interfacing with C |
| @subsubsection Interfacing with C |
| |
| @noindent |
| In order to minimize the impact of the transition to 64-bit addresses on |
| legacy programs, some fundamental types in the @code{Interfaces.C} |
| package hierarchy continue to be represented in 32 bits. |
| These types are: @code{ptrdiff_t}, @code{size_t}, and @code{chars_ptr}. |
| This eases integration with the default HP C layout choices, for example |
| as found in the system routines in @code{DECC$SHR.EXE}. |
| Because of this implementation choice, the type fully compatible with |
| @code{chars_ptr} is now @code{Short_Address} and not @code{Address}. |
| Depending on the context the compiler will issue a |
| warning or an error when type @code{Address} is used, alerting the user to a |
| potential problem. Otherwise 32-bit programs that use |
| @code{Interfaces.C} should normally not require code modifications |
| |
| The other issue arising with C interfacing concerns pragma @code{Convention}. |
| For VMS 64-bit systems, there is an issue of the appropriate default size |
| of C convention pointers in the absence of an explicit size clause. The HP |
| C compiler can choose either 32 or 64 bits depending on compiler options. |
| GNAT chooses 32-bits rather than 64-bits in the default case where no size |
| clause is given. This proves a better choice for porting 32-bit legacy |
| applications. In order to have a 64-bit representation, it is necessary to |
| specify a size representation clause. For example: |
| |
| @smallexample @c ada |
| type int_star is access Interfaces.C.int; |
| pragma Convention(C, int_star); |
| for int_star'Size use 64; -- Necessary to get 64 and not 32 bits |
| @end smallexample |
| |
| @node 32/64-bit descriptors |
| @subsubsection 32/64-bit descriptors |
| |
| @noindent |
| By default, GNAT uses a 64-bit descriptor mechanism. For an imported |
| subprogram (i.e., a subprogram identified by pragma @code{Import_Function}, |
| @code{Import_Procedure}, or @code{Import_Valued_Procedure}) that specifies |
| @code{Short_Descriptor} as its mechanism, a 32-bit descriptor is used. |
| @cindex @code{Short_Descriptor} mechanism for imported subprograms |
| |
| If the configuration pragma @code{Short_Descriptors} is supplied, then |
| all descriptors will be 32 bits. |
| @cindex pragma @code{Short_Descriptors} |
| |
| @node Experience with source compatibility |
| @subsubsection Experience with source compatibility |
| |
| @noindent |
| The Security Server and STARLET on I64 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. |
| Future GNAT technology enhancements may include a tool that detects and flags |
| these sorts of potential source code porting problems. |
| |
| @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:: |
| * 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 |
| By default, all allocations -- for both pool-specific and general |
| access types -- use the 64-bit storage pool. To override |
| this default, for an individual access type or globally, see |
| @ref{Access types and 32/64-bit allocation}. |
| |
| @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 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 |
| specs to see in which contexts objects allocated |
| in 64-bit address space are acceptable. |
| |
| @node Technical details |
| @subsection Technical details |
| |
| @noindent |
| 64-bit @value{EDITION} for Open VMS takes advantage of the freedom given in the |
| Ada standard with respect to the type of @code{System.Address}. Previous |
| versions of @value{EDITION} 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 64-bit @value{EDITION} for Open VMS, @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}, a feature introduced in Ada 95 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 64-bit 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 Project files:: |
| * Building DLLs with GNAT:: |
| * 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 C++ libraries except for |
| import libraries. Interfacing must be done by the mean of DLLs. |
| |
| @item |
| It is possible to link against Microsoft C libraries. Yet the preferred |
| solution is to use C/C++ compiler that comes with @value{EDITION}, since it |
| doesn't require having two different development environments and makes the |
| inter-language debugging experience smoother. |
| |
| @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 @env{TMP} environment variable. The file will be created: |
| |
| @itemize |
| @item Under the directory pointed to by the @env{TMP} environment variable if |
| this directory exists. |
| |
| @item Under @file{c:\temp}, if the @env{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} or Microsoft C 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 do want |
| to use the Microsoft tools for your C++ code, you have two choices: |
| |
| @enumerate |
| @item |
| Encapsulate your C++ 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 Project files}) and use the Microsoft |
| or whatever environment to build your executable. |
| @end enumerate |
| |
| In addition to the description about C main in |
| @pxref{Mixed Language Programming} section, if the C main uses a |
| stand-alone library it is required on x86-windows to |
| setup the SEH context. For this the C main must looks like this: |
| |
| @smallexample |
| /* main.c */ |
| extern void adainit (void); |
| extern void adafinal (void); |
| extern void __gnat_initialize(void*); |
| extern void call_to_ada (void); |
| |
| int main (int argc, char *argv[]) |
| @{ |
| int SEH [2]; |
| |
| /* Initialize the SEH context */ |
| __gnat_initialize (&SEH); |
| |
| adainit(); |
| |
| /* Then call Ada services in the stand-alone library */ |
| |
| call_to_ada(); |
| |
| adafinal(); |
| @} |
| @end smallexample |
| |
| Note that this is not needed on x86_64-windows where the Windows |
| native SEH support is used. |
| |
| @node Windows Calling Conventions |
| @section Windows Calling Conventions |
| @findex Stdcall |
| @findex APIENTRY |
| |
| This section pertain only to Win32. On Win64 there is a single native |
| calling convention. All convention specifiers are ignored on this |
| platform. |
| |
| @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{@var{nn}}, where @var{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{@var{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}, that is, there is no |
| decoration at all. No leading underscore and no Stdcall suffix |
| @code{@@}@code{@var{nn}}. |
| |
| @noindent |
| This is especially important as in some special cases a DLL's entry |
| point name lacks a trailing @code{@@}@code{@var{nn}} while the exported |
| name generated for a call has it. |
| |
| @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.dll.a}, @file{libapi.dll.a}, |
| @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.dll.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.dll.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 for an import library. The linker will |
| look for a library name in this specific order: |
| |
| @enumerate |
| @item @file{libAPI.dll.a} |
| @item @file{API.dll.a} |
| @item @file{libAPI.a} |
| @item @file{API.lib} |
| @item @file{libAPI.dll} |
| @item @file{API.dll} |
| @end enumerate |
| |
| The first three are the GNU style import libraries. The third is the |
| Microsoft style import libraries. The last two are the actual DLL names. |
| |
| 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 DLL 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.dll.a} or @file{libAPI.a} is available |
| with @file{API.dll} you can skip this section. You can also skip this |
| section if @file{API.dll} or @file{libAPI.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 |
| @r{[}LIBRARY @var{name}@r{]} |
| @r{[}DESCRIPTION @var{string}@r{]} |
| EXPORTS |
| @var{symbol1} |
| @var{symbol2} |
| @dots{} |
| @end cartouche |
| @end group |
| @end smallexample |
| |
| @table @code |
| @item LIBRARY @var{name} |
| This section, which is optional, gives the name of the DLL. |
| |
| @item DESCRIPTION @var{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{@var{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{@@}@var{nn} |
| suffix then you'll have to edit @file{api.def} to add it, and specify |
| @option{-k} to @command{gnatdll} when creating the import library. |
| |
| @noindent |
| Here are some hints to find the right @code{@@}@var{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.dll.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 @var{xyz}@code{.def}, the import library name will |
| be @code{lib}@var{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 Project files |
| @section Building DLLs with GNAT Project files |
| @cindex DLLs, building |
| |
| @noindent |
| There is nothing specific to Windows in the build process. |
| @pxref{Library Projects}. |
| |
| @noindent |
| Due to a system limitation, it is not possible under Windows to create threads |
| when inside the @code{DllMain} routine which is used for auto-initialization |
| of shared libraries, so it is not possible to have library level tasks in SALs. |
| |
| @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 @option{-shared} and |
| @option{-shared-libgcc} options. It is quite simple to use this method: |
| |
| @smallexample |
| $ gcc -shared -shared-libgcc -o api.dll obj1.o obj2.o @dots{} |
| @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 -shared-libgcc -o api.dll api.def obj1.o obj2.o @dots{} |
| @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 @option{-shared} binder's |
| option. |
| |
| @smallexample |
| $ gnatmake main -Iapilib -bargs -shared -largs -Lapilib -lAPI |
| @end smallexample |
| |
| @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 GNAT Project files |
| (@pxref{Building DLLs with GNAT Project files}) or the built-in GNAT |
| DLL support (@pxref{Building DLLs with GNAT}) or 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; |
| |
| @dots{} |
| -- 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; |
| @dots{} |
| -- 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 |
| @c $ gnatdll @ovar{switches} @var{list-of-files} @r{[}-largs @var{opts}@r{]} |
| @c Expanding @ovar macro inline (explanation in macro def comments) |
| $ gnatdll @r{[}@var{switches}@r{]} @var{list-of-files} @r{[}-largs @var{opts}@r{]} |
| @end cartouche |
| @end smallexample |
| |
| @noindent |
| where @var{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 @var{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 |
| @c @item -a@ovar{address} |
| @c Expanding @ovar macro inline (explanation in macro def comments) |
| @item -a@r{[}@var{address}@r{]} |
| @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 |
| @code{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.dll.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{@@}@var{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{@@}@var{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.dll.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.dll.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 |
| @c $ dlltool @ovar{switches} |
| @c Expanding @ovar macro inline (explanation in macro def comments) |
| $ dlltool @r{[}@var{switches}@r{]} |
| @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{@@}@var{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 @var{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 @var{assembler-name} |
| @cindex @option{--as} (@command{dlltool}) |
| Use @var{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 |
| |
| @item version information |
| @end itemize |
| |
| For example, a version information resource can be defined as follow and |
| embedded into an executable or DLL: |
| |
| A version information resource can be used to embed information into an |
| executable or a DLL. These information can be viewed using the file properties |
| from the Windows Explorer. Here is an example of a version information |
| resource: |
| |
| @smallexample |
| @group |
| 1 VERSIONINFO |
| FILEVERSION 1,0,0,0 |
| PRODUCTVERSION 1,0,0,0 |
| BEGIN |
| BLOCK "StringFileInfo" |
| BEGIN |
| BLOCK "080904E4" |
| BEGIN |
| VALUE "CompanyName", "My Company Name" |
| VALUE "FileDescription", "My application" |
| VALUE "FileVersion", "1.0" |
| VALUE "InternalName", "my_app" |
| VALUE "LegalCopyright", "My Name" |
| VALUE "OriginalFilename", "my_app.exe" |
| VALUE "ProductName", "My App" |
| VALUE "ProductVersion", "1.0" |
| END |
| END |
| |
| BLOCK "VarFileInfo" |
| BEGIN |
| VALUE "Translation", 0x809, 1252 |
| END |
| END |
| @end group |
| @end smallexample |
| |
| The value @code{0809} (langID) is for the U.K English language and |
| @code{04E4} (charsetID), which is equal to @code{1252} decimal, for |
| multilingual. |
| |
| @noindent |
| This section explains how to build, compile and use resources. Note that this |
| section does not cover all resource objects, for a complete description see |
| the corresponding Microsoft documentation. |
| |
| @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. |
| @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 |
| Storage_Size or with the @command{gnatbind -d} command. |
| |
| Since older versions of Windows (2000, NT4, etc.) do not allow setting the |
| reserve size of individual tasks, the link-time stack size applies to all |
| tasks, and pragma Storage_Size has no effect. |
| In particular, Stack Overflow checks are made against this |
| link-time specified size. |
| |
| 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 |
| |
| @node Mac OS Topics |
| @appendix Mac OS Topics |
| @cindex OS X |
| |
| @noindent |
| This chapter describes topics that are specific to Apple's OS X |
| platform. |
| |
| @menu |
| * Codesigning the Debugger:: |
| @end menu |
| |
| @node Codesigning the Debugger |
| @section Codesigning the Debugger |
| |
| @noindent |
| The Darwin Kernel requires the debugger to have special permissions |
| before it is allowed to control other processes. These permissions |
| are granted by codesigning the GDB executable. Without these |
| permissions, the debugger will report error messages such as: |
| |
| @smallexample |
| Starting program: /x/y/foo |
| Unable to find Mach task port for process-id 28885: (os/kern) failure (0x5). |
| (please check gdb is codesigned - see taskgated(8)) |
| @end smallexample |
| |
| Codesigning requires a certificate. The following procedure explains |
| how to create one: |
| |
| @itemize @bullet |
| @item Start the Keychain Access application (in |
| /Applications/Utilities/Keychain Access.app) |
| |
| @item Select the Keychain Access -> Certificate Assistant -> |
| Create a Certificate... menu |
| |
| @item Then: |
| |
| @itemize @bullet |
| @item Choose a name for the new certificate (this procedure will use |
| "gdb-cert" as an example) |
| |
| @item Set "Identity Type" to "Self Signed Root" |
| |
| @item Set "Certificate Type" to "Code Signing" |
| |
| @item Activate the "Let me override defaults" option |
| |
| @end itemize |
| |
| @item Click several times on "Continue" until the "Specify a Location |
| For The Certificate" screen appears, then set "Keychain" to "System" |
| |
| @item Click on "Continue" until the certificate is created |
| |
| @item Finally, in the view, double-click on the new certificate, |
| and set "When using this certificate" to "Always Trust" |
| |
| @item Exit the Keychain Access application and restart the computer |
| (this is unfortunately required) |
| |
| @end itemize |
| |
| Once a certificate has been created, the debugger can be codesigned |
| as follow. In a Terminal, run the following command... |
| |
| @smallexample |
| codesign -f -s "gdb-cert" <gnat_install_prefix>/bin/gdb |
| @end smallexample |
| |
| ... where "gdb-cert" should be replaced by the actual certificate |
| name chosen above, and <gnat_install_prefix> should be replaced by |
| the location where you installed GNAT. |
| |
| @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 |