| \input texinfo @c -*-texinfo-*- |
| @c %**start of header |
| @setfilename gnat_ugn.info |
| @documentencoding UTF-8 |
| @ifinfo |
| @*Generated by Sphinx 4.3.1.@* |
| @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 , Jan 03, 2022 |
| |
| AdaCore |
| |
| Copyright @copyright{} 2008-2022, 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:: |
| * A GNU/Linux Debug Quirk:: |
| |
| 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 |
|