1# Copyright (c) 2017, 2021, Oracle and/or its affiliates. 2# 3# This program is free software; you can redistribute it and/or modify 4# it under the terms of the GNU General Public License, version 2.0, 5# as published by the Free Software Foundation. 6# 7# This program is also distributed with certain software (including 8# but not limited to OpenSSL) that is licensed under separate terms, 9# as designated in a particular file or component or in included license 10# documentation. The authors of MySQL hereby grant you an additional 11# permission to link the program and your derivative works with the 12# separately licensed software that they have included with MySQL. 13# 14# This program is distributed in the hope that it will be useful, 15# but WITHOUT ANY WARRANTY; without even the implied warranty of 16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17# GNU General Public License, version 2.0, for more details. 18# 19# You should have received a copy of the GNU General Public License 20# along with this program; if not, write to the Free Software 21# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 22 23# Build TARGET_NAME (a static library) from "convenience libraries" 24# -DTARGET_NAME=${TARGET} 25# -DTARGET_LOC=$<TARGET_FILE:${TARGET}> 26# -DCFG_INTDIR=${CMAKE_CFG_INTDIR} 27 28SET(APPLE "@APPLE@") 29SET(LINUX "@LINUX@") 30SET(MSVC "@MSVC@") 31SET(SOLARIS "@SOLARIS@") 32SET(UNIX "@UNIX@") 33 34SET(MYLIBS "@MYLIBS@") 35SET(MYSQL_CMAKE_SCRIPT_DIR "@MYSQL_CMAKE_SCRIPT_DIR@") 36 37SET(CMAKE_AR "@CMAKE_AR@") 38SET(CMAKE_BINARY_DIR "@CMAKE_BINARY_DIR@") 39SET(CMAKE_COMMAND "@CMAKE_COMMAND@") 40SET(CMAKE_CXX_CREATE_STATIC_LIBRARY "@CMAKE_CXX_CREATE_STATIC_LIBRARY@") 41SET(CMAKE_C_CREATE_STATIC_LIBRARY "@CMAKE_C_CREATE_STATIC_LIBRARY@") 42SET(CMAKE_LINKER "@CMAKE_LINKER@") 43SET(CMAKE_RANLIB "@CMAKE_RANLIB@") 44SET(CMAKE_STATIC_LINKER_FLAGS "@CMAKE_STATIC_LINKER_FLAGS@") 45 46# MESSAGE(STATUS "merge_archives MYLIBS ${MYLIBS}") 47# MESSAGE(STATUS "merge_archives TARGET_LINK_FLAGS ${TARGET_LINK_FLAGS}") 48# MESSAGE(STATUS "merge_archives TARGET_LOC ${TARGET_LOC}") 49# MESSAGE(STATUS "merge_archives TARGET_NAME ${TARGET_NAME}") 50# 51# MESSAGE(STATUS "merge_archives CMAKE_AR ${CMAKE_AR}") 52# MESSAGE(STATUS "merge_archives CMAKE_BINARY_DIR ${CMAKE_BINARY_DIR}") 53# MESSAGE(STATUS "merge_archives CMAKE_COMMAND ${CMAKE_COMMAND}") 54# MESSAGE(STATUS "merge_archives CMAKE_CXX_CREATE_STATIC_LIBRARY ${CMAKE_CXX_CREATE_STATIC_LIBRARY}") 55# MESSAGE(STATUS "merge_archives CMAKE_C_CREATE_STATIC_LIBRARY ${CMAKE_C_CREATE_STATIC_LIBRARY}") 56# MESSAGE(STATUS "merge_archives CMAKE_LINKER ${CMAKE_LINKER}") 57# MESSAGE(STATUS "merge_archives CMAKE_RANLIB ${CMAKE_RANLIB}") 58# MESSAGE(STATUS "merge_archives CMAKE_STATIC_LINKER_FLAGS ${CMAKE_STATIC_LINKER_FLAGS}") 59 60SET(LIB_LOCATIONS) 61FOREACH(LIB ${MYLIBS}) 62 SET(FILENAME "${CMAKE_BINARY_DIR}/archive_output_directory") 63 SET(FILENAME "${FILENAME}/${CFG_INTDIR}/lib_location_${LIB}") 64 FILE(READ ${FILENAME} CONTENT) 65 STRING(REGEX REPLACE "\n" "" LIB_LOCATION ${CONTENT}) 66 LIST(APPEND LIB_LOCATIONS ${LIB_LOCATION}) 67# MESSAGE(STATUS "LIB ${LIB} LIB_LOCATION ${LIB_LOCATION}") 68ENDFOREACH() 69 70MACRO(CONFIGURE_FILE_CONTENT content file) 71 SET(CMAKE_CONFIGURABLE_FILE_CONTENT 72 "${content}") 73 CONFIGURE_FILE( 74 ${MYSQL_CMAKE_SCRIPT_DIR}/configurable_file_content.in 75 ${file} 76 @ONLY) 77ENDMACRO() 78 79# Remove the "dummy" library, created from the empty ${TARGET}_depends.c 80EXECUTE_PROCESS( 81 COMMAND ${CMAKE_COMMAND} -E remove ${TARGET_LOC} 82 ) 83 84IF(MSVC) 85 # See CMAKE_CXX_CREATE_STATIC_LIBRARY 86 FIND_PROGRAM(LINK_IN_PATH "link.exe") 87 MESSAGE(STATUS "merge_archives linker in PATH is ${LINK_IN_PATH}") 88 89 EXECUTE_PROCESS( 90 COMMAND ${CMAKE_LINKER} "/lib" "/NOLOGO" "${CMAKE_STATIC_LINKER_FLAGS}" 91 "/OUT:${TARGET_LOC}" ${LIB_LOCATIONS} 92 RESULT_VARIABLE link_result 93 OUTPUT_FILE link_output_file 94 ERROR_FILE link_error_file 95 ) 96 MESSAGE(STATUS "link_result is ${link_result}") 97 IF(link_result) 98 MESSAGE(WARNING "Retrying link with ${LINK_IN_PATH}") 99 EXECUTE_PROCESS( 100 COMMAND ${LINK_IN_PATH} "/lib" "/NOLOGO" "${CMAKE_STATIC_LINKER_FLAGS}" 101 "/OUT:${TARGET_LOC}" ${LIB_LOCATIONS} 102 RESULT_VARIABLE link_result 103 ) 104 ENDIF() 105 106ELSEIF(APPLE) 107 # libtool handles it for us 108 EXECUTE_PROCESS( 109 COMMAND /usr/bin/libtool -static -o ${TARGET_LOC} ${LIB_LOCATIONS} 110 ) 111ELSEIF(LINUX) 112 # First create a "thin" archive, then convert it to a normal one. 113 SET(CONTENT "create ${TARGET_LOC}\n") 114 SET(CONTENT "${CONTENT}addlib ${TARGET_LOC}\n") 115 SET(CONTENT "${CONTENT}save\n") 116 SET(CONTENT "${CONTENT}end\n") 117 CONFIGURE_FILE_CONTENT( 118 ${CONTENT} 119 "${CMAKE_BINARY_DIR}/archive_output_directory/cmake_ar_m_${TARGET_NAME}") 120 EXECUTE_PROCESS( 121 COMMAND ${CMAKE_AR} cqT ${TARGET_LOC} ${LIB_LOCATIONS} 122 ) 123 EXECUTE_PROCESS( 124 COMMAND ${CMAKE_AR} -M 125 INPUT_FILE 126 "${CMAKE_BINARY_DIR}/archive_output_directory/cmake_ar_m_${TARGET_NAME}" 127 ) 128 EXECUTE_PROCESS( 129 COMMAND ${CMAKE_RANLIB} ${TARGET_LOC} 130 ) 131ELSEIF(UNIX) 132 # freebsd and solaris, run 'ar -x' on all libraries, 133 # followed by 'ar -r' on all .o files 134 SET(TEMP_DIR 135 "${CMAKE_BINARY_DIR}/archive_output_directory/merge_archives_${TARGET_NAME}") 136 MAKE_DIRECTORY(${TEMP_DIR}) 137 FOREACH(LIB ${LIB_LOCATIONS}) 138 GET_FILENAME_COMPONENT(NAME_NO_EXT ${LIB} NAME_WE) 139 SET(TEMP_SUBDIR ${TEMP_DIR}/${NAME_NO_EXT}) 140 MAKE_DIRECTORY(${TEMP_SUBDIR}) 141 # Extract files into a sub-directory 142 EXECUTE_PROCESS( 143 COMMAND ${CMAKE_AR} -x ${LIB} 144 WORKING_DIRECTORY ${TEMP_SUBDIR} 145 ) 146 FILE(GLOB_RECURSE LIB_OBJECTS "${TEMP_SUBDIR}/*") 147 SET(OBJECTS ${OBJECTS} ${LIB_OBJECTS}) 148 ENDFOREACH() 149 150 # Use relative paths, makes command line shorter. 151 FOREACH(OBJ ${OBJECTS}) 152 FILE(RELATIVE_PATH OBJ ${TEMP_DIR} ${OBJ}) 153 FILE(TO_NATIVE_PATH ${OBJ} OBJ) 154 SET(ALL_OBJECTS ${ALL_OBJECTS} ${OBJ}) 155 ENDFOREACH() 156 157 EXECUTE_PROCESS( 158 COMMAND ${CMAKE_AR} -r ${TARGET_LOC} ${ALL_OBJECTS} 159 WORKING_DIRECTORY ${TEMP_DIR} 160 ) 161 EXECUTE_PROCESS( 162 COMMAND ${CMAKE_RANLIB} ${TARGET_LOC} 163 ) 164 165 # Cleanup 166 FILE(REMOVE_RECURSE ${TEMP_DIR}) 167ELSE() 168 MESSAGE(FATAL_ERROR "Don't know how to merge libraries.") 169ENDIF() 170