mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-02 08:11:12 +00:00
Rebuild hosts automatically (for now)
This commit is contained in:
parent
856c01f706
commit
7e1166b3a2
3 changed files with 81 additions and 65 deletions
|
@ -10,6 +10,10 @@ pub fn link(
|
|||
host_input_path: &Path,
|
||||
dest_filename: &Path,
|
||||
) -> io::Result<Child> {
|
||||
// TODO we should no longer need to do this once we have platforms on
|
||||
// a package repository, as we can then get precompiled hosts from there.
|
||||
rebuild_host(host_input_path);
|
||||
|
||||
match target {
|
||||
Triple {
|
||||
architecture: Architecture::X86_64,
|
||||
|
@ -25,6 +29,68 @@ pub fn link(
|
|||
}
|
||||
}
|
||||
|
||||
fn rebuild_host(host_input_path: &Path) {
|
||||
let c_host_src = host_input_path.with_file_name("host.c");
|
||||
let c_host_dest = host_input_path.with_file_name("c_host.o");
|
||||
let rust_host_src = host_input_path.with_file_name("host.rs");
|
||||
let rust_host_dest = host_input_path.with_file_name("rust_host.o");
|
||||
let host_dest = host_input_path.with_file_name("host.o");
|
||||
|
||||
// Compile host.c
|
||||
Command::new("clang")
|
||||
.env_clear()
|
||||
.args(&[
|
||||
"-c",
|
||||
c_host_src.to_str().unwrap(),
|
||||
"-o",
|
||||
c_host_dest.to_str().unwrap(),
|
||||
])
|
||||
.output()
|
||||
.unwrap();
|
||||
|
||||
if rust_host_src.exists() {
|
||||
// Compile and link host.rs, if it exists
|
||||
Command::new("rustc")
|
||||
.args(&[
|
||||
rust_host_src.to_str().unwrap(),
|
||||
"-o",
|
||||
rust_host_dest.to_str().unwrap(),
|
||||
])
|
||||
.output()
|
||||
.unwrap();
|
||||
|
||||
Command::new("ld")
|
||||
.env_clear()
|
||||
.args(&[
|
||||
"-r",
|
||||
c_host_dest.to_str().unwrap(),
|
||||
rust_host_dest.to_str().unwrap(),
|
||||
"-o",
|
||||
host_dest.to_str().unwrap(),
|
||||
])
|
||||
.output()
|
||||
.unwrap();
|
||||
|
||||
// Clean up rust_host.o
|
||||
Command::new("rm")
|
||||
.env_clear()
|
||||
.args(&[
|
||||
"-f",
|
||||
rust_host_dest.to_str().unwrap(),
|
||||
c_host_dest.to_str().unwrap(),
|
||||
])
|
||||
.output()
|
||||
.unwrap();
|
||||
} else {
|
||||
// Clean up rust_host.o
|
||||
Command::new("mv")
|
||||
.env_clear()
|
||||
.args(&[c_host_dest, host_dest])
|
||||
.output()
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
fn link_linux(
|
||||
target: &Triple,
|
||||
binary_path: &Path,
|
||||
|
@ -34,6 +100,8 @@ fn link_linux(
|
|||
// NOTE: order of arguments to `ld` matters here!
|
||||
// The `-l` flags should go after the `.o` arguments
|
||||
Command::new("ld")
|
||||
// Don't allow LD_ env vars to affect this
|
||||
.env_clear()
|
||||
.args(&[
|
||||
"-arch",
|
||||
arch_str(target),
|
||||
|
@ -73,6 +141,8 @@ fn link_macos(
|
|||
// NOTE: order of arguments to `ld` matters here!
|
||||
// The `-l` flags should go after the `.o` arguments
|
||||
Command::new("ld")
|
||||
// Don't allow LD_ env vars to affect this
|
||||
.env_clear()
|
||||
.args(&[
|
||||
"-arch",
|
||||
target.architecture.to_string().as_str(),
|
||||
|
|
|
@ -1,21 +1,8 @@
|
|||
## Recompiling the platform from source
|
||||
# Rebuilding the host from source
|
||||
|
||||
This example platform for "Hello, World!" includes the same host implemented
|
||||
in two different languages—C and Rust—to demonstrate how it's done in both.
|
||||
Ordinarily you'd only implement your host once, in your preferred language.
|
||||
Run `build.sh` to manually rebuild this platform's host.
|
||||
|
||||
|
||||
### Recompiling the C implementation
|
||||
|
||||
```shell
|
||||
$ clang -c host.c -o host.o
|
||||
```
|
||||
|
||||
Then `mv` the compiled `host.o` into the apropriate subdirectory under
|
||||
`host/` based on the operating system you've compiled it for.
|
||||
|
||||
### Recompiling the Rust implementation
|
||||
|
||||
```shell
|
||||
$ rustc
|
||||
```
|
||||
Note that the compiler currently has its own logic for rebuilding these hosts
|
||||
(in `link.rs`). It's hardcoded for now, but the long-term goal is that
|
||||
hosts will be precompiled by platform authors and distributed in packages,
|
||||
at which point only package authors will need to think about rebuilding hosts.
|
||||
|
|
|
@ -1,49 +1,8 @@
|
|||
# Rebuilding the host from source
|
||||
|
||||
Here are the current steps to rebuild this host. These
|
||||
steps can likely be moved into a `build.rs` script after
|
||||
turning `host.rs` into a `cargo` project, but that hasn't
|
||||
been attempted yet.
|
||||
Run `build.sh` to manually rebuild this platform's host.
|
||||
|
||||
## Compile the Rust and C sources
|
||||
|
||||
Currently this host has both a `host.rs` and a `host.c`.
|
||||
This is only because we haven't figured out a way to convince
|
||||
Rust to emit a `.o` file that doesn't define a `main` entrypoint,
|
||||
but which is capable of being linked into one later.
|
||||
|
||||
As a workaround, we have `host.rs` expose a function called
|
||||
`rust_main` instead of `main`, and all `host.c` does is provide
|
||||
an actual `main` which imports and then calls `rust_main` from
|
||||
the compiled `host.rs`. It's not the most elegant workaround,
|
||||
but [asking on `users.rust-lang.org`](https://users.rust-lang.org/t/error-when-compiling-linking-with-o-files/49635/4)
|
||||
didn't turn up any nicer approaches. Maybe they're out there though!
|
||||
|
||||
To make this workaround happen, we need to compile both `host.rs`
|
||||
and `host.c`. First, `cd` into `platform/host/src/` and then run:
|
||||
|
||||
```
|
||||
$ clang -c host.c -o c_host.o
|
||||
$ rustc host.rs -o rust_host.o
|
||||
```
|
||||
|
||||
Now we should have `c_host.o` and `rust_host.o` in the curent directory.
|
||||
|
||||
## Link together the `.o` files
|
||||
|
||||
Next, combine `c_host.o` and `rust_host.o` into `host.o` using `ld -r` like so:
|
||||
|
||||
```
|
||||
$ ld -r c_host.o rust_host.o -o host.o
|
||||
```
|
||||
|
||||
Move `host.o` into the appropriate `platform/` subdirectory
|
||||
based on your architecture and operating system. For example,
|
||||
on macOS, you'd move `host.o` into the `platform/host/x86_64-unknown-darwin10/` directory.
|
||||
|
||||
## All done!
|
||||
|
||||
Congratulations! You now have an updated host.
|
||||
|
||||
It's now fine to delete `c_host.o` and `rust_host.o`,
|
||||
since they were only needed to produce `host.o`.
|
||||
Note that the compiler currently has its own logic for rebuilding these hosts
|
||||
(in `link.rs`). It's hardcoded for now, but the long-term goal is that
|
||||
hosts will be precompiled by platform authors and distributed in packages,
|
||||
at which point only package authors will need to think about rebuilding hosts.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue