installer: Mount ESP once only.
[guix.git] / m4 / guix.m4
blobd0c5ec0f083ade56b614cef550ae87c6d3b93fb3
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/>.
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])
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
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])
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
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])
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
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
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
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
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.
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
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 '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])
159 dnl GUIX_CHECK_GUILE_SQLITE3
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])
177 dnl GUIX_TEST_ROOT_DIRECTORY
178 AC_DEFUN([GUIX_TEST_ROOT_DIRECTORY], [
179   AC_CACHE_CHECK([for unit test root directory],
180     [ac_cv_guix_test_root],
181     [ac_cv_guix_test_root="`pwd`/test-tmp"])
184 dnl 'BINPRM_BUF_SIZE' constant in Linux (we leave room for the trailing zero.)
185 dnl The Hurd has a limit of about a page (see exec/hashexec.c.)
186 m4_define([LINUX_HASH_BANG_LIMIT], 127)
188 dnl Hardcoded 'sun_path' length in <sys/un.h>.
189 m4_define([SOCKET_FILE_NAME_LIMIT], 108)
191 dnl GUIX_SOCKET_FILE_NAME_LENGTH
192 AC_DEFUN([GUIX_SOCKET_FILE_NAME_LENGTH], [
193   AC_CACHE_CHECK([the length of the installed socket file name],
194     [ac_cv_guix_socket_file_name_length],
195     [ac_cv_guix_socket_file_name_length="`echo -n "$guix_localstatedir/guix/daemon-socket/socket" | wc -c`"])
198 dnl GUIX_TEST_SOCKET_FILE_NAME_LENGTH
199 AC_DEFUN([GUIX_TEST_SOCKET_FILE_NAME_LENGTH], [
200   AC_REQUIRE([GUIX_TEST_ROOT_DIRECTORY])
201   AC_CACHE_CHECK([the length of the socket file name used in tests],
202     [ac_cv_guix_test_socket_file_name_length],
203     [ac_cv_guix_test_socket_file_name_length="`echo -n "$ac_cv_guix_test_root/var/123456/daemon-socket/socket" | wc -c`"])
206 dnl GUIX_HASH_BANG_LENGTH
207 AC_DEFUN([GUIX_HASH_BANG_LENGTH], [
208   AC_CACHE_CHECK([the length of a typical hash bang line],
209     [ac_cv_guix_hash_bang_length],
210     [ac_cv_guix_hash_bang_length=`echo -n "$storedir/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-bootstrap-binaries-0/bin/bash" | wc -c`])
213 dnl GUIX_TEST_HASH_BANG_LENGTH
214 AC_DEFUN([GUIX_TEST_HASH_BANG_LENGTH], [
215   AC_REQUIRE([GUIX_TEST_ROOT_DIRECTORY])
216   AC_CACHE_CHECK([the length of a hash bang line used in tests],
217     [ac_cv_guix_test_hash_bang_length],
218     [ac_cv_guix_test_hash_bang_length=`echo -n "$ac_cv_guix_test_root/store/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-bootstrap-binaries-0/bin/bash" | wc -c`])
221 dnl GUIX_CHECK_FILE_NAME_LIMITS
223 dnl GNU/Linux has a couple of silly limits that we can easily run into.
224 dnl Make sure everything is fine with the current settings.  Set $1 to
225 dnl 'yes' if tests can run, 'no' otherwise.
226 AC_DEFUN([GUIX_CHECK_FILE_NAME_LIMITS], [
227   AC_REQUIRE([GUIX_SOCKET_FILE_NAME_LENGTH])
228   AC_REQUIRE([GUIX_TEST_SOCKET_FILE_NAME_LENGTH])
229   AC_REQUIRE([GUIX_HASH_BANG_LENGTH])
230   AC_REQUIRE([GUIX_TEST_HASH_BANG_LENGTH])
232   if test "$ac_cv_guix_socket_file_name_length" -ge ]SOCKET_FILE_NAME_LIMIT[; then
233     AC_MSG_ERROR([socket file name would exceed the maxium allowed length])
234   fi
235   if test "$ac_cv_guix_test_socket_file_name_length" -ge ]SOCKET_FILE_NAME_LIMIT[; then
236     AC_MSG_WARN([socket file name limit may be exceeded when running tests])
237   fi
239   $1=yes
240   if test "$ac_cv_guix_hash_bang_length" -ge ]LINUX_HASH_BANG_LIMIT[; then
241     $1=no
242     AC_MSG_ERROR([store directory '$storedir' would lead to overly long hash-bang lines])
243   fi
244   if test "$ac_cv_guix_test_hash_bang_length" -ge ]LINUX_HASH_BANG_LIMIT[; then
245     $1=no
246     AC_MSG_WARN([test directory '$ac_cv_guix_test_root' may lead to overly long hash-bang lines])
247   fi
250 dnl GUIX_CHECK_CXX11
252 dnl Check whether the C++ compiler can compile a typical C++11 program.
253 AC_DEFUN([GUIX_CHECK_CXX11], [
254   AC_REQUIRE([AC_PROG_CXX])
255   AC_CACHE_CHECK([whether $CXX supports C++11],
256     [ac_cv_guix_cxx11_support],
257     [save_CXXFLAGS="$CXXFLAGS"
258      CXXFLAGS="-std=c++11 $CXXFLAGS"
259      AC_COMPILE_IFELSE([
260       AC_LANG_SOURCE([
261         #include <functional>
263         std::function<int(int)>
264         return_plus_lambda (int x)
265         {
266           auto result = [[&]](int y) {
267             return x + y;
268           };
270           return result;
271         }
272       ])],
273       [ac_cv_guix_cxx11_support=yes],
274       [ac_cv_guix_cxx11_support=no])
275     CXXFLAGS="$save_CXXFLAGS"
276   ])
279 dnl GUIX_ASSERT_CXX11
281 dnl Error out if the C++ compiler cannot compile C++11 code.
282 AC_DEFUN([GUIX_ASSERT_CXX11], [
283   GUIX_CHECK_CXX11
284   if test "x$ac_cv_guix_cxx11_support" != "xyes"; then
285     AC_MSG_ERROR([C++ compiler '$CXX' does not support the C++11 standard])
286   fi
289 dnl GUIX_LIBGCRYPT_LIBDIR VAR
291 dnl Attempt to determine libgcrypt's LIBDIR; store the result in VAR.
292 AC_DEFUN([GUIX_LIBGCRYPT_LIBDIR], [
293   AC_PATH_PROG([LIBGCRYPT_CONFIG], [libgcrypt-config])
294   AC_CACHE_CHECK([libgcrypt's library directory],
295     [guix_cv_libgcrypt_libdir],
296     [if test "x$LIBGCRYPT_CONFIG" != "x"; then
297        guix_cv_libgcrypt_libdir=`$LIBGCRYPT_CONFIG --libs | grep -e -L | sed -e "s/.*-L\([[^ ]]\+\)[[[:blank:]]]\+-lgcrypt.*/\1/g"`
298      else
299        guix_cv_libgcrypt_libdir=""
300      fi])
301   $1="$guix_cv_libgcrypt_libdir"
304 dnl GUIX_LIBZ_LIBDIR VAR
306 dnl Attempt to determine libz's LIBDIR; store the result in VAR.
307 AC_DEFUN([GUIX_LIBZ_LIBDIR], [
308   AC_REQUIRE([PKG_PROG_PKG_CONFIG])
309   AC_CACHE_CHECK([zlib's library directory],
310     [guix_cv_libz_libdir],
311     [guix_cv_libz_libdir="`$PKG_CONFIG zlib --variable=libdir 2> /dev/null`"])
312   $1="$guix_cv_libz_libdir"
315 dnl GUIX_LIBLZ_FILE_NAME VAR
317 dnl Attempt to determine liblz's absolute file name; store the result in VAR.
318 AC_DEFUN([GUIX_LIBLZ_FILE_NAME], [
319   AC_REQUIRE([PKG_PROG_PKG_CONFIG])
320   AC_CACHE_CHECK([lzlib's file name],
321     [guix_cv_liblz_libdir],
322     [old_LIBS="$LIBS"
323      LIBS="-llz"
324      AC_LINK_IFELSE([AC_LANG_SOURCE([int main () { return LZ_decompress_open(); }])],
325        [guix_cv_liblz_libdir="`ldd conftest$EXEEXT | grep liblz | sed '-es/.*=> \(.*\) .*$/\1/g'`"])
326      LIBS="$old_LIBS"])
327   $1="$guix_cv_liblz_libdir"
330 dnl GUIX_CURRENT_LOCALSTATEDIR
332 dnl Determine the localstatedir of an existing Guix installation and set
333 dnl 'guix_cv_current_localstatedir' accordingly.  Set it to "none" if no
334 dnl existing installation was found.
335 AC_DEFUN([GUIX_CURRENT_LOCALSTATEDIR], [
336   AC_PATH_PROG([GUILE], [guile])
337   AC_CACHE_CHECK([the current installation's localstatedir],
338     [guix_cv_current_localstatedir],
339     [dnl Call 'dirname' because (guix config) appends "/guix" to LOCALSTATEDIR.
340      guix_cv_current_localstatedir="`"$GUILE" \
341        -c '(use-modules (guix config))
342            (when (string=? %store-directory "'$storedir'")
343              (display (dirname %state-directory)))' \
344        2>/dev/null`"
345      if test "x$guix_cv_current_localstatedir" = "x"; then
346        guix_cv_current_localstatedir=none
347      fi])])
349 dnl GUIX_CHECK_LOCALSTATEDIR
351 dnl Check that the LOCALSTATEDIR value is consistent with that of the existing
352 dnl Guix installation, if any.  Error out or warn if they do not match.
353 AC_DEFUN([GUIX_CHECK_LOCALSTATEDIR], [
354   AC_REQUIRE([GUIX_CURRENT_LOCALSTATEDIR])
355   if test "x$guix_cv_current_localstatedir" != "xnone"; then
356     if test "$guix_cv_current_localstatedir" != "$guix_localstatedir"; then
357       case "$localstatedir" in
358         NONE|\${prefix}*)
359           # User kept the default value---i.e., did not pass '--localstatedir'.
360           AC_MSG_ERROR([chosen localstatedir '$guix_localstatedir' does not match \
361 that of the existing installation '$guix_cv_current_localstatedir'
362 Installing may corrupt $storedir!
363 Use './configure --localstatedir=$guix_cv_current_localstatedir'.])
364           ;;
365         *)
366           # User passed an explicit '--localstatedir'.  Assume they know what
367           # they're doing.
368           AC_MSG_WARN([chosen localstatedir '$guix_localstatedir' does not match \
369 that of the existing installation '$guix_cv_current_localstatedir'])
370           AC_MSG_WARN([installing may corrupt $storedir!])
371          ;;
372       esac
373     fi
374   fi])