Add experimental 'libsyncthing'

* This allows running C++ GUI code (as provided by this
  repository) and Syncthing itself in the same process.
* It basically seems to work. I can now run a Syncthing
  instance within the interactive C++ shell 'cling' :-)
* Syncthing and its assets are built within the usual
  CMake build process but disabled by default because still
  experimental. To enable the build, add '-DNO_LIBSYNCTHING=OFF'
  to CMake arguments.
* The Syncthing checkout with customized exports lives
  in the Git submodule under
  'libsyncthing/go/src/github.com/syncthing/syncthing'.
This commit is contained in:
Martchus 2018-04-08 21:36:08 +02:00
parent 37e24ccfb7
commit 6ab7662a64
8 changed files with 184 additions and 0 deletions

1
.gitignore vendored
View File

@ -47,6 +47,7 @@ testfiles/output.*
scripts/
# clang-format
/libsyncthing/.clang-format
/cli/.clang-format
/connector/.clang-format
/fileitemactionplugin/.clang-format

4
.gitmodules vendored Normal file
View File

@ -0,0 +1,4 @@
[submodule "libsyncthing/go/src/github.com/syncthing/syncthing"]
path = libsyncthing/go/src/github.com/syncthing/syncthing
url = https://github.com/Martchus/syncthing.git
branch = libsyncthing

View File

@ -25,6 +25,7 @@ else()
endif()
# options for partial build
option(NO_LIBSYNCTHING "whether building Syncthing itself as a library should be skipped" ON)
option(NO_CLI "whether building CLI should be skipped" OFF)
option(NO_TRAY "whether building the tray should be skipped" OFF)
option(NO_FILE_ITEM_ACTION_PLUGIN "whether building the file item action plugin should be skipped" "${FILE_ITEM_ACTION_PLUGIN_DISABLED_BY_DEFAULT}")
@ -37,6 +38,10 @@ enable_testing()
add_subdirectory(connector)
add_subdirectory(testhelper)
if (NOT NO_LIBSYNCTHING)
add_subdirectory(libsyncthing)
endif()
link_directories(${LIB_SYNCTHING_CONNECTOR_BINARY_DIR})
if(NOT NO_CLI)
add_subdirectory(cli)

101
libsyncthing/CMakeLists.txt Normal file
View File

@ -0,0 +1,101 @@
cmake_minimum_required(VERSION 3.1.0 FATAL_ERROR)
# metadata
set(META_PROJECT_NAME syncthing)
set(META_PROJECT_TYPE library)
set(META_APP_NAME "Syncthing library")
set(META_APP_DESCRIPTION "Syncthing itself, built as a shared or static library")
set(META_PROJECT_VARNAME_UPPER LIB_SYNCTHING)
# add project files
set(HEADER_FILES
interface.h
)
set(SRC_FILES
"${CMAKE_CURRENT_BINARY_DIR}/libsyncthinginternal.h"
interface.cpp
)
# find the go binary
find_program(GO_BIN go)
if(NOT GO_BIN)
message(FATAL_ERROR "The go binary could not be located.")
endif()
# locate the Syncthing checkout
set(GO_DEVELOPMENT_PATH "${CMAKE_CURRENT_SOURCE_DIR}/go" CACHE STRING "the 'GOPATH'")
set(SYNCTHING_PATH "${CMAKE_CURRENT_SOURCE_DIR}/go/src/github.com/syncthing/syncthing" CACHE STRING "path of Syncthing checkout")
# find Syncthing's assets
file(GLOB_RECURSE SRC_FILES_SYNCTHING_ASSETS
LIST_DIRECTORIES false
RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
"${SYNCTHING_PATH}/gui/*"
)
if(NOT SRC_FILES_SYNCTHING_ASSETS)
message(FATAL_ERROR "No asset files found in Syncthing checkout \"${CMAKE_CURRENT_SOURCE_DIR}/go/src/github.com/syncthing/syncthing\".")
endif()
# find Syncthing's source code
file(GLOB_RECURSE SRC_FILES_SYNCTHING
LIST_DIRECTORIES false
RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
"${SYNCTHING_PATH}/cmd/*.go"
)
if(NOT SRC_FILES_SYNCTHING)
message(FATAL_ERROR "No *.go files found in Syncthing checkout \"${CMAKE_CURRENT_SOURCE_DIR}/go/src/github.com/syncthing/syncthing\".")
endif()
list(APPEND SRC_FILES_SYNCTHING "${SYNCTHING_PATH}/lib/auto/gui.files.go")
message(STATUS "Syncthing's go files: ${SRC_FILES_SYNCTHING}")
# generate Syncthing's assets
add_custom_command(
OUTPUT
"${SYNCTHING_PATH}/lib/auto/gui.files.go"
COMMAND
"GOPATH=${GO_DEVELOPMENT_PATH}"
"${GO_BIN}" run ./script/genassets.go gui > lib/auto/gui.files.go
DEPENDS ${SRC_FILES_SYNCTHING_ASSETS}
WORKING_DIRECTORY "${SYNCTHING_PATH}"
COMMENT "Building Syncthing's assets"
)
# compile Syncthing as static library
# FIXME: handle cross-compilation
add_custom_command(
OUTPUT
"${CMAKE_CURRENT_BINARY_DIR}/libsyncthinginternal.a"
"${CMAKE_CURRENT_BINARY_DIR}/libsyncthinginternal.h"
COMMAND
"GOPATH=${GO_DEVELOPMENT_PATH}"
"${GO_BIN}" build -v -buildmode c-archive
-o "${CMAKE_CURRENT_BINARY_DIR}/libsyncthinginternal.a"
./cmd/syncthing
DEPENDS ${SRC_FILES_SYNCTHING}
WORKING_DIRECTORY "${SYNCTHING_PATH}"
COMMENT "Building Syncthing itself"
)
# do not use this library directly but depend on it
list(APPEND PRIVATE_LIBRARIES "${CMAKE_CURRENT_BINARY_DIR}/libsyncthinginternal.a")
# find c++utilities
find_package(c++utilities 4.9.0 REQUIRED)
list(APPEND CMAKE_MODULE_PATH ${CPP_UTILITIES_MODULE_DIRS})
list(APPEND PRIVATE_SHARED_INCLUDE_DIRS ${CPP_UTILITIES_INCLUDE_DIRS})
list(APPEND PRIVATE_STATIC_INCLUDE_DIRS ${CPP_UTILITIES_INCLUDE_DIRS})
# include modules to apply configuration
include(BasicConfig)
include(WindowsResources)
include(LibraryTarget)
include(ConfigHeader)
# create install target for static libsyncthinginternal.a if we're also creating a static libsyncthing.a
if(BUILD_STATIC_LIBS AND NOT META_NO_INSTALL_TARGETS AND ENABLE_INSTALL_TARGETS)
install(
FILES "${CMAKE_CURRENT_BINARY_DIR}/libsyncthinginternal.a"
DESTINATION "lib${SELECTED_LIB_SUFFIX}"
COMPONENT binary
)
endif()

27
libsyncthing/global.h Normal file
View File

@ -0,0 +1,27 @@
// Created via CMake from template global.h.in
// WARNING! Any changes to this file will be overwritten by the next CMake run!
#ifndef LIB_SYNCTHING_GLOBAL
#define LIB_SYNCTHING_GLOBAL
#include <c++utilities/application/global.h>
#ifdef LIB_SYNCTHING_STATIC
#define LIB_SYNCTHING_EXPORT
#define LIB_SYNCTHING_IMPORT
#else
#define LIB_SYNCTHING_EXPORT LIB_EXPORT
#define LIB_SYNCTHING_IMPORT LIB_IMPORT
#endif
/*!
* \def LIB_SYNCTHING_EXPORT
* \brief Marks the symbol to be exported by the syncthing library.
*/
/*!
* \def LIB_SYNCTHING_IMPORT
* \brief Marks the symbol to be imported from the syncthing library.
*/
#endif // LIB_SYNCTHING_GLOBAL

@ -0,0 +1 @@
Subproject commit 8557b9ca2062f4c9de418c965cb8eaee56f706ea

View File

@ -0,0 +1,22 @@
#include "./interface.h"
#include "libsyncthinginternal.h"
namespace LibSyncthing {
inline _GoString_ gostr(const std::string &str)
{
return _GoString_{ str.data(), static_cast<std::ptrdiff_t>(str.size()) };
}
void runSyncthing(const RuntimeOptions &options)
{
::runSyncthing(gostr(options.configDir), gostr(options.guiAddress), gostr(options.guiApiKey), gostr(options.logFile), options.verbose);
}
void generate(const std::string &generateDir)
{
::generate(gostr(generateDir));
}
} // namespace LibSyncthing

23
libsyncthing/interface.h Normal file
View File

@ -0,0 +1,23 @@
#ifndef LIBSYNCTHING_INTERFACE_H
#define LIBSYNCTHING_INTERFACE_H
#include "./global.h"
#include <string>
namespace LibSyncthing {
struct RuntimeOptions {
std::string configDir;
std::string guiAddress;
std::string guiApiKey;
std::string logFile;
bool verbose = false;
};
void LIB_SYNCTHING_EXPORT runSyncthing(const RuntimeOptions &options);
void LIB_SYNCTHING_EXPORT generate(const std::string &generateDir);
} // namespace LibSyncthing
#endif // LIBSYNCTHING_INTERFACE_H