Merge branch 'master' of git://git.pcp.io/kenj/pcp into kenj-merge
[pcp.git] / Makepkgs
blob4570599817eb9327e48746712ec2c20e8f4d6b2e
1 #!/bin/sh
3 # Make whichever packages the system supports
5 # Copyright (c) 2012-2015 Red Hat.
6 # Copyright (c) 2004 Silicon Graphics, Inc. All Rights Reserved.
7 #
8 # This program is free software; you can redistribute it and/or modify it
9 # under the terms of the GNU General Public License as published by the
10 # Free Software Foundation; either version 2 of the License, or (at your
11 # option) any later version.
13 # This program is distributed in the hope that it will be useful, but
14 # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 # for more details.
19 topdir=`pwd`
20 signed=false
21 verbose=false
22 srconly=false
23 dorpm=unknown
24 dodeb=unknown
25 vector=false
26 webjs=false
27 docker=false
29 if [ ! -d .git ]
30 then
31 echo "Error: can only be run from within the PCP git repository"
32 exit 1
35 if [ ! -f VERSION.pcp ]
36 then
37 echo "Error: can only be run from within the PCP source tree"
38 exit 1
41 # Find where a GNU tool is hiding, look for this line:
42 # "Report bugs to <bug-$gnutool@gnu.org>"
43 # or this line:
44 # "FreeBSD $gnutool YYYYMMDD"
45 # in the $gnutool --help output
47 gnu_tool()
49 prefix="$1"
50 shift
51 envvar="$1"
52 shift
53 oldcmd="$1"
54 shift
56 # Not in the environment, go search for it in the known locations.
58 if [ -z "$envvar" ]
59 then
60 for command in $oldcmd $@
62 exec=`which $command 2>/dev/null`
63 if [ -n "$exec" ]
64 then
65 if $command --help 2>&1 | egrep "(bug-$oldcmd@gnu.org)|(FreeBSD $gnutool)|(NetBSD $gnutool)|(Apple $gnutool)" >/dev/null
66 then
67 echo $exec
68 return 0
70 # special cases
72 if [ "$target" = openbsd -a $command = gzip ]
73 then
74 echo $exec
75 return 0
78 done
79 echo >&2 "$prefix: can't find GNU $oldcmd in the commands $oldcmd or $@"
80 [ $prefix = Error ] && exit 1
81 return 1
84 # Use the environment request and ensure it is a full path (do not
85 # change this behaviour, it is required for backward-compatibility
86 # - QA failures will result if you choose to ignore this warning).
88 command=`which $envvar 2>/dev/null`
89 if [ -z "$command" ]
90 then
91 echo >&2 "$prefix: $oldcmd (from the environment) does not exist!"
92 [ $prefix = Error ] && exit 1
93 return 1
95 echo $command
96 return 0
99 target=`uname -s | tr 'A-Z' 'a-z'`
101 export MAKE=`gnu_tool Error "$MAKE" make gmake`
102 export TAR=`gnu_tool Warning "$TAR" tar gtar gnutar`
103 export ZIP=`gnu_tool Error "$ZIP" gzip gnuzip`
105 # check if tar supports --transform else we must use git-archive later on (e.g. RHEL5)
106 [ ! -z "$TAR" ] && $TAR --help | 2>&1 grep -q transform || USE_GIT_ARCHIVE=1
108 tmp=`mktemp -d /tmp/pcp.XXXXXXXXX` || exit 1
109 trap "rm -rf $tmp" 0 1 2 3 15
111 configure=./configure
112 cmdline_configopts=''
114 for opt in $*
116 case "$opt" in
117 -clean|--clean)
118 # we always clean nowadays, so silently ignore
119 shift
121 -verbose|--verbose)
122 verbose=true
123 shift
125 --nonrpm)
126 dorpm=false
127 shift
129 --nondeb)
130 dodeb=false
131 shift
133 --signed)
134 signed=true
135 shift
137 --source)
138 srconly=true
139 shift
141 --target)
142 shift
143 target=$1
144 shift
146 --with-vector)
147 cmdline_configopts="$cmdline_configopts $opt"
148 vector=true
149 shift
151 --with-webjs)
152 cmdline_configopts="$cmdline_configopts $opt"
153 webjs=true
154 shift
156 --with-docker)
157 docker=true
158 shift
160 --with-make)
161 MAKE=$1
162 shift
164 --with-tar)
165 TAR=$1
166 shift
168 --with-zip)
169 ZIP=$1
170 shift
173 # Add remaining options to the ./configure command line
174 cmdline_configopts="$cmdline_configopts $opt"
175 shift
177 esac
178 done
180 if [ $dorpm = unknown ]
181 then
182 dorpm=false
183 [ -x /usr/bin/rpmbuild ] && dorpm=true
185 if [ $dodeb = unknown ]
186 then
187 dodeb=false
188 [ -x /usr/bin/dpkg-buildpackage ] && dodeb=true
191 # beware of double negatives here ...
193 if $dodeb && $dorpm
194 then
195 echo >&2 "Do not know how to build RPM and Debian packages at the same time!"
196 echo >&2 "Suggest --nonrpm or --nondeb on the command line."
197 exit 1
200 if $dodeb
201 then
202 # On Debian-based platforms, the debian/rules file already captures
203 # most of the required configure settings in $(configure_paths)
205 configopts=''
206 elif $dorpm
207 then
208 # On RPM-based platforms, rpm macros provide an excellent set of defaults.
209 # This set is based on Fedora 22 %configure macro from /usr/lib/rpm/macros,
210 # and is known to work as far back as RHEL5.
211 configopts="`rpmbuild --eval '--prefix=%{_prefix} --exec-prefix=%{_exec_prefix} --bindir=%{_bindir} --sbindir=%{_sbindir} --sysconfdir=%{_sysconfdir} --datadir=%{_datadir} --includedir=%{_includedir} --libdir=%{_libdir} --libexecdir=%{_libexecdir} --localstatedir=%{_localstatedir} --sharedstatedir=%{_sharedstatedir} --mandir=%{_mandir}' 2>/dev/null`"
212 # rpmbuild clears the environment, so force these settings into the
213 # rpm build configure
215 configopts="$configopts --with-make=$MAKE --with-tar=$TAR --with-zip=$ZIP"
216 elif [ $target = darwin ]
217 then
218 # On Mac OS X platforms, we install away from /usr/bin, /usr/lib
219 # and so on because of security requirements in recent versions.
221 configopts="--prefix=/usr/local --sysconfdir=/etc --localstatedir=/var"
222 elif [ $target = netbsd ]
223 then
224 # Try to mimic where pkgsrc/pkgin place things
226 configopts="--prefix=/usr/pkg --exec-prefix=/usr/pkg --mandir=/usr/pkg/man --with-rcdir=/etc/rc.d --localstatedir=/usr/pkg --with-rundir=/var/run --with-tmpdir=/var/tmp --with-logdir=/var/log/pcp"
227 else
228 # Bog-standard options suitable for a package on any platform.
229 # Command line can be used to extend this set, and any unusual
230 # platform-specific requirements are also appended later on.
231 configopts="--prefix=/usr --sysconfdir=/etc --localstatedir=/var"
234 # Platform-specific variants ...
236 case "$target"
238 mingw|mingw64|windows)
239 target=mingw
240 if $dorpm
241 then
242 echo >&2 "Warning: --dorpm ignored for Windows build"
244 dorpm=false
245 configopts="$configopts --disable-ssp"
246 export configure="/usr/bin/mingw64-configure"
247 export MAKE="/usr/bin/mingw64-make"
248 export QMAKE="/usr/bin/mingw64-qmake-qt4"
249 export PKG_CONFIG="/usr/bin/mingw64-pkg-config"
251 linux)
252 ARCH=`uname -m`
253 [ -f /etc/slackware-version -a "$ARCH" = x86_64 ] && configopts="$configopts --libdir=/usr/lib64"
255 sunos|SunOS)
256 ARCH=`isainfo -k`
257 [ "$ARCH" = amd64 -o "$ARCH" = sparcv9 ] && configopts="$configopts --libdir=/usr/lib/64"
258 export YACC=bison
259 export LEX=flex
261 esac
263 # now some specific QA/development hosts with special needs ...
265 case `hostname`
267 vm04|vm04.localdomain|vm11|vm11.localdomain)
268 # gcc -O2 is broken here (for the linux PMDA)
270 configopts="$configopts --with-optimization=no"
271 # over-ride the settings from dpkg-buildflags
273 export DEB_CFLAGS_SET=''
274 export DEB_CXXFLAGS_SET=''
276 esac
278 # and finally add in any from the command line
280 [ -n "$cmdline_configopts" ] && configopts="$configopts $cmdline_configopts"
282 . ./VERSION.pcp
283 VERSION=${PACKAGE_MAJOR}.${PACKAGE_MINOR}.${PACKAGE_REVISION}
285 LOGDIR=$topdir/Logs
286 rm -rf "$LOGDIR"
287 mkdir -p "$LOGDIR"
289 source=pcp-${VERSION}
290 SRCDIR=$topdir/$source
291 SRCTAR=$topdir/build/tar/$source.src.tar.gz
292 SRCWEBJS=$topdir/build/tar/webjs.tar.gz
293 SRCVECTOR=$topdir/build/tar/vector.tar.gz
295 build_failure()
297 # only print in non-verbose mode, otherwise we see double
298 if ! $verbose ; then
299 echo $@ failed, see log in $LOGDIR/pcp
300 tail $LOGDIR/pcp
302 exit 1
305 clean_packaging()
307 echo
308 echo "== Cleaning build tree for packaging build"
309 rm -rf "$SRCDIR" "$SRCTAR" .gitcensus
312 fix_version()
314 if [ -f "$1" -a -f "$2" ]
315 then
316 # as expected, both present
317 if diff "$1" "$2" >/dev/null 2>&1
318 then
320 else
321 # must be using git-archive(1) and VERSION.pcp has been
322 # modified, e.g. by pcp-daily script ... use the modified
323 # one to bump the build number in the packages
325 cp "$1" "$2"
327 else
328 echo "Arrgh ... expect both these to exist ..."
329 ls -l "$1" "$2"
330 exit 1
334 # Download sources from external repositories that we might want
335 # to include with the PCP packages.
337 third_parties()
339 if $vector
340 then
341 if [ ! -f "$SRCVECTOR" ]
342 then
343 echo "== Downloading Vector webapp"
344 wget -q -O "$SRCVECTOR" \
345 https://bintray.com/artifact/download/netflixoss/downloads/vector.tar.gz
346 [ $? -eq 0 ] && echo "Wrote: $SRCVECTOR"
348 if [ -f "$SRCVECTOR" ]
349 then
350 DESTVECTOR="$topdir/$source/build/tar/"`basename $SRCVECTOR`
351 cp "$SRCVECTOR" "$DESTVECTOR"
355 if $webjs
356 then
357 if [ ! -f "$SRCWEBJS" ]
358 then
359 echo "== Downloading webjs webapps"
360 wget -q -O $tmp/js.zip \
361 https://github.com/performancecopilot/pcp-webjs/archive/master.zip
362 [ $? -eq 0 ] && ./scripts/zip2tar $tmp/js.zip $SRCWEBJS
364 if [ -f "$SRCWEBJS" ]
365 then
366 DESTWEBJS="$topdir/$source/build/tar/"`basename $SRCWEBJS`
367 cp "$SRCWEBJS" "$DESTWEBJS"
372 # Generate a list of all the files git knows about, create the
373 # source tarball and then unpack it. We'll then do the package
374 # build in a guaranteed pristine environment.
376 src_tar_build()
378 if [ -z "$TAR" -o ! -z "$USE_GIT_ARCHIVE" ]
379 then
380 # no suitable GNU tar is available, use git-archive(1) - no local changes
381 if git status -s src man | grep '^.M'
382 then
383 echo "Arrgh, modified src files and either no tar ($TAR) or no --transform"
384 echo "support in tar, so local changes would not be included in the build."
385 exit 1
387 git archive --format=tar --prefix=$source/ HEAD | $ZIP > $SRCTAR
388 else
389 # build git file list and make tarball by hand to pick up any changes
390 git ls-files > .gitcensus
391 $TAR -cz --transform="s,^,$source/," --files-from=.gitcensus \
392 --file=$SRCTAR
393 rm .gitcensus
395 echo "Wrote: $SRCTAR"
398 # On sanity checks :- this is sick, but I'm really tired of QA failing
399 # because of bad binaries being built from the Debian/Ubuntu toolchain
400 # for # i?86 platforms
401 # - Ken McDonell Apr 2010
403 sanity_check_settings()
405 OPT=false
406 ARCH=`uname -m | sed -e 's/i.86/ia32/'`
407 if [ "$ARCH" != "ia32" ]
408 then
409 OPT=true # no workarounds needed for non-i?86 platforms
410 elif [ -f /etc/lsb-release ]
411 then
412 if grep -q 'DISTRIB_ID=Ubuntu' /etc/lsb-release
413 then
414 eval `grep DISTRIB_RELEASE= /etc/lsb-release`
415 XDISTRIB_RELEASE=`echo $DISTRIB_RELEASE | sed -e 's/[^0-9]//g'`
416 [ -z "$XDISTRIB_RELEASE" ] && XDISTRIB_RELEASE=0000
417 if [ $XDISTRIB_RELEASE -gt 1110 ]
418 then
419 # Hope the problem is fixed after Ubuntu 11.10
420 OPT=true
423 $OPT || echo "Building without optimization for Ubuntu $DISTRIB_RELEASE"
424 elif [ -f /etc/debian_version ]
425 then
426 DISTRIB_RELEASE=`cat /etc/debian_version`
427 XDISTRIB_RELEASE=`echo $DISTRIB_RELEASE | sed -e 's/[^0-9]//g'`
428 [ -z "$XDISTRIB_RELEASE" ] && XDISTRIB_RELEASE=0000
429 if [ $XDISTRIB_RELEASE -ge 700 ]
430 then
431 # Hope the problem is fixed in Debian 7.0.0
432 OPT=true
434 $OPT || echo "Building without optimization for Debian $DISTRIB_RELEASE"
437 if ! $OPT
438 then
439 ok=true
440 if grep -q '^my $default_flags .*O2' /usr/bin/dpkg-buildpackage
441 then
442 echo 'dpkg-buildpackage: need to remove O2 from $default_flags'
443 ok=false
445 if grep -q '^[ ]*LDFLAGS.*-Bsymbolic-functions' /usr/bin/dpkg-buildpackage
446 then
447 echo 'dpkg-buildpackage: need to remove -Bsymbolic-function from LDFLAGS'
448 ok=false
450 if ! $ok
451 then
452 echo "Refer to Debian/Ubuntu notes in PCP's ./INSTALL"
453 exit 1
455 # as of Debian 6.0.1 and Ubuntu 10.10, build flags are hidden and
456 # extracted using dpkg-buildflags which fortunately honours some
457 # environment variable settings
459 export DEB_CFLAGS_SET=''
460 export DEB_CXXFLAGS_SET=''
461 export DEB_LDFLAGS_SET=''
465 # Build Debian packages using the dpkg-buildpackage utility which runs
466 # the complete build, from configure through to final deb preparation.
468 debian_buildpackage()
470 echo
471 echo "== Building deb packages using dpkg-buildpackage"
473 SUDO=${SUDO:-fakeroot}
474 # don't sign by default
475 sign='-us -uc'
476 # sign if --signed and $DEB_SIGN_KEYID set in the environment
477 $signed && [ -n "$DEB_SIGN_KEYID" ] && sign=''
478 rm -f $tmp/failed
479 if $verbose ; then
480 (dpkg-buildpackage $sign -r$SUDO || touch $tmp/failed) 2>&1 | tee -a $LOGDIR/pcp
481 else
482 (dpkg-buildpackage $sign -r$SUDO || touch $tmp/failed) >>$LOGDIR/pcp 2>&1
484 [ -f $tmp/failed ] && build_failure debian buildpackage
487 prepare_debian_sources()
489 # shortcut for dpkg-buildpackage which does everything itself from here
490 SRCDIR="${topdir}/build/deb"
491 rm -rf "${SRCDIR}"
492 mkdir -p "$SRCDIR" 2>/dev/null
493 cd "$SRCDIR" || exit 1
494 $TAR -zxf "$SRCTAR" || exit 1
495 cd "$SRCDIR/$source" || exit 1
496 fix_version ${topdir}/VERSION.pcp VERSION.pcp
499 prepare_debian_control()
501 echo
502 echo "== Preparing source tree for dpkg-buildpackage"
503 rm -f $tmp/failed debian/control
504 if $verbose ; then
505 ($MAKE -C debian control 2>&1 || touch $tmp/failed) 2>&1 | tee -a $LOGDIR/pcp
506 else
507 ($MAKE -C debian control 2>&1 || touch $tmp/failed) >>$LOGDIR/pcp 2>&1
509 [ -f $tmp/failed ] && build_failure debian control
512 debian_build()
514 prepare_debian_sources
515 # Note: we need to run configure here to get things like builddefs
516 # created, but configure will be run _again_ from
517 # debian_buildpackage, but we need to make sure the same
518 # configure options are used in both places
520 export configure_opts="$configopts"
521 if [ ! -f debian/rules ]
522 then
523 echo "Botch: cannot find debian/rules"
524 exit 1
526 debian_opts=`sed -n <debian/rules -e '/^configure_paths/s/^[^=]*= *//p'`
527 if [ -z "$debian_opts" ]
528 then
529 echo "Botch: cannot get config options from configure_paths in debian/rules"
530 exit 1
532 configopts="$debian_opts $configopts"
533 configure_pcp
534 prepare_debian_control
535 sanity_check_settings
536 debian_buildpackage
537 exit 0
540 prepare_build()
542 echo
543 echo "== Preparing fresh build tree for packaging build"
545 if [ ! -d "$SRCDIR" ]; then
546 # extract gzipped tar archive
547 $TAR -xz --file="$SRCTAR" || exit 1
548 fix_version VERSION.pcp $SRCDIR/VERSION.pcp
552 configure_pcp()
554 echo
555 echo "== Configuring pcp, log is in $LOGDIR/pcp ($configopts)"
557 rm -f $tmp/failed
558 if $verbose
559 then
560 ($configure $configopts 2>&1 || touch $tmp/failed) 2>&1 | tee -a $LOGDIR/pcp
561 else
562 ($configure $configopts 2>&1 || touch $tmp/failed) >>$LOGDIR/pcp 2>&1
564 [ -f $tmp/failed ] && build_failure Configure
567 default_build()
569 echo
570 echo "== Building pcp, log is in $LOGDIR/pcp"
572 rm -f $tmp/failed
573 if $verbose ; then
574 ($MAKE default_pcp 2>&1 || touch $tmp/failed) 2>&1 | tee -a $LOGDIR/pcp
575 else
576 ($MAKE default_pcp 2>&1 || touch $tmp/failed) >>$LOGDIR/pcp 2>&1
578 [ -f $tmp/failed ] && build_failure Make default_pcp
581 packaging_pcp()
583 echo
584 echo "== Packaging pcp, log is in $LOGDIR/pcp" | tee -a $LOGDIR/pcp
586 rm -f $tmp/failed
587 if $verbose ; then
588 ($MAKE -C build pack_pcp 2>&1 || touch $tmp/failed) 2>&1 | tee -a $LOGDIR/pcp
589 else
590 ($MAKE -C build pack_pcp 2>&1 || touch $tmp/failed) >>$LOGDIR/pcp 2>&1
592 [ -f $tmp/failed ] && build_failure Packaging via pack_pcp
595 packaging_rpm()
597 echo
598 echo "== Building rpm packages, log is in $LOGDIR/pcp" | tee -a $LOGDIR/pcp
600 rm -f $tmp/failed
601 export DIST_ROOT=${topdir}/build/rpm/${source}
602 if $verbose ; then
603 ($MAKE -C build/rpm pack_pcp 2>&1 || touch $tmp/failed) 2>&1 | tee -a $LOGDIR/pcp
604 else
605 ($MAKE -C build/rpm pack_pcp 2>&1 || touch $tmp/failed) >>$LOGDIR/pcp 2>&1
607 [ -f $tmp/failed ] && build_failure Packaging RPMs via pack_pcp
610 packaging_docker()
612 echo
613 echo "== Building docker container images, log is in $LOGDIR/pcp" | tee -a $LOGDIR/pcp
614 rm -f $tmp/failed
616 if docker version >/dev/null 2>&1; then
617 v=`docker version | sed -e 's/\./ /g' | \
618 awk '/^Server/ {s=1; if($2 == "version:") {print 10*$3+$4; exit}}
619 /Version:/ {if (s) {print 10*$2+$3; exit}}'`
620 if [ -z "$v" -o "$v" -lt 14 ]; then
621 echo 'Error: docker version too old. Containers build skipped.'
622 touch $tmp/failed
624 else
625 echo 'Error: docker not enabled or not properly configured for non-root access.'
626 echo 'Check the docker service is enabled and running. You can allow non-root access'
627 echo 'as follows: edit /etc/sysconfig/docker and add OPTIONS="-G gid" where gid is a'
628 echo 'group name that you are a member of. Then restart the docker service.'
629 touch $tmp/failed
632 [ -f $tmp/failed ] && build_failure Packaging docker images, docker configuration
634 if $verbose ; then
635 ($MAKE -C build/containers pack_pcp 2>&1 || touch $tmp/failed) 2>&1 | tee -a $LOGDIR/pcp
636 else
637 ($MAKE -C build/containers pack_pcp 2>&1 || touch $tmp/failed) >>$LOGDIR/pcp 2>&1
640 [ -f $tmp/failed ] && build_failure Packaging docker containers via pack_pcp
643 # real build starts here
644 clean_packaging
645 src_tar_build
646 $srconly && exit 0
648 # short-circuit for performing builds with dpkg-buildpackage
649 $dodeb && debian_build
651 prepare_build
653 # download any requested third party sources we're packaging
654 third_parties
656 # shift into the clean packaging build tree from here onward
657 cd "$SRCDIR"
659 configure_pcp
661 # short-circuit for performing rpm-only builds with rpmbuild
662 # (skips over the default_build stage as rpmbuild does that).
663 if $dorpm
664 then
665 packaging_rpm
666 else
667 default_build # perform a complete build in-situ
668 packaging_pcp # create all known package formats
672 # --with-docker, currently only for RPM platforms with docker
673 if $docker
674 then
675 packaging_docker
678 # success!
679 if ! $verbose ; then
680 grep '^Wrote:' $LOGDIR/pcp | sed -e 's/\.\.\/\.\.\///'
682 exit 0