4

Can I use Cargo to build Rust code without using its standard project layout?

My source files are not in a directory called src and this will not change. My binaries must end up in the current directory (or, in some other projects, in a different directory that is not called target/SOMETHING). Can I tell Cargo that executable foo must be built from foo.rs and bar.rs in the same directory as Cargo.toml, and qux from foo.rs?

I don't care about Cargo as a build system or as a deployment system. I'm only interested in it as a library management system. Apparently Cargo is the only game in the Rust town for this.

Community
  • 1
  • 1
Gilles 'SO- stop being evil'
  • 104,111
  • 38
  • 209
  • 254
  • 4
    May I ask... *why?* Convention Over Configuration and all... – Matthieu M. Aug 27 '16 at 23:50
  • 4
    @MatthieuM. I've never understood why it wasn't “configuration over convention”. Convention fails the [rule of two](https://blogs.msdn.microsoft.com/oldnewthing/20050607-00/?p=35413): if you have two components with incompatible conventions, what do you do? You're stuck with an irresistible force hitting an immovable cargo. – Gilles 'SO- stop being evil' Aug 27 '16 at 23:53
  • 2
    *If you have two components with incompatible conventions, what do you do?* => you make the necessary changes so that both match the convention, obviously. Cargo was developed early enough that it could set conventions straight from the start (1.0) so that all projects would live by the same convention. That being said, it *might* be possible to tweak it (thus why I commented, not answered); I just wonder, personally, if that would be a good idea... the cost of changing the project might be lower than the cost of every single maintainer having to understand why it works differently. – Matthieu M. Aug 27 '16 at 23:57
  • 1
    @MatthieuM. Cargo was certainly not developed early enough so that it could set conventions. Directory trees have existed for more than half a century! Not all projects are pure Rust projects. (I have the same problem with Java sometimes, but the Rust toolchain seems to be even worse in that respect.) – Gilles 'SO- stop being evil' Aug 28 '16 at 00:00
  • I obviously meant conventions in Rust projects :) Anyway, I am not saying it is impossible, just that going against the flow is always an uphill battle. – Matthieu M. Aug 28 '16 at 00:08

1 Answers1

5

Not really. You can control where the source files are by explicitly specifying them in the manifest:

[[bin]]
name = "foo"
src = "foo.rs"

[[bin]]
name = "qux"
src = "splong.rs"

I don't know what you mean by foo being built from foo.rs and bar.rs, whilst qux is built only from foo.rs. You can't just arbitrarily glob source files together: either foo.rs uses bar.rs, or it doesn't.

But you can't control the target directory from within the manifest. There's the build.target-dir setting (in Cargo's configuration, not the manifest), but that only lets you change the target directory, not the second level inside of it. You can change it using the CARGO_TARGET_DIR environment variable, though you can't set environment variables from within the manifest, either.

That said, setting CARGO_TARGET_DIR to the root of the project will also change where all the intermediate files go, and it'll mean every time you switch between debug and release builds, you'll have to do a full recompile.

You may want to consider opening an issue on the Cargo issue tracker about making this an option.

DK.
  • 55,277
  • 5
  • 189
  • 162