From 56155829273bf428aebd9c501c2ff898058fafea Mon Sep 17 00:00:00 2001 From: Vasily Nemkov Date: Mon, 4 Dec 2023 22:49:38 +0100 Subject: [PATCH] Proper source and library version Added version.h -- master-copy of the version data of the library, which defines multiple macros, including CLICKHOUSE_CPP_VERSION Added version.cmake -- that sets project and library version info according to version.h, also reminds to update version upon new github release. Added method Client::GetVersion() that returns version info at run-time --- .github/workflows/linux.yml | 108 +++++++------ .github/workflows/macos.yml | 73 +++++---- .github/workflows/windows_mingw.yml | 81 +++++----- .github/workflows/windows_msvc.yml | 56 ++++--- CMakeLists.txt | 231 +++++++++++++++------------- clickhouse/CMakeLists.txt | 18 ++- clickhouse/client.cpp | 39 +++-- clickhouse/client.h | 13 ++ clickhouse/version.h | 16 ++ cmake/version.cmake | 88 +++++++++++ ut/client_ut.cpp | 18 +++ 11 files changed, 468 insertions(+), 273 deletions(-) create mode 100644 clickhouse/version.h create mode 100644 cmake/version.cmake diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 905c0868..9f233f98 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -8,6 +8,11 @@ on: pull_request: branches: [ master ] + release: + types: + - published + - prereleased + env: BUILD_TYPE: Release CLICKHOUSE_SERVER_IMAGE: "clickhouse/clickhouse-server:22.3" @@ -65,54 +70,57 @@ jobs: runs-on: ${{matrix.os}} steps: - - uses: actions/checkout@v2 - - - name: Install dependencies - run: | - sudo apt-get update && \ - sudo apt-get install -y \ - docker \ + - uses: actions/checkout@v4 + with: + fetch-depth: 100 + fetch-tags: true + + - name: Install dependencies + run: | + sudo apt-get update && \ + sudo apt-get install -y \ + docker \ + cmake \ + ${{matrix.COMPILER_INSTALL}} \ + ${{matrix.DEPENDENCIES_INSTALL}} + + - name: Install dependencies - Docker + run: | + sudo apt remove -y docker docker-engine docker.io containerd runc + sudo apt install -y apt-transport-https ca-certificates curl gnupg lsb-release + curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg + echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null + sudo apt update -q + sudo apt install docker-ce docker-ce-cli containerd.io + + - name: Configure project + run: | + cmake \ + -D CMAKE_C_COMPILER=${{matrix.C_COMPILER}} \ + -D CMAKE_CXX_COMPILER=${{matrix.CXX_COMPILER}} \ + -D CMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} \ + -D BUILD_TESTS=ON \ + ${{matrix.SSL_CMAKE_OPTION}} \ + ${{matrix.DEPENDENCIES_CMAKE_OPTIONS}} \ + -S ${{github.workspace}} \ + -B ${{github.workspace}}/build + + - name: Build project + run: | cmake \ - ${{matrix.COMPILER_INSTALL}} \ - ${{matrix.DEPENDENCIES_INSTALL}} - - - name: Install dependencies - Docker - run: | - sudo apt remove -y docker docker-engine docker.io containerd runc - sudo apt install -y apt-transport-https ca-certificates curl gnupg lsb-release - curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg - echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null - sudo apt update -q - sudo apt install docker-ce docker-ce-cli containerd.io - - - name: Configure project - run: | - cmake \ - -D CMAKE_C_COMPILER=${{matrix.C_COMPILER}} \ - -D CMAKE_CXX_COMPILER=${{matrix.CXX_COMPILER}} \ - -D CMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} \ - -D BUILD_TESTS=ON \ - ${{matrix.SSL_CMAKE_OPTION}} \ - ${{matrix.DEPENDENCIES_CMAKE_OPTIONS}} \ - -S ${{github.workspace}} \ - -B ${{github.workspace}}/build - - - name: Build project - run: | - cmake \ - --build ${{github.workspace}}/build \ - --config ${{env.BUILD_TYPE}} \ - --target all - - - name: Test - Start ClickHouse server in background - run: | - docker pull ${CLICKHOUSE_SERVER_IMAGE} - docker run -d --name clickhouse -p 9000:9000 ${CLICKHOUSE_SERVER_IMAGE} - docker ps -a - docker stats -a --no-stream - ## Check and wait until CH is ready to accept connections - docker exec clickhouse bash -c 'for i in {1..10}; do echo checking if clickhouse server is started attempt \#$i; if ( grep -q " Application: Ready for connections." /var/log/clickhouse-server/clickhouse-server.log ); then echo seems like clickhouse server is started; exit 0; fi; sleep 1; done; exit -1' - - - name: Test - working-directory: ${{github.workspace}}/build/ut - run: ./clickhouse-cpp-ut + --build ${{github.workspace}}/build \ + --config ${{env.BUILD_TYPE}} \ + --target all + + - name: Test - Start ClickHouse server in background + run: | + docker pull ${CLICKHOUSE_SERVER_IMAGE} + docker run -d --name clickhouse -p 9000:9000 ${CLICKHOUSE_SERVER_IMAGE} + docker ps -a + docker stats -a --no-stream + ## Check and wait until CH is ready to accept connections + docker exec clickhouse bash -c 'for i in {1..10}; do echo checking if clickhouse server is started attempt \#$i; if ( grep -q " Application: Ready for connections." /var/log/clickhouse-server/clickhouse-server.log ); then echo seems like clickhouse server is started; exit 0; fi; sleep 1; done; exit -1' + + - name: Test + working-directory: ${{github.workspace}}/build/ut + run: ./clickhouse-cpp-ut diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 215b2214..b3faae21 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -7,6 +7,10 @@ on: branches: [ master ] pull_request: branches: [ master ] + release: + types: + - published + - prereleased env: BUILD_TYPE: Release @@ -31,41 +35,44 @@ jobs: SSL_INSTALL: openssl steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 + with: + fetch-depth: 100 + fetch-tags: true - - name: Install dependencies - run: brew install cmake ${{matrix.SSL_INSTALL}} + - name: Install dependencies + run: brew install cmake ${{matrix.SSL_INSTALL}} - - name: Configure CMake - run: | - cmake \ - -D CMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} \ - -D BUILD_TESTS=ON \ - ${{matrix.SSL_CMAKE_OPTION}} \ - -S ${{github.workspace}} \ - -B ${{github.workspace}}/build + - name: Configure CMake + run: | + cmake \ + -D CMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} \ + -D BUILD_TESTS=ON \ + ${{matrix.SSL_CMAKE_OPTION}} \ + -S ${{github.workspace}} \ + -B ${{github.workspace}}/build - - name: Build - run: | - cmake \ - --build ${{github.workspace}}/build \ - --config ${{env.BUILD_TYPE}} \ - --target all + - name: Build + run: | + cmake \ + --build ${{github.workspace}}/build \ + --config ${{env.BUILD_TYPE}} \ + --target all - - name: Start tls offoader proxy - # that mimics non-secure clickhouse running on localhost - # by tunneling queries to remote tls server - # (needed because we can't start real clickhouse instance on macOS) - run: | - wget https://github.com/filimonov/go-tlsoffloader/releases/download/v0.1.2/go-tlsoffloader_0.1.2_Darwin_x86_64.tar.gz - tar -xvzf go-tlsoffloader_0.1.2_Darwin_x86_64.tar.gz - ./go-tlsoffloader -l localhost:9000 -b github.demo.trial.altinity.cloud:9440 & + - name: Start tls offoader proxy + # that mimics non-secure clickhouse running on localhost + # by tunneling queries to remote tls server + # (needed because we can't start real clickhouse instance on macOS) + run: | + wget https://github.com/filimonov/go-tlsoffloader/releases/download/v0.1.2/go-tlsoffloader_0.1.2_Darwin_x86_64.tar.gz + tar -xvzf go-tlsoffloader_0.1.2_Darwin_x86_64.tar.gz + ./go-tlsoffloader -l localhost:9000 -b github.demo.trial.altinity.cloud:9440 & - - name: Test - working-directory: ${{github.workspace}}/build/ut - env: - # It is impossible to start CH server in docker on macOS due to github actions limitations, - # so we use remote server to execute tests, some do not allow some features for anonymoust/free users: - # - system.query_log used by 'Client/ClientCase.Query_ID' - GTEST_FILTER: "-Client/ClientCase.Query_ID*:Client/ClientCase.TracingContext/*" - run: ./clickhouse-cpp-ut ${GTEST_FILTER} + - name: Test + working-directory: ${{github.workspace}}/build/ut + env: + # It is impossible to start CH server in docker on macOS due to github actions limitations, + # so we use remote server to execute tests, some do not allow some features for anonymoust/free users: + # - system.query_log used by 'Client/ClientCase.Query_ID' + GTEST_FILTER: "-Client/ClientCase.Query_ID*:Client/ClientCase.TracingContext/*" + run: ./clickhouse-cpp-ut ${GTEST_FILTER} diff --git a/.github/workflows/windows_mingw.yml b/.github/workflows/windows_mingw.yml index 6c6c3e9b..5681c7c4 100644 --- a/.github/workflows/windows_mingw.yml +++ b/.github/workflows/windows_mingw.yml @@ -8,6 +8,11 @@ on: pull_request: branches: [ master ] + release: + types: + - published + - prereleased + env: BUILD_TYPE: Release CLICKHOUSE_USER: clickhouse_cpp_cicd @@ -49,44 +54,48 @@ jobs: shell: msys2 {0} steps: - - uses: actions/checkout@v2 - - uses: msys2/setup-msys2@v2 - with: - msystem: ${{ matrix.sys }} - update: true - install: >- - mingw-w64-${{matrix.env}}-cmake - mingw-w64-${{matrix.env}}-make - mingw-w64-${{matrix.env}}-gcc - mingw-w64-${{matrix.env}}-openssl - mingw-w64-${{matrix.env}}-ninja - mingw-w64-${{matrix.env}}-wget - mingw-w64-${{matrix.env}}-ca-certificates - tar + - uses: actions/checkout@v4 + with: + fetch-depth: 100 + fetch-tags: true + - uses: msys2/setup-msys2@v2 + with: + msystem: ${{ matrix.sys }} + update: true + install: >- + mingw-w64-${{matrix.env}}-cmake + mingw-w64-${{matrix.env}}-make + mingw-w64-${{matrix.env}}-gcc + mingw-w64-${{matrix.env}}-openssl + mingw-w64-${{matrix.env}}-ninja + mingw-w64-${{matrix.env}}-wget + mingw-w64-${{matrix.env}}-ca-certificates + tar - - name: Configure CMake - run: cmake -B build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DBUILD_TESTS=ON - # -DWITH_OPENSSL=ON was not able to make it work (some strange issues with CA paths, need debug) + - name: Configure CMake + run: cmake -B build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DBUILD_TESTS=ON -DCHECK_VERSION=OFF + # -DWITH_OPENSSL=ON was not able to make it work (some strange issues with CA paths, need debug) + # -DCHECK_VERSION=OFF since it requires git, which can't be found from within cmake for some reason. - - name: Build - run: cmake --build build --config ${{env.BUILD_TYPE}} --target all + - name: Build + run: cmake --build build --config ${{env.BUILD_TYPE}} --target all - - name: Start tls offoader proxy - # that mimics non-secure clickhouse running on localhost - # by tunneling queries to remote tls server - # (needed because we can't start real clickhouse instance on windows) - run: | - wget https://github.com/filimonov/go-tlsoffloader/releases/download/v0.1.2/go-tlsoffloader_0.1.2_Windows_x86_64.tar.gz - tar -xvzf go-tlsoffloader_0.1.2_Windows_x86_64.tar.gz - ./go-tlsoffloader.exe -l localhost:9000 -b github.demo.trial.altinity.cloud:9440 & + - name: Start tls offoader proxy + # that mimics non-secure clickhouse running on localhost + # by tunneling queries to remote tls server + # (needed because we can't start real clickhouse instance on windows) + run: | + wget https://github.com/filimonov/go-tlsoffloader/releases/download/v0.1.2/go-tlsoffloader_0.1.2_Windows_x86_64.tar.gz + tar -xvzf go-tlsoffloader_0.1.2_Windows_x86_64.tar.gz + ./go-tlsoffloader.exe -l localhost:9000 -b github.demo.trial.altinity.cloud:9440 & - - name: Test - env: - # It is impossible to start CH server in docker on Windows due to github actions limitations, - # so we use remote server to execute tests, some do not allow some features for anonymoust/free users: - # - system.query_log used by 'Client/ClientCase.Query_ID' - GTEST_FILTER: "-Client/ClientCase.Query_ID*:Client/ClientCase.TracingContext/*" - run: ./build/ut/clickhouse-cpp-ut.exe ${GTEST_FILTER} + - name: Test + env: + # It is impossible to start CH server in docker on Windows due to github actions limitations, + # so we use remote server to execute tests, some do not allow some features for anonymoust/free users: + # - system.query_log used by 'Client/ClientCase.Query_ID' + GTEST_FILTER: "-Client/ClientCase.Query_ID*:Client/ClientCase.TracingContext/*" + run: ./build/ut/clickhouse-cpp-ut.exe ${GTEST_FILTER} - - name: Test (simple) - run: ./build/tests/simple/simple-test.exe + - name: Test (simple) + run: ./build/tests/simple/simple-test.exe diff --git a/.github/workflows/windows_msvc.yml b/.github/workflows/windows_msvc.yml index 760f5ab2..47fb6764 100644 --- a/.github/workflows/windows_msvc.yml +++ b/.github/workflows/windows_msvc.yml @@ -8,6 +8,11 @@ on: pull_request: branches: [ master ] + release: + types: + - published + - prereleased + env: BUILD_TYPE: Release CLICKHOUSE_USER: clickhouse_cpp_cicd @@ -36,31 +41,34 @@ jobs: runs-on: windows-latest steps: - - uses: actions/checkout@v2 - - uses: ilammy/msvc-dev-cmd@v1 + - uses: actions/checkout@v4 + with: + fetch-depth: 100 + fetch-tags: true + - uses: ilammy/msvc-dev-cmd@v1 - - name: Configure CMake - run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DBUILD_TESTS=ON + - name: Configure CMake + run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DBUILD_TESTS=ON - - name: Build - run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} + - name: Build + run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} - - name: Start tls offoader proxy - shell: bash - # that mimics non-secure clickhouse running on localhost - # by tunneling queries to remote tls server - # (needed because we can't start real clickhouse instance on windows) - run: | - choco install wget - wget https://github.com/filimonov/go-tlsoffloader/releases/download/v0.1.2/go-tlsoffloader_0.1.2_Windows_x86_64.tar.gz - tar -xvzf go-tlsoffloader_0.1.2_Windows_x86_64.tar.gz - ./go-tlsoffloader.exe -l localhost:9000 -b github.demo.trial.altinity.cloud:9440 & + - name: Start tls offoader proxy + shell: bash + # that mimics non-secure clickhouse running on localhost + # by tunneling queries to remote tls server + # (needed because we can't start real clickhouse instance on windows) + run: | + choco install wget + wget https://github.com/filimonov/go-tlsoffloader/releases/download/v0.1.2/go-tlsoffloader_0.1.2_Windows_x86_64.tar.gz + tar -xvzf go-tlsoffloader_0.1.2_Windows_x86_64.tar.gz + ./go-tlsoffloader.exe -l localhost:9000 -b github.demo.trial.altinity.cloud:9440 & - - name: Test - env: - # It is impossible to start CH server in docker on Windows due to github actions limitations, - # so we use remote server to execute tests, some do not allow some features for anonymoust/free users: - # - system.query_log used by 'Client/ClientCase.Query_ID' - GTEST_FILTER: "-Client/ClientCase.Query_ID*:Client/ClientCase.TracingContext/*" - working-directory: ${{github.workspace}}/build/ut - run: Release\clickhouse-cpp-ut.exe "${{env.GTEST_FILTER}}" + - name: Test + env: + # It is impossible to start CH server in docker on Windows due to github actions limitations, + # so we use remote server to execute tests, some do not allow some features for anonymoust/free users: + # - system.query_log used by 'Client/ClientCase.Query_ID' + GTEST_FILTER: "-Client/ClientCase.Query_ID*:Client/ClientCase.TracingContext/*" + working-directory: ${{github.workspace}}/build/ut + run: Release\clickhouse-cpp-ut.exe "${{env.GTEST_FILTER}}" diff --git a/CMakeLists.txt b/CMakeLists.txt index 3152b552..e2639f0d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,10 +1,11 @@ -CMAKE_MINIMUM_REQUIRED (VERSION 3.0.2) +CMAKE_MINIMUM_REQUIRED (VERSION 3.5.2) LIST (APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") INCLUDE (cpp17) INCLUDE (subdirs) INCLUDE (openssl) +INCLUDE (version) OPTION (BUILD_BENCHMARK "Build benchmark" OFF) OPTION (BUILD_TESTS "Build tests" OFF) @@ -14,122 +15,130 @@ OPTION (WITH_SYSTEM_ABSEIL "Use system ABSEIL" OFF) OPTION (WITH_SYSTEM_LZ4 "Use system LZ4" OFF) OPTION (WITH_SYSTEM_CITYHASH "Use system cityhash" OFF) OPTION (DEBUG_DEPENDENCIES "Print debug info about dependencies duting build" ON) +OPTION (CHECK_VERSION "Check that version number corresponds to git tag, usefull in CI/CD to validate that new version published on GitHub has same version in sources" ON) -PROJECT (CLICKHOUSE-CLIENT) +PROJECT (CLICKHOUSE-CLIENT + VERSION "${CLICKHOUSE_CPP_VERSION}" + DESCRIPTION "ClickHouse C++ client library" +) - USE_CXX17 () - USE_OPENSSL () +USE_CXX17 () +USE_OPENSSL () - IF (NOT CMAKE_BUILD_TYPE) - SET (CMAKE_BUILD_TYPE "RelWithDebInfo") - ENDIF () - - IF (UNIX) - IF (NOT APPLE) - SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread") - ENDIF () - SET (CMAKE_EXE_LINKER_FLAGS, "${CMAKE_EXE_LINKER_FLAGS} -lpthread") - # -Wpedantic makes int128 support somewhat harder and less performant (by not allowing builtin __int128) - # -Wno-deprecated-declarations to produce less cluttered output when building library itself (`deprecated` attributes are for library users) - SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Werror -Wno-deprecated-declarations") - ENDIF () - - IF (APPLE OR MSVC) - IF(BUILD_SHARED_LIBS) - MESSAGE(FATAL "Does not support shared on this platform") - ENDIF() - ENDIF() - - IF (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") - INCLUDE (CheckCXXSourceCompiles) - - CHECK_CXX_SOURCE_COMPILES("#include \nint main() { return __GLIBCXX__ != 0; }" - CLANG_WITH_LIB_STDCXX) - ENDIF () - - IF (CLANG_WITH_LIB_STDCXX) - # there is a problem with __builtin_mul_overflow call at link time - # the error looks like: ... undefined reference to `__muloti4' ... - # caused by clang bug https://bugs.llvm.org/show_bug.cgi?id=16404 - # explicit linking to compiler-rt allows to workaround the problem - SET (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} --rtlib=compiler-rt") - SET (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --rtlib=compiler-rt") - - # some workaround for linking issues on linux: - # /usr/bin/ld: CMakeFiles/simple-test.dir/main.cpp.o: undefined reference to symbol '_Unwind_Resume@@GCC_3.0' - # /usr/bin/ld: /lib/x86_64-linux-gnu/libgcc_s.so.1: error adding symbols: DSO missing from command line - # FIXME: that workaround breaks clang build on mingw - SET (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -lgcc_s") - SET (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lgcc_s") - ENDIF () +IF (CHECK_VERSION) + clickhouse_cpp_check_library_version(FATAL_ERROR) +ENDIF () - IF (WITH_SYSTEM_ABSEIL) - FIND_PACKAGE(absl REQUIRED) - ELSE () - INCLUDE_DIRECTORIES (contrib/absl) - SUBDIRS (contrib/absl/absl) - ENDIF () +IF (NOT CMAKE_BUILD_TYPE) + SET (CMAKE_BUILD_TYPE "RelWithDebInfo") +ENDIF () - IF (WITH_SYSTEM_LZ4) - FIND_PACKAGE(lz4 REQUIRED) - ELSE () - INCLUDE_DIRECTORIES (contrib/lz4/lz4) - SUBDIRS (contrib/lz4/lz4) +IF (UNIX) + IF (NOT APPLE) + SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread") ENDIF () - - IF (WITH_SYSTEM_CITYHASH) - FIND_PACKAGE(cityhash REQUIRED) - ELSE () - INCLUDE_DIRECTORIES (contrib/cityhash/cityhash) - SUBDIRS (contrib/cityhash/cityhash) - ENDIF () - + SET (CMAKE_EXE_LINKER_FLAGS, "${CMAKE_EXE_LINKER_FLAGS} -lpthread") + # -Wpedantic makes int128 support somewhat harder and less performant (by not allowing builtin __int128) + # -Wno-deprecated-declarations to produce less cluttered output when building library itself (`deprecated` attributes are for library users) + SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Werror -Wno-deprecated-declarations") +ENDIF () + +IF (APPLE OR MSVC) + IF(BUILD_SHARED_LIBS) + MESSAGE(FATAL "Does not support shared on this platform") + ENDIF() +ENDIF() + +IF (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + INCLUDE (CheckCXXSourceCompiles) + + CHECK_CXX_SOURCE_COMPILES("#include \nint main() { return __GLIBCXX__ != 0; }" + CLANG_WITH_LIB_STDCXX) +ENDIF () + +IF (CLANG_WITH_LIB_STDCXX) + # there is a problem with __builtin_mul_overflow call at link time + # the error looks like: ... undefined reference to `__muloti4' ... + # caused by clang bug https://bugs.llvm.org/show_bug.cgi?id=16404 + # explicit linking to compiler-rt allows to workaround the problem + SET (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} --rtlib=compiler-rt") + SET (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --rtlib=compiler-rt") + + # some workaround for linking issues on linux: + # /usr/bin/ld: CMakeFiles/simple-test.dir/main.cpp.o: undefined reference to symbol '_Unwind_Resume@@GCC_3.0' + # /usr/bin/ld: /lib/x86_64-linux-gnu/libgcc_s.so.1: error adding symbols: DSO missing from command line + # FIXME: that workaround breaks clang build on mingw + SET (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -lgcc_s") + SET (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lgcc_s") +ENDIF () + +IF (WITH_SYSTEM_ABSEIL) + FIND_PACKAGE(absl REQUIRED) +ELSE () + INCLUDE_DIRECTORIES (contrib/absl) + SUBDIRS (contrib/absl/absl) +ENDIF () + +IF (WITH_SYSTEM_LZ4) + FIND_PACKAGE(lz4 REQUIRED) +ELSE () + INCLUDE_DIRECTORIES (contrib/lz4/lz4) + SUBDIRS (contrib/lz4/lz4) +ENDIF () + +IF (WITH_SYSTEM_CITYHASH) + FIND_PACKAGE(cityhash REQUIRED) +ELSE () + INCLUDE_DIRECTORIES (contrib/cityhash/cityhash) + SUBDIRS (contrib/cityhash/cityhash) +ENDIF () + +SUBDIRS ( + clickhouse +) + +IF (BUILD_BENCHMARK) + SUBDIRS (bench) +ENDIF (BUILD_BENCHMARK) + +IF (BUILD_TESTS) + INCLUDE_DIRECTORIES (contrib/gtest/include contrib/gtest) SUBDIRS ( - clickhouse + contrib/gtest + tests/simple + ut ) - - IF (BUILD_BENCHMARK) - SUBDIRS (bench) - ENDIF (BUILD_BENCHMARK) - - IF (BUILD_TESTS) - INCLUDE_DIRECTORIES (contrib/gtest/include contrib/gtest) - SUBDIRS ( - contrib/gtest - tests/simple - ut +ENDIF (BUILD_TESTS) + +if(DEBUG_DEPENDENCIES) + function(print_target_properties target) + MESSAGE("${target} properties:") + set(properties "${ARGN}") + foreach(property_name ${properties}) + get_target_property(PROPERTY ${target} ${property_name}) + MESSAGE(NOTICE "\t${property_name} : ${PROPERTY}") + endforeach() + + # Can't get path to the target file at configure time, + # so have to create a target to fetch that info at generate time. + string(REPLACE ":" "_" target_plain_name ${target}) + add_custom_target(${target_plain_name}_print_debug_info COMMAND ${CMAKE_COMMAND} -E echo "${target} : $") + add_dependencies(clickhouse-cpp-lib ${target_plain_name}_print_debug_info) + endfunction() + + function(print_target_debug_info target) + print_target_properties(${target} + INCLUDE_DIRECTORIES + BINARY_DIR + INTERFACE_INCLUDE_DIRECTORIES + INTERFACE_LINK_LIBRARIES + LINK_LIBRARIES + LINK_LIBRARIES_ONLY_TARGETS + IMPORTED_LOCATION ) - ENDIF (BUILD_TESTS) - - if(DEBUG_DEPENDENCIES) - function(print_target_properties target) - MESSAGE("${target} properties:") - set(properties "${ARGN}") - foreach(property_name ${properties}) - get_target_property(PROPERTY ${target} ${property_name}) - MESSAGE(NOTICE "\t${property_name} : ${PROPERTY}") - endforeach() - - # Can't get path to the target file at configure time, - # so have to create a target to fetch that info at generate time. - string(REPLACE ":" "_" target_plain_name ${target}) - add_custom_target(${target_plain_name}_print_debug_info COMMAND ${CMAKE_COMMAND} -E echo "${target} : $") - add_dependencies(clickhouse-cpp-lib ${target_plain_name}_print_debug_info) - endfunction() - - function(print_target_debug_info target) - print_target_properties(${target} - INCLUDE_DIRECTORIES - BINARY_DIR - INTERFACE_INCLUDE_DIRECTORIES - INTERFACE_LINK_LIBRARIES - LINK_LIBRARIES - LINK_LIBRARIES_ONLY_TARGETS - IMPORTED_LOCATION - ) - endfunction() - - print_target_debug_info(absl::int128) - print_target_debug_info(cityhash::cityhash) - print_target_debug_info(lz4::lz4) - endif() + endfunction() + + print_target_debug_info(absl::int128) + print_target_debug_info(cityhash::cityhash) + print_target_debug_info(lz4::lz4) +endif() diff --git a/clickhouse/CMakeLists.txt b/clickhouse/CMakeLists.txt index 97f8cc56..1919418a 100644 --- a/clickhouse/CMakeLists.txt +++ b/clickhouse/CMakeLists.txt @@ -102,8 +102,13 @@ IF (WITH_OPENSSL) LIST(APPEND clickhouse-cpp-lib-src base/sslsocket.cpp) ENDIF () -ADD_LIBRARY (clickhouse-cpp-lib ${clickhouse-cpp-lib-src}) -SET_TARGET_PROPERTIES (clickhouse-cpp-lib PROPERTIES LINKER_LANGUAGE CXX) +ADD_LIBRARY (clickhouse-cpp-lib ${clickhouse-cpp-lib-src} + version.h) +SET_TARGET_PROPERTIES (clickhouse-cpp-lib + PROPERTIES + LINKER_LANGUAGE CXX + VERSION ${CLICKHOUSE_CPP_VERSION} +) TARGET_LINK_LIBRARIES (clickhouse-cpp-lib absl::int128 cityhash::cityhash @@ -115,7 +120,13 @@ TARGET_INCLUDE_DIRECTORIES (clickhouse-cpp-lib IF (NOT BUILD_SHARED_LIBS) ADD_LIBRARY (clickhouse-cpp-lib-static ALIAS clickhouse-cpp-lib) -ENDIF() +ELSE () + SET_TARGET_PROPERTIES (clickhouse-cpp-lib + PROPERTIES + SO_VERSION ${CLICKHOUSE_CPP_VERSION} + SO_VERSION ${CLICKHOUSE_CPP_VERSION_MAJOR} + ) +ENDIF () IF (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") @@ -153,6 +164,7 @@ INSTALL(FILES exceptions.h DESTINATION include/clickhouse/) INSTALL(FILES server_exception.h DESTINATION include/clickhouse/) INSTALL(FILES protocol.h DESTINATION include/clickhouse/) INSTALL(FILES query.h DESTINATION include/clickhouse/) +INSTALL(FILES version.h DESTINATION include/clickhouse/) # base INSTALL(FILES base/buffer.h DESTINATION include/clickhouse/base/) diff --git a/clickhouse/client.cpp b/clickhouse/client.cpp index 6f7ea213..7afafa4f 100644 --- a/clickhouse/client.cpp +++ b/clickhouse/client.cpp @@ -1,4 +1,5 @@ #include "client.h" +#include "clickhouse/version.h" #include "protocol.h" #include "base/compressed.h" @@ -8,20 +9,15 @@ #include "columns/factory.h" #include -#include #include -#include #include #include -#include #if defined(WITH_OPENSSL) #include "base/sslsocket.h" #endif #define DBMS_NAME "ClickHouse" -#define DBMS_VERSION_MAJOR 2 -#define DBMS_VERSION_MINOR 1 #define DBMS_MIN_REVISION_WITH_TEMPORARY_TABLES 50264 #define DBMS_MIN_REVISION_WITH_TOTAL_ROWS_IN_PROGRESS 51554 @@ -43,7 +39,7 @@ #define DBMS_MIN_REVISION_WITH_INITIAL_QUERY_START_TIME 54449 #define DBMS_MIN_REVISION_WITH_INCREMENTAL_PROFILE_EVENTS 54451 -#define REVISION DBMS_MIN_REVISION_WITH_INCREMENTAL_PROFILE_EVENTS +#define DMBS_PROTOCOL_REVISION DBMS_MIN_REVISION_WITH_INCREMENTAL_PROFILE_EVENTS namespace clickhouse { @@ -483,12 +479,12 @@ bool Client::Impl::ReceivePacket(uint64_t* server_packet) { if (!WireFormat::ReadUInt64(*input_, &info.bytes)) { return false; } - if constexpr(REVISION >= DBMS_MIN_REVISION_WITH_TOTAL_ROWS_IN_PROGRESS) { + if constexpr(DMBS_PROTOCOL_REVISION >= DBMS_MIN_REVISION_WITH_TOTAL_ROWS_IN_PROGRESS) { if (!WireFormat::ReadUInt64(*input_, &info.total_rows)) { return false; } } - if constexpr (REVISION >= DBMS_MIN_REVISION_WITH_CLIENT_WRITE_INFO) + if constexpr (DMBS_PROTOCOL_REVISION >= DBMS_MIN_REVISION_WITH_CLIENT_WRITE_INFO) { if (!WireFormat::ReadUInt64(*input_, &info.written_rows)) { return false; @@ -575,7 +571,7 @@ bool Client::Impl::ReceivePacket(uint64_t* server_packet) { bool Client::Impl::ReadBlock(InputStream& input, Block* block) { // Additional information about block. - if constexpr (REVISION >= DBMS_MIN_REVISION_WITH_BLOCK_INFO) { + if constexpr (DMBS_PROTOCOL_REVISION >= DBMS_MIN_REVISION_WITH_BLOCK_INFO) { uint64_t num; BlockInfo info; @@ -639,7 +635,7 @@ bool Client::Impl::ReadBlock(InputStream& input, Block* block) { bool Client::Impl::ReceiveData() { Block block; - if constexpr (REVISION >= DBMS_MIN_REVISION_WITH_TEMPORARY_TABLES) { + if constexpr (DMBS_PROTOCOL_REVISION >= DBMS_MIN_REVISION_WITH_TEMPORARY_TABLES) { if (!WireFormat::SkipString(*input_)) { return false; } @@ -729,9 +725,10 @@ void Client::Impl::SendQuery(const Query& query) { info.query_kind = 1; info.client_name = "ClickHouse client"; - info.client_version_major = DBMS_VERSION_MAJOR; - info.client_version_minor = DBMS_VERSION_MINOR; - info.client_revision = REVISION; + info.client_version_major = CLICKHOUSE_CPP_VERSION_MAJOR; + info.client_version_minor = CLICKHOUSE_CPP_VERSION_MINOR; + info.client_version_patch = CLICKHOUSE_CPP_VERSION_PATCH; + info.client_revision = DMBS_PROTOCOL_REVISION; WireFormat::WriteFixed(*output_, info.query_kind); @@ -870,9 +867,9 @@ void Client::Impl::InitializeStreams(std::unique_ptr&& socket) { bool Client::Impl::SendHello() { WireFormat::WriteUInt64(*output_, ClientCodes::Hello); WireFormat::WriteString(*output_, std::string(DBMS_NAME) + " client"); - WireFormat::WriteUInt64(*output_, DBMS_VERSION_MAJOR); - WireFormat::WriteUInt64(*output_, DBMS_VERSION_MINOR); - WireFormat::WriteUInt64(*output_, REVISION); + WireFormat::WriteUInt64(*output_, CLICKHOUSE_CPP_VERSION_MAJOR); + WireFormat::WriteUInt64(*output_, CLICKHOUSE_CPP_VERSION_MINOR); + WireFormat::WriteUInt64(*output_, DMBS_PROTOCOL_REVISION); WireFormat::WriteString(*output_, options_.default_database); WireFormat::WriteString(*output_, options_.user); WireFormat::WriteString(*output_, options_.password); @@ -1044,4 +1041,14 @@ const ServerInfo& Client::GetServerInfo() const { return impl_->GetServerInfo(); } +Client::Version Client::GetVersion() { + return Version { + CLICKHOUSE_CPP_VERSION_MAJOR, + CLICKHOUSE_CPP_VERSION_MINOR, + CLICKHOUSE_CPP_VERSION_PATCH, + CLICKHOUSE_CPP_VERSION_BUILD, + "" + }; +} + } diff --git a/clickhouse/client.h b/clickhouse/client.h index 35000784..450246e3 100644 --- a/clickhouse/client.h +++ b/clickhouse/client.h @@ -19,6 +19,7 @@ #include "columns/uuid.h" #include +#include #include #include #include @@ -266,6 +267,18 @@ class Client { // Try to connect to different endpoints one by one only one time. If it doesn't work, throw an exception. void ResetConnectionEndpoint(); + + struct Version + { + uint16_t major; + uint16_t minor; + uint16_t patch; + uint16_t build; + const char * extra; + }; + + static Version GetVersion(); + private: const ClientOptions options_; diff --git a/clickhouse/version.h b/clickhouse/version.h new file mode 100644 index 00000000..96a8835e --- /dev/null +++ b/clickhouse/version.h @@ -0,0 +1,16 @@ +#pragma once + +#define CLICKHOUSE_CPP_VERSION_MAJOR 2 +#define CLICKHOUSE_CPP_VERSION_MINOR 5 +#define CLICKHOUSE_CPP_VERSION_PATCH 1 + +#define CLICKHOUSE_CPP_VERSION_BUILD 0 + +// Expecting each version component to be less than 99 +#define CLICKHOUSE_CPP_VERSION \ + CLICKHOUSE_CPP_VERSION_MAJOR * 100 * 100 * 100 \ + + CLICKHOUSE_CPP_VERSION_MINOR * 100 * 100 \ + + CLICKHOUSE_CPP_VERSION_PATCH * 100 \ + + CLICKHOUSE_CPP_VERSION_BUILD + +#define CLICKHOUSE_CPP_VERSION_STRING #CLICKHOUSE_CPP_VERSION_MAJOR "." #CLICKHOUSE_CPP_VERSION_MINOR "." #CLICKHOUSE_CPP_VERSION_PATCH diff --git a/cmake/version.cmake b/cmake/version.cmake new file mode 100644 index 00000000..ce3ad233 --- /dev/null +++ b/cmake/version.cmake @@ -0,0 +1,88 @@ +# Set version value for the project and validate that it matches version reported by git. + +# Reference values are taken from the version.h. +# So even if the library code is decoupled from the cmake-specific project, +# source files still have proper version information. + +function (regex_extract_matching_groups INPUT REGEX_STR) + string (REGEX MATCHALL "${REGEX_STR}" _ "${INPUT}") + if (NOT CMAKE_MATCH_0) + return() + endif() + + set (MATCH_GROUP_INDEX 0) + foreach (OUTPUT_VAR ${ARGN}) + math (EXPR MATCH_GROUP_INDEX "${MATCH_GROUP_INDEX}+1") + set (MATCH_GROUP_VALUE "${CMAKE_MATCH_${MATCH_GROUP_INDEX}}") + set ("${OUTPUT_VAR}" "${MATCH_GROUP_VALUE}" PARENT_SCOPE) + endforeach () +endfunction () + +regex_extract_matching_groups("ttest" "FAILED TO SERCH" RESULT) + +function(clickhouse_cpp_get_version) + # Extract all components of the version from the clickhouse/version.h + + file(READ ${CMAKE_SOURCE_DIR}/clickhouse/version.h VERSION_FILE_DATA) + + foreach (VERSION_COMPONENT + IN ITEMS + CLICKHOUSE_CPP_VERSION_MAJOR + CLICKHOUSE_CPP_VERSION_MINOR + CLICKHOUSE_CPP_VERSION_PATCH + CLICKHOUSE_CPP_VERSION_BUILD) + + regex_extract_matching_groups( + "${VERSION_FILE_DATA}" + "#define ${VERSION_COMPONENT} ([0-9]+)" + "${VERSION_COMPONENT}") + + set ("${VERSION_COMPONENT}" "${${VERSION_COMPONENT}}" PARENT_SCOPE) + endforeach () + + set(CLICKHOUSE_CPP_VERSION "${CLICKHOUSE_CPP_VERSION_MAJOR}.${CLICKHOUSE_CPP_VERSION_MINOR}.${CLICKHOUSE_CPP_VERSION_PATCH}" PARENT_SCOPE) +endfunction() + +clickhouse_cpp_get_version() + +function(clickhouse_cpp_check_library_version CHECK_MODE) +## Verify that current tag matches the version + + find_program (GIT git) + if (GIT) + execute_process( + COMMAND ${GIT} describe --tags + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + OUTPUT_VARIABLE GIT_DESCRIBE_DATA + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + + regex_extract_matching_groups( + "${GIT_DESCRIBE_DATA}" + "^v([0-9]+)\\.([0-9]+)\\.([0-9]+)(\\-([0-9]+).*)?" + VERSION_FROM_GIT_DESCRIBE_MAJOR + VERSION_FROM_GIT_DESCRIBE_MINOR + VERSION_FROM_GIT_DESCRIBE_PATCH + CLICKHOUSE_CPP_VERSION_COMMIT + ) + + if (NOT (VERSION_FROM_GIT_DESCRIBE_MAJOR AND VERSION_FROM_GIT_DESCRIBE_MINOR AND VERSION_FROM_GIT_DESCRIBE_PATCH)) + message (${CHECK_MODE} "version obtained from `git describe` doesn't look like a valid version: \"${GIT_DESCRIBE_DATA}\"") + return () + endif () + + set (EXPECTED_CLICKHOUSE_CPP_VERSION "${VERSION_FROM_GIT_DESCRIBE_MAJOR}.${VERSION_FROM_GIT_DESCRIBE_MINOR}.${VERSION_FROM_GIT_DESCRIBE_PATCH}") + if (NOT "${EXPECTED_CLICKHOUSE_CPP_VERSION}" STREQUAL ${CLICKHOUSE_CPP_VERSION}) + message(${CHECK_MODE} "update CLICKHOUSE_CPP_VERSION_ values in version.h.\n" +"git reports version as \"${GIT_DESCRIBE_DATA}\"," +" hence expecting version to be ${EXPECTED_CLICKHOUSE_CPP_VERSION}, " +" instead got ${CLICKHOUSE_CPP_VERSION}") + endif () + else () + message (${CHECK_MODE} "git is not found, can't verify library version") + endif () + + message("Version check passed: ${CLICKHOUSE_CPP_VERSION}") +endfunction() + +# clickhouse_cpp_check_library_version() diff --git a/ut/client_ut.cpp b/ut/client_ut.cpp index a9dd8190..9df58c07 100644 --- a/ut/client_ut.cpp +++ b/ut/client_ut.cpp @@ -1,6 +1,7 @@ #include #include "clickhouse/base/socket.h" +#include "clickhouse/version.h" #include "readonly_client_test.h" #include "connection_failed_client_test.h" #include "ut/utils_comparison.h" @@ -93,6 +94,23 @@ class ClientCase : public testing::TestWithParam { const std::string column_name = "test_column"; }; +TEST_P(ClientCase, Version) { + auto version = client_->GetVersion(); + EXPECT_NE(0, CLICKHOUSE_CPP_VERSION); + + EXPECT_GE(2, CLICKHOUSE_CPP_VERSION_MAJOR); + EXPECT_LE(0, CLICKHOUSE_CPP_VERSION_MINOR); + EXPECT_LE(0, CLICKHOUSE_CPP_VERSION_PATCH); + + EXPECT_EQ(CLICKHOUSE_CPP_VERSION_MAJOR, version.major); + EXPECT_EQ(CLICKHOUSE_CPP_VERSION_MINOR, version.minor); + EXPECT_EQ(CLICKHOUSE_CPP_VERSION_PATCH, version.patch); + EXPECT_EQ(CLICKHOUSE_CPP_VERSION_BUILD, version.build); + EXPECT_EQ(CLICKHOUSE_CPP_VERSION_PATCH, version.patch); + + // EXPECT_EQ(CLICKHOUSE_CPP_VERSION, versionNumber(version.major, version.minor, version.patch, version.build)); +} + TEST_P(ClientCase, Array) { Block b;