Skip to content
Open
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
175 changes: 175 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
# ~~~
# Copyright 2025 Google LLC
#
# 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
#
# https://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_minimum_required(VERSION 3.13...3.24)

# Define the project name and where to report bugs.
set(PACKAGE_BUGREPORT "https://github.com/googleapis/google-cloud-cpp/issues")

project(
bigtable-emulator
VERSION 1.0.0
LANGUAGES CXX)
set(PROJECT_VERSION_PRE_RELEASE "rc")

if (NOT "${PROJECT_VERSION_PRE_RELEASE}" STREQUAL "")
set(PROJECT_VERSION "${PROJECT_VERSION}-${PROJECT_VERSION_PRE_RELEASE}")
endif ()

# Automatically update the version(s) in the `MODULE.bazel` file.
file(READ "MODULE.bazel" module_contents)
string(
REGEX
REPLACE "version = \".*\", # Updated by CMake"
"version = \"${PROJECT_VERSION}\", # Updated by CMake"
updated_contents "${module_contents}")
string(
REGEX
REPLACE
"compatibility_level = .*, # Updated by CMake"
"compatibility_level = ${PROJECT_VERSION_MAJOR}, # Updated by CMake"
updated_contents "${updated_contents}")
if (NOT ("${updated_contents}" STREQUAL "${module_contents}"))
# Rewrite the file *only* if it was updated.
file(WRITE "MODULE.bazel" "${updated_contents}")
endif ()

if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.5)
message(
WARNING "The `google-cloud-cpp` library is tested with GCC >= 7.5."
" We will consider patches for older versions.")
endif ()
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 6.0)
message(
WARNING
"The `google-cloud-cpp` library is tested with Clang >= 6.0."
" We will consider patches for older versions.")
endif ()
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
if (CMAKE_VERSION VERSION_LESS 3.15)
message(
FATAL_ERROR
"MSVC builds require CMake >= 3.15."
" Previous versions of CMake lack a standard mechanism to"
" select the runtime C++ library.")
endif ()
endif ()

list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)

include(FetchContent)

FetchContent_Declare(
google-cloud-cpp
URL https://github.com/googleapis/google-cloud-cpp/archive/refs/tags/v2.39.0.tar.gz
)

FetchContent_MakeAvailable(google-cloud-cpp)

add_library(
bigtable_emulator_common # cmake-format: sort
cell_view.h
cluster.cc
cluster.h
column_family.cc
column_family.h
filter.cc
filter.h
filtered_map.h
bigtable_limits.h
range_set.cc
range_set.h
row_streamer.cc
row_streamer.h
server.cc
server.h
table.cc
table.h
test_util.cc
test_util.h
to_grpc_status.cc
to_grpc_status.h)

target_link_libraries(
bigtable_emulator_common
google-cloud-cpp::bigtable
google-cloud-cpp::bigtable_protos
google-cloud-cpp::common
google-cloud-cpp::grpc_utils)

google_cloud_cpp_add_common_options(bigtable_emulator_common)

include(CreateBazelConfig)
create_bazel_config(bigtable_emulator_common YEAR 2024)

include(CTest)

if (BUILD_TESTING)
# List the unit tests, then setup the targets and dependencies.
set(bigtable_emulator_unit_tests
# cmake-format: sort
column_family_test.cc
conditional_mutations_test.cc
drop_row_range_test.cc
filter_test.cc
filtered_map_test.cc
mutations_test.cc
range_set_test.cc
server_test.cc
table_test.cc)
export_list_to_bazel("bigtable_emulator_unit_tests.bzl"
"bigtable_emulator_unit_tests" YEAR "2024")

foreach (fname ${bigtable_emulator_unit_tests})
google_cloud_cpp_add_executable(target "bigtable_emulator" "${fname}")
target_link_libraries(
${target}
PRIVATE bigtable_emulator_common
bigtable_client_testing
google_cloud_cpp_testing
google_cloud_cpp_testing_grpc
google-cloud-cpp::bigtable
google-cloud-cpp::bigtable_protos
google-cloud-cpp::common
google-cloud-cpp::grpc_utils)
google_cloud_cpp_add_common_options(${target})
add_test(NAME ${target} COMMAND ${target})
endforeach ()
endif ()

find_package(absl CONFIG REQUIRED)

set(bigtable_emulator_programs # cmake-format: sort
emulator.cc)
export_list_to_bazel("bigtable_emulator_programs.bzl"
"bigtable_emulator_programs" YEAR "2024")

foreach (fname ${bigtable_emulator_programs})
google_cloud_cpp_add_executable(target "bigtable" "${fname}")
target_link_libraries(
${target}
PRIVATE bigtable_emulator_common
absl::flags
absl::flags_parse
google-cloud-cpp::bigtable
google-cloud-cpp::bigtable_protos
google-cloud-cpp::common
google-cloud-cpp::grpc_utils
google_cloud_cpp_testing)
google_cloud_cpp_add_common_options(${target})
endforeach ()
41 changes: 37 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,26 +1,59 @@
# Single node, Memory Only Emulator for Google Bigtable
# Single Node, Memory Only Emulator for Google Bigtable

This is a single-node, non-persistent emulator for Google's Bigtable.

It should pass all the integration tests in Google's C++ client
repository (google-cloud-cpp), except those that must run against
production Bigtable.

## Dependencies

The Bigtable-emulator depends on `google-cloud-cpp` (which the build
tools retrieve and build automatically) and the `abseil`
library. Other dependencies such as `GRPC` are provided by
`google-cloud-cpp`.

## Building

Building the Bigtable emulator requires `bazel`.
The Bigtable emulator can be built with `bazel` or `cmake`.

The `cmake` build can be used to produce a `compile_commands.json`
which can be used with most IDEs and modern language servers
(e.g. `clang`) to provide code completion and much more.

### Bazel

```shell
cd bigtable-emulator
bazel build ...
```
## Running the Unit Tests
#### Running the Unit Tests With Bazel

```shell
bazel test ...
```

### Running the Emulator
### Cmake

The following cmake command will produce a development build that can
be debugged and that produces a `compile_commands.json` in the
`build/` directory that you can symlink to the root directory to get
completion and many other modern features from `clangd` and other
similar tools.

```shell
CXX=g++ CC=gcc CFLAGS="-g3 -O0" CXXFLAGS="-std=c++14 -pedantic -pedantic-errors -g3 -O0" CMAKE_CXX_FLAGS_DEBUG="-std=c++14 -g3 -O0 -ggdb" cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=1 -DCMAKE_BUILD_TYPE=Debug -H. -DGOOGLE_CLOUD_CPP_ENABLE=bigtable -Bbuild

make -j
```

#### Running the Unit Tests With Cmake

```shell
make test
```

## Running the Emulator

```shell
bigtable-emulator -p <port>
Expand Down
5 changes: 4 additions & 1 deletion bigtable_emulator_common.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,17 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
# DO NOT EDIT -- GENERATED BY CMake -- Change the CMakeLists.txt file if needed

"""Automatically generated source lists for bigtable_emulator_common - DO NOT EDIT."""

bigtable_emulator_common_hdrs = [
"cell_view.h",
"cluster.h",
"column_family.h",
"filter.h",
"filtered_map.h",
"limits.h",
"bigtable_limits.h",
"range_set.h",
"row_streamer.h",
"server.h",
Expand Down
3 changes: 3 additions & 0 deletions bigtable_emulator_programs.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
# DO NOT EDIT -- GENERATED BY CMake -- Change the CMakeLists.txt file if needed

"""Automatically generated unit tests list - DO NOT EDIT."""

bigtable_emulator_programs = [
"emulator.cc",
Expand Down
4 changes: 4 additions & 0 deletions bigtable_emulator_unit_tests.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
# 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.
#
# DO NOT EDIT -- GENERATED BY CMake -- Change the CMakeLists.txt file if needed

"""Automatically generated unit tests list - DO NOT EDIT."""

bigtable_emulator_unit_tests = [
"column_family_test.cc",
Expand Down
File renamed without changes.
98 changes: 98 additions & 0 deletions cmake/AddPkgConfig.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# ~~~
# Copyright 2022 Google LLC
#
# 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
#
# https://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.
# ~~~

# We do not use macros a lot, so this deserves a comment. Unlike functions,
# macros do not introduce a scope. This is an advantage when trying to set
# global variables, as we do here. It is obviously a disadvantage if you need
# local variables.
macro (google_cloud_cpp_set_pkgconfig_paths)
if (IS_ABSOLUTE "${CMAKE_INSTALL_LIBDIR}")
set(GOOGLE_CLOUD_CPP_PC_LIBDIR "${CMAKE_INSTALL_LIBDIR}")
else ()
set(GOOGLE_CLOUD_CPP_PC_LIBDIR
"\${exec_prefix}/${CMAKE_INSTALL_LIBDIR}")
endif ()

if (IS_ABSOLUTE "${CMAKE_INSTALL_INCLUDEDIR}")
set(GOOGLE_CLOUD_CPP_PC_INCLUDEDIR "${CMAKE_INSTALL_INCLUDEDIR}")
else ()
set(GOOGLE_CLOUD_CPP_PC_INCLUDEDIR
"\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}")
endif ()
endmacro ()

#
# Create the pkgconfig configuration file (aka *.pc file) and the rules to
# install it.
#
# * library: the name of the library, such as `storage`, or `spanner`
# * ARGN: the names of any pkgconfig modules the generated module depends on
#
function (google_cloud_cpp_add_pkgconfig library name description)
cmake_parse_arguments(
_opt "WITH_SHORT_TARGET" ""
"LIBS;WIN32_LIBS;NON_WIN32_LIBS;WIN32_REQUIRES;NON_WIN32_REQUIRES"
${ARGN})
if (_opt_WITH_SHORT_TARGET)
set(target "${library}")
else ()
set(target "google_cloud_cpp_${library}")
endif ()
set(GOOGLE_CLOUD_CPP_PC_NAME "${name}")
set(GOOGLE_CLOUD_CPP_PC_DESCRIPTION "${description}")
string(JOIN " " GOOGLE_CLOUD_CPP_PC_REQUIRES ${_opt_UNPARSED_ARGUMENTS})
google_cloud_cpp_set_pkgconfig_paths()
get_target_property(target_type ${target} TYPE)
if ("${target_type}" STREQUAL "INTERFACE_LIBRARY")
# Interface libraries only contain headers. They do not generate lib
# files to link against with `-l`.
set(GOOGLE_CLOUD_CPP_PC_LIBS "")
else ()
set(GOOGLE_CLOUD_CPP_PC_LIBS "-lgoogle_cloud_cpp_${library}")
endif ()
list(TRANSFORM _opt_LIBS PREPEND "-l" OUTPUT_VARIABLE _opt_LIBS)
string(JOIN " " GOOGLE_CLOUD_CPP_PC_LIBS "${GOOGLE_CLOUD_CPP_PC_LIBS}"
${_opt_LIBS})
if (WIN32)
list(TRANSFORM _opt_WIN32_LIBS PREPEND "-l" OUTPUT_VARIABLE
_opt_WIN32_LIBS)
string(JOIN " " GOOGLE_CLOUD_CPP_PC_LIBS "${GOOGLE_CLOUD_CPP_PC_LIBS}"
${_opt_WIN32_LIBS})
string(JOIN " " GOOGLE_CLOUD_CPP_PC_REQUIRES
"${GOOGLE_CLOUD_CPP_PC_REQUIRES}" ${_opt_WIN32_REQUIRES})
else ()
list(TRANSFORM _opt_NON_WIN32_LIBS PREPEND "-l" OUTPUT_VARIABLE
_opt_NON_WIN32_LIBS)
string(JOIN " " GOOGLE_CLOUD_CPP_PC_LIBS "${GOOGLE_CLOUD_CPP_PC_LIBS}"
${_opt_NON_WIN32_LIBS})
string(JOIN " " GOOGLE_CLOUD_CPP_PC_REQUIRES
"${GOOGLE_CLOUD_CPP_PC_REQUIRES}" ${_opt_NON_WIN32_REQUIRES})
endif ()
get_target_property(target_defs ${target} INTERFACE_COMPILE_DEFINITIONS)
if (target_defs)
foreach (def ${target_defs})
string(APPEND GOOGLE_CLOUD_CPP_PC_CFLAGS " -D${def}")
endforeach ()
endif ()

# Create and install the pkg-config files.
configure_file("${PROJECT_SOURCE_DIR}/cmake/templates/config.pc.in"
"google_cloud_cpp_${library}.pc" @ONLY)
install(
FILES "${CMAKE_CURRENT_BINARY_DIR}/google_cloud_cpp_${library}.pc"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig"
COMPONENT google_cloud_cpp_development)
endfunction ()
Loading