From 79304f4affb0c3d9d6640e6123b8dcfd54a32005 Mon Sep 17 00:00:00 2001 From: Marshall Pierce Date: Tue, 4 Nov 2025 18:35:58 +0000 Subject: [PATCH] Don't automatically link to libpcap pkg-config's default config will output `rustc-link-lib` when it finds a package. However, per this project's readme, linkage is the responsibility of the user, so it seems like merely probing for the version should not change any subsequent build config. Lines previously present in build.rs output that are now gone: ``` [pcap 2.3.0] cargo:rustc-link-search=native=/usr/lib/x86_64-linux-gnu [pcap 2.3.0] cargo:rustc-link-lib=pcap ``` Similarly, the `#[link(name = "pcap")]` in `raw` was making dependent binaries automatically link to libpcap.so. --- build.rs | 1 + examples/easylisten.rs | 3 +++ examples/getdevices.rs | 3 +++ examples/getstatistics.rs | 3 +++ examples/helpers/link.rs | 9 +++++++++ examples/iterprint.rs | 3 +++ examples/lendingiterprint.rs | 3 +++ examples/listenlocalhost.rs | 3 +++ examples/loop.rs | 3 +++ examples/nfbpfcompile.rs | 3 +++ examples/savefile.rs | 3 +++ examples/savemultiplefiles.rs | 3 +++ examples/stdin.rs | 3 +++ examples/streamecho.rs | 3 +++ examples/streamlisten.rs | 3 +++ examples/streamlisten_mt.rs | 3 +++ src/raw.rs | 2 -- tests/lib.rs | 8 ++++++++ tests/tap_tests.rs | 3 +++ 19 files changed, 63 insertions(+), 2 deletions(-) create mode 100644 examples/helpers/link.rs diff --git a/build.rs b/build.rs index cef094a25..0ba31f5f1 100644 --- a/build.rs +++ b/build.rs @@ -197,6 +197,7 @@ fn main() { fn from_pkg_config() -> Result { let mut config = pkg_config::Config::new(); + config.cargo_metadata(false); // If the user has went out of their way to specify LIBPCAP_VER (even though // LIBCAP_LIBDIR wasn't set), respect it. Otherwise fall back to any version // as long as it's supported. diff --git a/examples/easylisten.rs b/examples/easylisten.rs index de385ae91..f210a15ff 100644 --- a/examples/easylisten.rs +++ b/examples/easylisten.rs @@ -1,3 +1,6 @@ +#[path = "helpers/link.rs"] +mod link; + fn main() { // get the default Device let device = pcap::Device::lookup() diff --git a/examples/getdevices.rs b/examples/getdevices.rs index a2fcdce33..b66f7a05d 100644 --- a/examples/getdevices.rs +++ b/examples/getdevices.rs @@ -1,3 +1,6 @@ +#[path = "helpers/link.rs"] +mod link; + fn main() { // list all of the devices pcap tells us are available for device in pcap::Device::list().expect("device lookup failed") { diff --git a/examples/getstatistics.rs b/examples/getstatistics.rs index d63f4266f..1be9ca694 100644 --- a/examples/getstatistics.rs +++ b/examples/getstatistics.rs @@ -1,3 +1,6 @@ +#[path = "helpers/link.rs"] +mod link; + fn main() { // get the default Device let device = pcap::Device::lookup() diff --git a/examples/helpers/link.rs b/examples/helpers/link.rs new file mode 100644 index 000000000..e2dcfd37a --- /dev/null +++ b/examples/helpers/link.rs @@ -0,0 +1,9 @@ +//! Trigger linking against the appropriate library for example binaries. + +#[cfg(not(windows))] +#[link(name = "pcap")] +extern "C" {} + +#[cfg(windows)] +#[link(name = "wpcap")] +extern "C" {} diff --git a/examples/iterprint.rs b/examples/iterprint.rs index e1f9cde4e..3cdb48724 100644 --- a/examples/iterprint.rs +++ b/examples/iterprint.rs @@ -2,6 +2,9 @@ use pcap::{Capture, Device, Packet, PacketCodec, PacketHeader}; use std::error; +#[path = "helpers/link.rs"] +mod link; + /// Represents a owned packet #[derive(Debug, Clone, PartialEq, Eq)] pub struct PacketOwned { diff --git a/examples/lendingiterprint.rs b/examples/lendingiterprint.rs index 6539c7867..27aff76a9 100644 --- a/examples/lendingiterprint.rs +++ b/examples/lendingiterprint.rs @@ -4,6 +4,9 @@ use std::error; use gat_std::gatify; +#[path = "helpers/link.rs"] +mod link; + #[gatify] fn main() -> Result<(), Box> { let device = Device::lookup()?.ok_or("no device available")?; diff --git a/examples/listenlocalhost.rs b/examples/listenlocalhost.rs index 917729c09..8a07376a7 100644 --- a/examples/listenlocalhost.rs +++ b/examples/listenlocalhost.rs @@ -1,3 +1,6 @@ +#[path = "helpers/link.rs"] +mod link; + fn main() { // listen on the device named "any", which is only available on Linux. This is only for // demonstration purposes. diff --git a/examples/loop.rs b/examples/loop.rs index 9344b29e3..006c0364a 100644 --- a/examples/loop.rs +++ b/examples/loop.rs @@ -1,3 +1,6 @@ +#[path = "helpers/link.rs"] +mod link; + fn main() { // get the default Device let device = pcap::Device::lookup() diff --git a/examples/nfbpfcompile.rs b/examples/nfbpfcompile.rs index da2fe7dfa..258badd36 100644 --- a/examples/nfbpfcompile.rs +++ b/examples/nfbpfcompile.rs @@ -7,6 +7,9 @@ use pcap::{BpfProgram, Capture, Linktype}; use std::env; use std::process; +#[path = "helpers/link.rs"] +mod link; + fn main() { let (layertype, prog) = match env::args().len() { 2 => ("RAW".to_string(), env::args().nth(1).unwrap()), diff --git a/examples/savefile.rs b/examples/savefile.rs index 1228048f6..3194b5c96 100644 --- a/examples/savefile.rs +++ b/examples/savefile.rs @@ -1,5 +1,8 @@ use pcap::*; +#[path = "helpers/link.rs"] +mod link; + fn main() { { // open capture from default device diff --git a/examples/savemultiplefiles.rs b/examples/savemultiplefiles.rs index 919cd10b0..8c8cd7884 100644 --- a/examples/savemultiplefiles.rs +++ b/examples/savemultiplefiles.rs @@ -1,5 +1,8 @@ use pcap::Capture; +#[path = "helpers/link.rs"] +mod link; + fn main() { // get the default Device let device = pcap::Device::lookup().unwrap().unwrap(); diff --git a/examples/stdin.rs b/examples/stdin.rs index 2391aeb69..d3b437dd0 100644 --- a/examples/stdin.rs +++ b/examples/stdin.rs @@ -4,6 +4,9 @@ //! tcpdump -i en0 -U -w - | cargo run --example stdin //! +#[path = "helpers/link.rs"] +mod link; + #[cfg(not(windows))] mod inner { use pcap::{Packet, PacketCodec, PacketHeader}; diff --git a/examples/streamecho.rs b/examples/streamecho.rs index 38f5d82ef..0ff298b69 100644 --- a/examples/streamecho.rs +++ b/examples/streamecho.rs @@ -6,6 +6,9 @@ use futures::StreamExt; use pcap::{Active, Capture, Device, Error, Packet, PacketCodec, PacketStream}; use std::error; +#[path = "helpers/link.rs"] +mod link; + // Simple codec that returns owned copies, since the result may not // reference the input packet. pub struct BoxCodec; diff --git a/examples/streamlisten.rs b/examples/streamlisten.rs index c665f68ec..412ca1d8d 100644 --- a/examples/streamlisten.rs +++ b/examples/streamlisten.rs @@ -5,6 +5,9 @@ use futures::StreamExt; use pcap::{Active, Capture, Device, Error, Packet, PacketCodec, PacketStream}; +#[path = "helpers/link.rs"] +mod link; + pub struct SimpleDumpCodec; impl PacketCodec for SimpleDumpCodec { diff --git a/examples/streamlisten_mt.rs b/examples/streamlisten_mt.rs index 529832fa8..8b24b80a2 100644 --- a/examples/streamlisten_mt.rs +++ b/examples/streamlisten_mt.rs @@ -2,6 +2,9 @@ use futures::StreamExt; use pcap::{Active, Capture, Device, Error, Packet, PacketCodec, PacketStream}; use std::error; +#[path = "helpers/link.rs"] +mod link; + pub struct SimpleDumpCodec; impl PacketCodec for SimpleDumpCodec { diff --git a/src/raw.rs b/src/raw.rs index 0e1803684..b229aaece 100644 --- a/src/raw.rs +++ b/src/raw.rs @@ -260,7 +260,6 @@ pub mod ffi { pub mod ffi_unix { use super::*; - #[link(name = "pcap")] extern "C" { // pub fn pcap_inject(arg1: *mut pcap_t, arg2: *const c_void, arg3: size_t) -> c_int; pub fn pcap_set_rfmon(arg1: *mut pcap_t, arg2: c_int) -> c_int; @@ -287,7 +286,6 @@ pub mod ffi_windows { pub const WINPCAP_MINTOCOPY_DEFAULT: c_int = 16000; - #[link(name = "wpcap")] extern "C" { pub fn pcap_setmintocopy(arg1: *mut pcap_t, arg2: c_int) -> c_int; pub fn pcap_getevent(p: *mut pcap_t) -> HANDLE; diff --git a/tests/lib.rs b/tests/lib.rs index a475beb8a..5e636b85a 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -19,6 +19,14 @@ type suseconds_t = libc::suseconds_t; #[allow(non_camel_case_types)] type suseconds_t = libc::c_long; +#[cfg(not(windows))] +#[link(name = "pcap")] +extern "C" {} + +#[cfg(windows)] +#[link(name = "wpcap")] +extern "C" {} + fn capture_from_test_file(file_name: &str) -> Capture { let path = Path::new("tests/data/").join(file_name); Capture::from_file(path).unwrap() diff --git a/tests/tap_tests.rs b/tests/tap_tests.rs index 5f031fcb0..d046a0eb1 100644 --- a/tests/tap_tests.rs +++ b/tests/tap_tests.rs @@ -33,6 +33,9 @@ #[cfg(not(windows))] mod tests { + #[link(name = "pcap")] + extern "C" {} + use etherparse::{PacketBuilder, PacketHeaders}; use pcap::Capture; use tun_tap::Iface;