Merge branch 'master' of https://github.com/kmcdonell/pcp into kenj-merge
[pcp.git] / Makepkgs
blob543478b160090f51323f5bc630a12644d8b4a2f1
1 #!/bin/sh
3 # Make whichever packages the system supports
5 # Copyright (c) 2012-2017 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 webapps=false
26 docker=false
28 if [ ! -d .git ]
29 then
30 echo "Error: can only be run from within the PCP git repository"
31 exit 1
34 if [ ! -f VERSION.pcp ]
35 then
36 echo "Error: can only be run from within the PCP source tree"
37 exit 1
40 tmp=`mktemp -d /tmp/pcp.XXXXXXXXX` || exit 1
41 trap "rm -rf $tmp $tmp.help" 0 1 2 3 15
42 target=`uname -s | tr 'A-Z' 'a-z'`
44 # Find where a GNU tool is hiding, look for this line in the
45 # $gnutool --help output ...
46 # "Report bugs to <bug-$gnutool@gnu.org>"
47 # or lines like this:
48 # FreeBSD $gnutool
49 # NetBSD $gnutool
50 # OpenBSD $gnutool
51 # Apple $gnutool
52 # or these lines:
53 # *This* tar defaults to:
54 # --format=gnu ...
56 gnu_tool()
58 prefix="$1"
59 shift
60 envvar="$1"
61 shift
62 oldcmd="$1"
63 shift
65 # Not in the environment, go search for it in the known locations.
67 if [ -z "$envvar" ]
68 then
69 for command in $oldcmd $@
71 exec=`which $command 2>/dev/null`
72 if [ -n "$exec" ]
73 then
74 $command --help >$tmp.help 2>&1
75 if egrep "(bug-$oldcmd@gnu.org)|(FreeBSD $command)|(NetBSD $command)|(OpenBSD $command)|(Apple $command)" $tmp.help >/dev/null
76 then
77 echo $exec
78 return 0
80 awk <$tmp.help >$tmp.check '
81 BEGIN { want = 0 }
82 /This\** tar defaults to:/ { want=1; next }
83 want == 1 { print; exit }'
84 if grep '[-][-]format=gnu' <$tmp.check >/dev/null
85 then
86 echo $exec
87 return 0
89 # special cases
91 if [ "$target" = openbsd -a $command = gzip ]
92 then
93 echo $exec
94 return 0
97 done
98 echo >&2 "$prefix: can't find GNU $oldcmd in the commands $oldcmd or $@"
99 [ $prefix = Error ] && exit 1
100 return 1
103 # Use the environment request and ensure it is a full path (do not
104 # change this behaviour, it is required for backward-compatibility
105 # - QA failures will result if you choose to ignore this warning).
107 command=`which $envvar 2>/dev/null`
108 if [ -z "$command" ]
109 then
110 echo >&2 "$prefix: $oldcmd (from the environment) does not exist!"
111 [ $prefix = Error ] && exit 1
112 return 1
114 echo $command
115 return 0
118 export MAKE=`gnu_tool Error "$MAKE" make gmake`
119 export TAR=`gnu_tool Warning "$TAR" tar gtar gnutar`
120 export ZIP=`gnu_tool Error "$ZIP" gzip gnuzip`
122 # check if tar supports --transform else we must use git-archive later on (e.g. RHEL5)
123 [ -n "$TAR" ] && $TAR --help | 2>&1 grep -q transform || USE_GIT_ARCHIVE=1
124 #debug# echo TAR=$TAR USE_GIT_ARCHIVE=$USE_GIT_ARCHIVE
126 configure=./configure
127 cmdline_configopts=''
129 for opt in $*
131 case "$opt" in
132 -clean|--clean)
133 # we always clean nowadays, so silently ignore
134 shift
136 -verbose|--verbose)
137 verbose=true
138 shift
140 --nonrpm)
141 dorpm=false
142 shift
144 --nondeb)
145 dodeb=false
146 shift
148 --signed)
149 signed=true
150 shift
152 --source)
153 srconly=true
154 shift
156 --target)
157 shift
158 target=$1
159 shift
161 --with-webapps)
162 cmdline_configopts="$cmdline_configopts $opt"
163 webapps=true
164 shift
166 --with-docker)
167 docker=true
168 shift
170 --with-make)
171 MAKE=$1
172 shift
174 --with-tar)
175 TAR=$1
176 shift
178 --with-zip)
179 ZIP=$1
180 shift
183 # Add remaining options to the ./configure command line
184 cmdline_configopts="$cmdline_configopts $opt"
185 shift
187 esac
188 done
190 if [ $dorpm = unknown ]
191 then
192 dorpm=false
193 if which slackpkg >/dev/null 2>&1
194 then
195 # Slackware has rpm(1) and rpmbuild(1), but don't build RPMs
198 else
199 [ -x /usr/bin/rpmbuild ] && dorpm=true
202 if [ $dodeb = unknown ]
203 then
204 dodeb=false
205 [ -x /usr/bin/dpkg-buildpackage ] && dodeb=true
208 # Hmm ...
210 if $dodeb && $dorpm
211 then
212 echo >&2 "Do not know how to build RPM and Debian packages at the same time!"
213 echo >&2 "Suggest --nonrpm or --nondeb on the command line."
214 exit 1
217 if $dodeb
218 then
219 # On Debian-based platforms, the debian/rules file already captures
220 # most of the required configure settings in $(configure_paths)
222 configopts=''
223 elif $dorpm
224 then
225 # On RPM-based platforms, rpm macros provide an excellent set of defaults.
226 # This set is based on Fedora 22 %configure macro from /usr/lib/rpm/macros,
227 # and is known to work as far back as RHEL5.
228 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`"
229 # rpmbuild clears the environment, so force these settings into the
230 # rpm build configure
232 configopts="$configopts --with-make=$MAKE --with-tar=$TAR --with-zip=$ZIP"
233 elif [ $target = darwin ]
234 then
235 # On Mac OS X platforms, we install away from /usr/bin, /usr/lib
236 # and so on because of security requirements in recent versions.
238 configopts="--prefix=/usr/local --sysconfdir=/etc --localstatedir=/var"
239 elif [ $target = netbsd ]
240 then
241 # Try to mimic where pkgsrc/pkgin place things
243 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"
244 elif [ $target = freebsd ]
245 then
246 # Python build does not work on FreeBSD 9.3, so skip it
248 case `uname -r`
250 9.3*)
251 # Bog-standard, just without python
253 configopts="--prefix=/usr --sysconfdir=/etc --localstatedir=/var --with-python=no --with-python3=no"
256 # Bog-standard, as below ...
258 configopts="--prefix=/usr --sysconfdir=/etc --localstatedir=/var"
260 esac
261 else
262 # Bog-standard options suitable for a package on any platform.
263 # Command line can be used to extend this set, and any unusual
264 # platform-specific requirements are also appended later on.
265 configopts="--prefix=/usr --sysconfdir=/etc --localstatedir=/var"
268 # Platform-specific variants ...
270 case "$target"
272 mingw|mingw64|windows)
273 target=mingw
274 dorpm=false
275 configopts="$configopts --disable-ssp"
276 export configure="/usr/bin/mingw64-configure"
277 export MAKE="/usr/bin/mingw64-make"
278 export QMAKE="/usr/bin/mingw64-qmake-qt4"
279 export PKG_CONFIG="/usr/bin/mingw64-pkg-config"
281 linux)
282 ARCH=`uname -m`
283 [ -f /etc/slackware-version -a "$ARCH" = x86_64 ] && configopts="$configopts --libdir=/usr/lib64"
285 sunos|SunOS)
286 ARCH=`isainfo -k`
287 [ "$ARCH" = amd64 -o "$ARCH" = sparcv9 ] && configopts="$configopts --libdir=/usr/lib/64"
288 export YACC=bison
289 export LEX=flex
291 esac
293 # now some specific QA/development hosts with special needs ...
295 case `hostname`
297 vm11|vm11.localdomain)
298 # gcc -O2 is broken here (for the linux PMDA)
300 configopts="$configopts --with-optimization=no"
301 # over-ride the settings from dpkg-buildflags
303 export DEB_CFLAGS_SET=''
304 export DEB_CXXFLAGS_SET=''
306 esac
308 # and finally add in any from the command line
310 [ -n "$cmdline_configopts" ] && configopts="$configopts $cmdline_configopts"
312 . ./VERSION.pcp
313 VERSION=${PACKAGE_MAJOR}.${PACKAGE_MINOR}.${PACKAGE_REVISION}
315 LOGDIR=$topdir/Logs
316 rm -rf "$LOGDIR"
317 mkdir -p "$LOGDIR"
319 source=pcp-${VERSION}
320 SRCDIR="$topdir/$source"
321 SRCTREE="$topdir/$source"
322 SRCTAR=$topdir/build/tar/$source.src.tar.gz
324 build_failure()
326 # only print in non-verbose mode, otherwise we see double
327 if ! $verbose ; then
328 echo $@ failed, see log in $LOGDIR/pcp
329 tail $LOGDIR/pcp
331 exit 1
334 clean_packaging()
336 echo
337 echo "== Cleaning build tree for packaging build"
338 rm -rf "$SRCDIR" "$SRCTAR" .gitcensus
341 fix_version()
343 if [ -f "$1" -a -f "$2" ]
344 then
345 # as expected, both present
346 if diff "$1" "$2" >/dev/null 2>&1
347 then
349 else
350 # must be using git-archive(1) and VERSION.pcp has been
351 # modified, e.g. by pcp-daily script ... use the modified
352 # one to bump the build number in the packages
354 cp "$1" "$2"
356 else
357 echo "Arrgh ... expect both these to exist ..."
358 ls -l "$1" "$2"
359 exit 1
363 # Check web applications from external repositories are available to
364 # be included with the PCP packages.
366 prepare_webapps()
368 pass=true
370 if $webapps
371 then
372 for APP in vector grafana graphite blinkenlights
374 SRC="$topdir/build/tar/pcp-webapp-$APP.tar.gz"
375 if [ ! -f "$SRC" ]
376 then
377 https="https://github.com/performancecopilot"
378 echo "== Download to $SRC using:"
379 echo $https/pcp-webapp-$APP/archive/N.V.R/pcp-webapp-$APP-N.V.R.tar.gz
380 pass=false
382 done
385 $pass || exit 1
388 # Generate a list of all the files git knows about, create the
389 # source tarball and then unpack it. We'll then do the package
390 # build in a guaranteed pristine environment.
392 src_tar_build()
394 if [ -z "$TAR" -o ! -z "$USE_GIT_ARCHIVE" ]
395 then
396 # no suitable GNU tar is available, use git-archive(1) - no local changes
397 if git status -s src man | grep '^.M'
398 then
399 echo "Arrgh, modified src files and either no tar ($TAR) or no --transform"
400 echo "support in tar, so local changes would not be included in the build."
401 exit 1
403 git archive --format=tar --prefix=$source/ HEAD | $ZIP > $SRCTAR
404 else
405 # build git file list and make tarball by hand to pick up any changes
407 git ls-files > .gitcensus
409 # but first ensure a "build everything" debian/control has been
410 # recreated
412 cd debian
413 if ./pre-build
414 then
416 else
417 echo "Error: debian/pre-build failed when creating debian/control"
418 exit 1
420 cd ..
421 echo "debian/control" >> .gitcensus
423 $TAR -cz --transform="s,^,$source/," --files-from=.gitcensus \
424 --file=$SRCTAR
425 rm .gitcensus
427 echo "Wrote: $SRCTAR"
430 # On sanity checks :- this is sick, but I'm really tired of QA failing
431 # because of bad binaries being built from the Debian/Ubuntu toolchain
432 # for # i?86 platforms
433 # - Ken McDonell Apr 2010
435 sanity_check_settings()
437 OPT=false
438 ARCH=`uname -m | sed -e 's/i.86/ia32/'`
439 if [ "$ARCH" != "ia32" ]
440 then
441 OPT=true # no workarounds needed for non-i?86 platforms
442 elif [ -f /etc/lsb-release ]
443 then
444 if grep -q 'DISTRIB_ID=Ubuntu' /etc/lsb-release
445 then
446 eval `grep DISTRIB_RELEASE= /etc/lsb-release`
447 XDISTRIB_RELEASE=`echo $DISTRIB_RELEASE | sed -e 's/[^0-9]//g'`
448 [ -z "$XDISTRIB_RELEASE" ] && XDISTRIB_RELEASE=0000
449 if [ $XDISTRIB_RELEASE -gt 1110 ]
450 then
451 # Hope the problem is fixed after Ubuntu 11.10
452 OPT=true
455 $OPT || echo "Building without optimization for Ubuntu $DISTRIB_RELEASE"
456 elif [ -f /etc/debian_version ]
457 then
458 DISTRIB_RELEASE=`cat /etc/debian_version`
459 XDISTRIB_RELEASE=`echo $DISTRIB_RELEASE | sed -e 's/[^0-9]//g'`
460 [ -z "$XDISTRIB_RELEASE" ] && XDISTRIB_RELEASE=0000
461 if [ $XDISTRIB_RELEASE -ge 700 ]
462 then
463 # Hope the problem is fixed in Debian 7.0.0
464 OPT=true
466 $OPT || echo "Building without optimization for Debian $DISTRIB_RELEASE"
469 if ! $OPT
470 then
471 ok=true
472 if grep -q '^my $default_flags .*O2' /usr/bin/dpkg-buildpackage
473 then
474 echo 'dpkg-buildpackage: need to remove O2 from $default_flags'
475 ok=false
477 if grep -q '^[ ]*LDFLAGS.*-Bsymbolic-functions' /usr/bin/dpkg-buildpackage
478 then
479 echo 'dpkg-buildpackage: need to remove -Bsymbolic-function from LDFLAGS'
480 ok=false
482 if ! $ok
483 then
484 echo "Refer to Debian/Ubuntu notes in PCP's ./INSTALL"
485 exit 1
487 # as of Debian 6.0.1 and Ubuntu 10.10, build flags are hidden and
488 # extracted using dpkg-buildflags which fortunately honours some
489 # environment variable settings
491 export DEB_CFLAGS_SET=''
492 export DEB_CXXFLAGS_SET=''
493 export DEB_LDFLAGS_SET=''
497 # Build Debian packages using the dpkg-buildpackage utility which runs
498 # the complete build, from configure through to final deb preparation.
500 debian_buildpackage()
502 echo
503 echo "== Building deb packages using dpkg-buildpackage"
505 SUDO=${SUDO:-fakeroot}
506 # don't sign by default
507 sign='-us -uc'
508 # sign if --signed and $DEB_SIGN_KEYID set in the environment
509 # (always for an upload to Debian servers so its source only)
510 $signed && [ -n "$DEB_SIGN_KEYID" ] && sign='-S'
511 rm -f $tmp/failed
512 if $verbose ; then
513 (dpkg-buildpackage $sign -r$SUDO || touch $tmp/failed) 2>&1 | tee -a $LOGDIR/pcp
514 else
515 (dpkg-buildpackage $sign -r$SUDO || touch $tmp/failed) >>$LOGDIR/pcp 2>&1
517 [ -f $tmp/failed ] && build_failure debian buildpackage
520 prepare_debian_sources()
522 # shortcut for dpkg-buildpackage which does everything itself from here
523 rm -rf "$SRCDIR"
524 mkdir -p "$SRCDIR" 2>/dev/null
526 cd "$SRCDIR" || exit 1
527 $TAR -zxf "$SRCTAR" || exit 1
529 cd "$SRCTREE" || exit 1
530 prepare_webapps
532 fix_version ${topdir}/VERSION.pcp VERSION.pcp
535 prepare_debian_control()
537 echo
538 echo "== Preparing source tree for dpkg-buildpackage"
539 rm -f $tmp/failed debian/control
540 if $verbose ; then
541 ($MAKE -C debian control 2>&1 || touch $tmp/failed) 2>&1 | tee -a $LOGDIR/pcp
542 else
543 ($MAKE -C debian control 2>&1 || touch $tmp/failed) >>$LOGDIR/pcp 2>&1
545 [ -f $tmp/failed ] && build_failure debian control
548 debian_build()
550 SRCDIR="${topdir}/build/deb"
551 SRCTREE="${topdir}/build/deb/$source"
552 prepare_debian_sources
554 # Note: we need to run configure here to get things like builddefs
555 # created, but configure will be run _again_ from
556 # debian_buildpackage, but we need to make sure the same
557 # configure options are used in both places
559 export configure_opts="$configopts"
560 if [ ! -f debian/rules ]
561 then
562 echo "Botch: cannot find debian/rules"
563 exit 1
565 debian_opts=`sed -n <debian/rules -e '/^configure_paths/s/^[^=]*= *//p'`
566 if [ -z "$debian_opts" ]
567 then
568 echo "Botch: cannot get config options from configure_paths in debian/rules"
569 exit 1
571 configopts="$debian_opts $configopts"
572 configure_pcp
573 prepare_debian_control
574 sanity_check_settings
575 debian_buildpackage
577 # success!
578 if ! $verbose ; then
579 grep ^dpkg-deb $LOGDIR/pcp | \
580 sed -e 's,\.$,,g' -e "s,',,g" -e "s,\.\.,$topdir/build/deb,g" | \
581 awk '{ print "Wrote:", $NF }'
583 exit 0
586 prepare_build()
588 echo
589 echo "== Preparing fresh build tree for packaging build"
591 if [ ! -d "$SRCDIR" ]; then
592 # extract gzipped tar archive
593 $TAR -xz --file="$SRCTAR" || exit 1
594 fix_version VERSION.pcp $SRCDIR/VERSION.pcp
598 configure_pcp()
600 echo
601 echo "== Configuring pcp, log is in $LOGDIR/pcp ($configopts)"
603 rm -f $tmp/failed
604 if $verbose
605 then
606 ($configure $configopts 2>&1 || touch $tmp/failed) 2>&1 | tee -a $LOGDIR/pcp
607 else
608 ($configure $configopts 2>&1 || touch $tmp/failed) >>$LOGDIR/pcp 2>&1
610 [ -f $tmp/failed ] && build_failure Configure
613 default_build()
615 echo
616 echo "== Building pcp, log is in $LOGDIR/pcp"
618 rm -f $tmp/failed
619 if $verbose ; then
620 ($MAKE default_pcp 2>&1 || touch $tmp/failed) 2>&1 | tee -a $LOGDIR/pcp
621 else
622 ($MAKE default_pcp 2>&1 || touch $tmp/failed) >>$LOGDIR/pcp 2>&1
624 [ -f $tmp/failed ] && build_failure Make default_pcp
627 packaging_pcp()
629 echo
630 echo "== Packaging pcp, log is in $LOGDIR/pcp" | tee -a $LOGDIR/pcp
632 rm -f $tmp/failed
633 if $verbose ; then
634 ($MAKE -C build pack_pcp 2>&1 || touch $tmp/failed) 2>&1 | tee -a $LOGDIR/pcp
635 else
636 ($MAKE -C build pack_pcp 2>&1 || touch $tmp/failed) >>$LOGDIR/pcp 2>&1
638 [ -f $tmp/failed ] && build_failure Packaging via pack_pcp
641 packaging_rpm()
643 echo
644 echo "== Building rpm packages, log is in $LOGDIR/pcp" | tee -a $LOGDIR/pcp
646 rm -f $tmp/failed
647 export DIST_ROOT=${topdir}/build/rpm/${source}
648 # sign if --signed and $RPM_SIGN_KEYID set in the environment
649 $signed && [ -z "$RPM_SIGN_KEYID" ] && unset RPM_SIGN_KEYID
650 if $verbose ; then
651 ($MAKE -C build/rpm pack_pcp 2>&1 || touch $tmp/failed) 2>&1 | tee -a $LOGDIR/pcp
652 else
653 ($MAKE -C build/rpm pack_pcp 2>&1 || touch $tmp/failed) >>$LOGDIR/pcp 2>&1
655 [ -f $tmp/failed ] && build_failure Packaging RPMs via pack_pcp
658 packaging_docker()
660 echo
661 echo "== Building docker container images, log is in $LOGDIR/pcp" | tee -a $LOGDIR/pcp
662 rm -f $tmp/failed
664 if docker version >/dev/null 2>&1; then
665 v=`docker version | sed -e 's/\./ /g' | \
666 awk '/^Server/ {s=1; if($2 == "version:") {print 10*$3+$4; exit}}
667 /Version:/ {if (s) {print 10*$2+$3; exit}}'`
668 if [ -z "$v" -o "$v" -lt 14 ]; then
669 echo 'Error: docker version too old. Containers build skipped.'
670 touch $tmp/failed
672 else
673 echo 'Error: docker not enabled or not properly configured for non-root access.'
674 echo 'Check the docker service is enabled and running. You can allow non-root access'
675 echo 'as follows: edit /etc/sysconfig/docker and add OPTIONS="-G gid" where gid is a'
676 echo 'group name that you are a member of. Then restart the docker service.'
677 touch $tmp/failed
680 [ -f $tmp/failed ] && build_failure Packaging docker images, docker configuration
682 if $verbose ; then
683 ($MAKE -C build/containers pack_pcp 2>&1 || touch $tmp/failed) 2>&1 | tee -a $LOGDIR/pcp
684 else
685 ($MAKE -C build/containers pack_pcp 2>&1 || touch $tmp/failed) >>$LOGDIR/pcp 2>&1
688 [ -f $tmp/failed ] && build_failure Packaging docker containers via pack_pcp
691 # real build starts here
692 clean_packaging
693 src_tar_build
694 $srconly && exit 0
696 # short-circuit for performing builds with dpkg-buildpackage
697 $dodeb && debian_build
699 prepare_build
701 # check for requested web application sources we're packaging
702 prepare_webapps
704 # shift into the clean packaging build tree from here onward
705 cd "$SRCDIR"
707 configure_pcp
709 # short-circuit for performing rpm-only builds with rpmbuild
710 # (skips over the default_build stage as rpmbuild does that).
711 if $dorpm
712 then
713 packaging_rpm
714 else
715 default_build # perform a complete build in-situ
716 packaging_pcp # create all known package formats
720 # --with-docker, currently only for RPM platforms with docker
721 if $docker
722 then
723 packaging_docker
726 # success!
727 if ! $verbose ; then
728 grep '^Wrote:' $LOGDIR/pcp | sed -e 's/\.\.\/\.\.\///'
730 exit 0