I compiled a object file shm.o
and packaged it as a shared library libshm.so
arm-linux-gnueabihf-gcc -fPIC -o shm.o -c shm.c
arm-linux-gnueabihf-gcc -shared shm.o -o libshm.so -lrt
where shm.c
and output of nm libshm.so
are shown as follow.
/*shm.c*/
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
void func_shm(void)
{
int ret = shm_open("/test_shm", O_CREAT, 0644);
}
/*output of nm libshm.so*/
00000328 t $a
000002e4 t $a
00000484 t $a
...
...
00000328 t call_weak_fn
0001102c b completed.10740
w __cxa_finalize@@GLIBC_2.4
...
...
0000034c t deregister_tm_clones
000003e0 t __do_global_dtors_aux
00010f0c t __do_global_dtors_aux_fini_array_entry
00011028 d __dso_handle
00010f10 a _DYNAMIC
00000484 t _fini
00000448 t frame_dummy
00010f08 t __frame_dummy_init_array_entry
00000498 r __FRAME_END__
0000044c T func_shm
00011000 a _GLOBAL_OFFSET_TABLE_
w __gmon_start__
000002e4 t _init
w _ITM_deregisterTMCloneTable
w _ITM_registerTMCloneTable
00000390 t register_tm_clones
U shm_open@@GLIBC_2.4
0001102c d __TMC_END__
As it can see, at the second line to last, shm_open
is a undefined symbol even though -lrt
is appended.
As per shm_open(3) — Linux manual page; However, the version of glibc shown in the nm
is 2.4.
These functions are provided in glibc 2.2 and later.
My expectation are
libshm.so
will have a definition of
shm_open
, because -lrt
is appended at the end of command; Therefore shm_open
will not be an undefined symbol.
Any application that invokes func_shm
only needs to link to
libshm.so
without specifying -lrt
What should be done to get this problem fixed?
As it can see, at the second line to last, shm_open is a undefined symbol even though -lrt is appended.
This is expected: you are linking against librt.so
. The definition of shm_open
is in librt.so
, and not in your library.
My expectation is that after linking process, libshm.so will have a definition of shm_open, so shm_open should not be an undefined symbol.
This expectation is wrong.
What you described is what would have happened if you linked with librt.a
(archive library). In that case, the linker would have pulled the object implementing shm_open()
into libshm.so
.
But since you are linking against librt.so
(which provides the definition), the linker simply records that librt.so
is required at runtime, and that shm_open()
will need to come from some external shared library at runtime. The reference to shm_open()
in libshm.so
remains unresolved.
In addition, any application that invokes func_shm only needs to link to libshm.so without specifying -lrt
This is indeed what should already happen (provided you link libshm.so
against -lrt
, like your command line shows).
If the application itself doesn't call anything from librt.so
, and only calls func_shm()
, then linking it with gcc main.o -L/... -lshm
should work.
I tried this on Linux/x86_64, and it worked:
gcc -fPIC -shared -o libshm.so shm.c -lrt
# Verify that libshm.so requires librt.so:
readelf -d libshm.so | grep NEEDED
0x0000000000000001 (NEEDED) Shared library: [librt.so.1]
gcc main.c -L. -lshm
# success
Now, you might be confused because the application linked as above will not actually run:
./a.out
./a.out: error while loading shared libraries: libshm.so: cannot open shared object file: No such file or directory
But that is an entirely different problem -- the application doesn't know which directory to find libshm.so
. To fix this, add -Wl,-rpath=/path/to/dir
(which /path/to/dir
is the directory in which libshm.so
is to be found at runtime).