Skip to content

velox_buffer_test fails under monolithic build with "undefined symbols" error #33

@yingsu00

Description

@yingsu00

Problem description

In https://github.com/facebookincubator/velox/actions/runs/15969580003/job/45037545305?pr=13851, test symbols like VectorTestBase::~VectorTestBase() were missing from lib/libvelox.so when building velox_buffer_test:

/opt/rh/gcc-toolset-12/root/usr/libexec/gcc/x86_64-redhat-linux/12/ld: lib/libvelox.so: undefined reference to facebook::velox::test::VectorTestBase::~VectorTestBase()'
/opt/rh/gcc-toolset-12/root/usr/libexec/gcc/x86_64-redhat-linux/12/ld: lib/libvelox.so: undefined reference to facebook::velox::functions::test::FunctionBaseTest::SetUpTestCase()'
/opt/rh/gcc-toolset-12/root/usr/libexec/gcc/x86_64-redhat-linux/12/ld: lib/libvelox.so: undefined reference to facebook::velox::test::TypeTestBase::testTypeSerde(std::shared_ptr<facebook::velox::Type const> const&)'
/opt/rh/gcc-toolset-12/root/usr/libexec/gcc/x86_64-redhat-linux/12/ld: lib/libvelox.so: undefined reference to facebook::velox::test::TypeTestBase::TypeTestBase()'
/opt/rh/gcc-toolset-12/root/usr/libexec/gcc/x86_64-redhat-linux/12/ld: lib/libvelox.so: undefined reference to facebook::velox::test::VectorMaker::rowVector(std::vector<std::shared_ptr<facebook::velox::BaseVector>, std::allocator<std::shared_ptr<facebook::velox::BaseVector> > > const&)'
collect2: error: ld returned 1 exit status

This happens when VELOX_MONO_LIBRARY was enabled. There are two things causing this error:

  1. Under such a “mono‐library” build, every component target (like velox_buffer) is just an alias to the single big velox target.
    CMake/VeloxUtils.cmake:
function(velox_add_library TARGET)
  …
  if(VELOX_MONO_LIBRARY)
    if(TARGET velox)
      # append sources to the existing 'velox' target …
      target_sources(velox PRIVATE ${ARGN})
      install(TARGETS velox LINK_LIBRARY DESTINATION pyvelox COMPONENT pyvelox_libraries)
    else()
      set(_type STATIC)
      if(VELOX_BUILD_SHARED)
        set(_type SHARED)
      endif()
      # This is where libvelox.so is actually defined:
      add_library(velox ${_type} ${ARGN})
      set_target_properties(velox
        PROPERTIES
          LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib
          ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib
      )
      install(TARGETS velox DESTINATION lib/velox)
    endif()
    
    if(NOT TARGET ${TARGET})
      add_library(${TARGET} ALIAS velox) # alias each component target name back to the mono‐lib
    endif()
  else()
    # non-mono build creates separate libs instead
    velox_base_add_library(${TARGET} ${library_type} ${ARGN})
  endif()
  …
endfunction()

  1. velox_buffer_test only links to velox_buffer but not other test libs that contains those symbols.```
    target_link_libraries(
    velox_buffer_test
    velox_buffer # alias to the mono velox target
    GTest::gtest

    )
That causes g++ to pull in lib/libvelox.so on the link line. Any undefined symbols referenced inside libvelox.so will therefore be reported as missing at that final link step.

A quick fix for velox_buffer_test is to add the required test libs:

target_link_libraries(
velox_buffer_test
velox_buffer
velox_memory
velox_functions_test_lib # add
velox_presto_types_test_lib # add
velox_vector_test_lib # add
...
velox_test_util
...)

But in long term, we should avoid pulling test code into libvelox.so, the main production library. It happens when velox_add_library() was called on test targets, for example in velox/common/testutil/CMakeLists.txt:

velox_add_library(velox_test_util
ScopedTestTime.cpp
TestValue.cpp
RandomSeed.cpp
)
velox_link_libraries(
velox_test_util
PUBLIC velox_exception
PRIVATE glog::glog
Folly::folly
)

velox_add_library would add velox_test_util into libvelox.so, which is not supposed to happen. As a proper fix, we need to solve this and remove all test code from the production library libvelox.so.

### System information

Linux Ubuntu

### CMake log

```bash
FAILED: velox/buffer/tests/velox_buffer_test 
: && /opt/rh/gcc-toolset-12/root/bin/g++ -mavx2 -mfma -mavx -mf16c -mlzcnt -mbmi2 -D USE_VELOX_COMMON_BASE -D HAS_UNCAUGHT_EXCEPTIONS -DFOLLY_CFG_NO_COROUTINES -Wall -Wextra -Wno-unused        -Wno-unused-parameter        -Wno-sign-compare        -Wno-ignored-qualifiers        -Wno-implicit-fallthrough          -Wno-class-memaccess          -Wno-comment          -Wno-int-in-bool-context          -Wno-redundant-move          -Wno-array-bounds          -Wno-maybe-uninitialized          -Wno-unused-result          -Wno-format-overflow          -Wno-strict-aliasing -Werror -O3 -DNDEBUG -Wl,-export-dynamic velox/buffer/tests/CMakeFiles/velox_buffer_test.dir/BufferTest.cpp.o velox/buffer/tests/CMakeFiles/velox_buffer_test.dir/StringViewBufferHolderTest.cpp.o -o velox/buffer/tests/velox_buffer_test  -Wl,-rpath,/__w/velox/velox/_build/release/lib:/usr/local/lib64:/usr/local/lib:/__w/velox/velox/_build/release/_deps/curl-build/lib  lib/libvelox.so  lib/libgtest.a  lib/libgtest_main.a  lib/libgmock.a  /usr/local/lib64/libglog.so  -lpthread  /usr/local/lib64/libgflags.so.2.2.2  /usr/lib64/liblz4.so  /usr/lib64/libre2.so.9.0.0  /usr/local/lib64/libarrow.a  /usr/lib64/libdouble-conversion.so.3.1.5  /usr/local/lib64/libsnappy.a  /usr/local/lib64/libprotobuf.a  /usr/lib64/libzstd.so  /usr/local/lib/libthrift.a  velox/tpch/gen/dbgen/libdbgen.a  /usr/local/lib64/libsimdjson.a  /usr/local/lib/libstemmer.a  _deps/faiss-build/faiss/libfaiss.a  -lgomp  /lib64/libpthread.a  /usr/lib64/libopenblas.so  -lm  -ldl  /usr/local/lib64/libgeos.so.3.10.7  velox/functions/remote/if/libremote_function_thrift.a  /usr/local/lib/libthriftcpp2.a  /usr/local/lib/libthriftfrozen2.a  /usr/local/lib/libthriftmetadata.a  /usr/local/lib/libthriftanyrep.a  /usr/local/lib/libthrifttype.a  /usr/local/lib/libthriftprotocol.a  /usr/local/lib/libthriftprotocol.a  /usr/local/lib/libasync.a  /usr/local/lib/libruntime.a  /usr/local/lib/libtransport.a  /usr/local/lib/librpcmetadata.a  /usr/local/lib/libconcurrency.a  /lib64/libzstd.so  /usr/local/lib/libwangle.a  /usr/local/lib/libfizz.a  /usr/lib64/libsodium.so  /usr/lib64/librt.a  /usr/local/lib/libthrift-core.a  /usr/local/lib/libthrifttyperep.a  /usr/local/lib/libthriftannotation.a  /usr/local/lib/libserverdbginfo.a  /usr/local/lib/libfolly.so.0.58.0-dev  /usr/local/lib64/libfmt.a  /usr/local/lib/libboost_regex.so.1.84.0  /usr/local/lib/libboost_context.so.1.84.0  /usr/local/lib/libboost_filesystem.so.1.84.0  /usr/local/lib/libboost_program_options.so.1.84.0  /usr/local/lib/libboost_system.so.1.84.0  /usr/local/lib/libboost_thread.so.1.84.0  /usr/local/lib/libboost_atomic.so.1.84.0  /usr/lib64/libdouble-conversion.so  /usr/local/lib64/libgflags.so.2.2.2  /usr/local/lib64/libglog.so  /usr/lib64/libevent.so  /usr/lib64/libssl.so  /usr/lib64/libcrypto.so  /usr/lib64/liblz4.so  /usr/lib64/libzstd.so  /usr/local/lib64/libsnappy.a  /usr/lib64/libdwarf.so  /usr/lib64/libsodium.so  /usr/lib64/libxxhash.so  /usr/local/lib64/libaws-cpp-sdk-s3.a  /usr/local/lib64/libaws-cpp-sdk-identity-management.a  /usr/local/lib64/libaws-cpp-sdk-cognito-identity.a  /usr/local/lib64/libaws-cpp-sdk-sts.a  /usr/local/lib64/libaws-cpp-sdk-core.a  /usr/lib64/libz.so  /usr/lib64/libcurl.so  /usr/lib64/libz.so  /usr/local/lib64/libaws-crt-cpp.a  /usr/local/lib64/libaws-c-mqtt.a  /usr/local/lib64/libaws-c-event-stream.a  /usr/local/lib64/libaws-c-s3.a  /usr/local/lib64/libaws-c-auth.a  /usr/local/lib64/libaws-c-http.a  /usr/local/lib64/libaws-c-io.a  /usr/local/lib64/libs2n.a  /usr/lib64/libcrypto.so  /usr/local/lib64/libaws-c-compression.a  /usr/local/lib64/libaws-c-cal.a  /usr/local/lib64/libaws-c-sdkutils.a  /usr/local/lib64/libaws-checksums.a  /usr/local/lib64/libaws-c-common.a  -lpthread  -lm  -lrt  /usr/local/lib64/libgoogle_cloud_cpp_storage.a  /usr/local/lib64/libabsl_cord.a  /usr/local/lib64/libabsl_cordz_info.a  /usr/local/lib64/libabsl_cord_internal.a  /usr/local/lib64/libabsl_cordz_functions.a  /usr/local/lib64/libabsl_exponential_biased.a  /usr/local/lib64/libabsl_cordz_handle.a  /usr/local/lib64/libabsl_synchronization.a  /usr/local/lib64/libabsl_stacktrace.a  /usr/local/lib64/libabsl_graphcycles_internal.a  /usr/local/lib64/libabsl_kernel_timeout_internal.a  /usr/local/lib64/libabsl_symbolize.a  /usr/local/lib64/libabsl_debugging_internal.a  /usr/local/lib64/libabsl_malloc_internal.a  /usr/local/lib64/libabsl_demangle_internal.a  /usr/local/lib64/libabsl_crc_cord_state.a  /usr/local/lib64/libabsl_crc32c.a  /usr/local/lib64/libabsl_crc_internal.a  /usr/local/lib64/libabsl_crc_cpu_detect.a  /usr/local/lib64/libgoogle_cloud_cpp_rest_internal.a  /usr/local/lib64/libgoogle_cloud_cpp_common.a  /usr/local/lib64/libabsl_time.a  /usr/local/lib64/libabsl_civil_time.a  /usr/local/lib64/libabsl_time_zone.a  /usr/local/lib64/libabsl_bad_variant_access.a  /usr/local/lib64/libabsl_bad_optional_access.a  /usr/local/lib64/libabsl_str_format_internal.a  /usr/local/lib64/libabsl_strings.a  /usr/local/lib64/libabsl_strings_internal.a  /usr/local/lib64/libabsl_string_view.a  /usr/local/lib64/libabsl_base.a  /usr/local/lib64/libabsl_spinlock_wait.a  -lrt  /usr/local/lib64/libabsl_int128.a  /usr/local/lib64/libabsl_throw_delegate.a  /usr/local/lib64/libabsl_raw_logging_internal.a  /usr/local/lib64/libabsl_log_severity.a  /usr/local/lib64/libcrc32c.a  /usr/local/lib64/libazure-identity.a  /usr/local/lib64/libazure-storage-files-datalake.a  /usr/local/lib64/libazure-storage-blobs.a  /usr/local/lib64/libazure-storage-common.a  /usr/local/lib64/libazure-core.a  _deps/curl-build/lib/libcurl.so.4.8.0  /usr/lib64/libssl.so  /usr/lib64/libcrypto.so  /usr/lib64/libxml2.so  /usr/local/lib/libduckdb_static.a  -ldl  /usr/local/lib/libduckdb_fsst.a  /usr/local/lib/libduckdb_fmt.a  /usr/local/lib/libduckdb_pg_query.a  /usr/local/lib/libduckdb_re2.a  /usr/local/lib/libduckdb_miniz.a  /usr/local/lib/libduckdb_utf8proc.a  /usr/local/lib/libduckdb_hyperloglog.a  /usr/local/lib/libduckdb_fastpforlib.a  /usr/local/lib/libduckdb_mbedtls.a  /usr/local/lib/libjemalloc_extension.a  lib/libgtest.a && :
/opt/rh/gcc-toolset-12/root/usr/libexec/gcc/x86_64-redhat-linux/12/ld: lib/libvelox.so: undefined reference to `facebook::velox::test::VectorTestBase::~VectorTestBase()'
/opt/rh/gcc-toolset-12/root/usr/libexec/gcc/x86_64-redhat-linux/12/ld: lib/libvelox.so: undefined reference to `facebook::velox::functions::test::FunctionBaseTest::SetUpTestCase()'
/opt/rh/gcc-toolset-12/root/usr/libexec/gcc/x86_64-redhat-linux/12/ld: lib/libvelox.so: undefined reference to `facebook::velox::test::TypeTestBase::testTypeSerde(std::shared_ptr<facebook::velox::Type const> const&)'
/opt/rh/gcc-toolset-12/root/usr/libexec/gcc/x86_64-redhat-linux/12/ld: lib/libvelox.so: undefined reference to `facebook::velox::test::TypeTestBase::TypeTestBase()'
/opt/rh/gcc-toolset-12/root/usr/libexec/gcc/x86_64-redhat-linux/12/ld: lib/libvelox.so: undefined reference to `facebook::velox::test::VectorMaker::rowVector(std::vector<std::shared_ptr<facebook::velox::BaseVector>, std::allocator<std::shared_ptr<facebook::velox::BaseVector> > > const&)'
collect2: error: ld returned 1 exit status
[2268/2975] Building CXX object velox/functions/sparksql/benchmarks/CMakeFiles/velox_sparksql_benchmarks_hash.dir/HashBenchmark.cpp.o
[2269/2975] Building CXX object velox/connectors/fuzzer/CMakeFiles/velox_fuzzer_connector.dir/FuzzerConnector.cpp.o
[2270/2975] Building CXX object velox/functions/sparksql/tests/CMakeFiles/velox_functions_spark_test.dir/XxHash64Test.cpp.o
[2271/2975] Building CXX object velox/connectors/hive/iceberg/tests/CMakeFiles/velox_dwio_iceberg_reader_benchmark_lib.dir/IcebergSplitReaderBenchmark.cpp.o
[2272/2975] Building CXX object velox/functions/remote/benchmarks/CMakeFiles/velox_benchmark_local_remote_comparison.dir/LocalRemoteComparisonBenchmark.cpp.o
[2273/2975] Building CXX object velox/functions/tests/CMakeFiles/velox_function_registry_test.dir/FunctionRegistryTest.cpp.o
[2274/2975] Building CXX object velox/functions/remote/client/tests/CMakeFiles/velox_functions_remote_client_test.dir/RemoteFunctionTest.cpp.o
ninja: build stopped: subcommand failed.
make[1]: *** [Makefile:110: build] Error 1
make[1]: Leaving directory '/__w/velox/velox'
make: *** [Makefile:117: release] Error 2
Error: Process completed with exit code 2.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions