问题
I have been trying to compile openssl 1.0.0g with the following rpath:
$ORIGIN/../lib64
Everytime I readelf -d apps/openssl
, I am getting results like the following depending on what escaping variation I tried:
\RIGIN/../lib64
RIGIN/../lib64
ORIGIN/../lib64
I want to setup my rpath without using external tools like chrpath. Is it at all possible? I will basically accept anything that does not involve using external tools like chrpath (though I would already be done with that).
Ideally, I would like to do it by passing options on the command line (any form of -Wl,-rpath,$ORIGIN/../lib64
).
I don't mind editing the generated Makefile, which is what I have been trying last. If only I could get it to print a stupid dollar sign!!! I tried modifying LIBRPATH under the BUILDENV= block with no luck. My best results so far:
LIBRPATH=$$'ORIGIN/../lib64 # result: /../lib64
LIBRPATH=$$$$'ORIGIN/../lib64 # result: 12345<pid>/../lib64
I have read various rpath related questions and tried various escaping and quoting tricks but nothing worked so far!
回答1:
In your makefile try:
-Wl,-rpath,${ORIGIN}/../lib64
I am assuming that the ORIGIN is a shell variable.
EDIT
I have just found an answer to your question (better late then never): You need to prevent make from interpolating variables, to do that you need to use $$ (double dolar sign):
-Wl,-rpath,'$$ORIGIN/../lib64'
I know that it works because I have tested it with my own application, enjoy :)
回答2:
I went the chrpath way. http://enchildfone.wordpress.com/2010/03/23/a-description-of-rpath-origin-ld_library_path-and-portable-linux-binaries/
It is quite complicated to counter shell expansion of `$$ORIGIN`` in openssl. Sooner or later, it gets expanded because of the dollar sign. If you really want to go this way, you can do it. I have found the following to work with openssl 1.0.1g on Linux. In Makefile.shared, look for this line:
DO_GNU_APP=LDFLAGS="$(CFLAGS) -Wl,-rpath,$(LIBRPATH)"
Replace it with the following. This quoting-fu neutralize the expansion of $
. The double $$
is the way to get a single dollar sign in makefiles.
DO_GNU_APP=LDFLAGS="$(CFLAGS) -Wl,-rpath,'"'$$'"ORIGIN/../lib64'"
After compiling:
readelf -d apps/openssl | grep RPATH
0x000000000000000f (RPATH) Library rpath: ['$ORIGIN/../lib64']
回答3:
I don't mind editing the generated Makefile, which is what I have been trying last...
I'm not sure you can set it with a shell variable and relative path. I don't think ldd
expands the $ORIGIN
in $ORIGIN/../lib64
. In this case, I think you need to use ldconfig
to add $ORIGIN/../lib64
to the library search paths. See finding ldd search path on Server Fault for more details.
Since I'm not sure, I'll provide the instructions anyway. You don't need to change the Makefiles. As a matter of fact, I did not have any luck doing so in the past because things get overwritten, and other things like CFLAGS
and LDFLAGS
get ignored.
Also see Build OpenSSL with RPATH? Your question and the cited question are different question that converge on similar answers (no duplicates between them). But it provides the OpenSSL dev's position on RPATHs. It was a private email, so I shared the relevant details rather than the whole message.
If you manage to embed $ORIGIN/../lib64
in the ELF section and it works, then please report back. Below, I am using /usr/local/ssl/lib
for my RPATH. You should substitute $ORIGIN/../lib64
for /usr/local/ssl/lib
.
OpenSSL supports RPATH
's out of the box for BSD targets (but not others). From Configure:
# Unlike other OSes (like Solaris, Linux, Tru64, IRIX) BSD run-time
# linkers (tested OpenBSD, NetBSD and FreeBSD) "demand" RPATH set on
# .so objects. Apparently application RPATH is not global and does
# not apply to .so linked with other .so. Problem manifests itself
# when libssl.so fails to load libcrypto.so. One can argue that we
# should engrave this into Makefile.shared rules or into BSD-* config
# lines above. Meanwhile let's try to be cautious and pass -rpath to
# linker only when --prefix is not /usr.
if ($target =~ /^BSD\-/)
{
$shared_ldflag.=" -Wl,-rpath,\$(LIBRPATH)" if ($prefix !~ m|^/usr[/]*$|);
}
The easiest way to do it for OpenSSL 1.0.2 appears to be add it to linker flags during configuration
./config -Wl,-rpath=/usr/local/ssl/lib
You can also edit Configure line and hard code the rpath
. For example, I am working on Debian x86_64. So I opened the file Configure
in an editor, copied linux-x86_64
, named it linux-x86_64-rpath
, and made the following change to add the -rpath
option:
"linux-x86_64-rpath", "gcc:-m64 -DL_ENDIAN -O3 -Wall -Wl,-rpath=/usr/local/ssl/lib::
-D_REENTRANT::-Wl,-rpath=/usr/local/ssl/lib -ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:
${x86_64_asm}:elf:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::64",
Above, fields 2 and 6 were changed. They correspond to $cflag
and $ldflag
in OpenSSL's builds system.
Then, Configure with the new configuration:
$ ./Configure linux-x86_64-rpath shared no-ssl2 no-ssl3 no-comp \
--openssldir=/usr/local/ssl enable-ec_nistp_64_gcc_128
Finally, after make
, verify the settings stuck:
$ readelf -d ./libssl.so | grep -i rpath
0x000000000000000f (RPATH) Library rpath: [/usr/local/ssl/lib]
$ readelf -d ./libcrypto.so | grep -i rpath
0x000000000000000f (RPATH) Library rpath: [/usr/local/ssl/lib]
$ readelf -d ./apps/openssl | grep -i rpath
0x000000000000000f (RPATH) Library rpath: [/usr/local/ssl/lib]
Once you perform make install
, then ldd
will produce expected results:
$ ldd /usr/local/ssl/lib/libssl.so
linux-vdso.so.1 => (0x00007ffceff6c000)
libcrypto.so.1.0.0 => /usr/local/ssl/lib/libcrypto.so.1.0.0 (0x00007ff5eff96000)
...
$ ldd /usr/local/ssl/bin/openssl
linux-vdso.so.1 => (0x00007ffc30d3a000)
libssl.so.1.0.0 => /usr/local/ssl/lib/libssl.so.1.0.0 (0x00007f9e8372e000)
libcrypto.so.1.0.0 => /usr/local/ssl/lib/libcrypto.so.1.0.0 (0x00007f9e832c0000)
...
来源:https://stackoverflow.com/questions/9399677/how-to-compile-openssl-with-relative-rpath