5

It is possible to set both the favicon and the logo of the rustdoc for a crate by using:

  • #![doc(html_favicon_url = "<url_to>/favicon.ico")]
  • #![doc(html_logo_url = "<url_to>/logo.png")]

as documented here.

However I do not want to upload my logo publicly and would therefore like to automatically include these files in /target/doc and reference them from there.

Currently I have put the respective data urls (base64 encoded) into these fields and it works fine, but it enormously bloats the source file where these attributes are set.

I know I could just copy the images into target/doc after generating the documentation using a script and then reference them using the relative url, but I would like to avoid this, so that I can still generate the documentation using cargo doc.

Edit

The suggestion from the comment to set the --output flag of rustdoc using rustdocflags in .cargo/config.toml also did not work, because it leads to error: Option 'output' given more than once. Apart from that, it is not suited for me, because (at least as far as I understand) I can only give absolute paths there, whereas I would need a solution using relative paths for the images, because I have those images stored in a subdirectory of the cargo root directory, to allow for easy transfer to another system using git, etc.

frankenapps
  • 5,800
  • 6
  • 28
  • 69
  • "*but I would like to avoid this, so that I can still generate the documentation using `cargo doc`*"—perhaps you could elaborate on this a little more? Would a script, or `cargo` command, that wraps both actions together not suffice? – eggyal May 25 '21 at 17:17
  • If I put both actions in a script I will have to run the script (e.g. ./myscript.sh) which I think is not ideal, because then I will have to remember that for this particular project I can not generate the documentation using `cargo doc` as usual. – frankenapps May 25 '21 at 17:23
  • You could create a script that forwards its arguments to `rustdoc` and then copies the desired static assets into the resulting output folder; and then configure Cargo to use that script via the [`build.rustdoc`](https://doc.rust-lang.org/cargo/reference/config.html#buildrustdoc) setting within `.cargo/config.toml` inside your project root. – eggyal May 25 '21 at 17:45
  • @eggyal The `build.rustdoc` sounds interesting. I tried to supply my bash script, but it seems only executables are allowed (at least on windows), because I now get the error `%1 is not a valid Win32 application. (os error 193)`. I might create a small executable to do this, but I am not sure it is worth the hassle, because then I can also just keep the base64 encoded images (especially considering, that I would need to add the executable to git, too)... – frankenapps May 25 '21 at 18:40
  • I think you should be able to resolve that error for a script, but I'm not familiar enough with Windows. Perhaps try opening another question about that? – eggyal May 25 '21 at 18:45
  • Alternatively, I suppose you could set [`build.rustdocflags`](https://doc.rust-lang.org/cargo/reference/config.html#buildrustdocflags) to set [`--output`](https://doc.rust-lang.org/rustdoc/command-line-arguments.html#-o--output-output-path) to an existing folder that contains your image? – eggyal May 25 '21 at 19:25
  • 1
    To be clear, the idea was to output the generated rustdoc to a location that already contained the image in order that a relative path to the image would succeed. Anyway, I'm now thinking that a [build script](https://doc.rust-lang.org/cargo/reference/build-scripts.html) that copies the image into the target directory may actually be your best option here. – eggyal May 26 '21 at 11:25

1 Answers1

1

Thanks to the latest comment from eggyal I finally figured out how to do this:

In my build.rs I copy the files to target/doc/:

fn main() {
    // Copy the images to the output when generating documentation
    println!("cargo:rerun-if-changed=assets/doc");
    std::fs::copy("assets/doc/logo.ico", "target/doc/logo.ico").expect("Failed to copy crate favicon when building documentation.");
    std::fs::copy("assets/doc/logo.png", "target/doc/logo.png").expect("Failed to copy crate logo when building documentation.");
}

and then I just had to make sure, to use an absolute path when referencing them, like so:

#![doc(html_favicon_url = "/logo.ico")]
#![doc(html_logo_url = "/logo.png")]

In general it would be better to read the CARGO_TARGET_DIR environment variable instead of hardcoding target/doc, but this is not yet available in build scripts.

frankenapps
  • 5,800
  • 6
  • 28
  • 69
  • You might want to use env(OUT_DIR) instead of hard-coding “target/doc”. – eggyal May 26 '21 at 12:25
  • Also, I don’t think your `rerun-if-changed` is correct. target/doc is only changed by the build, *after* the build script has run. You should instead point it at your assets directory, so the build script is re-run and re-copies images to the output directory if *they* have changed. – eggyal May 26 '21 at 12:35
  • Well, but then they wouldn’t be copied after cargo clean, if I am not mistaken? – frankenapps May 26 '21 at 12:38
  • Everything gets rerun after cargo clean. – eggyal May 26 '21 at 12:39
  • Ah, I see. Thank you – frankenapps May 26 '21 at 12:42