undefined reference

This is a discussion on undefined reference within the C Programming forums, part of the General Programming Boards category; Let me preface by saying I am a newbie learning C. I am really pounding my head against the wall. ...

  1. #1
    Registered User
    Join Date
    Feb 2011
    Posts
    15

    undefined reference

    Let me preface by saying I am a newbie learning C. I am really pounding my head against the wall. I am using a header file that has a function suchandsuch () when I am calling this function from the main I am getting "undefined reference" error like it is not seeing the header file. I am using linux and eclipse.

    Here are clips from the files to implement:

    Main (main.c)

    #include "modbus.h"

    int main(void)
    {
    int socket;
    modbus_t *ctx;
    modbus_mapping_t *mb_mapping;

    ctx = modbus_new_tcp("127.0.0.1", 1502); /*this is the error for undefined*/

    HeaderFile1 (modbus.h)

    #include "modbus-tcp.h"
    #include "modbus-rtu.h"

    HeaderFile2 (modbus-tcp.h)

    #include modbus.h

    modbus_t* modbus_new_tcp(const char *ip_address, int port);
    /*Here is where the function is*/



    This seems to be pretty straight forward which is making me think it is something I am doing on the eclipse ide incorrectly. If it matters I am using Linux/Ubuntu and the header files are in usr/include/modbus. Any help would be greatly appreciated!

  2. #2
    Registered User
    Join Date
    May 2009
    Posts
    2,587
    "undefined reference" normally means you are not linking the library correctly; this is NOT the same as including the correct header file.

    Do you know the difference between compile and linker errors?

    Tim S.

  3. #3
    Third Eye Babkockdood's Avatar
    Join Date
    Apr 2010
    Posts
    352
    Use code tags, please.
    Quote Originally Posted by The Jargon File
    Microsoft Windows - A thirty-two bit extension and graphical shell to a sixteen-bit patch to an eight-bit operating system originally coded for a four-bit microprocessor which was written by a two-bit company that can't stand one bit of competition.

  4. #4
    Registered User
    Join Date
    Feb 2011
    Posts
    15
    I looked up linking errors. I am confused on what this is because I have provided the file path to the files in question. ( usr/include/modbus ) shows up in my include folder in eclipse for this project and (although not sure what it is yet) the fileName.o shows all of the files in question.

  5. #5
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by Trinity32244 View Post
    I looked up linking errors. I am confused on what this is because I have provided the file path to the files in question. ( usr/include/modbus ) shows up in my include folder in eclipse for this project and (although not sure what it is yet) the fileName.o shows all of the files in question.
    Are your include files (.h) and libraries (.o or .lib) in the same place?

    The compiler needs the includes
    The linker needs the libraries

    Usually there are two separate paths.

  6. #6
    Registered User
    Join Date
    Feb 2011
    Posts
    15
    I don't think their are any other files than the 4 header files included that are all .h .
    modbus.h
    modbus-tcp.h
    modbus-rtu.h
    modbus-version.h

    There are no .o or .lib files

  7. #7
    Registered User
    Join Date
    Feb 2011
    Posts
    15
    Thanks to all who have helped. I think that I have found the solution to the issue. As Tater said, there seems to be a library file with a .la extension or maybe the file that has .pc extension. For a newbie I am not sure why this file is needed at all because you have functions and header files which all of the logic seems to be there for everything to work with just the header files and the functions defined within them. In eclipse I right clicked on the project file then expanded the "C/C++ Build" then went to "settings" then expanded the "GCC C Linker" then went to "Libraries" then went under "Libraries (-l)" and added "modbus" it seemed to work. I am guessing that the default location for this to search is /usr/local/lib/pkgconfig which contained the file modbus.pc . Although I also changed the file name in eclipse libmodbus to test because I also have a file in /usr/local/lib called libmodbus.la and I don't get any errors with this either. Hope this helps someone in the future so they don't waste the 3.5 hours I did. Anybody to further explain for myself and other newbies would be appreciated I am sure.

  8. #8
    cas
    cas is offline
    Registered User
    Join Date
    Sep 2007
    Posts
    984
    .pc files are not libraries, but are pkg-config files, which contain information on how to find libraries (and headers, and other information) regardless of where a package is installed.

    .la files are libtool archive files and are the spawn of the devil. These are created by libtool along with the actual libraries, and they are unnecessary, unless you're using libltdl (part of libtool) to dynamically load objects. .la files are terrible because they contain hardcoded paths of other libraries, meaning if these are moved, the .la file breaks horribly, even though the actual libraries can gracefully deal with this.

    .so files are shared libraries.

    .a files are static libraries.

    Only the .so and .a files are the actual libraries.

  9. #9
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by Trinity32244 View Post
    Thanks to all who have helped. I think that I have found the solution to the issue. As Tater said, there seems to be a library file with a .la extension or maybe the file that has .pc extension. For a newbie I am not sure why this file is needed at all because you have functions and header files which all of the logic seems to be there for everything to work with just the header files and the functions defined within them.
    The header files contain prototypes... a bit of text describing the functions and variables to the compiler. They do not contain the actual machine code to make the function work... all they do is make a promise that the function's code exists *somewhere else*. It's kind of like telling a Cop ... "My license is at home" so that you can continue on your way (and we all know how well that works...)

    The actual code to make the various functions work will be contained in libraries, files made up of little blobs of machine code that are piled together to make your program. There's no promise here, the linker is a smart cop and he takes you home for a look... No license and you're in trouble.... no little blob of code and you don't get a working program.

  10. #10
    Registered User
    Join Date
    Feb 2011
    Posts
    15
    Thanks for both replies!! I am a little confused where the default location eclipse is looking then. When I went to the GCC C Linker > Libraries > Libraries (-l) in eclipse all I typed in was "modbus". As I look through my file system under /usr/local/lib there is no file or folder with name "modbus" (there are a few that are libmodbus.so.2 and libmodbus.so.2.0.0 and libmodbus.la and libmodbus.so but eclipse can't be looking at these with "modbus" as the entry. If I go to the folder in this directory pkgconfig ( /usr/local/lib/pkgconfig ) there is a file modbus.pc that has the following code:

    prefix=/usr/local
    exec_prefix=${prefix}
    libdir=${exec_prefix}/lib
    includedir=${prefix}/include

    Name: modbus
    Description: Modbus library
    Requires:
    Version: 2.0.3
    Libs: -L${libdir} -lmodbus
    Cflags: -I${includedir}

    Is this what eclipse is looking at? My problem seems to be resolved as stated above but I would definitely like to understand how this is working. Is seems I didn't (don't) even understand the basics of how all of this works because I thought the compiler looks at the .c and the .h files and translates to the assembly (machine) code directly at time of compile/build. It sounds like you pre-compile each .h file and during your main project compiling it does not look at the .h c code but instead expects a pre-compiled assembly code. If this is correct where are the compiled files for each .h stored? I can open each .h file in a text editor so either there are separate files (compiled and c text) or the text editor has the ability to translate the assembly code to c right? Sounds like the ladder would be true that the text editor sees .h extension and translates but if this is the case then all I should need is the header files with functions and still don't understand the need for the library? Getting way off topic but still appreciate any insight to help understand.

    From Tater's response, which seems to have already answered some of my questions, but I forgot to mention (to explain some of my confusion) that I see my custom header libraries but I don't see where the library is for like stdio.h or math.h ect and when I do a search for stdio.so on my computer I come up with no results?
    Last edited by Trinity32244; 04-08-2011 at 06:19 AM.

  11. #11
    Registered User
    Join Date
    Sep 2008
    Posts
    200
    Quote Originally Posted by Trinity32244 View Post
    ...there are a few that are libmodbus.so.2 and libmodbus.so.2.0.0 and libmodbus.la and libmodbus.so but eclipse can't be looking at these with "modbus" as the entry.

    Is seems I didn't (don't) even understand the basics of how all of this works...
    If you'd like to, this article will (hopefully) be helpful.

  12. #12
    cas
    cas is offline
    Registered User
    Join Date
    Sep 2007
    Posts
    984
    If this is correct where are the compiled files for each .h stored?
    That's the $64,000 question. The answer is, who knows?

    There's not necessarily (or perhaps even usually) a 1 to 1 correspondence between header files and libraries. There are many standard header files (stdio.h, string.h, locale.h, math.h), and so on; but on a typical Unix-like system, there are only two libraries that provide standard function: libc and libm. The latter holds math functions, the former holds all other functions. By default libc is linked, but libm is not. This division is historical and really shouldn't exist anymore, but there you are. On other systems, there might be only one standard library, or it might be split up into even more libraries. You just have to learn how a particular implementation works.

    Perhaps there should be an automatic way for a compiler/linker combination to determine what libraries are needed when linking, but that ship has sailed. When it comes to 3rd party libraries, you just have to know what to link in. pkg-config fixes this problem to some degree, by making it so you only have to know the package name, not the library name(s).

    went under "Libraries (-l)" and added "modbus" it seemed to work
    there are a few that are libmodbus.so.2 and libmodbus.so.2.0.0 and libmodbus.la and libmodbus.so but eclipse can't be looking at these with "modbus" as the entry
    It sounds to me like Eclipse did look at those (or rather, directed the linker to look at them). If you are linking and say "-lmodbus", the linker will look for a file called libmodbus.so or libmodbus.a. Since Eclipse described the "Libraries" section with a "-l", I suspect this is precisely what it did.

    It's possible, of course, that Eclipse knows about pkg-config, and if so, that would be the preferred method for finding libraries.

  13. #13
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by cas View Post
    Perhaps there should be an automatic way for a compiler/linker combination to determine what libraries are needed when linking, but that ship has sailed. When it comes to 3rd party libraries, you just have to know what to link in. pkg-config fixes this problem to some degree, by making it so you only have to know the package name, not the library name(s).
    Actually there is a way to correlate headers with libs...
    Code:
    #pragma comment(lib,libname.lib)
    
    #pragma lib "libname.lib"
    If your compiler supports it, these can inserted into the .h files to automatically find and include the correct libraries.

    I don't know how extensive the usage is elsewhere... but Pelles C does this with windows headers. You include the header and the linker is informed which library to use... extremely handy.

  14. #14
    Registered User
    Join Date
    Feb 2011
    Posts
    15
    First thanks a lot JohnGrahm and cas. The tutorial definitely cleared a lot of it up for me (although not sure I understand why it is done this way I will surely concede smart men then me established these methods and move on).

    cas you cleared up my confusion in that I did not understand how "modbus" could translate to libmodbus by eclipse but it makes since that the files are prefixed with "lib" all of the time so no need to put that in there and let eclipse or the gcc linker assume that the it is looking for "lib"+"entered_library_name".

    All in all, this makes very little since to me why it is done this way. The compiler already has to compile your code why not compile the the headers as well. I guess it saves time when compiling which may be an issue for big projects (maybe similar to rendering a large 3D CAD drawing can take 3 hours sometimes).

    Thanks again to all that have helped!!!!!!!!!!!!!!!!

  15. #15
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by Trinity32244 View Post
    First thanks a lot JohnGrahm and cas. The tutorial definitely cleared a lot of it up for me (although not sure I understand why it is done this way I will surely concede smart men then me established these methods and move on).
    You're talking about a programming method that was put into place some 40 years ago... the idea then was that one linker could be used with several different compilers. Now it is as it is for "backward compatibility" with older code...

    All in all, this makes very little since to me why it is done this way. The compiler already has to compile your code why not compile the the headers as well. I guess it saves time when compiling which may be an issue for big projects (maybe similar to rendering a large 3D CAD drawing can take 3 hours sometimes).
    Compilers don't do what you appear to think they do... A compiler does not write machine code. It creates a map of the program by crunching your source code down to a set of organized tokens and function calls.... Then the linker takes the object file, gathers up all the little blobs of code from libraries and, using the compiler's map, it creates the final executable.

    Think of it this way... the compiler builds the toy... the linker puts it in the box.

    Newer compilers (mercifully) execute the linker automatically, but these are two separate processes.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 4
    Last Post: 05-13-2011, 08:28 AM
  2. Replies: 7
    Last Post: 10-09-2007, 02:37 PM
  3. Problem with Makefile
    By pinkprincess in forum C Programming
    Replies: 3
    Last Post: 06-24-2007, 09:02 AM
  4. Textbox
    By maxorator in forum Windows Programming
    Replies: 20
    Last Post: 09-25-2005, 10:04 AM
  5. compiler problem
    By sofarsoclose in forum C Programming
    Replies: 3
    Last Post: 07-10-2003, 11:39 AM

Tags for this Thread


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21