CGO static/dynamic linking combined with gomobile bind

1,051 views
Skip to first unread message

mail.ja...@gmail.com

unread,
Oct 26, 2015, 11:40:41 AM10/26/15
to golang-nuts
Hello,

I am trying to use sqlite (+ libspatialite extension) with Go on Android. Using github.com/mattn/go-sqlite I can use sqlite3 just fine (See: https://github.com/mattn/go-sqlite3/issues/201#issuecomment-150725323)


- bundling the sqlite3 concatenated sources (sqlite3-amalgamation-sources) and using CGO to compile them.

What I would like to do, and where I would like your opinions/tips, which approach is the most feasible:

- Using sqlite3 + the libspatialite extension.

This could be done in several ways/approaches I could think of. Each one contains a description, where I fail:

1. Use a sqlite Extension: github.com/mattn-go-sqlite3 has support for loading sqlite3 extensions. I could just crosscompile a libspatilite.so library and load it.
    My problem here: How can I bundle additional files (libspatialite.so) along my other code using the gomobile bind toolchain? Can I create a fat binary which contains my compiled Go code + libspatilite.so? Or Can I change my LD_LIBRARY_PATH on the Android device?

2. Build a fat binary of sqlite3 and libspatiite outside of CGO toolchain and just statically link it. github.com/geopaparazzi/libjsqlite-spatialite-android has ready built binaries for android, which include sqlite3 + libspatialite.
    My problem here: How do I properly link a static library in CGO using the gomobile tool, meaning that it will also be in the generated Android aar?
    Assume my library is in a directory "libs/android/armeabi": If I put the following cgo command in my code: #cgo LDFLAGS: -L${SRCDIR}/libs/android/armeabi -lspatialite  I can build my project successfully, but the library is dynamically linked. Prepending -static -lspatialite does not help.
    Passing the linker flags directory to the compiler CC using -ldflags "-linkmode external -extldflags=-static" or -ldflags "-extldflags=-static" does not help either, since now it tries to statically link also the Android runtime.
   So what I would like to do: statically link my compiled C code the Go code. And after that use gomoble bind to create an Android aar.

3. Include the libspatilite sources and it's dependencies (ProjJ.4, libgeos) into github.com/mattn/go-sqlite.
    My problem here: How do I make sure that Proj.4 and libgeos are built before libspatilite? Since they depend on each other? Could I use pkg-config for each library and make pkg-config depend on another pkg-config?


My preferred way would be variant 2 or 3, but I do not know how I can tell the compiler to statically link my libspatilite binary into my Go code and ship it along into the aar generated by gomobile bind. The aar just contains a binary of the Go runtime + my Go code, but without the libspatilite code. Using variant 1, the compiled c code is properly included in the aar.



Thank you for your help/suggestions.

Jan



Hyang-Ah Hana Kim

unread,
Oct 26, 2015, 1:57:18 PM10/26/15
to mail.ja...@gmail.com, golang-nuts
Hi, Currently gomobile bind does not support a way to include extra .so files in the output aar. 
One obvious answer is to fix gomobile bind.

BTW have you tried to include the .so file in the final apk using any of the followings?

- Unzip the aar file and put the necessary lib*.so files under the right directory (jni/<abi>/), and then repackage.

or

- Put the prebuilt library (.so) as a separate module in Android Studio/Gradle project and let the module for go code 
depend on the module. I don't know if explicitly preloading the included .so file before using go code is necessary.

I didn't try any of the followings myself yet so none of them may not work though. 



Thank you for your help/suggestions.

Jan



--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
__

mail.ja...@gmail.com

unread,
Oct 27, 2015, 1:26:14 PM10/27/15
to golang-nuts, mail.ja...@gmail.com
Hi,

I tried your first approach and this works:

| - Unzip the aar file and put the necessary lib*.so files under the right directory (jni/<abi>/), and then repackage.

`libgojni.so` references my dynamically linked `libspatialite.so` and autoloads it.

There is no need to do a:
static {
    System.loadLibrary("spatialite");
}
which is great.

It shows the correct sqlite version, and I can create new tables. I still cannot access my libspatilite functions, but I guess this is a problem with my `libspatialite.so` and not with the Go toolchain.

So I guess it would be nice if `gomobile bind` could support this sometimes in the future? I mean, it is almost there, since you already integrate OpenAL. https://github.com/golang/mobile/blob/master/cmd/gomobile/build_androidapp.go#L160

Thank you for your help,

Jan

Hyang-Ah Hana Kim

unread,
Oct 27, 2015, 1:30:26 PM10/27/15
to Jan Weitz, golang-nuts
Good to hear that it's working.
To be honest, I am more leaning toward my second proposal (i.e. let android studio or more advanced build systems deal with this. :-) so I will probably experiment with my second proposal in the future before attempt to change the gomobile tool. 

Thanks for sharing how it went!

mail.ja...@gmail.com

unread,
Oct 27, 2015, 2:11:01 PM10/27/15
to golang-nuts, mail.ja...@gmail.com
One more question:

What happens if I do a `go install` of my go-spatialite project, which is already crosscompiled for android? E.g.:

env CC=$HOME/pkg/gomobile/android-ndk-r10e/arm/bin/arm-linux-androideabi-gcc CGO_ENABLED=1 GOOS=android GOARCH=arm GOARM=7 go install -a -x .

Now I can find the library in $HOME/pkg/android_arm/github.com/mattn/sqlite3/go-sqlite.a

Now I have another Go project, which should create an aar with gomoblile bind. Will it use the `go-sqlite.a` file or rebuild every dependency?

Sebastien Binet

unread,
Oct 28, 2015, 9:42:15 AM10/28/15
to mail.ja...@gmail.com, golang-nuts
hi,

On Tue, Oct 27, 2015 at 7:10 PM, <mail.ja...@gmail.com> wrote:
> One more question:
>
> What happens if I do a `go install` of my go-spatialite project, which is
> already crosscompiled for android? E.g.:
>
> env CC=$HOME/pkg/gomobile/android-ndk-r10e/arm/bin/arm-linux-androideabi-gcc
> CGO_ENABLED=1 GOOS=android GOARCH=arm GOARM=7 go install -a -x .
>
> Now I can find the library in
> $HOME/pkg/android_arm/github.com/mattn/sqlite3/go-sqlite.a
>
> Now I have another Go project, which should create an aar with gomoblile
> bind. Will it use the `go-sqlite.a` file or rebuild every dependency?

perhaps there is also the option of packaging the extra lib as syso files:
https://golang.org/pkg/go/build/#Package

go build understands and handles them seamlessly.

(I haven't used those myself but at some point this option was
recommanded to me by minux...)

-s

Jan Weitz

unread,
Oct 28, 2015, 12:30:33 PM10/28/15
to golang-nuts, mail.ja...@gmail.com
Thank you for your hint.
Reply all
Reply to author
Forward
0 new messages