]> git.draconx.ca Git - dxcommon.git/blob - m4/libhelper.m4
DX_C_ALIGNAS: Work around bash-5 parsing bug.
[dxcommon.git] / m4 / libhelper.m4
1 dnl Copyright © 2014, 2019 Nick Bowler
2 dnl
3 dnl Helper macros for implementing library tests.
4 dnl
5 dnl License WTFPL2: Do What The Fuck You Want To Public License, version 2.
6 dnl This is free software: you are free to do what the fuck you want to.
7 dnl There is NO WARRANTY, to the extent permitted by law.
8
9 dnl DX_LIB_SETUP(env-base, [human-name])
10 dnl
11 dnl Helper to setup a library test.  Defines two user variables FOO_CFLAGS
12 dnl and FOO_LIBS, where FOO is replaced with env-base in uppercase.  The
13 dnl human-name is the name of the library used in help text, by default the
14 dnl same as env-base.
15 AC_DEFUN([DX_LIB_SETUP],
16   [m4_do([AC_ARG_VAR(AS_TR_SH([m4_toupper([$1])])[_CFLAGS],
17                               [C compiler flags for ]m4_default([$2], [$1]))],
18          [AC_ARG_VAR(AS_TR_SH([m4_toupper([$1])])[_LIBS],
19                               [linker flags for ]m4_default([$2], [$1]))])])
20
21 dnl DX_LIB_PKGCONFIG_FLAGS(env-base, [library-name])
22 dnl
23 dnl Helper for querying a library's CFLAGS and LIBS values from the
24 dnl pkg-config database.  The results are stored in the cache variables
25 dnl dx_cv_foo_pkg_cflags and dx_cv_foo_pkg_libs, where foo is replaced with
26 dnl env-base in lowercase.  If not specified, the library name defaults to
27 dnl env-base.
28 AC_DEFUN([DX_LIB_PKGCONFIG_FLAGS],
29   [_DX_LIB_PKGCONFIG_FLAGS(AS_TR_SH([m4_tolower([$1])]),
30     [m4_default([$2], [$1])])])
31
32 dnl Internal helper macro for the above.
33 AC_DEFUN([_DX_LIB_PKGCONFIG_FLAGS], [AS_IF([test x"$PKG_CONFIG" != x""],
34         [AC_CACHE_CHECK([pkg-config database for $2], [dx_cv_$1_pkg_found],
35                 [m4_do([dx_cv_$1_pkg_found=yes],
36                         [m4_newline([DX_PKG_CONFIG([dx_cv_$1_pkg_cflags],
37                                 [--cflags "$2"], [],
38                                 [dx_cv_$1_pkg_found=no])])],
39                         [m4_newline([DX_PKG_CONFIG([dx_cv_$1_pkg_libs],
40                                 [--libs "$2"], [],
41                                 [dx_cv_$1_pkg_found=no])])])])])])
42
43 dnl DX_LIB_SEARCH(env-base, test, test-matrix)
44 dnl
45 dnl Helper to search for the correct compiler/linker flags for a particular
46 dnl library.  The test-matrix is an ordered, quoted list of quoted lists.
47 dnl Each entry in the test matrix has the following form:
48 dnl
49 dnl    [cflags, libs, shell-condition]
50 dnl
51 dnl For each item, the specified cflags and libs are temporarily appended to
52 dnl CFLAGS and LIBS, respectively, then the given test is run.  The test
53 dnl argument must be an m4 macro which takes one argument (action-if-ok).
54 dnl This macro shall expand to shell code which executes action-if-ok if and
55 dnl only if the test was successful.  The test macro is expanded only once.
56 dnl
57 dnl If a test is successful, dx_cv_foo_lib_found is set to "yes", where foo is
58 dnl replaced with env-base in lowercase.  Subsequent tests are not tried.
59 dnl The cflags and libs values from a successful test are stored in FOO_CFLAGS
60 dnl and FOO_LIBS, respectively, where FOO is replaced with env-base in
61 dnl uppercase.  These values are AC_SUBST-ed.  If no test was successful,
62 dnl dx_cv_foo_lib_found is set to "no".
63 dnl
64 dnl The result ("yes" or "no") are printed so this macro should be preceded
65 dnl by a call to AC_MSG_CHECKING.
66 AC_DEFUN([DX_LIB_SEARCH], [m4_divert_push([KILL])
67
68 m4_pushdef([_DX_CVNAME], AS_TR_SH([m4_tolower([dx_cv_$1_lib_])])[$][1])
69 m4_pushdef([_DX_FNNAME], AS_TR_SH([m4_tolower([dx_fn_$1_lib_])])[$][1])
70
71 m4_divert([INIT_PREPARE])dnl
72 # Helper function to test whether $1 works.
73 _DX_FNNAME([test]) () {
74 CFLAGS="$_dx_save_cflags $[]1"
75 LIBS="$_dx_save_libs $[]2"
76 m4_apply([$2], [dnl
77         _DX_CVNAME([found])=yes
78         _DX_CVNAME([cflags])=$[]1
79         _DX_CVNAME([libs])=$[]2])
80 }
81
82 m4_divert_pop()dnl
83 AC_CACHE_VAL([_DX_CVNAME([found])], [dnl
84 _DX_CVNAME([found])=no
85 _dx_save_cflags=$CFLAGS
86 _dx_save_libs=$LIBS
87 m4_map_sep([_DX_LIB_TEST], [m4_newline], [$3])
88 DX_VAR_NORMALIZE_SPACE([_DX_CVNAME([cflags])])
89 DX_VAR_NORMALIZE_SPACE([_DX_CVNAME([libs])])
90 CFLAGS=$_dx_save_cflags
91 LIBS=$_dx_save_libs])dnl
92
93 AC_MSG_RESULT([$_DX_CVNAME([found])])
94 AS_IF([test x"$_DX_CVNAME([found])" = x"yes"],
95   [m4_do([AC_SUBST(AS_TR_SH([m4_toupper([$1_CFLAGS])]),
96                    [$_DX_CVNAME([cflags])])],
97          [AC_SUBST(AS_TR_SH([m4_toupper([$1_LIBS])]),
98                    [$_DX_CVNAME([libs])])])])
99 m4_popdef([_DX_CVNAME], [_DX_FNNAME])])
100
101 dnl Internal helper macro for the above.
102 AC_DEFUN([_DX_LIB_TEST],
103         [AS_IF([m4_do([test x"$_DX_CVNAME([found])" != x"yes"],
104                 [m4_ifnblank([$3], [ && $3])])],
105         [_DX_FNNAME([test]) "$1" "$2"])])
106
107 dnl DX_LIB_SEARCH_LINK(env-base, test-program, test-matrix)
108 dnl
109 dnl Convenience wrapper around DX_LIB_SEARCH which implements the test
110 dnl function by attempting to linking the provided test program.
111 AC_DEFUN([DX_LIB_SEARCH_LINK],
112         [DX_LIB_SEARCH([$1], [m4_curry([AC_LINK_IFELSE], [$2])], [$3])])
113
114 dnl DX_LIB_USERFLAG_BLURB(env-base, [human-name])
115 dnl
116 dnl Expand to text explaining the FOO_CFLAGS and FOO_LIBS environment
117 dnl variables, used in error messages, where FOO is replaced with env-base
118 dnl in uppercase.  The human-name is the name of the library, by default the
119 dnl same as env-base.
120 AC_DEFUN([DX_LIB_USERFLAG_BLURB],
121         [_DX_LIB_USERFLAG_BLURB([m4_toupper([$1])], [m4_default([$2], [$1])])])
122
123 dnl Internal helper macro for the above.
124 AC_DEFUN([_DX_LIB_USERFLAG_BLURB], [dnl
125 If $2 is installed but was not detected by this configure script,
126 consider adjusting $1_CFLAGS and/or $1_LIBS as necessary.])
127
128 dnl DX_LIB_USERFLAG_BLURB(env-base, [human-name])
129 dnl
130 dnl Expand to text explaining the PKG_CONFIG_PATH environment variable,
131 dnl used in error messages.  The human-name is the name of the library, by
132 dnl default the same as env-base.
133 AC_DEFUN([DX_LIB_PKGCONFIG_BLURB],
134         [_DX_LIB_PKGCONFIG_BLURB([$1], [m4_default([$2], [$1])])])
135
136 dnl Internal helper macro for the above.
137 AC_DEFUN([_DX_LIB_PKGCONFIG_BLURB], [dnl
138 If pkg-config is installed, it may help to adjust PKG_CONFIG_PATH if
139 $2 is installed in a non-standard prefix.])
140
141 dnl DX_LIB_COMPILE_ERROR([text])
142 dnl
143 dnl Expand to C code which should fail compilation.  The given text should
144 dnl appear in any error message from the compiler, and should not contain
145 dnl any newlines.
146 AC_DEFUN([DX_LIB_COMPILE_ERROR], [m4_do([m4_newline([@%:@error $1])],
147         [m4_newline([static int AS_TR_SH([$1])@<:@-1@:>@;])])])