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