For forensic reason I want to compile some basic tool on Centos like cat,grep,vi,find,md5sum,dir..etc.It's very important to check the process list when we do forensic.so I try to compile ps(procps) statically.and I do failed.
here are the steps I tried:
git clone https://gitlab.com/procps-ng/procps.git
cd procps
./autogen.sh
./configure LDFLAGS="-static"
make SHARED=0 CC='gcc -static'
also googled so many posts and tried:
./configure LDFLAGS="-all-static"
./configure --enable-static --disable-shared
make SHARED=0 CC='gcc -static'
make -e LDFLAGS=-all-static
export LDFLAGS="-static -Wl,--no-export-dynamic"
make -e LDFLAGS=-all-static
make sense CC="gcc -static"
and combination of these configuration with make,none of this working,some compile failed and some success,but when I check it with ldd pscommands,it showed
[root#localhost ps]# ldd pscommand
linux-vdso.so.1 => (0x00007ffca9bc2000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007f3b078cd000)
libc.so.6 => /lib64/libc.so.6 (0x00007f3b07500000)
/lib64/ld-linux-x86-64.so.2 (0x00007f3b07ad1000)
Is procps has some deep dependent on these non static libary?
Just compiled for procps-ng-3.3.16 (the latest now), try :
./configure \
--disable-shared \
LDFLAGS=--static
You may need to install glibc-static.
Related
Say that you got a c program, but almost any program will do, and put it in a file:
#include <stdio.h>
#include <gnu/libc-version.h>
int main (void) {
puts (gnu_get_libc_version ());
return 0;
}
And say that you want to build it against a specific version of glibc, for some reason. My initial attempt at doing this would be to create a Guix environment containing that old version of glibc along with gcc (and coreutils for programs like ls).
$ guix environment --pure --ad-hoc glibc#2.29 gcc-toolchain coreutils
$ rm a.out && gcc printer.c && ldd a.out && a.out
linux-vdso.so.1 (0x00007ffd2cd0c000)
libgcc_s.so.1 => /gnu/store/jlrfl1ss3b4xjggvajwffa9zppfcxksf-gcc-5.5.0-lib/lib/libgcc_s.so.1 (0x00007fcefd7b6000)
libc.so.6 => /gnu/store/fa6wj5bxkj5ll1d7292a70knmyl7a0cr-glibc-2.31/lib/libc.so.6 (0x00007fcefd5f9000)
/gnu/store/fa6wj5bxkj5ll1d7292a70knmyl7a0cr-glibc-2.31/lib/ld-linux-x86-64.so.2 (0x00007fcefd7d1000)
2.31
Unfortunately this doesn't seem to work. The resulting program is linked against a newer version of glibc than I expected, 2.31 rather than 2.29. But this may be due to gcc itself being linked against linked against glibc 2.31 and that ends up polluting the environment, so to speak.
$ ldd $(which gcc)
linux-vdso.so.1 (0x00007fff7cfc5000)
libm.so.6 => /gnu/store/fa6wj5bxkj5ll1d7292a70knmyl7a0cr-glibc-2.31/lib/libm.so.6 (0x00007ff842b93000)
libc.so.6 => /gnu/store/fa6wj5bxkj5ll1d7292a70knmyl7a0cr-glibc-2.31/lib/libc.so.6 (0x00007ff8429d6000)
/gnu/store/fa6wj5bxkj5ll1d7292a70knmyl7a0cr-glibc-2.31/lib/ld-linux-x86-64.so.2 (0x00007ff842cd6000)
Where do I go from here? I've tried using older versions of gcc packaged in Guix, but they all seem to be built against glibc 2.31. I also tried adding -L /gnu/store/hlsas48h6x7364kcfs8yy6xfksdsffr4-glibc-2.29/lib to my gcc-invocation but to no avail.
I was able to figure it out, or rather: cbaines on #guix#freenode pointed me towards the function make-gcc-toolchain which allowed me to set up the environment I wanted. By placing the following code into a file called development-environment.scm:
(use-modules (gnu packages base)
(gnu packages commencement)
(gnu packages gcc)
(gnu packages version-control))
(define-public gcc-glibc-2.29-toolchain
(make-gcc-toolchain gcc glibc-2.29))
(list gcc-glibc-2.29-toolchain git coreutils)
and then running guix environment --pure --ad-hoc --load=development-environment.scm I was able to build my program using the version of glibc that I wanted:
$ rm a.out && gcc printer.c && ldd a.out && ./a.out
linux-vdso.so.1 (0x00007fff7e17c000)
libgcc_s.so.1 => /gnu/store/71rcc4qxfgyzr0qphkh9adjsqsb999zk-gcc-glibc-2.29-7.5.0-lib/lib/libgcc_s.so.1 (0x00007f2c8adc9000)
libc.so.6 => /gnu/store/hlsas48h6x7364kcfs8yy6xfksdsffr4-glibc-2.29/lib/libc.so.6 (0x00007f2c8ac0f000)
/gnu/store/hlsas48h6x7364kcfs8yy6xfksdsffr4-glibc-2.29/lib/ld-linux-x86-64.so.2 (0x00007f2c8ade4000)
2.29
Hot tip for posterity: put the following in a file called .envrc, install the package direnv and insert it into your shell rc, and fill it with the following content:
use guix --ad-hoc --load=development-environment.scm
That way, every time you enter that folder with your shell the development environment will be loaded for you. The right version of glibc/gcc will be run even without the --pure flag.
This question already has answers here:
Build OpenSSL with RPATH?
(2 answers)
How to compile OpenSSL with relative rpath
(5 answers)
Closed 4 years ago.
I have different openssl versions on my system and I don't want to install the most current openssl version into the system location - e.q. /usr/bin/openssl.
Now, when I compile openssl then I get this running ldd:
root => ldd /FaF/openssl/bin/openssl
linux-vdso.so.1 (0x00007ffe60d92000)
--> libssl.so.1.1 => not found
--> libcrypto.so.1.1 => not found
libdl.so.2 => /lib64/libdl.so.2 (0x00007facf337b000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007facf315e000)
libc.so.6 => /lib64/libc.so.6 (0x00007facf2dbd000)
/lib64/ld-linux-x86-64.so.2 (0x00007facf357f000)
I refer to libssl.so.1.1 and libcrypto.so.1.1 which are not found and this is OK that far.
Running ldd with preceded LD_LIBRARY_PATH works:
root => LD_LIBRARY_PATH=/FaF/openssl/lib/ ldd /FaF/openssl/bin/openssl
linux-vdso.so.1 (0x00007fff221a1000)
libssl.so.1.1 => /FaF/openssl/lib/libssl.so.1.1 (0x00007f45f842a000)
libcrypto.so.1.1 => /FaF/openssl/lib/libcrypto.so.1.1 (0x00007f45f7f9a000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007f45f7d96000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f45f7b79000)
libc.so.6 => /lib64/libc.so.6 (0x00007f45f77d8000)
/lib64/ld-linux-x86-64.so.2 (0x00007f45f869b000)
/FaF/openssl/lib is the directory where the correct libraries are.
I have now these possible solutions:
Adding /FaF/openssl/lib to /etc/ld.so.conf and running ldconfig - This is not really an option because it may break the system version of openssl.
As I did in the above example I can precede each time I need opensslwith LD_LIBRARY_PATH=/FaF/openssl/lib/ - not really a good option and it isn't always possible.
I can link the path with --rpath=/FaF/openssl/lib into openssl.
My question:
For the moment I didn't figure out how to set --rpath=/FaF/openssl/lib in the configure command which generates openssl. Can somebody provide me this information?
I tried setting LD_LIBRARY_PATH and LDFLAGS but nothing works.
I prefer a solution which is hard-coded into openssl so there are not other settings required.
OK. Here is the - very simple - way how to solve it according to 3) from my question.
I ran ./config -h and got this output:
root => ./config -h
Usage: config [options]
-d Build with debugging when possible.
-t Test mode, do not run the Configure perl script.
-v Verbose mode, show the exact Configure call that is being made.
-h This help.
Any other text will be passed to the Configure perl script.
See INSTALL for instructions.
Operating system: x86_64-whatever-linux2
Configuring for linux-x86_64
The text Any other text will be passed to the Configure perl script. says it all.
I just added the --rpath at the end to the config command which looks now like this:
./config --prefix=/FaF/openssl threads shared -Wl,--rpath=/FaF/openssl/lib
I need to build libldap under linux (and windows, but that's a different story).
When I do
./configure --prefix="$OPENLDAP_BUILD_PATH" --disable-slapd
make
make install
make clean
I get with ldd that libldap is linked with system libraries libssl.so and libcrypto.so. And what I need is to link it with my custom builds of this libraries.
I also tried this:
OPENLDAP2_BUILD_PATH="$BUILD_PATH/openldap2"
mkdir "$OPENLDAP2_BUILD_PATH"
OPENSSL_DEPENDENCY_PATH="$BUILD_PATH/openssl"
LD_LIBRARY_PATH="$OPENSSL_DEPENDENCY_PATH/lib:$LD_LIBRARY_PATH"
CPPFLAGS="-l$OPENSSL_DEPENDENCY_PATH/include/openssl"
LDFLAGS="-L$OPENSSL_DEPENDENCY_PATH/lib"
./configure --prefix="$OPENLDAP2_BUILD_PATH" --disable-slapd
make
make install
make clean
With no success either.
ldd libldap.so shows this:
linux-vdso.so.1 => (0x00007ffc91923000)
liblber-2.4.so.2 => /home/me/Work-U14/proj/shared/BUILD/openldap2/lib/liblber-2.4.so.2 (0x00007ff0ef638000)
libresolv.so.2 => /lib/x86_64-linux-gnu/libresolv.so.2 (0x00007ff0ef3f8000)
libssl.so.1.0.0 => /lib/x86_64-linux-gnu/libssl.so.1.0.0 (0x00007ff0ef198000)
libcrypto.so.1.0.0 => /lib/x86_64-linux-gnu/libcrypto.so.1.0.0 (0x00007ff0eedbc000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ff0ee9f4000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007ff0ee7ef000)
/lib64/ld-linux-x86-64.so.2 (0x000056386adf5000)
Found that below could work:
export LDFLAGS="-L/your/dir/to/openssl/lib"
export CPPFLAGS="-I/your/dir/to/openssl/include"
./configure ...
could work, the include path is:
-I/your/dir/to/openssl/include NOT
-I/your/dir/to/openssl/include/openssl
which the .h head files are all in the sub openssl dir under include,
the key point is get rid of the openssl dir under include dir, which by default for other packages we have to add this sub-directory under include, e.g. for apr, you have to make it as: -I/your/dir/to/apr/include/apr-1.
It's not a good solution, but a well-enough workaround for me.
I've written build.sh as follows:
#!/bin/sh
if [ -z "$BUILD_PATH" ]
then
echo "Variable BUILD_PATH isn't specified!"
exit
fi
OPENLDAP2_BUILD_PATH="$BUILD_PATH/openldap2"
export MY_OPENSSL_ROOT="$BUILD_PATH/openssl"
./configure --prefix=$OPENLDAP2_BUILD_PATH --disable-slapd >/home/sherst/Desktop/configure_log.openldap2 2>&1
make >/home/sherst/Desktop/make_log.openldap2 2>&1
make install >/home/sherst/Desktop/make_install_log.openldap2 2>&1
I've patched configure file as such:
LINE 15485
LIBS="-Wl,-rpath=$ORIGIN/ -L. -lssl -lcrypto $LIBS"
LINE 15582
TLS_LIBS="-Wl,-rpath=$MY_OPENSSL_ROOT/lib -L$MY_OPENSSL_ROOT/lib -lssl -lcrypto -lRSAglue -lrsaref"
LINE 15584
TLS_LIBS="-Wl,-rpath=$MY_OPENSSL_ROOT/lib -L$MY_OPENSSL_ROOT/lib -lssl -lcrypto"
In such way (I'm quite sure that it's very crude and overabundant) I've achieved that ldd shows links to my openssl libs. TO hard code them is a bad idea, but when, in distro, there will be no such paths, I expect ld to find them in local dir, where we plan to put them.
openldap faq says this should be achieved ain such way:
env CPPFLAGS=-I/path/to/openssl/include \
LDFLAGS=-L/path/to/openssl/lib-dir \
configure --with-tls ...
But that didn't work for me (perhaps, I did it wrong).
I found info how to add rpath here:
https://www.openldap.org/doc/admin24/install.html
Simply pass it to configure script:
/configure --enable-wrappers \
CPPFLAGS="-I/usr/local/include" \
LDFLAGS="-L/usr/local/lib -Wl,-rpath,/usr/local/lib"
I try to cross-compile node for my QNAP armv5te machine, on my Ubuntu 14.04 Desktop x64.
A node QPKG exists in QNAP App-center, but its version is old (0.8.22).
Here are informations about the server :
Linux SERVERNAME 3.4.6 #1 Mon Dec 29 06:00:47 CST 2014 armv5tel unknown
Processor name : Feroceon 88F6281 rev 1 (v5l) # 1.2 GHz
BogoMIPS : 1196.85
Features : swp half thumb fastmult edsp
CPU implementer : 0x56
CPU architecture: 5TE
CPU variant : 0x2
CPU part : 0x131
CPU revision : 1
Hardware : Feroceon-KW
ARM Revision : 0000
Serial : 0000000000000000
Here's the command I used on my desktop :
apt-get update
apt-get upgrade
apt-get install emdebian-archive-keyring
apt-get install libc6-armel-cross libc6-dev-armel-cross
apt-get install binutils-arm-linux-gnueabi
apt-get install gcc-4.7-arm-linux-gnueabi
apt-get install g++-4.7-arm-linux-gnueabi
apt-get install u-boot-tools
apt-get install libncurses5-dev
ln -s /user/bin/arm-linux-gnueabi-gcc-4.7 /usr/bin/arm-linux-gnueabi-gcc
ln -s /user/bin/arm-linux-gnueabi-g++-4.7 /usr/bin/arm-linux-gnueabi-g++
wget http://nodejs.org/dist/node-v0.10.35/node-v0.10.35.tar.gz
tar -zxf node-v0.10.35.tar.gz
cd node-v0.10.35
export TOOL_PREFIX="arm-linux-gnueabi"
export CC="${TOOL_PREFIX}-gcc"
export CXX="${TOOL_PREFIX}-g++"
export AR="${TOOL_PREFIX}-ar"
export RANLIB="${TOOL_PREFIX}-ranlib"
export LINK="${CXX}"
export CCFLAGS="-march=armv5te -mfpu=softfp -marm"
export CXXFLAGS="-march=armv5te -mno-unaligned-access"
export OPENSSL_armcap=5
export GYPFLAGS="-Darmeabi=soft -Dv8_can_use_vfp_instructions=false -Dv8_can_use_unaligned_accesses=false -Darmv7=0"
export VFP3=off
export VFP2=off
./configure --without-snapshot --dest-cpu=arm --dest-os=linux --prefix="/root/.nvm/v0.10.35"
make -j 4
make install
tar -zcf node-v0.10.35-linux-armv5.tar.gz v0.10.35
The compilation doesn't show any failures with these parameters. So after that I send the tarball to my QNAP server:
scp /root/.nvm/node-v0.10.35-linux-armv5.tar.gz admin#SERVERNAME:/share/HDA_DATA/.qpkg/nodejs
ssh SERVERNAME -l admin
cd /share/HDA_DATA/.qpkg/nodejs
tar -zxf node-v0.10.35-linux-armv5.tar.gz
ln -s v0.10.35 node
All my env variables are already set on my server. Now I can test node binary...
# node -v
node: /usr/lib/libstdc++.so.6: version `CXXABI_ARM_1.3.3' not found (required by node)
node: /lib/libc.so.6: version `GLIBC_2.15' not found (required by node)
node: /lib/libc.so.6: version `GLIBC_2.11' not found (required by node)
node: /lib/libc.so.6: version `GLIBC_2.7' not found (required by node)
Finally I have an error because C libraries are not the same on Ubuntu and Qnap, for Ubuntu desktop I have ldd (Ubuntu EGLIBC 2.19-0ubuntu6.5) 2.19 and on QNAP ldd (GNU libc) 2.5.
libc-dev and libstdc++ are packages handled by Optware ipkg on Qnap, (old versions too).
My question is what is the better way to fix this problem ? Force updating libs on server ? (and how to do that ?) Or maybe use static libs during compilation ? ( and how to do that too ?) Or other options ?
EDIT:
After my conversation with artless-noise, I understood I had several ways to fix library dependencies...
Dependencies in question:
# ldd /opt/bin/node
/opt/node/bin/node: /usr/lib/libstdc++.so.6: version `CXXABI_ARM_1.3.3' not found (required by /opt/node/bin/node)
/opt/node/bin/node: /lib/libc.so.6: version `GLIBC_2.15' not found (required by /opt/node/bin/node)
/opt/node/bin/node: /lib/libc.so.6: version `GLIBC_2.11' not found (required by /opt/node/bin/node)
/opt/node/bin/node: /lib/libc.so.6: version `GLIBC_2.7' not found (required by /opt/node/bin/node)
libdl.so.2 => /lib/libdl.so.2 (0xb6ed2000)
librt.so.1 => /lib/librt.so.1 (0xb6ec3000)
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0xb6de2000)
libm.so.6 => /lib/libm.so.6 (0xb6d32000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0xb6d1e000)
libpthread.so.0 => /lib/libpthread.so.0 (0xb6cfe000)
libc.so.6 => /lib/libc.so.6 (0xb6bca000)
/lib/ld-linux.so.3 (0xb6ee4000)
Copy libraries from Ubuntu GCC to the target machine, and override default ones :
It could be really dangerous, and may brick the system. To more, my goal is to create a QPKG for QNAP community, so ask people to override their C libs is not a really nice method.
Copy libraries and cohabit with original ones :
A nice method, just need to set LD_LIBRARY_PATH to a dir containing newest libs for the application. But I found an error using this method, again with c++ lib.
The error:
node: symbol lookup error: /opt/node/lib/c/libstdc++.so.6: undefined symbol: _ZNSt11__timepunctIcE2idE, version GLIBCXX_3.4
Create a static application :
Finally, I found the way to do it without any errors during compilation, and during execution on the target machine. Just need to add some flags.
New flags:
export CCFLAGS="-march=armv5te -mfpu=softfp -marm -static-libgcc"
export CXXFLAGS="-march=armv5te -mno-unaligned-access -static-libstdc++"
export LDFLAGS="-static"
Checking dynamic library links:
# ldd /opt/bin/node
not a dynamic executable
# npm version
{ test: '1.0.0',
npm: '2.3.0',
ares: '1.9.0-DEV',
http_parser: '1.0',
modules: '11',
node: '0.10.35',
openssl: '1.0.1j',
uv: '0.10.30',
v8: '3.14.5.9',
zlib: '1.2.8' }
EDIT: Finally a problem is again here, most of the node functions work, but not http...
i tested a simple script (from NodeJS API) to get info about a web page:
http.get("http://www.google.com/index.html", function(res) {
console.log("Got response: " + res.statusCode);
}).on('error', function(e) {
console.log("Got error: " + e.message);
});
And I got Got error: getaddrinfo ENOTFOUND, is it possible because node is static some features can't work ?
Finally, instead of trying to change libraries, I decided to have a better cross-compiler which matches with my target perfectly.
I used Crosstools-NG for that, but I could use the official QNAP Maxwell-ARM Toolchain too (I saw it too late...)
gcc (GCC) 4.2.4
g++ (GCC) 4.2.4
GNU ld (crosstool-NG 1.20.0) 2.19.1
ldd (crosstool-NG) 1.20.0
Python 2.7.6 (with gyp)
But a problem was always here, there's a node dependecy (libuv) which uses a library named linux-atomic, and that library was introduced in GCC since version 4.4.X. So here is the workaround I made to fix it :
cd /src
wget -q https://ftp.gnu.org/gnu/gcc/gcc-4.6.3/gcc-core-4.6.3.tar.gz
tar -zxf gcc-core-4.6.3.tar.gz
sed -i -e 's/define HIDDEN.*/define HIDDEN/' /src/gcc-4.6.3/gcc/config/arm/linux-atomic.c
export CC=arm-none-linux-gnueabi-gcc
export AR=arm-none-linux-gnueabi-ar
export RANLIB=arm-none-linux-gnueabi-ranlib
cd /src/gcc-4.6.3/gcc/config/arm
libtool --tag=CC --mode=compile $CC -g -O2 -MT linux-atomic.lo -MD -MP -MF linux-atomic.Tpo -c -o linux-atomic.lo linux-atomic.c
$AR cru /src/gcc-4.6.3/gcc/config/arm/.libs/liblinux-atomic.a /src/gcc-4.6.3/gcc/config/arm/.libs/linux-atomic.o
$RANLIB /src/gcc-4.6.3/gcc/config/arm/.libs/liblinux-atomic.a
# IMPORTANT: Assign environment variables like I made in my question above.
# Go to node src dir and configure
./configure --without-snapshot --dest-cpu=arm --dest-os=linux --prefix="${PREFIX_DIR}"
# When configuration is done, edit out/node.target.mk
vi out/node.target.mk
# Find LD_INPUTS files list and add your new library as last one:
# -> /src/gcc-4.6.3/gcc/config/arm/.libs/liblinux-atomic.a
# Now you can build node !
make -j4 #-jX where X is the number of available cores
make install DESTDIR=$TEMPDIR # Use DESTDIR to avoid installation directly in $PREFIX_DIR path
Workaround reference
With that configuration, I also could compile node with GCC 4.1.3 for x86 processors. And I made QPKG for QNAP users who doesn't want to compile by themselves : https://github.com/jbltx/nodejs-QPKG/tree/master/node-v0.10.35
I've download gdb-6.5.bz2.tar. Untar this file.
I write:
LDFLAGS=-static
./configure
but as a result i get a gdb, which require a so files, for instance: ncurses.so.5 libc.so.0 etc
How i can build statically ?
This message seems to imply that the correct usage is
$ make LDFLAGS=-static
Which seems surprising. Unfortunately, it also says it fails to build, and there are no follow-ups. Still the message is from 1999 so everything might have changed, perhaps the proper way today is to do it your way.
You can use the following options for configure script to generate a static GDB executable:
./configure --prefix=<> --enable-static=yes && make && make install
Both gcc and gdb disrespect the --enable-static flag which should be passed to configure, the correct way to do this is:
In the case of gdb 8.0, you have to also add the --disable-interprocess-agent to successfully build a static version:
mkdir build-gdb && cd build-gdb && ../configure --prefix=... --enable-static --disable-interprocess-agent ...
In the case of gcc 7.1, you have to also add the --disable-libcc1 to successfully build a static version:
mkdir build-gcc && cd guild-gcc && ../configure --prefix=... --enable-static --disable-shared --disable-libcc1 ...