-
Notifications
You must be signed in to change notification settings - Fork 6.7k
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
LLVM: add LLVM support on Windows #36753
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,9 +17,11 @@ if("${ARCH}" STREQUAL "arm") | |
set(CMAKE_EXE_LINKER_FLAGS_INIT "--specs=nosys.specs") | ||
elseif("${ARCH}" STREQUAL "x86") | ||
if(CONFIG_64BIT) | ||
set(triple x86_64-pc-none-elf) | ||
# The LLVM built-in linker lld is a generic driver, needs to use triple os filed | ||
# to distinguish which linker will be used. | ||
set(triple x86_64-pc-linux-elf) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does it force lld to generate an elf binary on Windows? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes, this is a target name for cross compiler, but on windows, the older name "i686-pc-none-elf" couldn't be recognized and used to find a valid linker, we need to use "i686-pc-linux-elf". There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. where is this coming from? Why does llvm on windows require a triple with linux in it? Is this in LLVM? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @nashif as I understood, we need to build a zephyr elf file which could be executed on linux, it's a cross compilation from windows to linux, and llvm on windows has four linker based on os type: ld.lld (Unix), ld64.lld (macOS), lld-link (Windows), wasm-ld (WebAssembly), so I added linux in triple name, then it will use this ld.lld. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I do not know how LLVM internally handles this; but, at least in terms of GNU toolchains, they are not the same thing and we must use If the Windows LLVM distribution does not support There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I installed LLVM 10.0.0 on Windows (same version as the one I have on my Linux machine) and tested this. I was able to reproduce In theory, if we have gcc/binutils that supports the Now the question is:
The main problem here is that, on both Linux and Windows, Clang is calling GCC front-end with There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. cc @tejlmand There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @stephanosio yes, actually I used a cross compiler i486-elf to complete the link process on windows, rather than the llvm built-in linker. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
it seems that it's related to gcc version, I found a comment "gcc 8.x doesn't support -fuse-ld=lld option at all, it has been only added in http://gcc.gnu.org/r265940 for gcc 9" "/usr/lib64/ccache/gcc" -nostdlib -fuse-ld=lld -m32 -o dummy /tmp/dummy-675e45.o There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I used gcc 8.3 before. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. AFAICS, this change is not necessary. See https://github.com/zephyrproject-rtos/zephyr/pull/36753/files#r666941908 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes, I agree this. |
||
else() | ||
set(triple i686-pc-none-elf) | ||
set(triple i686-pc-linux-elf) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same here. |
||
endif() | ||
endif() | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like Clang defaults to
-fuse-ld=bfd
(i.e. binutils linker) forx86_64-pc-none-elf
andi686-pc-none-elf
targets; so, if any, we should be specifying-fuse-ld=bfd
here.Note that
-fuse-ld=bfd
depends on the GNU binutils being available on the host and, to my knowledge, there is currently no readily available Windows binutils/gcc distribution supporting thex86_64-pc-none-elf
andi686-pc-none-elf
targets.For now, users shall be responsible for providing their own Windows binutils/gcc build that supports
x86_64-pc-none-elf
andi686-pc-none-elf
targets. In the future, the Windows Zephyr SDK distribution shall provide the binutils/gcc for use in this case.As a proof of concept, you can try using the following Windows Zephyr SDK test build:
https://github.com/zephyrproject-rtos/crosstool-ng-old/releases/download/zephyr-crosstool-ng-1.24.0.4/zephyr-crosstool-ng-1.24.0.4_windows-x86_64_x86_64-zephyr-elf.zip
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if we don't use i686-pc-linux-elf, this option -fuse-ld=lld is not necessary too.
because this is more about environment issues, we need to ensure there is a gnu linker which supports i686-pc-none-elf, then it will invoke this linker by default and won't report error "program not executable".
I installed a cross compiler i486-elf on windows, it supports i686-pc-none-elf, just need to add it into system path, then it's ok to build zephyr binary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@stephanosio I used -fuse-ld=lld because I wanted to use the llvm built-in linker to complete link process firstly, but I found that both on linux and windows, it reported the same error as below, then I used another i486-elf-ld on windows to build binary.