# SPDX-FileCopyrightText: 2023 Ivan Santa Maria # SPDX-License-Ref: BSD-3-Clause if(POLICY CMP0135) # remove if after cmake 3.23 is the minimum cmake_policy(SET CMP0135 NEW) endif() include(ExternalProject) include(MacroBoolToOnOff) # used always for stepped universal or non universal builds. set(PARENT_CMAKE_SOURCE_DIR ${CMAKE_SOURCE_DIR}) set(KRITA_MACOS_CONSOLIDATE_SCRIPT ${PARENT_CMAKE_SOURCE_DIR}/../tools/macos_consolidate.sh) set(kis_ONE_VALUE_ARGS URL URL_HASH DOWNLOAD_DIR WORKING_DIRECTORY GIT_REPOSITORY GIT_TAG GIT_REMOTE_UPDATE_STRATEGY GIT_SUBMODULES_RECURSE GIT_PROGRESS INSTALL_DIR ) set(kis_MULTI_VALUE_ARGS PATCH_COMMAND CONFIGURE_ARGS CMAKE_ARGS DEPENDS GIT_SUBMODULES CONFIGURE_COMMAND BUILD_COMMAND INSTALL_COMMAND UPDATE_COMMAND ) if (CMAKE_VERBOSE_MAKEFILE) set(KRITA_MESON_VERBOSE_OPTION --verbose) set(KRITA_MAKE_VERBOSE_OPTION VERBOSE=1) set(KRITA_CMAKE_VERBOSE_OPTION -DCMAKE_VERBOSE_MAKEFILE=ON) else() set(KRITA_MESON_VERBOSE_OPTION) set(KRITA_MAKE_VERBOSE_OPTION) set(KRITA_CMAKE_VERBOSE_OPTION) endif() MACRO_BOOL_TO_ON_OFF(CMAKE_VERBOSE_MAKEFILE _str_verbose_makefile) message (STATUS "Verbose output for external projects (set with -DCMAKE_VERBOSE_MAKEFILE=ON): ${_str_verbose_makefile}") # If APPLE call the muti build arch macro # in other case pass args to ExternalProject_Add # or if MESON given, make use of kis_ExternalProject_Add_meson macro(kis_ExternalProject_Add_with_separate_builds_apple) if(APPLE OR DEFINED ENV{FAKE_MACOS_ENVIRONMENT}) kis_ExternalProject_Add_macos(${ARGN}) else() set(options MESON AUTOMAKE) cmake_parse_arguments(EXT "${options}" "" "" ${ARGN}) if(${EXT_MESON}) kis_ExternalProject_Add_meson(${EXT_UNPARSED_ARGUMENTS}) else() # parsed arguments will not pass to child macro set(oneValueArgs WORKING_DIRECTORY) set(multiValueArgs CONFIGURE_ARGS UPDATE_COMMAND) cmake_parse_arguments(EXT "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) if (EXT_UPDATE_COMMAND) # There is some issue with passing an empty UPDATE_COMMAND via the macro arguments # so we just forbid that for now; noone uses updates currently anyway # If you'd like to recover this feature, test an external project with # GIT_REPOSITORY tag **and** try calling make ext_foo twice, it should not # fail message(FATAL_ERROR "separate build macro cannot handle non-empty UPDATE_COMMAND argument: ${EXT_UPDATE_COMMAND}") endif() ExternalProject_Add(${EXT_UNPARSED_ARGUMENTS} UPDATE_COMMAND "") endif() endif() endmacro() # Convenience macro to set all common MESON configuration macro(kis_ExternalProject_Add_meson EXT_NAME) set(onValueArgs "${kis_ONE_VALUE_ARGS}") set(multiValueArgs "${kis_MULTI_VALUE_ARGS}") cmake_parse_arguments(EXT "${options}" "${onValueArgs}" "${multiValueArgs}" ${ARGN}) ExternalProject_Add( ${EXT_NAME} DOWNLOAD_DIR ${EXTERNALS_DOWNLOAD_DIR} URL ${EXT_URL} URL_HASH ${EXT_URL_HASH} GIT_REPOSITORY ${EXT_GIT_REPOSITORY} GIT_TAG ${EXT_GIT_TAG} PATCH_COMMAND ${EXT_PATCH_COMMAND} CONFIGURE_COMMAND ${CMAKE_COMMAND} -E env PYTHONPATH=${_krita_pythonpath} PKG_CONFIG_ALLOW_SYSTEM_CFLAGS=1 ${MESON_BINARY_PATH} setup --libdir=lib -Dbuildtype=$,debug,debugoptimized> ${EXT_CONFIGURE_ARGS} BUILD_COMMAND ${CMAKE_COMMAND} -E env PYTHONPATH=${_krita_pythonpath} PKG_CONFIG_ALLOW_SYSTEM_CFLAGS=1 ${MESON_BINARY_PATH} compile ${KRITA_MESON_VERBOSE_OPTION} -C -j${SUBMAKE_JOBS} INSTALL_COMMAND ${CMAKE_COMMAND} -E env PYTHONPATH=${_krita_pythonpath} ${MESON_BINARY_PATH} install -C UPDATE_COMMAND "" DEPENDS ${EXT_DEPENDS} ) endmacro() # simplifies double arch compile con macos for external libraries not # supporting one step universal build # only define CONFIGURE, BUILD, INSTALL for custom build steps macro(kis_ExternalProject_Add_macos EXT_NAME) set(options MESON AUTOMAKE) set(onValueArgs URL URL_HASH DOWNLOAD_DIR WORKING_DIRECTORY GIT_REPOSITORY GIT_TAG GIT_REMOTE_UPDATE_STRATEGY GIT_SUBMODULES_RECURSE GIT_PROGRESS INSTALL_DIR ) set(multiValueArgs PATCH_COMMAND CONFIGURE_ARGS CMAKE_ARGS DEPENDS GIT_SUBMODULES CONFIGURE_COMMAND BUILD_COMMAND INSTALL_COMMAND UPDATE_COMMAND ) cmake_parse_arguments(EXT "${options}" "${onValueArgs}" "${multiValueArgs}" ${ARGN}) macro(compile_arch ARCH DEPENDEES EXT_MESON) # Some packages need special configure to set architecture string(REPLACE "@ARCH@" ${ARCH} EXT_CONFIGURE_COMMAND_ARCH "${EXT_CONFIGURE_COMMAND}") string(REPLACE "@ARCH@" ${ARCH} EXT_WORKING_DIRECTORY_ARCH "${EXT_WORKING_DIRECTORY}") if(NOT EXT_WORKING_DIRECTORY_ARCH) set(EXT_WORKING_DIRECTORY_ARCH ) endif() # CMake variant set(MAC_CONFIGURE_COMMAND arch -${ARCH} ${CMAKE_COMMAND} -S -B -${ARCH} ${KRITA_CMAKE_VERBOSE_OPTION} ${EXT_CONFIGURE_ARGS} ${EXT_CMAKE_ARGS} -DCMAKE_OSX_ARCHITECTURES:STRING=${ARCH} ) set(MAC_BUILD_COMMAND arch -${ARCH} ${CMAKE_COMMAND} --build -${ARCH} -j${SUBMAKE_JOBS} ) set(MAC_INSTALL_COMMAND DESTDIR=/build-${ARCH} ${CMAKE_COMMAND} --install -${ARCH} ) # Meson variant if(${EXT_MESON}) set(MAC_CONFIGURE_COMMAND ${CMAKE_COMMAND} -E env PYTHONPATH=${_krita_pythonpath} PKG_CONFIG_ALLOW_SYSTEM_CFLAGS=1 arch -${ARCH} ${MESON_BINARY_PATH} setup -${ARCH} --libdir=lib -Dbuildtype=$,debug,debugoptimized> -Dpkgconfig.relocatable=true ${EXT_CONFIGURE_ARGS} ${EXT_CMAKE_ARGS} --native-file=${CMAKE_CURRENT_BINARY_DIR}/meson-compiler_${ARCH}.ini ) set(MAC_BUILD_COMMAND ${CMAKE_COMMAND} -E env PYTHONPATH=${_krita_pythonpath} arch -${ARCH} ${MESON_BINARY_PATH} compile ${KRITA_MESON_VERBOSE_OPTION} -C -${ARCH} -j${SUBMAKE_JOBS} ) set(MAC_INSTALL_COMMAND ${CMAKE_COMMAND} -E env PYTHONPATH=${_krita_pythonpath} DESTDIR=/build-${ARCH} ${MESON_BINARY_PATH} install -C -${ARCH} ) endif() if(${EXT_AUTOMAKE} OR EXT_BUILD_COMMAND) set(MAC_CONFIGURE_COMMAND arch -${ARCH} -e "CFLAGS+=-arch ${ARCH}" -e "CXXFLAGS+=-arch ${ARCH}" /configure ${EXT_CONFIGURE_ARGS} ${EXT_CMAKE_ARGS} ) set(MAC_BUILD_COMMAND make clean COMMAND arch -${ARCH} make -j${SUBMAKE_JOBS} ${KRITA_MAKE_VERBOSE_OPTION} ) set(MAC_INSTALL_COMMAND make install DESTDIR=/build-${ARCH} INSTALL_ROOT=/build-${ARCH} ) endif() if(EXT_CONFIGURE_COMMAND AND NOT EXT_CONFIGURE_ARGS) set(MAC_CONFIGURE_COMMAND arch -${ARCH} ${EXT_CONFIGURE_COMMAND_ARCH}) endif() if(EXT_BUILD_COMMAND) set(MAC_BUILD_COMMAND arch -${ARCH} ${EXT_BUILD_COMMAND}) endif() if(EXT_INSTALL_COMMAND) # HACK: be over paranoid about DESTDIR set(MAC_INSTALL_COMMAND arch -${ARCH} -e DESTDIR=/build-${ARCH} -e INSTALL_ROOT=/build-${ARCH} ${EXT_INSTALL_COMMAND} DESTDIR=/build-${ARCH} INSTALL_ROOT=/build-${ARCH} ) endif() ExternalProject_Add_Step( ${EXT_NAME} build-${ARCH} # newline space is important COMMENT "Building ${EXT_NAME} ${ARCH}" WORKING_DIRECTORY ${EXT_WORKING_DIRECTORY_ARCH} # Configure arch variant COMMAND ${MAC_CONFIGURE_COMMAND} # build COMMAND ${MAC_BUILD_COMMAND} # install in tmp creating fat-bin COMMAND ${MAC_INSTALL_COMMAND} DEPENDEES ${DEPENDEES} DEPENDERS build ) endmacro() if(NOT EXT_GIT_REPOSITORY) ExternalProject_Add( ${EXT_NAME} DOWNLOAD_DIR ${EXTERNALS_DOWNLOAD_DIR} URL ${EXT_URL} URL_HASH ${EXT_URL_HASH} PATCH_COMMAND ${EXT_PATCH_COMMAND} CONFIGURE_COMMAND "" BUILD_COMMAND ${CMAKE_COMMAND} -E env ${KRITA_MACOS_CONSOLIDATE_SCRIPT} INSTALL_COMMAND "" UPDATE_COMMAND "" DEPENDS ${EXT_DEPENDS} ) else() ExternalProject_Add( ${EXT_NAME} DOWNLOAD_DIR ${EXTERNALS_DOWNLOAD_DIR} GIT_REPOSITORY ${EXT_GIT_REPOSITORY} GIT_TAG ${EXT_GIT_TAG} GIT_SUBMODULES ${EXT_GIT_SUBMODULES} GIT_SUBMODULES_RECURSE ${EXT_GIT_SUBMODULES_RECURSE} GIT_PROGRESS ${EXT_GIT_PROGRESS} GIT_REMOTE_UPDATE_STRATEGY ${EXT_GIT_REMOTE_UPDATE_STRATEGY} PATCH_COMMAND ${EXT_PATCH_COMMAND} CONFIGURE_COMMAND "" BUILD_COMMAND ${CMAKE_COMMAND} -E env ${KRITA_MACOS_CONSOLIDATE_SCRIPT} INSTALL_COMMAND "" UPDATE_COMMAND "" DEPENDS ${EXT_DEPENDS} ) endif() # FIXME: Since this var isn't set, setting to universal if(NOT CMAKE_OSX_ARCHITECTURES) set(CMAKE_OSX_ARCHITECTURES) list(APPEND CMAKE_OSX_ARCHITECTURES "x86_64") list(APPEND CMAKE_OSX_ARCHITECTURES "arm64") endif() set(step_depend configure) foreach(ARCH ${CMAKE_OSX_ARCHITECTURES}) compile_arch(${ARCH} ${step_depend} ${EXT_MESON}) set(step_depend build-${ARCH}) endforeach() # Add pre-install step that installs consolidated binaries # using DESTDIR handling if(${EXT_MESON} OR ${EXT_AUTOMAKE} OR EXT_BUILD_COMMAND) include(${CMAKE_SOURCE_DIR}/../cmake/find_automake_like_prefix.cmake) find_automake_like_prefix("${EXT_CONFIGURE_ARGS}" FINAL_PREFIX) endif() if(NOT FINAL_PREFIX AND EXT_CONFIGURE_ARGS) include(${CMAKE_SOURCE_DIR}/../cmake/find_qt_like_prefix.cmake) find_qt_like_prefix("${EXT_CONFIGURE_ARGS}" FINAL_PREFIX) endif() if(NOT FINAL_PREFIX AND EXT_CONFIGURE_COMMAND) include(${CMAKE_SOURCE_DIR}/../cmake/find_qt_like_prefix.cmake) find_qt_like_prefix("${EXT_CONFIGURE_COMMAND}" FINAL_PREFIX) endif() if(NOT FINAL_PREFIX AND EXT_CONFIGURE_COMMAND) include(${CMAKE_SOURCE_DIR}/../cmake/find_automake_like_prefix.cmake) find_automake_like_prefix("${EXT_CONFIGURE_COMMAND}" FINAL_PREFIX) endif() if(NOT FINAL_PREFIX AND EXT_CMAKE_ARGS) include(${CMAKE_SOURCE_DIR}/../cmake/find_cmake_like_prefix.cmake) find_cmake_like_prefix("${EXT_CMAKE_ARGS}" FINAL_PREFIX) endif() if (NOT FINAL_PREFIX) message(FATAL_ERROR "Cannot detect the final prefix from meson configuration string") endif() ExternalProject_Get_Property(${EXT_NAME} TMP_DIR) include(${CMAKE_SOURCE_DIR}/../cmake/offset_prefix_with_destdir.cmake) offset_prefix_with_destdir(${TMP_DIR}/build_uni ${FINAL_PREFIX} OFFSET_PREFIX) ExternalProject_Add_Step( ${EXT_NAME} pre-install # newline space is important COMMENT "Installing consolidated binaries for ${EXT_NAME}" COMMAND ${CMAKE_COMMAND} -DSRC=${OFFSET_PREFIX} -DDST=${FINAL_PREFIX} -P ${KRITA_CI_INSTALL_DIRECTORY} DEPENDERS install ) endmacro() macro(mkdir_build_arch_dir PROJECT_NAME ARCH) ExternalProject_Add_Step(${PROJECT_NAME} mkdir-build-${ARCH} COMMAND ${CMAKE_COMMAND} -E make_directory -${ARCH} DEPENDERS configure ) endmacro()