router/cmake/install_macros.cmake (217 lines of code) (raw):

# Copyright (c) 2025, Oracle and/or its affiliates. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2.0, # as published by the Free Software Foundation. # # This program is designed to work with certain software (including # but not limited to OpenSSL) that is licensed under separate terms, # as designated in a particular file or component or in included license # documentation. The authors of MySQL hereby grant you an additional # permission to link the program and your derivative works with the # separately licensed software that they have either included with # the program or referenced in the documentation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License, version 2.0, for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # Move the custom shared library and symlinks to library_output_directory. # # We ensure that the copied custom libraries have the execute bit set. # The following macro is duplicated in `cmake/install_macros.cmake`, # where this instance is being adjusted to handle JIT external # library, used by router. # # Set ${OUTPUT_LIBRARY_NAME} to the new location. # Set ${OUTPUT_TARGET_NAME} to the name of a target which will do the copying. # Add an INSTALL(FILES ....) rule to install library and symlinks into # ${INSTALL_PRIV_LIBDIR} FUNCTION(ROUTER_COPY_CUSTOM_SHARED_LIBRARY library_full_filename OUTPUT_LIBRARY_NAME OUTPUT_TARGET_NAME ) GET_FILENAME_COMPONENT(LIBRARY_EXT "${library_full_filename}" EXT) IF(NOT LIBRARY_EXT STREQUAL ".so") RETURN() ENDIF() GET_FILENAME_COMPONENT(library_directory "${library_full_filename}" DIRECTORY) GET_FILENAME_COMPONENT(library_name "${library_full_filename}" NAME) GET_FILENAME_COMPONENT(library_name_we "${library_full_filename}" NAME_WE) EXECUTE_PROCESS( COMMAND readlink "${library_full_filename}" OUTPUT_VARIABLE library_version OUTPUT_STRIP_TRAILING_WHITESPACE) FIND_SONAME(${library_full_filename} library_soname) FIND_OBJECT_DEPENDENCIES(${library_full_filename} library_dependencies) if("${library_version}" STREQUAL "") SET(library_version ${library_name}) ENDIF() IF("${library_soname}" STREQUAL "") SET(library_soname ${library_name}) ENDIF() MESSAGE(STATUS "CUSTOM library ${library_full_filename}") #MESSAGE(STATUS "CUSTOM version ${library_version}") #MESSAGE(STATUS "CUSTOM directory ${library_directory}") #MESSAGE(STATUS "CUSTOM name ${library_name}") #MESSAGE(STATUS "CUSTOM name_we ${library_name_we}") #MESSAGE(STATUS "CUSTOM soname ${library_soname}") SET(COPIED_LIBRARY_NAME "${CMAKE_BINARY_DIR}/library_output_directory/${library_name}") SET(COPY_TARGET_NAME "copy_${library_name_we}_dll") # Keep track of libraries and dependencies. SET(SONAME_${library_name_we} "${library_soname}" CACHE INTERNAL "SONAME for ${library_name_we}" FORCE) SET(NEEDED_${library_name_we} "${library_dependencies}" CACHE INTERNAL "" FORCE) SET(KNOWN_CUSTOM_LIBRARIES ${KNOWN_CUSTOM_LIBRARIES} ${library_name_we} CACHE INTERNAL "" FORCE) # Do copying and patching in a sub-process, so that we can skip it if # already done. The BYPRODUCTS arguments is needed by Ninja, and is # ignored on non-Ninja generators except to mark byproducts GENERATED. ADD_CUSTOM_TARGET(${COPY_TARGET_NAME} ALL COMMAND ${CMAKE_COMMAND} -Dlibrary_directory="${library_directory}" -Dlibrary_name="${library_name}" -Dlibrary_soname="${library_soname}" -Dlibrary_version="${library_version}" -P ${CMAKE_SOURCE_DIR}/router/cmake/copy_custom_library.cmake BYPRODUCTS "${CMAKE_BINARY_DIR}/library_output_directory/${library_name}" WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/library_output_directory/" ) # Link with the copied library, rather than the original one. SET(${OUTPUT_LIBRARY_NAME} "${COPIED_LIBRARY_NAME}" PARENT_SCOPE) SET(${OUTPUT_TARGET_NAME} "${COPY_TARGET_NAME}" PARENT_SCOPE) ADD_DEPENDENCIES(copy_linux_custom_dlls ${COPY_TARGET_NAME}) MESSAGE(STATUS "INSTALL ${library_name} to ${INSTALL_PRIV_LIBDIR}") # Cannot use INSTALL_PRIVATE_LIBRARY because these are not targets. INSTALL(FILES ${CMAKE_BINARY_DIR}/library_output_directory/${library_name} ${CMAKE_BINARY_DIR}/library_output_directory/${library_soname} ${CMAKE_BINARY_DIR}/library_output_directory/${library_version} DESTINATION "${ROUTER_INSTALL_LIBDIR}" COMPONENT Router PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE ) ENDFUNCTION(ROUTER_COPY_CUSTOM_SHARED_LIBRARY) # For 3rd party .dlls on Windows. # Adds a target which copies the .dll to library_output_directory # Adds INSTALL(FILES ....) rule to install the .dll to ${ROUTER_INSTALL_PLUGINDIR}. # Looks for matching .pdb file, and installs it if found. # The following macro is duplicated in `cmake/install_macros.cmake`, # where this instance is being adjusted to handle JIT external # library, used by router. # # Sets ${OUTPUT_TARGET_NAME} to the name of a target which will do the copying. FUNCTION(ROUTER_COPY_CUSTOM_DLL library_full_filename OUTPUT_LIBRARY_NAME OUTPUT_TARGET_NAME) IF(NOT WIN32) RETURN() ENDIF() GET_FILENAME_COMPONENT(library_directory "${library_full_filename}" DIRECTORY) GET_FILENAME_COMPONENT(library_name "${library_full_filename}" NAME) GET_FILENAME_COMPONENT(library_name_we "${library_full_filename}" NAME_WE) SET(LIBRARY_DIR "${CMAKE_BINARY_DIR}/plugin_output_directory") SET(SOURCE_DLL_NAME "${library_directory}/${library_name_we}.dll") SET(COPIED_LIBRARY_NAME "${LIBRARY_DIR}/${CMAKE_CFG_INTDIR}/${library_name_we}.dll") SET(COPY_TARGET_NAME "copy_${library_name_we}_dll") ADD_CUSTOM_COMMAND( OUTPUT "${COPIED_LIBRARY_NAME}" COMMAND ${CMAKE_COMMAND} -E copy_if_different "${SOURCE_DLL_NAME}" "${COPIED_LIBRARY_NAME}" ) MY_ADD_CUSTOM_TARGET(${COPY_TARGET_NAME} ALL DEPENDS "${COPIED_LIBRARY_NAME}" ) # Install the original file, to avoid referring to CMAKE_CFG_INTDIR. MESSAGE(STATUS "INSTALL ${SOURCE_DLL_NAME} to ${ROUTER_INSTALL_PLUGINDIR}") INSTALL(FILES "${SOURCE_DLL_NAME}" DESTINATION "${ROUTER_INSTALL_PLUGINDIR}" COMPONENT Router ) SET(${OUTPUT_LIBRARY_NAME} "${library_full_filename}" PARENT_SCOPE) SET(${OUTPUT_TARGET_NAME} "${COPY_TARGET_NAME}" PARENT_SCOPE) FIND_FILE(HAVE_${library_name_we}_PDB NAMES "${library_name_we}.pdb" PATHS "${library_directory}" NO_DEFAULT_PATH ) IF(HAVE_${library_name_we}_PDB) SET(COPIED_PDB_NAME "${LIBRARY_DIR}/${CMAKE_CFG_INTDIR}/${library_name_we}.pdb") SET(COPY_TARGET_PDB_NAME "copy_${library_name_we}_pdb") ADD_CUSTOM_COMMAND( OUTPUT "${COPIED_PDB_NAME}" COMMAND ${CMAKE_COMMAND} -E copy_if_different "${HAVE_${library_name_we}_PDB}" "${COPIED_PDB_NAME}" ) MY_ADD_CUSTOM_TARGET(${COPY_TARGET_PDB_NAME} ALL DEPENDS "${COPIED_PDB_NAME}" ) MESSAGE(STATUS "INSTALL ${HAVE_${library_name_we}_PDB} to ${ROUTER_INSTALL_PLUGINDIR}") INSTALL(FILES "${HAVE_${library_name_we}_PDB}" DESTINATION "${ROUTER_INSTALL_PLUGINDIR}" COMPONENT Router ) ENDIF() ENDFUNCTION(ROUTER_COPY_CUSTOM_DLL) # For 3rd party .dylib on MACOS. # Adds a target which copies the .dylib to library_output_directory # Adds INSTALL(FILES ....) rule to install the .dylib to ${ROUTER_INSTALL_PLUGINDIR}. # Sets ${OUTPUT_TARGET_NAME} to the name of a target which will do the copying. FUNCTION(ROUTER_COPY_CUSTOM_DYLIB library_full_filename OUTPUT_LIBRARY_NAME OUTPUT_TARGET_NAME) IF(NOT APPLE) RETURN() ENDIF() GET_FILENAME_COMPONENT(library_directory "${library_full_filename}" DIRECTORY) GET_FILENAME_COMPONENT(library_name "${library_full_filename}" NAME) GET_FILENAME_COMPONENT(library_name_we "${library_full_filename}" NAME_WE) SET(LIBRARY_DIR "${CMAKE_BINARY_DIR}/library_output_directory") SET(PLUGIN_DIR "${CMAKE_BINARY_DIR}/plugin_output_directory") IF(BUILD_IS_SINGLE_CONFIG) SET(COPIED_LIBRARY_NAME "${LIBRARY_DIR}/${library_name}") SET(LINK_PLUGIN_DIR "${PLUGIN_DIR}") ELSE() SET(COPIED_LIBRARY_NAME "${LIBRARY_DIR}/${CMAKE_CFG_INTDIR}/${library_name}") SET(LINK_PLUGIN_DIR "${PLUGIN_DIR}/${CMAKE_CFG_INTDIR}") ENDIF() SET(COPY_TARGET_NAME "copy_${library_name_we}_dylib") SET(LINK_TARGET_NAME "link_${library_name_we}_dylib") SET(BIND_TARGET_NAME "BIND_${library_name_we}_dylib") ADD_CUSTOM_TARGET(${COPY_TARGET_NAME} ALL COMMAND ${CMAKE_COMMAND} -E copy_if_different "${library_full_filename}" "${COPIED_LIBRARY_NAME}" ) ADD_CUSTOM_COMMAND(TARGET ${COPY_TARGET_NAME} POST_BUILD COMMAND install_name_tool -id "@rpath/${library_name}" "${COPIED_LIBRARY_NAME}" ) ADD_CUSTOM_TARGET(${LINK_TARGET_NAME} ALL COMMAND ${CMAKE_COMMAND} -E create_symlink "${COPIED_LIBRARY_NAME}" "${library_name}" WORKING_DIRECTORY "${LINK_PLUGIN_DIR}" COMMENT "Creating libpolyglot symlinks in plugin_output_directory" BYPRODUCTS "${LINK_PLUGIN_DIR}/${library_name}" ) MY_ADD_CUSTOM_TARGET(${BIND_TARGET_NAME} ALL DEPENDS "${COPIED_LIBRARY_NAME}" ) ADD_DEPENDENCIES(${BIND_TARGET_NAME} ${LINK_TARGET_NAME} ) ADD_DEPENDENCIES(${LINK_TARGET_NAME} ${COPY_TARGET_NAME}) MESSAGE(STATUS "INSTALL ${library_full_filename} to ${ROUTER_INSTALL_PLUGINDIR}") INSTALL(FILES "${COPIED_LIBRARY_NAME}" DESTINATION "${ROUTER_INSTALL_PLUGINDIR}" COMPONENT Router ) SET(${OUTPUT_LIBRARY_NAME} "${COPIED_LIBRARY_NAME}" PARENT_SCOPE) SET(${OUTPUT_TARGET_NAME} "${BIND_TARGET_NAME}" PARENT_SCOPE) ENDFUNCTION(ROUTER_COPY_CUSTOM_DYLIB)