coral-xyz / anchor

⚓ Solana Sealevel Framework
https://anchor-lang.com
Apache License 2.0
3.36k stars 1.25k forks source link

Compilation Error with Passing Cargo args when build program when IDL Generation is enabled in Anchor 0.30 #3054

Closed biryukovmaxim closed 4 days ago

biryukovmaxim commented 5 days ago

Hello! I'm from Debridge team. We faced an issue while updating our contract from anchor 0.28 to 0.30

Description:

After updating from Anchor 0.28 to 0.30, our project encounters a compilation error when conditional compilation features are used along with IDL generation. The error does not occur when compiling with the --no-idl flag.

MRE:

use anchor_lang::prelude::*;

declare_id!("8bBe1LzQ9cBVzk4bMqcYsRqM942C4DvYvwKy9bZqUVyg");

#[program]
pub mod mre_idl_bug {
    use cfg_if::cfg_if;
    use super::*;

    pub fn initialize(ctx: Context<Initialize>) -> Result<()> {
        cfg_if!(
           if #[cfg(feature = "one")] {
                const FOO: usize = 1;
           } else if #[cfg(feature = "two")] {
                const FOO: usize = 2;
           } else {
                compile_error!("You should use one of feature: `one`, `two`");
           }
        );

        msg!("Greetings from: {:?}", ctx.program_id);
        Ok(())
    }
}

#[derive(Accounts)]
pub struct Initialize {}

features "one" and "two" are added to Cargo.toml

Expected behavior:

Running anchor build -- --features one should produce a valid library and an IDL.

Actual result:

error: You should use one of feature: `one`, `two`
  --> programs/mre-idl-bug/src/lib.rs:17:17
   |
17 |                 compile_error!("You should use one of feature: `one`, `two`");
   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: could not compile `mre-idl-bug` (lib test) due to 1 previous error
Error: Building IDL failed

Analysis:

The issue likely stems from the IDL builder function not accepting and passing cargo_args, based on the examination of the source code here.

It works fine when I add flag --no-idl. It works fine with 0.28.0

acheroncrypto commented 5 days ago

The issue likely stems from the IDL builder function not accepting and passing cargo_args, based on the examination of the source code here.

Thanks, your analysis is correct; cargo arguments you pass don't apply to the IDL build command currently, as you've figured out.

Using the same cargo arguments both for the regular program build and the IDL build should be fine at first glance. If there is a problem, we can also introduce an option that takes in arguments to only pass to the IDL build command.

biryukovmaxim commented 5 days ago

I saw labels. From my perspective the issue is a bug(or at least breaking change) since it worked before

acheroncrypto commented 5 days ago

The reason I didn't classify this issue as a bug is because IDL generation process between v0.28 and v0.30 are vastly different (the old one did not use compilation), and you can fix this by including the feature you want to enable to the idl-build feature array in your Cargo.toml:

[features]
idl-build = ["anchor-lang/idl-build", "one"]

It's definitely a breaking change though, hence the versioning.