From 84ca63e8e73f481e13312a8a3557a42829d82913 Mon Sep 17 00:00:00 2001
From: Max Leonard Inden <mail@max-inden.de>
Date: Mon, 27 Jan 2025 20:04:36 +0100
Subject: [PATCH] fix(build.rs): use CARGO_CFG_TARGET_OS and target_os android

In a `build.rs` file `cfg(target_os = "linux")` refers to the target OS of the
`build.rs` binary. The environment variable `CARGO_CFG_TARGET_OS` refers to the
target OS of the final binary.

When cross-compiling, the target OS of the `build.rs` binary and the target OS
of the final binary are not the same. The `mtu`'s `build.rs` should use
`CARGO_CFG_TARGET_OS`.

In addition, `cfg(target_os = "linux")` does not include `android`. This
commit `cfg`s `linux` and `android` everywhere.
---
 Cargo.lock         |  2 +-
 Cargo.toml         |  4 +---
 build.rs           | 33 ++++++++++++++++++++-------------
 src/lib.rs         |  6 +++---
 src/routesocket.rs |  8 ++++----
 5 files changed, 29 insertions(+), 24 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index e7a87c0e..1a88ba5c 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -138,7 +138,7 @@ checksum = "903970ae2f248d7275214cf8f387f8ba0c4ea7e3d87a320e85493db60ce28616"
 
 [[package]]
 name = "mtu"
-version = "0.2.4"
+version = "0.2.5"
 dependencies = [
  "bindgen",
  "cfg_aliases",
diff --git a/Cargo.toml b/Cargo.toml
index d2ce23a5..d47964ff 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -7,7 +7,7 @@ homepage = "https://github.com/mozilla/mtu/"
 repository = "https://github.com/mozilla/mtu/"
 authors = ["The Mozilla Necko Team <necko@mozilla.com>"]
 readme = "README.md"
-version = "0.2.4"
+version = "0.2.5"
 edition = "2021"
 license = "MIT OR Apache-2.0"
 # Don't increase beyond what Firefox is currently using:
@@ -37,8 +37,6 @@ windows = { version = ">=0.58,<0.60", features = [
 [build-dependencies]
 cfg_aliases = { version = "0.2", default-features = false }
 mozbuild = { version = "0.1", default-features = false, optional = true }
-
-[target.'cfg(not(windows))'.build-dependencies]
 # Don't increase beyond what Firefox is currently using: https://searchfox.org/mozilla-central/source/Cargo.lock
 bindgen = { version = "0.69", default-features = false, features = ["runtime"] }
 
diff --git a/build.rs b/build.rs
index f137ace6..a635b6e9 100644
--- a/build.rs
+++ b/build.rs
@@ -6,7 +6,8 @@
 
 #![allow(clippy::unwrap_used)] // OK in build scripts.
 
-#[cfg(not(windows))]
+use std::env;
+
 const BINDINGS: &str = "bindings.rs";
 
 #[cfg(feature = "gecko")]
@@ -35,27 +36,34 @@ fn clang_args() -> Vec<String> {
     flags
 }
 
-#[cfg(not(any(feature = "gecko", target_os = "windows")))]
+#[cfg(not(feature = "gecko"))]
 const fn clang_args() -> Vec<String> {
     Vec::new()
 }
 
-#[cfg(not(windows))]
 fn bindgen() {
-    #[cfg(target_os = "linux")]
-    let bindings = bindgen::Builder::default()
-        .header_contents("rtnetlink.h", "#include <linux/rtnetlink.h>")
-        // Only generate bindings for the following types
-        .allowlist_type("rtattr|rtmsg|ifinfomsg|nlmsghdr");
-    #[cfg(not(target_os = "linux"))]
-    let bindings = bindgen::Builder::default()
+    let target_os = env::var("CARGO_CFG_TARGET_OS").expect("CARGO_CFG_TARGET_OS was not set");
+
+    if target_os == "windows" {
+        return;
+    }
+
+    let bindings = if matches!(target_os.as_str(), "linux" | "android") {
+        bindgen::Builder::default()
+            .header_contents("rtnetlink.h", "#include <linux/rtnetlink.h>")
+            // Only generate bindings for the following types
+            .allowlist_type("rtattr|rtmsg|ifinfomsg|nlmsghdr")
+    } else {
+        bindgen::Builder::default()
         .header_contents(
             "route.h",
             "#include <sys/types.h>\n#include <sys/socket.h>\n#include <net/route.h>\n#include <net/if.h>",
         )
         // Only generate bindings for the following types and items
         .allowlist_type("rt_msghdr|rt_metrics|if_data")
-        .allowlist_item("RTAX_MAX|RTM_GET|RTM_VERSION|RTA_DST|RTA_IFP");
+        .allowlist_item("RTAX_MAX|RTM_GET|RTM_VERSION|RTA_DST|RTA_IFP")
+    };
+
     let bindings = bindings
         .clang_args(clang_args())
         // Tell cargo to invalidate the built crate whenever any of the
@@ -73,7 +81,7 @@ fn bindgen() {
         .expect("Unable to generate bindings");
 
     // Write the bindings to the $OUT_DIR/$BINDINGS file.
-    let out_path = std::path::PathBuf::from(std::env::var("OUT_DIR").unwrap()).join(BINDINGS);
+    let out_path = std::path::PathBuf::from(env::var("OUT_DIR").unwrap()).join(BINDINGS);
     bindings
         .write_to_file(out_path.clone())
         .expect("Couldn't write bindings!");
@@ -102,6 +110,5 @@ fn main() {
         }
     }
 
-    #[cfg(not(windows))]
     bindgen();
 }
diff --git a/src/lib.rs b/src/lib.rs
index c90b85dd..5914ad5e 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -60,7 +60,7 @@ macro_rules! asserted_const_with_type {
 #[cfg(any(apple, bsd))]
 mod bsd;
 
-#[cfg(target_os = "linux")]
+#[cfg(any(target_os = "linux", target_os = "android"))]
 mod linux;
 
 #[cfg(target_os = "windows")]
@@ -71,7 +71,7 @@ mod routesocket;
 
 #[cfg(any(apple, bsd))]
 use bsd::interface_and_mtu_impl;
-#[cfg(target_os = "linux")]
+#[cfg(any(target_os = "linux", target_os = "android"))]
 use linux::interface_and_mtu_impl;
 #[cfg(target_os = "windows")]
 use windows::interface_and_mtu_impl;
@@ -133,7 +133,7 @@ mod test {
 
     #[cfg(any(apple, target_os = "freebsd",))]
     const LOOPBACK: &[NameMtu] = &[NameMtu(Some("lo0"), 16_384), NameMtu(Some("lo0"), 16_384)];
-    #[cfg(target_os = "linux")]
+    #[cfg(any(target_os = "linux", target_os = "android"))]
     const LOOPBACK: &[NameMtu] = &[NameMtu(Some("lo"), 65_536), NameMtu(Some("lo"), 65_536)];
     #[cfg(target_os = "windows")]
     const LOOPBACK: &[NameMtu] = &[
diff --git a/src/routesocket.rs b/src/routesocket.rs
index 6416c55d..96d3a75d 100644
--- a/src/routesocket.rs
+++ b/src/routesocket.rs
@@ -15,14 +15,14 @@ use libc::{fsync, read, socket, write, SOCK_RAW};
 
 use crate::unlikely_err;
 
-#[cfg(target_os = "linux")]
+#[cfg(any(target_os = "linux", target_os = "android"))]
 type AtomicRouteSocketSeq = std::sync::atomic::AtomicU32;
-#[cfg(target_os = "linux")]
+#[cfg(any(target_os = "linux", target_os = "android"))]
 type RouteSocketSeq = u32;
 
-#[cfg(not(target_os = "linux"))]
+#[cfg(not(any(target_os = "linux", target_os = "android")))]
 type AtomicRouteSocketSeq = std::sync::atomic::AtomicI32;
-#[cfg(not(target_os = "linux"))]
+#[cfg(not(any(target_os = "linux", target_os = "android")))]
 type RouteSocketSeq = i32;
 
 static SEQ: AtomicRouteSocketSeq = AtomicRouteSocketSeq::new(0);
