cmake_minimum_required(VERSION 3.31)

project(AndroidApp)


set(CMAKE_CXX_VISIBILITY_PRESET hidden)
set(CMAKE_C_VISIBILITY_PRESET hidden)

message("C compiler                     ${CMAKE_C_COMPILER}")
message("C++ compiler                   ${CMAKE_CXX_COMPILER}")
message("ANDROID_NDK                    ${ANDROID_NDK}")
message("ANDROID_SDK_ROOT               ${ANDROID_SDK_ROOT}")
message("CMAKE_SYSTEM_VERSION           ${CMAKE_SYSTEM_VERSION}")
message("CMAKE_ANDROID_API              ${CMAKE_ANDROID_API}")
message("ANDROID_PLATFORM               ${ANDROID_PLATFORM}")

set(CLASSPATH_SEPARATOR ":")
if(CMAKE_HOST_WIN32)
  set(CLASSPATH_SEPARATOR ";") # unfortunately not possible to use ; on all platforms
endif()

if(NOT ANDROID_SDK_ROOT)
  if($ENV{ANDROID_SDK_ROOT})
    set(ANDROID_SDK_ROOT $ENV{ANDROID_SDK_ROOT} CACHE PATH "Path to Android SDK")
  else()
    set(ANDROID_SDK_ROOT "/usr/lib/android-sdk/" CACHE PATH "Path to Android SDK")
  endif()
endif()

if(NOT BUILD_TOOLS)
  file(GLOB children RELATIVE ${ANDROID_SDK_ROOT}/build-tools "${ANDROID_SDK_ROOT}/build-tools/*")
  list(SORT children COMPARE NATURAL ORDER DESCENDING) # NOTE: also considers ${ANDROID_SDK_ROOT}/build-tools/debian
  set(BUILD_TOOLS)
  foreach(child ${children})
    if(IS_DIRECTORY ${ANDROID_SDK_ROOT}/build-tools/${child})
      list(APPEND BUILD_TOOLS ${ANDROID_SDK_ROOT}/build-tools/${child})
    endif()
  endforeach()
endif()
find_program(AAPT      NAMES aapt              REQUIRED PATHS ${BUILD_TOOLS})
find_program(AAPT2     NAMES aapt2             REQUIRED PATHS ${BUILD_TOOLS})
find_program(APKSIGNER NAMES apksigner signapk REQUIRED PATHS ${BUILD_TOOLS})
find_program(ZIPALIGN  NAMES zipalign          REQUIRED PATHS ${BUILD_TOOLS})

execute_process(COMMAND "${ZIPALIGN}" OUTPUT_VARIABLE ZIPALIGN_OUTPUT ERROR_VARIABLE ZIPALIGN_OUTPUT OUTPUT_STRIP_TRAILING_WHITESPACE)
string(FIND "${ZIPALIGN_OUTPUT}" " -P " position)
set(ZIPALIGN_ALIGNEMNT_ARG "-p")
if(position GREATER -1)
  set(ZIPALIGN_ALIGNEMNT_ARG "-P" "16") # from android 14(?), different page sizes are supported
endif()
find_program(DX        NAMES dx        PATHS ${BUILD_TOOLS})
find_program(D8        NAMES d8        PATHS ${BUILD_TOOLS})
if(NOT DX AND NOT D8)
  message(FATAL_ERROR "At least dx or d8 is required, none found in ${BUILD_TOOLS}")
endif()
find_program(KOTLINC   NAMES kotlinc   REQUIRED)
set(KOTLIN_STDLIB "/usr/share/java/kotlin-stdlib.jar")
find_program(ADB       NAMES adb       REQUIRED PATHS ${ANDROID_SDK_ROOT}/platform-tools)
find_program(PROGUARD  NAMES proguard)

find_package(Java 1.8)
find_package(Java COMPONENTS Development)
include(UseJava) # java, jar, and other tools
set(BUNDLETOOL ${Java_JAVA_EXECUTABLE} -jar ${CMAKE_SOURCE_DIR}/bundletool-all-1.18.1.jar)

if(NOT ANDROID_PLATFORM_DIR)
  file(GLOB children RELATIVE ${ANDROID_SDK_ROOT}/platforms "${ANDROID_SDK_ROOT}/platforms/*")
  list(SORT children COMPARE NATURAL ORDER DESCENDING)
  list(GET children 0 ANDROID_PLATFORM_DIR)
  if(ANDROID_PLATFORM_DIR STRLESS ANDROID_PLATFORM)
    message(FATAL_ERROR "ERROR: no valid platform found. Found ${ANDROID_SDK_ROOT}/platforms/${ANDROID_PLATFORM_DIR}, but it is less than configured minimum supported version: ${ANDROID_PLATFORM}")
  endif()
  set(ANDROID_PLATFORM_DIR ${ANDROID_SDK_ROOT}/platforms/${ANDROID_PLATFORM_DIR})
endif()
find_file(ANDROID_JAR
  NAMES android.jar
  PATHS ${ANDROID_PLATFORM_DIR}
  REQUIRED NO_CMAKE_FIND_ROOT_PATH
)

add_executable(main src/main.cpp)


add_library(hello SHARED
  src/hello.cpp
)

target_link_libraries(hello
  PRIVATE
    log # required for logging with __android_log_write -> goes to logcat
)

set(CLASS_APP_FOLDER "${CMAKE_BINARY_DIR}/class_app_apk")



# PROJECT files
set(INPUTFILES_JAVA
  ${CMAKE_CURRENT_SOURCE_DIR}/src/com/example/MainActivity.java
  ${CMAKE_CURRENT_SOURCE_DIR}/src/com/example/hello/Hello.java
  ${CMAKE_CURRENT_SOURCE_DIR}/src/com/example/hello/HelloFromCPP.java
)
set(INPUTFILES_KOTLIN ${CMAKE_CURRENT_SOURCE_DIR}/src/com/example/kotlin.kt)

set(BASE_CLASSPATH_FOR_JAVAC "${ANDROID_JAR}")
if(KOTLIN_STDLIB)
  # required at least for class kotlin.Metadata
  set(BASE_CLASSPATH_FOR_JAVAC "${BASE_CLASSPATH_FOR_JAVAC}${CLASSPATH_SEPARATOR}${KOTLIN_STDLIB}")
endif()


set(STRINGS_XML "${CMAKE_CURRENT_SOURCE_DIR}/res/values/strings.xml")
set(IDS         "${CMAKE_CURRENT_SOURCE_DIR}/res/values/ids.xml")
set(LAYOUTS_XML "${CMAKE_CURRENT_SOURCE_DIR}/res/layout/activity_main.xml")
set(MANIFEST    "${CMAKE_CURRENT_SOURCE_DIR}/src/AndroidManifest.xml")


# create APK directly
set(FINAL_APK "${CMAKE_CURRENT_BINARY_DIR}/app.apk")

# FIXME: iterate like java files
set(RESOURCES "${CMAKE_CURRENT_BINARY_DIR}/res_app_apk/layout/activity_main.xml")
add_custom_command(
  OUTPUT  ${RESOURCES}
  DEPENDS ${LAYOUTS_XML} ${STRINGS_XML}
  COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/res_app_apk/
  COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/res_app_apk/layout/
  COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/res_app_apk/values/
  COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/res_app_apk/drawable/
  COMMAND ${CMAKE_COMMAND} -E copy ${LAYOUTS_XML} ${CMAKE_CURRENT_BINARY_DIR}/res_app_apk/layout/activity_main.xml
  COMMAND ${CMAKE_COMMAND} -E copy ${STRINGS_XML} ${CMAKE_CURRENT_BINARY_DIR}/res_app_apk/values/strings.xml
  COMMAND ${CMAKE_COMMAND} -E copy ${IDS}         ${CMAKE_CURRENT_BINARY_DIR}/res_app_apk/values/ids.xml
  COMMENT "copy relevant resources to build folder"
  VERBATIM
)


set(CLASSPATH_GEN_APP ${CMAKE_CURRENT_BINARY_DIR}/gen_app_apk/)
set(PROGUARDRULES_D_APP ${CMAKE_CURRENT_BINARY_DIR}/proguard_rules/)
set(PROGUARDRULES_F_APP ${PROGUARDRULES_D_APP}/aapt.pro)
set(R_JAVA ${CLASSPATH_GEN_APP}/com/example/R.java)
add_custom_command(
  OUTPUT  ${R_JAVA} ${PROGUARDRULES_F_APP}
  DEPENDS ${MANIFEST} ${STRINGS_XML} ${LAYOUTS_XML} ${RESOURCES}
  COMMAND ${CMAKE_COMMAND} -E make_directory ${CLASSPATH_GEN_APP}
  COMMAND ${CMAKE_COMMAND} -E make_directory ${PROGUARDRULES_D_APP}
  COMMAND ${AAPT} package -f -m -J ${CLASSPATH_GEN_APP} -S ${CMAKE_CURRENT_BINARY_DIR}/res_app_apk -G ${PROGUARDRULES_F_APP} -M ${MANIFEST} -I ${ANDROID_JAR}
  COMMENT "create R.java file with aapt"
  VERBATIM
  CODEGEN
)

set(CLASS_FILES_KOTLIN ${CLASS_APP_FOLDER}/kotlin.jar)
add_custom_command(
  OUTPUT  ${CLASS_FILES_KOTLIN}
  DEPENDS ${INPUTFILES_KOTLIN} ${INPUTFILES_JAVA} ${R_JAVA}
  COMMAND ${CMAKE_COMMAND} -E make_directory ${CLASS_APP_FOLDER} # not required when not creating jar file
  COMMAND ${KOTLINC} -jvm-target 1.8 -classpath "${ANDROID_JAR}${CLASSPATH_SEPARATOR}${CLASSPATH_GEN_APP}" -d ${CLASS_FILES_KOTLIN} ${INPUTFILES_KOTLIN} ${INPUTFILES_JAVA} ${R_JAVA};
  COMMENT "kotlinc"
  VERBATIM
)

# java might depend on .class files generated by kotlin
set(CLASS_FILES_JAVA ${CLASS_APP_FOLDER}/java.jar)
add_custom_command(
  OUTPUT  ${CLASS_FILES_JAVA}
  DEPENDS ${INPUTFILES_JAVA} ${R_JAVA} ${CLASS_FILES_KOTLIN}
  COMMAND  ${Java_JAVAC_EXECUTABLE} -Xlint:all --class-path "${BASE_CLASSPATH_FOR_JAVAC}${CLASSPATH_SEPARATOR}${CLASS_FILES_KOTLIN}${CLASSPATH_SEPARATOR}${CLASSPATH_GEN_APP}" --source 8 --target 8 -d ${CLASS_APP_FOLDER}/java ${INPUTFILES_JAVA};
  COMMAND  ${Java_JAR_EXECUTABLE} --date "1980-01-01T12:01:00Z" --create --no-manifest --file ${CLASS_FILES_JAVA} -C ${CLASS_APP_FOLDER}/java .;
  COMMENT "javac + jar"
  VERBATIM
)

if(PROGUARD)
  set(CLASSPATH_FOR_PROGUARD ${ANDROID_JAR})
  if(CLASS_FILES_KOTLIN)
    # required at least for class kotlin.Metadata
    set(CLASSPATH_FOR_PROGUARD "${CLASSPATH_FOR_PROGUARD}${CLASSPATH_SEPARATOR}/usr/share/java/kotlin-stdlib.jar")
  endif()
  set(OPTIMIZED_CLASS ${CLASS_APP_FOLDER}/optimized.jar)
  add_custom_command(
    OUTPUT  ${OPTIMIZED_CLASS}
    DEPENDS ${CLASS_FILES_KOTLIN} ${CLASS_FILES_JAVA}
    COMMAND ${PROGUARD} -dontobfuscate -libraryjars ${CLASSPATH_FOR_PROGUARD}
                        -injars ${CLASS_FILES_JAVA}${CLASSPATH_SEPARATOR}${CLASS_FILES_KOTLIN}
                        -outjars ${OPTIMIZED_CLASS}
                        -dontwarn org.jetbrains.annotations.NotNull # used only for static analysis, safe to ignore, no need to add other jars to classpath
                        # should be user-supplied; callback for jni
                        -keep "public class com.example.hello.HelloFromCPP{public static void log();}"
                        -include ${PROGUARDRULES_F_APP} # references com.example.MainActivity
    COMMENT "optimize .class files"
    VERBATIM
  )
  set(CLASS_FILES ${OPTIMIZED_CLASS})
else()
  set(CLASS_FILES ${CLASS_FILES_KOTLIN} ${CLASS_FILES_JAVA})
endif()

# convert .class to dex; note that DX is not part of never apks
set(DEX_FILE ${CMAKE_CURRENT_BINARY_DIR}/base_app_apk/classes.dex)
if(D8) # prefer d8 to dx if available
  add_custom_command(
    OUTPUT  ${DEX_FILE}
    DEPENDS ${MANIFEST} ${CLASS_FILES}
    COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/base_app_apk
    COMMAND ${D8} --output ${CMAKE_CURRENT_BINARY_DIR}/base_app_apk/ --classpath ${ANDROID_JAR} ${CLASS_FILES}
    COMMENT "convert .class to .dex file (d8)"
    VERBATIM
  )
else()
  add_custom_command(
    OUTPUT  ${DEX_FILE}
    DEPENDS ${MANIFEST} ${CLASS_FILES}
    COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/base_app_apk
    COMMAND ${DX} --dex --min-sdk-version=23 --output=${DEX_FILE} ${CLASS_FILES}
    COMMENT "convert .class to .dex file (dx)"
    VERBATIM
  )
endif()

set(UNSIGNED_APK "${CMAKE_CURRENT_BINARY_DIR}/app.unsigned.apk")
add_custom_command(
  OUTPUT  ${UNSIGNED_APK}
  DEPENDS ${MANIFEST} ${DEX_FILE} hello ${RESOURCES}
  COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/base_app_apk/lib/${ANDROID_ABI}
  COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/libhello.so ${CMAKE_CURRENT_BINARY_DIR}/base_app_apk/lib/${ANDROID_ABI}
  COMMAND ${AAPT} package -f -F ${CMAKE_CURRENT_BINARY_DIR}/app.unaligned.apk -I ${ANDROID_JAR} -M ${MANIFEST} -S ${CMAKE_CURRENT_BINARY_DIR}/res_app_apk base_app_apk
  COMMAND ${ZIPALIGN} ${ZIPALIGN_ALIGNEMNT_ARG} -f 4 ${CMAKE_CURRENT_BINARY_DIR}/app.unaligned.apk ${UNSIGNED_APK}
  COMMAND ${CMAKE_COMMAND} -E remove ${CMAKE_CURRENT_BINARY_DIR}/app.unaligned.apk
  COMMENT "create unsigned apk"
  VERBATIM
)

set(KEYSTORE "${CMAKE_CURRENT_SOURCE_DIR}/keystore.jks")
add_custom_command(
  OUTPUT  ${FINAL_APK}
  DEPENDS ${UNSIGNED_APK}
  COMMAND ${ZIPALIGN} ${ZIPALIGN_ALIGNEMNT_ARG} -f 4 ${UNSIGNED_APK} ${FINAL_APK}
  COMMAND ${APKSIGNER} sign --in ${FINAL_APK} -ks ${KEYSTORE} --ks-key-alias androidkey --ks-pass pass:android --key-pass pass:android --min-sdk-version 21 --v2-signing-enabled true --v1-signing-enabled false
  COMMENT "create final signed apk"
  VERBATIM
)

# generate bundle

set(FLAT_RESOURCES ${CMAKE_BINARY_DIR}/flat_res/layout_activity_main.xml.flat ${CMAKE_BINARY_DIR}/flat_res/values_strings.arsc.flat ${CMAKE_BINARY_DIR}/flat_res/values_ids.arsc.flat)
add_custom_command(
  OUTPUT  ${FLAT_RESOURCES}
  DEPENDS ${STRINGS_XML} ${IDS} ${LAYOUTS_XML}
  COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/flat_res # otherwise aapt2 creates zip archive
  COMMAND ${AAPT2} compile -o ${CMAKE_BINARY_DIR}/flat_res/ ${STRINGS_XML} ${IDS} ${LAYOUTS_XML}
  COMMENT "compile resources to flat"
  VERBATIM
)

set(CLASSPATH_GEN_BUNDLE ${CMAKE_CURRENT_BINARY_DIR}/gen_app_bundle/)
set(R_JAVA_BUNDLE ${CLASSPATH_GEN_BUNDLE}/com/example/R.java)


set(PROGUARDRULES_D_BUNDLE ${CMAKE_CURRENT_BINARY_DIR}/proguard_rules_bundle/)
set(PROGUARDRULES_F_BUNDLE ${PROGUARDRULES_D_BUNDLE}/aapt.pro)

add_custom_command(
  OUTPUT  ${R_JAVA_BUNDLE} ${PROGUARDRULES_F_BUNDLE}
  DEPENDS ${FLAT_RESOURCES}
  COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/output_ # otherwise aapt2 link errors
  COMMAND ${CMAKE_COMMAND} -E make_directory ${CLASSPATH_GEN_BUNDLE}
  COMMAND ${CMAKE_COMMAND} -E make_directory ${PROGUARDRULES_D_BUNDLE}
  COMMAND ${AAPT2} link --proto-format -o ${CMAKE_BINARY_DIR}/output_
                        -I ${ANDROID_JAR}
                        --manifest ${MANIFEST}
                        -R ${FLAT_RESOURCES}
                        --output-to-dir
                        --java ${CLASSPATH_GEN_BUNDLE}/
                        --proguard ${PROGUARDRULES_F_BUNDLE}
  COMMENT "aapt2 link and create R.java"
  VERBATIM
  CODEGEN
)


set(CLASS_BUNDLE_FOLDER "${CMAKE_BINARY_DIR}/class_app_bundle")

set(CLASS_FILES_KOTLIN_BUNDLE "${CLASS_BUNDLE_FOLDER}/kotlin.jar")
add_custom_command(
  OUTPUT  ${CLASS_FILES_KOTLIN_BUNDLE}
  DEPENDS ${INPUTFILES_KOTLIN} ${INPUTFILES_JAVA} ${R_JAVA_BUNDLE}
  COMMAND ${CMAKE_COMMAND} -E make_directory ${CLASS_BUNDLE_FOLDER} # not required when not creating jar file
  COMMAND ${KOTLINC} -jvm-target 1.8 -classpath "${ANDROID_JAR}${CLASSPATH_SEPARATOR}${CLASSPATH_GEN_BUNDLE}" -d ${CLASS_FILES_KOTLIN_BUNDLE} ${INPUTFILES_KOTLIN} ${INPUTFILES_JAVA} ${R_JAVA_BUNDLE};
  COMMENT "kotlinc (bundle)"
  VERBATIM
)

set(CLASS_FILES_JAVA_BUNDLE "${CLASS_BUNDLE_FOLDER}/java.jar")
add_custom_command(
  OUTPUT  ${CLASS_FILES_JAVA_BUNDLE}
  DEPENDS ${INPUTFILES_JAVA} ${R_JAVA_BUNDLE} ${CLASS_FILES_KOTLIN_BUNDLE}
  COMMAND  ${Java_JAVAC_EXECUTABLE} -Xlint:all --class-path "${BASE_CLASSPATH_FOR_JAVAC}${CLASSPATH_SEPARATOR}${CLASS_FILES_KOTLIN_BUNDLE}${CLASSPATH_SEPARATOR}${CLASSPATH_GEN_BUNDLE}" --source 8 --target 8 -d ${CLASS_BUNDLE_FOLDER}/java ${INPUTFILES_JAVA};
  COMMAND  ${Java_JAR_EXECUTABLE} --create --no-manifest --file ${CLASS_FILES_JAVA_BUNDLE} -C ${CLASS_BUNDLE_FOLDER}/java .;
  COMMENT "javac + jar (bundle)"
  VERBATIM
)


if(PROGUARD)
  set(CLASSPATH_FOR_PROGUARD ${ANDROID_JAR})
  if(KOTLIN_STDLIB)
    # required at least for class kotlin.Metadata
    set(CLASSPATH_FOR_PROGUARD "${CLASSPATH_FOR_PROGUARD}${CLASSPATH_SEPARATOR}${KOTLIN_STDLIB}")
  endif()
  set(OPTIMIZED_CLASS_BUNDLE ${CLASS_BUNDLE_FOLDER}/optimized.jar)
  add_custom_command(
    OUTPUT  ${OPTIMIZED_CLASS_BUNDLE}
    DEPENDS ${CLASS_FILES_KOTLIN_BUNDLE} ${CLASS_FILES_JAVA_BUNDLE}
    COMMAND ${CMAKE_COMMAND} -E make_directory ${CLASS_BUNDLE_FOLDER}/optimized/
    COMMAND ${PROGUARD} -dontobfuscate -libraryjars ${CLASSPATH_FOR_PROGUARD}
                        -injars ${CLASS_FILES_JAVA_BUNDLE}/${CLASSPATH_SEPARATOR}${CLASS_FILES_KOTLIN_BUNDLE}
                        -outjars ${OPTIMIZED_CLASS_BUNDLE}
                        -dontwarn org.jetbrains.annotations.NotNull # used only for static analysis, safe to ignore, no need to add other jars to classpath
                        # should be user-supplied; callback for jni
                        -keep "public class com.example.hello.HelloFromCPP{public static void log();}"
                        -include ${PROGUARDRULES_F_BUNDLE} # references com.example.MainActivity
    COMMENT "optimize .class files (bundle)"
    VERBATIM
  )
  set(CLASS_FILES_BUNDLE ${OPTIMIZED_CLASS_BUNDLE})
else()
  set(CLASS_FILES_BUNDLE ${CLASS_FILES_KOTLIN_BUNDLE} ${CLASS_FILES_JAVA_BUNDLE})
endif()

# convert .class to dex
set(DEX_FILE_BUNDLE ${CMAKE_CURRENT_BINARY_DIR}/base_app_bundle/classes.dex)
if(D8)
  add_custom_command(
    OUTPUT  ${DEX_FILE_BUNDLE}
    DEPENDS ${MANIFEST} ${CLASS_FILES_BUNDLE}
    COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/base_app_bundle
    COMMAND ${D8} --output ${CMAKE_CURRENT_BINARY_DIR}/base_app_bundle/ --classpath ${ANDROID_JAR} ${CLASS_FILES_BUNDLE}
    COMMENT "convert .class to .dex file (d8)"
    VERBATIM
  )
else()
  add_custom_command(
    OUTPUT  ${DEX_FILE_BUNDLE}
    DEPENDS ${MANIFEST} ${CLASS_FILES_BUNDLE}
    COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/base_app_bundle
    COMMAND ${DX} --dex --min-sdk-version=23 --output=${DEX_FILE_BUNDLE} ${CLASS_FILES_BUNDLE}
    COMMENT "convert .class to .dex file (bundle)"
    VERBATIM
  )
endif()






add_custom_command(
  OUTPUT  ${CMAKE_BINARY_DIR}/base_for_bundle/resources.pb
  DEPENDS ${DEX_FILE_BUNDLE} hello

  COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/base_for_bundle

  COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/output_/resources.pb ${CMAKE_BINARY_DIR}/base_for_bundle/resources.pb


  COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/base_for_bundle/manifest
  COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/output_/AndroidManifest.xml ${CMAKE_BINARY_DIR}/base_for_bundle/manifest/AndroidManifest.xml

  COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/base_for_bundle/dex
  COMMAND ${CMAKE_COMMAND} -E copy ${DEX_FILE_BUNDLE} ${CMAKE_BINARY_DIR}/base_for_bundle/dex/classes.dex


  COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_BINARY_DIR}/output_/res ${CMAKE_BINARY_DIR}/base_for_bundle/res

  COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/base_for_bundle/lib/${ANDROID_ABI}
  COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/libhello.so ${CMAKE_CURRENT_BINARY_DIR}/base_for_bundle/lib/${ANDROID_ABI}

  #COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_BINARY_DIR}/dex/lib ${CMAKE_BINARY_DIR}/base_for_bundle/lib
  # roots
  # assets
  #COMMAND ${CMAKE_COMMAND} -E tar "cf" ${CMAKE_BINARY_DIR}/base.zip --format=zip -- ${CMAKE_BINARY_DIR}/base_for_bundle

  COMMENT "collect resources for bundle"
  VERBATIM
)


set(BASE_ZIP "${CMAKE_CURRENT_BINARY_DIR}/base.zip" )
add_custom_command( # separate command because of WORKING_DIRECTORY
  OUTPUT  ${BASE_ZIP}
  DEPENDS ${CMAKE_BINARY_DIR}/base_for_bundle/resources.pb
  #COMMAND ${CMAKE_COMMAND} -E tar "cf" ${CMAKE_BINARY_DIR}/base.zip --format=zip -- dex lib manifest res
  COMMAND ${CMAKE_COMMAND} -E tar "cf" ${CMAKE_BINARY_DIR}/base.zip --format=zip -- .
  WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/base_for_bundle/
  COMMENT "create base.zip"
  VERBATIM
)

set(FINAL_BUNDLE "${CMAKE_CURRENT_BINARY_DIR}/app.aab")
add_custom_command(
  OUTPUT  ${FINAL_BUNDLE}
  DEPENDS ${BASE_ZIP}

  COMMAND ${BUNDLETOOL} build-bundle --modules=${BASE_ZIP} --output=${FINAL_BUNDLE}
  COMMAND ${BUNDLETOOL} build-apks --bundle=${FINAL_BUNDLE}
                                   --output=${CMAKE_CURRENT_BINARY_DIR}/app.apks
                                   --mode=universal
                                   --ks=${KEYSTORE}
                                   --ks-pass pass:android
                                   --ks-key-alias=androidkey
                                   --key-pass pass:android
  COMMAND ${CMAKE_COMMAND} -E tar x ${CMAKE_CURRENT_BINARY_DIR}/app.apks universal.apk
  COMMENT "create final signed aab+apk"
  VERBATIM
)

add_custom_target(apk ALL DEPENDS ${FINAL_APK})
add_custom_target(aab ALL DEPENDS ${FINAL_BUNDLE})




