diff --git a/.gitignore b/.gitignore
index dd191b234..968f9e7c2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,5 @@
+*.a
+*.lib
*.pyc
*.pyd
*.o
@@ -15,3 +17,4 @@ MANIFEST
docs/_build/
docs/gh-pages/
.*.swp
+.vscode/
\ No newline at end of file
diff --git a/buildscripts/incremental/setup_conda_environment.sh b/buildscripts/incremental/setup_conda_environment.sh
index 20008b264..682f9b16a 100755
--- a/buildscripts/incremental/setup_conda_environment.sh
+++ b/buildscripts/incremental/setup_conda_environment.sh
@@ -26,13 +26,15 @@ set +v
source activate $CONDA_ENV
set -v
-# Install llvmdev (separate channel, for now)
-$CONDA_INSTALL -c numba/label/dev llvmdev="14.*"
-
-# Install the compiler toolchain, for osx, bootstrapping needed
-# which happens in build.sh
if [[ $(uname) == Linux ]]; then
-$CONDA_INSTALL gcc_linux-64 gxx_linux-64
+ # Install the compiler toolchain, for osx, bootstrapping needed
+ # which happens in build.sh
+ $CONDA_INSTALL gcc_linux-64 gxx_linux-64
+ # Install llvmdev (separate channel, for now)
+ $CONDA_INSTALL ohu::llvmdev
+ # $CONDA_INSTALL -c numba/label/dev llvmdev="14.*"
+else
+ $CONDA_INSTALL -c numba/label/dev llvmdev="14.*"
fi
# Install dependencies for code coverage (codecov.io)
diff --git a/docs/source/admin-guide/install.rst b/docs/source/admin-guide/install.rst
index 7bf5eea18..1c38d685c 100644
--- a/docs/source/admin-guide/install.rst
+++ b/docs/source/admin-guide/install.rst
@@ -41,9 +41,13 @@ maintainers do *not* use any LLVM shared libraries that may be present on the
system, and/or in the Conda environment. The parts of LLVM required by llvmlite
are statically linked at build time. As a result, installing llvmlite from a
binary package from the Numba channel does not also require the end user to
-install LLVM. (For more
-details on the reasoning behind this, see: :ref:`faq_why_static`). Note however
-also that llvmlite packages compiled by other parties, e.g. conda-forge may
+install LLVM. (For more details on the reasoning behind this, see:
+:ref:`faq_why_static`). From version 0.42, `compiler-rt `_
+builtin is also statically linked at build time to provide an implementation of the
+low-level target-specific hooks required by code generation and other runtime
+components. You can find a a list of supported IR from the builtin `here `_.
+
+Note also that llvmlite packages compiled by other parties, e.g. conda-forge may
split this into and ``llvmlite`` and ``llvm`` package and link dynamically.
Conda packages:
diff --git a/ffi/CMakeLists.txt b/ffi/CMakeLists.txt
index e4ce2c12c..a16b55f4f 100755
--- a/ffi/CMakeLists.txt
+++ b/ffi/CMakeLists.txt
@@ -7,8 +7,8 @@ project(llvmlite_ffi)
include(CheckIncludeFiles)
if(NOT MSVC)
- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-rtti -g")
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti -g")
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-rtti -g $ENV{CXX_STATIC_LINK}")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti -g $ENV{CXX_STATIC_LINK}")
endif()
find_package(LLVM REQUIRED CONFIG)
@@ -16,6 +16,18 @@ find_package(LLVM REQUIRED CONFIG)
message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")
+if(${CMAKE_SYSTEM_PROCESSOR} MATCHES "AMD64") # for desktop
+ set(ARCH "x86_64")
+else()
+ set(ARCH ${CMAKE_SYSTEM_PROCESSOR})
+endif()
+
+file(GLOB LLVM_EXCLUDE_LIB
+ "${LLVM_LIBRARY_DIR}/*LLVM*.a"
+)
+
+STRING(REPLACE ";" "," LLVM_EXCLUDE_LIB "${LLVM_EXCLUDE_LIB}")
+
# Set your project compile flags.
# E.g. if using the C++ header files
# you will need to enable C++11 support
@@ -42,6 +54,18 @@ add_library(llvmlite SHARED assembly.cpp bitcode.cpp core.cpp initfini.cpp
passmanagers.cpp targets.cpp dylib.cpp linker.cpp object_file.cpp
custom_passes.cpp orcjit.cpp)
+# Link compiler-rt whole archive
+if(${CMAKE_SYSTEM_NAME} MATCHES "Linux" OR ${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
+ if (EXISTS "$(LLVM_LIBDIR)/clang")
+ set(COMPILER_RT_LOCATION ${LLVM_LIBRARY_DIR}/linux/libclang_rt.builtins-${ARCH}.a)
+ else()
+ set(COMPILER_RT_LOCATION ${LLVM_LIBRARY_DIR}/clang/${LLVM_PACKAGE_VERSION}/lib/linux/libclang_rt.builtins-${ARCH}.a)
+ endif()
+ set_target_properties(llvmlite PROPERTIES
+ LINK_FLAGS "-Wl,--whole-archive,${COMPILER_RT_LOCATION},--no-whole-archive ")
+endif()
+
+
# Find the libraries that correspond to the LLVM components
# that we wish to use.
# The following line is broken with LLVM 10.0.0 due to a potential bug in
@@ -63,7 +87,7 @@ list(REMOVE_ITEM llvm_libs "OptRemarks")
target_link_libraries(llvmlite ${llvm_libs})
# -flto and --exclude-libs allow us to remove those parts of LLVM we don't use
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux" OR ${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
- set_property(TARGET llvmlite APPEND_STRING PROPERTY LINK_FLAGS "-flto -Wl,--exclude-libs,ALL")
+ set_property(TARGET llvmlite APPEND_STRING PROPERTY LINK_FLAGS "-flto -Wl,--exclude-libs,${LLVM_EXCLUDE_LIB}")
# On Darwin we only include the LLVMPY symbols we require and exclude
# everything else.
elseif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
diff --git a/ffi/Makefile.freebsd b/ffi/Makefile.freebsd
index 7b869e876..437c37569 100644
--- a/ffi/Makefile.freebsd
+++ b/ffi/Makefile.freebsd
@@ -3,8 +3,9 @@ CXX = clang++ -stdlib=libc++
# -flto and --exclude-libs allow us to remove those parts of LLVM we don't use
CXX_FLTO_FLAGS ?= -flto
-LD_FLTO_FLAGS ?= -flto -Wl,--exclude-libs=ALL
+LD_FLTO_FLAGS ?= -flto -Wl,--exclude-libs=$(LLVM_EXCLUDE_LIB)
+ARCH := `uname -m`
CXXFLAGS := $(CPPFLAGS) $(CXXFLAGS) $(LLVM_CXXFLAGS) $(CXX_FLTO_FLAGS)
LDFLAGS := $(LDFLAGS) $(LLVM_LDFLAGS) $(LD_FLTO_FLAGS)
LIBS = $(LLVM_LIBS)
@@ -14,10 +15,17 @@ SRC = assembly.cpp bitcode.cpp core.cpp initfini.cpp module.cpp value.cpp \
linker.cpp object_file.cpp
OUTPUT = libllvmlite.so
+ifneq ("$(wildcard $(LLVM_LIBDIR)/clang)","")
+ BUILTINS_ARCHIVE := $(LLVM_LIBDIR)/clang/*/lib/freebsd/libclang_rt.builtins-${ARCH}.a
+else
+ BUILTINS_ARCHIVE := $(LLVM_LIBDIR)/freebsd/libclang_rt.builtins-$(ARCH).a
+endif
+
all: $(OUTPUT)
$(OUTPUT): $(SRC) $(INCLUDE)
- $(CXX) -shared $(CXXFLAGS) $(SRC) -o $(OUTPUT) $(LDFLAGS) $(LIBS)
+ $(CXX) -shared $(CXXFLAGS) $(SRC) -o $(OUTPUT) $(LDFLAGS) $(LIBS) \
+ -Wl,--whole-archive ${BUILTINS_ARCHIVE} -Wl,--no-whole-archive
clean:
- rm -rf test
+ rm -rf test $(OUTPUT) $(OBJ)
diff --git a/ffi/Makefile.linux b/ffi/Makefile.linux
index c1df42dbb..1a844013f 100644
--- a/ffi/Makefile.linux
+++ b/ffi/Makefile.linux
@@ -3,10 +3,11 @@ CXX ?= g++
# -flto and --exclude-libs allow us to remove those parts of LLVM we don't use
CXX_FLTO_FLAGS ?= -flto
-LD_FLTO_FLAGS ?= -flto -Wl,--exclude-libs=ALL
+LD_FLTO_FLAGS ?= -flto=auto -flto -Wl,--exclude-libs=$(LLVM_EXCLUDE_LIB)
# -fPIC is required when compiling objects for a shared library
CXX_FPIC_FLAGS ?= -fPIC
+ARCH = `uname -m`
CXXFLAGS := $(CPPFLAGS) $(CXXFLAGS) $(LLVM_CXXFLAGS) $(CXX_FLTO_FLAGS) $(CXX_FPIC_FLAGS)
LDFLAGS := $(LDFLAGS) $(LLVM_LDFLAGS) $(LD_FLTO_FLAGS)
LIBS = $(LLVM_LIBS)
@@ -16,6 +17,12 @@ OBJ = assembly.o bitcode.o core.o initfini.o module.o value.o \
linker.o object_file.o custom_passes.o orcjit.o
OUTPUT = libllvmlite.so
+ifneq ("$(wildcard $(LLVM_LIBDIR)/clang)","")
+ BUILTINS_ARCHIVE := $(LLVM_LIBDIR)/clang/*/lib/linux/libclang_rt.builtins-${ARCH}.a
+else
+ BUILTINS_ARCHIVE := $(LLVM_LIBDIR)/linux/libclang_rt.builtins-$(ARCH).a
+endif
+
all: $(OUTPUT)
.cpp.o: $(INCLUDE)
@@ -23,8 +30,9 @@ all: $(OUTPUT)
$(OUTPUT): $(OBJ)
# static-libstdc++ avoids runtime dependencies on a
- # particular libstdc++ version.
- $(CXX) $(CXX_STATIC_LINK) -shared $(CXXFLAGS) $(OBJ) -o $(OUTPUT) $(LDFLAGS) $(LIBS)
+ # particular libstdc++ version.'
+ $(CXX) $(CXX_STATIC_LINK) -shared $(CXXFLAGS) $(OBJ) -o $(OUTPUT) $(LDFLAGS) $(LIBS) \
+ -Wl,--whole-archive $(BUILTINS_ARCHIVE) -Wl,--no-whole-archive
clean:
- rm -rf test $(OUTPUT) $(OBJ)
+ rm -rf test $(OUTPUT) $(OBJ)
\ No newline at end of file
diff --git a/ffi/build.py b/ffi/build.py
index f4f8c69fa..4176630f9 100755
--- a/ffi/build.py
+++ b/ffi/build.py
@@ -6,6 +6,7 @@
from __future__ import print_function
from ctypes.util import find_library
+from glob import glob
import re
import multiprocessing
import os
@@ -177,6 +178,12 @@ def main_posix(kind, library_ext):
libs = run_llvm_config(llvm_config, "--system-libs --libs all".split())
# Normalize whitespace (trim newlines)
os.environ['LLVM_LIBS'] = ' '.join(libs.split())
+ # Get LLVM information for building
+ llvm_libdir = run_llvm_config(llvm_config, ["--libdir"]).strip()
+ os.environ['LLVM_LIBDIR'] = llvm_libdir
+
+ exclude_file = glob(llvm_libdir + '/*LLVM*.a')
+ os.environ['LLVM_EXCLUDE_LIB'] = (',').join(exclude_file)
cxxflags = run_llvm_config(llvm_config, ["--cxxflags"])
# on OSX cxxflags has null bytes at the end of the string, remove them
diff --git a/llvmlite/tests/test_binding.py b/llvmlite/tests/test_binding.py
index d0955508d..967a96e5c 100644
--- a/llvmlite/tests/test_binding.py
+++ b/llvmlite/tests/test_binding.py
@@ -2120,6 +2120,13 @@ def test_libm(self):
llvm.load_library_permanently(libm)
+class TestArchive(BaseTest):
+ @unittest.skipUnless(platform.system() in ["Linux"],
+ "test only works on Linux")
+ def test_compiler_rt(self):
+ ffi.lib._lib_handle['__ashldi3']()
+
+
class TestAnalysis(BaseTest):
def build_ir_module(self):
m = ir.Module()
diff --git a/setup.py b/setup.py
index 75150ea4b..bbeaf30d1 100644
--- a/setup.py
+++ b/setup.py
@@ -139,7 +139,8 @@ def _rm_walk(self):
else:
for fname in files:
if (fname.endswith('.pyc') or fname.endswith('.so')
- or fname.endswith('.o')):
+ or fname.endswith('.o') or fname.endswith('.a')
+ or fname.endswith('.dll') or fname.endswith('.lib')):
fpath = os.path.join(path, fname)
os.remove(fpath)
log.info("removing '%s'", fpath)