diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index d2a51b1..e050914 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -80,6 +80,9 @@ jobs: - run: echo "/opt/llvm/bin" >> $GITHUB_PATH - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + submodules: 'recursive' + fetch-depth: 0 - name: Generate dependencies hash id: deps-hash @@ -90,19 +93,12 @@ jobs: echo "hash=$DEPS_HASH" >> $GITHUB_OUTPUT echo "Dependencies hash (first 8 chars): $DEPS_HASH" - - name: Checkout skywalking-data-collect-protocol - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - with: - repository: apache/skywalking-data-collect-protocol - ref: ${{ env.SKYWALKING_PROTOCOL_REF }} - path: 3rdparty/skywalking-data-collect-protocol - # Cache gRPC build - name: Cache gRPC build uses: actions/cache@v3 with: path: | - grpc/build + 3rdparty/grpc/build /usr/local/lib/libgrpc* /usr/local/lib/libprotobuf* /usr/local/lib/cmake/grpc @@ -115,21 +111,12 @@ jobs: restore-keys: | grpc-cmake-${{ runner.os }}-${{ steps.deps-hash.outputs.hash }}- grpc-cmake-${{ runner.os }}- - - - name: Checkout grpc - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - with: - repository: grpc/grpc - ref: ${{ env.GRPC_VERSION }} - path: grpc - submodules: true - - name: Install cmake dependencies and run cmake compile run: | sudo apt-get update sudo apt-get install -y cmake build-essential - sudo cmake -S ./grpc -B ./grpc/build - sudo cmake --build ./grpc/build --parallel 8 --target install + sudo cmake -S ./3rdparty/grpc -B ./3rdparty/grpc/build + sudo cmake --build ./3rdparty/grpc/build --parallel 8 --target install sudo cmake -S . -B ./build sudo cmake --build ./build diff --git a/.gitignore b/.gitignore index 5441f07..8a054bb 100644 --- a/.gitignore +++ b/.gitignore @@ -48,7 +48,6 @@ coverage_report # CMake build directories and dependencies build/ -3rdparty/ grpc/ ### Automatically added by Hedron's Bazel Compile Commands Extractor: https://github.com/hedronvision/bazel-compile-commands-extractor diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..db84bf1 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,19 @@ +[submodule "3rdparty/fmt"] + path = 3rdparty/fmt + url = https://github.com/fmtlib/fmt.git + +[submodule "3rdparty/grpc"] + path = 3rdparty/grpc + url = https://github.com/grpc/grpc.git + +[submodule "3rdparty/httplib"] + path = 3rdparty/httplib + url = https://github.com/yhirose/cpp-httplib.git + +[submodule "3rdparty/skywalking-data-collect-protocol"] + path = 3rdparty/skywalking-data-collect-protocol + url = https://github.com/apache/skywalking-data-collect-protocol.git + +[submodule "3rdparty/spdlog"] + path = 3rdparty/spdlog + url = https://github.com/gabime/spdlog.git diff --git a/3rdparty/fmt b/3rdparty/fmt new file mode 160000 index 0000000..b6f4cea --- /dev/null +++ b/3rdparty/fmt @@ -0,0 +1 @@ +Subproject commit b6f4ceaed0a0a24ccf575fab6c56dd50ccf6f1a9 diff --git a/3rdparty/grpc b/3rdparty/grpc new file mode 160000 index 0000000..893bdad --- /dev/null +++ b/3rdparty/grpc @@ -0,0 +1 @@ +Subproject commit 893bdadd56dbb75fb156175afdaa2b0d47e1c15b diff --git a/3rdparty/httplib b/3rdparty/httplib new file mode 160000 index 0000000..b6c55c6 --- /dev/null +++ b/3rdparty/httplib @@ -0,0 +1 @@ +Subproject commit b6c55c6030f5160d1a360a5a5180ba3205e2ce2f diff --git a/3rdparty/skywalking-data-collect-protocol b/3rdparty/skywalking-data-collect-protocol new file mode 160000 index 0000000..055d64b --- /dev/null +++ b/3rdparty/skywalking-data-collect-protocol @@ -0,0 +1 @@ +Subproject commit 055d64b104b5d84e15e27b74f5cbe712e7f9b0df diff --git a/3rdparty/spdlog b/3rdparty/spdlog new file mode 160000 index 0000000..76fb40d --- /dev/null +++ b/3rdparty/spdlog @@ -0,0 +1 @@ +Subproject commit 76fb40d95455f249bd70824ecfcae7a8f0930fa3 diff --git a/CMakeLists.txt b/CMakeLists.txt index 4da9a56..c2a761b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,13 +10,14 @@ project(cpp2sky 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(FMTLIB_FETCHCONTENT "Using fmt FetchContent to build" OFF) option(GENERATE_CPP2SKY_PKGCONFIG "Generate and install pkg-config files for UNIX" OFF) - +option(GRPC_FETCHCONTENT "Using gRPC FetchContent to build" OFF) +option(HTTPLIB_FETCHCONTENT "Using httplib FetchContent to build" OFF) +option(OVERRIDE_CXX_STANDARD_FLAGS "Force building with -std=c++11 even if the CXXFLAGS are configured differently" ON) +option(SKYWALKING_FETCHCONTENT "Using skywalking-data-collect-protocol FetchContent to build" OFF) +option(SPDLOG_FETCHCONTENT "Using spdlog FetchContent to build" OFF) if(OVERRIDE_CXX_STANDARD_FLAGS) set(CMAKE_CXX_STANDARD 17) @@ -46,6 +47,7 @@ include(fmtlib) include(spdlog) include(httplib) include(grpc) +include(skywalking) include(proto2cpp) target_link_libraries(${PROJECT_NAME} diff --git a/README.md b/README.md index 44b25fe..4426dd5 100644 --- a/README.md +++ b/README.md @@ -33,15 +33,136 @@ cc_binary( #### Cmake -You can compile this project, according to the following steps: +You can compile this project in one of three supported ways (submodule-first is recommended): + +- Recommended — Submodule-first (most reproducible): + +```bash +git clone --recurse-submodules git@github.com:SkyAPM/cpp2sky.git +git submodule update --init --recursive ``` -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 + +This repository pins several third-party dependencies under `3rdparty/` (example: `spdlog`, `fmt`, `httplib`, `skywalking-data-collect-protocol`). The top-level CMake will auto-detect these submodules and use them via `add_subdirectory()`. + + - FetchContent fallback (automatic clone at configure time): + +If a submodule is not present, CMake can automatically download the dependency at configure time using FetchContent. This is controlled by CMake options of the form `-D_FETCHCONTENT=ON`. + +Important: this project now defaults `*_FETCHCONTENT` to `OFF` to favour a submodule-first workflow (reproducible builds). Each dependency module will auto-detect a local `3rdparty/` submodule and, unless you explicitly set the corresponding `-D` option, enable the submodule and only enable FetchContent as a fallback when the submodule is absent. + +FetchContent is declared uniformly using `GIT_REPOSITORY` + `GIT_TAG` where possible so the build can be pinned to a tag or an exact commit SHA. We strongly encourage this pattern because it makes bumps and temporary testing against a branch/commit straightforward. + +Recommended FetchContent pattern (preferred) + +```cmake +# variables make bumps easy and visible in the cmake file +set(FMTLIB_GIT_URL https://github.com/fmtlib/fmt.git) +set(FMTLIB_GIT_TAG 8.1.1) # or a commit SHA like `d6a5b8f...` + +FetchContent_Declare( + fmtlib + GIT_REPOSITORY ${FMTLIB_GIT_URL} + GIT_TAG ${FMTLIB_GIT_TAG} +) +FetchContent_MakeAvailable(fmtlib) ``` +Why this is useful +- `GIT_TAG` accepts tags, branches or a full commit SHA — use a SHA to pin an exact commit that isn't tagged. +- Using named variables (`*_GIT_URL`, `*_GIT_TAG`) makes automated bump scripts and review diffs clearer. + +Notes on projects with nested submodules +- Some repositories (notably gRPC) include their own git submodules. For those projects we recommend either: + - Use the release archive (`URL` + `URL_HASH`) which avoids nested submodule handling, or + - Use `GIT_REPOSITORY` + `GIT_TAG` but initialize nested submodules after `FetchContent_Populate`: + +```cmake +FetchContent_GetProperties(grpc) +if(NOT grpc_POPULATED) + FetchContent_Populate(grpc) + execute_process(COMMAND ${GIT_EXECUTABLE} submodule update --init --recursive + WORKING_DIRECTORY ${grpc_SOURCE_DIR}) + add_subdirectory(${grpc_SOURCE_DIR} ${grpc_BINARY_DIR}) +endif() +``` + +In this repository we prefer the archive approach for gRPC in CI for simplicity, but the git+tag approach is supported and useful for local testing or when you need to pin to a commit SHA. + +If you need to force FetchContent for any dependency (for example, to debug or when you prefer not to initialize submodules), you can pass `-D_FETCHCONTENT=ON` on the `cmake` command line. If you pass conflicting options (both `-D_AS_SUBMODULE=ON` and `-D_FETCHCONTENT=ON`) CMake will stop with a helpful error and you must choose one. + +For SkyWalking you can enable FetchContent with: + +```bash +cmake -DSKYWALKING_FETCHCONTENT=ON -S . -B build +cmake --build build +``` + +- Explicit path (developer workflow): + +If you already have a local checkout of `skywalking-data-collect-protocol`, point CMake to it: + +```bash +cmake -DSKYWALKING_PROTOCOL_PATH=/path/to/skywalking-data-collect-protocol -S . -B build +cmake --build build +``` + +Notes about dependencies with special handling + +Most third-party dependencies follow the same pattern: prefer the pinned submodule under `3rdparty/` (submodule-first) and fall back to `FetchContent` at configure time when the submodule is not present. See the top-level `CMakeLists.txt` and the modules in `cmake/` for details. + +There are two cases worth calling out because their consumption/build steps differ slightly: + +- gRPC + + gRPC is not header-only and typically needs configuration and a build step (or its targets must be available via `find_package`). This repository includes a pinned copy of gRPC at `3rdparty/grpc` (tag `v1.74.1`) so builds are reproducible. CI is configured to build gRPC from that submodule. + + To build gRPC locally from the submodule and install it for the rest of the project: + + ```bash + # initialize submodules (if you haven't already) + git submodule update --init --recursive + + # install build deps + sudo apt-get update + sudo apt-get install -y cmake build-essential + + # configure & install gRPC from the submodule + cmake -S 3rdparty/grpc -B 3rdparty/grpc/build + cmake --build 3rdparty/grpc/build --parallel 8 --target install + + # configure & build cpp2sky + cmake -S . -B build + cmake --build build --parallel $(nproc) + ``` + + If you prefer not to use the submodule you can still clone and build gRPC separately and make its CMake targets available to the project, but using the pinned submodule is recommended for reproducibility. + +- skywalking-data-collect-protocol (protobufs) + + The SkyWalking protocol repository contains the protobuf definitions used to generate code for the project. The `cmake/skywalking.cmake` module sets `SKYWALKING_PROTOCOL_PATH` when the `3rdparty/skywalking-data-collect-protocol` submodule is present so the proto generation step can locate the `.proto` files. + + You can override that behavior by supplying an explicit path: + + ```bash + cmake -DSKYWALKING_PROTOCOL_PATH=/path/to/skywalking-data-collect-protocol -S . -B build + cmake --build build + ``` + + Alternatively, enable FetchContent for SkyWalking with `-DSKYWALKING_FETCHCONTENT=ON` to let CMake fetch the proto repo at configure time. + +How to bump a submodule (example for skywalking-data-collect-protocol): +```bash +cd 3rdparty/skywalking-data-collect-protocol +git fetch --tags +git checkout tags/v10.4.0 # or a specific commit +cd ../.. +git add 3rdparty/skywalking-data-collect-protocol +git commit -m "Pin skywalking-data-collect-protocol to v10.4.0" +git push +``` + +If you prefer CI to always fetch the latest submodules, ensure the workflow initializes submodules (this repo's CI uses `actions/checkout` with `submodules: 'recursive'`). + You can also use find_package to get target libary in your project. Like this: ``` find_package(cpp2sky CONFIG REQUIRED) diff --git a/cmake/fmtlib.cmake b/cmake/fmtlib.cmake index d86ec5c..4f03ff0 100644 --- a/cmake/fmtlib.cmake +++ b/cmake/fmtlib.cmake @@ -5,25 +5,49 @@ if(MSVC) endif() find_package(Threads REQUIRED) +## Auto-detect fmt submodule if top-level didn't set the option +if(NOT DEFINED FMTLIB_AS_SUBMODULE) + if(EXISTS "${CMAKE_SOURCE_DIR}/3rdparty/fmt/CMakeLists.txt") + set(FMTLIB_AS_SUBMODULE ON CACHE BOOL "Use fmt as submodule (auto-detected)") + if(NOT DEFINED FMTLIB_FETCHCONTENT) + # Prefer submodule when present: disable FetchContent unless user explicitly requested it + set(FMTLIB_FETCHCONTENT OFF CACHE BOOL "Disable FetchContent since submodule is present") + endif() + else() + set(FMTLIB_AS_SUBMODULE OFF CACHE BOOL "Use fmt as a git submodule under 3rdparty/fmt") + if(NOT DEFINED FMTLIB_FETCHCONTENT) + # Fallback: enable FetchContent when submodule absent + set(FMTLIB_FETCHCONTENT ON CACHE BOOL "Use FetchContent (fallback)") + endif() + endif() +endif() + +# Sanity check for conflicting options (user-provided flags only) +if(FMTLIB_AS_SUBMODULE AND FMTLIB_FETCHCONTENT) + message(FATAL_ERROR "Conflicting options: FMTLIB_AS_SUBMODULE and FMTLIB_FETCHCONTENT are both ON. Choose one.") +endif() 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) + add_subdirectory("${CMAKE_SOURCE_DIR}/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() + endif() + + set(FMTLIB_GIT_URL https://github.com/fmtlib/fmt.git) + set(FMTLIB_GIT_TAG 8.1.1) FetchContent_Declare( fmtlib - URL https://github.com/fmtlib/fmt/releases/download/8.1.1/fmt-8.1.1.zip - URL_HASH SHA256=23778bad8edba12d76e4075da06db591f3b0e3c6c04928ced4a7282ca3400e5d + GIT_REPOSITORY ${FMTLIB_GIT_URL} + GIT_TAG ${FMTLIB_GIT_TAG} ) FetchContent_MakeAvailable(fmtlib) else() diff --git a/cmake/grpc.cmake b/cmake/grpc.cmake index eed0e1a..6a68807 100644 --- a/cmake/grpc.cmake +++ b/cmake/grpc.cmake @@ -24,6 +24,27 @@ if(MSVC) endif() find_package(Threads REQUIRED) +# Auto-detect gRPC submodule if the top-level didn't set the option +if(NOT DEFINED GRPC_AS_SUBMODULE) + if(EXISTS "${CMAKE_SOURCE_DIR}/3rdparty/grpc") + set(GRPC_AS_SUBMODULE ON CACHE BOOL "Use gRPC as submodule (auto-detected)") + if(NOT DEFINED GRPC_FETCHCONTENT) + # Prefer submodule when present: disable FetchContent unless user explicitly requested it + set(GRPC_FETCHCONTENT OFF CACHE BOOL "Disable FetchContent since submodule is present") + endif() + else() + set(GRPC_AS_SUBMODULE OFF CACHE BOOL "Use gRPC as a git submodule under 3rdparty/grpc") + if(NOT DEFINED GRPC_FETCHCONTENT) + # Fallback: enable FetchContent when submodule absent + set(GRPC_FETCHCONTENT ON CACHE BOOL "Use FetchContent (fallback)") + endif() + endif() +endif() + +# Sanity check for conflicting options (user-provided flags only) +if(GRPC_AS_SUBMODULE AND GRPC_FETCHCONTENT) + message(FATAL_ERROR "Conflicting options: GRPC_AS_SUBMODULE and GRPC_FETCHCONTENT are both ON. Choose one.") +endif() if(GRPC_AS_SUBMODULE) # One way to build a projects that uses gRPC is to just include the @@ -45,9 +66,18 @@ if(GRPC_AS_SUBMODULE) # 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) + set(GRPC_ROOT_DIR "${CMAKE_SOURCE_DIR}/3rdparty/grpc") + endif() + # When building gRPC as a subdirectory, disable protobuf's install() export + # and tests by default to avoid protobuf trying to create an install export + # that references Abseil targets which are not part of the export set. + if(NOT DEFINED protobuf_INSTALL) + set(protobuf_INSTALL OFF CACHE BOOL "Disable protobuf install when built as submodule") + endif() + if(NOT DEFINED protobuf_BUILD_TESTS) + set(protobuf_BUILD_TESTS OFF CACHE BOOL "Disable protobuf tests when built as submodule") endif() - add_subdirectory(${GRPC_ROOT_DIR} 3rdparty/grpc) + add_subdirectory("${GRPC_ROOT_DIR}" "${CMAKE_CURRENT_BINARY_DIR}/grpc") message(STATUS "Using gRPC via add_subdirectory.") # After using add_subdirectory, we can now use the grpc targets directly from # this build. @@ -68,17 +98,44 @@ 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).") + message(STATUS "Using gRPC via FetchContent (git clone).") include(FetchContent) + + set(GRPC_GIT_URL https://github.com/grpc/grpc.git) + set(GRPC_GIT_TAG v1.74.1) + FetchContent_Declare( grpc - URL https://github.com/grpc/grpc/archive/refs/tags/v1.74.1.tar.gz - URL_HASH SHA256=7bf97c11cf3808d650a3a025bbf9c5f922c844a590826285067765dfd055d228 + GIT_REPOSITORY ${GRPC_GIT_URL} + GIT_TAG ${GRPC_GIT_TAG} + ) + + # Populate the content so we can initialize nested submodules if present, + # then add_subdirectory from the populated source dir. + FetchContent_GetProperties(grpc) + if(NOT grpc_POPULATED) + FetchContent_Populate(grpc) + find_package(Git REQUIRED) + execute_process( + COMMAND ${GIT_EXECUTABLE} submodule update --init --recursive + WORKING_DIRECTORY ${grpc_SOURCE_DIR} + RESULT_VARIABLE _grpc_submod_result + OUTPUT_QUIET + ERROR_QUIET ) - FetchContent_MakeAvailable(grpc) - - # Since FetchContent uses add_subdirectory under the hood, we can use - # the grpc targets directly from this build. + # Same safeguard when populating gRPC via FetchContent: prevent protobuf + # from registering install exports that reference Abseil-only targets. + if(NOT DEFINED protobuf_INSTALL) + set(protobuf_INSTALL OFF CACHE BOOL "Disable protobuf install when built via FetchContent") + endif() + if(NOT DEFINED protobuf_BUILD_TESTS) + set(protobuf_BUILD_TESTS OFF CACHE BOOL "Disable protobuf tests when built via FetchContent") + endif() + add_subdirectory(${grpc_SOURCE_DIR} ${grpc_BINARY_DIR}) + endif() + + # Since we used add_subdirectory, we can use the grpc targets directly from + # this build. set(_PROTOBUF_LIBPROTOBUF libprotobuf) set(_REFLECTION grpc++_reflection) set(_PROTOBUF_PROTOC $) diff --git a/cmake/httplib.cmake b/cmake/httplib.cmake index 832110e..c21579d 100644 --- a/cmake/httplib.cmake +++ b/cmake/httplib.cmake @@ -5,10 +5,31 @@ if(MSVC) endif() find_package(Threads REQUIRED) +## Auto-detect httplib submodule if top-level didn't set the option +if(NOT DEFINED HTTPLIB_AS_SUBMODULE) + # using submodule in case of git clone timeout + if(EXISTS "${CMAKE_SOURCE_DIR}/3rdparty/httplib/CMakeLists.txt") + set(HTTPLIB_AS_SUBMODULE ON CACHE BOOL "Use httplib as submodule (auto-detected)") + if(NOT DEFINED HTTPLIB_FETCHCONTENT) + # Prefer submodule when present: disable FetchContent unless user explicitly requested it + set(HTTPLIB_FETCHCONTENT OFF CACHE BOOL "Disable FetchContent since submodule is present") + endif() + else() + set(HTTPLIB_AS_SUBMODULE OFF CACHE BOOL "Use httplib as a git submodule under 3rdparty/httplib") + if(NOT DEFINED HTTPLIB_FETCHCONTENT) + # Fallback: enable FetchContent when submodule absent + set(HTTPLIB_FETCHCONTENT ON CACHE BOOL "Use FetchContent (fallback)") + endif() + endif() +endif() + +# Sanity check for conflicting options (user-provided flags only) +if(HTTPLIB_AS_SUBMODULE AND HTTPLIB_FETCHCONTENT) + message(FATAL_ERROR "Conflicting options: HTTPLIB_AS_SUBMODULE and HTTPLIB_FETCHCONTENT are both ON. Choose one.") +endif() if(HTTPLIB_AS_SUBMODULE) - # using submodule in case of git clone timeout - add_subdirectory(3rdparty/httplib ${CMAKE_CURRENT_BINARY_DIR}/httplib) + add_subdirectory("${CMAKE_SOURCE_DIR}/3rdparty/httplib" "${CMAKE_CURRENT_BINARY_DIR}/httplib") message(STATUS "Using httplib via add_subdirectory.") elseif(HTTPLIB_FETCHCONTENT) # using FetchContent to install spdlog diff --git a/cmake/proto2cpp.cmake b/cmake/proto2cpp.cmake index bd16313..594e9e4 100644 --- a/cmake/proto2cpp.cmake +++ b/cmake/proto2cpp.cmake @@ -75,7 +75,11 @@ endif() # First compile common proto files (dependencies) set(NEED_GRPC_SERVICE OFF) set(PROTOC_FILES common/Common.proto common/Command.proto) -set(PROTOC_BASE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/skywalking-data-collect-protocol") +if(DEFINED SKYWALKING_PROTOCOL_PATH) + set(PROTOC_BASE_DIR "${SKYWALKING_PROTOCOL_PATH}") +else() + message(FATAL_ERROR "skywalking-data-collect-protocol not configured. Initialize submodules (git submodule update --init --recursive), set -DSKYWALKING_PROTOCOL_PATH=/path/to/skywalking-data-collect-protocol, or enable SKYWALKING_FETCHCONTENT in CMake.") +endif() PROTOBUF_GENERATE_CPP(SDC_PROTO_SRCS SDC_PROTO_HDRS ${PROTOC_BASE_DIR} ${NEED_GRPC_SERVICE} ${PROTOC_FILES}) # Then compile service proto files (depend on common) diff --git a/cmake/skywalking.cmake b/cmake/skywalking.cmake new file mode 100644 index 0000000..0b6ff48 --- /dev/null +++ b/cmake/skywalking.cmake @@ -0,0 +1,61 @@ +cmake_minimum_required(VERSION 3.14) + +if(MSVC) + add_definitions(-D_WIN32_WINNT=0x600) +endif() + +find_package(Threads REQUIRED) +## Auto-detect skywalking-data-collect-protocol submodule if top-level didn't set the option +if(NOT DEFINED SKYWALKING_AS_SUBMODULE) + if(EXISTS "${CMAKE_SOURCE_DIR}/3rdparty/skywalking-data-collect-protocol/CMakeLists.txt" OR EXISTS "${CMAKE_SOURCE_DIR}/3rdparty/skywalking-data-collect-protocol") + set(SKYWALKING_AS_SUBMODULE ON CACHE BOOL "Use skywalking-data-collect-protocol as submodule (auto-detected)") + if(NOT DEFINED SKYWALKING_FETCHCONTENT) + # Prefer submodule when present: disable FetchContent unless user explicitly requested it + set(SKYWALKING_FETCHCONTENT OFF CACHE BOOL "Disable FetchContent since submodule is present") + endif() + else() + set(SKYWALKING_AS_SUBMODULE OFF CACHE BOOL "Use skywalking-data-collect-protocol as a git submodule under 3rdparty/skywalking-data-collect-protocol") + if(NOT DEFINED SKYWALKING_FETCHCONTENT) + # Fallback: enable FetchContent when submodule absent + set(SKYWALKING_FETCHCONTENT ON CACHE BOOL "Use FetchContent (fallback)") + endif() + endif() +endif() + +# Sanity check for conflicting options (user-provided flags only) +if(SKYWALKING_AS_SUBMODULE AND SKYWALKING_FETCHCONTENT) + message(FATAL_ERROR "Conflicting options: SKYWALKING_AS_SUBMODULE and SKYWALKING_FETCHCONTENT are both ON. Choose one.") +endif() + +## This module respects variables set by the top-level project: +## - SKYWALKING_FETCHCONTENT : option declared at top-level to allow FetchContent fallback +## - SKYWALKING_PROTOCOL_PATH : explicit path override + +if(SKYWALKING_AS_SUBMODULE) + set(SKYWALKING_PROTOCOL_PATH "${CMAKE_SOURCE_DIR}/3rdparty/skywalking-data-collect-protocol" CACHE PATH "Path to skywalking-data-collect-protocol (from submodule)") + message(STATUS "Using skywalking-data-collect-protocol from submodule: ${SKYWALKING_PROTOCOL_PATH}") +elseif(SKYWALKING_FETCHCONTENT) + include(FetchContent) + if(${CMAKE_VERSION} VERSION_LESS 3.14) + include(add_FetchContent_MakeAvailable.cmake) + endif() + + set(SKYWALKING_GIT_TAG v10.3.0) + set(SKYWALKING_GIT_URL https://github.com/apache/skywalking-data-collect-protocol.git) + + FetchContent_Declare( + skywalking_protocol + GIT_REPOSITORY ${SKYWALKING_GIT_URL} + GIT_TAG ${SKYWALKING_GIT_TAG} + ) + FetchContent_MakeAvailable(skywalking_protocol) + + # FetchContent makes available a variable _SOURCE_DIR + set(SKYWALKING_PROTOCOL_PATH "${skywalking_protocol_SOURCE_DIR}" CACHE PATH "Path to skywalking-data-collect-protocol (from FetchContent)") + message(STATUS "Using skywalking-data-collect-protocol via FetchContent: ${SKYWALKING_PROTOCOL_PATH}") +else() + if(NOT DEFINED SKYWALKING_PROTOCOL_PATH) + # Leave unset; proto2cpp will error with helpful message if not provided + message(STATUS "skywalking-data-collect-protocol not auto-detected; set -DSKYWALKING_PROTOCOL_PATH=/path or enable SKYWALKING_FETCHCONTENT.") + endif() +endif() diff --git a/cmake/spdlog.cmake b/cmake/spdlog.cmake index 47cb3b3..7a663f3 100644 --- a/cmake/spdlog.cmake +++ b/cmake/spdlog.cmake @@ -5,13 +5,34 @@ if(MSVC) endif() find_package(Threads REQUIRED) +# Auto-detect spdlog submodule if top-level didn't set the option +if(NOT DEFINED SPDLOG_AS_SUBMODULE) + if(EXISTS "${CMAKE_SOURCE_DIR}/3rdparty/spdlog/CMakeLists.txt") + set(SPDLOG_AS_SUBMODULE ON CACHE BOOL "Use spdlog as submodule (auto-detected)") + if(NOT DEFINED SPDLOG_FETCHCONTENT) + # Prefer submodule when present: disable FetchContent unless user explicitly requested it + set(SPDLOG_FETCHCONTENT OFF CACHE BOOL "Disable FetchContent since submodule is present") + endif() + else() + set(SPDLOG_AS_SUBMODULE OFF CACHE BOOL "Use spdlog as a git submodule under 3rdparty/spdlog") + if(NOT DEFINED SPDLOG_FETCHCONTENT) + # Fallback: enable FetchContent when submodule absent + set(SPDLOG_FETCHCONTENT ON CACHE BOOL "Use FetchContent (fallback)") + endif() + endif() +endif() + +# Sanity check for conflicting options (user-provided flags only) +if(SPDLOG_AS_SUBMODULE AND SPDLOG_FETCHCONTENT) + message(FATAL_ERROR "Conflicting options: SPDLOG_AS_SUBMODULE and SPDLOG_FETCHCONTENT are both ON. Choose one.") +endif() if(SPDLOG_AS_SUBMODULE) # using submodule in case of git clone timeout if(CPP2SKY_INSTALL) set(SPDLOG_MASTER_PROJECT ON) endif(CPP2SKY_INSTALL) - add_subdirectory(3rdparty/spdlog ${CMAKE_CURRENT_BINARY_DIR}/spdlog) + add_subdirectory("${CMAKE_SOURCE_DIR}/3rdparty/spdlog" "${CMAKE_CURRENT_BINARY_DIR}/spdlog") message(STATUS "Using spdlog via add_subdirectory.") elseif(SPDLOG_FETCHCONTENT) # using FetchContent to install spdlog