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