Skip to content

Commit 4b1a090

Browse files
committed
feat: build: Add cmake as a build option.
Bazel does not support compile_commands.json which makes development very cumbersome. To remove cmake as a build option is trivial: Simply delete the cmake configs and the notices in the *.bzl about them being generate by cmake. Also fix a typo on the README and make lint happy by renaming limits.h into something else that does not possibly clash with system headers.
1 parent ed6f851 commit 4b1a090

29 files changed

+3555
-6
lines changed

CMakeLists.txt

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
# ~~~
2+
# Copyright 2025 Google LLC
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# https://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
# ~~~
16+
17+
cmake_minimum_required(VERSION 3.13...3.24)
18+
19+
# Define the project name and where to report bugs.
20+
set(PACKAGE_BUGREPORT "https://github.com/googleapis/google-cloud-cpp/issues")
21+
22+
project(
23+
bigtable-emulator
24+
VERSION 1.0.0
25+
LANGUAGES CXX)
26+
set(PROJECT_VERSION_PRE_RELEASE "rc")
27+
28+
if (NOT "${PROJECT_VERSION_PRE_RELEASE}" STREQUAL "")
29+
set(PROJECT_VERSION "${PROJECT_VERSION}-${PROJECT_VERSION_PRE_RELEASE}")
30+
endif ()
31+
32+
# Automatically update the version(s) in the `MODULE.bazel` file.
33+
file(READ "MODULE.bazel" module_contents)
34+
string(
35+
REGEX
36+
REPLACE "version = \".*\", # Updated by CMake"
37+
"version = \"${PROJECT_VERSION}\", # Updated by CMake"
38+
updated_contents "${module_contents}")
39+
string(
40+
REGEX
41+
REPLACE
42+
"compatibility_level = .*, # Updated by CMake"
43+
"compatibility_level = ${PROJECT_VERSION_MAJOR}, # Updated by CMake"
44+
updated_contents "${updated_contents}")
45+
if (NOT ("${updated_contents}" STREQUAL "${module_contents}"))
46+
# Rewrite the file *only* if it was updated.
47+
file(WRITE "MODULE.bazel" "${updated_contents}")
48+
endif ()
49+
50+
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
51+
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.5)
52+
message(
53+
WARNING "The `google-cloud-cpp` library is tested with GCC >= 7.5."
54+
" We will consider patches for older versions.")
55+
endif ()
56+
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
57+
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 6.0)
58+
message(
59+
WARNING
60+
"The `google-cloud-cpp` library is tested with Clang >= 6.0."
61+
" We will consider patches for older versions.")
62+
endif ()
63+
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
64+
if (CMAKE_VERSION VERSION_LESS 3.15)
65+
message(
66+
FATAL_ERROR
67+
"MSVC builds require CMake >= 3.15."
68+
" Previous versions of CMake lack a standard mechanism to"
69+
" select the runtime C++ library.")
70+
endif ()
71+
endif ()
72+
73+
list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
74+
75+
include(FetchContent)
76+
77+
FetchContent_Declare(
78+
google-cloud-cpp
79+
URL https://github.com/googleapis/google-cloud-cpp/archive/refs/tags/v2.39.0.tar.gz
80+
)
81+
82+
FetchContent_MakeAvailable(google-cloud-cpp)
83+
84+
add_library(
85+
bigtable_emulator_common # cmake-format: sort
86+
cell_view.h
87+
cluster.cc
88+
cluster.h
89+
column_family.cc
90+
column_family.h
91+
filter.cc
92+
filter.h
93+
filtered_map.h
94+
bigtable_limits.h
95+
range_set.cc
96+
range_set.h
97+
row_streamer.cc
98+
row_streamer.h
99+
server.cc
100+
server.h
101+
table.cc
102+
table.h
103+
test_util.cc
104+
test_util.h
105+
to_grpc_status.cc
106+
to_grpc_status.h)
107+
108+
target_link_libraries(
109+
bigtable_emulator_common
110+
google-cloud-cpp::bigtable
111+
google-cloud-cpp::bigtable_protos
112+
google-cloud-cpp::common
113+
google-cloud-cpp::grpc_utils)
114+
115+
google_cloud_cpp_add_common_options(bigtable_emulator_common)
116+
117+
include(CreateBazelConfig)
118+
create_bazel_config(bigtable_emulator_common YEAR 2024)
119+
120+
include(CTest)
121+
122+
if (BUILD_TESTING)
123+
# List the unit tests, then setup the targets and dependencies.
124+
set(bigtable_emulator_unit_tests
125+
# cmake-format: sort
126+
column_family_test.cc
127+
conditional_mutations_test.cc
128+
drop_row_range_test.cc
129+
filter_test.cc
130+
filtered_map_test.cc
131+
mutations_test.cc
132+
range_set_test.cc
133+
server_test.cc
134+
table_test.cc)
135+
export_list_to_bazel("bigtable_emulator_unit_tests.bzl"
136+
"bigtable_emulator_unit_tests" YEAR "2024")
137+
138+
foreach (fname ${bigtable_emulator_unit_tests})
139+
google_cloud_cpp_add_executable(target "bigtable_emulator" "${fname}")
140+
target_link_libraries(
141+
${target}
142+
PRIVATE bigtable_emulator_common
143+
bigtable_client_testing
144+
google_cloud_cpp_testing
145+
google_cloud_cpp_testing_grpc
146+
google-cloud-cpp::bigtable
147+
google-cloud-cpp::bigtable_protos
148+
google-cloud-cpp::common
149+
google-cloud-cpp::grpc_utils)
150+
google_cloud_cpp_add_common_options(${target})
151+
add_test(NAME ${target} COMMAND ${target})
152+
endforeach ()
153+
endif ()
154+
155+
find_package(absl CONFIG REQUIRED)
156+
157+
set(bigtable_emulator_programs # cmake-format: sort
158+
emulator.cc)
159+
export_list_to_bazel("bigtable_emulator_programs.bzl"
160+
"bigtable_emulator_programs" YEAR "2024")
161+
162+
foreach (fname ${bigtable_emulator_programs})
163+
google_cloud_cpp_add_executable(target "bigtable" "${fname}")
164+
target_link_libraries(
165+
${target}
166+
PRIVATE bigtable_emulator_common
167+
absl::flags
168+
absl::flags_parse
169+
google-cloud-cpp::bigtable
170+
google-cloud-cpp::bigtable_protos
171+
google-cloud-cpp::common
172+
google-cloud-cpp::grpc_utils
173+
google_cloud_cpp_testing)
174+
google_cloud_cpp_add_common_options(${target})
175+
endforeach ()

README.md

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,59 @@
1-
# Single node, Memory Only Emulator for Google Bigtable
1+
# Single Node, Memory Only Emulator for Google Bigtable
22

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

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

9+
## Dependencies
10+
11+
The Bigtable-emulator depends on `google-cloud-cpp` (which the build
12+
tools retrieve and build automatically) and the `abseil`
13+
library. Other dependencies such as `GRPC` are provided by
14+
`google-cloud-cpp`.
15+
916
## Building
1017

11-
Building the Bigtable emulator requires `bazel`.
18+
The Bigtable emulator can be built with `bazel` or `cmake`.
19+
20+
The `cmake` build can be used to produce a `compile_commands.json`
21+
which can be used with most IDEs and modern language servers
22+
(e.g. `clang`) to provide code completion and much more.
23+
24+
### Bazel
1225

1326
```shell
1427
cd bigtable-emulator
1528
bazel build ...
1629
```
17-
## Running the Unit Tests
30+
#### Running the Unit Tests With Bazel
1831

1932
```shell
2033
bazel test ...
2134
```
2235

23-
### Running the Emulator
36+
### Cmake
37+
38+
The following cmake command will produce a development build that can
39+
be debugged and that produces a `compile_commands.json` in the
40+
`build/` directory that you can symlink to the root directory to get
41+
completion and many other modern features from `clangd` and other
42+
similar tools.
43+
44+
```shell
45+
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
46+
47+
make -j
48+
```
49+
50+
#### Running the Unit Tests With Cmake
51+
52+
```shell
53+
make test
54+
```
55+
56+
## Running the Emulator
2457

2558
```shell
2659
bigtable-emulator -p <port>

bigtable_emulator_common.bzl

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,17 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414
#
15+
# DO NOT EDIT -- GENERATED BY CMake -- Change the CMakeLists.txt file if needed
16+
17+
"""Automatically generated source lists for bigtable_emulator_common - DO NOT EDIT."""
1518

1619
bigtable_emulator_common_hdrs = [
1720
"cell_view.h",
1821
"cluster.h",
1922
"column_family.h",
2023
"filter.h",
2124
"filtered_map.h",
22-
"limits.h",
25+
"bigtable_limits.h",
2326
"range_set.h",
2427
"row_streamer.h",
2528
"server.h",

bigtable_emulator_programs.bzl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414
#
15+
# DO NOT EDIT -- GENERATED BY CMake -- Change the CMakeLists.txt file if needed
16+
17+
"""Automatically generated unit tests list - DO NOT EDIT."""
1518

1619
bigtable_emulator_programs = [
1720
"emulator.cc",

bigtable_emulator_unit_tests.bzl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@
1111
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
14+
#
15+
# DO NOT EDIT -- GENERATED BY CMake -- Change the CMakeLists.txt file if needed
16+
17+
"""Automatically generated unit tests list - DO NOT EDIT."""
1418

1519
bigtable_emulator_unit_tests = [
1620
"column_family_test.cc",
File renamed without changes.

cmake/AddPkgConfig.cmake

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
# ~~~
2+
# Copyright 2022 Google LLC
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# https://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
# ~~~
16+
17+
# We do not use macros a lot, so this deserves a comment. Unlike functions,
18+
# macros do not introduce a scope. This is an advantage when trying to set
19+
# global variables, as we do here. It is obviously a disadvantage if you need
20+
# local variables.
21+
macro (google_cloud_cpp_set_pkgconfig_paths)
22+
if (IS_ABSOLUTE "${CMAKE_INSTALL_LIBDIR}")
23+
set(GOOGLE_CLOUD_CPP_PC_LIBDIR "${CMAKE_INSTALL_LIBDIR}")
24+
else ()
25+
set(GOOGLE_CLOUD_CPP_PC_LIBDIR
26+
"\${exec_prefix}/${CMAKE_INSTALL_LIBDIR}")
27+
endif ()
28+
29+
if (IS_ABSOLUTE "${CMAKE_INSTALL_INCLUDEDIR}")
30+
set(GOOGLE_CLOUD_CPP_PC_INCLUDEDIR "${CMAKE_INSTALL_INCLUDEDIR}")
31+
else ()
32+
set(GOOGLE_CLOUD_CPP_PC_INCLUDEDIR
33+
"\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}")
34+
endif ()
35+
endmacro ()
36+
37+
#
38+
# Create the pkgconfig configuration file (aka *.pc file) and the rules to
39+
# install it.
40+
#
41+
# * library: the name of the library, such as `storage`, or `spanner`
42+
# * ARGN: the names of any pkgconfig modules the generated module depends on
43+
#
44+
function (google_cloud_cpp_add_pkgconfig library name description)
45+
cmake_parse_arguments(
46+
_opt "WITH_SHORT_TARGET" ""
47+
"LIBS;WIN32_LIBS;NON_WIN32_LIBS;WIN32_REQUIRES;NON_WIN32_REQUIRES"
48+
${ARGN})
49+
if (_opt_WITH_SHORT_TARGET)
50+
set(target "${library}")
51+
else ()
52+
set(target "google_cloud_cpp_${library}")
53+
endif ()
54+
set(GOOGLE_CLOUD_CPP_PC_NAME "${name}")
55+
set(GOOGLE_CLOUD_CPP_PC_DESCRIPTION "${description}")
56+
string(JOIN " " GOOGLE_CLOUD_CPP_PC_REQUIRES ${_opt_UNPARSED_ARGUMENTS})
57+
google_cloud_cpp_set_pkgconfig_paths()
58+
get_target_property(target_type ${target} TYPE)
59+
if ("${target_type}" STREQUAL "INTERFACE_LIBRARY")
60+
# Interface libraries only contain headers. They do not generate lib
61+
# files to link against with `-l`.
62+
set(GOOGLE_CLOUD_CPP_PC_LIBS "")
63+
else ()
64+
set(GOOGLE_CLOUD_CPP_PC_LIBS "-lgoogle_cloud_cpp_${library}")
65+
endif ()
66+
list(TRANSFORM _opt_LIBS PREPEND "-l" OUTPUT_VARIABLE _opt_LIBS)
67+
string(JOIN " " GOOGLE_CLOUD_CPP_PC_LIBS "${GOOGLE_CLOUD_CPP_PC_LIBS}"
68+
${_opt_LIBS})
69+
if (WIN32)
70+
list(TRANSFORM _opt_WIN32_LIBS PREPEND "-l" OUTPUT_VARIABLE
71+
_opt_WIN32_LIBS)
72+
string(JOIN " " GOOGLE_CLOUD_CPP_PC_LIBS "${GOOGLE_CLOUD_CPP_PC_LIBS}"
73+
${_opt_WIN32_LIBS})
74+
string(JOIN " " GOOGLE_CLOUD_CPP_PC_REQUIRES
75+
"${GOOGLE_CLOUD_CPP_PC_REQUIRES}" ${_opt_WIN32_REQUIRES})
76+
else ()
77+
list(TRANSFORM _opt_NON_WIN32_LIBS PREPEND "-l" OUTPUT_VARIABLE
78+
_opt_NON_WIN32_LIBS)
79+
string(JOIN " " GOOGLE_CLOUD_CPP_PC_LIBS "${GOOGLE_CLOUD_CPP_PC_LIBS}"
80+
${_opt_NON_WIN32_LIBS})
81+
string(JOIN " " GOOGLE_CLOUD_CPP_PC_REQUIRES
82+
"${GOOGLE_CLOUD_CPP_PC_REQUIRES}" ${_opt_NON_WIN32_REQUIRES})
83+
endif ()
84+
get_target_property(target_defs ${target} INTERFACE_COMPILE_DEFINITIONS)
85+
if (target_defs)
86+
foreach (def ${target_defs})
87+
string(APPEND GOOGLE_CLOUD_CPP_PC_CFLAGS " -D${def}")
88+
endforeach ()
89+
endif ()
90+
91+
# Create and install the pkg-config files.
92+
configure_file("${PROJECT_SOURCE_DIR}/cmake/templates/config.pc.in"
93+
"google_cloud_cpp_${library}.pc" @ONLY)
94+
install(
95+
FILES "${CMAKE_CURRENT_BINARY_DIR}/google_cloud_cpp_${library}.pc"
96+
DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig"
97+
COMPONENT google_cloud_cpp_development)
98+
endfunction ()

0 commit comments

Comments
 (0)