diff mbox series

[langdale,master] rust: Do not use default compiler flags defined in CC crate

Message ID 20221118144253.1156045-1-Anton.Antonov@arm.com
State New
Headers show
Series [langdale,master] rust: Do not use default compiler flags defined in CC crate | expand

Commit Message

Anton Antonov Nov. 18, 2022, 2:42 p.m. UTC
Rust crates build dependecy C libraries using "CC" crate.
This crate adds some default compiler parameters depending on target arch.
For some target archs these parameters conflict with the parameters defined by OE.

Warnings/errors like this can be seen in the case:

cc1: error: switch '-mcpu=cortex-a15' conflicts with switch '-march=armv7-a+fp' [-Werror]

Lets use the OE parameters only by exporting CRATE_CC_NO_DEFAULTS.
https://github.com/rust-lang/cc-rs#external-configuration-via-environment-variables

This patch fixes https://bugzilla.yoctoproject.org/show_bug.cgi?id=14947

Signed-off-by: Anton Antonov <Anton.Antonov@arm.com>
---
 meta/classes-recipe/rust-target-config.bbclass | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

Comments

Richard Purdie Nov. 18, 2022, 3:10 p.m. UTC | #1
On Fri, 2022-11-18 at 14:42 +0000, Anton Antonov wrote:
> Rust crates build dependecy C libraries using "CC" crate.
> This crate adds some default compiler parameters depending on target arch.
> For some target archs these parameters conflict with the parameters defined by OE.
> 
> Warnings/errors like this can be seen in the case:
> 
> cc1: error: switch '-mcpu=cortex-a15' conflicts with switch '-march=armv7-a+fp' [-Werror]
> 
> Lets use the OE parameters only by exporting CRATE_CC_NO_DEFAULTS.
> https://github.com/rust-lang/cc-rs#external-configuration-via-environment-variables
> 
> This patch fixes https://bugzilla.yoctoproject.org/show_bug.cgi?id=14947
> 
> Signed-off-by: Anton Antonov <Anton.Antonov@arm.com>
> ---
>  meta/classes-recipe/rust-target-config.bbclass | 18 ++++++++++++++++++
>  1 file changed, 18 insertions(+)
> 
> diff --git a/meta/classes-recipe/rust-target-config.bbclass b/meta/classes-recipe/rust-target-config.bbclass
> index 2710b4325d..4135335043 100644
> --- a/meta/classes-recipe/rust-target-config.bbclass
> +++ b/meta/classes-recipe/rust-target-config.bbclass
> @@ -401,3 +401,21 @@ python do_rust_gen_targets () {
>  addtask rust_gen_targets after do_patch before do_compile
>  do_rust_gen_targets[dirs] += "${RUST_TARGETS_DIR}"
>  
> +# For building C dependecies only use compiler parameters defined in OE-core
> +# and ignore the default parameters defined in the CC crate.
> +# https://github.com/rust-lang/cc-rs#external-configuration-via-environment-variables
> +# For rust native recipes we still rely on the CC crate parameters.
> +
> +CRATE_CC_NO_DEFAULTS:class-target ?= "true"
> +CRATE_CC_NO_DEFAULTS:class-nativesdk ?= "true"
> +CRATE_CC_NO_DEFAULTS:class-native ?= ""
> +
> +# The CC crate checks for CRATE_CC_NO_DEFAULTS existence not value.
> +# Even empty CRATE_CC_NO_DEFAULTS will be taken into account.
> +# So, don't export it if empty.
> +do_compile:prepend() {
> +    if [ -n "${CRATE_CC_NO_DEFAULTS}" ]; then
> +        export CRATE_CC_NO_DEFAULTS="${CRATE_CC_NO_DEFAULTS}"
> +        bbnote "CRATE_CC_NO_DEFAULTS is exported"
> +    fi
> +}

That looks like a good start. I wondered if this might work as a
slightly cleaner solution?:

CRATE_CC_NO_DEFAULTS = "true"
CRATE_CC_NO_DEFAULTS:class-native = ""
CRATE_CC_NO_DEFAULTS[export] = "${'1' if d.getVar('CRATE_CC_NO_DEFAULTS') == 'true' else '0'}"

Cheers,

Richard
Anton Antonov Nov. 18, 2022, 3:27 p.m. UTC | #2
Hi Richard,

Thank you for the suggestion. I was wondering how I can conditionally export a variable without updating a task. I will test and submit a new patch

Anton
Anton Antonov Nov. 18, 2022, 4:21 p.m. UTC | #3
Hi Richard,

  I’ve tested your approach. It doesn’t work for whatever reason. CRATE_CC_NO_DEFAULTS is empty exported for native recipes:

$ MACHINE=qemuarm bitbake rust-native -e |grep CRATE_CC_NO_DEFAULTS
# $CRATE_CC_NO_DEFAULTS [3 operations]
#     [export] "${'1' if d.getVar('CRATE_CC_NO_DEFAULTS') == 'true' else '0'}"
export CRATE_CC_NO_DEFAULTS=""
# $CRATE_CC_NO_DEFAULTS:class-native
CRATE_CC_NO_DEFAULTS:class-native=""


  I also tried:
CRATE_CC_NO_DEFAULTS[export] = "${@oe.utils.conditional('CRATE_CC_NO_DEFAULTS', '', '0', '1', d)}"
with the same result – empty export.

Cheers,
Anton

From: Richard Purdie <richard.purdie@linuxfoundation.org>
Date: Friday, 18 November 2022 at 15:10
To: Anton Antonov <Anton.Antonov@arm.com>, openembedded-core@lists.openembedded.org <openembedded-core@lists.openembedded.org>
Subject: Re: [OE-core] [langdale][master][PATCH] rust: Do not use default compiler flags defined in CC crate
On Fri, 2022-11-18 at 14:42 +0000, Anton Antonov wrote:
> Rust crates build dependecy C libraries using "CC" crate.
> This crate adds some default compiler parameters depending on target arch.
> For some target archs these parameters conflict with the parameters defined by OE.
>
> Warnings/errors like this can be seen in the case:
>
> cc1: error: switch '-mcpu=cortex-a15' conflicts with switch '-march=armv7-a+fp' [-Werror]
>
> Lets use the OE parameters only by exporting CRATE_CC_NO_DEFAULTS.
> https://github.com/rust-lang/cc-rs#external-configuration-via-environment-variables
>
> This patch fixes https://bugzilla.yoctoproject.org/show_bug.cgi?id=14947
>
> Signed-off-by: Anton Antonov <Anton.Antonov@arm.com>
> ---
>  meta/classes-recipe/rust-target-config.bbclass | 18 ++++++++++++++++++
>  1 file changed, 18 insertions(+)
>
> diff --git a/meta/classes-recipe/rust-target-config.bbclass b/meta/classes-recipe/rust-target-config.bbclass
> index 2710b4325d..4135335043 100644
> --- a/meta/classes-recipe/rust-target-config.bbclass
> +++ b/meta/classes-recipe/rust-target-config.bbclass
> @@ -401,3 +401,21 @@ python do_rust_gen_targets () {
>  addtask rust_gen_targets after do_patch before do_compile
>  do_rust_gen_targets[dirs] += "${RUST_TARGETS_DIR}"
>
> +# For building C dependecies only use compiler parameters defined in OE-core
> +# and ignore the default parameters defined in the CC crate.
> +# https://github.com/rust-lang/cc-rs#external-configuration-via-environment-variables
> +# For rust native recipes we still rely on the CC crate parameters.
> +
> +CRATE_CC_NO_DEFAULTS:class-target ?= "true"
> +CRATE_CC_NO_DEFAULTS:class-nativesdk ?= "true"
> +CRATE_CC_NO_DEFAULTS:class-native ?= ""
> +
> +# The CC crate checks for CRATE_CC_NO_DEFAULTS existence not value.
> +# Even empty CRATE_CC_NO_DEFAULTS will be taken into account.
> +# So, don't export it if empty.
> +do_compile:prepend() {
> +    if [ -n "${CRATE_CC_NO_DEFAULTS}" ]; then
> +        export CRATE_CC_NO_DEFAULTS="${CRATE_CC_NO_DEFAULTS}"
> +        bbnote "CRATE_CC_NO_DEFAULTS is exported"
> +    fi
> +}

That looks like a good start. I wondered if this might work as a
slightly cleaner solution?:

CRATE_CC_NO_DEFAULTS = "true"
CRATE_CC_NO_DEFAULTS:class-native = ""
CRATE_CC_NO_DEFAULTS[export] = "${'1' if d.getVar('CRATE_CC_NO_DEFAULTS') == 'true' else '0'}"

Cheers,

Richard
Richard Purdie Nov. 18, 2022, 4:35 p.m. UTC | #4
On Fri, 2022-11-18 at 16:21 +0000, Anton Antonov wrote:
>   I’ve tested your approach. It doesn’t work for whatever reason.
> CRATE_CC_NO_DEFAULTS is empty exported for native recipes:
> 
> $ MACHINE=qemuarm bitbake rust-native -e |grep CRATE_CC_NO_DEFAULTS
> # $CRATE_CC_NO_DEFAULTS [3 operations]
> #     [export] "${'1' if d.getVar('CRATE_CC_NO_DEFAULTS') == 'true'
> else '0'}"
> export CRATE_CC_NO_DEFAULTS=""
> # $CRATE_CC_NO_DEFAULTS:class-native
> CRATE_CC_NO_DEFAULTS:class-native=""
> 
> 
>   I also tried:
> CRATE_CC_NO_DEFAULTS[export] =
> "${@oe.utils.conditional('CRATE_CC_NO_DEFAULTS', '', '0', '1', d)}"
> with the same result – empty export.

I think it might need to be 0 or "" instead of '0'. It would be nice if
we could make False work too but I worry that might not.

Cheers,

Richard
Anton Antonov Nov. 18, 2022, 5:15 p.m. UTC | #5
Hi Richard,

  I’ve already unsuccessfully tried all these combinations with both “if” and oe.utils.conditional.

$ MACHINE=qemuarm bitbake rust-native -e |grep CRATE_CC_NO_DEFAULTS
# $CRATE_CC_NO_DEFAULTS [3 operations]
#     [export] "${@1 if d.getVar('CRATE_CC_NO_DEFAULTS') == 'true' else 0}"
export CRATE_CC_NO_DEFAULTS=""
# $CRATE_CC_NO_DEFAULTS:class-native
CRATE_CC_NO_DEFAULTS:class-native=""

$ MACHINE=qemuarm bitbake rust-native -e |grep CRATE_CC_NO_DEFAULTS
# $CRATE_CC_NO_DEFAULTS [3 operations]
#     [export] "${@'1' if d.getVar('CRATE_CC_NO_DEFAULTS') == 'true' else ''}"
export CRATE_CC_NO_DEFAULTS=""
# $CRATE_CC_NO_DEFAULTS:class-native
CRATE_CC_NO_DEFAULTS:class-native=""

Looking at this “0” should work
https://git.yoctoproject.org/poky/tree/meta/classes-recipe/go.bbclass#n30

But, even if I add
CRATE_CC_NO_DEFAULTS[export] = "0"
for testing, I still see:

$ MACHINE=qemuarm bitbake rust-native -e |grep CRATE_CC_NO_DEFAULTS
# $CRATE_CC_NO_DEFAULTS [3 operations]
export CRATE_CC_NO_DEFAULTS=""
# $CRATE_CC_NO_DEFAULTS:class-native
CRATE_CC_NO_DEFAULTS:class-native=""

Cheers,
Anton

From: Richard Purdie <richard.purdie@linuxfoundation.org>
Date: Friday, 18 November 2022 at 16:35
To: Anton Antonov <Anton.Antonov@arm.com>, openembedded-core@lists.openembedded.org <openembedded-core@lists.openembedded.org>
Subject: Re: [OE-core] [langdale][master][PATCH] rust: Do not use default compiler flags defined in CC crate
On Fri, 2022-11-18 at 16:21 +0000, Anton Antonov wrote:
>   I’ve tested your approach. It doesn’t work for whatever reason.
> CRATE_CC_NO_DEFAULTS is empty exported for native recipes:
>
> $ MACHINE=qemuarm bitbake rust-native -e |grep CRATE_CC_NO_DEFAULTS
> # $CRATE_CC_NO_DEFAULTS [3 operations]
> #     [export] "${'1' if d.getVar('CRATE_CC_NO_DEFAULTS') == 'true'
> else '0'}"
> export CRATE_CC_NO_DEFAULTS=""
> # $CRATE_CC_NO_DEFAULTS:class-native
> CRATE_CC_NO_DEFAULTS:class-native=""
>
>
>   I also tried:
> CRATE_CC_NO_DEFAULTS[export] =
> "${@oe.utils.conditional('CRATE_CC_NO_DEFAULTS', '', '0', '1', d)}"
> with the same result – empty export.

I think it might need to be 0 or "" instead of '0'. It would be nice if
we could make False work too but I worry that might not.

Cheers,

Richard
Peter Kjellerstedt Nov. 19, 2022, 1:57 a.m. UTC | #6
> -----Original Message-----
> From: openembedded-core@lists.openembedded.org <openembedded-core@lists.openembedded.org> On Behalf Of Richard Purdie
> Sent: den 18 november 2022 17:36
> To: Anton Antonov <Anton.Antonov@arm.com>; openembedded-core@lists.openembedded.org
> Subject: Re: [OE-core] [langdale][master][PATCH] rust: Do not use default compiler flags defined in CC crate
> 
> On Fri, 2022-11-18 at 16:21 +0000, Anton Antonov wrote:
> >   I’ve tested your approach. It doesn’t work for whatever reason.
> > CRATE_CC_NO_DEFAULTS is empty exported for native recipes:
> >
> > $ MACHINE=qemuarm bitbake rust-native -e |grep CRATE_CC_NO_DEFAULTS
> > # $CRATE_CC_NO_DEFAULTS [3 operations]
> > #     [export] "${'1' if d.getVar('CRATE_CC_NO_DEFAULTS') == 'true' else '0'}"
> > export CRATE_CC_NO_DEFAULTS=""
> > # $CRATE_CC_NO_DEFAULTS:class-native
> > CRATE_CC_NO_DEFAULTS:class-native=""
> >
> >
> >   I also tried:
> > CRATE_CC_NO_DEFAULTS[export] = "${@oe.utils.conditional('CRATE_CC_NO_DEFAULTS', '', '0', '1', d)}"
> > with the same result – empty export.
> 
> I think it might need to be 0 or "" instead of '0'. It would be nice if
> we could make False work too but I worry that might not.
> 
> Cheers,
> 
> Richard

None of this will work unless you change the code in bitbake/lib/bb/data.py 
to use d.getVarFlag(var, "export") instead of d.getVarFlag(var, "export", False).
However, I assume that is not wanted given that support for foo[unexport] = "1" 
was introduced to counteract a foo[export] = "1".

//Peter
Richard Purdie Nov. 20, 2022, 11:45 a.m. UTC | #7
On Sat, 2022-11-19 at 01:57 +0000, Peter Kjellerstedt wrote:
> > -----Original Message-----
> > From: openembedded-core@lists.openembedded.org
> > <openembedded-core@lists.openembedded.org> On Behalf Of Richard
> > Purdie
> > Sent: den 18 november 2022 17:36
> > To: Anton Antonov <Anton.Antonov@arm.com>;
> > openembedded-core@lists.openembedded.org
> > Subject: Re: [OE-core] [langdale][master][PATCH] rust: Do not use
> > default compiler flags defined in CC crate
> > 
> > On Fri, 2022-11-18 at 16:21 +0000, Anton Antonov wrote:
> > >   I’ve tested your approach. It doesn’t work for whatever reason.
> > > CRATE_CC_NO_DEFAULTS is empty exported for native recipes:
> > > 
> > > $ MACHINE=qemuarm bitbake rust-native -e |grep
> > > CRATE_CC_NO_DEFAULTS
> > > # $CRATE_CC_NO_DEFAULTS [3 operations]
> > > #     [export] "${'1' if d.getVar('CRATE_CC_NO_DEFAULTS') ==
> > > 'true' else '0'}"
> > > export CRATE_CC_NO_DEFAULTS=""
> > > # $CRATE_CC_NO_DEFAULTS:class-native
> > > CRATE_CC_NO_DEFAULTS:class-native=""
> > > 
> > > 
> > >   I also tried:
> > > CRATE_CC_NO_DEFAULTS[export] =
> > > "${@oe.utils.conditional('CRATE_CC_NO_DEFAULTS', '', '0', '1',
> > > d)}"
> > > with the same result – empty export.
> > 
> > I think it might need to be 0 or "" instead of '0'. It would be
> > nice if
> > we could make False work too but I worry that might not.
> > 
> > Cheers,
> > 
> > Richard
> 
> None of this will work unless you change the code in
> bitbake/lib/bb/data.py 
> to use d.getVarFlag(var, "export") instead of d.getVarFlag(var,
> "export", False).
> However, I assume that is not wanted given that support for
> foo[unexport] = "1" 
> was introduced to counteract a foo[export] = "1".

Good point, which reminds me why the code does this. Expanding the
value for all export variables would have a significant effect on some
performance sensitive code :(.

From memory I think there was a bit more to unexport than that. Looking
at the history:

https://git.yoctoproject.org/poky/commit/?id=0da3c82a66e02bf2d3780e23427d476766a0bcfc

I think it wasn't enough just to not export some things, we wanted to
actually unset them in the shell environment.

We may have later done more environment cleaning which made this
unnecessary, less sure about that. I did remove a lot of the unexports
(e.g. MACHINE and DISTRO) but SHELL[unexport] = "1" remains.

Cheers,

Richard
Anton Antonov Nov. 21, 2022, 9:39 a.m. UTC | #8
Hi Richard,

   Are you happy to accept my initial patch as it?

Cheers,
Anton

From: Richard Purdie <richard.purdie@linuxfoundation.org>
Date: Sunday, 20 November 2022 at 11:45
To: Peter Kjellerstedt <peter.kjellerstedt@axis.com>, Anton Antonov <Anton.Antonov@arm.com>, openembedded-core@lists.openembedded.org <openembedded-core@lists.openembedded.org>
Subject: Re: [OE-core] [langdale][master][PATCH] rust: Do not use default compiler flags defined in CC crate
On Sat, 2022-11-19 at 01:57 +0000, Peter Kjellerstedt wrote:
> > -----Original Message-----
> > From: openembedded-core@lists.openembedded.org
> > <openembedded-core@lists.openembedded.org> On Behalf Of Richard
> > Purdie
> > Sent: den 18 november 2022 17:36
> > To: Anton Antonov <Anton.Antonov@arm.com>;
> > openembedded-core@lists.openembedded.org
> > Subject: Re: [OE-core] [langdale][master][PATCH] rust: Do not use
> > default compiler flags defined in CC crate
> >
> > On Fri, 2022-11-18 at 16:21 +0000, Anton Antonov wrote:
> > >   I’ve tested your approach. It doesn’t work for whatever reason.
> > > CRATE_CC_NO_DEFAULTS is empty exported for native recipes:
> > >
> > > $ MACHINE=qemuarm bitbake rust-native -e |grep
> > > CRATE_CC_NO_DEFAULTS
> > > # $CRATE_CC_NO_DEFAULTS [3 operations]
> > > #     [export] "${'1' if d.getVar('CRATE_CC_NO_DEFAULTS') ==
> > > 'true' else '0'}"
> > > export CRATE_CC_NO_DEFAULTS=""
> > > # $CRATE_CC_NO_DEFAULTS:class-native
> > > CRATE_CC_NO_DEFAULTS:class-native=""
> > >
> > >
> > >   I also tried:
> > > CRATE_CC_NO_DEFAULTS[export] =
> > > "${@oe.utils.conditional('CRATE_CC_NO_DEFAULTS', '', '0', '1',
> > > d)}"
> > > with the same result – empty export.
> >
> > I think it might need to be 0 or "" instead of '0'. It would be
> > nice if
> > we could make False work too but I worry that might not.
> >
> > Cheers,
> >
> > Richard
>
> None of this will work unless you change the code in
> bitbake/lib/bb/data.py
> to use d.getVarFlag(var, "export") instead of d.getVarFlag(var,
> "export", False).
> However, I assume that is not wanted given that support for
> foo[unexport] = "1"
> was introduced to counteract a foo[export] = "1".

Good point, which reminds me why the code does this. Expanding the
value for all export variables would have a significant effect on some
performance sensitive code :(.

From memory I think there was a bit more to unexport than that. Looking
at the history:

https://git.yoctoproject.org/poky/commit/?id=0da3c82a66e02bf2d3780e23427d476766a0bcfc

I think it wasn't enough just to not export some things, we wanted to
actually unset them in the shell environment.

We may have later done more environment cleaning which made this
unnecessary, less sure about that. I did remove a lot of the unexports
(e.g. MACHINE and DISTRO) but SHELL[unexport] = "1" remains.

Cheers,

Richard
Richard Purdie Dec. 8, 2022, 12:17 p.m. UTC | #9
On Fri, 2022-11-18 at 14:42 +0000, Anton Antonov wrote:
> Rust crates build dependecy C libraries using "CC" crate.
> This crate adds some default compiler parameters depending on target arch.
> For some target archs these parameters conflict with the parameters defined by OE.
> 
> Warnings/errors like this can be seen in the case:
> 
> cc1: error: switch '-mcpu=cortex-a15' conflicts with switch '-march=armv7-a+fp' [-Werror]
> 
> Lets use the OE parameters only by exporting CRATE_CC_NO_DEFAULTS.
> https://github.com/rust-lang/cc-rs#external-configuration-via-environment-variables
> 
> This patch fixes https://bugzilla.yoctoproject.org/show_bug.cgi?id=14947
> 
> Signed-off-by: Anton Antonov <Anton.Antonov@arm.com>
> ---
>  meta/classes-recipe/rust-target-config.bbclass | 18 ++++++++++++++++++
>  1 file changed, 18 insertions(+)
> 
> diff --git a/meta/classes-recipe/rust-target-config.bbclass b/meta/classes-recipe/rust-target-config.bbclass
> index 2710b4325d..4135335043 100644
> --- a/meta/classes-recipe/rust-target-config.bbclass
> +++ b/meta/classes-recipe/rust-target-config.bbclass
> @@ -401,3 +401,21 @@ python do_rust_gen_targets () {
>  addtask rust_gen_targets after do_patch before do_compile
>  do_rust_gen_targets[dirs] += "${RUST_TARGETS_DIR}"
>  
> +# For building C dependecies only use compiler parameters defined in OE-core
> +# and ignore the default parameters defined in the CC crate.
> +# https://github.com/rust-lang/cc-rs#external-configuration-via-environment-variables
> +# For rust native recipes we still rely on the CC crate parameters.
> +
> +CRATE_CC_NO_DEFAULTS:class-target ?= "true"
> +CRATE_CC_NO_DEFAULTS:class-nativesdk ?= "true"
> +CRATE_CC_NO_DEFAULTS:class-native ?= ""
> +
> +# The CC crate checks for CRATE_CC_NO_DEFAULTS existence not value.
> +# Even empty CRATE_CC_NO_DEFAULTS will be taken into account.
> +# So, don't export it if empty.
> +do_compile:prepend() {
> +    if [ -n "${CRATE_CC_NO_DEFAULTS}" ]; then
> +        export CRATE_CC_NO_DEFAULTS="${CRATE_CC_NO_DEFAULTS}"
> +        bbnote "CRATE_CC_NO_DEFAULTS is exported"
> +    fi
> +}

Sorry about the delays on this. I did want to try and sort the
underlying export issue and whilst I proposed a patch, the performance
impact of it is a concern so it isn't moving forward right now.

I suspect that means we should merge a different fix for now. The above
is still a little more complex and harder to read than it could be.
Could you try a version which does something like:


do_compile:prepend:class-target() {
    export CRATE_CC_NO_DEFAULTS=1
}

do_compile:prepend:class-nativesdk() {
    export CRATE_CC_NO_DEFAULTS=1
}

which should be a bit clearer/simpler?

Cheers,

Richard
diff mbox series

Patch

diff --git a/meta/classes-recipe/rust-target-config.bbclass b/meta/classes-recipe/rust-target-config.bbclass
index 2710b4325d..4135335043 100644
--- a/meta/classes-recipe/rust-target-config.bbclass
+++ b/meta/classes-recipe/rust-target-config.bbclass
@@ -401,3 +401,21 @@  python do_rust_gen_targets () {
 addtask rust_gen_targets after do_patch before do_compile
 do_rust_gen_targets[dirs] += "${RUST_TARGETS_DIR}"
 
+# For building C dependecies only use compiler parameters defined in OE-core
+# and ignore the default parameters defined in the CC crate.
+# https://github.com/rust-lang/cc-rs#external-configuration-via-environment-variables
+# For rust native recipes we still rely on the CC crate parameters.
+
+CRATE_CC_NO_DEFAULTS:class-target ?= "true"
+CRATE_CC_NO_DEFAULTS:class-nativesdk ?= "true"
+CRATE_CC_NO_DEFAULTS:class-native ?= ""
+
+# The CC crate checks for CRATE_CC_NO_DEFAULTS existence not value.
+# Even empty CRATE_CC_NO_DEFAULTS will be taken into account.
+# So, don't export it if empty.
+do_compile:prepend() {
+    if [ -n "${CRATE_CC_NO_DEFAULTS}" ]; then
+        export CRATE_CC_NO_DEFAULTS="${CRATE_CC_NO_DEFAULTS}"
+        bbnote "CRATE_CC_NO_DEFAULTS is exported"
+    fi
+}