cgo directives: CFLAGS, LDFLAGS, and pkg-config
cgo build configuration.
#cgo CFLAGS feeds the C compiler include paths/defines, LDFLAGS feeds the linker libraries/paths, pkg-config auto-discovers both; needed to compile against a system C library.
WHAT THIS TESTS Whether you understand how cgo bridges Go to a C toolchain and the distinct compile-time versus link-time roles of its build directives.
A GOOD ANSWER COVERS cgo lets a Go file embed C in the comment immediately preceding import "C". Inside that preamble, lines beginning with #cgo configure the toolchain. CFLAGS is handed to the C compiler when it builds the embedded C, so you use it for include directories with -I, preprocessor defines with -D, and standard or optimization flags; without the right -I the C snippet fails to find headers. LDFLAGS is handed to the linker, so you use it for library search paths with -L and libraries to link with -l, plus options like -Wl flags; without the right -l symbols remain undefined at link time. pkg-config is a convenience: #cgo pkg-config: name runs the pkg-config tool against the library's .pc file and expands to the correct CFLAGS and LDFLAGS automatically, sparing you from hardcoding paths that differ per system. Directives can be constrained by build constraints, for example #cgo linux LDFLAGS for platform-specific linking.
COMMON WRONG ANSWERS Swapping the roles, putting -l in CFLAGS or -I in LDFLAGS. Believing pkg-config replaces the C compiler rather than just emitting flags. Forgetting that cgo requires a working C toolchain and disables cross-compilation unless configured.
LIKELY FOLLOW-UPS How do you scope flags per OS or architecture with build constraints? What is the cost of cgo regarding build speed and cross-compilation? How do static versus dynamic linking choices appear in LDFLAGS? Why prefer pkg-config over hardcoded paths?
ONE CONCRETE EXAMPLE Wrapping libcurl: the preamble has #cgo pkg-config: libcurl, which emits the include path so the C code can #include <curl/curl.h> and the linker flags so curl_easy_perform resolves. Without pkg-config you would write #cgo CFLAGS: -I/usr/include and #cgo LDFLAGS: -lcurl by hand, which is brittle across distributions, illustrating why pkg-config is preferred.
Read the original → pkg.go.dev
Get five bites like this every day.
Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.