Understanding the two different phases
When you invoke `gcc` it first runs the C compiler (`cc1`) to produce assembly, then calls the linker (`ld`). The error about `libmpfr.so.1` comes from `cc1` trying to load its own shared libraries at run time. The later "unrecognized command line option -L…" originates from `cc1` receiving a linker flag that belongs to the second phase. Mixing these phases creates the confusing messages you see.
Why adding the library path to LD_LIBRARY_PATH helped the first error
`cc1` is linked against MPFR and GMP. If the dynamic loader cannot locate `libmpfr.so.1` it aborts with the “cannot open shared object file” message. Adding the directories to `LD_LIBRARY_PATH` tells the loader where to find those shared objects, so `cc1` can start.
Why `-L` does not belong in LD_LIBRARY_PATH
The `-L` flag is a linker option, not an environment variable. It tells `ld` where to search for static or shared libraries during the link step. When you export `LD_LIBRARY_PATH` you only affect the run‑time loader, not the compile‑time linker. Passing `-L` to `gcc` without a following `-l` makes `gcc` forward it to `cc1`, which does not understand it, resulting in the “unrecognized command line option” error.
Correct ways to make the libraries visible
There are three reliable approaches: 1. **System‑wide configuration** – add the two directories to `/etc/ld.so.conf` (or a file under `/etc/ld.so.conf.d/`) and run `ldconfig`. This updates the loader cache for all users. 2. **Per‑user RPATH** – compile with `gcc test.c -Wl,-rpath,/lusr/opt/mpfr-2.4.2/lib:/lusr/opt/gmp-4.3.2/lib`. The resulting binary will embed the search path, eliminating the need for `LD_LIBRARY_PATH`. 3. **Temporary environment** – keep `LD_LIBRARY_PATH` set only for the session where you build, e.g. `LD_LIBRARY_PATH=/lusr/opt/mpfr-2.4.2/lib:/lusr/opt/gmp-4.3.2/lib gcc test.c`. All three keep `-L` out of the compiler front‑end and avoid the spurious error.
Putting it together – a minimal compile command
If you prefer an explicit link step, use both `-L` and `-l` together: ```bash gcc test.c -L/lusr/opt/mpfr-2.4.2/lib -L/lusr/opt/gmp-4.3.2/lib \ -lmpfr -lgmp -o test ``` The `-L` directories are consumed by the linker, while `-lmpfr -lgmp` request the actual libraries. No `cc1` error will appear because the runtime loader already knows where to find the shared objects (via `LD_LIBRARY_PATH` or system configuration).
Takeaway: Use LD_LIBRARY_PATH or ld.so.conf for runtime loading and pass -L/-l only to the linker, never to cc1.
People also ask
Do I need to set LD_LIBRARY_PATH for every compilation?
No; configure the loader with ldconfig or embed an RPATH in the binary to avoid per‑session settings.
What does the -Wl,-rpath option do?
It tells the linker to record a runtime library search path inside the executable, so the loader can find the libraries without external environment variables.
Why does GCC sometimes report linker errors from cc1?
Because GCC forwards all unknown flags to its front‑end; a misplaced -L reaches cc1, which cannot interpret it, producing the misleading message.
Inspired by a public discussion on Stack Overflow. This article is an original explanation for learners.