Scripts for quickly building/installing specified version of open source projects from source code to specified location.
-
Edit settings in
env.shbefore 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-strongwhich 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/yousongDefaults: 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/curlwas provided byapt-getand was configured with--enable-versioned-symbols, so the result binary references (depends on) those symbols (CURL_OPENSSL_3)libcurl.sobuilt by us does not enable that configure option, so the result library is missing the symbol- The
ldd /usr/bin/curlwas run withLD_LIBRARY_PATHbeing set to$INSTALL_PREFIX/libcausing 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
openvpnbinary was built before we have OpenSSL libraries present in$INSTALL_PREFIX/lib - That
openvpnbinary references (depends on) symbolOPENSSL_1.0.0as is provided by OpenSSL libraries provided byapt-get - Then custom OpenSSL libraries were built by us
- Then
RPATHstill 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_PATHor just remove$INSTALL_PREFIX/libfrom$LD_LIBRARY_PATH- Rebuild packages here to produce fresh binaries
Background information while debugging this
dpkg --search /lib64/ld-linux-x86-64.so.2to find out that the loader was provided bylibc6. It seems from the source codeelf/dl-version.c:match_symbolthat the warning message should not hurt much as long as the binaries themselves are compatible with each otherobjdump -p /usr/bin/curlto find out provides and version references from private headers (headers that are binary format specific)--version-scriptis the linker option for producing dynamic libraries with versioned symbols- OpenSSL packaged by Debian is patched with
debian/patches/version-script.patchto 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 installto 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/localis 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