compile optimized C++ for debug build in Android Studio - cmake

I want to set jniDebuggable to false in Android Studio's debug version, but it seems that it doesn't work even I set like this:
debug {
jniDebuggable false
}
Since my JNI debug build is slow when running, I want to use the release build (faster than debug) when I debug my Java code.
Who can tell me how to do?

As stated in the comments under the question post by #Alex Cohn, and adapted from this answer he wrote to "adding "-O0" to cppFlags fails to disable clang compile optimization in android studio", you could do:
android {
defaultConfig {
externalNativeBuild {
cmake {
arguments '-DCMAKE_BUILD_TYPE:STRING=Release'
That's if you don't need actual debug support for the native side of things (i.e. if by "debug", you really just mean running and testing your code without a debugger). If you do, use RelWithDebInfo instead of Release, which creates an optimized build with debug symbols (see here for CMake docs on build out-of-box-defined types).
See here for docs on Android NDK's CMake Guide, and here for docs on ExternalNativeBuildOptions.

Related

Dependencies between Android native modules (prefab) fail to build

Our Android application consists of 40-some Android Library Modules (ALMs), each of which also builds a C++ shared library with externalNativeBuild and CMake. So far we had the dependencies between these libs set up like this:
The dependent ALM references the dependency ALM with api project(':lib')
The dependent CMake script references the dependency .so with add_library(SHARED IMPORTED lib) and set_target_properties(lib PROPERTIES IMPORTED_LOCATION ...) and a relative path.
Recently we had to upgrade to the latest Android API version. This started off a cascade because now we were getting deprecated warnings in code generated by the navigation-ktx library, but upgrading that requires upgrading Gradle and the Android Gradle plugin. After that I started getting errors like liblib.so, needed by 'project', missing and no known rule to make it.
It looks like the latest Gradle parallelizes build tasks more heavily, and this means the dependent CMake/Ninja builds are being started concurrently with their dependencies, resulting in this error because the dependency is not yet built. I figured out that what we were doing was not entirely supported, but there is a "supported" way to do that now, so I refactored our entire build to use Prefab.
Now I started getting other errors, alternating between:
1.
C++ build system [prefab] failed while executing ...
Usage: prefab [OPTIONS] PACKAGE_PATH...
Error: Invalid value for "PACKAGE_PATH": Directory ... is not readable.
ld: error: undefined symbol ...
I looked into build/intermediates and found that in the 2nd case, the cmake config script was generated incorrectly: instead of add_library(lib::lib SHARED IMPORTED ) it had add_library(lib::lib INTERFACE IMPORTED) like it it was a header only library, and there was no IMPORTED_LOCATION set in the file.
What am I doing wrong and what should I do to unbreak our build?
It looks like the toolchain support for prefab interdependencies within a project is not quite finished. Others are reporting the same kind of errors at https://issuetracker.google.com/issues/265544858:
This appears to be a race condition with generating prefab cmake files.
It says in https://issuetracker.google.com/issues/221231432 that the header-only cmake config is generated to satisfy Android Studio's IDE features (completion, etc.) before the library is actually built.
Treat as-yet-unconfigured modules as if they are Header-only libraries for Android Studio purposes. This works because Android Studio doesn't care about linker flags for the purposes of providing language services.

Switch between Debug and Release Library in cmake programmatically for vcpkg installed libraries

I have successfully compiled my C++ program but I am a getting linker error
(default)\Catch2.lib(catch_stringref.cpp.obj) : error LNK2038: mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '0' doesn't match value '2' in main.cpp.obj
After reading the post I realized this is due to improper library selection by library (using release mode library while my application is in debug mode) hence I printed the path to catch2 library
CMake Code
find_library(CATCH2_LIBRARY catch2)
message ("CATCH2_LIBRARY : ${CATCH2_LIBRARY}")
target_link_libraries(${PROJECT_NAME} ${CATCH2_LIBRARY})
returned
CATCH2_LIBRARY : D:/vcpkg/installed/x64-windows/lib/Catch2.lib
instead of
D:/vcpkg/installed/x64-windows/debug/lib/Catch2d.lib
I wish to know how can I make the cmake look into the debug directory (for libraries) when I am building in debug mode and vice versa.
Kindly note in Debug Mode the library is Catch2d.lib and in release mode it is Catch2.lib.
Library Paths
Release Library Path : D:\vcpkg\installed\x64-windows\lib\Catch2.lib
Debug Library Path : D:\vcpkg\installed\x64-windows\debug\lib\Catch2d.lib
This is continuation of my first cmake usage saga carried forward from here
What you are most likely interested in, is something that's called a generator expression. This allows you to define specific flags/names/suffixes/prefixes etc. based on the specified configuration.
They usually look something like this:
target_link_libraries(foobar PRIVATE Catch2$<$<CONFIG:Debug>:d>)
When running cmake with the Debug configuration it will add a d at the end of Catch2

qt5 build with cmake on window: ERROR: C++11 <random> is required and is missing or failed to compile

My env:
Qt source: dev branch
cmake version: 3.18.4.0
os: windows
Build step:
cd qt_source
mkdir build
cd build
cmake -DMAKE_BUILD_TYPE=Release ..
Then error raised:
ERROR: C++11 <random> is required and is missing or failed to compile.
ERROR: detected a std::atomic implementation that fails for function pointers. Please apply the patch corresponding to your Standard Library vendor, found in qtbase/config.tests/atomicfptr
How can I debug this?
Update on 2020/10/26:
I used the vcpkg install qt5 and it works.
I'd recommend you to use a bit more stable Qt branch, e.g. 5.15.1 or 5.12, otherwise you should be aware that dev branch is on-going development of new features and Qt 6 (as of 01/11/2019), and all bug fixes that are not only relevant for Qt 5 (as of 15/05/2020).
From my practical experience, current dev branch always need some tricks to use and brings lots of problems. If you still need to test some feature that is available only in dev -- consider switch to some stable branch and cherry-pick changes you are interested in.
I was getting this error when trying to build Qt itself from sources with Visual Studio 16 2019 generator. Turned out, it is not supported (yet?), so I had to use Ninja generator instead (and set C/C++ compiler to cl.exe) - then the configuration and build went fine.
So perhaps that is the case with building projects too - you should check if you are using Ninja (and switch to it if not).

Kotlin Native cinterop def file: how to eliminate absolute path?

When specify linkerOpts, we need set absolute path for -L option, but it's easy to break.
In older version, setting linkerOpts in build.gradle could work, but in 1.3.50, it warns that "-linker-option(s)/-linkerOpts/-lopt option is not supported by cinterop. Please add linker options to .def file or binary compilation instead.", and build do fail with "Undefined symbols" error.
What could I do?
This option is going to be deprecated once, so the warning was intentionally added after the 1.3.50 release. The motivation here is that one should prefer to set all linker options, even platform-specific, via .def file.
But, the build should not break apart in this case. Can you add the script contents, to make it clearer - what exactly led to the error?
UPD: After the GH project was shared in the comments I want to add some details here. This problem is described in the documentation here, this part:
Often it's necessary to specify target-specific linker options for a binary which uses a native library. It can be done using the linkerOpts property of the binary.
So, in this particular case, it will be correct to add the option to the binaries section instead of the cinterops. In the end, I made things together with
binaries {
all {
linkerOpts = ['-L'+rootProject.projectDir+'/libs/NativeBase64/iOS/', '-lNativeBase64']
}
}

How can I get the Frege compiler to see Android API classes when using Gradle?

I am attempting to write an Android app using the Frege language. Unfortunately, I'm not aware of any examples of how to do this.
So, I'm using Gradle as my build system, with the Android Gradle plugin. Then to get the Frege code to be compiled, I'm using a javaexec to call the frege compiler before the Java files get compiled, as suggested in this post.
I was successful in building an Android application with Frege code that gets called by Java code, as shown here.
However, the Frege code can only call standard Java APIs. It can't call any of the Android APIs.
I'd like to be able to call Android APIs from Frege. There is a nice repo here that has Frege wrappers for the Android APIs. Unfortunately, it has no build system or instructions.
I believe I've successfully set up my build.gradle to build the FregeAndroid wrappers along with my project's code. The Frege compiler is indeed attempting to build them.
However, the FregeAndroid code fails to compile, because it can't see the Android API classes. I assume I need to somehow find where the Android API classes are, and then add that to the Frege compiler's classpath, so it can see those classes. Unfortunately, this is where I'm stuck. I'm a newbie at Gradle, and can't figure out how to do this.
Here is my project which I have so far, which fails to build, in the following way:
:compileDebugJavaWithJavac
Frege compiler args: "-inline -d src/frege -make -fp /Users/ppelleti/Library/Android/sdk/platforms/android-21/android.jar -sp /Users/ppelleti/programming/android/frege-on-android/FregeAndroid/src /Users/ppelleti/programming/android/frege-on-android/FregeAndroid/src/frege/android/animation/TimeInterpolator.fr"
calling: javac -cp /Users/ppelleti/.gradle/caches/modules-2/files-2.1/org.frege-lang/frege/3.23.401-g7c45277/716990197271fdc15917b4f8d023d63009ba6e39/frege-3.23.401-g7c45277.jar:/Users/ppelleti/Library/Android/sdk/extras/android/m2repository/com/android/support/multidex/1.0.0/multidex-1.0.0.aar:src/frege:/Users/ppelleti/Library/Android/sdk/platforms/android-21/android.jar -d src/frege -sourcepath /Users/ppelleti/programming/android/frege-on-android/FregeAndroid/src -encoding UTF-8 src/frege/frege/android/animation/TimeInterpolator.java
runtime 4.282 wallclock seconds.
Frege compiler args: "-inline -d src/frege -make -fp /Users/ppelleti/Library/Android/sdk/platforms/android-21/android.jar -sp /Users/ppelleti/programming/android/frege-on-android/FregeAndroid/src /Users/ppelleti/programming/android/frege-on-android/FregeAndroid/src/frege/android/app/Activity.fr"
Android.app.TaskStackBuilder: build failed because module is not on class path
Android.app.Fragment: build failed because module is not on class path
Android.app.LoaderManager: build failed because module is not on class path
[... omitted a bunch of similar lines ...]
Any ideas would be much appreciated!
It turns out that there were several problems, including problems with both the source path and the classpath. I've updated my repository to fix these problems.
However, ultimately the build fails because there are files missing from the FregeAndroid repo. So to get my example to build, it would be necessary to fix the FregeAndroid wrappers or write new wrappers.