Open8

Apache Arrowの開発メモ

Hiroyuki SatoHiroyuki Sato

CPPビルド基本

-DARROW_EXTRA_ERROR_CONTEXTninja-debug-maximalの時ONなので明示的にOFFにしたい時だけ指定する。

git clone https://github.com/apache/arrow/
cd arrow/cpp
mkdir build
cd build
cmake .. --preset ninja-debug-maximal \
  -DCMAKE_INSTALL_PREFIX=/tmp/local \
  -DARROW_CUDA=OFF \
  -DARROW_SKYHOOK=OFF \
  -DARROW_EXTRA_ERROR_CONTEXT=OFF
cmake --build .
cmake --install .

GLibビルド

meson setup \
      --backend=ninja \
      --prefix=/tmp/local \
      --libdir=lib \
      --pkg-config-path=/tmp/local/lib/pkgconfig \
      -Ddoc=false \
      -Dvapi=false \
      -Dwerror=false \
      c_glib.build \
      c_glib
ninja -C c_glib.build all

プリセットを見る。

cmake --list-presets
Available configure presets:

  "ninja-debug-minimal"          - Debug build without anything enabled
  "ninja-debug-basic"            - Debug build with tests and reduced dependencies
  "ninja-debug"                  - Debug build with tests and more optional components
  "ninja-debug-cuda"             - Debug build with tests and CUDA integration
  "ninja-debug-filesystems"      - Debug build with tests and filesystems
  "ninja-debug-flight"           - Debug build with tests and Flight
  "ninja-debug-flight-sql"       - Debug build with tests and Flight SQL
  "ninja-debug-gandiva"          - Debug build with tests and Gandiva
  "ninja-debug-python-minimal"   - Debug build for PyArrow with minimal features
  "ninja-debug-python"           - Debug build for PyArrow with common features (for backward compatibility)
  "ninja-debug-python-maximal"   - Debug build for PyArrow with everything enabled
  "ninja-debug-maximal"          - Debug build with everything enabled (except benchmarks)
  "ninja-debug-valgrind-basic"   - Debug build for Valgrind with reduced dependencies
  "ninja-debug-valgrind"         - Debug build for Valgrind with more optional components
  "ninja-debug-valgrind-minimal" - Debug build for Valgrind without anything enabled
  "ninja-debug-valgrind-maximal" - Debug build for Valgrind with everything enabled
  "ninja-release-minimal"        - Release build without anything enabled
  "ninja-release-basic"          - Release build with reduced dependencies
  "ninja-release"                - Release build with more optional components
  "ninja-release-cuda"           - Release build with CUDA integration
  "ninja-debug-emscripten"       - Debug build which builds an Emscripten library
  "ninja-release-emscripten"     - Release build which builds an Emscripten library
  "ninja-release-flight"         - Release build with Flight
  "ninja-release-flight-sql"     - Release build with Flight SQL
  "ninja-release-gandiva"        - Release build with Gandiva
  "ninja-release-python-minimal" - Release build for PyArrow with minimal features
  "ninja-release-python"         - Release build for PyArrow with common features (for backward compatibility)
  "ninja-release-python-maximal" - Release build for PyArrow with everything enabled
  "ninja-release-maximal"        - Release build with everything enabled (except benchmarks)
  "ninja-benchmarks-basic"       - Benchmarking build with reduced dependencies
  "ninja-benchmarks"             - Benchmarking build with more optional components
  "ninja-benchmarks-maximal"     - Benchmarking build with everything enabled
  "fuzzing"                      - Debug build with IPC and Parquet fuzzing targets

テスト1

て特定のメソッドだけ

../c_glib/test/run-test.sh -t TestDecimal128DataType
../c_glib/test/run-test.sh -n test_decimal_data_type_new

特定のテストだけ実行

テスト2

プリセットは、CMakePresets.json に記載されている。

プリセットの内容確認

for i in $( cmake --list-presets | awk '{ print $1 }' | tr -d '"' | tail +3 ) ; do
  echo "*********** $i ****************" ;
  cmake -N --preset $i
done

*********** ninja-debug-minimal ****************
Preset CMake variables:

  ARROW_BUILD_INTEGRATION="OFF"
  ARROW_BUILD_STATIC="OFF"
  ARROW_BUILD_TESTS="OFF"
  ARROW_EXTRA_ERROR_CONTEXT="ON"
  ARROW_WITH_RE2="OFF"
  ARROW_WITH_UTF8PROC="OFF"
  CMAKE_BUILD_TYPE="Debug"
  CMAKE_EXPORT_COMPILE_COMMANDS="ON"

*********** ninja-debug-basic ****************
Preset CMake variables:

  ARROW_BUILD_INTEGRATION="ON"
  ARROW_BUILD_STATIC="OFF"
  ARROW_BUILD_TESTS="ON"
  ARROW_COMPUTE="ON"
  ARROW_CSV="ON"
  ARROW_DATASET="ON"
  ARROW_EXTRA_ERROR_CONTEXT="ON"
  ARROW_FILESYSTEM="ON"
  ARROW_JSON="ON"
  ARROW_WITH_RE2="OFF"
  ARROW_WITH_UTF8PROC="OFF"
  CMAKE_BUILD_TYPE="Debug"
  CMAKE_EXPORT_COMPILE_COMMANDS="ON"
Hiroyuki SatoHiroyuki Sato

Decimalの精度

10^x
Decimal32Type 10^9
Decimal64Type 10^18
Decimal128Type 10^38
Decimal256Type 10^76
Hiroyuki SatoHiroyuki Sato

テスト

pre-commit run \
  --show-diff-on-failure \
  --color=always \
  --files \
    $( find c_glib \
      -name '*.cpp' \
      -o -name '*.h' \
      -o -name '*.hpp' \
      -print )

CIがやっているやつ

pre-commit run --all-files --color=always --show-diff-on-failure
Hiroyuki SatoHiroyuki Sato

以下のように書くと

//   * GArrowDecimal32Array: モジュール名を含んだクラス名
//   * garrow_decimal32_array: このクラス用の関数のプレフィックス
//   * GARROW: 大文字のモジュール名
//   * DECIMAL32_ARRAY: 大文字のクラス名(モジュール名なし)
//   * GArrowFixedSizeBinaryArray: 親クラス名
G_DECLARE_DERIVABLE_TYPE(GArrowDecimal32Array,
                         garrow_decimal32_array,
                         GARROW,
                         DECIMAL32_ARRAY,
                         GArrowFixedSizeBinaryArray)

次のようになる。


GType garrow_decimal32_array_get_type(void);

typedef struct _GArrowDecimal32Array GArrowDecimal32Array;
typedef struct _GArrowDecimal32ArrayClass GArrowDecimal32ArrayClass;
struct _GArrowDecimal32Array {
  GArrowFixedSizeBinaryArray parent_instance;
};
typedef GArrowDecimal32Array *GArrowDecimal32Array_autoptr;
typedef GList *GArrowDecimal32Array_listautoptr;
typedef GSList *GArrowDecimal32Array_slistautoptr;
typedef GQueue *GArrowDecimal32Array_queueautoptr;

static __attribute__((__unused__)) inline void
glib_autoptr_clear_GArrowDecimal32Array(GArrowDecimal32Array *_ptr) {
  if (_ptr)
    (glib_autoptr_clear_GArrowFixedSizeBinaryArray)(
        (GArrowFixedSizeBinaryArray *)_ptr);
}
static __attribute__((__unused__)) inline void
glib_autoptr_cleanup_GArrowDecimal32Array(GArrowDecimal32Array **_ptr) {
  glib_autoptr_clear_GArrowDecimal32Array(*_ptr);
}
static __attribute__((__unused__)) inline void
glib_autoptr_destroy_GArrowDecimal32Array(void *_ptr) {
  (glib_autoptr_clear_GArrowFixedSizeBinaryArray)(
      (GArrowFixedSizeBinaryArray *)_ptr);
}
static __attribute__((__unused__)) inline void
glib_listautoptr_cleanup_GArrowDecimal32Array(GList **_l) {
  g_list_free_full(*_l, glib_autoptr_destroy_GArrowDecimal32Array);
}
static __attribute__((__unused__)) inline void
glib_slistautoptr_cleanup_GArrowDecimal32Array(GSList **_l) {
  g_slist_free_full(*_l, glib_autoptr_destroy_GArrowDecimal32Array);
}
static __attribute__((__unused__)) inline void
glib_queueautoptr_cleanup_GArrowDecimal32Array(GQueue **_q) {
  if (*_q)
    g_queue_free_full(*_q, glib_autoptr_destroy_GArrowDecimal32Array);
}

typedef GArrowDecimal32ArrayClass *GArrowDecimal32ArrayClass_autoptr;
typedef GList *GArrowDecimal32ArrayClass_listautoptr;
typedef GSList *GArrowDecimal32ArrayClass_slistautoptr;
typedef GQueue *GArrowDecimal32ArrayClass_queueautoptr;

static __attribute__((__unused__)) inline void
glib_autoptr_clear_GArrowDecimal32ArrayClass(GArrowDecimal32ArrayClass *_ptr) {
  if (_ptr)
    (g_type_class_unref)((GArrowDecimal32ArrayClass *)_ptr);
}
static __attribute__((__unused__)) inline void
glib_autoptr_cleanup_GArrowDecimal32ArrayClass(
    GArrowDecimal32ArrayClass **_ptr) {
  glib_autoptr_clear_GArrowDecimal32ArrayClass(*_ptr);
}
static __attribute__((__unused__)) inline void
glib_autoptr_destroy_GArrowDecimal32ArrayClass(void *_ptr) {
  (g_type_class_unref)((GArrowDecimal32ArrayClass *)_ptr);
}
static __attribute__((__unused__)) inline void
glib_listautoptr_cleanup_GArrowDecimal32ArrayClass(GList **_l) {
  g_list_free_full(*_l, glib_autoptr_destroy_GArrowDecimal32ArrayClass);
}
static __attribute__((__unused__)) inline void
glib_slistautoptr_cleanup_GArrowDecimal32ArrayClass(GSList **_l) {
  g_slist_free_full(*_l, glib_autoptr_destroy_GArrowDecimal32ArrayClass);
}
static __attribute__((__unused__)) inline void
glib_queueautoptr_cleanup_GArrowDecimal32ArrayClass(GQueue **_q) {
  if (*_q)
    g_queue_free_full(*_q, glib_autoptr_destroy_GArrowDecimal32ArrayClass);
}

__attribute__((__unused__)) static inline GArrowDecimal32Array *
GARROW_DECIMAL32_ARRAY(gpointer ptr) {
  return (((GArrowDecimal32Array *)(void *)g_type_check_instance_cast(
      (GTypeInstance *)(ptr), (garrow_decimal32_array_get_type()))));
}
__attribute__((__unused__)) static inline GArrowDecimal32ArrayClass *
GARROW_DECIMAL32_ARRAY_CLASS(gpointer ptr) {
  return (((GArrowDecimal32ArrayClass *)(void *)g_type_check_class_cast(
      (GTypeClass *)(ptr), (garrow_decimal32_array_get_type()))));
}
__attribute__((__unused__)) static inline gboolean
GARROW_IS_DECIMAL32_ARRAY(gpointer ptr) {
  return ((__extension__({
    GTypeInstance *__inst = (GTypeInstance *)(ptr);
    GType __t = (garrow_decimal32_array_get_type());
    gboolean __r;
    if (!__inst)
      __r = (0);
    else if (__inst->g_class && __inst->g_class->g_type == __t)
      __r = (!(0));
    else
      __r = g_type_check_instance_is_a(__inst, __t);
    __r;
  })));
}
__attribute__((__unused__)) static inline gboolean
GARROW_IS_DECIMAL32_ARRAY_CLASS(gpointer ptr) {
  return ((__extension__({
    GTypeClass *__class = (GTypeClass *)(ptr);
    GType __t = (garrow_decimal32_array_get_type());
    gboolean __r;
    if (!__class)
      __r = (0);
    else if (__class->g_type == __t)
      __r = (!(0));
    else
      __r = g_type_check_class_is_a(__class, __t);
    __r;
  })));
}
__attribute__((__unused__)) static inline GArrowDecimal32ArrayClass *
GARROW_DECIMAL32_ARRAY_GET_CLASS(gpointer ptr) {
  return (((GArrowDecimal32ArrayClass *)(((GTypeInstance *)(ptr))->g_class)));
}
Hiroyuki SatoHiroyuki Sato
G_DEFINE_TYPE(GArrowDecimal32DataType,
              garrow_decimal32_data_type,
              GARROW_TYPE_DECIMAL_DATA_TYPE)
static void garrow_decimal32_data_type_init(GArrowDecimal32DataType *self);
static void
garrow_decimal32_data_type_class_init(GArrowDecimal32DataTypeClass *klass);
static GType garrow_decimal32_data_type_get_type_once(void);
static gpointer garrow_decimal32_data_type_parent_class = ((void *)0);
static gint GArrowDecimal32DataType_private_offset;
static void garrow_decimal32_data_type_class_intern_init(gpointer klass) {
  garrow_decimal32_data_type_parent_class = g_type_class_peek_parent(klass);
  if (GArrowDecimal32DataType_private_offset != 0)
    g_type_class_adjust_private_offset(klass,
                                       &GArrowDecimal32DataType_private_offset);
  garrow_decimal32_data_type_class_init((GArrowDecimal32DataTypeClass *)klass);
}
__attribute__((__unused__)) static inline gpointer
garrow_decimal32_data_type_get_instance_private(GArrowDecimal32DataType *self) {
  return (((gpointer)((guint8 *)(self) +
                      (glong)(GArrowDecimal32DataType_private_offset))));
}
GType garrow_decimal32_data_type_get_type(void) {
  static GType static_g_define_type_id = 0;
  if ((__extension__({
        _Static_assert(sizeof *(&static_g_define_type_id) == sizeof(gpointer),
                       "Expression evaluates to false");
        (void)(0 ? (gpointer) * (&static_g_define_type_id) : ((void *)0));
        (!(__extension__({
          _Static_assert(sizeof *(&static_g_define_type_id) == sizeof(gpointer),
                         "Expression evaluates to false");
          __typeof__(*(&static_g_define_type_id)) gapg_temp_newval;
          __typeof__((&static_g_define_type_id)) gapg_temp_atomic =
              (&static_g_define_type_id);
          __atomic_load(gapg_temp_atomic, &gapg_temp_newval, 5);
          gapg_temp_newval;
        })) &&
         g_once_init_enter_pointer(&static_g_define_type_id));
      }))) {
    GType g_define_type_id = garrow_decimal32_data_type_get_type_once();
    (__extension__({
      _Static_assert(sizeof *(&static_g_define_type_id) == sizeof(gpointer),
                     "Expression evaluates to false");
      0 ? (void)(*(&static_g_define_type_id) = (g_define_type_id)) : (void)0;
      g_once_init_leave_pointer((&static_g_define_type_id),
                                (gpointer)(guintptr)(g_define_type_id));
    }));
  }
  return static_g_define_type_id;
}
__attribute__((__noinline__)) static GType
garrow_decimal32_data_type_get_type_once(void) {
  GType g_define_type_id = g_type_register_static_simple(
      GARROW_TYPE_DECIMAL_DATA_TYPE,
      g_intern_static_string("GArrowDecimal32DataType"),
      sizeof(GArrowDecimal32DataTypeClass),
      (GClassInitFunc)(void (*)(
          void))garrow_decimal32_data_type_class_intern_init,
      sizeof(GArrowDecimal32DataType),
      (GInstanceInitFunc)(void (*)(void))garrow_decimal32_data_type_init,
      (GTypeFlags)0);
  {
    {
      {};
    }
  }
  return g_define_type_id;
}
Hiroyuki SatoHiroyuki Sato
G_DEFINE_TYPE_WITH_PRIVATE(GArrowDecimal32, garrow_decimal32, G_TYPE_OBJECT)
static void garrow_decimal32_init(GArrowDecimal32 *self);
static void garrow_decimal32_class_init(GArrowDecimal32Class *klass);
static GType garrow_decimal32_get_type_once(void);
static gpointer garrow_decimal32_parent_class = ((void *)0);
static gint GArrowDecimal32_private_offset;
static void garrow_decimal32_class_intern_init(gpointer klass) {
  garrow_decimal32_parent_class = g_type_class_peek_parent(klass);
  if (GArrowDecimal32_private_offset != 0)
    g_type_class_adjust_private_offset(klass, &GArrowDecimal32_private_offset);
  garrow_decimal32_class_init((GArrowDecimal32Class *)klass);
}
__attribute__((__unused__)) static inline gpointer
garrow_decimal32_get_instance_private(GArrowDecimal32 *self) {
  return (
      ((gpointer)((guint8 *)(self) + (glong)(GArrowDecimal32_private_offset))));
}
GType garrow_decimal32_get_type(void) {
  static GType static_g_define_type_id = 0;
  if ((__extension__({
        _Static_assert(sizeof *(&static_g_define_type_id) == sizeof(gpointer),
                       "Expression evaluates to false");
        (void)(0 ? (gpointer) * (&static_g_define_type_id) : ((void *)0));
        (!(__extension__({
          _Static_assert(sizeof *(&static_g_define_type_id) == sizeof(gpointer),
                         "Expression evaluates to false");
          __typeof__(*(&static_g_define_type_id)) gapg_temp_newval;
          __typeof__((&static_g_define_type_id)) gapg_temp_atomic =
              (&static_g_define_type_id);
          __atomic_load(gapg_temp_atomic, &gapg_temp_newval, 5);
          gapg_temp_newval;
        })) &&
         g_once_init_enter_pointer(&static_g_define_type_id));
      }))) {
    GType g_define_type_id = garrow_decimal32_get_type_once();
    (__extension__({
      _Static_assert(sizeof *(&static_g_define_type_id) == sizeof(gpointer),
                     "Expression evaluates to false");
      0 ? (void)(*(&static_g_define_type_id) = (g_define_type_id)) : (void)0;
      g_once_init_leave_pointer((&static_g_define_type_id),
                                (gpointer)(guintptr)(g_define_type_id));
    }));
  }
  return static_g_define_type_id;
}
__attribute__((__noinline__)) static GType
garrow_decimal32_get_type_once(void) {
  GType g_define_type_id = g_type_register_static_simple(
      ((GType)((20) << (2))), g_intern_static_string("GArrowDecimal32"),
      sizeof(GArrowDecimal32Class),
      (GClassInitFunc)(void (*)(void))garrow_decimal32_class_intern_init,
      sizeof(GArrowDecimal32),
      (GInstanceInitFunc)(void (*)(void))garrow_decimal32_init, (GTypeFlags)0);
  {
    {
      {
        GArrowDecimal32_private_offset = g_type_add_instance_private(
            g_define_type_id, sizeof(GArrowDecimal32Private));
      };
    }
  }
  return g_define_type_id;
}
Hiroyuki SatoHiroyuki Sato

GArrowBinaryViewDataType を作るときに、cpp内で実装しないといけない必須の関数はclass_init, init, new の三つつまりこういうこと。

G_DEFINE_TYPE(GArrowBinaryViewDataType,
              garrow_binary_view_data_type,
              GARROW_TYPE_DATA_TYPE)

static void
garrow_binary_view_data_type_init(GArrowBinaryViewDataType *object)
{
}

static void
garrow_binary_view_data_type_class_init(GArrowBinaryViewDataTypeClass *klass)
{
}

GArrowBinaryViewDataType *
garrow_binary_view_data_type_new(void)
{
}
Hiroyuki SatoHiroyuki Sato

Cの機能だけを使っている公開される定義はG_BEGIN_DECLS/G_END_DECLS内で、C++の機能を使っている定義は外です。たとえば、std::shared_ptr<...>はC++の機能