diff --git a/CMakeLists.txt b/CMakeLists.txt index 83e8af1e4..67b879a53 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,6 +24,7 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) # options option(MMDEPLOY_SHARED_LIBS "build shared libs" OFF) option(MMDEPLOY_BUILD_SDK "build MMDeploy SDK" OFF) +option(MMDEPLOY_DYNAMIC_BACKEND "dynamic load backend" OFF) option(MMDEPLOY_BUILD_SDK_MONOLITHIC "build single lib for SDK API" ON) option(MMDEPLOY_BUILD_TEST "build unittests" OFF) option(MMDEPLOY_BUILD_SDK_PYTHON_API "build SDK Python API" OFF) @@ -39,6 +40,10 @@ set(MMDEPLOY_TARGET_DEVICES "cpu" CACHE STRING "target devices to support") set(MMDEPLOY_TARGET_BACKENDS "" CACHE STRING "target inference engines to support") set(MMDEPLOY_CODEBASES "all" CACHE STRING "select OpenMMLab codebases") +if ((NOT MMDEPLOY_BUILD_SDK_MONOLITHIC) AND MMDEPLOY_DYNAMIC_BACKEND) + set(MMDEPLOY_DYNAMIC_BACKEND OFF) +endif () + if (NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE Release CACHE STRING "choose 'Release' as default build type" FORCE) endif () diff --git a/cmake/MMDeploy.cmake b/cmake/MMDeploy.cmake index bd982e183..e9219840b 100644 --- a/cmake/MMDeploy.cmake +++ b/cmake/MMDeploy.cmake @@ -12,6 +12,15 @@ function (mmdeploy_export NAME) RUNTIME DESTINATION bin) endfunction () +macro(mmdeploy_add_net NAME) + if (MMDEPLOY_DYNAMIC_BACKEND) + mmdeploy_add_library(${NAME} SHARED ${ARGN}) + target_link_libraries(${PROJECT_NAME} PRIVATE mmdeploy) + set(BACKEND_LIB_NAMES ${BACKEND_LIB_NAMES} ${PROJECT_NAME} PARENT_SCOPE) + else () + mmdeploy_add_module(${NAME} ${ARGN}) + endif () +endmacro() function (mmdeploy_add_library NAME) # EXCLUDE: exclude from registering & exporting diff --git a/cmake/loader.cpp.in b/cmake/loader.cpp.in index 6627d6e2e..57396b196 100644 --- a/cmake/loader.cpp.in +++ b/cmake/loader.cpp.in @@ -1,15 +1,37 @@ // Copyright (c) OpenMMLab. All rights reserved. -#include - +#include #include +#ifdef _WIN32 +#include +#else +#include +#endif + +#ifdef _WIN32 +#define LIBPREFIX "" +#define LIBSUFFIX ".dll" +#elif defined(__APPLE__) +#define LIBPREFIX "lib" +#define LIBSUFFIX ".dylib" +#else +#define LIBPREFIX "lib" +#define LIBSUFFIX ".so" +#endif + namespace mmdeploy { namespace { void* mmdeploy_load_library(const char* name) { fprintf(stderr, "loading %s ...\n", name); - auto handle = LoadLibraryA(name); + +#ifdef _WIN32 + auto handle = LoadLibraryExA(name, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); +#else + auto handle = dlopen(name, RTLD_NOW | RTLD_GLOBAL); +#endif + if (!handle) { fprintf(stderr, "failed to load library %s\n", name); return nullptr; @@ -26,7 +48,8 @@ class Loader { @_MMDEPLOY_DYNAMIC_MODULES@ }; for (const auto name : modules) { - mmdeploy_load_library(name); + std::string libname = std::string{} + LIBPREFIX + name + LIBSUFFIX; + mmdeploy_load_library(libname.c_str()); } } }; diff --git a/csrc/mmdeploy/apis/c/CMakeLists.txt b/csrc/mmdeploy/apis/c/CMakeLists.txt index 1d0533aff..3b5172219 100644 --- a/csrc/mmdeploy/apis/c/CMakeLists.txt +++ b/csrc/mmdeploy/apis/c/CMakeLists.txt @@ -80,5 +80,14 @@ if (MMDEPLOY_BUILD_SDK_CSHARP_API OR MMDEPLOY_BUILD_SDK_MONOLITHIC) set_target_properties(mmdeploy PROPERTIES VERSION ${MMDEPLOY_VERSION} SOVERSION ${MMDEPLOY_VERSION_MAJOR}) + if (APPLE) + set_target_properties(mmdeploy PROPERTIES + INSTALL_RPATH "@loader_path" + BUILD_RPATH "@loader_path") + else () + set_target_properties(mmdeploy PROPERTIES + INSTALL_RPATH "\$ORIGIN" + BUILD_RPATH "\$ORIGIN") + endif () mmdeploy_export(mmdeploy) endif () diff --git a/csrc/mmdeploy/net/CMakeLists.txt b/csrc/mmdeploy/net/CMakeLists.txt index 0c723d540..4b26305c6 100644 --- a/csrc/mmdeploy/net/CMakeLists.txt +++ b/csrc/mmdeploy/net/CMakeLists.txt @@ -2,6 +2,8 @@ project(mmdeploy_net_module) +set(BACKEND_LIB_NAMES) + if ("trt" IN_LIST MMDEPLOY_TARGET_BACKENDS) add_subdirectory(trt) endif () @@ -46,5 +48,22 @@ if ("rknn" IN_LIST MMDEPLOY_TARGET_BACKENDS) add_subdirectory(rknn) endif () -mmdeploy_add_module(${PROJECT_NAME} net_module.cpp) +if (MMDEPLOY_DYNAMIC_BACKEND) + set(_MODULE_STR ${BACKEND_LIB_NAMES}) + list(TRANSFORM _MODULE_STR REPLACE "(.+)" "\"\\1\"") + string(JOIN ",\n " _MODULE_STR ${_MODULE_STR}) + set(_MMDEPLOY_DYNAMIC_MODULES ${_MODULE_STR}) + + set(_LOADER_NAME net_loader) + set(_LOADER_PATH ${${PROJECT_NAME}_BINARY_DIR}/${_LOADER_NAME}.cpp) + configure_file( + ${CMAKE_SOURCE_DIR}/cmake/loader.cpp.in + ${_LOADER_PATH}) + if (NOT (WIN32 OR APPLE)) + SET(_DL_LIB dl) + endif () +endif () + +mmdeploy_add_module(${PROJECT_NAME} net_module.cpp ${_LOADER_PATH}) +target_link_libraries(${PROJECT_NAME} PUBLIC ${_DL_LIB}) add_library(mmdeploy::net_module ALIAS ${PROJECT_NAME}) diff --git a/csrc/mmdeploy/net/coreml/CMakeLists.txt b/csrc/mmdeploy/net/coreml/CMakeLists.txt index a4c3b2a0a..2f6de5427 100644 --- a/csrc/mmdeploy/net/coreml/CMakeLists.txt +++ b/csrc/mmdeploy/net/coreml/CMakeLists.txt @@ -5,7 +5,7 @@ project(mmdeploy_coreml_net) if ("cpu" IN_LIST MMDEPLOY_TARGET_DEVICES) find_library(CORE_ML CoreML) find_library(FOUNDATION Foundation) - mmdeploy_add_module(${PROJECT_NAME} coreml_net.mm) + mmdeploy_add_net(${PROJECT_NAME} coreml_net.mm) target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) target_link_libraries(${PROJECT_NAME} PRIVATE ${CORE_ML} ${FOUNDATION}) add_library(mmdeploy::coreml_net ALIAS ${PROJECT_NAME}) diff --git a/csrc/mmdeploy/net/ncnn/CMakeLists.txt b/csrc/mmdeploy/net/ncnn/CMakeLists.txt index ffd349f3d..7ae7a8538 100644 --- a/csrc/mmdeploy/net/ncnn/CMakeLists.txt +++ b/csrc/mmdeploy/net/ncnn/CMakeLists.txt @@ -6,7 +6,7 @@ if ("cpu" IN_LIST MMDEPLOY_TARGET_DEVICES) find_package(ncnn REQUIRED) - mmdeploy_add_module(${PROJECT_NAME} ncnn_net.cpp) + mmdeploy_add_net(${PROJECT_NAME} ncnn_net.cpp) target_link_libraries(${PROJECT_NAME} PRIVATE mmdeploy_ncnn_ops_obj) target_link_libraries(${PROJECT_NAME} PRIVATE ncnn) add_library(mmdeploy::ncnn_net ALIAS ${PROJECT_NAME}) diff --git a/csrc/mmdeploy/net/openvino/CMakeLists.txt b/csrc/mmdeploy/net/openvino/CMakeLists.txt index b0691be09..5c9d344db 100644 --- a/csrc/mmdeploy/net/openvino/CMakeLists.txt +++ b/csrc/mmdeploy/net/openvino/CMakeLists.txt @@ -5,7 +5,7 @@ project(mmdeploy_openvino_net) if ("cpu" IN_LIST MMDEPLOY_TARGET_DEVICES) find_package(InferenceEngine REQUIRED) - mmdeploy_add_module(${PROJECT_NAME} openvino_net.cpp) + mmdeploy_add_net(${PROJECT_NAME} openvino_net.cpp) target_link_libraries(${PROJECT_NAME} PRIVATE ${InferenceEngine_LIBRARIES}) add_library(mmdeploy::openvino_net ALIAS ${PROJECT_NAME}) diff --git a/csrc/mmdeploy/net/ort/CMakeLists.txt b/csrc/mmdeploy/net/ort/CMakeLists.txt index 00a941911..00ecdaf44 100644 --- a/csrc/mmdeploy/net/ort/CMakeLists.txt +++ b/csrc/mmdeploy/net/ort/CMakeLists.txt @@ -4,7 +4,7 @@ project(mmdeploy_ort_net) include(${CMAKE_SOURCE_DIR}/cmake/modules/FindONNXRUNTIME.cmake) -mmdeploy_add_module(${PROJECT_NAME} ort_net.cpp) +mmdeploy_add_net(${PROJECT_NAME} ort_net.cpp) target_include_directories(${PROJECT_NAME} PRIVATE ${ONNXRUNTIME_DIR}/include) target_link_libraries(${PROJECT_NAME} PRIVATE mmdeploy_onnxruntime_ops_obj) target_link_libraries(${PROJECT_NAME} PUBLIC onnxruntime) diff --git a/csrc/mmdeploy/net/torchscript/CMakeLists.txt b/csrc/mmdeploy/net/torchscript/CMakeLists.txt index f65c65c89..e3e25c9f8 100644 --- a/csrc/mmdeploy/net/torchscript/CMakeLists.txt +++ b/csrc/mmdeploy/net/torchscript/CMakeLists.txt @@ -8,7 +8,7 @@ if (MMDEPLOY_TORCHSCRIPT_SDK_BACKEND) find_package(Torch REQUIRED) find_package(TorchVision QUIET) - mmdeploy_add_module(${PROJECT_NAME} torch_net.cpp) + mmdeploy_add_net(${PROJECT_NAME} torch_net.cpp) target_link_libraries(${PROJECT_NAME} PRIVATE ${TORCH_LIBRARIES}) diff --git a/csrc/mmdeploy/net/trt/CMakeLists.txt b/csrc/mmdeploy/net/trt/CMakeLists.txt index 6703c7f4f..5de364162 100644 --- a/csrc/mmdeploy/net/trt/CMakeLists.txt +++ b/csrc/mmdeploy/net/trt/CMakeLists.txt @@ -4,7 +4,7 @@ project(mmdeploy_trt_net) include(${CMAKE_SOURCE_DIR}/cmake/tensorrt.cmake) -mmdeploy_add_module(${PROJECT_NAME} trt_net.cpp) +mmdeploy_add_net(${PROJECT_NAME} trt_net.cpp) target_include_directories(${PROJECT_NAME} PRIVATE ${TENSORRT_INCLUDE_DIR}) target_include_directories(${PROJECT_NAME} PRIVATE ${CUDNN_DIR}/include) diff --git a/csrc/mmdeploy/net/tvm/CMakeLists.txt b/csrc/mmdeploy/net/tvm/CMakeLists.txt index 67e6ae270..426d3bb4e 100644 --- a/csrc/mmdeploy/net/tvm/CMakeLists.txt +++ b/csrc/mmdeploy/net/tvm/CMakeLists.txt @@ -4,7 +4,7 @@ project(mmdeploy_tvm_net) include(${CMAKE_SOURCE_DIR}/cmake/modules/FindTVM.cmake) -mmdeploy_add_module(${PROJECT_NAME} tvm_net.cpp) +mmdeploy_add_net(${PROJECT_NAME} tvm_net.cpp) target_include_directories(${PROJECT_NAME} PRIVATE ${TVM_INCLUDE_DIR} ${DLPACK_INCLUDE_DIR} ${DMLC_CORE_INCLUDE_DIR}) target_link_libraries(${PROJECT_NAME} PRIVATE tvm_runtime mmdeploy_dlpack_utils)