6

I have the following file structure:

src/
    lib.rs
    foo.rs
build.rs

I would like to import something from foo.rs (lib.rs has pub mod foo in it already) into build.rs. (I'm trying to import a type in order to generate some JSON schema at build time)

Is this possible?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Foobar
  • 7,458
  • 16
  • 81
  • 161

1 Answers1

11

You cannot cleanly — the build script is used to build the library, so by definition must run before the library is built.

Clean solution

Put the type into another library and import the new library into both the build script and your original library

.
├── the_library
│   ├── Cargo.toml
│   ├── build.rs
│   └── src
│       └── lib.rs
└── the_type
    ├── Cargo.toml
    └── src
        └── lib.rs

the_type/src/lib.rs

pub struct TheCoolType;

the_library/Cargo.toml

# ...

[dependencies]
the_type = { path = "../the_type" }

[build-dependencies]
the_type = { path = "../the_type" }

the_library/build.rs

fn main() {
    the_type::TheCoolType;
}

the_library/src/lib.rs

pub fn thing() {
    the_type::TheCoolType;
}

Hacky solution

Use something like #[path] mod ... or include! to include the code twice. This is basically pure textual substitution, so it's very brittle.

.
├── Cargo.toml
├── build.rs
└── src
    ├── foo.rs
    └── lib.rs

build.rs

// One **exactly one** of this...
#[path = "src/foo.rs"]
mod foo;

// ... or this
// mod foo {
//     include!("src/foo.rs");
// }

fn main() {
    foo::TheCoolType;
}

src/lib.rs

mod foo;

pub fn thing() {
    foo::TheCoolType;
}

src/foo.rs

pub struct TheCoolType;
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
  • Isn't there an even hackier solution of just [`include!`](https://doc.rust-lang.org/std/macro.include.html)-ing the module into the build script? – Masklinn Jun 09 '21 at 14:02
  • @Masklinn isn't that what I describe in the section titled "Hacky solution": *Use something like `include!` or `#[path] mod ...`*? – Shepmaster Jun 09 '21 at 14:05
  • yep, I focused on the snippets and managed to overlook both the text and the comment mentioning include... – Masklinn Jun 09 '21 at 15:47
  • @Masklinn the code example [was only added in the most recent revision](https://stackoverflow.com/posts/67905413/revisions), but I mentioned the possibility of `include` from the first post ;-) – Shepmaster Jun 09 '21 at 15:49