Skip to content
Closed
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
190 changes: 166 additions & 24 deletions Formula/l/llgo.rb
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
class Llgo < Formula
desc "Go compiler based on LLVM integrate with the C ecosystem and Python"
homepage "https://github.com/goplus/llgo"
url "https://github.com/goplus/llgo/archive/refs/tags/v0.11.5.tar.gz"
sha256 "e025993d12c1f5e49e5b8dcb31c0e8b349efe56970d1a23d6c089ebd10928c6b"
homepage "https://github.com/luoliwoshang/llgo"
url "https://github.com/luoliwoshang/llgo/archive/refs/tags/v0.12.13.tar.gz"
sha256 "13106bf7d4812e58a427a565ab7413c6d086d12c3dbfaf058f47908cbe0bb40c"
license "Apache-2.0"
head "https://github.com/goplus/llgo.git", branch: "main"
head "https://github.com/luoliwoshang/llgo.git", branch: "main"

livecheck do
url :stable
Expand All @@ -21,18 +21,21 @@ class Llgo < Formula
sha256 x86_64_linux: "2486bc3ddd7c27fe03c9ae10df73553c09b9f21b3d4dc94b55f99da632dbbf5f"
end

depends_on "cmake" => :build
depends_on "ninja" => :build
depends_on "python@3.13" => :build
depends_on "bdw-gc"
depends_on "go@1.24"
depends_on "libffi"
depends_on "libuv"
depends_on "lld@19"
depends_on "llvm@19"
depends_on "openssl@3"
depends_on "pkgconf"
uses_from_macos "zlib"

on_linux do
depends_on "libunwind"
resource "espressif-llvm" do
url "https://github.com/espressif/llvm-project.git",
revision: "xtensa_release_19.1.2",
shallow: true
end

def find_dep(name)
Expand All @@ -41,37 +44,151 @@ def find_dep(name)
end

def install
llvm = find_dep("llvm")
esp_clang_path = libexec/"crosscompile/clang"
local_llvm_config = esp_clang_path/"bin/llvm-config"
local_llvm_include = esp_clang_path/"include"
local_llvm_lib = esp_clang_path/"lib"
llvm_build_target_component = %w[clang llvm-config llvm-ar llvm-nm lld]

resource("espressif-llvm").stage do
mkdir "build" do
cmake_args = %w[
-G Ninja
-DCMAKE_BUILD_TYPE=Release
-DLLVM_TARGETS_TO_BUILD=X86;ARM;AArch64;AVR;Mips;RISCV;WebAssembly
-DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD=Xtensa
-DLLVM_ENABLE_PROJECTS=clang;lld
-DLLVM_ENABLE_RUNTIMES=compiler-rt;libcxx;libcxxabi;libunwind
-DLLVM_POLLY_LINK_INTO_TOOLS=ON
-DLLVM_BUILD_EXTERNAL_COMPILER_RT=ON
-DLLVM_ENABLE_EH=ON
-DLLVM_ENABLE_RTTI=ON
-DLLVM_INCLUDE_DOCS=OFF
-DLLVM_INCLUDE_EXAMPLES=OFF
-DLLVM_INCLUDE_TESTS=OFF
-DLLVM_INCLUDE_BENCHMARKS=OFF
-DLLVM_BUILD_DOCS=OFF
-DLLVM_ENABLE_DOXYGEN=OFF
-DLLVM_INSTALL_UTILS=OFF
-DLLVM_ENABLE_Z3_SOLVER=OFF
-DLLVM_OPTIMIZED_TABLEGEN=ON
-DLLVM_USE_RELATIVE_PATHS_IN_FILES=ON
-DLLVM_SOURCE_PREFIX=.
-DLIBCXX_INSTALL_MODULES=ON
-DCLANG_FORCE_MATCHING_LIBCLANG_SOVERSION=OFF
-DCOMPILER_RT_BUILD_SANITIZERS=OFF
-DCOMPILER_RT_BUILD_XRAY=OFF
-DCOMPILER_RT_BUILD_LIBFUZZER=OFF
-DCOMPILER_RT_BUILD_PROFILE=OFF
-DCOMPILER_RT_BUILD_MEMPROF=OFF
-DCOMPILER_RT_BUILD_ORC=OFF
-DCOMPILER_RT_BUILD_GWP_ASAN=OFF
-DCOMPILER_RT_BUILD_CTX_PROFILE=OFF
-DCMAKE_POSITION_INDEPENDENT_CODE=ON
-DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=OFF
-DCOMPILER_RT_DEFAULT_TARGET_ONLY=ON
-DCOMPILER_RT_USE_BUILTINS_LIBRARY=ON
-DLIBCXX_ENABLE_STATIC_ABI_LIBRARY=ON
-DLIBCXX_STATICALLY_LINK_ABI_IN_SHARED_LIBRARY=OFF
-DLIBCXX_STATICALLY_LINK_ABI_IN_STATIC_LIBRARY=ON
-DLIBCXX_USE_COMPILER_RT=ON
-DLIBCXX_HAS_ATOMIC_LIB=OFF
-DLIBCXXABI_ENABLE_STATIC_UNWINDER=ON
-DLIBCXXABI_STATICALLY_LINK_UNWINDER_IN_SHARED_LIBRARY=OFF
-DLIBCXXABI_STATICALLY_LINK_UNWINDER_IN_STATIC_LIBRARY=ON
-DLIBCXXABI_USE_COMPILER_RT=ON
-DLIBCXXABI_USE_LLVM_UNWINDER=ON
-DLIBUNWIND_USE_COMPILER_RT=ON
-DSANITIZER_CXX_ABI=libc++
-DSANITIZER_TEST_CXX=libc++
-DLLVM_LINK_LLVM_DYLIB=ON
-DCLANG_LINK_CLANG_DYLIB=ON
-DCMAKE_STRIP=/usr/bin/strip
]

# Add macOS-specific arguments
cmake_args += if OS.mac?
%W[
-DLLVM_BUILD_LLVM_C_DYLIB=ON
-DLLVM_ENABLE_LIBCXX=ON
-DLIBCXX_PSTL_BACKEND=libdispatch
-DCMAKE_OSX_SYSROOT=#{MacOS.sdk_path}
-DCMAKE_OSX_ARCHITECTURES=#{Hardware::CPU.arch}
-DLIBCXXABI_USE_SYSTEM_LIBS=ON
]
else
%w[
-DLLVM_ENABLE_LIBXML2=OFF
-DLLVM_ENABLE_LIBCXX=OFF
-DCLANG_DEFAULT_CXX_STDLIB=libstdc++
-DLLVM_BUILD_LLVM_DYLIB=ON
-DCOMPILER_RT_USE_LLVM_UNWINDER=ON
]
end

cmake_args += %w[
-DLLVM_INCLUDE_TESTS=OFF
-DLLVM_ENABLE_TERMINFO=OFF
-DLLVM_ENABLE_ZSTD=OFF
-DLLVM_ENABLE_LIBEDIT=OFF
-DLLVM_ENABLE_Z3_SOLVER=OFF
-DLLVM_ENABLE_OCAMLDOC=OFF
-DLLVM_ENABLE_LIBXML2=OFF
-DLLVM_TOOL_CLANG_TOOLS_EXTRA_BUILD=OFF
-DCLANG_ENABLE_ARCMT=OFF
]
cmake_args << "-DCMAKE_INSTALL_PREFIX=#{esp_clang_path}"

# Fix rpath for libc++ libraries to pass Homebrew linkage tests
# Without @loader_path, libc++.1.0.dylib and libc++abi.1.0.dylib fail
# brew linkage --cached --test --strict with "Files with missing rpath" error
cmake_args << "-DRUNTIMES_CMAKE_ARGS=-DCMAKE_INSTALL_RPATH=#{rpath}"

system "cmake", *cmake_args, "../llvm"

# Build with all available cores
system "ninja", "-j#{ENV.make_jobs}", *llvm_build_target_component
system "ninja", "install"
end
end

ldflags = %W[
-s -w
-X github.com/goplus/llgo/internal/env.buildVersion=v#{version}
-X github.com/goplus/llgo/internal/env.buildTime=#{time.iso8601}
-X github.com/goplus/llgo/xtool/env/llvm.ldLLVMConfigBin=#{llvm.opt_bin/"llvm-config"}
-X github.com/goplus/llgo/xtool/env/llvm.ldLLVMConfigBin=#{local_llvm_config}
]
tags = nil

ENV.prepend "CGO_CXXFLAGS", "-std=c++17"
ENV.prepend "CGO_LDFLAGS", "-L#{local_llvm_lib} -lLLVM -Wl,-rpath,#{local_llvm_lib}"
if OS.linux?
ENV.prepend "CGO_CPPFLAGS",
"-I#{llvm.opt_include} " \
"-I#{local_llvm_include} " \
"-D_GNU_SOURCE " \
"-D__STDC_CONSTANT_MACROS " \
"-D__STDC_FORMAT_MACROS " \
"-D__STDC_LIMIT_MACROS"
ENV.prepend "CGO_LDFLAGS", "-L#{llvm.opt_lib} -lLLVM"
tags = "byollvm"
else
ENV.prepend "CGO_CPPFLAGS", "-I#{local_llvm_include}"
end

system "go", "build", *std_go_args(ldflags:, tags:), "-o", libexec/"bin/", "./cmd/llgo"
ohai "CGO_CXXFLAGS: #{ENV["CGO_CXXFLAGS"]}"
ohai "CGO_CPPFLAGS: #{ENV["CGO_CPPFLAGS"]}"
ohai "CGO_LDFLAGS: #{ENV["CGO_LDFLAGS"]}"
ohai "Start Building LLGO..."

# byollvm to use custom llvm
system "go", "build", *std_go_args(ldflags: ldflags, tags: "byollvm"), "-o", libexec/"bin/", "./cmd/llgo"

libexec.install "LICENSE", "README.md", "go.mod", "go.sum", "runtime"
libexec.install "LICENSE", "README.md", "go.mod", "go.sum", "runtime", "targets"

path_deps = %w[lld go pkgconf].map { |name| find_dep(name).opt_bin }
path_deps << llvm.opt_bin
path_deps = %w[go pkgconf].map { |name| find_dep(name).opt_bin }
path_deps << (esp_clang_path/"bin")
script_env = { PATH: "#{path_deps.join(":")}:$PATH" }

if OS.linux?
libunwind = find_dep("libunwind")
script_env[:CFLAGS] = "-I#{libunwind.opt_include} $CFLAGS"
script_env[:LDFLAGS] = "-L#{libunwind.opt_lib} -rpath #{libunwind.opt_lib} $LDFLAGS"
script_env[:CFLAGS] = "-I#{local_llvm_include} $CFLAGS"
script_env[:LDFLAGS] = "-L#{local_llvm_lib} $LDFLAGS"
end

(libexec/"bin").children.each do |f|
Expand All @@ -93,13 +210,18 @@ def install
bdwgc = find_dep("bdw-gc")
ENV.prepend_path "LD_LIBRARY_PATH", bdwgc.opt_lib

ohai "CCFLAGS: #{ENV["CCFLAGS"]}"
ohai "CFLAGS: #{ENV["CFLAGS"]}"
ohai "LDFLAGS: #{ENV["LDFLAGS"]}"

(testpath/"hello.go").write <<~GO
package main

import (
"fmt"

"github.com/goplus/lib/c"
"github.com/goplus/lib/cpp/std"
)

func Foo() string {
Expand All @@ -109,6 +231,7 @@ def install
func main() {
fmt.Println("Hello LLGo by fmt.Println")
c.Printf(c.Str("Hello LLGo by c.Printf\\n"))
c.Printf(std.Str("Hello LLGo by cpp/std.Str\\n").CStr())
}
GO
(testpath/"hello_test.go").write <<~GO
Expand All @@ -130,14 +253,33 @@ module hello
system go.opt_bin/"go", "get", "github.com/goplus/lib"
# Test llgo run
assert_equal "Hello LLGo by fmt.Println\n" \
"Hello LLGo by c.Printf\n",
shell_output("#{bin}/llgo run .")
"Hello LLGo by c.Printf\n" \
"Hello LLGo by cpp/std.Str\n",
shell_output("#{bin}/llgo run -v .")
# Test llgo build
system bin/"llgo", "build", "-o", "hello", "."
assert_equal "Hello LLGo by fmt.Println\n" \
"Hello LLGo by c.Printf\n",
"Hello LLGo by c.Printf\n" \
"Hello LLGo by cpp/std.Str\n",
shell_output("./hello")
# Test llgo test
assert_match "PASS", shell_output("#{bin}/llgo test .")

# Test embed targets
# Homebrew sets LDFLAGS with macOS-specific flags (-F/opt/homebrew/Frameworks,
# -Wl,-headerpad_max_install_names, -isysroot) that are incompatible with
# ld.lld when cross-compiling for embedded targets. Clear them.
with_env("LDFLAGS" => "") do
(testpath/"emb"/"main.go").write <<~GO
package main

func main() {
}
GO
cd testpath/"emb" do
system bin/"llgo", "build", "-v", "-target", "esp32-coreboard-v2", "-o", "demo.out", "."
assert_path_exists testpath/"emb"/"demo.out.bin"
end
end
end
end
Loading