亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

解決GO編譯時(shí)避免引入外部動(dòng)態(tài)庫(kù)的問(wèn)題

 更新時(shí)間:2022年10月20日 15:21:51   作者:oscar.chen  
最近碰到一個(gè)問(wèn)題,有一個(gè)流量采集的組件中使用到了github.com/google/gopacket 這個(gè)庫(kù),這個(gè)庫(kù)使用一切正常,但是唯獨(dú)有一個(gè)缺點(diǎn),編譯后的二進(jìn)制文件依賴(lài)于libpcap.so的動(dòng)態(tài)庫(kù),這篇文章主要介紹了GO編譯時(shí)避免引入外部動(dòng)態(tài)庫(kù)的解決方法,需要的朋友可以參考下

簡(jiǎn)介

最近碰到一個(gè)問(wèn)題,有一個(gè)流量采集的組件中使用到了github.com/google/gopacket 這個(gè)庫(kù),這個(gè)庫(kù)使用一切正常,但是唯獨(dú)有一個(gè)缺點(diǎn),編譯后的二進(jìn)制文件依賴(lài)于libpcap.so的動(dòng)態(tài)庫(kù)。這為安裝包兼容多個(gè)平臺(tái)造成了一定的困擾,于是便想著如何把libpcap這個(gè)外部依賴(lài)已靜態(tài)庫(kù)的方式在go程序編譯的同時(shí)link進(jìn)可執(zhí)行程序。

gopacket是如何構(gòu)建的?

此處先截取一小片源碼(github.com/google/gopacket/pcap/pcap_unix.go),此處可以看到在cgo中指定了部分的編譯參數(shù),其中的 "-lpcap" 便是指定link到的庫(kù)的名稱(chēng)。可以說(shuō)是相當(dāng)?shù)拇直┝恕?/p>

#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

// 使用gopacket 抓包的簡(jiǎn)單示例
package main

import (
	"github.com/google/gopacket"
	"github.com/google/gopacket/layers"
	"github.com/google/gopacket/pcap"
	logger "github.com/sirupsen/logrus"
	"log"
)

const (
	device  = "ens32"
	SnapLen = int32(65535) // libpcap 接收數(shù)據(jù)的長(zhǎng)度
	Promisc = false        // 是否開(kāi)啟混雜模式
	BPF     = "icmp"
)

func main() {
	handle, err := pcap.OpenLive(device, SnapLen, Promisc, pcap.BlockForever)
	if err != nil {
		log.Fatal(err)
	}
	defer handle.Close()

	// 編譯并設(shè)置bpf過(guò)濾規(guī)則
	if err = handle.SetBPFFilter(BPF); err != nil {
		log.Fatal(err)
	}

	// 開(kāi)始獲取流量
	packetSource := gopacket.NewPacketSource(handle, handle.LinkType())
	packetSource.NoCopy = true
	packetChan := packetSource.Packets()

	for packet := range packetChan {
		if packet.TransportLayer() == nil {
			// icmp流量
			icmpStreamHandle(packet)
		} else if packet.TransportLayer().LayerType() == layers.LayerTypeTCP {
			// tcp流量
			tcpStreamHandle(packet)
		} else if packet.TransportLayer().LayerType() == layers.LayerTypeUDP {
			// udp流量
			udpStreamHandle(packet)
		}
	}
}

func icmpStreamHandle(packet gopacket.Packet) {
	logger.Info("get icmp packet")
}
func tcpStreamHandle(packet gopacket.Packet) {
}
func udpStreamHandle(packet gopacket.Packet) {
}

編譯并ldd查看依賴(lài)庫(kù)的使用情況

[root@localhost ddk]# go build main.go && ldd main
	linux-vdso.so.1 =>  (0x00007ffe965f3000)
	libpcap.so.1 => /lib64/libpcap.so.1 (0x00007f6be101f000)
	libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f6be0e03000)
	libc.so.6 => /lib64/libc.so.6 (0x00007f6be0a35000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f6be1260000)
[root@localhost ddk]# 

很容易的查看到對(duì)libpcap.so.1 這個(gè)動(dòng)態(tài)庫(kù)的依賴(lài)

準(zhǔn)備靜態(tài)庫(kù)

找到你的libpcap.so 對(duì)應(yīng)的libpcap.a 文件,無(wú)論是通過(guò)安裝libpcap-devel(libpcap-dev)的庫(kù)還是直接從頭構(gòu)建。此處已重頭構(gòu)建為例:

yum install -y gcc flex byacc
cd /usr/local/source
wget http://www.tcpdump.org/release/libpcap-1.9.1.tar.gz
tar zxvf libpcap-1.9.1.tar.gz
cd libpcap-1.9.1 && ./configure && make

指定編譯參數(shù)

“-lpcap” 這個(gè)參數(shù)既可以用于鏈接動(dòng)態(tài)庫(kù)也可以用于鏈接靜態(tài)庫(kù),動(dòng)態(tài)庫(kù)優(yōu)先, 那么我我們讓go 編譯器在編譯時(shí)執(zhí)行搜索庫(kù)的路徑并把靜態(tài)庫(kù)放置于路徑下即可。

[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 main.go
[root@localhost ddk]# ldd main
	linux-vdso.so.1 =>  (0x00007fff6cde4000)
	libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f1e767fa000)
	libc.so.6 => /lib64/libc.so.6 (0x00007f1e7642c000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f1e76a16000)
[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 main.go。CGO_LDFLAGS 環(huán)境變量用于指定構(gòu)建時(shí)cgo的參數(shù),-L 指定了查找動(dòng)靜態(tài)庫(kù)的位置,-I 用于指定源碼頭文件的指定路徑,-ldflags '-w -s' 用于去除debug 和符號(hào)表的信息,不加也沒(méi)事。
現(xiàn)在我們可以看到對(duì)libpcap.so的動(dòng)態(tài)庫(kù)依賴(lài)消失了,因?yàn)閘ibpcap已靜態(tài)庫(kù)的方式鏈接進(jìn)了go編譯好的程序。

到此這篇關(guān)于GO編譯時(shí)避免引入外部動(dòng)態(tài)庫(kù)的解決方法的文章就介紹到這了,更多相關(guān)go編譯動(dòng)態(tài)庫(kù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 一文教你如何封裝安全的go

    一文教你如何封裝安全的go

    這篇文章主要給大家介紹了關(guān)于如何封裝安全go的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2022-02-02
  • Go語(yǔ)言Grpc?Stream的實(shí)現(xiàn)

    Go語(yǔ)言Grpc?Stream的實(shí)現(xiàn)

    本文主要介紹了Go語(yǔ)言Grpc?Stream的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-06-06
  • Go語(yǔ)言O(shè)RM框架構(gòu)造查詢(xún)條件示例詳解

    Go語(yǔ)言O(shè)RM框架構(gòu)造查詢(xún)條件示例詳解

    這篇文章主要為大家介紹了Go語(yǔ)言O(shè)RM框架構(gòu)造查詢(xún)條件示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • Gin golang web開(kāi)發(fā)模型綁定實(shí)現(xiàn)過(guò)程解析

    Gin golang web開(kāi)發(fā)模型綁定實(shí)現(xiàn)過(guò)程解析

    這篇文章主要介紹了Gin golang web開(kāi)發(fā)模型綁定實(shí)現(xiàn)過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-10-10
  • 詳解Go中的高效切片拼接和Go1.22提供的新方法

    詳解Go中的高效切片拼接和Go1.22提供的新方法

    在?Go?語(yǔ)言中,切片拼接是一項(xiàng)常見(jiàn)的操作,但如果處理不當(dāng),可能會(huì)導(dǎo)致性能問(wèn)題或意外的副作用,本文將詳細(xì)介紹幾種高效的切片拼接方法,希望對(duì)大家有所幫助
    2024-01-01
  • 我為什么喜歡Go語(yǔ)言(簡(jiǎn)潔的Go語(yǔ)言)

    我為什么喜歡Go語(yǔ)言(簡(jiǎn)潔的Go語(yǔ)言)

    從2000年至今,也寫(xiě)了11年代碼了,期間用過(guò)VB、Delphi、C#、C++、Ruby、Python,一直在尋找一門(mén)符合自己心意和理念的語(yǔ)言。我很在意寫(xiě)代碼時(shí)的手感和執(zhí)行的效率,所以在Go出現(xiàn)之前一直沒(méi)有找到
    2014-10-10
  • Go引用github包的詳細(xì)流程步驟

    Go引用github包的詳細(xì)流程步驟

    這篇文章主要給大家介紹了關(guān)于Go引用github包的詳細(xì)流程步驟,文中通過(guò)圖文介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Go具有一定的參考價(jià)值,需要的朋友可以參考下
    2024-02-02
  • golang控制結(jié)構(gòu)select機(jī)制及使用示例詳解

    golang控制結(jié)構(gòu)select機(jī)制及使用示例詳解

    這篇文章主要介紹了golang控制結(jié)構(gòu)select機(jī)制及使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-10-10
  • golang如何通過(guò)viper讀取config.yaml文件

    golang如何通過(guò)viper讀取config.yaml文件

    這篇文章主要介紹了golang通過(guò)viper讀取config.yaml文件,圍繞golang讀取config.yaml文件的相關(guān)資料展開(kāi)詳細(xì)內(nèi)容,需要的小伙伴可以參考一下
    2022-03-03
  • Go官方工具鏈用法詳解

    Go官方工具鏈用法詳解

    Go官方工具鏈工具要求所有的Go源代碼文件必須以.go后綴結(jié)尾。這里,我們假設(shè)一個(gè)最簡(jiǎn)單的Go程序放在hello.go的文件中,下面通過(guò)示例代碼給大家介紹Go官方工具鏈用法簡(jiǎn)介,需要的朋友可以參考下
    2021-10-10

最新評(píng)論