Jun 19, 2009 3:09 PM
$ORIGIN feature for C++ linking on AIX power?
Hello everyone!
I have an C++ application that uses a shared object. I would like to be able to build my program and then run it from another directory. Fine so far. My problem, is that I don't know where the shared library and executable will be installed - my software is provided to another group.
I think that typically the shared object would be installed at /usr/local/lib, or some application-specific path, like /opt/foo1/lib. But in my case, the shared object is side-by-side with the executable. Another group uses our objects and may choose to deploy this in a different directory.
Really, what I want is the $ORIGIN feature that is available on ELF systems. I suppose there is some way to do this with XCOFF, but I can't figure it out.
Here is an example to show the problem - the source files are taken form the "AIX Linking and Loading" guide. Assume 2 libraries (share1.c share2.c) and one executable (main.c)
bb04wrk31:/u/bioliv> cat share1.c
/************
#include <stdio.h>
void func1 (){
printf("func1 called\n");
}
void func2 (){
printf("func2 called\n");
}
bb04wrk31:/u/bioliv> cat share2.c
/************
void func3 (){
printf("func3 called\n");
}
bb04wrk31:/u/bioliv>
bb04wrk31:/u/bioliv>
bb04wrk31:/u/bioliv> cat main.c
#include <stdio.h>
extern void func1 (),
func2 (),
func3 ();
main (){
func1 ();
func2 ();
func3 ();
}
Build the shared libaries...
bb04wrk31:/u/bioliv> xlC -G -q64 share2.c -o share2.so
bb04wrk31:/u/bioliv> xlC -G -q64 share1.c -o share1.so
Build the main executable...
bb04wrk31:/u/bioliv> xlC -q64 main.c -o main share1.so share2.so
Works fine from current directory...
bb04wrk31:/u/bioliv> ./main
func1 called
func2 called
func3 called
Does not work when called from another directory...
bb04wrk31:/u/bioliv> mkdir foodir
bb04wrk31:/u/bioliv> cd foodir
bb04wrk31:/u/bioliv/foodir> ../main
Could not load program ../main:
Dependent module share1.so could not be loaded.
Could not load module share1.so.
System error: No such file or directory
Here is why...
bb04wrk31:/u/bioliv/foodir> ldd ../main
../main needs:
/usr/lib/libc.a(shr_64.o)
/usr/vacpp/lib/libC.a(shr_64.o)
/usr/vacpp/lib/libC.a(ansi_64.o)
Cannot find share1.so
Cannot find share2.so
/unix
/usr/lib/libcrypt.a(shr_64.o)
/usr/vacpp/lib/libC.a(ansicore_64.o)
/usr/vacpp/lib/libC.a(shrcore_64.o)
/usr/vacpp/lib/libC.a(shr3_64.o)
/usr/vacpp/lib/libC.a(shr2_64.o)
bb04wrk31:/u/bioliv/foodir> dump -H -X64 ../main
../main:
***Loader Section***
Loader Header Information
VERSION# #SYMtableENT #RELOCent LENidSTR
0x00000001 0x00000010 0x00000027 0x00000078
#IMPfilID OFFidSTR LENstrTBL OFFstrTBL
0x00000006 0x00000428 0x000000ee 0x000004a0
***Import File Strings***
INDEX PATH BASE MEMBER
0 /usr/vac/lib:/usr/vacpp/lib:/usr/lib:/lib
1 libc.a shr_64.o
2 libC.a shr_64.o
3 libC.a ansi_64.o
4 share1.so
5 share2.so
If I knew where the application would be deployed, I could write the install directory into the executable, using -blibpath, like this:
bb04wrk31:/u/bioliv> xlC -q64 main.c -o main share1.so share2.so -blibpath:/u/bioliv/:/usr/local/lib:/usr/lib:/lib
bb04wrk31:/u/bioliv> cd foodir
bb04wrk31:/u/bioliv/foodir> ../main
func1 called
func2 called
func3 called
bb04wrk31:/u/bioliv/foodir> !dump
dump -H -X64 ../main
../main:
***Loader Section***
Loader Header Information
VERSION# #SYMtableENT #RELOCent LENidSTR
0x00000001 0x00000010 0x00000027 0x00000076
#IMPfilID OFFidSTR LENstrTBL OFFstrTBL
0x00000006 0x00000428 0x000000ee 0x0000049e
***Import File Strings***
INDEX PATH BASE MEMBER
0 /u/bioliv/:/usr/local/lib:/usr/lib:/lib
1 libc.a shr_64.o
2 libC.a shr_64.o
3 libC.a ansi_64.o
4 share1.so
5 share2.so
I could also fix this at run-time using $LIBPATH, but that is not what I want.
Really, what I want is something like this:
bb04wrk31:/u/bioliv> xlC -q64 main.c -o main share1.so share2.so -blibpath:\$ORIGIN:/usr/local/lib:/usr/lib:/lib
But that doesn't seem to work.
Help!
-bill
I have an C++ application that uses a shared object. I would like to be able to build my program and then run it from another directory. Fine so far. My problem, is that I don't know where the shared library and executable will be installed - my software is provided to another group.
I think that typically the shared object would be installed at /usr/local/lib, or some application-specific path, like /opt/foo1/lib. But in my case, the shared object is side-by-side with the executable. Another group uses our objects and may choose to deploy this in a different directory.
Really, what I want is the $ORIGIN feature that is available on ELF systems. I suppose there is some way to do this with XCOFF, but I can't figure it out.
Here is an example to show the problem - the source files are taken form the "AIX Linking and Loading" guide. Assume 2 libraries (share1.c share2.c) and one executable (main.c)
bb04wrk31:/u/bioliv> cat share1.c
/************
- share1.c: shared library source.
#include <stdio.h>
void func1 (){
printf("func1 called\n");
}
void func2 (){
printf("func2 called\n");
}
bb04wrk31:/u/bioliv> cat share2.c
/************
- share2.c: shared library source.
void func3 (){
printf("func3 called\n");
}
bb04wrk31:/u/bioliv>
bb04wrk31:/u/bioliv>
bb04wrk31:/u/bioliv> cat main.c
#include <stdio.h>
extern void func1 (),
func2 (),
func3 ();
main (){
func1 ();
func2 ();
func3 ();
}
Build the shared libaries...
bb04wrk31:/u/bioliv> xlC -G -q64 share2.c -o share2.so
bb04wrk31:/u/bioliv> xlC -G -q64 share1.c -o share1.so
Build the main executable...
bb04wrk31:/u/bioliv> xlC -q64 main.c -o main share1.so share2.so
Works fine from current directory...
bb04wrk31:/u/bioliv> ./main
func1 called
func2 called
func3 called
Does not work when called from another directory...
bb04wrk31:/u/bioliv> mkdir foodir
bb04wrk31:/u/bioliv> cd foodir
bb04wrk31:/u/bioliv/foodir> ../main
Could not load program ../main:
Dependent module share1.so could not be loaded.
Could not load module share1.so.
System error: No such file or directory
Here is why...
bb04wrk31:/u/bioliv/foodir> ldd ../main
../main needs:
/usr/lib/libc.a(shr_64.o)
/usr/vacpp/lib/libC.a(shr_64.o)
/usr/vacpp/lib/libC.a(ansi_64.o)
Cannot find share1.so
Cannot find share2.so
/unix
/usr/lib/libcrypt.a(shr_64.o)
/usr/vacpp/lib/libC.a(ansicore_64.o)
/usr/vacpp/lib/libC.a(shrcore_64.o)
/usr/vacpp/lib/libC.a(shr3_64.o)
/usr/vacpp/lib/libC.a(shr2_64.o)
bb04wrk31:/u/bioliv/foodir> dump -H -X64 ../main
../main:
***Loader Section***
Loader Header Information
VERSION# #SYMtableENT #RELOCent LENidSTR
0x00000001 0x00000010 0x00000027 0x00000078
#IMPfilID OFFidSTR LENstrTBL OFFstrTBL
0x00000006 0x00000428 0x000000ee 0x000004a0
***Import File Strings***
INDEX PATH BASE MEMBER
0 /usr/vac/lib:/usr/vacpp/lib:/usr/lib:/lib
1 libc.a shr_64.o
2 libC.a shr_64.o
3 libC.a ansi_64.o
4 share1.so
5 share2.so
If I knew where the application would be deployed, I could write the install directory into the executable, using -blibpath, like this:
bb04wrk31:/u/bioliv> xlC -q64 main.c -o main share1.so share2.so -blibpath:/u/bioliv/:/usr/local/lib:/usr/lib:/lib
bb04wrk31:/u/bioliv> cd foodir
bb04wrk31:/u/bioliv/foodir> ../main
func1 called
func2 called
func3 called
bb04wrk31:/u/bioliv/foodir> !dump
dump -H -X64 ../main
../main:
***Loader Section***
Loader Header Information
VERSION# #SYMtableENT #RELOCent LENidSTR
0x00000001 0x00000010 0x00000027 0x00000076
#IMPfilID OFFidSTR LENstrTBL OFFstrTBL
0x00000006 0x00000428 0x000000ee 0x0000049e
***Import File Strings***
INDEX PATH BASE MEMBER
0 /u/bioliv/:/usr/local/lib:/usr/lib:/lib
1 libc.a shr_64.o
2 libC.a shr_64.o
3 libC.a ansi_64.o
4 share1.so
5 share2.so
I could also fix this at run-time using $LIBPATH, but that is not what I want.
Really, what I want is something like this:
bb04wrk31:/u/bioliv> xlC -q64 main.c -o main share1.so share2.so -blibpath:\$ORIGIN:/usr/local/lib:/usr/lib:/lib
But that doesn't seem to work.
Help!
-bill
