Linker error on Linux: "undefined reference to"

52,306

Solution 1

Put the libraries after the object files on the link command line:

gcc /media/sf_BitEagle_Projects/cbitcoin/build/obj/testCBAddress.o \
    /media/sf_BitEagle_Projects/cbitcoin/build/obj/CBOpenSSLCrypto.o \
    -L/media/sf_BitEagle_Projects/cbitcoin/build/bin \
    -lcbitcoin -Wl-rpath,/media/sf_BitEagle_Projects/cbitcoin/build/bin \
    -L/usr/local/ssl/lib/ -lssl -lcrypto \
    -o /media/sf_BitEagle_Projects/cbitcoin/build/bin/testCBAddress

If you don't do that, the linker may decide that it needs nothing from a particular library at the stage of the link where it scans the library, and then it won't rescan the library later after it finds some undefined symbols in the object files. If you put the object files first, you don't run into this problem.

Solution 2

I think it caused by can NOT find symbol, gcc will first go through from left, try to put the lib file at the end

Share:
52,306
Matthew Mitchell
Author by

Matthew Mitchell

Developer of iOS and Android Apps. Developer of the cbitcoin library: http://cbitcoin.com.

Updated on September 05, 2020

Comments

  • Matthew Mitchell
    Matthew Mitchell over 3 years

    I am able to make a shared library without problems. I create libcbitcoin.so (with no errors) and attempt to link against it with an executable as well as OpenSSL libraries. I use this command:

    gcc -L/media/sf_BitEagle_Projects/cbitcoin/build/bin -lcbitcoin \
    -Wl-rpath,/media/sf_BitEagle_Projects/cbitcoin/build/bin -lssl -lcrypto \
    -L/usr/local/ssl/lib/ -o /media/sf_BitEagle_Projects/cbitcoin/build/bin/testCBAddress \
    /media/sf_BitEagle_Projects/cbitcoin/build/obj/testCBAddress.o \
    /media/sf_BitEagle_Projects/cbitcoin/build/obj/CBOpenSSLCrypto.o
    

    The bin directory is the location of the library. The obj directory has the object files I wish to link into an executable. In the command I use the -L, -l and -rpath options which I thought was all that is needed for linking in linux. It seems I am wrong since I get errors like:

    /media/sf_BitEagle_Projects/cbitcoin/test/testCBAddress.c:40:
    undefined reference to `CBNewByteArrayFromString'
    

    CBNewByteArrayFromString is found in the library. For some reason it is not being linked. OpenSSL too:

    /media/sf_BitEagle_Projects/cbitcoin/dependencies/crypto/CBOpenSSLCrypto.c:37:
    undefined reference to `SHA1'
    

    How do I get the linking to work?

    GCC version: gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3

    On Linux Mint 13

    Thank you.

    • Jonathan Leffler
      Jonathan Leffler over 11 years
      Are you sure you want to hard-wire the /media/sf_BitEagle_Projects/cbitcoin/build/bin path into your executable?
    • Matthew Mitchell
      Matthew Mitchell over 11 years
      Here I'm just linking a test. It's designed to be run to test the library so it doesn't matter as long as it works after it has been built.
    • Jonathan Leffler
      Jonathan Leffler over 11 years
      OK — you're sure; that's fine.
    • Victor Sergienko
      Victor Sergienko almost 11 years
  • Ribo
    Ribo over 10 years
    Fixed my problem too. What a terrible(counter-intuitive, unexpected) bug/design-decision that is (to make the order of the options relative to the positional parameters significant) Conventionally options come first and other parameters follow.
  • Jonathan Leffler
    Jonathan Leffler over 10 years
    The -L options can go more or less anywhere on the command line, but you need to think of the -l name options as specifying a file that is processed at that point in the command line (so any relevant -L flag should preceed it). It has always been thus, since the beginning of (Unix) time — some time in the 1970s, anyway.
  • IMSoP
    IMSoP over 9 years
    It seems that the order of the -l options relative to each other matters as well, and the more general / lower level dependencies should come last, not first. I was getting undefined reference to 'pow' until I moved -lm to the very end of my option string.