# Preliminary CPack APK Support

**URL:** https://discourse.cmake.org/t/preliminary-cpack-apk-support/3767
**Category:** Development
**Created:** [July 15, 2021, 10:07pm UTC](https://discourse.cmake.org/t/preliminary-cpack-apk-support/3767 "2021-07-15T22:07:50Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![Honeybunch](https://discourse.cmake.org/user_avatar/discourse.cmake.org/honeybunch/32/1639_2.png) [@Honeybunch](https://discourse.cmake.org/u/Honeybunch)
#### Post date: [July 15, 2021, 10:07pm UTC](https://discourse.cmake.org/t/preliminary-cpack-apk-support/3767/1 "2021-07-15T22:07:50Z")

</div>

I’ve long ached for a way to build Android applications solely in my own CMake-based projects. I simply despise Android Studio as I’m mostly interested in building C & C++ heavy applications with little to no need for Java. Something I’ve done for a long time is roll a custom target that would invoke the Android SDK tools to package an APK myself. However after recently learning a bit more about CPack I thought “Why can’t CPack create an APK?”

After rummaging through the CPack code I managed to add a custom APK generator that is very similar to the NuGet generator. You can find the code at my CMake fork on Github here: [GitHub - Honeybunch/CMake: Mirror of CMake upstream repository](https://github.com/Honeybunch/CMake)

Most of the actual logic is housed in a CPackAPK.cmake script and cmCPackApkGenerator.cxx:  
(I can’t link the full links due to being a new user 😀)  
Modules/Internal/CPack/CPackAPK.cmake  
Source/CPack/cmCPackAPKGenerator.cxx

You can also see how I’m using this in a personal project of mine here:

> <https://github.com/Honeybunch/sdltest/blob/main/android/CMakeLists.txt>

I’m making this topic for a few reasons:  
#1 To gauge interest: Do people besides me actually want this?  
#2 To gauge correctness of what I have so far: I’m new to hacking on CMake and I’d like some extra eyes on what I’ve done so far. I’ve read what docs and code I can find about what I’m trying to do but would love some feedback.

So, some questions I have:  
Is this the sort of feature that Kitware would even accept? I have no idea if this is maybe some sort of ground that’s been covered before that I just can’t find the history on.  
What kinds of horrible things have I done in my CPackAPK module? There are some obvious flaws that need correction (a more robust way of detecting the Android SDK) but I wonder what lurks beneath that someone as green as me would miss.  
The CPackAPK module currently relies on the user having setup their install procedure to install files to a “normal-ish” android-style directory structure. How reasonable is this? I’ve found that the APK packaging tools are a bit picky about directories but I may just be using them wrong.  
I see there are some tests for CPack but I haven’t made it there yet due to the above concerns. I assume that skipping tests would not be acceptable for submission?

---

<div class="post-metadata">

### Author: ![ben.boeckel](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/b/ea5d25/32.png) [@ben.boeckel](https://discourse.cmake.org/u/ben.boeckel)
#### Post date: [July 16, 2021, 9:57am UTC](https://discourse.cmake.org/t/preliminary-cpack-apk-support/3767/2 "2021-07-16T09:57:17Z")

</div>

Cc: @brad.king

---

<div class="post-metadata">

### Author: ![kyle.edwards](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/k/65b543/32.png) [@kyle.edwards](https://discourse.cmake.org/u/kyle.edwards)
#### Post date: [July 16, 2021, 1:25pm UTC](https://discourse.cmake.org/t/preliminary-cpack-apk-support/3767/3 "2021-07-16T13:25:41Z")

</div>

See the [`externalNativeBuild`](https://developer.android.com/reference/tools/gradle-api/4.1/com/android/build/api/dsl/ExternalNativeBuild) tag in Android Studio’s Gradle plugin. It invokes CMake from Gradle, and is IMHO the most supported way of building Android apps that are primarily C++.

---

<div class="post-metadata">

### Author: ![Honeybunch](https://discourse.cmake.org/user_avatar/discourse.cmake.org/honeybunch/32/1639_2.png) [@Honeybunch](https://discourse.cmake.org/u/Honeybunch)
#### Post date: [July 16, 2021, 4:32pm UTC](https://discourse.cmake.org/t/preliminary-cpack-apk-support/3767/4 "2021-07-16T16:32:23Z")

</div>

I get what you’re saying. Gradle is the intended way to handle APK packaging. However, Gradle has caused me much pain and I figured I could solve the problem with CPack instead. My vision is that it would also be possible to create a CPack generator for iOS IPAs. So you’d be able to target Windows, Linux, macOS, Android and iOS with just CMake and the relevant native build tools installed.

If the larger argument that you’re making is that you need the Android SDK to do this anyway and that includes Gradle, I hear you. But I would rather only maintain one build system in my projects.

---

<div class="post-metadata">

### Author: ![cristianadam](https://discourse.cmake.org/user_avatar/discourse.cmake.org/cristianadam/32/124_2.png) [@cristianadam](https://discourse.cmake.org/u/cristianadam)
#### Post date: [November 1, 2023, 12:52pm UTC](https://discourse.cmake.org/t/preliminary-cpack-apk-support/3767/5 "2023-11-01T12:52:29Z")

</div>

At Qt we have a similar issue, see [[QTBUG-106495] Deploy to Android without gradle - Qt Bug Tracker](https://bugreports.qt.io/browse/QTBUG-106495)

From my point of view cpack should allow packaging of a project that has been built only via CMake. This is the case for Qt applications.

---

<div class="post-metadata">

### Author: ![cristianadam](https://discourse.cmake.org/user_avatar/discourse.cmake.org/cristianadam/32/124_2.png) [@cristianadam](https://discourse.cmake.org/u/cristianadam)
#### Post date: [January 12, 2024, 1:35pm UTC](https://discourse.cmake.org/t/preliminary-cpack-apk-support/3767/6 "2024-01-12T13:35:23Z")

</div>

At [the bugreport above](https://bugreports.qt.io/browse/QTBUG-106495) I mentioned the update of the fork and pushed the changes at [Files · cpack-apk · Cristian Adam / CMake · GitLab (kitware.com)](https://gitlab.kitware.com/cristianadam/cmake/-/tree/cpack-apk).

With the following `Packaging.cmake` file I was able to get a Qt Quick Application to work with Qt 6.6.0 on macOS with android-31. Gradle was failing due to a requirement to upgrade to android-33 due to the `androidx.core`.

```cmake
if (NOT ANDROID)
    return()
endif()

# Copy Qt Android xml templates
file(
    COPY "${Qt6Core_DIR}/../../../src/android/templates/"
    DESTINATION ${CMAKE_BINARY_DIR}/android-build
)

# Run androiddeployqt to modify the xml templates and copy the dependencies
find_program(androiddeployqt_program androiddeployqt PATHS ${QT_HOST_PATH}/bin)
install(CODE
    "execute_process(
        COMMAND ${androiddeployqt_program} --input ${CMAKE_BINARY_DIR}/android-${CMAKE_PROJECT_NAME}-deployment-settings.json
                    --output ${CMAKE_BINARY_DIR}/android-build
                    --aux-mode
     )

     # Fix issue with ${applicationId} breaking aapt

     file(READ ${CMAKE_BINARY_DIR}/android-build/AndroidManifest.xml AndroidManifestXml)
     string(REPLACE \"\\\${applicationId}\" \"org.qtproject.qt.android.bindings\" AndroidManifestXml \"\${AndroidManifestXml}\")
     file(WRITE ${CMAKE_BINARY_DIR}/android-build/AndroidManifest.xml \"\${AndroidManifestXml}\")
    "
)

# We need the libc++_shared.so STL file
find_library(android_stl_lib ${ANDROID_STL})
install(FILES ${android_stl_lib} DESTINATION lib/${ANDROID_ABI})

# For the android:name="androidx.core.content.FileProvider" permissions
if (NOT EXISTS ${CMAKE_BINARY_DIR}/android-build/core-1.10.1.zip)
    file(DOWNLOAD "https://maven.google.com/androidx/core/core/1.10.1/core-1.10.1.aar"
                  ${CMAKE_BINARY_DIR}/android-build/core-1.10.1.zip)
    file(ARCHIVE_EXTRACT INPUT ${CMAKE_BINARY_DIR}/android-build/core-1.10.1.zip
         DESTINATION ${CMAKE_BINARY_DIR}/android-build/libs
         PATTERNS *.jar
    )
endif()

# Install the resources so that cpack can package them
install(
    DIRECTORY
        ${CMAKE_BINARY_DIR}/android-build/assets
        ${CMAKE_BINARY_DIR}/android-build/res
    DESTINATION /
)

install(
    DIRECTORY
        ${CMAKE_BINARY_DIR}/android-build/libs/
    DESTINATION /lib
)

set(CPACK_PACKAGE_NAME ${CMAKE_PROJECT_NAME})
set(CPACK_PACKAGE_VENDOR "The Qt Company Ltd")
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "${CPACK_PACKAGE_NAME}")
set(CPACK_VERBATIM_VARIABLES YES)
set(CPACK_INSTALL_PREFIX "/")
set(CPACK_SET_DESTDIR ON)
set(CPACK_STRIP_FILES ON)

set(CPACK_GENERATOR APK)

set(CPACK_APK_NDK_PATH ${ANDROID_NDK})
set(CPACK_APK_TOOL_VERSION 31.0.0)
set(CPACK_APK_ANDROID_VERSION 31)
set(CPACK_APK_KEYSTORE_PATH ".keystore")
set(CPACK_APK_JAVA_BINDINGS_DIR "${Qt6Core_DIR}/../../../src/android/java/src")
set(CPACK_APK_MANIFEST_PATH ${CMAKE_BINARY_DIR}/android-build/AndroidManifest.xml)
set(CPACK_APK_PACKAGE_LIST lib)

# Make Qt Creator happy, to find the apk
file(WRITE ${CMAKE_BINARY_DIR}/postcpack.cmake
    "
    file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/android-build/build/outputs/apk/)
    file(COPY_FILE \${CPACK_TEMPORARY_DIRECTORY}/\${CPACK_PACKAGE_NAME}-\${CPACK_PACKAGE_VERSION}.apk
          ${CMAKE_BINARY_DIR}/android-build/build/outputs/apk/android-build-debug.apk
          ONLY_IF_DIFFERENT
     )"
)
set(CPACK_POST_BUILD_SCRIPTS ${CMAKE_BINARY_DIR}/postcpack.cmake)

include(CPack)

```

It would be great to have the compiling of java bindings files and do the `d8` and `aapt` magic.

---

<div class="post-metadata">

### Author: ![cristianadam](https://discourse.cmake.org/user_avatar/discourse.cmake.org/cristianadam/32/124_2.png) [@cristianadam](https://discourse.cmake.org/u/cristianadam)
#### Post date: [September 23, 2026, 5:54pm UTC](https://discourse.cmake.org/t/preliminary-cpack-apk-support/3767/7 "2026-09-23T17:54:28Z")

</div>

With the help of Claude Code I have a merge request [CPack: Add APK generator (!12545)](https://gitlab.kitware.com/cmake/cmake/-/merge_requests/12545) for [CPack APK Support (#28112) · Issue · cmake/cmake](https://gitlab.kitware.com/cmake/cmake/-/work_items/28112).

The issue has the recipe for a Qt Project. The Qt deployment API will have to adapt to take the new CPack APK into consideration.
