Merge branch 'ungrafting' into staging
[jackhill/guix/guix.git] / m4 / guix.m4
CommitLineData
2357f850 1dnl GNU Guix --- Functional package management for GNU
c1dc50ab 2dnl Copyright © 2012, 2013, 2014, 2015, 2016, 2018, 2019, 2020 Ludovic Courtès <ludo@gnu.org>
aa1e1947 3dnl Copyright © 2014 Mark H Weaver <mhw@netris.org>
3b88f376 4dnl Copyright © 2017 Efraim Flashner <efraim@flashner.co.il>
d388c2c4 5dnl
2357f850 6dnl This file is part of GNU Guix.
d388c2c4 7dnl
2357f850 8dnl GNU Guix is free software; you can redistribute it and/or modify it
d388c2c4
LC
9dnl under the terms of the GNU General Public License as published by
10dnl the Free Software Foundation; either version 3 of the License, or (at
11dnl your option) any later version.
12dnl
2357f850 13dnl GNU Guix is distributed in the hope that it will be useful, but
d388c2c4
LC
14dnl WITHOUT ANY WARRANTY; without even the implied warranty of
15dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16dnl GNU General Public License for more details.
17dnl
18dnl You should have received a copy of the GNU General Public License
2357f850 19dnl along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
d388c2c4 20
c2033df4
LC
21dnl GUIX_SYSTEM_TYPE
22dnl
23dnl Determine the Guix host system type, and store it in the
24dnl `guix_system' variable.
25AC_DEFUN([GUIX_SYSTEM_TYPE], [
26 AC_REQUIRE([AC_CANONICAL_HOST])
eb25a30a
LC
27 AC_PATH_PROG([SED], [sed])
28
dbdae9f9 29 AC_ARG_WITH(system, AS_HELP_STRING([--with-system=SYSTEM],
c2033df4
LC
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)
968ae903 36 machine_name="x86_64";;
dfdb15d9 37 arm|armv[[7-9]]*)
968ae903
LC
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 #
aa1e1947
MW
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";;
c2033df4
LC
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";;
4ed40a3e
MR
60 gnu*)
61 # Always use i586 for GNU/Hurd.
62 guix_system="i586-gnu";;
c2033df4
LC
63 *)
64 # Strip the version number from names such as `gnu0.3',
65 # `darwin10.2.0', etc.
eb25a30a 66 guix_system="$machine_name-`echo $host_os | "$SED" -e's/[0-9.]*$//g'`";;
c2033df4 67 esac])
5fedc65b
LC
68
69 AC_MSG_CHECKING([for the Guix system type])
70 AC_MSG_RESULT([$guix_system])
71
d8eea3d2 72 AC_SUBST([guix_system])
c2033df4 73])
9c7dd33a 74
b97556d7
LC
75dnl GUIX_ASSERT_SUPPORTED_SYSTEM
76dnl
77dnl Assert that this is a system to which the distro is ported.
78AC_DEFUN([GUIX_ASSERT_SUPPORTED_SYSTEM], [
79 AC_REQUIRE([GUIX_SYSTEM_TYPE])
80
dbdae9f9 81 AC_ARG_WITH([courage], [AS_HELP_STRING([--with-courage],
b97556d7
LC
82 [Assert that even if this platform is unsupported, you will be
83courageous 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
03e64049 91 x86_64-linux|i686-linux|armhf-linux|aarch64-linux)
b97556d7
LC
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.
98See "GNU Distribution" in the manual, or try `--with-courage'.])
99 fi
100 ;;
101 esac
102])
103
9c7dd33a
LC
104dnl GUIX_ASSERT_GUILE_FEATURES FEATURES
105dnl
106dnl Assert that FEATURES are provided by $GUILE.
107AC_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])
1959fb04 120
21531add
LC
121dnl GUIX_CHECK_GUILE_SSH
122dnl
123dnl Check whether a recent-enough Guile-SSH is available.
124AC_DEFUN([GUIX_CHECK_GUILE_SSH], [
e8088f0b
LDB
125 dnl Check whether '#:nodelay' paramater to 'make-session' (introduced in
126 dnl 0.13.0) is present.
21531add
LC
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)
37891872 132 (@ (ssh dist node) node-eval)
e8088f0b
LDB
133 (@ (ssh auth) userauth-gssapi!)
134 ((@ (ssh session) make-session) #:nodelay #t))])
21531add
LC
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
d59e75f3
LC
142dnl GUIX_CHECK_GUILE_SQLITE3
143dnl
144dnl Check whether a recent-enough Guile-Sqlite3 is available.
145AC_DEFUN([GUIX_CHECK_GUILE_SQLITE3], [
146 dnl Check whether 'sqlite-bind-arguments' is available. It was introduced
147 dnl in February 2018:
60e1c109 148 dnl <https://notabug.org/guile-sqlite3/guile-sqlite3/commit/1cd1dec96a9999db48c0ff45bab907efc637247f>.
d59e75f3
LC
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
81c3dc32
LC
160dnl GUIX_CHECK_GUILE_JSON
161dnl
162dnl Check whether a recent-enough Guile-JSON is available.
163AC_DEFUN([GUIX_CHECK_GUILE_JSON], [
b5eb901a
LC
164 dnl Check whether we're using Guile-JSON 4.3+, which provides
165 dnl 'define-json-mapping'.
81c3dc32
LC
166 AC_CACHE_CHECK([whether Guile-JSON is available and recent enough],
167 [guix_cv_have_recent_guile_json],
168 [GUILE_CHECK([retval],
b5eb901a
LC
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)))])
81c3dc32
LC
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
c1dc50ab
LC
188dnl GUIX_CHECK_GUILE_GCRYPT
189dnl
190dnl Check whether a recent-enough Guile-Gcrypt is available.
191AC_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])
81c3dc32 206
59bb1ae3
LC
207dnl GUIX_CHECK_GUILE_GIT
208dnl
209dnl Check whether a recent-enough Guile-Git is available.
210AC_DEFUN([GUIX_CHECK_GUILE_GIT], [
211 dnl Check whether we're using Guile-Git 0.3.0 or later. 0.3.0
212 dnl introduced SSH authentication support and more.
213 AC_CACHE_CHECK([whether Guile-Git is available and recent enough],
214 [guix_cv_have_recent_guile_git],
215 [GUILE_CHECK([retval],
216 [(use-modules (git) (git auth) (git submodule))
217 (let ((auth (%make-auth-ssh-agent)))
218 repository-close!
219 object-lookup-prefix
220 (make-clone-options
221 #:fetch-options (make-fetch-options auth)))])
222 if test "$retval" = 0; then
223 guix_cv_have_recent_guile_git="yes"
224 else
225 guix_cv_have_recent_guile_git="no"
226 fi])
227])
228
2178ed66
LC
229dnl GUIX_TEST_ROOT_DIRECTORY
230AC_DEFUN([GUIX_TEST_ROOT_DIRECTORY], [
231 AC_CACHE_CHECK([for unit test root directory],
232 [ac_cv_guix_test_root],
233 [ac_cv_guix_test_root="`pwd`/test-tmp"])
234])
235
93ce8a8e
LC
236dnl 'BINPRM_BUF_SIZE' constant in Linux (we leave room for the trailing zero.)
237dnl The Hurd has a limit of about a page (see exec/hashexec.c.)
238m4_define([LINUX_HASH_BANG_LIMIT], 127)
2178ed66
LC
239
240dnl Hardcoded 'sun_path' length in <sys/un.h>.
241m4_define([SOCKET_FILE_NAME_LIMIT], 108)
242
243dnl GUIX_SOCKET_FILE_NAME_LENGTH
244AC_DEFUN([GUIX_SOCKET_FILE_NAME_LENGTH], [
245 AC_CACHE_CHECK([the length of the installed socket file name],
246 [ac_cv_guix_socket_file_name_length],
247 [ac_cv_guix_socket_file_name_length="`echo -n "$guix_localstatedir/guix/daemon-socket/socket" | wc -c`"])
248])
249
250dnl GUIX_TEST_SOCKET_FILE_NAME_LENGTH
251AC_DEFUN([GUIX_TEST_SOCKET_FILE_NAME_LENGTH], [
252 AC_REQUIRE([GUIX_TEST_ROOT_DIRECTORY])
253 AC_CACHE_CHECK([the length of the socket file name used in tests],
254 [ac_cv_guix_test_socket_file_name_length],
255 [ac_cv_guix_test_socket_file_name_length="`echo -n "$ac_cv_guix_test_root/var/123456/daemon-socket/socket" | wc -c`"])
256])
257
258dnl GUIX_HASH_BANG_LENGTH
259AC_DEFUN([GUIX_HASH_BANG_LENGTH], [
260 AC_CACHE_CHECK([the length of a typical hash bang line],
261 [ac_cv_guix_hash_bang_length],
262 [ac_cv_guix_hash_bang_length=`echo -n "$storedir/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-bootstrap-binaries-0/bin/bash" | wc -c`])
263])
264
27ab3cee
LC
265dnl GUIX_TEST_HASH_BANG_LENGTH
266AC_DEFUN([GUIX_TEST_HASH_BANG_LENGTH], [
267 AC_REQUIRE([GUIX_TEST_ROOT_DIRECTORY])
268 AC_CACHE_CHECK([the length of a hash bang line used in tests],
269 [ac_cv_guix_test_hash_bang_length],
270 [ac_cv_guix_test_hash_bang_length=`echo -n "$ac_cv_guix_test_root/store/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-bootstrap-binaries-0/bin/bash" | wc -c`])
271])
272
2178ed66
LC
273dnl GUIX_CHECK_FILE_NAME_LIMITS
274dnl
275dnl GNU/Linux has a couple of silly limits that we can easily run into.
bb251307
LC
276dnl Make sure everything is fine with the current settings. Set $1 to
277dnl 'yes' if tests can run, 'no' otherwise.
2178ed66
LC
278AC_DEFUN([GUIX_CHECK_FILE_NAME_LIMITS], [
279 AC_REQUIRE([GUIX_SOCKET_FILE_NAME_LENGTH])
280 AC_REQUIRE([GUIX_TEST_SOCKET_FILE_NAME_LENGTH])
281 AC_REQUIRE([GUIX_HASH_BANG_LENGTH])
27ab3cee 282 AC_REQUIRE([GUIX_TEST_HASH_BANG_LENGTH])
2178ed66
LC
283
284 if test "$ac_cv_guix_socket_file_name_length" -ge ]SOCKET_FILE_NAME_LIMIT[; then
285 AC_MSG_ERROR([socket file name would exceed the maxium allowed length])
286 fi
287 if test "$ac_cv_guix_test_socket_file_name_length" -ge ]SOCKET_FILE_NAME_LIMIT[; then
288 AC_MSG_WARN([socket file name limit may be exceeded when running tests])
289 fi
bb251307
LC
290
291 $1=yes
2178ed66 292 if test "$ac_cv_guix_hash_bang_length" -ge ]LINUX_HASH_BANG_LIMIT[; then
bb251307 293 $1=no
2178ed66
LC
294 AC_MSG_ERROR([store directory '$storedir' would lead to overly long hash-bang lines])
295 fi
27ab3cee 296 if test "$ac_cv_guix_test_hash_bang_length" -ge ]LINUX_HASH_BANG_LIMIT[; then
bb251307 297 $1=no
27ab3cee
LC
298 AC_MSG_WARN([test directory '$ac_cv_guix_test_root' may lead to overly long hash-bang lines])
299 fi
2178ed66 300])
368d08f7
LC
301
302dnl GUIX_CHECK_CXX11
303dnl
304dnl Check whether the C++ compiler can compile a typical C++11 program.
305AC_DEFUN([GUIX_CHECK_CXX11], [
306 AC_REQUIRE([AC_PROG_CXX])
307 AC_CACHE_CHECK([whether $CXX supports C++11],
308 [ac_cv_guix_cxx11_support],
309 [save_CXXFLAGS="$CXXFLAGS"
310 CXXFLAGS="-std=c++11 $CXXFLAGS"
311 AC_COMPILE_IFELSE([
312 AC_LANG_SOURCE([
313 #include <functional>
314
315 std::function<int(int)>
316 return_plus_lambda (int x)
317 {
318 auto result = [[&]](int y) {
319 return x + y;
320 };
321
322 return result;
323 }
324 ])],
325 [ac_cv_guix_cxx11_support=yes],
326 [ac_cv_guix_cxx11_support=no])
327 CXXFLAGS="$save_CXXFLAGS"
328 ])
329])
330
331dnl GUIX_ASSERT_CXX11
332dnl
333dnl Error out if the C++ compiler cannot compile C++11 code.
334AC_DEFUN([GUIX_ASSERT_CXX11], [
335 GUIX_CHECK_CXX11
336 if test "x$ac_cv_guix_cxx11_support" != "xyes"; then
337 AC_MSG_ERROR([C++ compiler '$CXX' does not support the C++11 standard])
338 fi
339])
12e5b266 340
dd01fecd
LC
341dnl GUIX_LIBGCRYPT_LIBDIR VAR
342dnl
343dnl Attempt to determine libgcrypt's LIBDIR; store the result in VAR.
344AC_DEFUN([GUIX_LIBGCRYPT_LIBDIR], [
345 AC_PATH_PROG([LIBGCRYPT_CONFIG], [libgcrypt-config])
346 AC_CACHE_CHECK([libgcrypt's library directory],
347 [guix_cv_libgcrypt_libdir],
348 [if test "x$LIBGCRYPT_CONFIG" != "x"; then
ca34fc31 349 guix_cv_libgcrypt_libdir=`$LIBGCRYPT_CONFIG --libs | grep -e -L | sed -e "s/.*-L\([[^ ]]\+\)[[[:blank:]]]\+-lgcrypt.*/\1/g"`
dd01fecd
LC
350 else
351 guix_cv_libgcrypt_libdir=""
352 fi])
353 $1="$guix_cv_libgcrypt_libdir"
354])
ef5f5c86
LC
355
356dnl GUIX_CURRENT_LOCALSTATEDIR
357dnl
358dnl Determine the localstatedir of an existing Guix installation and set
359dnl 'guix_cv_current_localstatedir' accordingly. Set it to "none" if no
360dnl existing installation was found.
361AC_DEFUN([GUIX_CURRENT_LOCALSTATEDIR], [
362 AC_PATH_PROG([GUILE], [guile])
363 AC_CACHE_CHECK([the current installation's localstatedir],
364 [guix_cv_current_localstatedir],
365 [dnl Call 'dirname' because (guix config) appends "/guix" to LOCALSTATEDIR.
366 guix_cv_current_localstatedir="`"$GUILE" \
367 -c '(use-modules (guix config))
368 (when (string=? %store-directory "'$storedir'")
369 (display (dirname %state-directory)))' \
370 2>/dev/null`"
371 if test "x$guix_cv_current_localstatedir" = "x"; then
372 guix_cv_current_localstatedir=none
373 fi])])
374
375dnl GUIX_CHECK_LOCALSTATEDIR
376dnl
377dnl Check that the LOCALSTATEDIR value is consistent with that of the existing
378dnl Guix installation, if any. Error out or warn if they do not match.
379AC_DEFUN([GUIX_CHECK_LOCALSTATEDIR], [
380 AC_REQUIRE([GUIX_CURRENT_LOCALSTATEDIR])
381 if test "x$guix_cv_current_localstatedir" != "xnone"; then
382 if test "$guix_cv_current_localstatedir" != "$guix_localstatedir"; then
383 case "$localstatedir" in
384 NONE|\${prefix}*)
385 # User kept the default value---i.e., did not pass '--localstatedir'.
386 AC_MSG_ERROR([chosen localstatedir '$guix_localstatedir' does not match \
387that of the existing installation '$guix_cv_current_localstatedir'
388Installing may corrupt $storedir!
389Use './configure --localstatedir=$guix_cv_current_localstatedir'.])
390 ;;
391 *)
392 # User passed an explicit '--localstatedir'. Assume they know what
393 # they're doing.
394 AC_MSG_WARN([chosen localstatedir '$guix_localstatedir' does not match \
395that of the existing installation '$guix_cv_current_localstatedir'])
396 AC_MSG_WARN([installing may corrupt $storedir!])
397 ;;
398 esac
399 fi
400 fi])