From 7f1aa5b66b247f339a9e7c25415a9a5dd272763c Mon Sep 17 00:00:00 2001 From: Timothy Day Date: Sat, 18 Feb 2023 03:49:34 +0000 Subject: [PATCH] LU-16518 build: llvm/clang support Other projects, notably Linux, have build support for LLVM and Clang via special environment variables. This is implemented for Lustre, in the style of: https://www.kernel.org/doc/html/latest/kbuild/llvm.html Instances in which GCC is explicitly called are replaced by the use of $CC. The proper environment variables as passed to make invocations as needed. All checks which influence global compiler and toolchain settings are collected in 'config/lustre-toolchain.m4'. A configure option is added to disable the strict error flags that are passes to the C compiler by default. CFLAGS and EXTRA_CFLAGS are made to work in the typical way. Having fine grained control over compiler options makes experimenting with Clang smoother. Some compile checks in 'lustre-core.m4' have been improved by using unused variables and explicitly setting the compile flag to be used during the test. This also sets the execute bit on autogen.sh. Tested with: Linux (mainline) - 5.15.94 openZFS - 2.1.99 Lustre (latest master) - 2.15.55 CentOS - 8.5 Clang (default on CentOS) - 12.0.1 Test-Parameters: trivial Signed-off-by: Timothy Day Change-Id: Ia8654c22fa8fca7bfb96c545ac144a1d3737fa00 Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/50063 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Shaun Tancheff Reviewed-by: Jian Yu Reviewed-by: James Simmons Reviewed-by: Oleg Drokin --- autogen.sh | 0 config/lustre-build-linux.m4 | 8 +- config/lustre-build.m4 | 117 ---------------------- config/lustre-toolchain.m4 | 220 +++++++++++++++++++++++++++++++++++++++++ configure.ac | 5 +- lustre/autoconf/lustre-core.m4 | 14 +-- lustre/tests/Makefile.am | 3 + 7 files changed, 236 insertions(+), 131 deletions(-) mode change 100644 => 100755 autogen.sh create mode 100644 config/lustre-toolchain.m4 diff --git a/autogen.sh b/autogen.sh old mode 100644 new mode 100755 diff --git a/config/lustre-build-linux.m4 b/config/lustre-build-linux.m4 index 1ff6c47..59e010e 100644 --- a/config/lustre-build-linux.m4 +++ b/config/lustre-build-linux.m4 @@ -422,7 +422,7 @@ LB_LINUX_VERSION # --- Parallel config for kernel v5.17+ AS_IF([test "x$lb_cv_dequote_CC_VERSION_TEXT" = "xyes"], [ - CC_VERSION_TEXT=$(gcc --version | head -n1 | tr ' ()' '.') + CC_VERSION_TEXT=$($CC --version | head -n1 | tr ' ()' '.') MAKE_KMOD_ENV="CONFIG_CC_VERSION_TEXT='$CC_VERSION_TEXT'"]) # --- check that we can build modules at all @@ -842,10 +842,10 @@ AC_DEFUN([LB2_LINUX_TEST_COMPILE], [ J=${TEST_JOBS:-$(nproc)} AC_MSG_NOTICE([Making $1 in $D]) - AC_MSG_NOTICE([KBUILD_MODPOST_NOFINAL="yes" make modules -k -j${J} -C $LINUX_OBJ $ARCH_UM M=${D} $MAKE_KMOD_ENV]) + AC_MSG_NOTICE([KBUILD_MODPOST_NOFINAL="yes" make modules CC="$CC" -k -j${J} -C $LINUX_OBJ $ARCH_UM M=${D} $MAKE_KMOD_ENV]) AC_TRY_COMMAND([KBUILD_MODPOST_NOFINAL="yes" - make modules -k -j${J} -C $LINUX_OBJ $ARCH_UM M=${D} $MAKE_KMOD_ENV >${L} 2>&1]) + make modules CC="$CC" -k -j${J} -C $LINUX_OBJ $ARCH_UM M=${D} $MAKE_KMOD_ENV >${L} 2>&1]) AS_IF([test -f ${L}], [AS_IF([test -f $2/Makefile], [mv $2/Makefile $2/Makefile.compile.$1])], @@ -928,7 +928,7 @@ AC_DEFUN([LB2_LINUX_TEST_RESULT],[ for mf in $(ls -1 ${TEST_DIR}/Makefile.compile.*); do ln -sf $mf ${D}/Makefile KBUILD_MODPOST_NOFINAL="yes" - make modules -k -j${J} -C $LINUX_OBJ $ARCH_UM M=${D} >> rebuild.log 2>&1 + make modules CC="$CC" -k -j${J} -C $LINUX_OBJ $ARCH_UM M=${D} >> rebuild.log 2>&1 for dir in $(awk '/^obj-m/ { print [$]3 }' ${D}/$mf); do name=${dir%/} diff --git a/config/lustre-build.m4 b/config/lustre-build.m4 index 9fc78586..f7d1cfd 100644 --- a/config/lustre-build.m4 +++ b/config/lustre-build.m4 @@ -337,107 +337,6 @@ LC_PATH_DEFAULTS ]) # LB_PATH_DEFAULTS # -# LB_PROG_CC -# -# checks on the C compiler -# -AC_DEFUN([LB_PROG_CC], [ -AC_PROG_RANLIB -AC_CHECK_TOOL(LD, [ld], [no]) -AC_CHECK_TOOL(OBJDUMP, [objdump], [no]) -AC_CHECK_TOOL(STRIP, [strip], [no]) - -# --------- unsigned long long sane? ------- -AC_CHECK_SIZEOF(unsigned long long, 0) -AS_IF([test $ac_cv_sizeof_unsigned_long_long != 8], - [AC_MSG_ERROR([we assume that sizeof(unsigned long long) == 8.])]) - -AS_IF([test $target_cpu = powerpc64], [ - AC_MSG_WARN([set compiler with -m64]) - CFLAGS="$CFLAGS -m64" - CC="$CC -m64" -]) - -# libcfs/include for util headers, lustre/include for liblustreapi and friends -# UAPI headers from OpenSFS are included if modules support is enabled, otherwise -# it will use the native kernel implementation. -CPPFLAGS="-I$PWD/libcfs/include -I$PWD/lnet/utils/ -I$PWD/lustre/include $CPPFLAGS" - -CCASFLAGS="-Wall -fPIC -D_GNU_SOURCE" -AC_SUBST(CCASFLAGS) - -# everyone builds against lnet and lustre kernel headers -EXTRA_KCFLAGS="$EXTRA_KCFLAGS -g -I$PWD/libcfs/include -I$PWD/libcfs/include/libcfs -I$PWD/lnet/include/uapi -I$PWD/lnet/include -I$PWD/lustre/include/uapi -I$PWD/lustre/include" -AC_SUBST(EXTRA_KCFLAGS) -]) # LB_PROG_CC - -# -# Check if gcc supports -Wno-format-truncation -# -# To supress many warnings with gcc7 -# -AC_DEFUN([LB_CC_NO_FORMAT_TRUNCATION], [ - AC_MSG_CHECKING([for -Wno-format-truncation support]) - - saved_flags="$CFLAGS" - CFLAGS="$CFLAGS -Wno-format-truncation" - - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [])], [ - EXTRA_KCFLAGS="$EXTRA_KCFLAGS -Wno-format-truncation" - AC_SUBST(EXTRA_KCFLAGS) - AC_MSG_RESULT([yes]) - ], [ - AC_MSG_RESULT([no]) - ]) - - CFLAGS="$saved_flags" -]) - -# -# Check if gcc supports -Wno-stringop-truncation -# -# To supress many warnings with gcc8 -# -AC_DEFUN([LB_CC_NO_STRINGOP_TRUNCATION], [ - AC_MSG_CHECKING([for -Wno-stringop-truncation support]) - - saved_flags="$CFLAGS" - CFLAGS="$CFLAGS -Werror -Wno-stringop-truncation" - - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [])], [ - EXTRA_KCFLAGS="$EXTRA_KCFLAGS -Wno-stringop-truncation" - AC_SUBST(EXTRA_KCFLAGS) - AC_MSG_RESULT([yes]) - ], [ - AC_MSG_RESULT([no]) - ]) - - CFLAGS="$saved_flags" -]) - -# -# Check if gcc supports -Wno-stringop-overflow -# -# To supress many warnings with gcc8 -# -AC_DEFUN([LB_CC_NO_STRINGOP_OVERFLOW], [ - AC_MSG_CHECKING([for -Wno-stringop-overflow support]) - - saved_flags="$CFLAGS" - CFLAGS="$CFLAGS -Wno-stringop-overflow" - - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [])], [ - EXTRA_KCFLAGS="$EXTRA_KCFLAGS -Wno-stringop-overflow" - AC_SUBST(EXTRA_KCFLAGS) - AC_MSG_RESULT([yes]) - ], [ - AC_MSG_RESULT([no]) - ]) - - CFLAGS="$saved_flags" -]) - -# # LB_CONDITIONALS # # AM_CONDITIONAL instances for everything @@ -675,11 +574,6 @@ LB_INCLUDE_RULES LB_PATH_DEFAULTS -LB_PROG_CC -LB_CC_NO_FORMAT_TRUNCATION -LB_CC_NO_STRINGOP_TRUNCATION -LB_CC_NO_STRINGOP_OVERFLOW - LC_OSD_ADDON LB_CONFIG_DOCS @@ -742,15 +636,4 @@ AS_IF([test -d $TEST_DIR -a "x${PARALLEL_BUILD_OPT}" != "xdebug"], [ ]) AC_OUTPUT - -cat <<_ACEOF - -CC: $CC -LD: $LD -CPPFLAGS: $CPPFLAGS -CFLAGS: $CFLAGS -EXTRA_KCFLAGS: $EXTRA_KCFLAGS - -Type 'make' to build Lustre. -_ACEOF ]) # LB_CONFIGURE diff --git a/config/lustre-toolchain.m4 b/config/lustre-toolchain.m4 new file mode 100644 index 0000000..d8c85d8 --- /dev/null +++ b/config/lustre-toolchain.m4 @@ -0,0 +1,220 @@ +# SPDX-License-Identifier: GPL-2.0 + +# +# This file is part of Lustre, http://www.lustre.org/ +# +# config/lustre-toolchain.m4 +# +# Configure the global compiler flags and toolchain settings +# + +# +# LTC_LLVM_TOOLCHAIN +# +# Read LLVM and LLVM_IAS env variables and set CC and friends +# based on their values +# +AC_DEFUN([LTC_LLVM_TOOLCHAIN], [ +AC_ARG_VAR(LLVM, "Enable LLVM toolchain") +AC_ARG_VAR(LLVM_IAS, "Disable LLVM integrated assembler") + +if [[ -n "$LLVM" ]]; then + +if [[ -z "${LLVM##*/*}" ]]; then +LLVM_PREFIX="$LLVM" +fi + +if [[ -z "${LLVM##*-*}" ]]; then +LLVM_SUFFIX="$LLVM" +fi + +HOSTCC="$LLVM_PREFIX"clang"$LLVM_SUFFIX" +HOSTCXX="$LLVM_PREFIX"clang++"$LLVM_SUFFIX" +CC="$LLVM_PREFIX"clang"$LLVM_SUFFIX" +LD="$LLVM_PREFIX"ld.lld"$LLVM_SUFFIX" +AR="$LLVM_PREFIX"llvm-ar"$LLVM_SUFFIX" +NM="$LLVM_PREFIX"llvm-nm"$LLVM_SUFFIX" +OBJCOPY="$LLVM_PREFIX"llvm-objcopy"$LLVM_SUFFIX" +OBJDUMP="$LLVM_PREFIX"llvm-objdump"$LLVM_SUFFIX" +READELF="$LLVM_PREFIX"llvm-readelf"$LLVM_SUFFIX" +STRIP="$LLVM_PREFIX"llvm-strip"$LLVM_SUFFIX" + +if [[ "$LLVM_IAS" == "0" ]]; then +CC="$CC -fno-integrated-as" +fi + +fi +]) # LTC_LLVM_TOOLCHAIN + +# +# LTC_CONFIG_ERROR +# +# Simple flag to make compiler flags very lax, for +# development purposes +# +AC_DEFUN([LTC_CONFIG_ERROR], [ +AC_ARG_ENABLE([strict-errors], + AS_HELP_STRING([--disable-strict-errors], [Disable strict error C flags])) + +AS_IF([test "x$enable_strict_errors" != "xno"], [ +AS_IF([test $target_cpu == "i686" -o $target_cpu == "x86_64"], [ +CFLAGS="$CFLAGS -Wall -Werror" +]) +], [ +CFLAGS="$CFLAGS -Wall -Wno-error -Wno-error=incompatible-function-pointer-types -Wno-error=incompatible-pointer-types" +]) +]) # LTC_CONFIG_ERROR + +# +# LTC_PROG_CC +# +# checks on the C compiler +# +AC_DEFUN([LTC_PROG_CC], [ +AC_PROG_RANLIB +AC_CHECK_TOOL(LD, [ld], [no]) +AC_CHECK_TOOL(OBJDUMP, [objdump], [no]) +AC_CHECK_TOOL(STRIP, [strip], [no]) + +# --------- unsigned long long sane? ------- +AC_CHECK_SIZEOF(unsigned long long, 0) +AS_IF([test $ac_cv_sizeof_unsigned_long_long != 8], + [AC_MSG_ERROR([we assume that sizeof(unsigned long long) == 8.])]) + +AS_IF([test $target_cpu = powerpc64], [ + AC_MSG_WARN([set compiler with -m64]) + CFLAGS="$CFLAGS -m64" + CC="$CC -m64" +]) + +# libcfs/include for util headers, lustre/include for liblustreapi and friends +# UAPI headers from OpenSFS are included if modules support is enabled, otherwise +# it will use the native kernel implementation. +CPPFLAGS="-I$PWD/libcfs/include -I$PWD/lnet/utils/ -I$PWD/lustre/include $CPPFLAGS" + +CCASFLAGS="-Wall -fPIC -D_GNU_SOURCE" +AC_SUBST(CCASFLAGS) + +# everyone builds against lnet and lustre kernel headers +EXTRA_KCFLAGS="$EXTRA_KCFLAGS -g -I$PWD/libcfs/include -I$PWD/libcfs/include/libcfs -I$PWD/lnet/include/uapi -I$PWD/lnet/include -I$PWD/lustre/include/uapi -I$PWD/lustre/include" +AC_SUBST(EXTRA_KCFLAGS) +]) # LTC_PROG_CC + +# +# LTC_CC_NO_FORMAT_TRUNCATION +# +# Check if gcc supports -Wno-format-truncation +# To supress many warnings with gcc7 +# +AC_DEFUN([LTC_CC_NO_FORMAT_TRUNCATION], [ + AC_MSG_CHECKING([for -Wno-format-truncation support]) + + saved_flags="$CFLAGS" + CFLAGS="-Werror -Wno-format-truncation" + + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [])], [ + EXTRA_KCFLAGS="$EXTRA_KCFLAGS -Wno-format-truncation" + AC_SUBST(EXTRA_KCFLAGS) + AC_MSG_RESULT([yes]) + ], [ + AC_MSG_RESULT([no]) + ]) + + CFLAGS="$saved_flags" +]) # LTC_CC_NO_FORMAT_TRUNCATION + +# +# LTC_CC_NO_STRINGOP_TRUNCATION +# +# Check if gcc supports -Wno-stringop-truncation +# To supress many warnings with gcc8 +# +AC_DEFUN([LTC_CC_NO_STRINGOP_TRUNCATION], [ + AC_MSG_CHECKING([for -Wno-stringop-truncation support]) + + saved_flags="$CFLAGS" + CFLAGS="-Werror -Wno-stringop-truncation" + + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [])], [ + EXTRA_KCFLAGS="$EXTRA_KCFLAGS -Wno-stringop-truncation" + AC_SUBST(EXTRA_KCFLAGS) + AC_MSG_RESULT([yes]) + ], [ + AC_MSG_RESULT([no]) + ]) + + CFLAGS="$saved_flags" +]) # LTC_CC_NO_STRINGOP_TRUNCATION + +# +# LTC_CC_NO_STRINGOP_OVERFLOW +# +# Check if gcc supports -Wno-stringop-overflow +# To supress many warnings with gcc8 +# +AC_DEFUN([LTC_CC_NO_STRINGOP_OVERFLOW], [ + AC_MSG_CHECKING([for -Wno-stringop-overflow support]) + + saved_flags="$CFLAGS" + CFLAGS="-Werror -Wno-stringop-overflow" + + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [])], [ + EXTRA_KCFLAGS="$EXTRA_KCFLAGS -Wno-stringop-overflow" + AC_SUBST(EXTRA_KCFLAGS) + TEST_RESULT="yes" + AC_MSG_RESULT([yes]) + ], [ + AC_MSG_RESULT([no]) + ]) + + CFLAGS="$saved_flags" + AM_CONDITIONAL(NO_STRINGOP_OVERFLOW, test x$TEST_RESULT = xyes) +]) # LTC_CC_NO_STRINGOP_OVERFLOW + +# +# LTC_TOOLCHAIN_CONFIGURE +# +# main configure steps +# +AC_DEFUN([LTC_TOOLCHAIN_CONFIGURE], [ +AC_REQUIRE([LTC_LLVM_TOOLCHAIN]) +AC_REQUIRE([AC_PROG_CC]) + +AM_PROG_AS +AC_CHECK_TOOLS(AR, ar) +LTC_PROG_CC + +LTC_CONFIG_ERROR + +LTC_CC_NO_FORMAT_TRUNCATION +LTC_CC_NO_STRINGOP_TRUNCATION +LTC_CC_NO_STRINGOP_OVERFLOW + +if test $ac_test_CFLAGS; then + CFLAGS=$ac_save_CFLAGS +fi + +CFLAGS="$CFLAGS $EXTRA_CFLAGS" +]) # LTC_TOOLCHAIN_CONFIGURE + +# +# LTC_TOOLCHAIN_STATUS +# +# main configure steps +# +AC_DEFUN([LTC_TOOLCHAIN_STATUS], [ +cat <<_ACEOF + +CC: $CC +CFLAGS: $CFLAGS +EXTRA_CFLAGS: $EXTRA_CFLAGS + +EXTRA_KCFLAGS: $EXTRA_KCFLAGS + +LD: $LD + +CPPFLAGS: $CPPFLAGS + +Type 'make' to build Lustre. +_ACEOF +]) # LTC_TOOLCHAIN_STATUS diff --git a/configure.ac b/configure.ac index 7e26143..7c96386 100644 --- a/configure.ac +++ b/configure.ac @@ -22,15 +22,14 @@ AC_CANONICAL_TARGET AM_INIT_AUTOMAKE([1.10 tar-pax -Wno-portability subdir-objects]) AM_MAINTAINER_MODE([enable]) -AC_PROG_CC +LTC_TOOLCHAIN_CONFIGURE LT_INIT AC_PROG_MKDIR_P -AM_PROG_AS AC_PATH_PROG(FLEX, flex) AC_PATH_PROG(BISON, bison) AC_PATH_PROG(RPMBUILD, rpmbuild) -AC_CHECK_TOOLS(AR, ar) LUSTRE_VERSION_CPP_MACROS LB_CONFIGURE +LTC_TOOLCHAIN_STATUS diff --git a/lustre/autoconf/lustre-core.m4 b/lustre/autoconf/lustre-core.m4 index 9fc136e..3f94c95 100644 --- a/lustre/autoconf/lustre-core.m4 +++ b/lustre/autoconf/lustre-core.m4 @@ -70,7 +70,7 @@ AC_CHECK_FUNCS([copy_file_range], # AC_DEFUN([LC_FID2PATH_ANON_UNION], [ saved_flags="$CFLAGS" -CFLAGS="$CFLAGS -Werror" +CFLAGS="-Werror" AC_MSG_CHECKING([if 'struct getinfo_fid2path' has anonymous union]) AC_COMPILE_IFELSE([AC_LANG_SOURCE([ #include @@ -405,7 +405,7 @@ AS_IF([test "x$enable_gss" != xno], [ AC_DEFUN([LC_OPENSSL_HMAC], [ has_hmac_functions="no" saved_flags="$CFLAGS" -CFLAGS="$CFLAGS -Werror" +CFLAGS="-Werror" AC_MSG_CHECKING([whether OpenSSL has HMAC_Init_ex]) AS_IF([test "x$enable_ssk" != xno], [ AC_COMPILE_IFELSE([AC_LANG_SOURCE([ @@ -415,6 +415,7 @@ AC_COMPILE_IFELSE([AC_LANG_SOURCE([ int main(void) { int rc; rc = HMAC_Init_ex(NULL, "test", 4, EVP_md_null(), NULL); + return rc; } ])],[ has_hmac_functions="yes" @@ -430,7 +431,7 @@ CFLAGS="$saved_flags" AC_DEFUN([LC_OPENSSL_EVP_PKEY], [ has_evp_pkey="no" saved_flags="$CFLAGS" -CFLAGS="$CFLAGS -Werror" +CFLAGS="-Werror" AC_MSG_CHECKING([whether OpenSSL has EVP_PKEY_get_params]) AS_IF([test "x$enable_ssk" != xno], [ AC_COMPILE_IFELSE([AC_LANG_SOURCE([ @@ -440,6 +441,7 @@ AC_COMPILE_IFELSE([AC_LANG_SOURCE([ OSSL_PARAM *params; int rc = EVP_PKEY_get_params(NULL, params); + return rc; } ])],[ AC_DEFINE(HAVE_OPENSSL_EVP_PKEY, 1, [OpenSSL EVP_PKEY_get_params]) @@ -476,13 +478,14 @@ AC_MSG_RESULT([$enable_ssk]) # OpenSSL is needed for l_getsepol AC_DEFUN([LC_OPENSSL_GETSEPOL], [ saved_flags="$CFLAGS" -CFLAGS="$CFLAGS -Werror" +CFLAGS="-Werror" AC_MSG_CHECKING([whether openssl-devel is present]) AC_COMPILE_IFELSE([AC_LANG_SOURCE([ #include int main(void) { EVP_MD_CTX *mdctx = EVP_MD_CTX_create(); + (void) mdctx; } ])],[ AC_DEFINE(HAVE_OPENSSL_GETSEPOL, 1, [openssl-devel is present]) @@ -4451,9 +4454,6 @@ AC_DEFUN([LC_CONFIGURE], [ AC_MSG_NOTICE([Lustre core checks ==============================================================================]) -AS_IF([test $target_cpu == "i686" -o $target_cpu == "x86_64"], - [CFLAGS="$CFLAGS -Wall -Werror"]) - # maximum MDS thread count LC_MDS_MAX_THREADS diff --git a/lustre/tests/Makefile.am b/lustre/tests/Makefile.am index bec15eb..83229ab 100644 --- a/lustre/tests/Makefile.am +++ b/lustre/tests/Makefile.am @@ -114,7 +114,10 @@ nobase_test_DATA = $(nobase_noinst_DATA) LIBLUSTREAPI = $(top_builddir)/lustre/utils/liblustreapi.la +if NO_STRINGOP_OVERFLOW badarea_io_CFLAGS=-Wno-stringop-overflow +endif # NO_STRINGOP_OVERFLOW + mmap_sanity_LDADD = $(LIBLUSTREAPI) multiop_LDADD = $(LIBLUSTREAPI) $(PTHREAD_LIBS) llapi_layout_test_LDADD = $(LIBLUSTREAPI) -- 1.8.3.1