I can't compile telegram source code with NDK - android-studio

I installed NDK and set the NDK path in "Project Structure" :
And then I added below codes to build.gradle:
task buildNative(type: Exec, description: 'Compile JNI source via NDK')
{
def ndkDir = android.ndkDirectory
commandLine "$ndkDir/ndk-build.cmd",
'-C', file('jni').absolutePath, // Change src/main/jni the relative path to your jni source
'-j', Runtime.runtime.availableProcessors(),
'all',
'NDK_DEBUG=1'
}
task cleanNative(type: Exec, description: 'Clean JNI object files') {
def ndkDir = android.ndkDirectory
commandLine "$ndkDir/ndk-build.cmd",
'-C', file('jni').absolutePath, // Change src/main/jni the relative path to your jni source
'clean'
}
clean.dependsOn 'cleanNative'
tasks.withType(JavaCompile) {
compileTask -> compileTask.dependsOn buildNative
}
And add this code to "defauilConfig" in build.gradle :
ndk {
moduleName "TMessagesProj"
}
When I try to build an APK , I get this error :
Error:Execution failed for task ':TMessagesProj:buildNative'.
Process 'command 'C:\Users\Mehran\AppData\Local\Android\ndk\android-ndk-r12/ndk-build.cmd'' finished with non-zero exit value 2
This is the Messages Console :
make (e=2): The system cannot find the file specified.
make: *** [D:/Mehran/AndroidStudioProjects/TelegramTest/TMessagesProj/obj/local/armeabi/objs-debug/tmessages.22/./opus/src/opus_encoder.o] Error 2
make: Leaving directory `D:/Mehran/AndroidStudioProjects/TelegramTest/TMessagesProj/jni'
Sorry for my bad English.

Related

Gradle : Skipping task ':groovydoc' as it has no source files and no previous output files

I'm trying to create groovydoc using gradle. I have created the below task :
The groovy classes are present in - src/integration-test/groovy/com/x/folders/*.groovy
This is my sourcesets :
sourceSets {
integrationTestCompile {
java {
compileClasspath += main.output + test.output
runtimeClasspath += main.output + test.output
srcDirs = ['src/integration-test/groovy']
}
resources.srcDir file('src/integration-test/resources')
}
}
groovydoc {
source = sourceSets.integrationTestCompile.java.srcDirs
classpath = configurations.compile
include '**/com/x/common/controllers/*'
}
I get the below message :
> Task :groovydoc NO-SOURCE
Skipping task ':groovydoc' as it has no source files and no previous output files.
I may have wrongly entered the sourcesets, but I have tried different ways but still getting the very same error message.

Android Studio - error: linker command failed with exit code 1

I downloaded the code from this repository (its a app to control a parrot drone):
Github
with the hopes of getting it to work so i can study the code, however im getting this error that seems hard to find a solution after searching the web, i mostly found things for IOS, xcode, etc
I imported the project into android studio, when i try to execute the app i get the following error:
Error:error: linker command failed with exit code 1 (use -v to see invocation)
I am not really into NDK, but from what i saw it could be the reason, things i tried:
Downloaded NDK and added the correct path to it.
Using latest SDK.
Changes to build.gradle like setting buildToolsVersion "25.0.0", etc
Build.gradle (Project: ardrone)
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.2.2'
}
}
allprojects {
repositories {
jcenter()
}
}
Build.gradle (Module:app)
import org.apache.tools.ant.taskdefs.condition.Os
apply plugin: 'com.android.application'
android {
compileSdkVersion 24
buildToolsVersion "25.0.0"
defaultConfig {
multiDexEnabled true
applicationId "com.parrot.freeflight"
minSdkVersion 9
targetSdkVersion 24
versionCode 20000
versionName "2.0-SDK"
ndk {
moduleName "adfreeflight"
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
// TODO proguard-rules seem outdated and useless cause it's only Android stuff
}
}
sourceSets.main {
jni.srcDirs = [] // This prevents the auto generation of Android.mk
jniLibs.srcDir 'src/main/jniLibs'
// This is not necessary unless you have precompiled libraries in your project.
}
task buildNative(type: Exec, description: 'Compile JNI source via NDK') {
def ndkCommand = "${android.ndkDirectory}/ndk-build"
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
ndkCommand += ".cmd"
}
commandLine ndkCommand,
'-C', file('src/main/jni').absolutePath,
'-j', Runtime.runtime.availableProcessors(),
'all',
'NDK_DEBUG=1'
}
task cleanNative(type: Exec, description: 'Clean JNI object files') {
def ndkCommand = "${android.ndkDirectory}/ndk-build"
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
ndkCommand += ".cmd"
}
commandLine ndkCommand,
'-C', file('src/main/jni').absolutePath,
'clean'
}
clean.dependsOn 'cleanNative'
tasks.withType(JavaCompile) {
compileTask -> compileTask.dependsOn buildNative
}
}
dependencies {
compile 'com.google.android.gms:play-services:10.0.0'
compile files('libs/android-support-v13.jar')
compile files('libs/com.sony.rdis.receiver-20111206.jar')
compile files('libs/com.sony.rdis.receiver.utility-20111206.jar')
}
local.properties
ndk.dir=C\:\\Users\\BugDroid\\AppData\\Local\\Android\\Sdk\\ndk-bundle
sdk.dir=C\:\\Users\\BugDroid\\AppData\\Local\\Android\\Sdk
You need to check your log for more details as the error 'Linker command failed with exit code 1' is usually followed by the more detailed error.
So to find more details, in Xcode click on the error under Buildtime and choose Reveal in log. This should give you extra hint. Without any specific error, it's difficult to know what's the problem.

Multiple resource folders

I'm trying to add one more resource folder in my Android project.
I created a new folder extra-res so my project structure looks like this:
+ src
+ main
+ res
+ layout
+ ...etc...
+ extra-res
+ layout
So I added this to build.gradle:
android {
.........
sourceSets {
main {
res.srcDirs = ['res', 'extra-res']
}
}
}
But after editing the build.gradle file the build fails.
:app:processDebugResources
C:\Users\vovasoft\AndroidStudioProjects\sdbm\app\build\intermediates\manifests\full\debug\AndroidManifest.xml
Error:(13, 23) No resource found that matches the given name (at
'icon' with value '#drawable/ic_launcher').
Error:(14, 24) No resource found that matches the given name (at 'label' with value '#string/app_name').
Error:Execution failed for task ':app:processDebugResources'.
com.android.ide.common.internal.LoggedErrorException: Failed to run
command:
aapt.exe package -f --no-crunch -I android.jar -M \AndroidStudioProjects\sdbm\app\build\intermediates\manifests\full\debug\AndroidManifest.xml -S \AndroidStudioProjects\sdbm\app\build\intermediates\res\debug
-A \AndroidStudioProjects\sdbm\app\build\intermediates\assets\debug
-m -J C:\Users\vovasoft\AndroidStudioProjects\sdbm\app\build\generated\source\r\debug -F (at 'label' with value '#string/activity_edit_field').
Before editing build.gradle the build was successful.
I gave you some wrong information when I answered your original question in https://stackoverflow.com/a/28176489/2985303. That'll teach me about not testing an answer before posting it. You need to more fully qualify the resource directory paths, like so:
android {
sourceSets {
main {
res.srcDirs = ['src/main/res', 'src/main/extra-res']
}
}
}
I was getting that error beacause I forgot to include my new resource folder in build.gradle file.

Using clang from NDK gradle build system

Using the old Makefile-based Android build system it is possible to using clang to compile sources by adding
NDK_TOOLCHAIN_VERSION=clang
Is there some way to achieve the same thing using the new gradle build system?
It's not directly possible for now, but you can still use the regular Makefiles from gradle:
import org.apache.tools.ant.taskdefs.condition.Os
apply plugin: 'android'
android {
...
sourceSets.main {
jniLibs.srcDir 'src/main/libs' //set jniLibs directory to ./libs
jni.srcDirs = [] //disable automatic ndk-build call
}
// call regular ndk-build(.cmd) script from main src directory
task ndkBuild(type: Exec) {
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
commandLine 'ndk-build.cmd', '-C', file('src/main').absolutePath
} else {
commandLine 'ndk-build', '-C', file('src/main').absolutePath
}
}
tasks.withType(JavaCompile) {
compileTask -> compileTask.dependsOn ndkBuild
}
}
Newer NDK revisions default to Clang. However, you can explicitly request a toolchain using the -DANDROID_TOOLCHAIN switch.
As of the Android Gradle Plugin 2.2.0 things have become much better. You can also adopt cmake. You should look over the new documentation.
android {
...
defaultConfig {
...
// This block is different from the one you use to link Gradle
// to your CMake or ndk-build script.
externalNativeBuild {
// For ndk-build, instead use ndkBuild {}
cmake {
// Passes optional arguments to CMake.
arguments "-DANDROID_TOOLCHAIN=clang"
// Sets optional flags for the C compiler.
cFlags "-D_EXAMPLE_C_FLAG1", "-D_EXAMPLE_C_FLAG2"
// Sets a flag to enable format macro constants for the C++ compiler.
cppFlags "-D__STDC_FORMAT_MACROS"
}
}
}
buildTypes {...}
productFlavors {
...
demo {
...
externalNativeBuild {
cmake {
...
// Specifies which native libraries to build and package for this
// product flavor. If you don't configure this property, Gradle
// builds and packages all shared object libraries that you define
// in your CMake or ndk-build project.
targets "native-lib-demo"
}
}
}
paid {
...
externalNativeBuild {
cmake {
...
targets "native-lib-paid"
}
}
}
}
// Use this block to link Gradle to your CMake or ndk-build script.
externalNativeBuild {
cmake {...}
// or ndkBuild {...}
}
}

How to make a task to call a main class

What I am trying to do is make a task in build.gradle that will execute a main class (class with the main method), but I don't know how.
I made a test project to test how to do that. Here is the file structure layout:
testProject/
build.gradle
src/main/groovy/hello/world/HelloWorld.groovy
Here is the content of build.gradle:
apply plugin: 'groovy'
apply plugin: 'maven'
repositories {
mavenCentral()
}
dependencies {
compile 'org.codehaus.groovy:groovy-all:2.0.6'
}
task( hello, dependsOn: jar, type: JavaExec ) {
main = 'hello.world.HelloWorld'
}
Here is the content of HelloWorld.groovy:
package hello.world
class HelloWorld {
public static void main(String[] args) {
println "Hello World!"
}
}
Here is what I get from shell:
testProject>$ gradle hello
:compileJava UP-TO-DATE
:compileGroovy UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:jar UP-TO-DATE
:hello
Error: Could not find or load main class hello.world.HelloWorld
:hello FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':hello'.
> Process 'command '/Library/Java/JavaVirtualMachines/jdk1.7.0_25.jdk/Contents/Home/bin/java'' finished with non-zero exit value 1
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
BUILD FAILED
Total time: 4.232 secs
So, my question is: how can I make gradle hello work? Thank you very much.
After a bit of googling, I found a solution. The only thing I need to change is the task block. The working one is pasted below:
task( hello, dependsOn: jar, type: JavaExec ) {
main = 'hello.world.HelloWorld'
classpath = sourceSets.main.runtimeClasspath
}
There is an application plugin for doing this.
apply plugin: 'application'
mainClassName = 'hello.world.HelloWorld'
And then call
gradle run
Besides adding run task, applying application plugin will also change the behaviour of assemble task. Now it will produce a standalone application that can be run with a shell script.
Consider this build.gradle, which is a simplified version:
apply plugin: 'groovy'
task( hello, type: JavaExec ) {
main = 'hello.world.HelloWorld'
classpath = files('exampleDir/bin','jars/groovy-all-2.0.1.jar')
}
Note the 'classpath' argument to the JavaExec task. This uses subdirectories such as:
exampleDir/src/hello/world/HelloWorld.groovy
exampleDir/bin/hello/world/HelloWorld.class
jars/groovy-all-2.0.1.jar
where:
(a) groovy-all-2.0.1.jar copied from my GROOVY_HOME/embeddable
(b) HelloWorld.groovy is compiled via groovyc and is as follows:
package hello.world
class HelloWorld {
public static void main(String[] args) {
println "Hello World!"
}
}
Just specifying sourceSets.main.runtimeClasspath as a classpath might not be enough. If you see NoClassDefFoundError this might help:
task( hello, dependsOn: jar, type: JavaExec ) {
main = 'hello.world.HelloWorld'
classpath(sourceSets.main.runtimeClasspath, sourceSets.main.compileClasspath)
}

Resources