How to run c program with .so file
Asked Answered
C

4

12

I have gone through all the solutions on StackOverflow as well as Ask Ubuntu.

I have a Go program:

package main

import "C"

//export Getint
func Getint() int {
        return  2
}

func main() {}

and I have generated .so file for the same with name t.so and header filet.h`

Now I would like to use this function in my C program.
I have written the code but I don't know how to execute it.

#include <stdio.h>
#include <t.h>
int main()
{
int a;
a=Getint();
printf("number : %d",a);
return 0;
}

When I execute it with

gcc c.c t.so

it generates a.out file

but at the time of running a.out with ./a.out it gives an error:

./a.out
Error while loading shared libraries: t.so: can not open shared object file: no such file or directory exists.

then I tried with:

gcc -c c.c -l t.so

So it generates c.o file and it is not executable.

Cw answered 25/1, 2016 at 11:52 Comment(1)
all these files are in same locationCw
T
5

Most probably your loader cannot find the library. Try to put the path to the directory where the libarry is located to LD_LIBRARY_PATH prior to run your binary.

export LD_LIBRARY_PATH=/path/to/my/library
./a.out
Tamratamsky answered 25/1, 2016 at 11:56 Comment(1)
There are some concern in modifying "LD_LIBRARY_PATH" such as https://mcmap.net/q/540771/-why-does-setting-ld_library_path-change-the-shared-library-dependencies.Fivestar
U
11

You should use the linker option -rpath, which tells the linker to add information in the executable program where to find runtime libraries like your .so file.

This can be done using the GCC option -Wl which instructs the GCC frontend program to pass an option to the linker:

$ gcc c.c t.so -Wl,-rpath=$(pwd)

This will pass -rpath=$(pwd) to the linker, and $(pwd) causes the shell to call the pwd command to return the current directory.

As long as you don't move the library the program should work.


You can use the environment variable LD_LIBRARY_PATH too, but it's not recommended.

Unsnarl answered 25/1, 2016 at 12:1 Comment(0)
T
5

Most probably your loader cannot find the library. Try to put the path to the directory where the libarry is located to LD_LIBRARY_PATH prior to run your binary.

export LD_LIBRARY_PATH=/path/to/my/library
./a.out
Tamratamsky answered 25/1, 2016 at 11:56 Comment(1)
There are some concern in modifying "LD_LIBRARY_PATH" such as https://mcmap.net/q/540771/-why-does-setting-ld_library_path-change-the-shared-library-dependencies.Fivestar
B
3

.so files are shared object, meaning object that are available to all applications that need them.. that is, shared. Due to this characteristics, they need to be stored in a well known place. Also, they need to be indexed by the dynamic linker.

In linux for instance you typically have a file /etc/ld.so.conf where all directories where shared object are automatically read from are stored

So your options are:

  • Put your shared object file in a well known place
  • Put your shared object file in a place of your choice and let the dynamic linker know about it: in linux you can modify ld.so.conf and run ldconfig to update ld indexes
  • As other suggested write the path of your .so in the env variable LD_LIBRARY_PATH (since dynamic linker reads it before running your application). This must be done at each environment creation
  • As other suggested use -rpath when compiling. Note that in this way you cannot move your .so file after the compilation

Personally I prefer installing the .so file in a system library path

Bonney answered 25/1, 2016 at 12:32 Comment(7)
Would you add information for "a well known place"?Fivestar
As specified in the answer, a "well known place" is whatever directories are already indexed in the file /etc/ld.so.conf; usually /usr/lib is the general purpose path always included, but again.. check for your /etc/ld.so.conf. Note that you may have a directive in /etc/ld.so.conf to include all files present in /etc/ld.so.conf.d/; in this case open them one by one a find what path may better suit for youBonney
Is there any drawback in modifyting "/etc/ld.so.conf" file? I found this, man7.org/linux/man-pages/man8/ldconfig.8.html, and it sounds like manual editing not recommended.Fivestar
I don't see any drawback if you know what you're doing and you are the only user who use your computer. Example scenario: you are working on a project1 for a shared library, and at the same time on a project2 which will use it. I would 1) make prj1 output a file like libprj1.so in target dir 2) add in ld.so.conf absolute path of target 3) run # ldconfig after each recreation of libprj1.so 4) normally compile prj2 with -l prj1 . If you change the lib, you don't need to recompile prj2 (but you need to call ldconfig each time)Bonney
In that scenario I believe you can also compile prj2 with -L /absolute/path/to/target -l prj1.. without modifying ld paths and ldconfigBonney
@CloudCho what are your needs?Bonney
Thanks for sharing a case. I was looking for (manually) putting a generated SO file appropriate folder location, so I could call during executable file runtime (not compiling). - Your "well known" place looks like a good choice, but there is no traceability - (Manually) modifying "/etc/ld.so.conf" sounds more risky. - LD_LIBRARY_PATH not recommanded (ref: "rpath vs. LD_LIBRARY_PATH" at cprogramming.com/tutorial/shared-libraries-linux-gcc.html) - "rpath" is method during CPP code compiling not executable runtime.Fivestar
B
1

You should use LD_LIBRARY_PATH to let the dynamic linker find your shared library in the list. Syntax is similar to PATH a list of directories separted by :.

On OSX this environment variable is called DYLD_LIBRARY_PATH.

Bradleigh answered 25/1, 2016 at 11:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.