Skip to content
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

WIP: Initial changes to support macOS build #35

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
nlvm/nlvm
nlvm/nlvmr
nlvm/*.dSYM
nimcache
*.s
/nlvm/nlvm.self
Expand All @@ -22,3 +23,4 @@ tools
dist/
/megatest.nim
.vscode
.DS_Store
2 changes: 1 addition & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[submodule "Nim"]
path = Nim
url = https://github.com/arnetheduck/Nim.git
url = https://github.com/gushromp/Nim.git
branch = nlvm
13 changes: 11 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,21 @@ LLVM_PAT=0

LLVM_DIR=llvm-$(LLVM_MAJ).$(LLVM_MIN).$(LLVM_PAT).src

OS := $(shell uname)
ifeq ($(OS),Darwin)
SHALIB_EXT := dylib
else ifeq ($(OS),Linux)
SHALIB_EXT := so
else
$(error "Unsupported OS. Exiting.")
endif

ifdef STATIC_LLVM
NLVMCFLAGS=-d:staticLLVM --dynliboverrideall
LLVM_DEP=ext/$(LLVM_DIR)/sta/bin/llvm-config
export PATH := $(PWD)/ext/$(LLVM_DIR)/sta/bin:$(PATH)
else
LLVM_DEP=ext/$(LLVM_DIR)/sha/lib/libLLVM-$(LLVM_MAJ).so
LLVM_DEP=ext/$(LLVM_DIR)/sha/lib/libLLVM-$(LLVM_MAJ).$(SHALIB_EXT)
NLVMCFLAGS?=
endif

Expand Down Expand Up @@ -98,7 +107,7 @@ self: nlvm/nlvm.self
clean:
rm -rf $(NLVMC) $(NLVMR) nlvm/nlvm.ll nlvm/nlvm.self.ll nlvm/nlvm.self Nim/testresults/

ext/$(LLVM_DIR)/sha/lib/libLLVM-$(LLVM_MAJ).so:
ext/$(LLVM_DIR)/sha/lib/libLLVM-$(LLVM_MAJ).$(SHALIB_EXT):
sh ./make-llvm.sh $(LLVM_MAJ) $(LLVM_MIN) $(LLVM_PAT) sha \
-DLLVM_BUILD_LLVM_DYLIB=1 \
-DLLVM_LINK_LLVM_DYLIB=1 \
Expand Down
2 changes: 1 addition & 1 deletion Nim
22 changes: 21 additions & 1 deletion dl-llvm.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,26 @@
#!/bin/bash

OS="`uname`"
ARCH="`uname -m`"

if [ $ARCH == "arm64" ]; then
echo "LLVM doesn't provide precompiled binaries for arm64 yet :(. Remove STATIC_LLVM=1 and try again. Exiting..."
exit 1
fi

case $OS in
'Linux')
SUFFIX="$ARCH-linux-gnu-ubuntu-18.04"
;;
'Darwin')
SUFFIX="$ARCH-apple-darwin"
;;
*)
echo "Unsupported OS: $OS"
exit 1
;;
esac

[ $# -ge 4 ] || {
echo "$0 major minor patch output_dir"
exit 1
Expand All @@ -13,7 +34,6 @@ cd ext
VER="$1.$2"
VER2="$VER.$3"
TGT="$4"
SUFFIX="x86_64-linux-gnu-ubuntu-18.04"

LLVM_ROOT=llvm-$VER2.src

Expand Down
75 changes: 60 additions & 15 deletions llvm/llvm.nim
Original file line number Diff line number Diff line change
Expand Up @@ -3,42 +3,75 @@
# See the LICENSE file for license info (doh!)

import strutils
import strformat
import os

static:
if not (defined(linux) or defined(macosx)):
echo "Unsupported platform. Exiting."
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there's no need to quit in general, even if there's no explicit support for a platform - ie if it breaks, it'll break but maybe it won't

quit(-1)

const
LLVMLib = "libLLVM-14.so"
LLVMRoot = "../ext/llvm-14.0.0.src/"
LLDRoot = "../ext/lld-14.0.0.src/"
Root = currentSourcePath.parentDir().parentDir()
LLVMVersion* = "14.0.0"
LLVMRoot = fmt"{Root}/ext/llvm-{LLVMVersion}.src"
LLDRoot = fmt"{Root}/ext/lld-{LLVMVersion}.src"

{.passL: "-llldELF" .}
{.passL: "-llldWasm" .}
{.passL: "-llldMinGW" .}
{.passL: "-llldCommon" .}
{.passL: "-llldMachO" .}
{.passL: "-lz" .}
when defined(macosx):
{.passL: "-lxar" .}

when defined(staticLLVM):
const
LLVMOut = LLVMRoot & "sta/"
LLVMOut = fmt"{LLVMRoot}/sta"

{.passL: gorge(fmt"{LLVMRoot}/sta/bin/llvm-config --libs all").}

{.passL: gorge(LLVMRoot & "sta/bin/llvm-config --libs all").}
when defined(macosx):
const SDKRoot = gorge("xcrun --sdk macosx --show-sdk-path")
{.passC: fmt"-isysroot{SDKRoot}".}
{.passL: fmt"-Wl,-syslibroot,{SDKRoot}".}

else:
const
LLVMOut = LLVMRoot & "sha/"
LLVMOut = fmt"{LLVMRoot}/sha"

when defined(macosx):
{.passL: "-lLLVM".}
{.passL: fmt"-Wl,-rpath,@loader_path/../ext/llvm-{LLVMVersion}.src/sha/lib".}

elif defined(linux):
{.passL: "-lLLVM-14".}
{.passL: fmt"-Wl,'-rpath=$ORIGIN/../ext/llvm-{LLVMVersion}.src/sha/lib'".}


{.passL: "-lLLVM-14".}
{.passL: "-Wl,'-rpath=$ORIGIN/" & LLVMOut & "lib/'".}
{.passC: fmt"-I{LLVMRoot}/include".}
{.passC: fmt"-I{LLVMOut}/include".}

{.passC: "-I" & LLVMRoot & "include".}
{.passC: "-I" & LLVMOut & "include".}
{.passC: fmt"-I{LLDRoot}/include".}

{.passC: "-I" & LLDRoot & "include".}
when defined(linux):
{.passL: "-Wl,--as-needed".}
else:
{.passL: "-Wl".}

{.passL: gorge(fmt"{LLVMOut}/bin/llvm-config --ldflags").}
{.passL: gorge(fmt"{LLVMOut}/bin/llvm-config --system-libs").}

{.passL: "-Wl,--as-needed".}
{.passL: gorge(LLVMOut & "bin/llvm-config --ldflags").}
{.passL: gorge(LLVMOut & "bin/llvm-config --system-libs").}
{.compile("wrapper.cc", "-std=c++14").}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and with a small upstream fix, this is not needed either: 4355022


{.compile: "wrapper.cc".}
when defined(linux):
const
LLVMLib = "libLLVM-14.so"
elif defined(macosx):
const
LLVMLib = "libLLVM.dylib"
LLDBinary* = fmt"{LLVMOut}/bin/ld64.lld"

# Includes and helpers for generated code
type
Expand Down Expand Up @@ -264,6 +297,18 @@ proc nimLLDLinkElf*(args: openArray[string]): string =
result = strip($tmp)
disposeMessage(tmp)

proc nimLLDLinkMachO*(
argv: cstringArray, argc: cint): cstring {.importc: "LLVMNimLLDLinkMachO".}

proc nimLLDLinkMachO*(args: openArray[string]): string =
let argv = allocCStringArray(args)
defer: deallocCStringArray(argv)

let tmp = nimLLDLinkMachO(argv, args.len.cint)
if not tmp.isNil:
result = strip($tmp)
disposeMessage(tmp)

proc nimLLDLinkWasm*(
argv: cstringArray, argc: cint): cstring {.importc: "LLVMNimLLDLinkWasm".}

Expand Down
28 changes: 23 additions & 5 deletions llvm/wrapper.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
#include "llvm-c/Types.h"
#include "llvm-c/Core.h"

#include <iostream>

using namespace llvm;

typedef DIBuilder *LLVMNimDIBuilderRef;
Expand Down Expand Up @@ -49,23 +51,39 @@ extern "C" const char* LLVMNimLLDLinkElf(const char **args, size_t arg_count) {
SmallVector<char, 128> osv, esv;
raw_svector_ostream os(osv), es(esv);

if (!lld::elf::link(array_ref_args, os, es, false, false)) {
if (lld::elf::link(array_ref_args, os, es, false, false)) {
osv.push_back(0);
return LLVMCreateMessage(&osv[0]);
} else {
esv.push_back(0);
return LLVMCreateMessage(&esv[0]);
}
}

extern "C" const char* LLVMNimLLDLinkMachO(const char **args, size_t arg_count) {
ArrayRef<const char *> array_ref_args(args, arg_count);
SmallVector<char, 128> osv, esv;
raw_svector_ostream os(osv), es(esv);

return nullptr;
if (lld::macho::link(array_ref_args, os, es, false, false)) {
osv.push_back(0);
return LLVMCreateMessage(&osv[0]);
} else {
esv.push_back(0);
return LLVMCreateMessage(&esv[0]);
}
}

extern "C" const char* LLVMNimLLDLinkWasm(const char **args, size_t arg_count) {
ArrayRef<const char *> array_ref_args(args, arg_count);
SmallVector<char, 128> osv, esv;
raw_svector_ostream os(osv), es(esv);

if (!lld::wasm::link(array_ref_args, os, es, false, false)) {
if (lld::wasm::link(array_ref_args, os, es, false, false)) {
osv.push_back(0);
return LLVMCreateMessage(&osv[0]);
} else {
esv.push_back(0);
return LLVMCreateMessage(&esv[0]);
}

return nullptr;
}
20 changes: 17 additions & 3 deletions make-llvm.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,20 @@
# Build llvm, as used in the Makefile
# A bit broken because it doesn't track cmake options and deps correctly

OS="`uname`"
case $OS in
'Linux')
ADDITIONAL_CMAKE_ARGS="-DLLVM_USE_LINKER=gold"
;;
'Darwin')
ADDITIONAL_CMAKE_ARGS=""
;;
*)
echo "Unsupported OS: $OS"
exit 1
;;
esac

[ $# -gt 4 ] || {
echo "$0 major minor patch output_dir cmake_options*"
exit 1
Expand Down Expand Up @@ -39,7 +53,7 @@ LLD_ROOT=lld-$VER2.src
[ -d $LLVM_ROOT/projects/lld ] || {
rm -rf $LLVM_ROOT/projects/lld
cd $LLVM_ROOT/projects
ln -sfr ../../$LLD_ROOT lld
ln -sf ../../$LLD_ROOT lld
cd ../..
}

Expand All @@ -49,7 +63,7 @@ LLD_ROOT=lld-$VER2.src

[ -f libunwind-$VER2/CMakeLists.txt ] || {
tar xf libunwind-$VER2.src.tar.xz
cp -ar libunwind-$VER2.src/include/mach-o $LLD_ROOT/include
cp -a libunwind-$VER2.src/include/mach-o $LLD_ROOT/include
}

cd $LLVM_ROOT
Expand All @@ -58,6 +72,6 @@ mkdir -p $TGT
cd $TGT

shift 4
cmake -GNinja -DLLVM_USE_LINKER=gold LLVM_INCLUDE_BENCHMARKS=OFF "$@" ..
cmake -GNinja "$@" ..
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should continue to use gold on linux and disable benchmarks everywhere

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah sorry I made ADDITIONAL_CMAKE_FLAGS variable on the top and forgot to add it back here. As for deleting LLVM_INCLUDE_BENCHMARKS, I did so because it's already passed from the Makefile to the script.


ninja
Loading