Arbitrary flags cannot be passed through to the compiler.
-O has to be the default.
There will be toooooons of these eventually, yes.
Until this is implemented, cargo cannot be used for cross compilation.
+1 for passing flags to the compiler as a critical feature
-O has to be the default.
FWIW, I've forked cargo to always pass the "-O" flag to rustc.
-O should probably be the default for dependencies since they are compiled rarely, but it would be nice for cargo build to default to the fastest option for the main code (i.e. no -O).
cargo build --release to build with optimizations+1 for passing flags like --opt-level=3, -Z lto and --emit=obj via command line or manifest file.
And -Z no-landing-pads.
@alexchandel you seem to be able to do this, right?
Thankfully, Cargo doesn't crash when passed extra unrecognized flags. For libraries, I partially hack around this issue by calling rustc afterwards on the last thing cargo builds.
Please add some target and emission specifications. The lib.crate-types key is completely ignored, AS IS #![crate_type = "staticlib"].
Cargo isn't the last step in many build cycles, and the inability to output object files or to compile static libraries is a huge inconvenience.
Being able to output object files and such would be super awesome!
I tried hacking together a fix for this at https://github.com/bfops/cargo. If people are willing to test for me, you can add
extra_rustc_args = ["--foo", "bar"]
to your Cargo.toml. No support yet for passing directly from the command line.
:+1: to arbitrary rustc flags
It should be noted that the design of cargo is currently to explicitly _not_ allow arbitrary flags. It is very easy to have compilations go awry very quickly, and packages specifying flags for themselves is likely a decision that should not be up to the author but rather the builder.
We certainly plan on allowing more flavorful configuration that is possible today through profiles, but it will likely not just be "pass these flags through to the compiler".
@bfops - putting compiler flags into the TOML file won't work. Compiler flags have to be passed to Cargo from outside.
For example, when cross-compiling a single program for different targets I need to pass different command-line flags (target triple, location of linker, etc.) for each target.
@alexcrichton - I think you should always allow the user to "break glass in case of emergency". At the moment, I cannot use Cargo as a build tool. So, for anyone doing cross compilation, it's useless.
If you disallow passing flags to the rustc compiler you essentially couple the release cycles of Cargo and rustc, because Cargo will have to be changed to expose any new capabilities of rustc. But if you're going to couple Cargo and Rustc releases, you may as well pass compiler flags through, because Cargo can have built-in knowledge of the flags accepted by the rustc version it's coupled to, and be able to detect and reject invalid flags.
@npryce - I agree, flags in the TOML file isn't comprehensive. Once I'm done my exams, I'll try to continue development on my fork if another one hasn't taken off yet. Pull requests are always welcome too!
I'm not sure I entirely understand your use case, sorry. With the current set-up, you'd have to have different targets for windows builds, linux builds, etc. Each target can have its own flags. But yes, right now in my fork they have to be baked into the TOML file.
If arguments are specified on the command line (e.g. via --rustc_args=), should they be passed to one target? All of them? Tests? Examples? The dependencies as well?
@bfops In my case, I'm cross-compiling from Ubuntu x86 to Raspbian on the Raspberry Pi, but there are lots of different single-board Linux computers (Beaglebone, etc.) that my programs could run on. Each target typically has its own toolchain -- C compiler, linker, C stdlib, etc. When using Rust, the C compiler is not used, but the linker and C stdlib is.
At the moment I use Make for the build. I have a make include file per target (e.g. targets/raspi.mk) that defines the rustc flags for that target. My main makefile includes targets/$(target).mk. And I can pass the target to the make command: make target=raspi.
How Cargo should work, I don't know. Maybe the project's top-level cargo file should have a way of defining compiler arguments per target and be told the target as a command-line parameter.
Or, just say that Cargo will never be flexible enough for all uses and don't support cross-compilation at all. Let Cargo do dependency resolution well and make it easy to invoke from an existing build tool like Make.
@npryce My current cargo fork allows specifying rustc command line flags on a per-target basis, the remaining step would be to make the target a command-line parameter, which seems like a good feature either way. I'll look into it.
I'm going to close this issue as-is, as I don't think that it's particularly actionable any more. Support for per-project profiles recently landed which is how cargo plans to support customizing the build of a project.
Right now profiles are pretty bare, only supporting opt-level and debug, but the plan is to make them much richer by adding a variety of other options. At this time we don't plan on allowing, through the normal cargo build interface, arbitrary flags to be passed to the compiler. The plan is to have a composable set of sub-commands which will be used to customize a build of cargo if you'd like.
If you currently have a use case which cargo isn't supporting, then please feel free to open a bug about it! Specific problems are greatly appreciated, and the general idea is that build-related options (like most of those in -C) should be exposed through profiles.
So in summary:
cargo buildCurrently i have a little rust program, that i would like to be compiled dynamically linked, because the resulting binary becomes huge if not.
So, that is not yet possible with cargo?
@buster http://doc.crates.io/manifest.html#building-dynamic-or-static-libraries
@steveklabnik , actually i want to build a binary with "-C prefer-dynamic"...
+1 for "-C prefer-dynamic". Anybody figured out the right way to do that yet? 550 KB "hello world" is a dealbreaker for me.
Ugh, I need a -C ban-dynamic. @buster @prdoyle The big hello world is due to rust#22159. If you hack out allocation, it comes down to 4k (on OS X x64). Bear in mind though that the 500 kB is the amortized cost of jemalloc & friends: larger executables will have much better mileage / far fewer bytes per LOC than small ones because of this.
Sure, I get that it will be amortized, but it would be nice if Rust could be used for small programs too, even if they allocate some memory.
@prdoyle jemalloc could definitely use some optimization. I can't imagine how all 500kB could be necessary for a single malloc. Though many heap allocations could be optimized out. Yet on most platforms Rust programs are dynamically linked to the system library (glibc/libSystem/kernel32/etc), which uses 5-10MB of process memory. If we had our own system library, then a 500kB runtime wouldn't be so bad. Especially since with static linking & LTO, most programs would use a fraction of that.
+1 for LTO; we're thinking of building small shared objects in rust and deploying them inside Linux containers that have tight memory restrictions.
One can get LTO by customising the relevant profile.
This is very nice, but: https://github.com/lavrin/erlang-rust-nif/issues/3
cargo cannot compile under MacOS X without adding specific flags.
@maxlapshin would cargo rustc suffice for your use case?
Holy cargo....
It should be noted that the design of cargo is currently to explicitly not allow arbitrary flags. It is very easy to have compilations go awry very quickly,
I just want to know,a project like servo,how to use cargo for minimize version using prefer-dynamic args?
I found this bug and got confused, so I thought I'd add a note for the benefit of other visitors. As of November 2016 it's perfectly possible to pass arbitrary flags to rustc. If you want to use dynamic libraries, for example, you can do either:
cargo rustc -- -C prefer-dynamic
or
RUSTFLAGS='-C prefer-dynamic' cargo build
Hope this helps someone!
@PeteX It helped me, thanks!
There also seems to be flags like CARGO_TARGET_{target-triple in all caps and with "-" replaced by "_"}_LINKER which are still needed if, for example, you want to cross-compile the tests.
It should be noted that the design of cargo is currently to explicitly not allow arbitrary flags. It is very easy to have compilations go awry very quickly, and packages specifying flags for themselves is likely a decision that should not be up to the author but rather the builder.
I think this is a good argument for published dependencies, but less so for toplevel Cargo.tomls. We already have profiles for this, and ideally they'd be able to specify more. You can always override things via .cargo/config or editing the Cargo.toml.
This becomes frustrating because IDEs no longer work with projects forced to use RUSTFLAGS as part of their build process (e.g. Servo) since their build process is more than cargo build. At best they don't work, at worst they clobber builds to boot.
Really, even the ability to override this in .cargo/config ONLY would be quite useful. But it sounds very much like a profile thing.
Edit: My bad, it's possible to do this in the config already
Most helpful comment
I found this bug and got confused, so I thought I'd add a note for the benefit of other visitors. As of November 2016 it's perfectly possible to pass arbitrary flags to rustc. If you want to use dynamic libraries, for example, you can do either:
cargo rustc -- -C prefer-dynamicor
RUSTFLAGS='-C prefer-dynamic' cargo buildHope this helps someone!