google / mlir-hs

Haskell bindings for MLIR
Apache License 2.0
92 stars 16 forks source link

Building On Windows? #50

Closed MilesLitteral closed 5 months ago

MilesLitteral commented 9 months ago

Hi, Ive been trying to build the project on Windows and made a lot of headway learning what would be necessary to build mlir-hs with minimal pain; I was curious if anyone had any insights or suggestions to limit any issues (like the fact building LLVM dylibs are currently unsupported on Windows.)

jpienaar commented 8 months ago

Unfortunately I haven't tried on Windows. We did have a different approach where we built a new library instead of trying to use upstream that could have worked here.

Would be useful to incorporate what you find though.

MilesLitteral commented 8 months ago

I wrote the following batch script (.bat) that you can run in the root mlir-hs directory to build LLVM/MLIR for windows. Presuming Ninja and cmake are installed and I don't mind opening a pull request to add this script for ease of use to the repo:

REM cd should be  ".\mlir-hs-master\"
set root_dir=%cd%\llvm-project

if exist %root_dir% (
  echo "LLVM project dir found, continue"
) else (
  echo "LLVM Project dir not found, cloning and building"
  echo "Put the follwing on $PATH: %root_dir%"
  git clone https://github.com/llvm/llvm-project.git 
)

md %root_dir%\build 
cd %root_dir%\build 
call cmake %root_dir%\llvm -G "Ninja" -DCMAKE_INSTALL_PREFIX="%root_dir%\build\install" -DLLVM_ENABLE_PROJECTS=mlir -DLLVM_TARGETS_TO_BUILD="host" -DCMAKE_BUILD_TYPE=Release  -DLLVM_ENABLE_ASSERTIONS=ON -DLLVM_ENABLE_RTTI=ON -DLLVM_ENABLE_ZLIB=OFF -DLLVM_INSTALL_UTILS=ON -DLLVM_ENABLE_LIBEDIT=OFF 
call cmake --build . --config Release 
call cmake --build . --config Release --target install 
call cmake --build . --config Release --target check-mlir

I was then able to get mlir to build, put it on PATH, and function on windows. My current problem is I can't get the mlir-hs library itself to build because in setup.hs when cabal attempts to use getLLVMConfig (specifically llvmConfigProgram to learn what version of llvm-config is available) the function fails with no output from llvm-config. Yet when you run the same command (llvm-config --version) in powershell it works just fine. So I am now working through trying to get setup.hs to correctly capture llvm-config's output in windows. This is the console output of the point I'm stuck at:

Linking C:\\Users\\Me\\Projects\\mlir-hs-main\\.stack-work\\dist\\274b403a\\setup\\setup.exe ...
Warning: cannot determine version of C:\Users\Me\Projects\mlir-hs-main\llvm-project\build\bin\llvm-config.exe: ""
setup.EXE: The program 'llvm-config' version ==18.* is required but the
version of  C:\Users\Me\Projects\mlir-hs-main\llvm-project\build\bin\llvm-config.exe
could not be determined.

Error: [S-7282]
       Stack failed to execute the build plan.

       While executing the build plan, Stack encountered the error:

You can run the llvm-config built with the .bat just fine in cmd or powershell if it's on path
C:\Users\Me\Projects\mlir-hs-main> llvm-config --version
18.0.0git
MilesLitteral commented 8 months ago

I got further with building on Windows with a simplified approach. The manual steps I described is what I would now call "the hard way". You can leverage mingw directly to simplify installation (Works for any version before version 18, you have to build LLVM manually in MinGW to get later versions at time of writing): stack exec -- pacman -S mingw-w64-x86_64-mlir. However this leads to a different error, in which it can't find an llvm.lib and I'm currently unsure if any form of .dll could be linked. I intend to continue experimenting.

This is the error, it is generated when running stack build or stack install:

PS C:\Users\Me\OneDrive\Desktop\Projects\mlir-hs-main> stack build
mlir-hs> configure (lib)
C:/Users/Me/AppData/Local/Programs/stack/x86_64-windows/ghc-8.10.4/mingw/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: cannot find -lLLVM
collect2.exe: error: ld returned 1 exit status

EDIT: Building with cabal results in no success, regardless of version. Windows will fail because it will look for a library that doesn't exist even if you built it separately, install it in a visible place, and put it on $PATH. It doesn't take libLLVM.dll or libMLIR.dll or libLLVM-<version>.dll and seems to want a literal .lib file...like it literally wants ld.exe -lLLVM to work as if this is linux..? Looking into it currently, see below the error for what I discovered.

PS C:\Users\Me\OneDrive\Desktop\Projects\mlir-hs-main> cabal build
Build profile: -w ghc-8.10.4 -O1
In order, the following will be built (use -v for more details):
 - mlir-hs-0.1.0.0 (lib:mlir-hs, exe:mlir-hs-test) (first run)
C:/ProgramData/mingw64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/13.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: cannot find -lLLVM: No such file or directory
collect2.exe: error: ld returned 1 exit status

EDIT2: On Windows mingw-64w's c++ compiler is used, which can't resolve -lLLVM to the current LLVM library that is available on OS. if you give it the literal flag (in this case "-lLLVM-17" is the correct flag which points to the LLVM version available to mingw). The library builds if you then use the corresponding compatible mlir-hs version. Perhaps a hotfix could be written in Setup.hs which adds the version to the "-lLLVM" flag if the environment is Windows.

This works correctly:
c++ "C:/Users/Me/OneDrive/Desktop/Projects/mlir-hs-main/tblgen/mlir-hs-tblgen.cc"      
        "C:/Users/Me/OneDrive/Desktop/Projects/mlir-hs-main/tblgen/hs-generators.cc"  
        "-IC:/ghcup/msys64/mingw64/include" "-std=c++17" "-fno-exceptions" "-funwind-tables"
        "-D_FILE_OFFSET_BITS=64" "-D__STDC_CONSTANT_MACROS" 
        "-D__STDC_FORMAT_MACROS" 
        "-D__STDC_LIMIT_MACROS" 
        "-LC:/ghcup/msys64/mingw64/lib"
        "-lMLIR" 
        "-lLLVM-17"
        "-lMLIRTableGen"  
        "-lLLVMTableGen" 
        "-o" "C:\Users\Me\OneDrive\Desktop\Projects\mlir-hs-main\.bin/mlir-hs-tblgen"