public inbox for gcc-rust@gcc.gnu.org
 help / color / mirror / Atom feed
From: Richard Biener <richard.guenther@gmail.com>
To: Arthur Cohen <arthur.cohen@embecosm.com>
Cc: gcc-patches@gcc.gnu.org, gcc-rust@gcc.gnu.org
Subject: Re: [PATCH] rust: Do not link with libdl and libpthread unconditionally
Date: Tue, 30 Apr 2024 09:55:23 +0200	[thread overview]
Message-ID: <CAFiYyc0ii_rp29ShFU3m5fsOsjS_i4ETHpze+XTSbUOpMQvuVg@mail.gmail.com> (raw)
In-Reply-To: <20240419094903.512887-1-arthur.cohen@embecosm.com>

On Fri, Apr 19, 2024 at 11:49 AM Arthur Cohen <arthur.cohen@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
>

      reply	other threads:[~2024-04-30  7:55 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-04-19  9:47 Arthur Cohen
2024-04-30  7:55 ` Richard Biener [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CAFiYyc0ii_rp29ShFU3m5fsOsjS_i4ETHpze+XTSbUOpMQvuVg@mail.gmail.com \
    --to=richard.guenther@gmail.com \
    --cc=arthur.cohen@embecosm.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=gcc-rust@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).