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>
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|mips64el-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"
198 dnl GUIX_TEST_ROOT_DIRECTORY
199 AC_DEFUN([GUIX_TEST_ROOT_DIRECTORY], [
200 AC_CACHE_CHECK([for unit test root directory],
201 [ac_cv_guix_test_root],
202 [ac_cv_guix_test_root="`pwd`/test-tmp"])
205 dnl 'BINPRM_BUF_SIZE' constant in Linux (we leave room for the trailing zero.)
206 dnl The Hurd has a limit of about a page (see exec/hashexec.c.)
207 m4_define([LINUX_HASH_BANG_LIMIT], 127)
209 dnl Hardcoded 'sun_path' length in <sys/un.h>.
210 m4_define([SOCKET_FILE_NAME_LIMIT], 108)
212 dnl GUIX_SOCKET_FILE_NAME_LENGTH
213 AC_DEFUN([GUIX_SOCKET_FILE_NAME_LENGTH], [
214 AC_CACHE_CHECK([the length of the installed socket file name],
215 [ac_cv_guix_socket_file_name_length],
216 [ac_cv_guix_socket_file_name_length="`echo -n "$guix_localstatedir/guix/daemon-socket/socket" | wc -c`"])
219 dnl GUIX_TEST_SOCKET_FILE_NAME_LENGTH
220 AC_DEFUN([GUIX_TEST_SOCKET_FILE_NAME_LENGTH], [
221 AC_REQUIRE([GUIX_TEST_ROOT_DIRECTORY])
222 AC_CACHE_CHECK([the length of the socket file name used in tests],
223 [ac_cv_guix_test_socket_file_name_length],
224 [ac_cv_guix_test_socket_file_name_length="`echo -n "$ac_cv_guix_test_root/var/123456/daemon-socket/socket" | wc -c`"])
227 dnl GUIX_HASH_BANG_LENGTH
228 AC_DEFUN([GUIX_HASH_BANG_LENGTH], [
229 AC_CACHE_CHECK([the length of a typical hash bang line],
230 [ac_cv_guix_hash_bang_length],
231 [ac_cv_guix_hash_bang_length=`echo -n "$storedir/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-bootstrap-binaries-0/bin/bash" | wc -c`])
234 dnl GUIX_TEST_HASH_BANG_LENGTH
235 AC_DEFUN([GUIX_TEST_HASH_BANG_LENGTH], [
236 AC_REQUIRE([GUIX_TEST_ROOT_DIRECTORY])
237 AC_CACHE_CHECK([the length of a hash bang line used in tests],
238 [ac_cv_guix_test_hash_bang_length],
239 [ac_cv_guix_test_hash_bang_length=`echo -n "$ac_cv_guix_test_root/store/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-bootstrap-binaries-0/bin/bash" | wc -c`])
242 dnl GUIX_CHECK_FILE_NAME_LIMITS
244 dnl GNU/Linux has a couple of silly limits that we can easily run into.
245 dnl Make sure everything is fine with the current settings. Set $1 to
246 dnl 'yes' if tests can run, 'no' otherwise.
247 AC_DEFUN([GUIX_CHECK_FILE_NAME_LIMITS], [
248 AC_REQUIRE([GUIX_SOCKET_FILE_NAME_LENGTH])
249 AC_REQUIRE([GUIX_TEST_SOCKET_FILE_NAME_LENGTH])
250 AC_REQUIRE([GUIX_HASH_BANG_LENGTH])
251 AC_REQUIRE([GUIX_TEST_HASH_BANG_LENGTH])
253 if test "$ac_cv_guix_socket_file_name_length" -ge ]SOCKET_FILE_NAME_LIMIT[; then
254 AC_MSG_ERROR([socket file name would exceed the maxium allowed length])
256 if test "$ac_cv_guix_test_socket_file_name_length" -ge ]SOCKET_FILE_NAME_LIMIT[; then
257 AC_MSG_WARN([socket file name limit may be exceeded when running tests])
261 if test "$ac_cv_guix_hash_bang_length" -ge ]LINUX_HASH_BANG_LIMIT[; then
263 AC_MSG_ERROR([store directory '$storedir' would lead to overly long hash-bang lines])
265 if test "$ac_cv_guix_test_hash_bang_length" -ge ]LINUX_HASH_BANG_LIMIT[; then
267 AC_MSG_WARN([test directory '$ac_cv_guix_test_root' may lead to overly long hash-bang lines])
273 dnl Check whether the C++ compiler can compile a typical C++11 program.
274 AC_DEFUN([GUIX_CHECK_CXX11], [
275 AC_REQUIRE([AC_PROG_CXX])
276 AC_CACHE_CHECK([whether $CXX supports C++11],
277 [ac_cv_guix_cxx11_support],
278 [save_CXXFLAGS="$CXXFLAGS"
279 CXXFLAGS="-std=c++11 $CXXFLAGS"
282 #include <functional>
284 std::function<int(int)>
285 return_plus_lambda (int x)
287 auto result = [[&]](int y) {
294 [ac_cv_guix_cxx11_support=yes],
295 [ac_cv_guix_cxx11_support=no])
296 CXXFLAGS="$save_CXXFLAGS"
300 dnl GUIX_ASSERT_CXX11
302 dnl Error out if the C++ compiler cannot compile C++11 code.
303 AC_DEFUN([GUIX_ASSERT_CXX11], [
305 if test "x$ac_cv_guix_cxx11_support" != "xyes"; then
306 AC_MSG_ERROR([C++ compiler '$CXX' does not support the C++11 standard])
310 dnl GUIX_LIBGCRYPT_LIBDIR VAR
312 dnl Attempt to determine libgcrypt's LIBDIR; store the result in VAR.
313 AC_DEFUN([GUIX_LIBGCRYPT_LIBDIR], [
314 AC_PATH_PROG([LIBGCRYPT_CONFIG], [libgcrypt-config])
315 AC_CACHE_CHECK([libgcrypt's library directory],
316 [guix_cv_libgcrypt_libdir],
317 [if test "x$LIBGCRYPT_CONFIG" != "x"; then
318 guix_cv_libgcrypt_libdir=`$LIBGCRYPT_CONFIG --libs | grep -e -L | sed -e "s/.*-L\([[^ ]]\+\)[[[:blank:]]]\+-lgcrypt.*/\1/g"`
320 guix_cv_libgcrypt_libdir=""
322 $1="$guix_cv_libgcrypt_libdir"
325 dnl GUIX_LIBZ_LIBDIR VAR
327 dnl Attempt to determine libz's LIBDIR; store the result in VAR.
328 AC_DEFUN([GUIX_LIBZ_LIBDIR], [
329 AC_REQUIRE([PKG_PROG_PKG_CONFIG])
330 AC_CACHE_CHECK([zlib's library directory],
331 [guix_cv_libz_libdir],
332 [guix_cv_libz_libdir="`$PKG_CONFIG zlib --variable=libdir 2> /dev/null`"])
333 $1="$guix_cv_libz_libdir"
336 dnl GUIX_LIBLZ_FILE_NAME VAR
338 dnl Attempt to determine liblz's absolute file name; store the result in VAR.
339 AC_DEFUN([GUIX_LIBLZ_FILE_NAME], [
340 AC_REQUIRE([PKG_PROG_PKG_CONFIG])
341 AC_CACHE_CHECK([lzlib's file name],
342 [guix_cv_liblz_libdir],
345 AC_LINK_IFELSE([AC_LANG_SOURCE([int main () { return LZ_decompress_open(); }])],
346 [guix_cv_liblz_libdir="`ldd conftest$EXEEXT | grep liblz | sed '-es/.*=> \(.*\) .*$/\1/g'`"])
348 $1="$guix_cv_liblz_libdir"
351 dnl GUIX_CURRENT_LOCALSTATEDIR
353 dnl Determine the localstatedir of an existing Guix installation and set
354 dnl 'guix_cv_current_localstatedir' accordingly. Set it to "none" if no
355 dnl existing installation was found.
356 AC_DEFUN([GUIX_CURRENT_LOCALSTATEDIR], [
357 AC_PATH_PROG([GUILE], [guile])
358 AC_CACHE_CHECK([the current installation's localstatedir],
359 [guix_cv_current_localstatedir],
360 [dnl Call 'dirname' because (guix config) appends "/guix" to LOCALSTATEDIR.
361 guix_cv_current_localstatedir="`"$GUILE" \
362 -c '(use-modules (guix config))
363 (when (string=? %store-directory "'$storedir'")
364 (display (dirname %state-directory)))' \
366 if test "x$guix_cv_current_localstatedir" = "x"; then
367 guix_cv_current_localstatedir=none
370 dnl GUIX_CHECK_LOCALSTATEDIR
372 dnl Check that the LOCALSTATEDIR value is consistent with that of the existing
373 dnl Guix installation, if any. Error out or warn if they do not match.
374 AC_DEFUN([GUIX_CHECK_LOCALSTATEDIR], [
375 AC_REQUIRE([GUIX_CURRENT_LOCALSTATEDIR])
376 if test "x$guix_cv_current_localstatedir" != "xnone"; then
377 if test "$guix_cv_current_localstatedir" != "$guix_localstatedir"; then
378 case "$localstatedir" in
380 # User kept the default value---i.e., did not pass '--localstatedir'.
381 AC_MSG_ERROR([chosen localstatedir '$guix_localstatedir' does not match \
382 that of the existing installation '$guix_cv_current_localstatedir'
383 Installing may corrupt $storedir!
384 Use './configure --localstatedir=$guix_cv_current_localstatedir'.])
387 # User passed an explicit '--localstatedir'. Assume they know what
389 AC_MSG_WARN([chosen localstatedir '$guix_localstatedir' does not match \
390 that of the existing installation '$guix_cv_current_localstatedir'])
391 AC_MSG_WARN([installing may corrupt $storedir!])