From 57fbe767db60e1f2dc74736a4b71d249039aa328 Mon Sep 17 00:00:00 2001
From: Timm Fitschen <t.fitschen@indiscale.com>
Date: Thu, 1 Jul 2021 09:35:08 +0200
Subject: [PATCH] WIP: conan

---
 CMakeLists.txt              | 43 ++++++++++++++++---------------
 conanfile.py                | 50 +++++++++++++++++++++++++++++++++++++
 conanfile.txt               |  6 +++++
 test/CMakeLists.txt         | 14 +++++------
 test_package/CMakeLists.txt | 14 +++++++++++
 test_package/conanfile.py   | 25 +++++++++++++++++++
 test_package/example.cpp    |  5 ++++
 7 files changed, 130 insertions(+), 27 deletions(-)
 create mode 100644 conanfile.py
 create mode 100644 test_package/CMakeLists.txt
 create mode 100644 test_package/conanfile.py
 create mode 100644 test_package/example.cpp

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 8598f4c..1dc2304 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -87,28 +87,40 @@ if("${CMAKE_BUILD_TYPE}" MATCHES "Debug")
 
 endif()
 
+####################################################################
+## CODE GENERATION (WITH GRPC)
+####################################################################
 
-## CODE GENERATION
-option(GRPC_FETCHCONTENT "Fetch and build GRPC from the sources" OFF)
-include(FetchGRPC)
-
-#
 # Protobuf/Grpc source files
-#
 set(PROTO_FILES
     ${PROJECT_SOURCE_DIR}/proto/proto/caosdb/info/v1alpha1/main.proto
 )
 
 set(PROTO_PATH ${PROJECT_SOURCE_DIR}/proto/proto)
 
+# compiler binaries
+set(_PROTOBUF_PROTOC "${CMAKE_BINARY_DIR}/build_tools/protoc")
+set(_GRPC_CPP_PLUGIN_EXECUTABLE "${CMAKE_BINARY_DIR}/build_tools/grpc_cpp_plugin")
+
 # Generated sources
 set(hw_hdrs_path "info/v1alpha1")
 set(hw_proto_srcs "${CMAKE_CURRENT_BINARY_DIR}/include/caosdb/${hw_hdrs_path}/main.pb.cc")
 set(hw_proto_hdrs "${CMAKE_CURRENT_BINARY_DIR}/include/caosdb/${hw_hdrs_path}/main.pb.h")
 set(hw_grpc_srcs "${CMAKE_CURRENT_BINARY_DIR}/include/caosdb/${hw_hdrs_path}/main.grpc.pb.cc")
 set(hw_grpc_hdrs "${CMAKE_CURRENT_BINARY_DIR}/include/caosdb/${hw_hdrs_path}/main.grpc.pb.h")
+
+# compile *proto files to cpp
+set(GRPC_GENERATED_HEADERS
+    "${hw_proto_hdrs}"
+    "${hw_grpc_hdrs}")
+set(GRPC_GENERATED_SOURCES
+    "${hw_proto_srcs}"
+    "${hw_grpc_srcs}")
+set(GRPC_GENERATED
+    ${GRPC_GENERATED_SOURCES}
+    ${GRPC_GENERATED_HEADERS})
 add_custom_command(
-      OUTPUT "${hw_proto_srcs}" "${hw_proto_hdrs}" "${hw_grpc_srcs}" "${hw_grpc_hdrs}"
+      OUTPUT ${GRPC_GENERATED}
       COMMAND ${_PROTOBUF_PROTOC}
       ARGS --grpc_out "${CMAKE_CURRENT_BINARY_DIR}/include"
         --cpp_out "${CMAKE_CURRENT_BINARY_DIR}/include"
@@ -118,17 +130,11 @@ add_custom_command(
       DEPENDS "${PROTO_FILES}")
 
 
-
 # hw_grpc_proto
 add_library(caosdb_info_v1alpha1
-  ${hw_grpc_srcs}
-  ${hw_grpc_hdrs}
-  ${hw_proto_srcs}
-  ${hw_proto_hdrs})
+    ${GRPC_GENERATED})
 target_link_libraries(caosdb_info_v1alpha1
-  ${_REFLECTION}
-  ${_GRPC_GRPCPP}
-  ${_PROTOBUF_LIBPROTOBUF})
+  ${CONAN_LIBS})
 target_include_directories(caosdb_info_v1alpha1 PUBLIC
    # headers to include when building from source
    $<BUILD_INTERFACE:${libcaosdb_SOURCE_DIR}/include>
@@ -138,10 +144,7 @@ target_include_directories(caosdb_info_v1alpha1 PUBLIC
 
 target_link_libraries(caosdb
 caosdb_info_v1alpha1
-${CONAN_LIBS}
-${_REFLECTION}
-${_GRPC_GRPCPP}
-${_PROTOBUF_LIBPROTOBUF})
+${CONAN_LIBS})
 
 
 ###############################################
@@ -236,7 +239,7 @@ install(
 ## install(FILES ...) simply puts files in a certain place with certain
 ## properties. We're just copying them to the desired place here.
 install(FILES ${libcaosdb_INCL} DESTINATION ${libcaosdb_INCLUDE_DEST})
-install(FILES ${hw_grpc_hdrs} ${hw_proto_hdrs}
+install(FILES ${GRPC_GENERATED_HEADERS}
     DESTINATION ${libcaosdb_INCLUDE_DEST}/${hw_hdrs_path})
 install(FILES ${PROJECT_SOURCE_DIR}/caosdbConfig.cmake
     DESTINATION ${libcaosdb_CMAKE_DEST})
diff --git a/conanfile.py b/conanfile.py
new file mode 100644
index 0000000..062ec8d
--- /dev/null
+++ b/conanfile.py
@@ -0,0 +1,50 @@
+from conans import ConanFile, CMake, tools
+
+
+class LibcaosdbConan(ConanFile):
+    name = "libcaosdb"
+    version = "0.0.1"
+    license = "AGPL-3.0-or-later"
+    author = "Timm C. Fitschen <t.fitschen@indiscale.com>"
+    url = "https://gitlab.indiscale.com/caosdb/src/caosdb-cpplib.git"
+    description = "C++ library for the CaosDB project"
+    topics = ("data management", "caosdb")
+    settings = "os", "compiler", "build_type", "arch"
+    options = {"shared": [True, False], "fPIC": [True, False]}
+    default_options = {"shared": False, "fPIC": True}
+    generators = "cmake"
+    requires = [("boost/1.76.0"), ("gtest/1.11.0"), ("grpc/1.38.0")]
+    exports = "*.cpp", "*h"
+
+    def config_options(self):
+        if self.settings.os == "Windows":
+            del self.options.fPIC
+
+    def source(self):
+        self.run("git clone https://gitlab.indiscale.com/caosdb/src/caosdb-cpplib.git")
+
+    def imports(self):
+        self.copy("protoc*", "build_tools", "bin")
+        self.copy("grpc_cpp_plugin", "build_tools", "bin")
+
+    def build(self):
+        cmake = CMake(self)
+        cmake.configure(source_folder="src")
+        cmake.build()
+
+        # Explicit way:
+        # self.run('cmake %s/hello %s'
+        #          % (self.source_folder, cmake.command_line))
+        # self.run("cmake --build . %s" % cmake.build_config)
+
+    def package(self):
+        self.copy("*.h", dst="include", src="include")
+        self.copy("*hello.lib", dst="lib", keep_path=False)
+        self.copy("*.dll", dst="bin", keep_path=False)
+        self.copy("*.so", dst="lib", keep_path=False)
+        self.copy("*.dylib", dst="lib", keep_path=False)
+        self.copy("*.a", dst="lib", keep_path=False)
+
+    def package_info(self):
+        self.cpp_info.libs = ["libcaosdb"]
+
diff --git a/conanfile.txt b/conanfile.txt
index 9c597bc..486d3b1 100644
--- a/conanfile.txt
+++ b/conanfile.txt
@@ -1,5 +1,11 @@
 [requires]
 boost/1.76.0
+gtest/1.11.0
+grpc/1.38.0
 
 [generators]
 cmake
+
+[imports]
+bin, protoc* -> ./build_tools
+bin, grpc_cpp_plugin* -> ./build_tools
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 44dc1a7..a402a11 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -25,15 +25,15 @@ set(test_cases
     )
 
 # download gtest library
-include(FetchGTest)
+#include(FetchGTest)
 # add special cmake functions for gtest
 include(GoogleTest)
 
 # disable linting for gtest targets (not our concern)
-set_target_properties(gmock_main gmock gtest gtest_main PROPERTIES
-    CXX_CLANG_TIDY ""
-    CXX_INCLUDE_WHAT_YOU_USE ""
-    EXCLUDE_FROM_ALL 1)
+#set_target_properties(gmock_main gmock gtest gtest_main PROPERTIES
+    #CXX_CLANG_TIDY ""
+    #CXX_INCLUDE_WHAT_YOU_USE ""
+    #EXCLUDE_FROM_ALL 1)
 
 # loop over all test cases and add them to the test runner
 list(LENGTH test_cases len_test_cases)
@@ -41,7 +41,7 @@ math(EXPR len_test_cases "${len_test_cases} - 1")
 foreach (i RANGE "${len_test_cases}")
     list(GET test_cases ${i} test_case_name)
     add_executable(${test_case_name} ${test_case_name}.cpp)
-    target_link_libraries(${test_case_name} PRIVATE gtest_main caosdb)
+    target_link_libraries(${test_case_name} PRIVATE caosdb ${CONAN_LIBS_GTEST} ${CONAN_LIBS_BOOST})
     set_target_properties(${test_case_name} PROPERTIES CXX_CLANG_TIDY "")
     gtest_discover_tests(${test_case_name}
         PROPERTIES
@@ -58,7 +58,7 @@ if (LCOV_PATH)
         NAME unit_test_coverage
         EXECUTABLE ctest -L caosdb-cpplib-unit-tests
         EXCLUDE "${CMAKE_BINARY_DIR}/*"
-        DEPEDENCIES caosdb ${test_cases} gtest_main
+        DEPENDENCIES caosdb ${test_cases}
         LCOV_ARGS --rc lcov_branch_coverage=1 --no-external
         GENHTML_ARGS --rc lcov_branch_coverage=1
         )
diff --git a/test_package/CMakeLists.txt b/test_package/CMakeLists.txt
new file mode 100644
index 0000000..c575fe0
--- /dev/null
+++ b/test_package/CMakeLists.txt
@@ -0,0 +1,14 @@
+cmake_minimum_required(VERSION 3.1)
+project(PackageTest CXX)
+
+include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
+conan_basic_setup()
+
+add_executable(example example.cpp)
+target_link_libraries(example ${CONAN_LIBS})
+
+# CTest is a testing tool that can be used to test your project.
+# enable_testing()
+# add_test(NAME example
+#          WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/bin
+#          COMMAND example)
diff --git a/test_package/conanfile.py b/test_package/conanfile.py
new file mode 100644
index 0000000..fb6117e
--- /dev/null
+++ b/test_package/conanfile.py
@@ -0,0 +1,25 @@
+import os
+
+from conans import ConanFile, CMake, tools
+
+
+class LibcaosdbTestConan(ConanFile):
+    settings = "os", "compiler", "build_type", "arch"
+    generators = "cmake"
+
+    def build(self):
+        cmake = CMake(self)
+        # Current dir is "test_package/build/<build_id>" and CMakeLists.txt is
+        # in "test_package"
+        cmake.configure()
+        cmake.build()
+
+    def imports(self):
+        self.copy("*.dll", dst="bin", src="bin")
+        self.copy("*.dylib*", dst="bin", src="lib")
+        self.copy('*.so*', dst='bin', src='lib')
+
+    def test(self):
+        if not tools.cross_building(self):
+            os.chdir("bin")
+            self.run(".%sexample" % os.sep)
diff --git a/test_package/example.cpp b/test_package/example.cpp
new file mode 100644
index 0000000..0d25749
--- /dev/null
+++ b/test_package/example.cpp
@@ -0,0 +1,5 @@
+#include "hello.h"
+
+int main() {
+    hello();
+}
-- 
GitLab