Debug Android Native located in dependent eclipse project - android

(ADK 21, NDK r8d, Eclipse Juno)
[I've built several Android apps so decent experience using ADK/NDK etc]
Eclipse project setup:
- AppProject (android, java, no jni)
- LibProject (android, java, Yes jni)
Previously, all of it was in one project - builds fine, runs fine, and native debugging worked great.
Then I split off the "reusable" portion to make a library of common code to use with multiple "AppProject" application front ends. (Everything still builds, links, packs, and runs okay)
However, when I run "AppProject", I can no longer debug the native library.
What is the solution?
Possible option #1:
- Modify "LibProject" Android.mk to export a PreBuilt that is used by AppProject?
- (I would have all the debug symbols so I'm thinking that would work okay)
Would I need to cnature the AppProject as well? In other words, so it has an Android.mk to import the output .so from LibProject
Possible option #2
- http://stackoverflow.com/a/14344377/735533
- that workaround uses ndk-gdb
- I'm hoping for a solution where I can debug LibProject in Eclipse directly when running AppProject
Is there a better way to debug the native code located in the dependent project "LibProject" when running the main application "AppProject"?
Tia

For those curious ...
I tried prebuilts ...
And it definitely seems the be the way to go (test project setup worked)
But the structure of my codebase is a bit heavy on the native/non-native crosstalk and didn't want to take the time (yet) to do a proper reorganization at the moment.
However, restructuring as a prebuilt is on my "Important ToDo" list now
Anywhere, here is my solution.
On Linux (unix flavors) ... use links - the sources are linked into each AppProject from LibProject.
Basically the "LibProject" becomes a sort of "template" during development - it is not built or used as a library directly. Rather, each AppProject becomes self-sufficient, standalone, application with the contents of the library project embedded in its own code tree. Best part is native debugging works like a charm again.
Although it sort of defeats the point of making, there are benefits - one common codebase for the "library" portion ... which is really what I desire for the time being.
Also, conversion to use as a true Library dependency by the Application projects for, say, eventual release builds is an easy switch. Once debugged and ready, the Library can be built separately, packed normally with the application "front ends", and upgraded independently of the applications.

Related

Is there a way to include a native Windows library in a MAUI project?

I have a native Windows library I'd like to include as part of Windows build/package in my MAUI app. Is there a way to do this where it won't be included in the builds/packages of the other platforms?
I found a way to do this with Android native libraries: I simply place them in (ProjectDir)\Resources\lib\(Architecture), where (Architecture) is, for example, 'arm64-v8a'. Then I can simply flag them in the .csproj file as an AndroidNativeLibrary and all's well; they show up in my Android build and don't appear in any of the other builds (Windows, IOS, etc.).
Things I've tried:
Manually copying the Windows native lib (a DLL) to the generated AppX folder via a postbuild script. Not ideal. For one, the AppX folder isn't technically generated until after the build is finished; it's part of a packaging step (I believe). So, this kind of works, but isn't really the proper solution. I want the DLL to automatically be included by the packager.
Adding the DLL as an item to the .csproj. This means it gets automatically included in the AppX package, but is still not ideal as it subsequently winds up in every platform's build.
The most promising: referenced the DLL via a 'file' element in (ProjectDir)\Platforms\Windows\app.manifest. However, it doesn't seem like this manifest file plays any role in the build/packaging. Rather Package.appxmanifest seems to be the file that matters. If I throw intentional typos into app.manifest, building and packaging still succeed. I also added app.manifest to the csproj explicitly via ; it doesn't seem to care.
Anyway, any ideas/insight would be much appreciated.
Ok, I found a fantastic article that solves my problem: https://learn.microsoft.com/en-us/xamarin/cross-platform/cpp/
Not sure how I didn’t find this before; I was looking forever.

NDK on Android Studio keeps rebuilding all the time, takes forever

I have a big Android Studio project that has a separate module which contains native code.
The native build is defined with CMake and includes a bunch of source files of C++ code.
I noticed that since a very recent update (might be Android Studio 3.5), NDK rebuilds everything ALL THE TIME.
It can happen with a small change in Java code, switching flavor in an unrelated module in the project, incrementing version code, etc.
This is a major problem, since it can waste 10 minutes at a time for no reason.
I could not find a reasonable way to profile NDK builds in Android Studio and check what's causing the rebuild or what's taking so long.
Unfortunately the project's build files are too big to attach here. Any pointers for things to look after?
For the C/C++ code that you build with cmake, make sure you point cmake to a directory where it can keep its object files and binary outputs.
Let's say you have a dependency on Game in your top level CMakeLists.txt like so:
# dependency: Game
set ( game_src_DIR ../Game )
add_subdirectory( ${game_src_DIR} ${CMAKE_CURRENT_BINARY_DIR}/game )
Then the second parameter to add_subdirectory specified the place where AndroidStudio will keep the object files.
The debug and release object files will live in different subdirs, as will each dependency, so switching debug/release will not clash.
This appears to have been a regression in behavior from Android Studio 3.4 and has been fixed in Android Studio 4.1 Canary 4. Release notes are here.
Often, it helps to split the AS project such that the C++ part, possibly with its Java wrappers become a separate (library) module. This module will hopefully be more stable, not sensitive to increments of app version code.
Such module should not define many flavors, but have careful matching to the flavors of other modules. Sometimes, it makes sense even to disable "debug" variants for such library. There was an effort of the NDK team to better handle debug vs. release build switching, but this is still tricky.
But if after these improvements, insignificant changes to the project still cause massive rebuild, I would suggest to consider ccache.

Multiple Native Modules in Android Studio

I have a C++ codebase that is currently set up in Visual Studio (to run on Windows), with multiple Projects with inter-dependencies. I'm trying to bring it over to Android Studio, to get it running on Android.
I'm familiar with Visual Studio and C++, but quite new to Android Studio's Gradle and CMake.
My (possibly wrong) expectation is to try and treat Android Studio Projects like Visual Studio Solutions, and Android Studio Modules like Visual Studio Projects. Given that my codebase uses multiple Projects in Visual Studio, I am trying to create multiple Modules in Android Studio -- each one with their own build.gradle and CMakeLists.txt files.
The issue is that I cannot get one section of code (AS Module) to link with the other. I am compiling these different sections as STATIC using add_library() (I plan to have one Module that creates a SHARED library, to load into Java).
I can easily get the includes to work via include_directories("../OtherModule/src/"). However, I cannot get it to link. I cannot find the .so (or similar) file to link to (via target_link_libraries() or equivalent). When I extract the .arr file from a given Module, I do not see any .so or anything.
I realize that I could simply put the entire codebase under one Module (using one build.gradle and one CMakeLists.txt -- or network of CMakeLists.txt's using add_subdirectory()). I don't know if this is fine, or if it would take more/less time to build.
I'm sure that there could be multiple ways to set this up, and it could just be a matter of preference. All research that I've done thus far has only found strictly adding native code to the same module with Java code -- doing basic JNI native bridge stuff. I haven't been able to find a single article about multiple native Modules linking together.
I'm hoping that someone with more experience with native development on Android could help me out. Thanks!
TL;DR: Simplified scenario: (Without being concerned with the JNI native bridge) I have two Modules in Android Studio, both with only native code. I would like to have each Module have its own build.gradle and CMakeLists.txt, creating its own STATIC libraries. One Module depends on the other and must set the correct include and link directories. How do?! Is this even correct (or should there ever be only one Module with native code)?
I asked a related question here. It seems to me that AS...
...does not actually link the final module-library unless it's SHARED (it does allow static 'sub-libraries' within the module); consider making the final library shared - you will have to System.loadLibrary() it specifically in Java though.
...does not allow you to install files to other places (e.g., from your native module to your Android app). I work around this by fetching the library through set_target_properties( jniwrapper PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/../libnative/build/intermediates/cmake/${BUILD_TYPE}/obj/${ANDROID_ABI}/libnative.so ) and setting BUILD_TYPE in build.gradle. Not overly elegant though.
Overall, this does not seem to be an encouraged use-case in AS...

Android.mk for LibXtract

Can somebody help me write Android.mk for LibXtract or point me in correct directoin?
Here is source for lib - https://github.com/jamiebullock/LibXtract.git
Or mayby there is a way to use linux generated shared objects in Android?
Especially for bigger established projects, crafting Android.mk files is quite an effort. More so, if you are not familiar with Android NDK build architecture whose understanding requires digging deep into the documentation and Android NDK make files. I would suggest trying to use existing make files by setting CC to point to your NDK tool chain, and CFLAGS += -sysroot $(SYSROOT) where SYSROOT=${NDK_INSTALL_DIR}/platforms/android-<level>/arch-<arch>/ (depending on targeted Android API version and architecture). Even without knowing about your library, I would bet you should have good chance of success this way. Android NDK documentation (${NDK_INSTALL_DIR}/doc/STANDALONE-TOOLCHAIN.html) details the use of independent tool chain and also instructs how to create a standalone tool chain that will not require the use of -sysroot argument to xxx-gcc.
If you decide to use Android.mk instead, you might check existing projects -CSipSimple comes to my mind (PJSIP converted from standard form GNU make files).
Important is to create the shared objects using Android tool chains. It is possible to build them outside of your application source tree, and then just copy the shared objects into the package source libs/<architecture>/ directory.
Integration with your build system depends on details that are not known (including how smooth you desire this whole integration to be e.g. because of other people working with the same project). If you are creating an application from command line, the easiest would be to have GNU make file or shell script in the package root directory ensure libXtract.so and your application package is up-to-date by calling libXtract make file and ant to build and pack your Java application. If you are using ant there should be a way to specify using make to take care of libXtract.so. I am not sure if eclipse is completely relying on ant for building an application to know if this would be enough for enabling complete build by clicking mouse buttons from within eclipse, too.
The answer to this question says you could use cmake script to build Android.mk files - I have not tried this approach.

How to integrate Scala into core Android platform?

I am interested in integrating Scala (or some other non-Java JVM-language) into the android platform. I am not referring to writing an android application with Scala, that I did early early on, but actually hooking into the build process that builds the android platform source tree. I imagine this will be a matter of hooking into the makefiles and such. Does anyone have insight into this?
What I have so far:
The platform source treefrom git://android.git.kernel.org/platform/manifest.git built in its virgin form, guided by "[Download and build the Google Android][1]"
build/core/combo/scalac.mk # Configures scala compiler related variables, included by config.mk
Added definitions in build/core/definitions.mk for an all-subdir-scala-files and an all-scala-files-under
Added definition in definitions.mk to build scala files such that they are included in the package
What's left:
Include scala-library.jar
Ensure changes to -bootclasspath has not broken anything
Figure out how to handle case where scala classes depend on java classes and visa versa
Major cleanup of code
Testing!
Figure out what to do (other than just posting them here) with the changes I've made
Looks like I'm almost there!!!
Some notes from the past
Latest: I have found where the Java source files are compiled! In definitions.mk, see 'define transform-java-to-classes.jar'. The latest idea is to write a transform-scala-to-classes definition and then have it store those classes in the directly that gets packaged. I will call transform-scala-to-class right before this step in transform-java-to-classes.jar. Support for eclipse and cygwin will for now be dropped as it clutters up the code with workarounds and therefore increases my chances of failure.
The build process starts out by the root Makefile running build/core/main.mk
build/core/main.mk includes build/core/config.mk which includes build/core/combo/javac.mk which sets HOST_JAVAC, TARGET_JAVAC, and COMMON_JAVAC. COMMON_JAVAC is the "Java compiler command with common arguments," by the look of it the other two variables get these values by default, unless in a special environment (openjdk or eclipse). COMMON_JAVAC is not used outside this file. The other two are only used in build/core/definitions.mk.
build/core/java_library.mk (included by config.mk) seems to only be concerned with building jars. This is out of the scope of us caring. Any interaction with jars presupposes class files which presuppose that we were already successful in building our scala files.
There are checks in main.mk regarding the version of java. We will ignore these and assume that our version of scala is compatible. Right now (in combo/scalac.mk) I am using the same --target arg used in javac.mk. This should perhaps be stored in a variable.
main.mk also includes build/core/definitions.mk which in turns defines some useful functions. The one we care about here is all-java-files-under and all-subdir-java-files. The latter is used in Android.mk files to find java files. The former is used in the implementation of the latter. I will write Scala equivalents of them.
To figure out how the build process works, I am now running make with -n and others. I got this idea from the stackoverflow article "[Tool for debugging makefiles][2]". I am also investigating debugging with remake.
build/core/{config.mk, definitions.mk} gives us light as to which make files/commands are used to do what.
As a possible way of hacking in support on a per project bases, additional code could most likely be added to the project's Android.mk file. From platform/build/core/build-system.html we read "Android.mk is the standard name for the makefile fragments that control the building of a given module. Only the top directory should have a file named "Makefile"." You could create a new target like "scala-build" and run that (make PackageName scala-build) before the final make. One could perhaps also hide it sneakily in a variable assignment, mitigating the need for a target to be called explicitly.
Another way (far far more hackish) is to hijack the command being used for javac. This is set in build/core/combo/javac.mk. Your project's Android.mk will have to include *.scala files in LOCAL_SRC_FILES along with the *.java files.
Guys on reddit say, there's a tutorial on integration Scala into Android with ant here.

Categories

Resources