Skip to content

Commit

Permalink
feat: find and load externally built RIME plugins #431
Browse files Browse the repository at this point in the history
  • Loading branch information
lotem committed Jan 11, 2021
1 parent bb8c263 commit 855f001
Show file tree
Hide file tree
Showing 7 changed files with 88 additions and 8 deletions.
38 changes: 32 additions & 6 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,11 @@ option(ENABLE_LOGGING "Enable logging with google-glog library" ON)
option(BOOST_USE_CXX11 "Boost has been built with C++11 support" OFF)
option(BOOST_USE_SIGNALS2 "Boost use signals2 instead of signals" ON)
option(ENABLE_ASAN "Enable Address Sanitizer (Unix Only)" OFF)
option(INSTALL_PRIVATE_HEADERS "Install private headers (usually needed for externally built Rime plugins)" OFF)
option(ENABLE_EXTERNAL_PLUGINS "Enable loading of externally built Rime plugins (from directory set by RIME_PLUGINS_DIR variable)" OFF)

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

if(WIN32)
set(ext ".exe")
Expand Down Expand Up @@ -61,7 +64,7 @@ endif()
set(BOOST_COMPONENTS filesystem regex system)

if(BOOST_USE_SIGNALS2)
add_definitions("-DBOOST_SIGNALS2")
set(RIME_BOOST_SIGNALS2 1)
else()
set(BOOST_COMPONENTS ${BOOST_COMPONENTS} signals)
endif()
Expand Down Expand Up @@ -89,7 +92,7 @@ if(ENABLE_LOGGING)
add_definitions(-DGOOGLE_GLOG_DLL_DECL=)
endif()

add_definitions(-DRIME_ENABLE_LOGGING)
set(RIME_ENABLE_LOGGING 1)

endif()

Expand Down Expand Up @@ -134,6 +137,11 @@ else()
message(WARNING "X11/keysym.h not found.")
endif()

configure_file(
"${PROJECT_SOURCE_DIR}/src/rime/build_config.h.in"
"${PROJECT_BINARY_DIR}/src/rime/build_config.h")

include_directories(${PROJECT_BINARY_DIR}/src)
include_directories(${PROJECT_SOURCE_DIR}/src)
include_directories(${PROJECT_SOURCE_DIR}/thirdparty/include)
link_directories(${PROJECT_SOURCE_DIR}/thirdparty/lib)
Expand Down Expand Up @@ -177,7 +185,8 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "Linux|FreeBSD|DragonFly|GNU")
set(exec_prefix "${CMAKE_INSTALL_PREFIX}")
set(bindir "${CMAKE_INSTALL_FULL_BINDIR}")
set(libdir "${CMAKE_INSTALL_FULL_LIBDIR}")
set(pkgdatadir "${CMAKE_INSTALL_PREFIX}${rime_data_dir}")
set(pkgdatadir "${RIME_DATA_DIR}")
set(pluginsdir "${RIME_PLUGINS_DIR}")
set(includedir "${CMAKE_INSTALL_FULL_INCLUDEDIR}")
configure_file(
${PROJECT_SOURCE_DIR}/rime.pc.in
Expand All @@ -193,11 +202,23 @@ install(FILES cmake/RimeConfig.cmake
file(GLOB rime_public_header_files ${PROJECT_SOURCE_DIR}/src/*.h)
install(FILES ${rime_public_header_files}
DESTINATION ${CMAKE_INSTALL_FULL_INCLUDEDIR})
if(INSTALL_PRIVATE_HEADERS)
file(GLOB rime_private_header_files
${PROJECT_SOURCE_DIR}/src/rime/*.h
${PROJECT_BINARY_DIR}/src/rime/*.h)
install(FILES ${rime_private_header_files}
DESTINATION ${CMAKE_INSTALL_FULL_INCLUDEDIR}/rime)
foreach(rime_private_header_files_dir algo config dict gear lever)
file(GLOB rime_private_header_files
${PROJECT_SOURCE_DIR}/src/rime/${rime_private_header_files_dir}/*.h)
install(FILES ${rime_private_header_files}
DESTINATION ${CMAKE_INSTALL_FULL_INCLUDEDIR}/rime/${rime_private_header_files_dir})
endforeach()
endif()

if(BUILD_DATA)
file(GLOB rime_preset_data_files ${PROJECT_SOURCE_DIR}/data/preset/*.yaml)
install(FILES ${rime_preset_data_files}
DESTINATION ${CMAKE_INSTALL_PREFIX}${rime_data_dir})
install(FILES ${rime_preset_data_files} DESTINATION ${RIME_DATA_DIR})
endif()

if(BUILD_SHARED_LIBS)
Expand Down Expand Up @@ -227,6 +248,11 @@ if(BUILD_SHARED_LIBS AND BUILD_SEPARATE_LIBS AND rime_plugins_objs)
set(rime_plugins_library rime-plugins)
endif()

add_definitions(-DRIME_PLUGINS_DIR="${RIME_PLUGINS_DIR}")
if(ENABLE_EXTERNAL_PLUGINS)
add_definitions(-DRIME_ENABLE_EXTERNAL_PLUGINS)
endif()

add_subdirectory(src)

if(BUILD_SHARED_LIBS)
Expand Down
2 changes: 2 additions & 0 deletions rime.pc.in
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
pkgdatadir=@pkgdatadir@
pluginsdir=@pluginsdir@

Name: Rime
Description: Rime Input Method Engine
Expand Down
3 changes: 3 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ set(rime_optional_deps "")
if(Gflags_FOUND)
set(rime_optional_deps ${rime_optional_deps} ${Gflags_LIBRARY})
endif()
if(ENABLE_EXTERNAL_PLUGINS)
set(rime_optional_deps ${rime_optional_deps} dl)
endif()

set(rime_core_deps
${Boost_LIBRARIES}
Expand Down
11 changes: 11 additions & 0 deletions src/rime/build_config.h.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
//
// Copyright RIME Developers
// Distributed under the BSD License
//
#ifndef RIME_BUILD_CONFIG_H_
#define RIME_BUILD_CONFIG_H_

#cmakedefine RIME_BOOST_SIGNALS2
#cmakedefine RIME_ENABLE_LOGGING

#endif // RIME_BUILD_CONFIG_H_
6 changes: 4 additions & 2 deletions src/rime/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
#ifndef RIME_COMMON_H_
#define RIME_COMMON_H_

#include <rime/build_config.h>

#include <functional>
#include <list>
#include <map>
Expand All @@ -20,7 +22,7 @@
#include <vector>
#include <boost/optional.hpp>
#define BOOST_BIND_NO_PLACEHOLDERS
#ifdef BOOST_SIGNALS2
#ifdef RIME_BOOST_SIGNALS2
#include <boost/signals2/connection.hpp>
#include <boost/signals2/signal.hpp>
#else
Expand Down Expand Up @@ -79,7 +81,7 @@ inline an<T> New(Args&&... args) {
return std::make_shared<T>(std::forward<Args>(args)...);
}

#ifdef BOOST_SIGNALS2
#ifdef RIME_BOOST_SIGNALS2
using boost::signals2::connection;
using boost::signals2::signal;
#else
Expand Down
3 changes: 3 additions & 0 deletions src/rime/lever/deployment_tasks.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
//
// 2011-12-10 GONG Chen <chen.sst@gmail.com>
//

#include <rime/build_config.h>

#include <algorithm>
#include <boost/algorithm/string.hpp>
#include <boost/filesystem.hpp>
Expand Down
33 changes: 33 additions & 0 deletions src/rime/setup.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@
// 2011-10-02 GONG Chen <chen.sst@gmail.com>
//

#include <rime/build_config.h>

#ifdef RIME_ENABLE_EXTERNAL_PLUGINS
#include <dlfcn.h>
#include <glob.h>
#endif // RIME_ENABLE_EXTERNAL_PLUGINS

#ifdef RIME_ENABLE_LOGGING
#include <glog/logging.h>
#endif // RIME_ENABLE_LOGGING
Expand Down Expand Up @@ -36,6 +43,32 @@ RIME_API void LoadModules(const char* module_names[]) {
mm.LoadModule(module);
}
}

#ifdef RIME_ENABLE_EXTERNAL_PLUGINS
fs::path plugins_dir = fs::path(RIME_PLUGINS_DIR);
fs::path plugins_files = plugins_dir / "*.so";
glob_t glob_buffer;
if (glob(plugins_files.string().c_str(), 0, NULL, &glob_buffer) == 0) {
for (size_t i = 0; i < glob_buffer.gl_pathc; i++) {
fs::path plugin_file(glob_buffer.gl_pathv[i]);
fs::path plugin_name = plugin_file.stem();
fs::file_status plugin_file_status = fs::status(plugin_file);
if (fs::is_regular_file(plugin_file) &&
plugin_file_status.permissions() & (fs::owner_exe | fs::group_exe | fs::others_exe)) {
void* handle = dlopen(plugin_file.string().c_str(), RTLD_LAZY);
if (handle) {
if (RimeModule* module = mm.Find(plugin_name.string())) {
mm.LoadModule(module);
}
}
else {
LOG(ERROR) << "dlopen error: " << dlerror();
}
}
}
globfree(&glob_buffer);
}
#endif
}

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

0 comments on commit 855f001

Please sign in to comment.