projects/guix·blob master · refs

458 lines · 16.3 KiB

1dnl GNU Guix --- Functional package management for GNU
2dnl Copyright © 2012, 2013, 2014, 2015, 2016, 2018, 2019, 2020, 2021 Ludovic Courtès <[email protected]>
3dnl Copyright © 2014 Mark H Weaver <[email protected]>
4dnl Copyright © 2017, 2020, 2021, 2023 Efraim Flashner <[email protected]>
5dnl Copyright © 2021 Chris Marusich <[email protected]>
6dnl Copyright © 2024 Janneke Nieuwenhuizen <[email protected]>
7dnl
8dnl This file is part of GNU Guix.
9dnl
10dnl GNU Guix is free software; you can redistribute it and/or modify it
11dnl under the terms of the GNU General Public License as published by
12dnl the Free Software Foundation; either version 3 of the License, or (at
13dnl your option) any later version.
14dnl
15dnl GNU Guix is distributed in the hope that it will be useful, but
16dnl WITHOUT ANY WARRANTY; without even the implied warranty of
17dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18dnl GNU General Public License for more details.
19dnl
20dnl You should have received a copy of the GNU General Public License
21dnl along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
22
23dnl GUIX_SYSTEM_TYPE
24dnl
25dnl Determine the Guix host system type, and store it in the
26dnl `guix_system' variable.
27AC_DEFUN([GUIX_SYSTEM_TYPE], [
28 AC_REQUIRE([AC_CANONICAL_HOST])
29 AC_PATH_PROG([SED], [sed])
30
31 AC_ARG_WITH(system, AS_HELP_STRING([--with-system=SYSTEM],
32 [Platform identifier (e.g., `i686-linux').]),
33 [guix_system="$withval"],
34 [case "$host_cpu" in
35 i*86)
36 machine_name="i686";;
37 amd64)
38 machine_name="x86_64";;
39 arm|armv[[7-9]]*)
40 # Here we want to exclude CPUs such as "armv6l". On ARMv7
41 # machines, we normally get "armv7l". However, in Guix, we
42 # configure with --build=arm-unknown-linux-gnueabihf, leading
43 # to just "arm", so we also have to allow it.
44 #
45 # TODO: If not cross-compiling, add a sanity check to make
46 # sure this build machine has the needed features to
47 # support executables compiled using our armhf gcc,
48 # configured with:
49 # --with-arch=armv7-a
50 # --with-float=hard
51 # --with-mode=thumb
52 # --with-fpu=vfpv3-d16
53 machine_name="armhf";;
54 *)
55 machine_name="$host_cpu";;
56 esac
57
58 case "$host_os" in
59 linux-gnu*)
60 # For backward compatibility, strip the `-gnu' part.
61 guix_system="$machine_name-linux";;
62 linux-musl*)
63 guix_system="$machine_name-linux";;
64 gnu*)
65 case "$machine_name" in
66 i386|i486|i586|i686)
67 # Always use i586 for 32bit GNU/Hurd.
68 guix_system="i586-gnu";;
69 *)
70 guix_system="$machine_name-gnu";;
71 esac;;
72 *)
73 # Strip the version number from names such as `gnu0.3',
74 # `darwin10.2.0', etc.
75 guix_system="$machine_name-`echo $host_os | "$SED" -e's/[0-9.]*$//g'`";;
76 esac])
77
78 AC_MSG_CHECKING([for the Guix system type])
79 AC_MSG_RESULT([$guix_system])
80
81 AC_SUBST([guix_system])
82])
83
84dnl GUIX_ASSERT_SUPPORTED_SYSTEM
85dnl
86dnl Assert that this is a system to which the distro is ported.
87AC_DEFUN([GUIX_ASSERT_SUPPORTED_SYSTEM], [
88 AC_REQUIRE([GUIX_SYSTEM_TYPE])
89
90 AC_ARG_WITH([courage], [AS_HELP_STRING([--with-courage],
91 [Assert that even if this platform is unsupported, you will be
92courageous and port the GNU System distribution to it (see
93"GNU Distribution" in the manual.)])],
94 [guix_courageous="$withval"],
95 [guix_courageous="no"])
96
97 # Currently only Linux-based systems are supported, and only on some
98 # platforms.
99 case "$guix_system" in
100 x86_64-linux|i686-linux|armhf-linux|aarch64-linux|powerpc64le-linux|riscv64-linux|i586-gnu|x86_64-gnu)
101 ;;
102 mips64el-linux|powerpc-linux)
103 AC_MSG_WARN([building Guix on `$guix_system', which is not supported])
104 ;;
105 *)
106 if test "x$guix_courageous" = "xyes"; then
107 AC_MSG_WARN([building Guix on `$guix_system', which is not supported])
108 else
109 AC_MSG_ERROR([`$guix_system' is not a supported platform.
110See "GNU Distribution" in the manual, or try `--with-courage'.])
111 fi
112 ;;
113 esac
114])
115
116dnl GUIX_ASSERT_GUILE_FEATURES FEATURES
117dnl
118dnl Assert that FEATURES are provided by $GUILE.
119AC_DEFUN([GUIX_ASSERT_GUILE_FEATURES], [
120 for guix_guile_feature in $1
121 do
122 AC_MSG_CHECKING([whether $GUILE provides feature '$guix_guile_feature'])
123 if "$GUILE" -c "(exit (provided? '$guix_guile_feature))"
124 then
125 AC_MSG_RESULT([yes])
126 else
127 AC_MSG_RESULT([no])
128 AC_MSG_ERROR([$GUILE does not support feature '$guix_guile_feature', which is required.])
129 fi
130 done
131])
132
133dnl GUIX_CHECK_GUILE_SSH
134dnl
135dnl Check whether a recent-enough Guile-SSH is available.
136AC_DEFUN([GUIX_CHECK_GUILE_SSH], [
137 dnl Check whether '#:nodelay' parameter to 'make-session' (introduced in
138 dnl 0.13.0) is present.
139 AC_CACHE_CHECK([whether Guile-SSH is available and recent enough],
140 [guix_cv_have_recent_guile_ssh],
141 [GUILE_CHECK([retval],
142 [(and (@ (ssh channel) channel-send-eof)
143 (@ (ssh popen) open-remote-pipe)
144 (@ (ssh dist node) node-eval)
145 (@ (ssh auth) userauth-gssapi!)
146 ((@ (ssh session) make-session) #:nodelay #t #:config #f))])
147 if test "$retval" = 0; then
148 guix_cv_have_recent_guile_ssh="yes"
149 else
150 guix_cv_have_recent_guile_ssh="no"
151 fi])
152])
153
154dnl GUIX_CHECK_GUILE_SQLITE3
155dnl
156dnl Check whether a recent-enough Guile-Sqlite3 is available.
157AC_DEFUN([GUIX_CHECK_GUILE_SQLITE3], [
158 dnl Check whether 'sqlite-bind-arguments' is available. It was introduced
159 dnl in February 2018:
160 dnl <https://codeberg.org/guile-sqlite3/guile-sqlite3/commit/1cd1dec96a9999db48c0ff45bab907efc637247f>.
161 AC_CACHE_CHECK([whether Guile-Sqlite3 is available and recent enough],
162 [guix_cv_have_recent_guile_sqlite3],
163 [GUILE_CHECK([retval],
164 [(@ (sqlite3) sqlite-bind-arguments)])
165 if test "$retval" = 0; then
166 guix_cv_have_recent_guile_sqlite3="yes"
167 else
168 guix_cv_have_recent_guile_sqlite3="no"
169 fi])
170])
171
172dnl GUIX_CHECK_GUILE_JSON
173dnl
174dnl Check whether a recent-enough Guile-JSON is available.
175AC_DEFUN([GUIX_CHECK_GUILE_JSON], [
176 dnl Check whether we're using Guile-JSON 4.3+, which provides
177 dnl 'define-json-mapping'.
178 AC_CACHE_CHECK([whether Guile-JSON is available and recent enough],
179 [guix_cv_have_recent_guile_json],
180 [GUILE_CHECK([retval],
181 [(use-modules (json))
182
183 (define-json-mapping <frob> make-frob
184 frob?
185 json->frob
186 (a frob-a)
187 (b frob-b \"bee\"))
188
189 (exit
190 (equal? (json->frob
191 (open-input-string \"{ \\\"a\\\": 1, \\\"bee\\\": 2 }\"))
192 (make-frob 1 2)))])
193 if test "$retval" = 0; then
194 guix_cv_have_recent_guile_json="yes"
195 else
196 guix_cv_have_recent_guile_json="no"
197 fi])
198])
199
200dnl GUIX_CHECK_GUILE_GCRYPT
201dnl
202dnl Check whether a recent-enough Guile-Gcrypt is available.
203AC_DEFUN([GUIX_CHECK_GUILE_GCRYPT], [
204 dnl Check whether we're using Guile-Gcrypt 0.2.x or later. 0.2.0
205 dnl introduced the 'hash-algorithm' macro and related code.
206 AC_CACHE_CHECK([whether Guile-Gcrypt is available and recent enough],
207 [guix_cv_have_recent_guile_gcrypt],
208 [GUILE_CHECK([retval],
209 [(use-modules (gcrypt hash))
210 (equal? (hash-algorithm sha256)
211 (lookup-hash-algorithm 'sha256))])
212 if test "$retval" = 0; then
213 guix_cv_have_recent_guile_gcrypt="yes"
214 else
215 guix_cv_have_recent_guile_gcrypt="no"
216 fi])
217])
218
219dnl GUIX_CHECK_GUILE_GIT
220dnl
221dnl Check whether a recent-enough Guile-Git is available.
222AC_DEFUN([GUIX_CHECK_GUILE_GIT], [
223 dnl Check whether we're using Guile-Git 0.3.0 or later. 0.3.0
224 dnl introduced SSH authentication support and more.
225 AC_CACHE_CHECK([whether Guile-Git is available and recent enough],
226 [guix_cv_have_recent_guile_git],
227 [GUILE_CHECK([retval],
228 [(use-modules (git) (git auth) (git submodule))
229 (let ((auth (%make-auth-ssh-agent)))
230 repository-close!
231 object-lookup-prefix
232 (make-clone-options
233 #:fetch-options (make-fetch-options auth)))])
234 if test "$retval" = 0; then
235 guix_cv_have_recent_guile_git="yes"
236 else
237 guix_cv_have_recent_guile_git="no"
238 fi])
239])
240
241dnl GUIX_CHECK_GUILE_ZLIB
242dnl
243dnl Check whether a recent-enough Guile-zlib is available.
244AC_DEFUN([GUIX_CHECK_GUILE_ZLIB], [
245 dnl Check whether we're using Guile-zlib 0.1.0 or later.
246 dnl 0.1.0 introduced the 'make-zlib-input-port' and related code.
247 AC_CACHE_CHECK([whether Guile-zlib is available and recent enough],
248 [guix_cv_have_recent_guile_zlib],
249 [GUILE_CHECK([retval],
250 [(use-modules (zlib))
251 make-zlib-input-port])
252 if test "$retval" = 0; then
253 guix_cv_have_recent_guile_zlib="yes"
254 else
255 guix_cv_have_recent_guile_zlib="no"
256 fi])
257])
258
259dnl GUIX_TEST_ROOT_DIRECTORY
260AC_DEFUN([GUIX_TEST_ROOT_DIRECTORY], [
261 AC_CACHE_CHECK([for unit test root directory],
262 [ac_cv_guix_test_root],
263 [ac_cv_guix_test_root="`pwd`/test-tmp"])
264])
265
266dnl 'BINPRM_BUF_SIZE' constant in Linux (we leave room for the trailing zero.)
267dnl The Hurd has a limit of about a page (see exec/hashexec.c.)
268m4_define([LINUX_HASH_BANG_LIMIT], 127)
269
270dnl Hardcoded 'sun_path' length in <sys/un.h>.
271m4_define([SOCKET_FILE_NAME_LIMIT], 108)
272
273dnl GUIX_SOCKET_FILE_NAME_LENGTH
274AC_DEFUN([GUIX_SOCKET_FILE_NAME_LENGTH], [
275 AC_CACHE_CHECK([the length of the installed socket file name],
276 [ac_cv_guix_socket_file_name_length],
277 [ac_cv_guix_socket_file_name_length="`echo -n "$guix_localstatedir/guix/daemon-socket/socket" | wc -c`"])
278])
279
280dnl GUIX_TEST_SOCKET_FILE_NAME_LENGTH
281AC_DEFUN([GUIX_TEST_SOCKET_FILE_NAME_LENGTH], [
282 AC_REQUIRE([GUIX_TEST_ROOT_DIRECTORY])
283 AC_CACHE_CHECK([the length of the socket file name used in tests],
284 [ac_cv_guix_test_socket_file_name_length],
285 [ac_cv_guix_test_socket_file_name_length="`echo -n "$ac_cv_guix_test_root/var/123456/daemon-socket/socket" | wc -c`"])
286])
287
288dnl GUIX_HASH_BANG_LENGTH
289AC_DEFUN([GUIX_HASH_BANG_LENGTH], [
290 AC_CACHE_CHECK([the length of a typical hash bang line],
291 [ac_cv_guix_hash_bang_length],
292 [ac_cv_guix_hash_bang_length=`echo -n "$storedir/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-bootstrap-binaries-0/bin/bash" | wc -c`])
293])
294
295dnl GUIX_TEST_HASH_BANG_LENGTH
296AC_DEFUN([GUIX_TEST_HASH_BANG_LENGTH], [
297 AC_REQUIRE([GUIX_TEST_ROOT_DIRECTORY])
298 AC_CACHE_CHECK([the length of a hash bang line used in tests],
299 [ac_cv_guix_test_hash_bang_length],
300 [ac_cv_guix_test_hash_bang_length=`echo -n "$ac_cv_guix_test_root/store/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-bootstrap-binaries-0/bin/bash" | wc -c`])
301])
302
303dnl GUIX_CHECK_FILE_NAME_LIMITS
304dnl
305dnl GNU/Linux has a couple of silly limits that we can easily run into.
306dnl Make sure everything is fine with the current settings. Set $1 to
307dnl 'yes' if tests can run, 'no' otherwise.
308AC_DEFUN([GUIX_CHECK_FILE_NAME_LIMITS], [
309 AC_REQUIRE([GUIX_SOCKET_FILE_NAME_LENGTH])
310 AC_REQUIRE([GUIX_TEST_SOCKET_FILE_NAME_LENGTH])
311 AC_REQUIRE([GUIX_HASH_BANG_LENGTH])
312 AC_REQUIRE([GUIX_TEST_HASH_BANG_LENGTH])
313
314 if test "$ac_cv_guix_socket_file_name_length" -ge ]SOCKET_FILE_NAME_LIMIT[; then
315 AC_MSG_ERROR([socket file name would exceed the maximum allowed length])
316 fi
317 if test "$ac_cv_guix_test_socket_file_name_length" -ge ]SOCKET_FILE_NAME_LIMIT[; then
318 AC_MSG_WARN([socket file name limit may be exceeded when running tests])
319 fi
320
321 $1=yes
322 if test "$ac_cv_guix_hash_bang_length" -ge ]LINUX_HASH_BANG_LIMIT[; then
323 $1=no
324 AC_MSG_ERROR([store directory '$storedir' would lead to overly long hash-bang lines])
325 fi
326 if test "$ac_cv_guix_test_hash_bang_length" -ge ]LINUX_HASH_BANG_LIMIT[; then
327 $1=no
328 AC_MSG_WARN([test directory '$ac_cv_guix_test_root' may lead to overly long hash-bang lines])
329 fi
330])
331
332dnl GUIX_CHECK_CXX11
333dnl
334dnl Check whether the C++ compiler can compile a typical C++11 program.
335AC_DEFUN([GUIX_CHECK_CXX11], [
336 AC_REQUIRE([AC_PROG_CXX])
337 AC_CACHE_CHECK([whether $CXX supports C++11],
338 [ac_cv_guix_cxx11_support],
339 [save_CXXFLAGS="$CXXFLAGS"
340 CXXFLAGS="-std=c++11 $CXXFLAGS"
341 AC_COMPILE_IFELSE([
342 AC_LANG_SOURCE([
343 #include <functional>
344
345 std::function<int(int)>
346 return_plus_lambda (int x)
347 {
348 auto result = [[&]](int y) {
349 return x + y;
350 };
351
352 return result;
353 }
354 ])],
355 [ac_cv_guix_cxx11_support=yes],
356 [ac_cv_guix_cxx11_support=no])
357 CXXFLAGS="$save_CXXFLAGS"
358 ])
359])
360
361dnl GUIX_ASSERT_CXX11
362dnl
363dnl Error out if the C++ compiler cannot compile C++11 code.
364AC_DEFUN([GUIX_ASSERT_CXX11], [
365 GUIX_CHECK_CXX11
366 if test "x$ac_cv_guix_cxx11_support" != "xyes"; then
367 AC_MSG_ERROR([C++ compiler '$CXX' does not support the C++11 standard])
368 fi
369])
370
371dnl GUIX_LIBGCRYPT_LIBDIR VAR
372dnl
373dnl Attempt to determine libgcrypt's LIBDIR; store the result in VAR.
374AC_DEFUN([GUIX_LIBGCRYPT_LIBDIR], [
375 AC_PATH_PROG([LIBGCRYPT_CONFIG], [libgcrypt-config])
376 AC_CACHE_CHECK([libgcrypt's library directory],
377 [guix_cv_libgcrypt_libdir],
378 [if test "x$LIBGCRYPT_CONFIG" != "x"; then
379 guix_cv_libgcrypt_libdir=`$LIBGCRYPT_CONFIG --libs | grep -e -L | sed -e "s/.*-L\([[^ ]]\+\)[[[:blank:]]]\+-lgcrypt.*/\1/g"`
380 else
381 guix_cv_libgcrypt_libdir=""
382 fi])
383 $1="$guix_cv_libgcrypt_libdir"
384])
385
386dnl GUIX_CURRENT_LOCALSTATEDIR
387dnl
388dnl Determine the localstatedir of an existing Guix installation and set
389dnl 'guix_cv_current_localstatedir' accordingly. Set it to "none" if no
390dnl existing installation was found.
391AC_DEFUN([GUIX_CURRENT_LOCALSTATEDIR], [
392 AC_PATH_PROG([GUILE], [guile])
393 AC_CACHE_CHECK([the current installation's localstatedir],
394 [guix_cv_current_localstatedir],
395 [dnl Call 'dirname' because (guix config) appends "/guix" to LOCALSTATEDIR.
396 guix_cv_current_localstatedir="`"$GUILE" \
397 -c '(use-modules (guix config))
398 (when (string=? %store-directory "'$storedir'")
399 (display (dirname %state-directory)))' \
400 2>/dev/null`"
401 if test "x$guix_cv_current_localstatedir" = "x"; then
402 guix_cv_current_localstatedir=none
403 fi])])
404
405dnl GUIX_CHECK_LOCALSTATEDIR
406dnl
407dnl Check that the LOCALSTATEDIR value is consistent with that of the existing
408dnl Guix installation, if any. Error out or warn if they do not match.
409AC_DEFUN([GUIX_CHECK_LOCALSTATEDIR], [
410 AC_REQUIRE([GUIX_CURRENT_LOCALSTATEDIR])
411 if test "x$guix_cv_current_localstatedir" != "xnone"; then
412 if test "$guix_cv_current_localstatedir" != "$guix_localstatedir"; then
413 case "$localstatedir" in
414 NONE|\${prefix}*)
415 # User kept the default value---i.e., did not pass '--localstatedir'.
416 AC_MSG_ERROR([chosen localstatedir '$guix_localstatedir' does not match \
417that of the existing installation '$guix_cv_current_localstatedir'
418Installing may corrupt $storedir!
419Use './configure --localstatedir=$guix_cv_current_localstatedir'.])
420 ;;
421 *)
422 # User passed an explicit '--localstatedir'. Assume they know what
423 # they're doing.
424 AC_MSG_WARN([chosen localstatedir '$guix_localstatedir' does not match \
425that of the existing installation '$guix_cv_current_localstatedir'])
426 AC_MSG_WARN([installing may corrupt $storedir!])
427 ;;
428 esac
429 fi
430 fi])
431
432dnl GUIX_CHANNEL_METADATA
433dnl
434dnl Provide the channel metadata for this build. This allows 'guix describe'
435dnl to return meaningful data, as it would for a 'guix pull'-provided 'guix'.
436dnl The default URL and introduction are taken from (guix channels).
437AC_DEFUN([GUIX_CHANNEL_METADATA], [
438 AC_ARG_WITH([channel-url], [AS_HELP_STRING([--with-channel-url=URL],
439 [assert that this is built from the Git repository at URL])],
440 [guix_channel_url="\"$withval\""],
441 [guix_channel_url="\"https://git.guix.gnu.org/guix.git\""])
442 AC_ARG_WITH([channel-commit], [AS_HELP_STRING([--with-channel-commit=COMMIT],
443 [assert that this is built from COMMIT])],
444 [guix_channel_commit="\"$withval\""],
445 [guix_channel_commit="#f"])
446 AC_ARG_WITH([channel-introduction], [AS_HELP_STRING([--with-channel-introduction=COMMIT:FINGERPRINT],
447 [specify COMMIT and FINGERPRINT as the introduction of this channel])],
448 [guix_channel_introduction="'(\"`echo $withval | cut -f1 -d:`\" \"`echo $withval | cut -f2 -d:`\")"],
449 [guix_channel_introduction="'(\"9edb3f66fd807b096b48283debdcddccfea34bad\" . \"BBB0 2DDF 2CEA F6A8 0D1D E643 A2A0 6DF2 A33A 54FA\")"])
450
451 GUIX_CHANNEL_URL="$guix_channel_url"
452 GUIX_CHANNEL_COMMIT="$guix_channel_commit"
453 GUIX_CHANNEL_INTRODUCTION="$guix_channel_introduction"
454
455 AC_SUBST([GUIX_CHANNEL_URL])
456 AC_SUBST([GUIX_CHANNEL_COMMIT])
457 AC_SUBST([GUIX_CHANNEL_INTRODUCTION])
458])