On Fri, Apr 19, 2024 at 11:49 AM Arthur Cohen <arthur.co...@embecosm.com> wrote: > > Hi everyone, > > This patch checks for the presence of dlopen and pthread_create in libc. If > that is not the > case, we check for the existence of -ldl and -lpthread, as these libraries > are required to > link the Rust runtime to our Rust frontend. > > If these libs are not present on the system, then we disable the Rust > frontend. > > This was tested on x86_64, in an environment with a recent GLIBC and in a > container with GLIBC > 2.27. > > Apologies for sending it in so late.
For example GCC_ENABLE_PLUGINS simply does # Check -ldl saved_LIBS="$LIBS" AC_SEARCH_LIBS([dlopen], [dl]) if test x"$ac_cv_search_dlopen" = x"-ldl"; then pluginlibs="$pluginlibs -ldl" fi LIBS="$saved_LIBS" which I guess would also work for pthread_create? This would simplify the code a bit. > ChangeLog: > > * Makefile.tpl: Add CRAB1_LIBS variable. > * Makefile.in: Regenerate. > * configure: Regenerate. > * configure.ac: Check if -ldl and -lpthread are needed, and if so, add > them to CRAB1_LIBS. > > gcc/rust/ChangeLog: > > * Make-lang.in: Remove overazealous LIBS = -ldl -lpthread line, link > crab1 against CRAB1_LIBS. > --- > Makefile.in | 3 + > Makefile.tpl | 3 + > configure | 157 ++++++++++++++++++++++++++++++++++++++++++ > configure.ac | 94 +++++++++++++++++++++++++ > gcc/rust/Make-lang.in | 2 +- > 5 files changed, 258 insertions(+), 1 deletion(-) > > diff --git a/Makefile.in b/Makefile.in > index db4fa6c6260..34c5550beca 100644 > --- a/Makefile.in > +++ b/Makefile.in > @@ -197,6 +197,7 @@ HOST_EXPORTS = \ > $(BASE_EXPORTS) \ > CC="$(CC)"; export CC; \ > ADA_CFLAGS="$(ADA_CFLAGS)"; export ADA_CFLAGS; \ > + CRAB1_LIBS="$(CRAB1_LIBS)"; export CRAB1_LIBS; \ > CFLAGS="$(CFLAGS)"; export CFLAGS; \ > CONFIG_SHELL="$(SHELL)"; export CONFIG_SHELL; \ > CXX="$(CXX)"; export CXX; \ > @@ -450,6 +451,8 @@ GOCFLAGS = $(CFLAGS) > GDCFLAGS = @GDCFLAGS@ > GM2FLAGS = $(CFLAGS) > > +CRAB1_LIBS = @CRAB1_LIBS@ > + > PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ > > GUILE = guile > diff --git a/Makefile.tpl b/Makefile.tpl > index 1d5813cd569..8f4bf297918 100644 > --- a/Makefile.tpl > +++ b/Makefile.tpl > @@ -200,6 +200,7 @@ HOST_EXPORTS = \ > $(BASE_EXPORTS) \ > CC="$(CC)"; export CC; \ > ADA_CFLAGS="$(ADA_CFLAGS)"; export ADA_CFLAGS; \ > + CRAB1_LIBS="$(CRAB1_LIBS)"; export CRAB1_LIBS; \ > CFLAGS="$(CFLAGS)"; export CFLAGS; \ > CONFIG_SHELL="$(SHELL)"; export CONFIG_SHELL; \ > CXX="$(CXX)"; export CXX; \ > @@ -453,6 +454,8 @@ GOCFLAGS = $(CFLAGS) > GDCFLAGS = @GDCFLAGS@ > GM2FLAGS = $(CFLAGS) > > +CRAB1_LIBS = @CRAB1_LIBS@ > + > PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ > > GUILE = guile > diff --git a/configure b/configure > index 3b0abeb8b2e..75b489a5f57 100755 > --- a/configure > +++ b/configure > @@ -690,6 +690,7 @@ extra_host_zlib_configure_flags > extra_host_libiberty_configure_flags > stage1_languages > host_libs_picflag > +CRAB1_LIBS > PICFLAG > host_shared > gcc_host_pie > @@ -8875,6 +8876,142 @@ fi > > > > +# Rust requires -ldl and -lpthread if you are using an old glibc that does > not include them by > +# default, so we check for them here > + > +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if libc includes libdl and > libpthread" >&5 > +$as_echo_n "checking if libc includes libdl and libpthread... " >&6; } > + > +ac_ext=c > +ac_cpp='$CPP $CPPFLAGS' > +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' > +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS > conftest.$ac_ext $LIBS >&5' > +ac_compiler_gnu=$ac_cv_c_compiler_gnu > + > + > +requires_ldl=no > +requires_lpthread=no > +missing_rust_dynlibs=none > + > +cat confdefs.h - <<_ACEOF >conftest.$ac_ext > +/* end confdefs.h. */ > +#include <dlfcn.h> > +int > +main () > +{ > +dlopen(0,0); > + ; > + return 0; > +} > +_ACEOF > +if ac_fn_c_try_link "$LINENO"; then : > + > +else > + requires_ldl=yes > + > +fi > +rm -f core conftest.err conftest.$ac_objext \ > + conftest$ac_exeext conftest.$ac_ext > + > +if test $requires_ldl = yes; then > + tmp_LIBS=$LIBS > + LIBS="$LIBS -ldl" > + > + cat confdefs.h - <<_ACEOF >conftest.$ac_ext > +/* end confdefs.h. */ > +#include <dlfcn.h> > +int > +main () > +{ > +dlopen(0,0); > + ; > + return 0; > +} > +_ACEOF > +if ac_fn_c_try_link "$LINENO"; then : > + CRAB1_LIBS="$CRAB1_LIBS -ldl" > +else > + missing_rust_dynlibs="libdl" > + > +fi > +rm -f core conftest.err conftest.$ac_objext \ > + conftest$ac_exeext conftest.$ac_ext > + > + LIBS=$tmp_LIBS > +fi > + > +cat confdefs.h - <<_ACEOF >conftest.$ac_ext > +/* end confdefs.h. */ > +#include <pthread.h> > +int > +main () > +{ > +pthread_create(NULL,NULL,NULL,NULL); > + > + ; > + return 0; > +} > +_ACEOF > +if ac_fn_c_try_link "$LINENO"; then : > + > +else > + requires_lpthread=yes > + > +fi > +rm -f core conftest.err conftest.$ac_objext \ > + conftest$ac_exeext conftest.$ac_ext > + > +if test $requires_lpthread = yes; then > + tmp_LIBS=$LIBS > + LIBS="$LIBS -lpthread" > + > + cat confdefs.h - <<_ACEOF >conftest.$ac_ext > +/* end confdefs.h. */ > +#include <pthread.h> > +int > +main () > +{ > +pthread_create(NULL,NULL,NULL,NULL); > + > + ; > + return 0; > +} > +_ACEOF > +if ac_fn_c_try_link "$LINENO"; then : > + CRAB1_LIBS="$CRAB1_LIBS -lpthread" > +else > + missing_rust_dynlibs="$missing_rust_dynlibs, libpthread" > + > +fi > +rm -f core conftest.err conftest.$ac_objext \ > + conftest$ac_exeext conftest.$ac_ext > + > + LIBS=$tmp_LIBS > +fi > + > +if test "$missing_rust_dynlibs" = "none"; then > + if test $requires_ldl = yes -a $requires_lpthread = yes; then > + { $as_echo "$as_me:${as_lineno-$LINENO}: result: not included, but > available" >&5 > +$as_echo "not included, but available" >&6; } > + else > + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 > +$as_echo "yes" >&6; } > + fi > +else > + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no: missing > $missing_rust_dynlibs" >&5 > +$as_echo "no: missing $missing_rust_dynlibs" >&6; } > +fi > + > +CRAB1_LIBS="$CRAB1_LIBS" > + > + > +ac_ext=c > +ac_cpp='$CPP $CPPFLAGS' > +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' > +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS > conftest.$ac_ext $LIBS >&5' > +ac_compiler_gnu=$ac_cv_c_compiler_gnu > + > + > # If we are building PIC/PIE host executables, and we are building dependent > # libs (e.g. GMP) in-tree those libs need to be configured to generate PIC > # code. > @@ -9115,6 +9252,26 @@ $as_echo "$as_me: WARNING: GDC is required to build > $language" >&2;} > ;; > esac > > + # Disable Rust if we are missing some required C libraries for the > Rust runtime. > + case ${add_this_lang}:${language}:${missing_rust_dynlibs} in > + *:rust:none) > + # Nothing to do - we're not missing any C libraries > + ;; > + yes:rust:*) > + as_fn_error $? "some C libraries are required to build > $language: $missing_rust_dynlibs" "$LINENO" 5 > + add_this_lang=unsupported > + ;; > + all:rust:*) > + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: some C > libraries are required to build $language: $missing_rust_dynlibs" >&5 > +$as_echo "$as_me: WARNING: some C libraries are required to build $language: > $missing_rust_dynlibs" >&2;} > + add_this_lang=unsupported > + ;; > + *:rust:*) > + # Silently disable. > + add_this_lang=unsupported > + ;; > + esac > + > # Disable jit if -enable-host-shared not specified > # but not if building for Mingw. All code in Windows > # is position independent code (PIC). > diff --git a/configure.ac b/configure.ac > index 042681c27be..d96b7b5432e 100644 > --- a/configure.ac > +++ b/configure.ac > @@ -2037,6 +2037,81 @@ fi > > AC_SUBST(PICFLAG) > > +# Rust requires -ldl and -lpthread if you are using an old glibc that does > not include them by > +# default, so we check for them here > + > +AC_MSG_CHECKING([if libc includes libdl and libpthread]) > + > +AC_LANG_PUSH([C]) > + > +requires_ldl=no > +requires_lpthread=no > +missing_rust_dynlibs=none > + > +AC_LINK_IFELSE( > + [AC_LANG_PROGRAM( > + [#include <dlfcn.h>], > + [dlopen(0,0);], > + )], > + [], > + [requires_ldl=yes] > +) > + > +if test $requires_ldl = yes; then > + tmp_LIBS=$LIBS > + LIBS="$LIBS -ldl" > + > + AC_LINK_IFELSE( > + [AC_LANG_PROGRAM( > + [#include <dlfcn.h>], > + [dlopen(0,0);], > + )], > + [CRAB1_LIBS="$CRAB1_LIBS -ldl"], > + [missing_rust_dynlibs="libdl"] > + ) > + > + LIBS=$tmp_LIBS > +fi > + > +AC_LINK_IFELSE( > + [AC_LANG_PROGRAM( > + [#include <pthread.h>], > + [pthread_create(NULL,NULL,NULL,NULL);] > + )], > + [], > + [requires_lpthread=yes] > +) > + > +if test $requires_lpthread = yes; then > + tmp_LIBS=$LIBS > + LIBS="$LIBS -lpthread" > + > + AC_LINK_IFELSE( > + [AC_LANG_PROGRAM( > + [#include <pthread.h>], > + [pthread_create(NULL,NULL,NULL,NULL);] > + )], > + [CRAB1_LIBS="$CRAB1_LIBS -lpthread"], > + [missing_rust_dynlibs="$missing_rust_dynlibs, libpthread"] > + ) > + > + LIBS=$tmp_LIBS > +fi > + > +if test "$missing_rust_dynlibs" = "none"; then > + if test $requires_ldl = yes -a $requires_lpthread = yes; then > + AC_MSG_RESULT([not included, but available]) > + else > + AC_MSG_RESULT([yes]) > + fi > +else > + AC_MSG_RESULT([no: missing $missing_rust_dynlibs]) > +fi > + > +AC_SUBST(CRAB1_LIBS, "$CRAB1_LIBS") > + > +AC_LANG_POP([C]) > + > # If we are building PIC/PIE host executables, and we are building dependent > # libs (e.g. GMP) in-tree those libs need to be configured to generate PIC > # code. > @@ -2274,6 +2349,25 @@ if test -d ${srcdir}/gcc; then > ;; > esac > > + # Disable Rust if we are missing some required C libraries for the > Rust runtime. > + case ${add_this_lang}:${language}:${missing_rust_dynlibs} in > + *:rust:none) > + # Nothing to do - we're not missing any C libraries > + ;; > + yes:rust:*) > + AC_MSG_ERROR([some C libraries are required to build $language: > $missing_rust_dynlibs]) > + add_this_lang=unsupported > + ;; > + all:rust:*) > + AC_MSG_WARN([some C libraries are required to build $language: > $missing_rust_dynlibs]) > + add_this_lang=unsupported > + ;; > + *:rust:*) > + # Silently disable. > + add_this_lang=unsupported > + ;; > + esac > + > # Disable jit if -enable-host-shared not specified > # but not if building for Mingw. All code in Windows > # is position independent code (PIC). > diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in > index 8db04163618..bb2e246f9fa 100644 > --- a/gcc/rust/Make-lang.in > +++ b/gcc/rust/Make-lang.in > @@ -214,7 +214,7 @@ LIBPROC_MACRO_INTERNAL = > ../libgrust/libproc_macro_internal/libproc_macro_intern > crab1$(exeext): $(RUST_ALL_OBJS) attribs.o $(BACKEND) $(LIBDEPS) > $(LIBPROC_MACRO_INTERNAL) $(rust.prev) > @$(call LINK_PROGRESS,$(INDEX.rust),start) > +$(LLINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \ > - $(RUST_ALL_OBJS) attribs.o $(BACKEND) $(LIBS) > $(LIBPROC_MACRO_INTERNAL) $(BACKENDLIBS) > + $(RUST_ALL_OBJS) attribs.o $(BACKEND) $(LIBS) $(CRAB1_LIBS) > $(LIBPROC_MACRO_INTERNAL) $(BACKENDLIBS) > @$(call LINK_PROGRESS,$(INDEX.rust),end) > > # Build hooks. > -- > 2.42.1 >