Browse Source

cmake: merge_static_libs - correct duplicate assumptions (#1583)

This corrects build failures on ppc64{,le} with the
WITH_EMBEDDED_SERVER option enabled.

MDEV-22641 added an unusual case in which the same object
file in was included twice with a different function
defination. The original cmake/merge_archives_unix.cmake
did not tolerate such eventualities.

So we move to the highest voted answer on Stack Overflow
for the merging of static libraries.
https://stackoverflow.com/questions/3821916/how-to-merge-two-ar-static-libraries-into-one

Thin archives generated compile failures and the libtool
mechanism would of been another dependency and using .la
files that isn't part of a normal cmake output. The straight
Apple mechanism of libtool with static archives also failed
on Linux.

This leaves the MRI script mechansim which was implemented
in this change.
pull/1587/head
Daniel Black 5 years ago
committed by Vladislav Vaintroub
parent
commit
dc06873474
  1. 2
      .gitignore
  2. 32
      cmake/libutils.cmake
  3. 42
      cmake/merge_archives_unix.cmake

2
.gitignore

@ -8,6 +8,8 @@
.*.swp
*.ninja
.ninja_*
*.mri
*.mri.tpl
.gdb_history
.vs/
errmsg.sys

32
cmake/libutils.cmake

@ -127,7 +127,8 @@ ENDMACRO()
# Merge static libraries into a big static lib. The resulting library
# should not not have dependencies on other static libraries.
# We use it in MySQL to merge mysys,dbug,vio etc into mysqlclient
# We use it in MariaDB to merge mysys,dbug,vio etc into the embedded server
# mariadbd.
MACRO(MERGE_STATIC_LIBS TARGET OUTPUT_NAME LIBS_TO_MERGE)
# To produce a library we need at least one source file.
@ -196,18 +197,33 @@ MACRO(MERGE_STATIC_LIBS TARGET OUTPUT_NAME LIBS_TO_MERGE)
)
ELSE()
# Generic Unix, Cygwin or MinGW. In post-build step, call
# script, that extracts objects from archives with "ar x"
# and repacks them with "ar r"
# script, that uses a MRI script to append static archives.
IF(CMAKE_VERSION VERSION_LESS "3.0")
SET(MRI_SCRIPT "${CMAKE_CURRENT_BINARY_DIR}/${TARGET}.mri")
ELSE()
SET(MRI_SCRIPT "${CMAKE_CURRENT_BINARY_DIR}/${TARGET}-$<CONFIG>.mri")
ENDIF()
SET(MRI_SCRIPT_TPL "${MRI_SCRIPT}.tpl")
SET(SCRIPT_CONTENTS "CREATE $<TARGET_FILE:${TARGET}>\n")
FOREACH(LIB ${STATIC_LIBS})
STRING(APPEND SCRIPT_CONTENTS "ADDLIB ${LIB}\n")
ENDFOREACH()
STRING(APPEND SCRIPT_CONTENTS "SAVE\nEND\n")
FILE(WRITE ${MRI_SCRIPT_TPL} "${SCRIPT_CONTENTS}")
FILE(GENERATE OUTPUT ${MRI_SCRIPT} INPUT ${MRI_SCRIPT_TPL})
ADD_CUSTOM_COMMAND(TARGET ${TARGET} POST_BUILD
DEPENDS ${MRI_SCRIPT}
COMMAND ${CMAKE_COMMAND}
-DTARGET_LOCATION="$<TARGET_FILE:${TARGET}>"
-DTARGET="${TARGET}"
-DSTATIC_LIBS="${STATIC_LIBS}"
-DCMAKE_CURRENT_BINARY_DIR="${CMAKE_CURRENT_BINARY_DIR}"
ARGS
-DTARGET_SCRIPT="${MRI_SCRIPT}"
-DCMAKE_AR="${CMAKE_AR}"
-DCMAKE_RANLIB="${CMAKE_RANLIB}"
-P "${MYSQL_CMAKE_SCRIPT_DIR}/merge_archives_unix.cmake"
COMMAND ${CMAKE_RANLIB}
ARGS $<TARGET_FILE:${TARGET}>
)
SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES ${MRI_SCRIPT_TPL})
ENDIF()
ENDIF()
ENDMACRO()

42
cmake/merge_archives_unix.cmake

@ -1,4 +1,4 @@
# Copyright (c) 2009 Sun Microsystems, Inc.
# Copyright (c) 2020 IBM
# Use is subject to license terms.
#
# This program is free software; you can redistribute it and/or modify
@ -14,43 +14,7 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA
FILE(REMOVE "${TARGET_LOCATION}")
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)
SEPARATE_ARGUMENTS(STATIC_LIBS UNIX_COMMAND "${STATIC_LIBS}")
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}
)
FILE(GLOB_RECURSE LIB_OBJECTS "${TEMP_SUBDIR}/*")
SET(OBJECTS ${OBJECTS} ${LIB_OBJECTS})
ENDFOREACH()
# Use relative paths, makes command line shorter.
GET_FILENAME_COMPONENT(ABS_TEMP_DIR ${TEMP_DIR} ABSOLUTE)
FOREACH(OBJ ${OBJECTS})
FILE(RELATIVE_PATH OBJ ${ABS_TEMP_DIR} ${OBJ})
FILE(TO_NATIVE_PATH ${OBJ} OBJ)
SET(ALL_OBJECTS ${ALL_OBJECTS} ${OBJ})
ENDFOREACH()
FILE(TO_NATIVE_PATH ${TARGET_LOCATION} ${TARGET_LOCATION})
# Now pack the objects into library with ar.
EXECUTE_PROCESS(
COMMAND ${CMAKE_AR} -r ${TARGET_LOCATION} ${ALL_OBJECTS}
WORKING_DIRECTORY ${TEMP_DIR}
COMMAND ${CMAKE_AR} -M
INPUT_FILE ${TARGET_SCRIPT}
)
EXECUTE_PROCESS(
COMMAND ${CMAKE_RANLIB} ${TARGET_LOCATION}
WORKING_DIRECTORY ${TEMP_DIR}
)
# Cleanup
FILE(REMOVE_RECURSE ${TEMP_DIR})
Loading…
Cancel
Save