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)
tvm_option(USE_LLVM "Build with LLVM" OFF)
tvm_option(USE_RTTI "Build with RTTI" ON)
tvm_option(USE_MSVC_MT "Build with MT" OFF)
tvm_option(INSTALL_DEV "Install compiler infrastructure" OFF)
include_directories("include")
include_directories("HalideIR/src")
......@@ -139,20 +140,23 @@ elseif(DMLC_CORE_PATH)
include_directories(${DMLC_CORE_PATH}/include)
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})
add_library(libtvm SHARED ${COMPILER_SRCS} ${RUNTIME_SRCS})
add_library(libtvm_runtime SHARED ${RUNTIME_SRCS})
target_link_libraries(libtvm ${TVM_LINKER_LIBS} ${TVM_RUNTIME_LINKER_LIBS})
target_link_libraries(libtvm_runtime ${TVM_RUNTIME_LINKER_LIBS})
add_library(tvm SHARED ${COMPILER_SRCS} ${RUNTIME_SRCS})
add_library(tvm_runtime SHARED ${RUNTIME_SRCS})
target_link_libraries(tvm ${TVM_LINKER_LIBS} ${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
include $(config)
.PHONY: clean 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
.PHONY: clean install installdev all test doc pylint cpplint lint verilog cython cython2 cython3 web runtime
ifndef DMLC_CORE_PATH
DMLC_CORE_PATH = $(ROOTDIR)/dmlc-core
......@@ -122,12 +117,15 @@ endif
ifeq ($(OS),Windows_NT)
JVM_PKG_PROFILE := windows
SHARED_LIBRARY_SUFFIX := dll
else
UNAME_S := $(shell uname -s)
ifeq ($(UNAME_S), Darwin)
JVM_PKG_PROFILE := osx-x86_64
SHARED_LIBRARY_SUFFIX := dylib
else
JVM_PKG_PROFILE := linux-x86_64
SHARED_LIBRARY_SUFFIX := so
endif
endif
......@@ -143,6 +141,11 @@ else
JVM_PKG_PROFILE := $(JVM_PKG_PROFILE)-cpu
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
test: $(TEST)
......@@ -167,6 +170,14 @@ build/%.o: src/%.cc
$(CXX) $(CFLAGS) -MM -MT build/$*.o $< >build/$*.d
$(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)
@mkdir -p $(@D)
$(CXX) $(CFLAGS) $(FRAMEWORKS) -shared -o $@ $(filter %.o %.a, $^) $(LDFLAGS)
......@@ -207,6 +218,18 @@ lint: cpplint pylint jnilint
doc:
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:
cd python; python setup.py build_ext --inplace
......@@ -218,7 +241,7 @@ cython3:
cd python; python3 setup.py build_ext --inplace
cyclean:
rm -rf python/tvm/*/*/*.so python/tvm/*/*/*.cpp
rm -rf python/tvm/*/*/*.so python/tvm/*/*/*.dylib python/tvm/*/*/*.cpp
jvmpkg:
(cd $(ROOTDIR)/jvm; \
......
......@@ -13,13 +13,13 @@ from . import libinfo
# library loading
#----------------------------
if sys.version_info[0] == 3:
string_types = str,
string_types = (str,)
numeric_types = (float, int, np.float32, np.int32)
# this function is needed for python3
# to convert ctypes.char_p .value back to python str
py_str = lambda x: x.decode('utf-8')
else:
string_types = basestring,
string_types = (basestring,)
numeric_types = (float, int, long, np.float32, np.int32)
py_str = lambda x: x
......
......@@ -2,7 +2,6 @@
from __future__ import absolute_import
import sys
import os
import platform
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
"""
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, '../')
api_path = os.path.join(curr_path, '../../../lib/')
cmake_build_path = os.path.join(curr_path, '../../../build/Release/')
dll_path = [curr_path, root_path, api_path, cmake_build_path]
if os.name == 'nt':
vs_configuration = 'Release'
if platform.architecture()[0] == '64bit':
dll_path.append(os.path.join(curr_path, '../../../build', vs_configuration))
dll_path.append(os.path.join(curr_path, '../../../windows/x64', vs_configuration))
else:
dll_path.append(os.path.join(curr_path, '../../../build', vs_configuration))
dll_path.append(os.path.join(curr_path, '../../../windows', vs_configuration))
elif os.name == "posix" and os.environ.get('LD_LIBRARY_PATH', None):
# See https://github.com/dmlc/tvm/issues/281 for some background.
# NB: This will either be the source directory (if TVM is run
# inplace) or the install directory (if TVM is installed).
# An installed TVM's curr_path will look something like:
# $PREFIX/lib/python3.6/site-packages/tvm/_ffi
ffi_dir = os.path.dirname(os.path.abspath(os.path.expanduser(__file__)))
source_dir = os.path.join(ffi_dir, "..", "..", "..")
install_lib_dir = os.path.join(ffi_dir, "..", "..", "..", "..")
dll_path = []
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(":")])
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]
if search_path is not None:
if search_path is list:
......@@ -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]
runtime_dll_path = []
else:
if os.name == 'nt':
if sys.platform.startswith('win32'):
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]
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:
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]
......
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