Wednesday, October 5, 2022
HomeGolangUtilizing CGO with Pkg-Config And Customized Dynamic Library Places

Utilizing CGO with Pkg-Config And Customized Dynamic Library Places


Earlier within the month I wrote a put up about utilizing C Dynamic Libraries in Go Applications. The article constructed a dynamic library in C and created a Go program that used it. This system labored however provided that the dynamic library was in the identical folder as this system.

This constraint doesn’t enable for using the go get command to obtain, construct and set up a working model of this system. I didn’t need to have any necessities to pre-install dependencies or run further scripts or instructions after the decision to go get. The Go device was not going to repeat the dynamic library into the bin folder and due to this fact I might not have the ability to run this system as soon as the go get command was full. This was merely unacceptable and there needed to be a solution to make this work.

The answer to this drawback was twofold. First, I wanted to make use of a bundle configuration file to specify the compiler and linker choices to CGO. Second, I wanted to set an setting variable so the working system might discover the dynamic library with no need to repeat it to the bin folder.

For those who look, you will note that a few of the normal libraries present a bundle configuration (.computer) file. A particular program known as pkg-config is utilized by the construct instruments, reminiscent of gcc, to retrieve info from these recordsdata.

If we glance in the usual areas for header recordsdata, /usr/lib or /usr/native/lib, you’ll find a folder known as pkgconfig. Package deal configuration recordsdata that exist in these areas may be discovered by the pkg-config program by default.

Screen Shot

Have a look at the libcrypto.computer file and you may see the format and the way it offers compiler and linker info.

This specific file is sweet to have a look at as a result of it consists of the naked minimal format and parameters which might be required.

To study extra about these recordsdata learn this net web page: www.freedesktop.org/wiki/Software program/pkg-config

The prefix variable on the prime of the file is essential. This variable specifies the bottom folder location the place the library and embody recordsdata are put in.

One thing essential to notice is that you just can’t use an setting variable to assist specify a path location. For those who do, you should have issues with the construct instruments finding any of the recordsdata it wants. The setting variables find yourself being offered to the construct instruments as a literal string. Keep in mind this for later as a result of it is crucial.

Run the pkg-config program from a Terminal session utilizing these parameters:

pkg-config –cflags –libs libcrypto

These parameters ask the pkg-config program to indicate the compiler and linker settings specified within the .computer file known as libcrypto.

That is what ought to be returned:

-lcrypto -lz

Let’s have a look at one of many bundle configuration recordsdata from ImageMagick that I downloaded and put in below /usr/native for a challenge I’m engaged on:

Screen Shot

This file is a little more complicated. You’ll discover it specifies that the MagickCode library can also be required and specifies extra flags reminiscent of environmental variables.

Once I run the pkg-config program on this file I get the next info again:

pkg-config –cflags –libs MagickWand

-fopenmp -DMAGICKCORE_HDRI_ENABLE=0 -DMAGICKCORE_QUANTUM_DEPTH=16
-I/usr/native/embody/ImageMagick-6  -L/usr/native/lib -lMagickWand-6.Q16
-lMagickCore-6.Q16

You possibly can see that the trail areas for the header and library recordsdata are totally certified paths. All the different flags outlined within the bundle configuration file are additionally offered.

Now that we all know a bit about bundle configuration recordsdata and use the pkg-config device, let’s check out the modifications I made to the challenge for the C Dynamic Libraries in Go Applications put up. This challenge is now utilizing a bundle configuration file and new cgo parameters.

Earlier than we start I need to apologize. The dynamic library that I constructed for this challenge will solely construct on the Mac. Learn the put up I simply talked about to grasp why. A pre-built model of the dynamic library already exists in model management. In case you are not engaged on a Mac, the challenge won’t construct correctly, nonetheless all of the concepts, settings and constructs nonetheless apply.

Open a Terminal window and run the next instructions:

cd $HOME
export GOPATH=$HOME/keyboard
export PKG_CONFIG_PATH=$GOPATH/src/github.com/goinggo/keyboard/pkgconfig
export DYLD_LIBRARY_PATH=$GOPATH/src/github.com/goinggo/keyboard/DyLib
go get github.com/goinggo/keyboard

After you run these instructions, you should have all of the code from the GoingGo keyboard repository downloaded below a subfolder known as keyboard inside your property listing.

Screen Shot

You’ll discover the Go device was capable of obtain, construct and set up the keyboard program. Regardless that the header file and dynamic library was not positioned within the default /usr or /usr/native folders.

Within the bin folder we’ve got the one executable program with out the dynamic library. The dynamic library is barely positioned within the DyLib folder.

There’s a new folder within the challenge now known as pkgconfig. This folder comprises the bundle configuration file that makes this all doable.

The primary.go supply code file has been modified to reap the benefits of the brand new bundle configuration file.

If we instantly swap to the bin folder and run this system, we’ll see that it really works.

cd $GOPATH/bin
./keyboard

Screen Shot

Whenever you begin this system, it instantly asks you to enter some keys. Kind a number of letters after which hit the letter q to give up this system.

That is solely doable if the OS can discover all of the dynamic libraries this program relies on.

Let’s check out the code modifications that make this doable. Have a look at the principle.go supply code file to see how we reference the brand new bundle configuration file.

That is the unique code from the primary put up. On this model I specified the compiler and linker flags immediately. The placement of the header and dynamic library are referenced with a relative path.

bundle predominant

/*
#cgo CFLAGS: -I../DyLib
#cgo LDFLAGS: -L. -lkeyboard
#embody <keyboard.h>
*/
import “C”

That is the brand new code. Right here I inform CGO to make use of the pkg-config program to search out the compiler and linker flags. The title of the bundle configuration file is specified on the finish.

bundle predominant

/*
#cgo pkg-config: –define-variable=prefix=. GoingGoKeyboard
#embody <keyboard.h>
*/
import “C”

Discover using the pkg-config program choice –define-variable. This feature is the trick to creating every part work. Let’s get again to that in a second.

Run the pkg-config program towards our new bundle configuration file:

pkg-config –cflags –libs GoingGoKeyboard

-I$GOPATH/src/github.com/goinggo/keyboard/DyLib
-L$GOPATH/src/github.com/goinggo/keyboard/DyLib -lkeyboard

Screen Shot
For those who look intently on the output from the decision, you will note one thing that I instructed you was flawed. The $GOPATH setting variable is being offered.

Open the bundle config file which is positioned within the pkgconfig folder and you will note the pkg-config program doesn’t lie. Proper there on the prime I’m setting the prefix variable to a path utilizing $GOPATH. So why is every part working?

Now run the command once more utilizing the identical –define-variable choice we’re utilizing in predominant.go:

pkg-config –cflags –libs GoingGoKeyboard –define-variable=prefix=.

-I./DyLib
-L./DyLib -lkeyboard 

Do you see the distinction? Within the first name to the pkg-config program we get again paths which have the literal $GOPATH string as a result of that’s how the prefix variable is ready. Within the second name we override the worth of the prefix variable to the present listing. What we get again is strictly what we’d like.

Keep in mind this setting variable that we set previous to utilizing the Go device?

PKG_CONFIG_PATH=$GOPATH/src/github.com/goinggo/keyboard/pkgconfig

The PKG_CONFIG_PATH setting variable tells the pkg-config program the place it may well discover bundle configuration recordsdata that aren’t positioned in any of the default areas. That is how the pkg-config program is ready to discover our GoingGoKeyboard.computer file.

The final thriller to elucidate is how the OS can discover the dynamic library after we run this system. Keep in mind this setting variable that we set previous to utilizing the Go device?

export DYLD_LIBRARY_PATH=$GOPATH/src/github.com/goinggo/keyboard/DyLib

The DYLD_LIBRARY_PATH setting variable tells the OS the place else it may well search for dynamic libraries.Putting in your dynamic libraries within the /usr/native folder retains issues easy. All the construct instruments are configured to look on this folder by default. Nevertheless, utilizing the default areas to your customized or third celebration libraries require further steps of set up previous to operating the Go instruments. Through the use of a bundle configuration file and passing the pkg-config program the choices it wants, Go together with CGO can deploy builds that can set up and be able to run immediately.

One thing else I didn’t point out is that you should utilize this method to put in third celebration libraries that you could be be attempting out in a temp location. This makes it actual straightforward to take away the library in the event you resolve you don’t need to use it.

If you wish to play with the code or ideas on a Home windows or Ubuntu machine, learn C Dynamic Libraries in Go Applications to learn to construct your individual dynamic libraries that you may experiment with.



RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments