diff --git a/CMakeLists.txt b/CMakeLists.txt index 66322fe2fb..c993c628d3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,8 +27,8 @@ option(ENABLE_EXTERNAL_PLUGINS "Enable loading of externally built Rime plugins option(ENABLE_THREADING "Enable threading for deployer" ON) option(ENABLE_TIMESTAMP "Embed timestamp to schema artifacts" ON) -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") +set(RIME_DATA_DIR "rime-data" CACHE STRING "Target directory for Rime data") +set(RIME_PLUGINS_DIR "rime-plugins" CACHE STRING "Target directory for externally built Rime plugins") if(WIN32) set(ext ".exe") @@ -205,8 +205,8 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "Linux|FreeBSD|DragonFly|GNU|Darwin" OR MINGW) set(exec_prefix "${CMAKE_INSTALL_PREFIX}") set(bindir "${CMAKE_INSTALL_FULL_BINDIR}") set(libdir "${CMAKE_INSTALL_FULL_LIBDIR}") - set(pkgdatadir "${RIME_DATA_DIR}") - set(pluginsdir "${RIME_PLUGINS_DIR}") + set(pkgdatadir "${CMAKE_INSTALL_FULL_DATADIR}/${RIME_DATA_DIR}") + set(pluginsdir "${CMAKE_INSTALL_FULL_LIBDIR}/${RIME_PLUGINS_DIR}") set(includedir "${CMAKE_INSTALL_FULL_INCLUDEDIR}") configure_file( ${PROJECT_SOURCE_DIR}/rime.pc.in @@ -238,7 +238,7 @@ endif() if(BUILD_DATA) file(GLOB rime_preset_data_files ${PROJECT_SOURCE_DIR}/data/preset/*.yaml) - install(FILES ${rime_preset_data_files} DESTINATION ${RIME_DATA_DIR}) + install(FILES ${rime_preset_data_files} DESTINATION ${CMAKE_INSTALL_FULL_DATADIR}/${RIME_DATA_DIR}) endif() if(BUILD_SHARED_LIBS) diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index 9e6fe47e0e..09af61330c 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -1,5 +1,4 @@ set(RIME_SOURCE_DIR ${PROJECT_SOURCE_DIR}) -set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib) # work around CMake build issues on macOS set(rime_plugin_boilerplate_src "plugin.cc") @@ -55,10 +54,14 @@ foreach(plugin ${plugins}) message(STATUS "Plugin ${plugin_name} provides modules: ${plugin_modules}") add_library(${plugin_name} ${rime_plugin_boilerplate_src} ${plugin_objs}) target_link_libraries(${plugin_name} ${plugin_deps}) + set_target_properties(${plugin_name} + PROPERTIES + LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib/${RIME_PLUGINS_DIR} + RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin/${RIME_PLUGINS_DIR}) if(XCODE_VERSION) set_target_properties(${plugin_name} PROPERTIES INSTALL_NAME_DIR "@rpath") endif(XCODE_VERSION) - install(TARGETS ${plugin_name} DESTINATION ${RIME_PLUGINS_DIR}) + install(TARGETS ${plugin_name} DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR}/${RIME_PLUGINS_DIR}) endif() endforeach(plugin) diff --git a/plugins/plugins_module.cc b/plugins/plugins_module.cc index 6c191cab9e..8492cfe87e 100644 --- a/plugins/plugins_module.cc +++ b/plugins/plugins_module.cc @@ -93,8 +93,35 @@ PluginManager& PluginManager::instance() { } // namespace rime +#ifdef _WIN32 +// TODO: implement this when ready to support DLL plugins on Windows. +inline static rime::path current_module_path() { + return rime::path{}; +} +#else +#include + +inline static rime::path symbol_location(const void* symbol) { + Dl_info info; + // Some of the libc headers miss `const` in `dladdr(const void*, Dl_info*)` + const int res = dladdr(const_cast(symbol), &info); + if (res) { + return rime::path{info.dli_fname}; + } else { + return rime::path{}; + } +} + +inline static rime::path current_module_path() { + void rime_require_module_plugins(); + return symbol_location( + reinterpret_cast(&rime_require_module_plugins)); +} +#endif + static void rime_plugins_initialize() { - rime::PluginManager::instance().LoadPlugins(rime::path(RIME_PLUGINS_DIR)); + rime::PluginManager::instance().LoadPlugins( + current_module_path().remove_filename() / RIME_PLUGINS_DIR); } static void rime_plugins_finalize() {}