Scripts for quickly building/installing specified version of open source projects from source code to specified location.
-
Edit settings in
env.sh
before using this -
These scripts are not trying to be foolproof
Previously experience with target projects and some shell scripting experience is expected
-
Scripts are executed with
/bin/bash -e
-
Scripts are written in a way trying to be "reentrant"
-
Use absolute path
GNU wget
GNU tar, command line option --transform support
GNU gzip, BSD gunzip of at least El Capitan will exit with 1 when the archive was compressed with padded zeros
patch
uudecode, can be provided by debian package sharutils
md5sum
git
libtool
make
cmake
autoconf
- there are times we need to patch configure.ac and regenerate configure script with autoreconf
- json-c requires at least autoconf 2.68
texinfo
- gdb requires makeinfo to build info pages
Install on Debian
sudo apt-get install autoconf cmake libtool pkg-config
sudo apt-get install sharutils
Install on RHEL
sudo yum install -y sharutils
- gzip complains with trailing garbage ignored, http://www.gzip.org/#faq8
On RHEL/CentOS 6, the default toolchain is too old for building many packages of newest version.
- Anonymous struct/union support of c11 standard is required from gcc to build luajit bundled with wrk. GCC 4.4 does not work.
- ruby of at least version 1.9 is required to build mruby bundled with h2o
- Some packages requires newer versions of autoconf and pkg.m4 from pkg-config
- QEMU 2.5 requires g++ with flag
-fstack-protector-strong
which is not available in the 4.4 line
The solution at the moment is to use newer toolchain from Software Collections service before we can build toolchains by ourself
# Install base packages
yum install scl-utils
yum install centos-release-scl-rh
# GCC 4.9 from devtoolset, - https://www.softwarecollections.org/en/scls/rhscl/devtoolset-3/
#
# search what's available
#
# yum search devtoolset-3
yum install devtoolset-3-gcc devtoolset-3-gcc-c++ devtoolset-3-binutils
# Ruby 2.2, https://www.softwarecollections.org/en/scls/rhscl/rh-ruby22/
yum install rh-ruby22
# Autotools
# Try using Autotools in SCL at the moment, https://www.softwarecollections.org/en/scls/praiskup/autotools/
# Use them within a shell
scl enable devtoolset-3 rh-ruby22 autotools-latest zsh
Packages built will be installed to $INSTALL_PREFIX
, which is $HOME/.usr/
at the moment. Directory locations can be customized by editing env.sh
Just setting PATH
should be enough to use the built binaries as these
packages are to be compiled with -rpath
support which means that there is no
need to set LD_LIBRARY_PATH
or DYLD_LIBRARY_PATH
.
Steps to setup environment variables to use the built binaries
# Use installed binaries
export PATH=$INSTALL_PREFIX/bin:$INSTALL_PREFIX/sbin:$PATH
# Use installed manpages
MANPATH="$INSTALL_PREFIX/share/man:$(manpath)"
# Use kernel modules. Edit /etc/depmod.d/dist.conf to let depmod use
# external modules directories.
#
# Then execute "depmod -a" to update /lib/modules/$(uname -r)/modules.dep
# and check whether absolute paths to modules installed under
# $INSTALL_PATH appear there
#
search external updates extra built-in weak-updates
external * $INSTALL_PREFIX/lib/modules
Compile one by one and handle dependencies by mind
# download, prepare, configure, compile, staging
./build-nginx-vanilla.sh to staging
# single action configure
./build-nginx-vanilla.sh configure
# remove build_dir/nginx-1.9.9
./build-nginx-vanilla.sh clean
# uninstall based on dest_dir/nginx-1.9.9-install
./build-nginx-vanilla.sh uninstall
Compile with Makefile
# download, prepare, configure, compile, staging
make nginx/staging
# same but happens in tests_dir/
make nginx/staging/test
# do them all
make download
make staging
make install/test
Packages can depend on the installation of other packages to be successfully built and run. We can use system's package manager to help us for packages not provided here.
apt-get install build-essential
apt-get build-dep openvpn
apt-cache showsrc openvpn | grep Build-Depends
yum -y groupinstall "Development Tools"
yum-builddep openvpn
Most of the time sudo
will use a predefined PATH
for its child processes,
so binaries not in that directory list cannot be found.
There are a few methods to work around this
-
Use absolute path
sudo `which flowtop` -h
-
Put the following file to
/etc/sudoers.d/yousong
Defaults: yousong env_keep += "PATH", !secure_path
On Debian, Warning messages like the following can be emitted by dynamic linker
/usr/bin/curl: /home/yousong/.usr/lib/libcurl.so.4: no version information available (required by /usr/bin/curl)
/home/yousong/.usr/sbin/openvpn: /home/yousong/.usr/lib/libssl.so.1.0.0: no version information available (required by /home/yousong/.usr/sbin/openvpn)
/home/yousong/.usr/sbin/openvpn: /home/yousong/.usr/lib/libcrypto.so.1.0.0: no version information available (required by /home/yousong/.usr/sbin/openvpn)
These informations are most likely related to libraries provided by OpenSSL (libcrypto.so
and libssl.so
)
The first message about curl
was caused by the following facts
/usr/bin/curl
was provided byapt-get
and was configured with--enable-versioned-symbols
, so the result binary references (depends on) those symbols (CURL_OPENSSL_3
)libcurl.so
built by us does not enable that configure option, so the result library is missing the symbol- The
ldd /usr/bin/curl
was run withLD_LIBRARY_PATH
being set to$INSTALL_PREFIX/lib
causing the loader to first look for and find the libcurl there provided by us
The messages about openvpn
was caused by the following facts
- That
openvpn
binary was built before we have OpenSSL libraries present in$INSTALL_PREFIX/lib
- That
openvpn
binary references (depends on) symbolOPENSSL_1.0.0
as is provided by OpenSSL libraries provided byapt-get
- Then custom OpenSSL libraries were built by us
- Then
RPATH
still points the loader to first lookup the library in$INSTALL_PREFIX/lib
- Then loader found that the versioned symbol information is missing
To solve the problem
unset LD_LIBRARY_PATH
or just remove$INSTALL_PREFIX/lib
from$LD_LIBRARY_PATH
- Rebuild packages here to produce fresh binaries
Background information while debugging this
dpkg --search /lib64/ld-linux-x86-64.so.2
to find out that the loader was provided bylibc6
. It seems from the source codeelf/dl-version.c:match_symbol
that the warning message should not hurt much as long as the binaries themselves are compatible with each otherobjdump -p /usr/bin/curl
to find out provides and version references from private headers (headers that are binary format specific)--version-script
is the linker option for producing dynamic libraries with versioned symbols- OpenSSL packaged by Debian is patched with
debian/patches/version-script.patch
to provide versioned symbols - Curl packaged by Debian is configured with
--enable-versioned-symbols
I want to build packages from source for reasons like
- The one provided by the distribution is old, has bugs, lacks the features we want.
- QEMU, Vim, tmux, nginx, protobuf, openvswitch belong to this category
- Or the distribution does not provide it at all
- ag (the_silver_searcher), crosstool-ng, mausezahn, libcli, mosh, openrestry, tengine are of this type
- I want the process of
wget
,tar xzf
, patching,configure
,make
,make install
to be automatic or at least semi-automatic.- We can make it a "viola" thing when we need to do it again
- I want to do customizations and want to make the process easily repeatable/reproducible at a later time
- QEMU, nginx, vim are of this type
- We want the effect/result of the build to be local without requiring root privileges or polutting the system directories
- No,
/usr/local
is not an option
- No,
The idea is not new, yet the result is rewarding. Scripts here uses the naming
convention from OpenWrt package Makefile
.
- check if newer versions are available
redistributable packages
- separate runtime installdir, build-time libdir, incdir
- consistentency: /share vs. /usr/share