mozilla/rust — Issue #1850: Building and compiling C code with rustc/cargo
Author: thoughtpolice
Created: 2012-02-16 02:02:34+00:00
State: open

I discussed this in #1555. Basically, there are often times when you want to bundle some C code with a package, either because it's a binding and the source is portable, you're writing a shim for say, a C++ library, or just any transient piece of glue you want to distribute (say something that interfaces with `rt` etc.)

Cargo doesn't support this right now, as it only compiles crates in the source directory from what I can tell. `rustc` does not understand `.c` source files. Native modules work by mapping to shared libraries, but sometimes this is overkill (because the source is small,) and other times it's clunky (sundown and other libraries may be intended to included inline, so it's more work for a user who has to do it out of band anyway.) Sometimes these shims are even required - you need a stable name for the linker to resolve, because the shim you call's real function name is hidden behind a macro. This sort of wrapping occurs in many APIs.

Ideally for something like #1555, if we could compile C/C++ code one way or another with a crate, a `sundown` library can be registered with cargo-central, with the source inline as it's only 3 files, rustdoc can be split off and also put in cargo-central too. I think this is a nice way to go, but this is just one use case overall I think. It would also make it possible for me to reuse code and write bindings to other libraries easily (like LevelDB, and NaCl.)

There are two ways of accomplishing this broadly speaking, both with merits:

1) Make `rustc` be able to just accept c files to compile and run through the linker, along with crates. Alternatively this could be specified with crate attributes or something, listing the files to include in the build.
2) Make `cargo` actually take the responsibility of building the C files - this avoids complexity in the frontend but cargo may have to do a lot more.

I personally think 1 is the way to go and has the most bang for your buck, since rustc is already doing the compilation, and can give flags that may be necessary to the C compiler (like say, `-fPIC` or not.) This does keep cargo simpler. It also makes it really easy for users: `rustc leveldb ` or somesuch, for example, where there may be an `#cfiles[(...)]` attribute in the crate. You don't need cargo just to build your project, either.

This does mean there may need to be more syntax for accommodating native methods that resolve to a link time symbol, not a full blown library. I don't know what the syntax would look like, I'm open to suggestions from others here.