From 6de5e130a91dd8589c0b74264a49a4b8064280cc Mon Sep 17 00:00:00 2001 From: David McBride Date: Sun, 8 Feb 2015 18:41:18 +0000 Subject: [PATCH 1/7] Add support for building Ceph with compilers other than GCC. Modify the various build-script variants to use CC and CXX, rather than asuming the use of gcc and g++ --- though they will still use these by default if no other compiler is specified. --- build-ceph-deb-native.sh | 12 +++++++++++- build-ceph-deb.sh | 11 ++++++++++- build-ceph-gcov.sh | 12 +++++++++++- build-ceph-notcmalloc.sh | 11 ++++++++++- build-ceph-rpm.sh | 12 +++++++++++- build-ceph.sh | 12 +++++++++++- 6 files changed, 64 insertions(+), 6 deletions(-) diff --git a/build-ceph-deb-native.sh b/build-ceph-deb-native.sh index d99d73f..35762f1 100755 --- a/build-ceph-deb-native.sh +++ b/build-ceph-deb-native.sh @@ -18,6 +18,16 @@ rm -rf .git/modules/ /srv/git/bin/git submodule update --init git clean -fdx +# If CC is not already defined, use gcc. +if [ "x$CC" = "x" ]; then + export CC=gcc +fi + +# If CXX is not already defined, use g++. +if [ "x$CXX" = "x" ]; then + export CXX=g++ +fi + DIST=`lsb_release -sc` echo --START-IGNORE-WARNINGS @@ -42,7 +52,7 @@ if command -v ccache >/dev/null; then if [ ! -e "$CCACHE_DIR" ]; then echo "$0: have ccache but cache directory does not exist: $CCACHE_DIR" 1>&2 else - set -- CC='ccache gcc' CXX='ccache g++' + set -- CC="ccache $CC" CXX="ccache $CXX" fi else echo "$0: no ccache found, compiles will be slower." 1>&2 diff --git a/build-ceph-deb.sh b/build-ceph-deb.sh index ef5b7d0..e507528 100755 --- a/build-ceph-deb.sh +++ b/build-ceph-deb.sh @@ -18,6 +18,15 @@ rm -rf .git/modules/ /srv/git/bin/git submodule update --init git clean -fdx +# If CC is not already defined, use gcc. +if [ "x$CC" = "x" ]; then + export CC=gcc +fi + +# If CXX is not already defined, use g++. +if [ "x$CXX" = "x" ]; then + export CXX=g++ +fi DISTS=`cat ../../dists` @@ -43,7 +52,7 @@ if command -v ccache >/dev/null; then if [ ! -e "$CCACHE_DIR" ]; then echo "$0: have ccache but cache directory does not exist: $CCACHE_DIR" 1>&2 else - set -- CC='ccache gcc' CXX='ccache g++' + set -- CC="ccache $CC" CXX="ccache $CXX" fi else echo "$0: no ccache found, compiles will be slower." 1>&2 diff --git a/build-ceph-gcov.sh b/build-ceph-gcov.sh index f3f7ea4..bcd5527 100755 --- a/build-ceph-gcov.sh +++ b/build-ceph-gcov.sh @@ -19,6 +19,16 @@ rm -rf .git/modules/ /srv/git/bin/git submodule update --init git clean -fdx +# If CC is not already defined, use gcc. +if [ "x$CC" = "x" ]; then + export CC=gcc +fi + +# If CXX is not already defined, use g++. +if [ "x$CXX" = "x" ]; then + export CXX=g++ +fi + echo --START-IGNORE-WARNINGS [ ! -x autogen.sh ] || ./autogen.sh || exit 1 autoconf || true @@ -41,7 +51,7 @@ if command -v ccache >/dev/null; then if [ ! -e "$CCACHE_DIR" ]; then echo "$0: have ccache but cache directory does not exist: $CCACHE_DIR" 1>&2 else - set -- CC='ccache gcc' CXX='ccache g++' + set -- CC="ccache $CC" CXX="ccache $CXX" fi else echo "$0: no ccache found, compiles will be slower." 1>&2 diff --git a/build-ceph-notcmalloc.sh b/build-ceph-notcmalloc.sh index 107f2b8..76d829d 100755 --- a/build-ceph-notcmalloc.sh +++ b/build-ceph-notcmalloc.sh @@ -19,6 +19,15 @@ rm -rf .git/modules/ /srv/git/bin/git submodule update --init git clean -fdx +# If CC is not already defined, use gcc. +if [ "x$CC" = "x" ]; then + export CC=gcc +fi + +# If CXX is not already defined, use g++. +if [ "x$CXX" = "x" ]; then + export CXX=g++ +fi echo --START-IGNORE-WARNINGS [ ! -x autogen.sh ] || ./autogen.sh || exit 1 @@ -42,7 +51,7 @@ if command -v ccache >/dev/null; then if [ ! -e "$CCACHE_DIR" ]; then echo "$0: have ccache but cache directory does not exist: $CCACHE_DIR" 1>&2 else - set -- CC='ccache gcc' CXX='ccache g++' + set -- CC="ccache $CC" CXX="ccache $CXX" fi else echo "$0: no ccache found, compiles will be slower." 1>&2 diff --git a/build-ceph-rpm.sh b/build-ceph-rpm.sh index 5a5fea3..fd74333 100755 --- a/build-ceph-rpm.sh +++ b/build-ceph-rpm.sh @@ -18,6 +18,16 @@ rm -rf .git/modules/ /srv/git/bin/git submodule update --init git clean -fdx +# If CC is not already defined, use gcc. +if [ "x$CC" = "x" ]; then + export CC=gcc +fi + +# If CXX is not already defined, use g++. +if [ "x$CXX" = "x" ]; then + export CXX=g++ +fi + DISTS=`cat ../../dists` TARGET="$(cat ../../rsync-target)" TARGET="$(basename $TARGET)" @@ -67,7 +77,7 @@ if command -v ccache >/dev/null; then if [ ! -e "$CCACHE_DIR" ]; then echo "$0: have ccache but cache directory does not exist: $CCACHE_DIR" 1>&2 else - set -- CC='ccache gcc' CXX='ccache g++' + set -- CC="ccache $CC" CXX="ccache $CXX" fi else echo "$0: no ccache found, compiles will be slower." 1>&2 diff --git a/build-ceph.sh b/build-ceph.sh index 44789d9..de578ff 100755 --- a/build-ceph.sh +++ b/build-ceph.sh @@ -18,6 +18,16 @@ rm -rf .git/modules/ /srv/git/bin/git submodule update --init git clean -fdx +# If CC is not already defined, use gcc. +if [ "x$CC" = "x" ]; then + export CC=gcc +fi + +# If CXX is not already defined, use g++. +if [ "x$CXX" = "x" ]; then + export CXX=g++ +fi + echo --START-IGNORE-WARNINGS [ ! -x autogen.sh ] || ./autogen.sh || exit 1 autoconf || true @@ -40,7 +50,7 @@ if command -v ccache >/dev/null; then if [ ! -e "$CCACHE_DIR" ]; then echo "$0: have ccache but cache directory does not exist: $CCACHE_DIR" 1>&2 else - set -- CC='ccache gcc' CXX='ccache g++' + set -- CC="ccache $CC" CXX="ccache $CXX" fi else echo "$0: no ccache found, compiles will be slower." 1>&2 From 5b927ce1a2f7d253c48f33827756b2b27292ff5e Mon Sep 17 00:00:00 2001 From: David McBride Date: Sun, 8 Feb 2015 18:43:05 +0000 Subject: [PATCH 2/7] Add '-clang' build-option to build-auto.sh. If the auto-builder's hostname contains '-clang', then build Ceph using the clang and clang++ compilers, rather than using the default. --- build-auto.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/build-auto.sh b/build-auto.sh index 7666066..137547e 100755 --- a/build-auto.sh +++ b/build-auto.sh @@ -9,6 +9,12 @@ if ! hostname | grep -q ^gitbuilder- ; then exit 1 fi +if hostname | grep -q -- -clang ; then + echo "hostname has -clang, will build with CC=clang CXX=clang++" + export CC=clang + export CXX=clang++ +fi + if hostname | grep -q -- -notcmalloc ; then echo "hostname has -notcmalloc, will build --without-tcmalloc --without-cryptopp" export CEPH_EXTRA_CONFIGURE_ARGS="$CEPH_EXTRA_CONFIGURE_ARGS --without-tcmalloc" From 0259133f2851f1b68ac85d6c29c91e88cd991138 Mon Sep 17 00:00:00 2001 From: David McBride Date: Sun, 8 Feb 2015 19:08:06 +0000 Subject: [PATCH 3/7] Prepend to rather than replace CFLAGS and CXXFLAGS. Rather than replace the definitions of CFLAGS and CXXFLAGS when calling configure, instead prepend to those variables. This allows use to later define CFLAGS and CXXFLAGS values in the calling environment. --- build-ceph-deb-native.sh | 2 +- build-ceph-notcmalloc.sh | 2 +- build-ceph.sh | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build-ceph-deb-native.sh b/build-ceph-deb-native.sh index 35762f1..d66b270 100755 --- a/build-ceph-deb-native.sh +++ b/build-ceph-deb-native.sh @@ -34,7 +34,7 @@ echo --START-IGNORE-WARNINGS [ ! -x autogen.sh ] || ./autogen.sh || exit 1 autoconf || true echo --STOP-IGNORE-WARNINGS -[ ! -x configure ] || CFLAGS="-fno-omit-frame-pointer -g -O2" CXXFLAGS="-fno-omit-frame-pointer -g -O2" ./configure --with-debug --with-radosgw --with-fuse --with-tcmalloc --with-libatomic-ops --with-gtk2 --with-profiler --enable-cephfs-java || exit 2 +[ ! -x configure ] || CFLAGS="-fno-omit-frame-pointer -g -O2 $CFLAGS" CXXFLAGS="-fno-omit-frame-pointer -g -O2 $CXXFLAGS" ./configure --with-debug --with-radosgw --with-fuse --with-tcmalloc --with-libatomic-ops --with-gtk2 --with-profiler --enable-cephfs-java || exit 2 if [ ! -e Makefile ]; then echo "$0: no Makefile, aborting." 1>&2 diff --git a/build-ceph-notcmalloc.sh b/build-ceph-notcmalloc.sh index 76d829d..5ed1e32 100755 --- a/build-ceph-notcmalloc.sh +++ b/build-ceph-notcmalloc.sh @@ -33,7 +33,7 @@ echo --START-IGNORE-WARNINGS [ ! -x autogen.sh ] || ./autogen.sh || exit 1 autoconf || true echo --STOP-IGNORE-WARNINGS -[ ! -x configure ] || CFLAGS="-fno-omit-frame-pointer -g -O2" CXXFLAGS="-fno-omit-frame-pointer -g" ./configure --with-debug --with-radosgw --with-fuse --without-tcmalloc --with-libatomic-ops --with-gtk2 --with-profiler || exit 2 +[ ! -x configure ] || CFLAGS="-fno-omit-frame-pointer -g -O2 $CFLAGS" CXXFLAGS="-fno-omit-frame-pointer -g $CXXFLAGS" ./configure --with-debug --with-radosgw --with-fuse --without-tcmalloc --with-libatomic-ops --with-gtk2 --with-profiler || exit 2 if [ ! -e Makefile ]; then echo "$0: no Makefile, aborting." 1>&2 diff --git a/build-ceph.sh b/build-ceph.sh index de578ff..2896eb8 100755 --- a/build-ceph.sh +++ b/build-ceph.sh @@ -32,7 +32,7 @@ echo --START-IGNORE-WARNINGS [ ! -x autogen.sh ] || ./autogen.sh || exit 1 autoconf || true echo --STOP-IGNORE-WARNINGS -[ ! -x configure ] || CFLAGS="-fno-omit-frame-pointer -g -O2" CXXFLAGS="-fno-omit-frame-pointer -g" ./configure --with-debug --with-radosgw --with-fuse --with-tcmalloc --with-libatomic-ops --with-gtk2 --with-hadoop --with-profiler --enable-cephfs-java --with-librocksdb-static=check || exit 2 +[ ! -x configure ] || CFLAGS="-fno-omit-frame-pointer -g -O2 $CFLAGS" CXXFLAGS="-fno-omit-frame-pointer -g $CXXFLAGS" ./configure --with-debug --with-radosgw --with-fuse --with-tcmalloc --with-libatomic-ops --with-gtk2 --with-hadoop --with-profiler --enable-cephfs-java --with-librocksdb-static=check || exit 2 if [ ! -e Makefile ]; then echo "$0: no Makefile, aborting." 1>&2 From a541815e8bbbc046a19c9d8717a3f9878b5f786f Mon Sep 17 00:00:00 2001 From: David McBride Date: Sun, 8 Feb 2015 19:11:31 +0000 Subject: [PATCH 4/7] Add '-asan', '-tsan', '-wall' hostname-keyed options. Update build-auto.sh to check the hostname for additional elements: -asan: Enable AddressSanitizer in subsequent compilations, which introduces extra safety-features at program run-time. -tsan: Enable ThreadSanitizer in subsequent compilations, which introduces extra safety-features at program run-time. -wall: Enable -Wall, -Wpedantic, -Weverything flags in subsequent compilations. Note that, at least as of clang-3.5, the AddressSanitizer and ThreadSanitizer options are mutually incompatible. At time of writing, Ceph fails to build with -Wall -Wpedantic -Weverthing flags defined part-way through compiling rocksdb, because -Werror is also defined at that point. (Of course, subsequent compilation errors may well, and even are likely, to occur; this is just the first one we hit.) --- build-auto.sh | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/build-auto.sh b/build-auto.sh index 137547e..5736642 100755 --- a/build-auto.sh +++ b/build-auto.sh @@ -14,7 +14,21 @@ if hostname | grep -q -- -clang ; then export CC=clang export CXX=clang++ fi - +if hostname | grep -q -- -asan; then + echo "hostname has -asan, will build with -fsanitize=address" + export CFLAGS="-fsanitize=address $CFLAGS" + export CXXFLAGS="-fsanitize=address $CXXFLAGS" +fi +if hostname | grep -q -- -tsan; then + echo "hostname has -tsan, will build with -fsanitize=thread" + export CFLAGS="-fsanitize=thread $CFLAGS" + export CXXFLAGS="-fsanitize=thread $CXXFLAGS" +fi +if hostname | grep -q -- -wall; then + echo "hostname has -wall, will build with all possible warnings enabled" + export CFLAGS="-Wall -Weverything -Wpedantic $CFLAGS" + export CXXFLAGS="-Wall -Weverything -Wpedantic $CXXFLAGS" +fi if hostname | grep -q -- -notcmalloc ; then echo "hostname has -notcmalloc, will build --without-tcmalloc --without-cryptopp" export CEPH_EXTRA_CONFIGURE_ARGS="$CEPH_EXTRA_CONFIGURE_ARGS --without-tcmalloc" From e522cfaf3721e33895d942099a1229cffdb0ffc3 Mon Sep 17 00:00:00 2001 From: David McBride Date: Mon, 9 Feb 2015 09:30:27 +0000 Subject: [PATCH 5/7] Minimise unwanted interactions between clang and distcc. Clang and distcc (particulrly versions of distcc < 3.2) interact in some undesirable ways: Specifically, clang (with all warnings enabled) can generate spurious warnings (or errors, if -Werror is defined)! that are the result of preprocessing files and compiling in separate stages. Work around by exporting 'CCACHE_CPP2=yes' and definding '-Qunused-arguments' in CFLAGS and CXXFLAGS. See for further discussion: http://petereisentraut.blogspot.co.uk/2011/05/ccache-and-clang.html * --- build-auto.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/build-auto.sh b/build-auto.sh index 5736642..8147068 100755 --- a/build-auto.sh +++ b/build-auto.sh @@ -13,6 +13,10 @@ if hostname | grep -q -- -clang ; then echo "hostname has -clang, will build with CC=clang CXX=clang++" export CC=clang export CXX=clang++ + # Workaround nfortunate interactions between clang and distcc < 3.2. + export CCACHE_CPP2=yes + export CFLAGS="-Qunused-arguments $CFLAGS" + export CXXFLAGS="-Qunused-arguments $CXXFLAXS" fi if hostname | grep -q -- -asan; then echo "hostname has -asan, will build with -fsanitize=address" From 6619e29653c9cd5aa9cbafdfa928e4745b8f40cd Mon Sep 17 00:00:00 2001 From: David McBride Date: Mon, 9 Feb 2015 09:46:09 +0000 Subject: [PATCH 6/7] Add 'clang' to fabfile that governs autobuilder provisioning. Add 'clang' (and, on Redhat machines, 'clang-analyzer') to the set of packages to provision. --- fabfile.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fabfile.py b/fabfile.py index ffc553f..a56eb85 100644 --- a/fabfile.py +++ b/fabfile.py @@ -164,6 +164,8 @@ def _rh_gitbuilder(flavor, git_repo, extra_remotes={}, extra_packages=[], ignore _rpm_install( 'ntp', 'ccache', + 'clang', + 'clang-analyzer', 'git', 'logrotate', 'rsync', @@ -282,6 +284,7 @@ def _gitbuilder(flavor, git_repo, extra_remotes={}, extra_packages=[], ignore=[] 'ntp', 'build-essential', 'ccache', + 'clang', 'git', 'logrotate', # 'sun-java6-jdk', From 908dfb591333a8c90cc23aa7f1ceac02cb47d17f Mon Sep 17 00:00:00 2001 From: David McBride Date: Mon, 9 Feb 2015 10:17:43 +0000 Subject: [PATCH 7/7] Add support for building with Clang's static-analyzer. Add support for wrapping the top-level 'make' invocation with the contents of the BUILD_WRAPPER environment variable, and define this variable on hosts with the -analyze suffix present. Also disable the use of CCACHE in this case; it seems likely that these two facilities might interact poorly. This might be overly conservative, however. Note that while the static-analyzer is part of the clang project, its use does not imply that compilation must use clang; hence if you wish to both static-analyze and build Ceph with clang, then both the -analyze and -clang hostname suffixes are required. --- build-auto.sh | 6 ++++++ build-ceph-gcov.sh | 2 +- build-ceph-notcmalloc.sh | 2 +- build-ceph.sh | 2 +- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/build-auto.sh b/build-auto.sh index 8147068..1e27c3a 100755 --- a/build-auto.sh +++ b/build-auto.sh @@ -18,6 +18,12 @@ if hostname | grep -q -- -clang ; then export CFLAGS="-Qunused-arguments $CFLAGS" export CXXFLAGS="-Qunused-arguments $CXXFLAXS" fi +if hostname | grep -q -- -analyze ; then + echo "hostname has -analyze, will wrap build with scan-build static analyzer" + echo "Disabling CCache to ensure complete coverage." + export CCACHE_DISABLE=yes + export BUILD_WRAPPER="scan-build -o scan-build-report.tmp/" +fi if hostname | grep -q -- -asan; then echo "hostname has -asan, will build with -fsanitize=address" export CFLAGS="-fsanitize=address $CFLAGS" diff --git a/build-ceph-gcov.sh b/build-ceph-gcov.sh index bcd5527..f4892ed 100755 --- a/build-ceph-gcov.sh +++ b/build-ceph-gcov.sh @@ -58,7 +58,7 @@ else fi NCPU=$(( 2 * `grep -c processor /proc/cpuinfo` )) -ionice -c3 nice -n20 make -j$NCPU "$@" || exit 4 +ionice -c3 nice -n20 $BUILD_WRAPPER make -j$NCPU "$@" || exit 4 # The "make -q check" probe in build.sh.example is faulty in that # screwups in Makefiles make it think there are no unit tests to diff --git a/build-ceph-notcmalloc.sh b/build-ceph-notcmalloc.sh index 5ed1e32..f397b24 100755 --- a/build-ceph-notcmalloc.sh +++ b/build-ceph-notcmalloc.sh @@ -58,7 +58,7 @@ else fi NCPU=$(( 2 * `grep -c processor /proc/cpuinfo` )) -ionice -c3 nice -n20 make -j$NCPU "$@" || exit 4 +ionice -c3 nice -n20 $BUILD_WRAPPER make -j$NCPU "$@" || exit 4 # The "make -q check" probe in build.sh.example is faulty in that # screwups in Makefiles make it think there are no unit tests to diff --git a/build-ceph.sh b/build-ceph.sh index 2896eb8..e150629 100755 --- a/build-ceph.sh +++ b/build-ceph.sh @@ -57,7 +57,7 @@ else fi NCPU=$(( 2 * `grep -c processor /proc/cpuinfo` )) -ionice -c3 nice -n20 make -j$NCPU "$@" || exit 4 +ionice -c3 nice -n20 $BUILD_WRAPPER make -j$NCPU "$@" || exit 4 # The "make -q check" probe in build.sh.example is faulty in that # screwups in Makefiles make it think there are no unit tests to