forked from lanterndata/lantern
-
Notifications
You must be signed in to change notification settings - Fork 0
/
CMakeLists.txt
271 lines (220 loc) · 8.77 KB
/
CMakeLists.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
cmake_minimum_required(VERSION 3.3)
set(LANTERNDB_VERSION 0.0.4)
project(
LanternDB
VERSION ${LANTERNDB_VERSION}
LANGUAGES C CXX)
if (POLICY CMP0074)
# us <PackageName>_ROOT variables from inside find_package calls
cmake_policy(SET CMP0074 NEW)
endif()
if(POLICY CMP0077)
# Allow parent project to override options of children obtain via FetchContent
# or add_subdirectory.
cmake_policy(SET CMP0077 NEW)
endif()
# OPTIONS
option(DEV "Developer mode: provide code formatting, get postgres source, etc." OFF)
option(BUILD_WITH_USEARCH "Build with usearch as hnsw provider" ON)
option(BUILD_LIBHNSW "Build libhnsw as hnsw provider" OFF)
option(CODECOVERAGE "Enable code coverage for the build" OFF)
option(BENCH "Enable benchmarking" OFF)
if(CODECOVERAGE)
message(STATUS "Code coverage is enabled.")
# Note that --coverage is synonym for the necessary compiler and linker flags
# for the given compiler. For example, with GCC, --coverage translates to
# -fprofile-arcs -ftest-coverage when compiling and -lgcov when linking
add_compile_options(--coverage -O0)
# add NDEBUG to make sure asserts compile to a NOOP and do not negatively impact
# code coverage. Asserts check invariants but since 'assert' is defined as a macro-condition,
# codecov always considers it partially covered.
add_compile_definitions(NDEBUG)
add_link_options(--coverage)
endif(CODECOVERAGE)
if (BENCH)
message(STATUS "Benchmarking is enabled.")
add_compile_definitions(LANTERN_BENCH)
endif()
# options passed into lantern sourcecode
# todo:: tests for copynodes=ON are broken
option(LANTERNDB_COPYNODES "Copy postgres index tuples for external retriever during scan instead of pinning" OFF)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake)
message(STATUS "${CMAKE_COLOR_GREEN}Build type: ${CMAKE_BUILD_TYPE}${CMAKE_COLOR_RESET}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wno-conversion -Wno-unknown-pragmas")
find_package(PostgreSQL REQUIRED)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(SOURCES_DIR "src")
# todo:: list out all the files instead of glob
file(GLOB SOURCES "${SOURCES_DIR}/**/*.c" "${SOURCES_DIR}/*.c")
file(GLOB HEADER_FILES "${SOURCES_DIR}/**/*.h" "${SOURCES_DIR}/*.h")
set(USEARCH_USE_SIMSIMD OFF)
set(USEARCH_LOOKUP_LABEL OFF)
# we always use a usearch index from a single thread
set(USEARCH_CONCURRENT OFF)
set(USEARCH_BUILD_STATIC ON)
# do not add asan flags to usearch debug build of the library since
# we still have not figured out how to load those into postgres
set(USEARCH_DEBUG_BUILD_ASAN OFF)
# the var below can be used to skip -march=native in the usearch build
# which causes issues when built from docker on m1 macs
# set(USEARCH_NO_MARCH_NATIVE OFF)
set(USEARCH_BUILD_TEST OFF)
set(USEARCH_BUILD_BENCHMARK OFF)
add_subdirectory("./third_party/usearch/c")
string(REGEX MATCH "^PostgreSQL (\[0-9]+).*"
PostgreSQL_VERSION_NUMBER ${PostgreSQL_VERSION_STRING})
set(PG_VERSION ${CMAKE_MATCH_1})
# For Apple and Postgres 16 use .dylib instead of .so
if (APPLE AND PG_VERSION VERSION_GREATER_EQUAL "16")
set(CMAKE_SHARED_MODULE_SUFFIX ".dylib")
endif()
# ADD LanternDB! Let there be light!
add_library(lantern MODULE ${SOURCES})
# Add postgres extension packaging rules
target_include_directories(
lantern
SYSTEM PRIVATE ${PostgreSQL_SERVER_INCLUDE_DIRS}
PUBLIC ${CMAKE_SOURCE_DIR}/src
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
set(_link_flags "${PostgreSQL_SHARED_LINK_OPTIONS}")
foreach(_dir ${PostgreSQL_SERVER_LIBRARY_DIRS})
set(_link_flags "${_link_flags} -L${_dir}")
endforeach()
if(APPLE)
set(_link_flags "${_link_flags} -bundle_loader ${PG_BINARY} -undefined dynamic_lookup")
endif()
set_target_properties(
lantern
PROPERTIES PREFIX ""
LINK_FLAGS "${_link_flags}"
POSITION_INDEPENDENT_CODE ON)
# THIRD PARTY LIBRARIES
# needed to make sure cmake does not add libstdc++ to the linker command when an
# external cpp library is added more at`
# https://cmake-developers.cmake.narkive.com/JnbrDyGT/setting-linker-language-still-adds-lstdc
if(NOT APPLE)
# apples does not understand -static-libstdc++ used in usearch to bundle libstdc++ with the
# created archive.
# so, on apple we dynamically link to the c++ runtime
# todo:: find a way to statically link the c++ runtime on mac
set(CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "")
set(CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES "")
endif()
set_target_properties(lantern PROPERTIES LINKER_LANGUAGE C)
target_include_directories(lantern PRIVATE "./third_party/usearch/c")
target_link_directories(lantern PRIVATE "./src")
if (${BUILD_WITH_USEARCH})
target_link_libraries(lantern PRIVATE usearch_c)
target_compile_definitions(lantern PRIVATE LANTERN_USE_USEARCH)
endif()
if (${BUILD_WITH_LIBHNSW})
target_link_libraries(lantern PRIVATE hnsw)
target_compile_definitions(lantern PRIVATE LANTERN_USE_LIBHNSW)
endif()
if (${LANTERNDB_COPYNODES})
target_compile_definitions(lantern PRIVATE LANTERNDB_COPYNODES)
endif()
set(_script_file "lantern--${LANTERNDB_VERSION}.sql")
set (_update_files
sql/updates/0.0.1--0.0.2.sql
sql/updates/0.0.2--0.0.3.sql)
add_custom_command(
OUTPUT ${CMAKE_BINARY_DIR}/${_script_file}
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/sql/lantern.sql ${CMAKE_BINARY_DIR}/${_script_file}
DEPENDS ${CMAKE_SOURCE_DIR}/sql/lantern.sql
COMMENT "Copying lantern.sql into a versioned filename"
)
add_custom_target(phony_always_runs ALL DEPENDS ${CMAKE_BINARY_DIR}/${_script_file})
# AUTO-GENERATE lantern.control file for PostgreSQL
set(CONTROL_TEMPLATE "${CMAKE_MODULE_PATH}/lantern.control.template")
set(CONTROL_OUTPUT "${CMAKE_BINARY_DIR}/lantern.control")
configure_file(${CONTROL_TEMPLATE} ${CONTROL_OUTPUT})
# INSTALL
install(TARGETS lantern LIBRARY DESTINATION ${PostgreSQL_PACKAGE_LIBRARY_DIR})
install(FILES ${CONTROL_OUTPUT} ${CMAKE_BINARY_DIR}/${_script_file}
DESTINATION ${PostgreSQL_EXTENSION_DIR})
foreach(_update_file ${_update_files})
get_filename_component(_update_file_name ${_update_file} NAME)
install(FILES ${_update_file} DESTINATION ${PostgreSQL_EXTENSION_DIR} RENAME "lantern--${_update_file_name}")
endforeach()
# todo:: add llvm bytecode generation for postgres optimizations (see how the
# canonical extension building infra extension does it)
# UNINSTALL
add_custom_target(
uninstall
COMMAND ${CMAKE_COMMAND} -E remove -f
${PostgreSQL_EXTENSION_DIR}/${CONTROL_OUTPUT}
COMMAND ${CMAKE_COMMAND} -E remove -f
${PostgreSQL_EXTENSION_DIR}/${_script_file}
COMMAND ${CMAKE_COMMAND} -E remove -f
${PostgreSQL_PACKAGE_LIBRARY_DIR}/lantern.so)
# TEST
add_custom_target(
test
COMMAND ${CMAKE_SOURCE_DIR}/scripts/run_all_tests.sh
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/test
)
# BENCHMARK
add_custom_target(
benchmark
COMMAND ${CMAKE_SOURCE_DIR}/scripts/run_benchmarks.sh
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/build
)
add_custom_target(
benchmark-skip-setup
COMMAND ${CMAKE_SOURCE_DIR}/scripts/run_benchmarks.sh --skip-setup
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/build
)
add_custom_target(
benchmark-print-only
COMMAND ${CMAKE_SOURCE_DIR}/scripts/run_benchmarks.sh --print-only
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/build
)
# DEVELOPMENT
find_program(CLANG_FORMAT NAMES clang-format)
if (CLANG_FORMAT)
execute_process(COMMAND ${CLANG_FORMAT} --version
OUTPUT_VARIABLE CLANG_FORMAT_VERSION
OUTPUT_STRIP_TRAILING_WHITESPACE)
string(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+" CLANG_FORMAT_VERSION "${CLANG_FORMAT_VERSION}")
if(CLANG_FORMAT_VERSION VERSION_LESS 14)
message(WARNING "clang-format version ${CLANG_FORMAT_VERSION} found, need at least 14")
set(CLANG_FORMAT OFF)
endif()
endif()
if(DEV AND NOT CLANG_FORMAT)
message(FATAL_ERROR "clang-format not found!")
endif()
if (CLANG_FORMAT)
set(CLANG_FORMATTABLE_FILES ${SOURCES})
list(APPEND CLANG_FORMATTABLE_FILES ${HEADER_FILES})
# Add format target
add_custom_target(
format
COMMAND ${CLANG_FORMAT} -i ${CLANG_FORMATTABLE_FILES}
COMMENT "Formatting code with clang-format"
VERBATIM
)
# Add format check target
add_custom_target(
format_check
COMMAND ${CLANG_FORMAT} --dry-run -Werror ${CLANG_FORMATTABLE_FILES}
COMMENT "Checking code formatting with clang-format"
VERBATIM
)
endif()
# Package universal install script
add_custom_target(
archive
${CMAKE_COMMAND} -E env SOURCE_DIR=${CMAKE_SOURCE_DIR} BUILD_DIR=${CMAKE_BINARY_DIR} PG_VERSION=${PG_VERSION} ${CMAKE_SOURCE_DIR}/scripts/package.sh
DEPENDS ${CMAKE_BINARY_DIR}/${_script_file}
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
)
add_dependencies(archive lantern)
# Debian packaging
set(CPACK_GENERATOR "DEB")
set(CPACK_DEBIAN_PACKAGE_DEPENDS "postgresql-${PG_VERSION}, postgresql-${PG_VERSION}-pgvector")
set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Lantern Data")
include(CPack)