From b18d88183470f80793b0e5412d99f859a04ce2e7 Mon Sep 17 00:00:00 2001
From: aeberhardt <alexandre.eberhardt@savoirfairelinux.com>
Date: Thu, 5 Dec 2024 14:35:57 -0500
Subject: [PATCH] Build: clean CMakeList for Linux, Android and MacOS
 AutoAnswer

Change-Id: I7f483576273cce1141236cf528cee146f58d1431
---
 AutoAnswer/CMakeLists.txt | 253 +++++++++++++++++++++-----------------
 AutoAnswer/build.md       |  26 ++--
 2 files changed, 156 insertions(+), 123 deletions(-)

diff --git a/AutoAnswer/CMakeLists.txt b/AutoAnswer/CMakeLists.txt
index a84525e..47c297e 100644
--- a/AutoAnswer/CMakeLists.txt
+++ b/AutoAnswer/CMakeLists.txt
@@ -1,147 +1,172 @@
-# Copyright (C) 2023-2024 Savoir-faire Linux Inc.
+cmake_minimum_required (VERSION 3.10)
 
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
-# (at your option) any later version.
-
-# 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 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 Street, Fifth Floor, Boston, MA  02110-1301 USA.
-
-cmake_minimum_required(VERSION 3.10)
-
-# set the project name
+# Set the project name and version
 set (ProjectName AutoAnswer)
 set (Version 2.0.0)
-project(${ProjectName} VERSION ${Version})
 
-# Detect OS and architecture
-if(NOT CMAKE_SIZEOF_VOID_P EQUAL 8)
-    message(FATAL_ERROR "Unsupported architecture. Only x64 or aarch64 (arm64) is supported.")
+project (${ProjectName} VERSION ${Version})
+
+# Set default options
+option (DEBUG "Build in debug mode" OFF)
+
+# Set platform to build for
+set (PLATFORM_TYPE $ENV{PLATFORM_TYPE}) # can be LINUX or ANDROID
+if (PLATFORM_TYPE STREQUAL "ANDROID")
+    set (PLATFORM $ENV{ANDROID_ABI}) # can be arm64-v8a, armeabi-v7a or x86_64
+elseif(PLATFORM_TYPE STREQUAL "LINUX")
+    set (PLATFORM x86_64-linux-gnu) # can be x86_64-linux-gnu
+elseif(PLATFORM_TYPE STREQUAL "APPLE")
+    execute_process(
+        COMMAND sh -c "$(command -v cc || command -v gcc) -dumpmachine" # used to create the directory for daemon contribution, see daemon/contrib/bootstrap
+        OUTPUT_VARIABLE DUMP_MACHINE_RESULT
+        OUTPUT_STRIP_TRAILING_WHITESPACE
+    )
+    set (PLATFORM ${DUMP_MACHINE_RESULT})
+    execute_process(
+        COMMAND sh -c "uname -m"
+        OUTPUT_VARIABLE ARCH
+        OUTPUT_STRIP_TRAILING_WHITESPACE # remove the trailing "\n"
+    )
+    set (PLATFORM_LIB_DIR "${ARCH}-apple-darwin")
 else()
-    set (ARCH $CMAKE_SYSTEM_PROCESSOR)
-endif()
-
-if(WIN32)
-    set(DISTRIBUTION "x64-windows")
-elseif(APPLE)
-    set(DISTRIBUTION "${ARCH}-apple-darwin")
-elseif(ANDROID)
-    set(DISTRIBUTION "android")
+    message(FATAL_ERROR "Platform type not supported for now")
+endif ()
+
+set(CMAKE_ANDROID_ARCH_ABI ${PLATFORM})
+
+# set compilation flags based on platform
+if (PLATFORM STREQUAL "x86_64-linux-gnu")
+    set (CONTRIB_PLATFORM x86_64-linux-gnu)
+    set (distribution x86_64-linux-gnu)
+elseif (PLATFORM STREQUAL "arm64-v8a")
+    set (CONTRIB_PLATFORM aarch64-linux-android)
+    set (distribution android)
+elseif (PLATFORM STREQUAL "armeabi-v7a")
+    set (CONTRIB_PLATFORM arm-linux-androideabi)
+    set (distribution android)
+elseif (PLATFORM STREQUAL "x86_64")
+    set (CONTRIB_PLATFORM x86_64-linux-android)
+    set (distribution android)
+elseif (PLATFORM STREQUAL "x86_64-apple-darwin23.6.0")
+    set (CONTRIB_PLATFORM x86_64-apple-darwin23.6.0)
+    set (distribution x86_64-apple-darwin23.6.0)
 else()
-    set(DISTRIBUTION "x86_64-linux-gnu")
+    set (CONTRIB_PLATFORM ${PLATFORM})
+    set (dsitribution ${PLATFORM})
+endif ()
+
+if (PLATFORM_TYPE STREQUAL "ANDROID")
+    # should be removed and use the toolchain in env instead
+    set(CMAKE_ANDROID_ARCH_ABI ${PLATFORM}) # Set the desired ABI
+    set(CMAKE_ANDROID_STL_TYPE c++_shared) # Use C++ shared library
+    set(CMAKE_ANDROID_NDK_TOOLCHAIN_FILE /opt/android/ndk/26.3.11579264/build/cmake/android.toolchain.cmake)
+    set(CMAKE_TOOLCHAIN_FILE=/opt/android/ndk/26.3.11579264/build/cmake/android.toolchain.cmake)
+    set(CMAKE_C_COMPILER /opt/android/ndk/26.3.11579264/toolchains/llvm/prebuilt/linux-x86_64/bin/${CONTRIB_PLATFORM}30-clang)
+    set(CMAKE_CXX_COMPILER /opt/android/ndk/26.3.11579264/toolchains/llvm/prebuilt/linux-x86_64/bin/${CONTRIB_PLATFORM}30-clang++)
 endif()
 
-# Paths setup
-set (JAMI_PLUGINS_PATH ${PROJECT_SOURCE_DIR}/.. )
-set (DAEMON ${JAMI_PLUGINS_PATH}/daemon)
-set (DAEMON_SRC ${DAEMON}/src)
+message ("PLATFORM_TYPE: ${PLATFORM_TYPE}")
+message ("PLATFORM: ${PLATFORM}")
+message ("CONTRIB_PLATFORM: ${CONTRIB_PLATFORM}")
+message ("distribution: ${distribution}")
+
+# Set variables
+set (CMAKE_CXX_STANDARD 17)
+set (CMAKE_CXX_STANDARD_REQUIRED True)
+set (DAEMON ${PROJECT_SOURCE_DIR}/../daemon)
 set (CONTRIB_PATH ${DAEMON}/contrib)
-set (PLUGINS_LIB ${JAMI_PLUGINS_PATH}/lib)
-set (JPL_DIRECTORY ${PROJECT_BINARY_DIR}/jpl)
-set (JPL_FILE_NAME ${ProjectName}.jpl)
-set (SDK_PATH ${JAMI_PLUGINS_PATH}/SDK)
-set (PLUGIN_OUTPUT_DIR ${JPL_DIRECTORY}/lib/${DISTRIBUTION})
-
-message(Distribution:\ ${DISTRIBUTION})
-message(Building:\ ${ProjectName} ${Version})
-message(Build\ path:\ ${PROJECT_BINARY_DIR})
-message(JPL\ assembling\ path:\ ${JPL_DIRECTORY})
-message(JPL\ path:\ ${JAMI_PLUGINS_PATH}/build/${DISTRIBUTION}/${JPL_FILE_NAME})
-
-set(CMAKE_CXX_STANDARD 17)
-set(CMAKE_CXX_STANDARD_REQUIRED True)
-set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /DMSGPACK_NO_BOOST /MT")
-set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /DMSGPACK_NO_BOOST /MTd")
-
-set(plugin_SRC
+set (PLUGINS_LIB ${PROJECT_SOURCE_DIR}/../lib)
+set (CONTRIB_ROOT_PATH ${CONTRIB_PATH}/${CONTRIB_PLATFORM})
+set (CMAKE_BUILD_RPATH "$ORIGIN")
+set (SDK_PATH ${PROJECT_SOURCE_DIR}/../SDK)
+set (CMAKE_POSITION_INDEPENDENT_CODE ON)
+
+# Set platform specific variables
+if (PLATFORM_TYPE STREQUAL "ANDROID")
+    set (CMAKE_SHARED_LINKER_FLAGS "-Wl,-Bsymbolic")
+elseif (PLATFORM_TYPE STREQUAL "LINUX")
+    set (CMAKE_SHARED_LINKER_FLAGS "-Wl,-Bsymbolic")
+elseif(PLATFORM_TYPE STREQUAL "APPLE")
+    set (CMAKE_SHARED_LINKER_FLAGS "-Wl")
+endif ()
+
+list (APPEND CMAKE_FIND_ROOT_PATH ${CONTRIB_ROOT_PATH})
+set (CMAKE_FIND_ROOT_PATH_MODE_PACKAGE BOTH)
+list (APPEND CMAKE_PREFIX_PATH ${CONTRIB_ROOT_PATH})
+
+add_definitions (-DMSGPACK_NO_BOOST)
+
+if (DEBUG)
+    set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -fsanitize=address -Wall -Wextra -Wno-unused-parameter")
+    add_definitions (-D__DEBUG__)
+else ()
+    set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -Wall -Wextra -Wno-unused-parameter")
+endif ()
+
+if(PLATEFORM_TYPE STREQUAL "APPLE")
+    find_library (COREFOUNDATION CoreFoundation)
+    find_library (COREMEDIA CoreMedia)
+    find_library (COREVIDEO CoreVideo)
+    find_library (CORESERVICES CoreServices)
+    find_library (FOUNDATION Foundation)
+    find_library (AVFOUNDATION AVFoundation)
+    find_library (COREGRAPHICS CoreGraphics)
+    set (MACOS_LIBS
+        ${COREFOUNDATION}
+        ${COREMEDIA}
+        ${COREVIDEO}
+        ${CORESERVICES}
+        ${FOUNDATION}
+        ${AVFOUNDATION}
+        ${COREGRAPHICS}
+    )
+endif()
+# Source files
+set (plugin_SRC
     main.cpp
     BotChatHandler.cpp
     BotPeerChatSubscriber.cpp
     PluginPreferenceHandler.cpp
-    ${PLUGINS_LIB}/frameUtils.cpp
-    ${PLUGINS_LIB}/frameFilter.cpp
-)
-
-set(plugin_HDR
-    BotChatHandler.h
-    BotPeerChatSubscriber.h
-    PluginPreferenceHandler.h
-    ${PLUGINS_LIB}/frameUtils.h
-    ${PLUGINS_LIB}/pluglog.h
-    ${PLUGINS_LIB}/frameFilter.h
 )
 
 # Create shared library
-add_library(${ProjectName} SHARED ${plugin_SRC} ${plugin_HDR})
+add_library (${ProjectName} SHARED ${plugin_SRC})
 
-find_package(Python3 3.6 REQUIRED COMPONENTS Interpreter)
-
-target_include_directories(${ProjectName} PUBLIC
-    ${PROJECT_BINARY_DIR}
+# Include directories
+target_include_directories (${ProjectName} PUBLIC
     ${PROJECT_SOURCE_DIR}
+    ${DAEMON}/src
+    ${CONTRIB_PATH}/${CONTRIB_PLATFORM}/include
     ${PLUGINS_LIB}
-    ${DAEMON_SRC}
-    ${CONTRIB_PATH}
-    ${CONTRIB_PATH}/build/fmt/include
-    ${CONTRIB_PATH}/build/opendht/include
-    ${CONTRIB_PATH}/build/msgpack-c/include
 )
 
-# Link directories and libraries
-target_link_directories(${ProjectName} PUBLIC
-    ${CONTRIB_PATH}
-    ${CONTRIB_PATH}/build/fmt/msvc/Release
+# Link directories
+link_directories (
+    ${CONTRIB_PATH}/${CONTRIB_PLATFORM}/lib
 )
 
-target_link_libraries(${ProjectName} PUBLIC )
-
-# Android-specific flags
-if(ANDROID)
-    set(CMAKE_ANDROID_ARCH_ABI arm64-v8a) # Set the desired ABI
-    set(CMAKE_ANDROID_STL_TYPE c++_shared) # Use C++ shared library
-    set(CMAKE_ANDROID_NDK_TOOLCHAIN_FILE ${CONTRIB_PATH}/build/cmake/android.toolchain.cmake)
-    set(CMAKE_ANDROID_STL_INCLUDE_DIR ${CONTRIB_PATH}/sysroot/usr/include)
-    set(CMAKE_ANDROID_STL_LIBRARIES ${CONTRIB_PATH}/sysroot/usr/lib)
-endif()
+# Link libraries to the target
+target_link_libraries (${ProjectName} PUBLIC  ${MACOS_LIBS} ${LINK_LIBS}) # if the platform is not APPLE, MACOS_LIBS will be empty and will not affect the build
 
-if(CMAKE_CXX_FLAGS_DEBUG)
-    set(OUTPUT "${ProjectName}")
-    set(CLANG_OPTS "-g -fsanitize=address")
-    set(EXTRA_DEBUG_LIBRARIES "-lyaml-cpp")
-    set(EXTRA_DEFINES "-D__DEBUG__")
-else()
-    add_custom_command(
-        TARGET ${ProjectName}
-        PRE_BUILD
-        COMMAND ${Python3_EXECUTABLE} ${SDK_PATH}/jplManipulation.py --preassemble --plugin=${ProjectName}
-        COMMENT "Assembling Plugin files"
+if(PLATFORM_TYPE STREQUAL "APPLE")
+    set_target_properties (${ProjectName} PROPERTIES
+        LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/jpl/lib/${PLATFORM_LIB_DIR}"
     )
-endif()
+else ()
+    set_target_properties (${ProjectName} PROPERTIES
+        LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/jpl/lib/${PLATFORM}"
+    )
+endif ()
 
-add_custom_command(
+add_custom_command (
     TARGET ${ProjectName}
     PRE_BUILD
-    COMMAND ${Python3_EXECUTABLE} ${SDK_PATH}/jplManipulation.py --preassemble --plugin=${ProjectName}
+    COMMAND ${Python3_EXECUTABLE} ${SDK_PATH}/jplManipulation.py --preassemble --plugin=${ProjectName} --distribution=${distribution} --arch=${ARCH}
     COMMENT "Assembling Plugin files"
 )
-
-# Copy shared library to jpl directory
-add_custom_command(
-    TARGET ${ProjectName}
-    POST_BUILD
-    COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:${ProjectName}> ${PLUGIN_OUTPUT_DIR}
-    COMMENT "Copying output file to jpl directory"
-)
-
-add_custom_command(
+add_custom_command (
     TARGET ${ProjectName}
     POST_BUILD
-    COMMAND ${Python3_EXECUTABLE} ${SDK_PATH}/jplManipulation.py --assemble --plugin=${ProjectName}
+    COMMAND ${Python3_EXECUTABLE} ${SDK_PATH}/jplManipulation.py --assemble --plugin=${ProjectName} --distribution=${distribution}
     COMMENT "Generating JPL archive"
-)
+)
\ No newline at end of file
diff --git a/AutoAnswer/build.md b/AutoAnswer/build.md
index f0e8627..2a3cb8c 100644
--- a/AutoAnswer/build.md
+++ b/AutoAnswer/build.md
@@ -1,24 +1,32 @@
 # To build AutoAnswer, follow these steps:
 
-## Go to the AutoAnswer folder and create a build directory:
+build the folowing daemon contributions :
+- fmt
+- opendht
 
-```
-mkdir build-local
-cd build-local
+## from jami-plugins/ run:
+
+### Linux:
+```bash
+PLATFORM_TYPE="LINUX" python3 build-plugin.py --projects='AutoAnswer'
 ```
 
-## Run the following commands to build the project:
+### Android:
 
+```bash
+PLATFORM_TYPE="ANDROID" ANDROID_ABI="{Android ABI}" python3 build-plugin.py --projects='AutoAnswer'
 ```
-cmake ..
-cmake --build .
+
+### MacOS
+
+```bash
+PLATFORM_TYPE="MACOS" python3 build-plugin.py --projects='AutoAnswer'
 ```
 
 ## Once the build is complete, you will find your unsigned `AutoAnswer.jpl` in:
 
 ```
-jami-plugins/build/<your distribution>/
+jami-plugins/build/{your distribution}/
 ```
 
 ## To install it on Jami, you need to sign the plugin. Refer to `sign.md` in the `jami-plugins/` directory for instructions on how to sign your plugin.
-
-- 
GitLab