Pages

Unixbhaskar's Blog

Tuesday, March 30, 2010

Building rpm package from source

In this article I am gonna show you how to build/create rpm package from source file(.tar.gz,.bz2).Yes,you can find lot of article on the internet telling you the same story,but this is my personal experience with them.So you are welcome to improve it..provided it really makes sense.

I do not issue any guarantee that this will work for you.

We as an administrator basically managed rpm based distros in corporates and as a result of that it is often required that just for the convenience and ease of porting to other similar system to make it package manager aware of that particular distro(Same thing can be done with other distros with different package manager).

Step 1:
So first step to get the tarball from Sourceforge . I am going to get a software called "iperf",which is basically measuring maximum bandwidth performance for TCP and UDP.So here is the link to get it iperf, as I have get from the browser and my default directory to store the downloads is "Downloads" folder under my home directory.Like this;

bhaskar@bhaskar-laptop_08:41:25_Tue Mar 30:~/Downloads> ls
iperf-2.0.4.tar.gz


Step 2:

We need to create five directory according to the rpmbuild specification.So here we go:


bhaskar@bhaskar-laptop_08:44:15_Tue Mar 30:~> mkdir iperfRPM

bhaskar@bhaskar-laptop_08:44:28_Tue Mar 30:~> cd iperfRPM/

bhaskar@bhaskar-laptop_08:45:14_Tue Mar 30:~/iperfRPM> mkdir BUILD SOURCES SPECS SRPMS RPMS

bhaskar@bhaskar-laptop_08:45:47_Tue Mar 30:~/iperfRPM> ls
BUILD RPMS SOURCES SPECS SRPMS

Step 3:

Now we need to copy the source form "Download" directory to the /iperfRPM/SOURCES/ directory:

bhaskar@bhaskar-laptop_08:51:57_Tue Mar 30:~/Downloads> cp -v iperf-2.0.4.tar.gz ~/iperfRPM/SOURCES/
`iperf-2.0.4.tar.gz' -> `/home/bhaskar/iperfRPM/SOURCES/iperf-2.0.4.tar.gz'

Step 4:

Now the most important steps of all : to create the .spec file for that perticular software to be make rpm.Because rpm format understand certain formats and package creator have to follow that to make the rpm package manager to understand it.

so here we go:

bhaskar@bhaskar-laptop_08:58:56_Tue Mar 30:~/iperfRPM> cd SPECS/

bhaskar@bhaskar-laptop_08:58:59_Tue Mar 30:~/iperfRPM/SPECS> ls

bhaskar@bhaskar-laptop_08:58:59_Tue Mar 30:~/iperfRPM/SPECS> vim iperf.spec

And the content of the file would look like this :

# This is a sample spec file for iperf

%define _topdir /home/bhaskar/iperfRPM
%define name iperf
%define release 1
%define version 2.0.4
%define buildroot %{_topdir}/%{name}-%{version}-root

BuildRoot: %{buildroot}
Summary: iperf
License:
Name: %{name}
Version: %{version}
Release: %{release}
Source: %{name}-%{version}.tar.gz
Prefix: /usr
Group: Development/Tools

%description
Iperf was developed by NLANR/DAST as a modern alternative for measuring maximum TCP and UDP bandwidth performance. Iperf allows the tuning of various parameters and UDP characteristics. Iperf reports bandwidth, delay jitter, datagram loss.

%prep
%setup -q

%build
./configure
make

%install
make install prefix=$RPM_BUILD_ROOT/usr

%files
%defattr(-,root,root)
/usr/local/bin/iperf

%doc %attr(0444,root,root) /usr/local/share/man/man1/iperf.1


This file has descibes the purpose of the variables declared there. Most notably under %files section whatever file you include which will be integrated with the rpm .Essentially it will set the permission of the particular file too!

Now one more important note here that %buildroot variable is just an proxy place to hold the content of the software which is going to installed somewhere else.So it's very very important to specify that location properly(because I made a mess of it couple of times :) ).


Step 5:

So the final step is to build the rpm . I will create the binary as well as source rpm too.

NOTE: I have built this on Fedora 12 ..so it doesn't ship with rpmbuildtool,gcc,g++ . So I had to get them manually all(via yum install).Before I proceed to the next step.

bhaskar@bhaskar-laptop_09:20:37_Tue Mar 30:~/iperfRPM> sudo rpmbuild -v -ba --clean ~/iperfRPM/SPECS/iperf.spec

And here is output of that command

bhaskar@bhaskar-laptop_09:40:36_Tue Mar 30:~> sudo rpmbuild -v -ba --clean ~/iperfRPM/SPECS/iperf.spec
Executing(%prep): /bin/sh -e /var/tmp/rpm-tmp.Enxq4g
+ umask 022
+ cd /home/bhaskar/iperfRPM/BUILD
+ cd /home/bhaskar/iperfRPM/BUILD
+ rm -rf iperf-2.0.4
+ /usr/bin/gzip -dc /home/bhaskar/iperfRPM/SOURCES/iperf-2.0.4.tar.gz
+ /bin/tar -xf -
+ STATUS=0
+ '[' 0 -ne 0 ']'
+ cd iperf-2.0.4
+ /bin/chmod -Rf a+rX,u+w,g-w,o-w .
+ exit 0
Executing(%build): /bin/sh -e /var/tmp/rpm-tmp.5K92Wh
+ umask 022
+ cd /home/bhaskar/iperfRPM/BUILD
+ cd iperf-2.0.4
+ ./configure
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking for g++... g++
checking for C++ compiler default output file name... a.out
checking whether the C++ compiler works... yes
checking whether we are cross compiling... no
checking for suffix of executables...
checking for suffix of object files... o
checking whether we are using the GNU C++ compiler... yes
checking whether g++ accepts -g... yes
checking for style of include used by make... GNU
checking dependency style of g++... gcc3
checking for gcc... gcc
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking dependency style of gcc... gcc3
checking for strerror in -lcposix... no
checking for a BSD-compatible install... /usr/bin/install -c
checking whether make sets $(MAKE)... (cached) yes
checking for ranlib... ranlib
checking build system type... i686-pc-linux-gnu
checking host system type... i686-pc-linux-gnu
checking for the pthreads library -lpthreads... no
checking whether pthreads work without any flags... no
checking whether pthreads work with -Kthread... no
checking whether pthreads work with -kthread... no
checking for the pthreads library -llthread... no
checking whether pthreads work with -pthread... yes
checking for joinable pthread attribute... PTHREAD_CREATE_JOINABLE
checking if more special flags are required for pthreads... no
checking for cc_r... gcc
checking for gethostbyname... yes
checking for socket... yes
checking how to run the C preprocessor... gcc -E
checking for grep that handles long lines and -e... /bin/grep
checking for egrep... /bin/grep -E
checking for ANSI C header files... yes
checking for sys/types.h... yes
checking for sys/stat.h... yes
checking for stdlib.h... yes
checking for string.h... yes
checking for memory.h... yes
checking for strings.h... yes
checking for inttypes.h... yes
checking for stdint.h... yes
checking for unistd.h... yes
checking arpa/inet.h usability... yes
checking arpa/inet.h presence... yes
checking for arpa/inet.h... yes
checking libintl.h usability... yes
checking libintl.h presence... yes
checking for libintl.h... yes
checking netdb.h usability... yes
checking netdb.h presence... yes
checking for netdb.h... yes
checking netinet/in.h usability... yes
checking netinet/in.h presence... yes
checking for netinet/in.h... yes
checking for stdlib.h... (cached) yes
checking for string.h... (cached) yes
checking for strings.h... (cached) yes
checking sys/socket.h usability... yes
checking sys/socket.h presence... yes
checking for sys/socket.h... yes
checking sys/time.h usability... yes
checking sys/time.h presence... yes
checking for sys/time.h... yes
checking syslog.h usability... yes
checking syslog.h presence... yes
checking for syslog.h... yes
checking for unistd.h... (cached) yes
checking for an ANSI C-conforming const... yes
checking for size_t... yes
checking for ssize_t... yes
checking whether time.h and sys/time.h may both be included... yes
checking whether struct tm is in sys/time.h or time.h... time.h
checking for stdint types... stdint.h (shortcircuit)
make use of stdint.h in include/iperf-int.h (assuming C99 compatible system)
checking 3rd argument of accept... socklen_t
checking for pid_t... yes
checking vfork.h usability... no
checking vfork.h presence... no
checking for vfork.h... no
checking for fork... yes
checking for vfork... yes
checking for working fork... yes
checking for working vfork... (cached) yes
checking for stdlib.h... (cached) yes
checking for GNU libc compatible malloc... yes
checking for working memcmp... yes
checking sys/select.h usability... yes
checking sys/select.h presence... yes
checking for sys/select.h... yes
checking for sys/socket.h... (cached) yes
checking types of arguments for select... int,fd_set *,struct timeval *
checking return type of signal handlers... void
checking for strftime... yes
checking for vprintf... yes
checking for _doprnt... no
checking for atexit... yes
checking for gettimeofday... yes
checking for memset... yes
checking for pthread_cancel... no
checking for select... yes
checking for strchr... yes
checking for strerror... yes
checking for strtol... yes
checking for usleep... yes
checking for snprintf... yes
checking for inet_pton... yes
checking for inet_ntop... yes
checking for gettimeofday... (cached) yes
checking *printf() support for %lld... yes
checking for bool... no
checking size of bool... 0
checking if true is defined... yes
checking whether byte ordering is bigendian... no
checking for struct ip_mreq... yes
checking whether IP_ADD_MEMBERSHIP is declared... yes
checking for multicast support... yes
checking for struct sockaddr_storage... yes
checking for struct sockaddr_in6... yes
checking whether AF_INET6 is declared... yes
checking for IPv6 headers and structures... yes
checking for struct ipv6_mreq... yes
checking whether IPV6_ADD_MEMBERSHIP is declared... yes
checking whether IPV6_MULTICAST_HOPS is declared... yes
checking for IPv6 multicast support... yes
checking whether make is GNU make... yes
configure: creating ./config.status
config.status: creating Makefile
config.status: creating compat/Makefile
config.status: creating doc/Makefile
config.status: creating include/Makefile
config.status: creating src/Makefile
config.status: creating man/Makefile
config.status: creating config.h
config.status: executing depfiles commands
config.status: executing include/iperf-int.h commands
config.status: creating include/iperf-int.h : _IPERF_INCLUDE_IPERF_INT_H
+ make
make all-recursive
make[1]: Entering directory `/home/bhaskar/iperfRPM/BUILD/iperf-2.0.4'
Making all in compat
make[2]: Entering directory `/home/bhaskar/iperfRPM/BUILD/iperf-2.0.4/compat'
if gcc -DHAVE_CONFIG_H -I. -I. -I.. -I../include -I../include -Wall -O2 -MT Thread.o -MD -MP -MF ".deps/Thread.Tpo" -c -o Thread.o Thread.c; \
then mv -f ".deps/Thread.Tpo" ".deps/Thread.Po"; else rm -f ".deps/Thread.Tpo"; exit 1; fi
if gcc -DHAVE_CONFIG_H -I. -I. -I.. -I../include -I../include -Wall -O2 -MT error.o -MD -MP -MF ".deps/error.Tpo" -c -o error.o error.c; \
then mv -f ".deps/error.Tpo" ".deps/error.Po"; else rm -f ".deps/error.Tpo"; exit 1; fi
if g++ -DHAVE_CONFIG_H -I. -I. -I.. -I../include -I../include -Wall -O2 -MT delay.o -MD -MP -MF ".deps/delay.Tpo" -c -o delay.o delay.cpp; \
then mv -f ".deps/delay.Tpo" ".deps/delay.Po"; else rm -f ".deps/delay.Tpo"; exit 1; fi
if gcc -DHAVE_CONFIG_H -I. -I. -I.. -I../include -I../include -Wall -O2 -MT gettimeofday.o -MD -MP -MF ".deps/gettimeofday.Tpo" -c -o gettimeofday.o gettimeofday.c; \
then mv -f ".deps/gettimeofday.Tpo" ".deps/gettimeofday.Po"; else rm -f ".deps/gettimeofday.Tpo"; exit 1; fi
if gcc -DHAVE_CONFIG_H -I. -I. -I.. -I../include -I../include -Wall -O2 -MT inet_ntop.o -MD -MP -MF ".deps/inet_ntop.Tpo" -c -o inet_ntop.o inet_ntop.c; \
then mv -f ".deps/inet_ntop.Tpo" ".deps/inet_ntop.Po"; else rm -f ".deps/inet_ntop.Tpo"; exit 1; fi
if gcc -DHAVE_CONFIG_H -I. -I. -I.. -I../include -I../include -Wall -O2 -MT inet_pton.o -MD -MP -MF ".deps/inet_pton.Tpo" -c -o inet_pton.o inet_pton.c; \
then mv -f ".deps/inet_pton.Tpo" ".deps/inet_pton.Po"; else rm -f ".deps/inet_pton.Tpo"; exit 1; fi
if gcc -DHAVE_CONFIG_H -I. -I. -I.. -I../include -I../include -Wall -O2 -MT signal.o -MD -MP -MF ".deps/signal.Tpo" -c -o signal.o signal.c; \
then mv -f ".deps/signal.Tpo" ".deps/signal.Po"; else rm -f ".deps/signal.Tpo"; exit 1; fi
if gcc -DHAVE_CONFIG_H -I. -I. -I.. -I../include -I../include -Wall -O2 -MT snprintf.o -MD -MP -MF ".deps/snprintf.Tpo" -c -o snprintf.o snprintf.c; \
then mv -f ".deps/snprintf.Tpo" ".deps/snprintf.Po"; else rm -f ".deps/snprintf.Tpo"; exit 1; fi
if gcc -DHAVE_CONFIG_H -I. -I. -I.. -I../include -I../include -Wall -O2 -MT string.o -MD -MP -MF ".deps/string.Tpo" -c -o string.o string.c; \
then mv -f ".deps/string.Tpo" ".deps/string.Po"; else rm -f ".deps/string.Tpo"; exit 1; fi
rm -f libcompat.a
ar cru libcompat.a Thread.o error.o delay.o gettimeofday.o inet_ntop.o inet_pton.o signal.o snprintf.o string.o
ranlib libcompat.a
make[2]: Leaving directory `/home/bhaskar/iperfRPM/BUILD/iperf-2.0.4/compat'
Making all in doc
make[2]: Entering directory `/home/bhaskar/iperfRPM/BUILD/iperf-2.0.4/doc'
make[2]: Nothing to be done for `all'.
make[2]: Leaving directory `/home/bhaskar/iperfRPM/BUILD/iperf-2.0.4/doc'
Making all in include
make[2]: Entering directory `/home/bhaskar/iperfRPM/BUILD/iperf-2.0.4/include'
make[2]: Nothing to be done for `all'.
make[2]: Leaving directory `/home/bhaskar/iperfRPM/BUILD/iperf-2.0.4/include'
Making all in src
make[2]: Entering directory `/home/bhaskar/iperfRPM/BUILD/iperf-2.0.4/src'
if g++ -DHAVE_CONFIG_H -I. -I. -I.. -I../include -I../include -Wall -O2 -MT Client.o -MD -MP -MF ".deps/Client.Tpo" -c -o Client.o Client.cpp; \
then mv -f ".deps/Client.Tpo" ".deps/Client.Po"; else rm -f ".deps/Client.Tpo"; exit 1; fi
if gcc -DHAVE_CONFIG_H -I. -I. -I.. -I../include -I../include -Wall -O2 -MT Extractor.o -MD -MP -MF ".deps/Extractor.Tpo" -c -o Extractor.o Extractor.c; \
then mv -f ".deps/Extractor.Tpo" ".deps/Extractor.Po"; else rm -f ".deps/Extractor.Tpo"; exit 1; fi
if g++ -DHAVE_CONFIG_H -I. -I. -I.. -I../include -I../include -Wall -O2 -MT Launch.o -MD -MP -MF ".deps/Launch.Tpo" -c -o Launch.o Launch.cpp; \
then mv -f ".deps/Launch.Tpo" ".deps/Launch.Po"; else rm -f ".deps/Launch.Tpo"; exit 1; fi
if g++ -DHAVE_CONFIG_H -I. -I. -I.. -I../include -I../include -Wall -O2 -MT List.o -MD -MP -MF ".deps/List.Tpo" -c -o List.o List.cpp; \
then mv -f ".deps/List.Tpo" ".deps/List.Po"; else rm -f ".deps/List.Tpo"; exit 1; fi
if g++ -DHAVE_CONFIG_H -I. -I. -I.. -I../include -I../include -Wall -O2 -MT Listener.o -MD -MP -MF ".deps/Listener.Tpo" -c -o Listener.o Listener.cpp; \
then mv -f ".deps/Listener.Tpo" ".deps/Listener.Po"; else rm -f ".deps/Listener.Tpo"; exit 1; fi
if gcc -DHAVE_CONFIG_H -I. -I. -I.. -I../include -I../include -Wall -O2 -MT Locale.o -MD -MP -MF ".deps/Locale.Tpo" -c -o Locale.o Locale.c; \
then mv -f ".deps/Locale.Tpo" ".deps/Locale.Po"; else rm -f ".deps/Locale.Tpo"; exit 1; fi
if g++ -DHAVE_CONFIG_H -I. -I. -I.. -I../include -I../include -Wall -O2 -MT PerfSocket.o -MD -MP -MF ".deps/PerfSocket.Tpo" -c -o PerfSocket.o PerfSocket.cpp; \
then mv -f ".deps/PerfSocket.Tpo" ".deps/PerfSocket.Po"; else rm -f ".deps/PerfSocket.Tpo"; exit 1; fi
if gcc -DHAVE_CONFIG_H -I. -I. -I.. -I../include -I../include -Wall -O2 -MT ReportCSV.o -MD -MP -MF ".deps/ReportCSV.Tpo" -c -o ReportCSV.o ReportCSV.c; \
then mv -f ".deps/ReportCSV.Tpo" ".deps/ReportCSV.Po"; else rm -f ".deps/ReportCSV.Tpo"; exit 1; fi
if gcc -DHAVE_CONFIG_H -I. -I. -I.. -I../include -I../include -Wall -O2 -MT ReportDefault.o -MD -MP -MF ".deps/ReportDefault.Tpo" -c -o ReportDefault.o ReportDefault.c; \
then mv -f ".deps/ReportDefault.Tpo" ".deps/ReportDefault.Po"; else rm -f ".deps/ReportDefault.Tpo"; exit 1; fi
if gcc -DHAVE_CONFIG_H -I. -I. -I.. -I../include -I../include -Wall -O2 -MT Reporter.o -MD -MP -MF ".deps/Reporter.Tpo" -c -o Reporter.o Reporter.c; \
then mv -f ".deps/Reporter.Tpo" ".deps/Reporter.Po"; else rm -f ".deps/Reporter.Tpo"; exit 1; fi
if g++ -DHAVE_CONFIG_H -I. -I. -I.. -I../include -I../include -Wall -O2 -MT Server.o -MD -MP -MF ".deps/Server.Tpo" -c -o Server.o Server.cpp; \
then mv -f ".deps/Server.Tpo" ".deps/Server.Po"; else rm -f ".deps/Server.Tpo"; exit 1; fi
if g++ -DHAVE_CONFIG_H -I. -I. -I.. -I../include -I../include -Wall -O2 -MT Settings.o -MD -MP -MF ".deps/Settings.Tpo" -c -o Settings.o Settings.cpp; \
then mv -f ".deps/Settings.Tpo" ".deps/Settings.Po"; else rm -f ".deps/Settings.Tpo"; exit 1; fi
if gcc -DHAVE_CONFIG_H -I. -I. -I.. -I../include -I../include -Wall -O2 -MT SocketAddr.o -MD -MP -MF ".deps/SocketAddr.Tpo" -c -o SocketAddr.o SocketAddr.c; \
then mv -f ".deps/SocketAddr.Tpo" ".deps/SocketAddr.Po"; else rm -f ".deps/SocketAddr.Tpo"; exit 1; fi
if gcc -DHAVE_CONFIG_H -I. -I. -I.. -I../include -I../include -Wall -O2 -MT gnu_getopt.o -MD -MP -MF ".deps/gnu_getopt.Tpo" -c -o gnu_getopt.o gnu_getopt.c; \
then mv -f ".deps/gnu_getopt.Tpo" ".deps/gnu_getopt.Po"; else rm -f ".deps/gnu_getopt.Tpo"; exit 1; fi
if gcc -DHAVE_CONFIG_H -I. -I. -I.. -I../include -I../include -Wall -O2 -MT gnu_getopt_long.o -MD -MP -MF ".deps/gnu_getopt_long.Tpo" -c -o gnu_getopt_long.o gnu_getopt_long.c; \
then mv -f ".deps/gnu_getopt_long.Tpo" ".deps/gnu_getopt_long.Po"; else rm -f ".deps/gnu_getopt_long.Tpo"; exit 1; fi
if g++ -DHAVE_CONFIG_H -I. -I. -I.. -I../include -I../include -Wall -O2 -MT main.o -MD -MP -MF ".deps/main.Tpo" -c -o main.o main.cpp; \
then mv -f ".deps/main.Tpo" ".deps/main.Po"; else rm -f ".deps/main.Tpo"; exit 1; fi
if gcc -DHAVE_CONFIG_H -I. -I. -I.. -I../include -I../include -Wall -O2 -MT service.o -MD -MP -MF ".deps/service.Tpo" -c -o service.o service.c; \
then mv -f ".deps/service.Tpo" ".deps/service.Po"; else rm -f ".deps/service.Tpo"; exit 1; fi
if gcc -DHAVE_CONFIG_H -I. -I. -I.. -I../include -I../include -Wall -O2 -MT sockets.o -MD -MP -MF ".deps/sockets.Tpo" -c -o sockets.o sockets.c; \
then mv -f ".deps/sockets.Tpo" ".deps/sockets.Po"; else rm -f ".deps/sockets.Tpo"; exit 1; fi
if gcc -DHAVE_CONFIG_H -I. -I. -I.. -I../include -I../include -Wall -O2 -MT stdio.o -MD -MP -MF ".deps/stdio.Tpo" -c -o stdio.o stdio.c; \
then mv -f ".deps/stdio.Tpo" ".deps/stdio.Po"; else rm -f ".deps/stdio.Tpo"; exit 1; fi
if gcc -DHAVE_CONFIG_H -I. -I. -I.. -I../include -I../include -Wall -O2 -MT tcp_window_size.o -MD -MP -MF ".deps/tcp_window_size.Tpo" -c -o tcp_window_size.o tcp_window_size.c; \
then mv -f ".deps/tcp_window_size.Tpo" ".deps/tcp_window_size.Po"; else rm -f ".deps/tcp_window_size.Tpo"; exit 1; fi
g++ -Wall -O2 -o iperf -O2 -pthread -DHAVE_CONFIG_H Client.o Extractor.o Launch.o List.o Listener.o Locale.o PerfSocket.o ReportCSV.o ReportDefault.o Reporter.o Server.o Settings.o SocketAddr.o gnu_getopt.o gnu_getopt_long.o main.o service.o sockets.o stdio.o tcp_window_size.o ../compat/libcompat.a
make[2]: Leaving directory `/home/bhaskar/iperfRPM/BUILD/iperf-2.0.4/src'
Making all in man
make[2]: Entering directory `/home/bhaskar/iperfRPM/BUILD/iperf-2.0.4/man'
make[2]: Nothing to be done for `all'.
make[2]: Leaving directory `/home/bhaskar/iperfRPM/BUILD/iperf-2.0.4/man'
make[2]: Entering directory `/home/bhaskar/iperfRPM/BUILD/iperf-2.0.4'
make[2]: Leaving directory `/home/bhaskar/iperfRPM/BUILD/iperf-2.0.4'
make[1]: Leaving directory `/home/bhaskar/iperfRPM/BUILD/iperf-2.0.4'
+ exit 0
Executing(%install): /bin/sh -e /var/tmp/rpm-tmp.qhXikH
+ umask 022
+ cd /home/bhaskar/iperfRPM/BUILD
+ cd iperf-2.0.4
+ make install prefix=/home/bhaskar/rpmbuild/BUILDROOT/iperf-2.0.4-1.i386/usr
Making install in compat
make[1]: Entering directory `/home/bhaskar/iperfRPM/BUILD/iperf-2.0.4/compat'
make[2]: Entering directory `/home/bhaskar/iperfRPM/BUILD/iperf-2.0.4/compat'
make[2]: Nothing to be done for `install-exec-am'.
make[2]: Nothing to be done for `install-data-am'.
make[2]: Leaving directory `/home/bhaskar/iperfRPM/BUILD/iperf-2.0.4/compat'
make[1]: Leaving directory `/home/bhaskar/iperfRPM/BUILD/iperf-2.0.4/compat'
Making install in doc
make[1]: Entering directory `/home/bhaskar/iperfRPM/BUILD/iperf-2.0.4/doc'
make[2]: Entering directory `/home/bhaskar/iperfRPM/BUILD/iperf-2.0.4/doc'
make[2]: Nothing to be done for `install-exec-am'.
make[2]: Nothing to be done for `install-data-am'.
make[2]: Leaving directory `/home/bhaskar/iperfRPM/BUILD/iperf-2.0.4/doc'
make[1]: Leaving directory `/home/bhaskar/iperfRPM/BUILD/iperf-2.0.4/doc'
Making install in include
make[1]: Entering directory `/home/bhaskar/iperfRPM/BUILD/iperf-2.0.4/include'
make[2]: Entering directory `/home/bhaskar/iperfRPM/BUILD/iperf-2.0.4/include'
make[2]: Nothing to be done for `install-exec-am'.
make[2]: Nothing to be done for `install-data-am'.
make[2]: Leaving directory `/home/bhaskar/iperfRPM/BUILD/iperf-2.0.4/include'
make[1]: Leaving directory `/home/bhaskar/iperfRPM/BUILD/iperf-2.0.4/include'
Making install in src
make[1]: Entering directory `/home/bhaskar/iperfRPM/BUILD/iperf-2.0.4/src'
make[2]: Entering directory `/home/bhaskar/iperfRPM/BUILD/iperf-2.0.4/src'
test -z "/home/bhaskar/rpmbuild/BUILDROOT/iperf-2.0.4-1.i386/usr/bin" || mkdir -p -- "/home/bhaskar/rpmbuild/BUILDROOT/iperf-2.0.4-1.i386/usr/bin"
/usr/bin/install -c 'iperf' '/home/bhaskar/rpmbuild/BUILDROOT/iperf-2.0.4-1.i386/usr/bin/iperf'
make[2]: Nothing to be done for `install-data-am'.
make[2]: Leaving directory `/home/bhaskar/iperfRPM/BUILD/iperf-2.0.4/src'
make[1]: Leaving directory `/home/bhaskar/iperfRPM/BUILD/iperf-2.0.4/src'
Making install in man
make[1]: Entering directory `/home/bhaskar/iperfRPM/BUILD/iperf-2.0.4/man'
make[2]: Entering directory `/home/bhaskar/iperfRPM/BUILD/iperf-2.0.4/man'
make[2]: Nothing to be done for `install-exec-am'.
test -z "/home/bhaskar/rpmbuild/BUILDROOT/iperf-2.0.4-1.i386/usr/share/man/man1" || mkdir -p -- "/home/bhaskar/rpmbuild/BUILDROOT/iperf-2.0.4-1.i386/usr/share/man/man1"
/usr/bin/install -c -m 644 './iperf.1' '/home/bhaskar/rpmbuild/BUILDROOT/iperf-2.0.4-1.i386/usr/share/man/man1/iperf.1'
/usr/bin/install -c -m 644 './iperf.1' '/home/bhaskar/rpmbuild/BUILDROOT/iperf-2.0.4-1.i386/usr/share/man/man1/iperf.1'
make[2]: Leaving directory `/home/bhaskar/iperfRPM/BUILD/iperf-2.0.4/man'
make[1]: Leaving directory `/home/bhaskar/iperfRPM/BUILD/iperf-2.0.4/man'
make[1]: Entering directory `/home/bhaskar/iperfRPM/BUILD/iperf-2.0.4'
make[2]: Entering directory `/home/bhaskar/iperfRPM/BUILD/iperf-2.0.4'
make[2]: Nothing to be done for `install-exec-am'.
make[2]: Nothing to be done for `install-data-am'.
make[2]: Leaving directory `/home/bhaskar/iperfRPM/BUILD/iperf-2.0.4'
make[1]: Leaving directory `/home/bhaskar/iperfRPM/BUILD/iperf-2.0.4'
+ /usr/lib/rpm/brp-compress
+ /usr/lib/rpm/brp-strip
+ /usr/lib/rpm/brp-strip-static-archive
+ /usr/lib/rpm/brp-strip-comment-note
Processing files: iperf-2.0.4-1.i386
Requires(rpmlib): rpmlib(CompressedFileNames) <= 3.0.4-1 rpmlib(PayloadFilesHavePrefix) <= 4.0-1 Requires: libc.so.6 libc.so.6(GLIBC_2.0) libc.so.6(GLIBC_2.1) libc.so.6(GLIBC_2.1.3) libc.so.6(GLIBC_2.3) libc.so.6(GLIBC_2.7) libgcc_s.so.1 libgcc_s.so.1(GCC_3.0) libm.so.6 libpthread.so.0 libpthread.so.0(GLIBC_2.0) libpthread.so.0(GLIBC_2.1) libpthread.so.0(GLIBC_2.3.2) libstdc++.so.6 libstdc++.so.6(CXXABI_1.3) libstdc++.so.6(GLIBCXX_3.4) rtld(GNU_HASH) Checking for unpackaged file(s): /usr/lib/rpm/check-files /home/bhaskar/rpmbuild/BUILDROOT/iperf-2.0.4-1.i386 Wrote: /home/bhaskar/iperfRPM/SRPMS/iperf-2.0.4-1.src.rpm Wrote: /home/bhaskar/iperfRPM/RPMS/i386/iperf-2.0.4-1.i386.rpm Executing(--clean): /bin/sh -e /var/tmp/rpm-tmp.V9lg5X + umask 022 + cd /home/bhaskar/iperfRPM/BUILD + rm -rf iperf-2.0.4 + exit 0 So it's all done well. Now what this command will do? It will first create a folder under the user home directory called 'rpmbuild' bhaskar@bhaskar-laptop_09:43:59_Tue Mar 30:~> ls -ld rpmbuild/
drwxr-xr-x. 8 root root 4096 2010-03-30 09:40 rpmbuild/

Surprise by seeing the permisson of that folder..because I ran the command as sudo;Anyway it contains this dir inside it:

bhaskar@bhaskar-laptop_09:44:07_Tue Mar 30:~> ls -lath rpmbuild/
total 32K
drwxr-xr-x. 3 root root 4.0K 2010-03-30 09:41 BUILDROOT
drwxr-xr-x. 8 root root 4.0K 2010-03-30 09:40 .
drwxr-xr-x. 2 root root 4.0K 2010-03-30 09:40 BUILD
drwxr-xr-x. 2 root root 4.0K 2010-03-30 09:40 RPMS
drwxr-xr-x. 2 root root 4.0K 2010-03-30 09:40 SOURCES
drwxr-xr-x. 2 root root 4.0K 2010-03-30 09:40 SPECS
drwxr-xr-x. 2 root root 4.0K 2010-03-30 09:40 SRPMS
drwx------. 43 bhaskar bhaskar 4.0K 2010-03-30 09:40 ..


As I told you beforehand that all the placeholder file location will be under buildroot variable.Just to under BUILDROOT dir disclose this info:

bhaskar@bhaskar-laptop_09:45:40_Tue Mar 30:~> ls -lath ~/rpmbuild/BUILDROOT/
total 12K
drwxr-xr-x. 3 root root 4.0K 2010-03-30 09:41 .
drwxr-xr-x. 3 root root 4.0K 2010-03-30 09:41 iperf-2.0.4-1.i386
drwxr-xr-x. 8 root root 4.0K 2010-03-30 09:40 ..

bhaskar@bhaskar-laptop_09:47:10_Tue Mar 30:~> ls -lath ~/rpmbuild/BUILDROOT/iperf-2.0.4-1.i386/
total 12K
drwxr-xr-x. 4 root root 4.0K 2010-03-30 09:41 usr
drwxr-xr-x. 3 root root 4.0K 2010-03-30 09:41 .
drwxr-xr-x. 3 root root 4.0K 2010-03-30 09:41 ..

So it contain the actual place where the software is going to be installed system wide.

I want check whether that rpm is actually created in the right place or not.For that just look into RPMS and SRPMS dir of the buildroot dir:

bhaskar@bhaskar-laptop_09:49:56_Tue Mar 30:~> ls -alth ~/iperfRPM/RPMS/i386/
total 44K
drwxr-xr-x. 2 root root 4.0K 2010-03-30 09:41 .
-rw-r--r--. 1 root root 36K 2010-03-30 09:41 iperf-2.0.4-1.i386.rpm
drwxr-xr-x. 3 bhaskar bhaskar 4.0K 2010-03-30 09:41 ..

The rpms always create under the arch directory for which it specifically built.Likewise the SRPMS:

bhaskar@bhaskar-laptop_09:50:01_Tue Mar 30:~> ls -alth ~/iperfRPM/SRPMS/
total 256K
-rw-r--r--. 1 root root 245K 2010-03-30 09:41 iperf-2.0.4-1.src.rpm
drwxr-xr-x. 2 bhaskar bhaskar 4.0K 2010-03-30 09:41 .
drwxr-xr-x. 7 bhaskar bhaskar 4.0K 2010-03-30 08:45 ..

Step 6:

Now time to install the rpm

bhaskar@bhaskar-laptop_09:51:07_Tue Mar 30:~> sudo rpm -ivh ~/iperfRPM/RPMS/i386/iperf-2.0.4-1.i386.rpm
[sudo] password for bhaskar:
Preparing... ########################################### [100%]
1:iperf ########################################### [100%]

Now it's been installed.Just to crosss check with rpm query.

bhaskar@bhaskar-laptop_09:52:21_Tue Mar 30:~> rpm -qi iperf
Name : iperf Relocations: /usr
Version : 2.0.4 Vendor: (none)
Release : 1 Build Date: Tue 30 Mar 2010 09:41:11 AM IST
Install Date: Tue 30 Mar 2010 09:52:19 AM IST Build Host: localhost.localdomain
Group : Development/Tools Source RPM: iperf-2.0.4-1.src.rpm
Size : 71890 License: GPL
Signature : (none)
Summary : iperf
Description :
Iperf was developed by NLANR/DAST as a modern alternative for measuring maximum TCP and UDP bandwidth performance. Iperf allows the tuning of various parameters and UDP characteristics. Iperf reports bandwidth, delay jitter, datagram loss.

Now you can view the man page of it like it :

bhaskar@bhaskar-laptop_09:53:08_Tue Mar 30:~> man iperf

IPERF(1) User Manuals IPERF(1)

NAME
iperf - perform network throughput tests

SYNOPSIS
iperf -s [ options ]

iperf -c server [ options ]

iperf -u -s [ options ]

iperf -u -c server [ options ]

DESCRIPTION
iperf is a tool for performing network throughput measurements. It can test either TCP or UDP throughput. To perform an iperf test
the user must establish both a server (to discard traffic) and a client (to generate traffic).

GENERAL OPTIONS
-f, --format
[kmKM] format to report: Kbits, Mbits, KBytes, MBytes

-h, --help
print a help synopsis

-i, --interval n
pause n seconds between periodic bandwidth reports

-l, --len n[KM]

................ output ommited

Step 7:

To see how it can be use :

bhaskar@bhaskar-laptop_09:54:36_Tue Mar 30:~> iperf --help
Usage: iperf [-s|-c host] [options]
iperf [-h|--help] [-v|--version]

Client/Server:
-f, --format [kmKM] format to report: Kbits, Mbits, KBytes, MBytes
-i, --interval # seconds between periodic bandwidth reports
-l, --len #[KM] length of buffer to read or write (default 8 KB)
-m, --print_mss print TCP maximum segment size (MTU - TCP/IP header)
-o, --output output the report or error message to this specified file
-p, --port # server port to listen on/connect to
-u, --udp use UDP rather than TCP
-w, --window #[KM] TCP window size (socket buffer size)
-B, --bind bind to , an interface or multicast address
-C, --compatibility for use with older versions does not sent extra msgs
-M, --mss # set TCP maximum segment size (MTU - 40 bytes)
-N, --nodelay set TCP no delay, disabling Nagle's Algorithm
-V, --IPv6Version Set the domain to IPv6

Server specific:
-s, --server run in server mode
-U, --single_udp run in single threaded UDP mode
-D, --daemon run the server as a daemon

Client specific:
-b, --bandwidth #[KM] for UDP, bandwidth to send at in bits/sec
(default 1 Mbit/sec, implies -u)
-c, --client run in client mode, connecting to
-d, --dualtest Do a bidirectional test simultaneously
-n, --num #[KM] number of bytes to transmit (instead of -t)
-r, --tradeoff Do a bidirectional test individually
-t, --time # time in seconds to transmit for (default 10 secs)
-F, --fileinput input the data to be transmitted from a file
-I, --stdin input the data to be transmitted from stdin
-L, --listenport # port to recieve bidirectional tests back on
-P, --parallel # number of parallel client threads to run
-T, --ttl # time-to-live, for multicast (default 1)
-Z, --linux-congestion set TCP congestion control algorithm (Linux only)

Miscellaneous:
-x, --reportexclude [CDMSV] exclude C(connection) D(data) M(multicast) S(settings) V(server) reports
-y, --reportstyle C report as a Comma-Separated Values
-h, --help print this message and quit
-v, --version print version information and quit

[KM] Indicates options that support a K or M suffix for kilo- or mega-

The TCP window size option can be set by the environment variable
TCP_WINDOW_SIZE. Most other options can be set by an environment variable
IPERF_, such as IPERF_BANDWIDTH.

Report bugs to

Just like this:

bhaskar@bhaskar-laptop_09:55:33_Tue Mar 30:~> sudo iperf -c bhaskar-laptop
connect failed: Connection refused
write1 failed: Broken pipe
------------------------------------------------------------
Client connecting to bhaskar-laptop, TCP port 5001
write2 failed: Broken pipe
TCP window size: 16.0 KByte (default)
------------------------------------------------------------
[ 3] local 0.0.0.0 port 35914 connected with 127.0.0.1 port 5001
[ ID] Interval Transfer Bandwidth
[ 3] 0.0- 0.0 sec 0.00 Bytes 0.00 bits/sec

Conclusion: Building rpm is an complex task. One can do many thing with rpm namely sign it ,provide prequisite to build the software ,provide post install work ,pre install work done by the rpm all in the spec file.In return it gives you a better understanding of the underlying system and ease to maintain the system. I have been highly motivated by the articles published in IBM developerworks part1 , part2 and part3 


This is great site to explain all that step by step rpmbuild-process .

Hope this will help.

Bhaskar Chowdhury

2 comments:

  1. Thank you for the detailed description. If only these steps would not take so much time. For those who fell the same I would recommend checkinstall and RPM Package Maker. Both apps speed up the process, but they are a bit limited.

    ReplyDelete
  2. It is great i will try it
    Thx for that Bhaskar....

    ReplyDelete