Skip to content

Commit

Permalink
feat: support cmake compile (#124)
Browse files Browse the repository at this point in the history
  • Loading branch information
JayInnn authored Sep 20, 2023
1 parent 90da327 commit c2bb8b4
Show file tree
Hide file tree
Showing 17 changed files with 921 additions and 0 deletions.
10 changes: 10 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,16 @@ jobs:
- name: Run bazel test with CLANG c++17
run: |
bazel test --config=clang --cxxopt=-std=c++17 //...
- name: Install cmake dependencies and run cmake compile
run: |
sudo apt update
sudo apt -y install cmake
sudo git clone -b v9.1.0 https://github.com/apache/skywalking-data-collect-protocol.git ./3rdparty/skywalking-data-collect-protocol
sudo git clone -b v1.46.6 https://github.com/grpc/grpc.git --recursive
sudo cmake -S ./grpc -B ./grpc/build
sudo cmake --build ./grpc/build --parallel 8 --target install
sudo cmake -S . -B ./build
sudo cmake --build ./build
- name: Install lcov and genhtml and link llvm
run: |
sudo apt update
Expand Down
130 changes: 130 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
cmake_minimum_required(VERSION 3.14 FATAL_ERROR)

if(POLICY CMP0091)
cmake_policy(SET CMP0091 NEW) # recognize CMAKE_MSVC_RUNTIME_LIBRARY
endif()

project(cpp2sky
VERSION 0.5.1
DESCRIPTION "Distributed tracing and monitor SDK in CPP for Apache SkyWalking APM"
HOMEPAGE_URL "https://github.com/SkyAPM/cpp2sky"
)

option(OVERRIDE_CXX_STANDARD_FLAGS "Force building with -std=c++11 even if the CXXFLAGS are configured differently" ON)
option(SPDLOG_FETCHCONTENT "Using spdlog FetchContent to build" ON)
option(FMTLIB_FETCHCONTENT "Using fmt FetchContent to build" ON)
option(HTTPLIB_FETCHCONTENT "Using httplib FetchContent to build" ON)
option(CPP2SKY_INSTALL "Generate the install target." OFF)
option(GENERATE_CPP2SKY_PKGCONFIG "Generate and install pkg-config files for UNIX" OFF)


if(OVERRIDE_CXX_STANDARD_FLAGS)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_EXTENSIONS OFF)
endif()

include(GNUInstallDirs)
set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
find_package(Threads)


file(GLOB_RECURSE SOURCE_CC_FILES "source/*.cc")
file(GLOB_RECURSE SOURCE_HDR_FILES "source/*.h")
add_library(${PROJECT_NAME} STATIC ${SOURCE_CC_FILES} ${SOURCE_HDR_FILES})
target_include_directories(${PROJECT_NAME} PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
)

add_executable(example-sample "example/sample.cc")
add_executable(example-sample-client "example/sample_client.cc")
target_link_libraries(example-sample ${PROJECT_NAME})
target_link_libraries(example-sample-client ${PROJECT_NAME})


list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
include(fmtlib)
include(spdlog)
include(httplib)
include(grpc)
include(proto2cpp)

target_link_libraries(${PROJECT_NAME}
PUBLIC $<BUILD_INTERFACE:proto_lib>
${_REFLECTION}
${_GRPC_GRPCPP}
${_PROTOBUF_LIBPROTOBUF}
fmt
spdlog
$<$<BOOL:${HTTPLIB_FETCHCONTENT}>:httplib>
)


if(CPP2SKY_INSTALL)
include(CMakePackageConfigHelpers)
# Install the static library.
install(
TARGETS ${PROJECT_NAME}
EXPORT ${PROJECT_NAME}-targets
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)

# Install export
install(
EXPORT ${PROJECT_NAME}-targets
NAMESPACE ${PROJECT_NAME}::
FILE ${PROJECT_NAME}-targets.cmake
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
)

# Install the project include
install(DIRECTORY cpp2sky
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
FILES_MATCHING
PATTERN "*.h"
PATTERN "BUILD" EXCLUDE
PATTERN "*.proto" EXCLUDE
)

# Install *.cmake.in
configure_package_config_file(
${PROJECT_SOURCE_DIR}/cmake/cpp2sky-config.cmake.in
${PROJECT_BINARY_DIR}/${PROJECT_NAME}-config.cmake
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}
)

install(
FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
)
endif()


if(GENERATE_CPP2SKY_PKGCONFIG)
# see https://github.com/jupp0r/prometheus-cpp/issues/587
if(IS_ABSOLUTE "${CMAKE_INSTALL_INCLUDEDIR}")
set(CPP2SKY_PKGCONFIG_INCLUDEDIR "${CMAKE_INSTALL_INCLUDEDIR}")
else()
set(CPP2SKY_PKGCONFIG_INCLUDEDIR "\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}")
endif()

if(IS_ABSOLUTE "${CMAKE_INSTALL_LIBDIR}")
set(CPP2SKY_PKGCONFIG_LIBDIR "${CMAKE_INSTALL_LIBDIR}")
else()
set(CPP2SKY_PKGCONFIG_LIBDIR "\${exec_prefix}/${CMAKE_INSTALL_LIBDIR}")
endif()
configure_file(
${PROJECT_SOURCE_DIR}/cmake/cpp2sky.pc.in
${PROJECT_BINARY_DIR}/cpp2sky.pc
@ONLY
)

# Install the pkgconfig
install(
FILES ${PROJECT_BINARY_DIR}/cpp2sky.pc
DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig"
)

endif()
23 changes: 23 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,30 @@ cc_binary(
],
)
```
#### Cmake
You can compile this project, according to the following steps:
```
step 01: git clone git@github.com:SkyAPM/cpp2sky.git
step 02: git clone -b v9.1.0 https://github.com/apache/skywalking-data-collect-protocol.git ./3rdparty/skywalking-data-collect-protocol
step 03: git clone -b v1.46.6 https://github.com/grpc/grpc.git --recursive
step 04: cmake -S ./grpc -B ./grpc/build && cmake --build ./grpc/build --parallel 8 --target install
step 05: cmake -S . -B ./build && cmake --build ./build
```

You can also use find_package to get target libary in your project. Like this:
```
find_package(cpp2sky CONFIG REQUIRED)
target_link_libraries(${PROJECT_NAME} cpp2sky::cpp2sky proto_lib)
```
Of course, if OS is similar to Unix, you can also use pkgconfig to build the project. Like this:
```
find_package(PkgConfig REQUIRED)
pkg_check_modules(CPP2SKY_PKG REQUIRED cpp2sky)
```

Note:
- If you want to build this project over c11, you must update grpc version(current version:v1.46.6).
- Only test cmake using Centos and Ubuntu.
#### Docs

cpp2sky configration is based on protobuf, and docs are generated by [protodoc](https://github.com/etcd-io/protodoc). If you have any API change, you should run below.
Expand Down
15 changes: 15 additions & 0 deletions cmake/cpp2sky-config.cmake.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
@PACKAGE_INIT@
include(CMakeFindDependencyMacro)

set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
find_dependency(Threads)
unset(CMAKE_THREAD_PREFER_PTHREAD)

find_dependency(fmt)
find_dependency(spdlog)
find_dependency(httplib)
find_dependency(Protobuf)
find_dependency(gRPC)


include(${CMAKE_CURRENT_LIST_DIR}/cpp2sky-targets.cmake)
10 changes: 10 additions & 0 deletions cmake/cpp2sky.pc.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
prefix=@CMAKE_INSTALL_PREFIX@
exec_prefix=@CMAKE_INSTALL_PREFIX@
libdir=@CPP2SKY_PKGCONFIG_LIBDIR@
includedir=@CPP2SKY_PKGCONFIG_INCLUDEDIR@

Name: cpp2sky
Description: Distributed tracing and monitor SDK in CPP for Apache SkyWalking APM
Version: @CPP2SKY_VERSION@
Libs: -L${libdir} -lcpp2sky
Cflags: -I${includedir}/skywalking-protocol
32 changes: 32 additions & 0 deletions cmake/fmtlib.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
cmake_minimum_required(VERSION 3.14)

if(MSVC)
add_definitions(-D_WIN32_WINNT=0x600)
endif()

find_package(Threads REQUIRED)

if(FMTLIB_AS_SUBMODULE)
# using submodule in case of git clone timeout
if(CPP2SKY_INSTALL)
set(FMT_INSTALL ON)
endif(CPP2SKY_INSTALL)
add_subdirectory(3rdparty/fmt ${CMAKE_CURRENT_BINARY_DIR}/fmt)
message(STATUS "Using fmt via add_subdirectory.")
elseif(FMTLIB_FETCHCONTENT)
# using FetchContent to install spdlog
include(FetchContent)
if(${CMAKE_VERSION} VERSION_LESS 3.14)
include(add_FetchContent_MakeAvailable.cmake)
endif()

FetchContent_Declare(
fmtlib
URL https://github.com/fmtlib/fmt/releases/download/8.1.1/fmt-8.1.1.zip
URL_HASH SHA256=23778bad8edba12d76e4075da06db591f3b0e3c6c04928ced4a7282ca3400e5d
)
FetchContent_MakeAvailable(fmtlib)
else()
find_package(fmt CONFIG REQUIRED)
message(STATUS "Using fmt by find_package")
endif()
125 changes: 125 additions & 0 deletions cmake/grpc.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
# Copyright 2018 gRPC authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# cmake build file for C++ route_guide example.
# Assumes protobuf and gRPC have been installed using cmake.
# See cmake_externalproject/CMakeLists.txt for all-in-one cmake build
# that automatically builds all the dependencies before building route_guide.

cmake_minimum_required(VERSION 3.14)

if(MSVC)
add_definitions(-D_WIN32_WINNT=0x600)
endif()

find_package(Threads REQUIRED)

if(GRPC_AS_SUBMODULE)
# One way to build a projects that uses gRPC is to just include the
# entire gRPC project tree via "add_subdirectory".
# This approach is very simple to use, but the are some potential
# disadvantages:
# * it includes gRPC's CMakeLists.txt directly into your build script
# without and that can make gRPC's internal setting interfere with your
# own build.
# * depending on what's installed on your system, the contents of submodules
# in gRPC's third_party/* might need to be available (and there might be
# additional prerequisites required to build them). Consider using
# the gRPC_*_PROVIDER options to fine-tune the expected behavior.
#
# A more robust approach to add dependency on gRPC is using
# cmake's ExternalProject_Add (see cmake_externalproject/CMakeLists.txt).

# Include the gRPC's cmake build (normally grpc source code would live
# in a git submodule called "third_party/grpc", but this example lives in
# the same repository as gRPC sources, so we just look a few directories up)
if(NOT GRPC_ROOT_DIR)
set(GRPC_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/grpc)
endif()
add_subdirectory(${GRPC_ROOT_DIR} 3rdparty/grpc)
message(STATUS "Using gRPC via add_subdirectory.")
# After using add_subdirectory, we can now use the grpc targets directly from
# this build.
set(_PROTOBUF_LIBPROTOBUF libprotobuf)
set(_REFLECTION grpc++_reflection)
if(CMAKE_CROSSCOMPILING)
find_program(_PROTOBUF_PROTOC protoc)
else()
set(_PROTOBUF_PROTOC $<TARGET_FILE:protoc>)
endif()
set(_GRPC_GRPCPP grpc++)
if(CMAKE_CROSSCOMPILING)
find_program(_GRPC_CPP_PLUGIN_EXECUTABLE grpc_cpp_plugin)
else()
set(_GRPC_CPP_PLUGIN_EXECUTABLE $<TARGET_FILE:grpc_cpp_plugin>)
endif()
elseif(GRPC_FETCHCONTENT)
# Another way is to use CMake's FetchContent module to clone gRPC at
# configure time. This makes gRPC's source code available to your project,
# similar to a git submodule.
message(STATUS "Using gRPC via add_subdirectory (FetchContent).")
include(FetchContent)
FetchContent_Declare(
grpc
URL https://github.com/grpc/grpc/archive/a3ae8e00a2c5553c806e83fae83e33f0198913f0.tar.gz
URL_HASH SHA256=1ccc2056b68b81ada8df61310e03dfa0541c34821fd711654d0590a7321db9c8
)
FetchContent_MakeAvailable(grpc)

# Since FetchContent uses add_subdirectory under the hood, we can use
# the grpc targets directly from this build.
set(_PROTOBUF_LIBPROTOBUF libprotobuf)
set(_REFLECTION grpc++_reflection)
set(_PROTOBUF_PROTOC $<TARGET_FILE:protoc>)
set(_GRPC_GRPCPP grpc++)
if(CMAKE_CROSSCOMPILING)
find_program(_GRPC_CPP_PLUGIN_EXECUTABLE grpc_cpp_plugin)
else()
set(_GRPC_CPP_PLUGIN_EXECUTABLE $<TARGET_FILE:grpc_cpp_plugin>)
endif()
else()
# This branch assumes that gRPC and all its dependencies are already installed
# on this system, so they can be located by find_package().
message(STATUS "gRPC and all its dependencies should be able to located by find_package().")

# Find Protobuf installation
# Looks for protobuf-config.cmake file installed by Protobuf's cmake installation.
option(protobuf_MODULE_COMPATIBLE TRUE)
find_package(Protobuf CONFIG REQUIRED)
message(STATUS "Using protobuf ${Protobuf_VERSION}")

set(_PROTOBUF_LIBPROTOBUF protobuf::libprotobuf)
set(_REFLECTION gRPC::grpc++_reflection)

message(STATUS "CMAKE_CROSSCOMPILING: ${CMAKE_CROSSCOMPILING}")

if(CMAKE_CROSSCOMPILING)
find_program(_PROTOBUF_PROTOC protoc)
else()
set(_PROTOBUF_PROTOC $<TARGET_FILE:protobuf::protoc>)
endif()

# Find gRPC installation
# Looks for gRPCConfig.cmake file installed by gRPC's cmake installation.
find_package(gRPC CONFIG REQUIRED)
message(STATUS "Using gRPC ${gRPC_VERSION}")

set(_GRPC_GRPCPP gRPC::grpc++)
if(CMAKE_CROSSCOMPILING)
find_program(_GRPC_CPP_PLUGIN_EXECUTABLE grpc_cpp_plugin)
else()
set(_GRPC_CPP_PLUGIN_EXECUTABLE $<TARGET_FILE:gRPC::grpc_cpp_plugin>)
endif()

endif()
Loading

0 comments on commit c2bb8b4

Please sign in to comment.