Golang使用pkg-config自动获取头文件和链接库的方法
生活随笔
收集整理的這篇文章主要介紹了
Golang使用pkg-config自动获取头文件和链接库的方法
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
? ?為了能夠重用已有的C語言庫,我們在使用Golang開發(fā)項目或系統(tǒng)的時候難免會遇到Go和C語言混合編程,這時很多人都會選擇使用cgo。 話說cgo這個東西可算得上是讓人又愛又恨,好處在于它可以讓你快速重用已有的C語言庫,無需再用Golang重造一遍輪子,而壞處就在于它會在一定程度 上削弱你的系統(tǒng)性能。關于cgo的種種劣跡,Dave Cheney大神在他的博客上有一篇專門的文章《cgo is not Go》,感興趣的同學可以看一看。但話說回來,有時候為了快速開發(fā)滿足項目需求,使用cgo也實在是不得已而為之。
? ? ? ? ?在Golang中使用cgo調(diào)用C庫的時候,如果需要引用很多不同的第三方庫,那么使用#cgo CFLAGS:和#cgo LDFLAGS:的方式會引入很多行代碼。首先這會導致代碼很丑陋,最重要的是如果引用的不是標準庫,頭文件路徑和庫文件路徑寫死的話就會很麻煩。一旦第 三方庫的安裝路徑變化了,Golang的代碼也要跟著變化,所以使用pkg-config無疑是一種更為優(yōu)雅的方法,不管庫的安裝路徑有何變化,我們都不 需要修改Go代碼,接下來本博主就用一個簡單的例子來說明如何在cgo命令中使用pkg-config。 ? ? ? ? ?首先假定我們在路徑/home/ubuntu/third-parties/hello下安裝了一個名稱為hello的第三方C語言庫,其目錄結構如下所示,在hello_world.h中只定義了一個接口函數(shù)hello,該函數(shù)接收一個char *字符串作為變量并調(diào)用printf將其打印到標準輸出。 ? # tree /home/ubuntu/third-parties/hello/ /home/ubuntu/third-parties/hello/ ├── include │ ? └── hello_world.h └── lib ? ? ├── libhello.so ? ? └── pkgconfig ? ? ? ? └── hello.pc ? ? ? ? ?為了保證pkg-config能夠找到這個C語言庫,我們要為這個庫生成一個描述文件,也就是lib/pkgconfig目錄下的hello.pc,其內(nèi)容如下,有不了解該配置文件內(nèi)容的看客們可以去搜索一下pkg-config的相關文檔。 ? # cat hello.pc? prefix=/home/ubuntu/third-parties/hello exec_prefix=${prefix} libdir=${exec_prefix}/lib includedir=${exec_prefix}/include Name: hello Description: The hello library just for testing pkgconfig Version: 0.1 Libs: -lhello -L${libdir} Cflags: -I${includedir} ? ? ? ? ?完成pkg-config描述文件的創(chuàng)建后,還需要將該描述文件的路徑信息添加到PKG_CONFIG_PATH環(huán)境變量中,只有這樣 pkg-config才能正確獲取這個C語言庫的相關信息。此外,我們還需要將該C語言庫的庫文件路徑添加到LD_LIBRARY_PATH環(huán)境變量中, 具體命令如下: ? # export PKG_CONFIG_PATH=/home/ubuntu/third-parties/hello/lib/pkgconfig # pkg-config --list-all | grep libhello libhello ? ?libhello - The hello library just for testing pkgconfig # export LD_LIBRARY_PATH=/home/ubuntu/third-parties/hello/lib ? ? ? ? ?在完成以上一系列準備工作之后,我們就可以開始編寫Golang代碼了,以下是Golang調(diào)用C語言接口的代碼示例,我們只需要#cgo pkg-config: libhello和#include < hello_world.h >兩行語句即可實現(xiàn)對hello函數(shù)的調(diào)用。如果C語言庫的安裝路徑發(fā)生了變化,只需修改hello.pc這個描述文件即可,Golang代碼無需重新修改和編譯。 ? package main // #cgo pkg-config: libhello // #include < stdlib.h > // #include < hello_world.h > import "C" import ( "unsafe" ) func main() { msg := "Hello, world!" cmsg := C.CString(msg) C.hello(cmsg) C.free(unsafe.Pointer(cmsg)) } ? ? ? ? ?最后,編譯該程序代碼,查看可執(zhí)行程序是否正確鏈接了C語言庫,執(zhí)行程序驗證能否正確調(diào)用庫函數(shù)功能。 ? # go build hello_world.go? # ldd hello_world linux-vdso.so.1 => ?(0x00007ffff63d3000) libhello.so => /home/ubuntu/third-parties/hello/lib/libhello.so (0x00007fc31c0e1000) libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fc31bec3000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fc31bafe000) ? ? ? ? /lib64/ld-linux-x86-64.so.2 (0x00007fc31c2e3000) # ./hello_world? Hello, world! ? ? ? ? ?在以上步驟中需要關注的有兩個地方:1)創(chuàng)建C語言庫的pkg-config配置文件并將配置文件的路徑添加到環(huán)境變量 PKG_CONFIG_PATH中;2)C語言庫文件的路徑添加到環(huán)境變量LD_LIBRARY_PATH中,如果沒有這一步,Go語言程序可以編譯成 功,但是可執(zhí)行文件無法正確連接到C語言庫,會出現(xiàn)如下情況: ? # ldd hello_world linux-vdso.so.1 => ?(0x00007fffa49e2000) libhello.so => not found libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007feb0fe93000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007feb0face000) ? ? ? ? /lib64/ld-linux-x86-64.so.2 (0x00007feb100b1000)轉(zhuǎn)載于:https://www.cnblogs.com/satng/p/5538926.html
總結
以上是生活随笔為你收集整理的Golang使用pkg-config自动获取头文件和链接库的方法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: jmeter中文版新手入门教程
- 下一篇: 谭浩强C语言程序设计第五版第七章例题