forked from oils-for-unix/oils
-
Notifications
You must be signed in to change notification settings - Fork 0
/
configure
executable file
·487 lines (412 loc) · 12.3 KB
/
configure
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
#!/bin/sh
#
# POSIX shell script to detect target system properties required by Oil.
# Distributed with the source tarball.
#
# The only library Oil needs is readline.
#
# External utilities used: cc
#
# TODO: Should be able to run this from another directory.
#
# Other settings: LTO, PGO? Consider moving prefix, LTO, PGO to build and
# install steps.
TMP=${TMPDIR:-/tmp} # Assume that any system has $TMPDIR set or /tmp exists
readonly TMP # POSIX sh supports 'readonly'
log() {
echo "$0: $@" 1>&2
}
info() {
echo "$0 INFO: $@" 1>&2
}
die() {
echo "$0 ERROR: $@" 1>&2
exit 1
}
show_help() {
cat <<'EOF'
Usage: ./configure [OPTION...]
Detects system settings before a build of Oil.
Installation directories:
--prefix=PREFIX Prefix for the bin/ directory [/usr/local]
--datarootdir=DATAROOTDIR Prefix for data files, including man page [PREFIX/share]
Optional features:
--with-readline Fail unless readline is available.
--without-readline Don't compile with readline, even if it's available.
The shell won't have any interactive features.
--readline=DIR An alternative readline installation to link against
--with-systemtap-sdt Fail unless systemtap-sdt is available.
--without-systemtap-sdt Don't compile with systemtap-sdt, even if it's available.
EOF
}
# This script roughly follows the GNU Standards
# https://www.gnu.org/prep/standards/html_node/Configuration.html
# https://www.gnu.org/prep/standards/html_node/Directory-Variables.html
#
# Default installation is /usr/local/bin/oil, but this can be changed with
# --prefix.
#
# While this script only uses a handful of the standard directory variables
# listed on the above documents, it accepts most of them in the --arg=value
# form as noops. This helps automated build-systems passing preconfigured
# sets of arguments to configure oil.
FLAG_prefix='/usr/local'
FLAG_datarootdir='' # default initialized after processing flags
FLAG_with_readline='' # Fail if it's not available.
FLAG_without_readline='' # Don't even check if it's available
FLAG_readline=''
FLAG_with_systemtap_sdt='' # Fail if it's not available.
FLAG_without_systemtap_sdt='' # Don't even check if it's available
# These variables are set by detect_readline and used by echo_cpp and
# echo_shell_vars
detected_deps=''
have_readline=''
readline_dir=''
have_systemtap_sdt=''
parse_flags() {
while true; do
case "$1" in
'')
break
;;
--help)
# TODO: Fill out help
show_help
exit 0
;;
--with-readline)
FLAG_with_readline=1
;;
--without-readline)
FLAG_without_readline=1
;;
--readline=*)
FLAG_readline="${1#*=}"
;;
--readline)
if test $# -eq 1; then
die "--readline requires an argument"
fi
shift
FLAG_readline=$1
;;
--with-systemtap_sdt)
FLAG_with_systemtap_sdt=1
;;
--without-systemtap_sdt)
FLAG_without_systemtap_sdt=1
;;
# TODO: Maybe prefix only needs to be part of the install step? I'm not
# sure if we need it for building anything.
--prefix=*)
FLAG_prefix="${1#*=}"
;;
--prefix)
if test $# -eq 1; then
die "--prefix requires an argument"
fi
shift
FLAG_prefix=$1
;;
# Following autoconf's spelling of --mandir
--datarootdir=*)
FLAG_datarootdir="${1#*=}"
;;
--datarootdir)
if test $# -eq 1; then
die "--datarootdir requires an argument"
fi
shift
FLAG_datarootdir=$1
;;
--with-*|--enable-*)
info "Argument '$1' not used by this configure script"
;;
--build=*|--host=*)
info "Argument '$1' not used by this configure script"
;;
--exec-prefix=*|--bindir=*|--sbindir=*|--libexecdir=*|--sysconfdir=*)
info "Argument '$1' not used by this configure script"
;;
--sharedstatedir=*|--localstatedir=*|--runstatedir=*)
info "Argument '$1' not used by this configure script"
;;
--libdir=*|--includedir=*|--oldincludedir=*)
info "Argument '$1' not used by this configure script"
;;
--datadir=*|--infodir=*|--localedir=*|--mandir=*|--docdir=*)
info "Argument '$1' not used by this configure script"
;;
--htmldir=*|--dvidir=*|--pdfdir=*|--psdir=*)
info "Argument '$1' not used by this configure script"
;;
*)
die "Invalid argument '$1'"
;;
esac
shift
done
# If not set, fallback to --prefix
FLAG_datarootdir=${FLAG_datarootdir:-$FLAG_prefix/share}
}
# No output file, no logging, no stderr.
# TODO: Maybe send stdout/stderr to config.log?
cc_quiet() {
cc "$@" -o /dev/null >/dev/null 2>&1
}
cc_or_die() {
if ! cc "$@" >$TMP/cc.log 2>&1; then
log "Error running 'cc $@':"
cat $TMP/cc.log
die "Fatal compile error running feature test"
fi
}
# Check if a given program compiles
cc_statement() {
local pp_var="$1"
local prog="$2"
local includes="$3"
cat >$TMP/cc_statement.c <<EOF
$includes
int main() {
$prog
}
EOF
# Return exit code of compiler
if cc_quiet $TMP/cc_statement.c; then
echo "#define $pp_var 1"
return 0
else
return 1
fi
}
# Check if a given library is installed via compilation
cc_header_file() {
local pp_var="$1"
local c_lib="$2"
cc_statement "$pp_var" 'return 0;' "#include <$c_lib>"
}
detect_readline() {
detected_deps=1 # for assertions in echo_shell_vars and echo_cpp
# User disabled readline
if test -n "$FLAG_without_readline"; then
# have_readline remains false
return
fi
# User requested specific location
if test -n "$FLAG_readline"; then
if cc_quiet build/detect-readline.c \
-L "$FLAG_readline/lib" \
-I "$FLAG_readline/include" \
-l readline; then
readline_dir="$FLAG_readline"
have_readline=1
fi
return
fi
# Detect in default location
if cc_quiet build/detect-readline.c -l readline; then
have_readline=1
return
fi
# User requested that it be found
if test "$FLAG_with_readline" = 1 && test "$have_readline" != 1; then
die 'readline was not detected on the system (--with-readline passed).'
fi
}
detect_systemtap_sdt() {
detected_deps=1 # for assertions in echo_shell_vars and echo_cpp
if test -n "$FLAG_without_systemtap_sdt"; then
return
fi
if cc_quiet build/detect-systemtap-sdt.c; then
have_systemtap_sdt=1
return
fi
}
echo_shell_vars() {
if test "$detected_deps" != 1; then
die 'called echo_shell_vars before detecting readline.'
fi
if test "$have_readline" = 1; then
echo 'HAVE_READLINE=1'
echo "READLINE_DIR=$readline_dir"
else
echo 'HAVE_READLINE='
# Present a consistent interface to build/ninja-rules-cpp.sh
echo 'READLINE_DIR='
fi
if test "$have_systemtap_sdt" = 1; then
echo 'HAVE_SYSTEMTAP_SDT=1'
else
echo 'HAVE_SYSTEMTAP_SDT='
fi
echo "PREFIX=$FLAG_prefix"
echo "DATAROOTDIR=$FLAG_datarootdir"
if cc_quiet build/detect-cc.c -Wl,--gc-sections; then
echo 'STRIP_FLAGS=--gc-sections'
elif cc_quiet build/detect-cc.c -Wl,-dead_strip; then
echo 'STRIP_FLAGS=-dead_strip'
fi
}
# c.m4 AC_LANG_INT_SAVE
cc_print_expr() {
local c_expr="$1"
cat >$TMP/print_expr.c <<EOF
#include <stdio.h>
#include <sys/types.h> /* size_t, pid_t */
int main() {
printf("%lu", $c_expr);
}
EOF
cc_or_die -o $TMP/print_expr $TMP/print_expr.c
$TMP/print_expr > $TMP/print_expr.out
}
# Shell note:
# - local is not POSIX, but most shells have it.
# C note:
# - autoconf uses ac_fn_compute_int (in sh) aka AC_COMPUTE_INT (in m4).
# - it uses different tests when cross compiling.
# - cross-compiling does binary search?
# - other one does AC_LANG_INT_SAVE
# - generates a C program that outputs to conftest.val!
# - well why not use exit code?
# - QEMU configure doesn't do any tests
# Hm, don't bother with cross compiling case for now.
# Check if the size of a type is greater than a certain integer.
check_sizeof() {
local pp_var="$1"
local c_type="$2"
local min_bytes="$3"
cc_print_expr "sizeof($c_type)"
local actual_bytes
actual_bytes=$(cat $TMP/print_expr.out)
if test -n "$min_bytes" && test "$actual_bytes" -lt "$min_bytes"; then
die "sizeof($c_type) should be at least $min_bytes; got $actual_bytes"
fi
# Echo to stdout!
echo "#define $pp_var $actual_bytes"
}
detect_c_language() {
# This is the equivalent of AC_CHECK_SIZEOF(int, 4)
check_sizeof SIZEOF_INT 'int' 4
check_sizeof SIZEOF_LONG 'long' 4
check_sizeof SIZEOF_VOID_P 'void *' 4
check_sizeof SIZEOF_SHORT 'short' 2
check_sizeof SIZEOF_FLOAT 'float' 4
check_sizeof SIZEOF_DOUBLE 'double' 8
check_sizeof SIZEOF_SIZE_T 'size_t' 4
# NOTE: This might only be relevant for large file support, which we don't
# have.
check_sizeof SIZEOF_FPOS_T 'fpos_t' 4
check_sizeof SIZEOF_PID_T 'pid_t' 4
check_sizeof SIZEOF_OFF_T 'off_t' ''
# autoconf checks if we have time.h, but the check isn't used. We just
# assume it's there.
check_sizeof SIZEOF_TIME_T 'time_t' ''
if cc_statement HAVE_LONG_LONG 'long long x; x = (long long)0;'
then
check_sizeof SIZEOF_LONG_LONG 'long long' 8
fi
if cc_statement HAVE_LONG_DOUBLE 'long double x; x = (long double)0;'
then
check_sizeof SIZEOF_LONG_DOUBLE 'long double' 8
fi
if cc_statement HAVE_C99_BOOL '_Bool x; x = (_Bool)0;'
then
# NOTE: this is mainly used in ctypes.h, which we might not need.
check_sizeof SIZEOF__BOOL '_Bool' 1
fi
# NOTE: Python also has a check for C99 uintptr_t. Just assume we don't
# have it?
#if cc_statement HAVE_C99_BOOL 'wchar_t x; x = (wchar_t)0;'
#then
# check_sizeof SIZEOF_WCHAR_T 'wchar_t' 4
#fi
# TODO: Detect header and size.
echo '#define HAVE_WCHAR_H 1'
echo '#define SIZEOF_WCHAR_T 4'
cat >$TMP/detect_va_list.c <<EOF
#include <stdarg.h> /* C89 */
int main() {
va_list list1, list2;
list1 = list2;
}
EOF
if cc_quiet $TMP/detect_va_list.c; then
echo '' # not an array
else
echo '#define VA_LIST_IS_ARRAY 1'
fi
# TODO: are these feature checks really necessary, or can we
# strip these out of posixmodule.c entirely?
cc_header_file HAVE_PTY_H 'pty.h'
cc_header_file HAVE_LIBUTIL_H 'libutil.h'
cc_header_file HAVE_UTIL_H 'util.h'
# TODO: are these feature checks really necessary?
cc_statement HAVE_STAT_TV_NSEC \
'struct stat st; st.st_mtim.tv_nsec = 1; return 0;' \
'#include <sys/stat.h>'
cc_statement HAVE_STAT_TV_NSEC2 \
'struct stat st; st.st_mtimespec.tv_nsec = 1; return 0;' \
'#include <sys/stat.h>'
}
echo_cpp() {
if test "$detected_deps" != 1; then
die 'called echo_cpp before detecting readline.'
fi
# Dev builds can use non-portable clock_gettime()
if test -n "$_OIL_DEV"; then
echo '#define GC_TIMING 1'
log 'Turned on -D GC_TIMING because $_OIL_DEV is set'
fi
if test "$have_readline" = 1; then
echo '#define HAVE_READLINE 1'
else
echo '/* #undef HAVE_READLINE */'
fi
if test "$have_systemtap_sdt" = 1; then
echo '#define HAVE_SYSTEMTAP_SDT 1'
else
echo '/* #undef HAVE_SYSTEMTAP_SDT */'
fi
# Check if pwent is callable. E.g. bionic libc (Android) doesn't have it
if cc_quiet build/detect-pwent.c; then
echo '#define HAVE_PWENT 1'
else
echo '/* #undef HAVE_PWENT */'
fi
}
# Another way of working: set detected-config.mk ?
# And set the default target as oil_readline, oil_no_readline, oil_lto,
# oil_pgo, etc.?
main() {
parse_flags "$@" # sets FLAG_*
mkdir -p _build
if ! cc_quiet build/detect-cc.c; then
die "Couldn't compile a basic C program (cc not installed?)"
fi
# Sets globals $have_readline and $readline_dir
detect_readline
detect_systemtap_sdt
# Generate configuration for oil-native
local cpp_out=_build/detected-cpp-config.h
echo_cpp > $cpp_out
log "Wrote $cpp_out"
# Legacy OVM build: shell build actions will 'source
# _build/detected-config.sh'. And then adjust flags to compiler (-D, -l,
# etc.)
local sh_out=_build/detected-config.sh
echo_shell_vars > $sh_out
log "Wrote $sh_out"
# Fast mode
if test -n "$_OIL_DEV"; then
return
fi
local c_out=_build/detected-config.h
detect_c_language > $c_out
log "Wrote $c_out"
}
if test -z "$_OIL_CONFIGURE_TEST"; then
main "$@"
fi