Commit e9744431 by Edward Z. Yang Committed by Tianqi Chen

Build system and dynamic library fixes (#283)

* Install rules and dynamic library loading fixes.

A batch of fixes:

- Added 'install' rule to cmake and make, which installs runtime
  headers and library (libtvm_runtime).

- Added 'installdev' rule to make, which also installs the compiler
  infrastructure headers and library (libtvm)

- Added 'INSTALL_DEV' option to cmake, for toggling installation
  of compiler infrastructure headers and library

- cmake no longer builds into lib/ directory; instead all build
  products go in your build directory

- New algorithm for dynamic library loading, as described in #281.

Signed-off-by: Edward Z. Yang <ezyang@fb.com>

* Emit dylib on OS X

Signed-off-by: Edward Z. Yang <ezyang@fb.com>

* Lint fixes.

Signed-off-by: Edward Z. Yang <ezyang@fb.com>
parent fe51c498
...@@ -16,6 +16,7 @@ tvm_option(USE_RPC "Build with RPC" OFF) ...@@ -16,6 +16,7 @@ tvm_option(USE_RPC "Build with RPC" OFF)
tvm_option(USE_LLVM "Build with LLVM" OFF) tvm_option(USE_LLVM "Build with LLVM" OFF)
tvm_option(USE_RTTI "Build with RTTI" ON) tvm_option(USE_RTTI "Build with RTTI" ON)
tvm_option(USE_MSVC_MT "Build with MT" OFF) tvm_option(USE_MSVC_MT "Build with MT" OFF)
tvm_option(INSTALL_DEV "Install compiler infrastructure" OFF)
include_directories("include") include_directories("include")
include_directories("HalideIR/src") include_directories("HalideIR/src")
...@@ -139,20 +140,23 @@ elseif(DMLC_CORE_PATH) ...@@ -139,20 +140,23 @@ elseif(DMLC_CORE_PATH)
include_directories(${DMLC_CORE_PATH}/include) include_directories(${DMLC_CORE_PATH}/include)
endif() endif()
# Set library output directories
if(MSVC)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${PROJECT_SOURCE_DIR}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE ${PROJECT_SOURCE_DIR}/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${PROJECT_SOURCE_DIR}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG ${PROJECT_SOURCE_DIR}/lib)
else()
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR})
set(CMAKE_SHARED_LIBRARY_PREFIX "")
endif()
list(APPEND RUNTIME_SRCS ${GROUP_Include}) list(APPEND RUNTIME_SRCS ${GROUP_Include})
add_library(libtvm SHARED ${COMPILER_SRCS} ${RUNTIME_SRCS}) add_library(tvm SHARED ${COMPILER_SRCS} ${RUNTIME_SRCS})
add_library(libtvm_runtime SHARED ${RUNTIME_SRCS}) add_library(tvm_runtime SHARED ${RUNTIME_SRCS})
target_link_libraries(libtvm ${TVM_LINKER_LIBS} ${TVM_RUNTIME_LINKER_LIBS}) target_link_libraries(tvm ${TVM_LINKER_LIBS} ${TVM_RUNTIME_LINKER_LIBS})
target_link_libraries(libtvm_runtime ${TVM_RUNTIME_LINKER_LIBS}) target_link_libraries(tvm_runtime ${TVM_RUNTIME_LINKER_LIBS})
install(TARGETS tvm_runtime DESTINATION lib)
if (INSTALL_DEV)
install(TARGETS tvm DESTINATION lib)
install(
DIRECTORY "include/." DESTINATION "include"
FILES_MATCHING
PATTERN "*.h"
)
else(INSTALL_DEV)
install(
DIRECTORY "include/tvm/runtime/." DESTINATION "include/tvm/runtime"
FILES_MATCHING
PATTERN "*.h"
)
endif(INSTALL_DEV)
...@@ -10,12 +10,7 @@ endif ...@@ -10,12 +10,7 @@ endif
include $(config) include $(config)
.PHONY: clean all test doc pylint cpplint lint verilog cython cython2 cython3 web runtime .PHONY: clean install installdev all test doc pylint cpplint lint verilog cython cython2 cython3 web runtime
BUILD_TARGETS ?= lib/libtvm.so lib/libtvm_runtime.so
all: ${BUILD_TARGETS}
runtime: lib/libtvm_runtime.so
web: lib/libtvm_web_runtime.js lib/libtvm_web_runtime.bc
ifndef DMLC_CORE_PATH ifndef DMLC_CORE_PATH
DMLC_CORE_PATH = $(ROOTDIR)/dmlc-core DMLC_CORE_PATH = $(ROOTDIR)/dmlc-core
...@@ -122,12 +117,15 @@ endif ...@@ -122,12 +117,15 @@ endif
ifeq ($(OS),Windows_NT) ifeq ($(OS),Windows_NT)
JVM_PKG_PROFILE := windows JVM_PKG_PROFILE := windows
SHARED_LIBRARY_SUFFIX := dll
else else
UNAME_S := $(shell uname -s) UNAME_S := $(shell uname -s)
ifeq ($(UNAME_S), Darwin) ifeq ($(UNAME_S), Darwin)
JVM_PKG_PROFILE := osx-x86_64 JVM_PKG_PROFILE := osx-x86_64
SHARED_LIBRARY_SUFFIX := dylib
else else
JVM_PKG_PROFILE := linux-x86_64 JVM_PKG_PROFILE := linux-x86_64
SHARED_LIBRARY_SUFFIX := so
endif endif
endif endif
...@@ -143,6 +141,11 @@ else ...@@ -143,6 +141,11 @@ else
JVM_PKG_PROFILE := $(JVM_PKG_PROFILE)-cpu JVM_PKG_PROFILE := $(JVM_PKG_PROFILE)-cpu
endif endif
BUILD_TARGETS ?= lib/libtvm.$(SHARED_LIBRARY_SUFFIX) lib/libtvm_runtime.$(SHARED_LIBRARY_SUFFIX)
all: ${BUILD_TARGETS}
runtime: lib/libtvm_runtime.$(SHARED_LIBRARY_SUFFIX)
web: lib/libtvm_web_runtime.js lib/libtvm_web_runtime.bc
include tests/cpp/unittest.mk include tests/cpp/unittest.mk
test: $(TEST) test: $(TEST)
...@@ -167,6 +170,14 @@ build/%.o: src/%.cc ...@@ -167,6 +170,14 @@ build/%.o: src/%.cc
$(CXX) $(CFLAGS) -MM -MT build/$*.o $< >build/$*.d $(CXX) $(CFLAGS) -MM -MT build/$*.o $< >build/$*.d
$(CXX) -c $(CFLAGS) -c $< -o $@ $(CXX) -c $(CFLAGS) -c $< -o $@
lib/libtvm.dylib: $(ALL_DEP) $(RUNTIME_DEP)
@mkdir -p $(@D)
$(CXX) $(CFLAGS) $(FRAMEWORKS) -shared -o $@ $(filter %.o %.a, $^) $(LDFLAGS)
lib/libtvm_runtime.dylib: $(RUNTIME_DEP)
@mkdir -p $(@D)
$(CXX) $(CFLAGS) $(FRAMEWORKS) -shared -o $@ $(filter %.o %.a, $^) $(LDFLAGS)
lib/libtvm.so: $(ALL_DEP) $(RUNTIME_DEP) lib/libtvm.so: $(ALL_DEP) $(RUNTIME_DEP)
@mkdir -p $(@D) @mkdir -p $(@D)
$(CXX) $(CFLAGS) $(FRAMEWORKS) -shared -o $@ $(filter %.o %.a, $^) $(LDFLAGS) $(CXX) $(CFLAGS) $(FRAMEWORKS) -shared -o $@ $(filter %.o %.a, $^) $(LDFLAGS)
...@@ -207,6 +218,18 @@ lint: cpplint pylint jnilint ...@@ -207,6 +218,18 @@ lint: cpplint pylint jnilint
doc: doc:
doxygen docs/Doxyfile doxygen docs/Doxyfile
install: lib/libtvm_runtime.$(SHARED_LIBRARY_SUFFIX)
mkdir -p $(DESTDIR)$(PREFIX)/include/tvm/runtime
cp -R include/tvm/runtime/. $(DESTDIR)$(PREFIX)/include/tvm/runtime
cp lib/libtvm_runtime.$(SHARED_LIBRARY_SUFFIX) $(DESTDIR)$(PREFIX)/lib
installdev: lib/libtvm.$(SHARED_LIBRARY_SUFFIX) lib/libtvm_runtime.$(SHARED_LIBRARY_SUFFIX) lib/libtvm.a
mkdir -p $(DESTDIR)$(PREFIX)/include
cp -R include/tvm $(DESTDIR)$(PREFIX)/include
cp lib/libtvm.$(SHARED_LIBRARY_SUFFIX) $(DESTDIR)$(PREFIX)/lib
cp lib/libtvm_runtime.$(SHARED_LIBRARY_SUFFIX) $(DESTDIR)$(PREFIX)/lib
cp lib/libtvm.a $(DESTDIR)$(PREFIX)/lib
# Cython build # Cython build
cython: cython:
cd python; python setup.py build_ext --inplace cd python; python setup.py build_ext --inplace
...@@ -218,7 +241,7 @@ cython3: ...@@ -218,7 +241,7 @@ cython3:
cd python; python3 setup.py build_ext --inplace cd python; python3 setup.py build_ext --inplace
cyclean: cyclean:
rm -rf python/tvm/*/*/*.so python/tvm/*/*/*.cpp rm -rf python/tvm/*/*/*.so python/tvm/*/*/*.dylib python/tvm/*/*/*.cpp
jvmpkg: jvmpkg:
(cd $(ROOTDIR)/jvm; \ (cd $(ROOTDIR)/jvm; \
......
...@@ -13,13 +13,13 @@ from . import libinfo ...@@ -13,13 +13,13 @@ from . import libinfo
# library loading # library loading
#---------------------------- #----------------------------
if sys.version_info[0] == 3: if sys.version_info[0] == 3:
string_types = str, string_types = (str,)
numeric_types = (float, int, np.float32, np.int32) numeric_types = (float, int, np.float32, np.int32)
# this function is needed for python3 # this function is needed for python3
# to convert ctypes.char_p .value back to python str # to convert ctypes.char_p .value back to python str
py_str = lambda x: x.decode('utf-8') py_str = lambda x: x.decode('utf-8')
else: else:
string_types = basestring, string_types = (basestring,)
numeric_types = (float, int, long, np.float32, np.int32) numeric_types = (float, int, long, np.float32, np.int32)
py_str = lambda x: x py_str = lambda x: x
......
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
from __future__ import absolute_import from __future__ import absolute_import
import sys import sys
import os import os
import platform
def find_lib_path(name=None, search_path=None): def find_lib_path(name=None, search_path=None):
...@@ -19,21 +18,34 @@ def find_lib_path(name=None, search_path=None): ...@@ -19,21 +18,34 @@ def find_lib_path(name=None, search_path=None):
List of all found path to the libraries List of all found path to the libraries
""" """
use_runtime = os.environ.get("TVM_USE_RUNTIME_LIB", False) use_runtime = os.environ.get("TVM_USE_RUNTIME_LIB", False)
curr_path = os.path.dirname(os.path.abspath(os.path.expanduser(__file__)))
root_path = os.path.join(curr_path, '../') # See https://github.com/dmlc/tvm/issues/281 for some background.
api_path = os.path.join(curr_path, '../../../lib/')
cmake_build_path = os.path.join(curr_path, '../../../build/Release/') # NB: This will either be the source directory (if TVM is run
dll_path = [curr_path, root_path, api_path, cmake_build_path] # inplace) or the install directory (if TVM is installed).
if os.name == 'nt': # An installed TVM's curr_path will look something like:
vs_configuration = 'Release' # $PREFIX/lib/python3.6/site-packages/tvm/_ffi
if platform.architecture()[0] == '64bit': ffi_dir = os.path.dirname(os.path.abspath(os.path.expanduser(__file__)))
dll_path.append(os.path.join(curr_path, '../../../build', vs_configuration)) source_dir = os.path.join(ffi_dir, "..", "..", "..")
dll_path.append(os.path.join(curr_path, '../../../windows/x64', vs_configuration)) install_lib_dir = os.path.join(ffi_dir, "..", "..", "..", "..")
else:
dll_path.append(os.path.join(curr_path, '../../../build', vs_configuration)) dll_path = []
dll_path.append(os.path.join(curr_path, '../../../windows', vs_configuration))
elif os.name == "posix" and os.environ.get('LD_LIBRARY_PATH', None): if os.environ.get('TVM_LIBRARY_PATH', None):
dll_path.append(os.environ['TVM_LIBRARY_PATH'])
if sys.platform.startswith('linux') and os.environ.get('LD_LIBRARY_PATH', None):
dll_path.extend([p.strip() for p in os.environ['LD_LIBRARY_PATH'].split(":")]) dll_path.extend([p.strip() for p in os.environ['LD_LIBRARY_PATH'].split(":")])
elif sys.platform.startswith('darwin') and os.environ.get('DYLD_LIBRARY_PATH', None):
dll_path.extend([p.strip() for p in os.environ['DYLD_LIBRARY_PATH'].split(":")])
# Default cmake build directory
dll_path.append(os.path.join(source_dir, "build"))
# Default mkae build directory
dll_path.append(os.path.join(source_dir, "lib"))
dll_path.append(install_lib_dir)
dll_path = [os.path.abspath(x) for x in dll_path] dll_path = [os.path.abspath(x) for x in dll_path]
if search_path is not None: if search_path is not None:
if search_path is list: if search_path is list:
...@@ -44,9 +56,12 @@ def find_lib_path(name=None, search_path=None): ...@@ -44,9 +56,12 @@ def find_lib_path(name=None, search_path=None):
lib_dll_path = [os.path.join(p, name) for p in dll_path] lib_dll_path = [os.path.join(p, name) for p in dll_path]
runtime_dll_path = [] runtime_dll_path = []
else: else:
if os.name == 'nt': if sys.platform.startswith('win32'):
lib_dll_path = [os.path.join(p, 'libtvm.dll') for p in dll_path] lib_dll_path = [os.path.join(p, 'libtvm.dll') for p in dll_path]
runtime_dll_path = [os.path.join(p, 'libtvm_runtime.dll') for p in dll_path] runtime_dll_path = [os.path.join(p, 'libtvm_runtime.dll') for p in dll_path]
elif sys.platform.startswith('darwin'):
lib_dll_path = [os.path.join(p, 'libtvm.dylib') for p in dll_path]
runtime_dll_path = [os.path.join(p, 'libtvm_runtime.dylib') for p in dll_path]
else: else:
lib_dll_path = [os.path.join(p, 'libtvm.so') for p in dll_path] lib_dll_path = [os.path.join(p, 'libtvm.so') for p in dll_path]
runtime_dll_path = [os.path.join(p, 'libtvm_runtime.so') for p in dll_path] runtime_dll_path = [os.path.join(p, 'libtvm_runtime.so') for p in dll_path]
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment