Thread: Help me link to a .so

  1. #1
    Registered User
    Join Date
    Feb 2009
    Posts
    33

    Help me link to a .so

    I am trying to call one function in a .so which contains quite a lot of functions, but after having tried to get it working for days, am at a dead end. Using the nm command, the .so has a few undefined symbols, but the vast majority, including the one I am calling, are defined (labelled with a 'T'), so I see no reason for the linking to fail.

    The code that originally created the .so is not mine, the most involved I got was to run it's Makefile. A note is that a different project that relies on this .so, and other .so's, works fine on my machine, but I've been unable to find out how exactly they use the .so's.

    Code is:
    Code:
    #include <stdio.h>
    
    int main(void)
    {
    	int i;
    	i = SCIPtechVersion();
    	printf("Version is %i.\n", i);
    	return 0;
    }
    I have tried a number of ways to get the linking working, using different arrangements of -shared, -static, or no options

    1)
    Makefile:
    Code:
    SCIPDIR = /home/andy/Project/Source/ziboptsuite-1.2.0/scip-1.2.0
    HOMELIB = /home/andy/Project/Lib
    
    test:
    	gcc -shared test.c -o test.o
    	gcc test.o $(HOMELIB)/scip-1.2.0/libscip.so -o test
    
    clean:
    	rm test.o test
    Output is:
    Code:
    /home/andy/Project/Lib/scip-1.2.0/libscip.so: undefined reference to `gzputc'
    /home/andy/Project/Lib/scip-1.2.0/libscip.so: undefined reference to `SCIPlpiInfinity'
    /home/andy/Project/Lib/scip-1.2.0/libscip.so: undefined reference to `gzflush'
    /home/andy/Project/Lib/scip-1.2.0/libscip.so: undefined reference to `SCIPlpiGetObjval'
    /home/andy/Project/Lib/scip-1.2.0/libscip.so: undefined reference to `sqrt'
    .
    .
    .
    /home/andy/Project/Lib/scip-1.2.0/libscip.so: undefined reference to `fesetround'
    /home/andy/Project/Lib/scip-1.2.0/libscip.so: undefined reference to `SCIPlpiIsObjlimExc'
    /home/andy/Project/Lib/scip-1.2.0/libscip.so: undefined reference to `log10'
    /home/andy/Project/Lib/scip-1.2.0/libscip.so: undefined reference to `BMSduplicateBlockMemory_call'
    collect2: ld returned 1 exit status
    make: *** [test] Error 1
    True, these functions are undefined the original .so, but I am not asking to use these.
    2)
    Code:
    SCIPDIR = /home/andy/Project/Source/ziboptsuite-1.2.0/scip-1.2.0
    HOMELIB = /home/andy/Project/Lib
    
    test:
    	gcc -shared test.c -o test.o
    	gcc -shared test.o $(HOMELIB)/scip-1.2.0/libscip.so -o test
    
    clean:
    	rm test.o test
    The linking performs fine, but when I run the test binary, I get a segmentation fault.
    nm reveals that the symbol representing SCIPtechVersion isn't present in test, although it is present in test.o.

    3)
    Trying to link test.o and the .so file with -static fails because test.o is compiled as a dynamic object. If I try to compile test.c without the -shared option, it obviously fails due to the undefined function reference.


    I am desperate to resolve this issue. Hopefully, I've included enough information.

  2. #2
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    perhaps!
    Code:
    gcc test.c -L$(HOMELIB)/scip-1.2.0 -lscip -o test

  3. #3
    Registered User
    Join Date
    Sep 2007
    Posts
    1,012
    Don't use -shared with your code. That's used to create a shared library.

    You're really going to want to fix the unresolved symbols issue. You realize that even if you don't make use of those functions, code you call might? Thankfully some of them are easy. Use -lm and -lz to link in libm and libz which provide some functions you're missing. You're on your own for the non-standard functions; you could always just create stubs and hope for the best.

    You might be able to tell your linker to ignore unresolved symbols (GNU's linker supports --unresolved-symbols=ignore-all); but that's treading on dangerous ground.

  4. #4
    Registered User
    Join Date
    Feb 2009
    Posts
    33
    Quote Originally Posted by itCbitC View Post
    perhaps!
    Code:
    gcc test.c -L$(HOMELIB)/scip-1.2.0 -lscip -o test
    Gives me the same output as:
    gcc test.o $(HOMELIB)/scip-1.2.0/libscip.so -o test
    Quote Originally Posted by cas View Post
    Don't use -shared with your code. That's used to create a shared library.
    Are you referring to the use of -shared when compiling test.c, or when linking the objects? If test.c, then what would you suggest, as using that option is the only way I've find to get test.c to compile with the undefined function call.
    Quote Originally Posted by cas View Post
    You're really going to want to fix the unresolved symbols issue. You realize that even if you don't make use of those functions, code you call might? Thankfully some of them are easy. Use -lm and -lz to link in libm and libz which provide some functions you're missing. You're on your own for the non-standard functions; you could always just create stubs and hope for the best.
    Thanks for this tip. Including the other libraries in the library directory, as well as -lm, lz and -lreadline fixed all of the 'undefined reference' issues.

    The two lines in the "test:" section of the makefile are now:
    Code:
    gcc -shared test.c -o test.o
    gcc test.o -L$(HOMELIB)/scip-1.2.0 -llpispx -lobjscip -lscip -lsopex -lm -lz -lreadline -o test
    However, when I make and run, I get the error:
    ./test: error while loading shared libraries: test.o: cannot open shared object file: No such file or directory
    If I replace test.o with FULL-DIRECTOR-PATH/test.o, and similarly for the libraries, as issue arises from them, the code compiles and runs fine. It seems as if the linker forgest to give the test binary the library locations. Any idea why this happens?

  5. #5

  6. #6
    Registered User
    Join Date
    Sep 2007
    Posts
    1,012
    Are you referring to the use of -shared when compiling test.c, or when linking the objects? If test.c, then what would you suggest, as using that option is the only way I've find to get test.c to compile with the undefined function call.
    When building test.c. As I indicated, you really don't want to force a link with undefined references. You seem to have fixed them up, so why would you still want to get around that issue?
    However, when I make and run, I get the error:
    ./test: error while loading shared libraries: test.o: cannot open shared object file: No such file or directory
    That's because you used -shared when you build test.c. Now you've made it a shared object that the runtime linker will have to search for. It's not the linker's job to give library locations. You should put libraries in standard locations, use $LD_LIBRARY_PATH, or use -rpath (or its equivalent) when linking. That is, it's your job to make sure things are where they should be.

    But it's all moot. Don't build with -shared and you won't have to deal with test.o being a shared object.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Help me please.
    By yann in forum C Programming
    Replies: 15
    Last Post: 09-29-2009, 09:04 PM
  2. Linked List, Please Help!
    By CodeMonkeyZ in forum C Programming
    Replies: 5
    Last Post: 02-17-2009, 06:23 AM
  3. Function to check memory left from malloc and free?
    By Lechx in forum C Programming
    Replies: 4
    Last Post: 04-24-2006, 05:45 AM
  4. Request for comments
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 15
    Last Post: 01-02-2004, 10:33 AM
  5. Red Hat Linux GNU Link Question
    By PieartL in forum Linux Programming
    Replies: 2
    Last Post: 02-28-2002, 12:05 PM