mirror of
https://github.com/apache/arrow.git
synced 2026-10-29 00:56:31 +08:00
### Rationale for this change `find_package()`'s `VALIDATOR`'s result variable must be initialized to `TRUE` by caller. We reuse the `VALIDATOR` (`validate_apple_libtool()`) when we specify `CMAKE_LIBTOOL` explicitly. But we didn't initialize the result variable to `TRUE`. ### What changes are included in this PR? Initialize `is_apple_libtool` explicitly. ### Are these changes tested? Yes. ### Are there any user-facing changes? Yes. * GitHub Issue: #49974 Authored-by: Sutou Kouhei <kou@clear-code.com> Signed-off-by: Sutou Kouhei <kou@clear-code.com>
986 lines
34 KiB
CMake
986 lines
34 KiB
CMake
# 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.
|
|
|
|
# Common path suffixes to be searched by find_library or find_path.
|
|
# Windows artifacts may be found under "<root>/Library", so
|
|
# search there as well.
|
|
set(ARROW_LIBRARY_PATH_SUFFIXES
|
|
"${CMAKE_LIBRARY_ARCHITECTURE}"
|
|
"lib/${CMAKE_LIBRARY_ARCHITECTURE}"
|
|
"lib64"
|
|
"lib32"
|
|
"lib"
|
|
"bin"
|
|
"Library"
|
|
"Library/lib"
|
|
"Library/bin")
|
|
set(ARROW_INCLUDE_PATH_SUFFIXES "include" "Library" "Library/include")
|
|
|
|
function(add_thirdparty_lib LIB_NAME LIB_TYPE LIB)
|
|
set(options)
|
|
set(one_value_args)
|
|
set(multi_value_args DEPS INCLUDE_DIRECTORIES)
|
|
cmake_parse_arguments(ARG
|
|
"${options}"
|
|
"${one_value_args}"
|
|
"${multi_value_args}"
|
|
${ARGN})
|
|
if(ARG_UNPARSED_ARGUMENTS)
|
|
message(SEND_ERROR "Error: unrecognized arguments: ${ARG_UNPARSED_ARGUMENTS}")
|
|
endif()
|
|
|
|
add_library(${LIB_NAME} ${LIB_TYPE} IMPORTED)
|
|
if(${LIB_TYPE} STREQUAL "STATIC")
|
|
set_target_properties(${LIB_NAME} PROPERTIES IMPORTED_LOCATION "${LIB}")
|
|
message(STATUS "Added static library dependency ${LIB_NAME}: ${LIB}")
|
|
else()
|
|
if(WIN32)
|
|
# Mark the ".lib" location as part of a Windows DLL
|
|
set_target_properties(${LIB_NAME} PROPERTIES IMPORTED_IMPLIB "${LIB}")
|
|
else()
|
|
set_target_properties(${LIB_NAME} PROPERTIES IMPORTED_LOCATION "${LIB}")
|
|
endif()
|
|
message(STATUS "Added shared library dependency ${LIB_NAME}: ${LIB}")
|
|
endif()
|
|
if(ARG_DEPS)
|
|
set_target_properties(${LIB_NAME} PROPERTIES INTERFACE_LINK_LIBRARIES "${ARG_DEPS}")
|
|
endif()
|
|
if(ARG_INCLUDE_DIRECTORIES)
|
|
set_target_properties(${LIB_NAME} PROPERTIES INTERFACE_INCLUDE_DIRECTORIES
|
|
"${ARG_INCLUDE_DIRECTORIES}")
|
|
endif()
|
|
endfunction()
|
|
|
|
# Based on MIT-licensed
|
|
# https://gist.github.com/cristianadam/ef920342939a89fae3e8a85ca9459b49
|
|
function(arrow_create_merged_static_lib output_target)
|
|
set(options)
|
|
set(one_value_args NAME ROOT)
|
|
set(multi_value_args TO_MERGE)
|
|
cmake_parse_arguments(ARG
|
|
"${options}"
|
|
"${one_value_args}"
|
|
"${multi_value_args}"
|
|
${ARGN})
|
|
if(ARG_UNPARSED_ARGUMENTS)
|
|
message(SEND_ERROR "Error: unrecognized arguments: ${ARG_UNPARSED_ARGUMENTS}")
|
|
endif()
|
|
|
|
file(MAKE_DIRECTORY ${BUILD_OUTPUT_ROOT_DIRECTORY})
|
|
set(output_lib_path
|
|
${BUILD_OUTPUT_ROOT_DIRECTORY}${CMAKE_STATIC_LIBRARY_PREFIX}${ARG_NAME}${CMAKE_STATIC_LIBRARY_SUFFIX}
|
|
)
|
|
|
|
set(all_library_paths $<TARGET_FILE:${ARG_ROOT}>)
|
|
foreach(lib ${ARG_TO_MERGE})
|
|
list(APPEND all_library_paths $<TARGET_FILE:${lib}>)
|
|
endforeach()
|
|
|
|
if(APPLE)
|
|
# Get the version string from a libtool binary.
|
|
function(get_libtool_version item result_var)
|
|
execute_process(COMMAND "${item}" -V
|
|
OUTPUT_VARIABLE _version
|
|
OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET)
|
|
set(${result_var}
|
|
"${_version}"
|
|
PARENT_SCOPE)
|
|
endfunction()
|
|
|
|
# Validator function to confirm that the libtool is Apple's libtool.
|
|
# The apple-distributed libtool is what we want for bundling, but there is
|
|
# a GNU libtool that has a name collision (and happens to be bundled with R, too).
|
|
# We are not compatible with GNU libtool, so we need to avoid it.
|
|
function(validate_apple_libtool result_var item)
|
|
get_libtool_version("${item}" libtool_version)
|
|
if(NOT "${libtool_version}" MATCHES ".*cctools.+([0-9.]+).*")
|
|
set(${result_var}
|
|
FALSE
|
|
PARENT_SCOPE)
|
|
endif()
|
|
endfunction()
|
|
|
|
if(CMAKE_LIBTOOL)
|
|
set(LIBTOOL_MACOS ${CMAKE_LIBTOOL})
|
|
# Validate that CMAKE_LIBTOOL is Apple's libtool
|
|
set(is_apple_libtool TRUE)
|
|
validate_apple_libtool(is_apple_libtool "${LIBTOOL_MACOS}")
|
|
if(NOT is_apple_libtool)
|
|
get_libtool_version("${LIBTOOL_MACOS}" _libtool_version_output)
|
|
message(FATAL_ERROR "CMAKE_LIBTOOL does not appear to be Apple's libtool: ${LIBTOOL_MACOS}\nlibtool -V output: ${_libtool_version_output}"
|
|
)
|
|
endif()
|
|
else()
|
|
# Check in the obvious places first to find Apple's libtool
|
|
# HINTS is used before system paths and before PATHS, so we use that
|
|
# even though hard coded paths should go in PATHS
|
|
find_program(LIBTOOL_MACOS libtool
|
|
HINTS /usr/bin /Library/Developer/CommandLineTools/usr/bin VALIDATOR
|
|
validate_apple_libtool)
|
|
if(NOT LIBTOOL_MACOS)
|
|
# Find any libtool (without validation) to show its version in the error
|
|
find_program(_any_libtool libtool)
|
|
if(_any_libtool)
|
|
get_libtool_version("${_any_libtool}" _libtool_version_output)
|
|
endif()
|
|
message(FATAL_ERROR "Could not find Apple's libtool. GNU libtool is not compatible."
|
|
"\nFound libtool: ${_any_libtool}"
|
|
"\nlibtool -V output: ${_libtool_version_output}")
|
|
endif()
|
|
endif()
|
|
|
|
set(BUNDLE_COMMAND ${LIBTOOL_MACOS} "-no_warning_for_no_symbols" "-static" "-o"
|
|
${output_lib_path} ${all_library_paths})
|
|
elseif(MSVC)
|
|
if(CMAKE_LIBTOOL)
|
|
set(BUNDLE_TOOL ${CMAKE_LIBTOOL})
|
|
else()
|
|
find_program(BUNDLE_TOOL lib HINTS "${CMAKE_CXX_COMPILER}/..")
|
|
if(NOT BUNDLE_TOOL)
|
|
message(FATAL_ERROR "Cannot locate lib.exe to bundle libraries")
|
|
endif()
|
|
endif()
|
|
set(BUNDLE_COMMAND ${BUNDLE_TOOL} /NOLOGO /OUT:${output_lib_path}
|
|
${all_library_paths})
|
|
elseif(CMAKE_CXX_COMPILER_ID MATCHES "^(Clang|GNU|Intel|IntelLLVM)$")
|
|
set(ar_script_path ${CMAKE_BINARY_DIR}/${ARG_NAME}.ar)
|
|
|
|
file(WRITE ${ar_script_path}.in "CREATE ${output_lib_path}\n")
|
|
file(APPEND ${ar_script_path}.in "ADDLIB $<TARGET_FILE:${ARG_ROOT}>\n")
|
|
|
|
foreach(lib ${ARG_TO_MERGE})
|
|
file(APPEND ${ar_script_path}.in "ADDLIB $<TARGET_FILE:${lib}>\n")
|
|
endforeach()
|
|
|
|
file(APPEND ${ar_script_path}.in "SAVE\nEND\n")
|
|
file(GENERATE
|
|
OUTPUT ${ar_script_path}
|
|
INPUT ${ar_script_path}.in)
|
|
set(ar_tool ${CMAKE_AR})
|
|
|
|
if(CMAKE_INTERPROCEDURAL_OPTIMIZATION)
|
|
set(ar_tool ${CMAKE_CXX_COMPILER_AR})
|
|
endif()
|
|
|
|
set(BUNDLE_COMMAND ${ar_tool} -M < ${ar_script_path})
|
|
else()
|
|
message(FATAL_ERROR "Unknown bundle scenario!")
|
|
endif()
|
|
|
|
add_custom_target(${output_target}_merge ALL
|
|
${BUNDLE_COMMAND}
|
|
DEPENDS ${ARG_ROOT} ${ARG_TO_MERGE}
|
|
BYPRODUCTS ${output_lib_path}
|
|
COMMENT "Bundling ${output_lib_path}"
|
|
VERBATIM)
|
|
|
|
message(STATUS "Creating bundled static library target ${output_target} at ${output_lib_path}"
|
|
)
|
|
|
|
add_library(${output_target} STATIC IMPORTED GLOBAL)
|
|
set_target_properties(${output_target} PROPERTIES IMPORTED_LOCATION ${output_lib_path})
|
|
add_dependencies(${output_target} ${output_target}_merge)
|
|
endfunction()
|
|
|
|
function(arrow_install_cmake_package PACKAGE_NAME EXPORT_NAME)
|
|
set(CONFIG_CMAKE "${PACKAGE_NAME}Config.cmake")
|
|
set(BUILT_CONFIG_CMAKE "${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_CMAKE}")
|
|
configure_package_config_file("${CONFIG_CMAKE}.in" "${BUILT_CONFIG_CMAKE}"
|
|
INSTALL_DESTINATION "${ARROW_CMAKE_DIR}/${PACKAGE_NAME}")
|
|
set(CONFIG_VERSION_CMAKE "${PACKAGE_NAME}ConfigVersion.cmake")
|
|
set(BUILT_CONFIG_VERSION_CMAKE "${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_VERSION_CMAKE}")
|
|
write_basic_package_version_file("${BUILT_CONFIG_VERSION_CMAKE}"
|
|
COMPATIBILITY SameMajorVersion)
|
|
install(FILES "${BUILT_CONFIG_CMAKE}" "${BUILT_CONFIG_VERSION_CMAKE}"
|
|
DESTINATION "${ARROW_CMAKE_DIR}/${PACKAGE_NAME}")
|
|
set(TARGETS_CMAKE "${PACKAGE_NAME}Targets.cmake")
|
|
install(EXPORT ${EXPORT_NAME}
|
|
DESTINATION "${ARROW_CMAKE_DIR}/${PACKAGE_NAME}"
|
|
NAMESPACE "${PACKAGE_NAME}::"
|
|
FILE "${TARGETS_CMAKE}")
|
|
endfunction()
|
|
|
|
# \arg OUTPUTS list to append built targets to
|
|
function(ADD_ARROW_LIB LIB_NAME)
|
|
set(options)
|
|
set(one_value_args
|
|
BUILD_SHARED
|
|
BUILD_STATIC
|
|
CMAKE_PACKAGE_NAME
|
|
INSTALL_ARCHIVE_DIR
|
|
INSTALL_LIBRARY_DIR
|
|
INSTALL_RUNTIME_DIR
|
|
PKG_CONFIG_NAME
|
|
SHARED_LINK_FLAGS)
|
|
set(multi_value_args
|
|
SOURCES
|
|
OUTPUTS
|
|
STATIC_LINK_LIBS
|
|
SHARED_LINK_LIBS
|
|
SHARED_PRIVATE_LINK_LIBS
|
|
EXTRA_INCLUDES
|
|
PRIVATE_INCLUDES
|
|
DEPENDENCIES
|
|
DEFINITIONS
|
|
SHARED_INSTALL_INTERFACE_LIBS
|
|
STATIC_INSTALL_INTERFACE_LIBS
|
|
OUTPUT_PATH)
|
|
cmake_parse_arguments(ARG
|
|
"${options}"
|
|
"${one_value_args}"
|
|
"${multi_value_args}"
|
|
${ARGN})
|
|
if(ARG_UNPARSED_ARGUMENTS)
|
|
message(SEND_ERROR "Error: unrecognized arguments: ${ARG_UNPARSED_ARGUMENTS}")
|
|
endif()
|
|
|
|
if(ARG_OUTPUTS)
|
|
set(${ARG_OUTPUTS})
|
|
endif()
|
|
|
|
# Allow overriding ARROW_BUILD_SHARED and ARROW_BUILD_STATIC
|
|
if(DEFINED ARG_BUILD_SHARED)
|
|
set(BUILD_SHARED ${ARG_BUILD_SHARED})
|
|
else()
|
|
set(BUILD_SHARED ${ARROW_BUILD_SHARED})
|
|
endif()
|
|
if(DEFINED ARG_BUILD_STATIC)
|
|
set(BUILD_STATIC ${ARG_BUILD_STATIC})
|
|
else()
|
|
set(BUILD_STATIC ${ARROW_BUILD_STATIC})
|
|
endif()
|
|
if(ARG_OUTPUT_PATH)
|
|
set(OUTPUT_PATH ${ARG_OUTPUT_PATH})
|
|
else()
|
|
set(OUTPUT_PATH ${BUILD_OUTPUT_ROOT_DIRECTORY})
|
|
endif()
|
|
|
|
if(WIN32
|
|
OR CMAKE_GENERATOR STREQUAL Xcode
|
|
OR NOT ARROW_POSITION_INDEPENDENT_CODE)
|
|
# We need to compile C++ separately for each library kind (shared and static)
|
|
# because of dllexport declarations on Windows.
|
|
# The Xcode generator doesn't reliably work with Xcode as target names are not
|
|
# guessed correctly.
|
|
set(USE_OBJLIB OFF)
|
|
else()
|
|
set(USE_OBJLIB ON)
|
|
endif()
|
|
|
|
if(USE_OBJLIB)
|
|
# Generate a single "objlib" from all C++ modules and link
|
|
# that "objlib" into each library kind, to avoid compiling twice
|
|
add_library(${LIB_NAME}_objlib OBJECT ${ARG_SOURCES})
|
|
# Necessary to make static linking into other shared libraries work properly
|
|
set_property(TARGET ${LIB_NAME}_objlib PROPERTY POSITION_INDEPENDENT_CODE ON)
|
|
if(ARG_DEPENDENCIES)
|
|
add_dependencies(${LIB_NAME}_objlib ${ARG_DEPENDENCIES})
|
|
endif()
|
|
if(ARG_DEFINITIONS)
|
|
target_compile_definitions(${LIB_NAME}_objlib PRIVATE ${ARG_DEFINITIONS})
|
|
endif()
|
|
target_compile_options(${LIB_NAME}_objlib PRIVATE ${ARROW_LIBRARIES_ONLY_CXX_FLAGS})
|
|
set(LIB_DEPS $<TARGET_OBJECTS:${LIB_NAME}_objlib>)
|
|
set(EXTRA_DEPS)
|
|
|
|
if(ARG_OUTPUTS)
|
|
list(APPEND ${ARG_OUTPUTS} ${LIB_NAME}_objlib)
|
|
endif()
|
|
|
|
if(ARG_EXTRA_INCLUDES)
|
|
target_include_directories(${LIB_NAME}_objlib SYSTEM PUBLIC ${ARG_EXTRA_INCLUDES})
|
|
endif()
|
|
if(ARG_PRIVATE_INCLUDES)
|
|
target_include_directories(${LIB_NAME}_objlib PRIVATE ${ARG_PRIVATE_INCLUDES})
|
|
endif()
|
|
if(BUILD_SHARED)
|
|
if(ARG_SHARED_LINK_LIBS)
|
|
target_link_libraries(${LIB_NAME}_objlib PRIVATE ${ARG_SHARED_LINK_LIBS})
|
|
endif()
|
|
if(ARG_SHARED_PRIVATE_LINK_LIBS)
|
|
target_link_libraries(${LIB_NAME}_objlib PRIVATE ${ARG_SHARED_PRIVATE_LINK_LIBS})
|
|
endif()
|
|
endif()
|
|
if(BUILD_STATIC AND ARG_STATIC_LINK_LIBS)
|
|
target_link_libraries(${LIB_NAME}_objlib PRIVATE ${ARG_STATIC_LINK_LIBS})
|
|
endif()
|
|
else()
|
|
# Prepare arguments for separate compilation of static and shared libs below
|
|
set(LIB_DEPS ${ARG_SOURCES})
|
|
set(EXTRA_DEPS ${ARG_DEPENDENCIES})
|
|
endif()
|
|
|
|
if(ARG_EXTRA_INCLUDES)
|
|
set(LIB_INCLUDES ${ARG_EXTRA_INCLUDES})
|
|
else()
|
|
set(LIB_INCLUDES "")
|
|
endif()
|
|
|
|
if(ARG_INSTALL_ARCHIVE_DIR)
|
|
set(INSTALL_ARCHIVE_DIR ${ARG_INSTALL_ARCHIVE_DIR})
|
|
else()
|
|
set(INSTALL_ARCHIVE_DIR ${CMAKE_INSTALL_LIBDIR})
|
|
endif()
|
|
if(ARG_INSTALL_LIBRARY_DIR)
|
|
set(INSTALL_LIBRARY_DIR ${ARG_INSTALL_LIBRARY_DIR})
|
|
else()
|
|
set(INSTALL_LIBRARY_DIR ${CMAKE_INSTALL_LIBDIR})
|
|
endif()
|
|
if(ARG_INSTALL_RUNTIME_DIR)
|
|
set(INSTALL_RUNTIME_DIR ${ARG_INSTALL_RUNTIME_DIR})
|
|
else()
|
|
set(INSTALL_RUNTIME_DIR bin)
|
|
endif()
|
|
|
|
if(BUILD_SHARED)
|
|
add_library(${LIB_NAME}_shared SHARED ${LIB_DEPS})
|
|
if(EXTRA_DEPS)
|
|
add_dependencies(${LIB_NAME}_shared ${EXTRA_DEPS})
|
|
endif()
|
|
|
|
if(ARG_DEFINITIONS)
|
|
target_compile_definitions(${LIB_NAME}_shared PRIVATE ${ARG_DEFINITIONS})
|
|
endif()
|
|
target_compile_options(${LIB_NAME}_shared PRIVATE ${ARROW_LIBRARIES_ONLY_CXX_FLAGS})
|
|
|
|
if(ARG_OUTPUTS)
|
|
list(APPEND ${ARG_OUTPUTS} ${LIB_NAME}_shared)
|
|
endif()
|
|
|
|
if(LIB_INCLUDES)
|
|
target_include_directories(${LIB_NAME}_shared SYSTEM PUBLIC ${ARG_EXTRA_INCLUDES})
|
|
endif()
|
|
|
|
if(ARG_PRIVATE_INCLUDES)
|
|
target_include_directories(${LIB_NAME}_shared PRIVATE ${ARG_PRIVATE_INCLUDES})
|
|
endif()
|
|
|
|
# On iOS, specifying -undefined conflicts with enabling bitcode
|
|
if(APPLE
|
|
AND NOT IOS
|
|
AND NOT DEFINED ENV{EMSCRIPTEN})
|
|
# On OS X, you can avoid linking at library load time and instead
|
|
# expecting that the symbols have been loaded separately. This happens
|
|
# with libpython* where there can be conflicts between system Python and
|
|
# the Python from a thirdparty distribution
|
|
#
|
|
# When running with the Emscripten Compiler, we need not worry about
|
|
# python, and the Emscripten Compiler does not support this option.
|
|
set(ARG_SHARED_LINK_FLAGS "-undefined dynamic_lookup ${ARG_SHARED_LINK_FLAGS}")
|
|
endif()
|
|
|
|
set_target_properties(${LIB_NAME}_shared
|
|
PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${OUTPUT_PATH}"
|
|
RUNTIME_OUTPUT_DIRECTORY "${OUTPUT_PATH}"
|
|
PDB_OUTPUT_DIRECTORY "${OUTPUT_PATH}"
|
|
LINK_FLAGS "${ARG_SHARED_LINK_FLAGS}"
|
|
OUTPUT_NAME ${LIB_NAME}
|
|
VERSION "${ARROW_FULL_SO_VERSION}"
|
|
SOVERSION "${ARROW_SO_VERSION}")
|
|
|
|
target_link_libraries(${LIB_NAME}_shared
|
|
PUBLIC "$<BUILD_INTERFACE:${ARG_SHARED_LINK_LIBS}>"
|
|
"$<INSTALL_INTERFACE:${ARG_SHARED_INSTALL_INTERFACE_LIBS}>"
|
|
PRIVATE ${ARG_SHARED_PRIVATE_LINK_LIBS})
|
|
|
|
if(USE_OBJLIB)
|
|
# Ensure that dependencies are built before compilation of objects in
|
|
# object library, rather than only before the final link step
|
|
foreach(SHARED_LINK_LIB ${ARG_SHARED_LINK_LIBS})
|
|
if(TARGET ${SHARED_LINK_LIB})
|
|
add_dependencies(${LIB_NAME}_objlib ${SHARED_LINK_LIB})
|
|
endif()
|
|
endforeach()
|
|
endif()
|
|
|
|
if(ARROW_RPATH_ORIGIN)
|
|
if(APPLE)
|
|
set(_lib_install_rpath "@loader_path")
|
|
else()
|
|
set(_lib_install_rpath "\$ORIGIN")
|
|
endif()
|
|
set_target_properties(${LIB_NAME}_shared PROPERTIES INSTALL_RPATH
|
|
${_lib_install_rpath})
|
|
endif()
|
|
|
|
if(APPLE)
|
|
if(ARROW_INSTALL_NAME_RPATH)
|
|
set(_lib_install_name "@rpath")
|
|
else()
|
|
set(_lib_install_name "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}")
|
|
endif()
|
|
set_target_properties(${LIB_NAME}_shared
|
|
PROPERTIES BUILD_WITH_INSTALL_RPATH ON INSTALL_NAME_DIR
|
|
"${_lib_install_name}")
|
|
endif()
|
|
|
|
install(TARGETS ${LIB_NAME}_shared ${INSTALL_IS_OPTIONAL}
|
|
EXPORT ${LIB_NAME}_targets
|
|
ARCHIVE DESTINATION ${INSTALL_ARCHIVE_DIR}
|
|
LIBRARY DESTINATION ${INSTALL_LIBRARY_DIR}
|
|
RUNTIME DESTINATION ${INSTALL_RUNTIME_DIR}
|
|
INCLUDES
|
|
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
|
endif()
|
|
|
|
if(BUILD_STATIC)
|
|
add_library(${LIB_NAME}_static STATIC ${LIB_DEPS})
|
|
if(EXTRA_DEPS)
|
|
add_dependencies(${LIB_NAME}_static ${EXTRA_DEPS})
|
|
endif()
|
|
|
|
if(ARG_DEFINITIONS)
|
|
target_compile_definitions(${LIB_NAME}_static PRIVATE ${ARG_DEFINITIONS})
|
|
endif()
|
|
target_compile_options(${LIB_NAME}_static PRIVATE ${ARROW_LIBRARIES_ONLY_CXX_FLAGS})
|
|
|
|
if(ARG_OUTPUTS)
|
|
list(APPEND ${ARG_OUTPUTS} ${LIB_NAME}_static)
|
|
endif()
|
|
|
|
if(LIB_INCLUDES)
|
|
target_include_directories(${LIB_NAME}_static SYSTEM PUBLIC ${ARG_EXTRA_INCLUDES})
|
|
endif()
|
|
|
|
if(ARG_PRIVATE_INCLUDES)
|
|
target_include_directories(${LIB_NAME}_static PRIVATE ${ARG_PRIVATE_INCLUDES})
|
|
endif()
|
|
|
|
if(MSVC_TOOLCHAIN)
|
|
set(LIB_NAME_STATIC ${LIB_NAME}_static)
|
|
else()
|
|
set(LIB_NAME_STATIC ${LIB_NAME})
|
|
endif()
|
|
|
|
if(WIN32)
|
|
target_compile_definitions(${LIB_NAME}_static PUBLIC ARROW_STATIC)
|
|
target_compile_definitions(${LIB_NAME}_static PUBLIC ARROW_FLIGHT_STATIC)
|
|
target_compile_definitions(${LIB_NAME}_static PUBLIC ARROW_FLIGHT_SQL_STATIC)
|
|
endif()
|
|
|
|
set_target_properties(${LIB_NAME}_static
|
|
PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${OUTPUT_PATH}"
|
|
OUTPUT_NAME ${LIB_NAME_STATIC})
|
|
|
|
if(ARG_STATIC_INSTALL_INTERFACE_LIBS)
|
|
target_link_libraries(${LIB_NAME}_static
|
|
INTERFACE "$<INSTALL_INTERFACE:${ARG_STATIC_INSTALL_INTERFACE_LIBS}>"
|
|
)
|
|
endif()
|
|
|
|
if(ARG_STATIC_LINK_LIBS)
|
|
target_link_libraries(${LIB_NAME}_static
|
|
PUBLIC "$<BUILD_INTERFACE:${ARG_STATIC_LINK_LIBS}>")
|
|
if(USE_OBJLIB)
|
|
# Ensure that dependencies are built before compilation of objects in
|
|
# object library, rather than only before the final link step
|
|
foreach(STATIC_LINK_LIB ${ARG_STATIC_LINK_LIBS})
|
|
if(TARGET ${STATIC_LINK_LIB})
|
|
add_dependencies(${LIB_NAME}_objlib ${STATIC_LINK_LIB})
|
|
endif()
|
|
endforeach()
|
|
endif()
|
|
endif()
|
|
|
|
install(TARGETS ${LIB_NAME}_static ${INSTALL_IS_OPTIONAL}
|
|
EXPORT ${LIB_NAME}_targets
|
|
ARCHIVE DESTINATION ${INSTALL_ARCHIVE_DIR}
|
|
LIBRARY DESTINATION ${INSTALL_LIBRARY_DIR}
|
|
RUNTIME DESTINATION ${INSTALL_RUNTIME_DIR}
|
|
INCLUDES
|
|
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
|
endif()
|
|
|
|
if(ARG_CMAKE_PACKAGE_NAME)
|
|
arrow_install_cmake_package(${ARG_CMAKE_PACKAGE_NAME} ${LIB_NAME}_targets)
|
|
endif()
|
|
|
|
if(ARG_PKG_CONFIG_NAME)
|
|
arrow_add_pkg_config("${ARG_PKG_CONFIG_NAME}")
|
|
endif()
|
|
|
|
# Modify variable in calling scope
|
|
if(ARG_OUTPUTS)
|
|
set(${ARG_OUTPUTS}
|
|
${${ARG_OUTPUTS}}
|
|
PARENT_SCOPE)
|
|
endif()
|
|
endfunction()
|
|
|
|
#
|
|
# 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 benchmark' 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().
|
|
#
|
|
# \arg PREFIX a string to append to the name of the benchmark executable. For
|
|
# example, if you have src/arrow/foo/bar-benchmark.cc, then PREFIX "foo" will
|
|
# create test executable foo-bar-benchmark
|
|
# \arg LABELS the benchmark label or labels to assign the unit tests to. By
|
|
# default, benchmarks will go in the "benchmark" group. Custom targets for the
|
|
# group names must exist
|
|
function(ADD_BENCHMARK REL_BENCHMARK_NAME)
|
|
set(options)
|
|
set(one_value_args PREFIX)
|
|
set(multi_value_args
|
|
EXTRA_LINK_LIBS
|
|
STATIC_LINK_LIBS
|
|
DEPENDENCIES
|
|
SOURCES
|
|
EXTRA_SOURCES
|
|
LABELS)
|
|
cmake_parse_arguments(ARG
|
|
"${options}"
|
|
"${one_value_args}"
|
|
"${multi_value_args}"
|
|
${ARGN})
|
|
if(ARG_UNPARSED_ARGUMENTS)
|
|
message(SEND_ERROR "Error: unrecognized arguments: ${ARG_UNPARSED_ARGUMENTS}")
|
|
endif()
|
|
|
|
if(NO_BENCHMARKS)
|
|
return()
|
|
endif()
|
|
get_filename_component(BENCHMARK_NAME ${REL_BENCHMARK_NAME} NAME_WE)
|
|
|
|
if(ARG_PREFIX)
|
|
set(BENCHMARK_NAME "${ARG_PREFIX}-${BENCHMARK_NAME}")
|
|
endif()
|
|
|
|
set(SOURCES "")
|
|
|
|
if(ARG_EXTRA_SOURCES)
|
|
list(APPEND SOURCES ${ARG_EXTRA_SOURCES})
|
|
endif()
|
|
|
|
if(ARG_SOURCES)
|
|
list(APPEND SOURCES ${ARG_SOURCES})
|
|
else()
|
|
list(APPEND SOURCES "${REL_BENCHMARK_NAME}.cc")
|
|
endif()
|
|
|
|
# Make sure the executable name contains only hyphens, not underscores
|
|
string(REPLACE "_" "-" BENCHMARK_NAME ${BENCHMARK_NAME})
|
|
|
|
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 "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${BENCHMARK_NAME}")
|
|
add_executable(${BENCHMARK_NAME} ${SOURCES})
|
|
|
|
if(ARG_STATIC_LINK_LIBS)
|
|
# Customize link libraries
|
|
target_link_libraries(${BENCHMARK_NAME} PRIVATE ${ARG_STATIC_LINK_LIBS})
|
|
else()
|
|
target_link_libraries(${BENCHMARK_NAME} PRIVATE ${ARROW_BENCHMARK_LINK_LIBS})
|
|
endif()
|
|
add_dependencies(benchmark ${BENCHMARK_NAME})
|
|
|
|
if(ARG_EXTRA_LINK_LIBS)
|
|
target_link_libraries(${BENCHMARK_NAME} PRIVATE ${ARG_EXTRA_LINK_LIBS})
|
|
endif()
|
|
else()
|
|
# No executable, just invoke the benchmark (probably a script) directly.
|
|
set(BENCHMARK_PATH ${CMAKE_CURRENT_SOURCE_DIR}/${REL_BENCHMARK_NAME})
|
|
endif()
|
|
|
|
# With OSX and conda, we need to set the correct RPATH so that dependencies
|
|
# are found. The installed libraries with conda have an RPATH that matches
|
|
# for executables and libraries lying in $ENV{CONDA_PREFIX}/bin or
|
|
# $ENV{CONDA_PREFIX}/lib but our test libraries and executables are not
|
|
# installed there.
|
|
if(NOT "$ENV{CONDA_PREFIX}" STREQUAL "" AND APPLE)
|
|
set_target_properties(${BENCHMARK_NAME}
|
|
PROPERTIES BUILD_WITH_INSTALL_RPATH TRUE
|
|
INSTALL_RPATH_USE_LINK_PATH TRUE
|
|
INSTALL_RPATH
|
|
"$ENV{CONDA_PREFIX}/lib;${CMAKE_RUNTIME_OUTPUT_DIRECTORY}"
|
|
)
|
|
endif()
|
|
|
|
# Add test as dependency of relevant label targets
|
|
add_dependencies(all-benchmarks ${BENCHMARK_NAME})
|
|
foreach(TARGET ${ARG_LABELS})
|
|
add_dependencies(${TARGET} ${BENCHMARK_NAME})
|
|
endforeach()
|
|
|
|
if(ARG_DEPENDENCIES)
|
|
add_dependencies(${BENCHMARK_NAME} ${ARG_DEPENDENCIES})
|
|
endif()
|
|
|
|
if(ARG_LABELS)
|
|
set(ARG_LABELS "benchmark;${ARG_LABELS}")
|
|
else()
|
|
set(ARG_LABELS benchmark)
|
|
endif()
|
|
|
|
if(ARROW_BUILD_DETAILED_BENCHMARKS)
|
|
target_compile_definitions(${BENCHMARK_NAME} PRIVATE ARROW_BUILD_DETAILED_BENCHMARKS)
|
|
endif()
|
|
|
|
add_test(${BENCHMARK_NAME}
|
|
${BUILD_SUPPORT_DIR}/run-test.sh
|
|
${CMAKE_BINARY_DIR}
|
|
benchmark
|
|
${BENCHMARK_PATH})
|
|
|
|
set_property(TEST ${BENCHMARK_NAME}
|
|
APPEND
|
|
PROPERTY LABELS ${ARG_LABELS})
|
|
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.
|
|
#
|
|
# If given, SOURCES is the list of C++ source files to compile into the test
|
|
# executable. Otherwise, "REL_TEST_NAME.cc" is used.
|
|
#
|
|
# 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().
|
|
#
|
|
# \arg ENABLED if passed, add this unit test even if ARROW_BUILD_TESTS is off
|
|
# \arg PREFIX a string to append to the name of the test executable. For
|
|
# example, if you have src/arrow/foo/bar-test.cc, then PREFIX "foo" will create
|
|
# test executable foo-bar-test
|
|
# \arg LABELS the unit test label or labels to assign the unit tests
|
|
# to. By default, unit tests will go in the "unittest" group, but if we have
|
|
# multiple unit tests in some subgroup, you can assign a test to multiple
|
|
# groups use the syntax unittest;GROUP2;GROUP3. Custom targets for the group
|
|
# names must exist
|
|
function(ADD_TEST_CASE REL_TEST_NAME)
|
|
set(options NO_VALGRIND ENABLED)
|
|
set(one_value_args PREFIX)
|
|
set(multi_value_args
|
|
SOURCES
|
|
STATIC_LINK_LIBS
|
|
EXTRA_LINK_LIBS
|
|
EXTRA_INCLUDES
|
|
EXTRA_DEPENDENCIES
|
|
LABELS
|
|
EXTRA_LABELS
|
|
TEST_ARGUMENTS
|
|
DEFINITIONS)
|
|
cmake_parse_arguments(ARG
|
|
"${options}"
|
|
"${one_value_args}"
|
|
"${multi_value_args}"
|
|
${ARGN})
|
|
if(ARG_UNPARSED_ARGUMENTS)
|
|
message(SEND_ERROR "Error: unrecognized arguments: ${ARG_UNPARSED_ARGUMENTS}")
|
|
endif()
|
|
|
|
if(NO_TESTS AND NOT ARG_ENABLED)
|
|
return()
|
|
endif()
|
|
get_filename_component(TEST_NAME ${REL_TEST_NAME} NAME_WE)
|
|
|
|
if(ARG_PREFIX)
|
|
set(TEST_NAME "${ARG_PREFIX}-${TEST_NAME}")
|
|
endif()
|
|
|
|
if(ARG_SOURCES)
|
|
set(SOURCES ${ARG_SOURCES})
|
|
else()
|
|
set(SOURCES "${REL_TEST_NAME}.cc")
|
|
endif()
|
|
|
|
# Make sure the executable name contains only hyphens, not underscores
|
|
string(REPLACE "_" "-" TEST_NAME ${TEST_NAME})
|
|
|
|
set(TEST_PATH "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${TEST_NAME}")
|
|
add_executable(${TEST_NAME} ${SOURCES})
|
|
|
|
# With OSX and conda, we need to set the correct RPATH so that dependencies
|
|
# are found. The installed libraries with conda have an RPATH that matches
|
|
# for executables and libraries lying in $ENV{CONDA_PREFIX}/bin or
|
|
# $ENV{CONDA_PREFIX}/lib but our test libraries and executables are not
|
|
# installed there.
|
|
if(NOT "$ENV{CONDA_PREFIX}" STREQUAL "" AND APPLE)
|
|
set_target_properties(${TEST_NAME}
|
|
PROPERTIES BUILD_WITH_INSTALL_RPATH TRUE
|
|
INSTALL_RPATH_USE_LINK_PATH TRUE
|
|
INSTALL_RPATH
|
|
"${CMAKE_RUNTIME_OUTPUT_DIRECTORY};$ENV{CONDA_PREFIX}/lib"
|
|
)
|
|
endif()
|
|
|
|
# Ensure using bundled GoogleTest when we use bundled GoogleTest.
|
|
# ARROW_GTEST_GTEST_HEADERS is defined only when we use bundled
|
|
# GoogleTest.
|
|
target_link_libraries(${TEST_NAME} PRIVATE ${ARROW_GTEST_GTEST_HEADERS})
|
|
|
|
if(ARG_STATIC_LINK_LIBS)
|
|
# Customize link libraries
|
|
target_link_libraries(${TEST_NAME} PRIVATE ${ARG_STATIC_LINK_LIBS})
|
|
else()
|
|
target_link_libraries(${TEST_NAME} PRIVATE ${ARROW_TEST_LINK_LIBS})
|
|
endif()
|
|
|
|
if(ARG_EXTRA_LINK_LIBS)
|
|
target_link_libraries(${TEST_NAME} PRIVATE ${ARG_EXTRA_LINK_LIBS})
|
|
endif()
|
|
|
|
if(ARG_EXTRA_INCLUDES)
|
|
target_include_directories(${TEST_NAME} SYSTEM PUBLIC ${ARG_EXTRA_INCLUDES})
|
|
endif()
|
|
|
|
if(ARG_EXTRA_DEPENDENCIES)
|
|
add_dependencies(${TEST_NAME} ${ARG_EXTRA_DEPENDENCIES})
|
|
endif()
|
|
|
|
if(ARG_DEFINITIONS)
|
|
target_compile_definitions(${TEST_NAME} PRIVATE ${ARG_DEFINITIONS})
|
|
endif()
|
|
|
|
if(ARROW_TEST_MEMCHECK AND NOT ARG_NO_VALGRIND)
|
|
add_test(${TEST_NAME}
|
|
bash
|
|
-c
|
|
"cd '${CMAKE_SOURCE_DIR}'; \
|
|
valgrind --suppressions=valgrind.supp --tool=memcheck --gen-suppressions=all \
|
|
--num-callers=500 --leak-check=full --leak-check-heuristics=stdstring \
|
|
--error-exitcode=1 ${TEST_PATH} ${ARG_TEST_ARGUMENTS}")
|
|
elseif(WIN32 OR CMAKE_SYSTEM_NAME STREQUAL "Emscripten")
|
|
add_test(NAME ${TEST_NAME} COMMAND ${TEST_NAME} ${ARG_TEST_ARGUMENTS})
|
|
else()
|
|
add_test(${TEST_NAME}
|
|
${BUILD_SUPPORT_DIR}/run-test.sh
|
|
${CMAKE_BINARY_DIR}
|
|
test
|
|
${TEST_PATH}
|
|
${ARG_TEST_ARGUMENTS})
|
|
endif()
|
|
|
|
# Add test as dependency of relevant targets
|
|
add_dependencies(all-tests ${TEST_NAME})
|
|
foreach(TARGET ${ARG_LABELS})
|
|
add_dependencies(${TARGET} ${TEST_NAME})
|
|
endforeach()
|
|
|
|
set(LABELS)
|
|
list(APPEND LABELS "unittest")
|
|
if(ARG_LABELS)
|
|
list(APPEND LABELS ${ARG_LABELS})
|
|
endif()
|
|
# EXTRA_LABELS don't create their own dependencies, they are only used
|
|
# to ease running certain test categories.
|
|
if(ARG_EXTRA_LABELS)
|
|
list(APPEND LABELS ${ARG_EXTRA_LABELS})
|
|
endif()
|
|
|
|
foreach(LABEL ${ARG_LABELS})
|
|
# ensure there is a cmake target which exercises tests with this LABEL
|
|
set(LABEL_TEST_NAME "test-${LABEL}")
|
|
if(NOT TARGET ${LABEL_TEST_NAME})
|
|
add_custom_target(${LABEL_TEST_NAME}
|
|
ctest -L "${LABEL}" --output-on-failure
|
|
USES_TERMINAL)
|
|
endif()
|
|
# ensure the test is (re)built before the LABEL test runs
|
|
add_dependencies(${LABEL_TEST_NAME} ${TEST_NAME})
|
|
endforeach()
|
|
|
|
set_property(TEST ${TEST_NAME}
|
|
APPEND
|
|
PROPERTY LABELS ${LABELS})
|
|
endfunction()
|
|
|
|
#
|
|
# Examples
|
|
#
|
|
# Add a new example, with or without an executable that should be built.
|
|
# If examples are enabled then they will be run along side unit tests with ctest.
|
|
# 'make runexample' to build/run only examples.
|
|
#
|
|
# REL_EXAMPLE_NAME is the name of the example app. It may be a single component
|
|
# (e.g. monotime-example) or contain additional components (e.g.
|
|
# net/net_util-example). Either way, the last component must be a globally
|
|
# unique name.
|
|
|
|
# The example will registered as unit test with ctest with a label
|
|
# of 'example'.
|
|
#
|
|
# Arguments after the test name will be passed to set_tests_properties().
|
|
#
|
|
# \arg PREFIX a string to append to the name of the example executable. For
|
|
# example, if you have src/arrow/foo/bar-example.cc, then PREFIX "foo" will
|
|
# create test executable foo-bar-example
|
|
function(ADD_ARROW_EXAMPLE REL_EXAMPLE_NAME)
|
|
set(options)
|
|
set(one_value_args PREFIX)
|
|
set(multi_value_args EXTRA_INCLUDES EXTRA_LINK_LIBS EXTRA_SOURCES DEPENDENCIES)
|
|
cmake_parse_arguments(ARG
|
|
"${options}"
|
|
"${one_value_args}"
|
|
"${multi_value_args}"
|
|
${ARGN})
|
|
if(ARG_UNPARSED_ARGUMENTS)
|
|
message(SEND_ERROR "Error: unrecognized arguments: ${ARG_UNPARSED_ARGUMENTS}")
|
|
endif()
|
|
|
|
if(NO_EXAMPLES)
|
|
return()
|
|
endif()
|
|
get_filename_component(EXAMPLE_NAME ${REL_EXAMPLE_NAME} NAME_WE)
|
|
|
|
if(ARG_PREFIX)
|
|
set(EXAMPLE_NAME "${ARG_PREFIX}-${EXAMPLE_NAME}")
|
|
endif()
|
|
|
|
# Make sure the executable name contains only hyphens, not underscores
|
|
string(REPLACE "_" "-" EXAMPLE_NAME ${EXAMPLE_NAME})
|
|
|
|
if(EXISTS ${CMAKE_SOURCE_DIR}/examples/arrow/${REL_EXAMPLE_NAME}.cc)
|
|
# This example has a corresponding .cc file, set it up as an executable.
|
|
set(EXAMPLE_PATH "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${EXAMPLE_NAME}")
|
|
add_executable(${EXAMPLE_NAME} "${REL_EXAMPLE_NAME}.cc" ${ARG_EXTRA_SOURCES})
|
|
target_link_libraries(${EXAMPLE_NAME} ${ARROW_EXAMPLE_LINK_LIBS})
|
|
add_dependencies(runexample ${EXAMPLE_NAME})
|
|
|
|
if(ARG_EXTRA_LINK_LIBS)
|
|
target_link_libraries(${EXAMPLE_NAME} ${ARG_EXTRA_LINK_LIBS})
|
|
endif()
|
|
endif()
|
|
|
|
if(ARG_DEPENDENCIES)
|
|
add_dependencies(${EXAMPLE_NAME} ${ARG_DEPENDENCIES})
|
|
endif()
|
|
|
|
if(ARG_EXTRA_INCLUDES)
|
|
target_include_directories(${EXAMPLE_NAME} SYSTEM PUBLIC ${ARG_EXTRA_INCLUDES})
|
|
endif()
|
|
|
|
add_test(${EXAMPLE_NAME} ${EXAMPLE_PATH})
|
|
set_tests_properties(${EXAMPLE_NAME} PROPERTIES LABELS "example")
|
|
endfunction()
|
|
|
|
#
|
|
# Fuzzing
|
|
#
|
|
# Add new fuzz target executable.
|
|
#
|
|
# The single source file must define a function:
|
|
# extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
|
|
#
|
|
# No main function must be present within the source file!
|
|
#
|
|
function(ADD_FUZZ_TARGET REL_FUZZING_NAME)
|
|
set(options)
|
|
set(one_value_args PREFIX)
|
|
set(multi_value_args LINK_LIBS)
|
|
cmake_parse_arguments(ARG
|
|
"${options}"
|
|
"${one_value_args}"
|
|
"${multi_value_args}"
|
|
${ARGN})
|
|
if(ARG_UNPARSED_ARGUMENTS)
|
|
message(SEND_ERROR "Error: unrecognized arguments: ${ARG_UNPARSED_ARGUMENTS}")
|
|
endif()
|
|
|
|
if(NOT ARROW_FUZZING)
|
|
return()
|
|
endif()
|
|
|
|
get_filename_component(FUZZING_NAME ${REL_FUZZING_NAME} NAME_WE)
|
|
|
|
# Make sure the executable name contains only hyphens, not underscores
|
|
string(REPLACE "_" "-" FUZZING_NAME ${FUZZING_NAME})
|
|
|
|
if(ARG_PREFIX)
|
|
set(FUZZING_NAME "${ARG_PREFIX}-${FUZZING_NAME}")
|
|
endif()
|
|
|
|
# For OSS-Fuzz
|
|
# (https://google.github.io/oss-fuzz/advanced-topics/ideal-integration/)
|
|
if(DEFINED ENV{LIB_FUZZING_ENGINE})
|
|
set(FUZZ_LDFLAGS $ENV{LIB_FUZZING_ENGINE})
|
|
else()
|
|
set(FUZZ_LDFLAGS "-fsanitize=fuzzer")
|
|
endif()
|
|
|
|
add_executable(${FUZZING_NAME} "${REL_FUZZING_NAME}.cc")
|
|
target_link_libraries(${FUZZING_NAME} ${LINK_LIBS})
|
|
target_compile_options(${FUZZING_NAME} PRIVATE ${FUZZ_LDFLAGS})
|
|
set_target_properties(${FUZZING_NAME} PROPERTIES LINK_FLAGS ${FUZZ_LDFLAGS} LABELS
|
|
"fuzzing")
|
|
endfunction()
|
|
|
|
function(ARROW_INSTALL_ALL_HEADERS PATH)
|
|
set(options)
|
|
set(one_value_args)
|
|
set(multi_value_args PATTERN)
|
|
cmake_parse_arguments(ARG
|
|
"${options}"
|
|
"${one_value_args}"
|
|
"${multi_value_args}"
|
|
${ARGN})
|
|
if(NOT ARG_PATTERN)
|
|
# The .hpp extension is used by some vendored libraries
|
|
set(ARG_PATTERN "*.h" "*.hpp")
|
|
endif()
|
|
file(GLOB CURRENT_DIRECTORY_HEADERS ${ARG_PATTERN})
|
|
|
|
set(PUBLIC_HEADERS)
|
|
foreach(HEADER ${CURRENT_DIRECTORY_HEADERS})
|
|
get_filename_component(HEADER_BASENAME ${HEADER} NAME)
|
|
if(HEADER_BASENAME MATCHES "internal")
|
|
continue()
|
|
endif()
|
|
list(APPEND PUBLIC_HEADERS ${HEADER})
|
|
endforeach()
|
|
install(FILES ${PUBLIC_HEADERS} DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${PATH}")
|
|
endfunction()
|
|
|
|
function(ARROW_ADD_PKG_CONFIG MODULE)
|
|
configure_file(${MODULE}.pc.in "${CMAKE_CURRENT_BINARY_DIR}/${MODULE}.pc.generate.in"
|
|
@ONLY)
|
|
file(GENERATE
|
|
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>/${MODULE}.pc"
|
|
INPUT "${CMAKE_CURRENT_BINARY_DIR}/${MODULE}.pc.generate.in")
|
|
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>/${MODULE}.pc"
|
|
DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig/")
|
|
endfunction()
|
|
|
|
# Implementations of lisp "car" and "cdr" functions
|
|
macro(ARROW_CAR var)
|
|
set(${var} ${ARGV1})
|
|
endmacro()
|
|
|
|
macro(ARROW_CDR var rest)
|
|
set(${var} ${ARGN})
|
|
endmacro()
|