| \input texinfo @c -*-texinfo-*- |
| @c %**start of header |
| @setfilename gnat_ugn.info |
| @documentencoding UTF-8 |
| @ifinfo |
| @*Generated by Sphinx 4.0.2.@* |
| @end ifinfo |
| @settitle GNAT User's Guide for Native Platforms |
| @defindex ge |
| @paragraphindent 0 |
| @exampleindent 4 |
| @finalout |
| @dircategory GNU Ada Tools |
| @direntry |
| * gnat_ugn: (gnat_ugn.info). gnat_ugn |
| @end direntry |
| |
| @definfoenclose strong,`,' |
| @definfoenclose emph,`,' |
| @c %**end of header |
| |
| @copying |
| @quotation |
| GNAT User's Guide for Native Platforms , Oct 19, 2021 |
| |
| AdaCore |
| |
| Copyright @copyright{} 2008-2021, Free Software Foundation |
| @end quotation |
| |
| @end copying |
| |
| @titlepage |
| @title GNAT User's Guide for Native Platforms |
| @insertcopying |
| @end titlepage |
| @contents |
| |
| @c %** start of user preamble |
| |
| @c %** end of user preamble |
| |
| @ifnottex |
| @node Top |
| @top GNAT User's Guide for Native Platforms |
| @insertcopying |
| @end ifnottex |
| |
| @c %**start of body |
| @anchor{gnat_ugn doc}@anchor{0} |
| @emph{GNAT, The GNU Ada Development Environment} |
| |
| |
| @include gcc-common.texi |
| GCC version @value{version-GCC}@* |
| AdaCore |
| |
| 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 the Front-Cover Texts being |
| “GNAT User’s Guide for Native Platforms”, |
| and with no Back-Cover Texts. A copy of the license is |
| included in the section entitled @ref{1,,GNU Free Documentation License}. |
| |
| @menu |
| * About This Guide:: |
| * Getting Started with GNAT:: |
| * The GNAT Compilation Model:: |
| * Building Executable Programs with GNAT:: |
| * GNAT Utility Programs:: |
| * GNAT and Program Execution:: |
| * Platform-Specific Information:: |
| * Example of Binder Output File:: |
| * Elaboration Order Handling in GNAT:: |
| * Inline Assembler:: |
| * GNU Free Documentation License:: |
| * Index:: |
| |
| @detailmenu |
| --- 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 |
| |
| * System Requirements:: |
| * Running GNAT:: |
| * Running a Simple Ada Program:: |
| * Running a Program with Multiple Units:: |
| |
| The GNAT Compilation Model |
| |
| * Source Representation:: |
| * Foreign Language Representation:: |
| * File Naming Topics and Utilities:: |
| * Configuration Pragmas:: |
| * Generating Object Files:: |
| * Source Dependencies:: |
| * The Ada Library Information Files:: |
| * Binding an Ada Program:: |
| * GNAT and Libraries:: |
| * Conditional Compilation:: |
| * Mixed Language Programming:: |
| * GNAT and Other Compilation Models:: |
| * Using GNAT Files with External Tools:: |
| |
| Foreign Language Representation |
| |
| * Latin-1:: |
| * Other 8-Bit Codes:: |
| * Wide_Character Encodings:: |
| * Wide_Wide_Character Encodings:: |
| |
| File Naming Topics and Utilities |
| |
| * File Naming Rules:: |
| * Using Other File Names:: |
| * Alternative File Naming Schemes:: |
| * Handling Arbitrary File Naming Conventions with gnatname:: |
| * File Name Krunching with gnatkr:: |
| * Renaming Files with gnatchop:: |
| |
| Handling Arbitrary File Naming Conventions with gnatname |
| |
| * Arbitrary File Naming Conventions:: |
| * Running gnatname:: |
| * Switches for gnatname:: |
| * Examples of gnatname Usage:: |
| |
| File Name Krunching with gnatkr |
| |
| * About gnatkr:: |
| * Using gnatkr:: |
| * Krunching Method:: |
| * Examples of gnatkr Usage:: |
| |
| Renaming Files with 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:: |
| |
| GNAT and Libraries |
| |
| * Introduction to Libraries in GNAT:: |
| * General Ada Libraries:: |
| * Stand-alone Ada Libraries:: |
| * Rebuilding the GNAT Run-Time Library:: |
| |
| General Ada Libraries |
| |
| * Building a library:: |
| * Installing a library:: |
| * Using a library:: |
| |
| Stand-alone Ada Libraries |
| |
| * 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:: |
| |
| Conditional Compilation |
| |
| * Modeling Conditional Compilation in Ada:: |
| * Preprocessing with gnatprep:: |
| * Integrated Preprocessing:: |
| |
| Modeling Conditional Compilation in Ada |
| |
| * Use of Boolean Constants:: |
| * Debugging - A Special Case:: |
| * Conditionalizing Declarations:: |
| * Use of Alternative Implementations:: |
| * Preprocessing:: |
| |
| Preprocessing with gnatprep |
| |
| * Preprocessing Symbols:: |
| * Using gnatprep:: |
| * Switches for gnatprep:: |
| * Form of Definitions File:: |
| * Form of Input Text for gnatprep:: |
| |
| Mixed Language Programming |
| |
| * Interfacing to C:: |
| * Calling Conventions:: |
| * Building Mixed Ada and C++ Programs:: |
| * Generating Ada Bindings for C and C++ headers:: |
| * Generating C Headers for Ada Specifications:: |
| |
| Building Mixed Ada and C++ Programs |
| |
| * Interfacing to C++:: |
| * Linking a Mixed C++ & Ada Program:: |
| * A Simple Example:: |
| * Interfacing with C++ constructors:: |
| * Interfacing with C++ at the Class Level:: |
| |
| Generating Ada Bindings for C and C++ headers |
| |
| * Running the Binding Generator:: |
| * Generating Bindings for C++ Headers:: |
| * Switches:: |
| |
| Generating C Headers for Ada Specifications |
| |
| * Running the C Header Generator:: |
| |
| GNAT and Other Compilation Models |
| |
| * Comparison between GNAT and C/C++ Compilation Models:: |
| * Comparison between GNAT and Conventional Ada Library Models:: |
| |
| Using GNAT Files with External Tools |
| |
| * Using Other Utility Programs with GNAT:: |
| * The External Symbol Naming Scheme of GNAT:: |
| |
| Building Executable Programs with GNAT |
| |
| * Building with gnatmake:: |
| * Compiling with gcc:: |
| * Compiler Switches:: |
| * Linker Switches:: |
| * Binding with gnatbind:: |
| * Linking with gnatlink:: |
| * Using the GNU make Utility:: |
| |
| Building with gnatmake |
| |
| * Running gnatmake:: |
| * Switches for gnatmake:: |
| * Mode Switches for gnatmake:: |
| * Notes on the Command Line:: |
| * How gnatmake Works:: |
| * Examples of gnatmake Usage:: |
| |
| Compiling with gcc |
| |
| * Compiling Programs:: |
| * Search Paths and the Run-Time Library (RTL): Search Paths and the Run-Time Library RTL. |
| * Order of Compilation Issues:: |
| * Examples:: |
| |
| Compiler Switches |
| |
| * Alphabetical List of All Switches:: |
| * 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:: |
| * Code Generation Control:: |
| |
| Binding 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:: |
| * Dynamic Allocation Control:: |
| * Binding with Non-Ada Main Programs:: |
| * Binding Programs with No Main Subprogram:: |
| |
| Linking with gnatlink |
| |
| * Running gnatlink:: |
| * Switches for gnatlink:: |
| |
| 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:: |
| |
| GNAT Utility Programs |
| |
| * The File Cleanup Utility gnatclean:: |
| * The GNAT Library Browser gnatls:: |
| |
| The File Cleanup Utility gnatclean |
| |
| * Running gnatclean:: |
| * Switches for gnatclean:: |
| |
| The GNAT Library Browser gnatls |
| |
| * Running gnatls:: |
| * Switches for gnatls:: |
| * Example of gnatls Usage:: |
| |
| GNAT and Program Execution |
| |
| * Running and Debugging Ada Programs:: |
| * Profiling:: |
| * Improving Performance:: |
| * Overflow Check Handling in GNAT:: |
| * Performing Dimensionality Analysis in GNAT:: |
| * Stack Related Facilities:: |
| * Memory Management Issues:: |
| |
| 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:: |
| * Stopping When Ada Exceptions Are Raised:: |
| * Ada Tasks:: |
| * Debugging Generic Units:: |
| * Remote Debugging with gdbserver:: |
| * GNAT Abnormal Termination or Failure to Terminate:: |
| * Naming Conventions for GNAT Source Files:: |
| * Getting Internal Debugging Information:: |
| * Stack Traceback:: |
| * Pretty-Printers for the GNAT runtime:: |
| |
| Stack Traceback |
| |
| * Non-Symbolic Traceback:: |
| * Symbolic Traceback:: |
| |
| Profiling |
| |
| * Profiling an Ada Program with gprof:: |
| |
| Profiling an Ada Program with gprof |
| |
| * Compilation for profiling:: |
| * Program execution:: |
| * Running gprof:: |
| * Interpretation of profiling results:: |
| |
| Improving Performance |
| |
| * Performance Considerations:: |
| * Text_IO Suggestions:: |
| * 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:: |
| * Floating Point Operations:: |
| * Vectorization of loops:: |
| * Other Optimization Switches:: |
| * Optimization and Strict Aliasing:: |
| * Aliased Variables and Optimization:: |
| * Atomic Variables and Optimization:: |
| * Passive Task Optimization:: |
| |
| Reducing Size of Executables with Unused Subprogram/Data Elimination |
| |
| * About unused subprogram/data elimination:: |
| * Compilation options:: |
| * Example of unused subprogram/data elimination:: |
| |
| Overflow Check Handling in GNAT |
| |
| * Background:: |
| * Management of Overflows in GNAT:: |
| * Specifying the Desired Mode:: |
| * Default Settings:: |
| * Implementation Notes:: |
| |
| Stack Related Facilities |
| |
| * Stack Overflow Checking:: |
| * Static Stack Usage Analysis:: |
| * Dynamic Stack Usage Analysis:: |
| |
| Memory Management Issues |
| |
| * Some Useful Memory Pools:: |
| * The GNAT Debug Pool Facility:: |
| |
| Platform-Specific Information |
| |
| * Run-Time Libraries:: |
| * Specifying a Run-Time Library:: |
| * GNU/Linux Topics:: |
| * Microsoft Windows Topics:: |
| * Mac OS Topics:: |
| |
| Run-Time Libraries |
| |
| * Summary of Run-Time Configurations:: |
| |
| Specifying a Run-Time Library |
| |
| * Choosing the Scheduling Policy:: |
| |
| GNU/Linux Topics |
| |
| * Required Packages on GNU/Linux:: |
| |
| Microsoft Windows Topics |
| |
| * Using GNAT on Windows:: |
| * Using a network installation of GNAT:: |
| * CONSOLE and WINDOWS subsystems:: |
| * Temporary Files:: |
| * Disabling Command Line Argument Expansion:: |
| * Windows Socket Timeouts:: |
| * Mixed-Language Programming on Windows:: |
| * Windows Specific Add-Ons:: |
| |
| Mixed-Language Programming on Windows |
| |
| * Windows Calling Conventions:: |
| * Introduction to Dynamic Link Libraries (DLLs): Introduction to Dynamic Link Libraries DLLs. |
| * Using DLLs with GNAT:: |
| * Building DLLs with GNAT Project files:: |
| * Building DLLs with GNAT:: |
| * Building DLLs with gnatdll:: |
| * Ada DLLs and Finalization:: |
| * Creating a Spec for Ada DLLs:: |
| * GNAT and Windows Resources:: |
| * Using GNAT DLLs from Microsoft Visual Studio Applications:: |
| * Debugging a DLL:: |
| * Setting Stack Size from gnatlink:: |
| * Setting Heap Size from gnatlink:: |
| |
| Windows Calling Conventions |
| |
| * C Calling Convention:: |
| * Stdcall Calling Convention:: |
| * Win32 Calling Convention:: |
| * DLL Calling Convention:: |
| |
| Using DLLs with GNAT |
| |
| * Creating an Ada Spec for the DLL Services:: |
| * Creating an Import Library:: |
| |
| Building DLLs with gnatdll |
| |
| * Limitations When Using Ada DLLs from Ada:: |
| * Exporting Ada Entities:: |
| * Ada DLLs and Elaboration:: |
| |
| Creating a Spec for Ada DLLs |
| |
| * Creating the Definition File:: |
| * Using gnatdll:: |
| |
| GNAT and Windows Resources |
| |
| * Building Resources:: |
| * Compiling Resources:: |
| * Using Resources:: |
| |
| Debugging a DLL |
| |
| * Program and DLL Both Built with GCC/GNAT:: |
| * Program Built with Foreign Tools and DLL Built with GCC/GNAT:: |
| |
| Windows Specific Add-Ons |
| |
| * Win32Ada:: |
| * wPOSIX:: |
| |
| Mac OS Topics |
| |
| * Codesigning the Debugger:: |
| |
| Elaboration Order Handling in GNAT |
| |
| * Elaboration Code:: |
| * Elaboration Order:: |
| * Checking the Elaboration Order:: |
| * Controlling the Elaboration Order in Ada:: |
| * Controlling the Elaboration Order in GNAT:: |
| * Mixing Elaboration Models:: |
| * ABE Diagnostics:: |
| * SPARK Diagnostics:: |
| * Elaboration Circularities:: |
| * Resolving Elaboration Circularities:: |
| * Elaboration-related Compiler Switches:: |
| * Summary of Procedures for Elaboration Control:: |
| * Inspecting the Chosen Elaboration Order:: |
| |
| 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:: |
| |
| Other Asm Functionality |
| |
| * The Clobber Parameter:: |
| * The Volatile Parameter:: |
| |
| @end detailmenu |
| @end menu |
| |
| @node About This Guide,Getting Started with GNAT,Top,Top |
| @anchor{gnat_ugn/about_this_guide doc}@anchor{2}@anchor{gnat_ugn/about_this_guide about-this-guide}@anchor{3}@anchor{gnat_ugn/about_this_guide gnat-user-s-guide-for-native-platforms}@anchor{4}@anchor{gnat_ugn/about_this_guide id1}@anchor{5} |
| @chapter About This Guide |
| |
| |
| |
| This guide describes the use of GNAT, |
| a compiler and software development |
| toolset for the full Ada programming language. |
| It documents the features of the compiler and tools, and explains |
| how to use them to build Ada applications. |
| |
| GNAT implements Ada 95, Ada 2005, Ada 2012, and Ada 202x, and it may also be |
| invoked in Ada 83 compatibility mode. |
| By default, GNAT assumes Ada 2012, but you can override with a |
| compiler switch (@ref{6,,Compiling Different Versions of Ada}) |
| to explicitly specify the language version. |
| Throughout this manual, references to ‘Ada’ without a year suffix |
| apply to all Ada versions of the language, starting with Ada 95. |
| |
| @menu |
| * What This Guide Contains:: |
| * What You Should Know before Reading This Guide:: |
| * Related Information:: |
| * Conventions:: |
| |
| @end menu |
| |
| @node What This Guide Contains,What You Should Know before Reading This Guide,,About This Guide |
| @anchor{gnat_ugn/about_this_guide what-this-guide-contains}@anchor{7} |
| @section What This Guide Contains |
| |
| |
| This guide contains the following chapters: |
| |
| |
| @itemize * |
| |
| @item |
| @ref{8,,Getting Started with GNAT} describes how to get started compiling |
| and running Ada programs with the GNAT Ada programming environment. |
| |
| @item |
| @ref{9,,The GNAT Compilation Model} describes the compilation model used |
| by GNAT. |
| |
| @item |
| @ref{a,,Building Executable Programs with GNAT} describes how to use the |
| main GNAT tools to build executable programs, and it also gives examples of |
| using the GNU make utility with GNAT. |
| |
| @item |
| @ref{b,,GNAT Utility Programs} explains the various utility programs that |
| are included in the GNAT environment |
| |
| @item |
| @ref{c,,GNAT and Program Execution} covers a number of topics related to |
| running, debugging, and tuning the performace of programs developed |
| with GNAT |
| @end itemize |
| |
| Appendices cover several additional topics: |
| |
| |
| @itemize * |
| |
| @item |
| @ref{d,,Platform-Specific Information} describes the different run-time |
| library implementations and also presents information on how to use |
| GNAT on several specific platforms |
| |
| @item |
| @ref{e,,Example of Binder Output File} shows the source code for the binder |
| output file for a sample program. |
| |
| @item |
| @ref{f,,Elaboration Order Handling in GNAT} describes how GNAT helps |
| you deal with elaboration order issues. |
| |
| @item |
| @ref{10,,Inline Assembler} shows how to use the inline assembly facility |
| in an Ada program. |
| @end itemize |
| |
| @node What You Should Know before Reading This Guide,Related Information,What This Guide Contains,About This Guide |
| @anchor{gnat_ugn/about_this_guide what-you-should-know-before-reading-this-guide}@anchor{11} |
| @section What You Should Know before Reading This Guide |
| |
| |
| @geindex Ada 95 Language Reference Manual |
| |
| @geindex Ada 2005 Language Reference Manual |
| |
| This guide assumes a basic familiarity with the Ada 95 language, as |
| described in the International Standard ANSI/ISO/IEC-8652:1995, January |
| 1995. |
| Reference manuals for Ada 95, Ada 2005, and Ada 2012 are included in |
| the GNAT documentation package. |
| |
| @node Related Information,Conventions,What You Should Know before Reading This Guide,About This Guide |
| @anchor{gnat_ugn/about_this_guide related-information}@anchor{12} |
| @section Related Information |
| |
| |
| For further information about Ada and related tools, please refer to the |
| following documents: |
| |
| |
| @itemize * |
| |
| @item |
| @cite{Ada 95 Reference Manual}, @cite{Ada 2005 Reference Manual}, and |
| @cite{Ada 2012 Reference Manual}, which contain reference |
| material for the several revisions of the Ada language standard. |
| |
| @item |
| @cite{GNAT Reference_Manual}, which contains all reference material for the GNAT |
| implementation of Ada. |
| |
| @item |
| @cite{Using GNAT Studio}, which describes the GNAT Studio |
| Integrated Development Environment. |
| |
| @item |
| @cite{GNAT Studio Tutorial}, which introduces the |
| main GNAT Studio features through examples. |
| |
| @item |
| @cite{Debugging with GDB}, |
| for all details on the use of the GNU source-level debugger. |
| |
| @item |
| @cite{GNU Emacs Manual}, |
| for full information on the extensible editor and programming |
| environment Emacs. |
| @end itemize |
| |
| @node Conventions,,Related Information,About This Guide |
| @anchor{gnat_ugn/about_this_guide conventions}@anchor{13} |
| @section Conventions |
| |
| |
| @geindex Conventions |
| @geindex typographical |
| |
| @geindex Typographical conventions |
| |
| Following are examples of the typographical and graphic conventions used |
| in this guide: |
| |
| |
| @itemize * |
| |
| @item |
| @code{Functions}, @code{utility program names}, @code{standard names}, |
| and @code{classes}. |
| |
| @item |
| @code{Option flags} |
| |
| @item |
| @code{File names} |
| |
| @item |
| @code{Variables} |
| |
| @item |
| @emph{Emphasis} |
| |
| @item |
| [optional information or parameters] |
| |
| @item |
| Examples are described by text |
| |
| @example |
| and then shown this way. |
| @end example |
| |
| @item |
| Commands that are entered by the user are shown as preceded by a prompt string |
| comprising the @code{$} character followed by a space. |
| |
| @item |
| Full file names are shown with the ‘/’ character |
| as the directory separator; e.g., @code{parent-dir/subdir/myfile.adb}. |
| If you are using GNAT on a Windows platform, please note that |
| the ‘' character should be used instead. |
| @end itemize |
| |
| @node Getting Started with GNAT,The GNAT Compilation Model,About This Guide,Top |
| @anchor{gnat_ugn/getting_started_with_gnat doc}@anchor{14}@anchor{gnat_ugn/getting_started_with_gnat getting-started-with-gnat}@anchor{8}@anchor{gnat_ugn/getting_started_with_gnat id1}@anchor{15} |
| @chapter Getting Started with GNAT |
| |
| |
| This chapter describes how to use GNAT’s command line interface to build |
| executable Ada programs. |
| On most platforms a visually oriented Integrated Development Environment |
| is also available: GNAT Studio. |
| GNAT Studio offers a graphical “look and feel”, support for development in |
| other programming languages, comprehensive browsing features, and |
| many other capabilities. |
| For information on GNAT Studio please refer to the |
| @cite{GNAT Studio documentation}. |
| |
| @menu |
| * System Requirements:: |
| * Running GNAT:: |
| * Running a Simple Ada Program:: |
| * Running a Program with Multiple Units:: |
| |
| @end menu |
| |
| @node System Requirements,Running GNAT,,Getting Started with GNAT |
| @anchor{gnat_ugn/getting_started_with_gnat id2}@anchor{16}@anchor{gnat_ugn/getting_started_with_gnat system-requirements}@anchor{17} |
| @section System Requirements |
| |
| |
| Even though any machine can run the GNAT toolset and GNAT Studio IDE, in order |
| to get the best experience, we recommend using a machine with as many cores |
| as possible since all individual compilations can run in parallel. |
| A comfortable setup for a compiler server is a machine with 24 physical cores |
| or more, with at least 48 GB of memory (2 GB per core). |
| |
| For a desktop machine, a minimum of 4 cores is recommended (8 preferred), |
| with at least 2GB per core (so 8 to 16GB). |
| |
| In addition, for running and navigating sources in GNAT Studio smoothly, we |
| recommend at least 1.5 GB plus 3 GB of RAM per 1 million source line of code. |
| In other words, we recommend at least 3 GB for for 500K lines of code and |
| 7.5 GB for 2 million lines of code. |
| |
| Note that using local and fast drives will also make a difference in terms of |
| build and link time. Network drives such as NFS, SMB, or worse, configuration |
| management filesystems (such as ClearCase dynamic views) should be avoided as |
| much as possible and will produce very degraded performance (typically 2 to 3 |
| times slower than on local fast drives). If such slow drives cannot be avoided |
| for accessing the source code, then you should at least configure your project |
| file so that the result of the compilation is stored on a drive local to the |
| machine performing the run. This can be achieved by setting the @code{Object_Dir} |
| project file attribute. |
| |
| @node Running GNAT,Running a Simple Ada Program,System Requirements,Getting Started with GNAT |
| @anchor{gnat_ugn/getting_started_with_gnat id3}@anchor{18}@anchor{gnat_ugn/getting_started_with_gnat running-gnat}@anchor{19} |
| @section Running GNAT |
| |
| |
| Three steps are needed to create an executable file from an Ada source |
| file: |
| |
| |
| @itemize * |
| |
| @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 itemize |
| |
| All three steps are most commonly handled by using the @code{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,Running a Program with Multiple Units,Running GNAT,Getting Started with GNAT |
| @anchor{gnat_ugn/getting_started_with_gnat id4}@anchor{1a}@anchor{gnat_ugn/getting_started_with_gnat running-a-simple-ada-program}@anchor{1b} |
| @section Running a Simple Ada Program |
| |
| |
| Any text editor may be used to prepare an Ada program. |
| (If 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: |
| |
| @example |
| with Ada.Text_IO; use Ada.Text_IO; |
| procedure Hello is |
| begin |
| Put_Line ("Hello WORLD!"); |
| end Hello; |
| @end example |
| |
| This file should be named @code{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 @code{ads} for a |
| spec and @code{adb} for a body. |
| You can override this default file naming convention by use of the |
| special pragma @code{Source_File_Name} (for further information please |
| see @ref{1c,,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 |
| (see @ref{1d,,Renaming Files with gnatchop}). |
| |
| You can compile the program using the following command (@code{$} is used |
| as the command prompt in the examples in this document): |
| |
| @example |
| $ gcc -c hello.adb |
| @end example |
| |
| @code{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 @code{.ads} or @code{.adb}, and it will then call |
| the GNAT compiler to compile the specified file. |
| |
| The @code{-c} switch is required. It tells @code{gcc} to only do a |
| compilation. (For C programs, @code{gcc} can also do linking, but this |
| capability is not used directly for Ada programs, so the @code{-c} |
| switch must always be present.) |
| |
| This compile command generates a file |
| @code{hello.o}, which is the object |
| file corresponding to your Ada program. It also generates |
| an ‘Ada Library Information’ file @code{hello.ali}, |
| which contains additional information used to check |
| that an Ada program is consistent. |
| |
| To build an executable file, use either @code{gnatmake} or gprbuild with |
| the name of the main file: these tools are builders that will take care of |
| all the necessary build steps in the correct order. |
| In particular, these builders automatically recompile 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. |
| |
| @geindex Version skew (avoided by `@w{`}gnatmake`@w{`}) |
| |
| @example |
| $ gnatmake hello.adb |
| @end example |
| |
| The result is an executable program called @code{hello}, which can be |
| run by entering: |
| |
| @example |
| $ hello |
| @end example |
| |
| assuming that the current directory is on the search path |
| for executable programs. |
| |
| and, if all has gone well, you will see: |
| |
| @example |
| Hello WORLD! |
| @end example |
| |
| appear in response to this command. |
| |
| @node Running a Program with Multiple Units,,Running a Simple Ada Program,Getting Started with GNAT |
| @anchor{gnat_ugn/getting_started_with_gnat id5}@anchor{1e}@anchor{gnat_ugn/getting_started_with_gnat running-a-program-with-multiple-units}@anchor{1f} |
| @section Running a Program with Multiple Units |
| |
| |
| Consider a slightly more complicated example that has three files: a |
| main program, and the spec and body of a package: |
| |
| @example |
| 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; |
| |
| with Greetings; |
| procedure Gmain is |
| begin |
| Greetings.Hello; |
| Greetings.Goodbye; |
| end Gmain; |
| @end example |
| |
| Following the one-unit-per-file rule, place this program in the |
| following three separate files: |
| |
| |
| @table @asis |
| |
| @item @emph{greetings.ads} |
| |
| spec of package @code{Greetings} |
| |
| @item @emph{greetings.adb} |
| |
| body of package @code{Greetings} |
| |
| @item @emph{gmain.adb} |
| |
| body of main program |
| @end table |
| |
| 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 @code{-gnatc} switch: |
| |
| @example |
| $ gcc -c greetings.ads -gnatc |
| @end example |
| |
| Although the compilation can be done in separate steps, in practice it is |
| almost always more convenient to use the @code{gnatmake} or @code{gprbuild} tools: |
| |
| @example |
| $ gnatmake gmain.adb |
| @end example |
| |
| @c -- Example: A |withing| unit has a |with| clause, it |withs| a |withed| unit |
| |
| @node The GNAT Compilation Model,Building Executable Programs with GNAT,Getting Started with GNAT,Top |
| @anchor{gnat_ugn/the_gnat_compilation_model doc}@anchor{20}@anchor{gnat_ugn/the_gnat_compilation_model id1}@anchor{21}@anchor{gnat_ugn/the_gnat_compilation_model the-gnat-compilation-model}@anchor{9} |
| @chapter The GNAT Compilation Model |
| |
| |
| @geindex GNAT compilation model |
| |
| @geindex Compilation model |
| |
| 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 centralized program library. The chapter covers |
| the following material: |
| |
| |
| @itemize * |
| |
| @item |
| Topics related to source file makeup and naming |
| |
| |
| @itemize * |
| |
| @item |
| @ref{22,,Source Representation} |
| |
| @item |
| @ref{23,,Foreign Language Representation} |
| |
| @item |
| @ref{24,,File Naming Topics and Utilities} |
| @end itemize |
| |
| @item |
| @ref{25,,Configuration Pragmas} |
| |
| @item |
| @ref{26,,Generating Object Files} |
| |
| @item |
| @ref{27,,Source Dependencies} |
| |
| @item |
| @ref{28,,The Ada Library Information Files} |
| |
| @item |
| @ref{29,,Binding an Ada Program} |
| |
| @item |
| @ref{2a,,GNAT and Libraries} |
| |
| @item |
| @ref{2b,,Conditional Compilation} |
| |
| @item |
| @ref{2c,,Mixed Language Programming} |
| |
| @item |
| @ref{2d,,GNAT and Other Compilation Models} |
| |
| @item |
| @ref{2e,,Using GNAT Files with External Tools} |
| @end itemize |
| |
| @menu |
| * Source Representation:: |
| * Foreign Language Representation:: |
| * File Naming Topics and Utilities:: |
| * Configuration Pragmas:: |
| * Generating Object Files:: |
| * Source Dependencies:: |
| * The Ada Library Information Files:: |
| * Binding an Ada Program:: |
| * GNAT and Libraries:: |
| * Conditional Compilation:: |
| * Mixed Language Programming:: |
| * GNAT and Other Compilation Models:: |
| * Using GNAT Files with External Tools:: |
| |
| @end menu |
| |
| @node Source Representation,Foreign Language Representation,,The GNAT Compilation Model |
| @anchor{gnat_ugn/the_gnat_compilation_model id2}@anchor{2f}@anchor{gnat_ugn/the_gnat_compilation_model source-representation}@anchor{22} |
| @section Source Representation |
| |
| |
| @geindex Latin-1 |
| |
| @geindex VT |
| @geindex HT |
| @geindex CR |
| @geindex LF |
| @geindex FF |
| |
| 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 (see @ref{23,,Foreign Language Representation} |
| for support of non-USA character sets). The format effector characters |
| are represented using their standard ASCII encodings, as follows: |
| |
| @quotation |
| |
| |
| @multitable {xxxxxxxxxxxxx} {xxxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxx} |
| @item |
| |
| Character |
| |
| @tab |
| |
| Effect |
| |
| @tab |
| |
| Code |
| |
| @item |
| |
| @code{VT} |
| |
| @tab |
| |
| Vertical tab |
| |
| @tab |
| |
| @code{16#0B#} |
| |
| @item |
| |
| @code{HT} |
| |
| @tab |
| |
| Horizontal tab |
| |
| @tab |
| |
| @code{16#09#} |
| |
| @item |
| |
| @code{CR} |
| |
| @tab |
| |
| Carriage return |
| |
| @tab |
| |
| @code{16#0D#} |
| |
| @item |
| |
| @code{LF} |
| |
| @tab |
| |
| Line feed |
| |
| @tab |
| |
| @code{16#0A#} |
| |
| @item |
| |
| @code{FF} |
| |
| @tab |
| |
| Form feed |
| |
| @tab |
| |
| @code{16#0C#} |
| |
| @end multitable |
| |
| @end quotation |
| |
| 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. |
| |
| @geindex End of source file; Source file@comma{} end |
| |
| @geindex SUB (control character) |
| |
| 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. |
| |
| @geindex spec (definition) |
| @geindex compilation (definition) |
| |
| 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 @emph{spec}) and the corresponding body in |
| separate files. An Ada @emph{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,File Naming Topics and Utilities,Source Representation,The GNAT Compilation Model |
| @anchor{gnat_ugn/the_gnat_compilation_model foreign-language-representation}@anchor{23}@anchor{gnat_ugn/the_gnat_compilation_model id3}@anchor{30} |
| @section Foreign Language Representation |
| |
| |
| 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 (@ref{31,,Character Set Control}). |
| |
| @menu |
| * Latin-1:: |
| * Other 8-Bit Codes:: |
| * Wide_Character Encodings:: |
| * Wide_Wide_Character Encodings:: |
| |
| @end menu |
| |
| @node Latin-1,Other 8-Bit Codes,,Foreign Language Representation |
| @anchor{gnat_ugn/the_gnat_compilation_model id4}@anchor{32}@anchor{gnat_ugn/the_gnat_compilation_model latin-1}@anchor{33} |
| @subsection Latin-1 |
| |
| |
| @geindex Latin-1 |
| |
| The basic character set is Latin-1. This character set is defined by ISO |
| standard 8859, part 1. The lower half (character codes @code{16#00#} |
| … @code{16#7F#)} is identical to standard ASCII coding, but the upper |
| half is used to represent additional characters. These include extended letters |
| used by European languages, such as French accents, the vowels with umlauts |
| used in German, and the extra letter A-ring used in Swedish. |
| |
| @geindex 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 |
| @code{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,Wide_Character Encodings,Latin-1,Foreign Language Representation |
| @anchor{gnat_ugn/the_gnat_compilation_model id5}@anchor{34}@anchor{gnat_ugn/the_gnat_compilation_model other-8-bit-codes}@anchor{35} |
| @subsection Other 8-Bit Codes |
| |
| |
| GNAT also supports several other 8-bit coding schemes: |
| |
| @geindex Latin-2 |
| |
| @geindex ISO 8859-2 |
| |
| |
| @table @asis |
| |
| @item @emph{ISO 8859-2 (Latin-2)} |
| |
| Latin-2 letters allowed in identifiers, with uppercase and lowercase |
| equivalence. |
| @end table |
| |
| @geindex Latin-3 |
| |
| @geindex ISO 8859-3 |
| |
| |
| @table @asis |
| |
| @item @emph{ISO 8859-3 (Latin-3)} |
| |
| Latin-3 letters allowed in identifiers, with uppercase and lowercase |
| equivalence. |
| @end table |
| |
| @geindex Latin-4 |
| |
| @geindex ISO 8859-4 |
| |
| |
| @table @asis |
| |
| @item @emph{ISO 8859-4 (Latin-4)} |
| |
| Latin-4 letters allowed in identifiers, with uppercase and lowercase |
| equivalence. |
| @end table |
| |
| @geindex ISO 8859-5 |
| |
| @geindex Cyrillic |
| |
| |
| @table @asis |
| |
| @item @emph{ISO 8859-5 (Cyrillic)} |
| |
| ISO 8859-5 letters (Cyrillic) allowed in identifiers, with uppercase and |
| lowercase equivalence. |
| @end table |
| |
| @geindex ISO 8859-15 |
| |
| @geindex Latin-9 |
| |
| |
| @table @asis |
| |
| @item @emph{ISO 8859-15 (Latin-9)} |
| |
| ISO 8859-15 (Latin-9) letters allowed in identifiers, with uppercase and |
| lowercase equivalence |
| @end table |
| |
| @geindex code page 437 (IBM PC) |
| |
| |
| @table @asis |
| |
| @item @emph{IBM PC (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. |
| @end table |
| |
| @geindex code page 850 (IBM PC) |
| |
| |
| @table @asis |
| |
| @item @emph{IBM PC (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 @emph{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 @emph{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 |
| |
| For precise data on the encodings permitted, and the uppercase and lowercase |
| equivalences that are recognized, see the file @code{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,Wide_Wide_Character Encodings,Other 8-Bit Codes,Foreign Language Representation |
| @anchor{gnat_ugn/the_gnat_compilation_model id6}@anchor{36}@anchor{gnat_ugn/the_gnat_compilation_model wide-character-encodings}@anchor{37} |
| @subsection Wide_Character Encodings |
| |
| |
| 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 @emph{Hex Coding} |
| |
| In this encoding, a wide character is represented by the following five |
| character sequence: |
| |
| @example |
| ESC a b c d |
| @end example |
| |
| 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 @emph{Upper-Half Coding} |
| |
| @geindex 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 @emph{Shift JIS Coding} |
| |
| @geindex 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 @emph{EUC Coding} |
| |
| @geindex 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 @emph{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: |
| |
| @example |
| 16#0000#-16#007f#: 2#0xxxxxxx# |
| 16#0080#-16#07ff#: 2#110xxxxx# 2#10xxxxxx# |
| 16#0800#-16#ffff#: 2#1110xxxx# 2#10xxxxxx# 2#10xxxxxx# |
| @end example |
| |
| where the @code{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, and in the following section on wide wide |
| characters, the use of these sequences is documented). |
| |
| @item @emph{Brackets Coding} |
| |
| In this encoding, a wide character is represented by the following eight |
| character sequence: |
| |
| @example |
| [ " a b c d " ] |
| @end example |
| |
| 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 some standard |
| ACATS (Ada Conformity Assessment Test Suite) test suite distributions. |
| @end table |
| |
| @cartouche |
| @quotation 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. |
| @end quotation |
| @end cartouche |
| |
| @node Wide_Wide_Character Encodings,,Wide_Character Encodings,Foreign Language Representation |
| @anchor{gnat_ugn/the_gnat_compilation_model id7}@anchor{38}@anchor{gnat_ugn/the_gnat_compilation_model wide-wide-character-encodings}@anchor{39} |
| @subsection Wide_Wide_Character Encodings |
| |
| |
| GNAT allows wide 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 @emph{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 |
| of character codes with values greater than 16#FFFF# is a |
| is a four, five, or six byte sequence: |
| |
| @example |
| 16#01_0000#-16#10_FFFF#: 11110xxx 10xxxxxx 10xxxxxx |
| 10xxxxxx |
| 16#0020_0000#-16#03FF_FFFF#: 111110xx 10xxxxxx 10xxxxxx |
| 10xxxxxx 10xxxxxx |
| 16#0400_0000#-16#7FFF_FFFF#: 1111110x 10xxxxxx 10xxxxxx |
| 10xxxxxx 10xxxxxx 10xxxxxx |
| @end example |
| |
| where the @code{xxx} bits correspond to the left-padded bits of the |
| 32-bit character value. |
| |
| @item @emph{Brackets Coding} |
| |
| In this encoding, a wide wide character is represented by the following ten or |
| twelve byte character sequence: |
| |
| @example |
| [ " a b c d e f " ] |
| [ " a b c d e f g h " ] |
| @end example |
| |
| where @code{a-h} are the six or eight hexadecimal |
| characters (using uppercase letters) of the wide wide character code. For |
| example, [“1F4567”] is used to represent the wide wide character with code |
| @code{16#001F_4567#}. |
| |
| This scheme is compatible with use of the full Wide_Wide_Character set, |
| and is also the method used for wide wide character encoding in some standard |
| ACATS (Ada Conformity Assessment Test Suite) test suite distributions. |
| @end table |
| |
| @node File Naming Topics and Utilities,Configuration Pragmas,Foreign Language Representation,The GNAT Compilation Model |
| @anchor{gnat_ugn/the_gnat_compilation_model file-naming-topics-and-utilities}@anchor{24}@anchor{gnat_ugn/the_gnat_compilation_model id8}@anchor{3a} |
| @section File Naming Topics and Utilities |
| |
| |
| GNAT has a default file naming scheme and also provides the user with |
| a high degree of control over how the names and extensions of the |
| source files correspond to the Ada compilation units that they contain. |
| |
| @menu |
| * File Naming Rules:: |
| * Using Other File Names:: |
| * Alternative File Naming Schemes:: |
| * Handling Arbitrary File Naming Conventions with gnatname:: |
| * File Name Krunching with gnatkr:: |
| * Renaming Files with gnatchop:: |
| |
| @end menu |
| |
| @node File Naming Rules,Using Other File Names,,File Naming Topics and Utilities |
| @anchor{gnat_ugn/the_gnat_compilation_model file-naming-rules}@anchor{3b}@anchor{gnat_ugn/the_gnat_compilation_model id9}@anchor{3c} |
| @subsection File Naming Rules |
| |
| |
| 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 for all letters. |
| |
| An exception arises if the file name generated by the above rules starts |
| with one of the characters |
| @code{a}, @code{g}, @code{i}, or @code{s}, and the second character is a |
| minus. In this case, the character tilde 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 |
| @code{s-}, @code{a-}, @code{i-}, and @code{g-}, |
| respectively. |
| |
| The file extension is @code{.ads} for a spec and |
| @code{.adb} for a body. The following table shows some |
| examples of these rules. |
| |
| @quotation |
| |
| |
| @multitable {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx} |
| @item |
| |
| Source File |
| |
| @tab |
| |
| Ada Compilation Unit |
| |
| @item |
| |
| @code{main.ads} |
| |
| @tab |
| |
| Main (spec) |
| |
| @item |
| |
| @code{main.adb} |
| |
| @tab |
| |
| Main (body) |
| |
| @item |
| |
| @code{arith_functions.ads} |
| |
| @tab |
| |
| Arith_Functions (package spec) |
| |
| @item |
| |
| @code{arith_functions.adb} |
| |
| @tab |
| |
| Arith_Functions (package body) |
| |
| @item |
| |
| @code{func-spec.ads} |
| |
| @tab |
| |
| Func.Spec (child package spec) |
| |
| @item |
| |
| @code{func-spec.adb} |
| |
| @tab |
| |
| Func.Spec (child package body) |
| |
| @item |
| |
| @code{main-sub.adb} |
| |
| @tab |
| |
| Sub (subunit of Main) |
| |
| @item |
| |
| @code{a~bad.adb} |
| |
| @tab |
| |
| A.Bad (child package body) |
| |
| @end multitable |
| |
| @end quotation |
| |
| 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. @ref{3d,,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 see @ref{1d,,Renaming Files with gnatchop}.) |
| |
| Note: in the case of Windows or Mac OS operating systems, case is not |
| significant. So for example on Windows 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,Alternative File Naming Schemes,File Naming Rules,File Naming Topics and Utilities |
| @anchor{gnat_ugn/the_gnat_compilation_model id10}@anchor{3e}@anchor{gnat_ugn/the_gnat_compilation_model using-other-file-names}@anchor{1c} |
| @subsection Using Other File Names |
| |
| |
| @geindex File names |
| |
| 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. |
| |
| @geindex Source_File_Name pragma |
| |
| 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: |
| |
| @example |
| 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 example |
| |
| 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 @code{gnat.adc} |
| file used to hold configuration |
| pragmas that apply to a complete compilation environment. |
| For more details on how the @code{gnat.adc} file is created and used |
| see @ref{3f,,Handling of Configuration Pragmas}. |
| |
| @geindex gnat.adc |
| |
| 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 @code{.ads} or @code{.adb} it is necessary to use |
| a special syntax when compiling the file. The name in this case must be |
| preceded by the special sequence @code{-x} followed by a space and the name |
| of the language, here @code{ada}, as in: |
| |
| @example |
| $ gcc -c -x ada peculiar_file_name.sim |
| @end example |
| |
| @code{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 @code{gnatmake} command, it may not |
| be omitted. |
| |
| @node Alternative File Naming Schemes,Handling Arbitrary File Naming Conventions with gnatname,Using Other File Names,File Naming Topics and Utilities |
| @anchor{gnat_ugn/the_gnat_compilation_model alternative-file-naming-schemes}@anchor{40}@anchor{gnat_ugn/the_gnat_compilation_model id11}@anchor{41} |
| @subsection Alternative File Naming Schemes |
| |
| |
| @geindex File naming schemes |
| @geindex alternative |
| |
| @geindex File names |
| |
| The previous section 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 @code{gnat.adc} files, and also create |
| a maintenance problem. |
| |
| @geindex Source_File_Name pragma |
| |
| 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: |
| |
| @example |
| pragma Source_File_Name ( |
| Spec_File_Name => FILE_NAME_PATTERN |
| [ , Casing => CASING_SPEC] |
| [ , Dot_Replacement => STRING_LITERAL ] ); |
| |
| pragma Source_File_Name ( |
| Body_File_Name => FILE_NAME_PATTERN |
| [ , Casing => CASING_SPEC ] |
| [ , Dot_Replacement => STRING_LITERAL ] ) ; |
| |
| pragma Source_File_Name ( |
| Subunit_File_Name => FILE_NAME_PATTERN |
| [ , Casing => CASING_SPEC ] |
| [ , Dot_Replacement => STRING_LITERAL ] ) ; |
| |
| FILE_NAME_PATTERN ::= STRING_LITERAL |
| CASING_SPEC ::= Lowercase | Uppercase | Mixedcase |
| @end example |
| |
| 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. |
| |
| 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 * |
| |
| @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 |
| |
| 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 @code{.1.ada}, and |
| bodies end with @code{.2.ada}. GNAT will follow this scheme if the following |
| two pragmas appear: |
| |
| @example |
| pragma Source_File_Name |
| (Spec_File_Name => ".1.ada"); |
| pragma Source_File_Name |
| (Body_File_Name => ".2.ada"); |
| @end example |
| |
| The default GNAT scheme is actually implemented by providing the following |
| default pragmas internally: |
| |
| @example |
| pragma Source_File_Name |
| (Spec_File_Name => ".ads", Dot_Replacement => "-"); |
| pragma Source_File_Name |
| (Body_File_Name => ".adb", Dot_Replacement => "-"); |
| @end example |
| |
| 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 @code{_.ADA}, bodies |
| by adding @code{.ADA}, and subunits by |
| adding @code{.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. |
| |
| @example |
| 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 example |
| |
| @geindex gnatname |
| |
| @node Handling Arbitrary File Naming Conventions with gnatname,File Name Krunching with gnatkr,Alternative File Naming Schemes,File Naming Topics and Utilities |
| @anchor{gnat_ugn/the_gnat_compilation_model handling-arbitrary-file-naming-conventions-with-gnatname}@anchor{42}@anchor{gnat_ugn/the_gnat_compilation_model id12}@anchor{43} |
| @subsection Handling Arbitrary File Naming Conventions with @code{gnatname} |
| |
| |
| @geindex File Naming Conventions |
| |
| @menu |
| * Arbitrary File Naming Conventions:: |
| * Running gnatname:: |
| * Switches for gnatname:: |
| * Examples of gnatname Usage:: |
| |
| @end menu |
| |
| @node Arbitrary File Naming Conventions,Running gnatname,,Handling Arbitrary File Naming Conventions with gnatname |
| @anchor{gnat_ugn/the_gnat_compilation_model arbitrary-file-naming-conventions}@anchor{44}@anchor{gnat_ugn/the_gnat_compilation_model id13}@anchor{45} |
| @subsubsection Arbitrary File Naming Conventions |
| |
| |
| 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. |
| |
| 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 (@ref{25,,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 |
| (@ref{40,,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,Switches for gnatname,Arbitrary File Naming Conventions,Handling Arbitrary File Naming Conventions with gnatname |
| @anchor{gnat_ugn/the_gnat_compilation_model id14}@anchor{46}@anchor{gnat_ugn/the_gnat_compilation_model running-gnatname}@anchor{47} |
| @subsubsection Running @code{gnatname} |
| |
| |
| The usual form of the @code{gnatname} command is: |
| |
| @example |
| $ gnatname [ switches ] naming_pattern [ naming_patterns ] |
| [--and [ switches ] naming_pattern [ naming_patterns ]] |
| @end example |
| |
| All of the arguments are optional. If invoked without any argument, |
| @code{gnatname} will display its usage. |
| |
| 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. |
| |
| 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. |
| |
| @code{gnatname} may be called with several sections of directories/patterns. |
| Sections are separated by the 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 if @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. |
| |
| Examples of Naming Patterns are: |
| |
| @example |
| "*.[12].ada" |
| "*.ad[sb]*" |
| "body_*" "spec_*" |
| @end example |
| |
| For a more complete description of the syntax of Naming Patterns, |
| see the second kind of regular expressions described in @code{g-regexp.ads} |
| (the ‘Glob’ regular expressions). |
| |
| When invoked without the switch @code{-P}, @code{gnatname} will create a |
| configuration pragmas file @code{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,Examples of gnatname Usage,Running gnatname,Handling Arbitrary File Naming Conventions with gnatname |
| @anchor{gnat_ugn/the_gnat_compilation_model id15}@anchor{48}@anchor{gnat_ugn/the_gnat_compilation_model switches-for-gnatname}@anchor{49} |
| @subsubsection Switches for @code{gnatname} |
| |
| |
| Switches for @code{gnatname} must precede any specified Naming Pattern. |
| |
| You may specify any of the following switches to @code{gnatname}: |
| |
| @geindex --version (gnatname) |
| |
| |
| @table @asis |
| |
| @item @code{--version} |
| |
| Display Copyright and version, then exit disregarding all other options. |
| @end table |
| |
| @geindex --help (gnatname) |
| |
| |
| @table @asis |
| |
| @item @code{--help} |
| |
| If @code{--version} was not used, display usage, then exit disregarding |
| all other options. |
| |
| @item @code{--subdirs=@emph{dir}} |
| |
| Real object, library or exec directories are subdirectories <dir> of the |
| specified ones. |
| |
| @item @code{--no-backup} |
| |
| Do not create a backup copy of an existing project file. |
| |
| @item @code{--and} |
| |
| Start another section of directories/patterns. |
| @end table |
| |
| @geindex -c (gnatname) |
| |
| |
| @table @asis |
| |
| @item @code{-c@emph{filename}} |
| |
| Create a configuration pragmas file @code{filename} (instead of the default |
| @code{gnat.adc}). |
| There may be zero, one or more space between @code{-c} and |
| @code{filename}. |
| @code{filename} may include directory information. @code{filename} must be |
| writable. There may be only one switch @code{-c}. |
| When a switch @code{-c} is |
| specified, no switch @code{-P} may be specified (see below). |
| @end table |
| |
| @geindex -d (gnatname) |
| |
| |
| @table @asis |
| |
| @item @code{-d@emph{dir}} |
| |
| Look for source files in directory @code{dir}. There may be zero, one or more |
| spaces between @code{-d} and @code{dir}. |
| @code{dir} may end with @code{/**}, that is it may be of the form |
| @code{root_dir/**}. In this case, the directory @code{root_dir} and all of its |
| subdirectories, recursively, have to be searched for sources. |
| When a switch @code{-d} |
| is specified, the current working directory will not be searched for source |
| files, unless it is explicitly specified with a @code{-d} |
| or @code{-D} switch. |
| Several switches @code{-d} may be specified. |
| If @code{dir} is a relative path, it is relative to the directory of |
| the configuration pragmas file specified with switch |
| @code{-c}, |
| or to the directory of the project file specified with switch |
| @code{-P} or, |
| if neither switch @code{-c} |
| nor switch @code{-P} are specified, it is relative to the |
| current working directory. The directory |
| specified with switch @code{-d} must exist and be readable. |
| @end table |
| |
| @geindex -D (gnatname) |
| |
| |
| @table @asis |
| |
| @item @code{-D@emph{filename}} |
| |
| Look for source files in all directories listed in text file @code{filename}. |
| There may be zero, one or more spaces between @code{-D} |
| and @code{filename}. |
| @code{filename} must be an existing, readable text file. |
| Each nonempty line in @code{filename} must be a directory. |
| Specifying switch @code{-D} is equivalent to specifying as many |
| switches @code{-d} as there are nonempty lines in |
| @code{file}. |
| |
| @item @code{-eL} |
| |
| Follow symbolic links when processing project files. |
| |
| @geindex -f (gnatname) |
| |
| @item @code{-f@emph{pattern}} |
| |
| 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 switch is used. |
| For example, |
| |
| @example |
| gnatname -Pprj -f"*.c" "*.ada" |
| @end example |
| |
| will look for Ada units in all files with the @code{.ada} extension, |
| and will add to the list of file for project @code{prj.gpr} the C files |
| with extension @code{.c}. |
| |
| @geindex -h (gnatname) |
| |
| @item @code{-h} |
| |
| Output usage (help) information. The output is written to @code{stdout}. |
| |
| @geindex -P (gnatname) |
| |
| @item @code{-P@emph{proj}} |
| |
| Create or update project file @code{proj}. There may be zero, one or more space |
| between @code{-P} and @code{proj}. @code{proj} may include directory |
| information. @code{proj} must be writable. |
| There may be only one switch @code{-P}. |
| When a switch @code{-P} is specified, |
| no switch @code{-c} may be specified. |
| On all platforms, except on VMS, when @code{gnatname} is invoked for an |
| existing project file <proj>.gpr, a backup copy of the project file is created |
| in the project directory with file name <proj>.gpr.saved_x. ‘x’ is the first |
| non negative number that makes this backup copy a new file. |
| |
| @geindex -v (gnatname) |
| |
| @item @code{-v} |
| |
| Verbose mode. Output detailed explanation of behavior to @code{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. |
| @end table |
| |
| @geindex -v -v (gnatname) |
| |
| |
| @table @asis |
| |
| @item @code{-v -v} |
| |
| 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. |
| |
| @geindex -x (gnatname) |
| |
| @item @code{-x@emph{pattern}} |
| |
| Excluded patterns. Using this switch, it is possible to exclude some files |
| that would match the name patterns. For example, |
| |
| @example |
| gnatname -x "*_nt.ada" "*.ada" |
| @end example |
| |
| will look for Ada units in all files with the @code{.ada} extension, |
| except those whose names end with @code{_nt.ada}. |
| @end table |
| |
| @node Examples of gnatname Usage,,Switches for gnatname,Handling Arbitrary File Naming Conventions with gnatname |
| @anchor{gnat_ugn/the_gnat_compilation_model examples-of-gnatname-usage}@anchor{4a}@anchor{gnat_ugn/the_gnat_compilation_model id16}@anchor{4b} |
| @subsubsection Examples of @code{gnatname} Usage |
| |
| |
| @example |
| $ gnatname -c /home/me/names.adc -d sources "[a-z]*.ada*" |
| @end example |
| |
| In this example, the directory @code{/home/me} must already exist |
| and be writable. In addition, the directory |
| @code{/home/me/sources} (specified by |
| @code{-d sources}) must exist and be readable. |
| |
| Note the optional spaces after @code{-c} and @code{-d}. |
| |
| @example |
| $ gnatname -P/home/me/proj -x "*_nt_body.ada" |
| -dsources -dsources/plus -Dcommon_dirs.txt "body_*" "spec_*" |
| @end example |
| |
| Note that several switches @code{-d} may be used, |
| even in conjunction with one or several switches |
| @code{-D}. Several Naming Patterns and one excluded pattern |
| are used in this example. |
| |
| @node File Name Krunching with gnatkr,Renaming Files with gnatchop,Handling Arbitrary File Naming Conventions with gnatname,File Naming Topics and Utilities |
| @anchor{gnat_ugn/the_gnat_compilation_model file-name-krunching-with-gnatkr}@anchor{4c}@anchor{gnat_ugn/the_gnat_compilation_model id17}@anchor{4d} |
| @subsection File Name Krunching with @code{gnatkr} |
| |
| |
| @geindex gnatkr |
| |
| This section 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,Using gnatkr,,File Name Krunching with gnatkr |
| @anchor{gnat_ugn/the_gnat_compilation_model about-gnatkr}@anchor{4e}@anchor{gnat_ugn/the_gnat_compilation_model id18}@anchor{4f} |
| @subsubsection About @code{gnatkr} |
| |
| |
| 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 * |
| |
| @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 |
| @code{a}, @code{g}, @code{s}, or @code{i}, |
| then replace the dot by the character |
| @code{~} (tilde) |
| instead of a minus. |
| |
| 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 |
| @code{s-}, @code{a-}, @code{i-}, and @code{g-}, |
| respectively. |
| @end itemize |
| |
| The @code{-gnatk@emph{nn}} |
| switch of the compiler activates a ‘krunching’ |
| circuit that limits file names to nn characters (where nn is a decimal |
| integer). |
| |
| 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,Krunching Method,About gnatkr,File Name Krunching with gnatkr |
| @anchor{gnat_ugn/the_gnat_compilation_model id19}@anchor{50}@anchor{gnat_ugn/the_gnat_compilation_model using-gnatkr}@anchor{3d} |
| @subsubsection Using @code{gnatkr} |
| |
| |
| The @code{gnatkr} command has the form: |
| |
| @example |
| $ gnatkr name [ length ] |
| @end example |
| |
| @code{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 @code{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 @code{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 @code{hellworl.adb}. |
| |
| Note that the result is always all lower case. |
| Characters of the other case are folded as required. |
| |
| @code{length} represents the length of the krunched name. The default |
| when no argument is given is 8 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. |
| |
| 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,Examples of gnatkr Usage,Using gnatkr,File Name Krunching with gnatkr |
| @anchor{gnat_ugn/the_gnat_compilation_model id20}@anchor{51}@anchor{gnat_ugn/the_gnat_compilation_model krunching-method}@anchor{52} |
| @subsubsection Krunching Method |
| |
| |
| 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 |
| for all letters, except that a hyphen in the second character position is |
| replaced by a tilde if the first character is |
| @code{a}, @code{i}, @code{g}, or @code{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 * |
| |
| @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 @code{our-strings-wide_fixed.adb} |
| to fit the name into 8 characters as required by some operating systems: |
| |
| @example |
| 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 example |
| |
| @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: |
| |
| |
| @multitable {xxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxx} |
| @item |
| |
| Prefix |
| |
| @tab |
| |
| Replacement |
| |
| @item |
| |
| @code{ada-} |
| |
| @tab |
| |
| @code{a-} |
| |
| @item |
| |
| @code{gnat-} |
| |
| @tab |
| |
| @code{g-} |
| |
| @item |
| |
| @code{interfac es-} |
| |
| @tab |
| |
| @code{i-} |
| |
| @item |
| |
| @code{system-} |
| |
| @tab |
| |
| @code{s-} |
| |
| @end multitable |
| |
| |
| These system files have a hyphen in the second character position. That |
| is why normal user files replace such a character with a |
| tilde, to avoid confusion with system file names. |
| |
| As an example of this special rule, consider |
| @code{ada-strings-wide_fixed.adb}, which gets krunched as follows: |
| |
| @example |
| 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 example |
| @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,,Krunching Method,File Name Krunching with gnatkr |
| @anchor{gnat_ugn/the_gnat_compilation_model examples-of-gnatkr-usage}@anchor{53}@anchor{gnat_ugn/the_gnat_compilation_model id21}@anchor{54} |
| @subsubsection Examples of @code{gnatkr} Usage |
| |
| |
| @example |
| $ 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 |
| $ gnatkr very_long_unit_name.ads/count=6 --> vlunna.ads |
| $ gnatkr very_long_unit_name.ads/count=0 --> very_long_unit_name.ads |
| @end example |
| |
| @node Renaming Files with gnatchop,,File Name Krunching with gnatkr,File Naming Topics and Utilities |
| @anchor{gnat_ugn/the_gnat_compilation_model id22}@anchor{55}@anchor{gnat_ugn/the_gnat_compilation_model renaming-files-with-gnatchop}@anchor{1d} |
| @subsection Renaming Files with @code{gnatchop} |
| |
| |
| @geindex gnatchop |
| |
| This section 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,Operating gnatchop in Compilation Mode,,Renaming Files with gnatchop |
| @anchor{gnat_ugn/the_gnat_compilation_model handling-files-with-multiple-units}@anchor{56}@anchor{gnat_ugn/the_gnat_compilation_model id23}@anchor{57} |
| @subsubsection Handling Files with Multiple Units |
| |
| |
| 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. |
| |
| If you want to keep your files with multiple units, |
| perhaps to maintain compatibility with some other Ada compilation system, |
| you can use @code{gnatname} to generate or update your project files. |
| Generated or modified project files can be processed by GNAT. |
| |
| See @ref{42,,Handling Arbitrary File Naming Conventions with gnatname} |
| for more details on how to use @cite{gnatname}. |
| |
| Alternatively, 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 @code{gnatchop} once, generate the |
| new set of files and work with them from that point on. |
| |
| 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,Command Line for gnatchop,Handling Files with Multiple Units,Renaming Files with gnatchop |
| @anchor{gnat_ugn/the_gnat_compilation_model id24}@anchor{58}@anchor{gnat_ugn/the_gnat_compilation_model operating-gnatchop-in-compilation-mode}@anchor{59} |
| @subsubsection Operating gnatchop in Compilation Mode |
| |
| |
| 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 |
| @code{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 |
| @code{gnat.adc} file is the representation |
| of a compilation environment. For more information on the |
| @code{gnat.adc} file, see @ref{3f,,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,Switches for gnatchop,Operating gnatchop in Compilation Mode,Renaming Files with gnatchop |
| @anchor{gnat_ugn/the_gnat_compilation_model command-line-for-gnatchop}@anchor{5a}@anchor{gnat_ugn/the_gnat_compilation_model id25}@anchor{5b} |
| @subsubsection Command Line for @code{gnatchop} |
| |
| |
| The @code{gnatchop} command has the form: |
| |
| @example |
| $ gnatchop switches file_name [file_name ...] |
| [directory] |
| @end example |
| |
| 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. |
| |
| @code{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 @code{hellofiles} containing |
| |
| @example |
| procedure Hello; |
| |
| with Ada.Text_IO; use Ada.Text_IO; |
| procedure Hello is |
| begin |
| Put_Line ("Hello"); |
| end Hello; |
| @end example |
| |
| the command |
| |
| @example |
| $ gnatchop hellofiles |
| @end example |
| |
| generates two files in the current directory, one called |
| @code{hello.ads} containing the single line that is the procedure spec, |
| and the other called @code{hello.adb} containing the remaining text. The |
| original file is not affected. The generated files can be compiled in |
| the normal manner. |
| |
| 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 @code{toto.txt} containing |
| |
| @example |
| -- Just a comment |
| @end example |
| |
| the command |
| |
| @example |
| $ gnatchop toto.txt |
| @end example |
| |
| will not produce any new file and will result in the following warnings: |
| |
| @example |
| toto.txt:1:01: warning: empty file, contains no compilation units |
| no compilation units found |
| no source files written |
| @end example |
| |
| @node Switches for gnatchop,Examples of gnatchop Usage,Command Line for gnatchop,Renaming Files with gnatchop |
| @anchor{gnat_ugn/the_gnat_compilation_model id26}@anchor{5c}@anchor{gnat_ugn/the_gnat_compilation_model switches-for-gnatchop}@anchor{5d} |
| @subsubsection Switches for @code{gnatchop} |
| |
| |
| @code{gnatchop} recognizes the following switches: |
| |
| @geindex --version (gnatchop) |
| |
| |
| @table @asis |
| |
| @item @code{--version} |
| |
| Display Copyright and version, then exit disregarding all other options. |
| @end table |
| |
| @geindex --help (gnatchop) |
| |
| |
| @table @asis |
| |
| @item @code{--help} |
| |
| If @code{--version} was not used, display usage, then exit disregarding |
| all other options. |
| @end table |
| |
| @geindex -c (gnatchop) |
| |
| |
| @table @asis |
| |
| @item @code{-c} |
| |
| 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. |
| |
| @item @code{-gnat@emph{xxx}} |
| |
| This passes the given @code{-gnat@emph{xxx}} switch to @code{gnat} which is |
| used to parse the given file. Not all @emph{xxx} options make sense, |
| but for example, the use of @code{-gnati2} allows @code{gnatchop} to |
| process a source file that uses Latin-2 coding for identifiers. |
| |
| @item @code{-h} |
| |
| Causes @code{gnatchop} to generate a brief help summary to the standard |
| output file showing usage information. |
| @end table |
| |
| @geindex -k (gnatchop) |
| |
| |
| @table @asis |
| |
| @item @code{-k@emph{mm}} |
| |
| 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. |
| No space is allowed between the @code{-k} and the numeric value. The numeric |
| value may be omitted in which case a default of @code{-k8}, |
| suitable for use |
| with DOS-like file systems, is used. If no @code{-k} switch |
| is present then |
| there is no limit on the length of file names. |
| @end table |
| |
| @geindex -p (gnatchop) |
| |
| |
| @table @asis |
| |
| @item @code{-p} |
| |
| Causes the file modification 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. |
| @end table |
| |
| @geindex -q (gnatchop) |
| |
| |
| @table @asis |
| |
| @item @code{-q} |
| |
| Causes output of informational messages indicating the set of generated |
| files to be suppressed. Warnings and error messages are unaffected. |
| @end table |
| |
| @geindex -r (gnatchop) |
| |
| @geindex Source_Reference pragmas |
| |
| |
| @table @asis |
| |
| @item @code{-r} |
| |
| 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 @code{-g} switch of @code{gcc} or @code{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. |
| @end table |
| |
| @geindex -v (gnatchop) |
| |
| |
| @table @asis |
| |
| @item @code{-v} |
| |
| 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. |
| @end table |
| |
| @geindex -w (gnatchop) |
| |
| |
| @table @asis |
| |
| @item @code{-w} |
| |
| 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. |
| @end table |
| |
| @geindex --GCC= (gnatchop) |
| |
| |
| @table @asis |
| |
| @item @code{--GCC=@emph{xxxx}} |
| |
| 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 table |
| |
| @node Examples of gnatchop Usage,,Switches for gnatchop,Renaming Files with gnatchop |
| @anchor{gnat_ugn/the_gnat_compilation_model examples-of-gnatchop-usage}@anchor{5e}@anchor{gnat_ugn/the_gnat_compilation_model id27}@anchor{5f} |
| @subsubsection Examples of @code{gnatchop} Usage |
| |
| |
| @example |
| $ gnatchop -w hello_s.ada prerelease/files |
| @end example |
| |
| Chops the source file @code{hello_s.ada}. The output files will be |
| placed in the directory @code{prerelease/files}, |
| overwriting any |
| files with matching names in that directory (no files in the current |
| directory are modified). |
| |
| @example |
| $ gnatchop archive |
| @end example |
| |
| Chops the source file @code{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} |
| command), and then |
| @code{gnatchop} is used at the other end to reconstitute the original |
| file names. |
| |
| @example |
| $ gnatchop file1 file2 file3 direc |
| @end example |
| |
| Chops all units in files @code{file1}, @code{file2}, @code{file3}, placing |
| the resulting files in the directory @code{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 |
| @code{-w} 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. |
| |
| @node Configuration Pragmas,Generating Object Files,File Naming Topics and Utilities,The GNAT Compilation Model |
| @anchor{gnat_ugn/the_gnat_compilation_model configuration-pragmas}@anchor{25}@anchor{gnat_ugn/the_gnat_compilation_model id28}@anchor{60} |
| @section Configuration Pragmas |
| |
| |
| @geindex Configuration pragmas |
| |
| @geindex Pragmas |
| @geindex configuration |
| |
| Configuration pragmas include those pragmas described as |
| such in the Ada Reference Manual, as well as |
| implementation-dependent pragmas that are configuration pragmas. |
| See the @code{Implementation_Defined_Pragmas} chapter in the |
| @cite{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: |
| |
| @example |
| Ada_83 |
| Ada_95 |
| Ada_05 |
| Ada_2005 |
| Ada_12 |
| Ada_2012 |
| Allow_Integer_Address |
| Annotate |
| Assertion_Policy |
| Assume_No_Invalid_Values |
| C_Pass_By_Copy |
| Check_Float_Overflow |
| Check_Name |
| Check_Policy |
| Component_Alignment |
| Convention_Identifier |
| Debug_Policy |
| Default_Scalar_Storage_Order |
| Default_Storage_Pool |
| Detect_Blocking |
| Disable_Atomic_Synchronization |
| Discard_Names |
| Elaboration_Checks |
| Eliminate |
| Enable_Atomic_Synchronization |
| Extend_System |
| Extensions_Allowed |
| External_Name_Casing |
| Fast_Math |
| Favor_Top_Level |
| Ignore_Pragma |
| Implicit_Packing |
| Initialize_Scalars |
| Interrupt_State |
| License |
| Locking_Policy |
| No_Component_Reordering |
| No_Heap_Finalization |
| No_Strict_Aliasing |
| Normalize_Scalars |
| Optimize_Alignment |
| Overflow_Mode |
| Overriding_Renamings |
| Partition_Elaboration_Policy |
| Persistent_BSS |
| Prefix_Exception_Messages |
| Priority_Specific_Dispatching |
| Profile |
| Profile_Warnings |
| Queuing_Policy |
| Rename_Pragma |
| Restrictions |
| Restriction_Warnings |
| Reviewable |
| Short_Circuit_And_Or |
| Source_File_Name |
| Source_File_Name_Project |
| SPARK_Mode |
| Style_Checks |
| Suppress |
| Suppress_Exception_Locations |
| Task_Dispatching_Policy |
| Unevaluated_Use_Of_Old |
| Unsuppress |
| Use_VADS_Size |
| Validity_Checks |
| Warning_As_Error |
| Warnings |
| Wide_Character_Encoding |
| @end example |
| |
| @menu |
| * Handling of Configuration Pragmas:: |
| * The Configuration Pragmas Files:: |
| |
| @end menu |
| |
| @node Handling of Configuration Pragmas,The Configuration Pragmas Files,,Configuration Pragmas |
| @anchor{gnat_ugn/the_gnat_compilation_model handling-of-configuration-pragmas}@anchor{3f}@anchor{gnat_ugn/the_gnat_compilation_model id29}@anchor{61} |
| @subsection 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{59,,Operating gnatchop in Compilation Mode} for details. |
| However, for most purposes, it will be more convenient to edit the |
| @code{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 @emph{with}ed unit to the @emph{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 either 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,,Handling of Configuration Pragmas,Configuration Pragmas |
| @anchor{gnat_ugn/the_gnat_compilation_model id30}@anchor{62}@anchor{gnat_ugn/the_gnat_compilation_model the-configuration-pragmas-files}@anchor{63} |
| @subsection The Configuration Pragmas Files |
| |
| |
| @geindex gnat.adc |
| |
| 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 @code{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 @code{-gnatA} is used, @code{gnat.adc} is not |
| considered. When taken into account, @code{gnat.adc} is added to the |
| dependencies, so that if @code{gnat.adc} is modified later, an invocation of |
| @code{gnatmake} will recompile the source. |
| |
| Configuration pragmas may be entered into the @code{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 |
| @code{gnat.adc} file, which is a standard format source file. |
| |
| Besides @code{gnat.adc}, additional files containing configuration |
| pragmas may be applied to the current compilation using the switch |
| @code{-gnatec=@emph{path}} where @code{path} must designate an existing file that |
| contains only configuration pragmas. These configuration pragmas are |
| in addition to those found in @code{gnat.adc} (provided @code{gnat.adc} |
| is present and switch @code{-gnatA} is not used). |
| |
| It is allowable to specify several switches @code{-gnatec=}, all of which |
| will be taken into account. |
| |
| Files containing configuration pragmas specified with switches |
| @code{-gnatec=} are added to the dependencies, unless they are |
| temporary files. A file is considered temporary if its name ends in |
| @code{.tmp} or @code{.TMP}. Certain tools follow this naming |
| convention because they pass information to @code{gcc} via |
| temporary files that are immediately deleted; it doesn’t make sense to |
| depend on a file that no longer exists. Such tools include |
| @code{gprbuild}, @code{gnatmake}, and @code{gnatcheck}. |
| |
| By default, configuration pragma files are stored by their absolute paths in |
| ALI files. You can use the @code{-gnateb} switch in order to store them by |
| their basename instead. |
| |
| If you are using project file, a separate mechanism is provided using |
| project attributes. |
| |
| @c --Comment |
| @c See :ref:`Specifying_Configuration_Pragmas` for more details. |
| |
| @node Generating Object Files,Source Dependencies,Configuration Pragmas,The GNAT Compilation Model |
| @anchor{gnat_ugn/the_gnat_compilation_model generating-object-files}@anchor{26}@anchor{gnat_ugn/the_gnat_compilation_model id31}@anchor{64} |
| @section Generating Object Files |
| |
| |
| 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 * |
| |
| @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. |
| @end itemize |
| |
| @geindex Subunits |
| |
| |
| @itemize * |
| |
| @item |
| 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). |
| |
| @geindex Generics |
| |
| @item |
| 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 |
| |
| 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 |
| @code{.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 @code{-gnatc} switch. |
| |
| @node Source Dependencies,The Ada Library Information Files,Generating Object Files,The GNAT Compilation Model |
| @anchor{gnat_ugn/the_gnat_compilation_model id32}@anchor{65}@anchor{gnat_ugn/the_gnat_compilation_model source-dependencies}@anchor{27} |
| @section Source Dependencies |
| |
| |
| A given object file clearly depends on the source file which is compiled |
| to produce it. Here we are using “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 * |
| |
| @item |
| If a file being compiled @emph{with}s a unit @code{X}, the object file |
| depends on the file containing the spec of unit @code{X}. This includes |
| files that are @emph{with}ed implicitly either because they are parents |
| of @emph{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. |
| @end itemize |
| |
| @geindex Inline |
| |
| @geindex -gnatn switch |
| |
| |
| @itemize * |
| |
| @item |
| If a file being compiled contains a call to a subprogram for which |
| pragma @code{Inline} applies and inlining is activated with the |
| @code{-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. |
| |
| @geindex -gnatN switch |
| |
| The use of @code{-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 @code{-gnatn}, |
| the use of this switch generates additional dependencies. |
| |
| When using a gcc-based back end, then the use of |
| @code{-gnatN} is deprecated, and the use of @code{-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 @code{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 @code{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. |
| |
| These rules are applied transitively: if unit @code{A} @emph{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 @code{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 @code{gnatmake}. |
| @end itemize |
| |
| @node The Ada Library Information Files,Binding an Ada Program,Source Dependencies,The GNAT Compilation Model |
| @anchor{gnat_ugn/the_gnat_compilation_model id33}@anchor{66}@anchor{gnat_ugn/the_gnat_compilation_model the-ada-library-information-files}@anchor{28} |
| @section The Ada Library Information Files |
| |
| |
| @geindex Ada Library Information files |
| |
| @geindex ALI files |
| |
| Each compilation actually generates two output files. The first of these |
| is the normal object file that has a @code{.o} extension. The second is a |
| text file containing full dependency information. It has the same |
| name as the source file, but an @code{.ali} extension. |
| This file is known as the Ada Library Information (@code{ALI}) file. |
| The following information is contained in the @code{ALI} file. |
| |
| |
| @itemize * |
| |
| @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 @code{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 @emph{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 |
| |
| For a full detailed description of the format of the @code{ALI} file, |
| see the source of the body of unit @code{Lib.Writ}, contained in file |
| @code{lib-writ.adb} in the GNAT compiler sources. |
| |
| @node Binding an Ada Program,GNAT and Libraries,The Ada Library Information Files,The GNAT Compilation Model |
| @anchor{gnat_ugn/the_gnat_compilation_model binding-an-ada-program}@anchor{29}@anchor{gnat_ugn/the_gnat_compilation_model id34}@anchor{67} |
| @section Binding an Ada Program |
| |
| |
| 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 @code{b~xxx}.adb` (with the corresponding spec |
| @code{b~xxx}.ads`) where @code{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 GNAT and Libraries,Conditional Compilation,Binding an Ada Program,The GNAT Compilation Model |
| @anchor{gnat_ugn/the_gnat_compilation_model gnat-and-libraries}@anchor{2a}@anchor{gnat_ugn/the_gnat_compilation_model id35}@anchor{68} |
| @section GNAT and Libraries |
| |
| |
| @geindex Library building and using |
| |
| This section 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 (see the @emph{GNAT_Project_Manager} chapter of the |
| @emph{GPRbuild User’s Guide}) 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,General Ada Libraries,,GNAT and Libraries |
| @anchor{gnat_ugn/the_gnat_compilation_model id36}@anchor{69}@anchor{gnat_ugn/the_gnat_compilation_model introduction-to-libraries-in-gnat}@anchor{6a} |
| @subsection Introduction to Libraries in GNAT |
| |
| |
| 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 * |
| |
| @item |
| Source files, |
| |
| @item |
| @code{ALI} files (see @ref{28,,The Ada Library Information Files}), and |
| |
| @item |
| Object files, an archive or a shared library. |
| @end itemize |
| |
| 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} (@ref{6b,,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 @code{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,Stand-alone Ada Libraries,Introduction to Libraries in GNAT,GNAT and Libraries |
| @anchor{gnat_ugn/the_gnat_compilation_model general-ada-libraries}@anchor{6c}@anchor{gnat_ugn/the_gnat_compilation_model id37}@anchor{6d} |
| @subsection General Ada Libraries |
| |
| |
| @menu |
| * Building a library:: |
| * Installing a library:: |
| * Using a library:: |
| |
| @end menu |
| |
| @node Building a library,Installing a library,,General Ada Libraries |
| @anchor{gnat_ugn/the_gnat_compilation_model building-a-library}@anchor{6e}@anchor{gnat_ugn/the_gnat_compilation_model id38}@anchor{6f} |
| @subsubsection Building a library |
| |
| |
| 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} |
| (see the @emph{Library Projects} section in the @emph{GNAT Project Manager} |
| chapter of the @emph{GPRbuild User’s Guide}). |
| |
| 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: |
| |
| |
| @itemize * |
| |
| @item |
| |
| @table @asis |
| |
| @item @code{Library_Kind} |
| |
| This attribute controls whether the library is to be static or dynamic |
| @end table |
| |
| @item |
| |
| @table @asis |
| |
| @item @code{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. |
| @end table |
| |
| @item |
| @code{Library_Options} |
| |
| @item |
| |
| @table @asis |
| |
| @item @code{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 |
| @end itemize |
| |
| 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 @code{ALI} files |
| to the specified location). |
| |
| Here is a simple library project file: |
| |
| @example |
| 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 example |
| |
| and the compilation command to build and install the library: |
| |
| @example |
| $ gnatmake -Pmy_lib |
| @end example |
| |
| 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 (@ref{70,,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 |
| @code{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: |
| |
| @example |
| with My_Lib.Service1; |
| with My_Lib.Service2; |
| with My_Lib.Service3; |
| procedure My_Lib_Dummy is |
| begin |
| null; |
| end; |
| @end example |
| |
| Here are the generic commands that will build an archive or a shared library. |
| |
| @example |
| # 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 example |
| |
| Please note that the library must have a name of the form @code{lib@emph{xxx}.a} |
| or @code{lib@emph{xxx}.so} (or @code{lib@emph{xxx}.dll} on Windows) in order to |
| be accessed by the directive @code{-l@emph{xxx}} at link time. |
| |
| @node Installing a library,Using a library,Building a library,General Ada Libraries |
| @anchor{gnat_ugn/the_gnat_compilation_model id39}@anchor{71}@anchor{gnat_ugn/the_gnat_compilation_model installing-a-library}@anchor{72} |
| @subsubsection Installing a library |
| |
| |
| @geindex ADA_PROJECT_PATH |
| |
| @geindex GPR_PROJECT_PATH |
| |
| If you use project files, library installation is part of the library build |
| process (see the @emph{Installing a Library with Project Files} section of the |
| @emph{GNAT Project Manager} chapter of the @emph{GPRbuild User’s Guide}). |
| |
| 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{73,,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 |
| @code{ada_source_path} and @code{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: |
| |
| @example |
| $ gcc -v |
| @end example |
| |
| 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 @code{ada_source_path} and @code{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 @code{adainclude} (for the sources) and @code{adalib} (for the |
| objects and @code{ALI} files). When the files exist, the compiler does not |
| look in @code{adainclude} and @code{adalib}, and thus the |
| @code{ada_source_path} file |
| must contain the location for the GNAT run-time sources (which can simply |
| be @code{adainclude}). In the same way, the @code{ada_object_path} file must |
| contain the location for the GNAT run-time objects (which can simply |
| be @code{adalib}). |
| |
| You can also specify a new default path to the run-time library at compilation |
| time with the switch @code{--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 @code{gcc}, @code{gnatmake}, @code{gnatbind}, |
| @code{gnatls}, @code{gnatfind} and @code{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,,Installing a library,General Ada Libraries |
| @anchor{gnat_ugn/the_gnat_compilation_model id40}@anchor{74}@anchor{gnat_ugn/the_gnat_compilation_model using-a-library}@anchor{75} |
| @subsubsection Using a library |
| |
| |
| Once again, the project facility greatly simplifies the use of |
| libraries. In this context, using a library is just a matter of adding a |
| @emph{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: |
| |
| @example |
| with "my_lib"; |
| project My_Proj is |
| ... |
| end My_Proj; |
| @end example |
| |
| 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 @emph{with}ed by your main project, will link with the |
| third-party library @code{liba.a}: |
| |
| @example |
| 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 example |
| |
| 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. |
| |
| 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{73,,Search Paths and the Run-Time Library (RTL)} |
| and @ref{76,,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 @code{mylib} installed in |
| @code{/dir/my_lib_src} and @code{/dir/my_lib_obj} with the following commands: |
| |
| @example |
| $ gnatmake -aI/dir/my_lib_src -aO/dir/my_lib_obj my_appl \\ |
| -largs -lmy_lib |
| @end example |
| |
| This can be expressed more simply: |
| |
| @example |
| $ gnatmake my_appl |
| @end example |
| |
| when the following conditions are met: |
| |
| |
| @itemize * |
| |
| @item |
| @code{/dir/my_lib_src} has been added by the user to the environment |
| variable |
| @geindex ADA_INCLUDE_PATH |
| @geindex environment variable; ADA_INCLUDE_PATH |
| @code{ADA_INCLUDE_PATH}, or by the administrator to the file |
| @code{ada_source_path} |
| |
| @item |
| @code{/dir/my_lib_obj} has been added by the user to the environment |
| variable |
| @geindex ADA_OBJECTS_PATH |
| @geindex environment variable; ADA_OBJECTS_PATH |
| @code{ADA_OBJECTS_PATH}, or by the administrator to the file |
| @code{ada_object_path} |
| |
| @item |
| a pragma @code{Linker_Options} has been added to one of the sources. |
| For example: |
| |
| @example |
| pragma Linker_Options ("-lmy_lib"); |
| @end example |
| @end itemize |
| |
| Note that you may also load a library dynamically at |
| run time given its filename, as illustrated in the GNAT @code{plugins} example |
| in the directory @code{share/examples/gnat/plugins} within the GNAT |
| install area. |
| |
| @node Stand-alone Ada Libraries,Rebuilding the GNAT Run-Time Library,General Ada Libraries,GNAT and Libraries |
| @anchor{gnat_ugn/the_gnat_compilation_model id41}@anchor{77}@anchor{gnat_ugn/the_gnat_compilation_model stand-alone-ada-libraries}@anchor{6b} |
| @subsection Stand-alone Ada Libraries |
| |
| |
| @geindex Stand-alone libraries |
| |
| @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,Building a Stand-alone Library,,Stand-alone Ada Libraries |
| @anchor{gnat_ugn/the_gnat_compilation_model id42}@anchor{78}@anchor{gnat_ugn/the_gnat_compilation_model introduction-to-stand-alone-libraries}@anchor{79} |
| @subsubsection Introduction to Stand-alone Libraries |
| |
| |
| 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 @code{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 @code{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 @code{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,Creating a Stand-alone Library to be used in a non-Ada context,Introduction to Stand-alone Libraries,Stand-alone Ada Libraries |
| @anchor{gnat_ugn/the_gnat_compilation_model building-a-stand-alone-library}@anchor{7a}@anchor{gnat_ugn/the_gnat_compilation_model id43}@anchor{7b} |
| @subsubsection Building a Stand-alone Library |
| |
| |
| GNAT’s Project facility provides a simple way of building and installing |
| stand-alone libraries; see the @emph{Stand-alone Library Projects} section |
| in the @emph{GNAT Project Manager} chapter of the @emph{GPRbuild User’s Guide}. |
| 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 the @emph{Library Projects} section in the |
| @emph{GNAT Project Manager} chapter of the @emph{GPRbuild User’s Guide}), |
| the attribute @code{Library_Interface} must be defined. For example: |
| |
| @example |
| for Library_Dir use "lib_dir"; |
| for Library_Name use "dummy"; |
| for Library_Interface use ("int1", "int1.child"); |
| @end example |
| |
| 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 |
| (@code{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 @code{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. |
| |
| 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}: |
| |
| @example |
| for Library_Dir use "lib_dir"; |
| for Library_Name use "dummy"; |
| for Library_Kind use "dynamic"; |
| for Library_Interface use ("int1", "int1.child"); |
| for Library_Standalone use "encapsulated"; |
| @end example |
| |
| 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 * |
| |
| @item |
| Compile all library sources. |
| |
| @item |
| Invoke the binder with the switch @code{-n} (No Ada main program), |
| with all the @code{ALI} files of the interfaces, and |
| with the switch @code{-L} to give specific names to the @code{init} |
| and @code{final} procedures. For example: |
| |
| @example |
| $ gnatbind -n int1.ali int2.ali -Lsal1 |
| @end example |
| |
| @item |
| Compile the binder generated file: |
| |
| @example |
| $ gcc -c b~int2.adb |
| @end example |
| |
| @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 @code{SL} on the line in the @code{ALI} file that starts |
| with letter ‘P’) and make the modified copy of the @code{ALI} file |
| read-only. |
| @end itemize |
| |
| Using SALs is not different from using other libraries |
| (see @ref{75,,Using a library}). |
| |
| @node Creating a Stand-alone Library to be used in a non-Ada context,Restrictions in Stand-alone Libraries,Building a Stand-alone Library,Stand-alone Ada Libraries |
| @anchor{gnat_ugn/the_gnat_compilation_model creating-a-stand-alone-library-to-be-used-in-a-non-ada-context}@anchor{7c}@anchor{gnat_ugn/the_gnat_compilation_model id44}@anchor{7d} |
| @subsubsection Creating a Stand-alone Library to be used in a non-Ada context |
| |
| |
| 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: |
| |
| @example |
| 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 example |
| |
| 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) |
| |
| @example |
| /* 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 example |
| |
| 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. |
| |
| @example |
| #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 example |
| |
| 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. |
| |
| Note also that special care must be taken with multi-tasks |
| applications. The initialization and finalization routines are not |
| protected against concurrent access. If such requirement is needed it |
| must be ensured at the application level using a specific operating |
| system services like a mutex or a critical-section. |
| |
| @node Restrictions in Stand-alone Libraries,,Creating a Stand-alone Library to be used in a non-Ada context,Stand-alone Ada Libraries |
| @anchor{gnat_ugn/the_gnat_compilation_model id45}@anchor{7e}@anchor{gnat_ugn/the_gnat_compilation_model restrictions-in-stand-alone-libraries}@anchor{7f} |
| @subsubsection Restrictions in Stand-alone Libraries |
| |
| |
| The pragmas listed below should be used with caution inside libraries, |
| as they can create incompatibilities with other Ada libraries: |
| |
| |
| @itemize * |
| |
| @item |
| pragma @code{Locking_Policy} |
| |
| @item |
| pragma @code{Partition_Elaboration_Policy} |
| |
| @item |
| pragma @code{Queuing_Policy} |
| |
| @item |
| pragma @code{Task_Dispatching_Policy} |
| |
| @item |
| pragma @code{Unreserve_All_Interrupts} |
| @end itemize |
| |
| 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 @code{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,,Stand-alone Ada Libraries,GNAT and Libraries |
| @anchor{gnat_ugn/the_gnat_compilation_model id46}@anchor{80}@anchor{gnat_ugn/the_gnat_compilation_model rebuilding-the-gnat-run-time-library}@anchor{81} |
| @subsection Rebuilding the GNAT Run-Time Library |
| |
| |
| @geindex GNAT Run-Time Library |
| @geindex rebuilding |
| |
| @geindex Building the GNAT Run-Time Library |
| |
| @geindex Rebuilding the GNAT Run-Time Library |
| |
| @geindex Run-Time Library |
| @geindex rebuilding |
| |
| It may be useful to recompile the GNAT library in various debugging or |
| experimentation contexts. A project file called |
| @code{libada.gpr} 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: |
| |
| @example |
| $ gnatls -v |
| @end example |
| |
| The last entry in the source search path usually contains the |
| gnat library (the @code{adainclude} directory). This project file contains its |
| own documentation and in particular the set of instructions needed to rebuild a |
| new library and to use it. |
| |
| Note that rebuilding the GNAT Run-Time is only recommended for temporary |
| experiments or debugging, and is not supported. |
| |
| @geindex Conditional compilation |
| |
| @node Conditional Compilation,Mixed Language Programming,GNAT and Libraries,The GNAT Compilation Model |
| @anchor{gnat_ugn/the_gnat_compilation_model conditional-compilation}@anchor{2b}@anchor{gnat_ugn/the_gnat_compilation_model id47}@anchor{82} |
| @section Conditional Compilation |
| |
| |
| This section presents some guidelines for modeling conditional compilation in Ada and describes the |
| gnatprep preprocessor utility. |
| |
| @geindex Conditional compilation |
| |
| @menu |
| * Modeling Conditional Compilation in Ada:: |
| * Preprocessing with gnatprep:: |
| * Integrated Preprocessing:: |
| |
| @end menu |
| |
| @node Modeling Conditional Compilation in Ada,Preprocessing with gnatprep,,Conditional Compilation |
| @anchor{gnat_ugn/the_gnat_compilation_model id48}@anchor{83}@anchor{gnat_ugn/the_gnat_compilation_model modeling-conditional-compilation-in-ada}@anchor{84} |
| @subsection Modeling Conditional Compilation in Ada |
| |
| |
| 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 * |
| |
| @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 |
| |
| 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 section 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,Debugging - A Special Case,,Modeling Conditional Compilation in Ada |
| @anchor{gnat_ugn/the_gnat_compilation_model id49}@anchor{85}@anchor{gnat_ugn/the_gnat_compilation_model use-of-boolean-constants}@anchor{86} |
| @subsubsection Use of Boolean Constants |
| |
| |
| 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. |
| |
| @example |
| FP_Initialize_Required : constant Boolean := True; |
| ... |
| if FP_Initialize_Required then |
| ... |
| end if; |
| @end example |
| |
| 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.) |
| |
| @geindex Preprocessors (contrasted with conditional compilation) |
| |
| Typically the Boolean constants will be in a separate package, |
| something like: |
| |
| @example |
| package Config is |
| FP_Initialize_Required : constant Boolean := True; |
| Reset_Available : constant Boolean := False; |
| ... |
| end Config; |
| @end example |
| |
| 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 @emph{with} |
| of @code{Config} to make the constants visible. |
| |
| @node Debugging - A Special Case,Conditionalizing Declarations,Use of Boolean Constants,Modeling Conditional Compilation in Ada |
| @anchor{gnat_ugn/the_gnat_compilation_model debugging-a-special-case}@anchor{87}@anchor{gnat_ugn/the_gnat_compilation_model id50}@anchor{88} |
| @subsubsection Debugging - A Special Case |
| |
| |
| 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: |
| |
| @example |
| if Debugging then |
| Put_Line ("got to the first stage!"); |
| end if; |
| @end example |
| |
| or |
| |
| @example |
| if Debugging and then Temperature > 999.0 then |
| raise Temperature_Crazy; |
| end if; |
| @end example |
| |
| @geindex pragma Assert |
| |
| 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 |
| 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 the |
| @cite{GNAT_Reference_Manual}, but as an |
| example, the last test could be written: |
| |
| @example |
| pragma Assert (Temperature <= 999.0, "Temperature Crazy"); |
| @end example |
| |
| or simply |
| |
| @example |
| pragma Assert (Temperature <= 999.0); |
| @end example |
| |
| 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. |
| |
| @geindex pragma Assertion_Policy |
| |
| You can turn assertions on and off by using the @code{Assertion_Policy} |
| pragma. |
| |
| @geindex -gnata switch |
| |
| This is an Ada 2005 pragma which is implemented in all modes by |
| GNAT. Alternatively, you can use the @code{-gnata} switch |
| to enable assertions from the command line, which applies to |
| all versions of Ada. |
| |
| @geindex pragma Debug |
| |
| For the example above with the @code{Put_Line}, the GNAT-specific pragma |
| @code{Debug} can be used: |
| |
| @example |
| pragma Debug (Put_Line ("got to the first stage!")); |
| @end example |
| |
| 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. |
| |
| @geindex pragma Debug_Policy |
| |
| Debug pragmas are enabled using either the @code{-gnata} switch that also |
| controls assertions, or with a separate Debug_Policy pragma. |
| |
| 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 @code{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 @code{-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. |
| |
| @example |
| if ... then |
| ... -- some statements |
| else |
| pragma Assert (Num_Cases < 10); |
| null; |
| end if; |
| @end example |
| |
| @node Conditionalizing Declarations,Use of Alternative Implementations,Debugging - A Special Case,Modeling Conditional Compilation in Ada |
| @anchor{gnat_ugn/the_gnat_compilation_model conditionalizing-declarations}@anchor{89}@anchor{gnat_ugn/the_gnat_compilation_model id51}@anchor{8a} |
| @subsubsection Conditionalizing Declarations |
| |
| |
| 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. |
| |
| This may be possible using declare blocks controlled |
| by conditional constants: |
| |
| @example |
| if Small_Machine then |
| declare |
| X : Bit_String (1 .. 10); |
| begin |
| ... |
| end; |
| else |
| declare |
| X : Large_Bit_String (1 .. 1000); |
| begin |
| ... |
| end; |
| end if; |
| @end example |
| |
| 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 |
| |
| @example |
| for Rec use |
| Field1 at 0 range Boolean'Pos (Little_Endian) * 10 .. Bits_Per_Word; |
| end record; |
| @end example |
| |
| If @code{Bits_Per_Word} is set to 32, this generates either |
| |
| @example |
| for Rec use |
| Field1 at 0 range 0 .. 32; |
| end record; |
| @end example |
| |
| for the big endian case, or |
| |
| @example |
| for Rec use record |
| Field1 at 0 range 10 .. 32; |
| end record; |
| @end example |
| |
| 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,Preprocessing,Conditionalizing Declarations,Modeling Conditional Compilation in Ada |
| @anchor{gnat_ugn/the_gnat_compilation_model id52}@anchor{8b}@anchor{gnat_ugn/the_gnat_compilation_model use-of-alternative-implementations}@anchor{8c} |
| @subsubsection Use of Alternative Implementations |
| |
| |
| 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. |
| |
| @geindex 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: |
| |
| @example |
| if Ada_2005 then |
| ... neat Ada 2005 code |
| else |
| ... not quite as neat Ada 95 code |
| end if; |
| @end example |
| |
| 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 |
| |
| @example |
| procedure Insert is separate; |
| @end example |
| |
| 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 * |
| |
| @item |
| @code{file_queries-insert-2005.adb} |
| |
| @item |
| @code{file_queries-insert-95.adb} |
| @end itemize |
| |
| and the build script renames the appropriate file to @code{file_queries-insert.adb} and then carries out the compilation. |
| |
| This can also be done with project files’ naming schemes. For example: |
| |
| @example |
| for body ("File_Queries.Insert") use "file_queries-insert-2005.ada"; |
| @end example |
| |
| Note also that with project files it is desirable to use a different extension |
| than @code{ads} / @code{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: @code{s-asthan.ads} which is the same for all architectures, and three |
| bodies: |
| |
| |
| @itemize * |
| |
| @item |
| |
| @table @asis |
| |
| @item @code{s-asthan.adb} |
| |
| used for all non-VMS operating systems |
| @end table |
| |
| @item |
| |
| @table @asis |
| |
| @item @code{s-asthan-vms-alpha.adb} |
| |
| used for VMS on the Alpha |
| @end table |
| |
| @item |
| |
| @table @asis |
| |
| @item @code{s-asthan-vms-ia64.adb} |
| |
| used for VMS on the ia64 |
| @end table |
| @end itemize |
| |
| The dummy version @code{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 @code{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,,Use of Alternative Implementations,Modeling Conditional Compilation in Ada |
| @anchor{gnat_ugn/the_gnat_compilation_model id53}@anchor{8d}@anchor{gnat_ugn/the_gnat_compilation_model preprocessing}@anchor{8e} |
| @subsubsection Preprocessing |
| |
| |
| @geindex Preprocessing |
| |
| 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). |
| |
| @geindex gnatprep |
| |
| 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{8f,,Preprocessing with gnatprep}. |
| |
| The preprocessing language allows such constructs as |
| |
| @example |
| #if DEBUG or else (PRIORITY > 4) then |
| sequence of declarations |
| #else |
| completely different sequence of declarations |
| #end if; |
| @end example |
| |
| 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 given 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{90,,Integrated Preprocessing}. |
| |
| @node Preprocessing with gnatprep,Integrated Preprocessing,Modeling Conditional Compilation in Ada,Conditional Compilation |
| @anchor{gnat_ugn/the_gnat_compilation_model id54}@anchor{91}@anchor{gnat_ugn/the_gnat_compilation_model preprocessing-with-gnatprep}@anchor{8f} |
| @subsection Preprocessing with @code{gnatprep} |
| |
| |
| @geindex gnatprep |
| |
| @geindex Preprocessing (gnatprep) |
| |
| This section 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{2b,,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,Using gnatprep,,Preprocessing with gnatprep |
| @anchor{gnat_ugn/the_gnat_compilation_model id55}@anchor{92}@anchor{gnat_ugn/the_gnat_compilation_model preprocessing-symbols}@anchor{93} |
| @subsubsection Preprocessing Symbols |
| |
| |
| Preprocessing symbols are defined in @emph{definition files} and referenced in the |
| 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,Switches for gnatprep,Preprocessing Symbols,Preprocessing with gnatprep |
| @anchor{gnat_ugn/the_gnat_compilation_model id56}@anchor{94}@anchor{gnat_ugn/the_gnat_compilation_model using-gnatprep}@anchor{95} |
| @subsubsection Using @code{gnatprep} |
| |
| |
| To call @code{gnatprep} use: |
| |
| @example |
| $ gnatprep [ switches ] infile outfile [ deffile ] |
| @end example |
| |
| where |
| |
| |
| @itemize * |
| |
| @item |
| |
| @table @asis |
| |
| @item @emph{switches} |
| |
| is an optional sequence of switches as described in the next section. |
| @end table |
| |
| @item |
| |
| @table @asis |
| |
| @item @emph{infile} |
| |
| is the full name of the input file, which is an Ada source |
| file containing preprocessor directives. |
| @end table |
| |
| @item |
| |
| @table @asis |
| |
| @item @emph{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 @code{ads} or @code{adb} suffix. |
| @end table |
| |
| @item |
| |
| @table @asis |
| |
| @item @code{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 @code{-D} switch. |
| @end table |
| @end itemize |
| |
| @node Switches for gnatprep,Form of Definitions File,Using gnatprep,Preprocessing with gnatprep |
| @anchor{gnat_ugn/the_gnat_compilation_model id57}@anchor{96}@anchor{gnat_ugn/the_gnat_compilation_model switches-for-gnatprep}@anchor{97} |
| @subsubsection Switches for @code{gnatprep} |
| |
| |
| @geindex --version (gnatprep) |
| |
| |
| @table @asis |
| |
| @item @code{--version} |
| |
| Display Copyright and version, then exit disregarding all other options. |
| @end table |
| |
| @geindex --help (gnatprep) |
| |
| |
| @table @asis |
| |
| @item @code{--help} |
| |
| If @code{--version} was not used, display usage and then exit disregarding |
| all other options. |
| @end table |
| |
| @geindex -b (gnatprep) |
| |
| |
| @table @asis |
| |
| @item @code{-b} |
| |
| 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. |
| @end table |
| |
| @geindex -c (gnatprep) |
| |
| |
| @table @asis |
| |
| @item @code{-c} |
| |
| 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. |
| @end table |
| |
| @geindex -C (gnatprep) |
| |
| |
| @table @asis |
| |
| @item @code{-C} |
| |
| 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., for programs written in a |
| pre-2014 version of the SPARK Ada subset). 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). |
| @end table |
| |
| @geindex -D (gnatprep) |
| |
| |
| @table @asis |
| |
| @item @code{-D@emph{symbol}[=@emph{value}]} |
| |
| Defines a new preprocessing symbol with the specified 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. |
| @end table |
| |
| @geindex -r (gnatprep) |
| |
| |
| @table @asis |
| |
| @item @code{-r} |
| |
| 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 @code{-b} mode if @code{-c} |
| 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} |
| so that the final chopped files will correctly refer to the original |
| input source file for @code{gnatprep}. |
| @end table |
| |
| @geindex -s (gnatprep) |
| |
| |
| @table @asis |
| |
| @item @code{-s} |
| |
| Causes a sorted list of symbol names and values to be |
| listed on the standard output file. |
| @end table |
| |
| @geindex -T (gnatprep) |
| |
| |
| @table @asis |
| |
| @item @code{-T} |
| |
| Use LF as line terminators when writing files. By default the line terminator |
| of the host (LF under unix, CR/LF under Windows) is used. |
| @end table |
| |
| @geindex -u (gnatprep) |
| |
| |
| @table @asis |
| |
| @item @code{-u} |
| |
| 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 |
| |
| @geindex -v (gnatprep) |
| |
| |
| @table @asis |
| |
| @item @code{-v} |
| |
| Verbose mode: generates more output about work done. |
| @end table |
| |
| Note: if neither @code{-b} nor @code{-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. |
| |
| @node Form of Definitions File,Form of Input Text for gnatprep,Switches for gnatprep,Preprocessing with gnatprep |
| @anchor{gnat_ugn/the_gnat_compilation_model form-of-definitions-file}@anchor{98}@anchor{gnat_ugn/the_gnat_compilation_model id58}@anchor{99} |
| @subsubsection Form of Definitions File |
| |
| |
| The definitions file contains lines of the form: |
| |
| @example |
| symbol := value |
| @end example |
| |
| where @code{symbol} is a preprocessing symbol, and @code{value} is one of the following: |
| |
| |
| @itemize * |
| |
| @item |
| Empty, corresponding to a null substitution, |
| |
| @item |
| A string literal using normal Ada syntax, or |
| |
| @item |
| Any sequence of characters from the set @{letters, digits, period, underline@}. |
| @end itemize |
| |
| 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,,Form of Definitions File,Preprocessing with gnatprep |
| @anchor{gnat_ugn/the_gnat_compilation_model form-of-input-text-for-gnatprep}@anchor{9a}@anchor{gnat_ugn/the_gnat_compilation_model id59}@anchor{9b} |
| @subsubsection Form of Input Text for @code{gnatprep} |
| |
| |
| The input text may contain preprocessor conditional inclusion lines, |
| as well as general symbol substitution sequences. |
| |
| The preprocessor conditional inclusion commands have the form: |
| |
| @example |
| #if <expression> [then] |
| lines |
| #elsif <expression> [then] |
| lines |
| #elsif <expression> [then] |
| lines |
| ... |
| #else |
| lines |
| #end if; |
| @end example |
| |
| In this example, <expression> is defined by the following grammar: |
| |
| @example |
| <expression> ::= <symbol> |
| <expression> ::= <symbol> = "<value>" |
| <expression> ::= <symbol> = <symbol> |
| <expression> ::= <symbol> = <integer> |
| <expression> ::= <symbol> > <integer> |
| <expression> ::= <symbol> >= <integer> |
| <expression> ::= <symbol> < <integer> |
| <expression> ::= <symbol> <= <integer> |
| <expression> ::= <symbol> 'Defined |
| <expression> ::= not <expression> |
| <expression> ::= <expression> and <expression> |
| <expression> ::= <expression> or <expression> |
| <expression> ::= <expression> and then <expression> |
| <expression> ::= <expression> or else <expression> |
| <expression> ::= ( <expression> ) |
| @end example |
| |
| Note the following restriction: it is not allowed to have “and” or “or” |
| following “not” in the same expression without parentheses. For example, this |
| is not allowed: |
| |
| @example |
| not X or Y |
| @end example |
| |
| This can be expressed instead as one of the following forms: |
| |
| @example |
| (not X) or Y |
| not (X or Y) |
| @end example |
| |
| For the first test (<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. |
| |
| When comparing a symbol to an integer, the integer is any non negative |
| literal integer as defined in the Ada Reference Manual, such as 3, 16#FF# or |
| 2#11#. The symbol value must also be a non negative integer. Integer values |
| in the range 0 .. 2**31-1 are supported. |
| |
| The test (<expression> ::= <symbol>’Defined) is true only if |
| the symbol has been defined in the definition file or by a @code{-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 @code{-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: |
| |
| @example |
| $symbol |
| @end example |
| |
| 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: |
| |
| @example |
| Header : String := "$XYZ"; |
| @end example |
| |
| you should set XYZ to @code{"hello"} and write: |
| |
| @example |
| Header : String := $XYZ; |
| @end example |
| |
| and then the substitution will occur as desired. |
| |
| @node Integrated Preprocessing,,Preprocessing with gnatprep,Conditional Compilation |
| @anchor{gnat_ugn/the_gnat_compilation_model id60}@anchor{9c}@anchor{gnat_ugn/the_gnat_compilation_model integrated-preprocessing}@anchor{90} |
| @subsection Integrated Preprocessing |
| |
| |
| As noted above, a file to be preprocessed consists of Ada source code |
| in which preprocessing lines have been inserted. However, |
| instead of using @code{gnatprep} to explicitly preprocess a file as a separate |
| step before compilation, you can carry out the preprocessing implicitly |
| as part of compilation. Such @emph{integrated preprocessing}, which is the common |
| style with C, is performed when either or both of the following switches |
| are passed to the compiler: |
| |
| @quotation |
| |
| |
| @itemize * |
| |
| @item |
| @code{-gnatep}, which specifies the @emph{preprocessor data file}. |
| This file dictates how the source files will be preprocessed (e.g., which |
| symbol definition files apply to which sources). |
| |
| @item |
| @code{-gnateD}, which defines values for preprocessing symbols. |
| @end itemize |
| @end quotation |
| |
| Integrated preprocessing applies only to Ada source files, it is |
| not available for configuration pragma files. |
| |
| With integrated preprocessing, the output from the preprocessor is not, |
| by default, written to any external file. Instead it is passed |
| internally to the compiler. To preserve the result of |
| preprocessing in a file, either run @code{gnatprep} |
| in standalone mode or else supply the @code{-gnateG} switch |
| (described below) to the compiler. |
| |
| When using project files: |
| |
| @quotation |
| |
| |
| @itemize * |
| |
| @item |
| the builder switch @code{-x} should be used if any Ada source is |
| compiled with @code{gnatep=}, so that the compiler finds the |
| @emph{preprocessor data file}. |
| |
| @item |
| the preprocessing data file and the symbol definition files should be |
| located in the source directories of the project. |
| @end itemize |
| @end quotation |
| |
| Note that the @code{gnatmake} switch @code{-m} will almost |
| always trigger recompilation for sources that are preprocessed, |
| because @code{gnatmake} cannot compute the checksum of the source after |
| preprocessing. |
| |
| The actual preprocessing function is described in detail in |
| @ref{8f,,Preprocessing with gnatprep}. This section explains the switches |
| that relate to integrated preprocessing. |
| |
| @geindex -gnatep (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatep=@emph{preprocessor_data_file}} |
| |
| This switch specifies the file name (without directory |
| information) of the preprocessor data file. Either place this file |
| in one of the source directories, or, when using project |
| files, reference the project file’s directory via the |
| @code{project_name'Project_Dir} project attribute; e.g: |
| |
| @quotation |
| |
| @example |
| project Prj is |
| package Compiler is |
| for Switches ("Ada") use |
| ("-gnatep=" & Prj'Project_Dir & "prep.def"); |
| end Compiler; |
| end Prj; |
| @end example |
| @end quotation |
| |
| A preprocessor data file is a text file that contains @emph{preprocessor |
| control lines}. A preprocessor control line directs the preprocessing of |
| either a particular source file, or, analogous to @code{others} in Ada, |
| all sources not specified elsewhere in the preprocessor data file. |
| A preprocessor control line |
| can optionally identify a @emph{definition file} that assigns values to |
| preprocessor symbols, as well as a list of switches that relate to |
| preprocessing. |
| Empty lines and comments (using Ada syntax) are also permitted, with no |
| semantic effect. |
| |
| Here’s an example of a preprocessor data file: |
| |
| @quotation |
| |
| @example |
| "toto.adb" "prep.def" -u |
| -- Preprocess toto.adb, using definition file prep.def |
| -- Undefined symbols are treated as False |
| |
| * -c -DVERSION=V101 |
| -- Preprocess all other sources without using a definition file |
| -- Suppressed lined are commented |
| -- Symbol VERSION has the value V101 |
| |
| "tata.adb" "prep2.def" -s |
| -- Preprocess tata.adb, using definition file prep2.def |
| -- List all symbols with their values |
| @end example |
| @end quotation |
| |
| A preprocessor control line has the following syntax: |
| |
| @quotation |
| |
| @example |
| <preprocessor_control_line> ::= |
| <preprocessor_input> [ <definition_file_name> ] @{ <switch> @} |
| |
| <preprocessor_input> ::= <source_file_name> | '*' |
| |
| <definition_file_name> ::= <string_literal> |
| |
| <source_file_name> := <string_literal> |
| |
| <switch> := (See below for list) |
| @end example |
| @end quotation |
| |
| Thus each preprocessor control line starts with either a literal string or |
| the character ‘*’: |
| |
| |
| @itemize * |
| |
| @item |
| A literal string is the file name (without directory information) of the source |
| file that will be input to the preprocessor. |
| |
| @item |
| The character ‘*’ is a wild-card indicator; the additional parameters on the line |
| indicate the preprocessing for all the sources |
| that are not specified explicitly on other lines (the order of the lines is not |
| significant). |
| @end itemize |
| |
| It is an error to have two lines with the same file name or two |
| lines starting with the character ‘*’. |
| |
| After the file name or ‘*’, an optional literal string specifies the name of |
| the definition file to be used for preprocessing |
| (@ref{98,,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 the @code{-I} switch; otherwise |
| the compiler would not find the definition file. |
| |
| Finally, switches similar to those of @code{gnatprep} may optionally appear: |
| |
| |
| @table @asis |
| |
| @item @code{-b} |
| |
| Causes both preprocessor lines and the lines deleted by |
| preprocessing to be replaced by blank lines, preserving the line number. |
| This switch is always implied; however, if specified after @code{-c} |
| it cancels the effect of @code{-c}. |
| |
| @item @code{-c} |
| |
| Causes both preprocessor lines and the lines deleted |
| by preprocessing to be retained as comments marked |
| with the special string ‘@cite{–!}’. |
| |
| @item @code{-D@emph{symbol}=@emph{new_value}} |
| |
| Define or redefine @code{symbol} to have @code{new_value} as its value. |
| The permitted form for @code{symbol} is either an Ada identifier, or any Ada reserved word |
| aside from @code{if}, |
| @code{else}, @code{elsif}, @code{end}, @code{and}, @code{or} and @code{then}. |
| The permitted form for @code{new_value} is a literal string, an Ada identifier or any Ada reserved |
| word. A symbol declared with this switch replaces a symbol with the |
| same name defined in a definition file. |
| |
| @item @code{-s} |
| |
| Causes a sorted list of symbol names and values to be |
| listed on the standard output file. |
| |
| @item @code{-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 |
| @end table |
| |
| @geindex -gnateD (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnateD@emph{symbol}[=@emph{new_value}]} |
| |
| Define or redefine @code{symbol} to have @code{new_value} as its value. If no value |
| is supplied, then the value of @code{symbol} is @code{True}. |
| The form of @code{symbol} is an identifier, following normal Ada (case-insensitive) |
| rules for its syntax, and @code{new_value} is either an arbitrary string between double |
| quotes or 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}. |
| |
| Examples: |
| |
| @quotation |
| |
| @example |
| -gnateDToto=Tata |
| -gnateDFoo |
| -gnateDFoo=\"Foo-Bar\" |
| @end example |
| @end quotation |
| |
| A symbol declared with this switch on the command line replaces a |
| symbol with the same name either in a definition file or specified with a |
| switch @code{-D} in the preprocessor data file. |
| |
| This switch is similar to switch @code{-D} of @code{gnatprep}. |
| |
| @item @code{-gnateG} |
| |
| When integrated preprocessing is performed on source file @code{filename.extension}, |
| create or overwrite @code{filename.extension.prep} to contain |
| the result of the preprocessing. |
| For example if the source file is @code{foo.adb} then |
| the output file will be @code{foo.adb.prep}. |
| @end table |
| |
| @node Mixed Language Programming,GNAT and Other Compilation Models,Conditional Compilation,The GNAT Compilation Model |
| @anchor{gnat_ugn/the_gnat_compilation_model id61}@anchor{9d}@anchor{gnat_ugn/the_gnat_compilation_model mixed-language-programming}@anchor{2c} |
| @section Mixed Language Programming |
| |
| |
| @geindex Mixed Language Programming |
| |
| This section describes how to develop a mixed-language program, |
| with a focus on combining Ada with C or C++. |
| |
| @menu |
| * Interfacing to C:: |
| * Calling Conventions:: |
| * Building Mixed Ada and C++ Programs:: |
| * Generating Ada Bindings for C and C++ headers:: |
| * Generating C Headers for Ada Specifications:: |
| |
| @end menu |
| |
| @node Interfacing to C,Calling Conventions,,Mixed Language Programming |
| @anchor{gnat_ugn/the_gnat_compilation_model id62}@anchor{9e}@anchor{gnat_ugn/the_gnat_compilation_model interfacing-to-c}@anchor{9f} |
| @subsection Interfacing to C |
| |
| |
| 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: |
| |
| @example |
| /* file1.c */ |
| #include <stdio.h> |
| |
| void print_num (int num) |
| @{ |
| printf ("num is %d.\\n", num); |
| return; |
| @} |
| @end example |
| |
| @example |
| /* 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 example |
| |
| @example |
| -- 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 example |
| |
| To build this example: |
| |
| |
| @itemize * |
| |
| @item |
| First compile the foreign language files to |
| generate object files: |
| |
| @example |
| $ gcc -c file1.c |
| $ gcc -c file2.c |
| @end example |
| |
| @item |
| Then, compile the Ada units to produce a set of object files and ALI |
| files: |
| |
| @example |
| $ gnatmake -c my_main.adb |
| @end example |
| |
| @item |
| Run the Ada binder on the Ada main program: |
| |
| @example |
| $ gnatbind my_main.ali |
| @end example |
| |
| @item |
| Link the Ada main program, the Ada objects and the other language |
| objects: |
| |
| @example |
| $ gnatlink my_main.ali file1.o file2.o |
| @end example |
| @end itemize |
| |
| The last three steps can be grouped in a single command: |
| |
| @example |
| $ gnatmake my_main.adb -largs file1.o file2.o |
| @end example |
| |
| @geindex Binder output file |
| |
| 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 (@ref{a0,,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 |
| @code{b~xxx.adb} file where they can be accessed by your C |
| sources. To illustrate, we have the following example: |
| |
| @example |
| /* 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 example |
| |
| @example |
| -- unit1.ads |
| package Unit1 is |
| function Add (A, B : Integer) return Integer; |
| pragma Export (C, Add, "add"); |
| end Unit1; |
| @end example |
| |
| @example |
| -- unit1.adb |
| package body Unit1 is |
| function Add (A, B : Integer) return Integer is |
| begin |
| return A + B; |
| end Add; |
| end Unit1; |
| @end example |
| |
| @example |
| -- unit2.ads |
| package Unit2 is |
| function Sub (A, B : Integer) return Integer; |
| pragma Export (C, Sub, "sub"); |
| end Unit2; |
| @end example |
| |
| @example |
| -- unit2.adb |
| package body Unit2 is |
| function Sub (A, B : Integer) return Integer is |
| begin |
| return A - B; |
| end Sub; |
| end Unit2; |
| @end example |
| |
| The build procedure for this application is similar to the last |
| example’s: |
| |
| |
| @itemize * |
| |
| @item |
| First, compile the foreign language files to generate object files: |
| |
| @example |
| $ gcc -c main.c |
| @end example |
| |
| @item |
| Next, compile the Ada units to produce a set of object files and ALI |
| files: |
| |
| @example |
| $ gnatmake -c unit1.adb |
| $ gnatmake -c unit2.adb |
| @end example |
| |
| @item |
| Run the Ada binder on every generated ALI file. Make sure to use the |
| @code{-n} option to specify a foreign main program: |
| |
| @example |
| $ gnatbind -n unit1.ali unit2.ali |
| @end example |
| |
| @item |
| Link the Ada main program, the Ada objects and the foreign language |
| objects. You need only list the last ALI file here: |
| |
| @example |
| $ gnatlink unit2.ali main.o -o exec_file |
| @end example |
| |
| This procedure yields a binary executable called @code{exec_file}. |
| @end itemize |
| |
| 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 |
| @code{-nostartfiles} switch to @code{gnatlink}. |
| |
| @node Calling Conventions,Building Mixed Ada and C++ Programs,Interfacing to C,Mixed Language Programming |
| @anchor{gnat_ugn/the_gnat_compilation_model calling-conventions}@anchor{a1}@anchor{gnat_ugn/the_gnat_compilation_model id63}@anchor{a2} |
| @subsection Calling Conventions |
| |
| |
| @geindex Foreign Languages |
| |
| @geindex 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: |
| |
| @geindex Interfacing to Ada |
| |
| @geindex Other Ada compilers |
| |
| @geindex Convention Ada |
| |
| |
| @table @asis |
| |
| @item @code{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 laid 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. |
| @end table |
| |
| @geindex Interfacing to Assembly |
| |
| @geindex Convention Assembler |
| |
| |
| @table @asis |
| |
| @item @code{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). |
| @end table |
| |
| @geindex Convention Asm |
| |
| @geindex Asm |
| |
| |
| @table @asis |
| |
| @item @code{Asm} |
| |
| Equivalent to Assembler. |
| |
| @geindex Interfacing to COBOL |
| |
| @geindex Convention COBOL |
| @end table |
| |
| @geindex COBOL |
| |
| |
| @table @asis |
| |
| @item @code{COBOL} |
| |
| Data will be passed according to the conventions described |
| in section B.4 of the Ada Reference Manual. |
| @end table |
| |
| @geindex C |
| |
| @geindex Interfacing to C |
| |
| @geindex Convention C |
| |
| |
| @table @asis |
| |
| @item @code{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: |
| |
| @quotation |
| |
| @geindex C varargs function |
| |
| @geindex Interfacing to C varargs function |
| |
| @geindex varargs function interfaces |
| |
| 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}. |
| |
| 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 quotation |
| @end table |
| |
| @geindex Convention Default |
| |
| @geindex Default |
| |
| |
| @table @asis |
| |
| @item @code{Default} |
| |
| Equivalent to C. |
| @end table |
| |
| @geindex Convention External |
| |
| @geindex External |
| |
| |
| @table @asis |
| |
| @item @code{External} |
| |
| Equivalent to C. |
| @end table |
| |
| @geindex C++ |
| |
| @geindex Interfacing to C++ |
| |
| @geindex Convention C++ |
| |
| |
| @table @asis |
| |
| @item @code{C_Plus_Plus} (or @code{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 table |
| |
| @geindex Fortran |
| |
| @geindex Interfacing to Fortran |
| |
| @geindex Convention Fortran |
| |
| |
| @table @asis |
| |
| @item @code{Fortran} |
| |
| Data will be passed according to the conventions described |
| in section B.5 of the Ada Reference Manual. |
| |
| @item @code{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 * |
| |
| @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: |
| @end itemize |
| |
| @example |
| 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, "/"); |
| |
| This common idiom is often programmed with a generic definition and an |
| explicit body. The pragma makes it simpler to introduce such declarations. |
| It incurs no overhead in compilation time or code size, because it is |
| implemented as a single machine instruction. |
| @end example |
| |
| |
| @itemize * |
| |
| @item |
| General subprogram entities. This is used 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 @code{__builtin} functions |
| exposed by the GCC back-end, as in the following example: |
| |
| @example |
| function builtin_sqrt (F : Float) return Float; |
| pragma Import (Intrinsic, builtin_sqrt, "__builtin_sqrtf"); |
| @end example |
| |
| 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 |
| @end table |
| |
| @geindex Stdcall |
| |
| @geindex Convention Stdcall |
| |
| |
| @table @asis |
| |
| @item @code{Stdcall} |
| |
| This is relevant only to Windows 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. |
| @end table |
| |
| @geindex DLL |
| |
| @geindex Convention DLL |
| |
| |
| @table @asis |
| |
| @item @code{DLL} |
| |
| This is equivalent to @code{Stdcall}. |
| @end table |
| |
| @geindex Win32 |
| |
| @geindex Convention Win32 |
| |
| |
| @table @asis |
| |
| @item @code{Win32} |
| |
| This is equivalent to @code{Stdcall}. |
| @end table |
| |
| @geindex Stubbed |
| |
| @geindex Convention Stubbed |
| |
| |
| @table @asis |
| |
| @item @code{Stubbed} |
| |
| This is a special convention that indicates that the compiler |
| should provide a stub body that raises @code{Program_Error}. |
| @end table |
| |
| 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: |
| |
| @example |
| pragma Convention_Identifier (Fortran77, Fortran); |
| @end example |
| |
| 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. |
| |
| @node Building Mixed Ada and C++ Programs,Generating Ada Bindings for C and C++ headers,Calling Conventions,Mixed Language Programming |
| @anchor{gnat_ugn/the_gnat_compilation_model building-mixed-ada-and-c-programs}@anchor{a3}@anchor{gnat_ugn/the_gnat_compilation_model id64}@anchor{a4} |
| @subsection Building Mixed Ada and C++ Programs |
| |
| |
| 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. |
| |
| @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++,Linking a Mixed C++ & Ada Program,,Building Mixed Ada and C++ Programs |
| @anchor{gnat_ugn/the_gnat_compilation_model id65}@anchor{a5}@anchor{gnat_ugn/the_gnat_compilation_model id66}@anchor{a6} |
| @subsubsection Interfacing to C++ |
| |
| |
| GNAT supports interfacing with the G++ compiler (or any C++ compiler |
| generating code that is compatible with the G++ Application Binary |
| Interface —see @indicateurl{http://www.codesourcery.com/archives/cxx-abi}). |
| |
| 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{a7,,Generating Ada Bindings for C and C++ headers}). |
| This problem can also be addressed manually in two ways: |
| |
| |
| @itemize * |
| |
| @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. @code{nm}) and using it as the |
| Link_Name argument of the pragma import. |
| @end itemize |
| |
| Interfacing at the class level can be achieved by using the GNAT specific |
| pragmas such as @code{CPP_Constructor}. See the @cite{GNAT_Reference_Manual} for additional information. |
| |
| @node Linking a Mixed C++ & Ada Program,A Simple Example,Interfacing to C++,Building Mixed Ada and C++ Programs |
| @anchor{gnat_ugn/the_gnat_compilation_model linking-a-mixed-c-ada-program}@anchor{a8}@anchor{gnat_ugn/the_gnat_compilation_model linking-a-mixed-c-and-ada-program}@anchor{a9} |
| @subsubsection Linking a Mixed C++ & Ada Program |
| |
| |
| 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: |
| |
| |
| @itemize * |
| |
| @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. |
| |
| @example |
| $ 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 example |
| |
| @item |
| Using GNAT and G++ from two different GCC installations: If both |
| compilers are on the :envvar`PATH`, the previous method may be used. It is |
| important to note that environment variables such as |
| @geindex C_INCLUDE_PATH |
| @geindex environment variable; C_INCLUDE_PATH |
| @code{C_INCLUDE_PATH}, |
| @geindex GCC_EXEC_PREFIX |
| @geindex environment variable; GCC_EXEC_PREFIX |
| @code{GCC_EXEC_PREFIX}, |
| @geindex BINUTILS_ROOT |
| @geindex environment variable; BINUTILS_ROOT |
| @code{BINUTILS_ROOT}, and |
| @geindex GCC_ROOT |
| @geindex environment variable; GCC_ROOT |
| @code{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 @code{libgcc.a} GCC |
| library – that is, the one from the C++ compiler installation. The |
| implicit link command as suggested in the @code{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: |
| |
| @example |
| $ gnatbind ada_unit |
| $ gnatlink -v -v ada_unit file1.o file2.o --LINK=c++ |
| @end example |
| |
| 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: |
| |
| @example |
| $ 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 example |
| |
| @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} / @code{longjmp} exception mechanism is used, only the paths |
| to the @code{libgcc} libraries are required: |
| |
| @example |
| $ 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 example |
| |
| where CC is the name of the non-GNU C++ compiler. |
| |
| If the “zero cost” exception mechanism is used, and the platform |
| supports automatic registration of exception tables (e.g., Solaris), |
| paths to more objects are required: |
| |
| @example |
| $ 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 example |
| |
| If the “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 itemize |
| |
| Another alternative is to use the @code{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,Interfacing with C++ constructors,Linking a Mixed C++ & Ada Program,Building Mixed Ada and C++ Programs |
| @anchor{gnat_ugn/the_gnat_compilation_model a-simple-example}@anchor{aa}@anchor{gnat_ugn/the_gnat_compilation_model id67}@anchor{ab} |
| @subsubsection A Simple Example |
| |
| |
| 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. |
| |
| Here are the compilation commands: |
| |
| @example |
| $ 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 example |
| |
| Here are the corresponding sources: |
| |
| @example |
| //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 (); |
| @} |
| @end example |
| |
| @example |
| //ex7.h |
| |
| class Origin @{ |
| public: |
| int o_value; |
| @}; |
| class A : public Origin @{ |
| public: |
| void method1 (void); |
| void method2 (int v); |
| A(); |
| int a_value; |
| @}; |
| @end example |
| |
| @example |
| //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 example |
| |
| @example |
| -- simple_cpp_interface.ads |
| 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 example |
| |
| @example |
| -- simple_cpp_interface.adb |
| 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; |
| @end example |
| |
| @node Interfacing with C++ constructors,Interfacing with C++ at the Class Level,A Simple Example,Building Mixed Ada and C++ Programs |
| @anchor{gnat_ugn/the_gnat_compilation_model id68}@anchor{ac}@anchor{gnat_ugn/the_gnat_compilation_model interfacing-with-c-constructors}@anchor{ad} |
| @subsubsection Interfacing with C++ constructors |
| |
| |
| In order to interface with C++ constructors GNAT provides the |
| @code{pragma CPP_Constructor} (see the @cite{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: |
| |
| @example |
| class Root @{ |
| public: |
| int a_value; |
| int b_value; |
| virtual int Get_Value (); |
| Root(); // Default constructor |
| Root(int v); // 1st non-default constructor |
| Root(int v, int w); // 2nd non-default constructor |
| @}; |
| @end example |
| |
| For this purpose we can write the following package spec (further |
| information on how to build this spec is available in |
| @ref{ae,,Interfacing with C++ at the Class Level} and |
| @ref{a7,,Generating Ada Bindings for C and C++ headers}). |
| |
| @example |
| 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 example |
| |
| 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 * |
| |
| @item |
| On the right side of an initialization of an object of type @code{T}. |
| |
| @item |
| On the right side of an initialization of a record component of type @code{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 |
| |
| 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: |
| |
| @example |
| Obj1 : Root; |
| Obj2 : Root := Constructor; |
| Obj3 : Root := Constructor (v => 10); |
| Obj4 : Root := Constructor (30, 40); |
| @end example |
| |
| 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: |
| |
| @example |
| type DT is new Root with record |
| C_Value : Natural := 2009; |
| end record; |
| @end example |
| |
| 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. |
| |
| @example |
| Obj5 : DT; |
| Obj6 : DT := Function_Returning_DT (50); |
| Obj7 : DT := (Constructor (30,40) with C_Value => 50); |
| @end example |
| |
| 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: |
| |
| @example |
| 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 example |
| |
| The initialization of an object of type @code{Rec2} will call the |
| non-default C++ constructors specified for the imported components. |
| For example: |
| |
| @example |
| Obj8 : Rec2 (40); |
| @end example |
| |
| 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: |
| |
| @example |
| Obj9 : Rec2 := (Rec => (Data1 => Constructor (15, 16), |
| others => <>), |
| others => <>); |
| @end example |
| |
| 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: |
| |
| @example |
| 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 example |
| |
| 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,,Interfacing with C++ constructors,Building Mixed Ada and C++ Programs |
| @anchor{gnat_ugn/the_gnat_compilation_model id69}@anchor{af}@anchor{gnat_ugn/the_gnat_compilation_model interfacing-with-c-at-the-class-level}@anchor{ae} |
| @subsubsection Interfacing with C++ at the Class Level |
| |
| |
| 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), a constructor, |
| and two public primitives to set and get the value of this attribute. |
| |
| @example |
| class Animal @{ |
| public: |
| virtual void Set_Age (int New_Age); |
| virtual int Age (); |
| Animal() @{Age_Count = 0;@}; |
| private: |
| int Age_Count; |
| @}; |
| @end example |
| |
| 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: |
| |
| @example |
| class Carnivore @{ |
| public: |
| virtual int Number_Of_Teeth () = 0; |
| @}; |
| |
| class Domestic @{ |
| public: |
| virtual void Set_Owner (char* Name) = 0; |
| @}; |
| @end example |
| |
| Using these declarations, we can now say that a @code{Dog} is an animal that is |
| both Carnivore and Domestic, that is: |
| |
| @example |
| class Dog : Animal, Carnivore, Domestic @{ |
| public: |
| virtual int Number_Of_Teeth (); |
| virtual void Set_Owner (char* Name); |
| |
| Dog(); // Constructor |
| private: |
| int Tooth_Count; |
| char *Owner; |
| @}; |
| @end example |
| |
| 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: |
| |
| @example |
| with Interfaces.C.Strings; use Interfaces.C.Strings; |
| package Animals is |
| type Carnivore is limited interface; |
| pragma Convention (C_Plus_Plus, Carnivore); |
| function Number_Of_Teeth (X : Carnivore) |
| return Natural is abstract; |
| |
| type Domestic is limited interface; |
| pragma Convention (C_Plus_Plus, Domestic); |
| procedure Set_Owner |
| (X : in out Domestic; |
| Name : Chars_Ptr) is abstract; |
| |
| type Animal is tagged limited record |
| Age : Natural; |
| 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); |
| |
| function New_Animal return Animal; |
| pragma CPP_Constructor (New_Animal); |
| pragma Import (CPP, New_Animal, "_ZN6AnimalC1Ev"); |
| |
| type Dog is new Animal and Carnivore and Domestic with record |
| Tooth_Count : Natural; |
| Owner : Chars_Ptr; |
| end record; |
| pragma Import (C_Plus_Plus, Dog); |
| |
| function Number_Of_Teeth (A : Dog) return Natural; |
| 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 example |
| |
| 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. |
| |
| @example |
| with Animals; use Animals; |
| package Vaccinated_Animals is |
| type Vaccinated_Dog is new Dog with null record; |
| function Vaccination_Expired (A : Vaccinated_Dog) return Boolean; |
| end Vaccinated_Animals; |
| @end example |
| |
| 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: |
| |
| @example |
| with Interfaces.C.Strings; |
| use Interfaces.C.Strings; |
| package Animals is |
| type Carnivore is limited interface; |
| pragma Convention (C_Plus_Plus, Carnivore); |
| function Number_Of_Teeth (X : Carnivore) |
| return Natural is abstract; |
| |
| type Domestic is limited interface; |
| pragma Convention (C_Plus_Plus, Domestic); |
| procedure Set_Owner |
| (X : in out Domestic; |
| Name : Chars_Ptr) is abstract; |
| |
| type Animal is tagged record |
| Age : Natural; |
| 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); |
| |
| function New_Animal return Animal'Class; |
| pragma Export (C_Plus_Plus, New_Animal); |
| |
| 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 Natural; |
| 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 example |
| |
| Compared with our previous example the only differences are the use of |
| @code{pragma Convention} (instead of @code{pragma Import}), and 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: |
| |
| @example |
| #include "animals.h" |
| #include <iostream> |
| using namespace std; |
| |
| void Check_Carnivore (Carnivore *obj) @{...@} |
| void Check_Domestic (Domestic *obj) @{...@} |
| void Check_Animal (Animal *obj) @{...@} |
| void Check_Dog (Dog *obj) @{...@} |
| |
| 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 example |
| |
| @node Generating Ada Bindings for C and C++ headers,Generating C Headers for Ada Specifications,Building Mixed Ada and C++ Programs,Mixed Language Programming |
| @anchor{gnat_ugn/the_gnat_compilation_model generating-ada-bindings-for-c-and-c-headers}@anchor{a7}@anchor{gnat_ugn/the_gnat_compilation_model id70}@anchor{b0} |
| @subsection Generating Ada Bindings for C and C++ headers |
| |
| |
| @geindex Binding generation (for C and C++ headers) |
| |
| @geindex C headers (binding generation) |
| |
| @geindex C++ headers (binding generation) |
| |
| GNAT includes 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 * |
| |
| @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 are mapped to System.Address |
| |
| @item |
| identifiers with identical name (except casing) may generate compilation |
| errors (e.g. @code{shm_get} vs @code{SHM_GET}). |
| @end itemize |
| |
| The code is generated using Ada 2012 syntax, which makes it easier to interface |
| with other languages. In most cases you can still use the generated binding |
| even if your code is compiled using earlier versions of Ada (e.g. @code{-gnat95}). |
| |
| @menu |
| * Running the Binding Generator:: |
| * Generating Bindings for C++ Headers:: |
| * Switches:: |
| |
| @end menu |
| |
| @node Running the Binding Generator,Generating Bindings for C++ Headers,,Generating Ada Bindings for C and C++ headers |
| @anchor{gnat_ugn/the_gnat_compilation_model id71}@anchor{b1}@anchor{gnat_ugn/the_gnat_compilation_model running-the-binding-generator}@anchor{b2} |
| @subsubsection Running the Binding Generator |
| |
| |
| The binding generator is part of the @code{gcc} compiler and can be |
| invoked via the @code{-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: |
| |
| @example |
| $ gcc -c -fdump-ada-spec -C /usr/include/time.h |
| $ gcc -c *.ads |
| @end example |
| |
| will generate, under GNU/Linux, the following files: @code{time_h.ads}, |
| @code{bits_time_h.ads}, @code{stddef_h.ads}, @code{bits_types_h.ads} which |
| correspond to the files @code{/usr/include/time.h}, |
| @code{/usr/include/bits/time.h}, etc…, and then compile these Ada specs. |
| That is to say, the name of the Ada specs is in keeping with the relative path |
| under @code{/usr/include/} of the header files. This behavior is specific to |
| paths ending with @code{/include/}; in all the other cases, the name of the |
| Ada specs is derived from the simple name of the header files instead. |
| |
| The @code{-C} switch tells @code{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 @code{-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=@emph{unit}}. |
| |
| The simple @code{gcc`}-based command works only for C headers. For C++ headers |
| you need to use either the @code{g++} command or the combination @code{gcc -x c++`}. |
| |
| In some cases, the generated bindings will be more complete or more meaningful |
| when defining some macros, which you can do via the @code{-D} switch. This |
| is for example the case with @code{Xlib.h} under GNU/Linux: |
| |
| @example |
| $ gcc -c -fdump-ada-spec -DXLIB_ILLEGAL_ACCESS -C /usr/include/X11/Xlib.h |
| @end example |
| |
| The above will generate more complete bindings than a straight call without |
| the @code{-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 @code{readline/readline.h}, you need to first |
| include @code{stdio.h}, so you can create a file with the following two |
| lines in e.g. @code{readline1.h}: |
| |
| @example |
| #include <stdio.h> |
| #include <readline/readline.h> |
| @end example |
| |
| and then generate Ada bindings from this file: |
| |
| @example |
| $ gcc -c -fdump-ada-spec readline1.h |
| @end example |
| |
| @node Generating Bindings for C++ Headers,Switches,Running the Binding Generator,Generating Ada Bindings for C and C++ headers |
| @anchor{gnat_ugn/the_gnat_compilation_model generating-bindings-for-c-headers}@anchor{b3}@anchor{gnat_ugn/the_gnat_compilation_model id72}@anchor{b4} |
| @subsubsection Generating Bindings for C++ Headers |
| |
| |
| Generating bindings for C++ headers is done using the same options, always |
| with the @emph{g++} compiler. Note that generating Ada spec from C++ headers is a |
| much more complex job and support for C++ headers is much more limited that |
| support for C headers. As a result, you will need to modify the resulting |
| bindings by hand more extensively when using C++ headers. |
| |
| 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 |
| (see the @emph{Interfacing to C++} section in the @cite{GNAT Reference Manual} |
| for additional information on interfacing to C++). |
| |
| For example, given the following C++ header file: |
| |
| @example |
| 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 example |
| |
| The corresponding Ada code is generated: |
| |
| @example |
| 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 example |
| |
| @node Switches,,Generating Bindings for C++ Headers,Generating Ada Bindings for C and C++ headers |
| @anchor{gnat_ugn/the_gnat_compilation_model switches}@anchor{b5}@anchor{gnat_ugn/the_gnat_compilation_model switches-for-ada-binding-generation}@anchor{b6} |
| @subsubsection Switches |
| |
| |
| @geindex -fdump-ada-spec (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-fdump-ada-spec} |
| |
| Generate Ada spec files for the given header files transitively (including |
| all header files that these headers depend upon). |
| @end table |
| |
| @geindex -fdump-ada-spec-slim (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-fdump-ada-spec-slim} |
| |
| Generate Ada spec files for the header files specified on the command line |
| only. |
| @end table |
| |
| @geindex -fada-spec-parent (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-fada-spec-parent=@emph{unit}} |
| |
| Specifies that all files generated by @code{-fdump-ada-spec} are |
| to be child units of the specified parent unit. |
| @end table |
| |
| @geindex -C (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-C} |
| |
| Extract comments from headers and generate Ada comments in the Ada spec files. |
| @end table |
| |
| @node Generating C Headers for Ada Specifications,,Generating Ada Bindings for C and C++ headers,Mixed Language Programming |
| @anchor{gnat_ugn/the_gnat_compilation_model generating-c-headers-for-ada-specifications}@anchor{b7}@anchor{gnat_ugn/the_gnat_compilation_model id73}@anchor{b8} |
| @subsection Generating C Headers for Ada Specifications |
| |
| |
| @geindex Binding generation (for Ada specs) |
| |
| @geindex C headers (binding generation) |
| |
| GNAT includes a C header generator for Ada specifications which supports |
| Ada types that have a direct mapping to C types. This includes in particular |
| support for: |
| |
| |
| @itemize * |
| |
| @item |
| Scalar types |
| |
| @item |
| Constrained arrays |
| |
| @item |
| Records (untagged) |
| |
| @item |
| Composition of the above types |
| |
| @item |
| Constant declarations |
| |
| @item |
| Object declarations |
| |
| @item |
| Subprogram declarations |
| @end itemize |
| |
| @menu |
| * Running the C Header Generator:: |
| |
| @end menu |
| |
| @node Running the C Header Generator,,,Generating C Headers for Ada Specifications |
| @anchor{gnat_ugn/the_gnat_compilation_model running-the-c-header-generator}@anchor{b9} |
| @subsubsection Running the C Header Generator |
| |
| |
| The C header generator is part of the GNAT compiler and can be invoked via |
| the @code{-gnatceg} combination of switches, which will generate a @code{.h} |
| file corresponding to the given input file (Ada spec or body). Note that |
| only spec files are processed in any case, so giving a spec or a body file |
| as input is equivalent. For example: |
| |
| @example |
| $ gcc -c -gnatceg pack1.ads |
| @end example |
| |
| will generate a self-contained file called @code{pack1.h} including |
| common definitions from the Ada Standard package, followed by the |
| definitions included in @code{pack1.ads}, as well as all the other units |
| withed by this file. |
| |
| For instance, given the following Ada files: |
| |
| @example |
| package Pack2 is |
| type Int is range 1 .. 10; |
| end Pack2; |
| @end example |
| |
| @example |
| with Pack2; |
| |
| package Pack1 is |
| type Rec is record |
| Field1, Field2 : Pack2.Int; |
| end record; |
| |
| Global : Rec := (1, 2); |
| |
| procedure Proc1 (R : Rec); |
| procedure Proc2 (R : in out Rec); |
| end Pack1; |
| @end example |
| |
| The above @code{gcc} command will generate the following @code{pack1.h} file: |
| |
| @example |
| /* Standard definitions skipped */ |
| #ifndef PACK2_ADS |
| #define PACK2_ADS |
| typedef short_short_integer pack2__TintB; |
| typedef pack2__TintB pack2__int; |
| #endif /* PACK2_ADS */ |
| |
| #ifndef PACK1_ADS |
| #define PACK1_ADS |
| typedef struct _pack1__rec @{ |
| pack2__int field1; |
| pack2__int field2; |
| @} pack1__rec; |
| extern pack1__rec pack1__global; |
| extern void pack1__proc1(const pack1__rec r); |
| extern void pack1__proc2(pack1__rec *r); |
| #endif /* PACK1_ADS */ |
| @end example |
| |
| You can then @code{include} @code{pack1.h} from a C source file and use the types, |
| call subprograms, reference objects, and constants. |
| |
| @node GNAT and Other Compilation Models,Using GNAT Files with External Tools,Mixed Language Programming,The GNAT Compilation Model |
| @anchor{gnat_ugn/the_gnat_compilation_model gnat-and-other-compilation-models}@anchor{2d}@anchor{gnat_ugn/the_gnat_compilation_model id74}@anchor{ba} |
| @section GNAT and Other Compilation Models |
| |
| |
| This section compares the GNAT model with the approaches taken in |
| other environments, first the C/C++ model and then the mechanism that |
| has been used in other Ada systems, in particular those traditionally |
| used for Ada 83. |
| |
| @menu |
| * Comparison between GNAT and C/C++ Compilation Models:: |
| * Comparison between GNAT and Conventional Ada Library Models:: |
| |
| @end menu |
| |
| @node Comparison between GNAT and C/C++ Compilation Models,Comparison between GNAT and Conventional Ada Library Models,,GNAT and Other Compilation Models |
| @anchor{gnat_ugn/the_gnat_compilation_model comparison-between-gnat-and-c-c-compilation-models}@anchor{bb}@anchor{gnat_ugn/the_gnat_compilation_model id75}@anchor{bc} |
| @subsection Comparison between GNAT and C/C++ Compilation Models |
| |
| |
| 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 @emph{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. |
| |
| @geindex 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. |
| |
| @node Comparison between GNAT and Conventional Ada Library Models,,Comparison between GNAT and C/C++ Compilation Models,GNAT and Other Compilation Models |
| @anchor{gnat_ugn/the_gnat_compilation_model comparison-between-gnat-and-conventional-ada-library-models}@anchor{bd}@anchor{gnat_ugn/the_gnat_compilation_model id76}@anchor{be} |
| @subsection Comparison between GNAT and Conventional Ada Library Models |
| |
| |
| 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. |
| |
| @geindex 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 * |
| |
| @item |
| When a unit is @emph{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 |
| |
| 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 * |
| |
| @item |
| When a unit is @emph{with}ed, the unit seen by the compiler corresponds |
| to the source version of the unit that is currently accessible to the |
| compiler. |
| |
| @geindex Inlining |
| |
| @item |
| 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 compiled. |
| |
| @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 |
| |
| 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. |
| |
| @node Using GNAT Files with External Tools,,GNAT and Other Compilation Models,The GNAT Compilation Model |
| @anchor{gnat_ugn/the_gnat_compilation_model id77}@anchor{bf}@anchor{gnat_ugn/the_gnat_compilation_model using-gnat-files-with-external-tools}@anchor{2e} |
| @section Using GNAT Files with External Tools |
| |
| |
| This section explains how files that are produced by GNAT may be |
| used with tools designed for other languages. |
| |
| @menu |
| * Using Other Utility Programs with GNAT:: |
| * The External Symbol Naming Scheme of GNAT:: |
| |
| @end menu |
| |
| @node Using Other Utility Programs with GNAT,The External Symbol Naming Scheme of GNAT,,Using GNAT Files with External Tools |
| @anchor{gnat_ugn/the_gnat_compilation_model id78}@anchor{c0}@anchor{gnat_ugn/the_gnat_compilation_model using-other-utility-programs-with-gnat}@anchor{c1} |
| @subsection Using Other Utility Programs with GNAT |
| |
| |
| 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. |
| |
| 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), gdb (the FSF debugger), and utilities such |
| as Purify. |
| |
| @node The External Symbol Naming Scheme of GNAT,,Using Other Utility Programs with GNAT,Using GNAT Files with External Tools |
| @anchor{gnat_ugn/the_gnat_compilation_model id79}@anchor{c2}@anchor{gnat_ugn/the_gnat_compilation_model the-external-symbol-naming-scheme-of-gnat}@anchor{c3} |
| @subsection The External Symbol Naming Scheme of GNAT |
| |
| |
| 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: |
| |
| @example |
| package QRS is |
| MN : Integer; |
| end QRS; |
| @end example |
| |
| @geindex pragma Export |
| |
| The variable @code{MN} has a full expanded Ada name of @code{QRS.MN}, so |
| the corresponding link name is @code{qrs__mn}. |
| Of course if a @code{pragma Export} is used this may be overridden: |
| |
| @example |
| 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 example |
| |
| In this case, the link name for @code{Var1} is whatever link name the |
| C compiler would assign for the C function @code{var1_name}. This typically |
| would be either @code{var1_name} or @code{_var1_name}, depending on operating |
| system conventions, but other possibilities exist. The link name for |
| @code{Var2} is @code{var2_link_name}, and this is not operating system |
| dependent. |
| |
| 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: |
| |
| @example |
| procedure Hello (S : String); |
| @end example |
| |
| the external name of this procedure will be @code{_ada_hello}. |
| |
| @c -- Example: A |withing| unit has a |with| clause, it |withs| a |withed| unit |
| |
| @node Building Executable Programs with GNAT,GNAT Utility Programs,The GNAT Compilation Model,Top |
| @anchor{gnat_ugn/building_executable_programs_with_gnat doc}@anchor{c4}@anchor{gnat_ugn/building_executable_programs_with_gnat building-executable-programs-with-gnat}@anchor{a}@anchor{gnat_ugn/building_executable_programs_with_gnat id1}@anchor{c5} |
| @chapter Building Executable Programs with GNAT |
| |
| |
| This chapter describes first the gnatmake tool |
| (@ref{c6,,Building with gnatmake}), |
| which automatically determines the set of sources |
| needed by an Ada compilation unit and executes the necessary |
| (re)compilations, binding and linking. |
| It also explains how to use each tool individually: the |
| compiler (gcc, see @ref{c7,,Compiling with gcc}), |
| binder (gnatbind, see @ref{c8,,Binding with gnatbind}), |
| and linker (gnatlink, see @ref{c9,,Linking with gnatlink}) |
| to build executable programs. |
| Finally, this chapter provides examples of |
| how to make use of the general GNU make mechanism |
| in a GNAT context (see @ref{70,,Using the GNU make Utility}). |
| |
| |
| @menu |
| * Building with gnatmake:: |
| * Compiling with gcc:: |
| * Compiler Switches:: |
| * Linker Switches:: |
| * Binding with gnatbind:: |
| * Linking with gnatlink:: |
| * Using the GNU make Utility:: |
| |
| @end menu |
| |
| @node Building with gnatmake,Compiling with gcc,,Building Executable Programs with GNAT |
| @anchor{gnat_ugn/building_executable_programs_with_gnat building-with-gnatmake}@anchor{ca}@anchor{gnat_ugn/building_executable_programs_with_gnat the-gnat-make-program-gnatmake}@anchor{c6} |
| @section Building with @code{gnatmake} |
| |
| |
| @geindex gnatmake |
| |
| 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; and |
| |
| @item |
| Test. |
| @end enumerate |
| |
| @geindex Dependency rules (compilation) |
| |
| The third step in particular can be tricky, because not only do the modified |
| files 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. |
| |
| @code{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 |
| @code{gnatmake}. |
| |
| Note that for advanced forms of project structure, we recommend creating |
| a project file as explained in the @emph{GNAT_Project_Manager} chapter in the |
| @emph{GPRbuild User’s Guide}, and using the |
| @code{gprbuild} tool which supports building with project files and works similarly |
| to @code{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 |
| |
| @node Running gnatmake,Switches for gnatmake,,Building with gnatmake |
| @anchor{gnat_ugn/building_executable_programs_with_gnat id2}@anchor{cb}@anchor{gnat_ugn/building_executable_programs_with_gnat running-gnatmake}@anchor{cc} |
| @subsection Running @code{gnatmake} |
| |
| |
| The usual form of the @code{gnatmake} command is |
| |
| @example |
| $ gnatmake [<switches>] <file_name> [<file_names>] [<mode_switches>] |
| @end example |
| |
| The only required argument is one @code{file_name}, which specifies |
| a compilation unit that is a main program. Several @code{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 |
| @code{file_name}, between @code{file_names} or after the last @code{file_name}. |
| If @code{mode_switches} are present, they must always be placed after |
| the last @code{file_name} and all @code{switches}. |
| |
| If you are using standard file extensions (@code{.adb} and |
| @code{.ads}), then the |
| extension may be omitted from the @code{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 @code{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 |
| @code{gnatmake} was invoked and if it is not found, it will be search on |
| the source path of the compiler as described in |
| @ref{73,,Search Paths and the Run-Time Library (RTL)}. |
| |
| All @code{gnatmake} output (except when you specify @code{-M}) is sent to |
| @code{stderr}. The output produced by the |
| @code{-M} switch is sent to @code{stdout}. |
| |
| @node Switches for gnatmake,Mode Switches for gnatmake,Running gnatmake,Building with gnatmake |
| @anchor{gnat_ugn/building_executable_programs_with_gnat id3}@anchor{cd}@anchor{gnat_ugn/building_executable_programs_with_gnat switches-for-gnatmake}@anchor{ce} |
| @subsection Switches for @code{gnatmake} |
| |
| |
| You may specify any of the following switches to @code{gnatmake}: |
| |
| @geindex --version (gnatmake) |
| |
| |
| @table @asis |
| |
| @item @code{--version} |
| |
| Display Copyright and version, then exit disregarding all other options. |
| @end table |
| |
| @geindex --help (gnatmake) |
| |
| |
| @table @asis |
| |
| @item @code{--help} |
| |
| If @code{--version} was not used, display usage, then exit disregarding |
| all other options. |
| @end table |
| |
| @geindex --GCC=compiler_name (gnatmake) |
| |
| |
| @table @asis |
| |
| @item @code{--GCC=@emph{compiler_name}} |
| |
| Program used for compiling. The default is @code{gcc}. You need to use |
| quotes around @code{compiler_name} if @code{compiler_name} contains |
| spaces or other separator characters. |
| As an example @code{--GCC="foo -x -y"} |
| will instruct @code{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 @code{-c} is always inserted after your command name. Thus in the |
| above example the compiler command that will be used by @code{gnatmake} |
| will be @code{foo -c -x -y}. If several @code{--GCC=compiler_name} are |
| used, only the last @code{compiler_name} is taken into account. However, |
| all the additional switches are also taken into account. Thus, |
| @code{--GCC="foo -x -y" --GCC="bar -z -t"} is equivalent to |
| @code{--GCC="bar -x -y -z -t"}. |
| @end table |
| |
| @geindex --GNATBIND=binder_name (gnatmake) |
| |
| |
| @table @asis |
| |
| @item @code{--GNATBIND=@emph{binder_name}} |
| |
| Program used for binding. The default is @code{gnatbind}. You need to |
| use quotes around @code{binder_name} if @code{binder_name} contains spaces |
| or other separator characters. |
| As an example @code{--GNATBIND="bar -x -y"} |
| will instruct @code{gnatmake} to use @code{bar -x -y} as your |
| binder. Binder switches that are normally appended by @code{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. |
| @end table |
| |
| @geindex --GNATLINK=linker_name (gnatmake) |
| |
| |
| @table @asis |
| |
| @item @code{--GNATLINK=@emph{linker_name}} |
| |
| Program used for linking. The default is @code{gnatlink}. You need to |
| use quotes around @code{linker_name} if @code{linker_name} contains spaces |
| or other separator characters. |
| As an example @code{--GNATLINK="lan -x -y"} |
| will instruct @code{gnatmake} to use @code{lan -x -y} as your |
| linker. Linker switches that are normally appended by @code{gnatmake} to |
| @code{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. |
| |
| @item @code{--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 @code{--create-map-file=@emph{mapfile}} |
| |
| When linking an executable, create a map file with the specified name. |
| @end table |
| |
| @geindex --create-missing-dirs (gnatmake) |
| |
| |
| @table @asis |
| |
| @item @code{--create-missing-dirs} |
| |
| When using project files (@code{-P@emph{project}}), automatically create |
| missing object directories, library directories and exec |
| directories. |
| |
| @item @code{--single-compile-per-obj-dir} |
| |
| Disallow simultaneous compilations in the same object directory when |
| project files are used. |
| |
| @item @code{--subdirs=@emph{subdir}} |
| |
| Actual object directory of each project file is the subdirectory subdir of the |
| object directory specified or defaulted in the project file. |
| |
| @item @code{--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 @code{--source-info=@emph{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. @code{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. |
| @end table |
| |
| @geindex -a (gnatmake) |
| |
| |
| @table @asis |
| |
| @item @code{-a} |
| |
| 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, |
| @code{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 @code{-a} is also useful |
| in conjunction with @code{-f} |
| 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} compiles all GNAT |
| internal files with |
| @code{gcc -c -gnatpg} rather than @code{gcc -c}. |
| @end table |
| |
| @geindex -b (gnatmake) |
| |
| |
| @table @asis |
| |
| @item @code{-b} |
| |
| Bind only. Can be combined with @code{-c} to do |
| compilation and binding, but no link. |
| Can be combined with @code{-l} |
| to do binding and linking. When not combined with |
| @code{-c} |
| 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 @code{file_name} |
| may be given without extension, with the source extension or, if no GNAT |
| Project File is specified, with the ALI file extension. |
| @end table |
| |
| @geindex -c (gnatmake) |
| |
| |
| @table @asis |
| |
| @item @code{-c} |
| |
| Compile only. Do not perform binding, except when @code{-b} |
| is also specified. Do not perform linking, except if both |
| @code{-b} and |
| @code{-l} are also specified. |
| If the root unit specified by @code{file_name} is not a main unit, this is the |
| default. Otherwise @code{gnatmake} will attempt binding and linking |
| unless all objects are up to date and the executable is more recent than |
| the objects. |
| @end table |
| |
| @geindex -C (gnatmake) |
| |
| |
| @table @asis |
| |
| @item @code{-C} |
| |
| 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 |
| @code{-P} is used, a mapping file is always used, so |
| @code{-C} is unnecessary; in this case the mapping file |
| is initially populated based on the project file. If |
| @code{-C} is used without |
| @code{-P}, |
| the mapping file is initially empty. Each invocation of the compiler |
| will add any newly accessed sources to the mapping file. |
| @end table |
| |
| @geindex -C= (gnatmake) |
| |
| |
| @table @asis |
| |
| @item @code{-C=@emph{file}} |
| |
| 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`file`) or with multiple compiling processes |
| (-jnnn, when nnn is greater than 1). |
| @end table |
| |
| @geindex -d (gnatmake) |
| |
| |
| @table @asis |
| |
| @item @code{-d} |
| |
| Display progress for each source, up to date or not, as a single line: |
| |
| @example |
| completed x out of y (zz%) |
| @end example |
| |
| 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. |
| @end table |
| |
| @geindex -D (gnatmake) |
| |
| |
| @table @asis |
| |
| @item @code{-D @emph{dir}} |
| |
| Put all object files and ALI file in directory @code{dir}. |
| If the @code{-D} 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. |
| @end table |
| |
| @geindex -eI (gnatmake) |
| |
| |
| @table @asis |
| |
| @item @code{-eI@emph{nnn}} |
| |
| 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 @code{gnatmake} is |
| invoked for several mains. |
| @end table |
| |
| @geindex -eL (gnatmake) |
| |
| @geindex symbolic links |
| |
| |
| @table @asis |
| |
| @item @code{-eL} |
| |
| 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. |
| |
| @geindex 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 table |
| |
| @geindex -eS (gnatmake) |
| |
| |
| @table @asis |
| |
| @item @code{-eS} |
| |
| Output the commands for the compiler, the binder and the linker |
| on standard output, |
| instead of standard error. |
| @end table |
| |
| @geindex -f (gnatmake) |
| |
| |
| @table @asis |
| |
| @item @code{-f} |
| |
| 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 @code{-a} switch is also specified. |
| @end table |
| |
| @geindex -F (gnatmake) |
| |
| |
| @table @asis |
| |
| @item @code{-F} |
| |
| 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), then error lines start with the full path name of the project |
| file, rather than its simple file name. |
| @end table |
| |
| @geindex -g (gnatmake) |
| |
| |
| @table @asis |
| |
| @item @code{-g} |
| |
| Enable debugging. This switch is simply passed to the compiler and to the |
| linker. |
| @end table |
| |
| @geindex -i (gnatmake) |
| |
| |
| @table @asis |
| |
| @item @code{-i} |
| |
| In normal mode, @code{gnatmake} compiles all object files and ALI files |
| into the current directory. If the @code{-i} 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 @code{gnatmake} will automatically |
| maintain and update this organization. If no ALI files are found on the |
| Ada object path (see @ref{73,,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, @code{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. |
| @end table |
| |
| @geindex -j (gnatmake) |
| |
| @geindex Parallel make |
| |
| |
| @table @asis |
| |
| @item @code{-j@emph{n}} |
| |
| Use @code{n} processes to carry out the (re)compilations. On a multiprocessor |
| machine compilations will occur in parallel. If @code{n} is 0, then the |
| maximum number of parallel compilations is the number of core processors |
| on the platform. In the event of compilation errors, messages from various |
| compilations might get interspersed (but @code{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. |
| @end table |
| |
| @geindex -k (gnatmake) |
| |
| |
| @table @asis |
| |
| @item @code{-k} |
| |
| 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 @code{gnatmake} |
| terminates. |
| |
| If @code{gnatmake} is invoked with several @code{file_names} and with this |
| switch, if there are compilation errors when building an executable, |
| @code{gnatmake} will not attempt to build the following executables. |
| @end table |
| |
| @geindex -l (gnatmake) |
| |
| |
| @table @asis |
| |
| @item @code{-l} |
| |
| Link only. Can be combined with @code{-b} to binding |
| and linking. Linking will not be performed if combined with |
| @code{-c} |
| but not with @code{-b}. |
| When not combined with @code{-b} |
| 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 @code{file_name} |
| may be given without extension, with the source extension or, if no GNAT |
| Project File is specified, with the ALI file extension. |
| @end table |
| |
| @geindex -m (gnatmake) |
| |
| |
| @table @asis |
| |
| @item @code{-m} |
| |
| Specify that the minimum necessary amount of recompilations |
| be performed. In this mode @code{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 @code{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 @code{-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. |
| @end table |
| |
| @geindex Dependencies |
| @geindex producing list |
| |
| @geindex -M (gnatmake) |
| |
| |
| @table @asis |
| |
| @item @code{-M} |
| |
| Check if all objects are up to date. If they are, output the object |
| dependences to @code{stdout} in a form that can be directly exploited in |
| a @code{Makefile}. By default, each source file is prefixed with its |
| (relative or absolute) directory name. This name is whatever you |
| specified in the various @code{-aI} |
| and @code{-I} switches. If you use |
| @code{gnatmake -M} @code{-q} |
| (see below), only the source file names, |
| without relative paths, are output. If you just specify the @code{-M} |
| switch, dependencies of the GNAT internal system files are omitted. This |
| is typically what you want. If you also specify |
| the @code{-a} switch, |
| dependencies of the GNAT internal files are also listed. Note that |
| dependencies of the objects in external Ada libraries (see |
| switch @code{-aL@emph{dir}} in the following list) |
| are never reported. |
| @end table |
| |
| @geindex -n (gnatmake) |
| |
| |
| @table @asis |
| |
| @item @code{-n} |
| |
| 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. |
| @end table |
| |
| @geindex -o (gnatmake) |
| |
| |
| @table @asis |
| |
| @item @code{-o @emph{exec_name}} |
| |
| Output executable name. The name of the final executable program will be |
| @code{exec_name}. If the @code{-o} 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 @code{gnatmake} with several |
| @code{file_names}. |
| @end table |
| |
| @geindex -p (gnatmake) |
| |
| |
| @table @asis |
| |
| @item @code{-p} |
| |
| Same as @code{--create-missing-dirs} |
| @end table |
| |
| @geindex -P (gnatmake) |
| |
| |
| @table @asis |
| |
| @item @code{-P@emph{project}} |
| |
| Use project file @code{project}. Only one such switch can be used. |
| @end table |
| |
| @c -- Comment: |
| @c :ref:`gnatmake_and_Project_Files`. |
| |
| @geindex -q (gnatmake) |
| |
| |
| @table @asis |
| |
| @item @code{-q} |
| |
| Quiet. When this flag is not set, the commands carried out by |
| @code{gnatmake} are displayed. |
| @end table |
| |
| @geindex -s (gnatmake) |
| |
| |
| @table @asis |
| |
| @item @code{-s} |
| |
| 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, |
| @code{-O -O2} is different than @code{-O2 -O}, but @code{-g -O} |
| is equivalent to @code{-O -g}. |
| |
| This switch is recommended when Integrated Preprocessing is used. |
| @end table |
| |
| @geindex -u (gnatmake) |
| |
| |
| @table @asis |
| |
| @item @code{-u} |
| |
| 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 with a project file and no main has a special meaning. |
| @end table |
| |
| @c --Comment |
| @c (See :ref:`Project_Files_and_Main_Subprograms`.) |
| |
| @geindex -U (gnatmake) |
| |
| |
| @table @asis |
| |
| @item @code{-U} |
| |
| When used without a project file or with one or several mains on the command |
| line, is equivalent to -u. 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. |
| @end table |
| |
| @geindex -v (gnatmake) |
| |
| |
| @table @asis |
| |
| @item @code{-v} |
| |
| Verbose. Display the reason for all recompilations @code{gnatmake} |
| decides are necessary, with the highest verbosity level. |
| @end table |
| |
| @geindex -vl (gnatmake) |
| |
| |
| @table @asis |
| |
| @item @code{-vl} |
| |
| Verbosity level Low. Display fewer lines than in verbosity Medium. |
| @end table |
| |
| @geindex -vm (gnatmake) |
| |
| |
| @table @asis |
| |
| @item @code{-vm} |
| |
| Verbosity level Medium. Potentially display fewer lines than in verbosity High. |
| @end table |
| |
| @geindex -vm (gnatmake) |
| |
| |
| @table @asis |
| |
| @item @code{-vh} |
| |
| Verbosity level High. Equivalent to -v. |
| |
| @item @code{-vP@emph{x}} |
| |
| Indicate the verbosity of the parsing of GNAT project files. |
| See @ref{cf,,Switches Related to Project Files}. |
| @end table |
| |
| @geindex -x (gnatmake) |
| |
| |
| @table @asis |
| |
| @item @code{-x} |
| |
| 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 |
| @code{-x} is used, mains specified on the |
| command line need to be sources of a project file. |
| |
| @item @code{-X@emph{name}=@emph{value}} |
| |
| Indicate that external variable @code{name} has the value @code{value}. |
| The Project Manager will use this value for occurrences of |
| @code{external(name)} when parsing the project file. |
| @ref{cf,,Switches Related to Project Files}. |
| @end table |
| |
| @geindex -z (gnatmake) |
| |
| |
| @table @asis |
| |
| @item @code{-z} |
| |
| 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 |
| |
| @subsubheading GCC switches |
| |
| |
| Any uppercase or multi-character switch that is not a @code{gnatmake} switch |
| is passed to @code{gcc} (e.g., @code{-O}, @code{-gnato,} etc.) |
| |
| @subsubheading Source and library search path switches |
| |
| |
| @geindex -aI (gnatmake) |
| |
| |
| @table @asis |
| |
| @item @code{-aI@emph{dir}} |
| |
| When looking for source files also look in directory @code{dir}. |
| The order in which source files search is undertaken is |
| described in @ref{73,,Search Paths and the Run-Time Library (RTL)}. |
| @end table |
| |
| @geindex -aL (gnatmake) |
| |
| |
| @table @asis |
| |
| @item @code{-aL@emph{dir}} |
| |
| Consider @code{dir} as being an externally provided Ada library. |
| Instructs @code{gnatmake} to skip compilation units whose @code{.ALI} |
| files have been located in directory @code{dir}. This allows you to have |
| missing bodies for the units in @code{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 |
| @code{-aI@emph{dir}} or @code{-I@emph{dir}}. |
| Note: this switch is provided for compatibility with previous versions |
| of @code{gnatmake}. The easier method of causing standard libraries |
| to be excluded from consideration is to write-protect the corresponding |
| ALI files. |
| @end table |
| |
| @geindex -aO (gnatmake) |
| |
| |
| @table @asis |
| |
| @item @code{-aO@emph{dir}} |
| |
| When searching for library and object files, look in directory |
| @code{dir}. The order in which library files are searched is described in |
| @ref{76,,Search Paths for gnatbind}. |
| @end table |
| |
| @geindex Search paths |
| @geindex for gnatmake |
| |
| @geindex -A (gnatmake) |
| |
| |
| @table @asis |
| |
| @item @code{-A@emph{dir}} |
| |
| Equivalent to @code{-aL@emph{dir}} @code{-aI@emph{dir}}. |
| |
| @geindex -I (gnatmake) |
| |
| @item @code{-I@emph{dir}} |
| |
| Equivalent to @code{-aO@emph{dir} -aI@emph{dir}}. |
| @end table |
| |
| @geindex -I- (gnatmake) |
| |
| @geindex Source files |
| @geindex suppressing search |
| |
| |
| @table @asis |
| |
| @item @code{-I-} |
| |
| 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 @code{gnatmake} was invoked. |
| @end table |
| |
| @geindex -L (gnatmake) |
| |
| @geindex Linker libraries |
| |
| |
| @table @asis |
| |
| @item @code{-L@emph{dir}} |
| |
| Add directory @code{dir} to the list of directories in which the linker |
| will search for libraries. This is equivalent to |
| @code{-largs} @code{-L@emph{dir}}. |
| Furthermore, under Windows, the sources pointed to by the libraries path |
| set in the registry are not searched for. |
| @end table |
| |
| @geindex -nostdinc (gnatmake) |
| |
| |
| @table @asis |
| |
| @item @code{-nostdinc} |
| |
| Do not look for source files in the system default directory. |
| @end table |
| |
| @geindex -nostdlib (gnatmake) |
| |
| |
| @table @asis |
| |
| @item @code{-nostdlib} |
| |
| Do not look for library files in the system default directory. |
| @end table |
| |
| @geindex --RTS (gnatmake) |
| |
| |
| @table @asis |
| |
| @item @code{--RTS=@emph{rts-path}} |
| |
| Specifies the default location of the run-time library. GNAT looks for the |
| run-time |
| in the following directories, and stops as soon as a valid run-time is found |
| (@code{adainclude} or @code{ada_source_path}, and @code{adalib} or |
| @code{ada_object_path} present): |
| |
| |
| @itemize * |
| |
| @item |
| @emph{<current directory>/$rts_path} |
| |
| @item |
| @emph{<default-search-dir>/$rts_path} |
| |
| @item |
| @emph{<default-search-dir>/rts-$rts_path} |
| |
| @item |
| The selected path is handled like a normal RTS path. |
| @end itemize |
| @end table |
| |
| @node Mode Switches for gnatmake,Notes on the Command Line,Switches for gnatmake,Building with gnatmake |
| @anchor{gnat_ugn/building_executable_programs_with_gnat id4}@anchor{d0}@anchor{gnat_ugn/building_executable_programs_with_gnat mode-switches-for-gnatmake}@anchor{d1} |
| @subsection Mode Switches for @code{gnatmake} |
| |
| |
| 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. |
| |
| @geindex -cargs (gnatmake) |
| |
| |
| @table @asis |
| |
| @item @code{-cargs @emph{switches}} |
| |
| Compiler switches. Here @code{switches} is a list of switches |
| that are valid switches for @code{gcc}. They will be passed on to |
| all compile steps performed by @code{gnatmake}. |
| @end table |
| |
| @geindex -bargs (gnatmake) |
| |
| |
| @table @asis |
| |
| @item @code{-bargs @emph{switches}} |
| |
| Binder switches. Here @code{switches} is a list of switches |
| that are valid switches for @code{gnatbind}. They will be passed on to |
| all bind steps performed by @code{gnatmake}. |
| @end table |
| |
| @geindex -largs (gnatmake) |
| |
| |
| @table @asis |
| |
| @item @code{-largs @emph{switches}} |
| |
| Linker switches. Here @code{switches} is a list of switches |
| that are valid switches for @code{gnatlink}. They will be passed on to |
| all link steps performed by @code{gnatmake}. |
| @end table |
| |
| @geindex -margs (gnatmake) |
| |
| |
| @table @asis |
| |
| @item @code{-margs @emph{switches}} |
| |
| Make switches. The switches are directly interpreted by @code{gnatmake}, |
| regardless of any previous occurrence of @code{-cargs}, @code{-bargs} |
| or @code{-largs}. |
| @end table |
| |
| @node Notes on the Command Line,How gnatmake Works,Mode Switches for gnatmake,Building with gnatmake |
| @anchor{gnat_ugn/building_executable_programs_with_gnat id5}@anchor{d2}@anchor{gnat_ugn/building_executable_programs_with_gnat notes-on-the-command-line}@anchor{d3} |
| @subsection Notes on the Command Line |
| |
| |
| This section contains some additional useful notes on the operation |
| of the @code{gnatmake} command. |
| |
| @geindex Recompilation (by gnatmake) |
| |
| |
| @itemize * |
| |
| @item |
| If @code{gnatmake} finds no ALI files, it recompiles the main program |
| and all other units required by the main program. |
| This means that @code{gnatmake} |
| can be used for the initial compile, as well as during subsequent steps of |
| the development cycle. |
| |
| @item |
| If you enter @code{gnatmake foo.adb}, where @code{foo} |
| is a subunit or body of a generic unit, @code{gnatmake} recompiles |
| @code{foo.adb} (because it finds no ALI) and stops, issuing a |
| warning. |
| |
| @item |
| In @code{gnatmake} the switch @code{-I} |
| is used to specify both source and |
| library file paths. Use @code{-aI} |
| instead if you just want to specify |
| source paths only and @code{-aO} |
| if you want to specify library paths |
| only. |
| |
| @item |
| @code{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 |
| @code{-f} switch will not recompile these files |
| unless @code{-a} is also specified. |
| |
| @item |
| @code{gnatmake} has been designed to make the use of Ada libraries |
| particularly convenient. Assume you have an Ada library organized |
| as follows: @emph{obj-dir} contains the objects and ALI files for |
| of your Ada compilation units, |
| whereas @emph{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: |
| |
| @example |
| $ gnatmake -aI`include-dir` -aL`obj-dir` main |
| @end example |
| |
| @item |
| Using @code{gnatmake} along with the @code{-m (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,Examples of gnatmake Usage,Notes on the Command Line,Building with gnatmake |
| @anchor{gnat_ugn/building_executable_programs_with_gnat how-gnatmake-works}@anchor{d4}@anchor{gnat_ugn/building_executable_programs_with_gnat id6}@anchor{d5} |
| @subsection How @code{gnatmake} Works |
| |
| |
| Generally @code{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 @code{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 @emph{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. |
| |
| @code{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, |
| @code{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 @code{gnatmake} recursively applies the above procedure on all these |
| files. |
| |
| This process ensures that @code{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 |
| @code{gnatmake} will recompute a correct set of new dependencies if |
| necessary. |
| |
| When invoking @code{gnatmake} with several @code{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 |
| (@ref{1c,,Using Other File Names}), changing through a configuration pragmas |
| file the version of a source and invoking @code{gnatmake} to recompile may |
| have no effect, if the previous version of the source is still accessible |
| by @code{gnatmake}. It may be necessary to use the switch |
| -f. |
| |
| @node Examples of gnatmake Usage,,How gnatmake Works,Building with gnatmake |
| @anchor{gnat_ugn/building_executable_programs_with_gnat examples-of-gnatmake-usage}@anchor{d6}@anchor{gnat_ugn/building_executable_programs_with_gnat id7}@anchor{d7} |
| @subsection Examples of @code{gnatmake} Usage |
| |
| |
| |
| @table @asis |
| |
| @item @emph{gnatmake hello.adb} |
| |
| Compile all files necessary to bind and link the main program |
| @code{hello.adb} (containing unit @code{Hello}) and bind and link the |
| resulting object files to generate an executable file @code{hello}. |
| |
| @item @emph{gnatmake main1 main2 main3} |
| |
| Compile all files necessary to bind and link the main programs |
| @code{main1.adb} (containing unit @code{Main1}), @code{main2.adb} |
| (containing unit @code{Main2}) and @code{main3.adb} |
| (containing unit @code{Main3}) and bind and link the resulting object files |
| to generate three executable files @code{main1}, |
| @code{main2} and @code{main3}. |
| |
| @item @emph{gnatmake -q Main_Unit -cargs -O2 -bargs -l} |
| |
| Compile all files necessary to bind and link the main program unit |
| @code{Main_Unit} (from file @code{main_unit.adb}). All compilations will |
| be done with optimization level 2 and the order of elaboration will be |
| listed by the binder. @code{gnatmake} will operate in quiet mode, not |
| displaying commands it is executing. |
| @end table |
| |
| @node Compiling with gcc,Compiler Switches,Building with gnatmake,Building Executable Programs with GNAT |
| @anchor{gnat_ugn/building_executable_programs_with_gnat compiling-with-gcc}@anchor{c7}@anchor{gnat_ugn/building_executable_programs_with_gnat id8}@anchor{d8} |
| @section Compiling with @code{gcc} |
| |
| |
| This section discusses how to compile Ada programs using the @code{gcc} |
| command. It also describes the set of switches |
| that can be used to control the behavior of the compiler. |
| |
| @menu |
| * Compiling Programs:: |
| * Search Paths and the Run-Time Library (RTL): Search Paths and the Run-Time Library RTL. |
| * Order of Compilation Issues:: |
| * Examples:: |
| |
| @end menu |
| |
| @node Compiling Programs,Search Paths and the Run-Time Library RTL,,Compiling with gcc |
| @anchor{gnat_ugn/building_executable_programs_with_gnat compiling-programs}@anchor{d9}@anchor{gnat_ugn/building_executable_programs_with_gnat id9}@anchor{da} |
| @subsection Compiling Programs |
| |
| |
| The first step in creating an executable program is to compile the units |
| of the program using the @code{gcc} command. You must compile the |
| following files: |
| |
| |
| @itemize * |
| |
| @item |
| the body file (@code{.adb}) for a library level subprogram or generic |
| subprogram |
| |
| @item |
| the spec file (@code{.ads}) for a library level package or generic |
| package that has no body |
| |
| @item |
| the body file (@code{.adb}) for a library level package |
| or generic package that has a body |
| @end itemize |
| |
| You need @emph{not} compile the following files |
| |
| |
| @itemize * |
| |
| @item |
| the spec of a library unit which has a body |
| |
| @item |
| subunits |
| @end itemize |
| |
| 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. |
| |
| @geindex cannot generate code |
| |
| If you attempt to compile any of these files, you will get one of the |
| following error messages (where @code{fff} is the name of the file you |
| compiled): |
| |
| @quotation |
| |
| @example |
| cannot generate code for file `@w{`}fff`@w{`} (package spec) |
| to check package spec, use -gnatc |
| |
| cannot generate code for file `@w{`}fff`@w{`} (missing subunits) |
| to check parent unit, use -gnatc |
| |
| cannot generate code for file `@w{`}fff`@w{`} (subprogram spec) |
| to check subprogram spec, use -gnatc |
| |
| cannot generate code for file `@w{`}fff`@w{`} (subunit) |
| to check subunit, use -gnatc |
| @end example |
| @end quotation |
| |
| 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 @code{-gnatc} switch. |
| |
| The basic command for compiling a file containing an Ada unit is: |
| |
| @example |
| $ gcc -c [switches] <file name> |
| @end example |
| |
| where @code{file name} is the name of the Ada file (usually |
| having an extension @code{.ads} for a spec or @code{.adb} for a body). |
| You specify the |
| @code{-c} switch to tell @code{gcc} to compile, but not link, the file. |
| The result of a successful compilation is an object file, which has the |
| same name as the source file but an extension of @code{.o} and an Ada |
| Library Information (ALI) file, which also has the same name as the |
| source file, but with @code{.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. |
| |
| TESTING: the @code{--foobar@emph{NN}} switch |
| |
| @geindex gnat1 |
| |
| @code{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 @code{cc1}, and the Ada compiler is @code{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 @code{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 @code{gcc} |
| command. This causes @code{gcc} to call the appropriate compiler for |
| each file. For example, the following command lists two separate |
| files to be compiled: |
| |
| @example |
| $ gcc -c x.adb y.adb |
| @end example |
| |
| calls @code{gnat1} (the Ada compiler) twice to compile @code{x.adb} and |
| @code{y.adb}. |
| The compiler generates two object files @code{x.o} and @code{y.o} |
| and the two ALI files @code{x.ali} and @code{y.ali}. |
| |
| Any switches apply to all the files listed, see @ref{db,,Compiler Switches} for a |
| list of available @code{gcc} switches. |
| |
| @node Search Paths and the Run-Time Library RTL,Order of Compilation Issues,Compiling Programs,Compiling with gcc |
| @anchor{gnat_ugn/building_executable_programs_with_gnat id10}@anchor{dc}@anchor{gnat_ugn/building_executable_programs_with_gnat search-paths-and-the-run-time-library-rtl}@anchor{73} |
| @subsection Search Paths and the Run-Time Library (RTL) |
| |
| |
| 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: |
| |
| |
| @itemize * |
| |
| @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 @code{-I} switch given on the @code{gcc} |
| command line, in the order given. |
| |
| @geindex ADA_PRJ_INCLUDE_FILE |
| |
| @item |
| Each of the directories listed in the text file whose name is given |
| by the |
| @geindex ADA_PRJ_INCLUDE_FILE |
| @geindex environment variable; ADA_PRJ_INCLUDE_FILE |
| @code{ADA_PRJ_INCLUDE_FILE} environment variable. |
| @geindex ADA_PRJ_INCLUDE_FILE |
| @geindex environment variable; ADA_PRJ_INCLUDE_FILE |
| @code{ADA_PRJ_INCLUDE_FILE} is normally set by gnatmake or by the gnat |
| driver when project files are used. It should not normally be set |
| by other means. |
| |
| @geindex ADA_INCLUDE_PATH |
| |
| @item |
| Each of the directories listed in the value of the |
| @geindex ADA_INCLUDE_PATH |
| @geindex environment variable; ADA_INCLUDE_PATH |
| @code{ADA_INCLUDE_PATH} environment variable. |
| Construct this value |
| exactly as the |
| @geindex PATH |
| @geindex environment variable; PATH |
| @code{PATH} environment variable: a list of directory |
| names separated by colons (semicolons when working with the NT version). |
| |
| @item |
| The content of the @code{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. |
| @ref{72,,Installing a library} |
| @end itemize |
| |
| Specifying the switch @code{-I-} |
| 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 @code{-I} switch. |
| |
| Specifying the switch @code{-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. |
| Caution: The object file can be redirected with the @code{-o} switch; |
| however, @code{gcc} and @code{gnat1} have not been coordinated on this |
| so the @code{ALI} file will not go to the right place. Therefore, you should |
| avoid using the @code{-o} switch. |
| |
| @geindex System.IO |
| |
| The packages @code{Ada}, @code{System}, and @code{Interfaces} and their |
| children make up the GNAT RTL, together with the simple @code{System.IO} |
| package used in the @code{"Hello World"} example. The sources for these units |
| are needed by the compiler and are kept together in one directory. Not |
| all of the bodies are needed, but all of the sources are kept together |
| anyway. In a normal installation, you need not specify these directory |
| names when compiling or binding. Either the environment variables or |
| the built-in defaults cause these files to be found. |
| |
| In addition to the language-defined hierarchies (@code{System}, @code{Ada} and |
| @code{Interfaces}), the GNAT distribution provides a fourth hierarchy, |
| consisting of child units of @code{GNAT}. This is a collection of generally |
| useful types, subprograms, etc. See the @cite{GNAT_Reference_Manual} |
| for further details. |
| |
| Besides simplifying access to the RTL, a major use of search paths is |
| in compiling sources from multiple directories. This can make |
| development environments much more flexible. |
| |
| @node Order of Compilation Issues,Examples,Search Paths and the Run-Time Library RTL,Compiling with gcc |
| @anchor{gnat_ugn/building_executable_programs_with_gnat id11}@anchor{dd}@anchor{gnat_ugn/building_executable_programs_with_gnat order-of-compilation-issues}@anchor{de} |
| @subsection Order of Compilation Issues |
| |
| |
| If, in our earlier example, there was a spec for the @code{hello} |
| procedure, it would be contained in the file @code{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 * |
| |
| @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 |
| (@ref{28,,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 @emph{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,,Order of Compilation Issues,Compiling with gcc |
| @anchor{gnat_ugn/building_executable_programs_with_gnat examples}@anchor{df}@anchor{gnat_ugn/building_executable_programs_with_gnat id12}@anchor{e0} |
| @subsection Examples |
| |
| |
| The following are some typical Ada compilation command line examples: |
| |
| @example |
| $ gcc -c xyz.adb |
| @end example |
| |
| Compile body in file @code{xyz.adb} with all default options. |
| |
| @example |
| $ gcc -c -O2 -gnata xyz-def.adb |
| @end example |
| |
| Compile the child unit package in file @code{xyz-def.adb} with extensive |
| optimizations, and pragma @code{Assert}/@cite{Debug} statements |
| enabled. |
| |
| @example |
| $ gcc -c -gnatc abc-def.adb |
| @end example |
| |
| Compile the subunit in file @code{abc-def.adb} in semantic-checking-only |
| mode. |
| |
| @node Compiler Switches,Linker Switches,Compiling with gcc,Building Executable Programs with GNAT |
| @anchor{gnat_ugn/building_executable_programs_with_gnat compiler-switches}@anchor{e1}@anchor{gnat_ugn/building_executable_programs_with_gnat switches-for-gcc}@anchor{db} |
| @section Compiler Switches |
| |
| |
| The @code{gcc} command accepts switches that control the |
| compilation process. These switches are fully described in this section: |
| first an alphabetical listing of all switches with a brief description, |
| and then functionally grouped sets of switches with more detailed |
| information. |
| |
| 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 |
| * Alphabetical List of All Switches:: |
| * 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:: |
| * Code Generation Control:: |
| |
| @end menu |
| |
| @node Alphabetical List of All Switches,Output and Error Message Control,,Compiler Switches |
| @anchor{gnat_ugn/building_executable_programs_with_gnat alphabetical-list-of-all-switches}@anchor{e2}@anchor{gnat_ugn/building_executable_programs_with_gnat id13}@anchor{e3} |
| @subsection Alphabetical List of All Switches |
| |
| |
| @geindex -b (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-b @emph{target}} |
| |
| Compile your program to run on @code{target}, which is the name of a |
| system configuration. You must have a GNAT cross-compiler built if |
| @code{target} is not the same as your host system. |
| @end table |
| |
| @geindex -B (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-B@emph{dir}} |
| |
| Load compiler executables (for example, @code{gnat1}, the Ada compiler) |
| from @code{dir} instead of the default location. Only use this switch |
| when multiple versions of the GNAT compiler are available. |
| See the “Options for Directory Search” section in the |
| @cite{Using the GNU Compiler Collection (GCC)} manual for further details. |
| You would normally use the @code{-b} or @code{-V} switch instead. |
| @end table |
| |
| @geindex -c (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-c} |
| |
| Compile. Always use this switch when compiling Ada programs. |
| |
| Note: for some other languages when using @code{gcc}, notably in |
| the case of C and C++, it is possible to use |
| use @code{gcc} without a @code{-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 @code{gcc} cannot be used to run the GNAT binder. |
| @end table |
| |
| @geindex -fcallgraph-info (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-fcallgraph-info[=su,da]} |
| |
| 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 |
| @code{su} marker is specified, the callgraph is decorated with stack usage |
| information; it is equivalent to @code{-fstack-usage}. When the @code{da} |
| marker is specified, the callgraph is decorated with information about |
| dynamically allocated objects. |
| @end table |
| |
| @geindex -fdiagnostics-format (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-fdiagnostics-format=json} |
| |
| Makes GNAT emit warning and error messages as JSON. Inhibits printing of |
| text warning and errors messages except if @code{-gnatv} or |
| @code{-gnatl} are present. |
| @end table |
| |
| @geindex -fdump-scos (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-fdump-scos} |
| |
| Generates SCO (Source Coverage Obligation) information in the ALI file. |
| This information is used by advanced coverage tools. See unit @code{SCOs} |
| in the compiler sources for details in files @code{scos.ads} and |
| @code{scos.adb}. |
| @end table |
| |
| @geindex -fgnat-encodings (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-fgnat-encodings=[all|gdb|minimal]} |
| |
| This switch controls the balance between GNAT encodings and standard DWARF |
| emitted in the debug information. |
| @end table |
| |
| @geindex -flto (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-flto[=@emph{n}]} |
| |
| Enables Link Time Optimization. This switch must be used in conjunction |
| with the @code{-Ox} switches (but not with the @code{-gnatn} switch |
| since it is a full replacement for the latter) 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 big programs and reduce the |
| size of the executable, compared with a traditional per-unit compilation |
| with inlining across units enabled by the @code{-gnatn} switch. |
| The drawback of this approach is that it may require more memory and that |
| the debugging information generated by -g with it might be hardly usable. |
| The switch, as well as the accompanying @code{-Ox} switches, must be |
| specified both for the compilation and the link phases. |
| If the @code{n} parameter is specified, the optimization and final code |
| generation at link time are executed using @code{n} parallel jobs by |
| means of an installed @code{make} program. |
| @end table |
| |
| @geindex -fno-inline (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-fno-inline} |
| |
| Suppresses all inlining, unless requested with pragma @code{Inline_Always}. The |
| effect is enforced regardless of other optimization or inlining switches. |
| Note that inlining can also be suppressed on a finer-grained basis with |
| pragma @code{No_Inline}. |
| @end table |
| |
| @geindex -fno-inline-functions (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-fno-inline-functions} |
| |
| Suppresses automatic inlining of subprograms, which is enabled |
| if @code{-O3} is used. |
| @end table |
| |
| @geindex -fno-inline-small-functions (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-fno-inline-small-functions} |
| |
| Suppresses automatic inlining of small subprograms, which is enabled |
| if @code{-O2} is used. |
| @end table |
| |
| @geindex -fno-inline-functions-called-once (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-fno-inline-functions-called-once} |
| |
| Suppresses inlining of subprograms local to the unit and called once |
| from within it, which is enabled if @code{-O1} is used. |
| @end table |
| |
| @geindex -fno-ivopts (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-fno-ivopts} |
| |
| Suppresses high-level loop induction variable optimizations, which are |
| enabled if @code{-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. |
| @end table |
| |
| @geindex -fno-strict-aliasing (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-fno-strict-aliasing} |
| |
| Causes the compiler to avoid assumptions regarding non-aliasing |
| of objects of different types. See |
| @ref{e4,,Optimization and Strict Aliasing} for details. |
| @end table |
| |
| @geindex -fno-strict-overflow (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-fno-strict-overflow} |
| |
| Causes the compiler to avoid assumptions regarding the rules of signed |
| integer overflow. These rules specify that signed integer overflow will |
| result in a Constraint_Error exception at run time and are enforced in |
| default mode by the compiler, so this switch should not be necessary in |
| normal operating mode. It might be useful in conjunction with @code{-gnato0} |
| for very peculiar cases of low-level programming. |
| @end table |
| |
| @geindex -fstack-check (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-fstack-check} |
| |
| Activates stack checking. |
| See @ref{e5,,Stack Overflow Checking} for details. |
| @end table |
| |
| @geindex -fstack-usage (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-fstack-usage} |
| |
| Makes the compiler output stack usage information for the program, on a |
| per-subprogram basis. See @ref{e6,,Static Stack Usage Analysis} for details. |
| @end table |
| |
| @geindex -g (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-g} |
| |
| 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 |
| @code{-g} switch if you plan on using the debugger. |
| @end table |
| |
| @geindex -gnat05 (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnat05} |
| |
| Allow full Ada 2005 features. |
| @end table |
| |
| @geindex -gnat12 (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnat12} |
| |
| Allow full Ada 2012 features. |
| @end table |
| |
| @geindex -gnat83 (gcc) |
| |
| @geindex -gnat2005 (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnat2005} |
| |
| Allow full Ada 2005 features (same as @code{-gnat05}) |
| @end table |
| |
| @geindex -gnat2012 (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnat2012} |
| |
| Allow full Ada 2012 features (same as @code{-gnat12}) |
| @end table |
| |
| @geindex -gnat2022 (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnat2022} |
| |
| Allow full Ada 2022 features |
| |
| @item @code{-gnat83} |
| |
| Enforce Ada 83 restrictions. |
| @end table |
| |
| @geindex -gnat95 (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnat95} |
| |
| Enforce Ada 95 restrictions. |
| |
| Note: for compatibility with some Ada 95 compilers which support only |
| the @code{overriding} keyword of Ada 2005, the @code{-gnatd.D} switch can |
| be used along with @code{-gnat95} to achieve a similar effect with GNAT. |
| |
| @code{-gnatd.D} instructs GNAT to consider @code{overriding} as a keyword |
| and handle its associated semantic checks, even in Ada 95 mode. |
| @end table |
| |
| @geindex -gnata (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnata} |
| |
| 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. The default is that all these assertions are disabled, |
| and have no effect, other than being checked for syntactic validity, and |
| in the case of subtype predicates, constructions such as membership tests |
| still test predicates even if assertions are turned off. |
| @end table |
| |
| @geindex -gnatA (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatA} |
| |
| Avoid processing @code{gnat.adc}. If a @code{gnat.adc} file is present, |
| it will be ignored. |
| @end table |
| |
| @geindex -gnatb (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatb} |
| |
| Generate brief messages to @code{stderr} even if verbose mode set. |
| @end table |
| |
| @geindex -gnatB (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatB} |
| |
| Assume no invalid (bad) values except for ‘Valid attribute use |
| (@ref{e7,,Validity Checking}). |
| @end table |
| |
| @geindex -gnatc (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatc} |
| |
| Check syntax and semantics only (no code generation attempted). When the |
| compiler is invoked by @code{gnatmake}, if the switch @code{-gnatc} is |
| only given to the compiler (after @code{-cargs} or in package Compiler of |
| the project file, @code{gnatmake} will fail because it will not find the |
| object file after compilation. If @code{gnatmake} is called with |
| @code{-gnatc} as a builder switch (before @code{-cargs} or in package |
| Builder of the project file) then @code{gnatmake} will not fail because |
| it will not look for the object files after compilation, and it will not try |
| to build and link. |
| @end table |
| |
| @geindex -gnatC (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatC} |
| |
| Generate CodePeer intermediate format (no code generation attempted). |
| This switch will generate an intermediate representation suitable for |
| use by CodePeer (@code{.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). |
| @end table |
| |
| @geindex -gnatd (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatd} |
| |
| Specify debug options for the compiler. The string of characters after |
| the @code{-gnatd} specifies the specific debug options. The possible |
| characters are 0-9, a-z, A-Z, optionally preceded by a dot or underscore. |
| See compiler source file @code{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. |
| @end table |
| |
| @geindex -gnatD[nn] (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatD} |
| |
| Create expanded source files for source level debugging. This switch |
| also suppresses generation of cross-reference information |
| (see @code{-gnatx}). Note that this switch is not allowed if a previous |
| -gnatR switch has been given, since these two switches are not compatible. |
| @end table |
| |
| @geindex -gnateA (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnateA} |
| |
| Check that the actual parameters of a subprogram call are not aliases of one |
| another. To qualify as aliasing, their memory locations must be identical or |
| overlapping, at least one of the corresponding formal parameters must be of |
| mode OUT or IN OUT, and at least one of the corresponding formal parameters |
| must have its parameter passing mechanism not specified. |
| |
| @example |
| type Rec_Typ is record |
| Data : Integer := 0; |
| end record; |
| |
| function Self (Val : Rec_Typ) return Rec_Typ is |
| begin |
| return Val; |
| end Self; |
| |
| procedure Detect_Aliasing (Val_1 : in out Rec_Typ; Val_2 : Rec_Typ) is |
| begin |
| null; |
| end Detect_Aliasing; |
| |
| Obj : Rec_Typ; |
| |
| Detect_Aliasing (Obj, Obj); |
| Detect_Aliasing (Obj, Self (Obj)); |
| @end example |
| |
| In the example above, the first call to @code{Detect_Aliasing} fails with a |
| @code{Program_Error} at run time because the actuals for @code{Val_1} and |
| @code{Val_2} denote the same object. The second call executes without raising |
| an exception because @code{Self(Obj)} produces an anonymous object which does |
| not share the memory location of @code{Obj}. |
| @end table |
| |
| @geindex -gnateb (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnateb} |
| |
| Store configuration files by their basename in ALI files. This switch is |
| used for instance by gprbuild for distributed builds in order to prevent |
| issues where machine-specific absolute paths could end up being stored in |
| ALI files. |
| @end table |
| |
| @geindex -gnatec (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatec=@emph{path}} |
| |
| Specify a configuration pragma file |
| (the equal sign is optional) |
| (@ref{63,,The Configuration Pragmas Files}). |
| @end table |
| |
| @geindex -gnateC (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnateC} |
| |
| Generate CodePeer messages in a compiler-like format. This switch is only |
| effective if @code{-gnatcC} is also specified and requires an installation |
| of CodePeer. |
| @end table |
| |
| @geindex -gnated (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnated} |
| |
| Disable atomic synchronization |
| @end table |
| |
| @geindex -gnateD (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnateDsymbol[=@emph{value}]} |
| |
| Defines a symbol, associated with @code{value}, for preprocessing. |
| (@ref{90,,Integrated Preprocessing}). |
| @end table |
| |
| @geindex -gnateE (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnateE} |
| |
| 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. |
| @end table |
| |
| @geindex -gnatef (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatef} |
| |
| Display full source path name in brief error messages. |
| @end table |
| |
| @geindex -gnateF (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnateF} |
| |
| 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. |
| @end table |
| |
| @geindex -gnateg (gcc) |
| |
| @code{-gnateg} |
| @code{-gnatceg} |
| |
| @quotation |
| |
| The @code{-gnatc} switch must always be specified before this switch, e.g. |
| @code{-gnatceg}. Generate a C header from the Ada input file. See |
| @ref{b7,,Generating C Headers for Ada Specifications} for more |
| information. |
| @end quotation |
| |
| @geindex -gnateG (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnateG} |
| |
| Save result of preprocessing in a text file. |
| @end table |
| |
| @geindex -gnatei (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatei@emph{nnn}} |
| |
| Set maximum number of instantiations during compilation of a single unit to |
| @code{nnn}. This may be useful in increasing the default maximum of 8000 for |
| the rare case when a single unit legitimately exceeds this limit. |
| @end table |
| |
| @geindex -gnateI (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnateI@emph{nnn}} |
| |
| Indicates that the source is a multi-unit source and that the index of the |
| unit to compile is @code{nnn}. @code{nnn} needs to be a positive number and need |
| to be a valid index in the multi-unit source. |
| @end table |
| |
| @geindex -gnatel (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatel} |
| |
| This switch can be used with the static elaboration model to issue info |
| messages showing |
| where implicit @code{pragma Elaborate} and @code{pragma Elaborate_All} |
| are generated. This is useful in diagnosing elaboration circularities |
| caused by these implicit pragmas when using the static elaboration |
| model. See See the section in this guide on elaboration checking for |
| further details. These messages are not generated by default, and are |
| intended only for temporary use when debugging circularity problems. |
| @end table |
| |
| @geindex -gnatel (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnateL} |
| |
| This switch turns off the info messages about implicit elaboration pragmas. |
| @end table |
| |
| @geindex -gnatem (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatem=@emph{path}} |
| |
| Specify a mapping file |
| (the equal sign is optional) |
| (@ref{e8,,Units to Sources Mapping Files}). |
| @end table |
| |
| @geindex -gnatep (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatep=@emph{file}} |
| |
| Specify a preprocessing data file |
| (the equal sign is optional) |
| (@ref{90,,Integrated Preprocessing}). |
| @end table |
| |
| @geindex -gnateP (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnateP} |
| |
| 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. |
| @end table |
| |
| @geindex -gnateS (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnateS} |
| |
| Synonym of @code{-fdump-scos}, kept for backwards compatibility. |
| @end table |
| |
| @geindex -gnatet=file (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatet=@emph{path}} |
| |
| Generate target dependent information. The format of the output file is |
| described in the section about switch @code{-gnateT}. |
| @end table |
| |
| @geindex -gnateT (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnateT=@emph{path}} |
| |
| Read target dependent information, such as endianness or sizes and alignments |
| of base type. If this switch is passed, the default target dependent |
| information of the compiler is replaced by the one read from the input file. |
| This is used by tools other than the compiler, e.g. to do |
| semantic analysis of programs that will run on some other target than |
| the machine on which the tool is run. |
| |
| The following target dependent values should be defined, |
| where @code{Nat} denotes a natural integer value, @code{Pos} denotes a |
| positive integer value, and fields marked with a question mark are |
| boolean fields, where a value of 0 is False, and a value of 1 is True: |
| |
| @example |
| Bits_BE : Nat; -- Bits stored big-endian? |
| Bits_Per_Unit : Pos; -- Bits in a storage unit |
| Bits_Per_Word : Pos; -- Bits in a word |
| Bytes_BE : Nat; -- Bytes stored big-endian? |
| Char_Size : Pos; -- Standard.Character'Size |
| Double_Float_Alignment : Nat; -- Alignment of double float |
| Double_Scalar_Alignment : Nat; -- Alignment of double length scalar |
| Double_Size : Pos; -- Standard.Long_Float'Size |
| Float_Size : Pos; -- Standard.Float'Size |
| Float_Words_BE : Nat; -- Float words stored big-endian? |
| Int_Size : Pos; -- Standard.Integer'Size |
| Long_Double_Size : Pos; -- Standard.Long_Long_Float'Size |
| Long_Long_Size : Pos; -- Standard.Long_Long_Integer'Size |
| Long_Size : Pos; -- Standard.Long_Integer'Size |
| Maximum_Alignment : Pos; -- Maximum permitted alignment |
| Max_Unaligned_Field : Pos; -- Maximum size for unaligned bit field |
| Pointer_Size : Pos; -- System.Address'Size |
| Short_Enums : Nat; -- Foreign enums use short size? |
| Short_Size : Pos; -- Standard.Short_Integer'Size |
| Strict_Alignment : Nat; -- Strict alignment? |
| System_Allocator_Alignment : Nat; -- Alignment for malloc calls |
| Wchar_T_Size : Pos; -- Interfaces.C.wchar_t'Size |
| Words_BE : Nat; -- Words stored big-endian? |
| @end example |
| |
| @code{Bits_Per_Unit} is the number of bits in a storage unit, the equivalent of |
| GCC macro @code{BITS_PER_UNIT} documented as follows: @cite{Define this macro to be the number of bits in an addressable storage unit (byte); normally 8.} |
| |
| @code{Bits_Per_Word} is the number of bits in a machine word, the equivalent of |
| GCC macro @code{BITS_PER_WORD} documented as follows: @cite{Number of bits in a word; normally 32.} |
| |
| @code{Double_Float_Alignment}, if not zero, is the maximum alignment that the |
| compiler can choose by default for a 64-bit floating-point type or object. |
| |
| @code{Double_Scalar_Alignment}, if not zero, is the maximum alignment that the |
| compiler can choose by default for a 64-bit or larger scalar type or object. |
| |
| @code{Maximum_Alignment} is the maximum alignment that the compiler can choose |
| by default for a type or object, which is also the maximum alignment that can |
| be specified in GNAT. It is computed for GCC backends as @code{BIGGEST_ALIGNMENT |
| / BITS_PER_UNIT} where GCC macro @code{BIGGEST_ALIGNMENT} is documented as |
| follows: @cite{Biggest alignment that any data type can require on this machine@comma{} in bits.} |
| |
| @code{Max_Unaligned_Field} is the maximum size for unaligned bit field, which is |
| 64 for the majority of GCC targets (but can be different on some targets). |
| |
| @code{Strict_Alignment} is the equivalent of GCC macro @code{STRICT_ALIGNMENT} |
| documented as follows: @cite{Define this macro to be the value 1 if instructions will fail to work if given data not on the nominal alignment. If instructions will merely go slower in that case@comma{} define this macro as 0.} |
| |
| @code{System_Allocator_Alignment} is the guaranteed alignment of data returned |
| by calls to @code{malloc}. |
| |
| The format of the input file is as follows. First come the values of |
| the variables defined above, with one line per value: |
| |
| @example |
| name value |
| @end example |
| |
| where @code{name} is the name of the parameter, spelled out in full, |
| and cased as in the above list, and @code{value} is an unsigned decimal |
| integer. Two or more blanks separates the name from the value. |
| |
| All the variables must be present, in alphabetical order (i.e. the |
| same order as the list above). |
| |
| Then there is a blank line to separate the two parts of the file. Then |
| come the lines showing the floating-point types to be registered, with |
| one line per registered mode: |
| |
| @example |
| name digs float_rep size alignment |
| @end example |
| |
| where @code{name} is the string name of the type (which can have |
| single spaces embedded in the name (e.g. long double), @code{digs} is |
| the number of digits for the floating-point type, @code{float_rep} is |
| the float representation (I for IEEE-754-Binary, which is |
| the only one supported at this time), |
| @code{size} is the size in bits, @code{alignment} is the |
| alignment in bits. The name is followed by at least two blanks, fields |
| are separated by at least one blank, and a LF character immediately |
| follows the alignment field. |
| |
| Here is an example of a target parameterization file: |
| |
| @example |
| Bits_BE 0 |
| Bits_Per_Unit 8 |
| Bits_Per_Word 64 |
| Bytes_BE 0 |
| Char_Size 8 |
| Double_Float_Alignment 0 |
| Double_Scalar_Alignment 0 |
| Double_Size 64 |
| Float_Size 32 |
| Float_Words_BE 0 |
| Int_Size 64 |
| Long_Double_Size 128 |
| Long_Long_Size 64 |
| Long_Size 64 |
| Maximum_Alignment 16 |
| Max_Unaligned_Field 64 |
| Pointer_Size 64 |
| Short_Size 16 |
| Strict_Alignment 0 |
| System_Allocator_Alignment 16 |
| Wchar_T_Size 32 |
| Words_BE 0 |
| |
| float 15 I 64 64 |
| double 15 I 64 64 |
| long double 18 I 80 128 |
| TF 33 I 128 128 |
| @end example |
| @end table |
| |
| @geindex -gnateu (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnateu} |
| |
| Ignore unrecognized validity, warning, and style switches that |
| appear after this switch is given. This may be useful when |
| compiling sources developed on a later version of the compiler |
| with an earlier version. Of course the earlier version must |
| support this switch. |
| @end table |
| |
| @geindex -gnateV (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnateV} |
| |
| Check that all actual parameters of a subprogram call are valid according to |
| the rules of validity checking (@ref{e7,,Validity Checking}). |
| @end table |
| |
| @geindex -gnateY (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnateY} |
| |
| 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. |
| @end table |
| |
| @geindex -gnatE (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatE} |
| |
| Dynamic elaboration checking mode enabled. For further details see |
| @ref{f,,Elaboration Order Handling in GNAT}. |
| @end table |
| |
| @geindex -gnatf (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatf} |
| |
| Full errors. Multiple errors per line, all undefined references, do not |
| attempt to suppress cascaded errors. |
| @end table |
| |
| @geindex -gnatF (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatF} |
| |
| Externals names are folded to all uppercase. |
| @end table |
| |
| @geindex -gnatg (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatg} |
| |
| 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 @code{-gnatg} |
| implies @code{-gnatw.ge} and @code{-gnatyg} so that all standard |
| warnings and all standard style options are turned on. All warnings and style |
| messages are treated as errors. |
| @end table |
| |
| @geindex -gnatG[nn] (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatG=nn} |
| |
| List generated expanded code in source form. |
| @end table |
| |
| @geindex -gnath (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnath} |
| |
| Output usage information. The output is written to @code{stdout}. |
| @end table |
| |
| @geindex -gnatH (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatH} |
| |
| Legacy elaboration-checking mode enabled. When this switch is in effect, |
| the pre-18.x access-before-elaboration model becomes the de facto model. |
| For further details see @ref{f,,Elaboration Order Handling in GNAT}. |
| @end table |
| |
| @geindex -gnati (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnati@emph{c}} |
| |
| Identifier character set (@code{c} = 1/2/3/4/5/9/p/8/f/n/w). |
| For details of the possible selections for @code{c}, |
| see @ref{31,,Character Set Control}. |
| @end table |
| |
| @geindex -gnatI (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatI} |
| |
| 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, Scalar_Storage_Order, Size, Small, Stream_Size, |
| and Value_Size. Pragma Default_Scalar_Storage_Order is also ignored. |
| Note that this option should be used only for compiling – the |
| code is likely to malfunction at run time. |
| @end table |
| |
| @geindex -gnatjnn (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatj@emph{nn}} |
| |
| Reformat error messages to fit on @code{nn} character lines |
| @end table |
| |
| @geindex -gnatJ (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatJ} |
| |
| Permissive elaboration-checking mode enabled. When this switch is in effect, |
| the post-18.x access-before-elaboration model ignores potential issues with: |
| |
| |
| @itemize - |
| |
| @item |
| Accept statements |
| |
| @item |
| Activations of tasks defined in instances |
| |
| @item |
| Assertion pragmas |
| |
| @item |
| Calls from within an instance to its enclosing context |
| |
| @item |
| Calls through generic formal parameters |
| |
| @item |
| Calls to subprograms defined in instances |
| |
| @item |
| Entry calls |
| |
| @item |
| Indirect calls using ‘Access |
| |
| @item |
| Requeue statements |
| |
| @item |
| Select statements |
| |
| @item |
| Synchronous task suspension |
| @end itemize |
| |
| and does not emit compile-time diagnostics or run-time checks. For further |
| details see @ref{f,,Elaboration Order Handling in GNAT}. |
| @end table |
| |
| @geindex -gnatk (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatk=@emph{n}} |
| |
| Limit file names to @code{n} (1-999) characters (@code{k} = krunch). |
| @end table |
| |
| @geindex -gnatl (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatl} |
| |
| Output full source listing with embedded error messages. |
| @end table |
| |
| @geindex -gnatL (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatL} |
| |
| Used in conjunction with -gnatG or -gnatD to intersperse original |
| source lines (as comment lines with line numbers) in the expanded |
| source output. |
| @end table |
| |
| @geindex -gnatm (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatm=@emph{n}} |
| |
| Limit number of detected error or warning messages to @code{n} |
| where @code{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. |
| @end table |
| |
| @geindex -gnatn (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatn[12]} |
| |
| Activate inlining across units 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 units |
| or 2 for full inlining across units. If no inlining level is specified, |
| the compiler will pick it based on the optimization level. |
| @end table |
| |
| @geindex -gnatN (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatN} |
| |
| 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 |
| @code{-gnatG} output. |
| |
| When using a gcc-based back end, then the use of |
| @code{-gnatN} is deprecated, and the use of @code{-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 |
| |
| @geindex -gnato0 (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnato0} |
| |
| Suppresses overflow checking. This causes the behavior of the compiler to |
| match the default for older versions where overflow checking was suppressed |
| by default. This is equivalent to having |
| @code{pragma Suppress (Overflow_Check)} in a configuration pragma file. |
| @end table |
| |
| @geindex -gnato?? (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnato??} |
| |
| 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}: |
| |
| |
| @multitable {xxxxxxx} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx} |
| @item |
| |
| Digit |
| |
| @tab |
| |
| Interpretation |
| |
| @item |
| |
| @emph{1} |
| |
| @tab |
| |
| All intermediate overflows checked against base type (@code{STRICT}) |
| |
| @item |
| |
| @emph{2} |
| |
| @tab |
| |
| Minimize intermediate overflows (@code{MINIMIZED}) |
| |
| @item |
| |
| @emph{3} |
| |
| @tab |
| |
| Eliminate intermediate overflows (@code{ELIMINATED}) |
| |
| @end multitable |
| |
| |
| If only one digit appears, then it applies to all |
| cases; if two digits are given, then the first applies outside |
| assertions, pre/postconditions, and type invariants, and the second |
| applies within assertions, pre/postconditions, and type invariants. |
| |
| If no digits follow the @code{-gnato}, then it is equivalent to |
| @code{-gnato11}, |
| causing all intermediate overflows to be handled in strict |
| mode. |
| |
| This switch also causes arithmetic overflow checking to be performed |
| (as though @code{pragma Unsuppress (Overflow_Check)} had been specified). |
| |
| The default if no option @code{-gnato} is given is that overflow handling |
| is in @code{STRICT} mode (computations done using the base type), and that |
| overflow checking is enabled. |
| |
| Note that division by zero is a separate check that is not |
| controlled by this switch (divide-by-zero checking is on by default). |
| |
| See also @ref{e9,,Specifying the Desired Mode}. |
| @end table |
| |
| @geindex -gnatp (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatp} |
| |
| Suppress all checks. See @ref{ea,,Run-Time Checks} for details. This switch |
| has no effect if cancelled by a subsequent @code{-gnat-p} switch. |
| @end table |
| |
| @geindex -gnat-p (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnat-p} |
| |
| Cancel effect of previous @code{-gnatp} switch. |
| @end table |
| |
| @geindex -gnatq (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatq} |
| |
| Don’t quit. Try semantics, even if parse errors. |
| @end table |
| |
| @geindex -gnatQ (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatQ} |
| |
| Don’t quit. Generate @code{ALI} and tree files even if illegalities. |
| Note that code generation is still suppressed in the presence of any |
| errors, so even with @code{-gnatQ} no object file is generated. |
| @end table |
| |
| @geindex -gnatr (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatr} |
| |
| Treat pragma Restrictions as Restriction_Warnings. |
| @end table |
| |
| @geindex -gnatR (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatR[0|1|2|3|4][e][j][m][s]} |
| |
| Output representation information for declared types, objects and |
| subprograms. Note that this switch is not allowed if a previous |
| @code{-gnatD} switch has been given, since these two switches |
| are not compatible. |
| @end table |
| |
| @geindex -gnats (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnats} |
| |
| Syntax check only. |
| @end table |
| |
| @geindex -gnatS (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatS} |
| |
| Print package Standard. |
| @end table |
| |
| @geindex -gnatT (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatT@emph{nnn}} |
| |
| All compiler tables start at @code{nnn} times usual starting size. |
| @end table |
| |
| @geindex -gnatu (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatu} |
| |
| List units for this compilation. |
| @end table |
| |
| @geindex -gnatU (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatU} |
| |
| Tag all error messages with the unique string ‘error:’ |
| @end table |
| |
| @geindex -gnatv (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatv} |
| |
| Verbose mode. Full error output with source lines to @code{stdout}. |
| @end table |
| |
| @geindex -gnatV (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatV} |
| |
| Control level of validity checking (@ref{e7,,Validity Checking}). |
| @end table |
| |
| @geindex -gnatw (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatw@emph{xxx}} |
| |
| Warning mode where |
| @code{xxx} is a string of option letters that denotes |
| the exact warnings that |
| are enabled or disabled (@ref{eb,,Warning Message Control}). |
| @end table |
| |
| @geindex -gnatW (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatW@emph{e}} |
| |
| Wide character encoding method |
| (@code{e}=n/h/u/s/e/8). |
| @end table |
| |
| @geindex -gnatx (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatx} |
| |
| Suppress generation of cross-reference information. |
| @end table |
| |
| @geindex -gnatX (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatX} |
| |
| Enable GNAT implementation extensions and latest Ada version. |
| @end table |
| |
| @geindex -gnaty (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnaty} |
| |
| Enable built-in style checks (@ref{ec,,Style Checking}). |
| @end table |
| |
| @geindex -gnatz (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatz@emph{m}} |
| |
| Distribution stub generation and compilation |
| (@code{m}=r/c for receiver/caller stubs). |
| @end table |
| |
| @geindex -I (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-I@emph{dir}} |
| |
| @geindex RTL |
| |
| Direct GNAT to search the @code{dir} directory for source files needed by |
| the current compilation |
| (see @ref{73,,Search Paths and the Run-Time Library (RTL)}). |
| @end table |
| |
| @geindex -I- (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-I-} |
| |
| @geindex 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 |
| (see @ref{73,,Search Paths and the Run-Time Library (RTL)}). |
| @end table |
| |
| @geindex -o (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-o @emph{file}} |
| |
| This switch is used in @code{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 table |
| |
| @geindex -nostdinc (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-nostdinc} |
| |
| Inhibit the search of the default location for the GNAT Run Time |
| Library (RTL) source files. |
| @end table |
| |
| @geindex -nostdlib (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-nostdlib} |
| |
| Inhibit the search of the default location for the GNAT Run Time |
| Library (RTL) ALI files. |
| @end table |
| |
| @geindex -O (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-O[@emph{n}]} |
| |
| @code{n} controls the optimization level: |
| |
| |
| @multitable {xxxxxxxxx} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx} |
| @item |
| |
| @emph{n} |
| |
| @tab |
| |
| Effect |
| |
| @item |
| |
| @emph{0} |
| |
| @tab |
| |
| No optimization, the default setting if no @code{-O} appears |
| |
| @item |
| |
| @emph{1} |
| |
| @tab |
| |
| Normal optimization, the default if you specify @code{-O} without an |
| operand. A good compromise between code quality and compilation |
| time. |
| |
| @item |
| |
| @emph{2} |
| |
| @tab |
| |
| Extensive optimization, may improve execution time, possibly at |
| the cost of substantially increased compilation time. |
| |
| @item |
| |
| @emph{3} |
| |
| @tab |
| |
| Same as @code{-O2}, and also includes inline expansion for small |
| subprograms in the same unit. |
| |
| @item |
| |
| @emph{s} |
| |
| @tab |
| |
| Optimize space usage |
| |
| @end multitable |
| |
| |
| See also @ref{ed,,Optimization Levels}. |
| @end table |
| |
| @geindex -pass-exit-codes (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-pass-exit-codes} |
| |
| Catch exit codes from the compiler and use the most meaningful as |
| exit status. |
| @end table |
| |
| @geindex --RTS (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{--RTS=@emph{rts-path}} |
| |
| Specifies the default location of the run-time library. Same meaning as the |
| equivalent @code{gnatmake} flag (@ref{ce,,Switches for gnatmake}). |
| @end table |
| |
| @geindex -S (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-S} |
| |
| Used in place of @code{-c} to |
| cause the assembler source file to be |
| generated, using @code{.s} as the extension, |
| instead of the object file. |
| This may be useful if you need to examine the generated assembly code. |
| @end table |
| |
| @geindex -fverbose-asm (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-fverbose-asm} |
| |
| Used in conjunction with @code{-S} |
| to cause the generated assembly code file to be annotated with variable |
| names, making it significantly easier to follow. |
| @end table |
| |
| @geindex -v (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-v} |
| |
| Show commands generated by the @code{gcc} driver. Normally used only for |
| debugging purposes or if you need to be sure what version of the |
| compiler you are executing. |
| @end table |
| |
| @geindex -V (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-V @emph{ver}} |
| |
| Execute @code{ver} version of the compiler. This is the @code{gcc} |
| version, not the GNAT version. |
| @end table |
| |
| @geindex -w (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-w} |
| |
| 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 @code{-gnatws} had appeared at the start of |
| the options). |
| @end table |
| |
| @geindex Combining GNAT switches |
| |
| You may combine a sequence of GNAT switches into a single switch. For |
| example, the combined switch |
| |
| @quotation |
| |
| @example |
| -gnatofi3 |
| @end example |
| @end quotation |
| |
| is equivalent to specifying the following sequence of switches: |
| |
| @quotation |
| |
| @example |
| -gnato -gnatf -gnati3 |
| @end example |
| @end quotation |
| |
| The following restrictions apply to the combination of switches |
| in this manner: |
| |
| |
| @itemize * |
| |
| @item |
| The switch @code{-gnatc} if combined with other switches must come |
| first in the string. |
| |
| @item |
| The switch @code{-gnats} if combined with other switches must come |
| first in the string. |
| |
| @item |
| The switches |
| @code{-gnatzc} and @code{-gnatzr} may not be combined with any other |
| switches, and only one of them may appear in the command line. |
| |
| @item |
| The switch @code{-gnat-p} may not be combined with any other switch. |
| |
| @item |
| Once a ‘y’ appears in the string (that is a use of the @code{-gnaty} |
| switch), then all further characters in the switch are interpreted |
| as style modifiers (see description of @code{-gnaty}). |
| |
| @item |
| Once a ‘d’ appears in the string (that is a use of the @code{-gnatd} |
| switch), then all further characters in the switch are interpreted |
| as debug flags (see description of @code{-gnatd}). |
| |
| @item |
| Once a ‘w’ appears in the string (that is a use of the @code{-gnatw} |
| switch), then all further characters in the switch are interpreted |
| as warning mode modifiers (see description of @code{-gnatw}). |
| |
| @item |
| Once a ‘V’ appears in the string (that is a use of the @code{-gnatV} |
| switch), then all further characters in the switch are interpreted |
| as validity checking options (@ref{e7,,Validity Checking}). |
| |
| @item |
| Option ‘em’, ‘ec’, ‘ep’, ‘l=’ and ‘R’ must be the last options in |
| a combined list of options. |
| @end itemize |
| |
| @node Output and Error Message Control,Warning Message Control,Alphabetical List of All Switches,Compiler Switches |
| @anchor{gnat_ugn/building_executable_programs_with_gnat id14}@anchor{ee}@anchor{gnat_ugn/building_executable_programs_with_gnat output-and-error-message-control}@anchor{ef} |
| @subsection Output and Error Message Control |
| |
| |
| @geindex stderr |
| |
| The standard default format for error messages is called ‘brief format’. |
| Brief format messages are written to @code{stderr} (the standard error |
| file) and have the following form: |
| |
| @example |
| e.adb:3:04: Incorrect spelling of keyword "function" |
| e.adb:4:20: ";" should be "is" |
| @end example |
| |
| The first integer after the file name is the line number in the file, |
| and the second integer is the column number within the line. |
| @code{GNAT Studio} can parse the error messages |
| and point to the referenced character. |
| The following switches provide control over the error message |
| format: |
| |
| @geindex -gnatv (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatv} |
| |
| The @code{v} stands for verbose. |
| The effect of this setting is to write long-format error |
| messages to @code{stdout} (the standard output file. |
| The same program compiled with the |
| @code{-gnatv} switch would generate: |
| |
| @example |
| 3. funcion X (Q : Integer) |
| | |
| >>> Incorrect spelling of keyword "function" |
| 4. return Integer; |
| | |
| >>> ";" should be "is" |
| @end example |
| |
| The vertical bar indicates the location of the error, and the @code{>>>} |
| prefix can be used to search for error messages. When this switch is |
| used the only source lines output are those with errors. |
| @end table |
| |
| @geindex -gnatl (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatl} |
| |
| The @code{l} stands for list. |
| 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 @code{p.adb} might look like: |
| |
| @example |
| 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 example |
| |
| When you specify the @code{-gnatv} or @code{-gnatl} switches and |
| standard output is redirected, a brief summary is written to |
| @code{stderr} (standard error) giving the number of error messages and |
| warning messages generated. |
| @end table |
| |
| @geindex -gnatl=fname (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatl=@emph{fname}} |
| |
| This has the same effect as @code{-gnatl} except that the output is |
| written to a file instead of to standard output. If the given name |
| @code{fname} does not start with a period, then it is the full name |
| of the file to be written. If @code{fname} is an extension, it is |
| appended to the name of the file being compiled. For example, if |
| file @code{xyz.adb} is compiled with @code{-gnatl=.lst}, |
| then the output is written to file xyz.adb.lst. |
| @end table |
| |
| @geindex -gnatU (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatU} |
| |
| 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. |
| @end table |
| |
| @geindex -gnatb (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatb} |
| |
| The @code{b} stands for brief. |
| This switch causes GNAT to generate the |
| brief format error messages to @code{stderr} (the standard error |
| file) as well as the verbose |
| format message or full listing (which as usual is written to |
| @code{stdout} (the standard output file). |
| @end table |
| |
| @geindex -gnatm (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatm=@emph{n}} |
| |
| The @code{m} stands for maximum. |
| @code{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 |
| @code{-gnatm2} might yield |
| |
| @example |
| e.adb:3:04: Incorrect spelling of keyword "function" |
| e.adb:5:35: missing ".." |
| fatal error: maximum number of errors detected |
| compilation abandoned |
| @end example |
| |
| 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. |
| |
| Note that the equal sign is optional, so the switches |
| @code{-gnatm2} and @code{-gnatm=2} are equivalent. |
| @end table |
| |
| @geindex -gnatf (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatf} |
| |
| @geindex Error messages |
| @geindex suppressing |
| |
| The @code{f} stands for full. |
| 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 |
| |
| @example |
| e.adb:7:07: "V" is undefined (more references follow) |
| @end example |
| |
| where the parenthetical comment warns that there are additional |
| references to the variable @code{V}. Compiling the same program with the |
| @code{-gnatf} switch yields |
| |
| @example |
| 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 example |
| |
| The @code{-gnatf} switch also generates additional information for |
| some error messages. Some examples are: |
| |
| |
| @itemize * |
| |
| @item |
| Details on possibly non-portable unchecked conversion |
| |
| @item |
| List possible interpretations for ambiguous calls |
| |
| @item |
| Additional details on incorrect parameters |
| @end itemize |
| @end table |
| |
| @geindex -gnatjnn (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatjnn} |
| |
| In normal operation mode (or if @code{-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 @code{-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. |
| @end table |
| |
| @geindex -gnatq (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatq} |
| |
| The @code{q} stands for quit (really ‘don’t quit’). |
| 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. |
| @end table |
| |
| @geindex -gnatQ (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatQ} |
| |
| In normal operation mode, the @code{ALI} file is not generated if any |
| illegalities are detected in the program. The use of @code{-gnatQ} forces |
| generation of the @code{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 @code{ALI} file. This switch |
| implies @code{-gnatq}, since the semantic phase must be run to get a |
| meaningful ALI file. |
| |
| When @code{-gnatQ} is used and the generated @code{ALI} file is marked as |
| being in error, @code{gnatmake} will attempt to recompile the source when it |
| finds such an @code{ALI} file, including with switch @code{-gnatc}. |
| |
| Note that @code{-gnatQ} has no effect if @code{-gnats} is specified, |
| since ALI files are never generated if @code{-gnats} is set. |
| @end table |
| |
| @node Warning Message Control,Debugging and Assertion Control,Output and Error Message Control,Compiler Switches |
| @anchor{gnat_ugn/building_executable_programs_with_gnat id15}@anchor{f0}@anchor{gnat_ugn/building_executable_programs_with_gnat warning-message-control}@anchor{eb} |
| @subsection Warning Message Control |
| |
| |
| @geindex Warning messages |
| |
| 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: |
| |
| @example |
| 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 example |
| |
| 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 * |
| |
| @item |
| Possible infinitely recursive calls |
| |
| @item |
| Out-of-range values being assigned |
| |
| @item |
| Possible order of elaboration problems |
| |
| @item |
| Size not a multiple of alignment for a record type |
| |
| @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 @emph{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 @emph{with}ed by application unit |
| |
| @item |
| Values known to be out of range at compile time |
| |
| @item |
| Unreferenced or unmodified variables. Note that a special |
| exemption applies to variables which contain any of the substrings |
| @code{DISCARD, DUMMY, IGNORE, JUNK, UNUSED}, in any casing. Such variables |
| are considered likely to be intentionally used in a situation where |
| otherwise a warning would be given, so warnings of this kind are |
| always suppressed for such 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 |
| |
| 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 (see the description |
| of the pragma in the @cite{GNAT_Reference_manual}). |
| |
| @geindex -gnatwa (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatwa} |
| |
| @emph{Activate most optional warnings.} |
| |
| 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: |
| |
| |
| @itemize * |
| |
| @item |
| @code{-gnatwd} (implicit dereferencing) |
| |
| @item |
| @code{-gnatw.d} (tag warnings with -gnatw switch) |
| |
| @item |
| @code{-gnatwh} (hiding) |
| |
| @item |
| @code{-gnatw.h} (holes in record layouts) |
| |
| @item |
| @code{-gnatw.j} (late primitives of tagged types) |
| |
| @item |
| @code{-gnatw.k} (redefinition of names in standard) |
| |
| @item |
| @code{-gnatwl} (elaboration warnings) |
| |
| @item |
| @code{-gnatw.l} (inherited aspects) |
| |
| @item |
| @code{-gnatw.n} (atomic synchronization) |
| |
| @item |
| @code{-gnatwo} (address clause overlay) |
| |
| @item |
| @code{-gnatw.o} (values set by out parameters ignored) |
| |
| @item |
| @code{-gnatw.q} (questionable layout of record types) |
| |
| @item |
| @code{-gnatw_r} (out-of-order record representation clauses) |
| |
| @item |
| @code{-gnatw.s} (overridden size clause) |
| |
| @item |
| @code{-gnatwt} (tracking of deleted conditional code) |
| |
| @item |
| @code{-gnatw.u} (unordered enumeration) |
| |
| @item |
| @code{-gnatw.w} (use of Warnings Off) |
| |
| @item |
| @code{-gnatw.y} (reasons for package needing body) |
| @end itemize |
| |
| All other optional warnings are turned on. |
| @end table |
| |
| @geindex -gnatwA (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatwA} |
| |
| @emph{Suppress all optional errors.} |
| |
| 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 @code{-gnatws}, the |
| use of switch @code{-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 @code{-gnatws}, warnings suppressed by |
| the use of switch @code{-gnatwA} can be individually turned back |
| on. For example the use of switch @code{-gnatwA} followed by |
| switch @code{-gnatwd} will suppress all optional warnings except |
| the warnings for implicit dereferencing. |
| @end table |
| |
| @geindex -gnatw.a (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatw.a} |
| |
| @emph{Activate warnings on failing assertions.} |
| |
| @geindex 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. |
| @end table |
| |
| @geindex -gnatw.A (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatw.A} |
| |
| @emph{Suppress warnings on failing assertions.} |
| |
| @geindex Assert failures |
| |
| This switch suppresses warnings for assertions where the compiler can tell at |
| compile time that the assertion will fail. |
| @end table |
| |
| @geindex -gnatw_a |
| |
| |
| @table @asis |
| |
| @item @code{-gnatw_a} |
| |
| @emph{Activate warnings on anonymous allocators.} |
| |
| @geindex Anonymous allocators |
| |
| This switch activates warnings for allocators of anonymous access types, |
| which can involve run-time accessibility checks and lead to unexpected |
| accessibility violations. For more details on the rules involved, see |
| RM 3.10.2 (14). |
| @end table |
| |
| @geindex -gnatw_A |
| |
| |
| @table @asis |
| |
| @item @code{-gnatw_A} |
| |
| @emph{Supress warnings on anonymous allocators.} |
| |
| @geindex Anonymous allocators |
| |
| This switch suppresses warnings for anonymous access type allocators. |
| @end table |
| |
| @geindex -gnatwb (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatwb} |
| |
| @emph{Activate warnings on bad fixed values.} |
| |
| @geindex Bad fixed values |
| |
| @geindex Fixed-point Small value |
| |
| @geindex 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. |
| @end table |
| |
| @geindex -gnatwB (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatwB} |
| |
| @emph{Suppress warnings on bad fixed values.} |
| |
| This switch suppresses warnings for static fixed-point expressions whose |
| value is not an exact multiple of Small. |
| @end table |
| |
| @geindex -gnatw.b (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatw.b} |
| |
| @emph{Activate warnings on biased representation.} |
| |
| @geindex 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. |
| @end table |
| |
| @geindex -gnatwB (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatw.B} |
| |
| @emph{Suppress warnings on biased representation.} |
| |
| This switch suppresses warnings for representation clauses that force the use |
| of biased representation. |
| @end table |
| |
| @geindex -gnatwc (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatwc} |
| |
| @emph{Activate warnings on conditionals.} |
| |
| @geindex Conditionals |
| @geindex 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 @code{-gnatwa}. |
| @end table |
| |
| @geindex -gnatwC (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatwC} |
| |
| @emph{Suppress warnings on conditionals.} |
| |
| This switch suppresses warnings for conditional expressions used in |
| tests that are known to be True or False at compile time. |
| @end table |
| |
| @geindex -gnatw.c (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatw.c} |
| |
| @emph{Activate warnings on missing component clauses.} |
| |
| @geindex Component clause |
| @geindex 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. |
| @end table |
| |
| @geindex -gnatw.C (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatw.C} |
| |
| @emph{Suppress warnings on missing component clauses.} |
| |
| This switch suppresses warnings for record components that are |
| missing a component clause in the situation described above. |
| @end table |
| |
| @geindex -gnatw_c (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatw_c} |
| |
| @emph{Activate warnings on unknown condition in Compile_Time_Warning.} |
| |
| @geindex Compile_Time_Warning |
| |
| @geindex Compile_Time_Error |
| |
| This switch activates warnings on a pragma Compile_Time_Warning |
| or Compile_Time_Error whose condition has a value that is not |
| known at compile time. |
| The default is that such warnings are generated. |
| @end table |
| |
| @geindex -gnatw_C (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatw_C} |
| |
| @emph{Suppress warnings on unknown condition in Compile_Time_Warning.} |
| |
| This switch supresses warnings on a pragma Compile_Time_Warning |
| or Compile_Time_Error whose condition has a value that is not |
| known at compile time. |
| @end table |
| |
| @geindex -gnatwd (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatwd} |
| |
| @emph{Activate warnings on implicit dereferencing.} |
| |
| 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. |
| @end table |
| |
| @geindex -gnatwD (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatwD} |
| |
| @emph{Suppress warnings on implicit dereferencing.} |
| |
| @geindex Implicit dereferencing |
| |
| @geindex Dereferencing |
| @geindex implicit |
| |
| This switch suppresses warnings for implicit dereferences in |
| indexed components, slices, and selected components. |
| @end table |
| |
| @geindex -gnatw.d (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatw.d} |
| |
| @emph{Activate tagging of warning and info messages.} |
| |
| If this switch is set, then warning messages are tagged, with one of the |
| following strings: |
| |
| @quotation |
| |
| |
| @itemize - |
| |
| @item |
| @emph{[-gnatw?]} |
| Used to tag warnings controlled by the switch @code{-gnatwx} where x |
| is a letter a-z. |
| |
| @item |
| @emph{[-gnatw.?]} |
| Used to tag warnings controlled by the switch @code{-gnatw.x} where x |
| is a letter a-z. |
| |
| @item |
| @emph{[-gnatel]} |
| Used to tag elaboration information (info) messages generated when the |
| static model of elaboration is used and the @code{-gnatel} switch is set. |
| |
| @item |
| @emph{[restriction warning]} |
| Used to tag warning messages for restriction violations, activated by use |
| of the pragma @code{Restriction_Warnings}. |
| |
| @item |
| @emph{[warning-as-error]} |
| Used to tag warning messages that have been converted to error messages by |
| use of the pragma Warning_As_Error. Note that such warnings are prefixed by |
| the string “error: ” rather than “warning: “. |
| |
| @item |
| @emph{[enabled by default]} |
| Used to tag all other warnings that are always given by default, unless |
| warnings are completely suppressed using pragma @emph{Warnings(Off)} or |
| the switch @code{-gnatws}. |
| @end itemize |
| @end quotation |
| @end table |
| |
| @geindex -gnatw.d (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatw.D} |
| |
| @emph{Deactivate tagging of warning and info messages messages.} |
| |
| If this switch is set, then warning messages return to the default |
| mode in which warnings and info messages are not tagged as described above for |
| @code{-gnatw.d}. |
| @end table |
| |
| @geindex -gnatwe (gcc) |
| |
| @geindex Warnings |
| @geindex treat as error |
| |
| |
| @table @asis |
| |
| @item @code{-gnatwe} |
| |
| @emph{Treat warnings and style checks as errors.} |
| |
| 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. |
| Note also that this switch has no effect on info (information) messages, which |
| are not treated as errors if this switch is present. |
| @end table |
| |
| @geindex -gnatw.e (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatw.e} |
| |
| @emph{Activate every optional warning.} |
| |
| @geindex Warnings |
| @geindex 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. |
| @end table |
| |
| @geindex -gnatwE (gcc) |
| |
| @geindex Warnings |
| @geindex treat as error |
| |
| |
| @table @asis |
| |
| @item @code{-gnatwE} |
| |
| @emph{Treat all run-time exception warnings as errors.} |
| |
| This switch causes warning messages regarding errors that will be raised |
| during run-time execution to be treated as errors. |
| @end table |
| |
| @geindex -gnatwf (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatwf} |
| |
| @emph{Activate warnings on unreferenced formals.} |
| |
| @geindex Formals |
| @geindex 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 @code{-gnatwu}. The |
| default is that these warnings are not generated. |
| @end table |
| |
| @geindex -gnatwF (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatwF} |
| |
| @emph{Suppress warnings on unreferenced formals.} |
| |
| This switch suppresses warnings for unreferenced formal |
| parameters. Note that the |
| combination @code{-gnatwu} followed by @code{-gnatwF} has the |
| effect of warning on unreferenced entities other than subprogram |
| formals. |
| @end table |
| |
| @geindex -gnatwg (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatwg} |
| |
| @emph{Activate warnings on unrecognized pragmas.} |
| |
| @geindex Pragmas |
| @geindex 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. The default |
| is that such warnings are issued (satisfying the Ada Reference |
| Manual requirement that such warnings appear). |
| @end table |
| |
| @geindex -gnatwG (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatwG} |
| |
| @emph{Suppress warnings on unrecognized pragmas.} |
| |
| This switch suppresses warnings for unrecognized pragmas. |
| @end table |
| |
| @geindex -gnatw.g (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatw.g} |
| |
| @emph{Warnings used for GNAT sources.} |
| |
| This switch sets the warning categories that are used by the standard |
| GNAT style. Currently this is equivalent to |
| @code{-gnatwAao.q.s.CI.V.X.Z} |
| but more warnings may be added in the future without advanced notice. |
| @end table |
| |
| @geindex -gnatwh (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatwh} |
| |
| @emph{Activate warnings on hiding.} |
| |
| @geindex Hiding of Declarations |
| |
| This switch activates warnings on hiding declarations that are considered |
| potentially confusing. Not all cases of hiding cause warnings; for example an |
| overriding declaration hides an implicit declaration, which is just normal |
| code. The default is that warnings on hiding are not generated. |
| @end table |
| |
| @geindex -gnatwH (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatwH} |
| |
| @emph{Suppress warnings on hiding.} |
| |
| This switch suppresses warnings on hiding declarations. |
| @end table |
| |
| @geindex -gnatw.h (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatw.h} |
| |
| @emph{Activate warnings on holes/gaps in records.} |
| |
| @geindex 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. |
| @end table |
| |
| @geindex -gnatw.H (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatw.H} |
| |
| @emph{Suppress warnings on holes/gaps in records.} |
| |
| This switch suppresses warnings on component clauses in record |
| representation clauses that leave holes (haps) in the record layout. |
| @end table |
| |
| @geindex -gnatwi (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatwi} |
| |
| @emph{Activate warnings on implementation units.} |
| |
| This switch activates warnings for a @emph{with} of an internal GNAT |
| implementation unit, defined as any unit from the @code{Ada}, |
| @code{Interfaces}, @code{GNAT}, |
| 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 @emph{with}ed |
| by user programs. The default is that such warnings are generated |
| @end table |
| |
| @geindex -gnatwI (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatwI} |
| |
| @emph{Disable warnings on implementation units.} |
| |
| This switch disables warnings for a @emph{with} of an internal GNAT |
| implementation unit. |
| @end table |
| |
| @geindex -gnatw.i (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatw.i} |
| |
| @emph{Activate warnings on overlapping actuals.} |
| |
| 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. This warning is off by default. |
| @end table |
| |
| @geindex -gnatw.I (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatw.I} |
| |
| @emph{Disable warnings on overlapping actuals.} |
| |
| This switch disables warnings on overlapping actuals in a call. |
| @end table |
| |
| @geindex -gnatwj (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatwj} |
| |
| @emph{Activate warnings on obsolescent features (Annex J).} |
| |
| @geindex Features |
| @geindex obsolescent |
| |
| @geindex Obsolescent features |
| |
| If this warning option is activated, then warnings are generated for |
| calls to subprograms marked with @code{pragma Obsolescent} and |
| for use of features in Annex J of the Ada Reference Manual. In the |
| case of Annex J, not all features are flagged. In particular use |
| of the renamed packages (like @code{Text_IO}) and use of package |
| @code{ASCII} are not flagged, since these are very common and |
| would generate many annoying positive warnings. The default is that |
| such warnings are not generated. |
| |
| In addition to the above cases, warnings are also generated for |
| GNAT features that have been provided in past versions but which |
| have been superseded (typically by features in the new Ada standard). |
| For example, @code{pragma Ravenscar} will be flagged since its |
| function is replaced by @code{pragma Profile(Ravenscar)}, 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}. |
| @end table |
| |
| @geindex -gnatwJ (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatwJ} |
| |
| @emph{Suppress warnings on obsolescent features (Annex J).} |
| |
| This switch disables warnings on use of obsolescent features. |
| @end table |
| |
| @geindex -gnatw.j (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatw.j} |
| |
| @emph{Activate warnings on late declarations of tagged type primitives.} |
| |
| This switch activates warnings on visible primitives added to a |
| tagged type after deriving a private extension from it. |
| @end table |
| |
| @geindex -gnatw.J (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatw.J} |
| |
| @emph{Suppress warnings on late declarations of tagged type primitives.} |
| |
| This switch suppresses warnings on visible primitives added to a |
| tagged type after deriving a private extension from it. |
| @end table |
| |
| @geindex -gnatwk (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatwk} |
| |
| @emph{Activate warnings on variables that could be constants.} |
| |
| 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. |
| @end table |
| |
| @geindex -gnatwK (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatwK} |
| |
| @emph{Suppress warnings on variables that could be constants.} |
| |
| This switch disables warnings on variables that could be declared constants. |
| @end table |
| |
| @geindex -gnatw.k (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatw.k} |
| |
| @emph{Activate warnings on redefinition of names in standard.} |
| |
| 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. |
| @end table |
| |
| @geindex -gnatwK (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatw.K} |
| |
| @emph{Suppress warnings on redefinition of names in standard.} |
| |
| This switch disables warnings for declarations that declare a name that |
| is defined in package Standard. |
| @end table |
| |
| @geindex -gnatwl (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatwl} |
| |
| @emph{Activate warnings for elaboration pragmas.} |
| |
| @geindex Elaboration |
| @geindex warnings |
| |
| This switch activates warnings for possible elaboration problems, |
| including suspicious use |
| of @code{Elaborate} pragmas, when using the static elaboration model, and |
| possible situations that may raise @code{Program_Error} when using the |
| dynamic elaboration model. |
| See the section in this guide on elaboration checking for further details. |
| The default is that such warnings |
| are not generated. |
| @end table |
| |
| @geindex -gnatwL (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatwL} |
| |
| @emph{Suppress warnings for elaboration pragmas.} |
| |
| This switch suppresses warnings for possible elaboration problems. |
| @end table |
| |
| @geindex -gnatw.l (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatw.l} |
| |
| @emph{List inherited aspects.} |
| |
| 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. |
| @end table |
| |
| @geindex -gnatw.L (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatw.L} |
| |
| @emph{Suppress listing of inherited aspects.} |
| |
| This switch suppresses listing of inherited aspects. |
| @end table |
| |
| @geindex -gnatwm (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatwm} |
| |
| @emph{Activate warnings on modified but unreferenced variables.} |
| |
| 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. |
| The default is that these warnings are not given. |
| @end table |
| |
| @geindex -gnatwM (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatwM} |
| |
| @emph{Disable warnings on modified but unreferenced variables.} |
| |
| This switch disables warnings for variables that are assigned or |
| initialized, but never read. |
| @end table |
| |
| @geindex -gnatw.m (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatw.m} |
| |
| @emph{Activate warnings on suspicious modulus values.} |
| |
| 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). This switch also activates warnings for negative |
| literal values of a modular type, which are interpreted as large positive |
| integers after wrap-around. The default is that these warnings are given. |
| @end table |
| |
| @geindex -gnatw.M (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatw.M} |
| |
| @emph{Disable warnings on suspicious modulus values.} |
| |
| This switch disables warnings for suspicious modulus values. |
| @end table |
| |
| @geindex -gnatwn (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatwn} |
| |
| @emph{Set normal warnings mode.} |
| |
| 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 @code{-gnatwn} can be used to cancel the effect of |
| an explicit @code{-gnatws} or |
| @code{-gnatwe}. It also cancels the effect of the |
| implicit @code{-gnatwe} that is activated by the |
| use of @code{-gnatg}. |
| @end table |
| |
| @geindex -gnatw.n (gcc) |
| |
| @geindex Atomic Synchronization |
| @geindex warnings |
| |
| |
| @table @asis |
| |
| @item @code{-gnatw.n} |
| |
| @emph{Activate warnings on atomic synchronization.} |
| |
| This switch actives warnings when an access to an atomic variable |
| requires the generation of atomic synchronization code. These |
| warnings are off by default. |
| @end table |
| |
| @geindex -gnatw.N (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatw.N} |
| |
| @emph{Suppress warnings on atomic synchronization.} |
| |
| @geindex Atomic Synchronization |
| @geindex warnings |
| |
| This switch suppresses warnings when an access to an atomic variable |
| requires the generation of atomic synchronization code. |
| @end table |
| |
| @geindex -gnatwo (gcc) |
| |
| @geindex Address Clauses |
| @geindex warnings |
| |
| |
| @table @asis |
| |
| @item @code{-gnatwo} |
| |
| @emph{Activate warnings on address clause overlays.} |
| |
| 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. |
| @end table |
| |
| @geindex -gnatwO (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatwO} |
| |
| @emph{Suppress warnings on address clause overlays.} |
| |
| This switch suppresses warnings on possibly unintended initialization |
| effects of defining address clauses that cause one variable to overlap |
| another. |
| @end table |
| |
| @geindex -gnatw.o (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatw.o} |
| |
| @emph{Activate warnings on modified but unreferenced out parameters.} |
| |
| 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. |
| @end table |
| |
| @geindex -gnatw.O (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatw.O} |
| |
| @emph{Disable warnings on modified but unreferenced out parameters.} |
| |
| 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. |
| @end table |
| |
| @geindex -gnatwp (gcc) |
| |
| @geindex Inlining |
| @geindex warnings |
| |
| |
| @table @asis |
| |
| @item @code{-gnatwp} |
| |
| @emph{Activate warnings on ineffective pragma Inlines.} |
| |
| This switch activates warnings for failure of front end inlining |
| (activated by @code{-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. |
| Warnings on ineffective inlining by the gcc back-end can be activated |
| separately, using the gcc switch -Winline. |
| @end table |
| |
| @geindex -gnatwP (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatwP} |
| |
| @emph{Suppress warnings on ineffective pragma Inlines.} |
| |
| This switch suppresses warnings on ineffective pragma Inlines. If the |
| inlining mechanism cannot inline a call, it will simply ignore the |
| request silently. |
| @end table |
| |
| @geindex -gnatw.p (gcc) |
| |
| @geindex Parameter order |
| @geindex warnings |
| |
| |
| @table @asis |
| |
| @item @code{-gnatw.p} |
| |
| @emph{Activate warnings on parameter ordering.} |
| |
| 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. |
| @end table |
| |
| @geindex -gnatw.P (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatw.P} |
| |
| @emph{Suppress warnings on parameter ordering.} |
| |
| This switch suppresses warnings on cases of suspicious parameter |
| ordering. |
| @end table |
| |
| @geindex -gnatw_p (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatw_p} |
| |
| @emph{Activate warnings for pedantic checks.} |
| |
| This switch activates warnings for the failure of certain pedantic checks. |
| The only case currently supported is a check that the subtype_marks given |
| for corresponding formal parameter and function results in a subprogram |
| declaration and its body denote the same subtype declaration. The default |
| is that such warnings are not given. |
| @end table |
| |
| @geindex -gnatw_P (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatw_P} |
| |
| @emph{Suppress warnings for pedantic checks.} |
| |
| This switch suppresses warnings on violations of pedantic checks. |
| @end table |
| |
| @geindex -gnatwq (gcc) |
| |
| @geindex Parentheses |
| @geindex warnings |
| |
| |
| @table @asis |
| |
| @item @code{-gnatwq} |
| |
| @emph{Activate warnings on questionable missing parentheses.} |
| |
| 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. |
| @end table |
| |
| @geindex -gnatwQ (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatwQ} |
| |
| @emph{Suppress warnings on questionable missing parentheses.} |
| |
| This switch suppresses warnings for cases where the association is not |
| clear and the use of parentheses is preferred. |
| @end table |
| |
| @geindex -gnatw.q (gcc) |
| |
| @geindex Layout |
| @geindex warnings |
| |
| |
| @table @asis |
| |
| @item @code{-gnatw.q} |
| |
| @emph{Activate warnings on questionable layout of record types.} |
| |
| This switch activates warnings for cases where the default layout of |
| a record type, that is to say the layout of its components in textual |
| order of the source code, would very likely cause inefficiencies in |
| the code generated by the compiler, both in terms of space and speed |
| during execution. One warning is issued for each problematic component |
| without representation clause in the nonvariant part and then in each |
| variant recursively, if any. |
| |
| The purpose of these warnings is neither to prescribe an optimal layout |
| nor to force the use of representation clauses, but rather to get rid of |
| the most blatant inefficiencies in the layout. Therefore, the default |
| layout is matched against the following synthetic ordered layout and |
| the deviations are flagged on a component-by-component basis: |
| |
| |
| @itemize * |
| |
| @item |
| first all components or groups of components whose length is fixed |
| and a multiple of the storage unit, |
| |
| @item |
| then the remaining components whose length is fixed and not a multiple |
| of the storage unit, |
| |
| @item |
| then the remaining components whose length doesn’t depend on discriminants |
| (that is to say, with variable but uniform length for all objects), |
| |
| @item |
| then all components whose length depends on discriminants, |
| |
| @item |
| finally the variant part (if any), |
| @end itemize |
| |
| for the nonvariant part and for each variant recursively, if any. |
| |
| The exact wording of the warning depends on whether the compiler is allowed |
| to reorder the components in the record type or precluded from doing it by |
| means of pragma @code{No_Component_Reordering}. |
| |
| The default is that these warnings are not given. |
| @end table |
| |
| @geindex -gnatw.Q (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatw.Q} |
| |
| @emph{Suppress warnings on questionable layout of record types.} |
| |
| This switch suppresses warnings for cases where the default layout of |
| a record type would very likely cause inefficiencies. |
| @end table |
| |
| @geindex -gnatwr (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatwr} |
| |
| @emph{Activate warnings on redundant constructs.} |
| |
| This switch activates warnings for redundant constructs. The following |
| is the current list of constructs regarded as redundant: |
| |
| |
| @itemize * |
| |
| @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 an object or (unary or binary) operation of boolean type to |
| an explicit True value. |
| @end itemize |
| |
| The default is that warnings for redundant constructs are not given. |
| @end table |
| |
| @geindex -gnatwR (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatwR} |
| |
| @emph{Suppress warnings on redundant constructs.} |
| |
| This switch suppresses warnings for redundant constructs. |
| @end table |
| |
| @geindex -gnatw.r (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatw.r} |
| |
| @emph{Activate warnings for object renaming function.} |
| |
| 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. |
| @end table |
| |
| @geindex -gnatw.R (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatw.R} |
| |
| @emph{Suppress warnings for object renaming function.} |
| |
| This switch suppresses warnings for object renaming function. |
| @end table |
| |
| @geindex -gnatw_r (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatw_r} |
| |
| @emph{Activate warnings for out-of-order record representation clauses.} |
| |
| This switch activates warnings for record representation clauses, |
| if the order of component declarations, component clauses, |
| and bit-level layout do not all agree. |
| The default is that these warnings are not given. |
| @end table |
| |
| @geindex -gnatw_R (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatw_R} |
| |
| @emph{Suppress warnings for out-of-order record representation clauses.} |
| @end table |
| |
| @geindex -gnatws (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatws} |
| |
| @emph{Suppress all warnings.} |
| |
| 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 @code{-gnatwn}. |
| |
| Note that switch @code{-gnatws} does not suppress |
| warnings from the @code{gcc} back end. |
| To suppress these back end warnings as well, use the switch @code{-w} |
| in addition to @code{-gnatws}. Also this switch has no effect on the |
| handling of style check messages. |
| @end table |
| |
| @geindex -gnatw.s (gcc) |
| |
| @geindex Record Representation (component sizes) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatw.s} |
| |
| @emph{Activate warnings on overridden size clauses.} |
| |
| 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. |
| @end table |
| |
| @geindex -gnatw.S (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatw.S} |
| |
| @emph{Suppress warnings on overridden size clauses.} |
| |
| 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. |
| @end table |
| |
| @geindex -gnatwt (gcc) |
| |
| @geindex Deactivated code |
| @geindex warnings |
| |
| @geindex Deleted code |
| @geindex warnings |
| |
| |
| @table @asis |
| |
| @item @code{-gnatwt} |
| |
| @emph{Activate warnings for tracking of deleted conditional code.} |
| |
| 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. This may be |
| useful for detecting deactivated code in certified applications. |
| @end table |
| |
| @geindex -gnatwT (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatwT} |
| |
| @emph{Suppress warnings for tracking of deleted conditional code.} |
| |
| This switch suppresses warnings for tracking of deleted conditional code. |
| @end table |
| |
| @geindex -gnatw.t (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatw.t} |
| |
| @emph{Activate warnings on suspicious contracts.} |
| |
| This switch activates warnings on suspicious contracts. This includes |
| warnings on suspicious postconditions (whether a pragma @code{Postcondition} or a |
| @code{Post} aspect in Ada 2012) and suspicious contract cases (pragma or aspect |
| @code{Contract_Cases}). 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. This switch also controls |
| warnings on suspicious cases of expressions typically found in contracts like |
| quantified expressions and uses of Update attribute. The default is that such |
| warnings are generated. |
| @end table |
| |
| @geindex -gnatw.T (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatw.T} |
| |
| @emph{Suppress warnings on suspicious contracts.} |
| |
| This switch suppresses warnings on suspicious contracts. |
| @end table |
| |
| @geindex -gnatwu (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatwu} |
| |
| @emph{Activate warnings on unused entities.} |
| |
| This switch activates warnings to be generated for entities that |
| are declared but not referenced, and for units that are @emph{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 @emph{with}ed but never instantiated. |
| In the case where a package or subprogram body is compiled, and there |
| is a @emph{with} on the corresponding spec |
| that is only referenced in the body, |
| a warning is also generated, noting that the |
| @emph{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 @code{-gnatwf}). |
| @end table |
| |
| @geindex -gnatwU (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatwU} |
| |
| @emph{Suppress warnings on unused entities.} |
| |
| This switch suppresses warnings for unused entities and packages. |
| It also turns off warnings on unreferenced formals (and thus includes |
| the effect of @code{-gnatwF}). |
| @end table |
| |
| @geindex -gnatw.u (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatw.u} |
| |
| @emph{Activate warnings on unordered enumeration types.} |
| |
| 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{GNAT Reference Manual} for further details. |
| The default is that such warnings are not generated. |
| @end table |
| |
| @geindex -gnatw.U (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatw.U} |
| |
| @emph{Deactivate warnings on unordered enumeration types.} |
| |
| This switch causes all enumeration types to be considered as ordered, so |
| that no warnings are given for comparisons or subranges for any type. |
| @end table |
| |
| @geindex -gnatwv (gcc) |
| |
| @geindex Unassigned variable warnings |
| |
| |
| @table @asis |
| |
| @item @code{-gnatwv} |
| |
| @emph{Activate warnings on unassigned variables.} |
| |
| This switch activates warnings for access to variables which |
| may not be properly initialized. The default is that |
| such warnings are generated. This switch will also be emitted when |
| initializing an array or record object via the following aggregate: |
| |
| @example |
| Array_Or_Record : XXX := (others => <>); |
| @end example |
| |
| unless the relevant type fully initializes all components. |
| @end table |
| |
| @geindex -gnatwV (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatwV} |
| |
| @emph{Suppress warnings on unassigned variables.} |
| |
| This switch suppresses warnings for access to variables which |
| may not be properly initialized. |
| @end table |
| |
| @geindex -gnatw.v (gcc) |
| |
| @geindex bit order warnings |
| |
| |
| @table @asis |
| |
| @item @code{-gnatw.v} |
| |
| @emph{Activate info messages for non-default bit order.} |
| |
| 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. |
| @end table |
| |
| @geindex -gnatw.V (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatw.V} |
| |
| @emph{Suppress info messages for non-default bit order.} |
| |
| This switch suppresses information messages for the effects of specifying |
| non-default bit order on record components with component clauses. |
| @end table |
| |
| @geindex -gnatww (gcc) |
| |
| @geindex String indexing warnings |
| |
| |
| @table @asis |
| |
| @item @code{-gnatww} |
| |
| @emph{Activate warnings on wrong low bound assumption.} |
| |
| 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. |
| @end table |
| |
| @geindex -gnatwW (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatwW} |
| |
| @emph{Suppress warnings on wrong low bound assumption.} |
| |
| 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: |
| |
| @example |
| procedure K (S : String) is |
| pragma Assert (S'First = 1); |
| ... |
| @end example |
| @end table |
| |
| @geindex -gnatw.w (gcc) |
| |
| @geindex Warnings Off control |
| |
| |
| @table @asis |
| |
| @item @code{-gnatw.w} |
| |
| @emph{Activate warnings on Warnings Off pragmas.} |
| |
| 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}. |
| Also activates warnings for the case of |
| Warnings (Off, String), where either there is no matching |
| Warnings (On, String), or the Warnings (Off) did not suppress any warning. |
| The default is that these warnings are not given. |
| @end table |
| |
| @geindex -gnatw.W (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatw.W} |
| |
| @emph{Suppress warnings on unnecessary Warnings Off pragmas.} |
| |
| This switch suppresses warnings for use of @code{pragma Warnings (Off, ...)}. |
| @end table |
| |
| @geindex -gnatwx (gcc) |
| |
| @geindex Export/Import pragma warnings |
| |
| |
| @table @asis |
| |
| @item @code{-gnatwx} |
| |
| @emph{Activate warnings on Export/Import pragmas.} |
| |
| 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. |
| @end table |
| |
| @geindex -gnatwX (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatwX} |
| |
| @emph{Suppress warnings on Export/Import pragmas.} |
| |
| 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. |
| @end table |
| |
| @geindex -gnatwm (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatw.x} |
| |
| @emph{Activate warnings for No_Exception_Propagation mode.} |
| |
| 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 given for units that contain exception handlers. |
| |
| @item @code{-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. |
| @end table |
| |
| @geindex -gnatwy (gcc) |
| |
| @geindex Ada compatibility issues warnings |
| |
| |
| @table @asis |
| |
| @item @code{-gnatwy} |
| |
| @emph{Activate warnings for Ada compatibility issues.} |
| |
| 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. |
| @end table |
| |
| @geindex -gnatwY (gcc) |
| |
| @geindex Ada compatibility issues warnings |
| |
| |
| @table @asis |
| |
| @item @code{-gnatwY} |
| |
| @emph{Disable warnings for Ada compatibility issues.} |
| |
| This switch suppresses the warnings intended to help in identifying |
| incompatibilities between Ada language versions. |
| @end table |
| |
| @geindex -gnatw.y (gcc) |
| |
| @geindex Package spec needing body |
| |
| |
| @table @asis |
| |
| @item @code{-gnatw.y} |
| |
| @emph{Activate information messages for why package spec needs body.} |
| |
| There are a number of cases in which a package spec needs a body. |
| For example, the use of pragma Elaborate_Body, or the declaration |
| of a procedure specification requiring a completion. This switch |
| causes information messages to be output showing why a package |
| specification requires a body. This can be useful in the case of |
| a large package specification which is unexpectedly requiring a |
| body. The default is that such information messages are not output. |
| @end table |
| |
| @geindex -gnatw.Y (gcc) |
| |
| @geindex No information messages for why package spec needs body |
| |
| |
| @table @asis |
| |
| @item @code{-gnatw.Y} |
| |
| @emph{Disable information messages for why package spec needs body.} |
| |
| This switch suppresses the output of information messages showing why |
| a package specification needs a body. |
| @end table |
| |
| @geindex -gnatwz (gcc) |
| |
| @geindex Unchecked_Conversion warnings |
| |
| |
| @table @asis |
| |
| @item @code{-gnatwz} |
| |
| @emph{Activate warnings on unchecked conversions.} |
| |
| 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. |
| @end table |
| |
| @geindex -gnatwZ (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatwZ} |
| |
| @emph{Suppress warnings on unchecked conversions.} |
| |
| This switch suppresses warnings for unchecked conversions |
| where the types are known at compile time to have different |
| sizes or conventions. |
| @end table |
| |
| @geindex -gnatw.z (gcc) |
| |
| @geindex Size/Alignment warnings |
| |
| |
| @table @asis |
| |
| @item @code{-gnatw.z} |
| |
| @emph{Activate warnings for size not a multiple of alignment.} |
| |
| This switch activates warnings for cases of array and record types |
| with specified @code{Size} and @code{Alignment} attributes where the |
| size is not a multiple of the alignment, resulting in an object |
| size that is greater than the specified size. The default |
| is that such warnings are generated. |
| @end table |
| |
| @geindex -gnatw.Z (gcc) |
| |
| @geindex Size/Alignment warnings |
| |
| |
| @table @asis |
| |
| @item @code{-gnatw.Z} |
| |
| @emph{Suppress warnings for size not a multiple of alignment.} |
| |
| This switch suppresses warnings for cases of array and record types |
| with specified @code{Size} and @code{Alignment} attributes where the |
| size is not a multiple of the alignment, resulting in an object |
| size that is greater than the specified size. The warning can also |
| be suppressed by giving an explicit @code{Object_Size} value. |
| @end table |
| |
| @geindex -Wunused (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-Wunused} |
| |
| The warnings controlled by the @code{-gnatw} switch are generated by |
| the front end of the compiler. The GCC back end can provide |
| additional warnings and they are controlled by the @code{-W} switch. |
| For example, @code{-Wunused} activates back end |
| warnings for entities that are declared but not referenced. |
| @end table |
| |
| @geindex -Wuninitialized (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-Wuninitialized} |
| |
| Similarly, @code{-Wuninitialized} activates |
| the back end warning for uninitialized variables. This switch must be |
| used in conjunction with an optimization level greater than zero. |
| @end table |
| |
| @geindex -Wstack-usage (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-Wstack-usage=@emph{len}} |
| |
| Warn if the stack usage of a subprogram might be larger than @code{len} bytes. |
| See @ref{e6,,Static Stack Usage Analysis} for details. |
| @end table |
| |
| @geindex -Wall (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-Wall} |
| |
| This switch enables most warnings from the GCC back end. |
| The code generator detects a number of warning situations that are missed |
| by the 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 |
| @code{-gnatwa}, that is, most front-end warnings are activated as well. |
| @end table |
| |
| @geindex -w (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-w} |
| |
| Conversely, this switch suppresses warnings from the GCC back end. |
| The use of this switch also sets the default front-end warning mode to |
| @code{-gnatws}, that is, front-end warnings are suppressed as well. |
| @end table |
| |
| @geindex -Werror (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-Werror} |
| |
| This switch causes warnings from the GCC back end 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. |
| The use of this switch also sets the default front-end warning mode to |
| @code{-gnatwe}, that is, front-end warning messages and style check |
| messages are treated as errors as well. |
| @end table |
| |
| A string of warning parameters can be used in the same parameter. For example: |
| |
| @example |
| -gnatwaGe |
| @end example |
| |
| will turn on all optional warnings except for unrecognized pragma warnings, |
| and also specify that warnings should be treated as errors. |
| |
| When no switch @code{-gnatw} is used, this is equivalent to: |
| |
| @quotation |
| |
| |
| @itemize * |
| |
| @item |
| @code{-gnatw.a} |
| |
| @item |
| @code{-gnatwB} |
| |
| @item |
| @code{-gnatw.b} |
| |
| @item |
| @code{-gnatwC} |
| |
| @item |
| @code{-gnatw.C} |
| |
| @item |
| @code{-gnatwD} |
| |
| @item |
| @code{-gnatw.D} |
| |
| @item |
| @code{-gnatwF} |
| |
| @item |
| @code{-gnatw.F} |
| |
| @item |
| @code{-gnatwg} |
| |
| @item |
| @code{-gnatwH} |
| |
| @item |
| @code{-gnatw.H} |
| |
| @item |
| @code{-gnatwi} |
| |
| @item |
| @code{-gnatwJ} |
| |
| @item |
| @code{-gnatw.J} |
| |
| @item |
| @code{-gnatwK} |
| |
| @item |
| @code{-gnatw.K} |
| |
| @item |
| @code{-gnatwL} |
| |
| @item |
| @code{-gnatw.L} |
| |
| @item |
| @code{-gnatwM} |
| |
| @item |
| @code{-gnatw.m} |
| |
| @item |
| @code{-gnatwn} |
| |
| @item |
| @code{-gnatw.N} |
| |
| @item |
| @code{-gnatwo} |
| |
| @item |
| @code{-gnatw.O} |
| |
| @item |
| @code{-gnatwP} |
| |
| @item |
| @code{-gnatw.P} |
| |
| @item |
| @code{-gnatwq} |
| |
| @item |
| @code{-gnatw.Q} |
| |
| @item |
| @code{-gnatwR} |
| |
| @item |
| @code{-gnatw.R} |
| |
| @item |
| @code{-gnatw.S} |
| |
| @item |
| @code{-gnatwT} |
| |
| @item |
| @code{-gnatw.t} |
| |
| @item |
| @code{-gnatwU} |
| |
| @item |
| @code{-gnatw.U} |
| |
| @item |
| @code{-gnatwv} |
| |
| @item |
| @code{-gnatw.v} |
| |
| @item |
| @code{-gnatww} |
| |
| @item |
| @code{-gnatw.W} |
| |
| @item |
| @code{-gnatwx} |
| |
| @item |
| @code{-gnatw.X} |
| |
| @item |
| @code{-gnatwy} |
| |
| @item |
| @code{-gnatw.Y} |
| |
| @item |
| @code{-gnatwz} |
| |
| @item |
| @code{-gnatw.z} |
| @end itemize |
| @end quotation |
| |
| @node Debugging and Assertion Control,Validity Checking,Warning Message Control,Compiler Switches |
| @anchor{gnat_ugn/building_executable_programs_with_gnat debugging-and-assertion-control}@anchor{f1}@anchor{gnat_ugn/building_executable_programs_with_gnat id16}@anchor{f2} |
| @subsection Debugging and Assertion Control |
| |
| |
| @geindex -gnata (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnata} |
| |
| @geindex Assert |
| |
| @geindex Debug |
| |
| @geindex Assertions |
| |
| @geindex Precondition |
| |
| @geindex Postcondition |
| |
| @geindex Type invariants |
| |
| @geindex Subtype predicates |
| |
| The @code{-gnata} option is equivalent to the following @code{Assertion_Policy} pragma: |
| |
| @example |
| pragma Assertion_Policy (Check); |
| @end example |
| |
| Which is a shorthand for: |
| |
| @example |
| pragma Assertion_Policy |
| (Assert => Check, |
| Static_Predicate => Check, |
| Dynamic_Predicate => Check, |
| Pre => Check, |
| Pre'Class => Check, |
| Post => Check, |
| Post'Class => Check, |
| Type_Invariant => Check, |
| Type_Invariant'Class => Check); |
| @end example |
| |
| The pragmas @code{Assert} and @code{Debug} normally have no effect and |
| are ignored. This switch, where @code{a} stands for ‘assert’, causes |
| pragmas @code{Assert} and @code{Debug} to be activated. This switch also |
| causes preconditions, postconditions, subtype predicates, and |
| type invariants to be activated. |
| |
| The pragmas have the form: |
| |
| @example |
| pragma Assert (<Boolean-expression> [, <static-string-expression>]) |
| pragma Debug (<procedure call>) |
| pragma Type_Invariant (<type-local-name>, <Boolean-expression>) |
| pragma Predicate (<type-local-name>, <Boolean-expression>) |
| pragma Precondition (<Boolean-expression>, <string-expression>) |
| pragma Postcondition (<Boolean-expression>, <string-expression>) |
| @end example |
| |
| The aspects have the form: |
| |
| @example |
| with [Pre|Post|Type_Invariant|Dynamic_Predicate|Static_Predicate] |
| => <Boolean-expression>; |
| @end example |
| |
| The @code{Assert} pragma causes @code{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 @code{static-string-expression}, if |
| present, as the message associated with the exception). If no string |
| expression is given, the default is a string containing the file name and |
| line number of the pragma. |
| |
| The @code{Debug} pragma causes @code{procedure} to be called. Note that |
| @code{pragma Debug} may appear within a declaration sequence, allowing |
| debugging procedures to be called between declarations. |
| |
| For the aspect specification, the @code{Boolean-expression} is evaluated. |
| If the result is @code{True}, the aspect has no effect. If the result |
| is @code{False}, the exception @code{Assert_Failure} is raised. |
| @end table |
| |
| @node Validity Checking,Style Checking,Debugging and Assertion Control,Compiler Switches |
| @anchor{gnat_ugn/building_executable_programs_with_gnat id17}@anchor{f3}@anchor{gnat_ugn/building_executable_programs_with_gnat validity-checking}@anchor{e7} |
| @subsection Validity Checking |
| |
| |
| @geindex Validity Checking |
| |
| 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 @code{-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 @code{-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, and in particular |
| we do not recommend using these extra validity checking options in |
| combination with optimization, since this can confuse the optimizer. |
| If performance is a consideration, leading to the need to optimize, |
| then the validity checking options should not be used. |
| |
| The other @code{-gnatV@emph{x}} switches below allow finer-grained |
| control; you can enable whichever validity checks you desire. However, |
| for most debugging purposes, @code{-gnatVa} is sufficient, and the |
| default @code{-gnatVd} (i.e. standard Ada behavior) is usually |
| sufficient for non-debugging use. |
| |
| The @code{-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 @code{-gnatV@emph{x}} switch allows control over the validity |
| checking mode as described below. |
| 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. |
| |
| @geindex -gnatVa (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatVa} |
| |
| @emph{All validity checks.} |
| |
| All validity checks are turned on. |
| That is, @code{-gnatVa} is |
| equivalent to @code{gnatVcdfimoprst}. |
| @end table |
| |
| @geindex -gnatVc (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatVc} |
| |
| @emph{Validity checks for copies.} |
| |
| The right hand side of assignments, and the initializing values of |
| object declarations are validity checked. |
| @end table |
| |
| @geindex -gnatVd (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatVd} |
| |
| @emph{Default (RM) validity checks.} |
| |
| 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 @code{-gnatVD}. |
| They are turned on by default. If @code{-gnatVD} is specified, a subsequent |
| switch @code{-gnatVd} will leave the checks turned on. |
| Switch @code{-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. |
| @end table |
| |
| @geindex -gnatVe (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatVe} |
| |
| @emph{Validity checks for elementary components.} |
| |
| In the absence of this switch, assignments to record or array components are |
| not validity checked, even if validity checks for assignments generally |
| (@code{-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. |
| @end table |
| |
| @geindex -gnatVf (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatVf} |
| |
| @emph{Validity checks for floating-point values.} |
| |
| In the absence of this switch, validity checking occurs only for discrete |
| values. If @code{-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, @code{-gnatVif} or @code{-gnatVfi} |
| (the order does not matter) specifies that floating-point parameters of mode |
| @code{in} should be validity checked. |
| @end table |
| |
| @geindex -gnatVi (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatVi} |
| |
| @emph{Validity checks for `@w{`}in`@w{`} mode parameters.} |
| |
| Arguments for parameters of mode @code{in} are validity checked in function |
| and procedure calls at the point of call. |
| @end table |
| |
| @geindex -gnatVm (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatVm} |
| |
| @emph{Validity checks for `@w{`}in out`@w{`} mode parameters.} |
| |
| 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. |
| @end table |
| |
| @geindex -gnatVn (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatVn} |
| |
| @emph{No validity checks.} |
| |
| 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 @code{-gnatp} suppresses all run-time checks, including |
| validity checks, and thus implies @code{-gnatVn}. When this switch |
| is used, it cancels any other @code{-gnatV} previously issued. |
| @end table |
| |
| @geindex -gnatVo (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatVo} |
| |
| @emph{Validity checks for operator and attribute operands.} |
| |
| 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 @code{..} (e.g., slices, loops etc). |
| @end table |
| |
| @geindex -gnatVp (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatVp} |
| |
| @emph{Validity checks for parameters.} |
| |
| This controls the treatment of parameters within a subprogram (as opposed |
| to @code{-gnatVi} and @code{-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 @code{-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. |
| @end table |
| |
| @geindex -gnatVr (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatVr} |
| |
| @emph{Validity checks for function returns.} |
| |
| The expression in @code{return} statements in functions is validity |
| checked. |
| @end table |
| |
| @geindex -gnatVs (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatVs} |
| |
| @emph{Validity checks for subscripts.} |
| |
| 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). |
| @end table |
| |
| @geindex -gnatVt (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatVt} |
| |
| @emph{Validity checks for tests.} |
| |
| 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 |
| |
| The @code{-gnatV} switch may be followed by a string of letters |
| to turn on a series of validity checking options. |
| For example, @code{-gnatVcr} |
| 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, |
| the upper case letters @code{CDFIMORST} may |
| be used to turn off the corresponding lower case option. |
| Thus @code{-gnatVaM} turns on all validity checking options except for |
| checking of @code{in out} parameters. |
| |
| The specification of additional validity checking generates extra code (and |
| in the case of @code{-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,Run-Time Checks,Validity Checking,Compiler Switches |
| @anchor{gnat_ugn/building_executable_programs_with_gnat id18}@anchor{f4}@anchor{gnat_ugn/building_executable_programs_with_gnat style-checking}@anchor{ec} |
| @subsection Style Checking |
| |
| |
| @geindex Style checking |
| |
| @geindex -gnaty (gcc) |
| |
| The @code{-gnatyx} switch 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 @code{-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. |
| |
| |
| The string @code{x} is a sequence of letters or digits |
| indicating the particular style |
| checks to be performed. The following checks are defined: |
| |
| @geindex -gnaty[0-9] (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnaty0} |
| |
| @emph{Specify indentation level.} |
| |
| If a digit from 1-9 appears |
| in the string after @code{-gnaty} |
| then proper indentation is checked, with the digit indicating the |
| indentation level required. A value of zero turns off this style check. |
| The rule checks that the following constructs start on a column that is |
| a multiple of the alignment level: |
| |
| |
| @itemize * |
| |
| @item |
| beginnings of declarations (except record component declarations) |
| and statements; |
| |
| @item |
| beginnings of the structural components of compound statements; |
| |
| @item |
| @code{end} keyword that completes the declaration of a program unit declaration |
| or body or that completes a compound statement. |
| @end itemize |
| |
| 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, or they may be aligned with the source line on the previous |
| non-blank line. |
| @end table |
| |
| @geindex -gnatya (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatya} |
| |
| @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. |
| @end table |
| |
| @geindex -gnatyA (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatyA} |
| |
| @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. |
| @end table |
| |
| @geindex -gnatyb (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatyb} |
| |
| @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. |
| @end table |
| |
| @geindex -gnatyB (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatyB} |
| |
| @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}/@cite{or else} are |
| required. |
| @end table |
| |
| @geindex -gnatyc (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatyc} |
| |
| @emph{Check comments, double space.} |
| |
| Comments must meet the following set of rules: |
| |
| |
| @itemize * |
| |
| @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 from specialized tools |
| such as @code{gnatprep} (where @code{--!} is used) and in earlier versions of the SPARK |
| annotation |
| language (where @code{--#} is used). For the purposes of this rule, a |
| special character is defined as being in one of the ASCII ranges |
| @code{16#21#...16#2F#} or @code{16#3A#...16#3F#}. |
| Note that this usage is not permitted |
| in GNAT implementation units (i.e., when @code{-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: |
| |
| @example |
| --------------------------- |
| -- This is a box comment -- |
| -- with two text lines. -- |
| --------------------------- |
| @end example |
| @end itemize |
| @end table |
| |
| @geindex -gnatyC (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatyC} |
| |
| @emph{Check comments, single space.} |
| |
| This is identical to @code{c} except that only one space |
| is required following the @code{--} of a comment instead of two. |
| @end table |
| |
| @geindex -gnatyd (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatyd} |
| |
| @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). |
| @end table |
| |
| @geindex -gnatyD (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatyD} |
| |
| @emph{Check declared identifiers in mixed case.} |
| |
| Declared identifiers must be in mixed case, as in |
| This_Is_An_Identifier. Use -gnatyr in addition to ensure |
| that references match declarations. |
| @end table |
| |
| @geindex -gnatye (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatye} |
| |
| @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. |
| @end table |
| |
| @geindex -gnatyf (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatyf} |
| |
| @emph{No form feeds or vertical tabs.} |
| |
| Neither form feeds nor vertical tab characters are permitted |
| in the source text. |
| @end table |
| |
| @geindex -gnatyg (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatyg} |
| |
| @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. Currently this is equivalent to @code{-gnatyydISux}) |
| but additional style switches may be added to this set in the future without |
| advance notice. |
| @end table |
| |
| @geindex -gnatyh (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatyh} |
| |
| @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. |
| @end table |
| |
| @geindex -gnatyi (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatyi} |
| |
| @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}. |
| @end table |
| |
| @geindex -gnatyI (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatyI} |
| |
| @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. |
| @end table |
| |
| @geindex -gnatyk (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatyk} |
| |
| @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). A single error is reported for each line breaking |
| this rule even if multiple casing issues exist on a same line. |
| @end table |
| |
| @geindex -gnatyl (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatyl} |
| |
| @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: |
| |
| @example |
| 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 example |
| |
| 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: |
| |
| @example |
| Block : declare |
| A : Integer := 3; |
| begin |
| Proc (A, A); |
| end Block; |
| |
| Block : |
| declare |
| A : Integer := 3; |
| begin |
| Proc (A, A); |
| end Block; |
| @end example |
| |
| The same alternative format is allowed for loops. For example, both of |
| the following are permitted: |
| |
| @example |
| Clear : while J < 10 loop |
| A (J) := 0; |
| end loop Clear; |
| |
| Clear : |
| while J < 10 loop |
| A (J) := 0; |
| end loop Clear; |
| @end example |
| @end table |
| |
| @geindex -gnatyLnnn (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatyL} |
| |
| @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 |
| @emph{nnn}. A value of zero disconnects this style check. |
| @end table |
| |
| @geindex -gnatym (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatym} |
| |
| @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). |
| @end table |
| |
| @geindex -gnatyMnnn (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatyM} |
| |
| @emph{Set maximum line length.} |
| |
| The length of lines must not exceed the |
| given value @emph{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. |
| @end table |
| |
| @geindex -gnatyn (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatyn} |
| |
| @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}). |
| @end table |
| |
| @geindex -gnatyN (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatyN} |
| |
| @emph{Turn off all style checks.} |
| |
| All style check options are turned off. |
| @end table |
| |
| @geindex -gnatyo (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatyo} |
| |
| @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). |
| @end table |
| |
| @geindex -gnatyO (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatyO} |
| |
| @emph{Check that overriding subprograms are explicitly marked as such.} |
| |
| This applies to all subprograms of a derived type that override a primitive |
| operation of the type, for both tagged and untagged types. In particular, |
| the declaration of a primitive operation of a type extension that overrides |
| an inherited operation must carry an overriding indicator. Another case is |
| the declaration of a function that overrides a predefined operator (such |
| as an equality operator). |
| @end table |
| |
| @geindex -gnatyp (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatyp} |
| |
| @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. An exception is that SPARK_Mode is |
| allowed as an alternative for Spark_Mode. |
| @end table |
| |
| @geindex -gnatyr (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatyr} |
| |
| @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. |
| @end table |
| |
| @geindex -gnatys (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatys} |
| |
| @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. |
| @end table |
| |
| @geindex -gnatyS (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatyS} |
| |
| @emph{Check no statements after then/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}. |
| @end table |
| |
| @geindex -gnatyt (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatyt} |
| |
| @emph{Check token spacing.} |
| |
| The following token spacing rules are enforced: |
| |
| |
| @itemize * |
| |
| @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 |
| |
| Exactly one blank (and no other white space) must appear between |
| a @code{not} token and a following @code{in} token. |
| @end table |
| |
| @geindex -gnatyu (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatyu} |
| |
| @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. |
| @end table |
| |
| @geindex -gnatyx (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatyx} |
| |
| @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. |
| @end table |
| |
| @geindex -gnatyy (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatyy} |
| |
| @emph{Set all standard style check options.} |
| |
| This is equivalent to @code{gnaty3aAbcefhiklmnprst}, that is all checking |
| options enabled with the exception of @code{-gnatyB}, @code{-gnatyd}, |
| @code{-gnatyI}, @code{-gnatyLnnn}, @code{-gnatyo}, @code{-gnatyO}, |
| @code{-gnatyS}, @code{-gnatyu}, and @code{-gnatyx}. |
| @end table |
| |
| @geindex -gnaty- (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnaty-} |
| |
| @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 the @code{L} parameter without any integer value after that, because any |
| digit following @emph{-} in the parameter string of the @code{-gnaty} |
| option will be treated as canceling the indentation check. The same is true |
| for the @code{M} parameter. @code{y} and @code{N} parameters are not |
| allowed after @emph{-}. |
| @end table |
| |
| @geindex -gnaty+ (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnaty+} |
| |
| @emph{Enable style check options.} |
| |
| This causes any subsequent options in the string to enable the corresponding |
| style check option. That is, it cancels the effect of a previous -, |
| if any. |
| @end table |
| |
| @c end of switch description (leave this comment to ease automatic parsing for |
| |
| @c GNAT Studio |
| |
| 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. |
| |
| 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 ‘@cite{(style)}’. Note that these messages are treated as warning |
| messages, so they normally do not prevent the generation of an object |
| file. The @code{-gnatwe} switch can be used to treat warning messages, |
| including style messages, as fatal errors. |
| |
| The switch @code{-gnaty} on its own (that is not |
| followed by any letters or digits) is equivalent |
| to the use of @code{-gnatyy} as described above, that is all |
| built-in standard style check options are enabled. |
| |
| The switch @code{-gnatyN} clears any previously set style checks. |
| |
| @node Run-Time Checks,Using gcc for Syntax Checking,Style Checking,Compiler Switches |
| @anchor{gnat_ugn/building_executable_programs_with_gnat id19}@anchor{f5}@anchor{gnat_ugn/building_executable_programs_with_gnat run-time-checks}@anchor{ea} |
| @subsection Run-Time Checks |
| |
| |
| @geindex Division by zero |
| |
| @geindex Access before elaboration |
| |
| @geindex Checks |
| @geindex division by zero |
| |
| @geindex Checks |
| @geindex access before elaboration |
| |
| @geindex Checks |
| @geindex stack overflow checking |
| |
| By default, the following checks are suppressed: stack overflow |
| checks, and checks for access before elaboration on subprogram |
| calls. All other checks, including overflow checks, range checks and |
| array bounds checks, are turned on by default. The following @code{gcc} |
| switches refine this default behavior. |
| |
| @geindex -gnatp (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatp} |
| |
| @geindex Suppressing checks |
| |
| @geindex Checks |
| @geindex suppressing |
| |
| 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 @code{-gnatp} also implies @code{-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 erroneous |
| execution if that assumption is wrong. |
| |
| The checks subject to suppression include all the checks defined by the Ada |
| standard, the additional implementation defined checks @code{Alignment_Check}, |
| @code{Duplicated_Tag_Check}, @code{Predicate_Check}, @code{Container_Checks}, @code{Tampering_Check}, |
| and @code{Validity_Check}, as well as any checks introduced using @code{pragma Check_Name}. |
| Note that @code{Atomic_Synchronization} is not automatically suppressed by use of this option. |
| |
| If the code depends on certain checks being active, you can use |
| pragma @code{Unsuppress} either as a configuration pragma or as |
| a local pragma to make sure that a specified check is performed |
| even if @code{gnatp} is specified. |
| |
| The @code{-gnatp} switch has no effect if a subsequent |
| @code{-gnat-p} switch appears. |
| @end table |
| |
| @geindex -gnat-p (gcc) |
| |
| @geindex Suppressing checks |
| |
| @geindex Checks |
| @geindex suppressing |
| |
| @geindex Suppress |
| |
| |
| @table @asis |
| |
| @item @code{-gnat-p} |
| |
| This switch cancels the effect of a previous @code{gnatp} switch. |
| @end table |
| |
| @geindex -gnato?? (gcc) |
| |
| @geindex Overflow checks |
| |
| @geindex Overflow mode |
| |
| @geindex Check |
| @geindex overflow |
| |
| |
| @table @asis |
| |
| @item @code{-gnato??} |
| |
| 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 |
| |
| |
| @table @asis |
| |
| @item @emph{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 @emph{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 @emph{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 table |
| |
| If two digits are present after @code{-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 @code{-gnato} in previous versions of GNAT. |
| |
| @geindex Machine_Overflows |
| |
| Note that the @code{-gnato??} switch does not affect the code generated |
| for any floating-point operations; it applies only to integer semantics. |
| For floating-point, GNAT has the @code{Machine_Overflows} |
| attribute set to @code{False} and the normal mode of operation is to |
| generate IEEE NaN and infinite values on overflow or invalid operations |
| (such as dividing 0.0 by 0.0). |
| |
| The reason that we distinguish overflow checking from other kinds of |
| range constraint checking is that a failure of an overflow check, 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 @code{-gnato11} (equivalent to @code{-gnato1}), |
| so overflow checking is performed in STRICT mode by default. |
| @end table |
| |
| @geindex -gnatE (gcc) |
| |
| @geindex Elaboration checks |
| |
| @geindex Check |
| @geindex elaboration |
| |
| |
| @table @asis |
| |
| @item @code{-gnatE} |
| |
| Enables dynamic checks for access-before-elaboration |
| on subprogram calls and generic instantiations. |
| Note that @code{-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, |
| @ref{c7,,Compiling with gcc}. |
| @end table |
| |
| @geindex -fstack-check (gcc) |
| |
| @geindex Stack Overflow Checking |
| |
| @geindex Checks |
| @geindex stack overflow checking |
| |
| |
| @table @asis |
| |
| @item @code{-fstack-check} |
| |
| Activates stack overflow checking. For full details of the effect and use of |
| this switch see @ref{e5,,Stack Overflow Checking}. |
| @end table |
| |
| @geindex Unsuppress |
| |
| 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,Using gcc for Semantic Checking,Run-Time Checks,Compiler Switches |
| @anchor{gnat_ugn/building_executable_programs_with_gnat id20}@anchor{f6}@anchor{gnat_ugn/building_executable_programs_with_gnat using-gcc-for-syntax-checking}@anchor{f7} |
| @subsection Using @code{gcc} for Syntax Checking |
| |
| |
| @geindex -gnats (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnats} |
| |
| The @code{s} stands for ‘syntax’. |
| |
| Run GNAT in syntax checking only mode. For |
| example, the command |
| |
| @example |
| $ gcc -c -gnats x.adb |
| @end example |
| |
| compiles file @code{x.adb} in syntax-check-only mode. You can check a |
| series of files in a single command |
| , and can use wildcards to specify such a group of files. |
| Note that you must specify the @code{-c} (compile |
| only) flag in addition to the @code{-gnats} flag. |
| |
| You may use other switches in conjunction with @code{-gnats}. In |
| particular, @code{-gnatl} and @code{-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: |
| |
| @example |
| $ gcc -c -gnats -x ada toto.txt |
| toto.txt:1:01: warning: empty file, contains no compilation units |
| $ |
| @end example |
| |
| 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} |
| @emph{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}. |
| |
| @geindex Multiple units |
| @geindex 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 |
| (@ref{1d,,Renaming Files with gnatchop}). |
| @end table |
| |
| @node Using gcc for Semantic Checking,Compiling Different Versions of Ada,Using gcc for Syntax Checking,Compiler Switches |
| @anchor{gnat_ugn/building_executable_programs_with_gnat id21}@anchor{f8}@anchor{gnat_ugn/building_executable_programs_with_gnat using-gcc-for-semantic-checking}@anchor{f9} |
| @subsection Using @code{gcc} for Semantic Checking |
| |
| |
| @geindex -gnatc (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatc} |
| |
| The @code{c} stands for ‘check’. |
| 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 * |
| |
| @item |
| The needed source files must be accessible |
| (see @ref{73,,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 (@ref{3b,,File Naming Rules}). |
| @end itemize |
| |
| The output consists of error messages as appropriate. No object file is |
| generated. An @code{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,Character Set Control,Using gcc for Semantic Checking,Compiler Switches |
| @anchor{gnat_ugn/building_executable_programs_with_gnat compiling-different-versions-of-ada}@anchor{6}@anchor{gnat_ugn/building_executable_programs_with_gnat id22}@anchor{fa} |
| @subsection Compiling Different Versions of Ada |
| |
| |
| The switches described in this section allow you to explicitly specify |
| the version of the Ada language that your programs are written in. |
| The default mode is Ada 2012, |
| but you can also specify Ada 95, Ada 2005 mode, or |
| indicate Ada 83 compatibility mode. |
| |
| @geindex Compatibility with Ada 83 |
| |
| @geindex -gnat83 (gcc) |
| |
| @geindex ACVC |
| @geindex Ada 83 tests |
| |
| @geindex Ada 83 mode |
| |
| |
| @table @asis |
| |
| @item @code{-gnat83} (Ada 83 Compatibility Mode) |
| |
| 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 |
| @code{-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 |
| unconstrained |
| @geindex Generic formal parameters |
| 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 |
| @code{-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 the @emph{Compatibility and Porting Guide} chapter in the |
| @cite{GNAT Reference Manual}. |
| @end table |
| |
| @geindex -gnat95 (gcc) |
| |
| @geindex Ada 95 mode |
| |
| |
| @table @asis |
| |
| @item @code{-gnat95} (Ada 95 mode) |
| |
| 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 @code{-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 |
| @code{-gnat83}, @code{-gnat05/2005}, or @code{-gnat12/2012} |
| switch earlier in the command line. |
| @end table |
| |
| @geindex -gnat05 (gcc) |
| |
| @geindex -gnat2005 (gcc) |
| |
| @geindex Ada 2005 mode |
| |
| |
| @table @asis |
| |
| @item @code{-gnat05} or @code{-gnat2005} (Ada 2005 mode) |
| |
| 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 |
| @code{-gnat83} and @code{-gnat95} switches for further |
| information). |
| @end table |
| |
| @geindex -gnat12 (gcc) |
| |
| @geindex -gnat2012 (gcc) |
| |
| @geindex Ada 2012 mode |
| |
| |
| @table @asis |
| |
| @item @code{-gnat12} or @code{-gnat2012} (Ada 2012 mode) |
| |
| This switch directs the compiler to implement the Ada 2012 version of the |
| language (also the default). |
| 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 |
| @code{-gnat83}, @code{-gnat95}, and @code{-gnat05/2005} switches |
| for further information). |
| @end table |
| |
| @geindex -gnat2022 (gcc) |
| |
| @geindex Ada 2022 mode |
| |
| |
| @table @asis |
| |
| @item @code{-gnat2022} (Ada 2022 mode) |
| |
| This switch directs the compiler to implement the Ada 2022 version of the |
| language. |
| @end table |
| |
| @geindex -gnatX (gcc) |
| |
| @geindex Ada language extensions |
| |
| @geindex GNAT extensions |
| |
| |
| @table @asis |
| |
| @item @code{-gnatX} (Enable GNAT Extensions) |
| |
| This switch directs the compiler to implement the latest version of the |
| language (currently Ada 2022) 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, @code{Pragma Extensions_Allowed}. |
| @end table |
| |
| @node Character Set Control,File Naming Control,Compiling Different Versions of Ada,Compiler Switches |
| @anchor{gnat_ugn/building_executable_programs_with_gnat character-set-control}@anchor{31}@anchor{gnat_ugn/building_executable_programs_with_gnat id23}@anchor{fb} |
| @subsection Character Set Control |
| |
| |
| @geindex -gnati (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnati@emph{c}} |
| |
| 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. @code{c} is a |
| single character indicating the character set, as follows: |
| |
| |
| @multitable {xxxxxxxxxxxx} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx} |
| @item |
| |
| @emph{1} |
| |
| @tab |
| |
| ISO 8859-1 (Latin-1) identifiers |
| |
| @item |
| |
| @emph{2} |
| |
| @tab |
| |
| ISO 8859-2 (Latin-2) letters allowed in identifiers |
| |
| @item |
| |
| @emph{3} |
| |
| @tab |
| |
| ISO 8859-3 (Latin-3) letters allowed in identifiers |
| |
| @item |
| |
| @emph{4} |
| |
| @tab |
| |
| ISO 8859-4 (Latin-4) letters allowed in identifiers |
| |
| @item |
| |
| @emph{5} |
| |
| @tab |
| |
| ISO 8859-5 (Cyrillic) letters allowed in identifiers |
| |
| @item |
| |
| @emph{9} |
| |
| @tab |
| |
| ISO 8859-15 (Latin-9) letters allowed in identifiers |
| |
| @item |
| |
| @emph{p} |
| |
| @tab |
| |
| IBM PC letters (code page 437) allowed in identifiers |
| |
| @item |
| |
| @emph{8} |
| |
| @tab |
| |
| IBM PC letters (code page 850) allowed in identifiers |
| |
| @item |
| |
| @emph{f} |
| |
| @tab |
| |
| Full upper-half codes allowed in identifiers |
| |
| @item |
| |
| @emph{n} |
| |
| @tab |
| |
| No upper-half codes allowed in identifiers |
| |
| @item |
| |
| @emph{w} |
| |
| @tab |
| |
| Wide-character codes (that is, codes greater than 255) |
| allowed in identifiers |
| |
| @end multitable |
| |
| |
| See @ref{23,,Foreign Language Representation} for full details on the |
| implementation of these character sets. |
| @end table |
| |
| @geindex -gnatW (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatW@emph{e}} |
| |
| Specify the method of encoding for wide characters. |
| @code{e} is one of the following: |
| |
| |
| @multitable {xxxxxxxxxxxx} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx} |
| @item |
| |
| @emph{h} |
| |
| @tab |
| |
| Hex encoding (brackets coding also recognized) |
| |
| @item |
| |
| @emph{u} |
| |
| @tab |
| |
| Upper half encoding (brackets encoding also recognized) |
| |
| @item |
| |
| @emph{s} |
| |
| @tab |
| |
| Shift/JIS encoding (brackets encoding also recognized) |
| |
| @item |
| |
| @emph{e} |
| |
| @tab |
| |
| EUC encoding (brackets encoding also recognized) |
| |
| @item |
| |
| @emph{8} |
| |
| @tab |
| |
| UTF-8 encoding (brackets encoding also recognized) |
| |
| @item |
| |
| @emph{b} |
| |
| @tab |
| |
| Brackets encoding only (default value) |
| |
| @end multitable |
| |
| |
| For full details on these encoding |
| methods see @ref{37,,Wide_Character Encodings}. |
| Note that brackets coding is always accepted, even if one of the other |
| options is specified, so for example @code{-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 @code{-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 @code{-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,Subprogram Inlining Control,Character Set Control,Compiler Switches |
| @anchor{gnat_ugn/building_executable_programs_with_gnat file-naming-control}@anchor{fc}@anchor{gnat_ugn/building_executable_programs_with_gnat id24}@anchor{fd} |
| @subsection File Naming Control |
| |
| |
| @geindex -gnatk (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatk@emph{n}} |
| |
| Activates file name ‘krunching’. @code{n}, a decimal integer in the range |
| 1-999, indicates the maximum allowable length of a file name (not |
| including the @code{.ads} or @code{.adb} extension). The default is not |
| to enable file name krunching. |
| |
| For the source file naming rules, @ref{3b,,File Naming Rules}. |
| @end table |
| |
| @node Subprogram Inlining Control,Auxiliary Output Control,File Naming Control,Compiler Switches |
| @anchor{gnat_ugn/building_executable_programs_with_gnat id25}@anchor{fe}@anchor{gnat_ugn/building_executable_programs_with_gnat subprogram-inlining-control}@anchor{ff} |
| @subsection Subprogram Inlining Control |
| |
| |
| @geindex -gnatn (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatn[12]} |
| |
| The @code{n} here is intended to suggest the first syllable of the word ‘inline’. |
| GNAT recognizes and processes @code{Inline} pragmas. However, for inlining to |
| actually occur, optimization must be enabled and, by default, inlining of |
| subprograms across units is not performed. If you want to additionally |
| enable inlining of subprograms specified by pragma @code{Inline} across units, |
| you must also specify this switch. |
| |
| In the absence of this switch, GNAT does not attempt inlining across units |
| and does not 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 |
| units, which is a good compromise between compilation times and performances |
| at run time, or 2 for full inlining across units, 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 @code{-O1}, @code{-O2} or |
| @code{-Os} and 2 for @code{-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{100,,Inlining of Subprograms}. |
| @end table |
| |
| @geindex -gnatN (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatN} |
| |
| This switch activates front-end inlining which also |
| generates additional dependencies. |
| |
| When using a gcc-based back end, then the use of |
| @code{-gnatN} is deprecated, and the use of @code{-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,Debugging Control,Subprogram Inlining Control,Compiler Switches |
| @anchor{gnat_ugn/building_executable_programs_with_gnat auxiliary-output-control}@anchor{101}@anchor{gnat_ugn/building_executable_programs_with_gnat id26}@anchor{102} |
| @subsection Auxiliary Output Control |
| |
| |
| @geindex -gnatu (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatu} |
| |
| Print a list of units required by this compilation on @code{stdout}. |
| The listing includes all units on which the unit being compiled depends |
| either directly or indirectly. |
| @end table |
| |
| @geindex -pass-exit-codes (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-pass-exit-codes} |
| |
| If this switch is not used, the exit code returned by @code{gcc} when |
| compiling multiple files indicates whether all source files have |
| been successfully used to generate object files or not. |
| |
| When @code{-pass-exit-codes} is used, @code{gcc} exits with an extended |
| exit status and allows an integrated development environment to better |
| react to a compilation failure. Those exit status are: |
| |
| |
| @multitable {xxxxxxxxxxxx} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx} |
| @item |
| |
| @emph{5} |
| |
| @tab |
| |
| There was an error in at least one source file. |
| |
| @item |
| |
| @emph{3} |
| |
| @tab |
| |
| At least one source file did not generate an object file. |
| |
| @item |
| |
| @emph{2} |
| |
| @tab |
| |
| The compiler died unexpectedly (internal error for example). |
| |
| @item |
| |
| @emph{0} |
| |
| @tab |
| |
| An object file has been generated for every source file. |
| |
| @end multitable |
| |
| @end table |
| |
| @node Debugging Control,Exception Handling Control,Auxiliary Output Control,Compiler Switches |
| @anchor{gnat_ugn/building_executable_programs_with_gnat debugging-control}@anchor{103}@anchor{gnat_ugn/building_executable_programs_with_gnat id27}@anchor{104} |
| @subsection Debugging Control |
| |
| |
| @quotation |
| |
| @geindex Debugging options |
| @end quotation |
| |
| @geindex -gnatd (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatd@emph{x}} |
| |
| Activate internal debugging switches. @code{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 @code{debug.adb}. |
| @end table |
| |
| @geindex -gnatG (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatG[=@emph{nn}]} |
| |
| 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 @code{-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 @code{sprint.ads} for a full list. |
| |
| @geindex -gnatL (gcc) |
| |
| If the switch @code{-gnatL} is used in conjunction with |
| @code{-gnatG}, then the original source lines are interspersed |
| in the expanded source (as comment lines with the original line number). |
| |
| |
| @table @asis |
| |
| @item @code{new @emph{xxx} [storage_pool = @emph{yyy}]} |
| |
| Shows the storage pool being used for an allocator. |
| |
| @item @code{at end @emph{procedure-name};} |
| |
| Shows the finalization (cleanup) procedure for a scope. |
| |
| @item @code{(if @emph{expr} then @emph{expr} else @emph{expr})} |
| |
| Conditional expression equivalent to the @code{x?y:z} construction in C. |
| |
| @item @code{@emph{target}^(@emph{source})} |
| |
| A conversion with floating-point truncation instead of rounding. |
| |
| @item @code{@emph{target}?(@emph{source})} |
| |
| A conversion that bypasses normal Ada semantic checking. In particular |
| enumeration types and fixed-point types are treated simply as integers. |
| |
| @item @code{@emph{target}?^(@emph{source})} |
| |
| Combines the above two cases. |
| @end table |
| |
| @code{@emph{x} #/ @emph{y}} |
| |
| @code{@emph{x} #mod @emph{y}} |
| |
| @code{@emph{x} # @emph{y}} |
| |
| |
| @table @asis |
| |
| @item @code{@emph{x} #rem @emph{y}} |
| |
| A division or multiplication of fixed-point values which are treated as |
| integers without any kind of scaling. |
| |
| @item @code{free @emph{expr} [storage_pool = @emph{xxx}]} |
| |
| Shows the storage pool associated with a @code{free} statement. |
| |
| @item @code{[subtype or type declaration]} |
| |
| Used to list an equivalent declaration for an internally generated |
| type that is referenced elsewhere in the listing. |
| |
| @item @code{freeze @emph{type-name} [@emph{actions}]} |
| |
| Shows the point at which @code{type-name} is frozen, with possible |
| associated actions to be performed at the freeze point. |
| |
| @item @code{reference @emph{itype}} |
| |
| Reference (and hence definition) to internal type @code{itype}. |
| |
| @item @code{@emph{function-name}! (@emph{arg}, @emph{arg}, @emph{arg})} |
| |
| Intrinsic function call. |
| |
| @item @code{@emph{label-name} : label} |
| |
| Declaration of label @code{labelname}. |
| |
| @item @code{#$ @emph{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 @code{@emph{expr} && @emph{expr} && @emph{expr} ... && @emph{expr}} |
| |
| A multiple concatenation (same effect as @code{expr} & @code{expr} & |
| @code{expr}, but handled more efficiently). |
| |
| @item @code{[constraint_error]} |
| |
| Raise the @code{Constraint_Error} exception. |
| |
| @item @code{@emph{expression}'reference} |
| |
| A pointer to the result of evaluating @{expression@}. |
| |
| @item @code{@emph{target-type}!(@emph{source-expression})} |
| |
| An unchecked conversion of @code{source-expression} to @code{target-type}. |
| |
| @item @code{[@emph{numerator}/@emph{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 |
| @end table |
| |
| @geindex -gnatD (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatD[=nn]} |
| |
| When used in conjunction with @code{-gnatG}, this switch causes |
| the expanded source, as described above for |
| @code{-gnatG} to be written to files with names |
| @code{xxx.dg}, where @code{xxx} is the normal file name, |
| instead of to the standard output file. For |
| example, if the source file name is @code{hello.adb}, then a file |
| @code{hello.adb.dg} will be written. The debugging |
| information generated by the @code{gcc} @code{-g} switch |
| will refer to the generated @code{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 suppresses generation of cross-reference information (see |
| @code{-gnatx}) since otherwise the cross-reference information |
| would refer to the @code{.dg} file, which would cause |
| confusion since this is not the original source file. |
| |
| Note that @code{-gnatD} actually implies @code{-gnatG} |
| automatically, so it is not necessary to give both options. |
| In other words @code{-gnatD} is equivalent to @code{-gnatDG}). |
| |
| @geindex -gnatL (gcc) |
| |
| If the switch @code{-gnatL} is used in conjunction with |
| @code{-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. |
| @end table |
| |
| @geindex -gnatr (gcc) |
| |
| @geindex pragma Restrictions |
| |
| |
| @table @asis |
| |
| @item @code{-gnatr} |
| |
| 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. |
| @end table |
| |
| @geindex -gnatR (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatR[0|1|2|3|4][e][j][m][s]} |
| |
| This switch controls output from the compiler of a listing showing |
| representation information for declared types, objects and subprograms. |
| For @code{-gnatR0}, no information is output (equivalent to omitting |
| the @code{-gnatR} switch). For @code{-gnatR1} (which is the default, |
| so @code{-gnatR} with no parameter has the same effect), size and |
| alignment information is listed for declared array and record types. |
| |
| For @code{-gnatR2}, size and alignment information is listed for all |
| declared types and objects. The @code{Linker_Section} is also listed for any |
| entity for which the @code{Linker_Section} is set explicitly or implicitly (the |
| latter case occurs for objects of a type for which a @code{Linker_Section} |
| is set). |
| |
| For @code{-gnatR3}, symbolic expressions for values that are computed |
| at run time for records are included. These symbolic expressions have |
| a mostly obvious format with #n being used to represent the value of the |
| n’th discriminant. See source files @code{repinfo.ads/adb} in the |
| GNAT sources for full details on the format of @code{-gnatR3} output. |
| |
| For @code{-gnatR4}, information for relevant compiler-generated types |
| is also listed, i.e. when they are structurally part of other declared |
| types and objects. |
| |
| If the switch is followed by an @code{e} (e.g. @code{-gnatR2e}), then |
| extended representation information for record sub-components of records |
| is included. |
| |
| If the switch is followed by an @code{m} (e.g. @code{-gnatRm}), then |
| subprogram conventions and parameter passing mechanisms for all the |
| subprograms are included. |
| |
| If the switch is followed by a @code{j} (e.g., @code{-gnatRj}), then |
| the output is in the JSON data interchange format specified by the |
| ECMA-404 standard. The semantic description of this JSON output is |
| available in the specification of the Repinfo unit present in the |
| compiler sources. |
| |
| If the switch is followed by an @code{s} (e.g., @code{-gnatR3s}), then |
| the output is to a file with the name @code{file.rep} where @code{file} is |
| the name of the corresponding source file, except if @code{j} is also |
| specified, in which case the file name is @code{file.json}. |
| |
| 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}. |
| @end table |
| |
| @geindex -gnatS (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatS} |
| |
| The use of the switch @code{-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. |
| @end table |
| |
| @geindex -gnatx (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatx} |
| |
| Normally the compiler generates full cross-referencing information in |
| the @code{ALI} file. This information is used by a number of tools, |
| including @code{gnatfind} and @code{gnatxref}. The @code{-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 |
| |
| @geindex -fgnat-encodings (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-fgnat-encodings=[all|gdb|minimal]} |
| |
| This switch controls the balance between GNAT encodings and standard DWARF |
| emitted in the debug information. |
| |
| Historically, old debug formats like stabs were not powerful enough to |
| express some Ada types (for instance, variant records or fixed-point types). |
| To work around this, GNAT introduced proprietary encodings that embed the |
| missing information (“GNAT encodings”). |
| |
| Recent versions of the DWARF debug information format are now able to |
| correctly describe most of these Ada constructs (“standard DWARF”). As |
| third-party tools started to use this format, GNAT has been enhanced to |
| generate it. However, most tools (including GDB) are still relying on GNAT |
| encodings. |
| |
| To support all tools, GNAT needs to be versatile about the balance between |
| generation of GNAT encodings and standard DWARF. This is what |
| @code{-fgnat-encodings} is about. |
| |
| |
| @itemize * |
| |
| @item |
| @code{=all}: Emit all GNAT encodings, and then emit as much standard DWARF as |
| possible so it does not conflict with GNAT encodings. |
| |
| @item |
| @code{=gdb}: Emit as much standard DWARF as possible as long as the current |
| GDB handles it. Emit GNAT encodings for the rest. |
| |
| @item |
| @code{=minimal}: Emit as much standard DWARF as possible and emit GNAT |
| encodings for the rest. |
| @end itemize |
| @end table |
| |
| @node Exception Handling Control,Units to Sources Mapping Files,Debugging Control,Compiler Switches |
| @anchor{gnat_ugn/building_executable_programs_with_gnat exception-handling-control}@anchor{105}@anchor{gnat_ugn/building_executable_programs_with_gnat id28}@anchor{106} |
| @subsection Exception Handling Control |
| |
| |
| 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 @code{-funwind-tables} GCC’s |
| option. |
| |
| The following switches may be used to control which of the |
| two exception handling methods is used. |
| |
| @geindex --RTS=sjlj (gnatmake) |
| |
| |
| @table @asis |
| |
| @item @code{--RTS=sjlj} |
| |
| 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. |
| @end table |
| |
| @geindex --RTS=zcx (gnatmake) |
| |
| @geindex Zero Cost Exceptions |
| |
| |
| @table @asis |
| |
| @item @code{--RTS=zcx} |
| |
| 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 |
| |
| The same option @code{--RTS} must be used both for @code{gcc} |
| and @code{gnatbind}. Passing this option to @code{gnatmake} |
| (@ref{ce,,Switches for gnatmake}) will ensure the required consistency |
| through the compilation and binding steps. |
| |
| @node Units to Sources Mapping Files,Code Generation Control,Exception Handling Control,Compiler Switches |
| @anchor{gnat_ugn/building_executable_programs_with_gnat id29}@anchor{107}@anchor{gnat_ugn/building_executable_programs_with_gnat units-to-sources-mapping-files}@anchor{e8} |
| @subsection Units to Sources Mapping Files |
| |
| |
| @geindex -gnatem (gcc) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatem=@emph{path}} |
| |
| 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 @code{-gnatem} switch is not a switch that you would use |
| explicitly. It is intended primarily for use by automatic tools such as |
| @code{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: |
| |
| @example |
| main%b |
| main.2.ada |
| /gnat/project1/sources/main.2.ada |
| @end example |
| |
| When the switch @code{-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 @code{-gnatem} switches may be specified; however, only the |
| last one on the command line will be taken into account. |
| |
| When using a project file, @code{gnatmake} creates a temporary |
| mapping file and communicates it to the compiler using this switch. |
| @end table |
| |
| @node Code Generation Control,,Units to Sources Mapping Files,Compiler Switches |
| @anchor{gnat_ugn/building_executable_programs_with_gnat code-generation-control}@anchor{108}@anchor{gnat_ugn/building_executable_programs_with_gnat id30}@anchor{109} |
| @subsection Code Generation Control |
| |
| |
| The GCC technology provides a wide range of target dependent |
| @code{-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 @code{-m} switches may be |
| found in the GCC documentation. |
| |
| Use of these @code{-m} switches may in some cases result in improved |
| code performance. |
| |
| The GNAT technology is tested and qualified without any |
| @code{-m} switches, |
| so generally the most reliable approach is to avoid the use of these |
| switches. However, we generally expect most of these switches to work |
| successfully with GNAT, and many customers have reported successful |
| use of these options. |
| |
| Our general advice is to avoid the use of @code{-m} switches unless |
| special needs lead to requirements in this area. In particular, |
| there is no point in using @code{-m} switches to improve performance |
| unless you actually see a performance improvement. |
| |
| @node Linker Switches,Binding with gnatbind,Compiler Switches,Building Executable Programs with GNAT |
| @anchor{gnat_ugn/building_executable_programs_with_gnat id31}@anchor{10a}@anchor{gnat_ugn/building_executable_programs_with_gnat linker-switches}@anchor{10b} |
| @section Linker Switches |
| |
| |
| Linker switches can be specified after @code{-largs} builder switch. |
| |
| @geindex -fuse-ld=name |
| |
| |
| @table @asis |
| |
| @item @code{-fuse-ld=@emph{name}} |
| |
| Linker to be used. The default is @code{bfd} for @code{ld.bfd}, |
| the alternative being @code{gold} for @code{ld.gold}. The later is |
| a more recent and faster linker, but only available on GNU/Linux |
| platforms. |
| @end table |
| |
| @node Binding with gnatbind,Linking with gnatlink,Linker Switches,Building Executable Programs with GNAT |
| @anchor{gnat_ugn/building_executable_programs_with_gnat binding-with-gnatbind}@anchor{c8}@anchor{gnat_ugn/building_executable_programs_with_gnat id32}@anchor{10c} |
| @section Binding with @code{gnatbind} |
| |
| |
| @geindex gnatbind |
| |
| This chapter describes the GNAT binder, @code{gnatbind}, which is used |
| to bind compiled GNAT objects. |
| |
| The @code{gnatbind} program performs four separate functions: |
| |
| |
| @itemize * |
| |
| @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 @code{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 @code{gnatlink} utility used to link the Ada application. |
| @end itemize |
| |
| @menu |
| * Running gnatbind:: |
| * Switches for gnatbind:: |
| * Command-Line Access:: |
| * Search Paths for gnatbind:: |
| * Examples of gnatbind Usage:: |
| |
| @end menu |
| |
| @node Running gnatbind,Switches for gnatbind,,Binding with gnatbind |
| @anchor{gnat_ugn/building_executable_programs_with_gnat id33}@anchor{10d}@anchor{gnat_ugn/building_executable_programs_with_gnat running-gnatbind}@anchor{10e} |
| @subsection Running @code{gnatbind} |
| |
| |
| The form of the @code{gnatbind} command is |
| |
| @example |
| $ gnatbind [ switches ] mainprog[.ali] [ switches ] |
| @end example |
| |
| where @code{mainprog.adb} is the Ada file containing the main program |
| unit body. @code{gnatbind} constructs an Ada |
| package in two files whose names are |
| @code{b~mainprog.ads}, and @code{b~mainprog.adb}. |
| For example, if given the |
| parameter @code{hello.ali}, for a main program contained in file |
| @code{hello.adb}, the binder output files would be @code{b~hello.ads} |
| and @code{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 |
| @code{.ALI} |
| file is @code{pack.ali} and whose corresponding source spec file is |
| @code{pack.ads}, it attempts to locate the source file @code{pack.ads} |
| (using the same search path conventions as previously described for the |
| @code{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 @code{ALI} files |
| match. In other words, any @code{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). |
| |
| @geindex Source files |
| @geindex 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 @code{hello.adb} and a |
| package @code{P}, from file @code{p.ads} and you perform the following |
| steps: |
| |
| |
| @itemize * |
| |
| @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 @code{p.ads}. |
| |
| @item |
| Enter @code{gnatbind hello}. |
| @end itemize |
| |
| At this point, the file @code{p.ali} contains an out-of-date time stamp |
| because the file @code{p.ads} has been edited. The attempt at binding |
| fails, and the binder generates the following error messages: |
| |
| @example |
| error: "hello.adb" must be recompiled ("p.ads" has been modified) |
| error: "p.ads" has been modified and must be recompiled |
| @end example |
| |
| 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{e,,Example of Binder Output File}. |
| |
| In most normal usage, the default mode of @code{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 @code{-g} switch is used for |
| @code{gnatbind} and @code{gnatlink}. |
| |
| @node Switches for gnatbind,Command-Line Access,Running gnatbind,Binding with gnatbind |
| @anchor{gnat_ugn/building_executable_programs_with_gnat id34}@anchor{10f}@anchor{gnat_ugn/building_executable_programs_with_gnat switches-for-gnatbind}@anchor{110} |
| @subsection Switches for @code{gnatbind} |
| |
| |
| The following switches are available with @code{gnatbind}; details will |
| be presented in subsequent sections. |
| |
| @geindex --version (gnatbind) |
| |
| |
| @table @asis |
| |
| @item @code{--version} |
| |
| Display Copyright and version, then exit disregarding all other options. |
| @end table |
| |
| @geindex --help (gnatbind) |
| |
| |
| @table @asis |
| |
| @item @code{--help} |
| |
| If @code{--version} was not used, display usage, then exit disregarding |
| all other options. |
| @end table |
| |
| @geindex -a (gnatbind) |
| |
| |
| @table @asis |
| |
| @item @code{-a} |
| |
| 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. |
| @end table |
| |
| @geindex -aO (gnatbind) |
| |
| |
| @table @asis |
| |
| @item @code{-aO} |
| |
| Specify directory to be searched for ALI files. |
| @end table |
| |
| @geindex -aI (gnatbind) |
| |
| |
| @table @asis |
| |
| @item @code{-aI} |
| |
| Specify directory to be searched for source file. |
| @end table |
| |
| @geindex -A (gnatbind) |
| |
| |
| @table @asis |
| |
| @item @code{-A[=@emph{filename}]} |
| |
| Output ALI list (to standard output or to the named file). |
| @end table |
| |
| @geindex -b (gnatbind) |
| |
| |
| @table @asis |
| |
| @item @code{-b} |
| |
| Generate brief messages to @code{stderr} even if verbose mode set. |
| @end table |
| |
| @geindex -c (gnatbind) |
| |
| |
| @table @asis |
| |
| @item @code{-c} |
| |
| Check only, no generation of binder output file. |
| @end table |
| |
| @geindex -dnn[k|m] (gnatbind) |
| |
| |
| @table @asis |
| |
| @item @code{-d@emph{nn}[k|m]} |
| |
| This switch can be used to change the default task stack size value |
| to a specified size @code{nn}, which is expressed in bytes by default, or |
| in kilobytes when suffixed with @code{k} or in megabytes when suffixed |
| with @code{m}. |
| In the absence of a @code{[k|m]} suffix, this switch is equivalent, |
| in effect, to completing all task specs with |
| |
| @example |
| pragma Storage_Size (nn); |
| @end example |
| |
| When they do not already have such a pragma. |
| @end table |
| |
| @geindex -D (gnatbind) |
| |
| |
| @table @asis |
| |
| @item @code{-D@emph{nn}[k|m]} |
| |
| Set the default secondary stack size to @code{nn}. The suffix indicates whether |
| the size is in bytes (no suffix), kilobytes (@code{k} suffix) or megabytes |
| (@code{m} suffix). |
| |
| The secondary stack holds objects of unconstrained types that are returned by |
| functions, for example unconstrained Strings. The size of the secondary stack |
| can be dynamic or fixed depending on the target. |
| |
| For most targets, the secondary stack grows on demand and is implemented as |
| a chain of blocks in the heap. In this case, the default secondary stack size |
| determines the initial size of the secondary stack for each task and the |
| smallest amount the secondary stack can grow by. |
| |
| For Ravenscar, ZFP, and Cert run-times the size of the secondary stack is |
| fixed. This switch can be used to change the default size of these stacks. |
| The default secondary stack size can be overridden on a per-task basis if |
| individual tasks have different secondary stack requirements. This is |
| achieved through the Secondary_Stack_Size aspect that takes the size of the |
| secondary stack in bytes. |
| @end table |
| |
| @geindex -e (gnatbind) |
| |
| |
| @table @asis |
| |
| @item @code{-e} |
| |
| Output complete list of elaboration-order dependencies. |
| @end table |
| |
| @geindex -Ea (gnatbind) |
| |
| |
| @table @asis |
| |
| @item @code{-Ea} |
| |
| Store tracebacks in exception occurrences when the target supports it. |
| The “a” is for “address”; tracebacks will contain hexadecimal addresses, |
| unless symbolic tracebacks are enabled. |
| |
| See also the packages @code{GNAT.Traceback} and |
| @code{GNAT.Traceback.Symbolic} for more information. |
| Note that on x86 ports, you must not use @code{-fomit-frame-pointer} |
| @code{gcc} option. |
| @end table |
| |
| @geindex -Es (gnatbind) |
| |
| |
| @table @asis |
| |
| @item @code{-Es} |
| |
| Store tracebacks in exception occurrences when the target supports it. |
| The “s” is for “symbolic”; symbolic tracebacks are enabled. |
| @end table |
| |
| @geindex -E (gnatbind) |
| |
| |
| @table @asis |
| |
| @item @code{-E} |
| |
| Currently the same as @code{-Ea}. |
| @end table |
| |
| @geindex -f (gnatbind) |
| |
| |
| @table @asis |
| |
| @item @code{-f@emph{elab-order}} |
| |
| Force elaboration order. For further details see @ref{111,,Elaboration Control} |
| and @ref{f,,Elaboration Order Handling in GNAT}. |
| @end table |
| |
| @geindex -F (gnatbind) |
| |
| |
| @table @asis |
| |
| @item @code{-F} |
| |
| Force the checks of elaboration flags. @code{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. |
| @end table |
| |
| @geindex -h (gnatbind) |
| |
| |
| @table @asis |
| |
| @item @code{-h} |
| |
| Output usage (help) information. |
| @end table |
| |
| @geindex -H (gnatbind) |
| |
| |
| @table @asis |
| |
| @item @code{-H} |
| |
| Legacy elaboration order model enabled. For further details see |
| @ref{f,,Elaboration Order Handling in GNAT}. |
| @end table |
| |
| @geindex -H32 (gnatbind) |
| |
| |
| @table @asis |
| |
| @item @code{-H32} |
| |
| Use 32-bit allocations for @code{__gnat_malloc} (and thus for access types). |
| For further details see @ref{112,,Dynamic Allocation Control}. |
| @end table |
| |
| @geindex -H64 (gnatbind) |
| |
| @geindex __gnat_malloc |
| |
| |
| @table @asis |
| |
| @item @code{-H64} |
| |
| Use 64-bit allocations for @code{__gnat_malloc} (and thus for access types). |
| For further details see @ref{112,,Dynamic Allocation Control}. |
| |
| @geindex -I (gnatbind) |
| |
| @item @code{-I} |
| |
| Specify directory to be searched for source and ALI files. |
| |
| @geindex -I- (gnatbind) |
| |
| @item @code{-I-} |
| |
| 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. |
| |
| @geindex -l (gnatbind) |
| |
| @item @code{-l} |
| |
| Output chosen elaboration order. |
| |
| @geindex -L (gnatbind) |
| |
| @item @code{-L@emph{xxx}} |
| |
| Bind the units for library building. In this case the @code{adainit} and |
| @code{adafinal} procedures (@ref{a0,,Binding with Non-Ada Main Programs}) |
| are renamed to @code{@emph{xxx}init} and |
| @code{@emph{xxx}final}. |
| Implies -n. |
| (@ref{2a,,GNAT and Libraries}, for more details.) |
| |
| @geindex -M (gnatbind) |
| |
| @item @code{-M@emph{xyz}} |
| |
| Rename generated main program from main to xyz. This option is |
| supported on cross environments only. |
| |
| @geindex -m (gnatbind) |
| |
| @item @code{-m@emph{n}} |
| |
| Limit number of detected errors or warnings to @code{n}, where @code{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. |
| |
| @geindex -minimal (gnatbind) |
| |
| @item @code{-minimal} |
| |
| Generate a binder file suitable for space-constrained applications. When |
| active, binder-generated objects not required for program operation are no |
| longer generated. @strong{Warning:} this option comes with the following |
| limitations: |
| |
| |
| @itemize * |
| |
| @item |
| Starting the program’s execution in the debugger will cause it to |
| stop at the start of the @code{main} function instead of the main subprogram. |
| This can be worked around by manually inserting a breakpoint on that |
| subprogram and resuming the program’s execution until reaching that breakpoint. |
| |
| @item |
| Programs using GNAT.Compiler_Version will not link. |
| @end itemize |
| |
| @geindex -n (gnatbind) |
| |
| @item @code{-n} |
| |
| No main program. |
| |
| @geindex -nostdinc (gnatbind) |
| |
| @item @code{-nostdinc} |
| |
| Do not look for sources in the system default directory. |
| |
| @geindex -nostdlib (gnatbind) |
| |
| @item @code{-nostdlib} |
| |
| Do not look for library files in the system default directory. |
| |
| @geindex --RTS (gnatbind) |
| |
| @item @code{--RTS=@emph{rts-path}} |
| |
| Specifies the default location of the run-time library. Same meaning as the |
| equivalent @code{gnatmake} flag (@ref{ce,,Switches for gnatmake}). |
| |
| @geindex -o (gnatbind) |
| |
| @item @code{-o @emph{file}} |
| |
| Name the output file @code{file} (default is @code{b~`xxx}.adb`). |
| Note that if this option is used, then linking must be done manually, |
| gnatlink cannot be used. |
| |
| @geindex -O (gnatbind) |
| |
| @item @code{-O[=@emph{filename}]} |
| |
| Output object list (to standard output or to the named file). |
| |
| @geindex -p (gnatbind) |
| |
| @item @code{-p} |
| |
| Pessimistic (worst-case) elaboration order. |
| |
| @geindex -P (gnatbind) |
| |
| @item @code{-P} |
| |
| Generate binder file suitable for CodePeer. |
| |
| @geindex -R (gnatbind) |
| |
| @item @code{-R} |
| |
| Output closure source list, which includes all non-run-time units that are |
| included in the bind. |
| |
| @geindex -Ra (gnatbind) |
| |
| @item @code{-Ra} |
| |
| Like @code{-R} but the list includes run-time units. |
| |
| @geindex -s (gnatbind) |
| |
| @item @code{-s} |
| |
| Require all source files to be present. |
| |
| @geindex -S (gnatbind) |
| |
| @item @code{-S@emph{xxx}} |
| |
| Specifies the value to be used when detecting uninitialized scalar |
| objects with pragma Initialize_Scalars. |
| The @code{xxx} string specified with the switch is one of: |
| |
| |
| @itemize * |
| |
| @item |
| @code{in} for an invalid value. |
| |
| If zero is invalid for the discrete type in question, |
| then the scalar value is set to all zero bits. |
| For signed discrete types, the largest possible negative value of |
| the underlying scalar is set (i.e. a one bit followed by all zero bits). |
| For unsigned discrete types, the underlying scalar value is set to all |
| one bits. For floating-point types, a NaN value is set |
| (see body of package System.Scalar_Values for exact values). |
| |
| @item |
| @code{lo} for low value. |
| |
| If zero is invalid for the discrete type in question, |
| then the scalar value is set to all zero bits. |
| For signed discrete types, the largest possible negative value of |
| the underlying scalar is set (i.e. a one bit followed by all zero bits). |
| For unsigned discrete types, the underlying scalar value is set to all |
| zero bits. For floating-point, a small value is set |
| (see body of package System.Scalar_Values for exact values). |
| |
| @item |
| @code{hi} for high value. |
| |
| If zero is invalid for the discrete type in question, |
| then the scalar value is set to all one bits. |
| For signed discrete types, the largest possible positive value of |
| the underlying scalar is set (i.e. a zero bit followed by all one bits). |
| For unsigned discrete types, the underlying scalar value is set to all |
| one bits. For floating-point, a large value is set |
| (see body of package System.Scalar_Values for exact values). |
| |
| @item |
| @code{xx} for hex value (two hex digits). |
| |
| The underlying scalar is set to a value consisting of repeated bytes, whose |
| value corresponds to the given value. For example if @code{BF} is given, |
| then a 32-bit scalar value will be set to the bit patterm @code{16#BFBFBFBF#}. |
| @end itemize |
| |
| @geindex GNAT_INIT_SCALARS |
| |
| In addition, you can specify @code{-Sev} to indicate that the value is |
| to be set at run time. In this case, the program will look for an environment |
| variable of the form @code{GNAT_INIT_SCALARS=@emph{yy}}, where @code{yy} is one |
| of @code{in/lo/hi/@emph{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 @code{in} (invalid values). |
| @end table |
| |
| @geindex -static (gnatbind) |
| |
| |
| @table @asis |
| |
| @item @code{-static} |
| |
| Link against a static GNAT run-time. |
| |
| @geindex -shared (gnatbind) |
| |
| @item @code{-shared} |
| |
| Link against a shared GNAT run-time when available. |
| |
| @geindex -t (gnatbind) |
| |
| @item @code{-t} |
| |
| Tolerate time stamp and other consistency errors. |
| |
| @geindex -T (gnatbind) |
| |
| @item @code{-T@emph{n}} |
| |
| Set the time slice value to @code{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}. |
| |
| @geindex -u (gnatbind) |
| |
| @item @code{-u@emph{n}} |
| |
| Enable dynamic stack usage, with @code{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{113,,Dynamic Stack Usage Analysis} for details.) |
| |
| @geindex -v (gnatbind) |
| |
| @item @code{-v} |
| |
| Verbose mode. Write error messages, header, summary output to |
| @code{stdout}. |
| |
| @geindex -V (gnatbind) |
| |
| @item @code{-V@emph{key}=@emph{value}} |
| |
| Store the given association of @code{key} to @code{value} in the bind environment. |
| Values stored this way can be retrieved at run time using |
| @code{GNAT.Bind_Environment}. |
| |
| @geindex -w (gnatbind) |
| |
| @item @code{-w@emph{x}} |
| |
| Warning mode; @code{x} = s/e for suppress/treat as error. |
| |
| @geindex -Wx (gnatbind) |
| |
| @item @code{-Wx@emph{e}} |
| |
| Override default wide character encoding for standard Text_IO files. |
| |
| @geindex -x (gnatbind) |
| |
| @item @code{-x} |
| |
| Exclude source files (check object consistency only). |
| |
| @geindex -xdr (gnatbind) |
| |
| @item @code{-xdr} |
| |
| Use the target-independent XDR protocol for stream oriented attributes |
| instead of the default implementation which is based on direct binary |
| representations and is therefore target-and endianness-dependent. |
| However it does not support 128-bit integer types and the exception |
| @code{Ada.IO_Exceptions.Device_Error} is raised if any attempt is made |
| at streaming 128-bit integer types with it. |
| |
| @geindex -Xnnn (gnatbind) |
| |
| @item @code{-X@emph{nnn}} |
| |
| Set default exit status value, normally 0 for POSIX compliance. |
| |
| @geindex -y (gnatbind) |
| |
| @item @code{-y} |
| |
| Enable leap seconds support in @code{Ada.Calendar} and its children. |
| |
| @geindex -z (gnatbind) |
| |
| @item @code{-z} |
| |
| No main subprogram. |
| @end table |
| |
| You may obtain this listing of switches by running @code{gnatbind} with |
| no arguments. |
| |
| @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 |
| |
| @node Consistency-Checking Modes,Binder Error Message Control,,Switches for gnatbind |
| @anchor{gnat_ugn/building_executable_programs_with_gnat consistency-checking-modes}@anchor{114}@anchor{gnat_ugn/building_executable_programs_with_gnat id35}@anchor{115} |
| @subsubsection Consistency-Checking Modes |
| |
| |
| 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. |
| |
| @quotation |
| |
| @geindex -s (gnatbind) |
| @end quotation |
| |
| |
| @table @asis |
| |
| @item @code{-s} |
| |
| 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. |
| |
| @geindex -Wx (gnatbind) |
| |
| @item @code{-Wx@emph{e}} |
| |
| 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 |
| @code{-gnatWx} for the compiler). The |
| use of this switch for the binder (which has the same set of |
| possible arguments) overrides this default as specified. |
| |
| @geindex -x (gnatbind) |
| |
| @item @code{-x} |
| |
| 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 @code{gnatmake} because in this |
| case the checking against sources has already been performed by |
| @code{gnatmake} in the course of compilation (i.e., before binding). |
| @end table |
| |
| @node Binder Error Message Control,Elaboration Control,Consistency-Checking Modes,Switches for gnatbind |
| @anchor{gnat_ugn/building_executable_programs_with_gnat binder-error-message-control}@anchor{116}@anchor{gnat_ugn/building_executable_programs_with_gnat id36}@anchor{117} |
| @subsubsection Binder Error Message Control |
| |
| |
| The following switches provide control over the generation of error |
| messages from the binder: |
| |
| @quotation |
| |
| @geindex -v (gnatbind) |
| @end quotation |
| |
| |
| @table @asis |
| |
| @item @code{-v} |
| |
| Verbose mode. In the normal mode, brief error messages are generated to |
| @code{stderr}. If this switch is present, a header is written |
| to @code{stdout} and any error messages are directed to @code{stdout}. |
| All that is written to @code{stderr} is a brief summary message. |
| |
| @geindex -b (gnatbind) |
| |
| @item @code{-b} |
| |
| Generate brief error messages to @code{stderr} even if verbose mode is |
| specified. This is relevant only when used with the |
| @code{-v} switch. |
| |
| @geindex -m (gnatbind) |
| |
| @item @code{-m@emph{n}} |
| |
| Limits the number of error messages to @code{n}, a decimal integer in the |
| range 1-999. The binder terminates immediately if this limit is reached. |
| |
| @geindex -M (gnatbind) |
| |
| @item @code{-M@emph{xxx}} |
| |
| 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}. |
| |
| @geindex -ws (gnatbind) |
| |
| @geindex Warnings |
| |
| @item @code{-ws} |
| |
| Suppress all warning messages. |
| |
| @geindex -we (gnatbind) |
| |
| @item @code{-we} |
| |
| Treat any warning messages as fatal errors. |
| |
| @geindex -t (gnatbind) |
| |
| @geindex Time stamp checks |
| @geindex in binder |
| |
| @geindex Binder consistency checks |
| |
| @geindex Consistency checks |
| @geindex in binder |
| |
| @item @code{-t} |
| |
| The binder performs a number of consistency checks including: |
| |
| |
| @itemize * |
| |
| @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 |
| |
| 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 @code{-t} 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. |
| |
| @cartouche |
| @quotation Note |
| This means that @code{-t} should be used only in unusual situations, |
| with extreme care. |
| @end quotation |
| @end cartouche |
| @end table |
| |
| @node Elaboration Control,Output Control,Binder Error Message Control,Switches for gnatbind |
| @anchor{gnat_ugn/building_executable_programs_with_gnat elaboration-control}@anchor{111}@anchor{gnat_ugn/building_executable_programs_with_gnat id37}@anchor{118} |
| @subsubsection Elaboration Control |
| |
| |
| The following switches provide additional control over the elaboration |
| order. For further details see @ref{f,,Elaboration Order Handling in GNAT}. |
| |
| @geindex -f (gnatbind) |
| |
| |
| @table @asis |
| |
| @item @code{-f@emph{elab-order}} |
| |
| Force elaboration order. |
| |
| @code{elab-order} should be the name of a “forced elaboration order file”, that |
| is, a text file containing library item names, one per line. A name of the |
| form “some.unit%s” or “some.unit (spec)” denotes the spec of Some.Unit. A |
| name of the form “some.unit%b” or “some.unit (body)” denotes the body of |
| Some.Unit. Each pair of lines is taken to mean that there is an elaboration |
| dependence of the second line on the first. For example, if the file |
| contains: |
| |
| @example |
| this (spec) |
| this (body) |
| that (spec) |
| that (body) |
| @end example |
| |
| then the spec of This will be elaborated before the body of This, and the |
| body of This will be elaborated before the spec of That, and the spec of That |
| will be elaborated before the body of That. The first and last of these three |
| dependences are already required by Ada rules, so this file is really just |
| forcing the body of This to be elaborated before the spec of That. |
| |
| The given order must be consistent with Ada rules, or else @code{gnatbind} will |
| give elaboration cycle errors. For example, if you say x (body) should be |
| elaborated before x (spec), there will be a cycle, because Ada rules require |
| x (spec) to be elaborated before x (body); you can’t have the spec and body |
| both elaborated before each other. |
| |
| If you later add “with That;” to the body of This, there will be a cycle, in |
| which case you should erase either “this (body)” or “that (spec)” from the |
| above forced elaboration order file. |
| |
| Blank lines and Ada-style comments are ignored. Unit names that do not exist |
| in the program are ignored. Units in the GNAT predefined library are also |
| ignored. |
| @end table |
| |
| @geindex -p (gnatbind) |
| |
| |
| @table @asis |
| |
| @item @code{-p} |
| |
| Pessimistic elaboration order |
| |
| This switch is only applicable to the pre-20.x legacy elaboration models. |
| The post-20.x elaboration model uses a more informed approach of ordering |
| the units. |
| |
| 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 @code{-p} switch if dynamic |
| elaboration checking is used (@code{-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 @code{-p} |
| mode, so a safe elaboration order is assured. |
| |
| Note that @code{-p} is not intended for production use; it is more for |
| debugging/experimental use. |
| @end table |
| |
| @node Output Control,Dynamic Allocation Control,Elaboration Control,Switches for gnatbind |
| @anchor{gnat_ugn/building_executable_programs_with_gnat id38}@anchor{119}@anchor{gnat_ugn/building_executable_programs_with_gnat output-control}@anchor{11a} |
| @subsubsection Output Control |
| |
| |
| The following switches allow additional control over the output |
| generated by the binder. |
| |
| @quotation |
| |
| @geindex -c (gnatbind) |
| @end quotation |
| |
| |
| @table @asis |
| |
| @item @code{-c} |
| |
| 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. |
| |
| @geindex -e (gnatbind) |
| |
| @item @code{-e} |
| |
| 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 @code{stdout}. |
| |
| @geindex -h (gnatbind) |
| |
| @item @code{-h} |
| |
| Output usage information. The output is written to @code{stdout}. |
| |
| @geindex -K (gnatbind) |
| |
| @item @code{-K} |
| |
| Output linker options to @code{stdout}. Includes library search paths, |
| contents of pragmas Ident and Linker_Options, and libraries added |
| by @code{gnatbind}. |
| |
| @geindex -l (gnatbind) |
| |
| @item @code{-l} |
| |
| Output chosen elaboration order. The output is written to @code{stdout}. |
| |
| @geindex -O (gnatbind) |
| |
| @item @code{-O} |
| |
| 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 @code{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. |
| |
| @geindex -o (gnatbind) |
| |
| @item @code{-o @emph{file}} |
| |
| Set name of output file to @code{file} instead of the normal |
| @code{b~`mainprog}.adb` default. Note that @code{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. |
| |
| @geindex -r (gnatbind) |
| |
| @item @code{-r} |
| |
| 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,Binding with Non-Ada Main Programs,Output Control,Switches for gnatbind |
| @anchor{gnat_ugn/building_executable_programs_with_gnat dynamic-allocation-control}@anchor{112}@anchor{gnat_ugn/building_executable_programs_with_gnat id39}@anchor{11b} |
| @subsubsection Dynamic Allocation Control |
| |
| |
| The heap control switches – @code{-H32} and @code{-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 @asis |
| |
| @item @code{-H32} |
| |
| Allocate memory on 32-bit heap |
| |
| @item @code{-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 |
| |
| These switches are only effective on VMS platforms. |
| |
| @node Binding with Non-Ada Main Programs,Binding Programs with No Main Subprogram,Dynamic Allocation Control,Switches for gnatbind |
| @anchor{gnat_ugn/building_executable_programs_with_gnat binding-with-non-ada-main-programs}@anchor{a0}@anchor{gnat_ugn/building_executable_programs_with_gnat id40}@anchor{11c} |
| @subsubsection Binding with Non-Ada Main Programs |
| |
| |
| The description so far has 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 (@ref{2c,,Mixed Language Programming}). |
| The following switch is used in this situation: |
| |
| @quotation |
| |
| @geindex -n (gnatbind) |
| @end quotation |
| |
| |
| @table @asis |
| |
| @item @code{-n} |
| |
| No main program. The main program is not in Ada. |
| @end table |
| |
| 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: |
| |
| @quotation |
| |
| @geindex adainit |
| |
| |
| @table @asis |
| |
| @item @code{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. |
| @end table |
| |
| @geindex adafinal |
| |
| |
| @table @asis |
| |
| @item @code{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 |
| @end quotation |
| |
| @geindex -n (gnatbind) |
| |
| @geindex Binder |
| @geindex multiple input files |
| |
| If the @code{-n} switch |
| is given, more than one ALI file may appear on |
| the command line for @code{gnatbind}. The normal @code{closure} |
| calculation is performed for each of the specified units. Calculating |
| the closure means finding out the set of units involved by tracing |
| @emph{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 @code{-o file}. |
| |
| @geindex -o (gnatbind) |
| |
| The output is an Ada unit in source form that can be compiled with GNAT. |
| This compilation occurs automatically as part of the @code{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,,Binding with Non-Ada Main Programs,Switches for gnatbind |
| @anchor{gnat_ugn/building_executable_programs_with_gnat binding-programs-with-no-main-subprogram}@anchor{11d}@anchor{gnat_ugn/building_executable_programs_with_gnat id41}@anchor{11e} |
| @subsubsection Binding Programs with No Main Subprogram |
| |
| |
| 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: |
| |
| @quotation |
| |
| @geindex -z (gnatbind) |
| @end quotation |
| |
| |
| @table @asis |
| |
| @item @code{-z} |
| |
| 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 |
| @code{-Wx} to override this default). |
| @end table |
| |
| @node Command-Line Access,Search Paths for gnatbind,Switches for gnatbind,Binding with gnatbind |
| @anchor{gnat_ugn/building_executable_programs_with_gnat command-line-access}@anchor{11f}@anchor{gnat_ugn/building_executable_programs_with_gnat id42}@anchor{120} |
| @subsection Command-Line Access |
| |
| |
| 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 |
| |
| @example |
| int gnat_argc; |
| char **gnat_argv; |
| @end example |
| |
| @geindex gnat_argv |
| |
| @geindex 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 @emph{n} present, @code{gnatbind} |
| generates the C main program to automatically set these variables. |
| If the @emph{n} 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,Examples of gnatbind Usage,Command-Line Access,Binding with gnatbind |
| @anchor{gnat_ugn/building_executable_programs_with_gnat id43}@anchor{121}@anchor{gnat_ugn/building_executable_programs_with_gnat search-paths-for-gnatbind}@anchor{76} |
| @subsection Search Paths for @code{gnatbind} |
| |
| |
| 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 @code{gcc} |
| (see @ref{73,,Search Paths and the Run-Time Library (RTL)}). For ALI files the |
| directories searched are: |
| |
| |
| @itemize * |
| |
| @item |
| The directory containing the ALI file named in the command line, unless |
| the switch @code{-I-} is specified. |
| |
| @item |
| All directories specified by @code{-I} |
| switches on the @code{gnatbind} |
| command line, in the order given. |
| |
| @geindex ADA_PRJ_OBJECTS_FILE |
| |
| @item |
| Each of the directories listed in the text file whose name is given |
| by the |
| @geindex ADA_PRJ_OBJECTS_FILE |
| @geindex environment variable; ADA_PRJ_OBJECTS_FILE |
| @code{ADA_PRJ_OBJECTS_FILE} environment variable. |
| |
| @geindex ADA_PRJ_OBJECTS_FILE |
| @geindex environment variable; ADA_PRJ_OBJECTS_FILE |
| @code{ADA_PRJ_OBJECTS_FILE} is normally set by gnatmake or by the gnat |
| driver when project files are used. It should not normally be set |
| by other means. |
| |
| @geindex ADA_OBJECTS_PATH |
| |
| @item |
| Each of the directories listed in the value of the |
| @geindex ADA_OBJECTS_PATH |
| @geindex environment variable; ADA_OBJECTS_PATH |
| @code{ADA_OBJECTS_PATH} environment variable. |
| Construct this value |
| exactly as the |
| @geindex PATH |
| @geindex environment variable; PATH |
| @code{PATH} environment variable: a list of directory |
| names separated by colons (semicolons when working with the NT version |
| of GNAT). |
| |
| @item |
| The content of the @code{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 @code{-nostdlib} is |
| specified. See @ref{72,,Installing a library} |
| @end itemize |
| |
| @geindex -I (gnatbind) |
| |
| @geindex -aI (gnatbind) |
| |
| @geindex -aO (gnatbind) |
| |
| In the binder the switch @code{-I} |
| is used to specify both source and |
| library file paths. Use @code{-aI} |
| instead if you want to specify |
| source paths only, and @code{-aO} |
| if you want to specify library paths |
| only. This means that for the binder |
| @code{-I@emph{dir}} is equivalent to |
| @code{-aI@emph{dir}} |
| @code{-aO`@emph{dir}}. |
| The binder generates the bind file (a C language source file) in the |
| current working directory. |
| |
| @geindex Ada |
| |
| @geindex System |
| |
| @geindex Interfaces |
| |
| @geindex 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,,Search Paths for gnatbind,Binding with gnatbind |
| @anchor{gnat_ugn/building_executable_programs_with_gnat examples-of-gnatbind-usage}@anchor{122}@anchor{gnat_ugn/building_executable_programs_with_gnat id44}@anchor{123} |
| @subsection Examples of @code{gnatbind} Usage |
| |
| |
| Here are some examples of @code{gnatbind} invovations: |
| |
| @quotation |
| |
| @example |
| gnatbind hello |
| @end example |
| |
| The main program @code{Hello} (source program in @code{hello.adb}) is |
| bound using the standard switch settings. The generated main program is |
| @code{b~hello.adb}. This is the normal, default use of the binder. |
| |
| @example |
| gnatbind hello -o mainprog.adb |
| @end example |
| |
| The main program @code{Hello} (source program in @code{hello.adb}) is |
| bound using the standard switch settings. The generated main program is |
| @code{mainprog.adb} with the associated spec in |
| @code{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 quotation |
| |
| @node Linking with gnatlink,Using the GNU make Utility,Binding with gnatbind,Building Executable Programs with GNAT |
| @anchor{gnat_ugn/building_executable_programs_with_gnat id45}@anchor{124}@anchor{gnat_ugn/building_executable_programs_with_gnat linking-with-gnatlink}@anchor{c9} |
| @section Linking with @code{gnatlink} |
| |
| |
| @geindex gnatlink |
| |
| This chapter discusses @code{gnatlink}, a tool that links |
| an Ada program and builds an executable file. This utility |
| invokes the system linker (via the @code{gcc} command) |
| with a correct list of object files and library references. |
| @code{gnatlink} automatically determines the list of files and |
| references for the Ada part of a program. It uses the binder file |
| generated by the @code{gnatbind} to determine this list. |
| |
| @menu |
| * Running gnatlink:: |
| * Switches for gnatlink:: |
| |
| @end menu |
| |
| @node Running gnatlink,Switches for gnatlink,,Linking with gnatlink |
| @anchor{gnat_ugn/building_executable_programs_with_gnat id46}@anchor{125}@anchor{gnat_ugn/building_executable_programs_with_gnat running-gnatlink}@anchor{126} |
| @subsection Running @code{gnatlink} |
| |
| |
| The form of the @code{gnatlink} command is |
| |
| @example |
| $ gnatlink [ switches ] mainprog [.ali] |
| [ non-Ada objects ] [ linker options ] |
| @end example |
| |
| The arguments of @code{gnatlink} (switches, main @code{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 @code{ALI} file. |
| Any file name @code{F} without the @code{.ali} |
| extension will be taken as the main @code{ALI} file if a file exists |
| whose name is the concatenation of @code{F} and @code{.ali}. |
| |
| @code{mainprog.ali} references the ALI file of the main program. |
| The @code{.ali} extension of this file can be omitted. From this |
| reference, @code{gnatlink} locates the corresponding binder file |
| @code{b~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 @code{gnatlink} switches and the main |
| @code{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. |
| |
| @code{linker options} is an optional list of linker specific |
| switches. |
| The default linker called by gnatlink is @code{gcc} which in |
| turn calls the appropriate system linker. |
| |
| One useful option for the linker is @code{-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 @code{-lmy_lib} or |
| @code{-Ldir} can be added as is. |
| For options that are not recognized by |
| @code{gcc} as linker options, use the @code{gcc} switches |
| @code{-Xlinker} or @code{-Wl,}. |
| |
| Refer to the GCC documentation for |
| details. |
| |
| Here is an example showing how to generate a linker map: |
| |
| @example |
| $ gnatlink my_prog -Wl,-Map,MAPFILE |
| @end example |
| |
| Using @code{linker options} it is possible to set the program stack and |
| heap size. |
| See @ref{127,,Setting Stack Size from gnatlink} and |
| @ref{128,,Setting Heap Size from gnatlink}. |
| |
| @code{gnatlink} determines the list of objects required by the Ada |
| program and prepends them to the list of objects passed to the linker. |
| @code{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. |
| |
| @node Switches for gnatlink,,Running gnatlink,Linking with gnatlink |
| @anchor{gnat_ugn/building_executable_programs_with_gnat id47}@anchor{129}@anchor{gnat_ugn/building_executable_programs_with_gnat switches-for-gnatlink}@anchor{12a} |
| @subsection Switches for @code{gnatlink} |
| |
| |
| The following switches are available with the @code{gnatlink} utility: |
| |
| @geindex --version (gnatlink) |
| |
| |
| @table @asis |
| |
| @item @code{--version} |
| |
| Display Copyright and version, then exit disregarding all other options. |
| @end table |
| |
| @geindex --help (gnatlink) |
| |
| |
| @table @asis |
| |
| @item @code{--help} |
| |
| If @code{--version} was not used, display usage, then exit disregarding |
| all other options. |
| @end table |
| |
| @geindex Command line length |
| |
| @geindex -f (gnatlink) |
| |
| |
| @table @asis |
| |
| @item @code{-f} |
| |
| On some targets, the command line length is limited, and @code{gnatlink} |
| will generate a separate file for the linker if the list of object files |
| is too long. |
| The @code{-f} 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. |
| @end table |
| |
| @geindex Debugging information |
| @geindex including |
| |
| @geindex -g (gnatlink) |
| |
| |
| @table @asis |
| |
| @item @code{-g} |
| |
| The option to include debugging information causes the Ada bind file (in |
| other words, @code{b~mainprog.adb}) to be compiled with @code{-g}. |
| In addition, the binder does not delete the @code{b~mainprog.adb}, |
| @code{b~mainprog.o} and @code{b~mainprog.ali} files. |
| Without @code{-g}, the binder removes these files by default. |
| @end table |
| |
| @geindex -n (gnatlink) |
| |
| |
| @table @asis |
| |
| @item @code{-n} |
| |
| 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. |
| @end table |
| |
| @geindex -v (gnatlink) |
| |
| |
| @table @asis |
| |
| @item @code{-v} |
| |
| Verbose mode. 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. |
| @end table |
| |
| @geindex -v -v (gnatlink) |
| |
| |
| @table @asis |
| |
| @item @code{-v -v} |
| |
| 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. |
| @end table |
| |
| @geindex -o (gnatlink) |
| |
| |
| @table @asis |
| |
| @item @code{-o @emph{exec-name}} |
| |
| @code{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 @code{try}. |
| @end table |
| |
| @geindex -B (gnatlink) |
| |
| |
| @table @asis |
| |
| @item @code{-B@emph{dir}} |
| |
| Load compiler executables (for example, @code{gnat1}, the Ada compiler) |
| from @code{dir} instead of the default location. Only use this switch |
| when multiple versions of the GNAT compiler are available. |
| See the @code{Directory Options} section in @cite{The_GNU_Compiler_Collection} |
| for further details. You would normally use the @code{-b} or |
| @code{-V} switch instead. |
| @end table |
| |
| @geindex -M (gnatlink) |
| |
| |
| @table @asis |
| |
| @item @code{-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”. |
| @end table |
| |
| @geindex -M= (gnatlink) |
| |
| |
| @table @asis |
| |
| @item @code{-M=@emph{mapfile}} |
| |
| When linking an executable, create a map file. The name of the map file is |
| @code{mapfile}. |
| @end table |
| |
| @geindex --GCC=compiler_name (gnatlink) |
| |
| |
| @table @asis |
| |
| @item @code{--GCC=@emph{compiler_name}} |
| |
| Program used for compiling the binder file. The default is |
| @code{gcc}. You need to use quotes around @code{compiler_name} if |
| @code{compiler_name} contains spaces or other separator characters. |
| As an example @code{--GCC="foo -x -y"} will instruct @code{gnatlink} to |
| use @code{foo -x -y} as your compiler. Note that switch @code{-c} is always |
| inserted after your command name. Thus in the above example the compiler |
| command that will be used by @code{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 @code{--GCC="foo -x -y"}. But the back end |
| switches will be used for @code{--GCC="gcc -gnatv"}. If several |
| @code{--GCC=compiler_name} are used, only the last @code{compiler_name} |
| is taken into account. However, all the additional switches are also taken |
| into account. Thus, |
| @code{--GCC="foo -x -y" --GCC="bar -z -t"} is equivalent to |
| @code{--GCC="bar -x -y -z -t"}. |
| @end table |
| |
| @geindex --LINK= (gnatlink) |
| |
| |
| @table @asis |
| |
| @item @code{--LINK=@emph{name}} |
| |
| @code{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 @code{gcc}. When this switch is used, the |
| specified linker is called instead of @code{gcc} with exactly the same |
| parameters that would have been passed to @code{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 table |
| |
| @node Using the GNU make Utility,,Linking with gnatlink,Building Executable Programs with GNAT |
| @anchor{gnat_ugn/building_executable_programs_with_gnat id48}@anchor{12b}@anchor{gnat_ugn/building_executable_programs_with_gnat using-the-gnu-make-utility}@anchor{70} |
| @section Using the GNU @code{make} Utility |
| |
| |
| @geindex make (GNU) |
| @geindex GNU make |
| |
| This chapter offers some examples of makefiles that solve specific |
| problems. It does not explain how to write a makefile, nor does it try to replace the |
| @code{gnatmake} utility (@ref{c6,,Building with gnatmake}). |
| |
| All the examples in this section are specific to the GNU version of |
| make. Although @code{make} is a standard utility, and the basic language |
| is the same, these examples use some advanced features found only in |
| @code{GNU make}. |
| |
| @menu |
| * Using gnatmake in a Makefile:: |
| * Automatically Creating a List of Directories:: |
| * Generating the Command Line Switches:: |
| * Overcoming Command Line Length Limits:: |
| |
| @end menu |
| |
| @node Using gnatmake in a Makefile,Automatically Creating a List of Directories,,Using the GNU make Utility |
| @anchor{gnat_ugn/building_executable_programs_with_gnat id49}@anchor{12c}@anchor{gnat_ugn/building_executable_programs_with_gnat using-gnatmake-in-a-makefile}@anchor{12d} |
| @subsection Using gnatmake in a Makefile |
| |
| |
| @c index makefile (GNU make) |
| |
| 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 |
| @code{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 |
| (@ref{12e,,Automatically Creating a List of Directories}) |
| which might help you in case your project has a lot of subdirectories. |
| |
| @example |
| ## This Makefile is intended to be used with the following directory |
| ## configuration: |
| ## - The sources are split into a series of csc (computer software components) |
| ## Each of these csc is put in its own directory. |
| ## Their name are referenced by the directory names. |
| ## They will be compiled into shared library (although this would also work |
| ## with static libraries |
| ## - The main program (and possibly other packages that do not belong to any |
| ## csc is put in the top level directory (where the Makefile is). |
| ## toplevel_dir __ first_csc (sources) __ lib (will contain the library) |
| ## \\_ second_csc (sources) __ lib (will contain the library) |
| ## \\_ ... |
| ## Although this Makefile is build for shared library, it is easy to modify |
| ## to build partial link objects instead (modify the lines with -shared and |
| ## gnatlink below) |
| ## |
| ## With this makefile, you can change any file in the system or add any new |
| ## file, and everything will be recompiled correctly (only the relevant shared |
| ## objects will be recompiled, and the main program will be re-linked). |
| |
| # The list of computer software component for your project. This might be |
| # generated automatically. |
| CSC_LIST=aa bb cc |
| |
| # Name of the main program (no extension) |
| MAIN=main |
| |
| # If we need to build objects with -fPIC, uncomment the following line |
| #NEED_FPIC=-fPIC |
| |
| # The following variable should give the directory containing libgnat.so |
| # You can get this directory through 'gnatls -v'. This is usually the last |
| # directory in the Object_Path. |
| GLIB=... |
| |
| # The directories for the libraries |
| # (This macro expands the list of CSC to the list of shared libraries, you |
| # could simply use the expanded form: |
| # LIB_DIR=aa/lib/libaa.so bb/lib/libbb.so cc/lib/libcc.so |
| LIB_DIR=$@{foreach dir,$@{CSC_LIST@},$@{dir@}/lib/lib$@{dir@}.so@} |
| |
| $@{MAIN@}: objects $@{LIB_DIR@} |
| gnatbind $@{MAIN@} $@{CSC_LIST:%=-aO%/lib@} -shared |
| gnatlink $@{MAIN@} $@{CSC_LIST:%=-l%@} |
| |
| objects:: |
| # recompile the sources |
| gnatmake -c -i $@{MAIN@}.adb $@{NEED_FPIC@} $@{CSC_LIST:%=-I%@} |
| |
| # Note: In a future version of GNAT, the following commands will be simplified |
| # by a new tool, gnatmlib |
| $@{LIB_DIR@}: |
| mkdir -p $@{dir $@@ @} |
| cd $@{dir $@@ @} && gcc -shared -o $@{notdir $@@ @} ../*.o -L$@{GLIB@} -lgnat |
| cd $@{dir $@@ @} && cp -f ../*.ali . |
| |
| # The dependencies for the modules |
| # Note that we have to force the expansion of *.o, since in some cases |
| # make won't be able to do it itself. |
| aa/lib/libaa.so: $@{wildcard aa/*.o@} |
| bb/lib/libbb.so: $@{wildcard bb/*.o@} |
| cc/lib/libcc.so: $@{wildcard cc/*.o@} |
| |
| # Make sure all of the shared libraries are in the path before starting the |
| # program |
| run:: |
| LD_LIBRARY_PATH=`pwd`/aa/lib:`pwd`/bb/lib:`pwd`/cc/lib ./$@{MAIN@} |
| |
| clean:: |
| $@{RM@} -rf $@{CSC_LIST:%=%/lib@} |
| $@{RM@} $@{CSC_LIST:%=%/*.ali@} |
| $@{RM@} $@{CSC_LIST:%=%/*.o@} |
| $@{RM@} *.o *.ali $@{MAIN@} |
| @end example |
| |
| @node Automatically Creating a List of Directories,Generating the Command Line Switches,Using gnatmake in a Makefile,Using the GNU make Utility |
| @anchor{gnat_ugn/building_executable_programs_with_gnat automatically-creating-a-list-of-directories}@anchor{12e}@anchor{gnat_ugn/building_executable_programs_with_gnat id50}@anchor{12f} |
| @subsection Automatically Creating a List of Directories |
| |
| |
| In most makefiles, you will have to specify a list of directories, and |
| store it in a variable. For small projects, it is often easier to |
| specify each of them by hand, since you then have full control over what |
| is the proper order for these directories, which ones should be |
| included. |
| |
| However, in larger projects, which might involve hundreds of |
| subdirectories, it might be more convenient to generate this list |
| automatically. |
| |
| The example below presents two methods. The first one, although less |
| general, gives you more control over the list. It involves wildcard |
| characters, that are automatically expanded by @code{make}. Its |
| shortcoming is that you need to explicitly specify some of the |
| organization of your project, such as for instance the directory tree |
| depth, whether some directories are found in a separate tree, etc. |
| |
| The second method is the most general one. It requires an external |
| program, called @code{find}, which is standard on all Unix systems. All |
| the directories found under a given root directory will be added to the |
| list. |
| |
| @example |
| # 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 `@w{`}dir`@w{`} and `@w{`}sort`@w{`} 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 example |
| |
| @node Generating the Command Line Switches,Overcoming Command Line Length Limits,Automatically Creating a List of Directories,Using the GNU make Utility |
| @anchor{gnat_ugn/building_executable_programs_with_gnat generating-the-command-line-switches}@anchor{130}@anchor{gnat_ugn/building_executable_programs_with_gnat id51}@anchor{131} |
| @subsection Generating the Command Line Switches |
| |
| |
| Once you have created the list of directories as explained in the |
| previous section (@ref{12e,,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. |
| |
| @example |
| # 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 example |
| |
| @node Overcoming Command Line Length Limits,,Generating the Command Line Switches,Using the GNU make Utility |
| @anchor{gnat_ugn/building_executable_programs_with_gnat id52}@anchor{132}@anchor{gnat_ugn/building_executable_programs_with_gnat overcoming-command-line-length-limits}@anchor{133} |
| @subsection Overcoming Command Line Length Limits |
| |
| |
| 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 @code{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{12e,,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. |
| |
| @example |
| # 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 example |
| |
| @node GNAT Utility Programs,GNAT and Program Execution,Building Executable Programs with GNAT,Top |
| @anchor{gnat_ugn/gnat_utility_programs doc}@anchor{134}@anchor{gnat_ugn/gnat_utility_programs gnat-utility-programs}@anchor{b}@anchor{gnat_ugn/gnat_utility_programs id1}@anchor{135} |
| @chapter GNAT Utility Programs |
| |
| |
| This chapter describes a number of utility programs: |
| |
| |
| |
| @itemize * |
| |
| @item |
| @ref{136,,The File Cleanup Utility gnatclean} |
| |
| @item |
| @ref{137,,The GNAT Library Browser gnatls} |
| @end itemize |
| |
| Other GNAT utilities are described elsewhere in this manual: |
| |
| |
| @itemize * |
| |
| @item |
| @ref{42,,Handling Arbitrary File Naming Conventions with gnatname} |
| |
| @item |
| @ref{4c,,File Name Krunching with gnatkr} |
| |
| @item |
| @ref{1d,,Renaming Files with gnatchop} |
| |
| @item |
| @ref{8f,,Preprocessing with gnatprep} |
| @end itemize |
| |
| @menu |
| * The File Cleanup Utility gnatclean:: |
| * The GNAT Library Browser gnatls:: |
| |
| @end menu |
| |
| @node The File Cleanup Utility gnatclean,The GNAT Library Browser gnatls,,GNAT Utility Programs |
| @anchor{gnat_ugn/gnat_utility_programs id2}@anchor{138}@anchor{gnat_ugn/gnat_utility_programs the-file-cleanup-utility-gnatclean}@anchor{136} |
| @section The File Cleanup Utility @code{gnatclean} |
| |
| |
| @geindex File cleanup tool |
| |
| @geindex gnatclean |
| |
| @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:: |
| |
| @end menu |
| |
| @node Running gnatclean,Switches for gnatclean,,The File Cleanup Utility gnatclean |
| @anchor{gnat_ugn/gnat_utility_programs id3}@anchor{139}@anchor{gnat_ugn/gnat_utility_programs running-gnatclean}@anchor{13a} |
| @subsection Running @code{gnatclean} |
| |
| |
| The @code{gnatclean} command has the form: |
| |
| @quotation |
| |
| @example |
| $ gnatclean switches names |
| @end example |
| @end quotation |
| |
| where @code{names} is a list of source file names. Suffixes @code{.ads} and |
| @code{adb} may be omitted. If a project file is specified using switch |
| @code{-P}, then @code{names} may be completely omitted. |
| |
| In normal mode, @code{gnatclean} delete the files produced by the compiler and, |
| if switch @code{-c} is not specified, by the binder and |
| the linker. In informative-only mode, specified by switch |
| @code{-n}, the list of files that would have been deleted in |
| normal mode is listed, but no file is actually deleted. |
| |
| @node Switches for gnatclean,,Running gnatclean,The File Cleanup Utility gnatclean |
| @anchor{gnat_ugn/gnat_utility_programs id4}@anchor{13b}@anchor{gnat_ugn/gnat_utility_programs switches-for-gnatclean}@anchor{13c} |
| @subsection Switches for @code{gnatclean} |
| |
| |
| @code{gnatclean} recognizes the following switches: |
| |
| @geindex --version (gnatclean) |
| |
| |
| @table @asis |
| |
| @item @code{--version} |
| |
| Display copyright and version, then exit disregarding all other options. |
| @end table |
| |
| @geindex --help (gnatclean) |
| |
| |
| @table @asis |
| |
| @item @code{--help} |
| |
| If @code{--version} was not used, display usage, then exit disregarding |
| all other options. |
| |
| @item @code{--subdirs=@emph{subdir}} |
| |
| Actual object directory of each project file is the subdirectory subdir of the |
| object directory specified or defaulted in the project file. |
| |
| @item @code{--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. |
| @end table |
| |
| @geindex -c (gnatclean) |
| |
| |
| @table @asis |
| |
| @item @code{-c} |
| |
| 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. |
| @end table |
| |
| @geindex -D (gnatclean) |
| |
| |
| @table @asis |
| |
| @item @code{-D @emph{dir}} |
| |
| Indicate that ALI and object files should normally be found in directory @code{dir}. |
| @end table |
| |
| @geindex -F (gnatclean) |
| |
| |
| @table @asis |
| |
| @item @code{-F} |
| |
| 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), then error lines start with the full path name of the project |
| file, rather than its simple file name. |
| @end table |
| |
| @geindex -h (gnatclean) |
| |
| |
| @table @asis |
| |
| @item @code{-h} |
| |
| Output a message explaining the usage of @code{gnatclean}. |
| @end table |
| |
| @geindex -n (gnatclean) |
| |
| |
| @table @asis |
| |
| @item @code{-n} |
| |
| 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. |
| @end table |
| |
| @geindex -P (gnatclean) |
| |
| |
| @table @asis |
| |
| @item @code{-P@emph{project}} |
| |
| Use project file @code{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. |
| @end table |
| |
| @geindex -q (gnatclean) |
| |
| |
| @table @asis |
| |
| @item @code{-q} |
| |
| Quiet output. If there are no errors, do not output anything, except in |
| verbose mode (switch -v) or in informative-only mode |
| (switch -n). |
| @end table |
| |
| @geindex -r (gnatclean) |
| |
| |
| @table @asis |
| |
| @item @code{-r} |
| |
| When a project file is specified (using switch -P), |
| 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. |
| @end table |
| |
| @geindex -v (gnatclean) |
| |
| |
| @table @asis |
| |
| @item @code{-v} |
| |
| Verbose mode. |
| @end table |
| |
| @geindex -vP (gnatclean) |
| |
| |
| @table @asis |
| |
| @item @code{-vP@emph{x}} |
| |
| Indicates the verbosity of the parsing of GNAT project files. |
| @ref{cf,,Switches Related to Project Files}. |
| @end table |
| |
| @geindex -X (gnatclean) |
| |
| |
| @table @asis |
| |
| @item @code{-X@emph{name}=@emph{value}} |
| |
| Indicates that external variable @code{name} has the value @code{value}. |
| The Project Manager will use this value for occurrences of |
| @code{external(name)} when parsing the project file. |
| See @ref{cf,,Switches Related to Project Files}. |
| @end table |
| |
| @geindex -aO (gnatclean) |
| |
| |
| @table @asis |
| |
| @item @code{-aO@emph{dir}} |
| |
| When searching for ALI and object files, look in directory @code{dir}. |
| @end table |
| |
| @geindex -I (gnatclean) |
| |
| |
| @table @asis |
| |
| @item @code{-I@emph{dir}} |
| |
| Equivalent to @code{-aO@emph{dir}}. |
| @end table |
| |
| @geindex -I- (gnatclean) |
| |
| @geindex Source files |
| @geindex suppressing search |
| |
| |
| @table @asis |
| |
| @item @code{-I-} |
| |
| Do not look for ALI or object files in the directory |
| where @code{gnatclean} was invoked. |
| @end table |
| |
| @node The GNAT Library Browser gnatls,,The File Cleanup Utility gnatclean,GNAT Utility Programs |
| @anchor{gnat_ugn/gnat_utility_programs id5}@anchor{13d}@anchor{gnat_ugn/gnat_utility_programs the-gnat-library-browser-gnatls}@anchor{137} |
| @section The GNAT Library Browser @code{gnatls} |
| |
| |
| @geindex Library browser |
| |
| @geindex gnatls |
| |
| @code{gnatls} is a tool that outputs information about compiled |
| units. It gives the relationship between objects, unit names and source |
| files. It can also be used to check the source dependencies of a unit |
| as well as various characteristics. |
| |
| @menu |
| * Running gnatls:: |
| * Switches for gnatls:: |
| * Example of gnatls Usage:: |
| |
| @end menu |
| |
| @node Running gnatls,Switches for gnatls,,The GNAT Library Browser gnatls |
| @anchor{gnat_ugn/gnat_utility_programs id6}@anchor{13e}@anchor{gnat_ugn/gnat_utility_programs running-gnatls}@anchor{13f} |
| @subsection Running @code{gnatls} |
| |
| |
| The @code{gnatls} command has the form |
| |
| @quotation |
| |
| @example |
| $ gnatls switches object_or_ali_file |
| @end example |
| @end quotation |
| |
| The main argument is the list of object or @code{ali} files |
| (see @ref{28,,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: |
| |
| @quotation |
| |
| @example |
| $ 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 example |
| @end quotation |
| |
| The first line can be interpreted as follows: the main unit which is |
| contained in |
| object file @code{demo1.o} is demo1, whose main source is in |
| @code{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 @asis |
| |
| @item @emph{OK (unchanged)} |
| |
| The version of the source file used for the compilation of the |
| specified unit corresponds exactly to the actual source file. |
| |
| @item @emph{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 option |
| @code{-m} (minimal recompilation), a file marked |
| MOK will not be recompiled. |
| |
| @item @emph{DIF (modified)} |
| |
| No version of the source found on the path corresponds to the source |
| used to build this object. |
| |
| @item @emph{??? (file not found)} |
| |
| No source file was found for this unit. |
| |
| @item @emph{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,Example of gnatls Usage,Running gnatls,The GNAT Library Browser gnatls |
| @anchor{gnat_ugn/gnat_utility_programs id7}@anchor{140}@anchor{gnat_ugn/gnat_utility_programs switches-for-gnatls}@anchor{141} |
| @subsection Switches for @code{gnatls} |
| |
| |
| @code{gnatls} recognizes the following switches: |
| |
| @geindex --version (gnatls) |
| |
| |
| @table @asis |
| |
| @item @code{--version} |
| |
| Display copyright and version, then exit disregarding all other options. |
| @end table |
| |
| @geindex --help (gnatls) |
| |
| |
| @table @asis |
| |
| @item @code{--help} |
| |
| If @code{--version} was not used, display usage, then exit disregarding |
| all other options. |
| @end table |
| |
| @geindex -a (gnatls) |
| |
| |
| @table @asis |
| |
| @item @code{-a} |
| |
| Consider all units, including those of the predefined Ada library. |
| Especially useful with @code{-d}. |
| @end table |
| |
| @geindex -d (gnatls) |
| |
| |
| @table @asis |
| |
| @item @code{-d} |
| |
| List sources from which specified units depend on. |
| @end table |
| |
| @geindex -h (gnatls) |
| |
| |
| @table @asis |
| |
| @item @code{-h} |
| |
| Output the list of options. |
| @end table |
| |
| @geindex -o (gnatls) |
| |
| |
| @table @asis |
| |
| @item @code{-o} |
| |
| Only output information about object files. |
| @end table |
| |
| @geindex -s (gnatls) |
| |
| |
| @table @asis |
| |
| @item @code{-s} |
| |
| Only output information about source files. |
| @end table |
| |
| @geindex -u (gnatls) |
| |
| |
| @table @asis |
| |
| @item @code{-u} |
| |
| Only output information about compilation units. |
| @end table |
| |
| @geindex -files (gnatls) |
| |
| |
| @table @asis |
| |
| @item @code{-files=@emph{file}} |
| |
| Take as arguments the files listed in text file @code{file}. |
| Text file @code{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. |
| @end table |
| |
| @geindex -aO (gnatls) |
| |
| @geindex -aI (gnatls) |
| |
| @geindex -I (gnatls) |
| |
| @geindex -I- (gnatls) |
| |
| |
| @table @asis |
| |
| @item @code{-aO@emph{dir}}, @code{-aI@emph{dir}}, @code{-I@emph{dir}}, @code{-I-}, @code{-nostdinc} |
| |
| Source path manipulation. Same meaning as the equivalent @code{gnatmake} |
| flags (@ref{ce,,Switches for gnatmake}). |
| @end table |
| |
| @geindex -aP (gnatls) |
| |
| |
| @table @asis |
| |
| @item @code{-aP@emph{dir}} |
| |
| Add @code{dir} at the beginning of the project search dir. |
| @end table |
| |
| @geindex --RTS (gnatls) |
| |
| |
| @table @asis |
| |
| @item @code{--RTS=@emph{rts-path}} |
| |
| Specifies the default location of the runtime library. Same meaning as the |
| equivalent @code{gnatmake} flag (@ref{ce,,Switches for gnatmake}). |
| @end table |
| |
| @geindex -v (gnatls) |
| |
| |
| @table @asis |
| |
| @item @code{-v} |
| |
| 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: |
| |
| |
| @itemize * |
| |
| @item |
| @emph{Preelaborable}: The unit is preelaborable in the Ada sense. |
| |
| @item |
| @emph{No_Elab_Code}: No elaboration code has been produced by the compiler for this unit. |
| |
| @item |
| @emph{Pure}: The unit is pure in the Ada sense. |
| |
| @item |
| @emph{Elaborate_Body}: The unit contains a pragma Elaborate_Body. |
| |
| @item |
| @emph{Remote_Types}: The unit contains a pragma Remote_Types. |
| |
| @item |
| @emph{Shared_Passive}: The unit contains a pragma Shared_Passive. |
| |
| @item |
| @emph{Predefined}: This unit is part of the predefined environment and cannot be modified |
| by the user. |
| |
| @item |
| @emph{Remote_Call_Interface}: The unit contains a pragma Remote_Call_Interface. |
| @end itemize |
| @end table |
| |
| @node Example of gnatls Usage,,Switches for gnatls,The GNAT Library Browser gnatls |
| @anchor{gnat_ugn/gnat_utility_programs example-of-gnatls-usage}@anchor{142}@anchor{gnat_ugn/gnat_utility_programs id8}@anchor{143} |
| @subsection Example of @code{gnatls} Usage |
| |
| |
| Example of using the verbose switch. Note how the source and |
| object paths are affected by the -I switch. |
| |
| @quotation |
| |
| @example |
| $ 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 example |
| @end quotation |
| |
| 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. |
| |
| @quotation |
| |
| @example |
| $ 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 example |
| @end quotation |
| |
| |
| |
| |
| |
| |
| |
| |
| @c -- Example: A |withing| unit has a |with| clause, it |withs| a |withed| unit |
| |
| @node GNAT and Program Execution,Platform-Specific Information,GNAT Utility Programs,Top |
| @anchor{gnat_ugn/gnat_and_program_execution doc}@anchor{144}@anchor{gnat_ugn/gnat_and_program_execution gnat-and-program-execution}@anchor{c}@anchor{gnat_ugn/gnat_and_program_execution id1}@anchor{145} |
| @chapter GNAT and Program Execution |
| |
| |
| This chapter covers several topics: |
| |
| |
| @itemize * |
| |
| @item |
| @ref{146,,Running and Debugging Ada Programs} |
| |
| @item |
| @ref{147,,Profiling} |
| |
| @item |
| @ref{148,,Improving Performance} |
| |
| @item |
| @ref{149,,Overflow Check Handling in GNAT} |
| |
| @item |
| @ref{14a,,Performing Dimensionality Analysis in GNAT} |
| |
| @item |
| @ref{14b,,Stack Related Facilities} |
| |
| @item |
| @ref{14c,,Memory Management Issues} |
| @end itemize |
| |
| @menu |
| * Running and Debugging Ada Programs:: |
| * Profiling:: |
| * Improving Performance:: |
| * Overflow Check Handling in GNAT:: |
| * Performing Dimensionality Analysis in GNAT:: |
| * Stack Related Facilities:: |
| * Memory Management Issues:: |
| |
| @end menu |
| |
| @node Running and Debugging Ada Programs,Profiling,,GNAT and Program Execution |
| @anchor{gnat_ugn/gnat_and_program_execution id2}@anchor{146}@anchor{gnat_ugn/gnat_and_program_execution running-and-debugging-ada-programs}@anchor{14d} |
| @section Running and Debugging Ada Programs |
| |
| |
| @geindex Debugging |
| |
| This section discusses how to debug Ada programs. |
| |
| An incorrect Ada program may be handled in three ways by the GNAT compiler: |
| |
| |
| @itemize * |
| |
| @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 itemize |
| |
| @geindex Debugger |
| |
| @geindex gdb |
| |
| @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:: |
| * Stopping When Ada Exceptions Are Raised:: |
| * Ada Tasks:: |
| * Debugging Generic Units:: |
| * Remote Debugging with gdbserver:: |
| * GNAT Abnormal Termination or Failure to Terminate:: |
| * Naming Conventions for GNAT Source Files:: |
| * Getting Internal Debugging Information:: |
| * Stack Traceback:: |
| * Pretty-Printers for the GNAT runtime:: |
| |
| @end menu |
| |
| @node The GNAT Debugger GDB,Running GDB,,Running and Debugging Ada Programs |
| @anchor{gnat_ugn/gnat_and_program_execution id3}@anchor{14e}@anchor{gnat_ugn/gnat_and_program_execution the-gnat-debugger-gdb}@anchor{14f} |
| @subsection The GNAT Debugger GDB |
| |
| |
| @code{GDB} is a general purpose, platform-independent debugger that |
| can be used to debug mixed-language programs compiled with @code{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. |
| |
| See @cite{Debugging with GDB}, |
| 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 |
| @code{-g} switch in the @code{gcc} or @code{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. |
| |
| @node Running GDB,Introduction to GDB Commands,The GNAT Debugger GDB,Running and Debugging Ada Programs |
| @anchor{gnat_ugn/gnat_and_program_execution id4}@anchor{150}@anchor{gnat_ugn/gnat_and_program_execution running-gdb}@anchor{151} |
| @subsection Running GDB |
| |
| |
| This section describes how to initiate the debugger. |
| |
| The debugger can be launched from a @code{GNAT Studio} menu or |
| directly from the command line. The description below covers the latter use. |
| All the commands shown can be used in the @code{GNAT Studio} debug console window, |
| but there are usually more GUI-based ways to achieve the same effect. |
| |
| The command to run @code{GDB} is |
| |
| @quotation |
| |
| @example |
| $ gdb program |
| @end example |
| @end quotation |
| |
| where @code{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}. |
| |
| @node Introduction to GDB Commands,Using Ada Expressions,Running GDB,Running and Debugging Ada Programs |
| @anchor{gnat_ugn/gnat_and_program_execution id5}@anchor{152}@anchor{gnat_ugn/gnat_and_program_execution introduction-to-gdb-commands}@anchor{153} |
| @subsection Introduction to GDB Commands |
| |
| |
| @code{GDB} contains a large repertoire of commands. |
| See @cite{Debugging with GDB} for extensive documentation on the use |
| of these commands, together with examples of their use. Furthermore, |
| the command @emph{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. |
| |
| |
| @itemize * |
| |
| @item |
| |
| @table @asis |
| |
| @item @code{set args @emph{arguments}} |
| |
| The @emph{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. |
| @end table |
| |
| @item |
| |
| @table @asis |
| |
| @item @code{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. |
| @end table |
| |
| @item |
| |
| @table @asis |
| |
| @item @code{breakpoint @emph{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. @emph{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. |
| @end table |
| |
| @item |
| |
| @table @asis |
| |
| @item @code{catch exception @emph{name}} |
| |
| This command causes the program execution to stop whenever exception |
| @code{name} is raised. If @code{name} is omitted, then the execution is |
| suspended when any exception is raised. |
| @end table |
| |
| @item |
| |
| @table @asis |
| |
| @item @code{print @emph{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. |
| @end table |
| |
| @item |
| |
| @table @asis |
| |
| @item @code{continue} |
| |
| Continues execution following a breakpoint, until the next breakpoint or the |
| termination of the program. |
| @end table |
| |
| @item |
| |
| @table @asis |
| |
| @item @code{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. |
| @end table |
| |
| @item |
| |
| @table @asis |
| |
| @item @code{next} |
| |
| Executes a single line. If this line is a subprogram call, executes and |
| returns from the call. |
| @end table |
| |
| @item |
| |
| @table @asis |
| |
| @item @code{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. |
| @end table |
| |
| @item |
| |
| @table @asis |
| |
| @item @code{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. |
| @end table |
| |
| @item |
| |
| @table @asis |
| |
| @item @code{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. |
| @end table |
| |
| @item |
| |
| @table @asis |
| |
| @item @code{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), |
| @end table |
| |
| @item |
| |
| @table @asis |
| |
| @item @code{frame @emph{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 |
| |
| @item |
| |
| @table @asis |
| |
| @item @code{kill} |
| |
| Kills the child process in which the program is running under GDB. |
| This may be useful for several purposes: |
| |
| |
| @itemize * |
| |
| @item |
| It allows you to recompile and relink your program, since on many systems |
| you cannot regenerate an executable file while it is running in a process. |
| |
| @item |
| You can run your program outside the debugger, on systems that do not |
| permit executing a program outside GDB while breakpoints are set |
| within GDB. |
| |
| @item |
| It allows you to debug a core dump rather than a running process. |
| @end itemize |
| @end table |
| @end itemize |
| |
| The above list is a very short introduction to the commands that |
| @code{GDB} provides. Important additional capabilities, including conditional |
| breakpoints, the ability to execute command sequences on a breakpoint, |
| the ability to debug at the machine instruction level and many other |
| features are described in detail in @cite{Debugging with GDB}. |
| Note that most commands can be abbreviated |
| (for example, c for continue, bt for backtrace). |
| |
| @node Using Ada Expressions,Calling User-Defined Subprograms,Introduction to GDB Commands,Running and Debugging Ada Programs |
| @anchor{gnat_ugn/gnat_and_program_execution id6}@anchor{154}@anchor{gnat_ugn/gnat_and_program_execution using-ada-expressions}@anchor{155} |
| @subsection Using Ada Expressions |
| |
| |
| @geindex Ada expressions (in gdb) |
| |
| @code{GDB} supports a fairly large subset of Ada expression syntax, with some |
| extensions. The philosophy behind the design of this subset is |
| |
| @quotation |
| |
| |
| @itemize * |
| |
| @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 relevant in a debugging context. |
| |
| @item |
| That brevity is important to the @code{GDB} user. |
| @end itemize |
| @end quotation |
| |
| Thus, for brevity, the debugger acts as if there were |
| implicit @code{with} and @code{use} clauses in effect for all user-written |
| packages, thus making it unnecessary to fully qualify most names with |
| their packages, regardless of context. Where this causes ambiguity, |
| @code{GDB} asks the user’s intent. |
| |
| For details on the supported Ada syntax, see @cite{Debugging with GDB}. |
| |
| @node Calling User-Defined Subprograms,Using the next Command in a Function,Using Ada Expressions,Running and Debugging Ada Programs |
| @anchor{gnat_ugn/gnat_and_program_execution calling-user-defined-subprograms}@anchor{156}@anchor{gnat_ugn/gnat_and_program_execution id7}@anchor{157} |
| @subsection Calling User-Defined Subprograms |
| |
| |
| 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: |
| |
| @quotation |
| |
| @example |
| call subprogram-name (parameters) |
| @end example |
| @end quotation |
| |
| 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. |
| |
| Another useful application of this capability is to deal with situations of |
| complex data which are not handled suitably by GDB. For example, if you specify |
| Convention Fortran for a multi-dimensional array, GDB does not know that |
| the ordering of array elements has been switched and will not properly |
| address the array elements. In such a case, instead of trying to print the |
| elements directly from GDB, you can write a callable procedure that prints |
| the elements in the desired format. |
| |
| @node Using the next Command in a Function,Stopping When Ada Exceptions Are Raised,Calling User-Defined Subprograms,Running and Debugging Ada Programs |
| @anchor{gnat_ugn/gnat_and_program_execution id8}@anchor{158}@anchor{gnat_ugn/gnat_and_program_execution using-the-next-command-in-a-function}@anchor{159} |
| @subsection Using the @emph{next} Command in a Function |
| |
| |
| 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 ‘epilogue’ of the function. |
| This is the code that returns to the caller. There is only one copy of |
| this epilogue 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 epilogue 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 Stopping When Ada Exceptions Are Raised,Ada Tasks,Using the next Command in a Function,Running and Debugging Ada Programs |
| @anchor{gnat_ugn/gnat_and_program_execution id9}@anchor{15a}@anchor{gnat_ugn/gnat_and_program_execution stopping-when-ada-exceptions-are-raised}@anchor{15b} |
| @subsection Stopping When Ada Exceptions Are Raised |
| |
| |
| @geindex Exceptions (in gdb) |
| |
| You can set catchpoints that stop the program execution when your program |
| raises selected exceptions. |
| |
| |
| @itemize * |
| |
| @item |
| |
| @table @asis |
| |
| @item @code{catch exception} |
| |
| Set a catchpoint that stops execution whenever (any task in the) program |
| raises any exception. |
| @end table |
| |
| @item |
| |
| @table @asis |
| |
| @item @code{catch exception @emph{name}} |
| |
| Set a catchpoint that stops execution whenever (any task in the) program |
| raises the exception @emph{name}. |
| @end table |
| |
| @item |
| |
| @table @asis |
| |
| @item @code{catch exception unhandled} |
| |
| Set a catchpoint that stops executing whenever (any task in the) program |
| raises an exception for which there is no handler. |
| @end table |
| |
| @item |
| |
| @table @asis |
| |
| @item @code{info exceptions}, @code{info exceptions @emph{regexp}} |
| |
| The @code{info exceptions} command permits the user to examine all defined |
| exceptions within Ada programs. With a regular expression, @emph{regexp}, as |
| argument, prints out only those exceptions whose name matches @emph{regexp}. |
| @end table |
| @end itemize |
| |
| @geindex Tasks (in gdb) |
| |
| @node Ada Tasks,Debugging Generic Units,Stopping When Ada Exceptions Are Raised,Running and Debugging Ada Programs |
| @anchor{gnat_ugn/gnat_and_program_execution ada-tasks}@anchor{15c}@anchor{gnat_ugn/gnat_and_program_execution id10}@anchor{15d} |
| @subsection Ada Tasks |
| |
| |
| @code{GDB} allows the following task-related commands: |
| |
| |
| @itemize * |
| |
| @item |
| |
| @table @asis |
| |
| @item @code{info tasks} |
| |
| This command shows a list of current Ada tasks, as in the following example: |
| |
| @example |
| (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 example |
| |
| 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. |
| @end table |
| @end itemize |
| |
| @geindex Breakpoints and tasks |
| |
| |
| @itemize * |
| |
| @item |
| @code{break`@w{`}*linespec* `@w{`}task} @emph{taskid}, @code{break} @emph{linespec} @code{task} @emph{taskid} @code{if} … |
| |
| @quotation |
| |
| These commands are like the @code{break ... thread ...}. |
| @emph{linespec} specifies source lines. |
| |
| Use the qualifier @code{task @emph{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. @emph{taskid} is one of the |
| numeric task identifiers assigned by @code{GDB}, shown in the first |
| column of the @code{info tasks} display. |
| |
| If you do not specify @code{task @emph{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 @code{task @emph{taskid}} before the |
| breakpoint condition (before the @code{if}). |
| @end quotation |
| @end itemize |
| |
| @geindex Task switching (in gdb) |
| |
| |
| @itemize * |
| |
| @item |
| @code{task @emph{taskno}} |
| |
| @quotation |
| |
| This command allows switching to the task referred by @emph{taskno}. In |
| particular, this allows browsing of the backtrace of the specified |
| task. It is advisable to switch back to the original task before |
| continuing execution otherwise the scheduling of the program may be |
| perturbed. |
| @end quotation |
| @end itemize |
| |
| For more detailed information on the tasking support, |
| see @cite{Debugging with GDB}. |
| |
| @geindex Debugging Generic Units |
| |
| @geindex Generics |
| |
| @node Debugging Generic Units,Remote Debugging with gdbserver,Ada Tasks,Running and Debugging Ada Programs |
| @anchor{gnat_ugn/gnat_and_program_execution debugging-generic-units}@anchor{15e}@anchor{gnat_ugn/gnat_and_program_execution id11}@anchor{15f} |
| @subsection Debugging Generic Units |
| |
| |
| 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 |
| |
| @quotation |
| |
| @example |
| 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 example |
| @end quotation |
| |
| Then to break on a call to procedure kp in the k2 instance, simply |
| use the command: |
| |
| @quotation |
| |
| @example |
| (gdb) break g.k2.kp |
| @end example |
| @end quotation |
| |
| 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. |
| |
| @geindex Remote Debugging with gdbserver |
| |
| @node Remote Debugging with gdbserver,GNAT Abnormal Termination or Failure to Terminate,Debugging Generic Units,Running and Debugging Ada Programs |
| @anchor{gnat_ugn/gnat_and_program_execution id12}@anchor{160}@anchor{gnat_ugn/gnat_and_program_execution remote-debugging-with-gdbserver}@anchor{161} |
| @subsection Remote Debugging with gdbserver |
| |
| |
| 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. |
| |
| @quotation |
| |
| @example |
| $ gdbserver localhost:4444 program |
| Process program created; pid = 5685 |
| Listening on port 4444 |
| @end example |
| @end quotation |
| |
| 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. |
| |
| @quotation |
| |
| @example |
| $ 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 example |
| @end quotation |
| |
| 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, see the @emph{Using the gdbserver Program} |
| section in @cite{Debugging with GDB}. |
| GNAT provides support for gdbserver on x86-linux, x86-windows and x86_64-linux. |
| |
| @geindex Abnormal Termination or Failure to Terminate |
| |
| @node GNAT Abnormal Termination or Failure to Terminate,Naming Conventions for GNAT Source Files,Remote Debugging with gdbserver,Running and Debugging Ada Programs |
| @anchor{gnat_ugn/gnat_and_program_execution gnat-abnormal-termination-or-failure-to-terminate}@anchor{162}@anchor{gnat_ugn/gnat_and_program_execution id13}@anchor{163} |
| @subsection GNAT Abnormal Termination or Failure to Terminate |
| |
| |
| 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. |
| |
| |
| @itemize * |
| |
| @item |
| Run @code{gcc} with the @code{-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 @code{-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 @code{gcc} with the @code{-v} (verbose) switch. In this |
| mode, @code{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. |
| @end itemize |
| |
| @geindex -gnatdc switch |
| |
| |
| @itemize * |
| |
| @item |
| Run @code{gcc} with the @code{-gnatdc} switch. This is a GNAT specific |
| switch that does for the front-end what @code{-v} 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 @code{gcc}). You can use @code{gdb} on @code{gnat1} as you |
| would on a C program (but @ref{14f,,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 @code{gcc} backend, indicates the source line at |
| which the execution stopped, and @code{input_file name} indicates the name of |
| the source file. |
| @end itemize |
| |
| @node Naming Conventions for GNAT Source Files,Getting Internal Debugging Information,GNAT Abnormal Termination or Failure to Terminate,Running and Debugging Ada Programs |
| @anchor{gnat_ugn/gnat_and_program_execution id14}@anchor{164}@anchor{gnat_ugn/gnat_and_program_execution naming-conventions-for-gnat-source-files}@anchor{165} |
| @subsection Naming Conventions for GNAT Source Files |
| |
| |
| In order to examine the workings of the GNAT system, the following |
| brief description of its organization may be helpful: |
| |
| |
| @itemize * |
| |
| @item |
| Files with prefix @code{sc} contain the lexical scanner. |
| |
| @item |
| All files prefixed with @code{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 @code{par-ch9.adb}. |
| |
| @item |
| All files prefixed with @code{sem} perform semantic analysis. The |
| numbers correspond to chapters of the Ada standard. For example, all |
| issues involving context clauses can be found in @code{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 @code{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 |
| @code{exp_ch3.adb}. |
| |
| @item |
| The files prefixed with @code{bind} implement the binder, which |
| verifies the consistency of the compilation, determines an order of |
| elaboration, and generates the bind file. |
| |
| @item |
| The files @code{atree.ads} and @code{atree.adb} detail the low-level |
| data structures used by the front-end. |
| |
| @item |
| The files @code{sinfo.ads} and @code{sinfo.adb} detail the structure of |
| the abstract syntax tree as produced by the parser. |
| |
| @item |
| The files @code{einfo.ads} and @code{einfo.adb} detail the attributes of |
| all entities, computed during semantic analysis. |
| |
| @item |
| Library management issues are dealt with in files with prefix |
| @code{lib}. |
| |
| @geindex Annex A (in Ada Reference Manual) |
| |
| @item |
| Ada files with the prefix @code{a-} are children of @code{Ada}, as |
| defined in Annex A. |
| |
| @geindex Annex B (in Ada reference Manual) |
| |
| @item |
| Files with prefix @code{i-} are children of @code{Interfaces}, as |
| defined in Annex B. |
| |
| @geindex System (package in Ada Reference Manual) |
| |
| @item |
| Files with prefix @code{s-} are children of @code{System}. This includes |
| both language-defined children and GNAT run-time routines. |
| |
| @geindex GNAT (package) |
| |
| @item |
| Files with prefix @code{g-} are children of @code{GNAT}. These are useful |
| general-purpose packages, fully documented in their specs. All |
| the other @code{.c} files are modifications of common @code{gcc} files. |
| @end itemize |
| |
| @node Getting Internal Debugging Information,Stack Traceback,Naming Conventions for GNAT Source Files,Running and Debugging Ada Programs |
| @anchor{gnat_ugn/gnat_and_program_execution getting-internal-debugging-information}@anchor{166}@anchor{gnat_ugn/gnat_and_program_execution id15}@anchor{167} |
| @subsection Getting Internal Debugging Information |
| |
| |
| 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 @code{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. |
| |
| @geindex traceback |
| |
| @geindex stack traceback |
| |
| @geindex stack unwinding |
| |
| @node Stack Traceback,Pretty-Printers for the GNAT runtime,Getting Internal Debugging Information,Running and Debugging Ada Programs |
| @anchor{gnat_ugn/gnat_and_program_execution id16}@anchor{168}@anchor{gnat_ugn/gnat_and_program_execution stack-traceback}@anchor{169} |
| @subsection Stack Traceback |
| |
| |
| 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 @emph{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. |
| |
| @geindex traceback |
| @geindex non-symbolic |
| |
| @menu |
| * Non-Symbolic Traceback:: |
| * Symbolic Traceback:: |
| |
| @end menu |
| |
| @node Non-Symbolic Traceback,Symbolic Traceback,,Stack Traceback |
| @anchor{gnat_ugn/gnat_and_program_execution id17}@anchor{16a}@anchor{gnat_ugn/gnat_and_program_execution non-symbolic-traceback}@anchor{16b} |
| @subsubsection Non-Symbolic Traceback |
| |
| |
| Note: this feature is not supported on all platforms. See |
| @code{GNAT.Traceback} spec in @code{g-traceb.ads} |
| for a complete list of supported platforms. |
| |
| @subsubheading Tracebacks From an Unhandled Exception |
| |
| |
| A runtime non-symbolic traceback is a list of addresses of call instructions. |
| To enable this feature you must use the @code{-E} |
| @code{gnatbind} 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: |
| |
| @quotation |
| |
| @example |
| procedure STB is |
| |
| procedure P1 is |
| begin |
| raise Constraint_Error; |
| end P1; |
| |
| procedure P2 is |
| begin |
| P1; |
| end P2; |
| |
| begin |
| P2; |
| end STB; |
| @end example |
| |
| @example |
| $ 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 example |
| @end quotation |
| |
| 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. |
| |
| @quotation |
| |
| @example |
| $ gnatmake -g stb -bargs -E |
| $ stb |
| |
| Execution terminated by unhandled exception |
| Exception name: CONSTRAINT_ERROR |
| Message: stb.adb:5 |
| Call stack traceback locations: |
| 0x401373 0x40138b 0x40139c 0x401335 0x4011c4 0x4011f1 0x77e892a4 |
| |
| $ addr2line --exe=stb 0x401373 0x40138b 0x40139c 0x401335 0x4011c4 |
| 0x4011f1 0x77e892a4 |
| |
| 00401373 at d:/stb/stb.adb:5 |
| 0040138B at d:/stb/stb.adb:10 |
| 0040139C at d:/stb/stb.adb:14 |
| 00401335 at d:/stb/b~stb.adb:104 |
| 004011C4 at /build/.../crt1.c:200 |
| 004011F1 at /build/.../crt1.c:222 |
| 77E892A4 in ?? at ??:0 |
| @end example |
| @end quotation |
| |
| The @code{addr2line} tool has several other useful options: |
| |
| @quotation |
| |
| |
| @multitable {xxxxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx} |
| @item |
| |
| @code{--functions} |
| |
| @tab |
| |
| to get the function name corresponding to any location |
| |
| @item |
| |
| @code{--demangle=gnat} |
| |
| @tab |
| |
| to use the gnat decoding mode for the function names. |
| Note that for binutils version 2.9.x the option is |
| simply @code{--demangle}. |
| |
| @end multitable |
| |
| |
| @example |
| $ addr2line --exe=stb --functions --demangle=gnat 0x401373 0x40138b |
| 0x40139c 0x401335 0x4011c4 0x4011f1 |
| |
| 00401373 in stb.p1 at d:/stb/stb.adb:5 |
| 0040138B in stb.p2 at d:/stb/stb.adb:10 |
| 0040139C in stb at d:/stb/stb.adb:14 |
| 00401335 in main at d:/stb/b~stb.adb:104 |
| 004011C4 in <__mingw_CRTStartup> at /build/.../crt1.c:200 |
| 004011F1 in <mainCRTStartup> at /build/.../crt1.c:222 |
| @end example |
| @end quotation |
| |
| From this traceback we can see that the exception was raised in |
| @code{stb.adb} at line 5, which was reached from a procedure call in |
| @code{stb.adb} at line 10, and so on. The @code{b~std.adb} is the binder file, |
| which contains the call to the main program. |
| @ref{10e,,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: |
| |
| @quotation |
| |
| @example |
| $ gdb -nw stb |
| @end example |
| @end quotation |
| |
| Furthermore, this feature is not implemented inside Windows DLL. Only |
| the non-symbolic traceback is reported in this case. |
| |
| @quotation |
| |
| @example |
| (gdb) break *0x401373 |
| Breakpoint 1 at 0x401373: file stb.adb, line 5. |
| @end example |
| @end quotation |
| |
| 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. |
| |
| @subsubheading Tracebacks From Exception Occurrences |
| |
| |
| Non-symbolic tracebacks are obtained by using the @code{-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: |
| |
| @quotation |
| |
| @example |
| 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 example |
| @end quotation |
| |
| This program will output: |
| |
| @quotation |
| |
| @example |
| $ stb |
| |
| Exception name: CONSTRAINT_ERROR |
| Message: stb.adb:12 |
| Call stack traceback locations: |
| 0x4015e4 0x401633 0x401644 0x401461 0x4011c4 0x4011f1 0x77e892a4 |
| @end example |
| @end quotation |
| |
| @subsubheading Tracebacks From Anywhere in a Program |
| |
| |
| 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 |
| @code{-E} @code{gnatbind} option in this case, because the stack traceback mechanism |
| is invoked explicitly. |
| |
| 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: |
| |
| @quotation |
| |
| @example |
| 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 example |
| |
| @example |
| $ 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 example |
| @end quotation |
| |
| 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’). |
| |
| @geindex traceback |
| @geindex symbolic |
| |
| @node Symbolic Traceback,,Non-Symbolic Traceback,Stack Traceback |
| @anchor{gnat_ugn/gnat_and_program_execution id18}@anchor{16c}@anchor{gnat_ugn/gnat_and_program_execution symbolic-traceback}@anchor{16d} |
| @subsubsection Symbolic Traceback |
| |
| |
| A symbolic traceback is a stack traceback in which procedure names are |
| associated with each code location. |
| |
| Note that this feature is not supported on all platforms. See |
| @code{GNAT.Traceback.Symbolic} spec in @code{g-trasym.ads} for a complete |
| list of currently supported platforms. |
| |
| 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. |
| |
| @subsubheading Tracebacks From Exception Occurrences |
| |
| |
| Here is an example: |
| |
| @quotation |
| |
| @example |
| 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 example |
| |
| @example |
| $ gnatmake -g .\stb -bargs -E |
| $ 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 example |
| @end quotation |
| |
| In the above example the @code{.\} syntax in the @code{gnatmake} command |
| is currently required by @code{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 @code{-largs} section is for Windows platforms. By contrast, |
| under Unix there is no need for the @code{-largs} section. |
| Differences across platforms are due to details of linker implementation. |
| |
| @subsubheading Tracebacks From Anywhere in a Program |
| |
| |
| 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: |
| |
| @quotation |
| |
| @example |
| 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 example |
| @end quotation |
| |
| @subsubheading Automatic Symbolic Tracebacks |
| |
| |
| Symbolic tracebacks may also be enabled by using the -Es switch to gnatbind (as |
| in @code{gprbuild -g ... -bargs -Es}). |
| This will cause the Exception_Information to contain a symbolic traceback, |
| which will also be printed if an unhandled exception terminates the |
| program. |
| |
| @node Pretty-Printers for the GNAT runtime,,Stack Traceback,Running and Debugging Ada Programs |
| @anchor{gnat_ugn/gnat_and_program_execution id19}@anchor{16e}@anchor{gnat_ugn/gnat_and_program_execution pretty-printers-for-the-gnat-runtime}@anchor{16f} |
| @subsection Pretty-Printers for the GNAT runtime |
| |
| |
| As discussed in @cite{Calling User-Defined Subprograms}, GDB’s |
| @code{print} command only knows about the physical layout of program data |
| structures and therefore normally displays only low-level dumps, which |
| are often hard to understand. |
| |
| An example of this is when trying to display the contents of an Ada |
| standard container, such as @code{Ada.Containers.Ordered_Maps.Map}: |
| |
| @quotation |
| |
| @example |
| with Ada.Containers.Ordered_Maps; |
| |
| procedure PP is |
| package Int_To_Nat is |
| new Ada.Containers.Ordered_Maps (Integer, Natural); |
| |
| Map : Int_To_Nat.Map; |
| begin |
| Map.Insert (1, 10); |
| Map.Insert (2, 20); |
| Map.Insert (3, 30); |
| |
| Map.Clear; -- BREAK HERE |
| end PP; |
| @end example |
| @end quotation |
| |
| When this program is built with debugging information and run under |
| GDB up to the @code{Map.Clear} statement, trying to print @code{Map} will |
| yield information that is only relevant to the developers of our standard |
| containers: |
| |
| @quotation |
| |
| @example |
| (gdb) print map |
| $1 = ( |
| tree => ( |
| first => 0x64e010, |
| last => 0x64e070, |
| root => 0x64e040, |
| length => 3, |
| tc => ( |
| busy => 0, |
| lock => 0 |
| ) |
| ) |
| ) |
| @end example |
| @end quotation |
| |
| Fortunately, GDB has a feature called pretty-printers@footnote{http://docs.adacore.com/gdb-docs/html/gdb.html#Pretty_002dPrinter-Introduction}, |
| which allows customizing how GDB displays data structures. The GDB |
| shipped with GNAT embeds such pretty-printers for the most common |
| containers in the standard library. To enable them, either run the |
| following command manually under GDB or add it to your @code{.gdbinit} file: |
| |
| @quotation |
| |
| @example |
| python import gnatdbg; gnatdbg.setup() |
| @end example |
| @end quotation |
| |
| Once this is done, GDB’s @code{print} command will automatically use |
| these pretty-printers when appropriate. Using the previous example: |
| |
| @quotation |
| |
| @example |
| (gdb) print map |
| $1 = pp.int_to_nat.map of length 3 = @{ |
| [1] = 10, |
| [2] = 20, |
| [3] = 30 |
| @} |
| @end example |
| @end quotation |
| |
| Pretty-printers are invoked each time GDB tries to display a value, |
| including when displaying the arguments of a called subprogram (in |
| GDB’s @code{backtrace} command) or when printing the value returned by a |
| function (in GDB’s @code{finish} command). |
| |
| To display a value without involving pretty-printers, @code{print} can be |
| invoked with its @code{/r} option: |
| |
| @quotation |
| |
| @example |
| (gdb) print/r map |
| $1 = ( |
| tree => (... |
| @end example |
| @end quotation |
| |
| Finer control of pretty-printers is also possible: see GDB's online documentation@footnote{http://docs.adacore.com/gdb-docs/html/gdb.html#Pretty_002dPrinter-Commands} |
| for more information. |
| |
| @geindex Profiling |
| |
| @node Profiling,Improving Performance,Running and Debugging Ada Programs,GNAT and Program Execution |
| @anchor{gnat_ugn/gnat_and_program_execution id20}@anchor{170}@anchor{gnat_ugn/gnat_and_program_execution profiling}@anchor{147} |
| @section Profiling |
| |
| |
| This section describes how to use the @code{gprof} profiler tool on Ada programs. |
| |
| @geindex gprof |
| |
| @geindex Profiling |
| |
| @menu |
| * Profiling an Ada Program with gprof:: |
| |
| @end menu |
| |
| @node Profiling an Ada Program with gprof,,,Profiling |
| @anchor{gnat_ugn/gnat_and_program_execution id21}@anchor{171}@anchor{gnat_ugn/gnat_and_program_execution profiling-an-ada-program-with-gprof}@anchor{172} |
| @subsection Profiling an Ada Program with gprof |
| |
| |
| This section is not meant to be an exhaustive documentation of @code{gprof}. |
| Full documentation for it can be found in the @cite{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 * |
| |
| @item |
| linux x86/x86_64 |
| |
| @item |
| windows x86 |
| @end itemize |
| |
| In order to profile a program using @code{gprof}, several steps are needed: |
| |
| |
| @enumerate |
| |
| @item |
| Instrument the code, which requires a full recompilation of the project with the |
| proper switches. |
| |
| @item |
| Execute the program under the analysis conditions, i.e. with the desired |
| input. |
| |
| @item |
| Analyze the results using the @code{gprof} tool. |
| @end enumerate |
| |
| 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,Program execution,,Profiling an Ada Program with gprof |
| @anchor{gnat_ugn/gnat_and_program_execution compilation-for-profiling}@anchor{173}@anchor{gnat_ugn/gnat_and_program_execution id22}@anchor{174} |
| @subsubsection Compilation for profiling |
| |
| |
| @geindex -pg (gcc) |
| @geindex for profiling |
| |
| @geindex -pg (gnatlink) |
| @geindex for 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: |
| |
| @quotation |
| |
| @example |
| $ gnatmake -f -pg -P my_project |
| @end example |
| @end quotation |
| |
| Note that only the objects that were compiled with the @code{-pg} switch will |
| be profiled; if you need to profile your whole project, use the @code{-f} |
| gnatmake switch to force full recompilation. |
| |
| @node Program execution,Running gprof,Compilation for profiling,Profiling an Ada Program with gprof |
| @anchor{gnat_ugn/gnat_and_program_execution id23}@anchor{175}@anchor{gnat_ugn/gnat_and_program_execution program-execution}@anchor{176} |
| @subsubsection Program execution |
| |
| |
| 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 @code{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,Interpretation of profiling results,Program execution,Profiling an Ada Program with gprof |
| @anchor{gnat_ugn/gnat_and_program_execution id24}@anchor{177}@anchor{gnat_ugn/gnat_and_program_execution running-gprof}@anchor{178} |
| @subsubsection Running gprof |
| |
| |
| The @code{gprof} tool is called as follow: |
| |
| @quotation |
| |
| @example |
| $ gprof my_prog gmon.out |
| @end example |
| @end quotation |
| |
| or simply: |
| |
| @quotation |
| |
| @example |
| $ gprof my_prog |
| @end example |
| @end quotation |
| |
| The complete form of the gprof command line is the following: |
| |
| @quotation |
| |
| @example |
| $ gprof [switches] [executable [data-file]] |
| @end example |
| @end quotation |
| |
| @code{gprof} supports numerous switches. The order of these |
| switch 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: |
| |
| @geindex --demangle (gprof) |
| |
| |
| @table @asis |
| |
| @item @code{--demangle[=@emph{style}]}, @code{--no-demangle} |
| |
| 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}. |
| @end table |
| |
| @geindex -e (gprof) |
| |
| |
| @table @asis |
| |
| @item @code{-e @emph{function_name}} |
| |
| The @code{-e @emph{function}} option tells @code{gprof} not to print |
| information about the function @code{function_name} (and its |
| children…) 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 @code{[not printed]}. More than one @code{-e} option may be |
| given; only one @code{function_name} may be indicated with each @code{-e} |
| option. |
| @end table |
| |
| @geindex -E (gprof) |
| |
| |
| @table @asis |
| |
| @item @code{-E @emph{function_name}} |
| |
| The @code{-E @emph{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 @code{-E} option may be given; only one |
| @code{function_name} may be indicated with each @code{-E`} option. |
| @end table |
| |
| @geindex -f (gprof) |
| |
| |
| @table @asis |
| |
| @item @code{-f @emph{function_name}} |
| |
| The @code{-f @emph{function}} option causes @code{gprof} to limit the |
| call graph to the function @code{function_name} and its children (and |
| their children…). More than one @code{-f} option may be given; |
| only one @code{function_name} may be indicated with each @code{-f} |
| option. |
| @end table |
| |
| @geindex -F (gprof) |
| |
| |
| @table @asis |
| |
| @item @code{-F @emph{function_name}} |
| |
| The @code{-F @emph{function}} option works like the @code{-f} option, but |
| only time spent in the function and its children (and their |
| children…) will be used to determine total-time and |
| percentages-of-time for the call graph. More than one @code{-F} option |
| may be given; only one @code{function_name} may be indicated with each |
| @code{-F} option. The @code{-F} option overrides the @code{-E} option. |
| @end table |
| |
| @node Interpretation of profiling results,,Running gprof,Profiling an Ada Program with gprof |
| @anchor{gnat_ugn/gnat_and_program_execution id25}@anchor{179}@anchor{gnat_ugn/gnat_and_program_execution interpretation-of-profiling-results}@anchor{17a} |
| @subsubsection Interpretation of profiling results |
| |
| |
| 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. |
| |
| @node Improving Performance,Overflow Check Handling in GNAT,Profiling,GNAT and Program Execution |
| @anchor{gnat_ugn/gnat_and_program_execution id26}@anchor{148}@anchor{gnat_ugn/gnat_and_program_execution improving-performance}@anchor{17b} |
| @section Improving Performance |
| |
| |
| @geindex Improving performance |
| |
| This section 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 unused subprogram/data elimination feature, |
| which can reduce the size of program executables. |
| |
| @menu |
| * Performance Considerations:: |
| * Text_IO Suggestions:: |
| * Reducing Size of Executables with Unused Subprogram/Data Elimination:: |
| |
| @end menu |
| |
| @node Performance Considerations,Text_IO Suggestions,,Improving Performance |
| @anchor{gnat_ugn/gnat_and_program_execution id27}@anchor{17c}@anchor{gnat_ugn/gnat_and_program_execution performance-considerations}@anchor{17d} |
| @subsection Performance Considerations |
| |
| |
| The GNAT system provides a number of options that allow a trade-off |
| between |
| |
| |
| @itemize * |
| |
| @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 |
| |
| 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 * |
| |
| @item |
| no optimization |
| |
| @item |
| no inlining of subprogram calls |
| |
| @item |
| all run-time checks enabled except overflow and elaboration checks |
| @end itemize |
| |
| These options are suitable for most program development purposes. This |
| section 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:: |
| * Floating Point Operations:: |
| * Vectorization of loops:: |
| * Other Optimization Switches:: |
| * Optimization and Strict Aliasing:: |
| * Aliased Variables and Optimization:: |
| * Atomic Variables and Optimization:: |
| * Passive Task Optimization:: |
| |
| @end menu |
| |
| @node Controlling Run-Time Checks,Use of Restrictions,,Performance Considerations |
| @anchor{gnat_ugn/gnat_and_program_execution controlling-run-time-checks}@anchor{17e}@anchor{gnat_ugn/gnat_and_program_execution id28}@anchor{17f} |
| @subsubsection Controlling Run-Time Checks |
| |
| |
| By default, GNAT generates all run-time checks, except 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. |
| |
| @geindex -gnatp (gcc) |
| |
| @geindex -gnato (gcc) |
| |
| The gnat switch, @code{-gnatp} allows this default to be modified. See |
| @ref{ea,,Run-Time Checks}. |
| |
| Our experience is that the default is suitable for most development |
| purposes. |
| |
| 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 @code{-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 @code{-gnatVn}. Validity checks |
| are also suppressed entirely if @code{-gnatp} is used. |
| |
| @geindex Overflow checks |
| |
| @geindex Checks |
| @geindex overflow |
| |
| @geindex Suppress |
| |
| @geindex Unsuppress |
| |
| @geindex pragma Suppress |
| |
| @geindex 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,Optimization Levels,Controlling Run-Time Checks,Performance Considerations |
| @anchor{gnat_ugn/gnat_and_program_execution id29}@anchor{180}@anchor{gnat_ugn/gnat_and_program_execution use-of-restrictions}@anchor{181} |
| @subsubsection Use of Restrictions |
| |
| |
| The use of pragma Restrictions allows you to control which features are |
| permitted in your program. Apart from the obvious point that if you avoid |
| relatively expensive features like finalization (enforceable by the use |
| of pragma Restrictions (No_Finalization), the use of this pragma does not |
| affect the generated code in most cases. |
| |
| One notable exception to this rule is that the possibility of task abort |
| results in some distributed overhead, particularly if finalization or |
| exception handlers are used. The reason is that certain sections of code |
| have to be marked as non-abortable. |
| |
| If you use neither the @code{abort} statement, nor asynchronous transfer |
| of control (@code{select ... then abort}), then this distributed overhead |
| is removed, which may have a general positive effect in improving |
| overall performance. Especially code involving frequent use of tasking |
| constructs and controlled types will show much improved performance. |
| The relevant restrictions pragmas are |
| |
| @quotation |
| |
| @example |
| pragma Restrictions (No_Abort_Statements); |
| pragma Restrictions (Max_Asynchronous_Select_Nesting => 0); |
| @end example |
| @end quotation |
| |
| 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,Debugging Optimized Code,Use of Restrictions,Performance Considerations |
| @anchor{gnat_ugn/gnat_and_program_execution id30}@anchor{182}@anchor{gnat_ugn/gnat_and_program_execution optimization-levels}@anchor{ed} |
| @subsubsection Optimization Levels |
| |
| |
| @geindex -O (gcc) |
| |
| Without any optimization option, |
| 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, |
| the last such option is the one that is effective. |
| |
| 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 |
| @code{-O} switch (the permitted forms are @code{-O0}, @code{-O1} |
| @code{-O2}, @code{-O3}, and @code{-Os}) |
| to @code{gcc} to control the optimization level: |
| |
| |
| @itemize * |
| |
| @item |
| |
| @table @asis |
| |
| @item @code{-O0} |
| |
| No optimization (the default); |
| generates unoptimized code but has |
| the fastest compilation time. |
| |
| Note that many other compilers do substantial optimization even |
| if ‘no optimization’ is specified. With gcc, it is very unusual |
| to use @code{-O0} for production if execution time is of any concern, |
| since @code{-O0} means (almost) no optimization. This difference |
| between gcc and other compilers should be kept in mind when |
| doing performance comparisons. |
| @end table |
| |
| @item |
| |
| @table @asis |
| |
| @item @code{-O1} |
| |
| Moderate optimization; |
| optimizes reasonably well but does not |
| degrade compilation time significantly. |
| @end table |
| |
| @item |
| |
| @table @asis |
| |
| @item @code{-O2} |
| |
| Full optimization; |
| generates highly optimized code and has |
| the slowest compilation time. |
| @end table |
| |
| @item |
| |
| @table @asis |
| |
| @item @code{-O3} |
| |
| Full optimization as in @code{-O2}; |
| also uses more aggressive automatic inlining of subprograms within a unit |
| (@ref{100,,Inlining of Subprograms}) and attempts to vectorize loops. |
| @end table |
| |
| @item |
| |
| @table @asis |
| |
| @item @code{-Os} |
| |
| Optimize space usage (code and data) of resulting program. |
| @end table |
| @end itemize |
| |
| 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. |
| See the @emph{Options That Control Optimization} section in |
| @cite{Using the GNU Compiler Collection (GCC)} |
| for details about |
| the @code{-O} settings and a number of @code{-f} options that |
| individually enable or disable specific optimizations. |
| |
| Unlike some other compilation systems, @code{gcc} 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 @code{-O3}: The use of this optimization level |
| ought not to be automatically preferred over that of level @code{-O2}, |
| since it often results in larger executables which may run more slowly. |
| See further discussion of this point in @ref{100,,Inlining of Subprograms}. |
| |
| @node Debugging Optimized Code,Inlining of Subprograms,Optimization Levels,Performance Considerations |
| @anchor{gnat_ugn/gnat_and_program_execution debugging-optimized-code}@anchor{183}@anchor{gnat_ugn/gnat_and_program_execution id31}@anchor{184} |
| @subsubsection Debugging Optimized Code |
| |
| |
| @geindex Debugging optimized code |
| |
| @geindex Optimization and debugging |
| |
| Although it is possible to do a reasonable amount of debugging at |
| nonzero optimization levels, |
| the higher the level the more likely that |
| 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 @code{-O2} or @code{-O3}. |
| Explicit temporary variables that you code might be eliminated at |
| level @code{-O1} or higher. |
| |
| @geindex -g (gcc) |
| |
| The use of the @code{-g} switch, |
| 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: |
| |
| |
| @itemize * |
| |
| @item |
| @emph{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 - |
| |
| @item |
| @emph{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 |
| @emph{Invariant code motion:} moving an expression that does not change within a |
| loop, to the beginning of the loop. |
| |
| @item |
| @emph{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 |
| @emph{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} statement. |
| |
| @item |
| @emph{The ‘roving variable’:} The symptom is an unexpected value in a variable. |
| There are various reasons for this effect: |
| |
| |
| @itemize - |
| |
| @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 |
| |
| 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 itemize |
| |
| In light of such anomalies, a recommended technique is to use @code{-O0} |
| early in the software development cycle, when extensive debugging capabilities |
| are most needed, and then move to @code{-O1} and later @code{-O2} as |
| the debugger becomes less critical. |
| Whether to use the @code{-g} switch in the release version is |
| a release management issue. |
| Note that if you use @code{-g} you can then use the @code{strip} program |
| on the resulting executable, |
| which removes both debugging information and global symbols. |
| |
| @node Inlining of Subprograms,Floating Point Operations,Debugging Optimized Code,Performance Considerations |
| @anchor{gnat_ugn/gnat_and_program_execution id32}@anchor{185}@anchor{gnat_ugn/gnat_and_program_execution inlining-of-subprograms}@anchor{100} |
| @subsubsection Inlining of Subprograms |
| |
| |
| A call to a subprogram in the current unit is inlined if all the |
| following conditions are met: |
| |
| |
| @itemize * |
| |
| @item |
| The optimization level is at least @code{-O1}. |
| |
| @item |
| The called subprogram is suitable for inlining: It must be small enough |
| and not contain something that @code{gcc} cannot support in inlined |
| subprograms. |
| |
| @geindex pragma Inline |
| |
| @geindex Inline |
| |
| @item |
| Any one of the following applies: @code{pragma Inline} is applied to the |
| subprogram; the subprogram is local to the unit and called once from |
| within it; the subprogram is small and optimization level @code{-O2} is |
| specified; optimization level @code{-O3} is specified. |
| @end itemize |
| |
| Calls to subprograms in @emph{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 * |
| |
| @item |
| The optimization level is at least @code{-O1}. |
| |
| @item |
| The called subprogram is suitable for inlining: It must be small enough |
| and not contain something that @code{gcc} cannot support in inlined |
| subprograms. |
| |
| @item |
| There is a @code{pragma Inline} for the subprogram. |
| |
| @item |
| The @code{-gnatn} 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 @code{-gnatn} switch causes additional |
| compilation dependencies. Consider the following: |
| |
| @quotation |
| |
| @example |
| package R is |
| procedure Q; |
| pragma Inline (Q); |
| end R; |
| package body R is |
| ... |
| end R; |
| |
| with R; |
| procedure Main is |
| begin |
| ... |
| R.Q; |
| end Main; |
| @end example |
| @end quotation |
| |
| With the default behavior (no @code{-gnatn} switch specified), the |
| compilation of the @code{Main} procedure depends only on its own source, |
| @code{main.adb}, and the spec of the package in file @code{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 @code{-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 |
| @code{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 @code{gcc}. |
| |
| The use of front end inlining with @code{-gnatN} generates similar |
| additional dependencies. |
| |
| @geindex -fno-inline (gcc) |
| |
| Note: The @code{-fno-inline} switch overrides all other conditions and ensures that |
| no inlining occurs, unless requested with pragma Inline_Always for @code{gcc} |
| back-ends. The extra dependences resulting from @code{-gnatn} will still be active, |
| even if this switch is used to suppress the resulting inlining actions. |
| |
| @geindex -fno-inline-functions (gcc) |
| |
| Note: The @code{-fno-inline-functions} switch can be used to prevent |
| automatic inlining of subprograms if @code{-O3} is used. |
| |
| @geindex -fno-inline-small-functions (gcc) |
| |
| Note: The @code{-fno-inline-small-functions} switch can be used to prevent |
| automatic inlining of small subprograms if @code{-O2} is used. |
| |
| @geindex -fno-inline-functions-called-once (gcc) |
| |
| Note: The @code{-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 @code{-O1} is used. |
| |
| Note regarding the use of @code{-O3}: @code{-gnatn} is made up of two |
| sub-switches @code{-gnatn1} and @code{-gnatn2} that can be directly |
| specified in lieu of it, @code{-gnatn} being translated into one of them |
| based on the optimization level. With @code{-O2} or below, @code{-gnatn} |
| is equivalent to @code{-gnatn1} which activates pragma @code{Inline} with |
| moderate inlining across modules. With @code{-O3}, @code{-gnatn} is |
| equivalent to @code{-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 @code{-O2} |
| and @code{-gnatn} and avoid the use of @code{-O3} which has the additional |
| effect of inlining subprograms you did not think should be inlined. We have |
| found that the use of @code{-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 @code{-O3} is better than @code{-O2}, and |
| indeed you should use @code{-O3} only if tests show that it actually |
| improves performance for your program. |
| |
| @node Floating Point Operations,Vectorization of loops,Inlining of Subprograms,Performance Considerations |
| @anchor{gnat_ugn/gnat_and_program_execution floating-point-operations}@anchor{186}@anchor{gnat_ugn/gnat_and_program_execution id33}@anchor{187} |
| @subsubsection Floating Point Operations |
| |
| |
| @geindex Floating-Point Operations |
| |
| On almost all targets, GNAT maps Float and Long_Float to the 32-bit and |
| 64-bit standard IEEE floating-point representations, and operations will |
| use standard IEEE arithmetic as provided by the processor. On most, but |
| not all, architectures, the attribute Machine_Overflows is False for these |
| types, meaning that the semantics of overflow is implementation-defined. |
| In the case of GNAT, these semantics correspond to the normal IEEE |
| treatment of infinities and NaN (not a number) values. For example, |
| 1.0 / 0.0 yields plus infinitiy and 0.0 / 0.0 yields a NaN. By |
| avoiding explicit overflow checks, the performance is greatly improved |
| on many targets. However, if required, floating-point overflow can be |
| enabled by the use of the pragma Check_Float_Overflow. |
| |
| Another consideration that applies specifically to x86 32-bit |
| architectures is which form of floating-point arithmetic is used. |
| By default the operations use the old style x86 floating-point, |
| which implements an 80-bit extended precision form (on these |
| architectures the type Long_Long_Float corresponds to that form). |
| In addition, generation of efficient code in this mode means that |
| the extended precision form will be used for intermediate results. |
| This may be helpful in improving the final precision of a complex |
| expression. However it means that the results obtained on the x86 |
| will be different from those on other architectures, and for some |
| algorithms, the extra intermediate precision can be detrimental. |
| |
| In addition to this old-style floating-point, all modern x86 chips |
| implement an alternative floating-point operation model referred |
| to as SSE2. In this model there is no extended form, and furthermore |
| execution performance is significantly enhanced. To force GNAT to use |
| this more modern form, use both of the switches: |
| |
| @quotation |
| |
| -msse2 -mfpmath=sse |
| @end quotation |
| |
| A unit compiled with these switches will automatically use the more |
| efficient SSE2 instruction set for Float and Long_Float operations. |
| Note that the ABI has the same form for both floating-point models, |
| so it is permissible to mix units compiled with and without these |
| switches. |
| |
| @node Vectorization of loops,Other Optimization Switches,Floating Point Operations,Performance Considerations |
| @anchor{gnat_ugn/gnat_and_program_execution id34}@anchor{188}@anchor{gnat_ugn/gnat_and_program_execution vectorization-of-loops}@anchor{189} |
| @subsubsection Vectorization of loops |
| |
| |
| @geindex Optimization Switches |
| |
| You can take advantage of the auto-vectorizer present in the @code{gcc} |
| back end to vectorize loops with GNAT. The corresponding command line switch |
| is @code{-ftree-vectorize} but, as it is enabled by default at @code{-O3} |
| and other aggressive optimizations helpful for vectorization also are enabled |
| by default at this level, using @code{-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 @code{-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 @code{-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: |
| |
| @quotation |
| |
| @example |
| 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 example |
| @end quotation |
| |
| 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 compiling |
| with @code{-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: |
| |
| @quotation |
| |
| @example |
| Integer (S'Truncation (F)) |
| @end example |
| @end quotation |
| |
| 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: |
| |
| @quotation |
| |
| @example |
| type Array_Type is array (1 .. 4) of Long_Float; |
| @end example |
| @end quotation |
| |
| constrained array types with dynamic bounds: |
| |
| @quotation |
| |
| @example |
| 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 example |
| @end quotation |
| |
| or unconstrained array types: |
| |
| @quotation |
| |
| @example |
| type Array_Type is array (Positive range <>) of Long_Float; |
| @end example |
| @end quotation |
| |
| 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}: |
| |
| @quotation |
| |
| @example |
| pragma Loop_Optimize (Vector); |
| @end example |
| @end quotation |
| |
| placed immediately within the loop will convey the appropriate hint to the |
| compiler for this loop. |
| |
| It is also possible to help the compiler generate better vectorized code |
| for a given loop by asserting that there are no loop-carried dependencies |
| in the loop. Consider for example the procedure: |
| |
| @quotation |
| |
| @example |
| type Arr is array (1 .. 4) of Long_Float; |
| |
| procedure Add (X, Y : not null access Arr; R : not null access Arr) is |
| begin |
| for I in Arr'Range loop |
| R(I) := X(I) + Y(I); |
| end loop; |
| end; |
| @end example |
| @end quotation |
| |
| By default, the compiler cannot unconditionally vectorize the loop because |
| assigning to a component of the array designated by R in one iteration could |
| change the value read from the components of the array designated by X or Y |
| in a later iteration. As a result, the compiler will generate two versions |
| of the loop in the object code, one vectorized and the other not vectorized, |
| as well as a test to select the appropriate version at run time. This can |
| be overcome by another hint: |
| |
| @quotation |
| |
| @example |
| pragma Loop_Optimize (Ivdep); |
| @end example |
| @end quotation |
| |
| placed immediately within the loop will tell the compiler that it can safely |
| omit the non-vectorized version of the loop as well as the run-time test. |
| |
| @node Other Optimization Switches,Optimization and Strict Aliasing,Vectorization of loops,Performance Considerations |
| @anchor{gnat_ugn/gnat_and_program_execution id35}@anchor{18a}@anchor{gnat_ugn/gnat_and_program_execution other-optimization-switches}@anchor{18b} |
| @subsubsection Other Optimization Switches |
| |
| |
| @geindex Optimization Switches |
| |
| Since GNAT uses the @code{gcc} back end, all the specialized |
| @code{gcc} optimization switches are potentially usable. These switches |
| have not been extensively tested with GNAT but can generally be expected |
| to work. Examples of switches in this category are @code{-funroll-loops} |
| and the various target-specific @code{-m} options (in particular, it has |
| been observed that @code{-march=xxx} can significantly improve performance |
| on appropriate machines). For full details of these switches, see |
| the @emph{Submodel Options} section in the @emph{Hardware Models and Configurations} |
| chapter of @cite{Using the GNU Compiler Collection (GCC)}. |
| |
| @node Optimization and Strict Aliasing,Aliased Variables and Optimization,Other Optimization Switches,Performance Considerations |
| @anchor{gnat_ugn/gnat_and_program_execution id36}@anchor{18c}@anchor{gnat_ugn/gnat_and_program_execution optimization-and-strict-aliasing}@anchor{e4} |
| @subsubsection Optimization and Strict Aliasing |
| |
| |
| @geindex Aliasing |
| |
| @geindex Strict Aliasing |
| |
| @geindex No_Strict_Aliasing |
| |
| 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: |
| |
| @quotation |
| |
| @example |
| procedure R is |
| type Int1 is new Integer; |
| type Int2 is new Integer; |
| type Int1A is access Int1; |
| type Int2A is access Int2; |
| Int1V : Int1A; |
| Int2V : Int2A; |
| ... |
| |
| begin |
| ... |
| for J in Data'Range loop |
| if Data (J) = Int1V.all then |
| Int2V.all := Int2V.all + 1; |
| end if; |
| end loop; |
| ... |
| end R; |
| @end example |
| @end quotation |
| |
| 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 @code{-O2} or |
| higher or @code{-Os} and allows 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: |
| |
| @quotation |
| |
| @example |
| 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 example |
| @end quotation |
| |
| This program prints out 0 in @code{-O0} or @code{-O1} |
| mode, but it prints out 1 in @code{-O2} mode. That’s |
| because in strict aliasing mode, the compiler can and |
| does assume that the assignment to @code{v2.all} could not |
| affect the value of @code{v1.all}, since different types |
| are involved. |
| |
| This behavior is not a case of non-conformance with the standard, since |
| the Ada RM specifies that an unchecked conversion where the resulting |
| bit pattern is not a correct value of the target type can result in an |
| abnormal value and attempting to reference an abnormal value makes the |
| execution of a program erroneous. That’s the case here since the result |
| does not point to an object of type @code{int2}. This means that the |
| effect is entirely unpredictable. |
| |
| However, although that explanation may satisfy a language |
| lawyer, in practice an applications programmer expects an |
| unchecked conversion involving pointers to create true |
| aliases and the behavior of printing 1 seems plain wrong. |
| In this case, the strict aliasing optimization is unwelcome. |
| |
| Indeed the compiler recognizes this possibility, and the |
| unchecked conversion generates a warning: |
| |
| @quotation |
| |
| @example |
| 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 example |
| @end quotation |
| |
| Unfortunately the problem is recognized when compiling the body of |
| package @code{p2}, but the actual “bad” code is generated while |
| compiling the body of @code{m} and this latter compilation does not see |
| the suspicious @code{Unchecked_Conversion}. |
| |
| As implied by the warning message, there are approaches you can use to |
| avoid the unwanted strict aliasing optimization in a case like this. |
| |
| One possibility is to simply avoid the use of @code{-O2}, but |
| that is a bit drastic, since it throws away a number of useful |
| optimizations that do not involve strict aliasing assumptions. |
| |
| A less drastic approach is to compile the program using the |
| option @code{-fno-strict-aliasing}. Actually it is only the |
| unit containing the dereferencing of the suspicious pointer |
| that needs to be compiled. So in this case, if we compile |
| unit @code{m} with this switch, then we get the expected |
| value of zero printed. Analyzing which units might need |
| the switch can be painful, so a more reasonable approach |
| is to compile the entire program with options @code{-O2} |
| and @code{-fno-strict-aliasing}. If the performance is |
| satisfactory with this combination of options, then the |
| advantage is that the entire issue of possible “wrong” |
| optimization due to strict aliasing is avoided. |
| |
| To avoid the use of compiler switches, the configuration |
| pragma @code{No_Strict_Aliasing} with no parameters may be |
| used to specify that for all access types, the strict |
| aliasing optimization should be suppressed. |
| |
| However, these approaches are still overkill, in that they causes |
| all manipulations of all access values to be deoptimized. A more |
| refined approach is to concentrate attention on the specific |
| access type identified as problematic. |
| |
| First, if a careful analysis of uses of the pointer shows |
| that there are no possible problematic references, then |
| the warning can be suppressed by bracketing the |
| instantiation of @code{Unchecked_Conversion} to turn |
| the warning off: |
| |
| @quotation |
| |
| @example |
| pragma Warnings (Off); |
| function to_a2u is |
| new Unchecked_Conversion (a1, a2); |
| pragma Warnings (On); |
| @end example |
| @end quotation |
| |
| 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: |
| |
| @quotation |
| |
| @example |
| type a2 is access int2; |
| pragma No_Strict_Aliasing (a2); |
| @end example |
| @end quotation |
| |
| 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 |
| @code{-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 @code{-O2} |
| and @code{-O2 -fno-strict-aliasing} to see how much effect this |
| has on size and speed of the code. If you really need to use |
| @code{-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. |
| |
| @node Aliased Variables and Optimization,Atomic Variables and Optimization,Optimization and Strict Aliasing,Performance Considerations |
| @anchor{gnat_ugn/gnat_and_program_execution aliased-variables-and-optimization}@anchor{18d}@anchor{gnat_ugn/gnat_and_program_execution id37}@anchor{18e} |
| @subsubsection Aliased Variables and Optimization |
| |
| |
| @geindex Aliasing |
| |
| There are scenarios in which programs may |
| use low level techniques to modify variables |
| that otherwise might be considered to be unassigned. For example, |
| a variable can be passed to a procedure by reference, which takes |
| the address of the parameter and uses the address to modify the |
| variable’s value, even though it is passed as an IN parameter. |
| Consider the following example: |
| |
| @quotation |
| |
| @example |
| procedure P is |
| Max_Length : constant Natural := 16; |
| type Char_Ptr is access all Character; |
| |
| procedure Get_String(Buffer: Char_Ptr; Size : Integer); |
| pragma Import (C, Get_String, "get_string"); |
| |
| Name : aliased String (1 .. Max_Length) := (others => ' '); |
| Temp : Char_Ptr; |
| |
| function Addr (S : String) return Char_Ptr is |
| function To_Char_Ptr is |
| new Ada.Unchecked_Conversion (System.Address, Char_Ptr); |
| begin |
| return To_Char_Ptr (S (S'First)'Address); |
| end; |
| |
| begin |
| Temp := Addr (Name); |
| Get_String (Temp, Max_Length); |
| end; |
| @end example |
| @end quotation |
| |
| where Get_String is a C function that uses the address in Temp to |
| modify the variable @code{Name}. This code is dubious, and arguably |
| erroneous, and the compiler would be entitled to assume that |
| @code{Name} is never modified, and generate code accordingly. |
| |
| However, in practice, this would cause some existing code that |
| seems to work with no optimization to start failing at high |
| levels of optimzization. |
| |
| What the compiler does for such cases is to assume that marking |
| a variable as aliased indicates that some “funny business” may |
| be going on. The optimizer recognizes the aliased keyword and |
| inhibits optimizations that assume the value cannot be assigned. |
| This means that the above example will in fact “work” reliably, |
| that is, it will produce the expected results. |
| |
| @node Atomic Variables and Optimization,Passive Task Optimization,Aliased Variables and Optimization,Performance Considerations |
| @anchor{gnat_ugn/gnat_and_program_execution atomic-variables-and-optimization}@anchor{18f}@anchor{gnat_ugn/gnat_and_program_execution id38}@anchor{190} |
| @subsubsection Atomic Variables and Optimization |
| |
| |
| @geindex Atomic |
| |
| There are two considerations with regard to performance when |
| atomic variables are used. |
| |
| First, the RM only guarantees that access to atomic variables |
| be atomic, it has nothing to say about how this is achieved, |
| though there is a strong implication that this should not be |
| achieved by explicit locking code. Indeed GNAT will never |
| generate any locking code for atomic variable access (it will |
| simply reject any attempt to make a variable or type atomic |
| if the atomic access cannot be achieved without such locking code). |
| |
| That being said, it is important to understand that you cannot |
| assume that the entire variable will always be accessed. Consider |
| this example: |
| |
| @quotation |
| |
| @example |
| type R is record |
| A,B,C,D : Character; |
| end record; |
| for R'Size use 32; |
| for R'Alignment use 4; |
| |
| RV : R; |
| pragma Atomic (RV); |
| X : Character; |
| ... |
| X := RV.B; |
| @end example |
| @end quotation |
| |
| You cannot assume that the reference to @code{RV.B} |
| will read the entire 32-bit |
| variable with a single load instruction. It is perfectly legitimate if |
| the hardware allows it to do a byte read of just the B field. This read |
| is still atomic, which is all the RM requires. GNAT can and does take |
| advantage of this, depending on the architecture and optimization level. |
| Any assumption to the contrary is non-portable and risky. Even if you |
| examine the assembly language and see a full 32-bit load, this might |
| change in a future version of the compiler. |
| |
| If your application requires that all accesses to @code{RV} in this |
| example be full 32-bit loads, you need to make a copy for the access |
| as in: |
| |
| @quotation |
| |
| @example |
| declare |
| RV_Copy : constant R := RV; |
| begin |
| X := RV_Copy.B; |
| end; |
| @end example |
| @end quotation |
| |
| Now the reference to RV must read the whole variable. |
| Actually one can imagine some compiler which figures |
| out that the whole copy is not required (because only |
| the B field is actually accessed), but GNAT |
| certainly won’t do that, and we don’t know of any |
| compiler that would not handle this right, and the |
| above code will in practice work portably across |
| all architectures (that permit the Atomic declaration). |
| |
| The second issue with atomic variables has to do with |
| the possible requirement of generating synchronization |
| code. For more details on this, consult the sections on |
| the pragmas Enable/Disable_Atomic_Synchronization in the |
| GNAT Reference Manual. If performance is critical, and |
| such synchronization code is not required, it may be |
| useful to disable it. |
| |
| @node Passive Task Optimization,,Atomic Variables and Optimization,Performance Considerations |
| @anchor{gnat_ugn/gnat_and_program_execution id39}@anchor{191}@anchor{gnat_ugn/gnat_and_program_execution passive-task-optimization}@anchor{192} |
| @subsubsection Passive Task Optimization |
| |
| |
| @geindex Passive Task |
| |
| A passive task is one which is sufficiently simple that |
| in theory a compiler could recognize it an implement it |
| efficiently without creating a new thread. The original design |
| of Ada 83 had in mind this kind of passive task optimization, but |
| only a few Ada 83 compilers attempted it. The problem was that |
| it was difficult to determine the exact conditions under which |
| the optimization was possible. The result is a very fragile |
| optimization where a very minor change in the program can |
| suddenly silently make a task non-optimizable. |
| |
| With the revisiting of this issue in Ada 95, there was general |
| agreement that this approach was fundamentally flawed, and the |
| notion of protected types was introduced. When using protected |
| types, the restrictions are well defined, and you KNOW that the |
| operations will be optimized, and furthermore this optimized |
| performance is fully portable. |
| |
| Although it would theoretically be possible for GNAT to attempt to |
| do this optimization, but it really doesn’t make sense in the |
| context of Ada 95, and none of the Ada 95 compilers implement |
| this optimization as far as we know. In particular GNAT never |
| attempts to perform this optimization. |
| |
| In any new Ada 95 code that is written, you should always |
| use protected types in place of tasks that might be able to |
| be optimized in this manner. |
| Of course this does not help if you have legacy Ada 83 code |
| that depends on this optimization, but it is unusual to encounter |
| a case where the performance gains from this optimization |
| are significant. |
| |
| Your program should work correctly without this optimization. If |
| you have performance problems, then the most practical |
| approach is to figure out exactly where these performance problems |
| arise, and update those particular tasks to be protected types. Note |
| that typically clients of the tasks who call entries, will not have |
| to be modified, only the task definition itself. |
| |
| @node Text_IO Suggestions,Reducing Size of Executables with Unused Subprogram/Data Elimination,Performance Considerations,Improving Performance |
| @anchor{gnat_ugn/gnat_and_program_execution id40}@anchor{193}@anchor{gnat_ugn/gnat_and_program_execution text-io-suggestions}@anchor{194} |
| @subsection @code{Text_IO} Suggestions |
| |
| |
| @geindex Text_IO and performance |
| |
| 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 @emph{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 Executables with Unused Subprogram/Data Elimination,,Text_IO Suggestions,Improving Performance |
| @anchor{gnat_ugn/gnat_and_program_execution id41}@anchor{195}@anchor{gnat_ugn/gnat_and_program_execution reducing-size-of-executables-with-unused-subprogram-data-elimination}@anchor{196} |
| @subsection Reducing Size of Executables with Unused Subprogram/Data Elimination |
| |
| |
| @geindex Uunused subprogram/data elimination |
| |
| 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,Compilation options,,Reducing Size of Executables with Unused Subprogram/Data Elimination |
| @anchor{gnat_ugn/gnat_and_program_execution about-unused-subprogram-data-elimination}@anchor{197}@anchor{gnat_ugn/gnat_and_program_execution id42}@anchor{198} |
| @subsubsection About unused subprogram/data elimination |
| |
| |
| 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,Example of unused subprogram/data elimination,About unused subprogram/data elimination,Reducing Size of Executables with Unused Subprogram/Data Elimination |
| @anchor{gnat_ugn/gnat_and_program_execution compilation-options}@anchor{199}@anchor{gnat_ugn/gnat_and_program_execution id43}@anchor{19a} |
| @subsubsection Compilation options |
| |
| |
| The operation of eliminating the unused code and data from the final executable |
| is directly performed by the linker. |
| |
| @geindex -ffunction-sections (gcc) |
| |
| @geindex -fdata-sections (gcc) |
| |
| In order to do this, it has to work with objects compiled with the |
| following options: |
| @code{-ffunction-sections} @code{-fdata-sections}. |
| |
| 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 @code{-Wl,--gc-sections} option to gcc command or in the |
| @code{-largs} section of @code{gnatmake}. This will perform a |
| garbage collection of code and data never referenced. |
| |
| If the linker performs a partial link (@code{-r} linker option), then you |
| will need to provide the entry point using the @code{-e} / @code{--entry} |
| linker option. |
| |
| Note that objects compiled without the @code{-ffunction-sections} and |
| @code{-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,,Compilation options,Reducing Size of Executables with Unused Subprogram/Data Elimination |
| @anchor{gnat_ugn/gnat_and_program_execution example-of-unused-subprogram-data-elimination}@anchor{19b}@anchor{gnat_ugn/gnat_and_program_execution id44}@anchor{19c} |
| @subsubsection Example of unused subprogram/data elimination |
| |
| |
| Here is a simple example: |
| |
| @quotation |
| |
| @example |
| 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 example |
| @end quotation |
| |
| @code{Unused} and @code{Unused_Data} are never referenced in this code |
| excerpt, and hence they may be safely removed from the final executable. |
| |
| @quotation |
| |
| @example |
| $ 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 example |
| @end quotation |
| |
| 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. |
| |
| @geindex Overflow checks |
| |
| @geindex Checks (overflow) |
| |
| @node Overflow Check Handling in GNAT,Performing Dimensionality Analysis in GNAT,Improving Performance,GNAT and Program Execution |
| @anchor{gnat_ugn/gnat_and_program_execution id45}@anchor{149}@anchor{gnat_ugn/gnat_and_program_execution overflow-check-handling-in-gnat}@anchor{19d} |
| @section Overflow Check Handling in GNAT |
| |
| |
| This section explains how to control the handling of overflow checks. |
| |
| @menu |
| * Background:: |
| * Management of Overflows in GNAT:: |
| * Specifying the Desired Mode:: |
| * Default Settings:: |
| * Implementation Notes:: |
| |
| @end menu |
| |
| @node Background,Management of Overflows in GNAT,,Overflow Check Handling in GNAT |
| @anchor{gnat_ugn/gnat_and_program_execution background}@anchor{19e}@anchor{gnat_ugn/gnat_and_program_execution id46}@anchor{19f} |
| @subsection Background |
| |
| |
| Overflow checks are checks that the compiler may make to ensure |
| that intermediate results are not out of range. For example: |
| |
| @quotation |
| |
| @example |
| A : Integer; |
| ... |
| A := A + 1; |
| @end example |
| @end quotation |
| |
| 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: |
| |
| @quotation |
| |
| @example |
| A, C : Integer; |
| ... |
| A := (A + 1) + C; |
| @end example |
| @end quotation |
| |
| 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 * |
| |
| @item |
| raise an exception (@code{Constraint_Error}), or |
| |
| @item |
| yield the correct mathematical result which is then used in |
| subsequent operations. |
| @end itemize |
| |
| 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: |
| |
| @quotation |
| |
| @example |
| procedure P (A, B : Integer) with |
| Pre => A + B <= Integer'Last; |
| @end example |
| @end quotation |
| |
| 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: |
| |
| @quotation |
| |
| @example |
| procedure Q (A, B, C : Integer) with |
| Pre => A + B + C <= Integer'Last; |
| @end example |
| @end quotation |
| |
| Consider the call |
| |
| @quotation |
| |
| @example |
| Q (A => Integer'Last, B => 1, C => -1); |
| @end example |
| @end quotation |
| |
| 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 Management of Overflows in GNAT,Specifying the Desired Mode,Background,Overflow Check Handling in GNAT |
| @anchor{gnat_ugn/gnat_and_program_execution id47}@anchor{1a0}@anchor{gnat_ugn/gnat_and_program_execution management-of-overflows-in-gnat}@anchor{1a1} |
| @subsection Management of Overflows in GNAT |
| |
| |
| To deal with the portability issue, and with the problem of |
| mathematical versus run-time interpretation 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 * |
| |
| @item |
| @emph{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 |
| @emph{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: |
| |
| @quotation |
| |
| @example |
| procedure R (A, B, C, D : Integer) with |
| Pre => (A**2 * B**2) / (C**2 * D**2) <= 10; |
| @end example |
| @end quotation |
| |
| 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 @emph{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 |
| @emph{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 |
| |
| Note that these modes apply only to the evaluation of predefined |
| arithmetic, membership, and comparison operators for signed integer |
| arithmetic. |
| |
| 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). |
| |
| @node Specifying the Desired Mode,Default Settings,Management of Overflows in GNAT,Overflow Check Handling in GNAT |
| @anchor{gnat_ugn/gnat_and_program_execution id48}@anchor{1a2}@anchor{gnat_ugn/gnat_and_program_execution specifying-the-desired-mode}@anchor{e9} |
| @subsection Specifying the Desired Mode |
| |
| |
| @geindex pragma Overflow_Mode |
| |
| 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 |
| |
| @quotation |
| |
| @example |
| pragma Overflow_Mode ([General =>] MODE [, [Assertions =>] MODE]); |
| @end example |
| @end quotation |
| |
| where @code{MODE} is one of |
| |
| |
| @itemize * |
| |
| @item |
| @code{STRICT}: intermediate overflows checked (using base type) |
| |
| @item |
| @code{MINIMIZED}: minimize intermediate overflows |
| |
| @item |
| @code{ELIMINATED}: eliminate intermediate overflows |
| @end itemize |
| |
| 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: |
| |
| @quotation |
| |
| @example |
| pragma Overflow_Mode |
| (General => Minimized, Assertions => Eliminated); |
| @end example |
| @end quotation |
| |
| 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. |
| |
| @geindex -gnato? (gcc) |
| |
| @geindex -gnato?? (gcc) |
| |
| Additionally, a compiler switch @code{-gnato?} or @code{-gnato??} |
| can be used to control the checking mode default (which can be subsequently |
| overridden using pragmas). |
| |
| Here @code{?} is one of the digits @code{1} through @code{3}: |
| |
| @quotation |
| |
| |
| @multitable {xxxxxxxx} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx} |
| @item |
| |
| @code{1} |
| |
| @tab |
| |
| use base type for intermediate operations (@code{STRICT}) |
| |
| @item |
| |
| @code{2} |
| |
| @tab |
| |
| minimize intermediate overflows (@code{MINIMIZED}) |
| |
| @item |
| |
| @code{3} |
| |
| @tab |
| |
| eliminate intermediate overflows (@code{ELIMINATED}) |
| |
| @end multitable |
| |
| @end quotation |
| |
| 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 |
| @code{-gnato23}. |
| |
| If no digits follow the @code{-gnato}, then it is equivalent to |
| @code{-gnato11}, |
| causing all intermediate operations to be computed using the base |
| type (@code{STRICT} mode). |
| |
| @node Default Settings,Implementation Notes,Specifying the Desired Mode,Overflow Check Handling in GNAT |
| @anchor{gnat_ugn/gnat_and_program_execution default-settings}@anchor{1a3}@anchor{gnat_ugn/gnat_and_program_execution id49}@anchor{1a4} |
| @subsection Default Settings |
| |
| |
| The default mode for overflow checks is |
| |
| @quotation |
| |
| @example |
| General => Strict |
| @end example |
| @end quotation |
| |
| which causes all computations both inside and outside assertions to use |
| the base type. |
| |
| 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. |
| |
| @c Sphinx allows no emphasis within :index: role. As a workaround we |
| @c point the index to "switch" and use emphasis for "-gnato". |
| |
| The |
| @geindex -gnato (gcc) |
| switch @code{-gnato} (with no digits following) |
| is equivalent to |
| |
| @quotation |
| |
| @example |
| General => Strict |
| @end example |
| @end quotation |
| |
| which causes overflow checking of all intermediate overflows |
| both inside and outside assertions against the base type. |
| |
| 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. |
| |
| @node Implementation Notes,,Default Settings,Overflow Check Handling in GNAT |
| @anchor{gnat_ugn/gnat_and_program_execution id50}@anchor{1a5}@anchor{gnat_ugn/gnat_and_program_execution implementation-notes}@anchor{1a6} |
| @subsection 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, @code{A+B+C} parses as though it were @code{(A+B)+C}, but |
| the compiler can reintepret this as @code{A+(B+C)}, possibly |
| introducing or eliminating an overflow exception. The GNAT |
| compiler never takes advantage of this freedom, and the |
| expression @code{A+B+C} will be evaluated as @code{(A+B)+C}. |
| If you need the other order, you can write the parentheses |
| explicitly @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 |
| allocation, 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). |
| |
| @node Performing Dimensionality Analysis in GNAT,Stack Related Facilities,Overflow Check Handling in GNAT,GNAT and Program Execution |
| @anchor{gnat_ugn/gnat_and_program_execution id51}@anchor{14a}@anchor{gnat_ugn/gnat_and_program_execution performing-dimensionality-analysis-in-gnat}@anchor{1a7} |
| @section Performing Dimensionality Analysis in GNAT |
| |
| |
| @geindex Dimensionality analysis |
| |
| The GNAT compiler 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 constituents. |
| |
| @geindex Dimension_System aspect |
| |
| @geindex Dimension aspect |
| |
| This feature depends on Ada 2012 aspect specifications, and is available from |
| version 7.0.1 of GNAT onwards. |
| The GNAT-specific aspect @code{Dimension_System} |
| allows you to define a system of units; the aspect @code{Dimension} |
| then allows the user to declare dimensioned quantities within a given system. |
| (These aspects are described in the @emph{Implementation Defined Aspects} |
| chapter of the @emph{GNAT Reference Manual}). |
| |
| 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. |
| |
| @geindex System.Dim.Mks package (GNAT library) |
| |
| @geindex MKS_Type type |
| |
| The simplest way to impose dimensionality checking on a computation is to make |
| use of one of the instantiations of the package @code{System.Dim.Generic_Mks}, which |
| are part of the GNAT library. This generic package defines a floating-point |
| type @code{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 |
| @code{s-digemk.ads}. |
| |
| @quotation |
| |
| @geindex s-digemk.ads file |
| |
| @example |
| type Mks_Type is new Float_Type |
| 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 example |
| @end quotation |
| |
| The package then defines a series of subtypes that correspond to these |
| conventional units. For example: |
| |
| @quotation |
| |
| @example |
| subtype Length is Mks_Type |
| with |
| Dimension => (Symbol => 'm', Meter => 1, others => 0); |
| @end example |
| @end quotation |
| |
| and similarly for @code{Mass}, @code{Time}, @code{Electric_Current}, |
| @code{Thermodynamic_Temperature}, @code{Amount_Of_Substance}, and |
| @code{Luminous_Intensity} (the standard set of units of the SI system). |
| |
| The package also defines conventional names for values of each unit, for |
| example: |
| |
| @quotation |
| |
| @example |
| m : constant Length := 1.0; |
| kg : constant Mass := 1.0; |
| s : constant Time := 1.0; |
| A : constant Electric_Current := 1.0; |
| @end example |
| @end quotation |
| |
| as well as useful multiples of these units: |
| |
| @quotation |
| |
| @example |
| 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 example |
| @end quotation |
| |
| There are three instantiations of @code{System.Dim.Generic_Mks} defined in the |
| GNAT library: |
| |
| |
| @itemize * |
| |
| @item |
| @code{System.Dim.Float_Mks} based on @code{Float} defined in @code{s-diflmk.ads}. |
| |
| @item |
| @code{System.Dim.Long_Mks} based on @code{Long_Float} defined in @code{s-dilomk.ads}. |
| |
| @item |
| @code{System.Dim.Mks} based on @code{Long_Long_Float} defined in @code{s-dimmks.ads}. |
| @end itemize |
| |
| Using one of these packages, you 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: |
| |
| @quotation |
| |
| @example |
| subtype Acceleration is Mks_Type |
| with Dimension => ("m/sec^2", |
| Meter => 1, |
| Second => -2, |
| others => 0); |
| @end example |
| @end quotation |
| |
| Here is a complete example of use: |
| |
| @quotation |
| |
| @example |
| 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 example |
| @end quotation |
| |
| Execution of this program yields: |
| |
| @quotation |
| |
| @example |
| Gravitational constant: 9.81 m/sec^2 |
| distance travelled in 10 seconds of free fall 490.50 m |
| @end example |
| @end quotation |
| |
| However, incorrect assignments such as: |
| |
| @quotation |
| |
| @example |
| Distance := 5.0; |
| Distance := 5.0 * kg; |
| @end example |
| @end quotation |
| |
| are rejected with the following diagnoses: |
| |
| @quotation |
| |
| @example |
| 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 example |
| @end quotation |
| |
| The dimensions of an expression are properly displayed, even if there is |
| no explicit subtype for it. If we add to the program: |
| |
| @quotation |
| |
| @example |
| Put ("Final velocity: "); |
| Put (G * T, Aft =>2, Exp =>0); |
| Put_Line (""); |
| @end example |
| @end quotation |
| |
| then the output includes: |
| |
| @quotation |
| |
| @example |
| Final velocity: 98.10 m.s**(-1) |
| @end example |
| |
| @geindex Dimensionable type |
| |
| @geindex Dimensioned subtype |
| @end quotation |
| |
| The type @code{Mks_Type} is said to be a @emph{dimensionable type} since it has a |
| @code{Dimension_System} aspect, and the subtypes @code{Length}, @code{Mass}, etc., |
| are said to be @emph{dimensioned subtypes} since each one has a @code{Dimension} |
| aspect. |
| |
| @quotation |
| |
| @geindex Dimension Vector (for a dimensioned subtype) |
| |
| @geindex Dimension aspect |
| |
| @geindex Dimension_System aspect |
| @end quotation |
| |
| The @code{Dimension} aspect of a dimensioned subtype @code{S} defines a mapping |
| from the base type’s Unit_Names to integer (or, more generally, rational) |
| values. This mapping is the @emph{dimension vector} (also referred to as the |
| @emph{dimensionality}) for that subtype, denoted by @code{DV(S)}, and thus for each |
| object of that subtype. Intuitively, the value specified for each |
| @code{Unit_Name} is the exponent associated with that unit; a zero value |
| means that the unit is not used. For example: |
| |
| @quotation |
| |
| @example |
| declare |
| Acc : Acceleration; |
| ... |
| begin |
| ... |
| end; |
| @end example |
| @end quotation |
| |
| Here @code{DV(Acc)} = @code{DV(Acceleration)} = |
| @code{(Meter=>1, Kilogram=>0, Second=>-2, Ampere=>0, Kelvin=>0, Mole=>0, Candela=>0)}. |
| Symbolically, we can express this as @code{Meter / Second**2}. |
| |
| The dimension vector of an arithmetic expression is synthesized from the |
| dimension vectors of its components, with compile-time dimensionality checks |
| that help prevent mismatches such as using an @code{Acceleration} where a |
| @code{Length} is required. |
| |
| The dimension vector of the result of an arithmetic expression @emph{expr}, or |
| @code{DV(@emph{expr})}, is defined as follows, assuming conventional |
| mathematical definitions for the vector operations that are used: |
| |
| |
| @itemize * |
| |
| @item |
| If @emph{expr} is of the type @emph{universal_real}, or is not of a dimensioned subtype, |
| then @emph{expr} is dimensionless; @code{DV(@emph{expr})} is the empty vector. |
| |
| @item |
| @code{DV(@emph{op expr})}, where @emph{op} is a unary operator, is @code{DV(@emph{expr})} |
| |
| @item |
| @code{DV(@emph{expr1 op expr2})} where @emph{op} is “+” or “-” is @code{DV(@emph{expr1})} |
| provided that @code{DV(@emph{expr1})} = @code{DV(@emph{expr2})}. |
| If this condition is not met then the construct is illegal. |
| |
| @item |
| @code{DV(@emph{expr1} * @emph{expr2})} is @code{DV(@emph{expr1})} + @code{DV(@emph{expr2})}, |
| and @code{DV(@emph{expr1} / @emph{expr2})} = @code{DV(@emph{expr1})} - @code{DV(@emph{expr2})}. |
| In this context if one of the @emph{expr}s is dimensionless then its empty |
| dimension vector is treated as @code{(others => 0)}. |
| |
| @item |
| @code{DV(@emph{expr} ** @emph{power})} is @emph{power} * @code{DV(@emph{expr})}, |
| provided that @emph{power} is a static rational value. If this condition is not |
| met then the construct is illegal. |
| @end itemize |
| |
| Note that, by the above rules, it is illegal to use binary “+” or “-” to |
| combine a dimensioned and dimensionless value. Thus an expression such as |
| @code{acc-10.0} is illegal, where @code{acc} is an object of subtype |
| @code{Acceleration}. |
| |
| The dimensionality checks for relationals use the same rules as |
| for “+” and “-“, except when comparing to a literal; thus |
| |
| @quotation |
| |
| @example |
| acc > len |
| @end example |
| @end quotation |
| |
| is equivalent to |
| |
| @quotation |
| |
| @example |
| acc-len > 0.0 |
| @end example |
| @end quotation |
| |
| and is thus illegal, but |
| |
| @quotation |
| |
| @example |
| acc > 10.0 |
| @end example |
| @end quotation |
| |
| is accepted with a warning. Analogously a conditional expression requires the |
| same dimension vector for each branch (with no exception for literals). |
| |
| The dimension vector of a type conversion @code{T(@emph{expr})} is defined |
| as follows, based on the nature of @code{T}: |
| |
| |
| @itemize * |
| |
| @item |
| If @code{T} is a dimensioned subtype then @code{DV(T(@emph{expr}))} is @code{DV(T)} |
| provided that either @emph{expr} is dimensionless or |
| @code{DV(T)} = @code{DV(@emph{expr})}. The conversion is illegal |
| if @emph{expr} is dimensioned and @code{DV(@emph{expr})} /= @code{DV(T)}. |
| Note that vector equality does not require that the corresponding |
| Unit_Names be the same. |
| |
| As a consequence of the above rule, it is possible to convert between |
| different dimension systems that follow the same international system |
| of units, with the seven physical components given in the standard order |
| (length, mass, time, etc.). Thus a length in meters can be converted to |
| a length in inches (with a suitable conversion factor) but cannot be |
| converted, for example, to a mass in pounds. |
| |
| @item |
| If @code{T} is the base type for @emph{expr} (and the dimensionless root type of |
| the dimension system), then @code{DV(T(@emph{expr}))} is @code{DV(expr)}. |
| Thus, if @emph{expr} is of a dimensioned subtype of @code{T}, the conversion may |
| be regarded as a “view conversion” that preserves dimensionality. |
| |
| This rule makes it possible to write generic code that can be instantiated |
| with compatible dimensioned subtypes. The generic unit will contain |
| conversions that will consequently be present in instantiations, but |
| conversions to the base type will preserve dimensionality and make it |
| possible to write generic code that is correct with respect to |
| dimensionality. |
| |
| @item |
| Otherwise (i.e., @code{T} is neither a dimensioned subtype nor a dimensionable |
| base type), @code{DV(T(@emph{expr}))} is the empty vector. Thus a dimensioned |
| value can be explicitly converted to a non-dimensioned subtype, which |
| of course then escapes dimensionality analysis. |
| @end itemize |
| |
| The dimension vector for a type qualification @code{T'(@emph{expr})} is the same |
| as for the type conversion @code{T(@emph{expr})}. |
| |
| An assignment statement |
| |
| @quotation |
| |
| @example |
| Source := Target; |
| @end example |
| @end quotation |
| |
| requires @code{DV(Source)} = @code{DV(Target)}, and analogously for parameter |
| passing (the dimension vector for the actual parameter must be equal to the |
| dimension vector for the formal parameter). |
| |
| @node Stack Related Facilities,Memory Management Issues,Performing Dimensionality Analysis in GNAT,GNAT and Program Execution |
| @anchor{gnat_ugn/gnat_and_program_execution id52}@anchor{14b}@anchor{gnat_ugn/gnat_and_program_execution stack-related-facilities}@anchor{1a8} |
| @section Stack Related Facilities |
| |
| |
| This section 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,Static Stack Usage Analysis,,Stack Related Facilities |
| @anchor{gnat_ugn/gnat_and_program_execution id53}@anchor{1a9}@anchor{gnat_ugn/gnat_and_program_execution stack-overflow-checking}@anchor{e5} |
| @subsection Stack Overflow Checking |
| |
| |
| @geindex Stack Overflow Checking |
| |
| @geindex -fstack-check (gcc) |
| |
| For most operating systems, @code{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 @code{gcc} option |
| @code{-fstack-check}. For example: |
| |
| @quotation |
| |
| @example |
| $ gcc -c -fstack-check package1.adb |
| @end example |
| @end quotation |
| |
| 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 default stack size is defined by the GNAT runtime, |
| whose size may be modified at bind time through the @code{-d} bind switch |
| (@ref{110,,Switches for gnatbind}). Task specific stack sizes may be set using the |
| @code{Storage_Size} pragma. |
| |
| For the environment task, the stack size is determined by the operating system. |
| Consequently, to modify the size of the environment task please refer to your |
| operating system documentation. |
| |
| @node Static Stack Usage Analysis,Dynamic Stack Usage Analysis,Stack Overflow Checking,Stack Related Facilities |
| @anchor{gnat_ugn/gnat_and_program_execution id54}@anchor{1aa}@anchor{gnat_ugn/gnat_and_program_execution static-stack-usage-analysis}@anchor{e6} |
| @subsection Static Stack Usage Analysis |
| |
| |
| @geindex Static Stack Usage Analysis |
| |
| @geindex -fstack-usage |
| |
| A unit compiled with @code{-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 @code{.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 @code{-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,,Static Stack Usage Analysis,Stack Related Facilities |
| @anchor{gnat_ugn/gnat_and_program_execution dynamic-stack-usage-analysis}@anchor{113}@anchor{gnat_ugn/gnat_and_program_execution id55}@anchor{1ab} |
| @subsection Dynamic Stack Usage Analysis |
| |
| |
| It is possible to measure the maximum amount of stack used by a task, by |
| adding a switch to @code{gnatbind}, as: |
| |
| @quotation |
| |
| @example |
| $ gnatbind -u0 file |
| @end example |
| @end quotation |
| |
| With this option, at each task termination, its stack usage is output on |
| @code{stderr}. |
| Note that this switch is not compatible with tools like |
| Valgrind and DrMemory; they will report errors. |
| |
| It is not always convenient to output the stack usage when the program |
| is still running. Hence, it is possible to delay this output until program |
| termination. for a given number of tasks specified as the argument of the |
| @code{-u} option. For instance: |
| |
| @quotation |
| |
| @example |
| $ gnatbind -u100 file |
| @end example |
| @end quotation |
| |
| 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: |
| |
| @quotation |
| |
| @example |
| Index | Task Name | Stack Size | Stack Usage |
| @end example |
| @end quotation |
| |
| where: |
| |
| |
| @itemize * |
| |
| @item |
| @emph{Index} is a number associated with each task. |
| |
| @item |
| @emph{Task Name} is the name of the task analyzed. |
| |
| @item |
| @emph{Stack Size} is the maximum size for the stack. |
| |
| @item |
| @emph{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 itemize |
| |
| By default the environment task stack, the stack that contains the main unit, |
| is not processed. To enable processing of the environment task stack, the |
| environment variable GNAT_STACK_LIMIT needs to be set to the maximum size of |
| the environment task stack. This amount is given in kilobytes. For example: |
| |
| @quotation |
| |
| @example |
| $ set GNAT_STACK_LIMIT 1600 |
| @end example |
| @end quotation |
| |
| would specify to the analyzer that the environment task stack has a limit |
| of 1.6 megabytes. Any stack usage beyond this will be ignored by the analysis. |
| |
| The package @code{GNAT.Task_Stack_Usage} provides facilities to get |
| stack-usage reports at run time. See its body for the details. |
| |
| @node Memory Management Issues,,Stack Related Facilities,GNAT and Program Execution |
| @anchor{gnat_ugn/gnat_and_program_execution id56}@anchor{14c}@anchor{gnat_ugn/gnat_and_program_execution memory-management-issues}@anchor{1ac} |
| @section Memory Management Issues |
| |
| |
| This section 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’). |
| |
| |
| @menu |
| * Some Useful Memory Pools:: |
| * The GNAT Debug Pool Facility:: |
| |
| @end menu |
| |
| @node Some Useful Memory Pools,The GNAT Debug Pool Facility,,Memory Management Issues |
| @anchor{gnat_ugn/gnat_and_program_execution id57}@anchor{1ad}@anchor{gnat_ugn/gnat_and_program_execution some-useful-memory-pools}@anchor{1ae} |
| @subsection Some Useful Memory Pools |
| |
| |
| @geindex Memory Pool |
| |
| @geindex storage |
| @geindex pool |
| |
| 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: |
| |
| @quotation |
| |
| @example |
| 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 example |
| @end quotation |
| |
| The @code{System.Pool_Local} package offers the @code{Unbounded_Reclaim_Pool} storage |
| pool. The allocation strategy is similar to @code{Pool_Local} |
| 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: |
| |
| @quotation |
| |
| @example |
| 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 example |
| @end quotation |
| |
| The @code{System.Pool_Size} package implements the @code{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: |
| |
| @quotation |
| |
| @example |
| type T1 is access Something; |
| for T1'Storage_Size use 10_000; |
| @end example |
| @end quotation |
| |
| @node The GNAT Debug Pool Facility,,Some Useful Memory Pools,Memory Management Issues |
| @anchor{gnat_ugn/gnat_and_program_execution id58}@anchor{1af}@anchor{gnat_ugn/gnat_and_program_execution the-gnat-debug-pool-facility}@anchor{1b0} |
| @subsection The GNAT Debug Pool Facility |
| |
| |
| @geindex Debug Pool |
| |
| @geindex storage |
| @geindex pool |
| @geindex memory corruption |
| |
| 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. |
| |
| @quotation |
| |
| @example |
| type Ptr is access Some_Type; |
| Pool : GNAT.Debug_Pools.Debug_Pool; |
| for Ptr'Storage_Pool use Pool; |
| @end example |
| @end quotation |
| |
| @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 * |
| |
| @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 |
| |
| 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: |
| |
| @quotation |
| |
| @example |
| 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 example |
| @end quotation |
| |
| The debug pool mechanism provides the following precise diagnostics on the |
| execution of this erroneous program: |
| |
| @quotation |
| |
| @example |
| 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 example |
| @end quotation |
| |
| |
| @c -- Non-breaking space in running text |
| @c -- E.g. Ada |nbsp| 95 |
| |
| @node Platform-Specific Information,Example of Binder Output File,GNAT and Program Execution,Top |
| @anchor{gnat_ugn/platform_specific_information doc}@anchor{1b1}@anchor{gnat_ugn/platform_specific_information id1}@anchor{1b2}@anchor{gnat_ugn/platform_specific_information platform-specific-information}@anchor{d} |
| @chapter Platform-Specific Information |
| |
| |
| This appendix contains information relating to the implementation |
| of run-time libraries on various platforms and also covers |
| topics related to the GNAT implementation on Windows and Mac OS. |
| |
| @menu |
| * Run-Time Libraries:: |
| * Specifying a Run-Time Library:: |
| * GNU/Linux Topics:: |
| * Microsoft Windows Topics:: |
| * Mac OS Topics:: |
| |
| @end menu |
| |
| @node Run-Time Libraries,Specifying a Run-Time Library,,Platform-Specific Information |
| @anchor{gnat_ugn/platform_specific_information id2}@anchor{1b3}@anchor{gnat_ugn/platform_specific_information run-time-libraries}@anchor{1b4} |
| @section Run-Time Libraries |
| |
| |
| @geindex Tasking and threads libraries |
| |
| @geindex Threads libraries and tasking |
| |
| @geindex Run-time libraries (platform-specific information) |
| |
| The GNAT run-time implementation may vary with respect to both the |
| underlying threads library and the exception-handling scheme. |
| For threads support, the default run-time will bind to the thread |
| package of the underlying operating system. |
| |
| For exception handling, either or both of two models are supplied: |
| |
| @quotation |
| |
| @geindex Zero-Cost Exceptions |
| |
| @geindex ZCX (Zero-Cost Exceptions) |
| @end quotation |
| |
| |
| @itemize * |
| |
| @item |
| @strong{Zero-Cost Exceptions} (“ZCX”), |
| which uses binder-generated tables that |
| are interrogated at run time to locate a handler. |
| |
| @geindex setjmp/longjmp Exception Model |
| |
| @geindex SJLJ (setjmp/longjmp Exception Model) |
| |
| @item |
| @strong{setjmp / longjmp} (‘SJLJ’), |
| which uses dynamically-set data to establish |
| the set of handlers |
| @end itemize |
| |
| 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. |
| Note however that the ZCX run-time does not support asynchronous abort |
| of tasks (@code{abort} and @code{select-then-abort} constructs) and will instead |
| implement abort by polling points in the runtime. You can also add additional |
| polling points explicitly if needed in your application via @code{pragma |
| Abort_Defer}. |
| |
| This section summarizes which combinations of threads and exception support |
| are supplied on various GNAT platforms. |
| |
| @menu |
| * Summary of Run-Time Configurations:: |
| |
| @end menu |
| |
| @node Summary of Run-Time Configurations,,,Run-Time Libraries |
| @anchor{gnat_ugn/platform_specific_information id3}@anchor{1b5}@anchor{gnat_ugn/platform_specific_information summary-of-run-time-configurations}@anchor{1b6} |
| @subsection Summary of Run-Time Configurations |
| |
| |
| |
| @multitable {xxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxx} |
| @headitem |
| |
| Platform |
| |
| @tab |
| |
| Run-Time |
| |
| @tab |
| |
| Tasking |
| |
| @tab |
| |
| Exceptions |
| |
| @item |
| |
| GNU/Linux |
| |
| @tab |
| |
| rts-native |
| (default) |
| |
| @tab |
| |
| pthread library |
| |
| @tab |
| |
| ZCX |
| |
| @item |
| |
| rts-sjlj |
| |
| @tab |
| |
| pthread library |
| |
| @tab |
| |
| SJLJ |
| |
| @item |
| |
| Windows |
| |
| @tab |
| |
| rts-native |
| (default) |
| |
| @tab |
| |
| native Win32 threads |
| |
| @tab |
| |
| ZCX |
| |
| @item |
| |
| rts-sjlj |
| |
| @tab |
| |
| native Win32 threads |
| |
| @tab |
| |
| SJLJ |
| |
| @item |
| |
| Mac OS |
| |
| @tab |
| |
| rts-native |
| |
| @tab |
| |
| pthread library |
| |
| @tab |
| |
| ZCX |
| |
| @end multitable |
| |
| |
| @node Specifying a Run-Time Library,GNU/Linux Topics,Run-Time Libraries,Platform-Specific Information |
| @anchor{gnat_ugn/platform_specific_information id4}@anchor{1b7}@anchor{gnat_ugn/platform_specific_information specifying-a-run-time-library}@anchor{1b8} |
| @section Specifying a Run-Time Library |
| |
| |
| The @code{adainclude} subdirectory containing the sources of the GNAT |
| run-time library, and the @code{adalib} subdirectory containing the |
| @code{ALI} files and the static and/or shared GNAT library, are located |
| in the gcc target-dependent area: |
| |
| @quotation |
| |
| @example |
| target=$prefix/lib/gcc/gcc-*dumpmachine*/gcc-*dumpversion*/ |
| @end example |
| @end quotation |
| |
| 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: |
| |
| @c -- |
| @c -- $(target-dir) |
| @c -- | |
| @c -- +--- adainclude----------+ |
| @c -- | | |
| @c -- +--- adalib-----------+ | |
| @c -- | | | |
| @c -- +--- rts-native | | |
| @c -- | | | | |
| @c -- | +--- adainclude <---+ |
| @c -- | | | |
| @c -- | +--- adalib <----+ |
| @c -- | |
| @c -- +--- rts-sjlj |
| @c -- | |
| @c -- +--- adainclude |
| @c -- | |
| @c -- +--- adalib |
| |
| |
| @example |
| $(target-dir) |
| __/ / \ \___ |
| _______/ / \ \_________________ |
| / / \ \ |
| / / \ \ |
| ADAINCLUDE ADALIB rts-native rts-sjlj |
| : : / \ / \ |
| : : / \ / \ |
| : : / \ / \ |
| : : / \ / \ |
| +-------------> adainclude adalib adainclude adalib |
| : ^ |
| : : |
| +---------------------+ |
| |
| Run-Time Library Directory Structure |
| (Upper-case names and dotted/dashed arrows represent soft links) |
| @end example |
| |
| If the @emph{rts-sjlj} library is to be selected on a permanent basis, |
| these soft links can be modified with the following commands: |
| |
| @quotation |
| |
| @example |
| $ cd $target |
| $ rm -f adainclude adalib |
| $ ln -s rts-sjlj/adainclude adainclude |
| $ ln -s rts-sjlj/adalib adalib |
| @end example |
| @end quotation |
| |
| Alternatively, you can specify @code{rts-sjlj/adainclude} in the file |
| @code{$target/ada_source_path} and @code{rts-sjlj/adalib} in |
| @code{$target/ada_object_path}. |
| |
| @geindex --RTS option |
| |
| Selecting another run-time library temporarily can be |
| achieved by using the @code{--RTS} switch, e.g., @code{--RTS=sjlj} |
| @anchor{gnat_ugn/platform_specific_information choosing-the-scheduling-policy}@anchor{1b9} |
| @geindex SCHED_FIFO scheduling policy |
| |
| @geindex SCHED_RR scheduling policy |
| |
| @geindex SCHED_OTHER scheduling policy |
| |
| @menu |
| * Choosing the Scheduling Policy:: |
| |
| @end menu |
| |
| @node Choosing the Scheduling Policy,,,Specifying a Run-Time Library |
| @anchor{gnat_ugn/platform_specific_information id5}@anchor{1ba} |
| @subsection Choosing the Scheduling Policy |
| |
| |
| When using a POSIX threads implementation, you have a choice of several |
| scheduling policies: @code{SCHED_FIFO}, @code{SCHED_RR} and @code{SCHED_OTHER}. |
| |
| Typically, the default is @code{SCHED_OTHER}, while using @code{SCHED_FIFO} |
| or @code{SCHED_RR} requires special (e.g., root) privileges. |
| |
| @geindex pragma Time_Slice |
| |
| @geindex -T0 option |
| |
| @geindex pragma Task_Dispatching_Policy |
| |
| By default, GNAT uses the @code{SCHED_OTHER} policy. To specify |
| @code{SCHED_FIFO}, |
| you can use one of the following: |
| |
| |
| @itemize * |
| |
| @item |
| @code{pragma Time_Slice (0.0)} |
| |
| @item |
| the corresponding binder option @code{-T0} |
| |
| @item |
| @code{pragma Task_Dispatching_Policy (FIFO_Within_Priorities)} |
| @end itemize |
| |
| To specify @code{SCHED_RR}, |
| you should use @code{pragma Time_Slice} with a |
| value greater than 0.0, or else use the corresponding @code{-T} |
| binder option. |
| |
| To make sure a program is running as root, you can put something like |
| this in a library package body in your application: |
| |
| @quotation |
| |
| @example |
| function geteuid return Integer; |
| pragma Import (C, geteuid, "geteuid"); |
| Ignore : constant Boolean := |
| (if geteuid = 0 then True else raise Program_Error with "must be root"); |
| @end example |
| @end quotation |
| |
| It gets the effective user id, and if it’s not 0 (i.e. root), it raises |
| Program_Error. Note that if you re running the code in a container, this may |
| not be sufficient, as you may have sufficient priviledge on the container, |
| but not on the host machine running the container, so check that you also |
| have sufficient priviledge for running the container image. |
| |
| @geindex Linux |
| |
| @geindex GNU/Linux |
| |
| @node GNU/Linux Topics,Microsoft Windows Topics,Specifying a Run-Time Library,Platform-Specific Information |
| @anchor{gnat_ugn/platform_specific_information gnu-linux-topics}@anchor{1bb}@anchor{gnat_ugn/platform_specific_information id6}@anchor{1bc} |
| @section GNU/Linux Topics |
| |
| |
| This section describes topics that are specific to GNU/Linux platforms. |
| |
| @menu |
| * Required Packages on GNU/Linux:: |
| |
| @end menu |
| |
| @node Required Packages on GNU/Linux,,,GNU/Linux Topics |
| @anchor{gnat_ugn/platform_specific_information id7}@anchor{1bd}@anchor{gnat_ugn/platform_specific_information required-packages-on-gnu-linux}@anchor{1be} |
| @subsection Required Packages on GNU/Linux |
| |
| |
| GNAT requires the C library developer’s package to be installed. |
| The name of of that package depends on your GNU/Linux distribution: |
| |
| |
| @itemize * |
| |
| @item |
| RedHat, SUSE: @code{glibc-devel}; |
| |
| @item |
| Debian, Ubuntu: @code{libc6-dev} (normally installed by default). |
| @end itemize |
| |
| If using the 32-bit version of GNAT on a 64-bit version of GNU/Linux, |
| you’ll need the 32-bit version of the following packages: |
| |
| |
| @itemize * |
| |
| @item |
| RedHat, SUSE: @code{glibc.i686}, @code{glibc-devel.i686}, @code{ncurses-libs.i686} |
| |
| @item |
| Debian, Ubuntu: @code{libc6:i386}, @code{libc6-dev:i386}, @code{lib32ncursesw5} |
| @end itemize |
| |
| Other GNU/Linux distributions might be choosing a different name |
| for those packages. |
| |
| @geindex Windows |
| |
| @node Microsoft Windows Topics,Mac OS Topics,GNU/Linux Topics,Platform-Specific Information |
| @anchor{gnat_ugn/platform_specific_information id8}@anchor{1bf}@anchor{gnat_ugn/platform_specific_information microsoft-windows-topics}@anchor{1c0} |
| @section Microsoft Windows Topics |
| |
| |
| This section describes topics that are specific to the Microsoft Windows |
| platforms. |
| |
| |
| @menu |
| * Using GNAT on Windows:: |
| * Using a network installation of GNAT:: |
| * CONSOLE and WINDOWS subsystems:: |
| * Temporary Files:: |
| * Disabling Command Line Argument Expansion:: |
| * Windows Socket Timeouts:: |
| * Mixed-Language Programming on Windows:: |
| * Windows Specific Add-Ons:: |
| |
| @end menu |
| |
| @node Using GNAT on Windows,Using a network installation of GNAT,,Microsoft Windows Topics |
| @anchor{gnat_ugn/platform_specific_information id9}@anchor{1c1}@anchor{gnat_ugn/platform_specific_information using-gnat-on-windows}@anchor{1c2} |
| @subsection Using GNAT on Windows |
| |
| |
| One of the strengths of the GNAT technology is that its tool set |
| (@code{gcc}, @code{gnatbind}, @code{gnatlink}, @code{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 * |
| |
| @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 |
| |
| 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 * |
| |
| @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 GNAT, 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,CONSOLE and WINDOWS subsystems,Using GNAT on Windows,Microsoft Windows Topics |
| @anchor{gnat_ugn/platform_specific_information id10}@anchor{1c3}@anchor{gnat_ugn/platform_specific_information using-a-network-installation-of-gnat}@anchor{1c4} |
| @subsection Using a network installation of GNAT |
| |
| |
| 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 |
| @code{bin} directory of your GNAT installation in front of your PATH. For |
| example, if GNAT is installed in @code{\GNAT} directory of a share location |
| called @code{c-drive} on a machine @code{LOKI}, the following command will |
| make it available: |
| |
| @quotation |
| |
| @example |
| $ path \\loki\c-drive\gnat\bin;%path%` |
| @end example |
| @end quotation |
| |
| 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,Temporary Files,Using a network installation of GNAT,Microsoft Windows Topics |
| @anchor{gnat_ugn/platform_specific_information console-and-windows-subsystems}@anchor{1c5}@anchor{gnat_ugn/platform_specific_information id11}@anchor{1c6} |
| @subsection CONSOLE and WINDOWS subsystems |
| |
| |
| @geindex CONSOLE Subsystem |
| |
| @geindex WINDOWS Subsystem |
| |
| @geindex -mwindows |
| |
| 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 @code{-mwindows} linker option must be specified. |
| |
| @quotation |
| |
| @example |
| $ gnatmake winprog -largs -mwindows |
| @end example |
| @end quotation |
| |
| @node Temporary Files,Disabling Command Line Argument Expansion,CONSOLE and WINDOWS subsystems,Microsoft Windows Topics |
| @anchor{gnat_ugn/platform_specific_information id12}@anchor{1c7}@anchor{gnat_ugn/platform_specific_information temporary-files}@anchor{1c8} |
| @subsection Temporary Files |
| |
| |
| @geindex Temporary files |
| |
| It is possible to control where temporary files gets created by setting |
| the |
| @geindex TMP |
| @geindex environment variable; TMP |
| @code{TMP} environment variable. The file will be created: |
| |
| |
| @itemize * |
| |
| @item |
| Under the directory pointed to by the |
| @geindex TMP |
| @geindex environment variable; TMP |
| @code{TMP} environment variable if |
| this directory exists. |
| |
| @item |
| Under @code{c:\temp}, if the |
| @geindex TMP |
| @geindex environment variable; TMP |
| @code{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 |
| |
| 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 Disabling Command Line Argument Expansion,Windows Socket Timeouts,Temporary Files,Microsoft Windows Topics |
| @anchor{gnat_ugn/platform_specific_information disabling-command-line-argument-expansion}@anchor{1c9} |
| @subsection Disabling Command Line Argument Expansion |
| |
| |
| @geindex Command Line Argument Expansion |
| |
| By default, an executable compiled for the Windows platform will do |
| the following postprocessing on the arguments passed on the command |
| line: |
| |
| |
| @itemize * |
| |
| @item |
| If the argument contains the characters @code{*} and/or @code{?}, then |
| file expansion will be attempted. For example, if the current directory |
| contains @code{a.txt} and @code{b.txt}, then when calling: |
| |
| @example |
| $ my_ada_program *.txt |
| @end example |
| |
| The following arguments will effectively be passed to the main program |
| (for example when using @code{Ada.Command_Line.Argument}): |
| |
| @example |
| Ada.Command_Line.Argument (1) -> "a.txt" |
| Ada.Command_Line.Argument (2) -> "b.txt" |
| @end example |
| |
| @item |
| Filename expansion can be disabled for a given argument by using single |
| quotes. Thus, calling: |
| |
| @example |
| $ my_ada_program '*.txt' |
| @end example |
| |
| will result in: |
| |
| @example |
| Ada.Command_Line.Argument (1) -> "*.txt" |
| @end example |
| @end itemize |
| |
| Note that if the program is launched from a shell such as Cygwin Bash |
| then quote removal might be performed by the shell. |
| |
| In some contexts it might be useful to disable this feature (for example if |
| the program performs its own argument expansion). In order to do this, a C |
| symbol needs to be defined and set to @code{0}. You can do this by |
| adding the following code fragment in one of your Ada units: |
| |
| @example |
| Do_Argv_Expansion : Integer := 0; |
| pragma Export (C, Do_Argv_Expansion, "__gnat_do_argv_expansion"); |
| @end example |
| |
| The results of previous examples will be respectively: |
| |
| @example |
| Ada.Command_Line.Argument (1) -> "*.txt" |
| @end example |
| |
| and: |
| |
| @example |
| Ada.Command_Line.Argument (1) -> "'*.txt'" |
| @end example |
| |
| @node Windows Socket Timeouts,Mixed-Language Programming on Windows,Disabling Command Line Argument Expansion,Microsoft Windows Topics |
| @anchor{gnat_ugn/platform_specific_information windows-socket-timeouts}@anchor{1ca} |
| @subsection Windows Socket Timeouts |
| |
| |
| Microsoft Windows desktops older than @code{8.0} and Microsoft Windows Servers |
| older than @code{2019} set a socket timeout 500 milliseconds longer than the value |
| set by setsockopt with @code{SO_RCVTIMEO} and @code{SO_SNDTIMEO} options. The GNAT |
| runtime makes a correction for the difference in the corresponding Windows |
| versions. For Windows Server starting with version @code{2019}, the user must |
| provide a manifest file for the GNAT runtime to be able to recognize that |
| the Windows version does not need the timeout correction. The manifest file |
| should be located in the same directory as the executable file, and its file |
| name must match the executable name suffixed by @code{.manifest}. For example, |
| if the executable name is @code{sock_wto.exe}, then the manifest file name |
| has to be @code{sock_wto.exe.manifest}. The manifest file must contain at |
| least the following data: |
| |
| @example |
| <?xml version="1.0" encoding="UTF-8" standalone="yes"?> |
| <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> |
| <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> |
| <application> |
| <!-- Windows Vista --> |
| <supportedOS Id="@{e2011457-1546-43c5-a5fe-008deee3d3f0@}"/> |
| <!-- Windows 7 --> |
| <supportedOS Id="@{35138b9a-5d96-4fbd-8e2d-a2440225f93a@}"/> |
| <!-- Windows 8 --> |
| <supportedOS Id="@{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38@}"/> |
| <!-- Windows 8.1 --> |
| <supportedOS Id="@{1f676c76-80e1-4239-95bb-83d0f6d0da78@}"/> |
| <!-- Windows 10 --> |
| <supportedOS Id="@{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a@}"/> |
| </application> |
| </compatibility> |
| </assembly> |
| @end example |
| |
| Without the manifest file, the socket timeout is going to be overcorrected on |
| these Windows Server versions and the actual time is going to be 500 |
| milliseconds shorter than what was set with GNAT.Sockets.Set_Socket_Option. |
| Note that on Microsoft Windows versions where correction is necessary, there |
| is no way to set a socket timeout shorter than 500 ms. If a socket timeout |
| shorter than 500 ms is needed on these Windows versions, a call to |
| Check_Selector should be added before any socket read or write operations. |
| |
| @node Mixed-Language Programming on Windows,Windows Specific Add-Ons,Windows Socket Timeouts,Microsoft Windows Topics |
| @anchor{gnat_ugn/platform_specific_information id13}@anchor{1cb}@anchor{gnat_ugn/platform_specific_information mixed-language-programming-on-windows}@anchor{1cc} |
| @subsection Mixed-Language Programming on Windows |
| |
| |
| 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 @code{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: |
| |
| |
| @itemize * |
| |
| @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 |
| (@ref{1cd,,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 |
| (@ref{1ce,,Building DLLs with GNAT Project files}) and use the Microsoft |
| or whatever environment to build your executable. |
| @end itemize |
| |
| In addition to the description about C main in |
| @ref{2c,,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: |
| |
| @quotation |
| |
| @example |
| /* 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 example |
| @end quotation |
| |
| Note that this is not needed on x86_64-windows where the Windows |
| native SEH support is used. |
| |
| @menu |
| * Windows Calling Conventions:: |
| * Introduction to Dynamic Link Libraries (DLLs): Introduction to Dynamic Link Libraries DLLs. |
| * Using DLLs with GNAT:: |
| * Building DLLs with GNAT Project files:: |
| * Building DLLs with GNAT:: |
| * Building DLLs with gnatdll:: |
| * Ada DLLs and Finalization:: |
| * Creating a Spec for Ada DLLs:: |
| * GNAT and Windows Resources:: |
| * Using GNAT DLLs from Microsoft Visual Studio Applications:: |
| * Debugging a DLL:: |
| * Setting Stack Size from gnatlink:: |
| * Setting Heap Size from gnatlink:: |
| |
| @end menu |
| |
| @node Windows Calling Conventions,Introduction to Dynamic Link Libraries DLLs,,Mixed-Language Programming on Windows |
| @anchor{gnat_ugn/platform_specific_information id14}@anchor{1cf}@anchor{gnat_ugn/platform_specific_information windows-calling-conventions}@anchor{1d0} |
| @subsubsection Windows Calling Conventions |
| |
| |
| @geindex Stdcall |
| |
| @geindex APIENTRY |
| |
| This section pertain only to Win32. On Win64 there is a single native |
| calling convention. All convention specifiers are ignored on this |
| platform. |
| |
| 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 * |
| |
| @item |
| @code{C} (Microsoft defined) |
| |
| @item |
| @code{Stdcall} (Microsoft defined) |
| |
| @item |
| @code{Win32} (GNAT specific) |
| |
| @item |
| @code{DLL} (GNAT specific) |
| @end itemize |
| |
| @menu |
| * C Calling Convention:: |
| * Stdcall Calling Convention:: |
| * Win32 Calling Convention:: |
| * DLL Calling Convention:: |
| |
| @end menu |
| |
| @node C Calling Convention,Stdcall Calling Convention,,Windows Calling Conventions |
| @anchor{gnat_ugn/platform_specific_information c-calling-convention}@anchor{1d1}@anchor{gnat_ugn/platform_specific_information id15}@anchor{1d2} |
| @subsubsection @code{C} Calling Convention |
| |
| |
| This is the default calling convention used when interfacing to C/C++ |
| routines compiled with either @code{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: |
| |
| @quotation |
| |
| @example |
| int get_val (long); |
| @end example |
| @end quotation |
| |
| should be imported from Ada as follows: |
| |
| @quotation |
| |
| @example |
| function Get_Val (V : Interfaces.C.long) return Interfaces.C.int; |
| pragma Import (C, Get_Val, External_Name => "get_val"); |
| @end example |
| @end quotation |
| |
| 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, @ref{1d3,,Stdcall Calling Convention}). |
| |
| @node Stdcall Calling Convention,Win32 Calling Convention,C Calling Convention,Windows Calling Conventions |
| @anchor{gnat_ugn/platform_specific_information id16}@anchor{1d4}@anchor{gnat_ugn/platform_specific_information stdcall-calling-convention}@anchor{1d3} |
| @subsubsection @code{Stdcall} Calling Convention |
| |
| |
| 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{@@@emph{nn}}, where @code{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{@@@emph{nn}} are added automatically by |
| the compiler. For instance the Win32 function: |
| |
| @quotation |
| |
| @example |
| APIENTRY int get_val (long); |
| @end example |
| @end quotation |
| |
| should be imported from Ada as follows: |
| |
| @quotation |
| |
| @example |
| 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 example |
| @end quotation |
| |
| 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: |
| |
| @quotation |
| |
| @example |
| function Get_Val (V : Interfaces.C.long) return Interfaces.C.int; |
| pragma Import (Stdcall, Get_Val, External_Name => "retrieve_val"); |
| @end example |
| @end quotation |
| |
| 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: |
| |
| @quotation |
| |
| @example |
| function Get_Val (V : Interfaces.C.long) return Interfaces.C.int; |
| pragma Import (Stdcall, Get_Val, Link_Name => "retrieve_val"); |
| @end example |
| @end quotation |
| |
| then the imported routine is @code{retrieve_val}, that is, there is no |
| decoration at all. No leading underscore and no Stdcall suffix |
| @code{@@@emph{nn}}. |
| |
| This is especially important as in some special cases a DLL’s entry |
| point name lacks a trailing @code{@@@emph{nn}} while the exported |
| name generated for a call has it. |
| |
| 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: |
| |
| @quotation |
| |
| @example |
| int my_var; |
| @end example |
| @end quotation |
| |
| then, to access this variable from Ada you should write: |
| |
| @quotation |
| |
| @example |
| My_Var : Interfaces.C.int; |
| pragma Import (Stdcall, My_Var); |
| @end example |
| @end quotation |
| |
| 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,DLL Calling Convention,Stdcall Calling Convention,Windows Calling Conventions |
| @anchor{gnat_ugn/platform_specific_information id17}@anchor{1d5}@anchor{gnat_ugn/platform_specific_information win32-calling-convention}@anchor{1d6} |
| @subsubsection @code{Win32} Calling Convention |
| |
| |
| This convention, which is GNAT-specific is fully equivalent to the |
| @code{Stdcall} calling convention described above. |
| |
| @node DLL Calling Convention,,Win32 Calling Convention,Windows Calling Conventions |
| @anchor{gnat_ugn/platform_specific_information dll-calling-convention}@anchor{1d7}@anchor{gnat_ugn/platform_specific_information id18}@anchor{1d8} |
| @subsubsection @code{DLL} Calling Convention |
| |
| |
| This convention, which is GNAT-specific is fully equivalent to the |
| @code{Stdcall} calling convention described above. |
| |
| @node Introduction to Dynamic Link Libraries DLLs,Using DLLs with GNAT,Windows Calling Conventions,Mixed-Language Programming on Windows |
| @anchor{gnat_ugn/platform_specific_information id19}@anchor{1d9}@anchor{gnat_ugn/platform_specific_information introduction-to-dynamic-link-libraries-dlls}@anchor{1da} |
| @subsubsection Introduction to Dynamic Link Libraries (DLLs) |
| |
| |
| @geindex DLL |
| |
| 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 @code{API.dll}. To use the services |
| provided by @code{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 @code{API.lib}. When using GNAT this import |
| library is called either @code{libAPI.dll.a}, @code{libapi.dll.a}, |
| @code{libAPI.a} or @code{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: |
| |
| |
| @itemize * |
| |
| @item |
| Your application is loaded into memory. |
| |
| @item |
| The DLL @code{API.dll} is mapped into the address space of your |
| application. This means that: |
| |
| |
| @itemize - |
| |
| @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 @code{libAPI.dll.a} |
| or @code{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 @code{API.dll}. |
| |
| @item |
| If present in @code{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 itemize |
| |
| 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 @code{-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 (see @ref{1db,,The Definition File}). |
| |
| @node Using DLLs with GNAT,Building DLLs with GNAT Project files,Introduction to Dynamic Link Libraries DLLs,Mixed-Language Programming on Windows |
| @anchor{gnat_ugn/platform_specific_information id20}@anchor{1dc}@anchor{gnat_ugn/platform_specific_information using-dlls-with-gnat}@anchor{1cd} |
| @subsubsection Using DLLs with GNAT |
| |
| |
| To use the services of a DLL, say @code{API.dll}, in your Ada application |
| you must have: |
| |
| |
| @itemize * |
| |
| @item |
| The Ada spec for the routines and/or variables you want to access in |
| @code{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 (@code{libAPI.dll.a} or @code{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 |
| @code{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, @code{API.dll}. |
| @end itemize |
| |
| Once you have all the above, to compile an Ada application that uses the |
| services of @code{API.dll} and whose main subprogram is @code{My_Ada_App}, |
| you simply issue the command |
| |
| @quotation |
| |
| @example |
| $ gnatmake my_ada_app -largs -lAPI |
| @end example |
| @end quotation |
| |
| The argument @code{-largs -lAPI} at the end of the @code{gnatmake} command |
| tells the GNAT linker to look for an import library. The linker will |
| look for a library name in this specific order: |
| |
| |
| @itemize * |
| |
| @item |
| @code{libAPI.dll.a} |
| |
| @item |
| @code{API.dll.a} |
| |
| @item |
| @code{libAPI.a} |
| |
| @item |
| @code{API.lib} |
| |
| @item |
| @code{libAPI.dll} |
| |
| @item |
| @code{API.dll} |
| @end itemize |
| |
| 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 @code{API.dll} contains the |
| following pragma |
| |
| @quotation |
| |
| @example |
| pragma Linker_Options ("-lAPI"); |
| @end example |
| @end quotation |
| |
| you do not have to add @code{-largs -lAPI} at the end of the |
| @code{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 @code{API.dll}. |
| |
| @menu |
| * Creating an Ada Spec for the DLL Services:: |
| * Creating an Import Library:: |
| |
| @end menu |
| |
| @node Creating an Ada Spec for the DLL Services,Creating an Import Library,,Using DLLs with GNAT |
| @anchor{gnat_ugn/platform_specific_information creating-an-ada-spec-for-the-dll-services}@anchor{1dd}@anchor{gnat_ugn/platform_specific_information id21}@anchor{1de} |
| @subsubsection Creating an Ada Spec for the DLL Services |
| |
| |
| 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 @code{API.dll} is a file @code{api.h} containing the |
| following two definitions: |
| |
| @quotation |
| |
| @example |
| int some_var; |
| int get (char *); |
| @end example |
| @end quotation |
| |
| then the equivalent Ada spec could be: |
| |
| @quotation |
| |
| @example |
| 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 example |
| @end quotation |
| |
| @node Creating an Import Library,,Creating an Ada Spec for the DLL Services,Using DLLs with GNAT |
| @anchor{gnat_ugn/platform_specific_information creating-an-import-library}@anchor{1df}@anchor{gnat_ugn/platform_specific_information id22}@anchor{1e0} |
| @subsubsection Creating an Import Library |
| |
| |
| @geindex Import library |
| |
| If a Microsoft-style import library @code{API.lib} or a GNAT-style |
| import library @code{libAPI.dll.a} or @code{libAPI.a} is available |
| with @code{API.dll} you can skip this section. You can also skip this |
| section if @code{API.dll} or @code{libAPI.dll} is built with GNU tools |
| as in this case it is possible to link directly against the |
| DLL. Otherwise read on. |
| |
| @geindex Definition file |
| @anchor{gnat_ugn/platform_specific_information the-definition-file}@anchor{1db} |
| @subsubheading The Definition File |
| |
| |
| 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: |
| |
| @quotation |
| |
| @example |
| [LIBRARY `@w{`}name`@w{`}] |
| [DESCRIPTION `@w{`}string`@w{`}] |
| EXPORTS |
| `@w{`}symbol1`@w{`} |
| `@w{`}symbol2`@w{`} |
| ... |
| @end example |
| @end quotation |
| |
| |
| @table @asis |
| |
| @item @emph{LIBRARY name} |
| |
| This section, which is optional, gives the name of the DLL. |
| |
| @item @emph{DESCRIPTION string} |
| |
| This section, which is optional, gives a description string that will be |
| embedded in the import library. |
| |
| @item @emph{EXPORTS} |
| |
| This section gives the list of exported symbols (procedures, functions or |
| variables). For instance in the case of @code{API.dll} the @code{EXPORTS} |
| section of @code{API.def} looks like: |
| |
| @example |
| EXPORTS |
| some_var |
| get |
| @end example |
| @end table |
| |
| Note that you must specify the correct suffix (@code{@@@emph{nn}}) |
| (see @ref{1d0,,Windows Calling Conventions}) for a Stdcall |
| calling convention function in the exported symbols list. |
| |
| There can actually be other sections in a definition file, but these |
| sections are not relevant to the discussion at hand. |
| @anchor{gnat_ugn/platform_specific_information create-def-file-automatically}@anchor{1e1} |
| @subsubheading Creating a Definition File Automatically |
| |
| |
| You can automatically create the definition file @code{API.def} |
| (see @ref{1db,,The Definition File}) from a DLL. |
| For that use the @code{dlltool} program as follows: |
| |
| @quotation |
| |
| @example |
| $ dlltool API.dll -z API.def --export-all-symbols |
| @end example |
| |
| Note that if some routines in the DLL have the @code{Stdcall} convention |
| (@ref{1d0,,Windows Calling Conventions}) with stripped @code{@@@emph{nn}} |
| suffix then you’ll have to edit @code{api.def} to add it, and specify |
| @code{-k} to @code{gnatdll} when creating the import library. |
| |
| Here are some hints to find the right @code{@@@emph{nn}} suffix. |
| |
| |
| @itemize - |
| |
| @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). |
| |
| @example |
| $ dumpbin /exports api.lib |
| @end example |
| |
| @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 itemize |
| @end quotation |
| @anchor{gnat_ugn/platform_specific_information gnat-style-import-library}@anchor{1e2} |
| @subsubheading GNAT-Style Import Library |
| |
| |
| To create a static import library from @code{API.dll} with the GNAT tools |
| you should create the .def file, then use @code{gnatdll} tool |
| (see @ref{1e3,,Using gnatdll}) as follows: |
| |
| @quotation |
| |
| @example |
| $ gnatdll -e API.def -d API.dll |
| @end example |
| |
| @code{gnatdll} takes as input a definition file @code{API.def} and the |
| name of the DLL containing the services listed in the definition file |
| @code{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 @code{xyz.def}, the import library name will |
| be @code{libxyz.a}. Note that in the previous example option |
| @code{-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 (@ref{1e3,,Using gnatdll} for more information about @code{gnatdll}). |
| @end quotation |
| @anchor{gnat_ugn/platform_specific_information msvs-style-import-library}@anchor{1e4} |
| @subsubheading 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 (@ref{1cc,,Mixed-Language Programming on Windows}). |
| |
| To create a Microsoft-style import library for @code{API.dll} you |
| should create the .def file, then build the actual import library using |
| Microsoft’s @code{lib} utility: |
| |
| @quotation |
| |
| @example |
| $ lib -machine:IX86 -def:API.def -out:API.lib |
| @end example |
| |
| If you use the above command the definition file @code{API.def} must |
| contain a line giving the name of the DLL: |
| |
| @example |
| LIBRARY "API" |
| @end example |
| |
| See the Microsoft documentation for further details about the usage of |
| @code{lib}. |
| @end quotation |
| |
| @node Building DLLs with GNAT Project files,Building DLLs with GNAT,Using DLLs with GNAT,Mixed-Language Programming on Windows |
| @anchor{gnat_ugn/platform_specific_information building-dlls-with-gnat-project-files}@anchor{1ce}@anchor{gnat_ugn/platform_specific_information id23}@anchor{1e5} |
| @subsubsection Building DLLs with GNAT Project files |
| |
| |
| @geindex DLLs |
| @geindex building |
| |
| There is nothing specific to Windows in the build process. |
| See the @emph{Library Projects} section in the @emph{GNAT Project Manager} |
| chapter of the @emph{GPRbuild User’s Guide}. |
| |
| 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,Building DLLs with gnatdll,Building DLLs with GNAT Project files,Mixed-Language Programming on Windows |
| @anchor{gnat_ugn/platform_specific_information building-dlls-with-gnat}@anchor{1e6}@anchor{gnat_ugn/platform_specific_information id24}@anchor{1e7} |
| @subsubsection Building DLLs with GNAT |
| |
| |
| @geindex DLLs |
| @geindex building |
| |
| 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. |
| |
| |
| @itemize * |
| |
| @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 @code{gnatmake} tool. |
| |
| @item |
| Building the DLL. |
| To build the DLL you must use the @code{gcc} @code{-shared} and |
| @code{-shared-libgcc} options. It is quite simple to use this method: |
| |
| @example |
| $ gcc -shared -shared-libgcc -o api.dll obj1.o obj2.o ... |
| @end example |
| |
| 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 @code{gcc} a definition |
| file (see @ref{1db,,The Definition File}). |
| For example: |
| |
| @example |
| $ gcc -shared -shared-libgcc -o api.dll api.def obj1.o obj2.o ... |
| @end example |
| |
| 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: |
| |
| @example |
| $ mkdir apilib |
| $ copy *.ads *.ali api.dll apilib |
| $ attrib +R apilib\\*.ali |
| @end example |
| @end itemize |
| |
| 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 the @code{-shared} binder |
| option. |
| |
| @quotation |
| |
| @example |
| $ gnatmake main -Iapilib -bargs -shared -largs -Lapilib -lAPI |
| @end example |
| @end quotation |
| |
| @node Building DLLs with gnatdll,Ada DLLs and Finalization,Building DLLs with GNAT,Mixed-Language Programming on Windows |
| @anchor{gnat_ugn/platform_specific_information building-dlls-with-gnatdll}@anchor{1e8}@anchor{gnat_ugn/platform_specific_information id25}@anchor{1e9} |
| @subsubsection Building DLLs with gnatdll |
| |
| |
| @geindex DLLs |
| @geindex building |
| |
| Note that it is preferred to use GNAT Project files |
| (@ref{1ce,,Building DLLs with GNAT Project files}) or the built-in GNAT |
| DLL support (@ref{1e6,,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: |
| |
| |
| @itemize * |
| |
| @item |
| You need to mark each Ada 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 |
| (see @ref{1ea,,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 @code{gnatbind} to perform the elaboration of |
| the Ada code in the DLL (@ref{1eb,,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 @code{gnatbind} to perform the |
| finalization of the Ada code in the DLL (@ref{1ec,,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 |
| (@ref{1db,,The Definition File}). |
| |
| @item |
| Finally you must use @code{gnatdll} to produce the DLL and the import |
| library (@ref{1e3,,Using gnatdll}). |
| @end itemize |
| |
| 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. |
| See the @emph{Library Projects} section in the @emph{GNAT Project Manager} |
| chapter of the @emph{GPRbuild User’s Guide}. |
| |
| @c Limitations_When_Using_Ada_DLLs_from Ada: |
| |
| @menu |
| * Limitations When Using Ada DLLs from Ada:: |
| * Exporting Ada Entities:: |
| * Ada DLLs and Elaboration:: |
| |
| @end menu |
| |
| @node Limitations When Using Ada DLLs from Ada,Exporting Ada Entities,,Building DLLs with gnatdll |
| @anchor{gnat_ugn/platform_specific_information limitations-when-using-ada-dlls-from-ada}@anchor{1ed} |
| @subsubsection Limitations When Using Ada DLLs from Ada |
| |
| |
| 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,Ada DLLs and Elaboration,Limitations When Using Ada DLLs from Ada,Building DLLs with gnatdll |
| @anchor{gnat_ugn/platform_specific_information exporting-ada-entities}@anchor{1ea}@anchor{gnat_ugn/platform_specific_information id26}@anchor{1ee} |
| @subsubsection Exporting Ada Entities |
| |
| |
| @geindex Export table |
| |
| 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: |
| |
| @quotation |
| |
| @example |
| 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 example |
| |
| @example |
| 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 example |
| @end quotation |
| |
| 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: |
| |
| @quotation |
| |
| @example |
| 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 example |
| |
| @example |
| package body API is |
| function Factorial (Val : Integer) return Integer is |
| Fact : Integer := 1; |
| begin |
| Count := Count + 1; |
| for K in 1 .. Val loop |
| Fact := Fact * K; |
| end loop; |
| return Fact; |
| end Factorial; |
| |
| ... |
| -- The remainder of this package body is unchanged. |
| end API; |
| @end example |
| @end quotation |
| |
| 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 |
| (@ref{1ef,,Creating the Definition File}). |
| |
| @node Ada DLLs and Elaboration,,Exporting Ada Entities,Building DLLs with gnatdll |
| @anchor{gnat_ugn/platform_specific_information ada-dlls-and-elaboration}@anchor{1eb}@anchor{gnat_ugn/platform_specific_information id27}@anchor{1f0} |
| @subsubsection Ada DLLs and Elaboration |
| |
| |
| @geindex DLLs and elaboration |
| |
| 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 |
| (@ref{f,,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 |
| (@ref{a0,,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 (@ref{1e3,,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,Creating a Spec for Ada DLLs,Building DLLs with gnatdll,Mixed-Language Programming on Windows |
| @anchor{gnat_ugn/platform_specific_information ada-dlls-and-finalization}@anchor{1ec}@anchor{gnat_ugn/platform_specific_information id28}@anchor{1f1} |
| @subsubsection Ada DLLs and Finalization |
| |
| |
| @geindex DLLs and finalization |
| |
| 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 |
| (@ref{a0,,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 |
| (@ref{1e3,,Using gnatdll}). |
| |
| @node Creating a Spec for Ada DLLs,GNAT and Windows Resources,Ada DLLs and Finalization,Mixed-Language Programming on Windows |
| @anchor{gnat_ugn/platform_specific_information creating-a-spec-for-ada-dlls}@anchor{1f2}@anchor{gnat_ugn/platform_specific_information id29}@anchor{1f3} |
| @subsubsection Creating a Spec for Ada DLLs |
| |
| |
| 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: |
| |
| @quotation |
| |
| @example |
| extern int *_imp__count; |
| #define count (*_imp__count) |
| int factorial (int); |
| @end example |
| @end quotation |
| |
| 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}: |
| |
| @quotation |
| |
| @example |
| package API is |
| Count : Integer := 0; |
| ... |
| -- Remainder of the package omitted. |
| end API; |
| @end example |
| @end quotation |
| |
| 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: |
| |
| @quotation |
| |
| @example |
| package API is |
| Count : Integer; |
| pragma Import (DLL, Count); |
| end API; |
| @end example |
| @end quotation |
| |
| @menu |
| * Creating the Definition File:: |
| * Using gnatdll:: |
| |
| @end menu |
| |
| @node Creating the Definition File,Using gnatdll,,Creating a Spec for Ada DLLs |
| @anchor{gnat_ugn/platform_specific_information creating-the-definition-file}@anchor{1ef}@anchor{gnat_ugn/platform_specific_information id30}@anchor{1f4} |
| @subsubsection Creating the Definition File |
| |
| |
| 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: |
| |
| @quotation |
| |
| @example |
| EXPORTS |
| count |
| factorial |
| finalize_api |
| initialize_api |
| @end example |
| @end quotation |
| |
| 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: |
| |
| @quotation |
| |
| @example |
| EXPORTS |
| api__count |
| api__factorial |
| api__finalize_api |
| api__initialize_api |
| @end example |
| @end quotation |
| |
| @node Using gnatdll,,Creating the Definition File,Creating a Spec for Ada DLLs |
| @anchor{gnat_ugn/platform_specific_information id31}@anchor{1f5}@anchor{gnat_ugn/platform_specific_information using-gnatdll}@anchor{1e3} |
| @subsubsection Using @code{gnatdll} |
| |
| |
| @geindex gnatdll |
| |
| @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 |
| |
| @quotation |
| |
| @example |
| $ gnatdll [ switches ] list-of-files [ -largs opts ] |
| @end example |
| @end quotation |
| |
| where @code{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 @code{list-of-files} is |
| missing, only the static import library is generated. |
| |
| You may specify any of the following switches to @code{gnatdll}: |
| |
| @quotation |
| |
| @geindex -a (gnatdll) |
| @end quotation |
| |
| |
| @table @asis |
| |
| @item @code{-a[@emph{address}]} |
| |
| Build a non-relocatable DLL at @code{address}. If @code{address} is not |
| specified the default address @code{0x11000000} will be used. By default, |
| when this switch is missing, @code{gnatdll} builds relocatable DLL. We |
| advise the reader to build relocatable DLL. |
| |
| @geindex -b (gnatdll) |
| |
| @item @code{-b @emph{address}} |
| |
| Set the relocatable DLL base address. By default the address is |
| @code{0x11000000}. |
| |
| @geindex -bargs (gnatdll) |
| |
| @item @code{-bargs @emph{opts}} |
| |
| Binder options. Pass @code{opts} to the binder. |
| |
| @geindex -d (gnatdll) |
| |
| @item @code{-d @emph{dllfile}} |
| |
| @code{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 @code{dllfile} as shown in the following |
| example: if @code{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 @code{-e}) is obtained algorithmically from @code{dllfile} |
| as shown in the following example: |
| if @code{dllfile} is @code{xyz.dll}, the definition |
| file used is @code{xyz.def}. |
| |
| @geindex -e (gnatdll) |
| |
| @item @code{-e @emph{deffile}} |
| |
| @code{deffile} is the name of the definition file. |
| |
| @geindex -g (gnatdll) |
| |
| @item @code{-g} |
| |
| 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 |
| @code{-g} switch if you plan on using the debugger or the symbolic |
| stack traceback. |
| |
| @geindex -h (gnatdll) |
| |
| @item @code{-h} |
| |
| Help mode. Displays @code{gnatdll} switch usage information. |
| |
| @geindex -I (gnatdll) |
| |
| @item @code{-I@emph{dir}} |
| |
| Direct @code{gnatdll} to search the @code{dir} directory for source and |
| object files needed to build the DLL. |
| (@ref{73,,Search Paths and the Run-Time Library (RTL)}). |
| |
| @geindex -k (gnatdll) |
| |
| @item @code{-k} |
| |
| Removes the @code{@@@emph{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{@@@emph{nn}} suffix has been removed. This is the case for most |
| of the Windows NT DLL for example. This option has no effect when |
| @code{-n} option is specified. |
| |
| @geindex -l (gnatdll) |
| |
| @item @code{-l @emph{file}} |
| |
| The list of ALI and object files used to build the DLL are listed in |
| @code{file}, instead of being given in the command line. Each line in |
| @code{file} contains the name of an ALI or object file. |
| |
| @geindex -n (gnatdll) |
| |
| @item @code{-n} |
| |
| No Import. Do not create the import library. |
| |
| @geindex -q (gnatdll) |
| |
| @item @code{-q} |
| |
| Quiet mode. Do not display unnecessary messages. |
| |
| @geindex -v (gnatdll) |
| |
| @item @code{-v} |
| |
| Verbose mode. Display extra information. |
| |
| @geindex -largs (gnatdll) |
| |
| @item @code{-largs @emph{opts}} |
| |
| Linker options. Pass @code{opts} to the linker. |
| @end table |
| |
| @subsubheading @code{gnatdll} Example |
| |
| |
| As an example the command to build a relocatable DLL from @code{api.adb} |
| once @code{api.adb} has been compiled and @code{api.def} created is |
| |
| @quotation |
| |
| @example |
| $ gnatdll -d api.dll api.ali |
| @end example |
| @end quotation |
| |
| The above command creates two files: @code{libapi.dll.a} (the import |
| library) and @code{api.dll} (the actual DLL). If you want to create |
| only the DLL, just type: |
| |
| @quotation |
| |
| @example |
| $ gnatdll -d api.dll -n api.ali |
| @end example |
| @end quotation |
| |
| Alternatively if you want to create just the import library, type: |
| |
| @quotation |
| |
| @example |
| $ gnatdll -d api.dll |
| @end example |
| @end quotation |
| |
| @subsubheading @code{gnatdll} behind the Scenes |
| |
| |
| 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 @code{api.o} and |
| @code{api.ali} are available. To build a relocatable DLL, @code{gnatdll} does |
| the following: |
| |
| |
| @itemize * |
| |
| @item |
| @code{gnatdll} builds the base file (@code{api.base}). A base file gives |
| the information necessary to generate relocation information for the |
| DLL. |
| |
| @example |
| $ gnatbind -n api |
| $ gnatlink api -o api.jnk -mdll -Wl,--base-file,api.base |
| @end example |
| |
| In addition to the base file, the @code{gnatlink} command generates an |
| output file @code{api.jnk} which can be discarded. The @code{-mdll} switch |
| asks @code{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} (see @ref{1f6,,Using dlltool}) to build the |
| export table (@code{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. |
| |
| @example |
| $ dlltool --dllname api.dll --def api.def --base-file api.base \\ |
| --output-exp api.exp |
| @end example |
| |
| @item |
| @code{gnatdll} builds the base file using the new export table. Note that |
| @code{gnatbind} must be called once again since the binder generated file |
| has been deleted during the previous call to @code{gnatlink}. |
| |
| @example |
| $ gnatbind -n api |
| $ gnatlink api -o api.jnk api.exp -mdll |
| -Wl,--base-file,api.base |
| @end example |
| |
| @item |
| @code{gnatdll} builds the new export table using the new base file and |
| generates the DLL import library @code{libAPI.dll.a}. |
| |
| @example |
| $ dlltool --dllname api.dll --def api.def --base-file api.base \\ |
| --output-exp api.exp --output-lib libAPI.a |
| @end example |
| |
| @item |
| Finally @code{gnatdll} builds the relocatable DLL using the final export |
| table. |
| |
| @example |
| $ gnatbind -n api |
| $ gnatlink api api.exp -o api.dll -mdll |
| @end example |
| @end itemize |
| @anchor{gnat_ugn/platform_specific_information using-dlltool}@anchor{1f6} |
| @subsubheading Using @code{dlltool} |
| |
| |
| @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 |
| |
| @quotation |
| |
| @example |
| $ dlltool [`switches`] |
| @end example |
| @end quotation |
| |
| @code{dlltool} switches include: |
| |
| @geindex --base-file (dlltool) |
| |
| |
| @table @asis |
| |
| @item @code{--base-file @emph{basefile}} |
| |
| Read the base file @code{basefile} generated by the linker. This switch |
| is used to create a relocatable DLL. |
| @end table |
| |
| @geindex --def (dlltool) |
| |
| |
| @table @asis |
| |
| @item @code{--def @emph{deffile}} |
| |
| Read the definition file. |
| @end table |
| |
| @geindex --dllname (dlltool) |
| |
| |
| @table @asis |
| |
| @item @code{--dllname @emph{name}} |
| |
| 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 |
| @code{--output-lib}. |
| @end table |
| |
| @geindex -k (dlltool) |
| |
| |
| @table @asis |
| |
| @item @code{-k} |
| |
| Kill @code{@@@emph{nn}} from exported names |
| (@ref{1d0,,Windows Calling Conventions} |
| for a discussion about @code{Stdcall}-style symbols. |
| @end table |
| |
| @geindex --help (dlltool) |
| |
| |
| @table @asis |
| |
| @item @code{--help} |
| |
| Prints the @code{dlltool} switches with a concise description. |
| @end table |
| |
| @geindex --output-exp (dlltool) |
| |
| |
| @table @asis |
| |
| @item @code{--output-exp @emph{exportfile}} |
| |
| Generate an export file @code{exportfile}. The export file contains the |
| export table (list of symbols in the DLL) and is used to create the DLL. |
| @end table |
| |
| @geindex --output-lib (dlltool) |
| |
| |
| @table @asis |
| |
| @item @code{--output-lib @emph{libfile}} |
| |
| Generate a static import library @code{libfile}. |
| @end table |
| |
| @geindex -v (dlltool) |
| |
| |
| @table @asis |
| |
| @item @code{-v} |
| |
| Verbose mode. |
| @end table |
| |
| @geindex --as (dlltool) |
| |
| |
| @table @asis |
| |
| @item @code{--as @emph{assembler-name}} |
| |
| Use @code{assembler-name} as the assembler. The default is @code{as}. |
| @end table |
| |
| @node GNAT and Windows Resources,Using GNAT DLLs from Microsoft Visual Studio Applications,Creating a Spec for Ada DLLs,Mixed-Language Programming on Windows |
| @anchor{gnat_ugn/platform_specific_information gnat-and-windows-resources}@anchor{1f7}@anchor{gnat_ugn/platform_specific_information id32}@anchor{1f8} |
| @subsubsection GNAT and Windows Resources |
| |
| |
| @geindex Resources |
| @geindex windows |
| |
| Resources are an easy way to add Windows specific objects to your |
| application. The objects that can be added as resources include: |
| |
| |
| @itemize * |
| |
| @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: |
| |
| @quotation |
| |
| @example |
| 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 example |
| @end quotation |
| |
| 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. |
| |
| 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. |
| |
| @menu |
| * Building Resources:: |
| * Compiling Resources:: |
| * Using Resources:: |
| |
| @end menu |
| |
| @node Building Resources,Compiling Resources,,GNAT and Windows Resources |
| @anchor{gnat_ugn/platform_specific_information building-resources}@anchor{1f9}@anchor{gnat_ugn/platform_specific_information id33}@anchor{1fa} |
| @subsubsection Building Resources |
| |
| |
| @geindex Resources |
| @geindex building |
| |
| A resource file is an ASCII file. By convention resource files have an |
| @code{.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 @code{.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,Using Resources,Building Resources,GNAT and Windows Resources |
| @anchor{gnat_ugn/platform_specific_information compiling-resources}@anchor{1fb}@anchor{gnat_ugn/platform_specific_information id34}@anchor{1fc} |
| @subsubsection Compiling Resources |
| |
| |
| @geindex rc |
| |
| @geindex windres |
| |
| @geindex Resources |
| @geindex compiling |
| |
| 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: |
| |
| @quotation |
| |
| @example |
| $ windres -i myres.rc -o myres.o |
| @end example |
| @end quotation |
| |
| By default @code{windres} will run @code{gcc} to preprocess the @code{.rc} |
| file. You can specify an alternate preprocessor (usually named |
| @code{cpp.exe}) using the @code{windres} @code{--preprocessor} |
| parameter. A list of all possible options may be obtained by entering |
| the command @code{windres} @code{--help}. |
| |
| It is also possible to use the Microsoft resource compiler @code{rc.exe} |
| to produce a @code{.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 @code{.res} file to a |
| GNAT-compatible object file as follows: |
| |
| @quotation |
| |
| @example |
| $ windres -i myres.res -o myres.o |
| @end example |
| @end quotation |
| |
| @node Using Resources,,Compiling Resources,GNAT and Windows Resources |
| @anchor{gnat_ugn/platform_specific_information id35}@anchor{1fd}@anchor{gnat_ugn/platform_specific_information using-resources}@anchor{1fe} |
| @subsubsection Using Resources |
| |
| |
| @geindex Resources |
| @geindex using |
| |
| To include the resource file in your program just add the |
| GNAT-compatible object file for the resource(s) to the linker |
| arguments. With @code{gnatmake} this is done by using the @code{-largs} |
| option: |
| |
| @quotation |
| |
| @example |
| $ gnatmake myprog -largs myres.o |
| @end example |
| @end quotation |
| |
| @node Using GNAT DLLs from Microsoft Visual Studio Applications,Debugging a DLL,GNAT and Windows Resources,Mixed-Language Programming on Windows |
| @anchor{gnat_ugn/platform_specific_information using-gnat-dll-from-msvs}@anchor{1ff}@anchor{gnat_ugn/platform_specific_information using-gnat-dlls-from-microsoft-visual-studio-applications}@anchor{200} |
| @subsubsection Using GNAT DLLs from Microsoft Visual Studio Applications |
| |
| |
| @geindex Microsoft Visual Studio |
| @geindex use with GNAT DLLs |
| |
| This section describes a common case of mixed GNAT/Microsoft Visual Studio |
| application development, where the main program is developed using MSVS, and |
| is linked with a DLL developed using GNAT. Such a mixed application should |
| be developed following the general guidelines outlined above; below is the |
| cookbook-style sequence of steps to follow: |
| |
| |
| @enumerate |
| |
| @item |
| First develop and build the GNAT shared library using a library project |
| (let’s assume the project is @code{mylib.gpr}, producing the library @code{libmylib.dll}): |
| @end enumerate |
| |
| @quotation |
| |
| @example |
| $ gprbuild -p mylib.gpr |
| @end example |
| @end quotation |
| |
| |
| @enumerate 2 |
| |
| @item |
| Produce a .def file for the symbols you need to interface with, either by |
| hand or automatically with possibly some manual adjustments |
| (see @ref{1e1,,Creating Definition File Automatically}): |
| @end enumerate |
| |
| @quotation |
| |
| @example |
| $ dlltool libmylib.dll -z libmylib.def --export-all-symbols |
| @end example |
| @end quotation |
| |
| |
| @enumerate 3 |
| |
| @item |
| Make sure that MSVS command-line tools are accessible on the path. |
| |
| @item |
| Create the Microsoft-style import library (see @ref{1e4,,MSVS-Style Import Library}): |
| @end enumerate |
| |
| @quotation |
| |
| @example |
| $ lib -machine:IX86 -def:libmylib.def -out:libmylib.lib |
| @end example |
| @end quotation |
| |
| If you are using a 64-bit toolchain, the above becomes… |
| |
| @quotation |
| |
| @example |
| $ lib -machine:X64 -def:libmylib.def -out:libmylib.lib |
| @end example |
| @end quotation |
| |
| |
| @enumerate 5 |
| |
| @item |
| Build the C main |
| @end enumerate |
| |
| @quotation |
| |
| @example |
| $ cl /O2 /MD main.c libmylib.lib |
| @end example |
| @end quotation |
| |
| |
| @enumerate 6 |
| |
| @item |
| Before running the executable, make sure you have set the PATH to the DLL, |
| or copy the DLL into into the directory containing the .exe. |
| @end enumerate |
| |
| @node Debugging a DLL,Setting Stack Size from gnatlink,Using GNAT DLLs from Microsoft Visual Studio Applications,Mixed-Language Programming on Windows |
| @anchor{gnat_ugn/platform_specific_information debugging-a-dll}@anchor{201}@anchor{gnat_ugn/platform_specific_information id36}@anchor{202} |
| @subsubsection Debugging a DLL |
| |
| |
| @geindex DLL debugging |
| |
| 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: |
| |
| |
| @itemize * |
| |
| @item |
| The program and the DLL are built with GCC/GNAT. |
| |
| @item |
| The program is built with foreign tools and the DLL is built with |
| GCC/GNAT. |
| |
| @item |
| The program is built with GCC/GNAT and the DLL is built with |
| foreign tools. |
| @end itemize |
| |
| In this section we address only cases one and two above. |
| There is no point in trying to debug |
| a DLL with 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. |
| |
| @menu |
| * Program and DLL Both Built with GCC/GNAT:: |
| * Program Built with Foreign Tools and DLL Built with GCC/GNAT:: |
| |
| @end menu |
| |
| @node Program and DLL Both Built with GCC/GNAT,Program Built with Foreign Tools and DLL Built with GCC/GNAT,,Debugging a DLL |
| @anchor{gnat_ugn/platform_specific_information id37}@anchor{203}@anchor{gnat_ugn/platform_specific_information program-and-dll-both-built-with-gcc-gnat}@anchor{204} |
| @subsubsection Program and DLL Both Built with GCC/GNAT |
| |
| |
| 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}. |
| |
| The DLL (@ref{1da,,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: |
| |
| |
| @itemize * |
| |
| @item |
| Launch @code{GDB} on the main program. |
| |
| @example |
| $ gdb -nw ada_main |
| @end example |
| |
| @item |
| Start the program and stop at the beginning of the main procedure |
| |
| @example |
| (gdb) start |
| @end example |
| |
| 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 |
| |
| @example |
| (gdb) break ada_dll |
| (gdb) cont |
| @end example |
| @end itemize |
| |
| At this stage a breakpoint is set inside the DLL. From there on |
| you can use the standard approach to debug the whole program |
| (@ref{14d,,Running and Debugging Ada Programs}). |
| |
| @node Program Built with Foreign Tools and DLL Built with GCC/GNAT,,Program and DLL Both Built with GCC/GNAT,Debugging a DLL |
| @anchor{gnat_ugn/platform_specific_information id38}@anchor{205}@anchor{gnat_ugn/platform_specific_information program-built-with-foreign-tools-and-dll-built-with-gcc-gnat}@anchor{206} |
| @subsubsection Program Built with Foreign Tools and DLL Built with GCC/GNAT |
| |
| |
| 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. |
| |
| 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}. |
| |
| The DLL (see @ref{1da,,Introduction to Dynamic Link Libraries (DLLs)}) must have |
| been built with debugging information (see the GNAT @code{-g} option). |
| |
| @subsubheading Debugging the DLL Directly |
| |
| |
| |
| @itemize * |
| |
| @item |
| Find out the executable starting address |
| |
| @example |
| $ objdump --file-header main.exe |
| @end example |
| |
| The starting address is reported on the last line. For example: |
| |
| @example |
| main.exe: file format pei-i386 |
| architecture: i386, flags 0x0000010a: |
| EXEC_P, HAS_DEBUG, D_PAGED |
| start address 0x00401010 |
| @end example |
| |
| @item |
| Launch the debugger on the executable. |
| |
| @example |
| $ gdb main.exe |
| @end example |
| |
| @item |
| Set a breakpoint at the starting address, and launch the program. |
| |
| @example |
| $ (gdb) break *0x00401010 |
| $ (gdb) run |
| @end example |
| |
| The program will stop at the given address. |
| |
| @item |
| Set a breakpoint on a DLL subroutine. |
| |
| @example |
| (gdb) break ada_dll.adb:45 |
| @end example |
| |
| 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). |
| |
| @example |
| (gdb) set language ada |
| (gdb) break ada_dll |
| @end example |
| |
| @item |
| Continue the program. |
| |
| @example |
| (gdb) cont |
| @end example |
| |
| 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 (@ref{14d,,Running and Debugging Ada Programs}). |
| @end itemize |
| |
| It is also possible to debug the DLL by attaching to a running process. |
| |
| @subsubheading Attaching to a Running Process |
| |
| |
| @geindex DLL debugging |
| @geindex attach to process |
| |
| 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. |
| |
| |
| @itemize * |
| |
| @item |
| Launch the main program @code{main.exe}. |
| |
| @example |
| $ main |
| @end example |
| |
| @item |
| Use the Windows @emph{Task Manager} to find the process ID. Let’s say |
| that the process PID for @code{main.exe} is 208. |
| |
| @item |
| Launch gdb. |
| |
| @example |
| $ gdb |
| @end example |
| |
| @item |
| Attach to the running process to be debugged. |
| |
| @example |
| (gdb) attach 208 |
| @end example |
| |
| @item |
| Load the process debugging information. |
| |
| @example |
| (gdb) symbol-file main.exe |
| @end example |
| |
| @item |
| Break somewhere in the DLL. |
| |
| @example |
| (gdb) break ada_dll |
| @end example |
| |
| @item |
| Continue process execution. |
| |
| @example |
| (gdb) cont |
| @end example |
| @end itemize |
| |
| 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 |
| @ref{14d,,Running and Debugging Ada Programs}. |
| |
| @node Setting Stack Size from gnatlink,Setting Heap Size from gnatlink,Debugging a DLL,Mixed-Language Programming on Windows |
| @anchor{gnat_ugn/platform_specific_information id39}@anchor{207}@anchor{gnat_ugn/platform_specific_information setting-stack-size-from-gnatlink}@anchor{127} |
| @subsubsection Setting Stack Size from @code{gnatlink} |
| |
| |
| 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 @emph{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 @code{gnatlink} using either of the following: |
| |
| |
| @itemize * |
| |
| @item |
| @code{-Xlinker} linker option |
| |
| @example |
| $ gnatlink hello -Xlinker --stack=0x10000,0x1000 |
| @end example |
| |
| This sets the stack reserve size to 0x10000 bytes and the stack commit |
| size to 0x1000 bytes. |
| |
| @item |
| @code{-Wl} linker option |
| |
| @example |
| $ gnatlink hello -Wl,--stack=0x1000000 |
| @end example |
| |
| This sets the stack reserve size to 0x1000000 bytes. Note that with |
| @code{-Wl} option it is not possible to set the stack commit size |
| because the comma is a separator for this option. |
| @end itemize |
| |
| @node Setting Heap Size from gnatlink,,Setting Stack Size from gnatlink,Mixed-Language Programming on Windows |
| @anchor{gnat_ugn/platform_specific_information id40}@anchor{208}@anchor{gnat_ugn/platform_specific_information setting-heap-size-from-gnatlink}@anchor{128} |
| @subsubsection Setting Heap Size from @code{gnatlink} |
| |
| |
| Under Windows systems, it is possible to specify the program heap size from |
| @code{gnatlink} using either of the following: |
| |
| |
| @itemize * |
| |
| @item |
| @code{-Xlinker} linker option |
| |
| @example |
| $ gnatlink hello -Xlinker --heap=0x10000,0x1000 |
| @end example |
| |
| This sets the heap reserve size to 0x10000 bytes and the heap commit |
| size to 0x1000 bytes. |
| |
| @item |
| @code{-Wl} linker option |
| |
| @example |
| $ gnatlink hello -Wl,--heap=0x1000000 |
| @end example |
| |
| This sets the heap reserve size to 0x1000000 bytes. Note that with |
| @code{-Wl} option it is not possible to set the heap commit size |
| because the comma is a separator for this option. |
| @end itemize |
| |
| @node Windows Specific Add-Ons,,Mixed-Language Programming on Windows,Microsoft Windows Topics |
| @anchor{gnat_ugn/platform_specific_information win32-specific-addons}@anchor{209}@anchor{gnat_ugn/platform_specific_information windows-specific-add-ons}@anchor{20a} |
| @subsection Windows Specific Add-Ons |
| |
| |
| This section describes the Windows specific add-ons. |
| |
| @menu |
| * Win32Ada:: |
| * wPOSIX:: |
| |
| @end menu |
| |
| @node Win32Ada,wPOSIX,,Windows Specific Add-Ons |
| @anchor{gnat_ugn/platform_specific_information id41}@anchor{20b}@anchor{gnat_ugn/platform_specific_information win32ada}@anchor{20c} |
| @subsubsection Win32Ada |
| |
| |
| Win32Ada is a binding for the Microsoft Win32 API. This binding can be |
| easily installed from the provided installer. To use the Win32Ada |
| binding you need to use a project file, and adding a single with_clause |
| will give you full access to the Win32Ada binding sources and ensure |
| that the proper libraries are passed to the linker. |
| |
| @quotation |
| |
| @example |
| with "win32ada"; |
| project P is |
| for Sources use ...; |
| end P; |
| @end example |
| @end quotation |
| |
| To build the application you just need to call gprbuild for the |
| application’s project, here p.gpr: |
| |
| @quotation |
| |
| @example |
| gprbuild p.gpr |
| @end example |
| @end quotation |
| |
| @node wPOSIX,,Win32Ada,Windows Specific Add-Ons |
| @anchor{gnat_ugn/platform_specific_information id42}@anchor{20d}@anchor{gnat_ugn/platform_specific_information wposix}@anchor{20e} |
| @subsubsection wPOSIX |
| |
| |
| wPOSIX is a minimal POSIX binding whose goal is to help with building |
| cross-platforms applications. This binding is not complete though, as |
| the Win32 API does not provide the necessary support for all POSIX APIs. |
| |
| To use the wPOSIX binding you need to use a project file, and adding |
| a single with_clause will give you full access to the wPOSIX binding |
| sources and ensure that the proper libraries are passed to the linker. |
| |
| @quotation |
| |
| @example |
| with "wposix"; |
| project P is |
| for Sources use ...; |
| end P; |
| @end example |
| @end quotation |
| |
| To build the application you just need to call gprbuild for the |
| application’s project, here p.gpr: |
| |
| @quotation |
| |
| @example |
| gprbuild p.gpr |
| @end example |
| @end quotation |
| |
| @node Mac OS Topics,,Microsoft Windows Topics,Platform-Specific Information |
| @anchor{gnat_ugn/platform_specific_information id43}@anchor{20f}@anchor{gnat_ugn/platform_specific_information mac-os-topics}@anchor{210} |
| @section Mac OS Topics |
| |
| |
| @geindex OS X |
| |
| This section describes topics that are specific to Apple’s OS X |
| platform. |
| |
| @menu |
| * Codesigning the Debugger:: |
| |
| @end menu |
| |
| @node Codesigning the Debugger,,,Mac OS Topics |
| @anchor{gnat_ugn/platform_specific_information codesigning-the-debugger}@anchor{211} |
| @subsection Codesigning the Debugger |
| |
| |
| 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: |
| |
| @example |
| 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 example |
| |
| Codesigning requires a certificate. The following procedure explains |
| how to create one: |
| |
| |
| @itemize * |
| |
| @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 * |
| |
| @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: |
| |
| @quotation |
| |
| @example |
| $ codesign -f -s "gdb-cert" <gnat_install_prefix>/bin/gdb |
| @end example |
| @end quotation |
| |
| 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. Also, be sure that users are |
| in the Unix group @code{_developer}. |
| |
| @node Example of Binder Output File,Elaboration Order Handling in GNAT,Platform-Specific Information,Top |
| @anchor{gnat_ugn/example_of_binder_output doc}@anchor{212}@anchor{gnat_ugn/example_of_binder_output example-of-binder-output-file}@anchor{e}@anchor{gnat_ugn/example_of_binder_output id1}@anchor{213} |
| @chapter Example of Binder Output File |
| |
| |
| @geindex Binder output (example) |
| |
| This Appendix displays the source code for the output file |
| generated by @emph{gnatbind} for a simple ‘Hello World’ program. |
| Comments have been added for clarification purposes. |
| |
| @example |
| -- 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. |
| |
| pragma Ada_95; |
| with System; |
| package ada_main is |
| pragma Warnings (Off); |
| |
| -- 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: Pro 7.4.0w (20141119-49)" & ASCII.NUL; |
| pragma Export (C, GNAT_Version, "__gnat_version"); |
| |
| Ada_Main_Program_Name : constant String := "_ada_hello" & ASCII.NUL; |
| pragma Export (C, Ada_Main_Program_Name, "__gnat_ada_main_program_name"); |
| |
| -- 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 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 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. |
| |
| -- 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. |
| |
| -- 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. |
| |
| type Version_32 is mod 2 ** 32; |
| u00001 : constant Version_32 := 16#8ad6e54a#; |
| pragma Export (C, u00001, "helloB"); |
| u00002 : constant Version_32 := 16#fbff4c67#; |
| pragma Export (C, u00002, "system__standard_libraryB"); |
| u00003 : constant Version_32 := 16#1ec6fd90#; |
| pragma Export (C, u00003, "system__standard_libraryS"); |
| u00004 : constant Version_32 := 16#3ffc8e18#; |
| pragma Export (C, u00004, "adaS"); |
| u00005 : constant Version_32 := 16#28f088c2#; |
| pragma Export (C, u00005, "ada__text_ioB"); |
| u00006 : constant Version_32 := 16#f372c8ac#; |
| pragma Export (C, u00006, "ada__text_ioS"); |
| u00007 : constant Version_32 := 16#2c143749#; |
| pragma Export (C, u00007, "ada__exceptionsB"); |
| u00008 : constant Version_32 := 16#f4f0cce8#; |
| pragma Export (C, u00008, "ada__exceptionsS"); |
| u00009 : constant Version_32 := 16#a46739c0#; |
| pragma Export (C, u00009, "ada__exceptions__last_chance_handlerB"); |
| u00010 : constant Version_32 := 16#3aac8c92#; |
| pragma Export (C, u00010, "ada__exceptions__last_chance_handlerS"); |
| u00011 : constant Version_32 := 16#1d274481#; |
| pragma Export (C, u00011, "systemS"); |
| u00012 : constant Version_32 := 16#a207fefe#; |
| pragma Export (C, u00012, "system__soft_linksB"); |
| u00013 : constant Version_32 := 16#467d9556#; |
| pragma Export (C, u00013, "system__soft_linksS"); |
| u00014 : constant Version_32 := 16#b01dad17#; |
| pragma Export (C, u00014, "system__parametersB"); |
| u00015 : constant Version_32 := 16#630d49fe#; |
| pragma Export (C, u00015, "system__parametersS"); |
| u00016 : constant Version_32 := 16#b19b6653#; |
| pragma Export (C, u00016, "system__secondary_stackB"); |
| u00017 : constant Version_32 := 16#b6468be8#; |
| pragma Export (C, u00017, "system__secondary_stackS"); |
| u00018 : constant Version_32 := 16#39a03df9#; |
| pragma Export (C, u00018, "system__storage_elementsB"); |
| u00019 : constant Version_32 := 16#30e40e85#; |
| pragma Export (C, u00019, "system__storage_elementsS"); |
| u00020 : constant Version_32 := 16#41837d1e#; |
| pragma Export (C, u00020, "system__stack_checkingB"); |
| u00021 : constant Version_32 := 16#93982f69#; |
| pragma Export (C, u00021, "system__stack_checkingS"); |
| u00022 : constant Version_32 := 16#393398c1#; |
| pragma Export (C, u00022, "system__exception_tableB"); |
| u00023 : constant Version_32 := 16#b33e2294#; |
| pragma Export (C, u00023, "system__exception_tableS"); |
| u00024 : constant Version_32 := 16#ce4af020#; |
| pragma Export (C, u00024, "system__exceptionsB"); |
| u00025 : constant Version_32 := 16#75442977#; |
| pragma Export (C, u00025, "system__exceptionsS"); |
| u00026 : constant Version_32 := 16#37d758f1#; |
| pragma Export (C, u00026, "system__exceptions__machineS"); |
| u00027 : constant Version_32 := 16#b895431d#; |
| pragma Export (C, u00027, "system__exceptions_debugB"); |
| u00028 : constant Version_32 := 16#aec55d3f#; |
| pragma Export (C, u00028, "system__exceptions_debugS"); |
| u00029 : constant Version_32 := 16#570325c8#; |
| pragma Export (C, u00029, "system__img_intB"); |
| u00030 : constant Version_32 := 16#1ffca443#; |
| pragma Export (C, u00030, "system__img_intS"); |
| u00031 : constant Version_32 := 16#b98c3e16#; |
| pragma Export (C, u00031, "system__tracebackB"); |
| u00032 : constant Version_32 := 16#831a9d5a#; |
| pragma Export (C, u00032, "system__tracebackS"); |
| u00033 : constant Version_32 := 16#9ed49525#; |
| pragma Export (C, u00033, "system__traceback_entriesB"); |
| u00034 : constant Version_32 := 16#1d7cb2f1#; |
| pragma Export (C, u00034, "system__traceback_entriesS"); |
| u00035 : constant Version_32 := 16#8c33a517#; |
| pragma Export (C, u00035, "system__wch_conB"); |
| u00036 : constant Version_32 := 16#065a6653#; |
| pragma Export (C, u00036, "system__wch_conS"); |
| u00037 : constant Version_32 := 16#9721e840#; |
| pragma Export (C, u00037, "system__wch_stwB"); |
| u00038 : constant Version_32 := 16#2b4b4a52#; |
| pragma Export (C, u00038, "system__wch_stwS"); |
| u00039 : constant Version_32 := 16#92b797cb#; |
| pragma Export (C, u00039, "system__wch_cnvB"); |
| u00040 : constant Version_32 := 16#09eddca0#; |
| pragma Export (C, u00040, "system__wch_cnvS"); |
| u00041 : constant Version_32 := 16#6033a23f#; |
| pragma Export (C, u00041, "interfacesS"); |
| u00042 : constant Version_32 := 16#ece6fdb6#; |
| pragma Export (C, u00042, "system__wch_jisB"); |
| u00043 : constant Version_32 := 16#899dc581#; |
| pragma Export (C, u00043, "system__wch_jisS"); |
| u00044 : constant Version_32 := 16#10558b11#; |
| pragma Export (C, u00044, "ada__streamsB"); |
| u00045 : constant Version_32 := 16#2e6701ab#; |
| pragma Export (C, u00045, "ada__streamsS"); |
| u00046 : constant Version_32 := 16#db5c917c#; |
| pragma Export (C, u00046, "ada__io_exceptionsS"); |
| u00047 : constant Version_32 := 16#12c8cd7d#; |
| pragma Export (C, u00047, "ada__tagsB"); |
| u00048 : constant Version_32 := 16#ce72c228#; |
| pragma Export (C, u00048, "ada__tagsS"); |
| u00049 : constant Version_32 := 16#c3335bfd#; |
| pragma Export (C, u00049, "system__htableB"); |
| u00050 : constant Version_32 := 16#99e5f76b#; |
| pragma Export (C, u00050, "system__htableS"); |
| u00051 : constant Version_32 := 16#089f5cd0#; |
| pragma Export (C, u00051, "system__string_hashB"); |
| u00052 : constant Version_32 := 16#3bbb9c15#; |
| pragma Export (C, u00052, "system__string_hashS"); |
| u00053 : constant Version_32 := 16#807fe041#; |
| pragma Export (C, u00053, "system__unsigned_typesS"); |
| u00054 : constant Version_32 := 16#d27be59e#; |
| pragma Export (C, u00054, "system__val_lluB"); |
| u00055 : constant Version_32 := 16#fa8db733#; |
| pragma Export (C, u00055, "system__val_lluS"); |
| u00056 : constant Version_32 := 16#27b600b2#; |
| pragma Export (C, u00056, "system__val_utilB"); |
| u00057 : constant Version_32 := 16#b187f27f#; |
| pragma Export (C, u00057, "system__val_utilS"); |
| u00058 : constant Version_32 := 16#d1060688#; |
| pragma Export (C, u00058, "system__case_utilB"); |
| u00059 : constant Version_32 := 16#392e2d56#; |
| pragma Export (C, u00059, "system__case_utilS"); |
| u00060 : constant Version_32 := 16#84a27f0d#; |
| pragma Export (C, u00060, "interfaces__c_streamsB"); |
| u00061 : constant Version_32 := 16#8bb5f2c0#; |
| pragma Export (C, u00061, "interfaces__c_streamsS"); |
| u00062 : constant Version_32 := 16#6db6928f#; |
| pragma Export (C, u00062, "system__crtlS"); |
| u00063 : constant Version_32 := 16#4e6a342b#; |
| pragma Export (C, u00063, "system__file_ioB"); |
| u00064 : constant Version_32 := 16#ba56a5e4#; |
| pragma Export (C, u00064, "system__file_ioS"); |
| u00065 : constant Version_32 := 16#b7ab275c#; |
| pragma Export (C, u00065, "ada__finalizationB"); |
| u00066 : constant Version_32 := 16#19f764ca#; |
| pragma Export (C, u00066, "ada__finalizationS"); |
| u00067 : constant Version_32 := 16#95817ed8#; |
| pragma Export (C, u00067, "system__finalization_rootB"); |
| u00068 : constant Version_32 := 16#52d53711#; |
| pragma Export (C, u00068, "system__finalization_rootS"); |
| u00069 : constant Version_32 := 16#769e25e6#; |
| pragma Export (C, u00069, "interfaces__cB"); |
| u00070 : constant Version_32 := 16#4a38bedb#; |
| pragma Export (C, u00070, "interfaces__cS"); |
| u00071 : constant Version_32 := 16#07e6ee66#; |
| pragma Export (C, u00071, "system__os_libB"); |
| u00072 : constant Version_32 := 16#d7b69782#; |
| pragma Export (C, u00072, "system__os_libS"); |
| u00073 : constant Version_32 := 16#1a817b8e#; |
| pragma Export (C, u00073, "system__stringsB"); |
| u00074 : constant Version_32 := 16#639855e7#; |
| pragma Export (C, u00074, "system__stringsS"); |
| u00075 : constant Version_32 := 16#e0b8de29#; |
| pragma Export (C, u00075, "system__file_control_blockS"); |
| u00076 : constant Version_32 := 16#b5b2aca1#; |
| pragma Export (C, u00076, "system__finalization_mastersB"); |
| u00077 : constant Version_32 := 16#69316dc1#; |
| pragma Export (C, u00077, "system__finalization_mastersS"); |
| u00078 : constant Version_32 := 16#57a37a42#; |
| pragma Export (C, u00078, "system__address_imageB"); |
| u00079 : constant Version_32 := 16#bccbd9bb#; |
| pragma Export (C, u00079, "system__address_imageS"); |
| u00080 : constant Version_32 := 16#7268f812#; |
| pragma Export (C, u00080, "system__img_boolB"); |
| u00081 : constant Version_32 := 16#e8fe356a#; |
| pragma Export (C, u00081, "system__img_boolS"); |
| u00082 : constant Version_32 := 16#d7aac20c#; |
| pragma Export (C, u00082, "system__ioB"); |
| u00083 : constant Version_32 := 16#8365b3ce#; |
| pragma Export (C, u00083, "system__ioS"); |
| u00084 : constant Version_32 := 16#6d4d969a#; |
| pragma Export (C, u00084, "system__storage_poolsB"); |
| u00085 : constant Version_32 := 16#e87cc305#; |
| pragma Export (C, u00085, "system__storage_poolsS"); |
| u00086 : constant Version_32 := 16#e34550ca#; |
| pragma Export (C, u00086, "system__pool_globalB"); |
| u00087 : constant Version_32 := 16#c88d2d16#; |
| pragma Export (C, u00087, "system__pool_globalS"); |
| u00088 : constant Version_32 := 16#9d39c675#; |
| pragma Export (C, u00088, "system__memoryB"); |
| u00089 : constant Version_32 := 16#445a22b5#; |
| pragma Export (C, u00089, "system__memoryS"); |
| u00090 : constant Version_32 := 16#6a859064#; |
| pragma Export (C, u00090, "system__storage_pools__subpoolsB"); |
| u00091 : constant Version_32 := 16#e3b008dc#; |
| pragma Export (C, u00091, "system__storage_pools__subpoolsS"); |
| u00092 : constant Version_32 := 16#63f11652#; |
| pragma Export (C, u00092, "system__storage_pools__subpools__finalizationB"); |
| u00093 : constant Version_32 := 16#fe2f4b3a#; |
| pragma Export (C, u00093, "system__storage_pools__subpools__finalizationS"); |
| |
| -- BEGIN ELABORATION ORDER |
| -- ada%s |
| -- interfaces%s |
| -- system%s |
| -- system.case_util%s |
| -- system.case_util%b |
| -- system.htable%s |
| -- system.img_bool%s |
| -- system.img_bool%b |
| -- system.img_int%s |
| -- system.img_int%b |
| -- system.io%s |
| -- system.io%b |
| -- system.parameters%s |
| -- system.parameters%b |
| -- system.crtl%s |
| -- interfaces.c_streams%s |
| -- interfaces.c_streams%b |
| -- system.standard_library%s |
| -- system.exceptions_debug%s |
| -- system.exceptions_debug%b |
| -- system.storage_elements%s |
| -- system.storage_elements%b |
| -- system.stack_checking%s |
| -- system.stack_checking%b |
| -- system.string_hash%s |
| -- system.string_hash%b |
| -- system.htable%b |
| -- system.strings%s |
| -- system.strings%b |
| -- system.os_lib%s |
| -- system.traceback_entries%s |
| -- system.traceback_entries%b |
| -- ada.exceptions%s |
| -- system.soft_links%s |
| -- system.unsigned_types%s |
| -- system.val_llu%s |
| -- system.val_util%s |
| -- system.val_util%b |
| -- system.val_llu%b |
| -- system.wch_con%s |
| -- system.wch_con%b |
| -- system.wch_cnv%s |
| -- system.wch_jis%s |
| -- system.wch_jis%b |
| -- system.wch_cnv%b |
| -- system.wch_stw%s |
| -- system.wch_stw%b |
| -- ada.exceptions.last_chance_handler%s |
| -- ada.exceptions.last_chance_handler%b |
| -- system.address_image%s |
| -- system.exception_table%s |
| -- system.exception_table%b |
| -- ada.io_exceptions%s |
| -- ada.tags%s |
| -- ada.streams%s |
| -- ada.streams%b |
| -- interfaces.c%s |
| -- system.exceptions%s |
| -- system.exceptions%b |
| -- system.exceptions.machine%s |
| -- system.finalization_root%s |
| -- system.finalization_root%b |
| -- ada.finalization%s |
| -- ada.finalization%b |
| -- system.storage_pools%s |
| -- system.storage_pools%b |
| -- system.finalization_masters%s |
| -- system.storage_pools.subpools%s |
| -- system.storage_pools.subpools.finalization%s |
| -- system.storage_pools.subpools.finalization%b |
| -- system.memory%s |
| -- system.memory%b |
| -- system.standard_library%b |
| -- system.pool_global%s |
| -- system.pool_global%b |
| -- system.file_control_block%s |
| -- system.file_io%s |
| -- system.secondary_stack%s |
| -- system.file_io%b |
| -- system.storage_pools.subpools%b |
| -- system.finalization_masters%b |
| -- interfaces.c%b |
| -- ada.tags%b |
| -- system.soft_links%b |
| -- system.os_lib%b |
| -- system.secondary_stack%b |
| -- system.address_image%b |
| -- system.traceback%s |
| -- ada.exceptions%b |
| -- system.traceback%b |
| -- ada.text_io%s |
| -- ada.text_io%b |
| -- hello%b |
| -- END ELABORATION ORDER |
| |
| end ada_main; |
| @end example |
| |
| @example |
| pragma Ada_95; |
| -- 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"); |
| |
| pragma Suppress (Overflow_Check); |
| with Ada.Exceptions; |
| |
| -- Generated package body for Ada_Main starts here |
| |
| package body ada_main is |
| pragma Warnings (Off); |
| |
| -- These values are reference counter associated to units which have |
| -- been elaborated. It is also used to avoid elaborating the |
| -- same unit twice. |
| |
| E72 : Short_Integer; pragma Import (Ada, E72, "system__os_lib_E"); |
| E13 : Short_Integer; pragma Import (Ada, E13, "system__soft_links_E"); |
| E23 : Short_Integer; pragma Import (Ada, E23, "system__exception_table_E"); |
| E46 : Short_Integer; pragma Import (Ada, E46, "ada__io_exceptions_E"); |
| E48 : Short_Integer; pragma Import (Ada, E48, "ada__tags_E"); |
| E45 : Short_Integer; pragma Import (Ada, E45, "ada__streams_E"); |
| E70 : Short_Integer; pragma Import (Ada, E70, "interfaces__c_E"); |
| E25 : Short_Integer; pragma Import (Ada, E25, "system__exceptions_E"); |
| E68 : Short_Integer; pragma Import (Ada, E68, "system__finalization_root_E"); |
| E66 : Short_Integer; pragma Import (Ada, E66, "ada__finalization_E"); |
| E85 : Short_Integer; pragma Import (Ada, E85, "system__storage_pools_E"); |
| E77 : Short_Integer; pragma Import (Ada, E77, "system__finalization_masters_E"); |
| E91 : Short_Integer; pragma Import (Ada, E91, "system__storage_pools__subpools_E"); |
| E87 : Short_Integer; pragma Import (Ada, E87, "system__pool_global_E"); |
| E75 : Short_Integer; pragma Import (Ada, E75, "system__file_control_block_E"); |
| E64 : Short_Integer; pragma Import (Ada, E64, "system__file_io_E"); |
| E17 : Short_Integer; pragma Import (Ada, E17, "system__secondary_stack_E"); |
| E06 : Short_Integer; pragma Import (Ada, E06, "ada__text_io_E"); |
| |
| Local_Priority_Specific_Dispatching : constant String := ""; |
| Local_Interrupt_States : constant String := ""; |
| |
| Is_Elaborated : Boolean := False; |
| |
| procedure finalize_library is |
| begin |
| E06 := E06 - 1; |
| declare |
| procedure F1; |
| pragma Import (Ada, F1, "ada__text_io__finalize_spec"); |
| begin |
| F1; |
| end; |
| E77 := E77 - 1; |
| E91 := E91 - 1; |
| declare |
| procedure F2; |
| pragma Import (Ada, F2, "system__file_io__finalize_body"); |
| begin |
| E64 := E64 - 1; |
| F2; |
| end; |
| declare |
| procedure F3; |
| pragma Import (Ada, F3, "system__file_control_block__finalize_spec"); |
| begin |
| E75 := E75 - 1; |
| F3; |
| end; |
| E87 := E87 - 1; |
| declare |
| procedure F4; |
| pragma Import (Ada, F4, "system__pool_global__finalize_spec"); |
| begin |
| F4; |
| end; |
| declare |
| procedure F5; |
| pragma Import (Ada, F5, "system__storage_pools__subpools__finalize_spec"); |
| begin |
| F5; |
| end; |
| declare |
| procedure F6; |
| pragma Import (Ada, F6, "system__finalization_masters__finalize_spec"); |
| begin |
| F6; |
| end; |
| declare |
| procedure Reraise_Library_Exception_If_Any; |
| pragma Import (Ada, Reraise_Library_Exception_If_Any, "__gnat_reraise_library_exception_if_any"); |
| begin |
| Reraise_Library_Exception_If_Any; |
| end; |
| end finalize_library; |
| |
| ------------- |
| -- adainit -- |
| ------------- |
| |
| procedure adainit is |
| |
| Main_Priority : Integer; |
| pragma Import (C, Main_Priority, "__gl_main_priority"); |
| Time_Slice_Value : Integer; |
| pragma Import (C, Time_Slice_Value, "__gl_time_slice_val"); |
| WC_Encoding : Character; |
| pragma Import (C, WC_Encoding, "__gl_wc_encoding"); |
| Locking_Policy : Character; |
| pragma Import (C, Locking_Policy, "__gl_locking_policy"); |
| Queuing_Policy : Character; |
| pragma Import (C, Queuing_Policy, "__gl_queuing_policy"); |
| Task_Dispatching_Policy : Character; |
| pragma Import (C, Task_Dispatching_Policy, "__gl_task_dispatching_policy"); |
| Priority_Specific_Dispatching : System.Address; |
| pragma Import (C, Priority_Specific_Dispatching, "__gl_priority_specific_dispatching"); |
| Num_Specific_Dispatching : Integer; |
| pragma Import (C, Num_Specific_Dispatching, "__gl_num_specific_dispatching"); |
| Main_CPU : Integer; |
| pragma Import (C, Main_CPU, "__gl_main_cpu"); |
| Interrupt_States : System.Address; |
| pragma Import (C, Interrupt_States, "__gl_interrupt_states"); |
| Num_Interrupt_States : Integer; |
| pragma Import (C, Num_Interrupt_States, "__gl_num_interrupt_states"); |
| Unreserve_All_Interrupts : Integer; |
| pragma Import (C, Unreserve_All_Interrupts, "__gl_unreserve_all_interrupts"); |
| Detect_Blocking : Integer; |
| pragma Import (C, Detect_Blocking, "__gl_detect_blocking"); |
| Default_Stack_Size : Integer; |
| pragma Import (C, Default_Stack_Size, "__gl_default_stack_size"); |
| Leap_Seconds_Support : Integer; |
| pragma Import (C, Leap_Seconds_Support, "__gl_leap_seconds_support"); |
| |
| procedure Runtime_Initialize; |
| pragma Import (C, Runtime_Initialize, "__gnat_runtime_initialize"); |
| |
| Finalize_Library_Objects : No_Param_Proc; |
| pragma Import (C, Finalize_Library_Objects, "__gnat_finalize_library_objects"); |
| |
| -- Start of processing for adainit |
| |
| begin |
| |
| -- Record various information for this partition. The values |
| -- are derived by the binder from information stored in the ali |
| -- files by the compiler. |
| |
| if Is_Elaborated then |
| return; |
| end if; |
| Is_Elaborated := True; |
| Main_Priority := -1; |
| Time_Slice_Value := -1; |
| WC_Encoding := 'b'; |
| Locking_Policy := ' '; |
| Queuing_Policy := ' '; |
| Task_Dispatching_Policy := ' '; |
| Priority_Specific_Dispatching := |
| Local_Priority_Specific_Dispatching'Address; |
| Num_Specific_Dispatching := 0; |
| Main_CPU := -1; |
| Interrupt_States := Local_Interrupt_States'Address; |
| Num_Interrupt_States := 0; |
| Unreserve_All_Interrupts := 0; |
| Detect_Blocking := 0; |
| Default_Stack_Size := -1; |
| Leap_Seconds_Support := 0; |
| |
| Runtime_Initialize; |
| |
| Finalize_Library_Objects := finalize_library'access; |
| |
| -- 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. Increment a counter of |
| -- reference for each unit. |
| |
| System.Soft_Links'Elab_Spec; |
| System.Exception_Table'Elab_Body; |
| E23 := E23 + 1; |
| Ada.Io_Exceptions'Elab_Spec; |
| E46 := E46 + 1; |
| Ada.Tags'Elab_Spec; |
| Ada.Streams'Elab_Spec; |
| E45 := E45 + 1; |
| Interfaces.C'Elab_Spec; |
| System.Exceptions'Elab_Spec; |
| E25 := E25 + 1; |
| System.Finalization_Root'Elab_Spec; |
| E68 := E68 + 1; |
| Ada.Finalization'Elab_Spec; |
| E66 := E66 + 1; |
| System.Storage_Pools'Elab_Spec; |
| E85 := E85 + 1; |
| System.Finalization_Masters'Elab_Spec; |
| System.Storage_Pools.Subpools'Elab_Spec; |
| System.Pool_Global'Elab_Spec; |
| E87 := E87 + 1; |
| System.File_Control_Block'Elab_Spec; |
| E75 := E75 + 1; |
| System.File_Io'Elab_Body; |
| E64 := E64 + 1; |
| E91 := E91 + 1; |
| System.Finalization_Masters'Elab_Body; |
| E77 := E77 + 1; |
| E70 := E70 + 1; |
| Ada.Tags'Elab_Body; |
| E48 := E48 + 1; |
| System.Soft_Links'Elab_Body; |
| E13 := E13 + 1; |
| System.Os_Lib'Elab_Body; |
| E72 := E72 + 1; |
| System.Secondary_Stack'Elab_Body; |
| E17 := E17 + 1; |
| Ada.Text_Io'Elab_Spec; |
| Ada.Text_Io'Elab_Body; |
| E06 := E06 + 1; |
| end adainit; |
| |
| -------------- |
| -- adafinal -- |
| -------------- |
| |
| procedure adafinal is |
| procedure s_stalib_adafinal; |
| pragma Import (C, s_stalib_adafinal, "system__standard_library__adafinal"); |
| |
| procedure Runtime_Finalize; |
| pragma Import (C, Runtime_Finalize, "__gnat_runtime_finalize"); |
| |
| begin |
| if not Is_Elaborated then |
| return; |
| end if; |
| Is_Elaborated := False; |
| Runtime_Finalize; |
| s_stalib_adafinal; |
| end adafinal; |
| |
| -- 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"); |
| |
| ---------- |
| -- 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. |
| |
| 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. |
| |
| 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. |
| |
| procedure finalize; |
| pragma Import (C, finalize, "__gnat_finalize"); |
| |
| -- The following is to initialize the SEH exceptions |
| |
| SEH : aliased array (1 .. 2) of Integer; |
| |
| Ensure_Reference : aliased System.Address := Ada_Main_Program_Name'Address; |
| pragma Volatile (Ensure_Reference); |
| |
| -- Start of processing for main |
| |
| begin |
| -- Save global variables |
| |
| gnat_argc := argc; |
| gnat_argv := argv; |
| gnat_envp := envp; |
| |
| -- Call low level system initialization |
| |
| Initialize (SEH'Address); |
| |
| -- Call our generated Ada initialization routine |
| |
| adainit; |
| |
| -- 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. |
| |
| -- 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 example |
| |
| 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: |
| |
| @quotation |
| |
| @example |
| Ada.Text_Io'Elab_Body; |
| @end example |
| @end quotation |
| |
| 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). |
| |
| @c -- Example: A |withing| unit has a |with| clause, it |withs| a |withed| unit |
| |
| @node Elaboration Order Handling in GNAT,Inline Assembler,Example of Binder Output File,Top |
| @anchor{gnat_ugn/elaboration_order_handling_in_gnat doc}@anchor{214}@anchor{gnat_ugn/elaboration_order_handling_in_gnat elaboration-order-handling-in-gnat}@anchor{f}@anchor{gnat_ugn/elaboration_order_handling_in_gnat id1}@anchor{215} |
| @chapter Elaboration Order Handling in GNAT |
| |
| |
| @geindex Order of elaboration |
| |
| @geindex Elaboration control |
| |
| This appendix describes the handling of elaboration code in Ada and GNAT, and |
| discusses how the order of elaboration of program units can be controlled in |
| GNAT, either automatically or with explicit programming features. |
| |
| @menu |
| * Elaboration Code:: |
| * Elaboration Order:: |
| * Checking the Elaboration Order:: |
| * Controlling the Elaboration Order in Ada:: |
| * Controlling the Elaboration Order in GNAT:: |
| * Mixing Elaboration Models:: |
| * ABE Diagnostics:: |
| * SPARK Diagnostics:: |
| * Elaboration Circularities:: |
| * Resolving Elaboration Circularities:: |
| * Elaboration-related Compiler Switches:: |
| * Summary of Procedures for Elaboration Control:: |
| * Inspecting the Chosen Elaboration Order:: |
| |
| @end menu |
| |
| @node Elaboration Code,Elaboration Order,,Elaboration Order Handling in GNAT |
| @anchor{gnat_ugn/elaboration_order_handling_in_gnat elaboration-code}@anchor{216}@anchor{gnat_ugn/elaboration_order_handling_in_gnat id2}@anchor{217} |
| @section Elaboration Code |
| |
| |
| Ada defines the term @emph{execution} as the process by which a construct achieves |
| its run-time effect. This process is also referred to as @strong{elaboration} for |
| declarations and @emph{evaluation} for expressions. |
| |
| The execution model in Ada allows for certain sections of an Ada program to be |
| executed prior to execution of the program itself, primarily with the intent of |
| initializing data. These sections are referred to as @strong{elaboration code}. |
| Elaboration code is executed as follows: |
| |
| |
| @itemize * |
| |
| @item |
| All partitions of an Ada program are executed in parallel with one another, |
| possibly in a separate address space, and possibly on a separate computer. |
| |
| @item |
| The execution of a partition involves running the environment task for that |
| partition. |
| |
| @item |
| The environment task executes all elaboration code (if available) for all |
| units within that partition. This code is said to be executed at |
| @strong{elaboration time}. |
| |
| @item |
| The environment task executes the Ada program (if available) for that |
| partition. |
| @end itemize |
| |
| In addition to the Ada terminology, this appendix defines the following terms: |
| |
| |
| @itemize * |
| |
| @item |
| @emph{Invocation} |
| |
| The act of calling a subprogram, instantiating a generic, or activating a |
| task. |
| |
| @item |
| @emph{Scenario} |
| |
| A construct that is elaborated or invoked by elaboration code is referred to |
| as an @emph{elaboration scenario} or simply a @strong{scenario}. GNAT recognizes the |
| following scenarios: |
| |
| |
| @itemize - |
| |
| @item |
| @code{'Access} of entries, operators, and subprograms |
| |
| @item |
| Activation of tasks |
| |
| @item |
| Calls to entries, operators, and subprograms |
| |
| @item |
| Instantiations of generic templates |
| @end itemize |
| |
| @item |
| @emph{Target} |
| |
| A construct elaborated by a scenario is referred to as @emph{elaboration target} |
| or simply @strong{target}. GNAT recognizes the following targets: |
| |
| |
| @itemize - |
| |
| @item |
| For @code{'Access} of entries, operators, and subprograms, the target is the |
| entry, operator, or subprogram being aliased. |
| |
| @item |
| For activation of tasks, the target is the task body |
| |
| @item |
| For calls to entries, operators, and subprograms, the target is the entry, |
| operator, or subprogram being invoked. |
| |
| @item |
| For instantiations of generic templates, the target is the generic template |
| being instantiated. |
| @end itemize |
| @end itemize |
| |
| Elaboration code may appear in two distinct contexts: |
| |
| |
| @itemize * |
| |
| @item |
| @emph{Library level} |
| |
| A scenario appears at the library level when it is encapsulated by a package |
| [body] compilation unit, ignoring any other package [body] declarations in |
| between. |
| |
| @example |
| with Server; |
| package Client is |
| procedure Proc; |
| |
| package Nested is |
| Val : ... := Server.Func; |
| end Nested; |
| end Client; |
| @end example |
| |
| In the example above, the call to @code{Server.Func} is an elaboration scenario |
| because it appears at the library level of package @code{Client}. Note that the |
| declaration of package @code{Nested} is ignored according to the definition |
| given above. As a result, the call to @code{Server.Func} will be invoked when |
| the spec of unit @code{Client} is elaborated. |
| |
| @item |
| @emph{Package body statements} |
| |
| A scenario appears within the statement sequence of a package body when it is |
| bounded by the region starting from the @code{begin} keyword of the package body |
| and ending at the @code{end} keyword of the package body. |
| |
| @example |
| package body Client is |
| procedure Proc is |
| begin |
| ... |
| end Proc; |
| begin |
| Proc; |
| end Client; |
| @end example |
| |
| In the example above, the call to @code{Proc} is an elaboration scenario because |
| it appears within the statement sequence of package body @code{Client}. As a |
| result, the call to @code{Proc} will be invoked when the body of @code{Client} is |
| elaborated. |
| @end itemize |
| |
| @node Elaboration Order,Checking the Elaboration Order,Elaboration Code,Elaboration Order Handling in GNAT |
| @anchor{gnat_ugn/elaboration_order_handling_in_gnat elaboration-order}@anchor{218}@anchor{gnat_ugn/elaboration_order_handling_in_gnat id3}@anchor{219} |
| @section Elaboration Order |
| |
| |
| The sequence by which the elaboration code of all units within a partition is |
| executed is referred to as @strong{elaboration order}. |
| |
| Within a single unit, elaboration code is executed in sequential order. |
| |
| @quotation |
| |
| @example |
| package body Client is |
| Result : ... := Server.Func; |
| |
| procedure Proc is |
| package Inst is new Server.Gen; |
| begin |
| Inst.Eval (Result); |
| end Proc; |
| begin |
| Proc; |
| end Client; |
| @end example |
| @end quotation |
| |
| In the example above, the elaboration order within package body @code{Client} is |
| as follows: |
| |
| |
| @enumerate |
| |
| @item |
| The object declaration of @code{Result} is elaborated. |
| |
| |
| @itemize * |
| |
| @item |
| Function @code{Server.Func} is invoked. |
| @end itemize |
| |
| @item |
| The subprogram body of @code{Proc} is elaborated. |
| |
| @item |
| Procedure @code{Proc} is invoked. |
| |
| |
| @itemize * |
| |
| @item |
| Generic unit @code{Server.Gen} is instantiated as @code{Inst}. |
| |
| @item |
| Instance @code{Inst} is elaborated. |
| |
| @item |
| Procedure @code{Inst.Eval} is invoked. |
| @end itemize |
| @end enumerate |
| |
| The elaboration order of all units within a partition depends on the following |
| factors: |
| |
| |
| @itemize * |
| |
| @item |
| @emph{with}ed units |
| |
| @item |
| parent units |
| |
| @item |
| purity of units |
| |
| @item |
| preelaborability of units |
| |
| @item |
| presence of elaboration-control pragmas |
| |
| @item |
| invocations performed in elaboration code |
| @end itemize |
| |
| A program may have several elaboration orders depending on its structure. |
| |
| @quotation |
| |
| @example |
| package Server is |
| function Func (Index : Integer) return Integer; |
| end Server; |
| @end example |
| |
| @example |
| package body Server is |
| Results : array (1 .. 5) of Integer := (1, 2, 3, 4, 5); |
| |
| function Func (Index : Integer) return Integer is |
| begin |
| return Results (Index); |
| end Func; |
| end Server; |
| @end example |
| |
| @example |
| with Server; |
| package Client is |
| Val : constant Integer := Server.Func (3); |
| end Client; |
| @end example |
| |
| @example |
| with Client; |
| procedure Main is begin null; end Main; |
| @end example |
| @end quotation |
| |
| The following elaboration order exhibits a fundamental problem referred to as |
| @emph{access-before-elaboration} or simply @strong{ABE}. |
| |
| @quotation |
| |
| @example |
| spec of Server |
| spec of Client |
| body of Server |
| body of Main |
| @end example |
| @end quotation |
| |
| The elaboration of @code{Server}’s spec materializes function @code{Func}, making it |
| callable. The elaboration of @code{Client}’s spec elaborates the declaration of |
| @code{Val}. This invokes function @code{Server.Func}, however the body of |
| @code{Server.Func} has not been elaborated yet because @code{Server}’s body comes |
| after @code{Client}’s spec in the elaboration order. As a result, the value of |
| constant @code{Val} is now undefined. |
| |
| Without any guarantees from the language, an undetected ABE problem may hinder |
| proper initialization of data, which in turn may lead to undefined behavior at |
| run time. To prevent such ABE problems, Ada employs dynamic checks in the same |
| vein as index or null exclusion checks. A failed ABE check raises exception |
| @code{Program_Error}. |
| |
| The following elaboration order avoids the ABE problem and the program can be |
| successfully elaborated. |
| |
| @quotation |
| |
| @example |
| spec of Server |
| body of Server |
| spec of Client |
| body of Main |
| @end example |
| @end quotation |
| |
| Ada states that a total elaboration order must exist, but it does not define |
| what this order is. A compiler is thus tasked with choosing a suitable |
| elaboration order which satisfies the dependencies imposed by @emph{with} clauses, |
| unit categorization, elaboration-control pragmas, and invocations performed in |
| elaboration code. Ideally an order that avoids ABE problems should be chosen, |
| however a compiler may not always find such an order due to complications with |
| respect to control and data flow. |
| |
| @node Checking the Elaboration Order,Controlling the Elaboration Order in Ada,Elaboration Order,Elaboration Order Handling in GNAT |
| @anchor{gnat_ugn/elaboration_order_handling_in_gnat checking-the-elaboration-order}@anchor{21a}@anchor{gnat_ugn/elaboration_order_handling_in_gnat id4}@anchor{21b} |
| @section Checking the Elaboration Order |
| |
| |
| To avoid placing the entire elaboration-order burden on the programmer, Ada |
| provides three lines of defense: |
| |
| |
| @itemize * |
| |
| @item |
| @emph{Static semantics} |
| |
| Static semantic rules restrict the possible choice of elaboration order. For |
| instance, if unit Client @emph{with}s unit Server, then the spec of Server is |
| always elaborated prior to Client. The same principle applies to child units |
| - the spec of a parent unit is always elaborated prior to the child unit. |
| |
| @item |
| @emph{Dynamic semantics} |
| |
| Dynamic checks are performed at run time, to ensure that a target is |
| elaborated prior to a scenario that invokes it, thus avoiding ABE problems. |
| A failed run-time check raises exception @code{Program_Error}. The following |
| restrictions apply: |
| |
| |
| @itemize - |
| |
| @item |
| @emph{Restrictions on calls} |
| |
| An entry, operator, or subprogram can be called from elaboration code only |
| when the corresponding body has been elaborated. |
| |
| @item |
| @emph{Restrictions on instantiations} |
| |
| A generic unit can be instantiated by elaboration code only when the |
| corresponding body has been elaborated. |
| |
| @item |
| @emph{Restrictions on task activation} |
| |
| A task can be activated by elaboration code only when the body of the |
| associated task type has been elaborated. |
| @end itemize |
| |
| The restrictions above can be summarized by the following rule: |
| |
| @emph{If a target has a body, then this body must be elaborated prior to the |
| scenario that invokes the target.} |
| |
| @item |
| @emph{Elaboration control} |
| |
| Pragmas are provided for the programmer to specify the desired elaboration |
| order. |
| @end itemize |
| |
| @node Controlling the Elaboration Order in Ada,Controlling the Elaboration Order in GNAT,Checking the Elaboration Order,Elaboration Order Handling in GNAT |
| @anchor{gnat_ugn/elaboration_order_handling_in_gnat controlling-the-elaboration-order-in-ada}@anchor{21c}@anchor{gnat_ugn/elaboration_order_handling_in_gnat id5}@anchor{21d} |
| @section Controlling the Elaboration Order in Ada |
| |
| |
| Ada provides several idioms and pragmas to aid the programmer with specifying |
| the desired elaboration order and avoiding ABE problems altogether. |
| |
| |
| @itemize * |
| |
| @item |
| @emph{Packages without a body} |
| |
| A library package which does not require a completing body does not suffer |
| from ABE problems. |
| |
| @example |
| package Pack is |
| generic |
| type Element is private; |
| package Containers is |
| type Element_Array is array (1 .. 10) of Element; |
| end Containers; |
| end Pack; |
| @end example |
| |
| In the example above, package @code{Pack} does not require a body because it |
| does not contain any constructs which require completion in a body. As a |
| result, generic @code{Pack.Containers} can be instantiated without encountering |
| any ABE problems. |
| @end itemize |
| |
| @geindex pragma Pure |
| |
| |
| @itemize * |
| |
| @item |
| @emph{pragma Pure} |
| |
| Pragma @code{Pure} places sufficient restrictions on a unit to guarantee that no |
| scenario within the unit can result in an ABE problem. |
| @end itemize |
| |
| @geindex pragma Preelaborate |
| |
| |
| @itemize * |
| |
| @item |
| @emph{pragma Preelaborate} |
| |
| Pragma @code{Preelaborate} is slightly less restrictive than pragma @code{Pure}, |
| but still strong enough to prevent ABE problems within a unit. |
| @end itemize |
| |
| @geindex pragma Elaborate_Body |
| |
| |
| @itemize * |
| |
| @item |
| @emph{pragma Elaborate_Body} |
| |
| Pragma @code{Elaborate_Body} requires that the body of a unit is elaborated |
| immediately after its spec. This restriction guarantees that no client |
| scenario can invoke a server target before the target body has been |
| elaborated because the spec and body are effectively “glued” together. |
| |
| @example |
| package Server is |
| pragma Elaborate_Body; |
| |
| function Func return Integer; |
| end Server; |
| @end example |
| |
| @example |
| package body Server is |
| function Func return Integer is |
| begin |
| ... |
| end Func; |
| end Server; |
| @end example |
| |
| @example |
| with Server; |
| package Client is |
| Val : constant Integer := Server.Func; |
| end Client; |
| @end example |
| |
| In the example above, pragma @code{Elaborate_Body} guarantees the following |
| elaboration order: |
| |
| @example |
| spec of Server |
| body of Server |
| spec of Client |
| @end example |
| |
| because the spec of @code{Server} must be elaborated prior to @code{Client} by |
| virtue of the @emph{with} clause, and in addition the body of @code{Server} must be |
| elaborated immediately after the spec of @code{Server}. |
| |
| Removing pragma @code{Elaborate_Body} could result in the following incorrect |
| elaboration order: |
| |
| @example |
| spec of Server |
| spec of Client |
| body of Server |
| @end example |
| |
| where @code{Client} invokes @code{Server.Func}, but the body of @code{Server.Func} has |
| not been elaborated yet. |
| @end itemize |
| |
| The pragmas outlined above allow a server unit to guarantee safe elaboration |
| use by client units. Thus it is a good rule to mark units as @code{Pure} or |
| @code{Preelaborate}, and if this is not possible, mark them as @code{Elaborate_Body}. |
| |
| There are however situations where @code{Pure}, @code{Preelaborate}, and |
| @code{Elaborate_Body} are not applicable. Ada provides another set of pragmas for |
| use by client units to help ensure the elaboration safety of server units they |
| depend on. |
| |
| @geindex pragma Elaborate (Unit) |
| |
| |
| @itemize * |
| |
| @item |
| @emph{pragma Elaborate (Unit)} |
| |
| Pragma @code{Elaborate} can be placed in the context clauses of a unit, after a |
| @emph{with} clause. It guarantees that both the spec and body of its argument will |
| be elaborated prior to the unit with the pragma. Note that other unrelated |
| units may be elaborated in between the spec and the body. |
| |
| @example |
| package Server is |
| function Func return Integer; |
| end Server; |
| @end example |
| |
| @example |
| package body Server is |
| function Func return Integer is |
| begin |
| ... |
| end Func; |
| end Server; |
| @end example |
| |
| @example |
| with Server; |
| pragma Elaborate (Server); |
| package Client is |
| Val : constant Integer := Server.Func; |
| end Client; |
| @end example |
| |
| In the example above, pragma @code{Elaborate} guarantees the following |
| elaboration order: |
| |
| @example |
| spec of Server |
| body of Server |
| spec of Client |
| @end example |
| |
| Removing pragma @code{Elaborate} could result in the following incorrect |
| elaboration order: |
| |
| @example |
| spec of Server |
| spec of Client |
| body of Server |
| @end example |
| |
| where @code{Client} invokes @code{Server.Func}, but the body of @code{Server.Func} |
| has not been elaborated yet. |
| @end itemize |
| |
| @geindex pragma Elaborate_All (Unit) |
| |
| |
| @itemize * |
| |
| @item |
| @emph{pragma Elaborate_All (Unit)} |
| |
| Pragma @code{Elaborate_All} is placed in the context clauses of a unit, after |
| a @emph{with} clause. It guarantees that both the spec and body of its argument |
| will be elaborated prior to the unit with the pragma, as well as all units |
| @emph{with}ed by the spec and body of the argument, recursively. Note that other |
| unrelated units may be elaborated in between the spec and the body. |
| |
| @example |
| package Math is |
| function Factorial (Val : Natural) return Natural; |
| end Math; |
| @end example |
| |
| @example |
| package body Math is |
| function Factorial (Val : Natural) return Natural is |
| begin |
| ...; |
| end Factorial; |
| end Math; |
| @end example |
| |
| @example |
| package Computer is |
| type Operation_Kind is (None, Op_Factorial); |
| |
| function Compute |
| (Val : Natural; |
| Op : Operation_Kind) return Natural; |
| end Computer; |
| @end example |
| |
| @example |
| with Math; |
| package body Computer is |
| function Compute |
| (Val : Natural; |
| Op : Operation_Kind) return Natural |
| is |
| if Op = Op_Factorial then |
| return Math.Factorial (Val); |
| end if; |
| |
| return 0; |
| end Compute; |
| end Computer; |
| @end example |
| |
| @example |
| with Computer; |
| pragma Elaborate_All (Computer); |
| package Client is |
| Val : constant Natural := |
| Computer.Compute (123, Computer.Op_Factorial); |
| end Client; |
| @end example |
| |
| In the example above, pragma @code{Elaborate_All} can result in the following |
| elaboration order: |
| |
| @example |
| spec of Math |
| body of Math |
| spec of Computer |
| body of Computer |
| spec of Client |
| @end example |
| |
| Note that there are several allowable suborders for the specs and bodies of |
| @code{Math} and @code{Computer}, but the point is that these specs and bodies will |
| be elaborated prior to @code{Client}. |
| |
| Removing pragma @code{Elaborate_All} could result in the following incorrect |
| elaboration order: |
| |
| @example |
| spec of Math |
| spec of Computer |
| body of Computer |
| spec of Client |
| body of Math |
| @end example |
| |
| where @code{Client} invokes @code{Computer.Compute}, which in turn invokes |
| @code{Math.Factorial}, but the body of @code{Math.Factorial} has not been |
| elaborated yet. |
| @end itemize |
| |
| All pragmas shown above can be summarized by the following rule: |
| |
| @emph{If a client unit elaborates a server target directly or indirectly, then if |
| the server unit requires a body and does not have pragma Pure, Preelaborate, |
| or Elaborate_Body, then the client unit should have pragma Elaborate or |
| Elaborate_All for the server unit.} |
| |
| If the rule outlined above is not followed, then a program may fall in one of |
| the following states: |
| |
| |
| @itemize * |
| |
| @item |
| @emph{No elaboration order exists} |
| |
| In this case a compiler must diagnose the situation, and refuse to build an |
| executable program. |
| |
| @item |
| @emph{One or more incorrect elaboration orders exist} |
| |
| In this case a compiler can build an executable program, but |
| @code{Program_Error} will be raised when the program is run. |
| |
| @item |
| @emph{Several elaboration orders exist, some correct, some incorrect} |
| |
| In this case the programmer has not controlled the elaboration order. As a |
| result, a compiler may or may not pick one of the correct orders, and the |
| program may or may not raise @code{Program_Error} when it is run. This is the |
| worst possible state because the program may fail on another compiler, or |
| even another version of the same compiler. |
| |
| @item |
| @emph{One or more correct orders exist} |
| |
| In this case a compiler can build an executable program, and the program is |
| run successfully. This state may be guaranteed by following the outlined |
| rules, or may be the result of good program architecture. |
| @end itemize |
| |
| Note that one additional advantage of using @code{Elaborate} and @code{Elaborate_All} |
| is that the program continues to stay in the last state (one or more correct |
| orders exist) even if maintenance changes the bodies of targets. |
| |
| @node Controlling the Elaboration Order in GNAT,Mixing Elaboration Models,Controlling the Elaboration Order in Ada,Elaboration Order Handling in GNAT |
| @anchor{gnat_ugn/elaboration_order_handling_in_gnat controlling-the-elaboration-order-in-gnat}@anchor{21e}@anchor{gnat_ugn/elaboration_order_handling_in_gnat id6}@anchor{21f} |
| @section Controlling the Elaboration Order in GNAT |
| |
| |
| In addition to Ada semantics and rules synthesized from them, GNAT offers |
| three elaboration models to aid the programmer with specifying the correct |
| elaboration order and to diagnose elaboration problems. |
| |
| @geindex Dynamic elaboration model |
| |
| |
| @itemize * |
| |
| @item |
| @emph{Dynamic elaboration model} |
| |
| This is the most permissive of the three elaboration models and emulates the |
| behavior specified by the Ada Reference Manual. When the dynamic model is in |
| effect, GNAT makes the following assumptions: |
| |
| |
| @itemize - |
| |
| @item |
| All code within all units in a partition is considered to be elaboration |
| code. |
| |
| @item |
| Some of the invocations in elaboration code may not take place at run time |
| due to conditional execution. |
| @end itemize |
| |
| GNAT performs extensive diagnostics on a unit-by-unit basis for all scenarios |
| that invoke internal targets. In addition, GNAT generates run-time checks for |
| all external targets and for all scenarios that may exhibit ABE problems. |
| |
| The elaboration order is obtained by honoring all @emph{with} clauses, purity and |
| preelaborability of units, and elaboration-control pragmas. The dynamic model |
| attempts to take all invocations in elaboration code into account. If an |
| invocation leads to a circularity, GNAT ignores the invocation based on the |
| assumptions stated above. An order obtained using the dynamic model may fail |
| an ABE check at run time when GNAT ignored an invocation. |
| |
| The dynamic model is enabled with compiler switch @code{-gnatE}. |
| @end itemize |
| |
| @geindex Static elaboration model |
| |
| |
| @itemize * |
| |
| @item |
| @emph{Static elaboration model} |
| |
| This is the middle ground of the three models. When the static model is in |
| effect, GNAT makes the following assumptions: |
| |
| |
| @itemize - |
| |
| @item |
| Only code at the library level and in package body statements within all |
| units in a partition is considered to be elaboration code. |
| |
| @item |
| All invocations in elaboration will take place at run time, regardless of |
| conditional execution. |
| @end itemize |
| |
| GNAT performs extensive diagnostics on a unit-by-unit basis for all scenarios |
| that invoke internal targets. In addition, GNAT generates run-time checks for |
| all external targets and for all scenarios that may exhibit ABE problems. |
| |
| The elaboration order is obtained by honoring all @emph{with} clauses, purity and |
| preelaborability of units, presence of elaboration-control pragmas, and all |
| invocations in elaboration code. An order obtained using the static model is |
| guaranteed to be ABE problem-free, excluding dispatching calls and |
| access-to-subprogram types. |
| |
| The static model is the default model in GNAT. |
| @end itemize |
| |
| @geindex SPARK elaboration model |
| |
| |
| @itemize * |
| |
| @item |
| @emph{SPARK elaboration model} |
| |
| This is the most conservative of the three models and enforces the SPARK |
| rules of elaboration as defined in the SPARK Reference Manual, section 7.7. |
| The SPARK model is in effect only when a scenario and a target reside in a |
| region subject to @code{SPARK_Mode On}, otherwise the dynamic or static model |
| is in effect. |
| |
| The SPARK model is enabled with compiler switch @code{-gnatd.v}. |
| @end itemize |
| |
| @geindex Legacy elaboration models |
| |
| |
| @itemize * |
| |
| @item |
| @emph{Legacy elaboration models} |
| |
| In addition to the three elaboration models outlined above, GNAT provides the |
| following legacy models: |
| |
| |
| @itemize - |
| |
| @item |
| @cite{Legacy elaboration-checking model} available in pre-18.x versions of GNAT. |
| This model is enabled with compiler switch @code{-gnatH}. |
| |
| @item |
| @cite{Legacy elaboration-order model} available in pre-20.x versions of GNAT. |
| This model is enabled with binder switch @code{-H}. |
| @end itemize |
| @end itemize |
| |
| @geindex Relaxed elaboration mode |
| |
| The dynamic, legacy, and static models can be relaxed using compiler switch |
| @code{-gnatJ}, making them more permissive. Note that in this mode, GNAT |
| may not diagnose certain elaboration issues or install run-time checks. |
| |
| @node Mixing Elaboration Models,ABE Diagnostics,Controlling the Elaboration Order in GNAT,Elaboration Order Handling in GNAT |
| @anchor{gnat_ugn/elaboration_order_handling_in_gnat id7}@anchor{220}@anchor{gnat_ugn/elaboration_order_handling_in_gnat mixing-elaboration-models}@anchor{221} |
| @section Mixing Elaboration Models |
| |
| |
| It is possible to mix units compiled with a different elaboration model, |
| however the following rules must be observed: |
| |
| |
| @itemize * |
| |
| @item |
| A client unit compiled with the dynamic model can only @emph{with} a server unit |
| that meets at least one of the following criteria: |
| |
| |
| @itemize - |
| |
| @item |
| The server unit is compiled with the dynamic model. |
| |
| @item |
| The server unit is a GNAT implementation unit from the @code{Ada}, @code{GNAT}, |
| @code{Interfaces}, or @code{System} hierarchies. |
| |
| @item |
| The server unit has pragma @code{Pure} or @code{Preelaborate}. |
| |
| @item |
| The client unit has an explicit @code{Elaborate_All} pragma for the server |
| unit. |
| @end itemize |
| @end itemize |
| |
| These rules ensure that elaboration checks are not omitted. If the rules are |
| violated, the binder emits a warning: |
| |
| @quotation |
| |
| @example |
| warning: "x.ads" has dynamic elaboration checks and with's |
| warning: "y.ads" which has static elaboration checks |
| @end example |
| @end quotation |
| |
| The warnings can be suppressed by binder switch @code{-ws}. |
| |
| @node ABE Diagnostics,SPARK Diagnostics,Mixing Elaboration Models,Elaboration Order Handling in GNAT |
| @anchor{gnat_ugn/elaboration_order_handling_in_gnat abe-diagnostics}@anchor{222}@anchor{gnat_ugn/elaboration_order_handling_in_gnat id8}@anchor{223} |
| @section ABE Diagnostics |
| |
| |
| GNAT performs extensive diagnostics on a unit-by-unit basis for all scenarios |
| that invoke internal targets, regardless of whether the dynamic, SPARK, or |
| static model is in effect. |
| |
| Note that GNAT emits warnings rather than hard errors whenever it encounters an |
| elaboration problem. This is because the elaboration model in effect may be too |
| conservative, or a particular scenario may not be invoked due conditional |
| execution. The warnings can be suppressed selectively with @code{pragma Warnings |
| (Off)} or globally with compiler switch @code{-gnatwL}. |
| |
| A @emph{guaranteed ABE} arises when the body of a target is not elaborated early |
| enough, and causes @emph{all} scenarios that directly invoke the target to fail. |
| |
| @quotation |
| |
| @example |
| package body Guaranteed_ABE is |
| function ABE return Integer; |
| |
| Val : constant Integer := ABE; |
| |
| function ABE return Integer is |
| begin |
| ... |
| end ABE; |
| end Guaranteed_ABE; |
| @end example |
| @end quotation |
| |
| In the example above, the elaboration of @code{Guaranteed_ABE}’s body elaborates |
| the declaration of @code{Val}. This invokes function @code{ABE}, however the body of |
| @code{ABE} has not been elaborated yet. GNAT emits the following diagnostic: |
| |
| @quotation |
| |
| @example |
| 4. Val : constant Integer := ABE; |
| | |
| >>> warning: cannot call "ABE" before body seen |
| >>> warning: Program_Error will be raised at run time |
| @end example |
| @end quotation |
| |
| A @emph{conditional ABE} arises when the body of a target is not elaborated early |
| enough, and causes @emph{some} scenarios that directly invoke the target to fail. |
| |
| @quotation |
| |
| @example |
| 1. package body Conditional_ABE is |
| 2. procedure Force_Body is null; |
| 3. |
| 4. generic |
| 5. with function Func return Integer; |
| 6. package Gen is |
| 7. Val : constant Integer := Func; |
| 8. end Gen; |
| 9. |
| 10. function ABE return Integer; |
| 11. |
| 12. function Cause_ABE return Boolean is |
| 13. package Inst is new Gen (ABE); |
| 14. begin |
| 15. ... |
| 16. end Cause_ABE; |
| 17. |
| 18. Val : constant Boolean := Cause_ABE; |
| 19. |
| 20. function ABE return Integer is |
| 21. begin |
| 22. ... |
| 23. end ABE; |
| 24. |
| 25. Safe : constant Boolean := Cause_ABE; |
| 26. end Conditional_ABE; |
| @end example |
| @end quotation |
| |
| In the example above, the elaboration of package body @code{Conditional_ABE} |
| elaborates the declaration of @code{Val}. This invokes function @code{Cause_ABE}, |
| which instantiates generic unit @code{Gen} as @code{Inst}. The elaboration of |
| @code{Inst} invokes function @code{ABE}, however the body of @code{ABE} has not been |
| elaborated yet. GNAT emits the following diagnostic: |
| |
| @quotation |
| |
| @example |
| 13. package Inst is new Gen (ABE); |
| | |
| >>> warning: in instantiation at line 7 |
| >>> warning: cannot call "ABE" before body seen |
| >>> warning: Program_Error may be raised at run time |
| >>> warning: body of unit "Conditional_ABE" elaborated |
| >>> warning: function "Cause_ABE" called at line 18 |
| >>> warning: function "ABE" called at line 7, instance at line 13 |
| @end example |
| @end quotation |
| |
| Note that the same ABE problem does not occur with the elaboration of |
| declaration @code{Safe} because the body of function @code{ABE} has already been |
| elaborated at that point. |
| |
| @node SPARK Diagnostics,Elaboration Circularities,ABE Diagnostics,Elaboration Order Handling in GNAT |
| @anchor{gnat_ugn/elaboration_order_handling_in_gnat id9}@anchor{224}@anchor{gnat_ugn/elaboration_order_handling_in_gnat spark-diagnostics}@anchor{225} |
| @section SPARK Diagnostics |
| |
| |
| GNAT enforces the SPARK rules of elaboration as defined in the SPARK Reference |
| Manual section 7.7 when compiler switch @code{-gnatd.v} is in effect. Note |
| that GNAT emits hard errors whenever it encounters a violation of the SPARK |
| rules. |
| |
| @quotation |
| |
| @example |
| 1. with Server; |
| 2. package body SPARK_Diagnostics with SPARK_Mode is |
| 3. Val : constant Integer := Server.Func; |
| | |
| >>> call to "Func" during elaboration in SPARK |
| >>> unit "SPARK_Diagnostics" requires pragma "Elaborate_All" for "Server" |
| >>> body of unit "SPARK_Model" elaborated |
| >>> function "Func" called at line 3 |
| |
| 4. end SPARK_Diagnostics; |
| @end example |
| @end quotation |
| |
| @node Elaboration Circularities,Resolving Elaboration Circularities,SPARK Diagnostics,Elaboration Order Handling in GNAT |
| @anchor{gnat_ugn/elaboration_order_handling_in_gnat elaboration-circularities}@anchor{226}@anchor{gnat_ugn/elaboration_order_handling_in_gnat id10}@anchor{227} |
| @section Elaboration Circularities |
| |
| |
| An @strong{elaboration circularity} occurs whenever the elaboration of a set of |
| units enters a deadlocked state, where each unit is waiting for another unit |
| to be elaborated. This situation may be the result of improper use of @emph{with} |
| clauses, elaboration-control pragmas, or invocations in elaboration code. |
| |
| The following example exhibits an elaboration circularity. |
| |
| @quotation |
| |
| @example |
| with B; pragma Elaborate (B); |
| package A is |
| end A; |
| @end example |
| |
| @example |
| package B is |
| procedure Force_Body; |
| end B; |
| @end example |
| |
| @example |
| with C; |
| package body B is |
| procedure Force_Body is null; |
| |
| Elab : constant Integer := C.Func; |
| end B; |
| @end example |
| |
| @example |
| package C is |
| function Func return Integer; |
| end C; |
| @end example |
| |
| @example |
| with A; |
| package body C is |
| function Func return Integer is |
| begin |
| ... |
| end Func; |
| end C; |
| @end example |
| @end quotation |
| |
| The binder emits the following diagnostic: |
| |
| @quotation |
| |
| @example |
| error: Elaboration circularity detected |
| info: |
| info: Reason: |
| info: |
| info: unit "a (spec)" depends on its own elaboration |
| info: |
| info: Circularity: |
| info: |
| info: unit "a (spec)" has with clause and pragma Elaborate for unit "b (spec)" |
| info: unit "b (body)" is in the closure of pragma Elaborate |
| info: unit "b (body)" invokes a construct of unit "c (body)" at elaboration time |
| info: unit "c (body)" has with clause for unit "a (spec)" |
| info: |
| info: Suggestions: |
| info: |
| info: remove pragma Elaborate for unit "b (body)" in unit "a (spec)" |
| info: use the dynamic elaboration model (compiler switch -gnatE) |
| @end example |
| @end quotation |
| |
| The diagnostic consist of the following sections: |
| |
| |
| @itemize * |
| |
| @item |
| Reason |
| |
| This section provides a short explanation describing why the set of units |
| could not be ordered. |
| |
| @item |
| Circularity |
| |
| This section enumerates the units comprising the deadlocked set, along with |
| their interdependencies. |
| |
| @item |
| Suggestions |
| |
| This section enumerates various tactics for eliminating the circularity. |
| @end itemize |
| |
| @node Resolving Elaboration Circularities,Elaboration-related Compiler Switches,Elaboration Circularities,Elaboration Order Handling in GNAT |
| @anchor{gnat_ugn/elaboration_order_handling_in_gnat id11}@anchor{228}@anchor{gnat_ugn/elaboration_order_handling_in_gnat resolving-elaboration-circularities}@anchor{229} |
| @section Resolving Elaboration Circularities |
| |
| |
| 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 invoked |
| 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. |
| |
| When faced with an elaboration circularity, the programmer should also consider |
| the tactics given in the suggestions section of the circularity diagnostic. |
| Depending on the units involved in the circularity, their @emph{with} clauses, |
| purity, preelaborability, presence of elaboration-control pragmas and |
| invocations at elaboration time, the binder may suggest one or more of the |
| following tactics to eliminate the circularity: |
| |
| |
| @itemize * |
| |
| @item |
| Pragma Elaborate elimination |
| |
| @example |
| remove pragma Elaborate for unit "..." in unit "..." |
| @end example |
| |
| This tactic is suggested when the binder has determined that pragma |
| @code{Elaborate}: |
| |
| |
| @itemize - |
| |
| @item |
| Prevents a set of units from being elaborated. |
| |
| @item |
| The removal of the pragma will not eliminate the semantic effects of the |
| pragma. In other words, the argument of the pragma will still be elaborated |
| prior to the unit containing the pragma. |
| |
| @item |
| The removal of the pragma will enable the successful ordering of the units. |
| @end itemize |
| |
| The programmer should remove the pragma as advised, and rebuild the program. |
| |
| @item |
| Pragma Elaborate_All elimination |
| |
| @example |
| remove pragma Elaborate_All for unit "..." in unit "..." |
| @end example |
| |
| This tactic is suggested when the binder has determined that pragma |
| @code{Elaborate_All}: |
| |
| |
| @itemize - |
| |
| @item |
| Prevents a set of units from being elaborated. |
| |
| @item |
| The removal of the pragma will not eliminate the semantic effects of the |
| pragma. In other words, the argument of the pragma along with its @emph{with} |
| closure will still be elaborated prior to the unit containing the pragma. |
| |
| @item |
| The removal of the pragma will enable the successful ordering of the units. |
| @end itemize |
| |
| The programmer should remove the pragma as advised, and rebuild the program. |
| |
| @item |
| Pragma Elaborate_All downgrade |
| |
| @example |
| change pragma Elaborate_All for unit "..." to Elaborate in unit "..." |
| @end example |
| |
| This tactic is always suggested with the pragma @code{Elaborate_All} elimination |
| tactic. It offers a different alernative of guaranteeing that the argument of |
| the pragma will still be elaborated prior to the unit containing the pragma. |
| |
| The programmer should update the pragma as advised, and rebuild the program. |
| |
| @item |
| Pragma Elaborate_Body elimination |
| |
| @example |
| remove pragma Elaborate_Body in unit "..." |
| @end example |
| |
| This tactic is suggested when the binder has determined that pragma |
| @code{Elaborate_Body}: |
| |
| |
| @itemize - |
| |
| @item |
| Prevents a set of units from being elaborated. |
| |
| @item |
| The removal of the pragma will enable the successful ordering of the units. |
| @end itemize |
| |
| Note that the binder cannot determine whether the pragma is required for |
| other purposes, such as guaranteeing the initialization of a variable |
| declared in the spec by elaboration code in the body. |
| |
| The programmer should remove the pragma as advised, and rebuild the program. |
| |
| @item |
| Use of pragma Restrictions |
| |
| @example |
| use pragma Restrictions (No_Entry_Calls_In_Elaboration_Code) |
| @end example |
| |
| This tactic is suggested when the binder has determined that a task |
| activation at elaboration time: |
| |
| |
| @itemize - |
| |
| @item |
| Prevents a set of units from being elaborated. |
| @end itemize |
| |
| Note that the binder cannot determine with certainty whether the task will |
| block at elaboration time. |
| |
| The programmer should create a configuration file, place the pragma within, |
| update the general compilation arguments, and rebuild the program. |
| |
| @item |
| Use of dynamic elaboration model |
| |
| @example |
| use the dynamic elaboration model (compiler switch -gnatE) |
| @end example |
| |
| This tactic is suggested when the binder has determined that an invocation at |
| elaboration time: |
| |
| |
| @itemize - |
| |
| @item |
| Prevents a set of units from being elaborated. |
| |
| @item |
| The use of the dynamic model will enable the successful ordering of the |
| units. |
| @end itemize |
| |
| The programmer has two options: |
| |
| |
| @itemize - |
| |
| @item |
| Determine the units involved in the invocation using the detailed |
| invocation information, and add compiler switch @code{-gnatE} to the |
| compilation arguments of selected files only. This approach will yield |
| safer elaboration orders compared to the other option because it will |
| minimize the opportunities presented to the dynamic model for ignoring |
| invocations. |
| |
| @item |
| Add compiler switch @code{-gnatE} to the general compilation arguments. |
| @end itemize |
| |
| @item |
| Use of detailed invocation information |
| |
| @example |
| use detailed invocation information (compiler switch -gnatd_F) |
| @end example |
| |
| This tactic is always suggested with the use of the dynamic model tactic. It |
| causes the circularity section of the circularity diagnostic to describe the |
| flow of elaboration code from a unit to a unit, enumerating all such paths in |
| the process. |
| |
| The programmer should analyze this information to determine which units |
| should be compiled with the dynamic model. |
| |
| @item |
| Forced-dependency elimination |
| |
| @example |
| remove the dependency of unit "..." on unit "..." from the argument of switch -f |
| @end example |
| |
| This tactic is suggested when the binder has determined that a dependency |
| present in the forced-elaboration-order file indicated by binder switch |
| @code{-f}: |
| |
| |
| @itemize - |
| |
| @item |
| Prevents a set of units from being elaborated. |
| |
| @item |
| The removal of the dependency will enable the successful ordering of the |
| units. |
| @end itemize |
| |
| The programmer should edit the forced-elaboration-order file, remove the |
| dependency, and rebind the program. |
| |
| @item |
| All forced-dependency elimination |
| |
| @example |
| remove switch -f |
| @end example |
| |
| This tactic is suggested in case editing the forced-elaboration-order file is |
| not an option. |
| |
| The programmer should remove binder switch @code{-f} from the binder |
| arguments, and rebind. |
| |
| @item |
| Multiple-circularities diagnostic |
| |
| @example |
| diagnose all circularities (binder switch -d_C) |
| @end example |
| |
| By default, the binder will diagnose only the highest-precedence circularity. |
| If the program contains multiple circularities, the binder will suggest the |
| use of binder switch @code{-d_C} in order to obtain the diagnostics of all |
| circularities. |
| |
| The programmer should add binder switch @code{-d_C} to the binder |
| arguments, and rebind. |
| @end itemize |
| |
| If none of the tactics suggested by the binder eliminate the elaboration |
| circularity, the programmer should consider using one of the legacy elaboration |
| models, in the following order: |
| |
| |
| @itemize * |
| |
| @item |
| Use the pre-20.x legacy elaboration-order model, with binder switch |
| @code{-H}. |
| |
| @item |
| Use both pre-18.x and pre-20.x legacy elaboration models, with compiler |
| switch @code{-gnatH} and binder switch @code{-H}. |
| |
| @item |
| Use the relaxed static-elaboration model, with compiler switches |
| @code{-gnatH} @code{-gnatJ} and binder switch @code{-H}. |
| |
| @item |
| Use the relaxed dynamic-elaboration model, with compiler switches |
| @code{-gnatH} @code{-gnatJ} @code{-gnatE} and binder switch |
| @code{-H}. |
| @end itemize |
| |
| @node Elaboration-related Compiler Switches,Summary of Procedures for Elaboration Control,Resolving Elaboration Circularities,Elaboration Order Handling in GNAT |
| @anchor{gnat_ugn/elaboration_order_handling_in_gnat elaboration-related-compiler-switches}@anchor{22a}@anchor{gnat_ugn/elaboration_order_handling_in_gnat id12}@anchor{22b} |
| @section Elaboration-related Compiler Switches |
| |
| |
| GNAT has several switches that affect the elaboration model and consequently |
| the elaboration order chosen by the binder. |
| |
| @geindex -gnatE (gnat) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatE} |
| |
| Dynamic elaboration checking mode enabled |
| |
| When this switch is in effect, GNAT activates the dynamic model. |
| @end table |
| |
| @geindex -gnatel (gnat) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatel} |
| |
| Turn on info messages on generated Elaborate[_All] pragmas |
| |
| This switch is only applicable to the pre-20.x legacy elaboration models. |
| The post-20.x elaboration model no longer relies on implicitly generated |
| @code{Elaborate} and @code{Elaborate_All} pragmas to order units. |
| |
| When this switch is in effect, GNAT will emit the following supplementary |
| information depending on the elaboration model in effect. |
| |
| |
| @itemize - |
| |
| @item |
| @emph{Dynamic model} |
| |
| GNAT will indicate missing @code{Elaborate} and @code{Elaborate_All} pragmas for |
| all library-level scenarios within the partition. |
| |
| @item |
| @emph{Static model} |
| |
| GNAT will indicate all scenarios invoked during elaboration. In addition, |
| it will provide detailed traceback when an implicit @code{Elaborate} or |
| @code{Elaborate_All} pragma is generated. |
| |
| @item |
| @emph{SPARK model} |
| |
| GNAT will indicate how an elaboration requirement is met by the context of |
| a unit. This diagnostic requires compiler switch @code{-gnatd.v}. |
| |
| @example |
| 1. with Server; pragma Elaborate_All (Server); |
| 2. package Client with SPARK_Mode is |
| 3. Val : constant Integer := Server.Func; |
| | |
| >>> info: call to "Func" during elaboration in SPARK |
| >>> info: "Elaborate_All" requirement for unit "Server" met by pragma at line 1 |
| |
| 4. end Client; |
| @end example |
| @end itemize |
| @end table |
| |
| @geindex -gnatH (gnat) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatH} |
| |
| Legacy elaboration checking mode enabled |
| |
| When this switch is in effect, GNAT will utilize the pre-18.x elaboration |
| model. |
| @end table |
| |
| @geindex -gnatJ (gnat) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatJ} |
| |
| Relaxed elaboration checking mode enabled |
| |
| When this switch is in effect, GNAT will not process certain scenarios, |
| resulting in a more permissive elaboration model. Note that this may |
| eliminate some diagnostics and run-time checks. |
| @end table |
| |
| @geindex -gnatw.f (gnat) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatw.f} |
| |
| Turn on warnings for suspicious Subp’Access |
| |
| When this switch is in effect, GNAT will treat @code{'Access} of an entry, |
| operator, or subprogram as a potential call to the target and issue warnings: |
| |
| @example |
| 1. package body Attribute_Call is |
| 2. function Func return Integer; |
| 3. type Func_Ptr is access function return Integer; |
| 4. |
| 5. Ptr : constant Func_Ptr := Func'Access; |
| | |
| >>> warning: "Access" attribute of "Func" before body seen |
| >>> warning: possible Program_Error on later references |
| >>> warning: body of unit "Attribute_Call" elaborated |
| >>> warning: "Access" of "Func" taken at line 5 |
| |
| 6. |
| 7. function Func return Integer is |
| 8. begin |
| 9. ... |
| 10. end Func; |
| 11. end Attribute_Call; |
| @end example |
| |
| In the example above, the elaboration of declaration @code{Ptr} is assigned |
| @code{Func'Access} before the body of @code{Func} has been elaborated. |
| @end table |
| |
| @geindex -gnatwl (gnat) |
| |
| |
| @table @asis |
| |
| @item @code{-gnatwl} |
| |
| Turn on warnings for elaboration problems |
| |
| When this switch is in effect, GNAT emits diagnostics in the form of warnings |
| concerning various elaboration problems. The warnings are enabled by default. |
| The switch is provided in case all warnings are suppressed, but elaboration |
| warnings are still desired. |
| |
| @item @code{-gnatwL} |
| |
| Turn off warnings for elaboration problems |
| |
| When this switch is in effect, GNAT no longer emits any diagnostics in the |
| form of warnings. Selective suppression of elaboration problems is possible |
| using @code{pragma Warnings (Off)}. |
| |
| @example |
| 1. package body Selective_Suppression is |
| 2. function ABE return Integer; |
| 3. |
| 4. Val_1 : constant Integer := ABE; |
| | |
| >>> warning: cannot call "ABE" before body seen |
| >>> warning: Program_Error will be raised at run time |
| |
| 5. |
| 6. pragma Warnings (Off); |
| 7. Val_2 : constant Integer := ABE; |
| 8. pragma Warnings (On); |
| 9. |
| 10. function ABE return Integer is |
| 11. begin |
| 12. ... |
| 13. end ABE; |
| 14. end Selective_Suppression; |
| @end example |
| |
| Note that suppressing elaboration warnings does not eliminate run-time |
| checks. The example above will still fail at run time with an ABE. |
| @end table |
| |
| @node Summary of Procedures for Elaboration Control,Inspecting the Chosen Elaboration Order,Elaboration-related Compiler Switches,Elaboration Order Handling in GNAT |
| @anchor{gnat_ugn/elaboration_order_handling_in_gnat id13}@anchor{22c}@anchor{gnat_ugn/elaboration_order_handling_in_gnat summary-of-procedures-for-elaboration-control}@anchor{22d} |
| @section Summary of Procedures for Elaboration Control |
| |
| |
| A programmer should first compile the program with the default options, using |
| none of the binder or compiler switches. If the binder succeeds in finding an |
| elaboration order, then apart from possible cases involing dispatching calls |
| and access-to-subprogram types, the program is free of elaboration errors. |
| |
| If it is important for the program to be portable to compilers other than GNAT, |
| then the programmer should use compiler switch @code{-gnatel} and consider |
| the messages about missing or implicitly created @code{Elaborate} and |
| @code{Elaborate_All} pragmas. |
| |
| If the binder reports an elaboration circularity, the programmer has several |
| options: |
| |
| |
| @itemize * |
| |
| @item |
| Ensure that elaboration warnings are enabled. This will allow the static |
| model to output trace information of elaboration issues. The trace |
| information could shed light on previously unforeseen dependencies, as well |
| as their origins. Elaboration warnings are enabled with compiler switch |
| @code{-gnatwl}. |
| |
| @item |
| Cosider the tactics given in the suggestions section of the circularity |
| diagnostic. |
| |
| @item |
| If none of the steps outlined above resolve the circularity, use a more |
| permissive elaboration model, in the following order: |
| |
| |
| @itemize - |
| |
| @item |
| Use the pre-20.x legacy elaboration-order model, with binder switch |
| @code{-H}. |
| |
| @item |
| Use both pre-18.x and pre-20.x legacy elaboration models, with compiler |
| switch @code{-gnatH} and binder switch @code{-H}. |
| |
| @item |
| Use the relaxed static elaboration model, with compiler switches |
| @code{-gnatH} @code{-gnatJ} and binder switch @code{-H}. |
| |
| @item |
| Use the relaxed dynamic elaboration model, with compiler switches |
| @code{-gnatH} @code{-gnatJ} @code{-gnatE} and binder switch |
| @code{-H}. |
| @end itemize |
| @end itemize |
| |
| @node Inspecting the Chosen Elaboration Order,,Summary of Procedures for Elaboration Control,Elaboration Order Handling in GNAT |
| @anchor{gnat_ugn/elaboration_order_handling_in_gnat id14}@anchor{22e}@anchor{gnat_ugn/elaboration_order_handling_in_gnat inspecting-the-chosen-elaboration-order}@anchor{22f} |
| @section Inspecting the Chosen Elaboration Order |
| |
| |
| To see the elaboration order chosen by the binder, inspect the contents of file |
| @cite{b~xxx.adb}. On certain targets, this file appears as @cite{b_xxx.adb}. The |
| elaboration order appears as a sequence of calls to @code{Elab_Body} and |
| @code{Elab_Spec}, interspersed with assignments to @cite{Exxx} which indicates that a |
| particular unit is elaborated. For example: |
| |
| @quotation |
| |
| @example |
| System.Soft_Links'Elab_Body; |
| E14 := True; |
| System.Secondary_Stack'Elab_Body; |
| E18 := True; |
| System.Exception_Table'Elab_Body; |
| E24 := True; |
| Ada.Io_Exceptions'Elab_Spec; |
| E67 := True; |
| Ada.Tags'Elab_Spec; |
| Ada.Streams'Elab_Spec; |
| E43 := True; |
| Interfaces.C'Elab_Spec; |
| E69 := True; |
| System.Finalization_Root'Elab_Spec; |
| E60 := True; |
| System.Os_Lib'Elab_Body; |
| E71 := True; |
| System.Finalization_Implementation'Elab_Spec; |
| System.Finalization_Implementation'Elab_Body; |
| E62 := True; |
| Ada.Finalization'Elab_Spec; |
| E58 := True; |
| Ada.Finalization.List_Controller'Elab_Spec; |
| E76 := True; |
| System.File_Control_Block'Elab_Spec; |
| E74 := True; |
| System.File_Io'Elab_Body; |
| E56 := True; |
| Ada.Tags'Elab_Body; |
| E45 := True; |
| Ada.Text_Io'Elab_Spec; |
| Ada.Text_Io'Elab_Body; |
| E07 := True; |
| @end example |
| @end quotation |
| |
| Note also binder switch @code{-l}, which outputs the chosen elaboration |
| order and provides a more readable form of the above: |
| |
| @quotation |
| |
| @example |
| ada (spec) |
| interfaces (spec) |
| system (spec) |
| system.case_util (spec) |
| system.case_util (body) |
| system.concat_2 (spec) |
| system.concat_2 (body) |
| system.concat_3 (spec) |
| system.concat_3 (body) |
| system.htable (spec) |
| system.parameters (spec) |
| system.parameters (body) |
| system.crtl (spec) |
| interfaces.c_streams (spec) |
| interfaces.c_streams (body) |
| system.restrictions (spec) |
| system.restrictions (body) |
| system.standard_library (spec) |
| system.exceptions (spec) |
| system.exceptions (body) |
| system.storage_elements (spec) |
| system.storage_elements (body) |
| system.secondary_stack (spec) |
| system.stack_checking (spec) |
| system.stack_checking (body) |
| system.string_hash (spec) |
| system.string_hash (body) |
| system.htable (body) |
| system.strings (spec) |
| system.strings (body) |
| system.traceback (spec) |
| system.traceback (body) |
| system.traceback_entries (spec) |
| system.traceback_entries (body) |
| ada.exceptions (spec) |
| ada.exceptions.last_chance_handler (spec) |
| system.soft_links (spec) |
| system.soft_links (body) |
| ada.exceptions.last_chance_handler (body) |
| system.secondary_stack (body) |
| system.exception_table (spec) |
| system.exception_table (body) |
| ada.io_exceptions (spec) |
| ada.tags (spec) |
| ada.streams (spec) |
| interfaces.c (spec) |
| interfaces.c (body) |
| system.finalization_root (spec) |
| system.finalization_root (body) |
| system.memory (spec) |
| system.memory (body) |
| system.standard_library (body) |
| system.os_lib (spec) |
| system.os_lib (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) |
| system.val_uns (spec) |
| system.val_util (spec) |
| system.val_util (body) |
| system.val_uns (body) |
| system.wch_con (spec) |
| system.wch_con (body) |
| system.wch_cnv (spec) |
| system.wch_jis (spec) |
| system.wch_jis (body) |
| system.wch_cnv (body) |
| system.wch_stw (spec) |
| system.wch_stw (body) |
| ada.tags (body) |
| ada.exceptions (body) |
| ada.text_io (spec) |
| ada.text_io (body) |
| text_io (spec) |
| gdbstr (body) |
| @end example |
| @end quotation |
| |
| @node Inline Assembler,GNU Free Documentation License,Elaboration Order Handling in GNAT,Top |
| @anchor{gnat_ugn/inline_assembler doc}@anchor{230}@anchor{gnat_ugn/inline_assembler id1}@anchor{231}@anchor{gnat_ugn/inline_assembler inline-assembler}@anchor{10} |
| @chapter Inline Assembler |
| |
| |
| @geindex Inline Assembler |
| |
| 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 * |
| |
| @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 appendix 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 |
| |
| @node Basic Assembler Syntax,A Simple Example of Inline Assembler,,Inline Assembler |
| @anchor{gnat_ugn/inline_assembler basic-assembler-syntax}@anchor{232}@anchor{gnat_ugn/inline_assembler id2}@anchor{233} |
| @section Basic Assembler Syntax |
| |
| |
| 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 @code{as} (and which is often referred to as ‘AT&T syntax’). |
| The following table summarizes the main features of @code{as} syntax |
| and points out the differences from the Intel conventions. |
| See the gcc @code{as} and @code{gas} (an @code{as} macro |
| pre-processor) documentation for further information. |
| |
| |
| @display |
| @emph{Register names}@w{ } |
| @display |
| gcc / @code{as}: Prefix with ‘%’; for example @code{%eax}@w{ } |
| Intel: No extra punctuation; for example @code{eax}@w{ } |
| @end display |
| @end display |
| |
| |
| |
| |
| @display |
| @emph{Immediate operand}@w{ } |
| @display |
| gcc / @code{as}: Prefix with ‘$’; for example @code{$4}@w{ } |
| Intel: No extra punctuation; for example @code{4}@w{ } |
| @end display |
| @end display |
| |
| |
| |
| |
| @display |
| @emph{Address}@w{ } |
| @display |
| gcc / @code{as}: Prefix with ‘$’; for example @code{$loc}@w{ } |
| Intel: No extra punctuation; for example @code{loc}@w{ } |
| @end display |
| @end display |
| |
| |
| |
| |
| @display |
| @emph{Memory contents}@w{ } |
| @display |
| gcc / @code{as}: No extra punctuation; for example @code{loc}@w{ } |
| Intel: Square brackets; for example @code{[loc]}@w{ } |
| @end display |
| @end display |
| |
| |
| |
| |
| @display |
| @emph{Register contents}@w{ } |
| @display |
| gcc / @code{as}: Parentheses; for example @code{(%eax)}@w{ } |
| Intel: Square brackets; for example @code{[eax]}@w{ } |
| @end display |
| @end display |
| |
| |
| |
| |
| @display |
| @emph{Hexadecimal numbers}@w{ } |
| @display |
| gcc / @code{as}: Leading ‘0x’ (C language syntax); for example @code{0xA0}@w{ } |
| Intel: Trailing ‘h’; for example @code{A0h}@w{ } |
| @end display |
| @end display |
| |
| |
| |
| |
| @display |
| @emph{Operand size}@w{ } |
| @display |
| gcc / @code{as}: Explicit in op code; for example @code{movw} to move a 16-bit word@w{ } |
| Intel: Implicit, deduced by assembler; for example @code{mov}@w{ } |
| @end display |
| @end display |
| |
| |
| |
| |
| @display |
| @emph{Instruction repetition}@w{ } |
| @display |
| gcc / @code{as}: Split into two lines; for example@w{ } |
| @display |
| @code{rep}@w{ } |
| @code{stosl}@w{ } |
| @end display |
| Intel: Keep on one line; for example @code{rep stosl}@w{ } |
| @end display |
| @end display |
| |
| |
| |
| |
| @display |
| @emph{Order of operands}@w{ } |
| @display |
| gcc / @code{as}: Source first; for example @code{movw $4, %eax}@w{ } |
| Intel: Destination first; for example @code{mov eax, 4}@w{ } |
| @end display |
| @end display |
| |
| |
| |
| @node A Simple Example of Inline Assembler,Output Variables in Inline Assembler,Basic Assembler Syntax,Inline Assembler |
| @anchor{gnat_ugn/inline_assembler a-simple-example-of-inline-assembler}@anchor{234}@anchor{gnat_ugn/inline_assembler id3}@anchor{235} |
| @section A Simple Example of Inline Assembler |
| |
| |
| 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. |
| |
| @quotation |
| |
| @example |
| with System.Machine_Code; use System.Machine_Code; |
| procedure Nothing is |
| begin |
| Asm ("nop"); |
| end Nothing; |
| @end example |
| @end quotation |
| |
| @code{Asm} is a procedure declared in package @code{System.Machine_Code}; |
| here it takes one parameter, a @emph{template string} that must be a static |
| expression and that will form the generated instruction. |
| @code{Asm} may be regarded as a compile-time procedure that parses |
| the template string and additional parameters (none here), |
| from which it generates a sequence of assembly language instructions. |
| |
| The examples in this chapter will illustrate several of the forms |
| for invoking @code{Asm}; a complete specification of the syntax |
| is found in the @code{Machine_Code_Insertions} section of the |
| @cite{GNAT Reference Manual}. |
| |
| Under the standard GNAT conventions, the @code{Nothing} procedure |
| should be in a file named @code{nothing.adb}. |
| You can build the executable in the usual way: |
| |
| @quotation |
| |
| @example |
| $ gnatmake nothing |
| @end example |
| @end quotation |
| |
| 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: |
| |
| @quotation |
| |
| @example |
| $ gcc -c -S -fomit-frame-pointer -gnatp nothing.adb |
| @end example |
| @end quotation |
| |
| where the options are: |
| |
| |
| @itemize * |
| |
| @item |
| |
| @table @asis |
| |
| @item @code{-c} |
| |
| compile only (no bind or link) |
| @end table |
| |
| @item |
| |
| @table @asis |
| |
| @item @code{-S} |
| |
| generate assembler listing |
| @end table |
| |
| @item |
| |
| @table @asis |
| |
| @item @code{-fomit-frame-pointer} |
| |
| do not set up separate stack frames |
| @end table |
| |
| @item |
| |
| @table @asis |
| |
| @item @code{-gnatp} |
| |
| do not add runtime checks |
| @end table |
| @end itemize |
| |
| 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 @code{nothing.s} has the following |
| contents: |
| |
| @quotation |
| |
| @example |
| .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 example |
| @end quotation |
| |
| 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 |
| @code{as} assembler that comes with gcc. |
| |
| Assembling the file using the command |
| |
| @quotation |
| |
| @example |
| $ as nothing.s |
| @end example |
| @end quotation |
| |
| 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, @code{as} will generate an object file |
| @code{nothing.out}. |
| |
| @node Output Variables in Inline Assembler,Input Variables in Inline Assembler,A Simple Example of Inline Assembler,Inline Assembler |
| @anchor{gnat_ugn/inline_assembler id4}@anchor{236}@anchor{gnat_ugn/inline_assembler output-variables-in-inline-assembler}@anchor{237} |
| @section Output Variables in Inline Assembler |
| |
| |
| The examples in this section, showing how to access the processor flags, |
| illustrate how to specify the destination operands for assembly language |
| statements. |
| |
| @quotation |
| |
| @example |
| 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 example |
| @end quotation |
| |
| 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: |
| |
| @quotation |
| |
| @example |
| #APP |
| pushfl |
| popl %eax |
| movl %eax, -40(%ebp) |
| #NO_APP |
| @end example |
| @end quotation |
| |
| It would have been legal to write the Asm invocation as: |
| |
| @quotation |
| |
| @example |
| Asm ("pushfl popl %%eax movl %%eax, %0") |
| @end example |
| @end quotation |
| |
| but in the generated assembler file, this would come out as: |
| |
| @quotation |
| |
| @example |
| #APP |
| pushfl popl %eax movl %eax, -40(%ebp) |
| #NO_APP |
| @end example |
| @end quotation |
| |
| 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: |
| |
| @quotation |
| |
| @example |
| movl %%eax, %0 |
| @end example |
| @end quotation |
| |
| 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}: |
| |
| @quotation |
| |
| @example |
| Outputs => Unsigned_32'Asm_Output ("=g", Flags)); |
| @end example |
| @end quotation |
| |
| The output is defined by the @code{Asm_Output} attribute of the target type; |
| the general format is |
| |
| @quotation |
| |
| @example |
| Type'Asm_Output (constraint_string, variable_name) |
| @end example |
| @end quotation |
| |
| The constraint string directs the compiler how |
| to store/access the associated variable. In the example |
| |
| @quotation |
| |
| @example |
| Unsigned_32'Asm_Output ("=m", Flags); |
| @end example |
| @end quotation |
| |
| 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, |
| |
| @quotation |
| |
| @example |
| Unsigned_32'Asm_Output ("=r", Flags); |
| @end example |
| @end quotation |
| |
| 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 ‘=’, 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: |
| |
| @quotation |
| |
| |
| @multitable {xxxxxxxx} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx} |
| @item |
| |
| @emph{=} |
| |
| @tab |
| |
| output constraint |
| |
| @item |
| |
| @emph{g} |
| |
| @tab |
| |
| global (i.e., can be stored anywhere) |
| |
| @item |
| |
| @emph{m} |
| |
| @tab |
| |
| in memory |
| |
| @item |
| |
| @emph{I} |
| |
| @tab |
| |
| a constant |
| |
| @item |
| |
| @emph{a} |
| |
| @tab |
| |
| use eax |
| |
| @item |
| |
| @emph{b} |
| |
| @tab |
| |
| use ebx |
| |
| @item |
| |
| @emph{c} |
| |
| @tab |
| |
| use ecx |
| |
| @item |
| |
| @emph{d} |
| |
| @tab |
| |
| use edx |
| |
| @item |
| |
| @emph{S} |
| |
| @tab |
| |
| use esi |
| |
| @item |
| |
| @emph{D} |
| |
| @tab |
| |
| use edi |
| |
| @item |
| |
| @emph{r} |
| |
| @tab |
| |
| use one of eax, ebx, ecx or edx |
| |
| @item |
| |
| @emph{q} |
| |
| @tab |
| |
| use one of eax, ebx, ecx, edx, esi or edi |
| |
| @end multitable |
| |
| @end quotation |
| |
| The full set of constraints is described in the gcc and @code{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 |
| |
| @quotation |
| |
| @example |
| 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 example |
| @end quotation |
| |
| @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 * |
| |
| @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: |
| |
| @quotation |
| |
| @example |
| 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 example |
| @end quotation |
| |
| 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: |
| |
| @quotation |
| |
| @example |
| 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 example |
| @end quotation |
| |
| The @code{"a"} constraint tells the compiler that the @code{Flags} |
| variable will come from the eax register. Here is the resulting code: |
| |
| @quotation |
| |
| @example |
| #APP |
| pushfl |
| popl %eax |
| #NO_APP |
| movl %eax,-40(%ebp) |
| @end example |
| @end quotation |
| |
| 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: |
| |
| @quotation |
| |
| @example |
| 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 example |
| @end quotation |
| |
| @node Input Variables in Inline Assembler,Inlining Inline Assembler Code,Output Variables in Inline Assembler,Inline Assembler |
| @anchor{gnat_ugn/inline_assembler id5}@anchor{238}@anchor{gnat_ugn/inline_assembler input-variables-in-inline-assembler}@anchor{239} |
| @section Input Variables in Inline Assembler |
| |
| |
| 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: |
| |
| @quotation |
| |
| @example |
| 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 example |
| @end quotation |
| |
| 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: |
| |
| |
| @itemize * |
| |
| @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 itemize |
| |
| The resulting assembler file (with @code{-O2} optimization) contains: |
| |
| @quotation |
| |
| @example |
| _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 example |
| @end quotation |
| |
| @node Inlining Inline Assembler Code,Other Asm Functionality,Input Variables in Inline Assembler,Inline Assembler |
| @anchor{gnat_ugn/inline_assembler id6}@anchor{23a}@anchor{gnat_ugn/inline_assembler inlining-inline-assembler-code}@anchor{23b} |
| @section Inlining Inline Assembler Code |
| |
| |
| 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: |
| |
| @quotation |
| |
| @example |
| 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 example |
| @end quotation |
| |
| Compile the program with both optimization (@code{-O2}) and inlining |
| (@code{-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: |
| |
| @quotation |
| |
| @example |
| pushl %edi |
| call _increment__incr.1 |
| @end example |
| @end quotation |
| |
| the code for the function body directly appears: |
| |
| @quotation |
| |
| @example |
| movl %esi,%eax |
| #APP |
| incl %eax |
| #NO_APP |
| movl %eax,%edx |
| @end example |
| @end quotation |
| |
| thus saving the overhead of stack frame setup and an out-of-line call. |
| |
| @node Other Asm Functionality,,Inlining Inline Assembler Code,Inline Assembler |
| @anchor{gnat_ugn/inline_assembler id7}@anchor{23c}@anchor{gnat_ugn/inline_assembler other-asm-functionality}@anchor{23d} |
| @section Other @code{Asm} Functionality |
| |
| |
| 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 |
| |
| @node The Clobber Parameter,The Volatile Parameter,,Other Asm Functionality |
| @anchor{gnat_ugn/inline_assembler id8}@anchor{23e}@anchor{gnat_ugn/inline_assembler the-clobber-parameter}@anchor{23f} |
| @subsection The @code{Clobber} Parameter |
| |
| |
| 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: |
| |
| @quotation |
| |
| @example |
| 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 example |
| @end quotation |
| |
| 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: |
| |
| @quotation |
| |
| @example |
| 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 example |
| @end quotation |
| |
| 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: |
| |
| |
| @itemize * |
| |
| @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 itemize |
| |
| @node The Volatile Parameter,,The Clobber Parameter,Other Asm Functionality |
| @anchor{gnat_ugn/inline_assembler id9}@anchor{240}@anchor{gnat_ugn/inline_assembler the-volatile-parameter}@anchor{241} |
| @subsection The @code{Volatile} Parameter |
| |
| |
| @geindex Volatile parameter |
| |
| 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: |
| |
| @quotation |
| |
| @example |
| 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 example |
| @end quotation |
| |
| 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. |
| |
| @node GNU Free Documentation License,Index,Inline Assembler,Top |
| @anchor{share/gnu_free_documentation_license doc}@anchor{242}@anchor{share/gnu_free_documentation_license gnu-fdl}@anchor{1}@anchor{share/gnu_free_documentation_license gnu-free-documentation-license}@anchor{243} |
| @chapter GNU Free Documentation License |
| |
| |
| Version 1.3, 3 November 2008 |
| |
| Copyright 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc |
| @indicateurl{http://fsf.org/} |
| |
| Everyone is permitted to copy and distribute verbatim copies of this |
| license document, but changing it is not allowed. |
| |
| @strong{Preamble} |
| |
| The purpose of this License is to make a manual, textbook, or other |
| functional and useful document “free” in the sense of freedom: to |
| assure everyone the effective freedom to copy and redistribute it, |
| with or without modifying it, either commercially or noncommercially. |
| Secondarily, this License preserves for the author and publisher a way |
| to get credit for their work, while not being considered responsible |
| for modifications made by others. |
| |
| This License is a kind of “copyleft”, which means that derivative |
| works of the document must themselves be free in the same sense. It |
| complements the GNU General Public License, which is a copyleft |
| license designed for free software. |
| |
| We have designed this License in order to use it for manuals for free |
| software, because free software needs free documentation: a free |
| program should come with manuals providing the same freedoms that the |
| software does. But this License is not limited to software manuals; |
| it can be used for any textual work, regardless of subject matter or |
| whether it is published as a printed book. We recommend this License |
| principally for works whose purpose is instruction or reference. |
| |
| @strong{1. APPLICABILITY AND DEFINITIONS} |
| |
| This License applies to any manual or other work, in any medium, that |
| contains a notice placed by the copyright holder saying it can be |
| distributed under the terms of this License. Such a notice grants a |
| world-wide, royalty-free license, unlimited in duration, to use that |
| work under the conditions stated herein. The @strong{Document}, below, |
| refers to any such manual or work. Any member of the public is a |
| licensee, and is addressed as “@strong{you}”. You accept the license if you |
| copy, modify or distribute the work in a way requiring permission |
| under copyright law. |
| |
| A “@strong{Modified Version}” of the Document means any work containing the |
| Document or a portion of it, either copied verbatim, or with |
| modifications and/or translated into another language. |
| |
| A “@strong{Secondary Section}” is a named appendix or a front-matter section of |
| the Document that deals exclusively with the relationship of the |
| publishers or authors of the Document to the Document’s overall subject |
| (or to related matters) and contains nothing that could fall directly |
| within that overall subject. (Thus, if the Document is in part a |
| textbook of mathematics, a Secondary Section may not explain any |
| mathematics.) The relationship could be a matter of historical |
| connection with the subject or with related matters, or of legal, |
| commercial, philosophical, ethical or political position regarding |
| them. |
| |
| The “@strong{Invariant Sections}” are certain Secondary Sections whose titles |
| are designated, as being those of Invariant Sections, in the notice |
| that says that the Document is released under this License. If a |
| section does not fit the above definition of Secondary then it is not |
| allowed to be designated as Invariant. The Document may contain zero |
| Invariant Sections. If the Document does not identify any Invariant |
| Sections then there are none. |
| |
| The “@strong{Cover Texts}” are certain short passages of text that are listed, |
| as Front-Cover Texts or Back-Cover Texts, in the notice that says that |
| the Document is released under this License. A Front-Cover Text may |
| be at most 5 words, and a Back-Cover Text may be at most 25 words. |
| |
| A “@strong{Transparent}” copy of the Document means a machine-readable copy, |
| represented in a format whose specification is available to the |
| general public, that is suitable for revising the document |
| straightforwardly with generic text editors or (for images composed of |
| pixels) generic paint programs or (for drawings) some widely available |
| drawing editor, and that is suitable for input to text formatters or |
| for automatic translation to a variety of formats suitable for input |
| to text formatters. A copy made in an otherwise Transparent file |
| format whose markup, or absence of markup, has been arranged to thwart |
| or discourage subsequent modification by readers is not Transparent. |
| An image format is not Transparent if used for any substantial amount |
| of text. A copy that is not “Transparent” is called @strong{Opaque}. |
| |
| Examples of suitable formats for Transparent copies include plain |
| ASCII without markup, Texinfo input format, LaTeX input format, SGML |
| or XML using a publicly available DTD, and standard-conforming simple |
| HTML, PostScript or PDF designed for human modification. Examples of |
| transparent image formats include PNG, XCF and JPG. Opaque formats |
| include proprietary formats that can be read and edited only by |
| proprietary word processors, SGML or XML for which the DTD and/or |
| processing tools are not generally available, and the |
| machine-generated HTML, PostScript or PDF produced by some word |
| processors for output purposes only. |
| |
| The “@strong{Title Page}” means, for a printed book, the title page itself, |
| plus such following pages as are needed to hold, legibly, the material |
| this License requires to appear in the title page. For works in |
| formats which do not have any title page as such, “Title Page” means |
| the text near the most prominent appearance of the work’s title, |
| preceding the beginning of the body of the text. |
| |
| The “@strong{publisher}” means any person or entity that distributes |
| copies of the Document to the public. |
| |
| A section “@strong{Entitled XYZ}” means a named subunit of the Document whose |
| title either is precisely XYZ or contains XYZ in parentheses following |
| text that translates XYZ in another language. (Here XYZ stands for a |
| specific section name mentioned below, such as “@strong{Acknowledgements}”, |
| “@strong{Dedications}”, “@strong{Endorsements}”, or “@strong{History}”.) |
| To “@strong{Preserve the Title}” |
| of such a section when you modify the Document means that it remains a |
| section “Entitled XYZ” according to this definition. |
| |
| The Document may include Warranty Disclaimers next to the notice which |
| states that this License applies to the Document. These Warranty |
| Disclaimers are considered to be included by reference in this |
| License, but only as regards disclaiming warranties: any other |
| implication that these Warranty Disclaimers may have is void and has |
| no effect on the meaning of this License. |
| |
| @strong{2. VERBATIM COPYING} |
| |
| You may copy and distribute the Document in any medium, either |
| commercially or noncommercially, provided that this License, the |
| copyright notices, and the license notice saying this License applies |
| to the Document are reproduced in all copies, and that you add no other |
| conditions whatsoever to those of this License. You may not use |
| technical measures to obstruct or control the reading or further |
| copying of the copies you make or distribute. However, you may accept |
| compensation in exchange for copies. If you distribute a large enough |
| number of copies you must also follow the conditions in section 3. |
| |
| You may also lend copies, under the same conditions stated above, and |
| you may publicly display copies. |
| |
| @strong{3. COPYING IN QUANTITY} |
| |
| If you publish printed copies (or copies in media that commonly have |
| printed covers) of the Document, numbering more than 100, and the |
| Document’s license notice requires Cover Texts, you must enclose the |
| copies in covers that carry, clearly and legibly, all these Cover |
| Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on |
| the back cover. Both covers must also clearly and legibly identify |
| you as the publisher of these copies. The front cover must present |
| the full title with all words of the title equally prominent and |
| visible. You may add other material on the covers in addition. |
| Copying with changes limited to the covers, as long as they preserve |
| the title of the Document and satisfy these conditions, can be treated |
| as verbatim copying in other respects. |
| |
| If the required texts for either cover are too voluminous to fit |
| legibly, you should put the first ones listed (as many as fit |
| reasonably) on the actual cover, and continue the rest onto adjacent |
| pages. |
| |
| If you publish or distribute Opaque copies of the Document numbering |
| more than 100, you must either include a machine-readable Transparent |
| copy along with each Opaque copy, or state in or with each Opaque copy |
| a computer-network location from which the general network-using |
| public has access to download using public-standard network protocols |
| a complete Transparent copy of the Document, free of added material. |
| If you use the latter option, you must take reasonably prudent steps, |
| when you begin distribution of Opaque copies in quantity, to ensure |
| that this Transparent copy will remain thus accessible at the stated |
| location until at least one year after the last time you distribute an |
| Opaque copy (directly or through your agents or retailers) of that |
| edition to the public. |
| |
| It is requested, but not required, that you contact the authors of the |
| Document well before redistributing any large number of copies, to give |
| them a chance to provide you with an updated version of the Document. |
| |
| @strong{4. MODIFICATIONS} |
| |
| You may copy and distribute a Modified Version of the Document under |
| the conditions of sections 2 and 3 above, provided that you release |
| the Modified Version under precisely this License, with the Modified |
| Version filling the role of the Document, thus licensing distribution |
| and modification of the Modified Version to whoever possesses a copy |
| of it. In addition, you must do these things in the Modified Version: |
| |
| |
| @enumerate A |
| |
| @item |
| Use in the Title Page (and on the covers, if any) a title distinct |
| from that of the Document, and from those of previous versions |
| (which should, if there were any, be listed in the History section |
| of the Document). You may use the same title as a previous version |
| if the original publisher of that version gives permission. |
| |
| @item |
| List on the Title Page, as authors, one or more persons or entities |
| responsible for authorship of the modifications in the Modified |
| Version, together with at least five of the principal authors of the |
| Document (all of its principal authors, if it has fewer than five), |
| unless they release you from this requirement. |
| |
| @item |
| State on the Title page the name of the publisher of the |
| Modified Version, as the publisher. |
| |
| @item |
| Preserve all the copyright notices of the Document. |
| |
| @item |
| Add an appropriate copyright notice for your modifications |
| adjacent to the other copyright notices. |
| |
| @item |
| Include, immediately after the copyright notices, a license notice |
| giving the public permission to use the Modified Version under the |
| terms of this License, in the form shown in the Addendum below. |
| |
| @item |
| Preserve in that license notice the full lists of Invariant Sections |
| and required Cover Texts given in the Document’s license notice. |
| |
| @item |
| Include an unaltered copy of this License. |
| |
| @item |
| Preserve the section Entitled “History”, Preserve its Title, and add |
| to it an item stating at least the title, year, new authors, and |
| publisher of the Modified Version as given on the Title Page. If |
| there is no section Entitled “History” in the Document, create one |
| stating the title, year, authors, and publisher of the Document as |
| given on its Title Page, then add an item describing the Modified |
| Version as stated in the previous sentence. |
| |
| @item |
| Preserve the network location, if any, given in the Document for |
| public access to a Transparent copy of the Document, and likewise |
| the network locations given in the Document for previous versions |
| it was based on. These may be placed in the “History” section. |
| You may omit a network location for a work that was published at |
| least four years before the Document itself, or if the original |
| publisher of the version it refers to gives permission. |
| |
| @item |
| For any section Entitled “Acknowledgements” or “Dedications”, |
| Preserve the Title of the section, and preserve in the section all |
| the substance and tone of each of the contributor acknowledgements |
| and/or dedications given therein. |
| |
| @item |
| Preserve all the Invariant Sections of the Document, |
| unaltered in their text and in their titles. Section numbers |
| or the equivalent are not considered part of the section titles. |
| |
| @item |
| Delete any section Entitled “Endorsements”. Such a section |
| may not be included in the Modified Version. |
| |
| @item |
| Do not retitle any existing section to be Entitled “Endorsements” |
| or to conflict in title with any Invariant Section. |
| |
| @item |
| Preserve any Warranty Disclaimers. |
| @end enumerate |
| |
| If the Modified Version includes new front-matter sections or |
| appendices that qualify as Secondary Sections and contain no material |
| copied from the Document, you may at your option designate some or all |
| of these sections as invariant. To do this, add their titles to the |
| list of Invariant Sections in the Modified Version’s license notice. |
| These titles must be distinct from any other section titles. |
| |
| You may add a section Entitled “Endorsements”, provided it contains |
| nothing but endorsements of your Modified Version by various |
| parties—for example, statements of peer review or that the text has |
| been approved by an organization as the authoritative definition of a |
| standard. |
| |
| You may add a passage of up to five words as a Front-Cover Text, and a |
| passage of up to 25 words as a Back-Cover Text, to the end of the list |
| of Cover Texts in the Modified Version. Only one passage of |
| Front-Cover Text and one of Back-Cover Text may be added by (or |
| through arrangements made by) any one entity. If the Document already |
| includes a cover text for the same cover, previously added by you or |
| by arrangement made by the same entity you are acting on behalf of, |
| you may not add another; but you may replace the old one, on explicit |
| permission from the previous publisher that added the old one. |
| |
| The author(s) and publisher(s) of the Document do not by this License |
| give permission to use their names for publicity for or to assert or |
| imply endorsement of any Modified Version. |
| |
| @strong{5. COMBINING DOCUMENTS} |
| |
| You may combine the Document with other documents released under this |
| License, under the terms defined in section 4 above for modified |
| versions, provided that you include in the combination all of the |
| Invariant Sections of all of the original documents, unmodified, and |
| list them all as Invariant Sections of your combined work in its |
| license notice, and that you preserve all their Warranty Disclaimers. |
| |
| The combined work need only contain one copy of this License, and |
| multiple identical Invariant Sections may be replaced with a single |
| copy. If there are multiple Invariant Sections with the same name but |
| different contents, make the title of each such section unique by |
| adding at the end of it, in parentheses, the name of the original |
| author or publisher of that section if known, or else a unique number. |
| Make the same adjustment to the section titles in the list of |
| Invariant Sections in the license notice of the combined work. |
| |
| In the combination, you must combine any sections Entitled “History” |
| in the various original documents, forming one section Entitled |
| “History”; likewise combine any sections Entitled “Acknowledgements”, |
| and any sections Entitled “Dedications”. You must delete all sections |
| Entitled “Endorsements”. |
| |
| @strong{6. COLLECTIONS OF DOCUMENTS} |
| |
| You may make a collection consisting of the Document and other documents |
| released under this License, and replace the individual copies of this |
| License in the various documents with a single copy that is included in |
| the collection, provided that you follow the rules of this License for |
| verbatim copying of each of the documents in all other respects. |
| |
| You may extract a single document from such a collection, and distribute |
| it individually under this License, provided you insert a copy of this |
| License into the extracted document, and follow this License in all |
| other respects regarding verbatim copying of that document. |
| |
| @strong{7. AGGREGATION WITH INDEPENDENT WORKS} |
| |
| A compilation of the Document or its derivatives with other separate |
| and independent documents or works, in or on a volume of a storage or |
| distribution medium, is called an “aggregate” if the copyright |
| resulting from the compilation is not used to limit the legal rights |
| of the compilation’s users beyond what the individual works permit. |
| When the Document is included in an aggregate, this License does not |
| apply to the other works in the aggregate which are not themselves |
| derivative works of the Document. |
| |
| If the Cover Text requirement of section 3 is applicable to these |
| copies of the Document, then if the Document is less than one half of |
| the entire aggregate, the Document’s Cover Texts may be placed on |
| covers that bracket the Document within the aggregate, or the |
| electronic equivalent of covers if the Document is in electronic form. |
| Otherwise they must appear on printed covers that bracket the whole |
| aggregate. |
| |
| @strong{8. TRANSLATION} |
| |
| Translation is considered a kind of modification, so you may |
| distribute translations of the Document under the terms of section 4. |
| Replacing Invariant Sections with translations requires special |
| permission from their copyright holders, but you may include |
| translations of some or all Invariant Sections in addition to the |
| original versions of these Invariant Sections. You may include a |
| translation of this License, and all the license notices in the |
| Document, and any Warranty Disclaimers, provided that you also include |
| the original English version of this License and the original versions |
| of those notices and disclaimers. In case of a disagreement between |
| the translation and the original version of this License or a notice |
| or disclaimer, the original version will prevail. |
| |
| If a section in the Document is Entitled “Acknowledgements”, |
| “Dedications”, or “History”, the requirement (section 4) to Preserve |
| its Title (section 1) will typically require changing the actual |
| title. |
| |
| @strong{9. TERMINATION} |
| |
| You may not copy, modify, sublicense, or distribute the Document |
| except as expressly provided under this License. Any attempt |
| otherwise to copy, modify, sublicense, or distribute it is void, and |
| will automatically terminate your rights under this License. |
| |
| However, if you cease all violation of this License, then your license |
| from a particular copyright holder is reinstated (a) provisionally, |
| unless and until the copyright holder explicitly and finally |
| terminates your license, and (b) permanently, if the copyright holder |
| fails to notify you of the violation by some reasonable means prior to |
| 60 days after the cessation. |
| |
| Moreover, your license from a particular copyright holder is |
| reinstated permanently if the copyright holder notifies you of the |
| violation by some reasonable means, this is the first time you have |
| received notice of violation of this License (for any work) from that |
| copyright holder, and you cure the violation prior to 30 days after |
| your receipt of the notice. |
| |
| Termination of your rights under this section does not terminate the |
| licenses of parties who have received copies or rights from you under |
| this License. If your rights have been terminated and not permanently |
| reinstated, receipt of a copy of some or all of the same material does |
| not give you any rights to use it. |
| |
| @strong{10. FUTURE REVISIONS OF THIS LICENSE} |
| |
| The Free Software Foundation may publish new, revised versions |
| of the GNU Free Documentation License from time to time. Such new |
| versions will be similar in spirit to the present version, but may |
| differ in detail to address new problems or concerns. See |
| @indicateurl{http://www.gnu.org/copyleft/}. |
| |
| Each version of the License is given a distinguishing version number. |
| If the Document specifies that a particular numbered version of this |
| License “or any later version” applies to it, you have the option of |
| following the terms and conditions either of that specified version or |
| of any later version that has been published (not as a draft) by the |
| Free Software Foundation. If the Document does not specify a version |
| number of this License, you may choose any version ever published (not |
| as a draft) by the Free Software Foundation. If the Document |
| specifies that a proxy can decide which future versions of this |
| License can be used, that proxy’s public statement of acceptance of a |
| version permanently authorizes you to choose that version for the |
| Document. |
| |
| @strong{11. RELICENSING} |
| |
| “Massive Multiauthor Collaboration Site” (or “MMC Site”) means any |
| World Wide Web server that publishes copyrightable works and also |
| provides prominent facilities for anybody to edit those works. A |
| public wiki that anybody can edit is an example of such a server. A |
| “Massive Multiauthor Collaboration” (or “MMC”) contained in the |
| site means any set of copyrightable works thus published on the MMC |
| site. |
| |
| “CC-BY-SA” means the Creative Commons Attribution-Share Alike 3.0 |
| license published by Creative Commons Corporation, a not-for-profit |
| corporation with a principal place of business in San Francisco, |
| California, as well as future copyleft versions of that license |
| published by that same organization. |
| |
| “Incorporate” means to publish or republish a Document, in whole or |
| in part, as part of another Document. |
| |
| An MMC is “eligible for relicensing” if it is licensed under this |
| License, and if all works that were first published under this License |
| somewhere other than this MMC, and subsequently incorporated in whole |
| or in part into the MMC, (1) had no cover texts or invariant sections, |
| and (2) were thus incorporated prior to November 1, 2008. |
| |
| The operator of an MMC Site may republish an MMC contained in the site |
| under CC-BY-SA on the same site at any time before August 1, 2009, |
| provided the MMC is eligible for relicensing. |
| |
| @strong{ADDENDUM: How to use this License for your documents} |
| |
| To use this License in a document you have written, include a copy of |
| the License in the document and put the following copyright and |
| license notices just after the title page: |
| |
| @quotation |
| |
| Copyright © YEAR YOUR NAME. |
| 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, no Front-Cover Texts, and no Back-Cover Texts. |
| A copy of the license is included in the section entitled “GNU |
| Free Documentation License”. |
| @end quotation |
| |
| If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts, |
| replace the “with … Texts.” line with this: |
| |
| @quotation |
| |
| with the Invariant Sections being LIST THEIR TITLES, with the |
| Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST. |
| @end quotation |
| |
| If you have Invariant Sections without Cover Texts, or some other |
| combination of the three, merge those two alternatives to suit the |
| situation. |
| |
| If your document contains nontrivial examples of program code, we |
| recommend releasing these examples in parallel under your choice of |
| free software license, such as the GNU General Public License, |
| to permit their use in free software. |
| |
| @node Index,,GNU Free Documentation License,Top |
| @unnumbered Index |
| |
| |
| @printindex ge |
| |
| @anchor{cf}@w{ } |
| @anchor{gnat_ugn/gnat_utility_programs switches-related-to-project-files}@w{ } |
| |
| @c %**end of body |
| @bye |