diff --git a/.gitmodules b/.gitmodules index a618104f3642..74f29da77d2d 100644 --- a/.gitmodules +++ b/.gitmodules @@ -10,6 +10,9 @@ [submodule "contrib/librdkafka"] path = contrib/librdkafka url = https://github.com/ClickHouse/librdkafka +[submodule "contrib/libmaxminddb"] + path = contrib/libmaxminddb + url = https://github.com/maxmind/libmaxminddb.git [submodule "contrib/cctz"] path = contrib/cctz url = https://github.com/ClickHouse/cctz diff --git a/contrib/CMakeLists.txt b/contrib/CMakeLists.txt index c6d1dcb41e61..3d3e6164c32d 100644 --- a/contrib/CMakeLists.txt +++ b/contrib/CMakeLists.txt @@ -88,6 +88,8 @@ add_contrib (libarchive-cmake libarchive) add_contrib (corrosion-cmake corrosion) +add_contrib (libmaxminddb-cmake libmaxminddb) + if (ENABLE_FUZZING) add_contrib (libprotobuf-mutator-cmake libprotobuf-mutator) endif() diff --git a/contrib/libmaxminddb b/contrib/libmaxminddb new file mode 160000 index 000000000000..ac4d0d248003 --- /dev/null +++ b/contrib/libmaxminddb @@ -0,0 +1 @@ +Subproject commit ac4d0d2480032a8664e251588e57d7b306ca630c diff --git a/contrib/libmaxminddb-cmake/CMakeLists.txt b/contrib/libmaxminddb-cmake/CMakeLists.txt new file mode 100644 index 000000000000..78388e8e183d --- /dev/null +++ b/contrib/libmaxminddb-cmake/CMakeLists.txt @@ -0,0 +1,94 @@ +option (ENABLE_MAXMINDDB "Enable maxminddb library" OFF) + +if (NOT ENABLE_MAXMINDDB) + message (STATUS "Not using maxminddb") + return() +endif() + +set(LIBMAXMINDDB_VERSION "1.7.1") + +include(GNUInstallDirs) +include(CheckTypeSize) +check_type_size("unsigned __int128" UINT128) +check_type_size("unsigned int __attribute__((mode(TI)))" UINT128_USING_MODE) +if(HAVE_UINT128) + set(MMDB_UINT128_USING_MODE 0) + set(MMDB_UINT128_IS_BYTE_ARRAY 0) +elseif(HAVE_UINT128_USING_MODE) + set(MMDB_UINT128_USING_MODE 1) + set(MMDB_UINT128_IS_BYTE_ARRAY 0) +else() + set(MMDB_UINT128_USING_MODE 0) + set(MMDB_UINT128_IS_BYTE_ARRAY 1) +endif() + +include (TestBigEndian) +TEST_BIG_ENDIAN(IS_BIG_ENDIAN) + +if (${CMAKE_SYSTEM_NAME} MATCHES "Linux") + set(CMAKE_POSITION_INDEPENDENT_CODE ON) +endif() + +set(LIBMAXMINDDB_SOURCE_DIR "${ClickHouse_SOURCE_DIR}/contrib/libmaxminddb") +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/maxminddb_config.h.in + ${CMAKE_CURRENT_BINARY_DIR}/include/maxminddb_config.h) +configure_file( + "${LIBMAXMINDDB_SOURCE_DIR}/include/maxminddb.h" + "${CMAKE_CURRENT_BINARY_DIR}/include/maxminddb.h" + COPYONLY +) + +add_library(_maxminddb + ${LIBMAXMINDDB_SOURCE_DIR}/src/maxminddb.c + ${LIBMAXMINDDB_SOURCE_DIR}/src/data-pool.c +) +add_library(ch_contrib::maxminddb ALIAS _maxminddb) + +target_compile_definitions(_maxminddb PRIVATE PACKAGE_VERSION="${LIBMAXMINDDB_VERSION}") + +if(NOT IS_BIG_ENDIAN) + target_compile_definitions(_maxminddb PRIVATE MMDB_LITTLE_ENDIAN=1) +endif() + +if(MSVC) + target_compile_definitions(_maxminddb PRIVATE _CRT_SECURE_NO_WARNINGS) +endif() + +if(WIN32) + target_link_libraries(_maxminddb ws2_32) + if(MSVC_STATIC_RUNTIME) + # On MSVC, when MSVC_STATIC_RUNTIME is ON, MT (Release) and MTd (Debug) + # run-time libraries will be used instead of MD/MDd. The default is OFF so + # MD/MDd are used when nothing related is passed. + # + # Adapted from https://gitlab.kitware.com/cmake/community/-/wikis/FAQ#make-override-files + if(MSVC) + target_compile_options(my_target PRIVATE + $<$:/D_DEBUG /MTd /Zi /Ob0 /Od /RTC1> + $<$:/MT /O1 /Ob1 /D NDEBUG> + $<$:/MT /O2 /Ob2 /D NDEBUG> + $<$:/MT /Zi /O2 /Ob1 /D NDEBUG> + ) + endif() + endif() +endif() + +target_include_directories(_maxminddb PUBLIC + ${LIBMAXMINDDB_SOURCE_DIR} + ${CMAKE_CURRENT_BINARY_DIR}/include +) + +if(NOT MSVC) + add_executable(mmdblookup + ${LIBMAXMINDDB_SOURCE_DIR}/bin/mmdblookup.c + ) + target_compile_definitions(mmdblookup PRIVATE PACKAGE_VERSION="${LIBMAXMINDDB_VERSION}") + + # Otherwise 'undefined reference to WinMain' linker error happen due to wmain() + if(MINGW) + target_link_options(mmdblookup PRIVATE "-municode") + endif() + + target_link_libraries(mmdblookup _maxminddb pthread) +endif() + diff --git a/contrib/libmaxminddb-cmake/maxminddb_config.h.in b/contrib/libmaxminddb-cmake/maxminddb_config.h.in new file mode 100644 index 000000000000..28850712ab75 --- /dev/null +++ b/contrib/libmaxminddb-cmake/maxminddb_config.h.in @@ -0,0 +1,8 @@ +#pragma once + +/* Define as 1 if we use unsigned int __atribute__ ((__mode__(TI))) for uint128 values */ +#cmakedefine01 MMDB_UINT128_USING_MODE + +/* Define as 1 if we don't have an unsigned __int128 type */ +#cmakedefine01 MMDB_UINT128_IS_BYTE_ARRAY + diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 73aa409e9958..42cf251a82c2 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -552,6 +552,10 @@ if (TARGET ch_contrib::rocksdb) dbms_target_link_libraries(PUBLIC ch_contrib::rocksdb) endif() +if (TARGET ch_contrib::maxminddb) + dbms_target_link_libraries(PUBLIC ch_contrib::maxminddb) +endif() + if (TARGET ch_contrib::libpqxx) dbms_target_link_libraries(PUBLIC ch_contrib::libpqxx) endif() diff --git a/src/Common/config.h.in b/src/Common/config.h.in index 8e513dca1450..76977dc81814 100644 --- a/src/Common/config.h.in +++ b/src/Common/config.h.in @@ -65,6 +65,7 @@ #cmakedefine01 USE_BCRYPT #cmakedefine01 USE_LIBARCHIVE #cmakedefine01 USE_POCKETFFT +#cmakedefine01 USE_MAXMINDDB /// This is needed for .incbin in assembly. For some reason, include paths don't work there in presence of LTO. /// That's why we use absolute paths. diff --git a/src/configure_config.cmake b/src/configure_config.cmake index 141e51badbb5..9c65cef9ce6c 100644 --- a/src/configure_config.cmake +++ b/src/configure_config.cmake @@ -176,5 +176,8 @@ endif() if (TARGET ch_contrib::pocketfft) set(USE_POCKETFFT 1) endif() +if (TARGET ch_contrib::maxminddb) + set(USE_MAXMINDDB 1) +endif() set(SOURCE_DIR ${PROJECT_SOURCE_DIR})