Introduction
I recently encountered a problem. A component of traffic acquisition uses the /google/gopacket library. This library is used normally, but there is only one disadvantage. The compiled binary files depend on the dynamic library. This caused some trouble for the installation package to be compatible with multiple platforms, so I thought about how to link libpcap, an external method that relies on static libraries, to the executable program while compiling the Go program.
How is gopacket built?
Here we first intercept a small piece of source code (/google/gopack/pcap/pcap_unix.go). Here we can see that some of the compilation parameters are specified in cgo, where "-lpcap" is the name of the library specified to be linked. It can be said to be quite rough.
#cgo solaris LDFLAGS: -L /opt/local/lib -lpcap #cgo linux LDFLAGS: -lpcap #cgo dragonfly LDFLAGS: -lpcap #cgo freebsd LDFLAGS: -lpcap #cgo openbsd LDFLAGS: -lpcap #cgo netbsd LDFLAGS: -lpcap #cgo darwin LDFLAGS: -lpcap
Demo demo
// Simple example of using gopacket to catch packetspackage main import ( "/google/gopacket" "/google/gopacket/layers" "/google/gopacket/pcap" logger "/sirupsen/logrus" "log" ) const ( device = "ens32" SnapLen = int32(65535) // libpcap length of data received Promisc = false // Whether to enable mixed mode BPF = "icmp" ) func main() { handle, err := (device, SnapLen, Promisc, ) if err != nil { (err) } defer () // Compile and set bpf filtering rules if err = (BPF); err != nil { (err) } // Start getting traffic packetSource := (handle, ()) = true packetChan := () for packet := range packetChan { if () == nil { // icmp traffic icmpStreamHandle(packet) } else if ().LayerType() == { // tcp traffic tcpStreamHandle(packet) } else if ().LayerType() == { // udp traffic udpStreamHandle(packet) } } } func icmpStreamHandle(packet ) { ("get icmp packet") } func tcpStreamHandle(packet ) { } func udpStreamHandle(packet ) { }
Compile and ldd to view the usage of dependent libraries
[root@localhost ddk]# go build && ldd main .1 => (0x00007ffe965f3000) .1 => /lib64/.1 (0x00007f6be101f000) .0 => /lib64/.0 (0x00007f6be0e03000) .6 => /lib64/.6 (0x00007f6be0a35000) /lib64/.2 (0x00007f6be1260000) [root@localhost ddk]#
It's easy to see the dependencies on .1, the dynamic library
Prepare the static library
Find your corresponding file, whether it is by installing the libpcap-devel (libpcap-dev) library or building it directly from scratch. Here has been rebuilt as an example:
yum install -y gcc flex byacc cd /usr/local/source wget /release/libpcap-1.9. tar zxvf libpcap-1.9. cd libpcap-1.9.1 && ./configure && make
Specify the compile parameters
"-lpcap" parameter can be used to link dynamic libraries or static libraries. Dynamic libraries are preferred, so let the go compiler execute the path of the search library at compile time and place the static library under the path.
[root@localhost ddk]# CGO_LDFLAGS="-g -O2 -L/usr/local/source/libpcap-1.9.1 -I/usr/local/source/libpcap-1.9.1" go build -ldflags '-w -s' -o main [root@localhost ddk]# ldd main .1 => (0x00007fff6cde4000) .0 => /lib64/.0 (0x00007f1e767fa000) .6 => /lib64/.6 (0x00007f1e7642c000) /lib64/.2 (0x00007f1e76a16000) [root@localhost ddk]#
A little explanation of this compiled commandCGO_LDFLAGS="-g -O2 -L/usr/local/source/libpcap-1.9.1 -I/usr/local/source/libpcap-1.9.1" go build -ldflags '-w -s' -o main
. The CGO_LDFLAGS environment variable is used to specify the parameters of cgo during construction, -L specifies the location of the dynamic and static library, and -I specifies the specified path of the source terminal file.-ldflags '-w -s'
It is used to remove debug and symbol table information, and it is okay not to add it.
Now we can see that the dependency on the dynamic library has disappeared because libpcap has been linked into the program compiled by go in a static library.
This is the end of this article about the solution to avoid introducing external dynamic libraries when GO compiling. For more relevant content on GO compilation dynamic libraries, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!