diff --git a/eng/doc/NocgoOpenSSL.md b/eng/doc/NocgoOpenSSL.md index 059576f779..10826cf228 100644 --- a/eng/doc/NocgoOpenSSL.md +++ b/eng/doc/NocgoOpenSSL.md @@ -32,8 +32,31 @@ To see existing requests or request support for additional architectures, use th ## How the backend is selected -If cgo is enabled (e.g., `CGO_ENABLED=1`), the cgo-based OpenSSL backend is always used. -The cgo-less backend is only used when cgo is disabled **and** you're on a supported architecture. +* If cgo is explicitly enabled with `CGO_ENABLED=1`, the cgo-based OpenSSL backend is used. +* If cgo is disabled with `CGO_ENABLED=0`, then: + * If you're on a supported architecture, the cgo-less OpenSSL backend is used. + * If you're on an unsupported architecture, the build fails. +* If cgo is not explicitly enabled or disabled, then the cgo-less OpenSSL backend is used if the Go toolchain decides that cgo should be disabled. The rules are officially described by [cmd/cgo](https://pkg.go.dev/cmd/cgo). This is a summary, at the time of writing (2026-03-19): + * cgo is disabled if the Go toolchain is built with `CGO_ENABLED=0`. Note that that's not currently the case for the Microsoft build of Go. + * cgo is disabled when cross-compiling. + * cgo is disabled if the `CC` environment variable is not set to an existing executable. -This means if cgo is enabled by default on your platform or you enable cgo for other reasons (e.g., linking your own C library), the crypto backend will use the cgo-based implementation. -You can also intentionally enable cgo to successfully build for a platform without cgo-less OpenSSL support. +## Runtime dependencies + +The cgo-less OpenSSL backend still relies on the C machinery to load OpenSSL at runtime and manage threads. + +The following are the expected runtime dependencies other than OpenSSL itself on glibc-based systems: + +* `libc.so.6` for various C library functions. +* `libdl.so.2` for loading OpenSSL at runtime using `dlopen`. +* `libpthread.so.0` for managing Go's threads. + +> [!NOTE] +> The `libdl.so.2` and `libpthread.so.0` functionality is already provided by `libc.so.6` since glibc 2.34. +> The Microsoft build of Go supports platforms with older versions of glibc, so it still links to `libdl.so.2` and `libpthread.so.0` directly. +> +> There is no runtime dependency on the same libc that the program was built with. You can, for example, build a program on a system with glibc 2.34 or later and run it on a system with an older glibc version. +> +> If your platform doesn't provide these libraries, the preferred solution is to install the appropriate runtime or compatibility packages so that `libdl.so.2` and `libpthread.so.0` are available in standard system library directories (for example `/lib` or `/usr/lib`). +> +> As an advanced workaround, you may instead symlink `libdl.so.2` and `libpthread.so.0` to `libc.so.6` in a directory searched by the dynamic linker (for example, a system library directory) and update the loader cache if required (for example by running `ldconfig`); this typically requires root privileges and should only be done if you understand the implications for your system's C library.