Merge branch 'master' into staging
[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 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|mips64el-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_ASSERT_SYNTAX_OBJECT_EQUAL
122 dnl
123 dnl Guile 2.2.1 was a brown-paper-bag release where 'equal?' wouldn't work
124 dnl for syntax objects, which broke gexps. Unfortunately Fedora 25 provides it.
125 dnl Reject it.
126 AC_DEFUN([GUIX_ASSERT_SYNTAX_OBJECT_EQUAL], [
127 AC_CACHE_CHECK([whether 'equal?' works for syntax objects],
128 [ac_cv_guix_syntax_object_equal],
129 [if "$GUILE" -c '(exit (equal? (syntax x) (syntax x)))'
130 then
131 ac_cv_guix_syntax_object_equal=yes
132 else
133 ac_cv_guix_syntax_object_equal=no
134 fi])
135 if test "x$ac_cv_guix_syntax_object_equal" != xyes; then
136 # This bug was present in Guile 2.2.1 only.
137 AC_MSG_ERROR(['equal?' does not work for syntax object; upgrade to Guile 2.2.2 or later.])
138 fi
139 ])
140
141 dnl GUIX_CHECK_GUILE_SSH
142 dnl
143 dnl Check whether a recent-enough Guile-SSH is available.
144 AC_DEFUN([GUIX_CHECK_GUILE_SSH], [
145 dnl Check whether 'channel-send-eof' (introduced in 0.10.2) is present.
146 AC_CACHE_CHECK([whether Guile-SSH is available and recent enough],
147 [guix_cv_have_recent_guile_ssh],
148 [GUILE_CHECK([retval],
149 [(and (@ (ssh channel) channel-send-eof)
150 (@ (ssh popen) open-remote-pipe)
151 (@ (ssh dist node) node-eval))])
152 if test "$retval" = 0; then
153 guix_cv_have_recent_guile_ssh="yes"
154 else
155 guix_cv_have_recent_guile_ssh="no"
156 fi])
157 ])
158
159 dnl GUIX_CHECK_GUILE_SQLITE3
160 dnl
161 dnl Check whether a recent-enough Guile-Sqlite3 is available.
162 AC_DEFUN([GUIX_CHECK_GUILE_SQLITE3], [
163 dnl Check whether 'sqlite-bind-arguments' is available. It was introduced
164 dnl in February 2018:
165 dnl <https://notabug.org/guile-sqlite3/guile-sqlite3/commit/1cd1dec96a9999db48c0ff45bab907efc637247f>.
166 AC_CACHE_CHECK([whether Guile-Sqlite3 is available and recent enough],
167 [guix_cv_have_recent_guile_sqlite3],
168 [GUILE_CHECK([retval],
169 [(@ (sqlite3) sqlite-bind-arguments)])
170 if test "$retval" = 0; then
171 guix_cv_have_recent_guile_sqlite3="yes"
172 else
173 guix_cv_have_recent_guile_sqlite3="no"
174 fi])
175 ])
176
177 dnl GUIX_CHECK_GUILE_JSON
178 dnl
179 dnl Check whether a recent-enough Guile-JSON is available.
180 AC_DEFUN([GUIX_CHECK_GUILE_JSON], [
181 dnl Check whether we're using Guile-JSON 3.x, which uses a JSON-to-Scheme
182 dnl mapping different from that of earlier versions.
183 AC_CACHE_CHECK([whether Guile-JSON is available and recent enough],
184 [guix_cv_have_recent_guile_json],
185 [GUILE_CHECK([retval],
186 [(use-modules (json) (ice-9 match))
187 (match (json-string->scm \"[[ { \\\"a\\\": 42 } ]]\")
188 (#((("a" . 42))) #t))])
189 if test "$retval" = 0; then
190 guix_cv_have_recent_guile_json="yes"
191 else
192 guix_cv_have_recent_guile_json="no"
193 fi])
194 ])
195
196
197 dnl GUIX_TEST_ROOT_DIRECTORY
198 AC_DEFUN([GUIX_TEST_ROOT_DIRECTORY], [
199 AC_CACHE_CHECK([for unit test root directory],
200 [ac_cv_guix_test_root],
201 [ac_cv_guix_test_root="`pwd`/test-tmp"])
202 ])
203
204 dnl 'BINPRM_BUF_SIZE' constant in Linux (we leave room for the trailing zero.)
205 dnl The Hurd has a limit of about a page (see exec/hashexec.c.)
206 m4_define([LINUX_HASH_BANG_LIMIT], 127)
207
208 dnl Hardcoded 'sun_path' length in <sys/un.h>.
209 m4_define([SOCKET_FILE_NAME_LIMIT], 108)
210
211 dnl GUIX_SOCKET_FILE_NAME_LENGTH
212 AC_DEFUN([GUIX_SOCKET_FILE_NAME_LENGTH], [
213 AC_CACHE_CHECK([the length of the installed socket file name],
214 [ac_cv_guix_socket_file_name_length],
215 [ac_cv_guix_socket_file_name_length="`echo -n "$guix_localstatedir/guix/daemon-socket/socket" | wc -c`"])
216 ])
217
218 dnl GUIX_TEST_SOCKET_FILE_NAME_LENGTH
219 AC_DEFUN([GUIX_TEST_SOCKET_FILE_NAME_LENGTH], [
220 AC_REQUIRE([GUIX_TEST_ROOT_DIRECTORY])
221 AC_CACHE_CHECK([the length of the socket file name used in tests],
222 [ac_cv_guix_test_socket_file_name_length],
223 [ac_cv_guix_test_socket_file_name_length="`echo -n "$ac_cv_guix_test_root/var/123456/daemon-socket/socket" | wc -c`"])
224 ])
225
226 dnl GUIX_HASH_BANG_LENGTH
227 AC_DEFUN([GUIX_HASH_BANG_LENGTH], [
228 AC_CACHE_CHECK([the length of a typical hash bang line],
229 [ac_cv_guix_hash_bang_length],
230 [ac_cv_guix_hash_bang_length=`echo -n "$storedir/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-bootstrap-binaries-0/bin/bash" | wc -c`])
231 ])
232
233 dnl GUIX_TEST_HASH_BANG_LENGTH
234 AC_DEFUN([GUIX_TEST_HASH_BANG_LENGTH], [
235 AC_REQUIRE([GUIX_TEST_ROOT_DIRECTORY])
236 AC_CACHE_CHECK([the length of a hash bang line used in tests],
237 [ac_cv_guix_test_hash_bang_length],
238 [ac_cv_guix_test_hash_bang_length=`echo -n "$ac_cv_guix_test_root/store/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-bootstrap-binaries-0/bin/bash" | wc -c`])
239 ])
240
241 dnl GUIX_CHECK_FILE_NAME_LIMITS
242 dnl
243 dnl GNU/Linux has a couple of silly limits that we can easily run into.
244 dnl Make sure everything is fine with the current settings. Set $1 to
245 dnl 'yes' if tests can run, 'no' otherwise.
246 AC_DEFUN([GUIX_CHECK_FILE_NAME_LIMITS], [
247 AC_REQUIRE([GUIX_SOCKET_FILE_NAME_LENGTH])
248 AC_REQUIRE([GUIX_TEST_SOCKET_FILE_NAME_LENGTH])
249 AC_REQUIRE([GUIX_HASH_BANG_LENGTH])
250 AC_REQUIRE([GUIX_TEST_HASH_BANG_LENGTH])
251
252 if test "$ac_cv_guix_socket_file_name_length" -ge ]SOCKET_FILE_NAME_LIMIT[; then
253 AC_MSG_ERROR([socket file name would exceed the maxium allowed length])
254 fi
255 if test "$ac_cv_guix_test_socket_file_name_length" -ge ]SOCKET_FILE_NAME_LIMIT[; then
256 AC_MSG_WARN([socket file name limit may be exceeded when running tests])
257 fi
258
259 $1=yes
260 if test "$ac_cv_guix_hash_bang_length" -ge ]LINUX_HASH_BANG_LIMIT[; then
261 $1=no
262 AC_MSG_ERROR([store directory '$storedir' would lead to overly long hash-bang lines])
263 fi
264 if test "$ac_cv_guix_test_hash_bang_length" -ge ]LINUX_HASH_BANG_LIMIT[; then
265 $1=no
266 AC_MSG_WARN([test directory '$ac_cv_guix_test_root' may lead to overly long hash-bang lines])
267 fi
268 ])
269
270 dnl GUIX_CHECK_CXX11
271 dnl
272 dnl Check whether the C++ compiler can compile a typical C++11 program.
273 AC_DEFUN([GUIX_CHECK_CXX11], [
274 AC_REQUIRE([AC_PROG_CXX])
275 AC_CACHE_CHECK([whether $CXX supports C++11],
276 [ac_cv_guix_cxx11_support],
277 [save_CXXFLAGS="$CXXFLAGS"
278 CXXFLAGS="-std=c++11 $CXXFLAGS"
279 AC_COMPILE_IFELSE([
280 AC_LANG_SOURCE([
281 #include <functional>
282
283 std::function<int(int)>
284 return_plus_lambda (int x)
285 {
286 auto result = [[&]](int y) {
287 return x + y;
288 };
289
290 return result;
291 }
292 ])],
293 [ac_cv_guix_cxx11_support=yes],
294 [ac_cv_guix_cxx11_support=no])
295 CXXFLAGS="$save_CXXFLAGS"
296 ])
297 ])
298
299 dnl GUIX_ASSERT_CXX11
300 dnl
301 dnl Error out if the C++ compiler cannot compile C++11 code.
302 AC_DEFUN([GUIX_ASSERT_CXX11], [
303 GUIX_CHECK_CXX11
304 if test "x$ac_cv_guix_cxx11_support" != "xyes"; then
305 AC_MSG_ERROR([C++ compiler '$CXX' does not support the C++11 standard])
306 fi
307 ])
308
309 dnl GUIX_LIBGCRYPT_LIBDIR VAR
310 dnl
311 dnl Attempt to determine libgcrypt's LIBDIR; store the result in VAR.
312 AC_DEFUN([GUIX_LIBGCRYPT_LIBDIR], [
313 AC_PATH_PROG([LIBGCRYPT_CONFIG], [libgcrypt-config])
314 AC_CACHE_CHECK([libgcrypt's library directory],
315 [guix_cv_libgcrypt_libdir],
316 [if test "x$LIBGCRYPT_CONFIG" != "x"; then
317 guix_cv_libgcrypt_libdir=`$LIBGCRYPT_CONFIG --libs | grep -e -L | sed -e "s/.*-L\([[^ ]]\+\)[[[:blank:]]]\+-lgcrypt.*/\1/g"`
318 else
319 guix_cv_libgcrypt_libdir=""
320 fi])
321 $1="$guix_cv_libgcrypt_libdir"
322 ])
323
324 dnl GUIX_LIBZ_LIBDIR VAR
325 dnl
326 dnl Attempt to determine libz's LIBDIR; store the result in VAR.
327 AC_DEFUN([GUIX_LIBZ_LIBDIR], [
328 AC_REQUIRE([PKG_PROG_PKG_CONFIG])
329 AC_CACHE_CHECK([zlib's library directory],
330 [guix_cv_libz_libdir],
331 [guix_cv_libz_libdir="`$PKG_CONFIG zlib --variable=libdir 2> /dev/null`"])
332 $1="$guix_cv_libz_libdir"
333 ])
334
335 dnl GUIX_LIBLZ_FILE_NAME VAR
336 dnl
337 dnl Attempt to determine liblz's absolute file name; store the result in VAR.
338 AC_DEFUN([GUIX_LIBLZ_FILE_NAME], [
339 AC_REQUIRE([PKG_PROG_PKG_CONFIG])
340 AC_CACHE_CHECK([lzlib's file name],
341 [guix_cv_liblz_libdir],
342 [old_LIBS="$LIBS"
343 LIBS="-llz"
344 AC_LINK_IFELSE([AC_LANG_SOURCE([int main () { return LZ_decompress_open(); }])],
345 [guix_cv_liblz_libdir="`ldd conftest$EXEEXT | grep liblz | sed '-es/.*=> \(.*\) .*$/\1/g'`"])
346 LIBS="$old_LIBS"])
347 $1="$guix_cv_liblz_libdir"
348 ])
349
350 dnl GUIX_CURRENT_LOCALSTATEDIR
351 dnl
352 dnl Determine the localstatedir of an existing Guix installation and set
353 dnl 'guix_cv_current_localstatedir' accordingly. Set it to "none" if no
354 dnl existing installation was found.
355 AC_DEFUN([GUIX_CURRENT_LOCALSTATEDIR], [
356 AC_PATH_PROG([GUILE], [guile])
357 AC_CACHE_CHECK([the current installation's localstatedir],
358 [guix_cv_current_localstatedir],
359 [dnl Call 'dirname' because (guix config) appends "/guix" to LOCALSTATEDIR.
360 guix_cv_current_localstatedir="`"$GUILE" \
361 -c '(use-modules (guix config))
362 (when (string=? %store-directory "'$storedir'")
363 (display (dirname %state-directory)))' \
364 2>/dev/null`"
365 if test "x$guix_cv_current_localstatedir" = "x"; then
366 guix_cv_current_localstatedir=none
367 fi])])
368
369 dnl GUIX_CHECK_LOCALSTATEDIR
370 dnl
371 dnl Check that the LOCALSTATEDIR value is consistent with that of the existing
372 dnl Guix installation, if any. Error out or warn if they do not match.
373 AC_DEFUN([GUIX_CHECK_LOCALSTATEDIR], [
374 AC_REQUIRE([GUIX_CURRENT_LOCALSTATEDIR])
375 if test "x$guix_cv_current_localstatedir" != "xnone"; then
376 if test "$guix_cv_current_localstatedir" != "$guix_localstatedir"; then
377 case "$localstatedir" in
378 NONE|\${prefix}*)
379 # User kept the default value---i.e., did not pass '--localstatedir'.
380 AC_MSG_ERROR([chosen localstatedir '$guix_localstatedir' does not match \
381 that of the existing installation '$guix_cv_current_localstatedir'
382 Installing may corrupt $storedir!
383 Use './configure --localstatedir=$guix_cv_current_localstatedir'.])
384 ;;
385 *)
386 # User passed an explicit '--localstatedir'. Assume they know what
387 # they're doing.
388 AC_MSG_WARN([chosen localstatedir '$guix_localstatedir' does not match \
389 that of the existing installation '$guix_cv_current_localstatedir'])
390 AC_MSG_WARN([installing may corrupt $storedir!])
391 ;;
392 esac
393 fi
394 fi])