| # Licensed to the Apache Software Foundation (ASF) under one |
| # or more contributor license agreements. See the NOTICE file |
| # distributed with this work for additional information |
| # regarding copyright ownership. The ASF licenses this file |
| # to you under the Apache License, Version 2.0 (the |
| # "License"); you may not use this file except in compliance |
| # with the License. You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, |
| # software distributed under the License is distributed on an |
| # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| # KIND, either express or implied. See the License for the |
| # specific language governing permissions and limitations |
| # under the License. |
| |
| # Require cmake that supports BYPRODUCTS in add_custom_command, ExternalProject_Add [1]. |
| cmake_minimum_required(VERSION 3.2.0) |
| |
| file(READ "${CMAKE_CURRENT_SOURCE_DIR}/.parquetcppversion" PARQUET_VERSION) |
| string(REPLACE "\n" "" PARQUET_VERSION "${PARQUET_VERSION}") |
| string(REGEX MATCH "^([0-9]+\.[0-9]+\.[0-9]+(\.[0-9]+)?)" VERSION ${PARQUET_VERSION}) |
| if(NOT VERSION) |
| message(FATAL_ERROR "invalid .parquetcppversion") |
| endif() |
| |
| project(parquet-cpp VERSION ${VERSION}) |
| set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "C++ library to read and write the Apache Parquet columnar data format") |
| set(CPACK_PACKAGE_VERSION_MAJOR ${PROJECT_VERSION_MAJOR}) |
| set(CPACK_PACKAGE_VERSION_MINOR ${PROJECT_VERSION_MINOR}) |
| set(CPACK_PACKAGE_VERSION_PATCH ${PROJECT_VERSION_PATCH}) |
| set(CPACK_PACKAGE_VENDOR "Apache Software Foundation") |
| set(CPACK_PACKAGE_CONTACT "Apache Parquet Development <dev@parquet.apache.org>") |
| set(CPACK_STRIP_FILES TRUE) |
| set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/LICENSE.txt") |
| set(CPACK_DEBIAN_FILE_NAME "DEB-DEFAULT") |
| set(CPACK_RPM_FILE_NAME "RPM-DEFAULT") |
| set(CPACK_RPM_PACKAGE_LICENSE "Apache v2.0") |
| |
| include(ExternalProject) |
| include(FindPkgConfig) |
| |
| # This ensures that things like gnu++11 get passed correctly |
| set(CMAKE_CXX_STANDARD 11) |
| |
| # We require a C++11 compliant compiler |
| set(CMAKE_CXX_STANDARD_REQUIRED ON) |
| |
| include(GNUInstallDirs) |
| |
| set(PARQUET_SO_VERSION ${PROJECT_VERSION_MAJOR}) |
| set(PARQUET_ABI_VERSION ${PROJECT_VERSION}) |
| if(WIN32) |
| set(INSTALL_CMAKE_DIR cmake) |
| else() |
| set(INSTALL_CMAKE_DIR "${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}/cmake") |
| endif() |
| set(CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION "/usr/${CMAKE_INSTALL_LIBDIR}/pkgconfig") |
| include(CPack) |
| |
| include(CMakePackageConfigHelpers) |
| configure_package_config_file(cmake_modules/${PROJECT_NAME}Config.cmake.in |
| ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake |
| INSTALL_DESTINATION ${INSTALL_CMAKE_DIR} |
| PATH_VARS CMAKE_INSTALL_INCLUDEDIR CMAKE_INSTALL_LIBDIR) |
| write_basic_package_version_file(${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake |
| COMPATIBILITY SameMajorVersion) |
| install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake |
| ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake |
| DESTINATION ${INSTALL_CMAKE_DIR}) |
| |
| if (NOT "$ENV{PARQUET_GCC_ROOT}" STREQUAL "") |
| set(GCC_ROOT $ENV{PARQUET_GCC_ROOT}) |
| set(CMAKE_C_COMPILER ${GCC_ROOT}/bin/gcc) |
| set(GCOV_PATH ${GCC_ROOT}/bin/gcov) |
| set(CMAKE_CXX_COMPILER ${GCC_ROOT}/bin/g++) |
| endif() |
| |
| # generate CTest input files |
| enable_testing() |
| |
| # where to find cmake modules |
| set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake_modules") |
| set(BUILD_SUPPORT_DIR "${CMAKE_SOURCE_DIR}/build-support") |
| |
| set(CLANG_FORMAT_VERSION "5.0") |
| find_package(ClangTools) |
| if ("$ENV{CMAKE_EXPORT_COMPILE_COMMANDS}" STREQUAL "1" OR CLANG_TIDY_FOUND) |
| # Generate a Clang compile_commands.json "compilation database" file for use |
| # with various development tools, such as Vim's YouCompleteMe plugin. |
| # See http://clang.llvm.org/docs/JSONCompilationDatabase.html |
| set(CMAKE_EXPORT_COMPILE_COMMANDS 1) |
| endif() |
| |
| find_program(CCACHE_FOUND ccache) |
| if(CCACHE_FOUND) |
| set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache) |
| set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache) |
| endif(CCACHE_FOUND) |
| |
| if(APPLE) |
| set(CMAKE_MACOSX_RPATH 1) |
| endif() |
| |
| # if no build build type is specified, default to debug builds |
| if (NOT CMAKE_BUILD_TYPE) |
| set(CMAKE_BUILD_TYPE Debug) |
| endif(NOT CMAKE_BUILD_TYPE) |
| |
| # set compile output directory |
| string (TOLOWER ${CMAKE_BUILD_TYPE} BUILD_SUBDIR_NAME) |
| |
| # Top level cmake file, set options |
| if ("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}") |
| option(PARQUET_BUILD_SHARED |
| "Build the shared version of libparquet" |
| ON) |
| option(PARQUET_BUILD_STATIC |
| "Build the static version of libparquet. Always ON if building unit tests" |
| ON) |
| set(PARQUET_ARROW_LINKAGE "shared" CACHE STRING |
| "Libraries to link for Apache Arrow. static|shared (default shared)") |
| set(PARQUET_CXXFLAGS "" CACHE STRING |
| "Compiler flags to use when compiling Parquet") |
| option(PARQUET_USE_SSE |
| "Build with SSE4 optimizations" |
| OFF) |
| option(PARQUET_BUILD_BENCHMARKS |
| "Build the libparquet benchmark suite" |
| OFF) |
| |
| set(PARQUET_BUILD_WARNING_LEVEL "PRODUCTION" CACHE STRING |
| "Levels of compiler warnings for development: PRODUCTION/CHECKIN/EVERYTHING") |
| |
| option(PARQUET_BOOST_USE_SHARED |
| "Rely on boost shared libraries where relevant" |
| ON) |
| option(PARQUET_BUILD_TESTS |
| "Build the libparquet test suite" |
| ON) |
| option(PARQUET_TEST_MEMCHECK |
| "Run the test suite using valgrind --tool=memcheck" |
| OFF) |
| option(PARQUET_BUILD_EXECUTABLES |
| "Build the libparquet executable CLI tools" |
| ON) |
| option(PARQUET_RPATH_ORIGIN |
| "Build Parquet libraries with RPATH set to \$ORIGIN" |
| OFF) |
| option(PARQUET_MINIMAL_DEPENDENCY |
| "Depend only on Thirdparty headers to build libparquet. Always OFF if building binaries" |
| OFF) |
| |
| option(PARQUET_THRIFT_USE_BOOST |
| "Enable if Thirdparty Thrift uses boost::shared_ptr (Apache Thrift < 0.11)" |
| OFF) |
| |
| if (MSVC) |
| set(ARROW_MSVC_STATIC_LIB_SUFFIX "_static" CACHE STRING |
| "Arrow static lib suffix used on Windows with MSVC (default _static)") |
| set(THRIFT_MSVC_STATIC_LIB_SUFFIX "md" CACHE STRING |
| "Thrift static lib suffix used on Windows with MSVC (default md)") |
| option(PARQUET_USE_STATIC_CRT |
| "Build Parquet with statically linked CRT" |
| OFF) |
| endif() |
| |
| option(PARQUET_VERBOSE_THIRDPARTY_BUILD |
| "If off, output from ExternalProjects will be logged to files rather than shown" |
| OFF) |
| |
| endif() |
| |
| include(BuildUtils) |
| |
| if (PARQUET_BUILD_TESTS OR PARQUET_BUILD_EXECUTABLES OR PARQUET_BUILD_BENCHMARKS) |
| set(PARQUET_BUILD_STATIC ON) |
| set(PARQUET_MINIMAL_DEPENDENCY OFF) |
| endif() |
| |
| # If build in-source, create the latest symlink. If build out-of-source, which is |
| # preferred, simply output the binaries in the build folder |
| if (${CMAKE_SOURCE_DIR} STREQUAL "${CMAKE_CURRENT_BINARY_DIR}") |
| set(BUILD_OUTPUT_ROOT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/build/${BUILD_SUBDIR_NAME}") |
| # Link build/latest to the current build directory, to avoid developers |
| # accidentally running the latest debug build when in fact they're building |
| # release builds. |
| FILE(MAKE_DIRECTORY ${BUILD_OUTPUT_ROOT_DIRECTORY}) |
| if (NOT APPLE) |
| set(MORE_ARGS "-T") |
| endif() |
| EXECUTE_PROCESS(COMMAND ln ${MORE_ARGS} -sf ${BUILD_OUTPUT_ROOT_DIRECTORY} |
| ${CMAKE_CURRENT_BINARY_DIR}/build/latest) |
| else() |
| set(BUILD_OUTPUT_ROOT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${BUILD_SUBDIR_NAME}") |
| endif() |
| |
| # where to put generated archives (.a files) |
| set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${BUILD_OUTPUT_ROOT_DIRECTORY}") |
| set(ARCHIVE_OUTPUT_DIRECTORY "${BUILD_OUTPUT_ROOT_DIRECTORY}") |
| |
| # where to put generated libraries (.so files) |
| set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${BUILD_OUTPUT_ROOT_DIRECTORY}") |
| set(LIBRARY_OUTPUT_DIRECTORY "${BUILD_OUTPUT_ROOT_DIRECTORY}") |
| |
| # where to put generated binaries |
| set(EXECUTABLE_OUTPUT_PATH "${BUILD_OUTPUT_ROOT_DIRECTORY}") |
| |
| if (MSVC) |
| # define output directories to overwrite default Visual Studio generator output directories |
| FOREACH(BUILD_CONFIG ${CMAKE_CONFIGURATION_TYPES}) |
| string(TOUPPER ${BUILD_CONFIG} UPPERCASE_BUILD_CONFIG) |
| set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_${UPPERCASE_BUILD_CONFIG} ${BUILD_OUTPUT_ROOT_DIRECTORY}) |
| set(CMAKE_PDB_OUTPUT_DIRECTORY_${UPPERCASE_BUILD_CONFIG} ${BUILD_OUTPUT_ROOT_DIRECTORY}) |
| set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${UPPERCASE_BUILD_CONFIG} ${BUILD_OUTPUT_ROOT_DIRECTORY}) |
| set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_${UPPERCASE_BUILD_CONFIG} ${BUILD_OUTPUT_ROOT_DIRECTORY}) |
| ENDFOREACH() |
| endif() |
| |
| ############################################################ |
| # Benchmarking |
| ############################################################ |
| # Add a new micro benchmark, with or without an executable that should be built. |
| # If benchmarks are enabled then they will be run along side unit tests with ctest. |
| # 'make runbenchmark' and 'make unittest' to build/run only benchmark or unittests, |
| # respectively. |
| # |
| # REL_BENCHMARK_NAME is the name of the benchmark app. It may be a single component |
| # (e.g. monotime-benchmark) or contain additional components (e.g. |
| # net/net_util-benchmark). Either way, the last component must be a globally |
| # unique name. |
| |
| # The benchmark will registered as unit test with ctest with a label |
| # of 'benchmark'. |
| # |
| # Arguments after the test name will be passed to set_tests_properties(). |
| function(ADD_PARQUET_BENCHMARK REL_BENCHMARK_NAME) |
| if(NOT PARQUET_BUILD_BENCHMARKS) |
| return() |
| endif() |
| get_filename_component(BENCHMARK_NAME ${REL_BENCHMARK_NAME} NAME_WE) |
| |
| if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${REL_BENCHMARK_NAME}.cc) |
| # This benchmark has a corresponding .cc file, set it up as an executable. |
| set(BENCHMARK_PATH "${EXECUTABLE_OUTPUT_PATH}/${BENCHMARK_NAME}") |
| add_executable(${BENCHMARK_NAME} "${REL_BENCHMARK_NAME}.cc") |
| |
| if(APPLE) |
| # On OS X / Thrift >= 0.9.2, tr1/tuple.h is not in libc++ |
| SET_TARGET_PROPERTIES(${TEST_NAME} PROPERTIES COMPILE_FLAGS |
| -DGTEST_USE_OWN_TR1_TUPLE=1) |
| else() |
| # Linux, for Thrift >= 0.9.2 |
| SET_TARGET_PROPERTIES(${TEST_NAME} PROPERTIES COMPILE_FLAGS |
| -DGTEST_USE_OWN_TR1_TUPLE=0) |
| endif() |
| |
| target_link_libraries(${BENCHMARK_NAME} ${PARQUET_BENCHMARK_LINK_LIBS}) |
| add_dependencies(runbenchmark ${BENCHMARK_NAME}) |
| set(NO_COLOR "--color_print=false") |
| else() |
| # No executable, just invoke the benchmark (probably a script) directly. |
| set(BENCHMARK_PATH ${CMAKE_CURRENT_SOURCE_DIR}/${REL_BENCHMARK_NAME}) |
| set(NO_COLOR "") |
| endif() |
| |
| if(WIN32) |
| add_test(${BENCHMARK_NAME} ${BENCHMARK_PATH} ${NO_COLOR}) |
| else() |
| add_test(${BENCHMARK_NAME} |
| ${BUILD_SUPPORT_DIR}/run-test.sh ${CMAKE_BINARY_DIR} benchmark ${BENCHMARK_PATH} ${NO_COLOR}) |
| endif() |
| set_tests_properties(${BENCHMARK_NAME} PROPERTIES LABELS "benchmark") |
| if(ARGN) |
| set_tests_properties(${BENCHMARK_NAME} PROPERTIES ${ARGN}) |
| endif() |
| endfunction() |
| |
| # A wrapper for add_dependencies() that is compatible with NO_BENCHMARKS. |
| function(ADD_PARQUET_BENCHMARK_DEPENDENCIES REL_BENCHMARK_NAME) |
| if(NOT PARQUET_BUILD_BENCHMARKS) |
| return() |
| endif() |
| get_filename_component(BENCMARK_NAME ${REL_BENCHMARK_NAME} NAME_WE) |
| |
| add_dependencies(${BENCHMARK_NAME} ${ARGN}) |
| endfunction() |
| |
| ############################################################ |
| # Testing |
| ############################################################ |
| |
| # Add a new test case, with or without an executable that should be built. |
| # |
| # REL_TEST_NAME is the name of the test. It may be a single component |
| # (e.g. monotime-test) or contain additional components (e.g. |
| # net/net_util-test). Either way, the last component must be a globally |
| # unique name. |
| # |
| # The unit test is added with a label of "unittest" to support filtering with |
| # ctest. |
| # |
| # Arguments after the test name will be passed to set_tests_properties(). |
| function(ADD_PARQUET_TEST REL_TEST_NAME) |
| set(options) |
| set(one_value_args LINKAGE) |
| set(multi_value_args) |
| cmake_parse_arguments(ARG "${options}" "${one_value_args}" "${multi_value_args}" ${ARGN}) |
| |
| if(NOT PARQUET_BUILD_TESTS) |
| return() |
| endif() |
| |
| # TODO(wesm): not very rigorous error checking |
| if (ARG_LINKAGE AND "${ARG_LINKAGE}" STREQUAL "shared") |
| if(NOT PARQUET_BUILD_SHARED) |
| # Skip this test if we are not building the shared library |
| return() |
| else() |
| set(TEST_LINK_LIBS ${PARQUET_TEST_SHARED_LINK_LIBS}) |
| endif() |
| else() |
| set(TEST_LINK_LIBS ${PARQUET_TEST_LINK_LIBS}) |
| endif() |
| |
| get_filename_component(TEST_NAME ${REL_TEST_NAME} NAME_WE) |
| |
| if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${REL_TEST_NAME}.cc) |
| # This test has a corresponding .cc file, set it up as an executable. |
| set(TEST_PATH "${EXECUTABLE_OUTPUT_PATH}/${TEST_NAME}") |
| add_executable(${TEST_NAME} "${REL_TEST_NAME}.cc") |
| add_dependencies(unittest ${TEST_NAME}) |
| |
| if(APPLE) |
| # On OS X / Thrift >= 0.9.2, tr1/tuple.h is not in libc++ |
| SET_TARGET_PROPERTIES(${TEST_NAME} PROPERTIES COMPILE_FLAGS |
| -DGTEST_USE_OWN_TR1_TUPLE=1) |
| else() |
| # Linux, for Thrift >= 0.9.2 |
| SET_TARGET_PROPERTIES(${TEST_NAME} PROPERTIES COMPILE_FLAGS |
| -DGTEST_USE_OWN_TR1_TUPLE=0) |
| endif() |
| |
| target_link_libraries(${TEST_NAME} ${TEST_LINK_LIBS}) |
| else() |
| # No executable, just invoke the test (probably a script) directly. |
| set(TEST_PATH ${CMAKE_CURRENT_SOURCE_DIR}/${REL_TEST_NAME}) |
| endif() |
| |
| if (PARQUET_TEST_MEMCHECK) |
| SET_PROPERTY(TARGET ${TEST_NAME} |
| APPEND_STRING PROPERTY |
| COMPILE_FLAGS " -DPARQUET_VALGRIND") |
| add_test(${TEST_NAME} |
| valgrind --tool=memcheck --leak-check=full --error-exitcode=1 ${TEST_PATH}) |
| elseif(MSVC) |
| add_test(${TEST_NAME} ${TEST_PATH}) |
| else() |
| add_test(${TEST_NAME} |
| ${BUILD_SUPPORT_DIR}/run-test.sh ${CMAKE_BINARY_DIR} test ${TEST_PATH}) |
| endif() |
| set_tests_properties(${TEST_NAME} PROPERTIES LABELS "unittest") |
| if(ARGN) |
| set_tests_properties(${TEST_NAME} PROPERTIES ${ARGN}) |
| endif() |
| endfunction() |
| |
| # A wrapper for add_dependencies() that is compatible with PARQUET_BUILD_TESTS. |
| function(ADD_PARQUET_TEST_DEPENDENCIES REL_TEST_NAME) |
| if(NOT PARQUET_BUILD_TESTS) |
| return() |
| endif() |
| get_filename_component(TEST_NAME ${REL_TEST_NAME} NAME_WE) |
| |
| add_dependencies(${TEST_NAME} ${ARGN}) |
| endfunction() |
| |
| # A wrapper for add_dependencies() that is compatible with PARQUET_BUILD_TESTS. |
| function(ADD_PARQUET_LINK_LIBRARIES REL_TEST_NAME) |
| if(NOT PARQUET_BUILD_TESTS) |
| return() |
| endif() |
| get_filename_component(TEST_NAME ${REL_TEST_NAME} NAME_WE) |
| |
| target_link_libraries(${TEST_NAME} ${ARGN}) |
| endfunction() |
| |
| enable_testing() |
| |
| ############################################################ |
| # Dependencies |
| ############################################################ |
| |
| # Determine compiler version |
| include(CompilerInfo) |
| include(SetupCxxFlags) |
| |
| include_directories(${CMAKE_CURRENT_BINARY_DIR}/src) |
| include_directories( |
| ${CMAKE_CURRENT_SOURCE_DIR}/src |
| ) |
| |
| if (PARQUET_MINIMAL_DEPENDENCY) |
| set(IGNORE_OPTIONAL_PACKAGES ON) |
| message(STATUS "Build using minimal dependencies") |
| else() |
| set(IGNORE_OPTIONAL_PACKAGES OFF) |
| endif() |
| include(ThirdpartyToolchain) |
| |
| set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX_COMMON_FLAGS}") |
| set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${PARQUET_CXXFLAGS}") |
| |
| message(STATUS "CMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS}") |
| |
| # Thrift requires these definitions for some types that we use |
| add_definitions(-DHAVE_INTTYPES_H -DHAVE_NETDB_H) |
| if (MSVC) |
| add_definitions(-DNOMINMAX -D_CRT_SECURE_NO_WARNINGS) |
| else() |
| add_definitions(-DHAVE_NETINET_IN_H -fPIC) |
| endif() |
| |
| ############################################################ |
| # "make lint" target |
| ############################################################ |
| if (UNIX) |
| find_program(CPPLINT_BIN NAMES cpplint cpplint.py HINTS ${BUILD_SUPPORT_DIR}) |
| message(STATUS "Found cpplint executable at ${CPPLINT_BIN}") |
| # Full lint |
| add_custom_target(lint ${CPPLINT_BIN} |
| --verbose=2 |
| --linelength=90 |
| --filter=-whitespace/comments,-readability/todo,-build/header_guard,-runtime/references,-readability/check,-build/c++11,-build/include_order |
| `find ${CMAKE_CURRENT_SOURCE_DIR}/src ${CMAKE_CURRENT_SOURCE_DIR}/tools ${CMAKE_CURRENT_SOURCE_DIR}/examples ${CMAKE_CURRENT_SOURCE_DIR}/benchmarks -name \\*.cc -or -name \\*.h | sed -e '/parquet\\/parquet_/g'`) |
| endif (UNIX) |
| |
| ############################################################ |
| # "make format" and "make check-format" targets |
| ############################################################ |
| |
| # runs clang format and updates files in place. |
| add_custom_target(format-example |
| COMMAND |
| ${BUILD_SUPPORT_DIR}/run_clang_format.py |
| ${CLANG_FORMAT_BIN} |
| ${BUILD_SUPPORT_DIR}/clang_format_exclusions.txt |
| ${CMAKE_CURRENT_SOURCE_DIR}/examples/parquet-arrow) |
| |
| add_custom_target(format |
| DEPENDS format-example |
| COMMAND |
| ${BUILD_SUPPORT_DIR}/run_clang_format.py |
| ${CLANG_FORMAT_BIN} |
| ${BUILD_SUPPORT_DIR}/clang_format_exclusions.txt |
| ${CMAKE_CURRENT_SOURCE_DIR}/src) |
| |
| # runs clang format and exits with a non-zero exit code if any files need to be reformatted |
| |
| # TODO(wesm): Make this work in run_clang_format.py |
| add_custom_target(check-format-examples ${BUILD_SUPPORT_DIR}/run_clang_format.py |
| ${CLANG_FORMAT_BIN} |
| ${BUILD_SUPPORT_DIR}/clang_format_exclusions.txt |
| ${CMAKE_CURRENT_SOURCE_DIR}/examples/parquet-arrow 1) |
| add_custom_target(check-format |
| DEPENDS check-format-examples |
| COMMAND |
| ${BUILD_SUPPORT_DIR}/run_clang_format.py |
| ${CLANG_FORMAT_BIN} |
| ${BUILD_SUPPORT_DIR}/clang_format_exclusions.txt |
| ${CMAKE_CURRENT_SOURCE_DIR}/src 1) |
| |
| ############################################################ |
| # "make clang-tidy" and "make check-clang-tidy" targets |
| ############################################################ |
| |
| if (${CLANG_TIDY_FOUND}) |
| # runs clang-tidy and attempts to fix any warning automatically |
| add_custom_target(clang-tidy ${BUILD_SUPPORT_DIR}/run-clang-tidy.sh ${CLANG_TIDY_BIN} ${CMAKE_BINARY_DIR}/compile_commands.json 1 |
| `find ${CMAKE_CURRENT_SOURCE_DIR}/src ${CMAKE_CURRENT_SOURCE_DIR}/tools ${CMAKE_CURRENT_SOURCE_DIR}/examples ${CMAKE_CURRENT_SOURCE_DIR}/benchmarks -name \\*.cc | sed -e '/_types/g' | sed -e '/_constants/g'`) |
| # runs clang-tidy and exits with a non-zero exit code if any errors are found. |
| add_custom_target(check-clang-tidy ${BUILD_SUPPORT_DIR}/run-clang-tidy.sh ${CLANG_TIDY_BIN} ${CMAKE_BINARY_DIR}/compile_commands.json |
| 0 `find ${CMAKE_CURRENT_SOURCE_DIR}/src ${CMAKE_CURRENT_SOURCE_DIR}/tools ${CMAKE_CURRENT_SOURCE_DIR}/examples ${CMAKE_CURRENT_SOURCE_DIR}/benchmarks -name \\*.cc |grep -v -F -f ${CMAKE_CURRENT_SOURCE_DIR}/.clang-tidy-ignore`) |
| |
| endif() |
| |
| ############################################################# |
| # Code coverage |
| |
| # Adapted from Apache Kudu (incubating) |
| if ("${PARQUET_GENERATE_COVERAGE}") |
| if("${CMAKE_CXX_COMPILER}" MATCHES ".*clang.*") |
| # There appears to be some bugs in clang 3.3 which cause code coverage |
| # to have link errors, not locating the llvm_gcda_* symbols. |
| # This should be fixed in llvm 3.4 with http://llvm.org/viewvc/llvm-project?view=revision&revision=184666 |
| message(SEND_ERROR "Cannot currently generate coverage with clang") |
| endif() |
| message(STATUS "Configuring build for gcov") |
| set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --coverage") |
| # For coverage to work properly, we need to use static linkage. Otherwise, |
| # __gcov_flush() doesn't properly flush coverage from every module. |
| # See http://stackoverflow.com/questions/28164543/using-gcov-flush-within-a-library-doesnt-force-the-other-modules-to-yield-gc |
| if(NOT PARQUET_BUILD_STATIC) |
| message(SEND_ERROR "Coverage requires the static lib to be built") |
| endif() |
| endif() |
| |
| ############################################################# |
| # Boost linkage |
| |
| if (PARQUET_BOOST_USE_SHARED) |
| set(BOOST_LINK_LIBS |
| boost_shared_regex) |
| if(MSVC) |
| set(BOOST_LINK_LIBS ${BOOST_LINK_LIBS} |
| boost_shared_system) |
| endif() |
| else() |
| set(BOOST_LINK_LIBS |
| boost_static_regex) |
| if(MSVC) |
| set(BOOST_LINK_LIBS ${BOOST_LINK_LIBS} |
| boost_static_system boost_static_filesystem) |
| endif() |
| endif() |
| |
| ############################################################# |
| # Apache Arrow linkage |
| |
| if ("${PARQUET_ARROW_LINKAGE}" STREQUAL "shared") |
| set(ARROW_LINK_LIBS |
| arrow) |
| else() |
| ############################################################# |
| # Transitive Library Linkage |
| |
| if (NOT DEFINED ENV{BROTLI_STATIC_LIB_ENC} OR |
| NOT DEFINED ENV{BROTLI_STATIC_LIB_DEC} OR |
| NOT DEFINED ENV{BROTLI_STATIC_LIB_COMMON} OR |
| NOT DEFINED ENV{SNAPPY_STATIC_LIB} OR |
| NOT DEFINED ENV{ZLIB_STATIC_LIB} OR |
| NOT DEFINED ENV{LZ4_STATIC_LIB} OR |
| NOT DEFINED ENV{ZSTD_STATIC_LIB}) |
| message(FATAL_ERROR "Missing transitive dependencies for Arrow static linking") |
| endif() |
| |
| set(BROTLI_STATIC_LIB_ENC "$ENV{BROTLI_STATIC_LIB_ENC}") |
| set(BROTLI_STATIC_LIB_DEC "$ENV{BROTLI_STATIC_LIB_DEC}") |
| set(BROTLI_STATIC_LIB_COMMON "$ENV{BROTLI_STATIC_LIB_COMMON}") |
| set(SNAPPY_STATIC_LIB "$ENV{SNAPPY_STATIC_LIB}") |
| set(ZLIB_STATIC_LIB "$ENV{ZLIB_STATIC_LIB}") |
| set(LZ4_STATIC_LIB "$ENV{LZ4_STATIC_LIB}") |
| set(ZSTD_STATIC_LIB "$ENV{ZSTD_STATIC_LIB}") |
| |
| add_library(brotli_enc STATIC IMPORTED) |
| set_target_properties(brotli_enc PROPERTIES IMPORTED_LOCATION ${BROTLI_STATIC_LIB_ENC}) |
| add_library(brotli_dec STATIC IMPORTED) |
| set_target_properties(brotli_dec PROPERTIES IMPORTED_LOCATION ${BROTLI_STATIC_LIB_DEC}) |
| add_library(brotli_common STATIC IMPORTED) |
| set_target_properties(brotli_common PROPERTIES IMPORTED_LOCATION ${BROTLI_STATIC_LIB_COMMON}) |
| add_library(snappy STATIC IMPORTED) |
| set_target_properties(snappy PROPERTIES IMPORTED_LOCATION ${SNAPPY_STATIC_LIB}) |
| add_library(zlib STATIC IMPORTED) |
| set_target_properties(zlib PROPERTIES IMPORTED_LOCATION ${ZLIB_STATIC_LIB}) |
| add_library(lz4 STATIC IMPORTED) |
| set_target_properties(lz4 PROPERTIES IMPORTED_LOCATION ${LZ4_STATIC_LIB}) |
| add_library(zstd STATIC IMPORTED) |
| set_target_properties(zstd PROPERTIES IMPORTED_LOCATION ${ZSTD_STATIC_LIB}) |
| |
| set(TRANSITIVE_LINK_LIBS |
| snappy |
| zlib |
| brotli_enc |
| brotli_dec |
| brotli_common |
| lz4 |
| zstd |
| ) |
| |
| add_definitions(-DARROW_EXPORTING) |
| |
| set(ARROW_LINK_LIBS |
| arrow_static |
| ${TRANSITIVE_LINK_LIBS}) |
| endif() |
| |
| ############################################################# |
| # Test linking |
| |
| set(PARQUET_MIN_TEST_LIBS |
| gtest |
| gtest_main) |
| |
| if (APPLE) |
| set(PARQUET_MIN_TEST_LIBS |
| ${PARQUET_MIN_TEST_LIBS} |
| ${CMAKE_DL_LIBS}) |
| elseif(NOT MSVC) |
| set(PARQUET_MIN_TEST_LIBS |
| ${PARQUET_MIN_TEST_LIBS} |
| pthread |
| ${CMAKE_DL_LIBS}) |
| endif() |
| |
| set(PARQUET_TEST_LINK_LIBS ${PARQUET_MIN_TEST_LIBS} |
| ${ARROW_LINK_LIBS} |
| parquet_static) |
| |
| set(PARQUET_TEST_SHARED_LINK_LIBS ${PARQUET_MIN_TEST_LIBS} |
| parquet_shared) |
| |
| ############################################################# |
| # Benchmark linking |
| |
| if (PARQUET_BUILD_STATIC) |
| set(PARQUET_BENCHMARK_LINK_LIBS |
| parquet_benchmark_main |
| parquet_static) |
| else() |
| set(PARQUET_BENCHMARK_LINK_LIBS |
| parquet_benchmark_main |
| parquet_shared) |
| endif() |
| |
| ############################################################ |
| # Generated Thrift sources |
| |
| set(THRIFT_SRCS |
| src/parquet/parquet_constants.cpp |
| src/parquet/parquet_types.cpp) |
| |
| if (NOT MSVC) |
| set_source_files_properties(src/parquet/parquet_types.cpp PROPERTIES |
| COMPILE_FLAGS -Wno-unused-variable) |
| endif() |
| |
| # List of thrift output targets |
| set(THRIFT_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/src/parquet) |
| set(THRIFT_OUTPUT_FILES "${THRIFT_OUTPUT_DIR}/parquet_types.cpp") |
| set(THRIFT_OUTPUT_FILES ${THRIFT_OUTPUT_FILES} "${THRIFT_OUTPUT_DIR}/parquet_types.h") |
| set(THRIFT_OUTPUT_FILES ${THRIFT_OUTPUT_FILES} "${THRIFT_OUTPUT_DIR}/parquet_constants.cpp") |
| set(THRIFT_OUTPUT_FILES ${THRIFT_OUTPUT_FILES} "${THRIFT_OUTPUT_DIR}/parquet_constants.h") |
| |
| set_source_files_properties(${THRIFT_OUTPUT_FILES} PROPERTIES GENERATED TRUE) |
| |
| get_filename_component(ABS_PARQUET_THRIFT src/parquet/parquet.thrift ABSOLUTE) |
| |
| add_custom_command( |
| OUTPUT ${THRIFT_OUTPUT_FILES} |
| COMMAND ${THRIFT_COMPILER} --gen cpp -out ${THRIFT_OUTPUT_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/src/parquet/parquet.thrift |
| DEPENDS ${ABS_PARQUET_THRIFT} thriftstatic |
| COMMENT "Running thrift compiler on parquet.thrift" |
| VERBATIM |
| ) |
| |
| ############################################################ |
| # Library config |
| |
| set(LIBPARQUET_SRCS |
| src/parquet/arrow/reader.cc |
| src/parquet/arrow/record_reader.cc |
| src/parquet/arrow/schema.cc |
| src/parquet/arrow/writer.cc |
| src/parquet/column_reader.cc |
| src/parquet/column_scanner.cc |
| src/parquet/column_writer.cc |
| src/parquet/exception.cc |
| src/parquet/file_reader.cc |
| src/parquet/file_writer.cc |
| src/parquet/metadata.cc |
| src/parquet/parquet_constants.cpp |
| src/parquet/parquet_types.cpp |
| src/parquet/printer.cc |
| src/parquet/schema.cc |
| src/parquet/statistics.cc |
| src/parquet/types.cc |
| src/parquet/util/comparison.cc |
| src/parquet/util/memory.cc |
| ) |
| |
| # # Ensure that thrift compilation is done before using its generated headers |
| # # in parquet code. |
| add_custom_target(thrift-deps ALL |
| DEPENDS ${THRIFT_OUTPUT_FILES}) |
| set(PARQUET_DEPENDENCIES ${PARQUET_DEPENDENCIES} thrift-deps) |
| |
| if (NOT PARQUET_MINIMAL_DEPENDENCY) |
| # These are libraries that we will link privately with parquet_shared (as they |
| # do not need to be linked transitively by other linkers), but publicly with |
| # parquet_static (because internal users need to transitively link all |
| # dependencies) |
| set(LIBPARQUET_INTERFACE_LINK_LIBS |
| ${ARROW_LINK_LIBS} |
| ${BOOST_LINK_LIBS} |
| thriftstatic |
| ) |
| # Although we don't link parquet_objlib against anything, we need it to depend |
| # on these libs as we may generate their headers via ExternalProject_Add |
| set(PARQUET_DEPENDENCIES ${PARQUET_DEPENDENCIES} ${LIBPARQUET_INTERFACE_LINK_LIBS}) |
| endif() |
| |
| if(NOT APPLE AND NOT MSVC) |
| # Localize thirdparty symbols using a linker version script. This hides them |
| # from the client application. The OS X linker does not support the |
| # version-script option. |
| set(SHARED_LINK_FLAGS "-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/src/parquet/symbols.map") |
| endif() |
| |
| ADD_LIB(parquet |
| SOURCES ${LIBPARQUET_SRCS} |
| LIB_BUILD_SHARED ${PARQUET_BUILD_SHARED} |
| LIB_BUILD_STATIC ${PARQUET_BUILD_STATIC} |
| DEPENDENCIES ${PARQUET_DEPENDENCIES} |
| SHARED_LINK_FLAGS ${SHARED_LINK_FLAGS} |
| SHARED_PRIVATE_LINK_LIBS ${LIBPARQUET_INTERFACE_LINK_LIBS} |
| STATIC_LINK_LIBS ${LIBPARQUET_INTERFACE_LINK_LIBS} |
| ABI_VERSION ${PARQUET_ABI_VERSION} |
| SO_VERSION ${PARQUET_SO_VERSION} |
| LIB_RPATH_ORIGIN ${PARQUET_RPATH_ORIGIN} |
| ) |
| |
| ############################################################ |
| # Visibility |
| ############################################################ |
| # For generate_export_header() and add_compiler_export_flags(). |
| include(GenerateExportHeader) |
| |
| # Adapted from Apache Kudu: https://github.com/apache/kudu/commit/bd549e13743a51013585 |
| # Honor visibility properties for all target types. See |
| # "cmake --help-policy CMP0063" for details. |
| # |
| # This policy was only added to cmake in version 3.3, so until the cmake in |
| # thirdparty is updated, we must check if the policy exists before setting it. |
| if(POLICY CMP0063) |
| cmake_policy(SET CMP0063 NEW) |
| endif() |
| |
| if (PARQUET_BUILD_SHARED) |
| if (POLICY CMP0063) |
| set_target_properties(parquet_shared |
| PROPERTIES C_VISIBILITY_PRESET hidden) |
| set_target_properties(parquet_shared |
| PROPERTIES CXX_VISIBILITY_PRESET hidden) |
| set_target_properties(parquet_shared |
| PROPERTIES VISIBILITY_INLINES_HIDDEN 1) |
| else() |
| # Sets -fvisibility=hidden for gcc |
| add_compiler_export_flags() |
| endif() |
| endif() |
| |
| add_subdirectory(src/parquet) |
| add_subdirectory(src/parquet/api) |
| add_subdirectory(src/parquet/arrow) |
| add_subdirectory(src/parquet/util) |
| |
| if (NOT MSVC) |
| add_subdirectory(benchmarks) |
| endif() |
| add_subdirectory(examples/low-level-api) |
| add_subdirectory(tools) |
| |
| add_custom_target(clean-all |
| COMMAND ${CMAKE_BUILD_TOOL} clean |
| COMMAND ${CMAKE_COMMAND} -P cmake_modules/clean-all.cmake |
| ) |