]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
mkosi: Add support for building with LLVM
authorDaan De Meyer <daan.j.demeyer@gmail.com>
Sat, 1 Jun 2024 10:27:45 +0000 (12:27 +0200)
committerDaan De Meyer <daan.j.demeyer@gmail.com>
Mon, 3 Jun 2024 10:53:03 +0000 (12:53 +0200)
Now you can do mkosi -E LLVM=1 to build with clang+lld. This includes
support for building with sanitizers.

mkosi.images/system/mkosi.conf
mkosi.images/system/mkosi.conf.d/10-arch/mkosi.build.chroot
mkosi.images/system/mkosi.conf.d/10-arch/mkosi.conf
mkosi.images/system/mkosi.conf.d/10-centos-fedora/mkosi.build.chroot
mkosi.images/system/mkosi.conf.d/10-centos-fedora/mkosi.conf
mkosi.images/system/mkosi.conf.d/10-debian-ubuntu/mkosi.build.chroot
mkosi.images/system/mkosi.conf.d/10-debian-ubuntu/mkosi.conf
mkosi.images/system/mkosi.conf.d/10-opensuse/mkosi.build.chroot
mkosi.images/system/mkosi.conf.d/10-opensuse/mkosi.conf

index bc4d80cc05f55cbc4b2562014f92f2f68f9cc52f..7a520612765dde6ef5d50f01dffd927d829be4be 100644 (file)
@@ -26,6 +26,7 @@ Packages=
         attr
         bash-completion
         bpftrace
+        clang
         coreutils
         curl
         diffutils
@@ -42,6 +43,8 @@ Packages=
         kmod
         knot
         less
+        lld
+        llvm
         lvm2
         man
         mdadm
index 7df218823e96a719c994e7b2f315664aecf804a3..12575eef6a342b6eb990c165af50166ef92a0ed3 100755 (executable)
@@ -24,12 +24,29 @@ ln --symbolic . "pkg/$ID/src"
 # shellcheck source=/dev/null
 . /etc/makepkg.conf
 
+CFLAGS="-O${OPTIMIZATION:-0} -Wp,-U_FORTIFY_SOURCE"
+if ((LLVM)); then
+    # TODO: Remove -fno-sanitize-function when https://github.com/systemd/systemd/issues/29972 is fixed.
+    CFLAGS="$CFLAGS -shared-libasan -fno-sanitize=function"
+fi
+
+LDFLAGS=""
+if ((LLVM)) && [[ -n "$SANITIZERS" ]]; then
+    LDFLAGS="$LDFLAGS -Wl,-rpath=$(clang --print-file-name="")lib/linux"
+fi
+
 # Override the default options. Disable FORTIFY_SOURCE because it doesn't work with O0. We specifically
 # disable "strip", "zipman" and "lto" as they slow down builds significantly. OPTIONS= cannot be overridden
 # on the makepkg command line so we append to /etc/makepkg.conf instead. The rootfs is overlaid with a
 # writable tmpfs during the build script so these changes don't end up in the image itself.
 tee --append /etc/makepkg.conf >/dev/null <<EOF
-CFLAGS="$CFLAGS -O${OPTIMIZATION:-0} -Wp,-U_FORTIFY_SOURCE"
+export CC="$( ((LLVM)) && echo clang || echo gcc)"
+export CXX="$( ((LLVM)) && echo clang++ || echo g++)"
+export CC_LD="$( ((LLVM)) && echo lld)"
+export CXX_LD="$( ((LLVM)) && echo lld)"
+export CFLAGS="\$CFLAGS $CFLAGS"
+export CXXFLAGS="\$CXXFLAGS $CFLAGS"
+export LDFLAGS="\$LDFLAGS $LDFLAGS"
 OPTIONS=(
     docs
     !libtool
index 51f28903b383a57c77765c371d676006bb97acf7..48dc677a46055d854105556a9d78fa7afed7026e 100644 (file)
@@ -21,6 +21,7 @@ Packages=
         bind
         bpf
         btrfs-progs
+        compiler-rt
         compsize
         cryptsetup
         dbus-broker
@@ -62,6 +63,7 @@ Packages=
 
 InitrdPackages=
         btrfs-progs
+        compiler-rt
         tpm2-tools
 
 InitrdVolatilePackages=
index 9895f23908c46c2adcce0f78acd745ef1f257418..3bac3fbce9e401f036957b44604f41053f10d586 100755 (executable)
@@ -37,11 +37,29 @@ DIST="$(rpm --eval %dist)"
 ARCH="$(rpm --eval %_arch)"
 SRCDEST="/usr/src/debug/systemd-$VERSION-${RELEASE}${DIST}.$ARCH"
 
+COMMON_MACRO_OVERRIDES=(
+    --define "toolchain $( ((LLVM)) && echo clang || echo gcc)"
+    --define "_fortify_level 0"
+    --undefine _lto_cflags
+    # TODO: Remove once redhat-rpm-config 292 is available everywhere.
+    --define "_hardening_clang_cflags --config=/usr/lib/rpm/redhat/redhat-hardened-clang.cfg"
+    --define "_hardening_clang_ldflags --config=/usr/lib/rpm/redhat/redhat-hardened-clang-ld.cfg"
+)
+
 # TODO: Drop -U_FORTIFY_SOURCE when we switch to CentOS Stream 10.
-CFLAGS="$(rpm --define "_fortify_level 0" --undefine _lto_cflags --eval %build_cflags) -O${OPTIMIZATION:-0} -Wp,-U_FORTIFY_SOURCE"
+CFLAGS="-O${OPTIMIZATION:-0} -Wp,-U_FORTIFY_SOURCE"
 if ((WITH_DEBUG)); then
     CFLAGS="$CFLAGS -fdebug-prefix-map=../src=$SRCDEST"
 fi
+if ((LLVM)); then
+    # TODO: Remove -fno-sanitize-function when https://github.com/systemd/systemd/issues/29972 is fixed.
+    CFLAGS="$CFLAGS -shared-libasan -fno-sanitize=function"
+fi
+
+LDFLAGS=""
+if ((LLVM)) && [[ -n "$SANITIZERS" ]]; then
+    LDFLAGS="$LDFLAGS -Wl,-rpath=$(dirname "$(clang --print-file-name=libclang_rt.asan.so)")"
+fi
 
 IFS=
 # TODO: Replace meson_build and meson_install overrides with "--undefine __meson_verbose" once
@@ -49,7 +67,9 @@ IFS=
 # shellcheck disable=SC2046
 env \
 ANNOBIN="no-active-checks" \
-rpmbuild \
+CC_LD="$( ((LLVM)) && echo lld)" \
+CXX_LD="$( ((LLVM)) && echo lld)" \
+    rpmbuild \
     -bb \
     --build-in-place \
     --with upstream \
@@ -64,7 +84,10 @@ rpmbuild \
     $( ((WITH_DEBUG)) || echo "--define=debug_package %{nil}") \
     --define "version_override $VERSION" \
     --define "release_override $RELEASE" \
-    --define "build_cflags $CFLAGS" \
+    "${COMMON_MACRO_OVERRIDES[@]}" \
+    --define "build_cflags $(rpm "${COMMON_MACRO_OVERRIDES[@]}" --eval "%{?build_cflags}") $CFLAGS" \
+    --define "build_cxxflags $(rpm "${COMMON_MACRO_OVERRIDES[@]}" --eval "%{?build_cxxflags}") $CFLAGS" \
+    --define "build_ldflags $(rpm "${COMMON_MACRO_OVERRIDES[@]}" --eval "%{?build_ldflags}") $LDFLAGS" \
     --define "meson_build %{shrink:%{__meson} compile -C %{_vpath_builddir} -j %{_smp_build_ncpus} %{nil}}" \
     --define "meson_install %{shrink:DESTDIR=%{buildroot} %{__meson} install -C %{_vpath_builddir} --no-rebuild --quiet %{nil}}" \
     --define "meson_extra_configure_options -D mode=developer -D b_sanitize=${SANITIZERS:-none}" \
@@ -77,9 +100,7 @@ rpmbuild \
     --define "__elf_exclude_path ^/usr/lib/systemd/tests/unit-tests/.*$" \
     --define "__script_requires %{nil}" \
     --define "_find_debuginfo_dwz_opts %{nil}" \
-    --define "_fortify_level 0" \
     --define "_fixperms true" \
-    --undefine _lto_cflags \
     --undefine _package_note_flags \
     --noclean \
     "pkg/$ID/systemd.spec"
index 65bf20e8560faa38f1b4b64c58f6e0772014de0e..fea3853902ca7f741ac017e6d7013f1cce8ea192 100644 (file)
@@ -23,6 +23,7 @@ VolatilePackages=
 Packages=
         bind-utils
         bpftool
+        compiler-rt
         cryptsetup
         device-mapper-event
         device-mapper-multipath
index 023cfdf632a3f47f5eb91b7a35e43e2ea6751db8..8cdfdb719ed05f59392e7d2e703287f1f9b8835c 100755 (executable)
@@ -44,8 +44,24 @@ EOF
 cat debian/changelog >>debian/changelog.new
 mv debian/changelog.new debian/changelog
 
+CFLAGS="-O${OPTIMIZATION:-0}"
+if ((LLVM)); then
+    # TODO: Remove -fno-sanitize-function when https://github.com/systemd/systemd/issues/29972 is fixed.
+    CFLAGS="$CFLAGS -shared-libasan -fno-sanitize=function"
+fi
+
+LDFLAGS=""
+if ((LLVM)) && [[ -n "$SANITIZERS" ]]; then
+    LDFLAGS="$LDFLAGS -Wl,-rpath=$(clang --print-file-name="")lib/linux"
+fi
+
+# TODO: Drop GENSYMBOLS_LEVEL once https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=986746 is fixed.
 build() {
     env \
+    CC="$( ((LLVM)) && echo clang || echo gcc)" \
+    CXX="$( ((LLVM)) && echo clang++ || echo g++)" \
+    CC_LD="$( ((LLVM)) && echo lld)" \
+    CXX_LD="$( ((LLVM)) && echo lld)" \
     DEB_BUILD_OPTIONS="$(awk '$1=$1' <<<"\
         $( ((WITH_TESTS)) || echo nocheck) \
         $( ((WITH_DOCS)) || echo nodoc) \
@@ -59,11 +75,14 @@ build() {
         $( ((WITH_DOCS)) || echo nodoc) \
         pkg.systemd.upstream \
     ")" \
-    DEB_CFLAGS_APPEND="-O${OPTIMIZATION:-0}" \
+    DEB_CFLAGS_APPEND="$CFLAGS" \
+    DEB_CXXFLAGS_APPEND="$CFLAGS" \
+    DEB_LDFLAGS_APPEND="$LDFLAGS" \
     DPKG_FORCE="unsafe-io" \
     DPKG_DEB_COMPRESSOR_TYPE="none" \
     DH_MISSING="--fail-missing" \
     CONFFLAGS_UPSTREAM="-D mode=developer -D b_sanitize=${SANITIZERS:-none}" \
+    GENSYMBOLS_LEVEL="$( ((LLVM)) && echo 0 || echo 1)" \
         dpkg-buildpackage \
         --no-pre-clean \
         --unsigned-changes \
index 6c0eda2bcde4769b372ee74a620207d1d7e808bd..386c1923a54a7c1bc28ade2d33bd6ecff6ad97a5 100644 (file)
@@ -56,6 +56,7 @@ Packages=
         iputils-ping
         isc-dhcp-server
         libcap-ng-utils
+        libclang-rt-dev
         libtss2-rc0
         libtss2-tcti-device0
         locales
@@ -83,6 +84,7 @@ Packages=
 
 InitrdPackages=
         btrfs-progs
+        libclang-rt-dev
         tpm2-tools
 
 InitrdVolatilePackages=
index 13cda4c9b899eb6e93581abae41334553876f3d9..11be720453e72cf076b8c9805f9357f69e941c73 100755 (executable)
@@ -42,9 +42,24 @@ DIST="$(rpm --eval %dist)"
 ARCH="$(rpm --eval %_arch)"
 SRCDEST="/usr/src/debug/systemd-$VERSION-${RELEASE}${DIST}.$ARCH"
 
-EXTRA_CFLAGS="-O${OPTIMIZATION:-0} -Wp,-U_FORTIFY_SOURCE"
+CFLAGS="-O${OPTIMIZATION:-0} -Wp,-U_FORTIFY_SOURCE"
 if ((WITH_DEBUG)); then
-    EXTRA_CFLAGS="$EXTRA_CFLAGS -fdebug-prefix-map=../src=$SRCDEST"
+    CFLAGS="$CFLAGS -fdebug-prefix-map=../src=$SRCDEST"
+fi
+if ((LLVM)); then
+    # TODO: Remove -fno-sanitize-function when https://github.com/systemd/systemd/issues/29972 is fixed.
+    CFLAGS="$CFLAGS -shared-libasan -fno-sanitize=function"
+fi
+
+LDFLAGS="$(rpm --eval "%{?build_ldflags}") $LDFLAGS"
+if ((LLVM)) && [[ -n "$SANITIZERS" ]]; then
+    LDFLAGS="$LDFLAGS -Wl,-rpath=$(clang --print-file-name="")lib/linux"
+fi
+
+# A macro can't have an empty body and currently opensuse does not specify any of its own linker flags so
+# set LDFLAGS to %{nil} if there are no linker flags.
+if [[ -z "${LDFLAGS// }" ]]; then
+    LDFLAGS="%{nil}"
 fi
 
 build() {
@@ -54,6 +69,11 @@ build() {
     # TODO: Replace __meson_auto_features override with meson_extra_configure_options once the suse spec
     # starts to use it.
     # shellcheck disable=SC2046
+    env \
+    CC="$( ((LLVM)) && echo clang || echo gcc)" \
+    CXX="$( ((LLVM)) && echo clang++ || echo g++)" \
+    CC_LD="$( ((LLVM)) && echo lld)" \
+    CXX_LD="$( ((LLVM)) && echo lld)" \
     rpmbuild \
         -bb \
         --build-in-place \
@@ -70,7 +90,9 @@ build() {
         --define "version_override $VERSION" \
         --define "release_override $RELEASE" \
         --define "__check_files sh -c '$(rpm --define "_topdir /var/tmp" --eval %__check_files) | tee /tmp/unpackaged-files'" \
-        --define "build_cflags $(rpm --eval %build_cflags) $EXTRA_CFLAGS" \
+        --define "build_cflags $(rpm --eval "%{?build_cflags}") $CFLAGS" \
+        --define "build_cxxflags $(rpm --eval "%{?build_cxxflags}") $CFLAGS" \
+        --define "build_ldflags $LDFLAGS" \
         --define "meson_build %{shrink:%{__meson} compile -C %{_vpath_builddir} -j %{_smp_build_ncpus} %{nil}}" \
         --define "meson_install %{shrink:DESTDIR=%{buildroot} %{__meson} install -C %{_vpath_builddir} --no-rebuild --quiet %{nil}}" \
         --define "__meson_auto_features auto -D mode=developer -D b_sanitize=${SANITIZERS:-none}" \
index 188f548643b9551cc680a0c4634a5e7b35b5b7d2..71e315f869b46e4f095abf810164a9f5640ee72a 100644 (file)
@@ -39,8 +39,8 @@ Packages=
         docbook-xsl-stylesheets
         f2fs-tools
         gawk
-        git-core
         gcc-c++
+        git-core
         glibc-locale-base
         gnutls
         grep
@@ -90,6 +90,7 @@ Packages=
 
 InitrdPackages=
         btrfs-progs
+        clang
         kmod
         libkmod2
         tpm2.0-tools