diff --git a/configure b/configure index a740276ca..5c78fcbce 100755 --- a/configure +++ b/configure @@ -70,17 +70,23 @@ 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 +FLAG_without_libc_features='' # 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='' +# libc +have_fnm_extmatch='' +have_glob_period='' +have_pwent='' + parse_flags() { while true; do case "$1" in @@ -111,12 +117,12 @@ parse_flags() { FLAG_readline=$1 ;; - --with-systemtap_sdt) - FLAG_with_systemtap_sdt=1 + --without-systemtap-sdt) + FLAG_without_systemtap_sdt=1 ;; - --without-systemtap_sdt) - FLAG_without_systemtap_sdt=1 + --without-libc-features) + FLAG_without_libc_features=1 ;; # TODO: Maybe prefix only needs to be part of the install step? I'm not @@ -269,25 +275,51 @@ detect_systemtap_sdt() { fi } +detect_libc() { + if test -n "$FLAG_without_libc_features"; then + return + fi + + # Check if non-POSIX FNM_EXTMATCH is available + if cc_quiet build/detect-fnm-extmatch.c; then + have_fnm_extmatch=1 + fi + + # Check if non-POSIX GLOB_PERIOD is available + if cc_quiet build/detect-glob-period.c; then + have_glob_period=1 + fi + + # Check if pwent is callable. E.g. bionic libc (Android) doesn't have it + if cc_quiet build/detect-pwent.c; then + have_pwent=1 + fi +} + echo_shell_vars() { if test "$detected_deps" != 1; then die 'called echo_shell_vars before detecting readline.' fi + + # Present a consistent interface to build/ninja-rules-cpp.sh 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 + + # TODO: I don't think we need this in shell 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 @@ -433,21 +465,22 @@ echo_cpp() { echo '/* #undef HAVE_READLINE */' fi + # Used by mycpp/probes.h 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' + if test "$have_fnm_extmatch" = 1; then + echo '/* libc defines FNM_EXTMATCH */' else - echo '/* #undef HAVE_PWENT */' + # INVALID value that we can detect in code + # e.g. musl libc does not support this, but glibc does + echo '#define FNM_EXTMATCH 0' fi - # Check if non-POSIX GLOB_PERIOD is available - if cc_quiet build/detect-glob-period.c; then + if test "$have_glob_period" = 1; then echo '/* libc defines GLOB_PERIOD */' else # INVALID value that we can detect in code @@ -455,13 +488,11 @@ echo_cpp() { echo '#define GLOB_PERIOD 0' fi - # Check if non-POSIX GLOB_PERIOD is available - if cc_quiet build/detect-fnm-extmatch.c; then - echo '/* libc defines FNM_EXTMATCH */' + # Used by cpp/core.cc + if test "$have_pwent" = 1; then + echo '#define HAVE_PWENT 1' else - # INVALID value that we can detect in code - # e.g. musl libc does not support this, but glibc does - echo '#define FNM_EXTMATCH 0' + echo '/* #undef HAVE_PWENT */' fi } @@ -480,9 +511,11 @@ main() { # Sets globals $have_readline and $readline_dir detect_readline + detect_libc + detect_systemtap_sdt - # Generate configuration for oil-native + # Generate configuration for oils-for-unix local cpp_out=_build/detected-cpp-config.h echo_cpp > $cpp_out log "Wrote $cpp_out" diff --git a/core/state.py b/core/state.py index 69e6e9448..902bdda7d 100644 --- a/core/state.py +++ b/core/state.py @@ -36,6 +36,7 @@ NewDict) from pylib import os_path +from libc import GLOB_PERIOD import posix_ as posix from typing import Tuple, List, Dict, Optional, Any, cast, TYPE_CHECKING @@ -344,6 +345,14 @@ def _SetOptionNum(opt_name): return opt_num +def _MaybeWarnDotglob(): + # type: () -> None + if GLOB_PERIOD == 0: # invalid value that means it wasn't detected + # GNU libc and musl libc have GLOB_PERIOD, but Android doesn't + print_stderr( + "osh warning: GLOB_PERIOD wasn't found in libc, so 'shopt -s dotglob' won't work") + + class MutableOpts(object): def __init__(self, mem, environ, opt0_array, opt_stacks, opt_hook): @@ -379,6 +388,9 @@ def _InitOptionsFromEnv(self, shellopts): def Push(self, opt_num, b): # type: (int, bool) -> None + if opt_num == option_i.dotglob: + _MaybeWarnDotglob() + overlay = self.opt_stacks[opt_num] if overlay is None or len(overlay) == 0: self.opt_stacks[opt_num] = [b] # Allocate a new list @@ -418,6 +430,8 @@ def _Set(self, opt_num, b): For bash compatibility in command sub. """ + if opt_num == option_i.dotglob: + _MaybeWarnDotglob() # Like _Getter in core/optview.py overlay = self.opt_stacks[opt_num] @@ -510,7 +524,7 @@ def _SetOldOption(self, opt_name, b): self.SetDeferredErrExit(b) else: if opt_num == option_i.verbose and b: - print_stderr('Warning: set -o verbose not implemented') + print_stderr('osh warning: set -o verbose not implemented') self._SetArrayByNum(opt_num, b) # note: may FAIL before we get here. diff --git a/deps/from-tar.sh b/deps/from-tar.sh index 4c235dcaa..0b54b7154 100755 --- a/deps/from-tar.sh +++ b/deps/from-tar.sh @@ -1,15 +1,16 @@ #!/usr/bin/env bash # -# Handle build dependencies that are in tarballs. +# Handle build dependencies that are in tarballs, like the wild # # Usage: # deps/from-tar.sh # -# Examples: -# deps/from-tar.sh download-re2c -# deps/from-tar.sh build-re2c +# For releases: # -# The executable will be in ../oil_DEPS/re2c/re2c. +# deps/from-tar.sh configure-python +# deps/from-tar.sh build-python +# +# Note: this is not a tarball; it's in the repo. set -o nounset set -o pipefail diff --git a/devtools/release.sh b/devtools/release.sh index 984a7fd19..f4ca69193 100755 --- a/devtools/release.sh +++ b/devtools/release.sh @@ -6,7 +6,8 @@ # devtools/release.sh # # Steps: -# edit oils-version.txt, build/doc.sh update-src-versions, bump devtools/release-note.sh +# edit oils-version.txt, build/doc.sh update-src-versions, and +# bump devtools/release-note.sh # $0 make-release-branch # $0 two-tarballs # CPython, then oils-for-unix, which is INSTALLED # demo/osh-debug.sh osh-for-release: Start a shell to dogfood diff --git a/doc/portability.md b/doc/portability.md index d1f7d675c..b1e9609e5 100644 --- a/doc/portability.md +++ b/doc/portability.md @@ -30,8 +30,6 @@ which some libc's implement. This is unlike bash, which has its own glob library. -TODO: `shopt -s dotglob` should give a warning when turned on. - ### Atomic Assignments The signal handler assumes that int and pointer assignments are atomic. This diff --git a/frontend/py_readline.py b/frontend/py_readline.py index 5c7eafad5..5f28b9075 100644 --- a/frontend/py_readline.py +++ b/frontend/py_readline.py @@ -5,6 +5,10 @@ try: import line_input except ImportError: + # Note: build/ovm-compile.sh doesn't build pyext/line_input.c unless shell + # var $HAVE_READLINE is set + # On the other hand, cpp/frontend_pyreadline.cc uses -D HAVE_READLINE, a + # C++ preprocessor var line_input = None from typing import Optional, TYPE_CHECKING diff --git a/osh/glob_.py b/osh/glob_.py index 0afd5ac02..df939c37b 100644 --- a/osh/glob_.py +++ b/osh/glob_.py @@ -13,10 +13,11 @@ ) from core import pyutil from frontend import match -from libc import GLOB_PERIOD from mycpp import mylib from mycpp.mylib import log, print_stderr +from libc import GLOB_PERIOD + from typing import List, Tuple, cast, TYPE_CHECKING if TYPE_CHECKING: from core import optview diff --git a/test/configure-effects.sh b/test/configure-effects.sh new file mode 100755 index 000000000..e0812933c --- /dev/null +++ b/test/configure-effects.sh @@ -0,0 +1,62 @@ +#!/usr/bin/env bash +# +# What happens if various build features aren't detected? +# In Python and C++ +# +# Usage: +# test/configure-effects.sh + +set -o nounset +set -o pipefail +set -o errexit + +# bugs: +# echo | tr +# echo | cat +# history | less + +prepare-cpp() { + ./NINJA-config.sh + + # This overwrites the config + ./configure --without-readline --without-libc-features --without-systemtap-sdt + + ninja +} + +prepare-py() { + make +} + +test-osh() { + local osh=$1 + + $osh -x -c 'set -o vi' + $osh -x -c 'set -o emacs' + + # GLOB_PERIOD + $osh -x -c 'shopt -s dotglob' + + # FNM_EXTMATCH + # Hm this will works + $osh -x -c 'echo */@(*.bash|*.asdl)' + + # HAVE_PWENT + $osh -x -c 'compgen -A user' +} + +cpp() { + #prepare + + test-osh _bin/cxx-asan/osh +} + +py() { + #prepare-py + + ln -s -f -v oil.ovm _bin/osh + + test-osh _bin/osh +} + +"$@"