1# Qt Android CMake utility
2
3## What it is
4
5When using Qt for Android development, QMake & QtCreator is the only sane option for compiling and deploying. But if you prefer CMake, you're stuck and have no choice but writing .pro files that duplicate the functionality of your CMake files.
6
7This utility tries to avoids this by providing a CMake way of doing Android compilation and deployment, without QtCreator. It is based on:
8
9* the Android CMake toolchains available in the NDK
10* the ```androiddeployqt``` utility from the Qt Android SDK
11* the QML / Android example at https://github.com/calincru/QML-Android-Demo
12
13This utility has been developed for my own needs. Don't hesitate to use / share / fork / modify / improve it freely :)
14
15## How to use it
16
17### How to integrate it to your CMake configuration
18
19The toolchain file defines the ```ANDROID``` variable, so that everything which is added specifically for Android in your CMake files can be surrounded with
20
21```cmake
22if(ANDROID)
23    ...
24endif()
25```
26
27The first thing to do is to change your executable target into a library, because on Android, the entry point has to be a Java activity, and your C++ code is then loaded (as a library) and called by this activity.
28
29```cmake
30if(ANDROID)
31    add_library(my_app SHARED ...)
32else()
33    add_executable(my_app ...)
34endif()
35```
36
37Then all you have to do is to call the ```add_qt_android_apk``` macro to create a new target that will create the Android APK.
38
39```cmake
40if(ANDROID)
41    include(qt-android-cmake/AddQtAndroidApk.cmake)
42    add_qt_android_apk(my_app_apk my_app)
43endif()
44```
45
46And that's it. Your APK can now be created by running "make" (or "cmake --build ." if you don't want to bother typing the full path to the make.exe program included in the NDK).
47
48Of course, ```add_qt_android_apk``` accepts more options, see below for the detail.
49
50### How to run CMake
51
52First, you must make sure that the following environment variables are defined:
53
54* ```ANDROID_NDK```: root directory of the Android NDK
55* ```JAVA_HOME```: root directory of the Java JDK
56
57**IMPORTANT** ```JAVA_HOME``` must be defined when you compile the APK too.
58
59Additionally you can define the following ones, but you can also define them as CMake variables if you prefer:
60
61* ```ANDROID_SDK```: root directory of the Android SDK
62
63You can then run CMake:.
64
65**On Windows**
66```
67cmake -G"MinGW Makefiles"
68      -DCMAKE_TOOLCHAIN_FILE="%ANDROID_NDK%/build/cmake/android.toolchain.cmake"
69      -DCMAKE_MAKE_PROGRAM="%ANDROID_NDK%/prebuilt/windows-x86_64/bin/make.exe" .
70```
71
72**On Linux**
73```
74cmake -DCMAKE_TOOLCHAIN_FILE=path/to/the/android.toolchain.cmake .
75```
76
77**On Mac OS X**
78```
79This utility has not been tested on this OS yet :)
80```
81
82The Android toolchain can be customized with environment variables and/or CMake variables. Refer to its documentation (at the beginning of the toolchain file) for more details.
83
84## Options of the ```add_qt_android_apk``` macro
85
86The first two arguments of the macro are the name of the APK target to be created, and the target it must be based on (your executable). These are of course mandatory.
87
88The macro also accepts optional named arguments. Any combination of these arguments is valid, so that you can customize the generated APK according to your own needs.
89
90Here is the full list of possible arguments:
91
92### NAME
93
94The name of the application. If not given, the name of the source target is taken.
95
96Example:
97
98```cmake
99add_qt_android_apk(my_app_apk my_app
100    NAME "My App"
101)
102```
103
104### VERSION_CODE
105
106The internal version of the application. It must be a single number, incremented everytime your app is updated on the play store (otherwise it has no importance). If not given, the number 1 is used.
107
108Note that the public version of the application, which is a different thing, is taken from the VERSION property of the CMake target. If none is provided, the VERSION_CODE number is used.
109
110Example:
111
112```cmake
113add_qt_android_apk(my_app_apk my_app
114    VERSION_CODE 6
115)
116```
117
118### PACKAGE_NAME
119
120The name of the application package. If not given, "org.qtproject.${source_target}" , where source_target is the name of the source target, is taken.
121
122Example:
123
124```cmake
125add_qt_android_apk(my_app_apk my_app
126    PACKAGE_NAME "org.mycompany.myapp"
127)
128```
129
130### PACKAGE_SOURCES
131
132The path to a directory containing additional files for the package (custom manifest, resources, translations, Java classes, ...). If you were using a regular QMake project file (.pro), this directory would be the one that you assign to the  ```ANDROID_PACKAGE_SOURCE_DIR``` variable.
133
134If you don't provide this argument, a default manifest is generated from the ```AndroidManifest.xml.in``` template and automatically used for building the APK.
135
136Example:
137
138```cmake
139add_qt_android_apk(my_app_apk my_app
140    PACKAGE_SOURCES ${CMAKE_CURRENT_LIST_DIR}/my-android-sources
141)
142```
143
144### KEYSTORE
145
146The path to a keystore file and an alias, for signing the APK. If not provided, the APK won't be signed.
147
148Example:
149
150```cmake
151add_qt_android_apk(my_app_apk my_app
152    KEYSTORE ${CMAKE_CURRENT_LIST_DIR}/mykey.keystore myalias
153)
154```
155
156### KEYSTORE_PASSWORD
157
158The password associated to the given keystore. Note that this option is only considered if the ```KEYSTORE``` argument is used. If it is not given, the password will be asked directly in the console at build time.
159
160Example:
161
162```cmake
163add_qt_android_apk(my_app_apk my_app
164    KEYSTORE ${CMAKE_CURRENT_LIST_DIR}/mykey.keystore myalias
165    KEYSTORE_PASSWORD xxxxx
166)
167```
168
169### DEPENDS
170
171A list of dependencies (libraries) to be included into the APK. All the dependencies of the application must be listed here; if one is missing, the deployed application will fail to run on the device. The listed items can be either target names, or library paths.
172
173Example:
174
175```cmake
176add_qt_android_apk(my_app_apk my_app
177    DEPENDS a_linked_target "path/to/a_linked_library.so" etc.
178)
179```
180
181### INSTALL
182
183If this option is given, the created APK will be deployed to a connected Android device. By default, the chosen device is the default one, i.e. the first one of the ADB device list.
184
185Example:
186
187```cmake
188add_qt_android_apk(my_app_apk my_app
189    INSTALL
190)
191```
192## Troubleshooting
193
194In case of
195```
196-- Configuring done
197CMake Error in CMakeLists.txt:
198  No known features for CXX compiler
199
200  "GNU"
201
202  version 4.9.
203```
204see [Qt bug 54666](https://bugreports.qt.io/browse/QTBUG-54666) for details.
205
206## Contact
207
208Laurent Gomila: laurent.gom@gmail.com
209