638

I'm trying to compile my program and it returns this error :

usr/bin/ld: cannot find -l<nameOfTheLibrary>

in my makefile I use the command g++ and link to my library which is a symbolic link to my library located on an other directory.

Is there an option to add to make it work please?

seanmus
  • 508
  • 2
  • 15
ZoOo
  • 6,383
  • 3
  • 13
  • 5
  • 1
    Need more info. What command did you issue to compile your program? You can use _make -n your-target_ to have make just print the commands it would normally invoke – djf May 23 '13 at 09:26
  • Post the makefile or the command you execute. – Ortwin Angermeier May 23 '13 at 09:38
  • my command is this one : g++ - objetc1.o objetc2.o objetc3.o objetc4.o -L -l -lpthread -o myexe – ZoOo May 23 '13 at 09:38
  • 4
    Is the library you want to link with built with the same architecture(eg. 32/64 bit)? Is the library you want to link with a custom library? The library name matters, since it has to start with lib when using the `-l` switch (eg. libpthread.so you are already linking with). – Ortwin Angermeier May 23 '13 at 10:10
  • 1
    The problem was on my symbolic link on the library which wasn't good ! Thanks for your help ! – ZoOo May 23 '13 at 11:16
  • As u say an answer below has solved ur issue, so accept that answer. – goldenmean May 26 '13 at 12:09
  • just to second @OrtwinAngermeier comment about library naming conventions: http://stackoverflow.com/questions/6561273/is-liblibrary-name-a-so-a-naming-convention-for-static-libraries-in-linux – jotadepicas Jan 13 '16 at 02:41
  • On Debian / Ubuntu Linux try apt search _nameoflib_ so you will get the exact name of what you want to install – Allan Karlson May 03 '17 at 12:32
  • I acknowledge that the text of the error message is weird. I mean, it makes me wonder...why does this error not just say "cannot find " Why does it say "cannot find -l" Why is the `-l` in the error message? Does that mean it couldn't find the command line argument? I admit it makes me worry that it somehow misinterpreted the command line argument as a filename and was looking for a file called -l. – Wyck Mar 03 '21 at 15:35

14 Answers14

643

To figure out what the linker is looking for, run it in verbose mode.

For example, I encountered this issue while trying to compile MySQL with ZLIB support. I was receiving an error like this during compilation:

/usr/bin/ld: cannot find -lzlib

I did some Googl'ing and kept coming across different issues of the same kind where people would say to make sure the .so file actually exists and if it doesn't, then create a symlink to the versioned file, for example, zlib.so.1.2.8. But, when I checked, zlib.so DID exist. So, I thought, surely that couldn't be the problem.

I came across another post on the Internets that suggested to run make with LD_DEBUG=all:

LD_DEBUG=all make

Although I got a TON of debugging output, it wasn't actually helpful. It added more confusion than anything else. So, I was about to give up.

Then, I had an epiphany. I thought to actually check the help text for the ld command:

ld --help

From that, I figured out how to run ld in verbose mode (imagine that):

ld -lzlib --verbose

This is the output I got:

==================================================
attempt to open /usr/x86_64-linux-gnu/lib64/libzlib.so failed
attempt to open /usr/x86_64-linux-gnu/lib64/libzlib.a failed
attempt to open /usr/local/lib64/libzlib.so failed
attempt to open /usr/local/lib64/libzlib.a failed
attempt to open /lib64/libzlib.so failed
attempt to open /lib64/libzlib.a failed
attempt to open /usr/lib64/libzlib.so failed
attempt to open /usr/lib64/libzlib.a failed
attempt to open /usr/x86_64-linux-gnu/lib/libzlib.so failed
attempt to open /usr/x86_64-linux-gnu/lib/libzlib.a failed
attempt to open /usr/local/lib/libzlib.so failed
attempt to open /usr/local/lib/libzlib.a failed
attempt to open /lib/libzlib.so failed
attempt to open /lib/libzlib.a failed
attempt to open /usr/lib/libzlib.so failed
attempt to open /usr/lib/libzlib.a failed
/usr/bin/ld.bfd.real: cannot find -lzlib

Ding, ding, ding...

So, to finally fix it so I could compile MySQL with my own version of ZLIB (rather than the bundled version):

sudo ln -s /usr/lib/libz.so.1.2.8 /usr/lib/libzlib.so

Voila!

dcarrith
  • 7,510
  • 2
  • 18
  • 9
  • 84
    Thanks, this was helpful. For others using gcc to compile and link their program (rather than using ld directly), you can add `-Xlinker --verbose` to gcc's command-line arguments to have it pass this option to ld. –  Feb 12 '14 at 11:04
  • 7
    This also helped me. The Makefile I had was only expecting static libraries so it used `-Wl,-Bstatic`. This limits the search to .a files only. The verbose option showed this clearly. Once I removed `-Wl,-Bstatic` shared libraries were also searched. – micah94 Feb 23 '14 at 01:21
  • 2
    I'm on FreeBSD 10. The new LLVM Clang cc takes an argument of the form `-Wl,--verbose` and passes `--verbose` to the linker. – Christian - Reinstate Monica C May 12 '14 at 02:32
  • That was extremely helpful. Can you tell me how can we change the path for a particular flag in `ld`? – Shashwat Sep 18 '14 at 12:46
  • 9
    Now that's what I call a perfect answer! Thanks a lot. It saved a lot of time. Just to add to help someone like me. It can be used to debug path related issues as well. Make sure you check the path with -L with command, ld -L -l --verbose – sbhatt Mar 09 '15 at 20:09
  • How to configure `make` so that it will be verbose? – Black Aug 26 '15 at 12:51
  • Great answer. This led me to the problem for me: the packaged libs had the wrong permissions after placing them in the /usr/local/lib directory. I just typed: `chmod 755 ` and my source compiled. – chembrad Sep 09 '15 at 19:44
  • 3
    @EdwardBlack See this [answer](http://stackoverflow.com/a/9929507/720507). Essentially, for gcc, just add `-Wl,--verbose` to pass verbose to the linker. – chembrad Sep 09 '15 at 19:50
  • 1
    The tip about using `ld LIBNAME --verbose` was very useful. In my case, ld was expecting the .so but I had only the .so.1. – Diogo Melo Sep 14 '15 at 19:54
  • This tip `ld lzlib --verbose` is so useful. I figured out a mystery problem starting from the hit by this command's output. Actually some lib*.so is actually a link script and instruct how to link a shared library for use. – NathaneilCapital Mar 13 '16 at 00:59
  • I also got same output for #ld -lzlib --verbose --> attempt to open /usr/x86_64-linux-gnu/lib64/libzlib.so failed attempt to open /usr/x86_64-linux-gnu/lib64/libzlib.a failed attempt to open //usr/local/lib/x86_64-linux-gnu/libzlib.so failed attempt to open //usr/local/lib/x86_64-linux-gnu/libzlib.a failed – Ashish Karpe Apr 05 '16 at 13:44
  • but "sudo ln -s /usr/lib/libz.so.1.2.8 /usr/lib/libzlib.so" this is not working for me – Ashish Karpe Apr 05 '16 at 13:44
  • I have never understood how library finding worked for a long time. This has finally answered it. Thank you. – Tek May 08 '16 at 19:07
  • One more plus for a great answer. I also faced with the same issue ("attempt to open libc.a failed"), but in my case it just turned out that final parameter string which was passed to ld.exe appeared to be more than 8300 characters long (approximate number). After making toolchain path shorter the issue disappeared. – yurko Dec 22 '16 at 15:07
  • Ubuntu 16.10: sudo ln -s /usr/local/lib/libz.so.1.2.10 /usr/lib/libzlib.so – ilyasavitski Jan 04 '17 at 23:48
  • Thanks for the answer. But is there any way to resolve it, if I don't have permission to create the symbolic link? – Sidak Jan 30 '17 at 09:26
  • Perfect! I was lazy and ran my test in Cygwin instead of the Ubuntu VM. Turns out I shot myself in the foot. As a Windows shoehorn that creates a.exe in place of a.out, Cygwin also expects libxyz.dll, NOT libxyz.so! This made it clear to me. Thanks! – Jerry Miller Oct 17 '17 at 16:22
  • @dcarrith I didn't find this /usr/lib/libz.so.1.2.8 – Hana90 Apr 09 '18 at 12:13
  • 2
    See answer below https://stackoverflow.com/a/42339395/332359 for a better way than making the symlink yourself. – dmaestro12 Jun 23 '18 at 17:34
  • Is there an equivalent for macos's linker? – oarfish Oct 25 '22 at 07:19
  • In my case, the output of `--verbose` doesn't help. So I use the `LD_DEBUG=all` and then `grep` to find the info I need in a 1G log file... – Qin Heyang Nov 02 '22 at 11:02
  • For a similar issue. running "ld -lsqlite3 --verbose" has helped me get rid of the build error. Thanks! – Lokesh Purohit Jan 03 '23 at 13:19
247

If your library name is say libxyz.so and it is located on path say:

/home/user/myDir

then to link it to your program:

g++ -L/home/user/myDir -lxyz myprog.cpp -o myprog
Kevin Panko
  • 8,356
  • 19
  • 50
  • 61
Saurabh Bhola
  • 2,940
  • 1
  • 13
  • 10
  • 15
    my library is not a dynamic one (.so) but a static one (.a). Does the problem come from that? – ZoOo May 23 '13 at 09:41
  • 4
    @ZoOo that shouldn't normally matter, the linker can work with either one – djf May 23 '13 at 09:48
  • 8
    another way to link your library is that you can directly specify the name of the library with complete path, like g++ .. /path/mylib.a – Saurabh Bhola May 23 '13 at 09:52
  • 4
    Yes but it still doesn't work. My library is a symbolic link, i think the problem come from that because when i use the library in the other directory it works ! – ZoOo May 23 '13 at 10:02
  • 1
    I also directly the name of the library and it doesn't work ! – ZoOo May 23 '13 at 10:03
  • 2
    Is your symbolic link correctly pointing to the library at actual location??. can you post the output of "ll" on the symbolic link. – Saurabh Bhola May 23 '13 at 10:21
  • 1
    You're right ! Thanks for your help @SaurabhBhola my symbolic link pointing on the library in the other directory wasn't good ! I correct it and now it works !!! Thanks to all of you ! – ZoOo May 23 '13 at 11:14
  • How to I add the link to a make file? – Naveen Sep 30 '16 at 15:45
  • You need to put -lxyz *after* myprog.cpp since the linker will only resolve symbols for object files to the left on the command line. – wcochran Apr 10 '18 at 21:46
  • How do I tell the linker to look at a relative path? – Aaron Franke Apr 06 '21 at 06:07
  • Where can I find name of my program, what if I run `colcon build` or `cmake` ? And how find path of library ? What is g++ ? – Dmitriy Ogureckiy Feb 21 '23 at 18:15
83

There does not seem to be any answer which addresses the very common beginner problem of failing to install the required library in the first place.

On Debianish platforms, if libfoo is missing, you can frequently install it with something like

apt-get install libfoo-dev

The -dev version of the package is required for development work, even trivial development work such as compiling source code to link to the library.

The package name will sometimes require some decorations (libfoo0-dev? foo-dev without the lib prefix? etc), or you can simply use your distro's package search to find out precisely which packages provide a particular file.

(If there is more than one, you will need to find out what their differences are. Picking the coolest or the most popular is a common shortcut, but not an acceptable procedure for any serious development work.)

For other architectures (most notably RPM) similar procedures apply, though the details will be different.

tripleee
  • 175,061
  • 34
  • 275
  • 318
  • 5
    This just helped me with an issue I was having with a fresh server and Perl. `apt-get install libperl-dev` sorted it for me. Thanks :) – Andrew Newby Mar 27 '17 at 16:58
  • 1
    This! No need to mess with the Makefile – Byron Whitlock May 15 '17 at 17:36
  • This is probably the most common solution and helped me compile cacti-spine on CentOS 7. A simple `yum install openssl-devel` solved it. – djluko May 30 '17 at 06:21
  • 1
    This is the best fix if you find the symlink ending in .so is missing, but you have a symlink such as libfoo.so.6 --> libfoo.so.6.0.2 (for example), rather than making the symlink by hand. (meaning you have package libfoo installed, but not libfoo-dev) – dmaestro12 Jun 23 '18 at 17:29
  • 2
    Thanks for this! I would also like to add for beginners: ```1. apt install != apt install ``` That's to say: ```1. apt install sqlite3 != apt install libsqlite3-dev``` and ```2. apt install dbus != apt install libdbus-1-dev libdbus-glib-1-dev``` You have to make sure it's the library for gcc! – John Huynh Mar 29 '23 at 02:49
73

Compile Time

When g++ says cannot find -l<nameOfTheLibrary>, it means that g++ looked for the file lib{nameOfTheLibrary}.so, but it couldn't find it in the shared library search path, which by default points to /usr/lib and /usr/local/lib and somewhere else maybe.

To resolve this problem, you should either provide the library file (lib{nameOfTheLibrary}.so) in those search paths or use -L command option. -L{path} tells the g++ (actually ld) to find library files in path {path} in addition to default paths.

Example: Assuming you have a library at /home/taylor/libswift.so, and you want to link your app to this library. In this case you should supply the g++ with the following options:

g++ main.cpp -o main -L/home/taylor -lswift
  • Note 1: -l option gets the library name without lib and .so at its beginning and end.

  • Note 2: In some cases, the library file name is followed by its version, for instance libswift.so.1.2. In these cases, g++ also cannot find the library file. A simple workaround to fix this is creating a symbolic link to libswift.so.1.2 called libswift.so.


Runtime

When you link your app to a shared library, it's required that library stays available whenever you run the app. In runtime your app (actually dynamic linker) looks for its libraries in LD_LIBRARY_PATH. It's an environment variable which stores a list of paths.

Example: In case of our libswift.so example, dynamic linker cannot find libswift.so in LD_LIBRARY_PATH (which points to default search paths). To fix the problem you should append that variable with the path libswift.so is in.

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/taylor
Piotr Dobrogost
  • 41,292
  • 40
  • 236
  • 366
frogatto
  • 28,539
  • 11
  • 83
  • 129
  • Thanks for your post! I have been ignoring all the answers till the moment when I copied `.so` files to `/usr/lib`, but it became interesting for me whether `export` will help. Despite installation process after `make` continued longer, another error occured. This time, `.so.0` file was not found, but both `.so` and `.so.0` file were in the directory where I have build dependent package from source. Could you help with that? – A.Ametov Jan 24 '20 at 10:29
  • Also note, that library name is also case censitive. I tried to link library OpenCl and no success, but library OpenCL works fine :) – Alexey Sep 09 '22 at 09:10
44

During compilation with g++ via make define LIBRARY_PATH if it may not be appropriate to change the Makefile with the -Loption. I had put my extra library in /opt/lib so I did:

$ export LIBRARY_PATH=/opt/lib/

and then ran make for successful compilation and linking.

To run the program with a shared library define:

$ export LD_LIBRARY_PATH=/opt/lib/

before executing the program.

Finn Årup Nielsen
  • 6,130
  • 1
  • 33
  • 43
23

First, you need to know the naming rule of lxxx:

/usr/bin/ld: cannot find -lc
/usr/bin/ld: cannot find -lltdl
/usr/bin/ld: cannot find -lXtst

lc means libc.so, lltdl means libltdl.so, lXtst means libXts.so.

So, it is lib + lib-name + .so


Once we know the name, we can use locate to find the path of this lxxx.so file.

$ locate libiconv.so
/home/user/anaconda3/lib/libiconv.so   # <-- right here
/home/user/anaconda3/lib/libiconv.so.2
/home/user/anaconda3/lib/libiconv.so.2.5.1
/home/user/anaconda3/lib/preloadable_libiconv.so
/home/user/anaconda3/pkgs/libiconv-1.14-0/lib/libiconv.so
/home/user/anaconda3/pkgs/libiconv-1.14-0/lib/libiconv.so.2
/home/user/anaconda3/pkgs/libiconv-1.14-0/lib/libiconv.so.2.5.1
/home/user/anaconda3/pkgs/libiconv-1.14-0/lib/preloadable_libiconv.so

If you cannot find it, you need to install it by yum (I use CentOS). Usually you have this file, but it does not link to right place.


Link it to the right place, usually it is /lib64 or /usr/lib64

$ sudo ln -s /home/user/anaconda3/lib/libiconv.so /usr/lib64/

Done!

ref: https://i-pogo.blogspot.jp/2010/01/usrbinld-cannot-find-lxxx.html

Belter
  • 3,573
  • 5
  • 42
  • 58
  • 5
    `locate` only works if it is installed and running regularly. A crude workaround is to run `find` on your entire disk, but of course, it will take time. If you find yourself doing that frequently, consider installing `locate` just to lower the (interactive, human) cost of this operation. – tripleee Nov 27 '17 at 13:44
  • Thx your answer clued me in on what was going wrong. I created soft links to the "missing" `libXXX.so` files. ex: `ln -s libasound.so.2 libasound.so` – RyanNerd Sep 11 '21 at 21:47
7

When you compile your program you must supply the path to the library; in g++ use the -L option:

g++ myprogram.cc -o myprogram -lmylib -L/path/foo/bar
koan
  • 3,596
  • 2
  • 25
  • 35
  • 1
    Which property do we have to change in `ccmake` so that the `Makefile` is created with the linked flag? I want to link my `-lARToolkitPlus` flag to a path. – Shashwat Sep 18 '14 at 11:40
4

I had this problem with compiling LXC on a fresh VM with Centos 7.8. I tried all the above and failed. Some suggested removing the -static flag from the compiler configuration but I didn't want to change anything.

The only thing that helped was to install glibc-static and retry. Hope that helps someone.

Doron Cohen
  • 1,026
  • 8
  • 13
3

Check the location of your library, for example lxxx.so:

locate lxxx.so

If it is not in the /usr/lib folder, type this:

sudo cp yourpath/lxxx.so /usr/lib

Done.

allo
  • 3,955
  • 8
  • 40
  • 71
hua
  • 31
  • 1
3

Apart from the answers already given, it may also be the case that the *.so file exists but is not named properly. Or it may be the case that *.so file exists but it is owned by another user / root.

Issue 1: Improper name

If you are linking the file as -l<nameOfLibrary> then library file name MUST be of the form lib<nameOfLibrary> If you only have <nameOfLibrary>.so file, rename it!

Issue 2: Wrong owner

To verify that this is not the problem - do

ls -l /path/to/.so/file

If the file is owned by root or another user, you need to do

sudo chown yourUserName:yourUserName /path/to/.so/file
user13107
  • 3,239
  • 4
  • 34
  • 54
  • System files should obviously not be owned by yourself. The ownership discussion seems spurious anyway; the main concern is that the library needs to be world-readable (and, for security reasons, not world-writable). – tripleee May 17 '23 at 04:17
3

Here is Ubuntu information of my laptop.

lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 18.04.2 LTS
Release:    18.04
Codename:   bionic

I use locate to find the .so files for boost_filesystem and boost_system

locate libboost_filesystem
locate libboost_system

Then link .so files to /usr/lib and rename to .so

sudo ln -s /usr/lib/x86_64-linux-gnu/libboost_filesystem.so.1.65.1 /usr/lib/libboost_filesystem.so
sudo ln -s /usr/lib/x86_64-linux-gnu/libboost_system.so.1.65.1 /usr/lib/libboost_system.so

Done! R package velocyto.R was successfully installed!

Shicheng Guo
  • 1,233
  • 16
  • 19
  • You should not be manually manipulating anything in `/usr/lib`; this directory should be entirely managed by your package manager. – tripleee May 17 '23 at 04:16
2

This error may also be brought about if the symbolic link is to a dynamic library, .so, but for legacy reasons -static appears among the link flags. If so, try removing it.

Vzbux
  • 121
  • 1
2

The library I was trying to link to turned out to have a non-standard name (i.e. wasn't prefixed with 'lib'), so they recommended using a command like this to compile it -

gcc test.c -Iinclude lib/cspice.a -lm

Brian Burns
  • 20,575
  • 8
  • 83
  • 77
1

I encountered the same error message.

I built the cmocka as a so and tried to link it to my executable. But ld always complains below:

/usr/bin/ld: cannot find -lcmocka

It turns out that there are 3 files generated after cmocka is built:

  1. libcmocka.so
  2. libcmocka.so.0
  3. libcmocka.so.0.7.0

1 and 2 are symbol links and only 3 is the real file.

I only copied the 1 to my library folder, where ld failed to find the 3.

After I copied all 3, ld works.

smwikipedia
  • 61,609
  • 92
  • 309
  • 482