Compiling Reth on Freebsd

Since writing this post Reth has changed a lot and so does metrics-process which previously required a patch to compile on FreeBSD. I am happy to report that compiling Reth on FreeBSD has become much less painful, and below are the new instructions. I will keep the old content at the end for archival purposes.

Note that FreeBSD is not officially supported by Reth, so your mileage may vary.

There are four steps of the compilation process that break on FreeBSD as of commit ff56ce42d: compiling the dependencies metrics-process, jemallocator, reth-mdbx-sys; and linking.

Reth uses metrics-process to collect system metrics, but the package does not support FreeBSD yet. Fortunately in a recent version the package gained a new feature flag dummy that if enabled replaces the OS-specific implementation (which does not support FreeBSD) with a dummy no-op, so the package will compile on any OS. Apparently this is a no-op so no metrics will be collected, nor do I care, so it works well. It is necessary though to update Reth’s dependency to (1) use a more recent version of metrics-process that has this feature, and (2) enable the feature. This can be achieved with this patch.

diff --git a/bin/reth/Cargo.toml b/bin/reth/Cargo.toml
index 7cf23adbf..4b99695ef 100644
--- a/bin/reth/Cargo.toml
+++ b/bin/reth/Cargo.toml
@@ -68,7 +68,7 @@ confy.workspace = true
 toml = { workspace = true, features = ["display"] }

 # metrics
-metrics-process = "=1.0.14"
+metrics-process = { version = "1.2.0", features = ["dummy"] }

 # test vectors generation
 proptest.workspace = true
diff --git a/crates/node-core/Cargo.toml b/crates/node-core/Cargo.toml
index 308ae00b1..a5aa3d8de 100644
--- a/crates/node-core/Cargo.toml
+++ b/crates/node-core/Cargo.toml
@@ -57,7 +57,7 @@ tokio.workspace = true
 metrics-exporter-prometheus = "0.12.1"
 once_cell.workspace = true
 metrics-util = "0.15.0"
-metrics-process = "=1.0.14"
+metrics-process = { version = "1.2.0", features = ["dummy"] }
 metrics.workspace = true
 reth-metrics.workspace = true

jemallocator uses GNU make (gmake), so one needs to install it, and the package should then compile fine.

reth-mdbx-sys requires libclang at compile time, so one installs llvm.

Finally, during linking the linker will complain that it cannot locate symbols __cpu_indicator_init and __cpu_model. They are present in compiler-rt so one installs it. Cargo will not try to link with libgcc (which is a symlink to compiler-rt) though, so one needs to add

RUSTFLAGS="-C link-arg=-lgcc -Clink-arg=-static-libgcc"

when running cargo build. This is documented in Reth’s makefile but I personally find it very convoluted to use make when there is already Cargo.


Below is the old version of this post which describes a much more involved (and for sure redundant) process. The content is kept here only for archival purposes.

I recently decided to try Reth, the latest Blazing Fastâ„¢1 Ethereum execution client. I encountered a few errors when compiling it on FreeBSD, and was able to solve them. This blog post is a simple documentation of the process, and is basically a copy of the Github ticket I submitted. Note that FreeBSD is not officially supported by Reth, so your mileage may vary.

These are the steps I took.

diff --git a/src/collector.rs b/src/collector.rs
index 3b47870..3fd11d2 100644
--- a/src/collector.rs
+++ b/src/collector.rs
@@ -8,6 +8,9 @@ mod linux;
 #[path = "collector/windows.rs"]
 mod win;
 
+#[cfg(target_os = "freebsd")]
+mod freebsd;
+
 /// Process metrics
 /// https://prometheus.io/docs/instrumenting/writing_clientlibs/#process-metrics
 #[derive(Debug, Default, PartialEq)]
@@ -41,6 +44,9 @@ pub use linux::collect;
 #[cfg(target_os = "windows")]
 pub use win::collect;
 
+#[cfg(target_os = "freebsd")]
+pub use freebsd::collect;
+
 #[cfg(test)]
 mod tests {
     use super::*;
diff --git a/src/collector/freebsd.rs b/src/collector/freebsd.rs
new file mode 100644
index 0000000..fd3d6ec
--- /dev/null
+++ b/src/collector/freebsd.rs
@@ -0,0 +1,6 @@
+use super::Metrics;
+
+pub fn collect() -> Metrics {
+    let mut metrics = Metrics::default();
+    metrics
+}
diff --git a/Cargo.lock b/Cargo.lock
index 05c28fd0..f10b00ba 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -4259,8 +4259,6 @@ dependencies = [
 [[package]]
 name = "metrics-process"
 version = "1.0.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1c93f6ad342d3f7bc14724147e2dbc6eb6fdbe5a832ace16ea23b73618e8cc17"
 dependencies = [
  "libproc",
  "mach2",
diff --git a/Cargo.toml b/Cargo.toml
index 70f31199..b4f73230 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -193,3 +193,6 @@ tempfile = "3.8"
 proptest = "1.0"
 proptest-derive = "0.4"
 serial_test = "2"
+
+[patch.crates-io]
+metrics-process = { path = "/home/leiy/rs-metrics-process" }
diff --git a/bin/reth/Cargo.toml b/bin/reth/Cargo.toml
index 11ff97c0..2d28cc47 100644
--- a/bin/reth/Cargo.toml
+++ b/bin/reth/Cargo.toml
@@ -122,3 +122,4 @@ min-trace-logs = ["tracing/release_max_level_trace"]

 [build-dependencies]
 vergen = { version = "8.0.0", features = ["build", "cargo", "git", "gitcl"] }
+
diff --git a/bin/reth/build.rs b/bin/reth/build.rs
index b06bdf19..3c0b9885 100644
--- a/bin/reth/build.rs
+++ b/bin/reth/build.rs
@@ -3,6 +3,7 @@ use vergen::EmitBuilder;

 fn main() -> Result<(), Box<dyn Error>> {
     // Emit the instructions
+    println!("cargo:rustc-link-lib=static=gcc");
     EmitBuilder::builder()
         .git_sha(true)
         .build_timestamp()

As a side note, I also had to jump through a few hoops to compile Lighthouse, an Ethereum consensus client written in Rust. But the errors I encountered there were more straightforward to solve, so I will not document the solution here.


  1. Or is it Blazingly Fastâ„¢? I am not sure. I think I have seen both. Please confirm with your Rust sales representative. [return]