Open azureskyL opened 4 years ago
Try this
CGO_LDFLAGS+="-Wl,-static -L/usr/lib/x86_64-linux-gnu/libpcap.a -lpcap -Wl,-Bdynamic" go build
This will statically link libpcap
into your go binary. Make sure you provide correct location of libpcap.a
file.
@jandos Sorry for the late reply, I tried it, but new problems appeared.
$ locate libpcap.a /home/zxcasd/libpcap-1.4.0/libpcap.a /usr/lib/x86_64-linux-gnu/libpcap.a /usr/local/lib/libpcap.a $ CGO_LDFLAGS+="-Wl,-static -L/usr/lib/x86_64-linux-gnu/libpcap.a -lpcap -Wl,-Bdynamic" go build main.go # github.com/google/gopacket/pcap /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/libpcap.a(pcap.o): In function `pcap_set_immediate_mode': (.text+0x850): multiple definition of `pcap_set_immediate_mode' /tmp/go-build482533506/b111/_x002.o:/home/zxcasd/go/src/github.com/google/gopacket/pcap/pcap_unix.go:52: first defined here /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/libpcap.a(pcap.o): In function `pcap_set_tstamp_precision': (.text+0x8e0): multiple definition of `pcap_set_tstamp_precision' /tmp/go-build482533506/b111/_x002.o:/home/zxcasd/go/src/github.com/google/gopacket/pcap/pcap_unix.go:78: first defined here /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/libpcap.a(pcap.o): In function `pcap_get_tstamp_precision': (.text+0x980): multiple definition of `pcap_get_tstamp_precision' /tmp/go-build482533506/b111/_x002.o:/home/zxcasd/go/src/github.com/google/gopacket/pcap/pcap_unix.go:85: first defined here /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/libpcap.a(savefile.o): In function `pcap_fopen_offline_with_tstamp_precision': (.text+0x2e0): multiple definition of `pcap_fopen_offline_with_tstamp_precision' /tmp/go-build482533506/b111/_x002.o:/home/zxcasd/go/src/github.com/google/gopacket/pcap/pcap_unix.go:74: first defined here /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/libpcap.a(savefile.o): In function `pcap_open_offline_with_tstamp_precision': (.text+0x4f0): multiple definition of `pcap_open_offline_with_tstamp_precision' /tmp/go-build482533506/b111/_x002.o:/home/zxcasd/go/src/github.com/google/gopacket/pcap/pcap_unix.go:69: first defined here collect2: error: ld returned 1 exit status
I also tried these commands, but the result is the same.
$ CGO_LDFLAGS+="-Wl,-static -L/home/zxcasd/libpcap-1.4.0/libpcap.a -lpcap -Wl,-Bdynamic" go build main.go $ CGO_LDFLAGS+="-Wl,-static -L/usr/local/lib/libpcap.a -lpcap -Wl,-Bdynamic" go build main.go
You should build a statically compiled binary if you want portability. Try this:
export PCAPV=1.9.1
wget http://www.tcpdump.org/release/libpcap-$PCAPV.tar.gz && \
tar xvf libpcap-$PCAPV.tar.gz && \
cd libpcap-$PCAPV && \
./configure --with-pcap=linux && \
make
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build --ldflags "-L ./libpcap-$PCAPV -linkmode external -extldflags \"-static\"" -a -o main .
You should build a statically compiled binary if you want portability. Try this:
export PCAPV=1.9.1 wget http://www.tcpdump.org/release/libpcap-$PCAPV.tar.gz && \ tar xvf libpcap-$PCAPV.tar.gz && \ cd libpcap-$PCAPV && \ ./configure --with-pcap=linux && \ make CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build --ldflags "-L ./libpcap-$PCAPV -linkmode external -extldflags \"-static\"" -a -o main .
new problems arise, and I didn't find any solution. where should put the folder libpcap-1.9.1 ?
$ CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build --ldflags "-L ./libpcap-$PCAPV -linkmode external -extldflags \"-static\"" -a -o main main1.5.go # github.com/google/gopacket/pcap ../go/src/github.com/google/gopacket/pcap/pcap.go:30:22: undefined: pcapErrorNotActivated ../go/src/github.com/google/gopacket/pcap/pcap.go:52:17: undefined: pcapTPtr ../go/src/github.com/google/gopacket/pcap/pcap.go:64:10: undefined: pcapPkthdr
...in my case, after building libpcap, CGO_LDFLAGS+="-L/path/to/libpcap" go build -ldflags="-s -w" main.go
Ie. a simplified version of what jandos said... (as i didn't needed to pull other C libs afterwards). With disabled cgo, i got various complaints (from libc?)... but i didn't researched into it further.
i meet the same issue,it's hard encoded. https://github.com/google/gopacket/blob/master/pcap/pcap_unix.go
/*
so you just need do it like this:
yum install libpcap-devel -y
[root@hk libai]# cat a.go
package main
import (
"fmt"
_ "github.com/google/gopacket"
_ "github.com/google/gopacket/pcap"
)
func main() {
fmt.Println("It works!")
}
[root@hk libai]#go run a.go
# github.com/google/gopacket/pcap
../go/pkg/mod/github.com/google/gopacket@v1.1.17/pcap/pcap_unix.go:34:18: fatal error: pcap.h: No such file or directory
#include <pcap.h>
^
compilation terminated.
[root@hk libai]# yum install libpcap-devel -y
Loaded plugins: fastestmirror
Determining fastest mirrors
....
Transaction test succeeded
Running transaction
Installing : 14:libpcap-devel-1.5.3-11.el7.x86_64 1/1
Verifying : 14:libpcap-devel-1.5.3-11.el7.x86_64 1/1
Installed:
libpcap-devel.x86_64 14:1.5.3-11.el7
Complete!
[root@hk libai]# go run a.go
It works!
@NietzscheX you just built a dynamically linked binary.
The OP needs to do something like this:
LDFLAGS='-l/usr/lib/libpcap.a' CGO_ENABLED=1 \
go build -ldflags '-linkmode external -extldflags -static' -o static-binary cmd/*.go
basically this tells go, to use CGO and statically link everything and points at the libpcap archive. Note that with modern gcc, this isn't a perfect solution. You'll end up with the following warnings because you can't link in NSS:
/usr/bin/ld: /tmp/go-link-421168096/000009.o: in function `mygetgrouplist':
/build/golang-1.14-d9PooB/golang-1.14-1.14.3/src/os/user/getgrouplist_unix.go:16: warning: Using 'getgrouplist' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/bin/ld: /tmp/go-link-421168096/000008.o: in function `mygetgrgid_r':
/build/golang-1.14-d9PooB/golang-1.14-1.14.3/src/os/user/cgo_lookup_unix.go:38: warning: Using 'getgrgid_r' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/bin/ld: /tmp/go-link-421168096/000008.o: in function `mygetgrnam_r':
/build/golang-1.14-d9PooB/golang-1.14-1.14.3/src/os/user/cgo_lookup_unix.go:43: warning: Using 'getgrnam_r' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/bin/ld: /tmp/go-link-421168096/000008.o: in function `mygetpwnam_r':
/build/golang-1.14-d9PooB/golang-1.14-1.14.3/src/os/user/cgo_lookup_unix.go:33: warning: Using 'getpwnam_r' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/bin/ld: /tmp/go-link-421168096/000008.o: in function `mygetpwuid_r':
/build/golang-1.14-d9PooB/golang-1.14-1.14.3/src/os/user/cgo_lookup_unix.go:28: warning: Using 'getpwuid_r' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/bin/ld: /tmp/go-link-421168096/000006.o: in function `_cgo_26061493d47f_C2func_getaddrinfo':
/tmp/go-build/cgo-gcc-prolog:58: warning: Using 'getaddrinfo' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/libpcap.a(nametoaddr.o): in function `pcap_nametoaddr':
(.text+0x9): warning: Using 'gethostbyname' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/libpcap.a(nametoaddr.o): in function `pcap_nametonetaddr':
(.text+0x101): warning: Using 'getnetbyname_r' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/libpcap.a(nametoaddr.o): in function `pcap_nametoproto':
(.text+0x583): warning: Using 'getprotobyname_r' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
So there are certain system calls which aren't linkable and will cause crashes. So don't call those above listed functions. Obviously, if anyone has a better way of doing it I'm all ears...
export PCAPV=1.9.1 wget http://www.tcpdump.org/release/libpcap-$PCAPV.tar.gz && \ tar xvf libpcap-$PCAPV.tar.gz && \ cd libpcap-$PCAPV && \ ./configure --with-pcap=linux && \ make
i figured out from @charles-d-burton script, add the following env variables:
export LD_LIBRARY_PATH="-L<pcap path>/libpcap-$PCAPV"
export CGO_LDFLAGS="-L<pcap path>/libpcap-$PCAPV"
export CGO_CPPFLAGS="-I<pcap path>/libpcap-$PCAPV"
go build .
Musl-cross:
export PATH=/home/x/.local/opt/x86_64-linux-musl-cross/bin/:$PATH
git clone https://github.com/thom311/libnl && cd libnl ./configure --host=x86_64-pc-linux-gnu CC=x86_64-linux-musl-gcc --prefix=/home/x/.local/opt/x86_64-linux-musl-cross/x86_64-linux-musl make && make install
git clone git@github.com:the-tcpdump-group/libpcap.git&& cd libpcap ./configure --host=x86_64-pc-linux-gnu CC=x86_64-linux-musl-gcc --prefix=/home/x/.local/opt/x86_64-linux-musl-cross/x86_64-linux-musl --with-pcap=linux make && make install
CGO_ENABLED=1 CC=x86_64-linux-musl-gcc GOOS=linux GOARCH=amd64 go build –ldflags “-linkmode external -extldflags ‘-static -lnl-genl-3 -lnl-3’” -o app main.go
my
go
program importgopacket
, I usego build -o main main.go
to build program, system isUbuntu 18.04.3 LTS
withgo version go1.13.1 linux/amd64
. when I run the linux executeable programmain
inCentOS Release 6.10 (Final)
Kernel Linux 2.6.32-754.el6.x86_64, which does install go enveriment, it report an error:because CentOS doesn't contain
libpcap
, my goal is to run go program on the CentOS which dosen't havalibpcap
or go enveriment. Is there any way to package libraries 'libpcap' into go programs? How ?