SwiftAndroid: Statically linking libicu and/or the stdlib?


(Geordie J) #1

Hi, I’m still working on the deployment and JNI side of SwiftAndroid (github.com/SwiftAndroid). After success with some basic tests I’ve started fleshing out a “Swifty” JNI interface and connected to some existing Swift library code I want to try out. Now I’m stuck and I hope someone with more experience can lend some wisdom on the matter:

libicu doesn’t come packaged for Android, so the source needs to be downloaded, compiled and then icui18n and icuuc linked into libswiftCore and libswiftRuntime during the stdlib build process. After that, if I copy the libicui18n and libicuuc.so files into the system library path on the Android emulator, the Swift code links with swiftCore and executes fine there.

What I haven’t yet figured out is how to get these icu libraries dynamically linking at runtime on a non-rooted device. For some reason, and seemingly no matter what I do the runtime linker complains of missing symbols.

I’ve tried loading the libraries in various ways with no luck: the same way I’m loading everything else (my own program's swift module, the stdlib, etc.), as an explicit dependency of libswiftCore (in Android.mk), and at runtime in Java via System.loadLibrary(). All of these result in the same fatal error: that a certain libicu symbol is missing (nm tells me it’s present in icui18n) and therefore libswiftCore couldn’t be loaded.

Based on
a) the above issues,
b) the fact that the icu libraries are large (as big as the swift stdlib itself), and that seemingly only a very small amount of them is actually used,
c) the fact that the swift ABI is not yet set in stone anyway (I understand swiftCore is still packaged alongside every Swift iOS app, for example, which as far as I understand negates any benefit of dynamic linking for now)

.. it would make sense to me to just statically link the libicu dependencies into the stdlib for Android, or even just forego dynamic linking altogether on Android, except for the system libs.

Assuming static linking makes sense for Android (please correct me if my reasoning so far is wrong - this is all very new for me), here’s where I’m stuck at the moment. I’ve tried building swift via

\./utils/build\-script \-R \-\-no\-assertions \-b \-p \-\-extra\-swift\-args build\-swift\-static\-stdlib=1

but changing this static-stdlib flag seems to have no effect at all on the build output. As more of a longshot I also tried adding

list\(APPEND swift\_runtime\_compile\_flags
  "\-Bstatic”\)

to stdlib/public/runtime/CMakeLists.txt just before add_swift_library(swiftRuntime IS_STDLIB IS_STDLIB_CORE. Neither of these seemed to do anything whatsoever. I wish it would at least break so I don’t get my hopes up waiting for the stdlib to recompile :slight_smile:

I’m a bit lost in all the different components of the build system to be honest, so any input on these issues would be greatly appreciated!

Thanks
-Geordie


(Dmitri Gribenko) #2

This option builds static archives of the standard library, not a standard
library that links in everything statically.

I would expect you would need to add some non-trival amount of CMake code
if you want to statically link ICU.

Dmitri

···

On Mon, Dec 21, 2015 at 6:13 PM, Geordie Jay via swift-dev < swift-dev@swift.org> wrote:

    ./utils/build-script -R --no-assertions -b -p --extra-swift-args
build-swift-static-stdlib=1

--
main(i,j){for(i=2;;i++){for(j=2;j<i;j++){if(!(i%j)){j=0;break;}}if
(j){printf("%d\n",i);}}} /*Dmitri Gribenko <gribozavr@gmail.com>*/


(Geordie J) #3

Thanks for your reply Dmitri. I ended up getting this working by manually
changing the SONAME and other internal references from within and to ICU
from the stdlib and APKs are now working on all the non-rooted devices I
have available to me.

I don't know my way around CMake to make major (or evidently even minor)
changes to the build, but a statically linked stdlib would certainly be
advantageous for other uses as well, e.g. for Emscripten. One thing at a
time though..

Happy new year,
Geordie

···

Dmitri Gribenko <gribozavr@gmail.com> schrieb am Di., 22. Dez. 2015 um 06:45:

On Mon, Dec 21, 2015 at 6:13 PM, Geordie Jay via swift-dev < > swift-dev@swift.org> wrote:

    ./utils/build-script -R --no-assertions -b -p --extra-swift-args
build-swift-static-stdlib=1

This option builds static archives of the standard library, not a standard
library that links in everything statically.

I would expect you would need to add some non-trival amount of CMake code
if you want to statically link ICU.

Dmitri

--
main(i,j){for(i=2;;i++){for(j=2;j<i;j++){if(!(i%j)){j=0;break;}}if
(j){printf("%d\n",i);}}} /*Dmitri Gribenko <gribozavr@gmail.com>*/