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_ASSERT_SYNTAX_OBJECT_EQUAL
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.
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)))'
131 ac_cv_guix_syntax_object_equal=yes
133 ac_cv_guix_syntax_object_equal=no
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.])
141 dnl GUIX_CHECK_GUILE_SSH
143 dnl Check whether a recent-enough Guile-SSH is available.
144 AC_DEFUN([GUIX_CHECK_GUILE_SSH], [
145 dnl Check whether 'userauth-gssapi!' (introduced in 0.12.0) 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 (@ (ssh auth) userauth-gssapi!))])
153 if test "$retval" = 0; then
154 guix_cv_have_recent_guile_ssh="yes"
156 guix_cv_have_recent_guile_ssh="no"
160 dnl GUIX_CHECK_GUILE_SQLITE3
162 dnl Check whether a recent-enough Guile-Sqlite3 is available.
163 AC_DEFUN([GUIX_CHECK_GUILE_SQLITE3], [
164 dnl Check whether 'sqlite-bind-arguments' is available. It was introduced
165 dnl in February 2018:
166 dnl <https://notabug.org/guile-sqlite3/guile-sqlite3/commit/1cd1dec96a9999db48c0ff45bab907efc637247f>.
167 AC_CACHE_CHECK([whether Guile-Sqlite3 is available and recent enough],
168 [guix_cv_have_recent_guile_sqlite3],
169 [GUILE_CHECK([retval],
170 [(@ (sqlite3) sqlite-bind-arguments)])
171 if test "$retval" = 0; then
172 guix_cv_have_recent_guile_sqlite3="yes"
174 guix_cv_have_recent_guile_sqlite3="no"
178 dnl GUIX_CHECK_GUILE_JSON
180 dnl Check whether a recent-enough Guile-JSON is available.
181 AC_DEFUN([GUIX_CHECK_GUILE_JSON], [
182 dnl Check whether we're using Guile-JSON 3.x, which uses a JSON-to-Scheme
183 dnl mapping different from that of earlier versions.
184 AC_CACHE_CHECK([whether Guile-JSON is available and recent enough],
185 [guix_cv_have_recent_guile_json],
186 [GUILE_CHECK([retval],
187 [(use-modules (json) (ice-9 match))
188 (match (json-string->scm \"[[ { \\\"a\\\": 42 } ]]\")
189 (#((("a" . 42))) #t))])
190 if test "$retval" = 0; then
191 guix_cv_have_recent_guile_json="yes"
193 guix_cv_have_recent_guile_json="no"
197 dnl GUIX_CHECK_GUILE_GCRYPT
199 dnl Check whether a recent-enough Guile-Gcrypt is available.
200 AC_DEFUN([GUIX_CHECK_GUILE_GCRYPT], [
201 dnl Check whether we're using Guile-Gcrypt 0.2.x or later. 0.2.0
202 dnl introduced the 'hash-algorithm' macro and related code.
203 AC_CACHE_CHECK([whether Guile-Gcrypt is available and recent enough],
204 [guix_cv_have_recent_guile_gcrypt],
205 [GUILE_CHECK([retval],
206 [(use-modules (gcrypt hash))
207 (equal? (hash-algorithm sha256)
208 (lookup-hash-algorithm 'sha256))])
209 if test "$retval" = 0; then
210 guix_cv_have_recent_guile_gcrypt="yes"
212 guix_cv_have_recent_guile_gcrypt="no"
216 dnl GUIX_TEST_ROOT_DIRECTORY
217 AC_DEFUN([GUIX_TEST_ROOT_DIRECTORY], [
218 AC_CACHE_CHECK([for unit test root directory],
219 [ac_cv_guix_test_root],
220 [ac_cv_guix_test_root="`pwd`/test-tmp"])
223 dnl 'BINPRM_BUF_SIZE' constant in Linux (we leave room for the trailing zero.)
224 dnl The Hurd has a limit of about a page (see exec/hashexec.c.)
225 m4_define([LINUX_HASH_BANG_LIMIT], 127)
227 dnl Hardcoded 'sun_path' length in <sys/un.h>.
228 m4_define([SOCKET_FILE_NAME_LIMIT], 108)
230 dnl GUIX_SOCKET_FILE_NAME_LENGTH
231 AC_DEFUN([GUIX_SOCKET_FILE_NAME_LENGTH], [
232 AC_CACHE_CHECK([the length of the installed socket file name],
233 [ac_cv_guix_socket_file_name_length],
234 [ac_cv_guix_socket_file_name_length="`echo -n "$guix_localstatedir/guix/daemon-socket/socket" | wc -c`"])
237 dnl GUIX_TEST_SOCKET_FILE_NAME_LENGTH
238 AC_DEFUN([GUIX_TEST_SOCKET_FILE_NAME_LENGTH], [
239 AC_REQUIRE([GUIX_TEST_ROOT_DIRECTORY])
240 AC_CACHE_CHECK([the length of the socket file name used in tests],
241 [ac_cv_guix_test_socket_file_name_length],
242 [ac_cv_guix_test_socket_file_name_length="`echo -n "$ac_cv_guix_test_root/var/123456/daemon-socket/socket" | wc -c`"])
245 dnl GUIX_HASH_BANG_LENGTH
246 AC_DEFUN([GUIX_HASH_BANG_LENGTH], [
247 AC_CACHE_CHECK([the length of a typical hash bang line],
248 [ac_cv_guix_hash_bang_length],
249 [ac_cv_guix_hash_bang_length=`echo -n "$storedir/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-bootstrap-binaries-0/bin/bash" | wc -c`])
252 dnl GUIX_TEST_HASH_BANG_LENGTH
253 AC_DEFUN([GUIX_TEST_HASH_BANG_LENGTH], [
254 AC_REQUIRE([GUIX_TEST_ROOT_DIRECTORY])
255 AC_CACHE_CHECK([the length of a hash bang line used in tests],
256 [ac_cv_guix_test_hash_bang_length],
257 [ac_cv_guix_test_hash_bang_length=`echo -n "$ac_cv_guix_test_root/store/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-bootstrap-binaries-0/bin/bash" | wc -c`])
260 dnl GUIX_CHECK_FILE_NAME_LIMITS
262 dnl GNU/Linux has a couple of silly limits that we can easily run into.
263 dnl Make sure everything is fine with the current settings. Set $1 to
264 dnl 'yes' if tests can run, 'no' otherwise.
265 AC_DEFUN([GUIX_CHECK_FILE_NAME_LIMITS], [
266 AC_REQUIRE([GUIX_SOCKET_FILE_NAME_LENGTH])
267 AC_REQUIRE([GUIX_TEST_SOCKET_FILE_NAME_LENGTH])
268 AC_REQUIRE([GUIX_HASH_BANG_LENGTH])
269 AC_REQUIRE([GUIX_TEST_HASH_BANG_LENGTH])
271 if test "$ac_cv_guix_socket_file_name_length" -ge ]SOCKET_FILE_NAME_LIMIT[; then
272 AC_MSG_ERROR([socket file name would exceed the maxium allowed length])
274 if test "$ac_cv_guix_test_socket_file_name_length" -ge ]SOCKET_FILE_NAME_LIMIT[; then
275 AC_MSG_WARN([socket file name limit may be exceeded when running tests])
279 if test "$ac_cv_guix_hash_bang_length" -ge ]LINUX_HASH_BANG_LIMIT[; then
281 AC_MSG_ERROR([store directory '$storedir' would lead to overly long hash-bang lines])
283 if test "$ac_cv_guix_test_hash_bang_length" -ge ]LINUX_HASH_BANG_LIMIT[; then
285 AC_MSG_WARN([test directory '$ac_cv_guix_test_root' may lead to overly long hash-bang lines])
291 dnl Check whether the C++ compiler can compile a typical C++11 program.
292 AC_DEFUN([GUIX_CHECK_CXX11], [
293 AC_REQUIRE([AC_PROG_CXX])
294 AC_CACHE_CHECK([whether $CXX supports C++11],
295 [ac_cv_guix_cxx11_support],
296 [save_CXXFLAGS="$CXXFLAGS"
297 CXXFLAGS="-std=c++11 $CXXFLAGS"
300 #include <functional>
302 std::function<int(int)>
303 return_plus_lambda (int x)
305 auto result = [[&]](int y) {
312 [ac_cv_guix_cxx11_support=yes],
313 [ac_cv_guix_cxx11_support=no])
314 CXXFLAGS="$save_CXXFLAGS"
318 dnl GUIX_ASSERT_CXX11
320 dnl Error out if the C++ compiler cannot compile C++11 code.
321 AC_DEFUN([GUIX_ASSERT_CXX11], [
323 if test "x$ac_cv_guix_cxx11_support" != "xyes"; then
324 AC_MSG_ERROR([C++ compiler '$CXX' does not support the C++11 standard])
328 dnl GUIX_LIBGCRYPT_LIBDIR VAR
330 dnl Attempt to determine libgcrypt's LIBDIR; store the result in VAR.
331 AC_DEFUN([GUIX_LIBGCRYPT_LIBDIR], [
332 AC_PATH_PROG([LIBGCRYPT_CONFIG], [libgcrypt-config])
333 AC_CACHE_CHECK([libgcrypt's library directory],
334 [guix_cv_libgcrypt_libdir],
335 [if test "x$LIBGCRYPT_CONFIG" != "x"; then
336 guix_cv_libgcrypt_libdir=`$LIBGCRYPT_CONFIG --libs | grep -e -L | sed -e "s/.*-L\([[^ ]]\+\)[[[:blank:]]]\+-lgcrypt.*/\1/g"`
338 guix_cv_libgcrypt_libdir=""
340 $1="$guix_cv_libgcrypt_libdir"
343 dnl GUIX_LIBZ_LIBDIR VAR
345 dnl Attempt to determine libz's LIBDIR; store the result in VAR.
346 AC_DEFUN([GUIX_LIBZ_LIBDIR], [
347 AC_REQUIRE([PKG_PROG_PKG_CONFIG])
348 AC_CACHE_CHECK([zlib's library directory],
349 [guix_cv_libz_libdir],
350 [guix_cv_libz_libdir="`$PKG_CONFIG zlib --variable=libdir 2> /dev/null`"])
351 $1="$guix_cv_libz_libdir"
354 dnl GUIX_LIBLZ_FILE_NAME VAR
356 dnl Attempt to determine liblz's absolute file name; store the result in VAR.
357 AC_DEFUN([GUIX_LIBLZ_FILE_NAME], [
358 AC_REQUIRE([PKG_PROG_PKG_CONFIG])
359 AC_CACHE_CHECK([lzlib's file name],
360 [guix_cv_liblz_libdir],
363 AC_LINK_IFELSE([AC_LANG_SOURCE([int main () { return LZ_decompress_open(); }])],
364 [guix_cv_liblz_libdir="`ldd conftest$EXEEXT | grep liblz | sed '-es/.*=> \(.*\) .*$/\1/g'`"])
366 $1="$guix_cv_liblz_libdir"
369 dnl GUIX_CURRENT_LOCALSTATEDIR
371 dnl Determine the localstatedir of an existing Guix installation and set
372 dnl 'guix_cv_current_localstatedir' accordingly. Set it to "none" if no
373 dnl existing installation was found.
374 AC_DEFUN([GUIX_CURRENT_LOCALSTATEDIR], [
375 AC_PATH_PROG([GUILE], [guile])
376 AC_CACHE_CHECK([the current installation's localstatedir],
377 [guix_cv_current_localstatedir],
378 [dnl Call 'dirname' because (guix config) appends "/guix" to LOCALSTATEDIR.
379 guix_cv_current_localstatedir="`"$GUILE" \
380 -c '(use-modules (guix config))
381 (when (string=? %store-directory "'$storedir'")
382 (display (dirname %state-directory)))' \
384 if test "x$guix_cv_current_localstatedir" = "x"; then
385 guix_cv_current_localstatedir=none
388 dnl GUIX_CHECK_LOCALSTATEDIR
390 dnl Check that the LOCALSTATEDIR value is consistent with that of the existing
391 dnl Guix installation, if any. Error out or warn if they do not match.
392 AC_DEFUN([GUIX_CHECK_LOCALSTATEDIR], [
393 AC_REQUIRE([GUIX_CURRENT_LOCALSTATEDIR])
394 if test "x$guix_cv_current_localstatedir" != "xnone"; then
395 if test "$guix_cv_current_localstatedir" != "$guix_localstatedir"; then
396 case "$localstatedir" in
398 # User kept the default value---i.e., did not pass '--localstatedir'.
399 AC_MSG_ERROR([chosen localstatedir '$guix_localstatedir' does not match \
400 that of the existing installation '$guix_cv_current_localstatedir'
401 Installing may corrupt $storedir!
402 Use './configure --localstatedir=$guix_cv_current_localstatedir'.])
405 # User passed an explicit '--localstatedir'. Assume they know what
407 AC_MSG_WARN([chosen localstatedir '$guix_localstatedir' does not match \
408 that of the existing installation '$guix_cv_current_localstatedir'])
409 AC_MSG_WARN([installing may corrupt $storedir!])