111
|
1 .. role:: switch(samp)
|
|
2
|
|
3 .. -- Non-breaking space in running text
|
|
4 -- E.g. Ada |nbsp| 95
|
|
5
|
|
6 .. |nbsp| unicode:: 0xA0
|
|
7 :trim:
|
|
8
|
|
9 .. _Platform_Specific_Information:
|
|
10
|
|
11 *****************************
|
|
12 Platform-Specific Information
|
|
13 *****************************
|
|
14
|
|
15 This appendix contains information relating to the implementation
|
|
16 of run-time libraries on various platforms and also covers
|
|
17 topics related to the GNAT implementation on Windows and Mac OS.
|
|
18
|
|
19 .. _`Run_Time_Libraries`:
|
|
20
|
|
21 Run-Time Libraries
|
|
22 ==================
|
|
23
|
|
24 .. index:: Tasking and threads libraries
|
|
25 .. index:: Threads libraries and tasking
|
|
26 .. index:: Run-time libraries (platform-specific information)
|
|
27
|
|
28 The GNAT run-time implementation may vary with respect to both the
|
|
29 underlying threads library and the exception-handling scheme.
|
|
30 For threads support, the default run-time will bind to the thread
|
|
31 package of the underlying operating system.
|
|
32
|
|
33 For exception handling, either or both of two models are supplied:
|
|
34
|
|
35 .. index:: Zero-Cost Exceptions
|
|
36 .. index:: ZCX (Zero-Cost Exceptions)
|
|
37
|
|
38 * **Zero-Cost Exceptions** ("ZCX"),
|
|
39 which uses binder-generated tables that
|
|
40 are interrogated at run time to locate a handler.
|
|
41
|
|
42 .. index:: setjmp/longjmp Exception Model
|
|
43 .. index:: SJLJ (setjmp/longjmp Exception Model)
|
|
44
|
|
45 * **setjmp / longjmp** ('SJLJ'),
|
|
46 which uses dynamically-set data to establish
|
|
47 the set of handlers
|
|
48
|
|
49 Most programs should experience a substantial speed improvement by
|
|
50 being compiled with a ZCX run-time.
|
|
51 This is especially true for
|
|
52 tasking applications or applications with many exception handlers.}
|
|
53
|
|
54 This section summarizes which combinations of threads and exception support
|
|
55 are supplied on various GNAT platforms.
|
|
56 It then shows how to select a particular library either
|
|
57 permanently or temporarily,
|
|
58 explains the properties of (and tradeoffs among) the various threads
|
|
59 libraries, and provides some additional
|
|
60 information about several specific platforms.
|
|
61
|
|
62 .. _Summary_of_Run-Time_Configurations:
|
|
63
|
|
64 Summary of Run-Time Configurations
|
|
65 ----------------------------------
|
|
66
|
|
67 +-----------------+--------------+-------------------------+------------+
|
|
68 | Platform | Run-Time | Tasking | Exceptions |
|
|
69 +=================+==============+=========================+============+
|
|
70 | GNU/Linux | rts-native | pthread library | ZCX |
|
|
71 | | (default) | | |
|
|
72 | +--------------+-------------------------+------------+
|
|
73 | | rts-sjlj | pthread library | SJLJ |
|
|
74 +-----------------+--------------+-------------------------+------------+
|
|
75 | Windows | rts-native | native Win32 threads | ZCX |
|
|
76 | | (default) | | |
|
|
77 | +--------------+-------------------------+------------+
|
|
78 | | rts-sjlj | native Win32 threads | SJLJ |
|
|
79 +-----------------+--------------+-------------------------+------------+
|
|
80 | Mac OS | rts-native | pthread library | ZCX |
|
|
81 +-----------------+--------------+-------------------------+------------+
|
|
82
|
|
83
|
|
84 .. _Specifying_a_Run-Time_Library:
|
|
85
|
|
86 Specifying a Run-Time Library
|
|
87 =============================
|
|
88
|
|
89 The :file:`adainclude` subdirectory containing the sources of the GNAT
|
|
90 run-time library, and the :file:`adalib` subdirectory containing the
|
|
91 :file:`ALI` files and the static and/or shared GNAT library, are located
|
|
92 in the gcc target-dependent area:
|
|
93
|
|
94
|
|
95 ::
|
|
96
|
|
97 target=$prefix/lib/gcc/gcc-*dumpmachine*/gcc-*dumpversion*/
|
|
98
|
|
99 As indicated above, on some platforms several run-time libraries are supplied.
|
|
100 These libraries are installed in the target dependent area and
|
|
101 contain a complete source and binary subdirectory. The detailed description
|
|
102 below explains the differences between the different libraries in terms of
|
|
103 their thread support.
|
|
104
|
|
105 The default run-time library (when GNAT is installed) is *rts-native*.
|
|
106 This default run-time is selected by the means of soft links.
|
|
107 For example on x86-linux:
|
|
108
|
|
109 .. --
|
|
110 -- $(target-dir)
|
|
111 -- |
|
|
112 -- +--- adainclude----------+
|
|
113 -- | |
|
|
114 -- +--- adalib-----------+ |
|
|
115 -- | | |
|
|
116 -- +--- rts-native | |
|
|
117 -- | | | |
|
|
118 -- | +--- adainclude <---+
|
|
119 -- | | |
|
|
120 -- | +--- adalib <----+
|
|
121 -- |
|
|
122 -- +--- rts-sjlj
|
|
123 -- |
|
|
124 -- +--- adainclude
|
|
125 -- |
|
|
126 -- +--- adalib
|
|
127
|
|
128 .. only:: html or latex
|
|
129
|
|
130 .. image:: rtlibrary-structure.png
|
|
131
|
|
132 .. only:: not (html or latex)
|
|
133
|
|
134 ::
|
|
135
|
|
136 $(target-dir)
|
|
137 __/ / \ \___
|
|
138 _______/ / \ \_________________
|
|
139 / / \ \
|
|
140 / / \ \
|
|
141 ADAINCLUDE ADALIB rts-native rts-sjlj
|
|
142 : : / \ / \
|
|
143 : : / \ / \
|
|
144 : : / \ / \
|
|
145 : : / \ / \
|
|
146 +-------------> adainclude adalib adainclude adalib
|
|
147 : ^
|
|
148 : :
|
|
149 +---------------------+
|
|
150
|
|
151 Run-Time Library Directory Structure
|
|
152 (Upper-case names and dotted/dashed arrows represent soft links)
|
|
153
|
|
154 If the *rts-sjlj* library is to be selected on a permanent basis,
|
|
155 these soft links can be modified with the following commands:
|
|
156
|
|
157 ::
|
|
158
|
|
159 $ cd $target
|
|
160 $ rm -f adainclude adalib
|
|
161 $ ln -s rts-sjlj/adainclude adainclude
|
|
162 $ ln -s rts-sjlj/adalib adalib
|
|
163
|
|
164 Alternatively, you can specify :file:`rts-sjlj/adainclude` in the file
|
|
165 :file:`$target/ada_source_path` and :file:`rts-sjlj/adalib` in
|
|
166 :file:`$target/ada_object_path`.
|
|
167
|
|
168 .. index:: --RTS option
|
|
169
|
|
170 Selecting another run-time library temporarily can be
|
|
171 achieved by using the :switch:`--RTS` switch, e.g., :switch:`--RTS=sjlj`
|
|
172
|
|
173
|
|
174 .. _Choosing_the_Scheduling_Policy:
|
|
175
|
|
176 .. index:: SCHED_FIFO scheduling policy
|
|
177 .. index:: SCHED_RR scheduling policy
|
|
178 .. index:: SCHED_OTHER scheduling policy
|
|
179
|
|
180 Choosing the Scheduling Policy
|
|
181 ------------------------------
|
|
182
|
|
183 When using a POSIX threads implementation, you have a choice of several
|
|
184 scheduling policies: ``SCHED_FIFO``, ``SCHED_RR`` and ``SCHED_OTHER``.
|
|
185
|
|
186 Typically, the default is ``SCHED_OTHER``, while using ``SCHED_FIFO``
|
|
187 or ``SCHED_RR`` requires special (e.g., root) privileges.
|
|
188
|
|
189 .. index:: pragma Time_Slice
|
|
190 .. index:: -T0 option
|
|
191 .. index:: pragma Task_Dispatching_Policy
|
|
192
|
|
193
|
|
194 By default, GNAT uses the ``SCHED_OTHER`` policy. To specify
|
|
195 ``SCHED_FIFO``,
|
|
196 you can use one of the following:
|
|
197
|
|
198 * ``pragma Time_Slice (0.0)``
|
|
199 * the corresponding binder option :switch:`-T0`
|
|
200 * ``pragma Task_Dispatching_Policy (FIFO_Within_Priorities)``
|
|
201
|
|
202
|
|
203 To specify ``SCHED_RR``,
|
|
204 you should use ``pragma Time_Slice`` with a
|
|
205 value greater than 0.0, or else use the corresponding :switch:`-T`
|
|
206 binder option.
|
|
207
|
|
208
|
|
209 To make sure a program is running as root, you can put something like
|
|
210 this in a library package body in your application:
|
|
211
|
|
212 .. code-block:: ada
|
|
213
|
|
214 function geteuid return Integer;
|
|
215 pragma Import (C, geteuid, "geteuid");
|
|
216 Ignore : constant Boolean :=
|
|
217 (if geteuid = 0 then True else raise Program_Error with "must be root");
|
|
218
|
|
219 It gets the effective user id, and if it's not 0 (i.e. root), it raises
|
|
220 Program_Error.
|
|
221
|
131
|
222 .. index:: Linux
|
|
223 .. index:: GNU/Linux
|
|
224
|
|
225 .. _GNU_Linux_Topics:
|
|
226
|
|
227 GNU/Linux Topics
|
|
228 ================
|
|
229
|
|
230 This section describes topics that are specific to GNU/Linux platforms.
|
|
231
|
|
232 .. _Required_packages_on_GNU_Linux:
|
|
233
|
|
234 Required Packages on GNU/Linux
|
|
235 ------------------------------
|
|
236
|
|
237 GNAT requires the C library developer's package to be installed.
|
|
238 The name of of that package depends on your GNU/Linux distribution:
|
|
239
|
|
240 * RedHat, SUSE: ``glibc-devel``;
|
|
241 * Debian, Ubuntu: ``libc6-dev`` (normally installed by default).
|
|
242
|
|
243 If using the 32-bit version of GNAT on a 64-bit version of GNU/Linux,
|
|
244 you'll need the 32-bit version of the following packages:
|
|
245
|
|
246 * RedHat, SUSE: ``glibc.i686``, ``glibc-devel.i686``, ``ncurses-libs.i686``
|
|
247 * Debian, Ubuntu: ``libc6:i386``, ``libc6-dev:i386``, ``lib32ncursesw5``
|
|
248
|
|
249 Other GNU/Linux distributions might be choosing a different name
|
|
250 for those packages.
|
|
251
|
111
|
252 .. index:: Windows
|
|
253
|
|
254 .. _Microsoft_Windows_Topics:
|
|
255
|
|
256 Microsoft Windows Topics
|
|
257 ========================
|
|
258
|
|
259 This section describes topics that are specific to the Microsoft Windows
|
|
260 platforms.
|
|
261
|
|
262
|
|
263 .. only:: PRO or GPL
|
|
264
|
|
265 .. rubric:: Installing from the Command Line
|
|
266
|
|
267 By default the GNAT installers display a GUI that prompts you to enter
|
|
268 the installation path and similar information, and then guides you through the
|
|
269 installation process. It is also possible to perform silent installations
|
|
270 using the command-line interface.
|
|
271
|
|
272 In order to install one of the GNAT installers from the command
|
|
273 line you should pass parameter :switch:`/S` (and, optionally,
|
|
274 :switch:`/D=<directory>`) as command-line arguments.
|
|
275
|
|
276 .. only:: PRO
|
|
277
|
|
278 For example, for an unattended installation of
|
|
279 GNAT 7.0.2 into the default directory
|
|
280 ``C:\\GNATPRO\\7.0.2`` you would run:
|
|
281
|
|
282 ::
|
|
283
|
|
284 gnatpro-7.0.2-i686-pc-mingw32-bin.exe /S
|
|
285
|
|
286 To install into a custom directory, say, ``C:\\TOOLS\\GNATPRO\\7.0.2``:
|
|
287
|
|
288 ::
|
|
289
|
|
290 gnatpro-7.0.2-i686-pc-mingw32-bin /S /D=C:\TOOLS\GNATPRO\7.0.2
|
|
291
|
|
292 .. only:: GPL
|
|
293
|
|
294 For example, for an unattended installation of
|
|
295 GNAT 2012 into ``C:\\GNAT\\2012``:
|
|
296
|
|
297 ::
|
|
298
|
|
299 gnat-gpl-2012-i686-pc-mingw32-bin /S /D=C:\GNAT\2012
|
|
300
|
|
301 .. only:: PRO or GPL
|
|
302
|
|
303 You can use the same syntax for all installers.
|
|
304
|
|
305 Note that unattended installations don't modify system path, nor create file
|
|
306 associations, so such activities need to be done by hand.
|
|
307
|
|
308
|
|
309
|
|
310 .. _Using_GNAT_on_Windows:
|
|
311
|
|
312 Using GNAT on Windows
|
|
313 ---------------------
|
|
314
|
|
315 One of the strengths of the GNAT technology is that its tool set
|
|
316 (``gcc``, ``gnatbind``, ``gnatlink``, ``gnatmake``, the
|
|
317 ``gdb`` debugger, etc.) is used in the same way regardless of the
|
|
318 platform.
|
|
319
|
|
320 On Windows this tool set is complemented by a number of Microsoft-specific
|
|
321 tools that have been provided to facilitate interoperability with Windows
|
|
322 when this is required. With these tools:
|
|
323
|
|
324
|
|
325 * You can build applications using the ``CONSOLE`` or ``WINDOWS``
|
|
326 subsystems.
|
|
327
|
|
328 * You can use any Dynamically Linked Library (DLL) in your Ada code (both
|
|
329 relocatable and non-relocatable DLLs are supported).
|
|
330
|
|
331 * You can build Ada DLLs for use in other applications. These applications
|
|
332 can be written in a language other than Ada (e.g., C, C++, etc). Again both
|
|
333 relocatable and non-relocatable Ada DLLs are supported.
|
|
334
|
|
335 * You can include Windows resources in your Ada application.
|
|
336
|
|
337 * You can use or create COM/DCOM objects.
|
|
338
|
|
339 Immediately below are listed all known general GNAT-for-Windows restrictions.
|
|
340 Other restrictions about specific features like Windows Resources and DLLs
|
|
341 are listed in separate sections below.
|
|
342
|
|
343
|
|
344 * It is not possible to use ``GetLastError`` and ``SetLastError``
|
|
345 when tasking, protected records, or exceptions are used. In these
|
|
346 cases, in order to implement Ada semantics, the GNAT run-time system
|
|
347 calls certain Win32 routines that set the last error variable to 0 upon
|
|
348 success. It should be possible to use ``GetLastError`` and
|
|
349 ``SetLastError`` when tasking, protected record, and exception
|
|
350 features are not used, but it is not guaranteed to work.
|
|
351
|
|
352 * It is not possible to link against Microsoft C++ libraries except for
|
|
353 import libraries. Interfacing must be done by the mean of DLLs.
|
|
354
|
|
355 * It is possible to link against Microsoft C libraries. Yet the preferred
|
|
356 solution is to use C/C++ compiler that comes with GNAT, since it
|
|
357 doesn't require having two different development environments and makes the
|
|
358 inter-language debugging experience smoother.
|
|
359
|
|
360 * When the compilation environment is located on FAT32 drives, users may
|
|
361 experience recompilations of the source files that have not changed if
|
|
362 Daylight Saving Time (DST) state has changed since the last time files
|
|
363 were compiled. NTFS drives do not have this problem.
|
|
364
|
|
365 * No components of the GNAT toolset use any entries in the Windows
|
|
366 registry. The only entries that can be created are file associations and
|
|
367 PATH settings, provided the user has chosen to create them at installation
|
|
368 time, as well as some minimal book-keeping information needed to correctly
|
|
369 uninstall or integrate different GNAT products.
|
|
370
|
|
371
|
|
372 .. _Using_a_network_installation_of_GNAT:
|
|
373
|
|
374 Using a network installation of GNAT
|
|
375 ------------------------------------
|
|
376
|
|
377 Make sure the system on which GNAT is installed is accessible from the
|
|
378 current machine, i.e., the install location is shared over the network.
|
|
379 Shared resources are accessed on Windows by means of UNC paths, which
|
|
380 have the format ``\\\\server\\sharename\\path``
|
|
381
|
|
382 In order to use such a network installation, simply add the UNC path of the
|
|
383 :file:`bin` directory of your GNAT installation in front of your PATH. For
|
|
384 example, if GNAT is installed in :file:`\\GNAT` directory of a share location
|
|
385 called :file:`c-drive` on a machine :file:`LOKI`, the following command will
|
|
386 make it available:
|
|
387
|
|
388 ::
|
|
389
|
|
390 $ path \\loki\c-drive\gnat\bin;%path%`
|
|
391
|
|
392 Be aware that every compilation using the network installation results in the
|
|
393 transfer of large amounts of data across the network and will likely cause
|
|
394 serious performance penalty.
|
|
395
|
|
396 .. _CONSOLE_and_WINDOWS_subsystems:
|
|
397
|
|
398 CONSOLE and WINDOWS subsystems
|
|
399 ------------------------------
|
|
400
|
|
401 .. index:: CONSOLE Subsystem
|
|
402 .. index:: WINDOWS Subsystem
|
|
403 .. index:: -mwindows
|
|
404
|
|
405 There are two main subsystems under Windows. The ``CONSOLE`` subsystem
|
|
406 (which is the default subsystem) will always create a console when
|
|
407 launching the application. This is not something desirable when the
|
|
408 application has a Windows GUI. To get rid of this console the
|
|
409 application must be using the ``WINDOWS`` subsystem. To do so
|
|
410 the :switch:`-mwindows` linker option must be specified.
|
|
411
|
|
412 ::
|
|
413
|
|
414 $ gnatmake winprog -largs -mwindows
|
|
415
|
|
416 .. _Temporary_Files:
|
|
417
|
|
418 Temporary Files
|
|
419 ---------------
|
|
420
|
|
421 .. index:: Temporary files
|
|
422
|
|
423 It is possible to control where temporary files gets created by setting
|
|
424 the :envvar:`TMP` environment variable. The file will be created:
|
|
425
|
|
426 * Under the directory pointed to by the :envvar:`TMP` environment variable if
|
|
427 this directory exists.
|
|
428
|
|
429 * Under :file:`c:\\temp`, if the :envvar:`TMP` environment variable is not
|
|
430 set (or not pointing to a directory) and if this directory exists.
|
|
431
|
|
432 * Under the current working directory otherwise.
|
|
433
|
|
434 This allows you to determine exactly where the temporary
|
|
435 file will be created. This is particularly useful in networked
|
|
436 environments where you may not have write access to some
|
|
437 directories.
|
|
438
|
|
439 Disabling Command Line Argument Expansion
|
|
440 -----------------------------------------
|
|
441
|
|
442 .. index:: Command Line Argument Expansion
|
|
443
|
|
444 By default, an executable compiled for the Windows platform will do
|
|
445 the following postprocessing on the arguments passed on the command
|
|
446 line:
|
|
447
|
|
448 * If the argument contains the characters ``*`` and/or ``?``, then
|
|
449 file expansion will be attempted. For example, if the current directory
|
|
450 contains :file:`a.txt` and :file:`b.txt`, then when calling::
|
|
451
|
|
452 $ my_ada_program *.txt
|
|
453
|
|
454 The following arguments will effectively be passed to the main program
|
|
455 (for example when using ``Ada.Command_Line.Argument``)::
|
|
456
|
|
457 Ada.Command_Line.Argument (1) -> "a.txt"
|
|
458 Ada.Command_Line.Argument (2) -> "b.txt"
|
|
459
|
|
460 * Filename expansion can be disabled for a given argument by using single
|
|
461 quotes. Thus, calling::
|
|
462
|
|
463 $ my_ada_program '*.txt'
|
|
464
|
|
465 will result in::
|
|
466
|
|
467 Ada.Command_Line.Argument (1) -> "*.txt"
|
|
468
|
|
469 Note that if the program is launched from a shell such as Cygwin Bash
|
|
470 then quote removal might be performed by the shell.
|
|
471
|
|
472 In some contexts it might be useful to disable this feature (for example if
|
|
473 the program performs its own argument expansion). In order to do this, a C
|
|
474 symbol needs to be defined and set to ``0``. You can do this by
|
|
475 adding the following code fragment in one of your Ada units:
|
|
476
|
|
477 .. code-block:: ada
|
|
478
|
|
479 Do_Argv_Expansion : Integer := 0;
|
|
480 pragma Export (C, Do_Argv_Expansion, "__gnat_do_argv_expansion");
|
|
481
|
|
482 The results of previous examples will be respectively::
|
|
483
|
|
484 Ada.Command_Line.Argument (1) -> "*.txt"
|
|
485
|
|
486 and::
|
|
487
|
|
488 Ada.Command_Line.Argument (1) -> "'*.txt'"
|
|
489
|
|
490
|
|
491 .. _Mixed-Language_Programming_on_Windows:
|
|
492
|
|
493 Mixed-Language Programming on Windows
|
|
494 -------------------------------------
|
|
495
|
|
496 Developing pure Ada applications on Windows is no different than on
|
|
497 other GNAT-supported platforms. However, when developing or porting an
|
|
498 application that contains a mix of Ada and C/C++, the choice of your
|
|
499 Windows C/C++ development environment conditions your overall
|
|
500 interoperability strategy.
|
|
501
|
|
502 If you use ``gcc`` or Microsoft C to compile the non-Ada part of
|
|
503 your application, there are no Windows-specific restrictions that
|
|
504 affect the overall interoperability with your Ada code. If you do want
|
|
505 to use the Microsoft tools for your C++ code, you have two choices:
|
|
506
|
|
507 * Encapsulate your C++ code in a DLL to be linked with your Ada
|
|
508 application. In this case, use the Microsoft or whatever environment to
|
|
509 build the DLL and use GNAT to build your executable
|
|
510 (:ref:`Using_DLLs_with_GNAT`).
|
|
511
|
|
512 * Or you can encapsulate your Ada code in a DLL to be linked with the
|
|
513 other part of your application. In this case, use GNAT to build the DLL
|
|
514 (:ref:`Building_DLLs_with_GNAT_Project_files`) and use the Microsoft
|
|
515 or whatever environment to build your executable.
|
|
516
|
|
517 In addition to the description about C main in
|
|
518 :ref:`Mixed_Language_Programming` section, if the C main uses a
|
|
519 stand-alone library it is required on x86-windows to
|
|
520 setup the SEH context. For this the C main must looks like this:
|
|
521
|
|
522
|
|
523 .. code-block:: c
|
|
524
|
|
525 /* main.c */
|
|
526 extern void adainit (void);
|
|
527 extern void adafinal (void);
|
|
528 extern void __gnat_initialize(void*);
|
|
529 extern void call_to_ada (void);
|
|
530
|
|
531 int main (int argc, char *argv[])
|
|
532 {
|
|
533 int SEH [2];
|
|
534
|
|
535 /* Initialize the SEH context */
|
|
536 __gnat_initialize (&SEH);
|
|
537
|
|
538 adainit();
|
|
539
|
|
540 /* Then call Ada services in the stand-alone library */
|
|
541
|
|
542 call_to_ada();
|
|
543
|
|
544 adafinal();
|
|
545 }
|
|
546
|
|
547 Note that this is not needed on x86_64-windows where the Windows
|
|
548 native SEH support is used.
|
|
549
|
|
550
|
|
551 .. _Windows_Calling_Conventions:
|
|
552
|
|
553 Windows Calling Conventions
|
|
554 ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
555
|
|
556 .. index:: Stdcall
|
|
557 .. index:: APIENTRY
|
|
558
|
|
559 This section pertain only to Win32. On Win64 there is a single native
|
|
560 calling convention. All convention specifiers are ignored on this
|
|
561 platform.
|
|
562
|
|
563 When a subprogram ``F`` (caller) calls a subprogram ``G``
|
|
564 (callee), there are several ways to push ``G``\ 's parameters on the
|
|
565 stack and there are several possible scenarios to clean up the stack
|
|
566 upon ``G``\ 's return. A calling convention is an agreed upon software
|
|
567 protocol whereby the responsibilities between the caller (``F``) and
|
|
568 the callee (``G``) are clearly defined. Several calling conventions
|
|
569 are available for Windows:
|
|
570
|
|
571 * ``C`` (Microsoft defined)
|
|
572
|
|
573 * ``Stdcall`` (Microsoft defined)
|
|
574
|
|
575 * ``Win32`` (GNAT specific)
|
|
576
|
|
577 * ``DLL`` (GNAT specific)
|
|
578
|
|
579
|
|
580 .. _C_Calling_Convention:
|
|
581
|
|
582 ``C`` Calling Convention
|
|
583 """"""""""""""""""""""""
|
|
584
|
|
585 This is the default calling convention used when interfacing to C/C++
|
|
586 routines compiled with either ``gcc`` or Microsoft Visual C++.
|
|
587
|
|
588 In the ``C`` calling convention subprogram parameters are pushed on the
|
|
589 stack by the caller from right to left. The caller itself is in charge of
|
|
590 cleaning up the stack after the call. In addition, the name of a routine
|
|
591 with ``C`` calling convention is mangled by adding a leading underscore.
|
|
592
|
|
593 The name to use on the Ada side when importing (or exporting) a routine
|
|
594 with ``C`` calling convention is the name of the routine. For
|
|
595 instance the C function:
|
|
596
|
|
597 ::
|
|
598
|
|
599 int get_val (long);
|
|
600
|
|
601 should be imported from Ada as follows:
|
|
602
|
|
603 .. code-block:: ada
|
|
604
|
|
605 function Get_Val (V : Interfaces.C.long) return Interfaces.C.int;
|
|
606 pragma Import (C, Get_Val, External_Name => "get_val");
|
|
607
|
|
608 Note that in this particular case the ``External_Name`` parameter could
|
|
609 have been omitted since, when missing, this parameter is taken to be the
|
|
610 name of the Ada entity in lower case. When the ``Link_Name`` parameter
|
|
611 is missing, as in the above example, this parameter is set to be the
|
|
612 ``External_Name`` with a leading underscore.
|
|
613
|
|
614 When importing a variable defined in C, you should always use the ``C``
|
|
615 calling convention unless the object containing the variable is part of a
|
|
616 DLL (in which case you should use the ``Stdcall`` calling
|
|
617 convention, :ref:`Stdcall_Calling_Convention`).
|
|
618
|
|
619
|
|
620 .. _Stdcall_Calling_Convention:
|
|
621
|
|
622 ``Stdcall`` Calling Convention
|
|
623 """"""""""""""""""""""""""""""
|
|
624
|
|
625 This convention, which was the calling convention used for Pascal
|
|
626 programs, is used by Microsoft for all the routines in the Win32 API for
|
|
627 efficiency reasons. It must be used to import any routine for which this
|
|
628 convention was specified.
|
|
629
|
|
630 In the ``Stdcall`` calling convention subprogram parameters are pushed
|
|
631 on the stack by the caller from right to left. The callee (and not the
|
|
632 caller) is in charge of cleaning the stack on routine exit. In addition,
|
|
633 the name of a routine with ``Stdcall`` calling convention is mangled by
|
|
634 adding a leading underscore (as for the ``C`` calling convention) and a
|
|
635 trailing :samp:`@{nn}`, where ``nn`` is the overall size (in
|
|
636 bytes) of the parameters passed to the routine.
|
|
637
|
|
638 The name to use on the Ada side when importing a C routine with a
|
|
639 ``Stdcall`` calling convention is the name of the C routine. The leading
|
|
640 underscore and trailing :samp:`@{nn}` are added automatically by
|
|
641 the compiler. For instance the Win32 function:
|
|
642
|
|
643 ::
|
|
644
|
|
645 APIENTRY int get_val (long);
|
|
646
|
|
647 should be imported from Ada as follows:
|
|
648
|
|
649 .. code-block:: ada
|
|
650
|
|
651 function Get_Val (V : Interfaces.C.long) return Interfaces.C.int;
|
|
652 pragma Import (Stdcall, Get_Val);
|
|
653 -- On the x86 a long is 4 bytes, so the Link_Name is "_get_val@4"
|
|
654
|
|
655 As for the ``C`` calling convention, when the ``External_Name``
|
|
656 parameter is missing, it is taken to be the name of the Ada entity in lower
|
|
657 case. If instead of writing the above import pragma you write:
|
|
658
|
|
659 .. code-block:: ada
|
|
660
|
|
661 function Get_Val (V : Interfaces.C.long) return Interfaces.C.int;
|
|
662 pragma Import (Stdcall, Get_Val, External_Name => "retrieve_val");
|
|
663
|
|
664 then the imported routine is ``_retrieve_val@4``. However, if instead
|
|
665 of specifying the ``External_Name`` parameter you specify the
|
|
666 ``Link_Name`` as in the following example:
|
|
667
|
|
668 .. code-block:: ada
|
|
669
|
|
670 function Get_Val (V : Interfaces.C.long) return Interfaces.C.int;
|
|
671 pragma Import (Stdcall, Get_Val, Link_Name => "retrieve_val");
|
|
672
|
|
673 then the imported routine is ``retrieve_val``, that is, there is no
|
|
674 decoration at all. No leading underscore and no Stdcall suffix
|
|
675 :samp:`@{nn}`.
|
|
676
|
|
677 This is especially important as in some special cases a DLL's entry
|
|
678 point name lacks a trailing :samp:`@{nn}` while the exported
|
|
679 name generated for a call has it.
|
|
680
|
|
681 It is also possible to import variables defined in a DLL by using an
|
|
682 import pragma for a variable. As an example, if a DLL contains a
|
|
683 variable defined as:
|
|
684
|
|
685 .. code-block:: c
|
|
686
|
|
687 int my_var;
|
|
688
|
|
689 then, to access this variable from Ada you should write:
|
|
690
|
|
691 .. code-block:: ada
|
|
692
|
|
693 My_Var : Interfaces.C.int;
|
|
694 pragma Import (Stdcall, My_Var);
|
|
695
|
|
696 Note that to ease building cross-platform bindings this convention
|
|
697 will be handled as a ``C`` calling convention on non-Windows platforms.
|
|
698
|
|
699
|
|
700 .. _Win32_Calling_Convention:
|
|
701
|
|
702 ``Win32`` Calling Convention
|
|
703 """"""""""""""""""""""""""""
|
|
704
|
|
705 This convention, which is GNAT-specific is fully equivalent to the
|
|
706 ``Stdcall`` calling convention described above.
|
|
707
|
|
708
|
|
709 .. _DLL_Calling_Convention:
|
|
710
|
|
711 ``DLL`` Calling Convention
|
|
712 """"""""""""""""""""""""""
|
|
713
|
|
714 This convention, which is GNAT-specific is fully equivalent to the
|
|
715 ``Stdcall`` calling convention described above.
|
|
716
|
|
717
|
|
718 .. _Introduction_to_Dynamic_Link_Libraries_DLLs:
|
|
719
|
|
720 Introduction to Dynamic Link Libraries (DLLs)
|
|
721 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
722
|
|
723 .. index:: DLL
|
|
724
|
|
725 A Dynamically Linked Library (DLL) is a library that can be shared by
|
|
726 several applications running under Windows. A DLL can contain any number of
|
|
727 routines and variables.
|
|
728
|
|
729 One advantage of DLLs is that you can change and enhance them without
|
|
730 forcing all the applications that depend on them to be relinked or
|
|
731 recompiled. However, you should be aware than all calls to DLL routines are
|
|
732 slower since, as you will understand below, such calls are indirect.
|
|
733
|
|
734 To illustrate the remainder of this section, suppose that an application
|
|
735 wants to use the services of a DLL :file:`API.dll`. To use the services
|
|
736 provided by :file:`API.dll` you must statically link against the DLL or
|
|
737 an import library which contains a jump table with an entry for each
|
|
738 routine and variable exported by the DLL. In the Microsoft world this
|
|
739 import library is called :file:`API.lib`. When using GNAT this import
|
|
740 library is called either :file:`libAPI.dll.a`, :file:`libapi.dll.a`,
|
|
741 :file:`libAPI.a` or :file:`libapi.a` (names are case insensitive).
|
|
742
|
|
743 After you have linked your application with the DLL or the import library
|
|
744 and you run your application, here is what happens:
|
|
745
|
|
746 * Your application is loaded into memory.
|
|
747
|
|
748 * The DLL :file:`API.dll` is mapped into the address space of your
|
|
749 application. This means that:
|
|
750
|
|
751 - The DLL will use the stack of the calling thread.
|
|
752
|
|
753 - The DLL will use the virtual address space of the calling process.
|
|
754
|
|
755 - The DLL will allocate memory from the virtual address space of the calling
|
|
756 process.
|
|
757
|
|
758 - Handles (pointers) can be safely exchanged between routines in the DLL
|
|
759 routines and routines in the application using the DLL.
|
|
760
|
|
761 * The entries in the jump table (from the import library :file:`libAPI.dll.a`
|
|
762 or :file:`API.lib` or automatically created when linking against a DLL)
|
|
763 which is part of your application are initialized with the addresses
|
|
764 of the routines and variables in :file:`API.dll`.
|
|
765
|
|
766 * If present in :file:`API.dll`, routines ``DllMain`` or
|
|
767 ``DllMainCRTStartup`` are invoked. These routines typically contain
|
|
768 the initialization code needed for the well-being of the routines and
|
|
769 variables exported by the DLL.
|
|
770
|
|
771 There is an additional point which is worth mentioning. In the Windows
|
|
772 world there are two kind of DLLs: relocatable and non-relocatable
|
|
773 DLLs. Non-relocatable DLLs can only be loaded at a very specific address
|
|
774 in the target application address space. If the addresses of two
|
|
775 non-relocatable DLLs overlap and these happen to be used by the same
|
|
776 application, a conflict will occur and the application will run
|
|
777 incorrectly. Hence, when possible, it is always preferable to use and
|
|
778 build relocatable DLLs. Both relocatable and non-relocatable DLLs are
|
|
779 supported by GNAT. Note that the :switch:`-s` linker option (see GNU Linker
|
|
780 User's Guide) removes the debugging symbols from the DLL but the DLL can
|
|
781 still be relocated.
|
|
782
|
|
783 As a side note, an interesting difference between Microsoft DLLs and
|
|
784 Unix shared libraries, is the fact that on most Unix systems all public
|
|
785 routines are exported by default in a Unix shared library, while under
|
|
786 Windows it is possible (but not required) to list exported routines in
|
|
787 a definition file (see :ref:`The Definition File <The_Definition_File>`).
|
|
788
|
|
789
|
|
790 .. _Using_DLLs_with_GNAT:
|
|
791
|
|
792 Using DLLs with GNAT
|
|
793 ^^^^^^^^^^^^^^^^^^^^
|
|
794
|
|
795 To use the services of a DLL, say :file:`API.dll`, in your Ada application
|
|
796 you must have:
|
|
797
|
|
798 * The Ada spec for the routines and/or variables you want to access in
|
|
799 :file:`API.dll`. If not available this Ada spec must be built from the C/C++
|
|
800 header files provided with the DLL.
|
|
801
|
|
802 * The import library (:file:`libAPI.dll.a` or :file:`API.lib`). As previously
|
|
803 mentioned an import library is a statically linked library containing the
|
|
804 import table which will be filled at load time to point to the actual
|
|
805 :file:`API.dll` routines. Sometimes you don't have an import library for the
|
|
806 DLL you want to use. The following sections will explain how to build
|
|
807 one. Note that this is optional.
|
|
808
|
|
809 * The actual DLL, :file:`API.dll`.
|
|
810
|
|
811 Once you have all the above, to compile an Ada application that uses the
|
|
812 services of :file:`API.dll` and whose main subprogram is ``My_Ada_App``,
|
|
813 you simply issue the command
|
|
814
|
|
815 ::
|
|
816
|
|
817 $ gnatmake my_ada_app -largs -lAPI
|
|
818
|
|
819 The argument :switch:`-largs -lAPI` at the end of the ``gnatmake`` command
|
|
820 tells the GNAT linker to look for an import library. The linker will
|
|
821 look for a library name in this specific order:
|
|
822
|
|
823 * :file:`libAPI.dll.a`
|
|
824 * :file:`API.dll.a`
|
|
825 * :file:`libAPI.a`
|
|
826 * :file:`API.lib`
|
|
827 * :file:`libAPI.dll`
|
|
828 * :file:`API.dll`
|
|
829
|
|
830 The first three are the GNU style import libraries. The third is the
|
|
831 Microsoft style import libraries. The last two are the actual DLL names.
|
|
832
|
|
833 Note that if the Ada package spec for :file:`API.dll` contains the
|
|
834 following pragma
|
|
835
|
|
836 .. code-block:: ada
|
|
837
|
|
838 pragma Linker_Options ("-lAPI");
|
|
839
|
|
840 you do not have to add :switch:`-largs -lAPI` at the end of the
|
|
841 ``gnatmake`` command.
|
|
842
|
|
843 If any one of the items above is missing you will have to create it
|
|
844 yourself. The following sections explain how to do so using as an
|
|
845 example a fictitious DLL called :file:`API.dll`.
|
|
846
|
|
847
|
|
848 .. _Creating_an_Ada_Spec_for_the_DLL_Services:
|
|
849
|
|
850 Creating an Ada Spec for the DLL Services
|
|
851 """""""""""""""""""""""""""""""""""""""""
|
|
852
|
|
853 A DLL typically comes with a C/C++ header file which provides the
|
|
854 definitions of the routines and variables exported by the DLL. The Ada
|
|
855 equivalent of this header file is a package spec that contains definitions
|
|
856 for the imported entities. If the DLL you intend to use does not come with
|
|
857 an Ada spec you have to generate one such spec yourself. For example if
|
|
858 the header file of :file:`API.dll` is a file :file:`api.h` containing the
|
|
859 following two definitions:
|
|
860
|
|
861 .. code-block:: c
|
|
862
|
|
863 int some_var;
|
|
864 int get (char *);
|
|
865
|
|
866 then the equivalent Ada spec could be:
|
|
867
|
|
868 .. code-block:: ada
|
|
869
|
|
870 with Interfaces.C.Strings;
|
|
871 package API is
|
|
872 use Interfaces;
|
|
873
|
|
874 Some_Var : C.int;
|
|
875 function Get (Str : C.Strings.Chars_Ptr) return C.int;
|
|
876
|
|
877 private
|
|
878 pragma Import (C, Get);
|
|
879 pragma Import (DLL, Some_Var);
|
|
880 end API;
|
|
881
|
|
882
|
|
883 .. _Creating_an_Import_Library:
|
|
884
|
|
885 Creating an Import Library
|
|
886 """"""""""""""""""""""""""
|
|
887
|
|
888 .. index:: Import library
|
|
889
|
|
890 If a Microsoft-style import library :file:`API.lib` or a GNAT-style
|
|
891 import library :file:`libAPI.dll.a` or :file:`libAPI.a` is available
|
|
892 with :file:`API.dll` you can skip this section. You can also skip this
|
|
893 section if :file:`API.dll` or :file:`libAPI.dll` is built with GNU tools
|
|
894 as in this case it is possible to link directly against the
|
|
895 DLL. Otherwise read on.
|
|
896
|
|
897
|
|
898 .. index:: Definition file
|
|
899
|
|
900 .. _The_Definition_File:
|
|
901
|
|
902 .. rubric:: The Definition File
|
|
903
|
|
904 As previously mentioned, and unlike Unix systems, the list of symbols
|
|
905 that are exported from a DLL must be provided explicitly in Windows.
|
|
906 The main goal of a definition file is precisely that: list the symbols
|
|
907 exported by a DLL. A definition file (usually a file with a ``.def``
|
|
908 suffix) has the following structure:
|
|
909
|
|
910 ::
|
|
911
|
|
912 [LIBRARY ``name``]
|
|
913 [DESCRIPTION ``string``]
|
|
914 EXPORTS
|
|
915 ``symbol1``
|
|
916 ``symbol2``
|
|
917 ...
|
|
918
|
|
919 *LIBRARY name*
|
|
920 This section, which is optional, gives the name of the DLL.
|
|
921
|
|
922
|
|
923 *DESCRIPTION string*
|
|
924 This section, which is optional, gives a description string that will be
|
|
925 embedded in the import library.
|
|
926
|
|
927
|
|
928 *EXPORTS*
|
|
929 This section gives the list of exported symbols (procedures, functions or
|
|
930 variables). For instance in the case of :file:`API.dll` the ``EXPORTS``
|
|
931 section of :file:`API.def` looks like:
|
|
932
|
|
933 ::
|
|
934
|
|
935 EXPORTS
|
|
936 some_var
|
|
937 get
|
|
938
|
|
939 Note that you must specify the correct suffix (:samp:`@{nn}`)
|
|
940 (see :ref:`Windows_Calling_Conventions`) for a Stdcall
|
|
941 calling convention function in the exported symbols list.
|
|
942
|
|
943 There can actually be other sections in a definition file, but these
|
|
944 sections are not relevant to the discussion at hand.
|
|
945
|
|
946
|
|
947 .. _Create_Def_File_Automatically:
|
|
948
|
|
949 .. rubric:: Creating a Definition File Automatically
|
|
950
|
|
951 You can automatically create the definition file :file:`API.def`
|
|
952 (see :ref:`The Definition File <The_Definition_File>`) from a DLL.
|
|
953 For that use the ``dlltool`` program as follows:
|
|
954
|
|
955 ::
|
|
956
|
|
957 $ dlltool API.dll -z API.def --export-all-symbols
|
|
958
|
|
959 Note that if some routines in the DLL have the ``Stdcall`` convention
|
|
960 (:ref:`Windows_Calling_Conventions`) with stripped :samp:`@{nn}`
|
|
961 suffix then you'll have to edit :file:`api.def` to add it, and specify
|
|
962 :switch:`-k` to ``gnatdll`` when creating the import library.
|
|
963
|
|
964 Here are some hints to find the right :samp:`@{nn}` suffix.
|
|
965
|
|
966 - If you have the Microsoft import library (.lib), it is possible to get
|
|
967 the right symbols by using Microsoft ``dumpbin`` tool (see the
|
|
968 corresponding Microsoft documentation for further details).
|
|
969
|
|
970 ::
|
|
971
|
|
972 $ dumpbin /exports api.lib
|
|
973
|
|
974 - If you have a message about a missing symbol at link time the compiler
|
|
975 tells you what symbol is expected. You just have to go back to the
|
|
976 definition file and add the right suffix.
|
|
977
|
|
978
|
|
979 .. _GNAT-Style_Import_Library:
|
|
980
|
|
981 .. rubric:: GNAT-Style Import Library
|
|
982
|
|
983 To create a static import library from :file:`API.dll` with the GNAT tools
|
|
984 you should create the .def file, then use ``gnatdll`` tool
|
|
985 (see :ref:`Using_gnatdll`) as follows:
|
|
986
|
|
987 ::
|
|
988
|
|
989 $ gnatdll -e API.def -d API.dll
|
|
990
|
|
991 ``gnatdll`` takes as input a definition file :file:`API.def` and the
|
|
992 name of the DLL containing the services listed in the definition file
|
|
993 :file:`API.dll`. The name of the static import library generated is
|
|
994 computed from the name of the definition file as follows: if the
|
|
995 definition file name is :file:`xyz.def`, the import library name will
|
|
996 be :file:`libxyz.a`. Note that in the previous example option
|
|
997 :switch:`-e` could have been removed because the name of the definition
|
|
998 file (before the ``.def`` suffix) is the same as the name of the
|
|
999 DLL (:ref:`Using_gnatdll` for more information about ``gnatdll``).
|
|
1000
|
|
1001
|
|
1002 .. _MSVS-Style_Import_Library:
|
|
1003
|
|
1004 .. rubric:: Microsoft-Style Import Library
|
|
1005
|
|
1006 A Microsoft import library is needed only if you plan to make an
|
|
1007 Ada DLL available to applications developed with Microsoft
|
|
1008 tools (:ref:`Mixed-Language_Programming_on_Windows`).
|
|
1009
|
|
1010 To create a Microsoft-style import library for :file:`API.dll` you
|
|
1011 should create the .def file, then build the actual import library using
|
|
1012 Microsoft's ``lib`` utility:
|
|
1013
|
|
1014 ::
|
|
1015
|
|
1016 $ lib -machine:IX86 -def:API.def -out:API.lib
|
|
1017
|
|
1018 If you use the above command the definition file :file:`API.def` must
|
|
1019 contain a line giving the name of the DLL:
|
|
1020
|
|
1021 ::
|
|
1022
|
|
1023 LIBRARY "API"
|
|
1024
|
|
1025 See the Microsoft documentation for further details about the usage of
|
|
1026 ``lib``.
|
|
1027
|
|
1028
|
|
1029 .. _Building_DLLs_with_GNAT_Project_files:
|
|
1030
|
|
1031 Building DLLs with GNAT Project files
|
|
1032 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
1033
|
|
1034 .. index:: DLLs, building
|
|
1035
|
|
1036 There is nothing specific to Windows in the build process.
|
|
1037 See the *Library Projects* section in the *GNAT Project Manager*
|
|
1038 chapter of the *GPRbuild User's Guide*.
|
|
1039
|
|
1040 Due to a system limitation, it is not possible under Windows to create threads
|
|
1041 when inside the ``DllMain`` routine which is used for auto-initialization
|
|
1042 of shared libraries, so it is not possible to have library level tasks in SALs.
|
|
1043
|
|
1044
|
|
1045 .. _Building_DLLs_with_GNAT:
|
|
1046
|
|
1047 Building DLLs with GNAT
|
|
1048 ^^^^^^^^^^^^^^^^^^^^^^^
|
|
1049
|
|
1050 .. index:: DLLs, building
|
|
1051
|
|
1052 This section explain how to build DLLs using the GNAT built-in DLL
|
|
1053 support. With the following procedure it is straight forward to build
|
|
1054 and use DLLs with GNAT.
|
|
1055
|
|
1056
|
|
1057 * Building object files.
|
|
1058 The first step is to build all objects files that are to be included
|
|
1059 into the DLL. This is done by using the standard ``gnatmake`` tool.
|
|
1060
|
|
1061 * Building the DLL.
|
|
1062 To build the DLL you must use the ``gcc`` :switch:`-shared` and
|
|
1063 :switch:`-shared-libgcc` options. It is quite simple to use this method:
|
|
1064
|
|
1065 ::
|
|
1066
|
|
1067 $ gcc -shared -shared-libgcc -o api.dll obj1.o obj2.o ...
|
|
1068
|
|
1069 It is important to note that in this case all symbols found in the
|
|
1070 object files are automatically exported. It is possible to restrict
|
|
1071 the set of symbols to export by passing to ``gcc`` a definition
|
|
1072 file (see :ref:`The Definition File <The_Definition_File>`).
|
|
1073 For example:
|
|
1074
|
|
1075 ::
|
|
1076
|
|
1077 $ gcc -shared -shared-libgcc -o api.dll api.def obj1.o obj2.o ...
|
|
1078
|
|
1079 If you use a definition file you must export the elaboration procedures
|
|
1080 for every package that required one. Elaboration procedures are named
|
|
1081 using the package name followed by "_E".
|
|
1082
|
|
1083 * Preparing DLL to be used.
|
|
1084 For the DLL to be used by client programs the bodies must be hidden
|
|
1085 from it and the .ali set with read-only attribute. This is very important
|
|
1086 otherwise GNAT will recompile all packages and will not actually use
|
|
1087 the code in the DLL. For example:
|
|
1088
|
|
1089 ::
|
|
1090
|
|
1091 $ mkdir apilib
|
|
1092 $ copy *.ads *.ali api.dll apilib
|
|
1093 $ attrib +R apilib\\*.ali
|
|
1094
|
|
1095 At this point it is possible to use the DLL by directly linking
|
|
1096 against it. Note that you must use the GNAT shared runtime when using
|
|
1097 GNAT shared libraries. This is achieved by using the :switch:`-shared` binder
|
|
1098 option.
|
|
1099
|
|
1100 ::
|
|
1101
|
|
1102 $ gnatmake main -Iapilib -bargs -shared -largs -Lapilib -lAPI
|
|
1103
|
|
1104
|
|
1105 .. _Building_DLLs_with_gnatdll:
|
|
1106
|
|
1107 Building DLLs with gnatdll
|
|
1108 ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
1109
|
|
1110 .. index:: DLLs, building
|
|
1111
|
|
1112 Note that it is preferred to use GNAT Project files
|
|
1113 (:ref:`Building_DLLs_with_GNAT_Project_files`) or the built-in GNAT
|
|
1114 DLL support (:ref:`Building_DLLs_with_GNAT`) or to build DLLs.
|
|
1115
|
|
1116 This section explains how to build DLLs containing Ada code using
|
|
1117 ``gnatdll``. These DLLs will be referred to as Ada DLLs in the
|
|
1118 remainder of this section.
|
|
1119
|
|
1120 The steps required to build an Ada DLL that is to be used by Ada as well as
|
|
1121 non-Ada applications are as follows:
|
|
1122
|
|
1123 * You need to mark each Ada entity exported by the DLL with a ``C`` or
|
|
1124 ``Stdcall`` calling convention to avoid any Ada name mangling for the
|
|
1125 entities exported by the DLL
|
|
1126 (see :ref:`Exporting Ada Entities <Exporting_Ada_Entities>`). You can
|
|
1127 skip this step if you plan to use the Ada DLL only from Ada applications.
|
|
1128
|
|
1129 * Your Ada code must export an initialization routine which calls the routine
|
|
1130 ``adainit`` generated by ``gnatbind`` to perform the elaboration of
|
|
1131 the Ada code in the DLL (:ref:`Ada_DLLs_and_Elaboration`). The initialization
|
|
1132 routine exported by the Ada DLL must be invoked by the clients of the DLL
|
|
1133 to initialize the DLL.
|
|
1134
|
|
1135 * When useful, the DLL should also export a finalization routine which calls
|
|
1136 routine ``adafinal`` generated by ``gnatbind`` to perform the
|
|
1137 finalization of the Ada code in the DLL (:ref:`Ada_DLLs_and_Finalization`).
|
|
1138 The finalization routine exported by the Ada DLL must be invoked by the
|
|
1139 clients of the DLL when the DLL services are no further needed.
|
|
1140
|
|
1141 * You must provide a spec for the services exported by the Ada DLL in each
|
|
1142 of the programming languages to which you plan to make the DLL available.
|
|
1143
|
|
1144 * You must provide a definition file listing the exported entities
|
|
1145 (:ref:`The Definition File <The_Definition_File>`).
|
|
1146
|
|
1147 * Finally you must use ``gnatdll`` to produce the DLL and the import
|
|
1148 library (:ref:`Using_gnatdll`).
|
|
1149
|
|
1150 Note that a relocatable DLL stripped using the ``strip``
|
|
1151 binutils tool will not be relocatable anymore. To build a DLL without
|
|
1152 debug information pass :switch:`-largs -s` to ``gnatdll``. This
|
|
1153 restriction does not apply to a DLL built using a Library Project.
|
|
1154 See the *Library Projects* section in the *GNAT Project Manager*
|
|
1155 chapter of the *GPRbuild User's Guide*.
|
|
1156
|
|
1157
|
|
1158 .. Limitations_When_Using_Ada_DLLs_from Ada:
|
|
1159
|
|
1160 Limitations When Using Ada DLLs from Ada
|
|
1161 """"""""""""""""""""""""""""""""""""""""
|
|
1162
|
|
1163 When using Ada DLLs from Ada applications there is a limitation users
|
|
1164 should be aware of. Because on Windows the GNAT run-time is not in a DLL of
|
|
1165 its own, each Ada DLL includes a part of the GNAT run-time. Specifically,
|
|
1166 each Ada DLL includes the services of the GNAT run-time that are necessary
|
|
1167 to the Ada code inside the DLL. As a result, when an Ada program uses an
|
|
1168 Ada DLL there are two independent GNAT run-times: one in the Ada DLL and
|
|
1169 one in the main program.
|
|
1170
|
|
1171 It is therefore not possible to exchange GNAT run-time objects between the
|
|
1172 Ada DLL and the main Ada program. Example of GNAT run-time objects are file
|
|
1173 handles (e.g., ``Text_IO.File_Type``), tasks types, protected objects
|
|
1174 types, etc.
|
|
1175
|
|
1176 It is completely safe to exchange plain elementary, array or record types,
|
|
1177 Windows object handles, etc.
|
|
1178
|
|
1179
|
|
1180 .. _Exporting_Ada_Entities:
|
|
1181
|
|
1182 Exporting Ada Entities
|
|
1183 """"""""""""""""""""""
|
|
1184
|
|
1185 .. index:: Export table
|
|
1186
|
|
1187 Building a DLL is a way to encapsulate a set of services usable from any
|
|
1188 application. As a result, the Ada entities exported by a DLL should be
|
|
1189 exported with the ``C`` or ``Stdcall`` calling conventions to avoid
|
|
1190 any Ada name mangling. As an example here is an Ada package
|
|
1191 ``API``, spec and body, exporting two procedures, a function, and a
|
|
1192 variable:
|
|
1193
|
|
1194
|
|
1195 .. code-block:: ada
|
|
1196
|
|
1197 with Interfaces.C; use Interfaces;
|
|
1198 package API is
|
|
1199 Count : C.int := 0;
|
|
1200 function Factorial (Val : C.int) return C.int;
|
|
1201
|
|
1202 procedure Initialize_API;
|
|
1203 procedure Finalize_API;
|
|
1204 -- Initialization & Finalization routines. More in the next section.
|
|
1205 private
|
|
1206 pragma Export (C, Initialize_API);
|
|
1207 pragma Export (C, Finalize_API);
|
|
1208 pragma Export (C, Count);
|
|
1209 pragma Export (C, Factorial);
|
|
1210 end API;
|
|
1211
|
|
1212 .. code-block:: ada
|
|
1213
|
|
1214 package body API is
|
|
1215 function Factorial (Val : C.int) return C.int is
|
|
1216 Fact : C.int := 1;
|
|
1217 begin
|
|
1218 Count := Count + 1;
|
|
1219 for K in 1 .. Val loop
|
|
1220 Fact := Fact * K;
|
|
1221 end loop;
|
|
1222 return Fact;
|
|
1223 end Factorial;
|
|
1224
|
|
1225 procedure Initialize_API is
|
|
1226 procedure Adainit;
|
|
1227 pragma Import (C, Adainit);
|
|
1228 begin
|
|
1229 Adainit;
|
|
1230 end Initialize_API;
|
|
1231
|
|
1232 procedure Finalize_API is
|
|
1233 procedure Adafinal;
|
|
1234 pragma Import (C, Adafinal);
|
|
1235 begin
|
|
1236 Adafinal;
|
|
1237 end Finalize_API;
|
|
1238 end API;
|
|
1239
|
|
1240 If the Ada DLL you are building will only be used by Ada applications
|
|
1241 you do not have to export Ada entities with a ``C`` or ``Stdcall``
|
|
1242 convention. As an example, the previous package could be written as
|
|
1243 follows:
|
|
1244
|
|
1245 .. code-block:: ada
|
|
1246
|
|
1247 package API is
|
|
1248 Count : Integer := 0;
|
|
1249 function Factorial (Val : Integer) return Integer;
|
|
1250
|
|
1251 procedure Initialize_API;
|
|
1252 procedure Finalize_API;
|
|
1253 -- Initialization and Finalization routines.
|
|
1254 end API;
|
|
1255
|
|
1256 .. code-block:: ada
|
|
1257
|
|
1258 package body API is
|
|
1259 function Factorial (Val : Integer) return Integer is
|
|
1260 Fact : Integer := 1;
|
|
1261 begin
|
|
1262 Count := Count + 1;
|
|
1263 for K in 1 .. Val loop
|
|
1264 Fact := Fact * K;
|
|
1265 end loop;
|
|
1266 return Fact;
|
|
1267 end Factorial;
|
|
1268
|
|
1269 ...
|
|
1270 -- The remainder of this package body is unchanged.
|
|
1271 end API;
|
|
1272
|
|
1273 Note that if you do not export the Ada entities with a ``C`` or
|
|
1274 ``Stdcall`` convention you will have to provide the mangled Ada names
|
|
1275 in the definition file of the Ada DLL
|
|
1276 (:ref:`Creating_the_Definition_File`).
|
|
1277
|
|
1278
|
|
1279 .. _Ada_DLLs_and_Elaboration:
|
|
1280
|
|
1281 Ada DLLs and Elaboration
|
|
1282 """"""""""""""""""""""""
|
|
1283
|
|
1284 .. index:: DLLs and elaboration
|
|
1285
|
|
1286 The DLL that you are building contains your Ada code as well as all the
|
|
1287 routines in the Ada library that are needed by it. The first thing a
|
|
1288 user of your DLL must do is elaborate the Ada code
|
|
1289 (:ref:`Elaboration_Order_Handling_in_GNAT`).
|
|
1290
|
|
1291 To achieve this you must export an initialization routine
|
|
1292 (``Initialize_API`` in the previous example), which must be invoked
|
|
1293 before using any of the DLL services. This elaboration routine must call
|
|
1294 the Ada elaboration routine ``adainit`` generated by the GNAT binder
|
|
1295 (:ref:`Binding_with_Non-Ada_Main_Programs`). See the body of
|
|
1296 ``Initialize_Api`` for an example. Note that the GNAT binder is
|
|
1297 automatically invoked during the DLL build process by the ``gnatdll``
|
|
1298 tool (:ref:`Using_gnatdll`).
|
|
1299
|
|
1300 When a DLL is loaded, Windows systematically invokes a routine called
|
|
1301 ``DllMain``. It would therefore be possible to call ``adainit``
|
|
1302 directly from ``DllMain`` without having to provide an explicit
|
|
1303 initialization routine. Unfortunately, it is not possible to call
|
|
1304 ``adainit`` from the ``DllMain`` if your program has library level
|
|
1305 tasks because access to the ``DllMain`` entry point is serialized by
|
|
1306 the system (that is, only a single thread can execute 'through' it at a
|
|
1307 time), which means that the GNAT run-time will deadlock waiting for the
|
|
1308 newly created task to complete its initialization.
|
|
1309
|
|
1310
|
|
1311 .. _Ada_DLLs_and_Finalization:
|
|
1312
|
|
1313 Ada DLLs and Finalization
|
|
1314 ^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
1315
|
|
1316 .. index:: DLLs and finalization
|
|
1317
|
|
1318 When the services of an Ada DLL are no longer needed, the client code should
|
|
1319 invoke the DLL finalization routine, if available. The DLL finalization
|
|
1320 routine is in charge of releasing all resources acquired by the DLL. In the
|
|
1321 case of the Ada code contained in the DLL, this is achieved by calling
|
|
1322 routine ``adafinal`` generated by the GNAT binder
|
|
1323 (:ref:`Binding_with_Non-Ada_Main_Programs`).
|
|
1324 See the body of ``Finalize_Api`` for an
|
|
1325 example. As already pointed out the GNAT binder is automatically invoked
|
|
1326 during the DLL build process by the ``gnatdll`` tool
|
|
1327 (:ref:`Using_gnatdll`).
|
|
1328
|
|
1329
|
|
1330 .. _Creating_a_Spec_for_Ada_DLLs:
|
|
1331
|
|
1332 Creating a Spec for Ada DLLs
|
|
1333 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
1334
|
|
1335 To use the services exported by the Ada DLL from another programming
|
|
1336 language (e.g., C), you have to translate the specs of the exported Ada
|
|
1337 entities in that language. For instance in the case of ``API.dll``,
|
|
1338 the corresponding C header file could look like:
|
|
1339
|
|
1340 .. code-block:: c
|
|
1341
|
|
1342 extern int *_imp__count;
|
|
1343 #define count (*_imp__count)
|
|
1344 int factorial (int);
|
|
1345
|
|
1346 It is important to understand that when building an Ada DLL to be used by
|
|
1347 other Ada applications, you need two different specs for the packages
|
|
1348 contained in the DLL: one for building the DLL and the other for using
|
|
1349 the DLL. This is because the ``DLL`` calling convention is needed to
|
|
1350 use a variable defined in a DLL, but when building the DLL, the variable
|
|
1351 must have either the ``Ada`` or ``C`` calling convention. As an
|
|
1352 example consider a DLL comprising the following package ``API``:
|
|
1353
|
|
1354 .. code-block:: ada
|
|
1355
|
|
1356 package API is
|
|
1357 Count : Integer := 0;
|
|
1358 ...
|
|
1359 -- Remainder of the package omitted.
|
|
1360 end API;
|
|
1361
|
|
1362 After producing a DLL containing package ``API``, the spec that
|
|
1363 must be used to import ``API.Count`` from Ada code outside of the
|
|
1364 DLL is:
|
|
1365
|
|
1366 .. code-block:: ada
|
|
1367
|
|
1368 package API is
|
|
1369 Count : Integer;
|
|
1370 pragma Import (DLL, Count);
|
|
1371 end API;
|
|
1372
|
|
1373
|
|
1374 .. _Creating_the_Definition_File:
|
|
1375
|
|
1376 Creating the Definition File
|
|
1377 """"""""""""""""""""""""""""
|
|
1378
|
|
1379 The definition file is the last file needed to build the DLL. It lists
|
|
1380 the exported symbols. As an example, the definition file for a DLL
|
|
1381 containing only package ``API`` (where all the entities are exported
|
|
1382 with a ``C`` calling convention) is:
|
|
1383
|
|
1384 ::
|
|
1385
|
|
1386 EXPORTS
|
|
1387 count
|
|
1388 factorial
|
|
1389 finalize_api
|
|
1390 initialize_api
|
|
1391
|
|
1392 If the ``C`` calling convention is missing from package ``API``,
|
|
1393 then the definition file contains the mangled Ada names of the above
|
|
1394 entities, which in this case are:
|
|
1395
|
|
1396 ::
|
|
1397
|
|
1398 EXPORTS
|
|
1399 api__count
|
|
1400 api__factorial
|
|
1401 api__finalize_api
|
|
1402 api__initialize_api
|
|
1403
|
|
1404
|
|
1405 .. _Using_gnatdll:
|
|
1406
|
|
1407 Using ``gnatdll``
|
|
1408 """""""""""""""""
|
|
1409
|
|
1410 .. index:: gnatdll
|
|
1411
|
|
1412 ``gnatdll`` is a tool to automate the DLL build process once all the Ada
|
|
1413 and non-Ada sources that make up your DLL have been compiled.
|
|
1414 ``gnatdll`` is actually in charge of two distinct tasks: build the
|
|
1415 static import library for the DLL and the actual DLL. The form of the
|
|
1416 ``gnatdll`` command is
|
|
1417
|
|
1418 ::
|
|
1419
|
|
1420 $ gnatdll [ switches ] list-of-files [ -largs opts ]
|
|
1421
|
|
1422 where ``list-of-files`` is a list of ALI and object files. The object
|
|
1423 file list must be the exact list of objects corresponding to the non-Ada
|
|
1424 sources whose services are to be included in the DLL. The ALI file list
|
|
1425 must be the exact list of ALI files for the corresponding Ada sources
|
|
1426 whose services are to be included in the DLL. If ``list-of-files`` is
|
|
1427 missing, only the static import library is generated.
|
|
1428
|
|
1429 You may specify any of the following switches to ``gnatdll``:
|
|
1430
|
|
1431
|
|
1432 .. index:: -a (gnatdll)
|
|
1433
|
|
1434 :switch:`-a[{address}]`
|
|
1435 Build a non-relocatable DLL at ``address``. If ``address`` is not
|
|
1436 specified the default address ``0x11000000`` will be used. By default,
|
|
1437 when this switch is missing, ``gnatdll`` builds relocatable DLL. We
|
|
1438 advise the reader to build relocatable DLL.
|
|
1439
|
|
1440
|
|
1441 .. index:: -b (gnatdll)
|
|
1442
|
|
1443 :switch:`-b {address}`
|
|
1444 Set the relocatable DLL base address. By default the address is
|
|
1445 ``0x11000000``.
|
|
1446
|
|
1447
|
|
1448 .. index:: -bargs (gnatdll)
|
|
1449
|
|
1450 :switch:`-bargs {opts}`
|
|
1451 Binder options. Pass ``opts`` to the binder.
|
|
1452
|
|
1453
|
|
1454 .. index:: -d (gnatdll)
|
|
1455
|
|
1456 :switch:`-d {dllfile}`
|
|
1457 ``dllfile`` is the name of the DLL. This switch must be present for
|
|
1458 ``gnatdll`` to do anything. The name of the generated import library is
|
|
1459 obtained algorithmically from ``dllfile`` as shown in the following
|
|
1460 example: if ``dllfile`` is :file:`xyz.dll`, the import library name is
|
|
1461 :file:`libxyz.dll.a`. The name of the definition file to use (if not specified
|
|
1462 by option :switch:`-e`) is obtained algorithmically from ``dllfile``
|
|
1463 as shown in the following example:
|
|
1464 if ``dllfile`` is :file:`xyz.dll`, the definition
|
|
1465 file used is :file:`xyz.def`.
|
|
1466
|
|
1467
|
|
1468 .. index:: -e (gnatdll)
|
|
1469
|
|
1470 :switch:`-e {deffile}`
|
|
1471 ``deffile`` is the name of the definition file.
|
|
1472
|
|
1473
|
|
1474 .. index:: -g (gnatdll)
|
|
1475
|
|
1476 :switch:`-g`
|
|
1477 Generate debugging information. This information is stored in the object
|
|
1478 file and copied from there to the final DLL file by the linker,
|
|
1479 where it can be read by the debugger. You must use the
|
|
1480 :switch:`-g` switch if you plan on using the debugger or the symbolic
|
|
1481 stack traceback.
|
|
1482
|
|
1483
|
|
1484 .. index:: -h (gnatdll)
|
|
1485
|
|
1486 :switch:`-h`
|
|
1487 Help mode. Displays ``gnatdll`` switch usage information.
|
|
1488
|
|
1489
|
|
1490 .. index:: -I (gnatdll)
|
|
1491
|
|
1492 :switch:`-I{dir}`
|
|
1493 Direct ``gnatdll`` to search the ``dir`` directory for source and
|
|
1494 object files needed to build the DLL.
|
|
1495 (:ref:`Search_Paths_and_the_Run-Time_Library_RTL`).
|
|
1496
|
|
1497
|
|
1498 .. index:: -k (gnatdll)
|
|
1499
|
|
1500 :switch:`-k`
|
|
1501 Removes the :samp:`@{nn}` suffix from the import library's exported
|
|
1502 names, but keeps them for the link names. You must specify this
|
|
1503 option if you want to use a ``Stdcall`` function in a DLL for which
|
|
1504 the :samp:`@{nn}` suffix has been removed. This is the case for most
|
|
1505 of the Windows NT DLL for example. This option has no effect when
|
|
1506 :switch:`-n` option is specified.
|
|
1507
|
|
1508
|
|
1509 .. index:: -l (gnatdll)
|
|
1510
|
|
1511 :switch:`-l {file}`
|
|
1512 The list of ALI and object files used to build the DLL are listed in
|
|
1513 ``file``, instead of being given in the command line. Each line in
|
|
1514 ``file`` contains the name of an ALI or object file.
|
|
1515
|
|
1516
|
|
1517 .. index:: -n (gnatdll)
|
|
1518
|
|
1519 :switch:`-n`
|
|
1520 No Import. Do not create the import library.
|
|
1521
|
|
1522
|
|
1523 .. index:: -q (gnatdll)
|
|
1524
|
|
1525 :switch:`-q`
|
|
1526 Quiet mode. Do not display unnecessary messages.
|
|
1527
|
|
1528
|
|
1529 .. index:: -v (gnatdll)
|
|
1530
|
|
1531 :switch:`-v`
|
|
1532 Verbose mode. Display extra information.
|
|
1533
|
|
1534
|
|
1535 .. index:: -largs (gnatdll)
|
|
1536
|
|
1537 :switch:`-largs {opts}`
|
|
1538 Linker options. Pass ``opts`` to the linker.
|
|
1539
|
|
1540
|
|
1541 .. rubric:: ``gnatdll`` Example
|
|
1542
|
|
1543 As an example the command to build a relocatable DLL from :file:`api.adb`
|
|
1544 once :file:`api.adb` has been compiled and :file:`api.def` created is
|
|
1545
|
|
1546 ::
|
|
1547
|
|
1548 $ gnatdll -d api.dll api.ali
|
|
1549
|
|
1550 The above command creates two files: :file:`libapi.dll.a` (the import
|
|
1551 library) and :file:`api.dll` (the actual DLL). If you want to create
|
|
1552 only the DLL, just type:
|
|
1553
|
|
1554 ::
|
|
1555
|
|
1556 $ gnatdll -d api.dll -n api.ali
|
|
1557
|
|
1558 Alternatively if you want to create just the import library, type:
|
|
1559
|
|
1560 ::
|
|
1561
|
|
1562 $ gnatdll -d api.dll
|
|
1563
|
|
1564
|
|
1565 .. rubric:: ``gnatdll`` behind the Scenes
|
|
1566
|
|
1567 This section details the steps involved in creating a DLL. ``gnatdll``
|
|
1568 does these steps for you. Unless you are interested in understanding what
|
|
1569 goes on behind the scenes, you should skip this section.
|
|
1570
|
|
1571 We use the previous example of a DLL containing the Ada package ``API``,
|
|
1572 to illustrate the steps necessary to build a DLL. The starting point is a
|
|
1573 set of objects that will make up the DLL and the corresponding ALI
|
|
1574 files. In the case of this example this means that :file:`api.o` and
|
|
1575 :file:`api.ali` are available. To build a relocatable DLL, ``gnatdll`` does
|
|
1576 the following:
|
|
1577
|
|
1578 * ``gnatdll`` builds the base file (:file:`api.base`). A base file gives
|
|
1579 the information necessary to generate relocation information for the
|
|
1580 DLL.
|
|
1581
|
|
1582 ::
|
|
1583
|
|
1584 $ gnatbind -n api
|
|
1585 $ gnatlink api -o api.jnk -mdll -Wl,--base-file,api.base
|
|
1586
|
|
1587 In addition to the base file, the ``gnatlink`` command generates an
|
|
1588 output file :file:`api.jnk` which can be discarded. The :switch:`-mdll` switch
|
|
1589 asks ``gnatlink`` to generate the routines ``DllMain`` and
|
|
1590 ``DllMainCRTStartup`` that are called by the Windows loader when the DLL
|
|
1591 is loaded into memory.
|
|
1592
|
|
1593 * ``gnatdll`` uses ``dlltool`` (see :ref:`Using dlltool <Using_dlltool>`) to build the
|
|
1594 export table (:file:`api.exp`). The export table contains the relocation
|
|
1595 information in a form which can be used during the final link to ensure
|
|
1596 that the Windows loader is able to place the DLL anywhere in memory.
|
|
1597
|
|
1598 ::
|
|
1599
|
|
1600 $ dlltool --dllname api.dll --def api.def --base-file api.base \\
|
|
1601 --output-exp api.exp
|
|
1602
|
|
1603 * ``gnatdll`` builds the base file using the new export table. Note that
|
|
1604 ``gnatbind`` must be called once again since the binder generated file
|
|
1605 has been deleted during the previous call to ``gnatlink``.
|
|
1606
|
|
1607 ::
|
|
1608
|
|
1609 $ gnatbind -n api
|
|
1610 $ gnatlink api -o api.jnk api.exp -mdll
|
|
1611 -Wl,--base-file,api.base
|
|
1612
|
|
1613
|
|
1614 * ``gnatdll`` builds the new export table using the new base file and
|
|
1615 generates the DLL import library :file:`libAPI.dll.a`.
|
|
1616
|
|
1617
|
|
1618 ::
|
|
1619
|
|
1620 $ dlltool --dllname api.dll --def api.def --base-file api.base \\
|
|
1621 --output-exp api.exp --output-lib libAPI.a
|
|
1622
|
|
1623 * Finally ``gnatdll`` builds the relocatable DLL using the final export
|
|
1624 table.
|
|
1625
|
|
1626 ::
|
|
1627
|
|
1628 $ gnatbind -n api
|
|
1629 $ gnatlink api api.exp -o api.dll -mdll
|
|
1630
|
|
1631
|
|
1632 .. _Using_dlltool:
|
|
1633
|
|
1634 .. rubric:: Using ``dlltool``
|
|
1635
|
|
1636 ``dlltool`` is the low-level tool used by ``gnatdll`` to build
|
|
1637 DLLs and static import libraries. This section summarizes the most
|
|
1638 common ``dlltool`` switches. The form of the ``dlltool`` command
|
|
1639 is
|
|
1640
|
|
1641 ::
|
|
1642
|
|
1643 $ dlltool [`switches`]
|
|
1644
|
|
1645 ``dlltool`` switches include:
|
|
1646
|
|
1647
|
|
1648 .. index:: --base-file (dlltool)
|
|
1649
|
|
1650 :switch:`--base-file {basefile}`
|
|
1651 Read the base file ``basefile`` generated by the linker. This switch
|
|
1652 is used to create a relocatable DLL.
|
|
1653
|
|
1654
|
|
1655 .. index:: --def (dlltool)
|
|
1656
|
|
1657 :switch:`--def {deffile}`
|
|
1658 Read the definition file.
|
|
1659
|
|
1660
|
|
1661 .. index:: --dllname (dlltool)
|
|
1662
|
|
1663 :switch:`--dllname {name}`
|
|
1664 Gives the name of the DLL. This switch is used to embed the name of the
|
|
1665 DLL in the static import library generated by ``dlltool`` with switch
|
|
1666 :switch:`--output-lib`.
|
|
1667
|
|
1668
|
|
1669 .. index:: -k (dlltool)
|
|
1670
|
|
1671 :switch:`-k`
|
|
1672 Kill :samp:`@{nn}` from exported names
|
|
1673 (:ref:`Windows_Calling_Conventions`
|
|
1674 for a discussion about ``Stdcall``-style symbols.
|
|
1675
|
|
1676
|
|
1677 .. index:: --help (dlltool)
|
|
1678
|
|
1679 :switch:`--help`
|
|
1680 Prints the ``dlltool`` switches with a concise description.
|
|
1681
|
|
1682
|
|
1683 .. index:: --output-exp (dlltool)
|
|
1684
|
|
1685 :switch:`--output-exp {exportfile}`
|
|
1686 Generate an export file ``exportfile``. The export file contains the
|
|
1687 export table (list of symbols in the DLL) and is used to create the DLL.
|
|
1688
|
|
1689
|
|
1690 .. index:: --output-lib (dlltool)
|
|
1691
|
|
1692 :switch:`--output-lib {libfile}`
|
|
1693 Generate a static import library ``libfile``.
|
|
1694
|
|
1695
|
|
1696 .. index:: -v (dlltool)
|
|
1697
|
|
1698 :switch:`-v`
|
|
1699 Verbose mode.
|
|
1700
|
|
1701
|
|
1702 .. index:: --as (dlltool)
|
|
1703
|
|
1704 :switch:`--as {assembler-name}`
|
|
1705 Use ``assembler-name`` as the assembler. The default is ``as``.
|
|
1706
|
|
1707
|
|
1708 .. _GNAT_and_Windows_Resources:
|
|
1709
|
|
1710 GNAT and Windows Resources
|
|
1711 ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
1712
|
|
1713 .. index:: Resources, windows
|
|
1714
|
|
1715 Resources are an easy way to add Windows specific objects to your
|
|
1716 application. The objects that can be added as resources include:
|
|
1717
|
|
1718 * menus
|
|
1719
|
|
1720 * accelerators
|
|
1721
|
|
1722 * dialog boxes
|
|
1723
|
|
1724 * string tables
|
|
1725
|
|
1726 * bitmaps
|
|
1727
|
|
1728 * cursors
|
|
1729
|
|
1730 * icons
|
|
1731
|
|
1732 * fonts
|
|
1733
|
|
1734 * version information
|
|
1735
|
|
1736 For example, a version information resource can be defined as follow and
|
|
1737 embedded into an executable or DLL:
|
|
1738
|
|
1739 A version information resource can be used to embed information into an
|
|
1740 executable or a DLL. These information can be viewed using the file properties
|
|
1741 from the Windows Explorer. Here is an example of a version information
|
|
1742 resource:
|
|
1743
|
|
1744 ::
|
|
1745
|
|
1746 1 VERSIONINFO
|
|
1747 FILEVERSION 1,0,0,0
|
|
1748 PRODUCTVERSION 1,0,0,0
|
|
1749 BEGIN
|
|
1750 BLOCK "StringFileInfo"
|
|
1751 BEGIN
|
|
1752 BLOCK "080904E4"
|
|
1753 BEGIN
|
|
1754 VALUE "CompanyName", "My Company Name"
|
|
1755 VALUE "FileDescription", "My application"
|
|
1756 VALUE "FileVersion", "1.0"
|
|
1757 VALUE "InternalName", "my_app"
|
|
1758 VALUE "LegalCopyright", "My Name"
|
|
1759 VALUE "OriginalFilename", "my_app.exe"
|
|
1760 VALUE "ProductName", "My App"
|
|
1761 VALUE "ProductVersion", "1.0"
|
|
1762 END
|
|
1763 END
|
|
1764
|
|
1765 BLOCK "VarFileInfo"
|
|
1766 BEGIN
|
|
1767 VALUE "Translation", 0x809, 1252
|
|
1768 END
|
|
1769 END
|
|
1770
|
|
1771 The value ``0809`` (langID) is for the U.K English language and
|
|
1772 ``04E4`` (charsetID), which is equal to ``1252`` decimal, for
|
|
1773 multilingual.
|
|
1774
|
|
1775 This section explains how to build, compile and use resources. Note that this
|
|
1776 section does not cover all resource objects, for a complete description see
|
|
1777 the corresponding Microsoft documentation.
|
|
1778
|
|
1779
|
|
1780 .. _Building_Resources:
|
|
1781
|
|
1782 Building Resources
|
|
1783 """"""""""""""""""
|
|
1784
|
|
1785 .. index:: Resources, building
|
|
1786
|
|
1787 A resource file is an ASCII file. By convention resource files have an
|
|
1788 :file:`.rc` extension.
|
|
1789 The easiest way to build a resource file is to use Microsoft tools
|
|
1790 such as ``imagedit.exe`` to build bitmaps, icons and cursors and
|
|
1791 ``dlgedit.exe`` to build dialogs.
|
|
1792 It is always possible to build an :file:`.rc` file yourself by writing a
|
|
1793 resource script.
|
|
1794
|
|
1795 It is not our objective to explain how to write a resource file. A
|
|
1796 complete description of the resource script language can be found in the
|
|
1797 Microsoft documentation.
|
|
1798
|
|
1799
|
|
1800 .. _Compiling_Resources:
|
|
1801
|
|
1802 Compiling Resources
|
|
1803 """""""""""""""""""
|
|
1804
|
|
1805 .. index:: rc
|
|
1806 .. index:: windres
|
|
1807 .. index:: Resources, compiling
|
|
1808
|
|
1809 This section describes how to build a GNAT-compatible (COFF) object file
|
|
1810 containing the resources. This is done using the Resource Compiler
|
|
1811 ``windres`` as follows:
|
|
1812
|
|
1813 ::
|
|
1814
|
|
1815 $ windres -i myres.rc -o myres.o
|
|
1816
|
|
1817 By default ``windres`` will run ``gcc`` to preprocess the :file:`.rc`
|
|
1818 file. You can specify an alternate preprocessor (usually named
|
|
1819 :file:`cpp.exe`) using the ``windres`` :switch:`--preprocessor`
|
|
1820 parameter. A list of all possible options may be obtained by entering
|
|
1821 the command ``windres`` :switch:`--help`.
|
|
1822
|
|
1823 It is also possible to use the Microsoft resource compiler ``rc.exe``
|
|
1824 to produce a :file:`.res` file (binary resource file). See the
|
|
1825 corresponding Microsoft documentation for further details. In this case
|
|
1826 you need to use ``windres`` to translate the :file:`.res` file to a
|
|
1827 GNAT-compatible object file as follows:
|
|
1828
|
|
1829 ::
|
|
1830
|
|
1831 $ windres -i myres.res -o myres.o
|
|
1832
|
|
1833
|
|
1834 .. _Using_Resources:
|
|
1835
|
|
1836 Using Resources
|
|
1837 """""""""""""""
|
|
1838
|
|
1839 .. index:: Resources, using
|
|
1840
|
|
1841 To include the resource file in your program just add the
|
|
1842 GNAT-compatible object file for the resource(s) to the linker
|
|
1843 arguments. With ``gnatmake`` this is done by using the :switch:`-largs`
|
|
1844 option:
|
|
1845
|
|
1846 ::
|
|
1847
|
|
1848 $ gnatmake myprog -largs myres.o
|
|
1849
|
|
1850
|
|
1851 .. _Using_GNAT_DLL_from_MSVS:
|
|
1852
|
|
1853 Using GNAT DLLs from Microsoft Visual Studio Applications
|
|
1854 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
1855
|
|
1856 .. index:: Microsoft Visual Studio, use with GNAT DLLs
|
|
1857
|
|
1858 This section describes a common case of mixed GNAT/Microsoft Visual Studio
|
|
1859 application development, where the main program is developed using MSVS, and
|
|
1860 is linked with a DLL developed using GNAT. Such a mixed application should
|
|
1861 be developed following the general guidelines outlined above; below is the
|
|
1862 cookbook-style sequence of steps to follow:
|
|
1863
|
|
1864 1. First develop and build the GNAT shared library using a library project
|
|
1865 (let's assume the project is :file:`mylib.gpr`, producing the library :file:`libmylib.dll`):
|
|
1866
|
|
1867 ::
|
|
1868
|
|
1869 $ gprbuild -p mylib.gpr
|
|
1870
|
|
1871 2. Produce a .def file for the symbols you need to interface with, either by
|
|
1872 hand or automatically with possibly some manual adjustments
|
|
1873 (see :ref:`Creating Definition File Automatically <Create_Def_File_Automatically>`):
|
|
1874
|
|
1875 ::
|
|
1876
|
|
1877 $ dlltool libmylib.dll -z libmylib.def --export-all-symbols
|
|
1878
|
|
1879 3. Make sure that MSVS command-line tools are accessible on the path.
|
|
1880
|
|
1881 4. Create the Microsoft-style import library (see :ref:`MSVS-Style Import Library <MSVS-Style_Import_Library>`):
|
|
1882
|
|
1883 ::
|
|
1884
|
|
1885 $ lib -machine:IX86 -def:libmylib.def -out:libmylib.lib
|
|
1886
|
|
1887 If you are using a 64-bit toolchain, the above becomes...
|
|
1888
|
|
1889 ::
|
|
1890
|
|
1891 $ lib -machine:X64 -def:libmylib.def -out:libmylib.lib
|
|
1892
|
|
1893 5. Build the C main
|
|
1894
|
|
1895 ::
|
|
1896
|
|
1897 $ cl /O2 /MD main.c libmylib.lib
|
|
1898
|
|
1899 6. Before running the executable, make sure you have set the PATH to the DLL,
|
|
1900 or copy the DLL into into the directory containing the .exe.
|
|
1901
|
|
1902
|
|
1903 .. _Debugging_a_DLL:
|
|
1904
|
|
1905 Debugging a DLL
|
|
1906 ^^^^^^^^^^^^^^^
|
|
1907
|
|
1908 .. index:: DLL debugging
|
|
1909
|
|
1910 Debugging a DLL is similar to debugging a standard program. But
|
|
1911 we have to deal with two different executable parts: the DLL and the
|
|
1912 program that uses it. We have the following four possibilities:
|
|
1913
|
|
1914 * The program and the DLL are built with GCC/GNAT.
|
|
1915 * The program is built with foreign tools and the DLL is built with
|
|
1916 GCC/GNAT.
|
|
1917 * The program is built with GCC/GNAT and the DLL is built with
|
|
1918 foreign tools.
|
|
1919
|
|
1920 In this section we address only cases one and two above.
|
|
1921 There is no point in trying to debug
|
|
1922 a DLL with GNU/GDB, if there is no GDB-compatible debugging
|
|
1923 information in it. To do so you must use a debugger compatible with the
|
|
1924 tools suite used to build the DLL.
|
|
1925
|
|
1926 .. _Program_and_DLL_Both_Built_with_GCC/GNAT:
|
|
1927
|
|
1928 Program and DLL Both Built with GCC/GNAT
|
|
1929 """"""""""""""""""""""""""""""""""""""""
|
|
1930
|
|
1931 This is the simplest case. Both the DLL and the program have ``GDB``
|
|
1932 compatible debugging information. It is then possible to break anywhere in
|
|
1933 the process. Let's suppose here that the main procedure is named
|
|
1934 ``ada_main`` and that in the DLL there is an entry point named
|
|
1935 ``ada_dll``.
|
|
1936
|
|
1937 The DLL (:ref:`Introduction_to_Dynamic_Link_Libraries_DLLs`) and
|
|
1938 program must have been built with the debugging information (see GNAT -g
|
|
1939 switch). Here are the step-by-step instructions for debugging it:
|
|
1940
|
|
1941 * Launch ``GDB`` on the main program.
|
|
1942
|
|
1943 ::
|
|
1944
|
|
1945 $ gdb -nw ada_main
|
|
1946
|
|
1947 * Start the program and stop at the beginning of the main procedure
|
|
1948
|
|
1949 ::
|
|
1950
|
|
1951 (gdb) start
|
|
1952
|
|
1953 This step is required to be able to set a breakpoint inside the DLL. As long
|
|
1954 as the program is not run, the DLL is not loaded. This has the
|
|
1955 consequence that the DLL debugging information is also not loaded, so it is not
|
|
1956 possible to set a breakpoint in the DLL.
|
|
1957
|
|
1958 * Set a breakpoint inside the DLL
|
|
1959
|
|
1960 ::
|
|
1961
|
|
1962 (gdb) break ada_dll
|
|
1963 (gdb) cont
|
|
1964
|
|
1965 At this stage a breakpoint is set inside the DLL. From there on
|
|
1966 you can use the standard approach to debug the whole program
|
|
1967 (:ref:`Running_and_Debugging_Ada_Programs`).
|
|
1968
|
|
1969
|
|
1970 .. _Program_Built_with_Foreign_Tools_and_DLL_Built_with_GCC/GNAT:
|
|
1971
|
|
1972 Program Built with Foreign Tools and DLL Built with GCC/GNAT
|
|
1973 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
|
1974
|
|
1975 In this case things are slightly more complex because it is not possible to
|
|
1976 start the main program and then break at the beginning to load the DLL and the
|
|
1977 associated DLL debugging information. It is not possible to break at the
|
|
1978 beginning of the program because there is no ``GDB`` debugging information,
|
|
1979 and therefore there is no direct way of getting initial control. This
|
|
1980 section addresses this issue by describing some methods that can be used
|
|
1981 to break somewhere in the DLL to debug it.
|
|
1982
|
|
1983 First suppose that the main procedure is named ``main`` (this is for
|
|
1984 example some C code built with Microsoft Visual C) and that there is a
|
|
1985 DLL named ``test.dll`` containing an Ada entry point named
|
|
1986 ``ada_dll``.
|
|
1987
|
|
1988 The DLL (see :ref:`Introduction_to_Dynamic_Link_Libraries_DLLs`) must have
|
|
1989 been built with debugging information (see the GNAT :switch:`-g` option).
|
|
1990
|
|
1991
|
|
1992 .. rubric:: Debugging the DLL Directly
|
|
1993
|
|
1994 * Find out the executable starting address
|
|
1995
|
|
1996 ::
|
|
1997
|
|
1998 $ objdump --file-header main.exe
|
|
1999
|
|
2000 The starting address is reported on the last line. For example:
|
|
2001
|
|
2002 ::
|
|
2003
|
|
2004 main.exe: file format pei-i386
|
|
2005 architecture: i386, flags 0x0000010a:
|
|
2006 EXEC_P, HAS_DEBUG, D_PAGED
|
|
2007 start address 0x00401010
|
|
2008
|
|
2009 * Launch the debugger on the executable.
|
|
2010
|
|
2011 ::
|
|
2012
|
|
2013 $ gdb main.exe
|
|
2014
|
|
2015 * Set a breakpoint at the starting address, and launch the program.
|
|
2016
|
|
2017 ::
|
|
2018
|
|
2019 $ (gdb) break *0x00401010
|
|
2020 $ (gdb) run
|
|
2021
|
|
2022 The program will stop at the given address.
|
|
2023
|
|
2024 * Set a breakpoint on a DLL subroutine.
|
|
2025
|
|
2026 ::
|
|
2027
|
|
2028 (gdb) break ada_dll.adb:45
|
|
2029
|
|
2030 Or if you want to break using a symbol on the DLL, you need first to
|
|
2031 select the Ada language (language used by the DLL).
|
|
2032
|
|
2033 ::
|
|
2034
|
|
2035 (gdb) set language ada
|
|
2036 (gdb) break ada_dll
|
|
2037
|
|
2038 * Continue the program.
|
|
2039
|
|
2040 ::
|
|
2041
|
|
2042 (gdb) cont
|
|
2043
|
|
2044 This will run the program until it reaches the breakpoint that has been
|
|
2045 set. From that point you can use the standard way to debug a program
|
|
2046 as described in (:ref:`Running_and_Debugging_Ada_Programs`).
|
|
2047
|
|
2048 It is also possible to debug the DLL by attaching to a running process.
|
|
2049
|
|
2050
|
|
2051 .. rubric:: Attaching to a Running Process
|
|
2052
|
|
2053 .. index:: DLL debugging, attach to process
|
|
2054
|
|
2055 With ``GDB`` it is always possible to debug a running process by
|
|
2056 attaching to it. It is possible to debug a DLL this way. The limitation
|
|
2057 of this approach is that the DLL must run long enough to perform the
|
|
2058 attach operation. It may be useful for instance to insert a time wasting
|
|
2059 loop in the code of the DLL to meet this criterion.
|
|
2060
|
|
2061 * Launch the main program :file:`main.exe`.
|
|
2062
|
|
2063 ::
|
|
2064
|
|
2065 $ main
|
|
2066
|
|
2067 * Use the Windows *Task Manager* to find the process ID. Let's say
|
|
2068 that the process PID for :file:`main.exe` is 208.
|
|
2069
|
|
2070 * Launch gdb.
|
|
2071
|
|
2072 ::
|
|
2073
|
|
2074 $ gdb
|
|
2075
|
|
2076 * Attach to the running process to be debugged.
|
|
2077
|
|
2078 ::
|
|
2079
|
|
2080 (gdb) attach 208
|
|
2081
|
|
2082 * Load the process debugging information.
|
|
2083
|
|
2084 ::
|
|
2085
|
|
2086 (gdb) symbol-file main.exe
|
|
2087
|
|
2088 * Break somewhere in the DLL.
|
|
2089
|
|
2090 ::
|
|
2091
|
|
2092 (gdb) break ada_dll
|
|
2093
|
|
2094 * Continue process execution.
|
|
2095
|
|
2096 ::
|
|
2097
|
|
2098 (gdb) cont
|
|
2099
|
|
2100 This last step will resume the process execution, and stop at
|
|
2101 the breakpoint we have set. From there you can use the standard
|
|
2102 approach to debug a program as described in
|
|
2103 :ref:`Running_and_Debugging_Ada_Programs`.
|
|
2104
|
|
2105
|
|
2106 .. _Setting_Stack_Size_from_gnatlink:
|
|
2107
|
|
2108 Setting Stack Size from ``gnatlink``
|
|
2109 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
2110
|
|
2111 It is possible to specify the program stack size at link time. On modern
|
|
2112 versions of Windows, starting with XP, this is mostly useful to set the size of
|
|
2113 the main stack (environment task). The other task stacks are set with pragma
|
|
2114 Storage_Size or with the *gnatbind -d* command.
|
|
2115
|
|
2116 Since older versions of Windows (2000, NT4, etc.) do not allow setting the
|
|
2117 reserve size of individual tasks, the link-time stack size applies to all
|
|
2118 tasks, and pragma Storage_Size has no effect.
|
|
2119 In particular, Stack Overflow checks are made against this
|
|
2120 link-time specified size.
|
|
2121
|
|
2122 This setting can be done with ``gnatlink`` using either of the following:
|
|
2123
|
|
2124
|
|
2125 * :switch:`-Xlinker` linker option
|
|
2126
|
|
2127 ::
|
|
2128
|
|
2129 $ gnatlink hello -Xlinker --stack=0x10000,0x1000
|
|
2130
|
|
2131
|
|
2132 This sets the stack reserve size to 0x10000 bytes and the stack commit
|
|
2133 size to 0x1000 bytes.
|
|
2134
|
|
2135 * :switch:`-Wl` linker option
|
|
2136
|
|
2137 ::
|
|
2138
|
|
2139 $ gnatlink hello -Wl,--stack=0x1000000
|
|
2140
|
|
2141 This sets the stack reserve size to 0x1000000 bytes. Note that with
|
|
2142 :switch:`-Wl` option it is not possible to set the stack commit size
|
|
2143 because the comma is a separator for this option.
|
|
2144
|
|
2145
|
|
2146 .. _Setting_Heap_Size_from_gnatlink:
|
|
2147
|
|
2148 Setting Heap Size from ``gnatlink``
|
|
2149 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
2150
|
|
2151 Under Windows systems, it is possible to specify the program heap size from
|
|
2152 ``gnatlink`` using either of the following:
|
|
2153
|
|
2154 * :switch:`-Xlinker` linker option
|
|
2155
|
|
2156 ::
|
|
2157
|
|
2158 $ gnatlink hello -Xlinker --heap=0x10000,0x1000
|
|
2159
|
|
2160 This sets the heap reserve size to 0x10000 bytes and the heap commit
|
|
2161 size to 0x1000 bytes.
|
|
2162
|
|
2163 * :switch:`-Wl` linker option
|
|
2164
|
|
2165 ::
|
|
2166
|
|
2167 $ gnatlink hello -Wl,--heap=0x1000000
|
|
2168
|
|
2169
|
|
2170 This sets the heap reserve size to 0x1000000 bytes. Note that with
|
|
2171 :switch:`-Wl` option it is not possible to set the heap commit size
|
|
2172 because the comma is a separator for this option.
|
|
2173
|
|
2174
|
|
2175 .. _Win32_Specific_Addons:
|
|
2176
|
|
2177 Windows Specific Add-Ons
|
|
2178 -------------------------
|
|
2179
|
|
2180 This section describes the Windows specific add-ons.
|
|
2181
|
|
2182 .. _Win32Ada:
|
|
2183
|
|
2184 Win32Ada
|
|
2185 ^^^^^^^^
|
|
2186
|
|
2187 Win32Ada is a binding for the Microsoft Win32 API. This binding can be
|
|
2188 easily installed from the provided installer. To use the Win32Ada
|
|
2189 binding you need to use a project file, and adding a single with_clause
|
|
2190 will give you full access to the Win32Ada binding sources and ensure
|
|
2191 that the proper libraries are passed to the linker.
|
|
2192
|
|
2193 .. code-block:: gpr
|
|
2194
|
|
2195 with "win32ada";
|
|
2196 project P is
|
|
2197 for Sources use ...;
|
|
2198 end P;
|
|
2199
|
|
2200 To build the application you just need to call gprbuild for the
|
|
2201 application's project, here p.gpr:
|
|
2202
|
|
2203 .. code-block:: sh
|
|
2204
|
|
2205 gprbuild p.gpr
|
|
2206
|
|
2207 .. _wPOSIX:
|
|
2208
|
|
2209 wPOSIX
|
|
2210 ^^^^^^
|
|
2211
|
|
2212 wPOSIX is a minimal POSIX binding whose goal is to help with building
|
|
2213 cross-platforms applications. This binding is not complete though, as
|
|
2214 the Win32 API does not provide the necessary support for all POSIX APIs.
|
|
2215
|
|
2216 To use the wPOSIX binding you need to use a project file, and adding
|
|
2217 a single with_clause will give you full access to the wPOSIX binding
|
|
2218 sources and ensure that the proper libraries are passed to the linker.
|
|
2219
|
|
2220 .. code-block:: gpr
|
|
2221
|
|
2222 with "wposix";
|
|
2223 project P is
|
|
2224 for Sources use ...;
|
|
2225 end P;
|
|
2226
|
|
2227 To build the application you just need to call gprbuild for the
|
|
2228 application's project, here p.gpr:
|
|
2229
|
|
2230 .. code-block:: sh
|
|
2231
|
|
2232 gprbuild p.gpr
|
|
2233
|
|
2234
|
|
2235 .. _Mac_OS_Topics:
|
|
2236
|
|
2237 Mac OS Topics
|
|
2238 =============
|
|
2239
|
|
2240 .. index:: OS X
|
|
2241
|
|
2242 This section describes topics that are specific to Apple's OS X
|
|
2243 platform.
|
|
2244
|
|
2245 Codesigning the Debugger
|
|
2246 ------------------------
|
|
2247
|
|
2248 The Darwin Kernel requires the debugger to have special permissions
|
|
2249 before it is allowed to control other processes. These permissions
|
|
2250 are granted by codesigning the GDB executable. Without these
|
|
2251 permissions, the debugger will report error messages such as::
|
|
2252
|
|
2253 Starting program: /x/y/foo
|
|
2254 Unable to find Mach task port for process-id 28885: (os/kern) failure (0x5).
|
|
2255 (please check gdb is codesigned - see taskgated(8))
|
|
2256
|
|
2257 Codesigning requires a certificate. The following procedure explains
|
|
2258 how to create one:
|
|
2259
|
|
2260 * Start the Keychain Access application (in
|
|
2261 /Applications/Utilities/Keychain Access.app)
|
|
2262
|
|
2263 * Select the Keychain Access -> Certificate Assistant ->
|
|
2264 Create a Certificate... menu
|
|
2265
|
|
2266 * Then:
|
|
2267
|
|
2268 * Choose a name for the new certificate (this procedure will use
|
|
2269 "gdb-cert" as an example)
|
|
2270
|
|
2271 * Set "Identity Type" to "Self Signed Root"
|
|
2272
|
|
2273 * Set "Certificate Type" to "Code Signing"
|
|
2274
|
|
2275 * Activate the "Let me override defaults" option
|
|
2276
|
|
2277
|
|
2278 * Click several times on "Continue" until the "Specify a Location
|
|
2279 For The Certificate" screen appears, then set "Keychain" to "System"
|
|
2280
|
|
2281 * Click on "Continue" until the certificate is created
|
|
2282
|
|
2283 * Finally, in the view, double-click on the new certificate,
|
|
2284 and set "When using this certificate" to "Always Trust"
|
|
2285
|
|
2286 * Exit the Keychain Access application and restart the computer
|
|
2287 (this is unfortunately required)
|
|
2288
|
|
2289
|
|
2290 Once a certificate has been created, the debugger can be codesigned
|
|
2291 as follow. In a Terminal, run the following command:
|
|
2292
|
|
2293 ::
|
|
2294
|
|
2295 $ codesign -f -s "gdb-cert" <gnat_install_prefix>/bin/gdb
|
|
2296
|
|
2297 where "gdb-cert" should be replaced by the actual certificate
|
|
2298 name chosen above, and <gnat_install_prefix> should be replaced by
|
|
2299 the location where you installed GNAT. Also, be sure that users are
|
|
2300 in the Unix group ``_developer``.
|