diff --git a/druntime/.gitignore b/druntime/.gitignore index 454fd6d2e9d8..eee9cc2d601e 100644 --- a/druntime/.gitignore +++ b/druntime/.gitignore @@ -11,3 +11,6 @@ trace.log /msvc*.obj make *.lst + +# generated during the build +/src/core/sys/linux/config.d diff --git a/druntime/Makefile b/druntime/Makefile index 2efde5c94009..8b5a47014958 100644 --- a/druntime/Makefile +++ b/druntime/Makefile @@ -370,6 +370,10 @@ $(IMPDIR)/%.h : src/%.h @mkdir -p $(dir $@) @cp $< $@ +################### Feature tests for druntime bindings ######################### + +include features/GNUmakefile + ######################## Build DMD if non-existent ############################## ../generated/$(OS)/$(BUILD)/$(MODEL)/dmd$(DOTEXE): diff --git a/druntime/features/.gitignore b/druntime/features/.gitignore new file mode 100644 index 000000000000..ceeb05b41081 --- /dev/null +++ b/druntime/features/.gitignore @@ -0,0 +1 @@ +/tmp diff --git a/druntime/features/GNUmakefile b/druntime/features/GNUmakefile new file mode 100644 index 000000000000..47e8f5cc7ddb --- /dev/null +++ b/druntime/features/GNUmakefile @@ -0,0 +1,19 @@ +SED:=sed +ifeq ($(OS),$(filter $(OS),freebsd osx)) + SED_INPLACE:=-i '' +else + SED_INPLACE:=-i'' +endif + +export FEATURE_TMPDIR:=$(CURDIR)/features/tmp +export CC + +src/core/sys/linux/config.d: src/core/sys/linux/config.d.in + @cp $< $@ + @if [ "$(OS)" = linux ] \ + && ./features/cc_has_function.sh 'closefrom' '#include '; \ + then \ + $(SED) $(SED_INPLACE) "s/@HAVE_CLOSEFROM@/true/" $@; \ + else \ + $(SED) $(SED_INPLACE) "s/@HAVE_CLOSEFROM@/false/" $@; \ + fi diff --git a/druntime/features/cc_has_function.sh b/druntime/features/cc_has_function.sh new file mode 100755 index 000000000000..5c0eb67cc0e0 --- /dev/null +++ b/druntime/features/cc_has_function.sh @@ -0,0 +1,35 @@ +#!/bin/sh + +die () { + [ $# -ne 0 ] && echo "${@}" + exit 1 +} + +usage () { + echo "Usage: $0
" +} + +[ $# -ne 2 ] && usage && die "Invalid usage!" + +tmp="${FEATURE_TMPDIR}" + +mkdir -p "${tmp}" || die "Could not create temp directory" +outfile="${tmp}/check_${1}.c" + +# Check taken from the meson build system +cat > "${outfile}" < /dev/null 2>&1 +res=$? +[ "${res}" -eq 0 ] && echo "found" || echo "NOT found" + +rm -f "${outfile}" "${outfile}.prog" +exit "${res}" diff --git a/druntime/src/core/sys/linux/config.d b/druntime/src/core/sys/linux/config.d.in similarity index 94% rename from druntime/src/core/sys/linux/config.d rename to druntime/src/core/sys/linux/config.d.in index 5d38244f8584..db0d34fa1acc 100644 --- a/druntime/src/core/sys/linux/config.d +++ b/druntime/src/core/sys/linux/config.d.in @@ -30,3 +30,5 @@ deprecated("use _ATFILE_SOURCE") enum __USE_ATFILE = _ATFILE_SOURCE; deprecated("use _GNU_SOURCE") enum __USE_GNU = _GNU_SOURCE; + +enum __HAVE_CLOSEFROM = @HAVE_CLOSEFROM@; diff --git a/druntime/src/core/sys/linux/unistd.d b/druntime/src/core/sys/linux/unistd.d index 548870268dbf..788ff9693e98 100644 --- a/druntime/src/core/sys/linux/unistd.d +++ b/druntime/src/core/sys/linux/unistd.d @@ -1,6 +1,7 @@ module core.sys.linux.unistd; public import core.sys.posix.unistd; +import core.sys.linux.config; version (linux): extern(C): @@ -23,5 +24,6 @@ char* getpass(const(char)* prompt); // Exit all threads in a process void exit_group(int status); +static if (__HAVE_CLOSEFROM) /// Close all open file descriptors greater or equal to `lowfd` void closefrom(int lowfd);