libpd / pd-for-android

Pure Data for Android
351 stars 91 forks source link

Include header files in AAR required for building custom externals #75

Open rpattabi opened 6 years ago

rpattabi commented 6 years ago

pd-for-android currently includes libpd.so and native binaries of standard externals. However, the user of pd-for-android aar file wants to write custom externals, m_pd.h is also required. Such headers required for building custom externals can be packaged in AAR.

PdTest gives a nice example of custom external, but it does not depend on aar file which is what a typical user of this library will have.

Documenting the approach I use to build custom external here (Hope it helps someone. Suggestions and corrections are welcome).

Custom External: Compilation

Compilation of custom external requires m_pd.h in the include path. To achieve this

  1. git clone https://github.com/libpd/libpd
  2. Refer the clone header path in CMakeLists.txt of the custom external module like this. (I have android studio module for custom external and I use CMake for building c/c++ stuff for android as per current recommendation by Google)
cmake_minimum_required (VERSION 3.4.1)

set (SRC_PATH src/main/cpp)
link_directories ("libs/jni/${ANDROID_ABI}")

include_directories ("../../lib/libpd/pure-data/src")
add_library (myexternal_tilde SHARED ${SRC_PATH}/myexternal~.c)
target_compile_options (myexternal_tilde PRIVATE -std=c11 -DPD -O3)
target_link_libraries (myexternal_tilde pd)

Custom External: Linking

In order to make linking succeed, I pull libpd.so for different architectures from pd-for-android aar like this:

repositories {
    flatDir {
        dirs 'libs'
    }
}

configurations {
    aarjni {
        description = "copies jni directory from aar to libs"
        visible = false
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    aarjni "org.puredata.android:pd-core:$rootProject.ext.pdForAndroidVersion@aar"
}

// TODO ensure `cleanup` removes files copied by this task
// TODO make this task and configuration available to all projects
task extractJniFromAar {
    configurations.aarjni.resolvedConfiguration.resolvedArtifacts.each { artifact ->
        inputs.file artifact.file
        //noinspection UnnecessaryQualifiedReference
        def zipFile = new java.util.zip.ZipFile(artifact.file)
        zipFile.entries().each { entry ->
            if (!entry.isDirectory()) {
                outputs.file entry.getName()
            }
        }
    }
    doLast {
        inputs.files.each { zip ->
            copy {
                from zipTree(zip)
                into 'libs'
                include '/jni/**'
            }
        }
    }
}
preBuild.dependsOn extractJniFromAar

Conclusions

As you can see, compilation requires header files from pure data source which we have to pull manually. This makes compilation work, but there may be mismatch between the header files from libpd repository and native libs included in pd-for-android. I learned somewhere that aar file which carry native libraries can package header files as well.

Additionally, it would be great if pd-for-android can help further simplify this process.

joebowbeer commented 6 years ago

Please share your reference regarding packaging headers in AAR

I've only found is: https://stackoverflow.com/q/35140809/901597

rpattabi commented 6 years ago

Sorry for the late response. Seeing this just now.

I also don't know a standard way to package header files in AAR. One NDK contributor provides a workaround to include the headers here.

I also see vague mention of using C/C++ Package Managers for this purpose here. Interestingly, there seems to be many C/C++ package managers that mention that Android is supported. Examples are cdep, conan, hunter. They may provide a clean way to create AAR with additional stuff like header files although I couldn't figure out how to actually achieve that.

this conan documentation shows how to package header files along with the binaries. There may be a way to produce AAR through that.

I'm afraid, if any of these is of any relevance to the issue. I will be really surprised if other native libraries used for android does not have the similar need (which seems basic). I wonder how they handle this.

cerupcat commented 2 years ago

@rpattabi did you ever make progress on this?

I'm looking for tips on how to compile additional externals without also having to check out the PD repository and it sounds like maybe this work was a potential solution.

redbaron commented 2 years ago

Looks like Android Gradle Plugins supports it natively for a while now: https://developer.android.com/studio/build/dependencies#publish-native-libs-in-aars