blob: 045d23b56b154f16f78892a1a91e867c433bbe9a [file] [log] [blame]
# 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.
import os
from ..utils.cmake import CMakeDefinition
def truthifier(value):
return "ON" if value else "OFF"
def or_else(value, default):
return value if value else default
def coalesce(value, fallback):
return fallback if value is None else value
LLVM_VERSION = 7
class CppConfiguration:
def __init__(self,
# toolchain
cc=None, cxx=None, cxx_flags=None,
build_type=None, warn_level=None,
cpp_package_prefix=None, install_prefix=None, use_conda=None,
build_static=False, build_shared=True,
# tests & examples
with_tests=None, with_benchmarks=None, with_examples=None,
with_integration=None,
# static checks
use_asan=None, use_tsan=None, use_ubsan=None,
with_fuzzing=None,
# Components
with_compute=None, with_csv=None, with_cuda=None,
with_dataset=None, with_filesystem=None, with_flight=None,
with_gandiva=None, with_hdfs=None, with_hiveserver2=None,
with_ipc=True, with_json=None, with_jni=None,
with_mimalloc=None,
with_parquet=None, with_plasma=None, with_python=True,
with_r=None, with_s3=None,
# Compressions
with_brotli=None, with_bz2=None, with_lz4=None,
with_snappy=None, with_zlib=None, with_zstd=None,
# extras
with_lint_only=False,
use_gold_linker=True,
simd_level="SSE4_2",
cmake_extras=None):
self._cc = cc
self._cxx = cxx
self.cxx_flags = cxx_flags
self._build_type = build_type
self.warn_level = warn_level
self._install_prefix = install_prefix
self._package_prefix = cpp_package_prefix
self._use_conda = use_conda
self.build_static = build_static
self.build_shared = build_shared
self.with_tests = with_tests
self.with_benchmarks = with_benchmarks
self.with_examples = with_examples
self.with_integration = with_integration
self.use_asan = use_asan
self.use_tsan = use_tsan
self.use_ubsan = use_ubsan
self.with_fuzzing = with_fuzzing
self.with_compute = with_compute
self.with_csv = with_csv
self.with_cuda = with_cuda
self.with_dataset = with_dataset
self.with_filesystem = with_filesystem
self.with_flight = with_flight
self.with_gandiva = with_gandiva
self.with_hdfs = with_hdfs
self.with_hiveserver2 = with_hiveserver2
self.with_ipc = with_ipc
self.with_json = with_json
self.with_jni = with_jni
self.with_mimalloc = with_mimalloc
self.with_parquet = with_parquet
self.with_plasma = with_plasma
self.with_python = with_python
self.with_r = with_r
self.with_s3 = with_s3
self.with_brotli = with_brotli
self.with_bz2 = with_bz2
self.with_lz4 = with_lz4
self.with_snappy = with_snappy
self.with_zlib = with_zlib
self.with_zstd = with_zstd
self.with_lint_only = with_lint_only
self.use_gold_linker = use_gold_linker
self.simd_level = simd_level
self.cmake_extras = cmake_extras
# Fixup required dependencies by providing sane defaults if the caller
# didn't specify the option.
if self.with_r:
self.with_csv = coalesce(with_csv, True)
self.with_dataset = coalesce(with_dataset, True)
self.with_filesystem = coalesce(with_filesystem, True)
self.with_ipc = coalesce(with_ipc, True)
self.with_json = coalesce(with_json, True)
self.with_parquet = coalesce(with_parquet, True)
if self.with_python:
self.with_zlib = coalesce(with_zlib, True)
self.with_lz4 = coalesce(with_lz4, True)
if self.with_dataset:
self.with_filesystem = coalesce(with_filesystem, True)
self.with_parquet = coalesce(with_parquet, True)
if self.with_parquet:
self.with_snappy = coalesce(with_snappy, True)
@property
def build_type(self):
if self._build_type:
return self._build_type
if self.with_fuzzing:
return "relwithdebinfo"
return "release"
@property
def cc(self):
if self._cc:
return self._cc
if self.with_fuzzing:
return "clang-{}".format(LLVM_VERSION)
return None
@property
def cxx(self):
if self._cxx:
return self._cxx
if self.with_fuzzing:
return "clang++-{}".format(LLVM_VERSION)
return None
def _gen_defs(self):
if self.cxx_flags:
yield ("ARROW_CXXFLAGS", self.cxx_flags)
yield ("CMAKE_EXPORT_COMPILE_COMMANDS", truthifier(True))
yield ("CMAKE_BUILD_TYPE", self.build_type)
yield ("CMAKE_UNITY_BUILD", True)
if not self.with_lint_only:
yield ("BUILD_WARNING_LEVEL",
or_else(self.warn_level, "production"))
# if not ctx.quiet:
# yield ("ARROW_VERBOSE_THIRDPARTY_BUILD", "ON")
maybe_prefix = self.install_prefix
if maybe_prefix:
yield ("CMAKE_INSTALL_PREFIX", maybe_prefix)
if self._package_prefix is not None:
yield ("ARROW_DEPENDENCY_SOURCE", "SYSTEM")
yield ("ARROW_PACKAGE_PREFIX", self._package_prefix)
yield ("ARROW_BUILD_STATIC", truthifier(self.build_static))
yield ("ARROW_BUILD_SHARED", truthifier(self.build_shared))
# Tests and benchmarks
yield ("ARROW_BUILD_TESTS", truthifier(self.with_tests))
yield ("ARROW_BUILD_BENCHMARKS", truthifier(self.with_benchmarks))
yield ("ARROW_BUILD_EXAMPLES", truthifier(self.with_examples))
yield ("ARROW_BUILD_INTEGRATION", truthifier(self.with_integration))
# Static checks
yield ("ARROW_USE_ASAN", truthifier(self.use_asan))
yield ("ARROW_USE_TSAN", truthifier(self.use_tsan))
yield ("ARROW_USE_UBSAN", truthifier(self.use_ubsan))
yield ("ARROW_FUZZING", truthifier(self.with_fuzzing))
# Components
yield ("ARROW_COMPUTE", truthifier(self.with_compute))
yield ("ARROW_CSV", truthifier(self.with_csv))
yield ("ARROW_CUDA", truthifier(self.with_cuda))
yield ("ARROW_DATASET", truthifier(self.with_dataset))
yield ("ARROW_FILESYSTEM", truthifier(self.with_filesystem))
yield ("ARROW_FLIGHT", truthifier(self.with_flight))
yield ("ARROW_GANDIVA", truthifier(self.with_gandiva))
yield ("ARROW_PARQUET", truthifier(self.with_parquet))
yield ("ARROW_HDFS", truthifier(self.with_hdfs))
yield ("ARROW_HIVESERVER2", truthifier(self.with_hiveserver2))
yield ("ARROW_IPC", truthifier(self.with_ipc))
yield ("ARROW_JSON", truthifier(self.with_json))
yield ("ARROW_JNI", truthifier(self.with_jni))
yield ("ARROW_MIMALLOC", truthifier(self.with_mimalloc))
yield ("ARROW_PLASMA", truthifier(self.with_plasma))
yield ("ARROW_PYTHON", truthifier(self.with_python))
yield ("ARROW_S3", truthifier(self.with_s3))
# Compressions
yield ("ARROW_WITH_BROTLI", truthifier(self.with_brotli))
yield ("ARROW_WITH_BZ2", truthifier(self.with_bz2))
yield ("ARROW_WITH_LZ4", truthifier(self.with_lz4))
yield ("ARROW_WITH_SNAPPY", truthifier(self.with_snappy))
yield ("ARROW_WITH_ZLIB", truthifier(self.with_zlib))
yield ("ARROW_WITH_ZSTD", truthifier(self.with_zstd))
yield ("ARROW_LINT_ONLY", truthifier(self.with_lint_only))
# Some configurations don't like gnu gold linker.
broken_with_gold_ld = [self.with_fuzzing, self.with_gandiva]
if self.use_gold_linker and not any(broken_with_gold_ld):
yield ("ARROW_USE_LD_GOLD", truthifier(self.use_gold_linker))
yield ("ARROW_SIMD_LEVEL", or_else(self.simd_level, "SSE4_2"))
# Detect custom conda toolchain
if self.use_conda:
for d, v in [('CMAKE_AR', 'AR'), ('CMAKE_RANLIB', 'RANLIB')]:
v = os.environ.get(v)
if v:
yield (d, v)
@property
def install_prefix(self):
if self._install_prefix:
return self._install_prefix
if self.use_conda:
return os.environ.get("CONDA_PREFIX")
return None
@property
def use_conda(self):
# If the user didn't specify a preference, guess via environment
if self._use_conda is None:
return os.environ.get("CONDA_PREFIX") is not None
return self._use_conda
@property
def definitions(self):
extras = list(self.cmake_extras) if self.cmake_extras else []
definitions = ["-D{}={}".format(d[0], d[1]) for d in self._gen_defs()]
return definitions + extras
@property
def environment(self):
env = os.environ.copy()
if self.cc:
env["CC"] = self.cc
if self.cxx:
env["CXX"] = self.cxx
return env
class CppCMakeDefinition(CMakeDefinition):
def __init__(self, source, conf, **kwargs):
self.configuration = conf
super().__init__(source, **kwargs,
definitions=conf.definitions, env=conf.environment,
build_type=conf.build_type)