How to link to libc?

I have this Rust code converted from C source code Code shared from the Rust Playground · GitHub.

I'm trying to run the code as a script.

Right now I'm getting errors.

error[E0433]: failed to resolve: use of undeclared crate or module `libc`
  --> ./rust.sh:10:39
   |
10 |     fn fflush(__stream: *mut FILE) -> libc::c_int;
   |                                       ^^^^ use of undeclared crate or module `libc`

How to link to libc in the .rs file?

1 Like

When you say “run the code as a script”, exactly what are you doing?

If you are running rustc, then you are going to have a bad time. Most Rust programs use cargo, the Rust dependency management and build tool. It is very difficult to use any dependencies whatsoever without Cargo (or a complete replacement for it).

If you use Cargo, you will create a Cargo.toml file which can specify dependencies, including libc, and Cargo will build both libc (which is a Rust library itself — it's not your C libc, but a wrapper around it!) and your program.

You may also be interested in the unstable Cargo script feature, which lets you write a single-file Rust program that Cargo can build and run. However, because it is unstable, you need to use a nightly Rust version, and it may be changed in the future.

If you're already doing either of the above, then you just need to add libc to your dependencies — cargo add libc can modify your Cargo.toml for you.

I have this Rust code converted from C source code

If you clean up your translated C code (or rewrite it from scratch) so that it does not need libc and uses only Rust std functionality, then you will have much better Rust code, and you would not need Cargo in this case. (However, in general it is not good practice to try to write Rust programs with zero dependencies; you'll reinvent lots of things you don't need to.)

1 Like

For testing purposes, right now I'm doing this

$ ./rust.sh
#!/bin/sh
//bin/bash -ec '[ "$0" -nt "${0%.*}" ] && /home/user/bin/rustc/bin/rustc -L /home/user/bin/rust-std-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib "$0" -o "${0%.*}"; "${0%.*}" "$@"' "$0" "$@"; exit $?

use std::env;
// https://stackoverflow.com/a/75981598
fn main() {
  let args: Vec<String> = env::args().collect();
  if args.len() > 1 {
      println!("Hello {}!", &args[1]);
  } else {
      println!("Hello world!");
  }
}

I don't have any Cargo.toml.

My goal is to use Rust as a scripting language, exclusively, without compiling any executables.

That's how I learn different languages.

You may also be interested in the unstable Cargo script feature, which lets you write a single-file Rust program that Cargo can build and run. However, because it is unstable, you need to use a nightly Rust version, and it may be changed in the future.

That's where I was referred here to from Cargo does not handle `+toolchain` directives. · Issue #14363 · rust-lang/cargo · GitHub.

I don't have the disk space for the 1 GB standard Rust toolchain on this machine, so I extracted cargo, rustc, and rust-std from the Nightly archive.

(However, in general it is not good practice to try to write Rust programs with zero dependencies; you'll reinvent lots of things you don't need to.)

Right now I'm working on implementing a Native Messaging host in Rust using the standard library alone, no serde of any other dependencies. As I've done in C, C++, Python, Bash, WASI compiled from C, WAT in a Bash script passed to wasmtime using process substitution, JavaScript (Node.js, Deno, Bun, QuickJS, txiki.js, SpiderMonkey js shell, TypeScript).

For V8's d8 shell and Amazon Web Services - Labs llrt I had to create a child process to intercept and read standard input, then send standard input stream back to d8, and llrt, respectively.

This is my second time trying to use Rust.

@kpreid See GitHub - guest271314/NativeMessagingHosts: Native Messaging hosts.

I'm not an expert on using Rust without a regular toolchain install, but my best guess is that problem is that you don't have the rustc executable placed in a directory that's in your PATH so Cargo can find it. You'll also need to do something about telling it where to find the standard library, but I don't know how that works.

You should definitely focus on getting cargo -Zscript working instead of trying to use rustc directly.

1 Like

That's what my goal is. I know zero (0) Rust, so I am starting with an algorithm I have written in multiple programming languages.

I'll rewrite to use on the Rust standard library as I go along. Right now I'm just trying to execute the existing .rs script.

You've said that you wanted to use no dependencies, and also said that you want to execute the code you have. These are incompatible goals, because the code you have refers to libc, and Rust libc is a dependency. Pick one to pursue — you cannot have both.

1 Like

Well if cargo is dependent on rustc to do this, why can't we just use rustc directly?

I really cannot afford the expense of rust-docs at over 600 MB alone, and am not sure if the "minimal" install will remove that folder.

Right now I have to start with what I have.

You ain't gonna write the code for me. And I didn't ask for that.

I know the C version works, and I found the C to Rust converter.

As I said, my goal is to implement the Native Messaging host using Rust standard library alone.

I welcome contribution into the repository I linked to. I'll keep trying to learn as I go either way.

cargo is a tool to invoke rustc multiple times, with the right options, to compile non-trivial programs. They work together.

A rustup minimal install will not include anything you don't need.

The minimal profile includes as few components as possible to get a working compiler (rustc , rust-std , and cargo ).

Profiles - The rustup book

Those three pieces really are basically required, and rustup won't install things you don't need other than that (and itself).

1 Like

Well, there's rustup, too, evidently.

Right now I only have 417 MB of disk space on this device. In previous attempts I have ran out of disk space trying to install even the minimal Rust toolchain, which has prevented me from taking Rust for a spin.