This repository was archived by the owner on Mar 26, 2026. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCMakeLists.txt
More file actions
268 lines (236 loc) · 9.44 KB
/
CMakeLists.txt
File metadata and controls
268 lines (236 loc) · 9.44 KB
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
cmake_minimum_required(VERSION 3.21)
cmake_policy(SET CMP0048 NEW)
project(libsqlglot VERSION 0.4.1 LANGUAGES CXX)
# Generate version header
configure_file(
"${CMAKE_SOURCE_DIR}/include/libsqlglot/version.h.in"
"${CMAKE_BINARY_DIR}/include/libsqlglot/version.h"
@ONLY
)
include(CheckCXXCompilerFlag)
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
add_compile_options(-std=c++26)
set(CMAKE_REQUIRED_FLAGS "-std=c++26")
check_cxx_compiler_flag(-freflection HAVE_FREFLECTION)
if(NOT HAVE_FREFLECTION)
message(FATAL_ERROR "GCC ${CMAKE_CXX_COMPILER_VERSION} does not support -freflection (C++26 reflection). Need GCC 15+")
endif()
add_compile_options(-freflection)
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
add_compile_options(-std=c++26)
set(CMAKE_REQUIRED_FLAGS "-std=c++26")
check_cxx_compiler_flag(-freflection HAVE_FREFLECTION)
if(NOT HAVE_FREFLECTION)
message(FATAL_ERROR "Clang ${CMAKE_CXX_COMPILER_VERSION} does not support -freflection (C++26 reflection). Need Clang 18+")
endif()
add_compile_options(-freflection)
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
add_compile_options(/std:c++26)
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "19.40")
message(FATAL_ERROR "MSVC 19.40+ required for C++26 reflection (found ${CMAKE_CXX_COMPILER_VERSION})")
endif()
else()
message(FATAL_ERROR "Unknown compiler ${CMAKE_CXX_COMPILER_ID}. Supported: GCC 15+, Clang 18+, MSVC 19.40+")
endif()
message(STATUS "C++26 reflection enabled - keywords auto-generated from TokenType enum")
message(STATUS "Compiler: ${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}")
# Options
option(LIBSQLGLOT_BUILD_TESTS "Build tests" ON)
option(LIBSQLGLOT_BUILD_BENCHMARKS "Build benchmarks" OFF)
option(LIBSQLGLOT_BUILD_PYTHON "Build Python bindings" OFF)
option(LIBSQLGLOT_BUILD_SHARED "Build shared library" ON)
option(LIBSQLGLOT_ENABLE_SIMD "Enable SIMD optimisations" ON)
option(LIBSQLGLOT_ENABLE_NATIVE "Enable native CPU optimizations (-march=native)" OFF)
option(LIBSQLGLOT_FUZZ "Build fuzz targets" OFF)
option(LIBSQLGLOT_PGO_GENERATE "Generate PGO profile data" OFF)
option(LIBSQLGLOT_PGO_USE "Use PGO profile data for optimization" OFF)
# Compiler flags for our code (not dependencies)
set(LIBSQLGLOT_CXX_FLAGS -Wall -Wextra -Wpedantic -Werror -fno-rtti)
if(CMAKE_BUILD_TYPE STREQUAL "Release")
# Portable optimization flags (no -march=native for wheels)
# Use LIBSQLGLOT_ENABLE_NATIVE for local builds with machine-specific optimizations
if(LIBSQLGLOT_ENABLE_NATIVE)
list(APPEND LIBSQLGLOT_CXX_FLAGS -O3 -march=native -mtune=native -flto -fmerge-all-constants -fvisibility=hidden)
message(STATUS "Native optimizations enabled (-march=native -mtune=native)")
else()
# Portable: x86-64 baseline without AVX/AVX2/AVX512
list(APPEND LIBSQLGLOT_CXX_FLAGS -O3 -march=x86-64 -mtune=generic -flto -fmerge-all-constants -fvisibility=hidden)
message(STATUS "Portable optimizations enabled (-march=x86-64 -mtune=generic)")
endif()
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION ON) # Enable LTO
# Profile-Guided Optimization (PGO)
if(LIBSQLGLOT_PGO_GENERATE)
list(APPEND LIBSQLGLOT_CXX_FLAGS -fprofile-generate)
message(STATUS "PGO: Generating profile data (step 1/3)")
elseif(LIBSQLGLOT_PGO_USE)
list(APPEND LIBSQLGLOT_CXX_FLAGS -fprofile-use -fprofile-correction)
message(STATUS "PGO: Using profile data for optimization (step 3/3)")
endif()
elseif(CMAKE_BUILD_TYPE STREQUAL "Debug")
list(APPEND LIBSQLGLOT_CXX_FLAGS -O0 -g)
endif()
# Find Python for code generation
find_package(Python3 COMPONENTS Interpreter REQUIRED)
# Generate dialect reflection mappings from the Dialect enum
# This is a proper solution to the GCC 16 bug where enumerators_of() cannot be used in constexpr
set(DIALECT_HEADER "${CMAKE_SOURCE_DIR}/include/libsqlglot/dialects.h")
set(DIALECT_REFLECTION_GENERATED "${CMAKE_BINARY_DIR}/include/libsqlglot/dialect_reflection_generated.h")
# Create output directory
file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/include/libsqlglot")
add_custom_command(
OUTPUT ${DIALECT_REFLECTION_GENERATED}
COMMAND ${Python3_EXECUTABLE} ${CMAKE_SOURCE_DIR}/scripts/generate_dialect_reflection.py
${DIALECT_HEADER} ${DIALECT_REFLECTION_GENERATED}
DEPENDS ${DIALECT_HEADER} ${CMAKE_SOURCE_DIR}/scripts/generate_dialect_reflection.py
COMMENT "Generating dialect reflection mappings from Dialect enum"
VERBATIM
)
add_custom_target(generate_dialect_reflection ALL DEPENDS ${DIALECT_REFLECTION_GENERATED})
# Generate merged dialect grammars from patches
# Find all dialect patches
file(GLOB DIALECT_PATCHES "${CMAKE_SOURCE_DIR}/dialects/patches/*.json")
# Map patch names to base grammars
set(PATCH_BASE_MAP
"redshift:postgresql"
"duckdb:postgresql"
"cockroachdb:postgresql"
"materialize:postgresql"
"vertica:postgresql"
"greenplum:postgresql"
"risingwave:postgresql"
"timescaledb:postgresql"
"yugabytedb:postgresql"
"dune:postgresql"
"bigquery:postgresql"
"spark:hive"
"databricks:hive"
"impala:hive"
"spark2:hive"
"singlestore:mysql"
"doris:mysql"
"tidb:mysql"
"presto:trino"
"dremio:trino"
"oracle:plsql"
"fabric:tsql"
"druid:mysql"
"db2:derby"
"netezza:postgresql"
"tableau:postgresql"
"exasol:postgresql"
"solr:derby"
"calcite:derby"
)
set(MERGED_GRAMMARS "")
foreach(PATCH_FILE ${DIALECT_PATCHES})
get_filename_component(PATCH_NAME ${PATCH_FILE} NAME_WE)
# Find base grammar for this patch
set(BASE_GRAMMAR "")
foreach(MAPPING ${PATCH_BASE_MAP})
string(REGEX MATCH "^${PATCH_NAME}:(.+)$" MATCHED "${MAPPING}")
if(MATCHED)
set(BASE_GRAMMAR "${CMAKE_MATCH_1}")
break()
endif()
endforeach()
if(BASE_GRAMMAR)
set(BASE_GRAMMAR_FILE "${CMAKE_SOURCE_DIR}/generated/grammar_data/${BASE_GRAMMAR}_grammar_data.json")
set(OUTPUT_FILE "${CMAKE_BINARY_DIR}/generated/grammar_data/${PATCH_NAME}_grammar_data.json")
# Create output directory
file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/generated/grammar_data")
# Add custom command to merge grammar
add_custom_command(
OUTPUT ${OUTPUT_FILE}
COMMAND ${Python3_EXECUTABLE} ${CMAKE_SOURCE_DIR}/scripts/merge_grammar.py
${BASE_GRAMMAR_FILE} ${PATCH_FILE} ${OUTPUT_FILE}
DEPENDS ${BASE_GRAMMAR_FILE} ${PATCH_FILE} ${CMAKE_SOURCE_DIR}/scripts/merge_grammar.py
COMMENT "Merging ${PATCH_NAME} dialect grammar (base: ${BASE_GRAMMAR})"
VERBATIM
)
list(APPEND MERGED_GRAMMARS ${OUTPUT_FILE})
else()
message(WARNING "No base grammar mapping found for patch: ${PATCH_NAME}")
endif()
endforeach()
# Create custom target for all merged grammars
add_custom_target(merge_dialects ALL DEPENDS ${MERGED_GRAMMARS})
# Header-only interface target
add_library(libsqlglot INTERFACE)
target_include_directories(libsqlglot INTERFACE
$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/include>
$<BUILD_INTERFACE:${CMAKE_BINARY_DIR}/include>
$<INSTALL_INTERFACE:include>
)
# Note: CMake 3.28 doesn't support cxx_std_26, using manual flag above
# target_compile_features(libsqlglot INTERFACE cxx_std_26)
add_dependencies(libsqlglot generate_dialect_reflection merge_dialects)
# Optional compiled shared library
if(LIBSQLGLOT_BUILD_SHARED)
add_library(libsqlglot_shared SHARED src/libsqlglot.cpp)
target_link_libraries(libsqlglot_shared PUBLIC libsqlglot)
target_compile_options(libsqlglot_shared PRIVATE ${LIBSQLGLOT_CXX_FLAGS})
set_target_properties(libsqlglot_shared PROPERTIES
OUTPUT_NAME sqlglot
VERSION ${PROJECT_VERSION}
SOVERSION ${PROJECT_VERSION_MAJOR}
)
endif()
# FetchContent for downloading dependencies
include(FetchContent)
# Tests (Catch2)
if(LIBSQLGLOT_BUILD_TESTS)
FetchContent_Declare(
Catch2
GIT_REPOSITORY https://github.com/catchorg/Catch2.git
GIT_TAG v3.5.2
)
FetchContent_MakeAvailable(Catch2)
enable_testing()
add_subdirectory(tests)
endif()
# Benchmarks (Google Benchmark)
if(LIBSQLGLOT_BUILD_BENCHMARKS)
FetchContent_Declare(
benchmark
GIT_REPOSITORY https://github.com/google/benchmark.git
GIT_TAG v1.8.3
)
set(BENCHMARK_ENABLE_TESTING OFF CACHE BOOL "Disable benchmark tests" FORCE)
FetchContent_MakeAvailable(benchmark)
add_subdirectory(benchmarks)
endif()
# Python bindings (nanobind)
if(LIBSQLGLOT_BUILD_PYTHON)
find_package(Python COMPONENTS Interpreter Development.Module REQUIRED)
FetchContent_Declare(
nanobind
GIT_REPOSITORY https://github.com/wjakob/nanobind.git
GIT_TAG v2.10.0
)
FetchContent_MakeAvailable(nanobind)
add_subdirectory(src/python)
endif()
# Fuzz targets
if(LIBSQLGLOT_FUZZ)
if(NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang")
message(FATAL_ERROR "Fuzzing requires Clang compiler")
endif()
add_subdirectory(tests/fuzz)
endif()
# Installation
include(GNUInstallDirs)
install(TARGETS libsqlglot
EXPORT libsqlglotTargets
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)
install(DIRECTORY include/libsqlglot
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)
if(LIBSQLGLOT_BUILD_SHARED)
install(TARGETS libsqlglot_shared
EXPORT libsqlglotTargets
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
endif()