Skip to content

Commit

Permalink
Fix issue #12: Compile TokuDB SE into embedded library failed
Browse files Browse the repository at this point in the history
Two problems fixed in this patch:
1. cmake regular expression can't compile for "stdc++";
2. when create libmysqld.a archived library, object files of
   storage/tokudb/ft-index/src/loader.cc and
   storage/tokudb/ft-index/ft/loader/loader.cc conflicts,
   the former is overwrited, and lead to link failure finally.
  • Loading branch information
fungo authored and fungo committed Oct 18, 2016
1 parent c31dd4c commit 3d58918
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 6 deletions.
53 changes: 48 additions & 5 deletions cmake/merge_archives_unix.cmake.in
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,60 @@ SET(CMAKE_RANLIB "@CMAKE_RANLIB@")

SET(TEMP_DIR ${CMAKE_CURRENT_BINARY_DIR}/merge_archives_${TARGET})
MAKE_DIRECTORY(${TEMP_DIR})
# Extract each archive to its own subdirectory(avoid object filename clashes)

# Extract each archive to its own subdirectory(avoid object filename
# clashes) Since the lib may contain objects with the same name, we first
# list the archive contents, then uniquify the object names as we extract
# them.
# For example, in TokuDB, objects of bellow two files conflict.
# 1. storage/tokudb/ft-index/src/loader.cc
# 2. storage/tokudb/ft-index/ft/loader/loader.cc
FOREACH(LIB ${STATIC_LIBS})
GET_FILENAME_COMPONENT(NAME_NO_EXT ${LIB} NAME_WE)
SET(TEMP_SUBDIR ${TEMP_DIR}/${NAME_NO_EXT})
MAKE_DIRECTORY(${TEMP_SUBDIR})
EXECUTE_PROCESS(
COMMAND ${CMAKE_AR} -x ${LIB}
WORKING_DIRECTORY ${TEMP_SUBDIR}
)
COMMAND ${CMAKE_AR} -t ${LIB}
OUTPUT_VARIABLE LIB_OBJS
)
STRING(REGEX REPLACE "\n" ";" LIB_OBJ_LIST "${LIB_OBJS}")
STRING(REGEX REPLACE ";$" "" LIB_OBJ_LIST "${LIB_OBJ_LIST}")

LIST(LENGTH LIB_OBJ_LIST LENGTH_WITH_DUPS)
SET(LIB_OBJ_LIST_NO_DUPS ${LIB_OBJ_LIST})
IF (LENGTH_WITH_DUPS GREATER 0)
LIST(REMOVE_DUPLICATES LIB_OBJ_LIST_NO_DUPS)
ENDIF ()
LIST(LENGTH LIB_OBJ_LIST_NO_DUPS LENGTH_WITHOUT_DUPS)

IF(LENGTH_WITH_DUPS EQUAL LENGTH_WITHOUT_DUPS)
# Optimization for when lib doesn't actually have duplicate object
# names, we can just extract everything.
EXECUTE_PROCESS(
COMMAND ${CMAKE_AR} -x ${LIB}
WORKING_DIRECTORY ${TEMP_SUBDIR}
)
ELSE()
LIST(SORT LIB_OBJ_LIST)
SET(SAME_OBJ_COUNT 1)
SET(LAST_OBJ_NAME)
FOREACH(OBJ ${LIB_OBJ_LIST})
IF(OBJ STREQUAL LAST_OBJ_NAME)
GET_FILENAME_COMPONENT(OBJ_NO_EXT ${OBJ} NAME_WE)
FILE(RENAME "${TEMP_SUBDIR}/${OBJ}" "${TEMP_SUBDIR}/${OBJ_NO_EXT}.${SAME_OBJ_COUNT}.o")
MATH(EXPR SAME_OBJ_COUNT "${SAME_OBJ_COUNT}+1")
ELSE()
SET(SAME_OBJ_COUNT 1)
ENDIF()
SET(LAST_OBJ_NAME "${OBJ}")
EXECUTE_PROCESS(
COMMAND ${CMAKE_AR} -xN ${SAME_OBJ_COUNT} ${LIB} ${OBJ}
WORKING_DIRECTORY ${TEMP_SUBDIR}
)
ENDFOREACH()
ENDIF()

FILE(GLOB_RECURSE LIB_OBJECTS "${TEMP_SUBDIR}/*")
FILE(GLOB_RECURSE LIB_OBJECTS "${TEMP_SUBDIR}/*.o")
SET(OBJECTS ${OBJECTS} ${LIB_OBJECTS})
ENDFOREACH()

Expand Down
6 changes: 5 additions & 1 deletion scripts/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -282,9 +282,13 @@ MACRO(EXTRACT_LINK_LIBRARIES target var)
LIST(REMOVE_ITEM ${target}_LIB_DEPENDS "")
LIST(REMOVE_DUPLICATES ${target}_LIB_DEPENDS)
FOREACH(lib ${${target}_LIB_DEPENDS})
# TokuDB SE is built statically into AliSQL, and depends on stdc++ lib,
# which will be used here. The '+' character has special meaning in
# cmake regex, so "stdc++" need to be escaped before do matching.
string(REPLACE "++" "\\+\\+" lib_escaped ${lib})
# Filter out "general", it is not a library, just CMake hint
# Also, remove duplicates
IF(NOT lib STREQUAL "general" AND NOT ${var} MATCHES "-l${lib} ")
IF(NOT lib STREQUAL "general" AND NOT ${var} MATCHES "-l${lib_escaped} ")
IF (lib MATCHES "^\\-l")
SET(${var} "${${var}} ${lib} ")
ELSEIF(lib MATCHES "^/")
Expand Down

0 comments on commit 3d58918

Please sign in to comment.