Workshop: How to install programs from source
Table of Contents
In this workshop we will learn how to install a program from source to the home directory of the user. We will use the following programs, some of them already available at the computer room:
Name | installed version | latest version |
---|---|---|
fftw | 3.3.4 | 3.3.6 |
Eigen C++ | 3.2.7 | 3.3.3 |
git | 2.9.0 | 2.12.2 |
voro++ | Not installed | 0.4.6 |
1 Checking the version for already installed programs
If you used apt-get
or something related, you can use the package
manager to check. But, in general, you can check the versions by
looking at the appropriate places on your system. Typically,
libraries are installed under /usr/lib
or /usr/local/lib
, while
include files are installed under /usr/include
or
/usr/local/include
. Normally, if you are looking fir library
foo
, then you should look for the file libfoo.a
or libfoo.so
. One usefull utility for this is the command locate
or find
.
locate libfoo
find /usr/lib -iname "*libfoo*"
2 Preparing the local places to install the utilities
In this case we will install everything under the ~/local
subdirectory inside your home, so create it. The utilies will then
create the appropriate folders there. NOTE: Better use the $HOME
var instead of ~
.
3 Typical installation algorithm
- Download the source from the project page. This normally implies
downloading a tarball (file ending with
.tar.gz
or.tar.bz2
) . Un-compress the downloaded file. For a tarball, the command will be
tar xf filename.tar.gz
- Enter to the newly uncompressed folder (almost always usually
cd filename
). - READ the
README
and/or theINSTALL
file to check for important info regarding the program. - CONFIGURATION: You have two options.
If the program has a configure script, then just run
./configure --help
to check all the available options. Since we want to install on the
$HOME/local
directory, then we need to use./configure --prefix=$HOME/local
If you don't specify the prefix, then the program will be installed on the
/usr/bin
or/usr/local/bin
, whatever is the default. If this commands ends successfully, it will print some info to the screen and will tell you to go to the next step. Otherwise you will need to read the log and fix the errors (like installing a dependency).If the program uses
cmake
, a make configurator, then you need to do the following:mkdir build # creates a build directory to put there the temporary built files cd build cmake ../ -DCMAKE_INSTALL_PREFIX:PATH=$HOME/local # configure the building process for the source code located on the parent directory
COMPILATION: Now that you have configured your system, you need to compile by using the GNU make utility (Note: All this build utilities come from the gnu organization and are free software as in freedom). If you have several cores, you can use them in parallel, assuming the that the Makefile and your make versions supports it:
make -j 3 # for three cores, but, if you are unsure, just use one core.
INSTALLATION After successful compilation, you can install by using
make install
This will install the program (libraries, binaries, include files, manual files, etc) onto the
prefix
directory. If you want to instll system-wide (you did not set theprefix
), then you need to usesudo make install
.TESTING In this case use a program to test your installation. In this case, when you compile your program and you want to use the version that you installed, you need to tell the compiler where to find the libraries/includes, so you need something like
g++ -L $HOME/local/lib -I $HOME/local/include programname.cpp -llibname
-L $HOME/local/lib
tells the compiler to look for libraries on the$HOME/local/lib
directory.-I $HOME/local/include
tells the compiler to look for include files on the$HOME/local/include
directory.-llibname
tells the compiler to link with the given library. Sometimes is not needed. Sometimes is crucial.
4 Workshop
For each of the proposed utilities written at the beginning, follow the next procedure:
- Check the installed version number and compare with the latest one.
- Install the latest version on your home directory by following the procedure stated above.
- Run each of the following example program but make sure you a re using you installed version. Show to the instructor the compilation line.
5 Test Programs
5.1 fftw
// From : https://github.com/undees/fftw-example /* Start reading here */ #include <fftw3.h> #define NUM_POINTS 128 /* Never mind this bit */ #include <stdio.h> #include <math.h> #define REAL 0 #define IMAG 1 void acquire_from_somewhere(fftw_complex* signal) { /* Generate two sine waves of different frequencies and * amplitudes. */ int i; for (i = 0; i < NUM_POINTS; ++i) { double theta = (double)i / (double)NUM_POINTS * M_PI; signal[i][REAL] = 1.0 * cos(10.0 * theta) + 0.5 * cos(25.0 * theta); signal[i][IMAG] = 1.0 * sin(10.0 * theta) + 0.5 * sin(25.0 * theta); } } void do_something_with(fftw_complex* result) { int i; for (i = 0; i < NUM_POINTS; ++i) { double mag = sqrt(result[i][REAL] * result[i][REAL] + result[i][IMAG] * result[i][IMAG]); printf("%g\n", mag); } } /* Resume reading here */ int main() { fftw_complex signal[NUM_POINTS]; fftw_complex result[NUM_POINTS]; fftw_plan plan = fftw_plan_dft_1d(NUM_POINTS, signal, result, FFTW_FORWARD, FFTW_ESTIMATE); acquire_from_somewhere(signal); fftw_execute(plan); do_something_with(result); fftw_destroy_plan(plan); return 0; }
5.2 Eigen C++
#include <iostream> #include <Eigen/Dense> #include <Eigen/Core> using Eigen::MatrixXd; int main() { std::cout << EIGEN_MAYOR_VERSION << std::endl; std::cout << EIGEN_MINOR_VERSION << std::endl; MatrixXd m(2,2); m(0,0) = 3; m(1,0) = 2.5; m(0,1) = -1; m(1,1) = m(1,0) + m(0,1); std::cout << m << std::endl; }
#include <iostream> #include <Eigen/Dense> using namespace Eigen; int main() { Matrix2d a; a << 1, 2, 3, 4; MatrixXd b(2,2); b << 2, 3, 1, 4; std::cout << "a + b =\n" << a + b << std::endl; std::cout << "a - b =\n" << a - b << std::endl; std::cout << "Doing a += b;" << std::endl; a += b; std::cout << "Now a =\n" << a << std::endl; Vector3d v(1,2,3); Vector3d w(1,0,0); std::cout << "-v + w - v =\n" << -v + w - v << std::endl; }
#include <iostream> #include <Eigen/Dense> using namespace std; using namespace Eigen; int main() { Matrix3f A; Vector3f b; A << 1,2,3, 4,5,6, 7,8,10; b << 3, 3, 4; cout << "Here is the matrix A:\n" << A << endl; cout << "Here is the vector b:\n" << b << endl; Vector3f x = A.colPivHouseholderQr().solve(b); cout << "The solution is:\n" << x << endl; }
#include <iostream> #include <Eigen/Dense> using namespace std; using namespace Eigen; int main() { Matrix2f A; A << 1, 2, 2, 3; cout << "Here is the matrix A:\n" << A << endl; SelfAdjointEigenSolver<Matrix2f> eigensolver(A); if (eigensolver.info() != Success) abort(); cout << "The eigenvalues of A are:\n" << eigensolver.eigenvalues() << endl; cout << "Here's a matrix whose columns are eigenvectors of A \n" << "corresponding to these eigenvalues:\n" << eigensolver.eigenvectors() << endl; }
5.3 Git
Based on https://github.com/blog/2242-git-2-10-has-been-released .
$HOME/local/bin/git --version
Enter some repository you already have, make some changes, and run the following (this only works on the latest git)
$HOME/local/bin/git config color.diff.old "red strike" $HOME/local/bin/git config color.diff.new "green italic" $HOME/local/bin/git diff
Maybe you can create an alias, alias git=$HOME/local/bin/git
, or you
can modify the PATH
permanently by adding the following to your
$HOME/.bash_profile
file :
export PATH=$HOME/local/bin:$PATH
5.4 Voro++
Use http://math.lbl.gov/voro++/examples/random_points/
// Voronoi calculation example code // // Author : Chris H. Rycroft (LBL / UC Berkeley) // Email : chr@alum.mit.edu // Date : August 30th 2011 #include "voro++.hh" using namespace voro; // Set up constants for the container geometry const double x_min=-1,x_max=1; const double y_min=-1,y_max=1; const double z_min=-1,z_max=1; const double cvol=(x_max-x_min)*(y_max-y_min)*(x_max-x_min); // Set up the number of blocks that the container is divided into const int n_x=6,n_y=6,n_z=6; // Set the number of particles that are going to be randomly introduced const int particles=20; // This function returns a random double between 0 and 1 double rnd() {return double(rand())/RAND_MAX;} int main() { int i; double x,y,z; // Create a container with the geometry given above, and make it // non-periodic in each of the three coordinates. Allocate space for // eight particles within each computational block container con(x_min,x_max,y_min,y_max,z_min,z_max,n_x,n_y,n_z, false,false,false,8); // Randomly add particles into the container for(i=0;i<particles;i++) { x=x_min+rnd()*(x_max-x_min); y=y_min+rnd()*(y_max-y_min); z=z_min+rnd()*(z_max-z_min); con.put(i,x,y,z); } // Sum up the volumes, and check that this matches the container volume double vvol=con.sum_cell_volumes(); printf("Container volume : %g\n" "Voronoi volume : %g\n" "Difference : %g\n",cvol,vvol,vvol-cvol); // Output the particle positions in gnuplot format con.draw_particles("random_points_p.gnu"); // Output the Voronoi cells in gnuplot format con.draw_cells_gnuplot("random_points_v.gnu"); }
On gnuplot do the following: