kevinmehall/rust-peg

the `#[proc_macro]` attribute is only usable with crates of the `proc-macro` crate type

sudo-nice opened this issue · 2 comments

I can't build a binary statically, using peg as a dependency. Here is a tiny main.rs to reproduce:

extern crate peg;
use peg::parser;

parser!{
    pub grammar g() for [u8] {
        #[no_eof]
        pub rule foo() = "foo"
    }
}

fn main() {
    assert_eq!(g::foo(b"foobar"), Ok(()));
}

Cargo.toml:

[profile.release]
strip = "symbols"
lto = "fat"
panic = "abort"
codegen-units = 1

# Commenting out this line allows to compile
rustflags = ["-C", "target-feature=+crt-static"]

[package]
name = "bar"
version = "0.1.0"
edition = "2021"

[dependencies]
peg = "*"

Trying to build it with cargo build --release results in the error:

error: the `#[proc_macro]` attribute is only usable with crates of the `proc-macro` crate type
  --> /mnt/ssd1/rust/cargo/registry/src/index.crates.io-6f17d22bba15001f/peg-macros-0.8.2/lib.rs:20:1
   |
20 | #[proc_macro]
   | ^^^^^^^^^^^^^

error: could not compile `peg-macros` (lib) due to previous error

Debian GNU/Linux 11 (bullseye)
rustc 1.76.0-nightly (49b3924bd 2023-11-27)

Procedural macros are built as a dynamic library that is loaded into rustc at compile time for macro expansion, so they can't be compiled with crt-static. In theory, you should be able to still statically link the final executable with the macro-generated code, though. From rust-lang/rust#78210, it looks like explicitly passing --target x86_64-unknown-linux-gnu will make it pass your RUSTFLAGS only when building the target binary and not the macro.

I see, thank you for the clarification.
Rust-peg is a really nice piece of software, btw.