diff mbox series

build: Check for cargo when building rust language

Message ID 20240408163337.303317-2-pierre-emmanuel.patry@embecosm.com
State New
Headers show
Series build: Check for cargo when building rust language | expand

Commit Message

Pierre-Emmanuel Patry April 8, 2024, 4:33 p.m. UTC
From: Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>

Hello,

The rust frontend requires cargo to build some of it's components,
it's presence was not checked during configuration.

Best regards,
Pierre-Emmanuel

----------

Prevent rust language from building when cargo is
missing.

config/ChangeLog:

	* acx.m4: Add a macro to check for rust
	components.

ChangeLog:

	* configure: Regenerate.
	* configure.ac: Emit an error message when cargo
	is missing.

Signed-off-by: Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
---
 config/acx.m4 |  11 +++++
 configure     | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++
 configure.ac  |  18 ++++++++
 3 files changed, 146 insertions(+)

Comments

Richard Biener April 9, 2024, 7:42 a.m. UTC | #1
On Mon, Apr 8, 2024 at 6:39 PM <pierre-emmanuel.patry@embecosm.com> wrote:
>
> From: Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
>
> Hello,
>
> The rust frontend requires cargo to build some of it's components,
> it's presence was not checked during configuration.

OK.

Please work on documenting build requirements for rust in doc/install.texi,
look for where Ada build requirements are documented.

Richard.

> Best regards,
> Pierre-Emmanuel
>
> ----------
>
> Prevent rust language from building when cargo is
> missing.
>
> config/ChangeLog:
>
>         * acx.m4: Add a macro to check for rust
>         components.
>
> ChangeLog:
>
>         * configure: Regenerate.
>         * configure.ac: Emit an error message when cargo
>         is missing.
>
> Signed-off-by: Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
> ---
>  config/acx.m4 |  11 +++++
>  configure     | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  configure.ac  |  18 ++++++++
>  3 files changed, 146 insertions(+)
>
> diff --git a/config/acx.m4 b/config/acx.m4
> index 7efe98aaf96..3c5fe67342e 100644
> --- a/config/acx.m4
> +++ b/config/acx.m4
> @@ -424,6 +424,17 @@ else
>  fi
>  ])
>
> +# Test for Rust
> +# We require cargo and rustc for some parts of the rust compiler.
> +AC_DEFUN([ACX_PROG_CARGO],
> +[AC_REQUIRE([AC_CHECK_TOOL_PREFIX])
> +AC_CHECK_TOOL(CARGO, cargo, no)
> +if test "x$CARGO" != xno; then
> +  have_cargo=yes
> +else
> +  have_cargo=no
> +fi])
> +
>  # Test for D.
>  AC_DEFUN([ACX_PROG_GDC],
>  [AC_REQUIRE([AC_CHECK_TOOL_PREFIX])
> diff --git a/configure b/configure
> index 874966fb9f0..46e66e20197 100755
> --- a/configure
> +++ b/configure
> @@ -714,6 +714,7 @@ PGO_BUILD_GEN_CFLAGS
>  HAVE_CXX11_FOR_BUILD
>  HAVE_CXX11
>  do_compare
> +CARGO
>  GDC
>  GNATMAKE
>  GNATBIND
> @@ -5786,6 +5787,104 @@ else
>    have_gdc=no
>  fi
>
> +
> +if test -n "$ac_tool_prefix"; then
> +  # Extract the first word of "${ac_tool_prefix}cargo", so it can be a program name with args.
> +set dummy ${ac_tool_prefix}cargo; ac_word=$2
> +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
> +$as_echo_n "checking for $ac_word... " >&6; }
> +if ${ac_cv_prog_CARGO+:} false; then :
> +  $as_echo_n "(cached) " >&6
> +else
> +  if test -n "$CARGO"; then
> +  ac_cv_prog_CARGO="$CARGO" # Let the user override the test.
> +else
> +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
> +for as_dir in $PATH
> +do
> +  IFS=$as_save_IFS
> +  test -z "$as_dir" && as_dir=.
> +    for ac_exec_ext in '' $ac_executable_extensions; do
> +  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
> +    ac_cv_prog_CARGO="${ac_tool_prefix}cargo"
> +    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
> +    break 2
> +  fi
> +done
> +  done
> +IFS=$as_save_IFS
> +
> +fi
> +fi
> +CARGO=$ac_cv_prog_CARGO
> +if test -n "$CARGO"; then
> +  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CARGO" >&5
> +$as_echo "$CARGO" >&6; }
> +else
> +  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
> +$as_echo "no" >&6; }
> +fi
> +
> +
> +fi
> +if test -z "$ac_cv_prog_CARGO"; then
> +  ac_ct_CARGO=$CARGO
> +  # Extract the first word of "cargo", so it can be a program name with args.
> +set dummy cargo; ac_word=$2
> +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
> +$as_echo_n "checking for $ac_word... " >&6; }
> +if ${ac_cv_prog_ac_ct_CARGO+:} false; then :
> +  $as_echo_n "(cached) " >&6
> +else
> +  if test -n "$ac_ct_CARGO"; then
> +  ac_cv_prog_ac_ct_CARGO="$ac_ct_CARGO" # Let the user override the test.
> +else
> +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
> +for as_dir in $PATH
> +do
> +  IFS=$as_save_IFS
> +  test -z "$as_dir" && as_dir=.
> +    for ac_exec_ext in '' $ac_executable_extensions; do
> +  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
> +    ac_cv_prog_ac_ct_CARGO="cargo"
> +    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
> +    break 2
> +  fi
> +done
> +  done
> +IFS=$as_save_IFS
> +
> +fi
> +fi
> +ac_ct_CARGO=$ac_cv_prog_ac_ct_CARGO
> +if test -n "$ac_ct_CARGO"; then
> +  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CARGO" >&5
> +$as_echo "$ac_ct_CARGO" >&6; }
> +else
> +  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
> +$as_echo "no" >&6; }
> +fi
> +
> +  if test "x$ac_ct_CARGO" = x; then
> +    CARGO="no"
> +  else
> +    case $cross_compiling:$ac_tool_warned in
> +yes:)
> +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
> +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
> +ac_tool_warned=yes ;;
> +esac
> +    CARGO=$ac_ct_CARGO
> +  fi
> +else
> +  CARGO="$ac_cv_prog_CARGO"
> +fi
> +
> +if test "x$CARGO" != xno; then
> +  have_cargo=yes
> +else
> +  have_cargo=no
> +fi
>  { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to compare bootstrapped objects" >&5
>  $as_echo_n "checking how to compare bootstrapped objects... " >&6; }
>  if ${gcc_cv_prog_cmp_skip+:} false; then :
> @@ -9099,6 +9198,24 @@ $as_echo "$as_me: WARNING: --enable-host-shared required to build $language" >&2
>            ;;
>          esac
>
> +        # Disable Rust if cargo is unavailable.
> +        case ${add_this_lang}:${language}:${have_cargo} in
> +          yes:rust:no)
> +            # Specifically requested language; tell them.
> +            as_fn_error $? "cargo is required to build $language" "$LINENO" 5
> +            ;;
> +          all:rust:no)
> +            { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cargo is required to build $language" >&5
> +$as_echo "$as_me: WARNING: cargo is required to build $language" >&2;}
> +            add_this_lang=unsupported
> +            ;;
> +          *:rust:no)
> +            # Silently disable.
> +            add_this_lang=unsupported
> +            ;;
> +        esac
> +
> +
>          # Disable a language that is unsupported by the target.
>         case "${add_this_lang}: $unsupported_languages " in
>           no:*) ;;
> diff --git a/configure.ac b/configure.ac
> index 4f34004a072..8c33c89d02c 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -1411,6 +1411,7 @@ fi
>
>  ACX_PROG_GNAT
>  ACX_PROG_GDC
> +ACX_PROG_CARGO
>  ACX_PROG_CMP_IGNORE_INITIAL
>
>  AC_ARG_ENABLE([bootstrap],
> @@ -2305,6 +2306,23 @@ directories, to avoid imposing the performance cost of
>            ;;
>          esac
>
> +        # Disable Rust if cargo is unavailable.
> +        case ${add_this_lang}:${language}:${have_cargo} in
> +          yes:rust:no)
> +            # Specifically requested language; tell them.
> +            AC_MSG_ERROR([cargo is required to build $language])
> +            ;;
> +          all:rust:no)
> +            AC_MSG_WARN([cargo is required to build $language])
> +            add_this_lang=unsupported
> +            ;;
> +          *:rust:no)
> +            # Silently disable.
> +            add_this_lang=unsupported
> +            ;;
> +        esac
> +
> +
>          # Disable a language that is unsupported by the target.
>         case "${add_this_lang}: $unsupported_languages " in
>           no:*) ;;
> --
> 2.43.0
>
John Paul Adrian Glaubitz April 9, 2024, 7:47 a.m. UTC | #2
Hello,

On Mon, 2024-04-08 at 18:33 +0200, pierre-emmanuel.patry@embecosm.com wrote:
> The rust frontend requires cargo to build some of it's components,
> it's presence was not checked during configuration.

Isn't this creating a hen-and-egg problem? How am I supposed to build a Rust
compiler for a target which is not supported by rustc (yet) when gccrs is
supposed to build-depend on cargo which requires rustc?

Adrian
Jakub Jelinek April 9, 2024, 8 a.m. UTC | #3
On Tue, Apr 09, 2024 at 09:47:18AM +0200, John Paul Adrian Glaubitz wrote:
> Hello,
> 
> On Mon, 2024-04-08 at 18:33 +0200, pierre-emmanuel.patry@embecosm.com wrote:
> > The rust frontend requires cargo to build some of it's components,
> > it's presence was not checked during configuration.
> 
> Isn't this creating a hen-and-egg problem? How am I supposed to build a Rust
> compiler for a target which is not supported by rustc (yet) when gccrs is
> supposed to build-depend on cargo which requires rustc?

Cross-compilers?

	Jakub
John Paul Adrian Glaubitz April 9, 2024, 8:29 a.m. UTC | #4
On Tue, 2024-04-09 at 10:00 +0200, Jakub Jelinek wrote:
> On Tue, Apr 09, 2024 at 09:47:18AM +0200, John Paul Adrian Glaubitz wrote:
> > Hello,
> > 
> > On Mon, 2024-04-08 at 18:33 +0200, pierre-emmanuel.patry@embecosm.com wrote:
> > > The rust frontend requires cargo to build some of it's components,
> > > it's presence was not checked during configuration.
> > 
> > Isn't this creating a hen-and-egg problem? How am I supposed to build a Rust
> > compiler for a target which is not supported by rustc (yet) when gccrs is
> > supposed to build-depend on cargo which requires rustc?
> 
> Cross-compilers?

Well, ok. I had there would be a more convenient solution.

I guess we will have to wait for rustc_codegen_gcc to mature then.

Adrian
Iain Sandoe April 9, 2024, 8:55 a.m. UTC | #5
Hi Arthur,

> On 9 Apr 2024, at 11:40, Arthur Cohen <arthur.cohen@embecosm.com> wrote:

> On 4/9/24 09:47, John Paul Adrian Glaubitz wrote:
>> Hello,
>> On Mon, 2024-04-08 at 18:33 +0200, pierre-emmanuel.patry@embecosm.com wrote:
>>> The rust frontend requires cargo to build some of it's components,
>>> it's presence was not checked during configuration.
>> Isn't this creating a hen-and-egg problem? How am I supposed to build a Rust
>> compiler for a target which is not supported by rustc (yet) when gccrs is
>> supposed to build-depend on cargo which requires rustc?
>> Adrian
> 
> Quick reminder in case you haven't seen our Request for Comments on the main ML that this is only a temporary solution. Once gccrs can compile its dependencies, we'll go through a more "classical" bootstrapping chain.


I don’t suppose there’s some way to make a “download prerequisites” action for this?

(I realise that the prerequisite might not be available for a given platform - but then the configure will then just fail to detect them and carry on).

At the least the build documentation requested should (ideally) try to lower the barrier to finding the deps and give reliable sources for them.

> rustc_codegen_gcc can probably already be used for building these dependencies however, if you'd like to have a look at that.

Detailing the verious options would also be a helpful part of the build doc.

thanks
Iain
Iain Sandoe April 9, 2024, 10:09 a.m. UTC | #6
Hi Arthur,

> On 9 Apr 2024, at 13:01, Arthur Cohen <arthur.cohen@embecosm.com> wrote:
> 

> On 4/9/24 10:55, Iain Sandoe wrote:
>> Hi Arthur,
>>> On 9 Apr 2024, at 11:40, Arthur Cohen <arthur.cohen@embecosm.com> wrote:
>>> On 4/9/24 09:47, John Paul Adrian Glaubitz wrote:
>>>> Hello,
>>>> On Mon, 2024-04-08 at 18:33 +0200, pierre-emmanuel.patry@embecosm.com wrote:
>>>>> The rust frontend requires cargo to build some of it's components,
>>>>> it's presence was not checked during configuration.
>>>> Isn't this creating a hen-and-egg problem? How am I supposed to build a Rust
>>>> compiler for a target which is not supported by rustc (yet) when gccrs is
>>>> supposed to build-depend on cargo which requires rustc?
>>>> Adrian
>>> 
>>> Quick reminder in case you haven't seen our Request for Comments on the main ML that this is only a temporary solution. Once gccrs can compile its dependencies, we'll go through a more "classical" bootstrapping chain.
>> I don’t suppose there’s some way to make a “download prerequisites” action for this?
> 
> Do you mean downloading cargo/Rust as a prerequisite? I don't believe this is being done for GNAT/GDC, but I might be wrong.

No, you are quite correct, but the critical difference is that Ada and D both make use of earlier versions of GCC - so that (if one wished to be particular) it is possible to start with an earlier version of GCC and work forwards (in fact that’s what I’ve [I guess all of us] have done for D … and did a looong time ago for Ada).

The difference here is that we need to install an executable from somewhere else - and making that as simple and trustworthy as possible seems like a good move to encourage folks to build & test rust.

> If you mean the dependencies for our Rust components, those are currently being vendored so that we're able to build them offline. I'll push the commits soon.

OK.. I’m sorry to say this - but what’s actually needed is still a little fuzzy to me - but I am happy to wait to read the documentation patch and comment then.

thanks
Iain

> 
>> (I realise that the prerequisite might not be available for a given platform - but then the configure will then just fail to detect them and carry on).
>> At the least the build documentation requested should (ideally) try to lower the barrier to finding the deps and give reliable sources for them.
>>> rustc_codegen_gcc can probably already be used for building these dependencies however, if you'd like to have a look at that.
>> Detailing the verious options would also be a helpful part of the build doc.
>> thanks
>> Iain
> 
> Best,
> 
> Arthur
Arthur Cohen April 9, 2024, 10:40 a.m. UTC | #7
Morning all,

On 4/9/24 09:47, John Paul Adrian Glaubitz wrote:
> Hello,
> 
> On Mon, 2024-04-08 at 18:33 +0200, pierre-emmanuel.patry@embecosm.com wrote:
>> The rust frontend requires cargo to build some of it's components,
>> it's presence was not checked during configuration.
> 
> Isn't this creating a hen-and-egg problem? How am I supposed to build a Rust
> compiler for a target which is not supported by rustc (yet) when gccrs is
> supposed to build-depend on cargo which requires rustc?
> 
> Adrian
> 

Quick reminder in case you haven't seen our Request for Comments on the 
main ML that this is only a temporary solution. Once gccrs can compile 
its dependencies, we'll go through a more "classical" bootstrapping chain.

rustc_codegen_gcc can probably already be used for building these 
dependencies however, if you'd like to have a look at that.

Kindly,

Arthur
Arthur Cohen April 9, 2024, 12:01 p.m. UTC | #8
Hi Iain!

On 4/9/24 10:55, Iain Sandoe wrote:
> Hi Arthur,
> 
>> On 9 Apr 2024, at 11:40, Arthur Cohen <arthur.cohen@embecosm.com> wrote:
> 
>> On 4/9/24 09:47, John Paul Adrian Glaubitz wrote:
>>> Hello,
>>> On Mon, 2024-04-08 at 18:33 +0200, pierre-emmanuel.patry@embecosm.com wrote:
>>>> The rust frontend requires cargo to build some of it's components,
>>>> it's presence was not checked during configuration.
>>> Isn't this creating a hen-and-egg problem? How am I supposed to build a Rust
>>> compiler for a target which is not supported by rustc (yet) when gccrs is
>>> supposed to build-depend on cargo which requires rustc?
>>> Adrian
>>
>> Quick reminder in case you haven't seen our Request for Comments on the main ML that this is only a temporary solution. Once gccrs can compile its dependencies, we'll go through a more "classical" bootstrapping chain.
> 
> 
> I don’t suppose there’s some way to make a “download prerequisites” action for this?

Do you mean downloading cargo/Rust as a prerequisite? I don't believe 
this is being done for GNAT/GDC, but I might be wrong.

If you mean the dependencies for our Rust components, those are 
currently being vendored so that we're able to build them offline. I'll 
push the commits soon.

> 
> (I realise that the prerequisite might not be available for a given platform - but then the configure will then just fail to detect them and carry on).
> 
> At the least the build documentation requested should (ideally) try to lower the barrier to finding the deps and give reliable sources for them.
> 
>> rustc_codegen_gcc can probably already be used for building these dependencies however, if you'd like to have a look at that.
> 
> Detailing the verious options would also be a helpful part of the build doc.
> 
> thanks
> Iain
> 

Best,

Arthur
Arthur Cohen April 9, 2024, 1:53 p.m. UTC | #9
On 4/9/24 12:09, Iain Sandoe wrote:
> Hi Arthur,
> 
>> On 9 Apr 2024, at 13:01, Arthur Cohen <arthur.cohen@embecosm.com> wrote:
>>
> 
>> On 4/9/24 10:55, Iain Sandoe wrote:
>>> Hi Arthur,
>>>> On 9 Apr 2024, at 11:40, Arthur Cohen <arthur.cohen@embecosm.com> wrote:
>>>> On 4/9/24 09:47, John Paul Adrian Glaubitz wrote:
>>>>> Hello,
>>>>> On Mon, 2024-04-08 at 18:33 +0200, pierre-emmanuel.patry@embecosm.com wrote:
>>>>>> The rust frontend requires cargo to build some of it's components,
>>>>>> it's presence was not checked during configuration.
>>>>> Isn't this creating a hen-and-egg problem? How am I supposed to build a Rust
>>>>> compiler for a target which is not supported by rustc (yet) when gccrs is
>>>>> supposed to build-depend on cargo which requires rustc?
>>>>> Adrian
>>>>
>>>> Quick reminder in case you haven't seen our Request for Comments on the main ML that this is only a temporary solution. Once gccrs can compile its dependencies, we'll go through a more "classical" bootstrapping chain.
>>> I don’t suppose there’s some way to make a “download prerequisites” action for this?
>>
>> Do you mean downloading cargo/Rust as a prerequisite? I don't believe this is being done for GNAT/GDC, but I might be wrong.
> 
> No, you are quite correct, but the critical difference is that Ada and D both make use of earlier versions of GCC - so that (if one wished to be particular) it is possible to start with an earlier version of GCC and work forwards (in fact that’s what I’ve [I guess all of us] have done for D … and did a looong time ago for Ada).
> 
> The difference here is that we need to install an executable from somewhere else - and making that as simple and trustworthy as possible seems like a good move to encourage folks to build & test rust.

Ah, that's fair. I guess it will require some modifications to the 
script though, as I would not want to impose Rust on anyone not looking 
to compile gccrs. I'll add this to the list of things to work on before 
14.1 :)

Thanks!

> 
>> If you mean the dependencies for our Rust components, those are currently being vendored so that we're able to build them offline. I'll push the commits soon.
> 
> OK.. I’m sorry to say this - but what’s actually needed is still a little fuzzy to me - but I am happy to wait to read the documentation patch and comment then.
> 
> thanks
> Iain
> 
>>
>>> (I realise that the prerequisite might not be available for a given platform - but then the configure will then just fail to detect them and carry on).
>>> At the least the build documentation requested should (ideally) try to lower the barrier to finding the deps and give reliable sources for them.
>>>> rustc_codegen_gcc can probably already be used for building these dependencies however, if you'd like to have a look at that.
>>> Detailing the verious options would also be a helpful part of the build doc.
>>> thanks
>>> Iain
>>
>> Best,
>>
>> Arthur
>
Andrew Pinski April 9, 2024, 2:12 p.m. UTC | #10
On Mon, Apr 8, 2024 at 9:39 AM <pierre-emmanuel.patry@embecosm.com> wrote:
>
> From: Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
>
> Hello,
>
> The rust frontend requires cargo to build some of it's components,
> it's presence was not checked during configuration.

NOTE cargo itself is a huge security hole. If anything we should place
all of the required dependencies with the specific versions that has
been tested on gcc.gnu.org (with md5 sums) and download that instead
of depending on some random downloads via cargo. Talk about broken
supply chain when things are downloading things randomly off the
internet.

If there is a way to cache and use those specific versions using
cargo, that should be done but I suspect cargo does not work that way.
Also any time someone says this is a temporary measure it is NOT and
we should never treat it as such unless you already have a patch to
remove it.


Thanks,
Andrew Pinski


>
> Best regards,
> Pierre-Emmanuel
>
> ----------
>
> Prevent rust language from building when cargo is
> missing.
>
> config/ChangeLog:
>
>         * acx.m4: Add a macro to check for rust
>         components.
>
> ChangeLog:
>
>         * configure: Regenerate.
>         * configure.ac: Emit an error message when cargo
>         is missing.
>
> Signed-off-by: Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
> ---
>  config/acx.m4 |  11 +++++
>  configure     | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  configure.ac  |  18 ++++++++
>  3 files changed, 146 insertions(+)
>
> diff --git a/config/acx.m4 b/config/acx.m4
> index 7efe98aaf96..3c5fe67342e 100644
> --- a/config/acx.m4
> +++ b/config/acx.m4
> @@ -424,6 +424,17 @@ else
>  fi
>  ])
>
> +# Test for Rust
> +# We require cargo and rustc for some parts of the rust compiler.
> +AC_DEFUN([ACX_PROG_CARGO],
> +[AC_REQUIRE([AC_CHECK_TOOL_PREFIX])
> +AC_CHECK_TOOL(CARGO, cargo, no)
> +if test "x$CARGO" != xno; then
> +  have_cargo=yes
> +else
> +  have_cargo=no
> +fi])
> +
>  # Test for D.
>  AC_DEFUN([ACX_PROG_GDC],
>  [AC_REQUIRE([AC_CHECK_TOOL_PREFIX])
> diff --git a/configure b/configure
> index 874966fb9f0..46e66e20197 100755
> --- a/configure
> +++ b/configure
> @@ -714,6 +714,7 @@ PGO_BUILD_GEN_CFLAGS
>  HAVE_CXX11_FOR_BUILD
>  HAVE_CXX11
>  do_compare
> +CARGO
>  GDC
>  GNATMAKE
>  GNATBIND
> @@ -5786,6 +5787,104 @@ else
>    have_gdc=no
>  fi
>
> +
> +if test -n "$ac_tool_prefix"; then
> +  # Extract the first word of "${ac_tool_prefix}cargo", so it can be a program name with args.
> +set dummy ${ac_tool_prefix}cargo; ac_word=$2
> +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
> +$as_echo_n "checking for $ac_word... " >&6; }
> +if ${ac_cv_prog_CARGO+:} false; then :
> +  $as_echo_n "(cached) " >&6
> +else
> +  if test -n "$CARGO"; then
> +  ac_cv_prog_CARGO="$CARGO" # Let the user override the test.
> +else
> +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
> +for as_dir in $PATH
> +do
> +  IFS=$as_save_IFS
> +  test -z "$as_dir" && as_dir=.
> +    for ac_exec_ext in '' $ac_executable_extensions; do
> +  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
> +    ac_cv_prog_CARGO="${ac_tool_prefix}cargo"
> +    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
> +    break 2
> +  fi
> +done
> +  done
> +IFS=$as_save_IFS
> +
> +fi
> +fi
> +CARGO=$ac_cv_prog_CARGO
> +if test -n "$CARGO"; then
> +  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CARGO" >&5
> +$as_echo "$CARGO" >&6; }
> +else
> +  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
> +$as_echo "no" >&6; }
> +fi
> +
> +
> +fi
> +if test -z "$ac_cv_prog_CARGO"; then
> +  ac_ct_CARGO=$CARGO
> +  # Extract the first word of "cargo", so it can be a program name with args.
> +set dummy cargo; ac_word=$2
> +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
> +$as_echo_n "checking for $ac_word... " >&6; }
> +if ${ac_cv_prog_ac_ct_CARGO+:} false; then :
> +  $as_echo_n "(cached) " >&6
> +else
> +  if test -n "$ac_ct_CARGO"; then
> +  ac_cv_prog_ac_ct_CARGO="$ac_ct_CARGO" # Let the user override the test.
> +else
> +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
> +for as_dir in $PATH
> +do
> +  IFS=$as_save_IFS
> +  test -z "$as_dir" && as_dir=.
> +    for ac_exec_ext in '' $ac_executable_extensions; do
> +  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
> +    ac_cv_prog_ac_ct_CARGO="cargo"
> +    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
> +    break 2
> +  fi
> +done
> +  done
> +IFS=$as_save_IFS
> +
> +fi
> +fi
> +ac_ct_CARGO=$ac_cv_prog_ac_ct_CARGO
> +if test -n "$ac_ct_CARGO"; then
> +  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CARGO" >&5
> +$as_echo "$ac_ct_CARGO" >&6; }
> +else
> +  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
> +$as_echo "no" >&6; }
> +fi
> +
> +  if test "x$ac_ct_CARGO" = x; then
> +    CARGO="no"
> +  else
> +    case $cross_compiling:$ac_tool_warned in
> +yes:)
> +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
> +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
> +ac_tool_warned=yes ;;
> +esac
> +    CARGO=$ac_ct_CARGO
> +  fi
> +else
> +  CARGO="$ac_cv_prog_CARGO"
> +fi
> +
> +if test "x$CARGO" != xno; then
> +  have_cargo=yes
> +else
> +  have_cargo=no
> +fi
>  { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to compare bootstrapped objects" >&5
>  $as_echo_n "checking how to compare bootstrapped objects... " >&6; }
>  if ${gcc_cv_prog_cmp_skip+:} false; then :
> @@ -9099,6 +9198,24 @@ $as_echo "$as_me: WARNING: --enable-host-shared required to build $language" >&2
>            ;;
>          esac
>
> +        # Disable Rust if cargo is unavailable.
> +        case ${add_this_lang}:${language}:${have_cargo} in
> +          yes:rust:no)
> +            # Specifically requested language; tell them.
> +            as_fn_error $? "cargo is required to build $language" "$LINENO" 5
> +            ;;
> +          all:rust:no)
> +            { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cargo is required to build $language" >&5
> +$as_echo "$as_me: WARNING: cargo is required to build $language" >&2;}
> +            add_this_lang=unsupported
> +            ;;
> +          *:rust:no)
> +            # Silently disable.
> +            add_this_lang=unsupported
> +            ;;
> +        esac
> +
> +
>          # Disable a language that is unsupported by the target.
>         case "${add_this_lang}: $unsupported_languages " in
>           no:*) ;;
> diff --git a/configure.ac b/configure.ac
> index 4f34004a072..8c33c89d02c 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -1411,6 +1411,7 @@ fi
>
>  ACX_PROG_GNAT
>  ACX_PROG_GDC
> +ACX_PROG_CARGO
>  ACX_PROG_CMP_IGNORE_INITIAL
>
>  AC_ARG_ENABLE([bootstrap],
> @@ -2305,6 +2306,23 @@ directories, to avoid imposing the performance cost of
>            ;;
>          esac
>
> +        # Disable Rust if cargo is unavailable.
> +        case ${add_this_lang}:${language}:${have_cargo} in
> +          yes:rust:no)
> +            # Specifically requested language; tell them.
> +            AC_MSG_ERROR([cargo is required to build $language])
> +            ;;
> +          all:rust:no)
> +            AC_MSG_WARN([cargo is required to build $language])
> +            add_this_lang=unsupported
> +            ;;
> +          *:rust:no)
> +            # Silently disable.
> +            add_this_lang=unsupported
> +            ;;
> +        esac
> +
> +
>          # Disable a language that is unsupported by the target.
>         case "${add_this_lang}: $unsupported_languages " in
>           no:*) ;;
> --
> 2.43.0
>
Arthur Cohen April 9, 2024, 2:25 p.m. UTC | #11
Hi Andrew,

On 4/9/24 16:12, Andrew Pinski wrote:
> On Mon, Apr 8, 2024 at 9:39 AM <pierre-emmanuel.patry@embecosm.com> wrote:
>>
>> From: Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
>>
>> Hello,
>>
>> The rust frontend requires cargo to build some of it's components,
>> it's presence was not checked during configuration.
> 
> NOTE cargo itself is a huge security hole. If anything we should place
> all of the required dependencies with the specific versions that has
> been tested on gcc.gnu.org (with md5 sums) and download that instead
> of depending on some random downloads via cargo. Talk about broken
> supply chain when things are downloading things randomly off the
> internet.

There is no need to download things randomly off the internet in order 
to work with cargo. We have a commit being reviewed which vendors our 
format parser's two dependencies (libc and unicode functions), and makes 
it so that cargo builds our components with the --offline flag for no 
internet access. This will be upstreamed soon.

This was a simple one line command and it has been tested on containers 
without internet access.

> 
> If there is a way to cache and use those specific versions using
> cargo, that should be done but I suspect cargo does not work that way.

As we talked about yesterday on IRC, cargo does work that way. Sorry if 
I was unclear.

> Also any time someone says this is a temporary measure it is NOT and
> we should never treat it as such unless you already have a patch to
> remove it.

When the time comes we will be more than happy to remove our dependency 
on rustc in order to compiler our dependencies with our own Rust 
front-end. It is one of my objectives, and we're working hard towards 
making that possible :)

Respectfully,

Arthur

> 
> 
> Thanks,
> Andrew Pinski
> 
> 
>>
>> Best regards,
>> Pierre-Emmanuel
>>
>> ----------
>>
>> Prevent rust language from building when cargo is
>> missing.
>>
>> config/ChangeLog:
>>
>>          * acx.m4: Add a macro to check for rust
>>          components.
>>
>> ChangeLog:
>>
>>          * configure: Regenerate.
>>          * configure.ac: Emit an error message when cargo
>>          is missing.
>>
>> Signed-off-by: Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
>> ---
>>   config/acx.m4 |  11 +++++
>>   configure     | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++
>>   configure.ac  |  18 ++++++++
>>   3 files changed, 146 insertions(+)
>>
>> diff --git a/config/acx.m4 b/config/acx.m4
>> index 7efe98aaf96..3c5fe67342e 100644
>> --- a/config/acx.m4
>> +++ b/config/acx.m4
>> @@ -424,6 +424,17 @@ else
>>   fi
>>   ])
>>
>> +# Test for Rust
>> +# We require cargo and rustc for some parts of the rust compiler.
>> +AC_DEFUN([ACX_PROG_CARGO],
>> +[AC_REQUIRE([AC_CHECK_TOOL_PREFIX])
>> +AC_CHECK_TOOL(CARGO, cargo, no)
>> +if test "x$CARGO" != xno; then
>> +  have_cargo=yes
>> +else
>> +  have_cargo=no
>> +fi])
>> +
>>   # Test for D.
>>   AC_DEFUN([ACX_PROG_GDC],
>>   [AC_REQUIRE([AC_CHECK_TOOL_PREFIX])
>> diff --git a/configure b/configure
>> index 874966fb9f0..46e66e20197 100755
>> --- a/configure
>> +++ b/configure
>> @@ -714,6 +714,7 @@ PGO_BUILD_GEN_CFLAGS
>>   HAVE_CXX11_FOR_BUILD
>>   HAVE_CXX11
>>   do_compare
>> +CARGO
>>   GDC
>>   GNATMAKE
>>   GNATBIND
>> @@ -5786,6 +5787,104 @@ else
>>     have_gdc=no
>>   fi
>>
>> +
>> +if test -n "$ac_tool_prefix"; then
>> +  # Extract the first word of "${ac_tool_prefix}cargo", so it can be a program name with args.
>> +set dummy ${ac_tool_prefix}cargo; ac_word=$2
>> +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
>> +$as_echo_n "checking for $ac_word... " >&6; }
>> +if ${ac_cv_prog_CARGO+:} false; then :
>> +  $as_echo_n "(cached) " >&6
>> +else
>> +  if test -n "$CARGO"; then
>> +  ac_cv_prog_CARGO="$CARGO" # Let the user override the test.
>> +else
>> +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
>> +for as_dir in $PATH
>> +do
>> +  IFS=$as_save_IFS
>> +  test -z "$as_dir" && as_dir=.
>> +    for ac_exec_ext in '' $ac_executable_extensions; do
>> +  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
>> +    ac_cv_prog_CARGO="${ac_tool_prefix}cargo"
>> +    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
>> +    break 2
>> +  fi
>> +done
>> +  done
>> +IFS=$as_save_IFS
>> +
>> +fi
>> +fi
>> +CARGO=$ac_cv_prog_CARGO
>> +if test -n "$CARGO"; then
>> +  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CARGO" >&5
>> +$as_echo "$CARGO" >&6; }
>> +else
>> +  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
>> +$as_echo "no" >&6; }
>> +fi
>> +
>> +
>> +fi
>> +if test -z "$ac_cv_prog_CARGO"; then
>> +  ac_ct_CARGO=$CARGO
>> +  # Extract the first word of "cargo", so it can be a program name with args.
>> +set dummy cargo; ac_word=$2
>> +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
>> +$as_echo_n "checking for $ac_word... " >&6; }
>> +if ${ac_cv_prog_ac_ct_CARGO+:} false; then :
>> +  $as_echo_n "(cached) " >&6
>> +else
>> +  if test -n "$ac_ct_CARGO"; then
>> +  ac_cv_prog_ac_ct_CARGO="$ac_ct_CARGO" # Let the user override the test.
>> +else
>> +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
>> +for as_dir in $PATH
>> +do
>> +  IFS=$as_save_IFS
>> +  test -z "$as_dir" && as_dir=.
>> +    for ac_exec_ext in '' $ac_executable_extensions; do
>> +  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
>> +    ac_cv_prog_ac_ct_CARGO="cargo"
>> +    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
>> +    break 2
>> +  fi
>> +done
>> +  done
>> +IFS=$as_save_IFS
>> +
>> +fi
>> +fi
>> +ac_ct_CARGO=$ac_cv_prog_ac_ct_CARGO
>> +if test -n "$ac_ct_CARGO"; then
>> +  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CARGO" >&5
>> +$as_echo "$ac_ct_CARGO" >&6; }
>> +else
>> +  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
>> +$as_echo "no" >&6; }
>> +fi
>> +
>> +  if test "x$ac_ct_CARGO" = x; then
>> +    CARGO="no"
>> +  else
>> +    case $cross_compiling:$ac_tool_warned in
>> +yes:)
>> +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
>> +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
>> +ac_tool_warned=yes ;;
>> +esac
>> +    CARGO=$ac_ct_CARGO
>> +  fi
>> +else
>> +  CARGO="$ac_cv_prog_CARGO"
>> +fi
>> +
>> +if test "x$CARGO" != xno; then
>> +  have_cargo=yes
>> +else
>> +  have_cargo=no
>> +fi
>>   { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to compare bootstrapped objects" >&5
>>   $as_echo_n "checking how to compare bootstrapped objects... " >&6; }
>>   if ${gcc_cv_prog_cmp_skip+:} false; then :
>> @@ -9099,6 +9198,24 @@ $as_echo "$as_me: WARNING: --enable-host-shared required to build $language" >&2
>>             ;;
>>           esac
>>
>> +        # Disable Rust if cargo is unavailable.
>> +        case ${add_this_lang}:${language}:${have_cargo} in
>> +          yes:rust:no)
>> +            # Specifically requested language; tell them.
>> +            as_fn_error $? "cargo is required to build $language" "$LINENO" 5
>> +            ;;
>> +          all:rust:no)
>> +            { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cargo is required to build $language" >&5
>> +$as_echo "$as_me: WARNING: cargo is required to build $language" >&2;}
>> +            add_this_lang=unsupported
>> +            ;;
>> +          *:rust:no)
>> +            # Silently disable.
>> +            add_this_lang=unsupported
>> +            ;;
>> +        esac
>> +
>> +
>>           # Disable a language that is unsupported by the target.
>>          case "${add_this_lang}: $unsupported_languages " in
>>            no:*) ;;
>> diff --git a/configure.ac b/configure.ac
>> index 4f34004a072..8c33c89d02c 100644
>> --- a/configure.ac
>> +++ b/configure.ac
>> @@ -1411,6 +1411,7 @@ fi
>>
>>   ACX_PROG_GNAT
>>   ACX_PROG_GDC
>> +ACX_PROG_CARGO
>>   ACX_PROG_CMP_IGNORE_INITIAL
>>
>>   AC_ARG_ENABLE([bootstrap],
>> @@ -2305,6 +2306,23 @@ directories, to avoid imposing the performance cost of
>>             ;;
>>           esac
>>
>> +        # Disable Rust if cargo is unavailable.
>> +        case ${add_this_lang}:${language}:${have_cargo} in
>> +          yes:rust:no)
>> +            # Specifically requested language; tell them.
>> +            AC_MSG_ERROR([cargo is required to build $language])
>> +            ;;
>> +          all:rust:no)
>> +            AC_MSG_WARN([cargo is required to build $language])
>> +            add_this_lang=unsupported
>> +            ;;
>> +          *:rust:no)
>> +            # Silently disable.
>> +            add_this_lang=unsupported
>> +            ;;
>> +        esac
>> +
>> +
>>           # Disable a language that is unsupported by the target.
>>          case "${add_this_lang}: $unsupported_languages " in
>>            no:*) ;;
>> --
>> 2.43.0
>>
Thomas Schwinge April 15, 2024, 11:14 a.m. UTC | #12
Hi!

On 2024-04-08T18:33:38+0200, pierre-emmanuel.patry@embecosm.com wrote:
> The rust frontend requires cargo to build some of it's components,

In GCC upstream still: 's%requires%is going to require'.  ;-)

> it's presence was not checked during configuration.

After confirming the desired semantics/diagnostics, I've now pushed this
to trunk branch in commit 3e1e73fc99584440e5967577f2049573eeaf4596
"build: Check for cargo when building rust language".


I now wonder: instead of 'AC_CHECK_TOOL', shouldn't this use
'AC_CHECK_PROG'?  (We always want plain 'cargo', not host-prefixed
'aarch64-linux-gnu-cargo' etc., right?)  I'll look into changing this.


Grüße
 Thomas


> Prevent rust language from building when cargo is
> missing.
>
> config/ChangeLog:
>
> 	* acx.m4: Add a macro to check for rust
> 	components.
>
> ChangeLog:
>
> 	* configure: Regenerate.
> 	* configure.ac: Emit an error message when cargo
> 	is missing.
>
> Signed-off-by: Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
> ---
>  config/acx.m4 |  11 +++++
>  configure     | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  configure.ac  |  18 ++++++++
>  3 files changed, 146 insertions(+)
>
> diff --git a/config/acx.m4 b/config/acx.m4
> index 7efe98aaf96..3c5fe67342e 100644
> --- a/config/acx.m4
> +++ b/config/acx.m4
> @@ -424,6 +424,17 @@ else
>  fi
>  ])
>  
> +# Test for Rust
> +# We require cargo and rustc for some parts of the rust compiler.
> +AC_DEFUN([ACX_PROG_CARGO],
> +[AC_REQUIRE([AC_CHECK_TOOL_PREFIX])
> +AC_CHECK_TOOL(CARGO, cargo, no)
> +if test "x$CARGO" != xno; then
> +  have_cargo=yes
> +else
> +  have_cargo=no
> +fi])
> +
>  # Test for D.
>  AC_DEFUN([ACX_PROG_GDC],
>  [AC_REQUIRE([AC_CHECK_TOOL_PREFIX])
> diff --git a/configure b/configure
> index 874966fb9f0..46e66e20197 100755
> --- a/configure
> +++ b/configure
> @@ -714,6 +714,7 @@ PGO_BUILD_GEN_CFLAGS
>  HAVE_CXX11_FOR_BUILD
>  HAVE_CXX11
>  do_compare
> +CARGO
>  GDC
>  GNATMAKE
>  GNATBIND
> @@ -5786,6 +5787,104 @@ else
>    have_gdc=no
>  fi
>  
> +
> +if test -n "$ac_tool_prefix"; then
> +  # Extract the first word of "${ac_tool_prefix}cargo", so it can be a program name with args.
> +set dummy ${ac_tool_prefix}cargo; ac_word=$2
> +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
> +$as_echo_n "checking for $ac_word... " >&6; }
> +if ${ac_cv_prog_CARGO+:} false; then :
> +  $as_echo_n "(cached) " >&6
> +else
> +  if test -n "$CARGO"; then
> +  ac_cv_prog_CARGO="$CARGO" # Let the user override the test.
> +else
> +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
> +for as_dir in $PATH
> +do
> +  IFS=$as_save_IFS
> +  test -z "$as_dir" && as_dir=.
> +    for ac_exec_ext in '' $ac_executable_extensions; do
> +  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
> +    ac_cv_prog_CARGO="${ac_tool_prefix}cargo"
> +    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
> +    break 2
> +  fi
> +done
> +  done
> +IFS=$as_save_IFS
> +
> +fi
> +fi
> +CARGO=$ac_cv_prog_CARGO
> +if test -n "$CARGO"; then
> +  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CARGO" >&5
> +$as_echo "$CARGO" >&6; }
> +else
> +  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
> +$as_echo "no" >&6; }
> +fi
> +
> +
> +fi
> +if test -z "$ac_cv_prog_CARGO"; then
> +  ac_ct_CARGO=$CARGO
> +  # Extract the first word of "cargo", so it can be a program name with args.
> +set dummy cargo; ac_word=$2
> +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
> +$as_echo_n "checking for $ac_word... " >&6; }
> +if ${ac_cv_prog_ac_ct_CARGO+:} false; then :
> +  $as_echo_n "(cached) " >&6
> +else
> +  if test -n "$ac_ct_CARGO"; then
> +  ac_cv_prog_ac_ct_CARGO="$ac_ct_CARGO" # Let the user override the test.
> +else
> +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
> +for as_dir in $PATH
> +do
> +  IFS=$as_save_IFS
> +  test -z "$as_dir" && as_dir=.
> +    for ac_exec_ext in '' $ac_executable_extensions; do
> +  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
> +    ac_cv_prog_ac_ct_CARGO="cargo"
> +    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
> +    break 2
> +  fi
> +done
> +  done
> +IFS=$as_save_IFS
> +
> +fi
> +fi
> +ac_ct_CARGO=$ac_cv_prog_ac_ct_CARGO
> +if test -n "$ac_ct_CARGO"; then
> +  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CARGO" >&5
> +$as_echo "$ac_ct_CARGO" >&6; }
> +else
> +  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
> +$as_echo "no" >&6; }
> +fi
> +
> +  if test "x$ac_ct_CARGO" = x; then
> +    CARGO="no"
> +  else
> +    case $cross_compiling:$ac_tool_warned in
> +yes:)
> +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
> +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
> +ac_tool_warned=yes ;;
> +esac
> +    CARGO=$ac_ct_CARGO
> +  fi
> +else
> +  CARGO="$ac_cv_prog_CARGO"
> +fi
> +
> +if test "x$CARGO" != xno; then
> +  have_cargo=yes
> +else
> +  have_cargo=no
> +fi
>  { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to compare bootstrapped objects" >&5
>  $as_echo_n "checking how to compare bootstrapped objects... " >&6; }
>  if ${gcc_cv_prog_cmp_skip+:} false; then :
> @@ -9099,6 +9198,24 @@ $as_echo "$as_me: WARNING: --enable-host-shared required to build $language" >&2
>            ;;
>          esac
>  
> +        # Disable Rust if cargo is unavailable.
> +        case ${add_this_lang}:${language}:${have_cargo} in
> +          yes:rust:no)
> +            # Specifically requested language; tell them.
> +            as_fn_error $? "cargo is required to build $language" "$LINENO" 5
> +            ;;
> +          all:rust:no)
> +            { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cargo is required to build $language" >&5
> +$as_echo "$as_me: WARNING: cargo is required to build $language" >&2;}
> +            add_this_lang=unsupported
> +            ;;
> +          *:rust:no)
> +            # Silently disable.
> +            add_this_lang=unsupported
> +            ;;
> +        esac
> +
> +
>          # Disable a language that is unsupported by the target.
>  	case "${add_this_lang}: $unsupported_languages " in
>  	  no:*) ;;
> diff --git a/configure.ac b/configure.ac
> index 4f34004a072..8c33c89d02c 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -1411,6 +1411,7 @@ fi
>  
>  ACX_PROG_GNAT
>  ACX_PROG_GDC
> +ACX_PROG_CARGO
>  ACX_PROG_CMP_IGNORE_INITIAL
>  
>  AC_ARG_ENABLE([bootstrap],
> @@ -2305,6 +2306,23 @@ directories, to avoid imposing the performance cost of
>            ;;
>          esac
>  
> +        # Disable Rust if cargo is unavailable.
> +        case ${add_this_lang}:${language}:${have_cargo} in
> +          yes:rust:no)
> +            # Specifically requested language; tell them.
> +            AC_MSG_ERROR([cargo is required to build $language])
> +            ;;
> +          all:rust:no)
> +            AC_MSG_WARN([cargo is required to build $language])
> +            add_this_lang=unsupported
> +            ;;
> +          *:rust:no)
> +            # Silently disable.
> +            add_this_lang=unsupported
> +            ;;
> +        esac
> +
> +
>          # Disable a language that is unsupported by the target.
>  	case "${add_this_lang}: $unsupported_languages " in
>  	  no:*) ;;
> -- 
> 2.43.0
Andrew Pinski April 16, 2024, 8:34 p.m. UTC | #13
On Mon, Apr 8, 2024 at 9:39 AM <pierre-emmanuel.patry@embecosm.com> wrote:
>
> From: Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
>
> Hello,
>
> The rust frontend requires cargo to build some of it's components,
> it's presence was not checked during configuration.

WHY did this go in right before the release of GCC 14?
I don't get why this is considered temporary and it goes in right
before a release.
That seems broken to me.

Thanks,
Andrew

>
> Best regards,
> Pierre-Emmanuel
>
> ----------
>
> Prevent rust language from building when cargo is
> missing.
>
> config/ChangeLog:
>
>         * acx.m4: Add a macro to check for rust
>         components.
>
> ChangeLog:
>
>         * configure: Regenerate.
>         * configure.ac: Emit an error message when cargo
>         is missing.
>
> Signed-off-by: Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
> ---
>  config/acx.m4 |  11 +++++
>  configure     | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  configure.ac  |  18 ++++++++
>  3 files changed, 146 insertions(+)
>
> diff --git a/config/acx.m4 b/config/acx.m4
> index 7efe98aaf96..3c5fe67342e 100644
> --- a/config/acx.m4
> +++ b/config/acx.m4
> @@ -424,6 +424,17 @@ else
>  fi
>  ])
>
> +# Test for Rust
> +# We require cargo and rustc for some parts of the rust compiler.
> +AC_DEFUN([ACX_PROG_CARGO],
> +[AC_REQUIRE([AC_CHECK_TOOL_PREFIX])
> +AC_CHECK_TOOL(CARGO, cargo, no)
> +if test "x$CARGO" != xno; then
> +  have_cargo=yes
> +else
> +  have_cargo=no
> +fi])
> +
>  # Test for D.
>  AC_DEFUN([ACX_PROG_GDC],
>  [AC_REQUIRE([AC_CHECK_TOOL_PREFIX])
> diff --git a/configure b/configure
> index 874966fb9f0..46e66e20197 100755
> --- a/configure
> +++ b/configure
> @@ -714,6 +714,7 @@ PGO_BUILD_GEN_CFLAGS
>  HAVE_CXX11_FOR_BUILD
>  HAVE_CXX11
>  do_compare
> +CARGO
>  GDC
>  GNATMAKE
>  GNATBIND
> @@ -5786,6 +5787,104 @@ else
>    have_gdc=no
>  fi
>
> +
> +if test -n "$ac_tool_prefix"; then
> +  # Extract the first word of "${ac_tool_prefix}cargo", so it can be a program name with args.
> +set dummy ${ac_tool_prefix}cargo; ac_word=$2
> +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
> +$as_echo_n "checking for $ac_word... " >&6; }
> +if ${ac_cv_prog_CARGO+:} false; then :
> +  $as_echo_n "(cached) " >&6
> +else
> +  if test -n "$CARGO"; then
> +  ac_cv_prog_CARGO="$CARGO" # Let the user override the test.
> +else
> +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
> +for as_dir in $PATH
> +do
> +  IFS=$as_save_IFS
> +  test -z "$as_dir" && as_dir=.
> +    for ac_exec_ext in '' $ac_executable_extensions; do
> +  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
> +    ac_cv_prog_CARGO="${ac_tool_prefix}cargo"
> +    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
> +    break 2
> +  fi
> +done
> +  done
> +IFS=$as_save_IFS
> +
> +fi
> +fi
> +CARGO=$ac_cv_prog_CARGO
> +if test -n "$CARGO"; then
> +  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CARGO" >&5
> +$as_echo "$CARGO" >&6; }
> +else
> +  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
> +$as_echo "no" >&6; }
> +fi
> +
> +
> +fi
> +if test -z "$ac_cv_prog_CARGO"; then
> +  ac_ct_CARGO=$CARGO
> +  # Extract the first word of "cargo", so it can be a program name with args.
> +set dummy cargo; ac_word=$2
> +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
> +$as_echo_n "checking for $ac_word... " >&6; }
> +if ${ac_cv_prog_ac_ct_CARGO+:} false; then :
> +  $as_echo_n "(cached) " >&6
> +else
> +  if test -n "$ac_ct_CARGO"; then
> +  ac_cv_prog_ac_ct_CARGO="$ac_ct_CARGO" # Let the user override the test.
> +else
> +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
> +for as_dir in $PATH
> +do
> +  IFS=$as_save_IFS
> +  test -z "$as_dir" && as_dir=.
> +    for ac_exec_ext in '' $ac_executable_extensions; do
> +  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
> +    ac_cv_prog_ac_ct_CARGO="cargo"
> +    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
> +    break 2
> +  fi
> +done
> +  done
> +IFS=$as_save_IFS
> +
> +fi
> +fi
> +ac_ct_CARGO=$ac_cv_prog_ac_ct_CARGO
> +if test -n "$ac_ct_CARGO"; then
> +  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CARGO" >&5
> +$as_echo "$ac_ct_CARGO" >&6; }
> +else
> +  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
> +$as_echo "no" >&6; }
> +fi
> +
> +  if test "x$ac_ct_CARGO" = x; then
> +    CARGO="no"
> +  else
> +    case $cross_compiling:$ac_tool_warned in
> +yes:)
> +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
> +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
> +ac_tool_warned=yes ;;
> +esac
> +    CARGO=$ac_ct_CARGO
> +  fi
> +else
> +  CARGO="$ac_cv_prog_CARGO"
> +fi
> +
> +if test "x$CARGO" != xno; then
> +  have_cargo=yes
> +else
> +  have_cargo=no
> +fi
>  { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to compare bootstrapped objects" >&5
>  $as_echo_n "checking how to compare bootstrapped objects... " >&6; }
>  if ${gcc_cv_prog_cmp_skip+:} false; then :
> @@ -9099,6 +9198,24 @@ $as_echo "$as_me: WARNING: --enable-host-shared required to build $language" >&2
>            ;;
>          esac
>
> +        # Disable Rust if cargo is unavailable.
> +        case ${add_this_lang}:${language}:${have_cargo} in
> +          yes:rust:no)
> +            # Specifically requested language; tell them.
> +            as_fn_error $? "cargo is required to build $language" "$LINENO" 5
> +            ;;
> +          all:rust:no)
> +            { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cargo is required to build $language" >&5
> +$as_echo "$as_me: WARNING: cargo is required to build $language" >&2;}
> +            add_this_lang=unsupported
> +            ;;
> +          *:rust:no)
> +            # Silently disable.
> +            add_this_lang=unsupported
> +            ;;
> +        esac
> +
> +
>          # Disable a language that is unsupported by the target.
>         case "${add_this_lang}: $unsupported_languages " in
>           no:*) ;;
> diff --git a/configure.ac b/configure.ac
> index 4f34004a072..8c33c89d02c 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -1411,6 +1411,7 @@ fi
>
>  ACX_PROG_GNAT
>  ACX_PROG_GDC
> +ACX_PROG_CARGO
>  ACX_PROG_CMP_IGNORE_INITIAL
>
>  AC_ARG_ENABLE([bootstrap],
> @@ -2305,6 +2306,23 @@ directories, to avoid imposing the performance cost of
>            ;;
>          esac
>
> +        # Disable Rust if cargo is unavailable.
> +        case ${add_this_lang}:${language}:${have_cargo} in
> +          yes:rust:no)
> +            # Specifically requested language; tell them.
> +            AC_MSG_ERROR([cargo is required to build $language])
> +            ;;
> +          all:rust:no)
> +            AC_MSG_WARN([cargo is required to build $language])
> +            add_this_lang=unsupported
> +            ;;
> +          *:rust:no)
> +            # Silently disable.
> +            add_this_lang=unsupported
> +            ;;
> +        esac
> +
> +
>          # Disable a language that is unsupported by the target.
>         case "${add_this_lang}: $unsupported_languages " in
>           no:*) ;;
> --
> 2.43.0
>
Rainer Orth April 17, 2024, 8:13 a.m. UTC | #14
Andrew Pinski <pinskia@gmail.com> writes:

> On Mon, Apr 8, 2024 at 9:39 AM <pierre-emmanuel.patry@embecosm.com> wrote:
>>
>> From: Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
>>
>> Hello,
>>
>> The rust frontend requires cargo to build some of it's components,
>> it's presence was not checked during configuration.
>
> WHY did this go in right before the release of GCC 14?
> I don't get why this is considered temporary and it goes in right
> before a release.
> That seems broken to me.

two more questions about this:

Right now, the new cargo configure test disable rust on all of my
targets (Solaris, Linux, Darwin) which didn't have it installed.  Before
(as recent as last Friday), I could successfully build and test
crab1/rust on all of them without cargo in sight.  So I wonder if the
patch isn't premature.

Besides, while there are packaged versions of cargo for Solaris 11.4 and
Linux, Darwin hasn't anything (not checked Homebrew or similar yet).
What's worse, rustup only supports macOS 10.12 and up, while I'm still
regularly testing 10.7 and 10.11.  I don't really feel like building
rust from source here (if it works at all).  This hasn't been an issue
for any other languages that require additional tools for bootstrapping
(like Ada or D): there are versions of GNAT around that still support
those old Darwin releases, and I could use the C++ version of GDC in GCC
11.

At the very least, the Rust situation needs to be documented clearly.

	Rainer
Arthur Cohen April 17, 2024, 2:54 p.m. UTC | #15
Hi Rainer!

On 4/17/24 10:13, Rainer Orth wrote:
> Andrew Pinski <pinskia@gmail.com> writes:
> 
>> On Mon, Apr 8, 2024 at 9:39 AM <pierre-emmanuel.patry@embecosm.com> wrote:
>>>
>>> From: Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
>>>
>>> Hello,
>>>
>>> The rust frontend requires cargo to build some of it's components,
>>> it's presence was not checked during configuration.
>>
>> WHY did this go in right before the release of GCC 14?
>> I don't get why this is considered temporary and it goes in right
>> before a release.
>> That seems broken to me.
> 
> two more questions about this:
> 
> Right now, the new cargo configure test disable rust on all of my
> targets (Solaris, Linux, Darwin) which didn't have it installed.  Before
> (as recent as last Friday), I could successfully build and test
> crab1/rust on all of them without cargo in sight.  So I wonder if the
> patch isn't premature.

We already have components depending on Rust libraries in our 
development repository, so this patch is important to ensure errors are 
emitted early during the configure phase rather than later at build 
time. I don't think this is premature, considering that your targets 
would fail to build the Rust frontend next time we upstream commits, 
which should happen this week or early next week.

> Besides, while there are packaged versions of cargo for Solaris 11.4 and
> Linux, Darwin hasn't anything (not checked Homebrew or similar yet).
> What's worse, rustup only supports macOS 10.12 and up, while I'm still
> regularly testing 10.7 and 10.11.  I don't really feel like building
> rust from source here (if it works at all).  This hasn't been an issue
> for any other languages that require additional tools for bootstrapping
> (like Ada or D): there are versions of GNAT around that still support
> those old Darwin releases, and I could use the C++ version of GDC in GCC
> 11.

Sorry, I'm not too familiar with the Rust situation on macOS. I am 
reading that starting from Rust version 1.74, the minimum macOS version 
required is indeed 10.12, released in 2016 I believe?

We currently depend on Rust version 1.72, so you should be able to 
install it on macOS 10.11. Maybe with rustup? You can try something like 
the following:

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y 
--default-toolchain=1.72.0;

which is the default installation method for Rustup, with version 1.72 
of the language specified. I'm not able to test this, sorry, but I'm 
very interested in knowing if it works. I think you can also install 
Rust using Homebrew, but again I am not able to test this and apologize.

The goal is to reduce that Rust version further soon anyway - we are 
going to target Rust version 1.49, released 3 years ago, as that is the 
version that gccrs aims to compile. This will bring us closer to 
compiling our dependencies with our own frontend.

> At the very least, the Rust situation needs to be documented clearly.

I'd love to work on this - what sort of documentation do you have in 
mind? Do you mean something like the online GCC documentation or an 
in-tree file? Let me know what you'd like me to add and I'll be happy to 
do so.

> 
> 	Rainer
> 

Kindly,

Arthur
Rainer Orth April 23, 2024, 8:52 a.m. UTC | #16
Hi Arthur,

> On 4/17/24 10:13, Rainer Orth wrote:
>> Andrew Pinski <pinskia@gmail.com> writes:
>> 
>>> On Mon, Apr 8, 2024 at 9:39 AM <pierre-emmanuel.patry@embecosm.com> wrote:
>>>>
>>>> From: Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
>>>>
>>>> Hello,
>>>>
>>>> The rust frontend requires cargo to build some of it's components,
>>>> it's presence was not checked during configuration.
>>>
>>> WHY did this go in right before the release of GCC 14?
>>> I don't get why this is considered temporary and it goes in right
>>> before a release.
>>> That seems broken to me.
>> two more questions about this:
>> Right now, the new cargo configure test disable rust on all of my
>> targets (Solaris, Linux, Darwin) which didn't have it installed.  Before
>> (as recent as last Friday), I could successfully build and test
>> crab1/rust on all of them without cargo in sight.  So I wonder if the
>> patch isn't premature.
>
> We already have components depending on Rust libraries in our development
> repository, so this patch is important to ensure errors are emitted early
> during the configure phase rather than later at build time. I don't think
> this is premature, considering that your targets would fail to build the
> Rust frontend next time we upstream commits, which should happen this week
> or early next week.

it would have been very helpful to state this up front: introducing a
dependency that's never used outside of a configure test right night is
still damn confusing.  An alternative might have been to commit this
patch shortly before it's actually used.

>> Besides, while there are packaged versions of cargo for Solaris 11.4 and
>> Linux, Darwin hasn't anything (not checked Homebrew or similar yet).
>> What's worse, rustup only supports macOS 10.12 and up, while I'm still
>> regularly testing 10.7 and 10.11.  I don't really feel like building
>> rust from source here (if it works at all).  This hasn't been an issue
>> for any other languages that require additional tools for bootstrapping
>> (like Ada or D): there are versions of GNAT around that still support
>> those old Darwin releases, and I could use the C++ version of GDC in GCC
>> 11.
>
> Sorry, I'm not too familiar with the Rust situation on macOS. I am reading
> that starting from Rust version 1.74, the minimum macOS version required is
> indeed 10.12, released in 2016 I believe?
>
> We currently depend on Rust version 1.72, so you should be able to install
> it on macOS 10.11. Maybe with rustup? You can try something like the
> following:
>
> curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
> --default-toolchain=1.72.0;

I tried this with mixed success: while the part of the installation that
goes into $RUSTUP_HOME at least can run cargo --version on both 10.7
and 10.11, the other one (for $CARGO_HOME) dies with SIGILL on 10.7
trying the same.

However, when I ignore most of what's installed by rustup and point
$PATH at .../toolchains/1.72.0-x86_64-apple-darwin/bin, I can run the
cargo in there with --version even on 10.7.  For the moment, that's good
enough to get a trunk build/test with rust including working again, but
of course this doesn't prove that this will remain so once cargo is
actually used.

> which is the default installation method for Rustup, with version 1.72 of
> the language specified. I'm not able to test this, sorry, but I'm very
> interested in knowing if it works. I think you can also install Rust using
> Homebrew, but again I am not able to test this and apologize.

I'll go down this route (or try installing rust from source) only if
need be.

> The goal is to reduce that Rust version further soon anyway - we are going
> to target Rust version 1.49, released 3 years ago, as that is the version
> that gccrs aims to compile. This will bring us closer to compiling our
> dependencies with our own frontend.

Good.  At least knowing this it's easier to check what macOS versions
are supported by e.g. 1.49.

>> At the very least, the Rust situation needs to be documented clearly.
>
> I'd love to work on this - what sort of documentation do you have in mind?
> Do you mean something like the online GCC documentation or an in-tree file?
> Let me know what you'd like me to add and I'll be happy to do so.

I think this should go into gcc/doc/install.texi, as for all other
languages and targets.  This way you have all the necessary information
in one place, while some in-tree file is almost guaranteed to be
overlooked.

	Rainer
diff mbox series

Patch

diff --git a/config/acx.m4 b/config/acx.m4
index 7efe98aaf96..3c5fe67342e 100644
--- a/config/acx.m4
+++ b/config/acx.m4
@@ -424,6 +424,17 @@  else
 fi
 ])
 
+# Test for Rust
+# We require cargo and rustc for some parts of the rust compiler.
+AC_DEFUN([ACX_PROG_CARGO],
+[AC_REQUIRE([AC_CHECK_TOOL_PREFIX])
+AC_CHECK_TOOL(CARGO, cargo, no)
+if test "x$CARGO" != xno; then
+  have_cargo=yes
+else
+  have_cargo=no
+fi])
+
 # Test for D.
 AC_DEFUN([ACX_PROG_GDC],
 [AC_REQUIRE([AC_CHECK_TOOL_PREFIX])
diff --git a/configure b/configure
index 874966fb9f0..46e66e20197 100755
--- a/configure
+++ b/configure
@@ -714,6 +714,7 @@  PGO_BUILD_GEN_CFLAGS
 HAVE_CXX11_FOR_BUILD
 HAVE_CXX11
 do_compare
+CARGO
 GDC
 GNATMAKE
 GNATBIND
@@ -5786,6 +5787,104 @@  else
   have_gdc=no
 fi
 
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}cargo", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cargo; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CARGO+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CARGO"; then
+  ac_cv_prog_CARGO="$CARGO" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CARGO="${ac_tool_prefix}cargo"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CARGO=$ac_cv_prog_CARGO
+if test -n "$CARGO"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CARGO" >&5
+$as_echo "$CARGO" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CARGO"; then
+  ac_ct_CARGO=$CARGO
+  # Extract the first word of "cargo", so it can be a program name with args.
+set dummy cargo; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CARGO+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CARGO"; then
+  ac_cv_prog_ac_ct_CARGO="$ac_ct_CARGO" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CARGO="cargo"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CARGO=$ac_cv_prog_ac_ct_CARGO
+if test -n "$ac_ct_CARGO"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CARGO" >&5
+$as_echo "$ac_ct_CARGO" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_CARGO" = x; then
+    CARGO="no"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CARGO=$ac_ct_CARGO
+  fi
+else
+  CARGO="$ac_cv_prog_CARGO"
+fi
+
+if test "x$CARGO" != xno; then
+  have_cargo=yes
+else
+  have_cargo=no
+fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to compare bootstrapped objects" >&5
 $as_echo_n "checking how to compare bootstrapped objects... " >&6; }
 if ${gcc_cv_prog_cmp_skip+:} false; then :
@@ -9099,6 +9198,24 @@  $as_echo "$as_me: WARNING: --enable-host-shared required to build $language" >&2
           ;;
         esac
 
+        # Disable Rust if cargo is unavailable.
+        case ${add_this_lang}:${language}:${have_cargo} in
+          yes:rust:no)
+            # Specifically requested language; tell them.
+            as_fn_error $? "cargo is required to build $language" "$LINENO" 5
+            ;;
+          all:rust:no)
+            { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cargo is required to build $language" >&5
+$as_echo "$as_me: WARNING: cargo is required to build $language" >&2;}
+            add_this_lang=unsupported
+            ;;
+          *:rust:no)
+            # Silently disable.
+            add_this_lang=unsupported
+            ;;
+        esac
+
+
         # Disable a language that is unsupported by the target.
 	case "${add_this_lang}: $unsupported_languages " in
 	  no:*) ;;
diff --git a/configure.ac b/configure.ac
index 4f34004a072..8c33c89d02c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1411,6 +1411,7 @@  fi
 
 ACX_PROG_GNAT
 ACX_PROG_GDC
+ACX_PROG_CARGO
 ACX_PROG_CMP_IGNORE_INITIAL
 
 AC_ARG_ENABLE([bootstrap],
@@ -2305,6 +2306,23 @@  directories, to avoid imposing the performance cost of
           ;;
         esac
 
+        # Disable Rust if cargo is unavailable.
+        case ${add_this_lang}:${language}:${have_cargo} in
+          yes:rust:no)
+            # Specifically requested language; tell them.
+            AC_MSG_ERROR([cargo is required to build $language])
+            ;;
+          all:rust:no)
+            AC_MSG_WARN([cargo is required to build $language])
+            add_this_lang=unsupported
+            ;;
+          *:rust:no)
+            # Silently disable.
+            add_this_lang=unsupported
+            ;;
+        esac
+
+
         # Disable a language that is unsupported by the target.
 	case "${add_this_lang}: $unsupported_languages " in
 	  no:*) ;;