Compiling LLVM for P2 on Windows (it works!)
Supposedly this can work and have made a bit of progress:
Note: This may be all wrong!
Note2: This is probably a lot easier in Linux or Mac...
Install Visual Studio
- Add C++ Clange tools for Windows
- Add latest Win 11 SDK
Install Python
Install CMake
Install Git
Download LLVM P2
Extract "llvm-project-XXX" to somewhere
Create "build" folder under this folder
Run cmake, maybe like this:
cmake -G "Visual Studio 18 2026" -A x64 -Thost=x64 -DCMAKE_INSTALL_PREFIX=/opt/p2llvm -DLLVM_ENABLE_PROJECTS="lld;clang" -DCMAKE_BUILD_TYPE=Release -DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD=P2 -DLLVM_TARGETS_TO_BUILD="" ../llvm-project/llvm
Use Visual Studio to open "LLVM.slnx" solution.
Build solution. (takes forever)
Find clang.exe under \build\Release\bin
try to build something like:
clang -Os -ffunction-sections -fdata-sections -fno-jump-tables --target=p2 -I .\libc\include -I .\ -o hello.o -c hello.c
Here's where I'm stuck... Got a .o file but the linker doesn't seem to work :{
Update: Seems all needed was two .a files (gifted from @rogloh ) to make it work. Had no luck generating these myself in either Windows or Linux. Maybe build instructions for these are out of date or something…

Comments
Ok, starting over, something is horribly wrong...
On windows 10 or 11 you can install WSL to get an emulated Linux shell, which probably has higher chance of success with this sort of thing. Getting anything to work with CMake on windows is a hassle, even if it's not a massive project like LLVM.
It might be hopeless... Tried again and can compile but not link (again)...
Found something from 4 years ago where @iseries and maybe me? Got it working in windows …
https://forums.parallax.com/discussion/171962/llvm-backend-for-propeller-2/p5
Will try stuff in post #133 there next…
For linking as a separate step I tend to use Clang twice, with these options:
1) first compile only to get the .o file:
clang -c -Os -ffunction-sections -fdata-sections -fno-jump-tables --target=p2 -I .\libc\include -I .\ -o hello.o -c hello.c2) then link the .o to the .elf (you can combine multiple .o files here too if needed)
clang -v -Wl,-error-limit=0 -L /Users/roger/Applications/p2llvm/libp2/lib --target=p2 -Wl,--gc-sections -o hello.elf -Wl,--no-whole-archive -L /Users/roger/Applications/p2llvm/libc/lib hello.o-v prints actual linker options out,
-Wl,-error-limit=0 prints multiple errors before failing,
--target=p2 (P2 specific output)
-Wl,gc-sections passes --gc-sections to lld linker
-L /path/to/libs (use your path)
-Wl,--no-whole-archive (doesn't suck in the entire lib.a code when only a single function is accessed)
3) use loadp2 to send the .elf file to a P2 (it understands .elfs as well as binary files)
loadp2 -PATCH -f 160000000 -b 115200 -t hello.elfYou can also convert the .elf into a binary file if you want with this:
llvm-objcopy -O binary -j .text -j .rodata -j .data hello.elf hello.binNote this binary also needs to be patched when downloaded with loadp2 as I'm not sure that the LLVM toolchain building the startup code uses useful default startup frequencies or baud rates otherwise. I think it defaults to RCslow unless you call _clkset and _uart_init with some arguments. But if the binary is patched at the normal addresses it will use the desired values.
@rogloh Yeah, but it didn't work... Using Clang twice...
Trying now with that post #133 in other thread, mentioned above.
One hiccup is with this line:
cmake -S llvm -B build -DLLVM_ENABLE_PROJECTS="lld;clang" -DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD=P2 -DLLVM_TARGETS_TO_BUILD="" -DLLVM_COMPILER_JOBS="2" -Thost=x64Had to change llvm to ../llvm Hope that is right...
Says to do this:
Guess these are folders and not files? Don't have libp2.a, but do have folder libp2++...
Somehow got two build folders deep...
path=%path%;c:\opt\p2llvm\llvm-project\build\build\release\bin
Ok, can build, but stuck once again trying to turn .o into .elf:
Hmm ... Seems had same problem back in post #249 of other thread.
Will keep reading in hopes figured it out...
Ok, in post #255 or so seemed just copied the files needed, libc.a and libp2.a, from some link.
But, that link doesn't work anymore
Looking like libc.a and libp2.a have to be built on Linux...
But, think should be portable to Windows, not sure...
The python build script should be building the libp2.a and libc.a files for you. If it can build a customized llvm application which runs under Windows it can then use that to build and archive the lib files into static libraries. I can't see what would prevent it from running on Windows unless there is some config setup error or path error etc and remember that the build directory is not the same as the install directory. That multi-level folder nesting you have for the build folder may possibly have messed things up too given the python script uses these defaults:
DEBUG_BUILD_DIR = "llvm-project/build_debug"
RELEASE_BUILD_DIR = "llvm-project/build_release"
I think you might want to try to use Nikita's actual python script to install things. Windows has python3 available right?
First you need the --configure option to create Cmake settings. Seems like you already had those and built it separately.
Then you basically build everything, and if you do the --install option it will copy the llvm and library files it built in the build folders to the final install folder location nominated after they are built. At least that is what it does for me.
Don't pass the --skip_libc or --skip_libp2 option or it won't build these libraries. If you already have built llvm with Visual Studio you may be able to save time and skip the llvm toolcahin building step to avoid building it again using --skip_llvm option, but you would then also need to ensure that the RELEASE_BUILD_DIR points to the correct location on your PC so it will find the built files there.
In build.py here are the different options:
def main(): global build_dir parser = argparse.ArgumentParser(description='P2 LLVM Build Script') parser.add_argument('--configure', nargs='?', const=True, default=False) parser.add_argument('--skip_llvm', nargs='?', const=True, default=False) parser.add_argument('--skip_libc', nargs='?', const=True, default=False) parser.add_argument('--skip_libp2', nargs='?', const=True, default=False) parser.add_argument('--clean', nargs='?', const=True, default=False) parser.add_argument('--debug', nargs='?', const=True, default=False) parser.add_argument('--install', type=str, required=False) ...UPDATE: I just noticed you were not passing the -L option to nominate where to find the libraries in the linking step - see my prior post above.
C:\opt\p2llvm\llvm-project\build\build\Release>clang --target=p2 -Wl,--gc-sections -Wl,--print-gc-sections -o t0.elf t0.oYou will need to put that path in (relative to your own install folder). Without it there the linker won't know where to find these files. Also I have the p2.ld file present in the top level install folder of p2llvm and it seems to find it okay.

Think one thing that is wrong is the the visual studio project that cmake creates for this is rigged for wrong compiler…
Pretty sure these need to be built with the clang for P2…. Not sure how hard that will be change…
Maybe one can manually compile these things and the create the .a from all the .o files?
Maybe the above means that the Linux .a files should work in Windows?
If both compiled for P2, seems should..
It's been a long time since I built this project and I did not use any Linux to build it.
Everything compiles with Visual Studio but several things have changed since then. LLVM has been upgraded to a newer version.
I don't have my original build environment since my computer Died and had to get a new one which came with windows 11 plus had to reload most of my work. Have not reloaded this environment.
.a files are just archive files that are built similar to .o files.
Mike
Basically @Rayman you need to do this:
1) compile a custom LLVM using a host PC or Mac or Linux box to enable the "--target=p2" cross compiler feature in order to then compile for the P2 using it. You will first need a working native C++ compiler running on the host to do this. I used Clang on the Mac but in theory Visual Studio C++ should also be capable to build it if configured appropriately. It seems you were able to do this.
2) use this version of LLVM to build the target libp2.a and libc.a static libraries
3) compile projects for the P2 and link using Clang and lld (linker). For convenience the linker can be accessed indirectly via invoking Clang and passing the appropriate settings/paths to it.
I believe some of the custom lld linker settings might get hard coded into it during build time and not everything can be setup via the command line options. Maybe some paths were setup wrong if this fails to find the locations of libraries and linker scripts.
The entire build.py script file is meant to be able to handle this for you as it calls Cmake to build the needed libraries and (hopefully) also auto-configures it with the --configure option. However it may possibly need some customizing for Windows specific paths and tools (I'm not 100% sure as I don't have a Windows machine any more).
Think see problem with Python... It's trying to invoke "make.exe", which doesn't exist...
Can you find a Windows port of Make? GnuMake or something?
Think will just make these .a files in Linux and then copy to windows…
Try with msys2 https://www.msys2.org/ makes working with linux-like tools much easier on Windows.
Just tried with WSL and seems the Linux instructions are not good either.. Seems had to edit build.py to get anywhere...
Built Clang, but still no luck with libs..
Seems can't get it done in Windows or Linux
Think I'll wait until there are better instructions (or somebody gifts me the .a files)...
You can try these .a files but they were the modified ones I use to build MicroPython based on the changes I applied using the code in the zips from this post so YMMV.
https://forums.parallax.com/discussion/comment/1572778/#Comment_1572778
I'm not sure if these binary archived static libraries are compatible across host platforms, hopefully they will be given the target is the same.
These archive are created with the makefiles in those directories. They are clang compiled folder objects that are then packaged into an archive for consumption.
AR = llvm-ar
CC = clang
Mike
@rogloh Those seem to make it happy. Thanks!
Now, seems also missing p2.ld.. Searching for that now...
Ok, found p2.ld... Made an elf! Guess should see if it actually works...
Borrowed loadp2.exe from FlexProp and it works!
Build folder zips to 713 MB right now. This is mostly the bin output. Looks to be a lot of extraneous stuff, but hard to say. Guess will try to trim it down to essentials...
Good. Finally some progress. You can disassemble the code with
llvm-objdump -d file.elfassuming that got built with Clang. You can also see the symbols and what got included withllvm-objdump -x file.elf.Strangely I did a simple hello world and it was only 24844 bytes while yours was bigger at 78112 bytes. Maybe you included a bunch of other stuff?
❯ cat main.c #include <stdio.h> #include <propeller.h> int main(void) { _uart_init(63,62,115200,0); puts("hello world\n"); return 0; }Interestingly with this simple hello world program above I get a bunch of floating point stuff included. Presumably that is from the printf which might need to print floating point numbers?? Everything above $a00 is run from HUB RAM.
@rogloh Here are the files...