After getting tired of fighting dependencies manually, I’ve converted my rust bots to use cargo. That, in turn, required a bundler script to join multiple source files into the one that is sync’d with cg. I ended up cooking a build.rs that did that inside cargo and worked very well. I have now evolved it into a crate at the following repository:
This is an alternative to this script, though this project has no intention of performing any optimization, focusing only on convenience.
I’m not clear on how to use this script? It doesn’t seem to be bundling files for me. But I’m also not clear on whether I need a crate, or how to setup my project.
I’m not clear on what csbk.rs should be replaced with. I assumed my main.rs which has the entry point.
I’m also not sure about <crate name> – is this an input or output name? I created a lib.rs with some mod omd_name in it, but that didn’t appear to be enough. Do I need a separate directory structure for my crate and main files?
I’ve added an example subdirectory to the github repository. You can use that as a starting point also.
What the code does is also somewhat simplistic: it replaces the extern crate <crate> in the binary with the contents of lib.rs, while also replacing the pub mod ... lines with the contents of the corresponding rs file, recursively. It works on most cases, AFAICT, by taking advantage of some things that cargo itself is already opinionated about (lib.rs, etc.)
An example is nice. This work is well appreciated!
I hit a problem in the stream yesterday, and we needed to do a workaround. I had a src/bin/main.rs like this:
extern crate botters;
use botters::entry;
fn main() {
entry::entry()
}
This was causing duplicate mod errors in the emitted singlefile.rs.
407 | pub mod entry {
| ------------- previous definition of the module `entry` here
...
663 | use entry;
| ^^^^^ `entry` reimported here
As a workaround I built a second file:
extern crate botters;
use entry::*;
fn main() {
entry::entry()
}
This second one isn’t actually a valid Rust program, as entry::* doesn’t exist – but it works in the single file mode because they’ve been packed together.
I’m guessing this has to do with the form of the import, just use botters::entry, the whole thing, not specific names like use botters::entry::foo. Maybe you need to detect that case and just drop the line entirely?
The issue is a bit more involved, because the bundler has to track the embedded modules to know when the whole line can be dropped. The use is valid if you are importing a function that lives inside an embedded module, for instance. I’ll try fixing that over the weekend.
Thanks for pointing it out, and for using rust-sourcebundler!
One of the primary to-dos was always to convert my script into rust/get it supported under cargo! The main hold-up was that I had had issues working with string manipulations in Rust for puzzles, so I was hesitant.
Pretty printing and/or minification may still be on the table. But that’s a much simpler task in any case.
When I’m done with my assessments (in a few days) I’ll take a look at this and see if there are any features in my script that I could port onto yours, likely via fork+PR. (E.g. local (personal) crate support/addressing your issue).
Also is there any particular reason you implemented this for writing a dedicated build.rs instead of specifying the input and output paths purely by configuration in cargo.toml? (I don’t know for sure, but my understanding is that there is a way to specify the paths as configurations of your crate within the toml)