In order to be able to reuse the existing C language library, we will inevitably encounter go and C language mixed programming when using Golang development project or system, many people will choose to use CGO. Say CGO this thing can be considered to be a person to love and hate, the advantage is that it allows you to quickly reuse the existing C library, no need to re-build the wheel with Golang, and the downside is that it will to some extent weaken your system performance. About CGO's misdeeds, Dave Cheney the Great God has a special article on his blog, "CGO is not Go", interested students can take a look. But then again, sometimes in order to quickly develop to meet the needs of the project, the use of CGO is the last resort.
when using CGO to call C libraries in Golang, if you need to refer to many different third-party libraries, then using #cgo CFLAGS: and #cgo Ldflags: will introduce many lines of code. First, this can lead to ugly code, and most importantly, if you are referencing a library that is not standard, the header file path and the library file path will be cumbersome to write to. Once the installation path of the third-party library changes, the Golang code changes, so the use of pkg-config is undoubtedly a more elegant approach, no matter how the library's installation path changes, we do not need to modify the Go code, The blogger then uses a simple example to illustrate how to use pkg-config in the CGO command. First, suppose we install a third-party C-language library named Hello under Path/home/ubuntu/third-parties/hello, whose directory structure is shown below, in Hello_ World.h only defines an interface function Hello, which receives a char * string as a variable and invokes printf to print it to standard output. # tree/home/ubuntu/third-parties/hello//home/ubuntu/third-parties/hello/├──include│└──hello_world.h└──lib├──libhello.so└──pkgconfig└──hello.pc To ensure that pkg-config can find this C language library, we will generate a description file for this library, which is lib/ Pkgconfig Directory of HELLO.PC, the contents of which are as follows, there is no understanding of the configuration file content of the spectators can go to search for pkg-config related documents. # cat Hello.pcPrefix=/home/ubuntu/third-parties/helloExec_prefix=${prefix}Libdir=${exec_prefix}/libIncludedir=${exec_prefix}/includeName:hellodescription:the Hello Library just for testing pkgconfigversion:0.1Libs:-lhello-l${libdir}Cflags:-i${includedir} once the Pkg-config profile has been created, you will also need to add the path information for the profile to the PKG_CONFIG_PATH environment variable, so that pkg-config can correctly obtain information about the C-language library. In addition, we need to add the library file path of the C language library to the LD_LIBRARY_PATH environment variable, with the following specific commands: # Export Pkg_config_path=/home/ubuntu/third-parties/hello/lib/pkgconfig# pkg-config--list-all | grep libhelloLibhello libhello-the Hello Library just for testing pkgconfig# Export Ld_library_path=/home/ubuntu/third-parties/hello/lib after completing the series of preparations, we can begin to write the Golang code, the following is the code example of Golang calling the C interface, we only need to #cgo Pkg-config:libhello and #include < h Ello_world.h > Two-line statements enable calls to the Hello function. If the installation path of the C language library changes, simply modify the HELLO.PC profile so that the Golang code does not need to be re-modified and compiled. 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))} Finally, compile the program code to see if the executable program correctly links the C language library, and execute the program to verify that the library function function is called correctly. # Go Build hello_world.go# LDD Hello_worldlinux-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_worldHello, world!. There are two places to focus in the above steps: 1) Create a pkg-config configuration file for the C language library and add the path of the configuration file to the environment variable Pkg_config_path; 2) The path to the C-language library file is added to the environment variable Ld_library_ Path, if you do not have this step, the Go Language program can be compiled successfully, but the executable file is not properly connected to the C language Library, the following situation occurs: # LDD Hello_worldlinux-vdso.so.1 = (0x00007fffa49e2000)libhello.so = not foundlibpthread.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)
Golang ways to get header and link libraries automatically using Pkg-config