diff --git a/src/common/common.cmake b/src/common/common.cmake index 82437cd04ebe7..5c7cd52c902bf 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 0000000000000..7e705d94e7486 --- /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 0000000000000..3d28f7dd3f761 --- /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 e9cf977d9113d..ba5375680361c 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) { @@ -146,7 +138,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(); @@ -162,9 +154,33 @@ bool OCC::isVfsPluginAvailable(Vfs::Mode mode) auto name = modeToPluginName(mode); if (name.isEmpty()) return false; + auto pluginPath = pluginFileName(QStringLiteral("vfs"), name); + QPluginLoader loader(pluginPath); - if (!vfsFactoryHash()->contains(name)) { - qCDebug(lcPlugin) << "Plugin isn't registered:" << name; + auto basemeta = loader.metaData(); + if (basemeta.isEmpty() || !basemeta.contains(QStringLiteral("IID"))) { + qCDebug(lcPlugin) << "Plugin doesn't exist" << loader.fileName(); + return false; + } + if (basemeta[QStringLiteral("IID")].toString() != QLatin1String("org.owncloud.PluginFactory")) { + qCWarning(lcPlugin) << "Plugin has wrong IID" << loader.fileName() << basemeta[QStringLiteral("IID")]; + return false; + } + + auto metadata = basemeta[QStringLiteral("MetaData")].toObject(); + if (metadata[QStringLiteral("type")].toString() != QLatin1String("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; } @@ -212,24 +228,32 @@ std::unique_ptr OCC::createVfsFromPlugin(Vfs::Mode mode) auto name = modeToPluginName(mode); if (name.isEmpty()) return nullptr; + 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; + } + + QPluginLoader loader(pluginPath); + auto plugin = loader.instance(); + if (!plugin) { + qCCritical(lcPlugin) << "Could not load plugin" << pluginPath << loader.errorString(); return nullptr; } - const auto factory = vfsFactoryHash()->value(name); + 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 ba2c5c7af06c0..bc942d1375d11 100644 --- a/src/common/vfs.h +++ b/src/common/vfs.h @@ -14,7 +14,6 @@ #pragma once #include -#include #include #include @@ -119,9 +118,6 @@ class OCSYNC_EXPORT Vfs : public QObject 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 dad4eba106ea0..8d0789cef195a 100644 --- a/src/libsync/CMakeLists.txt +++ b/src/libsync/CMakeLists.txt @@ -58,24 +58,23 @@ 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 - ) + #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() + #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) @@ -159,3 +158,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 769d28eb151bd..5fe3a199b344e 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 0000000000000..3a9d4bf80e631 --- /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") + +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 0000000000000..4943aaa526520 --- /dev/null +++ b/src/libsync/vfs/cfapi/CMakeLists.txt @@ -0,0 +1,43 @@ +if (WIN32) +add_library("${synclib_NAME}_vfs_cfapi" SHARED + cfapiwrapper.cpp + hydrationjob.cpp + vfs_cfapi.cpp +) + +target_link_libraries("${synclib_NAME}_vfs_cfapi" + "${synclib_NAME}" + cldapi +) + +target_compile_definitions("${synclib_NAME}_vfs_cfapi" + PUBLIC -D_WIN32_WINNT=_WIN32_WINNT_WIN10 +) + +set_target_properties("${synclib_NAME}_vfs_cfapi" 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_cfapi" + PROPERTIES + LIBRARY_OUTPUT_DIRECTORY ${vfs_buildoutputdir} + RUNTIME_OUTPUT_DIRECTORY ${vfs_buildoutputdir} + ) + # For being lodable 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_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 a1c881369a7cb..5daf3277c55bc 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 2e8810b45e8ea..1cb2691abcac2 100644 --- a/src/libsync/vfs/cfapi/cfapiwrapper.h +++ b/src/libsync/vfs/cfapi/cfapiwrapper.h @@ -28,7 +28,7 @@ class VfsCfApi; namespace CfApiWrapper { -class OWNCLOUDSYNC_EXPORT ConnectionKey +class ConnectionKey { public: ConnectionKey(); @@ -38,7 +38,7 @@ class OWNCLOUDSYNC_EXPORT ConnectionKey std::unique_ptr _data; }; -class OWNCLOUDSYNC_EXPORT FileHandle +class FileHandle { public: using Deleter = void (*)(void *); @@ -53,7 +53,7 @@ class OWNCLOUDSYNC_EXPORT FileHandle std::unique_ptr _data; }; -class OWNCLOUDSYNC_EXPORT PlaceHolderInfo +class PlaceHolderInfo { public: using Deleter = void (*)(CF_PLACEHOLDER_BASIC_INFO *); @@ -71,17 +71,17 @@ class OWNCLOUDSYNC_EXPORT PlaceHolderInfo 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); +Result registerSyncRoot(const QString &path, const QString &providerName, const QString &providerVersion, const QString &folderAlias, const QString &displayName, const QString &accountDisplayName); +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); +Result connectSyncRoot(const QString &path, VfsCfApi *context); +Result disconnectSyncRoot(ConnectionKey &&key); -OWNCLOUDSYNC_EXPORT bool isSparseFile(const QString &path); +bool isSparseFile(const QString &path); -OWNCLOUDSYNC_EXPORT FileHandle handleForPath(const QString &path); +FileHandle handleForPath(const QString &path); -OWNCLOUDSYNC_EXPORT PlaceHolderInfo findPlaceholderInfo(const FileHandle &handle); +PlaceHolderInfo findPlaceholderInfo(const FileHandle &handle); enum SetPinRecurseMode { NoRecurse = 0, @@ -89,10 +89,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); +Result setPinState(const FileHandle &handle, PinState state, SetPinRecurseMode mode); +Result createPlaceholderInfo(const QString &path, time_t modtime, qint64 size, const QByteArray &fileId); +Result updatePlaceholderInfo(const FileHandle &handle, time_t modtime, qint64 size, const QByteArray &fileId, const QString &replacesPath = QString()); +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 47a12475152a1..f17dda8c83cf0 100644 --- a/src/libsync/vfs/cfapi/hydrationjob.h +++ b/src/libsync/vfs/cfapi/hydrationjob.h @@ -24,7 +24,7 @@ namespace OCC { class GETFileJob; class SyncJournalDb; -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 5db9c5d03ce4a..e145ceec58e23 100644 --- a/src/libsync/vfs/cfapi/vfs_cfapi.cpp +++ b/src/libsync/vfs/cfapi/vfs_cfapi.cpp @@ -114,7 +114,7 @@ Result VfsCfApi::updateMetadata(const QString &filePath, time_t m return cfapi::updatePlaceholderInfo(handle, modtime, size, fileId); } else { qCWarning(lcCfApi) << "Couldn't update metadata for non existing file" << localPath; - return "Couldn't update metadata"; + return {"Couldn't update metadata"}; } } @@ -447,5 +447,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 90511a48a8511..8de929c709188 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; @@ -85,4 +86,11 @@ public slots: 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 0000000000000..3765e02855145 --- /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 lodable 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 f3858e8a2f54d..d0634ea41d775 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 4aa513c038889..224491b875dde 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 @@ public slots: 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 0000000000000..6cb251b1dc8ac --- /dev/null +++ b/src/libsync/vfs/xattr/CMakeLists.txt @@ -0,0 +1,41 @@ +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 +) + +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 lodable 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_xattr" + LIBRARY DESTINATION "${vfs_installdir}" + RUNTIME DESTINATION "${vfs_installdir}" +) + diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index c10fa33956a79..7c15878e500ed 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -66,7 +66,7 @@ if (WIN32) nextcloud_add_test(LongWinPath) nextcloud_add_test(SyncCfApi) elseif(LINUX) # elseif(LINUX OR APPLE) - nextcloud_add_test(SyncXAttr) + #nextcloud_add_test(SyncXAttr) endif() nextcloud_add_benchmark(LargeSync)