Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add CMake support #73

Closed
wants to merge 15 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .github/workflows/pre-commit.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
name: pre-commit

on:
workflow_dispatch:
pull_request:
push:
branches: [main]
branches:
- main

jobs:
pre-commit:
Expand Down
48 changes: 48 additions & 0 deletions .github/workflows/ubuntu-build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
name: ubuntu-build

on:
workflow_dispatch:
pull_request:
push:
branches:
- main

concurrency:
group: ci-${{github.workflow}}-${{ github.ref }}
cancel-in-progress: true

jobs:
build:
runs-on: ubuntu-22.04
name: ubuntu-build
steps:
- name: Show env
run: env

- name: Checkout
uses: actions/checkout@v3

- name: Install Build Dependencies
shell: bash
run: |
sudo apt update && sudo apt install --no-install-recommends -y \
cmake \
make

- name: Show Python version and platform info
run: |
python --version
python -m platform

- name: Show CMake version
run: cmake --version

- name: CMake Configure
shell: bash
run: |
cmake -S . -B build -DCMAKE_VERBOSE_MAKEFILE=ON

- name: CMake Build
shell: bash
run: |
cmake --build build -j$(nproc)
138 changes: 138 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
cmake_minimum_required(VERSION 3.18)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")

project(pybind11_protobuf)

if(MSVC)
set(CMAKE_CXX_STANDARD 20)
else()
set(CMAKE_CXX_STANDARD 17)
endif()
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

set(CMAKE_POSITION_INDEPENDENT_CODE ON)

# ============================================================================
# Options

option(BUILD_TESTS "Build tests." OFF)

# ============================================================================
# Find Python

find_package(Python COMPONENTS Interpreter Development)

# ============================================================================
# Build dependencies

set(_absl_repository "https://github.com/abseil/abseil-cpp.git")
set(_absl_version 20220623.1)
set(_absl_tag 20220623.1)

set(_protobuf_repository "https://github.com/protocolbuffers/protobuf.git")
set(_protobuf_version 21.5)
set(_protobuf_tag v21.5)

set(_pybind11_repository "https://github.com/pybind/pybind11.git")
set(_pybind11_version 2.10)
set(_pybind11_tag v2.10.1)

add_subdirectory(cmake/dependencies dependencies)

# ============================================================================
# pybind11_proto_utils pybind11 extension module
pybind11_add_module(
pybind11_proto_utils MODULE pybind11_protobuf/proto_utils.cc
pybind11_protobuf/proto_utils.h)

target_link_libraries(
pybind11_proto_utils PRIVATE absl::strings protobuf::libprotobuf
${Python_LIBRARIES})

target_include_directories(
pybind11_proto_utils PRIVATE ${PROJECT_SOURCE_DIR} ${protobuf_INCLUDE_DIRS}
${protobuf_SOURCE_DIR} ${pybind11_INCLUDE_DIRS})

# ============================================================================
# pybind11_native_proto_caster shared library
add_library(
pybind11_native_proto_caster SHARED
# bazel: pybind_library: native_proto_caster
pybind11_protobuf/native_proto_caster.h
# bazel: pybind_library: enum_type_caster
pybind11_protobuf/enum_type_caster.h
# bazel: pybind_library: proto_cast_util
pybind11_protobuf/proto_cast_util.cc
pybind11_protobuf/proto_cast_util.h
pybind11_protobuf/proto_caster_impl.h
# bazel: cc_library::check_unknown_fields
pybind11_protobuf/check_unknown_fields.cc
pybind11_protobuf/check_unknown_fields.h)

target_link_libraries(
pybind11_native_proto_caster
absl::flat_hash_map
absl::flat_hash_set
absl::hash
absl::strings
absl::optional
protobuf::libprotobuf
pybind11::pybind11
${Python_LIBRARIES})

target_include_directories(
pybind11_native_proto_caster
PRIVATE ${PROJECT_SOURCE_DIR} ${protobuf_INCLUDE_DIRS} ${protobuf_SOURCE_DIR}
${pybind11_INCLUDE_DIRS})

# ============================================================================
# pybind11_wrapped_proto_caster shared library
add_library(
pybind11_wrapped_proto_caster SHARED
# bazel: pybind_library: wrapped_proto_caster
pybind11_protobuf/wrapped_proto_caster.h
# bazel: pybind_library: proto_cast_util
pybind11_protobuf/proto_cast_util.cc
pybind11_protobuf/proto_cast_util.h
pybind11_protobuf/proto_caster_impl.h
# bazel: cc_library: check_unknown_fields
pybind11_protobuf/check_unknown_fields.cc
pybind11_protobuf/check_unknown_fields.h)

target_link_libraries(
pybind11_wrapped_proto_caster
absl::flat_hash_map
absl::flat_hash_set
absl::hash
absl::strings
absl::optional
protobuf::libprotobuf
pybind11::pybind11
${Python_LIBRARIES})

target_include_directories(
pybind11_wrapped_proto_caster
PRIVATE ${PROJECT_SOURCE_DIR} ${protobuf_INCLUDE_DIRS} ${protobuf_SOURCE_DIR}
${pybind11_INCLUDE_DIRS})

# TODO set defines PYBIND11_PROTOBUF_ENABLE_PYPROTO_API see: bazel:
# pybind_library: proto_cast_util

# bazel equivs. checklist
#
# bazel: pybind_library: enum_type_caster - enum_type_caster.h
#
# bazel: pybind_library: native_proto_caster - native_proto_caster.h
#
# check_unknown_fields enum_type_caster proto_cast_util
#
# bazel: pybind_library: proto_cast_util - proto_cast_util.cc -
# proto_cast_util.h - proto_caster_impl.h
#
# check_unknown_fields
#
# bazel: pybind_library: wrapped_proto_caster - wrapped_proto_caster.h
#
# proto_cast_util
#
64 changes: 64 additions & 0 deletions cmake/dependencies/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
include(FetchContent)

# ============================================================================
# Declare all dependencies first

find_package(absl ${_absl_version} EXACT QUIET)
if(NOT absl_FOUND)
set(ABSL_PROPAGATE_CXX_STD ON)
FetchContent_Declare(
absl
GIT_REPOSITORY ${_absl_repository}
GIT_TAG ${_absl_tag})
endif()

# https://stackoverflow.com/questions/63309544/cmake-protobuf-external-to-application-code
# https://cmake.org/cmake/help/latest/policy/CMP0077.html
# https://gitlab.kitware.com/cmake/cmake/-/merge_requests/7565/diffs
find_package(Protobuf ${_protobuf_version} EXACT QUIET)
if(NOT Protobuf_FOUND)
set(protobuf_BUILD_TESTS
OFF
CACHE INTERNAL "")
FetchContent_Declare(
Protobuf
GIT_REPOSITORY ${_protobuf_repository}
GIT_TAG ${_protobuf_tag}
GIT_SUBMODULES "")
endif()

find_package(pybind11 ${_pybind11_version} EXACT QUIET)
if(NOT pybind11_FOUND)
set(PYBIND11_TEST OFF)
FetchContent_Declare(
pybind11
GIT_REPOSITORY ${_pybind11_repository}
GIT_TAG ${_pybind11_tag})
endif()

# ============================================================================
# Make dependencies avaialble

if(NOT absl_FOUND)
message(CHECK_START "Fetching Abseil-cpp")
list(APPEND CMAKE_MESSAGE_INDENT " ")
FetchContent_MakeAvailable(absl)
list(POP_BACK CMAKE_MESSAGE_INDENT)
message(CHECK_PASS "fetched")
endif()

if(NOT Protobuf_FOUND)
message(CHECK_START "Fetching Protobuf")
list(APPEND CMAKE_MESSAGE_INDENT " ")
FetchContent_MakeAvailable(Protobuf)
list(POP_BACK CMAKE_MESSAGE_INDENT)
message(CHECK_PASS "fetched")
endif()

if(NOT pybind11_FOUND)
message(CHECK_START "Fetching pybind11")
list(APPEND CMAKE_MESSAGE_INDENT " ")
FetchContent_MakeAvailable(pybind11)
list(POP_BACK CMAKE_MESSAGE_INDENT)
message(CHECK_PASS "fetched")
endif()