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>
6 dnl This file is part of GNU Guix.
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.
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.
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/>.
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])
29 AC_ARG_WITH(system, AC_HELP_STRING([--with-system=SYSTEM],
30 [Platform identifier (e.g., `i686-linux').]),
31 [guix_system="$withval"],
36 machine_name="x86_64";;
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.
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,
50 # --with-fpu=vfpv3-d16
51 machine_name="armhf";;
53 machine_name="$host_cpu";;
58 # For backward compatibility, strip the `-gnu' part.
59 guix_system="$machine_name-linux";;
61 # Always use i586 for GNU/Hurd.
62 guix_system="i586-gnu";;
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'`";;
69 AC_MSG_CHECKING([for the Guix system type])
70 AC_MSG_RESULT([$guix_system])
72 AC_SUBST([guix_system])
75 dnl GUIX_ASSERT_SUPPORTED_SYSTEM
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])
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"])
88 # Currently only Linux-based systems are supported, and only on some
90 case "$guix_system" in
91 x86_64-linux|i686-linux|armhf-linux|aarch64-linux)
94 if test "x$guix_courageous" = "xyes"; then
95 AC_MSG_WARN([building Guix on `$guix_system', which is not supported])
97 AC_MSG_ERROR([`$guix_system' is not a supported platform.
98 See "GNU Distribution" in the manual, or try `--with-courage'.])
104 dnl GUIX_ASSERT_GUILE_FEATURES FEATURES
106 dnl Assert that FEATURES are provided by $GUILE.
107 AC_DEFUN([GUIX_ASSERT_GUILE_FEATURES], [
108 for guix_guile_feature in $1
110 AC_MSG_CHECKING([whether $GUILE provides feature '$guix_guile_feature'])
111 if "$GUILE" -c "(exit (provided? '$guix_guile_feature))"
116 AC_MSG_ERROR([$GUILE does not support feature '$guix_guile_feature', which is required.])
121 dnl GUIX_CHECK_GUILE_SSH
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"
138 guix_cv_have_recent_guile_ssh="no"
142 dnl GUIX_CHECK_GUILE_SQLITE3
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"
156 guix_cv_have_recent_guile_sqlite3="no"
160 dnl GUIX_CHECK_GUILE_JSON
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))
171 (define-json-mapping <frob> make-frob
179 (open-input-string \"{ \\\"a\\\": 1, \\\"bee\\\": 2 }\"))
181 if test "$retval" = 0; then
182 guix_cv_have_recent_guile_json="yes"
184 guix_cv_have_recent_guile_json="no"
188 dnl GUIX_CHECK_GUILE_GCRYPT
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"
203 guix_cv_have_recent_guile_gcrypt="no"
207 dnl GUIX_CHECK_GUILE_GIT
209 dnl Check whether a recent-enough Guile-Git is available.
210 AC_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)))
221 #:fetch-options (make-fetch-options auth)))])
222 if test "$retval" = 0; then
223 guix_cv_have_recent_guile_git="yes"
225 guix_cv_have_recent_guile_git="no"
229 dnl GUIX_TEST_ROOT_DIRECTORY
230 AC_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"])
236 dnl 'BINPRM_BUF_SIZE' constant in Linux (we leave room for the trailing zero.)
237 dnl The Hurd has a limit of about a page (see exec/hashexec.c.)
238 m4_define([LINUX_HASH_BANG_LIMIT], 127)
240 dnl Hardcoded 'sun_path' length in <sys/un.h>.
241 m4_define([SOCKET_FILE_NAME_LIMIT], 108)
243 dnl GUIX_SOCKET_FILE_NAME_LENGTH
244 AC_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`"])
250 dnl GUIX_TEST_SOCKET_FILE_NAME_LENGTH
251 AC_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`"])
258 dnl GUIX_HASH_BANG_LENGTH
259 AC_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`])
265 dnl GUIX_TEST_HASH_BANG_LENGTH
266 AC_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`])
273 dnl GUIX_CHECK_FILE_NAME_LIMITS
275 dnl GNU/Linux has a couple of silly limits that we can easily run into.
276 dnl Make sure everything is fine with the current settings. Set $1 to
277 dnl 'yes' if tests can run, 'no' otherwise.
278 AC_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])
282 AC_REQUIRE([GUIX_TEST_HASH_BANG_LENGTH])
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])
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])
292 if test "$ac_cv_guix_hash_bang_length" -ge ]LINUX_HASH_BANG_LIMIT[; then
294 AC_MSG_ERROR([store directory '$storedir' would lead to overly long hash-bang lines])
296 if test "$ac_cv_guix_test_hash_bang_length" -ge ]LINUX_HASH_BANG_LIMIT[; then
298 AC_MSG_WARN([test directory '$ac_cv_guix_test_root' may lead to overly long hash-bang lines])
304 dnl Check whether the C++ compiler can compile a typical C++11 program.
305 AC_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"
313 #include <functional>
315 std::function<int(int)>
316 return_plus_lambda (int x)
318 auto result = [[&]](int y) {
325 [ac_cv_guix_cxx11_support=yes],
326 [ac_cv_guix_cxx11_support=no])
327 CXXFLAGS="$save_CXXFLAGS"
331 dnl GUIX_ASSERT_CXX11
333 dnl Error out if the C++ compiler cannot compile C++11 code.
334 AC_DEFUN([GUIX_ASSERT_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])
341 dnl GUIX_LIBGCRYPT_LIBDIR VAR
343 dnl Attempt to determine libgcrypt's LIBDIR; store the result in VAR.
344 AC_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
349 guix_cv_libgcrypt_libdir=`$LIBGCRYPT_CONFIG --libs | grep -e -L | sed -e "s/.*-L\([[^ ]]\+\)[[[:blank:]]]\+-lgcrypt.*/\1/g"`
351 guix_cv_libgcrypt_libdir=""
353 $1="$guix_cv_libgcrypt_libdir"
356 dnl GUIX_CURRENT_LOCALSTATEDIR
358 dnl Determine the localstatedir of an existing Guix installation and set
359 dnl 'guix_cv_current_localstatedir' accordingly. Set it to "none" if no
360 dnl existing installation was found.
361 AC_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)))' \
371 if test "x$guix_cv_current_localstatedir" = "x"; then
372 guix_cv_current_localstatedir=none
375 dnl GUIX_CHECK_LOCALSTATEDIR
377 dnl Check that the LOCALSTATEDIR value is consistent with that of the existing
378 dnl Guix installation, if any. Error out or warn if they do not match.
379 AC_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
385 # User kept the default value---i.e., did not pass '--localstatedir'.
386 AC_MSG_ERROR([chosen localstatedir '$guix_localstatedir' does not match \
387 that of the existing installation '$guix_cv_current_localstatedir'
388 Installing may corrupt $storedir!
389 Use './configure --localstatedir=$guix_cv_current_localstatedir'.])
392 # User passed an explicit '--localstatedir'. Assume they know what
394 AC_MSG_WARN([chosen localstatedir '$guix_localstatedir' does not match \
395 that of the existing installation '$guix_cv_current_localstatedir'])
396 AC_MSG_WARN([installing may corrupt $storedir!])