Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(c++): fix the 'multiple definition' bug when linking libarrow.a and libgraphar_bundled_dependencies.a in one CMakeLists.txt #657

Merged
merged 2 commits into from
Dec 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
137 changes: 122 additions & 15 deletions cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,94 @@ macro(install_graphar_target target)
)
endmacro()

# Implementations of lisp "car" and "cdr" functions
macro(GRAPHAR_CAR var)
set(${var} ${ARGV1})
endmacro()

macro(GRAPHAR_CDR var rest)
set(${var} ${ARGN})
endmacro()

# Based on MIT-licensed
# https://gist.github.com/cristianadam/ef920342939a89fae3e8a85ca9459b49
function(graphar_create_merged_static_lib output_target)
set(options)
set(one_value_args NAME ROOT)
set(multi_value_args TO_MERGE)
cmake_parse_arguments(ARG
"${options}"
"${one_value_args}"
"${multi_value_args}"
${ARGN})
if(ARG_UNPARSED_ARGUMENTS)
message(SEND_ERROR "Error: unrecognized arguments: ${ARG_UNPARSED_ARGUMENTS}")
endif()

set(output_lib_path
${BUILD_OUTPUT_ROOT_DIRECTORY}${CMAKE_STATIC_LIBRARY_PREFIX}${ARG_NAME}${CMAKE_STATIC_LIBRARY_SUFFIX}
)

set(all_library_paths $<TARGET_FILE:${ARG_ROOT}>)
foreach(lib ${ARG_TO_MERGE})
list(APPEND all_library_paths $<TARGET_FILE:${lib}>)
endforeach()

if(APPLE)
set(BUNDLE_COMMAND "libtool" "-no_warning_for_no_symbols" "-static" "-o"
${output_lib_path} ${all_library_paths})
elseif(CMAKE_CXX_COMPILER_ID MATCHES "^(Clang|GNU|Intel)$")
set(ar_script_path ${CMAKE_BINARY_DIR}/${ARG_NAME}.ar)

file(WRITE ${ar_script_path}.in "CREATE ${output_lib_path}\n")
file(APPEND ${ar_script_path}.in "ADDLIB $<TARGET_FILE:${ARG_ROOT}>\n")

foreach(lib ${ARG_TO_MERGE})
file(APPEND ${ar_script_path}.in "ADDLIB $<TARGET_FILE:${lib}>\n")
endforeach()

file(APPEND ${ar_script_path}.in "SAVE\nEND\n")
file(GENERATE
OUTPUT ${ar_script_path}
INPUT ${ar_script_path}.in)
set(ar_tool ${CMAKE_AR})

if(CMAKE_INTERPROCEDURAL_OPTIMIZATION)
set(ar_tool ${CMAKE_CXX_COMPILER_AR})
endif()

set(BUNDLE_COMMAND ${ar_tool} -M < ${ar_script_path})

elseif(MSVC)
if(CMAKE_LIBTOOL)
set(BUNDLE_TOOL ${CMAKE_LIBTOOL})
else()
find_program(BUNDLE_TOOL lib HINTS "${CMAKE_CXX_COMPILER}/..")
if(NOT BUNDLE_TOOL)
message(FATAL_ERROR "Cannot locate lib.exe to bundle libraries")
endif()
endif()
set(BUNDLE_COMMAND ${BUNDLE_TOOL} /NOLOGO /OUT:${output_lib_path}
${all_library_paths})
else()
message(FATAL_ERROR "Unknown bundle scenario!")
endif()

add_custom_target(${output_target}_merge ALL
${BUNDLE_COMMAND}
DEPENDS ${ARG_ROOT} ${ARG_TO_MERGE}
BYPRODUCTS ${output_lib_path}
COMMENT "Bundling ${output_lib_path}"
VERBATIM)

message(STATUS "Creating bundled static library target ${output_target} at ${output_lib_path}"
)

add_library(${output_target} STATIC IMPORTED)
set_target_properties(${output_target} PROPERTIES IMPORTED_LOCATION ${output_lib_path})
add_dependencies(${output_target} ${output_target}_merge)
endfunction()

macro(build_graphar)
file(GLOB_RECURSE CORE_SRC_FILES "src/graphar/*.cc" ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/mini-yaml/yaml/*.cpp)
if(GRAPHAR_BUILD_STATIC)
Expand Down Expand Up @@ -231,21 +319,40 @@ macro(build_graphar_with_arrow_bundled)
target_include_directories(graphar SYSTEM BEFORE PRIVATE ${GAR_ARROW_INCLUDE_DIR})
target_link_libraries(graphar PRIVATE ${CMAKE_DL_LIBS})

set(GAR_BUNDLED_DEPS_STATIC_LIBS)
list(APPEND GAR_BUNDLED_DEPS_STATIC_LIBS
gar_arrow_static
gar_parquet_static
gar_dataset_static
gar_acero_static
gar_arrow_bundled_dependencies_static)
graphar_car(_FIRST_LIB ${GAR_BUNDLED_DEPS_STATIC_LIBS})
graphar_cdr(_OTHER_LIBS ${GAR_BUNDLED_DEPS_STATIC_LIBS})

graphar_create_merged_static_lib(graphar_bundled_dependencies
NAME
graphar_bundled_dependencies
ROOT
${_FIRST_LIB}
TO_MERGE
${_OTHER_LIBS})
# We can't use install(TARGETS) here because
# graphar_bundled_dependencies is an IMPORTED library.
get_target_property(graphar_bundled_dependencies_path graphar_bundled_dependencies
IMPORTED_LOCATION)
install(FILES ${CMAKE_BINARY_DIR}/${graphar_bundled_dependencies_path} ${INSTALL_IS_OPTIONAL}
DESTINATION ${CMAKE_INSTALL_LIBDIR})
string(APPEND ARROW_PC_LIBS_PRIVATE " -lgraphar_bundled_dependencies")
list(INSERT ARROW_STATIC_INSTALL_INTERFACE_LIBS 0 "graphar_bundled_dependencies")

if(APPLE)
message(STATUS "Linking arrow bundled dependencies " ${GAR_PARQUET_STATIC_LIB} ${GAR_ACERO_STATIC_LIB})
target_link_libraries(graphar PRIVATE -Wl,-force_load gar_arrow_static
"${GAR_PARQUET_STATIC_LIB}"
"${GAR_DATASET_STATIC_LIB}"
"${GAR_ARROW_ACERO_STATIC_LIB}"
"${GAR_ARROW_BUNDLED_DEPS_STATIC_LIB}"
target_link_libraries(graphar PRIVATE -Wl,-force_load
graphar_bundled_dependencies
"-framework CoreFoundation"
"-framework Security")
else()
target_link_libraries(graphar PRIVATE -Wl,--exclude-libs,ALL -Wl,--whole-archive gar_arrow_static
"${GAR_PARQUET_STATIC_LIB}"
"${GAR_DATASET_STATIC_LIB}"
"${GAR_ARROW_ACERO_STATIC_LIB}"
"${GAR_ARROW_BUNDLED_DEPS_STATIC_LIB}" -Wl,--no-whole-archive)
target_link_libraries(graphar PRIVATE -Wl,--exclude-libs,ALL
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove -Wl,--whole-archive and -Wl,--no-whole-archive

graphar_bundled_dependencies)
endif()

# if OpenSSL library exists, link the OpenSSL library.
Expand All @@ -266,7 +373,7 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR}/src)
include_directories(src)

if (BUILD_ARROW_FROM_SOURCE)
# the nessary dependencies for building arrow from source
# the necessary dependencies for building arrow from source
find_package(OpenSSL REQUIRED)
if(OPENSSL_FOUND)
if(OPENSSL_VERSION LESS "1.1.0")
Expand Down Expand Up @@ -334,11 +441,11 @@ if (BUILD_EXAMPLES)
if (BUILD_ARROW_FROM_SOURCE)
target_include_directories(${E_NAME} SYSTEM BEFORE PRIVATE ${GAR_ARROW_INCLUDE_DIR})
if (APPLE)
target_link_libraries(${E_NAME} PRIVATE -Wl,-force_load gar_arrow_static
target_link_libraries(${E_NAME} PRIVATE -Wl,-force_load ${GAR_ARROW_STATIC_LIB}
"${GAR_PARQUET_STATIC_LIB}"
"${GAR_ARROW_BUNDLED_DEPS_STATIC_LIB}")
else()
target_link_libraries(${E_NAME} PRIVATE -Wl,--exclude-libs,ALL -Wl,--whole-archive gar_arrow_static
target_link_libraries(${E_NAME} PRIVATE -Wl,--exclude-libs,ALL -Wl,--whole-archive ${GAR_ARROW_STATIC_LIB}
"${GAR_PARQUET_STATIC_LIB}"
"${GAR_ARROW_BUNDLED_DEPS_STATIC_LIB}" -Wl,--no-whole-archive)
endif()
Expand Down Expand Up @@ -500,4 +607,4 @@ add_custom_target(graphar-clformat
add_custom_target(graphar-cpplint
COMMAND ${PROJECT_SOURCE_DIR}/misc/cpplint.py --root=${PROJECT_SOURCE_DIR}/include ${FILES_NEED_LINT}
COMMENT "Running cpplint check."
VERBATIM)
VERBATIM)
8 changes: 6 additions & 2 deletions cpp/cmake/apache-arrow.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ function(build_arrow)

set(GAR_ARROW_STATIC_LIB_FILENAME
"${CMAKE_STATIC_LIBRARY_PREFIX}arrow${CMAKE_STATIC_LIBRARY_SUFFIX}")
set(GAR_ARROW_STATIC_LIB "${GAR_ARROW_STATIC_LIBRARY_DIR}/${GAR_ARROW_STATIC_LIB_FILENAME}")
set(GAR_ARROW_STATIC_LIB "${GAR_ARROW_STATIC_LIBRARY_DIR}/${GAR_ARROW_STATIC_LIB_FILENAME}" CACHE INTERNAL "arrow lib")
set(GAR_PARQUET_STATIC_LIB_FILENAME
"${CMAKE_STATIC_LIBRARY_PREFIX}parquet${CMAKE_STATIC_LIBRARY_SUFFIX}")
set(GAR_PARQUET_STATIC_LIB "${GAR_ARROW_STATIC_LIBRARY_DIR}/${GAR_PARQUET_STATIC_LIB_FILENAME}" CACHE INTERNAL "parquet lib")
Expand Down Expand Up @@ -129,11 +129,13 @@ function(build_arrow)
set(GAR_ARROW_LIBRARY_TARGET gar_arrow_static)
set(GAR_PARQUET_LIBRARY_TARGET gar_parquet_static)
set(GAR_DATASET_LIBRARY_TARGET gar_dataset_static)
set(GAR_ARROW_BUNDLED_DEPS_TARGET gar_arrow_bundled_dependencies_static)

file(MAKE_DIRECTORY "${GAR_ARROW_INCLUDE_DIR}")
add_library(${GAR_ARROW_LIBRARY_TARGET} STATIC IMPORTED)
add_library(${GAR_PARQUET_LIBRARY_TARGET} STATIC IMPORTED)
add_library(${GAR_DATASET_LIBRARY_TARGET} STATIC IMPORTED)
add_library(${GAR_ARROW_BUNDLED_DEPS_TARGET} STATIC IMPORTED)
set_target_properties(${GAR_ARROW_LIBRARY_TARGET}
PROPERTIES INTERFACE_INCLUDE_DIRECTORIES ${GAR_ARROW_INCLUDE_DIR}
IMPORTED_LOCATION ${GAR_ARROW_STATIC_LIB})
Expand All @@ -143,6 +145,8 @@ function(build_arrow)
set_target_properties(${GAR_DATASET_LIBRARY_TARGET}
PROPERTIES INTERFACE_INCLUDE_DIRECTORIES ${GAR_ARROW_INCLUDE_DIR}
IMPORTED_LOCATION ${GAR_DATASET_STATIC_LIB})
set_target_properties(${GAR_ARROW_BUNDLED_DEPS_TARGET}
PROPERTIES IMPORTED_LOCATION ${GAR_ARROW_BUNDLED_DEPS_STATIC_LIB})
if (ARROW_VERSION_TO_BUILD GREATER_EQUAL "12.0.0")
set(GAR_ARROW_ACERO_STATIC_LIB_FILENAME
"${CMAKE_STATIC_LIBRARY_PREFIX}arrow_acero${CMAKE_STATIC_LIBRARY_SUFFIX}")
Expand All @@ -155,4 +159,4 @@ function(build_arrow)
endif()

add_dependencies(${GAR_ARROW_LIBRARY_TARGET} arrow_ep)
endfunction()
endfunction()
Loading