197

I work in Linux with C++ (Eclipse), and want to use a library. Eclipse shows me an error:

undefined reference to 'dlopen' 

Do you know a solution?

Here is my code:

#include <stdlib.h>
#include <stdio.h>
#include <dlfcn.h>

int main(int argc, char **argv) {
    void *handle;
    double (*desk)(char*);
    char *error;

    handle = dlopen ("/lib/CEDD_LIB.so.6", RTLD_LAZY);
    if (!handle) {
        fputs (dlerror(), stderr);
        exit(1);
    }

    desk= dlsym(handle, "Apply");

    if ((error = dlerror()) != NULL)  {
        fputs(error, stderr);
        exit(1);
    }

    dlclose(handle);
}
Sildoreth
  • 1,883
  • 1
  • 25
  • 38
user101375
  • 6,961
  • 9
  • 42
  • 43
  • 1
    I've had this error in a situation different to presented above. The fix was to reorder the `-l` flags. I had to put `-dl` after (in my case) `-ssl` and the error went away. – Paul Rooney Feb 10 '22 at 08:34

13 Answers13

316

You have to link against libdl, add

-ldl

to your linker options

Masci
  • 5,864
  • 1
  • 26
  • 21
  • 3
    I have run into the same problem... I added the compiler flag under Project>Properties>C/C++Build>Settings>(My Linker)>Miscellaneous in the Linker flags text field. It did nothing. – MirroredFate Feb 02 '13 at 07:09
  • 5
    Ha, ok, for anyone else that has this problem, use the above path, except go to Libraries rather than Miscellaneous and add the 'dl' – MirroredFate Feb 02 '13 at 07:53
  • 4
    This answer helped. For anyone who wants to find the location of libdl.so, just go to the root directory and type `locate libdl.so` – Nav Jul 04 '13 at 11:46
  • MirroredFate's answer worked for me as well. I don't understand why, though; every other library I've ever had to link worked when placed in Miscellaneous. – aggregate1166877 Jul 27 '14 at 22:19
  • i have added export LDFLAGS='-ldl' before build and it works – Jamviet.com Aug 20 '22 at 21:02
103

@Masci is correct, but in case you're using C (and the gcc compiler) take in account that this doesn't work:

gcc -ldl dlopentest.c

But this does:

gcc dlopentest.c -ldl

Took me a bit to figure out...

knocte
  • 16,941
  • 11
  • 79
  • 125
  • 3
    I've found that the order of the options matters too. On a project using sqlite3, I have to put -ldl (and -lpthread) after -lsqlite3. Don't know what that is, I'm sure the answer is there if I would just RTFM. –  Apr 04 '17 at 18:55
  • 1
    Holy crap, that's it! I would never have guessed that putting the options first (which makes more sense to me) doesn't work, while putting them after does. Thank you, @knocte! – Joe Strout Jul 21 '17 at 18:18
  • @user2918461 hit the nail on the head. I had to put the -l's in the "correct" order. – NDEthos Nov 18 '17 at 07:25
  • for anyone who is wondering why this is, its because ld reads the libraries left to right then notes any undefined symbols, filling them in when a different library gives them. the problem being it doesn't check for undefined symbols in the files _before_ the one it is linking – an inconspicuous semicolon May 18 '22 at 14:01
16

this doesn't work:

gcc -ldl dlopentest.c

But this does:

gcc dlopentest.c -ldl

That's one annoying "feature" for sure

I was struggling with it when writing heredoc syntax and found some interesting facts. With CC=Clang, this works:

$CC -ldl -x c -o app.exe - << EOF
#include <dlfcn.h>
#include <stdio.h>
int main(void)
{
  if(dlopen("libc.so.6", RTLD_LAZY | RTLD_GLOBAL))
    printf("libc.so.6 loading succeeded\n");
  else
    printf("libc.so.6 loading failed\n");
  return 0;
}
EOF

./app.exe

as well as all of these:

  • $CC -ldl -x c -o app.exe - << EOF
  • $CC -x c -ldl -o app.exe - << EOF
  • $CC -x c -o app.exe -ldl - << EOF
  • $CC -x c -o app.exe - -ldl << EOF

However, with CC=gcc, only the last variant works; -ldl after - (the stdin argument symbol).

vulcan raven
  • 32,612
  • 11
  • 57
  • 93
  • 1
    I encounter such problem too. But I don't know why `gcc dlopentest.c -ldl` works whereas `gcc -ldl dlopentest.c` does not. How do you think about it? – John Oct 08 '21 at 07:53
16

I was using CMake to compile my project and I've found the same problem.

The solution described here works like a charm, simply add ${CMAKE_DL_LIBS} to the target_link_libraries() call

Lucas Coelho
  • 583
  • 6
  • 11
  • 2
    Thanks! This helped me as well. But only after I changed my compiler to clang `SET(CMAKE_CXX_COMPILER /usr/bin/clang++)`. With /usr/bin/c++ on my Ubuntu it was not working... (see also vulcan raven's answer) – thomasfermi Nov 06 '19 at 10:24
8

The topic is quite old, yet I struggled with the same issue today while compiling cegui 0.7.1 (openVibe prerequisite).

What worked for me was to set: LDFLAGS="-Wl,--no-as-needed" in the Makefile.

I've also tried -ldl for LDFLAGS but to no avail.

bawey
  • 149
  • 1
  • 4
5

you can try to add this

LIBS=-ldl CFLAGS=-fno-strict-aliasing

to the configure options

user2948547
  • 326
  • 3
  • 8
  • 1
    Using the LIBS variable worked for me to get configure to put -ldl in the right place on the command line. – duncan Jan 14 '15 at 05:38
4

You needed to do something like this for the makefile:

LDFLAGS='-ldl'
make install

That'll pass the linker flags from make through to the linker. Doesn't matter that the makefile was autogenerated.

Guillaume Jacquenot
  • 11,217
  • 6
  • 43
  • 49
Rob
  • 4,404
  • 2
  • 32
  • 33
1

I met the same problem even using -ldl.

Besides this option, source files need to be placed before libraries, see undefined reference to `dlopen'.

Community
  • 1
  • 1
Deqing
  • 14,098
  • 15
  • 84
  • 131
1

In order to use dl functions you need to use the -ldl flag for the linker.

how you do it in eclipse ?

Press Project --> Properties --> C/C++ build --> Settings --> GCC C++ Linker -->
Libraries --> in the "Libraries(-l)" box press the "+" sign --> write "dl" (without the quotes)-> press ok --> clean & rebuild your project.

Amitk
  • 153
  • 2
  • 10
1
 $gcc -o program program.c -l <library_to_resolve_program.c's_unresolved_symbols>

A good description of why the placement of -l dl matters

But there's also a pretty succinct explanation in the docs From $man gcc

   -llibrary
   -l library
       Search the library named library when linking.  (The second
       alternative with the library as a separate argument is only for POSIX
       compliance and is not recommended.)
       It makes a difference where in the command you write this option; the
       linker searches and processes libraries and object files in the order
       they are specified.  Thus, foo.o -lz bar.o searches library z after
       file foo.o but before bar.o.  If bar.o refers to functions in z,
       those functions may not be loaded.
flerb
  • 644
  • 9
  • 14
0

Try to rebuild openssl (if you are linking with it) with flag no-threads.

Then try to link like this:

target_link_libraries(${project_name} dl pthread crypt m ${CMAKE_DL_LIBS})
James
  • 111
  • 9
0

In earlier versions(~2.7) of GNU tool chain, glibc did not have direct interface to link loader(dlopen and dlsym functions), so you had to provide -ldl(libdl) at compile time. You don't have to do that anymore with latest glibc version. Just include <dlcfn.h> and you are good to go.

0

using cmake for me it helped to put -ldl after ssl to the target:

target_link_libraries(ssl_test -WL,--start-group ssl -ldl crypto -WL,--end-group )

Seim2k20
  • 31
  • 5