App structure looks bloated

I'm building a SDK that is currently planned to generate a new project with the following structure:

foo-app
|__ res
| |____ lang
| |    |___ en-US
| |         |__ _.json
|__ src
| |____ app
| | |_____ localization.rs
| | |_____ main.rs
|__ .gitignore
|__ Cargo.toml
|__ Flx.toml
|__ README.md
|__ build.rs

The problem is that the project's entry point, src/app/main.rs, is wrapped by another entry point. The purpose of wrapping it is to setup some internal variables (and possibly more, futurely). Such wrapper entry point will be generated by build.rs. Here's what the entry point generated by build.rs will look like:

foo-app
|__ src
| |____ flxinternals
| | |_____ main.rs
| |____ flxinternals_entry.rs

I'm finding this annoying. I'd like to put these internal entry points somewhere else, like out of src:

foo-app
|__ .flx_internals
| |____ entry.rs

Is this possible? Here's the full structure: flx/flxsdk_starter_template at master · flxsdk/flx · GitHub

The conventional way to customize program start is not to generate files but to provide an attribute macro that can be applied to main(), like for example tokio::main. This will be a simpler file structure and more familiar to Rust programmers who have used other frameworks.

1 Like

But that means I'll have to create a separate crate on each rebuild... (For example, there's no way to put a crate on crates.io for that, because the script generated by build.rs will contain project settings such as short-id, full-id etc.). Maybe it could work, yeah... but I still didn't understand how to mimmick tokio::main's approach: Wrap entry point - #5 by Michael-F-Bryan Anyway, I'll still have to generate files on build as I said.

Code generated by build scripts should almost always be placed in the directory indicated by the OUT_DIR environment variable in the build script.

You can generate the code you need there, and then define a macro that will include the generated files and perform the set up without requiring the double entry point setup.

I can try and put together a complete example later

1 Like

That seems complicated. Say, I'd have to generate a crate at OUT_DIR, right? The problem is, how will I refer to its macro since the crate will be in a very variable location? I just did this in build.rs:

fn main() {
    panic!("{}", std::env::var("OUT_DIR").unwrap());
}

I got:

   Compiling foo-rs v0.1.0 (C:\Users\matheus-pc\Documents\foo-rs)
error: failed to run custom build command for `foo-rs v0.1.0 (C:\Users\matheus-pc\Documents\foo-rs)`

Caused by:
  process didn't exit successfully: `C:\Users\matheus-pc\Documents\foo-rs\target\debug\build\foo-rs-b04af091b1b406d0\build-script-build` (exit code: 101)
  --- stderr
  thread 'main' panicked at 'C:\Users\matheus-pc\Documents\foo-rs\target\debug\build\foo-rs-6da59176a7067545\out', build.rs:2:5
  note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

You include the generated Rust code via the OUT_DIR environment variable in the crate that has the build script, as demonstrated here

1 Like

Well, that really was useful! The only con is I've to add this to the app's entry point:

/// **DO NOT MODIFY THIS FUNCTION.**
fn initialize_flx() {
    include!(concat!(env!("OUT_DIR"), "/flx_entry.rs"));
}

Then initialize_flx is called by main() once.

I put together a simple example of how I might go about setting up crates for a situation like this in a repo on github

1 Like