How to build a static tar command - static-libraries

I downloaded tar 1.28 and am attempting to compile a static binary to use on system recovery media on Fedora Linux (x86_64). It doesn't have to include common libraries, such as libc or pthreads, but I'd like to eliminate dependencies on selinux, acl, attr, pcre and lzma, etc.
The README indicates I can use
./configure CC=gcc LDFLAGS=-static
but this creates a fully static binary (including libc), but is missing support for anything normally found in the shared libraries (SELinux, ACLs, etc). Reading the config.log shows failed attempts to find a static library for acl
So, I installed libselinux-devel-static RPM, and this time got the selinux support in there, but I can't find static libraries for anything else. Search results say that libacl.a is in libacl-devel, but not mine.
A fully static binary is ok, but really just want to get the odd-balls in there so I don't have to put the shared libraries on the media.

I was looking at this as well, and i would get the following error message:
CCLD tar
../gnu/libgnu.a(quotearg.o): In function `quote':
/home/anarcat/dist/tar-1.27.1/gnu/quotearg.c:968: multiple definition of `quote'
/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../../lib/libacl.a(quote.o):(.text+0x0): first defined here
names.o: In function `gid_to_gname':
/home/anarcat/dist/tar-1.27.1/src/names.c:95: warning: Using 'getgrgid' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
names.o: In function `gname_to_gid':
/home/anarcat/dist/tar-1.27.1/src/names.c:155: warning: Using 'getgrnam' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
names.o: In function `uname_to_uid':
/home/anarcat/dist/tar-1.27.1/src/names.c:125: warning: Using 'getpwnam' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
names.o: In function `uid_to_uname':
/home/anarcat/dist/tar-1.27.1/src/names.c:65: warning: Using 'getpwuid' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
../lib/libtar.a(rtapelib.o): In function `rmt_open__':
/home/anarcat/dist/tar-1.27.1/lib/rtapelib.c:428: warning: Using 'gethostbyname' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
collect2: error: ld returned 1 exit status
Makefile:1304: recipe for target 'tar' failed
I don't quite get it, but apparently, "You cannot getpwnam and friends with the whole flexibility that glibc has without shared libraries".
So game over? unclear.

For Fedora you can enable Repository CERT Forensics Tools
and complete build dependencies with some static libs (non-exhaustive list)
zlib-static
libiconv-static
libffi-devel
gettext-devel
pcre-static
ncurses-static
nss-devel
glibc-static
libselinux-static
libsepol-static
libattr-devel
libacl-devel
if libacl.a is missing you have to download source first from:
git clone https://git.savannah.nongnu.org/git/attr.git
git clone https://git.savannah.nongnu.org/git/acl.git
and compile with (first libattr, then libacl, then tar):
./autogen.sh
./configure --prefix=/usr --libexecdir=/usr/lib --enable-static --disable-shared --disable-rpath
make CFLAGS='-static'
make install

Related

/lib/i386-linux-gnu/libc.so.6: version `GLIBC_2.34' [duplicate]

I'm very new to Yesod and I'm having trouble building Yesod statically
so I can deploy to Heroku.
I have changed the default .cabal file to reflect static compilation
if flag(production)
cpp-options: -DPRODUCTION
ghc-options: -Wall -threaded -O2 -static -optl-static
else
ghc-options: -Wall -threaded -O0
And it no longer builds. I get a whole bunch of warnings and then a
slew of undefined references like this:
Linking dist/build/personal-website/personal-website ...
/usr/lib/ghc-7.0.3/libHSrts_thr.a(Linker.thr_o): In function
`internal_dlopen':
Linker.c:(.text+0x407): warning: Using 'dlopen' in statically linked
applications requires at runtime the shared libraries from the glibc
version used for linking
/usr/lib/ghc-7.0.3/unix-2.4.2.0/libHSunix-2.4.2.0.a(HsUnix.o): In
function `__hsunix_getpwent':
HsUnix.c:(.text+0xa1): warning: Using 'getpwent' in statically linked
applications requires at runtime the shared libraries from the glibc
version used for linking
/usr/lib/ghc-7.0.3/unix-2.4.2.0/libHSunix-2.4.2.0.a(HsUnix.o): In
function `__hsunix_getpwnam_r':
HsUnix.c:(.text+0xb1): warning: Using 'getpwnam_r' in statically
linked applications requires at runtime the shared libraries from the
glibc version used for linking
/usr/lib/libpq.a(thread.o): In function `pqGetpwuid':
(.text+0x15): warning: Using 'getpwuid_r' in statically linked
applications requires at runtime the shared libraries from the glibc
version used for linking
/usr/lib/libpq.a(ip.o): In function `pg_getaddrinfo_all':
(.text+0x31): warning: Using 'getaddrinfo' in statically linked
applications requires at runtime the shared libraries from the glibc
version used for linking
/usr/lib/ghc-7.0.3/site-local/network-2.3.0.2/
libHSnetwork-2.3.0.2.a(BSD__63.o): In function `sD3z_info':
(.text+0xe4): warning: Using 'gethostbyname' in statically linked
applications requires at runtime the shared libraries from the glibc
version used for linking
/usr/lib/ghc-7.0.3/site-local/network-2.3.0.2/
libHSnetwork-2.3.0.2.a(BSD__164.o): In function `sFKc_info':
(.text+0x12d): warning: Using 'getprotobyname' in statically linked
applications requires at runtime the shared libraries from the glibc
version used for linking
/usr/lib/ghc-7.0.3/site-local/network-2.3.0.2/
libHSnetwork-2.3.0.2.a(BSD__155.o): In function `sFDs_info':
(.text+0x4c): warning: Using 'getservbyname' in statically linked
applications requires at runtime the shared libraries from the glibc
version used for linking
/usr/lib/libpq.a(fe-misc.o): In function `pqSocketCheck':
(.text+0xa2d): undefined reference to `SSL_pending'
/usr/lib/libpq.a(fe-secure.o): In function `SSLerrmessage':
(.text+0x31): undefined reference to `ERR_get_error'
/usr/lib/libpq.a(fe-secure.o): In function `SSLerrmessage':
(.text+0x41): undefined reference to `ERR_reason_error_string'
/usr/lib/libpq.a(fe-secure.o): In function `initialize_SSL':
(.text+0x2f8): undefined reference to `SSL_check_private_key'
/usr/lib/libpq.a(fe-secure.o): In function `initialize_SSL':
(.text+0x3c0): undefined reference to `SSL_CTX_load_verify_locations'
(... snip ...)
If I just compile with just -static and without -optl-static
everything builds fine but the application crashes when it tries to
start on Heroku.
2011-12-28T01:20:51+00:00 heroku[web.1]: Starting process with command
`./dist/build/personal-website/personal-website -p 41083`
2011-12-28T01:20:51+00:00 app[web.1]: ./dist/build/personal-website/
personal-website: error while loading shared libraries: libgmp.so.10:
cannot open shared object file: No such file or directory
2011-12-28T01:20:52+00:00 heroku[web.1]: State changed from starting
to crashed
I tried adding libgmp.so.10 to the LD_LIBRARY_PATH as suggested in here
and then got the following error:
2011-12-28T01:31:23+00:00 app[web.1]: ./dist/build/personal-website/
personal-website: /lib/libc.so.6: version `GLIBC_2.14' not found
(required by ./dist/build/personal-website/personal-website)
2011-12-28T01:31:23+00:00 app[web.1]: ./dist/build/personal-website/
personal-website: /lib/libc.so.6: version `GLIBC_2.14' not found
(required by /app/dist/build/personal-website/libgmp.so.10)
2011-12-28T01:31:25+00:00 heroku[web.1]: State changed from starting
to crashed
2011-12-28T01:31:25+00:00 heroku[web.1]: Process exited
It seems that the version of libc that I'm compiling against is
different. I tried also adding libc to the batch of libraries the
same way I did for libgmp but this results in a segmentation fault
when the application starts on the Heroku side.
Everything works fine on my PC. I'm running 64bit archlinux with ghc
7.0.3. The blog post on the official Yesod blog looked pretty easy
but I'm stumped at this point. Anyone have any ideas? If there's a way to get this thing working without building statically I'm open to that too.
EDIT
Per Employed Russians answer I did the following to fix this.
First created a new directory lib under the project directory and copied the missing shared libraries into it. You can get this information by running ldd path/to/executable and heroku run ldd path/to/executable and comparing the output.
I then did heroku config:add LD_LIBRARY_PATH=./lib so when the application is started the dynamic linker will look for libraries in the new lib directory.
Finally I created an ubuntu 11.10 virtual machine and built and deployed to Heroku from there, this has an old enough glibc that it works on the Heroku host.
Edit:
I've since written a tutorial on the Yesod wiki
I have no idea what Yesod is, but I know exactly what each of your other errors means.
First, you should not try to link statically. The warning you get is exactly right: if you link statically, and use one of the routines for which you are getting the warning, then you must arrange to run on a system with exactly the same version of libc.so.6 as the one you used at build time.
Contrary to popular belief, static linking produces less, not more, portable executables on Linux.
Your other (static) link errors are caused by missing libopenssl.a at link time.
But let's assume that you are going to go the "sane" route, and use dynamic linking.
For dynamic linking, Linux (and most other UNIXes) support backward compatibility: an old binary continues to work on newer systems. But they don't support forward compatibility (a binary built on a newer system will generally not run on an older one).
But that's what you are trying to do: you built on a system with glibc-2.14 (or newer), and you are running on a system with glibc-2.13 (or older).
The other thing you need to know is that glibc is composed of some 200+ binaries that must all match exactly. Two key binaries are /lib/ld-linux.so and /lib/libc.so.6 (but there are many more: libpthread.so.0, libnsl.so.1, etc. etc). If some of these binaries came from different versions of glibc, you usually get a crash. And that is exactly what you got, when you tried to place your glibc-2.14 libc.so.6 on the LD_LIBRARY_PATH -- it no longer matches the system /lib/ld-linux.
So what are the solutions? There are several possibilities (in increasing difficulty):
You could copy ld-2.14.so (the target of /lib/ld-linux symlink) to the target system, and invoke it explicitly:
/path/to/ld-2.14.so --library-path <whatever> /path/to/your/executable
This generally works, but can confuse an application that looks at argv[0], and breaks for applications that re-exec themselves.
You could build on an older system.
You could use appgcc (this option has disappeared, see this for description of what it used to be).
You could set up a chroot environment matching the target system, and build inside that chroot.
You could build yourself a Linux-to-olderLinux crosscompiler
You have several issues.
You should not build production binaries on bleeding edge distributions. The libraries on the production system will not be forward compatible.
You should not link glibc statically - it will always at runtime try to load additional libraries. For example cpu-based assembly. That is what your first warnings are about.
The last linker errors look like they are related to a missing openssl library on the command line.
But all in all - downgrade your distribution.
I had similar problems launching to Heroku (which uses glibc-2.11) where I had an application that required glibc-2.14, but I did not have access to the source and could not re-build it. I tried many things and nothing worked.
My workaround was to launch the service on Amazon Elastic Beanstalk and just provide an API interface.
I found the information provided useful as well, I think the various descriptions miss a critical issue I also ran into while forcing an updated version of Vagrant to start working again.
It's the dependency references internal to something like complicated installs, like Yesod to Heroku. Those interanl refences need to be preserved.
This is the script I wrote to make problems go away (at least, hopefully, for a little while):
#!/bin/bash
cd $HOME/
GLIBC_VERSION="2.17"
GLIBC_PREFIX="/usr/glibc/"
VAGRANT_VERSION="2.2.19"
# Install the basic build system utilities.
yum groupinstall -y "Development tools"
yum install -y curl patchelf
# Grab the tarball with the GNU libc source code.
curl -Lfo glibc-${GLIBC_VERSION}.tar.gz "https://ftp.gnu.org/gnu/glibc/glibc-${GLIBC_VERSION}.tar.gz"
echo "a3b2086d5414e602b4b3d5a8792213feb3be664ffc1efe783a829818d3fca37a glibc-${GLIBC_VERSION}.tar.gz" | sha256sum -c || exit 1
# Extract the secrets and get ready to rumble.
tar xzvf glibc-${GLIBC_VERSION}.tar.gz
# The configure script requrires an independent build directory.
mkdir -p glibc-build && cd glibc-build
# Configure glibc with a GLIBC_PREFIX so it doesn't conflict with distro libc files..
../glibc-${GLIBC_VERSION}/configure --prefix="${GLIBC_PREFIX}" --libdir="${GLIBC_PREFIX}/lib" \
--libexecdir="${GLIBC_PREFIX}/lib" --enable-multi-arch
# Compile and then install GNU libc.
make -j8 && make install
# Download and install Vagrant.
curl -Lfo vagrant_${VAGRANT_VERSION}_x86_64.rpm "https://releases.hashicorp.com/vagrant/${VAGRANT_VERSION}/vagrant_${VAGRANT_VERSION}_x86_64.rpm"
echo "990e8d2159032915f21c0f1ccdcbca1a394f7937e06e43dc1dabe605d208dc20 vagrant_${VAGRANT_VERSION}_x86_64.rpm" | sha256sum -c || exit 1
yum install -y vagrant_${VAGRANT_VERSION}_x86_64.rpm
# Patch the binaries and shared libraries inside the Vagrant directory, so they use the new version of GNU libc.
(find /opt/vagrant/ -type f -exec file {} \; )| grep "dynamically linked" | awk -F':' '{print $1}' | while read FILE ; do
patchelf --set-rpath /opt/vagrant/embedded/lib:/opt/vagrant/embedded/lib64:/usr/glibc/lib:/usr/lib64:/lib64:/lib --set-interpreter /usr/glibc/lib/ld-linux-x86-64.so.2 "${FILE}"
done
The script should be pretty easy to understand, and adapt easily to whatever MacGuffin you want to make work, provied you understand it.
The only tricky part is the rpath you pass to patchelf. Upi need to make sure you preserve the search paths, and precedence your software requires. Or you end up fixing one problem only to create another equally frustrating roadblock.
P.S. Don't forget the update the hashes for any file you down. In particular, you need to compile/install a different version of GNU libc, you will need to update that hash to match the version you want to use.

enforce libtool to link with libdl.so

I am building a shared lib on Ubuntu 18.04.1 that has to be linked explicitly with libdl.so.
All is good when using a non-libtool makefile - "-ldl" is supplied to the linker and the produced binary imports libdl.so.
But when trying to build with a libtooled automake, the produced shared library does not import libdl.so despite fact that Makefile.am has la_LDFLAGS set to "-Wl,--no-as-needed -ldl"
I suspect that this is due to the fact that libtool comes with its own implementation of dl (libltdl) and it is linked in statically instead of libdl.so
Is there any way, a command line option perhaps, that will enforce libtool to use the native implementation instead of libltdl? - I have spent a lot of time finding it in vain.
The libtool version is 2.4.6
Thanks

Linking ports libraries under FreeBSD

I have built some libraries (gtk3, qt5, ...) through the ports collection under FreeBSD 11.2. In order to test them I just built minimal examples. Each time the linker complains about not finding these libraries.
Correct me if I am wrong, but under FreeBSD, regular packages (those which are setup with pkg) are installed under /usr/include and /usr/lib, however ports lie, by default, under /usr/local/include and /usr/local/lib.
Is there a simple way to tell the compiler to search under these directories rather than having huge compilation commands with the -I and -L options?
Thank you for your answers.
Edit
Here is my CMakeLists.txt:
cmake_minimum_required(VERSION 3.12)
project(gtk-test)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/modules/")
find_package(GTK3 REQUIRED)
include_directories(${GTK3_INCLUDE_DIRS})
link_directories(${GTK3_LIBRARY_DIRS})
add_executable(gtk-test gtk-test.c)
target_link_libraries(gtk-test ${GTK3_LIBRARIES})
I have solved the dependencies issue by grabbing the following CMake script:
https://github.com/eiskaltdcpp/eiskaltdcpp/blob/master/cmake/FindGTK3.cmake
However, another problem has pop up:
[100%] Linking C executable gtk-test
/usr/lib/crt1.o: In function `_start':
crt1.c:(.text+0x91): undefined reference to `main'
collect2: error: ld returned 1 exit status
Edit
I am stupid, I even did not notice that there was no main function in the sample. It works fine except that, by default, CMake cannot locate GTK3 library and its dependencies.
Here is the content of my CMake config scripts:
Qt5
Qt53DQuick
Qt53DRender
Qt5DataVisualization
Qt5Location
Qt5OpenGLExtensions
Qt5QuickTest
Qt5SerialBus
Qt5UiPlugin
Qt5WebKit
Qt5XmlPatterns
Qt53DAnimation
Qt53DQuickAnimation
Qt5Bluetooth
Qt5Designer
Qt5Multimedia
Qt5Positioning
Qt5QuickWidgets
Qt5SerialPort
Qt5UiTools
Qt5WebKitWidgets
assimp-4.1
Qt53DCore
Qt53DQuickExtras
Qt5Charts
Qt5Gamepad
Qt5MultimediaWidgets
Qt5PrintSupport
Qt5Script
Qt5Sql
Qt5WebChannel
Qt5WebSockets
harfbuzz
Qt53DExtras
Qt53DQuickInput
Qt5Concurrent
Qt5Gui
Qt5Network
Qt5Qml
Qt5ScriptTools
Qt5Svg
Qt5WebEngine
Qt5Widgets
libxml2
Qt53DInput
Qt53DQuickRender
Qt5Core
Qt5Help
Qt5Nfc
Qt5Quick
Qt5Scxml
Qt5Test
Qt5WebEngineCore
Qt5X11Extras
Qt53DLogic
Qt53DQuickScene2D
Qt5DBus
Qt5LinguistTools
Qt5OpenGL
Qt5QuickControls2
Qt5Sensors
Qt5TextToSpeech
Qt5WebEngineWidgets
Qt5Xml

Issues in Cross compiling when linking GMP to GCC

Using the How To Build GCC 4.8.2 ARM Cross-Compiler, I have installed and setup everything and it works just fine as mentioned in the post i.e., I was able to cross compile a simple C code. But, when I try to compile a simple GMP code, I get this error.
fatal error: gmp.h: No such file or directory
Compilation terminated
How should I fix this? My goal is to compile a gmp program. If possible, refer me to good tutorials.
Thanks!
If you want GMP compiled for the target system (ARM), you must compile it by itself using the newly built cross-compiler, not as a part of building GCC. GMP (along with MPFR, MPC, ISL, CLooG, etc.) being placed in the GCC toplevel source directory simply means that it gets compiled and linked for the cross-compiler you're building.
Since the cross-compiler will run on the host system, GMP will also be compiled for the host system, else linking the library would fail, and you wouldn't get a cross-compiler. It may sound silly, but there are reasons for doing it this way, such as buggy prebuilt packages provided by the package manager on the host system or merely to avoid installing those libraries on the host system when all you want is the cross-compilation toolchain.

AIX- Does not install shared lib

I am able to build the shared object successfully using the holy native compiler "xlc" on AIX.It does build the shared object library but does not install the shared object library.
Configure command is:
./configure --prefix=/PATH/to/install --exec-prefix=/PATH/to/install --enable-shared --enable-static=no --enable-module=so --build=powerpc-ibm-aix5.3.0.0 --host=powerpc-ibm-aix5.3.0.0 LDFLAGS="-G -shared"
Any help would be appreciated?
So you are trying to compile to the shared library location.
I would suggest seeing if you can compile/link to your local directory.
If that works, try copying the new library to the correct directory. It may be that the oldshared library is open by some process and therefore can't be overwritten.
Are you getting any error messages?
I could install the shared library successfully when i had to exclusively export LDFLAGS as "-brtl -L/path/to/install".
Under AIX, there are two types of shared libraries, AIX style, and SysV compat libs.
AIX style libs are archvies that can contain static libraries as well as multiple versions of shared libraries, and have names like libFOO.a
SysV-compat libs have names like libFoo.so and are more like what you would find on Linux.
Libtool will build either type. If you want SysV-compat libs, add -Wl,-brtl to LDFLAGS.
My guess is that you see /PATH/to/install/lib/libFOO.a and are assuming that it's a static library, when in fact, it's an AIX shared library.

Resources