From 86475591d44c96d7eeae4e5a0232fe7d86105a70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrien=20B=C3=A9raud?= Date: Fri, 1 Aug 2025 14:54:00 -0400 Subject: [PATCH] cmake: support building multi-arch contrib on macOS Change-Id: I29f135bb43c2b06cdb57f073e77872d923716f7a --- CMakeLists.txt | 74 +++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 67 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7e91a0d6d..f307c729b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -129,13 +129,73 @@ if (BUILD_CONTRIB) endif() file(LOCK ${CONTRIB_BUILD_PATH} DIRECTORY) - execute_process( - COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/contrib/bootstrap --host=${TARGET} - WORKING_DIRECTORY ${CONTRIB_BUILD_PATH}) - execute_process(COMMAND make list - WORKING_DIRECTORY ${CONTRIB_BUILD_PATH}) - execute_process(COMMAND make ${CONTRIB_BUILD_FLAGS} - WORKING_DIRECTORY ${CONTRIB_BUILD_PATH}) + message(STATUS "Building contrib for architectures: ${CMAKE_OSX_ARCHITECTURES} ${CMAKE_SYSTEM}") + list(LENGTH CMAKE_OSX_ARCHITECTURES CMAKE_OSX_ARCHITECTURES_LENGTH) + if (APPLE AND CMAKE_OSX_ARCHITECTURES_LENGTH GREATER 1) + message(STATUS "Building for multiple architectures: ${CMAKE_OSX_ARCHITECTURES}") + foreach(ARCH ${CMAKE_OSX_ARCHITECTURES}) + message(STATUS "Building for architecture: ${ARCH}") + set(ENV{CMAKE_OSX_ARCHITECTURES} ${ARCH}) + set(CC_TARGET ${ARCH}-apple-darwin${CMAKE_SYSTEM_VERSION}) + set(CC_CONTRIB_BUILD_PATH ${CMAKE_CURRENT_SOURCE_DIR}/contrib/native-${CC_TARGET}) + set(CC_CONTRIB_PATH ${CMAKE_CURRENT_SOURCE_DIR}/contrib/${CC_TARGET}) + file(MAKE_DIRECTORY ${CC_CONTRIB_BUILD_PATH}) + file(MAKE_DIRECTORY ${CC_CONTRIB_PATH}) + execute_process( + COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/contrib/bootstrap --host=${CC_TARGET} + WORKING_DIRECTORY ${CC_CONTRIB_BUILD_PATH}) + execute_process(COMMAND make list + WORKING_DIRECTORY ${CC_CONTRIB_BUILD_PATH}) + execute_process(COMMAND make ${CONTRIB_BUILD_FLAGS} + WORKING_DIRECTORY ${CC_CONTRIB_BUILD_PATH}) + endforeach() + # Build fat contrib: merge all .a files + set(FAT_CONTRIB_PATH ${CMAKE_CURRENT_SOURCE_DIR}/contrib/apple-darwin${CMAKE_SYSTEM_VERSION}) + execute_process(COMMAND rm -rf ${FAT_CONTRIB_PATH}) + list(GET CMAKE_OSX_ARCHITECTURES 0 ARCH_FIRST) + set(CONTRIB_PATH_FIRST ${CMAKE_CURRENT_SOURCE_DIR}/contrib/${ARCH_FIRST}-apple-darwin${CMAKE_SYSTEM_VERSION}) + string(REPLACE "arm64" "aarch64" ARCH_FIRST_LIB ${ARCH_FIRST}) + set(TARGET_FIRST_LIB ${ARCH_FIRST_LIB}-apple-darwin${CMAKE_SYSTEM_VERSION}) + execute_process(COMMAND cp -r ${CONTRIB_PATH_FIRST} ${FAT_CONTRIB_PATH}) + file(GLOB_RECURSE LIB_FILES ${FAT_CONTRIB_PATH}/lib/*.a) + foreach(LIB_FILE_PATH ${LIB_FILES}) + get_filename_component(LIB_FILE ${LIB_FILE_PATH} NAME) + get_filename_component(LIB_FILE_NAME ${LIB_FILE_PATH} NAME_WLE) + set(LIB_FILES_TO_MERGE "-create") + foreach(ARCH ${CMAKE_OSX_ARCHITECTURES}) + string(REPLACE "arm64" "aarch64" ARCH_LIB ${ARCH}) + set(CC_TARGET ${ARCH}-apple-darwin${CMAKE_SYSTEM_VERSION}) + set(CC_CONTRIB_PATH ${CMAKE_CURRENT_SOURCE_DIR}/contrib/${CC_TARGET}) + string(REPLACE ${TARGET_FIRST_LIB} ${ARCH_LIB}-apple-darwin${CMAKE_SYSTEM_VERSION} CC_LIB_FILE_NAME ${LIB_FILE}) + set(CC_LIB_FILE_PATH "${CC_CONTRIB_PATH}/lib/${CC_LIB_FILE_NAME}") + if(NOT EXISTS ${CC_LIB_FILE_PATH}) + message(FATAL_ERROR "Required library file not found: ${CC_LIB_FILE_PATH}") + endif() + list(APPEND LIB_FILES_TO_MERGE ${CC_LIB_FILE_PATH}) + endforeach() + list(APPEND LIB_FILES_TO_MERGE "-output" "${FAT_CONTRIB_PATH}/lib/${LIB_FILE}") + execute_process(COMMAND lipo ${LIB_FILES_TO_MERGE}) + endforeach() + # replace all path references in pc and cmake files + file(GLOB_RECURSE PC_FILES ${FAT_CONTRIB_PATH}/lib/pkgconfig/*.pc) + file(GLOB_RECURSE CMAKE_FILES ${FAT_CONTRIB_PATH}/lib/cmake/*.cmake) + list(APPEND ALL_FILES ${PC_FILES} ${CMAKE_FILES}) + foreach(FILE_PATH ${ALL_FILES}) + file(READ ${FILE_PATH} PC_FILE_CONTENT) + string(REPLACE ${CONTRIB_PATH_FIRST} ${FAT_CONTRIB_PATH} PC_FILE_CONTENT ${PC_FILE_CONTENT}) + file(WRITE ${FILE_PATH} ${PC_FILE_CONTENT}) + endforeach() + set(CONTRIB_PATH ${FAT_CONTRIB_PATH}) + else() + message(STATUS "Building contrib for ${TARGET}") + execute_process( + COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/contrib/bootstrap --host=${TARGET} + WORKING_DIRECTORY ${CONTRIB_BUILD_PATH}) + execute_process(COMMAND make list + WORKING_DIRECTORY ${CONTRIB_BUILD_PATH}) + execute_process(COMMAND make ${CONTRIB_BUILD_FLAGS} + WORKING_DIRECTORY ${CONTRIB_BUILD_PATH}) + endif() file(LOCK ${CONTRIB_BUILD_PATH} DIRECTORY RELEASE) else() set(SCRIPTS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/extras/scripts)