2 dnl These are the facilities for enable/disabling various features,
3 dnl and for collecting CFLAGS/LIBS and generating per feature .pc
4 dnl files, assembling list of source files to compile, creating
5 dnl cairo-features.h and other generated files, etc...
8 dnl ===========================================================================
11 dnl Used to force cache invalidation
13 m4_define([cr_cache_version], [6])
16 dnl Define a macro to enable features
17 dnl - Macro: _CAIRO_ENABLE (ID, NAME, WHAT, DEFAULT, COMMANDS)
21 dnl ID is the sub-namespace in function names, eg. "ft" for cairo_ft_...
22 dnl NAME is the human-readable name of the feature, eg. "FreeType font"
23 dnl WHAT is the type of feature:
24 dnl "surface" for surface backends
25 dnl "font" for font backends
26 dnl "functions" for set of functions
27 dnl "" for private configurations
28 dnl DEFAULT is the default state of the feature:
29 dnl "no" for experimental features, eg. your favorite new backend
30 dnl "yes" for recommended features, eg. png functions
31 dnl "auto" for other supported features, eg. xlib surface backend
32 dnl "always" for mandatory features (can't be disabled), eg. image surface backend
33 dnl COMMANDS are run to check whether the feature can be enabled. Their
34 dnl result may be cached, so user should not count on them being run.
35 dnl They should set use_$(ID) to something other than yes if the
36 dnl feature cannot be built, eg. "no (requires SomeThing)". It then
37 dnl should also set $(ID)_REQUIRES/CFLAGS/LIBS/...
38 dnl appropriately. Look at the macro definition for more details,
39 dnl or ask if in doubt.
41 AC_DEFUN([_CAIRO_ENABLE],
46 m4_tolower(AS_TR_SH([$1])),
48 [m4_fatal([invalid feature name `$1'])]
50 m4_pushdef([cr_feature], [$1])dnl
51 m4_pushdef([cr_feature_name], m4_normalize([$2]))dnl
52 m4_pushdef([cr_feature_what], m4_normalize([$3]))dnl
53 m4_pushdef([cr_feature_default], m4_normalize([$4]))dnl
54 m4_pushdef([cr_feature_commands], [$5])dnl
55 m4_pushdef([cr_feature_commands_len], m4_len([$5]))dnl
57 m4_pushdef([cr_feature_arg], m4_translit([$1],_,-))dnl
59 dnl Sanity check default
66 [m4_fatal([Invalid default value `]cr_feature_default[' for feature `]cr_feature['])]
69 m4_if(cr_feature_default, [always],
73 AC_ARG_ENABLE(cr_feature_arg,
74 AS_HELP_STRING([--enable-]cr_feature_arg[=@<:@no/auto/yes@:>@],
75 [Enable cairo's ]cr_feature_name[ feature @<:@default=]cr_feature_default[@:>@]),
76 enable_$1=$enableval, enable_$1=cr_feature_default)
81 use_$1="no (disabled, use --enable-cr_feature_arg to enable)"
84 dnl Cache invalidating:
86 dnl To be extremely user-friendly, we discard cache results if
87 dnl any of the following conditions happens:
89 dnl - Global cache version changes
90 dnl This is used to force a cache invalidation for these
93 dnl - Set of cached variables changes
94 dnl (XXX should also do if the default value of such
95 dnl variables changes. Argh...)
97 dnl - Length of the COMMANDS string changes!
98 dnl (This is much more friendly to the cache than caching
99 dnl the commands string itself. Note that this still does
100 dnl not catch all valid cases where we should be
101 dnl invalidting. For example if COMMANDS uses
102 dnl variables/macros defined outside, we don't detect changes
103 dnl in those variables. Also doesn't detect in-place
104 dnl modifications like bumping verson numbers.
105 dnl Just modify COMMANDS in an obvious way to force recheck.
106 dnl Hashing sounds a bit too harsh to do here...)
108 dnl - If feature is requested and cached results for enabling
109 dnl feature is no. We are going to terminate with an error
110 dnl if this happens anyway, so we can be more friendly by
111 dnl assuming that user installed some missing pieces since
112 dnl last time and so we recheck. Although even in that
113 dnl case other cached values probably get in the way...
115 AS_IF([test "x$cairo_cv_[]$1[]_cache_version" != "x[]cr_cache_version" -o \
116 "x$cairo_cv_[]$1[]_cache_commands_len" != "x[]cr_feature_commands_len" -o \
117 "x$cairo_cv_[]$1[]_cache_vars" != "x[]_CAIRO_FEATURE_VARS"],
118 [unset cairo_cv_[]$1[]_use])
119 AS_IF([test "x$enable_$1" = xyes -a "x$cairo_cv_[]$1[]_use" != xyes],
120 [unset cairo_cv_[]$1[]_use])
122 AC_CACHE_CHECK([for cairo's ]cr_feature_name[ feature], cairo_cv_[]$1[]_use,
126 CAIRO_FEATURE_VARS_FOREACH(cr_var, [cr_feature[_]cr_var[=]_CAIRO_SH_ESCAPE_UNQUOTED(m4_do([cr_var_default_]cr_var[_value]))]m4_newline)
128 cairo_cv_[]$1[]_use=$use_[]$1
129 cairo_cv_[]$1[]_cache_vars="_CAIRO_FEATURE_VARS"
130 cairo_cv_[]$1[]_cache_commands_len="cr_feature_commands_len"
131 cairo_cv_[]$1[]_cache_version="cr_cache_version"
132 CAIRO_FEATURE_VARS_FOREACH([cr_var], [[cairo_cv_]cr_feature[_]cr_var[=$]cr_feature[_]cr_var]m4_newline)
133 AC_MSG_CHECKING([whether cairo's ]cr_feature_name[ feature could be enabled])
136 use_[]$1=$cairo_cv_[]$1[]_use
138 AS_IF([test "x$enable_$1" = "xyes" -a "x$use_$1" != xyes],
141 m4_case(cr_feature_default,
142 [always], [mandatory],
143 [yes], [recommended],
145 ) cr_feature_name[ feature could not be enabled])
149 AC_MSG_ERROR([invalid argument passed to --enable-]cr_feature_arg[: `$use_$1', should be one of @<:@no/auto/yes@:>@])
152 AS_IF([test "x$use_$1" = "xyes"],
154 CAIRO_FEATURE_VARS_FOREACH([cr_var], [cr_feature[_]cr_var[=$cairo_cv_]cr_feature[_]cr_var]m4_newline)
155 CAIRO_ACCUMULATED_FEATURE_VARS_FOREACH([cr_var],
157 CAIRO_ACCUMULATE_UNQUOTED_BEFORE(cr_var, [$]cr_feature[_]cr_var)
160 dnl If not enabled, empty the vars so no one accidentally uses them.
161 CAIRO_FEATURE_VARS_FOREACH([cr_var], [cr_feature[_]cr_var[=$cairo_cv_]cr_feature[_]cr_var]m4_newline)
164 _CAIRO_FEATURE_HOOKS(cr_feature, cr_feature_name, cr_feature_default, cr_feature_what)dnl
166 m4_popdef([cr_feature])dnl
167 m4_popdef([cr_feature_name])dnl
168 m4_popdef([cr_feature_what])dnl
169 m4_popdef([cr_feature_default])dnl
170 m4_popdef([cr_feature_commands])dnl
171 m4_popdef([cr_feature_commands_len])dnl
172 m4_popdef([cr_feature_arg])dnl
176 dnl ===========================================================================
178 m4_define([_CAIRO_FEATURE_VARS])
181 dnl CAIRO_FEATURE_VARS_REGISTER(VARS, DEFAULT-VALUE=[])
183 dnl Registers variables to be collected from feature-enabling code segments.
184 dnl VARS should be a whitespace-separate list of variable names.
186 dnl DEFAULT-VALUE is m4 macros to set default value of VARS
188 AC_DEFUN([CAIRO_FEATURE_VARS_REGISTER],
190 m4_foreach_w([cr_var], [$1],
191 [m4_append_uniq([_CAIRO_FEATURE_VARS], cr_var, [ ],,
192 [m4_fatal([Feature variable `]cr_var[' already registered])])])dnl
193 m4_foreach_w([cr_var], [$1],
195 m4_define([cr_var_default_]cr_var[_value], m4_default([$2],[[$ac_env_[]]cr_feature[[]_]]cr_var[[_value]]))dnl
200 dnl CAIRO_FEATURE_VARS_FOREACH(VAR, COMMANDS)
202 dnl Run COMMANDS for each registered feature variable.
203 dnl Defines VAR to the variable being processed.
205 AC_DEFUN([CAIRO_FEATURE_VARS_FOREACH],
207 m4_foreach_w([$1], _CAIRO_FEATURE_VARS, [$2])dnl
211 dnl ===========================================================================
213 m4_define([_CAIRO_ACCUMULATORS])dnl
215 m4_define([_CAIRO_ACCUMULATORS_REGISTER],
217 m4_foreach_w([cr_var], [$1],
218 [m4_append_uniq([_CAIRO_ACCUMULATORS], cr_var, [ ],,
219 [m4_fatal([Accumulator `]cr_var[' already registered])])])dnl
220 m4_foreach_w([cr_var], [$1], [m4_define([cr_acc_]cr_var[_sep], [$2])])dnl
221 m4_foreach_w([cr_var], [$1], [[CAIRO_]cr_var[=$3]]m4_newline)dnl
222 m4_foreach_w([cr_var], [$1], [m4_pattern_allow([CAIRO_]cr_var)])dnl
225 m4_define([_CAIRO_SH_ESCAPE],['m4_bpatsubst([$1],['],[\\'])'])dnl
226 m4_define([_CAIRO_SH_ESCAPE_UNQUOTED],["m4_bpatsubst([$1],["],[\\"])"])dnl
229 dnl CAIRO_ACCUMULATORS_REGISTER(VARS, SEPARATOR=[], INITIAL-VALUE=[])
231 dnl Registers accumulators. An accumulator is a shell variable that can
232 dnl be accumulated to. The macros take care of adding a SEPARATOR between
233 dnl accumulated values.
235 dnl VARS should be a whitespace-separate list of variable names. The actual
236 dnl shell variable resulting for each variable is prefixed with CAIRO_.
238 AC_DEFUN([CAIRO_ACCUMULATORS_REGISTER],
240 _CAIRO_ACCUMULATORS_REGISTER([$1],[$2],_CAIRO_SH_ESCAPE([$3]))dnl
244 dnl Like CAIRO_ACCUMULATORS_REGISTER but INITIAL-VALUE is left unquoted,
245 dnl so it can reference other shell variables for example.
247 AC_DEFUN([CAIRO_ACCUMULATORS_REGISTER_UNQUOTED],
249 _CAIRO_ACCUMULATORS_REGISTER([$1],[$2],_CAIRO_SH_ESCAPE_UNQUOTED([$3]))dnl
252 m4_define([_CAIRO_ACCUMULATOR_CHECK],
254 m4_ifdef([cr_acc_$1_sep],,[m4_fatal([Accumulator `]$1[' not defined.])])dnl
257 m4_define([_CAIRO_ACCUMULATE],
259 _CAIRO_ACCUMULATOR_CHECK([$1])dnl
260 m4_ifval([$2], [$3]m4_newline)dnl
264 dnl CAIRO_ACCUMULATE(VAR, VALUE)
266 dnl Appends VALUE to accumulator VAR
268 AC_DEFUN([CAIRO_ACCUMULATE],
270 _CAIRO_ACCUMULATE([$1], [$2], [CAIRO_$1="${CAIRO_$1}]m4_do([cr_acc_$1_sep])["_CAIRO_SH_ESCAPE([$2])])dnl
274 dnl CAIRO_ACCUMULATE(VAR, VALUE)
276 dnl Prepends VALUE to accumulator VAR
278 AC_DEFUN([CAIRO_ACCUMULATE_BEFORE],
280 _CAIRO_ACCUMULATE([$1], [$2], [CAIRO_$1=_CAIRO_SH_ESCAPE([$2])"]m4_do([cr_acc_$1_sep])[${CAIRO_$1}"])dnl
283 m4_define([_CAIRO_ACCUMULATE_UNQUOTED],
285 _CAIRO_ACCUMULATOR_CHECK([$1])dnl
286 m4_ifval([$2], [m4_bmatch([$2],[[$]],[test -n "$2" &&]) $3]m4_newline)dnl
290 dnl CAIRO_ACCUMULATE_UNQUOTED(VAR, VALUE)
292 dnl Like CAIRO_ACCUMULATE but VALUE is left unquoted,
293 dnl so it can reference other shell variables for example.
295 AC_DEFUN([CAIRO_ACCUMULATE_UNQUOTED],
297 _CAIRO_ACCUMULATE_UNQUOTED([$1], [$2], [CAIRO_$1="${CAIRO_$1}]m4_do([cr_acc_$1_sep])["]_CAIRO_SH_ESCAPE_UNQUOTED([$2]))dnl
301 dnl CAIRO_ACCUMULATE_UNQUOTED_BEFORE(VAR, VALUE)
303 dnl Like CAIRO_ACCUMULATE_BEFORE but VALUE is left unquoted,
304 dnl so it can reference other shell variables for example.
306 AC_DEFUN([CAIRO_ACCUMULATE_UNQUOTED_BEFORE],
308 _CAIRO_ACCUMULATE_UNQUOTED([$1], [$2], [CAIRO_$1=]_CAIRO_SH_ESCAPE_UNQUOTED([$2])["]m4_do([cr_acc_$1_sep])[${CAIRO_$1}"])dnl
312 dnl CAIRO_ACCUMULATE_UNQUOTED_UNCHECKED(VAR, VALUE)
314 dnl Like CAIRO_ACCUMULATE_UNQUOTED but VALUE is not tested for emptiness.
316 AC_DEFUN([CAIRO_ACCUMULATE_UNQUOTED_UNCHECKED],
318 _CAIRO_ACCUMULATE([$1], [$2], [CAIRO_$1="${CAIRO_$1}]m4_do([cr_acc_$1_sep])["]_CAIRO_SH_ESCAPE_UNQUOTED([$2]))dnl
322 dnl CAIRO_ACCUMULATE_UNQUOTED_UNCHECKED_BEFORE(VAR, VALUE)
324 dnl Like CAIRO_ACCUMULATE_UNQUOTED_BEFORE but VALUE is not tested for emptiness.
326 AC_DEFUN([CAIRO_ACCUMULATE_UNQUOTED_BEFORE],
328 _CAIRO_ACCUMULATE([$1], [$2], [CAIRO_$1=]_CAIRO_SH_ESCAPE_UNQUOTED([$2])["]m4_do([cr_acc_$1_sep])[${CAIRO_$1}"])dnl
332 dnl CAIRO_ACCUMULATORS_FOREACH(VAR, COMMANDS)
334 dnl Run COMMANDS for each registered accumulator.
335 dnl Defines VAR to the accumulator being processed.
337 AC_DEFUN([CAIRO_ACCUMULATORS_FOREACH],
339 m4_foreach_w([$1], _CAIRO_ACCUMULATORS, [$2])dnl
343 dnl ===========================================================================
345 m4_define([_CAIRO_ACCUMULATED_FEATURE_VARS])dnl
348 dnl CAIRO_ACCUMULATED_FEATURE_VARS_REGISTER(VARS, DEFAULT-VALUE=[], SEPARATOR=[], INITIAL-VALUE=[])
350 dnl Defines VARS as feature variables and accumulators. Also accumulates
351 dnl (prepending, not appending) feature values for VARS.
353 AC_DEFUN([CAIRO_ACCUMULATED_FEATURE_VARS_REGISTER],
355 m4_foreach_w([cr_var], [$1],
356 [m4_append_uniq([_CAIRO_ACCUMULATED_FEATURE_VARS], cr_var, [ ],,
357 [m4_fatal([Accumulated feature variable `]cr_var[' already registered])])])dnl
358 CAIRO_FEATURE_VARS_REGISTER([$1],[$2])dnl
359 CAIRO_ACCUMULATORS_REGISTER_UNQUOTED([$1],[$3],[$4])dnl
363 dnl CAIRO_ACCUMULATED_FEATURE_VARS_FOREACH(VAR, COMMANDS)
365 dnl Run COMMANDS for each registered accumulated feature variable.
366 dnl Defines VAR to the variable being processed.
368 AC_DEFUN([CAIRO_ACCUMULATED_FEATURE_VARS_FOREACH],
370 m4_foreach_w([$1], _CAIRO_ACCUMULATED_FEATURE_VARS, [$2])dnl
373 dnl ===========================================================================
376 dnl CAIRO_FEATURE_IF_ENABLED(FEATURE=cr_feature, COMMANDS)
378 dnl Run COMMANDS if FEATURE is enabled.
380 AC_DEFUN([CAIRO_FEATURE_IF_ENABLED],
382 AS_IF([test "x$use_]m4_default([$1], cr_feature)[" = xyes], [$2], [$3])dnl
385 m4_define([_CAIRO_FEATURE_HOOK_MATCH_SH_BOOL],
389 [no], [AS_IF([test "x$2" != xyes], [:m4_newline()$3])],
390 [yes], [AS_IF([test "x$2" = xyes], [:m4_newline()$3])],
391 [m4_fatal([Invalid ENABLED value `]$1['])])dnl
394 m4_define([_CAIRO_FEATURE_HOOK_MATCH_M4],
400 [m4_bmatch([$1], [^!], [$3])])dnl
403 m4_define([_CAIRO_FEATURE_HOOKS])dnl
406 dnl CAIRO_FEATURE_HOOK_REGISTER(ENABLED, DEFAULT, WHAT, COMMANDS)
408 dnl ENABLED is the feature enabledness to match
409 dnl DEFAULT is the default value of features to match
410 dnl WHAT is the type of features to match
411 dnl COMMANDS is commands to run for matched features.
413 dnl Runs COMMANDS for features matching ENABLED, DEFAULT, and WHAT.
414 dnl Hooks are run for each feature in the order they are added.
416 dnl DEFAULT and WHAT are matched like this:
417 dnl [*] matches all values
418 dnl [val] matches [val]
419 dnl [!val] matches anything other than [val]
421 dnl ENABLED is matched like this:
422 dnl [yes] matches enabled features
423 dnl [no] matches disabled features
424 dnl [*] matches all features
426 dnl The following macros can be used in COMMANDS:
428 dnl cr_feature expands to the feature id, eg "ft"
429 dnl cr_feature_name expands to the human-readable name of the feature, eg. "FreeType font"
430 dnl cr_feature_default expands to the default state of the feature:
431 dnl "no" for experimental features, eg. your favorite new backend
432 dnl "yes" for recommended features, eg. png functions
433 dnl "auto" for other supported features, eg. xlib surface backend
434 dnl "always" for mandatory features (can't be disabled), eg. image surface backend
435 dnl cr_what expands to the type of feature:
436 dnl "surface" for surface backends
437 dnl "font" for font backends
438 dnl "functions" for set of functions
439 dnl "" for private configurations
441 dnl These four values are also set as $1 to $4. To know if feature was
442 dnl enabled from within COMMANDS, use CAIRO_FEATURE_IF_ENABLED:
444 dnl CAIRO_FEATURE_IF_ENABLED($1, [IF-ENABLED], [IF-DISABLED])
446 dnl or compare $use_$1 to string "yes". As in:
448 dnl AS_IF([test "x$use_$1" = "xyes"], [IF-ENABLED], [IF-DISABLED])
450 AC_DEFUN([CAIRO_FEATURE_HOOK_REGISTER],
452 m4_append([_CAIRO_FEATURE_HOOKS],
454 _CAIRO_FEATURE_HOOK_MATCH_M4([$2], cr_feature_default,
455 [_CAIRO_FEATURE_HOOK_MATCH_M4([$3], cr_feature_what,
456 [_CAIRO_FEATURE_HOOK_MATCH_SH_BOOL([$1], [$use_]cr_feature,