diff --git a/CMakeLists.txt b/CMakeLists.txt
index f6de5cf9d1950fa09fe5457a569bb021c42587c5..3d3332ebf53bd2867c0b060817fe55a5945015e5 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -133,14 +133,15 @@ add_custom_command(
         ${PROTO_FILES}
       DEPENDS ${PROTO_FILES})
 
+# add generated files to include path
+include_directories(${CMAKE_CURRENT_BINARY_DIR}/include)
+
 # show generated files
 message(DEBUG "GRPC_GENERATED: ${GRPC_GENERATED}")
 
 ###############################################################################
 ### Set up main targets
-### * [caosdb_grpc] - only in Debug builds. Otherwise this library is compiled
-###   into caosdb libraray
-### * caosdb (links to caosdb_grpc) - The main library.
+### * caosdb - The main library including the protobuf and grpc generated files.
 ### * cxxcaosdbcli - A C++ test client.
 ### * ccaosdb - A C-Wrapper of the C++ caosdb library.
 ### * ccaosdbcli - A plain C test client.
@@ -158,41 +159,21 @@ find_package(GTest REQUIRED)
 message(DEBUG "CMAKE_INCLUDE_PATH: ${CMAKE_INCLUDE_PATH}")
 message(DEBUG "PROTOBUF_INCLUDE_DIRS: ${PROTOBUF_INCLUDE_DIRS}")
 message(DEBUG "gRPC_INCLUDE_DIRS: ${gRPC_INCLUDE_DIRS}")
+message(DEBUG "Boost_INCLUDE_DIRS: ${Boost_INCLUDE_DIRS}")
+message(DEBUG "GTest_INCLUDE_DIRS: ${GTest_INCLUDE_DIRS}")
+message(DEBUG "CMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS}")
+message(DEBUG "libcaosdb_SOURCE_DIR: ${libcaosdb_SOURCE_DIR}")
+message(DEBUG "libcaosdb_BINARY_DIR: ${libcaosdb_BINARY_DIR}")
 
 
 # libcaosdb
 # ---------
-
-# In Debug, build separate libraries for grpc-generated code and caosdb
-if("${CMAKE_BUILD_TYPE}" MATCHES "Debug")
-
-    add_library(caosdb_grpc SHARED ${GRPC_GENERATED})
-    target_link_libraries(caosdb_grpc 
-        gRPC::grpc gRPC::grpc++ protobuf::libprotobuf ${Boost_LIBRARIES}
-    )
-    target_include_directories(caosdb_grpc PUBLIC
-        $<BUILD_INTERFACE:${PROJECT_INCLUDE_DIR}>
-        $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include>
-        $<INSTALL_INTERFACE:include>
-    )
-
-   add_library(caosdb SHARED ${libcaosdb_INCL} ${libcaosdb_SRC})
-
-   target_link_libraries(caosdb 
-        caosdb_grpc gRPC::grpc gRPC::grpc++ protobuf::libprotobuf ${Boost_LIBRARIES}
-    )
-
-    set(LIBCAOSDB caosdb caosdb_grpc)
-else()
-    add_library(caosdb
-        SHARED ${libcaosdb_INCL} ${libcaosdb_SRC} ${GRPC_GENERATED})
-     target_link_libraries(caosdb
-        gRPC::grpc gRPC::grpc++ protobuf::libprotobuf ${Boost_LIBRARIES}
-        stdc++fs
-    )
-     set(LIBCAOSDB caosdb)
-endif()
-
+add_library(caosdb SHARED
+     ${libcaosdb_INCL} ${libcaosdb_SRC} ${GRPC_GENERATED})
+target_link_libraries(caosdb PUBLIC
+    gRPC::grpc gRPC::grpc++ protobuf::libprotobuf ${Boost_LIBRARIES}
+)
+set(LIBCAOSDB caosdb)
 
 target_include_directories(caosdb PUBLIC
     $<BUILD_INTERFACE:${libcaosdb_SOURCE_DIR}/include>
@@ -201,16 +182,12 @@ target_include_directories(caosdb PUBLIC
     $<INSTALL_INTERFACE:include>
 )
 
-
-
-
 # libccaosdb
 # ----------
-add_library(ccaosdb SHARED src/ccaosdb.cpp)
-target_link_libraries(ccaosdb
+add_library(ccaosdb SHARED src/ccaosdb.cpp ${GRPC_GENERATED})
+target_link_libraries(ccaosdb PUBLIC
+    caosdb
     gRPC::grpc gRPC::grpc++ protobuf::libprotobuf ${Boost_LIBRARIES}
-    ${LIBCAOSDB}
-    stdc++fs
 )
 target_include_directories(ccaosdb PUBLIC
     $<BUILD_INTERFACE:${libcaosdb_SOURCE_DIR}/include>
@@ -227,13 +204,9 @@ target_include_directories(ccaosdbcli PUBLIC
     $<BUILD_INTERFACE:${libcaosdb_BINARY_DIR}/include>
     $<INSTALL_INTERFACE:include>
 )
-target_include_directories(ccaosdbcli SYSTEM PUBLIC
-    ${CONAN_INCLUDE_DIRS}
-)
 
-target_link_libraries(ccaosdbcli
-    gRPC::grpc protobuf::libprotobuf ${Boost_LIBRARIES}
-    ${LIBCAOSDB}
+target_link_libraries(ccaosdbcli PRIVATE
+    gRPC::grpc protobuf::libprotobuf ${Boost_LIBRARIES}    
     ccaosdb
 )
 
@@ -245,12 +218,8 @@ target_include_directories(cxxcaosdbcli PUBLIC
     $<BUILD_INTERFACE:${libcaosdb_BINARY_DIR}/include>
     $<INSTALL_INTERFACE:include>
 )
-target_include_directories(cxxcaosdbcli SYSTEM PUBLIC
-    ${CONAN_INCLUDE_DIRS}
-)
-target_link_libraries(cxxcaosdbcli
-    ${LIBCAOSDB}
-    gRPC::grpc protobuf::libprotobuf ${Boost_LIBRARIES}
+target_link_libraries(cxxcaosdbcli PRIVATE
+    caosdb gRPC::grpc++ protobuf::libprotobuf ${Boost_LIBRARIES}
 )
 
 
diff --git a/CMakeSettings.json b/CMakeSettings.json
new file mode 100644
index 0000000000000000000000000000000000000000..09da9d3ea26bd9563e1f4c89bee60f09fc16ad7a
--- /dev/null
+++ b/CMakeSettings.json
@@ -0,0 +1,27 @@
+{
+  "configurations": [
+    {
+      "name": "x64-Debug",
+      "generator": "Ninja",
+      "configurationType": "Debug",
+      "inheritEnvironments": [ "msvc_x64_x64" ],
+      "buildRoot": "${projectDir}\\build",
+      "installRoot": "${projectDir}\\out\\install\\${name}",
+      "cmakeCommandArgs": "",
+      "buildCommandArgs": "",
+      "ctestCommandArgs": ""
+    },
+    {
+      "name": "x64-Release",
+      "generator": "Ninja",
+      "configurationType": "RelWithDebInfo",
+      "buildRoot": "${projectDir}\\build",
+      "installRoot": "${projectDir}\\out\\install\\${name}",
+      "cmakeCommandArgs": "",
+      "buildCommandArgs": "",
+      "ctestCommandArgs": "",
+      "inheritEnvironments": [ "msvc_x64_x64" ],
+      "variables": []
+    }
+  ]
+}
\ No newline at end of file
diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md
index 82af15fb394963c75cea5215c648977a88b9afbd..3f5ccde73fd4f7dad16b2f47abd767f504567b41 100644
--- a/doc/CHANGELOG.md
+++ b/doc/CHANGELOG.md
@@ -26,6 +26,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 ### Fixed
 
 - Values can now hold empty vectors and do not silently convert them into a scalar.
+- [indiscale#34](https://gitlab.indiscale.com/caosdb/src/caosdb-cpplib/-/issues/34)
+  Building shared libraries on Windows.
 
 ### Security
 
diff --git a/doc/Install_develop.rst b/doc/Install_develop.rst
index 38d55b8a5d199da83394ae21b9b603b943f7d4fb..56908a7994e291956ad08fbfdf4c89ccd417e29b 100644
--- a/doc/Install_develop.rst
+++ b/doc/Install_develop.rst
@@ -110,23 +110,20 @@ We use `Visual Studio
 as compiler. We use `cmake <https://cmake.org/download/>`__ as build
 tool.
 
-1. clone/update the subrepo ``git submodule update --init proto``
-2. :code:``conan install .. -g visual_studio -s arch=x86_64 -s build_type=Release -s compiler.toolset=v142 -s compiler.version=16 -s compiler.runtime=MD --build=missing --update``
-3. ``cd build/Release``
-5. ``cmake -B . ..``
-6. open ``libcaosdb.sln`` with Visual Studio, change the buildtype to
-   ``Release`` and build the project. (You can open Tools/Command
-   Line/Developer Command Prompt and execute
+1. Install Python and create a virtual environment with the dependencies in `requirements.txt`.
+2. Activate the environment run in the repository folder: ``conan install . --build=missing -s build_type=Release``
+3. ``cmake --preset conan-default``
+4. Open ``build/libcaosdb.sln`` with Visual Studio, change the
+   buildtype to ``Release`` and build the project (ALL_BUILD). (You
+   can open Tools/Command Line/Developer Command Prompt and execute
    ``msbuild libcaosdb.sln /property:Configuration=Release``)
+5. Try running the cli clients in ``.\build\Release\``.
 
 Known problems
 ^^^^^^^^^^^^^^
 
--  Linking dynamic libraries currently fails on Windows. So probably
-   other CaosDB libraries which make use of libcaosdb also will not
-   build. This is a known bug and we hope to fix this in the next
-   release. See
-   `#34 <https://gitlab.indiscale.com/caosdb/src/caosdb-cpplib/-/issues/34>`__
+-  Building the unit tests on Windows currently fails with linker errors. See 
+   `#90 <https://gitlab.indiscale.com/caosdb/src/caosdb-cpplib/-/issues/90>`__
 
 Troubleshooting
 ~~~~~~~~~~~~~~~
diff --git a/include/caosdb/authentication.h b/include/caosdb/authentication.h
index 2e117265d71f660888d6fd76d5fe3a3f898cac95..0ea818cc9d95caab96eb45efad30bed6d1a13745 100644
--- a/include/caosdb/authentication.h
+++ b/include/caosdb/authentication.h
@@ -51,8 +51,8 @@ using grpc::string_ref;
 class Authenticator {
 public:
   virtual ~Authenticator() = default;
-  [[nodiscard]] virtual auto GetCallCredentials() const
-    -> std::shared_ptr<grpc::CallCredentials> = 0;
+  [[nodiscard]] virtual auto
+  GetCallCredentials() const -> std::shared_ptr<grpc::CallCredentials> = 0;
 };
 
 /**
diff --git a/include/caosdb/configuration.h b/include/caosdb/configuration.h
index 053888672ab3e1649a060553264fe8d26fda9907..11b29f3e25097d3d383da9c12aecae08eef188d9 100644
--- a/include/caosdb/configuration.h
+++ b/include/caosdb/configuration.h
@@ -58,8 +58,8 @@ private:
 public:
   ConnectionConfiguration(std::string host, int port);
   virtual ~ConnectionConfiguration() = default;
-  friend auto operator<<(std::ostream &out, const ConnectionConfiguration &configuration)
-    -> std::ostream &;
+  friend auto operator<<(std::ostream &out,
+                         const ConnectionConfiguration &configuration) -> std::ostream &;
 
   [[nodiscard]] auto virtual ToString() const -> std::string = 0;
   [[nodiscard]] auto GetHost() const -> std::string;
@@ -128,16 +128,16 @@ public:
   /**
    * See mGetConnectionConfiguration.
    */
-  inline static auto GetConnectionConfiguration(const std::string &name)
-    -> std::unique_ptr<ConnectionConfiguration> {
+  inline static auto
+  GetConnectionConfiguration(const std::string &name) -> std::unique_ptr<ConnectionConfiguration> {
     return GetInstance().mGetConnectionConfiguration(name);
   }
 
   /**
    * Return the ConnectionConfiguration for the default connection.
    */
-  inline static auto GetDefaultConnectionConfiguration()
-    -> std::unique_ptr<ConnectionConfiguration> {
+  inline static auto
+  GetDefaultConnectionConfiguration() -> std::unique_ptr<ConnectionConfiguration> {
     return GetInstance().mGetConnectionConfiguration(GetInstance().mGetDefaultConnectionName());
   }
 
@@ -158,7 +158,7 @@ private:
   JsonValue json_configuration;
 
   inline ConfigurationManager()
-    : json_configuration(nullptr){
+    : json_configuration(nullptr) {
         // InitializeDefaults();
       };
 
diff --git a/include/caosdb/connection.h b/include/caosdb/connection.h
index e2a17390293f43bf2d6cc8a2af77f5ca23ab13d0..d3f10480ca9dda9c9fab3bc196dffcd9117ea981 100644
--- a/include/caosdb/connection.h
+++ b/include/caosdb/connection.h
@@ -111,8 +111,8 @@ public:
    */
   // TODO(tf) find a way to deal with this:
   // NOLINTNEXTLINE(bugprone-easily-swappable-parameters)
-  [[nodiscard]] auto RetrieveSingleUser(const std::string &realm, const std::string &name) const
-    -> User;
+  [[nodiscard]] auto RetrieveSingleUser(const std::string &realm,
+                                        const std::string &name) const -> User;
 
   /**
    * Create a new user.
@@ -170,7 +170,7 @@ class ConnectionManager {
 private:
   mutable std::map<std::string, std::shared_ptr<Connection>> connections;
   mutable std::string default_connection_name;
-  inline ConnectionManager(){};
+  inline ConnectionManager() {};
 
   auto mHasConnection(const std::string &name) const -> bool;
 
diff --git a/include/caosdb/entity.h b/include/caosdb/entity.h
index 23b6e2f612a52e85df9eb2682b6cac11fd594063..354f60f24872a24ff424d6211304d319dad2188b 100644
--- a/include/caosdb/entity.h
+++ b/include/caosdb/entity.h
@@ -157,7 +157,7 @@ public:
 
   friend class Entity;
 
-  virtual ~RepeatedPtrFieldWrapper(){};
+  virtual ~RepeatedPtrFieldWrapper() {};
 
   inline auto ToString() const noexcept -> const std::string override {
     if (this->size() == 0) {
@@ -202,7 +202,7 @@ public:
   }
 
 protected:
-  RepeatedPtrFieldWrapper() : ProtoMessageWrapper<RepeatedPtrField<P>>(){};
+  RepeatedPtrFieldWrapper() : ProtoMessageWrapper<RepeatedPtrField<P>>() {};
   explicit inline RepeatedPtrFieldWrapper(RepeatedPtrField<P> *wrapped)
     : ProtoMessageWrapper<RepeatedPtrField<P>>(wrapped) {}
 
@@ -343,7 +343,7 @@ public:
 
 private:
   explicit inline Message(ProtoMessage *wrapped)
-    : ScalarProtoMessageWrapper<ProtoMessage>(wrapped){};
+    : ScalarProtoMessageWrapper<ProtoMessage>(wrapped) {};
 };
 
 /**
@@ -357,7 +357,7 @@ public:
   // friend class Property;
 
 private:
-  inline Messages() : RepeatedPtrFieldWrapper<Message, ProtoMessage>(){};
+  inline Messages() : RepeatedPtrFieldWrapper<Message, ProtoMessage>() {};
 };
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -372,8 +372,8 @@ private:
  */
 class Parent : public ScalarProtoMessageWrapper<ProtoParent> {
 public:
-  explicit inline Parent(ProtoParent *wrapped) : ScalarProtoMessageWrapper<ProtoParent>(wrapped){};
-  Parent() : ScalarProtoMessageWrapper<ProtoParent>(){};
+  explicit inline Parent(ProtoParent *wrapped) : ScalarProtoMessageWrapper<ProtoParent>(wrapped) {};
+  Parent() : ScalarProtoMessageWrapper<ProtoParent>() {};
   ~Parent() = default;
 
   /**
@@ -475,9 +475,9 @@ public:
   friend class Entity;
 
 private:
-  inline Parents() : RepeatedPtrFieldWrapper<Parent, ProtoParent>(){};
+  inline Parents() : RepeatedPtrFieldWrapper<Parent, ProtoParent>() {};
   explicit inline Parents(::google::protobuf::RepeatedPtrField<caosdb::entity::v1::Parent> *wrapped)
-    : RepeatedPtrFieldWrapper<Parent, ProtoParent>(wrapped){};
+    : RepeatedPtrFieldWrapper<Parent, ProtoParent>(wrapped) {};
 };
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -516,10 +516,10 @@ public:
       value(this->wrapped->has_value() ? this->wrapped->mutable_value()
                                        : static_cast<ProtoValue *>(nullptr)),
       data_type(this->wrapped->has_data_type() ? this->wrapped->mutable_data_type()
-                                               : static_cast<ProtoDataType *>(nullptr)){};
+                                               : static_cast<ProtoDataType *>(nullptr)) {};
   inline Property()
     : ScalarProtoMessageWrapper<ProtoProperty>(), value(static_cast<ProtoValue *>(nullptr)),
-      data_type(static_cast<ProtoDataType *>(nullptr)){};
+      data_type(static_cast<ProtoDataType *>(nullptr)) {};
 
   ~Property() = default;
 
@@ -660,9 +660,9 @@ public:
   friend class Entity;
 
 private:
-  inline Properties(){};
+  inline Properties() {};
   explicit inline Properties(RepeatedPtrField<ProtoProperty> *wrapped)
-    : RepeatedPtrFieldWrapper<Property, ProtoProperty>(wrapped){};
+    : RepeatedPtrFieldWrapper<Property, ProtoProperty>(wrapped) {};
 };
 
 ///////////////////////////////////////////////////////////////////////////////
diff --git a/include/caosdb/info.h b/include/caosdb/info.h
index 0c4132f770d7bd68f10a74743246c0c037364f01..4b7c948376df77ee5d468a69218aca64b38c91e3 100644
--- a/include/caosdb/info.h
+++ b/include/caosdb/info.h
@@ -53,7 +53,7 @@ public:
    * CaosDBConnection::GetVersionInfo() instead to get the version of the
    * server behind the given connection.
    */
-  explicit inline VersionInfo(ProtoVersionInfo *info) : info(info){};
+  explicit inline VersionInfo(ProtoVersionInfo *info) : info(info) {};
   [[nodiscard]] inline auto GetMajor() const -> int32_t { return this->info->major(); }
   [[nodiscard]] inline auto GetMinor() const -> int32_t { return this->info->minor(); }
   [[nodiscard]] inline auto GetPatch() const -> int32_t { return this->info->patch(); }
diff --git a/include/caosdb/logging.h b/include/caosdb/logging.h
index 3fda8e83ac5c164728b2cd156292d22952b70130..a0afefb69a042eed13bd38f1cea8d698e0b19893 100644
--- a/include/caosdb/logging.h
+++ b/include/caosdb/logging.h
@@ -29,6 +29,7 @@
 #include <memory>             // for shared_ptr
 #include <string>             // for string
 #include <vector>             // for vector
+#include <filesystem>         // for path
 
 namespace caosdb::logging {
 
@@ -46,6 +47,9 @@ public:
   auto operator<<(const char *msg) -> LoggerOutputStream &;
   auto operator<<(const std::string &msg) -> LoggerOutputStream &;
   auto operator<<(void *msg) -> LoggerOutputStream &;
+  auto operator<<(std::filesystem::path *path) -> LoggerOutputStream &;
+  auto operator<<(const std::filesystem::path &path) -> LoggerOutputStream &;
+
   static auto get(const std::string &channel, int level) -> LoggerOutputStream {
     return LoggerOutputStream(channel, level);
   }
@@ -84,7 +88,7 @@ private:
  */
 class LevelConfiguration {
 public:
-  LevelConfiguration(int level) : level(level){};
+  LevelConfiguration(int level) : level(level) {};
   [[nodiscard]] inline auto GetLevel() const -> int { return this->level; }
 
 private:
diff --git a/include/caosdb/transaction.h b/include/caosdb/transaction.h
index b1d3bee8f740b1bcbb62c5f8fe924a937cbdf36c..3d994168d57a9882f8b41215e6c3229275cd02b8 100644
--- a/include/caosdb/transaction.h
+++ b/include/caosdb/transaction.h
@@ -228,8 +228,8 @@ public:
    * If the file cannot be downloaded due to unsufficient permissions an error
    * is appended.
    */
-  auto RetrieveAndDownloadFileById(const std::string &id, const std::string &local_path) noexcept
-    -> StatusCode;
+  auto RetrieveAndDownloadFileById(const std::string &id,
+                                   const std::string &local_path) noexcept -> StatusCode;
 
   /**
    * Add an entity id to this transaction for retrieval.
@@ -481,8 +481,8 @@ private:
 };
 
 template <class InputIterator>
-inline auto Transaction::RetrieveById(InputIterator begin, InputIterator end) noexcept
-  -> StatusCode {
+inline auto Transaction::RetrieveById(InputIterator begin,
+                                      InputIterator end) noexcept -> StatusCode {
   ASSERT_CAN_ADD_RETRIEVAL
 
   auto next = begin;
diff --git a/include/caosdb/transaction_status.h b/include/caosdb/transaction_status.h
index d46f3911aa17fbf518fd43b91e3568e4e4740c2f..020da73655b8bc104dc2c4827566f1d783a37d10 100644
--- a/include/caosdb/transaction_status.h
+++ b/include/caosdb/transaction_status.h
@@ -40,7 +40,7 @@ using caosdb::exceptions::TransactionTypeError;
  * Define static factory method in the TransactionStatus class.
  */
 #define CAOSDB_TRANSACTION_STATUS_DEFAULT_FACTORY(_StatusName, _StatusCode)                        \
-  inline static auto _StatusName()->const TransactionStatus & {                                    \
+  inline static auto _StatusName() -> const TransactionStatus & {                                  \
     static const TransactionStatus instance(_StatusCode,                                           \
                                             caosdb::get_status_description(_StatusCode));          \
     return instance;                                                                               \
@@ -191,8 +191,8 @@ public:
     TransactionStatus::ThrowExceptionIfError(this->code, this->description);
   }
 
-  inline static auto ThrowExceptionIfError(StatusCode code, const std::string &description)
-    -> void {
+  inline static auto ThrowExceptionIfError(StatusCode code,
+                                           const std::string &description) -> void {
     if (!IsError(code)) {
       return;
     }
@@ -240,7 +240,7 @@ public:
   inline auto GetCode() const -> StatusCode { return this->code; }
 
   TransactionStatus(StatusCode code, const std::string &description)
-    : code(code), description(description){};
+    : code(code), description(description) {};
 
 private:
   /**
diff --git a/include/caosdb/utility.h b/include/caosdb/utility.h
index 13e3dfeb99dc5415a733d5b6dcea852705b1662d..2ae2d6d9089a08c2c604a4e37e032932f08a2f69 100644
--- a/include/caosdb/utility.h
+++ b/include/caosdb/utility.h
@@ -85,8 +85,8 @@ inline auto get_env_fallback(const char *key, const char *fallback) -> const cha
  * @brief Return the value of an environment variable or - if undefined - the
  * fallback value.
  */
-inline auto get_env_fallback(const std::string &key, const std::string &fallback)
-  -> const std::string {
+inline auto get_env_fallback(const std::string &key,
+                             const std::string &fallback) -> const std::string {
   const char *val = get_env_fallback(key.c_str(), fallback.c_str());
 
   auto const result = std::string(val);
@@ -172,8 +172,12 @@ auto load_json_file(const path &json_file) -> JsonValue;
 auto base64_encode(const std::string &plain) -> std::string;
 
 inline auto get_home_directory() -> const path {
+#if defined(_WIN32)
+  const auto *const home = getenv("USERPROFILE");
+#else
   const auto *const home = getenv("HOME");
-  // TODO(tf) Add windowsy way of determining the home directory
+#endif
+
   return home;
 }
 
diff --git a/include/caosdb/value.h b/include/caosdb/value.h
index 1da6f1c2178b1b9091b990a016e1959b5e7f2a4c..e17fc5517f8717bec8c8249e7ce6f07b0f7c0e35 100644
--- a/include/caosdb/value.h
+++ b/include/caosdb/value.h
@@ -170,7 +170,7 @@ public:
   /**
    * Destructor.
    */
-  inline ~ScalarValue(){};
+  inline ~ScalarValue() {};
   /**
    * Copy constructor.
    */
@@ -180,7 +180,7 @@ public:
   /**
    * Move constructor.
    */
-  inline ScalarValue(ScalarValue &&other) : ScalarValue(std::move(other.wrapped)){};
+  inline ScalarValue(ScalarValue &&other) : ScalarValue(std::move(other.wrapped)) {};
   /**
    * Copy assignment operator.
    */
diff --git a/src/caosdb/authentication.cpp b/src/caosdb/authentication.cpp
index 11c3c17366ae9d24f209f7915c640fd2fee80d95..919f9bca3b18fc3aa5192ed10855d60925101bc1 100644
--- a/src/caosdb/authentication.cpp
+++ b/src/caosdb/authentication.cpp
@@ -37,11 +37,10 @@ using grpc::string_ref;
 MetadataCredentialsPluginImpl::MetadataCredentialsPluginImpl(std::string key, std::string value)
   : key(std::move(key)), value(std::move(value)) {}
 
-auto MetadataCredentialsPluginImpl::GetMetadata(string_ref /*service_url*/,
-                                                string_ref /*method_name*/,
-                                                const AuthContext & /*channel_auth_context*/,
-                                                std::multimap<grpc::string, grpc::string> *metadata)
-  -> Status {
+auto MetadataCredentialsPluginImpl::GetMetadata(
+  string_ref /*service_url*/, string_ref /*method_name*/,
+  const AuthContext & /*channel_auth_context*/,
+  std::multimap<grpc::string, grpc::string> *metadata) -> Status {
 
   metadata->insert(std::make_pair(this->key, this->value));
   return Status::OK;
diff --git a/src/caosdb/configuration.cpp b/src/caosdb/configuration.cpp
index deddcd423ffc4c73158b63fb7cc9f89a6beb8a4d..507f11e3f8cd8f1fc87dbc04ca1375698e9439b6 100644
--- a/src/caosdb/configuration.cpp
+++ b/src/caosdb/configuration.cpp
@@ -285,8 +285,8 @@ auto CreateSyslogSinkConfiguration(const object & /*from*/, const std::string &n
   return result;
 }
 
-auto CreateFileSinkConfiguration(const object &from, const std::string &name, int level)
-  -> std::shared_ptr<caosdb::logging::SinkConfiguration> {
+auto CreateFileSinkConfiguration(const object &from, const std::string &name,
+                                 int level) -> std::shared_ptr<caosdb::logging::SinkConfiguration> {
   auto result = std::make_shared<FileSinkConfiguration>(name, level);
   if (from.contains("directory")) {
     result->SetDirectory(from.at("directory").as_string().c_str());
diff --git a/src/caosdb/logging.cpp b/src/caosdb/logging.cpp
index 59dd93eee3c72c061501bb5dca000752b47704b6..65b59c954e96a1a7a8d0b46f1183f949a07efa7b 100644
--- a/src/caosdb/logging.cpp
+++ b/src/caosdb/logging.cpp
@@ -29,6 +29,7 @@
 #include <boost/log/utility/setup/settings.hpp>
 #include <boost/smart_ptr/shared_ptr.hpp>
 #include <cstdint> // for uint64_t
+#include <filesystem>
 #include <memory>
 #include <string>
 #include <utility> // for move
@@ -106,6 +107,18 @@ auto LoggerOutputStream::operator<<(void *msg) -> LoggerOutputStream & {
   return *this;
 }
 
+auto LoggerOutputStream::operator<<(std::filesystem::path *path) -> LoggerOutputStream & {
+  BOOST_LOG_CHANNEL_SEV(caosdb::logging::logger::get(), channel, this->level) << path->string();
+
+  return *this;
+}
+
+LoggerOutputStream &LoggerOutputStream::operator<<(const std::filesystem::path &path) {
+
+  BOOST_LOG_CHANNEL_SEV(caosdb::logging::logger::get(), channel, this->level) << path.string();
+  return *this;
+}
+
 LoggingConfiguration::LoggingConfiguration(int level) : LevelConfiguration(level) {}
 
 auto LoggingConfiguration::AddSink(const std::shared_ptr<SinkConfiguration> &sink) -> void {
diff --git a/src/caosdb/result_set.cpp b/src/caosdb/result_set.cpp
index a4172a836d4e8bb9ed5e568439556ebace53c4e4..f4f4efddbd00edb9de9ce06a9a2225a8b73e0c16 100644
--- a/src/caosdb/result_set.cpp
+++ b/src/caosdb/result_set.cpp
@@ -20,6 +20,7 @@
 #include "caosdb/result_set.h" // for ResultSet
 #include <memory>              // for unique_ptr
 #include <utility>             // for move, pair
+#include <vector>
 
 namespace caosdb::transaction {
 
diff --git a/src/caosdb/result_table_impl.h b/src/caosdb/result_table_impl.h
index 3450a68cf7ae0638d42d3ea1c79fd9d181a3eaab..6570e7a71144906128da0cbf9ff38be270790fc0 100644
--- a/src/caosdb/result_table_impl.h
+++ b/src/caosdb/result_table_impl.h
@@ -76,8 +76,8 @@ class ResultTableImpl : public ScalarProtoMessageWrapper<ProtoSelectQueryResult>
   friend class ResultTable;
   friend class ResultTable::HeaderIterator;
   friend class ResultTableColumn;
-  friend auto ProcessSelectResponse(ProtoSelectQueryResult *select_result)
-    -> std::unique_ptr<ResultTable>;
+  friend auto
+  ProcessSelectResponse(ProtoSelectQueryResult *select_result) -> std::unique_ptr<ResultTable>;
 };
 
 } // namespace caosdb::transaction
diff --git a/src/caosdb/transaction.cpp b/src/caosdb/transaction.cpp
index 28f9e35fc1a70083d07c99e7f8a4fabfbe58bc32..c67cae1ac2e50d30b2cafbfc60b7e7c28795cd9d 100644
--- a/src/caosdb/transaction.cpp
+++ b/src/caosdb/transaction.cpp
@@ -40,6 +40,7 @@
 #include <map>                                                     // for map, operator!=
 #include <memory>                                                  // for unique_ptr
 #include <random>                                                  // for mt19937, rand...
+#include <string>                                                  // for string
 #include <system_error>                                            // for std::system_error
 #include <utility>                                                 // for move, pair
 // IWYU pragma: no_include <cxxabi.h>
@@ -78,9 +79,8 @@ auto Transaction::RetrieveById(const std::string &id) noexcept -> StatusCode {
   return this->status.GetCode();
 }
 
-auto Transaction::RetrieveAndDownloadFileById(const std::string &id,
-                                              const std::string &local_path) noexcept
-  -> StatusCode {
+auto Transaction::RetrieveAndDownloadFileById(
+  const std::string &id, const std::string &local_path) noexcept -> StatusCode {
   ASSERT_CAN_ADD_RETRIEVAL
 
   auto *retrieve_request = this->request->add_requests()->mutable_retrieve_request();
@@ -297,10 +297,9 @@ auto ProcessSelectResponse(ProtoSelectQueryResult *select_result) -> std::unique
   return ResultTableImpl::create(select_result);
 }
 
-auto Transaction::ProcessRetrieveResponse(RetrieveResponse *retrieve_response,
-                                          std::vector<std::unique_ptr<Entity>> *entities,
-                                          bool *set_error) const noexcept
-  -> std::unique_ptr<Entity> {
+auto Transaction::ProcessRetrieveResponse(
+  RetrieveResponse *retrieve_response, std::vector<std::unique_ptr<Entity>> *entities,
+  bool *set_error) const noexcept -> std::unique_ptr<Entity> {
   std::unique_ptr<Entity> result;
   switch (retrieve_response->retrieve_response_case()) {
   case RetrieveResponseCase::kEntityResponse: {
diff --git a/src/ccaosdb.cpp b/src/ccaosdb.cpp
index ae1a728f62b7cdfb293eb347d1a1966b86bfd3b2..82bcbae2c6eaee34368a871c9a5b7f983e838a2a 100644
--- a/src/ccaosdb.cpp
+++ b/src/ccaosdb.cpp
@@ -83,7 +83,7 @@ extern "C" {
       auto *wrapped_entity = WRAPPED_ENTITY_CAST(entity);                                          \
       auto *tmp = (char *)malloc(sizeof(char) * wrapped_entity->GetFunction.length() + 1);         \
       strcpy(tmp, wrapped_entity->GetFunction.c_str());                                            \
-      delete[] * out;                                                                              \
+      delete[] *out;                                                                               \
       *out = tmp;                                                                                  \
       return 0;                                                                                    \
     })
@@ -109,7 +109,7 @@ extern "C" {
       auto *wrapped_property = WRAPPED_PROPERTY_CAST(property);                                    \
       auto *tmp = (char *)malloc(sizeof(char) * wrapped_property->GetFunction.length() + 1);       \
       strcpy(tmp, wrapped_property->GetFunction.c_str());                                          \
-      delete[] * out;                                                                              \
+      delete[] *out;                                                                               \
       *out = tmp;                                                                                  \
       return 0;                                                                                    \
     })
@@ -136,7 +136,7 @@ extern "C" {
       auto *wrapped_parent = WRAPPED_PARENT_CAST(parent);                                          \
       auto *tmp = (char *)malloc(sizeof(char) * wrapped_parent->GetFunction.length() + 1);         \
       strcpy(tmp, wrapped_parent->GetFunction.c_str());                                            \
-      delete[] * out;                                                                              \
+      delete[] *out;                                                                               \
       *out = tmp;                                                                                  \
       return 0;                                                                                    \
     })
@@ -729,7 +729,7 @@ ERROR_RETURN_CODE(GENERIC_ERROR,
                     std::string role_str = ENUM_NAME_FROM_VALUE(wrapped_entity->GetRole(), Role);
                     auto *tmp = (char *)malloc(sizeof(char) * role_str.length() + 1);
                     strcpy(tmp, role_str.c_str());
-                    delete[] * out;
+                    delete[] *out;
                     *out = tmp;
                     return 0;
                   })
@@ -741,7 +741,7 @@ ERROR_RETURN_CODE(GENERIC_ERROR,
                     auto path = wrapped_entity->GetLocalPath().string();
                     auto *tmp = (char *)(malloc(sizeof(char) * path.length() + 1));
                     strcpy(tmp, path.c_str());
-                    delete[] * out;
+                    delete[] *out;
                     *out = tmp;
                     return 0;
                   })
@@ -887,7 +887,7 @@ ERROR_RETURN_CODE(GENERIC_ERROR,
                       ENUM_NAME_FROM_VALUE(wrapped_property->GetImportance(), Importance);
                     char *tmp = (char *)malloc(sizeof(char) * importance_str.length() + 1);
                     strcpy(tmp, importance_str.c_str());
-                    delete[] * out;
+                    delete[] *out;
                     *out = tmp;
                     return 0;
                   })
@@ -925,7 +925,7 @@ ERROR_RETURN_CODE(
     auto *wrapped_message = static_cast<caosdb::entity::Message *>(message->wrapped_message);
     auto *tmp = (char *)malloc(sizeof(char) * wrapped_message->GetDescription().length() + 1);
     strcpy(tmp, wrapped_message->GetDescription().c_str());
-    delete[] * out;
+    delete[] *out;
     *out = tmp;
     return 0;
   })
@@ -1000,7 +1000,7 @@ ERROR_RETURN_CODE(
     }
     char *tmp = (char *)malloc(sizeof(char) * datatype_name.length() + 1);
     strcpy(tmp, datatype_name.c_str());
-    delete[] * out;
+    delete[] *out;
     *out = tmp;
     return 0;
   })
@@ -1018,7 +1018,7 @@ ERROR_RETURN_CODE(GENERIC_ERROR,
                     auto *tmp =
                       (char *)malloc(sizeof(char) * wrapped_value->GetAsString().length() + 1);
                     strcpy(tmp, wrapped_value->GetAsString().c_str());
-                    delete[] * out;
+                    delete[] *out;
                     *out = tmp;
                     return 0;
                   })
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 931c9d69a919bd0f2695ae2a6a5fe45bb4b89aa3..dc15a2ab07c4138e960367c3676af4694f0b9676 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -65,7 +65,7 @@ foreach (i RANGE "${len_test_cases}")
     set(libcaosdb_TEST_SRC "${CMAKE_CURRENT_SOURCE_DIR}/${test_case_name}.cpp
         ${libcaosdb_TEST_SRC}")
     target_link_libraries(${test_case_name}
-        PRIVATE GTest::gtest_main ${LIBCAOSDB} ccaosdb  gtest::gtest)
+        PRIVATE GTest::gtest_main caosdb ccaosdb gtest::gtest)
     target_include_directories(${test_case_name}
       PUBLIC ${CMAKE_CURRENT_BINARY_DIR})
     if(_LINTING)