gnu: linux-libre@4.14: Update to 4.14.198.
[jackhill/guix/guix.git] / m4 / guix.m4
1 dnl GNU Guix --- Functional package management for GNU
2 dnl Copyright © 2012, 2013, 2014, 2015, 2016, 2018, 2019, 2020 Ludovic Courtès <ludo@gnu.org>
3 dnl Copyright © 2014 Mark H Weaver <mhw@netris.org>
4 dnl Copyright © 2017 Efraim Flashner <efraim@flashner.co.il>
5 dnl
6 dnl This file is part of GNU Guix.
7 dnl
8 dnl GNU Guix is free software; you can redistribute it and/or modify it
9 dnl under the terms of the GNU General Public License as published by
10 dnl the Free Software Foundation; either version 3 of the License, or (at
11 dnl your option) any later version.
12 dnl
13 dnl GNU Guix is distributed in the hope that it will be useful, but
14 dnl WITHOUT ANY WARRANTY; without even the implied warranty of
15 dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 dnl GNU General Public License for more details.
17 dnl
18 dnl You should have received a copy of the GNU General Public License
19 dnl along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
20
21 dnl GUIX_SYSTEM_TYPE
22 dnl
23 dnl Determine the Guix host system type, and store it in the
24 dnl `guix_system' variable.
25 AC_DEFUN([GUIX_SYSTEM_TYPE], [
26 AC_REQUIRE([AC_CANONICAL_HOST])
27 AC_PATH_PROG([SED], [sed])
28
29 AC_ARG_WITH(system, AC_HELP_STRING([--with-system=SYSTEM],
30 [Platform identifier (e.g., `i686-linux').]),
31 [guix_system="$withval"],
32 [case "$host_cpu" in
33 i*86)
34 machine_name="i686";;
35 amd64)
36 machine_name="x86_64";;
37 arm|armv[[7-9]]*)
38 # Here we want to exclude CPUs such as "armv6l". On ARMv7
39 # machines, we normally get "armv7l". However, in Guix, we
40 # configure with --build=arm-unknown-linux-gnueabihf, leading
41 # to just "arm", so we also have to allow it.
42 #
43 # TODO: If not cross-compiling, add a sanity check to make
44 # sure this build machine has the needed features to
45 # support executables compiled using our armhf gcc,
46 # configured with:
47 # --with-arch=armv7-a
48 # --with-float=hard
49 # --with-mode=thumb
50 # --with-fpu=vfpv3-d16
51 machine_name="armhf";;
52 *)
53 machine_name="$host_cpu";;
54 esac
55
56 case "$host_os" in
57 linux-gnu*)
58 # For backward compatibility, strip the `-gnu' part.
59 guix_system="$machine_name-linux";;
60 gnu*)
61 # Always use i586 for GNU/Hurd.
62 guix_system="i586-gnu";;
63 *)
64 # Strip the version number from names such as `gnu0.3',
65 # `darwin10.2.0', etc.
66 guix_system="$machine_name-`echo $host_os | "$SED" -e's/[0-9.]*$//g'`";;
67 esac])
68
69 AC_MSG_CHECKING([for the Guix system type])
70 AC_MSG_RESULT([$guix_system])
71
72 AC_SUBST([guix_system])
73 ])
74
75 dnl GUIX_ASSERT_SUPPORTED_SYSTEM
76 dnl
77 dnl Assert that this is a system to which the distro is ported.
78 AC_DEFUN([GUIX_ASSERT_SUPPORTED_SYSTEM], [
79 AC_REQUIRE([GUIX_SYSTEM_TYPE])
80
81 AC_ARG_WITH([courage], [AC_HELP_STRING([--with-courage],
82 [Assert that even if this platform is unsupported, you will be
83 courageous and port the GNU System distribution to it (see
84 "GNU Distribution" in the manual.)])],
85 [guix_courageous="$withval"],
86 [guix_courageous="no"])
87
88 # Currently only Linux-based systems are supported, and only on some
89 # platforms.
90 case "$guix_system" in
91 x86_64-linux|i686-linux|armhf-linux|aarch64-linux)
92 ;;
93 *)
94 if test "x$guix_courageous" = "xyes"; then
95 AC_MSG_WARN([building Guix on `$guix_system', which is not supported])
96 else
97 AC_MSG_ERROR([`$guix_system' is not a supported platform.
98 See "GNU Distribution" in the manual, or try `--with-courage'.])
99 fi
100 ;;
101 esac
102 ])
103
104 dnl GUIX_ASSERT_GUILE_FEATURES FEATURES
105 dnl
106 dnl Assert that FEATURES are provided by $GUILE.
107 AC_DEFUN([GUIX_ASSERT_GUILE_FEATURES], [
108 for guix_guile_feature in $1
109 do
110 AC_MSG_CHECKING([whether $GUILE provides feature '$guix_guile_feature'])
111 if "$GUILE" -c "(exit (provided? '$guix_guile_feature))"
112 then
113 AC_MSG_RESULT([yes])
114 else
115 AC_MSG_RESULT([no])
116 AC_MSG_ERROR([$GUILE does not support feature '$guix_guile_feature', which is required.])
117 fi
118 done
119 ])
120
121 dnl GUIX_CHECK_GUILE_SSH
122 dnl
123 dnl Check whether a recent-enough Guile-SSH is available.
124 AC_DEFUN([GUIX_CHECK_GUILE_SSH], [
125 dnl Check whether '#:nodelay' paramater to 'make-session' (introduced in
126 dnl 0.13.0) is present.
127 AC_CACHE_CHECK([whether Guile-SSH is available and recent enough],
128 [guix_cv_have_recent_guile_ssh],
129 [GUILE_CHECK([retval],
130 [(and (@ (ssh channel) channel-send-eof)
131 (@ (ssh popen) open-remote-pipe)
132 (@ (ssh dist node) node-eval)
133 (@ (ssh auth) userauth-gssapi!)
134 ((@ (ssh session) make-session) #:nodelay #t))])
135 if test "$retval" = 0; then
136 guix_cv_have_recent_guile_ssh="yes"
137 else
138 guix_cv_have_recent_guile_ssh="no"
139 fi])
140 ])
141
142 dnl GUIX_CHECK_GUILE_SQLITE3
143 dnl
144 dnl Check whether a recent-enough Guile-Sqlite3 is available.
145 AC_DEFUN([GUIX_CHECK_GUILE_SQLITE3], [
146 dnl Check whether 'sqlite-bind-arguments' is available. It was introduced
147 dnl in February 2018:
148 dnl <https://notabug.org/guile-sqlite3/guile-sqlite3/commit/1cd1dec96a9999db48c0ff45bab907efc637247f>.
149 AC_CACHE_CHECK([whether Guile-Sqlite3 is available and recent enough],
150 [guix_cv_have_recent_guile_sqlite3],
151 [GUILE_CHECK([retval],
152 [(@ (sqlite3) sqlite-bind-arguments)])
153 if test "$retval" = 0; then
154 guix_cv_have_recent_guile_sqlite3="yes"
155 else
156 guix_cv_have_recent_guile_sqlite3="no"
157 fi])
158 ])
159
160 dnl GUIX_CHECK_GUILE_JSON
161 dnl
162 dnl Check whether a recent-enough Guile-JSON is available.
163 AC_DEFUN([GUIX_CHECK_GUILE_JSON], [
164 dnl Check whether we're using Guile-JSON 4.3+, which provides
165 dnl 'define-json-mapping'.
166 AC_CACHE_CHECK([whether Guile-JSON is available and recent enough],
167 [guix_cv_have_recent_guile_json],
168 [GUILE_CHECK([retval],
169 [(use-modules (json))
170
171 (define-json-mapping <frob> make-frob
172 frob?
173 json->frob
174 (a frob-a)
175 (b frob-b \"bee\"))
176
177 (exit
178 (equal? (json->frob
179 (open-input-string \"{ \\\"a\\\": 1, \\\"bee\\\": 2 }\"))
180 (make-frob 1 2)))])
181 if test "$retval" = 0; then
182 guix_cv_have_recent_guile_json="yes"
183 else
184 guix_cv_have_recent_guile_json="no"
185 fi])
186 ])
187
188 dnl GUIX_CHECK_GUILE_GCRYPT
189 dnl
190 dnl Check whether a recent-enough Guile-Gcrypt is available.
191 AC_DEFUN([GUIX_CHECK_GUILE_GCRYPT], [
192 dnl Check whether we're using Guile-Gcrypt 0.2.x or later. 0.2.0
193 dnl introduced the 'hash-algorithm' macro and related code.
194 AC_CACHE_CHECK([whether Guile-Gcrypt is available and recent enough],
195 [guix_cv_have_recent_guile_gcrypt],
196 [GUILE_CHECK([retval],
197 [(use-modules (gcrypt hash))
198 (equal? (hash-algorithm sha256)
199 (lookup-hash-algorithm 'sha256))])
200 if test "$retval" = 0; then
201 guix_cv_have_recent_guile_gcrypt="yes"
202 else
203 guix_cv_have_recent_guile_gcrypt="no"
204 fi])
205 ])
206
207 dnl GUIX_TEST_ROOT_DIRECTORY
208 AC_DEFUN([GUIX_TEST_ROOT_DIRECTORY], [
209 AC_CACHE_CHECK([for unit test root directory],
210 [ac_cv_guix_test_root],
211 [ac_cv_guix_test_root="`pwd`/test-tmp"])
212 ])
213
214 dnl 'BINPRM_BUF_SIZE' constant in Linux (we leave room for the trailing zero.)
215 dnl The Hurd has a limit of about a page (see exec/hashexec.c.)
216 m4_define([LINUX_HASH_BANG_LIMIT], 127)
217
218 dnl Hardcoded 'sun_path' length in <sys/un.h>.
219 m4_define([SOCKET_FILE_NAME_LIMIT], 108)
220
221 dnl GUIX_SOCKET_FILE_NAME_LENGTH
222 AC_DEFUN([GUIX_SOCKET_FILE_NAME_LENGTH], [
223 AC_CACHE_CHECK([the length of the installed socket file name],
224 [ac_cv_guix_socket_file_name_length],
225 [ac_cv_guix_socket_file_name_length="`echo -n "$guix_localstatedir/guix/daemon-socket/socket" | wc -c`"])
226 ])
227
228 dnl GUIX_TEST_SOCKET_FILE_NAME_LENGTH
229 AC_DEFUN([GUIX_TEST_SOCKET_FILE_NAME_LENGTH], [
230 AC_REQUIRE([GUIX_TEST_ROOT_DIRECTORY])
231 AC_CACHE_CHECK([the length of the socket file name used in tests],
232 [ac_cv_guix_test_socket_file_name_length],
233 [ac_cv_guix_test_socket_file_name_length="`echo -n "$ac_cv_guix_test_root/var/123456/daemon-socket/socket" | wc -c`"])
234 ])
235
236 dnl GUIX_HASH_BANG_LENGTH
237 AC_DEFUN([GUIX_HASH_BANG_LENGTH], [
238 AC_CACHE_CHECK([the length of a typical hash bang line],
239 [ac_cv_guix_hash_bang_length],
240 [ac_cv_guix_hash_bang_length=`echo -n "$storedir/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-bootstrap-binaries-0/bin/bash" | wc -c`])
241 ])
242
243 dnl GUIX_TEST_HASH_BANG_LENGTH
244 AC_DEFUN([GUIX_TEST_HASH_BANG_LENGTH], [
245 AC_REQUIRE([GUIX_TEST_ROOT_DIRECTORY])
246 AC_CACHE_CHECK([the length of a hash bang line used in tests],
247 [ac_cv_guix_test_hash_bang_length],
248 [ac_cv_guix_test_hash_bang_length=`echo -n "$ac_cv_guix_test_root/store/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-bootstrap-binaries-0/bin/bash" | wc -c`])
249 ])
250
251 dnl GUIX_CHECK_FILE_NAME_LIMITS
252 dnl
253 dnl GNU/Linux has a couple of silly limits that we can easily run into.
254 dnl Make sure everything is fine with the current settings. Set $1 to
255 dnl 'yes' if tests can run, 'no' otherwise.
256 AC_DEFUN([GUIX_CHECK_FILE_NAME_LIMITS], [
257 AC_REQUIRE([GUIX_SOCKET_FILE_NAME_LENGTH])
258 AC_REQUIRE([GUIX_TEST_SOCKET_FILE_NAME_LENGTH])
259 AC_REQUIRE([GUIX_HASH_BANG_LENGTH])
260 AC_REQUIRE([GUIX_TEST_HASH_BANG_LENGTH])
261
262 if test "$ac_cv_guix_socket_file_name_length" -ge ]SOCKET_FILE_NAME_LIMIT[; then
263 AC_MSG_ERROR([socket file name would exceed the maxium allowed length])
264 fi
265 if test "$ac_cv_guix_test_socket_file_name_length" -ge ]SOCKET_FILE_NAME_LIMIT[; then
266 AC_MSG_WARN([socket file name limit may be exceeded when running tests])
267 fi
268
269 $1=yes
270 if test "$ac_cv_guix_hash_bang_length" -ge ]LINUX_HASH_BANG_LIMIT[; then
271 $1=no
272 AC_MSG_ERROR([store directory '$storedir' would lead to overly long hash-bang lines])
273 fi
274 if test "$ac_cv_guix_test_hash_bang_length" -ge ]LINUX_HASH_BANG_LIMIT[; then
275 $1=no
276 AC_MSG_WARN([test directory '$ac_cv_guix_test_root' may lead to overly long hash-bang lines])
277 fi
278 ])
279
280 dnl GUIX_CHECK_CXX11
281 dnl
282 dnl Check whether the C++ compiler can compile a typical C++11 program.
283 AC_DEFUN([GUIX_CHECK_CXX11], [
284 AC_REQUIRE([AC_PROG_CXX])
285 AC_CACHE_CHECK([whether $CXX supports C++11],
286 [ac_cv_guix_cxx11_support],
287 [save_CXXFLAGS="$CXXFLAGS"
288 CXXFLAGS="-std=c++11 $CXXFLAGS"
289 AC_COMPILE_IFELSE([
290 AC_LANG_SOURCE([
291 #include <functional>
292
293 std::function<int(int)>
294 return_plus_lambda (int x)
295 {
296 auto result = [[&]](int y) {
297 return x + y;
298 };
299
300 return result;
301 }
302 ])],
303 [ac_cv_guix_cxx11_support=yes],
304 [ac_cv_guix_cxx11_support=no])
305 CXXFLAGS="$save_CXXFLAGS"
306 ])
307 ])
308
309 dnl GUIX_ASSERT_CXX11
310 dnl
311 dnl Error out if the C++ compiler cannot compile C++11 code.
312 AC_DEFUN([GUIX_ASSERT_CXX11], [
313 GUIX_CHECK_CXX11
314 if test "x$ac_cv_guix_cxx11_support" != "xyes"; then
315 AC_MSG_ERROR([C++ compiler '$CXX' does not support the C++11 standard])
316 fi
317 ])
318
319 dnl GUIX_LIBGCRYPT_LIBDIR VAR
320 dnl
321 dnl Attempt to determine libgcrypt's LIBDIR; store the result in VAR.
322 AC_DEFUN([GUIX_LIBGCRYPT_LIBDIR], [
323 AC_PATH_PROG([LIBGCRYPT_CONFIG], [libgcrypt-config])
324 AC_CACHE_CHECK([libgcrypt's library directory],
325 [guix_cv_libgcrypt_libdir],
326 [if test "x$LIBGCRYPT_CONFIG" != "x"; then
327 guix_cv_libgcrypt_libdir=`$LIBGCRYPT_CONFIG --libs | grep -e -L | sed -e "s/.*-L\([[^ ]]\+\)[[[:blank:]]]\+-lgcrypt.*/\1/g"`
328 else
329 guix_cv_libgcrypt_libdir=""
330 fi])
331 $1="$guix_cv_libgcrypt_libdir"
332 ])
333
334 dnl GUIX_CURRENT_LOCALSTATEDIR
335 dnl
336 dnl Determine the localstatedir of an existing Guix installation and set
337 dnl 'guix_cv_current_localstatedir' accordingly. Set it to "none" if no
338 dnl existing installation was found.
339 AC_DEFUN([GUIX_CURRENT_LOCALSTATEDIR], [
340 AC_PATH_PROG([GUILE], [guile])
341 AC_CACHE_CHECK([the current installation's localstatedir],
342 [guix_cv_current_localstatedir],
343 [dnl Call 'dirname' because (guix config) appends "/guix" to LOCALSTATEDIR.
344 guix_cv_current_localstatedir="`"$GUILE" \
345 -c '(use-modules (guix config))
346 (when (string=? %store-directory "'$storedir'")
347 (display (dirname %state-directory)))' \
348 2>/dev/null`"
349 if test "x$guix_cv_current_localstatedir" = "x"; then
350 guix_cv_current_localstatedir=none
351 fi])])
352
353 dnl GUIX_CHECK_LOCALSTATEDIR
354 dnl
355 dnl Check that the LOCALSTATEDIR value is consistent with that of the existing
356 dnl Guix installation, if any. Error out or warn if they do not match.
357 AC_DEFUN([GUIX_CHECK_LOCALSTATEDIR], [
358 AC_REQUIRE([GUIX_CURRENT_LOCALSTATEDIR])
359 if test "x$guix_cv_current_localstatedir" != "xnone"; then
360 if test "$guix_cv_current_localstatedir" != "$guix_localstatedir"; then
361 case "$localstatedir" in
362 NONE|\${prefix}*)
363 # User kept the default value---i.e., did not pass '--localstatedir'.
364 AC_MSG_ERROR([chosen localstatedir '$guix_localstatedir' does not match \
365 that of the existing installation '$guix_cv_current_localstatedir'
366 Installing may corrupt $storedir!
367 Use './configure --localstatedir=$guix_cv_current_localstatedir'.])
368 ;;
369 *)
370 # User passed an explicit '--localstatedir'. Assume they know what
371 # they're doing.
372 AC_MSG_WARN([chosen localstatedir '$guix_localstatedir' does not match \
373 that of the existing installation '$guix_cv_current_localstatedir'])
374 AC_MSG_WARN([installing may corrupt $storedir!])
375 ;;
376 esac
377 fi
378 fi])