What is GNAT?

What is GNAT-Mac?

The GNAT-Mac Development Project

What is Ada?

A1.1 UsinggnatmakeA1.2 Overriding the GNAT default file-naming conventions

A1.3 Usinggdbto get a simple traceback

A1.4 Tracing a Program withgdbA1.5 Using

gnatfto get a cross reference

A1.6 Usinggnatk8

GNAT For The Macintosh

- Professor Michael Feldman
- Jim Hopper
- Dr. John Matthews
- Dr. Art Evans

Ada Core Technologies provides commercial support for GNAT and related software, including maintenance, porting of Ada83 applications to Ada95, porting of GNAT to new hardware platforms, training, and consulting. ACT can be contacted at:

73 Fifth Avenue, Suite 11-B

New York City, NY 10003

info@gnat.com

ACT maintains a site that holds the latest versions of the Macintosh
compilers and all documentation at:

or log in to: ftp://gnat-mac.com as
user **pubmcada, no password**, and cd to **/usr/users/macada/public**.

ACT provides GNAT compilers for all platforms (including the Mac) at this
site:

As of this writing, the relevant files are in directories mac68k and
powermac.

For other mirror sites, see the link "FTP and Mirror Sites" on
the ACT Home Page, http://www.gnat.com.

The Internet provides extensive resources for learning about all aspects of Ada. We recommend the Ada Home Page(http://www.adahome.com) for up-to-date links, directly or indirectly, to every Ada-related Ada resource on the Internet. For beginners, there are links to Ada tutorial material; for more advanced users there are links to the documentation defining the language. To learn more about HBAP, try the "Welcome Tour" link on the HBAP Home Page.

Copyright 1996, Michael B. Feldman. All Rights Reserved.

last revised September 1996

The document serves as an introduction to some of the tools provided
with the GNAT (GNU Ada 95) compilation system. This document does not replace
*gnatinfo.txt*, the "official" GNAT user manual, but rather
selectively augments it with examples of tool use and some helpful hints.
All these tools have many more options and flags than we shall cover here;
please refer to *gnatinfo.txt* for further details.

and the output is shown like this:sample command line

Consider a programsample output line

We have used the three options.

- verbose, which traces the steps in the build process
`-g`- include debugging info, which causes symbol table information to be included in the executable for debugging purposes. We will use this later.
`-gnatl`- which displays a compilation listing on the screen

Here is the screen output from this command, with our annotations:

GNATMAKE 3.05 (960607) Copyright 1995 Free Software Foundation, Inc. "test_factorial.ali" being checked ... -> "test_factorial.adb" time stamp mismatch test_factorial needs to be compiled; invoke the compiler and display the listing. gcc -c -g -gnatl test_factorial.adb GNAT 3.05 (960607) Copyright 1991-1996 Free Software Foundation, Inc. Compiling: test_factorial.adb (source file time stamp: 1996-09-22 15:15:47) 1. with Ada.Text_IO; 2. with Ada.Integer_Text_IO; 3. procedure Test_Factorial is 4. ---------------------------------------------------------------- 5. --| Demonstrates the factorial function 6. --| Author: Michael B. Feldman, The George Washington University 7. --| Copyright 1996, Michael B. Feldman. All Rights Reserved. 8. --| Last Modified: August 1996 9. ---------------------------------------------------------------- 10. 11. Answer: Positive; 12. 13. function Factorial (N : IN Positive) return Positive is 14. 15. -- Computes the factorial of N (N!) recursively 16. -- Pre : N is defined 17. -- Post: returns N! 18. 19. Result : Positive; 20. 21. begin -- Factorial 22. 23. if N = 1 then 24. Result := 1; -- stopping case 25. else 26. Result := N * Factorial(N-1); -- recursion 27. end if; 28. 29. return Result; 30. end Factorial; 31. 32. begin -- Test_Factorial 33. 34. Answer := Factorial(4); 35. Ada.Text_IO.Put(Item => "The value of 4! is "); 36. Ada.Integer_Text_IO.Put(Item => Answer, Width => 11); 37. Ada.Text_IO.New_Line; 38. 39. end Test_Factorial; 39 lines: No errorsSuccessful compilation; invoke the binder and linker.

Now we run the executable:gnatbind -x test_factorial.ali gnatlink -g test_factorial.ali

./test_factorialThe value of 4! is 24

These conventions are sometimes inconvenient, for example, when porting in Ada source code from another compiler with different conventions. It is possible to override these preferences, using a configuration file called

pragma Source_File_Name (Unit_Name => Rationals, Spec_File_Name => "prog21.ads"); pragma Source_File_Name (Unit_Name => Rationals, Body_File_Name => "prog22.adb"); pragma Source_File_Name (Unit_Name => Rationals.IO, Spec_File_Name => "prog23.ads"); pragma Source_File_Name (Unit_Name => Rationals.IO, Body_File_Name => "prog24.adb"); pragma Source_File_Name (Unit_Name => Test_Rationals_1, Body_File_Name => "prog25.adb");Rationals provide a simple rational number package;

(the

GNAT 3.05 (960607) Copyright 1991-1996 Free Software Foundation, Inc. Checking: prog21.ads (source file time stamp: 1996-09-22 14:14:00) 1. package Rationals is 2. ---------------------------------------------------------------- 3. --| 4. --| Specification of the abstract data type for representing 5. --| and manipulating rational numbers. 6. --| All rational quantities in this package are initialized 7. --| to 0/1. 8. --| 9. --| Author: Michael B. Feldman, The George Washington University 10. --| Copyright 1996, Michael B. Feldman. All Rights Reserved. 11. --| Last Modified: August 1996. 12. --| 13. ---------------------------------------------------------------- 14. 15. type Rational is private; 16. 17. ZeroDenominator: exception; 18. 19. function "/" (X : Integer; Y : Integer) return Rational; 20. -- constructor: 21. -- Pre : X and Y are defined 22. -- Post: returns a rational number 23. -- If Y > 0, returns Reduce(X,Y) 24. -- If Y < 0, returns Reduce(-X,-Y) 25. -- Raises: ZeroDenominator if Y = 0 26. 27. function "+"(R1 : Rational; R2 : Rational) return Rational; 28. -- dyadic arithmetic constructor: 29. -- Pre : R1 and R2 are defined 30. -- Post: returns the rational sum of R1 and R2 31. 32. private 33. -- A record of type Rational consists of a pair of Integer values 34. -- such that the first number represents the numerator of a rational 35. -- number and the second number represents the denominator. 36. 37. type Rational is record 38. Numerator : Integer := 0; 39. Denominator: Positive := 1; 40. end record; 41. end Rationals; 41 lines: No errors

We do the same for the spec of the rational input/output package:

GNAT 3.05 (960607) Copyright 1991-1996 Free Software Foundation, Inc. Checking: prog23.ads (source file time stamp: 1996-09-22 14:14:00) 1. with Ada.Text_IO; 2. package Rationals.IO is 3. ---------------------------------------------------------------- 4. --| Specification of the input/output child package for Rationals 5. --| 6. --| Author: Michael B. Feldman, The George Washington University 7. --| Copyright 1996, Michael B. Feldman. All Rights Reserved. 8. ---------------------------------------------------------------- 9. 10. procedure Get (Item : out Rational); 11. -- Pre : None 12. -- Post: The first integer number read is the numerator of Item; 13. -- the second integer number is the denominator of Item. 14. -- A "/" between the two numbers is optional. 15. -- The Rational constructor "/" is called 16. -- to produce a rational in reduced form. 17. 18. procedure Put (Item : in Rational); 19. -- Pre : Item is defined 20. -- Post: displays the numerator and denominator of Item. 21. 22. end Rationals.IO; 22 lines: No errors

Now we are ready to build

GNATMAKE 3.05 (960607) Copyright 1995 Free Software Foundation, Inc. gcc -c -g -gnatl prog25.adb GNAT 3.05 (960607) Copyright 1991-1996 Free Software Foundation, Inc. Compiling: prog25.adb (source file time stamp: 1996-09-22 14:14:01) 1. with Ada.Text_IO; 2. with Rationals; use type Rationals.Rational; 3. with Rationals.IO; 4. procedure Test_Rationals_1 is 5. ---------------------------------------------------------------- 6. --| Very rudimentary test of package Rationals and Rationals.IO 7. --| 8. --| Author: Michael B. Feldman, The George Washington University 9. --| Copyright 1996, Michael B. Feldman. All Rights Reserved. 10. --| Last Modified: July 1995 11. ---------------------------------------------------------------- 12. 13. A: Rationals.Rational; 14. B: Rationals.Rational; 15. C: Rationals.Rational; 16. D: Rationals.Rational; 17. E: Rationals.Rational; 18. F: Rationals.Rational; 19. 20. begin -- Test_Rationals_1 21. 22. A := 1/3; 23. B := 2/(-4); 24. Ada.Text_IO.Put(Item => "A = "); 25. Rationals.IO.Put(Item => A); 26. Ada.Text_IO.New_Line; 27. Ada.Text_IO.Put(Item => "B = "); 28. Rationals.IO.Put(Item => B); 29. Ada.Text_IO.New_Line; 30. 31. -- Read in rational numbers C and D. 32. Ada.Text_IO.Put(Item => "Enter rational number C > "); 33. Rationals.IO.Get(Item => C); 34. Ada.Text_IO.Put(Item => "Enter rational number D > "); 35. Rationals.IO.Get(Item => D); 36. Ada.Text_IO.New_Line; 37. 38. E := A + B; 39. Ada.Text_IO.Put(Item => "E = A + B is "); 40. Rationals.IO.Put(Item => E); 41. Ada.Text_IO.New_Line; 42. 43. F := C + D; 44. Ada.Text_IO.Put(Item => "F = C + D is "); 45. Rationals.IO.Put(Item => F); 46. Ada.Text_IO.New_Line; 47. 48. Ada.Text_IO.Put(Item => "A + E + F is "); 49. Rationals.IO.Put(Item => A + E + F); 50. Ada.Text_IO.New_Line; 51. 52. end Test_Rationals_1; 52 lines: No errors

GNAT 3.05 (960607) Copyright 1991-1996 Free Software Foundation, Inc. Compiling: prog22.adb (source file time stamp: 1996-09-22 14:14:00) 1. package body Rationals is 2. 3. ---------------------------------------------------------------- 4. --| Body of the abstract data type for representing 5. --| and manipulating rational numbers. 6. --| 7. --| Author: Michael B. Feldman, The George Washington University 8. --| Copyright 1996, Michael B. Feldman 9. --| Last Modified: August 1996 10. ---------------------------------------------------------------- 11. 12. -- local function GCD, not provided to clients 13. 14. function GCD(M: Positive; N: Positive) return Positive is 15. -- finds the greatest common divisor of M and N 16. -- Pre: M and N are defined 17. -- Post: returns the GCD of M and N, by Euclid's Algorithm 18. 19. R : Natural; 20. TempM: Positive; 21. TempN: Positive; 22. 23. begin -- GCD 24. 25. TempM := M; 26. TempN := N; 27. 28. R := TempM rem TempN; 29. 30. while R /= 0 loop 31. TempM := TempN; 32. TempN := R; 33. R := TempM rem TempN; 34. end loop; 35. 36. return TempN; 37. 38. end GCD; 39. 40. -- exported operations 41. 42. function "/" (X : Integer; Y : Integer) return Rational is 43. G: Positive; 44. begin -- "/" 45. 46. if Y = 0 then 47. raise ZeroDenominator; 48. end if; 49. 50. if X = 0 then 51. return (Numerator => 0, Denominator => 1); 52. end if; 53. 54. G := GCD(abs X, abs Y); 55. if Y > 0 then 56. return (Numerator => X/G, Denominator => Y/G); 57. else 58. return (Numerator => (-X)/G, Denominator => (-Y)/G); 59. end if; 60. 61. end "/"; 62. 63. -- dyadic arithmetic operator 64. 65. function "+"(R1 : Rational; R2 : Rational) return Rational is 66. N: Integer; 67. D: Positive; 68. begin -- "+" 69. N := R1.Numerator * R2.Denominator + R2.Numerator * R1.Denominator; 70. D := R1.Denominator * R2.Denominator; 71. return N/D; -- compiler will use Rational constructor here! 72. end "+"; 73. 74. end Rationals; 74 lines: No errors

Similarly,

gcc -c -g -gnatl prog24.adb

GNAT 3.05 (960607) Copyright 1991-1996 Free Software Foundation, Inc. Compiling: prog24.adb (source file time stamp: 1996-09-22 14:14:00) 1. with Ada.Text_IO; 2. with Ada.Integer_Text_IO; 3. package body Rationals.IO is 4. ---------------------------------------------------------------- 5. --| Body of the input/output child package for Rationals 6. --| 7. --| Author: Michael B. Feldman, The George Washington University 8. --| Copyright 1996, Michael B. Feldman. All Rights Reserved 9. --| Last Modified: August 1996 10. ---------------------------------------------------------------- 11. 12. -- input procedure 13. 14. procedure Get (Item : out Rational) is 15. 16. N: Integer; 17. D: Integer; 18. Dummy: Character; -- dummy character to hold the "/" 19. 20. begin -- Get 21. 22. Ada.Integer_Text_IO.Get(Item => N); 23. Ada.Text_IO.Get (Item => Dummy); 24. Ada.Integer_Text_IO.Get(Item => D); 25. Item := N/D; 26. 27. end Get; 28. 29. -- output procedure 30. 31. procedure Put (Item : in Rational) is 32. 33. begin -- Put 34. 35. Ada.Integer_Text_IO.Put(Item => Item.Numerator, Width => 1); 36. Ada.Text_IO.Put(Item => '/'); 37. Ada.Integer_Text_IO.Put(Item => Item.Denominator, Width => 1); 38. 39. end Put; 40. 41. end Rationals.IO; 41 lines: No errorsFinally,

gnatlink -g prog25.ali

Now we execute the demonstration program several times:

Here we entered a zero for the denominator of a rational. This is not allowed mathematically, so the exception is raised (somewhere in the rationals package) and propagated out of the main program../prog25A = 1/3 B = -1/2 Enter rational number C > 2/4 Enter rational number D > 9/6 E = A + B is -1/6 F = C + D is 2/1 A + E + F is 13/6A = 1/3 B = -1/2 Enter rational number C > 0/1 Enter rational number D > 9/6 E = A + B is -1/6 F = C + D is 3/2 A + E + F is 5/3./prog25./prog25A = 1/3 B = -1/2 Enter rational number C > 1/0 raised RATIONALS.ZERODENOMINATOR

We can get a full traceback showing where the exception was raised and how it propagated, but we need

and we are placed in

GDB is free software and you are welcome to distribute copies of it under certain conditions; type "show copying" to see the conditions. There is absolutely no warranty for GDB; type "show warranty" for details. GDB 4.15.1.gnat.1.10 Copyright 1995 Free Software Foundation, Inc. (gdb)We have indicated that we wishbreak __gnat_unhandled_exception

Breakpoint 1 at 0x17dec: file a-raise.c, line 65Now we tell

(gdb)Here we stop at the breakpoint, because we entered that zero denominator. Ignore the last line aboutrunStarting program: prog25 Breakpoint 1 at 0x1fa328c: file a-raise.c, line 65. A = 1/3 B = -1/2 Enter rational number C > 1 0 Breakpoint 1, __gnat_unhandled_exception (except=0x36abb58) at a-raise.c:65 a-raise.c:65: No such file or directory.

(gdb)Refer back to the listings above. The interesting part of the traceback, lines 4-6, shows that the exception was raised in the function "/" at line 22 ofbacktrace#0 __gnat_unhandled_exception (except=0x36abb58) at a- raise.c:65 #1 0x1fa33c4 in __gnat_raise_nodefer_with_msg (except=0x36abb58) at a-raise.c:108 #2 0x1fa3438 in __gnat_raise_nodefer (except=0x36abb58) at a-raise.c:120 #3 0x1fa34cc in __gnat_raise (except=0x36abb58) at a- raise.c:130 #4 0x1fa2510 in rationals."/" (x=1, y=0) at prog22.adb:47 #5 0x1fa288c in rationals.io.get (item={numerator = 0, denominator = 1}) at prog24.adb:25 #6 0x1fa2b08 in test_rationals_1 () at prog25.adb:33 #7 0x1f8b64c in main (argc=1, argv=0x1f8a3ec, envp=0x1f8a3f4) at b_prog25.c:40 #8 0x1f8b4e8 in __start (=0x4186001c, =0x81620008, =0x1) #9 0x1f8b4a0 in __start (=0x1f8a59f, =0x1f8a5c6, =0x1f8a5d1)

(gdb)quitThe program is running. Quit anyway (and kill it)? (y or n)y

First we stop at the first executable statement of the main program:gdb test_factorialGDB is free software and you are welcome to distribute copies of it under certain conditions; type "show copying" to see the conditions. There is absolutely no warranty for GDB; type "show warranty" for details. GDB 4.15.1.gnat.1.10, Copyright 1995 Free Software Foundation, Inc.

(gdb)Now we set a break for each time we callbreak test_factorialBreakpoint 1 at 0x16ee4: file test_factorial.adb, line 34.

(gdb)and we continue the run:break factorialBreakpoint 2 at 0x16dd0: file test_factorial.adb, line 23. (gdb)runStarting program: test_factorial Breakpoint 1 at 0x2f6ef24: file test_factorial.adb, line 34. Breakpoint 2 at 0x2f6ee10: file test_factorial.adb, line 23. Breakpoint 1, test_factorial () at test_factorial.adb:34 34 Answer := Factorial(4);

(gdb)Now we will set a watchpoint on the variablecontinueContinuing. Breakpoint 2, test_factorial.factorial (n=4) at test_factorial.adb:23 23 if N = 1 then

(gdb)The huge values (which vary from execution to execution) suggest thatwatch resultWatchpoint 3: test_factorial.factorial::result (gdb)continueContinuing. Watchpoint 3: test_factorial.factorial::result Old value = 57185676 New value = 57179476 0x1efec48 in test_factorial.factorial (n=32402616) at test_factorial.adb:13 13 function Factorial (N : IN Positive) return Positive is

(gdb)Now we've recursed all the way down, and start back up:continueContinuing. Breakpoint 2, test_factorial.factorial (n=3) at test_factorial.adb:23 23 if N = 1 then (gdb)continueContinuing. Breakpoint 2, test_factorial.factorial (n=2) at test_factorial.adb:23 23 if N = 1 then (gdb)continueContinuing. Watchpoint 3: test_factorial.factorial::result Old value = 57179476 New value = 0 0x1efec48 in test_factorial.factorial (n=32402440) at test_factorial.adb:13 13 function Factorial (N : IN Positive) return Positive is (gdb)continueContinuing. Breakpoint 2, test_factorial.factorial (n=1) at test_factorial.adb:23 23 if N = 1 then (gdb)continueContinuing. Watchpoint 3: test_factorial.factorial::result Old value = 0 New value = 1 0x1efec64 in test_factorial.factorial (n=1) at test_factorial.adb:24 24 Result := 1; -- stopping case

(gdb)Refer to the GNAT documents for a full set of documentation oncontinueContinuing. Watchpoint 3: test_factorial.factorial::result Old value = 1 New value = 57179476 0x1efed18 in test_factorial.factorial (n=2) at test_factorial.adb:29 29 return Result; (gdb)continueContinuing. Watchpoint 3: test_factorial.factorial::result Old value = 57179476 New value = 2 test_factorial.factorial (n=2) at test_factorial.adb:29 29 return Result; (gdb)continueContinuing. Watchpoint 3: test_factorial.factorial::result Old value = 2 New value = 57179476 0x1efed18 in test_factorial.factorial (n=3) at test_factorial.adb:29 29 return Result; (gdb)continueContinuing. Watchpoint 3: test_factorial.factorial::result Old value = 57179476 New value = 6 test_factorial.factorial (n=3) at test_factorial.adb:29 29 return Result; (gdb)continueContinuing. Watchpoint 3: test_factorial.factorial::result Old value = 6 New value = 57185676 0x1efed18 in test_factorial.factorial (n=4) at test_factorial.adb:29 29 return Result; (gdb)continueContinuing. Watchpoint 3: test_factorial.factorial::result Old value = 57185676 New value = 24 test_factorial.factorial (n=4) at test_factorial.adb:29 29 return Result; (gdb)continueContinuing. Watchpoint 3 deleted because the program has left the block in which its expression is valid. 0x1efecf8 in test_factorial.factorial (n=4) at test_factorial.adb:29 29 return Result; (gdb)continueContinuing. The value of 4! is 24 Program exited normally

(gdb)helpList of classes of commands: running -- Running the program stack -- Examining the stack data -- Examining data breakpoints -- Making program stop at certain points files -- Specifying and examining files status -- Status inquiries support -- Support facilities user-defined -- User-defined commands aliases -- Aliases of other commands obscure -- Obscure features internals -- Maintenance commands Type "help" followed by a class name for a list of commands in that class. Type "help" followed by command name for full documentation. Command name abbreviations are allowed if unambiguous.

Here we see the variables declared in

The main program calls some procedures fromcat X.ref%% prog25.adb 960922141401 %% test_rationals_1 procedure 4:11 a variable 13:3 prog25.adb {22:3 25:28 38:8 49:28} b variable 14:3 prog25.adb {23:3 28:28 38:12} c variable 15:3 prog25.adb {33:28 43:8} d variable 16:3 prog25.adb {35:28 43:12} e variable 17:3 prog25.adb {38:3 40:28 49:32} f variable 18:3 prog25.adb {43:3 45:28 49:36}

-- /usr/local/adainclude/a-textio.ads 960625050333 -- text_io package 30:13 prog25.adb {1:10 24:7 26:7 27:7 29:7 32:7 34:7 36:7 39:7 41:7 44:7 46:7 48:7 50:7} text_io.new_line procedure 141:14 prog25.adb {26:15 29:15 36:15 41:15 46:15 50:15} text_io.put procedure 217:14 prog25.adb {24:15 27:15 32:15 34:15 39:15 44:15 48:15} -- /usr/local/adainclude/ada.ads 960625050300 -- ada package 18:9 prog25.adb {24:3 26:3 27:3 29:3 32:3 34:3 36:3 39:3 41:3 44:3 46:3 48:3 50:3} 3}and from

-- prog21.ads 960922141400 -- rationals package 1:9 prog25.adb {2:6 2:26 13:6 14:6 15:6 16:6 17:6 18:6 25:3 28:3 33:3 35:3 40:3 45 :3 49:3} rational private_type 15:8 37:8 prog25.adb {2:36 13:16 14:16 15:16 16:16 17:16 18:16} "/" function 19:12 prog25.adb {22:9 23:9} "+" function 27:12 prog25.adb {38:10 43:10 49:34 49:30}and from

-- prog23.ads 960922141400 -- io package 2:19 prog25.adb {3:16 25:13 28:13 33:13 35:13 40:13 45:13 49:13} io.get procedure 10:13 prog25.adb {33:16 35:16} io.put procedure 18:13 prog25.adb {25:16 28:16 40:16 45:16 49:16}

For systems with limits on file names, GNAT has an algorithm (krunch) for "crunching" its preferred file names down to the limit. On the Mac, if we add the flag

Suppose the file name is long. How do we determine its krunched name? The tool

Given a unit:

Very_Long_Unit_Name.Long_Child_Package_Namestored in a file

Then rename the file accordingly:gnatk8 Very_Long_Unit_Name.Long_Child_Package_Name 27verlonuninamlonchilpackname

mv some_file.adb verlonuninamlonchilpackname.adb

[ Table of Contents ][ Appendix A2 ][ Top of Page ]