ld Cannot Find -lopenblas | Fix Linker Paths Fast

The ld cannot find -lopenblas error means your linker can’t locate the OpenBLAS library; install the dev package and point your build at the right lib path.

You run a build, the compile steps fly by, then the link step stops with /usr/bin/ld: cannot find -lopenblas. It feels abrupt, yet the clue is clear: your build asked for a library named openblas, and the linker didn’t see it in any of the library search paths.

This guide walks you through the fixes that work in real builds: system packages, Homebrew layouts, pkg-config checks, and the exact flags that make CMake, Make, and plain gcc behave.

What This Error Means In Plain Terms

When you pass -lopenblas to a linker, you’re saying “link against a file named like libopenblas.so, libopenblas.dylib, or libopenblas.a.” The linker then searches a list of directories for a matching file. If it doesn’t find one, you get the error.

The tricky part is that OpenBLAS can be installed and still not be linkable by default. That happens when the library is in a non-standard directory, when only the runtime package is installed (no dev files), or when your build system is using stale paths.

Fast Checks That Save Time

Before changing anything, check what your machine already has. These quick checks often show the missing piece in under a minute.

  1. Confirm The Link Flag — Find where -lopenblas is coming from (CMake output, Makefile, setup logs, or a build script) so you fix the right layer.
  2. Search For The Library File — Run find /usr /opt -name 'libopenblas*' 2>/dev/null to see if the file exists anywhere on disk.
  3. Check pkg-config Output — Try pkg-config --libs openblas. If it prints flags, your build can often reuse them directly.
  4. Inspect Default Library Paths — Print your link line and look for -L entries. If you see no -L pointing at the directory that contains libopenblas, that’s the whole story.

Why You See ld Cannot Find -lopenblas During Builds

The exact same error string can come from a few different root causes. Fixing the right one keeps you from playing whack-a-mole with random flags.

Missing Dev Package

Many systems split “runtime” libraries from “development” files. You can have OpenBLAS installed for running apps, yet still lack the linkable artifacts or metadata needed for builds.

  • Spot The Split — If your package list shows something like openblas but not openblas-dev or openblas-devel, you’re likely missing the dev side.
  • Install The Dev Files — Use the package name that matches your distro (see the install table below).

Library Installed In A Non-Standard Prefix

Homebrew and custom installs often place libraries under /opt/homebrew, /usr/local, or an app-specific prefix. The linker won’t search those paths unless you add them.

  • Find The Actual Path — Use brew --prefix openblas on macOS, or inspect your custom prefix.
  • Add A -L Path — Point the linker at that directory (more on that in the build sections).

Build System Not Using pkg-config

Some projects prefer pkg-config to discover BLAS/LAPACK flags. If the OpenBLAS .pc file is missing or not on PKG_CONFIG_PATH, discovery can fail and fall back to guesses that don’t match your setup.

  • Check For The .pc File — Look for something like openblas.pc under a pkgconfig directory.
  • Set PKG_CONFIG_PATH — Add the correct .../lib/pkgconfig directory to your shell or build config.

Wrong Architecture Or Mixed Toolchains

A common macOS issue is mixing an x86_64 Python, an arm64 library, and a compiler that picks one arch by default. On Linux, it can be a 32-bit vs 64-bit mismatch, or a cross toolchain that searches different sysroots.

  • Check The Library Arch — On macOS, run file /path/to/libopenblas.dylib. On Linux, use file /path/to/libopenblas.so.
  • Match The Build Target — Keep your compiler target and your OpenBLAS build on the same architecture.

Install OpenBLAS The Right Way On Common Systems

OpenBLAS can be installed from system repos or from Homebrew on macOS. The package names differ, so here’s a quick map that works for most setups. After installing, you should see a libopenblas file in a library directory and headers under an include directory.

System Install Command Quick Verify
Debian / Ubuntu sudo apt-get install libopenblas-dev dpkg -L libopenblas-dev | grep libopenblas
Fedora / RHEL-like sudo dnf install openblas-devel rpm -ql openblas-devel | grep libopenblas
Arch sudo pacman -S openblas pacman -Ql openblas | grep libopenblas
macOS (Homebrew) brew install openblas brew --prefix openblas

macOS Note About Homebrew Layout

On macOS, the Homebrew OpenBLAS formula is often “keg-only,” which means it won’t always be symlinked into the global /usr/local or /opt/homebrew library search locations. That’s normal. It just means you’ll pass explicit paths in your build.

Point Your Build At OpenBLAS Without Guesswork

Once OpenBLAS is installed, the job is getting your build system to pass the right include and library paths. You can do that in a few clean ways. Pick the one that matches how your project builds.

Fix It With pkg-config When Available

If pkg-config --libs openblas prints flags, use them. It’s the most direct way to keep paths correct across machines.

  1. Print The Flags — Run pkg-config --cflags --libs openblas and copy the output.
  2. Feed The Flags Into The Build — Add them to CFLAGS/CPPFLAGS and LDFLAGS, or configure your build tool to call pkg-config.
  3. Set PKG_CONFIG_PATH If Needed — If the command fails, export the directory that contains openblas.pc, often .../lib/pkgconfig.

Fix It In CMake

CMake-based projects vary, yet most accept either a BLAS hint or direct library paths. The goal is to hand CMake the OpenBLAS location so it prints a link line that includes the correct -L directory.

  1. Locate The Prefix — On macOS, run brew --prefix openblas and note the result. On Linux, you often won’t need a prefix if the dev package installed into standard paths.
  2. Set CMAKE_PREFIX_PATH — Try -DCMAKE_PREFIX_PATH=/path/to/prefix so find_package logic can see OpenBLAS under that prefix.
  3. Set Explicit Paths When Needed — If your project allows it, pass a full library path like -DBLAS_LIBRARIES=/path/to/libopenblas.so (or .dylib on macOS).
  4. Verify The Link Line — Build with verbose output and confirm the final link command includes a matching -L path and -lopenblas.

Fix It In A Makefile Or Plain gcc

If you control the link command, the fix is straightforward: add the library directory with -L, then link with -lopenblas. Add the include path with -I if you compile against OpenBLAS headers.

  • Add The Library Path — Use -L/path/to/openblas/lib before -lopenblas so the linker searches that directory first.
  • Add The Include Path — Use -I/path/to/openblas/include if your compile step needs it.
  • Keep Flag Order Sensible — Put object files first, then libraries, so the linker sees symbols before it tries to resolve them.

On macOS with Homebrew, a common pattern looks like this:

OPENBLAS_PREFIX="$(brew --prefix openblas)"
CFLAGS+=-I"${OPENBLAS_PREFIX}/include"
LDFLAGS+=-L"${OPENBLAS_PREFIX}/lib" -lopenblas

Fixing The OpenBLAS -lopenblas Linker Error On Linux And macOS

Some builds still fail after you install OpenBLAS and add -L. That usually means you’re dealing with one of the edge cases below. These are the ones that show up again and again in scientific Python builds, HPC toolchains, and mixed package setups.

Multiple BLAS Libraries Competing

It’s common to have more than one BLAS on a machine: OpenBLAS, a vendor BLAS, or a BLAS shipped by a Python distro. If the build finds one at configure time and tries to link another at build time, you’ll get confusing results.

  1. Pick One Source Of Truth — Decide whether you want system OpenBLAS or a Python-distributed BLAS, then stick with it for that build.
  2. Clean The Build Directory — Remove cached CMake files or prior build artifacts so stale paths don’t linger.
  3. Reconfigure With Clear Paths — Pass explicit -L and library selections so the link line matches your choice.

Runtime Works, Link Still Fails

Sometimes you can run code that uses OpenBLAS, yet your compile fails. That points to a path difference: runtime loaders can find libraries via loader paths, while the linker is stricter during builds.

  • Check The Linker Search Paths — Print the full link command and look for the -L directories.
  • Use An rpath When Shipping Binaries — Add an rpath flag so the built binary can find OpenBLAS at run time without extra shell variables.

Conda Or Virtual Environments Masking System Paths

If you build inside a Python virtual environment or Conda env, your compiler may pick headers and libs from the env first. That can be great, yet it can also hide a system OpenBLAS install from the build scripts you’re running.

  1. Check Which Compiler You’re Using — Run which gcc, which clang, and confirm they match your intent.
  2. Prefer One Set Of Libraries — If your env includes OpenBLAS, link against the env copy. If it doesn’t, point the build at the system copy with explicit -I and -L flags.
  3. Keep The Build Logs — Save verbose logs so you can see exactly where -lopenblas was requested.

Sanity Checks Before You Rebuild

Once you apply a fix, confirm the basics before you run a long compile. These checks keep you from waiting through a full build just to see the same linker line again.

Confirm The Library Is Discoverable

  1. Locate The File — Run find /usr /opt -name 'libopenblas*' 2>/dev/null | head and confirm the path you plan to use.
  2. Test pkg-config — Run pkg-config --libs openblas. If it prints a -L and -lopenblas, reuse those flags.
  3. Check The Loader Cache On Linux — Run ldconfig -p | grep -i openblas to see if the loader knows about it.

Try A Tiny Link Test

A small compile test can prove the link works before your full build runs.

  1. Create A Test File — Write a minimal C file that includes a BLAS header if available, or just links without calling anything.
  2. Link With Explicit Flags — Run cc test.c -L/path/to/lib -lopenblas -o test and confirm it produces a binary.
  3. Inspect The Linked Binary — On Linux, run ldd ./test. On macOS, run otool -L ./test. Confirm it points at the OpenBLAS library you expect.

References

If you want the upstream install notes and the current Homebrew formula details, these are the two most useful starting points.