| # 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) |