arnetheduck / nlvm

LLVM-based compiler for the Nim language
Other
701 stars 41 forks source link

OSX report #32

Closed Araq closed 2 years ago

Araq commented 2 years ago

I know that OSX is not officially supported but here is how far I got: I followed the Linux instructions and got:

make
sh ./make-llvm.sh 14 0 0 sha \
        -DLLVM_BUILD_LLVM_DYLIB=1 \
        -DLLVM_LINK_LLVM_DYLIB=1 \
        -DLLVM_ENABLE_ASSERTIONS=1 \
        -DLLVM_INCLUDE_TESTS=Off \
        -DLLVM_INCLUDE_EXAMPLES=Off \
        -DLLVM_INCLUDE_BENCHMARKS=Off \
        -DCMAKE_BUILD_TYPE=RelWithDebInfo
ln: illegal option -- r

Feel free to close this issue. As I said, just fyi.

gushromp commented 2 years ago

UPDATE 2:

Ran the test suite and a lot of the tests are failing, unfortunately. Some due to linker errors, some due to segfaults, and some due to this not being Linux :)

https://gist.github.com/gushromp/f0e169562bf40886d5465a549d8509b8


UPDATE:

Got a simple Nim program to build successfuly! :)

I added nlvmbase-arm64-MacOSX.ll with the (hopefully) correct triple and datalayout and needed to change linker parameters in lllink.nim to -fuse-ld=lld and got a working executable.

let a = 5 + 3
echo "Hello world from NLVM! Result is ", a

> ./test
Hello world from NLVM! Result is 8

With using macOS's built-in ld, I would get the following error:

Hint:  [Link]
Undefined symbols for architecture arm64:
  "_nlvmEHPersonality", referenced from:
      Dwarf Exception Unwind Info (__eh_frame) in test.o
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

I'll clean up a lot of the mess I've made by testing this stuff and prepare a PR.


@arnetheduck I've managed to build nlvm on macOS, but I still can't succesfully compile with it.

@Araq I thought I'd tag you too since you authored this issue originally and thought you'd be interested.


This is how far I've got on macOS, after installing all the prerequisite libraries via Homebrew.

1) Changed line 42 of make-llvm.sh to ln -sf ../../$LLD_ROOT lld 2) Changed line 52 of make-llvm.sh to cp -a libunwind-$VER2.src/include/mach-o $LLD_ROOT/include 3) Removed -DLLVM_USE_LINKER=gold from line 61 of make-llvm.sh because gold only supports ELF.

Those changes make it possible to build LLVM and Nim using make.

Then I ran into the following error, during compilation of llvm/wrapper.cc:

CC: wrapper
CC: ../Nim/compiler/commands.nim
In file included from /Users/blashyrk/Documents/source/nlvm/llvm/wrapper.cc:1:
In file included from ../ext/llvm-14.0.0.src/include/llvm/IR/Constants.h:23:
In file included from ../ext/llvm-14.0.0.src/include/llvm/ADT/APFloat.h:18:
In file included from ../ext/llvm-14.0.0.src/include/llvm/ADT/APInt.h:19:
../ext/llvm-14.0.0.src/include/llvm/Support/MathExtras.h:57:1: error: unknown type name 'constexpr'
constexpr double e          = 2.7182818284590452354, // (0x1.5bf0a8b145749P+1) https://oeis.org/A001113
^
../ext/llvm-14.0.0.src/include/llvm/Support/MathExtras.h:58:24: error: expected ';' after top level declarator
                 egamma     = .57721566490153286061, // (0x1.2788cfc6fb619P-1) https://oeis.org/A001620
                       ^
                       ;
../ext/llvm-14.0.0.src/include/llvm/Support/MathExtras.h:72:1: error: unknown type name 'constexpr'
constexpr float ef          = 2.71828183F, // (0x1.5bf0a8P+1) https://oeis.org/A001113

I tried fiddling with nlvm/nim.cfg in various ways, since I needed to pass -std=c++14 somehow, but it appears that clang is more strinct than gcc in this regard since if you try to pass it to C compilation units, it fails with an error saying that that flag is not available for C.

The only solution I found is to edit llvm/llvm.nim and change the relevant line to:

{.compile("wrapper.cpp", "-std=c++14").}

I also had to change the constant libLLVM-14.so to libLLVM-14.dylib and manually symlink libLLVM.dylib to libLLVM-14.dylib, as well as the formatting of passing some linker flags such as {.passL: "-Wl,'-rpath=$ORIGIN/" & LLVMOut & "lib/'".}

With these changes, nlvm compiled and linked successfully. Seems there are some differences between ELF and Mach-O RPATH since I now ran into a runtime error:

  Referenced from: /Users/blashyrk/Documents/source/nlvm/nlvm/nlvm
  Reason: tried: '$ORIGIN/../ext/llvm-14.0.0.src/sha/lib/libLLVM.dylib' (no such file), '$ORIGIN/../ext/llvm-14.0.0.src/sha/lib/libLLVM.dylib' (no such file), '/usr/local/lib/libLLVM.dylib' (no such file), '/usr/lib/libLLVM.dylib' (no such file)

... even thought the file was there (assuming the $ORIGIN thing is not ELF-only). I simply symlinked to /usr/lib/libLLVM.dylib to temporarily fix the issue.


After all that I tried to compile this simple input file:

let a = 5 + 3

and this is the output I get:

> nlvm/nlvm c --verbosity:3 test/test.nim

/Users/blashyrk/Documents/source/nlvm/Nim/config/nim.cfg(47, 3) Hint: added path: '/opt/nimble/pkgs2/' [Path]
    nimblepath="/opt/nimble/pkgs2/"
    ^
/Users/blashyrk/Documents/source/nlvm/Nim/compiler/nimblecmd.nim(139, 12) compiler msg initiated here [MsgOrigin]
/Users/blashyrk/Documents/source/nlvm/Nim/config/nim.cfg(48, 3) Hint: added path: '/opt/nimble/pkgs/' [Path]
    nimblepath="/opt/nimble/pkgs/"
    ^
/Users/blashyrk/Documents/source/nlvm/Nim/compiler/nimblecmd.nim(139, 12) compiler msg initiated here [MsgOrigin]
/Users/blashyrk/Documents/source/nlvm/Nim/config/nim.cfg(52, 1) Hint: added path: '/Users/blashyrk/.nimble/pkgs2/' [Path]
  nimblepath="$home/.nimble/pkgs2/"
  ^
/Users/blashyrk/Documents/source/nlvm/Nim/compiler/nimblecmd.nim(139, 12) compiler msg initiated here [MsgOrigin]
/Users/blashyrk/Documents/source/nlvm/Nim/config/nim.cfg(53, 1) Hint: added path: '/Users/blashyrk/.nimble/pkgs/' [Path]
  nimblepath="$home/.nimble/pkgs/"
  ^
/Users/blashyrk/Documents/source/nlvm/Nim/compiler/nimblecmd.nim(139, 12) compiler msg initiated here [MsgOrigin]
Hint: used config file '/Users/blashyrk/Documents/source/nlvm/Nim/config/nim.cfg' [Conf]
/Users/blashyrk/Documents/source/nlvm/Nim/compiler/nimconf.nim(297, 17) compiler msg initiated here [MsgOrigin]
Hint: used config file '/Users/blashyrk/Documents/source/nlvm/Nim/config/config.nims' [Conf]
/Users/blashyrk/Documents/source/nlvm/Nim/compiler/nimconf.nim(297, 17) compiler msg initiated here [MsgOrigin]
.............................................................
/Users/blashyrk/Documents/source/nlvm/test/test.nim(1, 1) Hint: (module: 26, symId: 0, typeId: 2, sealed: false) [ProcessingStmt]
  let a = 5 + 3
  ^
/Users/blashyrk/Documents/source/nlvm/Nim/compiler/passaux.nim(29, 10) compiler msg initiated here [MsgOrigin]
/Users/blashyrk/Documents/source/nlvm/test/test.nim(1, 5) Hint: global variable declared here [GlobalVar]
  let a = 5 + 3
      ^
/Users/blashyrk/Documents/source/nlvm/Nim/compiler/semstmts.nim(662, 16) compiler msg initiated here [MsgOrigin]
Hint: (module: 26, symId: 1, typeId: 6, sealed: false) [ProcessingStmt]
/Users/blashyrk/Documents/source/nlvm/Nim/compiler/passaux.nim(29, 10) compiler msg initiated here [MsgOrigin]
/Users/blashyrk/Documents/source/nlvm/test/test.nim(1, 5) Hint: 'a' is declared but not used [XDeclaredButNotUsed]
  let a = 5 + 3
      ^
/Users/blashyrk/Documents/source/nlvm/Nim/compiler/lookups.nim(294, 12) compiler msg initiated here [MsgOrigin]

No such file or directory

I didn't expect it to run as I see that there's no Mac targets defined anywhere in files such as llplatform.nim, lllink.nim etc. But it's a start :)

Most of the steps required to build LLVM, Nim and NLVM on Mac are very simple script changes and platform-specific constants, so if you'd like me to create a tracking PR/issue with these changes, I can do so.


Sidenote:

The {.compile.} pragma is broken when passing compiler arguments if you also include a space, meaning

{.compile("wrapper.cpp", "-std=c++14").}

works, but

{.compile ("wrapper.cpp", "-std=c++14").}

doesn't, because it appends the passed parameter to the -o 'outputpath' instead of passing it as a separate flag. I do not know if this is also/still in upstream Nim, that's why I'm mentioning it here instead of creating an issue there.

Araq commented 2 years ago

The {.compile.} pragma is broken when passing compiler arguments if you also include a space, meaning

It's not broken, passing a tuple to compile is different than passing two arguments.

astrolemonade commented 12 months ago

Hey! I've been trying to build nlvm on Mac but I receive the mentioned error, I am using the latest commit of nlvm: https://github.com/arnetheduck/nlvm/commit/f3a9bb42da9ed29c38f98c7d60c787ae5b55368c

image