Skip to content

Commit 855f001

Browse files
committed
feat: find and load externally built RIME plugins #431
1 parent bb8c263 commit 855f001

7 files changed

+88
-8
lines changed

CMakeLists.txt

+32-6
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,11 @@ option(ENABLE_LOGGING "Enable logging with google-glog library" ON)
2222
option(BOOST_USE_CXX11 "Boost has been built with C++11 support" OFF)
2323
option(BOOST_USE_SIGNALS2 "Boost use signals2 instead of signals" ON)
2424
option(ENABLE_ASAN "Enable Address Sanitizer (Unix Only)" OFF)
25+
option(INSTALL_PRIVATE_HEADERS "Install private headers (usually needed for externally built Rime plugins)" OFF)
26+
option(ENABLE_EXTERNAL_PLUGINS "Enable loading of externally built Rime plugins (from directory set by RIME_PLUGINS_DIR variable)" OFF)
2527

26-
set(rime_data_dir "/share/rime-data" CACHE STRING "Target directory for Rime data")
28+
set(RIME_DATA_DIR "${CMAKE_INSTALL_FULL_DATADIR}/rime-data" CACHE STRING "Target directory for Rime data")
29+
set(RIME_PLUGINS_DIR "${CMAKE_INSTALL_FULL_LIBDIR}/rime-plugins" CACHE STRING "Target directory for externally built Rime plugins")
2730

2831
if(WIN32)
2932
set(ext ".exe")
@@ -61,7 +64,7 @@ endif()
6164
set(BOOST_COMPONENTS filesystem regex system)
6265

6366
if(BOOST_USE_SIGNALS2)
64-
add_definitions("-DBOOST_SIGNALS2")
67+
set(RIME_BOOST_SIGNALS2 1)
6568
else()
6669
set(BOOST_COMPONENTS ${BOOST_COMPONENTS} signals)
6770
endif()
@@ -89,7 +92,7 @@ if(ENABLE_LOGGING)
8992
add_definitions(-DGOOGLE_GLOG_DLL_DECL=)
9093
endif()
9194

92-
add_definitions(-DRIME_ENABLE_LOGGING)
95+
set(RIME_ENABLE_LOGGING 1)
9396

9497
endif()
9598

@@ -134,6 +137,11 @@ else()
134137
message(WARNING "X11/keysym.h not found.")
135138
endif()
136139

140+
configure_file(
141+
"${PROJECT_SOURCE_DIR}/src/rime/build_config.h.in"
142+
"${PROJECT_BINARY_DIR}/src/rime/build_config.h")
143+
144+
include_directories(${PROJECT_BINARY_DIR}/src)
137145
include_directories(${PROJECT_SOURCE_DIR}/src)
138146
include_directories(${PROJECT_SOURCE_DIR}/thirdparty/include)
139147
link_directories(${PROJECT_SOURCE_DIR}/thirdparty/lib)
@@ -177,7 +185,8 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "Linux|FreeBSD|DragonFly|GNU")
177185
set(exec_prefix "${CMAKE_INSTALL_PREFIX}")
178186
set(bindir "${CMAKE_INSTALL_FULL_BINDIR}")
179187
set(libdir "${CMAKE_INSTALL_FULL_LIBDIR}")
180-
set(pkgdatadir "${CMAKE_INSTALL_PREFIX}${rime_data_dir}")
188+
set(pkgdatadir "${RIME_DATA_DIR}")
189+
set(pluginsdir "${RIME_PLUGINS_DIR}")
181190
set(includedir "${CMAKE_INSTALL_FULL_INCLUDEDIR}")
182191
configure_file(
183192
${PROJECT_SOURCE_DIR}/rime.pc.in
@@ -193,11 +202,23 @@ install(FILES cmake/RimeConfig.cmake
193202
file(GLOB rime_public_header_files ${PROJECT_SOURCE_DIR}/src/*.h)
194203
install(FILES ${rime_public_header_files}
195204
DESTINATION ${CMAKE_INSTALL_FULL_INCLUDEDIR})
205+
if(INSTALL_PRIVATE_HEADERS)
206+
file(GLOB rime_private_header_files
207+
${PROJECT_SOURCE_DIR}/src/rime/*.h
208+
${PROJECT_BINARY_DIR}/src/rime/*.h)
209+
install(FILES ${rime_private_header_files}
210+
DESTINATION ${CMAKE_INSTALL_FULL_INCLUDEDIR}/rime)
211+
foreach(rime_private_header_files_dir algo config dict gear lever)
212+
file(GLOB rime_private_header_files
213+
${PROJECT_SOURCE_DIR}/src/rime/${rime_private_header_files_dir}/*.h)
214+
install(FILES ${rime_private_header_files}
215+
DESTINATION ${CMAKE_INSTALL_FULL_INCLUDEDIR}/rime/${rime_private_header_files_dir})
216+
endforeach()
217+
endif()
196218

197219
if(BUILD_DATA)
198220
file(GLOB rime_preset_data_files ${PROJECT_SOURCE_DIR}/data/preset/*.yaml)
199-
install(FILES ${rime_preset_data_files}
200-
DESTINATION ${CMAKE_INSTALL_PREFIX}${rime_data_dir})
221+
install(FILES ${rime_preset_data_files} DESTINATION ${RIME_DATA_DIR})
201222
endif()
202223

203224
if(BUILD_SHARED_LIBS)
@@ -227,6 +248,11 @@ if(BUILD_SHARED_LIBS AND BUILD_SEPARATE_LIBS AND rime_plugins_objs)
227248
set(rime_plugins_library rime-plugins)
228249
endif()
229250

251+
add_definitions(-DRIME_PLUGINS_DIR="${RIME_PLUGINS_DIR}")
252+
if(ENABLE_EXTERNAL_PLUGINS)
253+
add_definitions(-DRIME_ENABLE_EXTERNAL_PLUGINS)
254+
endif()
255+
230256
add_subdirectory(src)
231257

232258
if(BUILD_SHARED_LIBS)

rime.pc.in

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ prefix=@prefix@
22
exec_prefix=@exec_prefix@
33
libdir=@libdir@
44
includedir=@includedir@
5+
pkgdatadir=@pkgdatadir@
6+
pluginsdir=@pluginsdir@
57

68
Name: Rime
79
Description: Rime Input Method Engine

src/CMakeLists.txt

+3
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ set(rime_optional_deps "")
3636
if(Gflags_FOUND)
3737
set(rime_optional_deps ${rime_optional_deps} ${Gflags_LIBRARY})
3838
endif()
39+
if(ENABLE_EXTERNAL_PLUGINS)
40+
set(rime_optional_deps ${rime_optional_deps} dl)
41+
endif()
3942

4043
set(rime_core_deps
4144
${Boost_LIBRARIES}

src/rime/build_config.h.in

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
//
2+
// Copyright RIME Developers
3+
// Distributed under the BSD License
4+
//
5+
#ifndef RIME_BUILD_CONFIG_H_
6+
#define RIME_BUILD_CONFIG_H_
7+
8+
#cmakedefine RIME_BOOST_SIGNALS2
9+
#cmakedefine RIME_ENABLE_LOGGING
10+
11+
#endif // RIME_BUILD_CONFIG_H_

src/rime/common.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
#ifndef RIME_COMMON_H_
88
#define RIME_COMMON_H_
99

10+
#include <rime/build_config.h>
11+
1012
#include <functional>
1113
#include <list>
1214
#include <map>
@@ -20,7 +22,7 @@
2022
#include <vector>
2123
#include <boost/optional.hpp>
2224
#define BOOST_BIND_NO_PLACEHOLDERS
23-
#ifdef BOOST_SIGNALS2
25+
#ifdef RIME_BOOST_SIGNALS2
2426
#include <boost/signals2/connection.hpp>
2527
#include <boost/signals2/signal.hpp>
2628
#else
@@ -79,7 +81,7 @@ inline an<T> New(Args&&... args) {
7981
return std::make_shared<T>(std::forward<Args>(args)...);
8082
}
8183

82-
#ifdef BOOST_SIGNALS2
84+
#ifdef RIME_BOOST_SIGNALS2
8385
using boost::signals2::connection;
8486
using boost::signals2::signal;
8587
#else

src/rime/lever/deployment_tasks.cc

+3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
//
55
// 2011-12-10 GONG Chen <chen.sst@gmail.com>
66
//
7+
8+
#include <rime/build_config.h>
9+
710
#include <algorithm>
811
#include <boost/algorithm/string.hpp>
912
#include <boost/filesystem.hpp>

src/rime/setup.cc

+33
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@
55
// 2011-10-02 GONG Chen <chen.sst@gmail.com>
66
//
77

8+
#include <rime/build_config.h>
9+
10+
#ifdef RIME_ENABLE_EXTERNAL_PLUGINS
11+
#include <dlfcn.h>
12+
#include <glob.h>
13+
#endif // RIME_ENABLE_EXTERNAL_PLUGINS
14+
815
#ifdef RIME_ENABLE_LOGGING
916
#include <glog/logging.h>
1017
#endif // RIME_ENABLE_LOGGING
@@ -36,6 +43,32 @@ RIME_API void LoadModules(const char* module_names[]) {
3643
mm.LoadModule(module);
3744
}
3845
}
46+
47+
#ifdef RIME_ENABLE_EXTERNAL_PLUGINS
48+
fs::path plugins_dir = fs::path(RIME_PLUGINS_DIR);
49+
fs::path plugins_files = plugins_dir / "*.so";
50+
glob_t glob_buffer;
51+
if (glob(plugins_files.string().c_str(), 0, NULL, &glob_buffer) == 0) {
52+
for (size_t i = 0; i < glob_buffer.gl_pathc; i++) {
53+
fs::path plugin_file(glob_buffer.gl_pathv[i]);
54+
fs::path plugin_name = plugin_file.stem();
55+
fs::file_status plugin_file_status = fs::status(plugin_file);
56+
if (fs::is_regular_file(plugin_file) &&
57+
plugin_file_status.permissions() & (fs::owner_exe | fs::group_exe | fs::others_exe)) {
58+
void* handle = dlopen(plugin_file.string().c_str(), RTLD_LAZY);
59+
if (handle) {
60+
if (RimeModule* module = mm.Find(plugin_name.string())) {
61+
mm.LoadModule(module);
62+
}
63+
}
64+
else {
65+
LOG(ERROR) << "dlopen error: " << dlerror();
66+
}
67+
}
68+
}
69+
globfree(&glob_buffer);
70+
}
71+
#endif
3972
}
4073

4174
// assume member is a non-null pointer in struct *p.

0 commit comments

Comments
 (0)