-
Notifications
You must be signed in to change notification settings - Fork 151
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
building with clang rather than gcc #124
Comments
@GoPerry any ideas here? |
@superm1 |
I guess that the default cc should be changed to clang ,then dkms built will use the new default compiler . @ColinIanKing Do you change your default compiler ? It not, could you help to have a try ? |
I think specifically they're building using CC environment variable, which is something the kernel allows but dkms currently resets the variable to avoid problems. |
I did some build test on this. #build error output This error Cflag is defined in kernel top Makefile. KBUILD_CFLAGS += -Wno-unused-but-set-variable So i would say that we cannot compile the dkms with clang in this situation. |
@ColinIanKing would it be possible for the kernel to store somewhere the exact compiler/ environment /flags used? I think sourcing that from DKMS is probably the safest solution. |
@superm1, yes, that is a good idea - I can dump these out before running dkms - is there currently a mechanism for DKMS to pull these in by sourcing them? |
To me the easiest hack will be in But if we want this to become a standard place that DKMS reads to get the information of the compiled kernel, probably needs some alignment to make the upstream kernel dump this somewhere too. |
Flexible compiler support would be highly appreciated. |
I have pinged the Debian VirtualBox maintainers again and asked for a handling like in
My
NOTE: Of course, you can pass your distro's default compiler ( For me the above works as |
Here's what I use for virtualbox on Arch (excerpt from PKGBUILD):
(I copy over the dkms.conf to the build directory, in order to prevent changing the default one.) |
Thanks for telling the other half of the story. |
@dileks |
You completed your story. |
Well there's nothing really new. Just thought it would be a good idea to post some contents of the PKGBUILD. |
If that's from Kbuild, it should get wrapped in |
@GoPerry do you have thoughts on not requiring specific warning flags, just like the Linux kernel's Kbuild doesn't, via |
are the examples how to build anything with dkms? It would be nice to have some steps to reproduce for others to understand the problem. |
do you mean that the dkms will use system default compiler which is set by "cc option" |
Just my 2 cents worth:
CC=clang CXX=clang++ LD=ld.lld AR=llvm-ar NM=llvm-nm OBJCOPY=llvm-objcopy OBJSIZE=llvm-size STRIP=llvm-strip as per nickdesaulniers comment, a simple dkms example can be found in https://kernel.ubuntu.com/~cking/hello-0.1.tar - put the contents into /usr/src and do:
|
This hack seems to work for me:
But I'm not a dkms expert, so I expect this is wrong on a few levels. |
That looks like it's parsing the contents of the current running kernel (
No; and I don't expect users to be changing their system default CC to clang; that's way too error prone. Instead build systems should allow for CC to be passed via env var to override the system default when appropriate. |
Getting the toolchain version from the vmlinux binary makes total sense, completely overlooked that. My original thoughts were that a clang built kernel should have dkms modules built for it using clang as I was under the impression that the modules needed to be built with clang to match the internal kernel ABIs. But I suppose if they are compatible ELF binaries that assumption maybe wrong. |
Out of curiosity, how do you extract that information from vmlinux? |
If the kernel has the config settings built in one can check for this in /proc/config and grep for the various config settings such as CONFIG_CC_VERSION_TEXT or CONFIG_CC_IS_GCC. However, quite a few distros disable this feature. Or use https://stuff.mit.edu/afs/sipb/contrib/linux/scripts/extract-ikconfig for the binary vmlinux image. |
Thanks! That's very useful. |
Yes, but remember that some kernels don't have this config built in, so the vmlinux image also needs to be scanned as a fallback :-/ |
You can use
|
LTO does not work here with virtualbox-dkms, see my yesterday's comment here: ClangBuiltLinux/linux#1104 |
This is the recommended answer. If you're in a hurry: $ strings vmlinux | grep 'Linux version'
Linux version 5.12.0+ (ndesaulniers@ndesaulniers1.mtv.corp.google.com) (Nick Desaulniers clang version 13.0.0 (git@github.com:llvm/llvm-project.git 07128a828bc9ec24c6bf788f34c324d9db4762f6), LLD 13.0.0 (git@github.com:llvm/llvm-project.git 07128a828bc9ec24c6bf788f34c324d9db4762f6)) #22 SMP Fri Apr 30 19:08:59 PDT 2021 |
Is there any updates to this? shouldn't dkms try to use the same compiler as the kernel instead of us hacking random files? This gets old fast when you have multiple dkms modules (nvidia, virtualbox, ntfs3) |
Using llvm-readelf does not seem to work, I get a "could not find section .comment" error message. Maybe that's because the binaries were stripped? @OneOfOne, I agree that DKMS should find the proper settings by itself, but don't ask me how it can be done best... |
Hi Guys, does anyone know if this will get fixed? We need DKMS to figure out which build-tools to use based off the way the kernel was built otherwise DKMS will fail for LLVM/Clang built kernels especially now that the flto=thin genie is out of the box! Without hacking continually we can't roll with newer kernel versions easily if we rely on DKMS for many applications and drivers. For my case which I'm guessing is a common use-case, Virtualbox! It's one of the most common desktop VM Managers and we can't use it with clang LTO'ed kernels!. Please someone fix this! |
Regarding the LTO thing, I submitted the potential workaround mentioned above upstream: |
Thanks torvic9! However that only addresses part of the problem if I understand the PR correctly, it only addresses the location of the cache needed for LTO'ing. Does it address how to figure out whether to use gcc and its associated build tools or llvm/clang? I think that's the biggest problem. |
No, this only covers LTO. For those who are running Arch, here is a very dirty and quick fix for DKMS, adding a simple clang check: I don't put it into a PR because, as said, it's dirty, it misses a couple of checks and is only for Arch, where I succesfully tested it with VBox. |
EDIT: I did something wrong, please disregard. |
After another round of testing on Arch, I can say that the combination of the ThinLTO patch (I will send a new version shortly) and the patched DKMS script results in correct automatic building of the VBox modules. |
Probably slightly safer to check via: $ readelf -p .comment vmlinux
String dump of section '.comment':
[ 0] Nick Desaulniers clang version 14.0.0 (git@github.com:llvm/llvm-project.git 9e729e177aa4631d45b5370e7d13929b52599865)
[ 76] Linker: LLD 14.0.0 (git@github.com:llvm/llvm-project.git 9e729e177aa4631d45b5370e7d13929b52599865) or $ strings vmlinux | grep "Linux version" | grep clang
Linux version 5.14.0-rc3-00353-ga8554b46d7bf (ndesaulniers@ndesaulniers1.mtv.corp.google.com) (Nick Desaulniers clang version 14.0.0 (git@github.com:llvm/llvm-project.git 9e729e177aa4631d45b5370e7d13929b52599865), LLD 14.0.0 (git@github.com:llvm/llvm-project.git 9e729e177aa4631d45b5370e7d13929b52599865)) #45 SMP Mon Aug 2 16:33:14 PDT 2021 |
Did you ever finish your patch for this? I'd like to start experimenting with clang LTO kernel builds here and dkms is a blocker. |
Patch was rejected upstream for valid reasons. |
Yeah, I think the dirty clang check is the way to go simply because there are so many kernel packages shipped with stripped binaries. I'm a little confused (sorry!); you're using the patched dkms script linked in the gist above and what else? |
A patch which allows you to choose a custom thinlto-cache directory (see above). |
Ok, I got this shit to work. The answer is buried up in @ColinIanKing 's comment above. Problem number 1: dkms doesn't use the same toolchain as the kernel when building out of tree modules: --- dkms.orig 2021-10-30 03:22:06.695198591 -0700
+++ dkms 2021-10-30 03:50:53.636569028 -0700
@@ -703,6 +703,17 @@
[[ ! $clean ]] && clean="make -C $kernel_source_dir M=$dkms_tree/$module/$module_version/build clean"
fi
+ if [[ -e $kernel_source_dir/vmlinux ]]; then
+ if readelf -p .comment $kernel_source_dir/vmlinux | grep -q clang; then
+ make_command="${make_command} CC=clang"
+ fi
+ fi
+ if [[ -e $kernel_source_dir/vmlinux ]]; then
+ if readelf -p .comment $kernel_source_dir/vmlinux | grep -q LLD; then
+ make_command="${make_command} LD=ld.lld"
+ fi
+ fi
+
# Set modules_conf_array
for ((index=0; index < ${#MODULES_CONF[@]}; index++)); do
[[ ${MODULES_CONF[$index]} ]] && modules_conf_array[$index]="${MODULES_CONF[$index]}" $ cp /usr/sbin/dkms dkms
$ vim dkms
$ sudo cp dkms /usr/sbin/dkms This doesn't precisely use the exact same tools necessarily for the out of tree modules, but it should invoke Problem number 2: I don't like to install clang to /usr/bin/ and friends, especially on the machine I'm developing LLVM on. DKMS currently limits the PATH to specifically `/bin:/sbin:/usr/bin:/usr/sbin:/usr/lib/dkms". So I at least need to create temporary symlinks: $ sudo ln -s `which clang` /usr/bin/clang
$ sudo ln -s `which ld.lld` /usr/bin/ld.lld
$ sudo rm -rf /var/lib/dkms/openrazer-driver/2.8.0
$ sudo dkms build -m openrazer-driver -v 2.8.0
Creating symlink /var/lib/dkms/openrazer-driver/2.8.0/source ->
/usr/src/openrazer-driver-2.8.0
DKMS: add completed.
Kernel preparation unnecessary for this kernel. Skipping...Building module:
cleaning build area...
KERNELDIR=/lib/modules/5.15.0-rc7+/build make driver CC=clang LD=ld.lld.....
cleaning build area...
DKMS: build completed.
$ sudo dkms install -m openrazer-driver -v 2.8.0
razerkbd.ko:
Running module version sanity check.
- Original module
- No original module exists within this kernel
- Installation
- Installing to /lib/modules/5.15.0-rc7+/kernel/drivers/hid/
razermouse.ko:
Running module version sanity check. - Original module
- No original module exists within this kernel
- Installation
- Installing to /lib/modules/5.15.0-rc7+/kernel/drivers/hid/
razermousemat.ko:
Running module version sanity check.
- Original module
- No original module exists within this kernel
- Installation
- Installing to /lib/modules/5.15.0-rc7+/kernel/drivers/hid/
razerkraken.ko:
Running module version sanity check.
- Original module
- No original module exists within this kernel
- Installation
- Installing to /lib/modules/5.15.0-rc7+/kernel/drivers/hid/
razeraccessory.ko:
Running module version sanity check.
- Original module
- No original module exists within this kernel
- Installation
- Installing to /lib/modules/5.15.0-rc7+/kernel/drivers/hid/
razercore.ko:
Running module version sanity check.
- Original module
- No original module exists within this kernel
- Installation
- Installing to /lib/modules/5.15.0-rc7+/kernel/drivers/hid/
depmod...
DKMS: install completed.
$ sudo insmod /var/lib/dkms/openrazer-driver/2.8.0/5.15.0-rc7+/x86_64/module/razercore.ko
$ dmesg | tail -n2
[ 4612.792088] razercore: loading out-of-tree module taints kernel.
[ 4612.792128] razercore: module verification failed: signature and/or required key missing - tainting kernel
$ lsmod | grep razer
razercore 40960 0
hid 135168 5 i2c_hid,razercore,usbhid,hid_generic,hid_rmi
$ sudo rm /usr/bin/clang /usr/bin/ld.lld |
When building the Linux kernel, one may use `make LLVM=1` to set multiple flags, akin to `make CC=clang LD=ld.lld NM=llvm-nm ...` (see the link below for kernel docs explaining this further in detail). When building kernel modules, to ensure we're using the same toolchain as the underlying core kernel image, Kbuild will error if it's reinvoked with a toolchain that differs. This causes DKMS to fail, since it's not re-specifying the same compiler (or linker, etc). Check the .comment section of the vmlinux file in the Linux kernel source dir, and set CC= and LD= flags for make based on that. Alternatively or additionally, we could also check for the presence of CONFIG_CC_IS_CLANG=y and CONFIG_LD_IS_LLD=y in the .config in the kernel sources. We could also check the .comment section of the booted kernel. Fixes: dell#124 Link: https://docs.kernel.org/kbuild/llvm.html Suggested-by: Colin Ian King <colin.king@canonical.com> Signed-off-by: Nick Desaulniers <nick.desaulniers@gmail.com>
When building the Linux kernel, one may use `make LLVM=1` to set multiple flags, akin to `make CC=clang LD=ld.lld NM=llvm-nm ...` (see the link below for kernel docs explaining this further in detail). When building kernel modules, to ensure we're using the same toolchain as the underlying core kernel image, Kbuild will error if it's reinvoked with a toolchain that differs. This causes DKMS to fail, since it's not re-specifying the same compiler (or linker, etc). Check the .comment section of the vmlinux file in the Linux kernel source dir, and set CC= and LD= flags for make based on that. Alternatively or additionally, we could also check for the presence of CONFIG_CC_IS_CLANG=y and CONFIG_LD_IS_LLD=y in the .config in the kernel sources. We could also check the .comment section of the booted kernel. Fixes: dell#124 Fixes: ClangBuiltLinux/linux#1104 Link: https://docs.kernel.org/kbuild/llvm.html Suggested-by: Colin Ian King <colin.king@canonical.com> Signed-off-by: Nick Desaulniers <nick.desaulniers@gmail.com>
When building the Linux kernel, one may use `make LLVM=1` to set multiple flags, akin to `make CC=clang LD=ld.lld NM=llvm-nm ...` (see the link below for kernel docs explaining this further in detail). When building kernel modules, to ensure we're using the same toolchain as the underlying core kernel image, Kbuild will error if it's reinvoked with a toolchain that differs. This causes DKMS to fail, since it's not re-specifying the same compiler (or linker, etc). Check the .comment section of the vmlinux file in the Linux kernel source dir, and set CC= and LD= flags for make based on that. Alternatively or additionally, we could also check for the presence of CONFIG_CC_IS_CLANG=y and CONFIG_LD_IS_LLD=y in the .config in the kernel sources. We could also check the .comment section of the booted kernel. Fixes: dell#124 Fixes: ClangBuiltLinux/linux#1104 Link: https://docs.kernel.org/kbuild/llvm.html Suggested-by: Colin Ian King <colin.king@canonical.com> Signed-off-by: Nick Desaulniers <nick.desaulniers@gmail.com>
As pointed in the pull request, many distributions use a bzImage compressed kernel, and the detection logic does not work there. I think parsing the
I think we can safely remove this and let it just use system defined paths. |
Yes, but is the
What I personally do is to simply grep for the clang string in vmlinux, something like this:
Then add clangopts array to the make command. |
Quite different on Fedora/Red Hat. Here is the full structure:
There is no uncompressed kernel image left around. Besides this, I don't think we should really parse binaries around. |
When building the Linux kernel, one may use `make LLVM=1` to set multiple flags, akin to `make CC=clang LD=ld.lld NM=llvm-nm ...` (see the link below for kernel docs explaining this further in detail). When building kernel modules, to ensure we're using the same toolchain as the underlying core kernel image, Kbuild will error if it's reinvoked with a toolchain that differs. This causes DKMS to fail, since it's not re-specifying the same compiler (or linker, etc). Check the .comment section of the vmlinux file in the Linux kernel source dir, and set CC= and LD= flags for make based on that. If vmlinux does not exist, grep .config for CONFIG_CC_IS_CLANG=y and CONFIG_LD_IS_LLD=y. Fixes: dell#124 Fixes: ClangBuiltLinux/linux#1104 Link: https://docs.kernel.org/kbuild/llvm.html Suggested-by: Colin Ian King <colin.king@canonical.com> Signed-off-by: Nick Desaulniers <nick.desaulniers@gmail.com>
When building the Linux kernel, one may use `make LLVM=1` to set multiple flags, akin to `make CC=clang LD=ld.lld NM=llvm-nm ...` (see the link below for kernel docs explaining this further in detail). When building kernel modules, to ensure we're using the same toolchain as the underlying core kernel image, Kbuild will error if it's reinvoked with a toolchain that differs. This causes DKMS to fail, since it's not re-specifying the same compiler (or linker, etc). Check the .comment section of the vmlinux file in the Linux kernel source dir, and set CC= and LD= flags for make based on that. If vmlinux does not exist, grep .config for CONFIG_CC_IS_CLANG=y and CONFIG_LD_IS_LLD=y. Fixes: dell#124 Fixes: ClangBuiltLinux/linux#1104 Link: https://docs.kernel.org/kbuild/llvm.html Suggested-by: Colin Ian King <colin.king@canonical.com> Signed-off-by: Nick Desaulniers <nick.desaulniers@gmail.com>
How does one get debug info for their kernel then? Usually, during the production of bzImage, vmlinux is stripped of debug info so that it doesn't occupy space on disk or take longer to decompress. For Android, we usually have kernel build artifacts of the compressed kernel image, and the vmlinux with debug symbols. |
I'm trying to build various dkms packages using clang rather than gcc and I don't know how to override the default gcc setting and get dkms to use clang instead.
The linux kernel now supports native clang builds, setting LLVM=1 enables this. Is there a way to force dkms to use this option too?
I've tried --directive LLVM=1 but that doesn't seem to work for me. Any ideas?
The text was updated successfully, but these errors were encountered: