File: README.md

package info (click to toggle)
xfce4-dev-tools 4.20.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,976 kB
  • sloc: sh: 5,180; ansic: 404; xml: 137; python: 128; makefile: 109
file content (286 lines) | stat: -rw-r--r-- 8,748 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
# Autotools `configure` Generation

The `xdt-autogen` script should be used to generate your `configure`
script from the `configure.ac` template.  Dropping an `autogen.sh`
script into the root of your project with the following content should
do it:

```sh
#!/bin/sh

export XDT_AUTOGEN_REQUIRED_VERSION="4.18.0"

(type xdt-autogen) >/dev/null 2>&1 || {
  cat >&2 <<EOF
autogen.sh: You don't seem to have the Xfce development tools installed on your system,
            which are required to build this software.
            Please install the xfce4-dev-tools package first; it is available
            from your distribution or https://www.xfce.org/.
EOF
  exit 1
}

exec xdt-autogen "$@"
```

As you can see, you can require a minimum version of `xdt-autogen` by
setting `XDT_AUTOGEN_REQUIRED_VERSION` before running it.

# Symbol Visibility and ABI checking

The scripts `xdt-check-abi` and `xdt-gen-visibility` can be used to
manage the ABI of your shared library.

## `xdt-check-abi`

The first script is a checker: it takes as its first argument a symbols
file (described later), and as its second argument the final compiled
library file.  It will exit 0 on success, or 1 on failure, and print out
a diff between the expected and actual ABI.

## `xdt-gen-visibility`

The second script generates aliases and attributes to set up GNU
visibility for the functions in your library.  It needs to generate both
a header and source file.  To summarize:

1. Create a symbols file that lists all symbols you wish to export from
   the library.
2. Use the script to generate a header, which must be included as the
   *last* `#include` statement in the list of includes in any source
   file that defines public symbols.
3. Use the script to generate a source file, which must be included at
   the very bottom of each source file that defines public symbols.
   Right before this include, you'll need to define a preprocessor macro
   to "enable" the declarations for the current file.
4. You should check to ensure the compiler in use supports visibility
   attributes, and you can also allow the person building to disable
   this functionality.
5. You should add `-fvisibilty=hidden` to the compiler command line.
   This sets the default visibility to "hidden"; the generated source
   and header files will explicitly "unhide" symbols that should be made
   public.
6. You must add `-DENABLE_SYMBOL_VISIBILITY=1` to the compiler command
   line, or otherwise cause that preprocessor macro to be defined.
7. Optionally, you can also include the header (again, as the last
   `#include` statement) in any source file that doesn't export public
   symbols, but *uses* any of those public symbols, and the generated
   function calls or variable accesses will be made more efficiently.

Details for autotools and meson, as well as the format of the symbols
file, are below.

### Build system integration

#### For autotools

In `configure.ac`:

```autoconf
AC_ARG_ENABLE([visibility],
              AS_HELP_STRING([--disable-visibility],
                             [Do not use ELF visibility attributes]),
              [enable_visibility=$enableval], [enable_visibility=yes])
have_gnuc_visibility=no
if test "x$enable_visibility" != "xno"; then
  XDT_SUPPORTED_FLAGS([xdt_vis_test_cflags], [-Wall -Werror -Wno-unused-parameter -fvisibility=hidden])
  saved_CFLAGS="$CFLAGS"
  CFLAGS="$CFLAGS $xdt_vis_test_cflags"
  AC_MSG_CHECKING([whether $CC supports the GNUC visibility attribute])
  AC_COMPILE_IFELSE([AC_LANG_SOURCE(
  [
    void test_default(void);
    void test_hidden(void);
    void __attribute__((visibility("default"))) test_default(void) {}
    void __attribute__((visibility("hidden"))) test_hidden(void) {}
    int main(int argc, char **argv) {
      test_default();
      test_hidden();
      return 0;
    }
  ])],
  [
    have_gnuc_visibility=yes
    AC_MSG_RESULT([yes])
  ],
  [
    AC_MSG_RESULT([no])
  ])
  CFLAGS="$saved_CFLAGS"
fi
if test "x$have_gnuc_visibility" = "xyes"; then
  CPPFLAGS="$CPPFLAGS -DENABLE_SYMBOL_VISIBILITY=1"
  CFLAGS="$CFLAGS -fvisibility=hidden"
fi
```

In `Makefile.am`:

```make
libexample_la_SOURCES = \
	# ... other sources ... \
	libexample-visibility.c \
	libexample-visibilty.h

%-visibility.h: %.symbols Makefile
	$(AM_V_GEN) xdt-gen-visibility --kind=header $< $@

%-visibility.c: %.symbols Makefile
	$(AM_V_GEN) xdt-gen-visibility --kind=source $< $@

BUILT_SOURCES = \
	libexample-visibility.c \
	libexample-visibilty.h

CLEANFILES = \
	libexample-visibility.c \
	libexample-visibilty.h

EXTRA_DIST = \
	libexample.symbols
```

While the generated source file does not need to be linked into the
final library (in fact doing so is a no-op, as the `#ifdef` statements
in the file will effectively make it an empty file when compiled that
way), the simplest way to ensure that the files are generated and
up-to-date is to include them as source files.

#### For meson

In the root `meson_options.txt`:

```
option(
  'visibility',
  type: 'boolean',
  value: true,
  description: 'Build with GNU symbol visibility',
)

```

In the project root's `meson.build`:

```meson
python3 = find_program('python3', required: true)
xdt_gen_visibility = find_program('xdt-gen-visibility', required: true)

gnu_symbol_visibility = 'default'
visibility_defines = []
if get_option('visibility')
    gnu_symbol_visibility = 'hidden'
    visibility_defines += '-DENABLE_SYMBOL_VISIBILITY=1'
endif
```

And in the `meson.build` where the library is built:

```meson
libexample_generated_files += custom_target(
  'libexample-visibility.h',
  input: 'libexample.symbols',
  output: 'libexample-visibility.h',
  command: [xdt_gen_visibility, '--kind=header', '@INPUT@', '@OUTPUT@'],
)
libexample_generated_files += custom_target(
  'libexample-visibility.c',
  input: 'libexample.symbols',
  output: 'libexample-visibility.c',
  command: [xdt_gen_visibility, '--kind=source', '@INPUT@', '@OUTPUT@'],
)

library(
  'libexample',
  [
    # ... source files ...
  ] + libexample_generated_files,
  # ...
  extra_args: visibility_defines,
  gnu_symbol_visibility: gnu_symbol_visibility,
  # ...
)
```

While the generated source file does not need to be linked into the
final library (in fact doing so is a no-op, as the `#ifdef` statements
in the file will effectively make it an empty file when compiled that
way), the simplest way to ensure that the files are generated and
up-to-date is to include them as source files.

### Inclusion in source files

The script assumes you are using header guards in your headers that look
like, e.g.:

```c
#ifndef __THE_FILE_NAME_H__
#define __THE_FILE_NAME_H__

// ...

#endif
```

If you are not, you will need to pass the `--ifdef-guard-format` option
to the script.  See the `--help` output for more information on format
options.  For reference, the default format is
`__{file_stem_upper_snake}_{file_type_upper}__`.

For the `.c` source files themselves, you will need to add the generated
header as the *last* `#include` statement.  This point is very
important!  If you are using a source-code formatting tool that
rearranges includes, ensure that you've configured it in a way such that
the visibility header will be sorted last.

Then at the *very bottom* of the file, as the last two lines, add:

```c
#define __THE_FILE_NAME_C__
#include <libexample-visibility.c>
```

If you aren't using the default `ifdef-guard-format`, you should use the
format you specified there as the format for this `#define`. Of course,
replace `THE_FILE_NAME` with the actual file stem, in whatever format
you've specified.

And yes, you're including the `.c` file, not a header, and the `#define`
includes the letter "C" (or "c"), and not "H" (or "h").

## The `.symbols` file

The symbols file, used by both the ABI checker and the visibility
header/source generator, should be broken up into sections based on the
C source file the symbol is defined in.  To start a new section, use a
comment formatted like this:

```
# file:the-file-name-stem`
```

Note that the file name should *not* include the `.c` suffix.

Following that should be a list of symbols to export, one per line.  If
the symbol is a variable (rather than a function), prefix the name with
`var:`.

You can add "attributes" as well.  After the symbol, put a space
separated list of tokens prefixed with `attr:`.  Here is a more complete
example:

```
# file:libexample-config
libexample_check_version
var:libexample_major_version
var:libexample_micro_version
var:libexample_minor_version

# file:ex-util
ex_do_something attr:G_GNUC_CONST
ex_do_something_else attr:G_GNUC_CONST attr:G_GNUC_PURE
ex_do_yet_another_thing
```

Blank lines and lines starting with a "#" (aside from the `file:` lines)
are ignored.