Skip to content

Commit d95950d

Browse files
authored
[Feature] Dynamically load net module to remove dependencies of mmdeploy.so (#1776) (#1822)
* dynamic load net module * export xxx_net * add runpath * link dl * remove -ldl for macos * fix rpath * module -> shared * set MMDEPLOY_DYNAMIC_BACKEND OFF when MMDEPLOY_BUILD_SDK_MONOLITHIC is OFF
1 parent 7de413a commit d95950d

File tree

12 files changed

+77
-12
lines changed

12 files changed

+77
-12
lines changed

CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
2424
# options
2525
option(MMDEPLOY_SHARED_LIBS "build shared libs" OFF)
2626
option(MMDEPLOY_BUILD_SDK "build MMDeploy SDK" OFF)
27+
option(MMDEPLOY_DYNAMIC_BACKEND "dynamic load backend" OFF)
2728
option(MMDEPLOY_BUILD_SDK_MONOLITHIC "build single lib for SDK API" ON)
2829
option(MMDEPLOY_BUILD_TEST "build unittests" OFF)
2930
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")
3940
set(MMDEPLOY_TARGET_BACKENDS "" CACHE STRING "target inference engines to support")
4041
set(MMDEPLOY_CODEBASES "all" CACHE STRING "select OpenMMLab codebases")
4142

43+
if ((NOT MMDEPLOY_BUILD_SDK_MONOLITHIC) AND MMDEPLOY_DYNAMIC_BACKEND)
44+
set(MMDEPLOY_DYNAMIC_BACKEND OFF)
45+
endif ()
46+
4247
if (NOT CMAKE_BUILD_TYPE)
4348
set(CMAKE_BUILD_TYPE Release CACHE STRING "choose 'Release' as default build type" FORCE)
4449
endif ()

cmake/MMDeploy.cmake

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,15 @@ function (mmdeploy_export NAME)
1212
RUNTIME DESTINATION bin)
1313
endfunction ()
1414

15+
macro(mmdeploy_add_net NAME)
16+
if (MMDEPLOY_DYNAMIC_BACKEND)
17+
mmdeploy_add_library(${NAME} SHARED ${ARGN})
18+
target_link_libraries(${PROJECT_NAME} PRIVATE mmdeploy)
19+
set(BACKEND_LIB_NAMES ${BACKEND_LIB_NAMES} ${PROJECT_NAME} PARENT_SCOPE)
20+
else ()
21+
mmdeploy_add_module(${NAME} ${ARGN})
22+
endif ()
23+
endmacro()
1524

1625
function (mmdeploy_add_library NAME)
1726
# EXCLUDE: exclude from registering & exporting

cmake/loader.cpp.in

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,37 @@
11
// Copyright (c) OpenMMLab. All rights reserved.
22

3-
#include <Windows.h>
4-
3+
#include <string>
54
#include <cstdio>
65

6+
#ifdef _WIN32
7+
#include <Windows.h>
8+
#else
9+
#include <dlfcn.h>
10+
#endif
11+
12+
#ifdef _WIN32
13+
#define LIBPREFIX ""
14+
#define LIBSUFFIX ".dll"
15+
#elif defined(__APPLE__)
16+
#define LIBPREFIX "lib"
17+
#define LIBSUFFIX ".dylib"
18+
#else
19+
#define LIBPREFIX "lib"
20+
#define LIBSUFFIX ".so"
21+
#endif
22+
723
namespace mmdeploy {
824
namespace {
925

1026
void* mmdeploy_load_library(const char* name) {
1127
fprintf(stderr, "loading %s ...\n", name);
12-
auto handle = LoadLibraryA(name);
28+
29+
#ifdef _WIN32
30+
auto handle = LoadLibraryExA(name, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
31+
#else
32+
auto handle = dlopen(name, RTLD_NOW | RTLD_GLOBAL);
33+
#endif
34+
1335
if (!handle) {
1436
fprintf(stderr, "failed to load library %s\n", name);
1537
return nullptr;
@@ -26,7 +48,8 @@ class Loader {
2648
@_MMDEPLOY_DYNAMIC_MODULES@
2749
};
2850
for (const auto name : modules) {
29-
mmdeploy_load_library(name);
51+
std::string libname = std::string{} + LIBPREFIX + name + LIBSUFFIX;
52+
mmdeploy_load_library(libname.c_str());
3053
}
3154
}
3255
};

csrc/mmdeploy/apis/c/CMakeLists.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,5 +80,14 @@ if (MMDEPLOY_BUILD_SDK_CSHARP_API OR MMDEPLOY_BUILD_SDK_MONOLITHIC)
8080
set_target_properties(mmdeploy PROPERTIES
8181
VERSION ${MMDEPLOY_VERSION}
8282
SOVERSION ${MMDEPLOY_VERSION_MAJOR})
83+
if (APPLE)
84+
set_target_properties(mmdeploy PROPERTIES
85+
INSTALL_RPATH "@loader_path"
86+
BUILD_RPATH "@loader_path")
87+
else ()
88+
set_target_properties(mmdeploy PROPERTIES
89+
INSTALL_RPATH "\$ORIGIN"
90+
BUILD_RPATH "\$ORIGIN")
91+
endif ()
8392
mmdeploy_export(mmdeploy)
8493
endif ()

csrc/mmdeploy/net/CMakeLists.txt

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
project(mmdeploy_net_module)
44

5+
set(BACKEND_LIB_NAMES)
6+
57
if ("trt" IN_LIST MMDEPLOY_TARGET_BACKENDS)
68
add_subdirectory(trt)
79
endif ()
@@ -46,5 +48,22 @@ if ("rknn" IN_LIST MMDEPLOY_TARGET_BACKENDS)
4648
add_subdirectory(rknn)
4749
endif ()
4850

49-
mmdeploy_add_module(${PROJECT_NAME} net_module.cpp)
51+
if (MMDEPLOY_DYNAMIC_BACKEND)
52+
set(_MODULE_STR ${BACKEND_LIB_NAMES})
53+
list(TRANSFORM _MODULE_STR REPLACE "(.+)" "\"\\1\"")
54+
string(JOIN ",\n " _MODULE_STR ${_MODULE_STR})
55+
set(_MMDEPLOY_DYNAMIC_MODULES ${_MODULE_STR})
56+
57+
set(_LOADER_NAME net_loader)
58+
set(_LOADER_PATH ${${PROJECT_NAME}_BINARY_DIR}/${_LOADER_NAME}.cpp)
59+
configure_file(
60+
${CMAKE_SOURCE_DIR}/cmake/loader.cpp.in
61+
${_LOADER_PATH})
62+
if (NOT (WIN32 OR APPLE))
63+
SET(_DL_LIB dl)
64+
endif ()
65+
endif ()
66+
67+
mmdeploy_add_module(${PROJECT_NAME} net_module.cpp ${_LOADER_PATH})
68+
target_link_libraries(${PROJECT_NAME} PUBLIC ${_DL_LIB})
5069
add_library(mmdeploy::net_module ALIAS ${PROJECT_NAME})

csrc/mmdeploy/net/coreml/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ project(mmdeploy_coreml_net)
55
if ("cpu" IN_LIST MMDEPLOY_TARGET_DEVICES)
66
find_library(CORE_ML CoreML)
77
find_library(FOUNDATION Foundation)
8-
mmdeploy_add_module(${PROJECT_NAME} coreml_net.mm)
8+
mmdeploy_add_net(${PROJECT_NAME} coreml_net.mm)
99
target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
1010
target_link_libraries(${PROJECT_NAME} PRIVATE ${CORE_ML} ${FOUNDATION})
1111
add_library(mmdeploy::coreml_net ALIAS ${PROJECT_NAME})

csrc/mmdeploy/net/ncnn/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ if ("cpu" IN_LIST MMDEPLOY_TARGET_DEVICES)
66

77
find_package(ncnn REQUIRED)
88

9-
mmdeploy_add_module(${PROJECT_NAME} ncnn_net.cpp)
9+
mmdeploy_add_net(${PROJECT_NAME} ncnn_net.cpp)
1010
target_link_libraries(${PROJECT_NAME} PRIVATE mmdeploy_ncnn_ops_obj)
1111
target_link_libraries(${PROJECT_NAME} PRIVATE ncnn)
1212
add_library(mmdeploy::ncnn_net ALIAS ${PROJECT_NAME})

csrc/mmdeploy/net/openvino/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ project(mmdeploy_openvino_net)
55
if ("cpu" IN_LIST MMDEPLOY_TARGET_DEVICES)
66
find_package(InferenceEngine REQUIRED)
77

8-
mmdeploy_add_module(${PROJECT_NAME} openvino_net.cpp)
8+
mmdeploy_add_net(${PROJECT_NAME} openvino_net.cpp)
99
target_link_libraries(${PROJECT_NAME} PRIVATE
1010
${InferenceEngine_LIBRARIES})
1111
add_library(mmdeploy::openvino_net ALIAS ${PROJECT_NAME})

csrc/mmdeploy/net/ort/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ project(mmdeploy_ort_net)
44

55
include(${CMAKE_SOURCE_DIR}/cmake/modules/FindONNXRUNTIME.cmake)
66

7-
mmdeploy_add_module(${PROJECT_NAME} ort_net.cpp)
7+
mmdeploy_add_net(${PROJECT_NAME} ort_net.cpp)
88
target_include_directories(${PROJECT_NAME} PRIVATE ${ONNXRUNTIME_DIR}/include)
99
target_link_libraries(${PROJECT_NAME} PRIVATE mmdeploy_onnxruntime_ops_obj)
1010
target_link_libraries(${PROJECT_NAME} PUBLIC onnxruntime)

csrc/mmdeploy/net/torchscript/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ if (MMDEPLOY_TORCHSCRIPT_SDK_BACKEND)
88
find_package(Torch REQUIRED)
99
find_package(TorchVision QUIET)
1010

11-
mmdeploy_add_module(${PROJECT_NAME} torch_net.cpp)
11+
mmdeploy_add_net(${PROJECT_NAME} torch_net.cpp)
1212

1313
target_link_libraries(${PROJECT_NAME} PRIVATE
1414
${TORCH_LIBRARIES})

0 commit comments

Comments
 (0)