diff --git a/.gitignore b/.gitignore index cc80f96..43de779 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ /config.status /config.sub /configure +/cov /depcomp /install-sh /libtool @@ -24,5 +25,6 @@ *.log *.o *.pc +*.profraw Makefile Makefile.in diff --git a/autogen.des b/autogen.des index baf8338..fcbddd4 100755 --- a/autogen.des +++ b/autogen.des @@ -7,19 +7,6 @@ set -ex # autoconf prior to 2.62 has issues with zsh 4.2 and newer export CONFIG_SHELL=/bin/sh -# BullseyeCoverage needs to know exactly which compiler we're using -if [ -z "$CC" -a -z "$CPP" -a -z "$CXX" ] ; then - if $(which clang clang++ >/dev/null) ; then - export CC=${CC:-clang} - export CPP=${CPP:-clang -E} - export CXX=${CXX:-clang++} - elif $(which gcc g++ >/dev/null) ; then - export CC=${CC:-gcc} - export CPP=${CPP:-gcc -E} - export CXX=${CXX:-g++} - fi -fi - ./configure \ --with-doc \ --with-pam-unix \ @@ -28,4 +15,5 @@ fi --enable-debug \ --enable-developer-warnings \ --enable-werror \ + --enable-code-coverage \ "$@" diff --git a/configure.ac b/configure.ac index aa5f0e8..65a08dd 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -AC_PREREQ([2.62]) +AC_PREREQ([2.69]) AC_INIT([OpenPAM], [trunk], [des@des.no], [openpam], [https://openpam.org/]) AC_CONFIG_SRCDIR([lib/libpam/pam_start.c]) AC_CONFIG_MACRO_DIR([m4]) @@ -7,13 +7,15 @@ AM_CONFIG_HEADER([config.h]) # C compiler and features AC_LANG(C) -AC_PROG_CC +AC_PROG_CC([clang gcc cc]) AC_PROG_CC_STDC AC_PROG_CPP +AC_PROG_CXX([clang++ g++ c++]) AC_GNU_SOURCE AC_C_CONST AC_C_RESTRICT AC_C_VOLATILE +AX_COMPILER_VENDOR # libtool LT_PREREQ([2.2.6]) @@ -122,6 +124,21 @@ AC_ARG_ENABLE([werror], AS_HELP_STRING([--enable-werror], [use -Werror (default is NO)]), [CFLAGS="${CFLAGS} -Werror"]) +AC_ARG_ENABLE([code-coverage], + AS_HELP_STRING([--enable-code-coverage], + [enable code coverage])) +AM_CONDITIONAL([CODE_COVERAGE], [test x"$enable_code_coverage" = x"yes"]) +AS_IF([test x"$enable_code_coverage" = x"yes"], [ + AS_IF([test x"$ax_cv_c_compiler_vendor" = x"clang"], [ + CFLAGS="${CFLAGS} -fprofile-instr-generate -fcoverage-mapping" + ], [ + AC_MSG_ERROR([code coverage is only supported with clang]) + ]) + AC_DEFINE([CODE_COVERAGE], [1], [Define to 1 if code coverage is enabled]) + AC_MSG_NOTICE([code coverage enabled]) +]) +AC_SUBST([enable_code_coverage], [$enable_code_coverage]) + AC_CONFIG_FILES([ Makefile bin/Makefile diff --git a/m4/.gitignore b/m4/.gitignore index 66461ef..c6b1273 100644 --- a/m4/.gitignore +++ b/m4/.gitignore @@ -1,2 +1,3 @@ /*.m4 +!/ax_compiler_vendor.m4 !/ax_pkg_config.m4 diff --git a/m4/ax_compiler_vendor.m4 b/m4/ax_compiler_vendor.m4 new file mode 100644 index 0000000..f06e865 --- /dev/null +++ b/m4/ax_compiler_vendor.m4 @@ -0,0 +1,117 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_compiler_vendor.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_COMPILER_VENDOR +# +# DESCRIPTION +# +# Determine the vendor of the C, C++ or Fortran compiler. The vendor is +# returned in the cache variable $ax_cv_c_compiler_vendor for C, +# $ax_cv_cxx_compiler_vendor for C++ or $ax_cv_fc_compiler_vendor for +# (modern) Fortran. The value is one of "intel", "ibm", "pathscale", +# "clang" (LLVM), "cray", "fujitsu", "sdcc", "sx", "portland" (PGI), "gnu" +# (GCC), "sun" (Oracle Developer Studio), "hp", "dec", "borland", +# "comeau", "kai", "lcc", "sgi", "microsoft", "metrowerks", "watcom", +# "tcc" (Tiny CC) or "unknown" (if the compiler cannot be determined). +# +# To check for a Fortran compiler, you must first call AC_FC_PP_SRCEXT +# with an appropriate preprocessor-enabled extension. For example: +# +# AC_LANG_PUSH([Fortran]) +# AC_PROG_FC +# AC_FC_PP_SRCEXT([F]) +# AX_COMPILER_VENDOR +# AC_LANG_POP([Fortran]) +# +# LICENSE +# +# Copyright (c) 2008 Steven G. Johnson +# Copyright (c) 2008 Matteo Frigo +# Copyright (c) 2018-19 John Zaitseff +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see . +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 30 + +AC_DEFUN([AX_COMPILER_VENDOR], [dnl + AC_CACHE_CHECK([for _AC_LANG compiler vendor], ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor, [dnl + dnl If you modify this list of vendors, please add similar support + dnl to ax_compiler_version.m4 if at all possible. + dnl + dnl Note: Do NOT check for GCC first since some other compilers + dnl define __GNUC__ to remain compatible with it. Compilers that + dnl are very slow to start (such as Intel) are listed first. + + vendors=" + intel: __ICC,__ECC,__INTEL_COMPILER + ibm: __xlc__,__xlC__,__IBMC__,__IBMCPP__,__ibmxl__ + pathscale: __PATHCC__,__PATHSCALE__ + clang: __clang__ + cray: _CRAYC + fujitsu: __FUJITSU + sdcc: SDCC,__SDCC + sx: _SX + portland: __PGI + gnu: __GNUC__ + sun: __SUNPRO_C,__SUNPRO_CC,__SUNPRO_F90,__SUNPRO_F95 + hp: __HP_cc,__HP_aCC + dec: __DECC,__DECCXX,__DECC_VER,__DECCXX_VER + borland: __BORLANDC__,__CODEGEARC__,__TURBOC__ + comeau: __COMO__ + kai: __KCC + lcc: __LCC__ + sgi: __sgi,sgi + microsoft: _MSC_VER + metrowerks: __MWERKS__ + watcom: __WATCOMC__ + tcc: __TINYC__ + unknown: UNKNOWN + " + for ventest in $vendors; do + case $ventest in + *:) + vendor=$ventest + continue + ;; + *) + vencpp="defined("`echo $ventest | sed 's/,/) || defined(/g'`")" + ;; + esac + + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [[ +#if !($vencpp) + thisisanerror; +#endif + ]])], [break]) + done + + ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor=`echo $vendor | cut -d: -f1` + ]) +])dnl diff --git a/misc/coverage.sh.in b/misc/coverage.sh.in index 83c378a..5011106 100644 --- a/misc/coverage.sh.in +++ b/misc/coverage.sh.in @@ -16,18 +16,19 @@ while getopts "j:" opt ; do esac done -if ! which -s cov01 covhtml ; then - echo "coverage tools not found" >&2 +if ! [ "@enable_code_coverage@" = "yes" ] ; then + echo "Code coverage disabled." >&2 + echo "Re-run ./configure with --enable-code-coverage and try again." >&2 exit 1 fi + srcdir="@abs_top_srcdir@" -htmldir="${srcdir}/covhtml" -export COVFILE="${srcdir}/test.cov" -gmake -C "${srcdir}" clean -find "${srcdir}" -type f -name "${COVFILE##*/}" -delete -rm -rf "${htmldir}" -cov01 -1 -gmake -C "${srcdir}" $j check || exit 1 -covhtml -d "${srcdir}" -f "${COVFILE}" "${htmldir}" -cov01 -0 -gmake -C "${srcdir}" clean +profdir="@abs_top_builddir@/cov" +profraw="${profdir}/@PACKAGE@.%p.raw" +profdata="${profdir}/@PACKAGE@.profdata" +export LLVM_PROFILE_FILE="${profraw}" +[ -e "${profdir}" ] && rm -r "${profdir}" +gmake -C "${srcdir}" $j check +llvm-profdata merge -sparse "${profdir}/@PACKAGE@".*.raw -o "${profdata}" +llvm-cov show -instr-profile="${profdata}" -format=html -output-dir="${profdir}" \ + --object "@abs_top_builddir@/lib/libpam/.libs/libpam.so"