On Fri, May 31, 2024 at 12:24 PM Arthur Cohen <arthur.co...@embecosm.com> wrote: > > Hi Richard, > > On 4/30/24 09:55, Richard Biener wrote: > > 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. > > Thanks a lot for the review. I've udpated the patch's content in > configure.ac per your suggestion. Tested similarly on x86_64 and in a > container with libc 2.27
LGTM. Thanks, Richard. > From 00669b600a75743523c358ee41ab999b6e9fa0f6 Mon Sep 17 00:00:00 2001 > From: Arthur Cohen <arthur.co...@embecosm.com> > Date: Fri, 12 Apr 2024 13:52:18 +0200 > Subject: [PATCH] rust: Do not link with libdl and libpthread unconditionally > > 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 | 154 ++++++++++++++++++++++++++++++++++++++++++ > configure.ac | 41 +++++++++++ > gcc/rust/Make-lang.in | 6 +- > 5 files changed, 203 insertions(+), 4 deletions(-) > > diff --git a/Makefile.in b/Makefile.in > index edb0c8a9a42..1753fb6b862 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 adbcbdd1d57..4aeaad3c1a5 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 02b435c1163..a9ea5258f0f 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 > @@ -8826,6 +8827,139 @@ 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 > + > +missing_rust_dynlibs=none > + > +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library > containing dlopen" >&5 > +$as_echo_n "checking for library containing dlopen... " >&6; } > +if ${ac_cv_search_dlopen+:} false; then : > + $as_echo_n "(cached) " >&6 > +else > + ac_func_search_save_LIBS=$LIBS > +cat confdefs.h - <<_ACEOF >conftest.$ac_ext > +/* end confdefs.h. */ > + > +/* Override any GCC internal prototype to avoid an error. > + Use char because int might match the return type of a GCC > + builtin and then its argument prototype would still apply. */ > +#ifdef __cplusplus > +extern "C" > +#endif > +char dlopen (); > +int > +main () > +{ > +return dlopen (); > + ; > + return 0; > +} > +_ACEOF > +for ac_lib in '' dl; do > + if test -z "$ac_lib"; then > + ac_res="none required" > + else > + ac_res=-l$ac_lib > + LIBS="-l$ac_lib $ac_func_search_save_LIBS" > + fi > + if ac_fn_c_try_link "$LINENO"; then : > + ac_cv_search_dlopen=$ac_res > +fi > +rm -f core conftest.err conftest.$ac_objext \ > + conftest$ac_exeext > + if ${ac_cv_search_dlopen+:} false; then : > + break > +fi > +done > +if ${ac_cv_search_dlopen+:} false; then : > + > +else > + ac_cv_search_dlopen=no > +fi > +rm conftest.$ac_ext > +LIBS=$ac_func_search_save_LIBS > +fi > +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_dlopen" >&5 > +$as_echo "$ac_cv_search_dlopen" >&6; } > +ac_res=$ac_cv_search_dlopen > +if test "$ac_res" != no; then : > + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" > + > +fi > + > +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library > containing pthread_create" >&5 > +$as_echo_n "checking for library containing pthread_create... " >&6; } > +if ${ac_cv_search_pthread_create+:} false; then : > + $as_echo_n "(cached) " >&6 > +else > + ac_func_search_save_LIBS=$LIBS > +cat confdefs.h - <<_ACEOF >conftest.$ac_ext > +/* end confdefs.h. */ > + > +/* Override any GCC internal prototype to avoid an error. > + Use char because int might match the return type of a GCC > + builtin and then its argument prototype would still apply. */ > +#ifdef __cplusplus > +extern "C" > +#endif > +char pthread_create (); > +int > +main () > +{ > +return pthread_create (); > + ; > + return 0; > +} > +_ACEOF > +for ac_lib in '' pthread; do > + if test -z "$ac_lib"; then > + ac_res="none required" > + else > + ac_res=-l$ac_lib > + LIBS="-l$ac_lib $ac_func_search_save_LIBS" > + fi > + if ac_fn_c_try_link "$LINENO"; then : > + ac_cv_search_pthread_create=$ac_res > +fi > +rm -f core conftest.err conftest.$ac_objext \ > + conftest$ac_exeext > + if ${ac_cv_search_pthread_create+:} false; then : > + break > +fi > +done > +if ${ac_cv_search_pthread_create+:} false; then : > + > +else > + ac_cv_search_pthread_create=no > +fi > +rm conftest.$ac_ext > +LIBS=$ac_func_search_save_LIBS > +fi > +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: > $ac_cv_search_pthread_create" >&5 > +$as_echo "$ac_cv_search_pthread_create" >&6; } > +ac_res=$ac_cv_search_pthread_create > +if test "$ac_res" != no; then : > + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" > + > +fi > + > + > +if test $ac_cv_search_dlopen = -ldl; then > + CRAB1_LIBS="$CRAB1_LIBS -ldl" > +elif test $ac_cv_search_dlopen = no; then > + missing_rust_dynlibs="libdl" > +fi > + > +if test $ac_cv_search_pthread_create = -lpthread; then > + CRAB1_LIBS="$CRAB1_LIBS -lpthread" > +elif test $ac_cv_search_pthread_crate = no; then > + missing_rust_dynlibs="$missing_rust_dynlibs, libpthread" > +fi > + > +CRAB1_LIBS="$CRAB1_LIBS" > + > + > # 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. > @@ -9066,6 +9200,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 1a19c07a27b..adb738ac346 100644 > --- a/configure.ac > +++ b/configure.ac > @@ -2036,6 +2036,28 @@ 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 > + > +missing_rust_dynlibs=none > + > +AC_SEARCH_LIBS([dlopen], [dl]) > +AC_SEARCH_LIBS([pthread_create], [pthread]) > + > +if test $ac_cv_search_dlopen = -ldl; then > + CRAB1_LIBS="$CRAB1_LIBS -ldl" > +elif test $ac_cv_search_dlopen = no; then > + missing_rust_dynlibs="libdl" > +fi > + > +if test $ac_cv_search_pthread_create = -lpthread; then > + CRAB1_LIBS="$CRAB1_LIBS -lpthread" > +elif test $ac_cv_search_pthread_crate = no; then > + missing_rust_dynlibs="$missing_rust_dynlibs, libpthread" > +fi > + > +AC_SUBST(CRAB1_LIBS, "$CRAB1_LIBS") > + > # 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. > @@ -2273,6 +2295,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 dd94c9b5eab..edcf2ee4c7b 100644 > --- a/gcc/rust/Make-lang.in > +++ b/gcc/rust/Make-lang.in > @@ -54,8 +54,6 @@ GCCRS_D_OBJS = \ > rust/rustspec.o \ > $(END) > > -LIBS += -ldl -lpthread > - > gccrs$(exeext): $(GCCRS_D_OBJS) $(EXTRA_GCC_OBJS) libcommon-target.a > $(LIBDEPS) > +$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \ > $(GCCRS_D_OBJS) $(EXTRA_GCC_OBJS) libcommon-target.a \ > @@ -234,7 +232,7 @@ crab1$(exeext): $(RUST_ALL_OBJS) attribs.o > $(BACKEND) $(LIBDEPS) $(LIBPROC_MACRO > @$(call LINK_PROGRESS,$(INDEX.rust),start) > +$(LLINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \ > $(RUST_ALL_OBJS) attribs.o $(BACKEND) \ > - $(LIBS) $(LIBPROC_MACRO_INTERNAL) $(LIBFORMAT_PARSER) > $(LIBFFI_POLONIUS) \ > + $(LIBS) $(CRAB1_LIBS) $(LIBPROC_MACRO_INTERNAL) > $(LIBFORMAT_PARSER) $(LIBFFI_POLONIUS) \ > $(BACKENDLIBS) > @$(call LINK_PROGRESS,$(INDEX.rust),end) > > @@ -496,4 +494,4 @@ rust/libffi_polonius.a: \ > rust/checks/errors/borrowck/ffi-polonius/Cargo.toml \ > $(wildcard $(srcdir)/rust/checks/errors/borrowck/ffi-polonius/src/*) > cargo build --manifest-path > $(srcdir)/rust/checks/errors/borrowck/ffi-polonius/Cargo.toml --release > --target-dir rust/ffi-polonius > - cp rust/ffi-polonius/release/libffi_polonius.a rust/libffi_polonius.a > \ No newline at end of file > + cp rust/ffi-polonius/release/libffi_polonius.a rust/libffi_polonius.a > -- > 2.42.0 >