The “ld cannot find -lstdc” message means your link step can’t locate the C++ standard library file that -lstdc points to.
If your build stops at the final step with /usr/bin/ld complaining about -lstdc, you’re close. The compiler already produced object files. The link step is missing one piece: a real library file named like libstdc.so (or a matching file in your toolchain) in a directory the linker searches.
This walkthrough gets you from error to a clean build on most Linux families. It tackles two time sinks: installing only runtime packages, and linking against a library directory that doesn’t match your CPU or toolchain.
If you’re stuck, copy the ld error line and the full link command; those two lines usually reveal the mismatch right away.
What “-lstdc” Means And Why ld Can’t Find It
The -l flag tells GNU ld to search for a library by name in its search directories. When you pass -lstdc, the linker looks for files that follow the usual naming pattern like libstdc.so or libstdc.a, using GNU ld’s option docs.
On many systems, the C++ standard library is shipped as libstdc++.so and the linker flag is -lstdc++. So when you see -lstdc, one of two things is true:
- Build Script Uses A Nonstandard Flag — A Makefile, CMake file, or vendor recipe is linking with
-lstdcwhile your system provideslibstdc++. - Toolchain Uses A Custom Library Name — A cross toolchain or SDK does provide
libstdc.soand the build expects that exact naming.
Either way, the fix comes from the same checklist: confirm the intended library name, confirm the file exists, then make sure the linker’s search list includes the directory that holds it.
Search paths are the hidden piece. ld checks each -L directory you pass, then its built-in defaults, which depend on how the toolchain was built. On multiarch distros, the real files may live under paths like /usr/lib/x86_64-linux-gnu or /usr/lib/aarch64-linux-gnu (see a worked overview of ld search paths). If your build only looks in /usr/lib, it can miss a library that is already installed.
Quick Checks That Pinpoint The Real Cause
Start here first. These checks show a missing file, a wrong name, or a wrong path.
Check The Exact Link Command
Re-run the build with verbose output so you can see the full link line. In Make, this is often make V=1. In CMake, it can be make VERBOSE=1. You’re looking for three clues: the exact -l flag, any -L paths, and whether the link driver is gcc, g++, or clang++.
- Spot The Library Name — If the command contains
-lstdc, verify that’s intentional and not a typo for-lstdc++. - Spot The Search Directories — Every
-L/pathadds a directory thatldwill scan while resolving-l…. - Spot The Driver — Linking C++ code with
g++orclang++often selects the right default C++ libraries (see GCC link options).
Check Whether The Library File Exists
Once you know the intended name, search common library directories. Run:
ls -1 /usr/lib*/libstdc* 2>/dev/null
ls -1 /lib*/libstdc* 2>/dev/null
ldconfig -p | grep -E 'libstdc(\+\+)?\.so' || true
If you only see libstdc++.so.* and never a plain libstdc++.so symlink, you likely have the runtime library but not the development files. Debian’s package notes describe these dev packages as the parts needed to build C++ programs (see libstdc++ dev package details).
Print The Search Paths ld Will Use
If you want proof of where the linker is looking, run a verbose link and watch the “SEARCH_DIR” lines. Don’t rely on ldconfig for this check since it targets the runtime loader (see why ldconfig can mislead here).
gcc -Wl,--verbose 2>&1 | grep SEARCH_DIR | head
LIBRARY_PATH=/tmp/empty gcc -Wl,--verbose 2>&1 | grep SEARCH_DIR | head
If the directory that holds your libstdc* file isn’t listed, add it with -L (Stack Overflow notes common ways to print search paths here).
Check CPU And Toolchain Match
A library can be present and still be unusable if it targets a different CPU. If you’re cross-compiling, confirm that your -L paths point to the cross sysroot, not your host system. Run file on the candidate library and compare it to your target output.
Fixing ld Cannot Find -lstdc On Linux Systems
The fastest fix is usually to install the correct development package for the C++ standard library in your distro. Development packages tend to add link-time artifacts like the unversioned .so symlink or the static archive that the link step expects.
Debian And Ubuntu
On Debian and Ubuntu, you usually need a matching g++ package plus the libstdc++ development package. Install them, then rebuild:
sudo apt update
sudo apt install g++ libstdc++-dev
If your distro uses versioned dev packages, pick the one that matches your GCC version, like libstdc++-12-dev or libstdc++-13-dev (Debian lists them under libstdc++-13-dev).
If the symlink is missing after install, reinstall the dev package, then run a clean rebuild so the link line refreshes on disk on your next build.
Fedora, RHEL, And CentOS
On Fedora and RHEL-family systems, install the C++ compiler and the development headers/libs:
sudo dnf install gcc-c++ libstdc++-devel
On older releases that still use yum, swap dnf for yum. Then rebuild your project so the link step sees the new files.
Arch Linux
On Arch, the base toolchain packages usually handle this. If you installed a minimal set, bring in the compiler group:
sudo pacman -S --needed base-devel gcc
If the error appears inside a vendor app bundle, watch for bundled libstdc++ copies that clash with system libs. An Arch forum thread shows this pattern in the wild.
Alpine Linux
On Alpine, install the build toolchain and the C++ runtime plus development pieces:
sudo apk add build-base g++ libstdc++
When It’s A Flag Or Build Script Problem
If your system clearly has libstdc++ but the build calls -lstdc, you have a naming mismatch. This shows up in older build recipes and hand-written Makefiles.
Swap -lstdc For -lstdc++
Search your build files for -lstdc. If you’re building C++ code on a typical GNU toolchain, the correct flag is often -lstdc++. A small edit can fix the entire build.
- Edit Makefile Link Flags — Replace
-lstdcwith-lstdc++, then runmake cleanand rebuild. - Update CMake Targets — Remove manual
-lstdcadditions and link via targets, or addstdc++totarget_link_libraries. - Use The C++ Link Driver — Drive the final link with
g++orclang++so the standard library choice matches the compiler.
Put -L Before -l
Order matters. If you add a custom library directory, place -L/your/path before -lstdc on the command line (see Red Hat’s notes on using libraries with GCC). Red Hat’s developer guide calls out that -L should come before -l so the linker can find libraries in the intended directories.
Let pkg-config Hand You The Right Flags
When dependencies ship a .pc file, pkg-config can print the correct -L and -l flags for your system’s layout. That beats hard-coded paths in a Makefile.
- Print Library Flags — Run
pkg-config --libs NAMEand copy the output into your build. - Print Include Flags — Run
pkg-config --cflags NAMEfor header paths.
Path Fixes That Stay Inside Your Project
Sometimes you can’t install packages, or you’re linking against a library in a project directory. In that case, steer the link step with build flags, then keep the change in your repo.
Add A Local Library Directory With -L
If your library is in a nonstandard folder, add its directory with -L. This affects the link step only.
- Add -L In The Link Line — Put
-L/path/to/libsbefore-lstdcso ld scans that folder early. - Confirm The Naming Pattern — The file should match
libNAME.soorlibNAME.afor the-lNAMEpattern (GNU make documents the default patterns here).
Use LIBRARY_PATH For A One-Off Build
GCC reads the LIBRARY_PATH variable while linking. It is separate from LD_LIBRARY_PATH, which affects runtime loading (see LIBRARY_PATH vs LD_LIBRARY_PATH).
LIBRARY_PATH=/path/to/libs:$LIBRARY_PATH make
Use rpath For Runtime Discovery
If your build links successfully and your program later fails with a “cannot open shared object file” message, that’s runtime loading, not link time. You can bake a runtime search directory into the binary with an rpath flag passed via the compiler driver (quick primer here).
g++ main.o -L/path/to/libs -Wl,-rpath,/path/to/libs -lstdc++ -o app
Common Scenarios And The Fix That Matches
The same linker message can come from several setups. Use the pattern that matches what you’re doing.
| Setup | What Usually Went Wrong | Fast Fix |
|---|---|---|
| Fresh Linux install | Runtime libs present, dev files missing | Install the distro’s libstdc++ dev package |
| Cross compile | Linker searching host paths, not sysroot | Point -L to the target sysroot lib dir |
| Vendor SDK | Build uses -lstdc but SDK ships different name | Match the flag to the SDK’s actual file |
| App bundle | Bundled libstdc++ conflicts with system | Use one toolchain and one lib set |
ld Cannot Find -lstdc
If you installed a library and ld still won’t see it, it’s easy to mix up the link-time search with the runtime loader search. A Unix & Linux answer spells it out: ldconfig configures the runtime loader, not the link editor, so a library can appear in ldconfig -p while the build still fails (details).
- Install The Development Package — That is the usual missing piece for link time.
- Add The Right -L Path — Point at the directory that contains the unversioned
.solink or the.aarchive. - Clean And Rebuild — Remove cached objects so your build reruns the full link step with the new flags.
A Clean Troubleshooting Flow You Can Reuse
When you hit this linker error, follow this flow. Each step proves one thing and cuts guesswork.
- Capture The Link Line — Build with verbose output and copy the full command.
- Validate The Name — Decide whether
-lstdcis intended or should be-lstdc++. - Locate The File — Find the matching
libstdc*.soor.aon disk. - Match The CPU — Run
fileon the library to confirm it matches the target. - Add Search Paths — Put
-Lpaths before-lflags; useLIBRARY_PATHonly for a temporary run. - Rebuild From Clean — Run the build clean target, then build again.
Once the link step finishes, run your binary once. If it fails at runtime, switch to rpath or a standard install location instead of leaning on LD_LIBRARY_PATH every day (see runtime loader notes).
