From 8ad6f89fed092d3de8e36ee1c949c98aa48e32c7 Mon Sep 17 00:00:00 2001 From: Matthieu Gallien Date: Fri, 11 Jun 2021 19:17:10 +0200 Subject: [PATCH] bring back dynamic load of VFS plugins Signed-off-by: Matthieu Gallien --- admin/win/msi/Nextcloud.wxs | 3 - src/common/common.cmake | 2 + src/common/plugin.cpp | 33 +++++++++++ src/common/plugin.h | 48 ++++++++++++++++ src/common/vfs.cpp | 78 ++++++++++++++++++-------- src/common/vfs.h | 4 -- src/libsync/CMakeLists.txt | 21 +------ src/libsync/propagatedownload.h | 3 +- src/libsync/vfs/CMakeLists.txt | 30 ++++++++++ src/libsync/vfs/cfapi/CMakeLists.txt | 36 ++++++++++++ src/libsync/vfs/cfapi/cfapiwrapper.cpp | 2 + src/libsync/vfs/cfapi/cfapiwrapper.h | 30 +++++----- src/libsync/vfs/cfapi/hydrationjob.h | 2 +- src/libsync/vfs/cfapi/vfs_cfapi.cpp | 4 +- src/libsync/vfs/cfapi/vfs_cfapi.h | 8 +++ src/libsync/vfs/suffix/CMakeLists.txt | 34 +++++++++++ src/libsync/vfs/suffix/vfs_suffix.cpp | 2 - src/libsync/vfs/suffix/vfs_suffix.h | 8 +++ src/libsync/vfs/xattr/CMakeLists.txt | 50 +++++++++++++++++ src/libsync/vfs/xattr/vfs_xattr.cpp | 2 - src/libsync/vfs/xattr/vfs_xattr.h | 8 +++ src/libsync/vfs/xattr/xattrwrapper.h | 2 + test/CMakeLists.txt | 4 ++ test/nextcloud_add_test.cmake | 12 ++++ 24 files changed, 353 insertions(+), 73 deletions(-) create mode 100644 src/common/plugin.cpp create mode 100644 src/common/plugin.h create mode 100644 src/libsync/vfs/CMakeLists.txt create mode 100644 src/libsync/vfs/cfapi/CMakeLists.txt create mode 100644 src/libsync/vfs/suffix/CMakeLists.txt create mode 100644 src/libsync/vfs/xattr/CMakeLists.txt diff --git a/admin/win/msi/Nextcloud.wxs b/admin/win/msi/Nextcloud.wxs index 18b13159a..04b1db0f0 100644 --- a/admin/win/msi/Nextcloud.wxs +++ b/admin/win/msi/Nextcloud.wxs @@ -52,9 +52,6 @@ - - - diff --git a/src/common/common.cmake b/src/common/common.cmake index 82437cd04..5c7cd52c9 100644 --- a/src/common/common.cmake +++ b/src/common/common.cmake @@ -11,6 +11,8 @@ set(common_SOURCES ${CMAKE_CURRENT_LIST_DIR}/remotepermissions.cpp ${CMAKE_CURRENT_LIST_DIR}/vfs.cpp ${CMAKE_CURRENT_LIST_DIR}/pinstate.cpp + ${CMAKE_CURRENT_LIST_DIR}/plugin.cpp ${CMAKE_CURRENT_LIST_DIR}/syncfilestatus.cpp ) +configure_file(${CMAKE_CURRENT_LIST_DIR}/vfspluginmetadata.json.in ${CMAKE_CURRENT_BINARY_DIR}/vfspluginmetadata.json) diff --git a/src/common/plugin.cpp b/src/common/plugin.cpp new file mode 100644 index 000000000..7e705d94e --- /dev/null +++ b/src/common/plugin.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (C) by Dominik Schmidt + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "plugin.h" + +#include "config.h" + +namespace OCC { + +PluginFactory::~PluginFactory() = default; + +QString pluginFileName(const QString &type, const QString &name) +{ + return QStringLiteral("%1sync_%2_%3") + .arg(QStringLiteral(APPLICATION_EXECUTABLE), type, name); +} + +} diff --git a/src/common/plugin.h b/src/common/plugin.h new file mode 100644 index 000000000..3d28f7dd3 --- /dev/null +++ b/src/common/plugin.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) by Dominik Schmidt + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#pragma once + +#include "ocsynclib.h" +#include + +namespace OCC { + +class OCSYNC_EXPORT PluginFactory +{ +public: + virtual ~PluginFactory(); + virtual QObject* create(QObject* parent) = 0; +}; + +template +class DefaultPluginFactory : public PluginFactory +{ +public: + QObject* create(QObject *parent) override + { + return new PluginClass(parent); + } +}; + +/// Return the expected name of a plugin, for use with QPluginLoader +QString pluginFileName(const QString &type, const QString &name); + +} + +Q_DECLARE_INTERFACE(OCC::PluginFactory, "org.owncloud.PluginFactory") diff --git a/src/common/vfs.cpp b/src/common/vfs.cpp index e9cf977d9..71ff5dae0 100644 --- a/src/common/vfs.cpp +++ b/src/common/vfs.cpp @@ -17,6 +17,7 @@ */ #include "vfs.h" +#include "plugin.h" #include "version.h" #include "syncjournaldb.h" @@ -27,15 +28,6 @@ using namespace OCC; -using MetaObjectHash = QHash; -Q_GLOBAL_STATIC(MetaObjectHash, vfsFactoryHash); - -void Vfs::registerPlugin(const QString &name, Factory factory) -{ - Q_ASSERT(!vfsFactoryHash()->contains(name)); - vfsFactoryHash()->insert(name, factory); -} - Vfs::Vfs(QObject* parent) : QObject(parent) { @@ -83,7 +75,8 @@ Result Vfs::checkAvailability(const QString &path) } } #else - Q_UNUSED(path); + Q_UNUSED(mode) + Q_UNUSED(path) #endif return true; } @@ -146,7 +139,7 @@ static QString modeToPluginName(Vfs::Mode mode) if (mode == Vfs::WithSuffix) return QStringLiteral("suffix"); if (mode == Vfs::WindowsCfApi) - return QStringLiteral("win"); + return QStringLiteral("cfapi"); if (mode == Vfs::XAttr) return QStringLiteral("xattr"); return QString(); @@ -157,14 +150,41 @@ Q_LOGGING_CATEGORY(lcPlugin, "plugins", QtInfoMsg) bool OCC::isVfsPluginAvailable(Vfs::Mode mode) { // TODO: cache plugins available? - if (mode == Vfs::Off) + if (mode == Vfs::Off) { return true; - auto name = modeToPluginName(mode); - if (name.isEmpty()) - return false; + } - if (!vfsFactoryHash()->contains(name)) { - qCDebug(lcPlugin) << "Plugin isn't registered:" << name; + auto name = modeToPluginName(mode); + if (name.isEmpty()) { + return false; + } + + QPluginLoader loader(pluginFileName(QStringLiteral("vfs"), name)); + + const auto baseMetaData = loader.metaData(); + if (baseMetaData.isEmpty() || !baseMetaData.contains(QStringLiteral("IID"))) { + qCDebug(lcPlugin) << "Plugin doesn't exist" << loader.fileName(); + return false; + } + if (baseMetaData[QStringLiteral("IID")].toString() != QStringLiteral("org.owncloud.PluginFactory")) { + qCWarning(lcPlugin) << "Plugin has wrong IID" << loader.fileName() << baseMetaData[QStringLiteral("IID")]; + return false; + } + + const auto metadata = baseMetaData[QStringLiteral("MetaData")].toObject(); + if (metadata[QStringLiteral("type")].toString() != QStringLiteral("vfs")) { + qCWarning(lcPlugin) << "Plugin has wrong type" << loader.fileName() << metadata[QStringLiteral("type")]; + return false; + } + if (metadata[QStringLiteral("version")].toString() != QStringLiteral(MIRALL_VERSION_STRING)) { + qCWarning(lcPlugin) << "Plugin has wrong version" << loader.fileName() << metadata[QStringLiteral("version")]; + return false; + } + + // Attempting to load the plugin is essential as it could have dependencies that + // can't be resolved and thus not be available after all. + if (!loader.load()) { + qCWarning(lcPlugin) << "Plugin failed to load:" << loader.errorString(); return false; } @@ -210,26 +230,36 @@ std::unique_ptr OCC::createVfsFromPlugin(Vfs::Mode mode) return std::unique_ptr(new VfsOff); auto name = modeToPluginName(mode); - if (name.isEmpty()) + if (name.isEmpty()) { return nullptr; + } + + const auto pluginPath = pluginFileName(QStringLiteral("vfs"), name); if (!isVfsPluginAvailable(mode)) { - qCCritical(lcPlugin) << "Could not load plugin: not existant" << name; + qCCritical(lcPlugin) << "Could not load plugin: not existant or bad metadata" << pluginPath; return nullptr; } - const auto factory = vfsFactoryHash()->value(name); + QPluginLoader loader(pluginPath); + auto plugin = loader.instance(); + if (!plugin) { + qCCritical(lcPlugin) << "Could not load plugin" << pluginPath << loader.errorString(); + return nullptr; + } + + auto factory = qobject_cast(plugin); if (!factory) { - qCCritical(lcPlugin) << "Could not load plugin" << name; + qCCritical(lcPlugin) << "Plugin" << loader.fileName() << "does not implement PluginFactory"; return nullptr; } - auto vfs = std::unique_ptr(qobject_cast(factory())); + auto vfs = std::unique_ptr(qobject_cast(factory->create(nullptr))); if (!vfs) { - qCCritical(lcPlugin) << "Plugin" << name << "does not create a Vfs instance"; + qCCritical(lcPlugin) << "Plugin" << loader.fileName() << "does not create a Vfs instance"; return nullptr; } - qCInfo(lcPlugin) << "Created VFS instance for:" << name; + qCInfo(lcPlugin) << "Created VFS instance from plugin" << pluginPath; return vfs; } diff --git a/src/common/vfs.h b/src/common/vfs.h index 1435f2633..0f12f8c2e 100644 --- a/src/common/vfs.h +++ b/src/common/vfs.h @@ -14,7 +14,6 @@ #pragma once #include -#include #include #include @@ -126,9 +125,6 @@ public: using AvailabilityResult = Result; public: - using Factory = Vfs* (*)(); - static void registerPlugin(const QString &name, Factory factory); - explicit Vfs(QObject* parent = nullptr); virtual ~Vfs(); diff --git a/src/libsync/CMakeLists.txt b/src/libsync/CMakeLists.txt index dad4eba10..40a98e1c9 100644 --- a/src/libsync/CMakeLists.txt +++ b/src/libsync/CMakeLists.txt @@ -58,26 +58,8 @@ set(libsync_SRCS creds/abstractcredentials.cpp creds/credentialscommon.cpp creds/keychainchunk.cpp - vfs/suffix/vfs_suffix.cpp ) -if (WIN32) - set(libsync_SRCS ${libsync_SRCS} - vfs/cfapi/cfapiwrapper.cpp - vfs/cfapi/hydrationjob.cpp - vfs/cfapi/vfs_cfapi.cpp - ) - add_definitions(-D_WIN32_WINNT=_WIN32_WINNT_WIN10) - list(APPEND OS_SPECIFIC_LINK_LIBRARIES cldapi) -elseif(LINUX) # elseif(LINUX OR APPLE) - set(libsync_SRCS ${libsync_SRCS} vfs/xattr/vfs_xattr.cpp) - if (APPLE) - set(libsync_SRCS ${libsync_SRCS} vfs/xattr/xattrwrapper_mac.cpp) - else() - set(libsync_SRCS ${libsync_SRCS} vfs/xattr/xattrwrapper_linux.cpp) - endif() -endif() - if(TOKEN_AUTH_ONLY) set (libsync_SRCS ${libsync_SRCS} creds/tokencredentials.cpp) else() @@ -159,3 +141,6 @@ if(NOT BUILD_OWNCLOUD_OSX_BUNDLE) else() install(TARGETS ${synclib_NAME} DESTINATION ${OWNCLOUD_OSX_BUNDLE}/Contents/MacOS) endif() + + +add_subdirectory(vfs) diff --git a/src/libsync/propagatedownload.h b/src/libsync/propagatedownload.h index 3b568a329..963bf1055 100644 --- a/src/libsync/propagatedownload.h +++ b/src/libsync/propagatedownload.h @@ -13,6 +13,7 @@ */ #pragma once +#include "owncloudlib.h" #include "owncloudpropagator.h" #include "networkjobs.h" #include "clientsideencryption.h" @@ -27,7 +28,7 @@ class PropagateDownloadEncrypted; * @brief The GETFileJob class * @ingroup libsync */ -class GETFileJob : public AbstractNetworkJob +class OWNCLOUDSYNC_EXPORT GETFileJob : public AbstractNetworkJob { Q_OBJECT QIODevice *_device; diff --git a/src/libsync/vfs/CMakeLists.txt b/src/libsync/vfs/CMakeLists.txt new file mode 100644 index 000000000..e7ad8da57 --- /dev/null +++ b/src/libsync/vfs/CMakeLists.txt @@ -0,0 +1,30 @@ +# Globbing for plugins has a problem with in-source builds +# that create directories for the build. +#file(GLOB VIRTUAL_FILE_SYSTEM_PLUGINS RELATIVE ${CMAKE_CURRENT_LIST_DIR} "*") + +list(APPEND VIRTUAL_FILE_SYSTEM_PLUGINS "suffix" "cfapi" "xattr") + +message("list of plugins ${VIRTUAL_FILE_SYSTEM_PLUGINS}") + +foreach(vfsPlugin ${VIRTUAL_FILE_SYSTEM_PLUGINS}) + set(vfsPluginPath ${vfsPlugin}) + get_filename_component(vfsPluginName ${vfsPlugin} NAME) + message("discovery ${vfsPlugin}") + if (NOT IS_ABSOLUTE ${vfsPlugin}) + set(vfsPluginPath "${CMAKE_CURRENT_SOURCE_DIR}/${vfsPlugin}") + message("${vfsPluginPath}") + endif() + if(NOT IS_DIRECTORY ${vfsPluginPath}) + continue() + endif() + + message("${vfsPluginPath} ${vfsPluginName}") + add_subdirectory(${vfsPluginPath} ${vfsPluginName}) + + if(UNIT_TESTING AND IS_DIRECTORY "${vfsPluginPath}/test") + add_subdirectory("${vfsPluginPath}/test" "${vfsPluginName}_test") + message(STATUS "Added vfsPlugin with tests: ${vfsPluginName}") + else() + message(STATUS "Added vfsPlugin without tests: ${vfsPluginName}") + endif() +endforeach() diff --git a/src/libsync/vfs/cfapi/CMakeLists.txt b/src/libsync/vfs/cfapi/CMakeLists.txt new file mode 100644 index 000000000..77392c21f --- /dev/null +++ b/src/libsync/vfs/cfapi/CMakeLists.txt @@ -0,0 +1,36 @@ +if (WIN32) + add_definitions(-D_WIN32_WINNT=_WIN32_WINNT_WIN10) + + add_library("${synclib_NAME}_vfs_cfapi" SHARED + cfapiwrapper.cpp + hydrationjob.cpp + vfs_cfapi.cpp + ) + + target_link_libraries("${synclib_NAME}_vfs_cfapi" + "${synclib_NAME}" + cldapi + ) + + set_target_properties("${synclib_NAME}_vfs_cfapi" PROPERTIES + LIBRARY_OUTPUT_DIRECTORY ${BIN_OUTPUT_DIRECTORY} + RUNTIME_OUTPUT_DIRECTORY ${BIN_OUTPUT_DIRECTORY} + PREFIX "" + AUTOMOC TRUE + ) + + target_include_directories("${synclib_NAME}_vfs_cfapi" BEFORE PUBLIC ${CMAKE_CURRENT_BINARY_DIR} INTERFACE ${CMAKE_BINARY_DIR}) + + set(vfs_installdir "${PLUGINDIR}") + + GENERATE_EXPORT_HEADER( "${synclib_NAME}_vfs_cfapi" + BASE_NAME "${synclib_NAME}_vfs_cfapi" + EXPORT_MACRO_NAME NEXTCLOUD_CFAPI_EXPORT + EXPORT_FILE_NAME cfapiexport.h + ) + + INSTALL(TARGETS "${synclib_NAME}_vfs_cfapi" + LIBRARY DESTINATION "${vfs_installdir}" + RUNTIME DESTINATION "${vfs_installdir}" + ) +endif() diff --git a/src/libsync/vfs/cfapi/cfapiwrapper.cpp b/src/libsync/vfs/cfapi/cfapiwrapper.cpp index 732b68d78..02ed7d362 100644 --- a/src/libsync/vfs/cfapi/cfapiwrapper.cpp +++ b/src/libsync/vfs/cfapi/cfapiwrapper.cpp @@ -19,6 +19,8 @@ #include "hydrationjob.h" #include "vfs_cfapi.h" +#include +#include #include #include #include diff --git a/src/libsync/vfs/cfapi/cfapiwrapper.h b/src/libsync/vfs/cfapi/cfapiwrapper.h index d81dfe936..e6f4ac8b9 100644 --- a/src/libsync/vfs/cfapi/cfapiwrapper.h +++ b/src/libsync/vfs/cfapi/cfapiwrapper.h @@ -15,7 +15,7 @@ #include -#include "owncloudlib.h" +#include "cfapiexport.h" #include "common/pinstate.h" #include "common/result.h" #include "common/vfs.h" @@ -29,7 +29,7 @@ class VfsCfApi; namespace CfApiWrapper { -class OWNCLOUDSYNC_EXPORT ConnectionKey +class NEXTCLOUD_CFAPI_EXPORT ConnectionKey { public: ConnectionKey(); @@ -39,7 +39,7 @@ private: std::unique_ptr _data; }; -class OWNCLOUDSYNC_EXPORT FileHandle +class NEXTCLOUD_CFAPI_EXPORT FileHandle { public: using Deleter = void (*)(void *); @@ -54,7 +54,7 @@ private: std::unique_ptr _data; }; -class OWNCLOUDSYNC_EXPORT PlaceHolderInfo +class NEXTCLOUD_CFAPI_EXPORT PlaceHolderInfo { public: using Deleter = void (*)(CF_PLACEHOLDER_BASIC_INFO *); @@ -72,17 +72,17 @@ private: std::unique_ptr _data; }; -OWNCLOUDSYNC_EXPORT Result registerSyncRoot(const QString &path, const QString &providerName, const QString &providerVersion, const QString &folderAlias, const QString &displayName, const QString &accountDisplayName); -OWNCLOUDSYNC_EXPORT Result unregisterSyncRoot(const QString &path, const QString &providerName, const QString &accountDisplayName); +NEXTCLOUD_CFAPI_EXPORT Result registerSyncRoot(const QString &path, const QString &providerName, const QString &providerVersion, const QString &folderAlias, const QString &displayName, const QString &accountDisplayName); +NEXTCLOUD_CFAPI_EXPORT Result unregisterSyncRoot(const QString &path, const QString &providerName, const QString &accountDisplayName); -OWNCLOUDSYNC_EXPORT Result connectSyncRoot(const QString &path, VfsCfApi *context); -OWNCLOUDSYNC_EXPORT Result disconnectSyncRoot(ConnectionKey &&key); +NEXTCLOUD_CFAPI_EXPORT Result connectSyncRoot(const QString &path, VfsCfApi *context); +NEXTCLOUD_CFAPI_EXPORT Result disconnectSyncRoot(ConnectionKey &&key); -OWNCLOUDSYNC_EXPORT bool isSparseFile(const QString &path); +NEXTCLOUD_CFAPI_EXPORT bool isSparseFile(const QString &path); -OWNCLOUDSYNC_EXPORT FileHandle handleForPath(const QString &path); +NEXTCLOUD_CFAPI_EXPORT FileHandle handleForPath(const QString &path); -OWNCLOUDSYNC_EXPORT PlaceHolderInfo findPlaceholderInfo(const FileHandle &handle); +PlaceHolderInfo findPlaceholderInfo(const FileHandle &handle); enum SetPinRecurseMode { NoRecurse = 0, @@ -90,10 +90,10 @@ enum SetPinRecurseMode { ChildrenOnly }; -OWNCLOUDSYNC_EXPORT Result setPinState(const FileHandle &handle, PinState state, SetPinRecurseMode mode); -OWNCLOUDSYNC_EXPORT Result createPlaceholderInfo(const QString &path, time_t modtime, qint64 size, const QByteArray &fileId); -OWNCLOUDSYNC_EXPORT Result updatePlaceholderInfo(const FileHandle &handle, time_t modtime, qint64 size, const QByteArray &fileId, const QString &replacesPath = QString()); -OWNCLOUDSYNC_EXPORT Result convertToPlaceholder(const FileHandle &handle, time_t modtime, qint64 size, const QByteArray &fileId, const QString &replacesPath); +NEXTCLOUD_CFAPI_EXPORT Result setPinState(const FileHandle &handle, PinState state, SetPinRecurseMode mode); +NEXTCLOUD_CFAPI_EXPORT Result createPlaceholderInfo(const QString &path, time_t modtime, qint64 size, const QByteArray &fileId); +NEXTCLOUD_CFAPI_EXPORT Result updatePlaceholderInfo(const FileHandle &handle, time_t modtime, qint64 size, const QByteArray &fileId, const QString &replacesPath = QString()); +NEXTCLOUD_CFAPI_EXPORT Result convertToPlaceholder(const FileHandle &handle, time_t modtime, qint64 size, const QByteArray &fileId, const QString &replacesPath); } diff --git a/src/libsync/vfs/cfapi/hydrationjob.h b/src/libsync/vfs/cfapi/hydrationjob.h index 0bfc516ac..242588120 100644 --- a/src/libsync/vfs/cfapi/hydrationjob.h +++ b/src/libsync/vfs/cfapi/hydrationjob.h @@ -25,7 +25,7 @@ class GETFileJob; class SyncJournalDb; class VfsCfApi; -class OWNCLOUDSYNC_EXPORT HydrationJob : public QObject +class HydrationJob : public QObject { Q_OBJECT public: diff --git a/src/libsync/vfs/cfapi/vfs_cfapi.cpp b/src/libsync/vfs/cfapi/vfs_cfapi.cpp index e97fa7031..d332480af 100644 --- a/src/libsync/vfs/cfapi/vfs_cfapi.cpp +++ b/src/libsync/vfs/cfapi/vfs_cfapi.cpp @@ -119,7 +119,7 @@ Result VfsCfApi::updateMetadata(const QString &filePath, time_t m } } else { qCWarning(lcCfApi) << "Couldn't update metadata for non existing file" << localPath; - return QStringLiteral("Couldn't update metadata"); + return {QStringLiteral("Couldn't update metadata")}; } } @@ -460,5 +460,3 @@ VfsCfApi::HydratationAndPinStates VfsCfApi::computeRecursiveHydrationAndPinState } } // namespace OCC - -OCC_DEFINE_VFS_FACTORY("win", OCC::VfsCfApi) diff --git a/src/libsync/vfs/cfapi/vfs_cfapi.h b/src/libsync/vfs/cfapi/vfs_cfapi.h index 3c41a6223..faa15d559 100644 --- a/src/libsync/vfs/cfapi/vfs_cfapi.h +++ b/src/libsync/vfs/cfapi/vfs_cfapi.h @@ -17,6 +17,7 @@ #include #include "common/vfs.h" +#include "common/plugin.h" namespace OCC { class HydrationJob; @@ -87,4 +88,11 @@ private: QScopedPointer d; }; +class CfApiVfsPluginFactory : public QObject, public DefaultPluginFactory +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.owncloud.PluginFactory" FILE "vfspluginmetadata.json") + Q_INTERFACES(OCC::PluginFactory) +}; + } // namespace OCC diff --git a/src/libsync/vfs/suffix/CMakeLists.txt b/src/libsync/vfs/suffix/CMakeLists.txt new file mode 100644 index 000000000..92426a5fb --- /dev/null +++ b/src/libsync/vfs/suffix/CMakeLists.txt @@ -0,0 +1,34 @@ +add_library("${synclib_NAME}_vfs_suffix" SHARED + vfs_suffix.cpp +) + +target_link_libraries("${synclib_NAME}_vfs_suffix" + "${synclib_NAME}" +) + +set_target_properties("${synclib_NAME}_vfs_suffix" PROPERTIES + LIBRARY_OUTPUT_DIRECTORY ${BIN_OUTPUT_DIRECTORY} + RUNTIME_OUTPUT_DIRECTORY ${BIN_OUTPUT_DIRECTORY} + PREFIX "" + AUTOMOC TRUE +) + +if(APPLE) + # for being loadable when client run from build dir + set(vfs_buildoutputdir "${BIN_OUTPUT_DIRECTORY}/${OWNCLOUD_OSX_BUNDLE}/Contents/PlugIns/") + set_target_properties("${synclib_NAME}_vfs_suffix" + PROPERTIES + LIBRARY_OUTPUT_DIRECTORY ${vfs_buildoutputdir} + RUNTIME_OUTPUT_DIRECTORY ${vfs_buildoutputdir} + ) + # For being loadable when client run from install dir (after make macdeployqt) + set(vfs_installdir "${LIB_INSTALL_DIR}/../PlugIns") +else() + set(vfs_installdir "${PLUGINDIR}") +endif() + +INSTALL(TARGETS "${synclib_NAME}_vfs_suffix" + LIBRARY DESTINATION "${vfs_installdir}" + RUNTIME DESTINATION "${vfs_installdir}" +) + diff --git a/src/libsync/vfs/suffix/vfs_suffix.cpp b/src/libsync/vfs/suffix/vfs_suffix.cpp index 547492eac..a34d22382 100644 --- a/src/libsync/vfs/suffix/vfs_suffix.cpp +++ b/src/libsync/vfs/suffix/vfs_suffix.cpp @@ -151,5 +151,3 @@ Vfs::AvailabilityResult VfsSuffix::availability(const QString &folderPath) } } // namespace OCC - -OCC_DEFINE_VFS_FACTORY("suffix", OCC::VfsSuffix) diff --git a/src/libsync/vfs/suffix/vfs_suffix.h b/src/libsync/vfs/suffix/vfs_suffix.h index ec608f620..8ac8c1217 100644 --- a/src/libsync/vfs/suffix/vfs_suffix.h +++ b/src/libsync/vfs/suffix/vfs_suffix.h @@ -17,6 +17,7 @@ #include #include "common/vfs.h" +#include "common/plugin.h" namespace OCC { @@ -60,4 +61,11 @@ protected: void startImpl(const VfsSetupParams ¶ms) override; }; +class SuffixVfsPluginFactory : public QObject, public DefaultPluginFactory +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.owncloud.PluginFactory" FILE "vfspluginmetadata.json") + Q_INTERFACES(OCC::PluginFactory) +}; + } // namespace OCC diff --git a/src/libsync/vfs/xattr/CMakeLists.txt b/src/libsync/vfs/xattr/CMakeLists.txt new file mode 100644 index 000000000..0eedd7da7 --- /dev/null +++ b/src/libsync/vfs/xattr/CMakeLists.txt @@ -0,0 +1,50 @@ +if (UNIX) + set(vfs_xattr_SRCS vfs_xattr.cpp) + if (APPLE) + set(vfs_xattr_SRCS ${vfs_xattr_SRCS} xattrwrapper_mac.cpp) + else() + set(vfs_xattr_SRCS ${vfs_xattr_SRCS} xattrwrapper_linux.cpp) + endif() + + add_library("${synclib_NAME}_vfs_xattr" SHARED + ${vfs_xattr_SRCS} + ) + + target_link_libraries("${synclib_NAME}_vfs_xattr" + "${synclib_NAME}" + ) + + set_target_properties("${synclib_NAME}_vfs_xattr" PROPERTIES + LIBRARY_OUTPUT_DIRECTORY ${BIN_OUTPUT_DIRECTORY} + RUNTIME_OUTPUT_DIRECTORY ${BIN_OUTPUT_DIRECTORY} + PREFIX "" + AUTOMOC TRUE + ) + + target_include_directories("${synclib_NAME}_vfs_xattr" BEFORE PUBLIC ${CMAKE_CURRENT_BINARY_DIR} INTERFACE ${CMAKE_CURRENT_BINARY_DIR}) + + if(APPLE) + # for being loadable when client run from build dir + set(vfs_buildoutputdir "${BIN_OUTPUT_DIRECTORY}/${OWNCLOUD_OSX_BUNDLE}/Contents/PlugIns/") + set_target_properties("${synclib_NAME}_vfs_xattr" + PROPERTIES + LIBRARY_OUTPUT_DIRECTORY ${vfs_buildoutputdir} + RUNTIME_OUTPUT_DIRECTORY ${vfs_buildoutputdir} + ) + # For being loadable when client run from install dir (after make macdeployqt) + set(vfs_installdir "${LIB_INSTALL_DIR}/../PlugIns") + else() + set(vfs_installdir "${PLUGINDIR}") + endif() + + GENERATE_EXPORT_HEADER( "${synclib_NAME}_vfs_xattr" + BASE_NAME "${synclib_NAME}_vfs_xattr" + EXPORT_MACRO_NAME NEXTCLOUD_XATTR_EXPORT + EXPORT_FILE_NAME xattrexport.h + ) + + INSTALL(TARGETS "${synclib_NAME}_vfs_xattr" + LIBRARY DESTINATION "${vfs_installdir}" + RUNTIME DESTINATION "${vfs_installdir}" + ) +endif() diff --git a/src/libsync/vfs/xattr/vfs_xattr.cpp b/src/libsync/vfs/xattr/vfs_xattr.cpp index dddfe3f74..614949ce5 100644 --- a/src/libsync/vfs/xattr/vfs_xattr.cpp +++ b/src/libsync/vfs/xattr/vfs_xattr.cpp @@ -182,5 +182,3 @@ void VfsXAttr::fileStatusChanged(const QString &, SyncFileStatus) } } // namespace OCC - -OCC_DEFINE_VFS_FACTORY("xattr", OCC::VfsXAttr) diff --git a/src/libsync/vfs/xattr/vfs_xattr.h b/src/libsync/vfs/xattr/vfs_xattr.h index 238f97e30..745ad8ef9 100644 --- a/src/libsync/vfs/xattr/vfs_xattr.h +++ b/src/libsync/vfs/xattr/vfs_xattr.h @@ -17,6 +17,7 @@ #include #include "common/vfs.h" +#include "common/plugin.h" namespace OCC { @@ -58,4 +59,11 @@ protected: void startImpl(const VfsSetupParams ¶ms) override; }; +class XattrVfsPluginFactory : public QObject, public DefaultPluginFactory +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.owncloud.PluginFactory" FILE "vfspluginmetadata.json") + Q_INTERFACES(OCC::PluginFactory) +}; + } // namespace OCC diff --git a/src/libsync/vfs/xattr/xattrwrapper.h b/src/libsync/vfs/xattr/xattrwrapper.h index 6e2f9a165..49d1b3f61 100644 --- a/src/libsync/vfs/xattr/xattrwrapper.h +++ b/src/libsync/vfs/xattr/xattrwrapper.h @@ -18,6 +18,8 @@ #include "owncloudlib.h" #include "common/result.h" +#include "xattrexport.h" + namespace OCC { namespace XAttrWrapper diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index c10fa3395..cc2d097bd 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -63,6 +63,10 @@ if( UNIX AND NOT APPLE ) endif(UNIX AND NOT APPLE) if (WIN32) + include_directories( + ${CMAKE_BINARY_DIR}/src/libsync/vfs/cfapi + ) + nextcloud_add_test(LongWinPath) nextcloud_add_test(SyncCfApi) elseif(LINUX) # elseif(LINUX OR APPLE) diff --git a/test/nextcloud_add_test.cmake b/test/nextcloud_add_test.cmake index 5cca34e6d..f7a6572b3 100644 --- a/test/nextcloud_add_test.cmake +++ b/test/nextcloud_add_test.cmake @@ -17,6 +17,18 @@ macro(nextcloud_add_test test_class) Qt5::Quick ) + if (WIN32) + target_link_libraries(${OWNCLOUD_TEST_CLASS}Test + "${synclib_NAME}_vfs_cfapi" + ) + endif() + + if (UNIX) + target_link_libraries(${OWNCLOUD_TEST_CLASS}Test + "${synclib_NAME}_vfs_xattr" + ) + endif() + IF(BUILD_UPDATER) target_link_libraries(${OWNCLOUD_TEST_CLASS}Test updater