summaryrefslogtreecommitdiffstats
path: root/src/arrow/dev/archery/archery/lang/cpp.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/arrow/dev/archery/archery/lang/cpp.py')
-rw-r--r--src/arrow/dev/archery/archery/lang/cpp.py296
1 files changed, 296 insertions, 0 deletions
diff --git a/src/arrow/dev/archery/archery/lang/cpp.py b/src/arrow/dev/archery/archery/lang/cpp.py
new file mode 100644
index 000000000..c2b1ca680
--- /dev/null
+++ b/src/arrow/dev/archery/archery/lang/cpp.py
@@ -0,0 +1,296 @@
+# 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, build_unity=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.build_unity = build_unity
+
+ 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)
+
+ 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))
+ yield ("CMAKE_UNITY_BUILD", truthifier(self.build_unity))
+
+ # 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)